trap_subr64.S (227386) | trap_subr64.S (230123) |
---|---|
1/* $FreeBSD: head/sys/powerpc/aim/trap_subr64.S 227386 2011-11-09 13:48:23Z nwhitehorn $ */ | 1/* $FreeBSD: head/sys/powerpc/aim/trap_subr64.S 230123 2012-01-15 00:08:14Z nwhitehorn $ */ |
2/* $NetBSD: trap_subr.S,v 1.20 2002/04/22 23:20:08 kleink Exp $ */ 3 4/*- 5 * Copyright (C) 1995, 1996 Wolfgang Solfrank. 6 * Copyright (C) 1995, 1996 TooLs GmbH. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without --- 97 unchanged lines hidden (view full) --- 107 * SPRG3 trap type 108 * savearea r27-r31,DAR,DSISR (DAR & DSISR only for DSI traps) 109 * r28 LR 110 * r29 CR 111 * r30 scratch 112 * r31 scratch 113 * r1 kernel stack 114 * SRR0/1 as at start of trap | 2/* $NetBSD: trap_subr.S,v 1.20 2002/04/22 23:20:08 kleink Exp $ */ 3 4/*- 5 * Copyright (C) 1995, 1996 Wolfgang Solfrank. 6 * Copyright (C) 1995, 1996 TooLs GmbH. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without --- 97 unchanged lines hidden (view full) --- 107 * SPRG3 trap type 108 * savearea r27-r31,DAR,DSISR (DAR & DSISR only for DSI traps) 109 * r28 LR 110 * r29 CR 111 * r30 scratch 112 * r31 scratch 113 * r1 kernel stack 114 * SRR0/1 as at start of trap |
115 * 116 * NOTE: SPRG1 is never used while the MMU is on, making it safe to reuse 117 * in any real-mode fault handler, including those handling double faults. |
|
115 */ 116#define FRAME_SETUP(savearea) \ 117/* Have to enable translation to allow access of kernel stack: */ \ 118 GET_CPUINFO(%r31); \ 119 mfsrr0 %r30; \ 120 std %r30,(savearea+CPUSAVE_SRR0)(%r31); /* save SRR0 */ \ 121 mfsrr1 %r30; \ 122 std %r30,(savearea+CPUSAVE_SRR1)(%r31); /* save SRR1 */ \ | 118 */ 119#define FRAME_SETUP(savearea) \ 120/* Have to enable translation to allow access of kernel stack: */ \ 121 GET_CPUINFO(%r31); \ 122 mfsrr0 %r30; \ 123 std %r30,(savearea+CPUSAVE_SRR0)(%r31); /* save SRR0 */ \ 124 mfsrr1 %r30; \ 125 std %r30,(savearea+CPUSAVE_SRR1)(%r31); /* save SRR1 */ \ |
126 mfsprg1 %r31; /* get saved SP (clears SPRG1) */ \ |
|
123 mfmsr %r30; \ 124 ori %r30,%r30,(PSL_DR|PSL_IR|PSL_RI)@l; /* relocation on */ \ 125 mtmsr %r30; /* stack can now be accessed */ \ 126 isync; \ | 127 mfmsr %r30; \ 128 ori %r30,%r30,(PSL_DR|PSL_IR|PSL_RI)@l; /* relocation on */ \ 129 mtmsr %r30; /* stack can now be accessed */ \ 130 isync; \ |
127 mfsprg1 %r31; /* get saved SP */ \ | |
128 stdu %r31,-(FRAMELEN+288)(%r1); /* save it in the callframe */ \ 129 std %r0, FRAME_0+48(%r1); /* save r0 in the trapframe */ \ 130 std %r31,FRAME_1+48(%r1); /* save SP " " */ \ 131 std %r2, FRAME_2+48(%r1); /* save r2 " " */ \ 132 std %r28,FRAME_LR+48(%r1); /* save LR " " */ \ 133 std %r29,FRAME_CR+48(%r1); /* save CR " " */ \ 134 GET_CPUINFO(%r2); \ 135 ld %r27,(savearea+CPUSAVE_R27)(%r2); /* get saved r27 */ \ --- 60 unchanged lines hidden (view full) --- 196 ld %r6,FRAME_LR+48(%r1); \ 197 GET_CPUINFO(%r7); \ 198 std %r2,(savearea+CPUSAVE_SRR0)(%r7); /* save SRR0 */ \ 199 std %r3,(savearea+CPUSAVE_SRR1)(%r7); /* save SRR1 */ \ 200 ld %r7,FRAME_CR+48(%r1); \ 201 mtctr %r4; \ 202 mtxer %r5; \ 203 mtlr %r6; \ | 131 stdu %r31,-(FRAMELEN+288)(%r1); /* save it in the callframe */ \ 132 std %r0, FRAME_0+48(%r1); /* save r0 in the trapframe */ \ 133 std %r31,FRAME_1+48(%r1); /* save SP " " */ \ 134 std %r2, FRAME_2+48(%r1); /* save r2 " " */ \ 135 std %r28,FRAME_LR+48(%r1); /* save LR " " */ \ 136 std %r29,FRAME_CR+48(%r1); /* save CR " " */ \ 137 GET_CPUINFO(%r2); \ 138 ld %r27,(savearea+CPUSAVE_R27)(%r2); /* get saved r27 */ \ --- 60 unchanged lines hidden (view full) --- 199 ld %r6,FRAME_LR+48(%r1); \ 200 GET_CPUINFO(%r7); \ 201 std %r2,(savearea+CPUSAVE_SRR0)(%r7); /* save SRR0 */ \ 202 std %r3,(savearea+CPUSAVE_SRR1)(%r7); /* save SRR1 */ \ 203 ld %r7,FRAME_CR+48(%r1); \ 204 mtctr %r4; \ 205 mtxer %r5; \ 206 mtlr %r6; \ |
204 mtsprg1 %r7; /* save cr */ \ | 207 mtsprg2 %r7; /* save cr */ \ |
205 ld %r31,FRAME_31+48(%r1); /* restore r0-31 */ \ 206 ld %r30,FRAME_30+48(%r1); \ 207 ld %r29,FRAME_29+48(%r1); \ 208 ld %r28,FRAME_28+48(%r1); \ 209 ld %r27,FRAME_27+48(%r1); \ 210 ld %r26,FRAME_26+48(%r1); \ 211 ld %r25,FRAME_25+48(%r1); \ 212 ld %r24,FRAME_24+48(%r1); \ --- 17 unchanged lines hidden (view full) --- 230 ld %r6, FRAME_6+48(%r1); \ 231 ld %r5, FRAME_5+48(%r1); \ 232 ld %r4, FRAME_4+48(%r1); \ 233 ld %r3, FRAME_3+48(%r1); \ 234 ld %r2, FRAME_2+48(%r1); \ 235 ld %r0, FRAME_0+48(%r1); \ 236 ld %r1, FRAME_1+48(%r1); \ 237/* Can't touch %r1 from here on */ \ | 208 ld %r31,FRAME_31+48(%r1); /* restore r0-31 */ \ 209 ld %r30,FRAME_30+48(%r1); \ 210 ld %r29,FRAME_29+48(%r1); \ 211 ld %r28,FRAME_28+48(%r1); \ 212 ld %r27,FRAME_27+48(%r1); \ 213 ld %r26,FRAME_26+48(%r1); \ 214 ld %r25,FRAME_25+48(%r1); \ 215 ld %r24,FRAME_24+48(%r1); \ --- 17 unchanged lines hidden (view full) --- 233 ld %r6, FRAME_6+48(%r1); \ 234 ld %r5, FRAME_5+48(%r1); \ 235 ld %r4, FRAME_4+48(%r1); \ 236 ld %r3, FRAME_3+48(%r1); \ 237 ld %r2, FRAME_2+48(%r1); \ 238 ld %r0, FRAME_0+48(%r1); \ 239 ld %r1, FRAME_1+48(%r1); \ 240/* Can't touch %r1 from here on */ \ |
238 mtsprg2 %r2; /* save r2 & r3 */ \ 239 mtsprg3 %r3; \ | 241 mtsprg3 %r3; /* save r3 */ \ |
240/* Disable translation, machine check and recoverability: */ \ | 242/* Disable translation, machine check and recoverability: */ \ |
241 mfmsr %r2; \ 242 andi. %r2,%r2,~(PSL_DR|PSL_IR|PSL_ME|PSL_RI)@l; \ 243 mtmsr %r2; \ | 243 mfmsr %r3; \ 244 andi. %r3,%r3,~(PSL_DR|PSL_IR|PSL_ME|PSL_RI)@l; \ 245 mtmsr %r3; \ |
244 isync; \ 245/* Decide whether we return to user mode: */ \ | 246 isync; \ 247/* Decide whether we return to user mode: */ \ |
246 GET_CPUINFO(%r2); \ 247 ld %r3,(savearea+CPUSAVE_SRR1)(%r2); \ | 248 GET_CPUINFO(%r3); \ 249 ld %r3,(savearea+CPUSAVE_SRR1)(%r3); \ |
248 mtcr %r3; \ 249 bf 17,1f; /* branch if PSL_PR is false */ \ 250/* Restore user SRs */ \ 251 GET_CPUINFO(%r3); \ 252 std %r27,(savearea+CPUSAVE_R27)(%r3); \ 253 std %r28,(savearea+CPUSAVE_R28)(%r3); \ 254 std %r29,(savearea+CPUSAVE_R29)(%r3); \ 255 std %r30,(savearea+CPUSAVE_R30)(%r3); \ 256 std %r31,(savearea+CPUSAVE_R31)(%r3); \ 257 mflr %r27; /* preserve LR */ \ 258 bl restore_usersrs; /* uses r28-r31 */ \ 259 mtlr %r27; \ 260 ld %r31,(savearea+CPUSAVE_R31)(%r3); \ 261 ld %r30,(savearea+CPUSAVE_R30)(%r3); \ 262 ld %r29,(savearea+CPUSAVE_R29)(%r3); \ 263 ld %r28,(savearea+CPUSAVE_R28)(%r3); \ 264 ld %r27,(savearea+CPUSAVE_R27)(%r3); \ | 250 mtcr %r3; \ 251 bf 17,1f; /* branch if PSL_PR is false */ \ 252/* Restore user SRs */ \ 253 GET_CPUINFO(%r3); \ 254 std %r27,(savearea+CPUSAVE_R27)(%r3); \ 255 std %r28,(savearea+CPUSAVE_R28)(%r3); \ 256 std %r29,(savearea+CPUSAVE_R29)(%r3); \ 257 std %r30,(savearea+CPUSAVE_R30)(%r3); \ 258 std %r31,(savearea+CPUSAVE_R31)(%r3); \ 259 mflr %r27; /* preserve LR */ \ 260 bl restore_usersrs; /* uses r28-r31 */ \ 261 mtlr %r27; \ 262 ld %r31,(savearea+CPUSAVE_R31)(%r3); \ 263 ld %r30,(savearea+CPUSAVE_R30)(%r3); \ 264 ld %r29,(savearea+CPUSAVE_R29)(%r3); \ 265 ld %r28,(savearea+CPUSAVE_R28)(%r3); \ 266 ld %r27,(savearea+CPUSAVE_R27)(%r3); \ |
2651: mfsprg1 %r2; /* restore cr */ \ 266 mtcr %r2; \ 267 GET_CPUINFO(%r2); \ 268 ld %r3,(savearea+CPUSAVE_SRR0)(%r2); /* restore srr0 */ \ | 2671: mfsprg2 %r3; /* restore cr */ \ 268 mtcr %r3; \ 269 GET_CPUINFO(%r3); \ 270 ld %r3,(savearea+CPUSAVE_SRR0)(%r3); /* restore srr0 */ \ |
269 mtsrr0 %r3; \ | 271 mtsrr0 %r3; \ |
270 ld %r3,(savearea+CPUSAVE_SRR1)(%r2); /* restore srr1 */ \ | 272 GET_CPUINFO(%r3); \ 273 ld %r3,(savearea+CPUSAVE_SRR1)(%r3); /* restore srr1 */ \ |
271 mtsrr1 %r3; \ | 274 mtsrr1 %r3; \ |
272 mfsprg2 %r2; /* restore r2 & r3 */ \ 273 mfsprg3 %r3 | 275 mfsprg3 %r3 /* restore r3 */ |
274 275#ifdef SMP 276/* 277 * Processor reset exception handler. These are typically 278 * the first instructions the processor executes after a 279 * software reset. We do this in two bits so that we are 280 * not still hanging around in the trap handling region 281 * once the MMU is turned on. --- 43 unchanged lines hidden (view full) --- 325 mtsprg1 %r1 /* save SP */ 326 mflr %r1 /* Save the old LR in r1 */ 327 mtsprg2 %r1 /* And then in SPRG2 */ 328 li %r1, 0xA0 /* How to get the vector from LR */ 329 bla generictrap /* LR & SPRG3 is exception # */ 330CNAME(trapsize) = .-CNAME(trapcode) 331 332/* | 276 277#ifdef SMP 278/* 279 * Processor reset exception handler. These are typically 280 * the first instructions the processor executes after a 281 * software reset. We do this in two bits so that we are 282 * not still hanging around in the trap handling region 283 * once the MMU is turned on. --- 43 unchanged lines hidden (view full) --- 327 mtsprg1 %r1 /* save SP */ 328 mflr %r1 /* Save the old LR in r1 */ 329 mtsprg2 %r1 /* And then in SPRG2 */ 330 li %r1, 0xA0 /* How to get the vector from LR */ 331 bla generictrap /* LR & SPRG3 is exception # */ 332CNAME(trapsize) = .-CNAME(trapcode) 333 334/* |
335 * For SLB misses: do special things for the kernel 336 * 337 * Note: SPRG1 is always safe to overwrite any time the MMU is on, which is 338 * the only time this can be called. 339 */ 340 .globl CNAME(slbtrap),CNAME(slbtrapsize) 341CNAME(slbtrap): 342 mtsprg1 %r1 /* save SP */ 343 GET_CPUINFO(%r1) 344 std %r2,(PC_SLBSAVE+16)(%r1) 345 mfcr %r2 /* save CR */ 346 std %r2,(PC_SLBSAVE+104)(%r1) 347 mfsrr1 %r2 /* test kernel mode */ 348 mtcr %r2 349 bf 17,1f /* branch if PSL_PR is false */ 350 /* User mode */ 351 ld %r2,(PC_SLBSAVE+104)(%r1) /* Restore CR */ 352 mtcr %r2 353 ld %r2,(PC_SLBSAVE+16)(%r1) /* Restore R2 */ 354 mflr %r1 /* Save the old LR in r1 */ 355 mtsprg2 %r1 /* And then in SPRG2 */ 356 li %r1, 0x80 /* How to get the vector from LR */ 357 bla generictrap /* LR & SPRG3 is exception # */ 3581: mflr %r2 /* Save the old LR in r2 */ 359 bla kern_slbtrap 360CNAME(slbtrapsize) = .-CNAME(slbtrap) 361 362kern_slbtrap: 363 std %r2,(PC_SLBSAVE+136)(%r1) /* old LR */ 364 std %r3,(PC_SLBSAVE+24)(%r1) /* save R3 */ 365 366 /* Check if this needs to be handled as a regular trap (userseg miss) */ 367 mflr %r2 368 andi. %r2,%r2,0xff80 369 cmpwi %r2,0x380 370 bne 1f 371 mfdar %r2 372 b 2f 3731: mfsrr0 %r2 3742: /* r2 now contains the fault address */ 375 lis %r3,SEGMENT_MASK@highesta 376 ori %r3,%r3,SEGMENT_MASK@highera 377 sldi %r3,%r3,32 378 oris %r3,%r3,SEGMENT_MASK@ha 379 ori %r3,%r3,SEGMENT_MASK@l 380 and %r2,%r2,%r3 /* R2 = segment base address */ 381 lis %r3,USER_ADDR@highesta 382 ori %r3,%r3,USER_ADDR@highera 383 sldi %r3,%r3,32 384 oris %r3,%r3,USER_ADDR@ha 385 ori %r3,%r3,USER_ADDR@l 386 cmpd %r2,%r3 /* Compare fault base to USER_ADDR */ 387 bne 3f 388 389 /* User seg miss, handle as a regular trap */ 390 ld %r2,(PC_SLBSAVE+104)(%r1) /* Restore CR */ 391 mtcr %r2 392 ld %r2,(PC_SLBSAVE+16)(%r1) /* Restore R2,R3 */ 393 ld %r3,(PC_SLBSAVE+24)(%r1) 394 ld %r1,(PC_SLBSAVE+136)(%r1) /* Save the old LR in r1 */ 395 mtsprg2 %r1 /* And then in SPRG2 */ 396 li %r1, 0x80 /* How to get the vector from LR */ 397 b generictrap /* Retain old LR using b */ 398 3993: /* Real kernel SLB miss */ 400 std %r0,(PC_SLBSAVE+0)(%r1) /* free all volatile regs */ 401 mfsprg1 %r2 /* Old R1 */ 402 std %r2,(PC_SLBSAVE+8)(%r1) 403 /* R2,R3 already saved */ 404 std %r4,(PC_SLBSAVE+32)(%r1) 405 std %r5,(PC_SLBSAVE+40)(%r1) 406 std %r6,(PC_SLBSAVE+48)(%r1) 407 std %r7,(PC_SLBSAVE+56)(%r1) 408 std %r8,(PC_SLBSAVE+64)(%r1) 409 std %r9,(PC_SLBSAVE+72)(%r1) 410 std %r10,(PC_SLBSAVE+80)(%r1) 411 std %r11,(PC_SLBSAVE+88)(%r1) 412 std %r12,(PC_SLBSAVE+96)(%r1) 413 /* CR already saved */ 414 mfxer %r2 /* save XER */ 415 std %r2,(PC_SLBSAVE+112)(%r1) 416 mflr %r2 /* save LR (SP already saved) */ 417 std %r2,(PC_SLBSAVE+120)(%r1) 418 mfctr %r2 /* save CTR */ 419 std %r2,(PC_SLBSAVE+128)(%r1) 420 421 /* Call handler */ 422 addi %r1,%r1,PC_SLBSTACK-48+1024 423 li %r2,~15 424 and %r1,%r1,%r2 425 lis %r3,tocbase@ha 426 ld %r2,tocbase@l(%r3) 427 mflr %r3 428 andi. %r3,%r3,0xff80 429 mfdar %r4 430 mfsrr0 %r5 431 bl handle_kernel_slb_spill 432 nop 433 434 /* Save r28-31, restore r4-r12 */ 435 GET_CPUINFO(%r1) 436 ld %r4,(PC_SLBSAVE+32)(%r1) 437 ld %r5,(PC_SLBSAVE+40)(%r1) 438 ld %r6,(PC_SLBSAVE+48)(%r1) 439 ld %r7,(PC_SLBSAVE+56)(%r1) 440 ld %r8,(PC_SLBSAVE+64)(%r1) 441 ld %r9,(PC_SLBSAVE+72)(%r1) 442 ld %r10,(PC_SLBSAVE+80)(%r1) 443 ld %r11,(PC_SLBSAVE+88)(%r1) 444 ld %r12,(PC_SLBSAVE+96)(%r1) 445 std %r28,(PC_SLBSAVE+64)(%r1) 446 std %r29,(PC_SLBSAVE+72)(%r1) 447 std %r30,(PC_SLBSAVE+80)(%r1) 448 std %r31,(PC_SLBSAVE+88)(%r1) 449 450 /* Restore kernel mapping */ 451 bl restore_kernsrs 452 453 /* Restore remaining registers */ 454 ld %r28,(PC_SLBSAVE+64)(%r1) 455 ld %r29,(PC_SLBSAVE+72)(%r1) 456 ld %r30,(PC_SLBSAVE+80)(%r1) 457 ld %r31,(PC_SLBSAVE+88)(%r1) 458 459 ld %r2,(PC_SLBSAVE+104)(%r1) 460 mtcr %r2 461 ld %r2,(PC_SLBSAVE+112)(%r1) 462 mtxer %r2 463 ld %r2,(PC_SLBSAVE+120)(%r1) 464 mtlr %r2 465 ld %r2,(PC_SLBSAVE+128)(%r1) 466 mtctr %r2 467 ld %r2,(PC_SLBSAVE+136)(%r1) 468 mtlr %r2 469 470 /* Restore r0-r3 */ 471 ld %r0,(PC_SLBSAVE+0)(%r1) 472 ld %r2,(PC_SLBSAVE+16)(%r1) 473 ld %r3,(PC_SLBSAVE+24)(%r1) 474 mfsprg1 %r1 475 476 /* Back to whatever we were doing */ 477 rfid 478 479/* |
|
333 * For ALI: has to save DSISR and DAR 334 */ 335 .globl CNAME(alitrap),CNAME(alisize) 336CNAME(alitrap): 337 mtsprg1 %r1 /* save SP */ 338 GET_CPUINFO(%r1) 339 std %r27,(PC_TEMPSAVE+CPUSAVE_R27)(%r1) /* free r27-r31 */ 340 std %r28,(PC_TEMPSAVE+CPUSAVE_R28)(%r1) --- 313 unchanged lines hidden --- | 480 * For ALI: has to save DSISR and DAR 481 */ 482 .globl CNAME(alitrap),CNAME(alisize) 483CNAME(alitrap): 484 mtsprg1 %r1 /* save SP */ 485 GET_CPUINFO(%r1) 486 std %r27,(PC_TEMPSAVE+CPUSAVE_R27)(%r1) /* free r27-r31 */ 487 std %r28,(PC_TEMPSAVE+CPUSAVE_R28)(%r1) --- 313 unchanged lines hidden --- |