feat: initial x86_64 port
This commit is contained in:
		
							parent
							
								
									0600245c83
								
							
						
					
					
						commit
						335e24a733
					
				
					 24 changed files with 1343 additions and 55 deletions
				
			
		
							
								
								
									
										12
									
								
								build
									
										
									
									
									
								
							
							
						
						
									
										12
									
								
								build
									
										
									
									
									
								
							|  | @ -1,12 +0,0 @@ | |||
| #!/usr/bin/env -S uv run -s | ||||
| # /// script | ||||
| # requires-python = ">=3.11" | ||||
| # dependencies = [ | ||||
| #   "cutekit @ git+https://github.com/cute-engineering/cutekit.git@stable", | ||||
| # ] | ||||
| # /// | ||||
| 
 | ||||
| import sys | ||||
| import cutekit as ck | ||||
| 
 | ||||
| sys.exit(ck.main()) | ||||
|  | @ -1,5 +1,4 @@ | |||
| from . import ( | ||||
|     headers, | ||||
|     cli, | ||||
|     enforce_c99 | ||||
| ) | ||||
|  |  | |||
|  | @ -1,24 +1,71 @@ | |||
| from cutekit import cli, model, shell, builder | ||||
| from pathlib import Path | ||||
| 
 | ||||
| @cli.command("boot", "Boot the kernel inside of Qemu") | ||||
| def _(args: model.RegistryArgs): | ||||
|     registry = model.Registry.use(args) | ||||
| from cutekit import cli, model, shell | ||||
| 
 | ||||
|     target = registry.lookup('kernel-riscv32', model.Target) | ||||
|     assert target is not None | ||||
| from .image import Image | ||||
| 
 | ||||
|     component = registry.lookup('core', model.Component) | ||||
|     assert component is not None | ||||
| 
 | ||||
|     scope = builder.TargetScope(registry, target) | ||||
|     kernelProduct = builder.build(scope, component)[0] | ||||
| def generateImg(img: Image, target: str) -> Path: | ||||
|     modules = [] | ||||
|     img.mkdir("/efi/boot") | ||||
|     img.mkdir("/bin") | ||||
|     img.cp(img.build("core", f"kernel-{target}"), Path("/kernel.elf")) | ||||
| 
 | ||||
|     shell.exec(*[ | ||||
|         "qemu-system-riscv32", | ||||
|         "-machine", "virt", | ||||
|         "-bios", "default", | ||||
|         "-nographic", | ||||
|         "-serial", "mon:stdio", | ||||
|         "-kernel", str(kernelProduct.path), | ||||
|         "--no-reboot", | ||||
|     ]) | ||||
| 
 | ||||
|     if target == "x86_64": | ||||
|         img.wget( | ||||
|             "https://codeberg.org/Limine/Limine/raw/branch/v10.x-binary/BOOTX64.EFI", | ||||
|             "efi/boot/bootx64.efi", | ||||
|         ) | ||||
|         img.export_limine(Path("/efi/boot"), Path("/kernel.elf"), modules) | ||||
|     return img.path | ||||
| 
 | ||||
| 
 | ||||
| @cli.command("image", "Generate the boot image") | ||||
| def _(): ... | ||||
| 
 | ||||
| 
 | ||||
| class StartArgs(model.RegistryArgs): | ||||
|     debug: bool = cli.arg(None, "debug", "Build the image in debug mode") | ||||
|     arch: str = cli.arg(None, "arch", "The architecture of the image", default="x86_64") | ||||
| 
 | ||||
| 
 | ||||
| @cli.command("image/start", "Run the system inside the emulator") | ||||
| def _(args: StartArgs): | ||||
|     if args.arch not in ["x86_64", "riscv32"]: | ||||
|         raise RuntimeError(f"Unsupported architecture: {args.arch}") | ||||
| 
 | ||||
|     p = generateImg(Image(model.Registry.use(args), f"kernel-{args.arch}"), args.arch) | ||||
| 
 | ||||
|     match args.arch: | ||||
|         case "x86_64": | ||||
|             shell.exec( | ||||
|                 *[ | ||||
|                     "qemu-system-x86_64", | ||||
|                     # "-enable-kvm", | ||||
|                     "-no-reboot", | ||||
|                     "-no-shutdown", | ||||
|                     # "-display", | ||||
|                     # "none", | ||||
|                     "-smp", | ||||
|                     "4", | ||||
|                     "-serial", | ||||
|                     "mon:stdio", | ||||
|                     "-drive", | ||||
|                     f"format=raw,file=fat:rw:{p},media=disk", | ||||
|                     "-bios", | ||||
|                     shell.wget("https://retrage.github.io/edk2-nightly/bin/RELEASEX64_OVMF.fd"), | ||||
|                 ] | ||||
|             ) | ||||
|         case "riscv32": | ||||
|             shell.exec( | ||||
|                 *[ | ||||
|                     "qemu-system-riscv32", | ||||
|                     "-machine", "virt", | ||||
|                     "-bios", "default", | ||||
|                     "-nographic", | ||||
|                     "-serial", "mon:stdio", | ||||
|                     "-kernel", str(p / "kernel.elf"), | ||||
|                     "--no-reboot", | ||||
|                 ] | ||||
|             ) | ||||
|  |  | |||
|  | @ -1,12 +0,0 @@ | |||
| from cutekit.rules import rules | ||||
| 
 | ||||
| rules['cc'].args.append('-pedantic') | ||||
| rules['cc'].args.append('-Wpedantic') | ||||
| rules['cc'].args.append('-Wno-dollar-in-identifier-extension') | ||||
| rules['cc'].args.append('-Wno-gnu-statement-expression-from-macro-expansion') | ||||
| 
 | ||||
| for arg in rules['cc'].args: | ||||
|     if "-std=" in arg: | ||||
|         rules['cc'].args.remove(arg) | ||||
|         rules['cc'].args.append('-std=c99') | ||||
|         break | ||||
							
								
								
									
										55
									
								
								meta/plugins/image.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								meta/plugins/image.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,55 @@ | |||
| import os | ||||
| from hashlib import blake2b | ||||
| from cutekit import model, builder, const, shell | ||||
| from pathlib import Path | ||||
| 
 | ||||
| 
 | ||||
| class Image: | ||||
|     def __init__(self, registry: model.Registry, name: str): | ||||
|         self.__registry: model.Registry = registry | ||||
|         self.__name = name | ||||
| 
 | ||||
|     @property | ||||
|     def path(self) -> Path: | ||||
|         return Path(const.PROJECT_CK_DIR) / "images" / self.__name | ||||
| 
 | ||||
|     def build(self, component_spec: str, target_spec: str) -> Path: | ||||
|         comp = self.__registry.lookup(component_spec, model.Component) | ||||
|         target = self.__registry.lookup(target_spec, model.Target) | ||||
| 
 | ||||
|         assert comp is not None | ||||
|         assert target is not None | ||||
| 
 | ||||
|         scope = builder.TargetScope(self.__registry, target) | ||||
|         return Path(builder.build(scope, comp)[0].path) | ||||
| 
 | ||||
|     def cp(self, src: Path, dst: Path) -> list[Path]: | ||||
|         shell.cp(str(src), str(self.path / str(dst).removeprefix(os.path.sep))) | ||||
|         return [dst] | ||||
| 
 | ||||
|     def mkdir(self, name: str): | ||||
|         (self.path / str(name).removeprefix("/")).mkdir(parents=True, exist_ok=True) | ||||
| 
 | ||||
|     def wget(self, link: str, dst: str): | ||||
|         shell.wget(link, str(self.path / str(dst).removeprefix(os.path.sep))) | ||||
| 
 | ||||
|     def get_hash(self, target: Path) -> str: | ||||
|         with (self.path / str(target).removeprefix(os.path.sep)).open("rb") as f: | ||||
|             return blake2b(f.read()).hexdigest() | ||||
| 
 | ||||
