diff --git a/src/kernel/arch/aarch64/include/cpu.hpp b/src/kernel/arch/aarch64/include/cpu.hpp index d4cbd077..23024142 100644 --- a/src/kernel/arch/aarch64/include/cpu.hpp +++ b/src/kernel/arch/aarch64/include/cpu.hpp @@ -19,8 +19,8 @@ #include -class Cpu { - public: -}; +namespace cpu { +; +}; // namespace cpu #endif // SIMPLEKERNEL_SRC_KERNEL_ARCH_AARCH64_INCLUDE_CPU_HPP_ diff --git a/src/kernel/arch/riscv64/include/cpu.hpp b/src/kernel/arch/riscv64/include/cpu.hpp index 1ec54313..9a438463 100644 --- a/src/kernel/arch/riscv64/include/cpu.hpp +++ b/src/kernel/arch/riscv64/include/cpu.hpp @@ -19,8 +19,8 @@ #include -class Cpu { - public: -}; +namespace cpu { +; +}; // namespace cpu #endif // SIMPLEKERNEL_SRC_KERNEL_ARCH_RISCV64_INCLUDE_CPU_HPP_ diff --git a/src/kernel/arch/x86_64/arch_main.cpp b/src/kernel/arch/x86_64/arch_main.cpp index 19b421a1..2d18286c 100644 --- a/src/kernel/arch/x86_64/arch_main.cpp +++ b/src/kernel/arch/x86_64/arch_main.cpp @@ -21,7 +21,7 @@ // printf_bare_metal 基本输出实现 /// @note 这里要注意,保证在 serial 初始化之前不能使用 printf /// 函数,否则会有全局对象依赖问题 -static auto serial = Cpu::Serial(Cpu::kCom1); +static auto serial = cpu::Serial(cpu::kCom1); extern "C" void _putchar(char character) { serial.Write(character); } static void Fillrect(uint8_t *vram, uint32_t pitch, uint8_t r, uint8_t g, diff --git a/src/kernel/arch/x86_64/include/cpu.hpp b/src/kernel/arch/x86_64/include/cpu.hpp index ae7e05ca..3e27c5df 100644 --- a/src/kernel/arch/x86_64/include/cpu.hpp +++ b/src/kernel/arch/x86_64/include/cpu.hpp @@ -19,155 +19,154 @@ #include -class Cpu { +namespace cpu { +/** + * @brief 读一个字节 + * @param port 要读的端口 + * @return uint8_t 读取到的数据 + */ +static 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 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 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 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 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 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: - /** - * @brief 读一个字节 - * @param port 要读的端口 - * @return uint8_t 读取到的数据 - */ - static inline uint8_t InByte(const uint32_t port) { - uint8_t data; - __asm__ __volatile__("inb %1, %0" : "=a"(data) : "dN"(port)); - return data; - } + 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"); + } - /** - * @brief 读一个字 - * @param port 要读的端口 - * @return uint16_t 读取到的数据 - */ - static inline uint16_t InWord(const uint32_t port) { - uint16_t data; - __asm__ __volatile__("inw %1, %0" : "=a"(data) : "dN"(port)); - return data; + // 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 读一个双字 - * @param port 要读的端口 - * @return uint32_t 读取到的数据 + * @brief 读一个字节 + * @return uint8_t 读取到的数据 */ - static inline uint32_t InLong(const uint32_t port) { - uint32_t data; - __asm__ __volatile__("inl %1, %0" : "=a"(data) : "dN"(port)); - return data; + [[nodiscard]] auto Read() const -> uint8_t { + while (!SerialReceived()) { + ; + } + return InByte(port_); } /** * @brief 写一个字节 - * @param port 要写的端口 - * @param data 要写的数据 + * @param c 要写的数据 */ - static inline void OutByte(const uint32_t port, const uint8_t data) { - __asm__ __volatile__("outb %1, %0" : : "dN"(port), "a"(data)); + void Write(uint8_t c) const { + while (!IsTransmitEmpty()) { + ; + } + OutByte(port_, c); } + private: + uint32_t port_; + /** - * @brief 写一个字 - * @param port 要写的端口 - * @param data 要写的数据 + * @brief 串口是否接收到数据 + * @return true + * @return false */ - static inline void OutWord(const uint32_t port, const uint16_t data) { - __asm__ __volatile__("outw %1, %0" : : "dN"(port), "a"(data)); + [[nodiscard]] auto SerialReceived() const -> bool { + return InByte(port_ + 5) & 1; } /** - * @brief 写一个双字 - * @param port 要写的端口 - * @param data 要写的数据 + * @brief 串口是否可以发送数据 + * @return true + * @return false */ - static inline void OutLong(const uint32_t port, const uint32_t data) { - __asm__ __volatile__("outl %1, %0" : : "dN"(port), "a"(data)); + [[nodiscard]] auto IsTransmitEmpty() const -> bool { + return InByte(port_ + 5) & 0x20; } - - /// @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; - } - }; }; +}; // namespace cpu #endif // SIMPLEKERNEL_SRC_KERNEL_ARCH_X86_64_INCLUDE_CPU_HPP_ diff --git a/test/system_test/gnu_efi_test/main.cpp b/test/system_test/gnu_efi_test/main.cpp index 344d5d2b..d49e3b6e 100644 --- a/test/system_test/gnu_efi_test/main.cpp +++ b/test/system_test/gnu_efi_test/main.cpp @@ -31,7 +31,7 @@ void _start(uint32_t argc, uint8_t *argv) { } extern "C" void _putchar(char character) { - auto serial = Cpu::Serial(Cpu::kCom1); + auto serial = cpu::Serial(cpu::kCom1); serial.Write(character); }