SimpleKernel 1.17.0
Loading...
Searching...
No Matches
Apic Class Reference

APIC 管理类,管理整个系统的 Local APIC 和 IO APIC. More...

#include <apic.h>

Collaboration diagram for Apic:
Collaboration graph

Public Member Functions

auto InitCurrentCpuLocalApic () -> Expected< void >
 初始化当前 CPU 的 Local APIC
 
auto SetIrqRedirection (uint8_t irq, uint8_t vector, uint32_t destination_apic_id, bool mask=false) -> Expected< void >
 设置 IRQ 重定向
 
auto MaskIrq (uint8_t irq) -> Expected< void >
 屏蔽 IRQ
 
auto UnmaskIrq (uint8_t irq) -> Expected< void >
 取消屏蔽 IRQ
 
auto SendIpi (uint32_t target_apic_id, uint8_t vector) const -> Expected< void >
 发送 IPI 到指定 CPU
 
auto BroadcastIpi (uint8_t vector) const -> Expected< void >
 广播 IPI 到所有其他 CPU
 
auto StartupAp (uint32_t apic_id, uint64_t ap_code_addr, size_t ap_code_size, uint64_t target_addr) const -> Expected< void >
 启动 AP (Application Processor)
 
auto StartupAllAps (uint64_t ap_code_addr, size_t ap_code_size, uint64_t target_addr) const -> void
 唤醒所有应用处理器 (AP)
 
auto SendEoi () const -> void
 发送 EOI 信号给当前 CPU 的 Local APIC
 
auto SetupPeriodicTimer (uint32_t frequency_hz, uint8_t vector) const -> void
 设置 Local APIC 定时器
 
auto PrintInfo () const -> void
 打印所有 APIC 信息(调试用)
 
构造/析构函数
 Apic (const size_t cpu_count)
 
 Apic ()=default
 
 Apic (const Apic &)=delete
 
 Apic (Apic &&)=default
 
auto operator= (const Apic &) -> Apic &=delete
 
auto operator= (Apic &&) -> Apic &=default
 
 ~Apic ()=default
 

Private Attributes

LocalApic local_apic_ {}
 Local APIC 操作接口(静态实例,用于当前 CPU)
 
IoApic io_apic_ {}
 只支持一个 IO APIC
 
size_t cpu_count_ {0}
 系统 CPU 数量
 

Detailed Description

APIC 管理类,管理整个系统的 Local APIC 和 IO APIC.

Note
在多核系统中:
  • Local APIC 是 per-CPU 的,每个核心通过 MSR 访问自己的 Local APIC
  • IO APIC 是系统级别的,通常有 1-2 个,处理外部中断

Definition at line 22 of file apic.h.

Constructor & Destructor Documentation

◆ Apic() [1/4]

Apic::Apic ( const size_t  cpu_count)
explicit

Definition at line 14 of file apic.cpp.

14 : cpu_count_(cpu_count) {
15 // 禁用传统的 8259A PIC 以避免与 APIC 冲突
16 cpu_io::Pic::Disable();
17}
size_t cpu_count_
系统 CPU 数量
Definition apic.h:133

◆ Apic() [2/4]

Apic::Apic ( )
default

◆ Apic() [3/4]

Apic::Apic ( const Apic )
delete

◆ Apic() [4/4]

Apic::Apic ( Apic &&  )
default

◆ ~Apic()

Apic::~Apic ( )
default

Member Function Documentation

◆ BroadcastIpi()

auto Apic::BroadcastIpi ( uint8_t  vector) const -> Expected<void>

广播 IPI 到所有其他 CPU

Parameters
vector中断向量
Returns
Expected<void> 广播成功返回空值,失败返回错误

Definition at line 78 of file apic.cpp.

78 {
79 return local_apic_.BroadcastIpi(vector);
80}
LocalApic local_apic_
Local APIC 操作接口(静态实例,用于当前 CPU)
Definition apic.h:127
auto BroadcastIpi(uint8_t vector) const -> Expected< void >
广播 IPI 到所有其他 CPU

◆ InitCurrentCpuLocalApic()

auto Apic::InitCurrentCpuLocalApic ( ) -> Expected<void>

初始化当前 CPU 的 Local APIC

Returns
Expected<void> 初始化成功返回空值,失败返回错误
Note
每个 CPU 核心启动时都需要调用此函数

Definition at line 19 of file apic.cpp.

19 {
20 return local_apic_.Init()
21 .and_then([]() -> Expected<void> {
23 "Local APIC initialized successfully for CPU with APIC ID {:#x}",
25 return {};
26 })
27 .or_else([](Error err) -> Expected<void> {
28 klog::Err("Failed to initialize Local APIC for current CPU: {}",
29 err.message());
30 return std::unexpected(err);
31 });
32}
auto Init() -> Expected< void >
初始化 Local APIC
std::expected< T, Error > Expected
std::expected 别名模板
Definition expected.hpp:365
auto GetCurrentCoreId() -> size_t
Definition cpu_io.h:26
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:

