SimpleKernel 1.17.0
Loading...
Searching...
No Matches
arch.h File Reference
#include <cpu_io.h>
#include <sys/cdefs.h>
#include <cstddef>
#include <cstdint>
Include dependency graph for arch.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

auto switch_to (cpu_io::CalleeSavedContext *prev, cpu_io::CalleeSavedContext *next) -> void
 
auto kernel_thread_entry () -> void
 
auto trap_return (void *) -> void
 
auto trap_entry () -> void
 
auto ArchInit (int argc, const char **argv) -> void
 体系结构相关初始化
 
auto ArchInitSMP (int argc, const char **argv) -> void
 从核的体系结构相关初始化
 
auto WakeUpOtherCores () -> void
 唤醒其余 core
 
auto InterruptInit (int argc, const char **argv) -> void
 体系结构相关中断初始化
 
auto InterruptInitSMP (int argc, const char **argv) -> void
 从核的体系结构相关中断初始化
 
auto TimerInit () -> void
 初始化定时器
 
auto TimerInitSMP () -> void
 从核的定时器初始化
 
auto InitTaskContext (cpu_io::CalleeSavedContext *task_context, void(*entry)(void *), void *arg, uint64_t stack_top) -> void
 初始化内核线程的任务上下文(重载1)
 
auto InitTaskContext (cpu_io::CalleeSavedContext *task_context, cpu_io::TrapContext *trap_context_ptr, uint64_t stack_top) -> void
 初始化用户线程的任务上下文(重载2)
 
__always_inline auto backtrace (void **buffer, int size) -> int
 获取调用栈
 
auto DumpStack () -> void
 打印调用栈
 

Variables

static constexpr size_t kMaxFrameCount = 128
 最多回溯 128 层调用栈
 

Function Documentation

◆ ArchInit()

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

体系结构相关初始化

Parameters
argc在不同体系结构有不同含义,同 _start
argv在不同体系结构有不同含义,同 _start
Precondition
引导程序已完成基本硬件初始化
Postcondition
架构相关硬件(串口、内存、设备树等)已初始化

Definition at line 48 of file arch_main.cpp.

48 {
49 KernelFdtSingleton::create(strtoull(argv[2], nullptr, 16));
50
51 BasicInfoSingleton::create(argc, argv);
52
53 // 解析内核 elf 信息
54 KernelElfSingleton::create(BasicInfoSingleton::instance().elf_addr);
55
56 KernelFdtSingleton::instance().CheckPSCI().or_else(
57 [](Error err) -> Expected<void> {
58 klog::Err("CheckPSCI failed: {}", err.message());
59 return {};
60 });
61
62 klog::Info("Hello aarch64 ArchInit");
63}
std::expected< T, Error > Expected
std::expected 别名模板
Definition expected.hpp:365
auto Err(etl::format_string< Args... > fmt, Args &&... args) -> void
以 ERROR 级别记录日志
auto Info(etl::format_string< Args... > fmt, Args &&... args) -> void
以 INFO 级别记录日志
#define strtoull
错误类型,用于 std::expected
Definition expected.hpp:343
constexpr auto message() const -> const char *
Definition expected.hpp:358
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ArchInitSMP()

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

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

Parameters
argc在不同体系结构有不同含义,同 _start
argv在不同体系结构有不同含义,同 _start
Precondition
主核已完成 ArchInit
Postcondition
从核的架构相关硬件已初始化

Definition at line 65 of file arch_main.cpp.

66 {}
Here is the call graph for this function:

◆ backtrace()

__always_inline auto backtrace ( void **  buffer,
int  size 
) -> int

获取调用栈

Parameters
buffer指向一个数组,该数组用于存储调用栈中的返回地址
size数组的大小,即调用栈中最多存储多少个返回地址
Returns
成功时返回实际写入数组中的地址数量,失败时返回 -1
Precondition
buffer 不为 nullptr,size > 0
Postcondition
buffer 中包含从当前帧开始的返回地址序列

◆ DumpStack()

auto DumpStack ( ) -> void

打印调用栈

Note
调用 backtrace 获取调用栈并解析符号后输出到日志

Definition at line 34 of file backtrace.cpp.

34 {
35 std::array<uint64_t, kMaxFrameCount> buffer{};
36
37 // 获取调用栈中的地址
38 auto num_frames = backtrace(buffer);
39
40 // 打印函数名
41 for (auto current_frame_idx = 0; current_frame_idx < num_frames;
42 current_frame_idx++) {
43 for (auto symtab : KernelElfSingleton::instance().symtab) {
44 if ((ELF64_ST_TYPE(symtab.st_info) == STT_FUNC) &&
45 (buffer[current_frame_idx] >= symtab.st_value) &&
46 (buffer[current_frame_idx] <= symtab.st_value + symtab.st_size)) {
47 klog::Err("[{}] {:#x}",
48 reinterpret_cast<const char*>(
49 KernelElfSingleton::instance().strtab + symtab.st_name),
50 buffer[current_frame_idx]);
51 }
52 }
53 }
54}
__always_inline auto backtrace(std::array< uint64_t, kMaxFrameCount > &buffer) -> int
Definition backtrace.cpp:18
etl::singleton< KernelElf > KernelElfSingleton
Here is the call graph for this function:
Here is the caller graph for this function:

