commit - ec901abe19e6762b61d8e24f6fd2cb9908af3b66
commit + 6efd408f5738f59c359283307b8bdb01ce000b8f
blob - 67f1d76e8ad6a249e4f884caf869a7809509da93
blob + 54c864c23b19f0d497af0de3d21153bea3fae281
--- .gitignore
+++ .gitignore
**/*.o
squat.elf
squat.img
-local.mk
+config.mk
blob - 05bcedef0d4e0cda55a63b8c080e810f9e31aacc
blob + 513b64ee093fc2d7f756aae7ee1d58cdc3def308
--- Makefile
+++ Makefile
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
OBJS = ${ASFILES:.S=.o} ${CXXFILES:.cc=.o}
-.PHONY: clean
+.PHONY: clean gdbstub
all: squat.img
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
+// 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
initialize();
void
-send(uint8_t value);
+send(uint8_t nValue);
uint8_t
recv();
blob - c4144f4f4f27dbfea85a4652e75c9fe9e952c475
blob + 33c10ac2df36f6d33dcfa9eb8fe5bc32918541d8
--- kernel.cc
+++ kernel.cc
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
-// 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
+// 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