6#include <opensbi_interface.h>
22using Ns16550aSingleton = etl::singleton<ns16550a::Ns16550a>;
28 auto& plic = InterruptSingleton::instance().plic();
29 auto source_id = plic.Which();
30 plic.Do(source_id, context);
39 auto instruction = *
reinterpret_cast<uint8_t*
>(context->sepc);
42 if ((instruction & 0x3) != 0x3) {
49 klog::Info(
"Handle {}", cpu_io::ScauseInfo::kExceptionNames[exception_code]);
55 auto addr = cpu_io::Stval::Read();
56 klog::Err(
"PageFault: {}({:#x}), addr: {:#x}",
57 cpu_io::ScauseInfo::kExceptionNames[exception_code], exception_code,
78 cpu_io::Sip::Ssip::Clear();
86 while (Ns16550aSingleton::instance().HasData()) {
87 uint8_t ch = Ns16550aSingleton::instance().GetChar();
96 VirtioDriverSingleton::instance().HandleInterrupt(
99 klog::Err(
"VirtIO blk IO error: {}",
static_cast<int>(status));
105auto RegisterInterrupts() ->
void {
107 InterruptSingleton::instance().RegisterInterruptFunc(
108 cpu_io::ScauseInfo::kSupervisorExternalInterrupt,
109 InterruptDelegate::create<ExternalInterruptHandler>());
111 auto [base, size, irq] = KernelFdtSingleton::instance().GetSerial().value();
114 Ns16550aSingleton::create(std::move(*uart_result));
116 klog::Err(
"Failed to create Ns16550a: {}",
117 static_cast<int>(uart_result.error().code));
121 InterruptSingleton::instance().RegisterInterruptFunc(
122 cpu_io::ScauseInfo::kBreakpoint,
123 InterruptDelegate::create<EbreakHandler>());
126 InterruptSingleton::instance().RegisterInterruptFunc(
127 cpu_io::ScauseInfo::kInstructionPageFault,
128 InterruptDelegate::create<PageFaultHandler>());
129 InterruptSingleton::instance().RegisterInterruptFunc(
130 cpu_io::ScauseInfo::kLoadPageFault,
131 InterruptDelegate::create<PageFaultHandler>());
132 InterruptSingleton::instance().RegisterInterruptFunc(
133 cpu_io::ScauseInfo::kStoreAmoPageFault,
134 InterruptDelegate::create<PageFaultHandler>());
137 InterruptSingleton::instance().RegisterInterruptFunc(
138 cpu_io::ScauseInfo::kEcallUserMode,
139 InterruptDelegate::create<SyscallHandler>());
142 InterruptSingleton::instance().RegisterInterruptFunc(
143 cpu_io::ScauseInfo::kSupervisorSoftwareInterrupt,
144 InterruptDelegate::create<IpiHandler>());
151 InterruptSingleton::instance().Do(context->scause, context);
156 InterruptSingleton::create();
159 RegisterInterrupts();
162 auto [plic_addr, plic_size, ndev, context_count] =
163 KernelFdtSingleton::instance().GetPlic().value();
164 VirtualMemorySingleton::instance()
165 .MapMMIO(plic_addr, plic_size)
171 return std::unexpected(err);
173 InterruptSingleton::instance().InitPlic(plic_addr, ndev, context_count);
177 cpu_io::Stvec::SetDirect(
reinterpret_cast<uint64_t
>(
trap_entry));
183 cpu_io::Sstatus::Sie::Set();
186 cpu_io::Sie::Ssie::Set();
189 cpu_io::Sie::Seie::Set();
193 std::get<2>(KernelFdtSingleton::instance().GetSerial().value());
194 InterruptSingleton::instance()
196 InterruptDelegate::create<SerialIrqHandler>())
199 return std::unexpected(err);
203 auto& blk_driver = VirtioDriverSingleton::instance();
204 auto blk_irq = blk_driver.GetIrq();
206 InterruptSingleton::instance()
207 .RegisterExternalInterrupt(
209 InterruptDelegate::create<VirtioBlkIrqHandler>())
211 klog::Err(
"Failed to register virtio-blk IRQ {}: {}", blk_irq,
213 return std::unexpected(err);
223 cpu_io::Stvec::SetDirect(
reinterpret_cast<uint64_t
>(
trap_entry));
229 cpu_io::Sstatus::Sie::Set();
232 cpu_io::Sie::Ssie::Set();
235 cpu_io::Sie::Seie::Set();
auto DumpStack() -> void
打印调用栈
auto etl_putchar(int c) -> void
早期控制台字符输出
auto InterruptInit(int, const char **) -> void
体系结构相关中断初始化
InterruptBase::InterruptDelegate InterruptDelegate
auto InterruptInitSMP(int, const char **) -> void
从核的体系结构相关中断初始化
auto Syscall(uint64_t, cpu_io::TrapContext *context_ptr) -> void
AArch64 系统调用处理
auto trap_entry() -> void
etl::delegate< uint64_t(uint64_t, cpu_io::TrapContext *)> InterruptDelegate
类型安全的中断处理委托
static auto Create(uint64_t dev_addr) -> Expected< Ns16550a >
工厂方法:创建并初始化 NS16550A 驱动
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 级别记录日志
auto Debug(etl::format_string< Args... > fmt, Args &&... args) -> void
以 DEBUG 级别记录日志(SIMPLEKERNEL_MIN_LOG_LEVEL > 0 时编译期消除)
auto HandleTrap(cpu_io::TrapContext *context) -> cpu_io::TrapContext *
constexpr auto message() const -> const char *