Support virt armv8.(Todo: fix clock intr)
This commit is contained in:
+3
-3
@@ -89,7 +89,7 @@ static void _sys_irq_init(int cpu_id)
|
||||
gic_init();
|
||||
}
|
||||
/* active hardware irq responser */
|
||||
xizi_trap_driver.switch_hw_irqtbl((uint32_t*)&_vector_jumper);
|
||||
xizi_trap_driver.switch_hw_irqtbl((uintptr_t*)&_vector_jumper);
|
||||
}
|
||||
|
||||
static void _cpu_irq_enable(void)
|
||||
@@ -117,7 +117,7 @@ static void _single_irq_disable(int irq, int cpu)
|
||||
}
|
||||
|
||||
#define VBAR
|
||||
static inline uint32_t* _switch_hw_irqtbl(uint32_t* new_tbl_base)
|
||||
static inline uintptr_t* _switch_hw_irqtbl(uintptr_t* new_tbl_base)
|
||||
{
|
||||
// get old irq table base addr
|
||||
uint32_t old_tbl_base = 0;
|
||||
@@ -132,7 +132,7 @@ static inline uint32_t* _switch_hw_irqtbl(uint32_t* new_tbl_base)
|
||||
sctlr &= ~(1 << 13);
|
||||
_ARM_MCR(15, 0, sctlr, 1, 0, 0);
|
||||
|
||||
return (uint32_t*)old_tbl_base;
|
||||
return (uintptr_t*)old_tbl_base;
|
||||
}
|
||||
|
||||
static void _bind_irq_handler(int irq, irq_handler_t handler)
|
||||
|
||||
@@ -51,7 +51,7 @@ Modification:
|
||||
void dump_tf(struct trapframe* tf)
|
||||
{
|
||||
KPrintf(" sp: 0x%x\n", tf->sp);
|
||||
KPrintf(" pc: 0x%x\n", tf->pc);
|
||||
KPrintf(" pc: 0x%x\n", tf->pc);
|
||||
KPrintf(" spsr: 0x%x\n", tf->spsr);
|
||||
KPrintf(" x0: 0x%x\n", tf->x0);
|
||||
KPrintf(" x1: 0x%x\n", tf->x1);
|
||||
|
||||
@@ -14,8 +14,7 @@ History:
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
*************************************************/
|
||||
#include "string.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "core.h"
|
||||
#include "gicv3_common_opa.h"
|
||||
@@ -169,19 +168,10 @@ void gic_init()
|
||||
gicdinit();
|
||||
}
|
||||
|
||||
static inline uint64_t cpuid()
|
||||
void gicv3inithart(uint32_t cpu_id)
|
||||
{
|
||||
uint64_t x;
|
||||
__asm__ volatile("mrs %0, mpidr_el1" : "=r"(x));
|
||||
return x & 0xff;
|
||||
}
|
||||
|
||||
void gicv3inithart()
|
||||
{
|
||||
uint32_t cpu = cpuid();
|
||||
|
||||
giccinit();
|
||||
gicrinit(cpu);
|
||||
gicrinit(cpu_id);
|
||||
|
||||
gic_enable();
|
||||
}
|
||||
@@ -259,7 +249,6 @@ void gic_setup_ppi(uint32_t cpuid, uint32_t intid)
|
||||
void gic_setup_spi(uint32_t cpuid, uint32_t intid)
|
||||
{
|
||||
gic_set_prio0(intid);
|
||||
// all interrupts are handled by cpu0
|
||||
gic_set_target(intid, cpuid);
|
||||
gic_clear_pending(intid);
|
||||
gic_enable_int(intid);
|
||||
|
||||
+1
-1
@@ -144,7 +144,7 @@ void gic_set_irq_priority(uint32_t irq_id, uint32_t priority);
|
||||
|
||||
void gic_setup_spi(uint32_t cpuid, uint32_t intid);
|
||||
|
||||
void gicv3inithart();
|
||||
void gicv3inithart(uint32_t cpu_id);
|
||||
//! @brief Send a software generated interrupt to a specific CPU.
|
||||
//!
|
||||
//! @param irq_id The interrupt number to send.
|
||||
|
||||
@@ -27,6 +27,8 @@ Modification:
|
||||
#ifndef __LINUX_IRQCHIP_ARM_GIC_H
|
||||
#define __LINUX_IRQCHIP_ARM_GIC_H
|
||||
|
||||
#include "memlayout.h"
|
||||
|
||||
// clang-format off
|
||||
// interrupt controller GICv3
|
||||
#define GICV3 (DEV_VRTMEM_BASE + 0x08000000L)
|
||||
|
||||
+15
-22
@@ -8,57 +8,50 @@
|
||||
|
||||
static inline void w_vbar_el1(uint64_t x)
|
||||
{
|
||||
asm volatile("msr vbar_el1, %0" : : "r"(x));
|
||||
__asm__ volatile("msr vbar_el1, %0" : : "r"(x));
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
r_esr_el1()
|
||||
static inline uint64_t r_esr_el1()
|
||||
{
|
||||
uint64_t x;
|
||||
asm volatile("mrs %0, esr_el1" : "=r"(x));
|
||||
__asm__ volatile("mrs %0, esr_el1" : "=r"(x));
|
||||
return x;
|
||||
}
|
||||
|
||||
static inline void
|
||||
w_esr_el1(uint64_t x)
|
||||
static inline void w_esr_el1(uint64_t x)
|
||||
{
|
||||
asm volatile("msr esr_el1, %0" : : "r"(x));
|
||||
__asm__ volatile("msr esr_el1, %0" : : "r"(x));
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
r_elr_el1()
|
||||
static inline uint64_t r_elr_el1()
|
||||
{
|
||||
uint64_t x;
|
||||
asm volatile("mrs %0, elr_el1" : "=r"(x));
|
||||
__asm__ volatile("mrs %0, elr_el1" : "=r"(x));
|
||||
return x;
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
r_far_el1()
|
||||
static inline uint64_t r_far_el1()
|
||||
{
|
||||
uint64_t x;
|
||||
asm volatile("mrs %0, far_el1" : "=r"(x));
|
||||
__asm__ volatile("mrs %0, far_el1" : "=r"(x));
|
||||
return x;
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
daif()
|
||||
static inline uint64_t daif()
|
||||
{
|
||||
uint64_t x;
|
||||
asm volatile("mrs %0, daif" : "=r"(x));
|
||||
__asm__ volatile("mrs %0, daif" : "=r"(x));
|
||||
return x;
|
||||
}
|
||||
|
||||
// enable interrupts(irq)
|
||||
static inline void
|
||||
intr_on()
|
||||
static inline void intr_on()
|
||||
{
|
||||
asm volatile("msr daifclr, #0xf" ::: "memory");
|
||||
__asm__ volatile("msr daifclr, #0xf" ::: "memory");
|
||||
}
|
||||
|
||||
// disable interrupts(irq)
|
||||
static inline void
|
||||
intr_off()
|
||||
static inline void intr_off()
|
||||
{
|
||||
asm volatile("msr daifset, #0xf" ::: "memory");
|
||||
__asm__ volatile("msr daifset, #0xf" ::: "memory");
|
||||
}
|
||||
@@ -41,7 +41,7 @@ extern void iabort_handler(struct trapframe* r);
|
||||
void kernel_abort_handler(struct trapframe* tf)
|
||||
{
|
||||
uint64_t esr = r_esr_el1();
|
||||
switch ((esr & 0x3F) >> 26) {
|
||||
switch ((esr >> 26) & 0x3F) {
|
||||
case 0b100100:
|
||||
case 0b100101:
|
||||
dabort_handler(tf);
|
||||
@@ -49,6 +49,11 @@ void kernel_abort_handler(struct trapframe* tf)
|
||||
case 0b100001:
|
||||
iabort_handler(tf);
|
||||
default:
|
||||
uint64_t ec = (esr >> 26) & 0x3f;
|
||||
uint64_t iss = esr & 0x1ffffff;
|
||||
ERROR("esr %p %p %p\n", esr, ec, iss);
|
||||
ERROR("elr = %p far = %p\n", r_elr_el1(), r_far_el1());
|
||||
ERROR("Current Task: %s.\n", cur_cpu()->task->name);
|
||||
panic("Unimplemented Error Occured.\n");
|
||||
}
|
||||
panic("Return from abort handler.\n");
|
||||
@@ -63,17 +68,10 @@ extern void context_switch(struct context**, struct context*);
|
||||
void syscall_arch_handler(struct trapframe* tf)
|
||||
{
|
||||
uint64_t ec = (r_esr_el1() >> 0x1A) & 0x3F;
|
||||
w_esr_el1(0);
|
||||
if (ec == 0b010101) {
|
||||
w_esr_el1(0);
|
||||
software_irq_dispatch(tf);
|
||||
} else {
|
||||
printf("USYSCALL: unexpected ec %p", r_esr_el1());
|
||||
printf(" elr=%p far=%p\n", r_elr_el1(), r_far_el1());
|
||||
// kill error task
|
||||
xizi_enter_kernel();
|
||||
assert(cur_cpu()->task == NULL);
|
||||
sys_exit(cur_cpu()->task);
|
||||
context_switch(&cur_cpu()->task->thread_context.context, cur_cpu()->scheduler);
|
||||
panic("dabort end should never be reashed.\n");
|
||||
kernel_abort_handler(tf);
|
||||
}
|
||||
}
|
||||
+1
-13
@@ -60,16 +60,6 @@ extern uint64_t _vector_jumper;
|
||||
extern uint64_t _vector_start;
|
||||
extern uint64_t _vector_end;
|
||||
|
||||
// void init_cpu_mode_stacks(int cpu_id)
|
||||
// {
|
||||
// uint32_t modes[] = { ARM_MODE_EL0_t, ARM_MODE_EL1_t, ARM_MODE_EL2_t, ARM_MODE_EL3_t };
|
||||
// // initialize the stacks for different mode
|
||||
// for (int i = 0; i < sizeof(modes) / sizeof(uint64_t); i++) {
|
||||
// memset(mode_stack_pages[cpu_id][i], 0, MODE_STACK_SIZE);
|
||||
// init_stack(modes[i], (uint64_t)mode_stack_pages[cpu_id][i]);
|
||||
// }
|
||||
// }
|
||||
|
||||
extern void alltraps();
|
||||
static void _sys_irq_init(int cpu_id)
|
||||
{
|
||||
@@ -77,15 +67,13 @@ static void _sys_irq_init(int cpu_id)
|
||||
xizi_trap_driver.switch_hw_irqtbl((uintptr_t*)alltraps);
|
||||
|
||||
if (cpu_id == 0) {
|
||||
xizi_trap_driver.switch_hw_irqtbl((uintptr_t*)alltraps);
|
||||
gic_init();
|
||||
}
|
||||
gicv3inithart();
|
||||
gicv3inithart(cpu_id);
|
||||
}
|
||||
|
||||
static void _cpu_irq_enable(void)
|
||||
{
|
||||
// arm_set_interrupt_state(true);
|
||||
intr_on();
|
||||
}
|
||||
|
||||
|
||||
@@ -32,117 +32,6 @@ Modification:
|
||||
|
||||
#include "core.h"
|
||||
|
||||
.global trap_irq_enter
|
||||
.global trap_return
|
||||
.global usertrapret
|
||||
.global init_stack
|
||||
|
||||
trap_return:
|
||||
// Restore registers
|
||||
ldp x1, x2, [sp], #16
|
||||
ldp x3, x0, [sp], #16
|
||||
msr sp_el0, x1
|
||||
msr spsr_el1, x2
|
||||
msr elr_el1, x3
|
||||
|
||||
ldp x1, x2, [sp], #16
|
||||
ldp x3, x4, [sp], #16
|
||||
ldp x5, x6, [sp], #16
|
||||
ldp x7, x8, [sp], #16
|
||||
ldp x9, x10, [sp], #16
|
||||
ldp x11, x12, [sp], #16
|
||||
ldp x13, x14, [sp], #16
|
||||
ldp x15, x16, [sp], #16
|
||||
ldp x17, x18, [sp], #16
|
||||
ldp x19, x20, [sp], #16
|
||||
ldp x21, x22, [sp], #16
|
||||
ldp x23, x24, [sp], #16
|
||||
ldp x25, x26, [sp], #16
|
||||
ldp x27, x28, [sp], #16
|
||||
ldp x29, x30, [sp], #16
|
||||
|
||||
eret
|
||||
|
||||
user_trap_swi_enter:
|
||||
// Save trapframe to swi stack
|
||||
stp x29, x30, [sp, #-16]!
|
||||
stp x27, x28, [sp, #-16]!
|
||||
stp x25, x26, [sp, #-16]!
|
||||
stp x23, x24, [sp, #-16]!
|
||||
stp x21, x22, [sp, #-16]!
|
||||
stp x19, x20, [sp, #-16]!
|
||||
stp x17, x18, [sp, #-16]!
|
||||
stp x15, x16, [sp, #-16]!
|
||||
stp x13, x14, [sp, #-16]!
|
||||
stp x11, x12, [sp, #-16]!
|
||||
stp x9, x10, [sp, #-16]!
|
||||
stp x7, x8, [sp, #-16]!
|
||||
stp x5, x6, [sp, #-16]!
|
||||
stp x3, x4, [sp, #-16]!
|
||||
stp x1, x2, [sp, #-16]!
|
||||
|
||||
// mrs x2, spsr_el1
|
||||
//str x2, [sp, #-8]
|
||||
//str x30, [sp, #-8]
|
||||
//stp sp, elr_el1, [sp, #-16]!
|
||||
//str sp, [sp, #-8]
|
||||
|
||||
// Call syscall handler
|
||||
mov x0, sp
|
||||
bl software_irq_dispatch
|
||||
b trap_return
|
||||
|
||||
trap_irq_enter:
|
||||
// Build trapframe.
|
||||
stp x29, x30, [sp, #-16]!
|
||||
stp x27, x28, [sp, #-16]!
|
||||
stp x25, x26, [sp, #-16]!
|
||||
stp x23, x24, [sp, #-16]!
|
||||
stp x21, x22, [sp, #-16]!
|
||||
stp x19, x20, [sp, #-16]!
|
||||
stp x17, x18, [sp, #-16]!
|
||||
stp x15, x16, [sp, #-16]!
|
||||
stp x13, x14, [sp, #-16]!
|
||||
stp x11, x12, [sp, #-16]!
|
||||
stp x9, x10, [sp, #-16]!
|
||||
stp x7, x8, [sp, #-16]!
|
||||
stp x5, x6, [sp, #-16]!
|
||||
stp x3, x4, [sp, #-16]!
|
||||
stp x1, x2, [sp, #-16]!
|
||||
|
||||
mrs x3, elr_el1
|
||||
mrs x2, spsr_el1
|
||||
mrs x1, sp_el0
|
||||
stp x3, x0, [sp, #-16]!
|
||||
stp x1, x2, [sp, #-16]!
|
||||
|
||||
//Call trap(struct trapframe*)
|
||||
mov x0, sp
|
||||
bl intr_irq_dispatch
|
||||
b trap_return
|
||||
|
||||
|
||||
|
||||
// Help forkret to call trap_return in an expected way
|
||||
//usertrapret:
|
||||
// Overlay stack pointer in trap_return
|
||||
// mov sp, x0
|
||||
// b trap_return
|
||||
|
||||
|
||||
init_stack:
|
||||
mrs x2, spsr_el1
|
||||
bic x2, x2, #SPSR_MODE_MASK
|
||||
orr x2, x2, x0
|
||||
msr spsr_el1, x2
|
||||
mov sp, x1
|
||||
bic x2, x2, #SPSR_MODE_MASK
|
||||
orr x2, x2, #ARM_MODE_EL1_t
|
||||
msr spsr_el1, x2
|
||||
ret
|
||||
|
||||
.section ".text"
|
||||
|
||||
.macro savereg
|
||||
msr daifset, #0xf
|
||||
// make room to save registers.
|
||||
@@ -197,7 +86,6 @@ init_stack:
|
||||
.endm
|
||||
|
||||
.macro usavereg
|
||||
msr daifset, #0xf
|
||||
sub sp, sp, #272
|
||||
|
||||
stp x0, x1, [sp, #16 * 0]
|
||||
@@ -298,43 +186,39 @@ el1sync:
|
||||
savereg
|
||||
|
||||
mov x0, sp
|
||||
bl kernel_abort_handler
|
||||
bl kernel_abort_handler
|
||||
b .
|
||||
|
||||
restorereg
|
||||
|
||||
eret
|
||||
el1irq:
|
||||
savereg
|
||||
|
||||
mov x0, sp
|
||||
# this should never happen by design
|
||||
bl kernel_intr_handler
|
||||
|
||||
restorereg
|
||||
|
||||
eret
|
||||
bl kernel_intr_handler
|
||||
b .
|
||||
|
||||
el0sync:
|
||||
msr daifset, #0xf
|
||||
usavereg
|
||||
|
||||
mov x0, sp
|
||||
bl syscall_arch_handler
|
||||
|
||||
urestorereg
|
||||
msr daifclr, #0xf
|
||||
|
||||
eret
|
||||
|
||||
el0irq:
|
||||
msr daifset, #0xf
|
||||
usavereg
|
||||
|
||||
mov x0, sp
|
||||
bl intr_irq_dispatch
|
||||
|
||||
trapret:
|
||||
.global trap_return
|
||||
trap_return:
|
||||
urestorereg
|
||||
msr daifclr, #0xf
|
||||
|
||||
eret
|
||||
|
||||
.global usertrapret
|
||||
usertrapret:
|
||||
mov sp, x0
|
||||
b trapret
|
||||
eret
|
||||
Reference in New Issue
Block a user