From 502413b9ab0e9c07fd516e8ab1ce661675459a5b Mon Sep 17 00:00:00 2001 From: karina Date: Thu, 23 Apr 2026 21:25:15 +0400 Subject: [PATCH] feat(kernel): add PL011 UART console and arch I/O helpers - Add IOSerial: PL011 (0x0900_0000) TX with FIFO-full polling, yield while waiting - Add Arch/IO.h (32-bit MMIO with DSB) and Arch/CPU.h (yield, WFI) - Extend types.h (e.g. ASCII, Address, Int/UInt aliases) - Wire KernelMain to IOSerialPutString for early boot output - Drop .sourcekit-lsp config; note IO glob in CMake (commented) --- .sourcekit-lsp/config.json | 8 -------- Kernel/CMakeLists.txt | 1 + Kernel/Include/Arch/CPU.h | 9 +++++++++ Kernel/Include/Arch/IO.h | 14 ++++++++++++++ Kernel/Include/IO/IOSerial.h | 9 +++++++++ Kernel/Include/types.h | 8 +++++++- Kernel/Source/IO/IOSerial.c | 25 +++++++++++++++++++++++++ Kernel/Source/KernelMain.c | 5 +++-- 8 files changed, 68 insertions(+), 11 deletions(-) delete mode 100644 .sourcekit-lsp/config.json create mode 100644 Kernel/Include/Arch/CPU.h create mode 100644 Kernel/Include/Arch/IO.h create mode 100644 Kernel/Include/IO/IOSerial.h create mode 100644 Kernel/Source/IO/IOSerial.c diff --git a/.sourcekit-lsp/config.json b/.sourcekit-lsp/config.json deleted file mode 100644 index 96d4543..0000000 --- a/.sourcekit-lsp/config.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "defaultWorkspaceType": "compilationDatabase", - "compilationDatabase": { - "searchPaths": [".", "Kernel"] - }, - "backgroundIndexing": true, - "backgroundPreparationMode": "enabled" -} diff --git a/Kernel/CMakeLists.txt b/Kernel/CMakeLists.txt index 6c42a05..91025ab 100644 --- a/Kernel/CMakeLists.txt +++ b/Kernel/CMakeLists.txt @@ -5,6 +5,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) file(GLOB_RECURSE KERNEL_SOURCES CMAKE_CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/Source/KernelMain.c ${CMAKE_CURRENT_SOURCE_DIR}/Source/Arch/entry.S +# ${CMAKE_CURRENT_SOURCE_DIR}/Source/IO/*.c ${CMAKE_CURRENT_SOURCE_DIR}/Source/**/*.c ) diff --git a/Kernel/Include/Arch/CPU.h b/Kernel/Include/Arch/CPU.h new file mode 100644 index 0000000..ce9532a --- /dev/null +++ b/Kernel/Include/Arch/CPU.h @@ -0,0 +1,9 @@ +#pragma once + +static inline void CPUYield() { + __asm__ volatile ("yield" ::: "memory"); +} + +static inline void CPUWaitForInterrupt() { + __asm__ volatile ("wfi" ::: "memory"); +} \ No newline at end of file diff --git a/Kernel/Include/Arch/IO.h b/Kernel/Include/Arch/IO.h new file mode 100644 index 0000000..6b378d1 --- /dev/null +++ b/Kernel/Include/Arch/IO.h @@ -0,0 +1,14 @@ +#pragma once +#include + +static inline void IOAddressWrite32(UInt64 address, UInt32 value) { + __asm__ volatile ("dsb sy" ::: "memory"); // wait till all previous writes are finished physically + *(volatile UInt32*)address = value; + __asm__ volatile ("dsb sy" ::: "memory"); // wait till my write is finished physically +} + +static inline UInt32 IOAddressRead32(UInt64 address) { + UInt32 value = *(volatile UInt32*)address; + __asm__ volatile ("dsb ld" ::: "memory"); // wait till my read is finished physically + return value; +} \ No newline at end of file diff --git a/Kernel/Include/IO/IOSerial.h b/Kernel/Include/IO/IOSerial.h new file mode 100644 index 0000000..f2d7787 --- /dev/null +++ b/Kernel/Include/IO/IOSerial.h @@ -0,0 +1,9 @@ +#pragma once +#include + +enum { + kUARTBaseAddress = 0x09000000, // TODO: make it dynamic by parsing DTB +}; + +Int32 IOSerialPutCharacter(ASCII character); +Int32 IOSerialPutString(const ASCII* string); \ No newline at end of file diff --git a/Kernel/Include/types.h b/Kernel/Include/types.h index 3c0ad3e..442cefc 100644 --- a/Kernel/Include/types.h +++ b/Kernel/Include/types.h @@ -7,12 +7,18 @@ typedef unsigned char UInt8; typedef unsigned short UInt16; typedef unsigned int UInt32; typedef unsigned long long UInt64; +typedef unsigned long long UInt; + +typedef UInt Address; +typedef UInt8* BytePointer; +typedef UInt8* MemoryPointer; typedef signed char Int8; typedef signed short Int16; typedef signed int Int32; typedef signed long long Int64; +typedef int Int; typedef UInt64 Size; - +typedef char ASCII; diff --git a/Kernel/Source/IO/IOSerial.c b/Kernel/Source/IO/IOSerial.c new file mode 100644 index 0000000..e2cf1f2 --- /dev/null +++ b/Kernel/Source/IO/IOSerial.c @@ -0,0 +1,25 @@ +#include +#include +#include + +Int32 IOSerialPutCharacter(ASCII character) { + // TXFF -- TRansmit FIFO Full for PL011 is 5 bit of FR reg (0x18) + UInt64 uartFR = kUARTBaseAddress + 0x18; + + while ((IOAddressRead32(uartFR) & (1 << 5)) != 0) { + CPUYield(); + } + + IOAddressWrite32(kUARTBaseAddress, character); + return character; +} + +Int32 IOSerialPutString(const ASCII* string) { + Int i = 0; + while (string[i] != '\0') { + IOSerialPutCharacter(string[i]); + i++; + } + + return i; +} \ No newline at end of file diff --git a/Kernel/Source/KernelMain.c b/Kernel/Source/KernelMain.c index 22c22be..10592dd 100644 --- a/Kernel/Source/KernelMain.c +++ b/Kernel/Source/KernelMain.c @@ -1,5 +1,6 @@ -#include "types.h" +#include +#include void KernelMain(void) { - volatile UInt64 meow = 0x12345; + IOSerialPutString("Meow nya!!\n"); } \ No newline at end of file