| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* | 
|  | 2 | * gdb-low.S contains the low-level trap handler for the GDB stub. | 
|  | 3 | * | 
|  | 4 | * Copyright (C) 1995 Andreas Busse | 
|  | 5 | */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 6 | #include <linux/sys.h> | 
|  | 7 |  | 
|  | 8 | #include <asm/asm.h> | 
|  | 9 | #include <asm/errno.h> | 
| Ralf Baechle | 192ef36 | 2006-07-07 14:07:18 +0100 | [diff] [blame] | 10 | #include <asm/irqflags.h> | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 11 | #include <asm/mipsregs.h> | 
|  | 12 | #include <asm/regdef.h> | 
|  | 13 | #include <asm/stackframe.h> | 
|  | 14 | #include <asm/gdb-stub.h> | 
|  | 15 |  | 
| Ralf Baechle | 875d43e | 2005-09-03 15:56:16 -0700 | [diff] [blame] | 16 | #ifdef CONFIG_32BIT | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 17 | #define DMFC0	mfc0 | 
|  | 18 | #define DMTC0	mtc0 | 
|  | 19 | #define LDC1	lwc1 | 
|  | 20 | #define SDC1	lwc1 | 
|  | 21 | #endif | 
| Ralf Baechle | 875d43e | 2005-09-03 15:56:16 -0700 | [diff] [blame] | 22 | #ifdef CONFIG_64BIT | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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) | 
| Ralf Baechle | a3dddd5 | 2006-03-11 08:18:41 +0000 | [diff] [blame] | 44 | .set	noat | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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 | */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 55 | mfc0	k0, CP0_CAUSE | 
|  | 56 | andi	k0, k0, 0x7c | 
| Atsushi Nemoto | 867a521 | 2006-05-09 20:23:49 +0900 | [diff] [blame] | 57 | #ifdef CONFIG_64BIT | 
|  | 58 | dsll	k0, k0, 1 | 
|  | 59 | #endif | 
|  | 60 | PTR_L	k1, saved_vectors(k0) | 
|  | 61 | jr	k1 | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 62 | nop | 
|  | 63 | 1: | 
|  | 64 | move	k0, sp | 
| Ralf Baechle | f4c72cc | 2005-10-18 13:25:29 +0100 | [diff] [blame] | 65 | PTR_SUBU sp, k1, GDB_FR_SIZE*2	# see comment above | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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 */ | 
| Ralf Baechle | 192ef36 | 2006-07-07 14:07:18 +0100 | [diff] [blame] | 124 | TRACE_IRQS_OFF | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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 |  | 
|  | 182 | 2: | 
|  | 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 |  | 
|  | 288 | 3: | 
| Ralf Baechle | 41c594a | 2006-04-05 09:45:45 +0100 | [diff] [blame] | 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 | 
| Ralf Baechle | 4277ff5 | 2006-06-03 22:40:15 +0100 | [diff] [blame] | 295 | _ehb | 
| Ralf Baechle | 41c594a | 2006-04-05 09:45:45 +0100 | [diff] [blame] | 296 | DMT	9				# dmt	t1 | 
|  | 297 | jal	mips_ihb | 
|  | 298 | nop | 
|  | 299 | #endif /* CONFIG_MIPS_MT_SMTC */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 300 | mfc0	t0, CP0_STATUS | 
|  | 301 | ori	t0, 0x1f | 
|  | 302 | xori	t0, 0x1f | 
|  | 303 | mtc0	t0, CP0_STATUS | 
| Ralf Baechle | 41c594a | 2006-04-05 09:45:45 +0100 | [diff] [blame] | 304 | #ifdef CONFIG_MIPS_MT_SMTC | 
|  | 305 | andi    t1, t1, VPECONTROL_TE | 
|  | 306 | beqz    t1, 9f | 
|  | 307 | nop | 
|  | 308 | EMT					# emt | 
|  | 309 | 9: | 
|  | 310 | mfc0	t1, CP0_TCSTATUS | 
|  | 311 | xori	t1, t1, TCSTATUS_IXMT | 
|  | 312 | or	t1, t1, t2 | 
|  | 313 | mtc0	t1, CP0_TCSTATUS | 
| Ralf Baechle | 4277ff5 | 2006-06-03 22:40:15 +0100 | [diff] [blame] | 314 | _ehb | 
| Ralf Baechle | 41c594a | 2006-04-05 09:45:45 +0100 | [diff] [blame] | 315 | #endif /* CONFIG_MIPS_MT_SMTC */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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 |  | 
|  | 370 | LEAF(kgdb_read_byte) | 
|  | 371 | 4:		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 |  | 
|  | 380 | LEAF(kgdb_write_byte) | 
|  | 381 | 5:		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 |  | 
|  | 392 | kgdbfault:	li	v0, -EFAULT | 
|  | 393 | jr	ra | 
|  | 394 | .end	kgdbfault |