diff options
author | Christophe Leroy <christophe.leroy@c-s.fr> | 2019-02-21 19:08:48 +0000 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2019-02-23 21:04:32 +1100 |
commit | 5e04ae85fbed8eef209a40a63f8ef507fe623064 (patch) | |
tree | b1a608bb1f8199d8f4e6be6e5d2c60562f363806 /arch/powerpc/mm/ppc_mmu_32.c | |
parent | 166d97d961588d2e52037e96da18d2ead455cec1 (diff) | |
download | lwn-5e04ae85fbed8eef209a40a63f8ef507fe623064.tar.gz lwn-5e04ae85fbed8eef209a40a63f8ef507fe623064.zip |
powerpc/mm/32s: add setibat() clearibat() and update_bats()
setibat() and clearibat() allows to manipulate IBATs independently
of DBATs.
update_bats() allows to update bats after init. This is done
with MMU off.
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc/mm/ppc_mmu_32.c')
-rw-r--r-- | arch/powerpc/mm/ppc_mmu_32.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/arch/powerpc/mm/ppc_mmu_32.c b/arch/powerpc/mm/ppc_mmu_32.c index 9225da8bae4c..7b011280d076 100644 --- a/arch/powerpc/mm/ppc_mmu_32.c +++ b/arch/powerpc/mm/ppc_mmu_32.c @@ -106,6 +106,38 @@ static unsigned int block_size(unsigned long base, unsigned long top) return min3(max_size, 1U << base_shift, 1U << block_shift); } +/* + * Set up one of the IBAT (block address translation) register pairs. + * The parameters are not checked; in particular size must be a power + * of 2 between 128k and 256M. + * Only for 603+ ... + */ +static void setibat(int index, unsigned long virt, phys_addr_t phys, + unsigned int size, pgprot_t prot) +{ + unsigned int bl = (size >> 17) - 1; + int wimgxpp; + struct ppc_bat *bat = BATS[index]; + unsigned long flags = pgprot_val(prot); + + if (!cpu_has_feature(CPU_FTR_NEED_COHERENT)) + flags &= ~_PAGE_COHERENT; + + wimgxpp = (flags & _PAGE_COHERENT) | (_PAGE_EXEC ? BPP_RX : BPP_XX); + bat[0].batu = virt | (bl << 2) | 2; /* Vs=1, Vp=0 */ + bat[0].batl = BAT_PHYS_ADDR(phys) | wimgxpp; + if (flags & _PAGE_USER) + bat[0].batu |= 1; /* Vp = 1 */ +} + +static void clearibat(int index) +{ + struct ppc_bat *bat = BATS[index]; + + bat[0].batu = 0; + bat[0].batl = 0; +} + unsigned long __init mmu_mapin_ram(unsigned long base, unsigned long top) { int idx; |