Support virt armv8.(Todo: fix clock intr)

This commit is contained in:
TXuian
2024-05-27 14:57:58 +08:00
parent 80f80b64f0
commit 71cf0c667c
58 changed files with 590 additions and 454 deletions
@@ -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);
@@ -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)
@@ -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);
}
}
@@ -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