diff options
author | Gleb O. Raiko <raiko@niisi.msk.ru> | 2000-04-07 12:55:57 +0000 |
---|---|---|
committer | Gleb O. Raiko <raiko@niisi.msk.ru> | 2000-04-07 12:55:57 +0000 |
commit | cdb6e8f01ce76e5128596c6d19804e3c402d35e1 (patch) | |
tree | 70af99983d916d2f7ed0129f4134b6154f0d3e29 /arch/mips | |
parent | fba859f9a0a26b3a0d4c116e161cb8698d666b07 (diff) |
Port paccess.h from mips64. mips32 paccess.h differs from the original one in
the following:
o works in case a constant address is passed to get_dbe/put_dbe
o uses faster binary search :-)
o the kernel are linked successfully even if get_dbe/put_dbe aren't
used
Diffstat (limited to 'arch/mips')
-rw-r--r-- | arch/mips/kernel/traps.c | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 90d2b90ed..26cd9fec8 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -227,8 +227,50 @@ void __die_if_kernel(const char * str, struct pt_regs * regs, const char *where, __die(str, regs, where, line); } +extern const struct exception_table_entry __start___dbe_table[]; +extern const struct exception_table_entry __stop___dbe_table[]; + +static void __declare_dbe_table(void) +{ + __asm__ __volatile__( + ".section\t__dbe_table,\"a\"\n\t" + ".previous" + ); +} + +static inline unsigned long +search_one_table(const struct exception_table_entry *first, + const struct exception_table_entry *last, + unsigned long value) +{ + const struct exception_table_entry *mid; + long diff; + + while (first < last) { + mid = (last - first) / 2 + first; + diff = mid->insn - value; + if (diff < 0) + first = mid + 1; + else + last = mid; + } + return (first == last && first->insn == value) ? first->nextinsn : 0; +} + +#define search_dbe_table(addr) \ + search_one_table(__start___dbe_table, __stop___dbe_table - 1, (addr)) + static void default_be_board_handler(struct pt_regs *regs) { + unsigned long new_epc; + unsigned long fixup = search_dbe_table(regs->cp0_epc); + + if (fixup) { + new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc); + regs->cp0_epc = new_epc; + return; + } + /* * Assume it would be too dangerous to continue ... */ @@ -282,7 +324,7 @@ void do_fpe(struct pt_regs *regs, unsigned long fcr31) { unsigned long pc; unsigned int insn; - extern void simfp(void*); + extern void simfp(unsigned int); #ifdef CONFIG_MIPS_FPE_MODULE if (fpe_handler != NULL) { |