Re: [UPDATED] [PATCH v4 3/7] [ppc] Process dynamic relocations for kernel
On 12/11/11 01:32, Segher Boessenkool wrote: Hi Suzuki, Looks quite good, a few comments... +get_type: + /* r4 holds the relocation type */ + extrwi r4, r4, 8, 24 /* r4 = ((char*)r4)[3] */ This comment is confusing (only makes sense together with the lwz a long way up). Agree, will fix them. +nxtrela: + /* + * We have to flush the modified instructions to the + * main storage from the d-cache. And also, invalidate the + * cached instructions in i-cache which has been modified. + * + * We delay the msync / isync operation till the end, since + * we won't be executing the modified instructions until + * we return from here. + */ + dcbst r4,r7 + icbi r4,r7 You still need a sync between these two. Without it, the icbi can complete before the dcbst for the same address does, which leaves room for an instruction fetch from that address to get old data. Ok. + cmpwi r8, 0 /* relasz = 0 ? */ + ble done + add r9, r9, r6 /* move to next entry in the .rela table */ + subf r8, r6, r8 /* relasz -= relaent */ + b applyrela + +done: + msync /* Wait for the flush to finish */ The instruction is called sync. msync is a BookE thing. next if (/R_PPC64_RELATIVE/ or /R_PPC64_NONE/ or /R_PPC64_ADDR64\s+mach_/); + next if (/R_PPC_ADDR16_LO/ or /R_PPC_ADDR16_HI/ or + /R_PPC_ADDR16_HA/ or /R_PPC_RELATIVE/); Nothing new, but these should probably have \b or \s or just a space on each side. Will fix this too. Also will include the R_PPC_NONE to the list of valid relocations. Thanks Suzuki Segher ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v4 3/7] [ppc] Process dynamic relocations for kernel
On 12/09/11 19:10, Josh Boyer wrote: On Fri, Dec 9, 2011 at 6:47 AM, Suzuki K. Poulosesuz...@in.ibm.com wrote: Signed-off-by: Suzuki K. Poulosesuz...@in.ibm.com Signed-off-by: Josh Poimboeufjpoim...@linux.vnet.ibm.com Cc: Paul Mackerraspau...@samba.org Cc: Benjamin Herrenschmidtb...@kernel.crashing.org Cc: Alan Modraamo...@au1.ibm.com Cc: Kumar Galaga...@kernel.crashing.org Cc: linuxppc-devlinuxppc-dev@lists.ozlabs.org --- arch/powerpc/Kconfig | 42 ++--- arch/powerpc/Makefile |6 +++-- arch/powerpc/kernel/Makefile |2 ++ arch/powerpc/kernel/vmlinux.lds.S |8 ++- arch/powerpc/relocs_check.pl |7 ++ 5 files changed, 44 insertions(+), 21 deletions(-) You're missing the whole reloc_32.S file in this patch. Forget to do a git-add? Can you resend just this patch with that fixed up? Yikes, missed that. Will send the updated one. Thanks Suzuki josh ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v4 0/7] Kudmp support for PPC440x
On 12/09/11 17:13, Suzuki K. Poulose wrote: The following series implements: * Generic framework for relocatable kernel on PPC32, based on processing the dynamic relocation entries. * Relocatable kernel support for 44x * Kdump support for 44x. Doesn't support 47x yet, as the kexec support is missing. Changes from V3: * Added a new config - NONSTATIC_KERNEL - to group different types of relocatable kernel. (Suggested by: Josh Boyer) * Added supported ppc relocation types in relocs_check.pl for verifying the relocations used in the kernel. Changes from V2: * Renamed old style mapping based RELOCATABLE on BookE to DYNAMIC_MEMSTART. Suggested by: Scott Wood * Added support for DYNAMIC_MEMSTART on PPC440x * Reverted back to RELOCATABLE and RELOCATABLE_PPC32 from RELOCATABLE_PPC32_PIE for relocation based on processing dynamic reloc entries for PPC32. * Ensure the modified instructions are flushed and the i-cache invalidated at the end of relocate(). - Reported by : Josh Poimboeuf Changes from V1: * Splitted patch 'Enable CONFIG_RELOCATABLE for PPC44x' to move some of the generic bits to a new patch. * Renamed RELOCATABLE_PPC32 to RELOCATABLE_PPC32_PIE and provided options to retained old style mapping. (Suggested by: Scott Wood) * Added support for avoiding the overlapping of uncompressed kernel with boot wrapper for PPC images. The patches are based on -next tree for ppc. I have tested these patches on Ebony, Sequoia and Virtex(QEMU Emulated). I haven't tested the RELOCATABLE bits on PPC_47x yet, as I don't have access to one. However, RELOCATABLE should work fine there as we only depend on the runtime address and the XLAT entry setup by the boot loader. It would be great if somebody could test these patches on a 47x. --- Updated diffstats: Suzuki K. Poulose (7): [boot] Change the load address for the wrapper to fit the kernel [44x] Enable CRASH_DUMP for 440x [44x] Enable CONFIG_RELOCATABLE for PPC44x [ppc] Define virtual-physical translations for RELOCATABLE [ppc] Process dynamic relocations for kernel [44x] Enable DYNAMIC_MEMSTART for 440x [booke] Rename mapping based RELOCATABLE to DYNAMIC_MEMSTART for BookE arch/powerpc/Kconfig | 46 +- arch/powerpc/Makefile |6 - arch/powerpc/boot/wrapper | 20 ++ arch/powerpc/configs/44x/iss476-smp_defconfig |2 arch/powerpc/include/asm/kdump.h |4 arch/powerpc/include/asm/page.h | 89 ++- arch/powerpc/kernel/Makefile |2 arch/powerpc/kernel/crash_dump.c |4 arch/powerpc/kernel/head_44x.S| 105 + arch/powerpc/kernel/head_fsl_booke.S |2 arch/powerpc/kernel/machine_kexec.c |2 arch/powerpc/kernel/prom_init.c |2 arch/powerpc/kernel/reloc_32.S| 207 + arch/powerpc/kernel/vmlinux.lds.S |8 + arch/powerpc/mm/44x_mmu.c |2 arch/powerpc/mm/init_32.c |7 + arch/powerpc/relocs_check.pl |7 + 17 files changed, 489 insertions(+), 26 deletions(-) create mode 100644 arch/powerpc/kernel/reloc_32.S Thanks Suzuki ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v3 2/8] [booke] Rename mapping based RELOCATABLE to DYNAMIC_MEMSTART for BookE
On 11/30/11 20:11, Josh Boyer wrote: On Mon, Nov 28, 2011 at 5:59 PM, Scott Woodscottw...@freescale.com wrote: On 11/23/2011 10:47 AM, Josh Boyer wrote: On Mon, Nov 14, 2011 at 12:41 AM, Suzuki K. Poulosesuz...@in.ibm.com wrote: The current implementation of CONFIG_RELOCATABLE in BookE is based on mapping the page aligned kernel load address to KERNELBASE. This approach however is not enough for platforms, where the TLB page size is large (e.g, 256M on 44x). So we are renaming the RELOCATABLE used currently in BookE to DYNAMIC_MEMSTART to reflect the actual method. Should reword the config help to make it clear what the alignment restriction is, or where to find the information for a particular platform. Someone reading page aligned without any context that we're talking about special large pages is going to think 4K -- and on e500, many large page sizes are supported, so the required alignment is found in Linux init code rather than a CPU manual. The CONFIG_RELOCATABLE for PPC32(BookE) based on processing of the dynamic relocations will be introduced in the later in the patch series. This change would allow the use of the old method of RELOCATABLE for platforms which can afford to enforce the page alignment (platforms with smaller TLB size). I'm OK with the general direction, but this touches a lot of non-4xx code. I'd prefer it if Ben took this directly on whatever final solution is done. I haven tested this change only on 440x. I don't have an FSL BookE to verify the changes there. Scott, Could you please test this patch on FSL and let me know the results ? Scott, did you ever get around to testing this? In my opinion, this shouldn't go in without a Tested-by: from someone that tried it on an FSL platform. Booted OK for me on e500v2 with RAM starting at 256M. Tested-by: Scott Woodscottw...@freescale.com We add DYNAMIC_MEMSTART for 32-bit, and we have RELOCATABLE for 64-bit. Then throughout almost the rest of the patch, all we're doing is duplicating what RELOCATABLE already did (e.g. if ! either thing). It works, but it is kind of ugly. Instead, could we define a helper config variable that can be used in place of that construct? Something like: config NONSTATIC_KERNEL (or whatever) bool default n ... config DYNAMIC_MEMSTART blah select NONSTATIC_KERNEL ... config RELOCATABLE blah select NONSTATIC_KERNEL I agree. Suzie do you think you could respin this patch with the suggested changes and include Scott's Tested-by? The rest of the series looks fine and I'd like to get it included in my next branch. Josh, I rebased my patches to 3.2.0-rc3 and was able to verify it on my QEMU setup. However I am facing problems getting the my boards booted with the network cards (even without the patches). Here is what I see : Creating 2 MTD partitions on 1ff80.large-flash: 0x-0x0038 : fs 0x0038-0x0040 : firmware PPC 4xx OCP EMAC driver, version 3.54 mal0: failed to map interrupts ! ZMII /plb/opb/emac-zmii@4780 initialized /plb/opb/ethernet@4800: Timeout waiting for dependent devices /plb/opb/ethernet@4900: Timeout waiting for dependent devices TCP cubic registered NET: Registered protocol family 17 Root-NFS: no NFS server address VFS: Unable to mount root fs via NFS, trying floppy. VFS: Cannot open root device (null) or unknown-block(2,0) Please append a correct root= boot option; here are the available partitions: 1f00 512 mtdblock0 (driver?) 1f013584 mtdblock1 (driver?) 1f02 512 mtdblock2 (driver?) Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(2,0) Have you come across this message ? Thanks Suzuki ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] powerpc/44x: Fix typos '47x' and 'CONFIG_47x'
On 11/15/11 04:00, Paul Bolle wrote: Commit 674bfa4855 (powerpc/44x: Kexec support for PPC440X chipsets) used the Kconfig symbol '47x', and the macro 'CONFIG_47x'. Neither exist. These should have been 'PPC_47x' and 'CONFIG_PPC_47x'. Fix these typos. Thanks for catching this. I have already sent a series which fixes the same. (Sub: Kdump support for PPC440x ). But I think I missed one hunk in the misc_32.S. Also fix a related preprocessor check at the top of kexec.h. Thanks Suzuki ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v3 0/8] Kdump support for PPC440x
[ Don't know what happened to the Cover message. Resending this again ] The following series implements: * Generic framework for relocatable kernel on PPC32, based on processing the dynamic relocation entries. * Relocatable kernel support for 44x * Kdump support for 44x. Doesn't support 47x yet, as the kexec support is missing. Changes from V2: * Renamed old style mapping based RELOCATABLE on BookE to DYNAMIC_MEMSTART. Suggested by: Scott Wood * Added support for DYNAMIC_MEMSTART on PPC440x * Reverted back to RELOCATABLE and RELOCATABLE_PPC32 from RELOCATABLE_PPC32_PIE * Ensure the modified instructions are flushed and the i-cache invalidated at the end of relocate(). - Reported by : Josh Poimboeuf Changes from V1: * Splitted patch 'Enable CONFIG_RELOCATABLE for PPC44x' to move some of the generic bits to a new patch. * Renamed RELOCATABLE_PPC32 to RELOCATABLE_PPC32_PIE and provided options to retained old style mapping. (Suggested by: Scott Wood) * Added support for avoiding the overlapping of uncompressed kernel with boot wrapper for PPC images. The patches are based on -next tree for ppc. I have tested these patches on Ebony, Sequoia and Virtex(QEMU Emulated). I haven't tested the RELOCATABLE bits on PPC_47x yet, as I don't have access to one. However, it should work fine there as we only depend on the runtime address and the XLAT entry setup by the boot loader. It would be great if somebody could test these patches on a 47x. --- Suzuki K. Poulose (8): [boot] Change the load address for the wrapper to fit the kernel [44x] Enable CRASH_DUMP for 440x [44x] Enable CONFIG_RELOCATABLE for PPC44x [ppc] Define virtual-physical translations for RELOCATABLE [ppc] Process dynamic relocations for kernel [44x] Enable DYNAMIC_MEMSTART for 440x [booke] Rename mapping based RELOCATABLE to DYNAMIC_MEMSTART for BookE [44x] Fix typo in KEXEC Kconfig dependency arch/powerpc/Kconfig | 39 - arch/powerpc/Makefile |6 - arch/powerpc/boot/wrapper | 20 ++ arch/powerpc/configs/44x/iss476-smp_defconfig |2 arch/powerpc/include/asm/kdump.h |5 - arch/powerpc/include/asm/page.h | 89 ++- arch/powerpc/kernel/Makefile |2 arch/powerpc/kernel/crash_dump.c |4 arch/powerpc/kernel/head_44x.S| 100 arch/powerpc/kernel/head_fsl_booke.S |2 arch/powerpc/kernel/machine_kexec.c |2 arch/powerpc/kernel/prom_init.c |2 arch/powerpc/kernel/reloc_32.S| 207 + arch/powerpc/kernel/vmlinux.lds.S |8 + arch/powerpc/mm/44x_mmu.c |2 arch/powerpc/mm/init_32.c |7 + 16 files changed, 470 insertions(+), 27 deletions(-) create mode 100644 arch/powerpc/kernel/reloc_32.S -- Suzuki ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v2 1/5] [ppc] Process dynamic relocations for kernel
On 11/09/11 12:03, Suzuki Poulose wrote: On Tue, 08 Nov 2011 10:19:05 -0600 Josh Poimboeufjpoim...@linux.vnet.ibm.com wrote: On Tue, 2011-11-08 at 12:41 +0530, Suzuki Poulose wrote: What I was suggesting is, instead of flushing the cache in relocate(), lets do it like: for e.g, on 440x, (in head_44x.S :) #ifdef CONFIG_RELOCATABLE ... bl relocate #Flush the d-cache and invalidate the i-cache here #endif This would let the different platforms do the the cache invalidation in their own way. Btw, I didn't find an instruction to flush the entire d-cache in PPC440 manual. We have instructions to flush only a block corresponding to an address. However, we have 'iccci' which would invalidate the entire i-cache which, which I think is better than 80,000 i-cache invalidates. In misc_32.S there are already some platform-independent cache management functions. If we use those, then relocate() could simply call them. Then the different platforms calling relocate() wouldn't have to worry about flushing/invalidating caches. For example, there's a clean_dcache_range() function. Given any range twice the size of the d-cache, it should flush the entire d-cache. But the only drawback is that it would require the caller to know the size of the d-cache. Instead, I think it would be preferable to create a new clean_dcache() (or clean_dcache_all()?) function in misc_32.S, which could call clean_dcache_range() with the appropriate args for flushing the entire d-cache. relocate() could then call the platform-independent clean_dcache(). How about using clean_dcache_range() to flush the range runtime address range [ _stext, _end ] ? That would flush the entire instructions. For i-cache invalidation there's already the (incorrectly named?) flush_instruction_cache(). It uses the appropriate platform-specific methods (e.g. iccci for 44x) to invalidate the entire i-cache. Agreed. The only thing that worries me is the use of KERNELBASE in the flush_instruction_cache() for CONFIG_4xx. Can we safely assume all 4xx implementations ignore the arguments passed to iccci ? Suzuki, if you agree with this direction, I could work up a new patch if needed. I have the following (untested) patch which uses clean_dcache_range() and flush_instruction_cache(): I will send the next version soon with those changes and the DYNAMIC_MEMSTART config for oldstyle relocatoin, if every one agrees to this. diff --git a/arch/powerpc/kernel/reloc_32.S b/arch/powerpc/kernel/reloc_32.S index 045d61e..cce0510 100644 --- a/arch/powerpc/kernel/reloc_32.S +++ b/arch/powerpc/kernel/reloc_32.S @@ -33,10 +33,9 @@ R_PPC_RELATIVE = 22 _GLOBAL(relocate) - mflrr0 + mflrr14 /* Save our LR */ bl 0f /* Find our current runtime address */ 0: mflrr12 /* Make it accessible */ - mtlrr0 lwz r11, (p_dyn - 0b)(r12) add r11, r11, r12 /* runtime address of .dynamic section */ @@ -87,18 +86,19 @@ eodyn: /* End of Dyn Table scan */ * Work out the current offset from the link time address of .rela * section. * cur_offset[r7] = rela.run[r9] - rela.link [r7] -* _stext.link[r10] = _stext.run[r10] - cur_offset[r7] -* final_offset[r3] = _stext.final[r3] - _stext.link[r10] +* _stext.link[r12] = _stext.run[r10] - cur_offset[r7] +* final_offset[r3] = _stext.final[r3] - _stext.link[r12] */ subfr7, r7, r9 /* cur_offset */ - subfr10, r7, r10 - subfr3, r10, r3 /* final_offset */ + subfr12, r7, r10 + subfr3, r12, r3 /* final_offset */ subfr8, r6, r8 /* relaz -= relaent */ /* * Scan through the .rela table and process each entry * r9 - points to the current .rela table entry * r13 - points to the symbol table +* r10 - holds the runtime address of _stext */ /* @@ -180,12 +180,23 @@ store_half: nxtrela: cmpwi r8, 0 /* relasz = 0 ? */ - ble done + ble flush add r9, r9, r6 /* move to next entry in the .rela table */ subf r8, r6, r8 /* relasz -= relaent */ b applyrela -done: blr + /* Flush the d-cache'd instructions */ +flush: + mr r3, r10 + lis r4, (_end - _stext)@h + ori r4, r4, (_end - _stext)@l Err ! This doesn't compile : arch/powerpc/kernel/reloc_32.S: Assembler messages: arch/powerpc/kernel/reloc_32.S:191: Error: can't resolve `_end' {*UND* section} - `_stext' {*UND* section} I will fix it, but the idea remains the same. Thanks Suzuki ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v2 1/5] [ppc] Process dynamic relocations for kernel
On 11/09/11 20:23, Josh Poimboeuf wrote: On Wed, 2011-11-09 at 12:03 +0530, Suzuki Poulose wrote: On Tue, 08 Nov 2011 10:19:05 -0600 Josh Poimboeufjpoim...@linux.vnet.ibm.com wrote: On Tue, 2011-11-08 at 12:41 +0530, Suzuki Poulose wrote: What I was suggesting is, instead of flushing the cache in relocate(), lets do it like: for e.g, on 440x, (in head_44x.S :) #ifdef CONFIG_RELOCATABLE ... bl relocate #Flush the d-cache and invalidate the i-cache here #endif This would let the different platforms do the the cache invalidation in their own way. Btw, I didn't find an instruction to flush the entire d-cache in PPC440 manual. We have instructions to flush only a block corresponding to an address. However, we have 'iccci' which would invalidate the entire i-cache which, which I think is better than 80,000 i-cache invalidates. In misc_32.S there are already some platform-independent cache management functions. If we use those, then relocate() could simply call them. Then the different platforms calling relocate() wouldn't have to worry about flushing/invalidating caches. For example, there's a clean_dcache_range() function. Given any range twice the size of the d-cache, it should flush the entire d-cache. But the only drawback is that it would require the caller to know the size of the d-cache. Instead, I think it would be preferable to create a new clean_dcache() (or clean_dcache_all()?) function in misc_32.S, which could call clean_dcache_range() with the appropriate args for flushing the entire d-cache. relocate() could then call the platform-independent clean_dcache(). How about using clean_dcache_range() to flush the range runtime address range [ _stext, _end ] ? That would flush the entire instructions. Wouldn't that result in more cache flushing than the original solution? For example, my kernel is 3.5MB. Assuming a 32 byte cache line size, clean_dcache_range(_stext, _end) would result in about 115,000 dcbst's (3.5MB / 32). Oops ! You are right. We could go back to the clean_dcache_all() or the initial approach that you suggested. (dcbst). I am not sure how do we flush the entire dcache(only). Could you post a patch which does the same ? Another option is to, change the current mapping to 'Write Through' before calling the relocate() and revert back to the original setting after relocate(). For i-cache invalidation there's already the (incorrectly named?) flush_instruction_cache(). It uses the appropriate platform-specific methods (e.g. iccci for 44x) to invalidate the entire i-cache. Agreed. The only thing that worries me is the use of KERNELBASE in the flush_instruction_cache() for CONFIG_4xx. Can we safely assume all 4xx implementations ignore the arguments passed to iccci ? Good question. I don't know the answer. :-) That also may suggest a bigger can of worms. A grep of the powerpc code shows many uses of KERNELBASE. For a relocatable kernel, nobody should be relying on KERNELBASE except for the early relocation code. Are we sure that all the other usages of KERNELBASE are safe? I think we could simply replace the occurrences of KERNELBASE (after the relocate()) with '_stext' which would give the virtual start address of the kernel. Thanks Suzuki ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v2 1/5] [ppc] Process dynamic relocations for kernel
On Tue, 08 Nov 2011 10:19:05 -0600 Josh Poimboeuf jpoim...@linux.vnet.ibm.com wrote: On Tue, 2011-11-08 at 12:41 +0530, Suzuki Poulose wrote: What I was suggesting is, instead of flushing the cache in relocate(), lets do it like: for e.g, on 440x, (in head_44x.S :) #ifdef CONFIG_RELOCATABLE ... bl relocate #Flush the d-cache and invalidate the i-cache here #endif This would let the different platforms do the the cache invalidation in their own way. Btw, I didn't find an instruction to flush the entire d-cache in PPC440 manual. We have instructions to flush only a block corresponding to an address. However, we have 'iccci' which would invalidate the entire i-cache which, which I think is better than 80,000 i-cache invalidates. In misc_32.S there are already some platform-independent cache management functions. If we use those, then relocate() could simply call them. Then the different platforms calling relocate() wouldn't have to worry about flushing/invalidating caches. For example, there's a clean_dcache_range() function. Given any range twice the size of the d-cache, it should flush the entire d-cache. But the only drawback is that it would require the caller to know the size of the d-cache. Instead, I think it would be preferable to create a new clean_dcache() (or clean_dcache_all()?) function in misc_32.S, which could call clean_dcache_range() with the appropriate args for flushing the entire d-cache. relocate() could then call the platform-independent clean_dcache(). How about using clean_dcache_range() to flush the range runtime address range [ _stext, _end ] ? That would flush the entire instructions. For i-cache invalidation there's already the (incorrectly named?) flush_instruction_cache(). It uses the appropriate platform-specific methods (e.g. iccci for 44x) to invalidate the entire i-cache. Agreed. The only thing that worries me is the use of KERNELBASE in the flush_instruction_cache() for CONFIG_4xx. Can we safely assume all 4xx implementations ignore the arguments passed to iccci ? Suzuki, if you agree with this direction, I could work up a new patch if needed. I have the following (untested) patch which uses clean_dcache_range() and flush_instruction_cache(): I will send the next version soon with those changes and the DYNAMIC_MEMSTART config for oldstyle relocatoin, if every one agrees to this. diff --git a/arch/powerpc/kernel/reloc_32.S b/arch/powerpc/kernel/reloc_32.S index 045d61e..cce0510 100644 --- a/arch/powerpc/kernel/reloc_32.S +++ b/arch/powerpc/kernel/reloc_32.S @@ -33,10 +33,9 @@ R_PPC_RELATIVE = 22 _GLOBAL(relocate) - mflrr0 + mflrr14 /* Save our LR */ bl 0f /* Find our current runtime address */ 0: mflrr12 /* Make it accessible */ - mtlrr0 lwz r11, (p_dyn - 0b)(r12) add r11, r11, r12 /* runtime address of .dynamic section */ @@ -87,18 +86,19 @@ eodyn: /* End of Dyn Table scan */ * Work out the current offset from the link time address of .rela * section. * cur_offset[r7] = rela.run[r9] - rela.link [r7] -* _stext.link[r10] = _stext.run[r10] - cur_offset[r7] -* final_offset[r3] = _stext.final[r3] - _stext.link[r10] +* _stext.link[r12] = _stext.run[r10] - cur_offset[r7] +* final_offset[r3] = _stext.final[r3] - _stext.link[r12] */ subfr7, r7, r9 /* cur_offset */ - subfr10, r7, r10 - subfr3, r10, r3 /* final_offset */ + subfr12, r7, r10 + subfr3, r12, r3 /* final_offset */ subfr8, r6, r8 /* relaz -= relaent */ /* * Scan through the .rela table and process each entry * r9 - points to the current .rela table entry * r13 - points to the symbol table +* r10 - holds the runtime address of _stext */ /* @@ -180,12 +180,23 @@ store_half: nxtrela: cmpwi r8, 0 /* relasz = 0 ? */ - ble done + ble flush add r9, r9, r6 /* move to next entry in the .rela table */ subf r8, r6, r8 /* relasz -= relaent */ b applyrela -done: blr + /* Flush the d-cache'd instructions */ +flush: + mr r3, r10 + lis r4, (_end - _stext)@h + ori r4, r4, (_end - _stext)@l + add r4, r3, r4 + bl clean_dcache_range + /* Invalidate the i-cache */ + bl flush_instruction_cache +done: + mtlrr14 + blr p_dyn: .long __dynamic_start - 0b Thanks Suzuki ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v2 1/5] [ppc] Process dynamic relocations for kernel
On 11/07/11 20:43, Josh Poimboeuf wrote: On Fri, 2011-11-04 at 14:06 +0530, Suzuki Poulose wrote: On 11/03/11 05:06, Josh Poimboeuf wrote: On Tue, 2011-10-25 at 17:23 +0530, Suzuki K. Poulose wrote: @@ -137,6 +137,9 @@ get_type: lwz r0, 8(r9) /* r_addend */ add r0, r0, r3 /* final addend */ stwxr0, r4, r7 /* memory[r4+r7]) = (u32)r0 */ + dcbst r4,r7 /* flush dcache line to memory */ + sync/* wait for flush to complete */ + icbir4,r7 /* invalidate icache line */ Doing it this way has two drawbacks : 1) Placing it here in relocate would do the flushing for each and every update. I agree. My kernel had around 80,000 relocations, which means 80,000 d-cache line flushes (for a 32k d-cache) and 80,000 i-cache line invalidates (for a 32k i-cache). Which is obviously a little overkill. Although I didn't notice a performance hit during boot. 2) I would like to keep this code as generic as possible for the PPC32 code. Could we move this to the place from relocate is called and flush the d-cache and i-cache entirely ? Why not put the cache flushing code at the end of relocate? Would some of the other PPC32 platforms not require the cache flushing? What I was suggesting is, instead of flushing the cache in relocate(), lets do it like: for e.g, on 440x, (in head_44x.S :) #ifdef CONFIG_RELOCATABLE ... bl relocate #Flush the d-cache and invalidate the i-cache here #endif This would let the different platforms do the the cache invalidation in their own way. Btw, I didn't find an instruction to flush the entire d-cache in PPC440 manual. We have instructions to flush only a block corresponding to an address. However, we have 'iccci' which would invalidate the entire i-cache which, which I think is better than 80,000 i-cache invalidates. Kumar / Josh, Do you have any suggestions here ? My PPC32 knowledge is 4xx-centric, so please feel free to rewrite the patch as needed to accommodate other PPC32 cores. Same here :) Thanks Suzuki ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v2 1/5] [ppc] Process dynamic relocations for kernel
On 11/03/11 05:06, Josh Poimboeuf wrote: On Tue, 2011-10-25 at 17:23 +0530, Suzuki K. Poulose wrote: The following patch implements the dynamic relocation processing for PPC32 kernel. relocate() accepts the target virtual address and relocates the kernel image to the same. Hi Suzuki, Thanks for the patches. I've been testing them on a 440-based card, and encountered TLB error exceptions because the BSS section wasn't getting properly cleared in early_init(). Thanks a lot for the testing. It turns out that some of the instructions which were modified in relocate() weren't then getting flushed out of the d-cache into memory. After that, early_init() executed the stale (non-modified) instructions for the BSS area. Those instructions just accessed offset 0 instead of the actual BSS-related offsets. That resulted in BSS not getting` zeroed. I was able to verify this on my 440 by comparing the d-cache and i-cache entries for the BSS-accessing instructions in early_init() using a RISCWatch. As I suspected, the instructions in the d-cache showed the corrected offsets, but the i-cache showed the old, non-relocated offsets. To fix the issue, I wrote the following patch, applied on top of your patches. Suggestions and comments are welcome. From c88ae39da0c0352f411aca8d9636990a442d47da Mon Sep 17 00:00:00 2001 From: Josh Poimboeufjpoim...@linux.vnet.ibm.com Date: Wed, 2 Nov 2011 16:41:24 -0500 Subject: [PATCH] Flush relocated instructions from data cache After updating instructions with relocated addresses, flush them from the data cache and invalidate the icache line so we don't execute stale instructions. Signed-off-by: Josh Poimboeufjpoim...@linux.vnet.ibm.com --- arch/powerpc/kernel/reloc_32.S | 11 ++- 1 files changed, 10 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/kernel/reloc_32.S b/arch/powerpc/kernel/reloc_32.S index 045d61e..a92857d 100644 --- a/arch/powerpc/kernel/reloc_32.S +++ b/arch/powerpc/kernel/reloc_32.S @@ -137,6 +137,9 @@ get_type: lwz r0, 8(r9) /* r_addend */ add r0, r0, r3 /* final addend */ stwxr0, r4, r7 /* memory[r4+r7]) = (u32)r0 */ + dcbst r4,r7 /* flush dcache line to memory */ + sync/* wait for flush to complete */ + icbir4,r7 /* invalidate icache line */ Doing it this way has two drawbacks : 1) Placing it here in relocate would do the flushing for each and every update. 2) I would like to keep this code as generic as possible for the PPC32 code. Could we move this to the place from relocate is called and flush the d-cache and i-cache entirely ? Thanks Suzuki ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 2/3] [44x] Enable CONFIG_RELOCATABLE for PPC44x
On 10/27/11 00:46, Scott Wood wrote: On 10/26/2011 02:12 PM, Suzuki Poulose wrote: On 10/25/11 21:04, Scott Wood wrote: On 10/12/2011 09:15 AM, Dave Hansen wrote: This is not the place to enforce that kind of thing. If CONFIG_RELOCATABLE is only supported on one platform, then do: config RELOCATABLE depends on 44x and take the 44x reference out of the #ifdef. ...but please first rename the existing, different CONFIG_RELOCATABLE behavior that is currently supported on e500. Scott, I have renamed the new type of relocation to RELOCATABLE_PPC32_PIE. The patches were posted yesterday. Please let me know your thoughts. I think it would make more sense to rename the existing behavior (maybe something like DYNAMIC_MEMSTART -- if there's even enough overhead to make it worth being configurable at all), since it's not fully relocatable and since 64-bit already uses RELOCATABLE to mean PIE. I think leaving the current behaviour as it is, and adding the PIE as an additional configuration option would be safe and wouldn't disturb the existing dependencies. ( CRASH_DUMP etc. depend on RELOCATABLE for archs which work fine ). For architectures with smaller TLB sizes, can afford to do the page aligned old style mapping and not worry about PIE at all. Thats just my view. Disclaimer : I am not an expert in the BookE land. :-) Thanks Suzuki ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 2/3] [44x] Enable CONFIG_RELOCATABLE for PPC44x
On 10/27/11 21:11, Scott Wood wrote: On 10/27/2011 03:43 AM, Suzuki Poulose wrote: On 10/27/11 00:46, Scott Wood wrote: On 10/26/2011 02:12 PM, Suzuki Poulose wrote: I have renamed the new type of relocation to RELOCATABLE_PPC32_PIE. The patches were posted yesterday. Please let me know your thoughts. I think it would make more sense to rename the existing behavior (maybe something like DYNAMIC_MEMSTART -- if there's even enough overhead to make it worth being configurable at all), since it's not fully relocatable and since 64-bit already uses RELOCATABLE to mean PIE. I think leaving the current behaviour as it is, and adding the PIE as an additional configuration option would be safe and wouldn't disturb the existing dependencies. That's how things grow to be an unmaintainable mess. AFAICT, what you're doing is the same as what 64-bit does for RELOCATABLE. If they're doing the same thing, they should be called the same thing. Whereas 64-bit and e500 are currently doing different things for RELOCATABLE -- so they should be called different things. OK. Agreed. I will resend the patches with the change. Thanks Suzuki ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 2/3] [44x] Enable CONFIG_RELOCATABLE for PPC44x
On 10/25/11 21:04, Scott Wood wrote: On 10/12/2011 09:15 AM, Dave Hansen wrote: On Tue, 2011-10-11 at 18:24 +0530, Suzuki Poulose wrote: On 10/10/11 23:30, Scott Wood wrote: On 10/10/2011 04:56 AM, Suzuki K. Poulose wrote: #if defined(CONFIG_RELOCATABLE) defined(CONFIG_44x) #define __va(x) ((void *)(unsigned long)((phys_addr_t)(x) - PHYSICAL_START + (KERNELBASE + RELOC_OFFSET))) #define __pa(x) ((unsigned long)(x) + PHYSICAL_START - (KERNELBASE + RELOC_OFFSET)) #endif Why is this 44x-specific? As of now, we compile with relocations only for the 44x. We could make this generic once the approach is accepted by everyone and implemented on the other platforms. This is not the place to enforce that kind of thing. If CONFIG_RELOCATABLE is only supported on one platform, then do: config RELOCATABLE depends on 44x and take the 44x reference out of the #ifdef. ...but please first rename the existing, different CONFIG_RELOCATABLE behavior that is currently supported on e500. Scott, I have renamed the new type of relocation to RELOCATABLE_PPC32_PIE. The patches were posted yesterday. Please let me know your thoughts. Thanks Suzuki ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: Kdump/kexec for mpc83xx
On 10/24/11 18:05, radha krishna wrote: Hi Team, I am using Linux-3.0 on mpc8379 RDB. I have downloaded kexec-tools-2.0.2 package from open source and cross compiled for ppc_6xx. But, the kexec is not booting with kernel loaded with kexec -l. I am not familiar with mcp8379 RDB. AFAIK, the ppc32 port of kexec-tools work just fine. You may need to check the kernel side to see if you are setting up the 'real mode' environment for the kernel copy step. Thanks Suzuki ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 2/3] [44x] Enable CONFIG_RELOCATABLE for PPC44x
On 10/10/11 23:30, Scott Wood wrote: On 10/10/2011 04:56 AM, Suzuki K. Poulose wrote: #if defined(CONFIG_RELOCATABLE) defined(CONFIG_44x) #define __va(x) ((void *)(unsigned long)((phys_addr_t)(x) - PHYSICAL_START + (KERNELBASE + RELOC_OFFSET))) #define __pa(x) ((unsigned long)(x) + PHYSICAL_START - (KERNELBASE + RELOC_OFFSET)) #endif Why is this 44x-specific? As of now, we compile with relocations only for the 44x. We could make this generic once the approach is accepted by everyone and implemented on the other platforms. Thanks Suzuki ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 1/3] [powerpc32] Process dynamic relocations for kernel
On 10/10/11 20:45, Scott Wood wrote: On 10/10/2011 04:55 AM, Suzuki K. Poulose wrote: The following patch implements the dynamic relocation processing for PPC32 kernel. relocate() accepts the target virtual address and relocates the kernel image to the same. How much overhead is involved in a true relocatable kernel? Is it worth preserving the old relocatable booke behavior under a different name? There are '75782' on an ebony kernel with minimal config. So thats a pretty big number for small embedded chips. I guess, preserving the 'old relocatable' (page aligned approach) would be a good idea for the architectures which can afford it. e.g, places where TLB size is 64M or less. Thanks Suzuki ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Defintion of kernstart_addr
Hi Kumar, I have been working on the CONFIG_RELOCATABLE support for PPC44x, trying to process the relocations generated by the compiler. Since the TLB size is 256M, we cannot enforce a page aligned kernel load address. I came across some issues with the __va() / __pa() translations, while the kernel load address is not page aligned. We have the following definition : #define __va(x) ((void *)(unsigned long)((phys_addr_t)(x) - PHYSICAL_START + KERNELBASE) where, PHYSICAL_START is #define'd to kernstart_addr variable, updated at boot time. I would like to know the exact meaning of the value in kerstart_addr. For e.g: When we have : PAGE_OFFSET = KERNELBASE = 0xc000, and kernel loaded at 64M (0x400) and we map Physical address 0 to Virtual address 0xc000. What should be the value of kernstart_addr ? Should it be 0 ? Or should it be 0x400 ? If we choose, 0x400, we get the translations wrong : __va(0x1) = 0x1 - 0x400 + 0xc000 = 0xbc01 If we select 0, we have problems at other places where we assume, PHYSICAL_START to be the va() of _stext. Thanks Suzuki ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [RFC] CONFIG_RELOCATABLE : __va() __pa() definitions
On 09/29/11 04:33, Benjamin Herrenschmidt wrote: On Tue, 2011-09-27 at 17:54 +0530, Suzuki Poulose wrote: Hi, I am working on enabling CONFIG_RELOCATABLE for PPC44x Embedded PowerPC boards as a foundation to enable CONFIG_CRASH_DUMP. After a discussion on the linux-ppcdev we decided that we will follow the 'processing relocation entries' approach for running the kernel from a different address. I think the best approach is to not touch KERNELBASE and PAGE_OFFSET, and just process relocations, that way __va() and __pa() are unoutched and plenty of other stuff won't break. Ben, I am processing the relocations in my approach. But even in that case, __va(), __pa() needs modification since , on BookE, we depend on PHYSICAL_START(kernstart_addr) to do the translations. So depending on the kernstart_addr, the __va() keeps changing, even though the mappings doesn't change. (Virtual to Physical mapping). Please note that, since we use 256M mappings, any address within the 256M will result in the same mapping. | Phys. Addr| Virt. Addr| PageBoundary (256M) |---| | | | | | | | | | (Phys. Start)%256M- |___|_ _ _ _ _ _ _ _|- Relocated. Kernel | | ^ | Virtual Address | | | | | | | | | | reloc_offset | | | | | | | | | | |___v___|-(KERNELBASE)% | | | 256M | | | | | | | | | | | | PageBoundary (256M) |---|---| | | | | | | Thanks Suzuki ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[RFC] CONFIG_RELOCATABLE : __va() __pa() definitions
Hi, I am working on enabling CONFIG_RELOCATABLE for PPC44x Embedded PowerPC boards as a foundation to enable CONFIG_CRASH_DUMP. After a discussion on the linux-ppcdev we decided that we will follow the 'processing relocation entries' approach for running the kernel from a different address. On PPC44x we pin the kernel text/data sections using 256M sized TLB entries. Since the embedded boards have limited amount of RAM, we cannot enforce the kernel load address to be aligned to 256M. This prevents us from mapping the 'loaded physical address' of the kernel to 'KERNELBASE' (virtual address of the kernel start). So we are forced to generate relocation entries and process them before we start using the virtual address(s) at the kernel boot time. Please note that the KERNELBASE doesn't have to be 256M aligned. I have adopted the following method for finding the relocation offset. 1) Find the physical address of _start (start of kernel text) 2) Calculate the relocation offset as : reloc_offset = (Phy_Addr(_stext) % 256M) - (KERNELBASE % 256M) And then map ALIGN_DOWN(KERNELBASE,256M) to ALIGN_DOWN(Phys_Addr(_stext),256M). | Phys. Addr| Virt. Addr| PageBoundary (256M) |---| | | | | | | | | | (Phys. Start)%256M-|___|_ _ _ _ _ _ _ _|- Act. Kernel | | ^ | Virtual Address | | | | | | | | | | reloc_offset | | | | | | | | | | |___v___|-(KERNELBASE)% | | | 256M | | | | | | | | | | | | PageBoundary (256M) |---|---| | | | | | | So the conversion of the addresses from virtual to physical and vice versa, needs to take care of the actual kernel virtual address taking into account of the relocation offset. Currently __va() __pa() has been defined as follows : #define __va(x) ((void *)(unsigned long)((phys_addr_t)(x) - PHYSICAL_START + KERNELBASE)) #define __pa(x) ((unsigned long)(x) + PHYSICAL_START - KERNELBASE) Where: * PHYSICAL_START (defined to variable, kernstart_addr) which holds the physical address where the kernel is loaded. This variable is initialized at the boot time. * KERNELBASE is the (compiled) kernel virtual start address. These definitions would hold only if the load address is Page aligned, which is not feasible onf PPC44x(as mentioned in the beginning). So we need new definitions for them in CONFIG_RELOCATABLE case. Here are the solutions that I could think of : 1) Update kernstart_addr(PHSYICAL_START) to match the Physical address of KERNELBASE. i.e, kernstart_addr = Phys.Addr(_stext) + Reloc Offset This may not sound good, however, the kernstart_addr is only used for the __va()/__pa() calculation. So we are OK to use that. 2) Redefine __va() __pa() i.e, #if defined(CONFIG_RELOCATABLE) defined(CONFIG_44x) #define __va(x) ((void *)(unsigned long)((phys_addr_t)(x) - PHYSICAL_START + (KERNELBASE + RELOC_OFFSET))) #define __pa(x) ((unsigned long)(x) + PHYSICAL_START - (KERNELBASE + RELOC_OFFSET)) #endif where, RELOC_OFFSET could be a) Either stored in a variable, say relocation_offset (like kernstart_addr) at boot time. OR b) #define RELOC_OFFSET ((PHYSICAL_START PPC_PIN_SIZE_OFFSET_MASK) - \ (KERNELBASE PPC_PIN_SIZE_OFFSET_MASK)) I am more tempted to adopt 2(a). Could you please let me know your suggestions / thoughts / comments. OR Do should we support CONFIG_RELOCATABLE CONFIG_KERNEL_START in the same time ? Thanks Suzuki ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[RFC] CONFIG_RELOCATABLE - __va() , __pa() definitions
[Resending - Missed a few key people on the Cc list + Some more comments] Hi, I am working on enabling CONFIG_RELOCATABLE for PPC44x Embedded PowerPC boards as a foundation to enable CONFIG_CRASH_DUMP. After a discussion on the linux-ppcdev , we decided that we will follow the 'processing relocation entries' approach for running the kernel from a different address. http://lists.ozlabs.org/pipermail/linuxppc-dev/2011-June/090986.html On PPC44x we pin the kernel text/data sections using 256M sized TLB entries. Since the embedded boards have limited amount of RAM, we cannot enforce the kernel load address to be aligned to 256M. This prevents us from mapping the 'loaded physical address' of the kernel to 'KERNELBASE' (virtual address of the kernel start). So we are forced to generate relocation entries and process them before we start using the virtual address(s) at the kernel boot time. Please note that the KERNELBASE doesn't have to be 256M aligned. I have adopted the following method for finding the relocation offset. 1) Find the physical address of _start (start of kernel text) 2) Calculate the relocation offset as : reloc_offset = (Phy_Addr(_stext) % 256M) - (KERNELBASE % 256M) And then map ALIGN_DOWN(KERNELBASE,256M) to ALIGN_DOWN(Phys_Addr(_stext),256M). | Phys. Addr| Virt. Addr| PageBoundary(256M) |---| | | | | | | | | | (Phys. Start)%256M-|___|_ _ _ _ _ _ _ _|- Act.Kernel | | ^ | Virtual Address | | | | | | | | | | reloc_offset | | | | | | | | | | |___v___|-(KERNELBASE)% | | | 256M | | | | | | | | | | | | PageBoundary(256M) |---|---| | | | | | | So the conversion of the addresses from virtual to physical and vice versa, needs to take care of the actual kernel virtual address taking into account of the relocation offset. Currently __va() __pa() has been defined as follows : #define __va(x) ((void *)(unsigned long)((phys_addr_t)(x) - PHYSICAL_START + KERNELBASE)) #define __pa(x) ((unsigned long)(x) + PHYSICAL_START - KERNELBASE) Where: * PHYSICAL_START (defined to variable, kernstart_addr) which holds the physical address where the kernel is loaded. This variable is initialized at the boot time. * KERNELBASE is the (compiled) kernel virtual start address. These definitions would hold only if the load address is Page aligned, which is not feasible onf PPC44x(as mentioned in the beginning). So we need new definitions for them in CONFIG_RELOCATABLE case. Here are the solutions that I could think of : 1) Update kernstart_addr(PHSYICAL_START) to match the Physical address of KERNELBASE. i.e, kernstart_addr = Phys.Addr(_stext) + Reloc Offset This may not sound good, however, the kernstart_addr is only used for the __va()/__pa() calculation. So we are OK to use that. 2) Redefine __va() __pa() i.e, #if defined(CONFIG_RELOCATABLE) defined(CONFIG_44x) #define __va(x) ((void *)(unsigned long)((phys_addr_t)(x) - PHYSICAL_START + (KERNELBASE + RELOC_OFFSET))) #define __pa(x) ((unsigned long)(x) + PHYSICAL_START - (KERNELBASE + RELOC_OFFSET)) #endif where, RELOC_OFFSET could be a) Either stored in a variable, say relocation_offset (like kernstart_addr) at boot time. OR b) #define RELOC_OFFSET ((PHYSICAL_START PPC_PIN_SIZE_OFFSET_MASK) - \ (KERNELBASE PPC_PIN_SIZE_OFFSET_MASK)) 3) Enforce CONFIG_KERNEL_START (i.e, KERNELBASE) to be PPC_PIN_SIZE(256M on PPC44x) aligned. I am more tempted to adopt 2(a). Could you please let me know your suggestions / thoughts / comments. Thanks Suzuki ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] PSeries: Cancel RTAS event scan before firmware flash
On 08/30/11 11:33, Benjamin Herrenschmidt wrote: On Wed, 2011-07-27 at 17:39 +0530, Ravi K. Nittala wrote: The firmware flash update is conducted using an RTAS call, that is serialized by lock_rtas() which uses spin_lock. rtasd keeps scanning for the RTAS events generated on the machine. This is performed via a delayed workqueue, invoking an RTAS call to scan the events. The flash update takes a while to complete and during this time, any other RTAS call has to wait. In this case, rtas_event_scan() waits for a long time on the spin_lock resulting in a soft lockup. Approaches to fix the issue : Approach 1: Stop all the other CPUs before we start flashing the firmware. Before the rtas firmware update starts, all other CPUs should be stopped. Which means no other CPU should be in lock_rtas(). We do not want other CPUs execute while FW update is in progress and the system will be rebooted anyway after the update. Shouldn't we resume the event scan after the flash ? The flash operation is performed in the reboot path at the very end. So, even if we restart the event scan, the thread may not be able to process the events. Hence we thought we would leave it stopped. Again, we do not have much expertise in deciding which is the best thing to do. We could resume the event scan, if you think that is needed. Thanks for the review. Suzuki ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] PSeries: Cancel RTAS event scan before firmware flash
On 08/30/11 11:51, Benjamin Herrenschmidt wrote: On Tue, 2011-08-30 at 16:19 +1000, Benjamin Herrenschmidt wrote: On Tue, 2011-08-30 at 11:47 +0530, Suzuki Poulose wrote: The flash operation is performed in the reboot path at the very end. So, even if we restart the event scan, the thread may not be able to process the events. Hence we thought we would leave it stopped. Again, we do not have much expertise in deciding which is the best thing to do. We could resume the event scan, if you think that is needed. Thanks for the review. No that's ok, I'll merge the patch as-is then. Actually, please dbl check you get the dependencies right. The event scan stuff is only compiled if CONFIG_PPC_RTAS_DAEMON is set, but the rtas flash code depends on a different config option that can be set independently. So at the very least you need an ifdef to guard the cross-call Thanks for catching this ! Will address this in the next version. Thanks Suzuki ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] PSeries: Cancel RTAS event scan before firmware flash
On 07/27/11 17:39, Ravi K. Nittala wrote: The firmware flash update is conducted using an RTAS call, that is serialized by lock_rtas() which uses spin_lock. rtasd keeps scanning for the RTAS events generated on the machine. This is performed via a delayed workqueue, invoking an RTAS call to scan the events. The flash update takes a while to complete and during this time, any other RTAS call has to wait. In this case, rtas_event_scan() waits for a long time on the spin_lock resulting in a soft lockup. Approaches to fix the issue : Approach 1: Stop all the other CPUs before we start flashing the firmware. Before the rtas firmware update starts, all other CPUs should be stopped. Which means no other CPU should be in lock_rtas(). We do not want other CPUs execute while FW update is in progress and the system will be rebooted anyway after the update. --- arch/powerpc/kernel/setup-common.c.orig2011-07-01 22:41:12.952507971 -0400 +++ arch/powerpc/kernel/setup-common.c2011-07-01 22:48:31.182507915 -0400 @@ -109,11 +109,12 @@ void machine_shutdown(void) void machine_restart(char *cmd) { machine_shutdown(); -if (ppc_md.restart) -ppc_md.restart(cmd); #ifdef CONFIG_SMP -smp_send_stop(); +smp_send_stop(); #endif +if (ppc_md.restart) +ppc_md.restart(cmd); + printk(KERN_EMERG System Halted, OK to turn off power\n); local_irq_disable(); while (1) ; Problems with this approach: Stopping the CPUs suddenly may cause other serious problems depending on what was running on them. Hence, this approach cannot be considered. Approach 2: Cancel the rtas_scan_event work before starting the firmware flash. Just before the flash update is performed, the queued rtas_event_scan() work item is cancelled from the work queue so that there is no other RTAS call issued while the flash is in progress. After the flash completes, the system reboots and the rtas_event_scan() is rescheduled. Approach 2 looks to be a better solution than Approach 1. Kindly let us know your thoughts. Patch attached. Ben, Could you please let us know your thoughts about the following patch ? Thanks Suzuki Signed-off-by: Suzuki Poulosesuz...@in.ibm.com Signed-off-by: Ravi Nittalaravi.nitt...@in.ibm.com --- arch/powerpc/include/asm/rtas.h |2 ++ arch/powerpc/kernel/rtas_flash.c |6 ++ arch/powerpc/kernel/rtasd.c |6 ++ 3 files changed, 14 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h index 58625d1..3f26f87 100644 --- a/arch/powerpc/include/asm/rtas.h +++ b/arch/powerpc/include/asm/rtas.h @@ -245,6 +245,8 @@ extern int early_init_dt_scan_rtas(unsigned long node, extern void pSeries_log_error(char *buf, unsigned int err_type, int fatal); +extern bool rtas_cancel_event_scan(void); + /* Error types logged. */ #define ERR_FLAG_ALREADY_LOGGED 0x0 #define ERR_FLAG_BOOT 0x1 /* log was pulled from NVRAM on boot */ diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c index e037c74..4174b4b 100644 --- a/arch/powerpc/kernel/rtas_flash.c +++ b/arch/powerpc/kernel/rtas_flash.c @@ -568,6 +568,12 @@ static void rtas_flash_firmware(int reboot_type) } /* +* Just before starting the firmware flash, cancel the event scan work +* to avoid any soft lockup issues. +*/ + rtas_cancel_event_scan(); + + /* * NOTE: the first block must be under 4GB, so we create * an entry with no data blocks in the reserved buffer in * the kernel data segment. diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c index 481ef06..e8f03fa 100644 --- a/arch/powerpc/kernel/rtasd.c +++ b/arch/powerpc/kernel/rtasd.c @@ -472,6 +472,12 @@ static void start_event_scan(void) event_scan_work, event_scan_delay); } +/* Cancel the rtas event scan work */ +bool rtas_cancel_event_scan(void) +{ + return cancel_delayed_work_sync(event_scan_work); +} + static int __init rtas_init(void) { struct proc_dir_entry *entry; ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v2] powerpc32: Kexec support for PPC440X chipsets
On 07/12/11 12:14, Suzuki K. Poulose wrote: Changes from V1: Uses a tmp mapping in the other address space to setup the 1:1 mapping (suggested by Sebastian Andrzej Siewior). Note: Should we do the same for kernel entry code for PPC44x ? This patch adds kexec support for PPC440 based chipsets.This work is based on the KEXEC patches for FSL BookE. The FSL BookE patch and the code flow could be found at the link below: http://patchwork.ozlabs.org/patch/49359/ Steps: 1) Invalidate all the TLB entries except the one this code is run from 2) Create a tmp mapping for our code in the other address space and jump to it 3) Invalidate the entry we used 4) Create a 1:1 mapping for 0-2GiB in blocks of 256M 5) Jump to the new 1:1 mapping and invalidate the tmp mapping I have tested this patches on Ebony, Sequoia boards and Virtex on QEMU. It would be great if somebody could test this on the other boards. Forgot to mention: You would need the current snapshot of kexec-tools, available at git://git.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git The following commits(in the current tree) are needed for the support of ppc32. commit 13f6d71bdf9836b90ae4ec21209383f1a3c56b0f kexec-tools: ppc32: Fixup ThreadPointer for purgatory code commit 9ec3fac7e8840fb31891ba49a626c5dd33e09e86 kexec-tools: powerpc: Use the #address-cells information to parsememory/reg commit 806ef8870539a6c74a2a98188d0207a038b16f77 Fix memory errors on ppc Thanks Suzuki ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v2] powerpc32: Kexec support for PPC440X chipsets
On 07/13/11 10:58, Kumar Gala wrote: On Jul 12, 2011, at 1:44 AM, Suzuki K. Poulose wrote: Changes from V1: Uses a tmp mapping in the other address space to setup the 1:1 mapping (suggested by Sebastian Andrzej Siewior). Note: Should we do the same for kernel entry code for PPC44x ? This patch adds kexec support for PPC440 based chipsets.This work is based on the KEXEC patches for FSL BookE. The FSL BookE patch and the code flow could be found at the link below: http://patchwork.ozlabs.org/patch/49359/ Steps: 1) Invalidate all the TLB entries except the one this code is run from 2) Create a tmp mapping for our code in the other address space and jump to it 3) Invalidate the entry we used 4) Create a 1:1 mapping for 0-2GiB in blocks of 256M 5) Jump to the new 1:1 mapping and invalidate the tmp mapping I have tested this patches on Ebony, Sequoia boards and Virtex on QEMU. It would be great if somebody could test this on the other boards. Signed-off-by: Suzuki Poulosesuz...@in.ibm.com Cc: Sebastian Andrzej Siewiorbige...@linutronix.de --- arch/powerpc/Kconfig |2 arch/powerpc/include/asm/kexec.h |2 arch/powerpc/kernel/misc_32.S| 170 ++ 3 files changed, 172 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 423145a6..d04fae0 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -349,7 +349,7 @@ config ARCH_ENABLE_MEMORY_HOTREMOVE config KEXEC bool kexec system call (EXPERIMENTAL) - depends on (PPC_BOOK3S || FSL_BOOKE) EXPERIMENTAL + depends on (PPC_BOOK3S || FSL_BOOKE || (44x !SMP !47x)) EXPERIMENTAL Is there something special about 47x that its not supported? At the moment, I have not written the code for doing the 47x TLB setup which is slightly different from 44x. It is in my TODO list. I don't have access to a 47x yet. I will work on it once I get access to the board. Thanks Suzuki help kexec is a system call that implements the ability to shutdown your current kernel, and to start another kernel. It is like a reboot - k ___ kexec mailing list ke...@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [RFC PATCH 7/7] powerpc: Support RELOCATABLE kernel for PPC44x
On 06/16/11 19:44, Michal Simek wrote: Changes: - Find out address where kernel runs - Create the first 256MB TLB from online detected address Limitations: - Kernel must be aligned to 256MB Backport: - Changes in page.h are backported from newer kernel version mmu_mapin_ram function has to reflect offset in memory start. memstart_addr and kernstart_addr are setup directly from asm code to ensure that only ppc44x is affected. Signed-off-by: Michal Simekmon...@monstr.eu --- arch/powerpc/Kconfig|3 ++- arch/powerpc/include/asm/page.h |7 ++- arch/powerpc/kernel/head_44x.S | 28 arch/powerpc/mm/44x_mmu.c |6 +- 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 45c9683..34c521e 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -796,7 +796,8 @@ config LOWMEM_CAM_NUM config RELOCATABLE bool Build a relocatable kernel (EXPERIMENTAL) - depends on EXPERIMENTAL ADVANCED_OPTIONS FLATMEM FSL_BOOKE + depends on EXPERIMENTAL ADVANCED_OPTIONS FLATMEM + depends on FSL_BOOKE || (44x !SMP) help This builds a kernel image that is capable of running at the location the kernel is loaded at (some alignment restrictions may diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h index 4940662..e813cc2 100644 --- a/arch/powerpc/include/asm/page.h +++ b/arch/powerpc/include/asm/page.h @@ -108,8 +108,13 @@ extern phys_addr_t kernstart_addr; #define pfn_to_kaddr(pfn) __va((pfn) PAGE_SHIFT) #define virt_addr_valid(kaddr)pfn_valid(__pa(kaddr) PAGE_SHIFT) -#define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET - MEMORY_START)) +#ifdef CONFIG_BOOKE +#define __va(x) ((void *)(unsigned long)((phys_addr_t)(x) - PHYSICAL_START + KERNELBASE)) +#define __pa(x) ((unsigned long)(x) + PHYSICAL_START - KERNELBASE) +#else +#define __va(x) ((void *)(unsigned long)((phys_addr_t)(x) + PAGE_OFFSET - MEMORY_START)) #define __pa(x) ((unsigned long)(x) - PAGE_OFFSET + MEMORY_START) +#endif /* * Unfortunately the PLT is in the BSS in the PPC32 ELF ABI, diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S index d80ce05..6a63d32 100644 --- a/arch/powerpc/kernel/head_44x.S +++ b/arch/powerpc/kernel/head_44x.S @@ -59,6 +59,17 @@ _ENTRY(_start); * of abatron_pteptrs */ nop + +#ifdef CONFIG_RELOCATABLE + bl jump/* Find our address */ + nop +jump: mflrr25 /* Make it accessible */ + /* just for and */ + lis r26, 0xfff0@h + ori r26, r26, 0xfff0@l + and.r21, r25, r26 +#endif Hmm. So we are assuming we are running from a 1:1 mapping at the entry. It is much more safe to read our tlb entry and use the RPN instead. +#ifdef CONFIG_RELOCATABLE + /* load physical address where kernel runs */ + mr r4,r21 +#else /* Kernel is at PHYSICAL_START */ lis r4,PHYSICAL_START@h ori r4,r4,PHYSICAL_START@l +#endif /* Load the kernel PID = 0 */ li r0,0 @@ -258,6 +274,18 @@ skpinv:addir4,r4,1 /* Increment */ mr r5,r29 mr r6,r28 mr r7,r27 + +#ifdef CONFIG_RELOCATABLE + /* save kernel and memory start */ + lis r25,kernstart_addr@h + ori r25,r25,kernstart_addr@l + stw r21,4(r25) 1) You have to use ERPN value in the higher word of kernel_start_addr. 2) You have to account for the (KERNEL_BASE - PAGE_OFFSET) shift for kernel_start_addr. + + lis r25,memstart_addr@h + ori r25,r25,memstart_addr@l + stw r21,4(r25) +#endif + Suzuki ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 1/3] powerpc/47x: allow kernel to be loaded in higher physical memory
On 07/12/11 18:57, Josh Boyer wrote: On Tue, Jul 5, 2011 at 2:18 AM, Suzuki Poulosesuz...@in.ibm.com wrote: On 07/05/11 10:06, Tony Breeds wrote: From: Dave Kleikampsha...@linux.vnet.ibm.com The 44x code (which is shared by 47x) assumes the available physical memory begins at 0x. This is not necessarily the case in an AMP environment. Support CONFIG_RELOCATABLE for 476 in order to allow the kernel to be loaded into a higher memory range. I think the code assumes, the kernel is loaded in 256M aligned page. You may want to mention that in the description here. Suzie, do you have any other concerns with this code in regards to your kexec/kdump work for 4xx? It seems fairly self-contained to me, so I'd like to apply it but I want to make sure it is not going to majorly conflict with the work you're doing. Please go ahead. Thanks Suzuki ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 1/3] powerpc/47x: allow kernel to be loaded in higher physical memory
On 07/05/11 10:06, Tony Breeds wrote: From: Dave Kleikampsha...@linux.vnet.ibm.com The 44x code (which is shared by 47x) assumes the available physical memory begins at 0x. This is not necessarily the case in an AMP environment. Support CONFIG_RELOCATABLE for 476 in order to allow the kernel to be loaded into a higher memory range. I think the code assumes, the kernel is loaded in 256M aligned page. You may want to mention that in the description here. Thanks Suzuki ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [RFC][PATCH] Kexec support for PPC440x
On 06/03/11 19:23, Sebastian Andrzej Siewior wrote: Suzuki Poulose wrote: The way you setup the 1:1 mapping should be close to what you are doing on kernel entry.Isn't it possible to include the file here and in the entry code? I will make this change and resend the patch. I took a look at the way we do it at kernel entry. It looks more cleaner to leave it untouched. Especially, when we add the support for 47x in the future, the code will become more unreadable. What do you think ? So the entry code has one 256MiB mapping, you need 8 of those. Entry goes for TLB 63 and you need to be flexible and avoid TLB 63 :). So after all you don't have that much in common with the entry code. If you look at the FSL-book code then you will notice that I tried to share some code. I don't understand why you don't flip the address space bit. On fsl we setup the tmp mapping in the other address space so we don't have two mappings for the same address. The entry code could be doing this with STS bit, I'm not sure. I am not sure if I understood this correctly. Could you explain how could there be two mappings for the same address ? We are setting up 1:1 mapping for 0-2GiB and the only mapping that could exist (in other words, not invalidated) is PAGE_OFFSET mapping. Since PAGE_OFFSET 2GiB we won't have multiple mappings. Or in other words we could limit KEXEC_*_MEMORY_LIMIT to PAGE_OFFSET to make sure the crossing doesn't occur. The kernel entry code sets up the mapping without a tmp mapping in 44x. i.e, it uses the mapping setup by the firmware/boot loader. Thanks Suzuki ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: Relocatable kernel for ppc44x
On 06/14/11 17:34, Michal Simek wrote: Hi, have someone tried to support RELOCATABLE kernel on ppc44x? As Josh, mentioned, I will be working on this. In fact I was trying a couple of patches towards this on PPC440x. But, I am stuck in debugging the hang that I am experiencing with the changes. I am setting up a RISCWatch processor probe to debug the same. Here is some information that I wanted to share : The PPC440X currently uses 256M TLB entries to pin the lowmem. When we go for a relocatable kernel we have to : 1) Restrict the kernel load address to be 256M aligned OR 2) Use 16M TLB(the next possible TLB page size supported) entries till the first 256M and then use the 256M TLB entries for the rest of lowmem. Option 1 is not feasible. Towards this, I have tried a patch which uses 16M TLB entries to map the entire lowmem on an ebony board. But that doesn't seem to work. I am setting up the JTAG to debug the state. I have attached the patch below for your reference. Any suggestions/comments would be really helpful. Thanks Suzuki == Use 16M TLB pages to pin the lowmem on PPC440x. --- arch/powerpc/include/asm/mmu-44x.h |9 + arch/powerpc/kernel/head_44x.S |2 +- arch/powerpc/mm/44x_mmu.c |2 +- 3 files changed, 11 insertions(+), 2 deletions(-) Index: linux-2.6.38.1/arch/powerpc/include/asm/mmu-44x.h === --- linux-2.6.38.1.orig/arch/powerpc/include/asm/mmu-44x.h +++ linux-2.6.38.1/arch/powerpc/include/asm/mmu-44x.h @@ -121,7 +121,12 @@ typedef struct { #endif /* Size of the TLBs used for pinning in lowmem */ +#define PPC_PIN_SIZE (1 24) /* 16M */ +#define PPC44x_TLB_PIN_SIZEPPC44x_TLB_16M +#if 0 #define PPC_PIN_SIZE (1 28) /* 256M */ +#define PPC44x_TLB_PIN_SIZEPPC44x_TLB_256M +#endif #if (PAGE_SHIFT == 12) #define PPC44x_TLBE_SIZE PPC44x_TLB_4K @@ -142,7 +147,11 @@ typedef struct { #error Unsupported PAGE_SIZE #endif +#if 0 #define mmu_linear_psize MMU_PAGE_256M +#else +#define mmu_linear_psize MMU_PAGE_16M +#endif #define PPC44x_PGD_OFF_SHIFT (32 - PGDIR_SHIFT + PGD_T_LOG2) #define PPC44x_PGD_OFF_MASK_BIT(PGDIR_SHIFT - PGD_T_LOG2) Index: linux-2.6.38.1/arch/powerpc/kernel/head_44x.S === --- linux-2.6.38.1.orig/arch/powerpc/kernel/head_44x.S +++ linux-2.6.38.1/arch/powerpc/kernel/head_44x.S @@ -805,7 +805,7 @@ skpinv: addir4,r4,1 /* Increment */ /* pageid fields */ clrrwi r3,r3,10/* Mask off the effective page number */ - ori r3,r3,PPC44x_TLB_VALID | PPC44x_TLB_256M + ori r3,r3,PPC44x_TLB_VALID | PPC44x_TLB_PIN_SIZE /* xlat fields */ clrrwi r4,r4,10/* Mask off the real page number */ Index: linux-2.6.38.1/arch/powerpc/mm/44x_mmu.c === --- linux-2.6.38.1.orig/arch/powerpc/mm/44x_mmu.c +++ linux-2.6.38.1/arch/powerpc/mm/44x_mmu.c @@ -84,7 +84,7 @@ static void __init ppc44x_pin_tlb(unsign : r (PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G), #endif r (phys), - r (virt | PPC44x_TLB_VALID | PPC44x_TLB_256M), + r (virt | PPC44x_TLB_VALID | PPC44x_TLB_PIN_SIZE), r (entry), i (PPC44x_TLB_PAGEID), i (PPC44x_TLB_XLAT), ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: Relocatable kernel for ppc44x
On 06/15/11 15:41, Benjamin Herrenschmidt wrote: On Wed, 2011-06-15 at 11:43 +0530, Suzuki Poulose wrote: On 06/14/11 17:34, Michal Simek wrote: Hi, have someone tried to support RELOCATABLE kernel on ppc44x? As Josh, mentioned, I will be working on this. In fact I was trying a couple of patches towards this on PPC440x. But, I am stuck in debugging the hang that I am experiencing with the changes. I am setting up a RISCWatch processor probe to debug the same. Here is some information that I wanted to share : The PPC440X currently uses 256M TLB entries to pin the lowmem. When we go for a relocatable kernel we have to : 1) Restrict the kernel load address to be 256M aligned Wait a minute ... :-) There's a difference between having the kernel run from any address and mapping the linear mapping not starting at 0. Those are completely orthogonal. I don't see why off hand you are changing the way the TLB is used. I started off with PHYSICAL_START support and that kind of hogged me into this approach :-). The only possible change needed is to make sure the initial bolted entry set by the asm code properly covers the kernel in whatever it's current location is. The rest is a matter of fixing up the relocations... Could we do something like, If kernel is loaded at X, 1. map : ((X-1) ~256M) to PAGE_OFFSET and so on to cover the kernel in 256M chunks. 2. Then process the relocations with (X % 256M) Thanks Suzuki ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[RFC][PATCH] kexec-tools: powerpc: Use the #address-cells information to parsememory/reg - V2
Hi, This is version 2 of the patch Changes from Version 1 : : Changed the interface for read_memory_region_limits to use 'int fd' instead of FILE*. : Use sizeof(variable) for read(, instead of sizeof(type). --- Fix parsing of the memory region information from the device-tree. The format of memory/reg is based on the #address-cells,#size-cells. Currently, the kexec-tools doesn't use the above values in parsing the memory/reg values. Hence the kexec cannot handle cases where #address-cells, #size-cells are different, (for e.g, PPC440X ). This patch introduces a read_memory_region_limits(), which parses the memory/reg contents based on the values of #address-cells and #size-cells. Signed-off-by: Suzuki K. Poulose suz...@in.ibm.com --- kexec/arch/ppc/crashdump-powerpc.c | 33 +-- kexec/arch/ppc/fs2dt.c | 14 --- kexec/arch/ppc/kexec-ppc.c | 158 ++--- kexec/arch/ppc/kexec-ppc.h |6 + 4 files changed, 129 insertions(+), 82 deletions(-) Index: kexec-tools-2.0.4/kexec/arch/ppc/kexec-ppc.c === --- kexec-tools-2.0.4.orig/kexec/arch/ppc/kexec-ppc.c +++ kexec-tools-2.0.4/kexec/arch/ppc/kexec-ppc.c @@ -16,6 +16,7 @@ #include dirent.h #include stdlib.h #include sys/stat.h +#include fcntl.h #include unistd.h #include ../../kexec.h @@ -26,6 +27,7 @@ #include config.h +unsigned long dt_address_cells = 0, dt_size_cells = 0; uint64_t rmo_top; unsigned long long crash_base = 0, crash_size = 0; unsigned long long initrd_base = 0, initrd_size = 0; @@ -34,6 +36,98 @@ unsigned int rtas_base, rtas_size; int max_memory_ranges; const char *ramdisk; +/* + * Reads the #address-cells and #size-cells on this platform. + * This is used to parse the memory/reg info from the device-tree + */ +int init_memory_region_info() +{ + size_t res = 0; + int fd; + char *file; + + file = /proc/device-tree/#address-cells; + fd = open(file, O_RDONLY); + if (fd 0) { + fprintf(stderr, Unable to open %s\n, file); + return -1; + } + + res = read(fd, dt_address_cells, sizeof(dt_address_cells)); + if (res != sizeof(dt_address_cells)) { + fprintf(stderr, Error reading %s\n, file); + return -1; + } + close(fd); + + file = /proc/device-tree/#size-cells; + fd = open(file, O_RDONLY); + if (fd 0) { + fprintf(stderr, Unable to open %s\n, file); + return -1; + } + + res = read(fd, dt_size_cells, sizeof(dt_size_cells)); + if (res != sizeof(dt_size_cells)) { + fprintf(stderr, Error reading %s\n, file); + return -1; + } + close(fd); + + /* Convert the sizes into bytes */ + dt_size_cells *= sizeof(unsigned long); + dt_address_cells *= sizeof(unsigned long); + + return 0; +} + +#define MAXBYTES 128 +/* + * Reads the memory region info from the device-tree node pointed + * by @fd and fills the *start, *end with the boundaries of the region + */ +int read_memory_region_limits(int fd, unsigned long long *start, + unsigned long long *end) +{ + char buf[MAXBYTES]; + unsigned long *p; + unsigned long nbytes = dt_address_cells + dt_size_cells; + + if (lseek(fd, 0, SEEK_SET) == -1) { + fprintf(stderr, Error in file seek\n); + return -1; + } + if (read(fd, buf, nbytes) != nbytes) { + fprintf(stderr, Error reading the memory region info\n); + return -1; + } + + p = (unsigned long*)buf; + if (dt_address_cells == sizeof(unsigned long)) { + *start = p[0]; + p++; + } else if (dt_address_cells == sizeof(unsigned long long)) { + *start = ((unsigned long long *)p)[0]; + p = (unsigned long long *)p + 1; + } else { + fprintf(stderr, Unsupported value for #address-cells : %ld\n, + dt_address_cells); + return -1; + } + + if (dt_size_cells == sizeof(unsigned long)) + *end = *start + p[0]; + else if (dt_size_cells == sizeof(unsigned long long)) + *end = *start + ((unsigned long long *)p)[0]; + else { + fprintf(stderr, Unsupported value for #size-cells : %ld\n, + dt_size_cells); + return -1; + } + + return 0; +} + void arch_reuse_initrd(void) { reuse_initrd = 1; @@ -182,9 +276,6 @@ static int sort_base_ranges(void) return 0; } - -#define MAXBYTES 128 - static int realloc_memory_ranges(void) { size_t memory_range_len; @@ -228,9 +319,8 @@ static int get_base_ranges(void) char fname[256]; char buf[MAXBYTES]; DIR *dir,
Re: [RFC][PATCH] powerpc: Use the #address-cells information to parse memory/reg
On 05/30/11 12:00, Suzuki Poulose wrote: Use the #address-cells, #size-cells information to parse the memory/reg info from device tree. The format of memory/reg is based on the #address-cells,#size-cells. Currently, the kexec-tools doesn't use the above values in parsing the memory/reg values. Hence the kexec cannot handle cases where #address-cells, #size-cells are different, (for e.g, PPC440X ). This patch introduces a read_memory_region_limits(), which parses the memory/reg contents based on the values of #address-cells and #size-cells. Changed the add_usable_mem_property() to accept FILE* fp instead of int fd, as most of the other users of read_memory_region_limits() deals with FILE*. Signed-off-by: Suzuki K. Poulose suz...@in.ibm.com Could you please let me know your thoughts/comments about this patch ? Thanks Suzuki --- kexec/arch/ppc/crashdump-powerpc.c | 23 -- kexec/arch/ppc/fs2dt.c | 31 ++-- kexec/arch/ppc/kexec-ppc.c | 136 ++--- kexec/arch/ppc/kexec-ppc.h | 6 + 4 files changed, 118 insertions(+), 78 deletions(-) Index: kexec-tools-2.0.4/kexec/arch/ppc/kexec-ppc.c === --- kexec-tools-2.0.4.orig/kexec/arch/ppc/kexec-ppc.c +++ kexec-tools-2.0.4/kexec/arch/ppc/kexec-ppc.c @@ -26,6 +26,7 @@ #include config.h +unsigned long dt_address_cells = 0, dt_size_cells = 0; uint64_t rmo_top; unsigned long long crash_base = 0, crash_size = 0; unsigned long long initrd_base = 0, initrd_size = 0; @@ -34,6 +35,92 @@ unsigned int rtas_base, rtas_size; int max_memory_ranges; const char *ramdisk; +/* + * Reads the #address-cells and #size-cells on this platform. + * This is used to parse the memory/reg info from the device-tree + */ +int init_memory_region_info() +{ + size_t res = 0; + FILE *fp; + char *file; + + file = /proc/device-tree/#address-cells; + fp = fopen(file, r); + if (!fp) { + fprintf(stderr,Unable to open %s\n, file); + return -1; + } + + res = fread(dt_address_cells,sizeof(unsigned long),1,fp); + if (res != 1) { + fprintf(stderr,Error reading %s\n, file); + return -1; + } + fclose(fp); + dt_address_cells *= sizeof(unsigned long); + + file = /proc/device-tree/#size-cells; + fp = fopen(file, r); + if (!fp) { + fprintf(stderr,Unable to open %s\n, file); + return -1; + } + + res = fread(dt_size_cells,sizeof(unsigned long),1,fp); + if (res != 1) { + fprintf(stderr,Error reading %s\n, file); + return -1; + } + fclose(fp); + dt_size_cells *= sizeof(unsigned long); + + return 0; +} + +#define MAXBYTES 128 +/* + * Reads the memory region info from the device-tree node pointed + * by @fp and fills the *start, *end with the boundaries of the region + */ +int read_memory_region_limits(FILE* fp, unsigned long long *start, + unsigned long long *end) +{ + char buf[MAXBYTES]; + unsigned long *p; + unsigned long nbytes = dt_address_cells + dt_size_cells; + + if (fread(buf, 1, MAXBYTES, fp) != nbytes) { + fprintf(stderr, Error reading the memory region info\n); + return -1; + } + + p = (unsigned long*)buf; + if (dt_address_cells == sizeof(unsigned long)) { + *start = p[0]; + p++; + } else if (dt_address_cells == sizeof(unsigned long long)) { + *start = ((unsigned long long *)p)[0]; + p = (unsigned long long *)p + 1; + } else { + fprintf(stderr,Unsupported value for #address-cells : %ld\n, + dt_address_cells); + return -1; + } + + if (dt_size_cells == sizeof(unsigned long)) + *end = *start + p[0]; + else if (dt_size_cells == sizeof(unsigned long long)) + *end = *start + ((unsigned long long *)p)[0]; + else { + fprintf(stderr,Unsupported value for #size-cells : %ld\n, + dt_size_cells); + return -1; + } + + return 0; +} + void arch_reuse_initrd(void) { reuse_initrd = 1; @@ -182,9 +269,6 @@ static int sort_base_ranges(void) return 0; } - -#define MAXBYTES 128 - static int realloc_memory_ranges(void) { size_t memory_range_len; @@ -248,6 +332,8 @@ static int get_base_ranges(void) return -1; } while ((mentry = readdir(dmem)) != NULL) { + unsigned long long start, end; + if (strcmp(mentry-d_name, reg)) continue; strcat(fname, /reg); @@ -257,8 +343,7 @@ static int get_base_ranges(void) closedir(dir); return -1; } - if ((n = fread(buf, 1, MAXBYTES, file)) 0) { - perror(fname); + if (read_memory_region_limits(file, start, end) != 0) { fclose(file); closedir(dmem); closedir(dir); @@ -271,24 +356,8 @@ static int get_base_ranges(void) } } - if (n == sizeof(uint32_t) * 2) { - base_memory_range[local_memory_ranges].start = - ((uint32_t *)buf)[0]; - base_memory_range[local_memory_ranges].end = - base_memory_range[local_memory_ranges].start + - ((uint32_t *)buf)[1]; - } - else if (n == sizeof(uint64_t) * 2) { - base_memory_range[local_memory_ranges].start = - ((uint64_t *)buf)[0]; - base_memory_range[local_memory_ranges].end = - base_memory_range[local_memory_ranges].start + - ((uint64_t *)buf)[1]; - } - else { - fprintf(stderr, Mem node has invalid size: %d\n, n); - return -1; - } + base_memory_range
Re: [RFC][PATCH] powerpc: Use the #address-cells information to parse memory/reg
On 06/06/11 14:21, Sebastian Andrzej Siewior wrote: Suzuki Poulose wrote: Could you please let me know your thoughts/comments about this patch ? I'm mostly fine with it. Maaxim copied fs2dt.c from ppc64 to ppc. So I guess ppc64 has the same problem. Yes, you are right. Porting this patch over to ppc64 is in my TODO list. ARM and MIPS is soon having DT support and kexec is probably also on their list so I would hate to see them to either copy the DT parsing file or having their own implementation. Maybe we should try to use libfdt for dt parsing. It has /proc import support so it should be fine for our needs. It is already in tree and used by ppc32 if a basic dtb is specified. I'm not sure if the /proc interface is part of dtc or libfdt. I'm not saying this has to be done now but maybe later before ARM and/or MIPS comes along needs something similar for their needs. If the libfdt is too complex for sucking in the dtb from /proc then maybe something else that generic and can be shared between booth ppc architectures and the other ones. OK Index: kexec-tools-2.0.4/kexec/arch/ppc/kexec-ppc.c === --- kexec-tools-2.0.4.orig/kexec/arch/ppc/kexec-ppc.c +++ kexec-tools-2.0.4/kexec/arch/ppc/kexec-ppc.c @@ -34,6 +35,92 @@ unsigned int rtas_base, rtas_size; int max_memory_ranges; const char *ramdisk; +/* + * Reads the #address-cells and #size-cells on this platform. + * This is used to parse the memory/reg info from the device-tree + */ +int init_memory_region_info() +{ + size_t res = 0; + FILE *fp; + char *file; + + file = /proc/device-tree/#address-cells; + fp = fopen(file, r); + if (!fp) { + fprintf(stderr,Unable to open %s\n, file); + return -1; + } + + res = fread(dt_address_cells,sizeof(unsigned long),1,fp); + if (res != 1) { + fprintf(stderr,Error reading %s\n, file); + return -1; + } + fclose(fp); + dt_address_cells *= sizeof(unsigned long); This should be sizeof(unsigned int). I know we on 32bit. OK. I was using (unsigned long) to get the word size on the machine. Given this code is duplicated in ppc64, thought of having a generic code which works fine for all ppcXX. As you mentioned, if we go about moving to a single copy of fdt code, using long would help us. + file = /proc/device-tree/#size-cells; + fp = fopen(file, r); + if (!fp) { + fprintf(stderr,Unable to open %s\n, file); + return -1; + } + + res = fread(dt_size_cells,sizeof(unsigned long),1,fp); + if (res != 1) { + fprintf(stderr,Error reading %s\n, file); + return -1; + } + fclose(fp); + dt_size_cells *= sizeof(unsigned long); same here. Thanks Suzuki ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [RFC][PATCH] powerpc: Use the #address-cells information to parsememory/reg
On 06/06/11 14:30, David Laight wrote: Changed the add_usable_mem_property() to accept FILE* fp instead of int fd, as most of the other users of read_memory_region_limits() deals with FILE*. Signed-off-by: Suzuki K. Poulosesuz...@in.ibm.com Could you please let me know your thoughts/comments about this patch ? Is the change to use 'FILE *' actually progress? I'd have thought that the randomly aligned read/lseek system calls that this allows to happen are not desirable for anything that isn't a true file. I will revert the other users back to 'fd' I'd also suggest that the sizeof's should be applied to the actual type of the variable being read/written, not arbitrarily 'long' or 'int', and this probably ought to be some fixed size type. I have used 'unsigned long'(for word sized values) or 'unsigned long long' (for double words) just to make sure we get the right values. Is this OK ? Thanks Suzuki ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [RFC][PATCH] Kexec support for PPC440x
On 06/02/11 12:04, Suzuki Poulose wrote: On 05/31/11 20:45, Sebastian Andrzej Siewior wrote: Suzuki Poulose wrote: Index: powerpc/arch/powerpc/kernel/44x_kexec_mapping.S === --- /dev/null +++ powerpc/arch/powerpc/kernel/44x_kexec_mapping.S + * + */ + bl nxtins /* Find our address */ +nxtins: mflr r5 /* Make it accessible */ Please don't mix labels and instructions. OK. + tlbsx r23,0,r5 /* Find entry we are in */ using tabs instead of spaces would make it look nice. Please also separate the arguments of the instruction i.e. tlbsx r23, 0, r5 Sure. Index: powerpc/arch/powerpc/kernel/misc_32.S === --- powerpc.orig/arch/powerpc/kernel/misc_32.S +++ powerpc/arch/powerpc/kernel/misc_32.S @@ -736,6 +736,28 @@ relocate_new_kernel: mr r5, r31 li r0, 0 +#elif defined(CONFIG_44x) !defined(CONFIG_47x) + + mr r29, r3 + mr r30, r4 + mr r31, r5 + +#include 44x_kexec_mapping.S The way you setup the 1:1 mapping should be close to what you are doing on kernel entry.Isn't it possible to include the file here and in the entry code? I will make this change and resend the patch. I took a look at the way we do it at kernel entry. It looks more cleaner to leave it untouched. Especially, when we add the support for 47x in the future, the code will become more unreadable. What do you think ? Thanks Suzuki Thanks Suzuki ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [RFC][PATCH] Kexec support for PPC440x
On 05/31/11 20:45, Sebastian Andrzej Siewior wrote: Suzuki Poulose wrote: Index: powerpc/arch/powerpc/kernel/44x_kexec_mapping.S === --- /dev/null +++ powerpc/arch/powerpc/kernel/44x_kexec_mapping.S + * + */ + bl nxtins /* Find our address */ +nxtins: mflr r5 /* Make it accessible */ Please don't mix labels and instructions. OK. + tlbsx r23,0,r5 /* Find entry we are in */ using tabs instead of spaces would make it look nice. Please also separate the arguments of the instruction i.e. tlbsx r23, 0, r5 Sure. Index: powerpc/arch/powerpc/kernel/misc_32.S === --- powerpc.orig/arch/powerpc/kernel/misc_32.S +++ powerpc/arch/powerpc/kernel/misc_32.S @@ -736,6 +736,28 @@ relocate_new_kernel: mr r5, r31 li r0, 0 +#elif defined(CONFIG_44x) !defined(CONFIG_47x) + + mr r29, r3 + mr r30, r4 + mr r31, r5 + +#include 44x_kexec_mapping.S The way you setup the 1:1 mapping should be close to what you are doing on kernel entry.Isn't it possible to include the file here and in the entry code? I will make this change and resend the patch. Thanks Suzuki ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [RFC][PATCH] Kexec support for PPC440x
On 06/02/11 12:55, Benjamin Herrenschmidt wrote: On Tue, 2011-05-31 at 17:15 +0200, Sebastian Andrzej Siewior wrote: Suzuki Poulose wrote: Index: powerpc/arch/powerpc/kernel/44x_kexec_mapping.S === --- /dev/null +++ powerpc/arch/powerpc/kernel/44x_kexec_mapping.S + * + */ +blnxtins/* Find our address */ +nxtins:mflrr5/* Make it accessible */ Please don't mix labels and instructions. With proper indent it's fine as long as he uses numerical relative labels which should be the case here. For example, the above, it should look like: bl 1f 1: mflrr5 +tlbsxr23,0,r5/* Find entry we are in */ using tabs instead of spaces would make it look nice. Please also separate the arguments of the instruction i.e. tlbsx r23, 0, r5 That's arguable. If you look at arch/powerpc, we tend not to separate the arguments ;-) Actually I used to, others didn't and I changed my own style. Index: powerpc/arch/powerpc/kernel/misc_32.S === --- powerpc.orig/arch/powerpc/kernel/misc_32.S +++ powerpc/arch/powerpc/kernel/misc_32.S @@ -736,6 +736,28 @@ relocate_new_kernel: mr r5, r31 lir0, 0 +#elif defined(CONFIG_44x) !defined(CONFIG_47x) + +mrr29, r3 +mrr30, r4 +mrr31, r5 + +#include 44x_kexec_mapping.S The way you setup the 1:1 mapping should be close to what you are doing on kernel entry. Isn't it possible to include the file here and in the entry code? It should just not be #included, what about branching out instead ? This code, i.e, relocate_new_kernel is copied into the control buffer, which will get the first chance to execute before the purgatory. So we may not be able to branch to the code, since we are executing this from a different address and we would invalidate the mapping for the code except the control buffer. Thanks Suzuki ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[RFC][PATCH] powerpc: Use the #address-cells information to parse memory/reg
Use the #address-cells, #size-cells information to parse the memory/reg info from device tree. The format of memory/reg is based on the #address-cells,#size-cells. Currently, the kexec-tools doesn't use the above values in parsing the memory/reg values. Hence the kexec cannot handle cases where #address-cells, #size-cells are different, (for e.g, PPC440X ). This patch introduces a read_memory_region_limits(), which parses the memory/reg contents based on the values of #address-cells and #size-cells. Changed the add_usable_mem_property() to accept FILE* fp instead of int fd, as most of the other users of read_memory_region_limits() deals with FILE*. Signed-off-by: Suzuki K. Poulose suz...@in.ibm.com --- kexec/arch/ppc/crashdump-powerpc.c | 23 -- kexec/arch/ppc/fs2dt.c | 31 ++-- kexec/arch/ppc/kexec-ppc.c | 136 ++--- kexec/arch/ppc/kexec-ppc.h |6 + 4 files changed, 118 insertions(+), 78 deletions(-) Index: kexec-tools-2.0.4/kexec/arch/ppc/kexec-ppc.c === --- kexec-tools-2.0.4.orig/kexec/arch/ppc/kexec-ppc.c +++ kexec-tools-2.0.4/kexec/arch/ppc/kexec-ppc.c @@ -26,6 +26,7 @@ #include config.h +unsigned long dt_address_cells = 0, dt_size_cells = 0; uint64_t rmo_top; unsigned long long crash_base = 0, crash_size = 0; unsigned long long initrd_base = 0, initrd_size = 0; @@ -34,6 +35,92 @@ unsigned int rtas_base, rtas_size; int max_memory_ranges; const char *ramdisk; +/* + * Reads the #address-cells and #size-cells on this platform. + * This is used to parse the memory/reg info from the device-tree + */ +int init_memory_region_info() +{ + size_t res = 0; + FILE *fp; + char *file; + + file = /proc/device-tree/#address-cells; + fp = fopen(file, r); + if (!fp) { + fprintf(stderr,Unable to open %s\n, file); + return -1; + } + + res = fread(dt_address_cells,sizeof(unsigned long),1,fp); + if (res != 1) { + fprintf(stderr,Error reading %s\n, file); + return -1; + } + fclose(fp); + dt_address_cells *= sizeof(unsigned long); + + file = /proc/device-tree/#size-cells; + fp = fopen(file, r); + if (!fp) { + fprintf(stderr,Unable to open %s\n, file); + return -1; + } + + res = fread(dt_size_cells,sizeof(unsigned long),1,fp); + if (res != 1) { + fprintf(stderr,Error reading %s\n, file); + return -1; + } + fclose(fp); + dt_size_cells *= sizeof(unsigned long); + + return 0; +} + +#define MAXBYTES 128 +/* + * Reads the memory region info from the device-tree node pointed + * by @fp and fills the *start, *end with the boundaries of the region + */ +int read_memory_region_limits(FILE* fp, unsigned long long *start, + unsigned long long *end) +{ + char buf[MAXBYTES]; + unsigned long *p; + unsigned long nbytes = dt_address_cells + dt_size_cells; + + if (fread(buf, 1, MAXBYTES, fp) != nbytes) { + fprintf(stderr, Error reading the memory region info\n); + return -1; + } + + p = (unsigned long*)buf; + if (dt_address_cells == sizeof(unsigned long)) { + *start = p[0]; + p++; + } else if (dt_address_cells == sizeof(unsigned long long)) { + *start = ((unsigned long long *)p)[0]; + p = (unsigned long long *)p + 1; + } else { + fprintf(stderr,Unsupported value for #address-cells : %ld\n, + dt_address_cells); + return -1; + } + + if (dt_size_cells == sizeof(unsigned long)) + *end = *start + p[0]; + else if (dt_size_cells == sizeof(unsigned long long)) + *end = *start + ((unsigned long long *)p)[0]; + else { + fprintf(stderr,Unsupported value for #size-cells : %ld\n, + dt_size_cells); + return -1; + } + + return 0; +} + void arch_reuse_initrd(void) { reuse_initrd = 1; @@ -182,9 +269,6 @@ static int sort_base_ranges(void) return 0; } - -#define MAXBYTES 128 - static int realloc_memory_ranges(void) { size_t memory_range_len; @@ -248,6 +332,8 @@ static int get_base_ranges(void) return -1; } while ((mentry = readdir(dmem)) != NULL) { + unsigned long long start, end; + if (strcmp(mentry-d_name, reg)) continue; strcat(fname, /reg); @@ -257,8 +343,7 @@ static int get_base_ranges(void) closedir(dir); return -1; } -
[RFC][PATCH] Kexec support for PPC440x
KEXEC Support for ppc440X The patch adds kexec support for PPC440x based boards. This work is based on the KEXEC patches for FSL BookE. The FSL BookE patch and the code flow could be found at the link below: http://patchwork.ozlabs.org/patch/49359/ We invalidate all the TLB entries except the one this code is run from, and create a 1:1 mapping for 0-2GiB in blocks of 256M. Later we jump to the 1:1 mapping. I have tested this patches on Ebony and Sequoia boards. It would be great if somebody could test this on the other boards. Signed-off-by: Suzuki K. Poulose suz...@in.ibm.com --- arch/powerpc/Kconfig|2 arch/powerpc/include/asm/kexec.h|2 arch/powerpc/kernel/44x_kexec_mapping.S | 66 arch/powerpc/kernel/misc_32.S | 22 ++ 4 files changed, 90 insertions(+), 2 deletions(-) Index: powerpc/arch/powerpc/Kconfig === --- powerpc.orig/arch/powerpc/Kconfig +++ powerpc/arch/powerpc/Kconfig @@ -349,7 +349,7 @@ config ARCH_ENABLE_MEMORY_HOTREMOVE config KEXEC bool kexec system call (EXPERIMENTAL) - depends on (PPC_BOOK3S || FSL_BOOKE) EXPERIMENTAL + depends on (PPC_BOOK3S || FSL_BOOKE || (44x !SMP !47x)) EXPERIMENTAL help kexec is a system call that implements the ability to shutdown your current kernel, and to start another kernel. It is like a reboot Index: powerpc/arch/powerpc/include/asm/kexec.h === --- powerpc.orig/arch/powerpc/include/asm/kexec.h +++ powerpc/arch/powerpc/include/asm/kexec.h @@ -2,7 +2,7 @@ #define _ASM_POWERPC_KEXEC_H #ifdef __KERNEL__ -#ifdef CONFIG_FSL_BOOKE +#if defined(CONFIG_FSL_BOOKE) || defined(CONFIG_44x) /* * On FSL-BookE we setup a 1:1 mapping which covers the first 2GiB of memory Index: powerpc/arch/powerpc/kernel/44x_kexec_mapping.S === --- /dev/null +++ powerpc/arch/powerpc/kernel/44x_kexec_mapping.S @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2011 IBM + * + * Author : Suzuki K. Poulose suz...@in.ibm.com + * + * This source code is licensed under the GNU General Public License, + * Version 2. See the file COPYING for more details. + * + * Code for setting up 1:1 mapping for PPC440x for KEXEC + * + * We cannot switch off the MMU on PPC44x. + * So we: + * 1) Invalidate all the mappings except the one we are + * running from. + * 2) Create a 1:1 mapping for 0-2GiB + * + * - Based on the kexec support code for FSL BookE + * - Based on the boot up code for ppc44x from head_44x.S + * - Doesn't support 47x yet. + * - Doesn't support SMP. + * + */ + bl nxtins /* Find our address */ +nxtins:mflrr5 /* Make it accessible */ + tlbsx r23,0,r5/* Find entry we are in */ + li r4,0/* Start at TLB entry 0 */ + li r3,0/* Set PAGEID inval value */ +1: cmpwr23,r4 /* Is this our entry? */ + beq skip/* If so, skip the inval */ + tlbwe r3,r4,PPC44x_TLB_PAGEID /* If not, inval the entry */ +skip: addir4,r4,1 /* Increment */ + cmpwi r4,64 /* Are we done? */ + bne 1b /* If not, repeat */ + isync + +/* + * Setup 1:1 mapping for 0-2GiB in blocks of 256M. + * r23 is the index to the mapping of this code. + * Skip it. + */ + /* attribute fields. rwx for SUPERVISOR mode */ + li r5, 0 + ori r5, r5, (PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G) + + li r11, 0 /* PageNumber */ + li r6, 0 /* TLB Index */ + +next_tlb: + rotlwi r3, r11, 28 /* Create EPN (bits 0-3) */ + mr r4, r3 /* RPN = EPN */ + ori r3, r3, PPC44x_TLB_VALID | PPC44x_TLB_256M /* SIZE = 256M, Valid */ + cmpwr6, r23 /* Is this our TLB entry ? */ + bne write_tlb + addir6, r6, 1 /* Skip our entry */ + +write_tlb: + tlbwe r3, r6, PPC44x_TLB_PAGEID /* PageID field : EPN, V, SIZE */ + tlbwe r4, r6, PPC44x_TLB_XLAT /* Address translation : RPN */ + tlbwe r5, r6, PPC44x_TLB_ATTRIB /* Attributes */ + + addir11, r11, 1 /* Increment PN */ + addir6, r6, 1 /* Increment TLB Index */ + cmpwi r11, 8 /* Are we done ? */ + bne next_tlb + isync + Index: powerpc/arch/powerpc/kernel/misc_32.S