mirror of
https://github.com/AsahiLinux/m1n1
synced 2024-11-21 22:23:05 +00:00
exceptions: add el3_call()
Signed-off-by: Nick Chan <towinchenmi@gmail.com>
This commit is contained in:
parent
1fd17b8933
commit
9ca6d1c16f
9 changed files with 33 additions and 2 deletions
|
@ -494,6 +494,7 @@ class M1N1Proxy(Reloadable):
|
||||||
P_PUT_SIMD_STATE = 0x00f
|
P_PUT_SIMD_STATE = 0x00f
|
||||||
P_REBOOT = 0x010
|
P_REBOOT = 0x010
|
||||||
P_SLEEP = 0x011
|
P_SLEEP = 0x011
|
||||||
|
P_EL3_CALL = 0x012
|
||||||
|
|
||||||
P_WRITE64 = 0x100
|
P_WRITE64 = 0x100
|
||||||
P_WRITE32 = 0x101
|
P_WRITE32 = 0x101
|
||||||
|
@ -760,6 +761,10 @@ class M1N1Proxy(Reloadable):
|
||||||
self.request(self.P_REBOOT, no_reply=True)
|
self.request(self.P_REBOOT, no_reply=True)
|
||||||
def sleep(self, deep=False):
|
def sleep(self, deep=False):
|
||||||
self.request(self.P_SLEEP, deep, no_reply=True)
|
self.request(self.P_SLEEP, deep, no_reply=True)
|
||||||
|
def el3_call(self, addr, *args):
|
||||||
|
if len(args) > 4:
|
||||||
|
raise ValueError("Too many arguments")
|
||||||
|
return self.request(self.P_EL3_CALL, addr, *args)
|
||||||
|
|
||||||
def write64(self, addr, data):
|
def write64(self, addr, data):
|
||||||
'''write 8 byte value to given address'''
|
'''write 8 byte value to given address'''
|
||||||
|
|
|
@ -281,6 +281,10 @@ void exc_sync(u64 *regs)
|
||||||
// Monitor call
|
// Monitor call
|
||||||
u32 imm = mrs(ESR_EL3) & 0xffff;
|
u32 imm = mrs(ESR_EL3) & 0xffff;
|
||||||
switch (imm) {
|
switch (imm) {
|
||||||
|
case 42:
|
||||||
|
regs[0] = ((uint64_t(*)(uint64_t, uint64_t, uint64_t, uint64_t))regs[0])(
|
||||||
|
regs[1], regs[2], regs[3], regs[4]);
|
||||||
|
return;
|
||||||
default:
|
default:
|
||||||
printf("Unknown SMC: 0x%x\n", imm);
|
printf("Unknown SMC: 0x%x\n", imm);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -49,6 +49,7 @@ void print_regs(u64 *regs, int el12);
|
||||||
|
|
||||||
uint64_t el0_call(void *func, uint64_t a, uint64_t b, uint64_t c, uint64_t d);
|
uint64_t el0_call(void *func, uint64_t a, uint64_t b, uint64_t c, uint64_t d);
|
||||||
uint64_t el1_call(void *func, uint64_t a, uint64_t b, uint64_t c, uint64_t d);
|
uint64_t el1_call(void *func, uint64_t a, uint64_t b, uint64_t c, uint64_t d);
|
||||||
|
uint64_t el3_call(void *func, uint64_t a, uint64_t b, uint64_t c, uint64_t d);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -242,3 +242,9 @@ _el1_vectors_start:
|
||||||
hvc 0x1e
|
hvc 0x1e
|
||||||
.align 7
|
.align 7
|
||||||
hvc 0x1f
|
hvc 0x1f
|
||||||
|
|
||||||
|
.globl el3_call
|
||||||
|
.type el3_call, @function
|
||||||
|
el3_call:
|
||||||
|
smc 42
|
||||||
|
ret
|
|
@ -116,6 +116,9 @@ int proxy_process(ProxyRequest *request, ProxyReply *reply)
|
||||||
case P_SLEEP:
|
case P_SLEEP:
|
||||||
cpu_sleep(request->args[0]);
|
cpu_sleep(request->args[0]);
|
||||||
break;
|
break;
|
||||||
|
case P_EL3_CALL:
|
||||||
|
reply->retval = el3_call((void *)request->args[0], request->args[1], request->args[2],
|
||||||
|
request->args[3], request->args[4]);
|
||||||
|
|
||||||
case P_WRITE64:
|
case P_WRITE64:
|
||||||
exc_guard = GUARD_SKIP;
|
exc_guard = GUARD_SKIP;
|
||||||
|
|
|
@ -24,6 +24,7 @@ typedef enum {
|
||||||
P_PUT_SIMD_STATE,
|
P_PUT_SIMD_STATE,
|
||||||
P_REBOOT,
|
P_REBOOT,
|
||||||
P_SLEEP,
|
P_SLEEP,
|
||||||
|
P_EL3_CALL,
|
||||||
|
|
||||||
P_WRITE64 = 0x100, // Generic register functions
|
P_WRITE64 = 0x100, // Generic register functions
|
||||||
P_WRITE32,
|
P_WRITE32,
|
||||||
|
|
|
@ -107,6 +107,12 @@ void smp_secondary_entry(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void smp_secondary_prep_el3(void)
|
||||||
|
{
|
||||||
|
msr(TPIDR_EL3, target_cpu);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
static void smp_start_cpu(int index, int die, int cluster, int core, u64 impl, u64 cpu_start_base)
|
static void smp_start_cpu(int index, int die, int cluster, int core, u64 impl, u64 cpu_start_base)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
|
@ -14,6 +14,7 @@ extern u8 *secondary_stacks[MAX_CPUS];
|
||||||
extern u8 *secondary_stacks_el3[MAX_EL3_CPUS];
|
extern u8 *secondary_stacks_el3[MAX_EL3_CPUS];
|
||||||
|
|
||||||
void smp_secondary_entry(void);
|
void smp_secondary_entry(void);
|
||||||
|
void smp_secondary_prep_el3(void);
|
||||||
|
|
||||||
void smp_start_secondaries(void);
|
void smp_start_secondaries(void);
|
||||||
void smp_stop_secondaries(bool deep_sleep);
|
void smp_stop_secondaries(bool deep_sleep);
|
||||||
|
@ -35,7 +36,9 @@ void smp_send_ipi(int cpu);
|
||||||
|
|
||||||
static inline int smp_id(void)
|
static inline int smp_id(void)
|
||||||
{
|
{
|
||||||
if (in_el2())
|
if (in_el3())
|
||||||
|
return mrs(TPIDR_EL3);
|
||||||
|
else if (in_el2())
|
||||||
return mrs(TPIDR_EL2);
|
return mrs(TPIDR_EL2);
|
||||||
else
|
else
|
||||||
return mrs(TPIDR_EL1);
|
return mrs(TPIDR_EL1);
|
||||||
|
|
|
@ -193,8 +193,10 @@ void _cpu_reset_c(void *stack)
|
||||||
|
|
||||||
exception_initialize();
|
exception_initialize();
|
||||||
|
|
||||||
if (in_el3())
|
if (in_el3()) {
|
||||||
|
smp_secondary_prep_el3();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!is_boot_cpu())
|
if (!is_boot_cpu())
|
||||||
smp_secondary_entry();
|
smp_secondary_entry();
|
||||||
|
|
Loading…
Reference in a new issue