Skip to content

Commit

Permalink
feat: aarch64 intr
Browse files Browse the repository at this point in the history
Signed-off-by: Zone.N <[email protected]>
  • Loading branch information
MRNIU committed Jan 10, 2025
1 parent 46edcc9 commit 18d80e7
Show file tree
Hide file tree
Showing 2 changed files with 231 additions and 39 deletions.
153 changes: 127 additions & 26 deletions src/kernel/arch/aarch64/interrupt.S
Original file line number Diff line number Diff line change
Expand Up @@ -18,58 +18,159 @@

// clang-format off

.global alltraps
.global vector_table
.balign 0x800
alltraps:
// Current EL with sp0
b .
vector_table:
// Current EL with SP0
.balign 0x80
b .
b sync_current_el_sp0
.balign 0x80
b .
b irq_current_el_sp0
.balign 0x80
b .
b fiq_current_el_sp0
.balign 0x80
b error_current_el_sp0

// Current EL with spx
// Current EL with SPx
.balign 0x80
b el1sync
b sync_current_el_spx
.balign 0x80
b el1irq
b irq_current_el_spx
.balign 0x80
b .
b fiq_current_el_spx
.balign 0x80
b .
b error_current_el_spx

// Lower EL using aarch64
// Lower EL using AArch64
.balign 0x80
b .
b sync_lower_el_aarch64
.balign 0x80
b .
b irq_lower_el_aarch64
.balign 0x80
b .
b fiq_lower_el_aarch64
.balign 0x80
b .
b error_lower_el_aarch64

// Lower EL using aarch32
// Lower EL using AArch32
.balign 0x80
b .
b sync_lower_el_aarch32
.balign 0x80
b .
b irq_lower_el_aarch32
.balign 0x80
b .
b fiq_lower_el_aarch32
.balign 0x80
b .
b error_lower_el_aarch32

// Exception handlers
sync_current_el_sp0:
savereg
mov x0, sp
bl sync_current_el_sp0_handler
restorereg
eret

irq_current_el_sp0:
savereg
mov x0, sp
bl irq_current_el_sp0_handler
restorereg
eret

fiq_current_el_sp0:
savereg
mov x0, sp
bl fiq_current_el_sp0_handler
restorereg
eret

error_current_el_sp0:
savereg
mov x0, sp
bl error_current_el_sp0_handler
restorereg
eret

sync_current_el_spx:
savereg
mov x0, sp
bl sync_current_el_spx_handler
restorereg
eret

irq_current_el_spx:
savereg
mov x0, sp
bl irq_current_el_spx_handler
restorereg
eret

fiq_current_el_spx:
savereg
mov x0, sp
bl fiq_current_el_spx_handler
restorereg
eret

el1sync:
error_current_el_spx:
savereg
mov x0, sp
bl kerneltrap
bl error_current_el_spx_handler
restorereg
eret
el1irq:

sync_lower_el_aarch64:
savereg
mov x0, sp
bl sync_lower_el_aarch64_handler
restorereg
eret

irq_lower_el_aarch64:
savereg
mov x0, sp
bl irq_lower_el_aarch64_handler
restorereg
eret

fiq_lower_el_aarch64:
savereg
mov x0, sp
bl fiq_lower_el_aarch64_handler
restorereg
eret

error_lower_el_aarch64:
savereg
mov x0, sp
bl error_lower_el_aarch64_handler
restorereg
eret

sync_lower_el_aarch32:
savereg
mov x0, sp
bl sync_lower_el_aarch32_handler
restorereg
eret

irq_lower_el_aarch32:
savereg
mov x0, sp
bl irq_lower_el_aarch32_handler
restorereg
eret

fiq_lower_el_aarch32:
savereg
mov x0, sp
bl fiq_lower_el_aarch32_handler
restorereg
eret

error_lower_el_aarch32:
savereg
mov x0, sp
bl kernelirq
bl error_lower_el_aarch32_handler
restorereg
eret

Expand Down
117 changes: 104 additions & 13 deletions src/kernel/arch/aarch64/interrupt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,25 +23,112 @@
* 由于 aarch64-linux-gnu-g++ 13.2.0 不支持 aarch64 的
* __attribute__((interrupt("IRQ"))) 写法,需要手动处理中断函数
*/
extern "C" void alltraps();
extern "C" void vector_table();

extern "C" void kerneltrap() {
auto esr = cpu_io::ESR_EL1::Read();
cpu_io::ESR_EL1::Write(0);
// 同步异常处理程序
extern "C" void sync_current_el_sp0_handler(uint64_t sp) {
klog::Err("Sync Exception at Current EL with SP0\n");
while (true) {
asm volatile("wfi");
}
}

extern "C" void irq_current_el_sp0_handler(uint64_t sp) {
klog::Err("IRQ Exception at Current EL with SP0\n");
// 处理 IRQ 中断
// ...
}

extern "C" void fiq_current_el_sp0_handler(uint64_t sp) {
klog::Err("FIQ Exception at Current EL with SP0\n");
// 处理 FIQ 中断
// ...
}

extern "C" void error_current_el_sp0_handler(uint64_t sp) {
klog::Err("Error Exception at Current EL with SP0\n");
while (true) {
asm volatile("wfi");
}
}

if (cpu_io::GetInterruptStatus() != 0) {
klog::Err("kerneltrap: interrupts enabled");
extern "C" void sync_current_el_spx_handler(uint64_t sp) {
klog::Err("Sync Exception at Current EL with SPx\n");
while (true) {
asm volatile("wfi");
}
}

auto ec = cpu_io::ESR_EL1::EC::Get();
auto iss = cpu_io::ESR_EL1::ISS::Get();
extern "C" void irq_current_el_spx_handler(uint64_t sp) {
klog::Err("IRQ Exception at Current EL with SPx\n");
// 处理 IRQ 中断
// ...
}

klog::Info("esr %p %p %p\n", esr, ec, iss);
klog::Info("elr=%p far=%p\n", cpu_io::ELR_EL1::Read(),
cpu_io::FAR_EL1::Read());
extern "C" void fiq_current_el_spx_handler(uint64_t sp) {
klog::Err("FIQ Exception at Current EL with SPx\n");
// 处理 FIQ 中断
// ...
}

extern "C" void error_current_el_spx_handler(uint64_t sp) {
klog::Err("Error Exception at Current EL with SPx\n");
while (true) {
asm volatile("wfi");
}
}

extern "C" void kernelirq() { klog::Info("kernelirq\n"); }
extern "C" void sync_lower_el_aarch64_handler(uint64_t sp) {
klog::Err("Sync Exception at Lower EL using AArch64\n");
while (true) {
asm volatile("wfi");
}
}

extern "C" void irq_lower_el_aarch64_handler(uint64_t sp) {
klog::Err("IRQ Exception at Lower EL using AArch64\n");
// 处理 IRQ 中断
// ...
}

extern "C" void fiq_lower_el_aarch64_handler(uint64_t sp) {
klog::Err("FIQ Exception at Lower EL using AArch64\n");
// 处理 FIQ 中断
// ...
}

extern "C" void error_lower_el_aarch64_handler(uint64_t sp) {
klog::Err("Error Exception at Lower EL using AArch64\n");
while (true) {
asm volatile("wfi");
}
}

extern "C" void sync_lower_el_aarch32_handler(uint64_t sp) {
klog::Err("Sync Exception at Lower EL using AArch32\n");
while (true) {
asm volatile("wfi");
}
}

extern "C" void irq_lower_el_aarch32_handler(uint64_t sp) {
klog::Err("IRQ Exception at Lower EL using AArch32\n");
// 处理 IRQ 中断
// ...
}

extern "C" void fiq_lower_el_aarch32_handler(uint64_t sp) {
klog::Err("FIQ Exception at Lower EL using AArch32\n");
// 处理 FIQ 中断
// ...
}

extern "C" void error_lower_el_aarch32_handler(uint64_t sp) {
klog::Err("Error Exception at Lower EL using AArch32\n");
while (true) {
asm volatile("wfi");
}
}

Interrupt::Interrupt() { klog::Info("Interrupt init.\n"); }

Expand All @@ -58,7 +145,11 @@ void Interrupt::RegisterInterruptFunc(uint64_t cause, InterruptFunc func) {
uint32_t InterruptInit(uint32_t, uint8_t *) {
klog::Info("Hello InterruptInit\n");

cpu_io::VBAR_EL1::Write(reinterpret_cast<uint64_t>(alltraps));
cpu_io::VBAR_EL1::Write(reinterpret_cast<uint64_t>(vector_table));

cpu_io::EnableInterrupt();

asm("udf #0");

return 0;
}

0 comments on commit 18d80e7

Please sign in to comment.