2021-09-27 10:38:54

by Christophe Leroy

[permalink] [raw]
Subject: [PATCH] powerpc/40x: Map 32Mbytes of memory at startup

As reported by Carlo, 16Mbytes is not enough with modern kernels
that tend to be a bit big, so map another 16M page at boot.

Cc: cp <[email protected]>
Signed-off-by: Christophe Leroy <[email protected]>
---
arch/powerpc/kernel/head_40x.S | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/head_40x.S b/arch/powerpc/kernel/head_40x.S
index 7d72ee5ab387..5fce4680d2d3 100644
--- a/arch/powerpc/kernel/head_40x.S
+++ b/arch/powerpc/kernel/head_40x.S
@@ -650,7 +650,7 @@ start_here:
b . /* prevent prefetch past rfi */

/* Set up the initial MMU state so we can do the first level of
- * kernel initialization. This maps the first 16 MBytes of memory 1:1
+ * kernel initialization. This maps the first 32 MBytes of memory 1:1
* virtual to physical and more importantly sets the cache mode.
*/
initial_mmu:
@@ -687,6 +687,12 @@ initial_mmu:
tlbwe r4,r0,TLB_DATA /* Load the data portion of the entry */
tlbwe r3,r0,TLB_TAG /* Load the tag portion of the entry */

+ li r0,62 /* TLB slot 62 */
+ addis r4,r4,SZ_16M
+ addis r3,r3,SZ_16M
+ tlbwe r4,r0,TLB_DATA /* Load the data portion of the entry */
+ tlbwe r3,r0,TLB_TAG /* Load the tag portion of the entry */
+
isync

/* Establish the exception vector base
--
2.31.1


2021-09-28 00:08:16

by cp

[permalink] [raw]
Subject: Re: [PATCH] powerpc/40x: Map 32Mbytes of memory at startup

hi,
this is my second patch-test report.

Today I have successfully tested Christophe Leroy's patch.

Attached a cleaned patch. With the previous one the kernel booted, but
there was a line missing.

I have also tested two different kernels with success

both kernel sizes were ~9.4MB
the Entry Point was always 0x00901b00

used toolchain:
- powerpc-unknown-linux-gnu-binutiles-v2.34
- powerpc-unknown-linux-gnu-gcc-v9.3.0

host:
- macmini-intel, Gentoo cross-compiler, 32bit userland

target:
- AMCC PPC405GP

wrapper:
- cuboot

Applied to
- kernel-v5.2.1-vanilla
- kernel-v5.7.19-vanilla

Attached I report here is the difference between the original file and mine.

Thanks guys!
Carlo

-----------------------
map 32MB of ram rather than 16MB
--- arch/powerpc/kernel/head_40x.S.original 2021-09-28
00:07:27.768000000 -0000
+++ arch/powerpc/kernel/head_40x.S 2021-09-28 00:07:27.760000000 -0000
@@ -25,6 +25,7 @@
* Kernel execution entry point code.
*/

+
#include <linux/init.h>
#include <asm/processor.h>
#include <asm/page.h>
@@ -842,17 +843,33 @@
mtspr SPRN_PID,r0
sync

- /* Configure and load one entry into TLB slots 63 */
- clrrwi r4,r4,10 /* Mask off the real page number */
- ori r4,r4,(TLB_WR | TLB_EX) /* Set the write and execute bits */
-
- clrrwi r3,r3,10 /* Mask off the effective page number */
- ori r3,r3,(TLB_VALID | TLB_PAGESZ(PAGESZ_16M))
-
- li r0,63 /* TLB slot 63 */
-
- tlbwe r4,r0,TLB_DATA /* Load the data portion of the entry */
- tlbwe r3,r0,TLB_TAG /* Load the tag portion of the entry */
+ /*
+ * Configure and load two entries into TLB slots 62 and 63.
+ * TLB 62 is used for first 16M page
+ * TLB 63 is for the second 16M page
+ * In case we are pinning TLBs, these are reserved in by
+ * the other TLB functions.
+ * If not reserved, then it doesn't matter where they are loaded.
+ */
+ clrrwi r4,r4,10 /* Mask off the real page number */
+ ori r4,r4,(TLB_WR | TLB_EX) /* Set the write and execute bits */
+
+ clrrwi r3,r3,10 /* Mask off the effective
page number */
+ ori r3,r3,(TLB_VALID | TLB_PAGESZ(PAGESZ_16M))
+
+ li r0,62 /* TLB slot 62 */
+
+ tlbwe r4,r0,TLB_DATA /* Load the data portion of
the entry */
+ tlbwe r3,r0,TLB_TAG /* Load the tag portion of the entry */
+
+ addis r4, r4, 0x0100 /* Map next 16 Mentries */
+ addis r3, r3, 0x0100
+
+ li r0,63 /* TLB slot 63 */
+
+ /* Load up the kernel context */
+ tlbwe r4,r0,TLB_DATA /* Load the data portion of
the entry */
+ tlbwe r3,r0,TLB_TAG /* Load the tag portion of the entry */

isync




On Mon, 27 Sept 2021 at 12:35, Christophe Leroy
<[email protected]> wrote:
>
> As reported by Carlo, 16Mbytes is not enough with modern kernels
> that tend to be a bit big, so map another 16M page at boot.

2021-09-28 00:20:27

by Michael Ellerman

[permalink] [raw]
Subject: Re: [PATCH] powerpc/40x: Map 32Mbytes of memory at startup

Christophe Leroy <[email protected]> writes:
> As reported by Carlo, 16Mbytes is not enough with modern kernels
> that tend to be a bit big, so map another 16M page at boot.

I guess we're not expecting systems with less than 32MB, so making it
unconditional is OK?

cheers

> diff --git a/arch/powerpc/kernel/head_40x.S b/arch/powerpc/kernel/head_40x.S
> index 7d72ee5ab387..5fce4680d2d3 100644
> --- a/arch/powerpc/kernel/head_40x.S
> +++ b/arch/powerpc/kernel/head_40x.S
> @@ -650,7 +650,7 @@ start_here:
> b . /* prevent prefetch past rfi */
>
> /* Set up the initial MMU state so we can do the first level of
> - * kernel initialization. This maps the first 16 MBytes of memory 1:1
> + * kernel initialization. This maps the first 32 MBytes of memory 1:1
> * virtual to physical and more importantly sets the cache mode.
> */
> initial_mmu:
> @@ -687,6 +687,12 @@ initial_mmu:
> tlbwe r4,r0,TLB_DATA /* Load the data portion of the entry */
> tlbwe r3,r0,TLB_TAG /* Load the tag portion of the entry */
>
> + li r0,62 /* TLB slot 62 */
> + addis r4,r4,SZ_16M
> + addis r3,r3,SZ_16M
> + tlbwe r4,r0,TLB_DATA /* Load the data portion of the entry */
> + tlbwe r3,r0,TLB_TAG /* Load the tag portion of the entry */
> +
> isync
>
> /* Establish the exception vector base
> --
> 2.31.1

2021-09-28 00:29:13

by cp

[permalink] [raw]
Subject: Re: [PATCH] powerpc/40x: Map 32Mbytes of memory at startup

> I guess we're not expecting systems with less than 32MB, so making it
> unconditional is OK?

hi
it's not 32MB of total physical ram, but rather using 32MB of the
total physical ram to correctly boot a kernel bigger than 8MB.

The problem is complex:
- u-boot loads things at 0x0200.0000 (in my case)
- then cuboot copies the kernel to 0x0090.0000, and appends the flat
device tree to the end of kernel
- then cuboot copies again the kernel to 0x0000.0000, and invokes head.S

at this point head.S needs to initialize the virtual memory, and needs
to have 32MB mapped in order to correctly gets the flat device tree

if the kernel is smaller than 8MB, then cuboot copies it to
0x0080.0000, and head.S only need to have 16MB mapped in order to gets
the flat device tree

Cheers