| 25 | } // namespace |
| 26 | |
| 27 | Interrupt::Interrupt() { |
| 28 | auto [dist_base_addr, dist_size, redist_base_addr, redist_size] = |
| 29 | KernelFdtSingleton::instance().GetGIC().value(); |
| 30 | VirtualMemorySingleton::instance() |
| 31 | .MapMMIO(dist_base_addr, dist_size) |
| 32 | .or_else([](Error err) -> Expected<void*> { |
| 33 | klog::Err("Failed to map GIC distributor MMIO: {}", err.message()); |
| 34 | while (true) { |
| 35 | cpu_io::Pause(); |
| 36 | } |
| 37 | return std::unexpected(err); |
| 38 | }); |
| 39 | VirtualMemorySingleton::instance() |
| 40 | .MapMMIO(redist_base_addr, redist_size) |
| 41 | .or_else([](Error err) -> Expected<void*> { |
| 42 | klog::Err("Failed to map GIC redistributor MMIO: {}", err.message()); |
| 43 | while (true) { |
| 44 | cpu_io::Pause(); |
| 45 | } |
| 46 | return std::unexpected(err); |
| 47 | }); |
| 48 | |
| 49 | gic_ = std::move(Gic(dist_base_addr, redist_base_addr)); |
| 50 | |
| 51 | // 注册默认中断处理函数 |
| 52 | for (auto& i : interrupt_handlers_) { |
| 53 | i = InterruptDelegate::create<DefaultInterruptHandler>(); |
| 54 | } |
| 55 | |
| 56 | // 设置 SGI 0 用于 IPI |
| 57 | auto cpuid = cpu_io::GetCurrentCoreId(); |
| 58 | gic_.Sgi(0, cpuid); |
| 59 | |
| 60 | klog::Info("Interrupt init."); |
| 61 | } |
| 62 | |
| 63 | auto Interrupt::Do(uint64_t cause, cpu_io::TrapContext* context) -> void { |
| 64 | cpu_io::ICC_EOIR1_EL1::Write(cause); |