summaryrefslogtreecommitdiff
path: root/main.c3
diff options
context:
space:
mode:
authorandromeda <andromeda@bsd.my.domain>2026-10-21 23:03:26 -0400
committerandromeda <andromeda@bsd.my.domain>2026-10-21 23:03:26 -0400
commit32ff1b81922209059e474268f2288328f2fac743 (patch)
tree32b5d41e595175429bc8bea26522e9341cb4d3a8 /main.c3
parent4a06a0a7519089caad53f72c8c8c2ebc3592091e (diff)
initial acpi support
Diffstat (limited to 'main.c3')
-rw-r--r--main.c3189
1 files changed, 186 insertions, 3 deletions
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 <andromeda@galaxious.de>\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]);
+}