Commit Diff


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 <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
@@ -4,6 +4,7 @@
 
 #include <hw.h>
 #include <uart.h>
+#include <uart16550.h>
 
 
 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);
 }