diff options
author | James Morris <jmorris@namei.org> | 2008-09-21 20:41:56 -0400 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2008-09-21 20:41:56 -0400 |
commit | ab2b49518e743962f71b94246855c44ee9cf52cc (patch) | |
tree | 26b260a350f0a0a0d19b558bf147b812e3a1564c /arch/mips/kernel/traps.c | |
parent | f058925b201357fba48d56cc9c1719ae274b2022 (diff) | |
parent | 72d31053f62c4bc464c2783974926969614a8649 (diff) |
Merge branch 'master' into next
Conflicts:
MAINTAINERS
Thanks for breaking my tree :-)
Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'arch/mips/kernel/traps.c')
-rw-r--r-- | arch/mips/kernel/traps.c | 40 |
1 files changed, 27 insertions, 13 deletions
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 426cced1e9dc..5fd0cd020af5 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
@@ -46,6 +46,9 @@ | |||
46 | #include <asm/types.h> | 46 | #include <asm/types.h> |
47 | #include <asm/stacktrace.h> | 47 | #include <asm/stacktrace.h> |
48 | 48 | ||
49 | extern void check_wait(void); | ||
50 | extern asmlinkage void r4k_wait(void); | ||
51 | extern asmlinkage void rollback_handle_int(void); | ||
49 | extern asmlinkage void handle_int(void); | 52 | extern asmlinkage void handle_int(void); |
50 | extern asmlinkage void handle_tlbm(void); | 53 | extern asmlinkage void handle_tlbm(void); |
51 | extern asmlinkage void handle_tlbl(void); | 54 | extern asmlinkage void handle_tlbl(void); |
@@ -373,8 +376,8 @@ void __noreturn die(const char * str, const struct pt_regs * regs) | |||
373 | do_exit(SIGSEGV); | 376 | do_exit(SIGSEGV); |
374 | } | 377 | } |
375 | 378 | ||
376 | extern const struct exception_table_entry __start___dbe_table[]; | 379 | extern struct exception_table_entry __start___dbe_table[]; |
377 | extern const struct exception_table_entry __stop___dbe_table[]; | 380 | extern struct exception_table_entry __stop___dbe_table[]; |
378 | 381 | ||
379 | __asm__( | 382 | __asm__( |
380 | " .section __dbe_table, \"a\"\n" | 383 | " .section __dbe_table, \"a\"\n" |
@@ -1200,7 +1203,7 @@ void *set_except_vector(int n, void *addr) | |||
1200 | if (n == 0 && cpu_has_divec) { | 1203 | if (n == 0 && cpu_has_divec) { |
1201 | *(u32 *)(ebase + 0x200) = 0x08000000 | | 1204 | *(u32 *)(ebase + 0x200) = 0x08000000 | |
1202 | (0x03ffffff & (handler >> 2)); | 1205 | (0x03ffffff & (handler >> 2)); |
1203 | flush_icache_range(ebase + 0x200, ebase + 0x204); | 1206 | local_flush_icache_range(ebase + 0x200, ebase + 0x204); |
1204 | } | 1207 | } |
1205 | return (void *)old_handler; | 1208 | return (void *)old_handler; |
1206 | } | 1209 | } |
@@ -1251,6 +1254,9 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs) | |||
1251 | 1254 | ||
1252 | extern char except_vec_vi, except_vec_vi_lui; | 1255 | extern char except_vec_vi, except_vec_vi_lui; |
1253 | extern char except_vec_vi_ori, except_vec_vi_end; | 1256 | extern char except_vec_vi_ori, except_vec_vi_end; |
1257 | extern char rollback_except_vec_vi; | ||
1258 | char *vec_start = (cpu_wait == r4k_wait) ? | ||
1259 | &rollback_except_vec_vi : &except_vec_vi; | ||
1254 | #ifdef CONFIG_MIPS_MT_SMTC | 1260 | #ifdef CONFIG_MIPS_MT_SMTC |
1255 | /* | 1261 | /* |
1256 | * We need to provide the SMTC vectored interrupt handler | 1262 | * We need to provide the SMTC vectored interrupt handler |
@@ -1258,11 +1264,11 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs) | |||
1258 | * Status.IM bit to be masked before going there. | 1264 | * Status.IM bit to be masked before going there. |
1259 | */ | 1265 | */ |
1260 | extern char except_vec_vi_mori; | 1266 | extern char except_vec_vi_mori; |
1261 | const int mori_offset = &except_vec_vi_mori - &except_vec_vi; | 1267 | const int mori_offset = &except_vec_vi_mori - vec_start; |
1262 | #endif /* CONFIG_MIPS_MT_SMTC */ | 1268 | #endif /* CONFIG_MIPS_MT_SMTC */ |
1263 | const int handler_len = &except_vec_vi_end - &except_vec_vi; | 1269 | const int handler_len = &except_vec_vi_end - vec_start; |
1264 | const int lui_offset = &except_vec_vi_lui - &except_vec_vi; | 1270 | const int lui_offset = &except_vec_vi_lui - vec_start; |
1265 | const int ori_offset = &except_vec_vi_ori - &except_vec_vi; | 1271 | const int ori_offset = &except_vec_vi_ori - vec_start; |
1266 | 1272 | ||
1267 | if (handler_len > VECTORSPACING) { | 1273 | if (handler_len > VECTORSPACING) { |
1268 | /* | 1274 | /* |
@@ -1272,7 +1278,7 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs) | |||
1272 | panic("VECTORSPACING too small"); | 1278 | panic("VECTORSPACING too small"); |
1273 | } | 1279 | } |
1274 | 1280 | ||
1275 | memcpy(b, &except_vec_vi, handler_len); | 1281 | memcpy(b, vec_start, handler_len); |
1276 | #ifdef CONFIG_MIPS_MT_SMTC | 1282 | #ifdef CONFIG_MIPS_MT_SMTC |
1277 | BUG_ON(n > 7); /* Vector index %d exceeds SMTC maximum. */ | 1283 | BUG_ON(n > 7); /* Vector index %d exceeds SMTC maximum. */ |
1278 | 1284 | ||
@@ -1283,7 +1289,8 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs) | |||
1283 | *w = (*w & 0xffff0000) | (((u32)handler >> 16) & 0xffff); | 1289 | *w = (*w & 0xffff0000) | (((u32)handler >> 16) & 0xffff); |
1284 | w = (u32 *)(b + ori_offset); | 1290 | w = (u32 *)(b + ori_offset); |
1285 | *w = (*w & 0xffff0000) | ((u32)handler & 0xffff); | 1291 | *w = (*w & 0xffff0000) | ((u32)handler & 0xffff); |
1286 | flush_icache_range((unsigned long)b, (unsigned long)(b+handler_len)); | 1292 | local_flush_icache_range((unsigned long)b, |
1293 | (unsigned long)(b+handler_len)); | ||
1287 | } | 1294 | } |
1288 | else { | 1295 | else { |
1289 | /* | 1296 | /* |
@@ -1295,7 +1302,8 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs) | |||
1295 | w = (u32 *)b; | 1302 | w = (u32 *)b; |
1296 | *w++ = 0x08000000 | (((u32)handler >> 2) & 0x03fffff); /* j handler */ | 1303 | *w++ = 0x08000000 | (((u32)handler >> 2) & 0x03fffff); /* j handler */ |
1297 | *w = 0; | 1304 | *w = 0; |
1298 | flush_icache_range((unsigned long)b, (unsigned long)(b+8)); | 1305 | local_flush_icache_range((unsigned long)b, |
1306 | (unsigned long)(b+8)); | ||
1299 | } | 1307 | } |
1300 | 1308 | ||
1301 | return (void *)old_handler; | 1309 | return (void *)old_handler; |
@@ -1515,7 +1523,7 @@ void __cpuinit per_cpu_trap_init(void) | |||
1515 | void __init set_handler(unsigned long offset, void *addr, unsigned long size) | 1523 | void __init set_handler(unsigned long offset, void *addr, unsigned long size) |
1516 | { | 1524 | { |
1517 | memcpy((void *)(ebase + offset), addr, size); | 1525 | memcpy((void *)(ebase + offset), addr, size); |
1518 | flush_icache_range(ebase + offset, ebase + offset + size); | 1526 | local_flush_icache_range(ebase + offset, ebase + offset + size); |
1519 | } | 1527 | } |
1520 | 1528 | ||
1521 | static char panic_null_cerr[] __cpuinitdata = | 1529 | static char panic_null_cerr[] __cpuinitdata = |
@@ -1552,6 +1560,10 @@ void __init trap_init(void) | |||
1552 | extern char except_vec3_generic, except_vec3_r4000; | 1560 | extern char except_vec3_generic, except_vec3_r4000; |
1553 | extern char except_vec4; | 1561 | extern char except_vec4; |
1554 | unsigned long i; | 1562 | unsigned long i; |
1563 | int rollback; | ||
1564 | |||
1565 | check_wait(); | ||
1566 | rollback = (cpu_wait == r4k_wait); | ||
1555 | 1567 | ||
1556 | #if defined(CONFIG_KGDB) | 1568 | #if defined(CONFIG_KGDB) |
1557 | if (kgdb_early_setup) | 1569 | if (kgdb_early_setup) |
@@ -1616,7 +1628,7 @@ void __init trap_init(void) | |||
1616 | if (board_be_init) | 1628 | if (board_be_init) |
1617 | board_be_init(); | 1629 | board_be_init(); |
1618 | 1630 | ||
1619 | set_except_vector(0, handle_int); | 1631 | set_except_vector(0, rollback ? rollback_handle_int : handle_int); |
1620 | set_except_vector(1, handle_tlbm); | 1632 | set_except_vector(1, handle_tlbm); |
1621 | set_except_vector(2, handle_tlbl); | 1633 | set_except_vector(2, handle_tlbl); |
1622 | set_except_vector(3, handle_tlbs); | 1634 | set_except_vector(3, handle_tlbs); |
@@ -1680,6 +1692,8 @@ void __init trap_init(void) | |||
1680 | signal32_init(); | 1692 | signal32_init(); |
1681 | #endif | 1693 | #endif |
1682 | 1694 | ||
1683 | flush_icache_range(ebase, ebase + 0x400); | 1695 | local_flush_icache_range(ebase, ebase + 0x400); |
1684 | flush_tlb_handlers(); | 1696 | flush_tlb_handlers(); |
1697 | |||
1698 | sort_extable(__start___dbe_table, __stop___dbe_table); | ||
1685 | } | 1699 | } |