aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/x86_64/include/x86_64/device_io/port_io.hpp22
-rw-r--r--arch/x86_64/include/x86_64/vga/crtc.hpp4
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
{