◆ InitTaskContext() [1/2]

auto InitTaskContext ( cpu_io::CalleeSavedContext task_context,
cpu_io::TrapContext trap_context_ptr,
uint64_t  stack_top 
) -> void

初始化用户线程的任务上下文(重载2)

Parameters
task_context指向任务上下文的指针
trap_context_ptr指向 Trap 上下文的指针
stack_top内核栈顶地址
Precondition
task_context 不为 nullptr,trap_context_ptr 已填充用户态寄存器
Postcondition
task_context 已设置为经由 trap_return 返回用户态的状态
Todo:
x86_64 实现待补充

Definition at line 90 of file arch_main.cpp.

92 {
93 // 清零上下文
94 std::memset(task_context, 0, sizeof(cpu_io::CalleeSavedContext));
95
96 task_context->ReturnAddress() =
97 reinterpret_cast<uint64_t>(kernel_thread_entry);
98 task_context->EntryFunction() = reinterpret_cast<uint64_t>(trap_return);
99 task_context->EntryArgument() = reinterpret_cast<uint64_t>(trap_context_ptr);
100 task_context->StackPointer() = stack_top;
101}
auto kernel_thread_entry() -> void
Definition arch.cpp:44
auto trap_return(void *) -> void
Definition arch.cpp:45
__always_inline uint64_t & EntryFunction()
Definition cpu_io.h:208
__always_inline uint64_t & EntryArgument()
Definition cpu_io.h:209
__always_inline uint64_t & ReturnAddress()
Definition cpu_io.h:207
__always_inline uint64_t & StackPointer()
Definition cpu_io.h:210
Here is the call graph for this function:

◆ InitTaskContext() [2/2]

auto InitTaskContext ( cpu_io::CalleeSavedContext task_context,
void(*)(void *)  entry,
void *  arg,
uint64_t  stack_top 
) -> void

初始化内核线程的任务上下文(重载1)

Parameters
task_context指向任务上下文的指针
entry线程入口函数
arg传递给线程的参数
stack_top内核栈顶地址
Precondition
task_context 不为 nullptr,stack_top 已按架构要求对齐
Postcondition
task_context 已设置为可被 switch_to 恢复的状态
Todo:
x86_64 实现待补充

Definition at line 77 of file arch_main.cpp.

79 {
80 // 清零上下文
81 std::memset(task_context, 0, sizeof(cpu_io::CalleeSavedContext));
82
83 task_context->ReturnAddress() =
84 reinterpret_cast<uint64_t>(kernel_thread_entry);
85 task_context->EntryFunction() = reinterpret_cast<uint64_t>(entry);
86 task_context->EntryArgument() = reinterpret_cast<uint64_t>(arg);
87 task_context->StackPointer() = stack_top;
88}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ InterruptInit()

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

体系结构相关中断初始化

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

Definition at line 175 of file interrupt_main.cpp.

175 {
176 InterruptSingleton::create();
177
178 cpu_io::VBAR_EL1::Write(reinterpret_cast<uint64_t>(vector_table));
179
180 auto uart_intid =
181 KernelFdtSingleton::instance().GetAarch64Intid("arm,pl011").value() +
183
184 klog::Info("uart_intid: {}", uart_intid);
185
186 // 通过统一接口注册 UART 外部中断(先注册 handler,再启用 GIC SPI)
187 InterruptSingleton::instance()
188 .RegisterExternalInterrupt(uart_intid, cpu_io::GetCurrentCoreId(), 0,
189 InterruptDelegate::create<uart_handler>())
190 .or_else([](Error err) -> Expected<void> {
191 klog::Err("Failed to register UART IRQ: {}", err.message());
192 return std::unexpected(err);
193 });
194
196
197 klog::Info("Hello InterruptInit");
198}
auto vector_table() -> void
异常向量表入口
static constexpr size_t kSpiBase
Definition gic.h:25
auto GetCurrentCoreId() -> size_t
Definition cpu_io.h:26
void EnableInterrupt()
Definition cpu_io.h:34
Here is the call graph for this function:
Here is the caller graph for this function:

◆ InterruptInitSMP()

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

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

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

Definition at line 200 of file interrupt_main.cpp.

200 {
201 cpu_io::VBAR_EL1::Write(reinterpret_cast<uint64_t>(vector_table));
202
203 InterruptSingleton::instance().SetUp();
204
206
207 klog::Info("Hello InterruptInitSMP");
208}
Here is the call graph for this function:

◆ kernel_thread_entry()

auto kernel_thread_entry ( ) -> void

