aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/traps.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel/traps.c')
-rw-r--r--arch/mips/kernel/traps.c318
1 files changed, 226 insertions, 92 deletions
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 25225515451f..77cff1f6d050 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -8,8 +8,8 @@
8 * Copyright (C) 1998 Ulf Carlsson 8 * Copyright (C) 1998 Ulf Carlsson
9 * Copyright (C) 1999 Silicon Graphics, Inc. 9 * Copyright (C) 1999 Silicon Graphics, Inc.
10 * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com 10 * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
11 * Copyright (C) 2000, 01 MIPS Technologies, Inc.
12 * Copyright (C) 2002, 2003, 2004, 2005, 2007 Maciej W. Rozycki 11 * Copyright (C) 2002, 2003, 2004, 2005, 2007 Maciej W. Rozycki
12 * Copyright (C) 2000, 2001, 2012 MIPS Technologies, Inc. All rights reserved.
13 */ 13 */
14#include <linux/bug.h> 14#include <linux/bug.h>
15#include <linux/compiler.h> 15#include <linux/compiler.h>
@@ -60,9 +60,9 @@ extern void check_wait(void);
60extern asmlinkage void r4k_wait(void); 60extern asmlinkage void r4k_wait(void);
61extern asmlinkage void rollback_handle_int(void); 61extern asmlinkage void rollback_handle_int(void);
62extern asmlinkage void handle_int(void); 62extern asmlinkage void handle_int(void);
63extern asmlinkage void handle_tlbm(void); 63extern u32 handle_tlbl[];
64extern asmlinkage void handle_tlbl(void); 64extern u32 handle_tlbs[];
65extern asmlinkage void handle_tlbs(void); 65extern u32 handle_tlbm[];
66extern asmlinkage void handle_adel(void); 66extern asmlinkage void handle_adel(void);
67extern asmlinkage void handle_ades(void); 67extern asmlinkage void handle_ades(void);
68extern asmlinkage void handle_ibe(void); 68extern asmlinkage void handle_ibe(void);
@@ -83,10 +83,6 @@ extern asmlinkage void handle_dsp(void);
83extern asmlinkage void handle_mcheck(void); 83extern asmlinkage void handle_mcheck(void);
84extern asmlinkage void handle_reserved(void); 84extern asmlinkage void handle_reserved(void);
85 85
86extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
87 struct mips_fpu_struct *ctx, int has_fpu,
88 void *__user *fault_addr);
89
90void (*board_be_init)(void); 86void (*board_be_init)(void);
91int (*board_be_handler)(struct pt_regs *regs, int is_fixup); 87int (*board_be_handler)(struct pt_regs *regs, int is_fixup);
92void (*board_nmi_handler_setup)(void); 88void (*board_nmi_handler_setup)(void);
@@ -482,6 +478,12 @@ asmlinkage void do_be(struct pt_regs *regs)
482#define SYNC 0x0000000f 478#define SYNC 0x0000000f
483#define RDHWR 0x0000003b 479#define RDHWR 0x0000003b
484 480
481/* microMIPS definitions */
482#define MM_POOL32A_FUNC 0xfc00ffff
483#define MM_RDHWR 0x00006b3c
484#define MM_RS 0x001f0000
485#define MM_RT 0x03e00000
486
485/* 487/*
486 * The ll_bit is cleared by r*_switch.S 488 * The ll_bit is cleared by r*_switch.S
487 */ 489 */
@@ -596,42 +598,62 @@ static int simulate_llsc(struct pt_regs *regs, unsigned int opcode)
596 * Simulate trapping 'rdhwr' instructions to provide user accessible 598 * Simulate trapping 'rdhwr' instructions to provide user accessible
597 * registers not implemented in hardware. 599 * registers not implemented in hardware.
598 */ 600 */
599static int simulate_rdhwr(struct pt_regs *regs, unsigned int opcode) 601static int simulate_rdhwr(struct pt_regs *regs, int rd, int rt)
600{ 602{
601 struct thread_info *ti = task_thread_info(current); 603 struct thread_info *ti = task_thread_info(current);
602 604
605 perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS,
606 1, regs, 0);
607 switch (rd) {
608 case 0: /* CPU number */
609 regs->regs[rt] = smp_processor_id();
610 return 0;
611 case 1: /* SYNCI length */
612 regs->regs[rt] = min(current_cpu_data.dcache.linesz,
613 current_cpu_data.icache.linesz);
614 return 0;
615 case 2: /* Read count register */
616 regs->regs[rt] = read_c0_count();
617 return 0;
618 case 3: /* Count register resolution */
619 switch (current_cpu_data.cputype) {
620 case CPU_20KC:
621 case CPU_25KF:
622 regs->regs[rt] = 1;
623 break;
624 default:
625 regs->regs[rt] = 2;
626 }
627 return 0;
628 case 29:
629 regs->regs[rt] = ti->tp_value;
630 return 0;
631 default:
632 return -1;
633 }
634}
635
636static int simulate_rdhwr_normal(struct pt_regs *regs, unsigned int opcode)
637{
603 if ((opcode & OPCODE) == SPEC3 && (opcode & FUNC) == RDHWR) { 638 if ((opcode & OPCODE) == SPEC3 && (opcode & FUNC) == RDHWR) {
604 int rd = (opcode & RD) >> 11; 639 int rd = (opcode & RD) >> 11;
605 int rt = (opcode & RT) >> 16; 640 int rt = (opcode & RT) >> 16;
606 perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 641
607 1, regs, 0); 642 simulate_rdhwr(regs, rd, rt);
608 switch (rd) { 643 return 0;
609 case 0: /* CPU number */ 644 }
610 regs->regs[rt] = smp_processor_id(); 645
611 return 0; 646 /* Not ours. */
612 case 1: /* SYNCI length */ 647 return -1;
613 regs->regs[rt] = min(current_cpu_data.dcache.linesz, 648}
614 current_cpu_data.icache.linesz); 649
615 return 0; 650static int simulate_rdhwr_mm(struct pt_regs *regs, unsigned short opcode)
616 case 2: /* Read count register */ 651{
617 regs->regs[rt] = read_c0_count(); 652 if ((opcode & MM_POOL32A_FUNC) == MM_RDHWR) {
618 return 0; 653 int rd = (opcode & MM_RS) >> 16;
619 case 3: /* Count register resolution */ 654 int rt = (opcode & MM_RT) >> 21;
620 switch (current_cpu_data.cputype) { 655 simulate_rdhwr(regs, rd, rt);
621 case CPU_20KC: 656 return 0;
622 case CPU_25KF:
623 regs->regs[rt] = 1;
624 break;
625 default:
626 regs->regs[rt] = 2;
627 }
628 return 0;
629 case 29:
630 regs->regs[rt] = ti->tp_value;
631 return 0;
632 default:
633 return -1;
634 }
635 } 657 }
636 658
637 /* Not ours. */ 659 /* Not ours. */
@@ -662,7 +684,7 @@ asmlinkage void do_ov(struct pt_regs *regs)
662 force_sig_info(SIGFPE, &info, current); 684 force_sig_info(SIGFPE, &info, current);
663} 685}
664 686
665static int process_fpemu_return(int sig, void __user *fault_addr) 687int process_fpemu_return(int sig, void __user *fault_addr)
666{ 688{
667 if (sig == SIGSEGV || sig == SIGBUS) { 689 if (sig == SIGSEGV || sig == SIGBUS) {
668 struct siginfo si = {0}; 690 struct siginfo si = {0};
@@ -813,9 +835,29 @@ static void do_trap_or_bp(struct pt_regs *regs, unsigned int code,
813asmlinkage void do_bp(struct pt_regs *regs) 835asmlinkage void do_bp(struct pt_regs *regs)
814{ 836{
815 unsigned int opcode, bcode; 837 unsigned int opcode, bcode;
816 838 unsigned long epc;
817 if (__get_user(opcode, (unsigned int __user *) exception_epc(regs))) 839 u16 instr[2];
818 goto out_sigsegv; 840
841 if (get_isa16_mode(regs->cp0_epc)) {
842 /* Calculate EPC. */
843 epc = exception_epc(regs);
844 if (cpu_has_mmips) {
845 if ((__get_user(instr[0], (u16 __user *)msk_isa16_mode(epc)) ||
846 (__get_user(instr[1], (u16 __user *)msk_isa16_mode(epc + 2)))))
847 goto out_sigsegv;
848 opcode = (instr[0] << 16) | instr[1];
849 } else {
850 /* MIPS16e mode */
851 if (__get_user(instr[0], (u16 __user *)msk_isa16_mode(epc)))
852 goto out_sigsegv;
853 bcode = (instr[0] >> 6) & 0x3f;
854 do_trap_or_bp(regs, bcode, "Break");
855 return;
856 }
857 } else {
858 if (__get_user(opcode, (unsigned int __user *) exception_epc(regs)))
859 goto out_sigsegv;
860 }
819 861
820 /* 862 /*
821 * There is the ancient bug in the MIPS assemblers that the break 863 * There is the ancient bug in the MIPS assemblers that the break
@@ -856,13 +898,22 @@ out_sigsegv:
856asmlinkage void do_tr(struct pt_regs *regs) 898asmlinkage void do_tr(struct pt_regs *regs)
857{ 899{
858 unsigned int opcode, tcode = 0; 900 unsigned int opcode, tcode = 0;
901 u16 instr[2];
902 unsigned long epc = exception_epc(regs);
859 903
860 if (__get_user(opcode, (unsigned int __user *) exception_epc(regs))) 904 if ((__get_user(instr[0], (u16 __user *)msk_isa16_mode(epc))) ||
861 goto out_sigsegv; 905 (__get_user(instr[1], (u16 __user *)msk_isa16_mode(epc + 2))))
906 goto out_sigsegv;
907 opcode = (instr[0] << 16) | instr[1];
862 908
863 /* Immediate versions don't provide a code. */ 909 /* Immediate versions don't provide a code. */
864 if (!(opcode & OPCODE)) 910 if (!(opcode & OPCODE)) {
865 tcode = ((opcode >> 6) & ((1 << 10) - 1)); 911 if (get_isa16_mode(regs->cp0_epc))
912 /* microMIPS */
913 tcode = (opcode >> 12) & 0x1f;
914 else
915 tcode = ((opcode >> 6) & ((1 << 10) - 1));
916 }
866 917
867 do_trap_or_bp(regs, tcode, "Trap"); 918 do_trap_or_bp(regs, tcode, "Trap");
868 return; 919 return;
@@ -875,6 +926,7 @@ asmlinkage void do_ri(struct pt_regs *regs)
875{ 926{
876 unsigned int __user *epc = (unsigned int __user *)exception_epc(regs); 927 unsigned int __user *epc = (unsigned int __user *)exception_epc(regs);
877 unsigned long old_epc = regs->cp0_epc; 928 unsigned long old_epc = regs->cp0_epc;
929 unsigned long old31 = regs->regs[31];
878 unsigned int opcode = 0; 930 unsigned int opcode = 0;
879 int status = -1; 931 int status = -1;
880 932
@@ -887,23 +939,37 @@ asmlinkage void do_ri(struct pt_regs *regs)
887 if (unlikely(compute_return_epc(regs) < 0)) 939 if (unlikely(compute_return_epc(regs) < 0))
888 return; 940 return;
889 941
890 if (unlikely(get_user(opcode, epc) < 0)) 942 if (get_isa16_mode(regs->cp0_epc)) {
891 status = SIGSEGV; 943 unsigned short mmop[2] = { 0 };
892 944
893 if (!cpu_has_llsc && status < 0) 945 if (unlikely(get_user(mmop[0], epc) < 0))
894 status = simulate_llsc(regs, opcode); 946 status = SIGSEGV;
947 if (unlikely(get_user(mmop[1], epc) < 0))
948 status = SIGSEGV;
949 opcode = (mmop[0] << 16) | mmop[1];
895 950
896 if (status < 0) 951 if (status < 0)
897 status = simulate_rdhwr(regs, opcode); 952 status = simulate_rdhwr_mm(regs, opcode);
953 } else {
954 if (unlikely(get_user(opcode, epc) < 0))
955 status = SIGSEGV;
898 956
899 if (status < 0) 957 if (!cpu_has_llsc && status < 0)
900 status = simulate_sync(regs, opcode); 958 status = simulate_llsc(regs, opcode);
959
960 if (status < 0)
961 status = simulate_rdhwr_normal(regs, opcode);
962
963 if (status < 0)
964 status = simulate_sync(regs, opcode);
965 }
901 966
902 if (status < 0) 967 if (status < 0)
903 status = SIGILL; 968 status = SIGILL;
904 969
905 if (unlikely(status > 0)) { 970 if (unlikely(status > 0)) {
906 regs->cp0_epc = old_epc; /* Undo skip-over. */ 971 regs->cp0_epc = old_epc; /* Undo skip-over. */
972 regs->regs[31] = old31;
907 force_sig(status, current); 973 force_sig(status, current);
908 } 974 }
909} 975}
@@ -973,7 +1039,7 @@ static int default_cu2_call(struct notifier_block *nfb, unsigned long action,
973asmlinkage void do_cpu(struct pt_regs *regs) 1039asmlinkage void do_cpu(struct pt_regs *regs)
974{ 1040{
975 unsigned int __user *epc; 1041 unsigned int __user *epc;
976 unsigned long old_epc; 1042 unsigned long old_epc, old31;
977 unsigned int opcode; 1043 unsigned int opcode;
978 unsigned int cpid; 1044 unsigned int cpid;
979 int status; 1045 int status;
@@ -987,26 +1053,41 @@ asmlinkage void do_cpu(struct pt_regs *regs)
987 case 0: 1053 case 0:
988 epc = (unsigned int __user *)exception_epc(regs); 1054 epc = (unsigned int __user *)exception_epc(regs);
989 old_epc = regs->cp0_epc; 1055 old_epc = regs->cp0_epc;
1056 old31 = regs->regs[31];
990 opcode = 0; 1057 opcode = 0;
991 status = -1; 1058 status = -1;
992 1059
993 if (unlikely(compute_return_epc(regs) < 0)) 1060 if (unlikely(compute_return_epc(regs) < 0))
994 return; 1061 return;
995 1062
996 if (unlikely(get_user(opcode, epc) < 0)) 1063 if (get_isa16_mode(regs->cp0_epc)) {
997 status = SIGSEGV; 1064 unsigned short mmop[2] = { 0 };
998 1065
999 if (!cpu_has_llsc && status < 0) 1066 if (unlikely(get_user(mmop[0], epc) < 0))
1000 status = simulate_llsc(regs, opcode); 1067 status = SIGSEGV;
1068 if (unlikely(get_user(mmop[1], epc) < 0))
1069 status = SIGSEGV;
1070 opcode = (mmop[0] << 16) | mmop[1];
1001 1071
1002 if (status < 0) 1072 if (status < 0)
1003 status = simulate_rdhwr(regs, opcode); 1073 status = simulate_rdhwr_mm(regs, opcode);
1074 } else {
1075 if (unlikely(get_user(opcode, epc) < 0))
1076 status = SIGSEGV;
1077
1078 if (!cpu_has_llsc && status < 0)
1079 status = simulate_llsc(regs, opcode);
1080
1081 if (status < 0)
1082 status = simulate_rdhwr_normal(regs, opcode);
1083 }
1004 1084
1005 if (status < 0) 1085 if (status < 0)
1006 status = SIGILL; 1086 status = SIGILL;
1007 1087
1008 if (unlikely(status > 0)) { 1088 if (unlikely(status > 0)) {
1009 regs->cp0_epc = old_epc; /* Undo skip-over. */ 1089 regs->cp0_epc = old_epc; /* Undo skip-over. */
1090 regs->regs[31] = old31;
1010 force_sig(status, current); 1091 force_sig(status, current);
1011 } 1092 }
1012 1093
@@ -1320,7 +1401,7 @@ asmlinkage void cache_parity_error(void)
1320void ejtag_exception_handler(struct pt_regs *regs) 1401void ejtag_exception_handler(struct pt_regs *regs)
1321{ 1402{
1322 const int field = 2 * sizeof(unsigned long); 1403 const int field = 2 * sizeof(unsigned long);
1323 unsigned long depc, old_epc; 1404 unsigned long depc, old_epc, old_ra;
1324 unsigned int debug; 1405 unsigned int debug;
1325 1406
1326 printk(KERN_DEBUG "SDBBP EJTAG debug exception - not handled yet, just ignored!\n"); 1407 printk(KERN_DEBUG "SDBBP EJTAG debug exception - not handled yet, just ignored!\n");
@@ -1335,10 +1416,12 @@ void ejtag_exception_handler(struct pt_regs *regs)
1335 * calculation. 1416 * calculation.
1336 */ 1417 */
1337 old_epc = regs->cp0_epc; 1418 old_epc = regs->cp0_epc;
1419 old_ra = regs->regs[31];
1338 regs->cp0_epc = depc; 1420 regs->cp0_epc = depc;
1339 __compute_return_epc(regs); 1421 compute_return_epc(regs);
1340 depc = regs->cp0_epc; 1422 depc = regs->cp0_epc;
1341 regs->cp0_epc = old_epc; 1423 regs->cp0_epc = old_epc;
1424 regs->regs[31] = old_ra;
1342 } else 1425 } else
1343 depc += 4; 1426 depc += 4;
1344 write_c0_depc(depc); 1427 write_c0_depc(depc);
@@ -1377,11 +1460,27 @@ unsigned long vi_handlers[64];
1377void __init *set_except_vector(int n, void *addr) 1460void __init *set_except_vector(int n, void *addr)
1378{ 1461{
1379 unsigned long handler = (unsigned long) addr; 1462 unsigned long handler = (unsigned long) addr;
1380 unsigned long old_handler = exception_handlers[n]; 1463 unsigned long old_handler;
1464
1465#ifdef CONFIG_CPU_MICROMIPS
1466 /*
1467 * Only the TLB handlers are cache aligned with an even
1468 * address. All other handlers are on an odd address and
1469 * require no modification. Otherwise, MIPS32 mode will
1470 * be entered when handling any TLB exceptions. That
1471 * would be bad...since we must stay in microMIPS mode.
1472 */
1473 if (!(handler & 0x1))
1474 handler |= 1;
1475#endif
1476 old_handler = xchg(&exception_handlers[n], handler);
1381 1477
1382 exception_handlers[n] = handler;
1383 if (n == 0 && cpu_has_divec) { 1478 if (n == 0 && cpu_has_divec) {
1479#ifdef CONFIG_CPU_MICROMIPS
1480 unsigned long jump_mask = ~((1 << 27) - 1);
1481#else
1384 unsigned long jump_mask = ~((1 << 28) - 1); 1482 unsigned long jump_mask = ~((1 << 28) - 1);
1483#endif
1385 u32 *buf = (u32 *)(ebase + 0x200); 1484 u32 *buf = (u32 *)(ebase + 0x200);
1386 unsigned int k0 = 26; 1485 unsigned int k0 = 26;
1387 if ((handler & jump_mask) == ((ebase + 0x200) & jump_mask)) { 1486 if ((handler & jump_mask) == ((ebase + 0x200) & jump_mask)) {
@@ -1397,7 +1496,7 @@ void __init *set_except_vector(int n, void *addr)
1397 return (void *)old_handler; 1496 return (void *)old_handler;
1398} 1497}
1399 1498
1400static asmlinkage void do_default_vi(void) 1499static void do_default_vi(void)
1401{ 1500{
1402 show_regs(get_irq_regs()); 1501 show_regs(get_irq_regs());
1403 panic("Caught unexpected vectored interrupt."); 1502 panic("Caught unexpected vectored interrupt.");
@@ -1408,17 +1507,18 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
1408 unsigned long handler; 1507 unsigned long handler;
1409 unsigned long old_handler = vi_handlers[n]; 1508 unsigned long old_handler = vi_handlers[n];
1410 int srssets = current_cpu_data.srsets; 1509 int srssets = current_cpu_data.srsets;
1411 u32 *w; 1510 u16 *h;
1412 unsigned char *b; 1511 unsigned char *b;
1413 1512
1414 BUG_ON(!cpu_has_veic && !cpu_has_vint); 1513 BUG_ON(!cpu_has_veic && !cpu_has_vint);
1514 BUG_ON((n < 0) && (n > 9));
1415 1515
1416 if (addr == NULL) { 1516 if (addr == NULL) {
1417 handler = (unsigned long) do_default_vi; 1517 handler = (unsigned long) do_default_vi;
1418 srs = 0; 1518 srs = 0;
1419 } else 1519 } else
1420 handler = (unsigned long) addr; 1520 handler = (unsigned long) addr;
1421 vi_handlers[n] = (unsigned long) addr; 1521 vi_handlers[n] = handler;
1422 1522
1423 b = (unsigned char *)(ebase + 0x200 + n*VECTORSPACING); 1523 b = (unsigned char *)(ebase + 0x200 + n*VECTORSPACING);
1424 1524
@@ -1437,9 +1537,8 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
1437 if (srs == 0) { 1537 if (srs == 0) {
1438 /* 1538 /*
1439 * If no shadow set is selected then use the default handler 1539 * If no shadow set is selected then use the default handler
1440 * that does normal register saving and a standard interrupt exit 1540 * that does normal register saving and standard interrupt exit
1441 */ 1541 */
1442
1443 extern char except_vec_vi, except_vec_vi_lui; 1542 extern char except_vec_vi, except_vec_vi_lui;
1444 extern char except_vec_vi_ori, except_vec_vi_end; 1543 extern char except_vec_vi_ori, except_vec_vi_end;
1445 extern char rollback_except_vec_vi; 1544 extern char rollback_except_vec_vi;
@@ -1452,11 +1551,20 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
1452 * Status.IM bit to be masked before going there. 1551 * Status.IM bit to be masked before going there.
1453 */ 1552 */
1454 extern char except_vec_vi_mori; 1553 extern char except_vec_vi_mori;
1554#if defined(CONFIG_CPU_MICROMIPS) || defined(CONFIG_CPU_BIG_ENDIAN)
1555 const int mori_offset = &except_vec_vi_mori - vec_start + 2;
1556#else
1455 const int mori_offset = &except_vec_vi_mori - vec_start; 1557 const int mori_offset = &except_vec_vi_mori - vec_start;
1558#endif
1456#endif /* CONFIG_MIPS_MT_SMTC */ 1559#endif /* CONFIG_MIPS_MT_SMTC */
1457 const int handler_len = &except_vec_vi_end - vec_start; 1560#if defined(CONFIG_CPU_MICROMIPS) || defined(CONFIG_CPU_BIG_ENDIAN)
1561 const int lui_offset = &except_vec_vi_lui - vec_start + 2;
1562 const int ori_offset = &except_vec_vi_ori - vec_start + 2;
1563#else
1458 const int lui_offset = &except_vec_vi_lui - vec_start; 1564 const int lui_offset = &except_vec_vi_lui - vec_start;
1459 const int ori_offset = &except_vec_vi_ori - vec_start; 1565 const int ori_offset = &except_vec_vi_ori - vec_start;
1566#endif
1567 const int handler_len = &except_vec_vi_end - vec_start;
1460 1568
1461 if (handler_len > VECTORSPACING) { 1569 if (handler_len > VECTORSPACING) {
1462 /* 1570 /*
@@ -1466,30 +1574,44 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
1466 panic("VECTORSPACING too small"); 1574 panic("VECTORSPACING too small");
1467 } 1575 }
1468 1576
1469 memcpy(b, vec_start, handler_len); 1577 set_handler(((unsigned long)b - ebase), vec_start,
1578#ifdef CONFIG_CPU_MICROMIPS
1579 (handler_len - 1));
1580#else
1581 handler_len);
1582#endif
1470#ifdef CONFIG_MIPS_MT_SMTC 1583#ifdef CONFIG_MIPS_MT_SMTC
1471 BUG_ON(n > 7); /* Vector index %d exceeds SMTC maximum. */ 1584 BUG_ON(n > 7); /* Vector index %d exceeds SMTC maximum. */
1472 1585
1473 w = (u32 *)(b + mori_offset); 1586 h = (u16 *)(b + mori_offset);
1474 *w = (*w & 0xffff0000) | (0x100 << n); 1587 *h = (0x100 << n);
1475#endif /* CONFIG_MIPS_MT_SMTC */ 1588#endif /* CONFIG_MIPS_MT_SMTC */
1476 w = (u32 *)(b + lui_offset); 1589 h = (u16 *)(b + lui_offset);
1477 *w = (*w & 0xffff0000) | (((u32)handler >> 16) & 0xffff); 1590 *h = (handler >> 16) & 0xffff;
1478 w = (u32 *)(b + ori_offset); 1591 h = (u16 *)(b + ori_offset);
1479 *w = (*w & 0xffff0000) | ((u32)handler & 0xffff); 1592 *h = (handler & 0xffff);
1480 local_flush_icache_range((unsigned long)b, 1593 local_flush_icache_range((unsigned long)b,
1481 (unsigned long)(b+handler_len)); 1594 (unsigned long)(b+handler_len));
1482 } 1595 }
1483 else { 1596 else {
1484 /* 1597 /*
1485 * In other cases jump directly to the interrupt handler 1598 * In other cases jump directly to the interrupt handler. It
1486 * 1599 * is the handler's responsibility to save registers if required
1487 * It is the handlers responsibility to save registers if required 1600 * (eg hi/lo) and return from the exception using "eret".
1488 * (eg hi/lo) and return from the exception using "eret"
1489 */ 1601 */
1490 w = (u32 *)b; 1602 u32 insn;
1491 *w++ = 0x08000000 | (((u32)handler >> 2) & 0x03fffff); /* j handler */ 1603
1492 *w = 0; 1604 h = (u16 *)b;
1605 /* j handler */
1606#ifdef CONFIG_CPU_MICROMIPS
1607 insn = 0xd4000000 | (((u32)handler & 0x07ffffff) >> 1);
1608#else
1609 insn = 0x08000000 | (((u32)handler & 0x0fffffff) >> 2);
1610#endif
1611 h[0] = (insn >> 16) & 0xffff;
1612 h[1] = insn & 0xffff;
1613 h[2] = 0;
1614 h[3] = 0;
1493 local_flush_icache_range((unsigned long)b, 1615 local_flush_icache_range((unsigned long)b,
1494 (unsigned long)(b+8)); 1616 (unsigned long)(b+8));
1495 } 1617 }
@@ -1534,6 +1656,7 @@ void __cpuinit per_cpu_trap_init(bool is_boot_cpu)
1534 unsigned int cpu = smp_processor_id(); 1656 unsigned int cpu = smp_processor_id();
1535 unsigned int status_set = ST0_CU0; 1657 unsigned int status_set = ST0_CU0;
1536 unsigned int hwrena = cpu_hwrena_impl_bits; 1658 unsigned int hwrena = cpu_hwrena_impl_bits;
1659 unsigned long asid = 0;
1537#ifdef CONFIG_MIPS_MT_SMTC 1660#ifdef CONFIG_MIPS_MT_SMTC
1538 int secondaryTC = 0; 1661 int secondaryTC = 0;
1539 int bootTC = (cpu == 0); 1662 int bootTC = (cpu == 0);
@@ -1617,8 +1740,9 @@ void __cpuinit per_cpu_trap_init(bool is_boot_cpu)
1617 } 1740 }
1618#endif /* CONFIG_MIPS_MT_SMTC */ 1741#endif /* CONFIG_MIPS_MT_SMTC */
1619 1742
1620 if (!cpu_data[cpu].asid_cache) 1743 asid = ASID_FIRST_VERSION;
1621 cpu_data[cpu].asid_cache = ASID_FIRST_VERSION; 1744 cpu_data[cpu].asid_cache = asid;
1745 TLBMISS_HANDLER_SETUP();
1622 1746
1623 atomic_inc(&init_mm.mm_count); 1747 atomic_inc(&init_mm.mm_count);
1624 current->active_mm = &init_mm; 1748 current->active_mm = &init_mm;
@@ -1648,7 +1772,11 @@ void __cpuinit per_cpu_trap_init(bool is_boot_cpu)
1648/* Install CPU exception handler */ 1772/* Install CPU exception handler */
1649void __cpuinit set_handler(unsigned long offset, void *addr, unsigned long size) 1773void __cpuinit set_handler(unsigned long offset, void *addr, unsigned long size)
1650{ 1774{
1775#ifdef CONFIG_CPU_MICROMIPS
1776 memcpy((void *)(ebase + offset), ((unsigned char *)addr - 1), size);
1777#else
1651 memcpy((void *)(ebase + offset), addr, size); 1778 memcpy((void *)(ebase + offset), addr, size);
1779#endif
1652 local_flush_icache_range(ebase + offset, ebase + offset + size); 1780 local_flush_icache_range(ebase + offset, ebase + offset + size);
1653} 1781}
1654 1782
@@ -1682,8 +1810,9 @@ __setup("rdhwr_noopt", set_rdhwr_noopt);
1682 1810
1683void __init trap_init(void) 1811void __init trap_init(void)
1684{ 1812{
1685 extern char except_vec3_generic, except_vec3_r4000; 1813 extern char except_vec3_generic;
1686 extern char except_vec4; 1814 extern char except_vec4;
1815 extern char except_vec3_r4000;
1687 unsigned long i; 1816 unsigned long i;
1688 int rollback; 1817 int rollback;
1689 1818
@@ -1700,7 +1829,12 @@ void __init trap_init(void)
1700 ebase = (unsigned long) 1829 ebase = (unsigned long)
1701 __alloc_bootmem(size, 1 << fls(size), 0); 1830 __alloc_bootmem(size, 1 << fls(size), 0);
1702 } else { 1831 } else {
1703 ebase = CKSEG0; 1832#ifdef CONFIG_KVM_GUEST
1833#define KVM_GUEST_KSEG0 0x40000000
1834 ebase = KVM_GUEST_KSEG0;
1835#else
1836 ebase = CKSEG0;
1837#endif
1704 if (cpu_has_mips_r2) 1838 if (cpu_has_mips_r2)
1705 ebase += (read_c0_ebase() & 0x3ffff000); 1839 ebase += (read_c0_ebase() & 0x3ffff000);
1706 } 1840 }
@@ -1816,11 +1950,11 @@ void __init trap_init(void)
1816 1950
1817 if (cpu_has_vce) 1951 if (cpu_has_vce)
1818 /* Special exception: R4[04]00 uses also the divec space. */ 1952 /* Special exception: R4[04]00 uses also the divec space. */
1819 memcpy((void *)(ebase + 0x180), &except_vec3_r4000, 0x100); 1953 set_handler(0x180, &except_vec3_r4000, 0x100);
1820 else if (cpu_has_4kex) 1954 else if (cpu_has_4kex)
1821 memcpy((void *)(ebase + 0x180), &except_vec3_generic, 0x80); 1955 set_handler(0x180, &except_vec3_generic, 0x80);
1822 else 1956 else
1823 memcpy((void *)(ebase + 0x080), &except_vec3_generic, 0x80); 1957 set_handler(0x080, &except_vec3_generic, 0x80);
1824 1958
1825 local_flush_icache_range(ebase, ebase + 0x400); 1959 local_flush_icache_range(ebase, ebase + 0x400);
1826 flush_tlb_handlers(); 1960 flush_tlb_handlers();