Commit Diff


commit - bb583ea6dc16a176cc9aaf8138e4e7e89886f663
commit + 42dfc04af51c29c3853644328b33f070c0f46f0c
blob - 74dda6587b2316981243632313760bebb227b981
blob + 91a800c4116bfb63124f41b7dd11adce52d48f44
--- include/hw.h
+++ include/hw.h
@@ -9,17 +9,28 @@
 namespace Hw {
 
 
-inline void write32(uintptr_t ptr, uint32_t value)
+template <typename T>
+void writeT(uintptr_t ptr, T value)
 {
-    *reinterpret_cast<uint32_t *>(ptr) = value;
+    asm volatile ("dmb sy" : : : "memory");
+    *reinterpret_cast<volatile T *>(ptr) = value;
 }
 
+constexpr auto write8 = &writeT<uint8_t>;
+constexpr auto write32 = &writeT<uint32_t>;
 
-inline uint32_t read32(uintptr_t ptr)
+
+template <typename T>
+T readT(uintptr_t ptr)
 {
-    return *reinterpret_cast<const uint32_t *>(ptr);
+    const auto rv = *reinterpret_cast<volatile const T *>(ptr);
+    asm volatile ("dmb sy" : : : "memory");
+    return rv;
 }
 
+constexpr auto read8 = &readT<uint8_t>;
+constexpr auto read32 = &readT<uint32_t>;
 
+
 }   // namespace Hw
 
blob - 32ad595e69a41daacd8a05acde3bbe17ca2607c0
blob + eafe421c10a35b5ef633100ee47fcee4c7b02880
--- include/uart16550.h
+++ include/uart16550.h
@@ -10,10 +10,53 @@ namespace Uart16550 {
 
 enum Register {
     INTERRUPT_ENABLE_REGISTER   = 0x04,
+    MODEM_CONTROL_REGISTER      = 0x10,
     LINE_STATUS_REGISTER        = 0x14,
 };
 
 
+struct InterruptEnableRegister {
+    union _U {
+        struct _Bits {
+            uint8_t m_EnableReceivedDataAvailableInterrupt          : 1;
+            uint8_t m_EnableTransmitHoldingRegisterEmptyInterrupt   : 1;
+            uint8_t m_EnableReceiverLineStatusInterrupt             : 1;
+            uint8_t m_EnableModemStatusInterrupt                    : 1;
+            uint8_t m_Reserved                                      : 3;
+            uint8_t m_ProgrammableThreInterruptModeEnable           : 1;
+        } m_Bits;
+        uint8_t m_nValue;
+    } m_u;
+
+    explicit InterruptEnableRegister(uint8_t nValue = 0)
+    {
+        m_u.m_nValue = nValue;
+    }
+};
+static_assert(sizeof(InterruptEnableRegister) == 1, "should be byte");
+
+
+struct ModemControlRegister {
+    union _U {
+        struct _Bits {
+            uint8_t m_DataTerminalReady     : 1;
+            uint8_t m_RequestToSend         : 1;
+            uint8_t m_Reserved              : 2;
+            uint8_t m_LoopBackMode          : 1;
+            uint8_t m_AutoFlowControlEnable : 1;
+            uint8_t m_SirModeEnable         : 1;
+        } m_Bits;
+        uint8_t m_nValue;
+    } m_u;
+
+    explicit ModemControlRegister(uint8_t nValue = 0)
+    {
+        m_u.m_nValue = nValue;
+    }
+};
+static_assert(sizeof(ModemControlRegister) == 1, "should be byte");
+
+
 struct LineStatusRegister {
     union _U {
         struct _Bits {
@@ -26,16 +69,15 @@ struct LineStatusRegister {
             uint8_t m_TransmitterEmpty         : 1;
             uint8_t m_RxDataErrorInFifo        : 1;
         } m_Bits;
-        uint32_t m_nValue;
+        uint8_t m_nValue;
     } m_u;
 
-    explicit LineStatusRegister(uint32_t nValue = 0)
+    explicit LineStatusRegister(uint8_t nValue = 0)
     {
         m_u.m_nValue = nValue;
     }
 };
-static_assert(sizeof(LineStatusRegister::_U::_Bits) == 1, "should be 1");
-static_assert(sizeof(LineStatusRegister) == 4, "should be 4");
+static_assert(sizeof(LineStatusRegister) == 1, "should be byte");
 
 
 }   // namespace Uart16550
blob - 49bf0c98cde1f56a532c2436a97d5a3922a3107b
blob + c1fd4791e78f489855b40d6ee017d9fd57b40a3f
--- uart_a64.cc
+++ uart_a64.cc
@@ -30,12 +30,19 @@ void initialize()
     for (; ; )
     {
         const Uart16550::LineStatusRegister LineStatusRegister {
-            Hw::read32(UART0_BASE + Uart16550::LINE_STATUS_REGISTER)
+            Hw::read8(UART0_BASE + Uart16550::LINE_STATUS_REGISTER)
         };
         if (LineStatusRegister.m_u.m_Bits.m_TransmitterEmpty)
             break;
     }
-    // Hw::write32(UART_BASE + Pl011::CONTROL_REGISTER, ControlRegister.m_u.m_nValue);
+
+    const Uart16550::InterruptEnableRegister InterruptEnableRegister{};
+    Hw::write8(UART0_BASE + Uart16550::INTERRUPT_ENABLE_REGISTER, InterruptEnableRegister.m_u.m_nValue);
+
+    Uart16550::ModemControlRegister ModemControlRegister;
+    ModemControlRegister.m_u.m_Bits.m_DataTerminalReady = 1;
+    ModemControlRegister.m_u.m_Bits.m_RequestToSend = 1;
+    Hw::write8(UART0_BASE + Uart16550::MODEM_CONTROL_REGISTER, ModemControlRegister.m_u.m_nValue);
 }