traps.c (172ae2e7f8ff9053905a36672453a6d2ff95b182) traps.c (3bffb6529cf10d48a97ac0d6d789986894c25c37)
1/*
2 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *

--- 1020 unchanged lines hidden (view full) ---

1029 }
1030#else
1031 _exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
1032#endif
1033}
1034#endif /* CONFIG_8xx */
1035
1036#ifdef CONFIG_PPC_ADV_DEBUG_REGS
1/*
2 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *

--- 1020 unchanged lines hidden (view full) ---

1029 }
1030#else
1031 _exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
1032#endif
1033}
1034#endif /* CONFIG_8xx */
1035
1036#ifdef CONFIG_PPC_ADV_DEBUG_REGS
1037static void handle_debug(struct pt_regs *regs, unsigned long debug_status)
1038{
1039 int changed = 0;
1040 /*
1041 * Determine the cause of the debug event, clear the
1042 * event flags and send a trap to the handler. Torez
1043 */
1044 if (debug_status & (DBSR_DAC1R | DBSR_DAC1W)) {
1045 dbcr_dac(current) &= ~(DBCR_DAC1R | DBCR_DAC1W);
1046#ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE
1047 current->thread.dbcr2 &= ~DBCR2_DAC12MODE;
1048#endif
1049 do_send_trap(regs, mfspr(SPRN_DAC1), debug_status, TRAP_HWBKPT,
1050 5);
1051 changed |= 0x01;
1052 } else if (debug_status & (DBSR_DAC2R | DBSR_DAC2W)) {
1053 dbcr_dac(current) &= ~(DBCR_DAC2R | DBCR_DAC2W);
1054 do_send_trap(regs, mfspr(SPRN_DAC2), debug_status, TRAP_HWBKPT,
1055 6);
1056 changed |= 0x01;
1057 } else if (debug_status & DBSR_IAC1) {
1058 current->thread.dbcr0 &= ~DBCR0_IAC1;
1059 dbcr_iac_range(current) &= ~DBCR_IAC12MODE;
1060 do_send_trap(regs, mfspr(SPRN_IAC1), debug_status, TRAP_HWBKPT,
1061 1);
1062 changed |= 0x01;
1063 } else if (debug_status & DBSR_IAC2) {
1064 current->thread.dbcr0 &= ~DBCR0_IAC2;
1065 do_send_trap(regs, mfspr(SPRN_IAC2), debug_status, TRAP_HWBKPT,
1066 2);
1067 changed |= 0x01;
1068 } else if (debug_status & DBSR_IAC3) {
1069 current->thread.dbcr0 &= ~DBCR0_IAC3;
1070 dbcr_iac_range(current) &= ~DBCR_IAC34MODE;
1071 do_send_trap(regs, mfspr(SPRN_IAC3), debug_status, TRAP_HWBKPT,
1072 3);
1073 changed |= 0x01;
1074 } else if (debug_status & DBSR_IAC4) {
1075 current->thread.dbcr0 &= ~DBCR0_IAC4;
1076 do_send_trap(regs, mfspr(SPRN_IAC4), debug_status, TRAP_HWBKPT,
1077 4);
1078 changed |= 0x01;
1079 }
1080 /*
1081 * At the point this routine was called, the MSR(DE) was turned off.
1082 * Check all other debug flags and see if that bit needs to be turned
1083 * back on or not.
1084 */
1085 if (DBCR_ACTIVE_EVENTS(current->thread.dbcr0, current->thread.dbcr1))
1086 regs->msr |= MSR_DE;
1087 else
1088 /* Make sure the IDM flag is off */
1089 current->thread.dbcr0 &= ~DBCR0_IDM;
1037
1090
1091 if (changed & 0x01)
1092 mtspr(SPRN_DBCR0, current->thread.dbcr0);
1093}
1094
1038void __kprobes DebugException(struct pt_regs *regs, unsigned long debug_status)
1039{
1095void __kprobes DebugException(struct pt_regs *regs, unsigned long debug_status)
1096{
1097 current->thread.dbsr = debug_status;
1098
1040 /* Hack alert: On BookE, Branch Taken stops on the branch itself, while
1041 * on server, it stops on the target of the branch. In order to simulate
1042 * the server behaviour, we thus restart right away with a single step
1043 * instead of stopping here when hitting a BT
1044 */
1045 if (debug_status & DBSR_BT) {
1046 regs->msr &= ~MSR_DE;
1047

--- 27 unchanged lines hidden (view full) ---

1075 if (notify_die(DIE_SSTEP, "single_step", regs, 5,
1076 5, SIGTRAP) == NOTIFY_STOP) {
1077 return;
1078 }
1079
1080 if (debugger_sstep(regs))
1081 return;
1082
1099 /* Hack alert: On BookE, Branch Taken stops on the branch itself, while
1100 * on server, it stops on the target of the branch. In order to simulate
1101 * the server behaviour, we thus restart right away with a single step
1102 * instead of stopping here when hitting a BT
1103 */
1104 if (debug_status & DBSR_BT) {
1105 regs->msr &= ~MSR_DE;
1106

--- 27 unchanged lines hidden (view full) ---

1134 if (notify_die(DIE_SSTEP, "single_step", regs, 5,
1135 5, SIGTRAP) == NOTIFY_STOP) {
1136 return;
1137 }
1138
1139 if (debugger_sstep(regs))
1140 return;
1141
1083 if (user_mode(regs))
1084 current->thread.dbcr0 &= ~(DBCR0_IC);
1085
1086 _exception(SIGTRAP, regs, TRAP_TRACE, regs->nip);
1087 } else if (debug_status & (DBSR_DAC1R | DBSR_DAC1W)) {
1088 regs->msr &= ~MSR_DE;
1089
1090 if (user_mode(regs)) {
1142 if (user_mode(regs)) {
1091 current->thread.dbcr0 &= ~(DBSR_DAC1R | DBSR_DAC1W |
1092 DBCR0_IDM);
1093 } else {
1094 /* Disable DAC interupts */
1095 mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) & ~(DBSR_DAC1R |
1096 DBSR_DAC1W | DBCR0_IDM));
1097
1098 /* Clear the DAC event */
1099 mtspr(SPRN_DBSR, (DBSR_DAC1R | DBSR_DAC1W));
1143 current->thread.dbcr0 &= ~DBCR0_IC;
1144#ifdef CONFIG_PPC_ADV_DEBUG_REGS
1145 if (DBCR_ACTIVE_EVENTS(current->thread.dbcr0,
1146 current->thread.dbcr1))
1147 regs->msr |= MSR_DE;
1148 else
1149 /* Make sure the IDM bit is off */
1150 current->thread.dbcr0 &= ~DBCR0_IDM;
1151#endif
1100 }
1152 }
1101 /* Setup and send the trap to the handler */
1102 do_dabr(regs, mfspr(SPRN_DAC1), debug_status);
1103 }
1153
1154 _exception(SIGTRAP, regs, TRAP_TRACE, regs->nip);
1155 } else
1156 handle_debug(regs, debug_status);
1104}
1105#endif /* CONFIG_PPC_ADV_DEBUG_REGS */
1106
1107#if !defined(CONFIG_TAU_INT)
1108void TAUException(struct pt_regs *regs)
1109{
1110 printk("TAU trap at PC: %lx, MSR: %lx, vector=%lx %s\n",
1111 regs->nip, regs->msr, regs->trap, print_tainted());

--- 291 unchanged lines hidden ---
1157}
1158#endif /* CONFIG_PPC_ADV_DEBUG_REGS */
1159
1160#if !defined(CONFIG_TAU_INT)
1161void TAUException(struct pt_regs *regs)
1162{
1163 printk("TAU trap at PC: %lx, MSR: %lx, vector=%lx %s\n",
1164 regs->nip, regs->msr, regs->trap, print_tainted());

--- 291 unchanged lines hidden ---