diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2025-12-12 10:28:36 +0100 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2025-12-12 10:28:36 +0100 |
| commit | f8c3c91e81f434c26dd84e5047a4420e8fb40534 (patch) | |
| tree | f1d1bf920146e3792c54e807d0470c7d611e26fd | |
| parent | 67267c4d103de2673191c113c1e99e66965aab5c (diff) | |
| download | teachos-f8c3c91e81f434c26dd84e5047a4420e8fb40534.tar.xz teachos-f8c3c91e81f434c26dd84e5047a4420e8fb40534.zip | |
x86_64/device_io: switch to typed port io.
| -rw-r--r-- | arch/x86_64/include/x86_64/device_io/port_io.hpp | 22 | ||||
| -rw-r--r-- | arch/x86_64/include/x86_64/vga/crtc.hpp | 4 |
2 files changed, 19 insertions, 7 deletions
diff --git a/arch/x86_64/include/x86_64/device_io/port_io.hpp b/arch/x86_64/include/x86_64/device_io/port_io.hpp index ceabf4a..9f115eb 100644 --- a/arch/x86_64/include/x86_64/device_io/port_io.hpp +++ b/arch/x86_64/include/x86_64/device_io/port_io.hpp @@ -2,6 +2,7 @@ #define TEACHOS_X86_64_IO_PORT_IO_HPP #include <array> +#include <concepts> #include <cstddef> #include <cstdint> #include <string_view> @@ -10,6 +11,16 @@ namespace teachos::io::x86_64 { + //! The requirements imposed on a type usable for port I/O. + template<typename ValueType> + concept port_io_type = requires { + requires sizeof(ValueType) == 1 || sizeof(ValueType) == 2 || sizeof(ValueType) == 4; + requires std::default_initializable<ValueType>; + std::bit_cast<ValueType>( + std::conditional_t<sizeof(ValueType) == 1, std::byte, + std::conditional_t<sizeof(ValueType) == 2, std::uint16_t, std::uint32_t>>{}); + }; + //! An I/O port of a given size at a given address. //! //! Port I/O leverages a separate address space to communicate with devices via the memory bus, allowing for byte to @@ -17,13 +28,14 @@ namespace teachos::io::x86_64 //! //! @tparam Address The address (port number) of the I/O port. //! @tparam Size The size (in bytes) of the I/O port. - template<std::uint16_t Address, std::size_t Size> - requires(Size == 1 || Size == 2 || Size == 4) + template<std::uint16_t Address, port_io_type ValueType> struct port { //! The type of data available for reading and writing through this port. - using value_type = - std::conditional_t<Size == 1, std::byte, std::conditional_t<Size == 2, std::uint16_t, std::uint32_t>>; + using value_type = ValueType; + + //! The size of the I/O port + constexpr auto static size = sizeof(value_type); //! Read from the I/O port. //! @@ -54,7 +66,7 @@ namespace teachos::io::x86_64 //! //! This index is used to select the correct assembly templates for the given operation (read or write), as well as //! the clobbered data register, from the relevant template arrays. - constexpr auto static asm_template_index = Size / 2; + constexpr auto static asm_template_index = size / 2; //! The assembly templates used for reading from an I/O port. constexpr auto static read_code = std::array{ diff --git a/arch/x86_64/include/x86_64/vga/crtc.hpp b/arch/x86_64/include/x86_64/vga/crtc.hpp index 8bdc12d..b2c8028 100644 --- a/arch/x86_64/include/x86_64/vga/crtc.hpp +++ b/arch/x86_64/include/x86_64/vga/crtc.hpp @@ -10,12 +10,12 @@ namespace teachos::vga::x86_64::crtc /** * @brief The address port of the CRT Controller. */ - using address = io::x86_64::port<0x3d4, 1>; // NOLINT(cppcoreguidelines-avoid-magic-numbers) + using address = io::x86_64::port<0x3d4, std::byte>; // NOLINT(cppcoreguidelines-avoid-magic-numbers) /** * @brief The data port of the CRT Controller. */ - using data = io::x86_64::port<0x3d5, 1>; // NOLINT(cppcoreguidelines-avoid-magic-numbers) + using data = io::x86_64::port<0x3d5, std::byte>; // NOLINT(cppcoreguidelines-avoid-magic-numbers) namespace registers { |
