Message ID | 1392077408-16551-5-git-send-email-agraf@suse.de |
---|---|
State | Superseded |
Delegated to: | York Sun |
Headers | show |
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
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
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 --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) \
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(-)