diff mbox

[U-Boot,v3,4/6] PPC: 85xx: Generalize DDR TLB mapping function

Message ID 1392077408-16551-5-git-send-email-agraf@suse.de
State Superseded
Delegated to: York Sun
Headers show

Commit Message

Alexander Graf Feb. 11, 2014, 12:10 a.m. UTC
The DDR mapping function really is just a generic virtual -> physical
mapping function. Generalize it so it can support any virtual starting
offset and IO maps just the same.

Signed-off-by: Alexander Graf <agraf@suse.de>
---
 arch/powerpc/cpu/mpc85xx/tlb.c |   48 ++++++++++++++++++++++++++--------------
 arch/powerpc/include/asm/mmu.h |    3 +++
 2 files changed, 34 insertions(+), 17 deletions(-)

Comments

Scott Wood Feb. 18, 2014, 11:21 p.m. UTC | #1
On Tue, 2014-02-11 at 01:10 +0100, Alexander Graf wrote:
> -	if (memsize)
> -		print_size(memsize, " left unmapped\n");
> +	if (size)
> +		print_size(size, " left unmapped\n");
> +}

The print_size should move to the caller, with some way to pass back the
amout left unmapped.  Non-RAM callers would treat a non-zero unmapped
value as an error.

> +unsigned int
> +setup_ddr_tlbs_phys(phys_addr_t p_addr, unsigned int memsize_in_meg)
> +{
> +	unsigned int ram_tlb_address = (unsigned int)CONFIG_SYS_DDR_SDRAM_BASE;
> +	u64 memsize = (u64)memsize_in_meg << 20;
> +
> +	memsize = min(memsize, CONFIG_MAX_MEM_MAPPED);
> +	tlb_map_range(ram_tlb_address, p_addr, memsize, true);
>  	return memsize_in_meg;
>  }

Here you seem to be hiding the message for RAM.

York, are you OK with just removing the message altogether, and having
tlb_map_range return a normal error code if it can't map everything
(with DDR size reduced in advance as above)?

> diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h
> index cadaeef..5493c51 100644
> --- a/arch/powerpc/include/asm/mmu.h
> +++ b/arch/powerpc/include/asm/mmu.h
> @@ -509,6 +509,9 @@ extern void print_tlbcam(void);
>  extern unsigned int setup_ddr_tlbs(unsigned int memsize_in_meg);
>  extern void clear_ddr_tlbs(unsigned int memsize_in_meg);
>  
> +extern void tlb_map_range(ulong v_addr, phys_addr_t p_addr, uint64_t size,
> +			  bool is_ram);

bool arguments tend to be hard to read at call sites -- flags (or enum)
with something like MAP_RAM/MAP_IO would be nicer (I'm not insisting,
though).

-Scott
Alexander Graf Feb. 20, 2014, 10:25 a.m. UTC | #2
On 19.02.2014, at 00:21, Scott Wood <scottwood@freescale.com> wrote:

> On Tue, 2014-02-11 at 01:10 +0100, Alexander Graf wrote:
>> -	if (memsize)
>> -		print_size(memsize, " left unmapped\n");
>> +	if (size)
>> +		print_size(size, " left unmapped\n");
>> +}
> 
> The print_size should move to the caller, with some way to pass back the
> amout left unmapped.  Non-RAM callers would treat a non-zero unmapped
> value as an error.
> 
>> +unsigned int
>> +setup_ddr_tlbs_phys(phys_addr_t p_addr, unsigned int memsize_in_meg)
>> +{
>> +	unsigned int ram_tlb_address = (unsigned int)CONFIG_SYS_DDR_SDRAM_BASE;
>> +	u64 memsize = (u64)memsize_in_meg << 20;
>> +
>> +	memsize = min(memsize, CONFIG_MAX_MEM_MAPPED);
>> +	tlb_map_range(ram_tlb_address, p_addr, memsize, true);
>> 	return memsize_in_meg;
>> }
> 
> Here you seem to be hiding the message for RAM.

It could still fail if we're running out of TLB entries, no?

