summaryrefslogtreecommitdiff
path: root/Libraries
diff options
context:
space:
mode:
authorLiav A <liavalb@gmail.com>2020-03-01 15:18:05 +0200
committerAndreas Kling <kling@serenityos.org>2020-03-02 22:23:39 +0100
commit7d39e380f9267756daeb32f9d58219ae028130a5 (patch)
tree951d8cd6a094ae227d9c5acf9bd24172b3eb5825 /Libraries
parent9440c45d6e167544ff5b4199f77c5872424b45a6 (diff)
downloadserenity-7d39e380f9267756daeb32f9d58219ae028130a5.zip
LibBareMetal: Add IOAddress class
Diffstat (limited to 'Libraries')
-rw-r--r--Libraries/LibBareMetal/IO.h64
1 files changed, 64 insertions, 0 deletions
diff --git a/Libraries/LibBareMetal/IO.h b/Libraries/LibBareMetal/IO.h
index 619d4dc2ab..3d97600ca6 100644
--- a/Libraries/LibBareMetal/IO.h
+++ b/Libraries/LibBareMetal/IO.h
@@ -26,6 +26,9 @@
#pragma once
+#include <AK/Assertions.h>
+#include <AK/LogStream.h>
+#include <AK/String.h>
#include <AK/Types.h>
#if defined(KERNEL)
@@ -100,3 +103,64 @@ inline void delay()
}
}
+
+class IOAddress {
+public:
+ IOAddress() {}
+ explicit IOAddress(u16 address)
+ : m_address(address)
+ {
+ }
+
+ IOAddress offset(u16 o) const { return IOAddress(m_address + o); }
+ u16 get() const { return m_address; }
+ void set(u16 address) { m_address = address; }
+ void mask(u16 m) { m_address &= m; }
+
+ template<typename T>
+ [[gnu::always_inline]] inline T in()
+ {
+ if constexpr (sizeof(T) == 4)
+ return IO::in32(get());
+ if constexpr (sizeof(T) == 2)
+ return IO::in16(get());
+ if constexpr (sizeof(T) == 1)
+ return IO::in8(get());
+ ASSERT_NOT_REACHED();
+ }
+
+ template<typename T>
+ [[gnu::always_inline]] inline void out(T value)
+ {
+ if constexpr (sizeof(T) == 4) {
+ IO::out32(get(), value);
+ return;
+ }
+ if constexpr (sizeof(T) == 2) {
+ IO::out16(get(), value);
+ return;
+ }
+ if constexpr (sizeof(T) == 1) {
+ IO::out8(get(), value);
+ return;
+ }
+ ASSERT_NOT_REACHED();
+ }
+
+ bool is_null() const { return m_address == 0; }
+
+ bool operator==(const IOAddress& other) const { return m_address == other.m_address; }
+ bool operator!=(const IOAddress& other) const { return m_address != other.m_address; }
+ bool operator>(const IOAddress& other) const { return m_address > other.m_address; }
+ bool operator>=(const IOAddress& other) const { return m_address >= other.m_address; }
+ bool operator<(const IOAddress& other) const { return m_address < other.m_address; }
+ bool operator<=(const IOAddress& other) const { return m_address <= other.m_address; }
+
+private:
+ u16 m_address { 0 };
+};
+
+inline const LogStream& operator<<(const LogStream& stream, IOAddress value)
+{
+ return stream << "IO " << String::format("%x", value.get());
+}