|
27 | 27 | #include "sk_cstdio"
|
28 | 28 | #include "sk_iostream"
|
29 | 29 |
|
| 30 | +namespace cpu { |
| 31 | +namespace vmm { |
| 32 | +enum { |
| 33 | + VALID_OFFSET = 0, |
| 34 | + READ_OFFSET = 1, |
| 35 | + WRITE_OFFSET = 2, |
| 36 | + EXEC_OFFSET = 3, |
| 37 | + USER_OFFSET = 4, |
| 38 | + GLOBAL_OFFSET = 5, |
| 39 | + ACCESSED_OFFSET = 6, |
| 40 | + DIRTY_OFFSET = 7, |
| 41 | + VALID = 1 << VALID_OFFSET, |
| 42 | + READ = 1 << READ_OFFSET, |
| 43 | + WRITE = 1 << WRITE_OFFSET, |
| 44 | + EXEC = 1 << EXEC_OFFSET, |
| 45 | + USER = 1 << USER_OFFSET, |
| 46 | + GLOBAL = 1 << GLOBAL_OFFSET, |
| 47 | + ACCESSED = 1 << ACCESSED_OFFSET, |
| 48 | + DIRTY = 1 << DIRTY_OFFSET, |
| 49 | +}; |
| 50 | +/// 有效位 |
| 51 | +static constexpr const uint8_t VMM_PAGE_VALID = VALID; |
| 52 | +/// 可读位 |
| 53 | +static constexpr const uint8_t VMM_PAGE_READABLE = READ; |
| 54 | +/// 可写位s |
| 55 | +static constexpr const uint8_t VMM_PAGE_WRITABLE = WRITE; |
| 56 | +/// 可执行位 |
| 57 | +static constexpr const uint8_t VMM_PAGE_EXECUTABLE = EXEC; |
| 58 | +/// 用户位 |
| 59 | +static constexpr const uint8_t VMM_PAGE_USER = USER; |
| 60 | +/// 全局位,我们不会使用 |
| 61 | +static constexpr const uint8_t VMM_PAGE_GLOBAL = GLOBAL; |
| 62 | +/// 已使用位,用于替换算法 |
| 63 | +static constexpr const uint8_t VMM_PAGE_ACCESSED = ACCESSED; |
| 64 | +/// 已修改位,用于替换算法 |
| 65 | +static constexpr const uint8_t VMM_PAGE_DIRTY = DIRTY; |
| 66 | +/// 内核虚拟地址相对物理地址的偏移 |
| 67 | +static constexpr const size_t KERNEL_OFFSET = 0x0; |
| 68 | +/// PTE 属性位数 |
| 69 | +static constexpr const size_t VMM_PTE_PROP_BITS = 10; |
| 70 | +/// PTE 页内偏移位数 |
| 71 | +static constexpr const size_t VMM_PAGE_OFF_BITS = 12; |
| 72 | +/// VPN 位数 |
| 73 | +static constexpr const size_t VMM_VPN_BITS = 9; |
| 74 | +/// VPN 位数掩码,9 位 VPN |
| 75 | +static constexpr const size_t VMM_VPN_BITS_MASK = 0x1FF; |
| 76 | +/// riscv64 使用了三级页表 |
| 77 | +static constexpr const size_t VMM_PT_LEVEL = 3; |
| 78 | + |
| 79 | +// 开启 PG |
| 80 | +inline void EnablePage() { |
| 81 | + kAllCsr.satp.asid.Write(0); |
| 82 | + kAllCsr.satp.mode.Write(register_info::csr::SatpInfo::kSv39); |
| 83 | +} |
| 84 | +inline void DisablePage() { |
| 85 | + kAllCsr.satp.mode.Write(register_info::csr::SatpInfo::kBare); |
| 86 | +} |
| 87 | + |
| 88 | +/** |
| 89 | + * @brief 设置 页目录 |
| 90 | + * @param _pgd 要设置的页表 |
| 91 | + * @return true 成功 |
| 92 | + * @return false 失败 |
| 93 | + */ |
| 94 | +inline void SetPageDirectory(uint64_t pgd) { kAllCsr.satp.ppn.Write(pgd); } |
| 95 | + |
| 96 | +/** |
| 97 | + * @brief 获取页目录 |
| 98 | + * @return uint64_t 页目录值 |
| 99 | + */ |
| 100 | +inline uint64_t GetPageDirectory() { return kAllCsr.satp.ppn.Get(); } |
| 101 | + |
| 102 | +inline void FlushPage(uint64_t addr) { |
| 103 | + (void)addr; |
| 104 | + __asm__ volatile("sfence.vma zero, zero"); |
| 105 | +} |
| 106 | + |
| 107 | +} // namespace vmm |
| 108 | +} // namespace cpu |
| 109 | + |
30 | 110 | #endif // SIMPLEKERNEL_SRC_KERNEL_ARCH_RISCV64_INCLUDE_CPU_CPU_HPP_
|
0 commit comments