> York, are you OK with just removing the message altogether, and having
> tlb_map_range return a normal error code if it can't map everything
> (with DDR size reduced in advance as above)?

How about we just change the return value of tlb_map_range to uint64_t and return size? That way we can 1:1 move the print code out of the function into the RAM map code and IO callers can just call assert(r != 0).

> 
>> diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h
>> index cadaeef..5493c51 100644
>> --- a/arch/powerpc/include/asm/mmu.h
>> +++ b/arch/powerpc/include/asm/mmu.h
>> @@ -509,6 +509,9 @@ extern void print_tlbcam(void);
>> extern unsigned int setup_ddr_tlbs(unsigned int memsize_in_meg);
>> extern void clear_ddr_tlbs(unsigned int memsize_in_meg);
>> 
>> +extern void tlb_map_range(ulong v_addr, phys_addr_t p_addr, uint64_t size,
>> +			  bool is_ram);
> 
> bool arguments tend to be hard to read at call sites -- flags (or enum)
> with something like MAP_RAM/MAP_IO would be nicer (I'm not insisting,
> though).

Good point.


Alex
Scott Wood Feb. 20, 2014, 3:47 p.m. UTC | #3
On Thu, 2014-02-20 at 11:25 +0100, Alexander Graf wrote:
> On 19.02.2014, at 00:21, Scott Wood <scottwood@freescale.com> wrote:
> 
> > On Tue, 2014-02-11 at 01:10 +0100, Alexander Graf wrote:
> >> -	if (memsize)
> >> -		print_size(memsize, " left unmapped\n");
> >> +	if (size)
> >> +		print_size(size, " left unmapped\n");
> >> +}
> > 
> > The print_size should move to the caller, with some way to pass back the
> > amout left unmapped.  Non-RAM callers would treat a non-zero unmapped
> > value as an error.
> > 
> >> +unsigned int
> >> +setup_ddr_tlbs_phys(phys_addr_t p_addr, unsigned int memsize_in_meg)
> >> +{
> >> +	unsigned int ram_tlb_address = (unsigned int)CONFIG_SYS_DDR_SDRAM_BASE;
> >> +	u64 memsize = (u64)memsize_in_meg << 20;
> >> +
> >> +	memsize = min(memsize, CONFIG_MAX_MEM_MAPPED);
> >> +	tlb_map_range(ram_tlb_address, p_addr, memsize, true);
> >> 	return memsize_in_meg;
> >> }
> > 
> > Here you seem to be hiding the message for RAM.
> 
> It could still fail if we're running out of TLB entries, no?

That's not the usual reason for that message to be printed.

> > York, are you OK with just removing the message altogether, and having
> > tlb_map_range return a normal error code if it can't map everything
> > (with DDR size reduced in advance as above)?
> 
> How about we just change the return value of tlb_map_range to uint64_t
> and return size? That way we can 1:1 move the print code out of the
> function into the RAM map code and IO callers can just call assert(r !=
> 0).

That's fine.  I was just wondering if the message had value at all,
given that it's expected if you have more than 2 GiB of RAM.
 
-Scott
diff mbox

Patch

diff --git a/arch/powerpc/cpu/mpc85xx/tlb.c b/arch/powerpc/cpu/mpc85xx/tlb.c
index 8748ecd..2011fb8 100644
--- a/arch/powerpc/cpu/mpc85xx/tlb.c
+++ b/arch/powerpc/cpu/mpc85xx/tlb.c
@@ -236,20 +236,26 @@  void init_addr_map(void)
 }
 #endif
 