◆ MaskIrq()

auto Apic::MaskIrq ( uint8_t  irq) -> Expected<void>

屏蔽 IRQ

Parameters
irqIRQ 号
Returns
Expected<void> 操作成功返回空值,失败返回错误

Definition at line 49 of file apic.cpp.

49 {
50 // 检查 IRQ 是否在有效范围内
52 klog::Err("IRQ {} exceeds IO APIC range (max: {})", irq,
54 return std::unexpected(Error(ErrorCode::kApicInvalidIrq));
55 }
56
57 io_apic_.MaskIrq(irq);
58 return {};
59}
IoApic io_apic_
只支持一个 IO APIC
Definition apic.h:130
auto GetMaxRedirectionEntries() const -> uint32_t
获取 IO APIC 最大重定向条目数
Definition io_apic.cpp:83
auto MaskIrq(uint8_t irq) const -> void
屏蔽 IRQ
Definition io_apic.cpp:49
Here is the call graph for this function:

◆ operator=() [1/2]

auto Apic::operator= ( Apic &&  ) -> Apic &=default
default

◆ operator=() [2/2]

auto Apic::operator= ( const Apic ) -> Apic &=delete
delete

◆ PrintInfo()

auto Apic::PrintInfo ( ) const -> void

打印所有 APIC 信息(调试用)

Definition at line 142 of file apic.cpp.

142 {
145}
auto PrintInfo() const -> void
打印 IO APIC 信息(调试用)
Definition io_apic.cpp:88
auto PrintInfo() const -> void
打印 Local APIC 信息(调试用)
Here is the call graph for this function:

◆ SendEoi()

auto Apic::SendEoi ( ) const -> void

发送 EOI 信号给当前 CPU 的 Local APIC

Definition at line 135 of file apic.cpp.

135{ local_apic_.SendEoi(); }
auto SendEoi() const -> void
发送中断结束信号 (EOI)
Here is the call graph for this function:

◆ SendIpi()

auto Apic::SendIpi ( uint32_t  target_apic_id,
uint8_t  vector 
) const -> Expected<void>

发送 IPI 到指定 CPU

Parameters
target_apic_id目标 CPU 的 APIC ID
vector中断向量
Returns
Expected<void> 发送成功返回空值,失败返回错误

Definition at line 73 of file apic.cpp.

74 {
75 return local_apic_.SendIpi(target_apic_id, vector);
76}
auto SendIpi(uint32_t destination_apic_id, uint8_t vector) const -> Expected< void >
发送处理器间中断 (IPI)

◆ SetIrqRedirection()

auto Apic::SetIrqRedirection ( uint8_t  irq,
uint8_t  vector,
uint32_t  destination_apic_id,
bool  mask = false 
) -> Expected<void>

设置 IRQ 重定向

Parameters
irqIRQ 号
vector中断向量
destination_apic_id目标 APIC ID
mask是否屏蔽中断
Returns
Expected<void> 设置成功返回空值,失败返回错误

Definition at line 34 of file apic.cpp.

36 {
37 // 检查 IRQ 是否在有效范围内
39 klog::Err("IRQ {} exceeds IO APIC range (max: {})", irq,
41 return std::unexpected(Error(ErrorCode::kApicInvalidIrq));
42 }
43
44 // 设置重定向
45 io_apic_.SetIrqRedirection(irq, vector, destination_apic_id, mask);
46 return {};
47}
auto SetIrqRedirection(uint8_t irq, uint8_t vector, uint32_t destination_apic_id, bool mask=false) const -> void
设置 IO APIC 重定向表项
Definition io_apic.cpp:22
Here is the call graph for this function:

◆ SetupPeriodicTimer()

auto Apic::SetupPeriodicTimer ( uint32_t  frequency_hz,
uint8_t  vector 
) const -> void

设置 Local APIC 定时器

Parameters
frequency_hz定时器频率(Hz)
vector中断向量号

Definition at line 137 of file apic.cpp.

138 {
139 local_apic_.SetupPeriodicTimer(frequency_hz, vector);
140}
auto SetupPeriodicTimer(uint32_t frequency_hz, uint8_t vector) const -> void
设置周期性定时器

◆ StartupAllAps()

auto Apic::StartupAllAps ( uint64_t  ap_code_addr,
size_t  ap_code_size,
uint64_t  target_addr 
) const -> void

唤醒所有应用处理器 (AP)

Parameters
ap_code_addrAP 启动代码的虚拟地址
ap_code_sizeAP 启动代码的大小
target_addrAP 代码要复制到的目标物理地址
Note
此方法会尝试唤醒除当前 BSP 外的所有 CPU 核心
函数内部会将启动代码复制到指定的目标地址,并计算 start_vector

