mirror of
https://github.com/AsahiLinux/m1n1
synced 2024-11-21 22:23:05 +00:00
gxf: add support for guarded exception levels
Signed-off-by: Sven Peter <sven@svenpeter.dev>
This commit is contained in:
parent
2c5b202c99
commit
1c604a77c5
11 changed files with 472 additions and 10 deletions
1
Makefile
1
Makefile
|
@ -42,6 +42,7 @@ OBJECTS := \
|
||||||
dart.o \
|
dart.o \
|
||||||
exception.o exception_asm.o \
|
exception.o exception_asm.o \
|
||||||
fb.o font.o font_retina.o \
|
fb.o font.o font_retina.o \
|
||||||
|
gxf.o gxf_asm.o \
|
||||||
heapblock.o \
|
heapblock.o \
|
||||||
hv.o hv_vm.o hv_exc.o hv_vuart.o hv_asm.o \
|
hv.o hv_vm.o hv_exc.o hv_vuart.o hv_asm.o \
|
||||||
iodev.o \
|
iodev.o \
|
||||||
|
|
|
@ -398,6 +398,8 @@ class M1N1Proxy:
|
||||||
P_EL0_CALL = 0x009
|
P_EL0_CALL = 0x009
|
||||||
P_EL1_CALL = 0x00a
|
P_EL1_CALL = 0x00a
|
||||||
P_VECTOR = 0x00b
|
P_VECTOR = 0x00b
|
||||||
|
P_GL1_CALL = 0x00c
|
||||||
|
P_GL2_CALL = 0x00d
|
||||||
|
|
||||||
P_WRITE64 = 0x100
|
P_WRITE64 = 0x100
|
||||||
P_WRITE32 = 0x101
|
P_WRITE32 = 0x101
|
||||||
|
@ -602,6 +604,14 @@ class M1N1Proxy:
|
||||||
if len(args) > 4:
|
if len(args) > 4:
|
||||||
raise ValueError("Too many arguments")
|
raise ValueError("Too many arguments")
|
||||||
return self.request(self.P_EL1_CALL, addr, *args)
|
return self.request(self.P_EL1_CALL, addr, *args)
|
||||||
|
def gl1_call(self, addr, *args):
|
||||||
|
if len(args) > 4:
|
||||||
|
raise ValueError("Too many arguments")
|
||||||
|
return self.request(self.P_GL1_CALL, addr, *args)
|
||||||
|
def gl2_call(self, addr, *args):
|
||||||
|
if len(args) > 4:
|
||||||
|
raise ValueError("Too many arguments")
|
||||||
|
return self.request(self.P_GL2_CALL, addr, *args)
|
||||||
|
|
||||||
def write64(self, addr, data):
|
def write64(self, addr, data):
|
||||||
if addr & 7:
|
if addr & 7:
|
||||||
|
|
|
@ -123,3 +123,36 @@
|
||||||
|
|
||||||
#define SYS_IMP_APL_UPMSR sys_reg(3, 7, 15, 6, 4)
|
#define SYS_IMP_APL_UPMSR sys_reg(3, 7, 15, 6, 4)
|
||||||
#define UPMSR_IACT (BIT(0))
|
#define UPMSR_IACT (BIT(0))
|
||||||
|
|
||||||
|
/* SPRR and GXF registers */
|
||||||
|
#define SYS_IMP_APL_SPRR_CONFIG_EL1 sys_reg(3, 6, 15, 1, 0)
|
||||||
|
#define SPRR_CONFIG_EN BIT(0)
|
||||||
|
#define SPRR_CONFIG_LOCK_CONFIG BIT(1)
|
||||||
|
#define SPRR_CONFIG_LOCK_PERM_EL0 BIT(4)
|
||||||
|
#define SPRR_CONFIG_LOCK_PERM_EL1 BIT(5)
|
||||||
|
|
||||||
|
#define SYS_IMP_APL_GXF_CONFIG_EL1 sys_reg(3, 6, 15, 1, 2)
|
||||||
|
#define GXF_CONFIG_EN BIT(0)
|
||||||
|
|
||||||
|
#define SYS_IMP_APL_GXF_STATUS sys_reg(3, 6, 15, 8, 0)
|
||||||
|
#define GXF_STATUS_GUARDED BIT(0)
|
||||||
|
|
||||||
|
#define SYS_IMP_APL_GXF_ABORT_EL1 sys_reg(3, 6, 15, 8, 2)
|
||||||
|
#define SYS_IMP_APL_GXF_ENTER_EL1 sys_reg(3, 6, 15, 8, 1)
|
||||||
|
|
||||||
|
#define SYS_IMP_APL_GXF_ABORT_EL12 sys_reg(3, 6, 15, 15, 3)
|
||||||
|
#define SYS_IMP_APL_GXF_ENTER_EL12 sys_reg(3, 6, 15, 15, 2)
|
||||||
|
|
||||||
|
#define SYS_IMP_APL_SPRR_PERM_EL0 sys_reg(3, 6, 15, 1, 5)
|
||||||
|
#define SYS_IMP_APL_SPRR_PERM_EL1 sys_reg(3, 6, 15, 1, 6)
|
||||||
|
|
||||||
|
#define SYS_IMP_APL_TPIDR_GL1 sys_reg(3, 6, 15, 10, 1)
|
||||||
|
#define SYS_IMP_APL_VBAR_GL1 sys_reg(3, 6, 15, 10, 2)
|
||||||
|
#define SYS_IMP_APL_SPSR_GL1 sys_reg(3, 6, 15, 10, 3)
|
||||||
|
#define SYS_IMP_APL_ASPSR_GL1 sys_reg(3, 6, 15, 10, 4)
|
||||||
|
#define SYS_IMP_APL_ESR_GL1 sys_reg(3, 6, 15, 10, 5)
|
||||||
|
#define SYS_IMP_APL_ELR_GL1 sys_reg(3, 6, 15, 10, 6)
|
||||||
|
#define SYS_IMP_APL_FAR_GL1 sys_reg(3, 6, 15, 10, 7)
|
||||||
|
|
||||||
|
#define SYS_IMP_APL_VBAR_GL12 sys_reg(3, 6, 15, 9, 2)
|
||||||
|
#define SYS_IMP_APL_SP_GL12 sys_reg(3, 6, 15, 10, 0)
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "exception.h"
|
#include "exception.h"
|
||||||
#include "cpu_regs.h"
|
#include "cpu_regs.h"
|
||||||
|
#include "gxf.h"
|
||||||
#include "iodev.h"
|
#include "iodev.h"
|
||||||
#include "uart.h"
|
#include "uart.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
@ -28,6 +29,14 @@ static char *m_table[0x10] = {
|
||||||
[0x09] = "EL2h", //
|
[0x09] = "EL2h", //
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static char *gl_m_table[0x10] = {
|
||||||
|
[0x00] = "GL0t", //
|
||||||
|
[0x04] = "GL1t", //
|
||||||
|
[0x05] = "GL1h", //
|
||||||
|
[0x08] = "GL2t", //
|
||||||
|
[0x09] = "GL2h", //
|
||||||
|
};
|
||||||
|
|
||||||
static char *ec_table[0x40] = {
|
static char *ec_table[0x40] = {
|
||||||
[0x00] = "unknown",
|
[0x00] = "unknown",
|
||||||
[0x01] = "wf*",
|
[0x01] = "wf*",
|
||||||
|
@ -72,6 +81,42 @@ static char *ec_table[0x40] = {
|
||||||
[0x3c] = "brk (a64)",
|
[0x3c] = "brk (a64)",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char *get_exception_source(int el12)
|
||||||
|
{
|
||||||
|
u64 spsr = el12 ? mrs(SPSR_EL12) : mrs(SPSR_EL1);
|
||||||
|
u64 aspsr = in_gl12() ? mrs(SYS_IMP_APL_ASPSR_GL1) : 0;
|
||||||
|
const char *m_desc = NULL;
|
||||||
|
|
||||||
|
if (aspsr & 1)
|
||||||
|
m_desc = gl_m_table[spsr & 0xf];
|
||||||
|
else
|
||||||
|
m_desc = m_table[spsr & 0xf];
|
||||||
|
|
||||||
|
if (!m_desc)
|
||||||
|
m_desc = "?";
|
||||||
|
|
||||||
|
return m_desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *get_exception_level(void)
|
||||||
|
{
|
||||||
|
u64 lvl = mrs(CurrentEL);
|
||||||
|
|
||||||
|
if (in_gl12()) {
|
||||||
|
if (lvl == 0x04)
|
||||||
|
return "GL1";
|
||||||
|
else if (lvl == 0x08)
|
||||||
|
return "GL2";
|
||||||
|
} else {
|
||||||
|
if (lvl == 0x04)
|
||||||
|
return "EL1";
|
||||||
|
else if (lvl == 0x08)
|
||||||
|
return "EL2";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "?";
|
||||||
|
}
|
||||||
|
|
||||||
void exception_initialize(void)
|
void exception_initialize(void)
|
||||||
{
|
{
|
||||||
msr(VBAR_EL1, _vectors_start);
|
msr(VBAR_EL1, _vectors_start);
|
||||||
|
@ -106,10 +151,8 @@ void print_regs(u64 *regs, int el12)
|
||||||
|
|
||||||
u64 spsr = el12 ? mrs(SPSR_EL12) : mrs(SPSR_EL1);
|
u64 spsr = el12 ? mrs(SPSR_EL12) : mrs(SPSR_EL1);
|
||||||
|
|
||||||
const char *m_desc = m_table[spsr & 0xf];
|
printf("Exception taken from %s\n", get_exception_source(el12));
|
||||||
printf("Exception taken from %s\n", m_desc ? m_desc : "?");
|
printf("Running in %s\n", get_exception_level());
|
||||||
|
|
||||||
printf("Running in EL%lu\n", mrs(CurrentEL) >> 2);
|
|
||||||
printf("MPIDR: 0x%lx\n", mrs(MPIDR_EL1));
|
printf("MPIDR: 0x%lx\n", mrs(MPIDR_EL1));
|
||||||
printf("Registers: (@%p)\n", regs);
|
printf("Registers: (@%p)\n", regs);
|
||||||
printf(" x0-x3: %016lx %016lx %016lx %016lx\n", regs[0], regs[1], regs[2], regs[3]);
|
printf(" x0-x3: %016lx %016lx %016lx %016lx\n", regs[0], regs[1], regs[2], regs[3]);
|
||||||
|
@ -127,6 +170,9 @@ void print_regs(u64 *regs, int el12)
|
||||||
printf("PC: 0x%lx (rel: 0x%lx)\n", elr, elr - (u64)_base);
|
printf("PC: 0x%lx (rel: 0x%lx)\n", elr, elr - (u64)_base);
|
||||||
printf("SP: 0x%lx\n", sp);
|
printf("SP: 0x%lx\n", sp);
|
||||||
printf("SPSR_EL1: 0x%lx\n", spsr);
|
printf("SPSR_EL1: 0x%lx\n", spsr);
|
||||||
|
if (in_gl12()) {
|
||||||
|
printf("ASPSR: 0x%lx\n", mrs(SYS_IMP_APL_ASPSR_GL1));
|
||||||
|
}
|
||||||
printf("FAR_EL1: 0x%lx\n", el12 ? mrs(FAR_EL12) : mrs(FAR_EL1));
|
printf("FAR_EL1: 0x%lx\n", el12 ? mrs(FAR_EL12) : mrs(FAR_EL1));
|
||||||
|
|
||||||
const char *ec_desc = ec_table[(esr >> 26) & 0x3f];
|
const char *ec_desc = ec_table[(esr >> 26) & 0x3f];
|
||||||
|
@ -168,7 +214,7 @@ void exc_sync(u64 *regs)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_el2() && (spsr & 0xf) == 5 && ((esr >> 26) & 0x3f) == 0x16) {
|
if (in_el2() && !in_gl12() && (spsr & 0xf) == 5 && ((esr >> 26) & 0x3f) == 0x16) {
|
||||||
// Hypercall
|
// Hypercall
|
||||||
u32 imm = mrs(ESR_EL2) & 0xffff;
|
u32 imm = mrs(ESR_EL2) & 0xffff;
|
||||||
switch (imm) {
|
switch (imm) {
|
||||||
|
@ -241,7 +287,7 @@ void exc_irq(u64 *regs)
|
||||||
ufstat = read32(0x235200018);
|
ufstat = read32(0x235200018);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uart_puts("Exception: IRQ");
|
printf("Exception: IRQ (from %s)\n", get_exception_source(0));
|
||||||
|
|
||||||
u32 reason = read32(0x23b102004);
|
u32 reason = read32(0x23b102004);
|
||||||
|
|
||||||
|
@ -259,8 +305,7 @@ void exc_irq(u64 *regs)
|
||||||
|
|
||||||
void exc_fiq(u64 *regs)
|
void exc_fiq(u64 *regs)
|
||||||
{
|
{
|
||||||
const char *m_desc = m_table[mrs(SPSR_EL1) & 0xf];
|
printf("Exception: FIQ (from %s)\n", get_exception_source(0));
|
||||||
printf("Exception: FIQ (from %s)\n", m_desc ? m_desc : "?");
|
|
||||||
|
|
||||||
u64 reg = mrs(CNTP_CTL_EL0);
|
u64 reg = mrs(CNTP_CTL_EL0);
|
||||||
if (reg == 0x5) {
|
if (reg == 0x5) {
|
||||||
|
|
97
src/gxf.c
Normal file
97
src/gxf.c
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
/* SPDX-License-Identifier: MIT */
|
||||||
|
|
||||||
|
#include "cpu_regs.h"
|
||||||
|
#include "exception.h"
|
||||||
|
#include "gxf.h"
|
||||||
|
#include "memory.h"
|
||||||
|
#include "uart.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
#define GL_STACK_SIZE 0x4000
|
||||||
|
|
||||||
|
uint64_t gxf_enter(void *func, uint64_t a, uint64_t b, uint64_t c, uint64_t d);
|
||||||
|
|
||||||
|
u8 gl1_stack[GL_STACK_SIZE] ALIGNED(64);
|
||||||
|
void *gl1_stack_base = &gl1_stack[GL_STACK_SIZE];
|
||||||
|
|
||||||
|
u8 gl2_stack[GL_STACK_SIZE] ALIGNED(64);
|
||||||
|
void *gl2_stack_base = &gl2_stack[GL_STACK_SIZE];
|
||||||
|
|
||||||
|
bool in_gl12(void)
|
||||||
|
{
|
||||||
|
if (!(mrs(SYS_IMP_APL_SPRR_CONFIG_EL1) & SPRR_CONFIG_EN))
|
||||||
|
return false;
|
||||||
|
if (!(mrs(SYS_IMP_APL_GXF_CONFIG_EL1) & GXF_CONFIG_EN))
|
||||||
|
return false;
|
||||||
|
if (!(mrs(SYS_IMP_APL_GXF_STATUS) & GXF_STATUS_GUARDED))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint64_t gl_call(void *func, uint64_t a, uint64_t b, uint64_t c, uint64_t d)
|
||||||
|
{
|
||||||
|
// disable the MMU first since enabling SPRR will change the meaning of all
|
||||||
|
// pagetable permission bits and also prevent us from having rwx pages
|
||||||
|
u64 mmu_state = mmu_disable();
|
||||||
|
u64 sprr_state = mrs(SYS_IMP_APL_SPRR_CONFIG_EL1) & SPRR_CONFIG_EN;
|
||||||
|
reg_set_sync(SYS_IMP_APL_SPRR_CONFIG_EL1, SPRR_CONFIG_EN);
|
||||||
|
|
||||||
|
u64 gxf_state = mrs(SYS_IMP_APL_GXF_CONFIG_EL1) & GXF_CONFIG_EN;
|
||||||
|
reg_set_sync(SYS_IMP_APL_GXF_CONFIG_EL1, GXF_CONFIG_EN);
|
||||||
|
|
||||||
|
uint64_t ret = gxf_enter(func, a, b, c, d);
|
||||||
|
|
||||||
|
msr_sync(SYS_IMP_APL_GXF_CONFIG_EL1, gxf_state);
|
||||||
|
msr_sync(SYS_IMP_APL_SPRR_CONFIG_EL1, sprr_state);
|
||||||
|
mmu_restore(mmu_state);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t gl2_call(void *func, uint64_t a, uint64_t b, uint64_t c, uint64_t d)
|
||||||
|
{
|
||||||
|
if (mrs(CurrentEL) != 0x8)
|
||||||
|
return -1;
|
||||||
|
return gl_call(func, a, b, c, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct gl_call_argv {
|
||||||
|
void *func;
|
||||||
|
uint64_t a, b, c, d;
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint64_t gl_call_wrapper(struct gl_call_argv *args)
|
||||||
|
{
|
||||||
|
return gl_call(args->func, args->a, args->b, args->c, args->d);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t gl1_call(void *func, uint64_t a, uint64_t b, uint64_t c, uint64_t d)
|
||||||
|
{
|
||||||
|
if (mrs(CurrentEL) == 0x4)
|
||||||
|
return gl_call(func, a, b, c, d);
|
||||||
|
|
||||||
|
struct gl_call_argv args;
|
||||||
|
args.func = func;
|
||||||
|
args.a = a;
|
||||||
|
args.b = b;
|
||||||
|
args.c = c;
|
||||||
|
args.d = d;
|
||||||
|
|
||||||
|
// enable EL1 here since once GXF has been enabled HCR_EL2 writes are only possible from GL2
|
||||||
|
reg_clr(HCR_EL2, BIT(27));
|
||||||
|
|
||||||
|
u64 mmu_state = mmu_disable();
|
||||||
|
u64 sprr_state = mrs(SYS_IMP_APL_SPRR_CONFIG_EL1) & SPRR_CONFIG_EN;
|
||||||
|
reg_set_sync(SYS_IMP_APL_SPRR_CONFIG_EL1, SPRR_CONFIG_EN);
|
||||||
|
|
||||||
|
u64 gxf_state = mrs(SYS_IMP_APL_GXF_CONFIG_EL1) & GXF_CONFIG_EN;
|
||||||
|
reg_set_sync(SYS_IMP_APL_GXF_CONFIG_EL1, GXF_CONFIG_EN);
|
||||||
|
|
||||||
|
uint64_t ret = el1_call(gl_call_wrapper, (uint64_t)&args, 0, 0, 0);
|
||||||
|
|
||||||
|
msr_sync(SYS_IMP_APL_GXF_CONFIG_EL1, gxf_state);
|
||||||
|
msr_sync(SYS_IMP_APL_SPRR_CONFIG_EL1, sprr_state);
|
||||||
|
mmu_restore(mmu_state);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
14
src/gxf.h
Normal file
14
src/gxf.h
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
/* SPDX-License-Identifier: MIT */
|
||||||
|
|
||||||
|
#ifndef __GXF_H__
|
||||||
|
#define __GXF_H__
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
bool in_gl12(void);
|
||||||
|
void gxf_init(void);
|
||||||
|
|
||||||
|
uint64_t gl1_call(void *func, uint64_t a, uint64_t b, uint64_t c, uint64_t d);
|
||||||
|
uint64_t gl2_call(void *func, uint64_t a, uint64_t b, uint64_t c, uint64_t d);
|
||||||
|
|
||||||
|
#endif
|
238
src/gxf_asm.S
Normal file
238
src/gxf_asm.S
Normal file
|
@ -0,0 +1,238 @@
|
||||||
|
/* SPDX-License-Identifier: MIT */
|
||||||
|
|
||||||
|
#include "cpu_regs.h"
|
||||||
|
|
||||||
|
#define genter .long 0x00201420
|
||||||
|
#define gexit .long 0x00201400
|
||||||
|
|
||||||
|
.global gxf_init
|
||||||
|
.type gxf_init, @function
|
||||||
|
gxf_init:
|
||||||
|
str x30, [sp, #-16]!
|
||||||
|
mov x0, 1
|
||||||
|
msr SYS_IMP_APL_SPRR_CONFIG_EL1, x0
|
||||||
|
isb
|
||||||
|
msr SYS_IMP_APL_GXF_CONFIG_EL1, x0
|
||||||
|
isb
|
||||||
|
ldr x0, =_gxf_setup
|
||||||
|
msr SYS_IMP_APL_GXF_ENTER_EL1, x0
|
||||||
|
isb
|
||||||
|
genter
|
||||||
|
msr SYS_IMP_APL_GXF_CONFIG_EL1, xzr
|
||||||
|
isb
|
||||||
|
msr SYS_IMP_APL_SPRR_CONFIG_EL1, xzr
|
||||||
|
isb
|
||||||
|
ldr x30, [sp], #16
|
||||||
|
ret
|
||||||
|
|
||||||
|
.globl gxf_enter
|
||||||
|
.type gxf_enter, @function
|
||||||
|
gxf_enter:
|
||||||
|
genter
|
||||||
|
ret
|
||||||
|
|
||||||
|
_gxf_setup:
|
||||||
|
ldr x0, =gl2_stack_base
|
||||||
|
ldr x0, [x0]
|
||||||
|
mov sp, x0
|
||||||
|
ldr x1, =_gxf_vectors
|
||||||
|
ldr x2, =_gxf_exc_sync
|
||||||
|
ldr x3, =_gxf_entry
|
||||||
|
msr SYS_IMP_APL_VBAR_GL1, x1
|
||||||
|
msr SYS_IMP_APL_GXF_ABORT_EL1, x2
|
||||||
|
msr SYS_IMP_APL_GXF_ENTER_EL1, x3
|
||||||
|
|
||||||
|
mrs x4, CurrentEL
|
||||||
|
cmp x4, #8
|
||||||
|
bne 1f
|
||||||
|
|
||||||
|
ldr x0, =gl1_stack_base
|
||||||
|
ldr x0, [x0]
|
||||||
|
msr SYS_IMP_APL_SP_GL12, x0
|
||||||
|
msr SYS_IMP_APL_VBAR_GL12, x1
|
||||||
|
msr SYS_IMP_APL_GXF_ABORT_EL12, x2
|
||||||
|
msr SYS_IMP_APL_GXF_ENTER_EL12, x3
|
||||||
|
|
||||||
|
1:
|
||||||
|
isb
|
||||||
|
gexit
|
||||||
|
|
||||||
|
_gxf_entry:
|
||||||
|
stp x29, x30, [sp, #-16]!
|
||||||
|
stp x23, x24, [sp, #-16]!
|
||||||
|
stp x21, x22, [sp, #-16]!
|
||||||
|
stp x19, x20, [sp, #-16]!
|
||||||
|
|
||||||
|
// these registers would be overwritten by each exception happening in GL1/2
|
||||||
|
// but we need them to gexit correctly again
|
||||||
|
mrs x20, SYS_IMP_APL_SPSR_GL1
|
||||||
|
mrs x21, SYS_IMP_APL_ASPSR_GL1
|
||||||
|
mrs x22, SYS_IMP_APL_ESR_GL1
|
||||||
|
mrs x23, SYS_IMP_APL_ELR_GL1
|
||||||
|
mrs x24, SYS_IMP_APL_FAR_GL1
|
||||||
|
|
||||||
|
mov x5, x0
|
||||||
|
mov x0, x1
|
||||||
|
mov x1, x2
|
||||||
|
mov x2, x3
|
||||||
|
mov x3, x4
|
||||||
|
|
||||||
|
blr x5
|
||||||
|
|
||||||
|
msr SYS_IMP_APL_SPSR_GL1, x20
|
||||||
|
msr SYS_IMP_APL_ASPSR_GL1, x21
|
||||||
|
msr SYS_IMP_APL_ESR_GL1, x22
|
||||||
|
msr SYS_IMP_APL_ELR_GL1, x23
|
||||||
|
msr SYS_IMP_APL_FAR_GL1, x24
|
||||||
|
|
||||||
|
ldp x19, x20, [sp], #16
|
||||||
|
ldp x21, x22, [sp], #16
|
||||||
|
ldp x23, x24, [sp], #16
|
||||||
|
ldp x29, x30, [sp], #16
|
||||||
|
|
||||||
|
isb
|
||||||
|
gexit
|
||||||
|
|
||||||
|
.align 11
|
||||||
|
_gxf_vectors:
|
||||||
|
mov x9, '0'
|
||||||
|
b _gxf_exc_unk
|
||||||
|
.align 7
|
||||||
|
mov x9, '1'
|
||||||
|
b _gxf_exc_unk
|
||||||
|
.align 7
|
||||||
|
mov x9, '2'
|
||||||
|
b _gxf_exc_unk
|
||||||
|
.align 7
|
||||||
|
mov x9, '3'
|
||||||
|
b _gxf_exc_unk
|
||||||
|
.align 7
|
||||||
|
b _gxf_exc_sync
|
||||||
|
.align 7
|
||||||
|
mov x9, '5'
|
||||||
|
b _gxf_exc_unk
|
||||||
|
.align 7
|
||||||
|
mov x9, '6'
|
||||||
|
b _gxf_exc_unk
|
||||||
|
.align 7
|
||||||
|
b _gxf_serr
|
||||||
|
.align 7
|
||||||
|
b _gxf_exc_sync
|
||||||
|
.align 7
|
||||||
|
mov x9, '9'
|
||||||
|
b _gxf_exc_unk
|
||||||
|
.align 7
|
||||||
|
mov x9, 'a'
|
||||||
|
b _gxf_exc_unk
|
||||||
|
.align 7
|
||||||
|
b _gxf_serr
|
||||||
|
.align 7
|
||||||
|
mov x9, 'c'
|
||||||
|
b _gxf_exc_unk
|
||||||
|
.align 7
|
||||||
|
mov x9, 'd'
|
||||||
|
b _gxf_exc_unk
|
||||||
|
.align 7
|
||||||
|
mov x9, 'e'
|
||||||
|
b _gxf_exc_unk
|
||||||
|
.align 7
|
||||||
|
mov x9, 'f'
|
||||||
|
b _gxf_exc_unk
|
||||||
|
.align 7
|
||||||
|
|
||||||
|
_gxf_exc_sync:
|
||||||
|
str x30, [sp, #-16]!
|
||||||
|
bl _gxf_exc_entry
|
||||||
|
bl exc_sync
|
||||||
|
b _gxf_exc_return
|
||||||
|
|
||||||
|
_gxf_serr:
|
||||||
|
str x30, [sp, #-16]!
|
||||||
|
bl _gxf_exc_entry
|
||||||
|
bl exc_serr
|
||||||
|
b _gxf_exc_return
|
||||||
|
|
||||||
|
_gxf_exc_entry:
|
||||||
|
stp x28, x29, [sp, #-16]!
|
||||||
|
stp x26, x27, [sp, #-16]!
|
||||||
|
stp x24, x25, [sp, #-16]!
|
||||||
|
stp x22, x23, [sp, #-16]!
|
||||||
|
stp x20, x21, [sp, #-16]!
|
||||||
|
stp x18, x19, [sp, #-16]!
|
||||||
|
stp x16, x17, [sp, #-16]!
|
||||||
|
stp x14, x15, [sp, #-16]!
|
||||||
|
stp x12, x13, [sp, #-16]!
|
||||||
|
stp x10, x11, [sp, #-16]!
|
||||||
|
stp x8, x9, [sp, #-16]!
|
||||||
|
stp x6, x7, [sp, #-16]!
|
||||||
|
stp x4, x5, [sp, #-16]!
|
||||||
|
stp x2, x3, [sp, #-16]!
|
||||||
|
stp x0, x1, [sp, #-16]!
|
||||||
|
|
||||||
|
mov x0, sp
|
||||||
|
|
||||||
|
mrs x1, SYS_IMP_APL_SPSR_GL1
|
||||||
|
msr SPSR_EL1, x1
|
||||||
|
mrs x1, SYS_IMP_APL_ELR_GL1
|
||||||
|
msr ELR_EL1, x1
|
||||||
|
mrs x1, SYS_IMP_APL_ESR_GL1
|
||||||
|
msr ESR_EL1, x1
|
||||||
|
mrs x1, SYS_IMP_APL_FAR_GL1
|
||||||
|
msr FAR_EL1, x1
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
_gxf_exc_return:
|
||||||
|
mrs x0, SPSR_EL1
|
||||||
|
msr SYS_IMP_APL_SPSR_GL1, x0
|
||||||
|
mrs x0, ELR_EL1
|
||||||
|
msr SYS_IMP_APL_ELR_GL1, x0
|
||||||
|
|
||||||
|
ldp x0, x1, [sp], #16
|
||||||
|
ldp x2, x3, [sp], #16
|
||||||
|
ldp x4, x5, [sp], #16
|
||||||
|
ldp x6, x7, [sp], #16
|
||||||
|
ldp x8, x9, [sp], #16
|
||||||
|
ldp x10, x11, [sp], #16
|
||||||
|
ldp x12, x13, [sp], #16
|
||||||
|
ldp x14, x15, [sp], #16
|
||||||
|
ldp x16, x17, [sp], #16
|
||||||
|
ldp x18, x19, [sp], #16
|
||||||
|
ldp x20, x21, [sp], #16
|
||||||
|
ldp x22, x23, [sp], #16
|
||||||
|
ldp x24, x25, [sp], #16
|
||||||
|
ldp x26, x27, [sp], #16
|
||||||
|
ldp x28, x29, [sp], #16
|
||||||
|
ldr x30, [sp], #16
|
||||||
|
isb
|
||||||
|
|
||||||
|
gexit
|
||||||
|
|
||||||
|
_gxf_exc_unk:
|
||||||
|
mov w0, 0xd /* '\r', clang compat */
|
||||||
|
bl debug_putc
|
||||||
|
mov w0, '\n'
|
||||||
|
bl debug_putc
|
||||||
|
mov w0, '!'
|
||||||
|
bl debug_putc
|
||||||
|
mov w0, 'G'
|
||||||
|
bl debug_putc
|
||||||
|
mov w0, 'L'
|
||||||
|
bl debug_putc
|
||||||
|
mov w0, 'E'
|
||||||
|
bl debug_putc
|
||||||
|
mov w0, 'X'
|
||||||
|
bl debug_putc
|
||||||
|
mov w0, 'C'
|
||||||
|
bl debug_putc
|
||||||
|
mov w0, ':'
|
||||||
|
bl debug_putc
|
||||||
|
mov w0, w9
|
||||||
|
bl debug_putc
|
||||||
|
mov w0, '!'
|
||||||
|
bl debug_putc
|
||||||
|
mov w0, 0xd /* '\r', clang compat */
|
||||||
|
bl debug_putc
|
||||||
|
mov w0, '\n'
|
||||||
|
bl debug_putc
|
||||||
|
b reboot
|
|
@ -4,6 +4,7 @@
|
||||||
#include "dart.h"
|
#include "dart.h"
|
||||||
#include "exception.h"
|
#include "exception.h"
|
||||||
#include "fb.h"
|
#include "fb.h"
|
||||||
|
#include "gxf.h"
|
||||||
#include "heapblock.h"
|
#include "heapblock.h"
|
||||||
#include "hv.h"
|
#include "hv.h"
|
||||||
#include "iodev.h"
|
#include "iodev.h"
|
||||||
|
@ -80,6 +81,14 @@ int proxy_process(ProxyRequest *request, ProxyReply *reply)
|
||||||
reply->retval = el1_call((void *)request->args[0], request->args[1], request->args[2],
|
reply->retval = el1_call((void *)request->args[0], request->args[1], request->args[2],
|
||||||
request->args[3], request->args[4]);
|
request->args[3], request->args[4]);
|
||||||
break;
|
break;
|
||||||
|
case P_GL1_CALL:
|
||||||
|
reply->retval = gl1_call((void *)request->args[0], request->args[1], request->args[2],
|
||||||
|
request->args[3], request->args[4]);
|
||||||
|
break;
|
||||||
|
case P_GL2_CALL:
|
||||||
|
reply->retval = gl2_call((void *)request->args[0], request->args[1], request->args[2],
|
||||||
|
request->args[3], request->args[4]);
|
||||||
|
break;
|
||||||
case P_VECTOR:
|
case P_VECTOR:
|
||||||
next_stage.entry = (generic_func *)request->args[0];
|
next_stage.entry = (generic_func *)request->args[0];
|
||||||
memcpy(next_stage.args, &request->args[1], 4 * sizeof(u64));
|
memcpy(next_stage.args, &request->args[1], 4 * sizeof(u64));
|
||||||
|
|
|
@ -18,6 +18,8 @@ typedef enum {
|
||||||
P_EL0_CALL,
|
P_EL0_CALL,
|
||||||
P_EL1_CALL,
|
P_EL1_CALL,
|
||||||
P_VECTOR,
|
P_VECTOR,
|
||||||
|
P_GL1_CALL,
|
||||||
|
P_GL2_CALL,
|
||||||
|
|
||||||
P_WRITE64 = 0x100, // Generic register functions
|
P_WRITE64 = 0x100, // Generic register functions
|
||||||
P_WRITE32,
|
P_WRITE32,
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "chickens.h"
|
#include "chickens.h"
|
||||||
#include "exception.h"
|
#include "exception.h"
|
||||||
|
#include "gxf.h"
|
||||||
#include "smp.h"
|
#include "smp.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
@ -91,6 +92,7 @@ void _start_c(void *boot_args, void *base)
|
||||||
(void *)(((u64)cur_boot_args.devtree) - cur_boot_args.virt_base + cur_boot_args.phys_base);
|
(void *)(((u64)cur_boot_args.devtree) - cur_boot_args.virt_base + cur_boot_args.phys_base);
|
||||||
|
|
||||||
exception_initialize();
|
exception_initialize();
|
||||||
|
gxf_init();
|
||||||
m1n1_main();
|
m1n1_main();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,21 @@
|
||||||
import json, sys
|
import json, sys
|
||||||
|
import argparse
|
||||||
|
|
||||||
data = json.load(open(sys.argv[1]))
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("--imp-apl-prefix", action="store_true")
|
||||||
|
parser.add_argument("regfile")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
if args.imp_apl_prefix:
|
||||||
|
prefix = "IMP_APL_"
|
||||||
|
else:
|
||||||
|
prefix = ""
|
||||||
|
|
||||||
|
data = json.load(open(args.regfile))
|
||||||
for reg in data:
|
for reg in data:
|
||||||
name = reg['name']
|
name = reg['name']
|
||||||
|
|
||||||
print(f"#define SYS_{name} sys_reg({', '.join(str(i) for i in reg['enc'])})")
|
print(f"#define SYS_{prefix}{name} sys_reg({', '.join(str(i) for i in reg['enc'])})")
|
||||||
|
|
||||||
if name[-4:-1] == "_EL":
|
if name[-4:-1] == "_EL":
|
||||||
name = name[:-4]
|
name = name[:-4]
|
||||||
|
|
Loading…
Reference in a new issue