[PATCH 1/5] powerpc: booke: Don't hard-code size of struct tlbcam

Subsystems: linux for powerpc (32-bit and 64-bit), the rest

STALE6423d

13 messages, 4 authors, 2009-01-13 · open the first message on its own page

[PATCH 1/5] powerpc: booke: Don't hard-code size of struct tlbcam

From: Trent Piepho <hidden>
Date: 2008-12-09 03:35:04

Some assembly code in head_fsl_booke.S hard-coded the size of struct tlbcam
to 20 when it indexed the TLBCAM table.  Anyone changing the size of struct
tlbcam would not know to expect that.

The kernel already has a system to get the size of C structures into
assembly language files, asm-offsets, so let's use it.

The definition of the struct gets moved to a header, so that asm-offsets.c
can include it.

Signed-off-by: Trent Piepho <redacted>
---
 arch/powerpc/kernel/asm-offsets.c    |    8 ++++++++
 arch/powerpc/kernel/head_fsl_booke.S |    2 +-
 arch/powerpc/mm/fsl_booke_mmu.c      |    8 +-------
 arch/powerpc/mm/mmu_decl.h           |    9 +++++++++
 4 files changed, 19 insertions(+), 8 deletions(-)
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 050abfd..4d62a8d 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -56,6 +56,10 @@
 #include "head_booke.h"
 #endif
 
+#if defined(CONFIG_FSL_BOOKE)
+#include "../mm/mmu_decl.h"
+#endif
+
 int main(void)
 {
 	DEFINE(THREAD, offsetof(struct task_struct, thread));
@@ -271,6 +275,10 @@ int main(void)
 	DEFINE(SAVED_KSP_LIMIT, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, saved_ksp_limit));
 #endif
 
+#ifdef CONFIG_FSL_BOOKE
+	DEFINE(TLBCAM_SIZE, sizeof(struct tlbcam));
+#endif
+
 	DEFINE(CLONE_VM, CLONE_VM);
 	DEFINE(CLONE_UNTRACED, CLONE_UNTRACED);
 
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
index 9a4639c..c591acb 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -909,7 +909,7 @@ KernelSPE:
 _GLOBAL(loadcam_entry)
 	lis	r4,TLBCAM@ha
 	addi	r4,r4,TLBCAM@l
-	mulli	r5,r3,20
+	mulli	r5,r3,TLBCAM_SIZE
 	add	r3,r5,r4
 	lwz	r4,0(r3)
 	mtspr	SPRN_MAS0,r4
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c
index 23cee39..c9ee59a 100644
--- a/arch/powerpc/mm/fsl_booke_mmu.c
+++ b/arch/powerpc/mm/fsl_booke_mmu.c
@@ -61,13 +61,7 @@ static unsigned long __cam0, __cam1, __cam2;
 
 #define NUM_TLBCAMS	(16)
 
