mirror of
https://github.com/AsahiLinux/m1n1
synced 2024-11-25 08:00:17 +00:00
exception,memory: s/EL2/EL1/
Since we're in VHE mode, we can pretend to be in EL1 - but this will allow us to really run in EL1 if we want to in the future. Signed-off-by: Hector Martin <marcan@marcan.st>
This commit is contained in:
parent
4282cd0578
commit
16cff51bd4
3 changed files with 29 additions and 29 deletions
|
@ -71,7 +71,7 @@ static char *ec_table[0x40] = {
|
|||
|
||||
void exception_initialize(void)
|
||||
{
|
||||
msr(VBAR_EL2, _vectors_start);
|
||||
msr(VBAR_EL1, _vectors_start);
|
||||
msr(DAIF, 0 << 6); // Enable SError, IRQ and FIQ
|
||||
}
|
||||
|
||||
|
@ -84,7 +84,7 @@ void print_regs(u64 *regs)
|
|||
{
|
||||
u64 sp = ((u64)(regs)) + 256;
|
||||
|
||||
const char *m_desc = m_table[mrs(SPSR_EL2) & 0xf];
|
||||
const char *m_desc = m_table[mrs(SPSR_EL1) & 0xf];
|
||||
printf("Exception taken from %s\n", m_desc ? m_desc : "?");
|
||||
|
||||
printf("Running in EL%d\n", mrs(CurrentEL) >> 2);
|
||||
|
@ -99,15 +99,15 @@ void print_regs(u64 *regs)
|
|||
printf("x24-x27: %016lx %016lx %016lx %016lx\n", regs[24], regs[25], regs[26], regs[27]);
|
||||
printf("x28-x30: %016lx %016lx %016lx\n", regs[28], regs[29], regs[30]);
|
||||
|
||||
u64 elr = mrs(elr_el2);
|
||||
u64 elr = mrs(elr_el1);
|
||||
|
||||
printf("PC: 0x%lx (rel: 0x%lx)\n", elr, elr - (u64)_base);
|
||||
printf("SP: 0x%lx\n", sp);
|
||||
printf("SPSR_EL2: 0x%lx\n", mrs(SPSR_EL2));
|
||||
printf("FAR_EL2: 0x%lx\n", mrs(FAR_EL2));
|
||||
printf("SPSR_EL1: 0x%lx\n", mrs(SPSR_EL1));
|
||||
printf("FAR_EL1: 0x%lx\n", mrs(FAR_EL1));
|
||||
|
||||
const char *ec_desc = ec_table[(mrs(ESR_EL2) >> 26) & 0x3f];
|
||||
printf("ESR_EL2: 0x%lx (%s)\n", mrs(ESR_EL2), ec_desc ? ec_desc : "?");
|
||||
const char *ec_desc = ec_table[(mrs(ESR_EL1) >> 26) & 0x3f];
|
||||
printf("ESR_EL1: 0x%lx (%s)\n", mrs(ESR_EL1), ec_desc ? ec_desc : "?");
|
||||
|
||||
u64 l2c_err_sts = mrs(SYS_APL_L2C_ERR_STS);
|
||||
|
||||
|
@ -133,14 +133,14 @@ void exc_sync(u64 *regs)
|
|||
u64 elr;
|
||||
u32 insn;
|
||||
|
||||
u64 spsr = mrs(SPSR_EL2);
|
||||
u64 esr = mrs(ESR_EL2);
|
||||
u64 spsr = mrs(SPSR_EL1);
|
||||
u64 esr = mrs(ESR_EL1);
|
||||
|
||||
if ((spsr & 0xf) == 0 && ((esr >> 26) & 0x3f) == 0x3c) {
|
||||
// On clean EL0 return, let the normal exception return
|
||||
// path take us back to the return thunk.
|
||||
msr(spsr_el2, 0x09); // EL2h
|
||||
msr(elr_el2, el0_ret);
|
||||
msr(SPSR_EL1, 0x09); // EL2h
|
||||
msr(ELR_EL1, el0_ret);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -155,13 +155,13 @@ void exc_sync(u64 *regs)
|
|||
|
||||
switch (exc_guard & GUARD_TYPE_MASK) {
|
||||
case GUARD_SKIP:
|
||||
elr = mrs(ELR_EL2) + 4;
|
||||
elr = mrs(ELR_EL1) + 4;
|
||||
break;
|
||||
case GUARD_MARK:
|
||||
// Assuming this is a load or store, dest reg is in low bits
|
||||
insn = read32(mrs(ELR_EL2));
|
||||
insn = read32(mrs(ELR_EL1));
|
||||
regs[insn & 0x1f] = 0xacce5515abad1dea;
|
||||
elr = mrs(ELR_EL2) + 4;
|
||||
elr = mrs(ELR_EL1) + 4;
|
||||
break;
|
||||
case GUARD_RETURN:
|
||||
regs[0] = 0xacce5515abad1dea;
|
||||
|
@ -177,7 +177,7 @@ void exc_sync(u64 *regs)
|
|||
|
||||
if (!(exc_guard & GUARD_SILENT))
|
||||
printf("Recovering from exception (ELR=0x%lx)\n", elr);
|
||||
msr(ELR_EL2, elr);
|
||||
msr(ELR_EL1, elr);
|
||||
|
||||
sysop("isb");
|
||||
sysop("dsb sy");
|
||||
|
|
|
@ -89,10 +89,10 @@ el0_call:
|
|||
|
||||
mrs x5, daif
|
||||
msr daifclr, 3
|
||||
msr spsr_el2, x5
|
||||
msr spsr_el1, x5
|
||||
|
||||
ldr x5, =_el0_thunk
|
||||
msr elr_el2, x5
|
||||
msr elr_el1, x5
|
||||
|
||||
ldr x5, =el0_stack_base
|
||||
ldr x5, [x5]
|
||||
|
|
24
src/memory.c
24
src/memory.c
|
@ -27,12 +27,12 @@ CACHE_RANGE_OP(dc_civac_range, "dc civac")
|
|||
static inline u64 read_sctlr(void)
|
||||
{
|
||||
sysop("isb");
|
||||
return mrs(SCTLR_EL2);
|
||||
return mrs(SCTLR_EL1);
|
||||
}
|
||||
|
||||
static inline void write_sctlr(u64 val)
|
||||
{
|
||||
msr(SCTLR_EL2, val);
|
||||
msr(SCTLR_EL1, val);
|
||||
sysop("isb");
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ static inline void write_sctlr(u64 val)
|
|||
#define PERM_RWX 0
|
||||
|
||||
/*
|
||||
* https://developer.arm.com/docs/ddi0595/g/aarch64-system-registers/sctlr_el2
|
||||
* https://developer.arm.com/docs/ddi0595/g/aarch64-system-registers/sctlr_el1
|
||||
* SCTLR_SPAN disables PAN getting enabled on exceptions.
|
||||
* SCTLR_I enables instruction caches.
|
||||
* SCTLR_C enables data caches.
|
||||
|
@ -73,7 +73,7 @@ static inline void write_sctlr(u64 val)
|
|||
#define SCTLR_M BIT(0)
|
||||
|
||||
/*
|
||||
* https://developer.arm.com/docs/ddi0595/h/aarch64-system-registers/tcr_el2
|
||||
* https://developer.arm.com/docs/ddi0595/h/aarch64-system-registers/tcr_el1
|
||||
* TCR_IPS_1TB selects 40 bits/1TB intermediate physical address size
|
||||
* TCR_PS_1TB selects 40 bits/1TB physical address size
|
||||
* TCR_TG0_16K selects 16K pages
|
||||
|
@ -293,7 +293,7 @@ static void mmu_add_default_mappings(void)
|
|||
|
||||
/*
|
||||
* create identity mapping for 16GB RAM from 0x88_0000_0000 to
|
||||
* 0x8c_0000_0000, writable by EL0 (but not executable by EL2)
|
||||
* 0x8c_0000_0000, writable by EL0 (but not executable by EL1)
|
||||
*/
|
||||
mmu_add_mapping(0x8800000000, 0x0800000000, 0x0400000000, MAIR_IDX_NORMAL, PERM_RWX_EL0);
|
||||
|
||||
|
@ -306,14 +306,14 @@ static void mmu_add_default_mappings(void)
|
|||
|
||||
static void mmu_configure(void)
|
||||
{
|
||||
msr(MAIR_EL2, (MAIR_ATTR_NORMAL_DEFAULT << MAIR_SHIFT_NORMAL) |
|
||||
msr(MAIR_EL1, (MAIR_ATTR_NORMAL_DEFAULT << MAIR_SHIFT_NORMAL) |
|
||||
(MAIR_ATTR_DEVICE_nGnRnE << MAIR_SHIFT_DEVICE_nGnRnE) |
|
||||
(MAIR_ATTR_DEVICE_nGnRE << MAIR_SHIFT_DEVICE_nGnRE));
|
||||
msr(TCR_EL2, TCR_IPS_1TB | TCR_TG1_16K | TCR_SH1_IS | TCR_ORGN1_WBWA | TCR_IRGN1_WBWA |
|
||||
msr(TCR_EL1, TCR_IPS_1TB | TCR_TG1_16K | TCR_SH1_IS | TCR_ORGN1_WBWA | TCR_IRGN1_WBWA |
|
||||
TCR_T1SZ_48BIT | TCR_TG0_16K | TCR_SH0_IS | TCR_ORGN0_WBWA | TCR_IRGN0_WBWA |
|
||||
TCR_T0SZ_48BIT);
|
||||
msr(TTBR0_EL2, (uintptr_t)pagetable_L0);
|
||||
msr(TTBR1_EL2, (uintptr_t)pagetable_L0);
|
||||
msr(TTBR0_EL1, (uintptr_t)pagetable_L0);
|
||||
msr(TTBR1_EL1, (uintptr_t)pagetable_L0);
|
||||
|
||||
// Armv8-A Address Translation, 100940_0101_en, page 28
|
||||
sysop("dsb ishst");
|
||||
|
@ -330,13 +330,13 @@ void mmu_init(void)
|
|||
mmu_add_default_mappings();
|
||||
mmu_configure();
|
||||
|
||||
// Enable EL0 memory access by EL2
|
||||
msr(pan, 0);
|
||||
// Enable EL0 memory access by EL1
|
||||
msr(PAN, 0);
|
||||
|
||||
u64 sctlr_old = read_sctlr();
|
||||
u64 sctlr_new = sctlr_old | SCTLR_I | SCTLR_C | SCTLR_M | SCTLR_SPAN;
|
||||
|
||||
printf("MMU: SCTLR_EL2: %x -> %x\n", sctlr_old, sctlr_new);
|
||||
printf("MMU: SCTLR_EL1: %x -> %x\n", sctlr_old, sctlr_new);
|
||||
write_sctlr(sctlr_new);
|
||||
printf("MMU: running with MMU and caches enabled!\n");
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue