8#include <opensbi_interface.h>
19 klog::Info(
"Default Interrupt handler [{}] {:#X}, {:#x}",
20 cpu_io::ScauseInfo::kInterruptNames[cause], cause,
21 reinterpret_cast<uintptr_t
>(context));
27 klog::Err(
"Default Exception handler [{}] {:#X}, {:#x}",
28 cpu_io::ScauseInfo::kExceptionNames[cause], cause,
29 reinterpret_cast<uintptr_t
>(context));
39 i = InterruptDelegate::create<DefaultInterruptHandler>();
43 i = InterruptDelegate::create<DefaultExceptionHandler>();
49 auto interrupt = cpu_io::Scause::Interrupt::Get(cause);
50 auto exception_code = cpu_io::Scause::ExceptionCode::Get(cause);
54 if (exception_code < cpu_io::ScauseInfo::kInterruptMaxCount) {
55 interrupt_handlers_[exception_code](exception_code, context);
59 if (exception_code < cpu_io::ScauseInfo::kExceptionMaxCount) {
60 exception_handlers_[exception_code](exception_code, context);
67 auto interrupt = cpu_io::Scause::Interrupt::Get(cause);
68 auto exception_code = cpu_io::Scause::ExceptionCode::Get(cause);
71 assert(exception_code < cpu_io::ScauseInfo::kInterruptMaxCount &&
72 "Interrupt code out of range");
74 interrupt_handlers_[exception_code] = func;
76 cpu_io::ScauseInfo::kInterruptNames[exception_code], cause);
78 assert(exception_code < cpu_io::ScauseInfo::kExceptionMaxCount &&
79 "Exception code out of range");
81 exception_handlers_[exception_code] = func;
83 cpu_io::ScauseInfo::kExceptionNames[exception_code], cause);
88 if (target_cpu_mask > (1UL << SIMPLEKERNEL_MAX_CORE_COUNT) - 1) {
92 auto ret = sbi_send_ipi(target_cpu_mask, 0);
93 if (ret.error != SBI_SUCCESS) {
101 if (BasicInfoSingleton::instance().core_count == 1) {
107 for (
size_t i = 0; i < BasicInfoSingleton::instance().core_count; ++i) {
113 return SendIpi(mask);
125 plic_.RegisterInterruptFunc(
static_cast<uint8_t
>(irq), handler);
128 plic_.Set(cpu_id, irq, priority,
true);
130 klog::Info(
"RegisterExternalInterrupt: IRQ {}, cpu {}, priority {}", irq,
137 plic_ =
Plic(dev_addr, ndev, context_count);
InterruptBase::InterruptDelegate InterruptDelegate
auto SendIpi(uint64_t target_cpu_mask) -> Expected< void > override
发送 IPI 到指定 CPU
auto RegisterExternalInterrupt(uint32_t irq, uint32_t cpu_id, uint32_t priority, InterruptDelegate handler) -> Expected< void > override
注册外部中断
auto Do(uint64_t cause, cpu_io::TrapContext *context) -> void override
执行中断处理
auto RegisterInterruptFunc(uint64_t cause, InterruptDelegate func) -> void override
注册中断处理函数
auto InitPlic(uint64_t dev_addr, size_t ndev, size_t context_count) -> void
初始化 PLIC
auto BroadcastIpi() -> Expected< void > override
广播 IPI 到所有 CPU
std::array< InterruptDelegate, cpu_io::ScauseInfo::kExceptionMaxCount > exception_handlers_
异常处理函数数组
std::array< InterruptDelegate, kMaxInterrupt > interrupt_handlers_
中断处理函数数组
static constexpr size_t kInterruptMaxCount
最大外部中断数量
std::expected< T, Error > Expected
std::expected 别名模板
auto GetCurrentCoreId() -> size_t
auto Err(etl::format_string< Args... > fmt, Args &&... args) -> void
以 ERROR 级别记录日志
auto Info(etl::format_string< Args... > fmt, Args &&... args) -> void
以 INFO 级别记录日志