SimpleKernel 1.17.0
Loading...
Searching...
No Matches
cpu_io.h
Go to the documentation of this file.
1
5#ifndef SIMPLEKERNEL_TESTS_UNIT_TEST_MOCKS_CPU_IO_H_
6#define SIMPLEKERNEL_TESTS_UNIT_TEST_MOCKS_CPU_IO_H_
7
8#include <atomic>
9#include <cassert>
10#include <cstddef>
11#include <cstdint>
12#include <mutex>
13#include <thread>
14#include <unordered_map>
15
17
18namespace cpu_io {
19
20inline void Pause() {
21 // 在单元测试中使用 yield 避免死循环
22 std::this_thread::yield();
23}
24
25// 使用线程 ID 映射到核心 ID(用于测试多核场景)
26inline auto GetCurrentCoreId() -> size_t {
28 assert(env &&
29 "TestEnvironmentState not set for current thread. "
30 "Did you forget to call SetCurrentThreadEnvironment()?");
31 return env->GetCoreIdForThread(std::this_thread::get_id());
32}
33
34inline void EnableInterrupt() {
36 assert(env && "TestEnvironmentState not set for current thread");
37 auto& core = env->GetCurrentCoreEnv();
38 core.interrupt_enabled = true;
39}
40
41inline void DisableInterrupt() {
43 assert(env && "TestEnvironmentState not set for current thread");
44 auto& core = env->GetCurrentCoreEnv();
45 core.interrupt_enabled = false;
46}
47
48inline bool GetInterruptStatus() {
50 assert(env && "TestEnvironmentState not set for current thread");
51 auto& core = env->GetCurrentCoreEnv();
52 return core.interrupt_enabled;
53}
54
55// Memory barrier stubs for unit testing
56inline void Mb() {}
57inline void Rmb() {}
58inline void Wmb() {}
59
60namespace virtual_memory {
61
62// 页大小常量
63static constexpr size_t kPageSize = 4096;
64static constexpr size_t kPteAttributeBits = 12;
65static constexpr size_t kPageOffsetBits = 12;
66static constexpr size_t kVpnBits = 9;
67static constexpr size_t kVpnMask = 0x1FF;
68static constexpr size_t kPageTableLevels = 4;
69
70// 页表项权限位定义
71static constexpr uint64_t kValid = 0x1;
72static constexpr uint64_t kWrite = 0x2;
73static constexpr uint64_t kUser = 0x4;
74static constexpr uint64_t kRead = 0x200;
75static constexpr uint64_t kExec = 0x400;
76static constexpr uint64_t kGlobal = 0x100;
77
78// 获取用户页面权限
79inline auto GetUserPagePermissions(bool readable = true, bool writable = false,
80 bool executable = false, bool global = false)
81 -> uint64_t {
82 uint64_t flags = kValid | kUser;
83 if (readable) {
84 flags |= kRead;
85 }
86 if (writable) {
87 flags |= kWrite;
88 }
89 if (executable) {
90 flags |= kExec;
91 }
92 if (global) {
93 flags |= kGlobal;
94 }
95 return flags;
96}
97
98// 获取内核页面权限
99inline auto GetKernelPagePermissions(bool readable = true,
100 bool writable = false,
101 bool executable = false,
102 bool global = false) -> uint64_t {
103 uint64_t flags = kValid; // Kernel pages don't need kUser
104 if (readable) {
105 flags |= kRead;
106 }
107 if (writable) {
108 flags |= kWrite;
109 }
110 if (executable) {
111 flags |= kExec;
112 }
113 if (global) {
114 flags |= kGlobal;
115 }
116 return flags;
117}
118
119// 页表操作函数
120inline void SetPageDirectory(uint64_t pd) {
122 assert(env && "TestEnvironmentState not set for current thread");
123 auto& core = env->GetCurrentCoreEnv();
124 core.page_directory = pd;
125}
126
127inline auto GetPageDirectory() -> uint64_t {
129 assert(env && "TestEnvironmentState not set for current thread");
130 auto& core = env->GetCurrentCoreEnv();
131 return core.page_directory;
132}
133
134inline void EnablePage() {
136 assert(env && "TestEnvironmentState not set for current thread");
137 auto& core = env->GetCurrentCoreEnv();
138 core.paging_enabled = true;
139}
140
141inline void FlushTLBAll() {
142 // 在测试环境中不需要实际操作
143}
144
145// 获取页表项权限
146inline auto GetTableEntryPermissions() -> uint64_t {
147 return kValid | kWrite | kUser | kRead | kExec;
148}
149
150// 获取虚拟页号
151inline auto GetVirtualPageNumber(uint64_t virtual_addr, size_t level)
152 -> uint64_t {
153 return (virtual_addr >> (kPageOffsetBits + level * kVpnBits)) & kVpnMask;
154}
155
156// 页对齐函数
157inline auto PageAlign(uint64_t addr) -> uint64_t {
158 return addr & ~(kPageSize - 1);
159}
160
161inline auto PageAlignUp(uint64_t addr) -> uint64_t {
162 return (addr + kPageSize - 1) & ~(kPageSize - 1);
163}
164
165inline auto IsPageAligned(uint64_t addr) -> bool {
166 return (addr & (kPageSize - 1)) == 0;
167}
168
169// 页表项操作函数
170inline auto IsPageTableEntryValid(uint64_t pte) -> bool {
171 return (pte & kValid) != 0;
172}
173
174inline auto PageTableEntryToPhysical(uint64_t pte) -> uint64_t {
175 return pte & 0x000FFFFFFFFFF000ULL;
176}
177
178inline auto PhysicalToPageTableEntry(uint64_t physical_addr, uint64_t flags)
179 -> uint64_t {
180 return (physical_addr & 0x000FFFFFFFFFF000ULL) | (flags & 0xFFF) |
181 (flags & (1ULL << 63));
182}
183
184} // namespace virtual_memory
185
187 uint64_t sp;
188 uint64_t a0;
189 uint64_t tp;
190
191 uint64_t padding[61];
192
193 // 统一的跨架构访问器方法
194 __always_inline uint64_t& UserStackPointer() { return sp; }
195 __always_inline uint64_t& ThreadPointer() { return tp; }
196 __always_inline uint64_t& ReturnValue() { return a0; }
197};
198
200 uint64_t ra;
201 uint64_t sp;
202 uint64_t s0;
203 uint64_t s1;
204
205 uint64_t padding[18];
206
207 __always_inline uint64_t& ReturnAddress() { return ra; }
208 __always_inline uint64_t& EntryFunction() { return s0; }
209 __always_inline uint64_t& EntryArgument() { return s1; }
210 __always_inline uint64_t& StackPointer() { return sp; }
211};
212
213} // namespace cpu_io
214
215#endif /* SIMPLEKERNEL_TESTS_UNIT_TEST_MOCKS_CPU_IO_H_ */
static auto GetCurrentThreadEnvironment() -> TestEnvironmentState *
获取当前线程的环境实例指针(供 Mock 层调用)
static constexpr uint64_t kValid
Definition cpu_io.h:71
static constexpr size_t kVpnMask
Definition cpu_io.h:67
static constexpr size_t kPageSize
Definition cpu_io.h:63
static constexpr uint64_t kGlobal
Definition cpu_io.h:76
void SetPageDirectory(uint64_t pd)
Definition cpu_io.h:120
static constexpr size_t kPteAttributeBits
Definition cpu_io.h:64
auto IsPageAligned(uint64_t addr) -> bool
Definition cpu_io.h:165
auto GetVirtualPageNumber(uint64_t virtual_addr, size_t level) -> uint64_t
Definition cpu_io.h:151
auto PageTableEntryToPhysical(uint64_t pte) -> uint64_t
Definition cpu_io.h:174
static constexpr uint64_t kUser
Definition cpu_io.h:73
static constexpr uint64_t kRead
Definition cpu_io.h:74
auto PageAlign(uint64_t addr) -> uint64_t
Definition cpu_io.h:157
auto IsPageTableEntryValid(uint64_t pte) -> bool
Definition cpu_io.h:170
auto GetTableEntryPermissions() -> uint64_t
Definition cpu_io.h:146
static constexpr uint64_t kWrite
Definition cpu_io.h:72
static constexpr size_t kPageTableLevels
Definition cpu_io.h:68
static constexpr size_t kPageOffsetBits
Definition cpu_io.h:65
auto GetKernelPagePermissions(bool readable=true, bool writable=false, bool executable=false, bool global=false) -> uint64_t
Definition cpu_io.h:99
auto GetPageDirectory() -> uint64_t
Definition cpu_io.h:127
static constexpr uint64_t kExec
Definition cpu_io.h:75
static constexpr size_t kVpnBits
Definition cpu_io.h:66
auto GetUserPagePermissions(bool readable=true, bool writable=false, bool executable=false, bool global=false) -> uint64_t
Definition cpu_io.h:79
auto PhysicalToPageTableEntry(uint64_t physical_addr, uint64_t flags) -> uint64_t
Definition cpu_io.h:178
auto PageAlignUp(uint64_t addr) -> uint64_t
Definition cpu_io.h:161
void Wmb()
Definition cpu_io.h:58
auto GetCurrentCoreId() -> size_t
Definition cpu_io.h:26
void DisableInterrupt()
Definition cpu_io.h:41
bool GetInterruptStatus()
Definition cpu_io.h:48
void Mb()
Definition cpu_io.h:56
void Rmb()
Definition cpu_io.h:57
void Pause()
Definition cpu_io.h:20
void EnableInterrupt()
Definition cpu_io.h:34
__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
__always_inline uint64_t & ReturnValue()
Definition cpu_io.h:196
__always_inline uint64_t & ThreadPointer()
Definition cpu_io.h:195
__always_inline uint64_t & UserStackPointer()
Definition cpu_io.h:194
uint64_t padding[61]
Definition cpu_io.h:191