diff --git a/src/kernel/arch/aarch64/backtrace.cpp b/src/kernel/arch/aarch64/backtrace.cpp index 30d1741cc..d1233305d 100644 --- a/src/kernel/arch/aarch64/backtrace.cpp +++ b/src/kernel/arch/aarch64/backtrace.cpp @@ -14,9 +14,9 @@ */ #include "arch.h" -#include "cpu.hpp" -#include "sk_cstdio" +#include "cpu/cpu.hpp" #include "kernel_elf.hpp" +#include "sk_cstdio" #include "sk_libc.h" int backtrace(void **buffer, int size) { diff --git a/src/kernel/arch/aarch64/include/cpu/cpu.hpp b/src/kernel/arch/aarch64/include/cpu/cpu.hpp new file mode 100644 index 000000000..0650d97d9 --- /dev/null +++ b/src/kernel/arch/aarch64/include/cpu/cpu.hpp @@ -0,0 +1,30 @@ + +/** + * @file cpu.hpp + * @brief aarch64 cpu 相关定义 + * @author Zone.N (Zone.Niuzh@hotmail.com) + * @version 1.0 + * @date 2024-03-05 + * @copyright MIT LICENSE + * https://github.com/Simple-XX/SimpleKernel + * @par change log: + * + *
DateAuthorDescription + *
2024-03-05Zone.N (Zone.Niuzh@hotmail.com)创建文件 + *
+ */ + +#ifndef SIMPLEKERNEL_SRC_KERNEL_ARCH_AARCH64_INCLUDE_CPU_CPU_HPP_ +#define SIMPLEKERNEL_SRC_KERNEL_ARCH_AARCH64_INCLUDE_CPU_CPU_HPP_ + +#include +#include +#include +#include + +#include "kernel_log.hpp" +#include "sk_cstdio" +#include "sk_iostream" +#include "sr.hpp" + +#endif // SIMPLEKERNEL_SRC_KERNEL_ARCH_AARCH64_INCLUDE_CPU_CPU_HPP_ diff --git a/src/kernel/arch/aarch64/include/cpu.hpp b/src/kernel/arch/aarch64/include/cpu/sr.hpp similarity index 86% rename from src/kernel/arch/aarch64/include/cpu.hpp rename to src/kernel/arch/aarch64/include/cpu/sr.hpp index f0e740793..eccd8a7ae 100644 --- a/src/kernel/arch/aarch64/include/cpu.hpp +++ b/src/kernel/arch/aarch64/include/cpu/sr.hpp @@ -1,7 +1,7 @@ /** - * @file cpu.hpp - * @brief aarch64 cpu 相关定义 + * @file sr.hpp + * @brief aarch64 sr 相关定义 * @author Zone.N (Zone.Niuzh@hotmail.com) * @version 1.0 * @date 2024-03-05 @@ -14,17 +14,17 @@ * */ -#ifndef SIMPLEKERNEL_SRC_KERNEL_ARCH_AARCH64_INCLUDE_CPU_HPP_ -#define SIMPLEKERNEL_SRC_KERNEL_ARCH_AARCH64_INCLUDE_CPU_HPP_ +#ifndef SIMPLEKERNEL_SRC_KERNEL_ARCH_AARCH64_INCLUDE_CPU_SR_HPP_ +#define SIMPLEKERNEL_SRC_KERNEL_ARCH_AARCH64_INCLUDE_CPU_SR_HPP_ #include #include #include #include +#include "kernel_log.hpp" #include "sk_cstdio" #include "sk_iostream" -#include "kernel_log.hpp" /** * aarch64 cpu 相关定义 @@ -33,7 +33,7 @@ namespace cpu { // 第一部分:寄存器定义 -namespace reginfo { +namespace register_info { struct RegInfoBase { /// 寄存器数据类型 @@ -53,7 +53,7 @@ struct RegInfoBase { /// 通用寄存器 struct X29Info : public RegInfoBase {}; -}; // namespace reginfo +}; // namespace register_info // 第二部分:读/写模版实现 namespace { @@ -80,10 +80,10 @@ class ReadOnlyRegBase { */ static __always_inline RegInfo::DataType Read() { typename RegInfo::DataType value{}; - if constexpr (std::is_same::value) { + if constexpr (std::is_same::value) { __asm__ volatile("mov %0, x29" : "=r"(value) : :); } else { - log::Err("No Type\n"); + klog::Err("No Type\n"); throw; } return value; @@ -117,10 +117,10 @@ class WriteOnlyRegBase { * @param value 要写的值 */ static __always_inline void Write(RegInfo::DataType value) { - if constexpr (std::is_same::value) { + if constexpr (std::is_same::value) { __asm__ volatile("mv fp, %0" : : "r"(value) :); } else { - log::Err("No Type\n"); + klog::Err("No Type\n"); throw; } } @@ -146,7 +146,7 @@ class ReadWriteRegBase : public ReadOnlyRegBase, }; // 第三部分:寄存器实例 -class X29 : public ReadWriteRegBase { +class X29 : public ReadWriteRegBase { public: friend sk_std::ostream &operator<<(sk_std::ostream &os, const X29 &x29) { printf("val: 0x%p", (void *)x29.Read()); @@ -166,4 +166,4 @@ struct AllXreg { }; // namespace cpu -#endif // SIMPLEKERNEL_SRC_KERNEL_ARCH_AARCH64_INCLUDE_CPU_HPP_ +#endif // SIMPLEKERNEL_SRC_KERNEL_ARCH_AARCH64_INCLUDE_CPU_SR_HPP_ diff --git a/src/kernel/arch/aarch64/interrupt.cpp b/src/kernel/arch/aarch64/interrupt.cpp index aad7ae143..b4fea79d4 100644 --- a/src/kernel/arch/aarch64/interrupt.cpp +++ b/src/kernel/arch/aarch64/interrupt.cpp @@ -15,10 +15,10 @@ #include "interrupt.h" -#include "cstdio" #include "kernel_log.hpp" +#include "sk_cstdio" -Interrupt::Interrupt() { Info("Interrupt init.\n"); } +Interrupt::Interrupt() { klog::Info("Interrupt init.\n"); } void Interrupt::Do(uint64_t cause, uint8_t *context) { (void)cause; @@ -31,7 +31,7 @@ void Interrupt::RegisterInterruptFunc(uint64_t cause, InterruptFunc func) { } uint32_t InterruptInit(uint32_t, uint8_t *) { - Info("Hello InterruptInit\n"); + klog::Info("Hello InterruptInit\n"); return 0; } diff --git a/src/kernel/arch/aarch64/interrupt.h b/src/kernel/arch/aarch64/interrupt.h index 9cc8277c0..cf03a83a1 100644 --- a/src/kernel/arch/aarch64/interrupt.h +++ b/src/kernel/arch/aarch64/interrupt.h @@ -19,10 +19,10 @@ #include -#include "cpu.hpp" +#include "cpu/cpu.hpp" #include "interrupt_base.h" #include "singleton.hpp" -#include "stdio.h" +#include "sk_stdio.h" class Interrupt final : public InterruptBase { public: diff --git a/src/kernel/arch/riscv64/arch_main.cpp b/src/kernel/arch/riscv64/arch_main.cpp index 1cbe6e87f..57f692e02 100644 --- a/src/kernel/arch/riscv64/arch_main.cpp +++ b/src/kernel/arch/riscv64/arch_main.cpp @@ -16,7 +16,7 @@ #include #include "basic_info.hpp" -#include "cpu.hpp" +#include "cpu/cpu.hpp" #include "kernel_elf.hpp" #include "kernel_fdt.hpp" #include "ns16550a.h" @@ -78,7 +78,7 @@ uint32_t ArchInit(uint32_t argc, uint8_t *argv) { // 解析内核 elf 信息 kKernelElf.GetInstance() = KernelElf(); - log::Info("Hello riscv64 ArchInit\n"); + klog::Info("Hello riscv64 ArchInit\n"); return 0; } diff --git a/src/kernel/arch/riscv64/backtrace.cpp b/src/kernel/arch/riscv64/backtrace.cpp index 529188a9f..9aac9952a 100644 --- a/src/kernel/arch/riscv64/backtrace.cpp +++ b/src/kernel/arch/riscv64/backtrace.cpp @@ -15,10 +15,10 @@ */ #include "arch.h" -#include "cpu.hpp" -#include "sk_cstdio" +#include "cpu/cpu.hpp" #include "kernel_elf.hpp" #include "kernel_fdt.hpp" +#include "sk_cstdio" #include "sk_libc.h" int backtrace(void **buffer, int size) { diff --git a/src/kernel/arch/riscv64/include/cpu/cpu.hpp b/src/kernel/arch/riscv64/include/cpu/cpu.hpp new file mode 100644 index 000000000..88f27f727 --- /dev/null +++ b/src/kernel/arch/riscv64/include/cpu/cpu.hpp @@ -0,0 +1,30 @@ + +/** + * @file cpu.hpp + * @brief riscv64 cpu 相关定义 + * @author Zone.N (Zone.Niuzh@hotmail.com) + * @version 1.0 + * @date 2024-03-05 + * @copyright MIT LICENSE + * https://github.com/Simple-XX/SimpleKernel + * @par change log: + * + *
DateAuthorDescription + *
2024-03-05Zone.N (Zone.Niuzh@hotmail.com)创建文件 + *
+ */ + +#ifndef SIMPLEKERNEL_SRC_KERNEL_ARCH_RISCV64_INCLUDE_CPU_CPU_HPP_ +#define SIMPLEKERNEL_SRC_KERNEL_ARCH_RISCV64_INCLUDE_CPU_CPU_HPP_ + +#include +#include +#include +#include + +#include "csr.hpp" +#include "kernel_log.hpp" +#include "sk_cstdio" +#include "sk_iostream" + +#endif // SIMPLEKERNEL_SRC_KERNEL_ARCH_RISCV64_INCLUDE_CPU_CPU_HPP_ diff --git a/src/kernel/arch/riscv64/include/cpu.hpp b/src/kernel/arch/riscv64/include/cpu/csr.hpp similarity index 70% rename from src/kernel/arch/riscv64/include/cpu.hpp rename to src/kernel/arch/riscv64/include/cpu/csr.hpp index 634f478bb..7ac8e68ca 100644 --- a/src/kernel/arch/riscv64/include/cpu.hpp +++ b/src/kernel/arch/riscv64/include/cpu/csr.hpp @@ -1,7 +1,7 @@ /** - * @file cpu.hpp - * @brief riscv64 cpu 相关定义 + * @file csr.hpp + * @brief riscv64 csr 相关定义 * @author Zone.N (Zone.Niuzh@hotmail.com) * @version 1.0 * @date 2024-03-05 @@ -14,8 +14,8 @@ * */ -#ifndef SIMPLEKERNEL_SRC_KERNEL_ARCH_RISCV64_INCLUDE_CPU_HPP_ -#define SIMPLEKERNEL_SRC_KERNEL_ARCH_RISCV64_INCLUDE_CPU_HPP_ +#ifndef SIMPLEKERNEL_SRC_KERNEL_ARCH_RISCV64_INCLUDE_CPU_CSR_HPP_ +#define SIMPLEKERNEL_SRC_KERNEL_ARCH_RISCV64_INCLUDE_CPU_CSR_HPP_ #include #include @@ -27,7 +27,7 @@ #include "sk_iostream" /** - * riscv64 cpu 相关定义 + * riscv64 cpu Control and Status Registers 相关定义 * @note 寄存器读写设计见 arch/README.md * @see priv-isa.pdf * https://github.com/riscv/riscv-isa-manual/releases/tag/20240411/priv-isa-asciidoc.pdf @@ -39,7 +39,7 @@ namespace cpu { // 第一部分:寄存器定义 -namespace reginfo { +namespace register_info { struct RegInfoBase { /// 寄存器数据类型 @@ -384,7 +384,7 @@ struct StimecmpInfo : public RegInfoBase {}; }; // namespace csr -}; // namespace reginfo +}; // namespace register_info // 第二部分:读/写模版实现 namespace { @@ -411,44 +411,51 @@ class ReadOnlyRegBase { */ static __always_inline RegInfo::DataType Read() { typename RegInfo::DataType value{}; - if constexpr (std::is_same::value) { + if constexpr (std::is_same::value) { __asm__ volatile("mv %0, fp" : "=r"(value) : :); } else if constexpr (std::is_same::value) { + register_info::csr::SstatusInfo>::value) { __asm__ volatile("csrr %0, sstatus" : "=r"(value) : :); } else if constexpr (std::is_same::value) { + register_info::csr::StvecInfo>::value) { __asm__ volatile("csrr %0, stvec" : "=r"(value) : :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrr %0, sip" : "=r"(value) : :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrr %0, sie" : "=r"(value) : :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrr %0, time" : "=r"(value) : :); } else if constexpr (std::is_same::value) { + register_info::csr::CycleInfo>::value) { __asm__ volatile("csrr %0, cycle" : "=r"(value) : :); } else if constexpr (std::is_same::value) { + register_info::csr::InstretInfo>::value) { __asm__ volatile("csrr %0, instret" : "=r"(value) : :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same< + RegInfo, + register_info::csr::SscratchInfo>::value) { __asm__ volatile("csrr %0, sscratch" : "=r"(value) : :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrr %0, sepc" : "=r"(value) : :); } else if constexpr (std::is_same::value) { + register_info::csr::ScauseInfo>::value) { __asm__ volatile("csrr %0, scause" : "=r"(value) : :); } else if constexpr (std::is_same::value) { + register_info::csr::StvalInfo>::value) { __asm__ volatile("csrr %0, stval" : "=r"(value) : :); - } else if constexpr (std::is_same::value) { - __asm__ volatile("csrr %0, satp" : "=r"(value) : :); } else if constexpr (std::is_same::value) { + register_info::csr::SatpInfo>::value) { + __asm__ volatile("csrr %0, satp" : "=r"(value) : :); + } else if constexpr (std::is_same< + RegInfo, + register_info::csr::StimecmpInfo>::value) { __asm__ volatile("csrr %0, stimecmp" : "=r"(value) : :); } else { - log::Err("No Type\n"); + klog::Err("No Type\n"); throw; } return value; @@ -482,33 +489,38 @@ class WriteOnlyRegBase { * @param value 要写的值 */ static __always_inline void Write(RegInfo::DataType value) { - if constexpr (std::is_same::value) { + if constexpr (std::is_same::value) { __asm__ volatile("mv fp, %0" : : "r"(value) :); } else if constexpr (std::is_same::value) { + register_info::csr::SstatusInfo>::value) { __asm__ volatile("csrw sstatus, %0" : : "r"(value) :); } else if constexpr (std::is_same::value) { + register_info::csr::StvecInfo>::value) { __asm__ volatile("csrw stvec, %0" : : "r"(value) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrw sip, %0" : : "r"(value) :); - } else if constexpr (std::is_same::value) { - __asm__ volatile("csrw sie, %0" : : "r"(value) :); } else if constexpr (std::is_same::value) { + register_info::csr::SieInfo>::value) { + __asm__ volatile("csrw sie, %0" : : "r"(value) :); + } else if constexpr (std::is_same< + RegInfo, + register_info::csr::SscratchInfo>::value) { __asm__ volatile("csrw sscratch, %0" : : "r"(value) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrw sepc, %0" : : "r"(value) :); } else if constexpr (std::is_same::value) { + register_info::csr::ScauseInfo>::value) { __asm__ volatile("csrw scause, %0" : : "r"(value) :); } else if constexpr (std::is_same::value) { + register_info::csr::StvalInfo>::value) { __asm__ volatile("csrw stval, %0" : : "r"(value) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrw satp, %0" : : "r"(value) :); } else { - log::Err("No Type\n"); + klog::Err("No Type\n"); throw; } } @@ -519,30 +531,36 @@ class WriteOnlyRegBase { * @note 只能写 kCsrImmOpMask 范围内的值 */ static __always_inline void WriteImm(const uint8_t value) { - if constexpr (std::is_same::value) { + if constexpr (std::is_same::value) { __asm__ volatile("csrwi sstatus, %0" : : "i"(value) :); } else if constexpr (std::is_same::value) { + register_info::csr::StvecInfo>::value) { __asm__ volatile("csrwi stvec, %0" : : "i"(value) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrwi sip, %0" : : "i"(value) :); - } else if constexpr (std::is_same::value) { - __asm__ volatile("csrwi sie, %0" : : "i"(value) :); } else if constexpr (std::is_same::value) { + register_info::csr::SieInfo>::value) { + __asm__ volatile("csrwi sie, %0" : : "i"(value) :); + } else if constexpr (std::is_same< + RegInfo, + register_info::csr::SscratchInfo>::value) { __asm__ volatile("csrwi sscratch, %0" : : "i"(value) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrwi sepc, %0" : : "i"(value) :); } else if constexpr (std::is_same::value) { + register_info::csr::ScauseInfo>::value) { __asm__ volatile("csrwi scause, %0" : : "i"(value) :); } else if constexpr (std::is_same::value) { + register_info::csr::StvalInfo>::value) { __asm__ volatile("csrwi stval, %0" : : "i"(value) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrwi satp, %0" : : "i"(value) :); } else { - log::Err("No Type\n"); + klog::Err("No Type\n"); throw; } } @@ -552,30 +570,36 @@ class WriteOnlyRegBase { * @param mask 掩码 */ static __always_inline void SetBits(uint64_t mask) { - if constexpr (std::is_same::value) { + if constexpr (std::is_same::value) { __asm__ volatile("csrrs zero, sstatus, %0" : : "r"(mask) :); } else if constexpr (std::is_same::value) { + register_info::csr::StvecInfo>::value) { __asm__ volatile("csrrs zero, stvec, %0" : : "r"(mask) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrrs zero, sip, %0" : : "r"(mask) :); - } else if constexpr (std::is_same::value) { - __asm__ volatile("csrrs zero, sie, %0" : : "r"(mask) :); } else if constexpr (std::is_same::value) { + register_info::csr::SieInfo>::value) { + __asm__ volatile("csrrs zero, sie, %0" : : "r"(mask) :); + } else if constexpr (std::is_same< + RegInfo, + register_info::csr::SscratchInfo>::value) { __asm__ volatile("csrrs zero, sscratch, %0" : : "r"(mask) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrrs zero, sepc, %0" : : "r"(mask) :); } else if constexpr (std::is_same::value) { + register_info::csr::ScauseInfo>::value) { __asm__ volatile("csrrs zero, scause, %0" : : "r"(mask) :); } else if constexpr (std::is_same::value) { + register_info::csr::StvalInfo>::value) { __asm__ volatile("csrrs zero, stval, %0" : : "r"(mask) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrrs zero, satp, %0" : : "r"(mask) :); } else { - log::Err("No Type\n"); + klog::Err("No Type\n"); throw; } } @@ -585,30 +609,36 @@ class WriteOnlyRegBase { * @param mask 掩码 */ static __always_inline void ClearBits(uint64_t mask) { - if constexpr (std::is_same::value) { + if constexpr (std::is_same::value) { __asm__ volatile("csrrc zero, sstatus, %0" : : "r"(mask) :); } else if constexpr (std::is_same::value) { + register_info::csr::StvecInfo>::value) { __asm__ volatile("csrrc zero, stvec, %0" : : "r"(mask) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrrc zero, sip, %0" : : "r"(mask) :); - } else if constexpr (std::is_same::value) { - __asm__ volatile("csrrc zero, sie, %0" : : "r"(mask) :); } else if constexpr (std::is_same::value) { + register_info::csr::SieInfo>::value) { + __asm__ volatile("csrrc zero, sie, %0" : : "r"(mask) :); + } else if constexpr (std::is_same< + RegInfo, + register_info::csr::SscratchInfo>::value) { __asm__ volatile("csrrc zero, sscratch, %0" : : "r"(mask) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrrc zero, sepc, %0" : : "r"(mask) :); } else if constexpr (std::is_same::value) { + register_info::csr::ScauseInfo>::value) { __asm__ volatile("csrrc zero, scause, %0" : : "r"(mask) :); } else if constexpr (std::is_same::value) { + register_info::csr::StvalInfo>::value) { __asm__ volatile("csrrc zero, stval, %0" : : "r"(mask) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrrc zero, satp, %0" : : "r"(mask) :); } else { - log::Err("No Type\n"); + klog::Err("No Type\n"); throw; } } @@ -619,30 +649,36 @@ class WriteOnlyRegBase { * @note 只能写 kCsrImmOpMask 范围内的值 */ static __always_inline void SetBitsImm(const uint8_t mask) { - if constexpr (std::is_same::value) { + if constexpr (std::is_same::value) { __asm__ volatile("csrrsi zero, sstatus, %0" : : "i"(mask) :); } else if constexpr (std::is_same::value) { + register_info::csr::StvecInfo>::value) { __asm__ volatile("csrrsi zero, stvec, %0" : : "i"(mask) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrrsi zero, sip, %0" : : "i"(mask) :); - } else if constexpr (std::is_same::value) { - __asm__ volatile("csrrsi zero, sie, %0" : : "i"(mask) :); } else if constexpr (std::is_same::value) { + register_info::csr::SieInfo>::value) { + __asm__ volatile("csrrsi zero, sie, %0" : : "i"(mask) :); + } else if constexpr (std::is_same< + RegInfo, + register_info::csr::SscratchInfo>::value) { __asm__ volatile("csrrsi zero, sscratch, %0" : : "i"(mask) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrrsi zero, sepc, %0" : : "i"(mask) :); } else if constexpr (std::is_same::value) { + register_info::csr::ScauseInfo>::value) { __asm__ volatile("csrrsi zero, scause, %0" : : "i"(mask) :); } else if constexpr (std::is_same::value) { + register_info::csr::StvalInfo>::value) { __asm__ volatile("csrrsi zero, stval, %0" : : "i"(mask) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrrsi zero, satp, %0" : : "i"(mask) :); } else { - log::Err("No Type\n"); + klog::Err("No Type\n"); throw; } } @@ -653,30 +689,36 @@ class WriteOnlyRegBase { * @note 只能写 kCsrImmOpMask 范围内的值 */ static __always_inline void ClearBitsImm(const uint8_t mask) { - if constexpr (std::is_same::value) { + if constexpr (std::is_same::value) { __asm__ volatile("csrrci zero, sstatus, %0" : : "i"(mask) :); } else if constexpr (std::is_same::value) { + register_info::csr::StvecInfo>::value) { __asm__ volatile("csrrci zero, stvec, %0" : : "i"(mask) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrrci zero, sip, %0" : : "i"(mask) :); - } else if constexpr (std::is_same::value) { - __asm__ volatile("csrrci zero, sie, %0" : : "i"(mask) :); } else if constexpr (std::is_same::value) { + register_info::csr::SieInfo>::value) { + __asm__ volatile("csrrci zero, sie, %0" : : "i"(mask) :); + } else if constexpr (std::is_same< + RegInfo, + register_info::csr::SscratchInfo>::value) { __asm__ volatile("csrrci zero, sscratch, %0" : : "i"(mask) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrrci zero, sepc, %0" : : "i"(mask) :); } else if constexpr (std::is_same::value) { + register_info::csr::ScauseInfo>::value) { __asm__ volatile("csrrci zero, scause, %0" : : "i"(mask) :); } else if constexpr (std::is_same::value) { + register_info::csr::StvalInfo>::value) { __asm__ volatile("csrrci zero, stval, %0" : : "i"(mask) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrrci zero, satp, %0" : : "i"(mask) :); } else { - log::Err("No Type\n"); + klog::Err("No Type\n"); throw; } } @@ -687,7 +729,7 @@ class WriteOnlyRegBase { */ template static void WriteConst() { - if constexpr ((value & reginfo::csr::kCsrImmOpMask) == value) { + if constexpr ((value & register_info::csr::kCsrImmOpMask) == value) { WriteImm(value); } else { Write(value); @@ -700,7 +742,7 @@ class WriteOnlyRegBase { */ template static void SetConst() { - if constexpr ((mask & reginfo::csr::kCsrImmOpMask) == mask) { + if constexpr ((mask & register_info::csr::kCsrImmOpMask) == mask) { SetBitsImm(mask); } else { SetBits(mask); @@ -713,7 +755,7 @@ class WriteOnlyRegBase { */ template static void ClearConst() { - if constexpr ((mask & reginfo::csr::kCsrImmOpMask) == mask) { + if constexpr ((mask & register_info::csr::kCsrImmOpMask) == mask) { ClearBitsImm(mask); } else { ClearBits(mask); @@ -751,36 +793,42 @@ class ReadWriteRegBase : public ReadOnlyRegBase, */ static __always_inline RegInfo::DataType ReadWrite(RegInfo::DataType value) { typename RegInfo::DataType old_value{}; - if constexpr (std::is_same::value) { + if constexpr (std::is_same::value) { __asm__ volatile("csrrw %0, sstatus, %1" : "=r"(old_value) : "r"(value) :); } else if constexpr (std::is_same::value) { + register_info::csr::StvecInfo>::value) { __asm__ volatile("csrrw %0, stvec, %1" : "=r"(old_value) : "r"(value) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrrw %0, sip, %1" : "=r"(old_value) : "r"(value) :); - } else if constexpr (std::is_same::value) { - __asm__ volatile("csrrw %0, sie, %1" : "=r"(old_value) : "r"(value) :); } else if constexpr (std::is_same::value) { + register_info::csr::SieInfo>::value) { + __asm__ volatile("csrrw %0, sie, %1" : "=r"(old_value) : "r"(value) :); + } else if constexpr (std::is_same< + RegInfo, + register_info::csr::SscratchInfo>::value) { __asm__ volatile("csrrw %0, sscratch, %1" : "=r"(old_value) : "r"(value) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrrw %0, sepc, %1" : "=r"(old_value) : "r"(value) :); } else if constexpr (std::is_same::value) { + register_info::csr::ScauseInfo>::value) { __asm__ volatile("csrrw %0, scause, %1" : "=r"(old_value) : "r"(value) :); } else if constexpr (std::is_same::value) { + register_info::csr::StvalInfo>::value) { __asm__ volatile("csrrw %0, stval, %1" : "=r"(old_value) : "r"(value) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrrw %0, satp, %1" : "=r"(old_value) : "r"(value) :); } else { - log::Err("No Type\n"); + klog::Err("No Type\n"); throw; } return old_value; @@ -794,39 +842,45 @@ class ReadWriteRegBase : public ReadOnlyRegBase, */ static __always_inline RegInfo::DataType ReadWriteImm(const uint8_t value) { typename RegInfo::DataType old_value{}; - if constexpr (std::is_same::value) { + if constexpr (std::is_same::value) { __asm__ volatile("csrrwi %0, sstatus, %1" : "=r"(old_value) : "i"(value) :); } else if constexpr (std::is_same::value) { + register_info::csr::StvecInfo>::value) { __asm__ volatile("csrrwi %0, stvec, %1" : "=r"(old_value) : "i"(value) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrrwi %0, sip, %1" : "=r"(old_value) : "i"(value) :); - } else if constexpr (std::is_same::value) { - __asm__ volatile("csrrwi %0, sie, %1" : "=r"(old_value) : "i"(value) :); } else if constexpr (std::is_same::value) { + register_info::csr::SieInfo>::value) { + __asm__ volatile("csrrwi %0, sie, %1" : "=r"(old_value) : "i"(value) :); + } else if constexpr (std::is_same< + RegInfo, + register_info::csr::SscratchInfo>::value) { __asm__ volatile("csrrwi %0, sscratch, %1" : "=r"(old_value) : "i"(value) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrrwi %0, sepc, %1" : "=r"(old_value) : "i"(value) :); } else if constexpr (std::is_same::value) { + register_info::csr::ScauseInfo>::value) { __asm__ volatile("csrrwi %0, scause, %1" : "=r"(old_value) : "i"(value) :); } else if constexpr (std::is_same::value) { + register_info::csr::StvalInfo>::value) { __asm__ volatile("csrrwi %0, stval, %1" : "=r"(old_value) : "i"(value) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrrwi %0, satp, %1" : "=r"(old_value) : "i"(value) :); } else { - log::Err("No Type\n"); + klog::Err("No Type\n"); throw; } return old_value; @@ -839,7 +893,7 @@ class ReadWriteRegBase : public ReadOnlyRegBase, */ template static RegInfo::DataType ReadWriteConst() { - if constexpr ((value & reginfo::csr::kCsrImmOpMask) == value) { + if constexpr ((value & register_info::csr::kCsrImmOpMask) == value) { return ReadWriteRegBase::ReadWriteImm(value); } else { return ReadWrite(value); @@ -853,30 +907,36 @@ class ReadWriteRegBase : public ReadOnlyRegBase, */ static __always_inline RegInfo::DataType ReadSetBits(uint64_t mask) { typename RegInfo::DataType value{}; - if constexpr (std::is_same::value) { + if constexpr (std::is_same::value) { __asm__ volatile("csrrs %0, sstatus, %1" : "=r"(value) : "r"(mask) :); } else if constexpr (std::is_same::value) { + register_info::csr::StvecInfo>::value) { __asm__ volatile("csrrs %0, stvec, %1" : "=r"(value) : "r"(mask) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrrs %0, sip, %1" : "=r"(value) : "r"(mask) :); - } else if constexpr (std::is_same::value) { - __asm__ volatile("csrrs %0, sie, %1" : "=r"(value) : "r"(mask) :); } else if constexpr (std::is_same::value) { + register_info::csr::SieInfo>::value) { + __asm__ volatile("csrrs %0, sie, %1" : "=r"(value) : "r"(mask) :); + } else if constexpr (std::is_same< + RegInfo, + register_info::csr::SscratchInfo>::value) { __asm__ volatile("csrrs %0, sscratch, %1" : "=r"(value) : "r"(mask) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrrs %0, sepc, %1" : "=r"(value) : "r"(mask) :); } else if constexpr (std::is_same::value) { + register_info::csr::ScauseInfo>::value) { __asm__ volatile("csrrs %0, scause, %1" : "=r"(value) : "r"(mask) :); } else if constexpr (std::is_same::value) { + register_info::csr::StvalInfo>::value) { __asm__ volatile("csrrs %0, stval, %1" : "=r"(value) : "r"(mask) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrrs %0, satp, %1" : "=r"(value) : "r"(mask) :); } else { - log::Err("No Type\n"); + klog::Err("No Type\n"); throw; } return value; @@ -889,30 +949,36 @@ class ReadWriteRegBase : public ReadOnlyRegBase, */ static __always_inline RegInfo::DataType ReadSetBitsImm(const uint8_t mask) { typename RegInfo::DataType value{}; - if constexpr (std::is_same::value) { + if constexpr (std::is_same::value) { __asm__ volatile("csrrsi %0, sstatus, %1" : "=r"(value) : "i"(mask) :); } else if constexpr (std::is_same::value) { + register_info::csr::StvecInfo>::value) { __asm__ volatile("csrrsi %0, stvec, %1" : "=r"(value) : "i"(mask) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrrsi %0, sip, %1" : "=r"(value) : "i"(mask) :); - } else if constexpr (std::is_same::value) { - __asm__ volatile("csrrsi %0, sie, %1" : "=r"(value) : "i"(mask) :); } else if constexpr (std::is_same::value) { + register_info::csr::SieInfo>::value) { + __asm__ volatile("csrrsi %0, sie, %1" : "=r"(value) : "i"(mask) :); + } else if constexpr (std::is_same< + RegInfo, + register_info::csr::SscratchInfo>::value) { __asm__ volatile("csrrsi %0, sscratch, %1" : "=r"(value) : "i"(mask) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrrsi %0, sepc, %1" : "=r"(value) : "i"(mask) :); } else if constexpr (std::is_same::value) { + register_info::csr::ScauseInfo>::value) { __asm__ volatile("csrrsi %0, scause, %1" : "=r"(value) : "i"(mask) :); } else if constexpr (std::is_same::value) { + register_info::csr::StvalInfo>::value) { __asm__ volatile("csrrsi %0, stval, %1" : "=r"(value) : "i"(mask) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrrsi %0, satp, %1" : "=r"(value) : "i"(mask) :); } else { - log::Err("No Type\n"); + klog::Err("No Type\n"); throw; } return value; @@ -925,7 +991,7 @@ class ReadWriteRegBase : public ReadOnlyRegBase, */ template static RegInfo::DataType ReadSetBitsConst() { - if constexpr ((mask & reginfo::csr::kCsrImmOpMask) == mask) { + if constexpr ((mask & register_info::csr::kCsrImmOpMask) == mask) { return ReadSetBitsImm(mask); } else { return ReadSetBits(mask); @@ -939,30 +1005,36 @@ class ReadWriteRegBase : public ReadOnlyRegBase, */ static __always_inline RegInfo::DataType ReadClearBits(uint64_t mask) { typename RegInfo::DataType value{}; - if constexpr (std::is_same::value) { + if constexpr (std::is_same::value) { __asm__ volatile("csrrc %0, sstatus, %1" : "=r"(value) : "r"(mask) :); } else if constexpr (std::is_same::value) { + register_info::csr::StvecInfo>::value) { __asm__ volatile("csrrc %0, stvec, %1" : "=r"(value) : "r"(mask) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrrc %0, sip, %1" : "=r"(value) : "r"(mask) :); - } else if constexpr (std::is_same::value) { - __asm__ volatile("csrrc %0, sie, %1" : "=r"(value) : "r"(mask) :); } else if constexpr (std::is_same::value) { + register_info::csr::SieInfo>::value) { + __asm__ volatile("csrrc %0, sie, %1" : "=r"(value) : "r"(mask) :); + } else if constexpr (std::is_same< + RegInfo, + register_info::csr::SscratchInfo>::value) { __asm__ volatile("csrrc %0, sscratch, %1" : "=r"(value) : "r"(mask) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrrc %0, sepc, %1" : "=r"(value) : "r"(mask) :); } else if constexpr (std::is_same::value) { + register_info::csr::ScauseInfo>::value) { __asm__ volatile("csrrc %0, scause, %1" : "=r"(value) : "r"(mask) :); } else if constexpr (std::is_same::value) { + register_info::csr::StvalInfo>::value) { __asm__ volatile("csrrc %0, stval, %1" : "=r"(value) : "r"(mask) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrrc %0, satp, %1" : "=r"(value) : "r"(mask) :); } else { - log::Err("No Type\n"); + klog::Err("No Type\n"); throw; } return value; @@ -976,30 +1048,36 @@ class ReadWriteRegBase : public ReadOnlyRegBase, static __always_inline RegInfo::DataType ReadClearBitsImm( const uint8_t mask) { typename RegInfo::DataType value{}; - if constexpr (std::is_same::value) { + if constexpr (std::is_same::value) { __asm__ volatile("csrrci %0, sstatus, %1" : "=r"(value) : "i"(mask) :); } else if constexpr (std::is_same::value) { + register_info::csr::StvecInfo>::value) { __asm__ volatile("csrrci %0, stvec, %1" : "=r"(value) : "i"(mask) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrrci %0, sip, %1" : "=r"(value) : "i"(mask) :); - } else if constexpr (std::is_same::value) { - __asm__ volatile("csrrci %0, sie, %1" : "=r"(value) : "i"(mask) :); } else if constexpr (std::is_same::value) { + register_info::csr::SieInfo>::value) { + __asm__ volatile("csrrci %0, sie, %1" : "=r"(value) : "i"(mask) :); + } else if constexpr (std::is_same< + RegInfo, + register_info::csr::SscratchInfo>::value) { __asm__ volatile("csrrci %0, sscratch, %1" : "=r"(value) : "i"(mask) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrrci %0, sepc, %1" : "=r"(value) : "i"(mask) :); } else if constexpr (std::is_same::value) { + register_info::csr::ScauseInfo>::value) { __asm__ volatile("csrrci %0, scause, %1" : "=r"(value) : "i"(mask) :); } else if constexpr (std::is_same::value) { + register_info::csr::StvalInfo>::value) { __asm__ volatile("csrrci %0, stval, %1" : "=r"(value) : "i"(mask) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("csrrci %0, satp, %1" : "=r"(value) : "i"(mask) :); } else { - log::Err("No Type\n"); + klog::Err("No Type\n"); throw; } return value; @@ -1012,7 +1090,7 @@ class ReadWriteRegBase : public ReadOnlyRegBase, */ template static RegInfo::DataType ReadClearBitsConst() { - if constexpr ((mask & reginfo::csr::kCsrImmOpMask) == mask) { + if constexpr ((mask & register_info::csr::kCsrImmOpMask) == mask) { return WriteOnlyRegBase::ReadClearBitsImm(mask); } else { return ReadClearBits(mask); @@ -1080,7 +1158,7 @@ class WriteOnlyField { * 置位对应 Reg 的由 RegInfo 规定的指定位 */ static __always_inline void Set() { - if constexpr ((RegInfo::kBitMask & reginfo::csr::kCsrImmOpMask) == + if constexpr ((RegInfo::kBitMask & register_info::csr::kCsrImmOpMask) == RegInfo::kBitMask) { Reg::SetBitsImm(RegInfo::kBitMask); } else { @@ -1092,7 +1170,7 @@ class WriteOnlyField { * 清零对应 Reg 的由 RegInfo 规定的指定位 */ static __always_inline void Clear() { - if constexpr ((RegInfo::kBitMask & reginfo::csr::kCsrImmOpMask) == + if constexpr ((RegInfo::kBitMask & register_info::csr::kCsrImmOpMask) == RegInfo::kBitMask) { Reg::ClearBitsImm(RegInfo::kBitMask); } else { @@ -1147,7 +1225,7 @@ class ReadWriteField : public ReadOnlyField, }; // 第三部分:寄存器实例 -class Fp : public ReadWriteRegBase { +class Fp : public ReadWriteRegBase { public: friend sk_std::ostream &operator<<(sk_std::ostream &os, const Fp &fp) { printf("val: 0x%p", (void *)fp.Read()); @@ -1162,16 +1240,16 @@ struct AllXreg { namespace csr { -class Sstatus : public ReadWriteRegBase { +class Sstatus : public ReadWriteRegBase { public: - ReadWriteField, - reginfo::csr::SstatusInfo::Sie> + ReadWriteField, + register_info::csr::SstatusInfo::Sie> sie; - ReadWriteField, - reginfo::csr::SstatusInfo::Spie> + ReadWriteField, + register_info::csr::SstatusInfo::Spie> spie; - ReadWriteField, - reginfo::csr::SstatusInfo::Spp> + ReadWriteField, + register_info::csr::SstatusInfo::Spp> spp; /// @name 构造/析构函数 @@ -1184,7 +1262,8 @@ class Sstatus : public ReadWriteRegBase { virtual ~Sstatus() = default; /// @} - friend sk_std::ostream &operator<<(sk_std::ostream &os, const Sstatus &sstatus) { + friend sk_std::ostream &operator<<(sk_std::ostream &os, + const Sstatus &sstatus) { auto sie = sstatus.sie.Get(); auto spie = sstatus.spie.Get(); auto spp = sstatus.spp.Get(); @@ -1198,18 +1277,18 @@ class Sstatus : public ReadWriteRegBase { } }; -class Stvec : public ReadWriteRegBase { +class Stvec : public ReadWriteRegBase { public: - ReadWriteField, - reginfo::csr::StvecInfo::Base> + ReadWriteField, + register_info::csr::StvecInfo::Base> base; - ReadWriteField, - reginfo::csr::StvecInfo::Mode> + ReadWriteField, + register_info::csr::StvecInfo::Mode> mode; void SetDirect(uint64_t addr) { base.Write(addr); - mode.Write(reginfo::csr::StvecInfo::kDirect); + mode.Write(register_info::csr::StvecInfo::kDirect); } /// @name 构造/析构函数 @@ -1226,22 +1305,23 @@ class Stvec : public ReadWriteRegBase { auto mode = stvec.mode.Get(); auto base = stvec.base.Get(); printf("val: 0x%p, mode: %s, base: 0x%lX", (void *)stvec.Read(), - (mode == reginfo::csr::StvecInfo::kDirect ? "Direct" : "Vectored"), + (mode == register_info::csr::StvecInfo::kDirect ? "Direct" + : "Vectored"), base); return os; } }; -class Sip : public ReadWriteRegBase { +class Sip : public ReadWriteRegBase { public: - ReadWriteField, - reginfo::csr::SipInfo::Ssip> + ReadWriteField, + register_info::csr::SipInfo::Ssip> ssip; - ReadWriteField, - reginfo::csr::SipInfo::Stip> + ReadWriteField, + register_info::csr::SipInfo::Stip> stip; - ReadWriteField, - reginfo::csr::SipInfo::Seip> + ReadWriteField, + register_info::csr::SipInfo::Seip> seip; /// @name 构造/析构函数 @@ -1266,16 +1346,16 @@ class Sip : public ReadWriteRegBase { } }; -class Sie : public ReadWriteRegBase { +class Sie : public ReadWriteRegBase { public: - ReadWriteField, - reginfo::csr::SieInfo::Ssie> + ReadWriteField, + register_info::csr::SieInfo::Ssie> ssie; - ReadWriteField, - reginfo::csr::SieInfo::Stie> + ReadWriteField, + register_info::csr::SieInfo::Stie> stie; - ReadWriteField, - reginfo::csr::SieInfo::Seie> + ReadWriteField, + register_info::csr::SieInfo::Seie> seie; /// @name 构造/析构函数 @@ -1300,7 +1380,7 @@ class Sie : public ReadWriteRegBase { } }; -class Time : public ReadOnlyRegBase { +class Time : public ReadOnlyRegBase { public: /// @name 构造/析构函数 /// @{ @@ -1318,7 +1398,7 @@ class Time : public ReadOnlyRegBase { } }; -class Cycle : public ReadOnlyRegBase { +class Cycle : public ReadOnlyRegBase { public: /// @name 构造/析构函数 /// @{ @@ -1336,7 +1416,7 @@ class Cycle : public ReadOnlyRegBase { } }; -class Instret : public ReadOnlyRegBase { +class Instret : public ReadOnlyRegBase { public: /// @name 构造/析构函数 /// @{ @@ -1348,13 +1428,14 @@ class Instret : public ReadOnlyRegBase { virtual ~Instret() = default; /// @} - friend sk_std::ostream &operator<<(sk_std::ostream &os, const Instret &instret) { + friend sk_std::ostream &operator<<(sk_std::ostream &os, + const Instret &instret) { printf("val: 0x%p", (void *)instret.Read()); return os; } }; -class Sscratch : public ReadWriteRegBase { +class Sscratch : public ReadWriteRegBase { public: /// @name 构造/析构函数 /// @{ @@ -1366,13 +1447,14 @@ class Sscratch : public ReadWriteRegBase { virtual ~Sscratch() = default; /// @} - friend sk_std::ostream &operator<<(sk_std::ostream &os, const Sscratch &sscratch) { + friend sk_std::ostream &operator<<(sk_std::ostream &os, + const Sscratch &sscratch) { printf("val: 0x%p", (void *)sscratch.Read()); return os; } }; -class Sepc : public ReadWriteRegBase { +class Sepc : public ReadWriteRegBase { public: /// @name 构造/析构函数 /// @{ @@ -1390,13 +1472,13 @@ class Sepc : public ReadWriteRegBase { } }; -class Scause : public ReadWriteRegBase { +class Scause : public ReadWriteRegBase { public: - ReadWriteField, - reginfo::csr::ScauseInfo::Interrupt> + ReadWriteField, + register_info::csr::ScauseInfo::Interrupt> interrupt; - ReadWriteField, - reginfo::csr::ScauseInfo::ExceptionCode> + ReadWriteField, + register_info::csr::ScauseInfo::ExceptionCode> exception_code; /// @name 构造/析构函数 @@ -1409,19 +1491,21 @@ class Scause : public ReadWriteRegBase { virtual ~Scause() = default; /// @} - friend sk_std::ostream &operator<<(sk_std::ostream &os, const Scause &scause) { + friend sk_std::ostream &operator<<(sk_std::ostream &os, + const Scause &scause) { auto exception_code = scause.exception_code.Get(); auto interrupt = scause.interrupt.Get(); - printf("val: 0x%p, exception_code: 0x%lX, interrupt: %s, name: %s", - (void *)scause.Read(), exception_code, interrupt ? "Yes" : "No", - interrupt - ? reginfo::csr::ScauseInfo::kInterruptNames[exception_code] - : reginfo::csr::ScauseInfo::kExceptionNames[exception_code]); + printf( + "val: 0x%p, exception_code: 0x%lX, interrupt: %s, name: %s", + (void *)scause.Read(), exception_code, interrupt ? "Yes" : "No", + interrupt + ? register_info::csr::ScauseInfo::kInterruptNames[exception_code] + : register_info::csr::ScauseInfo::kExceptionNames[exception_code]); return os; } }; -class Stval : public ReadWriteRegBase { +class Stval : public ReadWriteRegBase { public: /// @name 构造/析构函数 /// @{ @@ -1439,16 +1523,16 @@ class Stval : public ReadWriteRegBase { } }; -class Satp : public ReadWriteRegBase { +class Satp : public ReadWriteRegBase { public: - ReadWriteField, - reginfo::csr::SatpInfo::Ppn> + ReadWriteField, + register_info::csr::SatpInfo::Ppn> ppn; - ReadWriteField, - reginfo::csr::SatpInfo::Asid> + ReadWriteField, + register_info::csr::SatpInfo::Asid> asid; - ReadWriteField, - reginfo::csr::SatpInfo::Mode> + ReadWriteField, + register_info::csr::SatpInfo::Mode> mode; /// @name 构造/析构函数 @@ -1466,12 +1550,12 @@ class Satp : public ReadWriteRegBase { auto asid = satp.asid.Get(); auto mode = satp.mode.Get(); printf("val: 0x%p, ppn: 0x%lX, asid: 0x%X, mode: %s", (void *)satp.Read(), - ppn, asid, reginfo::csr::SatpInfo::kModeNames[mode]); + ppn, asid, register_info::csr::SatpInfo::kModeNames[mode]); return os; } }; -class Stimecmp : public ReadOnlyRegBase { +class Stimecmp : public ReadOnlyRegBase { public: /// @name 构造/析构函数 /// @{ @@ -1483,7 +1567,8 @@ class Stimecmp : public ReadOnlyRegBase { virtual ~Stimecmp() = default; /// @} - friend sk_std::ostream &operator<<(sk_std::ostream &os, const Stimecmp &stimecmp) { + friend sk_std::ostream &operator<<(sk_std::ostream &os, + const Stimecmp &stimecmp) { printf("val: 0x%p", (void *)stimecmp.Read()); return os; } @@ -1526,4 +1611,4 @@ class AllCsr { }; // namespace cpu -#endif // SIMPLEKERNEL_SRC_KERNEL_ARCH_RISCV64_INCLUDE_CPU_HPP_ +#endif // SIMPLEKERNEL_SRC_KERNEL_ARCH_RISCV64_INCLUDE_CPU_CSR_HPP_ diff --git a/src/kernel/arch/riscv64/interrupt.cpp b/src/kernel/arch/riscv64/interrupt.cpp index 7a3a53993..14e09d836 100644 --- a/src/kernel/arch/riscv64/interrupt.cpp +++ b/src/kernel/arch/riscv64/interrupt.cpp @@ -15,7 +15,7 @@ #include "interrupt.h" -#include "cpu.hpp" +#include "cpu/cpu.hpp" #include "kernel_fdt.hpp" #include "kernel_log.hpp" #include "opensbi_interface.h" @@ -23,10 +23,10 @@ #include "sk_iostream" Interrupt::InterruptFunc Interrupt::interrupt_handlers - [cpu::reginfo::csr::ScauseInfo::kInterruptMaxCount]; + [cpu::register_info::csr::ScauseInfo::kInterruptMaxCount]; Interrupt::InterruptFunc Interrupt::exception_handlers - [cpu::reginfo::csr::ScauseInfo::kExceptionMaxCount]; + [cpu::register_info::csr::ScauseInfo::kExceptionMaxCount]; __attribute__((interrupt("supervisor"))) alignas(4) static void TarpEntry() { sk_std::cout << sk_std::endl; @@ -49,8 +49,8 @@ Interrupt::Interrupt() { for (auto &i : interrupt_handlers) { i = [](uint64_t cause, uint8_t *context) -> uint64_t { printf("Default Interrupt handler [%s] 0x%X, 0x%p\n", - cpu::reginfo::csr::ScauseInfo::kInterruptNames[cause], cause, - context); + cpu::register_info::csr::ScauseInfo::kInterruptNames[cause], + cause, context); return 0; }; } @@ -58,8 +58,8 @@ Interrupt::Interrupt() { for (auto &i : exception_handlers) { i = [](uint64_t cause, uint8_t *context) -> uint64_t { printf("Default Exception handler [%s] 0x%X, 0x%p\n", - cpu::reginfo::csr::ScauseInfo::kExceptionNames[cause], cause, - context); + cpu::register_info::csr::ScauseInfo::kExceptionNames[cause], + cause, context); return 0; }; } @@ -82,7 +82,7 @@ Interrupt::Interrupt() { is_inited = true; } - log::Info("Interrupt init.\n"); + klog::Info("Interrupt init.\n"); } void Interrupt::Do(uint64_t cause, uint8_t *context) { @@ -91,12 +91,14 @@ void Interrupt::Do(uint64_t cause, uint8_t *context) { if (interrupt) { // 中断 - if (exception_code < cpu::reginfo::csr::ScauseInfo::kInterruptMaxCount) { + if (exception_code < + cpu::register_info::csr::ScauseInfo::kInterruptMaxCount) { interrupt_handlers[exception_code](exception_code, context); } } else { // 异常 - if (exception_code < cpu::reginfo::csr::ScauseInfo::kExceptionMaxCount) { + if (exception_code < + cpu::register_info::csr::ScauseInfo::kExceptionMaxCount) { exception_handlers[exception_code](exception_code, context); } } @@ -107,18 +109,22 @@ void Interrupt::RegisterInterruptFunc(uint64_t cause, InterruptFunc func) { auto exception_code = cpu::kAllCsr.scause.exception_code.Get(cause); if (interrupt) { - if (exception_code < cpu::reginfo::csr::ScauseInfo::kInterruptMaxCount) { + if (exception_code < + cpu::register_info::csr::ScauseInfo::kInterruptMaxCount) { interrupt_handlers[exception_code] = func; - printf("RegisterInterruptFunc [%s] 0x%X, 0x%p\n", - cpu::reginfo::csr::ScauseInfo::kInterruptNames[exception_code], - cause, func); + printf( + "RegisterInterruptFunc [%s] 0x%X, 0x%p\n", + cpu::register_info::csr::ScauseInfo::kInterruptNames[exception_code], + cause, func); } } else { - if (exception_code < cpu::reginfo::csr::ScauseInfo::kExceptionMaxCount) { + if (exception_code < + cpu::register_info::csr::ScauseInfo::kExceptionMaxCount) { exception_handlers[exception_code] = func; - printf("RegisterInterruptFunc [%s] 0x%X, 0x%p\n", - cpu::reginfo::csr::ScauseInfo::kExceptionNames[exception_code], - cause, func); + printf( + "RegisterInterruptFunc [%s] 0x%X, 0x%p\n", + cpu::register_info::csr::ScauseInfo::kExceptionNames[exception_code], + cause, func); } } } @@ -132,21 +138,21 @@ uint32_t InterruptInit(uint32_t, uint8_t *) { // 注册时钟中断 kInterrupt.GetInstance().RegisterInterruptFunc( - cpu::reginfo::csr::ScauseInfo::kSupervisorTimerInterrupt, + cpu::register_info::csr::ScauseInfo::kSupervisorTimerInterrupt, [](uint64_t exception_code, uint8_t *) -> uint64_t { sbi_set_timer(cpu::kAllCsr.time.Read() + kInterval); - printf("Handle %s\n", - cpu::reginfo::csr::ScauseInfo::kInterruptNames[exception_code]); + printf("Handle %s\n", cpu::register_info::csr::ScauseInfo:: + kInterruptNames[exception_code]); return 0; }); // ebreak 中断 kInterrupt.GetInstance().RegisterInterruptFunc( - cpu::reginfo::csr::ScauseInfo::kBreakpoint, + cpu::register_info::csr::ScauseInfo::kBreakpoint, [](uint64_t exception_code, uint8_t *) -> uint64_t { cpu::kAllCsr.sepc.Write(cpu::kAllCsr.sepc.Read() + 2); - printf("Handle %s\n", - cpu::reginfo::csr::ScauseInfo::kExceptionNames[exception_code]); + printf("Handle %s\n", cpu::register_info::csr::ScauseInfo:: + kExceptionNames[exception_code]); return 0; }); @@ -155,7 +161,7 @@ uint32_t InterruptInit(uint32_t, uint8_t *) { // 设置时钟中断时间 sbi_set_timer(kInterval); - log::Info("Hello InterruptInit\n"); + klog::Info("Hello InterruptInit\n"); return 0; } diff --git a/src/kernel/arch/riscv64/interrupt.h b/src/kernel/arch/riscv64/interrupt.h index 5f2b45a9e..b9d029a60 100644 --- a/src/kernel/arch/riscv64/interrupt.h +++ b/src/kernel/arch/riscv64/interrupt.h @@ -19,7 +19,7 @@ #include -#include "cpu.hpp" +#include "cpu/cpu.hpp" #include "interrupt_base.h" #include "singleton.hpp" #include "sk_stdio.h" @@ -54,10 +54,10 @@ class Interrupt final : public InterruptBase { private: /// 中断处理函数数组 alignas(4) static InterruptFunc - interrupt_handlers[cpu::reginfo::csr::ScauseInfo::kInterruptMaxCount]; + interrupt_handlers[cpu::register_info::csr::ScauseInfo::kInterruptMaxCount]; /// 异常处理函数数组 alignas(4) static InterruptFunc - exception_handlers[cpu::reginfo::csr::ScauseInfo::kExceptionMaxCount]; + exception_handlers[cpu::register_info::csr::ScauseInfo::kExceptionMaxCount]; }; /// 全局 elf 对象,需要在相应体系结构初始化时重新初始化 diff --git a/src/kernel/arch/x86_64/arch_main.cpp b/src/kernel/arch/x86_64/arch_main.cpp index a3e370255..46ad6726a 100644 --- a/src/kernel/arch/x86_64/arch_main.cpp +++ b/src/kernel/arch/x86_64/arch_main.cpp @@ -17,11 +17,11 @@ #include #include "basic_info.hpp" -#include "cpu.hpp" -#include "sk_cstdio" -#include "sk_cstring" +#include "cpu/cpu.hpp" #include "kernel_elf.hpp" #include "kernel_log.hpp" +#include "sk_cstdio" +#include "sk_cstring" // printf_bare_metal 基本输出实现 /// @note 这里要注意,保证在 serial 初始化之前不能使用 printf @@ -29,43 +29,47 @@ static cpu::Serial kSerial(cpu::kCom1); extern "C" void _putchar(char character) { kSerial.Write(character); } -/// gdt 描述符表,顺序与 cpu::reginfo::GdtrInfo 中的定义一致 -static cpu::reginfo::GdtrInfo::SegmentDescriptor - kSegmentDescriptors[cpu::reginfo::GdtrInfo::kMaxCount] = { +/// gdt 描述符表,顺序与 cpu::register_info::GdtrInfo 中的定义一致 +static cpu::register_info::GdtrInfo::SegmentDescriptor + kSegmentDescriptors[cpu::register_info::GdtrInfo::kMaxCount] = { // 第一个全 0 - cpu::reginfo::GdtrInfo::SegmentDescriptor(), + cpu::register_info::GdtrInfo::SegmentDescriptor(), // 内核代码段描述符 - cpu::reginfo::GdtrInfo::SegmentDescriptor( - cpu::reginfo::GdtrInfo::SegmentDescriptor::Type::kCodeExecuteRead, - cpu::reginfo::GdtrInfo::SegmentDescriptor::S::kCodeData, - cpu::reginfo::GdtrInfo::SegmentDescriptor::DPL::kRing0, - cpu::reginfo::GdtrInfo::SegmentDescriptor::P::kPresent, - cpu::reginfo::GdtrInfo::SegmentDescriptor::AVL::kNotAvailable, - cpu::reginfo::GdtrInfo::SegmentDescriptor::L::k64Bit), + cpu::register_info::GdtrInfo::SegmentDescriptor( + cpu::register_info::GdtrInfo::SegmentDescriptor::Type:: + kCodeExecuteRead, + cpu::register_info::GdtrInfo::SegmentDescriptor::S::kCodeData, + cpu::register_info::GdtrInfo::SegmentDescriptor::DPL::kRing0, + cpu::register_info::GdtrInfo::SegmentDescriptor::P::kPresent, + cpu::register_info::GdtrInfo::SegmentDescriptor::AVL::kNotAvailable, + cpu::register_info::GdtrInfo::SegmentDescriptor::L::k64Bit), // 内核数据段描述符 - cpu::reginfo::GdtrInfo::SegmentDescriptor( - cpu::reginfo::GdtrInfo::SegmentDescriptor::Type::kDataReadWrite, - cpu::reginfo::GdtrInfo::SegmentDescriptor::S::kCodeData, - cpu::reginfo::GdtrInfo::SegmentDescriptor::DPL::kRing0, - cpu::reginfo::GdtrInfo::SegmentDescriptor::P::kPresent, - cpu::reginfo::GdtrInfo::SegmentDescriptor::AVL::kNotAvailable, - cpu::reginfo::GdtrInfo::SegmentDescriptor::L::k64Bit), + cpu::register_info::GdtrInfo::SegmentDescriptor( + cpu::register_info::GdtrInfo::SegmentDescriptor::Type:: + kDataReadWrite, + cpu::register_info::GdtrInfo::SegmentDescriptor::S::kCodeData, + cpu::register_info::GdtrInfo::SegmentDescriptor::DPL::kRing0, + cpu::register_info::GdtrInfo::SegmentDescriptor::P::kPresent, + cpu::register_info::GdtrInfo::SegmentDescriptor::AVL::kNotAvailable, + cpu::register_info::GdtrInfo::SegmentDescriptor::L::k64Bit), // 用户代码段描述符 - cpu::reginfo::GdtrInfo::SegmentDescriptor( - cpu::reginfo::GdtrInfo::SegmentDescriptor::Type::kCodeExecuteRead, - cpu::reginfo::GdtrInfo::SegmentDescriptor::S::kCodeData, - cpu::reginfo::GdtrInfo::SegmentDescriptor::DPL::kRing3, - cpu::reginfo::GdtrInfo::SegmentDescriptor::P::kPresent, - cpu::reginfo::GdtrInfo::SegmentDescriptor::AVL::kNotAvailable, - cpu::reginfo::GdtrInfo::SegmentDescriptor::L::k64Bit), + cpu::register_info::GdtrInfo::SegmentDescriptor( + cpu::register_info::GdtrInfo::SegmentDescriptor::Type:: + kCodeExecuteRead, + cpu::register_info::GdtrInfo::SegmentDescriptor::S::kCodeData, + cpu::register_info::GdtrInfo::SegmentDescriptor::DPL::kRing3, + cpu::register_info::GdtrInfo::SegmentDescriptor::P::kPresent, + cpu::register_info::GdtrInfo::SegmentDescriptor::AVL::kNotAvailable, + cpu::register_info::GdtrInfo::SegmentDescriptor::L::k64Bit), // 用户数据段描述符 - cpu::reginfo::GdtrInfo::SegmentDescriptor( - cpu::reginfo::GdtrInfo::SegmentDescriptor::Type::kDataReadWrite, - cpu::reginfo::GdtrInfo::SegmentDescriptor::S::kCodeData, - cpu::reginfo::GdtrInfo::SegmentDescriptor::DPL::kRing3, - cpu::reginfo::GdtrInfo::SegmentDescriptor::P::kPresent, - cpu::reginfo::GdtrInfo::SegmentDescriptor::AVL::kNotAvailable, - cpu::reginfo::GdtrInfo::SegmentDescriptor::L::k64Bit), + cpu::register_info::GdtrInfo::SegmentDescriptor( + cpu::register_info::GdtrInfo::SegmentDescriptor::Type:: + kDataReadWrite, + cpu::register_info::GdtrInfo::SegmentDescriptor::S::kCodeData, + cpu::register_info::GdtrInfo::SegmentDescriptor::DPL::kRing3, + cpu::register_info::GdtrInfo::SegmentDescriptor::P::kPresent, + cpu::register_info::GdtrInfo::SegmentDescriptor::AVL::kNotAvailable, + cpu::register_info::GdtrInfo::SegmentDescriptor::L::k64Bit), }; // 引用链接脚本中的变量 @@ -93,7 +97,7 @@ BasicInfo::BasicInfo(uint32_t argc, uint8_t *argv) { uint32_t ArchInit(uint32_t argc, uint8_t *argv) { if (argc != 1) { - log::Err("argc != 1 [%d]\n", argc); + klog::Err("argc != 1 [%d]\n", argc); throw; } @@ -105,32 +109,32 @@ uint32_t ArchInit(uint32_t argc, uint8_t *argv) { kBasicInfo.GetInstance().elf_size); // 加载描述符 - cpu::reginfo::GdtrInfo::Gdtr gdtr{ - .limit = (sizeof(cpu::reginfo::GdtrInfo::SegmentDescriptor) * - cpu::reginfo::GdtrInfo::kMaxCount) - + cpu::register_info::GdtrInfo::Gdtr gdtr{ + .limit = (sizeof(cpu::register_info::GdtrInfo::SegmentDescriptor) * + cpu::register_info::GdtrInfo::kMaxCount) - 1, .base = kSegmentDescriptors, }; cpu::kAllCr.gdtr.Write(gdtr); - log::Debug("sizeof(cpu::reginfo::GdtrInfo::SegmentDescriptor): %d\n", - sizeof(cpu::reginfo::GdtrInfo::SegmentDescriptor)); - log::Debug("kSegmentDescriptors: 0x%X\n", kSegmentDescriptors); + klog::Debug("sizeof(cpu::register_info::GdtrInfo::SegmentDescriptor): %d\n", + sizeof(cpu::register_info::GdtrInfo::SegmentDescriptor)); + klog::Debug("kSegmentDescriptors: 0x%X\n", kSegmentDescriptors); // 加载内核数据段描述符 - cpu::kAllCr.ds.Write(sizeof(cpu::reginfo::GdtrInfo::SegmentDescriptor) * - cpu::reginfo::GdtrInfo::kKernelDataIndex); - cpu::kAllCr.es.Write(sizeof(cpu::reginfo::GdtrInfo::SegmentDescriptor) * - cpu::reginfo::GdtrInfo::kKernelDataIndex); - cpu::kAllCr.fs.Write(sizeof(cpu::reginfo::GdtrInfo::SegmentDescriptor) * - cpu::reginfo::GdtrInfo::kKernelDataIndex); - cpu::kAllCr.gs.Write(sizeof(cpu::reginfo::GdtrInfo::SegmentDescriptor) * - cpu::reginfo::GdtrInfo::kKernelDataIndex); - cpu::kAllCr.ss.Write(sizeof(cpu::reginfo::GdtrInfo::SegmentDescriptor) * - cpu::reginfo::GdtrInfo::kKernelDataIndex); + cpu::kAllCr.ds.Write(sizeof(cpu::register_info::GdtrInfo::SegmentDescriptor) * + cpu::register_info::GdtrInfo::kKernelDataIndex); + cpu::kAllCr.es.Write(sizeof(cpu::register_info::GdtrInfo::SegmentDescriptor) * + cpu::register_info::GdtrInfo::kKernelDataIndex); + cpu::kAllCr.fs.Write(sizeof(cpu::register_info::GdtrInfo::SegmentDescriptor) * + cpu::register_info::GdtrInfo::kKernelDataIndex); + cpu::kAllCr.gs.Write(sizeof(cpu::register_info::GdtrInfo::SegmentDescriptor) * + cpu::register_info::GdtrInfo::kKernelDataIndex); + cpu::kAllCr.ss.Write(sizeof(cpu::register_info::GdtrInfo::SegmentDescriptor) * + cpu::register_info::GdtrInfo::kKernelDataIndex); // 加载内核代码段描述符 - cpu::kAllCr.cs.Write(sizeof(cpu::reginfo::GdtrInfo::SegmentDescriptor) * - cpu::reginfo::GdtrInfo::kKernelCodeIndex); + cpu::kAllCr.cs.Write(sizeof(cpu::register_info::GdtrInfo::SegmentDescriptor) * + cpu::register_info::GdtrInfo::kKernelCodeIndex); sk_std::cout << "es: " << cpu::kAllCr.es << sk_std::endl; sk_std::cout << "cs: " << cpu::kAllCr.cs << sk_std::endl; @@ -139,14 +143,15 @@ uint32_t ArchInit(uint32_t argc, uint8_t *argv) { sk_std::cout << "fs: " << cpu::kAllCr.fs << sk_std::endl; sk_std::cout << "gs: " << cpu::kAllCr.gs << sk_std::endl; - for (size_t i = 0; i < (cpu::kAllCr.gdtr.Read().limit + 1) / - sizeof(cpu::reginfo::GdtrInfo::SegmentDescriptor); + for (size_t i = 0; + i < (cpu::kAllCr.gdtr.Read().limit + 1) / + sizeof(cpu::register_info::GdtrInfo::SegmentDescriptor); i++) { - log::Debug("gdtr[%d] 0x%p\n", i, cpu::kAllCr.gdtr.Read().base + i); - log::debug << *(cpu::kAllCr.gdtr.Read().base + i) << sk_std::endl; + klog::Debug("gdtr[%d] 0x%p\n", i, cpu::kAllCr.gdtr.Read().base + i); + klog::debug << *(cpu::kAllCr.gdtr.Read().base + i) << sk_std::endl; } - log::Info("Hello x86_64 ArchInit\n"); + klog::Info("Hello x86_64 ArchInit\n"); return 0; } diff --git a/src/kernel/arch/x86_64/backtrace.cpp b/src/kernel/arch/x86_64/backtrace.cpp index cb5f55b40..c4223fad3 100644 --- a/src/kernel/arch/x86_64/backtrace.cpp +++ b/src/kernel/arch/x86_64/backtrace.cpp @@ -14,9 +14,9 @@ */ #include "arch.h" -#include "cpu.hpp" -#include "sk_cstdio" +#include "cpu/cpu.hpp" #include "kernel_elf.hpp" +#include "sk_cstdio" #include "sk_libc.h" int backtrace(void **buffer, int size) { diff --git a/src/kernel/arch/x86_64/include/cpu/cpu.hpp b/src/kernel/arch/x86_64/include/cpu/cpu.hpp new file mode 100644 index 000000000..06b89907c --- /dev/null +++ b/src/kernel/arch/x86_64/include/cpu/cpu.hpp @@ -0,0 +1,517 @@ + +/** + * @file cpu.hpp + * @brief x86_64 cpu 相关定义 + * @author Zone.N (Zone.Niuzh@hotmail.com) + * @version 1.0 + * @date 2024-03-05 + * @copyright MIT LICENSE + * https://github.com/Simple-XX/SimpleKernel + * @par change log: + * + *
DateAuthorDescription + *
2024-03-05Zone.N (Zone.Niuzh@hotmail.com)创建文件 + *
+ */ + +#ifndef SIMPLEKERNEL_SRC_KERNEL_ARCH_X86_64_INCLUDE_CPU_CPU_HPP_ +#define SIMPLEKERNEL_SRC_KERNEL_ARCH_X86_64_INCLUDE_CPU_CPU_HPP_ + +#include +#include +#include +#include + +#include "cr.hpp" +#include "kernel_log.hpp" +#include "sk_cstdio" +#include "sk_iostream" + +/** + * x86_64 cpu 相关定义 + * @note 寄存器读写设计见 arch/README.md + * @see sdm.pdf + * Intel® 64 and IA-32 Architectures Software Developer’s Manual + * Volume 3 (3A, 3B, 3C, & 3D): System Programming Guide + * Order Number: 325384-083US + * https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html + */ +namespace cpu { +/** + * @brief 读一个字节 + * @param port 要读的端口 + * @return uint8_t 读取到的数据 + */ +static __always_inline uint8_t InByte(const uint32_t port) { + uint8_t data; + __asm__ volatile("inb %1, %0" : "=a"(data) : "dN"(port)); + return data; +} + +/** + * @brief 读一个字 + * @param port 要读的端口 + * @return uint16_t 读取到的数据 + */ +static __always_inline uint16_t InWord(const uint32_t port) { + uint16_t data; + __asm__ volatile("inw %1, %0" : "=a"(data) : "dN"(port)); + return data; +} + +/** + * @brief 读一个双字 + * @param port 要读的端口 + * @return uint32_t 读取到的数据 + */ +static __always_inline uint32_t InLong(const uint32_t port) { + uint32_t data; + __asm__ volatile("inl %1, %0" : "=a"(data) : "dN"(port)); + return data; +} + +/** + * @brief 写一个字节 + * @param port 要写的端口 + * @param data 要写的数据 + */ +static __always_inline void OutByte(const uint32_t port, const uint8_t data) { + __asm__ volatile("outb %1, %0" : : "dN"(port), "a"(data)); +} + +/** + * @brief 写一个字 + * @param port 要写的端口 + * @param data 要写的数据 + */ +static __always_inline void OutWord(const uint32_t port, const uint16_t data) { + __asm__ volatile("outw %1, %0" : : "dN"(port), "a"(data)); +} + +/** + * @brief 写一个双字 + * @param port 要写的端口 + * @param data 要写的数据 + */ +static __always_inline void OutLong(const uint32_t port, const uint32_t data) { + __asm__ volatile("outl %1, %0" : : "dN"(port), "a"(data)); +} + +/// @name 端口 +static constexpr const uint32_t kCom1 = 0x3F8; +/** + * 串口定义 + */ +class Serial { + public: + explicit Serial(uint32_t port) : port_(port) { + // Disable all interrupts + OutByte(port_ + 1, 0x00); + // Enable DLAB (set baud rate divisor) + OutByte(port_ + 3, 0x80); + // Set divisor to 3 (lo byte) 38400 baud + OutByte(port_ + 0, 0x03); + // (hi byte) + OutByte(port_ + 1, 0x00); + // 8 bits, no parity, one stop bit + OutByte(port_ + 3, 0x03); + // Enable FIFO, clear them, with 14-byte threshold + OutByte(port_ + 2, 0xC7); + // IRQs enabled, RTS/DSR set + OutByte(port_ + 4, 0x0B); + // Set in loopback mode, test the serial chip + OutByte(port_ + 4, 0x1E); + // Test serial chip (send byte 0xAE and check if serial returns same byte) + OutByte(port_ + 0, 0xAE); + // Check if serial is faulty (i.e: not same byte as sent) + if (InByte(port_ + 0) != 0xAE) { + asm("hlt"); + } + + // If serial is not faulty set it in normal operation mode (not-loopback + // with IRQs enabled and OUT#1 and OUT#2 bits enabled) + OutByte(port_ + 4, 0x0F); + } + + ~Serial() = default; + + /// @name 不使用的构造函数 + /// @{ + Serial() = delete; + Serial(const Serial &) = delete; + Serial(Serial &&) = delete; + auto operator=(const Serial &) -> Serial & = delete; + auto operator=(Serial &&) -> Serial & = delete; + /// @} + + /** + * @brief 读一个字节 + * @return uint8_t 读取到的数据 + */ + [[nodiscard]] auto Read() const -> uint8_t { + while (!SerialReceived()) { + ; + } + return InByte(port_); + } + + /** + * @brief 写一个字节 + * @param c 要写的数据 + */ + void Write(uint8_t c) const { + while (!IsTransmitEmpty()) { + ; + } + OutByte(port_, c); + } + + private: + uint32_t port_; + + /** + * @brief 串口是否接收到数据 + * @return true + * @return false + */ + [[nodiscard]] auto SerialReceived() const -> bool { + return InByte(port_ + 5) & 1; + } + + /** + * @brief 串口是否可以发送数据 + * @return true + * @return false + */ + [[nodiscard]] auto IsTransmitEmpty() const -> bool { + return InByte(port_ + 5) & 0x20; + } +}; + +/** + * 中断控制器(8259A) + * @see https://wiki.osdev.org/8259_PIC + * @note master 处理 8 个中断,slave 处理八个中断 + * @note 工作在 8086 模式下,中断处理完后需要通知 pic 重置 ISR 寄存器 + */ +class Pic { + public: + /** + * 构造函数 + * @param offset1 主片中断偏移,共 8 个 + * @param offset2 从片中断偏移,共 8 个 + */ + explicit Pic(uint8_t offset1, uint8_t offset2) + : offset1_(offset1), offset2_(offset2) { + // 0001 0001 + OutByte(kMasterCommand, kIcw1Init | kIcw1Icw4); + // 设置主片 IRQ 从 offset1_ 号中断开始 + OutByte(kMasterData, offset1_); + // 设置主片 IR2 引脚连接从片 + // 4: 0000 0100 + OutByte(kMasterData, 4); + // 设置主片按照 8086 的方式工作 + OutByte(kMasterData, kIcw48086); + + OutByte(kSlaveCommand, kIcw1Init | kIcw1Icw4); + // 设置从片 IRQ 从 offset2_ 号中断开始 + OutByte(kPic2Data, offset2_); + // 告诉从片输出引脚和主片 IR2 号相连 + // 2: 0000 0010 + OutByte(kPic2Data, 2); + // 设置从片按照 8086 的方式工作 + OutByte(kPic2Data, kIcw48086); + + // 关闭所有中断 + OutByte(kMasterData, 0xFF); + OutByte(kPic2Data, 0xFF); + } + + /// @name 构造/析构函数 + /// @{ + Pic() = delete; + Pic(const Pic &) = delete; + Pic(Pic &&) = delete; + auto operator=(const Pic &) -> Pic & = delete; + auto operator=(Pic &&) -> Pic & = delete; + ~Pic() = default; + /// @} + + /** + * 开启 pic 的 no 中断 + * @param no 中断号 + */ + void Enable(uint8_t no) { + uint8_t mask = 0; + if (no >= offset2_) { + mask = ((InByte(kPic2Data)) & (~(1 << (no % 8)))); + OutByte(kPic2Data, mask); + } else { + mask = ((InByte(kMasterData)) & (~(1 << (no % 8)))); + OutByte(kMasterData, mask); + } + } + + /** + * 关闭 8259A 芯片的所有中断 + */ + void Disable() { + // 屏蔽所有中断 + OutByte(kMasterData, 0xFF); + OutByte(kPic2Data, 0xFF); + } + + /** + * 关闭 pic 的 no 中断 + * @param no 中断号 + */ + void Disable(uint8_t no) { + uint8_t mask = 0; + if (no >= offset2_) { + mask = ((InByte(kPic2Data)) | (1 << (no % 8))); + OutByte(kPic2Data, mask); + } else { + mask = ((InByte(kMasterData)) | (1 << (no % 8))); + OutByte(kMasterData, mask); + } + } + + /** + * 通知 pic no 中断处理完毕 + * @param no 中断号 + */ + void Clear(uint8_t no) { + // 按照我们的设置,从 offset1_ 号中断起为用户自定义中断 + // 因为单片的 Intel 8259A 芯片只能处理 8 级中断 + // 故大于等于 offset2_ 的中断号是由从片处理的 + if (no >= offset2_) { + // 发送重设信号给从片 + OutByte(kSlaveCommand, kEoi); + } else { + // 发送重设信号给主片 + OutByte(kMasterCommand, kEoi); + } + } + + /** + * Returns the combined value of the cascaded PICs irq request register + * @return uint16_t 值 + */ + uint16_t GetIrr() { return GetIrqReg(kOcw3ReadIrr); } + + /** + * Returns the combined value of the cascaded PICs in-service register + * @return uint16_t 值 + */ + uint16_t GetIsr() { return GetIrqReg(kOcw3ReadIsr); } + + private: + uint8_t offset1_; + uint8_t offset2_; + + /// Master (IRQs 0-7) + static constexpr const uint8_t kMaster = 0x20; + /// Slave (IRQs 8-15) + static constexpr const uint8_t kSlave = 0xA0; + static constexpr const uint8_t kMasterCommand = kMaster; + static constexpr const uint8_t kMasterData = kMaster + 1; + static constexpr const uint8_t kSlaveCommand = kSlave; + static constexpr const uint8_t kPic2Data = kSlave + 1; + /// End-of-interrupt command code + static constexpr const uint8_t kEoi = 0x20; + + /// Indicates that ICW4 will be present + static constexpr const uint8_t kIcw1Icw4 = 0x01; + /// Single (cascade) mode + static constexpr const uint8_t kIcw1Single = 0x02; + /// Call address interval 4 (8) + static constexpr const uint8_t kIcw1Interval4 = 0x04; + /// Level triggered (edge) mode + static constexpr const uint8_t kIcw1Level = 0x08; + /// Initialization - required! + static constexpr const uint8_t kIcw1Init = 0x10; + + /// OCW3 irq ready next CMD read + static constexpr const uint8_t kOcw3ReadIrr = 0x0A; + /// OCW3 irq service next CMD read + static constexpr const uint8_t kOcw3ReadIsr = 0x0B; + + /// 8086/88 (MCS-80/85) mode + static constexpr const uint8_t kIcw48086 = 0x01; + /// Auto (normal) EOI + static constexpr const uint8_t kIcw4Auto = 0x02; + /// Buffered mode/slave + static constexpr const uint8_t kIcw4BufferSlave = 0x08; + /// Buffered mode/master + static constexpr const uint8_t kIcw4BufferMaster = 0x0C; + /// Special fully nested (not) + static constexpr const uint8_t kIcw4Sfnm = 0x10; + + /** + * 获取中断请求寄存器的值 + * @note OCW3 to PIC CMD to get the register values. PIC2 is chained, and + * represents IRQs 8-15. PIC1 is IRQs 0-7, with 2 being the chain + * @param ocw3 OCW3 + * @return uint16_t 值 + */ + uint16_t GetIrqReg(uint8_t ocw3) { + OutByte(kMasterCommand, ocw3); + OutByte(kSlaveCommand, ocw3); + return (InByte(kSlaveCommand) << 8) | InByte(kMasterCommand); + } +}; + +/** + * 时钟控制器(8253/8254) + * @see https://en.wikipedia.org/wiki/Intel_8253 + * @see https://wiki.osdev.org/Programmable_Interval_Timer + */ +class Pit { + public: + /** + * 构造函数 + * @param frequency 每秒中断次数 + */ + explicit Pit(uint16_t frequency) { + uint16_t divisor = kMaxFrequency / frequency; + + // 设置 8253/8254 芯片工作在模式 3 下 + OutByte(kCommand, (uint8_t)kChannel0 | (uint8_t)kHighAndLow | + (uint8_t)kSquareWaveGenerator); + + // 分别写入低字节和高字节 + OutByte(kChannel0Data, divisor & 0xFF); + OutByte(kChannel0Data, divisor >> 8); + } + + /// @name 构造/析构函数 + /// @{ + Pit() = delete; + Pit(const Pit &) = delete; + Pit(Pit &&) = delete; + auto operator=(const Pit &) -> Pit & = delete; + auto operator=(Pit &&) -> Pit & = delete; + ~Pit() = default; + /// @} + + /** + * 计数器更新 + */ + void Ticks() { ticks_ += 1; } + + /** + * 获取时钟中断次数 + * @return size_t 时钟中断次数 + */ + size_t GetTicks() const { return ticks_; } + + private: + /// 最大频率 + static constexpr const size_t kMaxFrequency = 1193180; + /// 通道 0 数据端口 + static constexpr const size_t kChannel0Data = 0x40; + /// 模式/命令端口 + static constexpr const size_t kCommand = 0x43; + + /** + * Bits Usage + * 6 and 7 Select channel : + * 0 0 = Channel 0 + * 0 1 = Channel 1 + * 1 0 = Channel 2 + * 1 1 = Read-back command (8254 only) + */ + enum Channel { + kChannel0 = 0x0, + kChannel1 = 0x40, + kChannel2 = 0x80, + }; + + /** + * Bits Usage + * 4 and 5 Access mode : + * 0 0 = Latch count value command + * 0 1 = Access mode: lobyte only + * 1 0 = Access mode: hibyte only + * 1 1 = Access mode: lobyte/hibyte + */ + enum Access { + kLatchCount = 0x0, + kLowOnly = 0x10, + kHighOnly = 0x20, + kHighAndLow = 0x30, + }; + + /** + * Bits Usage + * 1 to 3 Operating mode : + * 0 0 0 = Mode 0 (interrupt on terminal count) + * 0 0 1 = Mode 1 (hardware re-triggerable one-shot) + * 0 1 0 = Mode 2 (rate generator) + * 0 1 1 = Mode 3 (square wave generator) + * 1 0 0 = Mode 4 (software triggered strobe) + * 1 0 1 = Mode 5 (hardware triggered strobe) + * 1 1 0 = Mode 2 (rate generator, same as 010b) + * 1 1 1 = Mode 3 (square wave generator, same as 011b) + * 0 BCD/Binary mode: 0 = 16-bit binary, 1 = four-digit BCD + */ + enum Mode { + kInterruptOnTerminalCount = 0x0, + kHardwareRetriggerableOneShot = 0x2, + kRateGenerator = 0x4, + kSquareWaveGenerator = 0x6, + kSoftwareTriggeredStrobe = 0x8, + kHardwareTriggeredStrobe = 0xA, + }; + + /// 计数器 + volatile size_t ticks_ = 0; +}; + +/// 中断上下文,由 cpu 自动压入,无错误码 +struct InterruptContext { + uint64_t rip; + uint64_t cs; + uint64_t rflags; + uint64_t rsp; + uint64_t ss; + + friend sk_std::ostream &operator<<( + sk_std::ostream &os, const InterruptContext &interrupt_context) { + printf("rip: 0x%lX\n", interrupt_context.rip); + printf("cs: 0x%lX\n", interrupt_context.cs); + printf("rflags: 0x%lX\n", interrupt_context.rflags); + printf("rsp: 0x%lX\n", interrupt_context.rsp); + printf("ss: 0x%lX", interrupt_context.ss); + return os; + } +}; + +/// 中断上下文,由 cpu 自动压入,有错误码 +struct InterruptContextErrorCode { + register_info::IdtrInfo::ErrorCode error_code; + uint32_t padding; + uint64_t rip; + uint64_t cs; + uint64_t rflags; + uint64_t rsp; + uint64_t ss; + + friend sk_std::ostream &operator<<( + sk_std::ostream &os, + const InterruptContextErrorCode &interrupt_context_error_code) { + sk_std::cout << sk_std::endl + << interrupt_context_error_code.error_code << sk_std::endl; + printf("padding: 0x%X\n", interrupt_context_error_code.padding); + printf("rip: 0x%lX\n", interrupt_context_error_code.rip); + printf("cs: 0x%lX\n", interrupt_context_error_code.cs); + printf("rflags: 0x%lX\n", interrupt_context_error_code.rflags); + printf("rsp: 0x%lX\n", interrupt_context_error_code.rsp); + printf("ss: 0x%lX", interrupt_context_error_code.ss); + return os; + } +}; + +}; // namespace cpu + +#endif // SIMPLEKERNEL_SRC_KERNEL_ARCH_X86_64_INCLUDE_CPU_CPU_HPP_ diff --git a/src/kernel/arch/x86_64/include/cpu.hpp b/src/kernel/arch/x86_64/include/cpu/cr.hpp similarity index 63% rename from src/kernel/arch/x86_64/include/cpu.hpp rename to src/kernel/arch/x86_64/include/cpu/cr.hpp index f6c2e88b7..f9af65473 100644 --- a/src/kernel/arch/x86_64/include/cpu.hpp +++ b/src/kernel/arch/x86_64/include/cpu/cr.hpp @@ -1,7 +1,7 @@ /** - * @file cpu.hpp - * @brief x86_64 cpu 相关定义 + * @file cr.hpp + * @brief x86_64 cr 相关定义 * @author Zone.N (Zone.Niuzh@hotmail.com) * @version 1.0 * @date 2024-03-05 @@ -14,461 +14,26 @@ * */ -#ifndef SIMPLEKERNEL_SRC_KERNEL_ARCH_X86_64_INCLUDE_CPU_HPP_ -#define SIMPLEKERNEL_SRC_KERNEL_ARCH_X86_64_INCLUDE_CPU_HPP_ +#ifndef SIMPLEKERNEL_SRC_KERNEL_ARCH_X86_64_INCLUDE_CPU_CR_HPP_ +#define SIMPLEKERNEL_SRC_KERNEL_ARCH_X86_64_INCLUDE_CPU_CR_HPP_ #include #include #include #include +#include "kernel_log.hpp" #include "sk_cstdio" #include "sk_iostream" -#include "kernel_log.hpp" /** - * x86_64 cpu 相关定义 + * x86_64 cpu Control Registers 相关定义 * @note 寄存器读写设计见 arch/README.md - * @see sdm.pdf - * Intel® 64 and IA-32 Architectures Software Developer’s Manual - * Volume 3 (3A, 3B, 3C, & 3D): System Programming Guide - * Order Number: 325384-083US - * https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html */ namespace cpu { -/** - * @brief 读一个字节 - * @param port 要读的端口 - * @return uint8_t 读取到的数据 - */ -static __always_inline uint8_t InByte(const uint32_t port) { - uint8_t data; - __asm__ volatile("inb %1, %0" : "=a"(data) : "dN"(port)); - return data; -} - -/** - * @brief 读一个字 - * @param port 要读的端口 - * @return uint16_t 读取到的数据 - */ -static __always_inline uint16_t InWord(const uint32_t port) { - uint16_t data; - __asm__ volatile("inw %1, %0" : "=a"(data) : "dN"(port)); - return data; -} - -/** - * @brief 读一个双字 - * @param port 要读的端口 - * @return uint32_t 读取到的数据 - */ -static __always_inline uint32_t InLong(const uint32_t port) { - uint32_t data; - __asm__ volatile("inl %1, %0" : "=a"(data) : "dN"(port)); - return data; -} - -/** - * @brief 写一个字节 - * @param port 要写的端口 - * @param data 要写的数据 - */ -static __always_inline void OutByte(const uint32_t port, const uint8_t data) { - __asm__ volatile("outb %1, %0" : : "dN"(port), "a"(data)); -} - -/** - * @brief 写一个字 - * @param port 要写的端口 - * @param data 要写的数据 - */ -static __always_inline void OutWord(const uint32_t port, const uint16_t data) { - __asm__ volatile("outw %1, %0" : : "dN"(port), "a"(data)); -} - -/** - * @brief 写一个双字 - * @param port 要写的端口 - * @param data 要写的数据 - */ -static __always_inline void OutLong(const uint32_t port, const uint32_t data) { - __asm__ volatile("outl %1, %0" : : "dN"(port), "a"(data)); -} - -/// @name 端口 -static constexpr const uint32_t kCom1 = 0x3F8; -/** - * 串口定义 - */ -class Serial { - public: - explicit Serial(uint32_t port) : port_(port) { - // Disable all interrupts - OutByte(port_ + 1, 0x00); - // Enable DLAB (set baud rate divisor) - OutByte(port_ + 3, 0x80); - // Set divisor to 3 (lo byte) 38400 baud - OutByte(port_ + 0, 0x03); - // (hi byte) - OutByte(port_ + 1, 0x00); - // 8 bits, no parity, one stop bit - OutByte(port_ + 3, 0x03); - // Enable FIFO, clear them, with 14-byte threshold - OutByte(port_ + 2, 0xC7); - // IRQs enabled, RTS/DSR set - OutByte(port_ + 4, 0x0B); - // Set in loopback mode, test the serial chip - OutByte(port_ + 4, 0x1E); - // Test serial chip (send byte 0xAE and check if serial returns same byte) - OutByte(port_ + 0, 0xAE); - // Check if serial is faulty (i.e: not same byte as sent) - if (InByte(port_ + 0) != 0xAE) { - asm("hlt"); - } - - // If serial is not faulty set it in normal operation mode (not-loopback - // with IRQs enabled and OUT#1 and OUT#2 bits enabled) - OutByte(port_ + 4, 0x0F); - } - - ~Serial() = default; - - /// @name 不使用的构造函数 - /// @{ - Serial() = delete; - Serial(const Serial &) = delete; - Serial(Serial &&) = delete; - auto operator=(const Serial &) -> Serial & = delete; - auto operator=(Serial &&) -> Serial & = delete; - /// @} - - /** - * @brief 读一个字节 - * @return uint8_t 读取到的数据 - */ - [[nodiscard]] auto Read() const -> uint8_t { - while (!SerialReceived()) { - ; - } - return InByte(port_); - } - - /** - * @brief 写一个字节 - * @param c 要写的数据 - */ - void Write(uint8_t c) const { - while (!IsTransmitEmpty()) { - ; - } - OutByte(port_, c); - } - - private: - uint32_t port_; - - /** - * @brief 串口是否接收到数据 - * @return true - * @return false - */ - [[nodiscard]] auto SerialReceived() const -> bool { - return InByte(port_ + 5) & 1; - } - - /** - * @brief 串口是否可以发送数据 - * @return true - * @return false - */ - [[nodiscard]] auto IsTransmitEmpty() const -> bool { - return InByte(port_ + 5) & 0x20; - } -}; - -/** - * 中断控制器(8259A) - * @see https://wiki.osdev.org/8259_PIC - * @note master 处理 8 个中断,slave 处理八个中断 - * @note 工作在 8086 模式下,中断处理完后需要通知 pic 重置 ISR 寄存器 - */ -class Pic { - public: - /** - * 构造函数 - * @param offset1 主片中断偏移,共 8 个 - * @param offset2 从片中断偏移,共 8 个 - */ - explicit Pic(uint8_t offset1, uint8_t offset2) - : offset1_(offset1), offset2_(offset2) { - // 0001 0001 - OutByte(kMasterCommand, kIcw1Init | kIcw1Icw4); - // 设置主片 IRQ 从 offset1_ 号中断开始 - OutByte(kMasterData, offset1_); - // 设置主片 IR2 引脚连接从片 - // 4: 0000 0100 - OutByte(kMasterData, 4); - // 设置主片按照 8086 的方式工作 - OutByte(kMasterData, kIcw48086); - - OutByte(kSlaveCommand, kIcw1Init | kIcw1Icw4); - // 设置从片 IRQ 从 offset2_ 号中断开始 - OutByte(kPic2Data, offset2_); - // 告诉从片输出引脚和主片 IR2 号相连 - // 2: 0000 0010 - OutByte(kPic2Data, 2); - // 设置从片按照 8086 的方式工作 - OutByte(kPic2Data, kIcw48086); - - // 关闭所有中断 - OutByte(kMasterData, 0xFF); - OutByte(kPic2Data, 0xFF); - } - - /// @name 构造/析构函数 - /// @{ - Pic() = delete; - Pic(const Pic &) = delete; - Pic(Pic &&) = delete; - auto operator=(const Pic &) -> Pic & = delete; - auto operator=(Pic &&) -> Pic & = delete; - ~Pic() = default; - /// @} - - /** - * 开启 pic 的 no 中断 - * @param no 中断号 - */ - void Enable(uint8_t no) { - uint8_t mask = 0; - if (no >= offset2_) { - mask = ((InByte(kPic2Data)) & (~(1 << (no % 8)))); - OutByte(kPic2Data, mask); - } else { - mask = ((InByte(kMasterData)) & (~(1 << (no % 8)))); - OutByte(kMasterData, mask); - } - } - - /** - * 关闭 8259A 芯片的所有中断 - */ - void Disable() { - // 屏蔽所有中断 - OutByte(kMasterData, 0xFF); - OutByte(kPic2Data, 0xFF); - } - - /** - * 关闭 pic 的 no 中断 - * @param no 中断号 - */ - void Disable(uint8_t no) { - uint8_t mask = 0; - if (no >= offset2_) { - mask = ((InByte(kPic2Data)) | (1 << (no % 8))); - OutByte(kPic2Data, mask); - } else { - mask = ((InByte(kMasterData)) | (1 << (no % 8))); - OutByte(kMasterData, mask); - } - } - - /** - * 通知 pic no 中断处理完毕 - * @param no 中断号 - */ - void Clear(uint8_t no) { - // 按照我们的设置,从 offset1_ 号中断起为用户自定义中断 - // 因为单片的 Intel 8259A 芯片只能处理 8 级中断 - // 故大于等于 offset2_ 的中断号是由从片处理的 - if (no >= offset2_) { - // 发送重设信号给从片 - OutByte(kSlaveCommand, kEoi); - } else { - // 发送重设信号给主片 - OutByte(kMasterCommand, kEoi); - } - } - - /** - * Returns the combined value of the cascaded PICs irq request register - * @return uint16_t 值 - */ - uint16_t GetIrr() { return GetIrqReg(kOcw3ReadIrr); } - - /** - * Returns the combined value of the cascaded PICs in-service register - * @return uint16_t 值 - */ - uint16_t GetIsr() { return GetIrqReg(kOcw3ReadIsr); } - - private: - uint8_t offset1_; - uint8_t offset2_; - - /// Master (IRQs 0-7) - static constexpr const uint8_t kMaster = 0x20; - /// Slave (IRQs 8-15) - static constexpr const uint8_t kSlave = 0xA0; - static constexpr const uint8_t kMasterCommand = kMaster; - static constexpr const uint8_t kMasterData = kMaster + 1; - static constexpr const uint8_t kSlaveCommand = kSlave; - static constexpr const uint8_t kPic2Data = kSlave + 1; - /// End-of-interrupt command code - static constexpr const uint8_t kEoi = 0x20; - - /// Indicates that ICW4 will be present - static constexpr const uint8_t kIcw1Icw4 = 0x01; - /// Single (cascade) mode - static constexpr const uint8_t kIcw1Single = 0x02; - /// Call address interval 4 (8) - static constexpr const uint8_t kIcw1Interval4 = 0x04; - /// Level triggered (edge) mode - static constexpr const uint8_t kIcw1Level = 0x08; - /// Initialization - required! - static constexpr const uint8_t kIcw1Init = 0x10; - - /// OCW3 irq ready next CMD read - static constexpr const uint8_t kOcw3ReadIrr = 0x0A; - /// OCW3 irq service next CMD read - static constexpr const uint8_t kOcw3ReadIsr = 0x0B; - - /// 8086/88 (MCS-80/85) mode - static constexpr const uint8_t kIcw48086 = 0x01; - /// Auto (normal) EOI - static constexpr const uint8_t kIcw4Auto = 0x02; - /// Buffered mode/slave - static constexpr const uint8_t kIcw4BufferSlave = 0x08; - /// Buffered mode/master - static constexpr const uint8_t kIcw4BufferMaster = 0x0C; - /// Special fully nested (not) - static constexpr const uint8_t kIcw4Sfnm = 0x10; - - /** - * 获取中断请求寄存器的值 - * @note OCW3 to PIC CMD to get the register values. PIC2 is chained, and - * represents IRQs 8-15. PIC1 is IRQs 0-7, with 2 being the chain - * @param ocw3 OCW3 - * @return uint16_t 值 - */ - uint16_t GetIrqReg(uint8_t ocw3) { - OutByte(kMasterCommand, ocw3); - OutByte(kSlaveCommand, ocw3); - return (InByte(kSlaveCommand) << 8) | InByte(kMasterCommand); - } -}; - -/** - * 时钟控制器(8253/8254) - * @see https://en.wikipedia.org/wiki/Intel_8253 - * @see https://wiki.osdev.org/Programmable_Interval_Timer - */ -class Pit { - public: - /** - * 构造函数 - * @param frequency 每秒中断次数 - */ - explicit Pit(uint16_t frequency) { - uint16_t divisor = kMaxFrequency / frequency; - - // 设置 8253/8254 芯片工作在模式 3 下 - OutByte(kCommand, (uint8_t)kChannel0 | (uint8_t)kHighAndLow | - (uint8_t)kSquareWaveGenerator); - - // 分别写入低字节和高字节 - OutByte(kChannel0Data, divisor & 0xFF); - OutByte(kChannel0Data, divisor >> 8); - } - - /// @name 构造/析构函数 - /// @{ - Pit() = delete; - Pit(const Pit &) = delete; - Pit(Pit &&) = delete; - auto operator=(const Pit &) -> Pit & = delete; - auto operator=(Pit &&) -> Pit & = delete; - ~Pit() = default; - /// @} - - /** - * 计数器更新 - */ - void Ticks() { ticks_ += 1; } - - /** - * 获取时钟中断次数 - * @return size_t 时钟中断次数 - */ - size_t GetTicks() const { return ticks_; } - - private: - /// 最大频率 - static constexpr const size_t kMaxFrequency = 1193180; - /// 通道 0 数据端口 - static constexpr const size_t kChannel0Data = 0x40; - /// 模式/命令端口 - static constexpr const size_t kCommand = 0x43; - - /** - * Bits Usage - * 6 and 7 Select channel : - * 0 0 = Channel 0 - * 0 1 = Channel 1 - * 1 0 = Channel 2 - * 1 1 = Read-back command (8254 only) - */ - enum Channel { - kChannel0 = 0x0, - kChannel1 = 0x40, - kChannel2 = 0x80, - }; - - /** - * Bits Usage - * 4 and 5 Access mode : - * 0 0 = Latch count value command - * 0 1 = Access mode: lobyte only - * 1 0 = Access mode: hibyte only - * 1 1 = Access mode: lobyte/hibyte - */ - enum Access { - kLatchCount = 0x0, - kLowOnly = 0x10, - kHighOnly = 0x20, - kHighAndLow = 0x30, - }; - - /** - * Bits Usage - * 1 to 3 Operating mode : - * 0 0 0 = Mode 0 (interrupt on terminal count) - * 0 0 1 = Mode 1 (hardware re-triggerable one-shot) - * 0 1 0 = Mode 2 (rate generator) - * 0 1 1 = Mode 3 (square wave generator) - * 1 0 0 = Mode 4 (software triggered strobe) - * 1 0 1 = Mode 5 (hardware triggered strobe) - * 1 1 0 = Mode 2 (rate generator, same as 010b) - * 1 1 1 = Mode 3 (square wave generator, same as 011b) - * 0 BCD/Binary mode: 0 = 16-bit binary, 1 = four-digit BCD - */ - enum Mode { - kInterruptOnTerminalCount = 0x0, - kHardwareRetriggerableOneShot = 0x2, - kRateGenerator = 0x4, - kSquareWaveGenerator = 0x6, - kSoftwareTriggeredStrobe = 0x8, - kHardwareTriggeredStrobe = 0xA, - }; - - /// 计数器 - volatile size_t ticks_ = 0; -}; // 第一部分:寄存器定义 -namespace reginfo { +namespace register_info { struct RegInfoBase { /// 寄存器数据类型 @@ -1188,7 +753,7 @@ struct GsInfo : public SegmentSelector {}; }; // namespace segment_register -}; // namespace reginfo +}; // namespace register_info // 第二部分:读/写模版实现 namespace { @@ -1215,63 +780,75 @@ class ReadOnlyRegBase { */ static __always_inline RegInfo::DataType Read() { typename RegInfo::DataType value{}; - if constexpr (std::is_same::value) { + if constexpr (std::is_same::value) { __asm__ volatile("mov %%rbp, %0" : "=r"(value) : :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { uint32_t low{}; uint32_t high{}; __asm__ volatile("rdmsr" : "=a"(low), "=d"(high) : "c"(0xC0000080) :); value = ((uint64_t)high << 32) | low; - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("pushfq; popq %0" : "=r"(value) : :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("sgdt %0" : "=m"(value) : :); - } else if constexpr (std::is_same::value) { - log::Err("TODO\n"); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { + klog::Err("TODO\n"); + } else if constexpr (std::is_same::value) { __asm__ volatile("sidt %0" : "=m"(value) : :); - } else if constexpr (std::is_same::value) { - log::Err("TODO\n"); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { + klog::Err("TODO\n"); + } else if constexpr (std::is_same::value) { __asm__ volatile("mov %%cr0, %0" : "=r"(value) : :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("mov %%cr2, %0" : "=r"(value) : :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("mov %%cr3, %0" : "=r"(value) : :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("mov %%cr4, %0" : "=r"(value) : :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("mov %%cr8, %0" : "=r"(value) : :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("mov %%rbp, %0" : "=r"(value) : :); - } else if constexpr (std::is_same::value) { - log::Err("TODO\n"); + } else if constexpr (std::is_same::value) { + klog::Err("TODO\n"); } else if constexpr (std::is_same< RegInfo, - reginfo::segment_register::CsInfo>::value) { + register_info::segment_register::CsInfo>::value) { __asm__ volatile("mov %%cs, %0" : "=r"(value) : :); } else if constexpr (std::is_same< RegInfo, - reginfo::segment_register::SsInfo>::value) { + register_info::segment_register::SsInfo>::value) { __asm__ volatile("mov %%ss, %0" : "=r"(value) : :); } else if constexpr (std::is_same< RegInfo, - reginfo::segment_register::DsInfo>::value) { + register_info::segment_register::DsInfo>::value) { __asm__ volatile("mov %%ds, %0" : "=r"(value) : :); } else if constexpr (std::is_same< RegInfo, - reginfo::segment_register::EsInfo>::value) { + register_info::segment_register::EsInfo>::value) { __asm__ volatile("mov %%es, %0" : "=r"(value) : :); } else if constexpr (std::is_same< RegInfo, - reginfo::segment_register::FsInfo>::value) { + register_info::segment_register::FsInfo>::value) { __asm__ volatile("mov %%fs, %0" : "=r"(value) : :); } else if constexpr (std::is_same< RegInfo, - reginfo::segment_register::GsInfo>::value) { + register_info::segment_register::GsInfo>::value) { __asm__ volatile("mov %%gs, %0" : "=r"(value) : :); } else { - log::Err("No Type\n"); + klog::Err("No Type\n"); throw; } return value; @@ -1305,37 +882,48 @@ class WriteOnlyRegBase { * @param value 要写的值 */ static __always_inline void Write(RegInfo::DataType value) { - if constexpr (std::is_same::value) { + if constexpr (std::is_same::value) { __asm__ volatile("mov %0, %%rbp" : : "r"(value) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { uint32_t low = value & 0xFFFFFFFF; uint32_t high = value >> 32; __asm__ volatile("wrmsr" : : "c"(0xC0000080), "a"(low), "d"(high) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("pushq %0; popfq" : : "r"(value) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("lgdt %0" : : "m"(value) :); - } else if constexpr (std::is_same::value) { - log::Err("TODO\n"); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { + klog::Err("TODO\n"); + } else if constexpr (std::is_same::value) { __asm__ volatile("lidt %0" : : "m"(value) :); - } else if constexpr (std::is_same::value) { - log::Err("TODO\n"); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { + klog::Err("TODO\n"); + } else if constexpr (std::is_same::value) { __asm__ volatile("mov %0, %%cr0" : : "r"(value) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("mov %0, %%cr2" : : "r"(value) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("mov %0, %%cr3" : : "r"(value) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("mov %0, %%cr4" : : "r"(value) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("mov %0, %%cr8" : : "r"(value) :); - } else if constexpr (std::is_same::value) { - log::Err("TODO\n"); + } else if constexpr (std::is_same::value) { + klog::Err("TODO\n"); } else if constexpr (std::is_same< RegInfo, - reginfo::segment_register::CsInfo>::value) { + register_info::segment_register::CsInfo>::value) { auto JumpFunction = [=](uint16_t value) { __asm__ volatile( "push %0\n\t" @@ -1349,26 +937,26 @@ class WriteOnlyRegBase { JumpFunction(value); } else if constexpr (std::is_same< RegInfo, - reginfo::segment_register::SsInfo>::value) { + register_info::segment_register::SsInfo>::value) { __asm__ volatile("mov %0, %%ss" : : "r"(value) :); } else if constexpr (std::is_same< RegInfo, - reginfo::segment_register::DsInfo>::value) { + register_info::segment_register::DsInfo>::value) { __asm__ volatile("mov %0, %%ds" : : "r"(value) :); } else if constexpr (std::is_same< RegInfo, - reginfo::segment_register::EsInfo>::value) { + register_info::segment_register::EsInfo>::value) { __asm__ volatile("mov %0, %%es" : : "r"(value) :); } else if constexpr (std::is_same< RegInfo, - reginfo::segment_register::FsInfo>::value) { + register_info::segment_register::FsInfo>::value) { __asm__ volatile("mov %0, %%fs" : : "r"(value) :); } else if constexpr (std::is_same< RegInfo, - reginfo::segment_register::GsInfo>::value) { + register_info::segment_register::GsInfo>::value) { __asm__ volatile("mov %0, %%gs" : : "r"(value) :); } else { - log::Err("No Type\n"); + klog::Err("No Type\n"); throw; } } @@ -1378,17 +966,19 @@ class WriteOnlyRegBase { * @param offset 位偏移 */ static __always_inline void SetBits(uint64_t offset) { - if constexpr (std::is_same::value) { + if constexpr (std::is_same::value) { __asm__ volatile("bts %%rbp, %0" : : "r"(offset) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { uint32_t low{}; uint32_t high{}; __asm__ volatile("rdmsr" : "=a"(low), "=d"(high) : "c"(0xC0000080) :); uint64_t value = ((uint64_t)high << 32) | low; value |= (1ULL << offset); Write(value); - } else if constexpr (std::is_same::value) { - if (offset == reginfo::RflagsInfo::If::kBitOffset) { + } else if constexpr (std::is_same::value) { + if (offset == register_info::RflagsInfo::If::kBitOffset) { __asm__ volatile("sti"); } else { typename RegInfo::DataType old_value = 0; @@ -1396,28 +986,37 @@ class WriteOnlyRegBase { auto new_value = old_value | (1 << offset); Write(new_value); } - } else if constexpr (std::is_same::value) { - log::Err("TODO\n"); - } else if constexpr (std::is_same::value) { - log::Err("TODO\n"); - } else if constexpr (std::is_same::value) { - log::Err("TODO\n"); - } else if constexpr (std::is_same::value) { - log::Err("TODO\n"); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { + klog::Err("TODO\n"); + } else if constexpr (std::is_same::value) { + klog::Err("TODO\n"); + } else if constexpr (std::is_same::value) { + klog::Err("TODO\n"); + } else if constexpr (std::is_same::value) { + klog::Err("TODO\n"); + } else if constexpr (std::is_same::value) { __asm__ volatile("bts %%cr0, %0" : : "r"(offset) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("bts %%cr2, %0" : : "r"(offset) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("bts %%cr3, %0" : : "r"(offset) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("bts %%cr4, %0" : : "r"(offset) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("bts %%cr8, %0" : : "r"(offset) :); - } else if constexpr (std::is_same::value) { - log::Err("TODO\n"); + } else if constexpr (std::is_same::value) { + klog::Err("TODO\n"); } else { - log::Err("No Type\n"); + klog::Err("No Type\n"); throw; } } @@ -1427,17 +1026,19 @@ class WriteOnlyRegBase { * @param offset 位偏移 */ static __always_inline void ClearBits(uint64_t offset) { - if constexpr (std::is_same::value) { + if constexpr (std::is_same::value) { __asm__ volatile("btr %%rbp, %0" : : "r"(offset) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { uint32_t low{}; uint32_t high{}; __asm__ volatile("rdmsr" : "=a"(low), "=d"(high) : "c"(0xC0000080) :); uint64_t value = ((uint64_t)high << 32) | low; value &= ~(1ULL << offset); Write(value); - } else if constexpr (std::is_same::value) { - if (offset == reginfo::RflagsInfo::If::kBitOffset) { + } else if constexpr (std::is_same::value) { + if (offset == register_info::RflagsInfo::If::kBitOffset) { __asm__ volatile("cli"); } else { typename RegInfo::DataType old_value = 0; @@ -1445,28 +1046,37 @@ class WriteOnlyRegBase { auto new_value = old_value & (~(1ULL << offset)); Write(new_value); } - } else if constexpr (std::is_same::value) { - log::Err("TODO\n"); - } else if constexpr (std::is_same::value) { - log::Err("TODO\n"); - } else if constexpr (std::is_same::value) { - log::Err("TODO\n"); - } else if constexpr (std::is_same::value) { - log::Err("TODO\n"); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { + klog::Err("TODO\n"); + } else if constexpr (std::is_same::value) { + klog::Err("TODO\n"); + } else if constexpr (std::is_same::value) { + klog::Err("TODO\n"); + } else if constexpr (std::is_same::value) { + klog::Err("TODO\n"); + } else if constexpr (std::is_same::value) { __asm__ volatile("btr %%cr0, %0" : : "r"(offset) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("btr %%cr2, %0" : : "r"(offset) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("btr %%cr3, %0" : : "r"(offset) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("btr %%cr4, %0" : : "r"(offset) :); - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value) { __asm__ volatile("btr %%cr8, %0" : : "r"(offset) :); - } else if constexpr (std::is_same::value) { - log::Err("TODO\n"); + } else if constexpr (std::is_same::value) { + klog::Err("TODO\n"); } else { - log::Err("No Type\n"); + klog::Err("No Type\n"); throw; } } @@ -1552,16 +1162,17 @@ class ReadOnlyField { * @return RegInfo::DataType 指定位值的信息 */ static __always_inline RegInfo::DataType Get() { - if constexpr (std::is_same::value) { + if constexpr (std::is_same::value) { return Reg::Read().limit; } else if constexpr (std::is_same::value) { + register_info::GdtrInfo::Base>::value) { return Reg::Read().base; } else if constexpr (std::is_same::value) { + register_info::IdtrInfo::Limit>::value) { return Reg::Read().limit; } else if constexpr (std::is_same::value) { + register_info::IdtrInfo::Base>::value) { return Reg::Read().base; } else { return (typename RegInfo::DataType)((Reg::Read() & RegInfo::kBitMask) >> @@ -1575,16 +1186,17 @@ class ReadOnlyField { * @return RegInfo::DataType 指定位值的信息 */ static __always_inline RegInfo::DataType Get(RegInfo::DataType value) { - if constexpr (std::is_same::value) { + if constexpr (std::is_same::value) { return value; } else if constexpr (std::is_same::value) { + register_info::GdtrInfo::Base>::value) { return value; } else if constexpr (std::is_same::value) { + register_info::IdtrInfo::Limit>::value) { return value; } else if constexpr (std::is_same::value) { + register_info::IdtrInfo::Base>::value) { return value; } else { return (typename RegInfo::DataType)((value & RegInfo::kBitMask) >> @@ -1668,7 +1280,7 @@ class ReadWriteField : public ReadOnlyField, }; // 第三部分:寄存器实例 -class Rbp : public ReadWriteRegBase { +class Rbp : public ReadWriteRegBase { public: friend sk_std::ostream &operator<<(sk_std::ostream &os, const Rbp &rbp) { printf("val: 0x%p", (void *)rbp.Read()); @@ -1676,15 +1288,19 @@ class Rbp : public ReadWriteRegBase { } }; -class Efer : public ReadWriteRegBase { +class Efer : public ReadWriteRegBase { public: - ReadWriteField, reginfo::EferInfo::Sce> + ReadWriteField, + register_info::EferInfo::Sce> sce; - ReadWriteField, reginfo::EferInfo::Lme> + ReadWriteField, + register_info::EferInfo::Lme> lme; - ReadWriteField, reginfo::EferInfo::Lma> + ReadWriteField, + register_info::EferInfo::Lma> lma; - ReadWriteField, reginfo::EferInfo::Nxe> + ReadWriteField, + register_info::EferInfo::Nxe> nxe; /// @name 构造/析构函数 @@ -1713,9 +1329,10 @@ class Efer : public ReadWriteRegBase { } }; -class Rflags : public ReadWriteRegBase { +class Rflags : public ReadWriteRegBase { public: - ReadWriteField, reginfo::RflagsInfo::If> + ReadWriteField, + register_info::RflagsInfo::If> interrupt_enable_flag; /// @name 构造/析构函数 @@ -1737,11 +1354,13 @@ class Rflags : public ReadWriteRegBase { } }; -class Gdtr : public ReadWriteRegBase { +class Gdtr : public ReadWriteRegBase { public: - ReadWriteField, reginfo::GdtrInfo::Limit> + ReadWriteField, + register_info::GdtrInfo::Limit> limit; - ReadWriteField, reginfo::GdtrInfo::Base> + ReadWriteField, + register_info::GdtrInfo::Base> base; friend sk_std::ostream &operator<<(sk_std::ostream &os, const Gdtr &gdtr) { @@ -1751,7 +1370,7 @@ class Gdtr : public ReadWriteRegBase { } }; -class Ldtr : public ReadWriteRegBase { +class Ldtr : public ReadWriteRegBase { public: friend sk_std::ostream &operator<<(sk_std::ostream &os, const Ldtr &ldtr) { printf("val: 0x%p", (void *)ldtr.Read()); @@ -1759,11 +1378,13 @@ class Ldtr : public ReadWriteRegBase { } }; -class Idtr : public ReadWriteRegBase { +class Idtr : public ReadWriteRegBase { public: - ReadWriteField, reginfo::IdtrInfo::Limit> + ReadWriteField, + register_info::IdtrInfo::Limit> limit; - ReadWriteField, reginfo::IdtrInfo::Base> + ReadWriteField, + register_info::IdtrInfo::Base> base; friend sk_std::ostream &operator<<(sk_std::ostream &os, const Idtr &idtr) { @@ -1773,7 +1394,7 @@ class Idtr : public ReadWriteRegBase { } }; -class Tr : public ReadWriteRegBase { +class Tr : public ReadWriteRegBase { public: friend sk_std::ostream &operator<<(sk_std::ostream &os, const Tr &tr) { printf("val: 0x%p", (void *)tr.Read()); @@ -1783,13 +1404,13 @@ class Tr : public ReadWriteRegBase { namespace cr { -class Cr0 : public ReadWriteRegBase { +class Cr0 : public ReadWriteRegBase { public: - ReadWriteField, - reginfo::cr::Cr0Info::Pe> + ReadWriteField, + register_info::cr::Cr0Info::Pe> pe; - ReadWriteField, - reginfo::cr::Cr0Info::Pg> + ReadWriteField, + register_info::cr::Cr0Info::Pg> pg; /// @name 构造/析构函数 @@ -1814,7 +1435,7 @@ class Cr0 : public ReadWriteRegBase { } }; -class Cr2 : public ReadWriteRegBase { +class Cr2 : public ReadWriteRegBase { public: friend sk_std::ostream &operator<<(sk_std::ostream &os, const Cr2 &cr2) { printf("val: 0x%p", (void *)cr2.Read()); @@ -1822,16 +1443,16 @@ class Cr2 : public ReadWriteRegBase { } }; -class Cr3 : public ReadWriteRegBase { +class Cr3 : public ReadWriteRegBase { public: - ReadWriteField, - reginfo::cr::Cr3Info::Pwt> + ReadWriteField, + register_info::cr::Cr3Info::Pwt> pwt; - ReadWriteField, - reginfo::cr::Cr3Info::Pcd> + ReadWriteField, + register_info::cr::Cr3Info::Pcd> pcd; - ReadWriteField, - reginfo::cr::Cr3Info::PageDirectoryBase> + ReadWriteField, + register_info::cr::Cr3Info::PageDirectoryBase> page_directory_base; /// @name 构造/析构函数 @@ -1855,10 +1476,10 @@ class Cr3 : public ReadWriteRegBase { } }; -class Cr4 : public ReadWriteRegBase { +class Cr4 : public ReadWriteRegBase { public: - ReadWriteField, - reginfo::cr::Cr4Info::Pae> + ReadWriteField, + register_info::cr::Cr4Info::Pae> pae; /// @name 构造/析构函数 @@ -1879,7 +1500,7 @@ class Cr4 : public ReadWriteRegBase { } }; -class Cr8 : public ReadWriteRegBase { +class Cr8 : public ReadWriteRegBase { public: friend sk_std::ostream &operator<<(sk_std::ostream &os, const Cr8 &cr8) { printf("val: 0x%p", (void *)cr8.Read()); @@ -1889,7 +1510,7 @@ class Cr8 : public ReadWriteRegBase { }; // namespace cr -class Cpuid : public ReadOnlyRegBase { +class Cpuid : public ReadOnlyRegBase { public: friend sk_std::ostream &operator<<(sk_std::ostream &os, const Cpuid &cpuid) { printf("val: 0x%p", (void *)cpuid.Read()); @@ -1897,7 +1518,7 @@ class Cpuid : public ReadOnlyRegBase { } }; -class Xcr0 : public ReadWriteRegBase { +class Xcr0 : public ReadWriteRegBase { public: friend sk_std::ostream &operator<<(sk_std::ostream &os, const Xcr0 &xcr0) { printf("val: 0x%p", (void *)xcr0.Read()); @@ -1906,18 +1527,18 @@ class Xcr0 : public ReadWriteRegBase { }; namespace segment_register { -class Cs : public ReadWriteRegBase { +class Cs : public ReadWriteRegBase { public: - ReadOnlyField, - reginfo::segment_register::CsInfo::Rpl> + ReadOnlyField, + register_info::segment_register::CsInfo::Rpl> rpl; - ReadOnlyField, - reginfo::segment_register::CsInfo::Ti> + ReadOnlyField, + register_info::segment_register::CsInfo::Ti> ti; - ReadOnlyField, - reginfo::segment_register::CsInfo::Index> + ReadOnlyField, + register_info::segment_register::CsInfo::Index> index; /// @name 构造/析构函数 @@ -1941,18 +1562,18 @@ class Cs : public ReadWriteRegBase { } }; -class Ss : public ReadWriteRegBase { +class Ss : public ReadWriteRegBase { public: - ReadWriteField, - reginfo::segment_register::SsInfo::Rpl> + ReadWriteField, + register_info::segment_register::SsInfo::Rpl> rpl; - ReadWriteField, - reginfo::segment_register::SsInfo::Ti> + ReadWriteField, + register_info::segment_register::SsInfo::Ti> ti; - ReadWriteField, - reginfo::segment_register::SsInfo::Index> + ReadWriteField, + register_info::segment_register::SsInfo::Index> index; /// @name 构造/析构函数 @@ -1976,18 +1597,18 @@ class Ss : public ReadWriteRegBase { } }; -class Ds : public ReadWriteRegBase { +class Ds : public ReadWriteRegBase { public: - ReadWriteField, - reginfo::segment_register::DsInfo::Rpl> + ReadWriteField, + register_info::segment_register::DsInfo::Rpl> rpl; - ReadWriteField, - reginfo::segment_register::DsInfo::Ti> + ReadWriteField, + register_info::segment_register::DsInfo::Ti> ti; - ReadWriteField, - reginfo::segment_register::DsInfo::Index> + ReadWriteField, + register_info::segment_register::DsInfo::Index> index; /// @name 构造/析构函数 @@ -2011,18 +1632,18 @@ class Ds : public ReadWriteRegBase { } }; -class Es : public ReadWriteRegBase { +class Es : public ReadWriteRegBase { public: - ReadWriteField, - reginfo::segment_register::EsInfo::Rpl> + ReadWriteField, + register_info::segment_register::EsInfo::Rpl> rpl; - ReadWriteField, - reginfo::segment_register::EsInfo::Ti> + ReadWriteField, + register_info::segment_register::EsInfo::Ti> ti; - ReadWriteField, - reginfo::segment_register::EsInfo::Index> + ReadWriteField, + register_info::segment_register::EsInfo::Index> index; /// @name 构造/析构函数 @@ -2046,18 +1667,18 @@ class Es : public ReadWriteRegBase { } }; -class Fs : public ReadWriteRegBase { +class Fs : public ReadWriteRegBase { public: - ReadWriteField, - reginfo::segment_register::FsInfo::Rpl> + ReadWriteField, + register_info::segment_register::FsInfo::Rpl> rpl; - ReadWriteField, - reginfo::segment_register::FsInfo::Ti> + ReadWriteField, + register_info::segment_register::FsInfo::Ti> ti; - ReadWriteField, - reginfo::segment_register::FsInfo::Index> + ReadWriteField, + register_info::segment_register::FsInfo::Index> index; /// @name 构造/析构函数 @@ -2081,18 +1702,18 @@ class Fs : public ReadWriteRegBase { } }; -class Gs : public ReadWriteRegBase { +class Gs : public ReadWriteRegBase { public: - ReadWriteField, - reginfo::segment_register::GsInfo::Rpl> + ReadWriteField, + register_info::segment_register::GsInfo::Rpl> rpl; - ReadWriteField, - reginfo::segment_register::GsInfo::Ti> + ReadWriteField, + register_info::segment_register::GsInfo::Ti> ti; - ReadWriteField, - reginfo::segment_register::GsInfo::Index> + ReadWriteField, + register_info::segment_register::GsInfo::Index> index; /// @name 构造/析构函数 @@ -2146,54 +1767,10 @@ struct AllCr { }; // namespace -/// 中断上下文,由 cpu 自动压入,无错误码 -struct InterruptContext { - uint64_t rip; - uint64_t cs; - uint64_t rflags; - uint64_t rsp; - uint64_t ss; - - friend sk_std::ostream &operator<<( - sk_std::ostream &os, const InterruptContext &interrupt_context) { - printf("rip: 0x%lX\n", interrupt_context.rip); - printf("cs: 0x%lX\n", interrupt_context.cs); - printf("rflags: 0x%lX\n", interrupt_context.rflags); - printf("rsp: 0x%lX\n", interrupt_context.rsp); - printf("ss: 0x%lX", interrupt_context.ss); - return os; - } -}; - -/// 中断上下文,由 cpu 自动压入,有错误码 -struct InterruptContextErrorCode { - reginfo::IdtrInfo::ErrorCode error_code; - uint32_t padding; - uint64_t rip; - uint64_t cs; - uint64_t rflags; - uint64_t rsp; - uint64_t ss; - - friend sk_std::ostream &operator<<( - sk_std::ostream &os, - const InterruptContextErrorCode &interrupt_context_error_code) { - sk_std::cout << sk_std::endl - << interrupt_context_error_code.error_code << sk_std::endl; - printf("padding: 0x%X\n", interrupt_context_error_code.padding); - printf("rip: 0x%lX\n", interrupt_context_error_code.rip); - printf("cs: 0x%lX\n", interrupt_context_error_code.cs); - printf("rflags: 0x%lX\n", interrupt_context_error_code.rflags); - printf("rsp: 0x%lX\n", interrupt_context_error_code.rsp); - printf("ss: 0x%lX", interrupt_context_error_code.ss); - return os; - } -}; - // 第四部分:访问接口 [[maybe_unused]] static AllXreg kAllXreg; [[maybe_unused]] static AllCr kAllCr; }; // namespace cpu -#endif // SIMPLEKERNEL_SRC_KERNEL_ARCH_X86_64_INCLUDE_CPU_HPP_ +#endif // SIMPLEKERNEL_SRC_KERNEL_ARCH_X86_64_INCLUDE_CPU_CR_HPP_ diff --git a/src/kernel/arch/x86_64/interrupt.cpp b/src/kernel/arch/x86_64/interrupt.cpp index f05d4a1c5..ae798df9a 100644 --- a/src/kernel/arch/x86_64/interrupt.cpp +++ b/src/kernel/arch/x86_64/interrupt.cpp @@ -16,16 +16,16 @@ #include "interrupt.h" #include "arch.h" -#include "cpu.hpp" +#include "cpu/cpu.hpp" #include "kernel_log.hpp" #include "sk_cstdio" #include "sk_iostream" -Interrupt::InterruptFunc - Interrupt::interrupt_handlers[cpu::reginfo::IdtrInfo::kInterruptMaxCount]; +Interrupt::InterruptFunc Interrupt::interrupt_handlers + [cpu::register_info::IdtrInfo::kInterruptMaxCount]; -cpu::reginfo::IdtrInfo::Idt - Interrupt::idts[cpu::reginfo::IdtrInfo::kInterruptMaxCount]; +cpu::register_info::IdtrInfo::Idt + Interrupt::idts[cpu::register_info::IdtrInfo::kInterruptMaxCount]; /** * @brief 中断处理函数 @@ -42,18 +42,18 @@ TarpEntry(uint8_t *interrupt_context) { template void Interrupt::SetUpIdtr() { - if constexpr (no < cpu::reginfo::IdtrInfo::kInterruptMaxCount - 1) { - idts[no] = cpu::reginfo::IdtrInfo::Idt( + if constexpr (no < cpu::register_info::IdtrInfo::kInterruptMaxCount - 1) { + idts[no] = cpu::register_info::IdtrInfo::Idt( (uint64_t)TarpEntry, 8, 0x0, - cpu::reginfo::IdtrInfo::Idt::Type::k64BitInterruptGate, - cpu::reginfo::IdtrInfo::Idt::DPL::kRing0, - cpu::reginfo::IdtrInfo::Idt::P::kPresent); + cpu::register_info::IdtrInfo::Idt::Type::k64BitInterruptGate, + cpu::register_info::IdtrInfo::Idt::DPL::kRing0, + cpu::register_info::IdtrInfo::Idt::P::kPresent); SetUpIdtr(); } else { // 写入 idtr - static auto idtr = cpu::reginfo::IdtrInfo::Idtr{ - .limit = sizeof(cpu::reginfo::IdtrInfo::Idtr) * - cpu::reginfo::IdtrInfo::kInterruptMaxCount - + static auto idtr = cpu::register_info::IdtrInfo::Idtr{ + .limit = sizeof(cpu::register_info::IdtrInfo::Idtr) * + cpu::register_info::IdtrInfo::kInterruptMaxCount - 1, .base = idts, }; @@ -62,24 +62,25 @@ void Interrupt::SetUpIdtr() { // 输出 idtr 信息 sk_std::cout << cpu::kAllCr.idtr << sk_std::endl; for (size_t i = 0; i < (cpu::kAllCr.idtr.Read().limit + 1) / - sizeof(cpu::reginfo::IdtrInfo::Idtr); + sizeof(cpu::register_info::IdtrInfo::Idtr); i++) { - log::Debug("idtr[%d] 0x%p\n", i, cpu::kAllCr.idtr.Read().base + i); - log::debug << *(cpu::kAllCr.idtr.Read().base + i) << sk_std::endl; + klog::Debug("idtr[%d] 0x%p\n", i, cpu::kAllCr.idtr.Read().base + i); + klog::debug << *(cpu::kAllCr.idtr.Read().base + i) << sk_std::endl; } } } Interrupt::Interrupt() - : pic_(cpu::reginfo::IdtrInfo::kIrq0, cpu::reginfo::IdtrInfo::kIrq8), + : pic_(cpu::register_info::IdtrInfo::kIrq0, + cpu::register_info::IdtrInfo::kIrq8), pit_(200) { if (is_inited == false) { // 注册默认中断处理函数 for (auto &i : interrupt_handlers) { i = [](uint64_t cause, uint8_t *context) -> uint64_t { - log::Info("Default Interrupt handler [%s] 0x%X, 0x%p\n", - cpu::reginfo::IdtrInfo::kInterruptNames[cause], cause, - context); + klog::Info("Default Interrupt handler [%s] 0x%X, 0x%p\n", + cpu::register_info::IdtrInfo::kInterruptNames[cause], cause, + context); DumpStack(); while (1); }; @@ -95,20 +96,21 @@ Interrupt::Interrupt() is_inited = true; } - log::Info("Interrupt init.\n"); + klog::Info("Interrupt init.\n"); } void Interrupt::Do(uint64_t cause, uint8_t *context) { - if (cause < cpu::reginfo::IdtrInfo::kInterruptMaxCount) { + if (cause < cpu::register_info::IdtrInfo::kInterruptMaxCount) { interrupt_handlers[cause](cause, context); } } void Interrupt::RegisterInterruptFunc(uint64_t cause, InterruptFunc func) { - if (cause < cpu::reginfo::IdtrInfo::kInterruptMaxCount) { + if (cause < cpu::register_info::IdtrInfo::kInterruptMaxCount) { interrupt_handlers[cause] = func; - log::Debug("RegisterInterruptFunc [%s] 0x%X, 0x%p\n", - cpu::reginfo::IdtrInfo::kInterruptNames[cause], cause, func); + klog::Debug("RegisterInterruptFunc [%s] 0x%X, 0x%p\n", + cpu::register_info::IdtrInfo::kInterruptNames[cause], cause, + func); } } @@ -128,23 +130,24 @@ uint32_t InterruptInit(uint32_t, uint8_t *) { // 注册时钟中断 kInterrupt.GetInstance().RegisterInterruptFunc( - cpu::reginfo::IdtrInfo::kIrq0, + cpu::register_info::IdtrInfo::kIrq0, [](uint64_t exception_code, uint8_t *) -> uint64_t { kInterrupt.GetInstance().pit_.Ticks(); if (kInterrupt.GetInstance().pit_.GetTicks() % 100 == 0) { - log::Info("Handle %d %s\n", exception_code, - cpu::reginfo::IdtrInfo::kInterruptNames[exception_code]); + klog::Info( + "Handle %d %s\n", exception_code, + cpu::register_info::IdtrInfo::kInterruptNames[exception_code]); } kInterrupt.GetInstance().pic_.Clear(exception_code); return 0; }); // 允许时钟中断 - kInterrupt.GetInstance().pic_.Enable(cpu::reginfo::IdtrInfo::kIrq0); + kInterrupt.GetInstance().pic_.Enable(cpu::register_info::IdtrInfo::kIrq0); // 开启中断 cpu::kAllCr.rflags.interrupt_enable_flag.Set(); - log::Info("Hello InterruptInit\n"); + klog::Info("Hello InterruptInit\n"); return 0; } diff --git a/src/kernel/arch/x86_64/interrupt.h b/src/kernel/arch/x86_64/interrupt.h index c0cf1b834..828557251 100644 --- a/src/kernel/arch/x86_64/interrupt.h +++ b/src/kernel/arch/x86_64/interrupt.h @@ -19,7 +19,7 @@ #include -#include "cpu.hpp" +#include "cpu/cpu.hpp" #include "interrupt_base.h" #include "singleton.hpp" #include "sk_stdio.h" @@ -57,10 +57,10 @@ class Interrupt final : public InterruptBase { private: /// 中断处理函数数组 static InterruptFunc - interrupt_handlers[cpu::reginfo::IdtrInfo::kInterruptMaxCount]; + interrupt_handlers[cpu::register_info::IdtrInfo::kInterruptMaxCount]; - static cpu::reginfo::IdtrInfo::Idt - idts[cpu::reginfo::IdtrInfo::kInterruptMaxCount]; + static cpu::register_info::IdtrInfo::Idt + idts[cpu::register_info::IdtrInfo::kInterruptMaxCount]; /** * @brief 初始化 idtr diff --git a/src/kernel/include/kernel_elf.hpp b/src/kernel/include/kernel_elf.hpp index 5bfa84e89..f23cf577d 100644 --- a/src/kernel/include/kernel_elf.hpp +++ b/src/kernel/include/kernel_elf.hpp @@ -44,7 +44,7 @@ class KernelElf { */ explicit KernelElf(uint64_t elf_addr, size_t elf_size = 64) { if (!elf_addr || !elf_size) { - log::Err("Fatal Error: Invalid elf_addr or elf_size.\n"); + klog::Err("Fatal Error: Invalid elf_addr or elf_size.\n"); throw; } @@ -53,7 +53,7 @@ class KernelElf { // 检查 elf 头数据 auto check_elf_identity_ret = CheckElfIdentity(); if (!check_elf_identity_ret) { - log::Err("KernelElf NOT valid ELF file.\n"); + klog::Err("KernelElf NOT valid ELF file.\n"); throw; } @@ -106,15 +106,15 @@ class KernelElf { [[nodiscard]] bool CheckElfIdentity() const { if ((elf_[EI_MAG0] != ELFMAG0) || (elf_[EI_MAG1] != ELFMAG1) || (elf_[EI_MAG2] != ELFMAG2) || (elf_[EI_MAG3] != ELFMAG3)) { - log::Err("Fatal Error: Invalid ELF header.\n"); + klog::Err("Fatal Error: Invalid ELF header.\n"); throw; } if (elf_[EI_CLASS] == ELFCLASS32) { - log::Err("Found 32bit executable but NOT SUPPORT.\n"); + klog::Err("Found 32bit executable but NOT SUPPORT.\n"); throw; } if (elf_[EI_CLASS] != ELFCLASS64) { - log::Err("Fatal Error: Invalid executable.\n"); + klog::Err("Fatal Error: Invalid executable.\n"); throw; } return true; diff --git a/src/kernel/include/kernel_fdt.hpp b/src/kernel/include/kernel_fdt.hpp index d1fb6dab4..ca8fa8628 100644 --- a/src/kernel/include/kernel_fdt.hpp +++ b/src/kernel/include/kernel_fdt.hpp @@ -48,13 +48,13 @@ class KernelFdt { */ explicit KernelFdt(uint64_t fdt_addr) : fdt_addr_((void *)fdt_addr) { if (!fdt_addr_) { - log::Err("Fatal Error: Invalid fdt_addr.\n"); + klog::Err("Fatal Error: Invalid fdt_addr.\n"); throw; } // 检查 fdt 头数据 if (fdt_check_header(fdt_addr_) != 0) { - log::Err("Invalid device tree blob\n"); + klog::Err("Invalid device tree blob\n"); throw; } } @@ -82,14 +82,14 @@ class KernelFdt { // 找到 /memory 节点 auto offset = fdt_path_offset(fdt_addr_, "/memory"); if (offset < 0) { - log::Err("Error finding /memory node: %s\n", fdt_strerror(offset)); + klog::Err("Error finding /memory node: %s\n", fdt_strerror(offset)); throw; } // 获取 reg 属性 auto prop = fdt_get_property(fdt_addr_, offset, "reg", &len); if (!prop) { - log::Err("Error finding reg property: %s\n", fdt_strerror(len)); + klog::Err("Error finding reg property: %s\n", fdt_strerror(len)); throw; } @@ -115,14 +115,14 @@ class KernelFdt { // 找到 /memory 节点 auto offset = fdt_path_offset(fdt_addr_, "/soc/serial"); if (offset < 0) { - log::Err("Error finding /soc/serial node: %s\n", fdt_strerror(offset)); + klog::Err("Error finding /soc/serial node: %s\n", fdt_strerror(offset)); throw; } // 获取 reg 属性 auto prop = fdt_get_property(fdt_addr_, offset, "reg", &len); if (!prop) { - log::Err("Error finding reg property: %s\n", fdt_strerror(len)); + klog::Err("Error finding reg property: %s\n", fdt_strerror(len)); throw; } diff --git a/src/kernel/include/kernel_log.hpp b/src/kernel/include/kernel_log.hpp index 34c017f14..de9a0d3e2 100644 --- a/src/kernel/include/kernel_log.hpp +++ b/src/kernel/include/kernel_log.hpp @@ -86,7 +86,7 @@ class Logger : public sk_std::ostream { } // namespace -namespace log { +namespace klog { /** * @brief 与 printf 类似,只是颜色不同 */ diff --git a/src/kernel/main.cpp b/src/kernel/main.cpp index a9f7129a5..6c4b235d4 100644 --- a/src/kernel/main.cpp +++ b/src/kernel/main.cpp @@ -38,14 +38,14 @@ uint32_t main(uint32_t argc, uint8_t *argv) { [[maybe_unused]] auto arch_init_ret = ArchInit(argc, argv); printf("Hello SimpleKernel\n"); - log::Debug("Hello SimpleKernel\n"); - log::Info("Hello SimpleKernel\n"); - log::Warn("Hello SimpleKernel\n"); - log::Err("Hello SimpleKernel\n"); - log::debug << "Hello SimpleKernel\n"; - log::info << "Hello SimpleKernel\n"; - log::warn << "Hello SimpleKernel\n"; - log::err << "Hello SimpleKernel\n"; + klog::Debug("Hello SimpleKernel\n"); + klog::Info("Hello SimpleKernel\n"); + klog::Warn("Hello SimpleKernel\n"); + klog::Err("Hello SimpleKernel\n"); + klog::debug << "Hello SimpleKernel\n"; + klog::info << "Hello SimpleKernel\n"; + klog::warn << "Hello SimpleKernel\n"; + klog::err << "Hello SimpleKernel\n"; DumpStack(); diff --git a/test/system_test/cxx_init_test/main.cpp b/test/system_test/cxx_init_test/main.cpp index e1296e891..9d1c02a28 100644 --- a/test/system_test/cxx_init_test/main.cpp +++ b/test/system_test/cxx_init_test/main.cpp @@ -17,7 +17,7 @@ #include #include "basic_info.hpp" -#include "cpu.hpp" +#include "cpu/cpu.hpp" #include "sk_cstdio" #include "sk_cstring" #include "sk_libcxx.h" diff --git a/test/system_test/gnu_efi_test/main.cpp b/test/system_test/gnu_efi_test/main.cpp index c937366fc..12008af63 100644 --- a/test/system_test/gnu_efi_test/main.cpp +++ b/test/system_test/gnu_efi_test/main.cpp @@ -17,7 +17,7 @@ #include #include "basic_info.hpp" -#include "cpu.hpp" +#include "cpu/cpu.hpp" #include "sk_cstdio" #include "sk_cstring" diff --git a/test/unit_test/CMakeLists.txt b/test/unit_test/CMakeLists.txt index 9646735c8..b447ccef7 100644 --- a/test/unit_test/CMakeLists.txt +++ b/test/unit_test/CMakeLists.txt @@ -21,6 +21,7 @@ add_executable(${PROJECT_NAME} ) target_include_directories(${PROJECT_NAME} PRIVATE + ./ ${CMAKE_SOURCE_DIR}/src/kernel/include ${CMAKE_SOURCE_DIR}/src/kernel/arch ) @@ -35,7 +36,7 @@ target_link_options(${PROJECT_NAME} PRIVATE target_link_libraries(${PROJECT_NAME} PRIVATE ${DEFAULT_TEST_LINK_LIB} - ${dtc_BINARY_DIR}/libfdt/libfdt.a + dtc-lib ) gtest_discover_tests(${PROJECT_NAME}) diff --git a/test/unit_test/aarch64_cpu_test.cpp b/test/unit_test/aarch64_cpu_test.cpp index 90a9f5fec..964360f70 100644 --- a/test/unit_test/aarch64_cpu_test.cpp +++ b/test/unit_test/aarch64_cpu_test.cpp @@ -16,18 +16,18 @@ #include -#include "aarch64/include/cpu.hpp" +#include "aarch64/include/cpu/cpu.hpp" TEST(Aarch64RegInfoBaseTest, ValueTest) { - EXPECT_EQ(cpu::reginfo::RegInfoBase::kBitOffset, 0); - EXPECT_EQ(cpu::reginfo::RegInfoBase::kBitWidth, 64); - EXPECT_EQ(cpu::reginfo::RegInfoBase::kBitMask, 0xFFFFFFFFFFFFFFFF); - EXPECT_EQ(cpu::reginfo::RegInfoBase::kAllSetMask, 0xFFFFFFFFFFFFFFFF); + EXPECT_EQ(cpu::register_info::RegInfoBase::kBitOffset, 0); + EXPECT_EQ(cpu::register_info::RegInfoBase::kBitWidth, 64); + EXPECT_EQ(cpu::register_info::RegInfoBase::kBitMask, 0xFFFFFFFFFFFFFFFF); + EXPECT_EQ(cpu::register_info::RegInfoBase::kAllSetMask, 0xFFFFFFFFFFFFFFFF); } TEST(Aarch64X29InfoTest, ValueTest) { - EXPECT_EQ(cpu::reginfo::X29Info::kBitOffset, 0); - EXPECT_EQ(cpu::reginfo::X29Info::kBitWidth, 64); - EXPECT_EQ(cpu::reginfo::X29Info::kBitMask, 0xFFFFFFFFFFFFFFFF); - EXPECT_EQ(cpu::reginfo::X29Info::kAllSetMask, 0xFFFFFFFFFFFFFFFF); + EXPECT_EQ(cpu::register_info::X29Info::kBitOffset, 0); + EXPECT_EQ(cpu::register_info::X29Info::kBitWidth, 64); + EXPECT_EQ(cpu::register_info::X29Info::kBitMask, 0xFFFFFFFFFFFFFFFF); + EXPECT_EQ(cpu::register_info::X29Info::kAllSetMask, 0xFFFFFFFFFFFFFFFF); } diff --git a/test/unit_test/riscv64_cpu_test.cpp b/test/unit_test/riscv64_cpu_test.cpp index f882ad582..430e2dd78 100644 --- a/test/unit_test/riscv64_cpu_test.cpp +++ b/test/unit_test/riscv64_cpu_test.cpp @@ -16,126 +16,128 @@ #include -#include "riscv64/include/cpu.hpp" +#include "riscv64/include/cpu/cpu.hpp" TEST(Riscv64RegInfoBaseTest, ValueTest) { - EXPECT_EQ(cpu::reginfo::RegInfoBase::kBitOffset, 0); - EXPECT_EQ(cpu::reginfo::RegInfoBase::kBitWidth, 64); - EXPECT_EQ(cpu::reginfo::RegInfoBase::kBitMask, 0xFFFFFFFFFFFFFFFF); - EXPECT_EQ(cpu::reginfo::RegInfoBase::kAllSetMask, 0xFFFFFFFFFFFFFFFF); + EXPECT_EQ(cpu::register_info::RegInfoBase::kBitOffset, 0); + EXPECT_EQ(cpu::register_info::RegInfoBase::kBitWidth, 64); + EXPECT_EQ(cpu::register_info::RegInfoBase::kBitMask, 0xFFFFFFFFFFFFFFFF); + EXPECT_EQ(cpu::register_info::RegInfoBase::kAllSetMask, 0xFFFFFFFFFFFFFFFF); } TEST(Riscv64FpInfoTest, ValueTest) { - EXPECT_EQ(cpu::reginfo::FpInfo::kBitOffset, 0); - EXPECT_EQ(cpu::reginfo::FpInfo::kBitWidth, 64); - EXPECT_EQ(cpu::reginfo::FpInfo::kBitMask, 0xFFFFFFFFFFFFFFFF); - EXPECT_EQ(cpu::reginfo::FpInfo::kAllSetMask, 0xFFFFFFFFFFFFFFFF); + EXPECT_EQ(cpu::register_info::FpInfo::kBitOffset, 0); + EXPECT_EQ(cpu::register_info::FpInfo::kBitWidth, 64); + EXPECT_EQ(cpu::register_info::FpInfo::kBitMask, 0xFFFFFFFFFFFFFFFF); + EXPECT_EQ(cpu::register_info::FpInfo::kAllSetMask, 0xFFFFFFFFFFFFFFFF); } TEST(Riscv64SstatusInfoSieTest, ValueTest) { - EXPECT_EQ(cpu::reginfo::csr::SstatusInfo::Sie::kBitOffset, 1); - EXPECT_EQ(cpu::reginfo::csr::SstatusInfo::Sie::kBitWidth, 1); - EXPECT_EQ(cpu::reginfo::csr::SstatusInfo::Sie::kBitMask, 2); - EXPECT_EQ(cpu::reginfo::csr::SstatusInfo::Sie::kAllSetMask, 1); + EXPECT_EQ(cpu::register_info::csr::SstatusInfo::Sie::kBitOffset, 1); + EXPECT_EQ(cpu::register_info::csr::SstatusInfo::Sie::kBitWidth, 1); + EXPECT_EQ(cpu::register_info::csr::SstatusInfo::Sie::kBitMask, 2); + EXPECT_EQ(cpu::register_info::csr::SstatusInfo::Sie::kAllSetMask, 1); } TEST(Riscv64SstatusInfoSpieTest, ValueTest) { - EXPECT_EQ(cpu::reginfo::csr::SstatusInfo::Spie::kBitOffset, 5); - EXPECT_EQ(cpu::reginfo::csr::SstatusInfo::Spie::kBitWidth, 1); - EXPECT_EQ(cpu::reginfo::csr::SstatusInfo::Spie::kBitMask, 0x20); - EXPECT_EQ(cpu::reginfo::csr::SstatusInfo::Spie::kAllSetMask, 1); + EXPECT_EQ(cpu::register_info::csr::SstatusInfo::Spie::kBitOffset, 5); + EXPECT_EQ(cpu::register_info::csr::SstatusInfo::Spie::kBitWidth, 1); + EXPECT_EQ(cpu::register_info::csr::SstatusInfo::Spie::kBitMask, 0x20); + EXPECT_EQ(cpu::register_info::csr::SstatusInfo::Spie::kAllSetMask, 1); } TEST(Riscv64SstatusInfoSppTest, ValueTest) { - EXPECT_EQ(cpu::reginfo::csr::SstatusInfo::Spp::kBitOffset, 8); - EXPECT_EQ(cpu::reginfo::csr::SstatusInfo::Spp::kBitWidth, 1); - EXPECT_EQ(cpu::reginfo::csr::SstatusInfo::Spp::kBitMask, 0x100); - EXPECT_EQ(cpu::reginfo::csr::SstatusInfo::Spp::kAllSetMask, 1); + EXPECT_EQ(cpu::register_info::csr::SstatusInfo::Spp::kBitOffset, 8); + EXPECT_EQ(cpu::register_info::csr::SstatusInfo::Spp::kBitWidth, 1); + EXPECT_EQ(cpu::register_info::csr::SstatusInfo::Spp::kBitMask, 0x100); + EXPECT_EQ(cpu::register_info::csr::SstatusInfo::Spp::kAllSetMask, 1); } TEST(Riscv64StvecInfoModeTest, ValueTest) { - EXPECT_EQ(cpu::reginfo::csr::StvecInfo::Mode::kBitOffset, 0); - EXPECT_EQ(cpu::reginfo::csr::StvecInfo::Mode::kBitWidth, 2); - EXPECT_EQ(cpu::reginfo::csr::StvecInfo::Mode::kBitMask, 0x3); - EXPECT_EQ(cpu::reginfo::csr::StvecInfo::Mode::kAllSetMask, 0x3); + EXPECT_EQ(cpu::register_info::csr::StvecInfo::Mode::kBitOffset, 0); + EXPECT_EQ(cpu::register_info::csr::StvecInfo::Mode::kBitWidth, 2); + EXPECT_EQ(cpu::register_info::csr::StvecInfo::Mode::kBitMask, 0x3); + EXPECT_EQ(cpu::register_info::csr::StvecInfo::Mode::kAllSetMask, 0x3); } TEST(Riscv64SipInfoSsipTest, ValueTest) { - EXPECT_EQ(cpu::reginfo::csr::SipInfo::Ssip::kBitOffset, 1); - EXPECT_EQ(cpu::reginfo::csr::SipInfo::Ssip::kBitWidth, 1); - EXPECT_EQ(cpu::reginfo::csr::SipInfo::Ssip::kBitMask, 0x2); - EXPECT_EQ(cpu::reginfo::csr::SipInfo::Ssip::kAllSetMask, 1); + EXPECT_EQ(cpu::register_info::csr::SipInfo::Ssip::kBitOffset, 1); + EXPECT_EQ(cpu::register_info::csr::SipInfo::Ssip::kBitWidth, 1); + EXPECT_EQ(cpu::register_info::csr::SipInfo::Ssip::kBitMask, 0x2); + EXPECT_EQ(cpu::register_info::csr::SipInfo::Ssip::kAllSetMask, 1); } TEST(Riscv64SipInfoStipTest, ValueTest) { - EXPECT_EQ(cpu::reginfo::csr::SipInfo::Stip::kBitOffset, 05); - EXPECT_EQ(cpu::reginfo::csr::SipInfo::Stip::kBitWidth, 1); - EXPECT_EQ(cpu::reginfo::csr::SipInfo::Stip::kBitMask, 0x20); - EXPECT_EQ(cpu::reginfo::csr::SipInfo::Stip::kAllSetMask, 1); + EXPECT_EQ(cpu::register_info::csr::SipInfo::Stip::kBitOffset, 05); + EXPECT_EQ(cpu::register_info::csr::SipInfo::Stip::kBitWidth, 1); + EXPECT_EQ(cpu::register_info::csr::SipInfo::Stip::kBitMask, 0x20); + EXPECT_EQ(cpu::register_info::csr::SipInfo::Stip::kAllSetMask, 1); } TEST(Riscv64SipInfoSeipTest, ValueTest) { - EXPECT_EQ(cpu::reginfo::csr::SipInfo::Seip::kBitOffset, 9); - EXPECT_EQ(cpu::reginfo::csr::SipInfo::Seip::kBitWidth, 1); - EXPECT_EQ(cpu::reginfo::csr::SipInfo::Seip::kBitMask, 0x200); - EXPECT_EQ(cpu::reginfo::csr::SipInfo::Seip::kAllSetMask, 1); + EXPECT_EQ(cpu::register_info::csr::SipInfo::Seip::kBitOffset, 9); + EXPECT_EQ(cpu::register_info::csr::SipInfo::Seip::kBitWidth, 1); + EXPECT_EQ(cpu::register_info::csr::SipInfo::Seip::kBitMask, 0x200); + EXPECT_EQ(cpu::register_info::csr::SipInfo::Seip::kAllSetMask, 1); } TEST(Riscv64SieInfoSsiepTest, ValueTest) { - EXPECT_EQ(cpu::reginfo::csr::SieInfo::Ssie::kBitOffset, 1); - EXPECT_EQ(cpu::reginfo::csr::SieInfo::Ssie::kBitWidth, 1); - EXPECT_EQ(cpu::reginfo::csr::SieInfo::Ssie::kBitMask, 0x2); - EXPECT_EQ(cpu::reginfo::csr::SieInfo::Ssie::kAllSetMask, 1); + EXPECT_EQ(cpu::register_info::csr::SieInfo::Ssie::kBitOffset, 1); + EXPECT_EQ(cpu::register_info::csr::SieInfo::Ssie::kBitWidth, 1); + EXPECT_EQ(cpu::register_info::csr::SieInfo::Ssie::kBitMask, 0x2); + EXPECT_EQ(cpu::register_info::csr::SieInfo::Ssie::kAllSetMask, 1); } TEST(Riscv64SieInfoStieTest, ValueTest) { - EXPECT_EQ(cpu::reginfo::csr::SieInfo::Stie::kBitOffset, 5); - EXPECT_EQ(cpu::reginfo::csr::SieInfo::Stie::kBitWidth, 1); - EXPECT_EQ(cpu::reginfo::csr::SieInfo::Stie::kBitMask, 0x20); - EXPECT_EQ(cpu::reginfo::csr::SieInfo::Stie::kAllSetMask, 1); + EXPECT_EQ(cpu::register_info::csr::SieInfo::Stie::kBitOffset, 5); + EXPECT_EQ(cpu::register_info::csr::SieInfo::Stie::kBitWidth, 1); + EXPECT_EQ(cpu::register_info::csr::SieInfo::Stie::kBitMask, 0x20); + EXPECT_EQ(cpu::register_info::csr::SieInfo::Stie::kAllSetMask, 1); } TEST(Riscv64SieInfoSeieTest, ValueTest) { - EXPECT_EQ(cpu::reginfo::csr::SieInfo::Seie::kBitOffset, 9); - EXPECT_EQ(cpu::reginfo::csr::SieInfo::Seie::kBitWidth, 1); - EXPECT_EQ(cpu::reginfo::csr::SieInfo::Seie::kBitMask, 0x200); - EXPECT_EQ(cpu::reginfo::csr::SieInfo::Seie::kAllSetMask, 1); + EXPECT_EQ(cpu::register_info::csr::SieInfo::Seie::kBitOffset, 9); + EXPECT_EQ(cpu::register_info::csr::SieInfo::Seie::kBitWidth, 1); + EXPECT_EQ(cpu::register_info::csr::SieInfo::Seie::kBitMask, 0x200); + EXPECT_EQ(cpu::register_info::csr::SieInfo::Seie::kAllSetMask, 1); } TEST(Riscv64ScauseInfoExceptionCodeTest, ValueTest) { - EXPECT_EQ(cpu::reginfo::csr::ScauseInfo::ExceptionCode::kBitOffset, 0); - EXPECT_EQ(cpu::reginfo::csr::ScauseInfo::ExceptionCode::kBitWidth, 63); - EXPECT_EQ(cpu::reginfo::csr::ScauseInfo::ExceptionCode::kBitMask, + EXPECT_EQ(cpu::register_info::csr::ScauseInfo::ExceptionCode::kBitOffset, 0); + EXPECT_EQ(cpu::register_info::csr::ScauseInfo::ExceptionCode::kBitWidth, 63); + EXPECT_EQ(cpu::register_info::csr::ScauseInfo::ExceptionCode::kBitMask, 0x7FFFFFFFFFFFFFFF); - EXPECT_EQ(cpu::reginfo::csr::ScauseInfo::ExceptionCode::kAllSetMask, + EXPECT_EQ(cpu::register_info::csr::ScauseInfo::ExceptionCode::kAllSetMask, 0x7FFFFFFFFFFFFFFF); } TEST(Riscv64ScauseInfoInterruptTest, ValueTest) { - EXPECT_EQ(cpu::reginfo::csr::ScauseInfo::Interrupt::kBitOffset, 63); - EXPECT_EQ(cpu::reginfo::csr::ScauseInfo::Interrupt::kBitWidth, 1); - EXPECT_EQ(cpu::reginfo::csr::ScauseInfo::Interrupt::kBitMask, + EXPECT_EQ(cpu::register_info::csr::ScauseInfo::Interrupt::kBitOffset, 63); + EXPECT_EQ(cpu::register_info::csr::ScauseInfo::Interrupt::kBitWidth, 1); + EXPECT_EQ(cpu::register_info::csr::ScauseInfo::Interrupt::kBitMask, 0x8000000000000000); - EXPECT_EQ(cpu::reginfo::csr::ScauseInfo::Interrupt::kAllSetMask, 1); + EXPECT_EQ(cpu::register_info::csr::ScauseInfo::Interrupt::kAllSetMask, 1); } TEST(Riscv64SatpInfoPpnTest, ValueTest) { - EXPECT_EQ(cpu::reginfo::csr::SatpInfo::Ppn::kBitOffset, 0); - EXPECT_EQ(cpu::reginfo::csr::SatpInfo::Ppn::kBitWidth, 44); - EXPECT_EQ(cpu::reginfo::csr::SatpInfo::Ppn::kBitMask, 0xFFFFFFFFFFF); - EXPECT_EQ(cpu::reginfo::csr::SatpInfo::Ppn::kAllSetMask, 0xFFFFFFFFFFF); + EXPECT_EQ(cpu::register_info::csr::SatpInfo::Ppn::kBitOffset, 0); + EXPECT_EQ(cpu::register_info::csr::SatpInfo::Ppn::kBitWidth, 44); + EXPECT_EQ(cpu::register_info::csr::SatpInfo::Ppn::kBitMask, 0xFFFFFFFFFFF); + EXPECT_EQ(cpu::register_info::csr::SatpInfo::Ppn::kAllSetMask, 0xFFFFFFFFFFF); } TEST(Riscv64SatpInfoAsidTest, ValueTest) { - EXPECT_EQ(cpu::reginfo::csr::SatpInfo::Asid::kBitOffset, 44); - EXPECT_EQ(cpu::reginfo::csr::SatpInfo::Asid::kBitWidth, 16); - EXPECT_EQ(cpu::reginfo::csr::SatpInfo::Asid::kBitMask, ~0xF0000FFFFFFFFFFF); - EXPECT_EQ(cpu::reginfo::csr::SatpInfo::Asid::kAllSetMask, 0xFFFF); + EXPECT_EQ(cpu::register_info::csr::SatpInfo::Asid::kBitOffset, 44); + EXPECT_EQ(cpu::register_info::csr::SatpInfo::Asid::kBitWidth, 16); + EXPECT_EQ(cpu::register_info::csr::SatpInfo::Asid::kBitMask, + ~0xF0000FFFFFFFFFFF); + EXPECT_EQ(cpu::register_info::csr::SatpInfo::Asid::kAllSetMask, 0xFFFF); } TEST(Riscv64SatpInfoModeTest, ValueTest) { - EXPECT_EQ(cpu::reginfo::csr::SatpInfo::Mode::kBitOffset, 60); - EXPECT_EQ(cpu::reginfo::csr::SatpInfo::Mode::kBitWidth, 4); - EXPECT_EQ(cpu::reginfo::csr::SatpInfo::Mode::kBitMask, ~0xFFFFFFFFFFFFFFF); - EXPECT_EQ(cpu::reginfo::csr::SatpInfo::Mode::kAllSetMask, 0xF); + EXPECT_EQ(cpu::register_info::csr::SatpInfo::Mode::kBitOffset, 60); + EXPECT_EQ(cpu::register_info::csr::SatpInfo::Mode::kBitWidth, 4); + EXPECT_EQ(cpu::register_info::csr::SatpInfo::Mode::kBitMask, + ~0xFFFFFFFFFFFFFFF); + EXPECT_EQ(cpu::register_info::csr::SatpInfo::Mode::kAllSetMask, 0xF); } diff --git a/test/unit_test/sk_cstdio b/test/unit_test/sk_cstdio new file mode 100644 index 000000000..bbfe7e310 --- /dev/null +++ b/test/unit_test/sk_cstdio @@ -0,0 +1,22 @@ + +/** + * @file sk_cstdio + * @brief 测试使用的 sk_cstdio + * @author Zone.N (Zone.Niuzh@hotmail.com) + * @version 1.0 + * @date 2023-05-08 + * @copyright MIT LICENSE + * https://github.com/Simple-XX/SimpleKernel + * @par change log: + * + *
DateAuthorDescription + *
2023-05-08Zone.N创建文件 + *
+ */ + +#ifndef SIMPLEKERNEL_TEST_UNIT_TEST_SK_CSTDIO_ +#define SIMPLEKERNEL_TEST_UNIT_TEST_SK_CSTDIO_ + +#include "cstdio" + +#endif /* SIMPLEKERNEL_TEST_UNIT_TEST_SK_CSTDIO_ */ diff --git a/test/unit_test/sk_cstring b/test/unit_test/sk_cstring new file mode 100644 index 000000000..6d30ffda6 --- /dev/null +++ b/test/unit_test/sk_cstring @@ -0,0 +1,39 @@ + +/** + * @file sk_cstring + * @brief 测试使用的 sk_cstring + * @author Zone.N (Zone.Niuzh@hotmail.com) + * @version 1.0 + * @date 2023-05-08 + * @copyright MIT LICENSE + * https://github.com/Simple-XX/SimpleKernel + * @par change log: + * + *
DateAuthorDescription + *
2023-05-08Zone.N创建文件 + *
+ */ + +#ifndef SIMPLEKERNEL_TEST_UNIT_TEST_SK_CSTRING_ +#define SIMPLEKERNEL_TEST_UNIT_TEST_SK_CSTRING_ + +#include "cstring" + +namespace sk_std { + +using ::memcmp; +using ::memcpy; +using ::memmove; +using ::memset; +using ::strcat; +using ::strchr; +using ::strcmp; +using ::strcpy; +using ::strlen; +using ::strncmp; +using ::strncpy; +using ::strnlen; + +}; // namespace sk_std + +#endif /* SIMPLEKERNEL_TEST_UNIT_TEST_SK_CSTRING_ */ diff --git a/test/unit_test/sk_iostream b/test/unit_test/sk_iostream new file mode 100644 index 000000000..e2d9e35f9 --- /dev/null +++ b/test/unit_test/sk_iostream @@ -0,0 +1,92 @@ + +/** + * @file sk_iostream + * @brief 测试使用的 sk_iostream + * @author Zone.N (Zone.Niuzh@hotmail.com) + * @version 1.0 + * @date 2021-09-18 + * @copyright MIT LICENSE + * https://github.com/Simple-XX/SimpleKernel + * Based on https://github.com/MRNIU/MiniCRT + * @par change log: + * + *
DateAuthorDescription + *
2021-09-18digmouse233迁移到 doxygen + *
+ */ + +#ifndef SIMPLEKERNEL_TEST_UNIT_TEST_SK_IOSTREAM_ +#define SIMPLEKERNEL_TEST_UNIT_TEST_SK_IOSTREAM_ + +#include +#include + +namespace sk_std { +class ostream : public std::ostream { + public: + enum openmode : uint8_t { + in = 1, + out = 2, + binary = 4, + trunc = 8, + }; + + /// @name 构造/析构函数 + /// @{ + ostream() = default; + ostream(const ostream&) = default; + ostream(ostream&&) = default; + auto operator=(const ostream&) -> ostream& = default; + auto operator=(ostream&&) -> ostream& = default; + ~ostream() = default; + /// @} + + virtual ostream& operator<<(int8_t val) { + (void)val; + return *this; + } + virtual ostream& operator<<(uint8_t val) { + (void)val; + return *this; + } + virtual ostream& operator<<(const char* val) { + (void)val; + return *this; + } + virtual ostream& operator<<(int16_t val) { + (void)val; + return *this; + } + virtual ostream& operator<<(uint16_t val) { + (void)val; + return *this; + } + virtual ostream& operator<<(int32_t val) { + (void)val; + return *this; + } + virtual ostream& operator<<(uint32_t val) { + (void)val; + return *this; + } + virtual ostream& operator<<(int64_t val) { + (void)val; + return *this; + } + virtual ostream& operator<<(uint64_t val) { + (void)val; + return *this; + } + + virtual ostream& operator<<(ostream& (*manip)(ostream&)) { + return manip(*this); + } +}; + +inline ostream& endl(ostream& os) { return os << "\n"; } + +[[maybe_unused]] static ostream cout; + +}; // namespace sk_std + +#endif /* SIMPLEKERNEL_TEST_UNIT_TEST_SK_IOSTREAM_ */ diff --git a/test/unit_test/x86_64_cpu_test.cpp b/test/unit_test/x86_64_cpu_test.cpp index 730e144af..8f2c04a66 100644 --- a/test/unit_test/x86_64_cpu_test.cpp +++ b/test/unit_test/x86_64_cpu_test.cpp @@ -16,94 +16,96 @@ #include -#include "x86_64/include/cpu.hpp" +#include "x86_64/include/cpu/cpu.hpp" TEST(x8664RegInfoBaseTest, ValueTest) { - EXPECT_EQ(cpu::reginfo::RegInfoBase::kBitOffset, 0); - EXPECT_EQ(cpu::reginfo::RegInfoBase::kBitWidth, 64); - EXPECT_EQ(cpu::reginfo::RegInfoBase::kBitMask, 0xFFFFFFFFFFFFFFFF); - EXPECT_EQ(cpu::reginfo::RegInfoBase::kAllSetMask, 0xFFFFFFFFFFFFFFFF); + EXPECT_EQ(cpu::register_info::RegInfoBase::kBitOffset, 0); + EXPECT_EQ(cpu::register_info::RegInfoBase::kBitWidth, 64); + EXPECT_EQ(cpu::register_info::RegInfoBase::kBitMask, 0xFFFFFFFFFFFFFFFF); + EXPECT_EQ(cpu::register_info::RegInfoBase::kAllSetMask, 0xFFFFFFFFFFFFFFFF); } TEST(x8664RbpInfoTest, ValueTest) { - EXPECT_EQ(cpu::reginfo::RbpInfo::kBitOffset, 0); - EXPECT_EQ(cpu::reginfo::RbpInfo::kBitWidth, 64); - EXPECT_EQ(cpu::reginfo::RbpInfo::kBitMask, 0xFFFFFFFFFFFFFFFF); - EXPECT_EQ(cpu::reginfo::RbpInfo::kAllSetMask, 0xFFFFFFFFFFFFFFFF); + EXPECT_EQ(cpu::register_info::RbpInfo::kBitOffset, 0); + EXPECT_EQ(cpu::register_info::RbpInfo::kBitWidth, 64); + EXPECT_EQ(cpu::register_info::RbpInfo::kBitMask, 0xFFFFFFFFFFFFFFFF); + EXPECT_EQ(cpu::register_info::RbpInfo::kAllSetMask, 0xFFFFFFFFFFFFFFFF); } TEST(x8664EferInfoSceTest, ValueTest) { - EXPECT_EQ(cpu::reginfo::EferInfo::Sce::kBitOffset, 0); - EXPECT_EQ(cpu::reginfo::EferInfo::Sce::kBitWidth, 1); - EXPECT_EQ(cpu::reginfo::EferInfo::Sce::kBitMask, 0x1); - EXPECT_EQ(cpu::reginfo::EferInfo::Sce::kAllSetMask, 1); + EXPECT_EQ(cpu::register_info::EferInfo::Sce::kBitOffset, 0); + EXPECT_EQ(cpu::register_info::EferInfo::Sce::kBitWidth, 1); + EXPECT_EQ(cpu::register_info::EferInfo::Sce::kBitMask, 0x1); + EXPECT_EQ(cpu::register_info::EferInfo::Sce::kAllSetMask, 1); } TEST(x8664EferInfoLmeTest, ValueTest) { - EXPECT_EQ(cpu::reginfo::EferInfo::Lme::kBitOffset, 8); - EXPECT_EQ(cpu::reginfo::EferInfo::Lme::kBitWidth, 1); - EXPECT_EQ(cpu::reginfo::EferInfo::Lme::kBitMask, 0x100); - EXPECT_EQ(cpu::reginfo::EferInfo::Lme::kAllSetMask, 1); + EXPECT_EQ(cpu::register_info::EferInfo::Lme::kBitOffset, 8); + EXPECT_EQ(cpu::register_info::EferInfo::Lme::kBitWidth, 1); + EXPECT_EQ(cpu::register_info::EferInfo::Lme::kBitMask, 0x100); + EXPECT_EQ(cpu::register_info::EferInfo::Lme::kAllSetMask, 1); } TEST(x8664EferInfoLmaTest, ValueTest) { - EXPECT_EQ(cpu::reginfo::EferInfo::Lma::kBitOffset, 10); - EXPECT_EQ(cpu::reginfo::EferInfo::Lma::kBitWidth, 1); - EXPECT_EQ(cpu::reginfo::EferInfo::Lma::kBitMask, 0x400); - EXPECT_EQ(cpu::reginfo::EferInfo::Lma::kAllSetMask, 1); + EXPECT_EQ(cpu::register_info::EferInfo::Lma::kBitOffset, 10); + EXPECT_EQ(cpu::register_info::EferInfo::Lma::kBitWidth, 1); + EXPECT_EQ(cpu::register_info::EferInfo::Lma::kBitMask, 0x400); + EXPECT_EQ(cpu::register_info::EferInfo::Lma::kAllSetMask, 1); } TEST(x8664EferInfoNxeTest, ValueTest) { - EXPECT_EQ(cpu::reginfo::EferInfo::Nxe::kBitOffset, 11); - EXPECT_EQ(cpu::reginfo::EferInfo::Nxe::kBitWidth, 1); - EXPECT_EQ(cpu::reginfo::EferInfo::Nxe::kBitMask, 0x800); - EXPECT_EQ(cpu::reginfo::EferInfo::Nxe::kAllSetMask, 1); + EXPECT_EQ(cpu::register_info::EferInfo::Nxe::kBitOffset, 11); + EXPECT_EQ(cpu::register_info::EferInfo::Nxe::kBitWidth, 1); + EXPECT_EQ(cpu::register_info::EferInfo::Nxe::kBitMask, 0x800); + EXPECT_EQ(cpu::register_info::EferInfo::Nxe::kAllSetMask, 1); } TEST(x8664RflagsInfoNxeTest, ValueTest) { - EXPECT_EQ(cpu::reginfo::RflagsInfo::If::kBitOffset, 9); - EXPECT_EQ(cpu::reginfo::RflagsInfo::If::kBitWidth, 1); - EXPECT_EQ(cpu::reginfo::RflagsInfo::If::kBitMask, 0x200); - EXPECT_EQ(cpu::reginfo::RflagsInfo::If::kAllSetMask, 1); + EXPECT_EQ(cpu::register_info::RflagsInfo::If::kBitOffset, 9); + EXPECT_EQ(cpu::register_info::RflagsInfo::If::kBitWidth, 1); + EXPECT_EQ(cpu::register_info::RflagsInfo::If::kBitMask, 0x200); + EXPECT_EQ(cpu::register_info::RflagsInfo::If::kAllSetMask, 1); } TEST(x8664Cr0InfoPeTest, ValueTest) { - EXPECT_EQ(cpu::reginfo::cr::Cr0Info::Pe::kBitOffset, 0); - EXPECT_EQ(cpu::reginfo::cr::Cr0Info::Pe::kBitWidth, 1); - EXPECT_EQ(cpu::reginfo::cr::Cr0Info::Pe::kBitMask, 0x1); - EXPECT_EQ(cpu::reginfo::cr::Cr0Info::Pe::kAllSetMask, 1); + EXPECT_EQ(cpu::register_info::cr::Cr0Info::Pe::kBitOffset, 0); + EXPECT_EQ(cpu::register_info::cr::Cr0Info::Pe::kBitWidth, 1); + EXPECT_EQ(cpu::register_info::cr::Cr0Info::Pe::kBitMask, 0x1); + EXPECT_EQ(cpu::register_info::cr::Cr0Info::Pe::kAllSetMask, 1); } TEST(x8664Cr0InfoPgTest, ValueTest) { - EXPECT_EQ(cpu::reginfo::cr::Cr0Info::Pg::kBitOffset, 31); - EXPECT_EQ(cpu::reginfo::cr::Cr0Info::Pg::kBitWidth, 1); - EXPECT_EQ(cpu::reginfo::cr::Cr0Info::Pg::kBitMask, 0x80000000); - EXPECT_EQ(cpu::reginfo::cr::Cr0Info::Pg::kAllSetMask, 1); + EXPECT_EQ(cpu::register_info::cr::Cr0Info::Pg::kBitOffset, 31); + EXPECT_EQ(cpu::register_info::cr::Cr0Info::Pg::kBitWidth, 1); + EXPECT_EQ(cpu::register_info::cr::Cr0Info::Pg::kBitMask, 0x80000000); + EXPECT_EQ(cpu::register_info::cr::Cr0Info::Pg::kAllSetMask, 1); } TEST(x8664Cr3InfoPwtTest, ValueTest) { - EXPECT_EQ(cpu::reginfo::cr::Cr3Info::Pwt::kBitOffset, 3); - EXPECT_EQ(cpu::reginfo::cr::Cr3Info::Pwt::kBitWidth, 1); - EXPECT_EQ(cpu::reginfo::cr::Cr3Info::Pwt::kBitMask, 0x8); - EXPECT_EQ(cpu::reginfo::cr::Cr3Info::Pwt::kAllSetMask, 1); + EXPECT_EQ(cpu::register_info::cr::Cr3Info::Pwt::kBitOffset, 3); + EXPECT_EQ(cpu::register_info::cr::Cr3Info::Pwt::kBitWidth, 1); + EXPECT_EQ(cpu::register_info::cr::Cr3Info::Pwt::kBitMask, 0x8); + EXPECT_EQ(cpu::register_info::cr::Cr3Info::Pwt::kAllSetMask, 1); } TEST(x8664Cr0InfoPcdTest, ValueTest) { - EXPECT_EQ(cpu::reginfo::cr::Cr3Info::Pcd::kBitOffset, 4); - EXPECT_EQ(cpu::reginfo::cr::Cr3Info::Pcd::kBitWidth, 1); - EXPECT_EQ(cpu::reginfo::cr::Cr3Info::Pcd::kBitMask, 0x10); - EXPECT_EQ(cpu::reginfo::cr::Cr3Info::Pcd::kAllSetMask, 1); + EXPECT_EQ(cpu::register_info::cr::Cr3Info::Pcd::kBitOffset, 4); + EXPECT_EQ(cpu::register_info::cr::Cr3Info::Pcd::kBitWidth, 1); + EXPECT_EQ(cpu::register_info::cr::Cr3Info::Pcd::kBitMask, 0x10); + EXPECT_EQ(cpu::register_info::cr::Cr3Info::Pcd::kAllSetMask, 1); } TEST(x8664Cr3InfoPageDirectoryBaseTest, ValueTest) { - EXPECT_EQ(cpu::reginfo::cr::Cr3Info::PageDirectoryBase::kBitOffset, 12); - EXPECT_EQ(cpu::reginfo::cr::Cr3Info::PageDirectoryBase::kBitWidth, 52); - EXPECT_EQ(cpu::reginfo::cr::Cr3Info::PageDirectoryBase::kBitMask, ~0xFFF); - EXPECT_EQ(cpu::reginfo::cr::Cr3Info::PageDirectoryBase::kAllSetMask, 0xFFFFFFFFFFFFF); + EXPECT_EQ(cpu::register_info::cr::Cr3Info::PageDirectoryBase::kBitOffset, 12); + EXPECT_EQ(cpu::register_info::cr::Cr3Info::PageDirectoryBase::kBitWidth, 52); + EXPECT_EQ(cpu::register_info::cr::Cr3Info::PageDirectoryBase::kBitMask, + ~0xFFF); + EXPECT_EQ(cpu::register_info::cr::Cr3Info::PageDirectoryBase::kAllSetMask, + 0xFFFFFFFFFFFFF); } TEST(x8664Cr4InfoPaeTest, ValueTest) { - EXPECT_EQ(cpu::reginfo::cr::Cr4Info::Pae::kBitOffset, 5); - EXPECT_EQ(cpu::reginfo::cr::Cr4Info::Pae::kBitWidth, 1); - EXPECT_EQ(cpu::reginfo::cr::Cr4Info::Pae::kBitMask, 0x20); - EXPECT_EQ(cpu::reginfo::cr::Cr4Info::Pae::kAllSetMask, 1); + EXPECT_EQ(cpu::register_info::cr::Cr4Info::Pae::kBitOffset, 5); + EXPECT_EQ(cpu::register_info::cr::Cr4Info::Pae::kBitWidth, 1); + EXPECT_EQ(cpu::register_info::cr::Cr4Info::Pae::kBitMask, 0x20); + EXPECT_EQ(cpu::register_info::cr::Cr4Info::Pae::kAllSetMask, 1); }