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>
This commit is contained in:
committed by
Michael Ellerman
parent
166d97d961
commit
5e04ae85fb
@ -92,6 +92,8 @@ typedef struct {
|
|||||||
unsigned long vdso_base;
|
unsigned long vdso_base;
|
||||||
} mm_context_t;
|
} mm_context_t;
|
||||||
|
|
||||||
|
void update_bats(void);
|
||||||
|
|
||||||
/* patch sites */
|
/* patch sites */
|
||||||
extern s32 patch__hash_page_A0, patch__hash_page_A1, patch__hash_page_A2;
|
extern s32 patch__hash_page_A0, patch__hash_page_A1, patch__hash_page_A2;
|
||||||
extern s32 patch__hash_page_B, patch__hash_page_C;
|
extern s32 patch__hash_page_B, patch__hash_page_C;
|
||||||
|
@ -1096,6 +1096,41 @@ BEGIN_MMU_FTR_SECTION
|
|||||||
END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
|
END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
|
||||||
blr
|
blr
|
||||||
|
|
||||||
|
_ENTRY(update_bats)
|
||||||
|
lis r4, 1f@h
|
||||||
|
ori r4, r4, 1f@l
|
||||||
|
tophys(r4, r4)
|
||||||
|
mfmsr r6
|
||||||
|
mflr r7
|
||||||
|
li r3, MSR_KERNEL & ~(MSR_IR | MSR_DR)
|
||||||
|
rlwinm r0, r6, 0, ~MSR_RI
|
||||||
|
rlwinm r0, r0, 0, ~MSR_EE
|
||||||
|
mtmsr r0
|
||||||
|
mtspr SPRN_SRR0, r4
|
||||||
|
mtspr SPRN_SRR1, r3
|
||||||
|
SYNC
|
||||||
|
RFI
|
||||||
|
1: bl clear_bats
|
||||||
|
lis r3, BATS@ha
|
||||||
|
addi r3, r3, BATS@l
|
||||||
|
tophys(r3, r3)
|
||||||
|
LOAD_BAT(0, r3, r4, r5)
|
||||||
|
LOAD_BAT(1, r3, r4, r5)
|
||||||
|
LOAD_BAT(2, r3, r4, r5)
|
||||||
|
LOAD_BAT(3, r3, r4, r5)
|
||||||
|
BEGIN_MMU_FTR_SECTION
|
||||||
|
LOAD_BAT(4, r3, r4, r5)
|
||||||
|
LOAD_BAT(5, r3, r4, r5)
|
||||||
|
LOAD_BAT(6, r3, r4, r5)
|
||||||
|
LOAD_BAT(7, r3, r4, r5)
|
||||||
|
END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
|
||||||
|
li r3, MSR_KERNEL & ~(MSR_IR | MSR_DR | MSR_RI)
|
||||||
|
mtmsr r3
|
||||||
|
mtspr SPRN_SRR0, r7
|
||||||
|
mtspr SPRN_SRR1, r6
|
||||||
|
SYNC
|
||||||
|
RFI
|
||||||
|
|
||||||
flush_tlbs:
|
flush_tlbs:
|
||||||
lis r10, 0x40
|
lis r10, 0x40
|
||||||
1: addic. r10, r10, -0x1000
|
1: addic. r10, r10, -0x1000
|
||||||
|
@ -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);
|
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)
|
unsigned long __init mmu_mapin_ram(unsigned long base, unsigned long top)
|
||||||
{
|
{
|
||||||
int idx;
|
int idx;
|
||||||
|
Reference in New Issue
Block a user