|     def export_limine(self, target: Path, kernel: Path, modules: list[Path]): | ||||
|         rel_path = Path(self.path / str(target).removeprefix(os.path.sep)) | ||||
|         with (rel_path / "limine.conf").open("w") as f: | ||||
|             f.writelines( | ||||
|                 [ | ||||
|                     "randomize_memory: yes\n", | ||||
|                     "timeout: 0\n\n", | ||||
|                     f"/{self.__name}\n", | ||||
|                     "    protocol: limine\n", | ||||
|                     f"    kernel_path: boot():{kernel.as_posix()}#{self.get_hash(kernel)}\n", | ||||
|                 ] | ||||
|                 + [ | ||||
|                     f"    module_path: boot():{module.as_posix()}#{self.get_hash(module)}\n" | ||||
|                     for module in modules | ||||
|                 ] | ||||
|             ) | ||||
|  | @ -30,15 +30,16 @@ | |||
|             ] | ||||
|         }, | ||||
|         "ld": { | ||||
|             "cmd": "{shell.latest('clang')}", | ||||
|             "cmd": "{shell.latest('ld.lld')}", | ||||
|             "args": [ | ||||
|                 "--target=riscv32", | ||||
|                 "-nostdlib", | ||||
|                 "-ffreestanding", | ||||
|                 "-Wl,-Tmeta/targets/kernel-riscv32.ld" | ||||
|                 "-m", | ||||
|                 "elf32lriscv", | ||||
|                 "-T{utils.relpath('kernel-riscv32.ld')}", | ||||
|                 "-z", | ||||
|                 "max-page-size=0x1000" | ||||
|             ], | ||||
|             "files": [ | ||||
|                 "meta/targets/kernel-riscv32.ld" | ||||
|                 "{utils.relpath('kernel-riscv32.ld')}" | ||||
|             ] | ||||
|         }, | ||||
|         "ar": { | ||||
|  |  | |||
							
								
								
									
										78
									
								
								meta/targets/kernel-x86_64.json
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								meta/targets/kernel-x86_64.json
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,78 @@ | |||
| { | ||||
|     "$schema": "https://schemas.cute.engineering/stable/cutekit.manifest.target.v1", | ||||
|     "id": "kernel-x86_64", | ||||
|     "type": "target", | ||||
|     "props": { | ||||
|         "toolchain": "clang", | ||||
|         "arch": "x86_64", | ||||
|         "sys": "kernel", | ||||
|         "abi": "sysv", | ||||
|         "bits": "64", | ||||
|         "freestanding": true, | ||||
|         "host": false, | ||||
|         "sys-encoding": "utf8", | ||||
|         "sys-line-ending": "lf", | ||||
|         "sys-path-separator": "slash", | ||||
|         "sys-terminal": "ansi" | ||||
|     }, | ||||
|     "tools": { | ||||
|         "cc": { | ||||
|             "cmd": "{shell.latest('clang')}", | ||||
|             "args": [ | ||||
|                 "--target=x86_64-none-elf", | ||||
|                 "-ffreestanding", | ||||
|                 "-fno-stack-protector", | ||||
|                 "-mno-80387", | ||||
|                 "-mno-mmx", | ||||
|                 "-mno-3dnow", | ||||
|                 "-mno-sse", | ||||
|                 "-mno-sse2", | ||||
|                 "-mno-red-zone", | ||||
|                 "-mcmodel=kernel" | ||||
|             ] | ||||
|         }, | ||||
|         "cxx": { | ||||
|             "cmd": "{shell.latest('clang++')}", | ||||
|             "args": [ | ||||
|                 "--target=x86_64-none-elf", | ||||
|                 "-ffreestanding", | ||||
|                 "-fno-stack-protector", | ||||
|                 "-mno-80387", | ||||
|                 "-mno-mmx", | ||||
|                 "-mno-3dnow", | ||||
|                 "-mno-sse", | ||||
|                 "-mno-sse2", | ||||
|                 "-mno-red-zone", | ||||
|                 "-mcmodel=kernel", | ||||
|                 "-fno-exceptions", | ||||
|                 "-fno-rtti" | ||||
|             ] | ||||
|         }, | ||||
|         "ld": { | ||||
|             "cmd": "{shell.latest('ld.lld')}", | ||||
|             "args": [ | ||||
|                 "-m", | ||||
|                 "elf_x86_64", | ||||
|                 "-T{utils.relpath('kernel-x86_64.ld')}", | ||||
|                 "-z", | ||||
|                 "max-page-size=0x1000" | ||||
|             ], | ||||
|             "files": [ | ||||
|                 "{utils.relpath('kernel-x86_64.ld')}" | ||||
|             ] | ||||
|         }, | ||||
|         "ar": { | ||||
|             "cmd": "{shell.latest('llvm-ar')}", | ||||
|             "args": [ | ||||
|                 "rcs" | ||||
|             ] | ||||
|         }, | ||||
|         "as": { | ||||
|             "cmd": "nasm", | ||||
|             "args": [ | ||||
|                 "-f", | ||||
|                 "elf64" | ||||
|             ] | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										75
									
								
								meta/targets/kernel-x86_64.ld
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								meta/targets/kernel-x86_64.ld
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,75 @@ | |||
| /* Tell the linker that we want an x86_64 ELF64 output file */ | ||||
| OUTPUT_FORMAT(elf64-x86-64) | ||||
| 
 | ||||
| /* We want the symbol kmain to be our entry point */ | ||||
| ENTRY(x86_64_start) | ||||
| 
 | ||||
| /* Define the program headers we want so the bootloader gives us the right */ | ||||
| /* MMU permissions; this also allows us to exert more control over the linking */ | ||||
| /* process. */ | ||||
| PHDRS | ||||
| { | ||||
|     limine_requests PT_LOAD; | ||||
|     text PT_LOAD; | ||||
|     rodata PT_LOAD; | ||||
|     data PT_LOAD; | ||||
| } | ||||
| 
 | ||||
| SECTIONS | ||||
| { | ||||
|     /* We want to be placed in the topmost 2GiB of the address space, for optimisations */ | ||||
|     /* and because that is what the Limine spec mandates. */ | ||||
|     /* Any address in this region will do, but often 0xffffffff80000000 is chosen as */ | ||||
|     /* that is the beginning of the region. */ | ||||
|     . = 0xffffffff80000000; | ||||
| 
 | ||||
|     /* Define a section to contain the Limine requests and assign it to its own PHDR */ | ||||
|     .limine_requests : { | ||||
|         KEEP(*(.limine_requests_start)) | ||||
|         KEEP(*(.limine_requests)) | ||||
|         KEEP(*(.limine_requests_end)) | ||||
|     } :limine_requests | ||||
| 
 | ||||
|     /* Move to the next memory page for .text */ | ||||
|     . = ALIGN(CONSTANT(MAXPAGESIZE)); | ||||
| 
 | ||||
|     .text : { | ||||
|         *(.text .text.*) | ||||
|     } :text | ||||
| 
 | ||||
|     /* Move to the next memory page for .rodata */ | ||||
|     . = ALIGN(CONSTANT(MAXPAGESIZE)); | ||||
| 
 | ||||
|     .rodata : { | ||||
|         *(.rodata .rodata.*) | ||||
|     } :rodata | ||||
| 
 | ||||
|     /* Add a .note.gnu.build-id output section in case a build ID flag is added to the */ | ||||
|     /* linker command. */ | ||||
|     .note.gnu.build-id : { | ||||
|         *(.note.gnu.build-id) | ||||
|     } :rodata | ||||
| 
 | ||||
|     /* Move to the next memory page for .data */ | ||||
|     . = ALIGN(CONSTANT(MAXPAGESIZE)); | ||||
| 
 | ||||
|     .data : { | ||||
|         *(.data .data.*) | ||||
|     } :data | ||||
| 
 | ||||
|     /* NOTE: .bss needs to be the last thing mapped to :data, otherwise lots of */ | ||||
|     /* unnecessary zeros will be written to the binary. */ | ||||
|     /* If you need, for example, .init_array and .fini_array, those should be placed */ | ||||
|     /* above this. */ | ||||
|     .bss : { | ||||
|         *(.bss .bss.*) | ||||
|         *(COMMON) | ||||
|     } :data | ||||
| 
 | ||||
|     /* Discard .note.* and .eh_frame* since they may cause issues on some hosts. */ | ||||
|     /DISCARD/ : { | ||||
|         *(.eh_frame*) | ||||
|         *(.note .note.*) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -12,7 +12,7 @@ | |||
| #include "paging.h" | ||||
| 
 | ||||
| extern char __bss[], __bss_end[]; | ||||
| extern void kmain(void); | ||||
| void kmain(void); | ||||
| 
 | ||||
| static uint8_t early_heap[kib$(32)]; | ||||
| static DTBNode* dtb_root = NULL; | ||||
|  |  | |||
							
								
								
									
										18
									
								
								src/kernel/hal/x86_64/boot.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/kernel/hal/x86_64/boot.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,18 @@ | |||
| #include <dtb> | ||||
| #include <limine> | ||||
| #include <logger> | ||||
| 
 | ||||
| __attribute__((used, section(".limine_requests"))) static volatile LIMINE_BASE_REVISION(3); | ||||
| __attribute__((used, section(".limine_requests_start"))) static volatile LIMINE_REQUESTS_START_MARKER; | ||||
| __attribute__((used, section(".limine_requests_end"))) static volatile LIMINE_REQUESTS_END_MARKER; | ||||
| 
 | ||||
| void kmain(void); | ||||
| 
 | ||||
| void x86_64_start(void) { | ||||
|     info$("Hello, x86_64 !"); | ||||
|     // kmain();
 | ||||
| } | ||||
| 
 | ||||
| DTBNode* hal_dtb_root(void) { | ||||
|     return NULL; | ||||
| } | ||||
							
								
								
									
										44
									
								
								src/kernel/hal/x86_64/hal.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/kernel/hal/x86_64/hal.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,44 @@ | |||
| #include <hal> | ||||
| #include <limine> | ||||
| #include <logger> | ||||
| 
 | ||||
| #include "serial.h" | ||||
| 
 | ||||
| __attribute__((used, section(".limine_requests"))) static volatile struct limine_hhdm_request hhdm_req = { | ||||
|     .id       = LIMINE_HHDM_REQUEST, | ||||
|     .revision = 0, | ||||
| }; | ||||
| 
 | ||||
| void hal_putc(int ch) { | ||||
|     static bool is_serial_init = false; | ||||
|     if (!is_serial_init) [[clang::unlikely]] { | ||||
|         serial_init(COM1, SERIAL_BAUD_RATE); | ||||
|         is_serial_init = true; | ||||
|     } | ||||
| 
 | ||||
|     serial_putc(COM1, ch); | ||||
| } | ||||
| 
 | ||||
| size_t page_size(void) { | ||||
|     return 4096; | ||||
| } | ||||
| 
 | ||||
| void hal_brkpoint(void) { | ||||
|     __asm__ volatile("int $3"); | ||||
| } | ||||
| 
 | ||||
| void* hal_mmap_l2h(uintptr_t addr) { | ||||
|     if (hhdm_req.response == NULL) [[clang::unlikely]] { | ||||
|         panic$("Couldn't get limine's HHDM"); | ||||
|     } | ||||
| 
 | ||||
|     return (void*)(addr + hhdm_req.response->offset); | ||||
| } | ||||
| 
 | ||||
| void* hal_mmap_h2l(uintptr_t addr) { | ||||
|     if (hhdm_req.response == NULL) [[clang::unlikely]] { | ||||
|         panic$("Couldn't get limine's HHDM"); | ||||
|     } | ||||
| 
 | ||||
|     return (void*)(addr - hhdm_req.response->offset); | ||||
| } | ||||
							
								
								
									
										17
									
								
								src/kernel/hal/x86_64/ioport.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/kernel/hal/x86_64/ioport.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,17 @@ | |||
| #include "ioport.h" | ||||
| 
 | ||||
| uint8_t in8(uint16_t port) { | ||||
|     uint8_t ret; | ||||
|     __asm__ volatile("inb %w1, %b0" | ||||
|                      : "=a"(ret) | ||||
|                      : "Nd"(port) | ||||
|                      : "memory"); | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| void out8(uint16_t port, uint8_t val) { | ||||
|     __asm__ volatile("outb %b0, %w1" : | ||||
|                      : "a"(val), | ||||
|                        "Nd"(port) | ||||
|                      : "memory"); | ||||
| } | ||||
							
								
								
									
										6
									
								
								src/kernel/hal/x86_64/ioport.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								src/kernel/hal/x86_64/ioport.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,6 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <stdint.h> | ||||
| 
 | ||||
| uint8_t in8(uint16_t port); | ||||
| void out8(uint16_t port, uint8_t val); | ||||
							
								
								
									
										11
									
								
								src/kernel/hal/x86_64/manifest.json
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/kernel/hal/x86_64/manifest.json
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,11 @@ | |||
| { | ||||
|     "$schema": "https://schemas.cute.engineering/stable/cutekit.manifest.component.v1", | ||||
|     "type": "lib", | ||||
|     "id": "hal-x86_64", | ||||
|     "enableIf": { | ||||
|         "arch": ["x86_64"], | ||||
|         "sys": ["kernel"] | ||||
|     }, | ||||
|     "provides": ["hal-impl"], | ||||
|     "requires": ["pmm", "kmalloc", "handover", "handover-limine"] | ||||
| } | ||||
							
								
								
									
										39
									
								
								src/kernel/hal/x86_64/serial.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								src/kernel/hal/x86_64/serial.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,39 @@ | |||
| #include "serial.h" | ||||
| 
 | ||||
| #include "ioport.h" | ||||
| 
 | ||||
| static void write_register(uint16_t port, uint16_t offset, uint8_t value) { | ||||
|     out8(port + offset, value); | ||||
| } | ||||
| 
 | ||||
| static uint8_t read_register(uint16_t port, uint16_t offset) { | ||||
|     return in8(port + offset); | ||||
| } | ||||
| 
 | ||||
| void _serial_init(enum comPortNo port, uint32_t rate) { | ||||
|     if (SERIAL_BAUD_RATE % rate > 0) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     uint16_t div = SERIAL_BAUD_RATE / rate; | ||||
| 
 | ||||
|     write_register(port, SERIAL_INTERRUPT_REG, SERIAL_DISABLE_INTERRUPT); | ||||
|     write_register(port, SERIAL_LINE_CTRL_REG, SERIAL_LINE_CTRL_DLAB); | ||||
| 
 | ||||
|     write_register(port, SERIAL_BAUD_LSB, div & 0xff); | ||||
|     write_register(port, SERIAL_BAUD_MSB, div >> 8); | ||||
| 
 | ||||
|     write_register(port, SERIAL_LINE_CTRL_REG, SERIAL_LINE_CTRL_DATA8); | ||||
|     write_register(port, SERIAL_FIFO_CTRL_REG, SERIAL_FIFO_CTRL_FIFO | SERIAL_FIFO_CTRL_CLEAR_RX | SERIAL_FIFO_CTRL_CLEAR_TX | SERIAL_FIFO_CTRL_INT14); | ||||
|     write_register(port, SERIAL_MODEM_REG, SERIAL_MODEM_DTR | SERIAL_MODEM_RTS | SERIAL_MODEM_IRQ | SERIAL_MODEM_OUT2); | ||||
| } | ||||
| 
 | ||||
| static void serial_wait_ready(enum comPortNo port) { | ||||
|     while ((read_register(port, SERIAL_LINE_STATUS_REG) & SERIAL_LINE_TRANSMITTER_EMPTY) == 0) | ||||
|         ; | ||||
| } | ||||
| 
 | ||||
| void serial_putc(enum comPortNo port, char c) { | ||||
|     serial_wait_ready(port); | ||||
|     write_register(port, SERIAL_TRANSMIT_BUFFER, c); | ||||
| } | ||||
							
								
								
									
										64
									
								
								src/kernel/hal/x86_64/serial.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								src/kernel/hal/x86_64/serial.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,64 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <stdint.h> | ||||
| 
 | ||||
| #define SERIAL_INTERRUPT_REG     (1) | ||||
| #define SERIAL_ENABLE_INTERRUPT  (1) | ||||
| #define SERIAL_DISABLE_INTERRUPT (0) | ||||
| 
 | ||||
| #define SERIAL_TRANSMIT_BUFFER (0) | ||||
| 
 | ||||
| #define SERIAL_FIFO_CTRL_REG      (2) | ||||
| #define SERIAL_FIFO_CTRL_FIFO     (1 << 0) | ||||
| #define SERIAL_FIFO_CTRL_CLEAR_RX (1 << 1) | ||||
| #define SERIAL_FIFO_CTRL_CLEAR_TX (1 << 2) | ||||
| #define SERIAL_FIFO_CTRL_DMA      (1 << 3) | ||||
| #define SERIAL_FIFO_CTRL_INT1     (0b00) | ||||
| #define SERIAL_FIFO_CTRL_INT4     (0b01 << 6) | ||||
| #define SERIAL_FIFO_CTRL_INT8     (0b10 << 6) | ||||
| #define SERIAL_FIFO_CTRL_INT14    (0b11 << 6) | ||||
| 
 | ||||
| #define SERIAL_LINE_CTRL_REG    (3) | ||||
| #define SERIAL_LINE_CTRL_DATA5  (0b00) | ||||
| #define SERIAL_LINE_CTRL_DATA6  (0b01) | ||||
| #define SERIAL_LINE_CTRL_DATA7  (0b10) | ||||
| #define SERIAL_LINE_CTRL_DATA8  (0b11) | ||||
| #define SERIAL_LINE_CTRL_STOP   (1 << 2) | ||||
| #define SERIAL_LINE_CTRL_PARITY (0b111 << 3) | ||||
| #define SERIAL_LINE_CTRL_BRK    (1 << 6) | ||||
| #define SERIAL_LINE_CTRL_DLAB   (1 << 7) | ||||
| 
 | ||||
| #define SERIAL_MODEM_REG  (4) | ||||
| #define SERIAL_MODEM_DTR  (1 << 0) | ||||
| #define SERIAL_MODEM_RTS  (1 << 1) | ||||
| #define SERIAL_MODEM_OUT2 (1 << 2) | ||||
| #define SERIAL_MODEM_IRQ  (1 << 3) | ||||
| #define SERIAL_MODEM_LOOP (1 << 4) | ||||
| 
 | ||||
| #define SERIAL_LINE_STATUS_REG        (5) | ||||
| #define SERIAL_LINE_DATA_READY        (1 << 0) | ||||
| #define SERIAL_LINE_TRANSMITTER_EMPTY (1 << 5) | ||||
| 
 | ||||
| // IF DLAB = 1
 | ||||
| #define SERIAL_BAUD_LSB  (0) | ||||
| #define SERIAL_BAUD_MSB  (1) | ||||
| #define SERIAL_BAUD_RATE (115200) | ||||
| 
 | ||||
| enum comPortNo { | ||||
|     COM1 = 0x3f8, | ||||
|     COM2 = 0x2f8, | ||||
|     COM3 = 0x3e8, | ||||
|     COM4 = 0x2e8, | ||||
|     COM5 = 0x5f8, | ||||
|     COM6 = 0x4f8, | ||||
|     COM7 = 0x5e8, | ||||
|     COM8 = 0x4e8, | ||||
| }; | ||||
| 
 | ||||
| #define serial_init(PORT, RATE)                                        \ | ||||
|     _Static_assert(SERIAL_BAUD_RATE % RATE == 0, "Invalid baud rate"); \ | ||||
|     _serial_init(PORT, RATE); | ||||
| 
 | ||||
| void _serial_init(enum comPortNo port, uint32_t rate); | ||||
| 
 | ||||
| void serial_putc(enum comPortNo port, char c); | ||||
|  | @ -1 +0,0 @@ | |||
| #pragma once | ||||
							
								
								
									
										5
									
								
								src/kernel/libs/limine/manifest.json
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/kernel/libs/limine/manifest.json
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,5 @@ | |||
| { | ||||
|     "$schema": "https://schemas.cute.engineering/stable/cutekit.manifest.component.v1", | ||||
|     "type": "lib", | ||||
|     "id": "limine" | ||||
| } | ||||
							
								
								
									
										833
									
								
								src/kernel/libs/limine/mod.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										833
									
								
								src/kernel/libs/limine/mod.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,833 @@ | |||
| /* BSD Zero Clause License */ | ||||
| 
 | ||||
| /* Copyright (C) 2022-2025 Mintsuki and contributors.
 | ||||
|  * | ||||
|  * Permission to use, copy, modify, and/or distribute this software for any | ||||
|  * purpose with or without fee is hereby granted. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||||
|  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||||
|  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | ||||
|  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||||
|  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | ||||
|  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | ||||
|  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef LIMINE_H | ||||
| #    define LIMINE_H 1 | ||||
| 
 | ||||
| #    ifdef __cplusplus | ||||
| extern "C" { | ||||
| #    endif | ||||
| 
 | ||||
| #    include <stdint.h> | ||||
| 
 | ||||
| /* Misc */ | ||||
| 
 | ||||
| #    ifdef LIMINE_NO_POINTERS | ||||
| #        define LIMINE_PTR(TYPE) uint64_t | ||||
| #    else | ||||
| #        define LIMINE_PTR(TYPE) TYPE | ||||
| #    endif | ||||
| 
 | ||||
| #    ifndef LIMINE_API_REVISION | ||||
| #        define LIMINE_API_REVISION 0 | ||||
| #    endif | ||||
| 
 | ||||
| #    if LIMINE_API_REVISION > 3 | ||||
| #        error "limine.h API revision unsupported" | ||||
| #    endif | ||||
| 
 | ||||
| #    ifdef __GNUC__ | ||||
| #        define LIMINE_DEPRECATED __attribute__((__deprecated__)) | ||||
| #        define LIMINE_DEPRECATED_IGNORE_START \ | ||||
|             _Pragma("GCC diagnostic push")     \ | ||||
|                 _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") | ||||
| #        define LIMINE_DEPRECATED_IGNORE_END \ | ||||
|             _Pragma("GCC diagnostic pop") | ||||
| #    else | ||||
| #        define LIMINE_DEPRECATED | ||||
| #        define LIMINE_DEPRECATED_IGNORE_START | ||||
| #        define LIMINE_DEPRECATED_IGNORE_END | ||||
| #    endif | ||||
| 
 | ||||
| #    define LIMINE_REQUESTS_START_MARKER \ | ||||
|         uint64_t limine_requests_start_marker[4] = {0xf6b8f4b39de7d1ae, 0xfab91a6940fcb9cf, 0x785c6ed015d3e316, 0x181e920a7852b9d9}; | ||||
| #    define LIMINE_REQUESTS_END_MARKER \ | ||||
|         uint64_t limine_requests_end_marker[2] = {0xadc0e0531bb10d03, 0x9572709f31764c62}; | ||||
| 
 | ||||
| #    define LIMINE_REQUESTS_DELIMITER LIMINE_REQUESTS_END_MARKER | ||||
| 
 | ||||
| #    define LIMINE_BASE_REVISION(N) \ | ||||
|         uint64_t limine_base_revision[3] = {0xf9562b2d5c95a6c8, 0x6a7b384944536bdc, (N)}; | ||||
| 
 | ||||
| #    define LIMINE_BASE_REVISION_SUPPORTED (limine_base_revision[2] == 0) | ||||
| 
 | ||||
| #    define LIMINE_LOADED_BASE_REV_VALID (limine_base_revision[1] != 0x6a7b384944536bdc) | ||||
| #    define LIMINE_LOADED_BASE_REVISION  (limine_base_revision[1]) | ||||
| 
 | ||||
| #    define LIMINE_COMMON_MAGIC 0xc7b1dd30df4c8b88, 0x0a82e883a194f07b | ||||
| 
 | ||||
| struct limine_uuid { | ||||
|     uint32_t a; | ||||
|     uint16_t b; | ||||
|     uint16_t c; | ||||
|     uint8_t d[8]; | ||||
| }; | ||||
| 
 | ||||
| #    define LIMINE_MEDIA_TYPE_GENERIC 0 | ||||
| #    define LIMINE_MEDIA_TYPE_OPTICAL 1 | ||||
| #    define LIMINE_MEDIA_TYPE_TFTP    2 | ||||
| 
 | ||||
| struct limine_file { | ||||
|     uint64_t revision; | ||||
|     LIMINE_PTR(void*) | ||||
|     address; | ||||
|     uint64_t size; | ||||
|     LIMINE_PTR(char*) | ||||
|     path; | ||||
| #    if LIMINE_API_REVISION >= 3 | ||||
|     LIMINE_PTR(char*) | ||||
|     string; | ||||
| #    else | ||||
|     LIMINE_PTR(char*) | ||||
|     cmdline; | ||||
| #    endif | ||||
|     uint32_t media_type; | ||||
|     uint32_t unused; | ||||
|     uint32_t tftp_ip; | ||||
|     uint32_t tftp_port; | ||||
|     uint32_t partition_index; | ||||
|     uint32_t mbr_disk_id; | ||||
|     struct limine_uuid gpt_disk_uuid; | ||||
|     struct limine_uuid gpt_part_uuid; | ||||
|     struct limine_uuid part_uuid; | ||||
| }; | ||||
| 
 | ||||
| /* Boot info */ | ||||
| 
 | ||||
| #    define LIMINE_BOOTLOADER_INFO_REQUEST {LIMINE_COMMON_MAGIC, 0xf55038d8e2a1202f, 0x279426fcf5f59740} | ||||
| 
 | ||||
| struct limine_bootloader_info_response { | ||||
|     uint64_t revision; | ||||
|     LIMINE_PTR(char*) | ||||
|     name; | ||||
|     LIMINE_PTR(char*) | ||||
|     version; | ||||
| }; | ||||
| 
 | ||||
| struct limine_bootloader_info_request { | ||||
|     uint64_t id[4]; | ||||
|     uint64_t revision; | ||||
|     LIMINE_PTR(struct limine_bootloader_info_response*) | ||||
|     response; | ||||
| }; | ||||
| 
 | ||||
| /* Executable command line */ | ||||
| 
 | ||||
| #    define LIMINE_EXECUTABLE_CMDLINE_REQUEST {LIMINE_COMMON_MAGIC, 0x4b161536e598651e, 0xb390ad4a2f1f303a} | ||||
| 
 | ||||
| struct limine_executable_cmdline_response { | ||||
|     uint64_t revision; | ||||
|     LIMINE_PTR(char*) | ||||
|     cmdline; | ||||
| }; | ||||
| 
 | ||||
| struct limine_executable_cmdline_request { | ||||
|     uint64_t id[4]; | ||||
|     uint64_t revision; | ||||
|     LIMINE_PTR(struct limine_executable_cmdline_response*) | ||||
|     response; | ||||
| }; | ||||
| 
 | ||||
| /* Firmware type */ | ||||
| 
 | ||||
| #    define LIMINE_FIRMWARE_TYPE_REQUEST {LIMINE_COMMON_MAGIC, 0x8c2f75d90bef28a8, 0x7045a4688eac00c3} | ||||
| 
 | ||||
| #    define LIMINE_FIRMWARE_TYPE_X86BIOS 0 | ||||
| #    define LIMINE_FIRMWARE_TYPE_UEFI32  1 | ||||
| #    define LIMINE_FIRMWARE_TYPE_UEFI64  2 | ||||
| #    define LIMINE_FIRMWARE_TYPE_SBI     3 | ||||
| 
 | ||||
| struct limine_firmware_type_response { | ||||
|     uint64_t revision; | ||||
|     uint64_t firmware_type; | ||||
| }; | ||||
| 
 | ||||
| struct limine_firmware_type_request { | ||||
|     uint64_t id[4]; | ||||
|     uint64_t revision; | ||||
|     LIMINE_PTR(struct limine_firmware_type_response*) | ||||
|     response; | ||||
| }; | ||||
| 
 | ||||
| /* Stack size */ | ||||
| 
 | ||||
| #    define LIMINE_STACK_SIZE_REQUEST {LIMINE_COMMON_MAGIC, 0x224ef0460a8e8926, 0xe1cb0fc25f46ea3d} | ||||
| 
 | ||||
| struct limine_stack_size_response { | ||||
|     uint64_t revision; | ||||
| }; | ||||
| 
 | ||||
| struct limine_stack_size_request { | ||||
|     uint64_t id[4]; | ||||
|     uint64_t revision; | ||||
|     LIMINE_PTR(struct limine_stack_size_response*) | ||||
|     response; | ||||
|     uint64_t stack_size; | ||||
| }; | ||||
| 
 | ||||
| /* HHDM */ | ||||
| 
 | ||||
| #    define LIMINE_HHDM_REQUEST {LIMINE_COMMON_MAGIC, 0x48dcf1cb8ad2b852, 0x63984e959a98244b} | ||||
| 
 | ||||
| struct limine_hhdm_response { | ||||
|     uint64_t revision; | ||||
|     uint64_t offset; | ||||
| }; | ||||
| 
 | ||||
| struct limine_hhdm_request { | ||||
|     uint64_t id[4]; | ||||
|     uint64_t revision; | ||||
|     LIMINE_PTR(struct limine_hhdm_response*) | ||||
|     response; | ||||
| }; | ||||
| 
 | ||||
| /* Framebuffer */ | ||||
| 
 | ||||
| #    define LIMINE_FRAMEBUFFER_REQUEST {LIMINE_COMMON_MAGIC, 0x9d5827dcd881dd75, 0xa3148604f6fab11b} | ||||
| 
 | ||||
| #    define LIMINE_FRAMEBUFFER_RGB 1 | ||||
| 
 | ||||
| struct limine_video_mode { | ||||
|     uint64_t pitch; | ||||
|     uint64_t width; | ||||
|     uint64_t height; | ||||
|     uint16_t bpp; | ||||
|     uint8_t memory_model; | ||||
|     uint8_t red_mask_size; | ||||
|     uint8_t red_mask_shift; | ||||
|     uint8_t green_mask_size; | ||||
|     uint8_t green_mask_shift; | ||||
|     uint8_t blue_mask_size; | ||||
|     uint8_t blue_mask_shift; | ||||
| }; | ||||
| 
 | ||||
| struct limine_framebuffer { | ||||
|     LIMINE_PTR(void*) | ||||
|     address; | ||||
|     uint64_t width; | ||||
|     uint64_t height; | ||||
|     uint64_t pitch; | ||||
|     uint16_t bpp; | ||||
|     uint8_t memory_model; | ||||
|     uint8_t red_mask_size; | ||||
|     uint8_t red_mask_shift; | ||||
|     uint8_t green_mask_size; | ||||
|     uint8_t green_mask_shift; | ||||
|     uint8_t blue_mask_size; | ||||
|     uint8_t blue_mask_shift; | ||||
|     uint8_t unused[7]; | ||||
|     uint64_t edid_size; | ||||
|     LIMINE_PTR(void*) | ||||
|     edid; | ||||
|     /* Response revision 1 */ | ||||
|     uint64_t mode_count; | ||||
|     LIMINE_PTR(struct limine_video_mode**) | ||||
|     modes; | ||||
| }; | ||||
| 
 | ||||
| struct limine_framebuffer_response { | ||||
|     uint64_t revision; | ||||
|     uint64_t framebuffer_count; | ||||
|     LIMINE_PTR(struct limine_framebuffer**) | ||||
|     framebuffers; | ||||
| }; | ||||
| 
 | ||||
| struct limine_framebuffer_request { | ||||
|     uint64_t id[4]; | ||||
|     uint64_t revision; | ||||
|     LIMINE_PTR(struct limine_framebuffer_response*) | ||||
|     response; | ||||
| }; | ||||
| 
 | ||||
| /* Terminal */ | ||||
| 
 | ||||
| #    define LIMINE_TERMINAL_REQUEST {LIMINE_COMMON_MAGIC, 0xc8ac59310c2b0844, 0xa68d0c7265d38878} | ||||
| 
 | ||||
| #    define LIMINE_TERMINAL_CB_DEC           10 | ||||
| #    define LIMINE_TERMINAL_CB_BELL          20 | ||||
| #    define LIMINE_TERMINAL_CB_PRIVATE_ID    30 | ||||
| #    define LIMINE_TERMINAL_CB_STATUS_REPORT 40 | ||||
| #    define LIMINE_TERMINAL_CB_POS_REPORT    50 | ||||
| #    define LIMINE_TERMINAL_CB_KBD_LEDS      60 | ||||
| #    define LIMINE_TERMINAL_CB_MODE          70 | ||||
| #    define LIMINE_TERMINAL_CB_LINUX         80 | ||||
| 
 | ||||
| #    define LIMINE_TERMINAL_CTX_SIZE     ((uint64_t)(-1)) | ||||
| #    define LIMINE_TERMINAL_CTX_SAVE     ((uint64_t)(-2)) | ||||
| #    define LIMINE_TERMINAL_CTX_RESTORE  ((uint64_t)(-3)) | ||||
| #    define LIMINE_TERMINAL_FULL_REFRESH ((uint64_t)(-4)) | ||||
| 
 | ||||
| /* Response revision 1 */ | ||||
| #    define LIMINE_TERMINAL_OOB_OUTPUT_GET ((uint64_t)(-10)) | ||||
| #    define LIMINE_TERMINAL_OOB_OUTPUT_SET ((uint64_t)(-11)) | ||||
| 
 | ||||
| #    define LIMINE_TERMINAL_OOB_OUTPUT_OCRNL  (1 << 0) | ||||
| #    define LIMINE_TERMINAL_OOB_OUTPUT_OFDEL  (1 << 1) | ||||
| #    define LIMINE_TERMINAL_OOB_OUTPUT_OFILL  (1 << 2) | ||||
| #    define LIMINE_TERMINAL_OOB_OUTPUT_OLCUC  (1 << 3) | ||||
| #    define LIMINE_TERMINAL_OOB_OUTPUT_ONLCR  (1 << 4) | ||||
| #    define LIMINE_TERMINAL_OOB_OUTPUT_ONLRET (1 << 5) | ||||
| #    define LIMINE_TERMINAL_OOB_OUTPUT_ONOCR  (1 << 6) | ||||
| #    define LIMINE_TERMINAL_OOB_OUTPUT_OPOST  (1 << 7) | ||||
| 
 | ||||
| LIMINE_DEPRECATED_IGNORE_START | ||||
| 
 | ||||
| struct LIMINE_DEPRECATED limine_terminal; | ||||
| 
 | ||||
| typedef void (*limine_terminal_write)(struct limine_terminal*, char const*, uint64_t); | ||||
| typedef void (*limine_terminal_callback)(struct limine_terminal*, uint64_t, uint64_t, uint64_t, uint64_t); | ||||
| 
 | ||||
| struct LIMINE_DEPRECATED limine_terminal { | ||||
|     uint64_t columns; | ||||
|     uint64_t rows; | ||||
|     LIMINE_PTR(struct limine_framebuffer*) | ||||
|     framebuffer; | ||||
| }; | ||||
| 
 | ||||
| struct LIMINE_DEPRECATED limine_terminal_response { | ||||
|     uint64_t revision; | ||||
|     uint64_t terminal_count; | ||||
|     LIMINE_PTR(struct limine_terminal**) | ||||
|     terminals; | ||||
|     LIMINE_PTR(limine_terminal_write) | ||||
|     write; | ||||
| }; | ||||
| 
 | ||||
| struct LIMINE_DEPRECATED limine_terminal_request { | ||||
|     uint64_t id[4]; | ||||
|     uint64_t revision; | ||||
|     LIMINE_PTR(struct limine_terminal_response*) | ||||
|     response; | ||||
|     LIMINE_PTR(limine_terminal_callback) | ||||
|     callback; | ||||
| }; | ||||
| 
 | ||||
| LIMINE_DEPRECATED_IGNORE_END | ||||
| 
 | ||||
| /* Paging mode */ | ||||
| 
 | ||||
| #    define LIMINE_PAGING_MODE_REQUEST {LIMINE_COMMON_MAGIC, 0x95c1a0edab0944cb, 0xa4e5cb3842f7488a} | ||||
| 
 | ||||
| #    if defined(__x86_64__) || defined(__i386__) | ||||
| #        define LIMINE_PAGING_MODE_X86_64_4LVL 0 | ||||
| #        define LIMINE_PAGING_MODE_X86_64_5LVL 1 | ||||
| #        define LIMINE_PAGING_MODE_MIN         LIMINE_PAGING_MODE_X86_64_4LVL | ||||
| #        define LIMINE_PAGING_MODE_DEFAULT     LIMINE_PAGING_MODE_X86_64_4LVL | ||||
| #    elif defined(__aarch64__) | ||||
| #        define LIMINE_PAGING_MODE_AARCH64_4LVL 0 | ||||
| #        define LIMINE_PAGING_MODE_AARCH64_5LVL 1 | ||||
| #        define LIMINE_PAGING_MODE_MIN          LIMINE_PAGING_MODE_AARCH64_4LVL | ||||
| #        define LIMINE_PAGING_MODE_DEFAULT      LIMINE_PAGING_MODE_AARCH64_4LVL | ||||
| #    elif defined(__riscv) && (__riscv_xlen == 64) | ||||
| #        define LIMINE_PAGING_MODE_RISCV_SV39 0 | ||||
| #        define LIMINE_PAGING_MODE_RISCV_SV48 1 | ||||
| #        define LIMINE_PAGING_MODE_RISCV_SV57 2 | ||||
| #        define LIMINE_PAGING_MODE_MIN        LIMINE_PAGING_MODE_RISCV_SV39 | ||||
| #        define LIMINE_PAGING_MODE_DEFAULT    LIMINE_PAGING_MODE_RISCV_SV48 | ||||
| #    elif defined(__loongarch__) && (__loongarch_grlen == 64) | ||||
| #        define LIMINE_PAGING_MODE_LOONGARCH64_4LVL 0 | ||||
| #        define LIMINE_PAGING_MODE_MIN              LIMINE_PAGING_MODE_LOONGARCH64_4LVL | ||||
| #        define LIMINE_PAGING_MODE_DEFAULT          LIMINE_PAGING_MODE_LOONGARCH64_4LVL | ||||
| #    else | ||||
| #        error Unknown architecture | ||||
| #    endif | ||||
| 
 | ||||
| struct limine_paging_mode_response { | ||||
|     uint64_t revision; | ||||
|     uint64_t mode; | ||||
| }; | ||||
| 
 | ||||
| struct limine_paging_mode_request { | ||||
|     uint64_t id[4]; | ||||
|     uint64_t revision; | ||||
|     LIMINE_PTR(struct limine_paging_mode_response*) | ||||
|     response; | ||||
|     uint64_t mode; | ||||
|     uint64_t max_mode; | ||||
|     uint64_t min_mode; | ||||
| }; | ||||
| 
 | ||||
| /* 5-level paging */ | ||||
| 
 | ||||
| #    define LIMINE_5_LEVEL_PAGING_REQUEST {LIMINE_COMMON_MAGIC, 0x94469551da9b3192, 0xebe5e86db7382888} | ||||
| 
 | ||||
| LIMINE_DEPRECATED_IGNORE_START | ||||
| 
 | ||||
| struct LIMINE_DEPRECATED limine_5_level_paging_response { | ||||
|     uint64_t revision; | ||||
| }; | ||||
| 
 | ||||
| struct LIMINE_DEPRECATED limine_5_level_paging_request { | ||||
|     uint64_t id[4]; | ||||
|     uint64_t revision; | ||||
|     LIMINE_PTR(struct limine_5_level_paging_response*) | ||||
|     response; | ||||
| }; | ||||
| 
 | ||||
| LIMINE_DEPRECATED_IGNORE_END | ||||
| 
 | ||||
| /* MP */ | ||||
| 
 | ||||
| #    if LIMINE_API_REVISION >= 1 | ||||
| #        define LIMINE_MP_REQUEST {LIMINE_COMMON_MAGIC, 0x95a67b819a1b857e, 0xa0b61b723b6a73e0} | ||||
| #        define LIMINE_MP(TEXT)   limine_mp_##TEXT | ||||
| #    else | ||||
| #        define LIMINE_SMP_REQUEST {LIMINE_COMMON_MAGIC, 0x95a67b819a1b857e, 0xa0b61b723b6a73e0} | ||||
| #        define LIMINE_MP(TEXT)    limine_smp_##TEXT | ||||
| #    endif | ||||
| 
 | ||||
| struct LIMINE_MP(info); | ||||
| 
 | ||||
| typedef void (*limine_goto_address)(struct LIMINE_MP(info) *); | ||||
| 
 | ||||
| #    if defined(__x86_64__) || defined(__i386__) | ||||
| 
 | ||||
| #        if LIMINE_API_REVISION >= 1 | ||||
| #            define LIMINE_MP_X2APIC (1 << 0) | ||||
| #        else | ||||
| #            define LIMINE_SMP_X2APIC (1 << 0) | ||||
| #        endif | ||||
| 
 | ||||
| struct LIMINE_MP(info) { | ||||
|     uint32_t processor_id; | ||||
|     uint32_t lapic_id; | ||||
|     uint64_t reserved; | ||||
|     LIMINE_PTR(limine_goto_address) | ||||
|     goto_address; | ||||
|     uint64_t extra_argument; | ||||
| }; | ||||
| 
 | ||||
| struct LIMINE_MP(response) { | ||||
|     uint64_t revision; | ||||
|     uint32_t flags; | ||||
|     uint32_t bsp_lapic_id; | ||||
|     uint64_t cpu_count; | ||||
|     LIMINE_PTR(struct LIMINE_MP(info) **) | ||||
|     cpus; | ||||
| }; | ||||
| 
 | ||||
| #    elif defined(__aarch64__) | ||||
| 
 | ||||
| struct LIMINE_MP(info) { | ||||
|     uint32_t processor_id; | ||||
|     uint32_t reserved1; | ||||
|     uint64_t mpidr; | ||||
|     uint64_t reserved; | ||||
|     LIMINE_PTR(limine_goto_address) | ||||
|     goto_address; | ||||
|     uint64_t extra_argument; | ||||
| }; | ||||
| 
 | ||||
| struct LIMINE_MP(response) { | ||||
|     uint64_t revision; | ||||
|     uint64_t flags; | ||||
|     uint64_t bsp_mpidr; | ||||
|     uint64_t cpu_count; | ||||
|     LIMINE_PTR(struct LIMINE_MP(info) **) | ||||
|     cpus; | ||||
| }; | ||||
| 
 | ||||
| #    elif defined(__riscv) && (__riscv_xlen == 64) | ||||
| 
 | ||||
| struct LIMINE_MP(info) { | ||||
|     uint64_t processor_id; | ||||
|     uint64_t hartid; | ||||
|     uint64_t reserved; | ||||
|     LIMINE_PTR(limine_goto_address) | ||||
|     goto_address; | ||||
|     uint64_t extra_argument; | ||||
| }; | ||||
| 
 | ||||
| struct LIMINE_MP(response) { | ||||
|     uint64_t revision; | ||||
|     uint64_t flags; | ||||
|     uint64_t bsp_hartid; | ||||
|     uint64_t cpu_count; | ||||
|     LIMINE_PTR(struct LIMINE_MP(info) **) | ||||
|     cpus; | ||||
| }; | ||||
| 
 | ||||
| #    elif defined(__loongarch__) && (__loongarch_grlen == 64) | ||||
| 
 | ||||
| struct LIMINE_MP(info) { | ||||
|     uint64_t reserved; | ||||
| }; | ||||
| 
 | ||||
| struct LIMINE_MP(response) { | ||||
|     uint64_t cpu_count; | ||||
|     LIMINE_PTR(struct LIMINE_MP(info) **) | ||||
|     cpus; | ||||
| }; | ||||
| 
 | ||||
| #    else | ||||
| #        error Unknown architecture | ||||
| #    endif | ||||
| 
 | ||||
| struct LIMINE_MP(request) { | ||||
|     uint64_t id[4]; | ||||
|     uint64_t revision; | ||||
|     LIMINE_PTR(struct LIMINE_MP(response) *) | ||||
|     response; | ||||
|     uint64_t flags; | ||||
| }; | ||||
| 
 | ||||
| /* Memory map */ | ||||
| 
 | ||||
| #    define LIMINE_MEMMAP_REQUEST {LIMINE_COMMON_MAGIC, 0x67cf3d9d378a806f, 0xe304acdfc50c3c62} | ||||
| 
 | ||||
| #    define LIMINE_MEMMAP_USABLE                 0 | ||||
| #    define LIMINE_MEMMAP_RESERVED               1 | ||||
| #    define LIMINE_MEMMAP_ACPI_RECLAIMABLE       2 | ||||
| #    define LIMINE_MEMMAP_ACPI_NVS               3 | ||||
| #    define LIMINE_MEMMAP_BAD_MEMORY             4 | ||||
| #    define LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE 5 | ||||
| #    if LIMINE_API_REVISION >= 2 | ||||
| #        define LIMINE_MEMMAP_EXECUTABLE_AND_MODULES 6 | ||||
| #    else | ||||
| #        define LIMINE_MEMMAP_KERNEL_AND_MODULES 6 | ||||
| #    endif | ||||
| #    define LIMINE_MEMMAP_FRAMEBUFFER 7 | ||||
| 
 | ||||
| struct limine_memmap_entry { | ||||
|     uint64_t base; | ||||
|     uint64_t length; | ||||
|     uint64_t type; | ||||
| }; | ||||
| 
 | ||||
| struct limine_memmap_response { | ||||
|     uint64_t revision; | ||||
|     uint64_t entry_count; | ||||
|     LIMINE_PTR(struct limine_memmap_entry**) | ||||
|     entries; | ||||
| }; | ||||
| 
 | ||||
| struct limine_memmap_request { | ||||
|     uint64_t id[4]; | ||||
|     uint64_t revision; | ||||
|     LIMINE_PTR(struct limine_memmap_response*) | ||||
|     response; | ||||
| }; | ||||
| 
 | ||||
| /* Entry point */ | ||||
| 
 | ||||
| #    define LIMINE_ENTRY_POINT_REQUEST {LIMINE_COMMON_MAGIC, 0x13d86c035a1cd3e1, 0x2b0caa89d8f3026a} | ||||
| 
 | ||||
| typedef void (*limine_entry_point)(void); | ||||
| 
 | ||||
| struct limine_entry_point_response { | ||||
|     uint64_t revision; | ||||
| }; | ||||
| 
 | ||||
| struct limine_entry_point_request { | ||||
|     uint64_t id[4]; | ||||
|     uint64_t revision; | ||||
|     LIMINE_PTR(struct limine_entry_point_response*) | ||||
|     response; | ||||
|     LIMINE_PTR(limine_entry_point) | ||||
|     entry; | ||||
| }; | ||||
| 
 | ||||
| /* Executable File */ | ||||
| 
 | ||||
| #    if LIMINE_API_REVISION >= 2 | ||||
| #        define LIMINE_EXECUTABLE_FILE_REQUEST {LIMINE_COMMON_MAGIC, 0xad97e90e83f1ed67, 0x31eb5d1c5ff23b69} | ||||
| #    else | ||||
| #        define LIMINE_KERNEL_FILE_REQUEST {LIMINE_COMMON_MAGIC, 0xad97e90e83f1ed67, 0x31eb5d1c5ff23b69} | ||||
| #    endif | ||||
| 
 | ||||
| #    if LIMINE_API_REVISION >= 2 | ||||
| struct limine_executable_file_response { | ||||
| #    else | ||||
| struct limine_kernel_file_response { | ||||
| #    endif | ||||
|     uint64_t revision; | ||||
| #    if LIMINE_API_REVISION >= 2 | ||||
|     LIMINE_PTR(struct limine_file*) | ||||
|     executable_file; | ||||
| #    else | ||||
|     LIMINE_PTR(struct limine_file*) | ||||
|     kernel_file; | ||||
| #    endif | ||||
| }; | ||||
| 
 | ||||
| #    if LIMINE_API_REVISION >= 2 | ||||
| struct limine_executable_file_request { | ||||
| #    else | ||||
| struct limine_kernel_file_request { | ||||
| #    endif | ||||
|     uint64_t id[4]; | ||||
|     uint64_t revision; | ||||
| #    if LIMINE_API_REVISION >= 2 | ||||
|     LIMINE_PTR(struct limine_executable_file_response*) | ||||
|     response; | ||||
| #    else | ||||
|     LIMINE_PTR(struct limine_kernel_file_response*) | ||||
|     response; | ||||
| #    endif | ||||
| }; | ||||
| 
 | ||||
| /* Module */ | ||||
| 
 | ||||
| #    define LIMINE_MODULE_REQUEST {LIMINE_COMMON_MAGIC, 0x3e7e279702be32af, 0xca1c4f3bd1280cee} | ||||
| 
 | ||||
| #    define LIMINE_INTERNAL_MODULE_REQUIRED   (1 << 0) | ||||
| #    define LIMINE_INTERNAL_MODULE_COMPRESSED (1 << 1) | ||||
| 
 | ||||
| struct limine_internal_module { | ||||
|     LIMINE_PTR(char const*) | ||||
|     path; | ||||
| #    if LIMINE_API_REVISION >= 3 | ||||
|     LIMINE_PTR(const char*) | ||||
|     string; | ||||
| #    else | ||||
|     LIMINE_PTR(const char*) | ||||
|     cmdline; | ||||
| #    endif | ||||
|     uint64_t flags; | ||||
| }; | ||||
| 
 | ||||
| struct limine_module_response { | ||||
|     uint64_t revision; | ||||
|     uint64_t module_count; | ||||
|     LIMINE_PTR(struct limine_file**) | ||||
|     modules; | ||||
| }; | ||||
| 
 | ||||
| struct limine_module_request { | ||||
|     uint64_t id[4]; | ||||
|     uint64_t revision; | ||||
|     LIMINE_PTR(struct limine_module_response*) | ||||
|     response; | ||||
| 
 | ||||
|     /* Request revision 1 */ | ||||
|     uint64_t internal_module_count; | ||||
|     LIMINE_PTR(struct limine_internal_module**) | ||||
|     internal_modules; | ||||
| }; | ||||
| 
 | ||||
| /* RSDP */ | ||||
| 
 | ||||
| #    define LIMINE_RSDP_REQUEST {LIMINE_COMMON_MAGIC, 0xc5e77b6b397e7b43, 0x27637845accdcf3c} | ||||
| 
 | ||||
| struct limine_rsdp_response { | ||||
|     uint64_t revision; | ||||
| #    if LIMINE_API_REVISION >= 1 | ||||
|     uint64_t address; | ||||
| #    else | ||||
|     LIMINE_PTR(void*) | ||||
|     address; | ||||
| #    endif | ||||
| }; | ||||
| 
 | ||||
| struct limine_rsdp_request { | ||||
|     uint64_t id[4]; | ||||
|     uint64_t revision; | ||||
|     LIMINE_PTR(struct limine_rsdp_response*) | ||||
|     response; | ||||
| }; | ||||
| 
 | ||||
| /* SMBIOS */ | ||||
| 
 | ||||
| #    define LIMINE_SMBIOS_REQUEST {LIMINE_COMMON_MAGIC, 0x9e9046f11e095391, 0xaa4a520fefbde5ee} | ||||
| 
 | ||||
| struct limine_smbios_response { | ||||
|     uint64_t revision; | ||||
| #    if LIMINE_API_REVISION >= 1 | ||||
|     uint64_t entry_32; | ||||
|     uint64_t entry_64; | ||||
| #    else | ||||
|     LIMINE_PTR(void*) | ||||
|     entry_32; | ||||
|     LIMINE_PTR(void*) | ||||
|     entry_64; | ||||
| #    endif | ||||
| }; | ||||
| 
 | ||||
| struct limine_smbios_request { | ||||
|     uint64_t id[4]; | ||||
|     uint64_t revision; | ||||
|     LIMINE_PTR(struct limine_smbios_response*) | ||||
|     response; | ||||
| }; | ||||
| 
 | ||||
| /* EFI system table */ | ||||
| 
 | ||||
| #    define LIMINE_EFI_SYSTEM_TABLE_REQUEST {LIMINE_COMMON_MAGIC, 0x5ceba5163eaaf6d6, 0x0a6981610cf65fcc} | ||||
| 
 | ||||
| struct limine_efi_system_table_response { | ||||
|     uint64_t revision; | ||||
| #    if LIMINE_API_REVISION >= 1 | ||||
|     uint64_t address; | ||||
| #    else | ||||
|     LIMINE_PTR(void*) | ||||
|     address; | ||||
| #    endif | ||||
| }; | ||||
| 
 | ||||
| struct limine_efi_system_table_request { | ||||
|     uint64_t id[4]; | ||||
|     uint64_t revision; | ||||
|     LIMINE_PTR(struct limine_efi_system_table_response*) | ||||
|     response; | ||||
| }; | ||||
| 
 | ||||
| /* EFI memory map */ | ||||
| 
 | ||||
| #    define LIMINE_EFI_MEMMAP_REQUEST {LIMINE_COMMON_MAGIC, 0x7df62a431d6872d5, 0xa4fcdfb3e57306c8} | ||||
| 
 | ||||
| struct limine_efi_memmap_response { | ||||
|     uint64_t revision; | ||||
|     LIMINE_PTR(void*) | ||||
|     memmap; | ||||
|     uint64_t memmap_size; | ||||
|     uint64_t desc_size; | ||||
|     uint64_t desc_version; | ||||
| }; | ||||
| 
 | ||||
| struct limine_efi_memmap_request { | ||||
|     uint64_t id[4]; | ||||
|     uint64_t revision; | ||||
|     LIMINE_PTR(struct limine_efi_memmap_response*) | ||||
|     response; | ||||
| }; | ||||
| 
 | ||||
| /* Date at boot */ | ||||
| 
 | ||||
| #    if LIMINE_API_REVISION >= 3 | ||||
| #        define LIMINE_DATE_AT_BOOT_REQUEST {LIMINE_COMMON_MAGIC, 0x502746e184c088aa, 0xfbc5ec83e6327893} | ||||
| #    else | ||||
| #        define LIMINE_BOOT_TIME_REQUEST {LIMINE_COMMON_MAGIC, 0x502746e184c088aa, 0xfbc5ec83e6327893} | ||||
| #    endif | ||||
| 
 | ||||
| #    if LIMINE_API_REVISION >= 3 | ||||
| struct limine_date_at_boot_response { | ||||
| #    else | ||||
| struct limine_boot_time_response { | ||||
| #    endif | ||||
|     uint64_t revision; | ||||
| #    if LIMINE_API_REVISION >= 3 | ||||
|     int64_t timestamp; | ||||
| #    else | ||||
|     int64_t boot_time; | ||||
| #    endif | ||||
| }; | ||||
| 
 | ||||
| #    if LIMINE_API_REVISION >= 3 | ||||
| struct limine_date_at_boot_request { | ||||
| #    else | ||||
| struct limine_boot_time_request { | ||||
| #    endif | ||||
|     uint64_t id[4]; | ||||
|     uint64_t revision; | ||||
| #    if LIMINE_API_REVISION >= 3 | ||||
|     LIMINE_PTR(struct limine_date_at_boot_response*) | ||||
|     response; | ||||
| #    else | ||||
|     LIMINE_PTR(struct limine_boot_time_response*) | ||||
|     response; | ||||
| #    endif | ||||
| }; | ||||
| 
 | ||||
| /* Executable address */ | ||||
| 
 | ||||
| #    if LIMINE_API_REVISION >= 2 | ||||
| #        define LIMINE_EXECUTABLE_ADDRESS_REQUEST {LIMINE_COMMON_MAGIC, 0x71ba76863cc55f63, 0xb2644a48c516a487} | ||||
| #    else | ||||
| #        define LIMINE_KERNEL_ADDRESS_REQUEST {LIMINE_COMMON_MAGIC, 0x71ba76863cc55f63, 0xb2644a48c516a487} | ||||
| #    endif | ||||
| 
 | ||||
| #    if LIMINE_API_REVISION >= 2 | ||||
| struct limine_executable_address_response { | ||||
| #    else | ||||
| struct limine_kernel_address_response { | ||||
| #    endif | ||||
|     uint64_t revision; | ||||
|     uint64_t physical_base; | ||||
|     uint64_t virtual_base; | ||||
| }; | ||||
| 
 | ||||
| #    if LIMINE_API_REVISION >= 2 | ||||
| struct limine_executable_address_request { | ||||
| #    else | ||||
| struct limine_kernel_address_request { | ||||
| #    endif | ||||
|     uint64_t id[4]; | ||||
|     uint64_t revision; | ||||
| #    if LIMINE_API_REVISION >= 2 | ||||
|     LIMINE_PTR(struct limine_executable_address_response*) | ||||
|     response; | ||||
| #    else | ||||
|     LIMINE_PTR(struct limine_kernel_address_response*) | ||||
|     response; | ||||
| #    endif | ||||
| }; | ||||
| 
 | ||||
| /* Device Tree Blob */ | ||||
| 
 | ||||
| #    define LIMINE_DTB_REQUEST {LIMINE_COMMON_MAGIC, 0xb40ddb48fb54bac7, 0x545081493f81ffb7} | ||||
| 
 | ||||
| struct limine_dtb_response { | ||||
|     uint64_t revision; | ||||
|     LIMINE_PTR(void*) | ||||
|     dtb_ptr; | ||||
| }; | ||||
| 
 | ||||
| struct limine_dtb_request { | ||||
|     uint64_t id[4]; | ||||
|     uint64_t revision; | ||||
|     LIMINE_PTR(struct limine_dtb_response*) | ||||
|     response; | ||||
| }; | ||||
| 
 | ||||
| /* RISC-V Boot Hart ID */ | ||||
| 
 | ||||
| #    define LIMINE_RISCV_BSP_HARTID_REQUEST {LIMINE_COMMON_MAGIC, 0x1369359f025525f9, 0x2ff2a56178391bb6} | ||||
| 
 | ||||
| struct limine_riscv_bsp_hartid_response { | ||||
|     uint64_t revision; | ||||
|     uint64_t bsp_hartid; | ||||
| }; | ||||
| 
 | ||||
| struct limine_riscv_bsp_hartid_request { | ||||
|     uint64_t id[4]; | ||||
|     uint64_t revision; | ||||
|     LIMINE_PTR(struct limine_riscv_bsp_hartid_response*) | ||||
|     response; | ||||
| }; | ||||
| 
 | ||||
| /* Bootloader Performance */ | ||||
| 
 | ||||
| #    define LIMINE_BOOTLOADER_PERFORMANCE_REQUEST {LIMINE_COMMON_MAGIC, 0x6b50ad9bf36d13ad, 0xdc4c7e88fc759e17} | ||||
| 
 | ||||
| struct limine_bootloader_performance_response { | ||||
|     uint64_t revision; | ||||
|     uint64_t reset_usec; | ||||
|     uint64_t init_usec; | ||||
|     uint64_t exec_usec; | ||||
| }; | ||||
| 
 | ||||
| struct limine_bootloader_performance_request { | ||||
|     uint64_t id[4]; | ||||
|     uint64_t revision; | ||||
|     LIMINE_PTR(struct limine_bootloader_performance_response*) | ||||
|     response; | ||||
| }; | ||||
| 
 | ||||
| #    ifdef __cplusplus | ||||
| } | ||||
| #    endif | ||||
| 
 | ||||
| #endif | ||||
|  | @ -1,5 +1,6 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <hal> | ||||
| #include <helpers/loc.h> | ||||
| 
 | ||||
| typedef enum { | ||||
|  | @ -19,6 +20,10 @@ typedef enum { | |||
| #define error$(...) _log(LOG_ERROR, loc$(), __VA_ARGS__) | ||||
| #define print$(...) _log(LOG_NONE, (Loc){0}, __VA_ARGS__) | ||||
| 
 | ||||
| #define panic$(...)                       \ | ||||
|     _log(LOG_ERROR, loc$(), __VA_ARGS__); \ | ||||
|     hal_brkpoint(); | ||||
| 
 | ||||
| static char const* level_names[LOG_EVENT_LENGTH] = { | ||||
|     [LOG_NONE]  = "", | ||||
|     [LOG_DEBUG] = "DEBUG", | ||||
|  |  | |||
|  | @ -5,6 +5,7 @@ | |||
| #include "mod.h" | ||||
| 
 | ||||
| TaskError task_new(char const* name, HalPage* page_table, uintptr_t ip, Allocator* alloc) { | ||||
|     (void)ip; | ||||
|     Task* task = alloc->alloc(alloc, sizeof(Task)); | ||||
| 
 | ||||
|     if (task == NULL) { | ||||
|  |  | |||
|  | @ -1,9 +1,9 @@ | |||
| { | ||||
|     "$schema": "https://schemas.cute.engineering/stable/cutekit.manifest.component.v1", | ||||
|     "id": "kmalloc", | ||||
|     "type": "lib", | ||||
|     "id": "handover-limine", | ||||
|     "requires": [ | ||||
|         "allocators", | ||||
|         "traits" | ||||
|         "limine", | ||||
|         "handover" | ||||
|     ] | ||||
| } | ||||
							
								
								
									
										8
									
								
								src/libs/handover/limine/mod.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/libs/handover/limine/mod.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,8 @@ | |||
| #include "mod.h" | ||||
| #include <limine> | ||||
| 
 | ||||
| static HandoverPayload* payload = NULL; | ||||
| 
 | ||||
| HandoverPayload* handover(void) { | ||||
|     return payload; | ||||
| } | ||||
							
								
								
									
										7
									
								
								src/libs/handover/limine/mod.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/libs/handover/limine/mod.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,7 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <handover> | ||||
| 
 | ||||
| void handover_init(void); | ||||
| 
 | ||||
| HandoverPayload* handover(void); | ||||
		Loading…
	
	Add table
		
		Reference in a new issue