-struct tlbcam {
-   	u32	MAS0;
-	u32	MAS1;
-	u32	MAS2;
-	u32	MAS3;
-	u32	MAS7;
-} TLBCAM[NUM_TLBCAMS];
+struct tlbcam TLBCAM[NUM_TLBCAMS];
 
 struct tlbcamrange {
    	unsigned long start;
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
index fab3cfa..f0d0aae 100644
--- a/arch/powerpc/mm/mmu_decl.h
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -27,6 +27,15 @@ extern void hash_preload(struct mm_struct *mm, unsigned long ea,
 
 
 #ifdef CONFIG_PPC32
+
+struct tlbcam {
+	u32	MAS0;
+	u32	MAS1;
+	u32	MAS2;
+	u32	MAS3;
+	u32	MAS7;
+};
+
 extern void mapin_ram(void);
 extern int map_page(unsigned long va, phys_addr_t pa, int flags);
 extern void setbat(int index, unsigned long virt, phys_addr_t phys,
-- 
1.5.4.1

[PATCH 2/5] powerpc: booke: Remove num_tlbcam_entries

From: Trent Piepho <hidden>
Date: 2008-12-09 03:35:04

This is a global variable defined in fsl_booke_mmu.c with a value that gets
initialized in assembly code in head_fsl_booke.S.

It's never used.

If some code ever does want to know the number of entries in TLB1, then
"numcams = mfspr(SPRN_TLB1CFG) & 0xfff", is a whole lot simpler than a
global initialized during kernel boot from assembly.

Signed-off-by: Trent Piepho <redacted>
---
 arch/powerpc/kernel/head_fsl_booke.S |    4 ----
 arch/powerpc/mm/fsl_booke_mmu.c      |    1 -
 arch/powerpc/mm/mmu_decl.h           |    2 --
 3 files changed, 0 insertions(+), 7 deletions(-)
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
index c591acb..e33021f 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -389,10 +389,6 @@ skpinv:	addi	r6,r6,1				/* Increment */
 #endif
 #endif
 
-	mfspr	r3,SPRN_TLB1CFG
-	andi.	r3,r3,0xfff
-	lis	r4,num_tlbcam_entries@ha
-	stw	r3,num_tlbcam_entries@l(r4)
 /*
  * Decide what sort of machine this is and initialize the MMU.
  */
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c
index c9ee59a..1971e4e 100644
--- a/arch/powerpc/mm/fsl_booke_mmu.c
+++ b/arch/powerpc/mm/fsl_booke_mmu.c
@@ -56,7 +56,6 @@
 
 extern void loadcam_entry(unsigned int index);
 unsigned int tlbcam_index;
-unsigned int num_tlbcam_entries;
 static unsigned long __cam0, __cam1, __cam2;
 
 #define NUM_TLBCAMS	(16)
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
index f0d0aae..1db3c67 100644
--- a/arch/powerpc/mm/mmu_decl.h
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -51,8 +51,6 @@ extern unsigned int rtas_data, rtas_size;
 struct hash_pte;
 extern struct hash_pte *Hash, *Hash_end;
 extern unsigned long Hash_size, Hash_mask;
-
-extern unsigned int num_tlbcam_entries;
 #endif
 
 extern unsigned long ioremap_bot;
-- 
1.5.4.1

[PATCH 3/5] powerpc: booke: Remove code duplication in lowmem mapping

From: Trent Piepho <hidden>
Date: 2008-12-09 03:35:05

The code to map lowmem uses three CAM aka TLB[1] entries to cover it.  The
size of each is stored in three globals named __cam0, __cam1, and __cam2.
All the code that uses them is duplicated three times for each of the three
variables.

We have these things called arrays and loops....

Once converted to use an array, it will be easier to make the number of
CAMs configurable.

Signed-off-by: Trent Piepho <redacted>
---
 arch/powerpc/mm/fsl_booke_mmu.c |   79 +++++++++++++++-----------------------
 1 files changed, 31 insertions(+), 48 deletions(-)
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c
index 1971e4e..1dabe1a 100644
--- a/arch/powerpc/mm/fsl_booke_mmu.c
+++ b/arch/powerpc/mm/fsl_booke_mmu.c
@@ -56,7 +56,7 @@
 
 extern void loadcam_entry(unsigned int index);
 unsigned int tlbcam_index;
-static unsigned long __cam0, __cam1, __cam2;
+static unsigned long cam[3];
 
 #define NUM_TLBCAMS	(16)
 
@@ -152,19 +152,19 @@ void invalidate_tlbcam_entry(int index)
 	loadcam_entry(index);
 }
 
-void __init cam_mapin_ram(unsigned long cam0, unsigned long cam1,
-		unsigned long cam2)
+unsigned long __init mmu_mapin_ram(void)
 {
-	settlbcam(0, PAGE_OFFSET, memstart_addr, cam0, _PAGE_KERNEL, 0);
-	tlbcam_index++;
-	if (cam1) {
-		tlbcam_index++;
-		settlbcam(1, PAGE_OFFSET+cam0, memstart_addr+cam0, cam1, _PAGE_KERNEL, 0);
-	}
-	if (cam2) {
+	unsigned long virt = PAGE_OFFSET;
+	phys_addr_t phys = memstart_addr;
+
+	while (cam[tlbcam_index] && tlbcam_index < ARRAY_SIZE(cam)) {
+		settlbcam(tlbcam_index, virt, phys, cam[tlbcam_index], _PAGE_KERNEL, 0);
+		virt += cam[tlbcam_index];
+		phys += cam[tlbcam_index];
 		tlbcam_index++;
-		settlbcam(2, PAGE_OFFSET+cam0+cam1, memstart_addr+cam0+cam1, cam2, _PAGE_KERNEL, 0);
 	}
+
+	return virt - PAGE_OFFSET;
 }
 
 /*
@@ -175,51 +175,34 @@ void __init MMU_init_hw(void)
 	flush_instruction_cache();
 }
 
-unsigned long __init mmu_mapin_ram(void)
-{
-	cam_mapin_ram(__cam0, __cam1, __cam2);
-
-	return __cam0 + __cam1 + __cam2;
-}
-
-
 void __init
 adjust_total_lowmem(void)
 {
-	phys_addr_t max_lowmem_size = __max_low_memory;
-	phys_addr_t cam_max_size = 0x10000000;
 	phys_addr_t ram;
+	unsigned int max_cam = 28;	/* 2^28 = 256 Mb */
+	char buf[ARRAY_SIZE(cam) * 5 + 1], *p = buf;
+	int i;
 
-	/* adjust CAM size to max_lowmem_size */
-	if (max_lowmem_size < cam_max_size)
-		cam_max_size = max_lowmem_size;
-
-	/* adjust lowmem size to max_lowmem_size */
-	ram = min(max_lowmem_size, total_lowmem);
+	/* adjust lowmem size to __max_low_memory */
+	ram = min((phys_addr_t)__max_low_memory, (phys_addr_t)total_lowmem);
 
 	/* Calculate CAM values */
-	__cam0 = 1UL << 2 * (__ilog2(ram) / 2);
-	if (__cam0 > cam_max_size)
-		__cam0 = cam_max_size;
-	ram -= __cam0;
-	if (ram) {
-		__cam1 = 1UL << 2 * (__ilog2(ram) / 2);
-		if (__cam1 > cam_max_size)
-			__cam1 = cam_max_size;
-		ram -= __cam1;
-	}
-	if (ram) {
-		__cam2 = 1UL << 2 * (__ilog2(ram) / 2);
-		if (__cam2 > cam_max_size)
-			__cam2 = cam_max_size;
-		ram -= __cam2;
+	__max_low_memory = 0;
+	for (i = 0; ram && i < ARRAY_SIZE(cam); i++) {
+		unsigned int camsize = __ilog2(ram) & ~1U;
+		if (camsize > max_cam)
+			camsize = max_cam;
+		cam[i] = 1UL << camsize;
+		ram -= cam[i];
+		__max_low_memory += cam[i];
+
+		p += sprintf(p, "%lu/", cam[i] >> 20);
 	}
+	for (; i < ARRAY_SIZE(cam); i++)
+		p += sprintf(p, "0/");
+	p[-1] = '\0';
 
-	printk(KERN_INFO "Memory CAM mapping: CAM0=%ldMb, CAM1=%ldMb,"
-			" CAM2=%ldMb residual: %ldMb\n",
-			__cam0 >> 20, __cam1 >> 20, __cam2 >> 20,
-			(long int)((total_lowmem - __cam0 - __cam1 - __cam2)
-				   >> 20));
-	__max_low_memory = __cam0 + __cam1 + __cam2;
+	pr_info("Memory CAM mapping: %s Mb, residual: %ldMb\n", buf,
+	        (total_lowmem - __max_low_memory) >> 20);
 	__initial_memory_limit_addr = memstart_addr + __max_low_memory;
 }
-- 
1.5.4.1

[PATCH 4/5] powerpc: booke: Make CAM entries used for lowmem configurable

From: Trent Piepho <hidden>
Date: 2008-12-09 03:35:06

On booke processors, the code that maps low memory only uses up to three
CAM entries, even though there are sixteen and nothing else uses them.

Make this number configurable in the advanced options menu along with max
low memory size.  If one wants 1 GB of lowmem, then it's typically
necessary to have four CAM entries.

Signed-off-by: Trent Piepho <redacted>
---
 arch/powerpc/Kconfig            |   16 ++++++++++++++++
 arch/powerpc/mm/fsl_booke_mmu.c |    6 +++++-
 2 files changed, 21 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index be4f99b..2bb645c 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -696,6 +696,22 @@ config LOWMEM_SIZE
 	hex "Maximum low memory size (in bytes)" if LOWMEM_SIZE_BOOL
 	default "0x30000000"
 
+config LOWMEM_CAM_NUM_BOOL
+	bool "Set number of CAMs to use to map low memory"
+	depends on ADVANCED_OPTIONS && FSL_BOOKE
+	help
+	  This option allows you to set the maximum number of CAM slots that
+	  will be used to map low memory.  There are a limited number of slots
+	  available and even more limited number that will fit in the L1 MMU.
+	  However, using more entries will allow mapping more low memory.  This
+	  can be useful in optimizing the layout of kernel virtual memory.
+
+	  Say N here unless you know what you are doing.
+
+config LOWMEM_CAM_NUM
+	int "Number of CAMs to use to map low memory" if LOWMEM_CAM_NUM_BOOL
+	default 3
+
 config RELOCATABLE
 	bool "Build a relocatable kernel (EXPERIMENTAL)"
 	depends on EXPERIMENTAL && ADVANCED_OPTIONS && FLATMEM && FSL_BOOKE
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c
index 1dabe1a..73aa9b7 100644
--- a/arch/powerpc/mm/fsl_booke_mmu.c
+++ b/arch/powerpc/mm/fsl_booke_mmu.c
@@ -56,10 +56,14 @@
 
 extern void loadcam_entry(unsigned int index);
 unsigned int tlbcam_index;
-static unsigned long cam[3];
+static unsigned long cam[CONFIG_LOWMEM_CAM_NUM];
 
 #define NUM_TLBCAMS	(16)
 
+#if defined(CONFIG_LOWMEM_CAM_NUM_BOOL) && (CONFIG_LOWMEM_CAM_NUM >= NUM_TLBCAMS)
+#error "LOWMEM_CAM_NUM must be less than NUM_TLBCAMS"
+#endif
+
 struct tlbcam TLBCAM[NUM_TLBCAMS];
 
 struct tlbcamrange {
-- 
1.5.4.1

[PATCH 5/5] powerpc: booke: Allow larger CAM sizes than 256 MB

From: Trent Piepho <hidden>
Date: 2008-12-09 03:35:07

The code that maps kernel low memory would only use page sizes up to 256
MB.  On E500v2 pages up to 4 GB are supported.

However, a page must be aligned to a multiple of the page's size.  I.e.
256 MB pages must aligned to a 256 MB boundary.  This was enforced by a
requirement that the physical and virtual addresses of the start of lowmem
be aligned to 256 MB.  Clearly requiring 1GB or 4GB alignment to allow
pages of that size isn't acceptable.

To solve this, I simply have adjust_total_lowmem() take alignment into
account when it decides what size pages to use.  Give it PAGE_OFFSET =
0x7000_0000, PHYSICAL_START = 0x3000_0000, and 2GB of RAM, and it will map
pages like this:
PA 0x3000_0000 VA 0x7000_0000 Size 256 MB
PA 0x4000_0000 VA 0x8000_0000 Size 1 GB
PA 0x8000_0000 VA 0xC000_0000 Size 256 MB
PA 0x9000_0000 VA 0xD000_0000 Size 256 MB
PA 0xA000_0000 VA 0xE000_0000 Size 256 MB

Because the lowmem mapping code now takes alignment into account,
PHYSICAL_ALIGN can be lowered from 256 MB to 64 MB.  Even lower might be
possible.  The lowmem code will work down to 4 kB but it's possible some of
the boot code will fail before then.  Poor alignment will force small pages
to be used, which combined with the limited number of TLB1 pages available,
will result in very little memory getting mapped.  So alignments less than
64 MB probably aren't very useful anyway.

Signed-off-by: Trent Piepho <redacted>
---
 arch/powerpc/Kconfig            |    2 +-
 arch/powerpc/mm/fsl_booke_mmu.c |   14 +++++++++++++-
 2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 2bb645c..a7b6b8f 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -776,7 +776,7 @@ config PHYSICAL_START
 
 config PHYSICAL_ALIGN
 	hex
-	default "0x10000000" if FSL_BOOKE
+	default "0x04000000" if FSL_BOOKE
 	help
 	  This value puts the alignment restrictions on physical address
 	  where kernel is loaded and run from. Kernel is compiled for an
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c
index 73aa9b7..0b9ba6b 100644
--- a/arch/powerpc/mm/fsl_booke_mmu.c
+++ b/arch/powerpc/mm/fsl_booke_mmu.c
@@ -183,9 +183,14 @@ void __init
 adjust_total_lowmem(void)
 {
 	phys_addr_t ram;
-	unsigned int max_cam = 28;	/* 2^28 = 256 Mb */
+	unsigned int max_cam = (mfspr(SPRN_TLB1CFG) >> 16) & 0xff;
 	char buf[ARRAY_SIZE(cam) * 5 + 1], *p = buf;
 	int i;
+	unsigned long virt = PAGE_OFFSET & 0xffffffffUL;
+	unsigned long phys = memstart_addr & 0xffffffffUL;
+
+	/* Convert (4^max) kB to (2^max) bytes */
+	max_cam = max_cam * 2 + 10;
 
 	/* adjust lowmem size to __max_low_memory */
 	ram = min((phys_addr_t)__max_low_memory, (phys_addr_t)total_lowmem);
@@ -194,11 +199,18 @@ adjust_total_lowmem(void)
 	__max_low_memory = 0;
 	for (i = 0; ram && i < ARRAY_SIZE(cam); i++) {
 		unsigned int camsize = __ilog2(ram) & ~1U;
+		unsigned int align = __ffs(virt | phys) & ~1U;
+
+		if (camsize > align)
+			camsize = align;
 		if (camsize > max_cam)
 			camsize = max_cam;
+
 		cam[i] = 1UL << camsize;
 		ram -= cam[i];
 		__max_low_memory += cam[i];
+		virt += cam[i];
+		phys += cam[i];
 
 		p += sprintf(p, "%lu/", cam[i] >> 20);
 	}
-- 
1.5.4.1

Re: [PATCH 1/5] powerpc: booke: Don't hard-code size of struct tlbcam

From: Josh Boyer <hidden>
Date: 2008-12-09 14:27:03

On Mon,  8 Dec 2008 19:34:55 -0800
Trent Piepho [off-list ref] wrote:
Some assembly code in head_fsl_booke.S hard-coded the size of struct tlbcam
to 20 when it indexed the TLBCAM table.  Anyone changing the size of struct
tlbcam would not know to expect that.

The kernel already has a system to get the size of C structures into
assembly language files, asm-offsets, so let's use it.

The definition of the struct gets moved to a header, so that asm-offsets.c
can include it.
I don't mean to be overly picky, but your patch subjects and changelog
descriptions are a bit wrong.  This series pertains to FSL BookE chips,
not BookE in general.  There are other variants of BookE, such as 4xx.

If you could keep that in mind for future revisions, I'd appreciate
it.  Something like:

[PATCH] powerpc/fsl-booke: 

or something similar would be a bit more correct.  Unless you really
are changing something global to all BookE processors (which is sort of
rare at the moment).

josh

Re: [PATCH 1/5] powerpc: booke: Don't hard-code size of struct tlbcam

From: Kumar Gala <hidden>
Date: 2009-01-07 16:06:01

On Dec 8, 2008, at 9:34 PM, Trent Piepho wrote:
Some assembly code in head_fsl_booke.S hard-coded the size of struct  
tlbcam
to 20 when it indexed the TLBCAM table.  Anyone changing the size of  
struct
tlbcam would not know to expect that.

The kernel already has a system to get the size of C structures into
assembly language files, asm-offsets, so let's use it.

The definition of the struct gets moved to a header, so that asm- 
offsets.c
can include it.

Signed-off-by: Trent Piepho <redacted>
---
arch/powerpc/kernel/asm-offsets.c    |    8 ++++++++
arch/powerpc/kernel/head_fsl_booke.S |    2 +-
arch/powerpc/mm/fsl_booke_mmu.c      |    8 +-------
arch/powerpc/mm/mmu_decl.h           |    9 +++++++++
4 files changed, 19 insertions(+), 8 deletions(-)
applied to next

- k

Re: [PATCH 2/5] powerpc: booke: Remove num_tlbcam_entries

From: Kumar Gala <hidden>
Date: 2009-01-07 16:07:15

On Dec 8, 2008, at 9:34 PM, Trent Piepho wrote:
This is a global variable defined in fsl_booke_mmu.c with a value  
that gets
initialized in assembly code in head_fsl_booke.S.

It's never used.

If some code ever does want to know the number of entries in TLB1,  
then
"numcams = mfspr(SPRN_TLB1CFG) & 0xfff", is a whole lot simpler than a
global initialized during kernel boot from assembly.

Signed-off-by: Trent Piepho <redacted>
---
arch/powerpc/kernel/head_fsl_booke.S |    4 ----
arch/powerpc/mm/fsl_booke_mmu.c      |    1 -
arch/powerpc/mm/mmu_decl.h           |    2 --
3 files changed, 0 insertions(+), 7 deletions(-)
applied to next

- k

Re: [PATCH 3/5] powerpc: booke: Remove code duplication in lowmem mapping

From: Kumar Gala <hidden>
Date: 2009-01-07 16:16:01

void __init
adjust_total_lowmem(void)
{
-	phys_addr_t max_lowmem_size = __max_low_memory;
-	phys_addr_t cam_max_size = 0x10000000;
	phys_addr_t ram;
+	unsigned int max_cam = 28;	/* 2^28 = 256 Mb */
+	char buf[ARRAY_SIZE(cam) * 5 + 1], *p = buf;
+	int i;

-	/* adjust CAM size to max_lowmem_size */
-	if (max_lowmem_size < cam_max_size)
-		cam_max_size = max_lowmem_size;
-
-	/* adjust lowmem size to max_lowmem_size */
-	ram = min(max_lowmem_size, total_lowmem);
+	/* adjust lowmem size to __max_low_memory */
+	ram = min((phys_addr_t)__max_low_memory, (phys_addr_t)total_lowmem);

	/* Calculate CAM values */
-	__cam0 = 1UL << 2 * (__ilog2(ram) / 2);
-	if (__cam0 > cam_max_size)
-		__cam0 = cam_max_size;
-	ram -= __cam0;
-	if (ram) {
-		__cam1 = 1UL << 2 * (__ilog2(ram) / 2);
-		if (__cam1 > cam_max_size)
-			__cam1 = cam_max_size;
-		ram -= __cam1;
-	}
-	if (ram) {
-		__cam2 = 1UL << 2 * (__ilog2(ram) / 2);
-		if (__cam2 > cam_max_size)
-			__cam2 = cam_max_size;
-		ram -= __cam2;
+	__max_low_memory = 0;
+	for (i = 0; ram && i < ARRAY_SIZE(cam); i++) {
+		unsigned int camsize = __ilog2(ram) & ~1U;
+		if (camsize > max_cam)
+			camsize = max_cam;
+		cam[i] = 1UL << camsize;
+		ram -= cam[i];
+		__max_low_memory += cam[i];
+
+		p += sprintf(p, "%lu/", cam[i] >> 20);
	}
+	for (; i < ARRAY_SIZE(cam); i++)
+		p += sprintf(p, "0/");
+	p[-1] = '\0';
this all seems like overkill.  Can we use string_get_size() from lib/ 
string_helpers.c and just printf in a loop?
-	printk(KERN_INFO "Memory CAM mapping: CAM0=%ldMb, CAM1=%ldMb,"
-			" CAM2=%ldMb residual: %ldMb\n",
-			__cam0 >> 20, __cam1 >> 20, __cam2 >> 20,
-			(long int)((total_lowmem - __cam0 - __cam1 - __cam2)
-				   >> 20));
-	__max_low_memory = __cam0 + __cam1 + __cam2;
+	pr_info("Memory CAM mapping: %s Mb, residual: %ldMb\n", buf,
+	        (total_lowmem - __max_low_memory) >> 20);
	__initial_memory_limit_addr = memstart_addr + __max_low_memory;
}
- k

Re: [PATCH 1/5] powerpc: booke: Don't hard-code size of struct tlbcam

From: Kumar Gala <hidden>
Date: 2009-01-07 16:17:30

On Dec 9, 2008, at 8:26 AM, Josh Boyer wrote:
On Mon,  8 Dec 2008 19:34:55 -0800
Trent Piepho [off-list ref] wrote:
quoted
Some assembly code in head_fsl_booke.S hard-coded the size of  
struct tlbcam
to 20 when it indexed the TLBCAM table.  Anyone changing the size  
of struct
tlbcam would not know to expect that.

The kernel already has a system to get the size of C structures into
assembly language files, asm-offsets, so let's use it.

The definition of the struct gets moved to a header, so that asm- 
offsets.c
can include it.
I don't mean to be overly picky, but your patch subjects and changelog
descriptions are a bit wrong.  This series pertains to FSL BookE  
chips,
not BookE in general.  There are other variants of BookE, such as 4xx.

If you could keep that in mind for future revisions, I'd appreciate
it.  Something like:

[PATCH] powerpc/fsl-booke:

or something similar would be a bit more correct.  Unless you really
are changing something global to all BookE processors (which is sort  
of
rare at the moment).
I fixed this in the actually commit ;)

- k

Re: [PATCH 3/5] powerpc: booke: Remove code duplication in lowmem mapping

From: Kumar Gala <hidden>
Date: 2009-01-13 15:45:11

On Dec 8, 2008, at 9:34 PM, Trent Piepho wrote:
The code to map lowmem uses three CAM aka TLB[1] entries to cover  
it.  The
size of each is stored in three globals named __cam0, __cam1, and  
__cam2.
All the code that uses them is duplicated three times for each of  
the three
variables.

We have these things called arrays and loops....

Once converted to use an array, it will be easier to make the number  
of
CAMs configurable.

Signed-off-by: Trent Piepho <redacted>
---
arch/powerpc/mm/fsl_booke_mmu.c |   79 ++++++++++++++ 
+-----------------------
1 files changed, 31 insertions(+), 48 deletions(-)
applied.  Still not happy about the buf[] for output, but its minor.

- k

Re: [PATCH 4/5] powerpc: booke: Make CAM entries used for lowmem configurable

From: Kumar Gala <hidden>
Date: 2009-01-13 15:45:17

On Dec 8, 2008, at 9:34 PM, Trent Piepho wrote:
On booke processors, the code that maps low memory only uses up to  
three
CAM entries, even though there are sixteen and nothing else uses them.

Make this number configurable in the advanced options menu along  
with max
low memory size.  If one wants 1 GB of lowmem, then it's typically
necessary to have four CAM entries.

Signed-off-by: Trent Piepho <redacted>
---
arch/powerpc/Kconfig            |   16 ++++++++++++++++
arch/powerpc/mm/fsl_booke_mmu.c |    6 +++++-
2 files changed, 21 insertions(+), 1 deletions(-)
applied

- k

Re: [PATCH 5/5] powerpc: booke: Allow larger CAM sizes than 256 MB

From: Kumar Gala <hidden>
Date: 2009-01-13 15:45:33

On Dec 8, 2008, at 9:34 PM, Trent Piepho wrote:
The code that maps kernel low memory would only use page sizes up to  
256
MB.  On E500v2 pages up to 4 GB are supported.

However, a page must be aligned to a multiple of the page's size.   
I.e.
256 MB pages must aligned to a 256 MB boundary.  This was enforced  
by a
requirement that the physical and virtual addresses of the start of  
lowmem
be aligned to 256 MB.  Clearly requiring 1GB or 4GB alignment to allow
pages of that size isn't acceptable.

To solve this, I simply have adjust_total_lowmem() take alignment into
account when it decides what size pages to use.  Give it PAGE_OFFSET =
0x7000_0000, PHYSICAL_START = 0x3000_0000, and 2GB of RAM, and it  
will map
pages like this:
PA 0x3000_0000 VA 0x7000_0000 Size 256 MB
PA 0x4000_0000 VA 0x8000_0000 Size 1 GB
PA 0x8000_0000 VA 0xC000_0000 Size 256 MB
PA 0x9000_0000 VA 0xD000_0000 Size 256 MB
PA 0xA000_0000 VA 0xE000_0000 Size 256 MB

Because the lowmem mapping code now takes alignment into account,
PHYSICAL_ALIGN can be lowered from 256 MB to 64 MB.  Even lower  
might be
possible.  The lowmem code will work down to 4 kB but it's possible  
some of
the boot code will fail before then.  Poor alignment will force  
small pages
to be used, which combined with the limited number of TLB1 pages  
available,
will result in very little memory getting mapped.  So alignments  
less than
64 MB probably aren't very useful anyway.

Signed-off-by: Trent Piepho <redacted>
---
arch/powerpc/Kconfig            |    2 +-
arch/powerpc/mm/fsl_booke_mmu.c |   14 +++++++++++++-
2 files changed, 14 insertions(+), 2 deletions(-)
applied

- k
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help