Ver código fonte

feat(port): add class port

greatbridf 2 anos atrás
pai
commit
e929d98515
3 arquivos alterados com 83 adições e 0 exclusões
  1. 2 0
      CMakeLists.txt
  2. 66 0
      include/kernel/hw/port.hpp
  3. 15 0
      include/types/cplusplus.hpp

+ 2 - 0
CMakeLists.txt

@@ -28,6 +28,7 @@ project(kernel_main)
 
 set(CMAKE_C_FLAGS "-nostdinc -m32 -nostdlib -W -Wall -Wextra -Wno-builtin-declaration-mismatch -Wno-format -Werror=implicit-int -Werror=implicit-function-declaration -Werror=strict-aliasing -fverbose-asm -fno-exceptions -fno-pic -fno-stack-protector")
 set(CMAKE_CXX_FLAGS "-nostdinc -m32 -nostdlib -W -Wall -Wextra -Wno-builtin-declaration-mismatch -Wno-format -fverbose-asm -fno-use-cxa-atexit -fno-exceptions -fno-pic -fno-stack-protector")
+set(CMAKE_CXX_STANDARD 17)
 
 if (CMAKE_BUILD_TYPE STREQUAL "Debug")
     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -g")
@@ -70,6 +71,7 @@ set(KERNEL_MAIN_SOURCES src/kernel_main.c
                         include/kernel/vfs.h
                         include/kernel/vga.h
                         include/kernel/hw/keyboard.h
+                        include/kernel/hw/port.hpp
                         include/kernel/hw/serial.h
                         include/kernel/hw/timer.h
                         include/kernel/input/keycodes.h

+ 66 - 0
include/kernel/hw/port.hpp

@@ -0,0 +1,66 @@
+#pragma once
+
+#include <types/cplusplus.hpp>
+#include <types/stdint.h>
+
+namespace hw {
+template <typename port_size_t, bool r = true, bool w = true>
+class port {
+private:
+    uint16_t mp;
+
+public:
+    port(uint16_t p)
+        : mp(p)
+    {}
+
+    port_size_t operator*(void) const
+    {
+        static_assert(
+                types::is_same<port_size_t, uint8_t>::value ||
+                types::is_same<port_size_t, uint16_t>::value,
+                "this type is not implemented yet.");
+        port_size_t ret;
+        if constexpr (types::is_same<port_size_t, uint8_t>::value)
+            asm("inb %1, %0"
+                : "=a"(ret)
+                : "d"(mp)
+                );
+        if constexpr (types::is_same<port_size_t, uint16_t>::value)
+            asm("inw %1, %0"
+                : "=a"(ret)
+                : "d"(mp)
+                );
+        return ret;
+    }
+
+    port_size_t operator=(port_size_t n) const
+    {
+        static_assert(
+                types::is_same<port_size_t, uint8_t>::value ||
+                types::is_same<port_size_t, uint16_t>::value,
+                "this type is not implemented yet.");
+        if constexpr (types::is_same<port_size_t, uint8_t>::value)
+            asm("outb %1, %0"
+                : : "d"(mp), "a"(n)
+                );
+        if constexpr (types::is_same<port_size_t, uint16_t>::value)
+            asm("outw %1, %0"
+                : : "d"(mp), "a"(n)
+                );
+        return n;
+    }
+};
+
+using p8 = port<uint8_t>;
+using p8r = port<uint8_t, true, false>;
+using p8w = port<uint8_t, false, true>;
+using p16 = port<uint16_t>;
+using p16r = port<uint16_t, true, false>;
+using p16w = port<uint16_t, false, true>;
+
+template <> uint8_t p8r::operator=(uint8_t n) const = delete;
+template <> uint8_t p8w::operator*(void) const = delete;
+template <> uint16_t p16r::operator=(uint16_t n) const = delete;
+template <> uint16_t p16w::operator*(void) const = delete;
+} // namespace hw

+ 15 - 0
include/types/cplusplus.hpp

@@ -62,6 +62,21 @@ T&& forward(typename traits::remove_reference<T>::type& val)
     return static_cast<T&&>(val);
 }
 
+template <typename T, T _value>
+struct constant_value {
+    static constexpr T value = _value;
+};
+using true_type = constant_value<bool, true>;
+using false_type = constant_value<bool, false>;
+
+template <typename, typename>
+struct is_same : false_type
+{};
+
+template <typename T>
+struct is_same<T, T>: true_type
+{};
+
 } // namespace types
 
 #endif