commit 42dfc04af51c29c3853644328b33f070c0f46f0c from: Aleksey Ryndin date: Sat Mar 16 08:50:21 2024 UTC Append uart_a64 (16550) 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 +void writeT(uintptr_t ptr, T value) { - *reinterpret_cast(ptr) = value; + asm volatile ("dmb sy" : : : "memory"); + *reinterpret_cast(ptr) = value; } +constexpr auto write8 = &writeT; +constexpr auto write32 = &writeT; -inline uint32_t read32(uintptr_t ptr) + +template +T readT(uintptr_t ptr) { - return *reinterpret_cast(ptr); + const auto rv = *reinterpret_cast(ptr); + asm volatile ("dmb sy" : : : "memory"); + return rv; } +constexpr auto read8 = &readT; +constexpr auto read32 = &readT; + } // 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); }