commit bb583ea6dc16a176cc9aaf8138e4e7e89886f663 from: Aleksey Ryndin date: Thu Mar 14 16:34:11 2024 UTC Append uart_a64 commit - 249aeb61f4978f5c05562959185b42a888d6aaa8 commit + bb583ea6dc16a176cc9aaf8138e4e7e89886f663 blob - f4649a5ecc71247a92e21f9608f9735e811e7aff blob + db0fc1adcb394ccbb24031a5f646426c61ad8d89 --- Makefile +++ Makefile @@ -24,7 +24,7 @@ OBJS = ${ASFILES:.S=.o} ${CXXFILES:.cc=.o} .PHONY: all clean qemu gdb-remote tools -all: squat-${BOARD}.img +all: squat-${BOARD}.img tools squat-${BOARD}.img: squat-${BOARD}.elf ${OBJCOPY} squat-${BOARD}.elf -O binary squat-${BOARD}.img blob - /dev/null blob + 32ad595e69a41daacd8a05acde3bbe17ca2607c0 (mode 644) --- /dev/null +++ include/uart16550.h @@ -0,0 +1,41 @@ +// uart16550.h + +#pragma once + +#include + + +namespace Uart16550 { + + +enum Register { + INTERRUPT_ENABLE_REGISTER = 0x04, + LINE_STATUS_REGISTER = 0x14, +}; + + +struct LineStatusRegister { + union _U { + struct _Bits { + uint8_t m_DataReady : 1; + uint8_t m_OverrunError : 1; + uint8_t m_ParityError : 1; + uint8_t m_FramingError : 1; + uint8_t m_BreakInterrupt : 1; + uint8_t m_TxHoldingRegisterEmpty : 1; + uint8_t m_TransmitterEmpty : 1; + uint8_t m_RxDataErrorInFifo : 1; + } m_Bits; + uint32_t m_nValue; + } m_u; + + explicit LineStatusRegister(uint32_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"); + + +} // namespace Uart16550 blob - cf061cf874ec74861f86f7ca16b8792d77eb3546 blob + 49bf0c98cde1f56a532c2436a97d5a3922a3107b --- uart_a64.cc +++ uart_a64.cc @@ -4,6 +4,7 @@ #include #include +#include namespace Board { @@ -14,17 +15,26 @@ namespace { constexpr uintptr_t UART0_BASE = 0x01c28000; +constexpr auto SERIAL_CLOCK = 24000000; constexpr auto BAUDRATE = 115200; +constexpr auto BAUDRATE_DIVISOR = (BAUDRATE * 16); +constexpr auto CLOCK_DIVISOR = (SERIAL_CLOCK + (BAUDRATE_DIVISOR / 2)) / BAUDRATE_DIVISOR; +static_assert(CLOCK_DIVISOR == 13, "Should be 13"); } // anonymous namespace void initialize() { - /* TBD! */ - (void)UART0_BASE; - (void)BAUDRATE; + for (; ; ) + { + const Uart16550::LineStatusRegister LineStatusRegister { + Hw::read32(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); }