Date: Sat, 28 May 2011 04:10:44 +0000 (UTC) From: Marcel Moolenaar <marcel@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r222400 - head/sys/powerpc/booke Message-ID: <201105280410.p4S4AiSk067132@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: marcel Date: Sat May 28 04:10:44 2011 New Revision: 222400 URL: http://svn.freebsd.org/changeset/base/222400 Log: Better support different kernel hand-offs. When loaded directly from U-Boot, the kernel is passed a standard argc/argv pair. The Juniper loader passes the metadata pointer as the second argument and passes 0 in the first. The FreeBSD loader passes the metadata pointer in the first argument. As such, have locore preserve the first 2 arguments in registers r30 & r31. Change e500_init() to accept these arguments. Don't pass global offsets (i.e. kernel_text and _end) as arguments to e500_init(). We can reference those directly. Rename e500_init() to booke_init() now that we're changing the prototype. In booke_init(), "decode" arg1 and arg2 to obtain the metadata pointer correctly. For the U-Boot case, clear SBSS and BSS and bank on having a static FDT for now. This allows loading the ELF kernel and jumping to the entry point without trampoline. Modified: head/sys/powerpc/booke/locore.S head/sys/powerpc/booke/machdep.c head/sys/powerpc/booke/pmap.c Modified: head/sys/powerpc/booke/locore.S ============================================================================== --- head/sys/powerpc/booke/locore.S Sat May 28 00:58:19 2011 (r222399) +++ head/sys/powerpc/booke/locore.S Sat May 28 04:10:44 2011 (r222400) @@ -83,17 +83,18 @@ __start: * locore registers use: * r1 : stack pointer * r2 : trace pointer (AP only, for early diagnostics) - * r3-r27 : scratch registers - * r28 : kernload - * r29 : temp TLB1 entry - * r30 : initial TLB1 entry we started in - * r31 : metadata pointer + * r3-r26 : scratch registers + * r27 : kernload + * r28 : temp TLB1 entry + * r29 : initial TLB1 entry we started in + * r30-r31 : arguments (metadata pointer) */ /* - * Keep metadata ptr in r31 for later use. + * Keep arguments in r30 & r31 for later use. */ - mr %r31, %r3 + mr %r30, %r3 + mr %r31, %r4 /* * Initial cleanup @@ -120,7 +121,7 @@ __start: */ bl 1f 1: mflr %r3 - bl tlb1_find_current /* the entry number found is returned in r30 */ + bl tlb1_find_current /* the entry found is returned in r29 */ bl tlb1_inval_all_but_current /* @@ -140,7 +141,7 @@ __start: /* * Invalidate initial entry */ - mr %r3, %r30 + mr %r3, %r29 bl tlb1_inval_entry /* @@ -170,7 +171,7 @@ __start: bl 3f 3: mflr %r4 /* Use current address */ rlwinm %r4, %r4, 0, 0, 7 /* 16MB alignment mask */ - mr %r28, %r4 /* Keep kernel load address */ + mr %r27, %r4 /* Keep kernel load address */ ori %r4, %r4, (MAS3_SX | MAS3_SW | MAS3_SR)@l mtspr SPR_MAS3, %r4 /* Set RPN and protection */ isync @@ -193,7 +194,7 @@ __start: /* * Invalidate temp mapping */ - mr %r3, %r29 + mr %r3, %r28 bl tlb1_inval_entry /* @@ -201,7 +202,7 @@ __start: */ lis %r3, kernload@ha addi %r3, %r3, kernload@l - stw %r28, 0(%r3) + stw %r27, 0(%r3) #ifdef SMP /* * APs need a separate copy of kernload info within the __boot_page @@ -210,7 +211,7 @@ __start: */ lis %r3, kernload_ap@ha addi %r3, %r3, kernload_ap@l - stw %r28, 0(%r3) + stw %r27, 0(%r3) msync #endif @@ -229,14 +230,11 @@ __start: /* * Set up arguments and jump to system initialization code */ - lis %r3, kernel_text@ha - addi %r3, %r3, kernel_text@l - lis %r4, _end@ha - addi %r4, %r4, _end@l - mr %r5, %r31 /* metadata ptr */ + mr %r3, %r30 + mr %r4, %r31 /* Prepare e500 core */ - bl e500_init + bl booke_init /* Switch to thread0.td_kstack now */ mr %r1, %r3 @@ -290,7 +288,7 @@ kernload_ap: */ bl 2f 2: mflr %r3 - bl tlb1_find_current /* the entry number found is in r30 */ + bl tlb1_find_current /* the entry number found is in r29 */ bl tlb1_inval_all_but_current /* @@ -310,7 +308,7 @@ kernload_ap: /* * Invalidate initial entry */ - mr %r3, %r30 + mr %r3, %r29 bl tlb1_inval_entry /* @@ -373,7 +371,7 @@ kernload_ap: /* * Invalidate temp mapping */ - mr %r3, %r29 + mr %r3, %r28 bl tlb1_inval_entry /* @@ -425,7 +423,7 @@ tlb_inval_all: blr /* - * expects address to look up in r3, returns entry number in r30 + * expects address to look up in r3, returns entry number in r29 * * FIXME: the hidden assumption is we are now running in AS=0, but we should * retrieve actual AS from MSR[IS|DS] and put it in MAS6[SAS] @@ -437,7 +435,7 @@ tlb1_find_current: isync tlbsx 0, %r3 mfspr %r17, SPR_MAS0 - rlwinm %r30, %r17, 16, 20, 31 /* MAS0[ESEL] -> r30 */ + rlwinm %r29, %r17, 16, 20, 31 /* MAS0[ESEL] -> r29 */ /* Make sure we have IPROT set on the entry */ mfspr %r17, SPR_MAS1 @@ -470,14 +468,14 @@ tlb1_inval_entry: blr /* - * r30 current entry number - * r29 returned temp entry + * r29 current entry number + * r28 returned temp entry * r3-r5 scratched */ tlb1_temp_mapping_as1: /* Read our current translation */ lis %r3, MAS0_TLBSEL1@h /* Select TLB1 */ - rlwimi %r3, %r30, 16, 12, 15 /* Select our current entry */ + rlwimi %r3, %r29, 16, 12, 15 /* Select our current entry */ mtspr SPR_MAS0, %r3 isync tlbre @@ -489,8 +487,8 @@ tlb1_temp_mapping_as1: * entry is the last in TLB1 */ lis %r3, MAS0_TLBSEL1@h /* Select TLB1 */ - addi %r29, %r30, 1 /* Use next entry. */ - rlwimi %r3, %r29, 16, 12, 15 /* Select temp entry */ + addi %r28, %r29, 1 /* Use next entry. */ + rlwimi %r3, %r28, 16, 12, 15 /* Select temp entry */ mtspr SPR_MAS0, %r3 isync mfspr %r5, SPR_MAS1 @@ -510,7 +508,7 @@ tlb1_temp_mapping_as1: * Loops over TLB1, invalidates all entries skipping the one which currently * maps this code. * - * r30 current entry + * r29 current entry * r3-r5 scratched */ tlb1_inval_all_but_current: @@ -524,7 +522,7 @@ tlb1_inval_all_but_current: isync tlbre mfspr %r5, SPR_MAS1 - cmpw %r4, %r30 /* our current entry? */ + cmpw %r4, %r29 /* our current entry? */ beq 2f rlwinm %r5, %r5, 0, 2, 31 /* clear VALID and IPROT bits */ mtspr SPR_MAS1, %r5 Modified: head/sys/powerpc/booke/machdep.c ============================================================================== --- head/sys/powerpc/booke/machdep.c Sat May 28 00:58:19 2011 (r222399) +++ head/sys/powerpc/booke/machdep.c Sat May 28 04:10:44 2011 (r222400) @@ -190,7 +190,7 @@ SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, void print_kernel_section_addr(void); void print_kenv(void); -u_int e500_init(u_int32_t, u_int32_t, void *); +u_int booke_init(uint32_t, uint32_t); static void cpu_e500_startup(void *dummy) @@ -276,19 +276,41 @@ print_kernel_section_addr(void) } u_int -e500_init(u_int32_t startkernel, u_int32_t endkernel, void *mdp) +booke_init(uint32_t arg1, uint32_t arg2) { struct pcpu *pc; - void *kmdp; + void *kmdp, *mdp; vm_offset_t dtbp, end; uint32_t csr; kmdp = NULL; - end = endkernel; + end = (uintptr_t)_end; dtbp = (vm_offset_t)NULL; /* + * Handle the various ways we can get loaded and started: + * - FreeBSD's loader passes the pointer to the metadata + * in arg1, with arg2 undefined. arg1 has a value that's + * relative to the kernel's link address (i.e. larger + * than 0xc0000000). + * - Juniper's loader passes the metadata pointer in arg2 + * and sets arg1 to zero. This is to signal that the + * loader maps the kernel and starts it at its link + * address (unlike the FreeBSD loader). + * - U-Boot passes the standard argc and argv parameters + * in arg1 and arg2 (resp). arg1 is between 1 and some + * relatively small number, such as 64K. arg2 is the + * physical address of the argv vector. + */ + if (arg1 > (uintptr_t)kernel_text) /* FreeBSD loader */ + mdp = (void *)arg1; + else if (arg1 == 0) /* Juniper loader */ + mdp = (void *)arg2; + else /* U-Boot */ + mdp = NULL; + + /* * Parse metadata and fetch parameters. */ if (mdp != NULL) { @@ -309,17 +331,8 @@ e500_init(u_int32_t startkernel, u_int32 #endif } } else { - /* - * We should scream but how? Cannot even output anything... - */ - - /* - * FIXME add return value and handle in the locore so we can - * return to the loader maybe? (this seems not very easy to - * restore everything as the TLB have all been reprogrammed - * in the locore etc...) - */ - while (1); + bzero(__sbss_start, __sbss_end - __sbss_start); + bzero(__bss_start, _end - __bss_start); } #if defined(FDT_DTB_STATIC) @@ -368,9 +381,7 @@ e500_init(u_int32_t startkernel, u_int32 cninit(); /* Print out some debug info... */ - debugf("e500_init: console initialized\n"); - debugf(" arg1 startkernel = 0x%08x\n", startkernel); - debugf(" arg2 endkernel = 0x%08x\n", endkernel); + debugf("%s: console initialized\n", __func__); debugf(" arg3 mdp = 0x%08x\n", (u_int32_t)mdp); debugf(" end = 0x%08x\n", (u_int32_t)end); debugf(" boothowto = 0x%08x\n", boothowto); @@ -403,7 +414,7 @@ e500_init(u_int32_t startkernel, u_int32 /* Initialise virtual memory. */ pmap_mmu_install(MMU_TYPE_BOOKE, 0); - pmap_bootstrap(startkernel, end); + pmap_bootstrap((uintptr_t)kernel_text, end); debugf("MSR = 0x%08x\n", mfmsr()); //tlb1_print_entries(); //tlb1_print_tlbentries(); @@ -449,8 +460,8 @@ e500_init(u_int32_t startkernel, u_int32 printf("L1 I-cache %sabled\n", (csr & L1CSR1_ICE) ? "en" : "dis"); - debugf("e500_init: SP = 0x%08x\n", ((uintptr_t)thread0.td_pcb - 16) & ~15); - debugf("e500_init: e\n"); + debugf("%s: SP = 0x%08x\n", __func__, + ((uintptr_t)thread0.td_pcb - 16) & ~15); return (((uintptr_t)thread0.td_pcb - 16) & ~15); } Modified: head/sys/powerpc/booke/pmap.c ============================================================================== --- head/sys/powerpc/booke/pmap.c Sat May 28 00:58:19 2011 (r222399) +++ head/sys/powerpc/booke/pmap.c Sat May 28 04:10:44 2011 (r222400) @@ -943,7 +943,7 @@ pte_find(mmu_t mmu, pmap_t pmap, vm_offs /**************************************************************************/ /* - * This is called during e500_init, before the system is really initialized. + * This is called during booke_init, before the system is really initialized. */ static void mmu_booke_bootstrap(mmu_t mmu, vm_offset_t start, vm_offset_t kernelend)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201105280410.p4S4AiSk067132>