diff --git a/cppreduceOS.code-workspace b/cppreduceOS.code-workspace index 340695af..b85b224a 100644 --- a/cppreduceOS.code-workspace +++ b/cppreduceOS.code-workspace @@ -27,7 +27,12 @@ "pmm.h": "c", "panic.h": "c", "floppy.h": "c", - "syscall.h": "c" + "syscall.h": "c", + "mem.h": "c", + "list.h": "c", + "hashmap.h": "c", + "liballoc_forwarder.h": "c", + "vmm.h": "c" } } } \ No newline at end of file diff --git a/obj/assembly/bios.o b/obj/assembly/bios.o deleted file mode 100644 index a6f434fe..00000000 Binary files a/obj/assembly/bios.o and /dev/null differ diff --git a/obj/assembly/bochs.o b/obj/assembly/bochs.o deleted file mode 100644 index 859fa3cb..00000000 Binary files a/obj/assembly/bochs.o and /dev/null differ diff --git a/obj/assembly/boot.o b/obj/assembly/boot.o deleted file mode 100644 index b0e3d1e3..00000000 Binary files a/obj/assembly/boot.o and /dev/null differ diff --git a/obj/assembly/crtbegin.o b/obj/assembly/crtbegin.o deleted file mode 100644 index 49f9e248..00000000 Binary files a/obj/assembly/crtbegin.o and /dev/null differ diff --git a/obj/assembly/crtend.o b/obj/assembly/crtend.o deleted file mode 100644 index 09855c65..00000000 Binary files a/obj/assembly/crtend.o and /dev/null differ diff --git a/obj/assembly/crti.o b/obj/assembly/crti.o deleted file mode 100644 index 1a4b7bd1..00000000 Binary files a/obj/assembly/crti.o and /dev/null differ diff --git a/obj/assembly/crtn.o b/obj/assembly/crtn.o deleted file mode 100644 index 61b222e1..00000000 Binary files a/obj/assembly/crtn.o and /dev/null differ diff --git a/obj/assembly/gdt.o b/obj/assembly/gdt.o deleted file mode 100644 index f60b3d82..00000000 Binary files a/obj/assembly/gdt.o and /dev/null differ diff --git a/obj/assembly/idt.o b/obj/assembly/idt.o deleted file mode 100644 index 306e82e5..00000000 Binary files a/obj/assembly/idt.o and /dev/null differ diff --git a/obj/assembly/isr.o b/obj/assembly/isr.o deleted file mode 100644 index 67c9b7e1..00000000 Binary files a/obj/assembly/isr.o and /dev/null differ diff --git a/obj/assembly/tss.o b/obj/assembly/tss.o deleted file mode 100644 index f6039490..00000000 Binary files a/obj/assembly/tss.o and /dev/null differ diff --git a/obj/assembly/usermode.o b/obj/assembly/usermode.o deleted file mode 100644 index dce59818..00000000 Binary files a/obj/assembly/usermode.o and /dev/null differ diff --git a/obj/base/bios32.o b/obj/base/bios32.o deleted file mode 100644 index 3a7c57c4..00000000 Binary files a/obj/base/bios32.o and /dev/null differ diff --git a/obj/base/gdt.o b/obj/base/gdt.o deleted file mode 100644 index 42ec6eaf..00000000 Binary files a/obj/base/gdt.o and /dev/null differ diff --git a/obj/base/hal.o b/obj/base/hal.o deleted file mode 100644 index d6c87de5..00000000 Binary files a/obj/base/hal.o and /dev/null differ diff --git a/obj/base/idt.o b/obj/base/idt.o deleted file mode 100644 index 3b49ac07..00000000 Binary files a/obj/base/idt.o and /dev/null differ diff --git a/obj/base/isr.o b/obj/base/isr.o deleted file mode 100644 index b30d12bf..00000000 Binary files a/obj/base/isr.o and /dev/null differ diff --git a/obj/base/pic.o b/obj/base/pic.o deleted file mode 100644 index 15b44444..00000000 Binary files a/obj/base/pic.o and /dev/null differ diff --git a/obj/base/processor.o b/obj/base/processor.o deleted file mode 100644 index 2e3729fe..00000000 Binary files a/obj/base/processor.o and /dev/null differ diff --git a/obj/drivers/acpi.o b/obj/drivers/acpi.o deleted file mode 100644 index 86d9cb3f..00000000 Binary files a/obj/drivers/acpi.o and /dev/null differ diff --git a/obj/drivers/floppy.o b/obj/drivers/floppy.o deleted file mode 100644 index 1f25755f..00000000 Binary files a/obj/drivers/floppy.o and /dev/null differ diff --git a/obj/drivers/ide_ata.o b/obj/drivers/ide_ata.o deleted file mode 100644 index 2568aa73..00000000 Binary files a/obj/drivers/ide_ata.o and /dev/null differ diff --git a/obj/drivers/io_apic.o b/obj/drivers/io_apic.o deleted file mode 100644 index 3d6d34eb..00000000 Binary files a/obj/drivers/io_apic.o and /dev/null differ diff --git a/obj/drivers/keyboard.o b/obj/drivers/keyboard.o deleted file mode 100644 index 8c8fbdcb..00000000 Binary files a/obj/drivers/keyboard.o and /dev/null differ diff --git a/obj/drivers/local_apic.o b/obj/drivers/local_apic.o deleted file mode 100644 index e8a589fe..00000000 Binary files a/obj/drivers/local_apic.o and /dev/null differ diff --git a/obj/drivers/pci.o b/obj/drivers/pci.o deleted file mode 100644 index ceb6d260..00000000 Binary files a/obj/drivers/pci.o and /dev/null differ diff --git a/obj/drivers/pit.o b/obj/drivers/pit.o deleted file mode 100644 index 735f1b0e..00000000 Binary files a/obj/drivers/pit.o and /dev/null differ diff --git a/obj/drivers/rtc.o b/obj/drivers/rtc.o deleted file mode 100644 index f60bd3d8..00000000 Binary files a/obj/drivers/rtc.o and /dev/null differ diff --git a/obj/drivers/serial.o b/obj/drivers/serial.o deleted file mode 100644 index 94264bda..00000000 Binary files a/obj/drivers/serial.o and /dev/null differ diff --git a/obj/fonts/font.o b/obj/fonts/font.o deleted file mode 100644 index 12719e73..00000000 Binary files a/obj/fonts/font.o and /dev/null differ diff --git a/obj/fs/ext2.o b/obj/fs/ext2.o deleted file mode 100644 index b28c4ec8..00000000 Binary files a/obj/fs/ext2.o and /dev/null differ diff --git a/obj/fs/fat.o b/obj/fs/fat.o deleted file mode 100644 index 19e71053..00000000 Binary files a/obj/fs/fat.o and /dev/null differ diff --git a/obj/fs/initrd.o b/obj/fs/initrd.o deleted file mode 100644 index 3173e9c8..00000000 Binary files a/obj/fs/initrd.o and /dev/null differ diff --git a/obj/fs/vfs.o b/obj/fs/vfs.o deleted file mode 100644 index e3010921..00000000 Binary files a/obj/fs/vfs.o and /dev/null differ diff --git a/obj/gfx/bitmap.o b/obj/gfx/bitmap.o deleted file mode 100644 index 0fbfa364..00000000 Binary files a/obj/gfx/bitmap.o and /dev/null differ diff --git a/obj/gfx/font.o b/obj/gfx/font.o deleted file mode 100644 index da36f098..00000000 Binary files a/obj/gfx/font.o and /dev/null differ diff --git a/obj/gfx/font_data.o b/obj/gfx/font_data.o deleted file mode 100644 index b07225ce..00000000 Binary files a/obj/gfx/font_data.o and /dev/null differ diff --git a/obj/gfx/gfx.o b/obj/gfx/gfx.o deleted file mode 100644 index d6c85814..00000000 Binary files a/obj/gfx/gfx.o and /dev/null differ diff --git a/obj/gfx/terminal.o b/obj/gfx/terminal.o deleted file mode 100644 index d34fe3db..00000000 Binary files a/obj/gfx/terminal.o and /dev/null differ diff --git a/obj/gfx/vesa.o b/obj/gfx/vesa.o deleted file mode 100644 index ecedfd69..00000000 Binary files a/obj/gfx/vesa.o and /dev/null differ diff --git a/obj/kernel/cmds.o b/obj/kernel/cmds.o deleted file mode 100644 index 7ac1e3c5..00000000 Binary files a/obj/kernel/cmds.o and /dev/null differ diff --git a/obj/kernel/command.o b/obj/kernel/command.o deleted file mode 100644 index 1e6ff6d6..00000000 Binary files a/obj/kernel/command.o and /dev/null differ diff --git a/obj/kernel/kernel.o b/obj/kernel/kernel.o deleted file mode 100644 index c1a65e42..00000000 Binary files a/obj/kernel/kernel.o and /dev/null differ diff --git a/obj/kernel/panic.o b/obj/kernel/panic.o deleted file mode 100644 index e28a7ca6..00000000 Binary files a/obj/kernel/panic.o and /dev/null differ diff --git a/obj/kernel/test.o b/obj/kernel/test.o deleted file mode 100644 index 84676ca0..00000000 Binary files a/obj/kernel/test.o and /dev/null differ diff --git a/obj/libc/list.o b/obj/libc/list.o deleted file mode 100644 index e546eb65..00000000 Binary files a/obj/libc/list.o and /dev/null differ diff --git a/obj/libc/ordered_array.o b/obj/libc/ordered_array.o deleted file mode 100644 index 5d62d836..00000000 Binary files a/obj/libc/ordered_array.o and /dev/null differ diff --git a/obj/libc/printf.o b/obj/libc/printf.o deleted file mode 100644 index 273395bd..00000000 Binary files a/obj/libc/printf.o and /dev/null differ diff --git a/obj/libc/putchar.o b/obj/libc/putchar.o deleted file mode 100644 index b0b790b8..00000000 Binary files a/obj/libc/putchar.o and /dev/null differ diff --git a/obj/libc/sleep.o b/obj/libc/sleep.o deleted file mode 100644 index 6c397322..00000000 Binary files a/obj/libc/sleep.o and /dev/null differ diff --git a/obj/libc/spinlock.o b/obj/libc/spinlock.o deleted file mode 100644 index bf6d4723..00000000 Binary files a/obj/libc/spinlock.o and /dev/null differ diff --git a/obj/libc/stdlib.o b/obj/libc/stdlib.o deleted file mode 100644 index 1e7527be..00000000 Binary files a/obj/libc/stdlib.o and /dev/null differ diff --git a/obj/libc/string.o b/obj/libc/string.o deleted file mode 100644 index 780ee30e..00000000 Binary files a/obj/libc/string.o and /dev/null differ diff --git a/obj/libc/tree.o b/obj/libc/tree.o deleted file mode 100644 index 631dd516..00000000 Binary files a/obj/libc/tree.o and /dev/null differ diff --git a/obj/mem/dma.o b/obj/mem/dma.o deleted file mode 100644 index 9a647e79..00000000 Binary files a/obj/mem/dma.o and /dev/null differ diff --git a/obj/mem/liballoc/liballoc.o b/obj/mem/liballoc/liballoc.o deleted file mode 100644 index 58c7c62e..00000000 Binary files a/obj/mem/liballoc/liballoc.o and /dev/null differ diff --git a/obj/mem/liballoc/liballoc_forwarder.o b/obj/mem/liballoc/liballoc_forwarder.o deleted file mode 100644 index 6df54fb5..00000000 Binary files a/obj/mem/liballoc/liballoc_forwarder.o and /dev/null differ diff --git a/obj/mem/liballoc/liballoc_wrapper.o b/obj/mem/liballoc/liballoc_wrapper.o deleted file mode 100644 index 4b364ea1..00000000 Binary files a/obj/mem/liballoc/liballoc_wrapper.o and /dev/null differ diff --git a/obj/mem/pmm.o b/obj/mem/pmm.o deleted file mode 100644 index 89ad3a4e..00000000 Binary files a/obj/mem/pmm.o and /dev/null differ diff --git a/obj/mem/vmm.o b/obj/mem/vmm.o deleted file mode 100644 index e544a5f6..00000000 Binary files a/obj/mem/vmm.o and /dev/null differ diff --git a/obj/mem/vmm_pde.o b/obj/mem/vmm_pde.o deleted file mode 100644 index 7c8f0e92..00000000 Binary files a/obj/mem/vmm_pde.o and /dev/null differ diff --git a/obj/mem/vmm_pte.o b/obj/mem/vmm_pte.o deleted file mode 100644 index d064f61d..00000000 Binary files a/obj/mem/vmm_pte.o and /dev/null differ diff --git a/obj/misc/hashmap.o b/obj/misc/hashmap.o deleted file mode 100644 index 5c00efdc..00000000 Binary files a/obj/misc/hashmap.o and /dev/null differ diff --git a/obj/misc/list.o b/obj/misc/list.o deleted file mode 100644 index 7740a3e6..00000000 Binary files a/obj/misc/list.o and /dev/null differ diff --git a/obj/misc/tree.o b/obj/misc/tree.o deleted file mode 100644 index dc3b6e09..00000000 Binary files a/obj/misc/tree.o and /dev/null differ diff --git a/obj/tasks/syscall.o b/obj/tasks/syscall.o deleted file mode 100644 index 386e5729..00000000 Binary files a/obj/tasks/syscall.o and /dev/null differ diff --git a/obj/tasks/tss.o b/obj/tasks/tss.o deleted file mode 100644 index d731f353..00000000 Binary files a/obj/tasks/tss.o and /dev/null differ diff --git a/source/initial_ramdisk/generate_initrd b/source/initial_ramdisk/generate_initrd deleted file mode 100755 index 93cb36f6..00000000 Binary files a/source/initial_ramdisk/generate_initrd and /dev/null differ diff --git a/source/initial_ramdisk/obj/generate_initrd.o b/source/initial_ramdisk/obj/generate_initrd.o deleted file mode 100644 index a21bb72c..00000000 Binary files a/source/initial_ramdisk/obj/generate_initrd.o and /dev/null differ diff --git a/source/kernel/Makefile b/source/kernel/Makefile index f59d4579..b61a8371 100644 --- a/source/kernel/Makefile +++ b/source/kernel/Makefile @@ -19,7 +19,7 @@ OUT_KERNEL = . ASM_SOURCE_DIR = assembly # Directories (EDIT ME) -SOURCE_DIRECTORIES = kernel libc drivers base gfx fs mem tasks misc +SOURCE_DIRECTORIES = kernel drivers base gfx fs mem tasks misc SOURCE_SUBDIRECTORIES = mem/liballoc # We do this because shell find will pick up anything in subdirectories twice DIRECTORIES = $(addprefix $(OUT_OBJ)/,$(SOURCE_DIRECTORIES)) $(addprefix $(OUT_OBJ)/,$(SOURCE_SUBDIRECTORIES)) @@ -51,11 +51,11 @@ TARGET_DISABLED: $(OUT_KERNEL)/kernel_debug.elf: MAKE_OUTPUT_DIRS DELETE_OLD_KERNEL_OBJ BUILDSCRIPTS_DEBUG PRINT_ASM_HEADER $(ASM_OBJS) PRINT_C_HEADER $(C_OBJS) @echo "-- Linking $(OUT_KERNEL)/kernel.elf for DEBUG target..." - $(LD) $(LDFLAGS) -T linker.ld $(C_OBJS) $(ASM_OBJS) $(OUT_OBJ)/fonts/*.o -o kernel.elf $(LIBS) -lgcc + $(LD) $(LDFLAGS) -T linker.ld $(C_OBJS) $(ASM_OBJS) $(OUT_OBJ)/fonts/*.o -o kernel.elf $(LIBS) $(OUT_KERNEL)/kernel_release.elf: MAKE_OUTPUT_DIRS DELETE_OLD_KERNEL_OBJ BUILDSCRIPTS_RELEASE PRINT_ASM_HEADER $(ASM_OBJS) PRINT_C_HEADER $(C_OBJS) @echo "-- Linking $(OUT_KERNEL)/kernel.elf for RELEASE target..." - $(LD) $(LDFLAGS) -T linker.ld $(C_OBJS) $(ASM_OBJS) $(OUT_OBJ)/fonts/*.o -o kernel.elf $(LIBS) -lgcc + $(LD) $(LDFLAGS) -T linker.ld $(C_OBJS) $(ASM_OBJS) $(OUT_OBJ)/fonts/*.o -o kernel.elf $(LIBS) @echo "-- Stripping debug symbols..." objcopy --strip-debug kernel.elf @@ -106,7 +106,7 @@ $(OUT_OBJ)/%.o: %.c Makefile $(OUT_ASMOBJ)/crtbegin.o $(OUT_ASMOBJ)/crtend.o: - OBJ=`$(CC) $(CFLAGS) $(LDFLAGS) -print-file-name=$(@F)` && cp "$$OBJ" $@ + OBJ=`$(CC) $(CFLAGS) -print-file-name=$(@F)` && cp "$$OBJ" $@ # Installation functions diff --git a/source/kernel/base/bios32.c b/source/kernel/base/bios32.c index 61133520..fb5ae95e 100644 --- a/source/kernel/base/bios32.c +++ b/source/kernel/base/bios32.c @@ -1,62 +1,62 @@ -// ====================================================================== -// bios32.c - Handles real-mode interrupt calls in protected mode -// ====================================================================== - -#include "include/bios32.h" // Main header file - -idtPtr_t realModeGDT; -idtPtr_t realModeIDT; - -extern gdtEntry_t gdtEntries[8]; - -void (*bios32_execute)() = (void *)0x7c00; - -void bios32_init() { - // Set up the 16-bit code and data segment in GDT. - gdtSetGate(6, 0, 0xFFFFFFFF, 0x9A, 0x0F); - gdtSetGate(7, 0, 0xFFFFFFFF, 0x92, 0x0F); - - // Setup the real mode GDT ptr - realModeGDT.base_addr = (uint32_t)gdtEntries; - realModeGDT.limit = sizeof(gdtEntries) - 1; - - // Setup the real mode IDT ptr - realModeIDT.base_addr = 0; - realModeIDT.limit = 0x3FF; -} - -// bios32_call(uint8_t interrupt, REGISTERS_16 *in, REGISTERS_16 *out) - Calls bios32. -void bios32_call(uint8_t interrupt, REGISTERS_16 *in, REGISTERS_16 *out) { - serialPrintf("Preparing to call BIOS32 for int 0x%x...\n\tAX = 0x%x BX = 0x%x CX = 0x%x DX = 0x%x\n", interrupt, in->ax, in->bx, in->cx, in->dx); - void *newCodeBase = (void *)0x7c00; - - // Copy the GDT entries to the BIOS32 GDT entries. - memcpy(&bios32_gdt_entries, gdtEntries, sizeof(gdtEntries)); - - // Update the base address of the GDT entries, starting from 0x7C00. - realModeGDT.base_addr = (uint32_t)REBASE_ADDRESS((&bios32_gdt_entries)); - - // Copy the real mode GDT and IDT to their respective pointers. - memcpy(&bios32_gdt_ptr, &realModeGDT, sizeof(idtPtr_t)); - memcpy(&bios32_idt_ptr, &realModeIDT, sizeof(idtPtr_t)); - - // Copy the in registers to their pointers. - memcpy(&bios32_in_reg16_ptr, in, sizeof(REGISTERS_16)); - - // Get the in registers' address. - void *in_reg16_address = REBASE_ADDRESS(&bios32_in_reg16_ptr); - - // Copy the BIOS interrupt number to its respective pointer. - memcpy(&bios32_int_number_ptr, &interrupt, sizeof(uint8_t)); - - // Copy the bios32 code to a new address. - uint32_t size = (uint32_t)BIOS32_END - (uint32_t)BIOS32_START; - memcpy(newCodeBase, BIOS32_START, size); - - // Start executing the BIOS32 code. - bios32_execute(); - - // Copy the output registers to the out ptr. - in_reg16_address = REBASE_ADDRESS(&bios32_out_reg16_ptr); - memcpy(out, in_reg16_address, sizeof(REGISTERS_16)); -} +// ====================================================================== +// bios32.c - Handles real-mode interrupt calls in protected mode +// ====================================================================== + +#include // Main header file + +idtPtr_t realModeGDT; +idtPtr_t realModeIDT; + +extern gdtEntry_t gdtEntries[8]; + +void (*bios32_execute)() = (void *)0x7c00; + +void bios32_init() { + // Set up the 16-bit code and data segment in GDT. + gdtSetGate(6, 0, 0xFFFFFFFF, 0x9A, 0x0F); + gdtSetGate(7, 0, 0xFFFFFFFF, 0x92, 0x0F); + + // Setup the real mode GDT ptr + realModeGDT.base_addr = (uint32_t)gdtEntries; + realModeGDT.limit = sizeof(gdtEntries) - 1; + + // Setup the real mode IDT ptr + realModeIDT.base_addr = 0; + realModeIDT.limit = 0x3FF; +} + +// bios32_call(uint8_t interrupt, REGISTERS_16 *in, REGISTERS_16 *out) - Calls bios32. +void bios32_call(uint8_t interrupt, REGISTERS_16 *in, REGISTERS_16 *out) { + serialPrintf("Preparing to call BIOS32 for int 0x%x...\n\tAX = 0x%x BX = 0x%x CX = 0x%x DX = 0x%x\n", interrupt, in->ax, in->bx, in->cx, in->dx); + void *newCodeBase = (void *)0x7c00; + + // Copy the GDT entries to the BIOS32 GDT entries. + memcpy(&bios32_gdt_entries, gdtEntries, sizeof(gdtEntries)); + + // Update the base address of the GDT entries, starting from 0x7C00. + realModeGDT.base_addr = (uint32_t)REBASE_ADDRESS((&bios32_gdt_entries)); + + // Copy the real mode GDT and IDT to their respective pointers. + memcpy(&bios32_gdt_ptr, &realModeGDT, sizeof(idtPtr_t)); + memcpy(&bios32_idt_ptr, &realModeIDT, sizeof(idtPtr_t)); + + // Copy the in registers to their pointers. + memcpy(&bios32_in_reg16_ptr, in, sizeof(REGISTERS_16)); + + // Get the in registers' address. + void *in_reg16_address = REBASE_ADDRESS(&bios32_in_reg16_ptr); + + // Copy the BIOS interrupt number to its respective pointer. + memcpy(&bios32_int_number_ptr, &interrupt, sizeof(uint8_t)); + + // Copy the bios32 code to a new address. + uint32_t size = (uint32_t)BIOS32_END - (uint32_t)BIOS32_START; + memcpy(newCodeBase, BIOS32_START, size); + + // Start executing the BIOS32 code. + bios32_execute(); + + // Copy the output registers to the out ptr. + in_reg16_address = REBASE_ADDRESS(&bios32_out_reg16_ptr); + memcpy(out, in_reg16_address, sizeof(REGISTERS_16)); +} diff --git a/source/kernel/base/gdt.c b/source/kernel/base/gdt.c index f82f03c7..177133a8 100644 --- a/source/kernel/base/gdt.c +++ b/source/kernel/base/gdt.c @@ -1,56 +1,56 @@ -// ================================================== -// gdt.c - Global Descriptor Table initializer -// ================================================== -// This file is a part of the reduceOS C kernel. Please credit me if you use this code. - -/* Developer note: When reduceOS switched to multiboot, I totally forgot about this file. I'm not sure if this is why paging is failing, but it would be pretty funny if so. */ - -#include "include/gdt.h" // Main header file - -// Variable definitions -gdtEntry_t gdtEntries[MAX_DESCRIPTORS]; -gdtPtr_t gdtPtr; - -extern void tssFlush(); - -// Functions - -// gdtSetGate(int32_t num, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran) - Set the value of 1 GDT entry. -void gdtSetGate(int32_t num, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran) { - // Sanity check first! - ASSERT(num < MAX_DESCRIPTORS, "gdtSetGate()", "invalid descriptor number"); - - // Now set the proper values in the gdt entries. - gdtEntries[num].baseLow = (base & 0xFFFF); - gdtEntries[num].baseMiddle = (base >> 16) & 0xFF; - gdtEntries[num].baseHigh = (base >> 24) & 0xFF; - - gdtEntries[num].limitLow = (limit & 0xFFFF); - gdtEntries[num].granularity = (limit >> 16) & 0x0F; - - gdtEntries[num].granularity |= gran & 0xF0; - gdtEntries[num].access = access; -} - - -// gdtInit() - Initializes GDT and sets up all the pointers -void gdtInit() { - // Setup the gdtPtr to point to our gdtEntires - gdtPtr.limit = sizeof(gdtEntries)-1; - gdtPtr.base = (uint32_t)&gdtEntries; - - // Now setup the GDT entries - gdtSetGate(0, 0, 0, 0, 0); // Null segment - gdtSetGate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); // Code segment - gdtSetGate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); // Data segment - gdtSetGate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); // User mode code segment - gdtSetGate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); // User mode data segment. - tssWrite(5, 0x10, 0x0); // Task state segment - - // Install the GDT. - install_gdt((uint32_t)&gdtPtr); - - // Flush TSS. - tssFlush(); - -} +// ================================================== +// gdt.c - Global Descriptor Table initializer +// ================================================== +// This file is a part of the reduceOS C kernel. Please credit me if you use this code. + +/* Developer note: When reduceOS switched to multiboot, I totally forgot about this file. I'm not sure if this is why paging is failing, but it would be pretty funny if so. */ + +#include // Main header file + +// Variable definitions +gdtEntry_t gdtEntries[MAX_DESCRIPTORS]; +gdtPtr_t gdtPtr; + +extern void tssFlush(); + +// Functions + +// gdtSetGate(int32_t num, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran) - Set the value of 1 GDT entry. +void gdtSetGate(int32_t num, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran) { + // Sanity check first! + ASSERT(num < MAX_DESCRIPTORS, "gdtSetGate()", "invalid descriptor number"); + + // Now set the proper values in the gdt entries. + gdtEntries[num].baseLow = (base & 0xFFFF); + gdtEntries[num].baseMiddle = (base >> 16) & 0xFF; + gdtEntries[num].baseHigh = (base >> 24) & 0xFF; + + gdtEntries[num].limitLow = (limit & 0xFFFF); + gdtEntries[num].granularity = (limit >> 16) & 0x0F; + + gdtEntries[num].granularity |= gran & 0xF0; + gdtEntries[num].access = access; +} + + +// gdtInit() - Initializes GDT and sets up all the pointers +void gdtInit() { + // Setup the gdtPtr to point to our gdtEntires + gdtPtr.limit = sizeof(gdtEntries)-1; + gdtPtr.base = (uint32_t)&gdtEntries; + + // Now setup the GDT entries + gdtSetGate(0, 0, 0, 0, 0); // Null segment + gdtSetGate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); // Code segment + gdtSetGate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); // Data segment + gdtSetGate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); // User mode code segment + gdtSetGate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); // User mode data segment. + tssWrite(5, 0x10, 0x0); // Task state segment + + // Install the GDT. + install_gdt((uint32_t)&gdtPtr); + + // Flush TSS. + tssFlush(); + +} diff --git a/source/kernel/base/hal.c b/source/kernel/base/hal.c index 33c9748e..9cae1136 100644 --- a/source/kernel/base/hal.c +++ b/source/kernel/base/hal.c @@ -1,98 +1,98 @@ -// ===================================================================== -// hal.c - Hardware Abstraction Layer -// This file handles functions of the Hardware Abstraction Layer (HAL) -// ===================================================================== - -#include "include/hal.h" // Main header file - - -// Functions - -// void interruptCompleted(uint32_t intNo) - Notifies HAL interrupt is done. -void interruptCompleted(uint32_t intNo) { - // Do we need to send EOI to second PIC? - if (intNo >= 40) outportb(0xA0, 0x20); - - // Send EOI to master - outportb(0x20, 0x20); - -} - - -// void setVector(int intNo, uint32_t vect) - Sets a new interrupt vector. -void setVector(int intNo, uint32_t vect) { - idtInstallIR(intNo, 0x8E, 0x08, (uint32_t)vect); -} - -// void setVector_flags(int intNo, uint32_t vect, int flags) - Sets a new interrupt vector using flags. -void setVector_flags(int intNo, uint32_t vect, int flags) { - idtInstallIR(intNo, I86_IDT_DESC_PRESENT | I86_IDT_DESC_BIT32 | flags, 0x8, vect); -} - -// void enableHardwareInterrupts() - Enable hardware interrupts -void enableHardwareInterrupts() { - asm volatile ("sti"); -} - - -// void disableHardwareInterrupts() - Disable hardware interrupts -void disableHardwareInterrupts() { - asm volatile ("cli"); -} - -// uint8_t inportb(uint16_t port) - Read data from device through port mapped IO -uint8_t inportb(uint16_t port) { - uint8_t ret; - asm volatile ("inb %1, %0" : "=a"(ret) : "Nd"(port)); - return ret; -} - -// void outportb(unsigned short port, unsigned char value) - write byte to device through port mapped IO -void outportb(uint16_t port, uint8_t value) { - asm volatile("outb %1, %0" :: "dN"(port), "a"(value)); -} - -// inportw(unsigned short port) - Reads word from device -uint16_t inportw(uint16_t port) { - uint16_t ret; - asm volatile ("inw %1, %0" : "=a"(ret) : "Nd"(port)); - return ret; -} - -// outportw(unsigned short port, unsigned short data) - Writes word to device -void outportw(uint16_t port, uint16_t data) { - asm volatile ("outl %%eax, %%dx" :: "Nd"(port), "a"(data)); -} - -// void __cpuid(uint32_t type, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) - Returns an assembly cpuid instruction's results. -void __cpuid(uint32_t type, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) { - asm volatile("cpuid" - : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) - : "0"(type)); // Add type to eax -} - -// uint32_t inportl(uint16_t port) - Reads data from device via port mapped IO -uint32_t inportl(uint16_t port) { - uint32_t ret; - asm volatile ("inl %1, %0" : "=a"(ret) : "dN"(port)); - return ret; -} - -// void outportl(uint16_t port, uint8_t value) - Write byte to device via port mapped IO -void outportl(uint16_t port, uint32_t value) { - asm volatile ("outl %1, %0" :: "dN"(port), "a"(value)); -} - - -// size_t msb(size_t i) - Returns the most significant bit. -size_t msb(size_t i) -{ - size_t ret; - - if (!i) - return (sizeof(size_t)*8); - asm volatile ("bsr %1, %0" : "=r"(ret) : "r"(i) : "cc"); - - return ret; -} - +// ===================================================================== +// hal.c - Hardware Abstraction Layer +// This file handles functions of the Hardware Abstraction Layer (HAL) +// ===================================================================== + +#include // Main header file + + +// Functions + +// void interruptCompleted(uint32_t intNo) - Notifies HAL interrupt is done. +void interruptCompleted(uint32_t intNo) { + // Do we need to send EOI to second PIC? + if (intNo >= 40) outportb(0xA0, 0x20); + + // Send EOI to master + outportb(0x20, 0x20); + +} + + +// void setVector(int intNo, uint32_t vect) - Sets a new interrupt vector. +void setVector(int intNo, uint32_t vect) { + idtInstallIR(intNo, 0x8E, 0x08, (uint32_t)vect); +} + +// void setVector_flags(int intNo, uint32_t vect, int flags) - Sets a new interrupt vector using flags. +void setVector_flags(int intNo, uint32_t vect, int flags) { + idtInstallIR(intNo, I86_IDT_DESC_PRESENT | I86_IDT_DESC_BIT32 | flags, 0x8, vect); +} + +// void enableHardwareInterrupts() - Enable hardware interrupts +void enableHardwareInterrupts() { + asm volatile ("sti"); +} + + +// void disableHardwareInterrupts() - Disable hardware interrupts +void disableHardwareInterrupts() { + asm volatile ("cli"); +} + +// uint8_t inportb(uint16_t port) - Read data from device through port mapped IO +uint8_t inportb(uint16_t port) { + uint8_t ret; + asm volatile ("inb %1, %0" : "=a"(ret) : "Nd"(port)); + return ret; +} + +// void outportb(unsigned short port, unsigned char value) - write byte to device through port mapped IO +void outportb(uint16_t port, uint8_t value) { + asm volatile("outb %1, %0" :: "dN"(port), "a"(value)); +} + +// inportw(unsigned short port) - Reads word from device +uint16_t inportw(uint16_t port) { + uint16_t ret; + asm volatile ("inw %1, %0" : "=a"(ret) : "Nd"(port)); + return ret; +} + +// outportw(unsigned short port, unsigned short data) - Writes word to device +void outportw(uint16_t port, uint16_t data) { + asm volatile ("outl %%eax, %%dx" :: "Nd"(port), "a"(data)); +} + +// void __cpuid(uint32_t type, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) - Returns an assembly cpuid instruction's results. +void __cpuid(uint32_t type, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) { + asm volatile("cpuid" + : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) + : "0"(type)); // Add type to eax +} + +// uint32_t inportl(uint16_t port) - Reads data from device via port mapped IO +uint32_t inportl(uint16_t port) { + uint32_t ret; + asm volatile ("inl %1, %0" : "=a"(ret) : "dN"(port)); + return ret; +} + +// void outportl(uint16_t port, uint8_t value) - Write byte to device via port mapped IO +void outportl(uint16_t port, uint32_t value) { + asm volatile ("outl %1, %0" :: "dN"(port), "a"(value)); +} + + +// size_t msb(size_t i) - Returns the most significant bit. +size_t msb(size_t i) +{ + size_t ret; + + if (!i) + return (sizeof(size_t)*8); + asm volatile ("bsr %1, %0" : "=r"(ret) : "r"(i) : "cc"); + + return ret; +} + diff --git a/source/kernel/base/idt.c b/source/kernel/base/idt.c index 5b13f6aa..f0f6ec7d 100644 --- a/source/kernel/base/idt.c +++ b/source/kernel/base/idt.c @@ -1,33 +1,33 @@ -// ===================================================================== -// idt.c - Interrupt Descriptor Table -// This file handles setting up the Interrupt Descriptor Table (IDT) -// ===================================================================== - -#include "include/idt.h" // IDT header file - -extern void install_idt(uint32_t); - - - - -idtEntry_t idtEntries[I86_MAX_INTERRUPTS]; -idtPtr_t idtPtr; - - - - - - -int idtInstallIR(uint8_t i, uint8_t flags, uint16_t segmentSelector, uint32_t base) { - if (i < 0 || i >= I86_MAX_INTERRUPTS) return -1; // This would throw an out of bounds exception if it was. - - idtEntries[i].baseLow = base & 0xFFFF; - idtEntries[i].baseHigh = (base >> 16) & 0xFFFF; - - idtEntries[i].segmentSelector = segmentSelector; - idtEntries[i].reserved = 0; - - // NOTE: When user mode is enabled, make the below flags | 0x60. +// ===================================================================== +// idt.c - Interrupt Descriptor Table +// This file handles setting up the Interrupt Descriptor Table (IDT) +// ===================================================================== + +#include // IDT header file + +extern void install_idt(uint32_t); + + + + +idtEntry_t idtEntries[I86_MAX_INTERRUPTS]; +idtPtr_t idtPtr; + + + + + + +int idtInstallIR(uint8_t i, uint8_t flags, uint16_t segmentSelector, uint32_t base) { + if (i < 0 || i >= I86_MAX_INTERRUPTS) return -1; // This would throw an out of bounds exception if it was. + + idtEntries[i].baseLow = base & 0xFFFF; + idtEntries[i].baseHigh = (base >> 16) & 0xFFFF; + + idtEntries[i].segmentSelector = segmentSelector; + idtEntries[i].reserved = 0; + + // NOTE: When user mode is enabled, make the below flags | 0x60. idtEntries[i].flags = flags; return 0; @@ -51,8 +51,8 @@ void idtInit() { outportb(0x21, 0x04); outportb(0xA1, 0x02); outportb(0x21, 0x01); - outportb(0xA1, 0x01); - outportb(0x21, 0x0); + outportb(0xA1, 0x01); + outportb(0x21, 0x0); outportb(0xA1, 0x0); diff --git a/source/kernel/base/isr.c b/source/kernel/base/isr.c index 67bcfcf1..e2a71d61 100644 --- a/source/kernel/base/isr.c +++ b/source/kernel/base/isr.c @@ -1,106 +1,106 @@ -// ================================================== -// isr.c - Interrupt Service Routines initializer -// ================================================== - - -#include "include/isr.h" // Main header file - -ISR interruptHandlers[256]; // A list of all interrupt handlers - -#pragma GCC diagnostic ignored "-Wint-conversion" // Lots of warnings about setvector() not taking an unsigned int. Ignore them all. - - -// isrRegisterInterruptHandler(int num, ISR handler) - Registers an interrupt handler. -void isrRegisterInterruptHandler(int num, ISR handler) { - if (num < 256) { - interruptHandlers[num] = handler; - } -} - - -void isrExceptionHandler(registers_t *reg) { - if (interruptHandlers[reg->int_no] != NULL) { - ISR handler = interruptHandlers[reg->int_no]; - handler(reg); - } - - if (reg->int_no < 32) { - panicReg("i86", "ISR Exception", exception_messages[reg->int_no], reg); - } -} - -void isrIRQHandler(registers_t *reg) { - // Some debug code I left in in case anyone is modifying reduceOS. - //if (reg->int_no != 32) serialPrintf("isrIRQHandler received IRQ. IRQ: %i. Valid handler present: %s. INT NO: %i. Valid handler present (for INT_NO): %s", reg->err_code, (interruptHandlers[reg->err_code]) ? "YES" : "NO", reg->int_no, (interruptHandlers[reg->int_no]) ? "YES" : "NO"); - - if (interruptHandlers[reg->int_no] != NULL) { - // We now know there is a valid handler present. Execute it. - ISR handler = interruptHandlers[reg->int_no]; - handler(reg); - } - - // Send EOI to PIC (this function is present in hal.h) - - interruptCompleted(reg->int_no); -} - -void isrInstall() { - // First, install the proper ISR exception handlers into the system. - setVector(0, (uint32_t) isr0); - setVector(1, (uint32_t) isr1); - setVector(2, (uint32_t) isr2); - setVector(3, (uint32_t) isr3); - setVector(4, (uint32_t) isr4); - setVector(5, (uint32_t) isr5); - setVector(6, (uint32_t) isr6); - setVector(7, (uint32_t) isr7); - setVector(8, (uint32_t) isr8); - setVector(9, (uint32_t) isr9); - setVector(10, (uint32_t) isr10); - setVector(11, (uint32_t) isr11); - setVector(12, (uint32_t) isr12); - setVector(13, (uint32_t) isr13); - setVector(14, (uint32_t) isr14); - setVector(15, (uint32_t) isr15); - setVector(16, (uint32_t) isr16); - setVector(17, (uint32_t) isr17); - setVector(18, (uint32_t) isr18); - setVector(19, (uint32_t) isr19); - setVector(20, (uint32_t) isr20); - setVector(21, (uint32_t) isr21); - setVector(22, (uint32_t) isr22); - setVector(23, (uint32_t) isr23); - setVector(24, (uint32_t) isr24); - setVector(25, (uint32_t) isr25); - setVector(26, (uint32_t) isr26); - setVector(27, (uint32_t) isr27); - setVector(28, (uint32_t) isr28); - setVector(29, (uint32_t) isr29); - setVector(30, (uint32_t) isr30); - setVector(31, (uint32_t) isr31); - - // Initialize PIC - // i86_picInit(0x20, 0x28); - - // Register all IRQs - setVector(32, (uint32_t)irq_0); - setVector(33, (uint32_t)irq_1); - setVector(34, (uint32_t)irq_2); - setVector(35, (uint32_t)irq_3); - setVector(36, (uint32_t)irq_4); - setVector(37, (uint32_t)irq_5); - setVector(38, (uint32_t)irq_6); - setVector(39, (uint32_t)irq_7); - setVector(40, (uint32_t)irq_8); - setVector(41, (uint32_t)irq_9); - setVector(42, (uint32_t)irq_10); - setVector(43, (uint32_t)irq_11); - setVector(44, (uint32_t)irq_12); - setVector(45, (uint32_t)irq_13); - setVector(46, (uint32_t)irq_14); - setVector(47, (uint32_t)irq_15); - - // Register exception 128 (SYSCALLS) - //setVector(128, (uint32_t)isr128); - setVector_flags(128, (uint32_t)isr128, I86_IDT_DESC_RING3); -} \ No newline at end of file +// ================================================== +// isr.c - Interrupt Service Routines initializer +// ================================================== + + +#include // Main header file + +ISR interruptHandlers[256]; // A list of all interrupt handlers + +#pragma GCC diagnostic ignored "-Wint-conversion" // Lots of warnings about setvector() not taking an unsigned int. Ignore them all. + + +// isrRegisterInterruptHandler(int num, ISR handler) - Registers an interrupt handler. +void isrRegisterInterruptHandler(int num, ISR handler) { + if (num < 256) { + interruptHandlers[num] = handler; + } +} + + +void isrExceptionHandler(registers_t *reg) { + if (interruptHandlers[reg->int_no] != NULL) { + ISR handler = interruptHandlers[reg->int_no]; + handler(reg); + } + + if (reg->int_no < 32) { + panicReg("i86", "ISR Exception", exception_messages[reg->int_no], reg); + } +} + +void isrIRQHandler(registers_t *reg) { + // Some debug code I left in in case anyone is modifying reduceOS. + //if (reg->int_no != 32) serialPrintf("isrIRQHandler received IRQ. IRQ: %i. Valid handler present: %s. INT NO: %i. Valid handler present (for INT_NO): %s", reg->err_code, (interruptHandlers[reg->err_code]) ? "YES" : "NO", reg->int_no, (interruptHandlers[reg->int_no]) ? "YES" : "NO"); + + if (interruptHandlers[reg->int_no] != NULL) { + // We now know there is a valid handler present. Execute it. + ISR handler = interruptHandlers[reg->int_no]; + handler(reg); + } + + // Send EOI to PIC (this function is present in hal.h) + + interruptCompleted(reg->int_no); +} + +void isrInstall() { + // First, install the proper ISR exception handlers into the system. + setVector(0, (uint32_t) isr0); + setVector(1, (uint32_t) isr1); + setVector(2, (uint32_t) isr2); + setVector(3, (uint32_t) isr3); + setVector(4, (uint32_t) isr4); + setVector(5, (uint32_t) isr5); + setVector(6, (uint32_t) isr6); + setVector(7, (uint32_t) isr7); + setVector(8, (uint32_t) isr8); + setVector(9, (uint32_t) isr9); + setVector(10, (uint32_t) isr10); + setVector(11, (uint32_t) isr11); + setVector(12, (uint32_t) isr12); + setVector(13, (uint32_t) isr13); + setVector(14, (uint32_t) isr14); + setVector(15, (uint32_t) isr15); + setVector(16, (uint32_t) isr16); + setVector(17, (uint32_t) isr17); + setVector(18, (uint32_t) isr18); + setVector(19, (uint32_t) isr19); + setVector(20, (uint32_t) isr20); + setVector(21, (uint32_t) isr21); + setVector(22, (uint32_t) isr22); + setVector(23, (uint32_t) isr23); + setVector(24, (uint32_t) isr24); + setVector(25, (uint32_t) isr25); + setVector(26, (uint32_t) isr26); + setVector(27, (uint32_t) isr27); + setVector(28, (uint32_t) isr28); + setVector(29, (uint32_t) isr29); + setVector(30, (uint32_t) isr30); + setVector(31, (uint32_t) isr31); + + // Initialize PIC + // i86_picInit(0x20, 0x28); + + // Register all IRQs + setVector(32, (uint32_t)irq_0); + setVector(33, (uint32_t)irq_1); + setVector(34, (uint32_t)irq_2); + setVector(35, (uint32_t)irq_3); + setVector(36, (uint32_t)irq_4); + setVector(37, (uint32_t)irq_5); + setVector(38, (uint32_t)irq_6); + setVector(39, (uint32_t)irq_7); + setVector(40, (uint32_t)irq_8); + setVector(41, (uint32_t)irq_9); + setVector(42, (uint32_t)irq_10); + setVector(43, (uint32_t)irq_11); + setVector(44, (uint32_t)irq_12); + setVector(45, (uint32_t)irq_13); + setVector(46, (uint32_t)irq_14); + setVector(47, (uint32_t)irq_15); + + // Register exception 128 (SYSCALLS) + //setVector(128, (uint32_t)isr128); + setVector_flags(128, (uint32_t)isr128, I86_IDT_DESC_RING3); +} diff --git a/source/kernel/base/pic.c b/source/kernel/base/pic.c index 5f6580d6..81f80c2d 100644 --- a/source/kernel/base/pic.c +++ b/source/kernel/base/pic.c @@ -1,69 +1,69 @@ -// ========================================================================= -// pic.c - Programmable Interrupt Controller -// This file handles setting up the Programmable Interrupt Controller (PIC) -// ========================================================================= - - -// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -// DOES NOT WORK -// This file does not work. PIC is not initialized correctly, rendering keyboard and other things INOPERABLE. -// DO NOT USE - SEE IDT.C FOR TEMPORARY WORK AROUND -// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -#include "include/pic.h" // Main header file - - -// picSendCommand(uint8_t cmd, uint8_t picNum) - Send a command to a certain PIC -void picSendCommand(uint8_t cmd, uint8_t picNum) { - if (picNum > 1) return; // Don't bother if the picNum is greater than one (there are only two!) - - uint8_t reg = (picNum == 1) ? PIC2_REG_COMMAND : PIC1_REG_COMMAND; // Choose the right thing to send based on the picNum - outportb(reg, cmd); -} - -// picSendData(uint8_t data, uint8_t picNum) - Send data to PICs -void picSendData(uint8_t data, uint8_t picNum) { - if (picNum > 1) return; // Don't bother if the picNum is greater than one (there are only two) - - uint8_t reg = (picNum==1) ? PIC2_REG_DATA : PIC1_REG_DATA; - outportb(reg, data); -} - -// uint8_t picReadData(uint8_t picNum) - Read data from PICs -uint8_t picReadData(uint8_t picNum) { - if (picNum > 1) return; // Don't bother if the picNum is greater than one (there are only two) - - uint8_t reg = (picNum == 1) ? PIC2_REG_DATA : PIC1_REG_DATA; - return inportb(reg); -} - -// picInit(uint8_t base0, uint8_t base1) - Initialize the PIC -void picInit(uint8_t base0, uint8_t base1) { - uint8_t icw = 0; - - disableHardwareInterrupts(); // Disable hardware interrupts - - // Begin initialization of PIC - icw = (icw & ~PIC_ICW1_MASK_INIT) | PIC_ICW1_INIT_YES; - icw = (icw & ~PIC_ICW1_MASK_IC4) | PIC_ICW1_IC4_EXPECT; - - // Send commands to both PICs - picSendCommand(icw, 0); - picSendCommand(icw, 1); - - // Send initialization control word 2 (base addresses of the IRQs) - picSendData(base0, 0); - picSendData(base1, 1); - - // Send initialization control word 3 (connect between master + slave) - picSendData(0x04, 0); - picSendData(0x02, 1); - - // Send initialization control word 4 (enabled I86 mode) - - icw = (icw & ~PIC_ICW4_MASK_UPM) | PIC_ICW4_UPM_86MODE; - - picSendData(icw, 0); - picSendData(icw, 1); - printf("Programmable Interrupt Controller initialized.\n"); -} \ No newline at end of file +// ========================================================================= +// pic.c - Programmable Interrupt Controller +// This file handles setting up the Programmable Interrupt Controller (PIC) +// ========================================================================= + + +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// DOES NOT WORK +// This file does not work. PIC is not initialized correctly, rendering keyboard and other things INOPERABLE. +// DO NOT USE - SEE IDT.C FOR TEMPORARY WORK AROUND +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +#include // Main header file + + +// picSendCommand(uint8_t cmd, uint8_t picNum) - Send a command to a certain PIC +void picSendCommand(uint8_t cmd, uint8_t picNum) { + if (picNum > 1) return; // Don't bother if the picNum is greater than one (there are only two!) + + uint8_t reg = (picNum == 1) ? PIC2_REG_COMMAND : PIC1_REG_COMMAND; // Choose the right thing to send based on the picNum + outportb(reg, cmd); +} + +// picSendData(uint8_t data, uint8_t picNum) - Send data to PICs +void picSendData(uint8_t data, uint8_t picNum) { + if (picNum > 1) return; // Don't bother if the picNum is greater than one (there are only two) + + uint8_t reg = (picNum==1) ? PIC2_REG_DATA : PIC1_REG_DATA; + outportb(reg, data); +} + +// uint8_t picReadData(uint8_t picNum) - Read data from PICs +uint8_t picReadData(uint8_t picNum) { + if (picNum > 1) return; // Don't bother if the picNum is greater than one (there are only two) + + uint8_t reg = (picNum == 1) ? PIC2_REG_DATA : PIC1_REG_DATA; + return inportb(reg); +} + +// picInit(uint8_t base0, uint8_t base1) - Initialize the PIC +void picInit(uint8_t base0, uint8_t base1) { + uint8_t icw = 0; + + disableHardwareInterrupts(); // Disable hardware interrupts + + // Begin initialization of PIC + icw = (icw & ~PIC_ICW1_MASK_INIT) | PIC_ICW1_INIT_YES; + icw = (icw & ~PIC_ICW1_MASK_IC4) | PIC_ICW1_IC4_EXPECT; + + // Send commands to both PICs + picSendCommand(icw, 0); + picSendCommand(icw, 1); + + // Send initialization control word 2 (base addresses of the IRQs) + picSendData(base0, 0); + picSendData(base1, 1); + + // Send initialization control word 3 (connect between master + slave) + picSendData(0x04, 0); + picSendData(0x02, 1); + + // Send initialization control word 4 (enabled I86 mode) + + icw = (icw & ~PIC_ICW4_MASK_UPM) | PIC_ICW4_UPM_86MODE; + + picSendData(icw, 0); + picSendData(icw, 1); + printf("Programmable Interrupt Controller initialized.\n"); +} diff --git a/source/kernel/base/processor.c b/source/kernel/base/processor.c index 9afc2308..2531b358 100644 --- a/source/kernel/base/processor.c +++ b/source/kernel/base/processor.c @@ -1,170 +1,170 @@ -// ====================================================== -// processor.c - Handles all CPU related functions -// ====================================================== -// This file is a part of the reduceOS C kernel. Please credit me if you use this code. - -#include "include/processor.h" // Main header file - - -// Variables -static cpuInfo_t processor_data; - -// Functions: - - -// cpuInit() - Initializes the CPU with ISR, IDT, and GDT -void cpuInit() { - // Load GDT and IDT (IDT method sets up ISR as well as PIC) - gdtInit(); - idtInit(); - serialPrintf("GDT, IDT, and ISR have initialized successfully.\n"); - - // Enable interrupts. - enableHardwareInterrupts(); - serialPrintf("Interrupts successfully enabled.\n"); - - - // We want a fast boot so we'll only detect CPU frequency when needed. - processor_data.frequency = 0; - - // Now grab some vendor data. - uint32_t eaxvar; // Unused - memset(processor_data.vendor, 0, sizeof(processor_data.vendor)); - __cpuid(0, &eaxvar, &processor_data.vendor[0], &processor_data.vendor[8], &processor_data.vendor[4]); - - int edx = 0; - - // Also, get CPU long mode support. - asm volatile ("movl $0x80000001, %%eax\n" - "cpuid\n" : "=d"(edx) :: "eax", "ebx", "ecx"); - - - processor_data.long_mode_capable = edx & (1 << 29) ? 1 : 0; - - // SSE Support Checking - cpuCheckSSE(); - - - // Print a summary - // Now print a little summary - serialPrintf("======== CPU Data Collection Summary ========\n"); - serialPrintf("- CPU VENDOR ID: %s\n", processor_data.vendor); - serialPrintf("- Long Mode (x64) support: %i\n\n", processor_data.long_mode_capable); - - serialPrintf("== SSE Data Collection Summary ==\n"); - serialPrintf("SSE support: %s\n", processor_data.sse_support ? "YES" : "NO"); - serialPrintf("SSE2 support: %s\n", processor_data.sse2_support ? "YES" : "NO"); - serialPrintf("SSE3 support: %s\n", processor_data.sse3_support ? "YES" : "NO"); - serialPrintf("SSSE3 support: %s\n", processor_data.ssse3_support ? "YES" : "NO"); - serialPrintf("SSE4 support: %s\n", processor_data.sse4_support ? "YES" : "NO"); - serialPrintf("SSE5 support data summary:\n"); - serialPrintf("\tXOP support: %s\n", processor_data.sse5_Data.XOP_support ? "YES" : "NO"); - serialPrintf("\tFMA4 support: %s\n", processor_data.sse5_Data.FMA4_support ? "YES" : "NO"); - serialPrintf("\tCVT16 support: %s\n", processor_data.sse5_Data.CVT16_support ? "YES" : "NO"); - serialPrintf("\tAVX support: %s\n", processor_data.sse5_Data.AVX_support ? "YES" : "NO"); - serialPrintf("\tXSAVE support: %s\n", processor_data.sse5_Data.XSAVE_support ? "YES" : "NO"); - serialPrintf("\tAVX2 support: %s\n", processor_data.sse5_Data.AVX2_support ? "YES" : "NO"); - serialPrintf("== End SSE Data Collection Summary ==\n"); - serialPrintf("======== End CPU Data Collection Summary ========\n"); - - // Done! - - - printf("CPU initialization completed.\n"); - serialPrintf("CPU initialization completed\n"); - - return; - -} - - -// cpuCheckSSE() - Runs all the SSE checks and assigns correct values -void cpuCheckSSE() { - /* - In case you don't know what SSE is, it stands for Streaming SIMD Extensions - They are a special set of instructions known as single instruction, multiple data - These instructions can give a very high increase in data throughput - As well as that, they add a few XMM registers (and even some 128-bit ones!) which can load 16 bytes from memory or store 16 bytes into memory with a single instruction - */ - - uint32_t eax; // Unused - uint32_t edx; // SSE and SSE2 bits found here - uint32_t ecx; // SSE3, SSE4, and most of SSE5 are found here - uint32_t ebx; // AVX2 support checking - - __cpuid(1, &eax, &ebx, &ecx, &edx); - - processor_data.sse_support = edx & (1 << 25); // SSE support (bit 25 of EDX) - processor_data.sse2_support = edx & (1 << 26); // SSE2 support (bit 26 of EDX) - processor_data.sse3_support = ecx & (1 << 0); // SSE3 support (bit 0 of ECX) - processor_data.ssse3_support = ecx & (1 << 9); // SSSE3 support (Supplemntal Streaming SIMD Extensions, bit 9 of ECX) - - - // ok so basically I don't actually know if it changes whether SSE4.1, SSE4.2, or SSE4A is on or off - // soo only enable SSE4 support if all 3 are supported - processor_data.sse4_support = 0; - - if ((ecx & (1 << 19)) && (ecx & (1 << 20)) && (ecx & (1 << 6))) { - processor_data.sse4_support = 1; - } - - // SSE5 time, this is more complex, because it's split up - // I created a type called sseData_t to help out - - processor_data.sse5_Data.XOP_support = ecx & (1 << 11); // XOP support - processor_data.sse5_Data.FMA4_support = ecx & (1 << 16); // FMA4 support - processor_data.sse5_Data.CVT16_support = ecx & (1 << 29); // CVT16 support - processor_data.sse5_Data.AVX_support = ecx & (1 << 28); // AVX support - processor_data.sse5_Data.XSAVE_support = ecx & (1 << 26); // XSAVE support - processor_data.sse5_Data.AVX2_support = ecx & (1 << 5); // AVX2 support (potentially wrong page for CPUID?) - - // Hopefully done (praying I don't have to debug but some SSE stuff doesn't seem to work) - - - -} - - -// detectCPUFrequency() - Detect the CPU frequency (buggy and takes time) -uint32_t detectCPUFrequency() { - uint64_t start, end, diff; - uint64_t ticks, old; - - if (processor_data.frequency > 0) - return processor_data.frequency; - - old = pitGetTickCount(); - - // Wait for the next time slice. - while((ticks = pitGetTickCount()) - old == 0) continue; - - asm volatile ("rdtsc" : "=A"(start)); - // Wait a second to determine frequency. - while(pitGetTickCount() - ticks < 1000) continue; - asm volatile ("rdtsc" : "=A"(end)); - - diff = end > start ? end - start : start - end; - processor_data.frequency = (uint32_t) (diff / (uint64_t) 1000000); - - return processor_data.frequency; -} - - -// getCPUFrequency() - Returns the CPU frequency and gets it if it is not present. -uint32_t getCPUFrequency() { - if (processor_data.frequency > 0) - return processor_data.frequency; - - return detectCPUFrequency(); -} - - - -// getCPUVendorData() - Returns CPU vendor data -char *getCPUVendorData() { - return processor_data.vendor; -} - -bool isCPULongModeCapable() { - return processor_data.long_mode_capable ? true : false; -} \ No newline at end of file +// ====================================================== +// processor.c - Handles all CPU related functions +// ====================================================== +// This file is a part of the reduceOS C kernel. Please credit me if you use this code. + +#include // Main header file + + +// Variables +static cpuInfo_t processor_data; + +// Functions: + + +// cpuInit() - Initializes the CPU with ISR, IDT, and GDT +void cpuInit() { + // Load GDT and IDT (IDT method sets up ISR as well as PIC) + gdtInit(); + idtInit(); + serialPrintf("GDT, IDT, and ISR have initialized successfully.\n"); + + // Enable interrupts. + enableHardwareInterrupts(); + serialPrintf("Interrupts successfully enabled.\n"); + + + // We want a fast boot so we'll only detect CPU frequency when needed. + processor_data.frequency = 0; + + // Now grab some vendor data. + uint32_t eaxvar; // Unused + memset(processor_data.vendor, 0, sizeof(processor_data.vendor)); + __cpuid(0, &eaxvar, &processor_data.vendor[0], &processor_data.vendor[8], &processor_data.vendor[4]); + + int edx = 0; + + // Also, get CPU long mode support. + asm volatile ("movl $0x80000001, %%eax\n" + "cpuid\n" : "=d"(edx) :: "eax", "ebx", "ecx"); + + + processor_data.long_mode_capable = edx & (1 << 29) ? 1 : 0; + + // SSE Support Checking + cpuCheckSSE(); + + + // Print a summary + // Now print a little summary + serialPrintf("======== CPU Data Collection Summary ========\n"); + serialPrintf("- CPU VENDOR ID: %s\n", processor_data.vendor); + serialPrintf("- Long Mode (x64) support: %i\n\n", processor_data.long_mode_capable); + + serialPrintf("== SSE Data Collection Summary ==\n"); + serialPrintf("SSE support: %s\n", processor_data.sse_support ? "YES" : "NO"); + serialPrintf("SSE2 support: %s\n", processor_data.sse2_support ? "YES" : "NO"); + serialPrintf("SSE3 support: %s\n", processor_data.sse3_support ? "YES" : "NO"); + serialPrintf("SSSE3 support: %s\n", processor_data.ssse3_support ? "YES" : "NO"); + serialPrintf("SSE4 support: %s\n", processor_data.sse4_support ? "YES" : "NO"); + serialPrintf("SSE5 support data summary:\n"); + serialPrintf("\tXOP support: %s\n", processor_data.sse5_Data.XOP_support ? "YES" : "NO"); + serialPrintf("\tFMA4 support: %s\n", processor_data.sse5_Data.FMA4_support ? "YES" : "NO"); + serialPrintf("\tCVT16 support: %s\n", processor_data.sse5_Data.CVT16_support ? "YES" : "NO"); + serialPrintf("\tAVX support: %s\n", processor_data.sse5_Data.AVX_support ? "YES" : "NO"); + serialPrintf("\tXSAVE support: %s\n", processor_data.sse5_Data.XSAVE_support ? "YES" : "NO"); + serialPrintf("\tAVX2 support: %s\n", processor_data.sse5_Data.AVX2_support ? "YES" : "NO"); + serialPrintf("== End SSE Data Collection Summary ==\n"); + serialPrintf("======== End CPU Data Collection Summary ========\n"); + + // Done! + + + printf("CPU initialization completed.\n"); + serialPrintf("CPU initialization completed\n"); + + return; + +} + + +// cpuCheckSSE() - Runs all the SSE checks and assigns correct values +void cpuCheckSSE() { + /* + In case you don't know what SSE is, it stands for Streaming SIMD Extensions + They are a special set of instructions known as single instruction, multiple data + These instructions can give a very high increase in data throughput + As well as that, they add a few XMM registers (and even some 128-bit ones!) which can load 16 bytes from memory or store 16 bytes into memory with a single instruction + */ + + uint32_t eax; // Unused + uint32_t edx; // SSE and SSE2 bits found here + uint32_t ecx; // SSE3, SSE4, and most of SSE5 are found here + uint32_t ebx; // AVX2 support checking + + __cpuid(1, &eax, &ebx, &ecx, &edx); + + processor_data.sse_support = edx & (1 << 25); // SSE support (bit 25 of EDX) + processor_data.sse2_support = edx & (1 << 26); // SSE2 support (bit 26 of EDX) + processor_data.sse3_support = ecx & (1 << 0); // SSE3 support (bit 0 of ECX) + processor_data.ssse3_support = ecx & (1 << 9); // SSSE3 support (Supplemntal Streaming SIMD Extensions, bit 9 of ECX) + + + // ok so basically I don't actually know if it changes whether SSE4.1, SSE4.2, or SSE4A is on or off + // soo only enable SSE4 support if all 3 are supported + processor_data.sse4_support = 0; + + if ((ecx & (1 << 19)) && (ecx & (1 << 20)) && (ecx & (1 << 6))) { + processor_data.sse4_support = 1; + } + + // SSE5 time, this is more complex, because it's split up + // I created a type called sseData_t to help out + + processor_data.sse5_Data.XOP_support = ecx & (1 << 11); // XOP support + processor_data.sse5_Data.FMA4_support = ecx & (1 << 16); // FMA4 support + processor_data.sse5_Data.CVT16_support = ecx & (1 << 29); // CVT16 support + processor_data.sse5_Data.AVX_support = ecx & (1 << 28); // AVX support + processor_data.sse5_Data.XSAVE_support = ecx & (1 << 26); // XSAVE support + processor_data.sse5_Data.AVX2_support = ecx & (1 << 5); // AVX2 support (potentially wrong page for CPUID?) + + // Hopefully done (praying I don't have to debug but some SSE stuff doesn't seem to work) + + + +} + + +// detectCPUFrequency() - Detect the CPU frequency (buggy and takes time) +uint32_t detectCPUFrequency() { + uint64_t start, end, diff; + uint64_t ticks, old; + + if (processor_data.frequency > 0) + return processor_data.frequency; + + old = pitGetTickCount(); + + // Wait for the next time slice. + while((ticks = pitGetTickCount()) - old == 0) continue; + + asm volatile ("rdtsc" : "=A"(start)); + // Wait a second to determine frequency. + while(pitGetTickCount() - ticks < 1000) continue; + asm volatile ("rdtsc" : "=A"(end)); + + diff = end > start ? end - start : start - end; + processor_data.frequency = (uint32_t) (diff / (uint64_t) 1000000); + + return processor_data.frequency; +} + + +// getCPUFrequency() - Returns the CPU frequency and gets it if it is not present. +uint32_t getCPUFrequency() { + if (processor_data.frequency > 0) + return processor_data.frequency; + + return detectCPUFrequency(); +} + + + +// getCPUVendorData() - Returns CPU vendor data +char *getCPUVendorData() { + return processor_data.vendor; +} + +bool isCPULongModeCapable() { + return processor_data.long_mode_capable ? true : false; +} diff --git a/source/kernel/drivers/acpi.c b/source/kernel/drivers/acpi.c index 9e9f9acf..b558062d 100644 --- a/source/kernel/drivers/acpi.c +++ b/source/kernel/drivers/acpi.c @@ -1,241 +1,241 @@ -// ===================================================================== -// acpi.c - handles the Advanced Configuration Power Interface -// ===================================================================== -// This file is a part of the reduceOS C kernel. Please credit me if you use this code. - -#include "include/acpi.h" // Main header file - -// Variables -int ACPI_cpuCount = 0; -uint8_t ACPI_cpuIDs[16]; -ACPI_MADT *madt; - - -// Functions - -// (static) acpiRSDPChecksum(uint8_t *ptr) - Validate the RSDP checksum. -static bool acpiRSDPChecksum(uint8_t *ptr) { - uint8_t sum = 0; - for (uint32_t i = 0; i < 20; i++) { - sum += ptr[i]; - } - - if (sum) return false; - return true; -} - -// acpiParseFacp(ACPI_FADT *facp) - Parse the FACP (Fixed ACPI Description Table, its signature is FACP) -void acpiParseFacp(ACPI_FADT *facp) { - if (facp->SMI_CommandPort != 0) { - // Enable ACPI. - // outportb(facp->SMI_CommandPort, facp->AcpiEnable); - serialPrintf("acpiParseFacp: ACPI enabled succesfully.\n"); - } else { - serialPrintf("acpiParseFacp: Cannot enable ACPI, already enabled.\n"); - } - return; -} - -// acpiParseApic(ACPI_MADT *table) - Parse an APIC table for the RSDT. -void acpiParseApic(ACPI_MADT *table) { - madt = table; - - // Set up the local APIC address - serialPrintf("acpiParseApic: local APIC address is 0x%x\n", &madt->localAPIC_addr); - localAPICAddress = (uint8_t*)(void*)&madt->localAPIC_addr; - - - // Iterate through each APIC header, checking its type. - uint8_t *ptr = (uint8_t*)(madt + 1); - uint8_t *endAddr = (uint8_t *)madt + table->header.length; - while (ptr < endAddr) { - APICHeader *header = (APICHeader*)ptr; - uint8_t headerLength = header->length; - - if ((uint8_t)header->type == APIC_TYPE_LOCAL_APIC) { - APICLocal *local = (APICLocal*)ptr; - - serialPrintf("Found CPU: %d %d %x\n", local->ACPIProcessorID, local->apicID, local->flags); - if (ACPI_cpuCount < 16) { - ACPI_cpuIDs[ACPI_cpuCount] = local->apicID; - ACPI_cpuCount++; - } - } else if ((uint8_t)header->type == APIC_TYPE_IO_APIC) { - APICIO *io = (APICIO*)ptr; - serialPrintf("Found I/O APIC: %d 0x%x %d\n", io->ioAPIC_id, &io->ioAPIC_addr, io->globalSystemInterruptBase); - - ioAPIC_addr = (uint8_t*)&io->ioAPIC_addr; - } else if ((uint8_t)header->type == APIC_TYPE_INT_OVERRIDE) { - APICInterruptOverride *into = (APICInterruptOverride*)ptr; - serialPrintf("Found interrupt override: %d %d %d 0x%x\n", into->bus, into->source, into->interrupt, into->flags); - } else { - serialPrintf("Found unknown APIC structure type %d\n", (uint8_t)header->type); - } - ptr += headerLength; - } -} - - -// acpiParseRSDT(ACPIHeader *rsdt) - Parses the RSDT (Root System Description Table) -void acpiParseRSDT(ACPIHeader *rsdt) { - // Iterate through all tables and parse each one. - uint32_t *tablePtr = (uint32_t *)(rsdt + 1); - uint32_t *endAddr = (uint32_t*)((uint8_t*)rsdt + rsdt->length); - - - serialPrintf("ACPI table signatures (RSDT):\n"); - - while (tablePtr < endAddr) { - uint32_t address = *tablePtr++; - ACPIHeader *table = (ACPIHeader*)(uint64_t)address; - - // Parse the table signature first (like in acpiInit do our trick where we convert to uint32 and check against hex instead of calling strcmp). - uint32_t signature = (uint32_t)table->signature; - - // Get the string of the signature. - char signature_str[4]; - memcpy(signature_str, table->signature, 4); - signature_str[4] = '\0'; - serialPrintf("\t%s 0x%x\n", signature_str, signature); - - - // Check signature - can either be FACP or APIC. - if (!strncmp(signature_str, "FACP", 4)) { - acpiParseFacp((ACPI_FADT*)table); - } else if (!strncmp(signature_str, "APIC", 4)) { - acpiParseApic((ACPI_MADT*)table); - } - - - } -} - -// acpiParseXSDT(ACPIHeader *xsdt) - Parses the XSDT (eXtended System Description Table) -void acpiParseXSDT(ACPIHeader *xsdt) { - // It's close to the same thing as the RSDT but we use long values instead. - - uint64_t *tablePtr = (uint64_t*)(xsdt+1); - uint64_t *endAddr = (uint64_t*)((uint8_t*)xsdt + xsdt->length); - - serialPrintf("ACPI table signatures (XSDT):"); - while (tablePtr < endAddr) { - uint64_t address = *tablePtr++; - ACPIHeader *table = (ACPIHeader*)(uint64_t)address; - - // Parse the table signature first (like in acpiInit do our trick where we convert to uint32 and check against hex instead of calling strcmp). - uint32_t signature = (uint32_t)table->signature; - - // Get the string of the signature. - char signature_str[4]; - memcpy(signature_str, table->signature, 4); - signature_str[4] = '\0'; - serialPrintf("\t%s 0x%x\n", signature_str, signature); - - // Check signature - can either be FACP or APIC. - if (signature == 0x50434146) { - acpiParseFacp((ACPI_FADT*)table); - } else if (signature == 0x43495041) { - acpiParseApic((ACPI_MADT*)table); - } - - - } -} - - -// acpiParseRSDP(uint8_t *ptr) - Parses the RSDP (Root System Description Pointer) -bool acpiParseRSDP(uint8_t *ptr) { - // Validate the checksum first. - if (!acpiRSDPChecksum(ptr)) { - serialPrintf("acpiParseRSDP: checksum validation failed\n"); - return false; - } - - - - // Check the version and parse accordingly. - // We either need to parse the RSDT or XSDT (either standing for Root System Description Table or eXtended System Description Table) - // Note: Convert to v1 header here because v2 is just an extension, so if header revision is 2 then just reconvert to RSDP v2. - - RSDPDescriptor *header = (RSDPDescriptor*)ptr; - - - // OEMID is bugged (properly because it's not null terminated?) so we just copy the OEM to a char - char oem[7]; - memcpy(oem, header->OEMID, 6); - oem[6] = '\0'; - serialPrintf("acpiParseRSDP: (dbg) OEM is %s\n", oem); - - - - if (header->revision == 0) { - // (for debugging purposes) - serialPrintf("acpiParseRSDP: found ACPI version 1.0, parsing RSDT...\n"); - - uint32_t addr = *(uint32_t*)(ptr + 16); - - - vmm_allocateRegion(addr, addr, (uint32_t)(addr + (sizeof(char)*4))); - - ACPIHeader *rsdt = (ACPIHeader*)addr; - - acpiParseRSDT(rsdt); - } else if (header->revision == 2) { - // (for debugging purposes) - serialPrintf("acpiParseRSDP: found ACPI version 2.0, parsing XSDT...\n"); - - // Get RSDT and XSDT address for one final check. - uint32_t rsdtAddress = *(uint32_t*)(ptr + 16); - uint64_t xsdtAddress = *(uint64_t*)(ptr + 24); - - vmm_allocateRegion(rsdtAddress, rsdtAddress, (uint32_t)(rsdtAddress + (sizeof(char) * 4))); - vmm_allocateRegion(xsdtAddress, xsdtAddress, (uint32_t)(xsdtAddress + (sizeof(char) * 4))); - - if (xsdtAddress) { - // Parse the XSDT. - acpiParseXSDT((ACPIHeader*)(uint64_t)xsdtAddress); - } else { - // Parse the RSDT - acpiParseRSDT((ACPIHeader*)(uint64_t)rsdtAddress); - } - } else { - serialPrintf("apciParseRSDP: Unsupported ACPI version %d.\n", header->revision); - } - - return true; - -} - - -// acpiInit() - Initializes ACPI -void acpiInit() { - // We need to search the BIOS area for the RSDP (root system description pointer) - uint8_t *i = (uint8_t*)0x000E0000; - uint8_t *endArea = (uint8_t *)0x000FFFFF; - - bool foundRSDP = false; - - while (i < endArea) { - // Find the signature of whatever BIOS area we are in. - // The signature is actually characters that say 'RSD PTR ' (not null terminated). - // For now, to make things easier, we'll coonvert it to 0x2052545020445352 (the same string in unsigned long form.) - - uint64_t signature = *(uint64_t*)i; - if (signature == 0x2052545020445352) { - serialPrintf("acpiInit: Found RSDP signature at 0x%x\n", i); - // We (might've) found the RSDP. Parse it. - foundRSDP = true; - if (acpiParseRSDP(i)) { - serialPrintf("acpiInit: Successfully enabled ACPI.\n"); - printf("ACPI enabled successfully.\n"); - break; - } - foundRSDP = false; - } - - // We didn't find it, continue searching. - i += 16; - } - - // TODO: Implement AML checking -} \ No newline at end of file +// ===================================================================== +// acpi.c - handles the Advanced Configuration Power Interface +// ===================================================================== +// This file is a part of the reduceOS C kernel. Please credit me if you use this code. + +#include // Main header file + +// Variables +int ACPI_cpuCount = 0; +uint8_t ACPI_cpuIDs[16]; +ACPI_MADT *madt; + + +// Functions + +// (static) acpiRSDPChecksum(uint8_t *ptr) - Validate the RSDP checksum. +static bool acpiRSDPChecksum(uint8_t *ptr) { + uint8_t sum = 0; + for (uint32_t i = 0; i < 20; i++) { + sum += ptr[i]; + } + + if (sum) return false; + return true; +} + +// acpiParseFacp(ACPI_FADT *facp) - Parse the FACP (Fixed ACPI Description Table, its signature is FACP) +void acpiParseFacp(ACPI_FADT *facp) { + if (facp->SMI_CommandPort != 0) { + // Enable ACPI. + // outportb(facp->SMI_CommandPort, facp->AcpiEnable); + serialPrintf("acpiParseFacp: ACPI enabled succesfully.\n"); + } else { + serialPrintf("acpiParseFacp: Cannot enable ACPI, already enabled.\n"); + } + return; +} + +// acpiParseApic(ACPI_MADT *table) - Parse an APIC table for the RSDT. +void acpiParseApic(ACPI_MADT *table) { + madt = table; + + // Set up the local APIC address + serialPrintf("acpiParseApic: local APIC address is 0x%x\n", &madt->localAPIC_addr); + localAPICAddress = (uint8_t*)(void*)&madt->localAPIC_addr; + + + // Iterate through each APIC header, checking its type. + uint8_t *ptr = (uint8_t*)(madt + 1); + uint8_t *endAddr = (uint8_t *)madt + table->header.length; + while (ptr < endAddr) { + APICHeader *header = (APICHeader*)ptr; + uint8_t headerLength = header->length; + + if ((uint8_t)header->type == APIC_TYPE_LOCAL_APIC) { + APICLocal *local = (APICLocal*)ptr; + + serialPrintf("Found CPU: %d %d %x\n", local->ACPIProcessorID, local->apicID, local->flags); + if (ACPI_cpuCount < 16) { + ACPI_cpuIDs[ACPI_cpuCount] = local->apicID; + ACPI_cpuCount++; + } + } else if ((uint8_t)header->type == APIC_TYPE_IO_APIC) { + APICIO *io = (APICIO*)ptr; + serialPrintf("Found I/O APIC: %d 0x%x %d\n", io->ioAPIC_id, &io->ioAPIC_addr, io->globalSystemInterruptBase); + + ioAPIC_addr = (uint8_t*)&io->ioAPIC_addr; + } else if ((uint8_t)header->type == APIC_TYPE_INT_OVERRIDE) { + APICInterruptOverride *into = (APICInterruptOverride*)ptr; + serialPrintf("Found interrupt override: %d %d %d 0x%x\n", into->bus, into->source, into->interrupt, into->flags); + } else { + serialPrintf("Found unknown APIC structure type %d\n", (uint8_t)header->type); + } + ptr += headerLength; + } +} + + +// acpiParseRSDT(ACPIHeader *rsdt) - Parses the RSDT (Root System Description Table) +void acpiParseRSDT(ACPIHeader *rsdt) { + // Iterate through all tables and parse each one. + uint32_t *tablePtr = (uint32_t *)(rsdt + 1); + uint32_t *endAddr = (uint32_t*)((uint8_t*)rsdt + rsdt->length); + + + serialPrintf("ACPI table signatures (RSDT):\n"); + + while (tablePtr < endAddr) { + uint32_t address = *tablePtr++; + ACPIHeader *table = (ACPIHeader*)(uint64_t)address; + + // Parse the table signature first (like in acpiInit do our trick where we convert to uint32 and check against hex instead of calling strcmp). + uint32_t signature = (uint32_t)table->signature; + + // Get the string of the signature. + char signature_str[4]; + memcpy(signature_str, table->signature, 4); + signature_str[4] = '\0'; + serialPrintf("\t%s 0x%x\n", signature_str, signature); + + + // Check signature - can either be FACP or APIC. + if (!strncmp(signature_str, "FACP", 4)) { + acpiParseFacp((ACPI_FADT*)table); + } else if (!strncmp(signature_str, "APIC", 4)) { + acpiParseApic((ACPI_MADT*)table); + } + + + } +} + +// acpiParseXSDT(ACPIHeader *xsdt) - Parses the XSDT (eXtended System Description Table) +void acpiParseXSDT(ACPIHeader *xsdt) { + // It's close to the same thing as the RSDT but we use long values instead. + + uint64_t *tablePtr = (uint64_t*)(xsdt+1); + uint64_t *endAddr = (uint64_t*)((uint8_t*)xsdt + xsdt->length); + + serialPrintf("ACPI table signatures (XSDT):"); + while (tablePtr < endAddr) { + uint64_t address = *tablePtr++; + ACPIHeader *table = (ACPIHeader*)(uint64_t)address; + + // Parse the table signature first (like in acpiInit do our trick where we convert to uint32 and check against hex instead of calling strcmp). + uint32_t signature = (uint32_t)table->signature; + + // Get the string of the signature. + char signature_str[4]; + memcpy(signature_str, table->signature, 4); + signature_str[4] = '\0'; + serialPrintf("\t%s 0x%x\n", signature_str, signature); + + // Check signature - can either be FACP or APIC. + if (signature == 0x50434146) { + acpiParseFacp((ACPI_FADT*)table); + } else if (signature == 0x43495041) { + acpiParseApic((ACPI_MADT*)table); + } + + + } +} + + +// acpiParseRSDP(uint8_t *ptr) - Parses the RSDP (Root System Description Pointer) +bool acpiParseRSDP(uint8_t *ptr) { + // Validate the checksum first. + if (!acpiRSDPChecksum(ptr)) { + serialPrintf("acpiParseRSDP: checksum validation failed\n"); + return false; + } + + + + // Check the version and parse accordingly. + // We either need to parse the RSDT or XSDT (either standing for Root System Description Table or eXtended System Description Table) + // Note: Convert to v1 header here because v2 is just an extension, so if header revision is 2 then just reconvert to RSDP v2. + + RSDPDescriptor *header = (RSDPDescriptor*)ptr; + + + // OEMID is bugged (properly because it's not null terminated?) so we just copy the OEM to a char + char oem[7]; + memcpy(oem, header->OEMID, 6); + oem[6] = '\0'; + serialPrintf("acpiParseRSDP: (dbg) OEM is %s\n", oem); + + + + if (header->revision == 0) { + // (for debugging purposes) + serialPrintf("acpiParseRSDP: found ACPI version 1.0, parsing RSDT...\n"); + + uint32_t addr = *(uint32_t*)(ptr + 16); + + + vmm_allocateRegion(addr, addr, (uint32_t)(addr + (sizeof(char)*4))); + + ACPIHeader *rsdt = (ACPIHeader*)addr; + + acpiParseRSDT(rsdt); + } else if (header->revision == 2) { + // (for debugging purposes) + serialPrintf("acpiParseRSDP: found ACPI version 2.0, parsing XSDT...\n"); + + // Get RSDT and XSDT address for one final check. + uint32_t rsdtAddress = *(uint32_t*)(ptr + 16); + uint64_t xsdtAddress = *(uint64_t*)(ptr + 24); + + vmm_allocateRegion(rsdtAddress, rsdtAddress, (uint32_t)(rsdtAddress + (sizeof(char) * 4))); + vmm_allocateRegion(xsdtAddress, xsdtAddress, (uint32_t)(xsdtAddress + (sizeof(char) * 4))); + + if (xsdtAddress) { + // Parse the XSDT. + acpiParseXSDT((ACPIHeader*)(uint64_t)xsdtAddress); + } else { + // Parse the RSDT + acpiParseRSDT((ACPIHeader*)(uint64_t)rsdtAddress); + } + } else { + serialPrintf("apciParseRSDP: Unsupported ACPI version %d.\n", header->revision); + } + + return true; + +} + + +// acpiInit() - Initializes ACPI +void acpiInit() { + // We need to search the BIOS area for the RSDP (root system description pointer) + uint8_t *i = (uint8_t*)0x000E0000; + uint8_t *endArea = (uint8_t *)0x000FFFFF; + + bool foundRSDP = false; + + while (i < endArea) { + // Find the signature of whatever BIOS area we are in. + // The signature is actually characters that say 'RSD PTR ' (not null terminated). + // For now, to make things easier, we'll coonvert it to 0x2052545020445352 (the same string in unsigned long form.) + + uint64_t signature = *(uint64_t*)i; + if (signature == 0x2052545020445352) { + serialPrintf("acpiInit: Found RSDP signature at 0x%x\n", i); + // We (might've) found the RSDP. Parse it. + foundRSDP = true; + if (acpiParseRSDP(i)) { + serialPrintf("acpiInit: Successfully enabled ACPI.\n"); + printf("ACPI enabled successfully.\n"); + break; + } + foundRSDP = false; + } + + // We didn't find it, continue searching. + i += 16; + } + + // TODO: Implement AML checking +} diff --git a/source/kernel/drivers/floppy.c b/source/kernel/drivers/floppy.c index 875e2f1d..0d9c362b 100644 --- a/source/kernel/drivers/floppy.c +++ b/source/kernel/drivers/floppy.c @@ -3,7 +3,7 @@ // ========================================================= // This file is part of the reduceOS C kernel. Please credit me if you use this code. -#include "include/floppy.h" // Main header file +#include // Main header file // Variables static int floppyIRQ_fired = 0; @@ -537,4 +537,4 @@ void floppy_init() { // Set the drive information floppy_driveData(13, 1, 0xF, true); -} \ No newline at end of file +} diff --git a/source/kernel/drivers/ide_ata.c b/source/kernel/drivers/ide_ata.c index 4ae14ad8..bfa3af78 100644 --- a/source/kernel/drivers/ide_ata.c +++ b/source/kernel/drivers/ide_ata.c @@ -1,722 +1,722 @@ -// ========================================================= -// ide_ata.c - reduceOS IDE + ATA driver -// ========================================================= -// This file is a part of the reduceOS C kernel. Please credit me if you use this code. - -#include "include/ide_ata.h" // Main header file - -// What is IDE? -// According to the OSDev wiki, IDE is a keyword which refers to the electrical specification of the cables which connect ATA drives (like hard drives) to another device. The drives use the ATA (Advanced Technology Attachment) interface. An IDE cable also can terminate at an IDE card connected to PCI. -// ATAPI is an extension to ATA (recently renamed to PATA), adding support for the SCSI command set. -// More sources: https://wiki.osdev.org/PCI_IDE_Controller - - -// Variables -ideChannelRegisters_t channels[2]; // Primary and secondary channels -uint8_t ideBuffer[2048] = {0}; // Buffer to read the identification space into (see ide_ata.h). -volatile unsigned static char ideIRQ = 0; // Set to 1 when an IRQ is received. -static uint8_t atapiPacket[12] = {0xA8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // ATAPI drives -ideDevice_t ideDevices[4]; // Maximum devices supported is 4. - - - -// Function prototypes -uint8_t ideRead(uint8_t channel, uint8_t reg); // Reads in a register -void ideWrite(uint8_t channel, uint8_t reg, uint8_t data); // Writes to a register -void ideReadBuffer(uint8_t channel, uint8_t reg, uint32_t *buffer, uint32_t quads); // Reads the identification space and copies it to a buffer. -void insl(uint16_t reg, uint32_t *buffer, int quads); // Reads a long word from a register port for quads times. -void outsl(uint16_t reg, uint32_t *buffer, int quads); // Writes a long word to a register port for quads times -uint8_t idePolling(uint8_t channel, uint32_t advancedCheck); // Returns whether there was an error. -uint8_t idePrintErrors(uint32_t drive, uint8_t err); // Prints the errors that may have occurred. - -void ideWaitIRQ() { - while (!ideIRQ); - ideIRQ = 0; -} - -void ideIRQHandler() { - ideIRQ = 1; -} - - -void ideInit(uint32_t bar0, uint32_t bar1, uint32_t bar2, uint32_t bar3, uint32_t bar4) { - // Parameters: - // bar0 is the start of the IO ports used by the primary ATA channel - // bar1 is the start of the IO ports that control the primary ATA channel - // bar2 is the start of the IO ports used by the secondary ATA channel - // bar3 is the start of the IO ports that control the secondary ATA channel - // bar4 is the start of 8 IO ports that control the primary channel's bus master IDE. - // bar4 + 8 is the start of the 8 IO ports that control the secondary channel's bus master IDE. - - int count = 0; - - - // First, detect IO ports which interface the IDE controller. - channels[ATA_PRIMARY].ioBase = (bar0 & 0xFFFFFFFC) + 0x1F0 * (!bar0); // 0x1F0 is the default IO base - channels[ATA_PRIMARY].controlBase = (bar1 & 0xFFFFFFFC) + 0x3F6 * (!bar1); // 0x3F6 is the default control base - channels[ATA_SECONDARY].ioBase = (bar2 & 0xFFFFFFFC) + 0x170 * (!bar2); - channels[ATA_SECONDARY].controlBase = (bar3 & 0xFFFFFFFC) + 0x376 * (!bar3); - channels[ATA_PRIMARY].busMasterIDE = (bar4 & 0xFFFFFFFC) + 0; // Bus master IDE - channels[ATA_SECONDARY].busMasterIDE = (bar4 & 0xFFFFFFFC) + 8; - - // Next, disable IRQs in both channels (via setting bit 1 in the control port) - ideWrite(ATA_PRIMARY, ATA_REG_CONTROL, 2); - ideWrite(ATA_SECONDARY, ATA_REG_CONTROL, 2); - - // Now, detect ATA/ATAPI drives. - for (int i = 0; i < 2; i++) { - for (int j = 0; j < 2; j++) { - uint8_t err = 0, type = IDE_ATA, status; - ideDevices[count].reserved = 0; // Assuming there is no drive. - - // Step 1 - select the drive. - ideWrite(i, ATA_REG_HDDEVSEL, 0xA0 | (j << 4)); // Select the drive - sleep(1); // Wait 1 ms for drive select to wokr. - - // Next, send the ATA identify command - ideWrite(i, ATA_REG_COMMAND, ATA_IDENTIFY); - sleep(1); // Wait 1 ms for identify to work. - - // Now, poll. - if (ideRead(i, ATA_REG_STATUS) == 0) continue; // If status is 0, no device. - - while (1) { - status = ideRead(i, ATA_REG_STATUS); - if (status & ATA_STATUS_ERR) { err = 1; break; } // If err, device is not ATA. - if (!(status & ATA_STATUS_BSY) && (status & ATA_STATUS_DRQ)) break; // Everything is right. - } - - // Next, probe for ATAPI devices - if (err != 0) { - uint8_t cl = ideRead(i, ATA_REG_LBA1); - uint8_t ch = ideRead(i, ATA_REG_LBA2); - - if (cl == 0x14 && ch == 0xEB) { - type = IDE_ATAPI; - } else if (cl == 0x69 && ch == 0x96) { - type = IDE_ATAPI; - } else { - continue; // Unknown type. - } - - ideWrite(i, ATA_REG_COMMAND, ATA_IDENTIFY_PACKET); - sleep(1); - } - - // Read the identification space of the device. - ideReadBuffer(i, ATA_REG_DATA, (uint32_t*)ideBuffer, 128); - - // Next, read the device parameters. - ideDevices[count].reserved = 1; - ideDevices[count].type = type; - ideDevices[count].channel = i; - ideDevices[count].drive = j; - ideDevices[count].signature = *((uint16_t*)(ideBuffer + ATA_IDENT_DEVICETYPE)); - ideDevices[count].features = *((uint16_t*)(ideBuffer + ATA_IDENT_CAPABILITIES)); - ideDevices[count].commandSets = *((uint32_t *)(ideBuffer + ATA_IDENT_COMMANDSETS)); - - // Now, get the device size. - if (ideDevices[count].commandSets & (1 << 26)) { - // Device uses 48-bit addressing. - ideDevices[count].size = *((uint32_t*)(ideBuffer + ATA_IDENT_MAX_LBA_EXT)); - } else { - // Device uses CHS or 28-bit addressing - ideDevices[count].size = *((uint32_t*)(ideBuffer + ATA_IDENT_MAX_LBA)); - } - - // Finally (for this function), get the model string. - for (int k = 0; k < 40; k += 2) { - ideDevices[count].model[k] = ideBuffer[ATA_IDENT_MODEL + k + 1]; - ideDevices[count].model[k + 1] = ideBuffer[ATA_IDENT_MODEL + k]; - } - - ideDevices[count].model[40] = '\0'; // Zero terminate the string. - - count++; - } - } - - // Finally (for all of the driver), print a summary of the ATA devices - int drives = 0; - serialPrintf("IDE driver completed initialization.\n"); - for (int i = 0; i < 4; i++) { - if (ideDevices[i].reserved == 1) { - serialPrintf("Found %s drive - %s\n", (ideDevices[i].type == 0) ? "ATA" : "ATAPI", ideDevices[i].model); - // Quick maths to find out the drive capacity. - int capacityGB = ideDevices[i].size / 1024 / 1024; - int capacityMB = ideDevices[i].size / 1024 - (capacityGB * 1024); - int capacityKB = ideDevices[i].size - (capacityMB * 1024); - serialPrintf("\tCapacity: %i GB %i MB %i KB\n", capacityGB, capacityMB, capacityKB); - drives++; - } - } - - isrRegisterInterruptHandler(15, ideIRQHandler); - - - - printf("IDE driver initialized - found %i drives.\n", drives); - - - -} - - -// ideGetVFSNode(int driveNum) - Returns VFS node for an IDE drive -fsNode_t *ideGetVFSNode(int driveNum) { - fsNode_t *ret = kmalloc(sizeof(fsNode_t)); - - // First, make sure the drive actually exists. - if (ideDevices[driveNum].reserved != 1) { ret->impl = -1; return ret; } - - - - ret->gid = ret->uid = ret->inode = ret->length = ret->mask = 0; - ret->impl = driveNum; - ret->open = NULL; - ret->close = NULL; - ret->finddir = NULL; - ret->create = NULL; - ret->read = &ideRead_vfs; - ret->write = &ideWrite_vfs; - ret->readdir = NULL; - ret->mkdir = NULL; - strcpy(ret->name, "IDE/ATA drive"); - return ret; -} - - -// ide_fs_mount(const char *device, const char *mount_path) - Initializes the filesystem on a device -fsNode_t *ide_fs_mount(const char *device, const char *mount_path) { - serialPrintf("ide_fs_mount: Trying to mount drive %s on %s...\n", device, mount_path); - - // Convert it back to a number - int i = atoi(device); - - // Now, we try to get the VFS node for the device. - fsNode_t *vfsNode = ideGetVFSNode(i); - - // Check if it's actually a valid node - if (vfsNode->impl == -1) { - kfree(vfsNode); - return NULL; - } - - return vfsNode; -} - -// ide_install(int argc, char *argv[]) - Installs the IDE driver to initialize on any compatible drives -int ide_install(int argc, char *argv[]) { - vfs_registerFilesystem("ide", ide_fs_mount); - return 0; -} - - -// ideRead_vfs(struct fsNode *node, off_t off, uint32_t size, uint8_t *buffer) - Read function for the VFS -uint32_t ideRead_vfs(struct fsNode *node, off_t off, uint32_t size, uint8_t *buffer) { - // Create a temporary buffer that rounds up size to the nearest 512 multiple. - uint8_t *temporary_buffer = kmalloc((size + 512) - ((size + 512) % 512)); - - // Calculate the LBA, based off of offset rounded down (TODO: Make this conversion a longer value) - int lba = (off - (off % 512)) / 512; - - // Read in the sectors - int ret = ideReadSectors(((fsNode_t*)node)->impl, ((size + 512) - ((size + 512) % 512)) / 512, lba, temporary_buffer); - if (ret != IDE_OK) return ret; - - // We've now read in about one sector greater than our size, for offset purposes - // We can now copy the contents to our buffer. - int offset = off - (lba * 512); // This is the offset we need to memcpy() our buffer to - - memcpy(buffer, temporary_buffer + offset, size); - - kfree(temporary_buffer); - return IDE_OK; -} - -// ideWrite_vfs(struct fsNode *node, off_t off, uint32_t size, uint8_t *buffer) - Write function for the VFS -uint32_t ideWrite_vfs(struct fsNode *node, off_t off, uint32_t size, uint8_t *buffer) { - // First, create a padded buffer that rounds up size to the nearest 512 multiple. - // This buffer will serve as the actual things to write to the sector. - // We're first going to read in the sector at LBA, then replace the contents at offset to be the input buffer. - uint8_t padded_buffer[((size + 512) - ((size + 512) % 512))]; - - // Calculate the LBA, based off of offset rounded down - int lba = (off - (off % 512)) / 512; - - // Read in the sector for our offset - int ret = ideReadSectors(((fsNode_t*)node)->impl, 1, lba, (uint32_t*)padded_buffer); - if (ret != IDE_OK) return ret; - - // Copy the contents of buffer to padded_buffer with an offset - memcpy(padded_buffer + (off-(lba*512)), buffer, size); - - // Write the sectors - ret = ideWriteSectors(((fsNode_t*)node)->impl, ((size + 512) - ((size + 512) % 512)) / 512, lba, padded_buffer); - if (ret != IDE_OK) return ret; - - return IDE_OK; -} - - -// printIDESummary() - Print a basic summary of all available IDE drives. -void printIDESummary() { - for (int i = 0; i < 4; i++) { - if (ideDevices[i].reserved == 1) { - printf("Found %s drive - %s\n", (ideDevices[i].type == 0) ? "ATA" : "ATAPI", ideDevices[i].model); - // Quick maths to find out the drive capacity. - int capacityGB = ideDevices[i].size / 1024 / 1024; - int capacityMB = ideDevices[i].size / 1024 - (capacityGB * 1024); - int capacityKB = ideDevices[i].size - (capacityMB * 1024); - printf("\tCapacity: %i GB %i MB %i KB\n", capacityGB, capacityMB, capacityKB); - } - } -} - -// ideRead(uint8_t channel, uint8_t reg) - Reads in a register -uint8_t ideRead(uint8_t channel, uint8_t reg) { - uint8_t returnValue; - if (reg > 0x07 && reg < 0x0C) { - ideWrite(channel, ATA_REG_CONTROL, 0x80 | channels[channel].nIEN); - } - - if (reg < 0x08) { - returnValue = inportb(channels[channel].ioBase + reg - 0x00); - } else if (reg < 0x0C) { - returnValue = inportb(channels[channel].ioBase + reg - 0x06); - } else if (reg < 0x0E) { - returnValue = inportb(channels[channel].controlBase + reg - 0x0A); - } else if (reg < 0x16) { - returnValue = inportb(channels[channel].busMasterIDE + reg - 0x0E); - } - - if (reg > 0x07 && reg < 0x0C) { - ideWrite(channel, ATA_REG_CONTROL, channels[channel].nIEN); - } - - return returnValue; -} - -// ideWrite(uint8_t channel, uint8_t reg, uint8_t data) - Writes to an IDE register. -void ideWrite(uint8_t channel, uint8_t reg, uint8_t data) { - if (reg > 0x07 && reg < 0x0C) - ideWrite(channel, ATA_REG_CONTROL, 0x80 | channels[channel].nIEN); - - if (reg < 0x08) { - outportb(channels[channel].ioBase + reg - 0x00, data); - } else if (reg < 0x0C) { - outportb(channels[channel].ioBase + reg - 0x06, data); - } else if (reg < 0x0E) { - outportb(channels[channel].controlBase + reg - 0x0C, data); - } else if (reg < 0x16) { - outportb(channels[channel].busMasterIDE + reg - 0x0E, data); - } - - if (reg > 0x07 && reg < 0x0C) { - ideWrite(channel, ATA_REG_CONTROL, channels[channel].nIEN); - } -} - - - -// ideReadBuffer(uint8_t channel, uint8_t reg, uint32_t *buffer, uint32_t quads) - Reads the identification space and copies it to a buffer. -void ideReadBuffer(uint8_t channel, uint8_t reg, uint32_t *buffer, uint32_t quads) { - // Like most of the previous functions, if reg is greater than 0x07 but less than 0x0C, call ideWrite() - if (reg > 0x07 && reg < 0x0C) { - ideWrite(channel, ATA_REG_CONTROL, 0x80 | channels[channel].nIEN); - } - - //asm ("pushw %es; movw %ds, %ax; movw %ax, %es"); - - asm("pushw %es; pushw %ax; movw %ds, %ax; movw %ax, %es; popw %ax;"); - - if (reg < 0x08) { - insl(channels[channel].ioBase + reg - 0x00, buffer, quads); - } else if (reg < 0x0C) { - insl(channels[channel].ioBase + reg - 0x06, buffer, quads); - } else if (reg < 0x0E) { - insl(channels[channel].controlBase + reg - 0x0A, buffer, quads); - } else if (reg < 0x16) { - insl(channels[channel].busMasterIDE + reg - 0x0E, buffer, quads); - } - - asm ("popw %es"); - if (reg > 0x07 && reg < 0x0C) { - ideWrite(channel, ATA_REG_CONTROL, channels[channel].nIEN); - } -} - - - -// insl(uint16_t reg, uint32_t *buffer, int quads) - Reads a long word from a register port for quads times. -void insl(uint16_t reg, uint32_t *buffer, int quads) { - for (int index = 0; index < quads; index++) { - buffer[index] = inportl(reg); - } -} - -// outsl(uint16_t reg, uint32_t *buffer, int quads) - Writes a long word to a register port for quads times -void outsl(uint16_t reg, uint32_t *buffer, int quads) { - for (int index = 0; index < quads; index++) { - outportl(reg, buffer[index]); - } -} - - - -// idePolling(uint8_t channel, uint32_t advancedCheck) - Returns whether there was an error. -uint8_t idePolling(uint8_t channel, uint32_t advancedCheck) { - // First, delay 400 ns for BSY to be set. - for (int i = 0; i < 4; i++) ideRead(channel, ATA_REG_ALTSTATUS); - - // Next, wait for BSY to be cleared. - while (ideRead(channel, ATA_REG_STATUS) & ATA_STATUS_BSY); - - if (advancedCheck) { - // The user wants us to do an advanced check. - uint8_t state = ideRead(channel, ATA_REG_STATUS); // read the status register - - // Check for errors - if (state & ATA_STATUS_ERR) return 2; // Error. - - // Next, check if device fault - if (state & ATA_STATUS_DF) return 1; // Device fault. - - // Finally, check if data request ready. - // BSY is 0, DF is 0, and ERR is 0, so check for DRQ now. - - if ((state & ATA_STATUS_DRQ) == 0) return 3; // DRQ should be set. - } - - return 0; // No error. -} - - -// idePrintErrors(uint32_t drive, uint8_t err) - Prints the errors that may have occurred. -uint8_t idePrintErrors(uint32_t drive, uint8_t err) { - if (err == 0) return err; // Pesky users!! - serialPrintf("ide: encountered an error on drive 0x%x. error:", drive); - printf("IDE encountered error"); - - if (err == 1) { printf(" - device fault.\n"); err = 19; serialPrintf(" device fault.\n"); } - else if (err == 2) { - uint8_t st = ideRead(ideDevices[drive].channel, ATA_REG_ERROR); - if (st & ERR_AMNF) { printf(" - no address mark found.\n"); err = 7; serialPrintf(" no address mark found.\n"); } - if (st & ERR_TKZNF) { printf(" - no media or media error.\n"); err = 3; serialPrintf(" no media or media error (track zero or not found).\n"); } - if (st & ERR_ABRT) { printf(" - command aborted.\n"); err = 20; serialPrintf(" command aborted.\n"); } - if (st & ERR_MCR) { printf(" - no media or media error.\n"); err = 3; serialPrintf(" no media or media error (media change request)\n"); } - if (st & ERR_IDNF) { printf(" - ID mark not found.\n"); err = 21; serialPrintf(" ID mark not found.\n"); } - if (st & ERR_MC) { printf(" - no media or media error.\n"); err = 3; serialPrintf(" no media or media error (media changed)\n"); } - if (st & ERR_UNC) { printf(" - uncorrectable data error.\n"); err = 22; serialPrintf(" uncorrectable data error.\n"); } - if (st & ERR_BBK) { printf(" - bad sectors.\n"); err = 13; serialPrintf(" bad sectors.\n"); } - } else if (err == 3) { printf("- reads nothing.\n"); err = 23; serialPrintf(" reads nothing.\n"); } - else if (err == 4) { printf("- write protected drive.\n"); err = 8; serialPrintf(" write protected drive.\n"); } - - printf("Drive - [%s %s] %s\n", - (const char *[]){"Primary", "Secondary"}[ideDevices[drive].channel], - (const char *[]){"Master", "Slave"}[ideDevices[drive].channel], - ideDevices[drive].model); - - return err; -} - - -// ideAccessATA(uint8_t direction, uint8_t drive, uint64_t lba, uint8_t sectorNum, uint32_t edi) - Read/write sectors to an ATA drive (if direction is 0 we read, else write) -uint8_t ideAccessATA(uint8_t direction, uint8_t drive, uint64_t lba, uint8_t sectorNum, uint32_t edi) { - /* A bit of explanation about the parameters: - Drive is the drive number (can be 0-3) - lba is the LBA address which allows us to access disks (up to 2TB supported) - sectorNum is the number of sectors to be read - edi is the offset in that segment (data buffer memory address)*/ - - - // First, we define a few variables - uint8_t lbaMode, dma, cmd; // lbaMode: 0: CHS, 1: LBA28, 2: LBA48. dma: 0: No DMA, 1: DMA - uint8_t lbaIO[6]; - uint32_t channel = ideDevices[drive].channel; // Read the channel - uint32_t slaveBit = ideDevices[drive].drive; // Read the drive (master or slave) - uint32_t bus = channels[channel].ioBase; // Bus base (the data port) - uint32_t words = 256; // Almost every ATA drive has a sector size of 512 bytes - uint16_t cylinder; - uint8_t head, sect, err; - - // Disable IRQs to prevent problems. - ideWrite(channel, ATA_REG_CONTROL, channels[channel].nIEN = (ideIRQ = 0x0) + 0x02); - - // Now, let's read the paramters - - // Select one from LBA28, LBA48, or CHS - if (lba >= 0x10000000) { - // Drive supports LBA48. Use that. - - serialPrintf("WARNING: USAGE OF LBA48 DETECTED\n"); - lbaMode = 2; - lbaIO[0] = (lba & 0x000000FF) >> 0; - lbaIO[1] = (lba & 0x0000FF00) >> 8; - lbaIO[2] = (lba & 0x00FF0000) >> 16; - lbaIO[3] = (lba & 0xFF000000) >> 24; - lbaIO[4] = 0; // LBA28 is integer, so 32 bits are enough to access 2TB - lbaIO[5] = 0; - head = 0; // (lower 4 bits of ATA_REG_HDDEVSEL) - } else if (ideDevices[drive].features & 0x200) { - // Drive supports LBA28. - - lbaMode = 1; - lbaIO[0] = (lba & 0x00000FF) >> 0; - lbaIO[1] = (lba & 0x000FF00) >> 8; - lbaIO[2] = (lba & 0x0FF0000) >> 16; - lbaIO[3] = 0; // These registers are not used here. - lbaIO[4] = 0; - lbaIO[5] = 0; - head = (lba & 0xF000000) >> 24; - } else { - // Drive uses CHS. - lbaMode = 0; - sect = (lba % 63) + 1; - cylinder = (lba + 1 - sect) / (16 * 63); - lbaIO[0] = sect; - lbaIO[1] = (cylinder >> 0) & 0xFF; - lbaIO[2] = (cylinder >> 8) & 0xFF; - lbaIO[3] = 0; - lbaIO[4] = 0; - lbaIO[5] = 0; - head = (lba + 1 - sect) % (16 * 63) / (63); - } - - dma = 0; // Don't use DMA. - - - // Now we wait if the drive is busy. - while (ideRead(channel, ATA_REG_STATUS) & ATA_STATUS_BSY) { - - } - - // Select the drive from the controller. - if (lbaMode == 0) ideWrite(channel, ATA_REG_HDDEVSEL, 0xA0 | (slaveBit << 4) | head); // Drive & CHS. - else ideWrite(channel, ATA_REG_HDDEVSEL, 0xE0 | (slaveBit << 4) | head); - - - // Next, write the parameters to the registers. - if (lbaMode == 2) { - // Make sure to write a few extra parameters if we use LBA48. - // ideWrite makes it pretty simple if we want to write to the LBA0 and LBA3 registers. - ideWrite(channel, ATA_REG_SECCOUNT1, 0); - ideWrite(channel, ATA_REG_LBA3, lbaIO[3]); - ideWrite(channel, ATA_REG_LBA4, lbaIO[4]); - ideWrite(channel, ATA_REG_LBA5, lbaIO[5]); - } - - ideWrite(channel, ATA_REG_SECCOUNT0, sectorNum); - ideWrite(channel, ATA_REG_LBA0, lbaIO[0]); - ideWrite(channel, ATA_REG_LBA1, lbaIO[1]); - ideWrite(channel, ATA_REG_LBA2, lbaIO[2]); - - - // Now, select the command and send it. - // According to the ATA/ATAPI-8 specification, these are the available commands (and the routines that are followed) - // If DMA & LBA48, send DMA_EXT - // If DMA & LBA28, send DMA_LBA - // If DMA & LBA28, send DMA_CHS - // If not DMA & LBA48, send PIO_EXT. - // If not DMA & LBA28, send PIO_LBA - // If not DMA & LBA28, send PIO_CHS - - if (lbaMode == 0 && dma == 0 && direction == 0) cmd = ATA_READ_PIO; - if (lbaMode == 1 && dma == 0 && direction == 0) cmd = ATA_READ_PIO; - if (lbaMode == 2 && dma == 0 && direction == 0) cmd = ATA_READ_PIO_EXT; - if (lbaMode == 0 && dma == 1 && direction == 0) cmd = ATA_READ_DMA; - if (lbaMode == 1 && dma == 1 && direction == 0) cmd = ATA_READ_DMA; - if (lbaMode == 2 && dma == 1 && direction == 0) cmd = ATA_READ_DMA_EXT; - if (lbaMode == 0 && dma == 0 && direction == 1) cmd = ATA_WRITE_PIO; - if (lbaMode == 1 && dma == 0 && direction == 1) cmd = ATA_WRITE_PIO; - if (lbaMode == 2 && dma == 0 && direction == 1) cmd = ATA_WRITE_PIO_EXT; - if (lbaMode == 0 && dma == 1 && direction == 1) cmd = ATA_WRITE_DMA; - if (lbaMode == 1 && dma == 1 && direction == 1) cmd = ATA_WRITE_DMA; - if (lbaMode == 2 && dma == 1 && direction == 1) cmd = ATA_WRITE_DMA_EXT; - - ideWrite(channel, ATA_REG_COMMAND, cmd); // Send the command. - - - // Now that we have sent the command, we should poll and read/write a sector until all sectors are read/written. - if (dma) { - // TODO: Implement DMA reading + writing. - - } else { - if (direction == 0) { - // PIO read. - for (int i = 0; i < sectorNum; i++) { - err = idePolling(channel, 1); - if (err) { - serialPrintf("ideAccessATA (direction read): IDE polling returned non-zero value %i\n", err); - return err; // Return if an error occurred. - } - asm ("pushw %es"); - asm ("rep insw" :: "c"(words), "d"(bus), "D"(edi)); // Receive data. - asm ("popw %es"); - edi += (words * 2); - } - } else { - // PIO write - for (int i = 0; i < sectorNum; i++) { - idePolling(channel, 0); // Poll the channel. - asm ("pushw %ds"); - asm ("rep outsw" :: "c"(words), "d"(bus), "S"(edi)); // Send data. - asm ("popw %ds"); - edi += (words*2); - } - ideWrite(channel, ATA_REG_COMMAND, (char []) { ATA_CACHE_FLUSH, ATA_CACHE_FLUSH, ATA_CACHE_FLUSH_EXT }[lbaMode]); - idePolling(channel, 0); - } - } - - return 0; // Done! -} - -// ideReadATAPI(uint8_t drive, uint32_t lba, uint8_t sectorNum, uint32_t edi) - Read from an ATAPI drive. -uint8_t ideReadATAPI(uint8_t drive, uint32_t lba, uint8_t sectorNum, uint32_t edi) { - uint32_t channel = ideDevices[drive].channel; - uint32_t slaveBit = ideDevices[drive].drive; - uint32_t bus = channels[channel].ioBase; - uint32_t words = 1024; // Sector size (ATAPI drives have a sector size of 2048 bytes) - uint8_t err; - int i; - - // Enable IRQs. - ideWrite(channel, ATA_REG_CONTROL, channels[channel].nIEN = ideIRQ = 0x0); - - // Now, setup the SCSI packet. - atapiPacket[0] = ATAPI_READ; - atapiPacket[1] = 0x0; - atapiPacket[2] = (lba >> 24) & 0xFF; - atapiPacket[3] = (lba >> 16) & 0xFF; - atapiPacket[4] = (lba >> 8) & 0xFF; - atapiPacket[5] = (lba >> 0) & 0xFF; - atapiPacket[6] = 0x0; - atapiPacket[7] = 0x0; - atapiPacket[8] = 0x0; - atapiPacket[9] = sectorNum; - atapiPacket[10] = 0x0; - atapiPacket[11] = 0x0; - - // Now, select the drive. - ideWrite(channel, ATA_REG_HDDEVSEL, slaveBit); - - // Delay 400ns for select to coplete. - for (i = 0; i < 4; i++) { - ideRead(channel, ATA_REG_ALTSTATUS); - } - - // Inform controller we use PIO mode. - ideWrite(channel, ATA_REG_FEATURES, 0); - - // Notify controller size of buffer. - ideWrite(channel, ATA_REG_LBA1, (words*2) & 0xFF); // Lower byte of sector size. - ideWrite(channel, ATA_REG_LBA1, (words*2) >> 8); // Upper byte of sector size. - - // First, send the packet command (not the actual packet) - ideWrite(channel, ATA_REG_COMMAND, ATA_PACKET); - - // Wait for the drive to finish or return an error. - if (err = idePolling(channel, 1)) return err; // Error. - - // Send the packet data. - asm ("rep outsw" :: "c"(6), "d"(bus), "S"(atapiPacket)); - - // Receive the data. - for (i = 0; i < sectorNum; i++) { - ideWaitIRQ(); // Wait for an IRQ. - if (err = idePolling(channel, 1)) return err; // There was an error. - asm ("pushw %es"); - asm ("rep insw" :: "c"(words), "d"(bus), "D"(edi)); // Receive the data. - asm ("popw %es"); - edi += (words * 2); - } - - // Wait for an IRQ. - ideWaitIRQ(); - // Wait for BSY and DRQ to clear. - while (ideRead(channel, ATA_REG_STATUS) & (ATA_STATUS_BSY | ATA_STATUS_DRQ)); - - return 0; -} - - -// Note that the above functions (specifically ATA/ATAPI reading and writing) are not supposed to be used outside of ide_ata.c, but are there just in case. -// THESE are the functions supposed to be used outside of ATA: - -uint8_t package[8]; // package[0] contains err code - -// ideReadSectors(uint8_t drive, uint8_t sectorNum, uint64_t lba, uint32_t edi) - Read from an ATA/ATAPI drive. -int ideReadSectors(uint8_t drive, uint8_t sectorNum, uint64_t lba, uint32_t edi) { - - // Check if the drive is present. - if (drive > 3 | ideDevices[drive].reserved == 0) { - package[0] = 0x1; - serialPrintf("ideReadSectors: drive not found - cannot continue.\n"); - return IDE_DRIVE_NOT_FOUND; - } - - // Check if the inputs are valid. - else if (((lba + sectorNum) > ideDevices[drive].size) && (ideDevices[drive].type == IDE_ATA)) { - package[0] = 0x2; // Seeking to invalid position. - serialPrintf("ideReadSectors: LBA address invalid - greater than available sectors.\n"); - return IDE_LBA_INVALID; - } - // Read in PIO mode through polling and IRQs. - else { - uint8_t error; - if (ideDevices[drive].type == IDE_ATA) { - error = ideAccessATA(ATA_READ, drive, lba, sectorNum, edi); - return error; - } else if (ideDevices[drive].type == IDE_ATAPI) { - for (int i = 0; i < sectorNum; i++) { - error = ideReadATAPI(drive, lba + i, 1, edi + (i*2048)); - } - package[0] = idePrintErrors(drive, error); - - return package[0]; - } - } -} - - - -// ideWriteSectors(uint8_t drive, uint8_t sectorNum, uint32_t lba, uint32_t edi) - Write to an ATA drive. -int ideWriteSectors(uint8_t drive, uint8_t sectorNum, uint32_t lba, uint32_t edi) { - // Like the above funtion, we follow similar steps. - // Check if the drive is present. - if (drive > 3 | ideDevices[drive].reserved == 0) { - package[0] = 0x1; - serialPrintf("ideWriteSectors: drive not found - cannot continue.\n"); - return IDE_DRIVE_NOT_FOUND; - } - - // Check if the inputs are valid. - else if (((lba + sectorNum) > ideDevices[drive].size) && (ideDevices[drive].type == IDE_ATA)) { - package[0] = 0x2; // Seeking to invalid position. - serialPrintf("ideWriteSectors: LBA address invalid - greater than available sectors.\n"); - return IDE_LBA_INVALID; - } - // Now, write in PIO mode through polling and IRQs - else { - uint8_t error; - if (ideDevices[drive].type == IDE_ATA) { - error = ideAccessATA(ATA_WRITE, drive, lba, sectorNum, edi); - } else if (ideDevices[drive].type == IDE_ATAPI) error = 4; // Drive is write protected. - package[0] = idePrintErrors(drive, error); - - return package[0]; - } -} - -// Some getter functions.. - -// ideGetDriveCapacity(uint8_t drive) - Returns drive capacity -int ideGetDriveCapacity(uint8_t drive) { - // Sanity checks - if (drive > 3 | ideDevices[drive].reserved == 0) { - return -1; - } - - return ideDevices[drive].size; -} \ No newline at end of file +// ========================================================= +// ide_ata.c - reduceOS IDE + ATA driver +// ========================================================= +// This file is a part of the reduceOS C kernel. Please credit me if you use this code. + +#include // Main header file + +// What is IDE? +// According to the OSDev wiki, IDE is a keyword which refers to the electrical specification of the cables which connect ATA drives (like hard drives) to another device. The drives use the ATA (Advanced Technology Attachment) interface. An IDE cable also can terminate at an IDE card connected to PCI. +// ATAPI is an extension to ATA (recently renamed to PATA), adding support for the SCSI command set. +// More sources: https://wiki.osdev.org/PCI_IDE_Controller + + +// Variables +ideChannelRegisters_t channels[2]; // Primary and secondary channels +uint8_t ideBuffer[2048] = {0}; // Buffer to read the identification space into (see ide_ata.h). +volatile unsigned static char ideIRQ = 0; // Set to 1 when an IRQ is received. +static uint8_t atapiPacket[12] = {0xA8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // ATAPI drives +ideDevice_t ideDevices[4]; // Maximum devices supported is 4. + + + +// Function prototypes +uint8_t ideRead(uint8_t channel, uint8_t reg); // Reads in a register +void ideWrite(uint8_t channel, uint8_t reg, uint8_t data); // Writes to a register +void ideReadBuffer(uint8_t channel, uint8_t reg, uint32_t *buffer, uint32_t quads); // Reads the identification space and copies it to a buffer. +void insl(uint16_t reg, uint32_t *buffer, int quads); // Reads a long word from a register port for quads times. +void outsl(uint16_t reg, uint32_t *buffer, int quads); // Writes a long word to a register port for quads times +uint8_t idePolling(uint8_t channel, uint32_t advancedCheck); // Returns whether there was an error. +uint8_t idePrintErrors(uint32_t drive, uint8_t err); // Prints the errors that may have occurred. + +void ideWaitIRQ() { + while (!ideIRQ); + ideIRQ = 0; +} + +void ideIRQHandler() { + ideIRQ = 1; +} + + +void ideInit(uint32_t bar0, uint32_t bar1, uint32_t bar2, uint32_t bar3, uint32_t bar4) { + // Parameters: + // bar0 is the start of the IO ports used by the primary ATA channel + // bar1 is the start of the IO ports that control the primary ATA channel + // bar2 is the start of the IO ports used by the secondary ATA channel + // bar3 is the start of the IO ports that control the secondary ATA channel + // bar4 is the start of 8 IO ports that control the primary channel's bus master IDE. + // bar4 + 8 is the start of the 8 IO ports that control the secondary channel's bus master IDE. + + int count = 0; + + + // First, detect IO ports which interface the IDE controller. + channels[ATA_PRIMARY].ioBase = (bar0 & 0xFFFFFFFC) + 0x1F0 * (!bar0); // 0x1F0 is the default IO base + channels[ATA_PRIMARY].controlBase = (bar1 & 0xFFFFFFFC) + 0x3F6 * (!bar1); // 0x3F6 is the default control base + channels[ATA_SECONDARY].ioBase = (bar2 & 0xFFFFFFFC) + 0x170 * (!bar2); + channels[ATA_SECONDARY].controlBase = (bar3 & 0xFFFFFFFC) + 0x376 * (!bar3); + channels[ATA_PRIMARY].busMasterIDE = (bar4 & 0xFFFFFFFC) + 0; // Bus master IDE + channels[ATA_SECONDARY].busMasterIDE = (bar4 & 0xFFFFFFFC) + 8; + + // Next, disable IRQs in both channels (via setting bit 1 in the control port) + ideWrite(ATA_PRIMARY, ATA_REG_CONTROL, 2); + ideWrite(ATA_SECONDARY, ATA_REG_CONTROL, 2); + + // Now, detect ATA/ATAPI drives. + for (int i = 0; i < 2; i++) { + for (int j = 0; j < 2; j++) { + uint8_t err = 0, type = IDE_ATA, status; + ideDevices[count].reserved = 0; // Assuming there is no drive. + + // Step 1 - select the drive. + ideWrite(i, ATA_REG_HDDEVSEL, 0xA0 | (j << 4)); // Select the drive + sleep(1); // Wait 1 ms for drive select to wokr. + + // Next, send the ATA identify command + ideWrite(i, ATA_REG_COMMAND, ATA_IDENTIFY); + sleep(1); // Wait 1 ms for identify to work. + + // Now, poll. + if (ideRead(i, ATA_REG_STATUS) == 0) continue; // If status is 0, no device. + + while (1) { + status = ideRead(i, ATA_REG_STATUS); + if (status & ATA_STATUS_ERR) { err = 1; break; } // If err, device is not ATA. + if (!(status & ATA_STATUS_BSY) && (status & ATA_STATUS_DRQ)) break; // Everything is right. + } + + // Next, probe for ATAPI devices + if (err != 0) { + uint8_t cl = ideRead(i, ATA_REG_LBA1); + uint8_t ch = ideRead(i, ATA_REG_LBA2); + + if (cl == 0x14 && ch == 0xEB) { + type = IDE_ATAPI; + } else if (cl == 0x69 && ch == 0x96) { + type = IDE_ATAPI; + } else { + continue; // Unknown type. + } + + ideWrite(i, ATA_REG_COMMAND, ATA_IDENTIFY_PACKET); + sleep(1); + } + + // Read the identification space of the device. + ideReadBuffer(i, ATA_REG_DATA, (uint32_t*)ideBuffer, 128); + + // Next, read the device parameters. + ideDevices[count].reserved = 1; + ideDevices[count].type = type; + ideDevices[count].channel = i; + ideDevices[count].drive = j; + ideDevices[count].signature = *((uint16_t*)(ideBuffer + ATA_IDENT_DEVICETYPE)); + ideDevices[count].features = *((uint16_t*)(ideBuffer + ATA_IDENT_CAPABILITIES)); + ideDevices[count].commandSets = *((uint32_t *)(ideBuffer + ATA_IDENT_COMMANDSETS)); + + // Now, get the device size. + if (ideDevices[count].commandSets & (1 << 26)) { + // Device uses 48-bit addressing. + ideDevices[count].size = *((uint32_t*)(ideBuffer + ATA_IDENT_MAX_LBA_EXT)); + } else { + // Device uses CHS or 28-bit addressing + ideDevices[count].size = *((uint32_t*)(ideBuffer + ATA_IDENT_MAX_LBA)); + } + + // Finally (for this function), get the model string. + for (int k = 0; k < 40; k += 2) { + ideDevices[count].model[k] = ideBuffer[ATA_IDENT_MODEL + k + 1]; + ideDevices[count].model[k + 1] = ideBuffer[ATA_IDENT_MODEL + k]; + } + + ideDevices[count].model[40] = '\0'; // Zero terminate the string. + + count++; + } + } + + // Finally (for all of the driver), print a summary of the ATA devices + int drives = 0; + serialPrintf("IDE driver completed initialization.\n"); + for (int i = 0; i < 4; i++) { + if (ideDevices[i].reserved == 1) { + serialPrintf("Found %s drive - %s\n", (ideDevices[i].type == 0) ? "ATA" : "ATAPI", ideDevices[i].model); + // Quick maths to find out the drive capacity. + int capacityGB = ideDevices[i].size / 1024 / 1024; + int capacityMB = ideDevices[i].size / 1024 - (capacityGB * 1024); + int capacityKB = ideDevices[i].size - (capacityMB * 1024); + serialPrintf("\tCapacity: %i GB %i MB %i KB\n", capacityGB, capacityMB, capacityKB); + drives++; + } + } + + isrRegisterInterruptHandler(15, ideIRQHandler); + + + + printf("IDE driver initialized - found %i drives.\n", drives); + + + +} + + +// ideGetVFSNode(int driveNum) - Returns VFS node for an IDE drive +fsNode_t *ideGetVFSNode(int driveNum) { + fsNode_t *ret = kmalloc(sizeof(fsNode_t)); + + // First, make sure the drive actually exists. + if (ideDevices[driveNum].reserved != 1) { ret->impl = -1; return ret; } + + + + ret->gid = ret->uid = ret->inode = ret->length = ret->mask = 0; + ret->impl = driveNum; + ret->open = NULL; + ret->close = NULL; + ret->finddir = NULL; + ret->create = NULL; + ret->read = &ideRead_vfs; + ret->write = &ideWrite_vfs; + ret->readdir = NULL; + ret->mkdir = NULL; + strcpy(ret->name, "IDE/ATA drive"); + return ret; +} + + +// ide_fs_mount(const char *device, const char *mount_path) - Initializes the filesystem on a device +fsNode_t *ide_fs_mount(const char *device, const char *mount_path) { + serialPrintf("ide_fs_mount: Trying to mount drive %s on %s...\n", device, mount_path); + + // Convert it back to a number + int i = atoi(device); + + // Now, we try to get the VFS node for the device. + fsNode_t *vfsNode = ideGetVFSNode(i); + + // Check if it's actually a valid node + if (vfsNode->impl == -1) { + kfree(vfsNode); + return NULL; + } + + return vfsNode; +} + +// ide_install(int argc, char *argv[]) - Installs the IDE driver to initialize on any compatible drives +int ide_install(int argc, char *argv[]) { + vfs_registerFilesystem("ide", ide_fs_mount); + return 0; +} + + +// ideRead_vfs(struct fsNode *node, off_t off, uint32_t size, uint8_t *buffer) - Read function for the VFS +uint32_t ideRead_vfs(struct fsNode *node, off_t off, uint32_t size, uint8_t *buffer) { + // Create a temporary buffer that rounds up size to the nearest 512 multiple. + uint8_t *temporary_buffer = kmalloc((size + 512) - ((size + 512) % 512)); + + // Calculate the LBA, based off of offset rounded down (TODO: Make this conversion a longer value) + int lba = (off - (off % 512)) / 512; + + // Read in the sectors + int ret = ideReadSectors(((fsNode_t*)node)->impl, ((size + 512) - ((size + 512) % 512)) / 512, lba, temporary_buffer); + if (ret != IDE_OK) return ret; + + // We've now read in about one sector greater than our size, for offset purposes + // We can now copy the contents to our buffer. + int offset = off - (lba * 512); // This is the offset we need to memcpy() our buffer to + + memcpy(buffer, temporary_buffer + offset, size); + + kfree(temporary_buffer); + return IDE_OK; +} + +// ideWrite_vfs(struct fsNode *node, off_t off, uint32_t size, uint8_t *buffer) - Write function for the VFS +uint32_t ideWrite_vfs(struct fsNode *node, off_t off, uint32_t size, uint8_t *buffer) { + // First, create a padded buffer that rounds up size to the nearest 512 multiple. + // This buffer will serve as the actual things to write to the sector. + // We're first going to read in the sector at LBA, then replace the contents at offset to be the input buffer. + uint8_t padded_buffer[((size + 512) - ((size + 512) % 512))]; + + // Calculate the LBA, based off of offset rounded down + int lba = (off - (off % 512)) / 512; + + // Read in the sector for our offset + int ret = ideReadSectors(((fsNode_t*)node)->impl, 1, lba, (uint32_t*)padded_buffer); + if (ret != IDE_OK) return ret; + + // Copy the contents of buffer to padded_buffer with an offset + memcpy(padded_buffer + (off-(lba*512)), buffer, size); + + // Write the sectors + ret = ideWriteSectors(((fsNode_t*)node)->impl, ((size + 512) - ((size + 512) % 512)) / 512, lba, padded_buffer); + if (ret != IDE_OK) return ret; + + return IDE_OK; +} + + +// printIDESummary() - Print a basic summary of all available IDE drives. +void printIDESummary() { + for (int i = 0; i < 4; i++) { + if (ideDevices[i].reserved == 1) { + printf("Found %s drive - %s\n", (ideDevices[i].type == 0) ? "ATA" : "ATAPI", ideDevices[i].model); + // Quick maths to find out the drive capacity. + int capacityGB = ideDevices[i].size / 1024 / 1024; + int capacityMB = ideDevices[i].size / 1024 - (capacityGB * 1024); + int capacityKB = ideDevices[i].size - (capacityMB * 1024); + printf("\tCapacity: %i GB %i MB %i KB\n", capacityGB, capacityMB, capacityKB); + } + } +} + +// ideRead(uint8_t channel, uint8_t reg) - Reads in a register +uint8_t ideRead(uint8_t channel, uint8_t reg) { + uint8_t returnValue; + if (reg > 0x07 && reg < 0x0C) { + ideWrite(channel, ATA_REG_CONTROL, 0x80 | channels[channel].nIEN); + } + + if (reg < 0x08) { + returnValue = inportb(channels[channel].ioBase + reg - 0x00); + } else if (reg < 0x0C) { + returnValue = inportb(channels[channel].ioBase + reg - 0x06); + } else if (reg < 0x0E) { + returnValue = inportb(channels[channel].controlBase + reg - 0x0A); + } else if (reg < 0x16) { + returnValue = inportb(channels[channel].busMasterIDE + reg - 0x0E); + } + + if (reg > 0x07 && reg < 0x0C) { + ideWrite(channel, ATA_REG_CONTROL, channels[channel].nIEN); + } + + return returnValue; +} + +// ideWrite(uint8_t channel, uint8_t reg, uint8_t data) - Writes to an IDE register. +void ideWrite(uint8_t channel, uint8_t reg, uint8_t data) { + if (reg > 0x07 && reg < 0x0C) + ideWrite(channel, ATA_REG_CONTROL, 0x80 | channels[channel].nIEN); + + if (reg < 0x08) { + outportb(channels[channel].ioBase + reg - 0x00, data); + } else if (reg < 0x0C) { + outportb(channels[channel].ioBase + reg - 0x06, data); + } else if (reg < 0x0E) { + outportb(channels[channel].controlBase + reg - 0x0C, data); + } else if (reg < 0x16) { + outportb(channels[channel].busMasterIDE + reg - 0x0E, data); + } + + if (reg > 0x07 && reg < 0x0C) { + ideWrite(channel, ATA_REG_CONTROL, channels[channel].nIEN); + } +} + + + +// ideReadBuffer(uint8_t channel, uint8_t reg, uint32_t *buffer, uint32_t quads) - Reads the identification space and copies it to a buffer. +void ideReadBuffer(uint8_t channel, uint8_t reg, uint32_t *buffer, uint32_t quads) { + // Like most of the previous functions, if reg is greater than 0x07 but less than 0x0C, call ideWrite() + if (reg > 0x07 && reg < 0x0C) { + ideWrite(channel, ATA_REG_CONTROL, 0x80 | channels[channel].nIEN); + } + + //asm ("pushw %es; movw %ds, %ax; movw %ax, %es"); + + asm("pushw %es; pushw %ax; movw %ds, %ax; movw %ax, %es; popw %ax;"); + + if (reg < 0x08) { + insl(channels[channel].ioBase + reg - 0x00, buffer, quads); + } else if (reg < 0x0C) { + insl(channels[channel].ioBase + reg - 0x06, buffer, quads); + } else if (reg < 0x0E) { + insl(channels[channel].controlBase + reg - 0x0A, buffer, quads); + } else if (reg < 0x16) { + insl(channels[channel].busMasterIDE + reg - 0x0E, buffer, quads); + } + + asm ("popw %es"); + if (reg > 0x07 && reg < 0x0C) { + ideWrite(channel, ATA_REG_CONTROL, channels[channel].nIEN); + } +} + + + +// insl(uint16_t reg, uint32_t *buffer, int quads) - Reads a long word from a register port for quads times. +void insl(uint16_t reg, uint32_t *buffer, int quads) { + for (int index = 0; index < quads; index++) { + buffer[index] = inportl(reg); + } +} + +// outsl(uint16_t reg, uint32_t *buffer, int quads) - Writes a long word to a register port for quads times +void outsl(uint16_t reg, uint32_t *buffer, int quads) { + for (int index = 0; index < quads; index++) { + outportl(reg, buffer[index]); + } +} + + + +// idePolling(uint8_t channel, uint32_t advancedCheck) - Returns whether there was an error. +uint8_t idePolling(uint8_t channel, uint32_t advancedCheck) { + // First, delay 400 ns for BSY to be set. + for (int i = 0; i < 4; i++) ideRead(channel, ATA_REG_ALTSTATUS); + + // Next, wait for BSY to be cleared. + while (ideRead(channel, ATA_REG_STATUS) & ATA_STATUS_BSY); + + if (advancedCheck) { + // The user wants us to do an advanced check. + uint8_t state = ideRead(channel, ATA_REG_STATUS); // read the status register + + // Check for errors + if (state & ATA_STATUS_ERR) return 2; // Error. + + // Next, check if device fault + if (state & ATA_STATUS_DF) return 1; // Device fault. + + // Finally, check if data request ready. + // BSY is 0, DF is 0, and ERR is 0, so check for DRQ now. + + if ((state & ATA_STATUS_DRQ) == 0) return 3; // DRQ should be set. + } + + return 0; // No error. +} + + +// idePrintErrors(uint32_t drive, uint8_t err) - Prints the errors that may have occurred. +uint8_t idePrintErrors(uint32_t drive, uint8_t err) { + if (err == 0) return err; // Pesky users!! + serialPrintf("ide: encountered an error on drive 0x%x. error:", drive); + printf("IDE encountered error"); + + if (err == 1) { printf(" - device fault.\n"); err = 19; serialPrintf(" device fault.\n"); } + else if (err == 2) { + uint8_t st = ideRead(ideDevices[drive].channel, ATA_REG_ERROR); + if (st & ERR_AMNF) { printf(" - no address mark found.\n"); err = 7; serialPrintf(" no address mark found.\n"); } + if (st & ERR_TKZNF) { printf(" - no media or media error.\n"); err = 3; serialPrintf(" no media or media error (track zero or not found).\n"); } + if (st & ERR_ABRT) { printf(" - command aborted.\n"); err = 20; serialPrintf(" command aborted.\n"); } + if (st & ERR_MCR) { printf(" - no media or media error.\n"); err = 3; serialPrintf(" no media or media error (media change request)\n"); } + if (st & ERR_IDNF) { printf(" - ID mark not found.\n"); err = 21; serialPrintf(" ID mark not found.\n"); } + if (st & ERR_MC) { printf(" - no media or media error.\n"); err = 3; serialPrintf(" no media or media error (media changed)\n"); } + if (st & ERR_UNC) { printf(" - uncorrectable data error.\n"); err = 22; serialPrintf(" uncorrectable data error.\n"); } + if (st & ERR_BBK) { printf(" - bad sectors.\n"); err = 13; serialPrintf(" bad sectors.\n"); } + } else if (err == 3) { printf("- reads nothing.\n"); err = 23; serialPrintf(" reads nothing.\n"); } + else if (err == 4) { printf("- write protected drive.\n"); err = 8; serialPrintf(" write protected drive.\n"); } + + printf("Drive - [%s %s] %s\n", + (const char *[]){"Primary", "Secondary"}[ideDevices[drive].channel], + (const char *[]){"Master", "Slave"}[ideDevices[drive].channel], + ideDevices[drive].model); + + return err; +} + + +// ideAccessATA(uint8_t direction, uint8_t drive, uint64_t lba, uint8_t sectorNum, uint32_t edi) - Read/write sectors to an ATA drive (if direction is 0 we read, else write) +uint8_t ideAccessATA(uint8_t direction, uint8_t drive, uint64_t lba, uint8_t sectorNum, uint32_t edi) { + /* A bit of explanation about the parameters: + Drive is the drive number (can be 0-3) + lba is the LBA address which allows us to access disks (up to 2TB supported) + sectorNum is the number of sectors to be read + edi is the offset in that segment (data buffer memory address)*/ + + + // First, we define a few variables + uint8_t lbaMode, dma, cmd; // lbaMode: 0: CHS, 1: LBA28, 2: LBA48. dma: 0: No DMA, 1: DMA + uint8_t lbaIO[6]; + uint32_t channel = ideDevices[drive].channel; // Read the channel + uint32_t slaveBit = ideDevices[drive].drive; // Read the drive (master or slave) + uint32_t bus = channels[channel].ioBase; // Bus base (the data port) + uint32_t words = 256; // Almost every ATA drive has a sector size of 512 bytes + uint16_t cylinder; + uint8_t head, sect, err; + + // Disable IRQs to prevent problems. + ideWrite(channel, ATA_REG_CONTROL, channels[channel].nIEN = (ideIRQ = 0x0) + 0x02); + + // Now, let's read the paramters + + // Select one from LBA28, LBA48, or CHS + if (lba >= 0x10000000) { + // Drive supports LBA48. Use that. + + serialPrintf("WARNING: USAGE OF LBA48 DETECTED\n"); + lbaMode = 2; + lbaIO[0] = (lba & 0x000000FF) >> 0; + lbaIO[1] = (lba & 0x0000FF00) >> 8; + lbaIO[2] = (lba & 0x00FF0000) >> 16; + lbaIO[3] = (lba & 0xFF000000) >> 24; + lbaIO[4] = 0; // LBA28 is integer, so 32 bits are enough to access 2TB + lbaIO[5] = 0; + head = 0; // (lower 4 bits of ATA_REG_HDDEVSEL) + } else if (ideDevices[drive].features & 0x200) { + // Drive supports LBA28. + + lbaMode = 1; + lbaIO[0] = (lba & 0x00000FF) >> 0; + lbaIO[1] = (lba & 0x000FF00) >> 8; + lbaIO[2] = (lba & 0x0FF0000) >> 16; + lbaIO[3] = 0; // These registers are not used here. + lbaIO[4] = 0; + lbaIO[5] = 0; + head = (lba & 0xF000000) >> 24; + } else { + // Drive uses CHS. + lbaMode = 0; + sect = (lba % 63) + 1; + cylinder = (lba + 1 - sect) / (16 * 63); + lbaIO[0] = sect; + lbaIO[1] = (cylinder >> 0) & 0xFF; + lbaIO[2] = (cylinder >> 8) & 0xFF; + lbaIO[3] = 0; + lbaIO[4] = 0; + lbaIO[5] = 0; + head = (lba + 1 - sect) % (16 * 63) / (63); + } + + dma = 0; // Don't use DMA. + + + // Now we wait if the drive is busy. + while (ideRead(channel, ATA_REG_STATUS) & ATA_STATUS_BSY) { + + } + + // Select the drive from the controller. + if (lbaMode == 0) ideWrite(channel, ATA_REG_HDDEVSEL, 0xA0 | (slaveBit << 4) | head); // Drive & CHS. + else ideWrite(channel, ATA_REG_HDDEVSEL, 0xE0 | (slaveBit << 4) | head); + + + // Next, write the parameters to the registers. + if (lbaMode == 2) { + // Make sure to write a few extra parameters if we use LBA48. + // ideWrite makes it pretty simple if we want to write to the LBA0 and LBA3 registers. + ideWrite(channel, ATA_REG_SECCOUNT1, 0); + ideWrite(channel, ATA_REG_LBA3, lbaIO[3]); + ideWrite(channel, ATA_REG_LBA4, lbaIO[4]); + ideWrite(channel, ATA_REG_LBA5, lbaIO[5]); + } + + ideWrite(channel, ATA_REG_SECCOUNT0, sectorNum); + ideWrite(channel, ATA_REG_LBA0, lbaIO[0]); + ideWrite(channel, ATA_REG_LBA1, lbaIO[1]); + ideWrite(channel, ATA_REG_LBA2, lbaIO[2]); + + + // Now, select the command and send it. + // According to the ATA/ATAPI-8 specification, these are the available commands (and the routines that are followed) + // If DMA & LBA48, send DMA_EXT + // If DMA & LBA28, send DMA_LBA + // If DMA & LBA28, send DMA_CHS + // If not DMA & LBA48, send PIO_EXT. + // If not DMA & LBA28, send PIO_LBA + // If not DMA & LBA28, send PIO_CHS + + if (lbaMode == 0 && dma == 0 && direction == 0) cmd = ATA_READ_PIO; + if (lbaMode == 1 && dma == 0 && direction == 0) cmd = ATA_READ_PIO; + if (lbaMode == 2 && dma == 0 && direction == 0) cmd = ATA_READ_PIO_EXT; + if (lbaMode == 0 && dma == 1 && direction == 0) cmd = ATA_READ_DMA; + if (lbaMode == 1 && dma == 1 && direction == 0) cmd = ATA_READ_DMA; + if (lbaMode == 2 && dma == 1 && direction == 0) cmd = ATA_READ_DMA_EXT; + if (lbaMode == 0 && dma == 0 && direction == 1) cmd = ATA_WRITE_PIO; + if (lbaMode == 1 && dma == 0 && direction == 1) cmd = ATA_WRITE_PIO; + if (lbaMode == 2 && dma == 0 && direction == 1) cmd = ATA_WRITE_PIO_EXT; + if (lbaMode == 0 && dma == 1 && direction == 1) cmd = ATA_WRITE_DMA; + if (lbaMode == 1 && dma == 1 && direction == 1) cmd = ATA_WRITE_DMA; + if (lbaMode == 2 && dma == 1 && direction == 1) cmd = ATA_WRITE_DMA_EXT; + + ideWrite(channel, ATA_REG_COMMAND, cmd); // Send the command. + + + // Now that we have sent the command, we should poll and read/write a sector until all sectors are read/written. + if (dma) { + // TODO: Implement DMA reading + writing. + + } else { + if (direction == 0) { + // PIO read. + for (int i = 0; i < sectorNum; i++) { + err = idePolling(channel, 1); + if (err) { + serialPrintf("ideAccessATA (direction read): IDE polling returned non-zero value %i\n", err); + return err; // Return if an error occurred. + } + asm ("pushw %es"); + asm ("rep insw" :: "c"(words), "d"(bus), "D"(edi)); // Receive data. + asm ("popw %es"); + edi += (words * 2); + } + } else { + // PIO write + for (int i = 0; i < sectorNum; i++) { + idePolling(channel, 0); // Poll the channel. + asm ("pushw %ds"); + asm ("rep outsw" :: "c"(words), "d"(bus), "S"(edi)); // Send data. + asm ("popw %ds"); + edi += (words*2); + } + ideWrite(channel, ATA_REG_COMMAND, (char []) { ATA_CACHE_FLUSH, ATA_CACHE_FLUSH, ATA_CACHE_FLUSH_EXT }[lbaMode]); + idePolling(channel, 0); + } + } + + return 0; // Done! +} + +// ideReadATAPI(uint8_t drive, uint32_t lba, uint8_t sectorNum, uint32_t edi) - Read from an ATAPI drive. +uint8_t ideReadATAPI(uint8_t drive, uint32_t lba, uint8_t sectorNum, uint32_t edi) { + uint32_t channel = ideDevices[drive].channel; + uint32_t slaveBit = ideDevices[drive].drive; + uint32_t bus = channels[channel].ioBase; + uint32_t words = 1024; // Sector size (ATAPI drives have a sector size of 2048 bytes) + uint8_t err; + int i; + + // Enable IRQs. + ideWrite(channel, ATA_REG_CONTROL, channels[channel].nIEN = ideIRQ = 0x0); + + // Now, setup the SCSI packet. + atapiPacket[0] = ATAPI_READ; + atapiPacket[1] = 0x0; + atapiPacket[2] = (lba >> 24) & 0xFF; + atapiPacket[3] = (lba >> 16) & 0xFF; + atapiPacket[4] = (lba >> 8) & 0xFF; + atapiPacket[5] = (lba >> 0) & 0xFF; + atapiPacket[6] = 0x0; + atapiPacket[7] = 0x0; + atapiPacket[8] = 0x0; + atapiPacket[9] = sectorNum; + atapiPacket[10] = 0x0; + atapiPacket[11] = 0x0; + + // Now, select the drive. + ideWrite(channel, ATA_REG_HDDEVSEL, slaveBit); + + // Delay 400ns for select to coplete. + for (i = 0; i < 4; i++) { + ideRead(channel, ATA_REG_ALTSTATUS); + } + + // Inform controller we use PIO mode. + ideWrite(channel, ATA_REG_FEATURES, 0); + + // Notify controller size of buffer. + ideWrite(channel, ATA_REG_LBA1, (words*2) & 0xFF); // Lower byte of sector size. + ideWrite(channel, ATA_REG_LBA1, (words*2) >> 8); // Upper byte of sector size. + + // First, send the packet command (not the actual packet) + ideWrite(channel, ATA_REG_COMMAND, ATA_PACKET); + + // Wait for the drive to finish or return an error. + if (err = idePolling(channel, 1)) return err; // Error. + + // Send the packet data. + asm ("rep outsw" :: "c"(6), "d"(bus), "S"(atapiPacket)); + + // Receive the data. + for (i = 0; i < sectorNum; i++) { + ideWaitIRQ(); // Wait for an IRQ. + if (err = idePolling(channel, 1)) return err; // There was an error. + asm ("pushw %es"); + asm ("rep insw" :: "c"(words), "d"(bus), "D"(edi)); // Receive the data. + asm ("popw %es"); + edi += (words * 2); + } + + // Wait for an IRQ. + ideWaitIRQ(); + // Wait for BSY and DRQ to clear. + while (ideRead(channel, ATA_REG_STATUS) & (ATA_STATUS_BSY | ATA_STATUS_DRQ)); + + return 0; +} + + +// Note that the above functions (specifically ATA/ATAPI reading and writing) are not supposed to be used outside of ide_ata.c, but are there just in case. +// THESE are the functions supposed to be used outside of ATA: + +uint8_t package[8]; // package[0] contains err code + +// ideReadSectors(uint8_t drive, uint8_t sectorNum, uint64_t lba, uint32_t edi) - Read from an ATA/ATAPI drive. +int ideReadSectors(uint8_t drive, uint8_t sectorNum, uint64_t lba, uint32_t edi) { + + // Check if the drive is present. + if (drive > 3 | ideDevices[drive].reserved == 0) { + package[0] = 0x1; + serialPrintf("ideReadSectors: drive not found - cannot continue.\n"); + return IDE_DRIVE_NOT_FOUND; + } + + // Check if the inputs are valid. + else if (((lba + sectorNum) > ideDevices[drive].size) && (ideDevices[drive].type == IDE_ATA)) { + package[0] = 0x2; // Seeking to invalid position. + serialPrintf("ideReadSectors: LBA address invalid - greater than available sectors.\n"); + return IDE_LBA_INVALID; + } + // Read in PIO mode through polling and IRQs. + else { + uint8_t error; + if (ideDevices[drive].type == IDE_ATA) { + error = ideAccessATA(ATA_READ, drive, lba, sectorNum, edi); + return error; + } else if (ideDevices[drive].type == IDE_ATAPI) { + for (int i = 0; i < sectorNum; i++) { + error = ideReadATAPI(drive, lba + i, 1, edi + (i*2048)); + } + package[0] = idePrintErrors(drive, error); + + return package[0]; + } + } +} + + + +// ideWriteSectors(uint8_t drive, uint8_t sectorNum, uint32_t lba, uint32_t edi) - Write to an ATA drive. +int ideWriteSectors(uint8_t drive, uint8_t sectorNum, uint32_t lba, uint32_t edi) { + // Like the above funtion, we follow similar steps. + // Check if the drive is present. + if (drive > 3 | ideDevices[drive].reserved == 0) { + package[0] = 0x1; + serialPrintf("ideWriteSectors: drive not found - cannot continue.\n"); + return IDE_DRIVE_NOT_FOUND; + } + + // Check if the inputs are valid. + else if (((lba + sectorNum) > ideDevices[drive].size) && (ideDevices[drive].type == IDE_ATA)) { + package[0] = 0x2; // Seeking to invalid position. + serialPrintf("ideWriteSectors: LBA address invalid - greater than available sectors.\n"); + return IDE_LBA_INVALID; + } + // Now, write in PIO mode through polling and IRQs + else { + uint8_t error; + if (ideDevices[drive].type == IDE_ATA) { + error = ideAccessATA(ATA_WRITE, drive, lba, sectorNum, edi); + } else if (ideDevices[drive].type == IDE_ATAPI) error = 4; // Drive is write protected. + package[0] = idePrintErrors(drive, error); + + return package[0]; + } +} + +// Some getter functions.. + +// ideGetDriveCapacity(uint8_t drive) - Returns drive capacity +int ideGetDriveCapacity(uint8_t drive) { + // Sanity checks + if (drive > 3 | ideDevices[drive].reserved == 0) { + return -1; + } + + return ideDevices[drive].size; +} diff --git a/source/kernel/drivers/io_apic.c b/source/kernel/drivers/io_apic.c index bf3462a7..e483a80c 100644 --- a/source/kernel/drivers/io_apic.c +++ b/source/kernel/drivers/io_apic.c @@ -1,58 +1,58 @@ -// ======================================================= -// io_apic.c - Handles setting up the I/O APIC. -// ======================================================= -// This file is a part of the reduceOS C kernel. Please credit me if you use this code. - -#include "include/io_apic.h" // Main header file - -// (copy and pasted from local_apic.c) -// First, what is the local APIC? Well, APIC stands for "Advanced Programmable Interrupt Controller", or a newer version of the 8259 PIC chip. -// Intel's more recent processors now use the APIC standard, so it's essential to implement in a kernel. -// Second, why is it a "local" APIC? There are two versions of the APIC, IO and local. -// In an APIC-based system (either with a more recent processor or a multiprocessor system), each CPU is made of a core and local APIC. -// The local APIC is responsible for handling CPU-specific interrupt configuration and a little more. The IO APIC is part of the chipset and provides multi-processor interrupt management. -// https://wiki.osdev.org/APIC - - -// Global variables -uint8_t *ioAPIC_addr = 0x0; // SHOULD BE SET BY ACPI - -// Static functions - -// (static) ioAPIC_write(uint8_t *base, uint8_t reg, uint32_t val) - Write to the IO APIC. -static void ioAPIC_write(uint8_t *base, uint8_t reg, uint32_t val) { - *(volatile uint32_t *)(base + IO_APIC_REGSEL) = reg; - *(volatile uint32_t *)(base + IO_APIC_WIN) = val; -} - -// (static) ioAPIC_read(uint8_t *base, uint8_t reg) - Read from the IO APIC. -static uint32_t ioAPIC_read(uint8_t *base, uint8_t reg) { - *(volatile uint32_t *)(base + IO_APIC_REGSEL) = reg; - return *(volatile uint32_t *)(base + IO_APIC_WIN); -} - -// Functions. - -// ioAPIC_setEntry(uint8_t *base, uint8_t index, uint64_t data) - Set an entry in the IO APIC. -void ioAPIC_setEntry(uint8_t *base, uint8_t index, uint64_t data) { - ioAPIC_write(base, IO_APIC_REDTBL + index * 2, (uint32_t)data); - ioAPIC_write(base, IO_APIC_REDTBL + index * 2 + 1, (uint32_t)(data >> 32)); -} - -// ioAPIC_init() - Initialize the IO APIC. -void ioAPIC_init() { - // Make sure ACPI actually set this variable - if (ioAPIC_addr == 0x0) { - serialPrintf("ioAPIC_init: Cannot initialize I/O APIC when ioAPIC_addr == 0x0\n"); - return; - } - - // First, get the number of entries supported by the IO APIC. - uint32_t x = ioAPIC_read(ioAPIC_addr, IO_APIC_VER); - uint32_t count = ((x >> 16) & 0xFF) + 1; - - // serialPrintf("ioAPIC_init: got %d entries supported for the IO APIC\n", count); - - // Disable all entries. - for (uint32_t i = 0; i < count; i++) { ioAPIC_setEntry(ioAPIC_addr, i, 1 << 16); } -} \ No newline at end of file +// ======================================================= +// io_apic.c - Handles setting up the I/O APIC. +// ======================================================= +// This file is a part of the reduceOS C kernel. Please credit me if you use this code. + +#include // Main header file + +// (copy and pasted from local_apic.c) +// First, what is the local APIC? Well, APIC stands for "Advanced Programmable Interrupt Controller", or a newer version of the 8259 PIC chip. +// Intel's more recent processors now use the APIC standard, so it's essential to implement in a kernel. +// Second, why is it a "local" APIC? There are two versions of the APIC, IO and local. +// In an APIC-based system (either with a more recent processor or a multiprocessor system), each CPU is made of a core and local APIC. +// The local APIC is responsible for handling CPU-specific interrupt configuration and a little more. The IO APIC is part of the chipset and provides multi-processor interrupt management. +// https://wiki.osdev.org/APIC + + +// Global variables +uint8_t *ioAPIC_addr = 0x0; // SHOULD BE SET BY ACPI + +// Static functions + +// (static) ioAPIC_write(uint8_t *base, uint8_t reg, uint32_t val) - Write to the IO APIC. +static void ioAPIC_write(uint8_t *base, uint8_t reg, uint32_t val) { + *(volatile uint32_t *)(base + IO_APIC_REGSEL) = reg; + *(volatile uint32_t *)(base + IO_APIC_WIN) = val; +} + +// (static) ioAPIC_read(uint8_t *base, uint8_t reg) - Read from the IO APIC. +static uint32_t ioAPIC_read(uint8_t *base, uint8_t reg) { + *(volatile uint32_t *)(base + IO_APIC_REGSEL) = reg; + return *(volatile uint32_t *)(base + IO_APIC_WIN); +} + +// Functions. + +// ioAPIC_setEntry(uint8_t *base, uint8_t index, uint64_t data) - Set an entry in the IO APIC. +void ioAPIC_setEntry(uint8_t *base, uint8_t index, uint64_t data) { + ioAPIC_write(base, IO_APIC_REDTBL + index * 2, (uint32_t)data); + ioAPIC_write(base, IO_APIC_REDTBL + index * 2 + 1, (uint32_t)(data >> 32)); +} + +// ioAPIC_init() - Initialize the IO APIC. +void ioAPIC_init() { + // Make sure ACPI actually set this variable + if (ioAPIC_addr == 0x0) { + serialPrintf("ioAPIC_init: Cannot initialize I/O APIC when ioAPIC_addr == 0x0\n"); + return; + } + + // First, get the number of entries supported by the IO APIC. + uint32_t x = ioAPIC_read(ioAPIC_addr, IO_APIC_VER); + uint32_t count = ((x >> 16) & 0xFF) + 1; + + // serialPrintf("ioAPIC_init: got %d entries supported for the IO APIC\n", count); + + // Disable all entries. + for (uint32_t i = 0; i < count; i++) { ioAPIC_setEntry(ioAPIC_addr, i, 1 << 16); } +} diff --git a/source/kernel/drivers/keyboard.c b/source/kernel/drivers/keyboard.c index 29623969..44b478c4 100644 --- a/source/kernel/drivers/keyboard.c +++ b/source/kernel/drivers/keyboard.c @@ -1,285 +1,285 @@ -// ============================================= -// keyboard.c - reduceOS keyboard driver -// ============================================= -// This file is a part of the reduceOS C kernel. Please credit me if you use it. - -#include "include/keyboard.h" // Main include file - -static bool isEnabled = true; // As mentioned in keyboard.h, this header file contains definitions for special scancodes and other things. -static bool shiftKey = false; // Shift, caps lock, and ctrl key handling. -static bool capsLock = false; -static bool ctrlPressed = false; -static bool printChars = true; - - -char bufferPointer[256]; -int bindex = 0; -bool newline = false; - -// Making life so much easier for me. Instead of manually switching between the scancodes in a switch() statement, just match them to this! So much easier. -const char scancodeChars[] = { - '\0', '\0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', - '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', - '\0', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', '\0', - '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', '\0', '\0', '\0' -}; - -char ch = '\0'; // The char we will output. You may be wondering why it is declared here instead of in keyboardHandler() - that's because a few other functions need access to this variable. - - -// setKBHandler(bool state) - Changes if the keyboard handler is allowed to save characters. -// Dev notes: Possibly add some special keycodes (like CTRL + C) that can pause the boot process or do something (therefore bypassing this). -void setKBHandler(bool state) { isEnabled = state; } - -// setKBPrintChars(bool state) - Changes if the keyboard handler is allowed to output characters. -void setKBPrintChars(bool state) { printChars = state; } - -// getControl() - Returns whether control is down -bool getControl() { return ctrlPressed; } - - -char altChars(char ch) { - switch (ch) { - case '`': return '~'; - case '1': return '!'; - case '2': return '@'; - case '3': return '#'; - case '4': return '$'; - case '5': return '%'; - case '6': return '^'; - case '7': return '&'; - case '8': return '*'; - case '9': return '('; - case '0': return ')'; - case '-': return '_'; - case '=': return '+'; - case '[': return '{'; - case ']': return '}'; - case '\\': return '|'; - case ';': return ':'; - case '\'': return '\"'; - case ',': return '<'; - case '.': return '>'; - case '/': return '?'; - default: return ch; - } -} - - - -// keyboardRegisterKeyPress(char key) - Registers that a key was pressed. -void keyboardRegisterKeyPress(char key) { - - if (key == '\n') { - newline = true; - } else if (key == '\b' && bindex != 0) { - bufferPointer[bindex-1] = '\0'; - bindex--; - } else { - bufferPointer[bindex] = key; - bindex++; - } - -} - -void keyboardWaitForNewline() { - while (!newline); - newline = false; - - return; -} - -// keyboardHandler(registers_t *r) - The handler assigned by keyboardInitialize to IRQ 33. Handles all scancode stuff. -static void keyboardHandler(registers_t *r) { - uint8_t scancode = inportb(0x60); // No matter if the handler is enabled or not, we need to read from port 0x60 or the keyboard might stop responding. - - if (!isEnabled) { return; } // Do not continue if not enabled. - - - if (scancode & 0x80) { - // This signifies a key was released. We don't care UNLESS it's the shift key or control key. Then we care. - if (scancode == 0xAA || scancode == 0xB6) { // Left or right shift key was released - shiftKey = false; - } - - if (scancode == 0x9D) { - ctrlPressed = false; - } - ch = '\0'; - } else { - switch (scancode) { - case SCANCODE_CAPSLOCK: - ch = '\0'; - if (capsLock) { capsLock = false; } - else { - capsLock = true; - } - break; - - case SCANCODE_ENTER: - ch = '\n'; - break; - - case SCANCODE_LEFTSHIFT: - ch = '\0'; - shiftKey = true; - break; - - case SCANCODE_RIGHTSHIFT: - ch = '\0'; - shiftKey = true; - break; - - case SCANCODE_CTRL: - ch = '\0'; - ctrlPressed = true; - break; - - case SCANCODE_TAB: - ch = '\t'; - break; - - case SCANCODE_LEFT: - ch = '\0'; - terminalMoveArrowKeys(0); - break; - - case SCANCODE_RIGHT: - ch = '\0'; - terminalMoveArrowKeys(1); - break; - - case SCANCODE_SPACE: - ch = ' '; - break; - - case SCANCODE_BACKSPACE: - ch = '\b'; // \b will tell terminalPutchar() to handle this. - break; - - default: - ch = scancodeChars[(int) scancode]; - if (capsLock) { - if (shiftKey) { ch = altChars(ch); } // If SHIFT key is also pressed, do nothing except convert to alternate chars. - else { ch = toupper(ch); } // Else, convert to upper case. - } else { - if (shiftKey) { - if (isalpha(ch)) ch = toupper(ch); - else { ch = altChars(ch); } - } - } - } - } - - // keyboardGetChar() will handle getting the char and returning it (for the shell). - // Before we return we need to report that the key was pressed. - if (ch <= 0 || ch == '\0') { - // Do nothing if ch is 0 or \n. - } else { - keyboardRegisterKeyPress(ch); - if (printChars) { - terminalPutchar(ch); - vbeSwitchBuffers(); // sorry - } - } - - return; -} - - -// keyboardGetChar() - Returns the character currently present in ch- only if the character is NOT a \0 (signifying the end) -char keyboardGetChar() { - char c; // Our return value - while (true) { - if (ch == '\0') { - //printf(NULL); // UNKNOWN BUG: For some reason, we have to do something whenever this is called, or it doesn't return. I don't know why and I hope this will be fixed later. - } else { - c = ch; // Update c and ch to have proper values. - ch = 0; - break; - } - } - return c; -} - -// Custom method to wait for a character or until when ctrl is pressed, and then it returns -1. -char keyboardGetChar_ctrl() { - char c; - while (true) { - if (ch != '\0') { - c = ch; - ch = 0; - return c; - } - - if (ctrlPressed) { - return -1; - } - } -} - -// isKeyPressed() - A small method to return the key currently being pressed (if any) -char isKeyPressed() { - return ch; -} - - -// clearBuffer() - Clears the keyboard buffer. -void clearBuffer() { - memset(bufferPointer, 0, sizeof(char) * 256); - bindex = 0; -} - - -// keyboardGetKey() - Waits until a specific key is pressed and returns it. -// We leave this one because it can usually keep up. -void keyboardGetKey(char key, bool doPrintChars) { - bool previousPrintValue = printChars; // We will restore this value after we're done. - setKBPrintChars(doPrintChars); // Set KB print chars to whatever they want. - - - // A few special keys can be passed to this function. - // If \e is passed, wait for ENTER (ch is '\n'). If \s is passed, wait for SHIFT (shiftKey is true.). - // If \c is passed, wait for CTRL (ctrlPressed is true). - - if (key == '\e') { - while (keyboardGetChar() != '\n'); - setKBPrintChars(previousPrintValue); - return; - } else if (key == '\s') { - while (!shiftKey); - setKBPrintChars(previousPrintValue); - return; - } else if (key == '\c') { - while (!ctrlPressed); - setKBPrintChars(previousPrintValue); - return; - } else { - while(keyboardGetChar() != key); - setKBPrintChars(previousPrintValue); - return; - } - - -} - -char *getKeyboardBuffer() { - return bufferPointer; -} - -// keyboardGetLine() - A better version of keyboardGetInput that waits until ENTER key is pressed, and then sends it back (it never actually sends it back, only edits a buffer provided). -void keyboardGetLine(char *buffer) { - keyboardWaitForNewline(); - strcpy(buffer, bufferPointer); - clearBuffer(); - bindex = 0; - return; -} - - - -// keyboardInitialize() - Main function that loads the keyboard -void keyboardInitialize() { - isrRegisterInterruptHandler(33, keyboardHandler); // Register IRQ 33 as an ISR interrupt handler value. - printf("Keyboard driver initialized.\n"); -} \ No newline at end of file +// ============================================= +// keyboard.c - reduceOS keyboard driver +// ============================================= +// This file is a part of the reduceOS C kernel. Please credit me if you use it. + +#include // Main include file + +static bool isEnabled = true; // As mentioned in keyboard.h, this header file contains definitions for special scancodes and other things. +static bool shiftKey = false; // Shift, caps lock, and ctrl key handling. +static bool capsLock = false; +static bool ctrlPressed = false; +static bool printChars = true; + + +char bufferPointer[256]; +int bindex = 0; +bool newline = false; + +// Making life so much easier for me. Instead of manually switching between the scancodes in a switch() statement, just match them to this! So much easier. +const char scancodeChars[] = { + '\0', '\0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', + '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', + '\0', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', '\0', + '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', '\0', '\0', '\0' +}; + +char ch = '\0'; // The char we will output. You may be wondering why it is declared here instead of in keyboardHandler() - that's because a few other functions need access to this variable. + + +// setKBHandler(bool state) - Changes if the keyboard handler is allowed to save characters. +// Dev notes: Possibly add some special keycodes (like CTRL + C) that can pause the boot process or do something (therefore bypassing this). +void setKBHandler(bool state) { isEnabled = state; } + +// setKBPrintChars(bool state) - Changes if the keyboard handler is allowed to output characters. +void setKBPrintChars(bool state) { printChars = state; } + +// getControl() - Returns whether control is down +bool getControl() { return ctrlPressed; } + + +char altChars(char ch) { + switch (ch) { + case '`': return '~'; + case '1': return '!'; + case '2': return '@'; + case '3': return '#'; + case '4': return '$'; + case '5': return '%'; + case '6': return '^'; + case '7': return '&'; + case '8': return '*'; + case '9': return '('; + case '0': return ')'; + case '-': return '_'; + case '=': return '+'; + case '[': return '{'; + case ']': return '}'; + case '\\': return '|'; + case ';': return ':'; + case '\'': return '\"'; + case ',': return '<'; + case '.': return '>'; + case '/': return '?'; + default: return ch; + } +} + + + +// keyboardRegisterKeyPress(char key) - Registers that a key was pressed. +void keyboardRegisterKeyPress(char key) { + + if (key == '\n') { + newline = true; + } else if (key == '\b' && bindex != 0) { + bufferPointer[bindex-1] = '\0'; + bindex--; + } else { + bufferPointer[bindex] = key; + bindex++; + } + +} + +void keyboardWaitForNewline() { + while (!newline); + newline = false; + + return; +} + +// keyboardHandler(registers_t *r) - The handler assigned by keyboardInitialize to IRQ 33. Handles all scancode stuff. +static void keyboardHandler(registers_t *r) { + uint8_t scancode = inportb(0x60); // No matter if the handler is enabled or not, we need to read from port 0x60 or the keyboard might stop responding. + + if (!isEnabled) { return; } // Do not continue if not enabled. + + + if (scancode & 0x80) { + // This signifies a key was released. We don't care UNLESS it's the shift key or control key. Then we care. + if (scancode == 0xAA || scancode == 0xB6) { // Left or right shift key was released + shiftKey = false; + } + + if (scancode == 0x9D) { + ctrlPressed = false; + } + ch = '\0'; + } else { + switch (scancode) { + case SCANCODE_CAPSLOCK: + ch = '\0'; + if (capsLock) { capsLock = false; } + else { + capsLock = true; + } + break; + + case SCANCODE_ENTER: + ch = '\n'; + break; + + case SCANCODE_LEFTSHIFT: + ch = '\0'; + shiftKey = true; + break; + + case SCANCODE_RIGHTSHIFT: + ch = '\0'; + shiftKey = true; + break; + + case SCANCODE_CTRL: + ch = '\0'; + ctrlPressed = true; + break; + + case SCANCODE_TAB: + ch = '\t'; + break; + + case SCANCODE_LEFT: + ch = '\0'; + terminalMoveArrowKeys(0); + break; + + case SCANCODE_RIGHT: + ch = '\0'; + terminalMoveArrowKeys(1); + break; + + case SCANCODE_SPACE: + ch = ' '; + break; + + case SCANCODE_BACKSPACE: + ch = '\b'; // \b will tell terminalPutchar() to handle this. + break; + + default: + ch = scancodeChars[(int) scancode]; + if (capsLock) { + if (shiftKey) { ch = altChars(ch); } // If SHIFT key is also pressed, do nothing except convert to alternate chars. + else { ch = toupper(ch); } // Else, convert to upper case. + } else { + if (shiftKey) { + if (isalpha(ch)) ch = toupper(ch); + else { ch = altChars(ch); } + } + } + } + } + + // keyboardGetChar() will handle getting the char and returning it (for the shell). + // Before we return we need to report that the key was pressed. + if (ch <= 0 || ch == '\0') { + // Do nothing if ch is 0 or \n. + } else { + keyboardRegisterKeyPress(ch); + if (printChars) { + terminalPutchar(ch); + vbeSwitchBuffers(); // sorry + } + } + + return; +} + + +// keyboardGetChar() - Returns the character currently present in ch- only if the character is NOT a \0 (signifying the end) +char keyboardGetChar() { + char c; // Our return value + while (true) { + if (ch == '\0') { + //printf(NULL); // UNKNOWN BUG: For some reason, we have to do something whenever this is called, or it doesn't return. I don't know why and I hope this will be fixed later. + } else { + c = ch; // Update c and ch to have proper values. + ch = 0; + break; + } + } + return c; +} + +// Custom method to wait for a character or until when ctrl is pressed, and then it returns -1. +char keyboardGetChar_ctrl() { + char c; + while (true) { + if (ch != '\0') { + c = ch; + ch = 0; + return c; + } + + if (ctrlPressed) { + return -1; + } + } +} + +// isKeyPressed() - A small method to return the key currently being pressed (if any) +char isKeyPressed() { + return ch; +} + + +// clearBuffer() - Clears the keyboard buffer. +void clearBuffer() { + memset(bufferPointer, 0, sizeof(char) * 256); + bindex = 0; +} + + +// keyboardGetKey() - Waits until a specific key is pressed and returns it. +// We leave this one because it can usually keep up. +void keyboardGetKey(char key, bool doPrintChars) { + bool previousPrintValue = printChars; // We will restore this value after we're done. + setKBPrintChars(doPrintChars); // Set KB print chars to whatever they want. + + + // A few special keys can be passed to this function. + // If \e is passed, wait for ENTER (ch is '\n'). If \s is passed, wait for SHIFT (shiftKey is true.). + // If \c is passed, wait for CTRL (ctrlPressed is true). + + if (key == '\e') { + while (keyboardGetChar() != '\n'); + setKBPrintChars(previousPrintValue); + return; + } else if (key == '\s') { + while (!shiftKey); + setKBPrintChars(previousPrintValue); + return; + } else if (key == '\c') { + while (!ctrlPressed); + setKBPrintChars(previousPrintValue); + return; + } else { + while(keyboardGetChar() != key); + setKBPrintChars(previousPrintValue); + return; + } + + +} + +char *getKeyboardBuffer() { + return bufferPointer; +} + +// keyboardGetLine() - A better version of keyboardGetInput that waits until ENTER key is pressed, and then sends it back (it never actually sends it back, only edits a buffer provided). +void keyboardGetLine(char *buffer) { + keyboardWaitForNewline(); + strcpy(buffer, bufferPointer); + clearBuffer(); + bindex = 0; + return; +} + + + +// keyboardInitialize() - Main function that loads the keyboard +void keyboardInitialize() { + isrRegisterInterruptHandler(33, keyboardHandler); // Register IRQ 33 as an ISR interrupt handler value. + printf("Keyboard driver initialized.\n"); +} diff --git a/source/kernel/drivers/local_apic.c b/source/kernel/drivers/local_apic.c index 38aeb6c1..e0c60411 100644 --- a/source/kernel/drivers/local_apic.c +++ b/source/kernel/drivers/local_apic.c @@ -1,77 +1,77 @@ -// ======================================================= -// local_apic.c - Handles setting up the local APIC. -// ======================================================= -// This file is a part of the reduceOS C kernel. Please credit me if you use this code. - -#include "include/local_apic.h" // Main header file - - - -// First, what is the local APIC? Well, APIC stands for "Advanced Programmable Interrupt Controller", or a newer version of the 8259 PIC chip. -// Intel's more recent processors now use the APIC standard, so it's essential to implement in a kernel. -// Second, why is it a "local" APIC? There are two versions of the APIC, IO and local. -// In an APIC-based system (either with a more recent processor or a multiprocessor system), each CPU is made of a core and local APIC. -// The local APIC is responsible for handling CPU-specific interrupt configuration and a little more. The IO APIC is part of the chipset and provides multi-processor interrupt management. -// https://wiki.osdev.org/APIC - -// NOTE: localAPICAddress should be defined by the ACPI and/or linker script! -uint8_t *localAPICAddress = 0x0; - -// Now, onto the static functions! - -// (static) localAPIC_read(uint32_t reg) - Reads from the local APIC. -static uint32_t localAPIC_read(uint32_t reg) { - return *(volatile uint32_t *)(localAPICAddress + reg); -} - -// (static) localAPIC_write(uint32_t reg, uint32_t data) -static void localAPIC_write(uint32_t reg, uint32_t data) { - *(volatile uint32_t *)(localAPICAddress + reg) = data; -} - -// And finally, the main funtcions: - - -// localAPIC_init() - Initialize the local APIC -void localAPIC_init() { - // Make sure ACPI actually set something - if (localAPICAddress == 0x0) { - serialPrintf("localAPIC_init: Cannot initialize if localAPIC is 0x0.\n"); - return; - } - - // Clear task priority to enable all interrupts. - localAPIC_write(LOCAL_APIC_TPR, 0); - - // Enable logical destination mode - localAPIC_write(LOCAL_APIC_DFR, 0xFFFFFFFF); // Flat mode - localAPIC_write(LOCAL_APIC_LDR, 0x01000000); // All CPUs use logical ID 1 - - // Configure the SPI register. - localAPIC_write(LOCAL_APIC_SVR, 0x100 | 0xFF); -} - - -// localAPIC_getID() - returns the ID of the local APIC. -uint8_t localAPIC_getID() { - return localAPIC_read(LOCAL_APIC_ID) >> 24; -} - -// localAPIC_sendInit(uint8_t apicID) - Sends an init request to local APIC. -void localAPIC_sendInit(uint8_t apicID) { - localAPIC_write(LOCAL_APIC_ICRHI, apicID << ICR_DESTINATION_SHIFT); - localAPIC_write(LOCAL_APIC_ICRLO, ICR_INIT | ICR_PHYSICAL | ICR_ASSERT | ICR_EDGE | ICR_NO_SHORTHAND); - - // Wait until APIC is done. - while (localAPIC_read(LOCAL_APIC_ICRLO) & ICR_SEND_PENDING); -} - - -// localAPIC_sendStartup(uint8_t apicID, uint8_t vector) - Sends a startup request to an APIC with a vector. -void localAPIC_sendStartup(uint8_t apicID, uint8_t vector) { - localAPIC_write(LOCAL_APIC_ICRHI, apicID << ICR_DESTINATION_SHIFT); - localAPIC_write(LOCAL_APIC_ICRLO, vector | ICR_STARTUP | ICR_PHYSICAL | ICR_ASSERT | ICR_EDGE | ICR_NO_SHORTHAND); - - while (localAPIC_read(LOCAL_APIC_ICRLO) & ICR_SEND_PENDING); -} - +// ======================================================= +// local_apic.c - Handles setting up the local APIC. +// ======================================================= +// This file is a part of the reduceOS C kernel. Please credit me if you use this code. + +#include // Main header file + + + +// First, what is the local APIC? Well, APIC stands for "Advanced Programmable Interrupt Controller", or a newer version of the 8259 PIC chip. +// Intel's more recent processors now use the APIC standard, so it's essential to implement in a kernel. +// Second, why is it a "local" APIC? There are two versions of the APIC, IO and local. +// In an APIC-based system (either with a more recent processor or a multiprocessor system), each CPU is made of a core and local APIC. +// The local APIC is responsible for handling CPU-specific interrupt configuration and a little more. The IO APIC is part of the chipset and provides multi-processor interrupt management. +// https://wiki.osdev.org/APIC + +// NOTE: localAPICAddress should be defined by the ACPI and/or linker script! +uint8_t *localAPICAddress = 0x0; + +// Now, onto the static functions! + +// (static) localAPIC_read(uint32_t reg) - Reads from the local APIC. +static uint32_t localAPIC_read(uint32_t reg) { + return *(volatile uint32_t *)(localAPICAddress + reg); +} + +// (static) localAPIC_write(uint32_t reg, uint32_t data) +static void localAPIC_write(uint32_t reg, uint32_t data) { + *(volatile uint32_t *)(localAPICAddress + reg) = data; +} + +// And finally, the main funtcions: + + +// localAPIC_init() - Initialize the local APIC +void localAPIC_init() { + // Make sure ACPI actually set something + if (localAPICAddress == 0x0) { + serialPrintf("localAPIC_init: Cannot initialize if localAPIC is 0x0.\n"); + return; + } + + // Clear task priority to enable all interrupts. + localAPIC_write(LOCAL_APIC_TPR, 0); + + // Enable logical destination mode + localAPIC_write(LOCAL_APIC_DFR, 0xFFFFFFFF); // Flat mode + localAPIC_write(LOCAL_APIC_LDR, 0x01000000); // All CPUs use logical ID 1 + + // Configure the SPI register. + localAPIC_write(LOCAL_APIC_SVR, 0x100 | 0xFF); +} + + +// localAPIC_getID() - returns the ID of the local APIC. +uint8_t localAPIC_getID() { + return localAPIC_read(LOCAL_APIC_ID) >> 24; +} + +// localAPIC_sendInit(uint8_t apicID) - Sends an init request to local APIC. +void localAPIC_sendInit(uint8_t apicID) { + localAPIC_write(LOCAL_APIC_ICRHI, apicID << ICR_DESTINATION_SHIFT); + localAPIC_write(LOCAL_APIC_ICRLO, ICR_INIT | ICR_PHYSICAL | ICR_ASSERT | ICR_EDGE | ICR_NO_SHORTHAND); + + // Wait until APIC is done. + while (localAPIC_read(LOCAL_APIC_ICRLO) & ICR_SEND_PENDING); +} + + +// localAPIC_sendStartup(uint8_t apicID, uint8_t vector) - Sends a startup request to an APIC with a vector. +void localAPIC_sendStartup(uint8_t apicID, uint8_t vector) { + localAPIC_write(LOCAL_APIC_ICRHI, apicID << ICR_DESTINATION_SHIFT); + localAPIC_write(LOCAL_APIC_ICRLO, vector | ICR_STARTUP | ICR_PHYSICAL | ICR_ASSERT | ICR_EDGE | ICR_NO_SHORTHAND); + + while (localAPIC_read(LOCAL_APIC_ICRLO) & ICR_SEND_PENDING); +} + diff --git a/source/kernel/drivers/pci.c b/source/kernel/drivers/pci.c index 2debf825..4858838e 100644 --- a/source/kernel/drivers/pci.c +++ b/source/kernel/drivers/pci.c @@ -1,267 +1,267 @@ -// =================================================================== -// pci.c - Handles the Peripheral Component Interconnect (PCI) bus -// =================================================================== -// This file is a part of the reduceOS C kernel. Please credit me if you use it. - -// For more information on this topic, check https://wiki.osdev.org/PCI - -#include "include/pci.h" // Main header file - -// TODO: Implement support for different header types, we always assume header type 0x0. - -bool isPCIInitialized = false; // In case a function is ever called before initPCI is called, it knows to automatically call initPCI. - -pciDevice *pciDevices[32]; -uint32_t dev_idx = 0; - -pciDriver **pciDrivers = 0; -uint32_t drv_idx = 0; - -// pciConfigRead(uint16_t bus, uint16_t slot, uint16_t func, uint16_t offset) - Handles reading a PCI configuration. -uint32_t pciConfigRead(uint16_t bus, uint16_t slot, uint16_t func, uint16_t offset) { - // pci.h gives some vague descriptions of PCI_CONFIG_ADDR and PCI_CONFIG_DATA - here's a little more detail. - // To get PCI config data, we need to first send PCI_CONFIG_ADDR (0xCF8) a proper address of the PCI component we want to access (composed of a bus, slot, offset, and 0x80000000) - // This tells PCI_CONFIG_DATA where to read the data from. We send a read request to PCI_CONFIG_DATA, and it returns the data we want. - - // First, convert bus, slot, and func to uint64_t type - uint64_t addr; - uint64_t long_bus = (uint64_t)bus; - uint64_t long_slot = (uint64_t)slot; - uint64_t long_func = (uint64_t)func; - - // Now, calculate and send our PCI device addr. - addr = (uint64_t)((long_bus << 16) | (long_slot << 11) | (long_func << 8) | (offset & 0xFC) | ((uint32_t)0x80000000)); - outportl(PCI_CONFIG_ADDR, addr); - - uint32_t output = (uint32_t)((inportl(PCI_CONFIG_DATA) >> ((offset & 2) * 8)) & 0xFFFF); - return output; -} - -// pciConfigWrite(uint32_t bus, uint32_t slot, uint32_t offset, uint32_t value) - Write to a PCI configuration. -void pciConfigWrite(uint32_t bus, uint32_t slot, uint32_t offset, uint32_t value) { - if (isPCIInitialized) { - outportl(PCI_CONFIG_ADDR, bus); - outportl(PCI_CONFIG_ADDR, 0xF0); - outportl(0xC000 | (slot << 8) | offset, value); // 0xC000 is the start of a PCI IO configuration - } else { - // initPCI has not been called yet. - outportl(PCI_CONFIG_ADDR, (0x80000000 | (bus << 16) | (slot << 11) | offset)); - outportl(PCI_CONFIG_DATA, value); - } -} - - -// pciConfigReadField(uint32_t device, int field, int size) - A simplified version of pciConfigRead() that will take 3 parameters and read from a PCI device config space field. -uint32_t pciConfigReadField(uint32_t device, int field, int size) { - outportl(PCI_CONFIG_ADDR, PCI_ADDR(device, field)); - - if (size == 4) { - return inportl(PCI_CONFIG_DATA); - } else if (size == 2) { - uint16_t r = inportw(PCI_CONFIG_DATA) + (field & 2); - return r; - } else if (size == 1) { - uint8_t r = inportb(PCI_CONFIG_DATA + (field & 3)); - return r; - } - - return PCI_NONE; // Error -} - - -/* PCI SCANNING - Scans the PCI buses for devices and calls the given function for each device */ - -// (static) pciScanHit(pciFunction_t func, uint32_t device, void *extra) - Calls the function for the device -static void pciScanHit(pciFunction_t func, uint32_t device, void *extra) { - int dev_vend = (int)pciConfigReadField(device, PCI_OFFSET_VENDORID, 2); - int dev_dvid = (int)pciConfigReadField(device, PCI_OFFSET_DEVICEID, 2); - - func(device, dev_vend, dev_dvid, extra); -} - -// pciScanFunc(pciFunction_t f, int type, int bus, int slot, int func, void *extra) - Scans the slots for a device -void pciScanFunc(pciFunction_t f, int type, int bus, int slot, int func, void *extra) { - uint32_t device = (uint32_t)((bus << 16) | (slot << 8) | func); - uint32_t device_type = ((pciConfigReadField(device, PCI_OFFSET_VENDORID, 2) << 8) | pciConfigReadField(device, PCI_OFFSET_SUBCLASSID, 1)); - - if (type == -1 || type == device_type) pciScanHit(f, device, extra); - - if (device_type == PCI_TYPE_BRIDGE) pciScanBus(f, type, pciConfigReadField(device, PCI_SECONDARY_BUS, 1), extra); -} - - -// pciScanSlot(pciFunction_t func, int type, int bus, int slot, void *extra) - Scans a slot for a device -void pciScanSlot(pciFunction_t func, int type, int bus, int slot, void *extra) { - uint32_t device = (uint32_t)((bus << 16) | (slot << 8) | 0); - - if (pciConfigReadField(device, PCI_OFFSET_VENDORID, 2) == PCI_NONE) { - return; - } - - pciScanFunc(func, type, bus, slot, 0, extra); - if (!pciConfigReadField(device, PCI_OFFSET_HEADERTYPE, 1)) return; - - for (int f = 0; f < 8; f++) { - uint32_t device = (uint32_t)((bus << 16) | (slot << 8) | f); - if (pciConfigReadField(device, PCI_OFFSET_VENDORID, 2) != PCI_NONE) { - pciScanFunc(func, type, bus, slot, f, extra); - } - } -} - - -// pciScanBus(pciFunction_t func, int type, int bus, void *extra) - Scans each slot on the bus for a device -void pciScanBus(pciFunction_t func, int type, int bus, void *extra) { - for (int slot = 0; slot < PCI_MAX_SLOTS; slot++) { - pciScanSlot(func, type, bus, slot, extra); - } -} - - -// pciScan(pciFunction_t func, int type, void *extra) - Scans the PCI buses for devices (used to implement device discovery) -void pciScan(pciFunction_t func, int type, void *extra) { - if ((pciConfigReadField(0, PCI_OFFSET_HEADERTYPE, 1) & 0x80) == 0) { - pciScanBus(func, type, 0, extra); - return; - } - - int hit = 0; - for (int f = 0; f < 8; f++) { - uint32_t dev = (uint32_t)((0 << 16) | (0 << 8) | f); - if (pciConfigReadField(dev, PCI_OFFSET_VENDORID, 2) != PCI_NONE) { - hit = 1; - pciScanBus(func, type, f, extra); - } else { - break; - } - } - - if (!hit) { - for (int bus = 0; bus < 256; bus++) { - for (int slot = 0; slot < PCI_MAX_SLOTS; slot++) { - pciScanSlot(func, type, bus, slot, extra); - } - } - } -} - - -uint16_t pciGetVendorID(uint16_t bus, uint16_t device, uint16_t function) { - return (uint16_t)pciConfigRead(bus, device, function, PCI_OFFSET_VENDORID); -} - - - -uint16_t pciGetDeviceID(uint16_t bus, uint16_t device, uint16_t function) { - return (uint16_t)pciConfigRead(bus, device, function, PCI_OFFSET_DEVICEID); -} - -uint16_t pciGetClassID(uint16_t bus, uint16_t device, uint16_t function) { - return (uint16_t)(((uint32_t)pciConfigRead(bus, device, function, PCI_OFFSET_CLASSID)) & ~0x00FF) >> 8; -} - -uint16_t pciGetSubClassID(uint16_t bus, uint16_t device, uint16_t function) { - return (uint16_t)(((uint32_t)pciConfigRead(bus, device, function, PCI_OFFSET_SUBCLASSID)) & ~0xFF00); -} - -void pciProbeForDevices() { - for (uint32_t bus = 0; bus < 256; bus++) { - for (uint32_t slot = 0; slot < 32; slot++) { - for (uint32_t func = 0; func < 8; func++) { - uint16_t vendor = pciGetVendorID(bus, slot, func); - if (vendor == 0xFFFF) continue; // Not a PCI device - uint16_t deviceID = pciGetDeviceID(bus, slot, func); - - - serialPrintf("pciProbeForDevices: Found PCI device (function = 0x%x, vendor ID = 0x%x, device ID = 0x%x)\n", func, vendor, deviceID); - - pciDevice *dev = (pciDevice*)kmalloc(sizeof(pciDevice)); - dev->device = deviceID; - dev->driver = 0; - dev->func = func; - dev->vendor = vendor; - dev->bus = bus; - dev->slot = slot; - - - pciDevices[dev_idx] = dev; - dev_idx++; - } - } - } -} - - -void initPCI() { - if (isPCIInitialized) return; // Stupid users - - // Allocate memory for devices and drivers - pciDrivers = (pciDriver**)kmalloc(32 * sizeof(pciDriver)); - - // Probe PCI devices - pciProbeForDevices(); - - // Make sure the functions know initialization has completed. - isPCIInitialized = true; - printf("PCI handler initialized.\n"); -} - -int getDevTableId(uint32_t deviceID, uint32_t vendorID) { - int id = -1; - for (int i = 0; i < PCI_DEVTABLE_LEN; i++) { - if (PciDevTable[i].DevId == deviceID && PciDevTable[i].VenId == vendorID) { - id = i; - break; - } - } - - return id; -} - -int getClassIdType(uint16_t classID, uint16_t subclassID) { - int id = -1; - - for (int i = 0; i < PCI_CLASSCODETABLE_LEN; i++) { - if (PciClassCodeTable[i].BaseClass == classID && PciClassCodeTable[i].SubClass == subclassID) { - id = i; - break; - } - } - - return id; -} - -void printPCIInfo() { - - for (int i = 0; i < dev_idx; i++) { - - // Get the class type - uint16_t classID = pciGetClassID(pciDevices[i]->bus, pciDevices[i]->slot, pciDevices[i]->func); - uint16_t subclassID = pciGetSubClassID(pciDevices[i]->bus, pciDevices[i]->slot, pciDevices[i]->func); - int classTypeId = getClassIdType(classID, subclassID); - - int id = getDevTableId(pciDevices[i]->device, pciDevices[i]->vendor); - if (id != -1 && classTypeId != -1) { - if (PciClassCodeTable[classTypeId].ProgDesc != "") { - printf("%i) %s %s (%s - %s - %s)\n", i, PciDevTable[id].Chip, PciDevTable[i].ChipDesc, PciClassCodeTable[classTypeId].BaseDesc, PciClassCodeTable[classTypeId].SubDesc, PciClassCodeTable[classTypeId].ProgDesc); - } else { - printf("%i) %s %s (%s - %s)\n", i, PciDevTable[id].Chip, PciDevTable[i].ChipDesc, PciClassCodeTable[classTypeId].BaseDesc, PciClassCodeTable[classTypeId].SubDesc); - } - } else if (classTypeId != -1) { - // We don't know the exact device type - that's ok, just print Unknown and the class type - if (PciClassCodeTable[classTypeId].ProgDesc != "") { - printf("%i) Unknown Device (%s - %s - %s)\n", i, PciClassCodeTable[classTypeId].BaseDesc, PciClassCodeTable[classTypeId].SubDesc, PciClassCodeTable[classTypeId].ProgDesc); - } else { - printf("%i) Unknown Device (%s - %s)\n", i, PciClassCodeTable[classTypeId].BaseDesc, PciClassCodeTable[classTypeId].SubDesc); - } - } else { - // We don't know anything. - printf("%i) Unknown Device (Unknown Class Type)\n", i); - } - - printf("\tVendor ID: 0x%x, Device ID: 0x%x\n", pciDevices[i]->vendor, pciDevices[i]->device); - // pciGetStatus(pciDevices[i]->bus, pciDevices[i]->slot, pciDevices[i]->func); - - } - -} \ No newline at end of file +// =================================================================== +// pci.c - Handles the Peripheral Component Interconnect (PCI) bus +// =================================================================== +// This file is a part of the reduceOS C kernel. Please credit me if you use it. + +// For more information on this topic, check https://wiki.osdev.org/PCI + +#include // Main header file + +// TODO: Implement support for different header types, we always assume header type 0x0. + +bool isPCIInitialized = false; // In case a function is ever called before initPCI is called, it knows to automatically call initPCI. + +pciDevice *pciDevices[32]; +uint32_t dev_idx = 0; + +pciDriver **pciDrivers = 0; +uint32_t drv_idx = 0; + +// pciConfigRead(uint16_t bus, uint16_t slot, uint16_t func, uint16_t offset) - Handles reading a PCI configuration. +uint32_t pciConfigRead(uint16_t bus, uint16_t slot, uint16_t func, uint16_t offset) { + // pci.h gives some vague descriptions of PCI_CONFIG_ADDR and PCI_CONFIG_DATA - here's a little more detail. + // To get PCI config data, we need to first send PCI_CONFIG_ADDR (0xCF8) a proper address of the PCI component we want to access (composed of a bus, slot, offset, and 0x80000000) + // This tells PCI_CONFIG_DATA where to read the data from. We send a read request to PCI_CONFIG_DATA, and it returns the data we want. + + // First, convert bus, slot, and func to uint64_t type + uint64_t addr; + uint64_t long_bus = (uint64_t)bus; + uint64_t long_slot = (uint64_t)slot; + uint64_t long_func = (uint64_t)func; + + // Now, calculate and send our PCI device addr. + addr = (uint64_t)((long_bus << 16) | (long_slot << 11) | (long_func << 8) | (offset & 0xFC) | ((uint32_t)0x80000000)); + outportl(PCI_CONFIG_ADDR, addr); + + uint32_t output = (uint32_t)((inportl(PCI_CONFIG_DATA) >> ((offset & 2) * 8)) & 0xFFFF); + return output; +} + +// pciConfigWrite(uint32_t bus, uint32_t slot, uint32_t offset, uint32_t value) - Write to a PCI configuration. +void pciConfigWrite(uint32_t bus, uint32_t slot, uint32_t offset, uint32_t value) { + if (isPCIInitialized) { + outportl(PCI_CONFIG_ADDR, bus); + outportl(PCI_CONFIG_ADDR, 0xF0); + outportl(0xC000 | (slot << 8) | offset, value); // 0xC000 is the start of a PCI IO configuration + } else { + // initPCI has not been called yet. + outportl(PCI_CONFIG_ADDR, (0x80000000 | (bus << 16) | (slot << 11) | offset)); + outportl(PCI_CONFIG_DATA, value); + } +} + + +// pciConfigReadField(uint32_t device, int field, int size) - A simplified version of pciConfigRead() that will take 3 parameters and read from a PCI device config space field. +uint32_t pciConfigReadField(uint32_t device, int field, int size) { + outportl(PCI_CONFIG_ADDR, PCI_ADDR(device, field)); + + if (size == 4) { + return inportl(PCI_CONFIG_DATA); + } else if (size == 2) { + uint16_t r = inportw(PCI_CONFIG_DATA) + (field & 2); + return r; + } else if (size == 1) { + uint8_t r = inportb(PCI_CONFIG_DATA + (field & 3)); + return r; + } + + return PCI_NONE; // Error +} + + +/* PCI SCANNING - Scans the PCI buses for devices and calls the given function for each device */ + +// (static) pciScanHit(pciFunction_t func, uint32_t device, void *extra) - Calls the function for the device +static void pciScanHit(pciFunction_t func, uint32_t device, void *extra) { + int dev_vend = (int)pciConfigReadField(device, PCI_OFFSET_VENDORID, 2); + int dev_dvid = (int)pciConfigReadField(device, PCI_OFFSET_DEVICEID, 2); + + func(device, dev_vend, dev_dvid, extra); +} + +// pciScanFunc(pciFunction_t f, int type, int bus, int slot, int func, void *extra) - Scans the slots for a device +void pciScanFunc(pciFunction_t f, int type, int bus, int slot, int func, void *extra) { + uint32_t device = (uint32_t)((bus << 16) | (slot << 8) | func); + uint32_t device_type = ((pciConfigReadField(device, PCI_OFFSET_VENDORID, 2) << 8) | pciConfigReadField(device, PCI_OFFSET_SUBCLASSID, 1)); + + if (type == -1 || type == device_type) pciScanHit(f, device, extra); + + if (device_type == PCI_TYPE_BRIDGE) pciScanBus(f, type, pciConfigReadField(device, PCI_SECONDARY_BUS, 1), extra); +} + + +// pciScanSlot(pciFunction_t func, int type, int bus, int slot, void *extra) - Scans a slot for a device +void pciScanSlot(pciFunction_t func, int type, int bus, int slot, void *extra) { + uint32_t device = (uint32_t)((bus << 16) | (slot << 8) | 0); + + if (pciConfigReadField(device, PCI_OFFSET_VENDORID, 2) == PCI_NONE) { + return; + } + + pciScanFunc(func, type, bus, slot, 0, extra); + if (!pciConfigReadField(device, PCI_OFFSET_HEADERTYPE, 1)) return; + + for (int f = 0; f < 8; f++) { + uint32_t device = (uint32_t)((bus << 16) | (slot << 8) | f); + if (pciConfigReadField(device, PCI_OFFSET_VENDORID, 2) != PCI_NONE) { + pciScanFunc(func, type, bus, slot, f, extra); + } + } +} + + +// pciScanBus(pciFunction_t func, int type, int bus, void *extra) - Scans each slot on the bus for a device +void pciScanBus(pciFunction_t func, int type, int bus, void *extra) { + for (int slot = 0; slot < PCI_MAX_SLOTS; slot++) { + pciScanSlot(func, type, bus, slot, extra); + } +} + + +// pciScan(pciFunction_t func, int type, void *extra) - Scans the PCI buses for devices (used to implement device discovery) +void pciScan(pciFunction_t func, int type, void *extra) { + if ((pciConfigReadField(0, PCI_OFFSET_HEADERTYPE, 1) & 0x80) == 0) { + pciScanBus(func, type, 0, extra); + return; + } + + int hit = 0; + for (int f = 0; f < 8; f++) { + uint32_t dev = (uint32_t)((0 << 16) | (0 << 8) | f); + if (pciConfigReadField(dev, PCI_OFFSET_VENDORID, 2) != PCI_NONE) { + hit = 1; + pciScanBus(func, type, f, extra); + } else { + break; + } + } + + if (!hit) { + for (int bus = 0; bus < 256; bus++) { + for (int slot = 0; slot < PCI_MAX_SLOTS; slot++) { + pciScanSlot(func, type, bus, slot, extra); + } + } + } +} + + +uint16_t pciGetVendorID(uint16_t bus, uint16_t device, uint16_t function) { + return (uint16_t)pciConfigRead(bus, device, function, PCI_OFFSET_VENDORID); +} + + + +uint16_t pciGetDeviceID(uint16_t bus, uint16_t device, uint16_t function) { + return (uint16_t)pciConfigRead(bus, device, function, PCI_OFFSET_DEVICEID); +} + +uint16_t pciGetClassID(uint16_t bus, uint16_t device, uint16_t function) { + return (uint16_t)(((uint32_t)pciConfigRead(bus, device, function, PCI_OFFSET_CLASSID)) & ~0x00FF) >> 8; +} + +uint16_t pciGetSubClassID(uint16_t bus, uint16_t device, uint16_t function) { + return (uint16_t)(((uint32_t)pciConfigRead(bus, device, function, PCI_OFFSET_SUBCLASSID)) & ~0xFF00); +} + +void pciProbeForDevices() { + for (uint32_t bus = 0; bus < 256; bus++) { + for (uint32_t slot = 0; slot < 32; slot++) { + for (uint32_t func = 0; func < 8; func++) { + uint16_t vendor = pciGetVendorID(bus, slot, func); + if (vendor == 0xFFFF) continue; // Not a PCI device + uint16_t deviceID = pciGetDeviceID(bus, slot, func); + + + serialPrintf("pciProbeForDevices: Found PCI device (function = 0x%x, vendor ID = 0x%x, device ID = 0x%x)\n", func, vendor, deviceID); + + pciDevice *dev = (pciDevice*)kmalloc(sizeof(pciDevice)); + dev->device = deviceID; + dev->driver = 0; + dev->func = func; + dev->vendor = vendor; + dev->bus = bus; + dev->slot = slot; + + + pciDevices[dev_idx] = dev; + dev_idx++; + } + } + } +} + + +void initPCI() { + if (isPCIInitialized) return; // Stupid users + + // Allocate memory for devices and drivers + pciDrivers = (pciDriver**)kmalloc(32 * sizeof(pciDriver)); + + // Probe PCI devices + pciProbeForDevices(); + + // Make sure the functions know initialization has completed. + isPCIInitialized = true; + printf("PCI handler initialized.\n"); +} + +int getDevTableId(uint32_t deviceID, uint32_t vendorID) { + int id = -1; + for (int i = 0; i < PCI_DEVTABLE_LEN; i++) { + if (PciDevTable[i].DevId == deviceID && PciDevTable[i].VenId == vendorID) { + id = i; + break; + } + } + + return id; +} + +int getClassIdType(uint16_t classID, uint16_t subclassID) { + int id = -1; + + for (int i = 0; i < PCI_CLASSCODETABLE_LEN; i++) { + if (PciClassCodeTable[i].BaseClass == classID && PciClassCodeTable[i].SubClass == subclassID) { + id = i; + break; + } + } + + return id; +} + +void printPCIInfo() { + + for (int i = 0; i < dev_idx; i++) { + + // Get the class type + uint16_t classID = pciGetClassID(pciDevices[i]->bus, pciDevices[i]->slot, pciDevices[i]->func); + uint16_t subclassID = pciGetSubClassID(pciDevices[i]->bus, pciDevices[i]->slot, pciDevices[i]->func); + int classTypeId = getClassIdType(classID, subclassID); + + int id = getDevTableId(pciDevices[i]->device, pciDevices[i]->vendor); + if (id != -1 && classTypeId != -1) { + if (PciClassCodeTable[classTypeId].ProgDesc != "") { + printf("%i) %s %s (%s - %s - %s)\n", i, PciDevTable[id].Chip, PciDevTable[i].ChipDesc, PciClassCodeTable[classTypeId].BaseDesc, PciClassCodeTable[classTypeId].SubDesc, PciClassCodeTable[classTypeId].ProgDesc); + } else { + printf("%i) %s %s (%s - %s)\n", i, PciDevTable[id].Chip, PciDevTable[i].ChipDesc, PciClassCodeTable[classTypeId].BaseDesc, PciClassCodeTable[classTypeId].SubDesc); + } + } else if (classTypeId != -1) { + // We don't know the exact device type - that's ok, just print Unknown and the class type + if (PciClassCodeTable[classTypeId].ProgDesc != "") { + printf("%i) Unknown Device (%s - %s - %s)\n", i, PciClassCodeTable[classTypeId].BaseDesc, PciClassCodeTable[classTypeId].SubDesc, PciClassCodeTable[classTypeId].ProgDesc); + } else { + printf("%i) Unknown Device (%s - %s)\n", i, PciClassCodeTable[classTypeId].BaseDesc, PciClassCodeTable[classTypeId].SubDesc); + } + } else { + // We don't know anything. + printf("%i) Unknown Device (Unknown Class Type)\n", i); + } + + printf("\tVendor ID: 0x%x, Device ID: 0x%x\n", pciDevices[i]->vendor, pciDevices[i]->device); + // pciGetStatus(pciDevices[i]->bus, pciDevices[i]->slot, pciDevices[i]->func); + + } + +} diff --git a/source/kernel/drivers/pit.c b/source/kernel/drivers/pit.c index 1c19a130..ed6dfad3 100644 --- a/source/kernel/drivers/pit.c +++ b/source/kernel/drivers/pit.c @@ -1,97 +1,97 @@ -// ===================================================================== -// pit.c - Programmable Interval Timer -// This file handles setting up the Programmable Interval Timer (PIT) -// ===================================================================== - -#include "include/pit.h" // Main header file - -static volatile uint32_t pitTicks = 0; // Total PIT ticks -static bool pit_isInit = false; // Is the PIT initialized? - - - -// PIT timer interrupt handler -void pitIRQ() { - pitTicks++; // Increment tick count - if (terminalMode == 1) updateTextCursor_vesa(); // To be replaced with some sort of handler/caller list -} - -// Waits seconds. -void pitWaitSeconds(int seconds) { - int secondsPassed = 0; - do { - if (pitTicks % 100 == 0) secondsPassed++; - } while (secondsPassed < seconds); -} - - -// uint32_t pitSetTickCount(uint32_t i) - Sets a new tick count and returns the previous one. -uint32_t pitSetTickCount(uint32_t i) { - uint32_t ret = pitTicks; - pitTicks = i; - return ret; -} - -// uint32_t pitGetTickCount() - Returns tick count -uint32_t pitGetTickCount() { return pitTicks; } - -// void pitSendCommand(uint8_t cmd) - Sends a command to PIT -void pitSendCommand(uint8_t cmd) { - outportb(PIT_REG_COMMAND, cmd); -} - -// void pitSendData(uint16_t data, uint8_t counter) - Send data to a counter -void pitSendData(uint16_t data, uint8_t counter) { - uint8_t port = (counter == PIT_OCW_COUNTER_0) ? PIT_REG_COUNTER0: - ((counter==PIT_OCW_COUNTER_1) ? PIT_REG_COUNTER1 : PIT_REG_COUNTER2); - - outportb(port, (uint8_t) data); // Write the data. -} - - - -// void pitStartCounter(uint32_t freq, uint8_t counter, uint8_t mode) - Starts a counter from the provided parameters. -void pitStartCounter(uint32_t freq, uint8_t counter, uint8_t mode) { - if (freq == 0) return; // If the frequency is 0, return. - - uint16_t divisor = (uint16_t) (1193181 / (uint16_t)freq); - - // Sending the operational command - uint8_t ocw = 0; - ocw = (ocw & ~PIT_OCW_MASK_MODE) | mode; - ocw = (ocw & ~PIT_OCW_MASK_RL) | PIT_OCW_RL_DATA; - ocw = (ocw & ~PIT_OCW_MASK_COUNTER) | counter; - pitSendCommand(ocw); - - // Set frequency rate - pitSendData(divisor & 0xff, 0); - pitSendData((divisor >> 8) & 0xff, 0); - - // Reset tick count - pitTicks = 0; -} - -// void pitInit() - Initialize PIT -void pitInit() { - - // Install our interrupt handler (IRQ 0 uses INT 32) - isrRegisterInterruptHandler(32, pitIRQ); - - // Update the isInitialized variable. - pit_isInit = true; - - // We want to add some extra code to fully initialize the PIT properly. - // The default what we want to is to enable the PIT with a square wave generator and 100hz frequencey. - // If the user wants they can use one of the above functions to do so, but we're going to do it here. - // Setup the PIT for 100 hz. - // TODO: Remove above functions. - - - - int divisor = 1193180 / 1000; // Calculate divisor. - outportb(0x43, 0x36); // Command byte (0x36) - outportb(0x40, divisor & 0xFF); // Set the low and high byte of the divisor. - outportb(0x40, divisor >> 8); - - printf("Programmable Interval Timer initialized.\n"); -} \ No newline at end of file +// ===================================================================== +// pit.c - Programmable Interval Timer +// This file handles setting up the Programmable Interval Timer (PIT) +// ===================================================================== + +#include // Main header file + +static volatile uint32_t pitTicks = 0; // Total PIT ticks +static bool pit_isInit = false; // Is the PIT initialized? + + + +// PIT timer interrupt handler +void pitIRQ() { + pitTicks++; // Increment tick count + if (terminalMode == 1) updateTextCursor_vesa(); // To be replaced with some sort of handler/caller list +} + +// Waits seconds. +void pitWaitSeconds(int seconds) { + int secondsPassed = 0; + do { + if (pitTicks % 100 == 0) secondsPassed++; + } while (secondsPassed < seconds); +} + + +// uint32_t pitSetTickCount(uint32_t i) - Sets a new tick count and returns the previous one. +uint32_t pitSetTickCount(uint32_t i) { + uint32_t ret = pitTicks; + pitTicks = i; + return ret; +} + +// uint32_t pitGetTickCount() - Returns tick count +uint32_t pitGetTickCount() { return pitTicks; } + +// void pitSendCommand(uint8_t cmd) - Sends a command to PIT +void pitSendCommand(uint8_t cmd) { + outportb(PIT_REG_COMMAND, cmd); +} + +// void pitSendData(uint16_t data, uint8_t counter) - Send data to a counter +void pitSendData(uint16_t data, uint8_t counter) { + uint8_t port = (counter == PIT_OCW_COUNTER_0) ? PIT_REG_COUNTER0: + ((counter==PIT_OCW_COUNTER_1) ? PIT_REG_COUNTER1 : PIT_REG_COUNTER2); + + outportb(port, (uint8_t) data); // Write the data. +} + + + +// void pitStartCounter(uint32_t freq, uint8_t counter, uint8_t mode) - Starts a counter from the provided parameters. +void pitStartCounter(uint32_t freq, uint8_t counter, uint8_t mode) { + if (freq == 0) return; // If the frequency is 0, return. + + uint16_t divisor = (uint16_t) (1193181 / (uint16_t)freq); + + // Sending the operational command + uint8_t ocw = 0; + ocw = (ocw & ~PIT_OCW_MASK_MODE) | mode; + ocw = (ocw & ~PIT_OCW_MASK_RL) | PIT_OCW_RL_DATA; + ocw = (ocw & ~PIT_OCW_MASK_COUNTER) | counter; + pitSendCommand(ocw); + + // Set frequency rate + pitSendData(divisor & 0xff, 0); + pitSendData((divisor >> 8) & 0xff, 0); + + // Reset tick count + pitTicks = 0; +} + +// void pitInit() - Initialize PIT +void pitInit() { + + // Install our interrupt handler (IRQ 0 uses INT 32) + isrRegisterInterruptHandler(32, pitIRQ); + + // Update the isInitialized variable. + pit_isInit = true; + + // We want to add some extra code to fully initialize the PIT properly. + // The default what we want to is to enable the PIT with a square wave generator and 100hz frequencey. + // If the user wants they can use one of the above functions to do so, but we're going to do it here. + // Setup the PIT for 100 hz. + // TODO: Remove above functions. + + + + int divisor = 1193180 / 1000; // Calculate divisor. + outportb(0x43, 0x36); // Command byte (0x36) + outportb(0x40, divisor & 0xFF); // Set the low and high byte of the divisor. + outportb(0x40, divisor >> 8); + + printf("Programmable Interval Timer initialized.\n"); +} diff --git a/source/kernel/drivers/rtc.c b/source/kernel/drivers/rtc.c index 6c2d19b0..811ea440 100644 --- a/source/kernel/drivers/rtc.c +++ b/source/kernel/drivers/rtc.c @@ -1,96 +1,96 @@ -// ======================================================= -// rtc.c - System real-time clock driver (like CMOS) -// ======================================================= -// This file is a part of the reduceOS C kernel. Please credit me if you use this code. - -#include "include/rtc.h" // Main header file - - -// It's important to note that this file doesn't go very in-depth in the RTC - it only reads time and date from it. -// All RTC ports/registers are defiend in rtc.h. - -// Later, when ACPI is implemented, we can use a variable here to get the century. - -// rtc_getUpdateInProgress() - Returns if the RTC is doing an update -int rtc_getUpdateInProgress() { - outportb(CMOS_ADDRESS, 0x0A); - return (inportb(CMOS_DATA) & 0x80); -} - - -// rtc_getRegister(int register) - Returns the value of an RTC register -uint8_t rtc_getRegister(int reg) { - outportb(CMOS_ADDRESS, reg); - return inportb(CMOS_DATA); -} - -// rtc_getDateTime(uint8_t *second, uint8_t *minute, uint8_t *hour, uint8_t *day, uint8_t *month, uint8_t *year) - Returns the date and time (in the pointers) -void rtc_getDateTime(uint8_t *second, uint8_t *minute, uint8_t *hour, uint8_t *day, uint8_t *month, int *year) { - uint8_t lastSecond, lastMinute, lastHour, lastDay, lastMonth, lastYear, lastCentury, registerB; - // Because of some weird pointer logic, we have to make more variables and then set the pointers to the variables. - uint8_t seconds, minutes, hours, days, months, years; - - // First, make sure an update isn't in progress. - while (rtc_getUpdateInProgress()); - - // Get the registers. - seconds = rtc_getRegister(RTC_SECOND_REGISTER); - minutes = rtc_getRegister(RTC_MINUTE_REGISTER); - hours = rtc_getRegister(RTC_HOUR_REGISTER); - days = rtc_getRegister(RTC_DAY_REGISTER); - months = rtc_getRegister(RTC_MONTH_REGISTER); - years = rtc_getRegister(RTC_YEAR_REGISTER); - - // ACPI will come into play later. - - // Do a little workaround to get around RTC updates. - do { - lastSecond = seconds; - lastMinute = minutes; - lastHour = hours; - lastDay = days; - lastMonth = months; - lastYear = years; - - // Get new values. - while (rtc_getUpdateInProgress()); - seconds = rtc_getRegister(RTC_SECOND_REGISTER); - minutes = rtc_getRegister(RTC_MINUTE_REGISTER); - hours = rtc_getRegister(RTC_HOUR_REGISTER); - days = rtc_getRegister(RTC_DAY_REGISTER); - months = rtc_getRegister(RTC_MONTH_REGISTER); - years = rtc_getRegister(RTC_YEAR_REGISTER); - } while ((lastSecond != seconds) || (lastMinute != minutes) || (lastHour != hours) || - (lastDay != days) || (lastMonth != months) || (lastYear != years)); - - registerB = rtc_getRegister(0x08); - - // Now, convert BCD -> binary values (if necessary) - if (!(registerB & 0x04)) { - seconds = (seconds & 0x0F) + ((seconds / 16) * 10); - minutes = (minutes & 0x0F) + ((minutes / 16) * 10); - hours = ( (hours & 0x0F) + (((hours & 0x70) / 16) * 10)) | (hours & 0x80); - days = (days & 0x0F) + ((days / 16) * 10); - months = (months & 0x0F) + ((months / 16) * 10); - years = (years & 0x0F) + ((years / 16) * 10); - } - - // Convert 12 hour to 24 hour if necessary. - if (!(registerB & 0x02) && (hours & 0x80)) { - hours = ((hours & 0x7F) + 12) % 24; - } - - // Calculate full 4-digit year - by making another variable cause conversions are WEIRD - int actualYears = (int)years; - actualYears += ((RTC_CURRENT_YEAR / 100) * 100); - if (actualYears < RTC_CURRENT_YEAR) actualYears += 100; - - // Set the pointers. - *second = seconds; - *minute = minutes; - *hour = hours; - *day = days; - *month = months; - *year = actualYears; - -} \ No newline at end of file +// ======================================================= +// rtc.c - System real-time clock driver (like CMOS) +// ======================================================= +// This file is a part of the reduceOS C kernel. Please credit me if you use this code. + +#include // Main header file + + +// It's important to note that this file doesn't go very in-depth in the RTC - it only reads time and date from it. +// All RTC ports/registers are defiend in rtc.h. + +// Later, when ACPI is implemented, we can use a variable here to get the century. + +// rtc_getUpdateInProgress() - Returns if the RTC is doing an update +int rtc_getUpdateInProgress() { + outportb(CMOS_ADDRESS, 0x0A); + return (inportb(CMOS_DATA) & 0x80); +} + + +// rtc_getRegister(int register) - Returns the value of an RTC register +uint8_t rtc_getRegister(int reg) { + outportb(CMOS_ADDRESS, reg); + return inportb(CMOS_DATA); +} + +// rtc_getDateTime(uint8_t *second, uint8_t *minute, uint8_t *hour, uint8_t *day, uint8_t *month, uint8_t *year) - Returns the date and time (in the pointers) +void rtc_getDateTime(uint8_t *second, uint8_t *minute, uint8_t *hour, uint8_t *day, uint8_t *month, int *year) { + uint8_t lastSecond, lastMinute, lastHour, lastDay, lastMonth, lastYear, lastCentury, registerB; + // Because of some weird pointer logic, we have to make more variables and then set the pointers to the variables. + uint8_t seconds, minutes, hours, days, months, years; + + // First, make sure an update isn't in progress. + while (rtc_getUpdateInProgress()); + + // Get the registers. + seconds = rtc_getRegister(RTC_SECOND_REGISTER); + minutes = rtc_getRegister(RTC_MINUTE_REGISTER); + hours = rtc_getRegister(RTC_HOUR_REGISTER); + days = rtc_getRegister(RTC_DAY_REGISTER); + months = rtc_getRegister(RTC_MONTH_REGISTER); + years = rtc_getRegister(RTC_YEAR_REGISTER); + + // ACPI will come into play later. + + // Do a little workaround to get around RTC updates. + do { + lastSecond = seconds; + lastMinute = minutes; + lastHour = hours; + lastDay = days; + lastMonth = months; + lastYear = years; + + // Get new values. + while (rtc_getUpdateInProgress()); + seconds = rtc_getRegister(RTC_SECOND_REGISTER); + minutes = rtc_getRegister(RTC_MINUTE_REGISTER); + hours = rtc_getRegister(RTC_HOUR_REGISTER); + days = rtc_getRegister(RTC_DAY_REGISTER); + months = rtc_getRegister(RTC_MONTH_REGISTER); + years = rtc_getRegister(RTC_YEAR_REGISTER); + } while ((lastSecond != seconds) || (lastMinute != minutes) || (lastHour != hours) || + (lastDay != days) || (lastMonth != months) || (lastYear != years)); + + registerB = rtc_getRegister(0x08); + + // Now, convert BCD -> binary values (if necessary) + if (!(registerB & 0x04)) { + seconds = (seconds & 0x0F) + ((seconds / 16) * 10); + minutes = (minutes & 0x0F) + ((minutes / 16) * 10); + hours = ( (hours & 0x0F) + (((hours & 0x70) / 16) * 10)) | (hours & 0x80); + days = (days & 0x0F) + ((days / 16) * 10); + months = (months & 0x0F) + ((months / 16) * 10); + years = (years & 0x0F) + ((years / 16) * 10); + } + + // Convert 12 hour to 24 hour if necessary. + if (!(registerB & 0x02) && (hours & 0x80)) { + hours = ((hours & 0x7F) + 12) % 24; + } + + // Calculate full 4-digit year - by making another variable cause conversions are WEIRD + int actualYears = (int)years; + actualYears += ((RTC_CURRENT_YEAR / 100) * 100); + if (actualYears < RTC_CURRENT_YEAR) actualYears += 100; + + // Set the pointers. + *second = seconds; + *minute = minutes; + *hour = hours; + *day = days; + *month = months; + *year = actualYears; + +} diff --git a/source/kernel/drivers/serial.c b/source/kernel/drivers/serial.c index 62ea5ebe..c8574db8 100644 --- a/source/kernel/drivers/serial.c +++ b/source/kernel/drivers/serial.c @@ -1,102 +1,102 @@ -// ================================================ -// serial.c - reduceOS serial logging driver -// ================================================ -// This file is a part of the reduceOS C kernel. Please credit me if you use it. - -#include "include/serial.h" // Main header file - -// Variable declarations -bool serialTestPassed = true; -bool isSerialEnabled = false; - - -// Functions - -// (static) serialHasReceived() - Returns if the serial port received anything -static int serialHasReceived() { - return inportb(SERIAL_COM1 + 5) & 1; -} - -// serialRead() - Reads SERIAL_COM1 and returns whatever it found (only returns if serialHasReceived returns 1) -char serialRead() { - while (serialHasReceived() == 0); - return inportb(SERIAL_COM1); -} - -// (static) serialIsTransmitEmpty() - Checks if the serial port's transfer is empty. Returns 1 on yes, 0 on no. -static int serialIsTransmitEmpty() { - return inportb(SERIAL_COM1 + 5) & 0x20; -} - -// serialWrite(void *user, char c) - Writes character 'c' to serial when transmit is empty. -void serialWrite(void *user, char c) { - while (serialIsTransmitEmpty() == 0); - outportb(SERIAL_COM1, c); -} - - -// Now, for the actual functions... - -// serialPrintf(const char *str, ...) - Prints a formatted line to SERIAL_COM1. -void serialPrintf(const char *str, ...) { - if (!serialTestPassed) return; - - va_list(ap); - va_start(ap, str); - xvasprintf(serialWrite, NULL, str, ap); - va_end(ap); -} - -// serialReadLine(bool printChars) - Reads a line from SERIAL_COM1 -void serialReadLine(bool printChars, char *bufferPtr) { - char *buffer = kmalloc(8); // prolly a security nightmare but lol idc - int bindex = 0; - char receivedChar = '\0'; - while (receivedChar != 0xD) { // 0xD is a newline in serial - receivedChar = serialRead(); - buffer[bindex] = receivedChar; - bindex++; - if (printChars) printf("%c", receivedChar); - } - if (printChars) serialPrintf("\n"); - strcpy(bufferPtr, buffer); - return; -} - -int testSerial() { - // The first thing we need to do to test the serial chip is to set it in loopback mode. - outportb(SERIAL_COM1 + 4, 0x1E); // Set chip in loopback mode. - - // Now, we send byte 0xAE and check if the serial returns the same byte. - outportb(SERIAL_COM1 + 0, 0xAE); - - // Read the serial. - // Note: We do this manually through inportb() because (I think) the serial can hang and not respond, and the serialRead method only reads after the serial was read. - if (inportb(SERIAL_COM1 + 0) != 0xAE) { - serialTestPassed = false; - printf("serial: serial test failed\n"); - return -1; - } - - // The serial isn't faulty, hooray! - // Set in normal operations mode (non-loopback, IRQs enabled, OUT #1 and #2 bits enabled) - outportb(SERIAL_COM1 + 4, 0x0F); - return 0; -} - -// serialInit() - Initializes serial properly. -void serialInit() { - // TODO: Allow user to choose ports. - outportb(SERIAL_COM1 + 1, 0x00); // Disable all interrupts - outportb(SERIAL_COM1 + 3, 0x80); // Enable DLAB (set the baud rate divisor). - outportb(SERIAL_COM1 + 0, 0x03); // (low byte) Set divisor to 3 - 38400 baud. - outportb(SERIAL_COM1 + 1, 0x00); // (high byte) Set divisor to 3 - 38400 baud. - outportb(SERIAL_COM1 + 3, 0x03); // 8 bits, no parity, 1 stop bit. - outportb(SERIAL_COM1 + 2, 0xC7); // Enable the FIFO, clear them with 14-byte threshold - outportb(SERIAL_COM1 + 4, 0x0B); // Enable IRQs, set RTS / DSR (RTS stands for "request to send" and DSR stands for "data set ready") - - // Test the serial port to make sure it works properly. - testSerial(); - - isSerialEnabled = true; -} \ No newline at end of file +// ================================================ +// serial.c - reduceOS serial logging driver +// ================================================ +// This file is a part of the reduceOS C kernel. Please credit me if you use it. + +#include // Main header file + +// Variable declarations +bool serialTestPassed = true; +bool isSerialEnabled = false; + + +// Functions + +// (static) serialHasReceived() - Returns if the serial port received anything +static int serialHasReceived() { + return inportb(SERIAL_COM1 + 5) & 1; +} + +// serialRead() - Reads SERIAL_COM1 and returns whatever it found (only returns if serialHasReceived returns 1) +char serialRead() { + while (serialHasReceived() == 0); + return inportb(SERIAL_COM1); +} + +// (static) serialIsTransmitEmpty() - Checks if the serial port's transfer is empty. Returns 1 on yes, 0 on no. +static int serialIsTransmitEmpty() { + return inportb(SERIAL_COM1 + 5) & 0x20; +} + +// serialWrite(void *user, char c) - Writes character 'c' to serial when transmit is empty. +void serialWrite(void *user, char c) { + while (serialIsTransmitEmpty() == 0); + outportb(SERIAL_COM1, c); +} + + +// Now, for the actual functions... + +// serialPrintf(const char *str, ...) - Prints a formatted line to SERIAL_COM1. +void serialPrintf(const char *str, ...) { + if (!serialTestPassed) return; + + va_list(ap); + va_start(ap, str); + xvasprintf(serialWrite, NULL, str, ap); + va_end(ap); +} + +// serialReadLine(bool printChars) - Reads a line from SERIAL_COM1 +void serialReadLine(bool printChars, char *bufferPtr) { + char *buffer = kmalloc(8); // prolly a security nightmare but lol idc + int bindex = 0; + char receivedChar = '\0'; + while (receivedChar != 0xD) { // 0xD is a newline in serial + receivedChar = serialRead(); + buffer[bindex] = receivedChar; + bindex++; + if (printChars) printf("%c", receivedChar); + } + if (printChars) serialPrintf("\n"); + strcpy(bufferPtr, buffer); + return; +} + +int testSerial() { + // The first thing we need to do to test the serial chip is to set it in loopback mode. + outportb(SERIAL_COM1 + 4, 0x1E); // Set chip in loopback mode. + + // Now, we send byte 0xAE and check if the serial returns the same byte. + outportb(SERIAL_COM1 + 0, 0xAE); + + // Read the serial. + // Note: We do this manually through inportb() because (I think) the serial can hang and not respond, and the serialRead method only reads after the serial was read. + if (inportb(SERIAL_COM1 + 0) != 0xAE) { + serialTestPassed = false; + printf("serial: serial test failed\n"); + return -1; + } + + // The serial isn't faulty, hooray! + // Set in normal operations mode (non-loopback, IRQs enabled, OUT #1 and #2 bits enabled) + outportb(SERIAL_COM1 + 4, 0x0F); + return 0; +} + +// serialInit() - Initializes serial properly. +void serialInit() { + // TODO: Allow user to choose ports. + outportb(SERIAL_COM1 + 1, 0x00); // Disable all interrupts + outportb(SERIAL_COM1 + 3, 0x80); // Enable DLAB (set the baud rate divisor). + outportb(SERIAL_COM1 + 0, 0x03); // (low byte) Set divisor to 3 - 38400 baud. + outportb(SERIAL_COM1 + 1, 0x00); // (high byte) Set divisor to 3 - 38400 baud. + outportb(SERIAL_COM1 + 3, 0x03); // 8 bits, no parity, 1 stop bit. + outportb(SERIAL_COM1 + 2, 0xC7); // Enable the FIFO, clear them with 14-byte threshold + outportb(SERIAL_COM1 + 4, 0x0B); // Enable IRQs, set RTS / DSR (RTS stands for "request to send" and DSR stands for "data set ready") + + // Test the serial port to make sure it works properly. + testSerial(); + + isSerialEnabled = true; +} diff --git a/source/kernel/fs/ext2.c b/source/kernel/fs/ext2.c index 54b38ee3..5156abe8 100644 --- a/source/kernel/fs/ext2.c +++ b/source/kernel/fs/ext2.c @@ -6,9 +6,9 @@ -#include "include/ext2.h" // Main header file -#include "include/ide_ata.h" // IDE/ATA driver -#include "include/vfs.h" +#include // Main header file +#include // IDE/ATA driver +#include // External variables extern ideDevice_t ideDevices[4]; @@ -1391,4 +1391,4 @@ fsNode_t *ext2_fs_mount(const char *device, const char *mount_path) { int ext2_install(int argc, char *argv[]) { vfs_registerFilesystem("ext2", ext2_fs_mount); return 0; -} \ No newline at end of file +} diff --git a/source/kernel/fs/fat.c b/source/kernel/fs/fat.c index 0bd52eab..ec7cc361 100644 --- a/source/kernel/fs/fat.c +++ b/source/kernel/fs/fat.c @@ -1,885 +1,885 @@ -// ============================================================ -// fat.c - FAT filesystem driver -// ============================================================ -// This file was written for the reduceOS C kernel. Please credit me if you use this code. - -#include "include/fat.h" // Main header file - -// This driver is compatible with VFS standards but is missing writing functionality. That will be added later. -// DO NOT USE ANY INTERNAL FUNCTIONS. USE THE VFS ONES. - -/* -SUPPORTED FILESYSTEMS: - - FAT12 - - FAT16 - - FAT32 -*/ - -// If you want a lot of the details about FAT, see https://wiki.osdev.org/FAT - - -// NOTE: impl_struct is a reference to fat_t - -// Variables -uint8_t FAT[1024]; // File allocation table -fsNode_t driver; // Driver inode - - - -// Functions - -// fatToDOSName(char *filename, char *output, int length) - Convert a filename to DOS 8.3 file format -// NOTE: RESULT MUST BE NULL TERMINATED!!!! -int fatToDOSName(char *filename, char *output, int length) { - if (length > 11 || strlen(filename) > length) return -1; // Users. - - memset(output, ' ', length); - - // So, the FAT filesystem stores filenames as DOS 8.3 style filenames. - // For example, test.txt would be "TEST TXT" - // Another example, dir would be "DIR " - // NOTE: LFNs are different! They can be stored as normal filenames, like "TEST.TXT" Future support will be coming soon. - - // The first thing we need to do is convert the normal filename to uppercase, until we encounter a period. - bool adjustExtension = false; // Set to true if we're dealing with a file. - int i; - - for (i = 0; i < length && i < strlen(filename); i++) { - if (filename[i] == '.') { - adjustExtension = true; - output[i] = ' '; - i++; - break; - } else if (filename[i] == ' ') { - output[i] = ' '; - } else { - output[i] = toupper(filename[i]); - } - } - - if (adjustExtension) { - for (int j = 0; j < 3; j++) { - output[i + (8 - i) + j] = toupper(filename[i + j]); - } - } else if (i < length) { - for (i; i < length; i++) { - output[i] = ' '; - } - } - - return 0; -} - - -// fatParseRootDirectory32(fat_t *fs, char *path, fsNode_t *file) - FAT32 version of fatParseRootDirectory (could probably hack in a way to use fatReadInternal, but this is easier) -int fatParseRootDirectory32(fat_t *fs, char *path, fsNode_t *file) { - // FAT32 uses a cluster chain instead of a fixed root directory. - - if (file->impl) { - // Calculate the first sector of the cluster and read it in - int lba = ((file->impl - 2) * fs->drive->bpb->sectorsPerCluster) + fs->drive->firstDataSector; - uint8_t *buffer = kmalloc(fs->drive->bpb->sectorsPerCluster * 512); - fs->drive->driveobj->read(fs->drive->driveobj, lba * 512, fs->drive->bpb->sectorsPerCluster * 512, buffer); - - - fat_fileEntry_t *directory = (fat_fileEntry_t*)buffer; - - for (int i = 0; i < 16; i++) { - // Nasty hack we have here - - uint8_t attributes = directory->fileName[11]; // Save the attributes byte, as we need to null-terminate the string and compare. - directory->fileName[11] = 0; // Null-terminate - // Something's absolutely horrendously wrong in the stack that I can't copy this to an external variable. - - - // strcmp() will return a 0 if the other string is totally blank, bad! - // Solve with this if statement - if (strlen(directory->fileName) <= 0) continue; - - if (!strcmp(directory->fileName, path)) { - // We found the file! Congrats! - - // Reset the attributes byte - directory->fileName[11] = attributes; - - // Now, let's allocate a fat_t for the impl_struct and copy the contents of our directory. - file->impl_struct = kmalloc(sizeof(fat_t)); - ((fat_t*)(file->impl_struct))->drive = fs->drive; - ((fat_t*)(file->impl_struct))->fileEntry = kmalloc(sizeof(fat_fileEntry_t)); - memcpy(((fat_t*)(file->impl_struct))->fileEntry, directory, sizeof(fat_fileEntry_t)); - - if (((fat_t*)file->impl_struct)->fileEntry->size != directory->size) { - // There was an error in the memcpy() - file->flags = -1; - return EOF; - } - - - - strcpy(file->name, path); // Copy the file name into the result value - - // Check if its a directory or a file - if (directory->fileName[11] == 0x10) file->flags = VFS_DIRECTORY; - else file->flags = VFS_FILE; - - // Set the current cluster - file->impl = ((fat_t*)file->impl_struct)->fileEntry->firstClusterNumberLow; - - // Setup a few other fields - file->length = ((fat_t*)file->impl_struct)->fileEntry->size; - - - kfree(buffer); - return 1; - } - - directory++; - } - - // We couldn't find the file on this attempt. Let's calculate the next cluster number and try again. - // This requires us to read in the FAT. - - uint32_t fatOffset = file->impl * 4; - uint32_t fatSector = fs->drive->firstFatSector + (fatOffset / 512); - uint32_t entryOffset = fatOffset % 512; - - // Read the FATs - fs->drive->driveobj->read(fs->drive->driveobj, fatSector * 512, 1024, (uint8_t*)FAT); - - // Get the cluster number and mask it to ignore the high 4 bits. - uint32_t nextCluster = *(unsigned int*)&FAT[entryOffset]; - nextCluster &= 0x0FFFFFFF; - - // Check if it's the end of the root directory, or if it is corrupt. - if (nextCluster >= 0x0FFFFFF8 || nextCluster == 0x0FFFFFF7) return EOF; - - file->impl = nextCluster; - return 0; - } else { - serialPrintf("fatParseRootDirectory32: file.impl is unavailable. Returning EOF for error.\n"); - return EOF; - } - - return EOF; // Error. - -} - -// fatParseRootDirectory(fat_t *fs, char *path) - Locate a file or directory in the root directory -fsNode_t *fatParseRootDirectory(fat_t *fs, char *path) { - fsNode_t *file = kmalloc(sizeof(fsNode_t)); - - - // Call helper function for 8.3 filename - char filename[11]; - if (fatToDOSName(path, filename, 11) != 0) { - file->flags = -1; - return file; - } - - filename[11] = 0; - - // FAT32 is for another function, it's more complex. - if (fs->drive->fatType == 3) { - // Similar to fatReadInternal, we will iterate until we've exhausted all available cluster entries. - // Return codes: 0 = keep calling, 1 = found the file, -1 = EOF, return failure - file->impl = fs->drive->rootOffset; // First cluster number. - - - while (1) { - int ret = fatParseRootDirectory32(fs, filename, file); - if (ret == 1) return file; // Its already setup everything, we can just return the file. - - if (ret == -1) { - file->flags = -1; // Couldn't find the file. - return file; - } - - if (ret != 0) { - // There's been a problem in the code. - serialPrintf("fatParseRootDirectory: FAT32 parsing failed!\n"); - file->flags = -1; - return file; - } - } - } - - - uint8_t *buffer = kmalloc(512); - - for (int sector = 0; sector < 14; sector++) { - // Read in the sector. This calculation differs depending on what FAT type is being used. - // FAT12/16 have the root directory at a fixed position, and we can calculate it easily. - // FAT32 is where it gets tricky. FAT32 instead gives the root directory offset with a cluster, and it CAN be a cluster chain. - // This means that extra work is put in for a FAT32 system, and is why we would call to another method to do it earlier. - - //int lba = ((fs->drive->bpb->tableCount * fs->drive->bpb->tableSize16) + 1) + sector; - int lba = fs->drive->rootOffset + sector; - fs->drive->driveobj->read(fs->drive->driveobj, lba * 512, 512, buffer); - - fat_fileEntry_t *directory = (fat_fileEntry_t*)buffer; - - for (int i = 0; i < 16; i++) { - // Nasty hack we have here - - uint8_t attributes = directory->fileName[11]; // Save the attributes byte, as we need to null-terminate the string and compare. - directory->fileName[11] = 0; // Null-terminate - // Something's absolutely horrendously wrong in the stack that I can't copy this to an external variable. - - - // strcmp() will return a 0 if the other string is totally blank, bad! - // Solve with this if statement - if (strlen(directory->fileName) <= 0) continue; - - if (!strcmp(directory->fileName, filename)) { - // We found the file! Congrats! - - // Reset the attributes byte - directory->fileName[11] = attributes; - - // Now, let's allocate a fat_t for the impl_struct and copy the contents of our directory. - file->impl_struct = kmalloc(sizeof(fat_t)); - ((fat_t*)(file->impl_struct))->drive = fs->drive; - ((fat_t*)(file->impl_struct))->fileEntry = kmalloc(sizeof(fat_fileEntry_t)); - memcpy(((fat_t*)(file->impl_struct))->fileEntry, directory, sizeof(fat_fileEntry_t)); - - if (((fat_t*)file->impl_struct)->fileEntry->size != directory->size) { - // There was an error in the memcpy() - file->flags = -1; - return file; - } - - - - strcpy(file->name, path); // Copy the file name into the result value - - // Check if its a directory or a file - if (directory->fileName[11] == 0x10) file->flags = VFS_DIRECTORY; - else file->flags = VFS_FILE; - - // Set the current cluster - file->impl = ((fat_t*)file->impl_struct)->fileEntry->firstClusterNumberLow; - - // Setup a few other fields - file->length = ((fat_t*)file->impl_struct)->fileEntry->size; - - - kfree(buffer); - return file; - } - - directory++; - } - - - memset(buffer, 0, sizeof(buffer)); - } - - // Could not find file. - kfree(buffer); - file->flags = -1; // TBD: Make a VFS_INVALID flag - return file; -} - - -// fatReadInternal(fsNode_t *file, uint8_t *buffer, uint32_t length) - Reads a file in the FAT -// NOTE: DO NOT CALL DIRECTLY. CALL fatRead AND IT WILL SOLVE ALL YOUR PROBLEMS! -int fatReadInternal(fsNode_t *file, uint8_t *buffer, uint32_t length) { - if (file) { - // Get the fat_t structure - fat_t *fs = (fat_t*)(file->impl_struct); - - // Calculate and read in the starting physical sector - uint16_t cluster = file->impl; - uint32_t sector = ((cluster - 2) * fs->drive->bpb->sectorsPerCluster) + fs->drive->firstDataSector; - - uint8_t sector_buffer[fs->drive->bpb->sectorsPerCluster * 512]; - fs->drive->driveobj->read(fs->drive->driveobj, (uint32_t)sector * 512, fs->drive->bpb->sectorsPerCluster * 512, sector_buffer); - - - - // Copy the sector buffer to the output buffer - uint32_t len = (length > (fs->drive->bpb->sectorsPerCluster * 512)) ? fs->drive->bpb->sectorsPerCluster * 512 : length; - memcpy(buffer, sector_buffer, len); - - // Locate the File Allocation Table sector - uint32_t fatOffset; - if (fs->drive->fatType == 1) fatOffset = cluster + (cluster / 2); - else if (fs->drive->fatType == 2) fatOffset = cluster * 2; - else if (fs->drive->fatType == 3) fatOffset = cluster * 4; - else { serialPrintf("fatReadInternal: Unknown fatType!\n"); return -1; } - - - uint32_t fatSector = fs->drive->firstFatSector + (fatOffset / 512); - uint32_t entryOffset = fatOffset % 512; - - - - // Read the FATs - fs->drive->driveobj->read(fs->drive->driveobj, fatSector * 512, 1024, (uint8_t*)FAT); - - - // Read entry for the next cluster - // This should be done differently depending on the FAT version being used. - if (fs->drive->fatType == 1 || fs->drive->fatType == 2) { - uint16_t nextCluster = *(uint16_t*)&FAT[entryOffset]; - - - if (fs->drive->fatType == 1) { - // Convert the cluster (FAT12 only) - nextCluster = (cluster & 1) ? nextCluster >> 4 : nextCluster & 0xFFF; - } - - // Test for EOF - if ((nextCluster >= 0xFF8 && fs->drive->fatType == 1) || (nextCluster >= 0xFFF8 && fs->drive->fatType == 2)) { - return EOF; - } - - // Test for file corruption - if (nextCluster == 0 || (nextCluster == 0xFFF7 && fs->drive->fatType == 2) || (nextCluster == 0xFF7 && fs->drive->fatType == 1)) { - return EOF; - } - - // Set the next cluster - file->impl = nextCluster; - } else if (fs->drive->fatType == 3) { - // FAT32 needs to use an unsigned integer instead of a short. - - uint32_t nextCluster = *(uint32_t*)&FAT[entryOffset]; - nextCluster &= 0x0FFFFFFF; - - // Test for EOF and file corruption - if (nextCluster >= 0x0FFFFFF8 || nextCluster == 0x0FFFFFF7) { - return EOF; - } - - file->impl = nextCluster; - } - } - - return 0; -} - -// fatParseSubdirectory(fsNode_t *file, const char *path) - Locate a file/folder in a subdirectory. -fsNode_t *fatParseSubdirectory(fsNode_t *file, const char *path) { - fsNode_t *ret = kmalloc(sizeof(fsNode_t)); - ret->impl = file->impl; - ret->impl_struct = file->impl_struct; - - // First, get the DOS 8.3 filename. - char *filename = kmalloc(12); - if (fatToDOSName(path, filename, 11) != 0) { - ret->flags = -1; - return ret; - } - filename[11] = 0; - - // Search the directory (note: just randomly picked a value for retries because orig. impl is seemingly bugged) - for (int count = 0; count < 5; count++) { - // Read in the directory - uint8_t *buffer = kmalloc(512); - - int status = fatReadInternal(ret, buffer, 512); - - - // Setup the directory - fat_fileEntry_t *directory = (fat_fileEntry_t*)buffer; - - // 16 entries in a directory - for (int i = 0; i < 16; i++) { - // Get the filename - uint8_t attributes = directory->fileName[11]; // Save attributes - directory->fileName[11] = 0; - - - if (!strcmp(filename, directory->fileName)) { - // We found it! Setup the return file. - // Reset the attributes byte - directory->fileName[11] = attributes; - - // Now, let's allocate a fat_t for the impl_struct and copy the contents of our directory. - ret->impl_struct = kmalloc(sizeof(fat_t)); - ((fat_t*)(ret->impl_struct))->drive = ((fat_t*)(file->impl_struct))->drive; - ((fat_t*)(ret->impl_struct))->fileEntry = kmalloc(sizeof(fat_fileEntry_t)); - memcpy(((fat_t*)(ret->impl_struct))->fileEntry, directory, sizeof(fat_fileEntry_t)); - - if (((fat_t*)ret->impl_struct)->fileEntry->size != directory->size) { - // There was an error in the memcpy() - ret->flags = -1; - return ret; - } - - - strcpy(ret->name, path); // Copy the file name into the result value - - // Check if its a directory or a file - if (directory->fileName[11] == 0x10) ret->flags = VFS_DIRECTORY; - else ret->flags = VFS_FILE; - - // Set the current cluster - ret->impl = ((fat_t*)ret->impl_struct)->fileEntry->firstClusterNumberLow; - - // Setup a few other fields - ret->length = ((fat_t*)ret->impl_struct)->fileEntry->size; - - kfree(buffer); - return ret; - - } - - directory++; - } - - - // Check if EOF - if (status == EOF) { - kfree(buffer); - break; - } - } - - ret->flags = -1; - return ret; - -} - - -// fatOpenInternal(fsNode_t *driver, char *filename) - File open, can parse slashes and subdirectories -// WARNING: DO NOT USE OUTSIDE OF fatOpen - IT WILL NOT WORK! -fsNode_t *fatOpenInternal(fsNode_t *driver, char *filename) { - fsNode_t *directory = NULL; // directory is our current directory - bool isRootDir = true; - - // First, we do some hacky logic to determine if the file is in a subdirectory. - char *filepath = filename; - char *slash = strchr(filepath, '/'); - - - - if (!slash) { - fat_t *fs = (fat_t*)(driver->impl_struct); - // The file is not in a subdirectory. Scan the root directory. - directory = fatParseRootDirectory((fat_t*)(driver->impl_struct), filepath); - - if (directory->flags == VFS_FILE || directory->flags == VFS_DIRECTORY) { - return directory; // Nailed it - } - - // Failed to find - directory->flags = -1; // TBD: Make a VFS_INVALID flag. - return directory; - } - - slash++; // Go to next character - - // Okay, so there's a bit of a funny little bug in the code again. - // It's if the user tries to pass dir/nested instead of /dir/nested. - // The code skips to the first '/', completely ignoring the dir/ - // So we'll run a check here to make sure something's not going on here. - - if (filename[0] != '/') { - // There's a slash, but it's not at the beginning. Reset slash to be at 0. - slash = filepath; - } - - while (slash) { - // Get the path name. - char path[16]; - int i = 0; - for (i = 0; i < 16; i++) { - if (slash[i] == '/' || slash[i] == '\0') break; - - // Copy the character. - path[i] = slash[i]; - } - - path[i] = 0; // Null-terminate. - - // Check the bottom of the function for a bug description, but we'll check if the length is 0, as that means the user ended it with a "/" and nothing else - // This means they want a directory. - if (strlen(path) <= 0 && directory != NULL) { - // Preventing page faults with a directory != NULL - if (directory->flags == VFS_DIRECTORY) return directory; - } - - // Open subdirectory or file - if (isRootDir) { - directory = fatParseRootDirectory((fat_t*)(driver->impl_struct), path); - isRootDir = false; - } else { - directory = fatParseSubdirectory(directory, path); - } - - // Found directory or file? - if (directory->flags == -1) { - break; - } - - // Found file? - if (directory->flags == VFS_FILE) { - return directory; - } - - // Find the next '/' - slash = strchr(slash + 1, '/'); - if (slash) slash++; - else { - // Here's an interesting conundrum. This function searches through subdirectories for files/directories. - // If we want a file it's all good, it'll just return a file. But not a directory, since it might be a subdirectory that needs to be searched. - // We can resolve this using a little else statement that says if there are no more slashes in the path and there's a directory, return it. - - // There's just a slight problem: If the user puts something like "/dir/". This will break the code, since it sees another slash and thinks "oh, we have to use that slash." - // So we take care of that using the strlen() check further up - - if (directory->flags == VFS_DIRECTORY) return directory; - } - } - - // Unable to find. - serialPrintf("fatOpen: File %s not found.\n", filename); - directory->flags = -1; - return directory; -} - -/* VFS FUNCTIONS */ - -uint32_t fatRead(struct fsNode *node, uint32_t off, uint32_t size, uint8_t *buf) { - // Get the fat_t structure - fat_t *fs = (fat_t*)(((fsNode_t*)node)->impl_struct); - - // This might be inefficient, but to be honest I don't even care anymore. - // What we're going to do is combine offset and size, read that in using our cluster, and then deal with the consequences of our actions later. - // It will basically be like throwing memory away, but we will use kmalloc so we can return the memory (that is, assuming liballoc is initialized before FAT is) - int total_size = off + size; - - // Now, we need to calculate the amount of clusters this size is going to span. - // This math is weird, but that's just because we don't have a ceil() function - // The first thing we do is calculate the amount of sectors (sectors) that total_size will span. We check if it is dividable by 512, if it is, just divide, if it isn't, round up to nearest 512 and divide. - // Next, we calculate the amount of clusters. It's basically the same math. This can be implemented better, but it works ;) - int sectors = (total_size % 512 == 0) ? total_size / 512 : ((total_size + 512) - (total_size % 512)) / 512; - int clusters = (sectors % fs->drive->bpb->sectorsPerCluster == 0) ? (sectors / fs->drive->bpb->sectorsPerCluster) : ((sectors + fs->drive->bpb->sectorsPerCluster) - (sectors % fs->drive->bpb->sectorsPerCluster)) / fs->drive->bpb->sectorsPerCluster; - - // Now that we've calculated the amount of clusters, we need to read them into a temporary buffer. - uint8_t *buffer = kmalloc(sectors * 512); - - - // Iterate through each cluster and read it in - bool earlyTermination = false; // If fatReadInternal() returns EOF, it terminated too early. - for (int i = 0; i < clusters; i++) { - if (fatReadInternal(node, buffer, fs->drive->bpb->sectorsPerCluster * 512) == EOF && clusters - i > 1) { - earlyTermination = true; - break; - } - } - - if (earlyTermination) { - serialPrintf("fatRead: Too many clusters are being read! Chain terminated too early.\n"); - kfree(buffer); - return -1; - } - - - // Copy based off of the offset - memcpy(buf, buffer + off, size); - - // Free the buffer and return OK. - kfree(buffer); - return 0; -} - -uint32_t fatWrite(struct fsNode *node, uint32_t off, uint32_t size, uint8_t *buf) { - return 0; -} - -uint32_t fatOpen(struct fsNode *node) { - // All we do is just pass it to fatOpenInternal basically - // node->name should contain the filename that we want to open, and node->impl_struct should contain the fat_t object. - // However, as I'm writing this we're currently prototyping - so let's check to make sure fat_t is there, panic if it's not. - - // VFS is stupid so it will call this method in an attempt to open the FAT directory, which might corrupt it. - if (!strcmp(((fsNode_t*)node)->name, "FAT driver")) { return 0; } - - if (((fat_t*)(((fsNode_t*)node)->impl_struct))->drive->bpb->bootjmp[0] != 0xEB) { - panic("FAT", "fatOpen", "bootjmp[0] is not 0xEB"); - } - - - - - fsNode_t *ret; - ret = fatOpenInternal((fsNode_t*)node, ((fsNode_t*)node)->name); - - - - memcpy(node, ret, sizeof(fsNode_t)); - kfree(ret); - - // Compare the two and make sure we're doing this correctly - if (((fsNode_t*)node)->flags != ret->flags) { - panic("FAT", "fatOpen", "memcpy() failed"); - } - - // Done! - return 0; -} - -uint32_t fatClose(struct fsNode *node) { - return 0; // So much closing happening here -} - - -// fatFindDirectory(struct fsNode *node, char *name) - Searches through directories to find a file -fsNode_t *fatFindDirectory(struct fsNode *node, char *name) { - if (strlen(name) == 0) return NULL; // Users! - - char *nodename = ((fsNode_t*)node)->name; - // There's a potential bug where if the user passes the FAT driver object, we want to change it to a "/", because FAT driver isn't a directory. - // Plus: The VFS will try to call this driver will a full path to wherever it's mounted to, and since the mountpoint isn't actually a directory on the VFS, we get some issues. - if (!strcmp(nodename, "FAT driver")) nodename = "/"; - - // A special test case to prevent stupidity in users, where they try and run this with fatDriver as the node and "/". In an attempt to get the root directory, they pass the root directory. - // However, this may also be because node has a name of "FAT driver" instead of "/", in which case we'll go ahead and copy the contents to a return node while changing the name. - if (!strcmp(name, "/")) { - // Do note that this case could also be used on a user trying to get the root of a subdirectory, which is stupid but whatever. - fsNode_t *ret = kmalloc(sizeof(fsNode_t)); - memcpy(ret, node, sizeof(fsNode_t)); - - if (!strcmp(ret->name, "FAT driver")) strcpy(ret->name, "/"); - return ret; - } - - - char *path = kmalloc(strlen(nodename) + strlen(name) + 2); - strcpy(path, nodename); - - // Small patch to fix a potential negative bug. - if (strlen(nodename) > 0) { - if (nodename[strlen(nodename)-1] != '/') strcpy(path + strlen(nodename), "/"); // Adds a '/' if nodename doesn't add a slash. - } - - strcpy(path + strlen(path), name); - path[strlen(path)] = 0; - - // Construct the return node - fsNode_t *ret = fatOpenInternal((fsNode_t*)node, path); // I wanted to use fatOpen, but it doesn't work. Not sure why. - - // Check the flags. finddir methods are supposed to return NULL if something doesn't exist. - if (ret->flags == -1) { - kfree(path); - kfree(ret); - return NULL; - } - - // The issue becomes that the FAT parsing methods will automatically discard the full path and only keep the file/directory name - // Therefore, we'll have to override that. - strcpy(ret->name, path); // This can cause bugs in the future, since I'm not sure fatOpen is prepared to deal with this. - - // Else, we can simply free the path and return the node. - kfree(path); - return ret; -} - -// fatInit(fsNode_t *driveNode, int flags) - Creates a FAT filesystem driver on driveNode and returns it -fsNode_t *fatInit(fsNode_t *driveNode, int flags) { - serialPrintf("fatInit: FAT trying to initialize on driveNode (drive number/impl: %i)...\n", driveNode->impl); - - // Allocate a buffer to read in the BPB - uint32_t *buffer = kmalloc(512); - int ret = driveNode->read(driveNode, 0, 512, buffer); // Read in the 1st sector - - if (ret != IDE_OK) { - kfree(buffer); - return NULL; - } - - // Allocate memory for our structures - fat_t *driver = kmalloc(sizeof(fat_t)); - driver->drive = kmalloc(sizeof(fat_drive_t)); - driver->drive->bpb = kmalloc(sizeof(fat_BPB_t)); - - // Copy the BPB to the driver - memcpy(driver->drive->bpb, buffer, 512); - - // Discard the old buffer - kfree(buffer); - - // bootjmp is the ASM instruction to jump over the BPB - // Normally it's EB 3C 90, but the 3C can vary - if (driver->drive->bpb->bootjmp[0] == 0xEB && driver->drive->bpb->bootjmp[2] == 0x90) { - serialPrintf("fatInit: bootjmp identified on drive\n"); - - // Typecast the bpbs - driver->drive->extended16 = (fat_extendedBPB16_t*)(driver->drive->bpb->extended); - driver->drive->extended32 = (fat_extendedBPB32_t*)(driver->drive->bpb->extended); - - // Set the drive object - driver->drive->driveobj = kmalloc(sizeof(fsNode_t)); - memcpy(driver->drive->driveobj, driveNode, sizeof(fsNode_t)); - - // Now we need to identify the type of FAT used. We can do this by checking the total clusters. - // To calculate the total clusters, we need to first calculate the total number of sectors in the volume. - int totalSectors = (driver->drive->bpb->totalSectors16 == 0) ? driver->drive->bpb->totalSectors32 : driver->drive->bpb->totalSectors16; - driver->drive->totalSectors = totalSectors; - - // Now, we calculate the FAT size in sectors. - int fatSize = (driver->drive->bpb->tableSize16 == 0) ? driver->drive->extended32->tableSize32 : driver->drive->bpb->tableSize16; - driver->drive->fatSize = fatSize; - - // Calculate the size of the root directory - int rootDirSectors = ((driver->drive->bpb->rootEntryCount * 32) + (driver->drive->bpb->bytesPerSector - 1)) / driver->drive->bpb->bytesPerSector; // If 0, this is FAT32. - driver->drive->rootDirSectors = rootDirSectors; - - // Calculate the total number of data sectors. - int dataSectors = totalSectors - (driver->drive->bpb->reservedSectorCount + (driver->drive->bpb->tableCount * fatSize) + rootDirSectors); - driver->drive->dataSectors = dataSectors; - - // Finally, calculate the total number of clusters. - int totalClusters = dataSectors / driver->drive->bpb->sectorsPerCluster; - driver->drive->totalClusters = totalClusters; - - // For good measure, calculate the first data sector (where dirs and files are stored). - int firstDataSector = driver->drive->bpb->reservedSectorCount + (driver->drive->bpb->tableCount * fatSize) + rootDirSectors; - driver->drive->firstDataSector = firstDataSector; - - driver->drive->firstFatSector = driver->drive->bpb->reservedSectorCount; - - // The rootOffset may be calculated differently depending on the FAT filesystem. - int rootOffset = (driver->drive->bpb->tableCount * driver->drive->bpb->tableSize16) + 1; - driver->drive->rootOffset = rootOffset; - - // Identify the FAT type. - if (totalSectors < 4085) { - driver->drive->fatType = 1; // FAT12 - } else if (totalSectors < 65525) { - driver->drive->fatType = 2; // FAT16 - } else if (rootDirSectors == 0) { - driver->drive->fatType = 3; // FAT32 - serialPrintf("fatInit: Detected a FAT32 filesystem. Reading in and verifying FSInfo structure...\n"); - - // FSInfo is a structure that is required for FAT32 drivers. The sector number can be found in the extended BPB for FAT32. - fat_fsInfo_t *fsInfo = kmalloc(512); - int ret = driveNode->read(driveNode, 512 * driver->drive->extended32->fatInfo, 512, (uint8_t*)fsInfo); - if (ret != IDE_OK) { - serialPrintf("fatInit: Failed to read the FSInfo structure.\n"); - kfree(fsInfo); - kfree(driver->drive->bpb); - kfree(driver->drive); - kfree(driver); - return NULL; - } - - // Validate the fsInfo signatures - if (fsInfo->signature != 0x41615252 || fsInfo->signature2 != 0x61417272 || fsInfo->signature3 != 0xAA550000) { - serialPrintf("fatInit: FSInfo signatures invalid!\n\tSignature 1 = 0x%x\n\tSignature 2 = 0x%x\n\tTrailing signature = 0x%x\n", fsInfo->signature, fsInfo->signature2, fsInfo->signature3); - kfree(driver->drive->bpb); - kfree(driver->drive); - kfree(driver); - kfree(fsInfo); - return NULL; - } - - // The fsInfo structure mandates that the last known free cluster count be checked and recomputed if needed. - // It also should be range checked that it is avctually valid. - if (fsInfo->freeClusterCount == 0xFFFFFFFF || fsInfo->freeClusterCount > driver->drive->totalClusters) { - serialPrintf("fatInit: WARNING! Free cluster count needs to be recomputed. THIS IS TBD\n"); - } - - // The same should be done for the starting number for available clusters. We don't use this number for now, but it would be nice to have later. - // This number will likely come in handy when write functions are added, as during cluster allocation it should be modified - if (fsInfo->availableClusterStart == 0xFFFFFFFF || fsInfo->availableClusterStart > driver->drive->totalClusters) { - serialPrintf("fatInit: WARNING! Starting cluster number needs to be recomputed. Assuming 2.\n"); // TBD - } - - - driver->drive->fsInfo = fsInfo; - - // We also need to calculate the root offset - driver->drive->rootOffset = driver->drive->extended32->rootCluster; - - } else { - driver->drive->fatType = 0; // Unknown/unsupported. Return NULL. - kfree(driver->drive->bpb); - kfree(driver->drive); - kfree(driver); - serialPrintf("fatInit: Attempt to initialize on unknown FAT type!\n"); - return NULL; - } - - - - // Create the VFS node and return it - fsNode_t *ret = kmalloc(sizeof(fsNode_t)); - ret->flags = VFS_DIRECTORY; - ret->uid = ret->gid = ret->inode = ret->impl = ret->mask = 0; - ret->open = &fatOpen; - ret->close = &fatClose; - ret->create = NULL; - ret->read = &fatRead; - ret->write = &fatWrite; - ret->finddir = &fatFindDirectory; - ret->readdir = NULL; - ret->mkdir = NULL; - ret->impl_struct = driver; - strcpy(ret->name, "FAT driver"); - - return ret; - } - - return NULL; -} - -struct dirent *fat_readdir(fsNode_t *node, uint32_t index) { - // Okay, so first thing we need to do is calculate the path. - // Because a user might try to list the root, and since root's name is FAT driver, that's not gonna happen - - char *path = kmalloc(strlen(node->name)); - if (!strcmp(path, "FAT driver")) strcpy(path, "/"); - else strcpy(path, node->name); - - // This is not going to be easy to implement. - // Not sure how I'm gonna do it while at least looking somewhat decent... -} - -// (static) fat_tokenize(char *str, const char *sep, char **buf) - Wrapper to strtok_r, just here for compatibility with the impl. (Toaru) -static int fat_tokenize(char *str, const char *sep, char **buf) { - char * pch_i; - char * save_i; - int argc = 0; - pch_i = strtok_r(str,sep,&save_i); - if (!pch_i) { return 0; } - while (pch_i != NULL) { - buf[argc] = (char *)pch_i; - ++argc; - pch_i = strtok_r(NULL,sep,&save_i); - } - buf[argc] = NULL; - return argc; -} - -// fat_fs_mount(const char *device, const char *mount_path) - Mounts the FAT filesystem -fsNode_t *fat_fs_mount(const char *device, const char *mount_path) { - char *arg = kmalloc(strlen(device) + 1); - strcpy(arg, device); - - char *argv[10]; - int argc = fat_tokenize(arg, ",", argv); - - fsNode_t *dev = open_file(argv[0], 0); - if (!dev) { - serialPrintf("fat_fs_mount: Could not open device %s\n", argv[0]); - return NULL; - } - - - // No flags right now - int flags = 0; - - fsNode_t *fat = fatInit(dev, flags); - serialPrintf("%s mounted\n", fat->name); - return fat; -} - -// fat_install(int argc, char *argv[]) - Installs the FAT filesystem driver to automatically initialize on an ext2-type disk -int fat_install(int argc, char *argv[]) { - vfs_registerFilesystem("fat", fat_fs_mount); - return 0; -} \ No newline at end of file +// ============================================================ +// fat.c - FAT filesystem driver +// ============================================================ +// This file was written for the reduceOS C kernel. Please credit me if you use this code. + +#include // Main header file + +// This driver is compatible with VFS standards but is missing writing functionality. That will be added later. +// DO NOT USE ANY INTERNAL FUNCTIONS. USE THE VFS ONES. + +/* +SUPPORTED FILESYSTEMS: + - FAT12 + - FAT16 + - FAT32 +*/ + +// If you want a lot of the details about FAT, see https://wiki.osdev.org/FAT + + +// NOTE: impl_struct is a reference to fat_t + +// Variables +uint8_t FAT[1024]; // File allocation table +fsNode_t driver; // Driver inode + + + +// Functions + +// fatToDOSName(char *filename, char *output, int length) - Convert a filename to DOS 8.3 file format +// NOTE: RESULT MUST BE NULL TERMINATED!!!! +int fatToDOSName(char *filename, char *output, int length) { + if (length > 11 || strlen(filename) > length) return -1; // Users. + + memset(output, ' ', length); + + // So, the FAT filesystem stores filenames as DOS 8.3 style filenames. + // For example, test.txt would be "TEST TXT" + // Another example, dir would be "DIR " + // NOTE: LFNs are different! They can be stored as normal filenames, like "TEST.TXT" Future support will be coming soon. + + // The first thing we need to do is convert the normal filename to uppercase, until we encounter a period. + bool adjustExtension = false; // Set to true if we're dealing with a file. + int i; + + for (i = 0; i < length && i < strlen(filename); i++) { + if (filename[i] == '.') { + adjustExtension = true; + output[i] = ' '; + i++; + break; + } else if (filename[i] == ' ') { + output[i] = ' '; + } else { + output[i] = toupper(filename[i]); + } + } + + if (adjustExtension) { + for (int j = 0; j < 3; j++) { + output[i + (8 - i) + j] = toupper(filename[i + j]); + } + } else if (i < length) { + for (i; i < length; i++) { + output[i] = ' '; + } + } + + return 0; +} + + +// fatParseRootDirectory32(fat_t *fs, char *path, fsNode_t *file) - FAT32 version of fatParseRootDirectory (could probably hack in a way to use fatReadInternal, but this is easier) +int fatParseRootDirectory32(fat_t *fs, char *path, fsNode_t *file) { + // FAT32 uses a cluster chain instead of a fixed root directory. + + if (file->impl) { + // Calculate the first sector of the cluster and read it in + int lba = ((file->impl - 2) * fs->drive->bpb->sectorsPerCluster) + fs->drive->firstDataSector; + uint8_t *buffer = kmalloc(fs->drive->bpb->sectorsPerCluster * 512); + fs->drive->driveobj->read(fs->drive->driveobj, lba * 512, fs->drive->bpb->sectorsPerCluster * 512, buffer); + + + fat_fileEntry_t *directory = (fat_fileEntry_t*)buffer; + + for (int i = 0; i < 16; i++) { + // Nasty hack we have here + + uint8_t attributes = directory->fileName[11]; // Save the attributes byte, as we need to null-terminate the string and compare. + directory->fileName[11] = 0; // Null-terminate + // Something's absolutely horrendously wrong in the stack that I can't copy this to an external variable. + + + // strcmp() will return a 0 if the other string is totally blank, bad! + // Solve with this if statement + if (strlen(directory->fileName) <= 0) continue; + + if (!strcmp(directory->fileName, path)) { + // We found the file! Congrats! + + // Reset the attributes byte + directory->fileName[11] = attributes; + + // Now, let's allocate a fat_t for the impl_struct and copy the contents of our directory. + file->impl_struct = kmalloc(sizeof(fat_t)); + ((fat_t*)(file->impl_struct))->drive = fs->drive; + ((fat_t*)(file->impl_struct))->fileEntry = kmalloc(sizeof(fat_fileEntry_t)); + memcpy(((fat_t*)(file->impl_struct))->fileEntry, directory, sizeof(fat_fileEntry_t)); + + if (((fat_t*)file->impl_struct)->fileEntry->size != directory->size) { + // There was an error in the memcpy() + file->flags = -1; + return EOF; + } + + + + strcpy(file->name, path); // Copy the file name into the result value + + // Check if its a directory or a file + if (directory->fileName[11] == 0x10) file->flags = VFS_DIRECTORY; + else file->flags = VFS_FILE; + + // Set the current cluster + file->impl = ((fat_t*)file->impl_struct)->fileEntry->firstClusterNumberLow; + + // Setup a few other fields + file->length = ((fat_t*)file->impl_struct)->fileEntry->size; + + + kfree(buffer); + return 1; + } + + directory++; + } + + // We couldn't find the file on this attempt. Let's calculate the next cluster number and try again. + // This requires us to read in the FAT. + + uint32_t fatOffset = file->impl * 4; + uint32_t fatSector = fs->drive->firstFatSector + (fatOffset / 512); + uint32_t entryOffset = fatOffset % 512; + + // Read the FATs + fs->drive->driveobj->read(fs->drive->driveobj, fatSector * 512, 1024, (uint8_t*)FAT); + + // Get the cluster number and mask it to ignore the high 4 bits. + uint32_t nextCluster = *(unsigned int*)&FAT[entryOffset]; + nextCluster &= 0x0FFFFFFF; + + // Check if it's the end of the root directory, or if it is corrupt. + if (nextCluster >= 0x0FFFFFF8 || nextCluster == 0x0FFFFFF7) return EOF; + + file->impl = nextCluster; + return 0; + } else { + serialPrintf("fatParseRootDirectory32: file.impl is unavailable. Returning EOF for error.\n"); + return EOF; + } + + return EOF; // Error. + +} + +// fatParseRootDirectory(fat_t *fs, char *path) - Locate a file or directory in the root directory +fsNode_t *fatParseRootDirectory(fat_t *fs, char *path) { + fsNode_t *file = kmalloc(sizeof(fsNode_t)); + + + // Call helper function for 8.3 filename + char filename[11]; + if (fatToDOSName(path, filename, 11) != 0) { + file->flags = -1; + return file; + } + + filename[11] = 0; + + // FAT32 is for another function, it's more complex. + if (fs->drive->fatType == 3) { + // Similar to fatReadInternal, we will iterate until we've exhausted all available cluster entries. + // Return codes: 0 = keep calling, 1 = found the file, -1 = EOF, return failure + file->impl = fs->drive->rootOffset; // First cluster number. + + + while (1) { + int ret = fatParseRootDirectory32(fs, filename, file); + if (ret == 1) return file; // Its already setup everything, we can just return the file. + + if (ret == -1) { + file->flags = -1; // Couldn't find the file. + return file; + } + + if (ret != 0) { + // There's been a problem in the code. + serialPrintf("fatParseRootDirectory: FAT32 parsing failed!\n"); + file->flags = -1; + return file; + } + } + } + + + uint8_t *buffer = kmalloc(512); + + for (int sector = 0; sector < 14; sector++) { + // Read in the sector. This calculation differs depending on what FAT type is being used. + // FAT12/16 have the root directory at a fixed position, and we can calculate it easily. + // FAT32 is where it gets tricky. FAT32 instead gives the root directory offset with a cluster, and it CAN be a cluster chain. + // This means that extra work is put in for a FAT32 system, and is why we would call to another method to do it earlier. + + //int lba = ((fs->drive->bpb->tableCount * fs->drive->bpb->tableSize16) + 1) + sector; + int lba = fs->drive->rootOffset + sector; + fs->drive->driveobj->read(fs->drive->driveobj, lba * 512, 512, buffer); + + fat_fileEntry_t *directory = (fat_fileEntry_t*)buffer; + + for (int i = 0; i < 16; i++) { + // Nasty hack we have here + + uint8_t attributes = directory->fileName[11]; // Save the attributes byte, as we need to null-terminate the string and compare. + directory->fileName[11] = 0; // Null-terminate + // Something's absolutely horrendously wrong in the stack that I can't copy this to an external variable. + + + // strcmp() will return a 0 if the other string is totally blank, bad! + // Solve with this if statement + if (strlen(directory->fileName) <= 0) continue; + + if (!strcmp(directory->fileName, filename)) { + // We found the file! Congrats! + + // Reset the attributes byte + directory->fileName[11] = attributes; + + // Now, let's allocate a fat_t for the impl_struct and copy the contents of our directory. + file->impl_struct = kmalloc(sizeof(fat_t)); + ((fat_t*)(file->impl_struct))->drive = fs->drive; + ((fat_t*)(file->impl_struct))->fileEntry = kmalloc(sizeof(fat_fileEntry_t)); + memcpy(((fat_t*)(file->impl_struct))->fileEntry, directory, sizeof(fat_fileEntry_t)); + + if (((fat_t*)file->impl_struct)->fileEntry->size != directory->size) { + // There was an error in the memcpy() + file->flags = -1; + return file; + } + + + + strcpy(file->name, path); // Copy the file name into the result value + + // Check if its a directory or a file + if (directory->fileName[11] == 0x10) file->flags = VFS_DIRECTORY; + else file->flags = VFS_FILE; + + // Set the current cluster + file->impl = ((fat_t*)file->impl_struct)->fileEntry->firstClusterNumberLow; + + // Setup a few other fields + file->length = ((fat_t*)file->impl_struct)->fileEntry->size; + + + kfree(buffer); + return file; + } + + directory++; + } + + + memset(buffer, 0, sizeof(buffer)); + } + + // Could not find file. + kfree(buffer); + file->flags = -1; // TBD: Make a VFS_INVALID flag + return file; +} + + +// fatReadInternal(fsNode_t *file, uint8_t *buffer, uint32_t length) - Reads a file in the FAT +// NOTE: DO NOT CALL DIRECTLY. CALL fatRead AND IT WILL SOLVE ALL YOUR PROBLEMS! +int fatReadInternal(fsNode_t *file, uint8_t *buffer, uint32_t length) { + if (file) { + // Get the fat_t structure + fat_t *fs = (fat_t*)(file->impl_struct); + + // Calculate and read in the starting physical sector + uint16_t cluster = file->impl; + uint32_t sector = ((cluster - 2) * fs->drive->bpb->sectorsPerCluster) + fs->drive->firstDataSector; + + uint8_t sector_buffer[fs->drive->bpb->sectorsPerCluster * 512]; + fs->drive->driveobj->read(fs->drive->driveobj, (uint32_t)sector * 512, fs->drive->bpb->sectorsPerCluster * 512, sector_buffer); + + + + // Copy the sector buffer to the output buffer + uint32_t len = (length > (fs->drive->bpb->sectorsPerCluster * 512)) ? fs->drive->bpb->sectorsPerCluster * 512 : length; + memcpy(buffer, sector_buffer, len); + + // Locate the File Allocation Table sector + uint32_t fatOffset; + if (fs->drive->fatType == 1) fatOffset = cluster + (cluster / 2); + else if (fs->drive->fatType == 2) fatOffset = cluster * 2; + else if (fs->drive->fatType == 3) fatOffset = cluster * 4; + else { serialPrintf("fatReadInternal: Unknown fatType!\n"); return -1; } + + + uint32_t fatSector = fs->drive->firstFatSector + (fatOffset / 512); + uint32_t entryOffset = fatOffset % 512; + + + + // Read the FATs + fs->drive->driveobj->read(fs->drive->driveobj, fatSector * 512, 1024, (uint8_t*)FAT); + + + // Read entry for the next cluster + // This should be done differently depending on the FAT version being used. + if (fs->drive->fatType == 1 || fs->drive->fatType == 2) { + uint16_t nextCluster = *(uint16_t*)&FAT[entryOffset]; + + + if (fs->drive->fatType == 1) { + // Convert the cluster (FAT12 only) + nextCluster = (cluster & 1) ? nextCluster >> 4 : nextCluster & 0xFFF; + } + + // Test for EOF + if ((nextCluster >= 0xFF8 && fs->drive->fatType == 1) || (nextCluster >= 0xFFF8 && fs->drive->fatType == 2)) { + return EOF; + } + + // Test for file corruption + if (nextCluster == 0 || (nextCluster == 0xFFF7 && fs->drive->fatType == 2) || (nextCluster == 0xFF7 && fs->drive->fatType == 1)) { + return EOF; + } + + // Set the next cluster + file->impl = nextCluster; + } else if (fs->drive->fatType == 3) { + // FAT32 needs to use an unsigned integer instead of a short. + + uint32_t nextCluster = *(uint32_t*)&FAT[entryOffset]; + nextCluster &= 0x0FFFFFFF; + + // Test for EOF and file corruption + if (nextCluster >= 0x0FFFFFF8 || nextCluster == 0x0FFFFFF7) { + return EOF; + } + + file->impl = nextCluster; + } + } + + return 0; +} + +// fatParseSubdirectory(fsNode_t *file, const char *path) - Locate a file/folder in a subdirectory. +fsNode_t *fatParseSubdirectory(fsNode_t *file, const char *path) { + fsNode_t *ret = kmalloc(sizeof(fsNode_t)); + ret->impl = file->impl; + ret->impl_struct = file->impl_struct; + + // First, get the DOS 8.3 filename. + char *filename = kmalloc(12); + if (fatToDOSName(path, filename, 11) != 0) { + ret->flags = -1; + return ret; + } + filename[11] = 0; + + // Search the directory (note: just randomly picked a value for retries because orig. impl is seemingly bugged) + for (int count = 0; count < 5; count++) { + // Read in the directory + uint8_t *buffer = kmalloc(512); + + int status = fatReadInternal(ret, buffer, 512); + + + // Setup the directory + fat_fileEntry_t *directory = (fat_fileEntry_t*)buffer; + + // 16 entries in a directory + for (int i = 0; i < 16; i++) { + // Get the filename + uint8_t attributes = directory->fileName[11]; // Save attributes + directory->fileName[11] = 0; + + + if (!strcmp(filename, directory->fileName)) { + // We found it! Setup the return file. + // Reset the attributes byte + directory->fileName[11] = attributes; + + // Now, let's allocate a fat_t for the impl_struct and copy the contents of our directory. + ret->impl_struct = kmalloc(sizeof(fat_t)); + ((fat_t*)(ret->impl_struct))->drive = ((fat_t*)(file->impl_struct))->drive; + ((fat_t*)(ret->impl_struct))->fileEntry = kmalloc(sizeof(fat_fileEntry_t)); + memcpy(((fat_t*)(ret->impl_struct))->fileEntry, directory, sizeof(fat_fileEntry_t)); + + if (((fat_t*)ret->impl_struct)->fileEntry->size != directory->size) { + // There was an error in the memcpy() + ret->flags = -1; + return ret; + } + + + strcpy(ret->name, path); // Copy the file name into the result value + + // Check if its a directory or a file + if (directory->fileName[11] == 0x10) ret->flags = VFS_DIRECTORY; + else ret->flags = VFS_FILE; + + // Set the current cluster + ret->impl = ((fat_t*)ret->impl_struct)->fileEntry->firstClusterNumberLow; + + // Setup a few other fields + ret->length = ((fat_t*)ret->impl_struct)->fileEntry->size; + + kfree(buffer); + return ret; + + } + + directory++; + } + + + // Check if EOF + if (status == EOF) { + kfree(buffer); + break; + } + } + + ret->flags = -1; + return ret; + +} + + +// fatOpenInternal(fsNode_t *driver, char *filename) - File open, can parse slashes and subdirectories +// WARNING: DO NOT USE OUTSIDE OF fatOpen - IT WILL NOT WORK! +fsNode_t *fatOpenInternal(fsNode_t *driver, char *filename) { + fsNode_t *directory = NULL; // directory is our current directory + bool isRootDir = true; + + // First, we do some hacky logic to determine if the file is in a subdirectory. + char *filepath = filename; + char *slash = strchr(filepath, '/'); + + + + if (!slash) { + fat_t *fs = (fat_t*)(driver->impl_struct); + // The file is not in a subdirectory. Scan the root directory. + directory = fatParseRootDirectory((fat_t*)(driver->impl_struct), filepath); + + if (directory->flags == VFS_FILE || directory->flags == VFS_DIRECTORY) { + return directory; // Nailed it + } + + // Failed to find + directory->flags = -1; // TBD: Make a VFS_INVALID flag. + return directory; + } + + slash++; // Go to next character + + // Okay, so there's a bit of a funny little bug in the code again. + // It's if the user tries to pass dir/nested instead of /dir/nested. + // The code skips to the first '/', completely ignoring the dir/ + // So we'll run a check here to make sure something's not going on here. + + if (filename[0] != '/') { + // There's a slash, but it's not at the beginning. Reset slash to be at 0. + slash = filepath; + } + + while (slash) { + // Get the path name. + char path[16]; + int i = 0; + for (i = 0; i < 16; i++) { + if (slash[i] == '/' || slash[i] == '\0') break; + + // Copy the character. + path[i] = slash[i]; + } + + path[i] = 0; // Null-terminate. + + // Check the bottom of the function for a bug description, but we'll check if the length is 0, as that means the user ended it with a "/" and nothing else + // This means they want a directory. + if (strlen(path) <= 0 && directory != NULL) { + // Preventing page faults with a directory != NULL + if (directory->flags == VFS_DIRECTORY) return directory; + } + + // Open subdirectory or file + if (isRootDir) { + directory = fatParseRootDirectory((fat_t*)(driver->impl_struct), path); + isRootDir = false; + } else { + directory = fatParseSubdirectory(directory, path); + } + + // Found directory or file? + if (directory->flags == -1) { + break; + } + + // Found file? + if (directory->flags == VFS_FILE) { + return directory; + } + + // Find the next '/' + slash = strchr(slash + 1, '/'); + if (slash) slash++; + else { + // Here's an interesting conundrum. This function searches through subdirectories for files/directories. + // If we want a file it's all good, it'll just return a file. But not a directory, since it might be a subdirectory that needs to be searched. + // We can resolve this using a little else statement that says if there are no more slashes in the path and there's a directory, return it. + + // There's just a slight problem: If the user puts something like "/dir/". This will break the code, since it sees another slash and thinks "oh, we have to use that slash." + // So we take care of that using the strlen() check further up + + if (directory->flags == VFS_DIRECTORY) return directory; + } + } + + // Unable to find. + serialPrintf("fatOpen: File %s not found.\n", filename); + directory->flags = -1; + return directory; +} + +/* VFS FUNCTIONS */ + +uint32_t fatRead(struct fsNode *node, uint32_t off, uint32_t size, uint8_t *buf) { + // Get the fat_t structure + fat_t *fs = (fat_t*)(((fsNode_t*)node)->impl_struct); + + // This might be inefficient, but to be honest I don't even care anymore. + // What we're going to do is combine offset and size, read that in using our cluster, and then deal with the consequences of our actions later. + // It will basically be like throwing memory away, but we will use kmalloc so we can return the memory (that is, assuming liballoc is initialized before FAT is) + int total_size = off + size; + + // Now, we need to calculate the amount of clusters this size is going to span. + // This math is weird, but that's just because we don't have a ceil() function + // The first thing we do is calculate the amount of sectors (sectors) that total_size will span. We check if it is dividable by 512, if it is, just divide, if it isn't, round up to nearest 512 and divide. + // Next, we calculate the amount of clusters. It's basically the same math. This can be implemented better, but it works ;) + int sectors = (total_size % 512 == 0) ? total_size / 512 : ((total_size + 512) - (total_size % 512)) / 512; + int clusters = (sectors % fs->drive->bpb->sectorsPerCluster == 0) ? (sectors / fs->drive->bpb->sectorsPerCluster) : ((sectors + fs->drive->bpb->sectorsPerCluster) - (sectors % fs->drive->bpb->sectorsPerCluster)) / fs->drive->bpb->sectorsPerCluster; + + // Now that we've calculated the amount of clusters, we need to read them into a temporary buffer. + uint8_t *buffer = kmalloc(sectors * 512); + + + // Iterate through each cluster and read it in + bool earlyTermination = false; // If fatReadInternal() returns EOF, it terminated too early. + for (int i = 0; i < clusters; i++) { + if (fatReadInternal(node, buffer, fs->drive->bpb->sectorsPerCluster * 512) == EOF && clusters - i > 1) { + earlyTermination = true; + break; + } + } + + if (earlyTermination) { + serialPrintf("fatRead: Too many clusters are being read! Chain terminated too early.\n"); + kfree(buffer); + return -1; + } + + + // Copy based off of the offset + memcpy(buf, buffer + off, size); + + // Free the buffer and return OK. + kfree(buffer); + return 0; +} + +uint32_t fatWrite(struct fsNode *node, uint32_t off, uint32_t size, uint8_t *buf) { + return 0; +} + +uint32_t fatOpen(struct fsNode *node) { + // All we do is just pass it to fatOpenInternal basically + // node->name should contain the filename that we want to open, and node->impl_struct should contain the fat_t object. + // However, as I'm writing this we're currently prototyping - so let's check to make sure fat_t is there, panic if it's not. + + // VFS is stupid so it will call this method in an attempt to open the FAT directory, which might corrupt it. + if (!strcmp(((fsNode_t*)node)->name, "FAT driver")) { return 0; } + + if (((fat_t*)(((fsNode_t*)node)->impl_struct))->drive->bpb->bootjmp[0] != 0xEB) { + panic("FAT", "fatOpen", "bootjmp[0] is not 0xEB"); + } + + + + + fsNode_t *ret; + ret = fatOpenInternal((fsNode_t*)node, ((fsNode_t*)node)->name); + + + + memcpy(node, ret, sizeof(fsNode_t)); + kfree(ret); + + // Compare the two and make sure we're doing this correctly + if (((fsNode_t*)node)->flags != ret->flags) { + panic("FAT", "fatOpen", "memcpy() failed"); + } + + // Done! + return 0; +} + +uint32_t fatClose(struct fsNode *node) { + return 0; // So much closing happening here +} + + +// fatFindDirectory(struct fsNode *node, char *name) - Searches through directories to find a file +fsNode_t *fatFindDirectory(struct fsNode *node, char *name) { + if (strlen(name) == 0) return NULL; // Users! + + char *nodename = ((fsNode_t*)node)->name; + // There's a potential bug where if the user passes the FAT driver object, we want to change it to a "/", because FAT driver isn't a directory. + // Plus: The VFS will try to call this driver will a full path to wherever it's mounted to, and since the mountpoint isn't actually a directory on the VFS, we get some issues. + if (!strcmp(nodename, "FAT driver")) nodename = "/"; + + // A special test case to prevent stupidity in users, where they try and run this with fatDriver as the node and "/". In an attempt to get the root directory, they pass the root directory. + // However, this may also be because node has a name of "FAT driver" instead of "/", in which case we'll go ahead and copy the contents to a return node while changing the name. + if (!strcmp(name, "/")) { + // Do note that this case could also be used on a user trying to get the root of a subdirectory, which is stupid but whatever. + fsNode_t *ret = kmalloc(sizeof(fsNode_t)); + memcpy(ret, node, sizeof(fsNode_t)); + + if (!strcmp(ret->name, "FAT driver")) strcpy(ret->name, "/"); + return ret; + } + + + char *path = kmalloc(strlen(nodename) + strlen(name) + 2); + strcpy(path, nodename); + + // Small patch to fix a potential negative bug. + if (strlen(nodename) > 0) { + if (nodename[strlen(nodename)-1] != '/') strcpy(path + strlen(nodename), "/"); // Adds a '/' if nodename doesn't add a slash. + } + + strcpy(path + strlen(path), name); + path[strlen(path)] = 0; + + // Construct the return node + fsNode_t *ret = fatOpenInternal((fsNode_t*)node, path); // I wanted to use fatOpen, but it doesn't work. Not sure why. + + // Check the flags. finddir methods are supposed to return NULL if something doesn't exist. + if (ret->flags == -1) { + kfree(path); + kfree(ret); + return NULL; + } + + // The issue becomes that the FAT parsing methods will automatically discard the full path and only keep the file/directory name + // Therefore, we'll have to override that. + strcpy(ret->name, path); // This can cause bugs in the future, since I'm not sure fatOpen is prepared to deal with this. + + // Else, we can simply free the path and return the node. + kfree(path); + return ret; +} + +// fatInit(fsNode_t *driveNode, int flags) - Creates a FAT filesystem driver on driveNode and returns it +fsNode_t *fatInit(fsNode_t *driveNode, int flags) { + serialPrintf("fatInit: FAT trying to initialize on driveNode (drive number/impl: %i)...\n", driveNode->impl); + + // Allocate a buffer to read in the BPB + uint32_t *buffer = kmalloc(512); + int ret = driveNode->read(driveNode, 0, 512, buffer); // Read in the 1st sector + + if (ret != IDE_OK) { + kfree(buffer); + return NULL; + } + + // Allocate memory for our structures + fat_t *driver = kmalloc(sizeof(fat_t)); + driver->drive = kmalloc(sizeof(fat_drive_t)); + driver->drive->bpb = kmalloc(sizeof(fat_BPB_t)); + + // Copy the BPB to the driver + memcpy(driver->drive->bpb, buffer, 512); + + // Discard the old buffer + kfree(buffer); + + // bootjmp is the ASM instruction to jump over the BPB + // Normally it's EB 3C 90, but the 3C can vary + if (driver->drive->bpb->bootjmp[0] == 0xEB && driver->drive->bpb->bootjmp[2] == 0x90) { + serialPrintf("fatInit: bootjmp identified on drive\n"); + + // Typecast the bpbs + driver->drive->extended16 = (fat_extendedBPB16_t*)(driver->drive->bpb->extended); + driver->drive->extended32 = (fat_extendedBPB32_t*)(driver->drive->bpb->extended); + + // Set the drive object + driver->drive->driveobj = kmalloc(sizeof(fsNode_t)); + memcpy(driver->drive->driveobj, driveNode, sizeof(fsNode_t)); + + // Now we need to identify the type of FAT used. We can do this by checking the total clusters. + // To calculate the total clusters, we need to first calculate the total number of sectors in the volume. + int totalSectors = (driver->drive->bpb->totalSectors16 == 0) ? driver->drive->bpb->totalSectors32 : driver->drive->bpb->totalSectors16; + driver->drive->totalSectors = totalSectors; + + // Now, we calculate the FAT size in sectors. + int fatSize = (driver->drive->bpb->tableSize16 == 0) ? driver->drive->extended32->tableSize32 : driver->drive->bpb->tableSize16; + driver->drive->fatSize = fatSize; + + // Calculate the size of the root directory + int rootDirSectors = ((driver->drive->bpb->rootEntryCount * 32) + (driver->drive->bpb->bytesPerSector - 1)) / driver->drive->bpb->bytesPerSector; // If 0, this is FAT32. + driver->drive->rootDirSectors = rootDirSectors; + + // Calculate the total number of data sectors. + int dataSectors = totalSectors - (driver->drive->bpb->reservedSectorCount + (driver->drive->bpb->tableCount * fatSize) + rootDirSectors); + driver->drive->dataSectors = dataSectors; + + // Finally, calculate the total number of clusters. + int totalClusters = dataSectors / driver->drive->bpb->sectorsPerCluster; + driver->drive->totalClusters = totalClusters; + + // For good measure, calculate the first data sector (where dirs and files are stored). + int firstDataSector = driver->drive->bpb->reservedSectorCount + (driver->drive->bpb->tableCount * fatSize) + rootDirSectors; + driver->drive->firstDataSector = firstDataSector; + + driver->drive->firstFatSector = driver->drive->bpb->reservedSectorCount; + + // The rootOffset may be calculated differently depending on the FAT filesystem. + int rootOffset = (driver->drive->bpb->tableCount * driver->drive->bpb->tableSize16) + 1; + driver->drive->rootOffset = rootOffset; + + // Identify the FAT type. + if (totalSectors < 4085) { + driver->drive->fatType = 1; // FAT12 + } else if (totalSectors < 65525) { + driver->drive->fatType = 2; // FAT16 + } else if (rootDirSectors == 0) { + driver->drive->fatType = 3; // FAT32 + serialPrintf("fatInit: Detected a FAT32 filesystem. Reading in and verifying FSInfo structure...\n"); + + // FSInfo is a structure that is required for FAT32 drivers. The sector number can be found in the extended BPB for FAT32. + fat_fsInfo_t *fsInfo = kmalloc(512); + int ret = driveNode->read(driveNode, 512 * driver->drive->extended32->fatInfo, 512, (uint8_t*)fsInfo); + if (ret != IDE_OK) { + serialPrintf("fatInit: Failed to read the FSInfo structure.\n"); + kfree(fsInfo); + kfree(driver->drive->bpb); + kfree(driver->drive); + kfree(driver); + return NULL; + } + + // Validate the fsInfo signatures + if (fsInfo->signature != 0x41615252 || fsInfo->signature2 != 0x61417272 || fsInfo->signature3 != 0xAA550000) { + serialPrintf("fatInit: FSInfo signatures invalid!\n\tSignature 1 = 0x%x\n\tSignature 2 = 0x%x\n\tTrailing signature = 0x%x\n", fsInfo->signature, fsInfo->signature2, fsInfo->signature3); + kfree(driver->drive->bpb); + kfree(driver->drive); + kfree(driver); + kfree(fsInfo); + return NULL; + } + + // The fsInfo structure mandates that the last known free cluster count be checked and recomputed if needed. + // It also should be range checked that it is avctually valid. + if (fsInfo->freeClusterCount == 0xFFFFFFFF || fsInfo->freeClusterCount > driver->drive->totalClusters) { + serialPrintf("fatInit: WARNING! Free cluster count needs to be recomputed. THIS IS TBD\n"); + } + + // The same should be done for the starting number for available clusters. We don't use this number for now, but it would be nice to have later. + // This number will likely come in handy when write functions are added, as during cluster allocation it should be modified + if (fsInfo->availableClusterStart == 0xFFFFFFFF || fsInfo->availableClusterStart > driver->drive->totalClusters) { + serialPrintf("fatInit: WARNING! Starting cluster number needs to be recomputed. Assuming 2.\n"); // TBD + } + + + driver->drive->fsInfo = fsInfo; + + // We also need to calculate the root offset + driver->drive->rootOffset = driver->drive->extended32->rootCluster; + + } else { + driver->drive->fatType = 0; // Unknown/unsupported. Return NULL. + kfree(driver->drive->bpb); + kfree(driver->drive); + kfree(driver); + serialPrintf("fatInit: Attempt to initialize on unknown FAT type!\n"); + return NULL; + } + + + + // Create the VFS node and return it + fsNode_t *ret = kmalloc(sizeof(fsNode_t)); + ret->flags = VFS_DIRECTORY; + ret->uid = ret->gid = ret->inode = ret->impl = ret->mask = 0; + ret->open = &fatOpen; + ret->close = &fatClose; + ret->create = NULL; + ret->read = &fatRead; + ret->write = &fatWrite; + ret->finddir = &fatFindDirectory; + ret->readdir = NULL; + ret->mkdir = NULL; + ret->impl_struct = driver; + strcpy(ret->name, "FAT driver"); + + return ret; + } + + return NULL; +} + +struct dirent *fat_readdir(fsNode_t *node, uint32_t index) { + // Okay, so first thing we need to do is calculate the path. + // Because a user might try to list the root, and since root's name is FAT driver, that's not gonna happen + + char *path = kmalloc(strlen(node->name)); + if (!strcmp(path, "FAT driver")) strcpy(path, "/"); + else strcpy(path, node->name); + + // This is not going to be easy to implement. + // Not sure how I'm gonna do it while at least looking somewhat decent... +} + +// (static) fat_tokenize(char *str, const char *sep, char **buf) - Wrapper to strtok_r, just here for compatibility with the impl. (Toaru) +static int fat_tokenize(char *str, const char *sep, char **buf) { + char * pch_i; + char * save_i; + int argc = 0; + pch_i = strtok_r(str,sep,&save_i); + if (!pch_i) { return 0; } + while (pch_i != NULL) { + buf[argc] = (char *)pch_i; + ++argc; + pch_i = strtok_r(NULL,sep,&save_i); + } + buf[argc] = NULL; + return argc; +} + +// fat_fs_mount(const char *device, const char *mount_path) - Mounts the FAT filesystem +fsNode_t *fat_fs_mount(const char *device, const char *mount_path) { + char *arg = kmalloc(strlen(device) + 1); + strcpy(arg, device); + + char *argv[10]; + int argc = fat_tokenize(arg, ",", argv); + + fsNode_t *dev = open_file(argv[0], 0); + if (!dev) { + serialPrintf("fat_fs_mount: Could not open device %s\n", argv[0]); + return NULL; + } + + + // No flags right now + int flags = 0; + + fsNode_t *fat = fatInit(dev, flags); + serialPrintf("%s mounted\n", fat->name); + return fat; +} + +// fat_install(int argc, char *argv[]) - Installs the FAT filesystem driver to automatically initialize on an ext2-type disk +int fat_install(int argc, char *argv[]) { + vfs_registerFilesystem("fat", fat_fs_mount); + return 0; +} diff --git a/source/kernel/fs/initrd.c b/source/kernel/fs/initrd.c index 602504c1..e438b1a2 100644 --- a/source/kernel/fs/initrd.c +++ b/source/kernel/fs/initrd.c @@ -1,151 +1,151 @@ -// ============================================================ -// initrd.c - loads the reduceOS initial ramdisk -// ============================================================ -// Some code and concepts are from JamesM's kernel development tutorials. - -#include "include/initrd.h" // Main header file - -// First of all, what is an initial ramdisk? -/* Well, an initial ramdisk is a filesystem that is loaded in to memory on boot. -In reduceOS, it stores configuration files, executables, drivers, anything really. -However, it is important to note that an initial ramdisk is not actually a root filesystem. -In fact, it usually contains the drivers to access the root filesystem. -You cannot delete files in an initrd. -As of January 2nd, 2022, reduceOS's initial ramdisk cannot access subdirectories (we're using James Molloy's adaptation right now and will later switch.)*/ - - -// This initial ramdisk implemenetation is also CURRENTLY based on James Molloy's implementation. I'm working on my own implementation with subdirectory support and more. - -// GRUB passes our initrd as a mod - we handle the mod getting and stuff in the kernel C file. - -// First of all, begin with our variables. - -initrd_imageHeader_t *initrdHeader; // The header for the initrd. -initrd_fileHeader_t *fileHeaders; // A list of file headers -fsNode_t *initrdRoot; // The root directory node -fsNode_t *initrdDev; // dev directory node (used for mounting devfs later in reduceOS lifetime) -fsNode_t *rootNodes; // List of file nodes -int rootNodes_amount; // Amount of file nodes. - -struct dirent dirent; - - -// Moving on to the functions.... - - - -// (static) initrdRead(fsNode_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) - Read a file from an initrd. -static uint32_t initrdRead(fsNode_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) { - initrd_fileHeader_t header = fileHeaders[node->inode]; - if (offset > header.length) return 0; - if (offset + size > header.length) size = header.length - offset; - - memcpy(buffer, (uint8_t*)(header.offset + offset), size); - return size; -} - - - -// (static) initrdReaddir(fsNode_t *node, uint32_t index) - Reads a directory in the initrd. -static struct dirent *initrdReaddir(fsNode_t *node, uint32_t index) { - if (node == initrdRoot && index == 0) { - strcpy(dirent.name, "dev"); - dirent.name[3] = 0; - dirent.ino = 0; - return &dirent; - } - - if (index-1 >= rootNodes_amount) return 0; // Sneaky users trying to muck up our input! - - strcpy(dirent.name, rootNodes[index-1].name); - dirent.name[strlen(rootNodes[index-1].name)] = 0; - dirent.ino = rootNodes[index-1].inode; - return &dirent; -} - - -// (static) initrdFinddir(fsNode_t *node, char *name) - Finds a directory in the VFS node *node with the name *name. -static fsNode_t *initrdFinddir(fsNode_t *node, char *name) { - // Check if the user is attempting to find the dev node. - if (node == initrdRoot && !strcmp(name, "dev")) return initrdDev; - - for (int i = 0; i < rootNodes_amount; i++) { - if (!strcmp(name, rootNodes[i].name)) return &rootNodes[i]; - } - - return 0; -} - - - -// We have just one function that is accessible from the outside. -// initrdInit(uint32_t location) - Initializes the initrd image (located at location) -fsNode_t *initrdInit(uint32_t location) { - // First, iniitalize the main and file header pointers and populate the root directory. - - - - initrdHeader = (initrd_imageHeader_t*)location; - fileHeaders = (initrd_fileHeader_t*) (location + sizeof(initrd_imageHeader_t)); - - // Next, initialize the root directory. - // This is pretty simple. Allocate memory and setup all of the values (most are 0, but some have function pointers) - initrdRoot = (fsNode_t*)kmalloc(sizeof(fsNode_t)); - strcpy(initrdRoot->name, "initrd"); - initrdRoot->mask = initrdRoot->uid = initrdRoot->gid = initrdRoot->inode = initrdRoot->length = 0; - initrdRoot->flags = VFS_DIRECTORY; - initrdRoot->read = 0; - initrdRoot->write = 0; - initrdRoot->open = 0; - initrdRoot->close = 0; - initrdRoot->readdir = &initrdReaddir; - initrdRoot->finddir = &initrdFinddir; - initrdRoot->ptr = 0; - initrdRoot->impl = 0; - - // Now, initialize the dev directory. - initrdDev = (fsNode_t*)kmalloc(sizeof(fsNode_t)); - strcpy(initrdDev->name, "dev"); - initrdDev->mask = initrdDev->uid = initrdDev->gid = initrdDev->inode = initrdDev->length = 0; - initrdDev->flags = VFS_DIRECTORY; - initrdDev->read = 0; - initrdDev->write = 0; - initrdDev->open = 0; - initrdDev->close = 0; - initrdDev->readdir = &initrdReaddir; - initrdDev->finddir = &initrdFinddir; - initrdDev->ptr = 0; - initrdDev->impl = 0; - - // reduceOS has a special initial ramdisk structure - // Each file has a magic number starting at the top. - // The magic number is specific to each directory the file is in (starting at 0xAA for root directory) - // Each subdirectory has its own magic number too, 0xBA. - - - - rootNodes = (fsNode_t*)kmalloc(sizeof(fsNode_t) * initrdHeader->fileAmnt); - rootNodes_amount = initrdHeader->fileAmnt; - - // Iterate through all files and setup each one. - for (int i = 0; i < initrdHeader->fileAmnt; i++) { - // Edit the files header (currently holds the offset relative to ramdisk start) to point to file offset relative to size of memory. - fileHeaders[i].offset += location; - - // Create a new file node. - strcpy(rootNodes[i].name, &fileHeaders[i].name); - rootNodes[i].mask = rootNodes[i].uid = rootNodes[i].gid = 0; - rootNodes[i].length = fileHeaders[i].length; - rootNodes[i].inode = i; - rootNodes[i].flags = VFS_FILE; - rootNodes[i].read = &initrdRead; - rootNodes[i].write = 0; - rootNodes[i].readdir = 0; - rootNodes[i].finddir = 0; - rootNodes[i].open = 0; - rootNodes[i].close = 0; - rootNodes[i].impl = 0; - } - - return initrdRoot; -} \ No newline at end of file +// ============================================================ +// initrd.c - loads the reduceOS initial ramdisk +// ============================================================ +// Some code and concepts are from JamesM's kernel development tutorials. + +#include // Main header file + +// First of all, what is an initial ramdisk? +/* Well, an initial ramdisk is a filesystem that is loaded in to memory on boot. +In reduceOS, it stores configuration files, executables, drivers, anything really. +However, it is important to note that an initial ramdisk is not actually a root filesystem. +In fact, it usually contains the drivers to access the root filesystem. +You cannot delete files in an initrd. +As of January 2nd, 2022, reduceOS's initial ramdisk cannot access subdirectories (we're using James Molloy's adaptation right now and will later switch.)*/ + + +// This initial ramdisk implemenetation is also CURRENTLY based on James Molloy's implementation. I'm working on my own implementation with subdirectory support and more. + +// GRUB passes our initrd as a mod - we handle the mod getting and stuff in the kernel C file. + +// First of all, begin with our variables. + +initrd_imageHeader_t *initrdHeader; // The header for the initrd. +initrd_fileHeader_t *fileHeaders; // A list of file headers +fsNode_t *initrdRoot; // The root directory node +fsNode_t *initrdDev; // dev directory node (used for mounting devfs later in reduceOS lifetime) +fsNode_t *rootNodes; // List of file nodes +int rootNodes_amount; // Amount of file nodes. + +struct dirent dirent; + + +// Moving on to the functions.... + + + +// (static) initrdRead(fsNode_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) - Read a file from an initrd. +static uint32_t initrdRead(fsNode_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) { + initrd_fileHeader_t header = fileHeaders[node->inode]; + if (offset > header.length) return 0; + if (offset + size > header.length) size = header.length - offset; + + memcpy(buffer, (uint8_t*)(header.offset + offset), size); + return size; +} + + + +// (static) initrdReaddir(fsNode_t *node, uint32_t index) - Reads a directory in the initrd. +static struct dirent *initrdReaddir(fsNode_t *node, uint32_t index) { + if (node == initrdRoot && index == 0) { + strcpy(dirent.name, "dev"); + dirent.name[3] = 0; + dirent.ino = 0; + return &dirent; + } + + if (index-1 >= rootNodes_amount) return 0; // Sneaky users trying to muck up our input! + + strcpy(dirent.name, rootNodes[index-1].name); + dirent.name[strlen(rootNodes[index-1].name)] = 0; + dirent.ino = rootNodes[index-1].inode; + return &dirent; +} + + +// (static) initrdFinddir(fsNode_t *node, char *name) - Finds a directory in the VFS node *node with the name *name. +static fsNode_t *initrdFinddir(fsNode_t *node, char *name) { + // Check if the user is attempting to find the dev node. + if (node == initrdRoot && !strcmp(name, "dev")) return initrdDev; + + for (int i = 0; i < rootNodes_amount; i++) { + if (!strcmp(name, rootNodes[i].name)) return &rootNodes[i]; + } + + return 0; +} + + + +// We have just one function that is accessible from the outside. +// initrdInit(uint32_t location) - Initializes the initrd image (located at location) +fsNode_t *initrdInit(uint32_t location) { + // First, iniitalize the main and file header pointers and populate the root directory. + + + + initrdHeader = (initrd_imageHeader_t*)location; + fileHeaders = (initrd_fileHeader_t*) (location + sizeof(initrd_imageHeader_t)); + + // Next, initialize the root directory. + // This is pretty simple. Allocate memory and setup all of the values (most are 0, but some have function pointers) + initrdRoot = (fsNode_t*)kmalloc(sizeof(fsNode_t)); + strcpy(initrdRoot->name, "initrd"); + initrdRoot->mask = initrdRoot->uid = initrdRoot->gid = initrdRoot->inode = initrdRoot->length = 0; + initrdRoot->flags = VFS_DIRECTORY; + initrdRoot->read = 0; + initrdRoot->write = 0; + initrdRoot->open = 0; + initrdRoot->close = 0; + initrdRoot->readdir = &initrdReaddir; + initrdRoot->finddir = &initrdFinddir; + initrdRoot->ptr = 0; + initrdRoot->impl = 0; + + // Now, initialize the dev directory. + initrdDev = (fsNode_t*)kmalloc(sizeof(fsNode_t)); + strcpy(initrdDev->name, "dev"); + initrdDev->mask = initrdDev->uid = initrdDev->gid = initrdDev->inode = initrdDev->length = 0; + initrdDev->flags = VFS_DIRECTORY; + initrdDev->read = 0; + initrdDev->write = 0; + initrdDev->open = 0; + initrdDev->close = 0; + initrdDev->readdir = &initrdReaddir; + initrdDev->finddir = &initrdFinddir; + initrdDev->ptr = 0; + initrdDev->impl = 0; + + // reduceOS has a special initial ramdisk structure + // Each file has a magic number starting at the top. + // The magic number is specific to each directory the file is in (starting at 0xAA for root directory) + // Each subdirectory has its own magic number too, 0xBA. + + + + rootNodes = (fsNode_t*)kmalloc(sizeof(fsNode_t) * initrdHeader->fileAmnt); + rootNodes_amount = initrdHeader->fileAmnt; + + // Iterate through all files and setup each one. + for (int i = 0; i < initrdHeader->fileAmnt; i++) { + // Edit the files header (currently holds the offset relative to ramdisk start) to point to file offset relative to size of memory. + fileHeaders[i].offset += location; + + // Create a new file node. + strcpy(rootNodes[i].name, &fileHeaders[i].name); + rootNodes[i].mask = rootNodes[i].uid = rootNodes[i].gid = 0; + rootNodes[i].length = fileHeaders[i].length; + rootNodes[i].inode = i; + rootNodes[i].flags = VFS_FILE; + rootNodes[i].read = &initrdRead; + rootNodes[i].write = 0; + rootNodes[i].readdir = 0; + rootNodes[i].finddir = 0; + rootNodes[i].open = 0; + rootNodes[i].close = 0; + rootNodes[i].impl = 0; + } + + return initrdRoot; +} diff --git a/source/kernel/fs/vfs.c b/source/kernel/fs/vfs.c index df8fd033..27bab2c6 100644 --- a/source/kernel/fs/vfs.c +++ b/source/kernel/fs/vfs.c @@ -1,633 +1,633 @@ -// ===================================================== -// vfs.c - Virtual File System handler -// ===================================================== -// This file is a part of the reduceOS C kernel. Please credit me if you use this code. -// NOTE: Some functions are from ToaruOS by klange - these functions will be marked with a (TOARU) in their header. -// Thank you! - - -#include "include/vfs.h" // Main header file - -fsNode_t *fs_root = 0; // Root of the filesystem -tree_t *fs_tree = NULL; // Mountpoint tree -hashmap_t *fs_types = NULL; -char cwd[256] = "/"; - - -/* - In reduceOS, we follow a UNIX like structure with one device being the root device and having a filesystem tree. - We structure the root directory like UNIX, where it is / - Other devices are mounted in /device/ - For things like hard drives, they are mounted in hd01, where 0 is the drive number and 1 is the partition. - At least, that's the plan ;) -*/ - -// Functions: - -/* Most of these functions are really simple - just check if there's a callback in the node and call it! */ - -// readFilesystem(fsNode_t *node, off_t off, uint32_t size, uint8_t *buf) - Reads a file in a filesystem. -uint32_t readFilesystem(fsNode_t *node, off_t off, uint32_t size, uint8_t *buf) { - // This is pretty simple, we just use the callbacks in each node. - // Check if the node has a callback. - if (node->read != 0) { - return node->read(node, off, size, buf); - } else { - return 0; // It doesn't. - } -} - -// writeFilesystem(fsNode_t *node, off_t off, uint32_t size, uint8_t *buf) - Writes a file in a filesystem. -uint32_t writeFilesystem(fsNode_t *node, off_t off, uint32_t size, uint8_t *buf) { - if (node->write != 0) { - return node->write(node, off, size, buf); - } else { - return 0; - } -} - -// openFilesystem(fsNode_t *node, uint8_t read, uint8_t write) - Opens a node. -void openFilesystem(fsNode_t *node, uint8_t read, uint8_t write) { - if (node->open != 0) { - return node->open(node); - } -} - -// closeFilesystem(fsNode_t *node) - Closes a node. -void closeFilesystem(fsNode_t *node) { - if (node->close != 0) - return node->close(node); -} - -// Now it gets slightly more complicated. - -// readDirectoryFilesystem(fsNode_t *node, uint32_t index) - Reads a directory in a filesystem. -struct dirent *readDirectoryFilesystem(fsNode_t *node, uint32_t index) { - // Check if the node is a directory and if it has a callback. - if ((node->flags & 0x7) == VFS_DIRECTORY && node->readdir != 0) { - return node->readdir(node, index); - } else { return 0; } -} - - -// findDirectoryFilesystem(fsNode_t *node, char *name) - Finds a directory in a filesystem. -fsNode_t *findDirectoryFilesystem(fsNode_t *node, char *name) { - // Check if the node is a directory and if it has a callback. - if ((node->flags & 0x7) == VFS_DIRECTORY && node->finddir != 0) { - return node->finddir(node, name); - } else { - serialPrintf("The node does not have a finddir function\n"); - return 0; - } -} - - -// getRootFilesystem() - Returns root filesystem -fsNode_t *getRootFilesystem() { - return fs_root; -} - -// vfsInit() - Initializes the VFS -void vfsInit() { - fs_tree = tree_create(); // Create the mountpoint tree - - vfsEntry_t *root = kmalloc(sizeof(vfsEntry_t)); - - // Allocate memory for string pointers - root->fs_type = kmalloc(20); - root->device = kmalloc(20); - - strcpy(root->name, "/"); - root->file = 0; // Nothing is mounted - - // Setup the tree root - tree_set_root(fs_tree, root); - - fs_root = NULL; - - // Create the hashmap - fs_types = hashmap_create(5); -} - - -// vfs_registerFilesystem(const char *name, vfs_mountCallback callback) - Register a filesystem mount callback that will be called when needed (TOARU) -int vfs_registerFilesystem(const char *name, vfs_mountCallback callback) { - if (hashmap_get(fs_types, name)) return 1; - hashmap_set(fs_types, name, (void*)(uintptr_t)callback); - return 0; -} - -// vfs_mountType(const char *type, const char *arg, const char *mountpoint) - Calls the mount handler for a filesystem with the type (TOARU) -int vfs_mountType(const char *type, const char *arg, const char *mountpoint) { - vfs_mountCallback t = (vfs_mountCallback)(uintptr_t)hashmap_get(fs_types, type); - if (!t) { - serialPrintf("vfs_mountType: Unknown filesystem type: %s\n", type); - return -1; - } - - fsNode_t *n = t(arg, mountpoint); - - // Quick hack to let partition mappers not return a node to mount at mountpoint - if ((uintptr_t)n == (uintptr_t)1) return 0; - if (!n) return -1; - - // Mount the filesystem - tree_node_t *node = vfsMount(mountpoint, n); - if (node && node->value) { - vfsEntry_t *entry = (vfsEntry_t*)node->value; - entry->fs_type = kmalloc(strlen(type) + 1); - entry->device = kmalloc(strlen(arg) + 1); - - strcpy(entry->fs_type, type); - strcpy(entry->device, arg); - } - - serialPrintf("vfs_mountType: Mounted %s[%s] to %s: %p\n", type, arg, mountpoint, (void*)n); - debug_print_vfs_tree(); - - return 0; -} - -// (static) vfs_readdirMapper(fsNode_t *node, unsigned long index) - Maps a dirent to the VFS (TOARU) -static struct dirent *vfs_readdirMapper(fsNode_t *node, unsigned long index) { - tree_node_t *d = (tree_node_t*)node->device; - - if (!d) return NULL; - - if (index == 0) { - struct dirent *dir = kmalloc(sizeof(struct dirent)); - strcpy(dir->name, "."); - dir->ino = 0; - return dir; - } else if (index == 1) { - struct dirent *dir = kmalloc(sizeof(struct dirent)); - strcpy(dir->name, ".."); - dir->ino = 1; - return dir; - } - - index -= 2; - unsigned long i = 0; - foreach (child, d->children) { - if (i == index) { - // Recursively print the children - tree_node_t *tchild = (tree_node_t*)child->value; - vfsEntry_t *n = (vfsEntry_t*)tchild->value; - struct dirent *dir = kmalloc(sizeof(struct dirent)); - - size_t len = strlen(n->name) + 1; - memcpy(&dir->name, n->name, (256 < len) ? 256 : len); - dir->ino = 1; - return dir; - } - i++; - } - - return NULL; -} - -// (static) vfs_mapper() - Works with vfs_mapDirectory (TOARU) -static fsNode_t *vfs_mapper() { - fsNode_t *fnode = kmalloc(sizeof(fsNode_t)); - memset(fnode, 0x00, sizeof(fsNode_t)); - fnode->mask = 0555; - fnode->flags = VFS_DIRECTORY; - fnode->readdir = vfs_readdirMapper; - strcpy(fnode->name, "Mapped Directory"); - return fnode; -} - -// vfs_mapDirectory(const char *c) - Maps a directory in the virtual filesystem (TOARU) -void vfs_mapDirectory(const char *c) { - fsNode_t *f = vfs_mapper(); - vfsEntry_t *entry = vfsMount((char*)c, f); - if (!strcmp(c, "/")) { - f->device = fs_tree->root; - } else { - f->device = entry; - } -} - -// Technically (TOARU) -void debug_print_vfs_tree_node(tree_node_t *node, size_t height) { - if (!node) return; - - // Indent output according to height - char *indents = kmalloc(100); - memset(indents, 0, 100); - for (int i = 0; i < height; i++) { - indents[i] = ' '; - } - - // Get the current VFS node - vfsEntry_t *fnode = (vfsEntry_t*)node->value; - - // Print it out - if (fnode->file) { - serialPrintf("%s%s (0x%x) -> 0x%x (%s)\n", indents, fnode->name, node->value, (void*)fnode->file, fnode->file->name); - } else { - serialPrintf("%s%s (0x%x) -> (empty)\n", indents, fnode->name, node->value); - } - - kfree(indents); - - foreach(child, node->children) { - debug_print_vfs_tree_node(child->value, height + 1); - } -} - - -void debug_print_vfs_tree() { - serialPrintf("=== VFS TREE ===\n"); - debug_print_vfs_tree_node(fs_tree->root, 1); - serialPrintf("=== END VFS TREE ===\n"); -} - -// vfsMount(char *path, fsNode_t *localRoot) - Mount a filesystem to the specified path (TOARU) -void *vfsMount(char *path, fsNode_t *localRoot) { - if (!fs_tree) { - serialPrintf("vfsMount: Attempt to mount filesystem when tree is non-existant\n"); - return NULL; - } - if (!path || path[0] != '/') { - serialPrintf("vfsMount: We don't know current working directory - cannot mount to %s\n", path); - return NULL; - } - - tree_node_t *ret_val = NULL; - - - // Slice up the path - char *p = kmalloc(strlen(path)); - memcpy(p, path, strlen(path)); // Memory safety! - - char *i = p; - - while (i < p + strlen(path)) { - if (*i == '/') *i = '\0'; - i++; - } - - p[strlen(path)] = '\0'; - i = p + 1; - - // Setup the root node - tree_node_t *rootNode = fs_tree->root; - - if (*i == '\0') { - // We are setting the root node! Should be easy, I think. - serialPrintf("vfsMount: Mounting to /\n"); - vfsEntry_t *root = (vfsEntry_t*)rootNode->value; - if (root->file != 0) serialPrintf("vfsMount: Path %s is already mounted - please do the correct thing and UNMOUNT.\n", path); - serialPrintf("vfsMount: Setting up values (localRoot = 0x%x)\n", localRoot); - root->file = localRoot; - strcpy(root->device, "N/A"); - strcpy(root->fs_type, "N/A"); - strcpy(root->name, "/"); - - fs_root = localRoot; - ret_val = rootNode; - } else { - tree_node_t *node = rootNode; - char *at = i; - while (true) { - // Search for the path - - if (at >= p + strlen(path)) break; - int found = 0; - serialPrintf("vfsMount: Searching for %s...\n", at); - - foreach(child, node->children) { - tree_node_t *tchild = (tree_node_t *)child->value; - vfsEntry_t *entry = (vfsEntry_t*)tchild->value; - if (!strcmp(entry->name, at)) { - found = 1; - node = tchild; - ret_val = node; - break; - } - } - - if (!found) { - serialPrintf("vfsMount: Could not find %s - creating it.\n", at); - - - vfsEntry_t *entry = kmalloc(sizeof(vfsEntry_t)); - - strcpy(entry->name, at); - entry->file = 0; - entry->device = 0; - entry->fs_type = 0; - node = tree_node_insert_child(fs_tree, node, entry); - - } - at = at + strlen(at) + 1; - } - - vfsEntry_t *entry = (vfsEntry_t*)node->value; - if (entry->file) { - serialPrintf("vfsMount: Path %s is already mounted - please do the correct thing and UNMOUNT.\n", path); - } - - entry->file = localRoot; - ret_val = node; - } - - kfree(p); - return ret_val; -} - -// vfs_canonicalizePath(const char *cwd, const char *input) - Canonicalizes a path (cwd = current working directory, input = path to append/canonicalize on) (TOARU) -char *vfs_canonicalizePath(const char *cwd, const char *input) { - list_t *out = list_create(); // Stack-based canonicalizer, use list as a stack (ToaruOS) - - // Check if we have a relative path (not starting from root). If so, we need to canonicalize the working directory. - if (strlen(input) && input[0] != '/') { - // Make a copy of the current working directory - char *path = kmalloc((strlen(cwd) + 1) * sizeof(char)); - memcpy(path, cwd, strlen(cwd) + 1); - - // Setup the tokenizer - char *pch; - char *save; - pch = strtok_r(path, "/", &save); - - while (pch != NULL) { - // Make copies of the path elements - char *s = kmalloc(sizeof(char) * (strlen(pch) + 1)); - memcpy(s, pch, strlen(pch) + 1); - - // Put them in the list - list_insert(out, s); - - // Repeat! - pch = strtok_r(NULL, "/", &save); // note to self: why did I think I needed strtok_r? isn't this OS supposed to be memory-efficient? - // having serious reflection moments in code comments - this is why reduceOS is the best OS - } - - kfree(path); - } - - // Insert elements from new path - char *path = kmalloc((strlen(input) + 1) * sizeof(char)); - memcpy(path, input, strlen(input) + 1); - - // Initialize tokenizer - char *save; - char *pch; - pch = strtok_r(path, "/", &save); - - - // Tokenize the path and make sure to take dare of .. and . to represent list pop and current. - while (pch != NULL) { - if (!strcmp(pch, "..")) { - // Pop the list to move up. - node_t *node = list_pop(out); - if (node) { - kfree(node->value); - kfree(node); - } - } else if (!strcmp(pch, ".")) { - // Do nothing - } else { - // Normal path. Push onto list. - char *str = kmalloc(sizeof(char) * (strlen(pch) + 1)); - memcpy(str, pch, strlen(pch) + 1); - list_insert(out, str); - } - - pch = strtok_r(NULL, "/", &save); - } - - kfree(path); - - // Calculate the size of the path string - size_t size = 0; - foreach(item, out) { - size += strlen(item->value) + 1; - } - - // Join the list - char *output = kmalloc(sizeof(char) * (size + 1)); - char *offset = output; - - if (size == 0) { - // Assume this is the root directory - output = krealloc(output, sizeof(char) * 2); - output[0] = '/'; - output[1] = '\0'; // Don't forget the null-termination! - } else { - // Append each element together - foreach (item, out) { - offset[0] = '/'; - offset++; - memcpy(offset, item->value, strlen(item->value) + 1); - offset += strlen(item->value); - } - } - - // Cleanup the list and return - list_destroy(out); - list_free(out); - kfree(out); - - return output; -} - -// vfs_getMountpoint(char *path, unsigned int path_depth, char **outpath, unsigned int *outdepth) - Gets the mount point of something at path (TOARU) -fsNode_t *vfs_getMountpoint(char *path, unsigned int path_depth, char **outpath, unsigned int *outdepth) { - size_t depth = 0; - - for (depth = 0; depth <= path_depth; depth++) { - path += strlen(path) + 1; - } - - // Last available node - fsNode_t *last = fs_root; - tree_node_t *node = fs_tree->root; - - char *at = *outpath; - int _depth = 1; - int _tree_depth = 0; - - while (true) { - if (at >= path) break; // We exceeded path, we're done. - - int found = 0; - - foreach(child, node->children) { - tree_node_t *tchild = (tree_node_t*)child->value; - vfsEntry_t *entry = (vfsEntry_t*)tchild->value; - - if (!strcmp(entry->name, at)) { - // We found the entry - found = 1; - node = tchild; - at = at + strlen(at) + 1; - if (entry->file) { - _tree_depth = _depth; - last = entry->file; - *outpath = at; - } - break; - } - } - - if (!found) break; - _depth++; - } - - *outdepth = _tree_depth; - - if (last) { - // Clone the last object and return it. - fsNode_t *last2 = kmalloc(sizeof(fsNode_t)); - memcpy(last2, last, sizeof(fsNode_t)); - return last2; - } - - return last; -} - - -// open_file_recursive(const char *filename, uint64_t flags, uint64_t symlink_depth, char *relative) - Opens a file (but recursive and does all the work) (TOARU) -fsNode_t *open_file_recursive(const char *filename, uint64_t flags, uint64_t symlink_depth, char *relative) { - /* TODO: Add support for flags */ - - if (!filename) return NULL; // Stupid users. - - // Canonicalize the potentially relative path (doesn't start from /) - char *path = vfs_canonicalizePath(relative, filename); - - // Store the length to save those precious CPU cycles - size_t pathLength = strlen(path); - - - // If the length is 1, it can only be for the root filesystem, so clone & return that. - if (pathLength == 1) { - fsNode_t *rootClone = kmalloc(sizeof(fsNode_t)); - memcpy(rootClone, fs_root, sizeof(fsNode_t)); - - // Free the path - kfree(path); - - // Call the filesystem's open method - openFilesystem(rootClone, 1, 1); // Ignore flags because why not. - - return rootClone; - } - - // Man, we gotta do actual work now. This sucks. - - // First, we'll need to find each path separator. - char *pathOffset = path; - uint64_t pathDepth = 0; - - while (pathOffset < path + pathLength) { - if (*pathOffset == '/') { - *pathOffset = '\0'; - pathDepth++; - } - - pathOffset++; - } - - // Null-terminate - path[pathLength] = '\0'; - pathOffset = path + 1; - - - - // The path is currently tokenized and pathOffset points to the first token - // pathDepth is the number of directories in the path - - // So we'll have to dig through the tree to find the file. - unsigned int depth = 0; - fsNode_t *nodePtr = vfs_getMountpoint(path, pathDepth, &pathOffset, &depth); // Get the mountpoint for the file - - if (!nodePtr) return NULL; // Failed to find the file - - do { - // TODO: Symlink support is needed. Coming to you in 2026. - - if (pathOffset >= path + pathLength) { - kfree(path); - openFilesystem(nodePtr, 1, 1); - return nodePtr; - } - - if (depth == pathDepth) { - // We found the file and are done, open the node - openFilesystem(nodePtr, 1, 1); - kfree(path); - return nodePtr; - } - - // Still searching - serialPrintf("open_file_recursive: ... continuing to search for %s (current node: %s)...\n", pathOffset, nodePtr->name); - - fsNode_t *node_next = findDirectoryFilesystem(nodePtr, pathOffset); - kfree(nodePtr); - nodePtr = node_next; - - if (!nodePtr) { - // Could not find the requested directory - kfree(path); - return NULL; - } - - pathOffset += strlen(pathOffset) + 1; - ++depth; - } while (depth < pathDepth + 1); - - serialPrintf("open_file_recursive: Not found\n"); - kfree(path); - return NULL; -} - - - - -// open_file(const char *filename, unsigned int flags) - Opens a file using the VFS current working directory -fsNode_t *open_file(const char *filename, unsigned int flags) { - return open_file_recursive(filename, flags, 0, (char *)cwd); -} - - -// change_cwd(const char *newdir) - Changes the current working directory -void change_cwd(const char *newdir) { - if (fs_root == NULL) return; - - // This is a little weird - but we'll first need to just see if newdir refers to a relative path or a root directory - if (newdir[0] == '/') { - // It refers to the root directory, so this is easy, just overwrite cwd with newdir. - if (strlen(newdir) > 256) { - serialPrintf("change_cwd: Maximum path length (256) reached! Cannot continue.\n"); - return; - } - - strcpy(cwd, newdir); - return; - } - - // We just have to canonicalize the path, and then update CWD. - - char *temp_cwd = vfs_canonicalizePath(cwd, newdir); - if (strlen(temp_cwd) > 256) { - serialPrintf("change_cwd: Maximum path length (256) reached! Cannot continue.\n"); - kfree(temp_cwd); - return; - } - - strcpy(cwd, temp_cwd); - kfree(temp_cwd); - - - // Inform terminal of changes - updateShell(); -} - -// get_cwd() - Returns the current working directory -char *get_cwd() { - return cwd; -} \ No newline at end of file +// ===================================================== +// vfs.c - Virtual File System handler +// ===================================================== +// This file is a part of the reduceOS C kernel. Please credit me if you use this code. +// NOTE: Some functions are from ToaruOS by klange - these functions will be marked with a (TOARU) in their header. +// Thank you! + + +#include // Main header file + +fsNode_t *fs_root = 0; // Root of the filesystem +tree_t *fs_tree = NULL; // Mountpoint tree +hashmap_t *fs_types = NULL; +char cwd[256] = "/"; + + +/* + In reduceOS, we follow a UNIX like structure with one device being the root device and having a filesystem tree. + We structure the root directory like UNIX, where it is / + Other devices are mounted in /device/ + For things like hard drives, they are mounted in hd01, where 0 is the drive number and 1 is the partition. + At least, that's the plan ;) +*/ + +// Functions: + +/* Most of these functions are really simple - just check if there's a callback in the node and call it! */ + +// readFilesystem(fsNode_t *node, off_t off, uint32_t size, uint8_t *buf) - Reads a file in a filesystem. +uint32_t readFilesystem(fsNode_t *node, off_t off, uint32_t size, uint8_t *buf) { + // This is pretty simple, we just use the callbacks in each node. + // Check if the node has a callback. + if (node->read != 0) { + return node->read(node, off, size, buf); + } else { + return 0; // It doesn't. + } +} + +// writeFilesystem(fsNode_t *node, off_t off, uint32_t size, uint8_t *buf) - Writes a file in a filesystem. +uint32_t writeFilesystem(fsNode_t *node, off_t off, uint32_t size, uint8_t *buf) { + if (node->write != 0) { + return node->write(node, off, size, buf); + } else { + return 0; + } +} + +// openFilesystem(fsNode_t *node, uint8_t read, uint8_t write) - Opens a node. +void openFilesystem(fsNode_t *node, uint8_t read, uint8_t write) { + if (node->open != 0) { + return node->open(node); + } +} + +// closeFilesystem(fsNode_t *node) - Closes a node. +void closeFilesystem(fsNode_t *node) { + if (node->close != 0) + return node->close(node); +} + +// Now it gets slightly more complicated. + +// readDirectoryFilesystem(fsNode_t *node, uint32_t index) - Reads a directory in a filesystem. +struct dirent *readDirectoryFilesystem(fsNode_t *node, uint32_t index) { + // Check if the node is a directory and if it has a callback. + if ((node->flags & 0x7) == VFS_DIRECTORY && node->readdir != 0) { + return node->readdir(node, index); + } else { return 0; } +} + + +// findDirectoryFilesystem(fsNode_t *node, char *name) - Finds a directory in a filesystem. +fsNode_t *findDirectoryFilesystem(fsNode_t *node, char *name) { + // Check if the node is a directory and if it has a callback. + if ((node->flags & 0x7) == VFS_DIRECTORY && node->finddir != 0) { + return node->finddir(node, name); + } else { + serialPrintf("The node does not have a finddir function\n"); + return 0; + } +} + + +// getRootFilesystem() - Returns root filesystem +fsNode_t *getRootFilesystem() { + return fs_root; +} + +// vfsInit() - Initializes the VFS +void vfsInit() { + fs_tree = tree_create(); // Create the mountpoint tree + + vfsEntry_t *root = kmalloc(sizeof(vfsEntry_t)); + + // Allocate memory for string pointers + root->fs_type = kmalloc(20); + root->device = kmalloc(20); + + strcpy(root->name, "/"); + root->file = 0; // Nothing is mounted + + // Setup the tree root + tree_set_root(fs_tree, root); + + fs_root = NULL; + + // Create the hashmap + fs_types = hashmap_create(5); +} + + +// vfs_registerFilesystem(const char *name, vfs_mountCallback callback) - Register a filesystem mount callback that will be called when needed (TOARU) +int vfs_registerFilesystem(const char *name, vfs_mountCallback callback) { + if (hashmap_get(fs_types, name)) return 1; + hashmap_set(fs_types, name, (void*)(uintptr_t)callback); + return 0; +} + +// vfs_mountType(const char *type, const char *arg, const char *mountpoint) - Calls the mount handler for a filesystem with the type (TOARU) +int vfs_mountType(const char *type, const char *arg, const char *mountpoint) { + vfs_mountCallback t = (vfs_mountCallback)(uintptr_t)hashmap_get(fs_types, type); + if (!t) { + serialPrintf("vfs_mountType: Unknown filesystem type: %s\n", type); + return -1; + } + + fsNode_t *n = t(arg, mountpoint); + + // Quick hack to let partition mappers not return a node to mount at mountpoint + if ((uintptr_t)n == (uintptr_t)1) return 0; + if (!n) return -1; + + // Mount the filesystem + tree_node_t *node = vfsMount(mountpoint, n); + if (node && node->value) { + vfsEntry_t *entry = (vfsEntry_t*)node->value; + entry->fs_type = kmalloc(strlen(type) + 1); + entry->device = kmalloc(strlen(arg) + 1); + + strcpy(entry->fs_type, type); + strcpy(entry->device, arg); + } + + serialPrintf("vfs_mountType: Mounted %s[%s] to %s: %p\n", type, arg, mountpoint, (void*)n); + debug_print_vfs_tree(); + + return 0; +} + +// (static) vfs_readdirMapper(fsNode_t *node, unsigned long index) - Maps a dirent to the VFS (TOARU) +static struct dirent *vfs_readdirMapper(fsNode_t *node, unsigned long index) { + tree_node_t *d = (tree_node_t*)node->device; + + if (!d) return NULL; + + if (index == 0) { + struct dirent *dir = kmalloc(sizeof(struct dirent)); + strcpy(dir->name, "."); + dir->ino = 0; + return dir; + } else if (index == 1) { + struct dirent *dir = kmalloc(sizeof(struct dirent)); + strcpy(dir->name, ".."); + dir->ino = 1; + return dir; + } + + index -= 2; + unsigned long i = 0; + foreach (child, d->children) { + if (i == index) { + // Recursively print the children + tree_node_t *tchild = (tree_node_t*)child->value; + vfsEntry_t *n = (vfsEntry_t*)tchild->value; + struct dirent *dir = kmalloc(sizeof(struct dirent)); + + size_t len = strlen(n->name) + 1; + memcpy(&dir->name, n->name, (256 < len) ? 256 : len); + dir->ino = 1; + return dir; + } + i++; + } + + return NULL; +} + +// (static) vfs_mapper() - Works with vfs_mapDirectory (TOARU) +static fsNode_t *vfs_mapper() { + fsNode_t *fnode = kmalloc(sizeof(fsNode_t)); + memset(fnode, 0x00, sizeof(fsNode_t)); + fnode->mask = 0555; + fnode->flags = VFS_DIRECTORY; + fnode->readdir = vfs_readdirMapper; + strcpy(fnode->name, "Mapped Directory"); + return fnode; +} + +// vfs_mapDirectory(const char *c) - Maps a directory in the virtual filesystem (TOARU) +void vfs_mapDirectory(const char *c) { + fsNode_t *f = vfs_mapper(); + vfsEntry_t *entry = vfsMount((char*)c, f); + if (!strcmp(c, "/")) { + f->device = fs_tree->root; + } else { + f->device = entry; + } +} + +// Technically (TOARU) +void debug_print_vfs_tree_node(tree_node_t *node, size_t height) { + if (!node) return; + + // Indent output according to height + char *indents = kmalloc(100); + memset(indents, 0, 100); + for (int i = 0; i < height; i++) { + indents[i] = ' '; + } + + // Get the current VFS node + vfsEntry_t *fnode = (vfsEntry_t*)node->value; + + // Print it out + if (fnode->file) { + serialPrintf("%s%s (0x%x) -> 0x%x (%s)\n", indents, fnode->name, node->value, (void*)fnode->file, fnode->file->name); + } else { + serialPrintf("%s%s (0x%x) -> (empty)\n", indents, fnode->name, node->value); + } + + kfree(indents); + + foreach(child, node->children) { + debug_print_vfs_tree_node(child->value, height + 1); + } +} + + +void debug_print_vfs_tree() { + serialPrintf("=== VFS TREE ===\n"); + debug_print_vfs_tree_node(fs_tree->root, 1); + serialPrintf("=== END VFS TREE ===\n"); +} + +// vfsMount(char *path, fsNode_t *localRoot) - Mount a filesystem to the specified path (TOARU) +void *vfsMount(char *path, fsNode_t *localRoot) { + if (!fs_tree) { + serialPrintf("vfsMount: Attempt to mount filesystem when tree is non-existant\n"); + return NULL; + } + if (!path || path[0] != '/') { + serialPrintf("vfsMount: We don't know current working directory - cannot mount to %s\n", path); + return NULL; + } + + tree_node_t *ret_val = NULL; + + + // Slice up the path + char *p = kmalloc(strlen(path)); + memcpy(p, path, strlen(path)); // Memory safety! + + char *i = p; + + while (i < p + strlen(path)) { + if (*i == '/') *i = '\0'; + i++; + } + + p[strlen(path)] = '\0'; + i = p + 1; + + // Setup the root node + tree_node_t *rootNode = fs_tree->root; + + if (*i == '\0') { + // We are setting the root node! Should be easy, I think. + serialPrintf("vfsMount: Mounting to /\n"); + vfsEntry_t *root = (vfsEntry_t*)rootNode->value; + if (root->file != 0) serialPrintf("vfsMount: Path %s is already mounted - please do the correct thing and UNMOUNT.\n", path); + serialPrintf("vfsMount: Setting up values (localRoot = 0x%x)\n", localRoot); + root->file = localRoot; + strcpy(root->device, "N/A"); + strcpy(root->fs_type, "N/A"); + strcpy(root->name, "/"); + + fs_root = localRoot; + ret_val = rootNode; + } else { + tree_node_t *node = rootNode; + char *at = i; + while (true) { + // Search for the path + + if (at >= p + strlen(path)) break; + int found = 0; + serialPrintf("vfsMount: Searching for %s...\n", at); + + foreach(child, node->children) { + tree_node_t *tchild = (tree_node_t *)child->value; + vfsEntry_t *entry = (vfsEntry_t*)tchild->value; + if (!strcmp(entry->name, at)) { + found = 1; + node = tchild; + ret_val = node; + break; + } + } + + if (!found) { + serialPrintf("vfsMount: Could not find %s - creating it.\n", at); + + + vfsEntry_t *entry = kmalloc(sizeof(vfsEntry_t)); + + strcpy(entry->name, at); + entry->file = 0; + entry->device = 0; + entry->fs_type = 0; + node = tree_node_insert_child(fs_tree, node, entry); + + } + at = at + strlen(at) + 1; + } + + vfsEntry_t *entry = (vfsEntry_t*)node->value; + if (entry->file) { + serialPrintf("vfsMount: Path %s is already mounted - please do the correct thing and UNMOUNT.\n", path); + } + + entry->file = localRoot; + ret_val = node; + } + + kfree(p); + return ret_val; +} + +// vfs_canonicalizePath(const char *cwd, const char *input) - Canonicalizes a path (cwd = current working directory, input = path to append/canonicalize on) (TOARU) +char *vfs_canonicalizePath(const char *cwd, const char *input) { + list_t *out = list_create(); // Stack-based canonicalizer, use list as a stack (ToaruOS) + + // Check if we have a relative path (not starting from root). If so, we need to canonicalize the working directory. + if (strlen(input) && input[0] != '/') { + // Make a copy of the current working directory + char *path = kmalloc((strlen(cwd) + 1) * sizeof(char)); + memcpy(path, cwd, strlen(cwd) + 1); + + // Setup the tokenizer + char *pch; + char *save; + pch = strtok_r(path, "/", &save); + + while (pch != NULL) { + // Make copies of the path elements + char *s = kmalloc(sizeof(char) * (strlen(pch) + 1)); + memcpy(s, pch, strlen(pch) + 1); + + // Put them in the list + list_insert(out, s); + + // Repeat! + pch = strtok_r(NULL, "/", &save); // note to self: why did I think I needed strtok_r? isn't this OS supposed to be memory-efficient? + // having serious reflection moments in code comments - this is why reduceOS is the best OS + } + + kfree(path); + } + + // Insert elements from new path + char *path = kmalloc((strlen(input) + 1) * sizeof(char)); + memcpy(path, input, strlen(input) + 1); + + // Initialize tokenizer + char *save; + char *pch; + pch = strtok_r(path, "/", &save); + + + // Tokenize the path and make sure to take dare of .. and . to represent list pop and current. + while (pch != NULL) { + if (!strcmp(pch, "..")) { + // Pop the list to move up. + node_t *node = list_pop(out); + if (node) { + kfree(node->value); + kfree(node); + } + } else if (!strcmp(pch, ".")) { + // Do nothing + } else { + // Normal path. Push onto list. + char *str = kmalloc(sizeof(char) * (strlen(pch) + 1)); + memcpy(str, pch, strlen(pch) + 1); + list_insert(out, str); + } + + pch = strtok_r(NULL, "/", &save); + } + + kfree(path); + + // Calculate the size of the path string + size_t size = 0; + foreach(item, out) { + size += strlen(item->value) + 1; + } + + // Join the list + char *output = kmalloc(sizeof(char) * (size + 1)); + char *offset = output; + + if (size == 0) { + // Assume this is the root directory + output = krealloc(output, sizeof(char) * 2); + output[0] = '/'; + output[1] = '\0'; // Don't forget the null-termination! + } else { + // Append each element together + foreach (item, out) { + offset[0] = '/'; + offset++; + memcpy(offset, item->value, strlen(item->value) + 1); + offset += strlen(item->value); + } + } + + // Cleanup the list and return + list_destroy(out); + list_free(out); + kfree(out); + + return output; +} + +// vfs_getMountpoint(char *path, unsigned int path_depth, char **outpath, unsigned int *outdepth) - Gets the mount point of something at path (TOARU) +fsNode_t *vfs_getMountpoint(char *path, unsigned int path_depth, char **outpath, unsigned int *outdepth) { + size_t depth = 0; + + for (depth = 0; depth <= path_depth; depth++) { + path += strlen(path) + 1; + } + + // Last available node + fsNode_t *last = fs_root; + tree_node_t *node = fs_tree->root; + + char *at = *outpath; + int _depth = 1; + int _tree_depth = 0; + + while (true) { + if (at >= path) break; // We exceeded path, we're done. + + int found = 0; + + foreach(child, node->children) { + tree_node_t *tchild = (tree_node_t*)child->value; + vfsEntry_t *entry = (vfsEntry_t*)tchild->value; + + if (!strcmp(entry->name, at)) { + // We found the entry + found = 1; + node = tchild; + at = at + strlen(at) + 1; + if (entry->file) { + _tree_depth = _depth; + last = entry->file; + *outpath = at; + } + break; + } + } + + if (!found) break; + _depth++; + } + + *outdepth = _tree_depth; + + if (last) { + // Clone the last object and return it. + fsNode_t *last2 = kmalloc(sizeof(fsNode_t)); + memcpy(last2, last, sizeof(fsNode_t)); + return last2; + } + + return last; +} + + +// open_file_recursive(const char *filename, uint64_t flags, uint64_t symlink_depth, char *relative) - Opens a file (but recursive and does all the work) (TOARU) +fsNode_t *open_file_recursive(const char *filename, uint64_t flags, uint64_t symlink_depth, char *relative) { + /* TODO: Add support for flags */ + + if (!filename) return NULL; // Stupid users. + + // Canonicalize the potentially relative path (doesn't start from /) + char *path = vfs_canonicalizePath(relative, filename); + + // Store the length to save those precious CPU cycles + size_t pathLength = strlen(path); + + + // If the length is 1, it can only be for the root filesystem, so clone & return that. + if (pathLength == 1) { + fsNode_t *rootClone = kmalloc(sizeof(fsNode_t)); + memcpy(rootClone, fs_root, sizeof(fsNode_t)); + + // Free the path + kfree(path); + + // Call the filesystem's open method + openFilesystem(rootClone, 1, 1); // Ignore flags because why not. + + return rootClone; + } + + // Man, we gotta do actual work now. This sucks. + + // First, we'll need to find each path separator. + char *pathOffset = path; + uint64_t pathDepth = 0; + + while (pathOffset < path + pathLength) { + if (*pathOffset == '/') { + *pathOffset = '\0'; + pathDepth++; + } + + pathOffset++; + } + + // Null-terminate + path[pathLength] = '\0'; + pathOffset = path + 1; + + + + // The path is currently tokenized and pathOffset points to the first token + // pathDepth is the number of directories in the path + + // So we'll have to dig through the tree to find the file. + unsigned int depth = 0; + fsNode_t *nodePtr = vfs_getMountpoint(path, pathDepth, &pathOffset, &depth); // Get the mountpoint for the file + + if (!nodePtr) return NULL; // Failed to find the file + + do { + // TODO: Symlink support is needed. Coming to you in 2026. + + if (pathOffset >= path + pathLength) { + kfree(path); + openFilesystem(nodePtr, 1, 1); + return nodePtr; + } + + if (depth == pathDepth) { + // We found the file and are done, open the node + openFilesystem(nodePtr, 1, 1); + kfree(path); + return nodePtr; + } + + // Still searching + serialPrintf("open_file_recursive: ... continuing to search for %s (current node: %s)...\n", pathOffset, nodePtr->name); + + fsNode_t *node_next = findDirectoryFilesystem(nodePtr, pathOffset); + kfree(nodePtr); + nodePtr = node_next; + + if (!nodePtr) { + // Could not find the requested directory + kfree(path); + return NULL; + } + + pathOffset += strlen(pathOffset) + 1; + ++depth; + } while (depth < pathDepth + 1); + + serialPrintf("open_file_recursive: Not found\n"); + kfree(path); + return NULL; +} + + + + +// open_file(const char *filename, unsigned int flags) - Opens a file using the VFS current working directory +fsNode_t *open_file(const char *filename, unsigned int flags) { + return open_file_recursive(filename, flags, 0, (char *)cwd); +} + + +// change_cwd(const char *newdir) - Changes the current working directory +void change_cwd(const char *newdir) { + if (fs_root == NULL) return; + + // This is a little weird - but we'll first need to just see if newdir refers to a relative path or a root directory + if (newdir[0] == '/') { + // It refers to the root directory, so this is easy, just overwrite cwd with newdir. + if (strlen(newdir) > 256) { + serialPrintf("change_cwd: Maximum path length (256) reached! Cannot continue.\n"); + return; + } + + strcpy(cwd, newdir); + return; + } + + // We just have to canonicalize the path, and then update CWD. + + char *temp_cwd = vfs_canonicalizePath(cwd, newdir); + if (strlen(temp_cwd) > 256) { + serialPrintf("change_cwd: Maximum path length (256) reached! Cannot continue.\n"); + kfree(temp_cwd); + return; + } + + strcpy(cwd, temp_cwd); + kfree(temp_cwd); + + + // Inform terminal of changes + updateShell(); +} + +// get_cwd() - Returns the current working directory +char *get_cwd() { + return cwd; +} diff --git a/source/kernel/gfx/bitmap.c b/source/kernel/gfx/bitmap.c index f5d0c8b8..a712f1e9 100644 --- a/source/kernel/gfx/bitmap.c +++ b/source/kernel/gfx/bitmap.c @@ -1,130 +1,130 @@ -// ================================================== -// bitmap.c - reduceOS bitmap library -// ================================================== -// Written originally by szhou42, adapted into reduceOS. Credit to him. - -#include "include/bitmap.h" // Main header file -#include "include/ext2.h" - - - -char *addr = NULL; - -// bitmap_loadBitmap(fsNode_t *node) - Loads the bitmap into memory and returns the bitmap_t object. -bitmap_t *bitmap_loadBitmap(fsNode_t *node) { - if (!node) return NULL; - - // Allocate memory for where the bitmap data will go - - uint8_t *image_data = kmalloc(node->length + 1024 * 3); // extra 3 KB to be safe - memset(image_data, 0, sizeof(image_data)); - - // Read in the image data - int ret = node->read(node, 0, node->length, image_data); - if (ret != node->length) { - serialPrintf("bitmap_loadBitmap: Failed to read in bitmap data, returned %i\n", ret); - return NULL; - } - - // Basically do what createBitmap does but with a different start address - bitmap_fileHeader_t *h = image_data; - - if (h->type != 0x4D42) { - serialPrintf("bitmap_loadBitmap: Cannot load bitmap - signature is not 0x4D42 (BM). Signature given: 0x%x\n", h->type); - kfree(image_data); - return NULL; - } - - uint32_t offset = h->offbits; - - // Setup the infoheader - bitmap_infoHeader_t *info = image_data + sizeof(bitmap_fileHeader_t); - - // Setup the bitmap_t we are returning - bitmap_t *bmp = kmalloc(sizeof(bitmap_t)); - - bmp->width = info->width; - bmp->height = info->height; - bmp->imageBytes = (void*)((unsigned int)image_data + offset); - bmp->buffer = image_data; - bmp->totalSize = h->size; - bmp->bpp = info->bitcount; - - - - addr = image_data; - return bmp; -} - -bitmap_t *createBitmap() { - // The image we attempt to display is burned into the code by the linker (thankfully, initrd's interface sucks and that's totally not my fault) - bitmap_t *ret = kmalloc(sizeof(bitmap_t)); - char *start_addr; - if (addr != NULL) start_addr = addr; - else return NULL; - - bitmap_fileHeader_t *h = start_addr; - - // Validate signature - if (h->type != 0x4D42) { - serialPrintf("createBitmap: Signature is not 0x4D42 (BM)! Signature is: 0x%x\n", h->type); - kfree(ret); - return NULL; - } else { - serialPrintf("createBitmap: Signature OK on bitmap\n"); - } - - - uint32_t offset = h->offbits; - serialPrintf("createBitmap: Bitmap offset = %u\n", offset); - serialPrintf("createBitmap: Bitmap size = %u\n", h->size); - - // Setup infoheader - bitmap_infoHeader_t *info = start_addr + sizeof(bitmap_fileHeader_t); - - ret->width = info->width; - ret->height = info->height; - ret->imageBytes = (void*)((unsigned int)start_addr + offset); - ret->buffer = start_addr; - ret->totalSize = h->size; - ret->bpp = info->bitcount; - - serialPrintf("createBitmap: Bitmap dimensions are %u x %u\n", ret->width, ret->height); - serialPrintf("createBitmap: Image is located at 0x%x\n", ret->imageBytes); - serialPrintf("createBitmap: Successfully loaded bitmap.\n"); - return ret; -} - - -// displayBitmap(bitmap_t *bmp, int x, int y) - Displays a bitmap image on 2nd framebuffer -void displayBitmap(bitmap_t *bmp, int x, int y) { - // NOTE: x and y refer to the top left starting point of the bitmap, since I could honestly care less about my future self. - // NOTE FROM THE FUTURE: I hate you. - - if (!bmp) return; // Stupid users. - - uint8_t *image = bmp->imageBytes; - int j = 0; - - uint32_t height = 0; - if (bmp->height > 764) height = 764; // BUG BUG BUG BUG BUG - else height = bmp->height; - - - for(int i = 0; i < bmp->height-4-y; i++) { - // Copy the image to the framebuffer. - char * imageRow = image + i * bmp->width * 3; // Needed to get BGR values. - uint32_t * framebufferRow = (void*)framebuffer + (bmp->height - 1 - i) * bmp->width * 4; - j = 0; - - for(int k = 0; k < bmp->width; k++) { - uint32_t b = imageRow[j++] & 0xff; // BGR values are encoded in the bitmap - uint32_t g = imageRow[j++] & 0xff; - uint32_t r = imageRow[j++] & 0xff; - uint32_t rgb = ((r << 16) | (g << 8) | (b)) & 0x00ffffff; - rgb = rgb | 0xff000000; - framebufferRow[k] = rgb; - } - } - -} \ No newline at end of file +// ================================================== +// bitmap.c - reduceOS bitmap library +// ================================================== +// Written originally by szhou42, adapted into reduceOS. Credit to him. + +#include // Main header file +#include + + + +char *addr = NULL; + +// bitmap_loadBitmap(fsNode_t *node) - Loads the bitmap into memory and returns the bitmap_t object. +bitmap_t *bitmap_loadBitmap(fsNode_t *node) { + if (!node) return NULL; + + // Allocate memory for where the bitmap data will go + + uint8_t *image_data = kmalloc(node->length + 1024 * 3); // extra 3 KB to be safe + memset(image_data, 0, sizeof(image_data)); + + // Read in the image data + int ret = node->read(node, 0, node->length, image_data); + if (ret != node->length) { + serialPrintf("bitmap_loadBitmap: Failed to read in bitmap data, returned %i\n", ret); + return NULL; + } + + // Basically do what createBitmap does but with a different start address + bitmap_fileHeader_t *h = image_data; + + if (h->type != 0x4D42) { + serialPrintf("bitmap_loadBitmap: Cannot load bitmap - signature is not 0x4D42 (BM). Signature given: 0x%x\n", h->type); + kfree(image_data); + return NULL; + } + + uint32_t offset = h->offbits; + + // Setup the infoheader + bitmap_infoHeader_t *info = image_data + sizeof(bitmap_fileHeader_t); + + // Setup the bitmap_t we are returning + bitmap_t *bmp = kmalloc(sizeof(bitmap_t)); + + bmp->width = info->width; + bmp->height = info->height; + bmp->imageBytes = (void*)((unsigned int)image_data + offset); + bmp->buffer = image_data; + bmp->totalSize = h->size; + bmp->bpp = info->bitcount; + + + + addr = image_data; + return bmp; +} + +bitmap_t *createBitmap() { + // The image we attempt to display is burned into the code by the linker (thankfully, initrd's interface sucks and that's totally not my fault) + bitmap_t *ret = kmalloc(sizeof(bitmap_t)); + char *start_addr; + if (addr != NULL) start_addr = addr; + else return NULL; + + bitmap_fileHeader_t *h = start_addr; + + // Validate signature + if (h->type != 0x4D42) { + serialPrintf("createBitmap: Signature is not 0x4D42 (BM)! Signature is: 0x%x\n", h->type); + kfree(ret); + return NULL; + } else { + serialPrintf("createBitmap: Signature OK on bitmap\n"); + } + + + uint32_t offset = h->offbits; + serialPrintf("createBitmap: Bitmap offset = %u\n", offset); + serialPrintf("createBitmap: Bitmap size = %u\n", h->size); + + // Setup infoheader + bitmap_infoHeader_t *info = start_addr + sizeof(bitmap_fileHeader_t); + + ret->width = info->width; + ret->height = info->height; + ret->imageBytes = (void*)((unsigned int)start_addr + offset); + ret->buffer = start_addr; + ret->totalSize = h->size; + ret->bpp = info->bitcount; + + serialPrintf("createBitmap: Bitmap dimensions are %u x %u\n", ret->width, ret->height); + serialPrintf("createBitmap: Image is located at 0x%x\n", ret->imageBytes); + serialPrintf("createBitmap: Successfully loaded bitmap.\n"); + return ret; +} + + +// displayBitmap(bitmap_t *bmp, int x, int y) - Displays a bitmap image on 2nd framebuffer +void displayBitmap(bitmap_t *bmp, int x, int y) { + // NOTE: x and y refer to the top left starting point of the bitmap, since I could honestly care less about my future self. + // NOTE FROM THE FUTURE: I hate you. + + if (!bmp) return; // Stupid users. + + uint8_t *image = bmp->imageBytes; + int j = 0; + + uint32_t height = 0; + if (bmp->height > 764) height = 764; // BUG BUG BUG BUG BUG + else height = bmp->height; + + + for(int i = 0; i < bmp->height-4-y; i++) { + // Copy the image to the framebuffer. + char * imageRow = image + i * bmp->width * 3; // Needed to get BGR values. + uint32_t * framebufferRow = (void*)framebuffer + (bmp->height - 1 - i) * bmp->width * 4; + j = 0; + + for(int k = 0; k < bmp->width; k++) { + uint32_t b = imageRow[j++] & 0xff; // BGR values are encoded in the bitmap + uint32_t g = imageRow[j++] & 0xff; + uint32_t r = imageRow[j++] & 0xff; + uint32_t rgb = ((r << 16) | (g << 8) | (b)) & 0x00ffffff; + rgb = rgb | 0xff000000; + framebufferRow[k] = rgb; + } + } + +} diff --git a/source/kernel/gfx/font.c b/source/kernel/gfx/font.c index 216fbe92..5b898fd9 100644 --- a/source/kernel/gfx/font.c +++ b/source/kernel/gfx/font.c @@ -1,157 +1,157 @@ -// ========================================================== -// font.c - reduceOS font parser (supports bitmap and PSF) -// ========================================================== -// This file is a part of the reduceOS C kernel. Please credit me if you use this code. - -#include "include/font.h" // Main header file - -// PSF (as mentioned in the header file) stands for 'PC screen font', which is the font used by Linux for its console. -// The font is encoded with its own header and in unicode -// You can find more information on it here: https://wiki.osdev.org/PC_Screen_Font -// Unicode table decoding here is also sourced from the above link. - -PSF2_Header *font; // TODO: PSF1 support - -// External variables -extern char _binary_font_psf_start; -extern char _binary_font_psf_end; -extern uint32_t *vbeBuffer; -extern uint32_t font_data[127][20]; - -uint32_t currentFont[127][20]; - - -// Bitmap Font Functions - -// bitmapFontInit() - Initializes bitmap font reading with the default font found in font_data.c -void bitmapFontInit() { - memcpy(currentFont, font_data, sizeof(font_data)); -} - -// bitmapLoadFont(uint32_t *font_data) - Loads a a new font for the bitmap. -void bitmapLoadFont(uint32_t *font_data) { - memcpy(currentFont, font_data, sizeof(currentFont)); -} - - - - -// bitmapFontDrawChar(char ch, int x, int y, int color) - Puts a character of color 'color' at x, y -void bitmapFontDrawChar(char ch, int x, int y, int color) { - int pixelData, tempValue = 0; - - for (int i = 0; i < 20; i++) { - tempValue = x; - x += 20; - pixelData = currentFont[(int)ch][i]; - - while (pixelData > 0) { - if (pixelData & 1) vbePutPixel(x, y, color); - pixelData >>= 1; - x--; - } - - x = tempValue; - y++; - } -} - -// bitmapFontDrawString(char *str, int x, int y, int color) - Draw a string from the bitmap -void bitmapFontDrawString(char *str, int x, int y, int color) { - int tmpX = x, tmpY = y; - while (*str != '\0') { - bitmapFontDrawChar(*str, tmpX, tmpY, color); - *str++; - tmpX += 14; - - if (tmpX > modeWidth) { - tmpY += 17; - tmpX = x; - } - } -} - - - -// PSF Functions - -//uint8_t *psf_data; - -// reduceOS loads in with a default font for PSF, encoded into the actual kernel binary file. -// Other PSF fonts can be loaded from the initial ramdisk or storage mediums. - - -void psfGetPSFInfo() { - serialPrintf("psfGetPSFInfo: PSF font is loaded from 0x%x to 0x%x\n", &_binary_font_psf_start, &_binary_font_psf_end); - char *start_addr = &_binary_font_psf_start; - PSF1_Header *h1 = start_addr; - if (h1->magic == 0x0436) { - serialPrintf("psfGetPSFInfo: Font is PSF version 1\n"); - serialPrintf("psfGetPSFInfo: Font mode: %i\npsfGetPSFInfo: Character Size: %i\n", h1->fontMode, h1->characterSize); - } - - - PSF2_Header *h2 = start_addr; - if (h2->magic == 0x864ab572) { - serialPrintf("psfGetPSFInfo: Font is PSF version 2\n"); - serialPrintf("psfGetPSFInfo: Version is %i\n", h2->version); - serialPrintf("psfGetPSFInfo: Header size: %i\n",h2->header_size); - serialPrintf("psfGetPSFInfo: Unicode table contained: %s\n", (h2->flags == 0) ? "No" : "Yes"); - serialPrintf("psfGetPSFInfo: Glyphs = %i (size = %i bytes)\n", h2->glyphs, h2->bytesPerGlyph); - serialPrintf("psfGetPSFInfo: height = %i width = %i\n", h2->height, h2->width); - } - -} - - -// psfInit() - Initializes the default PSF font for reduceOS. -void psfInit() { - char *start_addr = &_binary_font_psf_start; - - - PSF1_Header *h1 = start_addr; - if (h1->magic == 0x0436) { - serialPrintf("psfInit: PSF version 1 is NOT supported!\n"); - return; - } - - - PSF2_Header *h2 = start_addr; - if (h2->magic == 0x864ab572) { - font = h2; - } - - printf("PSF initialized\n"); -} - - -int psfGetFontWidth() { return font->width; } -int psfGetFontHeight() { return font->height; } - -// psfDrawChar(unsigned short int c, int cx, int cy, uint32_t fg, uint32_t bg) - Draw a PC screen font character. -void psfDrawChar(unsigned short int c, int cx, int cy, uint32_t fg, uint32_t bg) { - // Check how many bytes encode one row. - int bytesPerLine = (font->width + 7) / 8; - - // Get a glyph for the character. - unsigned char *glyph = (unsigned char*)&_binary_font_psf_start + font->header_size + (c > 0 && c < font->glyphs ? c : 0) * font->bytesPerGlyph; - - // Display the pixels according to the bitmap. - int x, y, mask; - for (y = 0; y < font->height; y++) { - mask = 1 << (font->width - 1); - // Display a row. - for (x = 0; x < font->width; x++) { - if ((*((unsigned int*)glyph) & mask ? fg : bg) == bg) { - vbePutPixel(cx + x, cy + y, bg); - } else { - vbePutPixel(cx + x, cy + y, fg); - } - mask >>= 1; - } - - // Adjust to next line - glyph += bytesPerLine; - } -} - +// ========================================================== +// font.c - reduceOS font parser (supports bitmap and PSF) +// ========================================================== +// This file is a part of the reduceOS C kernel. Please credit me if you use this code. + +#include // Main header file + +// PSF (as mentioned in the header file) stands for 'PC screen font', which is the font used by Linux for its console. +// The font is encoded with its own header and in unicode +// You can find more information on it here: https://wiki.osdev.org/PC_Screen_Font +// Unicode table decoding here is also sourced from the above link. + +PSF2_Header *font; // TODO: PSF1 support + +// External variables +extern char _binary_font_psf_start; +extern char _binary_font_psf_end; +extern uint32_t *vbeBuffer; +extern uint32_t font_data[127][20]; + +uint32_t currentFont[127][20]; + + +// Bitmap Font Functions + +// bitmapFontInit() - Initializes bitmap font reading with the default font found in font_data.c +void bitmapFontInit() { + memcpy(currentFont, font_data, sizeof(font_data)); +} + +// bitmapLoadFont(uint32_t *font_data) - Loads a a new font for the bitmap. +void bitmapLoadFont(uint32_t *font_data) { + memcpy(currentFont, font_data, sizeof(currentFont)); +} + + + + +// bitmapFontDrawChar(char ch, int x, int y, int color) - Puts a character of color 'color' at x, y +void bitmapFontDrawChar(char ch, int x, int y, int color) { + int pixelData, tempValue = 0; + + for (int i = 0; i < 20; i++) { + tempValue = x; + x += 20; + pixelData = currentFont[(int)ch][i]; + + while (pixelData > 0) { + if (pixelData & 1) vbePutPixel(x, y, color); + pixelData >>= 1; + x--; + } + + x = tempValue; + y++; + } +} + +// bitmapFontDrawString(char *str, int x, int y, int color) - Draw a string from the bitmap +void bitmapFontDrawString(char *str, int x, int y, int color) { + int tmpX = x, tmpY = y; + while (*str != '\0') { + bitmapFontDrawChar(*str, tmpX, tmpY, color); + *str++; + tmpX += 14; + + if (tmpX > modeWidth) { + tmpY += 17; + tmpX = x; + } + } +} + + + +// PSF Functions + +//uint8_t *psf_data; + +// reduceOS loads in with a default font for PSF, encoded into the actual kernel binary file. +// Other PSF fonts can be loaded from the initial ramdisk or storage mediums. + + +void psfGetPSFInfo() { + serialPrintf("psfGetPSFInfo: PSF font is loaded from 0x%x to 0x%x\n", &_binary_font_psf_start, &_binary_font_psf_end); + char *start_addr = &_binary_font_psf_start; + PSF1_Header *h1 = start_addr; + if (h1->magic == 0x0436) { + serialPrintf("psfGetPSFInfo: Font is PSF version 1\n"); + serialPrintf("psfGetPSFInfo: Font mode: %i\npsfGetPSFInfo: Character Size: %i\n", h1->fontMode, h1->characterSize); + } + + + PSF2_Header *h2 = start_addr; + if (h2->magic == 0x864ab572) { + serialPrintf("psfGetPSFInfo: Font is PSF version 2\n"); + serialPrintf("psfGetPSFInfo: Version is %i\n", h2->version); + serialPrintf("psfGetPSFInfo: Header size: %i\n",h2->header_size); + serialPrintf("psfGetPSFInfo: Unicode table contained: %s\n", (h2->flags == 0) ? "No" : "Yes"); + serialPrintf("psfGetPSFInfo: Glyphs = %i (size = %i bytes)\n", h2->glyphs, h2->bytesPerGlyph); + serialPrintf("psfGetPSFInfo: height = %i width = %i\n", h2->height, h2->width); + } + +} + + +// psfInit() - Initializes the default PSF font for reduceOS. +void psfInit() { + char *start_addr = &_binary_font_psf_start; + + + PSF1_Header *h1 = start_addr; + if (h1->magic == 0x0436) { + serialPrintf("psfInit: PSF version 1 is NOT supported!\n"); + return; + } + + + PSF2_Header *h2 = start_addr; + if (h2->magic == 0x864ab572) { + font = h2; + } + + printf("PSF initialized\n"); +} + + +int psfGetFontWidth() { return font->width; } +int psfGetFontHeight() { return font->height; } + +// psfDrawChar(unsigned short int c, int cx, int cy, uint32_t fg, uint32_t bg) - Draw a PC screen font character. +void psfDrawChar(unsigned short int c, int cx, int cy, uint32_t fg, uint32_t bg) { + // Check how many bytes encode one row. + int bytesPerLine = (font->width + 7) / 8; + + // Get a glyph for the character. + unsigned char *glyph = (unsigned char*)&_binary_font_psf_start + font->header_size + (c > 0 && c < font->glyphs ? c : 0) * font->bytesPerGlyph; + + // Display the pixels according to the bitmap. + int x, y, mask; + for (y = 0; y < font->height; y++) { + mask = 1 << (font->width - 1); + // Display a row. + for (x = 0; x < font->width; x++) { + if ((*((unsigned int*)glyph) & mask ? fg : bg) == bg) { + vbePutPixel(cx + x, cy + y, bg); + } else { + vbePutPixel(cx + x, cy + y, fg); + } + mask >>= 1; + } + + // Adjust to next line + glyph += bytesPerLine; + } +} + diff --git a/source/kernel/gfx/font_data.c b/source/kernel/gfx/font_data.c index d12ba5fa..4f609f83 100644 --- a/source/kernel/gfx/font_data.c +++ b/source/kernel/gfx/font_data.c @@ -1,1835 +1,1835 @@ -// font_data.c - A small utility file containing some bitmap font data. - -#include "include/font_data.h" - -// Sourced from: https://github.com/pritamzope/OS - -uint32_t font_data[127][20] = { - // first 32 entries are empty - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - // 33 ! - { - 0b0000000000000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000000000000 - }, - // 34 " - { - 0b0000000000000000, - 0b0000000000000000, - 0b0000011001100000, - 0b0000011001100000, - 0b0000011001100000, - 0b0000011001100000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000 - }, - // 35 # - { - 0b0000000000000000, - 0b0000011000110000, - 0b0000011000110000, - 0b0000011000110000, - 0b0000011000110000, - 0b0001111111111000, - 0b0000110001100000, - 0b0000110001100000, - 0b0000110001100000, - 0b0000110001100000, - 0b0011111111111000, - 0b0001100011000000, - 0b0001100011000000, - 0b0001100011000000, - 0b0001100011000000, - 0b0000000000000000 - }, - // 36 $ - { - 0b0000000000000000, - 0b0000000110000000, - 0b0000011111100000, - 0b0000111111110000, - 0b0000110110110000, - 0b0000110110000000, - 0b0000111110000000, - 0b0000011111000000, - 0b0000000111100000, - 0b0000000110110000, - 0b0000000110110000, - 0b0000100110110000, - 0b0000111111110000, - 0b0000011111100000, - 0b0000000110000000, - 0b0000000000000000 - }, - // 37 % - { - 0b0000000000000000, - 0b0000000000000000, - 0b0001100000010000, - 0b0010010000110000, - 0b0110011001100000, - 0b0110011001000000, - 0b0110011011000000, - 0b0110010010011000, - 0b0010010110100100, - 0b0001100101100110, - 0b0000001101100110, - 0b0000011001100110, - 0b0000010000100100, - 0b0000110000011000, - 0b0001100000000000, - 0b0000000000000000 - }, - // 38 & - { - 0b0000000000000000, - 0b0000000000000000, - 0b0000001111000000, - 0b0000011001100000, - 0b0000010001100000, - 0b0000010001100000, - 0b0000011011000000, - 0b0000011110000000, - 0b0000111100010000, - 0b0001100100010000, - 0b0011000110010000, - 0b0011000011110000, - 0b0011100001100000, - 0b0001110111110000, - 0b0000111110011100, - 0b0000000000000000 - }, - // 39 ' - { - 0b0000000000000000, - 0b0000000000000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000 - }, - // 40 ( - { - 0b0000000000000000, - 0b0000000110000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000011000000000, - 0b0000011000000000, - 0b0000011000000000, - 0b0000011000000000, - 0b0000011000000000, - 0b0000011000000000, - 0b0000011000000000, - 0b0000011000000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000000110000000, - 0b0000000000000000 - }, - // 41 ) - { - 0b0000000000000000, - 0b0000001100000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000011000000, - 0b0000000011000000, - 0b0000000011000000, - 0b0000000011000000, - 0b0000000011000000, - 0b0000000011000000, - 0b0000000011000000, - 0b0000000011000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000001100000000, - 0b0000000000000000 - }, - // 42 * - { - 0b0000000000000000, - 0b0000000000000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000110110110000, - 0b0000011111100000, - 0b0000000110000000, - 0b0000001111000000, - 0b0000011001100000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000 - }, - // 43 + - { - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000111111110000, - 0b0000111111110000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000 - }, - // 44 , - { - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000111000000, - 0b0000000111000000, - 0b0000000011000000, - 0b0000000011000000, - 0b0000001011000000, - 0b0000000110000000, - 0b0000000000000000 - }, - // 45 - - { - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000111111110000, - 0b0000111111110000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000 - }, - // 46 . - { - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000111000000, - 0b0000000111000000, - 0b0000000111000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000 - }, - // 47 / - { - 0b0000000000000000, - 0b0000000001100000, - 0b0000000001100000, - 0b0000000011000000, - 0b0000000011000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000011000000000, - 0b0000011000000000, - 0b0000110000000000, - 0b0000110000000000, - 0b0001100000000000, - 0b0001100000000000, - 0b0000000000000000 - }, - // 48 0 - { - 0b0000000000000000, - 0b0000011111000000, - 0b0000111111100000, - 0b0000110001100000, - 0b0001100000110000, - 0b0001100000110000, - 0b0001101110110000, - 0b0001101110110000, - 0b0001100000110000, - 0b0001100000110000, - 0b0001100000110000, - 0b0001100000110000, - 0b0000110001100000, - 0b0000111111100000, - 0b0000011111000000, - 0b0000000000000000 - }, - // 49 1 - { - 0b0000000000000000, - 0b0000001110000000, - 0b0000011110000000, - 0b0000110110000000, - 0b0000100110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000111111110000, - 0b0000111111110000, - 0b0000000000000000 - }, - // 50 2 - { - 0b0000000000000000, - 0b0000011111000000, - 0b0000111111100000, - 0b0001100000110000, - 0b0001100000110000, - 0b0000000000110000, - 0b0000000000110000, - 0b0000000001100000, - 0b0000000011000000, - 0b0000000110000000, - 0b0000001100000000, - 0b0000011000000000, - 0b0000110000000000, - 0b0001111111110000, - 0b0001111111110000, - 0b0000000000000000 - }, - // 51 3 - { - 0b0000000000000000, - 0b0000011111000000, - 0b0000111111100000, - 0b0001100000110000, - 0b0001100000110000, - 0b0000000000110000, - 0b0000000001100000, - 0b0000001111000000, - 0b0000001111100000, - 0b0000000000110000, - 0b0000000000110000, - 0b0001100000110000, - 0b0001100000110000, - 0b0000111111100000, - 0b0000011111000000, - 0b0000000000000000 - }, - // 52 4 - { - 0b0000000000000000, - 0b0000000011100000, - 0b0000000111100000, - 0b0000000111100000, - 0b0000001101100000, - 0b0000001101100000, - 0b0000011001100000, - 0b0000111001100000, - 0b0000110001100000, - 0b0001100001100000, - 0b0001100001100000, - 0b0011111111111000, - 0b0011111111111000, - 0b0000000001100000, - 0b0000000001100000, - 0b0000000000000000 - }, - // 53 5 - { - 0b0000000000000000, - 0b0001111111110000, - 0b0001111111110000, - 0b0001100000000000, - 0b0001100000000000, - 0b0001100000000000, - 0b0001111111000000, - 0b0001111111100000, - 0b0000000000110000, - 0b0000000000110000, - 0b0000000000110000, - 0b0001100000110000, - 0b0001100000110000, - 0b0000111111100000, - 0b0000011111000000, - 0b0000000000000000 - }, - // 54 6 - { - 0b0000000000000000, - 0b0000001111000000, - 0b0000011111100000, - 0b0000110000110000, - 0b0001100000000000, - 0b0001100000000000, - 0b0001101111000000, - 0b0001111111100000, - 0b0001110000110000, - 0b0001100000110000, - 0b0001100000110000, - 0b0001100000110000, - 0b0000110000110000, - 0b0000111111100000, - 0b0000001111000000, - 0b0000000000000000 - }, - // 55 7 - { - 0b0000000000000000, - 0b0001111111110000, - 0b0001111111110000, - 0b0000000000110000, - 0b0000000001100000, - 0b0000000011000000, - 0b0000000011000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000000000000000 - }, - // 56 8 - { - 0b0000000000000000, - 0b0000011111000000, - 0b0000111111100000, - 0b0001100000110000, - 0b0001100000110000, - 0b0001100000110000, - 0b0000110001100000, - 0b0000011111000000, - 0b0000111111100000, - 0b0001100000110000, - 0b0001100000110000, - 0b0001100000110000, - 0b0001100000110000, - 0b0000111111100000, - 0b0000011111000000, - 0b0000000000000000 - }, - // 57 9 - { - 0b0000000000000000, - 0b0000011111000000, - 0b0000111111100000, - 0b0001100001100000, - 0b0001100000110000, - 0b0001100000110000, - 0b0001100000110000, - 0b0001100001110000, - 0b0000111111110000, - 0b0000011110110000, - 0b0000000000110000, - 0b0000000000110000, - 0b0001100001100000, - 0b0000111111100000, - 0b0000011110000000, - 0b0000000000000000 - }, - // 58 : - { - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000111000000, - 0b0000000111000000, - 0b0000000111000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000111000000, - 0b0000000111000000, - 0b0000000111000000, - 0b0000000000000000 - }, - // 59 ; - { - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000111000000, - 0b0000000111000000, - 0b0000000111000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000111000000, - 0b0000000111000000, - 0b0000000011000000, - 0b0000000011000000, - 0b0000001011000000, - 0b0000000110000000, - 0b0000000000000000 - }, - // 60 < - { - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000010000, - 0b0000000001110000, - 0b0000000111000000, - 0b0000111100000000, - 0b0000110000000000, - 0b0000111100000000, - 0b0000000111000000, - 0b0000000001110000, - 0b0000000000010000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000 - }, - // 61 = - { - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0001111111111000, - 0b0001111111111000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0001111111111000, - 0b0001111111111000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000 - }, - // 62 > - { - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000100000000000, - 0b0000111000000000, - 0b0000001110000000, - 0b0000000011110000, - 0b0000000000110000, - 0b0000000011110000, - 0b0000001110000000, - 0b0000111000000000, - 0b0000100000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000 - }, - // 63 ? - { - 0b0000000000000000, - 0b0000011111000000, - 0b0000111111100000, - 0b0001100000110000, - 0b0001100000110000, - 0b0001100000110000, - 0b0000000000110000, - 0b0000000001100000, - 0b0000000011000000, - 0b0000000110000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000000000000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000000000000000 - }, - // 64 @ - { - 0b0000000000000000, - 0b0000000000000000, - 0b0000111111100000, - 0b0001111111111000, - 0b0011100000001100, - 0b0111001110101100, - 0b0110011011101100, - 0b0110110001101100, - 0b0110100001101100, - 0b0110100011001100, - 0b0110110111011000, - 0b0110011101110000, - 0b0011000000000000, - 0b0011110011110000, - 0b0000111111000000, - 0b0000000000000000 - }, - // 65 A - { - 0b0000000000000000, - 0b0000001110000000, - 0b0000001111000000, - 0b0000011111000000, - 0b0000011111100000, - 0b0000111011100000, - 0b0000111001100000, - 0b0000110001110000, - 0b0001110001110000, - 0b0001111111111000, - 0b0011111111111000, - 0b0011111111111000, - 0b0011000000011100, - 0b0111000000011100, - 0b0111000000001110, - 0b0000000000000000 - }, - // 66 B - { - 0b0000000000000000, - 0b0011111111110000, - 0b0011111111111000, - 0b0011100000111000, - 0b0011100000111000, - 0b0011100000111000, - 0b0011111111110000, - 0b0011111111100000, - 0b0011111111111000, - 0b0011100000111000, - 0b0011100000011100, - 0b0011100000011100, - 0b0011100000111000, - 0b0011111111111000, - 0b0011111111110000, - 0b0000000000000000, - }, - // 67 C - { - 0b0000000000000000, - 0b0000011111110000, - 0b0000111111111100, - 0b0001110000011100, - 0b0011100000001100, - 0b0011100000000000, - 0b0011100000000000, - 0b0011100000000000, - 0b0011100000000000, - 0b0011100000000000, - 0b0011100000000100, - 0b0011110000001110, - 0b0001111000011100, - 0b0000111111111000, - 0b0000011111110000, - 0b0000000000000000 - }, - // 68 D - { - 0b0000000000000000, - 0b0011111111100000, - 0b0011111111111000, - 0b0011100000111100, - 0b0011100000011100, - 0b0011100000001110, - 0b0011100000001110, - 0b0011100000001110, - 0b0011100000001110, - 0b0011100000001110, - 0b0011100000001110, - 0b0011100000011100, - 0b0011100000111100, - 0b0011111111111000, - 0b0011111111100000, - 0b0000000000000000 - }, - // 69 E - { - 0b0000000000000000, - 0b0011111111111100, - 0b0011111111111100, - 0b0011100000000000, - 0b0011100000000000, - 0b0011100000000000, - 0b0011100000000000, - 0b0011111111111000, - 0b0011111111111000, - 0b0011100000000000, - 0b0011100000000000, - 0b0011100000000000, - 0b0011100000000000, - 0b0011111111111100, - 0b0011111111111100, - 0b0000000000000000 - }, - // 70 F - { - 0b0000000000000000, - 0b0011111111111100, - 0b0011111111111100, - 0b0011100000000000, - 0b0011100000000000, - 0b0011100000000000, - 0b0011100000000000, - 0b0011100000000000, - 0b0011111111111000, - 0b0011111111111000, - 0b0011100000000000, - 0b0011100000000000, - 0b0011100000000000, - 0b0011100000000000, - 0b0011100000000000, - 0b0000000000000000 - }, - // 71 G - { - 0b0000000000000000, - 0b0000011111111000, - 0b0000111111111100, - 0b0001110000011110, - 0b0011100000001110, - 0b0011100000000000, - 0b0011000000000000, - 0b0011000000000000, - 0b0011000001111110, - 0b0011000001111110, - 0b0011100000000110, - 0b0011100000000110, - 0b0001111000001110, - 0b0000111111111100, - 0b0000011111111000, - 0b0000000000000000 - }, - // 72 H - { - 0b0000000000000000, - 0b0011000000001100, - 0b0011000000001100, - 0b0011000000001100, - 0b0011000000001100, - 0b0011000000001100, - 0b0011000000001100, - 0b0011111111111100, - 0b0011111111111100, - 0b0011000000001100, - 0b0011000000001100, - 0b0011000000001100, - 0b0011000000001100, - 0b0011000000001100, - 0b0011000000001100, - 0b0000000000000000 - }, - // 73 I - { - 0b0000000000000000, - 0b0000001111000000, - 0b0000001111000000, - 0b0000001111000000, - 0b0000001111000000, - 0b0000001111000000, - 0b0000001111000000, - 0b0000001111000000, - 0b0000001111000000, - 0b0000001111000000, - 0b0000001111000000, - 0b0000001111000000, - 0b0000001111000000, - 0b0000001111000000, - 0b0000001111000000, - 0b0000000000000000 - }, - // 74 J - { - 0b0000000000000000, - 0b0000000111110000, - 0b0000000111110000, - 0b0000000001110000, - 0b0000000001110000, - 0b0000000001110000, - 0b0000000001110000, - 0b0000000001110000, - 0b0000000001110000, - 0b0000000001110000, - 0b0000000001110000, - 0b0011100001110000, - 0b0011100001110000, - 0b0001111111100000, - 0b0000111111000000, - 0b0000000000000000 - }, - // 75 K - { - 0b0000000000000000, - 0b0011100000111100, - 0b0011100001111000, - 0b0011100011110000, - 0b0011100111100000, - 0b0011101111000000, - 0b0011111110000000, - 0b0011111100000000, - 0b0011111110000000, - 0b0011100111000000, - 0b0011100011100000, - 0b0011100001110000, - 0b0011100000111000, - 0b0011100000011100, - 0b0011100000001110, - 0b0000000000000000 - }, - // 76 L - { - 0b0000000000000000, - 0b0001110000000000, - 0b0001110000000000, - 0b0001110000000000, - 0b0001110000000000, - 0b0001110000000000, - 0b0001110000000000, - 0b0001110000000000, - 0b0001110000000000, - 0b0001110000000000, - 0b0001110000000000, - 0b0001110000000000, - 0b0001110000000000, - 0b0001111111111000, - 0b0001111111111000, - 0b0000000000000000 - }, - // 77 M - { - 0b0000000000000000, - 0b0011000000001100, - 0b0011100000011100, - 0b0011100000011100, - 0b0011110000111100, - 0b0011110000111100, - 0b0011110000111100, - 0b0011011001101100, - 0b0011011001101100, - 0b0011011001101100, - 0b0011001111001100, - 0b0011001111001100, - 0b0011000110001100, - 0b0011000110001100, - 0b0011000000001100, - 0b0000000000000000 - }, - // 78 N - { - 0b0000000000000000, - 0b0011110000001100, - 0b0011110000001100, - 0b0011111000001100, - 0b0011111100001100, - 0b0011111100001100, - 0b0011101110001100, - 0b0011101110001100, - 0b0011100111001100, - 0b0011100011101100, - 0b0011100011101100, - 0b0011100001111100, - 0b0011100000111100, - 0b0011100000111100, - 0b0011100000011100, - 0b0000000000000000 - }, - // 79 O - { - 0b0000000000000000, - 0b0000111111110000, - 0b0001111111111000, - 0b0011110000111100, - 0b0011100000011100, - 0b0011000000001100, - 0b0011000000001100, - 0b0011000000001100, - 0b0011000000001100, - 0b0011000000001100, - 0b0011000000001100, - 0b0011100000011100, - 0b0011110000111100, - 0b0001111111111000, - 0b0000111111110000, - 0b0000000000000000 - }, - // 80 P - { - 0b0000000000000000, - 0b0011111111100000, - 0b0011111111110000, - 0b0011100000111000, - 0b0011100000011000, - 0b0011100000011000, - 0b0011100000011000, - 0b0011100000111000, - 0b0011111111110000, - 0b0011111111100000, - 0b0011100000000000, - 0b0011100000000000, - 0b0011100000000000, - 0b0011100000000000, - 0b0011100000000000, - 0b0000000000000000 - }, - // 81 Q - { - 0b0000000000000000, - 0b0000111111100000, - 0b0001111111110000, - 0b0011100000111000, - 0b0011000000011000, - 0b0111000000011100, - 0b0111000000011100, - 0b0111000000011100, - 0b0011000000011000, - 0b0011100000111000, - 0b0001111111110000, - 0b0000111111100000, - 0b0000001110000000, - 0b0000000111110000, - 0b0000000011110000, - 0b0000000000000000 - }, - // 82 R - { - 0b0000000000000000, - 0b0011111111111000, - 0b0011111111111100, - 0b0011100000011100, - 0b0011100000001100, - 0b0011100000001100, - 0b0011100000011100, - 0b0011111111111100, - 0b0011111111111000, - 0b0011100011100000, - 0b0011100001110000, - 0b0011100000111000, - 0b0011100000011000, - 0b0011100000011100, - 0b0011100000001110, - 0b0000000000000000 - }, - // 83 S - { - 0b0000000000000000, - 0b0000111111110000, - 0b0001111111111000, - 0b0011100000111000, - 0b0011100000011000, - 0b0011100000000000, - 0b0001111100000000, - 0b0000111111100000, - 0b0000001111111000, - 0b0000000000111000, - 0b0000000000011100, - 0b0011000000011100, - 0b0011100000111100, - 0b0001111111111000, - 0b0000111111110000, - 0b0000000000000000 - }, - // 84 T - { - 0b0000000000000000, - 0b0011111111111100, - 0b0011111111111100, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000000000000 - }, - // 85 U - { - 0b0000000000000000, - 0b0011000000001100, - 0b0011000000001100, - 0b0011000000001100, - 0b0011000000001100, - 0b0011000000001100, - 0b0011000000001100, - 0b0011000000001100, - 0b0011000000001100, - 0b0011000000001100, - 0b0011000000001100, - 0b0011000000001100, - 0b0001100000011000, - 0b0000111111110000, - 0b0000011111100000, - 0b0000000000000000 - }, - // 86 V - { - 0b0000000000000000, - 0b0001000000000100, - 0b0011100000001110, - 0b0011100000001110, - 0b0001110000001100, - 0b0001110000011100, - 0b0000111000011000, - 0b0000111000111000, - 0b0000011000111000, - 0b0000011100110000, - 0b0000001101110000, - 0b0000001101100000, - 0b0000001111100000, - 0b0000000111000000, - 0b0000000111000000, - 0b0000000000000000 - }, - // 87 W - { - 0b0000000000000000, - 0b0110000000000110, - 0b0110000000000110, - 0b0110000000000110, - 0b0110000110000110, - 0b0110000110000110, - 0b0110000110000110, - 0b0111001111000110, - 0b0011001111001100, - 0b0011001111001100, - 0b0011001001101100, - 0b0001111001101000, - 0b0001111001111000, - 0b0001110000111000, - 0b0000110000110000, - 0b0000000000000000 - }, - // 88 X - { - 0b0000000000000000, - 0b0011000000011000, - 0b0011100000111000, - 0b0001110001110000, - 0b0000111011100000, - 0b0000011111000000, - 0b0000001110000000, - 0b0000001110000000, - 0b0000001110000000, - 0b0000011111000000, - 0b0000111011100000, - 0b0001110001110000, - 0b0011100000111000, - 0b0011000000011000, - 0b0011000000011000, - 0b0000000000000000 - }, - // 89 Y - { - 0b0000000000000000, - 0b0011100000001100, - 0b0001110000011100, - 0b0000110000111000, - 0b0000111000110000, - 0b0000011101110000, - 0b0000001111100000, - 0b0000001111000000, - 0b0000000111000000, - 0b0000000111000000, - 0b0000000111000000, - 0b0000000111000000, - 0b0000000111000000, - 0b0000000111000000, - 0b0000000111000000, - 0b0000000000000000 - }, - // 90 Z - { - 0b0000000000000000, - 0b0011111111111100, - 0b0011111111111100, - 0b0000000000011100, - 0b0000000000111000, - 0b0000000001110000, - 0b0000000011100000, - 0b0000000111000000, - 0b0000001110000000, - 0b0000011100000000, - 0b0000111000000000, - 0b0001110000000000, - 0b0011110000000000, - 0b0011111111111100, - 0b0011111111111100, - 0b0000000000000000 - }, - // 91 [ - { - 0b0000000000000000, - 0b0000001111000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000001111000000, - 0b0000000000000000 - }, - // 92 '\' - { - 0b0000000000000000, - 0b0000011000000000, - 0b0000011000000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000011000000, - 0b0000000011000000, - 0b0000000001100000, - 0b0000000001100000, - 0b0000000000110000, - 0b0000000000110000, - 0b0000000000011000, - 0b0000000000011000, - 0b0000000000000000 - }, - // 93 ] - { - 0b0000000000000000, - 0b0000001111000000, - 0b0000000011000000, - 0b0000000011000000, - 0b0000000011000000, - 0b0000000011000000, - 0b0000000011000000, - 0b0000000011000000, - 0b0000000011000000, - 0b0000000011000000, - 0b0000000011000000, - 0b0000000011000000, - 0b0000000011000000, - 0b0000000011000000, - 0b0000001111000000, - 0b0000000000000000 - }, - // 94 ^ - { - 0b0000000000000000, - 0b0000000000000000, - 0b0000001100000000, - 0b0000001110000000, - 0b0000011010000000, - 0b0000010011000000, - 0b0000110001000000, - 0b0000100001100000, - 0b0001100000100000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000 - }, - // 95 _ - { - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0011111111111100, - 0b0011111111111100, - 0b0000000000000000 - }, - // 96 ` - { - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000110000000000, - 0b0000011000000000, - 0b0000001100000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000 - }, - // 97 a - { - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000011111000000, - 0b0000111111100000, - 0b0000110001100000, - 0b0000000001100000, - 0b0000011111100000, - 0b0000111111100000, - 0b0001100001100000, - 0b0001100001100000, - 0b0001111111110000, - 0b0000111110110000, - 0b0000000000000000 - }, - // 98 b - { - 0b0000000000000000, - 0b0001100000000000, - 0b0001100000000000, - 0b0001100000000000, - 0b0001100000000000, - 0b0001101111100000, - 0b0001111111110000, - 0b0001110000110000, - 0b0001100000110000, - 0b0001100000110000, - 0b0001100000110000, - 0b0001100000110000, - 0b0001110000110000, - 0b0001111111110000, - 0b0001101111100000, - 0b0000000000000000 - }, - // 99 c - { - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000001111100000, - 0b0000011111110000, - 0b0000110000111000, - 0b0000110000010000, - 0b0000110000000000, - 0b0000110000000000, - 0b0000110000010000, - 0b0000110000111000, - 0b0000011111110000, - 0b0000001111100000, - 0b0000000000000000 - }, - // 100 d - { - 0b0000000000000000, - 0b0000000000110000, - 0b0000000000110000, - 0b0000000000110000, - 0b0000000000110000, - 0b0000011110110000, - 0b0000111111110000, - 0b0001110001110000, - 0b0001100000110000, - 0b0001100000110000, - 0b0001100000110000, - 0b0001100000110000, - 0b0001110001110000, - 0b0000111111110000, - 0b0000011110110000, - 0b0000000000000000 - }, - // 101 e - { - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000001111100000, - 0b0000011111110000, - 0b0000110000011000, - 0b0000110000011000, - 0b0000111111111000, - 0b0000110000000000, - 0b0000110000000000, - 0b0000111000011000, - 0b0000011100110000, - 0b0000001111100000, - 0b0000000000000000 - }, - // 102 f - { - 0b0000000000000000, - 0b0000000111100000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000111111000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000000000000000 - }, - // 103 g - { - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000111111000000, - 0b0000111111100000, - 0b0001110011100000, - 0b0001100001100000, - 0b0001100001100000, - 0b0001100001100000, - 0b0001100001100000, - 0b0000110011100000, - 0b0000011111100000, - 0b0000000001100000, - 0b0000110011000000, - 0b0000011110000000 - }, - // 104 h - { - 0b0000000000000000, - 0b0000110000000000, - 0b0000110000000000, - 0b0000110000000000, - 0b0000110000000000, - 0b0000110111100000, - 0b0000111111110000, - 0b0000111000110000, - 0b0000110000110000, - 0b0000110000110000, - 0b0000110000110000, - 0b0000110000110000, - 0b0000110000110000, - 0b0000110000110000, - 0b0000110000110000, - 0b0000000000000000 - }, - // 105 i - { - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000000000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000000000000 - }, - // 106 j - { - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000000000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000011110000000, - 0b0000011100000000 - }, - // 107 k - { - 0b0000000000000000, - 0b0000011000000000, - 0b0000011000000000, - 0b0000011000000000, - 0b0000011000011000, - 0b0000011000110000, - 0b0000011001100000, - 0b0000011011000000, - 0b0000011110000000, - 0b0000011110000000, - 0b0000011011000000, - 0b0000011001100000, - 0b0000011000110000, - 0b0000011000011000, - 0b0000011000001000, - 0b0000000000000000 - }, - // 108 l - { - 0b0000000000000000, - 0b0000011110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000111100000, - 0b0000000011100000, - 0b0000000000000000 - }, - // 109 m - { - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0011011101111000, - 0b0011100111001100, - 0b0011000110001100, - 0b0011000110001100, - 0b0011000110001100, - 0b0011000110001100, - 0b0011000110001100, - 0b0011000110001100, - 0b0011000110001100, - 0b0000000000000000 - }, - // 110 n - { - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000110111000000, - 0b0000111001100000, - 0b0000110000110000, - 0b0000110000110000, - 0b0000110000110000, - 0b0000110000110000, - 0b0000110000110000, - 0b0000110000110000, - 0b0000110000110000, - 0b0000000000000000 - }, - // 111 o - { - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000001111000000, - 0b0000011001100000, - 0b0000110000110000, - 0b0000110000110000, - 0b0000110000110000, - 0b0000110000110000, - 0b0000110000110000, - 0b0000110000110000, - 0b0000011001100000, - 0b0000001111000000, - 0b0000000000000000 - }, - // 112 p - { - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000011111100000, - 0b0000011100110000, - 0b0000011000011000, - 0b0000011000011000, - 0b0000011000011000, - 0b0000011000011000, - 0b0000011100110000, - 0b0000011111100000, - 0b0000011000000000, - 0b0000011000000000, - 0b0000011000000000 - }, - // 113 q - { - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000011111100000, - 0b0000110011100000, - 0b0001100001100000, - 0b0001100001100000, - 0b0001100001100000, - 0b0001100001100000, - 0b0000110011100000, - 0b0000011111100000, - 0b0000000001100000, - 0b0000000001100000, - 0b0000000001100000 - }, - // 114 r - { - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000001011100000, - 0b0000001111000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000000000000000 - }, - // 115 s - { - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000011111000000, - 0b0000111001100000, - 0b0000110000100000, - 0b0000111100000000, - 0b0000011111000000, - 0b0000000111100000, - 0b0000000000110000, - 0b0000100000110000, - 0b0000111001110000, - 0b0000011111100000, - 0b0000000000000000 - }, - // 116 t - { - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000001000000000, - 0b0000011000000000, - 0b0000111110000000, - 0b0000011000000000, - 0b0000011000000000, - 0b0000011000000000, - 0b0000011000000000, - 0b0000011000000000, - 0b0000011000000000, - 0b0000011000000000, - 0b0000011100000000, - 0b0000001110000000, - 0b0000000000000000 - }, - // 117 u - { - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000110000110000, - 0b0000110000110000, - 0b0000110000110000, - 0b0000110000110000, - 0b0000110000110000, - 0b0000110000110000, - 0b0000110000110000, - 0b0000110000110000, - 0b0000011001110000, - 0b0000001111010000, - 0b0000000000000000 - }, - // 118 v - { - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0001100000110000, - 0b0001100000110000, - 0b0000110000110000, - 0b0000110001100000, - 0b0000011001100000, - 0b0000011001100000, - 0b0000011011000000, - 0b0000001111000000, - 0b0000001110000000, - 0b0000000110000000, - 0b0000000000000000 - }, - // 119 w - { - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0011000000011000, - 0b0011000000011000, - 0b0011000100011000, - 0b0011001110011000, - 0b0011001110011000, - 0b0011001010011000, - 0b0001111010110000, - 0b0001110011110000, - 0b0000110001100000, - 0b0000110001100000, - 0b0000000000000000 - }, - // 120 x - { - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000110000110000, - 0b0000111001110000, - 0b0000011101100000, - 0b0000001111000000, - 0b0000000110000000, - 0b0000001111000000, - 0b0000011101100000, - 0b0000111001110000, - 0b0000110000110000, - 0b0000000000000000 - }, - // 121 y - { - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000110000110000, - 0b0000011000100000, - 0b0000011001100000, - 0b0000001001100000, - 0b0000001101000000, - 0b0000000111000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000100000000, - 0b0000001100000000, - 0b0000111000000000 - }, - // 122 z - { - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000111111110000, - 0b0000000000110000, - 0b0000000001100000, - 0b0000000011000000, - 0b0000000110000000, - 0b0000001100000000, - 0b0000011000000000, - 0b0000110000000000, - 0b0000111111110000, - 0b0000000000000000 - }, - // 123 { - { - 0b0000000000000000, - 0b0000000111100000, - 0b0000001110000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000111000000000, - 0b0001110000000000, - 0b0000111000000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000001100000000, - 0b0000001110000000, - 0b0000000111100000, - 0b0000000000000000 - }, - // 124 | - { - 0b0000000000000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000110000000, - 0b0000000000000000 - }, - // 125 } - { - 0b0000000000000000, - 0b0000011110000000, - 0b0000000111000000, - 0b0000000011000000, - 0b0000000011000000, - 0b0000000011000000, - 0b0000000011000000, - 0b0000000001110000, - 0b0000000000111000, - 0b0000000001110000, - 0b0000000011000000, - 0b0000000011000000, - 0b0000000011000000, - 0b0000000111000000, - 0b0000011110000000, - 0b0000000000000000 - }, - // 126 ~ - { - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0001111110001000, - 0b0001000111111000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000, - 0b0000000000000000 - }, - -}; \ No newline at end of file +// font_data.c - A small utility file containing some bitmap font data. + +#include + +// Sourced from: https://github.com/pritamzope/OS + +uint32_t font_data[127][20] = { + // first 32 entries are empty + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + // 33 ! + { + 0b0000000000000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000000000000 + }, + // 34 " + { + 0b0000000000000000, + 0b0000000000000000, + 0b0000011001100000, + 0b0000011001100000, + 0b0000011001100000, + 0b0000011001100000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000 + }, + // 35 # + { + 0b0000000000000000, + 0b0000011000110000, + 0b0000011000110000, + 0b0000011000110000, + 0b0000011000110000, + 0b0001111111111000, + 0b0000110001100000, + 0b0000110001100000, + 0b0000110001100000, + 0b0000110001100000, + 0b0011111111111000, + 0b0001100011000000, + 0b0001100011000000, + 0b0001100011000000, + 0b0001100011000000, + 0b0000000000000000 + }, + // 36 $ + { + 0b0000000000000000, + 0b0000000110000000, + 0b0000011111100000, + 0b0000111111110000, + 0b0000110110110000, + 0b0000110110000000, + 0b0000111110000000, + 0b0000011111000000, + 0b0000000111100000, + 0b0000000110110000, + 0b0000000110110000, + 0b0000100110110000, + 0b0000111111110000, + 0b0000011111100000, + 0b0000000110000000, + 0b0000000000000000 + }, + // 37 % + { + 0b0000000000000000, + 0b0000000000000000, + 0b0001100000010000, + 0b0010010000110000, + 0b0110011001100000, + 0b0110011001000000, + 0b0110011011000000, + 0b0110010010011000, + 0b0010010110100100, + 0b0001100101100110, + 0b0000001101100110, + 0b0000011001100110, + 0b0000010000100100, + 0b0000110000011000, + 0b0001100000000000, + 0b0000000000000000 + }, + // 38 & + { + 0b0000000000000000, + 0b0000000000000000, + 0b0000001111000000, + 0b0000011001100000, + 0b0000010001100000, + 0b0000010001100000, + 0b0000011011000000, + 0b0000011110000000, + 0b0000111100010000, + 0b0001100100010000, + 0b0011000110010000, + 0b0011000011110000, + 0b0011100001100000, + 0b0001110111110000, + 0b0000111110011100, + 0b0000000000000000 + }, + // 39 ' + { + 0b0000000000000000, + 0b0000000000000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000 + }, + // 40 ( + { + 0b0000000000000000, + 0b0000000110000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000011000000000, + 0b0000011000000000, + 0b0000011000000000, + 0b0000011000000000, + 0b0000011000000000, + 0b0000011000000000, + 0b0000011000000000, + 0b0000011000000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000000110000000, + 0b0000000000000000 + }, + // 41 ) + { + 0b0000000000000000, + 0b0000001100000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000011000000, + 0b0000000011000000, + 0b0000000011000000, + 0b0000000011000000, + 0b0000000011000000, + 0b0000000011000000, + 0b0000000011000000, + 0b0000000011000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000001100000000, + 0b0000000000000000 + }, + // 42 * + { + 0b0000000000000000, + 0b0000000000000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000110110110000, + 0b0000011111100000, + 0b0000000110000000, + 0b0000001111000000, + 0b0000011001100000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000 + }, + // 43 + + { + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000111111110000, + 0b0000111111110000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000 + }, + // 44 , + { + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000111000000, + 0b0000000111000000, + 0b0000000011000000, + 0b0000000011000000, + 0b0000001011000000, + 0b0000000110000000, + 0b0000000000000000 + }, + // 45 - + { + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000111111110000, + 0b0000111111110000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000 + }, + // 46 . + { + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000111000000, + 0b0000000111000000, + 0b0000000111000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000 + }, + // 47 / + { + 0b0000000000000000, + 0b0000000001100000, + 0b0000000001100000, + 0b0000000011000000, + 0b0000000011000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000011000000000, + 0b0000011000000000, + 0b0000110000000000, + 0b0000110000000000, + 0b0001100000000000, + 0b0001100000000000, + 0b0000000000000000 + }, + // 48 0 + { + 0b0000000000000000, + 0b0000011111000000, + 0b0000111111100000, + 0b0000110001100000, + 0b0001100000110000, + 0b0001100000110000, + 0b0001101110110000, + 0b0001101110110000, + 0b0001100000110000, + 0b0001100000110000, + 0b0001100000110000, + 0b0001100000110000, + 0b0000110001100000, + 0b0000111111100000, + 0b0000011111000000, + 0b0000000000000000 + }, + // 49 1 + { + 0b0000000000000000, + 0b0000001110000000, + 0b0000011110000000, + 0b0000110110000000, + 0b0000100110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000111111110000, + 0b0000111111110000, + 0b0000000000000000 + }, + // 50 2 + { + 0b0000000000000000, + 0b0000011111000000, + 0b0000111111100000, + 0b0001100000110000, + 0b0001100000110000, + 0b0000000000110000, + 0b0000000000110000, + 0b0000000001100000, + 0b0000000011000000, + 0b0000000110000000, + 0b0000001100000000, + 0b0000011000000000, + 0b0000110000000000, + 0b0001111111110000, + 0b0001111111110000, + 0b0000000000000000 + }, + // 51 3 + { + 0b0000000000000000, + 0b0000011111000000, + 0b0000111111100000, + 0b0001100000110000, + 0b0001100000110000, + 0b0000000000110000, + 0b0000000001100000, + 0b0000001111000000, + 0b0000001111100000, + 0b0000000000110000, + 0b0000000000110000, + 0b0001100000110000, + 0b0001100000110000, + 0b0000111111100000, + 0b0000011111000000, + 0b0000000000000000 + }, + // 52 4 + { + 0b0000000000000000, + 0b0000000011100000, + 0b0000000111100000, + 0b0000000111100000, + 0b0000001101100000, + 0b0000001101100000, + 0b0000011001100000, + 0b0000111001100000, + 0b0000110001100000, + 0b0001100001100000, + 0b0001100001100000, + 0b0011111111111000, + 0b0011111111111000, + 0b0000000001100000, + 0b0000000001100000, + 0b0000000000000000 + }, + // 53 5 + { + 0b0000000000000000, + 0b0001111111110000, + 0b0001111111110000, + 0b0001100000000000, + 0b0001100000000000, + 0b0001100000000000, + 0b0001111111000000, + 0b0001111111100000, + 0b0000000000110000, + 0b0000000000110000, + 0b0000000000110000, + 0b0001100000110000, + 0b0001100000110000, + 0b0000111111100000, + 0b0000011111000000, + 0b0000000000000000 + }, + // 54 6 + { + 0b0000000000000000, + 0b0000001111000000, + 0b0000011111100000, + 0b0000110000110000, + 0b0001100000000000, + 0b0001100000000000, + 0b0001101111000000, + 0b0001111111100000, + 0b0001110000110000, + 0b0001100000110000, + 0b0001100000110000, + 0b0001100000110000, + 0b0000110000110000, + 0b0000111111100000, + 0b0000001111000000, + 0b0000000000000000 + }, + // 55 7 + { + 0b0000000000000000, + 0b0001111111110000, + 0b0001111111110000, + 0b0000000000110000, + 0b0000000001100000, + 0b0000000011000000, + 0b0000000011000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000000000000000 + }, + // 56 8 + { + 0b0000000000000000, + 0b0000011111000000, + 0b0000111111100000, + 0b0001100000110000, + 0b0001100000110000, + 0b0001100000110000, + 0b0000110001100000, + 0b0000011111000000, + 0b0000111111100000, + 0b0001100000110000, + 0b0001100000110000, + 0b0001100000110000, + 0b0001100000110000, + 0b0000111111100000, + 0b0000011111000000, + 0b0000000000000000 + }, + // 57 9 + { + 0b0000000000000000, + 0b0000011111000000, + 0b0000111111100000, + 0b0001100001100000, + 0b0001100000110000, + 0b0001100000110000, + 0b0001100000110000, + 0b0001100001110000, + 0b0000111111110000, + 0b0000011110110000, + 0b0000000000110000, + 0b0000000000110000, + 0b0001100001100000, + 0b0000111111100000, + 0b0000011110000000, + 0b0000000000000000 + }, + // 58 : + { + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000111000000, + 0b0000000111000000, + 0b0000000111000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000111000000, + 0b0000000111000000, + 0b0000000111000000, + 0b0000000000000000 + }, + // 59 ; + { + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000111000000, + 0b0000000111000000, + 0b0000000111000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000111000000, + 0b0000000111000000, + 0b0000000011000000, + 0b0000000011000000, + 0b0000001011000000, + 0b0000000110000000, + 0b0000000000000000 + }, + // 60 < + { + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000010000, + 0b0000000001110000, + 0b0000000111000000, + 0b0000111100000000, + 0b0000110000000000, + 0b0000111100000000, + 0b0000000111000000, + 0b0000000001110000, + 0b0000000000010000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000 + }, + // 61 = + { + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0001111111111000, + 0b0001111111111000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0001111111111000, + 0b0001111111111000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000 + }, + // 62 > + { + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000100000000000, + 0b0000111000000000, + 0b0000001110000000, + 0b0000000011110000, + 0b0000000000110000, + 0b0000000011110000, + 0b0000001110000000, + 0b0000111000000000, + 0b0000100000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000 + }, + // 63 ? + { + 0b0000000000000000, + 0b0000011111000000, + 0b0000111111100000, + 0b0001100000110000, + 0b0001100000110000, + 0b0001100000110000, + 0b0000000000110000, + 0b0000000001100000, + 0b0000000011000000, + 0b0000000110000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000000000000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000000000000000 + }, + // 64 @ + { + 0b0000000000000000, + 0b0000000000000000, + 0b0000111111100000, + 0b0001111111111000, + 0b0011100000001100, + 0b0111001110101100, + 0b0110011011101100, + 0b0110110001101100, + 0b0110100001101100, + 0b0110100011001100, + 0b0110110111011000, + 0b0110011101110000, + 0b0011000000000000, + 0b0011110011110000, + 0b0000111111000000, + 0b0000000000000000 + }, + // 65 A + { + 0b0000000000000000, + 0b0000001110000000, + 0b0000001111000000, + 0b0000011111000000, + 0b0000011111100000, + 0b0000111011100000, + 0b0000111001100000, + 0b0000110001110000, + 0b0001110001110000, + 0b0001111111111000, + 0b0011111111111000, + 0b0011111111111000, + 0b0011000000011100, + 0b0111000000011100, + 0b0111000000001110, + 0b0000000000000000 + }, + // 66 B + { + 0b0000000000000000, + 0b0011111111110000, + 0b0011111111111000, + 0b0011100000111000, + 0b0011100000111000, + 0b0011100000111000, + 0b0011111111110000, + 0b0011111111100000, + 0b0011111111111000, + 0b0011100000111000, + 0b0011100000011100, + 0b0011100000011100, + 0b0011100000111000, + 0b0011111111111000, + 0b0011111111110000, + 0b0000000000000000, + }, + // 67 C + { + 0b0000000000000000, + 0b0000011111110000, + 0b0000111111111100, + 0b0001110000011100, + 0b0011100000001100, + 0b0011100000000000, + 0b0011100000000000, + 0b0011100000000000, + 0b0011100000000000, + 0b0011100000000000, + 0b0011100000000100, + 0b0011110000001110, + 0b0001111000011100, + 0b0000111111111000, + 0b0000011111110000, + 0b0000000000000000 + }, + // 68 D + { + 0b0000000000000000, + 0b0011111111100000, + 0b0011111111111000, + 0b0011100000111100, + 0b0011100000011100, + 0b0011100000001110, + 0b0011100000001110, + 0b0011100000001110, + 0b0011100000001110, + 0b0011100000001110, + 0b0011100000001110, + 0b0011100000011100, + 0b0011100000111100, + 0b0011111111111000, + 0b0011111111100000, + 0b0000000000000000 + }, + // 69 E + { + 0b0000000000000000, + 0b0011111111111100, + 0b0011111111111100, + 0b0011100000000000, + 0b0011100000000000, + 0b0011100000000000, + 0b0011100000000000, + 0b0011111111111000, + 0b0011111111111000, + 0b0011100000000000, + 0b0011100000000000, + 0b0011100000000000, + 0b0011100000000000, + 0b0011111111111100, + 0b0011111111111100, + 0b0000000000000000 + }, + // 70 F + { + 0b0000000000000000, + 0b0011111111111100, + 0b0011111111111100, + 0b0011100000000000, + 0b0011100000000000, + 0b0011100000000000, + 0b0011100000000000, + 0b0011100000000000, + 0b0011111111111000, + 0b0011111111111000, + 0b0011100000000000, + 0b0011100000000000, + 0b0011100000000000, + 0b0011100000000000, + 0b0011100000000000, + 0b0000000000000000 + }, + // 71 G + { + 0b0000000000000000, + 0b0000011111111000, + 0b0000111111111100, + 0b0001110000011110, + 0b0011100000001110, + 0b0011100000000000, + 0b0011000000000000, + 0b0011000000000000, + 0b0011000001111110, + 0b0011000001111110, + 0b0011100000000110, + 0b0011100000000110, + 0b0001111000001110, + 0b0000111111111100, + 0b0000011111111000, + 0b0000000000000000 + }, + // 72 H + { + 0b0000000000000000, + 0b0011000000001100, + 0b0011000000001100, + 0b0011000000001100, + 0b0011000000001100, + 0b0011000000001100, + 0b0011000000001100, + 0b0011111111111100, + 0b0011111111111100, + 0b0011000000001100, + 0b0011000000001100, + 0b0011000000001100, + 0b0011000000001100, + 0b0011000000001100, + 0b0011000000001100, + 0b0000000000000000 + }, + // 73 I + { + 0b0000000000000000, + 0b0000001111000000, + 0b0000001111000000, + 0b0000001111000000, + 0b0000001111000000, + 0b0000001111000000, + 0b0000001111000000, + 0b0000001111000000, + 0b0000001111000000, + 0b0000001111000000, + 0b0000001111000000, + 0b0000001111000000, + 0b0000001111000000, + 0b0000001111000000, + 0b0000001111000000, + 0b0000000000000000 + }, + // 74 J + { + 0b0000000000000000, + 0b0000000111110000, + 0b0000000111110000, + 0b0000000001110000, + 0b0000000001110000, + 0b0000000001110000, + 0b0000000001110000, + 0b0000000001110000, + 0b0000000001110000, + 0b0000000001110000, + 0b0000000001110000, + 0b0011100001110000, + 0b0011100001110000, + 0b0001111111100000, + 0b0000111111000000, + 0b0000000000000000 + }, + // 75 K + { + 0b0000000000000000, + 0b0011100000111100, + 0b0011100001111000, + 0b0011100011110000, + 0b0011100111100000, + 0b0011101111000000, + 0b0011111110000000, + 0b0011111100000000, + 0b0011111110000000, + 0b0011100111000000, + 0b0011100011100000, + 0b0011100001110000, + 0b0011100000111000, + 0b0011100000011100, + 0b0011100000001110, + 0b0000000000000000 + }, + // 76 L + { + 0b0000000000000000, + 0b0001110000000000, + 0b0001110000000000, + 0b0001110000000000, + 0b0001110000000000, + 0b0001110000000000, + 0b0001110000000000, + 0b0001110000000000, + 0b0001110000000000, + 0b0001110000000000, + 0b0001110000000000, + 0b0001110000000000, + 0b0001110000000000, + 0b0001111111111000, + 0b0001111111111000, + 0b0000000000000000 + }, + // 77 M + { + 0b0000000000000000, + 0b0011000000001100, + 0b0011100000011100, + 0b0011100000011100, + 0b0011110000111100, + 0b0011110000111100, + 0b0011110000111100, + 0b0011011001101100, + 0b0011011001101100, + 0b0011011001101100, + 0b0011001111001100, + 0b0011001111001100, + 0b0011000110001100, + 0b0011000110001100, + 0b0011000000001100, + 0b0000000000000000 + }, + // 78 N + { + 0b0000000000000000, + 0b0011110000001100, + 0b0011110000001100, + 0b0011111000001100, + 0b0011111100001100, + 0b0011111100001100, + 0b0011101110001100, + 0b0011101110001100, + 0b0011100111001100, + 0b0011100011101100, + 0b0011100011101100, + 0b0011100001111100, + 0b0011100000111100, + 0b0011100000111100, + 0b0011100000011100, + 0b0000000000000000 + }, + // 79 O + { + 0b0000000000000000, + 0b0000111111110000, + 0b0001111111111000, + 0b0011110000111100, + 0b0011100000011100, + 0b0011000000001100, + 0b0011000000001100, + 0b0011000000001100, + 0b0011000000001100, + 0b0011000000001100, + 0b0011000000001100, + 0b0011100000011100, + 0b0011110000111100, + 0b0001111111111000, + 0b0000111111110000, + 0b0000000000000000 + }, + // 80 P + { + 0b0000000000000000, + 0b0011111111100000, + 0b0011111111110000, + 0b0011100000111000, + 0b0011100000011000, + 0b0011100000011000, + 0b0011100000011000, + 0b0011100000111000, + 0b0011111111110000, + 0b0011111111100000, + 0b0011100000000000, + 0b0011100000000000, + 0b0011100000000000, + 0b0011100000000000, + 0b0011100000000000, + 0b0000000000000000 + }, + // 81 Q + { + 0b0000000000000000, + 0b0000111111100000, + 0b0001111111110000, + 0b0011100000111000, + 0b0011000000011000, + 0b0111000000011100, + 0b0111000000011100, + 0b0111000000011100, + 0b0011000000011000, + 0b0011100000111000, + 0b0001111111110000, + 0b0000111111100000, + 0b0000001110000000, + 0b0000000111110000, + 0b0000000011110000, + 0b0000000000000000 + }, + // 82 R + { + 0b0000000000000000, + 0b0011111111111000, + 0b0011111111111100, + 0b0011100000011100, + 0b0011100000001100, + 0b0011100000001100, + 0b0011100000011100, + 0b0011111111111100, + 0b0011111111111000, + 0b0011100011100000, + 0b0011100001110000, + 0b0011100000111000, + 0b0011100000011000, + 0b0011100000011100, + 0b0011100000001110, + 0b0000000000000000 + }, + // 83 S + { + 0b0000000000000000, + 0b0000111111110000, + 0b0001111111111000, + 0b0011100000111000, + 0b0011100000011000, + 0b0011100000000000, + 0b0001111100000000, + 0b0000111111100000, + 0b0000001111111000, + 0b0000000000111000, + 0b0000000000011100, + 0b0011000000011100, + 0b0011100000111100, + 0b0001111111111000, + 0b0000111111110000, + 0b0000000000000000 + }, + // 84 T + { + 0b0000000000000000, + 0b0011111111111100, + 0b0011111111111100, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000000000000 + }, + // 85 U + { + 0b0000000000000000, + 0b0011000000001100, + 0b0011000000001100, + 0b0011000000001100, + 0b0011000000001100, + 0b0011000000001100, + 0b0011000000001100, + 0b0011000000001100, + 0b0011000000001100, + 0b0011000000001100, + 0b0011000000001100, + 0b0011000000001100, + 0b0001100000011000, + 0b0000111111110000, + 0b0000011111100000, + 0b0000000000000000 + }, + // 86 V + { + 0b0000000000000000, + 0b0001000000000100, + 0b0011100000001110, + 0b0011100000001110, + 0b0001110000001100, + 0b0001110000011100, + 0b0000111000011000, + 0b0000111000111000, + 0b0000011000111000, + 0b0000011100110000, + 0b0000001101110000, + 0b0000001101100000, + 0b0000001111100000, + 0b0000000111000000, + 0b0000000111000000, + 0b0000000000000000 + }, + // 87 W + { + 0b0000000000000000, + 0b0110000000000110, + 0b0110000000000110, + 0b0110000000000110, + 0b0110000110000110, + 0b0110000110000110, + 0b0110000110000110, + 0b0111001111000110, + 0b0011001111001100, + 0b0011001111001100, + 0b0011001001101100, + 0b0001111001101000, + 0b0001111001111000, + 0b0001110000111000, + 0b0000110000110000, + 0b0000000000000000 + }, + // 88 X + { + 0b0000000000000000, + 0b0011000000011000, + 0b0011100000111000, + 0b0001110001110000, + 0b0000111011100000, + 0b0000011111000000, + 0b0000001110000000, + 0b0000001110000000, + 0b0000001110000000, + 0b0000011111000000, + 0b0000111011100000, + 0b0001110001110000, + 0b0011100000111000, + 0b0011000000011000, + 0b0011000000011000, + 0b0000000000000000 + }, + // 89 Y + { + 0b0000000000000000, + 0b0011100000001100, + 0b0001110000011100, + 0b0000110000111000, + 0b0000111000110000, + 0b0000011101110000, + 0b0000001111100000, + 0b0000001111000000, + 0b0000000111000000, + 0b0000000111000000, + 0b0000000111000000, + 0b0000000111000000, + 0b0000000111000000, + 0b0000000111000000, + 0b0000000111000000, + 0b0000000000000000 + }, + // 90 Z + { + 0b0000000000000000, + 0b0011111111111100, + 0b0011111111111100, + 0b0000000000011100, + 0b0000000000111000, + 0b0000000001110000, + 0b0000000011100000, + 0b0000000111000000, + 0b0000001110000000, + 0b0000011100000000, + 0b0000111000000000, + 0b0001110000000000, + 0b0011110000000000, + 0b0011111111111100, + 0b0011111111111100, + 0b0000000000000000 + }, + // 91 [ + { + 0b0000000000000000, + 0b0000001111000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000001111000000, + 0b0000000000000000 + }, + // 92 '\' + { + 0b0000000000000000, + 0b0000011000000000, + 0b0000011000000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000011000000, + 0b0000000011000000, + 0b0000000001100000, + 0b0000000001100000, + 0b0000000000110000, + 0b0000000000110000, + 0b0000000000011000, + 0b0000000000011000, + 0b0000000000000000 + }, + // 93 ] + { + 0b0000000000000000, + 0b0000001111000000, + 0b0000000011000000, + 0b0000000011000000, + 0b0000000011000000, + 0b0000000011000000, + 0b0000000011000000, + 0b0000000011000000, + 0b0000000011000000, + 0b0000000011000000, + 0b0000000011000000, + 0b0000000011000000, + 0b0000000011000000, + 0b0000000011000000, + 0b0000001111000000, + 0b0000000000000000 + }, + // 94 ^ + { + 0b0000000000000000, + 0b0000000000000000, + 0b0000001100000000, + 0b0000001110000000, + 0b0000011010000000, + 0b0000010011000000, + 0b0000110001000000, + 0b0000100001100000, + 0b0001100000100000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000 + }, + // 95 _ + { + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0011111111111100, + 0b0011111111111100, + 0b0000000000000000 + }, + // 96 ` + { + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000110000000000, + 0b0000011000000000, + 0b0000001100000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000 + }, + // 97 a + { + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000011111000000, + 0b0000111111100000, + 0b0000110001100000, + 0b0000000001100000, + 0b0000011111100000, + 0b0000111111100000, + 0b0001100001100000, + 0b0001100001100000, + 0b0001111111110000, + 0b0000111110110000, + 0b0000000000000000 + }, + // 98 b + { + 0b0000000000000000, + 0b0001100000000000, + 0b0001100000000000, + 0b0001100000000000, + 0b0001100000000000, + 0b0001101111100000, + 0b0001111111110000, + 0b0001110000110000, + 0b0001100000110000, + 0b0001100000110000, + 0b0001100000110000, + 0b0001100000110000, + 0b0001110000110000, + 0b0001111111110000, + 0b0001101111100000, + 0b0000000000000000 + }, + // 99 c + { + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000001111100000, + 0b0000011111110000, + 0b0000110000111000, + 0b0000110000010000, + 0b0000110000000000, + 0b0000110000000000, + 0b0000110000010000, + 0b0000110000111000, + 0b0000011111110000, + 0b0000001111100000, + 0b0000000000000000 + }, + // 100 d + { + 0b0000000000000000, + 0b0000000000110000, + 0b0000000000110000, + 0b0000000000110000, + 0b0000000000110000, + 0b0000011110110000, + 0b0000111111110000, + 0b0001110001110000, + 0b0001100000110000, + 0b0001100000110000, + 0b0001100000110000, + 0b0001100000110000, + 0b0001110001110000, + 0b0000111111110000, + 0b0000011110110000, + 0b0000000000000000 + }, + // 101 e + { + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000001111100000, + 0b0000011111110000, + 0b0000110000011000, + 0b0000110000011000, + 0b0000111111111000, + 0b0000110000000000, + 0b0000110000000000, + 0b0000111000011000, + 0b0000011100110000, + 0b0000001111100000, + 0b0000000000000000 + }, + // 102 f + { + 0b0000000000000000, + 0b0000000111100000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000111111000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000000000000000 + }, + // 103 g + { + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000111111000000, + 0b0000111111100000, + 0b0001110011100000, + 0b0001100001100000, + 0b0001100001100000, + 0b0001100001100000, + 0b0001100001100000, + 0b0000110011100000, + 0b0000011111100000, + 0b0000000001100000, + 0b0000110011000000, + 0b0000011110000000 + }, + // 104 h + { + 0b0000000000000000, + 0b0000110000000000, + 0b0000110000000000, + 0b0000110000000000, + 0b0000110000000000, + 0b0000110111100000, + 0b0000111111110000, + 0b0000111000110000, + 0b0000110000110000, + 0b0000110000110000, + 0b0000110000110000, + 0b0000110000110000, + 0b0000110000110000, + 0b0000110000110000, + 0b0000110000110000, + 0b0000000000000000 + }, + // 105 i + { + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000000000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000000000000 + }, + // 106 j + { + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000000000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000011110000000, + 0b0000011100000000 + }, + // 107 k + { + 0b0000000000000000, + 0b0000011000000000, + 0b0000011000000000, + 0b0000011000000000, + 0b0000011000011000, + 0b0000011000110000, + 0b0000011001100000, + 0b0000011011000000, + 0b0000011110000000, + 0b0000011110000000, + 0b0000011011000000, + 0b0000011001100000, + 0b0000011000110000, + 0b0000011000011000, + 0b0000011000001000, + 0b0000000000000000 + }, + // 108 l + { + 0b0000000000000000, + 0b0000011110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000111100000, + 0b0000000011100000, + 0b0000000000000000 + }, + // 109 m + { + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0011011101111000, + 0b0011100111001100, + 0b0011000110001100, + 0b0011000110001100, + 0b0011000110001100, + 0b0011000110001100, + 0b0011000110001100, + 0b0011000110001100, + 0b0011000110001100, + 0b0000000000000000 + }, + // 110 n + { + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000110111000000, + 0b0000111001100000, + 0b0000110000110000, + 0b0000110000110000, + 0b0000110000110000, + 0b0000110000110000, + 0b0000110000110000, + 0b0000110000110000, + 0b0000110000110000, + 0b0000000000000000 + }, + // 111 o + { + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000001111000000, + 0b0000011001100000, + 0b0000110000110000, + 0b0000110000110000, + 0b0000110000110000, + 0b0000110000110000, + 0b0000110000110000, + 0b0000110000110000, + 0b0000011001100000, + 0b0000001111000000, + 0b0000000000000000 + }, + // 112 p + { + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000011111100000, + 0b0000011100110000, + 0b0000011000011000, + 0b0000011000011000, + 0b0000011000011000, + 0b0000011000011000, + 0b0000011100110000, + 0b0000011111100000, + 0b0000011000000000, + 0b0000011000000000, + 0b0000011000000000 + }, + // 113 q + { + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000011111100000, + 0b0000110011100000, + 0b0001100001100000, + 0b0001100001100000, + 0b0001100001100000, + 0b0001100001100000, + 0b0000110011100000, + 0b0000011111100000, + 0b0000000001100000, + 0b0000000001100000, + 0b0000000001100000 + }, + // 114 r + { + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000001011100000, + 0b0000001111000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000000000000000 + }, + // 115 s + { + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000011111000000, + 0b0000111001100000, + 0b0000110000100000, + 0b0000111100000000, + 0b0000011111000000, + 0b0000000111100000, + 0b0000000000110000, + 0b0000100000110000, + 0b0000111001110000, + 0b0000011111100000, + 0b0000000000000000 + }, + // 116 t + { + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000001000000000, + 0b0000011000000000, + 0b0000111110000000, + 0b0000011000000000, + 0b0000011000000000, + 0b0000011000000000, + 0b0000011000000000, + 0b0000011000000000, + 0b0000011000000000, + 0b0000011000000000, + 0b0000011100000000, + 0b0000001110000000, + 0b0000000000000000 + }, + // 117 u + { + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000110000110000, + 0b0000110000110000, + 0b0000110000110000, + 0b0000110000110000, + 0b0000110000110000, + 0b0000110000110000, + 0b0000110000110000, + 0b0000110000110000, + 0b0000011001110000, + 0b0000001111010000, + 0b0000000000000000 + }, + // 118 v + { + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0001100000110000, + 0b0001100000110000, + 0b0000110000110000, + 0b0000110001100000, + 0b0000011001100000, + 0b0000011001100000, + 0b0000011011000000, + 0b0000001111000000, + 0b0000001110000000, + 0b0000000110000000, + 0b0000000000000000 + }, + // 119 w + { + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0011000000011000, + 0b0011000000011000, + 0b0011000100011000, + 0b0011001110011000, + 0b0011001110011000, + 0b0011001010011000, + 0b0001111010110000, + 0b0001110011110000, + 0b0000110001100000, + 0b0000110001100000, + 0b0000000000000000 + }, + // 120 x + { + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000110000110000, + 0b0000111001110000, + 0b0000011101100000, + 0b0000001111000000, + 0b0000000110000000, + 0b0000001111000000, + 0b0000011101100000, + 0b0000111001110000, + 0b0000110000110000, + 0b0000000000000000 + }, + // 121 y + { + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000110000110000, + 0b0000011000100000, + 0b0000011001100000, + 0b0000001001100000, + 0b0000001101000000, + 0b0000000111000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000100000000, + 0b0000001100000000, + 0b0000111000000000 + }, + // 122 z + { + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000111111110000, + 0b0000000000110000, + 0b0000000001100000, + 0b0000000011000000, + 0b0000000110000000, + 0b0000001100000000, + 0b0000011000000000, + 0b0000110000000000, + 0b0000111111110000, + 0b0000000000000000 + }, + // 123 { + { + 0b0000000000000000, + 0b0000000111100000, + 0b0000001110000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000111000000000, + 0b0001110000000000, + 0b0000111000000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000001100000000, + 0b0000001110000000, + 0b0000000111100000, + 0b0000000000000000 + }, + // 124 | + { + 0b0000000000000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000110000000, + 0b0000000000000000 + }, + // 125 } + { + 0b0000000000000000, + 0b0000011110000000, + 0b0000000111000000, + 0b0000000011000000, + 0b0000000011000000, + 0b0000000011000000, + 0b0000000011000000, + 0b0000000001110000, + 0b0000000000111000, + 0b0000000001110000, + 0b0000000011000000, + 0b0000000011000000, + 0b0000000011000000, + 0b0000000111000000, + 0b0000011110000000, + 0b0000000000000000 + }, + // 126 ~ + { + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0001111110001000, + 0b0001000111111000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000 + }, + +}; diff --git a/source/kernel/gfx/gfx.c b/source/kernel/gfx/gfx.c index 98e84e57..0c7e8233 100644 --- a/source/kernel/gfx/gfx.c +++ b/source/kernel/gfx/gfx.c @@ -1,116 +1,116 @@ -// =================================================================== -// gfx.c - Graphics functions for drawing and such. -// =================================================================== -// This file is a part of the reduceOS C kernel. Please credit me if you use this code. - -#include "include/gfx.h" // Main header file - - - -// gfxDrawRect(int x1, int y1, int x2, int y2, uint32_t color, bool fill) - Draws a rectangle. -void gfxDrawRect(int x1, int y1, int x2, int y2, uint32_t color, bool fill) { - // Begin by drawing the first top and bottom lines. - if ((x2-x1) > 0) { - for (int i = x1; i < x2; i++) { - vbePutPixel(i, y1, color); - vbePutPixel(i, y2, color); - } - } else if ((x2-x1) < 0) { - for (int i = x2; i > x1; i--) { - vbePutPixel(i, y1, color); - vbePutPixel(i, y2, color); - } - } - - // Now, draw the left and right line. - if ((y2-y1) > 0) { - for (int i = y1; i < y2; i++) { - vbePutPixel(x1, i, color); - vbePutPixel(x2, i, color); - } - } else if ((y2-y1) < 0) { - for (int i = y2; i > y1; i--) { - vbePutPixel(x1, i, color); - vbePutPixel(x2, i, color); - } - } - - if (fill) { - if ((y2-y1) > 0) { - for (int y = y1; y < y2; y++) { - if ((x2-x1) > 0) { - for (int x = x1; x < x2; x++) { - vbePutPixel(x, y, color); - } - } else if ((x2-x1) < 0) { - for (int x = x2; x > x1; x--) { - vbePutPixel(x, y, color); - } - } - } - } else if ((y2-y1) < 0) { - for (int y = y2; y > y1; y--) { - if ((x2-x1) > 0) { - for (int x = x1; x < x2; x++) { - vbePutPixel(x, y, color); - } - } else if ((x2-x1) < 0) { - for (int x = x2; x > x1; x--) { - vbePutPixel(x, y, color); - } - } - } - } - } -} - - -// gfxDrawLine(int x1, int y1, int x2, int y2, uint32_t color) - Draw a line. -void gfxDrawLine(int x1, int y1, int x2, int y2, uint32_t color) { - // Determine direction to draw the line in. - int dx = (x1 < x2) ? 1 : -1; - int dy = (y1 < y2) ? 1 : -1; - - // Calculate the slope of the line. - int slope = (y2-y1) / (x2-x1); - - // Start drawing. - int x = x1; - int y = y1; - - if (slope < 1) { - int error = abs((x2-x1)/2); - - while (x != x2) { - vbePutPixel(x, y, color); - - x += dx; - error -= abs((y2-y1)); - if (error < 0) { - y += dy; - error += abs((x2-x1)); - } - } - } else if (slope > 1) { - int error = abs((y2-y1)/2); - - while (y != y2) { - vbePutPixel(x, y, color); - - y += dy; - error -= abs((x2-x1)); - if (error < 0) { - x += dx; - error += abs((y2-y1)); - } - } - } else if (slope == 1) { - while (x != x2 && y != y2) { - vbePutPixel(x, y, color); - - x += dx; - y += dy; - } - } -} - +// =================================================================== +// gfx.c - Graphics functions for drawing and such. +// =================================================================== +// This file is a part of the reduceOS C kernel. Please credit me if you use this code. + +#include // Main header file + + + +// gfxDrawRect(int x1, int y1, int x2, int y2, uint32_t color, bool fill) - Draws a rectangle. +void gfxDrawRect(int x1, int y1, int x2, int y2, uint32_t color, bool fill) { + // Begin by drawing the first top and bottom lines. + if ((x2-x1) > 0) { + for (int i = x1; i < x2; i++) { + vbePutPixel(i, y1, color); + vbePutPixel(i, y2, color); + } + } else if ((x2-x1) < 0) { + for (int i = x2; i > x1; i--) { + vbePutPixel(i, y1, color); + vbePutPixel(i, y2, color); + } + } + + // Now, draw the left and right line. + if ((y2-y1) > 0) { + for (int i = y1; i < y2; i++) { + vbePutPixel(x1, i, color); + vbePutPixel(x2, i, color); + } + } else if ((y2-y1) < 0) { + for (int i = y2; i > y1; i--) { + vbePutPixel(x1, i, color); + vbePutPixel(x2, i, color); + } + } + + if (fill) { + if ((y2-y1) > 0) { + for (int y = y1; y < y2; y++) { + if ((x2-x1) > 0) { + for (int x = x1; x < x2; x++) { + vbePutPixel(x, y, color); + } + } else if ((x2-x1) < 0) { + for (int x = x2; x > x1; x--) { + vbePutPixel(x, y, color); + } + } + } + } else if ((y2-y1) < 0) { + for (int y = y2; y > y1; y--) { + if ((x2-x1) > 0) { + for (int x = x1; x < x2; x++) { + vbePutPixel(x, y, color); + } + } else if ((x2-x1) < 0) { + for (int x = x2; x > x1; x--) { + vbePutPixel(x, y, color); + } + } + } + } + } +} + + +// gfxDrawLine(int x1, int y1, int x2, int y2, uint32_t color) - Draw a line. +void gfxDrawLine(int x1, int y1, int x2, int y2, uint32_t color) { + // Determine direction to draw the line in. + int dx = (x1 < x2) ? 1 : -1; + int dy = (y1 < y2) ? 1 : -1; + + // Calculate the slope of the line. + int slope = (y2-y1) / (x2-x1); + + // Start drawing. + int x = x1; + int y = y1; + + if (slope < 1) { + int error = abs((x2-x1)/2); + + while (x != x2) { + vbePutPixel(x, y, color); + + x += dx; + error -= abs((y2-y1)); + if (error < 0) { + y += dy; + error += abs((x2-x1)); + } + } + } else if (slope > 1) { + int error = abs((y2-y1)/2); + + while (y != y2) { + vbePutPixel(x, y, color); + + y += dy; + error -= abs((x2-x1)); + if (error < 0) { + x += dx; + error += abs((y2-y1)); + } + } + } else if (slope == 1) { + while (x != x2 && y != y2) { + vbePutPixel(x, y, color); + + x += dx; + y += dy; + } + } +} + diff --git a/source/kernel/gfx/terminal.c b/source/kernel/gfx/terminal.c index 04c96b11..2e92ede5 100644 --- a/source/kernel/gfx/terminal.c +++ b/source/kernel/gfx/terminal.c @@ -1,463 +1,463 @@ -// =================================================================== -// terminal.c - Handles all terminal functions for graphics -// =================================================================== -// This file is a part of the reduceOS C kernel. Please credit me if you use this code. - -#include "include/terminal.h" // This header file contains variable declarations as not to clutter up the actual C code. - -static char *shell = "\0"; // This will be used if we're handling typing - mainly used with backspace, to prevent deleting the prompt by accident. If this variable is \0, it will not be used. - - -// The terminal's mode is either VGA or VESA VBE. VESA VBE is currently using PSF functions (todo: implement a system wide font API to allow for changing between different fonts) -int vbeTerminalForeground, vbeTerminalBackground; -int terminalMode; // 0 signifies VGA mode, 1 signifies VESA VBE. -int vbeWidth, vbeHeight; - -// initTerminal() - Load the terminal, setup the buffers, reset the values, etc. -void initTerminal(void) { - if (!terminalMode) { - terminalX = 0, terminalY = 0; // Reset terminal X and Y - terminalColor = vgaColorEntry(COLOR_WHITE, COLOR_CYAN); // The terminal color will be white for the text and cyan for the BG on start. - terminalBuffer = VIDEO_MEM; // Initialize the terminal buffer as VIDEO_MEM (0xB8000) - - // Now we need to setup the screen by clearing it with ' '. - - for (size_t y = 0; y < SCREEN_HEIGHT; y++) { - for (size_t x = 0; x < SCREEN_WIDTH; x++) { - const size_t index = y * SCREEN_WIDTH + x; - terminalBuffer[index] = vgaEntry(' ', terminalColor); - } - } - } else { - // VBE reinit code goes here - terminalX = 0, terminalY = 0; // Reset X and Y - vbeTerminalForeground = COLOR_WHITE; - vbeTerminalBackground = COLOR_CYAN; - vbeWidth = modeWidth; - vbeHeight = modeHeight; - } -} - -// changeTerminalMode(int mode) - Changes the mode of the terminal, VGA or VBE. -void changeTerminalMode(int mode) { terminalMode = mode; initTerminal(); } - -// updateTerminalColor(uint8_t color) - Update the terminal color. Simple function. -// ! OBSOLETE AND TO BE REMOVED ! -void updateTerminalColor(uint8_t color) { terminalColor = color; } - -// updateTerminalColor_gfx(uint8_t fg, uint8_t bg) -void updateTerminalColor_gfx(uint8_t fg, uint8_t bg) { - vbeTerminalForeground = fg; - vbeTerminalBackground = bg; - terminalColor = vgaColorEntry(fg, bg); -} - - -// terminalPutcharXY(unsigned char c, uint8_t color, size_t x, size_t y) - Specific function to place a vgaEntry() at a specific point on the screen. -void terminalPutcharXY(unsigned char c, uint8_t color, size_t x, size_t y) { - const size_t index = y * SCREEN_WIDTH + x; // Same code as in initTerminal(). Calculate index to place char at and copy it. - terminalBuffer[index] = vgaEntry(c, color); -} - -// terminalGotoXY(size_t x, size_t y) - Changes the terminal position to X and Y -void terminalGotoXY(size_t x, size_t y) { - terminalX = x; - terminalY = y; -} - - -// This might seem bad, but it's actually not the worst. -extern uint32_t *framebuffer; -extern int psfGetFontHeight(); - -// scrollTerminal_vesa() - I wonder what this function does. -void scrollTerminal_vesa() { - if (terminalY >= modeHeight) { - - // Reading directly from vmem is very slow, but reading from our secondary buffer is not - for (int y = psfGetFontHeight(); y < modeHeight; y++) { - for (int x = 0; x < modeWidth; x++) { - vbePutPixel(x, y - psfGetFontHeight(), *(framebuffer + (y*1024 + x))); // Copy the pixels one line below to the current line. - } - } - - // Blank the bottom line. - for (int y = modeHeight-psfGetFontHeight(); y < modeHeight; y++) { - for (int x = 0; x < modeWidth; x++) { - vbePutPixel(x, y, VGA_TO_VBE(vbeTerminalBackground)); - } - } - - - // Update terminalY to the new position after scrolling - terminalY = modeHeight - psfGetFontHeight(); - } -} - - -// Unlike the alpha, this one has terminal scrolling! -// scrollTerminal() - Scrolls the terminal -void scrollTerminal() { - if (terminalMode == 1) { - scrollTerminal_vesa(); - return; - } - - uint16_t blank = 0x20 | (terminalColor << 8); - - if (terminalY >= SCREEN_HEIGHT) { - int i; - for (i = 0*SCREEN_WIDTH; i < (SCREEN_HEIGHT-1) * SCREEN_WIDTH; i++) { - terminalBuffer[i] = terminalBuffer[i+SCREEN_WIDTH]; - } - - for (int i = (SCREEN_HEIGHT - 1) * SCREEN_WIDTH; i < SCREEN_HEIGHT * SCREEN_WIDTH; i++) { - terminalBuffer[i] = blank; - } - - terminalY = SCREEN_HEIGHT - 1; - } -} - - -// terminalDeleteLastLine() - delete the last line of the terminal. Useful for scrolling. -void terminalDeleteLastLine() { - int x, *ptr; - - for (x = 0; x < SCREEN_WIDTH * 2; x++) { - ptr = VIDEO_MEM + (SCREEN_WIDTH * 2) * (SCREEN_HEIGHT - 1) + x; - *ptr = 0; - } -} - -void clearScreen_VESA(uint8_t fg, uint8_t bg) { - updateTerminalColor_gfx(fg, bg); - - terminalX = 0; - terminalY = 0; - - - for (size_t y = 0; y < vbeHeight; y++) { - for (size_t x = 0; x < vbeWidth; x++) { - // bad code fix later - vbePutPixel(x, y, VGA_TO_VBE(vbeTerminalBackground)); - } - } - vbeSwitchBuffers(); - - terminalX = 0; - terminalY = 0; -} - -// clearScreen(uint8_t fg, uint8_t bg) - clears the screen -void clearScreen(uint8_t fg, uint8_t bg) { - - if (terminalMode) { - clearScreen_VESA(fg, bg); - return; - } - - terminalColor = vgaColorEntry(fg, bg); - - for (size_t y = 0; y < SCREEN_HEIGHT; y++) { - for (size_t x = 0; x < SCREEN_WIDTH; x++) { - terminalPutcharXY(' ', terminalColor, x, y); // Reset all characters to be ' '. Obviously initTerminal() already does this, but we want to reimplement it without all the setup stuff. - } - } - - terminalX = 0; // Reset X & Y values - terminalY = 0; - return; -} - -// updateTextCursor() - Updates the text mode cursor to whatever terminalX and terminalY are. -void updateTextCursor() { - uint16_t pos = terminalY * SCREEN_WIDTH + terminalX; - - outportb(0x3D4, 14); - outportb(0x3D5, pos >> 8); - outportb(0x3D4, 15); - outportb(0x3D5, pos); -} - - -// updateTextCursor_vesa() - Does the same thing but in VESA (aka much more complex) - event in PIT IRQ - - -static bool cursorEnabled = true; -static int blinkTime = 0; // Time since last blink (~500ms) -static int blinkedLast = 0; // Did it blink last time? Do we need to clear/draw it? -void updateTextCursor_vesa() { - - if (!cursorEnabled) return; - - // This function is called by pitTicks on a reasonable level - if (blinkTime > 500) { - if (blinkedLast) { - for (int x = terminalX; x < terminalX + psfGetFontWidth(); x++) { - vbePutPixel(x, terminalY + psfGetFontHeight() - 2, VGA_TO_VBE(vbeTerminalBackground)); - } - blinkedLast = 0; - } else { - for (int x = terminalX; x < terminalX + psfGetFontWidth(); x++) { - vbePutPixel(x, terminalY + psfGetFontHeight() - 2, VGA_TO_VBE(vbeTerminalForeground)); - } - blinkedLast = 1; - } - - vbeSwitchBuffers(); - blinkTime = 0; - } else { - blinkTime++; - } -} - - - -// When a character is typed, we want the cursor to follow it. -static void redrawTextCursor_vesa() { - - if (!cursorEnabled) return; - - if (blinkedLast) { - blinkTime = 0; - for (int x = terminalX; x < terminalX + psfGetFontWidth(); x++) { - vbePutPixel(x, terminalY + psfGetFontHeight() - 2, VGA_TO_VBE(vbeTerminalForeground)); - } - } -} - -// If a newline is typed, remove the text cursor if it existed. -static void clearTextCursor_vesa() { - - if (!cursorEnabled) return; - - if (blinkedLast) { - for (int x = terminalX; x < terminalX + psfGetFontWidth(); x++) { - vbePutPixel(x, terminalY + psfGetFontHeight() - 2, VGA_TO_VBE(vbeTerminalBackground)); - } - } -} - -void setCursorEnabled(bool enabled) { - cursorEnabled = enabled; -} - -// No function description. Proprietary function used only by keyboard driver. -void terminalMoveArrowKeys(int arrowKey) { - if (arrowKey == 0 && terminalX != 0) { - terminalGotoXY(terminalX - 1, terminalY); - } else if (arrowKey == 1 && terminalX != SCREEN_WIDTH) { - terminalGotoXY(terminalX + 1, terminalY); - } -} - - -// terminalPutchar(char c) - This is the recommended function to use (besides printf, that'll be later) as it incorporates scrollTerminal and terminalDeleteLastLine. -void terminalPutchar(char c) { - if (terminalMode == 1) { - terminalPutcharVESA(c); - return; - } - int line; - unsigned char uc = c; // terminalPutcharXY() requires an unsigned char. - - // Perform the scrolling stuff for X - if (terminalX == SCREEN_WIDTH) { - terminalX = 0; - terminalY++; - } - - // Perform the scrolling stuff for Y - scrollTerminal(); - - - // Checking if c is a special character or not. - if (c == '\n') { - terminalY++; // Increment terminal Y - terminalX = 0; - - } else if (c == '\b') { - terminalBackspace(); // Handle backspace - } else if (c == '\0') { - // do nothing - } else if (c == '\t') { - for (int i = 0; i < 4; i++) { - terminalPutchar(' '); - } - } else if (c == '\r') { - terminalX = 0; - } else { - terminalPutcharXY(uc, terminalColor, terminalX, terminalY); // Place an entry at terminal X and Y. - terminalX++; - } - - - - - // Update text mode cursor - updateTextCursor(); -} - -// terminalPutcharVESA(char c) - VESA VBE putchar method (using PSF as of now) -// Note: Don't call this directly! vbeSwitchBuffers is not called, could result in issues and annoyances later. -void terminalPutcharVESA(char c) { - int line; - unsigned char uc = c; - - - - if (c == '\n') { - clearTextCursor_vesa(); // Clear the text cursor. - terminalY = terminalY + psfGetFontHeight(); - terminalX = 0; - } else if (c == '\b') { - clearTextCursor_vesa(); // Clear the text cursor. - terminalBackspaceVESA(); - } else if (c == '\0') { - // Do nothing - } else if (c == '\t') { - for (int i = 0; i < 4; i++) { - terminalPutcharVESA(' '); - } - } else if (c == '\r') { - terminalX = 0; - } else { - psfDrawChar(c, terminalX, terminalY, VGA_TO_VBE(vbeTerminalForeground), VGA_TO_VBE(vbeTerminalBackground)); - terminalX = terminalX + psfGetFontWidth(); - } - - if (terminalX == vbeWidth) { - terminalY = terminalY + psfGetFontHeight(); - terminalX = 0; - } - - scrollTerminal_vesa(); -} - -// terminalWrite(const char *data, size_t size) - Writes a certain amount of data to the terminal. -void terminalWrite(const char *data, size_t size) { - for (size_t i = 0; i < size; i++) { - terminalPutchar(data[i]); - } - - // printf() will handle the terminalPutchar -} - - -// terminalWriteString() - The exact same as terminal write, but shorter with no len option (we use strlen). Not recommended for use, use printf (further down in the file)! -void terminalWriteString(const char *data) { terminalWrite(data, strlen(data)); } - -// terminalBackspace() - Removes the last character outputted. -void terminalBackspace() { - if (terminalX == 0) return; // terminalX being 0 would cause a lot of problems. - if (terminalX <= strlen(shell) && shell != "\0") return; // Cannot overwrite the shell. - // First, go back one character. - terminalGotoXY(terminalX-1, terminalY); - - // Then, write a space where the character is. - terminalPutchar(' '); - - // Finally, set terminalX to one below current. - terminalGotoXY(terminalX-1, terminalY); -} - -// terminalBackspaceVESA() - Removes the last character outputted (VBE mode) -void terminalBackspaceVESA() { - if (terminalX < psfGetFontWidth()) return; - if (terminalX <= strlen(shell)*psfGetFontWidth() && shell != "\0") return; // Cannot overwrite shell - - // Go back one character. - terminalX = terminalX - psfGetFontWidth(); - - // Then, write a space where the character is. - terminalPutcharVESA(' '); - - // Set terminalX to one behind current. - terminalX = terminalX - psfGetFontWidth(); -} - - -void terminalWriteStringXY(const char *data, size_t x, size_t y) { - size_t previousX = terminalX; // Store terminalX and terminalY in temporary variables - size_t previousY = terminalY; - - terminalX = x; // Update terminalX & terminalY - terminalY = y; - - terminalWriteString(data); // Write the string to the X & Y. - - terminalX = previousX; // Restore terminalX & terminalY to their previous values. - terminalY = previousY; -} - -// updateBottomText() - A kernel function to make handling the beginning graphics easier. -void updateBottomText(char *bottomText) { - if (strlen(bottomText) > INT_MAX) return -1; // Overflow - - updateTerminalColor(vgaColorEntry(COLOR_BLACK, COLOR_LIGHT_GRAY)); - - for (int i = 0; i < SCREEN_WIDTH; i++) terminalPutcharXY(' ', vgaColorEntry(COLOR_BLACK, COLOR_LIGHT_GRAY), i, SCREEN_HEIGHT - 1); - terminalWriteStringXY(bottomText, 0, SCREEN_HEIGHT - 1); - - - updateTerminalColor(vgaColorEntry(COLOR_WHITE, COLOR_CYAN)); - return; -} - -// enableShell() - Enables a boundary that cannot be overwritten. -void enableShell(char *shellToUse) { shell = shellToUse; } - -// updateShell() - Updates the shell with the CWD. -void updateShell() { - kfree(shell); - shell = kmalloc(strlen("reduceOS > ") + strlen(get_cwd())); - strcpy(shell, "reduceOS "); - strcpy(shell + strlen("reduceOS "), get_cwd()); - strcpy(shell + strlen("reduceOS ") + strlen(get_cwd()), "> "); -} - -// getShell() - Returns the current shell -char *getShell() { return shell; } - -// instantUpdateTerminalColor(uint8_t fg, uint8_t bg) - Instantly update the terminal color (VESA only) -void instantUpdateTerminalColor(uint8_t fg, uint8_t bg) { - if (terminalMode != 1) return; // VESA only - - // NOTE: Function breaks if it tries to update a section where fg and bg are the same. - // The way we do this is to iterate over the entire thing two times - once to update bg, once to update fg. - - for (int y = 0; y < modeHeight; y++) { - for (int x = 0; x < modeWidth; x++) { - if (vbeGetPixel(x, y) == VGA_TO_VBE(vbeTerminalBackground)) { - vbePutPixel(x, y, VGA_TO_VBE(bg)); - } - } - } - - for (int y = 0; y < modeHeight; y++) { - for (int x = 0; x < modeWidth; x++) { - if (vbeGetPixel(x, y) == VGA_TO_VBE(vbeTerminalForeground)) { - vbePutPixel(x, y, VGA_TO_VBE(fg)); - } - } - } - - vbeTerminalBackground = bg; - vbeTerminalForeground = fg; - - vbeSwitchBuffers(); -} - -static bool updateScreen = true; - -// terminalSetUpdateScreen(bool state) - Toggles whether the screen should update when terminalUpdateScreen() is called. Useful for long printfs -void terminalSetUpdateScreen(bool state) { - updateScreen = state; -} - -// terminalUpdateScreen() - Update the buffers on the screen -void terminalUpdateScreen() { - if (terminalMode == 1 && updateScreen) vbeSwitchBuffers(); -} - +// =================================================================== +// terminal.c - Handles all terminal functions for graphics +// =================================================================== +// This file is a part of the reduceOS C kernel. Please credit me if you use this code. + +#include // This header file contains variable declarations as not to clutter up the actual C code. + +static char *shell = "\0"; // This will be used if we're handling typing - mainly used with backspace, to prevent deleting the prompt by accident. If this variable is \0, it will not be used. + + +// The terminal's mode is either VGA or VESA VBE. VESA VBE is currently using PSF functions (todo: implement a system wide font API to allow for changing between different fonts) +int vbeTerminalForeground, vbeTerminalBackground; +int terminalMode; // 0 signifies VGA mode, 1 signifies VESA VBE. +int vbeWidth, vbeHeight; + +// initTerminal() - Load the terminal, setup the buffers, reset the values, etc. +void initTerminal(void) { + if (!terminalMode) { + terminalX = 0, terminalY = 0; // Reset terminal X and Y + terminalColor = vgaColorEntry(COLOR_WHITE, COLOR_CYAN); // The terminal color will be white for the text and cyan for the BG on start. + terminalBuffer = VIDEO_MEM; // Initialize the terminal buffer as VIDEO_MEM (0xB8000) + + // Now we need to setup the screen by clearing it with ' '. + + for (size_t y = 0; y < SCREEN_HEIGHT; y++) { + for (size_t x = 0; x < SCREEN_WIDTH; x++) { + const size_t index = y * SCREEN_WIDTH + x; + terminalBuffer[index] = vgaEntry(' ', terminalColor); + } + } + } else { + // VBE reinit code goes here + terminalX = 0, terminalY = 0; // Reset X and Y + vbeTerminalForeground = COLOR_WHITE; + vbeTerminalBackground = COLOR_CYAN; + vbeWidth = modeWidth; + vbeHeight = modeHeight; + } +} + +// changeTerminalMode(int mode) - Changes the mode of the terminal, VGA or VBE. +void changeTerminalMode(int mode) { terminalMode = mode; initTerminal(); } + +// updateTerminalColor(uint8_t color) - Update the terminal color. Simple function. +// ! OBSOLETE AND TO BE REMOVED ! +void updateTerminalColor(uint8_t color) { terminalColor = color; } + +// updateTerminalColor_gfx(uint8_t fg, uint8_t bg) +void updateTerminalColor_gfx(uint8_t fg, uint8_t bg) { + vbeTerminalForeground = fg; + vbeTerminalBackground = bg; + terminalColor = vgaColorEntry(fg, bg); +} + + +// terminalPutcharXY(unsigned char c, uint8_t color, size_t x, size_t y) - Specific function to place a vgaEntry() at a specific point on the screen. +void terminalPutcharXY(unsigned char c, uint8_t color, size_t x, size_t y) { + const size_t index = y * SCREEN_WIDTH + x; // Same code as in initTerminal(). Calculate index to place char at and copy it. + terminalBuffer[index] = vgaEntry(c, color); +} + +// terminalGotoXY(size_t x, size_t y) - Changes the terminal position to X and Y +void terminalGotoXY(size_t x, size_t y) { + terminalX = x; + terminalY = y; +} + + +// This might seem bad, but it's actually not the worst. +extern uint32_t *framebuffer; +extern int psfGetFontHeight(); + +// scrollTerminal_vesa() - I wonder what this function does. +void scrollTerminal_vesa() { + if (terminalY >= modeHeight) { + + // Reading directly from vmem is very slow, but reading from our secondary buffer is not + for (int y = psfGetFontHeight(); y < modeHeight; y++) { + for (int x = 0; x < modeWidth; x++) { + vbePutPixel(x, y - psfGetFontHeight(), *(framebuffer + (y*1024 + x))); // Copy the pixels one line below to the current line. + } + } + + // Blank the bottom line. + for (int y = modeHeight-psfGetFontHeight(); y < modeHeight; y++) { + for (int x = 0; x < modeWidth; x++) { + vbePutPixel(x, y, VGA_TO_VBE(vbeTerminalBackground)); + } + } + + + // Update terminalY to the new position after scrolling + terminalY = modeHeight - psfGetFontHeight(); + } +} + + +// Unlike the alpha, this one has terminal scrolling! +// scrollTerminal() - Scrolls the terminal +void scrollTerminal() { + if (terminalMode == 1) { + scrollTerminal_vesa(); + return; + } + + uint16_t blank = 0x20 | (terminalColor << 8); + + if (terminalY >= SCREEN_HEIGHT) { + int i; + for (i = 0*SCREEN_WIDTH; i < (SCREEN_HEIGHT-1) * SCREEN_WIDTH; i++) { + terminalBuffer[i] = terminalBuffer[i+SCREEN_WIDTH]; + } + + for (int i = (SCREEN_HEIGHT - 1) * SCREEN_WIDTH; i < SCREEN_HEIGHT * SCREEN_WIDTH; i++) { + terminalBuffer[i] = blank; + } + + terminalY = SCREEN_HEIGHT - 1; + } +} + + +// terminalDeleteLastLine() - delete the last line of the terminal. Useful for scrolling. +void terminalDeleteLastLine() { + int x, *ptr; + + for (x = 0; x < SCREEN_WIDTH * 2; x++) { + ptr = VIDEO_MEM + (SCREEN_WIDTH * 2) * (SCREEN_HEIGHT - 1) + x; + *ptr = 0; + } +} + +void clearScreen_VESA(uint8_t fg, uint8_t bg) { + updateTerminalColor_gfx(fg, bg); + + terminalX = 0; + terminalY = 0; + + + for (size_t y = 0; y < vbeHeight; y++) { + for (size_t x = 0; x < vbeWidth; x++) { + // bad code fix later + vbePutPixel(x, y, VGA_TO_VBE(vbeTerminalBackground)); + } + } + vbeSwitchBuffers(); + + terminalX = 0; + terminalY = 0; +} + +// clearScreen(uint8_t fg, uint8_t bg) - clears the screen +void clearScreen(uint8_t fg, uint8_t bg) { + + if (terminalMode) { + clearScreen_VESA(fg, bg); + return; + } + + terminalColor = vgaColorEntry(fg, bg); + + for (size_t y = 0; y < SCREEN_HEIGHT; y++) { + for (size_t x = 0; x < SCREEN_WIDTH; x++) { + terminalPutcharXY(' ', terminalColor, x, y); // Reset all characters to be ' '. Obviously initTerminal() already does this, but we want to reimplement it without all the setup stuff. + } + } + + terminalX = 0; // Reset X & Y values + terminalY = 0; + return; +} + +// updateTextCursor() - Updates the text mode cursor to whatever terminalX and terminalY are. +void updateTextCursor() { + uint16_t pos = terminalY * SCREEN_WIDTH + terminalX; + + outportb(0x3D4, 14); + outportb(0x3D5, pos >> 8); + outportb(0x3D4, 15); + outportb(0x3D5, pos); +} + + +// updateTextCursor_vesa() - Does the same thing but in VESA (aka much more complex) - event in PIT IRQ + + +static bool cursorEnabled = true; +static int blinkTime = 0; // Time since last blink (~500ms) +static int blinkedLast = 0; // Did it blink last time? Do we need to clear/draw it? +void updateTextCursor_vesa() { + + if (!cursorEnabled) return; + + // This function is called by pitTicks on a reasonable level + if (blinkTime > 500) { + if (blinkedLast) { + for (int x = terminalX; x < terminalX + psfGetFontWidth(); x++) { + vbePutPixel(x, terminalY + psfGetFontHeight() - 2, VGA_TO_VBE(vbeTerminalBackground)); + } + blinkedLast = 0; + } else { + for (int x = terminalX; x < terminalX + psfGetFontWidth(); x++) { + vbePutPixel(x, terminalY + psfGetFontHeight() - 2, VGA_TO_VBE(vbeTerminalForeground)); + } + blinkedLast = 1; + } + + vbeSwitchBuffers(); + blinkTime = 0; + } else { + blinkTime++; + } +} + + + +// When a character is typed, we want the cursor to follow it. +static void redrawTextCursor_vesa() { + + if (!cursorEnabled) return; + + if (blinkedLast) { + blinkTime = 0; + for (int x = terminalX; x < terminalX + psfGetFontWidth(); x++) { + vbePutPixel(x, terminalY + psfGetFontHeight() - 2, VGA_TO_VBE(vbeTerminalForeground)); + } + } +} + +// If a newline is typed, remove the text cursor if it existed. +static void clearTextCursor_vesa() { + + if (!cursorEnabled) return; + + if (blinkedLast) { + for (int x = terminalX; x < terminalX + psfGetFontWidth(); x++) { + vbePutPixel(x, terminalY + psfGetFontHeight() - 2, VGA_TO_VBE(vbeTerminalBackground)); + } + } +} + +void setCursorEnabled(bool enabled) { + cursorEnabled = enabled; +} + +// No function description. Proprietary function used only by keyboard driver. +void terminalMoveArrowKeys(int arrowKey) { + if (arrowKey == 0 && terminalX != 0) { + terminalGotoXY(terminalX - 1, terminalY); + } else if (arrowKey == 1 && terminalX != SCREEN_WIDTH) { + terminalGotoXY(terminalX + 1, terminalY); + } +} + + +// terminalPutchar(char c) - This is the recommended function to use (besides printf, that'll be later) as it incorporates scrollTerminal and terminalDeleteLastLine. +void terminalPutchar(char c) { + if (terminalMode == 1) { + terminalPutcharVESA(c); + return; + } + int line; + unsigned char uc = c; // terminalPutcharXY() requires an unsigned char. + + // Perform the scrolling stuff for X + if (terminalX == SCREEN_WIDTH) { + terminalX = 0; + terminalY++; + } + + // Perform the scrolling stuff for Y + scrollTerminal(); + + + // Checking if c is a special character or not. + if (c == '\n') { + terminalY++; // Increment terminal Y + terminalX = 0; + + } else if (c == '\b') { + terminalBackspace(); // Handle backspace + } else if (c == '\0') { + // do nothing + } else if (c == '\t') { + for (int i = 0; i < 4; i++) { + terminalPutchar(' '); + } + } else if (c == '\r') { + terminalX = 0; + } else { + terminalPutcharXY(uc, terminalColor, terminalX, terminalY); // Place an entry at terminal X and Y. + terminalX++; + } + + + + + // Update text mode cursor + updateTextCursor(); +} + +// terminalPutcharVESA(char c) - VESA VBE putchar method (using PSF as of now) +// Note: Don't call this directly! vbeSwitchBuffers is not called, could result in issues and annoyances later. +void terminalPutcharVESA(char c) { + int line; + unsigned char uc = c; + + + + if (c == '\n') { + clearTextCursor_vesa(); // Clear the text cursor. + terminalY = terminalY + psfGetFontHeight(); + terminalX = 0; + } else if (c == '\b') { + clearTextCursor_vesa(); // Clear the text cursor. + terminalBackspaceVESA(); + } else if (c == '\0') { + // Do nothing + } else if (c == '\t') { + for (int i = 0; i < 4; i++) { + terminalPutcharVESA(' '); + } + } else if (c == '\r') { + terminalX = 0; + } else { + psfDrawChar(c, terminalX, terminalY, VGA_TO_VBE(vbeTerminalForeground), VGA_TO_VBE(vbeTerminalBackground)); + terminalX = terminalX + psfGetFontWidth(); + } + + if (terminalX == vbeWidth) { + terminalY = terminalY + psfGetFontHeight(); + terminalX = 0; + } + + scrollTerminal_vesa(); +} + +// terminalWrite(const char *data, size_t size) - Writes a certain amount of data to the terminal. +void terminalWrite(const char *data, size_t size) { + for (size_t i = 0; i < size; i++) { + terminalPutchar(data[i]); + } + + // printf() will handle the terminalPutchar +} + + +// terminalWriteString() - The exact same as terminal write, but shorter with no len option (we use strlen). Not recommended for use, use printf (further down in the file)! +void terminalWriteString(const char *data) { terminalWrite(data, strlen(data)); } + +// terminalBackspace() - Removes the last character outputted. +void terminalBackspace() { + if (terminalX == 0) return; // terminalX being 0 would cause a lot of problems. + if (terminalX <= strlen(shell) && shell != "\0") return; // Cannot overwrite the shell. + // First, go back one character. + terminalGotoXY(terminalX-1, terminalY); + + // Then, write a space where the character is. + terminalPutchar(' '); + + // Finally, set terminalX to one below current. + terminalGotoXY(terminalX-1, terminalY); +} + +// terminalBackspaceVESA() - Removes the last character outputted (VBE mode) +void terminalBackspaceVESA() { + if (terminalX < psfGetFontWidth()) return; + if (terminalX <= strlen(shell)*psfGetFontWidth() && shell != "\0") return; // Cannot overwrite shell + + // Go back one character. + terminalX = terminalX - psfGetFontWidth(); + + // Then, write a space where the character is. + terminalPutcharVESA(' '); + + // Set terminalX to one behind current. + terminalX = terminalX - psfGetFontWidth(); +} + + +void terminalWriteStringXY(const char *data, size_t x, size_t y) { + size_t previousX = terminalX; // Store terminalX and terminalY in temporary variables + size_t previousY = terminalY; + + terminalX = x; // Update terminalX & terminalY + terminalY = y; + + terminalWriteString(data); // Write the string to the X & Y. + + terminalX = previousX; // Restore terminalX & terminalY to their previous values. + terminalY = previousY; +} + +// updateBottomText() - A kernel function to make handling the beginning graphics easier. +void updateBottomText(char *bottomText) { + if (strlen(bottomText) > INT_MAX) return -1; // Overflow + + updateTerminalColor(vgaColorEntry(COLOR_BLACK, COLOR_LIGHT_GRAY)); + + for (int i = 0; i < SCREEN_WIDTH; i++) terminalPutcharXY(' ', vgaColorEntry(COLOR_BLACK, COLOR_LIGHT_GRAY), i, SCREEN_HEIGHT - 1); + terminalWriteStringXY(bottomText, 0, SCREEN_HEIGHT - 1); + + + updateTerminalColor(vgaColorEntry(COLOR_WHITE, COLOR_CYAN)); + return; +} + +// enableShell() - Enables a boundary that cannot be overwritten. +void enableShell(char *shellToUse) { shell = shellToUse; } + +// updateShell() - Updates the shell with the CWD. +void updateShell() { + kfree(shell); + shell = kmalloc(strlen("reduceOS > ") + strlen(get_cwd())); + strcpy(shell, "reduceOS "); + strcpy(shell + strlen("reduceOS "), get_cwd()); + strcpy(shell + strlen("reduceOS ") + strlen(get_cwd()), "> "); +} + +// getShell() - Returns the current shell +char *getShell() { return shell; } + +// instantUpdateTerminalColor(uint8_t fg, uint8_t bg) - Instantly update the terminal color (VESA only) +void instantUpdateTerminalColor(uint8_t fg, uint8_t bg) { + if (terminalMode != 1) return; // VESA only + + // NOTE: Function breaks if it tries to update a section where fg and bg are the same. + // The way we do this is to iterate over the entire thing two times - once to update bg, once to update fg. + + for (int y = 0; y < modeHeight; y++) { + for (int x = 0; x < modeWidth; x++) { + if (vbeGetPixel(x, y) == VGA_TO_VBE(vbeTerminalBackground)) { + vbePutPixel(x, y, VGA_TO_VBE(bg)); + } + } + } + + for (int y = 0; y < modeHeight; y++) { + for (int x = 0; x < modeWidth; x++) { + if (vbeGetPixel(x, y) == VGA_TO_VBE(vbeTerminalForeground)) { + vbePutPixel(x, y, VGA_TO_VBE(fg)); + } + } + } + + vbeTerminalBackground = bg; + vbeTerminalForeground = fg; + + vbeSwitchBuffers(); +} + +static bool updateScreen = true; + +// terminalSetUpdateScreen(bool state) - Toggles whether the screen should update when terminalUpdateScreen() is called. Useful for long printfs +void terminalSetUpdateScreen(bool state) { + updateScreen = state; +} + +// terminalUpdateScreen() - Update the buffers on the screen +void terminalUpdateScreen() { + if (terminalMode == 1 && updateScreen) vbeSwitchBuffers(); +} + diff --git a/source/kernel/gfx/vesa.c b/source/kernel/gfx/vesa.c index dd8073d7..9417e84e 100644 --- a/source/kernel/gfx/vesa.c +++ b/source/kernel/gfx/vesa.c @@ -1,283 +1,283 @@ -// ========================================================== -// vesa.c - VESA VBE graphics handler -// ========================================================== -// This file is a part of the reduceOS C kernel. Please credit me if you use this code. - -// VESA VBE is a type of graphics "mode", like VGA -// However, VESA VBE is different from VGA in the fact that it has its own "modes" -// These modes can correspond to different resolutions and colordepths -// For more information, see https://wiki.osdev.org/Drawing_In_a_Linear_Framebuffer - -#include "include/vesa.h" // Main header file - -// Variables - -vbeInfoBlock_t vbeInfo; -bool isVBESupported = false; - -uint32_t *vbeBuffer; // This is the buffer we will be drawing in -int selectedMode = -1; // The current mode selected. -uint32_t modeWidth, modeHeight, modeBpp = 0; // The height and width of the mode - -uint32_t *framebuffer; // A seperate framebuffer. -bool framebuffer_initialized = false; - -// Double buffering is utilized in this VBE driver. Basically, that means that instead of drawing directly to video memory, you draw to a framebuffer (the one above). -// For now we use manual swapping, but potentially later PIT will swap each tick. - - -// Static functions - -// (static) vbeGetInfo() - Gets VBE information. -static void vbeGetInfo() { - // Set up the registers for our INT 0x10 call. - REGISTERS_16 in, out = {0}; - in.ax = 0x4F00; - in.di = 0x7E00; - - // Call the BIOS for our interrupt. - bios32_call(0x10, &in, &out); - - if (out.ax != 0x004F) { - panic("VBE", "vbeGetModeInfo", "BIOS 0x10 call failed"); - } - - // Copy the data to vbeInfo. - memcpy(&vbeInfo, (void*)0x7E00, sizeof(vbeInfoBlock_t)); - - // Change supported variable. - isVBESupported = (out.ax == 0x4F); -} - - -// (static) vbeGetModeInfo(uint16_t mode) - Returns information on a certain mode. -static vbeModeInfo_t vbeGetModeInfo(uint16_t mode) { - // Like before, setup the registers for our INT 0x10 call. - // This time, however, change AX to be 0x4F01 to signify that we want mode info. - vbeModeInfo_t modeInfo; - - REGISTERS_16 in = {0}; - in.ax = 0x4F01; - in.cx = mode; - in.di = 0x7E00 + 1024; - - REGISTERS_16 out = {0}; - - // Call the BIOS for our interrupt. - bios32_call(0x10, &in, &out); - - if (out.ax != 0x004F) { - panic("VBE", "vbeGetModeInfo", "BIOS 0x10 call failed"); - } - - // Copy the data. - memcpy(&modeInfo, (void*)0x7E00 + 1024, sizeof(vbeModeInfo_t)); - return modeInfo; -} - -// DEBUG FUNCTION!! -void vesaPrintModes() { - uint16_t *modes = (uint16_t*)vbeInfo.videoModePtr; - uint16_t currentMode = *modes++; - - vbeModeInfo_t modeInfo; - - // Possible bug here - we are supposed to stop on currentMode being 0xFFFF, but this crashes a lot until it randomly works - unsure if bug with code or QEMU?? - // For now just choose the best resolution we can use without crashing the entire system. - for (int i = 0; i < 10; i++) { - modeInfo = vbeGetModeInfo(currentMode); - serialPrintf("Found mode %d - %d x %d with colordepth %d (mode is 0x%x)\n", currentMode, modeInfo.width, modeInfo.height, modeInfo.bpp, currentMode); - currentMode = *modes++; - } -} - - - - - -// Functions (non-static) - -// vbeSetMode(uint32_t mode) - Sets a VBE mode using BIOS32 -void vbeSetMode(uint32_t mode) { - // Like all BIOS32 calls, setup the registers first. - REGISTERS_16 in = {0}; - in.ax = 0x4F02; - in.bx = mode; - - REGISTERS_16 out = {0}; - - // Call BIOS interrupt 0x10. - bios32_call(0x10, &in, &out); - - if (out.ax != 0x004F) { - panic("VBE", "vbeGetModeInfo", "BIOS 0x10 call failed"); - } -} - -// vbeGetMode(uint32_t width, uint32_t height, uint32_t color_depth) - Returns the VBE mode with the parameters given. -uint32_t vbeGetMode(uint32_t width, uint32_t height, uint32_t color_depth) { - // First, get the mode list from the VBE video mode pointer. - uint16_t *modes = (uint16_t*)vbeInfo.videoModePtr; - uint16_t currentMode = *modes++; - - // This function has a potential bug, check vesaPrintModes() for the bug description. - - // Locate the mode. - while (currentMode != 0xFFFF) { - // Get the mode info and compare it against the parameters. - vbeModeInfo_t modeInfo = vbeGetModeInfo(currentMode); - - if (modeInfo.width == width && modeInfo.height == height && modeInfo.bpp == color_depth) { - return currentMode; // Found the mode! - } - - currentMode = *modes++; // Keep searching! - } - - return -1; // We didn't find the mode :( -} - - - -// Helper function to convert to a VBE RGB value. -uint32_t RGB_VBE(uint8_t r, uint8_t g, uint8_t b) { - uint32_t color = r; - color <<= 16; - color |= (g << 8); - color |= b; - return color; -} - -uint32_t VGA_TO_VBE(uint8_t vgaColor) { - switch (vgaColor) { - case COLOR_BLACK: - return RGB_VBE(0, 0, 0); - case COLOR_WHITE: - return RGB_VBE(255, 255, 255); - case COLOR_BLUE: - return RGB_VBE(0, 0, 170); - case COLOR_GREEN: - return RGB_VBE(0, 170, 0); - case COLOR_CYAN: - return RGB_VBE(0, 170, 170); - case COLOR_RED: - return RGB_VBE(170, 0, 0); - case COLOR_MAGENTA: - return RGB_VBE(170, 0, 170); - case COLOR_BROWN: - return RGB_VBE(170, 85, 0); - case COLOR_LIGHT_GRAY: - return RGB_VBE(170, 170, 170); // why did we do gray as light gray - case COLOR_DARK_GRAY: - return RGB_VBE(85, 85, 85); - case COLOR_LIGHT_BLUE: - return RGB_VBE(85, 85, 255); - case COLOR_LIGHT_GREEN: - return RGB_VBE(85, 85, 255); - case COLOR_LIGHT_CYAN: - return RGB_VBE(85, 255, 255); - case COLOR_LIGHT_RED: - return RGB_VBE(255, 85, 85); - case COLOR_LIGHT_MAGENTA: - return RGB_VBE(255, 85, 255); - case COLOR_YELLOW: - return RGB_VBE(255, 255, 85); - default: - serialPrintf("VGA_TO_VBE: stupid users (color = %i)\n", vgaColor); - return; - } - // lmao -} - - -// vesaInit() - Initializes VESA VBE. -void vesaInit() { - - // First, get VBE info and check if supported. - vbeGetInfo(); - - if (!isVBESupported) { - serialPrintf("vesaInit: VBE is not supported.\n"); - return; - } - - // There is a bug preventing us from checking some video modes - check vesaPrintModes() for the bug description. - // For now, just use 1024x768 with colordepth 32 - - // uint32_t mode = vbeGetMode(800, 600, 32); - // if (mode == -1) return; // No valid mode was found. - - - // Bypass getting the mode and just set it like so. - uint32_t mode = 0x144 | 0x4000; - - // Get a bit more information on the mode. - vbeModeInfo_t modeInfo = vbeGetModeInfo(mode); - - // Identity map framebuffer! - vmm_allocateRegion(modeInfo.framebuffer, modeInfo.framebuffer, 1024*768*4); - - // Make sure PMM knows not to allocate here - pmm_deinitRegion(modeInfo.framebuffer, 1024*768); - - // Change variables to reflect on modeInfo. - selectedMode = mode; - modeWidth = modeInfo.width; - modeHeight = modeInfo.height; - modeBpp = modeInfo.bpp; - vbeBuffer = (uint32_t*)modeInfo.framebuffer; - - - // Now, switch the mode. - vbeSetMode(mode); - - extern uint32_t bss_end; - extern uint32_t text_start; - - framebuffer = kmalloc(1024*768*4); - serialPrintf("vesaInit: Allocated framebuffer to 0x%x - 0x%x\n", framebuffer, (int)framebuffer + (1024*768*4)); - - // Because framebuffer is big and stupid pmm will get confused and try to still allocate memory INSIDE of it - // So we need to fix that by telling PMM to go pound sand and deinitialize the region - pmm_deinitRegion(framebuffer, 1024*768*4); - - /* This code is to stop liballoc from screwing absolutely everything up. It is not required! */ - ASSERT(!(framebuffer < &bss_end), "vesaInit", "Invalid framebuffer (in kernelspace)"); - ASSERT(!(framebuffer <= &text_start), "vesaInit", "Invalid framebuffer (before kernelspace)"); - - /* This is also not required. */ - framebuffer_initialized = true; -} - - - -// vbeSwitchBuffers() - Switches the framebuffers -int vbeSwitchBuffers() { - if (!isVBESupported) return -1; // Either VBE is not enabled or not supported. - if (!framebuffer_initialized) return -1; // Framebuffer not initialized. - - // Switch the framebuffers - for (int i = 0; i < 1024*768; i++) { - vbeBuffer[i] = framebuffer[i]; - } - - return 0; // Updated buffers successfully. -} - - -// Most of the graphics functions in here should not be used, instead using other graphics functions. - -// vbePutPixel(int x, int y, uint32_t color) - Puts a pixel on the screen. -void vbePutPixel(int x, int y, uint32_t color) { - // Get the location of the pixel. - uint32_t p = y * modeWidth + x; - *(framebuffer + p) = color; - - -} - -uint32_t vbeGetPixel(int x, int y) { - if (framebuffer_initialized) return *(framebuffer + (y * modeWidth + x)); - else return *(vbeBuffer + (y * modeWidth + x)); -} - +// ========================================================== +// vesa.c - VESA VBE graphics handler +// ========================================================== +// This file is a part of the reduceOS C kernel. Please credit me if you use this code. + +// VESA VBE is a type of graphics "mode", like VGA +// However, VESA VBE is different from VGA in the fact that it has its own "modes" +// These modes can correspond to different resolutions and colordepths +// For more information, see https://wiki.osdev.org/Drawing_In_a_Linear_Framebuffer + +#include // Main header file + +// Variables + +vbeInfoBlock_t vbeInfo; +bool isVBESupported = false; + +uint32_t *vbeBuffer; // This is the buffer we will be drawing in +int selectedMode = -1; // The current mode selected. +uint32_t modeWidth, modeHeight, modeBpp = 0; // The height and width of the mode + +uint32_t *framebuffer; // A seperate framebuffer. +bool framebuffer_initialized = false; + +// Double buffering is utilized in this VBE driver. Basically, that means that instead of drawing directly to video memory, you draw to a framebuffer (the one above). +// For now we use manual swapping, but potentially later PIT will swap each tick. + + +// Static functions + +// (static) vbeGetInfo() - Gets VBE information. +static void vbeGetInfo() { + // Set up the registers for our INT 0x10 call. + REGISTERS_16 in, out = {0}; + in.ax = 0x4F00; + in.di = 0x7E00; + + // Call the BIOS for our interrupt. + bios32_call(0x10, &in, &out); + + if (out.ax != 0x004F) { + panic("VBE", "vbeGetModeInfo", "BIOS 0x10 call failed"); + } + + // Copy the data to vbeInfo. + memcpy(&vbeInfo, (void*)0x7E00, sizeof(vbeInfoBlock_t)); + + // Change supported variable. + isVBESupported = (out.ax == 0x4F); +} + + +// (static) vbeGetModeInfo(uint16_t mode) - Returns information on a certain mode. +static vbeModeInfo_t vbeGetModeInfo(uint16_t mode) { + // Like before, setup the registers for our INT 0x10 call. + // This time, however, change AX to be 0x4F01 to signify that we want mode info. + vbeModeInfo_t modeInfo; + + REGISTERS_16 in = {0}; + in.ax = 0x4F01; + in.cx = mode; + in.di = 0x7E00 + 1024; + + REGISTERS_16 out = {0}; + + // Call the BIOS for our interrupt. + bios32_call(0x10, &in, &out); + + if (out.ax != 0x004F) { + panic("VBE", "vbeGetModeInfo", "BIOS 0x10 call failed"); + } + + // Copy the data. + memcpy(&modeInfo, (void*)0x7E00 + 1024, sizeof(vbeModeInfo_t)); + return modeInfo; +} + +// DEBUG FUNCTION!! +void vesaPrintModes() { + uint16_t *modes = (uint16_t*)vbeInfo.videoModePtr; + uint16_t currentMode = *modes++; + + vbeModeInfo_t modeInfo; + + // Possible bug here - we are supposed to stop on currentMode being 0xFFFF, but this crashes a lot until it randomly works - unsure if bug with code or QEMU?? + // For now just choose the best resolution we can use without crashing the entire system. + for (int i = 0; i < 10; i++) { + modeInfo = vbeGetModeInfo(currentMode); + serialPrintf("Found mode %d - %d x %d with colordepth %d (mode is 0x%x)\n", currentMode, modeInfo.width, modeInfo.height, modeInfo.bpp, currentMode); + currentMode = *modes++; + } +} + + + + + +// Functions (non-static) + +// vbeSetMode(uint32_t mode) - Sets a VBE mode using BIOS32 +void vbeSetMode(uint32_t mode) { + // Like all BIOS32 calls, setup the registers first. + REGISTERS_16 in = {0}; + in.ax = 0x4F02; + in.bx = mode; + + REGISTERS_16 out = {0}; + + // Call BIOS interrupt 0x10. + bios32_call(0x10, &in, &out); + + if (out.ax != 0x004F) { + panic("VBE", "vbeGetModeInfo", "BIOS 0x10 call failed"); + } +} + +// vbeGetMode(uint32_t width, uint32_t height, uint32_t color_depth) - Returns the VBE mode with the parameters given. +uint32_t vbeGetMode(uint32_t width, uint32_t height, uint32_t color_depth) { + // First, get the mode list from the VBE video mode pointer. + uint16_t *modes = (uint16_t*)vbeInfo.videoModePtr; + uint16_t currentMode = *modes++; + + // This function has a potential bug, check vesaPrintModes() for the bug description. + + // Locate the mode. + while (currentMode != 0xFFFF) { + // Get the mode info and compare it against the parameters. + vbeModeInfo_t modeInfo = vbeGetModeInfo(currentMode); + + if (modeInfo.width == width && modeInfo.height == height && modeInfo.bpp == color_depth) { + return currentMode; // Found the mode! + } + + currentMode = *modes++; // Keep searching! + } + + return -1; // We didn't find the mode :( +} + + + +// Helper function to convert to a VBE RGB value. +uint32_t RGB_VBE(uint8_t r, uint8_t g, uint8_t b) { + uint32_t color = r; + color <<= 16; + color |= (g << 8); + color |= b; + return color; +} + +uint32_t VGA_TO_VBE(uint8_t vgaColor) { + switch (vgaColor) { + case COLOR_BLACK: + return RGB_VBE(0, 0, 0); + case COLOR_WHITE: + return RGB_VBE(255, 255, 255); + case COLOR_BLUE: + return RGB_VBE(0, 0, 170); + case COLOR_GREEN: + return RGB_VBE(0, 170, 0); + case COLOR_CYAN: + return RGB_VBE(0, 170, 170); + case COLOR_RED: + return RGB_VBE(170, 0, 0); + case COLOR_MAGENTA: + return RGB_VBE(170, 0, 170); + case COLOR_BROWN: + return RGB_VBE(170, 85, 0); + case COLOR_LIGHT_GRAY: + return RGB_VBE(170, 170, 170); // why did we do gray as light gray + case COLOR_DARK_GRAY: + return RGB_VBE(85, 85, 85); + case COLOR_LIGHT_BLUE: + return RGB_VBE(85, 85, 255); + case COLOR_LIGHT_GREEN: + return RGB_VBE(85, 85, 255); + case COLOR_LIGHT_CYAN: + return RGB_VBE(85, 255, 255); + case COLOR_LIGHT_RED: + return RGB_VBE(255, 85, 85); + case COLOR_LIGHT_MAGENTA: + return RGB_VBE(255, 85, 255); + case COLOR_YELLOW: + return RGB_VBE(255, 255, 85); + default: + serialPrintf("VGA_TO_VBE: stupid users (color = %i)\n", vgaColor); + return; + } + // lmao +} + + +// vesaInit() - Initializes VESA VBE. +void vesaInit() { + + // First, get VBE info and check if supported. + vbeGetInfo(); + + if (!isVBESupported) { + serialPrintf("vesaInit: VBE is not supported.\n"); + return; + } + + // There is a bug preventing us from checking some video modes - check vesaPrintModes() for the bug description. + // For now, just use 1024x768 with colordepth 32 + + // uint32_t mode = vbeGetMode(800, 600, 32); + // if (mode == -1) return; // No valid mode was found. + + + // Bypass getting the mode and just set it like so. + uint32_t mode = 0x144 | 0x4000; + + // Get a bit more information on the mode. + vbeModeInfo_t modeInfo = vbeGetModeInfo(mode); + + // Identity map framebuffer! + vmm_allocateRegion(modeInfo.framebuffer, modeInfo.framebuffer, 1024*768*4); + + // Make sure PMM knows not to allocate here + pmm_deinitRegion(modeInfo.framebuffer, 1024*768); + + // Change variables to reflect on modeInfo. + selectedMode = mode; + modeWidth = modeInfo.width; + modeHeight = modeInfo.height; + modeBpp = modeInfo.bpp; + vbeBuffer = (uint32_t*)modeInfo.framebuffer; + + + // Now, switch the mode. + vbeSetMode(mode); + + extern uint32_t bss_end; + extern uint32_t text_start; + + framebuffer = kmalloc(1024*768*4); + serialPrintf("vesaInit: Allocated framebuffer to 0x%x - 0x%x\n", framebuffer, (int)framebuffer + (1024*768*4)); + + // Because framebuffer is big and stupid pmm will get confused and try to still allocate memory INSIDE of it + // So we need to fix that by telling PMM to go pound sand and deinitialize the region + pmm_deinitRegion(framebuffer, 1024*768*4); + + /* This code is to stop liballoc from screwing absolutely everything up. It is not required! */ + ASSERT(!(framebuffer < &bss_end), "vesaInit", "Invalid framebuffer (in kernelspace)"); + ASSERT(!(framebuffer <= &text_start), "vesaInit", "Invalid framebuffer (before kernelspace)"); + + /* This is also not required. */ + framebuffer_initialized = true; +} + + + +// vbeSwitchBuffers() - Switches the framebuffers +int vbeSwitchBuffers() { + if (!isVBESupported) return -1; // Either VBE is not enabled or not supported. + if (!framebuffer_initialized) return -1; // Framebuffer not initialized. + + // Switch the framebuffers + for (int i = 0; i < 1024*768; i++) { + vbeBuffer[i] = framebuffer[i]; + } + + return 0; // Updated buffers successfully. +} + + +// Most of the graphics functions in here should not be used, instead using other graphics functions. + +// vbePutPixel(int x, int y, uint32_t color) - Puts a pixel on the screen. +void vbePutPixel(int x, int y, uint32_t color) { + // Get the location of the pixel. + uint32_t p = y * modeWidth + x; + *(framebuffer + p) = color; + + +} + +uint32_t vbeGetPixel(int x, int y) { + if (framebuffer_initialized) return *(framebuffer + (y * modeWidth + x)); + else return *(vbeBuffer + (y * modeWidth + x)); +} + diff --git a/source/kernel/include/CONFIG.h b/source/kernel/include/CONFIG.h index d730a50f..ceced133 100644 --- a/source/kernel/include/CONFIG.h +++ b/source/kernel/include/CONFIG.h @@ -10,6 +10,6 @@ #define VERSION "1.3-prerelease1" // DO NOT MODIFY THE BELOW LINES!!! -#define BUILD_NUMBER "3643" -#define BUILD_DATE "08/07/24, 12:46:42" +#define BUILD_NUMBER "3660" +#define BUILD_DATE "08/07/24, 13:57:51" #define BUILD_CONFIGURATION "DEBUG" diff --git a/source/kernel/include/acpi.h b/source/kernel/include/acpi.h index ddd434ba..9f220fbd 100644 --- a/source/kernel/include/acpi.h +++ b/source/kernel/include/acpi.h @@ -1,172 +1,172 @@ -// acpi.h - header file for the Advanced Configuration Power Interface manager - -#ifndef ACPI_H -#define ACPI_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations. -#include "include/local_apic.h" // Local APIC (different from ACPI) -#include "include/io_apic.h" // IO APIC -#include "include/libc/string.h" // Misc. functions -#include "include/bios32.h" // BIOS32 functions - -// Typedefs - -// ACPI header -typedef struct { - char signature[4]; - uint32_t length; - uint8_t revision; - uint8_t checksum; - char OEM[6]; - char OEMTableID[8]; - uint32_t OEMRevision; - uint32_t creatorID; - uint32_t creatorRevision; -} __attribute__((packed)) ACPIHeader; - -// ACPI FADT (Fixed ACPI Description Table) -// https://wiki.osdev.org/FADT - -typedef struct { - uint8_t AddressSpace; - uint8_t BitWidth; - uint8_t BitOffset; - uint8_t AccessSize; - uint64_t Address; -} GenericAddressStructure; - -typedef struct { - ACPIHeader h; - uint32_t FirmwareCtrl; - uint32_t Dsdt; - - // field used in ACPI 1.0; no longer in use, for compatibility only - uint8_t Reserved; - - uint8_t PreferredPowerManagementProfile; - uint16_t SCI_Interrupt; - uint32_t SMI_CommandPort; - uint8_t AcpiEnable; - uint8_t AcpiDisable; - uint8_t S4BIOS_REQ; - uint8_t PSTATE_Control; - uint32_t PM1aEventBlock; - uint32_t PM1bEventBlock; - uint32_t PM1aControlBlock; - uint32_t PM1bControlBlock; - uint32_t PM2ControlBlock; - uint32_t PMTimerBlock; - uint32_t GPE0Block; - uint32_t GPE1Block; - uint8_t PM1EventLength; - uint8_t PM1ControlLength; - uint8_t PM2ControlLength; - uint8_t PMTimerLength; - uint8_t GPE0Length; - uint8_t GPE1Length; - uint8_t GPE1Base; - uint8_t CStateControl; - uint16_t WorstC2Latency; - uint16_t WorstC3Latency; - uint16_t FlushSize; - uint16_t FlushStride; - uint8_t DutyOffset; - uint8_t DutyWidth; - uint8_t DayAlarm; - uint8_t MonthAlarm; - uint8_t Century; - - // reserved in ACPI 1.0; used since ACPI 2.0+ - uint16_t BootArchitectureFlags; - - uint8_t Reserved2; - uint32_t Flags; - - // 12 byte structure; see below for details - GenericAddressStructure ResetReg; - - uint8_t ResetValue; - uint8_t Reserved3[3]; - - // 64bit pointers - Available on ACPI 2.0+ - uint64_t X_FirmwareControl; - uint64_t X_Dsdt; - - GenericAddressStructure X_PM1aEventBlock; - GenericAddressStructure X_PM1bEventBlock; - GenericAddressStructure X_PM1aControlBlock; - GenericAddressStructure X_PM1bControlBlock; - GenericAddressStructure X_PM2ControlBlock; - GenericAddressStructure X_PMTimerBlock; - GenericAddressStructure X_GPE0Block; - GenericAddressStructure X_GPE1Block; -} ACPI_FADT; - -// APIC headers -typedef struct { - uint8_t type; - uint8_t length; -} __attribute__((packed)) APICHeader; - -typedef struct { - APICHeader header; - uint8_t ACPIProcessorID; - uint8_t apicID; - uint32_t flags; -} __attribute__((packed)) APICLocal; - -typedef struct { - APICHeader header; - uint8_t ioAPIC_id; - uint8_t reserved; - uint32_t ioAPIC_addr; - uint32_t globalSystemInterruptBase; -} __attribute__((packed)) APICIO; - -typedef struct { - APICHeader header; - uint8_t bus; - uint8_t source; - uint32_t interrupt; - uint16_t flags; -} __attribute__((packed)) APICInterruptOverride; - -// RSDP (Root System Description Pointer) -// ACPI version 1.0 -typedef struct { - char signature[8]; - uint8_t checksum; - char OEMID[6]; - uint8_t revision; - uint32_t rsdtAddress; -} __attribute__((packed)) RSDPDescriptor; - -// ACPI version 2.0 -typedef struct { - RSDPDescriptor start; - uint32_t length; - uint64_t xsdtAddress; - uint8_t extendedChecksum; - uint8_t reserved[3]; -} __attribute__((packed)) RSDPDescriptor_v2; - -typedef struct { - ACPIHeader header; - uint32_t localAPIC_addr; - uint32_t flags; -} __attribute__((packed)) ACPI_MADT; - -// Definitions -#define APIC_TYPE_LOCAL_APIC 0 -#define APIC_TYPE_IO_APIC 1 -#define APIC_TYPE_INT_OVERRIDE 2 - - - -// External variables -extern uint8_t *localAPICAddress; -extern uint8_t *ioAPIC_addr; - - -#endif \ No newline at end of file +// acpi.h - header file for the Advanced Configuration Power Interface manager + +#ifndef ACPI_H +#define ACPI_H + +// Includes +#include // Integer declarations. +#include // Local APIC (different from ACPI) +#include // IO APIC +#include // Misc. functions +#include // BIOS32 functions + +// Typedefs + +// ACPI header +typedef struct { + char signature[4]; + uint32_t length; + uint8_t revision; + uint8_t checksum; + char OEM[6]; + char OEMTableID[8]; + uint32_t OEMRevision; + uint32_t creatorID; + uint32_t creatorRevision; +} __attribute__((packed)) ACPIHeader; + +// ACPI FADT (Fixed ACPI Description Table) +// https://wiki.osdev.org/FADT + +typedef struct { + uint8_t AddressSpace; + uint8_t BitWidth; + uint8_t BitOffset; + uint8_t AccessSize; + uint64_t Address; +} GenericAddressStructure; + +typedef struct { + ACPIHeader h; + uint32_t FirmwareCtrl; + uint32_t Dsdt; + + // field used in ACPI 1.0; no longer in use, for compatibility only + uint8_t Reserved; + + uint8_t PreferredPowerManagementProfile; + uint16_t SCI_Interrupt; + uint32_t SMI_CommandPort; + uint8_t AcpiEnable; + uint8_t AcpiDisable; + uint8_t S4BIOS_REQ; + uint8_t PSTATE_Control; + uint32_t PM1aEventBlock; + uint32_t PM1bEventBlock; + uint32_t PM1aControlBlock; + uint32_t PM1bControlBlock; + uint32_t PM2ControlBlock; + uint32_t PMTimerBlock; + uint32_t GPE0Block; + uint32_t GPE1Block; + uint8_t PM1EventLength; + uint8_t PM1ControlLength; + uint8_t PM2ControlLength; + uint8_t PMTimerLength; + uint8_t GPE0Length; + uint8_t GPE1Length; + uint8_t GPE1Base; + uint8_t CStateControl; + uint16_t WorstC2Latency; + uint16_t WorstC3Latency; + uint16_t FlushSize; + uint16_t FlushStride; + uint8_t DutyOffset; + uint8_t DutyWidth; + uint8_t DayAlarm; + uint8_t MonthAlarm; + uint8_t Century; + + // reserved in ACPI 1.0; used since ACPI 2.0+ + uint16_t BootArchitectureFlags; + + uint8_t Reserved2; + uint32_t Flags; + + // 12 byte structure; see below for details + GenericAddressStructure ResetReg; + + uint8_t ResetValue; + uint8_t Reserved3[3]; + + // 64bit pointers - Available on ACPI 2.0+ + uint64_t X_FirmwareControl; + uint64_t X_Dsdt; + + GenericAddressStructure X_PM1aEventBlock; + GenericAddressStructure X_PM1bEventBlock; + GenericAddressStructure X_PM1aControlBlock; + GenericAddressStructure X_PM1bControlBlock; + GenericAddressStructure X_PM2ControlBlock; + GenericAddressStructure X_PMTimerBlock; + GenericAddressStructure X_GPE0Block; + GenericAddressStructure X_GPE1Block; +} ACPI_FADT; + +// APIC headers +typedef struct { + uint8_t type; + uint8_t length; +} __attribute__((packed)) APICHeader; + +typedef struct { + APICHeader header; + uint8_t ACPIProcessorID; + uint8_t apicID; + uint32_t flags; +} __attribute__((packed)) APICLocal; + +typedef struct { + APICHeader header; + uint8_t ioAPIC_id; + uint8_t reserved; + uint32_t ioAPIC_addr; + uint32_t globalSystemInterruptBase; +} __attribute__((packed)) APICIO; + +typedef struct { + APICHeader header; + uint8_t bus; + uint8_t source; + uint32_t interrupt; + uint16_t flags; +} __attribute__((packed)) APICInterruptOverride; + +// RSDP (Root System Description Pointer) +// ACPI version 1.0 +typedef struct { + char signature[8]; + uint8_t checksum; + char OEMID[6]; + uint8_t revision; + uint32_t rsdtAddress; +} __attribute__((packed)) RSDPDescriptor; + +// ACPI version 2.0 +typedef struct { + RSDPDescriptor start; + uint32_t length; + uint64_t xsdtAddress; + uint8_t extendedChecksum; + uint8_t reserved[3]; +} __attribute__((packed)) RSDPDescriptor_v2; + +typedef struct { + ACPIHeader header; + uint32_t localAPIC_addr; + uint32_t flags; +} __attribute__((packed)) ACPI_MADT; + +// Definitions +#define APIC_TYPE_LOCAL_APIC 0 +#define APIC_TYPE_IO_APIC 1 +#define APIC_TYPE_INT_OVERRIDE 2 + + + +// External variables +extern uint8_t *localAPICAddress; +extern uint8_t *ioAPIC_addr; + + +#endif diff --git a/source/kernel/include/bios32.h b/source/kernel/include/bios32.h index 8457449a..ba936e57 100644 --- a/source/kernel/include/bios32.h +++ b/source/kernel/include/bios32.h @@ -1,28 +1,28 @@ -// bios32.h - header file for bios32.c (handles BIOS calls in protected mode) - -#ifndef BIOS32_H -#define BIOS32_H - -// Includes -#include "include/libc/stdint.h" // Integer definitions -#include "include/gdt.h" // Global descriptor table -#include "include/idt.h" // Interrupt descriptor table -#include "include/regs.h" // Registers - -// External functions -extern void BIOS32_START(); -extern void BIOS32_END(); -extern void *bios32_gdt_ptr; -extern void *bios32_gdt_entries; -extern void *bios32_idt_ptr; -extern void *bios32_in_reg16_ptr; -extern void *bios32_out_reg16_ptr; -extern void *bios32_int_number_ptr; - -#define REBASE_ADDRESS(x) (void*)(0x7c00 + (void*)x - (uint32_t)BIOS32_START) - - -void bios32_init(); // Initializes BIOS32. -void bios32_call(uint8_t int_num, REGISTERS_16 *in_reg, REGISTERS_16 *out_reg); // Call the BIOS in protected mode. - -#endif \ No newline at end of file +// bios32.h - header file for bios32.c (handles BIOS calls in protected mode) + +#ifndef BIOS32_H +#define BIOS32_H + +// Includes +#include // Integer definitions +#include // Global descriptor table +#include // Interrupt descriptor table +#include // Registers + +// External functions +extern void BIOS32_START(); +extern void BIOS32_END(); +extern void *bios32_gdt_ptr; +extern void *bios32_gdt_entries; +extern void *bios32_idt_ptr; +extern void *bios32_in_reg16_ptr; +extern void *bios32_out_reg16_ptr; +extern void *bios32_int_number_ptr; + +#define REBASE_ADDRESS(x) (void*)(0x7c00 + (void*)x - (uint32_t)BIOS32_START) + + +void bios32_init(); // Initializes BIOS32. +void bios32_call(uint8_t int_num, REGISTERS_16 *in_reg, REGISTERS_16 *out_reg); // Call the BIOS in protected mode. + +#endif diff --git a/source/kernel/include/bitmap.h b/source/kernel/include/bitmap.h index 324222ba..016e65db 100644 --- a/source/kernel/include/bitmap.h +++ b/source/kernel/include/bitmap.h @@ -1,52 +1,52 @@ -// bitmap.h - Header file for bitmap drawer/parser -#ifndef BITMAP_H -#define BITMAP_H - -#include "libc/string.h" // String functions -#include "libc/stdint.h" // Integer types (uint32_t, ...) -#include "initrd.h" // Initial ramdisk support -#include "vesa.h" // VESA VBE support - -// Typedefs -typedef struct { - uint16_t type; - uint32_t size; - uint16_t reserved1; - uint16_t resreved2; - uint32_t offbits; -} __attribute__((packed)) bitmap_fileHeader_t; - -typedef struct { - uint32_t size; - long width; - long height; - uint16_t planes; - uint16_t bitcount; - uint32_t compression; - uint32_t sizeImage; - long XPelsPerMeter; - long YPelsPerMeter; - uint32_t clrUsed; - uint32_t clrImportant; -} bitmap_infoHeader_t; - -typedef struct { - uint32_t width; - uint32_t height; - char *imageBytes; - char *buffer; - uint32_t totalSize; - uint32_t bpp; -} bitmap_t; - -typedef struct { - uint8_t r; - uint8_t g; - uint8_t b; - uint8_t a; -} palette_t; - - -// Functions -bitmap_t *bitmap_loadBitmap(fsNode_t *node); // Loads the bitmap into memory and returns the bitmap_t object. -#endif \ No newline at end of file +// bitmap.h - Header file for bitmap drawer/parser +#ifndef BITMAP_H +#define BITMAP_H + +#include // String functions +#include // Integer types (uint32_t, ...) +#include // Initial ramdisk support +#include // VESA VBE support + +// Typedefs +typedef struct { + uint16_t type; + uint32_t size; + uint16_t reserved1; + uint16_t resreved2; + uint32_t offbits; +} __attribute__((packed)) bitmap_fileHeader_t; + +typedef struct { + uint32_t size; + long width; + long height; + uint16_t planes; + uint16_t bitcount; + uint32_t compression; + uint32_t sizeImage; + long XPelsPerMeter; + long YPelsPerMeter; + uint32_t clrUsed; + uint32_t clrImportant; +} bitmap_infoHeader_t; + +typedef struct { + uint32_t width; + uint32_t height; + char *imageBytes; + char *buffer; + uint32_t totalSize; + uint32_t bpp; +} bitmap_t; + +typedef struct { + uint8_t r; + uint8_t g; + uint8_t b; + uint8_t a; +} palette_t; + + +// Functions +bitmap_t *bitmap_loadBitmap(fsNode_t *node); // Loads the bitmap into memory and returns the bitmap_t object. +#endif diff --git a/source/kernel/include/bootinfo.h b/source/kernel/include/bootinfo.h index 913666c1..9b21df00 100644 --- a/source/kernel/include/bootinfo.h +++ b/source/kernel/include/bootinfo.h @@ -1,67 +1,67 @@ -// bootinfo.h - header file defining multiboot_info, the structure passed by loadkernel and kernel assembly files. -// All credit from this file goes to BrokenThorn Entertainment. - -#ifndef BOOTINFO_H -#define BOOTINFO_H - -#include "include/libc/stdint.h" // Definitions of integer types, like uint8_t - -#define MULTIBOOT_MAGIC 0x1BADB002 - - -typedef struct { - uint32_t tab_size; - uint32_t string_size; - uint32_t address; - uint32_t reserved; -} aoutSymbolTable_t; - -typedef struct { - uint32_t number; - uint32_t size; - uint32_t address; - uint32_t shndx; -} elfHeader_t; - -typedef struct { - uint32_t m_flags; // m_flags - Multiboot flags (useless without a multiboot bootloader like GRUB) - uint32_t m_memoryLo; // m_memoryLo - Low address of memory - uint32_t m_memoryHi; // m_memoryHi - High address of memory (usually 0) - uint32_t m_bootDevice; // m_bootDevice - Value BIOS passed - uint32_t m_cmdLine; // m_cmdLine - command used to boot OS - uint32_t m_modsCount; // m_modsCount - Amount of mods passed (used with initrd) - uint32_t m_modsAddr; // m_modsAddr - Address of mods passed (used with initrd) - union { - aoutSymbolTable_t aout_sym; - elfHeader_t elf_sec; - } u; - uint32_t m_mmap_length; // m_mmap_length - Length of memory map - uint32_t m_mmap_addr; // m_mmap_addr - Address of memory map - uint32_t m_drives_length; // m_drives_length - Length of drive - uint32_t m_drives_addr; // m_drives_addr - Address of drive - uint32_t m_config_table; // m_config_table - Unused - uint32_t m_bootloader_name; // m_bootloader_name - The name of the bootloader that loaded the kernel - uint32_t m_apm_table; // m_apm_table - APM information - uint32_t m_vbe_control_info; // m_vbe_control_info - VBE control info - uint32_t m_vbe_mode_info; // m_vbe_mode_info - VBE mode info - uint16_t m_vbe_mode; // m_vbe_mode - VBE mode - uint32_t m_vbe_interface_addr; // m_vbe_interface_addr - VBE interface address - uint16_t m_vbe_interface_len; // m_vbe_interface_len - VBE interface length - uint64_t framebuffer_addr; - uint32_t framebuffer_pitch; - uint32_t framebuffer_width; - uint32_t framebuffer_height; - uint8_t framebuffer_bpp; - uint8_t framebuffer_type; // indexed = 0, RGB = 1, EGA = 2 -} multiboot_info; - -typedef struct { - uint32_t mod_start; - uint32_t mod_end; - uint32_t cmdline; - uint32_t padding; -} multiboot_mod_t; - - -#endif - +// bootinfo.h - header file defining multiboot_info, the structure passed by loadkernel and kernel assembly files. +// All credit from this file goes to BrokenThorn Entertainment. + +#ifndef BOOTINFO_H +#define BOOTINFO_H + +#include // Definitions of integer types, like uint8_t + +#define MULTIBOOT_MAGIC 0x1BADB002 + + +typedef struct { + uint32_t tab_size; + uint32_t string_size; + uint32_t address; + uint32_t reserved; +} aoutSymbolTable_t; + +typedef struct { + uint32_t number; + uint32_t size; + uint32_t address; + uint32_t shndx; +} elfHeader_t; + +typedef struct { + uint32_t m_flags; // m_flags - Multiboot flags (useless without a multiboot bootloader like GRUB) + uint32_t m_memoryLo; // m_memoryLo - Low address of memory + uint32_t m_memoryHi; // m_memoryHi - High address of memory (usually 0) + uint32_t m_bootDevice; // m_bootDevice - Value BIOS passed + uint32_t m_cmdLine; // m_cmdLine - command used to boot OS + uint32_t m_modsCount; // m_modsCount - Amount of mods passed (used with initrd) + uint32_t m_modsAddr; // m_modsAddr - Address of mods passed (used with initrd) + union { + aoutSymbolTable_t aout_sym; + elfHeader_t elf_sec; + } u; + uint32_t m_mmap_length; // m_mmap_length - Length of memory map + uint32_t m_mmap_addr; // m_mmap_addr - Address of memory map + uint32_t m_drives_length; // m_drives_length - Length of drive + uint32_t m_drives_addr; // m_drives_addr - Address of drive + uint32_t m_config_table; // m_config_table - Unused + uint32_t m_bootloader_name; // m_bootloader_name - The name of the bootloader that loaded the kernel + uint32_t m_apm_table; // m_apm_table - APM information + uint32_t m_vbe_control_info; // m_vbe_control_info - VBE control info + uint32_t m_vbe_mode_info; // m_vbe_mode_info - VBE mode info + uint16_t m_vbe_mode; // m_vbe_mode - VBE mode + uint32_t m_vbe_interface_addr; // m_vbe_interface_addr - VBE interface address + uint16_t m_vbe_interface_len; // m_vbe_interface_len - VBE interface length + uint64_t framebuffer_addr; + uint32_t framebuffer_pitch; + uint32_t framebuffer_width; + uint32_t framebuffer_height; + uint8_t framebuffer_bpp; + uint8_t framebuffer_type; // indexed = 0, RGB = 1, EGA = 2 +} multiboot_info; + +typedef struct { + uint32_t mod_start; + uint32_t mod_end; + uint32_t cmdline; + uint32_t padding; +} multiboot_mod_t; + + +#endif + diff --git a/source/kernel/include/cmds.h b/source/kernel/include/cmds.h index 3172581f..56e7edc6 100644 --- a/source/kernel/include/cmds.h +++ b/source/kernel/include/cmds.h @@ -4,7 +4,7 @@ #define CMDS_H // Includes -#include "include/kernel.h" // Steal everything from the kernel includes file (very bad practice) +#include // Steal everything from the kernel includes file (very bad practice) // Functions // I'm too tired to put them here, gcc will deal with it @@ -40,4 +40,4 @@ int edit(int argc, char *args[]); -#endif \ No newline at end of file +#endif diff --git a/source/kernel/include/command.h b/source/kernel/include/command.h index b190d248..e8760143 100644 --- a/source/kernel/include/command.h +++ b/source/kernel/include/command.h @@ -1,29 +1,29 @@ -// command.h - Header file for the command parser (command.c) - -#ifndef COMMAND_H -#define COMMAND_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/libc/string.h" // String functions -#include "include/heap.h" // Memory allocation functions -#include "include/terminal.h" // printf() - -// Typedefs -typedef int command(int argc, char *args[]); // This is the command FUNCTION - the thing that is called on a command. - - -// The main command array uses cmdData. The reason we use cmdData instead of command is because we need the NAME of the command. -// Comparisons would be pretty hard without a command name. -typedef struct { - char *cmdName; - command *cmdFunc; -} cmdData; - - -// Functions -int parseCommand(char *cmd); -void registerCommand(char *name, command cmd); -void initCommandHandler(); - -#endif \ No newline at end of file +// command.h - Header file for the command parser (command.c) + +#ifndef COMMAND_H +#define COMMAND_H + +// Includes +#include // Integer declarations +#include // String functions +#include // Memory allocation functions +#include // printf() + +// Typedefs +typedef int command(int argc, char *args[]); // This is the command FUNCTION - the thing that is called on a command. + + +// The main command array uses cmdData. The reason we use cmdData instead of command is because we need the NAME of the command. +// Comparisons would be pretty hard without a command name. +typedef struct { + char *cmdName; + command *cmdFunc; +} cmdData; + + +// Functions +int parseCommand(char *cmd); +void registerCommand(char *name, command cmd); +void initCommandHandler(); + +#endif diff --git a/source/kernel/include/dma.h b/source/kernel/include/dma.h index 2b124609..295559c7 100644 --- a/source/kernel/include/dma.h +++ b/source/kernel/include/dma.h @@ -4,8 +4,8 @@ #define DMA_H // Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/hal.h" // Hardware Abstraction Layer +#include // Integer declarations +#include // Hardware Abstraction Layer // Definitions @@ -108,4 +108,4 @@ void dma_setWrite(uint8_t channel); // Puts a channel into write transfer mode void dma_initPool(int pool_size); // Initialize a DMA pool of memory, that processes can pull from for their channels void *dma_allocPool(size_t size); // Gets a chunk from the DMA pool. Note: This chunk is statutory! You cannot put it back! -#endif \ No newline at end of file +#endif diff --git a/source/kernel/include/ext2.h b/source/kernel/include/ext2.h index 48453bf9..2687b209 100644 --- a/source/kernel/include/ext2.h +++ b/source/kernel/include/ext2.h @@ -4,8 +4,8 @@ #define EXT2_H // Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/vfs.h" +#include // Integer declarations +#include // Typedefs @@ -246,4 +246,4 @@ int ext2_fileToNode(ext2_t *fs, ext2_dirent_t *dirent, ext2_inode_t *inode, fsNo int ext2_install(int argc, char *argv[]); // Installs the EXT2 filesystem driver to automatically initialize when a disk is detected -#endif \ No newline at end of file +#endif diff --git a/source/kernel/include/fat.h b/source/kernel/include/fat.h index 398fa7e7..97c4d525 100644 --- a/source/kernel/include/fat.h +++ b/source/kernel/include/fat.h @@ -1,129 +1,129 @@ -// fat.h - include file for FAT - -#include "include/libc/stdint.h" // Integer definitions (uint32_t, ...) -#include "include/libc/string.h" // String functions -#include "include/vfs.h" // Virtual File System -#include "include/ide_ata.h" // IDE ATA driver - -// Typedefs - - -typedef struct { - uint32_t tableSize32; // Sectors per FAT, I think. - uint16_t extendedFlags; - uint16_t fatVersion; // OSDev wiki says "FAT drivers should respect this field". Yeah, about that. - uint32_t rootCluster; // Cluster of the root directory (often 2) - uint16_t fatInfo; // FAT32's FSInfo structure sector number - uint16_t backupSector; // Backup boot sector - uint8_t reserved[12]; - uint8_t driveNum; - uint8_t reserved2; - uint8_t bootSignature; - uint32_t volumeID; - uint8_t volumeLabel[11]; - uint8_t fatTypeLabel[8]; -} __attribute__((packed)) fat_extendedBPB32_t; - -typedef struct { - // FAT12 and FAT16 extended BPB - uint8_t biosDriveNum; - uint8_t reserved; - uint8_t bootSignature; - uint32_t volumeId; - uint8_t volumeLabel[11]; - uint8_t fatTypeLabel[8]; -} __attribute__((packed)) fat_extendedBPB16_t; - -typedef struct { - // FSInfo structure, only for FAT32 - uint32_t signature; // Should be 0x41615252 - uint8_t reserved[480]; // Whoa. That's a lot of reserved bytes! - uint32_t signature2; // Should be 0x614177272 - uint32_t freeClusterCount; // LAST KNOWN free cluster count. Needs to be recomputed if 0xFFFFFFFF, and also should be range checked (<= volume cluster count) - uint32_t availableClusterStart; // Available cluster start. If the value is 0xFFFFFFFF, there is no hint and we should do everything ourselves. - uint8_t reserved2[12]; // More reserved bytes - uint32_t signature3; // The THIRD signature, should be 0xAA550000 -} __attribute__((packed)) fat_fsInfo_t; - -typedef struct { - uint8_t bootjmp[3]; - uint8_t oemName[8]; - uint16_t bytesPerSector; - uint8_t sectorsPerCluster; - uint16_t reservedSectorCount; - uint8_t tableCount; - uint16_t rootEntryCount; - uint16_t totalSectors16; // If this is zero, there are more than 65535 sectors (actual count is stored in totalSectors32) - uint8_t mediaType; - uint16_t tableSize16; // Sectors per FAT for FAT12/FAT16 - uint16_t sectorsPerTrack; - uint16_t headSideCount; - uint32_t hiddenSectorCount; - uint32_t totalSectors32; // Total count of sectors (if greater than 65535) - uint8_t extended[54]; // Will be typecast depending on FAT type -} __attribute__((packed)) fat_BPB_t; - - - -// This structure is referenced in the VFS impl_struct flag, and allocated a specific amount of memory. -// This is probably a very bad idea, but it does help cleanup code slightly. -typedef struct { - fsNode_t *driveobj; - int fatType; // 0 - exFAT, 1 - FAT12, 2 - FAT16, 3 - FAT32 - int totalSectors; // Calculated in fatInit - int fatSize; // Calculated in fatInit - int rootDirSectors; // Calculated in fatInit - int dataSectors; // Calculated in fatInit - int totalClusters; // Calculated in fatInit - int firstDataSector; // Calculated in fatInit - int firstFatSector; // Calculated in fatInit - int rootOffset; // Calculated in fatInit - fat_BPB_t *bpb; // BPB in the FAT - fat_extendedBPB16_t *extended16; // Is there a more memory-efficient way to do this? - fat_extendedBPB32_t *extended32; - fat_fsInfo_t *fsInfo; -} __attribute__((packed)) fat_drive_t; - -typedef struct { - uint8_t fileName[11]; - uint8_t attributes; - uint8_t reserved; - uint8_t creationTime_tenths; // Tenths of a second - uint16_t creationTime; // Hour = 5 bits, Minutes = 6 bits, Seconds = 5 bits - multiply seconds by 2. - uint16_t creationDate; // Year = 7 bits, Month = 4 bits, Day = 5 bits - uint16_t lastAccessDate; // Year = 7 bits, Month = 4 bits, Day = 5 bits. - uint16_t firstClusterNumber; // High 16 bits of the entry first cluster number. Always 0 for FAT12 and FAT16 - uint16_t lastModificationTime; // Same format as creationTime - uint16_t lastModificationDate; // Same format as creationDate - uint16_t firstClusterNumberLow; // Low 16 bits of the entry's first cluster number (used to find the first cluster). - uint32_t size; // Size of the file in bytes -} __attribute__((packed)) fat_fileEntry_t; - -typedef struct { - uint8_t entryOrder; - uint8_t firstChars[10]; - uint8_t attribute; // Always 0x0F - uint8_t longEntryType; // Zero for name entries. - uint8_t checksum; // Checksum of the short file name. - uint8_t secondChars[12]; - uint8_t reserved[2]; - uint8_t thirdChars[4]; -} __attribute__((packed)) fat_lfnEntry_t; - -// This will be what's in impl_struct, it contains information about the filesystem and the drive object -typedef struct { - fat_fileEntry_t *fileEntry; // Used if this is a structure for a file - fat_drive_t *drive; -} fat_t; - -// Functions - -fsNode_t *fatInit(fsNode_t *driveNode, int flags); -uint32_t fatOpen(struct fsNode *node); -uint32_t fatRead(struct fsNode *node, uint32_t off, uint32_t size, uint8_t *buf); -uint32_t fatClose(struct fsNode *node); -uint32_t fatWrite(struct fsNode *node, uint32_t off, uint32_t size, uint8_t *buf); -int fat_install(int argc, char *argv[]); // Installs the FAT filesystem driver - -fsNode_t *fatOpenInternal(fsNode_t *driver, char *filename); -int fatReadInternal(fsNode_t *file, uint8_t *buffer, uint32_t length); \ No newline at end of file +// fat.h - include file for FAT + +#include // Integer definitions (uint32_t, ...) +#include // String functions +#include // Virtual File System +#include // IDE ATA driver + +// Typedefs + + +typedef struct { + uint32_t tableSize32; // Sectors per FAT, I think. + uint16_t extendedFlags; + uint16_t fatVersion; // OSDev wiki says "FAT drivers should respect this field". Yeah, about that. + uint32_t rootCluster; // Cluster of the root directory (often 2) + uint16_t fatInfo; // FAT32's FSInfo structure sector number + uint16_t backupSector; // Backup boot sector + uint8_t reserved[12]; + uint8_t driveNum; + uint8_t reserved2; + uint8_t bootSignature; + uint32_t volumeID; + uint8_t volumeLabel[11]; + uint8_t fatTypeLabel[8]; +} __attribute__((packed)) fat_extendedBPB32_t; + +typedef struct { + // FAT12 and FAT16 extended BPB + uint8_t biosDriveNum; + uint8_t reserved; + uint8_t bootSignature; + uint32_t volumeId; + uint8_t volumeLabel[11]; + uint8_t fatTypeLabel[8]; +} __attribute__((packed)) fat_extendedBPB16_t; + +typedef struct { + // FSInfo structure, only for FAT32 + uint32_t signature; // Should be 0x41615252 + uint8_t reserved[480]; // Whoa. That's a lot of reserved bytes! + uint32_t signature2; // Should be 0x614177272 + uint32_t freeClusterCount; // LAST KNOWN free cluster count. Needs to be recomputed if 0xFFFFFFFF, and also should be range checked (<= volume cluster count) + uint32_t availableClusterStart; // Available cluster start. If the value is 0xFFFFFFFF, there is no hint and we should do everything ourselves. + uint8_t reserved2[12]; // More reserved bytes + uint32_t signature3; // The THIRD signature, should be 0xAA550000 +} __attribute__((packed)) fat_fsInfo_t; + +typedef struct { + uint8_t bootjmp[3]; + uint8_t oemName[8]; + uint16_t bytesPerSector; + uint8_t sectorsPerCluster; + uint16_t reservedSectorCount; + uint8_t tableCount; + uint16_t rootEntryCount; + uint16_t totalSectors16; // If this is zero, there are more than 65535 sectors (actual count is stored in totalSectors32) + uint8_t mediaType; + uint16_t tableSize16; // Sectors per FAT for FAT12/FAT16 + uint16_t sectorsPerTrack; + uint16_t headSideCount; + uint32_t hiddenSectorCount; + uint32_t totalSectors32; // Total count of sectors (if greater than 65535) + uint8_t extended[54]; // Will be typecast depending on FAT type +} __attribute__((packed)) fat_BPB_t; + + + +// This structure is referenced in the VFS impl_struct flag, and allocated a specific amount of memory. +// This is probably a very bad idea, but it does help cleanup code slightly. +typedef struct { + fsNode_t *driveobj; + int fatType; // 0 - exFAT, 1 - FAT12, 2 - FAT16, 3 - FAT32 + int totalSectors; // Calculated in fatInit + int fatSize; // Calculated in fatInit + int rootDirSectors; // Calculated in fatInit + int dataSectors; // Calculated in fatInit + int totalClusters; // Calculated in fatInit + int firstDataSector; // Calculated in fatInit + int firstFatSector; // Calculated in fatInit + int rootOffset; // Calculated in fatInit + fat_BPB_t *bpb; // BPB in the FAT + fat_extendedBPB16_t *extended16; // Is there a more memory-efficient way to do this? + fat_extendedBPB32_t *extended32; + fat_fsInfo_t *fsInfo; +} __attribute__((packed)) fat_drive_t; + +typedef struct { + uint8_t fileName[11]; + uint8_t attributes; + uint8_t reserved; + uint8_t creationTime_tenths; // Tenths of a second + uint16_t creationTime; // Hour = 5 bits, Minutes = 6 bits, Seconds = 5 bits - multiply seconds by 2. + uint16_t creationDate; // Year = 7 bits, Month = 4 bits, Day = 5 bits + uint16_t lastAccessDate; // Year = 7 bits, Month = 4 bits, Day = 5 bits. + uint16_t firstClusterNumber; // High 16 bits of the entry first cluster number. Always 0 for FAT12 and FAT16 + uint16_t lastModificationTime; // Same format as creationTime + uint16_t lastModificationDate; // Same format as creationDate + uint16_t firstClusterNumberLow; // Low 16 bits of the entry's first cluster number (used to find the first cluster). + uint32_t size; // Size of the file in bytes +} __attribute__((packed)) fat_fileEntry_t; + +typedef struct { + uint8_t entryOrder; + uint8_t firstChars[10]; + uint8_t attribute; // Always 0x0F + uint8_t longEntryType; // Zero for name entries. + uint8_t checksum; // Checksum of the short file name. + uint8_t secondChars[12]; + uint8_t reserved[2]; + uint8_t thirdChars[4]; +} __attribute__((packed)) fat_lfnEntry_t; + +// This will be what's in impl_struct, it contains information about the filesystem and the drive object +typedef struct { + fat_fileEntry_t *fileEntry; // Used if this is a structure for a file + fat_drive_t *drive; +} fat_t; + +// Functions + +fsNode_t *fatInit(fsNode_t *driveNode, int flags); +uint32_t fatOpen(struct fsNode *node); +uint32_t fatRead(struct fsNode *node, uint32_t off, uint32_t size, uint8_t *buf); +uint32_t fatClose(struct fsNode *node); +uint32_t fatWrite(struct fsNode *node, uint32_t off, uint32_t size, uint8_t *buf); +int fat_install(int argc, char *argv[]); // Installs the FAT filesystem driver + +fsNode_t *fatOpenInternal(fsNode_t *driver, char *filename); +int fatReadInternal(fsNode_t *file, uint8_t *buffer, uint32_t length); diff --git a/source/kernel/include/floppy.h b/source/kernel/include/floppy.h index 330bc430..6a08a76c 100644 --- a/source/kernel/include/floppy.h +++ b/source/kernel/include/floppy.h @@ -4,9 +4,9 @@ #define FLOPPY_H // Includes -#include "include/libc/stdint.h" // Integer definitions -#include "include/hal.h" // Hardware Abstraction Layer -#include "include/dma.h" // Direct Memory Addressing (floppies CAN use PIO mode to transfer, but its better to do ISA DMA) +#include // Integer definitions +#include // Hardware Abstraction Layer +#include // Direct Memory Addressing (floppies CAN use PIO mode to transfer, but its better to do ISA DMA) // Definitions (note: not gonna even bother with 5.25-inch drives, sticking with 3.5-inch) #define FLOPPY_HEADS 2 @@ -114,4 +114,4 @@ void floppy_acknowledgeIRQ(uint32_t *st0, uint32_t *cyl); // Acknowledges to the int floppy_readSector(int lba, uint8_t *buffer); // Read a sector from the floppy disk. -#endif \ No newline at end of file +#endif diff --git a/source/kernel/include/font.h b/source/kernel/include/font.h index 7856ac67..0e017cb0 100644 --- a/source/kernel/include/font.h +++ b/source/kernel/include/font.h @@ -1,72 +1,72 @@ -// font.h - header file for the reduceOS font parser - -#ifndef FONT_H -#define FONT_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/libc/limits.h" // Limits. -#include "include/heap.h" // Allocation functions. -#include "include/vesa.h" // VESA VBE drawing -#include "include/font_data.h" // Font data -#include "include/terminal.h" - - -/* Note: PSF stands for 'PC Screen Font', the font used by Linux for its console */ -// Definitions - -#define PSF2_MAGIC 0x864AB572 - - -// Typedefs - -typedef struct { - uint32_t magic; // Magic bytes for identification. - uint32_t version; // Should always be zero. - uint32_t header_size; // Offset of bitmaps in file. - uint32_t flags; // 0 without a unicode table. - uint32_t glyphs; // Number of glyphs - uint32_t bytesPerGlyph; // Size of each glyph. - uint32_t height; // Height of glyph in pixels. - uint32_t width; // Width of glyph in pixels. -} PSF2_Header; - - -typedef struct { - uint8_t magic[2]; // Magic bytes for idnetiifcation. - uint8_t fontMode; // PSF font mode - uint8_t characterSize; // PSF character size. -} PSF1_Header; - - -// Definitions - -// PSF 1 definitions -#define PSF1_MODE512 0x01 -#define PSF1_MODEHASTAB 0x02 -#define PSF1_MODEHASSEQ 0x04 -#define PSF1_MAXMODE 0x05 - -#define PSF1_SEPARATOR 0xFFFF -#define PSF1_STARTSEQ 0xFFFE - -// PSF 2 definitions -#define PSF2_HAS_UNICODE_TABLE 0x01 // Flag bit. - -#define PSF2_MAXVERSION 0 // Maximum version - -#define PSF2_SEPARATOR 0xFF -#define PSF2_STARTSEQ 0xFE - - -// Functions -void bitmapFontInit(); // Initializes bitmap font reading with the default font found in font_data.c -void bitmapLoadFont(uint32_t *font_data); // Loads a a new font for the bitmap. -void bitmapFontDrawChar(char ch, int x, int y, int color); // Puts a character of color 'color' at x, y -void bitmapFontDrawString(char *str, int x, int y, int color); // Draw a string from the bitmap -void psfInit(); // Initializes the default PSF font for reduceOS. -int psfGetFontWidth(); // Get PSF font width -int psfGetFontHeight(); // Get PSF font eheight -void psfDrawChar(unsigned short int c, int cx, int cy, uint32_t fg, uint32_t bg); // Draw a PC screen font character. - -#endif \ No newline at end of file +// font.h - header file for the reduceOS font parser + +#ifndef FONT_H +#define FONT_H + +// Includes +#include // Integer declarations +#include // Limits. +#include // Allocation functions. +#include // VESA VBE drawing +#include // Font data +#include + + +/* Note: PSF stands for 'PC Screen Font', the font used by Linux for its console */ +// Definitions + +#define PSF2_MAGIC 0x864AB572 + + +// Typedefs + +typedef struct { + uint32_t magic; // Magic bytes for identification. + uint32_t version; // Should always be zero. + uint32_t header_size; // Offset of bitmaps in file. + uint32_t flags; // 0 without a unicode table. + uint32_t glyphs; // Number of glyphs + uint32_t bytesPerGlyph; // Size of each glyph. + uint32_t height; // Height of glyph in pixels. + uint32_t width; // Width of glyph in pixels. +} PSF2_Header; + + +typedef struct { + uint8_t magic[2]; // Magic bytes for idnetiifcation. + uint8_t fontMode; // PSF font mode + uint8_t characterSize; // PSF character size. +} PSF1_Header; + + +// Definitions + +// PSF 1 definitions +#define PSF1_MODE512 0x01 +#define PSF1_MODEHASTAB 0x02 +#define PSF1_MODEHASSEQ 0x04 +#define PSF1_MAXMODE 0x05 + +#define PSF1_SEPARATOR 0xFFFF +#define PSF1_STARTSEQ 0xFFFE + +// PSF 2 definitions +#define PSF2_HAS_UNICODE_TABLE 0x01 // Flag bit. + +#define PSF2_MAXVERSION 0 // Maximum version + +#define PSF2_SEPARATOR 0xFF +#define PSF2_STARTSEQ 0xFE + + +// Functions +void bitmapFontInit(); // Initializes bitmap font reading with the default font found in font_data.c +void bitmapLoadFont(uint32_t *font_data); // Loads a a new font for the bitmap. +void bitmapFontDrawChar(char ch, int x, int y, int color); // Puts a character of color 'color' at x, y +void bitmapFontDrawString(char *str, int x, int y, int color); // Draw a string from the bitmap +void psfInit(); // Initializes the default PSF font for reduceOS. +int psfGetFontWidth(); // Get PSF font width +int psfGetFontHeight(); // Get PSF font eheight +void psfDrawChar(unsigned short int c, int cx, int cy, uint32_t fg, uint32_t bg); // Draw a PC screen font character. + +#endif diff --git a/source/kernel/include/font_data.h b/source/kernel/include/font_data.h index e6e02bd0..556a5905 100644 --- a/source/kernel/include/font_data.h +++ b/source/kernel/include/font_data.h @@ -1,13 +1,13 @@ -// font_data.h - Utility file containing bitmap font data. - -#ifndef FONT_DATA_H -#define FONT_DATA_H - -// Includes -#include "include/libc/stdint.h" - -// Variables -extern uint32_t font_data[127][20]; - - -#endif \ No newline at end of file +// font_data.h - Utility file containing bitmap font data. + +#ifndef FONT_DATA_H +#define FONT_DATA_H + +// Includes +#include + +// Variables +extern uint32_t font_data[127][20]; + + +#endif diff --git a/source/kernel/include/gdt.h b/source/kernel/include/gdt.h index be46a45a..c4e1d488 100644 --- a/source/kernel/include/gdt.h +++ b/source/kernel/include/gdt.h @@ -1,44 +1,44 @@ -// gdt.h - header file for the global descriptor table. - -#ifndef GDT_H -#define GDT_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/terminal.h" // printf -#include "include/libc/assert.h" // ASSERT() macro -#include "include/tss.h" // Task State Segment - -// Definitions -#define MAX_DESCRIPTORS 8 - -// Typedefs - -// gdtEntry - defines one GDT entry. -struct gdtEntry_struct { - uint16_t limitLow; // Lower 16-bits of the limit - uint16_t baseLow; // Lower 16 bits of the base. - uint8_t baseMiddle; // Next 8 bits of the base - uint8_t access; // Access flags (determine what ring the segment can be used in) - uint8_t granularity; - uint8_t baseHigh; // Last 8 bits of the base. -} __attribute__((packed)); - -typedef struct gdtEntry_struct gdtEntry_t; - -// gdtPtr - defined a GDT pointer (points to start of array of GDT etnries) -struct gdtPtr_struct { - uint16_t limit; // Upper 16 bits of all selector limits - uint32_t base; // Address of the 1st gdtEntry_t struct. -} __attribute__((packed)); - -typedef struct gdtPtr_struct gdtPtr_t; - -// External functions -extern void install_gdt(uint32_t); - -// Functions -void gdtSetGate(int32_t num, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran); // Set the value of 1 GDT entry. -void gdtInit(); // Installs the GDT ptr and sets up all the registers - -#endif \ No newline at end of file +// gdt.h - header file for the global descriptor table. + +#ifndef GDT_H +#define GDT_H + +// Includes +#include // Integer declarations +#include // printf +#include // ASSERT() macro +#include // Task State Segment + +// Definitions +#define MAX_DESCRIPTORS 8 + +// Typedefs + +// gdtEntry - defines one GDT entry. +struct gdtEntry_struct { + uint16_t limitLow; // Lower 16-bits of the limit + uint16_t baseLow; // Lower 16 bits of the base. + uint8_t baseMiddle; // Next 8 bits of the base + uint8_t access; // Access flags (determine what ring the segment can be used in) + uint8_t granularity; + uint8_t baseHigh; // Last 8 bits of the base. +} __attribute__((packed)); + +typedef struct gdtEntry_struct gdtEntry_t; + +// gdtPtr - defined a GDT pointer (points to start of array of GDT etnries) +struct gdtPtr_struct { + uint16_t limit; // Upper 16 bits of all selector limits + uint32_t base; // Address of the 1st gdtEntry_t struct. +} __attribute__((packed)); + +typedef struct gdtPtr_struct gdtPtr_t; + +// External functions +extern void install_gdt(uint32_t); + +// Functions +void gdtSetGate(int32_t num, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran); // Set the value of 1 GDT entry. +void gdtInit(); // Installs the GDT ptr and sets up all the registers + +#endif diff --git a/source/kernel/include/gfx.h b/source/kernel/include/gfx.h index c63872b3..d889e043 100644 --- a/source/kernel/include/gfx.h +++ b/source/kernel/include/gfx.h @@ -1,14 +1,14 @@ -// gfx.h - header file for the graphics handler - -#ifndef GFX_H -#define GFX_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/vesa.h" // VESA VBE functions - -// Functions -void gfxDrawRect(int x1, int y1, int x2, int y2, uint32_t color, bool fill); // Draws a rectangle -void gfxDrawLine(int x1, int y1, int x2, int y2, uint32_t color); // Draw a line. - -#endif \ No newline at end of file +// gfx.h - header file for the graphics handler + +#ifndef GFX_H +#define GFX_H + +// Includes +#include // Integer declarations +#include // VESA VBE functions + +// Functions +void gfxDrawRect(int x1, int y1, int x2, int y2, uint32_t color, bool fill); // Draws a rectangle +void gfxDrawLine(int x1, int y1, int x2, int y2, uint32_t color); // Draw a line. + +#endif diff --git a/source/kernel/include/graphics.h b/source/kernel/include/graphics.h index cbdf5962..9ec459ae 100644 --- a/source/kernel/include/graphics.h +++ b/source/kernel/include/graphics.h @@ -1,46 +1,46 @@ -// graphics.h - Header file for graphics.c -// Note that graphics.c and terminal.c are different. One houses the main code for anything graphics related(drawing, colors, etc) and the other handles console output and misc. other functions. -#ifndef GRAPHICS_H -#define GRAPHICS_H - -#include "include/libc/stdint.h" // Integer declarations -#include "include/libc/stdbool.h" // Boolean declarations -#include "include/libc/stddef.h" // size_t declaration -#include "include/libc/string.h" // String functions - - -// Basic graphics definitions, like the video memory address -static uint16_t* const VIDEO_MEM = (uint16_t*) 0xB8000; -static size_t SCREEN_WIDTH = 80; -static size_t SCREEN_HEIGHT = 25; - -// Color enumerator. -enum gfxColor { - COLOR_BLACK = 0, - COLOR_BLUE = 1, - COLOR_GREEN = 2, - COLOR_CYAN = 3, - COLOR_RED = 4, - COLOR_MAGENTA = 5, - COLOR_BROWN = 6, - COLOR_LIGHT_GRAY = 7, - COLOR_DARK_GRAY = 8, - COLOR_LIGHT_BLUE = 9, - COLOR_LIGHT_GREEN = 10, - COLOR_LIGHT_CYAN = 11, - COLOR_LIGHT_RED = 12, - COLOR_LIGHT_MAGENTA = 13, - COLOR_YELLOW = 14, - COLOR_WHITE = 15 -}; - -// vgaEntry() - Functions returns a valid VGA character entry. -// Parameters: unsigned char uc and uint8_t color -static inline uint16_t vgaEntry(unsigned char uc, uint8_t color) { return (uint16_t) uc | (uint16_t) color << 8; } - -// vgaColorEntry() - Function returns a valid VGA color entry. -// Parameters: Two gfxColor enums, foreground color and background color -static inline uint8_t vgaColorEntry(enum gfxColor foreground, enum gfxColor background) { return foreground | background << 4; } - - -#endif \ No newline at end of file +// graphics.h - Header file for graphics.c +// Note that graphics.c and terminal.c are different. One houses the main code for anything graphics related(drawing, colors, etc) and the other handles console output and misc. other functions. +#ifndef GRAPHICS_H +#define GRAPHICS_H + +#include // Integer declarations +#include // Boolean declarations +#include // size_t declaration +#include // String functions + + +// Basic graphics definitions, like the video memory address +static uint16_t* const VIDEO_MEM = (uint16_t*) 0xB8000; +static size_t SCREEN_WIDTH = 80; +static size_t SCREEN_HEIGHT = 25; + +// Color enumerator. +enum gfxColor { + COLOR_BLACK = 0, + COLOR_BLUE = 1, + COLOR_GREEN = 2, + COLOR_CYAN = 3, + COLOR_RED = 4, + COLOR_MAGENTA = 5, + COLOR_BROWN = 6, + COLOR_LIGHT_GRAY = 7, + COLOR_DARK_GRAY = 8, + COLOR_LIGHT_BLUE = 9, + COLOR_LIGHT_GREEN = 10, + COLOR_LIGHT_CYAN = 11, + COLOR_LIGHT_RED = 12, + COLOR_LIGHT_MAGENTA = 13, + COLOR_YELLOW = 14, + COLOR_WHITE = 15 +}; + +// vgaEntry() - Functions returns a valid VGA character entry. +// Parameters: unsigned char uc and uint8_t color +static inline uint16_t vgaEntry(unsigned char uc, uint8_t color) { return (uint16_t) uc | (uint16_t) color << 8; } + +// vgaColorEntry() - Function returns a valid VGA color entry. +// Parameters: Two gfxColor enums, foreground color and background color +static inline uint8_t vgaColorEntry(enum gfxColor foreground, enum gfxColor background) { return foreground | background << 4; } + + +#endif diff --git a/source/kernel/include/hal.h b/source/kernel/include/hal.h index cd0cef46..320e9863 100644 --- a/source/kernel/include/hal.h +++ b/source/kernel/include/hal.h @@ -1,35 +1,35 @@ -// hal.h - Header file for the HAL.c file (Hardware Abstraction Layer) - -#ifndef HAL_H -#define HAL_H - - -// Includes -#include "include/idt.h" // Interrupt Descriptor Table -#include "include/pic.h" // Programmable Interrupt Controller -#include "include/pit.h" // Programmable interval Timer -#include "include/libc/stdint.h" // Integer declarations (like uint8_t, uint16_t, etc..) -#include "include/libc/stddef.h" // size_t declaration - -// Definitions - -#define far -#define near - -// Functions - -void setVector(int intNo, uint32_t vect); // Sets a new interrupt vector. -void interruptCompleted(uint32_t intNo); // Notifies HAL interrupt is done. -void enableHardwareInterrupts(); // Enable hardware interrupts -void disableHardwareInterrupts(); // Disable hardware interrupts -uint8_t inportb(uint16_t port); // Read data from a device using port mapped IO -void outportb(uint16_t port, uint8_t value); // Write data to a device using port mapped IO -uint16_t inportw(uint16_t port); // Read data from a device using port mapped IO -void outportw(uint16_t port, uint16_t data); // Write data to a device using port mapped IO -void __cpuid(uint32_t type, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx); // Returns an assembly cpuid instruction. -uint32_t inportl(uint16_t port); // Read data from a device via port mapped IO -void outportl(uint16_t port, uint32_t data); // Write data to a device via port mapped IO -size_t msb(size_t i); // Returns the most significant bit. -void setVector_flags(int intNo, uint32_t vect, int flags); // Sets a new interrupt vector using flags. - -#endif +// hal.h - Header file for the HAL.c file (Hardware Abstraction Layer) + +#ifndef HAL_H +#define HAL_H + + +// Includes +#include // Interrupt Descriptor Table +#include // Programmable Interrupt Controller +#include // Programmable interval Timer +#include // Integer declarations (like uint8_t, uint16_t, etc..) +#include // size_t declaration + +// Definitions + +#define far +#define near + +// Functions + +void setVector(int intNo, uint32_t vect); // Sets a new interrupt vector. +void interruptCompleted(uint32_t intNo); // Notifies HAL interrupt is done. +void enableHardwareInterrupts(); // Enable hardware interrupts +void disableHardwareInterrupts(); // Disable hardware interrupts +uint8_t inportb(uint16_t port); // Read data from a device using port mapped IO +void outportb(uint16_t port, uint8_t value); // Write data to a device using port mapped IO +uint16_t inportw(uint16_t port); // Read data from a device using port mapped IO +void outportw(uint16_t port, uint16_t data); // Write data to a device using port mapped IO +void __cpuid(uint32_t type, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx); // Returns an assembly cpuid instruction. +uint32_t inportl(uint16_t port); // Read data from a device via port mapped IO +void outportl(uint16_t port, uint32_t data); // Write data to a device via port mapped IO +size_t msb(size_t i); // Returns the most significant bit. +void setVector_flags(int intNo, uint32_t vect, int flags); // Sets a new interrupt vector using flags. + +#endif diff --git a/source/kernel/include/hashmap.h b/source/kernel/include/hashmap.h index 2ba2fa72..037dabdd 100644 --- a/source/kernel/include/hashmap.h +++ b/source/kernel/include/hashmap.h @@ -1,8 +1,8 @@ // hashmap.h - Authored by klange, I deserve no credit. License information in misc/hashmap.c #include -#include "include/libc/string.h" -#include "include/list.h" +#include +#include typedef unsigned int (*hashmap_hash_t) (const void * key); @@ -39,4 +39,4 @@ extern void hashmap_free(hashmap_t * map); extern unsigned int hashmap_string_hash(const void * key); extern int hashmap_string_comp(const void * a, const void * b); extern void * hashmap_string_dupe(const void * key); -extern int hashmap_is_empty(hashmap_t * map); \ No newline at end of file +extern int hashmap_is_empty(hashmap_t * map); diff --git a/source/kernel/include/heap.h b/source/kernel/include/heap.h index f96e778b..755b25aa 100644 --- a/source/kernel/include/heap.h +++ b/source/kernel/include/heap.h @@ -1,2 +1,2 @@ // heap.h - Kept for legacy code compatibility, will be removed. -#include "include/liballoc_forwarder.h" +#include diff --git a/source/kernel/include/ide_ata.h b/source/kernel/include/ide_ata.h index af38deac..b94dd4d1 100644 --- a/source/kernel/include/ide_ata.h +++ b/source/kernel/include/ide_ata.h @@ -1,149 +1,149 @@ -// ide_ata.h - header file for the PCI IDE controller - -#ifndef IDE_ATA__H -#define IDE_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/hal.h" // Hardware abstraction layer -#include "include/isr.h" // IRQ handling -#include "include/vfs.h" // Virtual File System -#include "include/libc/sleep.h" // Sleep function - - -// Definitions - -// Status port bit masks -#define ATA_STATUS_BSY 0x80 // Busy -#define ATA_STATUS_DRDY 0x40 // Drive ready -#define ATA_STATUS_DF 0x20 // Drive write fault -#define ATA_STATUS_DSC 0x10 // Drive seek complete -#define ATA_STATUS_DRQ 0x08 // Data request ready -#define ATA_STATUS_CORR 0x04 // Corrected data -#define ATA_STATUS_IDX 0x02 // Index -#define ATA_STATUS_ERR 0x01 // Error - - -// Error register bits -#define ERR_AMNF 0x01 // Address mark not found. -#define ERR_TKZNF 0x02 // Track zero not found. -#define ERR_ABRT 0x04 // Aborted command. -#define ERR_MCR 0x08 // Media change request. -#define ERR_IDNF 0x10 // ID not found -#define ERR_MC 0x20 // Media changed. -#define ERR_UNC 0x40 // Unrecoverable data error. -#define ERR_BBK 0x80 // Bad block. - -// IDE commands (https://wiki.osdev.org/PCI_IDE_Controller) -#define ATA_READ_PIO 0x20 -#define ATA_READ_PIO_EXT 0x24 -#define ATA_READ_DMA 0xC8 -#define ATA_READ_DMA_EXT 0x25 -#define ATA_WRITE_PIO 0x30 -#define ATA_WRITE_PIO_EXT 0x34 -#define ATA_WRITE_DMA 0xCA -#define ATA_WRITE_DMA_EXT 0x35 -#define ATA_CACHE_FLUSH 0xE7 -#define ATA_CACHE_FLUSH_EXT 0xEA -#define ATA_PACKET 0xA0 -#define ATA_IDENTIFY_PACKET 0xA1 -#define ATA_IDENTIFY 0xEC - -// ATAPI-specific commands -#define ATAPI_READ 0xA8 -#define ATAPI_EJECT 0x18 - -// Identification space information (identification space is the buffer of 512 bytes returned by ATA_IDENTIFY_PACKET and ATA_IDENTIFY) -#define ATA_IDENT_DEVICETYPE 0 -#define ATA_IDENT_CYLINDERS 2 -#define ATA_IDENT_HEADS 6 -#define ATA_IDENT_SECTORS 12 -#define ATA_IDENT_SERIAL 20 -#define ATA_IDENT_MODEL 54 -#define ATA_IDENT_CAPABILITIES 98 -#define ATA_IDENT_FIELDVALID 106 -#define ATA_IDENT_MAX_LBA 120 -#define ATA_IDENT_COMMANDSETS 164 -#define ATA_IDENT_MAX_LBA_EXT 200 - - -// IDE/ATA interface types -#define IDE_ATA 0x00 -#define IDE_ATAPI 0x01 - -#define ATA_MASTER 0x00 -#define ATA_SLAVE 0x01 - -// ATA registers -#define ATA_REG_DATA 0x00 -#define ATA_REG_ERROR 0x01 -#define ATA_REG_FEATURES 0x01 -#define ATA_REG_SECCOUNT0 0x02 -#define ATA_REG_LBA0 0x03 -#define ATA_REG_LBA1 0x04 -#define ATA_REG_LBA2 0x05 -#define ATA_REG_HDDEVSEL 0x06 -#define ATA_REG_COMMAND 0x07 -#define ATA_REG_STATUS 0x07 -#define ATA_REG_SECCOUNT1 0x08 -#define ATA_REG_LBA3 0x09 -#define ATA_REG_LBA4 0x0A -#define ATA_REG_LBA5 0x0B -#define ATA_REG_CONTROL 0x0C -#define ATA_REG_ALTSTATUS 0x0C -#define ATA_REG_DEVADDRESS 0x0D - -// ATA channels -#define ATA_PRIMARY 0x00 -#define ATA_SECONDARY 0x01 - -// ATA directions -#define ATA_READ 0x00 -#define ATA_WRITE 0x01 - -// Errors (Needs to be fixed because weird return values can happen) -#define IDE_OK 0 -#define IDE_DRIVE_NOT_FOUND -1 -#define IDE_LBA_INVALID -2 - -// Typedefs - -// IDE channel registers -typedef struct { - uint16_t ioBase; // IO base - uint16_t controlBase; // Control base - uint16_t busMasterIDE; // Bus master IDE - uint8_t nIEN; // nIEN (no interrupt) -} ideChannelRegisters_t; - - -typedef struct { - uint8_t reserved; // Defines whether the drive realy exists (non-zero if it does) - uint8_t channel; // Defines whether the drive is primary channel or secondary (non-zero if secondary) - uint8_t drive; // Defines whether the drive is a master drive or a slave drive (non-zero if slave) - uint16_t type; // Defines what the drive is (non-zero if ATAPI) - uint16_t signature; // Drive signature - uint16_t features; // Drive features - uint32_t commandSets; // Command sets supported - uint32_t size; // Size (in sectors) - uint8_t model[41]; // Drive model. -} ideDevice_t; - -// Functions -uint8_t ideRead(uint8_t channel, uint8_t reg); // Reads in a register -void ideWrite(uint8_t channel, uint8_t reg, uint8_t data); // Writes to a register -void ideReadBuffer(uint8_t channel, uint8_t reg, uint32_t *buffer, uint32_t quads); // Reads the identification space and copies it to a buffer. -void insl(uint16_t reg, uint32_t *buffer, int quads); // Reads a long word from a register port for quads times. -void outsl(uint16_t reg, uint32_t *buffer, int quads); // Writes a long word to a register port for quads times -uint8_t idePolling(uint8_t channel, uint32_t advancedCheck); // Returns whether there was an error. -uint8_t idePrintErrors(uint32_t drive, uint8_t err); // Prints the errors that may have occurred. -void ideInit(uint32_t bar0, uint32_t bar1, uint32_t bar2, uint32_t bar3, uint32_t bar4); // Initialize IDE drives. -void printIDESummary(); // Print a summary of all IDE drives found. -uint8_t ideAccessATA(uint8_t direction, uint8_t drive, uint64_t lba, uint8_t sectorNum, uint32_t edi); // Access an ATA drive (direction specifies what operation to perform) -uint8_t ideReadATAPI(uint8_t drive, uint32_t lba, uint8_t sectorNum, uint32_t edi); // Read from an ATAPI drive. -int ideReadSectors(uint8_t drive, uint8_t sectorNum, uint64_t lba, uint32_t edi); // Read from an ATA/ATAPI drive. -int ideWriteSectors(uint8_t drive, uint8_t sectorNum, uint32_t lba, uint32_t edi); // Write to an ATA drive. -int ideGetDriveCapacity(uint8_t drive); // Returns drive capacity -uint32_t ideRead_vfs(struct fsNode *node, off_t off, uint32_t size, uint8_t *buffer); // Read function for the VFS -uint32_t ideWrite_vfs(struct fsNode *node, off_t off, uint32_t size, uint8_t *buffer); // Write function in the VFS -#endif \ No newline at end of file +// ide_ata.h - header file for the PCI IDE controller + +#ifndef IDE_ATA__H +#define IDE_H + +// Includes +#include // Integer declarations +#include // Hardware abstraction layer +#include // IRQ handling +#include // Virtual File System +#include // Sleep function + + +// Definitions + +// Status port bit masks +#define ATA_STATUS_BSY 0x80 // Busy +#define ATA_STATUS_DRDY 0x40 // Drive ready +#define ATA_STATUS_DF 0x20 // Drive write fault +#define ATA_STATUS_DSC 0x10 // Drive seek complete +#define ATA_STATUS_DRQ 0x08 // Data request ready +#define ATA_STATUS_CORR 0x04 // Corrected data +#define ATA_STATUS_IDX 0x02 // Index +#define ATA_STATUS_ERR 0x01 // Error + + +// Error register bits +#define ERR_AMNF 0x01 // Address mark not found. +#define ERR_TKZNF 0x02 // Track zero not found. +#define ERR_ABRT 0x04 // Aborted command. +#define ERR_MCR 0x08 // Media change request. +#define ERR_IDNF 0x10 // ID not found +#define ERR_MC 0x20 // Media changed. +#define ERR_UNC 0x40 // Unrecoverable data error. +#define ERR_BBK 0x80 // Bad block. + +// IDE commands (https://wiki.osdev.org/PCI_IDE_Controller) +#define ATA_READ_PIO 0x20 +#define ATA_READ_PIO_EXT 0x24 +#define ATA_READ_DMA 0xC8 +#define ATA_READ_DMA_EXT 0x25 +#define ATA_WRITE_PIO 0x30 +#define ATA_WRITE_PIO_EXT 0x34 +#define ATA_WRITE_DMA 0xCA +#define ATA_WRITE_DMA_EXT 0x35 +#define ATA_CACHE_FLUSH 0xE7 +#define ATA_CACHE_FLUSH_EXT 0xEA +#define ATA_PACKET 0xA0 +#define ATA_IDENTIFY_PACKET 0xA1 +#define ATA_IDENTIFY 0xEC + +// ATAPI-specific commands +#define ATAPI_READ 0xA8 +#define ATAPI_EJECT 0x18 + +// Identification space information (identification space is the buffer of 512 bytes returned by ATA_IDENTIFY_PACKET and ATA_IDENTIFY) +#define ATA_IDENT_DEVICETYPE 0 +#define ATA_IDENT_CYLINDERS 2 +#define ATA_IDENT_HEADS 6 +#define ATA_IDENT_SECTORS 12 +#define ATA_IDENT_SERIAL 20 +#define ATA_IDENT_MODEL 54 +#define ATA_IDENT_CAPABILITIES 98 +#define ATA_IDENT_FIELDVALID 106 +#define ATA_IDENT_MAX_LBA 120 +#define ATA_IDENT_COMMANDSETS 164 +#define ATA_IDENT_MAX_LBA_EXT 200 + + +// IDE/ATA interface types +#define IDE_ATA 0x00 +#define IDE_ATAPI 0x01 + +#define ATA_MASTER 0x00 +#define ATA_SLAVE 0x01 + +// ATA registers +#define ATA_REG_DATA 0x00 +#define ATA_REG_ERROR 0x01 +#define ATA_REG_FEATURES 0x01 +#define ATA_REG_SECCOUNT0 0x02 +#define ATA_REG_LBA0 0x03 +#define ATA_REG_LBA1 0x04 +#define ATA_REG_LBA2 0x05 +#define ATA_REG_HDDEVSEL 0x06 +#define ATA_REG_COMMAND 0x07 +#define ATA_REG_STATUS 0x07 +#define ATA_REG_SECCOUNT1 0x08 +#define ATA_REG_LBA3 0x09 +#define ATA_REG_LBA4 0x0A +#define ATA_REG_LBA5 0x0B +#define ATA_REG_CONTROL 0x0C +#define ATA_REG_ALTSTATUS 0x0C +#define ATA_REG_DEVADDRESS 0x0D + +// ATA channels +#define ATA_PRIMARY 0x00 +#define ATA_SECONDARY 0x01 + +// ATA directions +#define ATA_READ 0x00 +#define ATA_WRITE 0x01 + +// Errors (Needs to be fixed because weird return values can happen) +#define IDE_OK 0 +#define IDE_DRIVE_NOT_FOUND -1 +#define IDE_LBA_INVALID -2 + +// Typedefs + +// IDE channel registers +typedef struct { + uint16_t ioBase; // IO base + uint16_t controlBase; // Control base + uint16_t busMasterIDE; // Bus master IDE + uint8_t nIEN; // nIEN (no interrupt) +} ideChannelRegisters_t; + + +typedef struct { + uint8_t reserved; // Defines whether the drive realy exists (non-zero if it does) + uint8_t channel; // Defines whether the drive is primary channel or secondary (non-zero if secondary) + uint8_t drive; // Defines whether the drive is a master drive or a slave drive (non-zero if slave) + uint16_t type; // Defines what the drive is (non-zero if ATAPI) + uint16_t signature; // Drive signature + uint16_t features; // Drive features + uint32_t commandSets; // Command sets supported + uint32_t size; // Size (in sectors) + uint8_t model[41]; // Drive model. +} ideDevice_t; + +// Functions +uint8_t ideRead(uint8_t channel, uint8_t reg); // Reads in a register +void ideWrite(uint8_t channel, uint8_t reg, uint8_t data); // Writes to a register +void ideReadBuffer(uint8_t channel, uint8_t reg, uint32_t *buffer, uint32_t quads); // Reads the identification space and copies it to a buffer. +void insl(uint16_t reg, uint32_t *buffer, int quads); // Reads a long word from a register port for quads times. +void outsl(uint16_t reg, uint32_t *buffer, int quads); // Writes a long word to a register port for quads times +uint8_t idePolling(uint8_t channel, uint32_t advancedCheck); // Returns whether there was an error. +uint8_t idePrintErrors(uint32_t drive, uint8_t err); // Prints the errors that may have occurred. +void ideInit(uint32_t bar0, uint32_t bar1, uint32_t bar2, uint32_t bar3, uint32_t bar4); // Initialize IDE drives. +void printIDESummary(); // Print a summary of all IDE drives found. +uint8_t ideAccessATA(uint8_t direction, uint8_t drive, uint64_t lba, uint8_t sectorNum, uint32_t edi); // Access an ATA drive (direction specifies what operation to perform) +uint8_t ideReadATAPI(uint8_t drive, uint32_t lba, uint8_t sectorNum, uint32_t edi); // Read from an ATAPI drive. +int ideReadSectors(uint8_t drive, uint8_t sectorNum, uint64_t lba, uint32_t edi); // Read from an ATA/ATAPI drive. +int ideWriteSectors(uint8_t drive, uint8_t sectorNum, uint32_t lba, uint32_t edi); // Write to an ATA drive. +int ideGetDriveCapacity(uint8_t drive); // Returns drive capacity +uint32_t ideRead_vfs(struct fsNode *node, off_t off, uint32_t size, uint8_t *buffer); // Read function for the VFS +uint32_t ideWrite_vfs(struct fsNode *node, off_t off, uint32_t size, uint8_t *buffer); // Write function in the VFS +#endif diff --git a/source/kernel/include/idt.h b/source/kernel/include/idt.h index 7f6d1404..8725f197 100644 --- a/source/kernel/include/idt.h +++ b/source/kernel/include/idt.h @@ -1,57 +1,57 @@ -// idt.h - IDT header file, contains includes/declarations for the idt.c file. - -#ifndef IDT_H -#define IDT_H - -// Includes -#include "include/libc/stddef.h" // size_t declaration -#include "include/libc/stdint.h" // Integer type declarations -#include "include/libc/stdbool.h" // Boolean declarations -#include "include/libc/string.h" // String functions -#include "include/libc/limits.h" // Limits on integers and more. -#include "include/libc/stdarg.h" // va argument handling (for ... on printf) -#include "include/libc/va_list.h" // va_list declared here. -#include "include/terminal.h" // printf() and other terminal functions - -// Definitions - -#define I86_MAX_INTERRUPTS 256 // 256 maximum interrupts - -// These must be in the format 0D110 where D is the descriptor type -#define I86_IDT_DESC_BIT16 0x06 // 00000110 -#define I86_IDT_DESC_BIT32 0x0E // 00001110 -#define I86_IDT_DESC_RING1 0x40 // 01000000 -#define I86_IDT_DESC_RING2 0x20 // 00100000 -#define I86_IDT_DESC_RING3 0x60 // 01100000 -#define I86_IDT_DESC_PRESENT 0x80 // 10000000 - - -// Typedefs - -typedef void (*IDT_IRQ_HANDLER)(void); // Interrupt handler without an error code. Interrupt handlers are called by the processor. Since the stack setup may change, we leave it up to the interrupts' implementation to handle it and properly return. - -typedef struct { - uint16_t baseLow; // Lower 16 bits (0-15) of the interrupt routine address (address to jump when interrupt fires.) - uint16_t segmentSelector; // Code segment selector in GDT - uint8_t reserved; // Reserved. Should be 0. - uint8_t flags; // Bit flags. - uint16_t baseHigh; // Higher 16 bits (16-31) of the interrupt routine address (see baseLow) -} __attribute__((packed)) idtEntry_t; - -typedef struct { - uint16_t limit; // size of the IDT - uint32_t base_addr; // base address of the IDT -} __attribute__((packed)) idtPtr_t; - - - - -// Functions - - -extern int idtInstallIR(uint8_t i, uint8_t flags, uint16_t segmentSelector, uint32_t base); // Installs interrupt handler. When INT is fired, it calls this -extern void idtInit(); // Initializes basic IDT. - - - -#endif \ No newline at end of file +// idt.h - IDT header file, contains includes/declarations for the idt.c file. + +#ifndef IDT_H +#define IDT_H + +// Includes +#include // size_t declaration +#include // Integer type declarations +#include // Boolean declarations +#include // String functions +#include // Limits on integers and more. +#include // va argument handling (for ... on printf) +#include // va_list declared here. +#include // printf() and other terminal functions + +// Definitions + +#define I86_MAX_INTERRUPTS 256 // 256 maximum interrupts + +// These must be in the format 0D110 where D is the descriptor type +#define I86_IDT_DESC_BIT16 0x06 // 00000110 +#define I86_IDT_DESC_BIT32 0x0E // 00001110 +#define I86_IDT_DESC_RING1 0x40 // 01000000 +#define I86_IDT_DESC_RING2 0x20 // 00100000 +#define I86_IDT_DESC_RING3 0x60 // 01100000 +#define I86_IDT_DESC_PRESENT 0x80 // 10000000 + + +// Typedefs + +typedef void (*IDT_IRQ_HANDLER)(void); // Interrupt handler without an error code. Interrupt handlers are called by the processor. Since the stack setup may change, we leave it up to the interrupts' implementation to handle it and properly return. + +typedef struct { + uint16_t baseLow; // Lower 16 bits (0-15) of the interrupt routine address (address to jump when interrupt fires.) + uint16_t segmentSelector; // Code segment selector in GDT + uint8_t reserved; // Reserved. Should be 0. + uint8_t flags; // Bit flags. + uint16_t baseHigh; // Higher 16 bits (16-31) of the interrupt routine address (see baseLow) +} __attribute__((packed)) idtEntry_t; + +typedef struct { + uint16_t limit; // size of the IDT + uint32_t base_addr; // base address of the IDT +} __attribute__((packed)) idtPtr_t; + + + + +// Functions + + +extern int idtInstallIR(uint8_t i, uint8_t flags, uint16_t segmentSelector, uint32_t base); // Installs interrupt handler. When INT is fired, it calls this +extern void idtInit(); // Initializes basic IDT. + + + +#endif diff --git a/source/kernel/include/initrd.h b/source/kernel/include/initrd.h index 30a9e4dc..5688981b 100644 --- a/source/kernel/include/initrd.h +++ b/source/kernel/include/initrd.h @@ -1,38 +1,38 @@ -// initrd.h - header file for initrd.c (manages the initial ramdisk) - -#ifndef INITRD_H -#define INITRD_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/libc/string.h" // String functions -#include "include/vfs.h" // Virtual File System definitions -#include "include/terminal.h" // printf() - -// Typedefs - -// Image header -typedef struct { - uint32_t fileAmnt; // Number of files in the ramdisk. -} initrd_imageHeader_t; - -// File header -typedef struct { - uint8_t magic; // Magic number (used for error checking, should be 0xBF) - int8_t name[64]; // Filename. - uint32_t offset; // Offset in the ramdisk where the file starts. - uint32_t length; // File length. -} initrd_fileHeader_t; - -// Subdirectory structure -typedef struct { - uint8_t magic; // Magic number (should be 0xBA) - int8_t name; - uint8_t fileMagic; // File magic number (see initrdInit()) -} initrd_subdirectoryHeader_t; - -// Function (there's just one lol): -fsNode_t *initrdInit(uint32_t location); // Loads initrd by defining pointers, setting values, etc. - - -#endif \ No newline at end of file +// initrd.h - header file for initrd.c (manages the initial ramdisk) + +#ifndef INITRD_H +#define INITRD_H + +// Includes +#include // Integer declarations +#include // String functions +#include // Virtual File System definitions +#include // printf() + +// Typedefs + +// Image header +typedef struct { + uint32_t fileAmnt; // Number of files in the ramdisk. +} initrd_imageHeader_t; + +// File header +typedef struct { + uint8_t magic; // Magic number (used for error checking, should be 0xBF) + int8_t name[64]; // Filename. + uint32_t offset; // Offset in the ramdisk where the file starts. + uint32_t length; // File length. +} initrd_fileHeader_t; + +// Subdirectory structure +typedef struct { + uint8_t magic; // Magic number (should be 0xBA) + int8_t name; + uint8_t fileMagic; // File magic number (see initrdInit()) +} initrd_subdirectoryHeader_t; + +// Function (there's just one lol): +fsNode_t *initrdInit(uint32_t location); // Loads initrd by defining pointers, setting values, etc. + + +#endif diff --git a/source/kernel/include/io_apic.h b/source/kernel/include/io_apic.h index 34fac100..39e115e8 100644 --- a/source/kernel/include/io_apic.h +++ b/source/kernel/include/io_apic.h @@ -1,25 +1,25 @@ -// io_apic.h - header file for io_apic.c - -#ifndef IO_APIC_H -#define IO_APIC_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations - -// Definitions - -// Registers for the IO APIC (memory mapped) -#define IO_APIC_REGSEL 0x00 -#define IO_APIC_WIN 0x10 - -// Registers for the IO APIC -#define IO_APIC_ID 0x00 -#define IO_APIC_VER 0x01 -#define IO_APIC_ARB 0x02 -#define IO_APIC_REDTBL 0x10 - -// Functions -void ioAPIC_setEntry(uint8_t *base, uint8_t index, uint64_t data); // Set an entry in the IO APIC. -void ioAPIC_init(); // Initialize the IO APIC. - -#endif \ No newline at end of file +// io_apic.h - header file for io_apic.c + +#ifndef IO_APIC_H +#define IO_APIC_H + +// Includes +#include // Integer declarations + +// Definitions + +// Registers for the IO APIC (memory mapped) +#define IO_APIC_REGSEL 0x00 +#define IO_APIC_WIN 0x10 + +// Registers for the IO APIC +#define IO_APIC_ID 0x00 +#define IO_APIC_VER 0x01 +#define IO_APIC_ARB 0x02 +#define IO_APIC_REDTBL 0x10 + +// Functions +void ioAPIC_setEntry(uint8_t *base, uint8_t index, uint64_t data); // Set an entry in the IO APIC. +void ioAPIC_init(); // Initialize the IO APIC. + +#endif diff --git a/source/kernel/include/isr.h b/source/kernel/include/isr.h index 4a517d5f..911fbe94 100644 --- a/source/kernel/include/isr.h +++ b/source/kernel/include/isr.h @@ -1,140 +1,140 @@ -// isr.h - header file for isr.c -// ISR - Interrupt Service Routines - -#ifndef ISR_H -#define ISR_H - -// Includes - -#include "include/libc/stdint.h" // Integer declarations like uint8_t, int16_t, etc. -#include "include/hal.h" // Some misc functions for interrupts. - - -#include "include/panic.h" // Kernel panicking. Used on i86DefaultHandler. -#include "include/regs.h" // registers_t typedef - -// Definitions - -// IRQ default constants -#define IRQ_BASE 0x20 // Base IRQ -#define IRQ0_TIMER 0x00 // Timer IRQ -#define IRQ1_KEYBOARD 0x01 // Keyboard IRQ -#define IRQ2_CASCADE 0x02 // Cascade IRQ -#define IRQ3_SERIAL_PORT2 0x03 // Serial 2 IRQ -#define IRQ4_SERIAL_PORT1 0x04 // Serial 1 IRQ -#define IRQ5_RESERVED 0x05 // Reserved -#define IRQ6_DISKETTE_DRIVE 0x06 // Disk drive IRQ -#define IRQ7_PARALLEL_PORT 0x07 // Parallel IRQ -#define IRQ8_CMOS_CLOCK 0x08 // CMOS IRQ -#define IRQ9_CGA 0x09 // CGA graphics IRQ -#define IRQ10_RESERVED 0x0A // Reserved -#define IRQ11_RESERVED 0x0B // Reserved -#define IRQ12_AUXILIARY 0x0C // Auxilary IRQ -#define IRQ13_FPU 0x0D // FPU IRQ -#define IRQ14_HARD_DISK 0x0E // HDD IRQ -#define IRQ15_RESERVED 0x0F // Reserved - - - -// Typedefs - -typedef void (*ISR)(registers_t *); - -// Variable definitions - -static char *exception_messages[32] = { - "Division by zero", - "Debug", - "Non-maskable interrupt", - "Breakpoint", - "Overflow", - "Bound range exceeded", - "Invalid opcode", - "Device not available (no math coprocessor)", - "Double fault", - "Coprocessor segment overrun", - "Invalid TSS", - "Segment not present", - "Stack-segment fault", - "General protection", - "Page fault", - "Unknown interrupt (intel reserved)", - "x87 FPU floating-point error (math fault)", - "Alignment check", - "Machine check", - "SIMD floating-point exception", - "Virtualization exception", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved" -}; - - - -// External declarations -extern void isr0(); -extern void isr1(); -extern void isr2(); -extern void isr3(); -extern void isr4(); -extern void isr5(); -extern void isr6(); -extern void isr7(); -extern void isr8(); -extern void isr9(); -extern void isr10(); -extern void isr11(); -extern void isr12(); -extern void isr13(); -extern void isr14(); -extern void isr15(); -extern void isr16(); -extern void isr17(); -extern void isr18(); -extern void isr19(); -extern void isr20(); -extern void isr21(); -extern void isr22(); -extern void isr23(); -extern void isr24(); -extern void isr25(); -extern void isr26(); -extern void isr27(); -extern void isr28(); -extern void isr29(); -extern void isr30(); -extern void isr31(); -extern void isr128(); - -extern void irq_0(); -extern void irq_1(); -extern void irq_2(); -extern void irq_3(); -extern void irq_4(); -extern void irq_5(); -extern void irq_6(); -extern void irq_7(); -extern void irq_8(); -extern void irq_9(); -extern void irq_10(); -extern void irq_11(); -extern void irq_12(); -extern void irq_13(); -extern void irq_14(); -extern void irq_15(); - -// Functions - -void isrRegisterInterruptHandler(int num, ISR handler); // Registers an interrupt handler -void isrEndInterrupt(int num); // Ends an interrupt. -void isrInstall(); // Installs ISR - -#endif \ No newline at end of file +// isr.h - header file for isr.c +// ISR - Interrupt Service Routines + +#ifndef ISR_H +#define ISR_H + +// Includes + +#include // Integer declarations like uint8_t, int16_t, etc. +#include // Some misc functions for interrupts. + + +#include // Kernel panicking. Used on i86DefaultHandler. +#include // registers_t typedef + +// Definitions + +// IRQ default constants +#define IRQ_BASE 0x20 // Base IRQ +#define IRQ0_TIMER 0x00 // Timer IRQ +#define IRQ1_KEYBOARD 0x01 // Keyboard IRQ +#define IRQ2_CASCADE 0x02 // Cascade IRQ +#define IRQ3_SERIAL_PORT2 0x03 // Serial 2 IRQ +#define IRQ4_SERIAL_PORT1 0x04 // Serial 1 IRQ +#define IRQ5_RESERVED 0x05 // Reserved +#define IRQ6_DISKETTE_DRIVE 0x06 // Disk drive IRQ +#define IRQ7_PARALLEL_PORT 0x07 // Parallel IRQ +#define IRQ8_CMOS_CLOCK 0x08 // CMOS IRQ +#define IRQ9_CGA 0x09 // CGA graphics IRQ +#define IRQ10_RESERVED 0x0A // Reserved +#define IRQ11_RESERVED 0x0B // Reserved +#define IRQ12_AUXILIARY 0x0C // Auxilary IRQ +#define IRQ13_FPU 0x0D // FPU IRQ +#define IRQ14_HARD_DISK 0x0E // HDD IRQ +#define IRQ15_RESERVED 0x0F // Reserved + + + +// Typedefs + +typedef void (*ISR)(registers_t *); + +// Variable definitions + +static char *exception_messages[32] = { + "Division by zero", + "Debug", + "Non-maskable interrupt", + "Breakpoint", + "Overflow", + "Bound range exceeded", + "Invalid opcode", + "Device not available (no math coprocessor)", + "Double fault", + "Coprocessor segment overrun", + "Invalid TSS", + "Segment not present", + "Stack-segment fault", + "General protection", + "Page fault", + "Unknown interrupt (intel reserved)", + "x87 FPU floating-point error (math fault)", + "Alignment check", + "Machine check", + "SIMD floating-point exception", + "Virtualization exception", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved" +}; + + + +// External declarations +extern void isr0(); +extern void isr1(); +extern void isr2(); +extern void isr3(); +extern void isr4(); +extern void isr5(); +extern void isr6(); +extern void isr7(); +extern void isr8(); +extern void isr9(); +extern void isr10(); +extern void isr11(); +extern void isr12(); +extern void isr13(); +extern void isr14(); +extern void isr15(); +extern void isr16(); +extern void isr17(); +extern void isr18(); +extern void isr19(); +extern void isr20(); +extern void isr21(); +extern void isr22(); +extern void isr23(); +extern void isr24(); +extern void isr25(); +extern void isr26(); +extern void isr27(); +extern void isr28(); +extern void isr29(); +extern void isr30(); +extern void isr31(); +extern void isr128(); + +extern void irq_0(); +extern void irq_1(); +extern void irq_2(); +extern void irq_3(); +extern void irq_4(); +extern void irq_5(); +extern void irq_6(); +extern void irq_7(); +extern void irq_8(); +extern void irq_9(); +extern void irq_10(); +extern void irq_11(); +extern void irq_12(); +extern void irq_13(); +extern void irq_14(); +extern void irq_15(); + +// Functions + +void isrRegisterInterruptHandler(int num, ISR handler); // Registers an interrupt handler +void isrEndInterrupt(int num); // Ends an interrupt. +void isrInstall(); // Installs ISR + +#endif diff --git a/source/kernel/include/kernel.h b/source/kernel/include/kernel.h index 08bade4c..2669259a 100644 --- a/source/kernel/include/kernel.h +++ b/source/kernel/include/kernel.h @@ -1,43 +1,43 @@ -// kernel.h - Includes and function declarations for the kernel - -#ifndef KERNEL_H -#define KERNEL_H - -// Includes -#include "include/libc/stddef.h" // size_t declaration -#include "include/libc/stdint.h" // Integer type declarations -#include "include/libc/stdbool.h" // Boolean declarations -#include "include/libc/string.h" // String functions -#include "include/libc/limits.h" // Limits on integers and more. -#include "include/libc/stdarg.h" // va argument handling (for ... on printf) -#include "include/libc/va_list.h" // va_list declared here. -#include "include/libc/assert.h" // Assertion macro -#include "include/libc/udivdi3.h" // udivdi3 -#include "include/libc/sleep.h" // Sleeping -#include "include/graphics.h" // Graphics handling -#include "include/terminal.h" // Terminal handling -#include "include/idt.h" // Interrupt Descriptor Table -#include "include/gdt.h" // Global Descriptor Table -#include "include/pic.h" // Programmable Interrupt Controller -#include "include/pit.h" // Programmable Interval Timer -#include "include/hal.h" // Hardware Abstraction Layer -#include "include/keyboard.h" // Keyboard driver -#include "include/panic.h" // Kernel panicking -#include "include/bootinfo.h" // Boot information -#include "include/command.h" // Command parser -#include "include/pci.h" // PCI driver -#include "include/serial.h" // Serial logging -#include "include/initrd.h" // Initial ramdisk management. -#include "include/vfs.h" // Virtual file system. -#include "include/ide_ata.h" // ATA driver -#include "include/rtc.h" // Real-time clock. -#include "include/bios32.h" // BIOS32 calls -#include "include/processor.h" // Procesor handler -#include "include/vesa.h" // VESA VBE graphics driver -#include "include/syscall.h" // System call -#include "include/bitmap.h" // Bitmap image controls -#include "include/CONFIG.h" // reduceOS configuration -#include "include/floppy.h" // FDC driver -#include "include/test.h" // Test command - -#endif \ No newline at end of file +// kernel.h - Includes and function declarations for the kernel + +#ifndef KERNEL_H +#define KERNEL_H + +// Includes +#include // size_t declaration +#include // Integer type declarations +#include // Boolean declarations +#include // String functions +#include // Limits on integers and more. +#include // va argument handling (for ... on printf) +#include // va_list declared here. +#include // Assertion macro +#include // udivdi3 +#include // Sleeping +#include // Graphics handling +#include // Terminal handling +#include // Interrupt Descriptor Table +#include // Global Descriptor Table +#include // Programmable Interrupt Controller +#include // Programmable Interval Timer +#include // Hardware Abstraction Layer +#include // Keyboard driver +#include // Kernel panicking +#include // Boot information +#include // Command parser +#include // PCI driver +#include // Serial logging +#include // Initial ramdisk management. +#include // Virtual file system. +#include // ATA driver +#include // Real-time clock. +#include // BIOS32 calls +#include // Procesor handler +#include // VESA VBE graphics driver +#include // System call +#include // Bitmap image controls +#include // reduceOS configuration +#include // FDC driver +#include // Test command + +#endif diff --git a/source/kernel/include/keyboard.h b/source/kernel/include/keyboard.h index 4ca36550..6d401852 100644 --- a/source/kernel/include/keyboard.h +++ b/source/kernel/include/keyboard.h @@ -1,87 +1,87 @@ -// keyboard.h - header file for keyboard.c, the keyboard driver - -#ifndef KEYBOARD_H -#define KEYBOARD_H - - -// Includes -#include "include/libc/stdint.h" // Integer declarations like uint8_t, etc. -#include "include/libc/string.h" // String functions -#include "include/libc/stdbool.h" // Booleans - -#include "include/isr.h" // Interrupt Service Routines -#include "include/terminal.h" // Terminal functions like printf. -#include "include/panic.h" // Register declarations -#include "include/heap.h" // Heap declarations (for allocating memory) - -// Definitions - -#define SCANCODE_ESC 0x01 -#define SCANCODE_BACKSPACE 0x0E -#define SCANCODE_ENTER 0x1C -#define SCANCODE_CTRL 0x1D // CTRL key is special (along with a few others) - The keyboard signifies left or right control based on whether the extended byte (E0) was sent first. We don't take into account extended bit - we don't need to! There is no difference between right and left control (the kb handler picks both up!) -#define SCANCODE_LEFTSHIFT 0x2A -#define SCANCODE_RIGHTSHIFT 0x36 -#define SCANCODE_ALT 0x38 -#define SCANCODE_CAPSLOCK 0x3A -#define SCANCODE_F1 0x3B -#define SCANCODE_F2 0x3C -#define SCANCODE_F3 0x3D -#define SCANCODE_F4 0x3E -#define SCANCODE_F5 0x3F -#define SCANCODE_F6 0x40 -#define SCANCODE_F7 0x41 -#define SCANCODE_F8 0x42 -#define SCANCODE_F9 0x43 -#define SCANCODE_F10 0x44 -#define SCANCODE_NUMLOCK 0x45 -#define SCANCODE_SCROLL_LOCK 0x46 -#define SCANCODE_HOME 0x47 -#define SCANCODE_UP 0x18 -#define SCANCODE_PGUP 0x49 -#define SCANCODE_DOWN 0x19 -#define SCANCODE_PGDOWN 0x51 -#define SCANCODE_LEFT 0x38 -#define SCANCODE_RIGHT 0x45 -#define SCANCODE_F11 0x57 -#define SCANCODE_F12 0x58 -#define SCANCODE_TAB 0x0F -#define SCANCODE_SPACE 0x39 -#define SCANCODE_EXTENDEDBYTE 0xE0 - -#define MAX_BUFFER_CHARS 500 // We can hold about 500 chars - this is a hard limit (as of now). TODO: Possibly, if it turns out we do need to have 500 chars as a hard limit, add a speaker beep that will notify the user when the buffer is overflowing. - - - - -// Typedefs - -typedef enum scancodes_special { - DETECTION_ERROR = 0x00, // This can also mean an internal buffer overrun - SELF_TEST_PASS = 0xAA, // Sent after reset (0xFF) command, or kb power up. - ECHO_RESP = 0xEE, // Sent after echo command (0xEE) - CMD_ACK = 0xFA, // Sent when a command is acknowledged. - SELF_TEST_FAIL1 = 0xFC, // Sent when the keyboard fails a self test. Sent after reset (0xFF) command or kb power up. Note there are two possible values sent. - SELF_TEST_FAIL2 = 0xFD, - RESEND_CMD = 0xFE, // Keyboard wants control or to repeat last command - DETECTION_ERROR2 = 0xFF // Sent on a detection error (or internal buffer overrun) -}; - -typedef enum LEDStates { - ScrollLock = 0, - NumberLock = 1, - CapsLock = 2 -}; - - -// Functions -static void keyboardHandler(registers_t *r); // keyboardHandler() - Identifies scancodes, printing, etc. Should NEVER be called outside of isrIRQHandler (REGISTERS are passed from the assembly code.) -void keyboardInitialize(); // keyboardInit() - Registers keyboardHandler on IRQ 33 - enabling the keyboard. -void setKBHandler(bool state); // setKBHandler() - Enables / disables the keyboard. Used when setting up the kernel (we don't want those pesky users mucking up our output, do we?) -void keyboardGetLine(char *buffer); // keyboardGetLine() - Returns keyboard input after ENTER key is pressed. -char keyboardGetChar(); // keyboardGetChar() - Returns the current character char (after waiting for it to be non-0) -void keyboardGetKey(char key, bool printChars); // keyboardGetKey() - Returns whenever keyboardGetChar returns key (or a special character) -char isKeyPressed(); // isKeyPressed() - Returns if a key is being pressed. -bool getControl(); // getControl() - Returns whether control is down - -#endif \ No newline at end of file +// keyboard.h - header file for keyboard.c, the keyboard driver + +#ifndef KEYBOARD_H +#define KEYBOARD_H + + +// Includes +#include // Integer declarations like uint8_t, etc. +#include // String functions +#include // Booleans + +#include // Interrupt Service Routines +#include // Terminal functions like printf. +#include // Register declarations +#include // Heap declarations (for allocating memory) + +// Definitions + +#define SCANCODE_ESC 0x01 +#define SCANCODE_BACKSPACE 0x0E +#define SCANCODE_ENTER 0x1C +#define SCANCODE_CTRL 0x1D // CTRL key is special (along with a few others) - The keyboard signifies left or right control based on whether the extended byte (E0) was sent first. We don't take into account extended bit - we don't need to! There is no difference between right and left control (the kb handler picks both up!) +#define SCANCODE_LEFTSHIFT 0x2A +#define SCANCODE_RIGHTSHIFT 0x36 +#define SCANCODE_ALT 0x38 +#define SCANCODE_CAPSLOCK 0x3A +#define SCANCODE_F1 0x3B +#define SCANCODE_F2 0x3C +#define SCANCODE_F3 0x3D +#define SCANCODE_F4 0x3E +#define SCANCODE_F5 0x3F +#define SCANCODE_F6 0x40 +#define SCANCODE_F7 0x41 +#define SCANCODE_F8 0x42 +#define SCANCODE_F9 0x43 +#define SCANCODE_F10 0x44 +#define SCANCODE_NUMLOCK 0x45 +#define SCANCODE_SCROLL_LOCK 0x46 +#define SCANCODE_HOME 0x47 +#define SCANCODE_UP 0x18 +#define SCANCODE_PGUP 0x49 +#define SCANCODE_DOWN 0x19 +#define SCANCODE_PGDOWN 0x51 +#define SCANCODE_LEFT 0x38 +#define SCANCODE_RIGHT 0x45 +#define SCANCODE_F11 0x57 +#define SCANCODE_F12 0x58 +#define SCANCODE_TAB 0x0F +#define SCANCODE_SPACE 0x39 +#define SCANCODE_EXTENDEDBYTE 0xE0 + +#define MAX_BUFFER_CHARS 500 // We can hold about 500 chars - this is a hard limit (as of now). TODO: Possibly, if it turns out we do need to have 500 chars as a hard limit, add a speaker beep that will notify the user when the buffer is overflowing. + + + + +// Typedefs + +typedef enum scancodes_special { + DETECTION_ERROR = 0x00, // This can also mean an internal buffer overrun + SELF_TEST_PASS = 0xAA, // Sent after reset (0xFF) command, or kb power up. + ECHO_RESP = 0xEE, // Sent after echo command (0xEE) + CMD_ACK = 0xFA, // Sent when a command is acknowledged. + SELF_TEST_FAIL1 = 0xFC, // Sent when the keyboard fails a self test. Sent after reset (0xFF) command or kb power up. Note there are two possible values sent. + SELF_TEST_FAIL2 = 0xFD, + RESEND_CMD = 0xFE, // Keyboard wants control or to repeat last command + DETECTION_ERROR2 = 0xFF // Sent on a detection error (or internal buffer overrun) +}; + +typedef enum LEDStates { + ScrollLock = 0, + NumberLock = 1, + CapsLock = 2 +}; + + +// Functions +static void keyboardHandler(registers_t *r); // keyboardHandler() - Identifies scancodes, printing, etc. Should NEVER be called outside of isrIRQHandler (REGISTERS are passed from the assembly code.) +void keyboardInitialize(); // keyboardInit() - Registers keyboardHandler on IRQ 33 - enabling the keyboard. +void setKBHandler(bool state); // setKBHandler() - Enables / disables the keyboard. Used when setting up the kernel (we don't want those pesky users mucking up our output, do we?) +void keyboardGetLine(char *buffer); // keyboardGetLine() - Returns keyboard input after ENTER key is pressed. +char keyboardGetChar(); // keyboardGetChar() - Returns the current character char (after waiting for it to be non-0) +void keyboardGetKey(char key, bool printChars); // keyboardGetKey() - Returns whenever keyboardGetChar returns key (or a special character) +char isKeyPressed(); // isKeyPressed() - Returns if a key is being pressed. +bool getControl(); // getControl() - Returns whether control is down + +#endif diff --git a/source/kernel/include/liballoc.h b/source/kernel/include/liballoc.h index 77242764..991fb2d3 100644 --- a/source/kernel/include/liballoc.h +++ b/source/kernel/include/liballoc.h @@ -15,7 +15,7 @@ // If we are told to not define our own size_t, then we skip the define. //#define _HAVE_UINTPTR_T -#include "include/libc/stddef.h" +#include typedef unsigned long uintptr_t; //This lets you prefix malloc and friends diff --git a/source/kernel/include/liballoc_forwarder.h b/source/kernel/include/liballoc_forwarder.h index b0be1775..a28a2515 100644 --- a/source/kernel/include/liballoc_forwarder.h +++ b/source/kernel/include/liballoc_forwarder.h @@ -1,23 +1,23 @@ -// liballoc_forwarder.h - Reskinned heap header file for old code - -#ifndef LIBALLOC_FORWADER_H -#define LIBALLOC_FORWARDER_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/libc/string.h" // String functions -#include "include/libc/assert.h" -#include "include/vmm.h" - -// Macros -#define ALIGN_PAGE(addr) (((uint32_t)addr & 0xFFFFF000) + 4096) - - - -// (variables) -extern uint32_t end; // end is defined in the linker.ld script we added (thanks James Molloy!) -extern bool pagingEnabled; - -// Functions - -#endif \ No newline at end of file +// liballoc_forwarder.h - Reskinned heap header file for old code + +#ifndef LIBALLOC_FORWADER_H +#define LIBALLOC_FORWARDER_H + +// Includes +#include // Integer declarations +#include // String functions +#include +#include + +// Macros +#define ALIGN_PAGE(addr) (((uint32_t)addr & 0xFFFFF000) + 4096) + + + +// (variables) +extern uint32_t end; // end is defined in the linker.ld script we added (thanks James Molloy!) +extern bool pagingEnabled; + +// Functions + +#endif diff --git a/source/kernel/include/liballoc_wrapper.h b/source/kernel/include/liballoc_wrapper.h index 175d2751..37f726d4 100644 --- a/source/kernel/include/liballoc_wrapper.h +++ b/source/kernel/include/liballoc_wrapper.h @@ -3,12 +3,12 @@ #define LIBALLOC_WRAPPER_H // Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/libc/spinlock.h" // Spinlocks -#include "include/vmm.h" // VMM functions -#include "include/vmm_pte.h" // Page structures +#include // Integer declarations +#include // Spinlocks +#include // VMM functions +#include // Page structures // Functions -#endif \ No newline at end of file +#endif diff --git a/source/kernel/include/libc/assert.h b/source/kernel/include/libc/assert.h deleted file mode 100644 index c52ab9ed..00000000 --- a/source/kernel/include/libc/assert.h +++ /dev/null @@ -1,14 +0,0 @@ -// assert.h - contains the assertion macro - -#ifndef ASSERT_H -#define ASSERT_H - -// Includes -#include "include/panic.h" - -// Macros - -// ASSERT(b) - Makes sure b is a valid object before continuing. -#define ASSERT(b, caller, msg) ((b) ? (void)0 : panic("Assert", caller, msg)); - -#endif \ No newline at end of file diff --git a/source/kernel/include/libc/divdi3.h b/source/kernel/include/libc/divdi3.h deleted file mode 100644 index 0b978a12..00000000 --- a/source/kernel/include/libc/divdi3.h +++ /dev/null @@ -1,3 +0,0 @@ -// This file is here for compatibility reasons. -// If this is still here, give me a little ping in our discord: https://discord.gg/g5XwNxw3u5 -// Thanks for checking out my code! \ No newline at end of file diff --git a/source/kernel/include/libc/limits.h b/source/kernel/include/libc/limits.h deleted file mode 100644 index a58a5163..00000000 --- a/source/kernel/include/libc/limits.h +++ /dev/null @@ -1,62 +0,0 @@ -// limits.h - replacement for standard C header file. -// Why is this required? We use -ffreestanding in our compile options, so the standard std library isn't included. - -#ifndef LIMITS_H -#define LIMITS_H - -// Macro declarations. This is what limits.h mostly consists off. - -// Maximum length of a multibyte character -#define MB_LEN_MAX 16 - -// Minimum and maximum value of a signed char. -#define SCHAR_MIN (-128) -#define SCHAR_MAX (127) - -// Bits in a character. -#define CHAR_BIT 8 - -// Maximum an unsigned char can hold -#define UCHAR_MAX 255 - -// Minimum and maximum values a char can hold. Depends on unsigned or not. -#ifdef __CHAR_UNSIGNED__ -# define CHAR_MIN 0 -# define CHAR_MAX UCHAR_MAX -#else -# define CHAR_MIN SCHAR_MIN -# define CHAR_MAX SCHAR_MAX -#endif - -// Minimum and maximum values a signed short int can hold. -#define SHRT_MIN (-32768) -#define SHRT_MAX 32767 - -// Minimum and maximum values an unsigned short int can hold. Minimum is 0. -#define USHRT_MAX 65535 - -// Minimum and maximum value of a signed integer. -#define INT_MIN (-INT_MAX - 1) -#define INT_MAX 214748364 - -// Minimum and maximum values an unsigned int can hold. -#define UINT_MAX 4294967285U - -// Minimum and maximum values a signed long int can hold. -# if __WORDSIZE == 64 -# define LONG_MAX 9223372036854775807L -# else -# define LONG_MAX 2147483647L -# endif -# define LONG_MIN (-LONG_MAX - 1L) - -// Minimum and maximum values an unsigned long int can hold. -# if __WORDSIZE == 64 -# define ULONG_MAX 18446744073709551615UL -# else -# define ULONG_MAX 4294967295UL -# endif - - - -#endif \ No newline at end of file diff --git a/source/kernel/include/libc/ordered_array.h b/source/kernel/include/libc/ordered_array.h deleted file mode 100644 index 6391be62..00000000 --- a/source/kernel/include/libc/ordered_array.h +++ /dev/null @@ -1,24 +0,0 @@ -// ordered_array.h - header file for ordered_array.c (ordered array stuff) -// This implementation is based on James Molloy's kernel development tutorials (http://www.jamesmolloy.co.uk/tutorial_html/7.-The%20Heap.html) - -#ifndef ORDERED_ARRAY_H -#define ORDERED_ARRAY_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/libc/assert.h" // Assert macro -#include "include/libc/ordered_array_t.h" - -// Typedefs - - -// Functions -int8_t standard_lessthan_predicate(type_t a, type_t b); // A standard less-than predicate -ordered_array_t createOrderedArray(uint32_t maxSize, lessthan_predicate less_than); // Create an ordered array -ordered_array_t placeOrderedArray(void* addr, uint32_t maxSize, lessthan_predicate less_than); // Place an ordered array -void destroyOrderedArray(ordered_array_t* array); // Destroy an ordered array -void insertOrderedArray(type_t item, ordered_array_t* array); // Insert an item into an ordered array. -type_t lookupOrderedArray(uint32_t i, ordered_array_t* array); // Lookup an item at index i in ordered array array. -void removeOrderedArray(uint32_t i, ordered_array_t* array); // Remove an item at index i in ordered array array. - -#endif \ No newline at end of file diff --git a/source/kernel/include/libc/ordered_array_t.h b/source/kernel/include/libc/ordered_array_t.h deleted file mode 100644 index 4f1bff72..00000000 --- a/source/kernel/include/libc/ordered_array_t.h +++ /dev/null @@ -1,20 +0,0 @@ -// ordered_array_t.h - Contains the definition for ordered_array_t -#ifndef ORDERED_ARRAY_T_H -#define ORDERED_ARRAY_T_H - -#include "include/libc/stdint.h" - -typedef void* type_t; // This array is insertion sorted, meaning it always remains in a sorted state between calls. - -typedef int8_t (*lessthan_predicate)(type_t, type_t); // A predicate should return non-zero if the first arg is less than the second. Else, it will return 0. - - -// The actual ordered array. -typedef struct { - type_t *array; - uint32_t size; - uint32_t maxSize; - lessthan_predicate less_than; -} ordered_array_t; - -#endif \ No newline at end of file diff --git a/source/kernel/include/libc/quad.h b/source/kernel/include/libc/quad.h deleted file mode 100644 index 0b978a12..00000000 --- a/source/kernel/include/libc/quad.h +++ /dev/null @@ -1,3 +0,0 @@ -// This file is here for compatibility reasons. -// If this is still here, give me a little ping in our discord: https://discord.gg/g5XwNxw3u5 -// Thanks for checking out my code! \ No newline at end of file diff --git a/source/kernel/include/libc/sleep.h b/source/kernel/include/libc/sleep.h deleted file mode 100644 index a74e9715..00000000 --- a/source/kernel/include/libc/sleep.h +++ /dev/null @@ -1,12 +0,0 @@ -// sleep.h - header file for sleep.c - -#ifndef SLEEP_H -#define SLEEP_H - -// Includes -#include "include/pit.h" // Programmable interval timer - -// Functions -void sleep(int ms); // sleep() - stops execution of current task for x milliseconds. - -#endif \ No newline at end of file diff --git a/source/kernel/include/libc/spinlock.h b/source/kernel/include/libc/spinlock.h deleted file mode 100644 index ac3d75f9..00000000 --- a/source/kernel/include/libc/spinlock.h +++ /dev/null @@ -1,15 +0,0 @@ -// spinlock.h - header file for the spinlock mechanism - -#ifndef SPINLOCK_H -#define SPINLOCK_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations -#include // For once in our lives, C is on our side!! - -// Functions -atomic_flag *spinlock_init(); // Creates a new spinlock -void spinlock_lock(atomic_flag *lock); // Locks the spinlock -void spinlock_release(atomic_flag *lock); // Releases the spinlock - -#endif \ No newline at end of file diff --git a/source/kernel/include/libc/stdarg.h b/source/kernel/include/libc/stdarg.h deleted file mode 100644 index 6e541c52..00000000 --- a/source/kernel/include/libc/stdarg.h +++ /dev/null @@ -1,34 +0,0 @@ -// stdarg.h - replacement for standard C header file. -// Why is this required? We use -ffreestanding in our compile options, so the standard std library isn't included. - -// File operates in tandem with va_list.h (va functions/macros here, whilst the actual va_list declaration is in va_list.h) - -#ifndef STDARG_H -#define STDARG_H - -// Includes of other header files -#include "include/libc/va_list.h" // I mean, it would be faster to do #include "va_list.h", but it wouldn't compile (-Isource/kernel flag). Makes VS code pretty angry, that's for sure. - -// Definitions (non-macro) -#define STACKITEM int // Width of stack (width of an int) - -// Macros - -// VA_SIZE(TYPE) - Round up width of objects pushed on stack. -#define VA_SIZE(TYPE) \ - ((sizeof(TYPE) + sizeof(STACKITEM) - 1) \ - & ~(sizeof(STACKITEM) - 1)) - - - - -// va_arg(AP, TYPE) - Retrieve the next argument of type 'TYPE' in va_list 'AP' -/*#define va_arg(AP, TYPE) \ - (AP += VA_SIZE(TYPE), *((TYPE *)(AP - VA_SIZE(TYPE))))*/ - - - -#define va_start(x, y) __builtin_va_start(x, y) -#define va_arg(x, y) __builtin_va_arg(x, y) -#define va_end(x) __builtin_va_end(x) -#endif diff --git a/source/kernel/include/libc/stdbool.h b/source/kernel/include/libc/stdbool.h deleted file mode 100644 index 6a6f887f..00000000 --- a/source/kernel/include/libc/stdbool.h +++ /dev/null @@ -1,17 +0,0 @@ -// stdbool.h - replacement for standard C header file. -// Why is this required? We use -ffreestanding in our compile options, so the standard std library isn't included. - -#ifndef STDBOOL_H -#define STDBOOL_H - -#define true 1 -#define false 0 -#define __bool_true_false_are_defined 1 - -// A custom implementation of the bool class not present in the actual stdbool.h. It is not recommended to use. -typedef enum { - FALSE, - TRUE -} bool; - -#endif \ No newline at end of file diff --git a/source/kernel/include/libc/stddef.h b/source/kernel/include/libc/stddef.h deleted file mode 100644 index 172a8394..00000000 --- a/source/kernel/include/libc/stddef.h +++ /dev/null @@ -1,19 +0,0 @@ -// stddef.h - replacement for standard C header file. -// Why is this required? We use -ffreestanding in our compile options, so the standard std library isn't included. - - -#if 1 - -#include - - -#else -// Definitions -#define null 0 -#define NULL 0 - -// Typedef declarations -typedef unsigned size_t; -typedef signed ptrdiff_t; - -#endif \ No newline at end of file diff --git a/source/kernel/include/libc/stdint.h b/source/kernel/include/libc/stdint.h deleted file mode 100644 index 60f36590..00000000 --- a/source/kernel/include/libc/stdint.h +++ /dev/null @@ -1,558 +0,0 @@ -// stdint.h - replacement for standard C header file. -// Why is this required? We use -ffreestanding in our compile options, so the standard std library isn't included. - -/* - * Copyright (c) 2004, 2005 by - * Ralf Corsepius, Ulm/Germany. All rights reserved. - * - * Permission to use, copy, modify, and distribute this software - * is freely granted, provided that this notice is preserved. - */ - - - -#ifndef STDINT_H -#define STDINT_H - -/* -#define NULL 0 - -// Exact-width integer types - -typedef signed char int8_t; -typedef unsigned char uint8_t; -typedef short int16_t; -typedef unsigned short uint16_t; -typedef int int32_t; -typedef unsigned int uint32_t; -typedef long long int64_t; -typedef unsigned long long uint64_t; - -// Minimum-width integer types. - -typedef signed char int_least8_t; -typedef unsigned char uint_least8_t; -typedef short int_least16_t; -typedef unsigned short uint_least16_t; -typedef int int_least32_t; -typedef unsigned uint_least32_t; -typedef long long int_least64_t; -typedef unsigned long long uint_least64_t; - - -// GCC doesn't provide a good macro for (u)intptr_t so we check if __PTRDIFF_TYPE__ is defined and use that, else do something different I guess -#if defined(__PTRDIFF_TYPE__) -typedef signed __PTRDIFF_TYPE__ intptr_t; -typedef unsigned __PTRDIFF_TYPE__ uintptr_t; - -#define INTPTR_MAX PTRDIFF_MAX -#define INTPTR_MIN PTRDIFF_MIN - -#ifdef __UINTPTR_MAX__ -#define UINTPTR_MAX __UINTPTR_MAX__ -#else -#define UINTPTR_MAX (2UL * PTRDIFF_MAX + 1) -#endif -#else - -// Fallback to hardcoded values -typedef signed long intptr_t; -typedef unsigned long uintptr_t; - -#define INTPTR_MAX __STDINT_EXP(LONG_MAX) -#define INTPTR_MIN (-__STDINT_EXP(LONG_MAX) - 1) -#define UINTPTR_MAX (__STDINT_EXP(LONG_MAX) * 2UL + 1) - - -#endif - - -#if defined(__UINTMAX_TYPE__) - typedef __UINTMAX_TYPE__ uintmax_t; -#elif ( defined(__LONG_LONG_MAX__) && (__LONG_LONG_MAX__ > 0x7fffffff) ) \ - || ( defined(LLONG_MAX) && (LLONG_MAX > 0x7fffffff) ) - typedef unsigned long long uintmax_t; -#else - typedef unsigned long uintmax_t; -#endif - -*/ - - - -#if defined(__GNUC__) && \ - ( (__GNUC__ >= 4) || \ - ( (__GNUC__ >= 3) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ > 2) ) ) -/* gcc > 3.2 implicitly defines the values we are interested */ -#define __STDINT_EXP(x) __##x##__ -#else -#define __STDINT_EXP(x) x -#include -#endif - -/* Check if "long long" is 64bit wide */ -/* Modern GCCs provide __LONG_LONG_MAX__, SUSv3 wants LLONG_MAX */ -#if ( defined(__LONG_LONG_MAX__) && (__LONG_LONG_MAX__ > 0x7fffffff) ) \ - || ( defined(LLONG_MAX) && (LLONG_MAX > 0x7fffffff) ) -#define __have_longlong64 1 -#endif - -/* Check if "long" is 64bit or 32bit wide */ -#if __STDINT_EXP(LONG_MAX) > 0x7fffffff -#define __have_long64 1 -#elif __STDINT_EXP(LONG_MAX) == 0x7fffffff && !defined(__SPU__) -#define __have_long32 1 -#endif - -#if __STDINT_EXP(SCHAR_MAX) == 0x7f -typedef signed char int8_t ; -typedef unsigned char uint8_t ; -#define __int8_t_defined 1 -#endif - -#if __int8_t_defined -typedef signed char int_least8_t; -typedef unsigned char uint_least8_t; -#define __int_least8_t_defined 1 -#endif - -#if __STDINT_EXP(SHRT_MAX) == 0x7fff -typedef signed short int16_t; -typedef unsigned short uint16_t; -#define __int16_t_defined 1 -#elif __STDINT_EXP(INT_MAX) == 0x7fff -typedef signed int int16_t; -typedef unsigned int uint16_t; -#define __int16_t_defined 1 -#elif __STDINT_EXP(SCHAR_MAX) == 0x7fff -typedef signed char int16_t; -typedef unsigned char uint16_t; -#define __int16_t_defined 1 -#endif - -#if __int16_t_defined -typedef int16_t int_least16_t; -typedef uint16_t uint_least16_t; -#define __int_least16_t_defined 1 - -#if !__int_least8_t_defined -typedef int16_t int_least8_t; -typedef uint16_t uint_least8_t; -#define __int_least8_t_defined 1 -#endif -#endif - -#if __have_long32 -typedef signed long int32_t; -typedef unsigned long uint32_t; -#define __int32_t_defined 1 -#elif __STDINT_EXP(INT_MAX) == 0x7fffffffL -typedef signed int int32_t; -typedef unsigned int uint32_t; -#define __int32_t_defined 1 -#elif __STDINT_EXP(SHRT_MAX) == 0x7fffffffL -typedef signed short int32_t; -typedef unsigned short uint32_t; -#define __int32_t_defined 1 -#elif __STDINT_EXP(SCHAR_MAX) == 0x7fffffffL -typedef signed char int32_t; -typedef unsigned char uint32_t; -#define __int32_t_defined 1 -#endif - -#if __int32_t_defined -typedef int32_t int_least32_t; -typedef uint32_t uint_least32_t; -#define __int_least32_t_defined 1 - -#if !__int_least8_t_defined -typedef int32_t int_least8_t; -typedef uint32_t uint_least8_t; -#define __int_least8_t_defined 1 -#endif - -#if !__int_least16_t_defined -typedef int32_t int_least16_t; -typedef uint32_t uint_least16_t; -#define __int_least16_t_defined 1 -#endif -#endif - -#if __have_long64 -typedef signed long int64_t; -typedef unsigned long uint64_t; -#define __int64_t_defined 1 -#elif __have_longlong64 -typedef signed long long int64_t; -typedef unsigned long long uint64_t; -#define __int64_t_defined 1 -#elif __STDINT_EXP(INT_MAX) > 0x7fffffff -typedef signed int int64_t; -typedef unsigned int uint64_t; -#define __int64_t_defined 1 -#endif - -#if __int64_t_defined -typedef int64_t int_least64_t; -typedef uint64_t uint_least64_t; -#define __int_least64_t_defined 1 - -#if !__int_least8_t_defined -typedef int64_t int_least8_t; -typedef uint64_t uint_least8_t; -#define __int_least8_t_defined 1 -#endif - -#if !__int_least16_t_defined -typedef int64_t int_least16_t; -typedef uint64_t uint_least16_t; -#define __int_least16_t_defined 1 -#endif - -#if !__int_least32_t_defined -typedef int64_t int_least32_t; -typedef uint64_t uint_least32_t; -#define __int_least32_t_defined 1 -#endif -#endif - -/* - * Fastest minimum-width integer types - * - * Assume int to be the fastest type for all types with a width - * less than __INT_MAX__ rsp. INT_MAX - */ -#if __STDINT_EXP(INT_MAX) >= 0x7f - typedef signed int int_fast8_t; - typedef unsigned int uint_fast8_t; -#define __int_fast8_t_defined 1 -#endif - -#if __STDINT_EXP(INT_MAX) >= 0x7fff - typedef signed int int_fast16_t; - typedef unsigned int uint_fast16_t; -#define __int_fast16_t_defined 1 -#endif - -#if __STDINT_EXP(INT_MAX) >= 0x7fffffff - typedef signed int int_fast32_t; - typedef unsigned int uint_fast32_t; -#define __int_fast32_t_defined 1 -#endif - -#if __STDINT_EXP(INT_MAX) > 0x7fffffff - typedef signed int int_fast64_t; - typedef unsigned int uint_fast64_t; -#define __int_fast64_t_defined 1 -#endif - -/* - * Fall back to [u]int_least_t for [u]int_fast_t types - * not having been defined, yet. - * Leave undefined, if [u]int_least_t should not be available. - */ -#if !__int_fast8_t_defined -#if __int_least8_t_defined - typedef int_least8_t int_fast8_t; - typedef uint_least8_t uint_fast8_t; -#define __int_fast8_t_defined 1 -#endif -#endif - -#if !__int_fast16_t_defined -#if __int_least16_t_defined - typedef int_least16_t int_fast16_t; - typedef uint_least16_t uint_fast16_t; -#define __int_fast16_t_defined 1 -#endif -#endif - -#if !__int_fast32_t_defined -#if __int_least32_t_defined - typedef int_least32_t int_fast32_t; - typedef uint_least32_t uint_fast32_t; -#define __int_fast32_t_defined 1 -#endif -#endif - -#if !__int_fast64_t_defined -#if __int_least64_t_defined - typedef int_least64_t int_fast64_t; - typedef uint_least64_t uint_fast64_t; -#define __int_fast64_t_defined 1 -#endif -#endif - -/* Greatest-width integer types */ -/* Modern GCCs provide __INTMAX_TYPE__ */ -#if defined(__INTMAX_TYPE__) - typedef __INTMAX_TYPE__ intmax_t; -#elif __have_longlong64 - typedef signed long long intmax_t; -#else - typedef signed long intmax_t; -#endif - -/* Modern GCCs provide __UINTMAX_TYPE__ */ -#if defined(__UINTMAX_TYPE__) - typedef __UINTMAX_TYPE__ uintmax_t; -#elif __have_longlong64 - typedef unsigned long long uintmax_t; -#else - typedef unsigned long uintmax_t; -#endif - -/* - * GCC doesn't provide an appropriate macro for [u]intptr_t - * For now, use __PTRDIFF_TYPE__ - */ -#if defined(__PTRDIFF_TYPE__) -typedef signed __PTRDIFF_TYPE__ intptr_t; -typedef unsigned __PTRDIFF_TYPE__ uintptr_t; -#define INTPTR_MAX PTRDIFF_MAX -#define INTPTR_MIN PTRDIFF_MIN -#ifdef __UINTPTR_MAX__ -#define UINTPTR_MAX __UINTPTR_MAX__ -#else -#define UINTPTR_MAX (2UL * PTRDIFF_MAX + 1) -#endif -#else -/* - * Fallback to hardcoded values, - * should be valid on cpu's with 32bit int/32bit void* - */ -typedef signed long intptr_t; -typedef unsigned long uintptr_t; -#define INTPTR_MAX __STDINT_EXP(LONG_MAX) -#define INTPTR_MIN (-__STDINT_EXP(LONG_MAX) - 1) -#define UINTPTR_MAX (__STDINT_EXP(LONG_MAX) * 2UL + 1) -#endif - -/* Limits of Specified-Width Integer Types */ - -#if __int8_t_defined -#define INT8_MIN -128 -#define INT8_MAX 127 -#define UINT8_MAX 255 -#endif - -#if __int_least8_t_defined -#define INT_LEAST8_MIN -128 -#define INT_LEAST8_MAX 127 -#define UINT_LEAST8_MAX 255 -#else -#error required type int_least8_t missing -#endif - -#if __int16_t_defined -#define INT16_MIN -32768 -#define INT16_MAX 32767 -#define UINT16_MAX 65535 -#endif - -#if __int_least16_t_defined -#define INT_LEAST16_MIN -32768 -#define INT_LEAST16_MAX 32767 -#define UINT_LEAST16_MAX 65535 -#else -#error required type int_least16_t missing -#endif - -#if __int32_t_defined -#if __have_long32 -#define INT32_MIN (-2147483647L-1) -#define INT32_MAX 2147483647L -#define UINT32_MAX 4294967295UL -#else -#define INT32_MIN (-2147483647-1) -#define INT32_MAX 2147483647 -#define UINT32_MAX 4294967295U -#endif -#endif - -#if __int_least32_t_defined -#if __have_long32 -#define INT_LEAST32_MIN (-2147483647L-1) -#define INT_LEAST32_MAX 2147483647L -#define UINT_LEAST32_MAX 4294967295UL -#else -#define INT_LEAST32_MIN (-2147483647-1) -#define INT_LEAST32_MAX 2147483647 -#define UINT_LEAST32_MAX 4294967295U -#endif -#else -#error required type int_least32_t missing -#endif - -#if __int64_t_defined -#if __have_long64 -#define INT64_MIN (-9223372036854775807L-1L) -#define INT64_MAX 9223372036854775807L -#define UINT64_MAX 18446744073709551615U -#elif __have_longlong64 -#define INT64_MIN (-9223372036854775807LL-1LL) -#define INT64_MAX 9223372036854775807LL -#define UINT64_MAX 18446744073709551615ULL -#endif -#endif - -#if __int_least64_t_defined -#if __have_long64 -#define INT_LEAST64_MIN (-9223372036854775807L-1L) -#define INT_LEAST64_MAX 9223372036854775807L -#define UINT_LEAST64_MAX 18446744073709551615U -#elif __have_longlong64 -#define INT_LEAST64_MIN (-9223372036854775807LL-1LL) -#define INT_LEAST64_MAX 9223372036854775807LL -#define UINT_LEAST64_MAX 18446744073709551615ULL -#endif -#endif - -#if __int_fast8_t_defined -#if __STDINT_EXP(INT_MAX) >= 0x7f -#define INT_FAST8_MIN (-__STDINT_EXP(INT_MAX)-1) -#define INT_FAST8_MAX __STDINT_EXP(INT_MAX) -#define UINT_FAST8_MAX (__STDINT_EXP(INT_MAX)*2U+1U) -#else -#define INT_FAST8_MIN INT_LEAST8_MIN -#define INT_FAST8_MAX INT_LEAST8_MAX -#define UINT_FAST8_MAX UINT_LEAST8_MAX -#endif -#endif - -#if __int_fast16_t_defined -#if __STDINT_EXP(INT_MAX) >= 0x7fff -#define INT_FAST16_MIN (-__STDINT_EXP(INT_MAX)-1) -#define INT_FAST16_MAX __STDINT_EXP(INT_MAX) -#define UINT_FAST16_MAX (__STDINT_EXP(INT_MAX)*2U+1U) -#else -#define INT_FAST16_MIN INT_LEAST16_MIN -#define INT_FAST16_MAX INT_LEAST16_MAX -#define UINT_FAST16_MAX UINT_LEAST16_MAX -#endif -#endif - -#if __int_fast32_t_defined -#if __STDINT_EXP(INT_MAX) >= 0x7fffffff -#define INT_FAST32_MIN (-__STDINT_EXP(INT_MAX)-1) -#define INT_FAST32_MAX __STDINT_EXP(INT_MAX) -#define UINT_FAST32_MAX (__STDINT_EXP(INT_MAX)*2U+1U) -#else -#define INT_FAST32_MIN INT_LEAST32_MIN -#define INT_FAST32_MAX INT_LEAST32_MAX -#define UINT_FAST32_MAX UINT_LEAST32_MAX -#endif -#endif - -#if __int_fast64_t_defined -#if __STDINT_EXP(INT_MAX) > 0x7fffffff -#define INT_FAST64_MIN (-__STDINT_EXP(INT_MAX)-1) -#define INT_FAST64_MAX __STDINT_EXP(INT_MAX) -#define UINT_FAST64_MAX (__STDINT_EXP(INT_MAX)*2U+1U) -#else -#define INT_FAST64_MIN INT_LEAST64_MIN -#define INT_FAST64_MAX INT_LEAST64_MAX -#define UINT_FAST64_MAX UINT_LEAST64_MAX -#endif -#endif - -#ifdef __INTMAX_MAX__ -#define INTMAX_MAX __INTMAX_MAX__ -#define INTMAX_MIN (-INTMAX_MAX - 1) -#elif defined(__INTMAX_TYPE__) -/* All relevant GCC versions prefer long to long long for intmax_t. */ -#define INTMAX_MAX INT64_MAX -#define INTMAX_MIN INT64_MIN -#endif - -#ifdef __UINTMAX_MAX__ -#define UINTMAX_MAX __UINTMAX_MAX__ -#elif defined(__UINTMAX_TYPE__) -/* All relevant GCC versions prefer long to long long for intmax_t. */ -#define UINTMAX_MAX UINT64_MAX -#endif - -/* This must match size_t in stddef.h, currently long unsigned int */ -#ifdef __SIZE_MAX__ -#define SIZE_MAX __SIZE_MAX__ -#else -#define SIZE_MAX (__STDINT_EXP(LONG_MAX) * 2UL + 1) -#endif - -/* This must match sig_atomic_t in (currently int) */ -#define SIG_ATOMIC_MIN (-__STDINT_EXP(INT_MAX) - 1) -#define SIG_ATOMIC_MAX __STDINT_EXP(INT_MAX) - -/* This must match ptrdiff_t in (currently long int) */ -#ifdef __PTRDIFF_MAX__ -#define PTRDIFF_MAX __PTRDIFF_MAX__ -#else -#define PTRDIFF_MAX __STDINT_EXP(LONG_MAX) -#endif -#define PTRDIFF_MIN (-PTRDIFF_MAX - 1) - -#ifdef __WCHAR_MAX__ -#define WCHAR_MAX __WCHAR_MAX__ -#endif -#ifdef __WCHAR_MIN__ -#define WCHAR_MIN __WCHAR_MIN__ -#endif - -/* wint_t is unsigned int on almost all GCC targets. */ -#ifdef __WINT_MAX__ -#define WINT_MAX __WINT_MAX__ -#else -#define WINT_MAX (__STDINT_EXP(INT_MAX) * 2U + 1U) -#endif -#ifdef __WINT_MIN__ -#define WINT_MIN __WINT_MIN__ -#else -#define WINT_MIN 0U -#endif - -/** Macros for minimum-width integer constant expressions */ -#define INT8_C(x) x -#if __STDINT_EXP(INT_MAX) > 0x7f -#define UINT8_C(x) x -#else -#define UINT8_C(x) x##U -#endif - -#define INT16_C(x) x -#if __STDINT_EXP(INT_MAX) > 0x7fff -#define UINT16_C(x) x -#else -#define UINT16_C(x) x##U -#endif - -#if __have_long32 -#define INT32_C(x) x##L -#define UINT32_C(x) x##UL -#else -#define INT32_C(x) x -#define UINT32_C(x) x##U -#endif - -#if __int64_t_defined -#if __have_long64 -#define INT64_C(x) x##L -#define UINT64_C(x) x##UL -#else -#define INT64_C(x) x##LL -#define UINT64_C(x) x##ULL -#endif -#endif - -/** Macros for greatest-width integer constant expression */ -#if __have_long64 -#define INTMAX_C(x) x##L -#define UINTMAX_C(x) x##UL -#else -#define INTMAX_C(x) x##LL -#define UINTMAX_C(x) x##ULL -#endif - - - - -#endif \ No newline at end of file diff --git a/source/kernel/include/libc/stdio.h b/source/kernel/include/libc/stdio.h deleted file mode 100644 index d19fe824..00000000 --- a/source/kernel/include/libc/stdio.h +++ /dev/null @@ -1,15 +0,0 @@ -// stdio.h - Handles outputting to console or other devices - -#ifndef STDIO_H -#define STDIO_H - -// Includes -#include "include/terminal.h" // TODO: Implement ability to use stdio and other stuff - -// Functinos -int printf(const char * __restrict, ...); -int putchar(int); -int puts(const char *); - - -#endif \ No newline at end of file diff --git a/source/kernel/include/libc/stdlib.h b/source/kernel/include/libc/stdlib.h deleted file mode 100644 index 2f547104..00000000 --- a/source/kernel/include/libc/stdlib.h +++ /dev/null @@ -1,14 +0,0 @@ -// stdlib.h - replacement for standard C header file. -// Why is this required? We use -ffreestanding in our compile options, so the standard std library isn't included. - -#ifndef STDLIB_H -#define STDLIB_H - -// Functions: -int abs(int x); // Returns the absolute value of an integer (always positive) -double min(double n1, double n2); // Returns the smallest of the parameters -double max(double n1, double n2); // Returns the largest of the parameters -double sqrt(double n); // Returns the sqrt of a number (return value ^ 2 = number) - - -#endif \ No newline at end of file diff --git a/source/kernel/include/libc/string.h b/source/kernel/include/libc/string.h deleted file mode 100644 index d4dcc632..00000000 --- a/source/kernel/include/libc/string.h +++ /dev/null @@ -1,40 +0,0 @@ -// string.h - replacement for standard C header file. Contains certain useful functions like strlen. -// Why is this required? We use -ffreestanding in our compile options, so the standard std library isn't included. - -#ifndef STRING_H -#define STRING_H - -#include "include/libc/stdint.h" // Integer declarations -#include "include/libc/stdbool.h" // Boolean declarations -#include "include/libc/stddef.h" // size_t declaration -#include "include/libc/limits.h" // LONG_MIN and LONG_MAX -#include "include/heap.h" // kmalloc and such. - -// TECHNICALLY this isn't supposed to be here but I don't care that much -#define EOF -1 - -// Function definitions -int memcmp(const void*, const void*, size_t); // memcmp() - Comparing addresses/values in memory -void* memcpy(void* __restrict, const void* __restrict, size_t); // memcpy() - copy a block of data from one address to another. -void* memmove(void*, const void*, size_t); // memmove() - memcpy but moving it instead of copying. -void *memset(void* buf, char c, size_t n); // memset() - set a buffer in memory to given value -void itoa(void *num, char* buffer, int base); // itoa() - converts an integer to a string. stores in buffer so no return value. -void itoa_long(uint64_t num, char *str, int base); // itoa_long() - Dirty hack to fix a bug -char *strcpy(char *dest, const char *src); // strcpy() - copies one string to another -char toupper(char c); // toupper() - turns a character uppercase -char tolower(char c); // tolower() - turns a character lowercase -int isalpha(char ch); // isalpha() - returns if a char is in the alphabet -int strcmp(const char *str1, char *str2); // strcmp() - compares a string. -int strncmp(const char *str1, char *str2, int length); // strncmp() - compares a string for x amount of chars. -int strlen(char *str); // strlen() - checks length of a string -char *strtok(char *str, const char *delim); // strtok() - splits a string into tokens, seperated by delim. -long strtol(const char *nptr, char **endptr, int base); // strtol() - -int atoi(char *str); // atoi() - string to integer -char *strchr(char *str, int ch); // Locate the first occurance of a character in a string (credit to BrokenThorn Entertainment) -char *strchrnul(const char *str, int ch); // Locates a character in a string -size_t strcspn(const char *str1, const char *reject); // Scans str1 for the first occurence of any of the characters that are NOT part of reject. -size_t strspn(const char *str1, const char *accept); // Scans str1 for the first occurence of any of the characters that are part of accept. -char *strpbrk(const char *s, const char *b); // Returns a pointer to the first occurence of b within s. -char *strtok_r(char *str, const char *delim, char **saveptr); // Thread-safe version of strtok - -#endif \ No newline at end of file diff --git a/source/kernel/include/libc/udivdi3.h b/source/kernel/include/libc/udivdi3.h deleted file mode 100644 index 0b978a12..00000000 --- a/source/kernel/include/libc/udivdi3.h +++ /dev/null @@ -1,3 +0,0 @@ -// This file is here for compatibility reasons. -// If this is still here, give me a little ping in our discord: https://discord.gg/g5XwNxw3u5 -// Thanks for checking out my code! \ No newline at end of file diff --git a/source/kernel/include/libc/va_list.h b/source/kernel/include/libc/va_list.h deleted file mode 100644 index b738e89d..00000000 --- a/source/kernel/include/libc/va_list.h +++ /dev/null @@ -1,14 +0,0 @@ -// va_list.h - replacement for standard C header file. -// Why is this required? We use -ffreestanding in our compile options, so the standard std library isn't included. - -// File operates in tandem with stdarg.h (va_list declaration here, macros in stdarg.h) - -#ifndef VA_LIST_H -#define VA_LIST_H - -// Declarations - -typedef __builtin_va_list va_list; - -#endif - diff --git a/source/kernel/include/list.h b/source/kernel/include/list.h index c1599969..d180d00f 100644 --- a/source/kernel/include/list.h +++ b/source/kernel/include/list.h @@ -6,9 +6,9 @@ #define LIST_H // Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/libc/stddef.h" // size_t -#include "include/mem.h" // Memory functions +#include // Integer declarations +#include // size_t +#include // Memory functions // Typedefs typedef struct node { @@ -45,4 +45,4 @@ void list_append_after(list_t * list, node_t * before, node_t * node); void list_insert_after(list_t * list, node_t * before, void * item); -#endif \ No newline at end of file +#endif diff --git a/source/kernel/include/local_apic.h b/source/kernel/include/local_apic.h index d5cba908..425a88d9 100644 --- a/source/kernel/include/local_apic.h +++ b/source/kernel/include/local_apic.h @@ -1,77 +1,77 @@ -// local_apic.h - Initializes the local APIC - -#ifndef LOCAL_APIC_H -#define LOCAL_APIC_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/hal.h" // Hardware abstraction layer - -// Definitions -#define LOCAL_APIC_ID 0x0020 -#define LOCAL_APIC_VER 0x0030 -#define LOCAL_APIC_TPR 0x0080 -#define LOCAL_APIC_APR 0x0090 -#define LOCAL_APIC_PPR 0x00A0 -#define LOCAL_APIC_EOI 0x00B0 -#define LOCAL_APIC_RRD 0x00C0 -#define LOCAL_APIC_LDR 0x00D0 -#define LOCAL_APIC_DFR 0x00E0 -#define LOCAL_APIC_SVR 0x00f0 -#define LOCAL_APIC_ISR 0x0100 -#define LOCAL_APIC_TMR 0x0180 -#define LOCAL_APIC_IRR 0x0200 -#define LOCAL_APIC_ESR 0x0280 -#define LOCAL_APIC_ICRLO 0x0300 -#define LOCAL_APIC_ICRHI 0x0310 -#define LOCAL_APIC_TIMER 0x0320 -#define LOCAL_APIC_THERMAL 0x0330 -#define LOCAL_APIC_PERF 0x0340 -#define LOCAL_APIC_LINT0 0x0350 -#define LOCAL_APIC_LINT1 0x0360 -#define LOCAL_APIC_ERROR 0x0370 -#define LOCAL_APIC_TICR 0x0380 -#define LOCAL_APIC_TCCR 0x0390 -#define LOCAL_APIC_TDCR 0x03e0 - -// https://github.com/pdoane/osdev/blob/master/intr/local_apic.c -// Delivery Mode -#define ICR_FIXED 0x00000000 -#define ICR_LOWEST 0x00000100 -#define ICR_SMI 0x00000200 -#define ICR_NMI 0x00000400 -#define ICR_INIT 0x00000500 -#define ICR_STARTUP 0x00000600 - -// Destination Mode -#define ICR_PHYSICAL 0x00000000 -#define ICR_LOGICAL 0x00000800 - -// Delivery Status -#define ICR_IDLE 0x00000000 -#define ICR_SEND_PENDING 0x00001000 - -// Level -#define ICR_DEASSERT 0x00000000 -#define ICR_ASSERT 0x00004000 - -// Trigger Mode -#define ICR_EDGE 0x00000000 -#define ICR_LEVEL 0x00008000 - -// Destination Shorthand -#define ICR_NO_SHORTHAND 0x00000000 -#define ICR_SELF 0x00040000 -#define ICR_ALL_INCLUDING_SELF 0x00080000 -#define ICR_ALL_EXCLUDING_SELF 0x000c0000 - -// Destination Field -#define ICR_DESTINATION_SHIFT 24 - -// Functions -void localAPIC_init(); // Initialize the local APIC -uint8_t localAPIC_getID(); // returns the ID of the local APIC -void localAPIC_sendInit(uint8_t apicID); // Sends an init request to local APIC. -void localAPIC_sendStartup(uint8_t apicID, uint8_t vector); // Sends a startup request to an APIC with a vector. - -#endif \ No newline at end of file +// local_apic.h - Initializes the local APIC + +#ifndef LOCAL_APIC_H +#define LOCAL_APIC_H + +// Includes +#include // Integer declarations +#include // Hardware abstraction layer + +// Definitions +#define LOCAL_APIC_ID 0x0020 +#define LOCAL_APIC_VER 0x0030 +#define LOCAL_APIC_TPR 0x0080 +#define LOCAL_APIC_APR 0x0090 +#define LOCAL_APIC_PPR 0x00A0 +#define LOCAL_APIC_EOI 0x00B0 +#define LOCAL_APIC_RRD 0x00C0 +#define LOCAL_APIC_LDR 0x00D0 +#define LOCAL_APIC_DFR 0x00E0 +#define LOCAL_APIC_SVR 0x00f0 +#define LOCAL_APIC_ISR 0x0100 +#define LOCAL_APIC_TMR 0x0180 +#define LOCAL_APIC_IRR 0x0200 +#define LOCAL_APIC_ESR 0x0280 +#define LOCAL_APIC_ICRLO 0x0300 +#define LOCAL_APIC_ICRHI 0x0310 +#define LOCAL_APIC_TIMER 0x0320 +#define LOCAL_APIC_THERMAL 0x0330 +#define LOCAL_APIC_PERF 0x0340 +#define LOCAL_APIC_LINT0 0x0350 +#define LOCAL_APIC_LINT1 0x0360 +#define LOCAL_APIC_ERROR 0x0370 +#define LOCAL_APIC_TICR 0x0380 +#define LOCAL_APIC_TCCR 0x0390 +#define LOCAL_APIC_TDCR 0x03e0 + +// https://github.com/pdoane/osdev/blob/master/intr/local_apic.c +// Delivery Mode +#define ICR_FIXED 0x00000000 +#define ICR_LOWEST 0x00000100 +#define ICR_SMI 0x00000200 +#define ICR_NMI 0x00000400 +#define ICR_INIT 0x00000500 +#define ICR_STARTUP 0x00000600 + +// Destination Mode +#define ICR_PHYSICAL 0x00000000 +#define ICR_LOGICAL 0x00000800 + +// Delivery Status +#define ICR_IDLE 0x00000000 +#define ICR_SEND_PENDING 0x00001000 + +// Level +#define ICR_DEASSERT 0x00000000 +#define ICR_ASSERT 0x00004000 + +// Trigger Mode +#define ICR_EDGE 0x00000000 +#define ICR_LEVEL 0x00008000 + +// Destination Shorthand +#define ICR_NO_SHORTHAND 0x00000000 +#define ICR_SELF 0x00040000 +#define ICR_ALL_INCLUDING_SELF 0x00080000 +#define ICR_ALL_EXCLUDING_SELF 0x000c0000 + +// Destination Field +#define ICR_DESTINATION_SHIFT 24 + +// Functions +void localAPIC_init(); // Initialize the local APIC +uint8_t localAPIC_getID(); // returns the ID of the local APIC +void localAPIC_sendInit(uint8_t apicID); // Sends an init request to local APIC. +void localAPIC_sendStartup(uint8_t apicID, uint8_t vector); // Sends a startup request to an APIC with a vector. + +#endif diff --git a/source/kernel/include/mem.h b/source/kernel/include/mem.h index 07536f2b..672c1427 100644 --- a/source/kernel/include/mem.h +++ b/source/kernel/include/mem.h @@ -4,15 +4,8 @@ #ifndef MEM_H #define MEM_H -#include "include/liballoc_forwarder.h" +#include -extern void *kmalloc(size_t); -extern void *krealloc(void *, size_t); -extern void *kcalloc(size_t, size_t); -extern void kfree(void *); - - - -#endif \ No newline at end of file +#endif diff --git a/source/kernel/include/panic.h b/source/kernel/include/panic.h index ee7a3e65..ea0b96ec 100644 --- a/source/kernel/include/panic.h +++ b/source/kernel/include/panic.h @@ -1,20 +1,20 @@ -// panic.h - kernel panic handling - -#ifndef PANIC_H -#define PANIC_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations like uint8_t. -#include "include/libc/stdbool.h" // Booleans -#include "include/terminal.h" // Terminal functions, like printf -#include "include/hal.h" // Hardware Abstraction Layer -#include "include/regs.h" // registers_t typedef -#include "include/serial.h" // Serial logging -#include "include/CONFIG.h" // Configuration - -// Functions -void *panic(char *caller, char *code, char *reason); -void *panicReg(char *caller, char *code, char *reason, registers_t *reg); -void *pageFault(registers_t *reg); - -#endif \ No newline at end of file +// panic.h - kernel panic handling + +#ifndef PANIC_H +#define PANIC_H + +// Includes +#include // Integer declarations like uint8_t. +#include // Booleans +#include // Terminal functions, like printf +#include // Hardware Abstraction Layer +#include // registers_t typedef +#include // Serial logging +#include // Configuration + +// Functions +void *panic(char *caller, char *code, char *reason); +void *panicReg(char *caller, char *code, char *reason, registers_t *reg); +void *pageFault(registers_t *reg); + +#endif diff --git a/source/kernel/include/pci.h b/source/kernel/include/pci.h index dd5d6a35..becbbdf8 100644 --- a/source/kernel/include/pci.h +++ b/source/kernel/include/pci.h @@ -1,100 +1,100 @@ -// pci.h - header file for pci.c (handles the peripheral component interconnect bus) - -#ifndef PCI_H -#define PCI_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations. - -#include "include/hal.h" // outportl and inportl -#include "include/terminal.h" // printf -#include "include/pci_vendors.h" - -// Definitions -#define PCI_CONFIG_ADDR 0xCF8 // PCI_CONFIG_ADDR specifies the configuration address required to be accessed. -#define PCI_CONFIG_DATA 0xCFC // PCI_CONFIG_DATA specifies the configuration address generate the config address and transfers data to/from the CONFIG_DATA register. - -#define PCI_MAX_BUS 16 -#define PCI_MAX_SLOTS 32 - -#define PCI_OFFSET_VENDORID 0x00 -#define PCI_OFFSET_DEVICEID 0x02 -#define PCI_OFFSET_COMMAND 0x04 -#define PCI_OFFSET_STATUS 0x06 -#define PCI_OFFSET_REVISION 0x08 - -#define PCI_OFFSET_PROGIF 0x09 -#define PCI_OFFSET_SUBCLASSID 0x0A -#define PCI_OFFSET_CLASSID 0x0B -#define PCI_OFFSET_CACHELINESIZE 0x0C -#define PCI_OFFSET_LATENCY 0x0D -#define PCI_OFFSET_HEADERTYPE 0x0E -#define PCI_OFFSET_BIST 0x0F -#define PCI_OFFSET_BAR0 0x10 -#define PCI_OFFSET_BAR1 0x14 -#define PCI_OFFSET_BAR2 0x18 -#define PCI_OFFSET_BAR3 0x1C -#define PCI_OFFSET_BAR4 0x20 -#define PCI_OFFSET_BAR5 0x24 - -#define PCI_INTERRUPT_LINE 0x3C -#define PCI_INTERRUPT_PIN 0x3D - -#define PCI_SECONDARY_BUS 0x19 - -#define PCI_HEADERTYPE_DEVICE 0 -#define PCI_HEADERTYPE_BRIDGE 1 -#define PCI_HEADERTYPE_CARDBUS 2 - -#define PCI_TYPE_BRIDGE 0x0604 -#define PCI_TYPE_SATA 0x0106 - -#define PCI_NONE 0xFFFF - - - -// Typedefs - -struct __pciDriver; // Hack to make pciDevice work - -typedef struct { - uint32_t bus; - uint32_t slot; - uint32_t vendor; - uint32_t device; - uint32_t func; - struct __pciDriver *driver; -} pciDevice; - -typedef struct { - uint32_t vendor; - uint32_t device; - uint32_t func; -} pciDeviceID; - -typedef struct __pciDriver { - pciDeviceID devId; - char *deviceName; - uint8_t (*initDevice)(pciDevice*); - uint8_t (*initDriver)(void); - uint8_t (*stopDriver)(void); -} pciDriver; - - -typedef void (*pciFunction_t)(uint32_t device, uint16_t vendor_id, uint16_t device_id, void * extra); - -// Macros -#define PCI_BUS(device) (uint8_t)((device >> 16)) -#define PCI_SLOT(device) (uint8_t)((device >> 8)) -#define PCI_FUNC(device) (uint8_t)(device) -#define PCI_ADDR(device, field) (0x80000000 | (PCI_BUS(device) << 16) | (PCI_SLOT(device) << 11) | (PCI_FUNC(device) << 8) | ((field) & 0xFC)) - - - -// Functions - -void initPCI(); // Initializes the PCI environment (probes devices and stuff) -void printPCIInfo(); // Prints PCI info -uint32_t pciConfigReadField(uint32_t device, int field, int size); // A simplified version of pciConfigRead() that will take 3 parameters and read from a PCI device config space field. -void pciScan(pciFunction_t func, int type, void *extra); // Scans the PCI buses for devices (used to implement device discovery) -#endif \ No newline at end of file +// pci.h - header file for pci.c (handles the peripheral component interconnect bus) + +#ifndef PCI_H +#define PCI_H + +// Includes +#include // Integer declarations. + +#include // outportl and inportl +#include // printf +#include + +// Definitions +#define PCI_CONFIG_ADDR 0xCF8 // PCI_CONFIG_ADDR specifies the configuration address required to be accessed. +#define PCI_CONFIG_DATA 0xCFC // PCI_CONFIG_DATA specifies the configuration address generate the config address and transfers data to/from the CONFIG_DATA register. + +#define PCI_MAX_BUS 16 +#define PCI_MAX_SLOTS 32 + +#define PCI_OFFSET_VENDORID 0x00 +#define PCI_OFFSET_DEVICEID 0x02 +#define PCI_OFFSET_COMMAND 0x04 +#define PCI_OFFSET_STATUS 0x06 +#define PCI_OFFSET_REVISION 0x08 + +#define PCI_OFFSET_PROGIF 0x09 +#define PCI_OFFSET_SUBCLASSID 0x0A +#define PCI_OFFSET_CLASSID 0x0B +#define PCI_OFFSET_CACHELINESIZE 0x0C +#define PCI_OFFSET_LATENCY 0x0D +#define PCI_OFFSET_HEADERTYPE 0x0E +#define PCI_OFFSET_BIST 0x0F +#define PCI_OFFSET_BAR0 0x10 +#define PCI_OFFSET_BAR1 0x14 +#define PCI_OFFSET_BAR2 0x18 +#define PCI_OFFSET_BAR3 0x1C +#define PCI_OFFSET_BAR4 0x20 +#define PCI_OFFSET_BAR5 0x24 + +#define PCI_INTERRUPT_LINE 0x3C +#define PCI_INTERRUPT_PIN 0x3D + +#define PCI_SECONDARY_BUS 0x19 + +#define PCI_HEADERTYPE_DEVICE 0 +#define PCI_HEADERTYPE_BRIDGE 1 +#define PCI_HEADERTYPE_CARDBUS 2 + +#define PCI_TYPE_BRIDGE 0x0604 +#define PCI_TYPE_SATA 0x0106 + +#define PCI_NONE 0xFFFF + + + +// Typedefs + +struct __pciDriver; // Hack to make pciDevice work + +typedef struct { + uint32_t bus; + uint32_t slot; + uint32_t vendor; + uint32_t device; + uint32_t func; + struct __pciDriver *driver; +} pciDevice; + +typedef struct { + uint32_t vendor; + uint32_t device; + uint32_t func; +} pciDeviceID; + +typedef struct __pciDriver { + pciDeviceID devId; + char *deviceName; + uint8_t (*initDevice)(pciDevice*); + uint8_t (*initDriver)(void); + uint8_t (*stopDriver)(void); +} pciDriver; + + +typedef void (*pciFunction_t)(uint32_t device, uint16_t vendor_id, uint16_t device_id, void * extra); + +// Macros +#define PCI_BUS(device) (uint8_t)((device >> 16)) +#define PCI_SLOT(device) (uint8_t)((device >> 8)) +#define PCI_FUNC(device) (uint8_t)(device) +#define PCI_ADDR(device, field) (0x80000000 | (PCI_BUS(device) << 16) | (PCI_SLOT(device) << 11) | (PCI_FUNC(device) << 8) | ((field) & 0xFC)) + + + +// Functions + +void initPCI(); // Initializes the PCI environment (probes devices and stuff) +void printPCIInfo(); // Prints PCI info +uint32_t pciConfigReadField(uint32_t device, int field, int size); // A simplified version of pciConfigRead() that will take 3 parameters and read from a PCI device config space field. +void pciScan(pciFunction_t func, int type, void *extra); // Scans the PCI buses for devices (used to implement device discovery) +#endif diff --git a/source/kernel/include/pic.h b/source/kernel/include/pic.h index a3662720..504455c4 100644 --- a/source/kernel/include/pic.h +++ b/source/kernel/include/pic.h @@ -1,131 +1,131 @@ -// pic.h - Header file for pic.c (Programmable Interrupt Controller) - -#ifndef PIC_H -#define PIC_H - -// Includes -#include "include/idt.h" // Interrupt Descriptor Table - -#include "include/hal.h" // Hardware Abstraction Layer -#include "include/terminal.h" // Terminal output (printf) -#include "include/libc/stdint.h" // Integer types like uint8_t, uint16_t, etc... - - -// Definitions - - - - -// PIC 1 register port addresses -#define PIC1_REG_COMMAND 0x20 -#define PIC1_REG_STATUS 0x20 -#define PIC1_REG_DATA 0x21 -#define PIC1_REG_IMR 0x21 - -// PIC 2 register port addresses -#define PIC2_REG_COMMAND 0xA0 -#define PIC2_REG_STATUS 0xA0 -#define PIC2_REG_DATA 0xA1 -#define PIC2_REG_IMR 0xA1 - -// Initialization control word 1 bit masks -#define PIC_ICW1_MASK_IC4 0x1 // 00000001 -#define PIC_ICW1_MASK_SNGL 0x2 // 00000010 -#define PIC_ICW1_MASK_ADI 0x4 // 00000100 -#define PIC_ICW1_MASK_LTIM 0x8 // 00001000 -#define PIC_ICW1_MASK_INIT 0x10 // 00010000 - -// Note: Initialization control words 2 and 3 don't require bit masks, so we don't need to define them -// Control word 4, on the other hand does, so we do need to define them. - -// Initialization control word 4 bit masks -#define PIC_ICW4_MASK_UPM 0x1 // 00000001 -#define PIC_ICW4_MASK_AEOI 0x2 // 00000010 -#define PIC_ICW4_MASK_MS 0x4 // 00000100 -#define PIC_ICW4_MASK_BUF 0x8 // 00001000 -#define PIC_ICW4_MASK_SFNM 0x10 // 00010000 - - - -// Moving on to the control bits... -// Initialization command 1 control bits -#define PIC_ICW1_IC4_EXPECT 1 // 1 -#define PIC_ICW1_IC4_NO 0 // 0 -#define PIC_ICW1_SNGL_YES 2 // 10 -#define PIC_ICW1_SNGL_NO 0 // 00 -#define PIC_ICW1_ADI_CALLINTERVAL4 4 // 100 -#define PIC_ICW1_ADI_CALLINTERVAL8 0 // 000 -#define PIC_ICW1_LTIM_LEVELTRIGGERED 8 // 1000 -#define PIC_ICW1_LTIM_EDGETRIGGERED 0 // 0000 -#define PIC_ICW1_INIT_YES 0x10 // 10000 -#define PIC_ICW1_INIT_NO 0 // 00000 - -// Initialization command 4 control bits -#define PIC_ICW4_UPM_86MODE 1 // 1 -#define PIC_ICW4_UPM_MCSMODE 0 // 0 -#define PIC_ICW4_AEOI_AUTOEOI 2 // 10 -#define PIC_ICW4_AEOI_NOAUTOEOI 0 // 00 -#define PIC_ICW4_MS_BUFFERMASTER 4 // 100 -#define PIC_ICW4_MS_BUFFERSLAVE 0 // 0 -#define PIC_ICW4_BUF_MODEYES 8 // 1000 -#define PIC_ICW4_BUF_MODENO 0 // 0 -#define PIC_ICW4_SFNM_NESTEDMODE 0x10 // 10000 -#define PIC_ICW4_SFNM_NOTNESTED 0 // 0 - -// Devices - -// These devices use PIC 1 to generate interrupts -#define PIC_IRQ_TIMER 0 -#define PIC_IRQ_KEYBOARD 1 -#define PIC_IRQ_SERIAL2 3 -#define PIC_IRQ_SERIAL1 4 -#define PIC_IRQ_PARALLEL2 5 -#define PIC_IRQ_DISKETTE 6 -#define PIC_IRQ_PARALLEL1 7 - -// These devices use PIC 2 to generate interrupts -#define PIC_IRQ_CMOSTTIMER 0 -#define PIC_IRQ_CGARETRACE 1 -#define PIC_IRQ_AUXILIARY 4 -#define PIC_IRQ_FPU 5 -#define PIC_IRQ_HDC 6 - - -// Command word bit masks - -// Command word 2 bit masks - use when sending commands -#define PIC_OCW2_MASK_L1 1 // 00000001 -#define PIC_OCW2_MASK_L2 2 // 00000010 -#define PIC_OCW2_MASK_L3 4 // 00000100 -#define PIC_OCW2_MASK_EOI 0x20 // 00100000 -#define PIC_OCW2_MASK_SL 0x40 // 01000000 -#define PIC_OCW2_MASK_ROTATE 0x80 // 10000000 - -// Command word 3 bit masks - use when sending commands -#define PIC_OCW3_MASK_RIS 1 // 00000001 -#define PIC_OCW3_MASK_RIR 2 // 00000010 -#define PIC_OCW3_MASK_MODE 4 // 00000100 -#define PIC_OCW3_MASK_SMM 0x20 // 00100000 -#define PIC_OCW3_MASK_ESMM 0x40 // 01000000 -#define PIC_OCW3_MASK_D7 0x80 // 10000000 - - - -// Function definitions - -// Read data byte from PIC -extern uint8_t picReadData(uint8_t picNum); - -// Send a data byte from PIC -extern void picSendData(uint8_t data, uint8_t picNum); - -// Send operational command to PIC -extern void picSendCommand(uint8_t cmd, uint8_t picNum); - -// Enables and disables interrupts -extern void picMaskIRQ(uint8_t irqmask, uint8_t picNum); - -// Initialize pic -extern void picInit(uint8_t base0, uint8_t base1); - -#endif \ No newline at end of file +// pic.h - Header file for pic.c (Programmable Interrupt Controller) + +#ifndef PIC_H +#define PIC_H + +// Includes +#include // Interrupt Descriptor Table + +#include // Hardware Abstraction Layer +#include // Terminal output (printf) +#include // Integer types like uint8_t, uint16_t, etc... + + +// Definitions + + + + +// PIC 1 register port addresses +#define PIC1_REG_COMMAND 0x20 +#define PIC1_REG_STATUS 0x20 +#define PIC1_REG_DATA 0x21 +#define PIC1_REG_IMR 0x21 + +// PIC 2 register port addresses +#define PIC2_REG_COMMAND 0xA0 +#define PIC2_REG_STATUS 0xA0 +#define PIC2_REG_DATA 0xA1 +#define PIC2_REG_IMR 0xA1 + +// Initialization control word 1 bit masks +#define PIC_ICW1_MASK_IC4 0x1 // 00000001 +#define PIC_ICW1_MASK_SNGL 0x2 // 00000010 +#define PIC_ICW1_MASK_ADI 0x4 // 00000100 +#define PIC_ICW1_MASK_LTIM 0x8 // 00001000 +#define PIC_ICW1_MASK_INIT 0x10 // 00010000 + +// Note: Initialization control words 2 and 3 don't require bit masks, so we don't need to define them +// Control word 4, on the other hand does, so we do need to define them. + +// Initialization control word 4 bit masks +#define PIC_ICW4_MASK_UPM 0x1 // 00000001 +#define PIC_ICW4_MASK_AEOI 0x2 // 00000010 +#define PIC_ICW4_MASK_MS 0x4 // 00000100 +#define PIC_ICW4_MASK_BUF 0x8 // 00001000 +#define PIC_ICW4_MASK_SFNM 0x10 // 00010000 + + + +// Moving on to the control bits... +// Initialization command 1 control bits +#define PIC_ICW1_IC4_EXPECT 1 // 1 +#define PIC_ICW1_IC4_NO 0 // 0 +#define PIC_ICW1_SNGL_YES 2 // 10 +#define PIC_ICW1_SNGL_NO 0 // 00 +#define PIC_ICW1_ADI_CALLINTERVAL4 4 // 100 +#define PIC_ICW1_ADI_CALLINTERVAL8 0 // 000 +#define PIC_ICW1_LTIM_LEVELTRIGGERED 8 // 1000 +#define PIC_ICW1_LTIM_EDGETRIGGERED 0 // 0000 +#define PIC_ICW1_INIT_YES 0x10 // 10000 +#define PIC_ICW1_INIT_NO 0 // 00000 + +// Initialization command 4 control bits +#define PIC_ICW4_UPM_86MODE 1 // 1 +#define PIC_ICW4_UPM_MCSMODE 0 // 0 +#define PIC_ICW4_AEOI_AUTOEOI 2 // 10 +#define PIC_ICW4_AEOI_NOAUTOEOI 0 // 00 +#define PIC_ICW4_MS_BUFFERMASTER 4 // 100 +#define PIC_ICW4_MS_BUFFERSLAVE 0 // 0 +#define PIC_ICW4_BUF_MODEYES 8 // 1000 +#define PIC_ICW4_BUF_MODENO 0 // 0 +#define PIC_ICW4_SFNM_NESTEDMODE 0x10 // 10000 +#define PIC_ICW4_SFNM_NOTNESTED 0 // 0 + +// Devices + +// These devices use PIC 1 to generate interrupts +#define PIC_IRQ_TIMER 0 +#define PIC_IRQ_KEYBOARD 1 +#define PIC_IRQ_SERIAL2 3 +#define PIC_IRQ_SERIAL1 4 +#define PIC_IRQ_PARALLEL2 5 +#define PIC_IRQ_DISKETTE 6 +#define PIC_IRQ_PARALLEL1 7 + +// These devices use PIC 2 to generate interrupts +#define PIC_IRQ_CMOSTTIMER 0 +#define PIC_IRQ_CGARETRACE 1 +#define PIC_IRQ_AUXILIARY 4 +#define PIC_IRQ_FPU 5 +#define PIC_IRQ_HDC 6 + + +// Command word bit masks + +// Command word 2 bit masks - use when sending commands +#define PIC_OCW2_MASK_L1 1 // 00000001 +#define PIC_OCW2_MASK_L2 2 // 00000010 +#define PIC_OCW2_MASK_L3 4 // 00000100 +#define PIC_OCW2_MASK_EOI 0x20 // 00100000 +#define PIC_OCW2_MASK_SL 0x40 // 01000000 +#define PIC_OCW2_MASK_ROTATE 0x80 // 10000000 + +// Command word 3 bit masks - use when sending commands +#define PIC_OCW3_MASK_RIS 1 // 00000001 +#define PIC_OCW3_MASK_RIR 2 // 00000010 +#define PIC_OCW3_MASK_MODE 4 // 00000100 +#define PIC_OCW3_MASK_SMM 0x20 // 00100000 +#define PIC_OCW3_MASK_ESMM 0x40 // 01000000 +#define PIC_OCW3_MASK_D7 0x80 // 10000000 + + + +// Function definitions + +// Read data byte from PIC +extern uint8_t picReadData(uint8_t picNum); + +// Send a data byte from PIC +extern void picSendData(uint8_t data, uint8_t picNum); + +// Send operational command to PIC +extern void picSendCommand(uint8_t cmd, uint8_t picNum); + +// Enables and disables interrupts +extern void picMaskIRQ(uint8_t irqmask, uint8_t picNum); + +// Initialize pic +extern void picInit(uint8_t base0, uint8_t base1); + +#endif diff --git a/source/kernel/include/pit.h b/source/kernel/include/pit.h index c05b6ae4..bc44eea3 100644 --- a/source/kernel/include/pit.h +++ b/source/kernel/include/pit.h @@ -1,70 +1,70 @@ -// pit.h - Header file for pit.c (Programmable Interval Timer) - -#ifndef PIT_H -#define PIT_H - -// Includes -#include "include/idt.h" // Interrupt Descriptor Table -#include "include/pic.h" // Programmable Interrupt Controller -#include "include/hal.h" // Hardware Abstraction Layer -#include "include/terminal.h" // Terminal output (printf) -#include "include/isr.h" // Interrupt Service Routines -#include "include/libc/stdint.h" // Integer declarations - -// Definitions - -// Controller registers -#define PIT_REG_COUNTER0 0x40 -#define PIT_REG_COUNTER1 0x41 -#define PIT_REG_COUNTER2 0x42 -#define PIT_REG_COMMAND 0x43 - - -// Operational command bit masks - -#define PIT_OCW_MASK_BINCOUNT 1 // 00000001 -#define PIT_OCW_MASK_MODE 0xE // 00001110 -#define PIT_OCW_MASK_RL 0x30 // 00110000 -#define PIT_OCW_MASK_COUNTER 0xC0 // 11000000 - - -// Operational command control bits - -// Use these when setting binary count mode -#define PIT_OCW_BINCOUNT_BINARY 0 // 0 -#define PIT_OCW_BINCOUNT_BCD 1 // 1 - -// Use these when setting counter mode -#define PIT_OCW_MODE_TERMINALCOUNT 0 // 0000 -#define PIT_OCW_MODE_ONESHOT 0x2 // 0010 -#define PIT_OCW_MODE_RATEGEN 0x4 // 0100 -#define PIT_OCW_MODE_SQUAREWAVEGEN 0x6 // 0110 -#define PIT_OCW_MODE_SOFTWARETRIG 0x8 // 1000 -#define PIT_OCW_MODE_HARDWARETRIG 0xA // 1010 - -// Use these when setting data transfer -#define PIT_OCW_RL_LATCH 0 // 000000 -#define PIT_OCW_RL_LSBONLY 0x10 // 010000 -#define PIT_OCW_RL_MSBONLY 0x20 // 100000 -#define PIT_OCW_RL_DATA 0x30 // 110000 - -// Use these when setting the counter we're working with -#define PIT_OCW_COUNTER_0 0 // 00000000 -#define PIT_OCW_COUNTER_1 0x40 // 01000000 -#define PIT_OCW_COUNTER_2 0x80 // 10000000 - - - -// Functions - - -void pitSendCommand(uint8_t cmd); // Send operational command to PIT. -void pitSendData(uint16_t data, uint8_t counter); // Write data byte to a counter. -uint32_t pitSetTickCount(uint32_t i); // Sets new PIT tick count and returns prev. value. -uint32_t pitGetTickCount(); // Returns current tick count. -void pitStartCounter(uint32_t freq, uint8_t counter, uint8_t mode); // Starts a counter (counter continues until another call) -void pitInit(); // Initialize PIT -bool pitIsInitialized(); // Check if the PIT is initialized. - - -#endif \ No newline at end of file +// pit.h - Header file for pit.c (Programmable Interval Timer) + +#ifndef PIT_H +#define PIT_H + +// Includes +#include // Interrupt Descriptor Table +#include // Programmable Interrupt Controller +#include // Hardware Abstraction Layer +#include // Terminal output (printf) +#include // Interrupt Service Routines +#include // Integer declarations + +// Definitions + +// Controller registers +#define PIT_REG_COUNTER0 0x40 +#define PIT_REG_COUNTER1 0x41 +#define PIT_REG_COUNTER2 0x42 +#define PIT_REG_COMMAND 0x43 + + +// Operational command bit masks + +#define PIT_OCW_MASK_BINCOUNT 1 // 00000001 +#define PIT_OCW_MASK_MODE 0xE // 00001110 +#define PIT_OCW_MASK_RL 0x30 // 00110000 +#define PIT_OCW_MASK_COUNTER 0xC0 // 11000000 + + +// Operational command control bits + +// Use these when setting binary count mode +#define PIT_OCW_BINCOUNT_BINARY 0 // 0 +#define PIT_OCW_BINCOUNT_BCD 1 // 1 + +// Use these when setting counter mode +#define PIT_OCW_MODE_TERMINALCOUNT 0 // 0000 +#define PIT_OCW_MODE_ONESHOT 0x2 // 0010 +#define PIT_OCW_MODE_RATEGEN 0x4 // 0100 +#define PIT_OCW_MODE_SQUAREWAVEGEN 0x6 // 0110 +#define PIT_OCW_MODE_SOFTWARETRIG 0x8 // 1000 +#define PIT_OCW_MODE_HARDWARETRIG 0xA // 1010 + +// Use these when setting data transfer +#define PIT_OCW_RL_LATCH 0 // 000000 +#define PIT_OCW_RL_LSBONLY 0x10 // 010000 +#define PIT_OCW_RL_MSBONLY 0x20 // 100000 +#define PIT_OCW_RL_DATA 0x30 // 110000 + +// Use these when setting the counter we're working with +#define PIT_OCW_COUNTER_0 0 // 00000000 +#define PIT_OCW_COUNTER_1 0x40 // 01000000 +#define PIT_OCW_COUNTER_2 0x80 // 10000000 + + + +// Functions + + +void pitSendCommand(uint8_t cmd); // Send operational command to PIT. +void pitSendData(uint16_t data, uint8_t counter); // Write data byte to a counter. +uint32_t pitSetTickCount(uint32_t i); // Sets new PIT tick count and returns prev. value. +uint32_t pitGetTickCount(); // Returns current tick count. +void pitStartCounter(uint32_t freq, uint8_t counter, uint8_t mode); // Starts a counter (counter continues until another call) +void pitInit(); // Initialize PIT +bool pitIsInitialized(); // Check if the PIT is initialized. + + +#endif diff --git a/source/kernel/include/pmm.h b/source/kernel/include/pmm.h index 5e9a0427..bd73a7a7 100644 --- a/source/kernel/include/pmm.h +++ b/source/kernel/include/pmm.h @@ -4,11 +4,11 @@ #define PMM_H // Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/libc/string.h" // String functions -#include "include/heap.h" // kmalloc() -#include "include/bootinfo.h" // Multiboot info -#include "include/serial.h" +#include // Integer declarations +#include // String functions +#include // kmalloc() +#include // Multiboot info +#include // Variables extern uint32_t *frames; @@ -57,4 +57,4 @@ uint32_t pmm_getMaxBlocks(); // Returns the total amount of memory blocks uint32_t pmm_getUsedBlocks(); // Returns the amount of used blocks uint32_t pmm_getFreeBlocks(); // Returns the amount of free blocks -#endif \ No newline at end of file +#endif diff --git a/source/kernel/include/processor.h b/source/kernel/include/processor.h index 1ffeb3c1..9cbe8f77 100644 --- a/source/kernel/include/processor.h +++ b/source/kernel/include/processor.h @@ -1,48 +1,48 @@ -// processor.h - Handles all CPU related functions - -#ifndef PROCESSOR_H -#define PROCESSOR_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/gdt.h" // Global descriptor table -#include "include/idt.h" // Interrupt descriptor table -#include "include/isr.h" // Interrupt service routines -#include "include/hal.h" // Hardware Abstraction Layer - - -// Typedefs - -typedef struct { - int XOP_support; // XOP support - int FMA4_support; // FMA4 support - int CVT16_support; // CVT16 support - int AVX_support; // AVX support (Advanced Vector Extensions) - int XSAVE_support; // XSAVE support (CPU extended power management support) - int AVX2_support; // AVX2 support - // TODO: AVX-512 support -} sseData_t; - -typedef struct { - char vendor[13]; // Vendor data - int long_mode_capable; // Long mode capabilities - uint32_t frequency; // Frequency (in Hz) - - // Streaming SIMD Extensions - int sse_support; // SSE support - int sse2_support; // SSE2 support - int sse3_support; // SSE3 support - int ssse3_support; // SSSE3 Support (Supplemental Streaming SIMD Extensions) - int sse4_support; // SSE4 support - sseData_t sse5_Data; // SSE5 data -} cpuInfo_t; - - - -// Functions -void cpuInit(); // Initializes the CPU with ISR, IDT, and GDT -uint32_t getCPUFrequency(); // Returns the CPU frequency (todo: create processor.c). -bool isCPULongModeCapable(); // Returns if the CPU is 64-bit capable -char *getCPUVendorData(); // Returns CPU vendor data - -#endif \ No newline at end of file +// processor.h - Handles all CPU related functions + +#ifndef PROCESSOR_H +#define PROCESSOR_H + +// Includes +#include // Integer declarations +#include // Global descriptor table +#include // Interrupt descriptor table +#include // Interrupt service routines +#include // Hardware Abstraction Layer + + +// Typedefs + +typedef struct { + int XOP_support; // XOP support + int FMA4_support; // FMA4 support + int CVT16_support; // CVT16 support + int AVX_support; // AVX support (Advanced Vector Extensions) + int XSAVE_support; // XSAVE support (CPU extended power management support) + int AVX2_support; // AVX2 support + // TODO: AVX-512 support +} sseData_t; + +typedef struct { + char vendor[13]; // Vendor data + int long_mode_capable; // Long mode capabilities + uint32_t frequency; // Frequency (in Hz) + + // Streaming SIMD Extensions + int sse_support; // SSE support + int sse2_support; // SSE2 support + int sse3_support; // SSE3 support + int ssse3_support; // SSSE3 Support (Supplemental Streaming SIMD Extensions) + int sse4_support; // SSE4 support + sseData_t sse5_Data; // SSE5 data +} cpuInfo_t; + + + +// Functions +void cpuInit(); // Initializes the CPU with ISR, IDT, and GDT +uint32_t getCPUFrequency(); // Returns the CPU frequency (todo: create processor.c). +bool isCPULongModeCapable(); // Returns if the CPU is 64-bit capable +char *getCPUVendorData(); // Returns CPU vendor data + +#endif diff --git a/source/kernel/include/regs.h b/source/kernel/include/regs.h index efebf704..238e277c 100644 --- a/source/kernel/include/regs.h +++ b/source/kernel/include/regs.h @@ -1,33 +1,33 @@ -// regs.h - simple header file that contains definitions of register structs - -#ifndef REGS_H -#define REGS_H - - -// Includes -#include "include/libc/stdint.h" // Integer declarations - -// Typedefs -typedef struct REGISTERS { - uint32_t ds; - uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; // pushed by pusha - uint32_t int_no, err_code; // Interrupt # and error code - uint32_t eip, cs, eflags, useresp, ss; // pushed by the processor automatically -} registers_t; - -// Registers (16-bit real mode) -typedef struct { - uint16_t di, si, bp, sp, bx, dx, cx, ax; - uint16_t ds, es, fs, gs, ss; - uint16_t eflags; -} REGISTERS_16; - -// A special register struct for multitasking -typedef struct REGISTERS_MULTITASK { - uint32_t ds, es; - uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; // pushed by pusha - uint32_t int_no, err_code; // Interrupt # and error code - uint32_t eip, cs, eflags, useresp, ss; // pushed by the processor automatically -} registers_multitask_t; - -#endif \ No newline at end of file +// regs.h - simple header file that contains definitions of register structs + +#ifndef REGS_H +#define REGS_H + + +// Includes +#include // Integer declarations + +// Typedefs +typedef struct REGISTERS { + uint32_t ds; + uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; // pushed by pusha + uint32_t int_no, err_code; // Interrupt # and error code + uint32_t eip, cs, eflags, useresp, ss; // pushed by the processor automatically +} registers_t; + +// Registers (16-bit real mode) +typedef struct { + uint16_t di, si, bp, sp, bx, dx, cx, ax; + uint16_t ds, es, fs, gs, ss; + uint16_t eflags; +} REGISTERS_16; + +// A special register struct for multitasking +typedef struct REGISTERS_MULTITASK { + uint32_t ds, es; + uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; // pushed by pusha + uint32_t int_no, err_code; // Interrupt # and error code + uint32_t eip, cs, eflags, useresp, ss; // pushed by the processor automatically +} registers_multitask_t; + +#endif diff --git a/source/kernel/include/rtc.h b/source/kernel/include/rtc.h index 2bb75757..d3542a53 100644 --- a/source/kernel/include/rtc.h +++ b/source/kernel/include/rtc.h @@ -1,27 +1,27 @@ -// rtc.h - header file for the real-time clock driver - -#ifndef RTC_H -#define RTC_H - -// Includes -#include "include/libc/stdint.h" // Integer definitions -#include "include/hal.h" // Hardware abstraction layer - -// WARNING: The below is a user-created constant! This needs to change each year and cannot automatically update! -#define RTC_CURRENT_YEAR 2023 // wooo 2023 - -// The rest are just ports and stuff. -#define CMOS_ADDRESS 0x70 -#define CMOS_DATA 0x71 - -#define RTC_SECOND_REGISTER 0x00 -#define RTC_MINUTE_REGISTER 0x02 -#define RTC_HOUR_REGISTER 0x04 -#define RTC_DAY_REGISTER 0x07 -#define RTC_MONTH_REGISTER 0x08 -#define RTC_YEAR_REGISTER 0x09 - -// Functions -void rtc_getDateTime(uint8_t *second, uint8_t *minute, uint8_t *hour, uint8_t *day, uint8_t *month, int *year); // Returns the date and time (in the pointers) - -#endif \ No newline at end of file +// rtc.h - header file for the real-time clock driver + +#ifndef RTC_H +#define RTC_H + +// Includes +#include // Integer definitions +#include // Hardware abstraction layer + +// WARNING: The below is a user-created constant! This needs to change each year and cannot automatically update! +#define RTC_CURRENT_YEAR 2023 // wooo 2023 + +// The rest are just ports and stuff. +#define CMOS_ADDRESS 0x70 +#define CMOS_DATA 0x71 + +#define RTC_SECOND_REGISTER 0x00 +#define RTC_MINUTE_REGISTER 0x02 +#define RTC_HOUR_REGISTER 0x04 +#define RTC_DAY_REGISTER 0x07 +#define RTC_MONTH_REGISTER 0x08 +#define RTC_YEAR_REGISTER 0x09 + +// Functions +void rtc_getDateTime(uint8_t *second, uint8_t *minute, uint8_t *hour, uint8_t *day, uint8_t *month, int *year); // Returns the date and time (in the pointers) + +#endif diff --git a/source/kernel/include/serial.h b/source/kernel/include/serial.h index 099da348..c70e5f4a 100644 --- a/source/kernel/include/serial.h +++ b/source/kernel/include/serial.h @@ -1,30 +1,30 @@ -// serial.h - header file for serial.c (serial logging manager) - -#ifndef SERIAL_H -#define SERIAL_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/hal.h" // outportb() and inportb() -#include "include/terminal.h" // printf_putchar function. - -// Definitions -#define SERIAL_COM1 0x3F8 -#define SERIAL_COM2 0x2F8 -#define SERIAL_COM3 0x3E8 -#define SERIAL_COM4 0x2E8 -#define SERIAL_COM5 0x5F8 -#define SERIAL_COM6 0x4F8 -#define SERIAL_COM7 0x5E8 -#define SERIAL_COM8 0x4E8 - -// Variables -extern bool isSerialEnabled; - -// Functions -void serialInit(); // Initialize serial (default port COM1, unchangable as of now.) -char serialRead(); // Read one character from SERIAL_COM1 -void serialReadLine(bool printChars, char *bufferPtr); // Read line from SERIAL_COM1 -void serialWrite(void *user, char c); // Writes character 'c' to serial when transmit is empty. -void serialPrintf(const char *str, ...); // Prints a formatted line to SERIAL_COM1. -#endif \ No newline at end of file +// serial.h - header file for serial.c (serial logging manager) + +#ifndef SERIAL_H +#define SERIAL_H + +// Includes +#include // Integer declarations +#include // outportb() and inportb() +#include // printf_putchar function. + +// Definitions +#define SERIAL_COM1 0x3F8 +#define SERIAL_COM2 0x2F8 +#define SERIAL_COM3 0x3E8 +#define SERIAL_COM4 0x2E8 +#define SERIAL_COM5 0x5F8 +#define SERIAL_COM6 0x4F8 +#define SERIAL_COM7 0x5E8 +#define SERIAL_COM8 0x4E8 + +// Variables +extern bool isSerialEnabled; + +// Functions +void serialInit(); // Initialize serial (default port COM1, unchangable as of now.) +char serialRead(); // Read one character from SERIAL_COM1 +void serialReadLine(bool printChars, char *bufferPtr); // Read line from SERIAL_COM1 +void serialWrite(void *user, char c); // Writes character 'c' to serial when transmit is empty. +void serialPrintf(const char *str, ...); // Prints a formatted line to SERIAL_COM1. +#endif diff --git a/source/kernel/include/syscall.h b/source/kernel/include/syscall.h index 279d9b52..4cf3bfb5 100644 --- a/source/kernel/include/syscall.h +++ b/source/kernel/include/syscall.h @@ -4,8 +4,8 @@ #define SYSCALL_H // Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/isr.h" // Interrupt Service Routines +#include // Integer declarations +#include // Interrupt Service Routines // Macros // See syscall.c for an explanation of why we need these macros. @@ -41,4 +41,4 @@ int syscall_##func(P1 p1) { \ void initSyscalls(); -#endif \ No newline at end of file +#endif diff --git a/source/kernel/include/terminal.h b/source/kernel/include/terminal.h index 9e0b987d..f48b9c72 100644 --- a/source/kernel/include/terminal.h +++ b/source/kernel/include/terminal.h @@ -1,56 +1,56 @@ -// terminal.h - Handling all terminal functions(like printf, putchar, etc.) - - -#ifndef TERMINAL_H -#define TERMINAL_H - -#include "include/libc/stddef.h" // size_t declaration -#include "include/libc/stdint.h" // Integer type declarations -#include "include/libc/stdbool.h" // Boolean declarations -#include "include/libc/string.h" // String functions -#include "include/libc/limits.h" // Limits on integers and more. - -//#include "include/libc/stdarg.h" // va argument handling (for ... on printf) -// #include "include/libc/va_list.h" // va_list declared here. -#include -#include "include/graphics.h" // Utility functions -#include "include/serial.h" // Serial logging -#include "include/vesa.h" // VESA VBE - - -// Variable declarations - -static size_t terminalX; // X position of terminal buffer, or column -static size_t terminalY; // Y position of terminal buffer, or row -static uint8_t terminalColor; // The current color of the terminal. -static uint16_t *terminalBuffer; // The most important one: the terminal buffer. -extern int vbeWidth, vbeHeight; -extern int terminalMode; // 0 signifies VGA mode, 1 signifies VESA VBE. - - -// VGA memory address, width, height etc are stored in graphics.h. - -// Function declarations - -void terminalInit(void); // terminalInit() - load the terminal -void changeTerminalMode(int mode); // changeTerminalMode() - Update the terminal mode (0 = VGA, 1 = VESA) -void updateTerminalColor(uint8_t color); // updateTerminalColor() - Change the terminal color. Requires a vgaColorEntry already setup. -void terminalPutcharXY(unsigned char c, uint8_t color, size_t x, size_t y); // terminalPutcharXY() - Place an unsigned char at a certain X and Y. Not recommended, doesn't include scrolling stuff. -void terminalGotoXY(size_t x, size_t y); // terminalGotoXY() - Change the position to X and Y -void scrollTerminal(); // scrollTerminal() - I don't see how this could be used outside of terminal.c, but just in case. Scrolls the terminal down. -void terminalDeleteLastLine(); // terminalDeleteLastLine() - Removes the last line placed by the terminal. -void clearScreen(uint8_t fg, uint8_t bg); // clearScreen() - Clears the terminal screen. -void terminalPutchar(char c); // terminalPutchar() - Recommended function. Incorporates scrollTerminal and terminalDeleteLastLine. -void terminalWrite(const char *data, size_t size); // terminalWrite() - This nor terminalWriteString is recommended for use. Use printf. It prints data using a for loop, but needs length. -void terminalWriteString(const char* data); // terminalWriteString() - The exact same as terminalWrite but with strlen() included. -void terminalBackspace(); // terminalBackspace() - Removes the last character printed. -void terminalWriteStringXY(const char *data, size_t x, size_t y); // terminalWriteStringXY() - Moves the terminal to X and Y, prints the string, then moves back to the original position. -void terminalMoveArrowKeys(int arrowKey); // terminalMoveArrowKeys() - used by keyboard.c, a function to move the cursor around -void updateBottomText(char *bottomText); // updateBottomText() - A function to update that bottom bar of text -void enableShell(char *shellToUse); // Enables a boundary that cannot be overwritten. -void updateTextCursor_vesa(); // Updating the text cursor in VESA VBE. -void terminalUpdateScreen(); // Update the screen buffers -void instantUpdateTerminalColor(uint8_t fg, uint8_t bg); // Instantly update the terminal color (VESA only) -void terminalSetUpdateScreen(bool state); // Toggles whether the screen should update when terminalUpdateScreen() is called - -#endif \ No newline at end of file +// terminal.h - Handling all terminal functions(like printf, putchar, etc.) + + +#ifndef TERMINAL_H +#define TERMINAL_H + +#include // size_t declaration +#include // Integer type declarations +#include // Boolean declarations +#include // String functions +#include // Limits on integers and more. + +//#include "include/libc/stdarg.h" // va argument handling (for ... on printf) +// #include "include/libc/va_list.h" // va_list declared here. +#include +#include // Utility functions +#include // Serial logging +#include // VESA VBE + + +// Variable declarations + +static size_t terminalX; // X position of terminal buffer, or column +static size_t terminalY; // Y position of terminal buffer, or row +static uint8_t terminalColor; // The current color of the terminal. +static uint16_t *terminalBuffer; // The most important one: the terminal buffer. +extern int vbeWidth, vbeHeight; +extern int terminalMode; // 0 signifies VGA mode, 1 signifies VESA VBE. + + +// VGA memory address, width, height etc are stored in graphics.h. + +// Function declarations + +void terminalInit(void); // terminalInit() - load the terminal +void changeTerminalMode(int mode); // changeTerminalMode() - Update the terminal mode (0 = VGA, 1 = VESA) +void updateTerminalColor(uint8_t color); // updateTerminalColor() - Change the terminal color. Requires a vgaColorEntry already setup. +void terminalPutcharXY(unsigned char c, uint8_t color, size_t x, size_t y); // terminalPutcharXY() - Place an unsigned char at a certain X and Y. Not recommended, doesn't include scrolling stuff. +void terminalGotoXY(size_t x, size_t y); // terminalGotoXY() - Change the position to X and Y +void scrollTerminal(); // scrollTerminal() - I don't see how this could be used outside of terminal.c, but just in case. Scrolls the terminal down. +void terminalDeleteLastLine(); // terminalDeleteLastLine() - Removes the last line placed by the terminal. +void clearScreen(uint8_t fg, uint8_t bg); // clearScreen() - Clears the terminal screen. +void terminalPutchar(char c); // terminalPutchar() - Recommended function. Incorporates scrollTerminal and terminalDeleteLastLine. +void terminalWrite(const char *data, size_t size); // terminalWrite() - This nor terminalWriteString is recommended for use. Use printf. It prints data using a for loop, but needs length. +void terminalWriteString(const char* data); // terminalWriteString() - The exact same as terminalWrite but with strlen() included. +void terminalBackspace(); // terminalBackspace() - Removes the last character printed. +void terminalWriteStringXY(const char *data, size_t x, size_t y); // terminalWriteStringXY() - Moves the terminal to X and Y, prints the string, then moves back to the original position. +void terminalMoveArrowKeys(int arrowKey); // terminalMoveArrowKeys() - used by keyboard.c, a function to move the cursor around +void updateBottomText(char *bottomText); // updateBottomText() - A function to update that bottom bar of text +void enableShell(char *shellToUse); // Enables a boundary that cannot be overwritten. +void updateTextCursor_vesa(); // Updating the text cursor in VESA VBE. +void terminalUpdateScreen(); // Update the screen buffers +void instantUpdateTerminalColor(uint8_t fg, uint8_t bg); // Instantly update the terminal color (VESA only) +void terminalSetUpdateScreen(bool state); // Toggles whether the screen should update when terminalUpdateScreen() is called + +#endif diff --git a/source/kernel/include/tree.h b/source/kernel/include/tree.h index 07d7484c..9a8e53fe 100644 --- a/source/kernel/include/tree.h +++ b/source/kernel/include/tree.h @@ -5,10 +5,10 @@ #define TREE_H // Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/libc/stddef.h" // size_t -#include "include/list.h" // List implementation -#include "include/mem.h" // Memory allocation +#include // Integer declarations +#include // size_t +#include // List implementation +#include // Memory allocation // Typedefs typedef struct tree_node { @@ -42,4 +42,4 @@ void tree_break_off(tree_t * tree, tree_node_t * node); size_t tree_count_children(tree_node_t *node); tree_node_t *tree_find_parent(tree_t *tree, tree_node_t *node); -#endif \ No newline at end of file +#endif diff --git a/source/kernel/include/tss.h b/source/kernel/include/tss.h index 6bf08cc5..bcbcc3cb 100644 --- a/source/kernel/include/tss.h +++ b/source/kernel/include/tss.h @@ -1,56 +1,56 @@ -// tss.h - Task State Segment structure definitions - -#ifndef TSS_H -#define TSS_H - -// Includes -#include "include/libc/stdint.h" // Integer definitions -#include "include/gdt.h" - - -// Typedefs -// Note: This will need to be updated when we upgrade to reduceOS x86_64. -// However, by then we may have an entirely new TSS implementation, so, eh. - - -// https://wiki.osdev.org/Getting_to_Ring_3 -typedef struct { - uint32_t prev_tss; // The previous TSS - with hardware task switching these form a kind of backward linked list. - uint32_t esp0; // The stack pointer to load when changing to kernel mode. - uint32_t ss0; // The stack segment to load when changing to kernel mode. - // Everything below here is unused. - uint32_t esp1; // esp and ss 1 and 2 would be used when switching to rings 1 or 2. - uint32_t ss1; - uint32_t esp2; - uint32_t ss2; - uint32_t cr3; - uint32_t eip; - uint32_t eflags; - uint32_t eax; - uint32_t ecx; - uint32_t edx; - uint32_t ebx; - uint32_t esp; - uint32_t ebp; - uint32_t esi; - uint32_t edi; - uint32_t es; - uint32_t cs; - uint32_t ss; - uint32_t ds; - uint32_t fs; - uint32_t gs; - uint32_t ldt; - uint16_t trap; - uint16_t iomap_base; -} __attribute__((packed)) tss_entry_t; - - -// External functions -extern void tssFlush(); - -// Functions -void tssWrite(int32_t index, uint16_t ss0, uint32_t esp0); -void setKernelStack(uint32_t stack); - -#endif +// tss.h - Task State Segment structure definitions + +#ifndef TSS_H +#define TSS_H + +// Includes +#include // Integer definitions +#include + + +// Typedefs +// Note: This will need to be updated when we upgrade to reduceOS x86_64. +// However, by then we may have an entirely new TSS implementation, so, eh. + + +// https://wiki.osdev.org/Getting_to_Ring_3 +typedef struct { + uint32_t prev_tss; // The previous TSS - with hardware task switching these form a kind of backward linked list. + uint32_t esp0; // The stack pointer to load when changing to kernel mode. + uint32_t ss0; // The stack segment to load when changing to kernel mode. + // Everything below here is unused. + uint32_t esp1; // esp and ss 1 and 2 would be used when switching to rings 1 or 2. + uint32_t ss1; + uint32_t esp2; + uint32_t ss2; + uint32_t cr3; + uint32_t eip; + uint32_t eflags; + uint32_t eax; + uint32_t ecx; + uint32_t edx; + uint32_t ebx; + uint32_t esp; + uint32_t ebp; + uint32_t esi; + uint32_t edi; + uint32_t es; + uint32_t cs; + uint32_t ss; + uint32_t ds; + uint32_t fs; + uint32_t gs; + uint32_t ldt; + uint16_t trap; + uint16_t iomap_base; +} __attribute__((packed)) tss_entry_t; + + +// External functions +extern void tssFlush(); + +// Functions +void tssWrite(int32_t index, uint16_t ss0, uint32_t esp0); +void setKernelStack(uint32_t stack); + +#endif diff --git a/source/kernel/include/vesa.h b/source/kernel/include/vesa.h index 77865c30..db135c9f 100644 --- a/source/kernel/include/vesa.h +++ b/source/kernel/include/vesa.h @@ -1,76 +1,76 @@ -// vesa.h - header file for the VESA VBE handler - -#ifndef VESA_H -#define VESA_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/bios32.h" // BIOS32 calls (for switching) -#include "include/bootinfo.h" - -// Typedefs - -// vbeInfoBlock_t - A block of information for VESA VBE -typedef struct { - char *signature; // Block signature, should always be "VESA" - uint16_t version; // Version of VBE - uint16_t oemStringPtr[2]; // Pointer to OEM - uint8_t features[4]; // Available features - uint32_t *videoModePtr; - uint16_t totalMemory; // Total video memory (in number of 64KB blocks) -} __attribute__((packed)) vbeInfoBlock_t; - -// vbeModeInfo_t - VBE mode information (structure originated from https://wiki.osdev.org/Getting_VBE_Mode_Info) -typedef struct { - uint16_t attributes; // deprecated, only bit 7 should be of interest to you, and it indicates the mode supports a linear frame buffer. - uint8_t window_a; // deprecated - uint8_t window_b; // deprecated - uint16_t granularity; // deprecated; used while calculating bank numbers - uint16_t window_size; - uint16_t segment_a; - uint16_t segment_b; - uint32_t win_func_ptr; // deprecated; used to switch banks from protected mode without returning to real mode - uint16_t pitch; // number of bytes per horizontal line - uint16_t width; // width in pixels - uint16_t height; // height in pixels - uint8_t w_char; // unused... - uint8_t y_char; // ... - uint8_t planes; - uint8_t bpp; // bits per pixel in this mode - uint8_t banks; // deprecated; total number of banks in this mode - uint8_t memory_model; - uint8_t bank_size; // deprecated; size of a bank, almost always 64 KB but may be 16 KB... - uint8_t image_pages; - uint8_t reserved0; - - uint8_t red_mask; - uint8_t red_position; - uint8_t green_mask; - uint8_t green_position; - uint8_t blue_mask; - uint8_t blue_position; - uint8_t reserved_mask; - uint8_t reserved_position; - uint8_t direct_color_attributes; - - uint32_t framebuffer; // physical address of the linear frame buffer; write here to draw to the screen - uint32_t off_screen_mem_off; - uint16_t off_screen_mem_size; // size of memory in the framebuffer but not being displayed on the screen - uint8_t reserved1[206]; -} __attribute__((packed)) vbeModeInfo_t; - - -// Framebuffers (probably not a good idea but I could care less) -extern uint32_t *vbeBuffer; -extern uint32_t *framebuffer; // 2nd framebuffer. -extern uint32_t modeWidth; -extern uint32_t modeHeight; - - -// Functions -void vesaInit(); -uint32_t RGB_VBE(uint8_t r, uint8_t g, uint8_t b); -void vbePutPixel(int x, int y, uint32_t color); - - -#endif \ No newline at end of file +// vesa.h - header file for the VESA VBE handler + +#ifndef VESA_H +#define VESA_H + +// Includes +#include // Integer declarations +#include // BIOS32 calls (for switching) +#include + +// Typedefs + +// vbeInfoBlock_t - A block of information for VESA VBE +typedef struct { + char *signature; // Block signature, should always be "VESA" + uint16_t version; // Version of VBE + uint16_t oemStringPtr[2]; // Pointer to OEM + uint8_t features[4]; // Available features + uint32_t *videoModePtr; + uint16_t totalMemory; // Total video memory (in number of 64KB blocks) +} __attribute__((packed)) vbeInfoBlock_t; + +// vbeModeInfo_t - VBE mode information (structure originated from https://wiki.osdev.org/Getting_VBE_Mode_Info) +typedef struct { + uint16_t attributes; // deprecated, only bit 7 should be of interest to you, and it indicates the mode supports a linear frame buffer. + uint8_t window_a; // deprecated + uint8_t window_b; // deprecated + uint16_t granularity; // deprecated; used while calculating bank numbers + uint16_t window_size; + uint16_t segment_a; + uint16_t segment_b; + uint32_t win_func_ptr; // deprecated; used to switch banks from protected mode without returning to real mode + uint16_t pitch; // number of bytes per horizontal line + uint16_t width; // width in pixels + uint16_t height; // height in pixels + uint8_t w_char; // unused... + uint8_t y_char; // ... + uint8_t planes; + uint8_t bpp; // bits per pixel in this mode + uint8_t banks; // deprecated; total number of banks in this mode + uint8_t memory_model; + uint8_t bank_size; // deprecated; size of a bank, almost always 64 KB but may be 16 KB... + uint8_t image_pages; + uint8_t reserved0; + + uint8_t red_mask; + uint8_t red_position; + uint8_t green_mask; + uint8_t green_position; + uint8_t blue_mask; + uint8_t blue_position; + uint8_t reserved_mask; + uint8_t reserved_position; + uint8_t direct_color_attributes; + + uint32_t framebuffer; // physical address of the linear frame buffer; write here to draw to the screen + uint32_t off_screen_mem_off; + uint16_t off_screen_mem_size; // size of memory in the framebuffer but not being displayed on the screen + uint8_t reserved1[206]; +} __attribute__((packed)) vbeModeInfo_t; + + +// Framebuffers (probably not a good idea but I could care less) +extern uint32_t *vbeBuffer; +extern uint32_t *framebuffer; // 2nd framebuffer. +extern uint32_t modeWidth; +extern uint32_t modeHeight; + + +// Functions +void vesaInit(); +uint32_t RGB_VBE(uint8_t r, uint8_t g, uint8_t b); +void vbePutPixel(int x, int y, uint32_t color); + + +#endif diff --git a/source/kernel/include/vfs.h b/source/kernel/include/vfs.h index 3262c9f1..b0cca79b 100644 --- a/source/kernel/include/vfs.h +++ b/source/kernel/include/vfs.h @@ -1,116 +1,116 @@ -// vfs.h - Contains declarations of the virtual filesystem and the initial ramdisk. - -#ifndef VFS_H -#define VFS_H - -/* First, a quick explanation of what a VFS actually is: - (wiki.osdev.org) A virtual filesystem is not an on-disk filesystem or a network filesystem. It's an abstraction that many OSes use to provide applications. - A VFS is used to seperate the high-level interface to the FS from the low level interfaces that different implementations (like FAT, ext3, etc), may require. */ - -// Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/tree.h" // Mountpoint tree -#include "include/hashmap.h" // Mount hashmap - - -// Definitions -#define VFS_FILE 0x01 -#define VFS_DIRECTORY 0x02 -#define VFS_CHARDEVICE 0x03 -#define VFS_BLOCKDEVICE 0x04 -#define VFS_PIPE 0x05 -#define VFS_SYMLINK 0x06 -#define VFS_MOUNTPOINT 0x08 // This one defines if the file is an active mountpoint - - - - -// Typedefs - -// Filesystem node (prototype) -struct fsNode; - - -// Offset -typedef uint64_t off_t; - -// Function prototypes (from the POSIX specification): -/* These prototypes define the type of callbacks that are called when the read/write/open/close methods are called */ -typedef uint32_t (*read_t)(struct fsNode*, off_t, uint32_t, uint8_t*); -typedef uint32_t (*write_t)(struct fsNode*, off_t, uint32_t, uint8_t*); -typedef void (*open_t)(struct fsNode*); -typedef void (*close_t)(struct fsNode*); - -// These aren't from the POSIX specification. -typedef struct dirent * (*readdir_t)(struct fsNode*, uint32_t); -typedef struct fsNode * (*finddir_t)(struct fsNode*, char *name); -typedef void (*create_t) (struct vfs_node *, char *name, uint16_t permission); -typedef void (*mkdir_t) (struct vfs_node *, char *name, uint16_t permission); - - -// Actual typedef structures. -typedef struct { - char name[128]; // FS Name (max of 128) - uint32_t mask; // Permissions mask - uint32_t uid; // Owning user - uint32_t gid; // Owning group - uint32_t flags; // Includes the node type. - uint32_t inode; // Device-specific, provides a way for a filesystem to identify files - uint32_t length; // Size of file. - uint32_t impl; // Implementation defined number. - uint32_t *impl_struct; // Implementation structure. - read_t read; // Read function - write_t write; // Write function - open_t open; // Open function - close_t close; // Close function - readdir_t readdir; // Readdir function - finddir_t finddir; // Finddir function - create_t create; // Create function - mkdir_t mkdir; // Make directory function. - struct fsNode *ptr; // Used by mountpoints and symlinks. - struct fsNode *device; // Pointer to the device needed -} fsNode_t; - -// Hashmap callback -typedef fsNode_t * (*vfs_mountCallback)(const char * arg, const char * mount_point); - - -// Directory entry. -struct dirent { - char name[256]; // Filename - uint32_t ino; // (required by POSIX) Inode number. -}; - -// Entry for the filesystem tree -typedef struct vfsEntry { - char name[20]; - fsNode_t *file; - char *device; - char *fs_type; -} vfsEntry_t; - - - -extern fsNode_t *fs_root; // Filesystem root - -// Functions: -uint32_t readFilesystem(fsNode_t *node, off_t off, uint32_t size, uint8_t *buf); // Reads a file in a filesystem. -uint32_t writeFilesystem(fsNode_t *node, off_t off, uint32_t size, uint8_t *buf); // Writes a file in a filesystem. -void openFilesystem(fsNode_t *node, uint8_t read, uint8_t write); // Opens a filesystem. -void closeFilesystem(fsNode_t *node); // Closes a filesystem. -struct dirent *readDirectoryFilesystem(fsNode_t *node, uint32_t index); // Reads a directory in a filesystem. -fsNode_t *findDirectoryFilesystem(fsNode_t *node, char *name); // Finds a directory in a filesystem. -fsNode_t *openFile(const char *name); // Opens a file. -fsNode_t *getRootFilesystem(); // Returns root filesystem. -void *vfsMount(char *path, fsNode_t *localRoot); // Mount a filesystem to the specified path -void vfsInit(); // Initialize the VFS -fsNode_t *open_file(const char *filename, unsigned int flags); // Opens a file using the VFS current working directory -void change_cwd(const char *newdir); // Changes the current working directory -char *get_cwd(); // Returns the current working directory -fsNode_t *open_file_recursive(const char *filename, uint64_t flags, uint64_t symlink_depth, char *relative); // Opens a file (but recursive and does all the work -fsNode_t *vfs_getMountpoint(char *path, unsigned int path_depth, char **outpath, unsigned int *outdepth); // Gets the mountpoint of something at path -int vfs_mountType(const char *type, const char *arg, const char *mountpoint); // Calls the mount handler for the filesystem driver for type -int vfs_registerFilesystem(const char *name, vfs_mountCallback callback); // Registers a filesystem mount callback that will be called when needed -void vfs_mapDirectory(const char *c); // Maps a directory in the virtual filesystem -char *vfs_canonicalizePath(const char *cwd, const char *input); // Canonicalizes a path -#endif \ No newline at end of file +// vfs.h - Contains declarations of the virtual filesystem and the initial ramdisk. + +#ifndef VFS_H +#define VFS_H + +/* First, a quick explanation of what a VFS actually is: + (wiki.osdev.org) A virtual filesystem is not an on-disk filesystem or a network filesystem. It's an abstraction that many OSes use to provide applications. + A VFS is used to seperate the high-level interface to the FS from the low level interfaces that different implementations (like FAT, ext3, etc), may require. */ + +// Includes +#include // Integer declarations +#include // Mountpoint tree +#include // Mount hashmap + + +// Definitions +#define VFS_FILE 0x01 +#define VFS_DIRECTORY 0x02 +#define VFS_CHARDEVICE 0x03 +#define VFS_BLOCKDEVICE 0x04 +#define VFS_PIPE 0x05 +#define VFS_SYMLINK 0x06 +#define VFS_MOUNTPOINT 0x08 // This one defines if the file is an active mountpoint + + + + +// Typedefs + +// Filesystem node (prototype) +struct fsNode; + + +// Offset +typedef uint64_t off_t; + +// Function prototypes (from the POSIX specification): +/* These prototypes define the type of callbacks that are called when the read/write/open/close methods are called */ +typedef uint32_t (*read_t)(struct fsNode*, off_t, uint32_t, uint8_t*); +typedef uint32_t (*write_t)(struct fsNode*, off_t, uint32_t, uint8_t*); +typedef void (*open_t)(struct fsNode*); +typedef void (*close_t)(struct fsNode*); + +// These aren't from the POSIX specification. +typedef struct dirent * (*readdir_t)(struct fsNode*, uint32_t); +typedef struct fsNode * (*finddir_t)(struct fsNode*, char *name); +typedef void (*create_t) (struct vfs_node *, char *name, uint16_t permission); +typedef void (*mkdir_t) (struct vfs_node *, char *name, uint16_t permission); + + +// Actual typedef structures. +typedef struct { + char name[128]; // FS Name (max of 128) + uint32_t mask; // Permissions mask + uint32_t uid; // Owning user + uint32_t gid; // Owning group + uint32_t flags; // Includes the node type. + uint32_t inode; // Device-specific, provides a way for a filesystem to identify files + uint32_t length; // Size of file. + uint32_t impl; // Implementation defined number. + uint32_t *impl_struct; // Implementation structure. + read_t read; // Read function + write_t write; // Write function + open_t open; // Open function + close_t close; // Close function + readdir_t readdir; // Readdir function + finddir_t finddir; // Finddir function + create_t create; // Create function + mkdir_t mkdir; // Make directory function. + struct fsNode *ptr; // Used by mountpoints and symlinks. + struct fsNode *device; // Pointer to the device needed +} fsNode_t; + +// Hashmap callback +typedef fsNode_t * (*vfs_mountCallback)(const char * arg, const char * mount_point); + + +// Directory entry. +struct dirent { + char name[256]; // Filename + uint32_t ino; // (required by POSIX) Inode number. +}; + +// Entry for the filesystem tree +typedef struct vfsEntry { + char name[20]; + fsNode_t *file; + char *device; + char *fs_type; +} vfsEntry_t; + + + +extern fsNode_t *fs_root; // Filesystem root + +// Functions: +uint32_t readFilesystem(fsNode_t *node, off_t off, uint32_t size, uint8_t *buf); // Reads a file in a filesystem. +uint32_t writeFilesystem(fsNode_t *node, off_t off, uint32_t size, uint8_t *buf); // Writes a file in a filesystem. +void openFilesystem(fsNode_t *node, uint8_t read, uint8_t write); // Opens a filesystem. +void closeFilesystem(fsNode_t *node); // Closes a filesystem. +struct dirent *readDirectoryFilesystem(fsNode_t *node, uint32_t index); // Reads a directory in a filesystem. +fsNode_t *findDirectoryFilesystem(fsNode_t *node, char *name); // Finds a directory in a filesystem. +fsNode_t *openFile(const char *name); // Opens a file. +fsNode_t *getRootFilesystem(); // Returns root filesystem. +void *vfsMount(char *path, fsNode_t *localRoot); // Mount a filesystem to the specified path +void vfsInit(); // Initialize the VFS +fsNode_t *open_file(const char *filename, unsigned int flags); // Opens a file using the VFS current working directory +void change_cwd(const char *newdir); // Changes the current working directory +char *get_cwd(); // Returns the current working directory +fsNode_t *open_file_recursive(const char *filename, uint64_t flags, uint64_t symlink_depth, char *relative); // Opens a file (but recursive and does all the work +fsNode_t *vfs_getMountpoint(char *path, unsigned int path_depth, char **outpath, unsigned int *outdepth); // Gets the mountpoint of something at path +int vfs_mountType(const char *type, const char *arg, const char *mountpoint); // Calls the mount handler for the filesystem driver for type +int vfs_registerFilesystem(const char *name, vfs_mountCallback callback); // Registers a filesystem mount callback that will be called when needed +void vfs_mapDirectory(const char *c); // Maps a directory in the virtual filesystem +char *vfs_canonicalizePath(const char *cwd, const char *input); // Canonicalizes a path +#endif diff --git a/source/kernel/include/vmm.h b/source/kernel/include/vmm.h index 62ce41a6..733a3d85 100644 --- a/source/kernel/include/vmm.h +++ b/source/kernel/include/vmm.h @@ -4,18 +4,18 @@ #define VMM_H // Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/libc/string.h" // String functions +#include // Integer declarations +#include // String functions -#include "include/vmm_pte.h" -#include "include/vmm_pde.h" +#include +#include -#include "include/panic.h" // Kernel panicking -#include "include/heap.h" // Kernel heap management. -#include "include/terminal.h" -#include "include/serial.h" -#include "include/pmm.h" // Physical memory management +#include // Kernel panicking +#include // Kernel heap management. +#include +#include +#include // Physical memory management @@ -58,4 +58,4 @@ void vmm_disablePaging(); // Disables paging void vmm_allocateRegion(uint32_t physical_address, uint32_t virtual_address, size_t size); // Identity map a region void vmmInit(); // Initialize the VMM -#endif \ No newline at end of file +#endif diff --git a/source/kernel/include/vmm_pde.h b/source/kernel/include/vmm_pde.h index d3685900..134fc8b3 100644 --- a/source/kernel/include/vmm_pde.h +++ b/source/kernel/include/vmm_pde.h @@ -4,11 +4,11 @@ #define VMM_PDE_H // Includes -#include "include/libc/stdint.h" // Integer declarations +#include // Integer declarations typedef uint32_t pde_t; // See vmm_pte.h -#include "include/libc/string.h" // Will cause include loop +#include // Will cause include loop // Definitions #define PAGETABLE_ADDRSPACE 0x400000 // 4 MB address space diff --git a/source/kernel/include/vmm_pte.h b/source/kernel/include/vmm_pte.h index 16252490..9da5d15f 100644 --- a/source/kernel/include/vmm_pte.h +++ b/source/kernel/include/vmm_pte.h @@ -6,14 +6,14 @@ // We get an include loop if we include string.h before defining pte_t. -#include "include/libc/stdint.h" // Integer declarations +#include // Integer declarations // Typedefs typedef uint32_t pte_t; // Includes -#include "include/libc/string.h" +#include // Definitions #define PAGEDIR_ADDRSPACE 0x100000000 // 4 GB address space @@ -41,4 +41,4 @@ void pte_setframe(pte_t *entry, uint32_t physical_addr); bool pte_ispresent(pte_t entry); bool pte_iswritable(pte_t entry); uint32_t pte_getframe(pte_t entry); -#endif \ No newline at end of file +#endif diff --git a/source/kernel/kernel/cmds.c b/source/kernel/kernel/cmds.c index f663bdbd..89fd0d66 100644 --- a/source/kernel/kernel/cmds.c +++ b/source/kernel/kernel/cmds.c @@ -3,9 +3,9 @@ // ========================================================== // This file is part of the reduceOS C kernel. Please credit me if you use this code. -#include "include/cmds.h" -#include "include/kernel.h" -#include "include/vfs.h" +#include +#include +#include extern fsNode_t *fatDriver; extern fsNode_t *ext2_root; @@ -739,4 +739,4 @@ int mountFAT(int argc, char *args[]) { } return 0; -} \ No newline at end of file +} diff --git a/source/kernel/kernel/command.c b/source/kernel/kernel/command.c index 59326f53..b07f8a46 100644 --- a/source/kernel/kernel/command.c +++ b/source/kernel/kernel/command.c @@ -1,138 +1,138 @@ -// ================================================ -// command.c - reduceOS command parser -// ================================================ -// This file is a part of the reduceOS C kernel. Please credit me if you use it. - -#include "include/command.h" // Main header file - -// Commands in reduceOS must follow this structure: -// The command function is stored in an array of a type called cmdData (this typedef is present in command.h, note that it is different from command) -// The function returns an integer, which can be any value, but mainly only 1 and -1. -// 1 means success, while -1 means a failure. -// The command can also take a parameter called args (of type char*[]) and argc (of type int) - -cmdData cmdFunctions[1024]; // As of now maximum commands is 1024. -static int index = 0; // Index of commands to add. - -// Functions -// (static) parseArguments(char *cmd, char ) - Removes spaces and parses any arguments. Returns amount of arguments and sets the actual arguments in *args. Each argument is seperated by a -static int parseArguments(char *cmd, char ***parsedArguments) { - // Count number of arguments in the command. - int commandAmount = 0; - int charactersFromLastSpace = 0; - for (int i = 0; cmd[i] != '\0'; i++) { - if (cmd[i] == ' ' && charactersFromLastSpace >= 1) { - commandAmount++; - charactersFromLastSpace = 0; - } else if (cmd[i] == ' ' && charactersFromLastSpace == 0) { - // users are attempting to crash the OS by typing only spaces! - // not on my watch! - return -1; - } else { - charactersFromLastSpace++; - } - } - - // Add one for the command itself. - commandAmount++; - - // Allocate memory for argument array - *parsedArguments = kmalloc(commandAmount * sizeof(char *)); - if (*parsedArguments == NULL) return -1; - - // Fill the array with arguments - int i = 0, start = 0; - for (int j = 0; cmd[j] != '\0'; j++) { - if (cmd[j] == ' ') { - int len = j - start; - (*parsedArguments)[i] = kmalloc((len + 1) * sizeof(char)); - if ((*parsedArguments)[i] == NULL) return -1; - strcpy((*parsedArguments)[i], &cmd[start]); - (*parsedArguments)[i][len] = '\0'; - i++; - start = j + 1; - } - } - - int len = strlen(cmd) - start; - (*parsedArguments)[i] = kmalloc((len + 1) * sizeof(char)); - if ((*parsedArguments)[i] == NULL) return -1; - - strcpy((*parsedArguments)[i], &cmd[start]); - return commandAmount; -} - - -// parseCommand(char *cmd) - Parses a command to get the function to call. -int parseCommand(char *cmd) { - if (index == 0 || strlen(cmd) == 0) return -1; - - char **argv; - int argc = parseArguments(cmd, &argv); - - if (argc == -1) return -1; - - - for (int i = 0; i < 1024; i++) { - cmdData *data = &cmdFunctions[i]; - if (strlen(data->cmdName) == strlen(argv[0])) { - if (strcmp(argv[0], data->cmdName) == 0) { - command *func = data->cmdFunc; - int ret; - ret = func(argc, argv); - // Free the memory allocated for the parsed command - for (int arg = 0; arg < argc; arg++) kfree(argv[arg]); - kfree(argv); - return ret; - } - } - } - - - printf("Unknown command - %s\n", cmd); - -} - -// Help command - prints all available commands. -int help(int argc, char *args[]) { - printf("reduceOS v%s - help command\nAvailable commands: ", VERSION); - - for (int i = 0; i < index; i++) { - cmdData *data = &cmdFunctions[i]; - printf("%s, ", data->cmdName); - } - - - printf("\n"); - return 0; -} - -// registerCommand(char *name, command cmd) - Registers a command and stores it in cmdFunctions. -void registerCommand(char *name, command cmd) { - if (index < 1024) { - - cmdData data; // Add the command's name and function to data. - data.cmdName = name; - data.cmdFunc = cmd; - - cmdFunctions[index] = data; // Store the command data in array. It will be called in parseCommand. - index += 1; - } -} - - - -// initCommandHandler() - Inititializes the command handler -void initCommandHandler() { - for (int i = 0; i < 1024; i++) { - cmdData data; - data.cmdName = "\0"; - data.cmdFunc = NULL; - - cmdFunctions[i] = data; - } - - // Register help command. - registerCommand("help", (command*)help); - printf("Command parser initialized successfully.\n"); -} \ No newline at end of file +// ================================================ +// command.c - reduceOS command parser +// ================================================ +// This file is a part of the reduceOS C kernel. Please credit me if you use it. + +#include // Main header file + +// Commands in reduceOS must follow this structure: +// The command function is stored in an array of a type called cmdData (this typedef is present in command.h, note that it is different from command) +// The function returns an integer, which can be any value, but mainly only 1 and -1. +// 1 means success, while -1 means a failure. +// The command can also take a parameter called args (of type char*[]) and argc (of type int) + +cmdData cmdFunctions[1024]; // As of now maximum commands is 1024. +static int index = 0; // Index of commands to add. + +// Functions +// (static) parseArguments(char *cmd, char ) - Removes spaces and parses any arguments. Returns amount of arguments and sets the actual arguments in *args. Each argument is seperated by a +static int parseArguments(char *cmd, char ***parsedArguments) { + // Count number of arguments in the command. + int commandAmount = 0; + int charactersFromLastSpace = 0; + for (int i = 0; cmd[i] != '\0'; i++) { + if (cmd[i] == ' ' && charactersFromLastSpace >= 1) { + commandAmount++; + charactersFromLastSpace = 0; + } else if (cmd[i] == ' ' && charactersFromLastSpace == 0) { + // users are attempting to crash the OS by typing only spaces! + // not on my watch! + return -1; + } else { + charactersFromLastSpace++; + } + } + + // Add one for the command itself. + commandAmount++; + + // Allocate memory for argument array + *parsedArguments = kmalloc(commandAmount * sizeof(char *)); + if (*parsedArguments == NULL) return -1; + + // Fill the array with arguments + int i = 0, start = 0; + for (int j = 0; cmd[j] != '\0'; j++) { + if (cmd[j] == ' ') { + int len = j - start; + (*parsedArguments)[i] = kmalloc((len + 1) * sizeof(char)); + if ((*parsedArguments)[i] == NULL) return -1; + strcpy((*parsedArguments)[i], &cmd[start]); + (*parsedArguments)[i][len] = '\0'; + i++; + start = j + 1; + } + } + + int len = strlen(cmd) - start; + (*parsedArguments)[i] = kmalloc((len + 1) * sizeof(char)); + if ((*parsedArguments)[i] == NULL) return -1; + + strcpy((*parsedArguments)[i], &cmd[start]); + return commandAmount; +} + + +// parseCommand(char *cmd) - Parses a command to get the function to call. +int parseCommand(char *cmd) { + if (index == 0 || strlen(cmd) == 0) return -1; + + char **argv; + int argc = parseArguments(cmd, &argv); + + if (argc == -1) return -1; + + + for (int i = 0; i < 1024; i++) { + cmdData *data = &cmdFunctions[i]; + if (strlen(data->cmdName) == strlen(argv[0])) { + if (strcmp(argv[0], data->cmdName) == 0) { + command *func = data->cmdFunc; + int ret; + ret = func(argc, argv); + // Free the memory allocated for the parsed command + for (int arg = 0; arg < argc; arg++) kfree(argv[arg]); + kfree(argv); + return ret; + } + } + } + + + printf("Unknown command - %s\n", cmd); + +} + +// Help command - prints all available commands. +int help(int argc, char *args[]) { + printf("reduceOS v%s - help command\nAvailable commands: ", VERSION); + + for (int i = 0; i < index; i++) { + cmdData *data = &cmdFunctions[i]; + printf("%s, ", data->cmdName); + } + + + printf("\n"); + return 0; +} + +// registerCommand(char *name, command cmd) - Registers a command and stores it in cmdFunctions. +void registerCommand(char *name, command cmd) { + if (index < 1024) { + + cmdData data; // Add the command's name and function to data. + data.cmdName = name; + data.cmdFunc = cmd; + + cmdFunctions[index] = data; // Store the command data in array. It will be called in parseCommand. + index += 1; + } +} + + + +// initCommandHandler() - Inititializes the command handler +void initCommandHandler() { + for (int i = 0; i < 1024; i++) { + cmdData data; + data.cmdName = "\0"; + data.cmdFunc = NULL; + + cmdFunctions[i] = data; + } + + // Register help command. + registerCommand("help", (command*)help); + printf("Command parser initialized successfully.\n"); +} diff --git a/source/kernel/kernel/kernel.c b/source/kernel/kernel/kernel.c index 10fb6fa8..684da3a2 100644 --- a/source/kernel/kernel/kernel.c +++ b/source/kernel/kernel/kernel.c @@ -1,361 +1,361 @@ -// ===================================================================== -// kernel.c - Main reduceOS kernel -// This file handles most of the logic and puts everything together -// ===================================================================== -// This file is apart of the reduceOS C kernel. Please credit me if you use this code. - -#include "include/kernel.h" // Kernel header file -#include "include/cmds.h" - - - -// ide_ata.c defined variables -extern ideDevice_t ideDevices[4]; - -// initrd.c defined variables -extern fsNode_t *initrdDev; - -multiboot_info *globalInfo; - -extern void switchToUserMode(); // User mode switch function - - - -void usermodeMain() { - printf("Hello, usermode world! printf() is working!\n"); - - syscall_terminalWriteString("System calls are online!\n"); - - syscall_terminalUpdateScreen(); - - for (;;); -} - - - - -int enterUsermode(int argc, char *args[]) { - printf("Entering usermode, please wait...\n"); - setKernelStack(2048); - switchToUserMode(); - return -1; -} - - - -fsNode_t *fatDriver = NULL; -fsNode_t *ext2_root = NULL; - - - -// kmain() - The most important function in all of reduceOS. Jumped here by loadKernel.asm. -void kmain(unsigned long addr, unsigned long loader_magic) { - // Update global multiboot info. - - multiboot_info *mboot; - - globalInfo = (multiboot_info*)addr; - - // Some extra stuff - extern uint32_t text_start; - extern uint32_t text_end; - extern uint32_t data_start; - extern uint32_t data_end; - extern uint32_t bss_start; - extern uint32_t bss_end; - - - extern uint32_t modeWidth; - extern uint32_t modeHeight; - extern uint32_t modeBpp; - extern uint32_t *vbeBuffer; - - // Perform some basic setup - initTerminal(); // Initialize the terminal and clear the screen - updateTerminalColor(vgaColorEntry(COLOR_BLACK, COLOR_LIGHT_GRAY)); // Update terminal color - - - // First, setup the top bar. - printf("reduceOS v%s %s (created by @sasdallas)", VERSION, CODENAME); - for (int i = 0; i < (SCREEN_WIDTH - strlen("reduceOS v (created by @sasdallas) ") - strlen(CODENAME) - strlen(VERSION)); i++) printf(" "); // tbf - // Next, update terminal color to the proper color. - updateTerminalColor(vgaColorEntry(COLOR_WHITE, COLOR_CYAN)); - printf("reduceOS is loading, please wait...\n"); - - // Change the bottom text of the terminal (updateBottomText) - updateBottomText("Loading reduceOS..."); - - // Initialize serial logging - serialInit(); - serialPrintf("============================================================================================================================\n"); - serialPrintf("\treduceOS v%s %s - written by sasdallas\n", VERSION, CODENAME); - serialPrintf("\tNew kernel, same trash.\n"); - serialPrintf("\tBuild %s-%s, compiled on %s\n", BUILD_NUMBER, BUILD_CONFIGURATION, BUILD_DATE); - serialPrintf("============================================================================================================================\n\n"); - serialPrintf("Kernel location: 0x%x - 0x%x\nText section: 0x%x - 0x%x; Data section: 0x%x - 0x%x; BSS section: 0x%x - 0x%x\n", &text_start, &bss_end, &text_start, &text_end, &data_start, &data_end, &bss_start, &bss_end); - serialPrintf("Loader magic: 0x%x\n\n", loader_magic); - serialPrintf("Serial logging initialized!\n"); - - printf("Serial logging initialized on COM1.\n"); - - - if (loader_magic != 0x43D8C305) { - serialPrintf("loader magic: 0x%x addr: 0x%x\n", loader_magic, addr); - panic("kernel", "kmain", "loader_magic != 0x43D8C305"); - } - - - serialPrintf("kmain: CPU has long mode support: %i\n", isCPULongModeCapable()); - - - - // ==== MEMORY MANAGEMENT INITIALIZATION ==== - // Now that initial ramdisk has loaded, we can initialize memory management - updateBottomText("Initializing physical memory manager..."); - pmmInit((globalInfo->m_memoryHi - globalInfo->m_memoryLo)); - - // Initialize the memory map - pmm_initializeMemoryMap(globalInfo); - - - // Deallocate the kernel's region. - uint32_t kernelStart = (uint32_t)&text_start; - uint32_t kernelEnd = (uint32_t)&bss_end; - pmm_deinitRegion(0x100000, (kernelEnd - kernelStart)); - - // Before anything else is allocated, we need to deinitialize a few other regions. - // Here is the list: - /* - - ACPI (0x000E0000 - 0x000FFFFF) - */ - - pmm_deinitRegion(0x000E0000, 0x000FFFFF-0x000E0000); - - updateBottomText("Initializing HAL..."); - cpuInit(); - printf("HAL initialization completed.\n"); - - // Initialize ACPI (has to be done before VMM initializes) - updateBottomText("Initializing ACPI..."); - acpiInit(); - - // Initialize VMM - vmmInit(); - serialPrintf("Initialized memory management successfully.\n"); - - - // TODO: ACPI might need to reinitialize its regions so do we need to reallocate? I call vmm_allocateRegion in ACPI, but does that work before vmmInit? - - - ASSERT(globalInfo->m_modsCount > 0, "kmain", "Initial ramdisk not found (modsCount is 0)"); - uint32_t initrdLocation = *((uint32_t*)(globalInfo->m_modsAddr)); - uint32_t initrdEnd = *(uint32_t*)(globalInfo->m_modsAddr + 4); - serialPrintf("GRUB did pass an initial ramdisk at 0x%x.\n", globalInfo->m_modsAddr); - - multiboot_mod_t *mod; - int i; - for (i = 0, mod = (multiboot_mod_t*)globalInfo->m_modsAddr; i < globalInfo->m_modsCount; i++, mod++) { - serialPrintf("\tmod_start = 0x%x, mod_end = 0x%x, cmdline = %s\n", mod->mod_start, mod->mod_end, (char*)mod->cmdline); - } - - - // ONLY WORKS WHEN LOADING WITH GRUB. DOES NOT WORK ON QEMU. - //fsNode_t *initrd = initrdInit(initrdLocation); - printf("Initrd image initialized!\n"); - serialPrintf("initrdInit: Initial ramdisk loaded - location is 0x%x and end address is 0x%x\n", initrdLocation, initrdEnd); - - - - bios32_init(); - serialPrintf("bios32 initialized successfully!\n"); - - - - // Initialize Keyboard - updateBottomText("Initializing keyboard..."); - keyboardInitialize(); - setKBHandler(true); - serialPrintf("Keyboard handler initialized.\n"); - - - // PIT timer - updateBottomText("Initializing PIT..."); - pitInit(); - serialPrintf("PIT started at 1000hz\n"); - - - // Probe for PCI devices - updateBottomText("Probing PCI..."); - initPCI(); - serialPrintf("initPCI: PCI probe completed\n"); - - - - - - - - // Initialize the floppy drive - floppy_init(); - serialPrintf("Initialized floppy drive successfully.\n"); - - - - // DEFINITELY sketchy! What's going on with this system? - serialPrintf("WARNING: Enabling liballoc! Stand away from the flames!\n"); - enable_liballoc(); - - // Calculate the initial ramdisk location in memory (panic if it's not there) - - - - // Initialize the IDE controller. - updateBottomText("Initializing IDE controller..."); - ideInit(0x1F0, 0x3F6, 0x170, 0x376, 0x000); // Initialize parallel IDE - - - /* VESA initialization */ - bool didInitVesa = true; - char c = isKeyPressed(); - if (c == 'c') { - didInitVesa = false; - } else { - vesaInit(); // Initialize VBE - } - - - - - - - if (didInitVesa) { - // Initialize PSF - psfInit(); - - vbeSwitchBuffers(); - - changeTerminalMode(1); // Update terminal mode - } - - - - - // Initialize the VFS - vfsInit(); - - // First, we need to install the EXT2 and FAT drivers. - ext2_install(0, NULL); - fat_install(0, NULL); - ide_install(0, NULL); - - // Then, we need to map the /dev/ directory - vfs_mapDirectory("/dev"); - - // Now, we can iterate through each IDE node, mount them to the dev directory, and try to use them as root if needed - bool rootMounted = false; - for (int i = 0; i < 4; i++) { - fsNode_t *ideNode = ideGetVFSNode(i); - - // First, we'll mount this device to /dev/idex - char *name = kmalloc(sizeof(char) * (strlen("/dev/ide") + 1)); - strcpy(name, "/dev/ide"); - itoa(i, name + strlen("/dev/ide"), 10); - - - vfsMount(name, ideGetVFSNode(i)); - - if ((ideDevices[i].reserved == 1) && (ideDevices[i].size > 1)) { - // The EXT2 driver needs to be mounted first on / - if (!rootMounted) { - int ret = vfs_mountType("ext2", name, "/"); - if (ret == 0) rootMounted = true; - else { - // Other filesystem should initialize differently - } - } - } - } - - debug_print_vfs_tree(); - - // For compatibility with our tests, we need to set the ext2_root variable. - // The user can use the mount_fat command to mount the FAT driver. - if (rootMounted) ext2_root = open_file("/", 0); - - - - uint8_t seconds, minutes, hours, days, months; - int years; - - rtc_getDateTime(&seconds, &minutes, &hours, &days, &months, &years); - serialPrintf("rtc_getDateTime: Got date and time from RTC (formatted as M/D/Y H:M:S): %i/%i/%i %i:%i:%i\n", months, days, years, hours, minutes, seconds); - - - - // Initialize system calls - initSyscalls(); - - // Start paging if VBE was not initialized. - useCommands(); -} - - - -void useCommands() { - serialPrintf("kmain: Memory management online with %i KB of physical memory\n", pmm_getPhysicalMemorySize()); - - - clearScreen(COLOR_WHITE, COLOR_CYAN); - - clearBuffer(); - - - initCommandHandler(); - registerCommand("isr", (command*)testISRException); - registerCommand("system", (command*)getSystemInformation); - registerCommand("echo", (command*)echo); - registerCommand("crash", (command*)crash); - registerCommand("pci", (command*)pciInfo); - registerCommand("initrd", (command*)getInitrdFiles); - registerCommand("ata", (command*)ataPoll); - registerCommand("panic", (command*)panicTest); - registerCommand("sector", (command*)readSectorTest); - registerCommand("shutdown", (command*)shutdown); - registerCommand("memory", (command*)memoryInfo); - registerCommand("dump", (command*)dump); - registerCommand("about", (command*)about); - registerCommand("version", (command*)about); - registerCommand("color", (command*)color); - registerCommand("pagefault", (command*)doPageFault); - registerCommand("read_floppy", (command*)read_floppy); - registerCommand("test", (command*)test); - registerCommand("user", (command*)enterUsermode); - - - registerCommand("mount_fat", (command*)mountFAT); - - registerCommand("ls", (command*)ls); - registerCommand("cd", (command*)cd); - registerCommand("cat", (command*)cat); - registerCommand("create", (command*)create); - registerCommand("mkdir", (command*)mkdir); - registerCommand("pwd", (command*)pwd); - registerCommand("bitmap", (command*)show_bitmap); - registerCommand("edit", (command*)edit); - - serialPrintf("kmain: All commands registered successfully.\n"); - serialPrintf("kmain: Warning: User is an unstable environment.\n"); - - char buffer[256]; // We will store keyboard input here. - printf("reduceOS has finished loading successfully.\n"); - printf("Please type your commands below.\n"); - printf("Type 'help' for help.\n"); - if (!fs_root) printf("WARNING: No root filesystem is mounted.\n"); - enableShell("reduceOS /> "); // Enable a boundary (our prompt) - - while (true) { - printf(getShell()); - keyboardGetLine(buffer); - parseCommand(buffer); - } -} \ No newline at end of file +// ===================================================================== +// kernel.c - Main reduceOS kernel +// This file handles most of the logic and puts everything together +// ===================================================================== +// This file is apart of the reduceOS C kernel. Please credit me if you use this code. + +#include // Kernel header file +#include + + + +// ide_ata.c defined variables +extern ideDevice_t ideDevices[4]; + +// initrd.c defined variables +extern fsNode_t *initrdDev; + +multiboot_info *globalInfo; + +extern void switchToUserMode(); // User mode switch function + + + +void usermodeMain() { + printf("Hello, usermode world! printf() is working!\n"); + + syscall_terminalWriteString("System calls are online!\n"); + + syscall_terminalUpdateScreen(); + + for (;;); +} + + + + +int enterUsermode(int argc, char *args[]) { + printf("Entering usermode, please wait...\n"); + setKernelStack(2048); + switchToUserMode(); + return -1; +} + + + +fsNode_t *fatDriver = NULL; +fsNode_t *ext2_root = NULL; + + + +// kmain() - The most important function in all of reduceOS. Jumped here by loadKernel.asm. +void kmain(unsigned long addr, unsigned long loader_magic) { + // Update global multiboot info. + + multiboot_info *mboot; + + globalInfo = (multiboot_info*)addr; + + // Some extra stuff + extern uint32_t text_start; + extern uint32_t text_end; + extern uint32_t data_start; + extern uint32_t data_end; + extern uint32_t bss_start; + extern uint32_t bss_end; + + + extern uint32_t modeWidth; + extern uint32_t modeHeight; + extern uint32_t modeBpp; + extern uint32_t *vbeBuffer; + + // Perform some basic setup + initTerminal(); // Initialize the terminal and clear the screen + updateTerminalColor(vgaColorEntry(COLOR_BLACK, COLOR_LIGHT_GRAY)); // Update terminal color + + + // First, setup the top bar. + printf("reduceOS v%s %s (created by @sasdallas)", VERSION, CODENAME); + for (int i = 0; i < (SCREEN_WIDTH - strlen("reduceOS v (created by @sasdallas) ") - strlen(CODENAME) - strlen(VERSION)); i++) printf(" "); // tbf + // Next, update terminal color to the proper color. + updateTerminalColor(vgaColorEntry(COLOR_WHITE, COLOR_CYAN)); + printf("reduceOS is loading, please wait...\n"); + + // Change the bottom text of the terminal (updateBottomText) + updateBottomText("Loading reduceOS..."); + + // Initialize serial logging + serialInit(); + serialPrintf("============================================================================================================================\n"); + serialPrintf("\treduceOS v%s %s - written by sasdallas\n", VERSION, CODENAME); + serialPrintf("\tNew kernel, same trash.\n"); + serialPrintf("\tBuild %s-%s, compiled on %s\n", BUILD_NUMBER, BUILD_CONFIGURATION, BUILD_DATE); + serialPrintf("============================================================================================================================\n\n"); + serialPrintf("Kernel location: 0x%x - 0x%x\nText section: 0x%x - 0x%x; Data section: 0x%x - 0x%x; BSS section: 0x%x - 0x%x\n", &text_start, &bss_end, &text_start, &text_end, &data_start, &data_end, &bss_start, &bss_end); + serialPrintf("Loader magic: 0x%x\n\n", loader_magic); + serialPrintf("Serial logging initialized!\n"); + + printf("Serial logging initialized on COM1.\n"); + + + if (loader_magic != 0x43D8C305) { + serialPrintf("loader magic: 0x%x addr: 0x%x\n", loader_magic, addr); + panic("kernel", "kmain", "loader_magic != 0x43D8C305"); + } + + + serialPrintf("kmain: CPU has long mode support: %i\n", isCPULongModeCapable()); + + + + // ==== MEMORY MANAGEMENT INITIALIZATION ==== + // Now that initial ramdisk has loaded, we can initialize memory management + updateBottomText("Initializing physical memory manager..."); + pmmInit((globalInfo->m_memoryHi - globalInfo->m_memoryLo)); + + // Initialize the memory map + pmm_initializeMemoryMap(globalInfo); + + + // Deallocate the kernel's region. + uint32_t kernelStart = (uint32_t)&text_start; + uint32_t kernelEnd = (uint32_t)&bss_end; + pmm_deinitRegion(0x100000, (kernelEnd - kernelStart)); + + // Before anything else is allocated, we need to deinitialize a few other regions. + // Here is the list: + /* + - ACPI (0x000E0000 - 0x000FFFFF) + */ + + pmm_deinitRegion(0x000E0000, 0x000FFFFF-0x000E0000); + + updateBottomText("Initializing HAL..."); + cpuInit(); + printf("HAL initialization completed.\n"); + + // Initialize ACPI (has to be done before VMM initializes) + updateBottomText("Initializing ACPI..."); + acpiInit(); + + // Initialize VMM + vmmInit(); + serialPrintf("Initialized memory management successfully.\n"); + + + // TODO: ACPI might need to reinitialize its regions so do we need to reallocate? I call vmm_allocateRegion in ACPI, but does that work before vmmInit? + + + ASSERT(globalInfo->m_modsCount > 0, "kmain", "Initial ramdisk not found (modsCount is 0)"); + uint32_t initrdLocation = *((uint32_t*)(globalInfo->m_modsAddr)); + uint32_t initrdEnd = *(uint32_t*)(globalInfo->m_modsAddr + 4); + serialPrintf("GRUB did pass an initial ramdisk at 0x%x.\n", globalInfo->m_modsAddr); + + multiboot_mod_t *mod; + int i; + for (i = 0, mod = (multiboot_mod_t*)globalInfo->m_modsAddr; i < globalInfo->m_modsCount; i++, mod++) { + serialPrintf("\tmod_start = 0x%x, mod_end = 0x%x, cmdline = %s\n", mod->mod_start, mod->mod_end, (char*)mod->cmdline); + } + + + // ONLY WORKS WHEN LOADING WITH GRUB. DOES NOT WORK ON QEMU. + //fsNode_t *initrd = initrdInit(initrdLocation); + printf("Initrd image initialized!\n"); + serialPrintf("initrdInit: Initial ramdisk loaded - location is 0x%x and end address is 0x%x\n", initrdLocation, initrdEnd); + + + + bios32_init(); + serialPrintf("bios32 initialized successfully!\n"); + + + + // Initialize Keyboard + updateBottomText("Initializing keyboard..."); + keyboardInitialize(); + setKBHandler(true); + serialPrintf("Keyboard handler initialized.\n"); + + + // PIT timer + updateBottomText("Initializing PIT..."); + pitInit(); + serialPrintf("PIT started at 1000hz\n"); + + + // Probe for PCI devices + updateBottomText("Probing PCI..."); + initPCI(); + serialPrintf("initPCI: PCI probe completed\n"); + + + + + + + + // Initialize the floppy drive + floppy_init(); + serialPrintf("Initialized floppy drive successfully.\n"); + + + + // DEFINITELY sketchy! What's going on with this system? + serialPrintf("WARNING: Enabling liballoc! Stand away from the flames!\n"); + enable_liballoc(); + + // Calculate the initial ramdisk location in memory (panic if it's not there) + + + + // Initialize the IDE controller. + updateBottomText("Initializing IDE controller..."); + ideInit(0x1F0, 0x3F6, 0x170, 0x376, 0x000); // Initialize parallel IDE + + + /* VESA initialization */ + bool didInitVesa = true; + char c = isKeyPressed(); + if (c == 'c') { + didInitVesa = false; + } else { + vesaInit(); // Initialize VBE + } + + + + + + + if (didInitVesa) { + // Initialize PSF + psfInit(); + + vbeSwitchBuffers(); + + changeTerminalMode(1); // Update terminal mode + } + + + + + // Initialize the VFS + vfsInit(); + + // First, we need to install the EXT2 and FAT drivers. + ext2_install(0, NULL); + fat_install(0, NULL); + ide_install(0, NULL); + + // Then, we need to map the /dev/ directory + vfs_mapDirectory("/dev"); + + // Now, we can iterate through each IDE node, mount them to the dev directory, and try to use them as root if needed + bool rootMounted = false; + for (int i = 0; i < 4; i++) { + fsNode_t *ideNode = ideGetVFSNode(i); + + // First, we'll mount this device to /dev/idex + char *name = kmalloc(sizeof(char) * (strlen("/dev/ide") + 1)); + strcpy(name, "/dev/ide"); + itoa(i, name + strlen("/dev/ide"), 10); + + + vfsMount(name, ideGetVFSNode(i)); + + if ((ideDevices[i].reserved == 1) && (ideDevices[i].size > 1)) { + // The EXT2 driver needs to be mounted first on / + if (!rootMounted) { + int ret = vfs_mountType("ext2", name, "/"); + if (ret == 0) rootMounted = true; + else { + // Other filesystem should initialize differently + } + } + } + } + + debug_print_vfs_tree(); + + // For compatibility with our tests, we need to set the ext2_root variable. + // The user can use the mount_fat command to mount the FAT driver. + if (rootMounted) ext2_root = open_file("/", 0); + + + + uint8_t seconds, minutes, hours, days, months; + int years; + + rtc_getDateTime(&seconds, &minutes, &hours, &days, &months, &years); + serialPrintf("rtc_getDateTime: Got date and time from RTC (formatted as M/D/Y H:M:S): %i/%i/%i %i:%i:%i\n", months, days, years, hours, minutes, seconds); + + + + // Initialize system calls + initSyscalls(); + + // Start paging if VBE was not initialized. + useCommands(); +} + + + +void useCommands() { + serialPrintf("kmain: Memory management online with %i KB of physical memory\n", pmm_getPhysicalMemorySize()); + + + clearScreen(COLOR_WHITE, COLOR_CYAN); + + clearBuffer(); + + + initCommandHandler(); + registerCommand("isr", (command*)testISRException); + registerCommand("system", (command*)getSystemInformation); + registerCommand("echo", (command*)echo); + registerCommand("crash", (command*)crash); + registerCommand("pci", (command*)pciInfo); + registerCommand("initrd", (command*)getInitrdFiles); + registerCommand("ata", (command*)ataPoll); + registerCommand("panic", (command*)panicTest); + registerCommand("sector", (command*)readSectorTest); + registerCommand("shutdown", (command*)shutdown); + registerCommand("memory", (command*)memoryInfo); + registerCommand("dump", (command*)dump); + registerCommand("about", (command*)about); + registerCommand("version", (command*)about); + registerCommand("color", (command*)color); + registerCommand("pagefault", (command*)doPageFault); + registerCommand("read_floppy", (command*)read_floppy); + registerCommand("test", (command*)test); + registerCommand("user", (command*)enterUsermode); + + + registerCommand("mount_fat", (command*)mountFAT); + + registerCommand("ls", (command*)ls); + registerCommand("cd", (command*)cd); + registerCommand("cat", (command*)cat); + registerCommand("create", (command*)create); + registerCommand("mkdir", (command*)mkdir); + registerCommand("pwd", (command*)pwd); + registerCommand("bitmap", (command*)show_bitmap); + registerCommand("edit", (command*)edit); + + serialPrintf("kmain: All commands registered successfully.\n"); + serialPrintf("kmain: Warning: User is an unstable environment.\n"); + + char buffer[256]; // We will store keyboard input here. + printf("reduceOS has finished loading successfully.\n"); + printf("Please type your commands below.\n"); + printf("Type 'help' for help.\n"); + if (!fs_root) printf("WARNING: No root filesystem is mounted.\n"); + enableShell("reduceOS /> "); // Enable a boundary (our prompt) + + while (true) { + printf(getShell()); + keyboardGetLine(buffer); + parseCommand(buffer); + } +} diff --git a/source/kernel/kernel/panic.c b/source/kernel/kernel/panic.c index 06deb7b3..fff6e268 100644 --- a/source/kernel/kernel/panic.c +++ b/source/kernel/kernel/panic.c @@ -1,221 +1,221 @@ -// ===================================================================== -// panic.c - Kernel panic -// This file handles the kernel panicking and exiting -// ===================================================================== -// This file is apart of the reduceOS C kernel. Please credit me if you use this code. - - -#include "include/panic.h" // Main panic include file - -typedef struct { - struct stack_frame* ebp; - uint32_t eip; -} stack_frame; - -// This static function performes a stack trace to get the callers of panic. -static void stackTrace(uint32_t maximumFrames) { - stack_frame *stk; - asm volatile ("movl %%ebp, %0" : "=r"(stk)); - printf("\nStack trace:\n"); - serialPrintf("\nSTACK TRACE (EBP based):\n"); - for (uint32_t frame = 0; stk && frame < maximumFrames; frame++) { - printf("Frame %i: 0x%x\n", frame, stk->eip); - serialPrintf("FRAME %i: 0x%x\n", frame, stk->eip); - stk = stk->ebp; - } -} - -// Panic - halts system and prints an error message -void *panic(char *caller, char *code, char *reason) { - serialPrintf("===========================================================\n"); - serialPrintf("panic() called! FATAL ERROR!\n"); - serialPrintf("*** [%s] %s: %s\n", caller, code, reason); - serialPrintf("panic type: kernel panic\n"); - - - setKBHandler(false); - clearScreen(COLOR_WHITE, COLOR_RED); - updateTerminalColor_gfx(COLOR_BLACK, COLOR_LIGHT_GRAY); // Update terminal color - - // Make things look nicer - terminalSetUpdateScreen(false); - - printf("reduceOS v%s %s - Kernel Panic", VERSION, CODENAME); - if (terminalMode == 0) { - for (int i = 0; i < (SCREEN_WIDTH - strlen("reduceOS v - Kernel Panic") - strlen(CODENAME) - strlen(VERSION)); i++) printf(" "); // vga only because idc enough to do PSF_WIDTH - } else { - for (int i = 0; i < ((modeWidth - ((strlen("reduceOS v - Kernel Panic") + strlen(CODENAME) + strlen(VERSION)) * psfGetFontWidth()))); i += psfGetFontWidth()) printf(" "); - } - - terminalSetUpdateScreen(true); - terminalUpdateScreen(); - - // updateBottomText("A fatal error occurred!"); - - updateTerminalColor_gfx(COLOR_WHITE, COLOR_RED); - - printf("reduceOS encountered a fatal error and needs to shutdown.\n"); - printf("The error cause will be printed below. If you start an issue on GitHub, please include the following text.\n"); - printf("Apologies for any inconveniences caused by this error.\n"); - printf("\n"); - printf("The error encountered was:\n"); - printf("*** [%s] %s: %s \n", caller, code, reason); - - - registers_t *reg; - - // Funny - asm volatile ("mov %%eax, %0" : "=r"(reg->eax)); - asm volatile ("mov %%ebx, %0" : "=r"(reg->ebx)); - asm volatile ("mov %%ecx, %0" : "=r"(reg->ecx)); - asm volatile ("mov %%edx, %0" : "=r"(reg->edx)); - asm volatile ("mov %%esi, %0" : "=r"(reg->esi)); - asm volatile ("mov %%esp, %0" : "=r"(reg->esp)); - asm volatile ("mov %%ebp, %0" : "=r"(reg->ebp)); - asm volatile ("mov %%edi, %0" : "=r"(reg->edi)); - asm volatile ("mov %%ds, %0" : "=r"(reg->ds)); - asm volatile ("mov %%cs, %0" : "=r"(reg->cs)); - asm volatile ("mov %%ss, %0" : "=r"(reg->ss)); - - printf("\nStack dump:\n\n"); - printf("No error code was set (kernel panic).\n"); - printf("eax=0x%x, ebx=0x%x, ecx=0x%x, edx=0x%x\n", reg->eax, reg->ebx, reg->ecx, reg->edx); - printf("edi=0x%x, esi=0x%x, ebp=0x%x, esp=0x%x\n", reg->edi, reg->esi, reg->ebp, reg->esp); - printf("cs=0x%x, ss=0x%x\n", reg->cs, reg->ss); - - serialPrintf("STACK DUMP:\n"); - serialPrintf("eax=0x%x, ebx=0x%x, ecx=0x%x, edx=0x%x\n", reg->eax, reg->ebx, reg->ecx, reg->edx); - serialPrintf("edi=0x%x, esi=0x%x, ebp=0x%x, esp=0x%x\n", reg->edi, reg->esi, reg->ebp, reg->esp); - serialPrintf("cs=0x%x, ss=0x%x\n", reg->cs, reg->ss); - - - // TODO: Add debug symbols into the initrd so we get function names. - stackTrace(5); // Get a stack trace. - - asm volatile ("hlt"); - for (;;); -} - - -void *panicReg(char *caller, char *code, char *reason, registers_t *reg) { - serialPrintf("===========================================================\n"); - serialPrintf("panic() called! FATAL ERROR!\n"); - serialPrintf("*** ISR threw exception: %s\n", reason); - serialPrintf("panic type: %s.\n", code); - - - setKBHandler(false); - clearScreen(COLOR_WHITE, COLOR_RED); - updateTerminalColor_gfx(COLOR_BLACK, COLOR_LIGHT_GRAY); // Update terminal color - - // Make things look nicer - terminalSetUpdateScreen(false); - - printf("reduceOS v%s %s - Kernel Panic", VERSION, CODENAME); - if (terminalMode == 0) { - for (int i = 0; i < (SCREEN_WIDTH - strlen("reduceOS v - Kernel Panic") - strlen(CODENAME) - strlen(VERSION)); i++) printf(" "); // vga only because idc enough to do PSF_WIDTH - } else { - for (int i = 0; i < ((modeWidth - ((strlen("reduceOS v - Kernel Panic") + strlen(CODENAME) + strlen(VERSION)) * psfGetFontWidth()))); i += psfGetFontWidth()) printf(" "); - } - - terminalSetUpdateScreen(true); - terminalUpdateScreen(); - - // updateBottomText("A fatal error occurred!"); - - updateTerminalColor_gfx(COLOR_WHITE, COLOR_RED); - - printf("reduceOS encountered a fatal error and needs to shutdown.\n"); - printf("The error cause will be printed below. If you start an issue on GitHub, please include the following text.\n"); - printf("Apologies for any inconveniences caused by this error.\n"); - printf("\n"); - printf("The error encountered was:\n"); - printf("*** [%s] %s: %s \n", caller, code, reason); - printf("\nStack dump:\n\n"); - - printf("Error Code: %d\n", reg->err_code); - printf("eax=0x%x, ebx=0x%x, ecx=0x%x, edx=0x%x\n", reg->eax, reg->ebx, reg->ecx, reg->edx); - printf("edi=0x%x, esi=0x%x, ebp=0x%x, esp=0x%x\n", reg->edi, reg->esi, reg->ebp, reg->esp); - printf("eip=0x%x, cs=0x%x, ss=0x%x, eflags=0x%x, useresp=0x%x\n", reg->eip, reg->ss, reg->eflags, reg->useresp); - - serialPrintf("\nerr_code %d\n", reg->err_code); - serialPrintf("REGISTER DUMP:\n"); - serialPrintf("eax=0x%x, ebx=0x%x, ecx=0x%x, edx=0x%x\n", reg->eax, reg->ebx, reg->ecx, reg->edx); - serialPrintf("edi=0x%x, esi=0x%x, ebp=0x%x, esp=0x%x\n", reg->edi, reg->esi, reg->ebp, reg->esp); - serialPrintf("eip=0x%x, cs=0x%x, ss=0x%x, eflags=0x%x, useresp=0x%x\n", reg->eip, reg->ss, reg->eflags, reg->useresp); - - // Perform stack trace - stackTrace(5); - - asm volatile ("hlt"); - for (;;); -} - - - -// Oh no! We encountered a page fault! -void *pageFault(registers_t *reg) { - // Get the faulting address from CR2 - uint32_t faultAddress; - asm volatile("mov %%cr2, %0" : "=r" (faultAddress)); - - serialPrintf("===========================================================\n"); - serialPrintf("panic() called! FATAL ERROR!\n"); - serialPrintf("*** Page fault at address 0x%x\n", faultAddress); - - setKBHandler(false); - - // Get the flags - int present = !(reg->err_code & 0x1); // Page not present? - int rw = reg->err_code & 0x2; // Was this a write operation? - int user = reg->err_code & 0x4; // Were we in user-mode? - int reserved = reg->err_code & 0x8; // Were the reserved bits of page entry overwritten? - - clearScreen(COLOR_WHITE, COLOR_RED); - updateTerminalColor_gfx(COLOR_BLACK, COLOR_LIGHT_GRAY); // Update terminal color - - // Make things look nicer - terminalSetUpdateScreen(false); - - printf("reduceOS v%s %s - Kernel Panic", VERSION, CODENAME); - if (terminalMode == 0) { - for (int i = 0; i < (SCREEN_WIDTH - strlen("reduceOS v - Kernel Panic") - strlen(CODENAME) - strlen(VERSION)); i++) printf(" "); // vga only because idc enough to do PSF_WIDTH - } else { - for (int i = 0; i < ((modeWidth - ((strlen("reduceOS v - Kernel Panic") + strlen(CODENAME) + strlen(VERSION)) * psfGetFontWidth()))); i += psfGetFontWidth()) printf(" "); - } - - terminalSetUpdateScreen(true); - terminalUpdateScreen(); - - updateTerminalColor_gfx(COLOR_WHITE, COLOR_RED); - - printf("reduceOS encountered a fatal error and needs to shutdown.\n"); - printf("The error cause will be printed below. If you start an issue on GitHub, please include the following text.\n"); - printf("Apologies for any inconveniences caused by this error.\n"); - printf("\n"); - printf("The error encountered was:\n"); - printf("*** Page fault at address 0x%x\n", faultAddress); - printf("*** Flags: %s%s%s%s\n", (present) ? "present " : "\0", (rw) ? "read-only " : "\0", (user) ? "user-mode " : "\0 ", (reserved) ? "reserved " : "\0"); - printf("\nStack dump:\n\n"); - - printf("Error Code: %d\n", reg->err_code); - printf("eax=0x%x, ebx=0x%x, ecx=0x%x, edx=0x%x\n", reg->eax, reg->ebx, reg->ecx, reg->edx); - printf("edi=0x%x, esi=0x%x, ebp=0x%x, esp=0x%x\n", reg->edi, reg->esi, reg->ebp, reg->esp); - printf("eip=0x%x, cs=0x%x, ss=0x%x, eflags=0x%x, useresp=0x%x\n", reg->eip, reg->ss, reg->eflags, reg->useresp); - - serialPrintf("*** Flags: %s%s%s%s\n", (present) ? "present " : "\0", (rw) ? "read-only " : "\0", (user) ? "user-mode " : "\0", (reserved) ? "reserved " : "\0"); - - - serialPrintf("\nerr_code %d\n", reg->err_code); - serialPrintf("REGISTER DUMP:\n"); - serialPrintf("eax=0x%x, ebx=0x%x, ecx=0x%x, edx=0x%x\n", reg->eax, reg->ebx, reg->ecx, reg->edx); - serialPrintf("edi=0x%x, esi=0x%x, ebp=0x%x, esp=0x%x\n", reg->edi, reg->esi, reg->ebp, reg->esp); - serialPrintf("eip=0x%x, cs=0x%x, ss=0x%x, eflags=0x%x, useresp=0x%x\n", reg->eip, reg->ss, reg->eflags, reg->useresp); - - - stackTrace(5); - - - asm volatile ("hlt"); - for (;;); -} \ No newline at end of file +// ===================================================================== +// panic.c - Kernel panic +// This file handles the kernel panicking and exiting +// ===================================================================== +// This file is apart of the reduceOS C kernel. Please credit me if you use this code. + + +#include // Main panic include file + +typedef struct { + struct stack_frame* ebp; + uint32_t eip; +} stack_frame; + +// This static function performes a stack trace to get the callers of panic. +static void stackTrace(uint32_t maximumFrames) { + stack_frame *stk; + asm volatile ("movl %%ebp, %0" : "=r"(stk)); + printf("\nStack trace:\n"); + serialPrintf("\nSTACK TRACE (EBP based):\n"); + for (uint32_t frame = 0; stk && frame < maximumFrames; frame++) { + printf("Frame %i: 0x%x\n", frame, stk->eip); + serialPrintf("FRAME %i: 0x%x\n", frame, stk->eip); + stk = stk->ebp; + } +} + +// Panic - halts system and prints an error message +void *panic(char *caller, char *code, char *reason) { + serialPrintf("===========================================================\n"); + serialPrintf("panic() called! FATAL ERROR!\n"); + serialPrintf("*** [%s] %s: %s\n", caller, code, reason); + serialPrintf("panic type: kernel panic\n"); + + + setKBHandler(false); + clearScreen(COLOR_WHITE, COLOR_RED); + updateTerminalColor_gfx(COLOR_BLACK, COLOR_LIGHT_GRAY); // Update terminal color + + // Make things look nicer + terminalSetUpdateScreen(false); + + printf("reduceOS v%s %s - Kernel Panic", VERSION, CODENAME); + if (terminalMode == 0) { + for (int i = 0; i < (SCREEN_WIDTH - strlen("reduceOS v - Kernel Panic") - strlen(CODENAME) - strlen(VERSION)); i++) printf(" "); // vga only because idc enough to do PSF_WIDTH + } else { + for (int i = 0; i < ((modeWidth - ((strlen("reduceOS v - Kernel Panic") + strlen(CODENAME) + strlen(VERSION)) * psfGetFontWidth()))); i += psfGetFontWidth()) printf(" "); + } + + terminalSetUpdateScreen(true); + terminalUpdateScreen(); + + // updateBottomText("A fatal error occurred!"); + + updateTerminalColor_gfx(COLOR_WHITE, COLOR_RED); + + printf("reduceOS encountered a fatal error and needs to shutdown.\n"); + printf("The error cause will be printed below. If you start an issue on GitHub, please include the following text.\n"); + printf("Apologies for any inconveniences caused by this error.\n"); + printf("\n"); + printf("The error encountered was:\n"); + printf("*** [%s] %s: %s \n", caller, code, reason); + + + registers_t *reg; + + // Funny + asm volatile ("mov %%eax, %0" : "=r"(reg->eax)); + asm volatile ("mov %%ebx, %0" : "=r"(reg->ebx)); + asm volatile ("mov %%ecx, %0" : "=r"(reg->ecx)); + asm volatile ("mov %%edx, %0" : "=r"(reg->edx)); + asm volatile ("mov %%esi, %0" : "=r"(reg->esi)); + asm volatile ("mov %%esp, %0" : "=r"(reg->esp)); + asm volatile ("mov %%ebp, %0" : "=r"(reg->ebp)); + asm volatile ("mov %%edi, %0" : "=r"(reg->edi)); + asm volatile ("mov %%ds, %0" : "=r"(reg->ds)); + asm volatile ("mov %%cs, %0" : "=r"(reg->cs)); + asm volatile ("mov %%ss, %0" : "=r"(reg->ss)); + + printf("\nStack dump:\n\n"); + printf("No error code was set (kernel panic).\n"); + printf("eax=0x%x, ebx=0x%x, ecx=0x%x, edx=0x%x\n", reg->eax, reg->ebx, reg->ecx, reg->edx); + printf("edi=0x%x, esi=0x%x, ebp=0x%x, esp=0x%x\n", reg->edi, reg->esi, reg->ebp, reg->esp); + printf("cs=0x%x, ss=0x%x\n", reg->cs, reg->ss); + + serialPrintf("STACK DUMP:\n"); + serialPrintf("eax=0x%x, ebx=0x%x, ecx=0x%x, edx=0x%x\n", reg->eax, reg->ebx, reg->ecx, reg->edx); + serialPrintf("edi=0x%x, esi=0x%x, ebp=0x%x, esp=0x%x\n", reg->edi, reg->esi, reg->ebp, reg->esp); + serialPrintf("cs=0x%x, ss=0x%x\n", reg->cs, reg->ss); + + + // TODO: Add debug symbols into the initrd so we get function names. + stackTrace(5); // Get a stack trace. + + asm volatile ("hlt"); + for (;;); +} + + +void *panicReg(char *caller, char *code, char *reason, registers_t *reg) { + serialPrintf("===========================================================\n"); + serialPrintf("panic() called! FATAL ERROR!\n"); + serialPrintf("*** ISR threw exception: %s\n", reason); + serialPrintf("panic type: %s.\n", code); + + + setKBHandler(false); + clearScreen(COLOR_WHITE, COLOR_RED); + updateTerminalColor_gfx(COLOR_BLACK, COLOR_LIGHT_GRAY); // Update terminal color + + // Make things look nicer + terminalSetUpdateScreen(false); + + printf("reduceOS v%s %s - Kernel Panic", VERSION, CODENAME); + if (terminalMode == 0) { + for (int i = 0; i < (SCREEN_WIDTH - strlen("reduceOS v - Kernel Panic") - strlen(CODENAME) - strlen(VERSION)); i++) printf(" "); // vga only because idc enough to do PSF_WIDTH + } else { + for (int i = 0; i < ((modeWidth - ((strlen("reduceOS v - Kernel Panic") + strlen(CODENAME) + strlen(VERSION)) * psfGetFontWidth()))); i += psfGetFontWidth()) printf(" "); + } + + terminalSetUpdateScreen(true); + terminalUpdateScreen(); + + // updateBottomText("A fatal error occurred!"); + + updateTerminalColor_gfx(COLOR_WHITE, COLOR_RED); + + printf("reduceOS encountered a fatal error and needs to shutdown.\n"); + printf("The error cause will be printed below. If you start an issue on GitHub, please include the following text.\n"); + printf("Apologies for any inconveniences caused by this error.\n"); + printf("\n"); + printf("The error encountered was:\n"); + printf("*** [%s] %s: %s \n", caller, code, reason); + printf("\nStack dump:\n\n"); + + printf("Error Code: %d\n", reg->err_code); + printf("eax=0x%x, ebx=0x%x, ecx=0x%x, edx=0x%x\n", reg->eax, reg->ebx, reg->ecx, reg->edx); + printf("edi=0x%x, esi=0x%x, ebp=0x%x, esp=0x%x\n", reg->edi, reg->esi, reg->ebp, reg->esp); + printf("eip=0x%x, cs=0x%x, ss=0x%x, eflags=0x%x, useresp=0x%x\n", reg->eip, reg->ss, reg->eflags, reg->useresp); + + serialPrintf("\nerr_code %d\n", reg->err_code); + serialPrintf("REGISTER DUMP:\n"); + serialPrintf("eax=0x%x, ebx=0x%x, ecx=0x%x, edx=0x%x\n", reg->eax, reg->ebx, reg->ecx, reg->edx); + serialPrintf("edi=0x%x, esi=0x%x, ebp=0x%x, esp=0x%x\n", reg->edi, reg->esi, reg->ebp, reg->esp); + serialPrintf("eip=0x%x, cs=0x%x, ss=0x%x, eflags=0x%x, useresp=0x%x\n", reg->eip, reg->ss, reg->eflags, reg->useresp); + + // Perform stack trace + stackTrace(5); + + asm volatile ("hlt"); + for (;;); +} + + + +// Oh no! We encountered a page fault! +void *pageFault(registers_t *reg) { + // Get the faulting address from CR2 + uint32_t faultAddress; + asm volatile("mov %%cr2, %0" : "=r" (faultAddress)); + + serialPrintf("===========================================================\n"); + serialPrintf("panic() called! FATAL ERROR!\n"); + serialPrintf("*** Page fault at address 0x%x\n", faultAddress); + + setKBHandler(false); + + // Get the flags + int present = !(reg->err_code & 0x1); // Page not present? + int rw = reg->err_code & 0x2; // Was this a write operation? + int user = reg->err_code & 0x4; // Were we in user-mode? + int reserved = reg->err_code & 0x8; // Were the reserved bits of page entry overwritten? + + clearScreen(COLOR_WHITE, COLOR_RED); + updateTerminalColor_gfx(COLOR_BLACK, COLOR_LIGHT_GRAY); // Update terminal color + + // Make things look nicer + terminalSetUpdateScreen(false); + + printf("reduceOS v%s %s - Kernel Panic", VERSION, CODENAME); + if (terminalMode == 0) { + for (int i = 0; i < (SCREEN_WIDTH - strlen("reduceOS v - Kernel Panic") - strlen(CODENAME) - strlen(VERSION)); i++) printf(" "); // vga only because idc enough to do PSF_WIDTH + } else { + for (int i = 0; i < ((modeWidth - ((strlen("reduceOS v - Kernel Panic") + strlen(CODENAME) + strlen(VERSION)) * psfGetFontWidth()))); i += psfGetFontWidth()) printf(" "); + } + + terminalSetUpdateScreen(true); + terminalUpdateScreen(); + + updateTerminalColor_gfx(COLOR_WHITE, COLOR_RED); + + printf("reduceOS encountered a fatal error and needs to shutdown.\n"); + printf("The error cause will be printed below. If you start an issue on GitHub, please include the following text.\n"); + printf("Apologies for any inconveniences caused by this error.\n"); + printf("\n"); + printf("The error encountered was:\n"); + printf("*** Page fault at address 0x%x\n", faultAddress); + printf("*** Flags: %s%s%s%s\n", (present) ? "present " : "\0", (rw) ? "read-only " : "\0", (user) ? "user-mode " : "\0 ", (reserved) ? "reserved " : "\0"); + printf("\nStack dump:\n\n"); + + printf("Error Code: %d\n", reg->err_code); + printf("eax=0x%x, ebx=0x%x, ecx=0x%x, edx=0x%x\n", reg->eax, reg->ebx, reg->ecx, reg->edx); + printf("edi=0x%x, esi=0x%x, ebp=0x%x, esp=0x%x\n", reg->edi, reg->esi, reg->ebp, reg->esp); + printf("eip=0x%x, cs=0x%x, ss=0x%x, eflags=0x%x, useresp=0x%x\n", reg->eip, reg->ss, reg->eflags, reg->useresp); + + serialPrintf("*** Flags: %s%s%s%s\n", (present) ? "present " : "\0", (rw) ? "read-only " : "\0", (user) ? "user-mode " : "\0", (reserved) ? "reserved " : "\0"); + + + serialPrintf("\nerr_code %d\n", reg->err_code); + serialPrintf("REGISTER DUMP:\n"); + serialPrintf("eax=0x%x, ebx=0x%x, ecx=0x%x, edx=0x%x\n", reg->eax, reg->ebx, reg->ecx, reg->edx); + serialPrintf("edi=0x%x, esi=0x%x, ebp=0x%x, esp=0x%x\n", reg->edi, reg->esi, reg->ebp, reg->esp); + serialPrintf("eip=0x%x, cs=0x%x, ss=0x%x, eflags=0x%x, useresp=0x%x\n", reg->eip, reg->ss, reg->eflags, reg->useresp); + + + stackTrace(5); + + + asm volatile ("hlt"); + for (;;); +} diff --git a/source/kernel/kernel/test.c b/source/kernel/kernel/test.c index 046842cd..72476dd7 100644 --- a/source/kernel/kernel/test.c +++ b/source/kernel/kernel/test.c @@ -1,17 +1,17 @@ // test.c - Test command for reduceOS -#include "include/test.h" - -#include "include/libc/stdint.h" -#include "include/libc/string.h" - -#include "include/fat.h" -#include "include/serial.h" -#include "include/terminal.h" -#include "include/floppy.h" -#include "include/ext2.h" -#include "include/bitmap.h" -#include "include/vfs.h" +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include extern ideDevice_t ideDevices[4]; diff --git a/source/kernel/libc/ordered_array.c b/source/kernel/libc/ordered_array.c deleted file mode 100644 index 92f12d35..00000000 --- a/source/kernel/libc/ordered_array.c +++ /dev/null @@ -1,84 +0,0 @@ -// ordered_array.c - Contains ordered array functions and definitions. -// Implementation credits in header file. - -#include "include/libc/ordered_array.h" // Main header file - -// Functions: - -// standard_lessthan_predicate(type_t a, type_t b) - Returns whether a is less than b. -int8_t standard_lessthan_predicate(type_t a, type_t b) { return (a < b) ? 1 : 0; } - -// createOrderedArray(uint32_t maxSize, lessthan_predicate less_than) - Creates and returns an ordered array -ordered_array_t createOrderedArray(uint32_t maxSize, lessthan_predicate less_than) { - ordered_array_t retValue; // This is the array we will return - retValue.array = (void*)kmalloc(maxSize * sizeof(type_t)); // Allocate space for the actual array - memset(retValue.array, 0, maxSize * sizeof(type_t)); // Fill the array with zeroes - - // Finish filling in the remaining values. - retValue.size = 0; - retValue.maxSize = maxSize; - retValue.less_than = less_than; - - // Return the ordered array - return retValue; -} - -// placeOrderedArray(void *addr, uint32_t maxSize, lessthan_predicate less_than) - Place an ordered array at address *addr (note: creates an ordered array) -ordered_array_t placeOrderedArray(void* addr, uint32_t maxSize, lessthan_predicate less_than) { - ordered_array_t retValue; - retValue.array = (type_t*)addr; // Set the array to the address given. - memset(retValue.array, 0, maxSize * sizeof(type_t)); // Fill the array with zeroes - - // Finish filling in the remaining values. - retValue.size = 0; - retValue.maxSize = maxSize; - retValue.less_than = less_than; - - // Return the ordered array. - return retValue; -} - -void destroyOrderedArray(ordered_array_t* array) { - // Not available, since we need kfree, but heap uses this to setup kfree, so it doesn't really work. -} - -// insertOrderedArray(type_t item, ordered_array_t *array) - Insert an item into array at a free index. -void insertOrderedArray(type_t item, ordered_array_t* array) { - ASSERT(array->less_than, "insertOrderedArray", "Invalid array less than (is 0)"); // Assert the less_than (check if it's valid) - - uint32_t iterator = 0; - while (iterator < array->size && array->less_than(array->array[iterator], item)) iterator++; // Get a free index in the ordered array. - - if (iterator == array->size) { - // Easy! Just add it at the end of the array - array->array[array->size++] = item; - } - else { - // We have a little more work to do. - type_t tmp = array->array[iterator]; - array->array[iterator] = item; - while (iterator < array->size) { - iterator++; - type_t tmp2 = array->array[iterator]; - array->array[iterator] = tmp; - tmp = tmp2; - } - array->size++; - } -} - -// lookupOrderedArray(uint32_t i, ordered_array_t *array) - Lookup an item in ordered array array at index i. -type_t lookupOrderedArray(uint32_t i, ordered_array_t* array) { - ASSERT(i < array->size, "lookupOrderedArray", "Index too large."); // Assert i (check if it's valid) - return array->array[i]; // Return the value -} - -// removeOrderedArray(uint32_t i, ordered_array_t *array) - Remove an item from ordered array array at index i. -void removeOrderedArray(uint32_t i, ordered_array_t* array) { - while (i < array->size) { - // Shift values left and increment i. - array->array[i] = array->array[i + 1]; - i++; - } - array->size--; // Decrement size -} \ No newline at end of file diff --git a/source/kernel/libc/printf.c b/source/kernel/libc/printf.c deleted file mode 100644 index 2176927c..00000000 --- a/source/kernel/libc/printf.c +++ /dev/null @@ -1,381 +0,0 @@ -// printf.c - Main printing function - -// WARNING: I DO NOT OWN THIS IMPLEMENTATION AT ALL. I DID NOT CREATE IT OR CODE IT AT ALL. THE ORIGINAL HEADER OF THE IMPLEMENTATION WILL BE PUT HERE: -/** - * @file kprintf.c - * @brief Kernel printf implementation. - * - * This is the newer, 64-bit-friendly printf originally implemented - * for EFI builds of Kuroko. It was merged into the ToaruOS libc - * and later became the kernel printf in Misaka. It supports the - * standard set of width specifiers, '0' or ' ' padding, left or - * right alignment, and the usermode version has a (rudimentary, - * inaccurate) floating point printer. This kernel version excludes - * float support. printf output is passed to callback functions - * which can write the output to a string buffer or spit them - * directly at an MMIO port. Support is also present for bounded - * writes, and we've left @c sprintf out of the kernel entirely - * in favor of @c snprintf. - * - * @copyright - * This file is part of ToaruOS and is released under the terms - * of the NCSA / University of Illinois License - see LICENSE.md - * Copyright (C) 2011-2021 K. Lange - */ - -#include "include/libc/stdint.h" -#include "include/libc/string.h" -#include "include/libc/stdlib.h" -#include "include/libc/stddef.h" -#include "include/libc/stdarg.h" - - -size_t (*printf_output)(size_t, uint8_t *) = NULL; - -#define OUT(c) do { callback(userData, (c)); written++; } while (0) -static size_t print_dec(unsigned long long value, unsigned int width, int (*callback)(void*,char), void * userData, int fill_zero, int align_right, int precision) { - size_t written = 0; - unsigned long long n_width = 1; - unsigned long long i = 9; - if (precision == -1) precision = 1; - - if (value == 0) { - n_width = 0; - } else { - unsigned long long val = value; - while (val >= 10UL) { - val /= 10UL; - n_width++; - } - } - - if (n_width < (unsigned long long)precision) n_width = precision; - - int printed = 0; - if (align_right) { - while (n_width + printed < width) { - OUT(fill_zero ? '0' : ' '); - printed += 1; - } - - i = n_width; - char tmp[100]; - while (i > 0) { - unsigned long long n = value / 10; - long long r = value % 10; - tmp[i - 1] = r + '0'; - i--; - value = n; - } - while (i < n_width) { - OUT(tmp[i]); - i++; - } - } else { - i = n_width; - char tmp[100]; - while (i > 0) { - unsigned long long n = value / 10; - long long r = value % 10; - tmp[i - 1] = r + '0'; - i--; - value = n; - printed++; - } - while (i < n_width) { - OUT(tmp[i]); - i++; - } - while (printed < (long long)width) { - OUT(fill_zero ? '0' : ' '); - printed += 1; - } - } - - return written; -} - -/* - * Hexadecimal to string - */ -static size_t print_hex(unsigned long long value, unsigned int width, int (*callback)(void*,char), void* userData, int fill_zero, int alt, int caps, int align) { - size_t written = 0; - int i = width; - - unsigned long long n_width = 1; - unsigned long long j = 0x0F; - while (value > j && j < UINT64_MAX) { - n_width += 1; - j *= 0x10; - j += 0x0F; - } - - if (!fill_zero && align == 1) { - while (i > (long long)n_width + 2*!!alt) { - OUT(' '); - i--; - } - } - - if (alt) { - OUT('0'); - OUT(caps ? 'X' : 'x'); - } - - if (fill_zero && align == 1) { - while (i > (long long)n_width + 2*!!alt) { - OUT('0'); - i--; - } - } - - i = (long long)n_width; - while (i-- > 0) { - char c = (caps ? "0123456789ABCDEF" : "0123456789abcdef")[(value>>(i*4))&0xF]; - OUT(c); - } - - if (align == 0) { - i = width; - while (i > (long long)n_width + 2*!!alt) { - OUT(' '); - i--; - } - } - - return written; -} - -/* - * vasprintf() - */ -size_t xvasprintf(int (*callback)(void *, char), void * userData, const char * fmt, va_list args) { - const char * s; - size_t written = 0; - for (const char *f = fmt; *f; f++) { - if (*f != '%') { - OUT(*f); - continue; - } - ++f; - unsigned int arg_width = 0; - int align = 1; /* right */ - int fill_zero = 0; - int big = 0; - int alt = 0; - int always_sign = 0; - int precision = -1; - while (1) { - if (*f == '-') { - align = 0; - ++f; - } else if (*f == '#') { - alt = 1; - ++f; - } else if (*f == '*') { - arg_width = (int)va_arg(args, int); - ++f; - } else if (*f == '0') { - fill_zero = 1; - ++f; - } else if (*f == '+') { - always_sign = 1; - ++f; - } else if (*f == ' ') { - always_sign = 2; - ++f; - } else { - break; - } - } - while (*f >= '0' && *f <= '9') { - arg_width *= 10; - arg_width += *f - '0'; - ++f; - } - if (*f == '.') { - ++f; - precision = 0; - if (*f == '*') { - precision = (int)va_arg(args, int); - ++f; - } else { - while (*f >= '0' && *f <= '9') { - precision *= 10; - precision += *f - '0'; - ++f; - } - } - } - if (*f == 'l') { - big = 1; - ++f; - if (*f == 'l') { - big = 2; - ++f; - } - } - if (*f == 'j') { - big = (sizeof(uintmax_t) == sizeof(unsigned long long) ? 2 : - sizeof(uintmax_t) == sizeof(unsigned long) ? 1 : 0); - ++f; - } - if (*f == 'z') { - big = (sizeof(size_t) == sizeof(unsigned long long) ? 2 : - sizeof(size_t) == sizeof(unsigned long) ? 1 : 0); - ++f; - } - if (*f == 't') { - big = (sizeof(ptrdiff_t) == sizeof(unsigned long long) ? 2 : - sizeof(ptrdiff_t) == sizeof(unsigned long) ? 1 : 0); - ++f; - } - /* fmt[i] == '%' */ - switch (*f) { - case 's': /* String pointer -> String */ - { - size_t count = 0; - if (big) { - return written; - } else { - s = (char *)va_arg(args, char *); - if (s == NULL) { - s = "(null)"; - } - if (precision >= 0) { - while (*s && precision > 0) { - OUT(*s++); - count++; - precision--; - if (arg_width && count == arg_width) break; - } - } else { - while (*s) { - OUT(*s++); - count++; - if (arg_width && count == arg_width) break; - } - } - } - while (count < arg_width) { - OUT(' '); - count++; - } - } - break; - case 'c': /* Single character */ - OUT((char)va_arg(args,int)); - break; - case 'p': - alt = 1; - if (sizeof(void*) == sizeof(long long)) big = 2; - /* fallthrough */ - case 'X': - case 'x': /* Hexadecimal number */ - { - unsigned long long val; - if (big == 2) { - val = (unsigned long long)va_arg(args, unsigned long long); - } else if (big == 1) { - val = (unsigned long)va_arg(args, unsigned long); - } else { - val = (unsigned int)va_arg(args, unsigned int); - } - written += print_hex(val, arg_width, callback, userData, fill_zero, alt, !(*f & 32), align); - } - break; - case 'i': - case 'd': /* Decimal number */ - { - long long val; - if (big == 2) { - val = (long long)va_arg(args, long long); - } else if (big == 1) { - val = (long)va_arg(args, long); - } else { - val = (int)va_arg(args, int); - } - if (val < 0) { - OUT('-'); - val = -val; - } else if (always_sign) { - OUT(always_sign == 2 ? ' ' : '+'); - } - written += print_dec(val, arg_width, callback, userData, fill_zero, align, precision); - } - break; - case 'u': /* Unsigned ecimal number */ - { - unsigned long long val; - if (big == 2) { - val = (unsigned long long)va_arg(args, unsigned long long); - } else if (big == 1) { - val = (unsigned long)va_arg(args, unsigned long); - } else { - val = (unsigned int)va_arg(args, unsigned int); - } - written += print_dec(val, arg_width, callback, userData, fill_zero, align, precision); - } - break; - case '%': /* Escape */ - OUT('%'); - break; - default: /* Nothing at all, just dump it */ - OUT(*f); - break; - } - } - return written; -} - -struct CBData { - char * str; - size_t size; - size_t written; -}; - -static int cb_sprintf(void * user, char c) { - struct CBData * data = user; - if (data->size > data->written + 1) { - data->str[data->written] = c; - data->written++; - if (data->written < data->size) { - data->str[data->written] = '\0'; - } - } - return 0; -} - -int vsnprintf(char *str, size_t size, const char *format, va_list ap) { - struct CBData data = {str,size,0}; - int out = xvasprintf(cb_sprintf, &data, format, ap); - cb_sprintf(&data, '\0'); - return out; -} - -int snprintf(char * str, size_t size, const char * format, ...) { - struct CBData data = {str,size,0}; - va_list args; - va_start(args, format); - int out = xvasprintf(cb_sprintf, &data, format, args); - va_end(args); - cb_sprintf(&data, '\0'); - return out; -} - -static int cb_printf(void * user, char c) { - terminalPutchar(c); - return 0; -} - -int printf(const char * fmt, ...) { - va_list args; - va_start(args, fmt); - int out = xvasprintf(cb_printf, NULL, fmt, args); - va_end(args); - - // We do a bit of funny (do not do this - libc calling conventions would stab and kill me if they saw this) - terminalUpdateScreen(); - - return out; -} \ No newline at end of file diff --git a/source/kernel/libc/putchar.c b/source/kernel/libc/putchar.c deleted file mode 100644 index 3976486f..00000000 --- a/source/kernel/libc/putchar.c +++ /dev/null @@ -1,10 +0,0 @@ -// putchar.c - prints characters to string - -#include "include/libc/stdio.h" - -// putchar(int ic) - terminalPutchar with return values. -int putchar(int ic) { - char c = (char) ic; - terminalWrite(&c, sizeof(c)); - return ic; -} \ No newline at end of file diff --git a/source/kernel/libc/sleep.c b/source/kernel/libc/sleep.c deleted file mode 100644 index 202084bb..00000000 --- a/source/kernel/libc/sleep.c +++ /dev/null @@ -1,14 +0,0 @@ -// sleep.c - Custom libc header file that uses the programmable interval timer to sleep for X milliseconds. -// Note that while I try my best to adhere to C standards, none of the libc function for the kernel will ever be used by an application, it's to make the code more easier to read. - -#include "include/libc/sleep.h" // Main header file - - -void sleep(int ms) { - // Originally, the default for a PIT timer is around 18.222Hz. - // Luckily, our pitInit function intializes the PIT with 100Hz. - - int startTickCount = pitGetTickCount(); - while (pitGetTickCount() - startTickCount < ms); - return; -} \ No newline at end of file diff --git a/source/kernel/libc/spinlock.c b/source/kernel/libc/spinlock.c deleted file mode 100644 index 4e0c5510..00000000 --- a/source/kernel/libc/spinlock.c +++ /dev/null @@ -1,25 +0,0 @@ -// spinlock.c - Implements spinlocks to lock/unlock resources - -#include "include/libc/spinlock.h" // Main header file - -// This spinlock implementation is very basic and needs to be improved, but it does work. - - -// spinlock_init() - Creates a new spinlock -atomic_flag *spinlock_init() { - atomic_flag *lock = ATOMIC_FLAG_INIT; - return lock; -} - - -// spinlock_lock(atomic_flag *lock) - Locks the spinlock -void spinlock_lock(atomic_flag *lock) { - while (atomic_flag_test_and_set_explicit(lock, memory_order_acquire)) { - asm volatile ("pause"); // IA-32 pause instruction, should prevent P-4s and Xeons from corrupting stuff - } -} - -// spinlock_release(atomic_flag *lock) - Releases the spinlock -void spinlock_release(atomic_flag *lock) { - atomic_flag_clear_explicit(lock, memory_order_release); -} \ No newline at end of file diff --git a/source/kernel/libc/stdlib.c b/source/kernel/libc/stdlib.c deleted file mode 100644 index 5732a201..00000000 --- a/source/kernel/libc/stdlib.c +++ /dev/null @@ -1,45 +0,0 @@ -// stdlib.c - replacement for standard C stdlib file. Contains certain useful functions like abs(). -// Why is this required? We use -ffreestanding in our compile options, so the standard std library isn't included. -// Note that while I try my best to adhere to C standards, none of the libc function for the kernel will ever be used by an application, it's to make the code more easier to read. - - -#include "include/libc/stdlib.h" - -// abs(int x) - absolute value -int abs(int x) { - if (x < 0) x = -x; - return x; -} - -// min(double n1, double n2) - Returns the minimum number -double min(double n1, double n2) { - if (n1 > n2) return n2; - return n1; // Just in case the numbers are equal, return n1, because they're the same anyway. -} - -// max(double n1, double n2) - Returns the minimum number -double max(double n1, double n2) { - if (n1 > n2) return n1; - return n2; // Just in case the numbers are equal, return n2, because they're the same anyway. -} - -// sqrt(double n) - Returns square root of a number -double sqrt(double n) { - // Binary search implementation of square root - double low = min(1, n); - double high = max(1, n); - double mid; - - // Update bounds to be off the target by a factor of 10 - while (100 * low * low < n) low *= 10; - while (0.01 * high * high > n) high *= 0.1; - - for (int i = 0; i < 100; i++) { - mid += (low + high) / 2; - if (mid*mid == n) return mid; - if (mid*mid > n) high = mid; - else low = mid; - } - - return mid; -} diff --git a/source/kernel/libc/string.c b/source/kernel/libc/string.c deleted file mode 100644 index 2cc90982..00000000 --- a/source/kernel/libc/string.c +++ /dev/null @@ -1,422 +0,0 @@ -// string.c - replacement for standard C string file. Contains certain useful functions like strlen. -// Why is this required? We use -ffreestanding in our compile options, so the standard std library isn't included. -// Note that while I try my best to adhere to C standards, none of the libc function for the kernel will ever be used by an application, it's to make the code more easier to read. - -#include "include/libc/string.h" // We need to include our header file. - - -// Macros for assistance (ToaruOS) -#define BITOP(A, B, OP) ((A)[(size_t)(B)/(8*sizeof *(A))] OP (size_t)1<<((size_t)(B)%(8*sizeof *(A)))) -#define ONES ((size_t)-1/UCHAR_MAX) -#define HIGHS (ONES * (UCHAR_MAX/2+1)) -#define HASZERO(X) (((X)-ONES) & ~(X) & HIGHS) - -// memcmp() - Comparing addresses/values in memory -// Three parameters - objects 1 and 2(const void*) and the amount of bytes to compare(size_t) - -int memcmp(const void *s1, const void *s2, size_t n) { - unsigned char *p1 = s1, *p2 = s2; // Changing them to types to avoid errors with the compiler - - if (s1 == s2) return 0; // Both pointers are pointing towards the same memory block. We don't need to check them. - - while (n > 0) { - if (*p1 != *p2) return (*p1 > *p2) ? 1:-1; // If they are not the same, return either 1 or -1 depending on whether the mismatching character was greater or smaller than the other. - n--; // Decrement n and increment p1 and p2 to move on to the next char - p1++; - p2++; - } -} - -// memcpy() - Copy a block of data from a source address to a destination address. -// Three parameters - destination block(void*), source block(void*), and amount of bytes to copy(size_t) - -void* memcpy(void* __restrict destination, const void* __restrict source, size_t n) { - // Typecast both addresses to char* and assign them to csrc and cdest. - char *csrc = (char *)source, *cdest = (char *)destination; - - // Now copy the contents of source to destination. - for (int i = 0; i < n; i++) { cdest[i] = csrc[i]; } -} - - - -// memmove() - Move a block data from a source address to a destination address -// Three parameters - source block(void*), destination block(void*), and amount of bytes to move(size_t) - -void* memmove(void* destination, const void* source, size_t n) { - // First, we need to typecast destination to an unsigned char*, as well as typecast source to a constant unsigned char. - unsigned char* dst = (unsigned char*) dst; - const unsigned char* src = (const unsigned char*) source; - - // If the destination is smaller than the source, we can do a normal for loop with i < n. - if (dst < src) { - for (size_t i = 0; i < n; i++) - dst[i] = src[i]; - - } else { - // If that's not the case, the for loop can decrement i. - for (size_t i = n; i != 0; i--) - dst[i-1] = src[i-1]; // i-1 accounts for the indexes. - } - - // Now just simply return destination (same type as function return, void*) - return destination; -} - - -// memset() - Set a buffer in memory to a given value. -// Three parameters - buffer, value, amount of times to set - -void* memset(void *buf, char c, size_t n) { - unsigned char *temp = (unsigned char *)buf; - for (; n != 0; n--) temp[n-1] = c; - return buf; -} - -// strlen() - Returns the length of a string(size_t) -// One parameter - str -int strlen(char *str) { - int i = 0; - while (*str++) { - i++; - } - return i; -} - - -// itoa() - converts an integer to a string -// Three parameters - Integer, string buffer, integer base (1-16) -void itoa(void *n, char *buffer, int base) { - static char bchars[] = {"FEDCBA9876543210123456789ABCDEF"}; - char tbuf[32]; // Temporary buffer - int pos = 0; - int opos = 0; - int top = 0; - - int num = (int)n; - - if (num < 0 && base == 10) { // We need to do a little extra work if the value is negative. - *buffer++ = '-'; - } - - if (num == 0 || base > 16) { // Don't even bother if the base is greater than 16 or the number is 0. - buffer[0] = '0'; - buffer[1] = '\0'; - return; - } - - // First, get the character - while (num != 0) { - tbuf[pos] = bchars[15 + num % base]; - pos++; - num /= base; - } - - top = pos--; - - for (opos = 0; opos < top; pos--,opos++) - buffer[opos] = tbuf[pos]; - - buffer[opos] = 0; -} - - -// itoa_long(uint64_t value, char *str, int base) - Disgusting hack to make longs work with itoa() -void itoa_long(uint64_t value, char* str, int base) { - if (base < 2 || base > 36) { - *str = '\0'; // Invalid base; return an empty string - return str; - } - - char* digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - char buffer[65]; // Enough to handle uint64_t in binary (base 2) - char* ptr = buffer + sizeof(buffer) - 1; - *ptr = '\0'; // Null-terminate the buffer - - // Handle zero explicitly - if (value == 0) { - *--ptr = digits[0]; - } else { - // Convert the number to the specified base - while (value != 0) { - *--ptr = digits[value % base]; - value /= base; - } - } - - // Copy the result to the output string - while (*ptr) { - *str++ = *ptr++; - } - *str = '\0'; // Null-terminate the result string -} - - - -// strcpy() - copies a string to a string. -// Two parameters - destination and source. -char *strcpy(char *dest, const char *src) { - char *dest_p = dest; - while (*dest++ = *src++); // Copy all the contents of src to destination. - return dest_p; -} - -// toupper() - turns a char uppercase -// One parameter - char. -char toupper(char c) { - if ((c >= 'a') && (c <= 'z')) - return (c - 32); - return c; -} - - -// tolower() - turns a char lowercase -// One parameter - char. -char tolower(char c) { - if ((c >= 'A') && (c <= 'Z')) - return (c + 32); - return c; -} - -// isalpha() - returns if a char is in the alphabet -int isalpha(char ch) { - return (((ch >= 'A') && (ch <= 'Z')) || ((ch >= 'a') && (ch <= 'z'))); -} - -// strcmp() - compares s1 to s2 -// Two parameters - strings #1 and #2. -int strcmp (const char* str1, char *str2) { - int i = 0; - - while ((str1[i] == str2[i])) { - if (str2[i++] == 0) - return 0; - } - return 1; -} - -// strncmp() - Compares str1 to str2 for x amount of chars. -// Three parameters - strings #1 and #2 and the # of chars -int strncmp(const char *str1, char *str2, int length) { - int i = 0; - - while ((str1[i] == str2[i])) { - if (str2[i++] == 0) - return 0; - } - return 1; -} - -// atoi() - Converts a string to an integer -// Needs more parameters and isn't complete. -int atoi(char *str) { - int ret = 0; - for (int i = 0; i < strlen(str); i++) { - ret = ret * 10 + str[i] - '0'; - } - - return ret; -} - -// strtok() - Splits a string into tokens, seperated by characters in delim. -char *strtok(char *str, const char *delim) { - static int currentIndex = 0; - - if (!str || !delim || str[currentIndex] == '\0') return NULL; - - // Allocate memory for character. - char *w = (char*)kmalloc(sizeof(char)*100); - - int i = currentIndex, k = 0, j = 0; - while (str[i] != '\0') { - j = 0; - while (delim[j] != '\0') { - if (str[i] != delim[j]) w[k] = str[i]; - else goto Done; - j++; - } - - i++; - k++; - } - -Done: - w[i] = 0; - currentIndex = i+1; - return w; -} - - -// Strtol implementation that needs some cleaning up and possibly refactoring -// EXACT Source: https://github.com/gcc-mirror/gcc/blob/master/libiberty/strtol.c - -#define ISDIGIT(c) ((c) >= '0' && (c) <= '9') -#define ISUPPER(c) ((c) >= 'A' && (c) <= 'Z') -#define ISALPHA(c) (((c) >= 'a' && (c) <= 'z') | ((c) >= 'A' && (c) <= 'Z')) - -long strtol(const char *nptr, char **endptr, int base) { - const char *s = nptr; - unsigned long acc; - int c; - unsigned long cutoff; - int neg = 0, any, cutlim; - - /* - * Skip white space and pick up leading +/- sign if any. - * If base is 0, allow 0x for hex and 0 for octal, else - * assume decimal; if base is already 16, allow 0x. - */ - do { - c = *s++; - } while (c == ' '); - if (c == '-') { - neg = 1; - c = *s++; - } else if (c == '+') - c = *s++; - if ((base == 0 || base == 16) && - c == '0' && (*s == 'x' || *s == 'X')) { - c = s[1]; - s += 2; - base = 16; - } - if (base == 0) - base = c == '0' ? 8 : 10; - - /* - * Compute the cutoff value between legal numbers and illegal - * numbers. That is the largest legal value, divided by the - * base. An input number that is greater than this value, if - * followed by a legal input character, is too big. One that - * is equal to this value may be valid or not; the limit - * between valid and invalid numbers is then based on the last - * digit. For instance, if the range for longs is - * [-2147483648..2147483647] and the input base is 10, - * cutoff will be set to 214748364 and cutlim to either - * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated - * a value > 214748364, or equal but the next digit is > 7 (or 8), - * the number is too big, and we will return a range error. - * - * Set any if any `digits' consumed; make it negative to indicate - * overflow. - */ - cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX; - cutlim = cutoff % (unsigned long)base; - cutoff /= (unsigned long)base; - for (acc = 0, any = 0;; c = *s++) { - if (ISDIGIT(c)) - c -= '0'; - else if (ISALPHA(c)) - c -= ISUPPER(c) ? 'A' - 10 : 'a' - 10; - else - break; - if (c >= base) - break; - if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) - any = -1; - else { - any = 1; - acc *= base; - acc += c; - } - } - if (any < 0) { - acc = neg ? LONG_MIN : LONG_MAX; - panic("string.c", "strtol", "Out of range exception"); - } else if (neg) - acc = -acc; - if (endptr != 0) - *endptr = (char *) (any ? s - 1 : nptr); - return (acc); -} - -// strchr(char *str, int ch) - Locate the first occurance of a character in a string (credit to BrokenThorn Entertainment) -char *strchr(char *str, int ch) { - do { - if (*str == ch) { - return (char*)str; - } - } while (*str++); - - return 0; // Nothing. -} - -// strchrnul(const char *str, int ch) - Locates a character in a string (why do we need this?) -char *strchrnul(const char *str, int ch) { - size_t *w; - size_t k; - - ch = (uint8_t)ch; - if (!ch) return (char*)str + strlen(str); // Return basically what is a NULL - - for (; (uintptr_t)str % sizeof(size_t); str++) { - if (!*str || *(unsigned char *)str == ch) return (char*)str; - } - - k = ONES * ch; - for (w = (void*)str; !HASZERO(*w) && !HASZERO(*w^k); w++); - for (str = (void*)w; *str && *(unsigned char*)str != ch; str++); - - return (char*)str; -} - - -// strcspn(const char *str1, const char *reject) - Scans str1 for the first occurence of any of the characters that are NOT part of reject. -size_t strcspn(const char *str1, const char *reject) { - const char *a = str1; - if (reject[0] && reject[1]) { - size_t byteset[32 / sizeof(size_t)] = {0}; - for (; *reject && BITOP(byteset, *(unsigned char *)reject, |=); reject++); - for (; *str1 && !BITOP(byteset, *(unsigned char *)str1, &); str1++); - return str1 - a; - } - - return strchrnul(str1, *reject) - a; -} - -// strspn(const char *str1, const char *accept) - Scans str1 for the first occurence of any of the characters that are part of accept. -size_t strspn(const char *str1, const char *accept) { - const char *a = str1; - size_t byteset[32 / sizeof(size_t)] = {0}; - - if (!accept[0]) return 0; - - if (!accept[1]) { - for (; *str1 == *accept; str1++); - return str1 - a; - } - - for (; *accept && BITOP(byteset, *(unsigned char *)accept, |=); accept++); - for (; *str1 && BITOP(byteset, *(unsigned char *)str1, &); str1++); - - return str1 - a; -} - -// strpbrk(const char *s, const char *b) - Returns a pointer to the first occurence of b within s. -char *strpbrk(const char *s, const char *b) { - s += strcspn(s, b); - return *s ? (char*)s : 0; -} - -// strtok_r(char *str, const char *delim, char **saveptr) - Thread-safe version of strtok -char *strtok_r(char *str, const char *delim, char **saveptr) { - char *token; - if (str == NULL) str = *saveptr; - - str += strspn(str, delim); - if (*str == '\0') { - *saveptr = str; - return NULL; // No occurence - } - - token = str; - str = strpbrk(token, delim); - if (str == NULL) { - *saveptr = (char*)((size_t)strchr(token, '\0')); - } else { - *str = '\0'; - *saveptr = str + 1; - } - - return token; -} diff --git a/source/kernel/make.config b/source/kernel/make.config index d53c3a53..e25eb3ec 100644 --- a/source/kernel/make.config +++ b/source/kernel/make.config @@ -13,7 +13,7 @@ INCLUDE_DIR?=$(PREFIX)/include/kernel LIBDIRS = $(dir $(shell $(CC) -print-libgcc-file-name)) -CFLAGS := $(CFLAGS) -m32 -fno-stack-protector -g -std=gnu99 -ffreestanding -fno-pie -Wall -Wextra -I. +CFLAGS := $(CFLAGS) -m32 -fno-stack-protector -g -std=gnu99 -ffreestanding -fno-pie -Wall -Wextra CPPFLAGS := $(CPPFLAGS) -LDFLAGS := $(LDFLAGS) -melf_i386 -L$(LIBDIRS) -LIBS := $(LIBS) \ No newline at end of file +LDFLAGS := $(LDFLAGS) -melf_i386 -L$(LIBDIRS) -L$(DESTDIR)$(LIBDIR) +LIBS := $(LIBS) -lgcc -lc_reduced \ No newline at end of file diff --git a/source/kernel/mem/dma.c b/source/kernel/mem/dma.c index 10a619d6..bdb62f3d 100644 --- a/source/kernel/mem/dma.c +++ b/source/kernel/mem/dma.c @@ -3,7 +3,7 @@ // ========================================================= // This file is part of the reduceOS C kernel. Please credit me if you use this code. -#include "include/dma.h" // Main header file +#include // Main header file // NOTE: This file is NOT for PCI Busmastering DMA, rather ISA DMA // Also, ISA DMA is pretty useless (OSDev wiki refers to it as the fitting "appendix of the PC") diff --git a/source/kernel/mem/liballoc/liballoc.c b/source/kernel/mem/liballoc/liballoc.c index eccf5fb5..24a3ca42 100644 --- a/source/kernel/mem/liballoc/liballoc.c +++ b/source/kernel/mem/liballoc/liballoc.c @@ -1,4 +1,4 @@ -#include "include/liballoc.h" +#include /** Durand's Amazing Super Duper Memory functions. */ @@ -49,7 +49,7 @@ #define LIBALLOC_DEAD 0xdeaddead #if defined DEBUG || defined INFO -#include "include/serial.h" +#include #define FLUSH() asm ("nop") diff --git a/source/kernel/mem/liballoc/liballoc_forwarder.c b/source/kernel/mem/liballoc/liballoc_forwarder.c index 90c8b885..58124461 100644 --- a/source/kernel/mem/liballoc/liballoc_forwarder.c +++ b/source/kernel/mem/liballoc/liballoc_forwarder.c @@ -1,62 +1,62 @@ -// ======================================================================== -// liballoc_forwader.c - The embodyment of my hatred -// ======================================================================== - -#include "include/liballoc_forwarder.h" // Main header file - -uint32_t placement_address = (uint32_t)&end; -int liballoc_enabled = 0; - - -// Just a quick, dirty hack I came up with. -// Allow me to explain - we're running back into an old friend/enemy, BIOS32. -// BIOS32 causes bugs in paging code and HAS to be called for VBE/VESA, which sucks because no one likes it. -// ESPECIALLY not my memory code! liballoc specifically causes a ton of issues with it, and I'm sick and tired of it. -// BIOS32 will be replaced with a v86 monitor eventually, but for now we're just not going to bother with it. -// I hate my life. - - -void enable_liballoc() { liballoc_enabled = 1; } - -uint32_t kmalloc(uint32_t size){ - - // Check if liballoc is enabled, and if so, use that instead. - if (liballoc_enabled) { - return liballoc_kmalloc(size); - } else { - // I'm going mentally insane - if ((placement_address && 0x00000FFF)) { - placement_address = ALIGN_PAGE(placement_address); - } - - uint32_t ret = placement_address; - placement_address += size; - return ret; - } -} - - -void *krealloc(void *a, size_t b) { - if (liballoc_enabled) { - return liballoc_krealloc(a, b); - } else { - serialPrintf("krealloc: Something tried to reallocate but we don't have liballoc running!\n"); - } -} - -void *kcalloc(void *a, size_t b) { - if (liballoc_enabled) { - return liballoc_kcalloc(a, b); - } else { - serialPrintf("kcalloc: Something tried to call calloc but we don't have liballoc running!\n"); - } -} - -void kfree(void *a) { - if (liballoc_enabled) { - return liballoc_kfree(a); - } else { - serialPrintf("kfree: Something tried to call kfree but we don't have liballoc running!\n"); - } -} - +// ======================================================================== +// liballoc_forwader.c - The embodyment of my hatred +// ======================================================================== + +#include // Main header file + +uint32_t placement_address = (uint32_t)&end; +int liballoc_enabled = 0; + + +// Just a quick, dirty hack I came up with. +// Allow me to explain - we're running back into an old friend/enemy, BIOS32. +// BIOS32 causes bugs in paging code and HAS to be called for VBE/VESA, which sucks because no one likes it. +// ESPECIALLY not my memory code! liballoc specifically causes a ton of issues with it, and I'm sick and tired of it. +// BIOS32 will be replaced with a v86 monitor eventually, but for now we're just not going to bother with it. +// I hate my life. + + +void enable_liballoc() { liballoc_enabled = 1; } + +uint32_t kmalloc(uint32_t size){ + + // Check if liballoc is enabled, and if so, use that instead. + if (liballoc_enabled) { + return liballoc_kmalloc(size); + } else { + // I'm going mentally insane + if ((placement_address && 0x00000FFF)) { + placement_address = ALIGN_PAGE(placement_address); + } + + uint32_t ret = placement_address; + placement_address += size; + return ret; + } +} + + +void *krealloc(void *a, size_t b) { + if (liballoc_enabled) { + return liballoc_krealloc(a, b); + } else { + serialPrintf("krealloc: Something tried to reallocate but we don't have liballoc running!\n"); + } +} + +void *kcalloc(void *a, size_t b) { + if (liballoc_enabled) { + return liballoc_kcalloc(a, b); + } else { + serialPrintf("kcalloc: Something tried to call calloc but we don't have liballoc running!\n"); + } +} + +void kfree(void *a) { + if (liballoc_enabled) { + return liballoc_kfree(a); + } else { + serialPrintf("kfree: Something tried to call kfree but we don't have liballoc running!\n"); + } +} + diff --git a/source/kernel/mem/liballoc/liballoc_wrapper.c b/source/kernel/mem/liballoc/liballoc_wrapper.c index f04c7490..5a1838e5 100644 --- a/source/kernel/mem/liballoc/liballoc_wrapper.c +++ b/source/kernel/mem/liballoc/liballoc_wrapper.c @@ -5,7 +5,7 @@ // NOTE: liballoc is NOT by me! It is not by blanham (creator of the repo linked in the README.MD), but rather by Durand Miller // NO CODE OF LIBALLOC.C OR LIBALLOC.H IS CREATED BY ME. -#include "include/liballoc_wrapper.h" // Main header file +#include // Main header file atomic_flag lock = ATOMIC_FLAG_INIT; // Memory lock (we dont use spinlock_init because ehhhh) diff --git a/source/kernel/mem/pmm.c b/source/kernel/mem/pmm.c index ae99f29c..bb86e56f 100644 --- a/source/kernel/mem/pmm.c +++ b/source/kernel/mem/pmm.c @@ -4,7 +4,7 @@ // This file is a part of the reduceOS C kernel. Please credit me if you use this code. // Some code was sourced from JamesM's Kernel Development Tutorials. Please credit him as well. -#include "include/pmm.h" // Main header file +#include // Main header file // (from JamesM's kernel dev tutorials) #define INDEX_BIT(a) (a/(8*4)) @@ -263,4 +263,4 @@ uint32_t pmm_getUsedBlocks() { uint32_t pmm_getFreeBlocks() { return (pmm_getMaxBlocks() - pmm_getUsedBlocks()); -} \ No newline at end of file +} diff --git a/source/kernel/mem/vmm.c b/source/kernel/mem/vmm.c index df75f1ae..d11a5baf 100644 --- a/source/kernel/mem/vmm.c +++ b/source/kernel/mem/vmm.c @@ -4,10 +4,10 @@ // This file is part of the reduceOS C kernel. Please credit me if you use this code. // NOTICE: Paging file structure and design sourced from BrokenThorn Entertainment. MOST code is written by me, but PLEASE credit them! -#include "include/vmm.h" // Main header file +#include // Main header file -#include "include/panic.h" // Kernel panicking +#include // Kernel panicking // Variables pagedirectory_t *currentDirectory = 0; // Current page directory diff --git a/source/kernel/mem/vmm_pde.c b/source/kernel/mem/vmm_pde.c index 974b7b25..59d9353c 100644 --- a/source/kernel/mem/vmm_pde.c +++ b/source/kernel/mem/vmm_pde.c @@ -4,7 +4,7 @@ // This file is part of the reduceOS C kernel. Please credit me if you use this code. // NOTICE: Paging file structure and design sourced from BrokenThorn Entertainment. MOST code is written by me, but PLEASE credit them! -#include "include/vmm_pde.h" // Main header file +#include // Main header file // Most of this file is just PDE helper functions diff --git a/source/kernel/mem/vmm_pte.c b/source/kernel/mem/vmm_pte.c index e1f89497..e4e6f845 100644 --- a/source/kernel/mem/vmm_pte.c +++ b/source/kernel/mem/vmm_pte.c @@ -4,7 +4,7 @@ // This file is part of the reduceOS C kernel. Please credit me if you use this code. // NOTICE: Paging file structure and design sourced from BrokenThorn Entertainment. MOST code is written by me, but PLEASE credit them! -#include "include/vmm_pte.h" // Main header file +#include // Main header file // Most of this file is just PTE helper functions. @@ -36,4 +36,4 @@ bool pte_iswritable(pte_t entry) { // pte_getframe(pte_t entry) - Returns the address of the PTE frame. uint32_t pte_getframe(pte_t entry) { return entry & PTE_FRAME; -} \ No newline at end of file +} diff --git a/source/kernel/misc/hashmap.c b/source/kernel/misc/hashmap.c index 0e792af6..35d2464d 100644 --- a/source/kernel/misc/hashmap.c +++ b/source/kernel/misc/hashmap.c @@ -9,10 +9,13 @@ */ -#include "include/libc/string.h" -#include "include/libc/list.h" -#include "include/hashmap.h" -#include "include/mem.h" +#include +#include +#include + +extern void kfree(void *); + + unsigned int hashmap_string_hash(const void * _key) { unsigned int hash = 0; @@ -232,4 +235,4 @@ int hashmap_is_empty(hashmap_t * map) { if (map->entries[i]) return 0; } return 1; -} \ No newline at end of file +} diff --git a/source/kernel/misc/list.c b/source/kernel/misc/list.c index 0343dedd..b9b0aa62 100644 --- a/source/kernel/misc/list.c +++ b/source/kernel/misc/list.c @@ -1,6 +1,6 @@ // list.c - Simple list implementation, shouldn't be in libc but whatever -#include "include/list.h" // Main header file +#include // Main header file // list_destroy(list_t *list) - Destroys the contents of a list void list_destroy(list_t *list) { diff --git a/source/kernel/misc/tree.c b/source/kernel/misc/tree.c index 8757f557..7932cda7 100644 --- a/source/kernel/misc/tree.c +++ b/source/kernel/misc/tree.c @@ -1,6 +1,6 @@ // tree.c - General purpose tree implementation, shouldn't even be in libc. -#include "include/tree.h" // Main header file +#include // Main header file // tree_create() - Create a new tree tree_t *tree_create() { @@ -157,4 +157,4 @@ tree_node_t *tree_node_find(tree_node_t *node, void *search, tree_comparator_t c // tree_find(tree_t *tree, void *value, tree_comparator_t comparator) - Find a value within a tree tree_node_t *tree_find(tree_t *tree, void *value, tree_comparator_t comparator) { return tree_node_find(tree->root, value, comparator); -} \ No newline at end of file +} diff --git a/source/kernel/tasks/syscall.c b/source/kernel/tasks/syscall.c index b75ce0d2..740097ba 100644 --- a/source/kernel/tasks/syscall.c +++ b/source/kernel/tasks/syscall.c @@ -4,7 +4,7 @@ // This file is a part of the reduceOS C kernel. Please credit me if you use this code. -#include "include/syscall.h" // Main header file +#include // Main header file @@ -65,4 +65,4 @@ void syscallHandler(registers_t *regs) { pop %%ebx; \ pop %%ebx; \ " : "=a" (returnValue) : "r" (regs->edi), "r" (regs->esi), "r" (regs->edx), "r" (regs->ecx), "r" (regs->ebx), "r" (fn)); -} \ No newline at end of file +} diff --git a/source/kernel/tasks/tss.c b/source/kernel/tasks/tss.c index 10f2d6d9..8a39e544 100644 --- a/source/kernel/tasks/tss.c +++ b/source/kernel/tasks/tss.c @@ -1,36 +1,36 @@ -// ================================================================= -// tss.c - Handles managing the Task State Segment -// ================================================================= -// This file is a part of the reduceOS C kernel. Please credit me if you use this code. - -#include "include/tss.h" // Task State Segment - -tss_entry_t tss; - -// tssWrite(int32_t index, uint16_t ss0, uint32_t esp0) - Write to task state segment (and initalize structure) -void tssWrite(int32_t index, uint16_t ss0, uint32_t esp0) { - // Begin by getting base and limit of entry into GDT. - uint32_t base = (uint32_t)&tss; - uint32_t limit = base + sizeof(tss); - - gdtSetGate(index, base, limit, 0xE9, 0x00); - - // Ensure descriptor is 0. - memset(&tss, 0, sizeof(tss)); - - // Set the kernel stack segment and pointer. - tss.ss0 = ss0; - tss.esp0 = esp0; - - - // Setup CS, SS, DS, ES, FS, and GS entries in the TSS - they specify what segments should be loaded when processor switches to kernel mode. - tss.cs = 0x0B; - tss.ss = tss.ds = tss.es = tss.fs = tss.gs = 0x13; -} - - - -// setKernelStack(uint32_t stack) - Set the kernel stack. -void setKernelStack(uint32_t stack) { - tss.esp0 = stack; -} +// ================================================================= +// tss.c - Handles managing the Task State Segment +// ================================================================= +// This file is a part of the reduceOS C kernel. Please credit me if you use this code. + +#include // Task State Segment + +tss_entry_t tss; + +// tssWrite(int32_t index, uint16_t ss0, uint32_t esp0) - Write to task state segment (and initalize structure) +void tssWrite(int32_t index, uint16_t ss0, uint32_t esp0) { + // Begin by getting base and limit of entry into GDT. + uint32_t base = (uint32_t)&tss; + uint32_t limit = base + sizeof(tss); + + gdtSetGate(index, base, limit, 0xE9, 0x00); + + // Ensure descriptor is 0. + memset(&tss, 0, sizeof(tss)); + + // Set the kernel stack segment and pointer. + tss.ss0 = ss0; + tss.esp0 = esp0; + + + // Setup CS, SS, DS, ES, FS, and GS entries in the TSS - they specify what segments should be loaded when processor switches to kernel mode. + tss.cs = 0x0B; + tss.ss = tss.ds = tss.es = tss.fs = tss.gs = 0x13; +} + + + +// setKernelStack(uint32_t stack) - Set the kernel stack. +void setKernelStack(uint32_t stack) { + tss.esp0 = stack; +} diff --git a/source/libc_reduced/Makefile b/source/libc_reduced/Makefile index 84daeb29..712369c7 100644 --- a/source/libc_reduced/Makefile +++ b/source/libc_reduced/Makefile @@ -12,7 +12,7 @@ PYTHON = python3 # Should expose this so the user can modify. Sorry! # Source directories # Other Directories -OUT_OBJ = $(PROJECT_ROOT)/obj/libc_reduced/ +OUT_OBJ = $(PROJECT_ROOT)/obj/libc_reduced OUT_LIBRARY = . # Directories (EDIT ME) @@ -37,7 +37,7 @@ TARGET_DISABLED: -libc_reduced.a: $(C_OBJS) +libc_reduced.a: MAKE_OUTPUT_DIRS $(C_OBJS) @echo "-- Building libc_reduced.a..." $(AR) rcs $@ $(C_OBJS) @@ -45,6 +45,7 @@ libc_reduced.a: $(C_OBJS) # Other targets for the Makefile MAKE_OUTPUT_DIRS: + @-$(MKDIR) $(OUT_OBJ) @-$(MKDIR) $(DIRECTORIES) @@ -68,10 +69,10 @@ install-headers: install: libc_reduced.a @echo "-- Installing libc_reduced.a..." mkdir -p $(DESTDIR)$(LIBDIR) - cp libc.a $(DESTDIR)$(LIBDIR) + cp libc_reduced.a $(DESTDIR)$(LIBDIR) # Clean function clean: -$(RM) -rf $(DIRECTORIES) -$(RM) $(OUT_ASMOBJ)/*.o - -$(RM) libc.a \ No newline at end of file + -$(RM) libc_reduced.a \ No newline at end of file diff --git a/source/libc_reduced/include/stddef.h b/source/libc_reduced/include/stddef.h index e89827db..11f1f7d2 100644 --- a/source/libc_reduced/include/stddef.h +++ b/source/libc_reduced/include/stddef.h @@ -2,11 +2,6 @@ // Why is this required? We use -ffreestanding in our compile options, so the standard std library isn't included. -#if 1 - -#include - -#else // Definitions #define null 0 #define NULL 0 @@ -15,4 +10,3 @@ typedef unsigned size_t; typedef signed ptrdiff_t; -#endif \ No newline at end of file diff --git a/source/libc_reduced/make.config b/source/libc_reduced/make.config index 1a73c646..c16ec77e 100644 --- a/source/libc_reduced/make.config +++ b/source/libc_reduced/make.config @@ -9,7 +9,7 @@ DESTDIR?= PREFIX?=/usr/local EXEC_PREFIX?=$(PREFIX) BOOT_OUTPUT?=/boot -INCLUDE_DIR?=$(PREFIX)/include/kernel +INCLUDE_DIR?=$(PREFIX)/include LIBDIR?=$(EXEC_PREFIX)/lib LIBDIRS = $(dir $(shell $(CC) -print-libgcc-file-name)) diff --git a/source/sysroot/boot/kernel.elf b/source/sysroot/boot/kernel.elf deleted file mode 100755 index d878c758..00000000 Binary files a/source/sysroot/boot/kernel.elf and /dev/null differ diff --git a/source/sysroot/usr/fonts/font.o b/source/sysroot/usr/fonts/font.o deleted file mode 100644 index 12719e73..00000000 Binary files a/source/sysroot/usr/fonts/font.o and /dev/null differ diff --git a/source/sysroot/usr/include/kernel/CONFIG.h b/source/sysroot/usr/include/kernel/CONFIG.h deleted file mode 100644 index d730a50f..00000000 --- a/source/sysroot/usr/include/kernel/CONFIG.h +++ /dev/null @@ -1,15 +0,0 @@ -// ============================================================= -// reduceOS internal configuration file -// ============================================================= -// SECTIONS OF THIS FILE ARE AUTOMATED BY BUILDSCRIPTS. DO NOT MODIFY ANY SECTIONS MARKED AS SO. -// This file contains configuration data for all of reduceOS, such as the release codename, build no. & date, debug/release config, etc. - - -// YOU CAN MODIFY THE BELOW LINES -#define CODENAME "Apricity" -#define VERSION "1.3-prerelease1" - -// DO NOT MODIFY THE BELOW LINES!!! -#define BUILD_NUMBER "3643" -#define BUILD_DATE "08/07/24, 12:46:42" -#define BUILD_CONFIGURATION "DEBUG" diff --git a/source/sysroot/usr/include/kernel/acpi.h b/source/sysroot/usr/include/kernel/acpi.h deleted file mode 100644 index ddd434ba..00000000 --- a/source/sysroot/usr/include/kernel/acpi.h +++ /dev/null @@ -1,172 +0,0 @@ -// acpi.h - header file for the Advanced Configuration Power Interface manager - -#ifndef ACPI_H -#define ACPI_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations. -#include "include/local_apic.h" // Local APIC (different from ACPI) -#include "include/io_apic.h" // IO APIC -#include "include/libc/string.h" // Misc. functions -#include "include/bios32.h" // BIOS32 functions - -// Typedefs - -// ACPI header -typedef struct { - char signature[4]; - uint32_t length; - uint8_t revision; - uint8_t checksum; - char OEM[6]; - char OEMTableID[8]; - uint32_t OEMRevision; - uint32_t creatorID; - uint32_t creatorRevision; -} __attribute__((packed)) ACPIHeader; - -// ACPI FADT (Fixed ACPI Description Table) -// https://wiki.osdev.org/FADT - -typedef struct { - uint8_t AddressSpace; - uint8_t BitWidth; - uint8_t BitOffset; - uint8_t AccessSize; - uint64_t Address; -} GenericAddressStructure; - -typedef struct { - ACPIHeader h; - uint32_t FirmwareCtrl; - uint32_t Dsdt; - - // field used in ACPI 1.0; no longer in use, for compatibility only - uint8_t Reserved; - - uint8_t PreferredPowerManagementProfile; - uint16_t SCI_Interrupt; - uint32_t SMI_CommandPort; - uint8_t AcpiEnable; - uint8_t AcpiDisable; - uint8_t S4BIOS_REQ; - uint8_t PSTATE_Control; - uint32_t PM1aEventBlock; - uint32_t PM1bEventBlock; - uint32_t PM1aControlBlock; - uint32_t PM1bControlBlock; - uint32_t PM2ControlBlock; - uint32_t PMTimerBlock; - uint32_t GPE0Block; - uint32_t GPE1Block; - uint8_t PM1EventLength; - uint8_t PM1ControlLength; - uint8_t PM2ControlLength; - uint8_t PMTimerLength; - uint8_t GPE0Length; - uint8_t GPE1Length; - uint8_t GPE1Base; - uint8_t CStateControl; - uint16_t WorstC2Latency; - uint16_t WorstC3Latency; - uint16_t FlushSize; - uint16_t FlushStride; - uint8_t DutyOffset; - uint8_t DutyWidth; - uint8_t DayAlarm; - uint8_t MonthAlarm; - uint8_t Century; - - // reserved in ACPI 1.0; used since ACPI 2.0+ - uint16_t BootArchitectureFlags; - - uint8_t Reserved2; - uint32_t Flags; - - // 12 byte structure; see below for details - GenericAddressStructure ResetReg; - - uint8_t ResetValue; - uint8_t Reserved3[3]; - - // 64bit pointers - Available on ACPI 2.0+ - uint64_t X_FirmwareControl; - uint64_t X_Dsdt; - - GenericAddressStructure X_PM1aEventBlock; - GenericAddressStructure X_PM1bEventBlock; - GenericAddressStructure X_PM1aControlBlock; - GenericAddressStructure X_PM1bControlBlock; - GenericAddressStructure X_PM2ControlBlock; - GenericAddressStructure X_PMTimerBlock; - GenericAddressStructure X_GPE0Block; - GenericAddressStructure X_GPE1Block; -} ACPI_FADT; - -// APIC headers -typedef struct { - uint8_t type; - uint8_t length; -} __attribute__((packed)) APICHeader; - -typedef struct { - APICHeader header; - uint8_t ACPIProcessorID; - uint8_t apicID; - uint32_t flags; -} __attribute__((packed)) APICLocal; - -typedef struct { - APICHeader header; - uint8_t ioAPIC_id; - uint8_t reserved; - uint32_t ioAPIC_addr; - uint32_t globalSystemInterruptBase; -} __attribute__((packed)) APICIO; - -typedef struct { - APICHeader header; - uint8_t bus; - uint8_t source; - uint32_t interrupt; - uint16_t flags; -} __attribute__((packed)) APICInterruptOverride; - -// RSDP (Root System Description Pointer) -// ACPI version 1.0 -typedef struct { - char signature[8]; - uint8_t checksum; - char OEMID[6]; - uint8_t revision; - uint32_t rsdtAddress; -} __attribute__((packed)) RSDPDescriptor; - -// ACPI version 2.0 -typedef struct { - RSDPDescriptor start; - uint32_t length; - uint64_t xsdtAddress; - uint8_t extendedChecksum; - uint8_t reserved[3]; -} __attribute__((packed)) RSDPDescriptor_v2; - -typedef struct { - ACPIHeader header; - uint32_t localAPIC_addr; - uint32_t flags; -} __attribute__((packed)) ACPI_MADT; - -// Definitions -#define APIC_TYPE_LOCAL_APIC 0 -#define APIC_TYPE_IO_APIC 1 -#define APIC_TYPE_INT_OVERRIDE 2 - - - -// External variables -extern uint8_t *localAPICAddress; -extern uint8_t *ioAPIC_addr; - - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/assert.h b/source/sysroot/usr/include/kernel/assert.h deleted file mode 100644 index c0b53b65..00000000 --- a/source/sysroot/usr/include/kernel/assert.h +++ /dev/null @@ -1,14 +0,0 @@ -// assert.h - contains the assertion macro - -#ifndef ASSERT_H -#define ASSERT_H - -// Includes -#include - -// Macros - -// ASSERT(b) - Makes sure b is a valid object before continuing. -#define ASSERT(b, caller, msg) ((b) ? (void)0 : panic("Assert", caller, msg)); - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/bios32.h b/source/sysroot/usr/include/kernel/bios32.h deleted file mode 100644 index 8457449a..00000000 --- a/source/sysroot/usr/include/kernel/bios32.h +++ /dev/null @@ -1,28 +0,0 @@ -// bios32.h - header file for bios32.c (handles BIOS calls in protected mode) - -#ifndef BIOS32_H -#define BIOS32_H - -// Includes -#include "include/libc/stdint.h" // Integer definitions -#include "include/gdt.h" // Global descriptor table -#include "include/idt.h" // Interrupt descriptor table -#include "include/regs.h" // Registers - -// External functions -extern void BIOS32_START(); -extern void BIOS32_END(); -extern void *bios32_gdt_ptr; -extern void *bios32_gdt_entries; -extern void *bios32_idt_ptr; -extern void *bios32_in_reg16_ptr; -extern void *bios32_out_reg16_ptr; -extern void *bios32_int_number_ptr; - -#define REBASE_ADDRESS(x) (void*)(0x7c00 + (void*)x - (uint32_t)BIOS32_START) - - -void bios32_init(); // Initializes BIOS32. -void bios32_call(uint8_t int_num, REGISTERS_16 *in_reg, REGISTERS_16 *out_reg); // Call the BIOS in protected mode. - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/bitmap.h b/source/sysroot/usr/include/kernel/bitmap.h deleted file mode 100644 index 324222ba..00000000 --- a/source/sysroot/usr/include/kernel/bitmap.h +++ /dev/null @@ -1,52 +0,0 @@ -// bitmap.h - Header file for bitmap drawer/parser -#ifndef BITMAP_H -#define BITMAP_H - -#include "libc/string.h" // String functions -#include "libc/stdint.h" // Integer types (uint32_t, ...) -#include "initrd.h" // Initial ramdisk support -#include "vesa.h" // VESA VBE support - -// Typedefs -typedef struct { - uint16_t type; - uint32_t size; - uint16_t reserved1; - uint16_t resreved2; - uint32_t offbits; -} __attribute__((packed)) bitmap_fileHeader_t; - -typedef struct { - uint32_t size; - long width; - long height; - uint16_t planes; - uint16_t bitcount; - uint32_t compression; - uint32_t sizeImage; - long XPelsPerMeter; - long YPelsPerMeter; - uint32_t clrUsed; - uint32_t clrImportant; -} bitmap_infoHeader_t; - -typedef struct { - uint32_t width; - uint32_t height; - char *imageBytes; - char *buffer; - uint32_t totalSize; - uint32_t bpp; -} bitmap_t; - -typedef struct { - uint8_t r; - uint8_t g; - uint8_t b; - uint8_t a; -} palette_t; - - -// Functions -bitmap_t *bitmap_loadBitmap(fsNode_t *node); // Loads the bitmap into memory and returns the bitmap_t object. -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/bootinfo.h b/source/sysroot/usr/include/kernel/bootinfo.h deleted file mode 100644 index 913666c1..00000000 --- a/source/sysroot/usr/include/kernel/bootinfo.h +++ /dev/null @@ -1,67 +0,0 @@ -// bootinfo.h - header file defining multiboot_info, the structure passed by loadkernel and kernel assembly files. -// All credit from this file goes to BrokenThorn Entertainment. - -#ifndef BOOTINFO_H -#define BOOTINFO_H - -#include "include/libc/stdint.h" // Definitions of integer types, like uint8_t - -#define MULTIBOOT_MAGIC 0x1BADB002 - - -typedef struct { - uint32_t tab_size; - uint32_t string_size; - uint32_t address; - uint32_t reserved; -} aoutSymbolTable_t; - -typedef struct { - uint32_t number; - uint32_t size; - uint32_t address; - uint32_t shndx; -} elfHeader_t; - -typedef struct { - uint32_t m_flags; // m_flags - Multiboot flags (useless without a multiboot bootloader like GRUB) - uint32_t m_memoryLo; // m_memoryLo - Low address of memory - uint32_t m_memoryHi; // m_memoryHi - High address of memory (usually 0) - uint32_t m_bootDevice; // m_bootDevice - Value BIOS passed - uint32_t m_cmdLine; // m_cmdLine - command used to boot OS - uint32_t m_modsCount; // m_modsCount - Amount of mods passed (used with initrd) - uint32_t m_modsAddr; // m_modsAddr - Address of mods passed (used with initrd) - union { - aoutSymbolTable_t aout_sym; - elfHeader_t elf_sec; - } u; - uint32_t m_mmap_length; // m_mmap_length - Length of memory map - uint32_t m_mmap_addr; // m_mmap_addr - Address of memory map - uint32_t m_drives_length; // m_drives_length - Length of drive - uint32_t m_drives_addr; // m_drives_addr - Address of drive - uint32_t m_config_table; // m_config_table - Unused - uint32_t m_bootloader_name; // m_bootloader_name - The name of the bootloader that loaded the kernel - uint32_t m_apm_table; // m_apm_table - APM information - uint32_t m_vbe_control_info; // m_vbe_control_info - VBE control info - uint32_t m_vbe_mode_info; // m_vbe_mode_info - VBE mode info - uint16_t m_vbe_mode; // m_vbe_mode - VBE mode - uint32_t m_vbe_interface_addr; // m_vbe_interface_addr - VBE interface address - uint16_t m_vbe_interface_len; // m_vbe_interface_len - VBE interface length - uint64_t framebuffer_addr; - uint32_t framebuffer_pitch; - uint32_t framebuffer_width; - uint32_t framebuffer_height; - uint8_t framebuffer_bpp; - uint8_t framebuffer_type; // indexed = 0, RGB = 1, EGA = 2 -} multiboot_info; - -typedef struct { - uint32_t mod_start; - uint32_t mod_end; - uint32_t cmdline; - uint32_t padding; -} multiboot_mod_t; - - -#endif - diff --git a/source/sysroot/usr/include/kernel/cmds.h b/source/sysroot/usr/include/kernel/cmds.h deleted file mode 100644 index 3172581f..00000000 --- a/source/sysroot/usr/include/kernel/cmds.h +++ /dev/null @@ -1,43 +0,0 @@ -// cmds.h - header file - -#ifndef CMDS_H -#define CMDS_H - -// Includes -#include "include/kernel.h" // Steal everything from the kernel includes file (very bad practice) - -// Functions -// I'm too tired to put them here, gcc will deal with it - - -int testISRException(int argc, char *args[]); -int getSystemInformation(int argc, char *args[]); -int echo(int argc, char *args[]); -int crash(int argc, char *args[]); -int pciInfo(int argc, char *args[]); -int getInitrdFiles(int argc, char *args[]); -int ataPoll(int argc, char *args[]); -int panicTest(int argc, char *args[]); -int readSectorTest(int argc, char *args[]); -int shutdown(int argc, char *args[]); -int memoryInfo(int argc, char *args[]); -int dump(int argc, char *args[]); -int about(int argc, char *args[]); -int color(int argc, char *args[]); -int doPageFault(int argc, char *args[]); -int read_floppy(int argc, char *args[]); - - -int mountFAT(int argc, char *args[]); -int ls(int argc, char *args[]); -int cd(int argc, char *args[]); -int cat(int argc, char *args[]); -int create(int argc, char *args[]); -int mkdir(int argc, char *args[]); -int pwd(int argc, char *args[]); -int show_bitmap(int argc, char *args[]); -int edit(int argc, char *args[]); - - - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/command.h b/source/sysroot/usr/include/kernel/command.h deleted file mode 100644 index b190d248..00000000 --- a/source/sysroot/usr/include/kernel/command.h +++ /dev/null @@ -1,29 +0,0 @@ -// command.h - Header file for the command parser (command.c) - -#ifndef COMMAND_H -#define COMMAND_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/libc/string.h" // String functions -#include "include/heap.h" // Memory allocation functions -#include "include/terminal.h" // printf() - -// Typedefs -typedef int command(int argc, char *args[]); // This is the command FUNCTION - the thing that is called on a command. - - -// The main command array uses cmdData. The reason we use cmdData instead of command is because we need the NAME of the command. -// Comparisons would be pretty hard without a command name. -typedef struct { - char *cmdName; - command *cmdFunc; -} cmdData; - - -// Functions -int parseCommand(char *cmd); -void registerCommand(char *name, command cmd); -void initCommandHandler(); - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/divdi3.h b/source/sysroot/usr/include/kernel/divdi3.h deleted file mode 100644 index 0b978a12..00000000 --- a/source/sysroot/usr/include/kernel/divdi3.h +++ /dev/null @@ -1,3 +0,0 @@ -// This file is here for compatibility reasons. -// If this is still here, give me a little ping in our discord: https://discord.gg/g5XwNxw3u5 -// Thanks for checking out my code! \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/dma.h b/source/sysroot/usr/include/kernel/dma.h deleted file mode 100644 index 2b124609..00000000 --- a/source/sysroot/usr/include/kernel/dma.h +++ /dev/null @@ -1,111 +0,0 @@ -// dma.h - header file for the direct memory access controller - -#ifndef DMA_H -#define DMA_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/hal.h" // Hardware Abstraction Layer - - -// Definitions - - -// Start address & count registers (slave) -#define DMA_SLAVE_STARTADDR0_REG 0x00 // (W) Start address register for channel 0 (unusable) -#define DMA_SLAVE_COUNT0_REG 0x01 // (W) Count register for channel 0 (unusable) -#define DMA_SLAVE_STARTADDR1_REG 0x02 // (W) Start address register for channel 1 -#define DMA_SLAVE_COUNT1_REG 0x03 // (W) Count register for channel 1 -#define DMA_SLAVE_STARTADDR2_REG 0x04 // (W) Start address register for channel 2 -#define DMA_SLAVE_COUNT2_REG 0x05 // (W) Count register for channel 2 -#define DMA_SLAVE_STARTADDR3_REG 0x06 // (W) Start address register for channel 3 -#define DMA_SLAVE_COUNT3_REG 0x07 // (W) Count register for channel 3 - - -// Start address & count registers (master) -#define DMA_MASTER_STARTADDR4_REG 0xC0 // (W) Start address register for channel 4 (unusable) -#define DMA_MASTER_COUNT4_REG 0xC2 // (W) Count register for channel 4 (unusable) -#define DMA_MASTER_STARTADDR5_REG 0xC4 // (W) Start address register for channel 5 -#define DMA_MASTER_COUNT5_REG 0xC6 // (W) Count register for channel 5 -#define DMA_MASTER_STARTADDR6_REG 0xC8 // (W) Start address register for channel 6 -#define DMA_MASTER_COUNT6_REG 0xCA // (W) Count register for channel 6 -#define DMA_MASTER_STARTADDR7_REG 0xCC // (W) Start address register for channel 7 -#define DMA_MASTER_COUNT7_REG 0xCE // (W) Count register for channel 7 - -// Other registers (slave) -#define DMA_SLAVE_STATUS_REG 0x08 // (R) Status register -#define DMA_SLAVE_COMMAND_REG 0x08 // (W) Command register -#define DMA_SLAVE_REQUEST_REG 0x09 // (W) Request register -#define DMA_SLAVE_MASKCHANNEL_REG 0x0A // (W) Single channel mask register -#define DMA_SLAVE_MODE_REG 0x0B // (W) Mode register -#define DMA_SLAVE_RESETFLOP_REG 0x0C // (W) Flip-flop reset register -#define DMA_SLAVE_INTERMED_REG 0x0D // (R) Intermediate register -#define DMA_SLAVE_RESETMASTER_REG 0x0D // (W) Master reset register -#define DMA_SLAVE_MASKRESET_REG 0x0E // (W) Mask reset register -#define DMA_SLAVE_MULTICHNL_REG 0x0F // (RW) Multichannel mask register - -// Other registers (MASTER) -#define DMA_MASTER_STATUS_REG 0x08 // (R) Status register -#define DMA_MASTER_COMMAND_REG 0x08 // (W) Command register -#define DMA_MASTER_REQUEST_REG 0x09 // (W) Request register -#define DMA_MASTER_MASKCHANNEL_REG 0x0A // (W) Single channel mask register -#define DMA_MASTER_MODE_REG 0x0B // (W) Mode register -#define DMA_MASTER_RESETFLOP_REG 0x0C // (W) Flip-flop reset register -#define DMA_MASTER_INTERMED_REG 0x0D // (R) Intermediate register -#define DMA_MASTER_RESETMASTER_REG 0x0D // (W) Master reset register -#define DMA_MASTER_MASKRESET_REG 0x0E // (W) Mask reset register -#define DMA_MASTER_MULTICHNL_REG 0x0F // (RW) Multichannel mask register - - -// Page access registers (contains upper 8 bits of the 24-bit transfer memory address) -#define DMA_CHNL0_PAGEACCESS_REG 0x87 -#define DMA_CHNL1_PAGEACCESS_REG 0x83 -#define DMA_CHNL2_PAGEACCESS_REG 0x81 -#define DMA_CHNL3_PAGEACCESS_REG 0x82 -#define DMA_CHNL4_PAGEACCESS_REG 0x8F -#define DMA_CHNL5_PAGEACCESS_REG 0x8B -#define DMA_CHNL6_PAGEACCESS_REG 0x89 -#define DMA_CHNL7_PAGEACCESS_REG 0x8A - - -// Command register bits (literally none of these work lmao) -#define DMA_CMD_MEMORYTOMEMORY 0x1 // Memory transfers, hardware framebuffering - doesn't work -#define DMA_CMD_ADDRHOLDCHNL0 0x2 // Holds the channel 0 address - doesn't work. -#define DMA_CMD_ENABLE 0x4 // Does actually work! Disables DMA controller if set -#define DMA_CMD_COMP 0x8 // Controls whether DMA timing is compressed - doesn't work. -#define DMA_CMD_PRIORITY 0x10 // Fixed/normal DMA priority - doesn't work. -#define DMA_CMD_EXTW 0x20 // Controls whether write selection is late/extended - doesn't work. -#define DMA_CMD_DROP 0x40 // DMA request sense control - doesn't work. -#define DMA_CMD_ACK 0x80 // DMA acknowledged - doesn't work. - -// Mode register bits (ugly bitmask but works) -#define DMA_MODE_SELECT_MASK 0x3 // Channel selection bits -#define DMA_MODE_TRANSFER_MASK 0xC // Transfer type -#define DMA_MODE_SELFTEST 0 // (transfer type) Tells the DMA controller to perform a self-test -#define DMA_MODE_READTRANSFER 4 // (transfer type) Tells the DMA controller to do a read transfer -#define DMA_MODE_WRITETRANSFER 8 // (transfer type) Tells the DMA controller to do a write transfer -#define DMA_MODE_AUTO_MASK 0x10 // Automatically reinitialize after transfer completion -#define DMA_MODE_IDEC_MASK 0x20 // Reverses the memory order of the data. -#define DMA_MODE_MASK 0xC0 // Actual DMA mode -#define DMA_MODE_TRANSFERONDEMAND 0 // (mode) Transfer on demand -#define DMA_MODE_SINGLETRANSFER 0x40 // (mode) Single DMA transfer -#define DMA_MODE_BLOCKTRANSFER 0x80 // (mode) Block transfer -#define DMA_MODE_CASCADETRANSFER 0xC0 // (mode) Cascading DMA chips - - -// Functions -void dma_setStartAddress(uint8_t channel, uint8_t addrLow, uint8_t addrHi); // Set the starting address for the DMA controller -void dma_setCount(uint8_t channnel, uint8_t countLow, uint8_t countHi); // Sets the channel count -void dma_setPageAccess(uint8_t channel, uint8_t addr); // Set the page access bits -void dma_disableDMAC(int port, bool disabled); // Disables a DMAC (probably doesn't even work) -void dma_maskChannel(uint8_t channel); // Masks a channel in the DMAC -void dma_unmaskChannel(uint8_t channel); // Unmasks a channel in the DMAC -void dma_resetFlipFlop(int dma); // Resets the DMA flip flop (b/n 16-bit transfers) -void dma_resetDMA(int dma); // Resets the DMAC -void dma_resetMask(int dma); // Resets the masks in the DMAC, unmasking all channels -void dma_setRead(uint8_t channel); // Puts a channel into read transfer mode -void dma_setWrite(uint8_t channel); // Puts a channel into write transfer mode -void dma_initPool(int pool_size); // Initialize a DMA pool of memory, that processes can pull from for their channels -void *dma_allocPool(size_t size); // Gets a chunk from the DMA pool. Note: This chunk is statutory! You cannot put it back! - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/ext2.h b/source/sysroot/usr/include/kernel/ext2.h deleted file mode 100644 index 48453bf9..00000000 --- a/source/sysroot/usr/include/kernel/ext2.h +++ /dev/null @@ -1,249 +0,0 @@ -// ext2.h - EXT2 filesystem driver header - -#ifndef EXT2_H -#define EXT2_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/vfs.h" - -// Typedefs - -// Extended superblock fields -typedef struct ext2_extended { - uint32_t non_reserved_inode; // First non-reserved inode in the system (version < 1.0 have it fixed as 11) - uint16_t inode_struct_size; // Size of each inode structure in bytes (version < 1.0 have it fixed as 128) - uint16_t blockgroup_superblock; // Block group that the superblock is part of - uint32_t optional_features; // See definitions for the bitmasks of this value - uint32_t required_features; // See definitions for the bitmasks of this value - uint32_t readonly_features; // Features that if not supported render the volume forced to be remounted R/O - uint8_t filesystem_id[16]; // ID of the filesystem - char volumeName[16]; // Null-terminated volume name - char lastPath[64]; // Null-terminated last path the volume was mounted to - uint32_t compression_algorithm; // Compression algorithm used - uint8_t prealloc_files; // Number of blocks to preallocate for the files - uint8_t prealloc_directories; // Number of blocks to preallocate for the directories - uint16_t unused; // Unused - uint8_t journal_id[16]; // Journal ID - uint32_t journal_inode; // Journal inode - uint32_t journal_device; // Journal device - uint32_t orphan_head; // Head of orphan inode list. - - char unused2[1024-236]; -} __attribute__((packed)) ext2_extended_t; - - -// Superblock structure -typedef struct ext2_superblock { - uint32_t total_inodes; // Total amount of inodes - uint32_t total_blocks; // Total amount of blocks - uint32_t superuser_reserved; // Total amount of blocks reserved for the superuser - uint32_t total_unallocated_blocks; // Total number of unallocated blocks. - uint32_t total_unallocated_inodes; // Total number of unallocated inodes - uint32_t superblock_number; // Block number of the block containing the superblock - uint32_t unshifted_block_size; // Unshifted block size - shift 1024 to the left (or log2(block size) - 10) - uint32_t unshifted_fragment_size; // Unshifted fragment size - shift 1024 to the left (or log2(fragment size) - 10) - uint32_t blockgroup_blocks; // Number of blocks in each block group. - uint32_t blockgroup_fragments; // Number of fragments in each block group. - uint32_t blockgroup_inodes; // Number of inodes in each block group - uint32_t last_mount_time; // Last mount time in POSIX time - uint32_t last_written_time; // Last written time in POSIX time - uint16_t mount_since_consistency; // Number of times the volume has been mounted since the last consistency check. - uint16_t mounts_before_check; // Number of mounts allowed before next consistency check. - uint16_t ext2_signature; // Signature of EXT2 (0xEF53) - uint16_t filesystem_state; // State of the filesystem - uint16_t error_method; // What to do upon error - uint16_t minor_version; // Minor portion of version - uint32_t last_consistency_check; // Last consistency check in POSIX time - uint32_t interval_check; // Interval between consistency checks - uint32_t creator_os_id; // Operating system ID of creator (see os_id) - uint32_t major_version; // Major portion of version - uint16_t reserved_userID; // User ID that can use reserved blocks - uint16_t reserved_groupID; // Group ID that can use reserved blocks - ext2_extended_t extension; // Extended superblock (mainly for ext3 and ext4, but has some good values) -} __attribute__((packed)) ext2_superblock_t; - - -// Block group descriptor -typedef struct ext2_bgd { - uint32_t block_usage_bitmap; // Block address of block usage bitmap - uint32_t inode_usage_bitmap; // Block address of inode usage bitmap - uint32_t inode_table; // Starting block address of inode table - uint16_t unallocated_blocks; // Number of unallocated blocks in groups - uint16_t unallocated_inodes; // Number of unallocated inodes in groups - uint16_t directories; // Number of directories in groups - uint16_t pad; - uint8_t reserved[12]; -} __attribute__((packed)) ext2_bgd_t; - -// Inode -typedef struct ext2_inode { - uint16_t permissions; // Types and permissions - uint16_t uid; // User ID - uint32_t size; // Lower 32 bits of size in bytes - uint32_t last_access; // Last access time (in POSIX time) - uint32_t creation_time; // Creation time (in POSIX time) - uint32_t last_modification; // Last modification time (in POSIX time) - uint32_t deletion_time; // Deletion time (in POSIX time) - uint16_t gid; // Group ID - uint16_t hard_links; // Count of dirents to this inode (0 = data blocks are unallocated) - uint32_t disk_sectors; // SECTORS in use by this inode - uint32_t flags; // Flags (see definitions) - uint32_t os_specific1; // OS-specific value - uint32_t blocks[15]; // DBPs and IBPs (12 direct blocks + 3 indirect blocks) - uint32_t generation; // Generation # (primarily NFS) - uint32_t extended_attr_block; // Extended attribute block ONLY IF version >= 1, else reserved. - union { - uint32_t dir_acl; // Used if version is not 0 and if inode is directory. - uint32_t size_high; // Used if version is not 0 and if inode is file. - }; - uint32_t fragment_block_addr; // Fragment block address - uint8_t os_specific2[12]; // OS-specific value -} __attribute__((packed)) ext2_inode_t; - -// Directory entry -typedef struct ext2_dirent { - uint32_t inode; // Inode # for the dirent - uint16_t entry_size; // Size of this entry - uint8_t name_length; // Least-significant 8 bytes of the name length - uint8_t type; // Type indicator (only if dirents have file type byte is set) - char name[]; // Directory name -} __attribute__((packed)) ext2_dirent_t; - - -// Cache structure -typedef struct ext2_cache { - uint32_t block; - uint32_t times; - uint8_t dirty; - char *block_data; -} __attribute__((packed)) ext2_cache_t; - -// Enums -typedef enum { - LINUX = 0, - GNU_HURD = 1, - MASIX = 2, - FREEBSD = 3, - OTHER = 4 -} os_id; - -typedef enum { - IGNORE = 1, // Ignore the error - REMOUNT_RO = 2, // Remount as R/O - PANIC = 3 // Kernel panic -} error_method; - -typedef enum { - CLEAN = 1, - ERROR = 2 -} fs_state; - - - -// Structure to help organize and manage the ext2 filesystem -typedef struct ext2 { - fsNode_t *drive; // ext2 drive - ext2_superblock_t *superblock; // Superblock structure - uint32_t block_size; // Block size - uint32_t blocks_per_group; // Blocks per group - uint32_t inodes_per_group; // Inodes per group - uint32_t total_groups; // Total groups - uint32_t bgd_blocks; // Block Group Descriptor blocks - ext2_bgd_t *bgd_list; // Block Group Descriptor list -} ext2_t; - -// Definitions - -// General -#define EXT2_SIGNATURE 0xEF53 -#define EXT2_DIRECT_BLOCKS 12 -#define EXT2_ROOT_INODE_NUMBER 2 - - -// Filesystem states -#define EXT2_FS_CLEAN 1 -#define EXT2_FS_ERROR 2 - -// Optional feature flags (bitmask) -#define EXT2_PREALLOCATE_BLOCKS 0x0001 // Preallocate some amount of blocks to a directory when creating a new one -#define EXT2_AFS_SERVER_INODES 0x0002 // AFS server inodes exist -#define EXT2_JOURNAL_EXISTS 0x0004 // Filesystem has a journal (ext3) -#define EXT2_INODES_EXTENDED 0x0008 // Inodes can have extended attributes -#define EXT2_FS_RESIZE 0x0010 // Filesystem can resize itself for larger partitions -#define EXT2_DIRS_USE_HASH_INDEX 0x0020 // Directories use hash index - -// Required feature flags (bitmask) -#define EXT2_COMPRESSION_USED 0x0001 // Compression is used -#define EXT2_DIRECTORIES_TYPEFIELD 0x0002 // Directory entries contain a type field -#define EXT2_FS_REPLAY_JOURNAL 0x0004 // Filesystem needs to replay its journal -#define EXT2_FS_JOURNAL_DEVICE 0x0008 // Filesystem uses a journal device - -// Read-only feature flags -#define EXT2_SPARSE_SUPERBLKS_GROUPD 0x0001 // Sparse superblocks and group descriptor tables -#define EXT2_FILESIZE_64BIT 0x0002 // Filesystem uses a 64-bit file size -#define EXT2_DIR_BINARYTREE 0x0004 // Directory contents are stroed as a binary tree - -// Inode types -#define EXT2_INODE_FIFO 0x1000 // FIFO -#define EXT2_INODE_CHARDEV 0x2000 // Character device -#define EXT2_INODE_DIRECTORY 0x4000 // Directory -#define EXT2_INODE_BLKDEVICE 0x6000 // Block device -#define EXT2_INODE_FILE 0x8000 // Regular old file -#define EXT2_INODE_SYMLINK 0xA000 // Symbolic link -#define EXT2_INODE_SOCKET 0xC000 // Unix socket - -// Inode permissions -#define EXT2_PERM_OX 0x001 // Other execute -#define EXT2_PERM_OW 0x002 // Other write -#define EXT2_PERM_OR 0x004 // Other read -#define EXT2_PERM_GX 0x008 // Group execute -#define EXT2_PERM_GW 0x010 // Group write -#define EXT2_PERM_GR 0x020 // Group read -#define EXT2_PERM_UX 0x040 // User execute -#define EXT2_PERM_UW 0x080 // User write -#define EXT2_PERM_UR 0x100 // User read -#define EXT2_PERM_STICKY 0x200 // Sticky bit -#define EXT2_PERM_SETGID 0x400 // Set group ID -#define EXT2_PERM_SETUID 0x800 // Set user ID - -// Inode flags (only ones needed) -#define EXT2_INODE_SYNCUPD 0x00000008 // Syncronous updates - new data written immediately to disk -#define EXT2_INODE_IMMUTABLE 0x00000010 // Immutable file -#define EXT2_INODE_APPEND 0x00000020 // Append only -#define EXT2_INODE_NODUMP 0x00000040 // File is not included in the 'dump' command -#define EXT2_INODE_NOUPDACCESS 0x00000080 // Last accessed time should not be updated -#define EXT2_INODE_HASHIDX 0x00010000 // Hash indexed directory -#define EXT2_INODE_AFS 0x00020000 // AFS directory -#define EXT2_INODE_JOURNALDATA 0x00040000 // Journal file data - -// Macros (for using BGDs) -#define BLOCKBIT(n) (bg_buffer[((n) >> 3)] & (1 << (((n) % 8)))) -#define BLOCKBYTE(n) (bg_buffer[((n) >> 3)]) -#define SETBIT(n) (1 << (((n) % 8))) - - -// Functions -int ext2_readBlock(ext2_t *fs, uint32_t block, uint8_t *buf); // Read a block from the device -int ext2_writeBlock(ext2_t *fs, uint32_t block, uint8_t *buf); // Write a block to the device -int ext2_readInodeBlock(ext2_t *fs, ext2_inode_t *inode, uint32_t inodeBlock, uint8_t *buffer); // Reads a block in the specified inode -uint32_t ext2_writeInodeBlock(ext2_t *fs, ext2_inode_t *inode, uint32_t inodeBlock, uint32_t block, uint8_t *buffer); // Writes a block in the specified inode -uint32_t ext2_allocateBlock(ext2_t *fs); // Allocate a block from the ext2 block bitmaps -void ext2_freeBlock(ext2_t *fs, uint32_t block); // Frees a block from the ext2 block bitmaps -void ext2_rewriteBGDs(ext2_t *fs); // Rewrite the block group descriptors -ext2_superblock_t *ext2_readSuperblock(fsNode_t *device); // Reads and returns the superblock for a drive -int ext2_writeSuperBlock(ext2_t *fs); // Rewrites the superblock according to the superblock currently on the strutcure -ext2_inode_t *ext2_readInodeMetadata(ext2_t *fs, uint32_t inode); // Given an inode number, find the inode on the disk and read it -int ext2_writeInodeMetadata(ext2_t *fs, ext2_inode_t *inode, uint32_t index); // Write an inode metadata at an index -uint32_t ext2_getDiskBlockNumber(ext2_t *fs, ext2_inode_t *inode, uint32_t inodeBlock); // Gets the actual index of inodeBlock on the disk -uint32_t ext2_readInodeFiledata(ext2_t *fs, ext2_inode_t *inode, uint32_t offset, uint32_t size, uint8_t *buffer); // Read the actual file data referenced from the inode -void ext2_allocateInodeBlock(ext2_t *fs, ext2_inode_t *inode, uint32_t index, uint32_t block); // Allocate an inode block -void ext2_freeInodeBlock(ext2_t *fs, ext2_inode_t *inode, uint32_t index, uint32_t block); // Free an inode block -uint32_t ext2_allocateInode(ext2_t *fs); // Allocate an inode from the inode bitmap -void ext2_freeInode(ext2_t *fs, uint32_t inode); // Frees an inode from the inode bitmap -fsNode_t *ext2_finddir(fsNode_t *node, char *name); // Returns NULL if file exists, and the node for the file if it does -int ext2_fileToNode(ext2_t *fs, ext2_dirent_t *dirent, ext2_inode_t *inode, fsNode_t *ret); -int ext2_install(int argc, char *argv[]); // Installs the EXT2 filesystem driver to automatically initialize when a disk is detected - - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/fat.h b/source/sysroot/usr/include/kernel/fat.h deleted file mode 100644 index 398fa7e7..00000000 --- a/source/sysroot/usr/include/kernel/fat.h +++ /dev/null @@ -1,129 +0,0 @@ -// fat.h - include file for FAT - -#include "include/libc/stdint.h" // Integer definitions (uint32_t, ...) -#include "include/libc/string.h" // String functions -#include "include/vfs.h" // Virtual File System -#include "include/ide_ata.h" // IDE ATA driver - -// Typedefs - - -typedef struct { - uint32_t tableSize32; // Sectors per FAT, I think. - uint16_t extendedFlags; - uint16_t fatVersion; // OSDev wiki says "FAT drivers should respect this field". Yeah, about that. - uint32_t rootCluster; // Cluster of the root directory (often 2) - uint16_t fatInfo; // FAT32's FSInfo structure sector number - uint16_t backupSector; // Backup boot sector - uint8_t reserved[12]; - uint8_t driveNum; - uint8_t reserved2; - uint8_t bootSignature; - uint32_t volumeID; - uint8_t volumeLabel[11]; - uint8_t fatTypeLabel[8]; -} __attribute__((packed)) fat_extendedBPB32_t; - -typedef struct { - // FAT12 and FAT16 extended BPB - uint8_t biosDriveNum; - uint8_t reserved; - uint8_t bootSignature; - uint32_t volumeId; - uint8_t volumeLabel[11]; - uint8_t fatTypeLabel[8]; -} __attribute__((packed)) fat_extendedBPB16_t; - -typedef struct { - // FSInfo structure, only for FAT32 - uint32_t signature; // Should be 0x41615252 - uint8_t reserved[480]; // Whoa. That's a lot of reserved bytes! - uint32_t signature2; // Should be 0x614177272 - uint32_t freeClusterCount; // LAST KNOWN free cluster count. Needs to be recomputed if 0xFFFFFFFF, and also should be range checked (<= volume cluster count) - uint32_t availableClusterStart; // Available cluster start. If the value is 0xFFFFFFFF, there is no hint and we should do everything ourselves. - uint8_t reserved2[12]; // More reserved bytes - uint32_t signature3; // The THIRD signature, should be 0xAA550000 -} __attribute__((packed)) fat_fsInfo_t; - -typedef struct { - uint8_t bootjmp[3]; - uint8_t oemName[8]; - uint16_t bytesPerSector; - uint8_t sectorsPerCluster; - uint16_t reservedSectorCount; - uint8_t tableCount; - uint16_t rootEntryCount; - uint16_t totalSectors16; // If this is zero, there are more than 65535 sectors (actual count is stored in totalSectors32) - uint8_t mediaType; - uint16_t tableSize16; // Sectors per FAT for FAT12/FAT16 - uint16_t sectorsPerTrack; - uint16_t headSideCount; - uint32_t hiddenSectorCount; - uint32_t totalSectors32; // Total count of sectors (if greater than 65535) - uint8_t extended[54]; // Will be typecast depending on FAT type -} __attribute__((packed)) fat_BPB_t; - - - -// This structure is referenced in the VFS impl_struct flag, and allocated a specific amount of memory. -// This is probably a very bad idea, but it does help cleanup code slightly. -typedef struct { - fsNode_t *driveobj; - int fatType; // 0 - exFAT, 1 - FAT12, 2 - FAT16, 3 - FAT32 - int totalSectors; // Calculated in fatInit - int fatSize; // Calculated in fatInit - int rootDirSectors; // Calculated in fatInit - int dataSectors; // Calculated in fatInit - int totalClusters; // Calculated in fatInit - int firstDataSector; // Calculated in fatInit - int firstFatSector; // Calculated in fatInit - int rootOffset; // Calculated in fatInit - fat_BPB_t *bpb; // BPB in the FAT - fat_extendedBPB16_t *extended16; // Is there a more memory-efficient way to do this? - fat_extendedBPB32_t *extended32; - fat_fsInfo_t *fsInfo; -} __attribute__((packed)) fat_drive_t; - -typedef struct { - uint8_t fileName[11]; - uint8_t attributes; - uint8_t reserved; - uint8_t creationTime_tenths; // Tenths of a second - uint16_t creationTime; // Hour = 5 bits, Minutes = 6 bits, Seconds = 5 bits - multiply seconds by 2. - uint16_t creationDate; // Year = 7 bits, Month = 4 bits, Day = 5 bits - uint16_t lastAccessDate; // Year = 7 bits, Month = 4 bits, Day = 5 bits. - uint16_t firstClusterNumber; // High 16 bits of the entry first cluster number. Always 0 for FAT12 and FAT16 - uint16_t lastModificationTime; // Same format as creationTime - uint16_t lastModificationDate; // Same format as creationDate - uint16_t firstClusterNumberLow; // Low 16 bits of the entry's first cluster number (used to find the first cluster). - uint32_t size; // Size of the file in bytes -} __attribute__((packed)) fat_fileEntry_t; - -typedef struct { - uint8_t entryOrder; - uint8_t firstChars[10]; - uint8_t attribute; // Always 0x0F - uint8_t longEntryType; // Zero for name entries. - uint8_t checksum; // Checksum of the short file name. - uint8_t secondChars[12]; - uint8_t reserved[2]; - uint8_t thirdChars[4]; -} __attribute__((packed)) fat_lfnEntry_t; - -// This will be what's in impl_struct, it contains information about the filesystem and the drive object -typedef struct { - fat_fileEntry_t *fileEntry; // Used if this is a structure for a file - fat_drive_t *drive; -} fat_t; - -// Functions - -fsNode_t *fatInit(fsNode_t *driveNode, int flags); -uint32_t fatOpen(struct fsNode *node); -uint32_t fatRead(struct fsNode *node, uint32_t off, uint32_t size, uint8_t *buf); -uint32_t fatClose(struct fsNode *node); -uint32_t fatWrite(struct fsNode *node, uint32_t off, uint32_t size, uint8_t *buf); -int fat_install(int argc, char *argv[]); // Installs the FAT filesystem driver - -fsNode_t *fatOpenInternal(fsNode_t *driver, char *filename); -int fatReadInternal(fsNode_t *file, uint8_t *buffer, uint32_t length); \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/floppy.h b/source/sysroot/usr/include/kernel/floppy.h deleted file mode 100644 index 330bc430..00000000 --- a/source/sysroot/usr/include/kernel/floppy.h +++ /dev/null @@ -1,117 +0,0 @@ -// floppy.h - Header file for the floppy driver - -#ifndef FLOPPY_H -#define FLOPPY_H - -// Includes -#include "include/libc/stdint.h" // Integer definitions -#include "include/hal.h" // Hardware Abstraction Layer -#include "include/dma.h" // Direct Memory Addressing (floppies CAN use PIO mode to transfer, but its better to do ISA DMA) - -// Definitions (note: not gonna even bother with 5.25-inch drives, sticking with 3.5-inch) -#define FLOPPY_HEADS 2 -#define FLOPPY_144MB_CYLINDERS 80 -#define FLOPPY_144MB_SECTORS_PER_TRACK 18 - -#define FLOPPY_IRQ 6 -#define FLOPPY_DMA_CHANNEL 2 - - -// Floppy registers -#define FLOPPY_STATUS_A 0x3F0 // (read-only) Status register A -#define FLOPPY_STATUS_B 0x3F1 // (read-only) Status register B -#define FLOPPY_DIGITALOUTPUT 0x3F2 // Digital output registers -#define FLOPPY_TAPEDRIVE 0x3F3 // Tape drive -#define FLOPPY_MAINSTATUS 0x3F4 // (read-only) MSR -#define FLOPPY_DATARATE_SEL 0x3F4 // (write-only) Data rate selection -#define FLOPPY_DATA_FIFO 0x3F5 // Data FIFO buffer -#define FLOPPY_DIGITALINPUT 0x3F7 // (read-only) Digital input register -#define FLOPPY_CONFIGCTRL 0x3F7 // (write-only) Config control register - -// Digital Output bitflags -#define FLOPPY_DIGITALOUTPUT_MOTOR3 0x80 // Turns on drive 3's motor -#define FLOPPY_DIGITALOUTPUT_MOTOR2 0x40 // Turns on drive 2's motor -#define FLOPPY_DIGITALOUTPUT_MOTOR1 0x20 // Turns on drive 1's motor -#define FLOPPY_DIGITALOUTPUT_MOTOR0 0x10 // Turns on drive 0's motor -#define FLOPPY_DIGITALOUTPUT_IRQ 0x8 // Enables IRQs and DMA -#define FLOPPY_DIGITALOUTPUT_RESET 0x4 // If cleared, enter reset mode. Else, normal operation -#define FLOPPY_DIGITALOUTPUT_DRIVESEL01 0x3 // Select drive number for next access - -// MSR bitflags -#define FLOPPY_MSR_RQM 0x80 // OK to exchange bytes with FIFO IO port? -#define FLOPPY_MSR_DIO 0x40 // Does the FIFO IO port expect an IN opcode? -#define FLOPPY_MSR_NDMA 0x20 // Set in execution phase of PIO mode read/write commands only -#define FLOPPY_MSR_CB 0x10 // Command Busy -#define FLOPPY_MSR_SEEK3 0x8 // Drive 3 is seeking -#define FLOPPY_MSR_SEEK2 0x4 // Drive 2 is seeking -#define FLOPPY_MSR_SEEK1 0x2 // Drive 1 is seeking -#define FLOPPY_MSR_SEEK0 0x1 // Drive 0 is seeking - -// Floppy commands (written to the DATA_FIFO) -#define FLOPPY_CMD_READTRACK 2 // (generates IRQ6) -#define FLOPPY_CMD_SPECIFY 3 // Set drive parameters -#define FLOPPY_CMD_SENSESTATUS 4 // Check the drive status -#define FLOPPY_CMD_WRITEDATA 5 // Write data -#define FLOPPY_CMD_READDATA 6 // Read data -#define FLOPPY_CMD_RECALIBRATE 7 // Seeks to cylinder 0 -#define FLOPPY_CMD_SENSEINT 8 // Acknowledge IRQ6, get the status of the last command. -#define FLOPPY_CMD_WRITEDELETED 9 // TBD -#define FLOPPY_CMD_READID 10 // (generates IRQ6) -#define FLOPPY_CMD_READDELETED 12 // TBD -#define FLOPPY_CMD_TRACKFORMAT 13 // Format a track -#define FLOPPY_CMD_DUMPREG 14 // TBD -#define FLOPPY_CMD_SEEK 15 // Seek both heads to cylinder X -#define FLOPPY_CMD_VERSION 16 // Get the floppy controller version -#define FLOPPY_CMD_SCANEQ 17 // TBD -#define FLOPPY_CMD_PERPENDICULAR 18 // Turn on/off perpendicular mode(?) -#define FLOPPY_CMD_CONFIGURE 19 // Set controller parameters -#define FLOPPY_CMD_LOCK 20 // Prevent controller parameters from resetting -#define FLOPPY_CMD_VERIFY 22 // TBD -#define FLOPPY_CMD_SCANLOE 25 // TBD -#define FLOPPY_CMD_SCANHOE 29 // TBD - -// Extended command bitmasks -#define FLOPPY_CMD_EXT_SKIP 0x20 // Skip deleted data address marks -#define FLOPPY_CMD_EXT_DENSITY 0x40 // Operate in FM (single density) or MFM (double density) mode -#define FLOPPY_CMD_EXT_MULTITRACK 0x80 // Operate on one track or both tracks of the cylinder - - -// GAP 3 (gap length - space b/n sectors on the disk) -#define FLOPPY_GAP3_STD 42 // tbd, i can't read documentation -#define FLOPPY_GAP3_3_5 27 // 3.5" drives - -// When sending commands to the FDC, they must follow a specific formula: 2 ^ n * 128 -// According to the documentation, some drives support reading up to 16KB per sector, but most don't, so we'll use a list of the most common -#define FLOPPY_BPS_128 0 // 128 bytes per sector -#define FLOPPY_BPS_256 1 // 256 bytes per sector -#define FLOPPY_BPS_512 2 // 512 bytes per sector -#define FLOPPY_BPS_1024 3 // 1024 bytes per sector - -// Error codes floppyReadSector might return. -#define FLOPPY_OK 0 -#define FLOPPY_ERROR -1 -#define FLOPPY_INVALID_CMD -2 -#define FLOPPY_DRIVE_NOT_READY -3 -#define FLOPPY_SEEK_FAIL -4 -#define FLOPPY_DRIVE_READ_ONLY -5 - -// Functions -void floppy_init(); // Initialize the floppy drive -void floppy_reset(); // Resets the floppy drive -void floppy_disableFDC(); // Disables the FDC -void floppy_enableFDC(); // Enables the FDC -int floppy_seek(uint32_t cylinder, uint32_t head); // Seek a floppy drive's head to a cylinder -int floppy_calibrateDrive(uint32_t drive); // Calibrate a floppy drive -void floppy_setDrive(uint8_t drive); // Set the current drive -void floppy_driveData(uint32_t steprate, uint32_t loadtime, uint32_t unloadtime, bool isDMA); // Passes control info to the FDC about the drive -int floppy_readSectorInternal(uint8_t head, uint8_t track, uint8_t sector); // Read a sector (internal use, should be static but eh) -void floppy_dmaInit(uint8_t *buffer, size_t length); // Initialize the floppy drive for DMA -void floppy_stopMotor(); // Stop the floppy motor -void floppy_startMotor(uint8_t drive); // Start the motor on a drive -void floppy_IRQ(); // Called when floppy IRQ is present -void floppy_waitIRQ(); // Waits for an IRQ, then resets the value -void floppy_acknowledgeIRQ(uint32_t *st0, uint32_t *cyl); // Acknowledges to the FDC an interrupt was received -int floppy_readSector(int lba, uint8_t *buffer); // Read a sector from the floppy disk. - - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/font.h b/source/sysroot/usr/include/kernel/font.h deleted file mode 100644 index 7856ac67..00000000 --- a/source/sysroot/usr/include/kernel/font.h +++ /dev/null @@ -1,72 +0,0 @@ -// font.h - header file for the reduceOS font parser - -#ifndef FONT_H -#define FONT_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/libc/limits.h" // Limits. -#include "include/heap.h" // Allocation functions. -#include "include/vesa.h" // VESA VBE drawing -#include "include/font_data.h" // Font data -#include "include/terminal.h" - - -/* Note: PSF stands for 'PC Screen Font', the font used by Linux for its console */ -// Definitions - -#define PSF2_MAGIC 0x864AB572 - - -// Typedefs - -typedef struct { - uint32_t magic; // Magic bytes for identification. - uint32_t version; // Should always be zero. - uint32_t header_size; // Offset of bitmaps in file. - uint32_t flags; // 0 without a unicode table. - uint32_t glyphs; // Number of glyphs - uint32_t bytesPerGlyph; // Size of each glyph. - uint32_t height; // Height of glyph in pixels. - uint32_t width; // Width of glyph in pixels. -} PSF2_Header; - - -typedef struct { - uint8_t magic[2]; // Magic bytes for idnetiifcation. - uint8_t fontMode; // PSF font mode - uint8_t characterSize; // PSF character size. -} PSF1_Header; - - -// Definitions - -// PSF 1 definitions -#define PSF1_MODE512 0x01 -#define PSF1_MODEHASTAB 0x02 -#define PSF1_MODEHASSEQ 0x04 -#define PSF1_MAXMODE 0x05 - -#define PSF1_SEPARATOR 0xFFFF -#define PSF1_STARTSEQ 0xFFFE - -// PSF 2 definitions -#define PSF2_HAS_UNICODE_TABLE 0x01 // Flag bit. - -#define PSF2_MAXVERSION 0 // Maximum version - -#define PSF2_SEPARATOR 0xFF -#define PSF2_STARTSEQ 0xFE - - -// Functions -void bitmapFontInit(); // Initializes bitmap font reading with the default font found in font_data.c -void bitmapLoadFont(uint32_t *font_data); // Loads a a new font for the bitmap. -void bitmapFontDrawChar(char ch, int x, int y, int color); // Puts a character of color 'color' at x, y -void bitmapFontDrawString(char *str, int x, int y, int color); // Draw a string from the bitmap -void psfInit(); // Initializes the default PSF font for reduceOS. -int psfGetFontWidth(); // Get PSF font width -int psfGetFontHeight(); // Get PSF font eheight -void psfDrawChar(unsigned short int c, int cx, int cy, uint32_t fg, uint32_t bg); // Draw a PC screen font character. - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/font_data.h b/source/sysroot/usr/include/kernel/font_data.h deleted file mode 100644 index e6e02bd0..00000000 --- a/source/sysroot/usr/include/kernel/font_data.h +++ /dev/null @@ -1,13 +0,0 @@ -// font_data.h - Utility file containing bitmap font data. - -#ifndef FONT_DATA_H -#define FONT_DATA_H - -// Includes -#include "include/libc/stdint.h" - -// Variables -extern uint32_t font_data[127][20]; - - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/gdt.h b/source/sysroot/usr/include/kernel/gdt.h deleted file mode 100644 index be46a45a..00000000 --- a/source/sysroot/usr/include/kernel/gdt.h +++ /dev/null @@ -1,44 +0,0 @@ -// gdt.h - header file for the global descriptor table. - -#ifndef GDT_H -#define GDT_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/terminal.h" // printf -#include "include/libc/assert.h" // ASSERT() macro -#include "include/tss.h" // Task State Segment - -// Definitions -#define MAX_DESCRIPTORS 8 - -// Typedefs - -// gdtEntry - defines one GDT entry. -struct gdtEntry_struct { - uint16_t limitLow; // Lower 16-bits of the limit - uint16_t baseLow; // Lower 16 bits of the base. - uint8_t baseMiddle; // Next 8 bits of the base - uint8_t access; // Access flags (determine what ring the segment can be used in) - uint8_t granularity; - uint8_t baseHigh; // Last 8 bits of the base. -} __attribute__((packed)); - -typedef struct gdtEntry_struct gdtEntry_t; - -// gdtPtr - defined a GDT pointer (points to start of array of GDT etnries) -struct gdtPtr_struct { - uint16_t limit; // Upper 16 bits of all selector limits - uint32_t base; // Address of the 1st gdtEntry_t struct. -} __attribute__((packed)); - -typedef struct gdtPtr_struct gdtPtr_t; - -// External functions -extern void install_gdt(uint32_t); - -// Functions -void gdtSetGate(int32_t num, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran); // Set the value of 1 GDT entry. -void gdtInit(); // Installs the GDT ptr and sets up all the registers - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/gfx.h b/source/sysroot/usr/include/kernel/gfx.h deleted file mode 100644 index c63872b3..00000000 --- a/source/sysroot/usr/include/kernel/gfx.h +++ /dev/null @@ -1,14 +0,0 @@ -// gfx.h - header file for the graphics handler - -#ifndef GFX_H -#define GFX_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/vesa.h" // VESA VBE functions - -// Functions -void gfxDrawRect(int x1, int y1, int x2, int y2, uint32_t color, bool fill); // Draws a rectangle -void gfxDrawLine(int x1, int y1, int x2, int y2, uint32_t color); // Draw a line. - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/graphics.h b/source/sysroot/usr/include/kernel/graphics.h deleted file mode 100644 index cbdf5962..00000000 --- a/source/sysroot/usr/include/kernel/graphics.h +++ /dev/null @@ -1,46 +0,0 @@ -// graphics.h - Header file for graphics.c -// Note that graphics.c and terminal.c are different. One houses the main code for anything graphics related(drawing, colors, etc) and the other handles console output and misc. other functions. -#ifndef GRAPHICS_H -#define GRAPHICS_H - -#include "include/libc/stdint.h" // Integer declarations -#include "include/libc/stdbool.h" // Boolean declarations -#include "include/libc/stddef.h" // size_t declaration -#include "include/libc/string.h" // String functions - - -// Basic graphics definitions, like the video memory address -static uint16_t* const VIDEO_MEM = (uint16_t*) 0xB8000; -static size_t SCREEN_WIDTH = 80; -static size_t SCREEN_HEIGHT = 25; - -// Color enumerator. -enum gfxColor { - COLOR_BLACK = 0, - COLOR_BLUE = 1, - COLOR_GREEN = 2, - COLOR_CYAN = 3, - COLOR_RED = 4, - COLOR_MAGENTA = 5, - COLOR_BROWN = 6, - COLOR_LIGHT_GRAY = 7, - COLOR_DARK_GRAY = 8, - COLOR_LIGHT_BLUE = 9, - COLOR_LIGHT_GREEN = 10, - COLOR_LIGHT_CYAN = 11, - COLOR_LIGHT_RED = 12, - COLOR_LIGHT_MAGENTA = 13, - COLOR_YELLOW = 14, - COLOR_WHITE = 15 -}; - -// vgaEntry() - Functions returns a valid VGA character entry. -// Parameters: unsigned char uc and uint8_t color -static inline uint16_t vgaEntry(unsigned char uc, uint8_t color) { return (uint16_t) uc | (uint16_t) color << 8; } - -// vgaColorEntry() - Function returns a valid VGA color entry. -// Parameters: Two gfxColor enums, foreground color and background color -static inline uint8_t vgaColorEntry(enum gfxColor foreground, enum gfxColor background) { return foreground | background << 4; } - - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/hal.h b/source/sysroot/usr/include/kernel/hal.h deleted file mode 100644 index cd0cef46..00000000 --- a/source/sysroot/usr/include/kernel/hal.h +++ /dev/null @@ -1,35 +0,0 @@ -// hal.h - Header file for the HAL.c file (Hardware Abstraction Layer) - -#ifndef HAL_H -#define HAL_H - - -// Includes -#include "include/idt.h" // Interrupt Descriptor Table -#include "include/pic.h" // Programmable Interrupt Controller -#include "include/pit.h" // Programmable interval Timer -#include "include/libc/stdint.h" // Integer declarations (like uint8_t, uint16_t, etc..) -#include "include/libc/stddef.h" // size_t declaration - -// Definitions - -#define far -#define near - -// Functions - -void setVector(int intNo, uint32_t vect); // Sets a new interrupt vector. -void interruptCompleted(uint32_t intNo); // Notifies HAL interrupt is done. -void enableHardwareInterrupts(); // Enable hardware interrupts -void disableHardwareInterrupts(); // Disable hardware interrupts -uint8_t inportb(uint16_t port); // Read data from a device using port mapped IO -void outportb(uint16_t port, uint8_t value); // Write data to a device using port mapped IO -uint16_t inportw(uint16_t port); // Read data from a device using port mapped IO -void outportw(uint16_t port, uint16_t data); // Write data to a device using port mapped IO -void __cpuid(uint32_t type, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx); // Returns an assembly cpuid instruction. -uint32_t inportl(uint16_t port); // Read data from a device via port mapped IO -void outportl(uint16_t port, uint32_t data); // Write data to a device via port mapped IO -size_t msb(size_t i); // Returns the most significant bit. -void setVector_flags(int intNo, uint32_t vect, int flags); // Sets a new interrupt vector using flags. - -#endif diff --git a/source/sysroot/usr/include/kernel/hashmap.h b/source/sysroot/usr/include/kernel/hashmap.h deleted file mode 100644 index 2ba2fa72..00000000 --- a/source/sysroot/usr/include/kernel/hashmap.h +++ /dev/null @@ -1,42 +0,0 @@ -// hashmap.h - Authored by klange, I deserve no credit. License information in misc/hashmap.c - -#include -#include "include/libc/string.h" -#include "include/list.h" - - -typedef unsigned int (*hashmap_hash_t) (const void * key); -typedef int (*hashmap_comp_t) (const void * a, const void * b); -typedef void (*hashmap_free_t) (void *); -typedef void * (*hashmap_dupe_t) (const void *); - -typedef struct hashmap_entry { - char * key; - void * value; - struct hashmap_entry * next; -} hashmap_entry_t; - -typedef struct hashmap { - hashmap_hash_t hash_func; - hashmap_comp_t hash_comp; - hashmap_dupe_t hash_key_dup; - hashmap_free_t hash_key_free; - hashmap_free_t hash_val_free; - size_t size; - hashmap_entry_t ** entries; -} hashmap_t; - -extern hashmap_t * hashmap_create(int size); -extern hashmap_t * hashmap_create_int(int size); -extern void * hashmap_set(hashmap_t * map, const void * key, void * value); -extern void * hashmap_get(hashmap_t * map, const void * key); -extern void * hashmap_remove(hashmap_t * map, const void * key); -extern int hashmap_has(hashmap_t * map, const void * key); -extern list_t * hashmap_keys(hashmap_t * map); -extern list_t * hashmap_values(hashmap_t * map); -extern void hashmap_free(hashmap_t * map); - -extern unsigned int hashmap_string_hash(const void * key); -extern int hashmap_string_comp(const void * a, const void * b); -extern void * hashmap_string_dupe(const void * key); -extern int hashmap_is_empty(hashmap_t * map); \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/heap.h b/source/sysroot/usr/include/kernel/heap.h deleted file mode 100644 index f96e778b..00000000 --- a/source/sysroot/usr/include/kernel/heap.h +++ /dev/null @@ -1,2 +0,0 @@ -// heap.h - Kept for legacy code compatibility, will be removed. -#include "include/liballoc_forwarder.h" diff --git a/source/sysroot/usr/include/kernel/ide_ata.h b/source/sysroot/usr/include/kernel/ide_ata.h deleted file mode 100644 index af38deac..00000000 --- a/source/sysroot/usr/include/kernel/ide_ata.h +++ /dev/null @@ -1,149 +0,0 @@ -// ide_ata.h - header file for the PCI IDE controller - -#ifndef IDE_ATA__H -#define IDE_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/hal.h" // Hardware abstraction layer -#include "include/isr.h" // IRQ handling -#include "include/vfs.h" // Virtual File System -#include "include/libc/sleep.h" // Sleep function - - -// Definitions - -// Status port bit masks -#define ATA_STATUS_BSY 0x80 // Busy -#define ATA_STATUS_DRDY 0x40 // Drive ready -#define ATA_STATUS_DF 0x20 // Drive write fault -#define ATA_STATUS_DSC 0x10 // Drive seek complete -#define ATA_STATUS_DRQ 0x08 // Data request ready -#define ATA_STATUS_CORR 0x04 // Corrected data -#define ATA_STATUS_IDX 0x02 // Index -#define ATA_STATUS_ERR 0x01 // Error - - -// Error register bits -#define ERR_AMNF 0x01 // Address mark not found. -#define ERR_TKZNF 0x02 // Track zero not found. -#define ERR_ABRT 0x04 // Aborted command. -#define ERR_MCR 0x08 // Media change request. -#define ERR_IDNF 0x10 // ID not found -#define ERR_MC 0x20 // Media changed. -#define ERR_UNC 0x40 // Unrecoverable data error. -#define ERR_BBK 0x80 // Bad block. - -// IDE commands (https://wiki.osdev.org/PCI_IDE_Controller) -#define ATA_READ_PIO 0x20 -#define ATA_READ_PIO_EXT 0x24 -#define ATA_READ_DMA 0xC8 -#define ATA_READ_DMA_EXT 0x25 -#define ATA_WRITE_PIO 0x30 -#define ATA_WRITE_PIO_EXT 0x34 -#define ATA_WRITE_DMA 0xCA -#define ATA_WRITE_DMA_EXT 0x35 -#define ATA_CACHE_FLUSH 0xE7 -#define ATA_CACHE_FLUSH_EXT 0xEA -#define ATA_PACKET 0xA0 -#define ATA_IDENTIFY_PACKET 0xA1 -#define ATA_IDENTIFY 0xEC - -// ATAPI-specific commands -#define ATAPI_READ 0xA8 -#define ATAPI_EJECT 0x18 - -// Identification space information (identification space is the buffer of 512 bytes returned by ATA_IDENTIFY_PACKET and ATA_IDENTIFY) -#define ATA_IDENT_DEVICETYPE 0 -#define ATA_IDENT_CYLINDERS 2 -#define ATA_IDENT_HEADS 6 -#define ATA_IDENT_SECTORS 12 -#define ATA_IDENT_SERIAL 20 -#define ATA_IDENT_MODEL 54 -#define ATA_IDENT_CAPABILITIES 98 -#define ATA_IDENT_FIELDVALID 106 -#define ATA_IDENT_MAX_LBA 120 -#define ATA_IDENT_COMMANDSETS 164 -#define ATA_IDENT_MAX_LBA_EXT 200 - - -// IDE/ATA interface types -#define IDE_ATA 0x00 -#define IDE_ATAPI 0x01 - -#define ATA_MASTER 0x00 -#define ATA_SLAVE 0x01 - -// ATA registers -#define ATA_REG_DATA 0x00 -#define ATA_REG_ERROR 0x01 -#define ATA_REG_FEATURES 0x01 -#define ATA_REG_SECCOUNT0 0x02 -#define ATA_REG_LBA0 0x03 -#define ATA_REG_LBA1 0x04 -#define ATA_REG_LBA2 0x05 -#define ATA_REG_HDDEVSEL 0x06 -#define ATA_REG_COMMAND 0x07 -#define ATA_REG_STATUS 0x07 -#define ATA_REG_SECCOUNT1 0x08 -#define ATA_REG_LBA3 0x09 -#define ATA_REG_LBA4 0x0A -#define ATA_REG_LBA5 0x0B -#define ATA_REG_CONTROL 0x0C -#define ATA_REG_ALTSTATUS 0x0C -#define ATA_REG_DEVADDRESS 0x0D - -// ATA channels -#define ATA_PRIMARY 0x00 -#define ATA_SECONDARY 0x01 - -// ATA directions -#define ATA_READ 0x00 -#define ATA_WRITE 0x01 - -// Errors (Needs to be fixed because weird return values can happen) -#define IDE_OK 0 -#define IDE_DRIVE_NOT_FOUND -1 -#define IDE_LBA_INVALID -2 - -// Typedefs - -// IDE channel registers -typedef struct { - uint16_t ioBase; // IO base - uint16_t controlBase; // Control base - uint16_t busMasterIDE; // Bus master IDE - uint8_t nIEN; // nIEN (no interrupt) -} ideChannelRegisters_t; - - -typedef struct { - uint8_t reserved; // Defines whether the drive realy exists (non-zero if it does) - uint8_t channel; // Defines whether the drive is primary channel or secondary (non-zero if secondary) - uint8_t drive; // Defines whether the drive is a master drive or a slave drive (non-zero if slave) - uint16_t type; // Defines what the drive is (non-zero if ATAPI) - uint16_t signature; // Drive signature - uint16_t features; // Drive features - uint32_t commandSets; // Command sets supported - uint32_t size; // Size (in sectors) - uint8_t model[41]; // Drive model. -} ideDevice_t; - -// Functions -uint8_t ideRead(uint8_t channel, uint8_t reg); // Reads in a register -void ideWrite(uint8_t channel, uint8_t reg, uint8_t data); // Writes to a register -void ideReadBuffer(uint8_t channel, uint8_t reg, uint32_t *buffer, uint32_t quads); // Reads the identification space and copies it to a buffer. -void insl(uint16_t reg, uint32_t *buffer, int quads); // Reads a long word from a register port for quads times. -void outsl(uint16_t reg, uint32_t *buffer, int quads); // Writes a long word to a register port for quads times -uint8_t idePolling(uint8_t channel, uint32_t advancedCheck); // Returns whether there was an error. -uint8_t idePrintErrors(uint32_t drive, uint8_t err); // Prints the errors that may have occurred. -void ideInit(uint32_t bar0, uint32_t bar1, uint32_t bar2, uint32_t bar3, uint32_t bar4); // Initialize IDE drives. -void printIDESummary(); // Print a summary of all IDE drives found. -uint8_t ideAccessATA(uint8_t direction, uint8_t drive, uint64_t lba, uint8_t sectorNum, uint32_t edi); // Access an ATA drive (direction specifies what operation to perform) -uint8_t ideReadATAPI(uint8_t drive, uint32_t lba, uint8_t sectorNum, uint32_t edi); // Read from an ATAPI drive. -int ideReadSectors(uint8_t drive, uint8_t sectorNum, uint64_t lba, uint32_t edi); // Read from an ATA/ATAPI drive. -int ideWriteSectors(uint8_t drive, uint8_t sectorNum, uint32_t lba, uint32_t edi); // Write to an ATA drive. -int ideGetDriveCapacity(uint8_t drive); // Returns drive capacity -uint32_t ideRead_vfs(struct fsNode *node, off_t off, uint32_t size, uint8_t *buffer); // Read function for the VFS -uint32_t ideWrite_vfs(struct fsNode *node, off_t off, uint32_t size, uint8_t *buffer); // Write function in the VFS -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/idt.h b/source/sysroot/usr/include/kernel/idt.h deleted file mode 100644 index 7f6d1404..00000000 --- a/source/sysroot/usr/include/kernel/idt.h +++ /dev/null @@ -1,57 +0,0 @@ -// idt.h - IDT header file, contains includes/declarations for the idt.c file. - -#ifndef IDT_H -#define IDT_H - -// Includes -#include "include/libc/stddef.h" // size_t declaration -#include "include/libc/stdint.h" // Integer type declarations -#include "include/libc/stdbool.h" // Boolean declarations -#include "include/libc/string.h" // String functions -#include "include/libc/limits.h" // Limits on integers and more. -#include "include/libc/stdarg.h" // va argument handling (for ... on printf) -#include "include/libc/va_list.h" // va_list declared here. -#include "include/terminal.h" // printf() and other terminal functions - -// Definitions - -#define I86_MAX_INTERRUPTS 256 // 256 maximum interrupts - -// These must be in the format 0D110 where D is the descriptor type -#define I86_IDT_DESC_BIT16 0x06 // 00000110 -#define I86_IDT_DESC_BIT32 0x0E // 00001110 -#define I86_IDT_DESC_RING1 0x40 // 01000000 -#define I86_IDT_DESC_RING2 0x20 // 00100000 -#define I86_IDT_DESC_RING3 0x60 // 01100000 -#define I86_IDT_DESC_PRESENT 0x80 // 10000000 - - -// Typedefs - -typedef void (*IDT_IRQ_HANDLER)(void); // Interrupt handler without an error code. Interrupt handlers are called by the processor. Since the stack setup may change, we leave it up to the interrupts' implementation to handle it and properly return. - -typedef struct { - uint16_t baseLow; // Lower 16 bits (0-15) of the interrupt routine address (address to jump when interrupt fires.) - uint16_t segmentSelector; // Code segment selector in GDT - uint8_t reserved; // Reserved. Should be 0. - uint8_t flags; // Bit flags. - uint16_t baseHigh; // Higher 16 bits (16-31) of the interrupt routine address (see baseLow) -} __attribute__((packed)) idtEntry_t; - -typedef struct { - uint16_t limit; // size of the IDT - uint32_t base_addr; // base address of the IDT -} __attribute__((packed)) idtPtr_t; - - - - -// Functions - - -extern int idtInstallIR(uint8_t i, uint8_t flags, uint16_t segmentSelector, uint32_t base); // Installs interrupt handler. When INT is fired, it calls this -extern void idtInit(); // Initializes basic IDT. - - - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/initrd.h b/source/sysroot/usr/include/kernel/initrd.h deleted file mode 100644 index 30a9e4dc..00000000 --- a/source/sysroot/usr/include/kernel/initrd.h +++ /dev/null @@ -1,38 +0,0 @@ -// initrd.h - header file for initrd.c (manages the initial ramdisk) - -#ifndef INITRD_H -#define INITRD_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/libc/string.h" // String functions -#include "include/vfs.h" // Virtual File System definitions -#include "include/terminal.h" // printf() - -// Typedefs - -// Image header -typedef struct { - uint32_t fileAmnt; // Number of files in the ramdisk. -} initrd_imageHeader_t; - -// File header -typedef struct { - uint8_t magic; // Magic number (used for error checking, should be 0xBF) - int8_t name[64]; // Filename. - uint32_t offset; // Offset in the ramdisk where the file starts. - uint32_t length; // File length. -} initrd_fileHeader_t; - -// Subdirectory structure -typedef struct { - uint8_t magic; // Magic number (should be 0xBA) - int8_t name; - uint8_t fileMagic; // File magic number (see initrdInit()) -} initrd_subdirectoryHeader_t; - -// Function (there's just one lol): -fsNode_t *initrdInit(uint32_t location); // Loads initrd by defining pointers, setting values, etc. - - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/io_apic.h b/source/sysroot/usr/include/kernel/io_apic.h deleted file mode 100644 index 34fac100..00000000 --- a/source/sysroot/usr/include/kernel/io_apic.h +++ /dev/null @@ -1,25 +0,0 @@ -// io_apic.h - header file for io_apic.c - -#ifndef IO_APIC_H -#define IO_APIC_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations - -// Definitions - -// Registers for the IO APIC (memory mapped) -#define IO_APIC_REGSEL 0x00 -#define IO_APIC_WIN 0x10 - -// Registers for the IO APIC -#define IO_APIC_ID 0x00 -#define IO_APIC_VER 0x01 -#define IO_APIC_ARB 0x02 -#define IO_APIC_REDTBL 0x10 - -// Functions -void ioAPIC_setEntry(uint8_t *base, uint8_t index, uint64_t data); // Set an entry in the IO APIC. -void ioAPIC_init(); // Initialize the IO APIC. - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/isr.h b/source/sysroot/usr/include/kernel/isr.h deleted file mode 100644 index 4a517d5f..00000000 --- a/source/sysroot/usr/include/kernel/isr.h +++ /dev/null @@ -1,140 +0,0 @@ -// isr.h - header file for isr.c -// ISR - Interrupt Service Routines - -#ifndef ISR_H -#define ISR_H - -// Includes - -#include "include/libc/stdint.h" // Integer declarations like uint8_t, int16_t, etc. -#include "include/hal.h" // Some misc functions for interrupts. - - -#include "include/panic.h" // Kernel panicking. Used on i86DefaultHandler. -#include "include/regs.h" // registers_t typedef - -// Definitions - -// IRQ default constants -#define IRQ_BASE 0x20 // Base IRQ -#define IRQ0_TIMER 0x00 // Timer IRQ -#define IRQ1_KEYBOARD 0x01 // Keyboard IRQ -#define IRQ2_CASCADE 0x02 // Cascade IRQ -#define IRQ3_SERIAL_PORT2 0x03 // Serial 2 IRQ -#define IRQ4_SERIAL_PORT1 0x04 // Serial 1 IRQ -#define IRQ5_RESERVED 0x05 // Reserved -#define IRQ6_DISKETTE_DRIVE 0x06 // Disk drive IRQ -#define IRQ7_PARALLEL_PORT 0x07 // Parallel IRQ -#define IRQ8_CMOS_CLOCK 0x08 // CMOS IRQ -#define IRQ9_CGA 0x09 // CGA graphics IRQ -#define IRQ10_RESERVED 0x0A // Reserved -#define IRQ11_RESERVED 0x0B // Reserved -#define IRQ12_AUXILIARY 0x0C // Auxilary IRQ -#define IRQ13_FPU 0x0D // FPU IRQ -#define IRQ14_HARD_DISK 0x0E // HDD IRQ -#define IRQ15_RESERVED 0x0F // Reserved - - - -// Typedefs - -typedef void (*ISR)(registers_t *); - -// Variable definitions - -static char *exception_messages[32] = { - "Division by zero", - "Debug", - "Non-maskable interrupt", - "Breakpoint", - "Overflow", - "Bound range exceeded", - "Invalid opcode", - "Device not available (no math coprocessor)", - "Double fault", - "Coprocessor segment overrun", - "Invalid TSS", - "Segment not present", - "Stack-segment fault", - "General protection", - "Page fault", - "Unknown interrupt (intel reserved)", - "x87 FPU floating-point error (math fault)", - "Alignment check", - "Machine check", - "SIMD floating-point exception", - "Virtualization exception", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved" -}; - - - -// External declarations -extern void isr0(); -extern void isr1(); -extern void isr2(); -extern void isr3(); -extern void isr4(); -extern void isr5(); -extern void isr6(); -extern void isr7(); -extern void isr8(); -extern void isr9(); -extern void isr10(); -extern void isr11(); -extern void isr12(); -extern void isr13(); -extern void isr14(); -extern void isr15(); -extern void isr16(); -extern void isr17(); -extern void isr18(); -extern void isr19(); -extern void isr20(); -extern void isr21(); -extern void isr22(); -extern void isr23(); -extern void isr24(); -extern void isr25(); -extern void isr26(); -extern void isr27(); -extern void isr28(); -extern void isr29(); -extern void isr30(); -extern void isr31(); -extern void isr128(); - -extern void irq_0(); -extern void irq_1(); -extern void irq_2(); -extern void irq_3(); -extern void irq_4(); -extern void irq_5(); -extern void irq_6(); -extern void irq_7(); -extern void irq_8(); -extern void irq_9(); -extern void irq_10(); -extern void irq_11(); -extern void irq_12(); -extern void irq_13(); -extern void irq_14(); -extern void irq_15(); - -// Functions - -void isrRegisterInterruptHandler(int num, ISR handler); // Registers an interrupt handler -void isrEndInterrupt(int num); // Ends an interrupt. -void isrInstall(); // Installs ISR - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/kernel.h b/source/sysroot/usr/include/kernel/kernel.h deleted file mode 100644 index 08bade4c..00000000 --- a/source/sysroot/usr/include/kernel/kernel.h +++ /dev/null @@ -1,43 +0,0 @@ -// kernel.h - Includes and function declarations for the kernel - -#ifndef KERNEL_H -#define KERNEL_H - -// Includes -#include "include/libc/stddef.h" // size_t declaration -#include "include/libc/stdint.h" // Integer type declarations -#include "include/libc/stdbool.h" // Boolean declarations -#include "include/libc/string.h" // String functions -#include "include/libc/limits.h" // Limits on integers and more. -#include "include/libc/stdarg.h" // va argument handling (for ... on printf) -#include "include/libc/va_list.h" // va_list declared here. -#include "include/libc/assert.h" // Assertion macro -#include "include/libc/udivdi3.h" // udivdi3 -#include "include/libc/sleep.h" // Sleeping -#include "include/graphics.h" // Graphics handling -#include "include/terminal.h" // Terminal handling -#include "include/idt.h" // Interrupt Descriptor Table -#include "include/gdt.h" // Global Descriptor Table -#include "include/pic.h" // Programmable Interrupt Controller -#include "include/pit.h" // Programmable Interval Timer -#include "include/hal.h" // Hardware Abstraction Layer -#include "include/keyboard.h" // Keyboard driver -#include "include/panic.h" // Kernel panicking -#include "include/bootinfo.h" // Boot information -#include "include/command.h" // Command parser -#include "include/pci.h" // PCI driver -#include "include/serial.h" // Serial logging -#include "include/initrd.h" // Initial ramdisk management. -#include "include/vfs.h" // Virtual file system. -#include "include/ide_ata.h" // ATA driver -#include "include/rtc.h" // Real-time clock. -#include "include/bios32.h" // BIOS32 calls -#include "include/processor.h" // Procesor handler -#include "include/vesa.h" // VESA VBE graphics driver -#include "include/syscall.h" // System call -#include "include/bitmap.h" // Bitmap image controls -#include "include/CONFIG.h" // reduceOS configuration -#include "include/floppy.h" // FDC driver -#include "include/test.h" // Test command - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/keyboard.h b/source/sysroot/usr/include/kernel/keyboard.h deleted file mode 100644 index 4ca36550..00000000 --- a/source/sysroot/usr/include/kernel/keyboard.h +++ /dev/null @@ -1,87 +0,0 @@ -// keyboard.h - header file for keyboard.c, the keyboard driver - -#ifndef KEYBOARD_H -#define KEYBOARD_H - - -// Includes -#include "include/libc/stdint.h" // Integer declarations like uint8_t, etc. -#include "include/libc/string.h" // String functions -#include "include/libc/stdbool.h" // Booleans - -#include "include/isr.h" // Interrupt Service Routines -#include "include/terminal.h" // Terminal functions like printf. -#include "include/panic.h" // Register declarations -#include "include/heap.h" // Heap declarations (for allocating memory) - -// Definitions - -#define SCANCODE_ESC 0x01 -#define SCANCODE_BACKSPACE 0x0E -#define SCANCODE_ENTER 0x1C -#define SCANCODE_CTRL 0x1D // CTRL key is special (along with a few others) - The keyboard signifies left or right control based on whether the extended byte (E0) was sent first. We don't take into account extended bit - we don't need to! There is no difference between right and left control (the kb handler picks both up!) -#define SCANCODE_LEFTSHIFT 0x2A -#define SCANCODE_RIGHTSHIFT 0x36 -#define SCANCODE_ALT 0x38 -#define SCANCODE_CAPSLOCK 0x3A -#define SCANCODE_F1 0x3B -#define SCANCODE_F2 0x3C -#define SCANCODE_F3 0x3D -#define SCANCODE_F4 0x3E -#define SCANCODE_F5 0x3F -#define SCANCODE_F6 0x40 -#define SCANCODE_F7 0x41 -#define SCANCODE_F8 0x42 -#define SCANCODE_F9 0x43 -#define SCANCODE_F10 0x44 -#define SCANCODE_NUMLOCK 0x45 -#define SCANCODE_SCROLL_LOCK 0x46 -#define SCANCODE_HOME 0x47 -#define SCANCODE_UP 0x18 -#define SCANCODE_PGUP 0x49 -#define SCANCODE_DOWN 0x19 -#define SCANCODE_PGDOWN 0x51 -#define SCANCODE_LEFT 0x38 -#define SCANCODE_RIGHT 0x45 -#define SCANCODE_F11 0x57 -#define SCANCODE_F12 0x58 -#define SCANCODE_TAB 0x0F -#define SCANCODE_SPACE 0x39 -#define SCANCODE_EXTENDEDBYTE 0xE0 - -#define MAX_BUFFER_CHARS 500 // We can hold about 500 chars - this is a hard limit (as of now). TODO: Possibly, if it turns out we do need to have 500 chars as a hard limit, add a speaker beep that will notify the user when the buffer is overflowing. - - - - -// Typedefs - -typedef enum scancodes_special { - DETECTION_ERROR = 0x00, // This can also mean an internal buffer overrun - SELF_TEST_PASS = 0xAA, // Sent after reset (0xFF) command, or kb power up. - ECHO_RESP = 0xEE, // Sent after echo command (0xEE) - CMD_ACK = 0xFA, // Sent when a command is acknowledged. - SELF_TEST_FAIL1 = 0xFC, // Sent when the keyboard fails a self test. Sent after reset (0xFF) command or kb power up. Note there are two possible values sent. - SELF_TEST_FAIL2 = 0xFD, - RESEND_CMD = 0xFE, // Keyboard wants control or to repeat last command - DETECTION_ERROR2 = 0xFF // Sent on a detection error (or internal buffer overrun) -}; - -typedef enum LEDStates { - ScrollLock = 0, - NumberLock = 1, - CapsLock = 2 -}; - - -// Functions -static void keyboardHandler(registers_t *r); // keyboardHandler() - Identifies scancodes, printing, etc. Should NEVER be called outside of isrIRQHandler (REGISTERS are passed from the assembly code.) -void keyboardInitialize(); // keyboardInit() - Registers keyboardHandler on IRQ 33 - enabling the keyboard. -void setKBHandler(bool state); // setKBHandler() - Enables / disables the keyboard. Used when setting up the kernel (we don't want those pesky users mucking up our output, do we?) -void keyboardGetLine(char *buffer); // keyboardGetLine() - Returns keyboard input after ENTER key is pressed. -char keyboardGetChar(); // keyboardGetChar() - Returns the current character char (after waiting for it to be non-0) -void keyboardGetKey(char key, bool printChars); // keyboardGetKey() - Returns whenever keyboardGetChar returns key (or a special character) -char isKeyPressed(); // isKeyPressed() - Returns if a key is being pressed. -bool getControl(); // getControl() - Returns whether control is down - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/liballoc.h b/source/sysroot/usr/include/kernel/liballoc.h deleted file mode 100644 index 77242764..00000000 --- a/source/sysroot/usr/include/kernel/liballoc.h +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef _LIBALLOC_H -#define _LIBALLOC_H - -/** \defgroup ALLOCHOOKS liballoc hooks - * - * These are the OS specific functions which need to - * be implemented on any platform that the library - * is expected to work on. - */ - -/** @{ */ - - - -// If we are told to not define our own size_t, then we skip the define. -//#define _HAVE_UINTPTR_T - -#include "include/libc/stddef.h" -typedef unsigned long uintptr_t; - -//This lets you prefix malloc and friends -#define PREFIX(func) liballoc_k ## func - -#ifdef __cplusplus -extern "C" { -#endif - - - -/** This function is supposed to lock the memory data structures. It - * could be as simple as disabling interrupts or acquiring a spinlock. - * It's up to you to decide. - * - * \return 0 if the lock was acquired successfully. Anything else is - * failure. - */ -extern int liballoc_lock(); - -/** This function unlocks what was previously locked by the liballoc_lock - * function. If it disabled interrupts, it enables interrupts. If it - * had acquiried a spinlock, it releases the spinlock. etc. - * - * \return 0 if the lock was successfully released. - */ -extern int liballoc_unlock(); - -/** This is the hook into the local system which allocates pages. It - * accepts an integer parameter which is the number of pages - * required. The page size was set up in the liballoc_init function. - * - * \return NULL if the pages were not allocated. - * \return A pointer to the allocated memory. - */ -extern void* liballoc_alloc(size_t); - -/** This frees previously allocated memory. The void* parameter passed - * to the function is the exact same value returned from a previous - * liballoc_alloc call. - * - * The integer value is the number of pages to free. - * - * \return 0 if the memory was successfully freed. - */ -extern int liballoc_free(void*,size_t); - - - - -extern void *PREFIX(malloc)(size_t); ///< The standard function. -extern void *PREFIX(realloc)(void *, size_t); ///< The standard function. -extern void *PREFIX(calloc)(size_t, size_t); ///< The standard function. -extern void PREFIX(free)(void *); ///< The standard function. - - - -#ifdef __cplusplus -} -#endif - -/** @} */ - -#endif - - diff --git a/source/sysroot/usr/include/kernel/liballoc_forwarder.h b/source/sysroot/usr/include/kernel/liballoc_forwarder.h deleted file mode 100644 index b0be1775..00000000 --- a/source/sysroot/usr/include/kernel/liballoc_forwarder.h +++ /dev/null @@ -1,23 +0,0 @@ -// liballoc_forwarder.h - Reskinned heap header file for old code - -#ifndef LIBALLOC_FORWADER_H -#define LIBALLOC_FORWARDER_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/libc/string.h" // String functions -#include "include/libc/assert.h" -#include "include/vmm.h" - -// Macros -#define ALIGN_PAGE(addr) (((uint32_t)addr & 0xFFFFF000) + 4096) - - - -// (variables) -extern uint32_t end; // end is defined in the linker.ld script we added (thanks James Molloy!) -extern bool pagingEnabled; - -// Functions - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/liballoc_wrapper.h b/source/sysroot/usr/include/kernel/liballoc_wrapper.h deleted file mode 100644 index 175d2751..00000000 --- a/source/sysroot/usr/include/kernel/liballoc_wrapper.h +++ /dev/null @@ -1,14 +0,0 @@ -// liballoc_wrapper.h - liballoc reduceOS wrapper header file -#ifndef LIBALLOC_WRAPPER_H -#define LIBALLOC_WRAPPER_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/libc/spinlock.h" // Spinlocks -#include "include/vmm.h" // VMM functions -#include "include/vmm_pte.h" // Page structures - -// Functions - - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/libc/assert.h b/source/sysroot/usr/include/kernel/libc/assert.h deleted file mode 100644 index c52ab9ed..00000000 --- a/source/sysroot/usr/include/kernel/libc/assert.h +++ /dev/null @@ -1,14 +0,0 @@ -// assert.h - contains the assertion macro - -#ifndef ASSERT_H -#define ASSERT_H - -// Includes -#include "include/panic.h" - -// Macros - -// ASSERT(b) - Makes sure b is a valid object before continuing. -#define ASSERT(b, caller, msg) ((b) ? (void)0 : panic("Assert", caller, msg)); - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/libc/divdi3.h b/source/sysroot/usr/include/kernel/libc/divdi3.h deleted file mode 100644 index 0b978a12..00000000 --- a/source/sysroot/usr/include/kernel/libc/divdi3.h +++ /dev/null @@ -1,3 +0,0 @@ -// This file is here for compatibility reasons. -// If this is still here, give me a little ping in our discord: https://discord.gg/g5XwNxw3u5 -// Thanks for checking out my code! \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/libc/limits.h b/source/sysroot/usr/include/kernel/libc/limits.h deleted file mode 100644 index a58a5163..00000000 --- a/source/sysroot/usr/include/kernel/libc/limits.h +++ /dev/null @@ -1,62 +0,0 @@ -// limits.h - replacement for standard C header file. -// Why is this required? We use -ffreestanding in our compile options, so the standard std library isn't included. - -#ifndef LIMITS_H -#define LIMITS_H - -// Macro declarations. This is what limits.h mostly consists off. - -// Maximum length of a multibyte character -#define MB_LEN_MAX 16 - -// Minimum and maximum value of a signed char. -#define SCHAR_MIN (-128) -#define SCHAR_MAX (127) - -// Bits in a character. -#define CHAR_BIT 8 - -// Maximum an unsigned char can hold -#define UCHAR_MAX 255 - -// Minimum and maximum values a char can hold. Depends on unsigned or not. -#ifdef __CHAR_UNSIGNED__ -# define CHAR_MIN 0 -# define CHAR_MAX UCHAR_MAX -#else -# define CHAR_MIN SCHAR_MIN -# define CHAR_MAX SCHAR_MAX -#endif - -// Minimum and maximum values a signed short int can hold. -#define SHRT_MIN (-32768) -#define SHRT_MAX 32767 - -// Minimum and maximum values an unsigned short int can hold. Minimum is 0. -#define USHRT_MAX 65535 - -// Minimum and maximum value of a signed integer. -#define INT_MIN (-INT_MAX - 1) -#define INT_MAX 214748364 - -// Minimum and maximum values an unsigned int can hold. -#define UINT_MAX 4294967285U - -// Minimum and maximum values a signed long int can hold. -# if __WORDSIZE == 64 -# define LONG_MAX 9223372036854775807L -# else -# define LONG_MAX 2147483647L -# endif -# define LONG_MIN (-LONG_MAX - 1L) - -// Minimum and maximum values an unsigned long int can hold. -# if __WORDSIZE == 64 -# define ULONG_MAX 18446744073709551615UL -# else -# define ULONG_MAX 4294967295UL -# endif - - - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/libc/list.h b/source/sysroot/usr/include/kernel/libc/list.h deleted file mode 100644 index c1599969..00000000 --- a/source/sysroot/usr/include/kernel/libc/list.h +++ /dev/null @@ -1,48 +0,0 @@ -// list.h - Just a small list implementation (shouldn't be in libc, but I don't care) -// You can find this impl. here: https://github.com/stevej/osdev/blob/master/kernel/include/list.h (FORKED FROM TOARUOS) - - -#ifndef LIST_H -#define LIST_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/libc/stddef.h" // size_t -#include "include/mem.h" // Memory functions - -// Typedefs -typedef struct node { - struct node *next; // Next node - struct node *prev; // Previous node - void *value; // Value of this node -} node_t; - - -typedef struct list { - struct node *head; - struct node *tail; - size_t length; -} list_t; - -// Macros -#define foreach(i, list) for (node_t *i = list->head; i != NULL; i = i->next) - -// Functions -void list_destroy(list_t * list); -void list_free(list_t * list); -void list_append(list_t * list, node_t * item); -void list_insert(list_t * list, void * item); -list_t * list_create(); -node_t * list_find(list_t * list, void * value); -void list_remove(list_t * list, size_t index); -void list_delete(list_t * list, node_t * node); -node_t * list_pop(list_t * list); -node_t * list_dequeue(list_t * list); -list_t * list_copy(list_t * original); -void list_merge(list_t * target, list_t * source); - -void list_append_after(list_t * list, node_t * before, node_t * node); -void list_insert_after(list_t * list, node_t * before, void * item); - - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/libc/ordered_array.h b/source/sysroot/usr/include/kernel/libc/ordered_array.h deleted file mode 100644 index 6391be62..00000000 --- a/source/sysroot/usr/include/kernel/libc/ordered_array.h +++ /dev/null @@ -1,24 +0,0 @@ -// ordered_array.h - header file for ordered_array.c (ordered array stuff) -// This implementation is based on James Molloy's kernel development tutorials (http://www.jamesmolloy.co.uk/tutorial_html/7.-The%20Heap.html) - -#ifndef ORDERED_ARRAY_H -#define ORDERED_ARRAY_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/libc/assert.h" // Assert macro -#include "include/libc/ordered_array_t.h" - -// Typedefs - - -// Functions -int8_t standard_lessthan_predicate(type_t a, type_t b); // A standard less-than predicate -ordered_array_t createOrderedArray(uint32_t maxSize, lessthan_predicate less_than); // Create an ordered array -ordered_array_t placeOrderedArray(void* addr, uint32_t maxSize, lessthan_predicate less_than); // Place an ordered array -void destroyOrderedArray(ordered_array_t* array); // Destroy an ordered array -void insertOrderedArray(type_t item, ordered_array_t* array); // Insert an item into an ordered array. -type_t lookupOrderedArray(uint32_t i, ordered_array_t* array); // Lookup an item at index i in ordered array array. -void removeOrderedArray(uint32_t i, ordered_array_t* array); // Remove an item at index i in ordered array array. - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/libc/ordered_array_t.h b/source/sysroot/usr/include/kernel/libc/ordered_array_t.h deleted file mode 100644 index 4f1bff72..00000000 --- a/source/sysroot/usr/include/kernel/libc/ordered_array_t.h +++ /dev/null @@ -1,20 +0,0 @@ -// ordered_array_t.h - Contains the definition for ordered_array_t -#ifndef ORDERED_ARRAY_T_H -#define ORDERED_ARRAY_T_H - -#include "include/libc/stdint.h" - -typedef void* type_t; // This array is insertion sorted, meaning it always remains in a sorted state between calls. - -typedef int8_t (*lessthan_predicate)(type_t, type_t); // A predicate should return non-zero if the first arg is less than the second. Else, it will return 0. - - -// The actual ordered array. -typedef struct { - type_t *array; - uint32_t size; - uint32_t maxSize; - lessthan_predicate less_than; -} ordered_array_t; - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/libc/quad.h b/source/sysroot/usr/include/kernel/libc/quad.h deleted file mode 100644 index 0b978a12..00000000 --- a/source/sysroot/usr/include/kernel/libc/quad.h +++ /dev/null @@ -1,3 +0,0 @@ -// This file is here for compatibility reasons. -// If this is still here, give me a little ping in our discord: https://discord.gg/g5XwNxw3u5 -// Thanks for checking out my code! \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/libc/sleep.h b/source/sysroot/usr/include/kernel/libc/sleep.h deleted file mode 100644 index a74e9715..00000000 --- a/source/sysroot/usr/include/kernel/libc/sleep.h +++ /dev/null @@ -1,12 +0,0 @@ -// sleep.h - header file for sleep.c - -#ifndef SLEEP_H -#define SLEEP_H - -// Includes -#include "include/pit.h" // Programmable interval timer - -// Functions -void sleep(int ms); // sleep() - stops execution of current task for x milliseconds. - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/libc/spinlock.h b/source/sysroot/usr/include/kernel/libc/spinlock.h deleted file mode 100644 index ac3d75f9..00000000 --- a/source/sysroot/usr/include/kernel/libc/spinlock.h +++ /dev/null @@ -1,15 +0,0 @@ -// spinlock.h - header file for the spinlock mechanism - -#ifndef SPINLOCK_H -#define SPINLOCK_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations -#include // For once in our lives, C is on our side!! - -// Functions -atomic_flag *spinlock_init(); // Creates a new spinlock -void spinlock_lock(atomic_flag *lock); // Locks the spinlock -void spinlock_release(atomic_flag *lock); // Releases the spinlock - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/libc/stdarg.h b/source/sysroot/usr/include/kernel/libc/stdarg.h deleted file mode 100644 index 6e541c52..00000000 --- a/source/sysroot/usr/include/kernel/libc/stdarg.h +++ /dev/null @@ -1,34 +0,0 @@ -// stdarg.h - replacement for standard C header file. -// Why is this required? We use -ffreestanding in our compile options, so the standard std library isn't included. - -// File operates in tandem with va_list.h (va functions/macros here, whilst the actual va_list declaration is in va_list.h) - -#ifndef STDARG_H -#define STDARG_H - -// Includes of other header files -#include "include/libc/va_list.h" // I mean, it would be faster to do #include "va_list.h", but it wouldn't compile (-Isource/kernel flag). Makes VS code pretty angry, that's for sure. - -// Definitions (non-macro) -#define STACKITEM int // Width of stack (width of an int) - -// Macros - -// VA_SIZE(TYPE) - Round up width of objects pushed on stack. -#define VA_SIZE(TYPE) \ - ((sizeof(TYPE) + sizeof(STACKITEM) - 1) \ - & ~(sizeof(STACKITEM) - 1)) - - - - -// va_arg(AP, TYPE) - Retrieve the next argument of type 'TYPE' in va_list 'AP' -/*#define va_arg(AP, TYPE) \ - (AP += VA_SIZE(TYPE), *((TYPE *)(AP - VA_SIZE(TYPE))))*/ - - - -#define va_start(x, y) __builtin_va_start(x, y) -#define va_arg(x, y) __builtin_va_arg(x, y) -#define va_end(x) __builtin_va_end(x) -#endif diff --git a/source/sysroot/usr/include/kernel/libc/stdbool.h b/source/sysroot/usr/include/kernel/libc/stdbool.h deleted file mode 100644 index 6a6f887f..00000000 --- a/source/sysroot/usr/include/kernel/libc/stdbool.h +++ /dev/null @@ -1,17 +0,0 @@ -// stdbool.h - replacement for standard C header file. -// Why is this required? We use -ffreestanding in our compile options, so the standard std library isn't included. - -#ifndef STDBOOL_H -#define STDBOOL_H - -#define true 1 -#define false 0 -#define __bool_true_false_are_defined 1 - -// A custom implementation of the bool class not present in the actual stdbool.h. It is not recommended to use. -typedef enum { - FALSE, - TRUE -} bool; - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/libc/stddef.h b/source/sysroot/usr/include/kernel/libc/stddef.h deleted file mode 100644 index 172a8394..00000000 --- a/source/sysroot/usr/include/kernel/libc/stddef.h +++ /dev/null @@ -1,19 +0,0 @@ -// stddef.h - replacement for standard C header file. -// Why is this required? We use -ffreestanding in our compile options, so the standard std library isn't included. - - -#if 1 - -#include - - -#else -// Definitions -#define null 0 -#define NULL 0 - -// Typedef declarations -typedef unsigned size_t; -typedef signed ptrdiff_t; - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/libc/stdint.h b/source/sysroot/usr/include/kernel/libc/stdint.h deleted file mode 100644 index 60f36590..00000000 --- a/source/sysroot/usr/include/kernel/libc/stdint.h +++ /dev/null @@ -1,558 +0,0 @@ -// stdint.h - replacement for standard C header file. -// Why is this required? We use -ffreestanding in our compile options, so the standard std library isn't included. - -/* - * Copyright (c) 2004, 2005 by - * Ralf Corsepius, Ulm/Germany. All rights reserved. - * - * Permission to use, copy, modify, and distribute this software - * is freely granted, provided that this notice is preserved. - */ - - - -#ifndef STDINT_H -#define STDINT_H - -/* -#define NULL 0 - -// Exact-width integer types - -typedef signed char int8_t; -typedef unsigned char uint8_t; -typedef short int16_t; -typedef unsigned short uint16_t; -typedef int int32_t; -typedef unsigned int uint32_t; -typedef long long int64_t; -typedef unsigned long long uint64_t; - -// Minimum-width integer types. - -typedef signed char int_least8_t; -typedef unsigned char uint_least8_t; -typedef short int_least16_t; -typedef unsigned short uint_least16_t; -typedef int int_least32_t; -typedef unsigned uint_least32_t; -typedef long long int_least64_t; -typedef unsigned long long uint_least64_t; - - -// GCC doesn't provide a good macro for (u)intptr_t so we check if __PTRDIFF_TYPE__ is defined and use that, else do something different I guess -#if defined(__PTRDIFF_TYPE__) -typedef signed __PTRDIFF_TYPE__ intptr_t; -typedef unsigned __PTRDIFF_TYPE__ uintptr_t; - -#define INTPTR_MAX PTRDIFF_MAX -#define INTPTR_MIN PTRDIFF_MIN - -#ifdef __UINTPTR_MAX__ -#define UINTPTR_MAX __UINTPTR_MAX__ -#else -#define UINTPTR_MAX (2UL * PTRDIFF_MAX + 1) -#endif -#else - -// Fallback to hardcoded values -typedef signed long intptr_t; -typedef unsigned long uintptr_t; - -#define INTPTR_MAX __STDINT_EXP(LONG_MAX) -#define INTPTR_MIN (-__STDINT_EXP(LONG_MAX) - 1) -#define UINTPTR_MAX (__STDINT_EXP(LONG_MAX) * 2UL + 1) - - -#endif - - -#if defined(__UINTMAX_TYPE__) - typedef __UINTMAX_TYPE__ uintmax_t; -#elif ( defined(__LONG_LONG_MAX__) && (__LONG_LONG_MAX__ > 0x7fffffff) ) \ - || ( defined(LLONG_MAX) && (LLONG_MAX > 0x7fffffff) ) - typedef unsigned long long uintmax_t; -#else - typedef unsigned long uintmax_t; -#endif - -*/ - - - -#if defined(__GNUC__) && \ - ( (__GNUC__ >= 4) || \ - ( (__GNUC__ >= 3) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ > 2) ) ) -/* gcc > 3.2 implicitly defines the values we are interested */ -#define __STDINT_EXP(x) __##x##__ -#else -#define __STDINT_EXP(x) x -#include -#endif - -/* Check if "long long" is 64bit wide */ -/* Modern GCCs provide __LONG_LONG_MAX__, SUSv3 wants LLONG_MAX */ -#if ( defined(__LONG_LONG_MAX__) && (__LONG_LONG_MAX__ > 0x7fffffff) ) \ - || ( defined(LLONG_MAX) && (LLONG_MAX > 0x7fffffff) ) -#define __have_longlong64 1 -#endif - -/* Check if "long" is 64bit or 32bit wide */ -#if __STDINT_EXP(LONG_MAX) > 0x7fffffff -#define __have_long64 1 -#elif __STDINT_EXP(LONG_MAX) == 0x7fffffff && !defined(__SPU__) -#define __have_long32 1 -#endif - -#if __STDINT_EXP(SCHAR_MAX) == 0x7f -typedef signed char int8_t ; -typedef unsigned char uint8_t ; -#define __int8_t_defined 1 -#endif - -#if __int8_t_defined -typedef signed char int_least8_t; -typedef unsigned char uint_least8_t; -#define __int_least8_t_defined 1 -#endif - -#if __STDINT_EXP(SHRT_MAX) == 0x7fff -typedef signed short int16_t; -typedef unsigned short uint16_t; -#define __int16_t_defined 1 -#elif __STDINT_EXP(INT_MAX) == 0x7fff -typedef signed int int16_t; -typedef unsigned int uint16_t; -#define __int16_t_defined 1 -#elif __STDINT_EXP(SCHAR_MAX) == 0x7fff -typedef signed char int16_t; -typedef unsigned char uint16_t; -#define __int16_t_defined 1 -#endif - -#if __int16_t_defined -typedef int16_t int_least16_t; -typedef uint16_t uint_least16_t; -#define __int_least16_t_defined 1 - -#if !__int_least8_t_defined -typedef int16_t int_least8_t; -typedef uint16_t uint_least8_t; -#define __int_least8_t_defined 1 -#endif -#endif - -#if __have_long32 -typedef signed long int32_t; -typedef unsigned long uint32_t; -#define __int32_t_defined 1 -#elif __STDINT_EXP(INT_MAX) == 0x7fffffffL -typedef signed int int32_t; -typedef unsigned int uint32_t; -#define __int32_t_defined 1 -#elif __STDINT_EXP(SHRT_MAX) == 0x7fffffffL -typedef signed short int32_t; -typedef unsigned short uint32_t; -#define __int32_t_defined 1 -#elif __STDINT_EXP(SCHAR_MAX) == 0x7fffffffL -typedef signed char int32_t; -typedef unsigned char uint32_t; -#define __int32_t_defined 1 -#endif - -#if __int32_t_defined -typedef int32_t int_least32_t; -typedef uint32_t uint_least32_t; -#define __int_least32_t_defined 1 - -#if !__int_least8_t_defined -typedef int32_t int_least8_t; -typedef uint32_t uint_least8_t; -#define __int_least8_t_defined 1 -#endif - -#if !__int_least16_t_defined -typedef int32_t int_least16_t; -typedef uint32_t uint_least16_t; -#define __int_least16_t_defined 1 -#endif -#endif - -#if __have_long64 -typedef signed long int64_t; -typedef unsigned long uint64_t; -#define __int64_t_defined 1 -#elif __have_longlong64 -typedef signed long long int64_t; -typedef unsigned long long uint64_t; -#define __int64_t_defined 1 -#elif __STDINT_EXP(INT_MAX) > 0x7fffffff -typedef signed int int64_t; -typedef unsigned int uint64_t; -#define __int64_t_defined 1 -#endif - -#if __int64_t_defined -typedef int64_t int_least64_t; -typedef uint64_t uint_least64_t; -#define __int_least64_t_defined 1 - -#if !__int_least8_t_defined -typedef int64_t int_least8_t; -typedef uint64_t uint_least8_t; -#define __int_least8_t_defined 1 -#endif - -#if !__int_least16_t_defined -typedef int64_t int_least16_t; -typedef uint64_t uint_least16_t; -#define __int_least16_t_defined 1 -#endif - -#if !__int_least32_t_defined -typedef int64_t int_least32_t; -typedef uint64_t uint_least32_t; -#define __int_least32_t_defined 1 -#endif -#endif - -/* - * Fastest minimum-width integer types - * - * Assume int to be the fastest type for all types with a width - * less than __INT_MAX__ rsp. INT_MAX - */ -#if __STDINT_EXP(INT_MAX) >= 0x7f - typedef signed int int_fast8_t; - typedef unsigned int uint_fast8_t; -#define __int_fast8_t_defined 1 -#endif - -#if __STDINT_EXP(INT_MAX) >= 0x7fff - typedef signed int int_fast16_t; - typedef unsigned int uint_fast16_t; -#define __int_fast16_t_defined 1 -#endif - -#if __STDINT_EXP(INT_MAX) >= 0x7fffffff - typedef signed int int_fast32_t; - typedef unsigned int uint_fast32_t; -#define __int_fast32_t_defined 1 -#endif - -#if __STDINT_EXP(INT_MAX) > 0x7fffffff - typedef signed int int_fast64_t; - typedef unsigned int uint_fast64_t; -#define __int_fast64_t_defined 1 -#endif - -/* - * Fall back to [u]int_least_t for [u]int_fast_t types - * not having been defined, yet. - * Leave undefined, if [u]int_least_t should not be available. - */ -#if !__int_fast8_t_defined -#if __int_least8_t_defined - typedef int_least8_t int_fast8_t; - typedef uint_least8_t uint_fast8_t; -#define __int_fast8_t_defined 1 -#endif -#endif - -#if !__int_fast16_t_defined -#if __int_least16_t_defined - typedef int_least16_t int_fast16_t; - typedef uint_least16_t uint_fast16_t; -#define __int_fast16_t_defined 1 -#endif -#endif - -#if !__int_fast32_t_defined -#if __int_least32_t_defined - typedef int_least32_t int_fast32_t; - typedef uint_least32_t uint_fast32_t; -#define __int_fast32_t_defined 1 -#endif -#endif - -#if !__int_fast64_t_defined -#if __int_least64_t_defined - typedef int_least64_t int_fast64_t; - typedef uint_least64_t uint_fast64_t; -#define __int_fast64_t_defined 1 -#endif -#endif - -/* Greatest-width integer types */ -/* Modern GCCs provide __INTMAX_TYPE__ */ -#if defined(__INTMAX_TYPE__) - typedef __INTMAX_TYPE__ intmax_t; -#elif __have_longlong64 - typedef signed long long intmax_t; -#else - typedef signed long intmax_t; -#endif - -/* Modern GCCs provide __UINTMAX_TYPE__ */ -#if defined(__UINTMAX_TYPE__) - typedef __UINTMAX_TYPE__ uintmax_t; -#elif __have_longlong64 - typedef unsigned long long uintmax_t; -#else - typedef unsigned long uintmax_t; -#endif - -/* - * GCC doesn't provide an appropriate macro for [u]intptr_t - * For now, use __PTRDIFF_TYPE__ - */ -#if defined(__PTRDIFF_TYPE__) -typedef signed __PTRDIFF_TYPE__ intptr_t; -typedef unsigned __PTRDIFF_TYPE__ uintptr_t; -#define INTPTR_MAX PTRDIFF_MAX -#define INTPTR_MIN PTRDIFF_MIN -#ifdef __UINTPTR_MAX__ -#define UINTPTR_MAX __UINTPTR_MAX__ -#else -#define UINTPTR_MAX (2UL * PTRDIFF_MAX + 1) -#endif -#else -/* - * Fallback to hardcoded values, - * should be valid on cpu's with 32bit int/32bit void* - */ -typedef signed long intptr_t; -typedef unsigned long uintptr_t; -#define INTPTR_MAX __STDINT_EXP(LONG_MAX) -#define INTPTR_MIN (-__STDINT_EXP(LONG_MAX) - 1) -#define UINTPTR_MAX (__STDINT_EXP(LONG_MAX) * 2UL + 1) -#endif - -/* Limits of Specified-Width Integer Types */ - -#if __int8_t_defined -#define INT8_MIN -128 -#define INT8_MAX 127 -#define UINT8_MAX 255 -#endif - -#if __int_least8_t_defined -#define INT_LEAST8_MIN -128 -#define INT_LEAST8_MAX 127 -#define UINT_LEAST8_MAX 255 -#else -#error required type int_least8_t missing -#endif - -#if __int16_t_defined -#define INT16_MIN -32768 -#define INT16_MAX 32767 -#define UINT16_MAX 65535 -#endif - -#if __int_least16_t_defined -#define INT_LEAST16_MIN -32768 -#define INT_LEAST16_MAX 32767 -#define UINT_LEAST16_MAX 65535 -#else -#error required type int_least16_t missing -#endif - -#if __int32_t_defined -#if __have_long32 -#define INT32_MIN (-2147483647L-1) -#define INT32_MAX 2147483647L -#define UINT32_MAX 4294967295UL -#else -#define INT32_MIN (-2147483647-1) -#define INT32_MAX 2147483647 -#define UINT32_MAX 4294967295U -#endif -#endif - -#if __int_least32_t_defined -#if __have_long32 -#define INT_LEAST32_MIN (-2147483647L-1) -#define INT_LEAST32_MAX 2147483647L -#define UINT_LEAST32_MAX 4294967295UL -#else -#define INT_LEAST32_MIN (-2147483647-1) -#define INT_LEAST32_MAX 2147483647 -#define UINT_LEAST32_MAX 4294967295U -#endif -#else -#error required type int_least32_t missing -#endif - -#if __int64_t_defined -#if __have_long64 -#define INT64_MIN (-9223372036854775807L-1L) -#define INT64_MAX 9223372036854775807L -#define UINT64_MAX 18446744073709551615U -#elif __have_longlong64 -#define INT64_MIN (-9223372036854775807LL-1LL) -#define INT64_MAX 9223372036854775807LL -#define UINT64_MAX 18446744073709551615ULL -#endif -#endif - -#if __int_least64_t_defined -#if __have_long64 -#define INT_LEAST64_MIN (-9223372036854775807L-1L) -#define INT_LEAST64_MAX 9223372036854775807L -#define UINT_LEAST64_MAX 18446744073709551615U -#elif __have_longlong64 -#define INT_LEAST64_MIN (-9223372036854775807LL-1LL) -#define INT_LEAST64_MAX 9223372036854775807LL -#define UINT_LEAST64_MAX 18446744073709551615ULL -#endif -#endif - -#if __int_fast8_t_defined -#if __STDINT_EXP(INT_MAX) >= 0x7f -#define INT_FAST8_MIN (-__STDINT_EXP(INT_MAX)-1) -#define INT_FAST8_MAX __STDINT_EXP(INT_MAX) -#define UINT_FAST8_MAX (__STDINT_EXP(INT_MAX)*2U+1U) -#else -#define INT_FAST8_MIN INT_LEAST8_MIN -#define INT_FAST8_MAX INT_LEAST8_MAX -#define UINT_FAST8_MAX UINT_LEAST8_MAX -#endif -#endif - -#if __int_fast16_t_defined -#if __STDINT_EXP(INT_MAX) >= 0x7fff -#define INT_FAST16_MIN (-__STDINT_EXP(INT_MAX)-1) -#define INT_FAST16_MAX __STDINT_EXP(INT_MAX) -#define UINT_FAST16_MAX (__STDINT_EXP(INT_MAX)*2U+1U) -#else -#define INT_FAST16_MIN INT_LEAST16_MIN -#define INT_FAST16_MAX INT_LEAST16_MAX -#define UINT_FAST16_MAX UINT_LEAST16_MAX -#endif -#endif - -#if __int_fast32_t_defined -#if __STDINT_EXP(INT_MAX) >= 0x7fffffff -#define INT_FAST32_MIN (-__STDINT_EXP(INT_MAX)-1) -#define INT_FAST32_MAX __STDINT_EXP(INT_MAX) -#define UINT_FAST32_MAX (__STDINT_EXP(INT_MAX)*2U+1U) -#else -#define INT_FAST32_MIN INT_LEAST32_MIN -#define INT_FAST32_MAX INT_LEAST32_MAX -#define UINT_FAST32_MAX UINT_LEAST32_MAX -#endif -#endif - -#if __int_fast64_t_defined -#if __STDINT_EXP(INT_MAX) > 0x7fffffff -#define INT_FAST64_MIN (-__STDINT_EXP(INT_MAX)-1) -#define INT_FAST64_MAX __STDINT_EXP(INT_MAX) -#define UINT_FAST64_MAX (__STDINT_EXP(INT_MAX)*2U+1U) -#else -#define INT_FAST64_MIN INT_LEAST64_MIN -#define INT_FAST64_MAX INT_LEAST64_MAX -#define UINT_FAST64_MAX UINT_LEAST64_MAX -#endif -#endif - -#ifdef __INTMAX_MAX__ -#define INTMAX_MAX __INTMAX_MAX__ -#define INTMAX_MIN (-INTMAX_MAX - 1) -#elif defined(__INTMAX_TYPE__) -/* All relevant GCC versions prefer long to long long for intmax_t. */ -#define INTMAX_MAX INT64_MAX -#define INTMAX_MIN INT64_MIN -#endif - -#ifdef __UINTMAX_MAX__ -#define UINTMAX_MAX __UINTMAX_MAX__ -#elif defined(__UINTMAX_TYPE__) -/* All relevant GCC versions prefer long to long long for intmax_t. */ -#define UINTMAX_MAX UINT64_MAX -#endif - -/* This must match size_t in stddef.h, currently long unsigned int */ -#ifdef __SIZE_MAX__ -#define SIZE_MAX __SIZE_MAX__ -#else -#define SIZE_MAX (__STDINT_EXP(LONG_MAX) * 2UL + 1) -#endif - -/* This must match sig_atomic_t in (currently int) */ -#define SIG_ATOMIC_MIN (-__STDINT_EXP(INT_MAX) - 1) -#define SIG_ATOMIC_MAX __STDINT_EXP(INT_MAX) - -/* This must match ptrdiff_t in (currently long int) */ -#ifdef __PTRDIFF_MAX__ -#define PTRDIFF_MAX __PTRDIFF_MAX__ -#else -#define PTRDIFF_MAX __STDINT_EXP(LONG_MAX) -#endif -#define PTRDIFF_MIN (-PTRDIFF_MAX - 1) - -#ifdef __WCHAR_MAX__ -#define WCHAR_MAX __WCHAR_MAX__ -#endif -#ifdef __WCHAR_MIN__ -#define WCHAR_MIN __WCHAR_MIN__ -#endif - -/* wint_t is unsigned int on almost all GCC targets. */ -#ifdef __WINT_MAX__ -#define WINT_MAX __WINT_MAX__ -#else -#define WINT_MAX (__STDINT_EXP(INT_MAX) * 2U + 1U) -#endif -#ifdef __WINT_MIN__ -#define WINT_MIN __WINT_MIN__ -#else -#define WINT_MIN 0U -#endif - -/** Macros for minimum-width integer constant expressions */ -#define INT8_C(x) x -#if __STDINT_EXP(INT_MAX) > 0x7f -#define UINT8_C(x) x -#else -#define UINT8_C(x) x##U -#endif - -#define INT16_C(x) x -#if __STDINT_EXP(INT_MAX) > 0x7fff -#define UINT16_C(x) x -#else -#define UINT16_C(x) x##U -#endif - -#if __have_long32 -#define INT32_C(x) x##L -#define UINT32_C(x) x##UL -#else -#define INT32_C(x) x -#define UINT32_C(x) x##U -#endif - -#if __int64_t_defined -#if __have_long64 -#define INT64_C(x) x##L -#define UINT64_C(x) x##UL -#else -#define INT64_C(x) x##LL -#define UINT64_C(x) x##ULL -#endif -#endif - -/** Macros for greatest-width integer constant expression */ -#if __have_long64 -#define INTMAX_C(x) x##L -#define UINTMAX_C(x) x##UL -#else -#define INTMAX_C(x) x##LL -#define UINTMAX_C(x) x##ULL -#endif - - - - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/libc/stdio.h b/source/sysroot/usr/include/kernel/libc/stdio.h deleted file mode 100644 index d19fe824..00000000 --- a/source/sysroot/usr/include/kernel/libc/stdio.h +++ /dev/null @@ -1,15 +0,0 @@ -// stdio.h - Handles outputting to console or other devices - -#ifndef STDIO_H -#define STDIO_H - -// Includes -#include "include/terminal.h" // TODO: Implement ability to use stdio and other stuff - -// Functinos -int printf(const char * __restrict, ...); -int putchar(int); -int puts(const char *); - - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/libc/stdlib.h b/source/sysroot/usr/include/kernel/libc/stdlib.h deleted file mode 100644 index 2f547104..00000000 --- a/source/sysroot/usr/include/kernel/libc/stdlib.h +++ /dev/null @@ -1,14 +0,0 @@ -// stdlib.h - replacement for standard C header file. -// Why is this required? We use -ffreestanding in our compile options, so the standard std library isn't included. - -#ifndef STDLIB_H -#define STDLIB_H - -// Functions: -int abs(int x); // Returns the absolute value of an integer (always positive) -double min(double n1, double n2); // Returns the smallest of the parameters -double max(double n1, double n2); // Returns the largest of the parameters -double sqrt(double n); // Returns the sqrt of a number (return value ^ 2 = number) - - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/libc/string.h b/source/sysroot/usr/include/kernel/libc/string.h deleted file mode 100644 index d4dcc632..00000000 --- a/source/sysroot/usr/include/kernel/libc/string.h +++ /dev/null @@ -1,40 +0,0 @@ -// string.h - replacement for standard C header file. Contains certain useful functions like strlen. -// Why is this required? We use -ffreestanding in our compile options, so the standard std library isn't included. - -#ifndef STRING_H -#define STRING_H - -#include "include/libc/stdint.h" // Integer declarations -#include "include/libc/stdbool.h" // Boolean declarations -#include "include/libc/stddef.h" // size_t declaration -#include "include/libc/limits.h" // LONG_MIN and LONG_MAX -#include "include/heap.h" // kmalloc and such. - -// TECHNICALLY this isn't supposed to be here but I don't care that much -#define EOF -1 - -// Function definitions -int memcmp(const void*, const void*, size_t); // memcmp() - Comparing addresses/values in memory -void* memcpy(void* __restrict, const void* __restrict, size_t); // memcpy() - copy a block of data from one address to another. -void* memmove(void*, const void*, size_t); // memmove() - memcpy but moving it instead of copying. -void *memset(void* buf, char c, size_t n); // memset() - set a buffer in memory to given value -void itoa(void *num, char* buffer, int base); // itoa() - converts an integer to a string. stores in buffer so no return value. -void itoa_long(uint64_t num, char *str, int base); // itoa_long() - Dirty hack to fix a bug -char *strcpy(char *dest, const char *src); // strcpy() - copies one string to another -char toupper(char c); // toupper() - turns a character uppercase -char tolower(char c); // tolower() - turns a character lowercase -int isalpha(char ch); // isalpha() - returns if a char is in the alphabet -int strcmp(const char *str1, char *str2); // strcmp() - compares a string. -int strncmp(const char *str1, char *str2, int length); // strncmp() - compares a string for x amount of chars. -int strlen(char *str); // strlen() - checks length of a string -char *strtok(char *str, const char *delim); // strtok() - splits a string into tokens, seperated by delim. -long strtol(const char *nptr, char **endptr, int base); // strtol() - -int atoi(char *str); // atoi() - string to integer -char *strchr(char *str, int ch); // Locate the first occurance of a character in a string (credit to BrokenThorn Entertainment) -char *strchrnul(const char *str, int ch); // Locates a character in a string -size_t strcspn(const char *str1, const char *reject); // Scans str1 for the first occurence of any of the characters that are NOT part of reject. -size_t strspn(const char *str1, const char *accept); // Scans str1 for the first occurence of any of the characters that are part of accept. -char *strpbrk(const char *s, const char *b); // Returns a pointer to the first occurence of b within s. -char *strtok_r(char *str, const char *delim, char **saveptr); // Thread-safe version of strtok - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/libc/tree.h b/source/sysroot/usr/include/kernel/libc/tree.h deleted file mode 100644 index 159286e9..00000000 --- a/source/sysroot/usr/include/kernel/libc/tree.h +++ /dev/null @@ -1,45 +0,0 @@ -// tree.h - General tree implementation -// You can find this impl. here: https://github.com/stevej/osdev/blob/master/kernel/include/tree.h (FORKED FROM TOARUOS) - -#ifndef TREE_H -#define TREE_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/libc/stddef.h" // size_t -#include "include/libc/list.h" // List implementation -#include "include/mem.h" // Memory allocation - -// Typedefs -typedef struct tree_node { - void *value; - list_t *children; - struct tree_node *parent; -} tree_node_t; - -typedef struct { - size_t nodes; - struct tree_node *root; -} tree_t; - -typedef uint8_t (*tree_comparator_t) (void *, void *); - -// Functions -tree_t * tree_create(); -void tree_set_root(tree_t * tree, void * value); -void tree_node_destroy(tree_node_t * node); -void tree_destroy(tree_t * tree); -void tree_free(tree_t * tree); -tree_node_t * tree_node_create(void * value); -void tree_node_insert_child_node(tree_t * tree, tree_node_t * parent, tree_node_t * node); -tree_node_t * tree_node_insert_child(tree_t * tree, tree_node_t * parent, void * value); -tree_node_t * tree_node_find_parent(tree_node_t * haystack, tree_node_t * needle); -void tree_node_parent_remove(tree_t * tree, tree_node_t * parent, tree_node_t * node); -void tree_node_remove(tree_t * tree, tree_node_t * node); -void tree_remove(tree_t * tree, tree_node_t * node); -tree_node_t * tree_find(tree_t * tree, void * value, tree_comparator_t comparator); -void tree_break_off(tree_t * tree, tree_node_t * node); -size_t tree_count_children(tree_node_t *node); -tree_node_t *tree_find_parent(tree_t *tree, tree_node_t *node); - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/libc/udivdi3.h b/source/sysroot/usr/include/kernel/libc/udivdi3.h deleted file mode 100644 index 0b978a12..00000000 --- a/source/sysroot/usr/include/kernel/libc/udivdi3.h +++ /dev/null @@ -1,3 +0,0 @@ -// This file is here for compatibility reasons. -// If this is still here, give me a little ping in our discord: https://discord.gg/g5XwNxw3u5 -// Thanks for checking out my code! \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/libc/va_list.h b/source/sysroot/usr/include/kernel/libc/va_list.h deleted file mode 100644 index b738e89d..00000000 --- a/source/sysroot/usr/include/kernel/libc/va_list.h +++ /dev/null @@ -1,14 +0,0 @@ -// va_list.h - replacement for standard C header file. -// Why is this required? We use -ffreestanding in our compile options, so the standard std library isn't included. - -// File operates in tandem with stdarg.h (va_list declaration here, macros in stdarg.h) - -#ifndef VA_LIST_H -#define VA_LIST_H - -// Declarations - -typedef __builtin_va_list va_list; - -#endif - diff --git a/source/sysroot/usr/include/kernel/limits.h b/source/sysroot/usr/include/kernel/limits.h deleted file mode 100644 index a58a5163..00000000 --- a/source/sysroot/usr/include/kernel/limits.h +++ /dev/null @@ -1,62 +0,0 @@ -// limits.h - replacement for standard C header file. -// Why is this required? We use -ffreestanding in our compile options, so the standard std library isn't included. - -#ifndef LIMITS_H -#define LIMITS_H - -// Macro declarations. This is what limits.h mostly consists off. - -// Maximum length of a multibyte character -#define MB_LEN_MAX 16 - -// Minimum and maximum value of a signed char. -#define SCHAR_MIN (-128) -#define SCHAR_MAX (127) - -// Bits in a character. -#define CHAR_BIT 8 - -// Maximum an unsigned char can hold -#define UCHAR_MAX 255 - -// Minimum and maximum values a char can hold. Depends on unsigned or not. -#ifdef __CHAR_UNSIGNED__ -# define CHAR_MIN 0 -# define CHAR_MAX UCHAR_MAX -#else -# define CHAR_MIN SCHAR_MIN -# define CHAR_MAX SCHAR_MAX -#endif - -// Minimum and maximum values a signed short int can hold. -#define SHRT_MIN (-32768) -#define SHRT_MAX 32767 - -// Minimum and maximum values an unsigned short int can hold. Minimum is 0. -#define USHRT_MAX 65535 - -// Minimum and maximum value of a signed integer. -#define INT_MIN (-INT_MAX - 1) -#define INT_MAX 214748364 - -// Minimum and maximum values an unsigned int can hold. -#define UINT_MAX 4294967285U - -// Minimum and maximum values a signed long int can hold. -# if __WORDSIZE == 64 -# define LONG_MAX 9223372036854775807L -# else -# define LONG_MAX 2147483647L -# endif -# define LONG_MIN (-LONG_MAX - 1L) - -// Minimum and maximum values an unsigned long int can hold. -# if __WORDSIZE == 64 -# define ULONG_MAX 18446744073709551615UL -# else -# define ULONG_MAX 4294967295UL -# endif - - - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/list.h b/source/sysroot/usr/include/kernel/list.h deleted file mode 100644 index c1599969..00000000 --- a/source/sysroot/usr/include/kernel/list.h +++ /dev/null @@ -1,48 +0,0 @@ -// list.h - Just a small list implementation (shouldn't be in libc, but I don't care) -// You can find this impl. here: https://github.com/stevej/osdev/blob/master/kernel/include/list.h (FORKED FROM TOARUOS) - - -#ifndef LIST_H -#define LIST_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/libc/stddef.h" // size_t -#include "include/mem.h" // Memory functions - -// Typedefs -typedef struct node { - struct node *next; // Next node - struct node *prev; // Previous node - void *value; // Value of this node -} node_t; - - -typedef struct list { - struct node *head; - struct node *tail; - size_t length; -} list_t; - -// Macros -#define foreach(i, list) for (node_t *i = list->head; i != NULL; i = i->next) - -// Functions -void list_destroy(list_t * list); -void list_free(list_t * list); -void list_append(list_t * list, node_t * item); -void list_insert(list_t * list, void * item); -list_t * list_create(); -node_t * list_find(list_t * list, void * value); -void list_remove(list_t * list, size_t index); -void list_delete(list_t * list, node_t * node); -node_t * list_pop(list_t * list); -node_t * list_dequeue(list_t * list); -list_t * list_copy(list_t * original); -void list_merge(list_t * target, list_t * source); - -void list_append_after(list_t * list, node_t * before, node_t * node); -void list_insert_after(list_t * list, node_t * before, void * item); - - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/local_apic.h b/source/sysroot/usr/include/kernel/local_apic.h deleted file mode 100644 index d5cba908..00000000 --- a/source/sysroot/usr/include/kernel/local_apic.h +++ /dev/null @@ -1,77 +0,0 @@ -// local_apic.h - Initializes the local APIC - -#ifndef LOCAL_APIC_H -#define LOCAL_APIC_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/hal.h" // Hardware abstraction layer - -// Definitions -#define LOCAL_APIC_ID 0x0020 -#define LOCAL_APIC_VER 0x0030 -#define LOCAL_APIC_TPR 0x0080 -#define LOCAL_APIC_APR 0x0090 -#define LOCAL_APIC_PPR 0x00A0 -#define LOCAL_APIC_EOI 0x00B0 -#define LOCAL_APIC_RRD 0x00C0 -#define LOCAL_APIC_LDR 0x00D0 -#define LOCAL_APIC_DFR 0x00E0 -#define LOCAL_APIC_SVR 0x00f0 -#define LOCAL_APIC_ISR 0x0100 -#define LOCAL_APIC_TMR 0x0180 -#define LOCAL_APIC_IRR 0x0200 -#define LOCAL_APIC_ESR 0x0280 -#define LOCAL_APIC_ICRLO 0x0300 -#define LOCAL_APIC_ICRHI 0x0310 -#define LOCAL_APIC_TIMER 0x0320 -#define LOCAL_APIC_THERMAL 0x0330 -#define LOCAL_APIC_PERF 0x0340 -#define LOCAL_APIC_LINT0 0x0350 -#define LOCAL_APIC_LINT1 0x0360 -#define LOCAL_APIC_ERROR 0x0370 -#define LOCAL_APIC_TICR 0x0380 -#define LOCAL_APIC_TCCR 0x0390 -#define LOCAL_APIC_TDCR 0x03e0 - -// https://github.com/pdoane/osdev/blob/master/intr/local_apic.c -// Delivery Mode -#define ICR_FIXED 0x00000000 -#define ICR_LOWEST 0x00000100 -#define ICR_SMI 0x00000200 -#define ICR_NMI 0x00000400 -#define ICR_INIT 0x00000500 -#define ICR_STARTUP 0x00000600 - -// Destination Mode -#define ICR_PHYSICAL 0x00000000 -#define ICR_LOGICAL 0x00000800 - -// Delivery Status -#define ICR_IDLE 0x00000000 -#define ICR_SEND_PENDING 0x00001000 - -// Level -#define ICR_DEASSERT 0x00000000 -#define ICR_ASSERT 0x00004000 - -// Trigger Mode -#define ICR_EDGE 0x00000000 -#define ICR_LEVEL 0x00008000 - -// Destination Shorthand -#define ICR_NO_SHORTHAND 0x00000000 -#define ICR_SELF 0x00040000 -#define ICR_ALL_INCLUDING_SELF 0x00080000 -#define ICR_ALL_EXCLUDING_SELF 0x000c0000 - -// Destination Field -#define ICR_DESTINATION_SHIFT 24 - -// Functions -void localAPIC_init(); // Initialize the local APIC -uint8_t localAPIC_getID(); // returns the ID of the local APIC -void localAPIC_sendInit(uint8_t apicID); // Sends an init request to local APIC. -void localAPIC_sendStartup(uint8_t apicID, uint8_t vector); // Sends a startup request to an APIC with a vector. - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/mem.h b/source/sysroot/usr/include/kernel/mem.h deleted file mode 100644 index 07536f2b..00000000 --- a/source/sysroot/usr/include/kernel/mem.h +++ /dev/null @@ -1,18 +0,0 @@ -// mem.h - A header file for the entire memory management system -// It's not much, just a forwarder to the actual stuff ;) - -#ifndef MEM_H -#define MEM_H - -#include "include/liballoc_forwarder.h" - - -extern void *kmalloc(size_t); -extern void *krealloc(void *, size_t); -extern void *kcalloc(size_t, size_t); -extern void kfree(void *); - - - - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/ordered_array.h b/source/sysroot/usr/include/kernel/ordered_array.h deleted file mode 100644 index 24d4067e..00000000 --- a/source/sysroot/usr/include/kernel/ordered_array.h +++ /dev/null @@ -1,24 +0,0 @@ -// ordered_array.h - header file for ordered_array.c (ordered array stuff) -// This implementation is based on James Molloy's kernel development tutorials (http://www.jamesmolloy.co.uk/tutorial_html/7.-The%20Heap.html) - -#ifndef ORDERED_ARRAY_H -#define ORDERED_ARRAY_H - -// Includes -#include -#include // Assert macro -#include - -// Typedefs - - -// Functions -int8_t standard_lessthan_predicate(type_t a, type_t b); // A standard less-than predicate -ordered_array_t createOrderedArray(uint32_t maxSize, lessthan_predicate less_than); // Create an ordered array -ordered_array_t placeOrderedArray(void* addr, uint32_t maxSize, lessthan_predicate less_than); // Place an ordered array -void destroyOrderedArray(ordered_array_t* array); // Destroy an ordered array -void insertOrderedArray(type_t item, ordered_array_t* array); // Insert an item into an ordered array. -type_t lookupOrderedArray(uint32_t i, ordered_array_t* array); // Lookup an item at index i in ordered array array. -void removeOrderedArray(uint32_t i, ordered_array_t* array); // Remove an item at index i in ordered array array. - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/ordered_array_t.h b/source/sysroot/usr/include/kernel/ordered_array_t.h deleted file mode 100644 index 0b469368..00000000 --- a/source/sysroot/usr/include/kernel/ordered_array_t.h +++ /dev/null @@ -1,20 +0,0 @@ -// ordered_array_t.h - Contains the definition for ordered_array_t -#ifndef ORDERED_ARRAY_T_H -#define ORDERED_ARRAY_T_H - -#include - -typedef void* type_t; // This array is insertion sorted, meaning it always remains in a sorted state between calls. - -typedef int8_t (*lessthan_predicate)(type_t, type_t); // A predicate should return non-zero if the first arg is less than the second. Else, it will return 0. - - -// The actual ordered array. -typedef struct { - type_t *array; - uint32_t size; - uint32_t maxSize; - lessthan_predicate less_than; -} ordered_array_t; - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/panic.h b/source/sysroot/usr/include/kernel/panic.h deleted file mode 100644 index ee7a3e65..00000000 --- a/source/sysroot/usr/include/kernel/panic.h +++ /dev/null @@ -1,20 +0,0 @@ -// panic.h - kernel panic handling - -#ifndef PANIC_H -#define PANIC_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations like uint8_t. -#include "include/libc/stdbool.h" // Booleans -#include "include/terminal.h" // Terminal functions, like printf -#include "include/hal.h" // Hardware Abstraction Layer -#include "include/regs.h" // registers_t typedef -#include "include/serial.h" // Serial logging -#include "include/CONFIG.h" // Configuration - -// Functions -void *panic(char *caller, char *code, char *reason); -void *panicReg(char *caller, char *code, char *reason, registers_t *reg); -void *pageFault(registers_t *reg); - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/pci.h b/source/sysroot/usr/include/kernel/pci.h deleted file mode 100644 index dd5d6a35..00000000 --- a/source/sysroot/usr/include/kernel/pci.h +++ /dev/null @@ -1,100 +0,0 @@ -// pci.h - header file for pci.c (handles the peripheral component interconnect bus) - -#ifndef PCI_H -#define PCI_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations. - -#include "include/hal.h" // outportl and inportl -#include "include/terminal.h" // printf -#include "include/pci_vendors.h" - -// Definitions -#define PCI_CONFIG_ADDR 0xCF8 // PCI_CONFIG_ADDR specifies the configuration address required to be accessed. -#define PCI_CONFIG_DATA 0xCFC // PCI_CONFIG_DATA specifies the configuration address generate the config address and transfers data to/from the CONFIG_DATA register. - -#define PCI_MAX_BUS 16 -#define PCI_MAX_SLOTS 32 - -#define PCI_OFFSET_VENDORID 0x00 -#define PCI_OFFSET_DEVICEID 0x02 -#define PCI_OFFSET_COMMAND 0x04 -#define PCI_OFFSET_STATUS 0x06 -#define PCI_OFFSET_REVISION 0x08 - -#define PCI_OFFSET_PROGIF 0x09 -#define PCI_OFFSET_SUBCLASSID 0x0A -#define PCI_OFFSET_CLASSID 0x0B -#define PCI_OFFSET_CACHELINESIZE 0x0C -#define PCI_OFFSET_LATENCY 0x0D -#define PCI_OFFSET_HEADERTYPE 0x0E -#define PCI_OFFSET_BIST 0x0F -#define PCI_OFFSET_BAR0 0x10 -#define PCI_OFFSET_BAR1 0x14 -#define PCI_OFFSET_BAR2 0x18 -#define PCI_OFFSET_BAR3 0x1C -#define PCI_OFFSET_BAR4 0x20 -#define PCI_OFFSET_BAR5 0x24 - -#define PCI_INTERRUPT_LINE 0x3C -#define PCI_INTERRUPT_PIN 0x3D - -#define PCI_SECONDARY_BUS 0x19 - -#define PCI_HEADERTYPE_DEVICE 0 -#define PCI_HEADERTYPE_BRIDGE 1 -#define PCI_HEADERTYPE_CARDBUS 2 - -#define PCI_TYPE_BRIDGE 0x0604 -#define PCI_TYPE_SATA 0x0106 - -#define PCI_NONE 0xFFFF - - - -// Typedefs - -struct __pciDriver; // Hack to make pciDevice work - -typedef struct { - uint32_t bus; - uint32_t slot; - uint32_t vendor; - uint32_t device; - uint32_t func; - struct __pciDriver *driver; -} pciDevice; - -typedef struct { - uint32_t vendor; - uint32_t device; - uint32_t func; -} pciDeviceID; - -typedef struct __pciDriver { - pciDeviceID devId; - char *deviceName; - uint8_t (*initDevice)(pciDevice*); - uint8_t (*initDriver)(void); - uint8_t (*stopDriver)(void); -} pciDriver; - - -typedef void (*pciFunction_t)(uint32_t device, uint16_t vendor_id, uint16_t device_id, void * extra); - -// Macros -#define PCI_BUS(device) (uint8_t)((device >> 16)) -#define PCI_SLOT(device) (uint8_t)((device >> 8)) -#define PCI_FUNC(device) (uint8_t)(device) -#define PCI_ADDR(device, field) (0x80000000 | (PCI_BUS(device) << 16) | (PCI_SLOT(device) << 11) | (PCI_FUNC(device) << 8) | ((field) & 0xFC)) - - - -// Functions - -void initPCI(); // Initializes the PCI environment (probes devices and stuff) -void printPCIInfo(); // Prints PCI info -uint32_t pciConfigReadField(uint32_t device, int field, int size); // A simplified version of pciConfigRead() that will take 3 parameters and read from a PCI device config space field. -void pciScan(pciFunction_t func, int type, void *extra); // Scans the PCI buses for devices (used to implement device discovery) -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/pci_vendors.h b/source/sysroot/usr/include/kernel/pci_vendors.h deleted file mode 100644 index 43dc1f5e..00000000 --- a/source/sysroot/usr/include/kernel/pci_vendors.h +++ /dev/null @@ -1,1830 +0,0 @@ -// pci_vendors.h - Contains a list of all PCI vendors. -// I DID NOT MAKE THIS FILE - THE ORIGINAL SOURCE I GOT IT FROM (possibly not the OG source of the list) WAS HERE: https://github.com/RWTH-OS/eduOS/blob/master/arch/x86/kernel/pcihdr.h - - - -typedef struct _PCI_VENTABLE -{ - /// Vendor ID - unsigned short VenId ; - /// Short vendor name string - char * VenShort ; - /// Full vendor nae string - char * VenFull ; -} PCI_VENTABLE, *PPCI_VENTABLE ; - -static const PCI_VENTABLE PciVenTable [] = -{ - { 0x003D, "Lockheed Martin", "Lockheed Martin Corp" } , - { 0x0E11, "Compaq", "Compaq" } , - { 0x1000, "LSI", "LSI Logic" } , - { 0x1001, "KOLTER", "Kolter Electronic - Germany" } , - { 0x1002, "ATI", "ATI Technologies" } , - { 0x1003, "ULSI", "ULSI" } , - { 0x1004, "VLSI", "VLSI Technology" } , - { 0x1005, "Avance", "Avance Logic Inc." } , - { 0x1006, "Reply", "Reply Group" } , - { 0x1007, "NetFrame", "Netframe Systems" } , - { 0x1008, "Epson", "Epson" } , - { 0x100A, "Phoenix", "Phoenix Technologies Ltd." } , - { 0x100B, "NSC", "National Semiconductor" } , - { 0x100C, "Tseng", "Tseng Labs" } , - { 0x100D, "AST", "AST Research" } , - { 0x100E, "Weitek", "Weitek" } , - { 0x1010, "VLogic", "Video Logic Ltd." } , - { 0x1011, "DEC", "Digital Equipment Corporation" } , - { 0x1012, "Micronics", "Micronics Computers Inc." } , - { 0x1013, "Cirrus", "Cirrus Logic" } , - { 0x1014, "IBM", "IBM" } , - { 0x1015, "LSIL", "LSI Logic Corp of Canada" } , - { 0x1016, "Fujitsu ICL", "Fujitsu ICL Computers" } , - { 0x1017, "Spea", "Spea Software AG" } , - { 0x1018, "Unisys", "Unisys Systems" } , - { 0x1019, "ECS", "Elitegroup Computer Sys" } , - { 0x101A, "NCR", "NCR/AT&T GIS" } , - { 0x101B, "Vitesse", "Vitesse Semiconductor" } , - { 0x101C, "WD", "Western Digital" } , - { 0x101E, "AMI", "American Megatrends Inc." } , - { 0x101F, "PictureTel", "PictureTel Corp." } , - { 0x1020, "Hitachi", "Hitachi Computer Electronics" } , - { 0x1021, "OKI", "Oki Electric Industry" } , - { 0x1022, "AMD", "Advanced Micro Devices" } , - { 0x1023, "Trident", "Trident Microsystems" } , - { 0x1024, "Zenith", "Zenith Data Systems" } , - { 0x1025, "Acer", "Acer Incorporated" } , - { 0x1028, "Dell", "Dell Computer Corporation" } , - { 0x1029, "Siem-Nix", "Siemens Nixdorf AG" } , - { 0x102A, "LSI", "LSI Logic Headland Div" } , - { 0x102B, "Matrox", "Matrox" } , - { 0x102C, "C&T", "Chips And Technologies" } , - { 0x102D, "Wyse", "Wyse Technologies" } , - { 0x102E, "Olivetti", "Olivetti Advanced Technology" } , - { 0x102F, "Toshiba", "Toshiba America" } , - { 0x1030, "TMC", "TMC Research" } , - { 0x1031, "miro", "miro Computer Products AG" } , - { 0x1032, "Compaq", "Compaq" } , - { 0x1033, "NEC", "NEC Corporation" } , - { 0x1034, "Burndy", "Burndy Corporation" } , - { 0x1035, "C&CRL", "Computer&Communication Research Lab" } , - { 0x1036, "FDomain", "Future Domain" } , - { 0x1037, "Hitachi", "Hitachi Micro Systems Inc" } , - { 0x1038, "AMP", "AMP Incorporated" } , - { 0x1039, "SIS", "Silicon Integrated System" } , - { 0x103A, "Seiko", "Seiko Epson Corporation" } , - { 0x103B, "Tatung", "Tatung Corp. Of America" } , - { 0x103C, "HP", "Hewlett-Packard Company" } , - { 0x103E, "Solliday", "Solliday Engineering" } , - { 0x103F, "Logic Mod.", "Logic Modeling" } , - { 0x1040, "Kubota", "Kubota Pacific Computer Inc." } , - { 0x1041, "Computrend", "Computrend" } , - { 0x1042, "PC Tech.", "PC Technology" } , - { 0x1043, "Asustek", "Asustek Computer Inc." } , - { 0x1044, "DPT", "Distributed Processing Tech" } , - { 0x1045, "OPTi", "OPTi" } , - { 0x1046, "IPC", "IPC Corporation LTD" } , - { 0x1047, "Genoa", "Genoa Systems Corp." } , - { 0x1048, "ELSA", "ELSA AG" } , - { 0x1049, "Fountain", "Fountain Technology" } , - { 0x104A, "STM", "ST Microelectronics" } , - { 0x104B, "Mylex", "Mylex Corporation" } , - { 0x104C, "TI", "Texas Instruments" } , - { 0x104D, "Sony", "Sony Corporation" } , - { 0x104E, "Oak", "Oak Technology" } , - { 0x104F, "Co-Time", "Co-Time Computer Ltd." } , - { 0x1050, "Winbond", "Winbond Electronics Corp." } , - { 0x1051, "Anigma", "Anigma Corp." } , - { 0x1052, "Young", "Young Micro Systems" } , - { 0x1054, "Hitachi", "Hitachi LTD" } , - { 0x1055, "EFAR", "EFAR Microsystems" } , - { 0x1056, "ICL", "ICL" } , - { 0x1057, "Motorola", "Motorola" } , - { 0x1058, "E&TR", "Electronics & Telecommunication Res" } , - { 0x1059, "Teknor", "Teknor Microsystems" } , - { 0x105A, "Promise", "Promise Technology" } , - { 0x105B, "Foxconn", "Foxconn International" } , - { 0x105C, "Wipro", "Wipro Infotech Limited" } , - { 0x105D, "Number-Nine", "Number Nine Visual Technology" } , - { 0x105E, "Vtech", "Vtech Engineering Canada Ltd." } , - { 0x105F, "Infotronic", "Infotronic America Inc." } , - { 0x1060, "UMC", "United Microelectronics" } , - { 0x1061, "8x8", "8x8 Inc." } , - { 0x1062, "Maspar", "Maspar Computer Corp." } , - { 0x1063, "OOA", "Ocean Office Automation" } , - { 0x1064, "Alcatel", "Alcatel Cit" } , - { 0x1065, "TM", "Texas Microsystems" } , - { 0x1066, "Picopower", "Picopower Technology" } , - { 0x1067, "Mitsubishi", "Mitsubishi Electronics" } , - { 0x1068, "Div. Tech.", "Diversified Technology" } , - { 0x1069, "Mylex", "Mylex Corporation" } , - { 0x106A, "Aten", "Aten Research Inc." } , - { 0x106B, "Apple", "Apple Computer Inc." } , - { 0x106C, "Hyundai", "Hyundai Electronics America" } , - { 0x106D, "Sequent", "Sequent" } , - { 0x106E, "DFI", "DFI Inc." } , - { 0x106F, "CityGate", "City Gate Development LTD" } , - { 0x1070, "Daewoo", "Daewoo Telecom Ltd." } , - { 0x1071, "Mitac", "Mitac" } , - { 0x1072, "GIT", "GIT Co. Ltd." } , - { 0x1073, "Yamaha", "Yamaha Corporation" } , - { 0x1074, "Nexgen", "Nexgen Microsysteme" } , - { 0x1075, "AIR", "Advanced Integration Research" } , - { 0x1076, "Chaintech", "Chaintech Computer Co. Ltd." } , - { 0x1077, "Q Logic", "Q Logic" } , - { 0x1078, "Cyrix", "Cyrix Corporation" } , - { 0x1079, "I-Bus", "I-Bus" } , - { 0x107A, "Networth", "Networth" } , - { 0x107B, "Gateway", "Gateway 2000" } , - { 0x107C, "Goldstar", "Goldstar Co. Ltd." } , - { 0x107D, "Leadtek", "Leadtek Research" } , - { 0x107E, "Interphase", "Interphase Corporation" } , - { 0x107F, "DTC", "Data Technology Corporation" } , - { 0x1080, "Contaq", "Contaq Microsystems" } , - { 0x1081, "Supermac", "Supermac Technology Inc." } , - { 0x1082, "EFA", "EFA Corporation Of America" } , - { 0x1083, "Forex", "Forex Computer Corporation" } , - { 0x1084, "Parador", "Parador" } , - { 0x1085, "Tulip", "Tulip Computers Int'l BV" } , - { 0x1086, "J. Bond", "J. Bond Computer Systems" } , - { 0x1087, "Cache", "Cache Computer" } , - { 0x1088, "MS Son", "Microcomputer Systems (M) Son" } , - { 0x1089, "DG", "Data General Corporation" } , - { 0x108A, "Bit3", "Bit3 Computer" } , - { 0x108C, "Elonex", "Elonex PLC c/o Oakleigh Systems Inc." } , - { 0x108D, "Olicom", "Olicom" } , - { 0x108E, "Sun", "Sun Microsystems" } , - { 0x108F, "Systemsoft", "Systemsoft Corporation" } , - { 0x1090, "Encore", "Encore Computer Corporation" } , - { 0x1091, "Intergraph", "Intergraph Corporation" } , - { 0x1092, "Diamond", "Diamond Computer Systems" } , - { 0x1093, "Nat. Inst.", "National Instruments" } , - { 0x1094, "FIC", "First Int'l Computers" } , - { 0x1095, "CMD", "CMD Technology Inc." } , - { 0x1096, "Alacron", "Alacron" } , - { 0x1097, "Appian", "Appian Graphics" } , - { 0x1098, "Quantum", "Quantum Designs Ltd." } , - { 0x1099, "Samsung", "Samsung Electronics Co. Ltd." } , - { 0x109A, "Packard-Bell", "Packard Bell" } , - { 0x109B, "Gemlight", "Gemlight Computer Ltd." } , - { 0x109C, "Megachips", "Megachips Corporation" } , - { 0x109D, "Zida", "Zida Technologies Ltd." } , - { 0x109E, "Brooktree", "Brooktree Corporation" } , - { 0x109F, "Trigem", "Trigem Computer Inc." } , - { 0x10A0, "Meidensha", "Meidensha Corporation" } , - { 0x10A1, "Juko", "Juko Electronics Inc. Ltd." } , - { 0x10A2, "Quantum", "Quantum Corporation" } , - { 0x10A3, "Everex", "Everex Systems Inc." } , - { 0x10A4, "Globe", "Globe Manufacturing Sales" } , - { 0x10A5, "Racal", "Racal Interlan" } , - { 0x10A6, "Informtech", "Informtech Industrial Ltd." } , - { 0x10A7, "Benchmarq", "Benchmarq Microelectronics" } , - { 0x10A8, "Sierra", "Sierra Semiconductor" } , - { 0x10A9, "SG", "Silicon Graphics" } , - { 0x10AA, "ACC", "ACC Microelectronics" } , - { 0x10AB, "Digicom", "Digicom" } , - { 0x10AC, "Honeywell", "Honeywell IASD" } , - { 0x10AD, "Symphony", "Symphony Labs" } , - { 0x10AE, "Cornerstone", "Cornerstone Technology" } , - { 0x10AF, "MCS", "Micro Computer Systems Inc." } , - { 0x10B0, "Cardexpert", "Cardexpert Technology" } , - { 0x10B1, "Cabletron", "Cabletron Systems Inc." } , - { 0x10B2, "Raytheon", "Raytheon Company" } , - { 0x10B3, "Databook", "Databook Inc." } , - { 0x10B4, "STB", "STB Systems" } , - { 0x10B5, "PLX", "PLX Technology" } , - { 0x10B6, "Madge", "Madge Networks" } , - { 0x10B7, "3Com", "3Com Corporation" } , - { 0x10B8, "Standard", "Standard Microsystems" } , - { 0x10B9, "ALI", "Acer Labs Inc." } , - { 0x10BA, "Mitsubishi", "Mitsubishi Electronics Corp." } , - { 0x10BB, "Dapha", "Dapha Electronics Corporation" } , - { 0x10BC, "ALR", "Advanced Logic Research Inc." } , - { 0x10BD, "Surecom", "Surecom Technology" } , - { 0x10BE, "Tseng", "Tsenglabs International Corp." } , - { 0x10BF, "MOST", "MOST Corp." } , - { 0x10C0, "Boca", "Boca Research Inc." } , - { 0x10C1, "ICM", "ICM Corp. Ltd." } , - { 0x10C2, "Auspex", "Auspex Systems Inc." } , - { 0x10C3, "Samsung", "Samsung Semiconductors" } , - { 0x10C4, "Award", "Award Software Int'l Inc." } , - { 0x10C5, "Xerox", "Xerox Corporation" } , - { 0x10C6, "Rambus", "Rambus Inc." } , - { 0x10C7, "Media Vision", "Media Vision" } , - { 0x10C8, "Neomagic", "Neomagic Corporation" } , - { 0x10C9, "Dataexpert", "Dataexpert Corporation" } , - { 0x10CA, "Fujitsu", "Fujitsu" } , - { 0x10CB, "Omron", "Omron Corporation" } , - { 0x10CC, "Mentor", "Mentor Arc Inc." } , - { 0x10CD, "AdvanSys", "Advanced System Products" } , - { 0x10CE, "Radius", "Radius Inc." } , - { 0x10CF, "TTI", "Citicorp TTI" } , - { 0x10D0, "Fujitsu", "Fujitsu Limited" } , - { 0x10D1, "Future+", "Future+ Systems" } , - { 0x10D2, "Molex", "Molex Incorporated" } , - { 0x10D3, "Jabil", "Jabil Circuit Inc." } , - { 0x10D4, "Hualon", "Hualon Microelectronics" } , - { 0x10D5, "Autologic", "Autologic Inc." } , - { 0x10D6, "Cetia", "Cetia" } , - { 0x10D7, "BCM", "BCM Advanced Research" } , - { 0x10D8, "APL", "Advanced Peripherals Labs" } , - { 0x10D9, "Macronix", "Macronix International Co. Ltd." } , - { 0x10DA, "T-C", "Thomas-Conrad Corporation" } , - { 0x10DB, "Rohm", "Rohm Research" } , - { 0x10DC, "CERN", "CERN-European Lab. for Particle Physics" } , - { 0x10DD, "E&S", "Evans & Sutherland" } , - { 0x10DE, "Nvidia", "Nvidia Corporation" } , - { 0x10DF, "Emulex", "Emulex Corporation" } , - { 0x10E0, "IMS", "Integrated Micro Solutions" } , - { 0x10E1, "Tekram", "Tekram Technology Corp. Ltd." } , - { 0x10E2, "Aptix", "Aptix Corporation" } , - { 0x10E3, "Tundra", "Tundra Semiconductor Corp." } , - { 0x10E4, "Tandem", "Tandem Computers" } , - { 0x10E5, "MIC", "Micro Industries Corporation" } , - { 0x10E6, "Gainbery", "Gainbery Computer Products Inc." } , - { 0x10E7, "Vadem", "Vadem" } , - { 0x10E8, "AMCC", "Applied Micro Circuits Corp." } , - { 0x10E9, "Alps", "Alps Electronic Corp. Ltd." } , - { 0x10EA, "Intergraphics", "Integraphics Systems" } , - { 0x10EB, "Artist", "Artist Graphics" } , - { 0x10EC, "Realtek", "Realtek Semiconductor" } , - { 0x10ED, "Ascii", "Ascii Corporation" } , - { 0x10EE, "Xilinx", "Xilinx Corporation" } , - { 0x10EF, "Racore", "Racore Computer Products" } , - { 0x10F0, "Peritek", "Peritek Corporation" } , - { 0x10F1, "Tyan", "Tyan Computer" } , - { 0x10F2, "Achme", "Achme Computer Inc." } , - { 0x10F3, "Alaris", "Alaris Inc." } , - { 0x10F4, "S-Mos", "S-Mos Systems" } , - { 0x10F5, "NKK", "NKK Corporation" } , - { 0x10F6, "Creative", "Creative Electronic Systems SA" } , - { 0x10F7, "Matsushita", "Matsushita Electric Industrial Corp." } , - { 0x10F8, "Altos", "Altos India Ltd." } , - { 0x10F9, "PC-Direct", "PC Direct" } , - { 0x10FA, "Truevision", "Truevision" } , - { 0x10FB, "Thesys", "Thesys Microelectronic's" } , - { 0x10FC, "I-O", "I-O Data Device Inc." } , - { 0x10FD, "Soyo", "Soyo Technology Corp. Ltd." } , - { 0x10FE, "Fast", "Fast Electronic GmbH" } , - { 0x10FF, "Ncube", "Ncube" } , - { 0x1100, "Jazz", "Jazz Multimedia" } , - { 0x1101, "Initio", "Initio Corporation" } , - { 0x1102, "Creative Labs", "Creative Labs" } , - { 0x1103, "Triones", "Triones Technologies Inc." } , - { 0x1104, "Rasterops", "Rasterops" } , - { 0x1105, "Sigma", "Sigma Designs Inc." } , - { 0x1106, "VIA", "VIA Technologies Inc" } , - { 0x1107, "Stratus", "Stratus Computer" } , - { 0x1108, "Proteon", "Proteon Inc." } , - { 0x1109, "Cogent", "Cogent Data Technologies" } , - { 0x110A, "Siemens", "Siemens AG / Siemens Nixdorf AG" } , - { 0x110B, "Chromatic", "Chromatic Research Inc" } , - { 0x110C, "Mini-Max", "Mini-Max Technology Inc." } , - { 0x110D, "ZNYX", "ZNYX Corporation" } , - { 0x110E, "CPU Tech.", "CPU Technology" } , - { 0x110F, "Ross", "Ross Technology" } , - { 0x1110, "Powerhouse", "Powerhouse Systems" } , - { 0x1111, "SCO", "Santa Cruz Operation" } , - { 0x1112, "Osicom", "Osicom Technologies Inc." } , - { 0x1113, "Accton", "Accton Technology Corporation" } , - { 0x1114, "Atmel", "Atmel Corp." } , - { 0x1115, "Dupont", "Dupont Pixel Systems Ltd." } , - { 0x1116, "Data Trans.", "Data Translation" } , - { 0x1117, "Datacube", "Datacube Inc." } , - { 0x1118, "Berg", "Berg Electronics" } , - { 0x1119, "Vortex", "Vortex Computersysteme GmbH" } , - { 0x111A, "Eff. Net.", "Efficent Networks" } , - { 0x111B, "Teledyne", "Teledyne Electronic Systems" } , - { 0x111C, "Tricord", "Tricord Systems Inc." } , - { 0x111D, "IDT", "Integrated Device Technology Inc." } , - { 0x111E, "Eldec", "Eldec Corp." } , - { 0x111F, "PDI", "Precision Digital Images" } , - { 0x1120, "EMC", "EMC Corp." } , - { 0x1121, "Zilog", "Zilog" } , - { 0x1122, "Multi-Tech", "Multi-Tech Systems Inc." } , - { 0x1123, "EDI", "Excellent Design Inc." } , - { 0x1124, "Leutron", "Leutron Vision AG" } , - { 0x1125, "Eurocore", "Eurocore/Vigra" } , - { 0x1126, "Vigra", "Vigra" } , - { 0x1127, "FORE", "FORE Systems" } , - { 0x1129, "Firmworks", "Firmworks" } , - { 0x112A, "Hermes", "Hermes Electronics Co. Ltd." } , - { 0x112B, "Linotype", "Linotype - Hell AG" } , - { 0x112C, "Zenith", "Zenith Data Systems" } , - { 0x112D, "Ravicad", "Ravicad" } , - { 0x112E, "Infomedia", "Infomedia" } , - { 0x112F, "ImagTech", "Imaging Technology" } , - { 0x1130, "Computervision", "Computervision" } , - { 0x1131, "Philips", "Philips Semiconductors" } , - { 0x1132, "Mitel", "Mitel Corp." } , - { 0x1133, "EIC", "Eicon Technology Corporation" } , - { 0x1134, "MCS", "Mercury Computer Systems Inc." } , - { 0x1135, "Fuji", "Fuji Xerox Co Ltd" } , - { 0x1136, "Momentum", "Momentum Data Systems" } , - { 0x1137, "Cisco", "Cisco Systems Inc" } , - { 0x1138, "Ziatech", "Ziatech Corporation" } , - { 0x1139, "Dyn. Pict.", "Dynamic Pictures Inc" } , - { 0x113A, "FWB", "FWB Inc" } , - { 0x113B, "NCD", "Network Computing Devices" } , - { 0x113C, "Cyclone", "Cyclone Microsystems" } , - { 0x113D, "Leading Edge", "Leading Edge Products Inc" } , - { 0x113E, "Sanyo", "Sanyo Electric Co" } , - { 0x113F, "Equinox", "Equinox Systems" } , - { 0x1140, "Intervoice", "Intervoice Inc" } , - { 0x1141, "Crest", "Crest Microsystem Inc" } , - { 0x1142, "Alliance", "Alliance Semiconductor CA - USA" } , - { 0x1143, "Netpower", "Netpower Inc" } , - { 0x1144, "Cinn. Mil.", "Cincinnati Milacron" } , - { 0x1145, "Workbit", "Workbit Corp" } , - { 0x1146, "Force", "Force Computers" } , - { 0x1147, "Interface", "Interface Corp" } , - { 0x1148, "S&K", "Schneider & Koch" } , - { 0x1149, "Win System", "Win System Corporation" } , - { 0x114A, "VMIC", "VMIC" } , - { 0x114B, "Canopus", "Canopus Co. Ltd" } , - { 0x114C, "Annabooks", "Annabooks" } , - { 0x114D, "IC Corp.", "IC Corporation" } , - { 0x114E, "Nikon", "Nikon Systems Inc" } , - { 0x114F, "Stargate", "Stargate" } , - { 0x1150, "TMC", "Thinking Machines Corporation" } , - { 0x1151, "JAE", "JAE Electronics Inc." } , - { 0x1152, "Megatek", "Megatek" } , - { 0x1153, "Land Win", "Land Win Electronic Corp" } , - { 0x1154, "Melco", "Melco Inc" } , - { 0x1155, "Pine", "Pine Technology Ltd" } , - { 0x1156, "Periscope", "Periscope Engineering" } , - { 0x1157, "Avsys", "Avsys Corporation" } , - { 0x1158, "Voarx", "Voarx R&D Inc" } , - { 0x1159, "Mutech", "Mutech" } , - { 0x115A, "Harlequin", "Harlequin Ltd" } , - { 0x115B, "Parallax", "Parallax Graphics" } , - { 0x115C, "Photron", "Photron Ltd." } , - { 0x115D, "Xircom", "Xircom" } , - { 0x115E, "Peer", "Peer Protocols Inc" } , - { 0x115F, "Maxtor", "Maxtor Corporation" } , - { 0x1160, "Megasoft", "Megasoft Inc" } , - { 0x1161, "PFU", "PFU Ltd" } , - { 0x1162, "OA Lab", "OA Laboratory Co Ltd" } , - { 0x1163, "Rendition", "Rendition Inc" } , - { 0x1164, "APT", "Advanced Peripherals Tech" } , - { 0x1165, "Imagraph", "Imagraph Corporation" } , - { 0x1166, "Pequr", "Pequr Technology Inc." } , - { 0x1167, "Mutoh", "Mutoh Industries Inc" } , - { 0x1168, "Thine", "Thine Electronics Inc" } , - { 0x1169, "CDAC", "Centre f/Dev. of Adv. Computing" } , - { 0x116A, "Polaris", "Polaris Communications" } , - { 0x116B, "Connectware", "Connectware Inc" } , - { 0x116C, "Int Res.", "Intelligent Resources" } , - { 0x116E, "EFI", "Electronics for Imaging" } , - { 0x116F, "WkSta. Tech.", "Workstation Technology" } , - { 0x1170, "Inventec", "Inventec Corporation" } , - { 0x1171, "Lough. Sound", "Loughborough Sound Images" } , - { 0x1172, "Altera", "Altera Corporation" } , - { 0x1173, "Adobe", "Adobe Systems" } , - { 0x1174, "Bridgeport", "Bridgeport Machines" } , - { 0x1175, "Mitron", "Mitron Computer Inc." } , - { 0x1176, "SBE", "SBE" } , - { 0x1177, "Silicon Eng.", "Silicon Engineering" } , - { 0x1178, "Alfa", "Alfa Inc" } , - { 0x1179, "Toshiba", "Toshiba America Info Systems" } , - { 0x117A, "A-Trend", "A-Trend Technology" } , - { 0x117B, "LG Elec.", "LG Electronics Inc." } , - { 0x117C, "Atto", "Atto Technology" } , - { 0x117D, "B&D", "Becton & Dickinson" } , - { 0x117E, "T/R", "T/R Systems" } , - { 0x117F, "ICS", "Integrated Circuit Systems" } , - { 0x1180, "Ricoh", "Ricoh Co Ltd" } , - { 0x1181, "Telmatics", "Telmatics International" } , - { 0x1183, "Fujikura", "Fujikura Ltd" } , - { 0x1184, "Forks", "Forks Inc" } , - { 0x1185, "Dataworld", "Dataworld" } , - { 0x1186, "D-Link", "D-Link System Inc" } , - { 0x1187, "ATL", "Advanced Technology Laboratories" } , - { 0x1188, "Shima", "Shima Seiki Manufacturing Ltd." } , - { 0x1189, "Matsushita", "Matsushita Electronics" } , - { 0x118A, "Hilevel", "Hilevel Technology" } , - { 0x118B, "Hypertec", "Hypertec Pty Ltd" } , - { 0x118C, "Corollary", "Corollary Inc" } , - { 0x118D, "BitFlow", "BitFlow Inc" } , - { 0x118E, "Hermstedt", "Hermstedt GmbH" } , - { 0x118F, "Green", "Green Logic" } , - { 0x1191, "Artop", "Artop Electric" } , - { 0x1192, "Densan", "Densan Co. Ltd" } , - { 0x1193, "Zeitnet", "Zeitnet Inc." } , - { 0x1194, "Toucan", "Toucan Technology" } , - { 0x1195, "Ratoc", "Ratoc System Inc" } , - { 0x1196, "Hytec", "Hytec Electronics Ltd" } , - { 0x1197, "Gage", "Gage Applied Sciences Inc." } , - { 0x1198, "Lambda", "Lambda Systems Inc" } , - { 0x1199, "Attachmate", "Attachmate Corp." } , - { 0x119A, "Mind Share", "Mind Share Inc." } , - { 0x119B, "Omega", "Omega Micro Inc." } , - { 0x119C, "ITI", "Information Technology Inst." } , - { 0x119D, "Bug", "Bug Sapporo Japan" } , - { 0x119E, "Fujitsu", "Fujitsu" } , - { 0x119F, "Bull", "Bull Hn Information Systems" } , - { 0x11A0, "Convex", "Convex Computer Corporation" } , - { 0x11A1, "Hamamatsu", "Hamamatsu Photonics K.K." } , - { 0x11A2, "Sierra", "Sierra Research and Technology" } , - { 0x11A3, "Deuretzbacher", "Deuretzbacher GmbH & Co. Eng. KG" } , - { 0x11A4, "Barco", "Barco" } , - { 0x11A5, "MicroUnity", "MicroUnity Systems Engineering Inc." } , - { 0x11A6, "Pure Data", "Pure Data" } , - { 0x11A7, "Power Comp.", "Power Computing Corp." } , - { 0x11A8, "Systech", "Systech Corp." } , - { 0x11A9, "InnoSys", "InnoSys Inc." } , - { 0x11AA, "Actel", "Actel" } , - { 0x11AB, "Galileo", "Galileo Technology Ltd." } , - { 0x11AC, "Canon", "Canon Information Systems" } , - { 0x11AD, "Lite-On", "Lite-On Communications Inc" } , - { 0x11AE, "Scitex", "Scitex Corporation Ltd" } , - { 0x11AF, "Avid", "Avid Technology Inc." } , - { 0x11B0, "V3", "V3 Semiconductor Inc." } , - { 0x11B1, "Apricot", "Apricot Computers" } , - { 0x11B2, "Kodak", "Eastman Kodak" } , - { 0x11B3, "Barr", "Barr Systems Inc." } , - { 0x11B4, "Leitch", "Leitch Technology International" } , - { 0x11B5, "Radstone", "Radstone Technology Plc" } , - { 0x11B6, "United Video", "United Video Corp" } , - { 0x11B7, "Motorola", "Motorola" } , - { 0x11B8, "Xpoint", "Xpoint Technologies Inc" } , - { 0x11B9, "Pathlight", "Pathlight Technology Inc." } , - { 0x11BA, "Videotron", "Videotron Corp" } , - { 0x11BB, "Pyramid", "Pyramid Technology" } , - { 0x11BC, "Net. Periph.", "Network Peripherals Inc" } , - { 0x11BD, "Pinnacle", "Pinnacle Systems Inc." } , - { 0x11BE, "IMI", "International Microcircuits Inc" } , - { 0x11BF, "Astrodesign", "Astrodesign Inc." } , - { 0x11C0, "H-P", "Hewlett-Packard" } , - { 0x11C1, "AT&T", "AT&T Microelectronics" } , - { 0x11C2, "Sand", "Sand Microelectronics" } , - { 0x11C3, "NEC", "NEC Corporation" } , - { 0x11C4, "Doc. Tech.", "Document Technologies Ind." } , - { 0x11C5, "Shiva", "Shiva Corporatin" } , - { 0x11C6, "Dainippon", "Dainippon Screen Mfg. Co" } , - { 0x11C7, "D.C.M.", "D.C.M. Data Systems" } , - { 0x11C8, "Dolphin", "Dolphin Interconnect Solutions" } , - { 0x11C9, "MAGMA", "MAGMA" } , - { 0x11CA, "LSI Sys.", "LSI Systems Inc" } , - { 0x11CB, "Specialix", "Specialix International Ltd." } , - { 0x11CC, "M&K", "Michels & Kleberhoff Computer GmbH" } , - { 0x11CD, "HAL", "HAL Computer Systems Inc." } , - { 0x11CE, "PRI", "Primary Rate Inc" } , - { 0x11CF, "PEC", "Pioneer Electronic Corporation" } , - { 0x11D0, "Loral", "Loral Frederal Systems - Manassas" } , - { 0x11D1, "AuraVision", "AuraVision Corporation" } , - { 0x11D2, "Intercom", "Intercom Inc." } , - { 0x11D3, "Trancell", "Trancell Systems Inc" } , - { 0x11D4, "AD", "Analog Devices" } , - { 0x11D5, "Ikon", "Ikon Corp" } , - { 0x11D6, "Tekelec", "Tekelec Technologies" } , - { 0x11D7, "Trenton", "Trenton Terminals Inc" } , - { 0x11D8, "ITD", "Image Technologies Development" } , - { 0x11D9, "Tec", "Tec Corporation" } , - { 0x11DA, "Novell", "Novell" } , - { 0x11DB, "Sega", "Sega Enterprises Ltd" } , - { 0x11DC, "Questra", "Questra Corp" } , - { 0x11DD, "Crosfield", "Crosfield Electronics Ltd" } , - { 0x11DE, "Zoran", "Zoran Corporation" } , - { 0x11DF, "New Wave", "New Wave Pdg" } , - { 0x11E0, "Cray", "Cray Communications A/S" } , - { 0x11E1, "Gec Plessey", "Gec Plessey Semi Inc" } , - { 0x11E2, "Samsung", "Samsung Information Systems America" } , - { 0x11E3, "Quicklogic", "Quicklogic Corp" } , - { 0x11E4, "Second Wave", "Second Wave Inc" } , - { 0x11E5, "IIX", "IIX Consulting" } , - { 0x11E6, "Mitsui", "Mitsui-Zosen System Research" } , - { 0x11E7, "Toshiba", "Toshiba America Elec. Co" } , - { 0x11E8, "DPSI", "Digital Processing Systems Inc" } , - { 0x11E9, "Highwater", "Highwater Designs Ltd" } , - { 0x11EA, "Elsag", "Elsag Bailey" } , - { 0x11EB, "Formation", "Formation Inc" } , - { 0x11EC, "Coreco", "Coreco Inc" } , - { 0x11ED, "Mediamatics", "Mediamatics" } , - { 0x11EE, "Dome", "Dome Imaging Systems Inc" } , - { 0x11EF, "Nicolet", "Nicolet Technologies BV" } , - { 0x11F0, "Compu-Shack", "Compu-Shack GmbH" } , - { 0x11F1, "Symbios", "Symbios Logic Inc" } , - { 0x11F2, "Pic-Tel", "Picture Tel Japan KK" } , - { 0x11F3, "Keithley", "Keithley Metrabyte" } , - { 0x11F4, "Kinetic", "Kinetic Systems Corporation" } , - { 0x11F5, "Comp Dev", "Computing Devices Intl" } , - { 0x11F6, "Powermatic", "Powermatic Data Systems Ltd" } , - { 0x11F7, "S-A", "Scientific Atlanta" } , - { 0x11F8, "PMC-Sierra", "PMC-Sierra Inc." } , - { 0x11F9, "I-Cube", "I-Cube Inc" } , - { 0x11FA, "Kasan", "Kasan Electronics Co Ltd" } , - { 0x11FB, "Datel", "Datel Inc" } , - { 0x11FC, "Silicon Magic", "Silicon Magic" } , - { 0x11FD, "High Street", "High Street Consultants" } , - { 0x11FE, "Comtrol", "Comtrol Corp" } , - { 0x11FF, "Scion", "Scion Corp" } , - { 0x1200, "CSS", "CSS Corp" } , - { 0x1201, "Vista", "Vista Controls Corp" } , - { 0x1202, "Network Gen", "Network General Corp" } , - { 0x1203, "Agfa", "Bayer Corporation Agfa Div" } , - { 0x1204, "Lattice", "Lattice Semiconductor Corp" } , - { 0x1205, "Array", "Array Corp" } , - { 0x1206, "Amdahl", "Amdahl Corp" } , - { 0x1208, "Parsytec", "Parsytec GmbH" } , - { 0x1209, "Sci Sys", "Sci Systems Inc" } , - { 0x120A, "Synaptel", "Synaptel" } , - { 0x120B, "Adaptive", "Adaptive Solutions" } , - { 0x120D, "Comp Labs", "Compression Labs Inc." } , - { 0x120E, "Cyclades", "Cyclades Corporation" } , - { 0x120F, "Essential", "Essential Communications" } , - { 0x1210, "Hyperparallel", "Hyperparallel Technologies" } , - { 0x1211, "Braintech", "Braintech Inc" } , - { 0x1212, "Kingston", "Kingston Technology Corp" } , - { 0x1213, "AISI", "Applied Intelligent Systems Inc" } , - { 0x1214, "Perf Tech", "Performance Technologies Inc" } , - { 0x1215, "Interware", "Interware Co Ltd" } , - { 0x1216, "Purup", "Purup Prepress A/S" } , - { 0x1217, "O2Micro", "O2Micro Inc" } , - { 0x1218, "Hybricon", "Hybricon Corp" } , - { 0x1219, "First Virtual", "First Virtual Corp" } , - { 0x121A, "3dfx", "3dfx Interactive Inc" } , - { 0x121B, "ATM", "Advanced Telecommunications Modules" } , - { 0x121C, "Nippon Texa", "Nippon Texa Co Ltd" } , - { 0x121D, "Lippert", "Lippert Automationstechnik GmbH" } , - { 0x121E, "CSPI", "CSPI" } , - { 0x121F, "Arcus", "Arcus Technology Inc" } , - { 0x1220, "Ariel", "Ariel Corporation" } , - { 0x1221, "Contec", "Contec Co Ltd" } , - { 0x1222, "Ancor", "Ancor Communications Inc" } , - { 0x1223, "Heurikon", "Heurikon/Computer Products" } , - { 0x1224, "Int. Img.", "Interactive Images" } , - { 0x1225, "Power IO", "Power I/O Inc." } , - { 0x1227, "Tech-Source", "Tech-Source" } , - { 0x1228, "Norsk", "Norsk Elektro Optikk A/S" } , - { 0x1229, "Data Kin", "Data Kinesis Inc." } , - { 0x122A, "Int. Telecom", "Integrated Telecom" } , - { 0x122B, "LG Ind.", "LG Industrial Systems Co. Ltd." } , - { 0x122C, "Sican", "Sican GmbH" } , - { 0x122D, "Aztech", "Aztech System Ltd" } , - { 0x122E, "Xyratex", "Xyratex" } , - { 0x122F, "Andrew", "Andrew Corp." } , - { 0x1230, "Fishcamp", "Fishcamp Engineering" } , - { 0x1231, "W McCoach", "Woodward McCoach Inc." } , - { 0x1232, "GPT", "GPT Ltd." } , - { 0x1233, "Bus-Tech", "Bus-Tech Inc." } , - { 0x1234, "Technical", "Technical Corp (Potentially BOCHS emulator)" } , - { 0x1235, "Risq Mod", "Risq Modular Systems Inc." } , - { 0x1236, "Sigma", "Sigma Designs Corp." } , - { 0x1237, "Alta Tech", "Alta Technology Corp." } , - { 0x1238, "Adtran", "Adtran" } , - { 0x1239, "3DO", "The 3DO Company" } , - { 0x123A, "Visicom", "Visicom Laboratories Inc." } , - { 0x123B, "Seeq", "Seeq Technology Inc." } , - { 0x123C, "Century Sys", "Century Systems Inc." } , - { 0x123D, "EDT", "Engineering Design Team Inc." } , - { 0x123F, "C-Cube", "C-Cube Microsystems" } , - { 0x1240, "Marathon", "Marathon Technologies Corp." } , - { 0x1241, "DSC", "DSC Communications" } , - { 0x1243, "Delphax", "Delphax" } , - { 0x1244, "AVM", "AVM" } , - { 0x1245, "APD", "APD S.A." } , - { 0x1246, "Dipix", "Dipix Technologies Inc" } , - { 0x1247, "Xylon", "Xylon Research Inc." } , - { 0x1248, "Central Data", "Central Data Corp." } , - { 0x1249, "Samsung", "Samsung Electronics Co. Ltd." } , - { 0x124A, "AEG", "AEG Electrocom GmbH" } , - { 0x124B, "GreenSpring", "GreenSpring Computers" } , - { 0x124C, "Solitron", "Solitron Technologies Inc." } , - { 0x124D, "Stallion", "Stallion Technologies" } , - { 0x124E, "Cylink", "Cylink" } , - { 0x124F, "Infortrend", "Infortrend Technology Inc" } , - { 0x1250, "Hitachi", "Hitachi Microcomputer System Ltd." } , - { 0x1251, "VLSI Sol.", "VLSI Solution OY" } , - { 0x1253, "Guzik", "Guzik Technical Enterprises" } , - { 0x1254, "Linear Systems", "Linear Systems Ltd." } , - { 0x1255, "Optibase", "Optibase Ltd." } , - { 0x1256, "Perceptive", "Perceptive Solutions Inc." } , - { 0x1257, "Vertex", "Vertex Networks Inc." } , - { 0x1258, "Gilbarco", "Gilbarco Inc." } , - { 0x1259, "Allied Tsyn", "Allied Telesyn International" } , - { 0x125A, "ABB Pwr", "ABB Power Systems" } , - { 0x125B, "Asix", "Asix Electronics Corp." } , - { 0x125C, "Aurora", "Aurora Technologies Inc." } , - { 0x125D, "ESS", "ESS Technology" } , - { 0x125E, "Specvideo", "Specialvideo Engineering SRL" } , - { 0x125F, "Concurrent", "Concurrent Technologies Inc." } , - { 0x1260, "Harris", "Harris Semiconductor" } , - { 0x1261, "Matsushita", "Matsushita-Kotobuki Electronics Indu" } , - { 0x1262, "ES Comp.", "ES Computer Co. Ltd." } , - { 0x1263, "Sonic Sol.", "Sonic Solutions" } , - { 0x1264, "Aval Nag.", "Aval Nagasaki Corp." } , - { 0x1265, "Casio", "Casio Computer Co. Ltd." } , - { 0x1266, "Microdyne", "Microdyne Corp." } , - { 0x1267, "SA Telecom", "S.A. Telecommunications" } , - { 0x1268, "Tektronix", "Tektronix" } , - { 0x1269, "Thomson-CSF", "Thomson-CSF/TTM" } , - { 0x126A, "Lexmark", "Lexmark International Inc." } , - { 0x126B, "Adax", "Adax Inc." } , - { 0x126C, "NorTel", "Northern Telecom" } , - { 0x126D, "Splash", "Splash Technology Inc." } , - { 0x126E, "Sumitomo", "Sumitomo Metal Industries Ltd." } , - { 0x126F, "Sil Motion", "Silicon Motion" } , - { 0x1270, "Olympus", "Olympus Optical Co. Ltd." } , - { 0x1271, "GW Instr.", "GW Instruments" } , - { 0x1272, "Telematics", "Telematics International" } , - { 0x1273, "Hughes", "Hughes Network Systems" } , - { 0x1274, "Ensoniq", "Ensoniq" } , - { 0x1275, "NetApp", "Network Appliance" } , - { 0x1276, "Sw Net Tech", "Switched Network Technologies Inc." } , - { 0x1277, "Comstream", "Comstream" } , - { 0x1278, "Transtech", "Transtech Parallel Systems" } , - { 0x1279, "Transmeta", "Transmeta Corp." } , - { 0x127A, "Rockwell Semi", "Rockwell Semiconductor Systems" } , - { 0x127B, "Pixera", "Pixera Corp" } , - { 0x127C, "Crosspoint", "Crosspoint Solutions Inc." } , - { 0x127D, "Vela Res", "Vela Research" } , - { 0x127E, "Winnow", "Winnov L.P." } , - { 0x127F, "Fujifilm", "Fujifilm" } , - { 0x1280, "Photoscript", "Photoscript Group Ltd." } , - { 0x1281, "Yokogawa", "Yokogawa Electronic Corp." } , - { 0x1282, "Davicom", "Davicom Semiconductor Inc." } , - { 0x1283, "ITExpress", "Integrated Technology Express Inc." } , - { 0x1284, "Sahara", "Sahara Networks Inc." } , - { 0x1285, "Plat Tech", "Platform Technologies Inc." } , - { 0x1286, "Mazet", "Mazet GmbH" } , - { 0x1287, "LuxSonor", "LuxSonor Inc." } , - { 0x1288, "Timestep", "Timestep Corp." } , - { 0x1289, "AVC Tech", "AVC Technology Inc." } , - { 0x128A, "Asante", "Asante Technologies Inc." } , - { 0x128B, "Transwitch", "Transwitch Corp." } , - { 0x128C, "Retix", "Retix Corp." } , - { 0x128D, "G2 Net", "G2 Networks Inc." } , - { 0x128E, "Samho", "Samho Multi Tech Ltd." } , - { 0x128F, "Tateno", "Tateno Dennou Inc." } , - { 0x1290, "Sord", "Sord Computer Corp." } , - { 0x1291, "NCS Comp", "NCS Computer Italia" } , - { 0x1292, "Tritech", "Tritech Microelectronics Intl PTE" } , - { 0x1293, "M Reality", "Media Reality Technology" } , - { 0x1294, "Rhetorex", "Rhetorex Inc." } , - { 0x1295, "Imagenation", "Imagenation Corp." } , - { 0x1296, "Kofax", "Kofax Image Products" } , - { 0x1297, "Holco", "Holco Enterprise" } , - { 0x1298, "Spellcaster", "Spellcaster Telecommunications Inc." } , - { 0x1299, "Know Tech", "Knowledge Technology Laboratories" } , - { 0x129A, "VMETRO", "VMETRO" } , - { 0x129B, "Img Access", "Image Access" } , - { 0x129D, "CompCore", "CompCore Multimedia Inc." } , - { 0x129E, "Victor Jpn", "Victor Co. of Japan Ltd." } , - { 0x129F, "OEC Med", "OEC Medical Systems Inc." } , - { 0x12A0, "A-B", "Allen Bradley Co." } , - { 0x12A1, "Simpact", "Simpact Inc" } , - { 0x12A2, "NewGen", "NewGen Systems Corp." } , - { 0x12A3, "Lucent", "Lucent Technologies" } , - { 0x12A4, "NTT Elect", "NTT Electronics Technology Co." } , - { 0x12A5, "Vision Dyn", "Vision Dynamics Ltd." } , - { 0x12A6, "Scalable", "Scalable Networks Inc." } , - { 0x12A7, "AMO", "AMO GmbH" } , - { 0x12A8, "News Datacom", "News Datacom" } , - { 0x12A9, "Xiotech", "Xiotech Corp." } , - { 0x12AA, "SDL", "SDL Communications Inc." } , - { 0x12AB, "Yuan Yuan", "Yuan Yuan Enterprise Co. Ltd." } , - { 0x12AC, "MeasureX", "MeasureX Corp." } , - { 0x12AD, "Multidata", "Multidata GmbH" } , - { 0x12AE, "Alteon", "Alteon Networks Inc." } , - { 0x12AF, "TDK USA", "TDK USA Corp." } , - { 0x12B0, "Jorge Sci", "Jorge Scientific Corp." } , - { 0x12B1, "GammaLink", "GammaLink" } , - { 0x12B2, "Gen Signal", "General Signal Networks" } , - { 0x12B3, "Inter-Face", "Inter-Face Co. Ltd." } , - { 0x12B4, "Future Tel", "Future Tel Inc." } , - { 0x12B5, "Granite", "Granite Systems Inc." } , - { 0x12B6, "Nat Micro", "Natural Microsystems" } , - { 0x12B7, "Acumen", "Acumen" } , - { 0x12B8, "Korg", "Korg" } , - { 0x12B9, "US Robotics", "US Robotics" } , - { 0x12BA, "Bittware", "Bittware Research Systems Inc" } , - { 0x12BB, "Nippon Uni", "Nippon Unisoft Corp." } , - { 0x12BC, "Array Micro", "Array Microsystems" } , - { 0x12BD, "Computerm", "Computerm Corp." } , - { 0x12BE, "Anchor Chips", "Anchor Chips Inc." } , - { 0x12BF, "Fujifilm", "Fujifilm Microdevices" } , - { 0x12C0, "Infimed", "Infimed" } , - { 0x12C1, "GMM Res", "GMM Research Corp." } , - { 0x12C2, "Mentec", "Mentec Ltd." } , - { 0x12C3, "Holtek", "Holtek Microelectronics Inc." } , - { 0x12C4, "Conn Tech", "Connect Tech Inc." } , - { 0x12C5, "PicturEl", "Picture Elements Inc." } , - { 0x12C6, "Mitani", "Mitani Corp." } , - { 0x12C7, "Dialogic", "Dialogic Corp." } , - { 0x12C8, "G Force", "G Force Co. Ltd." } , - { 0x12C9, "Gigi Ops", "Gigi Operations" } , - { 0x12CA, "ICE", "Integrated Computing Engines, Inc." } , - { 0x12CB, "Antex", "Antex Electronics Corp." } , - { 0x12CC, "Pluto", "Pluto Technologies International" } , - { 0x12CD, "Aims Lab", "Aims Lab" } , - { 0x12CE, "Netspeed", "Netspeed Inc." } , - { 0x12CF, "Prophet", "Prophet Systems Inc." } , - { 0x12D0, "GDE Sys", "GDE Systems Inc." } , - { 0x12D1, "PsiTech", "PsiTech" } , - { 0x12D2, "NVidia", "NVidia / SGS Thomson" } , - { 0x12D3, "Vingmed", "Vingmed Sound A/S" } , - { 0x12D4, "DGM&S", "DGM & S" } , - { 0x12D5, "Equator", "Equator Technologies" } , - { 0x12D6, "Analogic", "Analogic Corp." } , - { 0x12D7, "Biotronic", "Biotronic SRL" } , - { 0x12D8, "Pericom", "Pericom Semiconductor" } , - { 0x12D9, "Aculab", "Aculab Plc." } , - { 0x12DA, "True Time", "True Time" } , - { 0x12DB, "Annapolis", "Annapolis Micro Systems Inc." } , - { 0x12DC, "Symicron", "Symicron Computer Communication Ltd." } , - { 0x12DD, "MGI", "Management Graphics Inc." } , - { 0x12DE, "Rainbow", "Rainbow Technologies" } , - { 0x12DF, "SBS Tech", "SBS Technologies Inc." } , - { 0x12E0, "Chase", "Chase Research PLC" } , - { 0x12E1, "Nintendo", "Nintendo Co. Ltd." } , - { 0x12E2, "Datum", "Datum Inc. Bancomm-Timing Division" } , - { 0x12E3, "Imation", "Imation Corp. - Medical Imaging Syst" } , - { 0x12E4, "Brooktrout", "Brooktrout Technology Inc." } , - { 0x12E6, "Cirel", "Cirel Systems" } , - { 0x12E7, "Sebring", "Sebring Systems Inc" } , - { 0x12E8, "CRISC", "CRISC Corp." } , - { 0x12E9, "GE Spacenet", "GE Spacenet" } , - { 0x12EA, "Zuken", "Zuken" } , - { 0x12EB, "Aureal", "Aureal Semiconductor" } , - { 0x12EC, "3A Intl", "3A International Inc." } , - { 0x12ED, "Optivision", "Optivision Inc." } , - { 0x12EE, "Orange Micro", "Orange Micro, Inc." } , - { 0x12EF, "Vienna", "Vienna Systems" } , - { 0x12F0, "Pentek", "Pentek" } , - { 0x12F1, "Sorenson", "Sorenson Vision Inc." } , - { 0x12F2, "Gammagraphx", "Gammagraphx Inc." } , - { 0x12F4, "Megatel", "Megatel" } , - { 0x12F5, "Forks", "Forks" } , - { 0x12F6, "Dawson Fr", "Dawson France" } , - { 0x12F7, "Cognex", "Cognex" } , - { 0x12F8, "Electronic-Design", "Electronic-Design GmbH" } , - { 0x12F9, "FFT", "FourFold Technologies" } , - { 0x12FE, "ESD", "ESD Electronic System Design GmbH" } , - { 0x1307, "ComputerBoards", "ComputerBoards" } , - { 0x1318, "Packet Engines", "Packet Engines, Inc." } , - { 0x1319, "Forte Media", "Forte Media, Inc." } , - { 0x1331, "RadiSys", "RadiSys Corporation" } , - { 0x1335, "Videomail", "Videomail Inc." } , - { 0x1347, "Odetics", "Odetics" } , - { 0x135D, "ABB Network Partn", "ABB Network Partner AB" } , - { 0x137E, "PTSC", "Patriot Scientific Corp." } , - { 0x1390, "CDI", "Concept Development Inc." } , - { 0x13FA, "Pentland", "Pentland Systems Ltd." } , - { 0x1402, "Meilhaus Electronic", "Meilhaus Electronic GmbH Germany" } , - { 0x1406, "Océ", "Océ Printing Systems" } , - { 0x144B, "Loronix", "Loronix Information Systems, Inc." } , - { 0x1458, "Giga-Byte", "Giga-Byte Technologies" } , - { 0x14D4, "PANACOM", "Panacom Technology Corporation" } , - { 0x1500, "DELTA", "DELTA Electronics, Inc." } , - { 0x1522, "MainPine", "MainPine Limited" } , - { 0x1C1C, "Symphony", "Symphony" } , - { 0x1DE1, "Tekram", "Tekram" } , - { 0x270F, "ChainTech", "ChainTech Computer Co. Ltd." } , - { 0x3000, "Hansol", "Hansol Electronics Inc." } , - { 0x3142, "PostImpressions", "Post Impressions Systems" } , - { 0x3D3D, "3DLabs", "3Dlabs, Inc. Ltd" } , - { 0x4005, "Avance", "Avance Logic Inc." } , - { 0x4033, "Addtron", "Addtron Technology Co., Inc." } , - { 0x4143, "DEC", "Digital Equipment Corp." } , - { 0x4594, "", "Cogetec Informatique Inc." } , - { 0x4680, "UMAX Comp", "UMAX Computer Corp." } , - { 0x4B10, "Buslogic", "Buslogic Inc" } , - { 0x5333, "S3", "S3 Incorporated" } , - { 0x5455, "TU-Berlin", "Technische Universtiaet Berlin" } , - { 0x5519, "Cnet", "Cnet Technoliges, Inc." } , - { 0x5700, "Netpower", "Netpower" } , - { 0x6374, "C4T", "c't Magazin f_r Computertechnik" } , - { 0x7BDE, "MIDAC", "MIDAC Corporation" } , - { 0x8001, "BEYERTONE", "Beyertone AG - Germany" } , - { 0x8008, "QUANCOM", "QUANCOM Informationssysteme GmbH" } , - { 0x8086, "Intel", "Intel Corporation" } , - { 0x8800, "Trigem", "Trigem Computer" } , - { 0x8888, "Sil Magic", "Silicon Magic" } , - { 0x8E0E, "Computone", "Computone Corporation" } , - { 0x9004, "Adaptec", "Adaptec" } , - { 0x9005, "Adaptec", "Adaptec" } , - { 0x907F, "Atronics", "Atronics" } , - { 0xC0FE, "Mot Engrg", "Motion Engineering Inc." } , - { 0xD4D4, "DY4", "DY4 Systems Inc." } , - { 0xE159, "Tiger Jet", "Tiger Jet Network Inc" } , - { 0xEDD8, "ARC", "ARC Logic" } , - { 0xFA57, "FAST", "Fast Search & Transfer ASA" } , - { 0xFFFF, "BAD!", "ILLEGITIMATE VENDOR ID" } , -} ; - -// Use this value for loop control during searching: -#define PCI_VENTABLE_LEN (sizeof(PciVenTable)/sizeof(PCI_VENTABLE)) - -/** @brief PCI device table structure */ -typedef struct _PCI_DEVTABLE -{ - /// Vendor ID - unsigned short VenId ; - /// Device ID - unsigned short DevId ; - /// Chipset name string - char * Chip ; - /// Chipset description string - char * ChipDesc ; -} PCI_DEVTABLE, *PPCI_DEVTABLE ; - -static const PCI_DEVTABLE PciDevTable [] = -{ - { 0x0E11, 0x0002, "ISA Bridge", "" } , - { 0x0E11, 0x1000, "", "Triflex/PCI CPU Bridge" } , - { 0x0E11, 0x2000, "", "Triflex/PCI CPU Bridge" } , - { 0x0E11, 0x3032, "QVision", "GUI Accelerator v0" } , - { 0x0E11, 0x3033, "QVision", "GUI Accelerator v1" } , - { 0x0E11, 0x3034, "QVision", "GUI Accelerator v2" } , - { 0x0E11, 0x4000, "4000", "Triflex/PCI CPU Bridge" } , - { 0x0E11, 0xAE32, "", "Netelligent 10/100 TX" } , - { 0x0E11, 0xAE34, "", "Netelligent 10 T" } , - { 0x0E11, 0xAE35, "", "Integrated NetFlex 3/P" } , - { 0x0E11, 0xAE40, "", "Dual Port Netelligent 10/100 TX" } , - { 0x0E11, 0xAE43, "", "ProLiant Integrated Netelligent 10/100 TX" } , - { 0x0E11, 0xB011, "", "Dual Port Netelligent 10/100 TX" } , - { 0x0E11, 0xF130, "", "NetFlex 3/P" } , - { 0x0E11, 0xF150, "", "NetFlex 3/P w/ BNC" } , - { 0x1000, 0x0001, "53C810", "Fast/Narrow SCSI I/O Cntrlr" } , - { 0x1000, 0x0002, "53C820", "Fast-wide SCSI" } , - { 0x1000, 0x0003, "53C825", "Fast-wide SCSI" } , - { 0x1000, 0x0004, "53C815", "Fast SCSI" } , - { 0x1000, 0x0005, "53C810AP", "Fast SCSI" } , - { 0x1000, 0x0006, "53C860", "Ultra SCSI/Narrow" } , - { 0x1000, 0x000B, "53C896", "dual-channel Ultra-2 Wide SCSI" } , - { 0x1000, 0x000C, "SYM53C895", "Ultra-2 Wide SCSI" } , - { 0x1000, 0x000D, "53C885", "Ultra Wide SCSI, Ethernet" } , - { 0x1000, 0x000F, "53C875, 53C876", "Ultra-Wide SCSI (53C876 is dual-channel)" } , - { 0x1000, 0x0012, "53C895A", "Ultra-2 Wide SCSI" } , - { 0x1000, 0x008F, "53C875J", "Ultra Wide SCSI" } , - { 0x1001, 0x0010, "ispLSI1032E", "PCI 1616, 16 TTL-IN, 16 TTL-OUT" } , - { 0x1001, 0x0011, "ispLSI1032E", "OPTO-PCI, 16 IN / 16 OUT 24 VDC" } , - { 0x1001, 0x0012, "ispLSI1032E", "PCI-AD, PCI-ADDA analog I/O-card" } , - { 0x1001, 0x0013, "ispLSI1032E", "PCI-OptoRel, PCI-Relais 16 Relais & Opto" } , - { 0x1001, 0x0014, "ispLSI1032E", "Timer, Pulse & Counter-card 16..32 bit" } , - { 0x1001, 0x0015, "ispLSI1032E", "PCI-DAC416, 4 channel D/A16bit precision" } , - { 0x1002, 0x4158, "68800", "Mach 32" } , - { 0x1002, 0x4354, "215CT222", "" } , - { 0x1002, 0x4358, "210888CX", "" } , - { 0x1002, 0x4742, "", "3D Rage Pro" } , - { 0x1002, 0x4749, "3D RAGE PRO 2X AGP", "ATI ALL IN WONDER PRO (8MB)" } , - { 0x1002, 0x4750, "3D RAGE PRO", "Graphics Accelerator" } , - { 0x1002, 0x4758, "210888GX", "Mach 64 (WinTurbo)" } , - { 0x1002, 0x5246, "", "" } , - { 0x1002, 0x5654, "215VT222", "VIDEO XPRESSION" } , - { 0x1003, 0x0201, "US201", "Graphics Cntrlr" } , - { 0x1004, 0x0005, "82C591", "CPU Bridge" } , - { 0x1004, 0x0006, "82C593", "ISA Bridge" } , - { 0x1004, 0x0007, "82C594", "Wildcat System Controller" } , - { 0x1004, 0x0008, "82C596/597", "Wildcat ISA Bridge" } , - { 0x1004, 0x000C, "82C541", "" } , - { 0x1004, 0x000D, "82C543", "" } , - { 0x1004, 0x0101, "82C532", "" } , - { 0x1004, 0x0102, "82C534", "PCI to PCI Bridge" } , - { 0x1004, 0x0104, "82C535", "Host Bridge" } , - { 0x1004, 0x0105, "82C147", "" } , - { 0x1004, 0x0200, "82C975", "RISC GUI Accelerator" } , - { 0x1004, 0x0280, "82C925", "RISC GUI Accelerator" } , - { 0x1005, 0x2301, "ALG2301", "GUI Accelerator" } , - { 0x1005, 0x2302, "ALG2302", "GUI Accelerator" } , - { 0x100B, 0x0001, "DP83810", "10/100 Ethernet MAC" } , - { 0x100B, 0x0002, "PC87415", "PCI-IDE DMA Master Mode Interface Ctrlr" } , - { 0x100B, 0xD001, "PC87410", "PCI-IDE Interface" } , - { 0x100C, 0x3202, "ET4000W32P-A", "GUI Accelerator" } , - { 0x100C, 0x3205, "ET4000W32P-B", "GUI Accelerator" } , - { 0x100C, 0x3206, "ET4000W32P-C", "GUI Accelerator" } , - { 0x100C, 0x3207, "ET4000W32P-D", "GUI Accelerator" } , - { 0x100C, 0x3208, "ET6000", "Graphics/Multimedia Engine" } , - { 0x100E, 0x9001, "P9000", "GUI Accelerator" } , - { 0x100E, 0x9100, "P9100", "GUI Accelerator" } , - { 0x1011, 0x0001, "DC21050", "PCI-PCI Bridge" } , - { 0x1011, 0x0002, "DC21040", "Ethernet Ctrlr" } , - { 0x1011, 0x0009, "DC21140", "Fast Ethernet Ctrlr" } , - { 0x1011, 0x000F, "DEFPA", "FDDI" } , - { 0x1011, 0x0014, "DC21041", "Ethernet Ctrlr" } , - { 0x1011, 0x0016, "DGLPB", "ATM" } , - { 0x1011, 0x0019, "DC21143", "PCI/CardBus 10/100 Mbit Ethernet Ctlr" } , - { 0x1011, 0x0021, "21052", "PCI-PCI Bridge" } , - { 0x1011, 0x0022, "21150", "PCI-PCI Bridge" } , - { 0x1011, 0x0024, "21152", "PCI-PCI Bridge" } , - { 0x1011, 0x0025, "21153", "PCI-PCI Bridge" } , - { 0x1011, 0x0026, "21154", "PCI-PCI Bridge" } , - { 0x1011, 0x0046, "21554", "PCI-to-PCI Bridge" } , - { 0x1013, 0x0038, "CL-GD7548", "Video Controller" } , - { 0x1013, 0x004C, "CL-GD7556", "64-bit Accelerated LCD/CRT Controller" } , - { 0x1013, 0x00A0, "CL-GD5340", "GUI Accelerator" } , - { 0x1013, 0x00A4, "GD 5434", "GUI Accelerator" } , - { 0x1013, 0x00A8, "GD 5434-HC-B", "GUI Accelerator" } , - { 0x1013, 0x00AC, "CL-GD5436", "" } , - { 0x1013, 0x00B8, "GD5446", "Visual Media Accelerator (64bit)" } , - { 0x1013, 0x00BC, "CL-GD5480", "64-bit SGRAM GUI accelerator" } , - { 0x1013, 0x00D0, "CL-GD5462", "Laguna VisualMedia graphics accelerator" } , - { 0x1013, 0x00D4, "CL-GD5464", "Laguna VisualMedia graphics accelerator" } , - { 0x1013, 0x00D6, "GD-546x VGA", "laguna" } , - { 0x1013, 0x1100, "CL 6729", "PCMCIA Bridge" } , - { 0x1013, 0x1110, "6832", "PCMCIA/CardBus Controller" } , - { 0x1013, 0x1200, "7542", "GUI Accelerator" } , - { 0x1013, 0x1202, "7543", "GUI Accelerator" } , - { 0x1013, 0x1204, "7541", "Nordic-lite VGA Cntrlr" } , - { 0x1013, 0x6001, "CS4610", "CrystalClear SoundFusion PCI Audio Accel" } , - { 0x1013, 0x6003, "CS4614", "CrystalClear SoundFusion PCI Audio Accel" } , - { 0x1013, 0x6005, "CS4281", "CrystalClear PCI Audio Interface" } , - { 0x1014, 0x0002, "MCA Bridge", "MCA Bridge" } , - { 0x1014, 0x0005, "Alta Lite", "CPU Bridge" } , - { 0x1014, 0x0007, "Alta MP", "CPU Bridge" } , - { 0x1014, 0x000A, "ISA Bridge w/PnP", "ISA Bridge w/PnP" } , - { 0x1014, 0x0017, "CPU Bridge", "CPU Bridge" } , - { 0x1014, 0x0018, "Auto LANStreamer", "" } , - { 0x1014, 0x001B, "GXT-150P", "Graphics Adapter" } , - { 0x1014, 0x0020, "", "MCA Bridge" } , - { 0x1014, 0x0022, "PCI-PCI BRIDGE", "PCI-PCI BRIDGE" } , - { 0x1014, 0x002E, "RAID SCSI", "RAID SCSI device" } , - { 0x1014, 0x0036, "Miami/PCI", "32-bit LocalBus Bridge" } , - { 0x1014, 0x003E, "85H9533", "Token Ring Card" } , - { 0x1014, 0x0053, "", "25 MBit ATM controller" } , - { 0x1014, 0x005D, "05J3506", "TCP/IP networking device" } , - { 0x1014, 0x00CE, "02li537", "Adapter 2 Token Ring Card" } , - { 0x101A, 0x0009, "Altera FLEX", "??? Raid Controller ???" } , - { 0x101C, 0x0193, "WD33C193A", "8-bit SCSI Cntrlr" } , - { 0x101C, 0x0196, "SCSI Bridge", "SCSI Bridge" } , - { 0x101C, 0x0197, "WD33C197A", "16-bit SCSI Cntrlr" } , - { 0x101C, 0x0296, "WD33C296A", "high perf 16-bit SCSI Cntrlr" } , - { 0x101C, 0x3193, "WD7193", "Fast SCSI-II" } , - { 0x101C, 0x3197, "WD7197", "Fast-wide SCSI-II" } , - { 0x101C, 0x3296, "WD33C296A", "Fast Wide SCSI bridge" } , - { 0x101C, 0x4296, "WD34C296", "Wide Fast-20 Bridge" } , - { 0x101C, 0xC24A, "90C", "" } , - { 0x101E, 0x9010, "MegaRAID", "Fast-wide SCSI/RAID" } , - { 0x101E, 0x9030, "", "IDE Cntrlr" } , - { 0x101E, 0x9031, "", "IDE Cntrlr" } , - { 0x101E, 0x9032, "", "IDE and SCSI Cntrlr" } , - { 0x101E, 0x9033, "", "SCSI Cntrlr" } , - { 0x101E, 0x9040, "", "Multimedia card" } , - { 0x1022, 0x2000, "79C970", "Ethernet Ctrlr" } , - { 0x1022, 0x2020, "53C974", "SCSI Ctrlr" } , - { 0x1022, 0x2040, "79C974", "Ethernet & SCSI Ctrlr" } , - { 0x1023, 0x2000, "4DWAVE-DX", "advanced PCI DirectSound accelerator" } , - { 0x1023, 0x9320, "", "32-bit GUI Accelerator" } , - { 0x1023, 0x9350, "", "32-bit GUI Accelerator" } , - { 0x1023, 0x9360, "", "Flat panel Cntrlr" } , - { 0x1023, 0x9420, "9420", "VGA Ctrlr" } , - { 0x1023, 0x9440, "tgui9440-3", "tgui9440-3" } , - { 0x1023, 0x9460, "", "32-bit GUI Accelerator" } , - { 0x1023, 0x9660, "9385", "Cyber 9385 Portable PC Video Controller (9660?)" } , - { 0x1023, 0x9682, "", "Multimedia Accelerator" } , - { 0x1023, 0x9750, "9750", "AGP-Chipset" } , - { 0x1025, 0x1435, "M1435", "VL Bridge" } , - { 0x1025, 0x1445, "M1445", "VL Bridge & EIDE" } , - { 0x1025, 0x1449, "M1449", "ISA Bridge" } , - { 0x1025, 0x1451, "M1451", "Pentium Chipset" } , - { 0x1025, 0x1461, "M1461", "P54C Chipset" } , - { 0x1025, 0x3141, "M3141", "GUI Accelerator" } , - { 0x1025, 0x3143, "M3143", "GUI Accelerator" } , - { 0x1025, 0x3145, "M3145", "GUI Accelerator" } , - { 0x1025, 0x3147, "M3147", "GUI Accelerator" } , - { 0x1025, 0x3149, "M3149", "GUI Accelerator" } , - { 0x1025, 0x3151, "M3151", "GUI Accelerator" } , - { 0x1025, 0x5215, "?", "EIDE Ctrlr" } , - { 0x102A, 0x0000, "HYDRA", "P5 Chipset" } , - { 0x102A, 0x0010, "ASPEN", "i486 Chipset" } , - { 0x102B, 0x0518, "Atlas PX2085", "GUI Accelerator" } , - { 0x102B, 0x0519, "MGA-2064", "Millenium GUI Accelerator" } , - { 0x102B, 0x051A, "MGA 1064SG", "64-bit graphics chip" } , - { 0x102B, 0x051B, "", "Millenium II" } , - { 0x102B, 0x051F, "MGA2164WA-B", "Matrox Millenium II AGP" } , - { 0x102B, 0x0521, "MGA-G200", "Millennium/Mystique G200 AGP" } , - { 0x102B, 0x0D10, "Impression", "Impression GUI accelerator" } , - { 0x102C, 0x00B8, "64310", "GUI Accelerator" } , - { 0x102C, 0x00C0, "69000", "Video Accelerator with Integrated Memory" } , - { 0x102C, 0x00D0, "65545", "Flat panel/crt VGA Cntrlr" } , - { 0x102C, 0x00D8, "65540", "Flat Panel/CRT VGA Controller" } , - { 0x102C, 0x00DC, "65548", "GUI Accelerator" } , - { 0x102C, 0x00E0, "65550", "LCD/CRT controller" } , - { 0x102C, 0x00E4, "65554", "Flat Panel/LCD CRT GUI Accelerator" } , - { 0x102C, 0x00E5, "65555", "VGA GUI Accelerator" } , - { 0x102C, 0x00F4, "68554", "HiQVision Flat Panel/CRT GUI Controller" } , - { 0x102F, 0x0009, "", "r4x00 Bridge" } , - { 0x1031, 0x5607, "", "video in and out with motion jpeg compression and deco" } , - { 0x1033, 0x0001, "", "PCI to 486 like bus Bridge" } , - { 0x1033, 0x0002, "", "PCI to vl98 Bridge" } , - { 0x1033, 0x0003, "", "atm lan Cntrlr" } , - { 0x1033, 0x0004, "", "r4000PCI bus Bridge" } , - { 0x1033, 0x0005, "", "PCI to 486 like peripheral bus Bridge" } , - { 0x1033, 0x0006, "", "GUI Accelerator" } , - { 0x1033, 0x0007, "", "PCI to ux-bus Bridge" } , - { 0x1033, 0x0008, "", "GUI Accelerator (vga equivalent)" } , - { 0x1033, 0x0009, "", "graphic Cntrlr for 98" } , - { 0x1036, 0x0000, "TMC-18C30", "Fast SCSI" } , - { 0x1039, 0x0001, "86C201", "True-Color GUI Accelerator" } , - { 0x1039, 0x0002, "", "VGA Cntrlr" } , - { 0x1039, 0x0006, "85C501/2", "Pentium Bridge" } , - { 0x1039, 0x0008, "85C503/5513/SiS5595", "ISA Bridge" } , - { 0x1039, 0x0009, "SiS5595", "PCI System I/O Chipset (PMU configuration)" } , - { 0x1039, 0x0200, "SiS5597", "5597 Onboard Graphics Controller" } , - { 0x1039, 0x0406, "85C501/2", "Pentium Bridge" } , - { 0x1039, 0x0496, "85C496", "VL Bridge" } , - { 0x1039, 0x0596, "", "p5 chipset w/DE" } , - { 0x1039, 0x0601, "601", "EIDE Ctrlr" } , - { 0x1039, 0x3602, "", "IDE Cntrlr" } , - { 0x1039, 0x5401, "", "486 chipset" } , - { 0x1039, 0x5511, "SiS5511/5512", "Pentium Chipset" } , - { 0x1039, 0x5513, "SiS5513", "EIDE Ctrlr" } , - { 0x1039, 0x5581, "", "p5 chipset" } , - { 0x1039, 0x5582, "", "ISA Bridge" } , - { 0x1039, 0x5591, "SiS5591/2", "Pentium PCI/AGP chipset" } , - { 0x1039, 0x5596, "", "p5 chipset" } , - { 0x1039, 0x5597, "SiS5597", "5597 Northbridge" } , - { 0x1039, 0x6204, "", "video decoder/mpeg interface" } , - { 0x1039, 0x6205, "", "PCI vga Cntrlr" } , - { 0x1039, 0x7001, "SiS5595", "PCI System I/O Chipset (USB controller)" } , - { 0x103C, 0x1030, "J2585A", "10/100VG LAN Adapter" } , - { 0x103C, 0x2910, "E2910A", "PCI Bus Exerciser" } , - { 0x103C, 0x2920, "", "Fast Host Interface" } , - { 0x103C, 0x2924, "E2924A", "PCI Host Interface Adapter" } , - { 0x103C, 0x2925, "E2925A", "32 bit PCI Bus Exerciser and Analyzer" } , - { 0x103C, 0x2926, "E2926A", "64 bit PCI Bus Exerciser and Analyzer" } , - { 0x103C, 0x2927, "E2927A", "64 Bit, 66/50MHz PCI Analyzer & Exerciser" } , - { 0x103C, 0x2940, "E2940A", "64 bit, 66/50MHz CompactPCI Analyzer&Exerciser" } , - { 0x1042, 0x1000, "FDC 37C665", "EIDE" } , - { 0x1042, 0x1000, "RZ1000", "IDE Ctrlr" } , - { 0x1042, 0x1001, "37C922", "" } , - { 0x1043, 0x0200, "AGP-V3400", "Asus RivaTNT Video Board" } , - { 0x1044, 0xA400, "2124A/9X", "SmartCache/Raid SCSI" } , - { 0x1045, 0xA0F8, "82C750", "PCI USB Controller" } , - { 0x1045, 0xC101, "82C264", "GUI Accelerator" } , - { 0x1045, 0xC178, "92C178", "LCD GUI Accelerator" } , - { 0x1045, 0xC557, "82C557", "CPU Bridge (Viper)" } , - { 0x1045, 0xC558, "82C558", "ISA Bridge w/PnP" } , - { 0x1045, 0xC621, "82C621", "PCI IDE Controller (PIC)" } , - { 0x1045, 0xC822, "82C822", "EIDE Ctrlr" } , - { 0x1045, 0xC825, "82C825 function 0", "PCI-to-ISA Bridge" } , - { 0x1045, 0xC935, "82C935", "MachOne integrated PCI audio processor" } , - { 0x1045, 0xD568, "82C825 function 1", "PCI bus master IDE controller" } , - { 0x1045, 0xD768, "82C750", "Ultra DMA IDE controller" } , - { 0x104B, 0x0140, "BT-946C", "SCSI-II" } , - { 0x104B, 0x1040, "BA80C30", "SCSI" } , - { 0x104B, 0x8130, "Flashpoint LT", "Ultra SCSI" } , - { 0x104C, 0x0500, "", "100 MBit LAN Cntrlr" } , - { 0x104C, 0x0508, "", "tms380c2x compressor interface" } , - { 0x104C, 0x1000, "TI PCI Eagle i/f AS", "" } , - { 0x104C, 0xA001, "TDC1570", "64-bit PCI ATM sar" } , - { 0x104C, 0xA100, "TDC1561", "32-bit PCI ATM sar" } , - { 0x104C, 0xAC10, "PCI1050", "pc card Cntrlr" } , - { 0x104C, 0xAC11, "PCI1053", "pc card Cntrlr" } , - { 0x104C, 0xAC12, "PCI1130", "pc card Cardbus Cntrlr" } , - { 0x104C, 0xAC13, "PCI1031", "PCI-TO-PC CARD16 CONTROLLER UNIT" } , - { 0x104c, 0xAC15, "PCI1131", "Dual Socket PCI CardBus Controller" } , - { 0x104C, 0xAC16, "PCI1250", "pc card Cardbus Cntrlr" } , - { 0x104C, 0xac17, "PCI1220", "CardBus Controller" } , - { 0x104c, 0xAC19, "PCI1221", "PC Card Controller" } , - { 0x104c, 0xAC1C, "PCI1225", "PC Card Controller" } , - { 0x104c, 0xAC1D, "PCI1251A", "PC Card Controller" } , - { 0x104c, 0xAC1E, "PCI1211", "High Performance PC Card Controller" } , - { 0x104c, 0xAC51, "PCI1420", "PC Card Controller" } , - { 0x104c, 0xAC60, "PCI2040", "PCI-DSP Bridge Controller" } , - { 0x104E, 0x0107, "OTI107", "Spitfire VGA Accelerator" } , - { 0x1050, 0x0000, "", "Ethernet Cntrlr" } , - { 0x1050, 0x0940, "w89c940f", "winbond pci ethernet" } , - { 0x1054, 0x0001, "", "PCI Bridge" } , - { 0x1054, 0x0002, "", "PCI bus Cntrlr" } , - { 0x1055, 0x0810, "", "486 host Bridge" } , - { 0x1055, 0x0922, "", "Pentium/p54c host Bridge" } , - { 0x1055, 0x0926, "", "ISA Bridge" } , - { 0x1057, 0x0001, "MPC105", "PowerPC Chipset" } , - { 0x1057, 0x0002, "MPC106", "PowerPC Chipset" } , - { 0x105A, 0x4D33, "PDC20246", "Ultra ATA controller" } , - { 0x105A, 0x5300, "DC5300", "" } , - { 0x105D, 0x2309, "Imagine 128", "GUI Accelerator" } , - { 0x105D, 0x2339, "I128s2", "Imagine 128 Series 2" } , - { 0x105D, 0x493D, "T2R", "Imagine 128 3D" } , - { 0x105D, 0x5348, "Revolution IV", "Revolution IV" } , - { 0x1060, 0x0001, "UM82C881", "486 Chipset" } , - { 0x1060, 0x0002, "UM82C886", "ISA Bridge" } , - { 0x1060, 0x0101, "UM8673F", "EIDE Controller" } , - { 0x1060, 0x0881, "UM8881", "HB4 486 PCI Chipset" } , - { 0x1060, 0x0881, "UM8881", "" } , - { 0x1060, 0x0886, "UM8886F", "ISA Bridge" } , - { 0x1060, 0x0891, "UM82C891", "Pentium Chipset" } , - { 0x1060, 0x1001, "UM886A", "IDE Cntrlr (dual function)" } , - { 0x1060, 0x673A, "UM8886", "Funktion 1: EIDE Controller" } , - { 0x1060, 0x8710, "UM8710", "VGA Cntrlr" } , - { 0x1060, 0x886A, "UM8886", "ISA Bridge with EIDE" } , - { 0x1060, 0x8881, "UM8881F", "HB4 486 PCI Chipset" } , - { 0x1060, 0x8886, "UM8886", "ISA Bridge" } , - { 0x1060, 0x8891, "UM8891", "586 Chipset" } , - { 0x1060, 0x9017, "UM9017F", "" } , - { 0x1060, 0xE881, "UM8881", "486 Chipset" } , - { 0x1060, 0xE886, "UM8886", "ISA Bridge w/EIDE" } , - { 0x1060, 0xE891, "UM8891", "Pentium Chipset" } , - { 0x1061, 0x0001, "AGX016", "GUI Accelerator" } , - { 0x1061, 0x0002, "IIT3204/3501", "MPEG Decoder" } , - { 0x1066, 0x0000, "PT80C826", "VL Bridge" } , - { 0x1069, 0x0001, "DAC960P", "DAC960P 3 ch SCSI RAID Controller" } , - { 0x1069, 0x0002, "DAC960PD", "DAC960PD 3 ch SCSI RAID Controller" } , - { 0x1069, 0x0010, "DAC960PJ", "DAC960PJ 3 ch SCSI RAID Controller" } , - { 0x1069, 0xBA55, "1100", "eXtremeRAID Controller" } , - { 0x1073, 0x0001, "", "3D graphics Cntrlr" } , - { 0x1073, 0x0002, "YGV615", "RPA3 3D-Graphics Controller" } , - { 0x1073, 0x000C, "YMF740", "DS-1L PCI audio controller" } , - { 0x1073, 0x000D, "YMF724", "DS-1 PCI audio controller" } , - { 0x1073, 0x0010, "YMF744", "DS-1S PCI audio controller" } , - { 0x1077, 0x1020, "ISP1020A", "Fast-wide SCSI" } , - { 0x1077, 0x1022, "ISP1022A", "Fast-wide SCSI" } , - { 0x1078, 0x0001, "MediaGXm MMX", "Cyrix Integrated CPU" } , - { 0x1078, 0x0100, "Cx5530", "South Bridge for Cyrixs MediaGX uProcessor" } , - { 0x107D, 0x0000, "P86C850", "Graphic GLU-Logic" } , - { 0x107E, 0x0001, "", "ATM interface card" } , - { 0x107E, 0x0002, "", "100 vg anylan Cntrlr" } , - { 0x107E, 0x0008, "", "155 MBit ATM controller" } , - { 0x107F, 0x0802, "SL82C105", "EIDE Ctrlr" } , - { 0x1080, 0x0600, "82C599", "VL Bridge" } , - { 0x1083, 0x0001, "FR710", "EIDE Ctrlr" } , - { 0x1083, 0x0613, "", "Host Bridge" } , - { 0x108A, 0x0001, "Model 617", "PCI-VME Bus Adapter" } , - { 0x108D, 0x0001, "", "Ethernet Ctrlr" } , - { 0x1091, 0x0020, "", "3D Graphics Processor" } , - { 0x1091, 0x0021, "", "3D graphics processor w/texturing" } , - { 0x1091, 0x0040, "", "3D graphics frame buffer" } , - { 0x1091, 0x0041, "", "3D graphics frame buffer" } , - { 0x1091, 0x0060, "", "Proprietary bus Bridge" } , - { 0x1091, 0x0720, "", "Motion JPEG Codec" } , - { 0x1093, 0xC801, "PCI-GPIB", "GPIB Controller Interface Board" } , - { 0x1095, 0x0640, "PCI0640A", "EIDE Ctrlr" } , - { 0x1095, 0x0642, "", "IDE Cntrlr w/RAID 1" } , - { 0x1095, 0x0643, "PCI0643", "PCI EIDE controller" } , - { 0x1095, 0x0646, "PCI0646", "bus master IDE" } , - { 0x1095, 0x0650, "PBC0650A", "Fast SCSI-II Ctrlr" } , - { 0x1095, 0x0670, "USB0670", "PCI-USB ASIC" } , - { 0x1095, 0x0673, "USB0673", "PCI-USB ASIC" } , - { 0x1098, 0x0001, "QD-8500", "" } , - { 0x1098, 0x0002, "QD-8580", "" } , - { 0x109E, 0x0350, "BT848", "TV/PCI with DMA Push" } , - { 0x109E, 0x0351, "Bt849", "" } , - { 0x109E, 0x2115, "BtV 2115", "BtV Mediastream Controller" } , - { 0x109E, 0x2125, "BtV 2125", "BtV Mediastream Controller" } , - { 0x109E, 0x8230, "?", "?" } , - { 0x10A8, 0x0000, "?", "64-bit GUI Accelerator" } , - { 0x10AA, 0x0000, "2188", "ACCM 2188 VL-PCI Bridge (Pentium)" } , - { 0x10AD, 0x0001, "W83769F", "EIDE Ctrlr" } , - { 0x10AD, 0x0103, "sl82c103", "PCI-ide mode 4.5 Cntrlr" } , - { 0x10AD, 0x0105, "sl82c105", "- bus master PCI-ide mode 4.5 Cntrlr" } , - { 0x10B5, 0x9036, "PCI9036", "Interface chip" } , - { 0x10B5, 0x9050, "PCI 9050", "Target PCI Interface Chip" } , - { 0x10B5, 0x9060, "PCI9060xx", "Interface chip" } , - { 0x10B5, 0x9080, "PCI 9080", "High performance PCI to Local Bus chip" } , - { 0x10B6, 0x0001, "Smart 16/4", "Ringnode" } , - { 0x10B6, 0x0004, "", "Smart 16/4 Ringnode" } , - { 0x10B6, 0x1000, "Collage 25", "ATM adapter" } , - { 0x10B6, 0x1001, "Collage 155", "ATM adapter" } , - { 0x10B7, 0x0001, "3C985", "Gigabit Etherlink" } , - { 0x10B7, 0x5900, "3C590", "Ethernet 10bT" } , - { 0x10B7, 0x5950, "3C595", "Ethernet 100bTX" } , - { 0x10B7, 0x5951, "3C595", "Ethernet 100bT4" } , - { 0x10B7, 0x5952, "3C595", "Ethernet 100b-MII" } , - { 0x10B7, 0x8811, "", "Token Ring" } , - { 0x10B7, 0x9000, "3C900-TPO", "Fast Etherlink XL PCI 10" } , - { 0x10B7, 0x9001, "3C900-COMBO", "Fast Etherlink XL PCI 10" } , - { 0x10B7, 0x9050, "3C905-TX", "Fast Etherlink XL PCI 10/100" } , - { 0x10B7, 0x9051, "3C905-T4", "Fast Etherlink XL 10/100" } , - { 0x10B7, 0x9055, "3C905B", "Fast Etherlink XL 10/100" } , - { 0x10B8, 0x1000, "37C665", "FDC" } , - { 0x10B8, 0x1001, "37C922", "FDC" } , - { 0x10B8, 0xA011, "83C170QF", "Fast ethernet controller" } , - { 0x10B9, 0x1435, "M1435", "VL Bridge" } , - { 0x10B9, 0x1445, "M1445", "VL Bridge w/EIDE" } , - { 0x10B9, 0x1449, "M1449", "ISA Bridge" } , - { 0x10B9, 0x1451, "M1451", "Pentium Chipset" } , - { 0x10B9, 0x1461, "M1461", "P54C Chipset" } , - { 0x10b9, 0x1531, "M1531B", "ALi Aladdin IV Host Bridge" } , - { 0x10B9, 0x1533, "M1533", "PCI South Bridge" } , - { 0x10B9, 0x1541, "M1541", "Aladdin V AGPset Host Bridge" } , - { 0x10B9, 0x1543, "M1543", "Aladdin V AGPset South Bridge" } , - { 0x10b9, 0x1621, "M1621", "Aladdin-Pro II Northbridge" } , - { 0x10b9, 0x1631, "M1631", "Aladdin Pro III Northbridge" } , - { 0x10B9, 0x3141, "M3141", "GUI Accelerator" } , - { 0x10B9, 0x3143, "M3143", "GUI Accelerator" } , - { 0x10B9, 0x3145, "M3145", "GUI Accelerator" } , - { 0x10B9, 0x3147, "M3147", "GUI Accelerator" } , - { 0x10B9, 0x3149, "M3149", "GUI Accelerator" } , - { 0x10B9, 0x3151, "M3151", "GUI Accelerator" } , - { 0x10B9, 0x5215, "MS4803", "EIDE Ctrlr" } , - { 0x10B9, 0x5217, "m5217h", "I/O (?)" } , - { 0x10B9, 0x5219, "m5219", "I/O (?)" } , - { 0x10B9, 0x5229, "M1543 Southbridge", "PCI-to-ISA Bus Bridge with Super I/O" } , - { 0x10B9, 0x5235, "m5225", "I/O (?)" } , - { 0x10b9, 0x5237, "M1541A", "Aladdin V USB Controller" } , - { 0x10b9, 0x5243, "M1541A", "Aladdin V PCI-to-PCI Bridge" } , - { 0x10b9, 0x5247, "M5247", "Aladdin V built-in PCI-to-PCI bridge" } , - { 0x10BD, 0x0E34, "NE34", "NE2000 PCI clone" } , - { 0x10BD, 0x5240, "", "IDE Cntrlr" } , - { 0x10BD, 0x5241, "", "PCMCIA Bridge" } , - { 0x10BD, 0x5242, "", "General Purpose Cntrlr" } , - { 0x10BD, 0x5243, "", "Bus Cntrlr" } , - { 0x10BD, 0x5244, "", "FCD Cntrlr" } , - { 0x10C8, 0x0000, "", "Graphics Cntrlr" } , - { 0x10C8, 0x0003, "", "NeoMagic MagicGraph 128ZV" } , - { 0x10C8, 0x0005, "", "MagicGraph 256AV" } , - { 0x10C8, 0x0083, "NM2097", "Graphic Controller NeoMagic MagicGraph128ZV+" } , - { 0x10CD, 0x1100, "", "SCSI I/O Cntrlr" } , - { 0x10CD, 0x1200, "ASC1200", "Fast SCSI-II" } , - { 0x10CD, 0x1300, "ASC-3050", "ASC-3150" } , - { 0x10CF, 0x2001, "mb86605", "Wide SCSI-2" } , - { 0x10D9, 0x0531, "MX98715", "Single Chip Fast Ethernet NIC Controller" } , - { 0x10DC, 0x0002, "ATT 2C15-3 (FPGA)", "SCI bridge on PCI 5 Volt card" } , - { 0x10DC, 0x0010, "680-1110-150/400", "Simple PMC/PCI to S-LINK interface" } , - { 0x10DC, 0x0011, "680-1110-200/450", "Simple S-LINK to PMC/PCI interface" } , - { 0x10DC, 0x10DC, "ATT 2C15-3 (FPGA)", "" } , - { 0x10DD, 0x0001, "", "3D graphics processor" } , - { 0x10DE, 0x0018, "Riva 128", "Riva 128 accelerator" } , - { 0x10DE, 0x0020, "Riva TNT", "AGP" } , - { 0x10DE, 0x0028, "Riva TNT2", "Riva TNT2" } , - { 0x10DF, 0x1AE5, "", "Fibre Channel Host Adapter" } , - { 0x10E0, 0x5026, "IMS5026/27/28", "VL Bridge" } , - { 0x10E0, 0x5028, "", "ISA Bridge" } , - { 0x10E0, 0x8849, "8849", "VL Bridge" } , - { 0x10E0, 0x8853, "", "ATM network card" } , - { 0x10E0, 0x9128, "IMS9129", "GUI Accelerator" } , - { 0x10E3, 0x0000, "CA91C042", "VMEbus Bridge" } , - { 0x10E3, 0x0860, "CA91C860", "Motorola Processor Bridge" } , - { 0x10E3, 0x0862, "CA91L826A", "PCI to Motorola Processor Bridge" } , - { 0x10E8, 0x4750, "S5933", "PCI Ctrlr" } , - { 0x10E8, 0x8033, "BBK-PCI light", "Transputer Link Interface" } , - { 0x10E8, 0x8043, "LANai4.x", "Myrinet LANai interface chip" } , - { 0x10E8, 0x8088, "FS", "Kongsberg Spacetec Format Synchronizer" } , - { 0x10E8, 0x8089, "SOB", "Kongsberg Spacetec Serial Output Board" } , - { 0x10E8, 0x811A, "PCI-DSlink", "PCI-IEEE1355-DS-DE interface" } , - { 0x10EB, 0x0101, "3GA", "64 bit graphics processor" } , - { 0x10EC, 0x8029, "RTL8029", "NE2000 compatible Ethernet" } , - { 0x10ec, 0x8139, "RTL8139", "Fast ethernet" } , - { 0x10ED, 0x7310, "V7310", "VGA Video Overlay Adapter" } , - { 0x10F0, 0xA800, "VCL-P", "Graphics board" } , - { 0x10F0, 0xB300, "VCL-M", "graphics board" } , - { 0x10F5, 0xA001, "NDR4000", "NR4600 Bridge" } , - { 0x10FA, 0x0000, "", "GUI Accelerator" } , - { 0x10FA, 0x0001, "", "GUI Accelerator" } , - { 0x10FA, 0x0002, "", "GUI Accelerator" } , - { 0x10FA, 0x0003, "", "GUI Accelerator" } , - { 0x10FA, 0x0004, "", "GUI Accelerator" } , - { 0x10FA, 0x0005, "", "GUI Accelerator" } , - { 0x10FA, 0x0006, "", "GUI Accelerator" } , - { 0x10FA, 0x0007, "", "GUI Accelerator" } , - { 0x10FA, 0x0008, "", "GUI Accelerator" } , - { 0x10FA, 0x0009, "", "GUI Accelerator" } , - { 0x10FA, 0x0010, "", "GUI Accelerator" } , - { 0x10FA, 0x0011, "", "GUI Accelerator" } , - { 0x10FA, 0x0012, "", "GUI Accelerator" } , - { 0x10FA, 0x0013, "", "GUI Accelerator" } , - { 0x10FA, 0x0014, "", "GUI Accelerator" } , - { 0x10FA, 0x0015, "", "GUI Accelerator" } , - { 0x1101, 0x9100, "", "8-bit Fast-wide SCSI" } , - { 0x1101, 0x9400, "INIC-940", "Fast Wide SCSI" } , - { 0x1101, 0x9700, "", "Fast Wide SCSI" } , - { 0x1102, 0x0002, "EMU10000", "Sound Blaster Live!" } , - { 0x1102, 0x7002, "EMU10000", "Game Port" } , - { 0x1105, 0x8300, "VM491", "DVD/MPEG-2 accelerator" } , - { 0x1106, 0x0505, "82C505", "VL Bridge" } , - { 0x1106, 0x0561, "82C561", "IDE" } , - { 0x1106, 0x0571, "VT82C586/686", "PCI IDE Controller" } , - { 0x1106, 0x0576, "82C576", "P54 Ctrlr" } , - { 0x1106, 0x0585, "VT82C585VP", "Host Bus-PCI Bridge" } , - { 0x1106, 0x0586, "VT82C586VP", "PCI-to-ISA Bridge" } , - { 0x1106, 0x0595, "VP2", "Apollo VP2" } , - { 0x1106, 0x0596, "VT82C596", "PCI ISA Bridge" } , - { 0x1106, 0x0597, "VT82C597", "Host Bridge (Apollo VP3)" } , - { 0x1106, 0x0598, "VT82C598", "Apollo MVP3 Host Bridge" } , - { 0x1106, 0x0686, "VT82C686", "PCI-to-ISA bridge" } , - { 0x1106, 0x0691, "VT82C691", "Apollo Pro Host Bridge" } , - { 0x1106, 0x0693, "VT82C693", "Apollo Pro+ Host Bridge" } , - { 0x1106, 0x0926, "VT86C926", "Ethernet Ctrlr (NE2000 compatible)" } , - { 0x1106, 0x1000, "82C570MV", "P54 Ctrlr" } , - { 0x1106, 0x1106, "82C570MV", "ISA Bridge w/IDE" } , - { 0x1106, 0x3038, "VT83C572", "PCI USB Controller" } , - { 0x1106, 0x3040, "VT82C586B", "power management" } , - { 0x1106, 0x3050, "VT82C596", "Power Management Controller" } , - { 0x1106, 0x3058, "VT82C686", "Audio Codec 97" } , - { 0x1106, 0x3068, "VT82C686", "Modem Codec 97" } , - { 0x1106, 0x3086, "VT82C686", "Power management" } , - { 0x1106, 0x8597, "VT82C597", "PCI-to-PCI Bridge (AGP)" } , - { 0x1106, 0x8598, "VT82C598", "Apollo MVP3 PCI-to-PCI Bridge" } , - { 0x1106, 0x8691, "VT82C691", "Apollo Pro PCI-to-PCI Bridge" } , - { 0x1106, 0x8693, "VT82C693", "Apollo Pro+ PCI-to-PCI Bridge" } , - { 0x1108, 0x0100, "p1690plus-AA", "Token Ring Adapter" } , - { 0x1108, 0x0101, "p1690plus-AB", "2-Port Token Ring Adapter" } , - { 0x1109, 0x1400, "EM110TX", "EX110TX PCI Fast Ethernet Adapter" } , - { 0x110A, 0x113C, "FPGA-CPTR", "Hardware Tracer for CP113C / CP113D" } , - { 0x110A, 0x3160, "MCCA", "Pentium-PCI Host Bridge Core ASIC" } , - { 0x110A, 0x4942, "FPGA-IBTR", "I-Bus Tracer for MBD" } , - { 0x110A, 0x6120, "SZB6120", "Multimedia Adapter" } , - { 0x1112, 0x2200, "", "FDDI adapter" } , - { 0x1112, 0x2300, "", "fast ethernet adapter" } , - { 0x1112, 0X2340, "4 Port FEN Adapter", "4 10/100 UTP Fast Ethernet Adapter" } , - { 0x1112, 0x2400, "", "ATM adapter" } , - { 0x1117, 0x9500, "", "max-lc SVGA card" } , - { 0x1117, 0x9501, "", "max-lc image processing" } , - { 0x1119, 0x0000, "GDT6000/6020/6050", "SCSI RAID" } , - { 0x1119, 0x0001, "GDT6000/6010", "SCSI RAID" } , - { 0x1119, 0x0002, "GDT6110/6510", "SCSI RAID" } , - { 0x1119, 0x0003, "GDT6120/6520", "2-chan SCSI RAID" } , - { 0x1119, 0x0004, "GDT6530", "3-chan SCSI RAID" } , - { 0x1119, 0x0005, "GDT6550", "5-chan SCSI RAID" } , - { 0x111A, 0x0000, "155P-MF1", "" } , - { 0x111C, 0x0001, "", "Powerbus Bridge" } , - { 0x111F, 0x5243, "", "Frame Capture Bus Interface" } , - { 0x112E, 0x0000, "", "EIDE/hdd and IDE/cd-rom Ctrlr" } , - { 0x112E, 0x000B, "", "EIDE/hdd and IDE/cd-rom Ctrlr" } , - { 0x112F, 0x0000, "ICPCI", "" } , - { 0x112F, 0x0001, "", "video frame grabber/processor" } , - { 0x1131, 0x2780, "tda 2780 AQ", "Tv deflection" } , - { 0x1131, 0x5400, "TM100", "TriMedia" } , - { 0x1131, 0x7146, "SAA7146", "Multi Media Bridge Scaler" } , - { 0x1134, 0x0001, "", "Raceway Bridge" } , - { 0x1135, 0x0001, "", "Printer Cntrlr" } , - { 0x1138, 0x8905, "8905", "STD 32 Bridge" } , - { 0x1139, 0x0001, "", "VGA" } , - { 0x1139, 0x0001, "", "VGA compatible 3D graphics" } , - { 0x1141, 0x0001, "", "EIDE/ATAPI super adapter" } , - { 0x1142, 0x3210, "ProMotion 3210", "VGA/AVI Playback Accelerator" } , - { 0x1142, 0x6410, "", "GUI Accelerator" } , - { 0x1142, 0x6412, "", "GUI Accelerator" } , - { 0x1142, 0x6420, "", "GUI Accelerator" } , - { 0x1142, 0x6422, "Provideo", "" } , - { 0x1142, 0x6424, "", "GUI Accelerator" } , - { 0x1142, 0x6426, "", "GUI Accelerator" } , - { 0x1144, 0x0001, "", "Noservo Cntrlr" } , - { 0x1148, 0x4000, "", "FDDI adapter" } , - { 0x1158, 0x3011, "", "Tokenet/vg 1001/10m anylan" } , - { 0x1158, 0x9051, "", "Lanfleet/Truevalue" } , - { 0x1159, 0x0001, "MV1000", "" } , - { 0x1161, 0x0001, "", "Host Bridge" } , - { 0x1165, 0x0001, "", "Motion JPEG rec/play w/audio" } , - { 0x1166, 0x0005, "", "PCI Host Bridge (Southbridge copy)" } , - { 0x1178, 0xAFA1, "", "Fast Ethernet" } , - { 0x1179, 0x0601, "", "Toshiba CPU to PCI bridge" } , - { 0x1179, 0x060A, "", "Toshiba ToPIC95 CardBus Controller" } , - { 0x1179, 0x0701, "", "PCI Communication Device" } , - { 0x1180, 0x0465, "RL5C465", "CardBus controller" } , - { 0x1180, 0x0466, "RL5C466", "CardBus controller" } , - { 0x1180, 0x0475, "RL5C475", "CardBus controller" } , - { 0x1180, 0x0476, "RL5C476", "CardBus controller" } , - { 0x1186, 0x0100, "DC21041", "" } , - { 0x1189, 0x1592, "", "?" } , - { 0x118C, 0x0014, "PCIB", "C-bus II to PCI bus host bridge chip" } , - { 0x118C, 0x1117, "MAC-94C201B3", "Corollary/Intel Memory Controller Chip" } , - { 0x118D, 0x0001, "n/a", "Raptor-PCI framegrabber" } , - { 0x118D, 0x0012, "Model 12", "Road Runner Frame Grabber" } , - { 0x118D, 0x0014, "Model 14", "Road Runner Frame Grabber" } , - { 0x118D, 0x0024, "Model 24", "Road Runner Frame Grabber" } , - { 0x118D, 0x0044, "Model 44", "Road Runner Frame Grabber" } , - { 0x118D, 0x0112, "Model 12", "Road Runner Frame Grabber" } , - { 0x118D, 0x0114, "Model 14", "Road Runner Frame Grabber" } , - { 0x118D, 0x0124, "Model 24", "Road Runner Frame Grabber" } , - { 0x118D, 0x0144, "Model 44", "Road Runner Frame Grabber" } , - { 0x118D, 0x0212, "Model 12", "Road Runner Frame Grabber" } , - { 0x118D, 0x0214, "Model 14", "Road Runner Frame Grabber" } , - { 0x118D, 0x0224, "Model 24", "Road Runner Frame Grabber" } , - { 0x118D, 0x0244, "Model 44", "Road Runner Frame Grabber" } , - { 0x118D, 0x0312, "Model 12", "Road Runner Frame Grabber" } , - { 0x118D, 0x0314, "Model 14", "Road Runner Frame Grabber" } , - { 0x118D, 0x0324, "Model 24", "Road Runner Frame Grabber" } , - { 0x118D, 0x0344, "Model 44", "Road Runner Frame Grabber" } , - { 0x1191, 0x0001, "", "IDE Ctrlr" } , - { 0x1191, 0x0002, "", "IDE Cntrlr" } , - { 0x1191, 0x0003, "", "SCSI-2 cache Cntrlr" } , - { 0x1191, 0x0004, "atp8400a", "ASIC cache controller" } , - { 0x1191, 0x8001, "", "SCSI-2 cache Cntrlr" } , - { 0x1191, 0x8002, "ATP-850S", "artop SCSI-2 Cntrlr" } , - { 0x1193, 0x0001, "1221", "" } , - { 0x1199, 0x0001, "", "IRMA 3270 PCI Adapter" } , - { 0x1199, 0x0002, "", "Advanced ISCA PCI Adapter" } , - { 0x1199, 0x0201, "", "SDLC PCI Adapter" } , - { 0x11A9, 0x4240, "AMCC S5933Q", "Intelligent Serial Card" } , - { 0x11AB, 0x0146, "GT-64010", "System ctrlr w/PCI for R46xx CPU" } , - { 0x11AB, 0x4801, "GT-48001", "8 port switched ethernet ctrlr" } , - { 0x11AB, 0x4809, "EV-48300", "Evaluation board for the GT-48300" } , - { 0x11AB, 0xF003, "GT-64010", "Primary Image Piranha Image Generator" } , - { 0x11AB, 0xF004, "GT64120", "Primary Image Barracuda Image Generator" } , - { 0x11AD, 0x0002, "NGMC169B", "10/100 Ethernet (NetGear FA310TX)" } , - { 0x11B0, 0x0292, "V292PBC", "Am29030/40 Bridge" } , - { 0x11B0, 0x0960, "V96xPBC", "i960 Bridges for i960 Processors" } , - { 0x11B0, 0xC960, "V96DPC", "i960 Dual PCI Bridge" } , - { 0x11b3, 0001, "", "CHANNEL-IN (BT) Rev 1" } , - { 0x11b3, 0002, "", "CHANNEL-OUT (BT) Rev 1" } , - { 0x11b3, 0010, "", "CHANNEL-IN (ES)" } , - { 0x11b3, 0100, "", "SYNC MAX PCI" } , - { 0x11b3, 1001, "", "CHANNEL-IN (BT) Rev 2" } , - { 0x11b3, 1002, "", "CHANNEL-OUT (BT) Rev 2" } , - { 0x11B9, 0xC0ED, "SSA Ctrlr", "" } , - { 0x11C1, 0x0442, "1646T00", "V.90 Lucent Modem" } , - { 0x11C8, 0x0658, "PSB", "PCI-SCI Bridge" } , - { 0x11C9, 0x0010, "", "16-line serial DMA" } , - { 0x11C9, 0x0011, "", "4-line serial DMA" } , - { 0x11CB, 0x2000, "PCI-9050", "Target Interface" } , - { 0x11CB, 0x4000, "SUPI-1", "Target Interface" } , - { 0x11CB, 0x8000, "T225", "Bridge" } , - { 0x11D1, 0x01F7, "VxP524", "PCI Video Processor" } , - { 0x11F8, 0x7375, "PM7375", "LASAR-155 ATM SAR" } , - { 0x1208, 0x4853, "", "HS-Link Device" } , - { 0x120E, 0x0100, "Cyclom-Y", "Multiport Serial Card" } , - { 0x120E, 0x0200, "Cyclom-Z", "Intelligent Multiport Serial" } , - { 0x1217, 0x6832, "OZ6832", "CardBus Controller" } , - { 0x121A, 0x0001, "Voodoo", "Voodoo 3D Acceleration Chip" } , - { 0x121A, 0x0002, "Voodoo2", "Voodoo 2 3D Accelerator" } , - { 0x121A, 0x0003, "", "Voodoo Banshee" } , - { 0x121a, 0x4, "", "Voodoo3 2000" } , - { 0x121a, 0x5, "", "Voodoo3 3000" } , - { 0x1244, 0x0700, "AVM", "B1 ISDN controller" } , - { 0x125D, 0x1968, "ES1968", "Maestro-2 PCI audio accelerator" } , - { 0x125D, 0x1969, "ES1938/41/46", "Solo-1 PCI AudioDrive family" } , - { 0x1274, 0x1371, "ES1371", "AudioPCI" } , - { 0x1274, 0x5000, "ES1370", "AudioPCI" } , - { 0x127A, 0x1002, "RC56HCFPCI", "Modem enumerator" } , - { 0x127A, 0x1025, "", "PCI modem" } , - { 0x127A, 0x2014, "", "PCI modem" } , - { 0x12BE, 0x3041, "AN3041Q", "CO-MEM PCI Bus Interface and Cache" } , - { 0x12be, 0x3042, "AN3042", "PCI Generic Host Bridge/Shared Memory" } , - { 0x12C5, 0x007F, "ISE", "PEI Imaging Subsystem Engine" } , - { 0x12C5, 0x0081, "pcivst", "PCI Thresholding Engine" } , - { 0x12D2, 0x0018, "RIVA 128", "Riva 128 2D/3D GUI Accelerator" } , - { 0x12DB, 0x0003, "", "FoxFire II" } , - { 0x12E0, 0x0010, "ST16C654", "Quad UART" } , - { 0x12E0, 0x0020, "ST16C654", "Quad UART" } , - { 0x12E0, 0x0030, "ST16C654", "Quad UART" } , - { 0x12EB, 0x0001, "AU8820", "Vortex Digital Audio Processor" } , - { 0x12eb, 0x0002, "", "Vortex 2 Digital Audio Processor" } , - { 0x1307, 0x0006, "PCI-GPIB", "" } , - { 0x1307, 0x0028, "CIO-DIO24", "24 Bit Digital Input/Output Board" } , - { 0x1318, 0x0911, "G-NIC II", "1000BT Network Interface Card" } , - { 0x1319, 0x0801, "FM801", "PCI audio controller" } , - { 0x144B, 0x0601, "", "" } , - { 0x14D4, 0x0400, "Panacom 7", "Interface chip" } , - { 0x1500, 0x1300, "SIS900", "10/100M PCI Fast Ethernet Controller" } , - { 0x1500, 0x1320, "VT86C100A", "10/100M PCI Fast Ethernet Controler" } , - { 0x1500, 0x1360, "RTL8139A", "10/100 Mbps PCI Fast Ethernet Controller" } , - { 0x1500, 0x1380, "DEC21143PD", "10/100M PCI Fast Ethernet Controller" } , - { 0x1C1C, 0x0001, "FR710", "EIDE Ctrlr" } , - { 0x1C1C, 0x0001, "82C101", "IDE Ctrlr" } , - { 0x1DE1, 0xDC29, "DC290M", "Bus Master IDE PCI 2 controllers" } , - { 0x3D3D, 0x0004, "3C0SX", "GUI Accelerator" } , - { 0x4005, 0x2301, "ALG2301", "GUI Accelerator" } , - { 0x4005, 0x2302, "ALG2302", "GUI Accelerator" } , - { 0x4033, 0x1300, "SIS900", "10/100Mbps Fast Ethernet Controller" } , - { 0x4033, 0x1320, "VT86C100A", "10/100M PCI Fast Ethernet Controller" } , - { 0x4033, 0x1360, "RTL8139A", "10/100 Mbps PCI Fast Ethernet Controller" } , - { 0x4033, 0x1380, "DEC 21143PD", "10/100M PCI Fast Ethernet Controller" } , - { 0x4B10, 0x3080, "", "SCSI - ti" } , - { 0x4B10, 0x4010, "", "Fast/wide SCSI-2" } , - { 0x5333, 0x5631, "86C325", "Virge 3D GUI Accelerator" } , - { 0x5333, 0x8800, "", "Vision 866 GUI Accelerator" } , - { 0x5333, 0x8801, "", "Vision 964 GUI Accelerator" } , - { 0x5333, 0x8810, "86C764", "Trio 32 GUI Accelerator v0" } , - { 0x5333, 0x8811, "86C764", "Trio 32/64 GUI Accelerator v1" } , - { 0x5333, 0x8813, "86C764", "Trio 32/64 GUI Accelerator v3" } , - { 0x5333, 0x883D, "86C988", "ViRGE/VX 3D GUI Accelerator" } , - { 0x5333, 0x8880, "86C868", "Vision 868 GUI Accelerator" } , - { 0x5333, 0x8881, "86C868", "Vision 868 GUI Accelerator" } , - { 0x5333, 0x8882, "86C868", "Vision 868 GUI Accelerator" } , - { 0x5333, 0x8883, "86C868", "Vision 868 GUI Accelerator" } , - { 0x5333, 0x88B0, "86C928", "GUI Accelerator v0" } , - { 0x5333, 0x88B1, "86C928", "GUI Accelerator v1" } , - { 0x5333, 0x88B2, "86C928", "GUI Accelerator v2" } , - { 0x5333, 0x88B3, "86C928", "GUI Accelerator v3" } , - { 0x5333, 0x88C0, "86C864", "GUI Accelerator v0" } , - { 0x5333, 0x88C1, "86C864", "GUI Accelerator v1" } , - { 0x5333, 0x88C2, "86C864", "GUI Accelerator v2" } , - { 0x5333, 0x88C3, "86C864", "GUI Accelerator v3" } , - { 0x5333, 0x88D0, "86C964", "GUI Accelerator v0" } , - { 0x5333, 0x88D1, "86C964", "GUI Accelerator v1" } , - { 0x5333, 0x88D2, "86C964", "GUI Accelerator v2" } , - { 0x5333, 0x88D3, "86C964", "GUI Accelerator v3" } , - { 0x5333, 0x88F0, "86C968", "GUI Accelerator v0" } , - { 0x5333, 0x88F1, "86C968", "GUI Accelerator v1" } , - { 0x5333, 0x88F2, "86C968", "GUI Accelerator v2" } , - { 0x5333, 0x88F3, "86C968", "GUI Accelerator v3" } , - { 0x5333, 0x8901, "Trio 64V2 DX", "S3 Trio 64V2 DX (775)" } , - { 0x5333, 0x8904, "86C365", "Trio3D" } , - { 0x5333, 0x8A01, "82C375/6", "ViRGE/DX & /GX" } , - { 0x5333, 0x8A13, "82C362", "Trio3DX2 AGP" } , - { 0x5333, 0xCA00, "86C617", "SonicVibes PCI Audio Accelerator" } , - { 0x5455, 0x4458, "S5933", "PCI-MyBus-Bridge" } , - { 0x6374, 0x6773, "GPPCI", "PCI Interface" } , - { 0x8001, 0x0010, "ispLSI1032E", "PCI-decoder" } , - { 0x8008, 0x0010, "PWDOG1/2", "PCI-Watchdog 1" } , - { 0x8008, 0x0011, "PWDOG1/2", "Watchdog2/PCI" } , - { 0x8008, 0x0016, "PROTO2", "" } , - { 0x8008, 0x0100, "PREL8", "" } , - { 0x8008, 0x0102, "PREL16", "" } , - { 0x8008, 0x0103, "POPTOREL16", "" } , - { 0x8008, 0x0105, "POPTO16IN", "" } , - { 0x8008, 0x0106, "PTTL24IO", "" } , - { 0x8008, 0x0107, "PUNIREL", "" } , - { 0x8008, 0x1000, "PDAC4", "" } , - { 0x8008, 0x1001, "PAD12DAC4", "" } , - { 0x8008, 0x1002, "PAD16DAC4", "" } , - { 0x8008, 0x1005, "PAD12", "" } , - { 0x8008, 0x1006, "PAD16", "" } , - { 0x8008, 0x3000, "POPTOLCA", "" } , - { 0x8086, 0x0482, "82375EB", "PCI-EISA Bridge (PCEB)" } , - { 0x8086, 0x0483, "82424", "CPU (i486) Bridge (Saturn)" } , - { 0x8086, 0x0484, "82378ZB", "SIO ISA Bridge" } , - { 0x8086, 0x0486, "82425EX", "PCI System Controller (PSC) for i486 (Aries)" } , - { 0x8086, 0x04A3, "82434LX", "CPU (Pentium) Bridge (Mercury)" } , - { 0x8086, 0x0960, "80960RP", "i960 RP Microprocessor/Bridge" } , - { 0x8086, 0x1221, "82092AA", "PCMCIA Bridge" } , - { 0x8086, 0x1222, "82092AA", "IDE Ctrlr" } , - { 0x8086, 0x1223, "SAA7116", "" } , - { 0x8086, 0x1227, "EtherExpress PRO100", "10/100 Fast Ethernet Adapter Card" } , - { 0x8086, 0x1228, "EE PRO/100 Smart", "Intelligent 10/100 Fast Ethernet Adapter" } , - { 0x8086, 0x1229, "82557", "Fast Ethernet LAN Controller" } , - { 0x8086, 0x122D, "82437FX", "System Controller (TSC)" } , - { 0x8086, 0x122E, "82371FB", "PCI to ISA Bridge (Triton)" } , - { 0x8086, 0x1230, "82371FB", "IDE Interface (Triton)" } , - { 0x8086, 0x1234, "82371MX", "Mobile PCI I/O IDE Xcelerator (MPIIX)" } , - { 0x8086, 0x1235, "82437MX", "Mobile System Controller (MTSC)" } , - { 0x8086, 0x1237, "82441FX", "PCI & Memory Controller (PMC)" } , - { 0x8086, 0x1239, "82371FB", "IDE Interface (Triton)" } , - { 0x8086, 0x123C, "82380AB", "Mobile PCI-to-ISA Bridge (MISA)" } , - { 0x8086, 0x124B, "82380FB", "82380FB(MPCI2)" } , - { 0x8086, 0x1250, "82439HX", "System Controller (TXC)" } , - { 0x8086, 0x1960, "80960RP", "i960RP Microprocessor" } , - { 0x8086, 0x2125, "82801AB", "AC97 Audio Controller" } , - { 0x8086, 0x2410, "82801AA", "LPC Interface" } , - { 0x8086, 0x2411, "82801AA", "IDE Controller" } , - { 0x8086, 0x2412, "82801AA", "USB Controller" } , - { 0x8086, 0x2413, "82801AA", "SMBus Controller" } , - { 0x8086, 0x2415, "82801AA", "AC97 Audio Controller" } , - { 0x8086, 0x2416, "82801AA", "AC97 Modem Controller" } , - { 0x8086, 0x2418, "82801AA", "Hub Interface-to-PCI Bridge" } , - { 0x8086, 0x2420, "82801AB", "LPC Interface" } , - { 0x8086, 0x2421, "82801AB", "IDE Controller" } , - { 0x8086, 0x2422, "82801AB", "USB Controller" } , - { 0x8086, 0x2423, "82801AB", "SMBus Controller" } , - { 0x8086, 0x2425, "82801AB", "AC97 Audio Controller" } , - { 0x8086, 0x2426, "82801AB", "AC97 Modem Controller" } , - { 0x8086, 0x2428, "82801AB", "Hub Interface-to-PCI Bridge" } , - { 0x8086, 0x7000, "82371SB", "PIIX3 PCI-to-ISA Bridge (Triton II)" } , - { 0x8086, 0x7010, "82371SB", "PIIX3 IDE Interface (Triton II)" } , - { 0x8086, 0x7020, "82371SB", "PIIX3 USB Host Controller (Triton II)" } , - { 0x8086, 0x7030, "82437VX", "System Controller" } , - { 0x8086, 0x7051, "PB 642365-003", "Intel Business Video Conferencing Card" } , - { 0x8086, 0x7100, "430TX", "82439TX MTXC System Ctrlr" } , - { 0x8086, 0x7110, "82371AB", "PIIX4 ISA Bridge" } , - { 0x8086, 0x7111, "82371AB", "PIIX4 IDE Controller" } , - { 0x8086, 0x7112, "82371AB", "PIIX4 USB Interface" } , - { 0x8086, 0x7113, "82371AB", "PIIX4 Power Management Controller" } , - { 0x8086, 0x7120, "82810", "Host-Hub Interface Bridge / DRAM Ctrlr" } , - { 0x8086, 0x7121, "82810", "Graphics Device" } , - { 0x8086, 0x7122, "82810-DC100", "Host-Hub Interface Bridge / DRAM Ctrlr" } , - { 0x8086, 0x7123, "82810-DC100", "Graphics Device" } , - { 0x8086, 0x7180, "82443LX/EX (PAC)", "Host/PCI bridge in 440LX/EX AGP chipset" } , - { 0x8086, 0x7181, "", "AGP device in 440LX/EX AGP chipset" } , - { 0x8086, 0x7190, "82443BX/ZX", "440BX/ZX AGPset Host Bridge" } , - { 0x8086, 0x7191, "82443BX/ZX", "440BX/ZX AGPset PCI-to-PCI bridge" } , - { 0x8086, 0x7192, "82443BX/ZX", "440BX/ZX chipset Host-to-PCI Bridge" } , - { 0x8086, 0x71A0, "82443GX", "Host-to-PCI Bridge" } , - { 0x8086, 0x71A1, "82443GX", "PCI-to-PCI Bridge (AGP)" } , - { 0x8086, 0x71A2, "82443GX", "Host-to-PCI Bridge" } , - { 0x8086, 0x7800, "i740", "i740 Display Adapter" } , - { 0x8086, 0x84C4, "82450KX/GX", "450KX/GX PCI Bridge (Orion)" } , - { 0x8086, 0x84C5, "82453KX/GX", "450KX/GX Memory Controller (Orion)" } , - { 0x8086, 0x84CA, "82451NX", "450NX PCIset Memory & I/O Controller" } , - { 0x8086, 0x84CB, "82454NX", "450NX PCIset PCI Expander Bridge" } , - { 0x8800, 0x2008, "", "video assistant component" } , - { 0x9004, 0x1078, "AIC-7810C", "RAID Coprocessor" } , - { 0x9004, 0x3B78, "AHA-4944W/4944UW", "QuadChannel Fast-Wide/Ultra-Wide Diff. SCSI Ctrlr" } , - { 0x9004, 0x5075, "AIC-755x", "SCSI Ctrlr" } , - { 0x9004, 0x5078, "AVA-29xx", "AVA-2902I/AVA-2902E/AVA-2904/AVA-2910 SCSI Ctrlr" } , - { 0x9004, 0x5175, "AIC-755x", "SCSI Ctrlr" } , - { 0x9004, 0x5178, "AIC-7850", "FAST-SCSI Ctrlr" } , - { 0x9004, 0x5275, "AIC-755x", "SCSI Ctrlr" } , - { 0x9004, 0x5278, "AIC-7850", "Fast SCSI Ctrlr" } , - { 0x9004, 0x5375, "AIC-755x", "SCSI Ctrlr" } , - { 0x9004, 0x5378, "AIC-7850", "Fast SCSI Ctrlr" } , - { 0x9004, 0x5475, "AIC-755x", "SCSI Ctrlr" } , - { 0x9004, 0x5478, "AIC-7850", "Fast SCSI Ctrlr" } , - { 0x9004, 0x5575, "AVA-2930", "SCSI Ctrlr" } , - { 0x9004, 0x5578, "AIC-7855", "Fast SCSI Ctrlr" } , - { 0x9004, 0x5675, "AIC-755x", "SCSI Ctrlr" } , - { 0x9004, 0x5678, "AIC-7856", "Fast SCSI Ctrlr" } , - { 0x9004, 0x5775, "AIC-755x", "SCSI Ctrlr" } , - { 0x9004, 0x5778, "AIC-7850", "Fast SCSI Ctrlr" } , - { 0x9004, 0x5800, "AIC-5800", "PCI-to-1394 Ctrlr" } , - { 0x9004, 0x6078, "AIC-7860", "SCSI Ctrlr" } , - { 0x9004, 0x6178, "AHA-2940AU", "SCSI Ctrlr" } , - { 0x9004, 0x6278, "AIC-7860", "SCSI Ctrlr" } , - { 0x9004, 0x6378, "AIC-7860", "SCSI Ctrlr" } , - { 0x9004, 0x6478, "AIC-786x", "SCSI Ctrlr" } , - { 0x9004, 0x6578, "AIC-786x", "SCSI Ctrlr" } , - { 0x9004, 0x6678, "AIC-786x", "SCSI Ctrlr" } , - { 0x9004, 0x6778, "AIC-786x", "SCSI Ctrlr" } , - { 0x9004, 0x7078, "AIC-7870", "Fast and Wide SCSI Ctrlr" } , - { 0x9004, 0x7178, "AHA-2940/2940W", "Fast/Fast-Wide SCSI Ctrlr" } , - { 0x9004, 0x7278, "AHA-3940/3940W", "Multichannel Fast/Fast-Wide SCSI Ctrlr" } , - { 0x9004, 0x7378, "AHA-3985", "4-chan RAID SCSI Ctrlr" } , - { 0x9004, 0x7478, "AHA-2944", "SCSI Ctrlr" } , - { 0x9004, 0x7578, "AHA-3944/3944W", "Multichannel Fast/Fast-Wide Diff. SCSI Ctrlr" } , - { 0x9004, 0x7678, "AHA-4944W/4944UW", "QuadChannel Fast-Wide/Ultra-Wide Diff. SCSI Ctrlr" } , - { 0x9004, 0x7778, "AIC-787x", "SCSI Ctrlr" } , - { 0x9004, 0x7810, "aic 7810", "Memory control IC" } , - { 0x9004, 0x7850, "aic-7850", "SCSI IC" } , - { 0x9004, 0x7855, "aha 2930", "Single SCSI channel" } , - { 0x9004, 0x7860, "AIC-7860", "SCSI Ctrlr" } , - { 0x9004, 0x7870, "aic-7870", "SCSI IC" } , - { 0x9004, 0x7871, "aha 2940", "SCSI" } , - { 0x9004, 0x7872, "aha 3940", "Multiple SCSI channels" } , - { 0x9004, 0x7873, "aha 3980", "Multiple SCSI channels" } , - { 0x9004, 0x7874, "aha 2944", "Differential SCSI" } , - { 0x9004, 0x7880, "aic7880", "Fast 20 SCSI" } , - { 0x9004, 0x7890, "AIC-7890", "SCSI controller" } , - { 0x9004, 0x7891, "AIC-789x", "SCSI controller" } , - { 0x9004, 0x7892, "AIC-789x", "SCSI controller" } , - { 0x9004, 0x7893, "AIC-789x", "SCSI controller" } , - { 0x9004, 0x7894, "AIC-789x", "SCSI controller" } , - { 0x9004, 0x7895, "AIC-7895", "Ultra-Wide SCSI Ctrlr on AHA-2940 AHA-394x" } , - { 0x9004, 0x7896, "AIC-789x", "SCSI controller" } , - { 0x9004, 0x7897, "AIC-789x", "SCSI controller" } , - { 0x9004, 0x8078, "AIC-7880", "Ultra Wide SCSI" } , - { 0x9004, 0x8178, "AHA-2940U/2940UW", "Ultra/Ultra-Wide SCSI Ctrlr" } , - { 0x9004, 0x8278, "AHA-3940Uxx", "AHA-3940U/3940UW/3940UWD SCSI Ctrlr" } , - { 0x9004, 0x8478, "AHA-2944UW", "Ultra-Wide Diff. SCSI Ctrlr" } , - { 0x9004, 0x8578, "AHA-3944U/3944UWD", "Fast-Wide/Ultra-Wide Diff. SCSI Ctrlr" } , - { 0x9004, 0x8678, "AHA-4944UW", "QuadChannel Ultra-Wide Diff. SCSI Ctrlr" } , - { 0x9004, 0x8778, "AIC-788x", "Ultra-Wide SCSI Ctrlr" } , - { 0x9004, 0xEC78, "AHA-4944W/4944UW", "QuadChannel Fast-Wide/Ultra-Wide Diff. SCSI Ctrlr" } , - { 0x9005, 0x001f, "AIC-7890", "Ultra2-Wide SCSI controller" } , - { 0x907F, 0x2015, "IDE-2015PL", "EIDE Ctrlr" } , - { 0xD4D4, 0x0601, "", "" } , - { 0xEDD8, 0xA091, "Stingray", "GUI Accelerator" } , - { 0xEDD8, 0xA099, "Stingray", "2000PV GUI Accelerator" } , - { 0xEDD8, 0xA0A1, "ark2000mt", "64-bit GUI accelerator w/DCI playback" } , - { 0xFFFF, 0x0140, "BAD !", "BAD Buslogic BT-946C SCSI?" } , - { 0x1234, 0x1111, "BOCHS", "BOCHS Emulator Graphics Adaptor"} // Custom addition -} ; - -// Use this value for loop control during searching: -#define PCI_DEVTABLE_LEN (sizeof(PciDevTable)/sizeof(PCI_DEVTABLE)) - - -/** @brief PCI class code structure */ -typedef struct _PCI_CLASSCODETABLE -{ - /// Base class identifier - unsigned short BaseClass ; - /// Sub class identifier - unsigned short SubClass ; - /// Programming interface identifier - unsigned short ProgIf ; - /// Base class description string - char * BaseDesc ; - /// Sub class description string - char * SubDesc ; - /// Programming interface description string - char * ProgDesc ; -} PCI_CLASSCODETABLE, *PPCI_CLASSCODETABLE ; - -static const PCI_CLASSCODETABLE PciClassCodeTable [] = -{ - { 0x00, 0x00, 0x00, "Pre-2.0 PCI Specification Device", "Non-VGA","" } , - { 0x00, 0x01, 0x00, "Pre-2.0 PCI Specification Device", "VGA Compatible", "" } , - - { 0x01, 0x00, 0x00, "Mass Storage Controller", "SCSI", "" } , - { 0x01, 0x01, 0x00, "Mass Storage Controller", "IDE", "" } , - { 0x01, 0x02, 0x00, "Mass Storage Controller", "Floppy", "" } , - { 0x01, 0x03, 0x00, "Mass Storage Controller", "IPI", "" } , - { 0x01, 0x04, 0x00, "Mass Storage Controller", "RAID", "" } , - { 0x01, 0x80, 0x00, "Mass Storage Controller", "Other", "" } , - - { 0x02, 0x00, 0x00, "Network Controller", "Ethernet", "" } , - { 0x02, 0x01, 0x00, "Network Controller", "Token Ring", "" } , - { 0x02, 0x02, 0x00, "Network Controller", "FDDI", "" } , - { 0x02, 0x03, 0x00, "Network Controller", "ATM", "" } , - { 0x02, 0x80, 0x00, "Network Controller", "Other", "" } , - - { 0x03, 0x00, 0x00, "Display Controller", "PC Compatible", "VGA" } , - { 0x03, 0x00, 0x01, "Display Controller", "PC Compatible", "8514" } , - { 0x03, 0x01, 0x00, "Display Controller", "XGA", "" } , - { 0x03, 0x80, 0x00, "Display Controller", "Other", "" } , - - { 0x04, 0x00, 0x00, "Multimedia Device", "Video", "" } , - { 0x04, 0x01, 0x00, "Multimedia Device", "Audio", "" } , - { 0x04, 0x80, 0x00, "Multimedia Device", "Other", "" } , - - { 0x05, 0x00, 0x00, "Memory Controller", "RAM", "" } , - { 0x05, 0x01, 0x00, "Memory Controller", "Flash", "" } , - { 0x05, 0x80, 0x00, "Memory Controller", "Other", "" } , - - { 0x06, 0x00, 0x00, "Bridge Device", "Host/PCI", "" } , - { 0x06, 0x01, 0x00, "Bridge Device", "PCI/ISA", "" } , - { 0x06, 0x02, 0x00, "Bridge Device", "PCI/EISA", "" } , - { 0x06, 0x03, 0x00, "Bridge Device", "PCI/Micro Channel", "" } , - { 0x06, 0x04, 0x00, "Bridge Device", "PCI/PCI", "" } , - { 0x06, 0x05, 0x00, "Bridge Device", "PCI/PCMCIA", "" } , - { 0x06, 0x06, 0x00, "Bridge Device", "PCI/NuBus", "" } , - { 0x06, 0x07, 0x00, "Bridge Device", "PCI/CardBus", "" } , - { 0x06, 0x80, 0x00, "Bridge Device", "Other", "" } , - - { 0x07, 0x00, 0x00, "Simple Communications Controller", "Serial", "Generic XT Compatible" } , - { 0x07, 0x00, 0x01, "Simple Communications Controller", "Serial", "16450 Compatible" } , - { 0x07, 0x00, 0x02, "Simple Communications Controller", "Serial", "16550 Compatible" } , - { 0x07, 0x01, 0x00, "Simple Communications Controller", "Parallel", "Standard" } , - { 0x07, 0x01, 0x00, "Simple Communications Controller", "Parallel", "Bidirectional" } , - { 0x07, 0x01, 0x01, "Simple Communications Controller", "Parallel", "ECP 1.X Compliant" } , - { 0x07, 0x80, 0x02, "Simple Communications Controller", "Other", "" } , - - { 0x08, 0x00, 0x00, "Base Systems Peripheral", "PIC (Programmable Interrupt Controller)", "Generic 8259" } , - { 0x08, 0x00, 0x01, "Base Systems Peripheral", "PIC (Programmable Interrupt Controller)", "ISA" } , - { 0x08, 0x00, 0x02, "Base Systems Peripheral", "PIC (Programmable Interrupt Controller)", "PCI" } , - { 0x08, 0x01, 0x00, "Base Systems Peripheral", "DMA (Direct Memory Access)", "Generic 8259" } , - { 0x08, 0x01, 0x01, "Base Systems Peripheral", "DMA (Direct Memory Access)", "ISA" } , - { 0x08, 0x01, 0x02, "Base Systems Peripheral", "DMA (Direct Memory Access)", "EISA" } , - { 0x08, 0x02, 0x00, "Base Systems Peripheral", "System Timer", "Generic 8259" } , - { 0x08, 0x02, 0x01, "Base Systems Peripheral", "System Timer", "ISA" } , - { 0x08, 0x02, 0x02, "Base Systems Peripheral", "System Timer", "EISA" } , - { 0x08, 0x03, 0x00, "Base Systems Peripheral", "RTC (Real Time Clock)", "Generic" } , - { 0x08, 0x03, 0x01, "Base Systems Peripheral", "RTC (Real Time Clock)", "ISA" } , - { 0x08, 0x80, 0x00, "Base Systems Peripheral", "Other", "" } , - - { 0x09, 0x00, 0x00, "Input Device", "Keyboard", "" } , - { 0x09, 0x01, 0x00, "Input Device", "Digitizer (Pen)", "" } , - { 0x09, 0x02, 0x00, "Input Device", "Mouse", "" } , - { 0x09, 0x80, 0x00, "Input Device", "Other", "" } , - - { 0x0A, 0x00, 0x00, "Docking Station", "Generic", "" } , - { 0x0A, 0x80, 0x00, "Docking Station", "Other", "" } , - - { 0x0B, 0x00, 0x00, "Processor", "i386", "" } , - { 0x0B, 0x01, 0x00, "Processor", "i486", "" } , - { 0x0B, 0x02, 0x00, "Processor", "Pentium", "" } , - { 0x0B, 0x10, 0x00, "Processor", "Alpha", "" } , - { 0x0B, 0x20, 0x00, "Processor", "Power PC", "" } , - { 0x0B, 0x80, 0x00, "Processor", "Co-processor", "" } , - - { 0x0C, 0x00, 0x00, "Serial Bus Controller", "Firewire (IEEE 1394)", "" } , - { 0x0C, 0x01, 0x00, "Serial Bus Controller", "ACCESS.bus", "" } , - { 0x0C, 0x02, 0x00, "Serial Bus Controller", "SSA (Serial Storage Archetecture)", "" } , - { 0x0C, 0x03, 0x00, "Serial Bus Controller", "USB (Universal Serial Bus)", "" } , - { 0x0C, 0x04, 0x00, "Serial Bus Controller", "Fibre Channel", "" } , - - { 0xFF, 0x00, 0x00, "Unknown", "Device Does Not Fit In Class Codes", "UDF" } , -} ; - -// Use this value for loop control during searching: -#define PCI_CLASSCODETABLE_LEN (sizeof(PciClassCodeTable)/sizeof(PCI_CLASSCODETABLE)) - - -static const char * PciCommandFlags [] = -{ - "I/O Access", - "Memory Access", - "Bus Mastering", - "Special Cycles", - "Memory Write & Invalidate", - "Palette Snoop", - "Parity Errors", - "Wait Cycles", - "System Errors", - "Fast Back-To-Back", - "Reserved 10", - "Reserved 11", - "Reserved 12", - "Reserved 13", - "Reserved 14", - "Reserved 15" -} ; - -// Use this value for loop control during searching: -#define PCI_COMMANDFLAGS_LEN (sizeof(PciCommandFlags)/sizeof(char *)) - - -static const char * PciStatusFlags [] = -{ - "Reserved 0", - "Reserved 1", - "Reserved 2", - "Reserved 3", - "Reserved 4", - "66 MHz Capable", - "User-Defined Features", - "Fast Back-To-Back", - "Data Parity Reported", - "", - "", - "Signalled Target Abort", - "Received Target Abort", - "Received Master Abort", - "Signalled System Error", - "Detected Parity Error" -} ; - -// Use this value for loop control during searching: -#define PCI_STATUSFLAGS_LEN (sizeof(PciStatusFlags)/sizeof(char *)) - - -static const char * PciDevSelFlags [] = -{ - "Fast Devsel Speed", // TypeC - "Medium Devsel Speed", // TypeB - "Slow Devsel Speed", // TypeA - "Reserved 9&10" -} ; - -// Use this value for loop control during searching: -#define PCI_DEVSELFLAGS_LEN (sizeof(PciDevSelFlags)/sizeof(char *)) \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/pic.h b/source/sysroot/usr/include/kernel/pic.h deleted file mode 100644 index a3662720..00000000 --- a/source/sysroot/usr/include/kernel/pic.h +++ /dev/null @@ -1,131 +0,0 @@ -// pic.h - Header file for pic.c (Programmable Interrupt Controller) - -#ifndef PIC_H -#define PIC_H - -// Includes -#include "include/idt.h" // Interrupt Descriptor Table - -#include "include/hal.h" // Hardware Abstraction Layer -#include "include/terminal.h" // Terminal output (printf) -#include "include/libc/stdint.h" // Integer types like uint8_t, uint16_t, etc... - - -// Definitions - - - - -// PIC 1 register port addresses -#define PIC1_REG_COMMAND 0x20 -#define PIC1_REG_STATUS 0x20 -#define PIC1_REG_DATA 0x21 -#define PIC1_REG_IMR 0x21 - -// PIC 2 register port addresses -#define PIC2_REG_COMMAND 0xA0 -#define PIC2_REG_STATUS 0xA0 -#define PIC2_REG_DATA 0xA1 -#define PIC2_REG_IMR 0xA1 - -// Initialization control word 1 bit masks -#define PIC_ICW1_MASK_IC4 0x1 // 00000001 -#define PIC_ICW1_MASK_SNGL 0x2 // 00000010 -#define PIC_ICW1_MASK_ADI 0x4 // 00000100 -#define PIC_ICW1_MASK_LTIM 0x8 // 00001000 -#define PIC_ICW1_MASK_INIT 0x10 // 00010000 - -// Note: Initialization control words 2 and 3 don't require bit masks, so we don't need to define them -// Control word 4, on the other hand does, so we do need to define them. - -// Initialization control word 4 bit masks -#define PIC_ICW4_MASK_UPM 0x1 // 00000001 -#define PIC_ICW4_MASK_AEOI 0x2 // 00000010 -#define PIC_ICW4_MASK_MS 0x4 // 00000100 -#define PIC_ICW4_MASK_BUF 0x8 // 00001000 -#define PIC_ICW4_MASK_SFNM 0x10 // 00010000 - - - -// Moving on to the control bits... -// Initialization command 1 control bits -#define PIC_ICW1_IC4_EXPECT 1 // 1 -#define PIC_ICW1_IC4_NO 0 // 0 -#define PIC_ICW1_SNGL_YES 2 // 10 -#define PIC_ICW1_SNGL_NO 0 // 00 -#define PIC_ICW1_ADI_CALLINTERVAL4 4 // 100 -#define PIC_ICW1_ADI_CALLINTERVAL8 0 // 000 -#define PIC_ICW1_LTIM_LEVELTRIGGERED 8 // 1000 -#define PIC_ICW1_LTIM_EDGETRIGGERED 0 // 0000 -#define PIC_ICW1_INIT_YES 0x10 // 10000 -#define PIC_ICW1_INIT_NO 0 // 00000 - -// Initialization command 4 control bits -#define PIC_ICW4_UPM_86MODE 1 // 1 -#define PIC_ICW4_UPM_MCSMODE 0 // 0 -#define PIC_ICW4_AEOI_AUTOEOI 2 // 10 -#define PIC_ICW4_AEOI_NOAUTOEOI 0 // 00 -#define PIC_ICW4_MS_BUFFERMASTER 4 // 100 -#define PIC_ICW4_MS_BUFFERSLAVE 0 // 0 -#define PIC_ICW4_BUF_MODEYES 8 // 1000 -#define PIC_ICW4_BUF_MODENO 0 // 0 -#define PIC_ICW4_SFNM_NESTEDMODE 0x10 // 10000 -#define PIC_ICW4_SFNM_NOTNESTED 0 // 0 - -// Devices - -// These devices use PIC 1 to generate interrupts -#define PIC_IRQ_TIMER 0 -#define PIC_IRQ_KEYBOARD 1 -#define PIC_IRQ_SERIAL2 3 -#define PIC_IRQ_SERIAL1 4 -#define PIC_IRQ_PARALLEL2 5 -#define PIC_IRQ_DISKETTE 6 -#define PIC_IRQ_PARALLEL1 7 - -// These devices use PIC 2 to generate interrupts -#define PIC_IRQ_CMOSTTIMER 0 -#define PIC_IRQ_CGARETRACE 1 -#define PIC_IRQ_AUXILIARY 4 -#define PIC_IRQ_FPU 5 -#define PIC_IRQ_HDC 6 - - -// Command word bit masks - -// Command word 2 bit masks - use when sending commands -#define PIC_OCW2_MASK_L1 1 // 00000001 -#define PIC_OCW2_MASK_L2 2 // 00000010 -#define PIC_OCW2_MASK_L3 4 // 00000100 -#define PIC_OCW2_MASK_EOI 0x20 // 00100000 -#define PIC_OCW2_MASK_SL 0x40 // 01000000 -#define PIC_OCW2_MASK_ROTATE 0x80 // 10000000 - -// Command word 3 bit masks - use when sending commands -#define PIC_OCW3_MASK_RIS 1 // 00000001 -#define PIC_OCW3_MASK_RIR 2 // 00000010 -#define PIC_OCW3_MASK_MODE 4 // 00000100 -#define PIC_OCW3_MASK_SMM 0x20 // 00100000 -#define PIC_OCW3_MASK_ESMM 0x40 // 01000000 -#define PIC_OCW3_MASK_D7 0x80 // 10000000 - - - -// Function definitions - -// Read data byte from PIC -extern uint8_t picReadData(uint8_t picNum); - -// Send a data byte from PIC -extern void picSendData(uint8_t data, uint8_t picNum); - -// Send operational command to PIC -extern void picSendCommand(uint8_t cmd, uint8_t picNum); - -// Enables and disables interrupts -extern void picMaskIRQ(uint8_t irqmask, uint8_t picNum); - -// Initialize pic -extern void picInit(uint8_t base0, uint8_t base1); - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/pit.h b/source/sysroot/usr/include/kernel/pit.h deleted file mode 100644 index c05b6ae4..00000000 --- a/source/sysroot/usr/include/kernel/pit.h +++ /dev/null @@ -1,70 +0,0 @@ -// pit.h - Header file for pit.c (Programmable Interval Timer) - -#ifndef PIT_H -#define PIT_H - -// Includes -#include "include/idt.h" // Interrupt Descriptor Table -#include "include/pic.h" // Programmable Interrupt Controller -#include "include/hal.h" // Hardware Abstraction Layer -#include "include/terminal.h" // Terminal output (printf) -#include "include/isr.h" // Interrupt Service Routines -#include "include/libc/stdint.h" // Integer declarations - -// Definitions - -// Controller registers -#define PIT_REG_COUNTER0 0x40 -#define PIT_REG_COUNTER1 0x41 -#define PIT_REG_COUNTER2 0x42 -#define PIT_REG_COMMAND 0x43 - - -// Operational command bit masks - -#define PIT_OCW_MASK_BINCOUNT 1 // 00000001 -#define PIT_OCW_MASK_MODE 0xE // 00001110 -#define PIT_OCW_MASK_RL 0x30 // 00110000 -#define PIT_OCW_MASK_COUNTER 0xC0 // 11000000 - - -// Operational command control bits - -// Use these when setting binary count mode -#define PIT_OCW_BINCOUNT_BINARY 0 // 0 -#define PIT_OCW_BINCOUNT_BCD 1 // 1 - -// Use these when setting counter mode -#define PIT_OCW_MODE_TERMINALCOUNT 0 // 0000 -#define PIT_OCW_MODE_ONESHOT 0x2 // 0010 -#define PIT_OCW_MODE_RATEGEN 0x4 // 0100 -#define PIT_OCW_MODE_SQUAREWAVEGEN 0x6 // 0110 -#define PIT_OCW_MODE_SOFTWARETRIG 0x8 // 1000 -#define PIT_OCW_MODE_HARDWARETRIG 0xA // 1010 - -// Use these when setting data transfer -#define PIT_OCW_RL_LATCH 0 // 000000 -#define PIT_OCW_RL_LSBONLY 0x10 // 010000 -#define PIT_OCW_RL_MSBONLY 0x20 // 100000 -#define PIT_OCW_RL_DATA 0x30 // 110000 - -// Use these when setting the counter we're working with -#define PIT_OCW_COUNTER_0 0 // 00000000 -#define PIT_OCW_COUNTER_1 0x40 // 01000000 -#define PIT_OCW_COUNTER_2 0x80 // 10000000 - - - -// Functions - - -void pitSendCommand(uint8_t cmd); // Send operational command to PIT. -void pitSendData(uint16_t data, uint8_t counter); // Write data byte to a counter. -uint32_t pitSetTickCount(uint32_t i); // Sets new PIT tick count and returns prev. value. -uint32_t pitGetTickCount(); // Returns current tick count. -void pitStartCounter(uint32_t freq, uint8_t counter, uint8_t mode); // Starts a counter (counter continues until another call) -void pitInit(); // Initialize PIT -bool pitIsInitialized(); // Check if the PIT is initialized. - - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/pmm.h b/source/sysroot/usr/include/kernel/pmm.h deleted file mode 100644 index 5e9a0427..00000000 --- a/source/sysroot/usr/include/kernel/pmm.h +++ /dev/null @@ -1,60 +0,0 @@ -// pmm.h - Header file for physical memory management - -#ifndef PMM_H -#define PMM_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/libc/string.h" // String functions -#include "include/heap.h" // kmalloc() -#include "include/bootinfo.h" // Multiboot info -#include "include/serial.h" - -// Variables -extern uint32_t *frames; -extern uint32_t nframes; - -// Typedefs -typedef uint32_t physical_address; - - -// Structure for a memory region in a memory map. -// Might be GRUB-specific, dunno. - - -typedef enum { - AVAILABLE = 1, - RESERVED, - ACPI_RECLAIMABLE, - ACPI_NVS, - } MULTIBOOT_MEMORY_TYPE; - - -typedef struct { - uint32_t size; - uint32_t addressLo; - uint32_t addressHi; - uint32_t lengthLo; - uint32_t lengthHi; - MULTIBOOT_MEMORY_TYPE type; - -} memoryRegion_t; - - - -// Functions -void pmm_printMemoryMap(multiboot_info *info); // Print the memory map -void pmm_initializeMemoryMap(multiboot_info *info); // Initialize the memory map -void pmmInit(uint32_t physMemorySize); // Initialize PMM -void pmm_initRegion(uint32_t base, size_t size); // Initialize a region as available memory -void pmm_deinitRegion(uint32_t base, size_t size); // Deinitialize a region as unusable memory. -void *pmm_allocateBlock(); // Allocates a block -void pmm_freeBlock(void *block); // Frees a block -void *pmm_allocateBlocks(size_t size); // Allocates size amount of blocks -void pmm_freeBlocks(void *ptr, size_t size); // Frees blocks in memory -uint32_t pmm_getPhysicalMemorySize(); // Returns amount of physical memory -uint32_t pmm_getMaxBlocks(); // Returns the total amount of memory blocks -uint32_t pmm_getUsedBlocks(); // Returns the amount of used blocks -uint32_t pmm_getFreeBlocks(); // Returns the amount of free blocks - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/processor.h b/source/sysroot/usr/include/kernel/processor.h deleted file mode 100644 index 1ffeb3c1..00000000 --- a/source/sysroot/usr/include/kernel/processor.h +++ /dev/null @@ -1,48 +0,0 @@ -// processor.h - Handles all CPU related functions - -#ifndef PROCESSOR_H -#define PROCESSOR_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/gdt.h" // Global descriptor table -#include "include/idt.h" // Interrupt descriptor table -#include "include/isr.h" // Interrupt service routines -#include "include/hal.h" // Hardware Abstraction Layer - - -// Typedefs - -typedef struct { - int XOP_support; // XOP support - int FMA4_support; // FMA4 support - int CVT16_support; // CVT16 support - int AVX_support; // AVX support (Advanced Vector Extensions) - int XSAVE_support; // XSAVE support (CPU extended power management support) - int AVX2_support; // AVX2 support - // TODO: AVX-512 support -} sseData_t; - -typedef struct { - char vendor[13]; // Vendor data - int long_mode_capable; // Long mode capabilities - uint32_t frequency; // Frequency (in Hz) - - // Streaming SIMD Extensions - int sse_support; // SSE support - int sse2_support; // SSE2 support - int sse3_support; // SSE3 support - int ssse3_support; // SSSE3 Support (Supplemental Streaming SIMD Extensions) - int sse4_support; // SSE4 support - sseData_t sse5_Data; // SSE5 data -} cpuInfo_t; - - - -// Functions -void cpuInit(); // Initializes the CPU with ISR, IDT, and GDT -uint32_t getCPUFrequency(); // Returns the CPU frequency (todo: create processor.c). -bool isCPULongModeCapable(); // Returns if the CPU is 64-bit capable -char *getCPUVendorData(); // Returns CPU vendor data - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/quad.h b/source/sysroot/usr/include/kernel/quad.h deleted file mode 100644 index 0b978a12..00000000 --- a/source/sysroot/usr/include/kernel/quad.h +++ /dev/null @@ -1,3 +0,0 @@ -// This file is here for compatibility reasons. -// If this is still here, give me a little ping in our discord: https://discord.gg/g5XwNxw3u5 -// Thanks for checking out my code! \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/regs.h b/source/sysroot/usr/include/kernel/regs.h deleted file mode 100644 index efebf704..00000000 --- a/source/sysroot/usr/include/kernel/regs.h +++ /dev/null @@ -1,33 +0,0 @@ -// regs.h - simple header file that contains definitions of register structs - -#ifndef REGS_H -#define REGS_H - - -// Includes -#include "include/libc/stdint.h" // Integer declarations - -// Typedefs -typedef struct REGISTERS { - uint32_t ds; - uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; // pushed by pusha - uint32_t int_no, err_code; // Interrupt # and error code - uint32_t eip, cs, eflags, useresp, ss; // pushed by the processor automatically -} registers_t; - -// Registers (16-bit real mode) -typedef struct { - uint16_t di, si, bp, sp, bx, dx, cx, ax; - uint16_t ds, es, fs, gs, ss; - uint16_t eflags; -} REGISTERS_16; - -// A special register struct for multitasking -typedef struct REGISTERS_MULTITASK { - uint32_t ds, es; - uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; // pushed by pusha - uint32_t int_no, err_code; // Interrupt # and error code - uint32_t eip, cs, eflags, useresp, ss; // pushed by the processor automatically -} registers_multitask_t; - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/rtc.h b/source/sysroot/usr/include/kernel/rtc.h deleted file mode 100644 index 2bb75757..00000000 --- a/source/sysroot/usr/include/kernel/rtc.h +++ /dev/null @@ -1,27 +0,0 @@ -// rtc.h - header file for the real-time clock driver - -#ifndef RTC_H -#define RTC_H - -// Includes -#include "include/libc/stdint.h" // Integer definitions -#include "include/hal.h" // Hardware abstraction layer - -// WARNING: The below is a user-created constant! This needs to change each year and cannot automatically update! -#define RTC_CURRENT_YEAR 2023 // wooo 2023 - -// The rest are just ports and stuff. -#define CMOS_ADDRESS 0x70 -#define CMOS_DATA 0x71 - -#define RTC_SECOND_REGISTER 0x00 -#define RTC_MINUTE_REGISTER 0x02 -#define RTC_HOUR_REGISTER 0x04 -#define RTC_DAY_REGISTER 0x07 -#define RTC_MONTH_REGISTER 0x08 -#define RTC_YEAR_REGISTER 0x09 - -// Functions -void rtc_getDateTime(uint8_t *second, uint8_t *minute, uint8_t *hour, uint8_t *day, uint8_t *month, int *year); // Returns the date and time (in the pointers) - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/serial.h b/source/sysroot/usr/include/kernel/serial.h deleted file mode 100644 index 099da348..00000000 --- a/source/sysroot/usr/include/kernel/serial.h +++ /dev/null @@ -1,30 +0,0 @@ -// serial.h - header file for serial.c (serial logging manager) - -#ifndef SERIAL_H -#define SERIAL_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/hal.h" // outportb() and inportb() -#include "include/terminal.h" // printf_putchar function. - -// Definitions -#define SERIAL_COM1 0x3F8 -#define SERIAL_COM2 0x2F8 -#define SERIAL_COM3 0x3E8 -#define SERIAL_COM4 0x2E8 -#define SERIAL_COM5 0x5F8 -#define SERIAL_COM6 0x4F8 -#define SERIAL_COM7 0x5E8 -#define SERIAL_COM8 0x4E8 - -// Variables -extern bool isSerialEnabled; - -// Functions -void serialInit(); // Initialize serial (default port COM1, unchangable as of now.) -char serialRead(); // Read one character from SERIAL_COM1 -void serialReadLine(bool printChars, char *bufferPtr); // Read line from SERIAL_COM1 -void serialWrite(void *user, char c); // Writes character 'c' to serial when transmit is empty. -void serialPrintf(const char *str, ...); // Prints a formatted line to SERIAL_COM1. -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/sleep.h b/source/sysroot/usr/include/kernel/sleep.h deleted file mode 100644 index 57981e62..00000000 --- a/source/sysroot/usr/include/kernel/sleep.h +++ /dev/null @@ -1,12 +0,0 @@ -// sleep.h - header file for sleep.c - -#ifndef SLEEP_H -#define SLEEP_H - -// Includes -#include // Programmable interval timer - -// Functions -void sleep(int ms); // sleep() - stops execution of current task for x milliseconds. - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/spinlock.h b/source/sysroot/usr/include/kernel/spinlock.h deleted file mode 100644 index bfee53d1..00000000 --- a/source/sysroot/usr/include/kernel/spinlock.h +++ /dev/null @@ -1,15 +0,0 @@ -// spinlock.h - header file for the spinlock mechanism - -#ifndef SPINLOCK_H -#define SPINLOCK_H - -// Includes -#include // Integer declarations -#include // For once in our lives, C is on our side!! - -// Functions -atomic_flag *spinlock_init(); // Creates a new spinlock -void spinlock_lock(atomic_flag *lock); // Locks the spinlock -void spinlock_release(atomic_flag *lock); // Releases the spinlock - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/stdarg.h b/source/sysroot/usr/include/kernel/stdarg.h deleted file mode 100644 index 3919e4d9..00000000 --- a/source/sysroot/usr/include/kernel/stdarg.h +++ /dev/null @@ -1,34 +0,0 @@ -// stdarg.h - replacement for standard C header file. -// Why is this required? We use -ffreestanding in our compile options, so the standard std library isn't included. - -// File operates in tandem with va_list.h (va functions/macros here, whilst the actual va_list declaration is in va_list.h) - -#ifndef STDARG_H -#define STDARG_H - -// Includes of other header files -#include - -// Definitions (non-macro) -#define STACKITEM int // Width of stack (width of an int) - -// Macros - -// VA_SIZE(TYPE) - Round up width of objects pushed on stack. -#define VA_SIZE(TYPE) \ - ((sizeof(TYPE) + sizeof(STACKITEM) - 1) \ - & ~(sizeof(STACKITEM) - 1)) - - - - -// va_arg(AP, TYPE) - Retrieve the next argument of type 'TYPE' in va_list 'AP' -/*#define va_arg(AP, TYPE) \ - (AP += VA_SIZE(TYPE), *((TYPE *)(AP - VA_SIZE(TYPE))))*/ - - - -#define va_start(x, y) __builtin_va_start(x, y) -#define va_arg(x, y) __builtin_va_arg(x, y) -#define va_end(x) __builtin_va_end(x) -#endif diff --git a/source/sysroot/usr/include/kernel/stdbool.h b/source/sysroot/usr/include/kernel/stdbool.h deleted file mode 100644 index 2bf923e9..00000000 --- a/source/sysroot/usr/include/kernel/stdbool.h +++ /dev/null @@ -1,16 +0,0 @@ -// stdbool.h - replacement for standard C header file. -// Why is this required? We use -ffreestanding in our compile options, so the standard std library isn't included. - -#ifndef STDBOOL_H -#define STDBOOL_H - -#define true 1 -#define false 0 -#define __bool_true_false_are_defined 1 - -typedef enum { - FALSE, - TRUE -} bool; - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/stddef.h b/source/sysroot/usr/include/kernel/stddef.h deleted file mode 100644 index e89827db..00000000 --- a/source/sysroot/usr/include/kernel/stddef.h +++ /dev/null @@ -1,18 +0,0 @@ -// stddef.h - replacement for standard C header file. -// Why is this required? We use -ffreestanding in our compile options, so the standard std library isn't included. - - -#if 1 - -#include - -#else -// Definitions -#define null 0 -#define NULL 0 - -// Typedef declarations -typedef unsigned size_t; -typedef signed ptrdiff_t; - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/stdint.h b/source/sysroot/usr/include/kernel/stdint.h deleted file mode 100644 index 60f36590..00000000 --- a/source/sysroot/usr/include/kernel/stdint.h +++ /dev/null @@ -1,558 +0,0 @@ -// stdint.h - replacement for standard C header file. -// Why is this required? We use -ffreestanding in our compile options, so the standard std library isn't included. - -/* - * Copyright (c) 2004, 2005 by - * Ralf Corsepius, Ulm/Germany. All rights reserved. - * - * Permission to use, copy, modify, and distribute this software - * is freely granted, provided that this notice is preserved. - */ - - - -#ifndef STDINT_H -#define STDINT_H - -/* -#define NULL 0 - -// Exact-width integer types - -typedef signed char int8_t; -typedef unsigned char uint8_t; -typedef short int16_t; -typedef unsigned short uint16_t; -typedef int int32_t; -typedef unsigned int uint32_t; -typedef long long int64_t; -typedef unsigned long long uint64_t; - -// Minimum-width integer types. - -typedef signed char int_least8_t; -typedef unsigned char uint_least8_t; -typedef short int_least16_t; -typedef unsigned short uint_least16_t; -typedef int int_least32_t; -typedef unsigned uint_least32_t; -typedef long long int_least64_t; -typedef unsigned long long uint_least64_t; - - -// GCC doesn't provide a good macro for (u)intptr_t so we check if __PTRDIFF_TYPE__ is defined and use that, else do something different I guess -#if defined(__PTRDIFF_TYPE__) -typedef signed __PTRDIFF_TYPE__ intptr_t; -typedef unsigned __PTRDIFF_TYPE__ uintptr_t; - -#define INTPTR_MAX PTRDIFF_MAX -#define INTPTR_MIN PTRDIFF_MIN - -#ifdef __UINTPTR_MAX__ -#define UINTPTR_MAX __UINTPTR_MAX__ -#else -#define UINTPTR_MAX (2UL * PTRDIFF_MAX + 1) -#endif -#else - -// Fallback to hardcoded values -typedef signed long intptr_t; -typedef unsigned long uintptr_t; - -#define INTPTR_MAX __STDINT_EXP(LONG_MAX) -#define INTPTR_MIN (-__STDINT_EXP(LONG_MAX) - 1) -#define UINTPTR_MAX (__STDINT_EXP(LONG_MAX) * 2UL + 1) - - -#endif - - -#if defined(__UINTMAX_TYPE__) - typedef __UINTMAX_TYPE__ uintmax_t; -#elif ( defined(__LONG_LONG_MAX__) && (__LONG_LONG_MAX__ > 0x7fffffff) ) \ - || ( defined(LLONG_MAX) && (LLONG_MAX > 0x7fffffff) ) - typedef unsigned long long uintmax_t; -#else - typedef unsigned long uintmax_t; -#endif - -*/ - - - -#if defined(__GNUC__) && \ - ( (__GNUC__ >= 4) || \ - ( (__GNUC__ >= 3) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ > 2) ) ) -/* gcc > 3.2 implicitly defines the values we are interested */ -#define __STDINT_EXP(x) __##x##__ -#else -#define __STDINT_EXP(x) x -#include -#endif - -/* Check if "long long" is 64bit wide */ -/* Modern GCCs provide __LONG_LONG_MAX__, SUSv3 wants LLONG_MAX */ -#if ( defined(__LONG_LONG_MAX__) && (__LONG_LONG_MAX__ > 0x7fffffff) ) \ - || ( defined(LLONG_MAX) && (LLONG_MAX > 0x7fffffff) ) -#define __have_longlong64 1 -#endif - -/* Check if "long" is 64bit or 32bit wide */ -#if __STDINT_EXP(LONG_MAX) > 0x7fffffff -#define __have_long64 1 -#elif __STDINT_EXP(LONG_MAX) == 0x7fffffff && !defined(__SPU__) -#define __have_long32 1 -#endif - -#if __STDINT_EXP(SCHAR_MAX) == 0x7f -typedef signed char int8_t ; -typedef unsigned char uint8_t ; -#define __int8_t_defined 1 -#endif - -#if __int8_t_defined -typedef signed char int_least8_t; -typedef unsigned char uint_least8_t; -#define __int_least8_t_defined 1 -#endif - -#if __STDINT_EXP(SHRT_MAX) == 0x7fff -typedef signed short int16_t; -typedef unsigned short uint16_t; -#define __int16_t_defined 1 -#elif __STDINT_EXP(INT_MAX) == 0x7fff -typedef signed int int16_t; -typedef unsigned int uint16_t; -#define __int16_t_defined 1 -#elif __STDINT_EXP(SCHAR_MAX) == 0x7fff -typedef signed char int16_t; -typedef unsigned char uint16_t; -#define __int16_t_defined 1 -#endif - -#if __int16_t_defined -typedef int16_t int_least16_t; -typedef uint16_t uint_least16_t; -#define __int_least16_t_defined 1 - -#if !__int_least8_t_defined -typedef int16_t int_least8_t; -typedef uint16_t uint_least8_t; -#define __int_least8_t_defined 1 -#endif -#endif - -#if __have_long32 -typedef signed long int32_t; -typedef unsigned long uint32_t; -#define __int32_t_defined 1 -#elif __STDINT_EXP(INT_MAX) == 0x7fffffffL -typedef signed int int32_t; -typedef unsigned int uint32_t; -#define __int32_t_defined 1 -#elif __STDINT_EXP(SHRT_MAX) == 0x7fffffffL -typedef signed short int32_t; -typedef unsigned short uint32_t; -#define __int32_t_defined 1 -#elif __STDINT_EXP(SCHAR_MAX) == 0x7fffffffL -typedef signed char int32_t; -typedef unsigned char uint32_t; -#define __int32_t_defined 1 -#endif - -#if __int32_t_defined -typedef int32_t int_least32_t; -typedef uint32_t uint_least32_t; -#define __int_least32_t_defined 1 - -#if !__int_least8_t_defined -typedef int32_t int_least8_t; -typedef uint32_t uint_least8_t; -#define __int_least8_t_defined 1 -#endif - -#if !__int_least16_t_defined -typedef int32_t int_least16_t; -typedef uint32_t uint_least16_t; -#define __int_least16_t_defined 1 -#endif -#endif - -#if __have_long64 -typedef signed long int64_t; -typedef unsigned long uint64_t; -#define __int64_t_defined 1 -#elif __have_longlong64 -typedef signed long long int64_t; -typedef unsigned long long uint64_t; -#define __int64_t_defined 1 -#elif __STDINT_EXP(INT_MAX) > 0x7fffffff -typedef signed int int64_t; -typedef unsigned int uint64_t; -#define __int64_t_defined 1 -#endif - -#if __int64_t_defined -typedef int64_t int_least64_t; -typedef uint64_t uint_least64_t; -#define __int_least64_t_defined 1 - -#if !__int_least8_t_defined -typedef int64_t int_least8_t; -typedef uint64_t uint_least8_t; -#define __int_least8_t_defined 1 -#endif - -#if !__int_least16_t_defined -typedef int64_t int_least16_t; -typedef uint64_t uint_least16_t; -#define __int_least16_t_defined 1 -#endif - -#if !__int_least32_t_defined -typedef int64_t int_least32_t; -typedef uint64_t uint_least32_t; -#define __int_least32_t_defined 1 -#endif -#endif - -/* - * Fastest minimum-width integer types - * - * Assume int to be the fastest type for all types with a width - * less than __INT_MAX__ rsp. INT_MAX - */ -#if __STDINT_EXP(INT_MAX) >= 0x7f - typedef signed int int_fast8_t; - typedef unsigned int uint_fast8_t; -#define __int_fast8_t_defined 1 -#endif - -#if __STDINT_EXP(INT_MAX) >= 0x7fff - typedef signed int int_fast16_t; - typedef unsigned int uint_fast16_t; -#define __int_fast16_t_defined 1 -#endif - -#if __STDINT_EXP(INT_MAX) >= 0x7fffffff - typedef signed int int_fast32_t; - typedef unsigned int uint_fast32_t; -#define __int_fast32_t_defined 1 -#endif - -#if __STDINT_EXP(INT_MAX) > 0x7fffffff - typedef signed int int_fast64_t; - typedef unsigned int uint_fast64_t; -#define __int_fast64_t_defined 1 -#endif - -/* - * Fall back to [u]int_least_t for [u]int_fast_t types - * not having been defined, yet. - * Leave undefined, if [u]int_least_t should not be available. - */ -#if !__int_fast8_t_defined -#if __int_least8_t_defined - typedef int_least8_t int_fast8_t; - typedef uint_least8_t uint_fast8_t; -#define __int_fast8_t_defined 1 -#endif -#endif - -#if !__int_fast16_t_defined -#if __int_least16_t_defined - typedef int_least16_t int_fast16_t; - typedef uint_least16_t uint_fast16_t; -#define __int_fast16_t_defined 1 -#endif -#endif - -#if !__int_fast32_t_defined -#if __int_least32_t_defined - typedef int_least32_t int_fast32_t; - typedef uint_least32_t uint_fast32_t; -#define __int_fast32_t_defined 1 -#endif -#endif - -#if !__int_fast64_t_defined -#if __int_least64_t_defined - typedef int_least64_t int_fast64_t; - typedef uint_least64_t uint_fast64_t; -#define __int_fast64_t_defined 1 -#endif -#endif - -/* Greatest-width integer types */ -/* Modern GCCs provide __INTMAX_TYPE__ */ -#if defined(__INTMAX_TYPE__) - typedef __INTMAX_TYPE__ intmax_t; -#elif __have_longlong64 - typedef signed long long intmax_t; -#else - typedef signed long intmax_t; -#endif - -/* Modern GCCs provide __UINTMAX_TYPE__ */ -#if defined(__UINTMAX_TYPE__) - typedef __UINTMAX_TYPE__ uintmax_t; -#elif __have_longlong64 - typedef unsigned long long uintmax_t; -#else - typedef unsigned long uintmax_t; -#endif - -/* - * GCC doesn't provide an appropriate macro for [u]intptr_t - * For now, use __PTRDIFF_TYPE__ - */ -#if defined(__PTRDIFF_TYPE__) -typedef signed __PTRDIFF_TYPE__ intptr_t; -typedef unsigned __PTRDIFF_TYPE__ uintptr_t; -#define INTPTR_MAX PTRDIFF_MAX -#define INTPTR_MIN PTRDIFF_MIN -#ifdef __UINTPTR_MAX__ -#define UINTPTR_MAX __UINTPTR_MAX__ -#else -#define UINTPTR_MAX (2UL * PTRDIFF_MAX + 1) -#endif -#else -/* - * Fallback to hardcoded values, - * should be valid on cpu's with 32bit int/32bit void* - */ -typedef signed long intptr_t; -typedef unsigned long uintptr_t; -#define INTPTR_MAX __STDINT_EXP(LONG_MAX) -#define INTPTR_MIN (-__STDINT_EXP(LONG_MAX) - 1) -#define UINTPTR_MAX (__STDINT_EXP(LONG_MAX) * 2UL + 1) -#endif - -/* Limits of Specified-Width Integer Types */ - -#if __int8_t_defined -#define INT8_MIN -128 -#define INT8_MAX 127 -#define UINT8_MAX 255 -#endif - -#if __int_least8_t_defined -#define INT_LEAST8_MIN -128 -#define INT_LEAST8_MAX 127 -#define UINT_LEAST8_MAX 255 -#else -#error required type int_least8_t missing -#endif - -#if __int16_t_defined -#define INT16_MIN -32768 -#define INT16_MAX 32767 -#define UINT16_MAX 65535 -#endif - -#if __int_least16_t_defined -#define INT_LEAST16_MIN -32768 -#define INT_LEAST16_MAX 32767 -#define UINT_LEAST16_MAX 65535 -#else -#error required type int_least16_t missing -#endif - -#if __int32_t_defined -#if __have_long32 -#define INT32_MIN (-2147483647L-1) -#define INT32_MAX 2147483647L -#define UINT32_MAX 4294967295UL -#else -#define INT32_MIN (-2147483647-1) -#define INT32_MAX 2147483647 -#define UINT32_MAX 4294967295U -#endif -#endif - -#if __int_least32_t_defined -#if __have_long32 -#define INT_LEAST32_MIN (-2147483647L-1) -#define INT_LEAST32_MAX 2147483647L -#define UINT_LEAST32_MAX 4294967295UL -#else -#define INT_LEAST32_MIN (-2147483647-1) -#define INT_LEAST32_MAX 2147483647 -#define UINT_LEAST32_MAX 4294967295U -#endif -#else -#error required type int_least32_t missing -#endif - -#if __int64_t_defined -#if __have_long64 -#define INT64_MIN (-9223372036854775807L-1L) -#define INT64_MAX 9223372036854775807L -#define UINT64_MAX 18446744073709551615U -#elif __have_longlong64 -#define INT64_MIN (-9223372036854775807LL-1LL) -#define INT64_MAX 9223372036854775807LL -#define UINT64_MAX 18446744073709551615ULL -#endif -#endif - -#if __int_least64_t_defined -#if __have_long64 -#define INT_LEAST64_MIN (-9223372036854775807L-1L) -#define INT_LEAST64_MAX 9223372036854775807L -#define UINT_LEAST64_MAX 18446744073709551615U -#elif __have_longlong64 -#define INT_LEAST64_MIN (-9223372036854775807LL-1LL) -#define INT_LEAST64_MAX 9223372036854775807LL -#define UINT_LEAST64_MAX 18446744073709551615ULL -#endif -#endif - -#if __int_fast8_t_defined -#if __STDINT_EXP(INT_MAX) >= 0x7f -#define INT_FAST8_MIN (-__STDINT_EXP(INT_MAX)-1) -#define INT_FAST8_MAX __STDINT_EXP(INT_MAX) -#define UINT_FAST8_MAX (__STDINT_EXP(INT_MAX)*2U+1U) -#else -#define INT_FAST8_MIN INT_LEAST8_MIN -#define INT_FAST8_MAX INT_LEAST8_MAX -#define UINT_FAST8_MAX UINT_LEAST8_MAX -#endif -#endif - -#if __int_fast16_t_defined -#if __STDINT_EXP(INT_MAX) >= 0x7fff -#define INT_FAST16_MIN (-__STDINT_EXP(INT_MAX)-1) -#define INT_FAST16_MAX __STDINT_EXP(INT_MAX) -#define UINT_FAST16_MAX (__STDINT_EXP(INT_MAX)*2U+1U) -#else -#define INT_FAST16_MIN INT_LEAST16_MIN -#define INT_FAST16_MAX INT_LEAST16_MAX -#define UINT_FAST16_MAX UINT_LEAST16_MAX -#endif -#endif - -#if __int_fast32_t_defined -#if __STDINT_EXP(INT_MAX) >= 0x7fffffff -#define INT_FAST32_MIN (-__STDINT_EXP(INT_MAX)-1) -#define INT_FAST32_MAX __STDINT_EXP(INT_MAX) -#define UINT_FAST32_MAX (__STDINT_EXP(INT_MAX)*2U+1U) -#else -#define INT_FAST32_MIN INT_LEAST32_MIN -#define INT_FAST32_MAX INT_LEAST32_MAX -#define UINT_FAST32_MAX UINT_LEAST32_MAX -#endif -#endif - -#if __int_fast64_t_defined -#if __STDINT_EXP(INT_MAX) > 0x7fffffff -#define INT_FAST64_MIN (-__STDINT_EXP(INT_MAX)-1) -#define INT_FAST64_MAX __STDINT_EXP(INT_MAX) -#define UINT_FAST64_MAX (__STDINT_EXP(INT_MAX)*2U+1U) -#else -#define INT_FAST64_MIN INT_LEAST64_MIN -#define INT_FAST64_MAX INT_LEAST64_MAX -#define UINT_FAST64_MAX UINT_LEAST64_MAX -#endif -#endif - -#ifdef __INTMAX_MAX__ -#define INTMAX_MAX __INTMAX_MAX__ -#define INTMAX_MIN (-INTMAX_MAX - 1) -#elif defined(__INTMAX_TYPE__) -/* All relevant GCC versions prefer long to long long for intmax_t. */ -#define INTMAX_MAX INT64_MAX -#define INTMAX_MIN INT64_MIN -#endif - -#ifdef __UINTMAX_MAX__ -#define UINTMAX_MAX __UINTMAX_MAX__ -#elif defined(__UINTMAX_TYPE__) -/* All relevant GCC versions prefer long to long long for intmax_t. */ -#define UINTMAX_MAX UINT64_MAX -#endif - -/* This must match size_t in stddef.h, currently long unsigned int */ -#ifdef __SIZE_MAX__ -#define SIZE_MAX __SIZE_MAX__ -#else -#define SIZE_MAX (__STDINT_EXP(LONG_MAX) * 2UL + 1) -#endif - -/* This must match sig_atomic_t in (currently int) */ -#define SIG_ATOMIC_MIN (-__STDINT_EXP(INT_MAX) - 1) -#define SIG_ATOMIC_MAX __STDINT_EXP(INT_MAX) - -/* This must match ptrdiff_t in (currently long int) */ -#ifdef __PTRDIFF_MAX__ -#define PTRDIFF_MAX __PTRDIFF_MAX__ -#else -#define PTRDIFF_MAX __STDINT_EXP(LONG_MAX) -#endif -#define PTRDIFF_MIN (-PTRDIFF_MAX - 1) - -#ifdef __WCHAR_MAX__ -#define WCHAR_MAX __WCHAR_MAX__ -#endif -#ifdef __WCHAR_MIN__ -#define WCHAR_MIN __WCHAR_MIN__ -#endif - -/* wint_t is unsigned int on almost all GCC targets. */ -#ifdef __WINT_MAX__ -#define WINT_MAX __WINT_MAX__ -#else -#define WINT_MAX (__STDINT_EXP(INT_MAX) * 2U + 1U) -#endif -#ifdef __WINT_MIN__ -#define WINT_MIN __WINT_MIN__ -#else -#define WINT_MIN 0U -#endif - -/** Macros for minimum-width integer constant expressions */ -#define INT8_C(x) x -#if __STDINT_EXP(INT_MAX) > 0x7f -#define UINT8_C(x) x -#else -#define UINT8_C(x) x##U -#endif - -#define INT16_C(x) x -#if __STDINT_EXP(INT_MAX) > 0x7fff -#define UINT16_C(x) x -#else -#define UINT16_C(x) x##U -#endif - -#if __have_long32 -#define INT32_C(x) x##L -#define UINT32_C(x) x##UL -#else -#define INT32_C(x) x -#define UINT32_C(x) x##U -#endif - -#if __int64_t_defined -#if __have_long64 -#define INT64_C(x) x##L -#define UINT64_C(x) x##UL -#else -#define INT64_C(x) x##LL -#define UINT64_C(x) x##ULL -#endif -#endif - -/** Macros for greatest-width integer constant expression */ -#if __have_long64 -#define INTMAX_C(x) x##L -#define UINTMAX_C(x) x##UL -#else -#define INTMAX_C(x) x##LL -#define UINTMAX_C(x) x##ULL -#endif - - - - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/stdio.h b/source/sysroot/usr/include/kernel/stdio.h deleted file mode 100644 index a5a9d75d..00000000 --- a/source/sysroot/usr/include/kernel/stdio.h +++ /dev/null @@ -1,15 +0,0 @@ -// stdio.h - Handles outputting to console or other devices - -#ifndef STDIO_H -#define STDIO_H - -// Includes -#include // TODO: Implement ability to use stdio and other stuff - -// Functinos -int printf(const char * __restrict, ...); -int putchar(int); -int puts(const char *); - - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/stdlib.h b/source/sysroot/usr/include/kernel/stdlib.h deleted file mode 100644 index 2f547104..00000000 --- a/source/sysroot/usr/include/kernel/stdlib.h +++ /dev/null @@ -1,14 +0,0 @@ -// stdlib.h - replacement for standard C header file. -// Why is this required? We use -ffreestanding in our compile options, so the standard std library isn't included. - -#ifndef STDLIB_H -#define STDLIB_H - -// Functions: -int abs(int x); // Returns the absolute value of an integer (always positive) -double min(double n1, double n2); // Returns the smallest of the parameters -double max(double n1, double n2); // Returns the largest of the parameters -double sqrt(double n); // Returns the sqrt of a number (return value ^ 2 = number) - - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/string.h b/source/sysroot/usr/include/kernel/string.h deleted file mode 100644 index 840b6d94..00000000 --- a/source/sysroot/usr/include/kernel/string.h +++ /dev/null @@ -1,40 +0,0 @@ -// string.h - replacement for standard C header file. Contains certain useful functions like strlen. -// Why is this required? We use -ffreestanding in our compile options, so the standard std library isn't included. - -#ifndef STRING_H -#define STRING_H - -#include // Integer declarations -#include // Boolean declarations -#include // size_t declaration -#include // LONG_MIN and LONG_MAX -#include - -// TECHNICALLY this isn't supposed to be here but I don't care that much -#define EOF -1 - -// Function definitions -int memcmp(const void*, const void*, size_t); // memcmp() - Comparing addresses/values in memory -void* memcpy(void* __restrict, const void* __restrict, size_t); // memcpy() - copy a block of data from one address to another. -void* memmove(void*, const void*, size_t); // memmove() - memcpy but moving it instead of copying. -void *memset(void* buf, char c, size_t n); // memset() - set a buffer in memory to given value -void itoa(void *num, char* buffer, int base); // itoa() - converts an integer to a string. stores in buffer so no return value. -void itoa_long(uint64_t num, char *str, int base); // itoa_long() - Dirty hack to fix a bug -char *strcpy(char *dest, const char *src); // strcpy() - copies one string to another -char toupper(char c); // toupper() - turns a character uppercase -char tolower(char c); // tolower() - turns a character lowercase -int isalpha(char ch); // isalpha() - returns if a char is in the alphabet -int strcmp(const char *str1, char *str2); // strcmp() - compares a string. -int strncmp(const char *str1, char *str2, int length); // strncmp() - compares a string for x amount of chars. -int strlen(char *str); // strlen() - checks length of a string -char *strtok(char *str, const char *delim); // strtok() - splits a string into tokens, seperated by delim. -long strtol(const char *nptr, char **endptr, int base); // strtol() - -int atoi(char *str); // atoi() - string to integer -char *strchr(char *str, int ch); // Locate the first occurance of a character in a string (credit to BrokenThorn Entertainment) -char *strchrnul(const char *str, int ch); // Locates a character in a string -size_t strcspn(const char *str1, const char *reject); // Scans str1 for the first occurence of any of the characters that are NOT part of reject. -size_t strspn(const char *str1, const char *accept); // Scans str1 for the first occurence of any of the characters that are part of accept. -char *strpbrk(const char *s, const char *b); // Returns a pointer to the first occurence of b within s. -char *strtok_r(char *str, const char *delim, char **saveptr); // Thread-safe version of strtok - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/syscall.h b/source/sysroot/usr/include/kernel/syscall.h deleted file mode 100644 index 279d9b52..00000000 --- a/source/sysroot/usr/include/kernel/syscall.h +++ /dev/null @@ -1,44 +0,0 @@ -// syscall.h - handler for system calls - -#ifndef SYSCALL_H -#define SYSCALL_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/isr.h" // Interrupt Service Routines - -// Macros -// See syscall.c for an explanation of why we need these macros. - -// 5 DEFINE_SYSCALL macros (just function prototypes) -#define DEFINE_SYSCALL0(func) int syscall_##func(); -#define DEFINE_SYSCALL1(func, p1) int syscall_##func(p1); - -// Define some system calls -DEFINE_SYSCALL1(terminalWriteString, const char*); -DEFINE_SYSCALL1(terminalPutchar, char); -DEFINE_SYSCALL0(terminalUpdateScreen); - -// 5 DECLARE_SYSCALL macros, the only reason we have 5 is to allow for parameters. -// EAX = Number, EBX = Parameter 1, ECX = Parameter 2, EDX = Parameter 3 - -#define DECLARE_SYSCALL0(func, num) \ -int syscall_##func() { \ - int a; \ - asm volatile ("int $0x80" : "=a" (a) : "0" (num)); \ - return a; \ -} - -#define DECLARE_SYSCALL1(func, num, P1) \ -int syscall_##func(P1 p1) { \ - int a; \ - asm volatile ("int $0x80" : "=a" (a) : "0" (num), "b"((int)p1)); \ - return a; \ -} - - -// Functions -void initSyscalls(); - - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/terminal.h b/source/sysroot/usr/include/kernel/terminal.h deleted file mode 100644 index 9e0b987d..00000000 --- a/source/sysroot/usr/include/kernel/terminal.h +++ /dev/null @@ -1,56 +0,0 @@ -// terminal.h - Handling all terminal functions(like printf, putchar, etc.) - - -#ifndef TERMINAL_H -#define TERMINAL_H - -#include "include/libc/stddef.h" // size_t declaration -#include "include/libc/stdint.h" // Integer type declarations -#include "include/libc/stdbool.h" // Boolean declarations -#include "include/libc/string.h" // String functions -#include "include/libc/limits.h" // Limits on integers and more. - -//#include "include/libc/stdarg.h" // va argument handling (for ... on printf) -// #include "include/libc/va_list.h" // va_list declared here. -#include -#include "include/graphics.h" // Utility functions -#include "include/serial.h" // Serial logging -#include "include/vesa.h" // VESA VBE - - -// Variable declarations - -static size_t terminalX; // X position of terminal buffer, or column -static size_t terminalY; // Y position of terminal buffer, or row -static uint8_t terminalColor; // The current color of the terminal. -static uint16_t *terminalBuffer; // The most important one: the terminal buffer. -extern int vbeWidth, vbeHeight; -extern int terminalMode; // 0 signifies VGA mode, 1 signifies VESA VBE. - - -// VGA memory address, width, height etc are stored in graphics.h. - -// Function declarations - -void terminalInit(void); // terminalInit() - load the terminal -void changeTerminalMode(int mode); // changeTerminalMode() - Update the terminal mode (0 = VGA, 1 = VESA) -void updateTerminalColor(uint8_t color); // updateTerminalColor() - Change the terminal color. Requires a vgaColorEntry already setup. -void terminalPutcharXY(unsigned char c, uint8_t color, size_t x, size_t y); // terminalPutcharXY() - Place an unsigned char at a certain X and Y. Not recommended, doesn't include scrolling stuff. -void terminalGotoXY(size_t x, size_t y); // terminalGotoXY() - Change the position to X and Y -void scrollTerminal(); // scrollTerminal() - I don't see how this could be used outside of terminal.c, but just in case. Scrolls the terminal down. -void terminalDeleteLastLine(); // terminalDeleteLastLine() - Removes the last line placed by the terminal. -void clearScreen(uint8_t fg, uint8_t bg); // clearScreen() - Clears the terminal screen. -void terminalPutchar(char c); // terminalPutchar() - Recommended function. Incorporates scrollTerminal and terminalDeleteLastLine. -void terminalWrite(const char *data, size_t size); // terminalWrite() - This nor terminalWriteString is recommended for use. Use printf. It prints data using a for loop, but needs length. -void terminalWriteString(const char* data); // terminalWriteString() - The exact same as terminalWrite but with strlen() included. -void terminalBackspace(); // terminalBackspace() - Removes the last character printed. -void terminalWriteStringXY(const char *data, size_t x, size_t y); // terminalWriteStringXY() - Moves the terminal to X and Y, prints the string, then moves back to the original position. -void terminalMoveArrowKeys(int arrowKey); // terminalMoveArrowKeys() - used by keyboard.c, a function to move the cursor around -void updateBottomText(char *bottomText); // updateBottomText() - A function to update that bottom bar of text -void enableShell(char *shellToUse); // Enables a boundary that cannot be overwritten. -void updateTextCursor_vesa(); // Updating the text cursor in VESA VBE. -void terminalUpdateScreen(); // Update the screen buffers -void instantUpdateTerminalColor(uint8_t fg, uint8_t bg); // Instantly update the terminal color (VESA only) -void terminalSetUpdateScreen(bool state); // Toggles whether the screen should update when terminalUpdateScreen() is called - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/test.h b/source/sysroot/usr/include/kernel/test.h deleted file mode 100644 index e9a14824..00000000 --- a/source/sysroot/usr/include/kernel/test.h +++ /dev/null @@ -1,12 +0,0 @@ -// test.h - test command -#ifndef TEST_CMD_H -#define TEST_CMD_H - - - - -// Function -int test(int argc, char *args[]); - - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/tree.h b/source/sysroot/usr/include/kernel/tree.h deleted file mode 100644 index 07d7484c..00000000 --- a/source/sysroot/usr/include/kernel/tree.h +++ /dev/null @@ -1,45 +0,0 @@ -// tree.h - General tree implementation -// You can find this impl. here: https://github.com/stevej/osdev/blob/master/kernel/include/tree.h (FORKED FROM TOARUOS) - -#ifndef TREE_H -#define TREE_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/libc/stddef.h" // size_t -#include "include/list.h" // List implementation -#include "include/mem.h" // Memory allocation - -// Typedefs -typedef struct tree_node { - void *value; - list_t *children; - struct tree_node *parent; -} tree_node_t; - -typedef struct { - size_t nodes; - struct tree_node *root; -} tree_t; - -typedef uint8_t (*tree_comparator_t) (void *, void *); - -// Functions -tree_t * tree_create(); -void tree_set_root(tree_t * tree, void * value); -void tree_node_destroy(tree_node_t * node); -void tree_destroy(tree_t * tree); -void tree_free(tree_t * tree); -tree_node_t * tree_node_create(void * value); -void tree_node_insert_child_node(tree_t * tree, tree_node_t * parent, tree_node_t * node); -tree_node_t * tree_node_insert_child(tree_t * tree, tree_node_t * parent, void * value); -tree_node_t * tree_node_find_parent(tree_node_t * haystack, tree_node_t * needle); -void tree_node_parent_remove(tree_t * tree, tree_node_t * parent, tree_node_t * node); -void tree_node_remove(tree_t * tree, tree_node_t * node); -void tree_remove(tree_t * tree, tree_node_t * node); -tree_node_t * tree_find(tree_t * tree, void * value, tree_comparator_t comparator); -void tree_break_off(tree_t * tree, tree_node_t * node); -size_t tree_count_children(tree_node_t *node); -tree_node_t *tree_find_parent(tree_t *tree, tree_node_t *node); - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/tss.h b/source/sysroot/usr/include/kernel/tss.h deleted file mode 100644 index 6bf08cc5..00000000 --- a/source/sysroot/usr/include/kernel/tss.h +++ /dev/null @@ -1,56 +0,0 @@ -// tss.h - Task State Segment structure definitions - -#ifndef TSS_H -#define TSS_H - -// Includes -#include "include/libc/stdint.h" // Integer definitions -#include "include/gdt.h" - - -// Typedefs -// Note: This will need to be updated when we upgrade to reduceOS x86_64. -// However, by then we may have an entirely new TSS implementation, so, eh. - - -// https://wiki.osdev.org/Getting_to_Ring_3 -typedef struct { - uint32_t prev_tss; // The previous TSS - with hardware task switching these form a kind of backward linked list. - uint32_t esp0; // The stack pointer to load when changing to kernel mode. - uint32_t ss0; // The stack segment to load when changing to kernel mode. - // Everything below here is unused. - uint32_t esp1; // esp and ss 1 and 2 would be used when switching to rings 1 or 2. - uint32_t ss1; - uint32_t esp2; - uint32_t ss2; - uint32_t cr3; - uint32_t eip; - uint32_t eflags; - uint32_t eax; - uint32_t ecx; - uint32_t edx; - uint32_t ebx; - uint32_t esp; - uint32_t ebp; - uint32_t esi; - uint32_t edi; - uint32_t es; - uint32_t cs; - uint32_t ss; - uint32_t ds; - uint32_t fs; - uint32_t gs; - uint32_t ldt; - uint16_t trap; - uint16_t iomap_base; -} __attribute__((packed)) tss_entry_t; - - -// External functions -extern void tssFlush(); - -// Functions -void tssWrite(int32_t index, uint16_t ss0, uint32_t esp0); -void setKernelStack(uint32_t stack); - -#endif diff --git a/source/sysroot/usr/include/kernel/udivdi3.h b/source/sysroot/usr/include/kernel/udivdi3.h deleted file mode 100644 index 0b978a12..00000000 --- a/source/sysroot/usr/include/kernel/udivdi3.h +++ /dev/null @@ -1,3 +0,0 @@ -// This file is here for compatibility reasons. -// If this is still here, give me a little ping in our discord: https://discord.gg/g5XwNxw3u5 -// Thanks for checking out my code! \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/va_list.h b/source/sysroot/usr/include/kernel/va_list.h deleted file mode 100644 index b738e89d..00000000 --- a/source/sysroot/usr/include/kernel/va_list.h +++ /dev/null @@ -1,14 +0,0 @@ -// va_list.h - replacement for standard C header file. -// Why is this required? We use -ffreestanding in our compile options, so the standard std library isn't included. - -// File operates in tandem with stdarg.h (va_list declaration here, macros in stdarg.h) - -#ifndef VA_LIST_H -#define VA_LIST_H - -// Declarations - -typedef __builtin_va_list va_list; - -#endif - diff --git a/source/sysroot/usr/include/kernel/vesa.h b/source/sysroot/usr/include/kernel/vesa.h deleted file mode 100644 index 77865c30..00000000 --- a/source/sysroot/usr/include/kernel/vesa.h +++ /dev/null @@ -1,76 +0,0 @@ -// vesa.h - header file for the VESA VBE handler - -#ifndef VESA_H -#define VESA_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/bios32.h" // BIOS32 calls (for switching) -#include "include/bootinfo.h" - -// Typedefs - -// vbeInfoBlock_t - A block of information for VESA VBE -typedef struct { - char *signature; // Block signature, should always be "VESA" - uint16_t version; // Version of VBE - uint16_t oemStringPtr[2]; // Pointer to OEM - uint8_t features[4]; // Available features - uint32_t *videoModePtr; - uint16_t totalMemory; // Total video memory (in number of 64KB blocks) -} __attribute__((packed)) vbeInfoBlock_t; - -// vbeModeInfo_t - VBE mode information (structure originated from https://wiki.osdev.org/Getting_VBE_Mode_Info) -typedef struct { - uint16_t attributes; // deprecated, only bit 7 should be of interest to you, and it indicates the mode supports a linear frame buffer. - uint8_t window_a; // deprecated - uint8_t window_b; // deprecated - uint16_t granularity; // deprecated; used while calculating bank numbers - uint16_t window_size; - uint16_t segment_a; - uint16_t segment_b; - uint32_t win_func_ptr; // deprecated; used to switch banks from protected mode without returning to real mode - uint16_t pitch; // number of bytes per horizontal line - uint16_t width; // width in pixels - uint16_t height; // height in pixels - uint8_t w_char; // unused... - uint8_t y_char; // ... - uint8_t planes; - uint8_t bpp; // bits per pixel in this mode - uint8_t banks; // deprecated; total number of banks in this mode - uint8_t memory_model; - uint8_t bank_size; // deprecated; size of a bank, almost always 64 KB but may be 16 KB... - uint8_t image_pages; - uint8_t reserved0; - - uint8_t red_mask; - uint8_t red_position; - uint8_t green_mask; - uint8_t green_position; - uint8_t blue_mask; - uint8_t blue_position; - uint8_t reserved_mask; - uint8_t reserved_position; - uint8_t direct_color_attributes; - - uint32_t framebuffer; // physical address of the linear frame buffer; write here to draw to the screen - uint32_t off_screen_mem_off; - uint16_t off_screen_mem_size; // size of memory in the framebuffer but not being displayed on the screen - uint8_t reserved1[206]; -} __attribute__((packed)) vbeModeInfo_t; - - -// Framebuffers (probably not a good idea but I could care less) -extern uint32_t *vbeBuffer; -extern uint32_t *framebuffer; // 2nd framebuffer. -extern uint32_t modeWidth; -extern uint32_t modeHeight; - - -// Functions -void vesaInit(); -uint32_t RGB_VBE(uint8_t r, uint8_t g, uint8_t b); -void vbePutPixel(int x, int y, uint32_t color); - - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/vfs.h b/source/sysroot/usr/include/kernel/vfs.h deleted file mode 100644 index 3262c9f1..00000000 --- a/source/sysroot/usr/include/kernel/vfs.h +++ /dev/null @@ -1,116 +0,0 @@ -// vfs.h - Contains declarations of the virtual filesystem and the initial ramdisk. - -#ifndef VFS_H -#define VFS_H - -/* First, a quick explanation of what a VFS actually is: - (wiki.osdev.org) A virtual filesystem is not an on-disk filesystem or a network filesystem. It's an abstraction that many OSes use to provide applications. - A VFS is used to seperate the high-level interface to the FS from the low level interfaces that different implementations (like FAT, ext3, etc), may require. */ - -// Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/tree.h" // Mountpoint tree -#include "include/hashmap.h" // Mount hashmap - - -// Definitions -#define VFS_FILE 0x01 -#define VFS_DIRECTORY 0x02 -#define VFS_CHARDEVICE 0x03 -#define VFS_BLOCKDEVICE 0x04 -#define VFS_PIPE 0x05 -#define VFS_SYMLINK 0x06 -#define VFS_MOUNTPOINT 0x08 // This one defines if the file is an active mountpoint - - - - -// Typedefs - -// Filesystem node (prototype) -struct fsNode; - - -// Offset -typedef uint64_t off_t; - -// Function prototypes (from the POSIX specification): -/* These prototypes define the type of callbacks that are called when the read/write/open/close methods are called */ -typedef uint32_t (*read_t)(struct fsNode*, off_t, uint32_t, uint8_t*); -typedef uint32_t (*write_t)(struct fsNode*, off_t, uint32_t, uint8_t*); -typedef void (*open_t)(struct fsNode*); -typedef void (*close_t)(struct fsNode*); - -// These aren't from the POSIX specification. -typedef struct dirent * (*readdir_t)(struct fsNode*, uint32_t); -typedef struct fsNode * (*finddir_t)(struct fsNode*, char *name); -typedef void (*create_t) (struct vfs_node *, char *name, uint16_t permission); -typedef void (*mkdir_t) (struct vfs_node *, char *name, uint16_t permission); - - -// Actual typedef structures. -typedef struct { - char name[128]; // FS Name (max of 128) - uint32_t mask; // Permissions mask - uint32_t uid; // Owning user - uint32_t gid; // Owning group - uint32_t flags; // Includes the node type. - uint32_t inode; // Device-specific, provides a way for a filesystem to identify files - uint32_t length; // Size of file. - uint32_t impl; // Implementation defined number. - uint32_t *impl_struct; // Implementation structure. - read_t read; // Read function - write_t write; // Write function - open_t open; // Open function - close_t close; // Close function - readdir_t readdir; // Readdir function - finddir_t finddir; // Finddir function - create_t create; // Create function - mkdir_t mkdir; // Make directory function. - struct fsNode *ptr; // Used by mountpoints and symlinks. - struct fsNode *device; // Pointer to the device needed -} fsNode_t; - -// Hashmap callback -typedef fsNode_t * (*vfs_mountCallback)(const char * arg, const char * mount_point); - - -// Directory entry. -struct dirent { - char name[256]; // Filename - uint32_t ino; // (required by POSIX) Inode number. -}; - -// Entry for the filesystem tree -typedef struct vfsEntry { - char name[20]; - fsNode_t *file; - char *device; - char *fs_type; -} vfsEntry_t; - - - -extern fsNode_t *fs_root; // Filesystem root - -// Functions: -uint32_t readFilesystem(fsNode_t *node, off_t off, uint32_t size, uint8_t *buf); // Reads a file in a filesystem. -uint32_t writeFilesystem(fsNode_t *node, off_t off, uint32_t size, uint8_t *buf); // Writes a file in a filesystem. -void openFilesystem(fsNode_t *node, uint8_t read, uint8_t write); // Opens a filesystem. -void closeFilesystem(fsNode_t *node); // Closes a filesystem. -struct dirent *readDirectoryFilesystem(fsNode_t *node, uint32_t index); // Reads a directory in a filesystem. -fsNode_t *findDirectoryFilesystem(fsNode_t *node, char *name); // Finds a directory in a filesystem. -fsNode_t *openFile(const char *name); // Opens a file. -fsNode_t *getRootFilesystem(); // Returns root filesystem. -void *vfsMount(char *path, fsNode_t *localRoot); // Mount a filesystem to the specified path -void vfsInit(); // Initialize the VFS -fsNode_t *open_file(const char *filename, unsigned int flags); // Opens a file using the VFS current working directory -void change_cwd(const char *newdir); // Changes the current working directory -char *get_cwd(); // Returns the current working directory -fsNode_t *open_file_recursive(const char *filename, uint64_t flags, uint64_t symlink_depth, char *relative); // Opens a file (but recursive and does all the work -fsNode_t *vfs_getMountpoint(char *path, unsigned int path_depth, char **outpath, unsigned int *outdepth); // Gets the mountpoint of something at path -int vfs_mountType(const char *type, const char *arg, const char *mountpoint); // Calls the mount handler for the filesystem driver for type -int vfs_registerFilesystem(const char *name, vfs_mountCallback callback); // Registers a filesystem mount callback that will be called when needed -void vfs_mapDirectory(const char *c); // Maps a directory in the virtual filesystem -char *vfs_canonicalizePath(const char *cwd, const char *input); // Canonicalizes a path -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/vmm.h b/source/sysroot/usr/include/kernel/vmm.h deleted file mode 100644 index 62ce41a6..00000000 --- a/source/sysroot/usr/include/kernel/vmm.h +++ /dev/null @@ -1,61 +0,0 @@ -// vmm.h - Header file for virtual memory manager - -#ifndef VMM_H -#define VMM_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations -#include "include/libc/string.h" // String functions - - -#include "include/vmm_pte.h" -#include "include/vmm_pde.h" - -#include "include/panic.h" // Kernel panicking -#include "include/heap.h" // Kernel heap management. -#include "include/terminal.h" -#include "include/serial.h" -#include "include/pmm.h" // Physical memory management - - - -// Typedefs -typedef uint32_t virtual_address; - - -// pagetable_t -typedef struct { - pte_t entries[1024]; // x86 architecture specifies 1024 entries per page table -} pagetable_t; - -// pagedirectory_t -typedef struct { - pde_t entries[1024]; -} pagedirectory_t; - -// Definitions -#define PAGE_SIZE 4096 // Page size - - -// Macros -#define PAGEDIR_INDEX(x) (((x) >> 22) & 0x3ff) // Returns the index of x within the PDE -#define PAGETBL_INDEX(x) (((x) >> 12) & 0x3ff) // Returns the index of x within the PTE -#define VIRTUAL_TO_PHYS(addr) (*addr & ~0xFFF) // Returns the physical address of addr. - -// Functions -pte_t *vmm_tableLookupEntry(pagetable_t *table, uint32_t virtual_addr); // Look up an entry within the page table -pde_t *vmm_directoryLookupEntry(pagedirectory_t *directory, uint32_t virtual_addr); // Look up an entry within the page directory -void vmm_loadPDBR(uint32_t pdbr_addr); // Loads a new value into the PDBR address -bool vmm_switchDirectory(pagedirectory_t *directory); // Changes the current page directory -void vmm_flushTLBEntry(uint32_t addr); // Invalidates the current TLB entry -pagedirectory_t *vmm_getCurrentDirectory(); // Returns the current page directory -bool vmm_allocatePage(pte_t *entry); // Allocates VMM pages -void vmm_freePage(pte_t *entry); // Frees a page -pde_t *vmm_getPageTable(void *virtual_address); // Returns the page table for a virtual address -void vmm_mapPage(void *physical_addr, void *virtual_addr); // Maps a page from the physical address to its virtual address -void vmm_enablePaging(); // Enables paging -void vmm_disablePaging(); // Disables paging -void vmm_allocateRegion(uint32_t physical_address, uint32_t virtual_address, size_t size); // Identity map a region -void vmmInit(); // Initialize the VMM - -#endif \ No newline at end of file diff --git a/source/sysroot/usr/include/kernel/vmm_pde.h b/source/sysroot/usr/include/kernel/vmm_pde.h deleted file mode 100644 index d3685900..00000000 --- a/source/sysroot/usr/include/kernel/vmm_pde.h +++ /dev/null @@ -1,45 +0,0 @@ -// vmm_pde.h - Virtual memory manager page directory entries - -#ifndef VMM_PDE_H -#define VMM_PDE_H - -// Includes -#include "include/libc/stdint.h" // Integer declarations - -typedef uint32_t pde_t; // See vmm_pte.h - -#include "include/libc/string.h" // Will cause include loop - -// Definitions -#define PAGETABLE_ADDRSPACE 0x400000 // 4 MB address space - -// Enums - -// PDE flags -enum PAGING_PDE_FLAGS { - PDE_PRESENT = 1, - PDE_WRITABLE = 2, - PDE_USER = 4, - PDE_PWT = 8, - PDE_PCD = 0x10, - PDE_ACCESSED = 0x20, - PDE_DIRTY = 0x40, - PDE_4MB = 0x80, - PDE_CPU_GLOBAL = 0x100, - PDE_LV4_GLOBAL = 0x200, - PDE_FRAME = 0x7FFFF000 -}; - - -// Functions -void pde_addattrib(pde_t *entry, uint32_t attribute); -void pde_delattrib(pde_t *entry, uint32_t attribute); -void pde_setframe(pde_t *entry, uint32_t physical_addr); -bool pde_ispresent(pde_t entry); -bool pde_iswritable(pde_t entry); -uint32_t pde_getframe(pde_t entry); -bool pde_isuser(pde_t entry); -bool pde_is4mb(pde_t entry); - - -#endif diff --git a/source/sysroot/usr/include/kernel/vmm_pte.h b/source/sysroot/usr/include/kernel/vmm_pte.h deleted file mode 100644 index 16252490..00000000 --- a/source/sysroot/usr/include/kernel/vmm_pte.h +++ /dev/null @@ -1,44 +0,0 @@ -// vmm_pte.h - header file for the VMM page table entry handler - -#ifndef VMM_PTE_H -#define VMM_PTE_H - - -// We get an include loop if we include string.h before defining pte_t. - -#include "include/libc/stdint.h" // Integer declarations - -// Typedefs -typedef uint32_t pte_t; - - -// Includes -#include "include/libc/string.h" - -// Definitions -#define PAGEDIR_ADDRSPACE 0x100000000 // 4 GB address space - -// Enums -enum PTE_FLAGS { - PTE_PRESENT = 1, - PTE_WRITABLE = 2, - PTE_USER = 4, - PTE_WRITETHROUGH = 8, - PTE_NOT_CACHEABLE = 0x10, - PTE_ACCESSED = 0x20, - PTE_DIRTY = 0x40, - PTE_PAT = 0x80, - PTE_CPU_GLOBAL = 0x100, - PTE_LV4_GLOBAL = 0x200, - PTE_FRAME = 0x7FFFF000 -}; - - -// Functions -void pte_addattrib(pte_t *entry, uint32_t attribute); -void pte_delattrib(pte_t *entry, uint32_t attribute); -void pte_setframe(pte_t *entry, uint32_t physical_addr); -bool pte_ispresent(pte_t entry); -bool pte_iswritable(pte_t entry); -uint32_t pte_getframe(pte_t entry); -#endif \ No newline at end of file