commit - bb583ea6dc16a176cc9aaf8138e4e7e89886f663
commit + 42dfc04af51c29c3853644328b33f070c0f46f0c
blob - 74dda6587b2316981243632313760bebb227b981
blob + 91a800c4116bfb63124f41b7dd11adce52d48f44
--- include/hw.h
+++ include/hw.h
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
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 {
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
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);
}