From 32ff1b81922209059e474268f2288328f2fac743 Mon Sep 17 00:00:00 2001 From: andromeda Date: Wed, 21 Oct 2026 23:03:26 -0400 Subject: initial acpi support --- main.c3 | 189 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 186 insertions(+), 3 deletions(-) (limited to 'main.c3') diff --git a/main.c3 b/main.c3 index 286b4fe..0e0340b 100644 --- a/main.c3 +++ b/main.c3 @@ -16,7 +16,14 @@ module c3os; +import acpi; + import uefi; +import uefi::guid; +import uefi::protocol::mem; + +const MDESCS_LEN = 8192; +macro String version() => "0.1.0"; EfiHandle eh; SystemTable* st; @@ -25,19 +32,195 @@ fn EfiStatus efi_main(EfiHandle image_handle, SystemTable* system_table) @export { eh = image_handle; st = system_table; + BootServices* bs = st.bootServices; + + util::puts("welcome to c3os version "); + util::puts(version()); + util::puts("\r\n"); + util::puts("c3os copyright (c) 2026 andromeda \r\n"); + util::puts("This program comes with ABSOLUTELY NO WARRANTY.\r\n"); + util::puts("This is free software, and you are welcome to redistribute it\r\n"); + util::puts("under certain conditions; see ./LICENSE for details.\r\n"); + + log::info("UEFI vendor: "); + st.conOut._output_string(st.conOut, st.firmwareVendor); + util::puts(" revision "); + util::puti(st.firmwareRevision); + util::puts("\r\n"); + + usz mdescs_len = MDESCS_LEN; + MemoryDescriptor[MDESCS_LEN / MemoryDescriptor::size] mdescs = { }; + usz mdescs_map_key = 0; + usz mdescs_descriptor_size = 0; + uint mdescs_descriptor_version = 0; + bs.get_memory_map(&mdescs_len, &mdescs, &mdescs_map_key, &mdescs_descriptor_size, &mdescs_descriptor_version); + + usz acpi_index; + for (usz i = 0; i < st.numberOfTableEntries; i++) + { + if (guid::@compare(st.configurationTable[i].vendorGuid, guid::ACPI_20_TABLE)) + { + acpi_index = i; + } + } + + if (acpi_index == 0 || !guid::@compare(st.configurationTable[acpi_index].vendorGuid, guid::ACPI_20_TABLE)) + { + log::fatal("acpi table not found"); + spin(); + } + + RootSystemDescriptionPointer* rsdp = st.configurationTable[acpi_index].vendorTable; + + if (!rsdp.is_valid()) + { + log::fatal("checksum verification for root system description pointer failed\r\n"); + spin(); + } + + ExtendedSystemDescriptionTable* xsdt = rsdp.xsdtAddress; + + if (!xsdt.is_valid()) + { + log::fatal("checksum verification for extended system description table failed\r\n"); + spin(); + } + + uint num_entries = (xsdt.length - ExtendedSystemDescriptionTable::size) / ulong::size; + + for (usz i = 0; i < num_entries; i++) + { + DescriptionHeader* dh = (DescriptionHeader*)(uptr)xsdt.descriptionHeaders[i]; - st.conOut.@output_string("Hello World!\n"); + if (dh.is_valid()) + { + log::info("valid signature: "); + util::putbs(&dh.signature, 4); + util::puts("\r\n"); + } + else + { + log::info("invalid signature: "); + util::putbs(&dh.signature, 4); + util::puts("\r\n"); + } + } + + util::puts("done\r\n"); spin(); return SUCCESS; } alias PanicFn = fn void(String message, String file, String function, int line); -PanicFn panicfn = &_panicfn; -fn void _panicfn(String reason, String file = "", String func = "", int line = 0) => spin(); +PanicFn panicfn = &panic; + +fn void panic(String message = "test", String file = "", String function = "", int line = 0) +{ + util::puts("PANIC: "); + util::puts(message); + util::puts("\r\nfunc "); + util::puts(function); + util::puts(" in file "); + util::puts(file); + util::puts(" at line "); + util::puti((usz)line); + util::puts("\r\n"); + spin(); +} fn void spin() { asm("cli"); asm("hlt"); } + +module c3os::log; + +import c3os::util; + +fn void fatal(String s) +{ + util::puts("[fatal]: "); + util::puts(s); +} + +fn void info(String s) +{ + util::puts("[info]: "); + util::puts(s); +} + +fn void warn(String s) +{ + util::puts("[warn]: "); + util::puts(s); +} + +module c3os::util; + +import uefi; + +fn int memcmp(void* b1, void* b2, usz len) @export("memcmp") @nostrip +{ + for (usz i = 0; i < len; i++) + { + if (((char*)b1)[i] < ((char*)b2)[i]) return -1; + if (((char*)b1)[i] > ((char*)b2)[i]) return 1; + } + return 0; +} + +fn void* memcpy(void* dst, void* src, usz len) @export("memcpy") @nostrip +{ + for (usz i = 0; i < len; i++) ((char*)dst)[i] = ((char*)src)[i]; + return dst; +} + +fn void* memset(void* b, int c, usz len) @export("memset") @nostrip +{ + for (usz i = 0; i < len; i++) + { + ((char*)b)[i] = (char)c; + } + return b; +} + +fn void puts(String s) => putbs(s, s.len); + +fn void putbs(char[] s, int n) +{ + ushort[1024] buf = { }; + for (int i = 0;; i++) + { + if (i == n || i == buf.len - 1) + { + buf[i] = '\0'; + break; + } + buf[i] = s[i]; + } + putw((EfiString)&buf); +} + +fn void putw(EfiString w) => c3os::st.conOut._output_string(c3os::st.conOut, w); + +fn void puti(usz i) +{ + usz place = 1; + usz index = 0; + ushort[48] buf = { }; + while (i / place > 0) + { + buf[buf.len - 2 - index] = '0' + (char)((i / place) % 10); + place *= 10; + index += 1; + } + if (i == 0) + { + buf[buf.len - 2] = '0'; + index += 1; + } + buf[buf.len - 1] = '\0'; + putw((EfiString)&buf[buf.len - 1 - index]); +} -- cgit v1.3.1