diff --git a/UPDATING b/UPDATING index 05a9e70dd5f..81f47deaf05 100644 --- a/UPDATING +++ b/UPDATING @@ -31,6 +31,12 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 11.x IS SLOW: disable the most expensive debugging functionality run "ln -s 'abort:false,junk:false' /etc/malloc.conf".) +20150307: + The 32-bit PowerPC kernel has been changed to a position-independent + executable. This can only be booted with a version of loader(8) + newer than January 31, 2015, so make sure to update both world and + kernel before rebooting. + 20150217: If you are running a -CURRENT kernel since r273872 (Oct 30th, 2014), but before r278950, the RNG was not seeded properly. Immediately diff --git a/sys/conf/Makefile.powerpc b/sys/conf/Makefile.powerpc index e2d51577158..769b068ed5f 100644 --- a/sys/conf/Makefile.powerpc +++ b/sys/conf/Makefile.powerpc @@ -37,10 +37,9 @@ INCLUDES+= -I$S/contrib/libfdt CFLAGS+= -msoft-float -Wa,-many -.if ${MACHINE_ARCH} == "powerpc64" +# Build position-independent kernel CFLAGS+= -fPIC LDFLAGS+= -pie -.endif .if !empty(DDB_ENABLED) CFLAGS+= -fno-omit-frame-pointer diff --git a/sys/kern/link_elf.c b/sys/kern/link_elf.c index 3cf19e1323c..65c8276a950 100644 --- a/sys/kern/link_elf.c +++ b/sys/kern/link_elf.c @@ -411,7 +411,7 @@ link_elf_init(void* arg) ef = (elf_file_t) linker_kernel_file; ef->preloaded = 1; -#ifdef __powerpc64__ +#ifdef __powerpc__ ef->address = (caddr_t) (__startkernel - KERNBASE); #else ef->address = 0; diff --git a/sys/powerpc/aim/locore32.S b/sys/powerpc/aim/locore32.S index a2cb1028701..477ae88114e 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 + /* Figure out where we are */ + bl 1f + .long _DYNAMIC-. + .long _GLOBAL_OFFSET_TABLE_-. + .long tmpstk-. +1: mflr %r30 - /* 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 + /* 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 5d7c784ed60..22f3b2fe61d 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 7c753b541dd..056c0732367 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,21 +350,12 @@ 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 */ @@ -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 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 76c2baec913..81a767963a6 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 diff --git a/sys/powerpc/booke/locore.S b/sys/powerpc/booke/locore.S index 9d00327159d..37860e52dae 100644 --- a/sys/powerpc/booke/locore.S +++ b/sys/powerpc/booke/locore.S @@ -205,10 +205,28 @@ done_mapping: /* * Setup a temporary stack */ - lis %r1, tmpstack@ha - addi %r1, %r1, tmpstack@l + bl 1f + .long tmpstack-. +1: mflr %r1 + lwz %r2,0(%r1) + add %r1,%r1,%r2 addi %r1, %r1, (TMPSTACKSZ - 16) +/* + * Relocate kernel + */ + bl 1f + .long _DYNAMIC-. + .long _GLOBAL_OFFSET_TABLE_-. +1: mflr %r5 + lwz %r3,0(%r5) /* _DYNAMIC in %r3 */ + add %r3,%r3,%r5 + lwz %r4,4(%r5) /* GOT pointer */ + add %r4,%r4,%r5 + lwz %r4,4(%r4) /* got[0] is _DYNAMIC link addr */ + subf %r4,%r4,%r3 /* subtract to calculate relocbase */ + bl elf_reloc_self + /* * Initialise exception vector offsets */ @@ -338,10 +356,13 @@ bp_tlb1_end: blt 4b /* Switch to the final mapping */ - lis %r5, __boot_page@ha - ori %r5, %r5, __boot_page@l bl 5f -5: mflr %r3 + .long __boot_page-. +5: mflr %r5 + lwz %r3,0(%r3) + add %r5,%r5,%r3 /* __boot_page in r5 */ + bl 6f +6: mflr %r3 rlwinm %r3, %r3, 0, 0xfff /* Offset from boot page start */ add %r3, %r3, %r5 /* Make this virtual address */ addi %r3, %r3, 32 @@ -365,8 +386,11 @@ bp_tlb1_end: /* * Setup a temporary stack */ - lis %r1, tmpstack@ha - addi %r1, %r1, tmpstack@l + bl 1f + .long tmpstack-. +1: mflr %r1 + lwz %r2,0(%r1) + add %r1,%r1,%r2 addi %r1, %r1, (TMPSTACKSZ - 16) /* @@ -377,8 +401,11 @@ bp_tlb1_end: /* * Assign our pcpu instance */ - lis %r3, ap_pcpu@h - ori %r3, %r3, ap_pcpu@l + bl 1f + .long ap_pcpu-. +1: mflr %r4 + lwz %r3, 0(%r4) + add %r3, %r3, %r4 lwz %r3, 0(%r3) mtsprg0 %r3 @@ -543,24 +570,14 @@ __boot_page_padding: * dedicated for cases when invalidation(s) should NOT be propagated to other * CPUs. * - * Global vars tlb0_ways, tlb0_entries_per_way are assumed to have been set up - * correctly (by tlb0_get_tlbconf()). + * void tid_flush(tlbtid_t tid, int tlb0_ways, int tlb0_entries_per_way); * + * XXX: why isn't this in C? */ ENTRY(tid_flush) cmpwi %r3, TID_KERNEL beq tid_flush_end /* don't evict kernel translations */ - /* Number of TLB0 ways */ - lis %r4, tlb0_ways@h - ori %r4, %r4, tlb0_ways@l - lwz %r4, 0(%r4) - - /* Number of entries / way */ - lis %r5, tlb0_entries_per_way@h - ori %r5, %r5, tlb0_entries_per_way@l - lwz %r5, 0(%r5) - /* Disable interrupts */ mfmsr %r10 wrteei 0 @@ -718,6 +735,11 @@ setfault: /* Data section */ /************************************************************************/ .data + .align 3 +GLOBAL(__startkernel) + .long begin +GLOBAL(__endkernel) + .long end .align 4 tmpstack: .space TMPSTACKSZ diff --git a/sys/powerpc/booke/pmap.c b/sys/powerpc/booke/pmap.c index 5ee5b0a5940..573364afb67 100644 --- a/sys/powerpc/booke/pmap.c +++ b/sys/powerpc/booke/pmap.c @@ -159,7 +159,7 @@ unsigned int kernel_ptbls; /* Number of KVA ptbls. */ #define PMAP_REMOVE_DONE(pmap) \ ((pmap) != kernel_pmap && (pmap)->pm_stats.resident_count == 0) -extern void tid_flush(tlbtid_t); +extern void tid_flush(tlbtid_t tid, int tlb0_ways, int tlb0_entries_per_way); extern int elf32_nxstack; /**************************************************************************/ @@ -2818,7 +2818,7 @@ tid_alloc(pmap_t pmap) tidbusy[thiscpu][tid]->pm_tid[thiscpu] = TID_NONE; /* Flush all entries from TLB0 matching this TID. */ - tid_flush(tid); + tid_flush(tid, tlb0_ways, tlb0_entries_per_way); } tidbusy[thiscpu][tid] = pmap; diff --git a/sys/powerpc/booke/trap_subr.S b/sys/powerpc/booke/trap_subr.S index 757644963b3..bc6bad3083c 100644 --- a/sys/powerpc/booke/trap_subr.S +++ b/sys/powerpc/booke/trap_subr.S @@ -542,8 +542,11 @@ INTERRUPT(int_data_tlb_error) search_kernel_pmap: /* Load r26 with kernel_pmap address */ - lis %r26, kernel_pmap_store@h - ori %r26, %r26, kernel_pmap_store@l + bl 1f + .long kernel_pmap_store-. +1: mflr %r21 + lwz %r26, 0(%r21) + add %r26, %r21, %r26 /* kernel_pmap_store in r26 */ /* Force kernel tid, set TID to 0 in MAS1. */ li %r21, 0 @@ -737,12 +740,17 @@ INTERRUPT(int_debug) FRAME_SETUP(SPR_SPRG2, PC_BOOKE_CRITSAVE, EXC_DEBUG) GET_CPUINFO(%r3) lwz %r3, (PC_BOOKE_CRITSAVE+CPUSAVE_SRR0)(%r3) - lis %r4, interrupt_vector_base@ha - addi %r4, %r4, interrupt_vector_base@l + bl 0f + .long interrupt_vector_base-. + .long interrupt_vector_top-. +0: mflr %r5 + lwz %r4,0(%r5) /* interrupt_vector_base in r4 */ + add %r4,%r4,%r5 cmplw cr0, %r3, %r4 blt 1f - lis %r4, interrupt_vector_top@ha - addi %r4, %r4, interrupt_vector_top@l + lwz %r4,4(%r5) /* interrupt_vector_top in r4 */ + add %r4,%r4,%r5 + addi %r4,%r4,4 cmplw cr0, %r3, %r4 bge 1f /* Disable single-stepping for the interrupt handlers. */ diff --git a/sys/powerpc/ofw/ofwcall32.S b/sys/powerpc/ofw/ofwcall32.S index d2ba70f49ae..6c460c11557 100644 --- a/sys/powerpc/ofw/ofwcall32.S +++ b/sys/powerpc/ofw/ofwcall32.S @@ -66,17 +66,21 @@ ASENTRY(ofwcall) /* Record the old MSR */ mfmsr %r6 + /* GOT pointer in r7 */ + bl _GLOBAL_OFFSET_TABLE_@local-4 + mflr %r7 + /* read client interface handler */ - lis %r4,openfirmware_entry@ha - lwz %r4,openfirmware_entry@l(%r4) + lwz %r4,openfirmware_entry@got(%r7) + lwz %r4,0(%r4) /* * Set the MSR to the OF value. This has the side effect of disabling * exceptions, which prevents preemption later. */ - lis %r5,ofmsr@ha - lwz %r5,ofmsr@l(%r5) + lwz %r5,ofmsr@got(%r7) + lwz %r5,0(%r5) mtmsr %r5 isync @@ -87,8 +91,8 @@ ASENTRY(ofwcall) * later. */ mr %r5,%r1 - lis %r1,(ofwstk+OFWSTKSZ-32)@ha - addi %r1,%r1,(ofwstk+OFWSTKSZ-32)@l + lwz %r1,ofwstk@got(%r7) + addi %r1,%r1,(OFWSTKSZ-32) stw %r5,20(%r1) /* Save real stack pointer */ stw %r2,24(%r1) /* Save curthread */ stw %r6,28(%r1) /* Save old MSR */ @@ -124,18 +128,22 @@ ASENTRY(rtascall) mflr %r0 stw %r0,4(%r1) + /* GOT pointer in r7 */ + bl _GLOBAL_OFFSET_TABLE_@local-4 + mflr %r7 + /* Record the old MSR to real-mode-accessible area */ mfmsr %r0 - lis %r5,rtas_regsave@ha - stw %r0,rtas_regsave@l(%r5) + lwz %r5,rtas_regsave@got(%r7) + stw %r0,0(%r5) /* read client interface handler */ - lis %r5,rtas_entry@ha - lwz %r5,rtas_entry@l(%r5) + lwz %r5,rtas_entry@got(%r7) + lwz %r5,0(%r5) /* Set the MSR to the RTAS value */ - lis %r6,rtasmsr@ha - lwz %r6,rtasmsr@l(%r6) + lwz %r6,rtasmsr@got(%r7) + lwz %r6,0(%r6) mtmsr %r6 isync @@ -143,9 +151,13 @@ ASENTRY(rtascall) mtctr %r5 bctrl + /* GOT pointer in r7 */ + bl _GLOBAL_OFFSET_TABLE_@local-4 + mflr %r7 + /* Now set the MSR back */ - lis %r6,rtas_regsave@ha - lwz %r6,rtas_regsave@l(%r6) + lwz %r6,rtas_regsave@got(%r7) + lwz %r6,0(%r6) mtmsr %r6 isync diff --git a/sys/powerpc/powerpc/elf32_machdep.c b/sys/powerpc/powerpc/elf32_machdep.c index 1e0b43b9928..ea00306787c 100644 --- a/sys/powerpc/powerpc/elf32_machdep.c +++ b/sys/powerpc/powerpc/elf32_machdep.c @@ -147,6 +147,8 @@ SYSINIT(oelf32, SI_SUB_EXEC, SI_ORDER_ANY, (sysinit_cfunc_t) elf32_insert_brand_entry, &freebsd_brand_oinfo); +void elf_reloc_self(Elf_Dyn *dynp, Elf_Addr relocbase); + void elf32_dump_thread(struct thread *td, void *dst, size_t *off) { @@ -252,6 +254,39 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data, return(0); } +void +elf_reloc_self(Elf_Dyn *dynp, Elf_Addr relocbase) +{ + Elf_Rela *rela = 0, *relalim; + Elf_Addr relasz = 0; + Elf_Addr *where; + + /* + * Extract the rela/relasz values from the dynamic section + */ + for (; dynp->d_tag != DT_NULL; dynp++) { + switch (dynp->d_tag) { + case DT_RELA: + rela = (Elf_Rela *)(relocbase+dynp->d_un.d_ptr); + break; + case DT_RELASZ: + relasz = dynp->d_un.d_val; + break; + } + } + + /* + * Relocate these values + */ + relalim = (Elf_Rela *)((caddr_t)rela + relasz); + for (; rela < relalim; rela++) { + if (ELF_R_TYPE(rela->r_info) != R_PPC_RELATIVE) + continue; + where = (Elf_Addr *)(relocbase + rela->r_offset); + *where = (Elf_Addr)(relocbase + rela->r_addend); + } +} + int elf_reloc(linker_file_t lf, Elf_Addr relocbase, const void *data, int type, elf_lookup_fn lookup) diff --git a/sys/powerpc/powerpc/swtch32.S b/sys/powerpc/powerpc/swtch32.S index dc28323866e..12b1bc03a39 100644 --- a/sys/powerpc/powerpc/swtch32.S +++ b/sys/powerpc/powerpc/swtch32.S @@ -121,8 +121,9 @@ ENTRY(cpu_switch) cpu_switchin: #if defined(SMP) && defined(SCHED_ULE) /* Wait for the new thread to become unblocked */ - lis %r6,blocked_lock@ha - addi %r6,%r6,blocked_lock@l + bl _GLOBAL_OFFSET_TABLE_@local-4 + mflr %r6 + lwz %r6,blocked_lock@got(%r6) blocked_loop: lwz %r7,TD_LOCK(%r2) cmpw %r6,%r7