SimpleKernel 1.17.0
Loading...
Searching...
No Matches
interrupt_main.cpp File Reference
#include <cpu_io.h>
#include <opensbi_interface.h>
#include "arch.h"
#include "basic_info.hpp"
#include "interrupt.h"
#include "kernel.h"
#include "kernel_fdt.hpp"
#include "kernel_log.hpp"
#include "kstd_cstdio"
#include "ns16550a/ns16550a.hpp"
#include "syscall.hpp"
#include "task_manager.hpp"
#include "virtio/virtio_driver.hpp"
#include "virtual_memory.hpp"
Include dependency graph for interrupt_main.cpp:

Go to the source code of this file.

Functions

auto HandleTrap (cpu_io::TrapContext *context) -> cpu_io::TrapContext *
 
auto InterruptInit (int, const char **) -> void
 体系结构相关中断初始化
 
auto InterruptInitSMP (int, const char **) -> void
 从核的体系结构相关中断初始化
 

Function Documentation

◆ HandleTrap()

auto HandleTrap ( cpu_io::TrapContext context) -> cpu_io::TrapContext*

Definition at line 149 of file interrupt_main.cpp.

150 {
151 InterruptSingleton::instance().Do(context->scause, context);
152 return context;
153}

◆ InterruptInit()

auto InterruptInit ( int  argc,
const char **  argv 
) -> void

体系结构相关中断初始化

Parameters
argc在不同体系结构有不同含义,同 _start
argv在不同体系结构有不同含义,同 _start
Precondition
ArchInit 已完成
Postcondition
中断控制器已初始化,中断向量表已设置

Definition at line 155 of file interrupt_main.cpp.

155 {
156 InterruptSingleton::create();
157
158 // 注册中断处理函数
159 RegisterInterrupts();
160
161 // 初始化 plic
162 auto [plic_addr, plic_size, ndev, context_count] =
163 KernelFdtSingleton::instance().GetPlic().value();
164 VirtualMemorySingleton::instance()
165 .MapMMIO(plic_addr, plic_size)
166 .or_else([](Error err) -> Expected<void*> {
167 klog::Err("Failed to map PLIC MMIO: {}", err.message());
168 while (true) {
170 }
171 return std::unexpected(err);
172 });
173 InterruptSingleton::instance().InitPlic(plic_addr, ndev, context_count);
174
175 // 设置 trap vector
176 auto success =
177 cpu_io::Stvec::SetDirect(reinterpret_cast<uint64_t>(trap_entry));
178 if (!success) {
179 klog::Err("Failed to set trap vector");
180 }
181
182 // 开启 Supervisor 中断
183 cpu_io::Sstatus::Sie::Set();
184
185 // 开启内部中断
186 cpu_io::Sie::Ssie::Set();
187
188 // 开启外部中断
189 cpu_io::Sie::Seie::Set();
190
191 // 通过统一接口注册串口外部中断(先注册 handler,再启用 PLIC)
192 auto serial_irq =
193 std::get<2>(KernelFdtSingleton::instance().GetSerial().value());
194 InterruptSingleton::instance()
195 .RegisterExternalInterrupt(serial_irq, cpu_io::GetCurrentCoreId(), 1,
196 InterruptDelegate::create<SerialIrqHandler>())
197 .or_else([](Error err) -> Expected<void> {
198 klog::Err("Failed to register serial IRQ: {}", err.message());
199 return std::unexpected(err);
200 });
201
202 // 通过统一接口注册 virtio-blk 外部中断
203 auto& blk_driver = VirtioDriverSingleton::instance();
204 auto blk_irq = blk_driver.GetIrq();
205 if (blk_irq != 0) {
206 InterruptSingleton::instance()
207 .RegisterExternalInterrupt(
208 blk_irq, cpu_io::GetCurrentCoreId(), 1,
209 InterruptDelegate::create<VirtioBlkIrqHandler>())
210 .or_else([blk_irq](Error err) -> Expected<void> {
211 klog::Err("Failed to register virtio-blk IRQ {}: {}", blk_irq,
212 err.message());
213 return std::unexpected(err);
214 });
215 }
216
217 klog::Info("Hello InterruptInit");
218}
auto trap_entry() -> void
Definition arch.cpp:46
std::expected< T, Error > Expected
std::expected 别名模板
Definition expected.hpp:365
auto GetCurrentCoreId() -> size_t
Definition cpu_io.h:26
void Pause()
Definition cpu_io.h:20
auto Err(etl::format_string< Args... > fmt, Args &&... args) -> void
以 ERROR 级别记录日志
auto Info(etl::format_string< Args... > fmt, Args &&... args) -> void
以 INFO 级别记录日志
错误类型,用于 std::expected
Definition expected.hpp:343
constexpr auto message() const -> const char *
Definition expected.hpp:358
Here is the call graph for this function:

◆ InterruptInitSMP()

auto InterruptInitSMP ( int  argc,
const char **  argv 
) -> void

从核的体系结构相关中断初始化

Parameters
argc在不同体系结构有不同含义,同 _start
argv在不同体系结构有不同含义,同 _start
Precondition
主核已完成 InterruptInit
Postcondition
从核的中断控制器已初始化

Definition at line 220 of file interrupt_main.cpp.

220 {
221 // 设置 trap vector
222 auto success =
223 cpu_io::Stvec::SetDirect(reinterpret_cast<uint64_t>(trap_entry));
224 if (!success) {
225 klog::Err("Failed to set trap vector");
226 }
227
228 // 开启 Supervisor 中断
229 cpu_io::Sstatus::Sie::Set();
230
231 // 开启内部中断
232 cpu_io::Sie::Ssie::Set();
233
234 // 开启外部中断
235 cpu_io::Sie::Seie::Set();
236
237 klog::Info("Hello InterruptInitSMP");
238}
Here is the call graph for this function: