commit - 249aeb61f4978f5c05562959185b42a888d6aaa8
commit + bb583ea6dc16a176cc9aaf8138e4e7e89886f663
blob - f4649a5ecc71247a92e21f9608f9735e811e7aff
blob + db0fc1adcb394ccbb24031a5f646426c61ad8d89
--- Makefile
+++ Makefile
.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
+// uart16550.h
+
+#pragma once
+
+#include <stdint.h>
+
+
+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
#include <hw.h>
#include <uart.h>
+#include <uart16550.h>
namespace Board {
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);
}