Definition at line 44 of file arch.cpp.

44{}
Here is the caller graph for this function:

◆ switch_to()

auto switch_to ( cpu_io::CalleeSavedContext prev_ctx,
cpu_io::CalleeSavedContext next_ctx 
)

Definition at line 15 of file arch.cpp.

16 {
17 auto* env_state =
19 assert(env_state &&
20 "TestEnvironmentState not set for current thread. "
21 "Did you forget to call SetCurrentThreadEnvironment()?");
22
23 auto& core_env = env_state->GetCurrentCoreEnv();
24
25 // 从上下文指针查找对应的任务
26 auto* prev_task = env_state->FindTaskByContext(prev_ctx);
27 auto* next_task = env_state->FindTaskByContext(next_ctx);
28
29 // 获取 PerCpu 数据
31
32 // 记录切换事件到环境层
34 event.timestamp = (per_cpu.sched_data ? per_cpu.sched_data->local_tick : 0);
35 event.from = prev_task;
36 event.to = next_task;
37 event.core_id = core_env.core_id;
38 core_env.switch_history.push_back(event);
39
40 // 更新 PerCpu 的当前线程
41 per_cpu.running_task = next_task;
42}
static auto GetCurrentThreadEnvironment() -> TestEnvironmentState *
获取当前线程的环境实例指针(供 Mock 层调用)
static __always_inline auto GetCurrentCore() -> PerCpu &
获取当前核心的 PerCpu 数据
Definition per_cpu.hpp:55
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TimerInit()

auto TimerInit ( ) -> void

初始化定时器

Precondition
InterruptInit 已完成
Postcondition
定时器中断已启用,系统 tick 开始计数

Definition at line 47 of file timer.cpp.

47 {
48 // 计算 interval
49 interval = BasicInfoSingleton::instance().interval / SIMPLEKERNEL_TICK;
50
51 // 获取定时器中断号
52 timer_intid = KernelFdtSingleton::instance()
53 .GetAarch64Intid("arm,armv8-timer")
54 .value() +
56
57 InterruptSingleton::instance().RegisterInterruptFunc(
58 timer_intid, InterruptDelegate::create<TimerHandler>());
59
60 InterruptSingleton::instance().Ppi(timer_intid, cpu_io::GetCurrentCoreId());
61
62 cpu_io::CNTV_CTL_EL0::ENABLE::Clear();
63 cpu_io::CNTV_CTL_EL0::IMASK::Set();
64
65 cpu_io::CNTV_TVAL_EL0::Write(interval);
66
67 cpu_io::CNTV_CTL_EL0::ENABLE::Set();
68 cpu_io::CNTV_CTL_EL0::IMASK::Clear();
69}
static constexpr size_t kPpiBase
Definition gic.h:23
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TimerInitSMP()

auto TimerInitSMP ( ) -> void

从核的定时器初始化

Precondition
主核已完成 TimerInit,从核已完成 InterruptInitSMP
Postcondition
从核的定时器中断已启用

Definition at line 35 of file timer.cpp.

35 {
36 InterruptSingleton::instance().Ppi(timer_intid, cpu_io::GetCurrentCoreId());
37
38 cpu_io::CNTV_CTL_EL0::ENABLE::Clear();
39 cpu_io::CNTV_CTL_EL0::IMASK::Set();
40
41 cpu_io::CNTV_TVAL_EL0::Write(interval);
42
43 cpu_io::CNTV_CTL_EL0::ENABLE::Set();
44 cpu_io::CNTV_CTL_EL0::IMASK::Clear();
45}
Here is the call graph for this function:

◆ trap_entry()

auto trap_entry ( ) -> void

Definition at line 46 of file arch.cpp.

46{}
Here is the caller graph for this function:

◆ trap_return()

auto trap_return ( void *  ) -> void

Definition at line 45 of file arch.cpp.

45{}
Here is the caller graph for this function:

◆ WakeUpOtherCores()

auto WakeUpOtherCores ( ) -> void

唤醒其余 core

Precondition
主核已完成初始化
Postcondition
所有从核开始执行 ArchInitSMP

Definition at line 68 of file arch_main.cpp.

68 {
69 for (size_t i = 0; i < BasicInfoSingleton::instance().core_count; i++) {
70 auto ret = cpu_io::psci::CpuOn(i, reinterpret_cast<uint64_t>(_boot), 0);
71 if ((ret != cpu_io::psci::SUCCESS) && (ret != cpu_io::psci::ALREADY_ON)) {
72 klog::Warn("hart {} start failed: {}", i, ret);
73 }
74 }
75}
void _boot()
内核入口,在 boot.S 中定义
auto Warn(etl::format_string< Args... > fmt, Args &&... args) -> void
以 WARN 级别记录日志
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ kMaxFrameCount

constexpr size_t kMaxFrameCount = 128
staticconstexpr

最多回溯 128 层调用栈

Definition at line 105 of file arch.h.