diff options
author | nwhitehorn <nwhitehorn@FreeBSD.org> | 2015-03-07 20:14:46 +0000 |
---|---|---|
committer | nwhitehorn <nwhitehorn@FreeBSD.org> | 2015-03-07 20:14:46 +0000 |
commit | fd67077071422de4142fee1a503eb3f51ae23a26 (patch) | |
tree | 4f8a9355bf11c3502e46145775f18a5dc72d52f1 /sys/powerpc/aim | |
parent | 4388fb8eb58edb77cefd62079e82719ee96cc09e (diff) | |
download | FreeBSD-src-fd67077071422de4142fee1a503eb3f51ae23a26.zip FreeBSD-src-fd67077071422de4142fee1a503eb3f51ae23a26.tar.gz |
Make 32-bit PowerPC kernels, like 64-bit PowerPC kernels, position-independent
executables. The goal here, not yet accomplished, is to let the e500 kernel
run under QEMU by setting KERNBASE to something that fits in low memory and
then having the kernel relocate itself at runtime.
Diffstat (limited to 'sys/powerpc/aim')
-rw-r--r-- | sys/powerpc/aim/locore32.S | 57 | ||||
-rw-r--r-- | sys/powerpc/aim/machdep.c | 28 | ||||
-rw-r--r-- | sys/powerpc/aim/trap_subr32.S | 91 | ||||
-rw-r--r-- | sys/powerpc/aim/trap_subr64.S | 3 |
4 files changed, 106 insertions, 73 deletions
diff --git a/sys/powerpc/aim/locore32.S b/sys/powerpc/aim/locore32.S index a2cb102..477ae88 100644 --- a/sys/powerpc/aim/locore32.S +++ b/sys/powerpc/aim/locore32.S @@ -108,36 +108,47 @@ kernel_text: .text .globl __start __start: - li 8,0 - li 9,0x100 - mtctr 9 -1: - dcbf 0,8 - icbi 0,8 - addi 8,8,0x20 - bdnz 1b - sync - isync - - /* Zero bss, in case we were started by something unhelpful */ - li 0,0 - lis 8,_edata@ha - addi 8,8,_edata@l - lis 9,_end@ha - addi 9,9,_end@l -2: stw 0,0(8) - addi 8,8,4 - cmplw 8,9 - blt 2b + /* Figure out where we are */ + bl 1f + .long _DYNAMIC-. + .long _GLOBAL_OFFSET_TABLE_-. + .long tmpstk-. +1: mflr %r30 + + /* Set up temporary stack pointer */ + lwz %r1,8(%r30) + add %r1,%r1,%r30 + addi %r1,%r1,(8+TMPSTKSZ-32) + + /* Relocate self */ + stw %r3,16(%r1) + stw %r4,20(%r1) + stw %r5,24(%r1) + stw %r6,28(%r1) + + lwz %r3,0(%r30) /* _DYNAMIC in %r3 */ + add %r3,%r3,%r30 + lwz %r4,4(%r30) /* GOT pointer */ + add %r4,%r4,%r30 + lwz %r4,4(%r4) /* got[0] is _DYNAMIC link addr */ + subf %r4,%r4,%r3 /* subtract to calculate relocbase */ + bl elf_reloc_self - lis 1,(tmpstk+TMPSTKSZ-16)@ha - addi 1,1,(tmpstk+TMPSTKSZ-16)@l + lwz %r3,16(%r1) + lwz %r4,20(%r1) + lwz %r5,24(%r1) + lwz %r6,28(%r1) + /* MD setup */ bl powerpc_init + + /* Set stack pointer to new value and branch to mi_startup */ mr %r1, %r3 li %r3, 0 stw %r3, 0(%r1) bl mi_startup + + /* If mi_startup somehow returns, exit. This would be bad. */ b OF_exit /* diff --git a/sys/powerpc/aim/machdep.c b/sys/powerpc/aim/machdep.c index 5d7c784..22f3b2f 100644 --- a/sys/powerpc/aim/machdep.c +++ b/sys/powerpc/aim/machdep.c @@ -235,10 +235,13 @@ extern void *testppc64, *testppc64size; extern void *restorebridge, *restorebridgesize; extern void *rfid_patch, *rfi_patch1, *rfi_patch2; extern void *trapcode64; + +extern Elf_Addr _GLOBAL_OFFSET_TABLE_[]; #endif extern void *rstcode, *rstcodeend; -extern void *trapcode, *trapcodeend, *trapcode2; +extern void *trapcode, *trapcodeend; +extern void *generictrap, *generictrap64; extern void *slbtrap, *slbtrapend; extern void *alitrap, *aliend; extern void *dsitrap, *dsiend; @@ -254,7 +257,6 @@ powerpc_init(vm_offset_t fdt, vm_offset_t toc, vm_offset_t ofentry, void *mdp) { struct pcpu *pc; vm_offset_t startkernel, endkernel; - void *generictrap; size_t trap_offset, trapsize; vm_offset_t trap; void *kmdp; @@ -467,20 +469,9 @@ powerpc_init(vm_offset_t fdt, vm_offset_t toc, vm_offset_t ofentry, void *mdp) /* rfi_patch2 is at the end of dbleave */ bcopy(&rfid_patch,&rfi_patch2,4); #endif - - /* - * Set the common trap entry point to the one that - * knows to restore 32-bit operation on execution. - */ - - generictrap = &trapcode64; - } else { - generictrap = &trapcode; } - #else /* powerpc64 */ cpu_features |= PPC_FEATURE_64; - generictrap = &trapcode; #endif trapsize = (size_t)&trapcodeend - (size_t)&trapcode; @@ -490,7 +481,7 @@ powerpc_init(vm_offset_t fdt, vm_offset_t toc, vm_offset_t ofentry, void *mdp) * different ones in a minute. */ for (trap = EXC_RST; trap < EXC_LAST; trap += 0x20) - bcopy(generictrap, (void *)trap, trapsize); + bcopy(&trapcode, (void *)trap, trapsize); #ifndef __powerpc64__ if (cpu_features & PPC_FEATURE_64) { @@ -530,12 +521,19 @@ powerpc_init(vm_offset_t fdt, vm_offset_t toc, vm_offset_t ofentry, void *mdp) #ifdef __powerpc64__ /* Set TOC base so that the interrupt code can get at it */ - *((void **)TRAP_GENTRAP) = &trapcode2; + *((void **)TRAP_GENTRAP) = &generictrap; *((register_t *)TRAP_TOCBASE) = toc; bcopy(&slbtrap, (void *)EXC_DSE,(size_t)&slbtrapend - (size_t)&slbtrap); bcopy(&slbtrap, (void *)EXC_ISE,(size_t)&slbtrapend - (size_t)&slbtrap); #else + /* Set branch address for trap code */ + if (cpu_features & PPC_FEATURE_64) + *((void **)TRAP_GENTRAP) = &generictrap64; + else + *((void **)TRAP_GENTRAP) = &generictrap; + *((void **)TRAP_TOCBASE) = _GLOBAL_OFFSET_TABLE_; + /* G2-specific TLB miss helper handlers */ bcopy(&imisstrap, (void *)EXC_IMISS, (size_t)&imisssize); bcopy(&dlmisstrap, (void *)EXC_DLMISS, (size_t)&dlmisssize); diff --git a/sys/powerpc/aim/trap_subr32.S b/sys/powerpc/aim/trap_subr32.S index 7c753b5..056c073 100644 --- a/sys/powerpc/aim/trap_subr32.S +++ b/sys/powerpc/aim/trap_subr32.S @@ -74,8 +74,9 @@ * Kernel SRs are loaded directly from kernel_pmap_ */ #define RESTORE_KERN_SRS(pmap,sr) \ - lis pmap,CNAME(kernel_pmap_store)@ha; \ - lwzu sr,CNAME(kernel_pmap_store)+PM_SR@l(pmap); \ + lwz pmap,TRAP_TOCBASE(0); \ + lwz pmap,CNAME(kernel_pmap_store)@got(pmap); \ + lwzu sr,PM_SR(pmap); \ RESTORE_SRS(pmap,sr) /* @@ -301,7 +302,12 @@ CNAME(restorebridgesize) = .-CNAME(restorebridge) */ .globl CNAME(rstcode), CNAME(rstcodeend) CNAME(rstcode): - ba cpu_reset + bl 1f + .long cpu_reset +1: mflr %r31 + lwz %r31,0(%r31) + mtlr %r31 + blrl CNAME(rstcodeend): cpu_reset: @@ -313,12 +319,12 @@ cpu_reset: mflr %r1 addi %r1,%r1,(124-16)@l - bla CNAME(cpudep_ap_early_bootstrap) + bl CNAME(cpudep_ap_early_bootstrap) lis %r3,1@l - bla CNAME(pmap_cpu_bootstrap) - bla CNAME(cpudep_ap_bootstrap) + bl CNAME(pmap_cpu_bootstrap) + bl CNAME(cpudep_ap_bootstrap) mr %r1,%r3 - bla CNAME(cpudep_ap_setup) + bl CNAME(cpudep_ap_setup) GET_CPUINFO(%r5) lwz %r3,(PC_RESTORE)(%r5) cmplwi %cr0,%r3,0 @@ -327,7 +333,7 @@ cpu_reset: b CNAME(longjmp) 2: #ifdef SMP - bla CNAME(machdep_ap_bootstrap) + bl CNAME(machdep_ap_bootstrap) #endif /* Should not be reached */ @@ -344,22 +350,13 @@ CNAME(trapcode): mtsprg1 %r1 /* save SP */ mflr %r1 /* Save the old LR in r1 */ mtsprg2 %r1 /* And then in SPRG2 */ - li %r1, 0x20 /* How to get the vector from LR */ - bla generictrap /* LR & SPRG3 is exception # */ + lwz %r1, TRAP_GENTRAP(0) /* Get branch address */ + mtlr %r1 + li %r1, 0xe0 /* How to get the vector from LR */ + blrl /* LR & (0xff00 | r1) is exception # */ CNAME(trapcodeend): /* - * 64-bit version of trapcode. Identical, except it calls generictrap64. - */ - .globl CNAME(trapcode64) -CNAME(trapcode64): - mtsprg1 %r1 /* save SP */ - mflr %r1 /* Save the old LR in r1 */ - mtsprg2 %r1 /* And then in SPRG2 */ - li %r1, 0x20 /* How to get the vector from LR */ - bla generictrap64 /* LR & SPRG3 is exception # */ - -/* * For ALI: has to save DSISR and DAR */ .globl CNAME(alitrap),CNAME(aliend) @@ -385,7 +382,14 @@ CNAME(alitrap): /* Test whether we already had PR set */ mfsrr1 %r31 mtcr %r31 - bla s_trap + + /* Jump to s_trap */ + bl 1f + .long s_trap +1: mflr %r31 + lwz %r31,0(%r31) + mtlr %r31 + blrl CNAME(aliend): /* @@ -449,7 +453,7 @@ isi1: xoris %r0, %r0, 0x2 /* flip the msr<tgpr> bit */ mtcrf 0x80, %r3 /* restore CR0 */ mtmsr %r0 /* flip back to the native gprs */ - ba EXC_ISI /* go to instr. access interrupt */ + ba EXC_ISI /* go to instr. access interrupt */ CNAME(imisssize) = .-CNAME(imisstrap) @@ -613,13 +617,15 @@ CNAME(dsitrap): rlwinm %r31,%r31,7,25,28 /* get segment * 8 */ /* get batu */ - addis %r31,%r31,CNAME(battable)@ha - lwz %r30,CNAME(battable)@l(31) + lwz %r30,TRAP_TOCBASE(0) + lwz %r30,CNAME(battable)@got(%r30) + add %r31,%r30,%r31 + lwz %r30,0(%r31) mtcr %r30 bf 30,1f /* branch if supervisor valid is false */ /* get batl */ - lwz %r31,CNAME(battable)+4@l(31) + lwz %r31,4(%r31) /* We randomly use the highest two bat registers here */ mftb %r28 andi. %r28,%r28,1 @@ -644,7 +650,14 @@ CNAME(dsitrap): rfi /* return to trapped code */ 1: mflr %r28 /* save LR (SP already saved) */ - bla disitrap + + /* Jump to disitrap */ + bl 4f + .long disitrap +4: mflr %r1 + lwz %r1,0(%r1) + mtlr %r1 + blrl CNAME(dsiend): /* @@ -711,7 +724,7 @@ realtrap: GET_CPUINFO(%r1) lwz %r1,PC_CURPCB(%r1) RESTORE_KERN_SRS(%r30,%r31) /* enable kernel mapping */ - ba s_trap + b s_trap /* * generictrap does some standard setup for trap handling to minimize @@ -723,6 +736,7 @@ realtrap: * SPRG2 - Original LR */ + .globl CNAME(generictrap64) generictrap64: mtsprg3 %r31 mfmsr %r31 @@ -731,6 +745,7 @@ generictrap64: mfsprg3 %r31 isync + .globl CNAME(generictrap) generictrap: /* Save R1 for computing the exception vector */ mtsprg3 %r1 @@ -848,8 +863,9 @@ dbtrap: andi. %r1,%r1,0xff00 mtsprg3 %r1 - lis %r1,(tmpstk+TMPSTKSZ-16)@ha /* get new SP */ - addi %r1,%r1,(tmpstk+TMPSTKSZ-16)@l + lwz %r1,TRAP_TOCBASE(0) /* get new SP */ + lwz %r1,tmpstk@got(%r1) + addi %r1,%r1,TMPSTKSZ-16 FRAME_SETUP(PC_DBSAVE) /* Call C trap code: */ @@ -896,9 +912,11 @@ 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 */ + lwz %r1, TRAP_GENTRAP(0) /* Get branch address */ + mtlr %r1 + li %r1, 0 /* How to get the vector from LR */ + blrl /* LR & (0xff00 | r1) is exception # */ 1: /* Privileged, so drop to KDB */ GET_CPUINFO(%r1) @@ -908,6 +926,13 @@ CNAME(dblow): stw %r30,(PC_DBSAVE+CPUSAVE_R30)(%r1) /* free r30 */ stw %r31,(PC_DBSAVE+CPUSAVE_R31)(%r1) /* free r31 */ mflr %r28 /* save LR */ - bla dbtrap + + /* Jump to dbtrap */ + bl 2f + .long dbtrap +2: mflr %r1 + lwz %r1,0(%r1) + mtlr %r1 + blrl CNAME(dbend): #endif /* KDB */ diff --git a/sys/powerpc/aim/trap_subr64.S b/sys/powerpc/aim/trap_subr64.S index 76c2bae..81a7679 100644 --- a/sys/powerpc/aim/trap_subr64.S +++ b/sys/powerpc/aim/trap_subr64.S @@ -673,8 +673,7 @@ realtrap: * SPRG2 - Original LR */ - .globl CNAME(trapcode2) -trapcode2: + .globl CNAME(generictrap) generictrap: /* Save R1 for computing the exception vector */ mtsprg3 %r1 |