[RFC] powerpc/boot: add kernel,end node to the cuboot target
Sebastian Siewior
sebastian at breakpoint.cc
Tue Sep 30 06:04:48 EST 2008
* Milton Miller | 2008-09-23 20:24:02 [-0500]:
>If you have any questions about kdump or what needs to happen,
>please feel free to contact me either by email or on irc (sometimes
>I use mdm other times the email login as my nick, and when connected
>I tend to leave it well past the hours I am at the computer).
I copied most of the 64bit code to parse the device tree without the pci
nodes & moved it to 32. The userland *could* work, I'm not sure. My
outout is:
|load: entry = 0x80053c flags = 0
|nr_segments = 2
|segment[0].buf = 0x1002b8f0
|segment[0].bufsz = 80
|segment[0].mem = (nil)
|segment[0].memsz = 1000
|segment[1].buf = 0x4803f008
|segment[1].bufsz = 3a3138
|segment[1].mem = 0x800000
|segment[1].memsz = 3b0000
Now. The entry address in image->start is valid and is the entrypoint of
the "custom" cuImage. Custom means that it does not depend any register
values passed from u-boot (the original one needs a pointer to bd_t).
The only requirement is a valid 1:1 memory mapping.
I learned, that I can not disable the MMU on Book-E so I have to create
a new temporary mapping in my relocate_new_kernel routine. _start is
doing the same thing what I am trying to accomplish: create a new
mapping and don't kill the current one and switch over. This is done by
disabling all mappings but the current, creating a new mapping with
EFN/RPN = 0 and swapping the TS bit in MAS1. This is my current patch
which is not really working:
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index 7a6dfbc..49c9c2a 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -878,22 +878,142 @@ relocate_new_kernel:
/* r4 = reboot_code_buffer */
/* r5 = start_address */
- li r0, 0
+ mr r27, r4
+ mr r28, r5
+ mr r29, r6
+
+ li r25,0 /* phys kernel start (low) */
+ li r24,0 /* CPU number */
+ li r23,0 /* phys kernel start (high) */
+
+
+/* 1. Find the index of the entry we're executing in */
+ bl invstr /* Find our address */
+invstr: mflr r6 /* Make it accessible */
+ mfmsr r7
+ rlwinm r4,r7,27,31,31 /* extract MSR[IS] */
+ mfspr r7, SPRN_PID0
+ slwi r7,r7,16
+ or r7,r7,r4
+ mtspr SPRN_MAS6,r7
+ tlbsx 0,r6 /* search MSR[IS], SPID=PID0 */
+#ifndef CONFIG_E200
+ mfspr r7,SPRN_MAS1
+ andis. r7,r7,MAS1_VALID at h
+ bne match_TLB
The branch above is taken, so I've found my current mapping
+ mfspr r7,SPRN_PID1
+ slwi r7,r7,16
+ or r7,r7,r4
+ mtspr SPRN_MAS6,r7
+ tlbsx 0,r6 /* search MSR[IS], SPID=PID1 */
+ mfspr r7,SPRN_MAS1
+ andis. r7,r7,MAS1_VALID at h
+ bne match_TLB
+ mfspr r7, SPRN_PID2
+ slwi r7,r7,16
+ or r7,r7,r4
+ mtspr SPRN_MAS6,r7
+ tlbsx 0,r6 /* Fall through, we had to match */
+#endif
+match_TLB:
+
+ rlwinm r3,r7,16,20,31 /* Extract MAS0(Entry) */
+
+ mfspr r7,SPRN_MAS1 /* Insure IPROT set */
+ oris r7,r7,MAS1_IPROT at h
+ mtspr SPRN_MAS1,r7
+ tlbwe
+
+/* 2. Invalidate all entries except the entry we're executing in */
+ mfspr r9,SPRN_TLB1CFG
+ andi. r9,r9,0xfff
+ li r6,0 /* Set Entry counter to 0 */
+1: lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */
+ rlwimi r7,r6,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r6) */
+ mtspr SPRN_MAS0,r7
+ tlbre
+ mfspr r7,SPRN_MAS1
+ rlwinm r7,r7,0,2,31 /* Clear MAS1 Valid and IPROT */
+ cmpw r3,r6
+ beq skpinv /* Dont update the current execution TLB */
+ mtspr SPRN_MAS1,r7
+ tlbwe
+ isync
+skpinv: addi r6,r6,1 /* Increment */
+ cmpw r6,r9 /* Are we done? */
+ bne 1b /* If not, repeat */
- /*
- * Set Machine Status Register to a known status,
- * switch the MMU off and jump to 1: in a single step.
- */
+ /* Invalidate TLB0 */
+ li r6,0x04
+ tlbivax 0,r6
+ TLBSYNC
+ /* Invalidate TLB1 */
+ li r6,0x0c
+ tlbivax 0,r6
+ TLBSYNC
- mr r8, r0
- ori r8, r8, MSR_RI|MSR_ME
- mtspr SPRN_SRR1, r8
- addi r8, r4, 1f - relocate_new_kernel
- mtspr SPRN_SRR0, r8
- sync
+/* 3. Setup a temp mapping and jump to it */
+ andi. r5, r3, 0x1 /* Find an entry not used and is non-zero */
+ addi r5, r5, 0x1
+ lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */
+ rlwimi r7,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */
+ mtspr SPRN_MAS0,r7
+ tlbre
+
+ /* set mask to 0xfffff000 , EFN / RPN should be 0 / 0 */
+ li r8, -1
+ li r6, 12
+ slw r6,r8,r6 /* convert to mask */
+
+ li r7, 0 /* find our address */
+ addi r7, r27, current_IP - relocate_new_kernel
+current_IP:
+
+ mfspr r8,SPRN_MAS3
+#ifdef CONFIG_PHYS_64BIT
+ mfspr r23,SPRN_MAS7
+#endif
+ and r8,r6,r8
+ subfic r9,r6,-4096
+ and r9,r9,r7
+
+ or r25,r8,r9
+ ori r8,r25,(MAS3_SX|MAS3_SW|MAS3_SR)
+
+ /* Just modify the entry ID and EPN for the temp mapping */
+ lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */
+ rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */
+ mtspr SPRN_MAS0,r7
+ xori r6,r4,1 /* Setup TMP mapping in the other Address space */
+ slwi r6,r6,12
+ oris r6,r6,(MAS1_VALID|MAS1_IPROT)@h
+ ori r6,r6,(MAS1_TSIZE(BOOKE_PAGESZ_1GB))@l
+ mtspr SPRN_MAS1,r6
+ mfspr r6,SPRN_MAS2
+ li r7,0 /* temp EPN = 0 */
+ rlwimi r7,r6,0,20,31
+
+ mtspr SPRN_MAS2,r7
+ mtspr SPRN_MAS3,r8
Here I get:
MAS0: 0x10010000
MAS1: 0xc0001a00
MAS2: 0x00000000
MAS3: 0x00000015
+ tlbwe
I haven't made it to here.
+
+ xori r6,r4,1
+ slwi r6,r6,5 /* setup new context with other address space */
+
+ li r7, 0 /* find our address */
+ addi r7, r27, old_copy_code - relocate_new_kernel
+
+ mtspr SPRN_SRR0,r7
+ mtspr SPRN_SRR1,r6
rfi
+old_copy_code:
+
+ mr r4, r27
+ mr r5, r28
+ mr r6, r29
+
+ li r0, 0
-1:
/* from this point address translation is turned off */
/* and interrupts are disabled */
In order to dump the MASx values, I did not invalidate the TLBs entries
(s/beq skpinv/b skpinv) and branched to address 0 before the tlbwe to
receive a register dump. This little trick did not work after the tlbwe
instruction. I probably overwrote the wrong / active TLB entry. Since
the TI bit is fliped, this new TLB entry should not be used anyway.
Without invalidating the TLBs, I may have picked the wrong ESEL index
and overwrote either my current mapping or that one that used by the
expection handler/serial port and the bug is somewhere else.
Milton, do have an idea how I could debug this further? My cuImage does
not expect any register values or anything so I thing it hangs here
somewhere and never enter the cuImage code.
>milton
Sebastian
More information about the Linuxppc-dev
mailing list