Commit Diff


commit - ec901abe19e6762b61d8e24f6fd2cb9908af3b66
commit + 6efd408f5738f59c359283307b8bdb01ce000b8f
blob - 67f1d76e8ad6a249e4f884caf869a7809509da93
blob + 54c864c23b19f0d497af0de3d21153bea3fae281
--- .gitignore
+++ .gitignore
@@ -1,4 +1,4 @@
 **/*.o
 squat.elf
 squat.img
-local.mk
+config.mk
blob - 05bcedef0d4e0cda55a63b8c080e810f9e31aacc
blob + 513b64ee093fc2d7f756aae7ee1d58cdc3def308
--- Makefile
+++ Makefile
@@ -2,12 +2,13 @@ AS		= clang
 CXX		= clang++
 LD		= ld.lld
 OBJCOPY		= llvm-objcopy
--include	local.mk
 
 ARCH		= aarch64
 TARGET		= ${ARCH}-none-elf
-BOARD		= qemu_virt
+BOARD		= virt
 
+-include	config.mk
+
 ASFLAGS		= -target ${TARGET}
 ASFILES		= boot.o
 
@@ -18,7 +19,7 @@ CXXFILES	= kernel.cc uart_${BOARD}.cc
 
 OBJS		= ${ASFILES:.S=.o} ${CXXFILES:.cc=.o}
 
-.PHONY:	clean
+.PHONY:	clean gdbstub
 
 all: squat.img
 
@@ -33,3 +34,7 @@ squat.elf: linker.ld ${OBJS}
 
 clean:
 	rm -rf *.o squat.elf squat.img
+
+gdbstub: squat.img
+	qemu-system-${ARCH} -s -S -M ${BOARD} -cpu cortex-a53 \
+			    -kernel squat.img -nographic -monitor none -serial stdio
blob - /dev/null
blob + e5a8442da87eec7b52d8f5ddee52d77dd2028e32 (mode 644)
--- /dev/null
+++ include/pl011.h
@@ -0,0 +1,73 @@
+// pl011.h
+
+#pragma once
+
+#include <stdint.h>
+
+
+namespace Pl011 {
+
+
+enum Register {
+    DATA_REGISTER       = 0x00,
+    FLAG_REGISTER       = 0x18,
+    CONTROL_REGISTER    = 0x30,
+};
+
+
+struct FlagRegister {
+    union _U {
+        struct _Bits {
+            uint16_t m_ClearToSend      : 1;
+            uint16_t m_DataSetReady     : 1;
+            uint16_t m_DataCarrierDetect: 1;
+            uint16_t m_Busy             : 1;
+            uint16_t m_ReceiveFifoEmpty : 1;
+            uint16_t m_TransmitFifoFull : 1;
+            uint16_t m_ReceiveFifoFull  : 1;
+            uint16_t m_TransmitFifoEmpty: 1;
+            uint16_t m_RingIndicator    : 1;
+            uint16_t m_ReservedZero     : 7;
+        } m_Bits;
+        uint32_t m_nValue;
+    } m_u;
+
+    explicit FlagRegister(uint32_t nValue = 0)
+    {
+        m_u.m_nValue = nValue;
+    }
+};
+static_assert(sizeof(FlagRegister::_U::_Bits) == 2, "should be 2");
+static_assert(sizeof(FlagRegister) == 4, "should be 4");
+
+
+struct ControlRegister {
+    union _U {
+        struct _Bits {
+            uint16_t m_UartEnable       : 1;
+            uint16_t m_SirEnable        : 1;
+            uint16_t m_SirLowIrDaMode   : 1;
+            uint16_t m_ReservedZero     : 4;
+            uint16_t m_LoopbackEnable   : 1;
+            uint16_t m_TransmitEnable   : 1;
+            uint16_t m_ReceiveEnable    : 1;
+            uint16_t m_DataTransmitReady: 1;
+            uint16_t m_RequestToSend    : 1;
+            uint16_t m_Out1             : 1;
+            uint16_t m_Out2             : 1;
+            uint16_t m_RtsEnable        : 1;
+            uint16_t m_CtsEnable        : 1;
+        } m_Bits;
+        uint32_t m_nValue;
+    } m_u;
+
+    ControlRegister()
+    {
+        m_u.m_nValue = 0;
+    }
+};
+static_assert(sizeof(ControlRegister::_U::_Bits) == 2, "should be 2");
+static_assert(sizeof(ControlRegister) == 4, "should be 4");
+
+
+} // namespace Pl011
blob - eeae5fd55c128bd0f5a46cc928e3c0f248d90289
blob + a84a44765226a27452302bf120d891121f7c88be
--- include/uart.h
+++ include/uart.h
@@ -13,7 +13,7 @@ void
 initialize();
 
 void
-send(uint8_t value);
+send(uint8_t nValue);
 
 uint8_t
 recv();
blob - c4144f4f4f27dbfea85a4652e75c9fe9e952c475
blob + 33c10ac2df36f6d33dcfa9eb8fe5bc32918541d8
--- kernel.cc
+++ kernel.cc
@@ -23,10 +23,8 @@ void
 kernel_entry_point()
 {
     Board::Uart::initialize();
+    uart_send_string("Squat entry point\r\n");
 
-
-    uart_send_string("Test ECHO mode\r\n");
-
     for (; ; )
-        Board::Uart::send(Board::Uart::recv());
+        ;
 }
blob - 4bca98c1bdcfe706477e07f9e95f14ffc9468376 (mode 644)
blob + /dev/null
--- uart_qemu_virt.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-// uart_qemu_virt.cc
-
-
-#include <hw.h>
-#include <uart.h>
-
-
-namespace Board {
-namespace Uart {
-
-
-namespace {
-
-// constexpr uintptr_t UART_BASE = 0xffffffffc9000000ULL;
-
-} // anonymous namespace
-
-
-void initialize()
-{
-}
-
-
-void send(uint8_t /*value*/)
-{
-}
-
-
-uint8_t recv()
-{
-    return 0;
-}
-
-
-} // namespace Uart
-} // namespace Board
blob - /dev/null
blob + 78a76dc47a113d54d8f6d7fbbbb62dea9e81744f (mode 644)
--- /dev/null
+++ uart_virt.cc
@@ -0,0 +1,50 @@
+// uart_virt.cc
+// QEMU `virt` generic virtual platform
+
+
+#include <hw.h>
+#include <uart.h>
+#include <pl011.h>
+
+
+namespace Board {
+namespace Uart {
+
+
+namespace {
+
+constexpr uintptr_t UART_BASE = 0xffffffffc9000000ULL;
+
+} // anonymous namespace
+
+
+void initialize()
+{
+    Pl011::ControlRegister ControlRegister;
+    ControlRegister.m_u.m_Bits.m_UartEnable = 1;
+    ControlRegister.m_u.m_Bits.m_TransmitEnable = 1;
+    Hw::write32(UART_BASE + Pl011::CONTROL_REGISTER, ControlRegister.m_u.m_nValue);
+}
+
+
+void send(uint8_t nValue)
+{
+    // spin while fifo is full
+    for (; ; )
+    {
+        Pl011::FlagRegister FlagRegister{Hw::read32(UART_BASE + Pl011::FLAG_REGISTER)};
+        if (!FlagRegister.m_u.m_Bits.m_TransmitFifoFull)
+            break;
+    }
+    Hw::write32(UART_BASE + Pl011::DATA_REGISTER, nValue);
+}
+
+
+uint8_t recv()
+{
+    return 0;
+}
+
+
+} // namespace Uart
+} // namespace Board