mirror of https://gitee.com/openkylin/linux.git
powerpc/mm/32s: rework mmu_mapin_ram()
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>
This commit is contained in:
parent
14e609d693
commit
e4d6654ebe
|
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue