Skip to content

Commit

Permalink
powerpc/mm/32s: rework mmu_mapin_ram()
Browse files Browse the repository at this point in the history
This patch reworks mmu_mapin_ram() to be more generic and map as much
blocks as possible. It now supports blocks not starting at address 0.

It scans DBATs array to find free ones instead of forcing the use of
BAT2 and BAT3.

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
  • Loading branch information
Christophe Leroy authored and Michael Ellerman committed Feb 23, 2019
1 parent 14e609d commit e4d6654
Showing 1 changed file with 41 additions and 22 deletions.
63 changes: 41 additions & 22 deletions arch/powerpc/mm/ppc_mmu_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,39 +73,58 @@ unsigned long p_block_mapped(phys_addr_t pa)
return 0;
}

static int find_free_bat(void)
{
int b;

if (cpu_has_feature(CPU_FTR_601)) {
for (b = 0; b < 4; b++) {
struct ppc_bat *bat = BATS[b];

if (!(bat[0].batl & 0x40))
return b;
}
} else {
int n = mmu_has_feature(MMU_FTR_USE_HIGH_BATS) ? 8 : 4;

for (b = 0; b < n; b++) {
struct ppc_bat *bat = BATS[b];

if (!(bat[1].batu & 3))
return b;
}
}
return -1;
}

static unsigned int block_size(unsigned long base, unsigned long top)
{
unsigned int max_size = (cpu_has_feature(CPU_FTR_601) ? 8 : 256) << 20;
unsigned int base_shift = (fls(base) - 1) & 31;
unsigned int block_shift = (fls(top - base) - 1) & 31;

return min3(max_size, 1U << base_shift, 1U << block_shift);
}

unsigned long __init mmu_mapin_ram(unsigned long base, unsigned long top)
{
unsigned long tot, bl, done;
unsigned long max_size = (256<<20);
int idx;

if (__map_without_bats) {
printk(KERN_DEBUG "RAM mapped without BATs\n");
return 0;
return base;
}

/* Set up BAT2 and if necessary BAT3 to cover RAM. */
while ((idx = find_free_bat()) != -1 && base != top) {
unsigned int size = block_size(base, top);

/* Make sure we don't map a block larger than the
smallest alignment of the physical address. */
tot = top;
for (bl = 128<<10; bl < max_size; bl <<= 1) {
if (bl * 2 > tot)
if (size < 128 << 10)
break;
setbat(idx, PAGE_OFFSET + base, base, size, PAGE_KERNEL_X);
base += size;
}

setbat(2, PAGE_OFFSET, 0, bl, PAGE_KERNEL_X);
done = (unsigned long)bat_addrs[2].limit - PAGE_OFFSET + 1;
if ((done < tot) && !bat_addrs[3].limit) {
/* use BAT3 to cover a bit more */
tot -= done;
for (bl = 128<<10; bl < max_size; bl <<= 1)
if (bl * 2 > tot)
break;
setbat(3, PAGE_OFFSET+done, done, bl, PAGE_KERNEL_X);
done = (unsigned long)bat_addrs[3].limit - PAGE_OFFSET + 1;
}

return done;
return base;
}

/*
Expand Down

0 comments on commit e4d6654

Please sign in to comment.