1/* 2 * gdb-low.S contains the low-level trap handler for the GDB stub. 3 * 4 * Copyright (C) 1995 Andreas Busse 5 */ 6#include <linux/sys.h> 7 8#include <asm/asm.h> 9#include <asm/errno.h> 10#include <asm/irqflags.h> 11#include <asm/mipsregs.h> 12#include <asm/regdef.h> 13#include <asm/stackframe.h> 14#include <asm/gdb-stub.h> 15 16#ifdef CONFIG_32BIT 17#define DMFC0 mfc0 18#define DMTC0 mtc0 19#define LDC1 lwc1 20#define SDC1 lwc1 21#endif 22#ifdef CONFIG_64BIT 23#define DMFC0 dmfc0 24#define DMTC0 dmtc0 25#define LDC1 ldc1 26#define SDC1 ldc1 27#endif 28 29/* 30 * [jsun] We reserves about 2x GDB_FR_SIZE in stack. The lower (addressed) 31 * part is used to store registers and passed to exception handler. 32 * The upper part is reserved for "call func" feature where gdb client 33 * saves some of the regs, setups call frame and passes args. 34 * 35 * A trace shows about 200 bytes are used to store about half of all regs. 36 * The rest should be big enough for frame setup and passing args. 37 */ 38 39/* 40 * The low level trap handler 41 */ 42 .align 5 43 NESTED(trap_low, GDB_FR_SIZE, sp) 44 .set noat 45 .set noreorder 46 47 mfc0 k0, CP0_STATUS 48 sll k0, 3 /* extract cu0 bit */ 49 bltz k0, 1f 50 move k1, sp 51 52 /* 53 * Called from user mode, go somewhere else. 54 */ 55 mfc0 k0, CP0_CAUSE 56 andi k0, k0, 0x7c 57#ifdef CONFIG_64BIT 58 dsll k0, k0, 1 59#endif 60 PTR_L k1, saved_vectors(k0) 61 jr k1 62 nop 631: 64 move k0, sp 65 PTR_SUBU sp, k1, GDB_FR_SIZE*2 # see comment above 66 LONG_S k0, GDB_FR_REG29(sp) 67 LONG_S $2, GDB_FR_REG2(sp) 68 69/* 70 * First save the CP0 and special registers 71 */ 72 73 mfc0 v0, CP0_STATUS 74 LONG_S v0, GDB_FR_STATUS(sp) 75 mfc0 v0, CP0_CAUSE 76 LONG_S v0, GDB_FR_CAUSE(sp) 77 DMFC0 v0, CP0_EPC 78 LONG_S v0, GDB_FR_EPC(sp) 79 DMFC0 v0, CP0_BADVADDR 80 LONG_S v0, GDB_FR_BADVADDR(sp) 81 mfhi v0 82 LONG_S v0, GDB_FR_HI(sp) 83 mflo v0 84 LONG_S v0, GDB_FR_LO(sp) 85 86/* 87 * Now the integer registers 88 */ 89 90 LONG_S zero, GDB_FR_REG0(sp) /* I know... */ 91 LONG_S $1, GDB_FR_REG1(sp) 92 /* v0 already saved */ 93 LONG_S $3, GDB_FR_REG3(sp) 94 LONG_S $4, GDB_FR_REG4(sp) 95 LONG_S $5, GDB_FR_REG5(sp) 96 LONG_S $6, GDB_FR_REG6(sp) 97 LONG_S $7, GDB_FR_REG7(sp) 98 LONG_S $8, GDB_FR_REG8(sp) 99 LONG_S $9, GDB_FR_REG9(sp) 100 LONG_S $10, GDB_FR_REG10(sp) 101 LONG_S $11, GDB_FR_REG11(sp) 102 LONG_S $12, GDB_FR_REG12(sp) 103 LONG_S $13, GDB_FR_REG13(sp) 104 LONG_S $14, GDB_FR_REG14(sp) 105 LONG_S $15, GDB_FR_REG15(sp) 106 LONG_S $16, GDB_FR_REG16(sp) 107 LONG_S $17, GDB_FR_REG17(sp) 108 LONG_S $18, GDB_FR_REG18(sp) 109 LONG_S $19, GDB_FR_REG19(sp) 110 LONG_S $20, GDB_FR_REG20(sp) 111 LONG_S $21, GDB_FR_REG21(sp) 112 LONG_S $22, GDB_FR_REG22(sp) 113 LONG_S $23, GDB_FR_REG23(sp) 114 LONG_S $24, GDB_FR_REG24(sp) 115 LONG_S $25, GDB_FR_REG25(sp) 116 LONG_S $26, GDB_FR_REG26(sp) 117 LONG_S $27, GDB_FR_REG27(sp) 118 LONG_S $28, GDB_FR_REG28(sp) 119 /* sp already saved */ 120 LONG_S $30, GDB_FR_REG30(sp) 121 LONG_S $31, GDB_FR_REG31(sp) 122 123 CLI /* disable interrupts */ 124 TRACE_IRQS_OFF 125 126/* 127 * Followed by the floating point registers 128 */ 129 mfc0 v0, CP0_STATUS /* FPU enabled? */ 130 srl v0, v0, 16 131 andi v0, v0, (ST0_CU1 >> 16) 132 133 beqz v0,2f /* disabled, skip */ 134 nop 135 136 SDC1 $0, GDB_FR_FPR0(sp) 137 SDC1 $1, GDB_FR_FPR1(sp) 138 SDC1 $2, GDB_FR_FPR2(sp) 139 SDC1 $3, GDB_FR_FPR3(sp) 140 SDC1 $4, GDB_FR_FPR4(sp) 141 SDC1 $5, GDB_FR_FPR5(sp) 142 SDC1 $6, GDB_FR_FPR6(sp) 143 SDC1 $7, GDB_FR_FPR7(sp) 144 SDC1 $8, GDB_FR_FPR8(sp) 145 SDC1 $9, GDB_FR_FPR9(sp) 146 SDC1 $10, GDB_FR_FPR10(sp) 147 SDC1 $11, GDB_FR_FPR11(sp) 148 SDC1 $12, GDB_FR_FPR12(sp) 149 SDC1 $13, GDB_FR_FPR13(sp) 150 SDC1 $14, GDB_FR_FPR14(sp) 151 SDC1 $15, GDB_FR_FPR15(sp) 152 SDC1 $16, GDB_FR_FPR16(sp) 153 SDC1 $17, GDB_FR_FPR17(sp) 154 SDC1 $18, GDB_FR_FPR18(sp) 155 SDC1 $19, GDB_FR_FPR19(sp) 156 SDC1 $20, GDB_FR_FPR20(sp) 157 SDC1 $21, GDB_FR_FPR21(sp) 158 SDC1 $22, GDB_FR_FPR22(sp) 159 SDC1 $23, GDB_FR_FPR23(sp) 160 SDC1 $24, GDB_FR_FPR24(sp) 161 SDC1 $25, GDB_FR_FPR25(sp) 162 SDC1 $26, GDB_FR_FPR26(sp) 163 SDC1 $27, GDB_FR_FPR27(sp) 164 SDC1 $28, GDB_FR_FPR28(sp) 165 SDC1 $29, GDB_FR_FPR29(sp) 166 SDC1 $30, GDB_FR_FPR30(sp) 167 SDC1 $31, GDB_FR_FPR31(sp) 168 169/* 170 * FPU control registers 171 */ 172 173 cfc1 v0, CP1_STATUS 174 LONG_S v0, GDB_FR_FSR(sp) 175 cfc1 v0, CP1_REVISION 176 LONG_S v0, GDB_FR_FIR(sp) 177 178/* 179 * Current stack frame ptr 180 */ 181 1822: 183 LONG_S sp, GDB_FR_FRP(sp) 184 185/* 186 * CP0 registers (R4000/R4400 unused registers skipped) 187 */ 188 189 mfc0 v0, CP0_INDEX 190 LONG_S v0, GDB_FR_CP0_INDEX(sp) 191 mfc0 v0, CP0_RANDOM 192 LONG_S v0, GDB_FR_CP0_RANDOM(sp) 193 DMFC0 v0, CP0_ENTRYLO0 194 LONG_S v0, GDB_FR_CP0_ENTRYLO0(sp) 195 DMFC0 v0, CP0_ENTRYLO1 196 LONG_S v0, GDB_FR_CP0_ENTRYLO1(sp) 197 DMFC0 v0, CP0_CONTEXT 198 LONG_S v0, GDB_FR_CP0_CONTEXT(sp) 199 mfc0 v0, CP0_PAGEMASK 200 LONG_S v0, GDB_FR_CP0_PAGEMASK(sp) 201 mfc0 v0, CP0_WIRED 202 LONG_S v0, GDB_FR_CP0_WIRED(sp) 203 DMFC0 v0, CP0_ENTRYHI 204 LONG_S v0, GDB_FR_CP0_ENTRYHI(sp) 205 mfc0 v0, CP0_PRID 206 LONG_S v0, GDB_FR_CP0_PRID(sp) 207 208 .set at 209 210/* 211 * Continue with the higher level handler 212 */ 213 214 move a0,sp 215 216 jal handle_exception 217 nop 218 219/* 220 * Restore all writable registers, in reverse order 221 */ 222 223 .set noat 224 225 LONG_L v0, GDB_FR_CP0_ENTRYHI(sp) 226 LONG_L v1, GDB_FR_CP0_WIRED(sp) 227 DMTC0 v0, CP0_ENTRYHI 228 mtc0 v1, CP0_WIRED 229 LONG_L v0, GDB_FR_CP0_PAGEMASK(sp) 230 LONG_L v1, GDB_FR_CP0_ENTRYLO1(sp) 231 mtc0 v0, CP0_PAGEMASK 232 DMTC0 v1, CP0_ENTRYLO1 233 LONG_L v0, GDB_FR_CP0_ENTRYLO0(sp) 234 LONG_L v1, GDB_FR_CP0_INDEX(sp) 235 DMTC0 v0, CP0_ENTRYLO0 236 LONG_L v0, GDB_FR_CP0_CONTEXT(sp) 237 mtc0 v1, CP0_INDEX 238 DMTC0 v0, CP0_CONTEXT 239 240 241/* 242 * Next, the floating point registers 243 */ 244 mfc0 v0, CP0_STATUS /* check if the FPU is enabled */ 245 srl v0, v0, 16 246 andi v0, v0, (ST0_CU1 >> 16) 247 248 beqz v0, 3f /* disabled, skip */ 249 nop 250 251 LDC1 $31, GDB_FR_FPR31(sp) 252 LDC1 $30, GDB_FR_FPR30(sp) 253 LDC1 $29, GDB_FR_FPR29(sp) 254 LDC1 $28, GDB_FR_FPR28(sp) 255 LDC1 $27, GDB_FR_FPR27(sp) 256 LDC1 $26, GDB_FR_FPR26(sp) 257 LDC1 $25, GDB_FR_FPR25(sp) 258 LDC1 $24, GDB_FR_FPR24(sp) 259 LDC1 $23, GDB_FR_FPR23(sp) 260 LDC1 $22, GDB_FR_FPR22(sp) 261 LDC1 $21, GDB_FR_FPR21(sp) 262 LDC1 $20, GDB_FR_FPR20(sp) 263 LDC1 $19, GDB_FR_FPR19(sp) 264 LDC1 $18, GDB_FR_FPR18(sp) 265 LDC1 $17, GDB_FR_FPR17(sp) 266 LDC1 $16, GDB_FR_FPR16(sp) 267 LDC1 $15, GDB_FR_FPR15(sp) 268 LDC1 $14, GDB_FR_FPR14(sp) 269 LDC1 $13, GDB_FR_FPR13(sp) 270 LDC1 $12, GDB_FR_FPR12(sp) 271 LDC1 $11, GDB_FR_FPR11(sp) 272 LDC1 $10, GDB_FR_FPR10(sp) 273 LDC1 $9, GDB_FR_FPR9(sp) 274 LDC1 $8, GDB_FR_FPR8(sp) 275 LDC1 $7, GDB_FR_FPR7(sp) 276 LDC1 $6, GDB_FR_FPR6(sp) 277 LDC1 $5, GDB_FR_FPR5(sp) 278 LDC1 $4, GDB_FR_FPR4(sp) 279 LDC1 $3, GDB_FR_FPR3(sp) 280 LDC1 $2, GDB_FR_FPR2(sp) 281 LDC1 $1, GDB_FR_FPR1(sp) 282 LDC1 $0, GDB_FR_FPR0(sp) 283 284/* 285 * Now the CP0 and integer registers 286 */ 287 2883: 289#ifdef CONFIG_MIPS_MT_SMTC 290 /* Read-modify write of Status must be atomic */ 291 mfc0 t2, CP0_TCSTATUS 292 ori t1, t2, TCSTATUS_IXMT 293 mtc0 t1, CP0_TCSTATUS 294 andi t2, t2, TCSTATUS_IXMT 295 _ehb 296 DMT 9 # dmt t1 297 jal mips_ihb 298 nop 299#endif /* CONFIG_MIPS_MT_SMTC */ 300 mfc0 t0, CP0_STATUS 301 ori t0, 0x1f 302 xori t0, 0x1f 303 mtc0 t0, CP0_STATUS 304#ifdef CONFIG_MIPS_MT_SMTC 305 andi t1, t1, VPECONTROL_TE 306 beqz t1, 9f 307 nop 308 EMT # emt 3099: 310 mfc0 t1, CP0_TCSTATUS 311 xori t1, t1, TCSTATUS_IXMT 312 or t1, t1, t2 313 mtc0 t1, CP0_TCSTATUS 314 _ehb 315#endif /* CONFIG_MIPS_MT_SMTC */ 316 LONG_L v0, GDB_FR_STATUS(sp) 317 LONG_L v1, GDB_FR_EPC(sp) 318 mtc0 v0, CP0_STATUS 319 DMTC0 v1, CP0_EPC 320 LONG_L v0, GDB_FR_HI(sp) 321 LONG_L v1, GDB_FR_LO(sp) 322 mthi v0 323 mtlo v1 324 LONG_L $31, GDB_FR_REG31(sp) 325 LONG_L $30, GDB_FR_REG30(sp) 326 LONG_L $28, GDB_FR_REG28(sp) 327 LONG_L $27, GDB_FR_REG27(sp) 328 LONG_L $26, GDB_FR_REG26(sp) 329 LONG_L $25, GDB_FR_REG25(sp) 330 LONG_L $24, GDB_FR_REG24(sp) 331 LONG_L $23, GDB_FR_REG23(sp) 332 LONG_L $22, GDB_FR_REG22(sp) 333 LONG_L $21, GDB_FR_REG21(sp) 334 LONG_L $20, GDB_FR_REG20(sp) 335 LONG_L $19, GDB_FR_REG19(sp) 336 LONG_L $18, GDB_FR_REG18(sp) 337 LONG_L $17, GDB_FR_REG17(sp) 338 LONG_L $16, GDB_FR_REG16(sp) 339 LONG_L $15, GDB_FR_REG15(sp) 340 LONG_L $14, GDB_FR_REG14(sp) 341 LONG_L $13, GDB_FR_REG13(sp) 342 LONG_L $12, GDB_FR_REG12(sp) 343 LONG_L $11, GDB_FR_REG11(sp) 344 LONG_L $10, GDB_FR_REG10(sp) 345 LONG_L $9, GDB_FR_REG9(sp) 346 LONG_L $8, GDB_FR_REG8(sp) 347 LONG_L $7, GDB_FR_REG7(sp) 348 LONG_L $6, GDB_FR_REG6(sp) 349 LONG_L $5, GDB_FR_REG5(sp) 350 LONG_L $4, GDB_FR_REG4(sp) 351 LONG_L $3, GDB_FR_REG3(sp) 352 LONG_L $2, GDB_FR_REG2(sp) 353 LONG_L $1, GDB_FR_REG1(sp) 354#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) 355 LONG_L k0, GDB_FR_EPC(sp) 356 LONG_L $29, GDB_FR_REG29(sp) /* Deallocate stack */ 357 jr k0 358 rfe 359#else 360 LONG_L sp, GDB_FR_REG29(sp) /* Deallocate stack */ 361 362 .set mips3 363 eret 364 .set mips0 365#endif 366 .set at 367 .set reorder 368 END(trap_low) 369 370LEAF(kgdb_read_byte) 3714: lb t0, (a0) 372 sb t0, (a1) 373 li v0, 0 374 jr ra 375 .section __ex_table,"a" 376 PTR 4b, kgdbfault 377 .previous 378 END(kgdb_read_byte) 379 380LEAF(kgdb_write_byte) 3815: sb a0, (a1) 382 li v0, 0 383 jr ra 384 .section __ex_table,"a" 385 PTR 5b, kgdbfault 386 .previous 387 END(kgdb_write_byte) 388 389 .type kgdbfault@function 390 .ent kgdbfault 391 392kgdbfault: li v0, -EFAULT 393 jr ra 394 .end kgdbfault 395