diff --git a/sys/powerpc/aim/machdep.c b/sys/powerpc/aim/machdep.c index d0aac4c7f466..b463c48bee2d 100644 --- a/sys/powerpc/aim/machdep.c +++ b/sys/powerpc/aim/machdep.c @@ -238,7 +238,7 @@ extern void *trapcode64; #endif extern void *rstcode, *rstsize; -extern void *trapcode, *trapsize; +extern void *trapcode, *trapsize, *trapcode2; extern void *slbtrap, *slbtrapsize; extern void *alitrap, *alisize; extern void *dsitrap, *dsisize; @@ -506,6 +506,7 @@ powerpc_init(vm_offset_t fdt, vm_offset_t toc, vm_offset_t ofentry, void *mdp) generictrap = &trapcode; /* Set TOC base so that the interrupt code can get at it */ + *((void **)TRAP_GENTRAP) = &trapcode2; *((register_t *)TRAP_TOCBASE) = toc; #endif diff --git a/sys/powerpc/aim/trap_subr64.S b/sys/powerpc/aim/trap_subr64.S index 63ca50a4bfe3..a2d5bc5b1b40 100644 --- a/sys/powerpc/aim/trap_subr64.S +++ b/sys/powerpc/aim/trap_subr64.S @@ -302,8 +302,13 @@ CNAME(rstcode): insrdi %r9,%r8,1,0 mtmsrd %r9 isync + bl 1f + .llong cpu_reset +1: mflr %r9 + ld %r9,0(%r9) + mtlr %r9 - ba cpu_reset + blr CNAME(rstsize) = . - CNAME(rstcode) cpu_reset: @@ -342,16 +347,20 @@ cpu_reset: /* * This code gets copied to all the trap vectors - * (except ISI/DSI, ALI, and the interrupts) + * (except ISI/DSI, ALI, and the interrupts). Has to fit in 8 instructions! */ .globl CNAME(trapcode),CNAME(trapsize) + .p2align 3 CNAME(trapcode): mtsprg1 %r1 /* save SP */ mflr %r1 /* Save the old LR in r1 */ mtsprg2 %r1 /* And then in SPRG2 */ + li %r1,TRAP_GENTRAP + ld %r1,0(%r1) + mtlr %r1 li %r1, 0xA0 /* How to get the vector from LR */ - bla generictrap /* LR & SPRG3 is exception # */ + blrl /* Branch to generictrap */ CNAME(trapsize) = .-CNAME(trapcode) /* @@ -361,6 +370,7 @@ CNAME(trapsize) = .-CNAME(trapcode) * the only time this can be called. */ .globl CNAME(slbtrap),CNAME(slbtrapsize) + .p2align 3 CNAME(slbtrap): mtsprg1 %r1 /* save SP */ GET_CPUINFO(%r1) @@ -369,17 +379,31 @@ CNAME(slbtrap): std %r2,(PC_SLBSAVE+104)(%r1) mfsrr1 %r2 /* test kernel mode */ mtcr %r2 - bf 17,1f /* branch if PSL_PR is false */ + bf 17,2f /* branch if PSL_PR is false */ /* User mode */ ld %r2,(PC_SLBSAVE+104)(%r1) /* Restore CR */ mtcr %r2 ld %r2,(PC_SLBSAVE+16)(%r1) /* Restore R2 */ mflr %r1 /* Save the old LR in r1 */ mtsprg2 %r1 /* And then in SPRG2 */ + /* 52 bytes so far */ + bl 1f + .llong generictrap +1: mflr %r1 + ld %r1,0(%r1) + mtlr %r1 li %r1, 0x80 /* How to get the vector from LR */ - bla generictrap /* LR & SPRG3 is exception # */ -1: mflr %r2 /* Save the old LR in r2 */ - bla kern_slbtrap + blrl /* Branch to generictrap */ + /* 84 bytes */ +2: mflr %r2 /* Save the old LR in r2 */ + nop + bl 3f /* Begin dance to jump to kern_slbtrap*/ + .llong kern_slbtrap +3: mflr %r1 + ld %r1,0(%r1) + mtlr %r1 + GET_CPUINFO(%r1) + blrl /* 124 bytes -- 4 to spare */ CNAME(slbtrapsize) = .-CNAME(slbtrap) kern_slbtrap: @@ -518,6 +542,16 @@ CNAME(alitrap): mflr %r28 /* save LR */ mfcr %r29 /* save CR */ + /* Begin dance to branch to s_trap in a bit */ + b 1f + .p2align 3 +1: nop + bl 1f + .llong s_trap +1: mflr %r31 + ld %r31,0(%r31) + mtlr %r31 + /* Put our exception vector in SPRG3 */ li %r31, EXC_ALI mtsprg3 %r31 @@ -525,13 +559,12 @@ CNAME(alitrap): /* Test whether we already had PR set */ mfsrr1 %r31 mtcr %r31 - bla s_trap + blrl CNAME(alisize) = .-CNAME(alitrap) /* * Similar to the above for DSI - * Has to handle BAT spills - * and standard pagetable spills + * Has to handle standard pagetable spills */ .globl CNAME(dsitrap),CNAME(dsisize) CNAME(dsitrap): @@ -542,14 +575,18 @@ CNAME(dsitrap): std %r29,(PC_DISISAVE+CPUSAVE_R29)(%r1) std %r30,(PC_DISISAVE+CPUSAVE_R30)(%r1) std %r31,(PC_DISISAVE+CPUSAVE_R31)(%r1) - mfsprg1 %r1 /* restore SP */ mfcr %r29 /* save CR */ mfxer %r30 /* save XER */ mtsprg2 %r30 /* in SPRG2 */ mfsrr1 %r31 /* test kernel mode */ mtcr %r31 mflr %r28 /* save LR (SP already saved) */ - bla disitrap + bl 1f /* Begin branching to disitrap */ + .llong disitrap +1: mflr %r1 + ld %r1,0(%r1) + mtlr %r1 + blrl /* Branch to generictrap */ CNAME(dsisize) = .-CNAME(dsitrap) /* @@ -624,7 +661,7 @@ realtrap: bl restore_kernsrs /* enable kernel mapping */ mfsprg2 %r29 mr %r28,%r27 - ba s_trap + b s_trap /* * generictrap does some standard setup for trap handling to minimize @@ -636,6 +673,8 @@ realtrap: * SPRG2 - Original LR */ + .globl CNAME(trapcode2) +trapcode2: generictrap: /* Save R1 for computing the exception vector */ mtsprg3 %r1 @@ -657,6 +696,7 @@ generictrap: mfsprg3 %r31 ori %r31,%r31,0xff00 mflr %r30 + addi %r30,%r30,-4 /* The branch instruction, not the next */ and %r30,%r30,%r31 mtsprg3 %r30 @@ -804,9 +844,16 @@ CNAME(dblow): mfsprg2 %r29 /* ... and r29 */ mflr %r1 /* save LR */ mtsprg2 %r1 /* And then in SPRG2 */ - li %r1, 0 /* How to get the vector from LR */ - bla generictrap /* and we look like a generic trap */ + nop /* Begin branching to generictrap */ + bl 9f + .llong generictrap +9: mflr %r1 + ld %r1,0(%r1) + mtlr %r1 + li %r1, 0 /* How to get the vector from LR */ + blrl /* Branch to generictrap */ + 1: GET_CPUINFO(%r1) std %r27,(PC_DBSAVE+CPUSAVE_R27)(%r1) /* free r27 */ @@ -816,6 +863,11 @@ CNAME(dblow): std %r30,(PC_DBSAVE+CPUSAVE_R30)(%r1) /* free r30 */ std %r31,(PC_DBSAVE+CPUSAVE_R31)(%r1) /* free r31 */ mflr %r28 /* save LR */ - bla dbtrap + bl 9f /* Begin branch */ + .llong dbtrap +9: mflr %r1 + ld %r1,0(%r1) + mtlr %r1 + blrl /* Branch to generictrap */ CNAME(dbsize) = .-CNAME(dblow) #endif /* KDB */ diff --git a/sys/powerpc/include/trap.h b/sys/powerpc/include/trap.h index 3b1ade582e10..cd5ac188fd59 100644 --- a/sys/powerpc/include/trap.h +++ b/sys/powerpc/include/trap.h @@ -123,7 +123,8 @@ /* DTrace trap opcode. */ #define EXC_DTRACE 0x7c810808 -/* Magic pointer to store TOC base for trap handlers on ppc64 */ +/* Magic pointer to store TOC base and other info for trap handlers on ppc64 */ +#define TRAP_GENTRAP 0x1f0 #define TRAP_TOCBASE 0x1f8 #ifndef LOCORE