-unsigned int
-setup_ddr_tlbs_phys(phys_addr_t p_addr, unsigned int memsize_in_meg)
+void
+tlb_map_range(ulong v_addr, phys_addr_t p_addr, uint64_t size, bool is_ram)
 {
 	int i;
 	unsigned int tlb_size;
-	unsigned int wimge = MAS2_M;
-	unsigned int ram_tlb_address = (unsigned int)CONFIG_SYS_DDR_SDRAM_BASE;
+	unsigned int wimge;
+	unsigned int perm;
 	unsigned int max_cam, tsize_mask;
-	u64 size, memsize = (u64)memsize_in_meg << 20;
 
+	if (is_ram) {
+		perm = MAS3_SX|MAS3_SW|MAS3_SR;
+		wimge = MAS2_M;
 #ifdef CONFIG_SYS_PPC_DDR_WIMGE
-	wimge = CONFIG_SYS_PPC_DDR_WIMGE;
+		wimge = CONFIG_SYS_PPC_DDR_WIMGE;
 #endif
-	size = min(memsize, CONFIG_MAX_MEM_MAPPED);
+	} else {
+		perm = MAS3_SW|MAS3_SR;
+		wimge = MAS2_I|MAS2_G;
+	}
+
 	if ((mfspr(SPRN_MMUCFG) & MMUCFG_MAVN) == MMUCFG_MAVN_V1) {
 		/* Convert (4^max) kB to (2^max) bytes */
 		max_cam = ((mfspr(SPRN_TLB1CFG) >> 16) & 0xf) * 2 + 10;
@@ -261,11 +267,11 @@  setup_ddr_tlbs_phys(phys_addr_t p_addr, unsigned int memsize_in_meg)
 	}
 
 	for (i = 0; size && i < 8; i++) {
-		int ram_tlb_index = find_free_tlbcam();
+		int tlb_index = find_free_tlbcam();
 		u32 camsize = __ilog2_u64(size) & tsize_mask;
-		u32 align = __ilog2(ram_tlb_address) & tsize_mask;
+		u32 align = __ilog2(v_addr) & tsize_mask;
 
-		if (ram_tlb_index == -1)
+		if (tlb_index == -1)
 			break;
 
 		if (align == -2) align = max_cam;
@@ -277,18 +283,26 @@  setup_ddr_tlbs_phys(phys_addr_t p_addr, unsigned int memsize_in_meg)
 
 		tlb_size = camsize - 10;
 
-		set_tlb(1, ram_tlb_address, p_addr,
-			MAS3_SX|MAS3_SW|MAS3_SR, wimge,
-			0, ram_tlb_index, tlb_size, 1);
+		set_tlb(1, v_addr, p_addr, perm, wimge,
+			0, tlb_index, tlb_size, 1);
 
 		size -= 1ULL << camsize;
-		memsize -= 1ULL << camsize;
-		ram_tlb_address += 1UL << camsize;
+		v_addr += 1UL << camsize;
 		p_addr += 1UL << camsize;
 	}
 
-	if (memsize)
-		print_size(memsize, " left unmapped\n");
+	if (size)
+		print_size(size, " left unmapped\n");
+}
+
+unsigned int
+setup_ddr_tlbs_phys(phys_addr_t p_addr, unsigned int memsize_in_meg)
+{
+	unsigned int ram_tlb_address = (unsigned int)CONFIG_SYS_DDR_SDRAM_BASE;
+	u64 memsize = (u64)memsize_in_meg << 20;
+
+	memsize = min(memsize, CONFIG_MAX_MEM_MAPPED);
+	tlb_map_range(ram_tlb_address, p_addr, memsize, true);
 	return memsize_in_meg;
 }
 
diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h
index cadaeef..5493c51 100644
--- a/arch/powerpc/include/asm/mmu.h
+++ b/arch/powerpc/include/asm/mmu.h
@@ -509,6 +509,9 @@  extern void print_tlbcam(void);
 extern unsigned int setup_ddr_tlbs(unsigned int memsize_in_meg);
 extern void clear_ddr_tlbs(unsigned int memsize_in_meg);
 
+extern void tlb_map_range(ulong v_addr, phys_addr_t p_addr, uint64_t size,
+			  bool is_ram);
+
 extern void write_tlb(u32 _mas0, u32 _mas1, u32 _mas2, u32 _mas3, u32 _mas7);
 
 #define SET_TLB_ENTRY(_tlb, _epn, _rpn, _perms, _wimge, _ts, _esel, _sz, _iprot) \