* [RFC PATCH v3] powerpc: Loading kernels over 8Mbytes without CONFIG_PIN_TLB
@ 2013-12-15 15:09 Christophe Leroy
2014-03-19 20:42 ` [RFC, " Scott Wood
0 siblings, 1 reply; 2+ messages in thread
From: Christophe Leroy @ 2013-12-15 15:09 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, scottwood
Cc: linux-kernel, linuxppc-dev
Hereunder is a try to implement the sizing of the initial memory size based on
initial-mapped-area size given by uboot in r7.
As this has an impact on all powerpc platforms due to the need to provide the
info up to function setup_initial_memory_limit(), I'm not completly sure of the
proper implementation.
Thanks to provide comments.
Today on the 8xx, the only way to load kernels whose size is greater than
8Mbytes is to activate CONFIG_PIN_TLB. Otherwise, the physical memory initially
mapped is limited to 8Mbytes. This patch uses the size of initial memory mapped
by the bootloader and given to the kernel through register r7.
This is done regardless of whether CONFIG_PIN_TLB is active or not. It allows to
load "big" kernels (for instance when activating CONFIG_LOCKDEP_SUPPORT) without
having to activate CONFIG_PIN_TLB.
Not-yet-signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
Index: linux/arch/powerpc/include/asm/mmu.h
===================================================================
--- linux/arch/powerpc/include/asm/mmu.h (revision 5484)
+++ linux/arch/powerpc/include/asm/mmu.h (copie de travail)
@@ -138,7 +138,8 @@
extern void early_init_mmu_secondary(void);
extern void setup_initial_memory_limit(phys_addr_t first_memblock_base,
- phys_addr_t first_memblock_size);
+ phys_addr_t first_memblock_size,
+ u64 init_mem_size);
#ifdef CONFIG_PPC64
/* This is our real memory area size on ppc64 server, on embedded, we
Index: linux/arch/powerpc/kernel/head_8xx.S
===================================================================
--- linux/arch/powerpc/kernel/head_8xx.S (revision 5484)
+++ linux/arch/powerpc/kernel/head_8xx.S (copie de travail)
@@ -31,6 +31,8 @@
#include <asm/asm-offsets.h>
#include <asm/ptrace.h>
+#define EPAPR_MAGIC 0x65504150
+
/* Macro to make the code more readable. */
#ifdef CONFIG_8xx_CPU6
#define DO_8xx_CPU6(val, reg) \
@@ -77,10 +79,19 @@
.globl __start
__start:
mr r31,r3 /* save device tree ptr */
+ li r30,0
+ lis r8,EPAPR_MAGIC@h
+ ori r8,r8, EPAPR_MAGIC@l
+ cmpw cr0,r8, r6
+ bne 1f
+
+ mr r30,r7 /* save initial ram size */
+
/* We have to turn on the MMU right away so we get cache modes
* set correctly.
*/
+1:
bl initial_mmu
/* We now have the lower 8 Meg mapped into TLB entries, and the caches
@@ -717,6 +728,8 @@
*/
li r3,0
mr r4,r31
+ li r5,0
+ mr r6,r30
bl machine_init
bl MMU_init
@@ -841,11 +854,17 @@
ori r8, r8, MI_BOOTINIT|0x2 /* Inhibit cache -- Cort */
mtspr SPRN_MD_RPN, r8
+ /* Map two more 8M kernel data pages if needed
+ * We check how much memory is mapped by the bootloader
+ */
+ lis r8, 0x0100
+ cmplw cr0, r8, r30
+ blt 2f
+
#ifdef CONFIG_PIN_TLB
- /* Map two more 8M kernel data pages.
- */
addi r10, r10, 0x0100
mtspr SPRN_MD_CTR, r10
+#endif
lis r8, KERNELBASE@h /* Create vaddr for TLB */
addis r8, r8, 0x0080 /* Add 8M */
@@ -858,20 +877,26 @@
addis r11, r11, 0x0080 /* Add 8M */
mtspr SPRN_MD_RPN, r11
+ lis r8, 0x0180
+ cmplw cr0, r8, r30
+ blt 2f
+
+#ifdef CONFIG_PIN_TLB
addi r10, r10, 0x0100
mtspr SPRN_MD_CTR, r10
+#endif
addis r8, r8, 0x0080 /* Add 8M */
mtspr SPRN_MD_EPN, r8
mtspr SPRN_MD_TWC, r9
addis r11, r11, 0x0080 /* Add 8M */
mtspr SPRN_MD_RPN, r11
-#endif
/* Since the cache is enabled according to the information we
* just loaded into the TLB, invalidate and enable the caches here.
* We should probably check/set other modes....later.
*/
+2:
lis r8, IDC_INVALL@h
mtspr SPRN_IC_CST, r8
mtspr SPRN_DC_CST, r8
Index: linux/arch/powerpc/kernel/prom.c
===================================================================
--- linux/arch/powerpc/kernel/prom.c (revision 5484)
+++ linux/arch/powerpc/kernel/prom.c (copie de travail)
@@ -649,7 +649,7 @@
}
}
-void __init early_init_devtree(void *params)
+void __init early_init_devtree(void *params, u64 init_mem_size)
{
phys_addr_t limit;
@@ -697,7 +697,7 @@
/* make sure we've parsed cmdline for mem= before this */
if (memory_limit)
first_memblock_size = min_t(u64, first_memblock_size, memory_limit);
- setup_initial_memory_limit(memstart_addr, first_memblock_size);
+ setup_initial_memory_limit(memstart_addr, first_memblock_size, init_mem_size);
/* Reserve MEMBLOCK regions used by kernel, initrd, dt, etc... */
memblock_reserve(PHYSICAL_START, __pa(klimit) - PHYSICAL_START);
/* If relocatable, reserve first 32k for interrupt vectors etc. */
Index: linux/arch/powerpc/kernel/setup_32.c
===================================================================
--- linux/arch/powerpc/kernel/setup_32.c (revision 5484)
+++ linux/arch/powerpc/kernel/setup_32.c (copie de travail)
@@ -119,7 +119,7 @@
* This is called very early on the boot process, after a minimal
* MMU environment has been set up but before MMU_init is called.
*/
-notrace void __init machine_init(u64 dt_ptr)
+notrace void __init machine_init(u64 dt_ptr, u64 init_mem_size)
{
lockdep_init();
@@ -127,7 +127,7 @@
udbg_early_init();
/* Do some early initialization based on the flat device tree */
- early_init_devtree(__va(dt_ptr));
+ early_init_devtree(__va(dt_ptr), init_mem_size);
epapr_paravirt_early_init();
Index: linux/arch/powerpc/kernel/setup_64.c
===================================================================
--- linux/arch/powerpc/kernel/setup_64.c (revision 5484)
+++ linux/arch/powerpc/kernel/setup_64.c (copie de travail)
@@ -185,7 +185,7 @@
* device-tree is not accessible via normal means at this point.
*/
-void __init early_setup(unsigned long dt_ptr)
+void __init early_setup(unsigned long dt_ptr, u64 init_mem_size)
{
static __initdata struct paca_struct boot_paca;
@@ -214,7 +214,7 @@
* tree, such as retrieving the physical memory map or
* calculating/retrieving the hash table size.
*/
- early_init_devtree(__va(dt_ptr));
+ early_init_devtree(__va(dt_ptr), init_mem_size);
epapr_paravirt_early_init();
Index: linux/arch/powerpc/mm/40x_mmu.c
===================================================================
--- linux/arch/powerpc/mm/40x_mmu.c (revision 5484)
+++ linux/arch/powerpc/mm/40x_mmu.c (copie de travail)
@@ -147,7 +147,8 @@
}
void setup_initial_memory_limit(phys_addr_t first_memblock_base,
- phys_addr_t first_memblock_size)
+ phys_addr_t first_memblock_size,
+ u64 init_mem_size)
{
/* We don't currently support the first MEMBLOCK not mapping 0
* physical on those processors
Index: linux/arch/powerpc/mm/44x_mmu.c
===================================================================
--- linux/arch/powerpc/mm/44x_mmu.c (revision 5484)
+++ linux/arch/powerpc/mm/44x_mmu.c (copie de travail)
@@ -212,7 +212,8 @@
}
void setup_initial_memory_limit(phys_addr_t first_memblock_base,
- phys_addr_t first_memblock_size)
+ phys_addr_t first_memblock_size,
+ u64 init_mem_size)
{
u64 size;
Index: linux/arch/powerpc/mm/fsl_booke_mmu.c
===================================================================
--- linux/arch/powerpc/mm/fsl_booke_mmu.c (revision 5484)
+++ linux/arch/powerpc/mm/fsl_booke_mmu.c (copie de travail)
@@ -234,7 +234,8 @@
}
void setup_initial_memory_limit(phys_addr_t first_memblock_base,
- phys_addr_t first_memblock_size)
+ phys_addr_t first_memblock_size,
+ u64 init_mem_size)
{
phys_addr_t limit = first_memblock_base + first_memblock_size;
Index: linux/arch/powerpc/mm/hash_utils_64.c
===================================================================
--- linux/arch/powerpc/mm/hash_utils_64.c (revision 5484)
+++ linux/arch/powerpc/mm/hash_utils_64.c (copie de travail)
@@ -1416,7 +1416,8 @@
#endif /* CONFIG_DEBUG_PAGEALLOC */
void setup_initial_memory_limit(phys_addr_t first_memblock_base,
- phys_addr_t first_memblock_size)
+ phys_addr_t first_memblock_size,
+ u64 init_mem_size)
{
/* We don't currently support the first MEMBLOCK not mapping 0
* physical on those processors
Index: linux/arch/powerpc/mm/init_32.c
===================================================================
--- linux/arch/powerpc/mm/init_32.c (revision 5484)
+++ linux/arch/powerpc/mm/init_32.c (copie de travail)
@@ -206,19 +206,16 @@
#ifdef CONFIG_8xx /* No 8xx specific .c file to put that in ... */
void setup_initial_memory_limit(phys_addr_t first_memblock_base,
- phys_addr_t first_memblock_size)
+ phys_addr_t first_memblock_size,
+ u64 init_mem_size)
{
/* We don't currently support the first MEMBLOCK not mapping 0
* physical on those processors
*/
BUG_ON(first_memblock_base != 0);
-#ifdef CONFIG_PIN_TLB
- /* 8xx can only access 24MB at the moment */
- memblock_set_current_limit(min_t(u64, first_memblock_size, 0x01800000));
-#else
- /* 8xx can only access 8MB at the moment */
- memblock_set_current_limit(min_t(u64, first_memblock_size, 0x00800000));
-#endif
+ if (!init_mem_size)
+ init_mem_size = 0x00800000;
+ memblock_set_current_limit(min_t(u64, first_memblock_size, init_mem_size));
}
#endif /* CONFIG_8xx */
Index: linux/arch/powerpc/mm/ppc_mmu_32.c
===================================================================
--- linux/arch/powerpc/mm/ppc_mmu_32.c (revision 5484)
+++ linux/arch/powerpc/mm/ppc_mmu_32.c (copie de travail)
@@ -273,7 +273,8 @@
}
void setup_initial_memory_limit(phys_addr_t first_memblock_base,
- phys_addr_t first_memblock_size)
+ phys_addr_t first_memblock_size,
+ u64 init_mem_size)
{
/* We don't currently support the first MEMBLOCK not mapping 0
* physical on those processors
Index: linux/arch/powerpc/mm/tlb_nohash.c
===================================================================
--- linux/arch/powerpc/mm/tlb_nohash.c (revision 5484)
+++ linux/arch/powerpc/mm/tlb_nohash.c (copie de travail)
@@ -654,7 +654,8 @@
}
void setup_initial_memory_limit(phys_addr_t first_memblock_base,
- phys_addr_t first_memblock_size)
+ phys_addr_t first_memblock_size,
+ u64 init_mem_size)
{
/* On non-FSL Embedded 64-bit, we adjust the RMA size to match
* the bolted TLB entry. We know for now that only 1G
---
Ce courrier électronique ne contient aucun virus ou logiciel malveillant parce que la protection avast! Antivirus est active.
http://www.avast.com
^ permalink raw reply [flat|nested] 2+ messages in thread* Re: [RFC, v3] powerpc: Loading kernels over 8Mbytes without CONFIG_PIN_TLB
2013-12-15 15:09 [RFC PATCH v3] powerpc: Loading kernels over 8Mbytes without CONFIG_PIN_TLB Christophe Leroy
@ 2014-03-19 20:42 ` Scott Wood
0 siblings, 0 replies; 2+ messages in thread
From: Scott Wood @ 2014-03-19 20:42 UTC (permalink / raw)
To: LEROY Christophe
Cc: Benjamin Herrenschmidt, Paul Mackerras, linuxppc-dev, linux-kernel
On Sun, Dec 15, 2013 at 04:09:57PM +0100, LEROY Christophe wrote:
> Hereunder is a try to implement the sizing of the initial memory size based on
> initial-mapped-area size given by uboot in r7.
> As this has an impact on all powerpc platforms due to the need to provide the
> info up to function setup_initial_memory_limit(), I'm not completly sure of the
> proper implementation.
> Thanks to provide comments.
>
> Today on the 8xx, the only way to load kernels whose size is greater than
> 8Mbytes is to activate CONFIG_PIN_TLB. Otherwise, the physical memory initially
> mapped is limited to 8Mbytes. This patch uses the size of initial memory mapped
> by the bootloader and given to the kernel through register r7.
> This is done regardless of whether CONFIG_PIN_TLB is active or not. It allows to
> load "big" kernels (for instance when activating CONFIG_LOCKDEP_SUPPORT) without
> having to activate CONFIG_PIN_TLB.
>
> Not-yet-signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
>
> ---
> Ce courrier électronique ne contient aucun virus ou logiciel malveillant parce que la protection avast! Antivirus est active.
> http://www.avast.com
>
> Index: linux/arch/powerpc/include/asm/mmu.h
> ===================================================================
> --- linux/arch/powerpc/include/asm/mmu.h (revision 5484)
> +++ linux/arch/powerpc/include/asm/mmu.h (copie de travail)
> @@ -138,7 +138,8 @@
> extern void early_init_mmu_secondary(void);
>
> extern void setup_initial_memory_limit(phys_addr_t first_memblock_base,
> - phys_addr_t first_memblock_size);
> + phys_addr_t first_memblock_size,
> + u64 init_mem_size);
What is the difference between first_memblock_size and init_mem_size, in
terms of what you expect setup_initial_memory_limit to do with them?
Can you just pass in min(first_memblock_size, init_mem_size), with the
non-ePAPR fallback handled in head_8xx.S (just load r30 with 8M instead
of zero)?
> #ifdef CONFIG_PPC64
> /* This is our real memory area size on ppc64 server, on embedded, we
> Index: linux/arch/powerpc/kernel/head_8xx.S
> ===================================================================
> --- linux/arch/powerpc/kernel/head_8xx.S (revision 5484)
> +++ linux/arch/powerpc/kernel/head_8xx.S (copie de travail)
> @@ -31,6 +31,8 @@
> #include <asm/asm-offsets.h>
> #include <asm/ptrace.h>
>
> +#define EPAPR_MAGIC 0x65504150
> +
> /* Macro to make the code more readable. */
> #ifdef CONFIG_8xx_CPU6
> #define DO_8xx_CPU6(val, reg) \
> @@ -77,10 +79,19 @@
> .globl __start
> __start:
> mr r31,r3 /* save device tree ptr */
> + li r30,0
>
> + lis r8,EPAPR_MAGIC@h
> + ori r8,r8, EPAPR_MAGIC@l
> + cmpw cr0,r8, r6
Whitespace
> + bne 1f
> +
> + mr r30,r7 /* save initial ram size */
> +
> /* We have to turn on the MMU right away so we get cache modes
> * set correctly.
> */
> +1:
> bl initial_mmu
>
> /* We now have the lower 8 Meg mapped into TLB entries, and the caches
> @@ -717,6 +728,8 @@
> */
> li r3,0
> mr r4,r31
> + li r5,0
> + mr r6,r30
> bl machine_init
> bl MMU_init
>
> @@ -841,11 +854,17 @@
> ori r8, r8, MI_BOOTINIT|0x2 /* Inhibit cache -- Cort */
> mtspr SPRN_MD_RPN, r8
>
> + /* Map two more 8M kernel data pages if needed
> + * We check how much memory is mapped by the bootloader
> + */
Whitespace
> Index: linux/arch/powerpc/kernel/prom.c
> ===================================================================
> --- linux/arch/powerpc/kernel/prom.c (revision 5484)
> +++ linux/arch/powerpc/kernel/prom.c (copie de travail)
> @@ -649,7 +649,7 @@
> }
> }
>
> -void __init early_init_devtree(void *params)
> +void __init early_init_devtree(void *params, u64 init_mem_size)
> {
> phys_addr_t limit;
>
> @@ -697,7 +697,7 @@
> /* make sure we've parsed cmdline for mem= before this */
> if (memory_limit)
> first_memblock_size = min_t(u64, first_memblock_size, memory_limit);
> - setup_initial_memory_limit(memstart_addr, first_memblock_size);
> + setup_initial_memory_limit(memstart_addr, first_memblock_size, init_mem_size);
Line length.
Yes, I know there's an existing violation on the previous line. :-)
> Index: linux/arch/powerpc/mm/init_32.c
> ===================================================================
> --- linux/arch/powerpc/mm/init_32.c (revision 5484)
> +++ linux/arch/powerpc/mm/init_32.c (copie de travail)
> @@ -206,19 +206,16 @@
>
> #ifdef CONFIG_8xx /* No 8xx specific .c file to put that in ... */
> void setup_initial_memory_limit(phys_addr_t first_memblock_base,
> - phys_addr_t first_memblock_size)
> + phys_addr_t first_memblock_size,
> + u64 init_mem_size)
> {
> /* We don't currently support the first MEMBLOCK not mapping 0
> * physical on those processors
> */
> BUG_ON(first_memblock_base != 0);
>
> -#ifdef CONFIG_PIN_TLB
> - /* 8xx can only access 24MB at the moment */
> - memblock_set_current_limit(min_t(u64, first_memblock_size, 0x01800000));
> -#else
> - /* 8xx can only access 8MB at the moment */
> - memblock_set_current_limit(min_t(u64, first_memblock_size, 0x00800000));
> -#endif
> + if (!init_mem_size)
> + init_mem_size = 0x00800000;
> + memblock_set_current_limit(min_t(u64, first_memblock_size, init_mem_size));
Line length
> }
> #endif /* CONFIG_8xx */
> Index: linux/arch/powerpc/mm/ppc_mmu_32.c
> ===================================================================
> --- linux/arch/powerpc/mm/ppc_mmu_32.c (revision 5484)
> +++ linux/arch/powerpc/mm/ppc_mmu_32.c (copie de travail)
> @@ -273,7 +273,8 @@
> }
>
> void setup_initial_memory_limit(phys_addr_t first_memblock_base,
> - phys_addr_t first_memblock_size)
> + phys_addr_t first_memblock_size,
> + u64 init_mem_size)
> {
> /* We don't currently support the first MEMBLOCK not mapping 0
> * physical on those processors
> Index: linux/arch/powerpc/mm/tlb_nohash.c
> ===================================================================
> --- linux/arch/powerpc/mm/tlb_nohash.c (revision 5484)
> +++ linux/arch/powerpc/mm/tlb_nohash.c (copie de travail)
> @@ -654,7 +654,8 @@
> }
>
> void setup_initial_memory_limit(phys_addr_t first_memblock_base,
> - phys_addr_t first_memblock_size)
> + phys_addr_t first_memblock_size,
> + u64 init_mem_size)
> {
> /* On non-FSL Embedded 64-bit, we adjust the RMA size to match
> * the bolted TLB entry. We know for now that only 1G
It seems a bit odd for this function to take init_mem_size on these other
platforms, but not use it.
-Scott
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2014-03-19 20:42 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-12-15 15:09 [RFC PATCH v3] powerpc: Loading kernels over 8Mbytes without CONFIG_PIN_TLB Christophe Leroy
2014-03-19 20:42 ` [RFC, " Scott Wood
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®