Definition at line 110 of file apic.cpp.

111 {
112 assert(ap_code_addr != 0 && "AP code address must not be null");
113 assert(ap_code_size != 0 && "AP code size must not be zero");
114 assert((target_addr & 0xFFF) == 0 && "Target address must be 4KB aligned");
115 assert(target_addr < 0x100000 &&
116 "Target address exceeds real mode limit (1MB)");
117
118 // 启动 APIC ID 0 到 cpu_count_-1 的所有处理器
119 // 跳过当前的 BSP (Bootstrap Processor)
120 for (size_t apic_id = 0; apic_id < cpu_count_; apic_id++) {
121 // 跳过当前 BSP
122 if (static_cast<uint32_t>(apic_id) == cpu_io::GetCurrentCoreId()) {
123 continue;
124 }
125 StartupAp(static_cast<uint32_t>(apic_id), ap_code_addr, ap_code_size,
126 target_addr)
127 .or_else([apic_id](Error err) -> Expected<void> {
128 klog::Err("Failed to start AP with APIC ID {:#x}: {}", apic_id,
129 err.message());
130 return std::unexpected(err);
131 });
132 }
133}
auto StartupAp(uint32_t apic_id, uint64_t ap_code_addr, size_t ap_code_size, uint64_t target_addr) const -> Expected< void >
启动 AP (Application Processor)
Definition apic.cpp:82
Here is the call graph for this function:

◆ StartupAp()

auto Apic::StartupAp ( uint32_t  apic_id,
uint64_t  ap_code_addr,
size_t  ap_code_size,
uint64_t  target_addr 
) const -> Expected<void>

启动 AP (Application Processor)

Parameters
apic_id目标 APIC ID
ap_code_addrAP 启动代码的虚拟地址
ap_code_sizeAP 启动代码的大小
target_addrAP 代码要复制到的目标物理地址
Returns
Expected<void> 启动成功返回空值,失败返回错误
Note
函数内部会将启动代码复制到指定的目标地址,并计算 start_vector

Definition at line 82 of file apic.cpp.

84 {
85 assert(ap_code_addr != 0 && "AP code address must not be null");
86 assert(ap_code_size != 0 && "AP code size must not be zero");
87 assert((target_addr & 0xFFF) == 0 && "Target address must be 4KB aligned");
88 assert(target_addr < 0x100000 &&
89 "Target address exceeds real mode limit (1MB)");
90
91 std::memcpy(reinterpret_cast<void*>(target_addr),
92 reinterpret_cast<void*>(ap_code_addr), ap_code_size);
93
94 // 验证复制是否成功
95 if (std::memcmp(reinterpret_cast<const void*>(target_addr),
96 reinterpret_cast<const void*>(ap_code_addr),
97 ap_code_size) != 0) {
98 klog::Err("AP code copy verification failed");
99 return std::unexpected(Error(ErrorCode::kApicCodeCopyFailed));
100 }
101
102 // 计算启动向量 (物理地址 / 4096)
103 auto start_vector = static_cast<uint8_t>(target_addr >> 12);
104 // 使用 Local APIC 发送 INIT-SIPI-SIPI 序列
105 local_apic_.WakeupAp(apic_id, start_vector);
106
107 return {};
108}
auto WakeupAp(uint32_t destination_apic_id, uint8_t start_vector) const -> void
唤醒应用处理器 (AP)
@ kApicCodeCopyFailed
Here is the call graph for this function:

◆ UnmaskIrq()

auto Apic::UnmaskIrq ( uint8_t  irq) -> Expected<void>

取消屏蔽 IRQ

Parameters
irqIRQ 号
Returns
Expected<void> 操作成功返回空值,失败返回错误

Definition at line 61 of file apic.cpp.

61 {
62 // 检查 IRQ 是否在有效范围内
64 klog::Err("IRQ {} exceeds IO APIC range (max: {})", irq,
66 return std::unexpected(Error(ErrorCode::kApicInvalidIrq));
67 }
68
70 return {};
71}
auto UnmaskIrq(uint8_t irq) const -> void
取消屏蔽 IRQ
Definition io_apic.cpp:61
Here is the call graph for this function:

Member Data Documentation

◆ cpu_count_

size_t Apic::cpu_count_ {0}
private

系统 CPU 数量

Definition at line 133 of file apic.h.

133{0};

◆ io_apic_

IoApic Apic::io_apic_ {}
private

只支持一个 IO APIC

Definition at line 130 of file apic.h.

130{};

◆ local_apic_

LocalApic Apic::local_apic_ {}
private

Local APIC 操作接口(静态实例,用于当前 CPU)

Definition at line 127 of file apic.h.

127{};

The documentation for this class was generated from the following files: