From 6019c9307d7f13e5348ea14ace54be24eb0f2bbb Mon Sep 17 00:00:00 2001 From: Max Wash Date: Thu, 19 Feb 2026 18:54:48 +0000 Subject: [PATCH] kernel: separate headers into kernel and user headers all kernel headers have been moved from include/mango to include/kernel and include definitions that are only relevant to kernel-space. any definitions that are relevant to both kernel- and user-space (i.e. type definitions, syscall IDs) have been moved to include/mango within libmango. --- CMakeLists.txt | 1 + arch/user/cpu.c | 2 +- arch/user/hwlock.c | 4 +- arch/user/init.c | 10 +- arch/user/initcall.c | 2 +- arch/user/stdcon.c | 10 +- arch/x86_64/asm-offset.c | 4 +- arch/x86_64/cpu.c | 2 +- arch/x86_64/e820.c | 8 +- arch/x86_64/gdt.c | 4 +- arch/x86_64/include/arch/gdt.h | 2 +- arch/x86_64/include/arch/irq.h | 4 +- arch/x86_64/include/arch/paging.h | 4 +- arch/x86_64/include/arch/tss.h | 4 +- arch/x86_64/include/mango/machine/cpu.h | 73 - arch/x86_64/include/mango/machine/hwlock.h | 22 - arch/x86_64/include/mango/machine/init.h | 28 - arch/x86_64/include/mango/machine/irq.h | 5 - arch/x86_64/include/mango/machine/panic.h | 12 - arch/x86_64/include/mango/machine/pmap.h | 11 - arch/x86_64/include/mango/machine/thread.h | 29 - arch/x86_64/include/mango/machine/vm.h | 30 - arch/x86_64/init.c | 30 +- arch/x86_64/initcall.c | 2 +- arch/x86_64/irq.c | 22 +- arch/x86_64/panic.c | 10 +- arch/x86_64/pit.c | 6 +- arch/x86_64/pmap.c | 28 +- arch/x86_64/serial.c | 4 +- arch/x86_64/thread.c | 4 +- arch/x86_64/tss.c | 2 +- arch/x86_64/vga.c | 6 +- ds/bitmap.c | 4 +- ds/btree.c | 2 +- ds/queue.c | 2 +- ds/ringbuffer.c | 4 +- include/mango/arg.h | 14 - include/mango/bitmap.h | 35 - include/mango/bsp.h | 38 - include/mango/btree.h | 381 ----- include/mango/clock.h | 27 - include/mango/compiler.h | 41 - include/mango/console.h | 56 - include/mango/cpu.h | 65 - include/mango/fb.h | 49 - include/mango/flags.h | 11 - include/mango/handle.h | 56 - include/mango/init.h | 41 - include/mango/input.h | 184 -- include/mango/locks.h | 25 - include/mango/memblock.h | 345 ---- include/mango/object.h | 95 - include/mango/panic.h | 13 - include/mango/percpu.h | 36 - include/mango/pmap.h | 81 - include/mango/printk.h | 23 - include/mango/queue.h | 62 - include/mango/ringbuffer.h | 34 - include/mango/sched.h | 250 --- include/mango/syscall.h | 20 - include/mango/test.h | 14 - include/mango/types.h | 22 - include/mango/util.h | 69 - include/mango/vm-object.h | 68 - include/mango/vm-region.h | 115 -- include/mango/vm.h | 367 ---- init/init.c | 3 +- init/main.c | 32 +- kernel/arg.c | 6 +- kernel/bsp.c | 13 +- kernel/clock.c | 6 +- kernel/console.c | 8 +- kernel/cpu.c | 6 +- kernel/handle.c | 10 +- kernel/object.c | 6 +- kernel/panic.c | 10 +- kernel/percpu.c | 6 +- kernel/printk.c | 8 +- libc/include/mango/libc/ctype.h | 26 - libc/include/mango/libc/stdio.h | 21 - libc/include/mango/libc/string.h | 36 - libc/stdio/printf.c | 1616 +++++++++++------- libc/string/memmove.c | 2 +- libc/string/memset.c | 12 +- libc/string/strcat.c | 2 +- libc/string/strcmp.c | 24 +- libc/string/strcpy.c | 2 +- libc/string/strlen.c | 7 +- libc/string/strrchr.c | 2 +- libc/string/strtok.c | 2 +- {include => libmango/include}/mango/status.h | 5 +- libmango/include/mango/syscall.h | 35 + libmango/include/mango/types.h | 62 + sched/core.c | 14 +- sched/runqueue.c | 6 +- sched/task.c | 20 +- sched/thread.c | 10 +- sched/timer.c | 8 +- sched/wait.c | 4 +- sched/workqueue.c | 8 +- syscall/dispatch.c | 6 +- test/obj.c | 8 +- test/test.c | 4 +- util/data_size.c | 2 +- util/endian.c | 2 +- util/random.c | 2 +- vm/bootstrap.c | 12 +- vm/cache.c | 10 +- vm/flat.c | 6 +- vm/kmalloc.c | 10 +- vm/memblock.c | 6 +- vm/model.c | 2 +- vm/page.c | 10 +- vm/sparse.c | 16 +- vm/vm-object.c | 5 +- vm/vm-region.c | 15 +- vm/zone.c | 18 +- 117 files changed, 1361 insertions(+), 3845 deletions(-) delete mode 100644 arch/x86_64/include/mango/machine/cpu.h delete mode 100644 arch/x86_64/include/mango/machine/hwlock.h delete mode 100644 arch/x86_64/include/mango/machine/init.h delete mode 100644 arch/x86_64/include/mango/machine/irq.h delete mode 100644 arch/x86_64/include/mango/machine/panic.h delete mode 100644 arch/x86_64/include/mango/machine/pmap.h delete mode 100644 arch/x86_64/include/mango/machine/thread.h delete mode 100644 arch/x86_64/include/mango/machine/vm.h delete mode 100644 include/mango/arg.h delete mode 100644 include/mango/bitmap.h delete mode 100644 include/mango/bsp.h delete mode 100644 include/mango/btree.h delete mode 100644 include/mango/clock.h delete mode 100644 include/mango/compiler.h delete mode 100644 include/mango/console.h delete mode 100644 include/mango/cpu.h delete mode 100644 include/mango/fb.h delete mode 100644 include/mango/flags.h delete mode 100644 include/mango/handle.h delete mode 100644 include/mango/init.h delete mode 100644 include/mango/input.h delete mode 100644 include/mango/locks.h delete mode 100644 include/mango/memblock.h delete mode 100644 include/mango/object.h delete mode 100644 include/mango/panic.h delete mode 100644 include/mango/percpu.h delete mode 100644 include/mango/pmap.h delete mode 100644 include/mango/printk.h delete mode 100644 include/mango/queue.h delete mode 100644 include/mango/ringbuffer.h delete mode 100644 include/mango/sched.h delete mode 100644 include/mango/syscall.h delete mode 100644 include/mango/test.h delete mode 100644 include/mango/types.h delete mode 100644 include/mango/util.h delete mode 100644 include/mango/vm-object.h delete mode 100644 include/mango/vm-region.h delete mode 100644 include/mango/vm.h delete mode 100644 libc/include/mango/libc/ctype.h delete mode 100644 libc/include/mango/libc/stdio.h delete mode 100644 libc/include/mango/libc/string.h rename {include => libmango/include}/mango/status.h (83%) create mode 100644 libmango/include/mango/syscall.h create mode 100644 libmango/include/mango/types.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e57630f..adc2ff0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,6 +40,7 @@ add_executable(${kernel_exe_name} target_include_directories(${kernel_exe_name} PRIVATE include libc/include + libmango/include arch/${kernel_arch}/include) target_compile_options(${kernel_exe_name} PRIVATE -nostdlib -ffreestanding diff --git a/arch/user/cpu.c b/arch/user/cpu.c index f8ff887..a7bd380 100644 --- a/arch/user/cpu.c +++ b/arch/user/cpu.c @@ -1,5 +1,5 @@ #include -#include +#include int ml_init_bootcpu(void) { diff --git a/arch/user/hwlock.c b/arch/user/hwlock.c index 40e57e6..0074865 100644 --- a/arch/user/hwlock.c +++ b/arch/user/hwlock.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include void ml_hwlock_lock(ml_hwlock_t *lck) { diff --git a/arch/user/init.c b/arch/user/init.c index f0f884d..ede1132 100644 --- a/arch/user/init.c +++ b/arch/user/init.c @@ -1,11 +1,11 @@ #include #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include #include diff --git a/arch/user/initcall.c b/arch/user/initcall.c index c332f84..9aab208 100644 --- a/arch/user/initcall.c +++ b/arch/user/initcall.c @@ -1,4 +1,4 @@ -#include +#include #ifdef __APPLE__ extern char __start_initcall0[] __asm("section$start$__DATA$__initcall0.init"); diff --git a/arch/user/stdcon.c b/arch/user/stdcon.c index 59d2922..64a1052 100644 --- a/arch/user/stdcon.c +++ b/arch/user/stdcon.c @@ -1,10 +1,10 @@ -#include -#include +#include +#include #include #include -#include -#include -#include +#include +#include +#include static void stdcon_write(struct console *con, const char *s, unsigned int len) { diff --git a/arch/x86_64/asm-offset.c b/arch/x86_64/asm-offset.c index 012d98a..9424c0f 100644 --- a/arch/x86_64/asm-offset.c +++ b/arch/x86_64/asm-offset.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include //size_t THREAD_sp = offsetof(struct thread, tr_sp); diff --git a/arch/x86_64/cpu.c b/arch/x86_64/cpu.c index 8014bde..9246aaa 100644 --- a/arch/x86_64/cpu.c +++ b/arch/x86_64/cpu.c @@ -1,5 +1,5 @@ #include -#include +#include int ml_cpu_block_init(ml_cpu_block *p) { diff --git a/arch/x86_64/e820.c b/arch/x86_64/e820.c index 68a95c5..1a29228 100644 --- a/arch/x86_64/e820.c +++ b/arch/x86_64/e820.c @@ -1,8 +1,8 @@ -#include "mango/types.h" -#include -#include -#include #include +#include +#include +#include +#include void e820_scan(multiboot_memory_map_t *mmap, size_t len) { diff --git a/arch/x86_64/gdt.c b/arch/x86_64/gdt.c index 759ec18..4dd3cae 100644 --- a/arch/x86_64/gdt.c +++ b/arch/x86_64/gdt.c @@ -1,7 +1,7 @@ #include #include -#include -#include +#include +#include #include static void init_entry(struct gdt_entry *entry, int access, int flags) diff --git a/arch/x86_64/include/arch/gdt.h b/arch/x86_64/include/arch/gdt.h index d12e97e..b78b56c 100644 --- a/arch/x86_64/include/arch/gdt.h +++ b/arch/x86_64/include/arch/gdt.h @@ -2,7 +2,7 @@ #define ARCH_GDT_H_ #include -#include +#include #include #ifdef __cplusplus diff --git a/arch/x86_64/include/arch/irq.h b/arch/x86_64/include/arch/irq.h index bb0fbf3..008a794 100644 --- a/arch/x86_64/include/arch/irq.h +++ b/arch/x86_64/include/arch/irq.h @@ -1,8 +1,8 @@ #ifndef ARCH_IRQ_H_ #define ARCH_IRQ_H_ -#include -#include +#include +#include #include #ifdef __cplusplus diff --git a/arch/x86_64/include/arch/paging.h b/arch/x86_64/include/arch/paging.h index ff34016..9c6a770 100644 --- a/arch/x86_64/include/arch/paging.h +++ b/arch/x86_64/include/arch/paging.h @@ -1,8 +1,8 @@ #ifndef ARCH_PAGING_H_ #define ARCH_PAGING_H_ -#include -#include +#include +#include #ifdef __cplusplus extern "C" { diff --git a/arch/x86_64/include/arch/tss.h b/arch/x86_64/include/arch/tss.h index c4ee648..6a259e1 100644 --- a/arch/x86_64/include/arch/tss.h +++ b/arch/x86_64/include/arch/tss.h @@ -1,8 +1,8 @@ #ifndef ARCH_TSS_H_ #define ARCH_TSS_H_ -#include -#include +#include +#include #include #define TSS_GDT_INDEX 5 diff --git a/arch/x86_64/include/mango/machine/cpu.h b/arch/x86_64/include/mango/machine/cpu.h deleted file mode 100644 index f540bce..0000000 --- a/arch/x86_64/include/mango/machine/cpu.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef MANGO_X86_64_CPU_H_ -#define MANGO_X86_64_CPU_H_ - -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define ML_BIG_ENDIAN 0 - -#define ml_cpu_block_get_id(p) ((p)->c_cpu_id) -#define ml_cpu_block_get_data(p) ((p)->c_data) - -#if 0 -#define ml_read_sp(sp, bp) \ - asm volatile("mov %%rsp, %0" : "=r"(sp)); \ - asm volatile("mov %%rbp, %0" : "=r"(bp)); -#endif - -struct cpu_data; - -typedef struct ml_cpu_block { - struct ml_cpu_block *c_this; - - struct gdt c_gdt; - struct gdt_ptr c_gdt_ptr; - - struct tss c_tss; - struct tss_ptr c_tss_ptr; - - struct idt_ptr c_idt_ptr; - unsigned int c_cpu_id; - - struct cpu_data *c_data; -} ml_cpu_block; - -struct ml_cpu_context { - uint64_t r15, r14, r13, r12, r11, r10, r9, r8; - uint64_t rdi, rsi, rbp, unused_rsp, rbx, rdx, rcx, rax; - uint64_t int_no, err_no; - uint64_t rip, cs, rflags, rsp, ss; -} __packed; - -#define ml_cpu_pause() __asm__ __volatile__("hlt") -#define ml_cpu_relax() __asm__ __volatile__("pause") - -#define ml_int_disable() __asm__ __volatile__("cli") -#define ml_int_enable() __asm__ __volatile__("sti") - -extern int ml_init_bootcpu(void); - -extern int ml_cpu_block_init(ml_cpu_block *p); -extern int ml_cpu_block_use(ml_cpu_block *p); - -extern virt_addr_t ml_cpu_block_get_ustack(ml_cpu_block *p); -extern virt_addr_t ml_cpu_block_get_kstack(ml_cpu_block *p); - -extern void ml_cpu_block_set_ustack(ml_cpu_block *p, virt_addr_t sp); -extern void ml_cpu_block_set_kstack(ml_cpu_block *p, virt_addr_t sp); - -/* defined in cpu_ctrl.S */ -extern void ml_halt_cpu(void); -extern ml_cpu_block *ml_this_cpu(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/arch/x86_64/include/mango/machine/hwlock.h b/arch/x86_64/include/mango/machine/hwlock.h deleted file mode 100644 index f1166da..0000000 --- a/arch/x86_64/include/mango/machine/hwlock.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef MANGO_X86_64_HWLOCK_H_ -#define MANGO_X86_64_HWLOCK_H_ - -#define ML_HWLOCK_INIT (0) - -#ifdef __cplusplus -extern "C" { -#endif - -typedef int ml_hwlock_t; - -extern void ml_hwlock_lock(ml_hwlock_t *lck); -extern void ml_hwlock_unlock(ml_hwlock_t *lck); - -extern void ml_hwlock_lock_irqsave(ml_hwlock_t *lck, unsigned long *flags); -extern void ml_hwlock_unlock_irqrestore(ml_hwlock_t *lck, unsigned long flags); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/arch/x86_64/include/mango/machine/init.h b/arch/x86_64/include/mango/machine/init.h deleted file mode 100644 index 669f9fa..0000000 --- a/arch/x86_64/include/mango/machine/init.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef MANGO_X86_64_INIT_H_ -#define MANGO_X86_64_INIT_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define __X2(x) #x -#define __X(x) __X2(x) - -#define __define_initcall(fn, id) \ - static initcall_t __initcall_##fn##id __used __section( \ - ".initcall" __X(id) ".init") \ - = (fn) - -extern int ml_init(uintptr_t arg); - -extern const struct framebuffer_varinfo *bootfb_varinfo(void); -extern const struct framebuffer_fixedinfo *bootfb_fixedinfo(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/arch/x86_64/include/mango/machine/irq.h b/arch/x86_64/include/mango/machine/irq.h deleted file mode 100644 index 0d47448..0000000 --- a/arch/x86_64/include/mango/machine/irq.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef MANGO_X86_64_IRQ_H_ -#define MANGO_X86_64_IRQ_H_ - - -#endif diff --git a/arch/x86_64/include/mango/machine/panic.h b/arch/x86_64/include/mango/machine/panic.h deleted file mode 100644 index ddd0b8f..0000000 --- a/arch/x86_64/include/mango/machine/panic.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef MANGO_X86_64_PANIC_H_ -#define MANGO_X86_64_PANIC_H_ - -#include - -struct ml_cpu_context; - -extern void ml_print_cpu_state(struct ml_cpu_context *ctx); -extern void ml_print_stack_trace(uintptr_t ip); -extern void ml_print_stack_trace_irq(struct ml_cpu_context *ctx); - -#endif diff --git a/arch/x86_64/include/mango/machine/pmap.h b/arch/x86_64/include/mango/machine/pmap.h deleted file mode 100644 index 8d47179..0000000 --- a/arch/x86_64/include/mango/machine/pmap.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef MANGO_X86_64_PMAP_H_ -#define MANGO_X86_64_PMAP_H_ - -#include - -#define ML_PMAP_INVALID ((uintptr_t)-1) - -typedef pml4t_ptr_t ml_pmap_t; -typedef uint64_t ml_pfn_t; - -#endif diff --git a/arch/x86_64/include/mango/machine/thread.h b/arch/x86_64/include/mango/machine/thread.h deleted file mode 100644 index fa22802..0000000 --- a/arch/x86_64/include/mango/machine/thread.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef MANGO_X86_64_THREAD_H_ -#define MANGO_X86_64_THREAD_H_ - -#include - -struct ml_cpu_context; - -/* switch from one thread to another. the stack of the `to` thread must have - * been prepared in one of two ways: - * 1) a previous call to ml_thread_switch where it was the `from` thread. - * 2) a call to ml_thread_prepare_kernel_context - * the switch occurs entirely with kernel mode. a further return from an - * interrupt context is then used to return to usermode if necessary. - */ -extern void ml_thread_switch(struct thread *from, struct thread *to); - -/* perform the initial transition to userspace. the stack must be prepared using - * ml_thread_prepare_user_context before this function can be used */ -extern void ml_thread_switch_user(void); -/* prepare the stack so that ml_thread_switch can jump to the specified IP/SP */ -extern void ml_thread_prepare_kernel_context(uintptr_t ip, uintptr_t *sp); -/* prepare the stack so that ml_thread_switch_user can jump to usermode - * with the specified IP/user SP */ -extern void ml_thread_prepare_user_context( - virt_addr_t ip, - virt_addr_t user_sp, - virt_addr_t *kernel_sp); - -#endif diff --git a/arch/x86_64/include/mango/machine/vm.h b/arch/x86_64/include/mango/machine/vm.h deleted file mode 100644 index 38364e4..0000000 --- a/arch/x86_64/include/mango/machine/vm.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef MANGO_X86_64_VM_H_ -#define MANGO_X86_64_VM_H_ - -/* kernel higher-half base virtual address. */ -#define VM_KERNEL_VOFFSET 0xFFFFFFFF80000000 - -/* direct page-mapping region. - NOTE that these are the maximum bounds of this region. - the actual size depends on the amount of physical - memory present. */ -#define VM_PAGEMAP_BASE 0xFFFF888000000000 -#define VM_PAGEMAP_LIMIT 0xFFFFC87FFFFFFFFF - -#define VM_PAGE_SIZE 0x1000 -#define VM_PAGE_MASK (VM_PAGE_SIZE - 1) -#define VM_PAGE_SHIFT 12 - -#define VM_PAGE_MIN_ORDER VM_PAGE_4K -#define VM_PAGE_MAX_ORDER VM_PAGE_8M - -#define VM_ZONE_MIN VM_ZONE_DMA -#define VM_ZONE_MAX VM_ZONE_NORMAL - -#define VM_USER_BASE 0x0000000000100000 -#define VM_USER_LIMIT 0x00007fffffffffff - -#define VM_KERNEL_BASE 0XFFFF800000000000 -#define VM_KERNEL_LIMIT 0XFFFFFFFFFFFFFFFF - -#endif diff --git a/arch/x86_64/init.c b/arch/x86_64/init.c index 2a74599..70b0e6b 100644 --- a/arch/x86_64/init.c +++ b/arch/x86_64/init.c @@ -2,21 +2,21 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #define PTR32(x) ((void *)((uintptr_t)(x))) diff --git a/arch/x86_64/initcall.c b/arch/x86_64/initcall.c index 53d85c9..6577244 100644 --- a/arch/x86_64/initcall.c +++ b/arch/x86_64/initcall.c @@ -1,4 +1,4 @@ -#include +#include extern char __initcall0_start[]; extern char __initcall1_start[]; diff --git a/arch/x86_64/irq.c b/arch/x86_64/irq.c index f18b445..3716988 100644 --- a/arch/x86_64/irq.c +++ b/arch/x86_64/irq.c @@ -1,13 +1,13 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include #include #define MAX_ISR_HANDLERS 16 @@ -31,7 +31,7 @@ static uintptr_t int_entry_points[NR_IDT_ENTRIES]; static void set_syscall_gate(uintptr_t rip) { uint64_t user_cs = 0x13; - uint64_t kernel_cs = 0x8; + uint64_t kernel_cs = 0x08; uintptr_t star_reg = 0xC0000081; uintptr_t lstar_reg = 0xC0000082; @@ -97,11 +97,7 @@ static void pf_handler(struct ml_cpu_context *regs) virt_addr_t fault_ptr = pf_faultptr(); - kern_status_t status = KERN_FATAL_ERROR; - - if (regs->err_no & PF_USER) { - status = pmap_handle_fault(fault_ptr, fault_flags); - } + kern_status_t status = pmap_handle_fault(fault_ptr, fault_flags); if (status == KERN_OK) { return; diff --git a/arch/x86_64/panic.c b/arch/x86_64/panic.c index 66889a8..21afab1 100644 --- a/arch/x86_64/panic.c +++ b/arch/x86_64/panic.c @@ -1,9 +1,9 @@ #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #define R_CF 0 #define R_PF 2 diff --git a/arch/x86_64/pit.c b/arch/x86_64/pit.c index c8d7b28..d2627e5 100644 --- a/arch/x86_64/pit.c +++ b/arch/x86_64/pit.c @@ -1,8 +1,8 @@ #include #include -#include -#include -#include +#include +#include +#include #define PIT_COUNTER0 0x40 #define PIT_CMD 0x43 diff --git a/arch/x86_64/pmap.c b/arch/x86_64/pmap.c index 96ff69b..9dee925 100644 --- a/arch/x86_64/pmap.c +++ b/arch/x86_64/pmap.c @@ -1,14 +1,14 @@ -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include -#include -#include -#include /* some helpful datasize constants */ #define C_1GiB 0x40000000ULL @@ -43,7 +43,7 @@ static pmap_t alloc_pmap(void) return vm_virt_to_phys(p); } -static pte_t make_pte(pfn_t pfn, enum vm_prot prot, enum page_size size) +static pte_t make_pte(pfn_t pfn, vm_prot_t prot, enum page_size size) { pte_t v = pfn; @@ -139,7 +139,7 @@ static kern_status_t do_pmap_add( pmap_t pmap, virt_addr_t pv, pfn_t pfn, - enum vm_prot prot, + vm_prot_t prot, enum page_size size) { unsigned int pml4t_index = BAD_INDEX, pdpt_index = BAD_INDEX, @@ -371,7 +371,7 @@ kern_status_t pmap_add( pmap_t pmap, virt_addr_t p, pfn_t pfn, - enum vm_prot prot, + vm_prot_t prot, enum pmap_flags flags) { enum page_size ps = PS_4K; @@ -387,7 +387,7 @@ kern_status_t pmap_add_block( virt_addr_t p, pfn_t pfn, size_t len, - enum vm_prot prot, + vm_prot_t prot, enum pmap_flags flags) { return KERN_OK; diff --git a/arch/x86_64/serial.c b/arch/x86_64/serial.c index 79f8f48..97212eb 100644 --- a/arch/x86_64/serial.c +++ b/arch/x86_64/serial.c @@ -1,8 +1,8 @@ #include #include #include -#include -#include +#include +#include #define COM1 0x3F8 #define COM2 0x2F8 diff --git a/arch/x86_64/thread.c b/arch/x86_64/thread.c index 823b5d2..9b29acc 100644 --- a/arch/x86_64/thread.c +++ b/arch/x86_64/thread.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include /* this is the context information restored by ml_thread_switch. * since ml_thread_switch only jumps to kernel-mode, IRETQ isn't used, diff --git a/arch/x86_64/tss.c b/arch/x86_64/tss.c index 7edae81..d22450f 100644 --- a/arch/x86_64/tss.c +++ b/arch/x86_64/tss.c @@ -2,7 +2,7 @@ #include #include -#include +#include static void tss_flush(int index) { diff --git a/arch/x86_64/vga.c b/arch/x86_64/vga.c index 0aff2cd..297cdce 100644 --- a/arch/x86_64/vga.c +++ b/arch/x86_64/vga.c @@ -1,9 +1,9 @@ #include #include #include -#include -#include -#include +#include +#include +#include struct vga_console { uint16_t *vga_framebuffer; diff --git a/ds/bitmap.c b/ds/bitmap.c index 514be59..6cde51a 100644 --- a/ds/bitmap.c +++ b/ds/bitmap.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include void bitmap_zero(unsigned long *map, unsigned long nbits) { diff --git a/ds/btree.c b/ds/btree.c index 311ff89..8ee4867 100644 --- a/ds/btree.c +++ b/ds/btree.c @@ -57,7 +57,7 @@ provide a comparator function. */ -#include +#include #include #define MAX(a, b) ((a) > (b) ? (a) : (b)) diff --git a/ds/queue.c b/ds/queue.c index 31f2765..f855002 100644 --- a/ds/queue.c +++ b/ds/queue.c @@ -1,4 +1,4 @@ -#include +#include size_t queue_length(struct queue *q) { diff --git a/ds/ringbuffer.c b/ds/ringbuffer.c index 1dcbc71..3f7fdbc 100644 --- a/ds/ringbuffer.c +++ b/ds/ringbuffer.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include size_t ringbuffer_unread(struct ringbuffer *ring_buffer) { diff --git a/include/mango/arg.h b/include/mango/arg.h deleted file mode 100644 index f1b8106..0000000 --- a/include/mango/arg.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef MANGO_ARG_H_ -#define MANGO_ARG_H_ - -#include -#include - -#define CMDLINE_MAX 4096 - -extern kern_status_t parse_cmdline(const char *cmdline); - -extern const char *arg_value(const char *arg_name); -extern bool arg_is_set(const char *arg_name); - -#endif diff --git a/include/mango/bitmap.h b/include/mango/bitmap.h deleted file mode 100644 index 98101e0..0000000 --- a/include/mango/bitmap.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef MANGO_BITMAP_H_ -#define MANGO_BITMAP_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define BITS_PER_WORD (8 * sizeof(unsigned long)) -#define __DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) -#define BITMAP_WORDS(nbits) __DIV_ROUND_UP(nbits, BITS_PER_WORD) -#define BITMAP_NPOS ((unsigned int)-1) - -#define DECLARE_BITMAP(name, nbits) unsigned long name[BITMAP_WORDS(nbits)] - -extern void bitmap_zero(unsigned long *map, unsigned long nbits); -extern void bitmap_fill(unsigned long *map, unsigned long nbits); -extern void bitmap_set(unsigned long *map, unsigned long bit); -extern void bitmap_clear(unsigned long *map, unsigned long bit); -extern bool bitmap_check(unsigned long *map, unsigned long bit); - -extern unsigned int bitmap_count_set(unsigned long *map, unsigned long nbits); -extern unsigned int bitmap_count_clear(unsigned long *map, unsigned long nbits); - -extern unsigned int bitmap_highest_set(unsigned long *map, unsigned long nbits); -extern unsigned int bitmap_highest_clear(unsigned long *map, unsigned long nbits); -extern unsigned int bitmap_lowest_set(unsigned long *map, unsigned long nbits); -extern unsigned int bitmap_lowest_clear(unsigned long *map, unsigned long nbits); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/mango/bsp.h b/include/mango/bsp.h deleted file mode 100644 index 7aa219b..0000000 --- a/include/mango/bsp.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef MANGO_BSP_H_ -#define MANGO_BSP_H_ - -#include -#include -#include -#include -#include - -#define BSP_MAGIC 0xcafebabe - -struct task; - -struct bsp_trailer { - /* these fields are stored in big endian in the package itself */ - uint32_t bsp_magic; - uint64_t bsp_fs_offset; - uint32_t bsp_fs_len; - uint64_t bsp_exec_offset; - uint32_t bsp_exec_len; - uint64_t bsp_text_faddr, bsp_text_vaddr, bsp_text_size; - uint64_t bsp_data_faddr, bsp_data_vaddr, bsp_data_size; - uint64_t bsp_exec_entry; -} __packed; - -struct bsp { - /* the values in this struct are stored in host byte order */ - struct bsp_trailer bsp_trailer; - struct vm_object *bsp_vmo; -}; - -extern void bsp_set_location(const struct boot_module *mod); -extern void bsp_get_location(struct boot_module *out); - -extern kern_status_t bsp_load(struct bsp *bsp, const struct boot_module *mod); -extern kern_status_t bsp_launch_async(struct bsp *bsp, struct task *task); - -#endif diff --git a/include/mango/btree.h b/include/mango/btree.h deleted file mode 100644 index 4cd965e..0000000 --- a/include/mango/btree.h +++ /dev/null @@ -1,381 +0,0 @@ -/* - The Clear BSD License - - Copyright (c) 2023 Max Wash - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted (subject to the limitations in the disclaimer - below) provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from this - software without specific prior written permission. - */ - -#ifndef MANGO_BTREE_H_ -#define MANGO_BTREE_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* if your custom structure contains a struct btree_node (i.e. it can be part of a btree), - you can use this macro to convert a struct btree_node* to a your_type* - - @param t the name of your custom type (something that can be passed to offsetof) - @param m the name of the struct btree_node member variable within your custom type. - @param v the struct btree_node pointer that you wish to convert. if this is NULL, NULL will be returned. -*/ -#define BTREE_CONTAINER(t, m, v) ((void *)((v) ? (uintptr_t)(v) - (offsetof(t, m)) : 0)) - -/* defines a simple node insertion function. - this function assumes that your nodes have simple integer keys that can be compared with the usual operators. - - EXAMPLE: - if you have a tree node type like this: - - struct my_tree_node { - int key; - struct btree_node base; - } - - You would use the following call to generate an insert function for a tree with this node type: - - BTREE_DEFINE_SIMPLE_INSERT(struct my_tree_node, base, key, my_tree_node_insert); - - Which would emit a function defined like: - - static void my_tree_node_insert(struct btree *tree, struct my_tree_node *node); - - @param node_type your custom tree node type. usually a structure that contains a struct btree_node member. - @param container_node_member the name of the struct btree_node member variable within your custom type. - @param container_key_member the name of the key member variable within your custom type. - @param function_name the name of the function to generate. -*/ -#define BTREE_DEFINE_SIMPLE_INSERT(node_type, container_node_member, container_key_member, function_name) \ - void function_name(struct btree *tree, node_type *node) \ - { \ - if (!tree->b_root) { \ - tree->b_root = &node->container_node_member; \ - btree_insert_fixup(tree, &node->container_node_member); \ - return; \ - } \ - \ - struct btree_node *cur = tree->b_root; \ - while (1) { \ - node_type *cur_node = BTREE_CONTAINER(node_type, container_node_member, cur); \ - struct btree_node *next = NULL; \ - \ - if (node->container_key_member > cur_node->container_key_member) { \ - next = btree_right(cur); \ - \ - if (!next) { \ - btree_put_right(cur, &node->container_node_member); \ - break; \ - } \ - } else if (node->container_key_member < cur_node->container_key_member) { \ - next = btree_left(cur); \ - \ - if (!next) { \ - btree_put_left(cur, &node->container_node_member); \ - break; \ - } \ - } else { \ - return; \ - } \ - \ - cur = next; \ - } \ - \ - btree_insert_fixup(tree, &node->container_node_member); \ - } - -/* defines a node insertion function. - this function should be used for trees with complex node keys that cannot be directly compared. - a comparator for your keys must be supplied. - - EXAMPLE: - if you have a tree node type like this: - - struct my_tree_node { - complex_key_t key; - struct btree_node base; - } - - You would need to define a comparator function or macro with the following signature: - - int my_comparator(struct my_tree_node *a, struct my_tree_node *b); - - Which implements the following: - - return -1 if a < b - return 0 if a == b - return 1 if a > b - - You would use the following call to generate an insert function for a tree with this node type: - - BTREE_DEFINE_INSERT(struct my_tree_node, base, key, my_tree_node_insert, my_comparator); - - Which would emit a function defined like: - - static void my_tree_node_insert(struct btree *tree, struct my_tree_node *node); - - @param node_type your custom tree node type. usually a structure that contains a struct btree_node member. - @param container_node_member the name of the struct btree_node member variable within your custom type. - @param container_key_member the name of the key member variable within your custom type. - @param function_name the name of the function to generate. - @param comparator the name of a comparator function or functional-macro that conforms to the - requirements listed above. -*/ -#define BTREE_DEFINE_INSERT(node_type, container_node_member, container_key_member, function_name, comparator) \ - void function_name(struct btree *tree, node_type *node) \ - { \ - if (!tree->b_root) { \ - tree->b_root = &node->container_node_member; \ - btree_insert_fixup(tree, &node->container_node_member); \ - return; \ - } \ - \ - struct btree_node *cur = tree->b_root; \ - while (1) { \ - node_type *cur_node = BTREE_CONTAINER(node_type, container_node_member, cur); \ - struct btree_node *next = NULL; \ - int cmp = comparator(node, cur_node); \ - \ - if (cmp == 1) { \ - next = btree_right(cur); \ - \ - if (!next) { \ - btree_put_right(cur, &node->container_node_member); \ - break; \ - } \ - } else if (cmp == -1) { \ - next = btree_left(cur); \ - \ - if (!next) { \ - btree_put_left(cur, &node->container_node_member); \ - break; \ - } \ - } else { \ - return; \ - } \ - \ - cur = next; \ - } \ - \ - btree_insert_fixup(tree, &node->container_node_member); \ - } - -/* defines a simple tree search function. - this function assumes that your nodes have simple integer keys that can be compared with the usual operators. - - EXAMPLE: - if you have a tree node type like this: - - struct my_tree_node { - int key; - struct btree_node base; - } - - You would use the following call to generate a search function for a tree with this node type: - - BTREE_DEFINE_SIMPLE_GET(struct my_tree_node, int, base, key, my_tree_node_get); - - Which would emit a function defined like: - - static struct my_tree_node *my_tree_node_get(struct btree *tree, int key); - - @param node_type your custom tree node type. usually a structure that contains a struct btree_node member. - @param key_type the type name of the key embedded in your custom tree node type. this type must be - compatible with the builtin comparison operators. - @param container_node_member the name of the struct btree_node member variable within your custom type. - @param container_key_member the name of the key member variable within your custom type. - @param function_name the name of the function to generate. -*/ -#define BTREE_DEFINE_SIMPLE_GET(node_type, key_type, container_node_member, container_key_member, function_name) \ - node_type *function_name(struct btree *tree, key_type key) \ - { \ - struct btree_node *cur = tree->b_root; \ - while (cur) { \ - node_type *cur_node = BTREE_CONTAINER(node_type, container_node_member, cur); \ - if (key > cur_node->container_key_member) { \ - cur = btree_right(cur); \ - } else if (key < cur_node->container_key_member) { \ - cur = btree_left(cur); \ - } else { \ - return cur_node; \ - } \ - } \ - \ - return NULL; \ - } - -/* perform an in-order traversal of a binary tree - - If you have a tree defined like: - - struct btree my_tree; - - with nodes defined like: - - struct my_tree_node { - int key; - struct btree_node base; - } - - and you want to do something like: - - foreach (struct my_tree_node *node : my_tree) { ... } - - you should use this: - - btree_foreach (struct my_tree_node, node, &my_tree, base) { ... } - - @param iter_type the type name of the iterator variable. this should be the tree's node type, and shouldn't be a pointer. - @param iter_name the name of the iterator variable. - @param tree_name a pointer to the tree to traverse. - @param node_member the name of the struct btree_node member variable within the tree node type. -*/ -#define btree_foreach(iter_type, iter_name, tree_name, node_member) \ - for (iter_type *iter_name = BTREE_CONTAINER(iter_type, node_member, btree_first(tree_name)); \ - iter_name; \ - iter_name = BTREE_CONTAINER(iter_type, node_member, btree_next(&((iter_name)->node_member)))) - -/* perform an reverse in-order traversal of a binary tree - - If you have a tree defined like: - - struct btree my_tree; - - with nodes defined like: - - struct my_tree_node { - int key; - struct btree_node base; - } - - and you want to do something like: - - foreach (struct my_tree_node *node : reverse(my_tree)) { ... } - - you should use this: - - btree_foreach_r (struct my_tree_node, node, &my_tree, base) { ... } - - @param iter_type the type name of the iterator variable. this should be the tree's node type, and shouldn't be a pointer. - @param iter_name the name of the iterator variable. - @param tree_name a pointer to the tree to traverse. - @param node_member the name of the struct btree_node member variable within the tree node type. -*/ -#define btree_foreach_r(iter_type, iter_name, tree_name, node_member) \ - for (iter_type *iter_name = BTREE_CONTAINER(iter_type, node_member, btree_last(tree_name)); \ - iter_name; \ - iter_name = BTREE_CONTAINER(iter_type, node_member, btree_prev(&((iter_name)->node_member)))) - -/* binary tree nodes. this *cannot* be used directly. you need to define a custom node type - that contains a member variable of type struct btree_node. - - you would then use the supplied macros to define functions to manipulate your custom binary tree. -*/ -struct btree_node { - struct btree_node *b_parent, *b_left, *b_right; - unsigned short b_height; -}; - -/* binary tree. unlike struct btree_node, you can define variables of type struct btree. */ -struct btree { - struct btree_node *b_root; -}; - -/* re-balance a binary tree after an insertion operation. - - NOTE that, if you define an insertion function using BTREE_DEFINE_INSERT or similar, - this function will automatically called for you. - - @param tree the tree to re-balance. - @param node the node that was just inserted into the tree. -*/ -extern void btree_insert_fixup(struct btree *tree, struct btree_node *node); - -/* delete a node from a binary tree and re-balance the tree afterwards. - - @param tree the tree to delete from - @param node the node to delete. -*/ -extern void btree_delete(struct btree *tree, struct btree_node *node); - -/* get the first node in a binary tree. - - this will be the node with the smallest key (i.e. the node that is furthest-left from the root) -*/ -extern struct btree_node *btree_first(struct btree *tree); - -/* get the last node in a binary tree. - - this will be the node with the largest key (i.e. the node that is furthest-right from the root) -*/ -extern struct btree_node *btree_last(struct btree *tree); -/* for any binary tree node, this function returns the node with the next-largest key value */ -extern struct btree_node *btree_next(struct btree_node *node); -/* for any binary tree node, this function returns the node with the next-smallest key value */ -extern struct btree_node *btree_prev(struct btree_node *node); - -/* sets `child` as the immediate left-child of `parent` */ -static inline void btree_put_left(struct btree_node *parent, struct btree_node *child) -{ - parent->b_left = child; - child->b_parent = parent; -} - -/* sets `child` as the immediate right-child of `parent` */ -static inline void btree_put_right(struct btree_node *parent, struct btree_node *child) -{ - parent->b_right = child; - child->b_parent = parent; -} - -/* get the immediate left-child of `node` */ -static inline struct btree_node *btree_left(struct btree_node *node) -{ - return node->b_left; -} - -/* get the immediate right-child of `node` */ -static inline struct btree_node *btree_right(struct btree_node *node) -{ - return node->b_right; -} - -/* get the immediate parent of `node` */ -static inline struct btree_node *btree_parent(struct btree_node *node) -{ - return node->b_parent; -} - -/* get the height of `node`. - - the height of a node is defined as the length of the longest path - between the node and a leaf node. - - this count includes the node itself, so the height of a leaf node will be 1. -*/ -static inline unsigned short btree_height(struct btree_node *node) -{ - return node->b_height; -} - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/mango/clock.h b/include/mango/clock.h deleted file mode 100644 index 4928e31..0000000 --- a/include/mango/clock.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef MANGO_CLOCK_H_ -#define MANGO_CLOCK_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -#define HZ (clock_hz()) - -typedef uint64_t clock_ticks_t; - -extern volatile clock_ticks_t clock_ticks; - -extern clock_ticks_t clock_hz(void); - -extern void clock_calibrate(clock_ticks_t hz); -extern void clock_advance(clock_ticks_t ticks); -extern void clock_wait(clock_ticks_t ticks); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/mango/compiler.h b/include/mango/compiler.h deleted file mode 100644 index 8477ead..0000000 --- a/include/mango/compiler.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef MANGO_COMPILER_H_ -#define MANGO_COMPILER_H_ - -#ifdef __cplusplus -template -T read_once(const volatile T *ptr) -{ - return *ptr; -} - -template -void write_once(volatile T *ptr, T value) -{ - *ptr = value; -} -#else - -#define READ_ONCE(p) (*((const volatile typeof(p) *)&(p))) -#define WRITE_ONCE(p, v) *(volatile typeof(p) *)&(p) = (v) - -#endif - -#undef __used -#define __used __attribute__((__used__)) - -#undef __noreturn -#define __noreturn __attribute__((__noreturn__)) - -#undef __packed -#define __packed __attribute__((__packed__)) - -#undef __section -#define __section(name) __attribute__((__section__(name))) - -#undef __aligned -#define __aligned(x) __attribute__((__aligned__(x))) - -#undef __weak -#define __weak __attribute__((__weak__)) - -#endif diff --git a/include/mango/console.h b/include/mango/console.h deleted file mode 100644 index 45bab80..0000000 --- a/include/mango/console.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef MANGO_CONSOLE_H_ -#define MANGO_CONSOLE_H_ - -/* The console system - - Consoles are like simplified TTYs. Their purpose is to serve as an output - sink for messages printed using printk. - - a struct console could be used to represent a serial port, UART port, or even - a text-based framebuffer display. Anything where the job of displaying - or sending text can be abstracted to a simple write() call. - - A secondary purpose of consoles is to allow input. For example, a console - representing a serial port may allow both sending AND receiving over the - port. -*/ -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -enum console_flags { - /* console is only used during the boot process. the console - will be automatically de-registered when the first - non-boot console is registered */ - CON_BOOT = 0x01u, -}; - -struct console { - char c_name[16]; - enum console_flags c_flags; - spin_lock_t c_lock; - - void (*c_write)(struct console *, const char *, unsigned int); - int (*c_read)(struct console *, char *, unsigned int); - - struct queue_entry c_list; -}; - -extern kern_status_t console_register(struct console *con); -extern kern_status_t console_unregister(struct console *con); - -extern struct queue *get_consoles(unsigned long *flags); -extern void put_consoles(struct queue *consoles, unsigned long flags); - -extern void console_write(struct console *con, const char *s, unsigned int len); -extern int console_read(struct console *con, char *s, unsigned int len); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/mango/cpu.h b/include/mango/cpu.h deleted file mode 100644 index bd00ceb..0000000 --- a/include/mango/cpu.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef MANGO_CPU_H_ -#define MANGO_CPU_H_ - -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -enum cpu_flags { - CPU_ONLINE = 0x01u, -}; - -struct cpu_data { - enum cpu_flags c_flags; - unsigned int c_id; - int c_preempt_count; - - struct runqueue c_rq; - struct workqueue c_wq; - struct queue c_timers; -}; - -/* maximum number of processor cores that the kernel can support. - TODO move to build config option */ -#define CPU_MAX 128 - -#define this_cpu() (ml_cpu_block_get_id(ml_this_cpu())) - -extern struct cpu_data *get_this_cpu(void); -extern struct cpu_data *get_cpu(unsigned int id); -extern void put_cpu(struct cpu_data *cpu); - -extern bool cpu_is_available(unsigned int cpu_id); -extern bool cpu_is_online(unsigned int cpu_id); - -extern void cpu_set_available(unsigned int cpu_id); -extern void cpu_set_online(unsigned int cpu_id); - -extern unsigned int cpu_nr_available(void); -extern unsigned int cpu_nr_online(void); - -extern cycles_t get_cycles(void); -static inline cycles_t cycles_diff(cycles_t then, cycles_t now) -{ - return now >= then ? now - then : (CYCLES_MAX - then) + now; -} - -#define irq_enable() ml_int_enable() -#define irq_disable() ml_int_disable() - -extern void preempt_disable(void); -extern void preempt_enable(void); -extern int preempt_count(void); - -extern unsigned int cpu_get_highest_available(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/mango/fb.h b/include/mango/fb.h deleted file mode 100644 index c718dce..0000000 --- a/include/mango/fb.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef MANGO_FB_H_ -#define MANGO_FB_H_ - -#include - -enum framebuffer_flags { - FB_MODE_RGB = 0x01u, - FB_MODE_VGATEXT = 0x02u, - FB_MODE_PALETTE = 0x04u, -}; - -struct framebuffer_bitfield { - uint32_t b_offset; - uint16_t b_length; -}; - -struct framebuffer_varinfo { - enum framebuffer_flags fb_flags; - - uint32_t fb_xres; - uint32_t fb_yres; - uint32_t fb_bpp; - uint32_t fb_stride; - - union { - struct { - uint32_t fb_xcells; - uint32_t fb_ycells; - }; - - struct { - struct framebuffer_bitfield fb_red; - struct framebuffer_bitfield fb_green; - struct framebuffer_bitfield fb_blue; - struct framebuffer_bitfield fb_alpha; - }; - - struct { - uintptr_t fb_palette_addr; - uint16_t fb_palette_nr_colours; - }; - }; -}; - -struct framebuffer_fixedinfo { - uint64_t fb_baseptr; -}; - -#endif diff --git a/include/mango/flags.h b/include/mango/flags.h deleted file mode 100644 index b30a531..0000000 --- a/include/mango/flags.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef MANGO_FLAGS_H_ -#define MANGO_FLAGS_H_ - -#include - -typedef enum { - S_NORMAL = 0x00u, - S_NOBLOCK = 0x01u, -} mango_flags_t; - -#endif diff --git a/include/mango/handle.h b/include/mango/handle.h deleted file mode 100644 index 2ff62d9..0000000 --- a/include/mango/handle.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef MANGO_HANDLE_H_ -#define MANGO_HANDLE_H_ - -#include -#include -#include - -/* subtract 32 bytes to account for the handle bitmap */ -#define HANDLES_PER_TABLE ((4096 - 32) / sizeof(struct handle)) -#define REFS_PER_TABLE ((4096 - 64) / sizeof(struct handle_table *)) - -typedef uint32_t kern_handle_t; - -struct object; - -struct handle { - union { - struct object *h_object; - uint64_t __x; - }; - - uint64_t h_flags; -}; - -struct handle_table { - union { - struct { - /* bitmap tracks which bits in t_handle_list are - * allocated */ - DECLARE_BITMAP(t_handle_map, HANDLES_PER_TABLE); - struct handle t_handle_list[HANDLES_PER_TABLE]; - } t_handles; - - struct { - /* bitmap tracks which sub-tables are fully-allocated */ - DECLARE_BITMAP(t_subtable_map, REFS_PER_TABLE); - struct handle_table *t_subtable_list[REFS_PER_TABLE]; - } t_subtables; - }; -}; - -extern struct handle_table *handle_table_create(void); -extern void handle_table_destroy(struct handle_table *tab); - -extern kern_status_t handle_table_alloc_handle( - struct handle_table *tab, - struct handle **out_slot, - kern_handle_t *out_handle); -extern void handle_table_free_handle( - struct handle_table *tab, - kern_handle_t handle); -extern struct handle *handle_table_get_handle( - struct handle_table *tab, - kern_handle_t handle); - -#endif diff --git a/include/mango/init.h b/include/mango/init.h deleted file mode 100644 index caf515d..0000000 --- a/include/mango/init.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef MANGO_INIT_H_ -#define MANGO_INIT_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef int (*initcall_t)(void); - -#define INITLEVEL_EARLY 0 -#define INITLEVEL_CORE 1 -#define INITLEVEL_POSTCORE 2 -#define INITLEVEL_ARCH 3 -#define INITLEVEL_SUBSYS 4 -#define INITLEVEL_ROOTFS 5 -#define INITLEVEL_DEVICE 6 -#define INITLEVEL_LATE 7 -#define INITLEVEL_TESTS 8 - -#define early_initcall(fn) __define_initcall(fn, INITLEVEL_EARLY) -#define core_initcall(fn) __define_initcall(fn, INITLEVEL_CORE) -#define postcore_initcall(fn) __define_initcall(fn, INITLEVEL_POSTCORE) -#define arch_initcall(fn) __define_initcall(fn, INITLEVEL_ARCH) -#define subsys_initcall(fn) __define_initcall(fn, INITLEVEL_SUBSYS) -#define rootfs_initcall(fn) __define_initcall(fn, INITLEVEL_ROOTFS) -#define device_initcall(fn) __define_initcall(fn, INITLEVEL_DEVICE) -#define late_initcall(fn) __define_initcall(fn, INITLEVEL_LATE) -#define test_initcall(fn) __define_initcall(fn, INITLEVEL_TESTS) - -extern void print_kernel_banner(void); -extern int do_initcalls(void); -extern int start_initlevel(int level); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/mango/input.h b/include/mango/input.h deleted file mode 100644 index 707c998..0000000 --- a/include/mango/input.h +++ /dev/null @@ -1,184 +0,0 @@ -#ifndef MANGO_INPUT_H_ -#define MANGO_INPUT_H_ - -#include -#include -#include - -enum input_event_hook_flags { - INPUT_HOOK_SQUASH_EVENT = 0x01u, -}; - -struct device; - -enum input_event_type { - INPUT_TYPE_UNKNOWN = 0x00u, - INPUT_TYPE_KEY = 0x01u, - INPUT_TYPE_MOTION = 0x02u, -}; - -enum input_event_motion_type { - INPUT_MOTION_TYPE_MOUSE = 0x01u, - INPUT_MOTION_TYPE_SCROLL = 0x02u, -}; - -enum input_keycode { - KEY_UNKNOWN = 0x00u, - KEY_A = 0x01u, - KEY_B = 0x02u, - KEY_C = 0x03u, - KEY_D = 0x04u, - KEY_E = 0x05u, - KEY_F = 0x06u, - KEY_G = 0x07u, - KEY_H = 0x08u, - KEY_I = 0x09u, - KEY_J = 0x0Au, - KEY_K = 0x0Bu, - KEY_L = 0x0Cu, - KEY_M = 0x0Du, - KEY_N = 0x0Eu, - KEY_O = 0x0Fu, - KEY_P = 0x10u, - KEY_Q = 0x11u, - KEY_R = 0x12u, - KEY_S = 0x13u, - KEY_T = 0x14u, - KEY_U = 0x15u, - KEY_V = 0x16u, - KEY_W = 0x17u, - KEY_X = 0x18u, - KEY_Y = 0x19u, - KEY_Z = 0x1Au, - KEY_KEY_1 = 0x1Bu, - KEY_KEY_2 = 0x1Cu, - KEY_KEY_3 = 0x1Du, - KEY_KEY_4 = 0x1Eu, - KEY_KEY_5 = 0x1Fu, - KEY_KEY_6 = 0x20u, - KEY_KEY_7 = 0x21u, - KEY_KEY_8 = 0x22u, - KEY_KEY_9 = 0x23u, - KEY_KEY_0 = 0x24u, - KEY_ENTER = 0x25u, - KEY_ESCAPE = 0x26u, - KEY_BACKSPACE = 0x27u, - KEY_TAB = 0x28u, - KEY_SPACE = 0x29u, - KEY_MINUS = 0x2Au, - KEY_EQUALS = 0x2Bu, - KEY_LEFT_BRACE = 0x2Cu, - KEY_RIGHT_BRACE = 0x2Du, - KEY_BACKSLASH = 0x2Eu, - KEY_NON_US_HASH = 0x2Fu, - KEY_SEMICOLON = 0x30u, - KEY_APOSTROPHE = 0x31u, - KEY_GRAVE_ACCENT = 0x32u, - KEY_COMMA = 0x33u, - KEY_DOT = 0x34u, - KEY_SLASH = 0x35u, - KEY_CAPS_LOCK = 0x36u, - KEY_F1 = 0x37u, - KEY_F2 = 0x38u, - KEY_F3 = 0x39u, - KEY_F4 = 0x3Au, - KEY_F5 = 0x3Bu, - KEY_F6 = 0x3Cu, - KEY_F7 = 0x3Du, - KEY_F8 = 0x3Eu, - KEY_F9 = 0x3Fu, - KEY_F10 = 0x40u, - KEY_F11 = 0x41u, - KEY_F12 = 0x42u, - KEY_PRINT_SCREEN = 0x43u, - KEY_SCROLL_LOCK = 0x44u, - KEY_PAUSE = 0x45u, - KEY_INSERT = 0x46u, - KEY_HOME = 0x47u, - KEY_PAGE_UP = 0x48u, - KEY_DELETE = 0x49u, - KEY_END = 0x4Au, - KEY_PAGE_DOWN = 0x4Bu, - KEY_RIGHT = 0x4Cu, - KEY_LEFT = 0x4Du, - KEY_DOWN = 0x4Eu, - KEY_UP = 0x4Fu, - KEY_NUM_LOCK = 0x50u, - KEY_KEYPAD_SLASH = 0x51u, - KEY_KEYPAD_ASTERISK = 0x52u, - KEY_KEYPAD_MINUS = 0x53u, - KEY_KEYPAD_PLUS = 0x54u, - KEY_KEYPAD_ENTER = 0x55u, - KEY_KEYPAD_1 = 0x56u, - KEY_KEYPAD_2 = 0x57u, - KEY_KEYPAD_3 = 0x58u, - KEY_KEYPAD_4 = 0x59u, - KEY_KEYPAD_5 = 0x5Au, - KEY_KEYPAD_6 = 0x5Bu, - KEY_KEYPAD_7 = 0x5Cu, - KEY_KEYPAD_8 = 0x5Du, - KEY_KEYPAD_9 = 0x5Eu, - KEY_KEYPAD_0 = 0x5Fu, - KEY_KEYPAD_DOT = 0x60u, - KEY_NON_US_BACKSLASH = 0x61u, - KEY_KEYPAD_EQUALS = 0x62u, - KEY_MENU = 0x63u, - KEY_LEFT_CTRL = 0x64u, - KEY_LEFT_SHIFT = 0x65u, - KEY_LEFT_ALT = 0x66u, - KEY_LEFT_META = 0x67u, - KEY_RIGHT_CTRL = 0x68u, - KEY_RIGHT_SHIFT = 0x69u, - KEY_RIGHT_ALT = 0x6Au, - KEY_RIGHT_META = 0x6Bu, - KEY_MEDIA_MUTE = 0x6Cu, - KEY_MEDIA_VOLUME_INCREMENT = 0x6Du, - KEY_MEDIA_VOLUME_DECREMENT = 0x6Eu, -}; - -enum input_key_state { - INPUT_KEYSTATE_DOWN = 0x00u, - INPUT_KEYSTATE_UP = 0x01u, -}; - -enum input_button { - INPUT_BUTTON_MOUSE_LEFT = 0x00u, - INPUT_BUTTON_MOUSE_MIDDLE = 0x01u, - INPUT_BUTTON_MOUSE_RIGHT = 0x02u, - INPUT_BUTTON_MOUSE_BACK = 0x03u, - INPUT_BUTTON_MOUSE_FORWARD = 0x04u, -}; - -enum input_button_state { - INPUT_BUTTON_DOWN = 0x00u, - INPUT_BUTTON_UP = 0x01u, -}; - -struct input_event { - enum input_event_type ev_type; - union { - struct { - enum input_event_motion_type type; - int16_t movement_x; - int16_t movement_y; - } ev_motion; - - struct { - enum input_button button; - enum input_button_state state; - } ev_button; - - struct { - enum input_keycode key; - enum input_key_state state; - } ev_key; - }; -}; - -struct input_event_hook { - void(*hook_callback)(struct device *, struct input_event *, enum input_event_hook_flags *, void *); - void *hook_arg; - struct queue_entry hook_head; -}; - -#endif diff --git a/include/mango/locks.h b/include/mango/locks.h deleted file mode 100644 index 9289640..0000000 --- a/include/mango/locks.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef MANGO_LOCKS_H_ -#define MANGO_LOCKS_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef __aligned(8) ml_hwlock_t spin_lock_t; - -#define SPIN_LOCK_INIT ML_HWLOCK_INIT - -#define spin_lock(lck) ml_hwlock_lock(lck); -#define spin_unlock(lck) ml_hwlock_unlock(lck); - -#define spin_lock_irqsave(lck, flags) ml_hwlock_lock_irqsave(lck, flags); -#define spin_unlock_irqrestore(lck, flags) ml_hwlock_unlock_irqrestore(lck, flags); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/mango/memblock.h b/include/mango/memblock.h deleted file mode 100644 index 931d26d..0000000 --- a/include/mango/memblock.h +++ /dev/null @@ -1,345 +0,0 @@ -/* - The Clear BSD License - - Copyright (c) 2023 Max Wash - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted (subject to the limitations in the disclaimer - below) provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from this - software without specific prior written permission. - */ -#ifndef MANGO_MEMBLOCK_H_ -#define MANGO_MEMBLOCK_H_ - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define MEMBLOCK_INIT_MEMORY_REGION_COUNT 128 -#define MEMBLOCK_INIT_RESERVED_REGION_COUNT 128 - -#define __for_each_mem_range(i, type_a, type_b, p_start, p_end) \ - for ((i)->__idx = 0, \ - __next_memory_region(i, type_a, type_b, p_start, p_end); \ - (i)->__idx != ULLONG_MAX; \ - __next_memory_region(i, type_a, type_b, p_start, p_end)) - -/* iterate through all memory regions known to memblock. - - this consists of all regions that have been registered - with memblock using memblock_add(). - - this iteration can be optionally constrained to a given region. - - @param i the iterator. this should be a pointer of type struct memblock_iter. - for each iteration, this structure will be filled with details about - the current memory region. - @param p_start the lower bound of the memory region to iterate through. - if you don't want to use a lower bound, pass 0. - @param p_end the upper bound of the memory region to iterate through. - if you don't want to use an upper bound, pass UINTPTR_MAX. - - EXAMPLE: to iterate through all memory regions (with no bounds): - - struct memblock_iter it; - for_each_mem_region (&it, 0x0, UINTPTR_MAX) { ... } - - - EXAMPLE: to iterate through all memory regions between physical - addresses 0x40000 and 0x80000: - - struct memblock_iter it; - for_each_mem_region (&it, 0x40000, 0x80000) { ... } -*/ -#define for_each_mem_range(i, p_start, p_end) \ - __for_each_mem_range(i, &memblock.memory, NULL, p_start, p_end) - -/* iterate through all memory regions reserved using memblock. - - this consists of all regions that have been registered - with memblock using memblock_reserve(). - - this iteration can be optionally constrained to a given region. - - @param i the iterator. this should be a pointer of type struct memblock_iter. - for each iteration, this structure will be filled with details about - the current memory region. - @param p_start the lower bound of the memory region to iterate through. - if you don't want to use a lower bound, pass 0. - @param p_end the upper bound of the memory region to iterate through. - if you don't want to use an upper bound, pass UINTPTR_MAX. - - EXAMPLE: to iterate through all reserved memory regions (with no bounds): - - struct memblock_iter it; - for_each_reserved_mem_region (&it, 0x0, UINTPTR_MAX) { ... } - - - EXAMPLE: to iterate through all reserved memory regions between physical - addresses 0x40000 and 0x80000: - - struct memblock_iter it; - for_each_reserved_mem_region (&it, 0x40000, 0x80000) { ... } -*/ -#define for_each_reserved_mem_range(i, p_start, p_end) \ - __for_each_mem_range(i, &memblock.reserved, NULL, p_start, p_end) - -/* iterate through all memory regions known by memblock to be free. - - this consists of all regions BETWEEN those regions that have been - registered using memblock_reserve(), bounded within the memory - regions added using memblock_add(). - - this iteration can be optionally constrained to a given region. - - @param i the iterator. this should be a pointer of type struct memblock_iter. - for each iteration, this structure will be filled with details about - the current memory region. - @param p_start the lower bound of the memory region to iterate through. - if you don't want to use a lower bound, pass 0. - @param p_end the upper bound of the memory region to iterate through. - if you don't want to use an upper bound, pass UINTPTR_MAX. - - EXAMPLE: if you have added the following memory regions to - memblock using memblock_add(): - - - 0x00000 -> 0x05fff - - 0x08000 -> 0x1ffff - - ...and you have reserved the following memory regions using - memblock_reserve(): - - - 0x01000 -> 0x04fff - - 0x09000 -> 0x0ffff - - the following call: - - struct memblock_iter it; - for_each_free_mem_range (&it, 0x0, UINTPTR_MAX) { ... } - - would iterate through the following sequence of free memory ranges: - - - 0x00000 -> 0x00fff - - 0x05000 -> 0x05fff - - 0x08000 -> 0x08fff - - 0x10000 -> 0x1ffff -*/ -#define for_each_free_mem_range(i, p_start, p_end) \ - __for_each_mem_range( \ - i, \ - &memblock.memory, \ - &memblock.reserved, \ - p_start, \ - p_end) - -typedef uint64_t memblock_index_t; - -enum memblock_region_status { - /* Used in memblock.memory regions, indicates that the memory region - * exists */ - MEMBLOCK_MEMORY = 0, - /* Used in memblock.reserved regions, indicates that the memory region - * was reserved by a call to memblock_alloc() */ - MEMBLOCK_ALLOC, - /* Used in memblock.reserved regions, indicates that the memory region - * was reserved by a call to memblock_reserve() */ - MEMBLOCK_RESERVED, -}; - -struct memblock_region { - /* the status of the memory region (free, reserved, allocated, etc) */ - enum memblock_region_status status; - /* the address of the first byte that makes up the region */ - phys_addr_t base; - /* the address of the last byte that makes up the region */ - phys_addr_t limit; -}; - -/* buffer of memblock regions, all of which are the same type - (memory, reserved, etc) */ -struct memblock_type { - struct memblock_region *regions; - unsigned int count; - unsigned int max; - const char *name; -}; - -struct memblock { - /* bounds of the memory region that can be used by memblock_alloc() - both of these are virtual addresses */ - uintptr_t m_alloc_start, m_alloc_end; - /* memblock assumes that all memory in the alloc zone is contiguously - mapped (if paging is enabled). m_voffset is the offset that needs to - be added to a given physical address to get the corresponding virtual - address */ - uintptr_t m_voffset; - - struct memblock_type memory; - struct memblock_type reserved; -}; - -struct memblock_iter { - memblock_index_t __idx; - phys_addr_t it_base; - phys_addr_t it_limit; - enum memblock_region_status it_status; -}; - -/* global memblock state. */ -extern struct memblock memblock; - -extern int __next_mem_range(struct memblock_iter *it); - -/* initialise the global memblock state. - this function must be called before any other memblock functions can be used. - - this function sets the bounds of the heap area. memory allocation requests - using memblock_alloc() will be constrained to this zone. - - memblock assumes that all physical memory in the system is mapped to - an area in virtual memory, such that converting a physical address to - a valid virtual address can be done by simply applying an offset. - - @param alloc_start the virtual address of the start of the heap area. - @param alloc_end the virtual address of the end of the heap area. - @param voffset the offset between the physical address of a given page and - its corresponding virtual address. -*/ -extern int memblock_init( - uintptr_t alloc_start, - uintptr_t alloc_end, - uintptr_t voffset); - -/* add a region of memory to memblock. - - this function is used to define regions of memory that are accessible, but - says nothing about the STATE of the given memory. - - all memory is free by default. once a region of memory is added, - memblock_reserve() can be used to mark the memory as reserved. - - @param base the physical address of the start of the memory region to add. - @oaram size the size of the memory region to add in bytes. -*/ -extern int memblock_add(phys_addr_t base, size_t size); -/* mark a region of memory as reserved. - - this function can only operate on regions of memory that have been previously - registered with memblock using memblock_add(). - - reserved memory will not be used by memblock_alloc(), and will remain - reserved when the vm_page memory map is initialised. - - @param base the physical address of the start of the memory region to - reserve. - @oaram size the size of the memory region to reserve in bytes. -*/ -extern int memblock_reserve(phys_addr_t base, size_t size); - -/* allocate a block of memory, returning a virtual address. - - this function selects the first available region of memory that satisfies - the requested allocation size, marks `size` bytes of this region as reserved, - and returns the virtual address of the region. - - when looking for a suitable region of memory, this function searches the - intersection of the following memory zones: - - the regions of memory added with memblock_alloc(). - - the region of memory specified as the heap bounds during the call - to memblock_init(). - and excludes the following regions: - - the regions of memory marked as reserved by memblock_reserve() and - previous calls to memblock_alloc() - - @param size the size of the buffer to allocate in bytes. - @param align the alignment to use. for example, an alignment of 4096 - will result in the returned pointer being a multiple - of 4096. this must be a power of 2. -*/ -extern void *memblock_alloc(size_t size, phys_addr_t align); - -/* allocate a block of memory, returning a physical address. - - this function selects the first available region of memory that satisfies - the requested allocation size, marks `size` bytes of this region as reserved, - and returns the virtual address of the region. - - when looking for a suitable region of memory, this function searches the - intersection of the following memory zones: - - the regions of memory added with memblock_alloc(). - - the region of memory specified as the heap bounds during the call - to memblock_init(). - and excludes the following regions: - - the regions of memory marked as reserved by memblock_reserve() and - previous calls to memblock_alloc() - - @param size the size of the buffer to allocate in bytes. - @param align the alignment to use. for example, an alignment of 4096 - will result in the returned pointer being a multiple - of 4096. this must be a power of 2. -*/ -extern phys_addr_t memblock_alloc_phys(size_t size, phys_addr_t align); - -/* free a block of memory using its virtual address. - - due to limitations in memblock (as it is meant to be a simple, - early-boot allocator), you must specify the size of the memory - region you intend to free. - - @param addr the virtual address of the region to free. - @param size the size of the region to free in bytes. -*/ -extern int memblock_free(void *addr, size_t size); - -/* free a block of memory using its physical address. - - due to limitations in memblock (as it is meant to be a simple, - early-boot allocator), you must specify the size of the memory - region you intend to free. - - @param addr the physical address of the region to free. - @param size the size of the region to free in bytes. -*/ -extern int memblock_free_phys(phys_addr_t addr, size_t size); - -/* convert a virtual pointer returned by memblock - to a physical address. - - @param p the pointer to convert. -*/ -extern phys_addr_t memblock_virt_to_phys(const void *p); - -/* convert a physical address returned by memblock - to a virtual pointer. - - @param p the address to convert. -*/ -extern void *memblock_phys_to_virt(phys_addr_t p); - -extern void __next_memory_region( - struct memblock_iter *it, - struct memblock_type *type_a, - struct memblock_type *type_b, - phys_addr_t start, - phys_addr_t end); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/mango/object.h b/include/mango/object.h deleted file mode 100644 index cce6904..0000000 --- a/include/mango/object.h +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef MANGO_OBJECT_H_ -#define MANGO_OBJECT_H_ - -#include -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define DEFINE_OBJECT_LOCK_FUNCTION(object_name, base) \ - static inline void object_name##_lock(struct object_name *p) \ - { \ - object_lock(&p->base); \ - } \ - static inline void object_name##_unlock(struct object_name *p) \ - { \ - object_unlock(&p->base); \ - } \ - static inline void object_name##_lock_irqsave( \ - struct object_name *p, \ - unsigned long *flags) \ - { \ - object_lock_irqsave(&p->base, flags); \ - } \ - static inline void object_name##_unlock_irqrestore( \ - struct object_name *p, \ - unsigned long flags) \ - { \ - object_unlock_irqrestore(&p->base, flags); \ - } - -#define OBJECT_MAGIC 0xBADDCAFE -#define OBJECT_NAME_MAX 64 -#define OBJECT_PATH_MAX 256 - -#define OBJECT_CAST(to_type, to_type_member, p) \ - ((to_type *)((uintptr_t)p) - offsetof(to_type, to_type_member)) -#define OBJECT_C_CAST(c_type, c_type_member, obj_type, objp) \ - OBJECT_IS_TYPE(objp, obj_type) \ - ? OBJECT_CAST(c_type, c_type_member, (objp)) : NULL -#define OBJECT_IS_TYPE(obj, type_ptr) ((obj)->ob_type == (type_ptr)) - -struct object; -struct object_attrib; - -enum object_type_flags { - OBJTYPE_INIT = 0x01u, -}; - -struct object_ops { - kern_status_t (*destroy)(struct object *obj); -}; - -struct object_type { - enum object_type_flags ob_flags; - char ob_name[32]; - unsigned int ob_size; - unsigned int ob_header_offset; - struct vm_cache ob_cache; - struct queue_entry ob_list; - struct object_ops ob_ops; -}; - -struct object { - uint32_t ob_magic; - struct object_type *ob_type; - spin_lock_t ob_lock; - unsigned int ob_refcount; - unsigned int ob_handles; - struct queue_entry ob_list; -} __aligned(sizeof(long)); - -extern kern_status_t object_bootstrap(void); -extern kern_status_t object_type_register(struct object_type *p); -extern kern_status_t object_type_unregister(struct object_type *p); - -extern struct object *object_create(struct object_type *type); -extern struct object *object_ref(struct object *obj); -extern void object_unref(struct object *obj); -extern void object_add_handle(struct object *obj); -extern void object_remove_handle(struct object *obj); -extern void object_lock(struct object *obj); -extern void object_unlock(struct object *obj); -extern void object_lock_irqsave(struct object *obj, unsigned long *flags); -extern void object_unlock_irqrestore(struct object *obj, unsigned long flags); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/mango/panic.h b/include/mango/panic.h deleted file mode 100644 index cfce017..0000000 --- a/include/mango/panic.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef MANGO_PANIC_H_ -#define MANGO_PANIC_H_ - -#include - -struct ml_cpu_context; - -#define panic(...) panic_irq(NULL, __VA_ARGS__) - -extern void __noreturn -panic_irq(struct ml_cpu_context *ctx, const char *fmt, ...); - -#endif diff --git a/include/mango/percpu.h b/include/mango/percpu.h deleted file mode 100644 index 04dd3de..0000000 --- a/include/mango/percpu.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef MANGO_PERCPU_H_ -#define MANGO_PERCPU_H_ - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define DEFINE_PERCPU_VAR(type, name) \ - __section(".data.percpu") type name - -#define percpu_get(var) \ - __extension__({ \ - preempt_disable(); \ - __percpu_get(this_cpu(), var); \ - }) - -#define percpu_get_from(cpu, var) \ - __extension__({ \ - preempt_disable(); \ - __percpu_get(cpu, var); \ - }) - -#define percpu_put(var) preempt_enable(); - -extern kern_status_t init_per_cpu_areas(void); -extern void *__percpu_get(unsigned int cpu, void *var); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/mango/pmap.h b/include/mango/pmap.h deleted file mode 100644 index 4ba2836..0000000 --- a/include/mango/pmap.h +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef MANGO_PMAP_H_ -#define MANGO_PMAP_H_ - -/* all the functions declared in this file are defined in arch/xyz/pmap.c */ - -#include -#include -#include -#include - -#define PMAP_INVALID ML_PMAP_INVALID -#define PFN(x) ((x) >> VM_PAGE_SHIFT) - -#ifdef __cplusplus -extern "C" { -#endif - -typedef ml_pmap_t pmap_t; -typedef ml_pfn_t pfn_t; - -enum pmap_fault_flags { - /* if set, the faulting page is present, and the fault is - * protection-related. - * if clear, the faulting page is missing, and the - * fault is due to the missing page. - */ - PMAP_FAULT_PRESENT = 0x01u, - /* if set, the faulting page was accessed from user mode. - * if clear, the faulting page was accessed from kernel mode. - */ - PMAP_FAULT_USER = 0x02u, - /* if set, the fault was caused by a write operation. - * if clear, the faulting page was caused by a read operation. - */ - PMAP_FAULT_WRITE = 0x04u, - /* if set, the fault was caused while fetching an instruction from the - * faulting page. - */ - PMAP_FAULT_IFETCH = 0x08u, - /* if set, the fault was caused by misconfigured page tables */ - PMAP_FAULT_BADCFG = 0x10u, -}; - -enum pmap_flags { - PMAP_NORMAL = 0x00u, - PMAP_HUGEPAGE = 0x01u, -}; - -extern void pmap_bootstrap(void); -extern pmap_t get_kernel_pmap(void); - -extern pmap_t pmap_create(void); -extern void pmap_destroy(pmap_t pmap); -extern void pmap_switch(pmap_t pmap); - -extern kern_status_t pmap_handle_fault( - virt_addr_t fault_addr, - enum pmap_fault_flags flags); - -extern kern_status_t pmap_add( - pmap_t pmap, - virt_addr_t p, - pfn_t pfn, - enum vm_prot prot, - enum pmap_flags flags); -extern kern_status_t pmap_add_block( - pmap_t pmap, - virt_addr_t p, - pfn_t pfn, - size_t len, - enum vm_prot prot, - enum pmap_flags flags); - -extern kern_status_t pmap_remove(pmap_t pmap, void *p); -extern kern_status_t pmap_remove_range(pmap_t pmap, void *p, size_t len); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/mango/printk.h b/include/mango/printk.h deleted file mode 100644 index 7fe654f..0000000 --- a/include/mango/printk.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef MANGO_PRINTK_H_ -#define MANGO_PRINTK_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef TRACE -#define tracek(...) printk(__VA_ARGS__) -#else -#define tracek(...) -#endif - -extern void early_printk_init(struct console *con); -extern int printk(const char *format, ...); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/mango/queue.h b/include/mango/queue.h deleted file mode 100644 index a78718c..0000000 --- a/include/mango/queue.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef MANGO_QUEUE_H_ -#define MANGO_QUEUE_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define QUEUE_CONTAINER(t, m, v) ((void *)((v) ? (uintptr_t)(v) - (offsetof(t, m)) : 0)) - -#define QUEUE_INIT ((struct queue){ .q_first = NULL, .q_last = NULL }) -#define QUEUE_ENTRY_INIT ((struct queue_entry){ .qe_next = NULL, .qe_prev = NULL }) - -#define queue_foreach(iter_type, iter_name, queue_name, node_member) \ - for (iter_type *iter_name = (iter_type *)QUEUE_CONTAINER(iter_type, node_member, queue_first(queue_name)); \ - iter_name; \ - iter_name = (iter_type *)QUEUE_CONTAINER(iter_type, node_member, queue_next(&((iter_name)->node_member)))) - -#define queue_foreach_r(iter_type, iter_name, queue_name, node_member) \ - for (iter_type *iter_name = (iter_type *)QUEUE_CONTAINER(iter_type, node_member, queue_last(queue_name)); \ - iter_name; \ - iter_name = (iter_type *)QUEUE_CONTAINER(iter_type, node_member, queue_prev(&((iter_name)->node_member)))) - -struct queue_entry { - struct queue_entry *qe_next; - struct queue_entry *qe_prev; -}; - -struct queue { - struct queue_entry *q_first; - struct queue_entry *q_last; -}; - -static inline void queue_init(struct queue *q) { memset(q, 0x00, sizeof *q); } -static inline bool queue_empty(struct queue *q) { return q->q_first == NULL; } - -static inline struct queue_entry *queue_first(struct queue *q) { return q->q_first; } -static inline struct queue_entry *queue_last(struct queue *q) { return q->q_last; } -static inline struct queue_entry *queue_next(struct queue_entry *entry) { return entry->qe_next; } -static inline struct queue_entry *queue_prev(struct queue_entry *entry) { return entry->qe_prev; } - -extern size_t queue_length(struct queue *q); - -extern void queue_insert_before(struct queue *q, struct queue_entry *entry, struct queue_entry *before); -extern void queue_insert_after(struct queue *q, struct queue_entry *entry, struct queue_entry *after); - -extern void queue_push_front(struct queue *q, struct queue_entry *entry); -extern void queue_push_back(struct queue *q, struct queue_entry *entry); - -extern struct queue_entry *queue_pop_front(struct queue *q); -extern struct queue_entry *queue_pop_back(struct queue *q); - -extern void queue_delete(struct queue *q, struct queue_entry *entry); -extern void queue_delete_all(struct queue *q); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/mango/ringbuffer.h b/include/mango/ringbuffer.h deleted file mode 100644 index 624da7c..0000000 --- a/include/mango/ringbuffer.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef MANGO_RINGBUFFER_H_ -#define MANGO_RINGBUFFER_H_ - -#include -#include - -struct ringbuffer { - unsigned char *r_buffer; - size_t r_write_ptr; - size_t r_read_ptr; - size_t r_size; - spin_lock_t r_lock; - struct waitqueue r_wait_readers; - struct waitqueue r_wait_writers; -}; - -extern struct ringbuffer *ringbuffer_create(size_t size); -extern void ringbuffer_destroy(struct ringbuffer *buf); - -extern kern_status_t ringbuffer_init(struct ringbuffer *buf, size_t size); -extern kern_status_t ringbuffer_deinit(struct ringbuffer *buf); - -extern size_t ringbuffer_unread(struct ringbuffer *buf); -extern size_t ringbuffer_avail(struct ringbuffer *buf); -extern size_t ringbuffer_read(struct ringbuffer *buf, size_t size, void *buffer, mango_flags_t flags); -extern size_t ringbuffer_write(struct ringbuffer *buf, size_t size, const void *buffer, mango_flags_t flags); - -/* TODO */ -//extern size_t ringbuffer_peek(struct ringbuffer *buf, size_t at, size_t size, void *buffer); -//extern size_t ringbuffer_skip(struct ringbuffer *buf, size_t count); - -extern int ringbuffer_write_would_block(struct ringbuffer *buf); - -#endif diff --git a/include/mango/sched.h b/include/mango/sched.h deleted file mode 100644 index f9bb6f1..0000000 --- a/include/mango/sched.h +++ /dev/null @@ -1,250 +0,0 @@ -#ifndef MANGO_SCHED_H_ -#define MANGO_SCHED_H_ - -#include -#include -#include -#include -#include -#include - -#define TASK_NAME_MAX 64 -#define PRIO_MAX 32 -#define PID_MAX 99999 -#define THREAD_KSTACK_ORDER VM_PAGE_4K -#define THREAD_MAX 65536 - -#define wait_event(wq, cond) \ - ({ \ - struct thread *self = current_thread(); \ - struct wait_item waiter; \ - wait_item_init(&waiter, self); \ - for (;;) { \ - thread_wait_begin(&waiter, wq); \ - if (cond) { \ - break; \ - } \ - schedule(SCHED_NORMAL); \ - } \ - thread_wait_end(&waiter, wq); \ - }) - -#ifdef __cplusplus -extern "C" { -#endif - -struct runqueue; -struct work_item; - -enum task_state { - TASK_RUNNING, - TASK_STOPPED, -}; - -enum thread_state { - THREAD_READY = 1, - THREAD_SLEEPING = 2, - THREAD_STOPPED = 3, -}; - -enum thread_flags { - THREAD_F_NEED_RESCHED = 0x01u, - THREAD_F_NO_PREEMPT = 0x02u, -}; - -enum sched_priority { - PRIO_IDLE = 4, - PRIO_SUBNORMAL = 6, - PRIO_NORMAL = 10, - PRIO_SUPERNORMAL = 14, - PRIO_HIGH = 18, - PRIO_REALTIME = 24, -}; - -enum sched_mode { - /* used when calling from non-interrupt context. - threads that aren't in state THREAD_READY are - removed from the runqueue. */ - SCHED_NORMAL = 0, - /* used when calling from interrupt context. - threads that aren't in state THREAD_READY are - still added to the runqueue. */ - SCHED_IRQ = 1, -}; - -struct task { - struct object t_base; - - struct task *t_parent; - long t_id; - enum task_state t_state; - char t_name[TASK_NAME_MAX]; - - pmap_t t_pmap; - struct vm_region *t_address_space; - struct handle_table *t_handles; - - struct btree_node t_tasklist; - struct queue_entry t_child_entry; - - size_t t_next_thread_id; - struct queue t_threads; - struct queue t_children; -}; - -struct thread { - struct object thr_base; - - enum thread_state tr_state; - enum thread_flags tr_flags; - struct task *tr_parent; - - unsigned int tr_id; - unsigned int tr_prio; - - cycles_t tr_charge_period_start; - cycles_t tr_quantum_cycles, tr_quantum_target; - cycles_t tr_total_cycles; - - virt_addr_t tr_ip, tr_sp, tr_bp; - virt_addr_t tr_cpu_user_sp, tr_cpu_kernel_sp; - - struct runqueue *tr_rq; - - struct queue_entry tr_parent_entry; - struct queue_entry tr_rqentry; - - struct vm_page *tr_kstack; - struct vm_object *tr_ustack; -}; - -struct runqueue { - struct queue rq_queues[PRIO_MAX]; - uint32_t rq_readybits; - spin_lock_t rq_lock; - unsigned int rq_nthreads; - - struct thread *rq_cur, *rq_idle; -}; - -struct timer { - struct queue_entry t_entry; - struct cpu_data *t_cpu; - struct thread *t_owner; - unsigned long t_expiry; - void (*t_callback)(struct timer *); -}; - -struct wait_item { - struct thread *w_thread; - struct queue_entry w_entry; -}; - -struct waitqueue { - struct queue wq_waiters; - spin_lock_t wq_lock; -}; - -typedef void (*work_func_t)(struct work_item *); - -struct work_item { - void *w_data; - work_func_t w_func; - struct queue_entry w_head; -}; - -struct worker_pool { - struct thread **wp_workers; - size_t wp_nworkers; -}; - -struct workqueue { - spin_lock_t wq_lock; - struct queue wq_queue; /* list of struct work_item */ -}; - -extern kern_status_t sched_init(void); -extern void schedule(enum sched_mode mode); -extern void preempt_disable(void); -extern void preempt_enable(void); - -extern void rq_init(struct runqueue *rq); -extern struct thread *rq_dequeue(struct runqueue *rq); -extern void rq_enqueue(struct runqueue *rq, struct thread *thr); -static inline void rq_lock(struct runqueue *rq, unsigned long *flags) -{ - spin_lock_irqsave(&rq->rq_lock, flags); -} -static inline void rq_unlock(struct runqueue *rq, unsigned long flags) -{ - spin_unlock_irqrestore(&rq->rq_lock, flags); -} -extern void rq_remove_thread(struct runqueue *rq, struct thread *thr); -extern struct runqueue *cpu_rq(unsigned int cpu); - -extern struct task *task_alloc(void); -extern struct task *task_create(struct task *parent, const char *name); -static inline struct task *task_ref(struct task *task) -{ - return OBJECT_CAST(struct task, t_base, object_ref(&task->t_base)); -} -static inline void task_unref(struct task *task) -{ - object_unref(&task->t_base); -} -extern struct task *task_from_pid(unsigned int pid); -extern struct thread *task_create_thread(struct task *parent); -extern struct task *kernel_task(void); -extern struct task *idle_task(void); -extern cycles_t default_quantum(void); - -extern bool need_resched(void); -extern struct task *current_task(void); -extern struct thread *current_thread(void); - -extern struct runqueue *select_rq_for_thread(struct thread *thr); -extern void schedule_thread_on_cpu(struct thread *thr); - -extern void start_charge_period(void); -extern void end_charge_period(void); - -DEFINE_OBJECT_LOCK_FUNCTION(task, t_base) - -extern struct thread *thread_alloc(void); -extern kern_status_t thread_init_kernel(struct thread *thr, virt_addr_t ip); -extern kern_status_t thread_init_user( - struct thread *thr, - virt_addr_t ip, - virt_addr_t sp); -extern int thread_priority(struct thread *thr); -extern void idle(void); -extern struct thread *create_kernel_thread(void (*fn)(void)); -extern struct thread *create_idle_thread(void); - -extern void add_timer(struct timer *timer); -extern void remove_timer(struct timer *timer); -extern unsigned long schedule_timeout(unsigned long clock_ticks); -extern unsigned long milli_sleep(unsigned long ms); -extern void sleep_forever(void); - -extern void wait_item_init(struct wait_item *item, struct thread *thr); -extern void thread_wait_begin(struct wait_item *waiter, struct waitqueue *q); -extern void thread_wait_end(struct wait_item *waiter, struct waitqueue *q); -extern void wait_on_queue(struct waitqueue *q); -extern void wakeup_queue(struct waitqueue *q); -extern void wakeup_one(struct waitqueue *q); - -extern void work_item_init(work_func_t func, void *data, struct work_item *out); -extern void workqueue_init(struct workqueue *wq); -extern struct worker_pool *worker_pool_create(size_t nworkers); -extern struct worker_pool *global_worker_pool(void); -extern bool schedule_work_on(struct workqueue *wq, struct work_item *work); -extern bool schedule_work(struct work_item *work); - -extern void wake_workers(struct workqueue *wq, struct worker_pool *pool); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/mango/syscall.h b/include/mango/syscall.h deleted file mode 100644 index 1dadb0c..0000000 --- a/include/mango/syscall.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef MANGO_SYSCALL_H_ -#define MANGO_SYSCALL_H_ - -#include -#include -#include - -#define SYS_EXIT 1 -#define SYS_VM_OBJECT_CREATE 2 - -extern kern_status_t sys_exit(int status); -extern kern_status_t sys_vm_object_create( - const char *name, - size_t len, - enum vm_prot prot, - kern_handle_t *out_handle); - -extern virt_addr_t syscall_get_function(unsigned int sysid); - -#endif diff --git a/include/mango/test.h b/include/mango/test.h deleted file mode 100644 index 5271e98..0000000 --- a/include/mango/test.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef MANGO_TEST_H_ -#define MANGO_TEST_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -extern int run_all_tests(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/mango/types.h b/include/mango/types.h deleted file mode 100644 index 54f143e..0000000 --- a/include/mango/types.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef MANGO_TYPES_H_ -#define MANGO_TYPES_H_ - -#include -#include - -#define CYCLES_MAX UINT64_MAX - -typedef uintptr_t phys_addr_t; -typedef uintptr_t virt_addr_t; -typedef uint64_t cycles_t; -typedef uint64_t sectors_t; -typedef uint64_t off_t; - -typedef unsigned int umode_t; - -struct boot_module { - phys_addr_t mod_base; - size_t mod_size; -}; - -#endif diff --git a/include/mango/util.h b/include/mango/util.h deleted file mode 100644 index c2b550e..0000000 --- a/include/mango/util.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef MANGO_UTIL_H_ -#define MANGO_UTIL_H_ - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define MIN(x, y) ((x) < (y) ? (x) : (y)) -#define MAX(x, y) ((x) > (y) ? (x) : (y)) -#define CLAMP(x, lo, hi) (MIN(MAX(x, lo), hi)) - -extern uint64_t hash_string(const char *s); -extern void data_size_to_string(size_t value, char *out, size_t outsz); -static inline bool power_of_2(size_t x) -{ - return (x > 0 && (x & (x - 1)) == 0); -} -static inline unsigned long long div64_pow2( - unsigned long long x, - unsigned long long y) -{ - return x >> (__builtin_ctz(y)); -} - -static inline unsigned long long absdiff64( - unsigned long long x, - unsigned long long y) -{ - return x < y ? y - x : x - y; -} - -extern int16_t host_to_big_i16(int16_t v); -extern int16_t host_to_little_i16(int16_t v); -extern int16_t big_to_host_i16(int16_t v); -extern int16_t little_to_host_i16(int16_t v); -extern uint16_t host_to_big_u16(uint16_t v); -extern uint16_t host_to_little_u16(uint16_t v); -extern uint16_t big_to_host_u16(uint16_t v); -extern uint16_t little_to_host_u16(uint16_t v); - -extern int32_t host_to_big_i32(int32_t v); -extern int32_t host_to_little_i32(int32_t v); -extern int32_t big_to_host_i32(int32_t v); -extern int32_t little_to_host_i32(int32_t v); -extern uint32_t host_to_big_u32(uint32_t v); -extern uint32_t host_to_little_u32(uint32_t v); -extern uint32_t big_to_host_u32(uint32_t v); -extern uint32_t little_to_host_u32(uint32_t v); - -extern int64_t host_to_big_i64(int64_t v); -extern int64_t host_to_little_i64(int64_t v); -extern int64_t big_to_host_i64(int64_t v); -extern int64_t little_to_host_i64(int64_t v); -extern uint64_t host_to_big_u64(uint64_t v); -extern uint64_t host_to_little_u64(uint64_t v); -extern uint64_t big_to_host_u64(uint64_t v); -extern uint64_t little_to_host_u64(uint64_t v); - -extern bool fill_random(void *buffer, unsigned int size); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/mango/vm-object.h b/include/mango/vm-object.h deleted file mode 100644 index 77e553b..0000000 --- a/include/mango/vm-object.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef MANGO_VM_OBJECT_H_ -#define MANGO_VM_OBJECT_H_ - -#include -#include - -#define VM_OBJECT_NAME_MAX 64 - -enum vm_object_flags { - /* the memory behind this vm-object wasn't allocated by us, and - * therefore shouldn't be freed by us */ - VMO_IN_PLACE = 0x01u, -}; - -struct vm_object { - struct object vo_base; - - char vo_name[VM_OBJECT_NAME_MAX]; - enum vm_object_flags vo_flags; - - /* queue of struct vm_region_mapping */ - struct queue vo_mappings; - - /* memory protection flags. mappings of this vm_object can only use - * a subset of the flags set in this mask. */ - enum vm_prot vo_prot; - - /* btree of vm_pages that have been allocated to this vm_object. - * vm_page->p_vmo_offset and the size of each page is the bst key. */ - struct btree vo_pages; - /* total length of the vm_object in bytes. */ - size_t vo_size; -}; - -extern kern_status_t vm_object_type_init(void); - -/* create a vm_object with the specified length in bytes and protection flags. - * the length will be automatically rounded up to the nearest vm_object page - * order size. the actual page frames themselves won't be allocated until - * they are mapped and accessed. */ -extern struct vm_object *vm_object_create( - const char *name, - size_t len, - enum vm_prot prot); - -/* create a vm_object that represents the specified range of physical memory. - * the length will be automatically rounded up to the nearest vm_object page - * order size. - * NOTE this function assumes that the physical memory has already been - * reserved, and is not in use by any other kernel component. */ -extern struct vm_object *vm_object_create_in_place( - const char *name, - phys_addr_t base, - size_t len, - enum vm_prot prot); - -extern struct vm_page *vm_object_get_page( - const struct vm_object *vo, - off_t offset); - -extern struct vm_page *vm_object_alloc_page( - struct vm_object *vo, - off_t offset, - enum vm_page_order size); - -DEFINE_OBJECT_LOCK_FUNCTION(vm_object, vo_base) - -#endif diff --git a/include/mango/vm-region.h b/include/mango/vm-region.h deleted file mode 100644 index c609b6a..0000000 --- a/include/mango/vm-region.h +++ /dev/null @@ -1,115 +0,0 @@ -#ifndef MANGO_VM_REGION_H_ -#define MANGO_VM_REGION_H_ - -#include -#include -#include - -#define VM_REGION_NAME_MAX 64 - -#define VM_REGION_ANY_OFFSET ((off_t) - 1) - -struct vm_region; -struct vm_object; - -enum vm_region_entry_type { - VM_REGION_ENTRY_NONE = 0, - VM_REGION_ENTRY_REGION, - VM_REGION_ENTRY_MAPPING, -}; - -struct vm_region_entry { - struct btree_node e_node; - struct vm_region_entry *e_parent; - enum vm_region_entry_type e_type; - /* offset in bytes of this entry within its immediate parent. */ - off_t e_offset; - /* size of the entry in bytes */ - size_t e_size; -}; - -struct vm_region_mapping { - struct vm_region_entry m_entry; - struct vm_object *m_object; - - /* used to link to vm_object->vo_mappings */ - struct queue_entry m_object_entry; - - enum vm_prot m_prot; - /* offset in bytes to the start of the object data that was mapped */ - off_t m_object_offset; -}; - -struct vm_region { - struct object vr_base; - struct vm_region_entry vr_entry; - - char vr_name[VM_REGION_NAME_MAX]; - - /* btree of struct vm_region_entry. - * sibling entries cannot overlap each other, and child entries must - * be entirely contained within their immediate parent entry. */ - struct btree vr_entries; - - /* memory protection restriction mask. - * any mapping in this region, or any of its children, cannot use - * protection flags that are not set in this mask. - * for example, if VM_PROT_EXEC is /not/ set here, no mapping - * can be created in this region or any child region with VM_PROT_EXEC - * set. */ - enum vm_prot vr_prot; - - /* the physical address space in which mappings in this region (and - * its children) are created */ - pmap_t vr_pmap; -}; - -extern kern_status_t vm_region_type_init(void); - -/* create a new vm-region, optionally within a parent region. - * `offset` is the byte offset within the parent region where the new region - * should start. - * if no parent is specified, `offset` is the absolute virtual address of the - * start of the region. - * in both cases, `len` is the length of the new region in bytes. */ -extern kern_status_t vm_region_create( - struct vm_region *parent, - const char *name, - off_t offset, - size_t len, - enum vm_prot prot, - struct vm_region **out); - -/* map a vm-object into a vm-region. - * [region_offset,length] must fall within exactly one region, and cannot span - * multiple sibling regions. - * if [region_offset,length] falls within a child region, the map operation - * will be transparently redirected to the relevant region. - * `prot` must be allowed both by the region into which the mapping is being - * created AND the vm-object being mapped. */ -extern kern_status_t vm_region_map_object( - struct vm_region *region, - off_t region_offset, - struct vm_object *object, - off_t object_offset, - size_t length, - enum vm_prot prot, - virt_addr_t *out); - -/* find the mapping corresponding to the given virtual address, and page-in the - * necessary vm_page to allow the memory access to succeed. if the relevant - * vm-object page hasn't been allocated yet, it will be allocated here. */ -extern kern_status_t vm_region_demand_map( - struct vm_region *region, - virt_addr_t addr, - enum pmap_fault_flags flags); - -/* get the absolute base virtual address of a region within its - * parent/ancestors. */ -extern virt_addr_t vm_region_get_base_address(const struct vm_region *region); - -extern void vm_region_dump(struct vm_region *region, int depth); - -DEFINE_OBJECT_LOCK_FUNCTION(vm_region, vr_base) - -#endif diff --git a/include/mango/vm.h b/include/mango/vm.h deleted file mode 100644 index 9e8e697..0000000 --- a/include/mango/vm.h +++ /dev/null @@ -1,367 +0,0 @@ -#ifndef MANGO_VM_H_ -#define MANGO_VM_H_ - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct bcache; - -/* maximum number of NUMA nodes */ -#define VM_MAX_NODES 64 -/* maximum number of memory zones per node */ -#define VM_MAX_ZONES (VM_ZONE_MAX + 1) -/* maximum number of supported page orders */ -#define VM_MAX_PAGE_ORDERS (VM_PAGE_MAX_ORDER + 1) -/* maximum number of sparse memory sectors */ -#define VM_MAX_SECTORS 8192 - -/* maximum number of disk sectors that can be stored in a single - page. AKA the number of bits in the sector bitmap. - used by the block cache */ -#define VM_MAX_SECTORS_PER_PAGE 32 - -#define VM_CHECK_ALIGN(p, mask) ((((p) & (mask)) == (p)) ? 1 : 0) - -#define VM_CACHE_INITIALISED(c) ((c)->c_obj_count != 0) -#define VM_PAGE_IS_FREE(pg) \ - (((pg)->p_flags & (VM_PAGE_RESERVED | VM_PAGE_ALLOC)) == 0) - -#define vm_page_foreach(pg, i) \ - for (struct vm_page *i = (pg); i; i = vm_page_get_next_tail(i)) - -typedef phys_addr_t vm_alignment_t; -typedef unsigned int vm_node_id_t; - -enum vm_model { - VM_MODEL_FLAT = 1, - VM_MODEL_SPARSE, -}; - -enum vm_prot { - VM_PROT_READ = 0x01u, - VM_PROT_WRITE = 0x02u, - VM_PROT_EXEC = 0x04u, - VM_PROT_USER = 0x08u, - VM_PROT_SVR = 0x10u, - VM_PROT_NOCACHE = 0x20u, -}; - -enum vm_flags { - VM_NORMAL = 0x00u, - VM_GET_DMA = 0x01u, -}; - -enum vm_zone_id { - /* NOTE that these are used as indices into the node_zones array in - vm/zone.c they need to be continuous, and must start at 0! - - not all of these zones are implemented for every architecture. */ - VM_ZONE_DMA = 0u, - VM_ZONE_NORMAL = 1u, - VM_ZONE_HIGHMEM = 2u, -}; - -enum vm_page_order { - VM_PAGE_4K = 0u, - VM_PAGE_8K, - VM_PAGE_16K, - VM_PAGE_32K, - VM_PAGE_64K, - VM_PAGE_128K, - VM_PAGE_256K, - VM_PAGE_512K, - VM_PAGE_1M, - VM_PAGE_2M, - VM_PAGE_4M, - VM_PAGE_8M, - VM_PAGE_16M, - VM_PAGE_32M, - VM_PAGE_64M, - VM_PAGE_128M, - - /* struct vm_page only has 4 bits to store the page order with. - the maximum order that can be stored in 4 bits is 15 (VM_PAGE_128M) - to use any of the page orders listed here, this field - will have to be expanded. */ - VM_PAGE_256M, - VM_PAGE_512M, - VM_PAGE_1G, - VM_PAGE_2G, - VM_PAGE_4G, - VM_PAGE_8G, - VM_PAGE_16G, - VM_PAGE_32G, - VM_PAGE_64G, -}; - -enum vm_page_flags { - /* page is reserved (probably by a call to memblock_reserve()) and - cannot be returned by any allocation function */ - VM_PAGE_RESERVED = 0x01u, - /* page has been allocated by a zone's buddy allocator, and is in-use */ - VM_PAGE_ALLOC = 0x02u, - /* page is the first page of a huge-page */ - VM_PAGE_HEAD = 0x04u, - /* page is part of a huge-page */ - VM_PAGE_HUGE = 0x08u, - /* page is holding cached data from secondary storage, and can be freed - * if necessary (and not dirty). */ - VM_PAGE_CACHE = 0x10u, -}; - -enum vm_memory_region_status { - VM_REGION_FREE = 0x01u, - VM_REGION_RESERVED = 0x02u, -}; - -enum vm_cache_flags { - VM_CACHE_OFFSLAB = 0x01u, - VM_CACHE_DMA = 0x02u -}; - -struct vm_zone_descriptor { - enum vm_zone_id zd_id; - vm_node_id_t zd_node; - const char zd_name[32]; - phys_addr_t zd_base; - phys_addr_t zd_limit; -}; - -struct vm_zone { - struct vm_zone_descriptor z_info; - spin_lock_t z_lock; - - struct queue z_free_pages[VM_MAX_PAGE_ORDERS]; - unsigned long z_size; -}; - -struct vm_pg_data { - struct vm_zone pg_zones[VM_MAX_ZONES]; -}; - -struct vm_cache { - const char *c_name; - enum vm_cache_flags c_flags; - struct queue_entry c_list; - - struct queue c_slabs_full; - struct queue c_slabs_partial; - struct queue c_slabs_empty; - - spin_lock_t c_lock; - - /* number of objects that can be stored in a single slab */ - unsigned int c_obj_count; - /* the size of object kept in the cache */ - unsigned int c_obj_size; - /* combined size of struct vm_slab and the freelist */ - unsigned int c_hdr_size; - /* power of 2 alignment for objects returned from the cache */ - unsigned int c_align; - /* offset from one object to the next in a slab. - this may be different from c_obj_size depending - on the alignment settings for this cache. */ - unsigned int c_stride; - /* size of page used for slabs */ - unsigned int c_page_order; -}; - -struct vm_slab { - struct vm_cache *s_cache; - /* queue entry for struct vm_cache.c_slabs_* */ - struct queue_entry s_list; - /* pointer to the first object slot. */ - void *s_objects; - /* the number of objects allocated on the slab. */ - unsigned int s_obj_allocated; - /* the index of the next free object. - if s_free is equal to FREELIST_END (defined in vm/cache.c) - there are no free slots left in the slab. */ - unsigned int s_free; - /* list of free object slots. - when allocating: - - s_free should be set to the value of s_freelist[s_free] - when freeing: - - s_free should be set to the index of the object being freed. - - s_freelist[s_free] should be set to the previous value of s_free. - this is commented as it as flexible arrays are not supported in c++. - */ - // unsigned int s_freelist[]; -}; - -struct vm_page { - /* order of the page block that this page belongs too */ - uint32_t p_order : 4; - /* the id of the NUMA node that this page belongs to */ - uint32_t p_node : 6; - /* the id of the memory zone that this page belongs to */ - uint32_t p_zone : 3; - /* vm_page_flags_t bitfields. */ - uint32_t p_sector : 11; - /* some unused bits */ - uint32_t p_reserved : 8; - - uint32_t p_flags; - - /* owner-specific pointer */ - union { - struct vm_slab *p_slab; - struct bcache *p_bcache; - void *p_priv0; - }; - - /* multi-purpose list/tree entry. - the owner of the page can decide what to do with this. - some examples: - - the buddy allocator uses this to maintain its per-zone free-page - lists. - - vm_object uses it to maintain a btree of allocated pages keyed - by offset/size. - - the block cache uses this to maintain a tree of pages keyed by - block number. - */ - union { - struct queue_entry p_list; - struct btree_node p_bnode; - - /* btree_node contains three pointers, so provide three - pointer-sized integers for use if p_bnode isn't needed. */ - uintptr_t priv1[3]; - }; - - union { - /* used by bcache when sector size is < page size. bitmap of - * present/missing sectors */ - DECLARE_BITMAP(p_blockbits, VM_MAX_SECTORS_PER_PAGE); - uint32_t p_priv2; - }; - - union { - /* sector address, used by bcache */ - sectors_t p_blockid; - /* offset of this page within the vm_object it is a part of */ - off_t p_vmo_offset; - - uint32_t p_priv3[2]; - }; -} __aligned(2 * sizeof(unsigned long)); - -/* represents a sector of memory, containing its own array of vm_pages. - this struct is used under the sparse memory model, instead of the - global vm_page array */ -struct vm_sector { - /* sector size. this must be a power of 2. - all sectors in the system have the same size. */ - enum vm_page_order s_size; - /* PFN of the first page contained in s_pages. - to find the PFN of any page contained within s_pages, - simply add its offset within the array to s_first_pfn */ - size_t s_first_pfn; - /* array of pages contained in this sector */ - struct vm_page *s_pages; -}; - -extern kern_status_t vm_bootstrap( - const struct vm_zone_descriptor *zones, - size_t nr_zones); -extern enum vm_model vm_memory_model(void); -extern void vm_set_memory_model(enum vm_model model); - -extern struct vm_pg_data *vm_pg_data_get(vm_node_id_t node); - -extern phys_addr_t vm_virt_to_phys(const void *p); -extern void *vm_phys_to_virt(phys_addr_t p); - -extern size_t vm_page_order_to_bytes(enum vm_page_order order); -extern size_t vm_page_order_to_pages(enum vm_page_order order); -extern vm_alignment_t vm_page_order_to_alignment(enum vm_page_order order); -extern void vm_page_init_array(void); -extern struct vm_page *vm_page_get(phys_addr_t addr); -extern phys_addr_t vm_page_get_paddr(struct vm_page *pg); -extern struct vm_zone *vm_page_get_zone(struct vm_page *pg); -extern void *vm_page_get_vaddr(struct vm_page *pg); -extern size_t vm_page_get_pfn(struct vm_page *pg); -static inline size_t vm_page_get_size_bytes(const struct vm_page *pg) -{ - return vm_page_order_to_bytes(pg->p_order); -} -extern struct vm_page *vm_page_alloc( - enum vm_page_order order, - enum vm_flags flags); -extern void vm_page_free(struct vm_page *pg); - -extern int vm_page_split( - struct vm_page *pg, - struct vm_page **a, - struct vm_page **b); -extern struct vm_page *vm_page_merge(struct vm_page *a, struct vm_page *b); -extern struct vm_page *vm_page_get_buddy(struct vm_page *pg); -extern struct vm_page *vm_page_get_next_tail(struct vm_page *pg); - -extern size_t vm_bytes_to_pages(size_t bytes); - -extern void vm_zone_init( - struct vm_zone *z, - const struct vm_zone_descriptor *zone_info); -extern struct vm_page *vm_zone_alloc_page( - struct vm_zone *z, - enum vm_page_order order, - enum vm_flags flags); -extern void vm_zone_free_page(struct vm_zone *z, struct vm_page *pg); - -extern struct vm_cache *vm_cache_create( - const char *name, - size_t objsz, - enum vm_cache_flags flags); -extern void vm_cache_init(struct vm_cache *cache); -extern void vm_cache_destroy(struct vm_cache *cache); -extern void *vm_cache_alloc(struct vm_cache *cache, enum vm_flags flags); -extern void vm_cache_free(struct vm_cache *cache, void *p); - -extern void kmalloc_init(void); -extern void *kmalloc(size_t count, enum vm_flags flags); -extern void *kzalloc(size_t count, enum vm_flags flags); -extern void kfree(void *p); - -/* Flat memory model functions */ -extern void vm_flat_init(void); -extern struct vm_page *vm_page_get_flat(phys_addr_t addr); -extern size_t vm_page_get_pfn_flat(struct vm_page *pg); - -/* Sparse memory model functions */ -extern void vm_sparse_init(void); -extern struct vm_page *vm_page_get_sparse(phys_addr_t addr); -extern size_t vm_page_get_pfn_sparse(struct vm_page *pg); - -#ifdef __cplusplus -} -#endif - -#ifdef __cplusplus -inline void *operator new(size_t count, void *p) -{ - return p; -} - -#define kmalloc_object(objtype, flags, ...) \ - __extension__({ \ - void *p = kmalloc(sizeof(objtype), flags); \ - if (p) { \ - new (p) objtype(__VA_ARGS__); \ - } \ - (objtype *)p; \ - }) - -#endif - -#endif diff --git a/init/init.c b/init/init.c index 796cf5b..bb18f7a 100644 --- a/init/init.c +++ b/init/init.c @@ -1,5 +1,4 @@ -#include - +#include int do_initcalls(void) { diff --git a/init/main.c b/init/main.c index c0d269f..b0b638c 100644 --- a/init/main.c +++ b/init/main.c @@ -1,18 +1,20 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include extern unsigned long get_rflags(void); diff --git a/kernel/arg.c b/kernel/arg.c index f7a591e..d423fbb 100644 --- a/kernel/arg.c +++ b/kernel/arg.c @@ -1,6 +1,6 @@ -#include -#include -#include +#include +#include +#include static char g_cmdline[CMDLINE_MAX + 1] = {0}; diff --git a/kernel/bsp.c b/kernel/bsp.c index 8559558..df5808a 100644 --- a/kernel/bsp.c +++ b/kernel/bsp.c @@ -1,9 +1,10 @@ -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include #define BOOTSTRAP_STACK_SIZE 0x10000 diff --git a/kernel/clock.c b/kernel/clock.c index f5a225f..b14ceb9 100644 --- a/kernel/clock.c +++ b/kernel/clock.c @@ -1,6 +1,6 @@ -#include -#include -#include +#include +#include +#include static clock_ticks_t ticks_per_sec = 0; volatile clock_ticks_t clock_ticks = 0; diff --git a/kernel/console.c b/kernel/console.c index 43f6998..0195379 100644 --- a/kernel/console.c +++ b/kernel/console.c @@ -1,7 +1,7 @@ -#include -#include -#include -#include +#include +#include +#include +#include static struct queue consoles; static spin_lock_t consoles_lock = SPIN_LOCK_INIT; diff --git a/kernel/cpu.c b/kernel/cpu.c index 4e62387..756c833 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -1,6 +1,6 @@ -#include -#include -#include +#include +#include +#include DECLARE_BITMAP(cpu_available, CPU_MAX); DECLARE_BITMAP(cpu_online, CPU_MAX); diff --git a/kernel/handle.c b/kernel/handle.c index 8dd8b50..d92f025 100644 --- a/kernel/handle.c +++ b/kernel/handle.c @@ -1,7 +1,9 @@ -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include /* depth=3 gives a maximum of ~66.6 million handles */ #define MAX_TABLE_DEPTH 3 diff --git a/kernel/object.c b/kernel/object.c index 0cc675b..3c04a26 100644 --- a/kernel/object.c +++ b/kernel/object.c @@ -1,6 +1,6 @@ -#include -#include -#include +#include +#include +#include #define HAS_OP(obj, opname) ((obj)->ob_type->ob_ops.opname) diff --git a/kernel/panic.c b/kernel/panic.c index 7d5e2cc..6efe0f5 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -1,8 +1,8 @@ -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include static int has_panicked = 0; diff --git a/kernel/percpu.c b/kernel/percpu.c index 9dddfb6..fcaf9bc 100644 --- a/kernel/percpu.c +++ b/kernel/percpu.c @@ -1,6 +1,6 @@ -#include -#include -#include +#include +#include +#include #include #include diff --git a/kernel/printk.c b/kernel/printk.c index f61c1a1..aea015d 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -1,7 +1,7 @@ -#include -#include -#include -#include +#include +#include +#include +#include #include #define LOG_BUFFER_SIZE 0x40000 diff --git a/libc/include/mango/libc/ctype.h b/libc/include/mango/libc/ctype.h deleted file mode 100644 index 4dc2eef..0000000 --- a/libc/include/mango/libc/ctype.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef MANGO_LIBC_TYPES_H_ -#define MANGO_LIBC_TYPES_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -extern int isalnum(int c); -extern int isalpha(int c); -extern int iscntrl(int c); -extern int isdigit(int c); -extern int isgraph(int c); -extern int islower(int c); -extern int isprint(int c); -extern int ispunct(int c); -extern int isspace(int c); -extern int isupper(int c); -extern int isxdigit(int c); -extern int tolower(int c); -extern int toupper(int c); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/libc/include/mango/libc/stdio.h b/libc/include/mango/libc/stdio.h deleted file mode 100644 index f7078ad..0000000 --- a/libc/include/mango/libc/stdio.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef MANGO_STDIO_H_ -#define MANGO_STDIO_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -int snprintf(char *buffer, size_t count, const char *format, ...); -int vsnprintf(char *buffer, size_t count, const char *format, va_list va); - -int fctprintf(void (*out)(char character, void *arg), void *arg, const char*format, ...); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/libc/include/mango/libc/string.h b/libc/include/mango/libc/string.h deleted file mode 100644 index 10a29ed..0000000 --- a/libc/include/mango/libc/string.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef MANGO_LIBC_STRING_H_ -#define MANGO_LIBC_STRING_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -extern char *strcpy(char *output, const char *input); -extern char *strncpy(char *output, const char *input, unsigned long count); -extern char *strchrnul(const char *s, int c); -extern char *strchr(const char *s, int c); -extern size_t lfind(const char *str, const char accept); -extern size_t strspn(const char *s, const char *c); -extern size_t strcspn(const char *s, const char *c); -extern char *strpbrk(const char *s, const char *b); -extern size_t strlen(const char *str); -extern char *strrchr(const char *str, int c); -extern int strcmp(const char *s1, const char *s2); -extern int strncmp(const char *s1, const char *s2, unsigned long n); -extern void *memcpy(void *str1, const void *str2, size_t n); -extern int memcmp(const void *str1, const void *str2, size_t n); -extern void *memset(void *str, int c, size_t n); -extern void *memmove(void *dst, const void *src, size_t n); -extern char *strdup(const char *src); -extern char *strtok_r(char *str, const char *delim, char **saveptr); -extern char *strcat(char *dest, const char *src); -extern char *strncat(char *dest, const char *src, size_t num); -extern void *memchr(const void *ptr, int value, unsigned long num); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/libc/stdio/printf.c b/libc/stdio/printf.c index fb644fc..adcd8b5 100644 --- a/libc/stdio/printf.c +++ b/libc/stdio/printf.c @@ -22,19 +22,20 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // -// \brief Tiny printf, sprintf and (v)snprintf implementation, optimized for speed on -// embedded systems with a very limited resources. These routines are thread -// safe and reentrant! -// Use this instead of the bloated standard/newlib printf cause these use -// malloc for printf (and may not be thread safe). +// \brief Tiny printf, sprintf and (v)snprintf implementation, optimized for +// speed on +// embedded systems with a very limited resources. These routines are +// thread safe and reentrant! Use this instead of the bloated +// standard/newlib printf cause these use malloc for printf (and may not +// be thread safe). // /////////////////////////////////////////////////////////////////////////////// -#include -#include -#include -#include +#include #include +#include +#include +#include #define PRINTF_DISABLE_SUPPORT_FLOAT @@ -45,19 +46,18 @@ #include "printf_config.h" #endif - // 'ntoa' conversion buffer size, this must be big enough to hold one converted // numeric number including padded zeros (dynamically created on stack) // default: 32 byte #ifndef PRINTF_NTOA_BUFFER_SIZE -#define PRINTF_NTOA_BUFFER_SIZE 32U +#define PRINTF_NTOA_BUFFER_SIZE 32U #endif // 'ftoa' conversion buffer size, this must be big enough to hold one converted // float number including padded zeros (dynamically created on stack) // default: 32 byte #ifndef PRINTF_FTOA_BUFFER_SIZE -#define PRINTF_FTOA_BUFFER_SIZE 32U +#define PRINTF_FTOA_BUFFER_SIZE 32U #endif // support for the floating point type (%f) @@ -75,13 +75,13 @@ // define the default floating point precision // default: 6 digits #ifndef PRINTF_DEFAULT_FLOAT_PRECISION -#define PRINTF_DEFAULT_FLOAT_PRECISION 6U +#define PRINTF_DEFAULT_FLOAT_PRECISION 6U #endif // define the largest float suitable to print with %f // default: 1e9 #ifndef PRINTF_MAX_FLOAT -#define PRINTF_MAX_FLOAT 1e9 +#define PRINTF_MAX_FLOAT 1e9 #endif // support for the long long types (%llu or %p) @@ -100,777 +100,1117 @@ /////////////////////////////////////////////////////////////////////////////// // internal flag definitions -#define FLAGS_ZEROPAD (1U << 0U) -#define FLAGS_LEFT (1U << 1U) -#define FLAGS_PLUS (1U << 2U) -#define FLAGS_SPACE (1U << 3U) -#define FLAGS_HASH (1U << 4U) -#define FLAGS_UPPERCASE (1U << 5U) -#define FLAGS_CHAR (1U << 6U) -#define FLAGS_SHORT (1U << 7U) -#define FLAGS_LONG (1U << 8U) -#define FLAGS_LONG_LONG (1U << 9U) +#define FLAGS_ZEROPAD (1U << 0U) +#define FLAGS_LEFT (1U << 1U) +#define FLAGS_PLUS (1U << 2U) +#define FLAGS_SPACE (1U << 3U) +#define FLAGS_HASH (1U << 4U) +#define FLAGS_UPPERCASE (1U << 5U) +#define FLAGS_CHAR (1U << 6U) +#define FLAGS_SHORT (1U << 7U) +#define FLAGS_LONG (1U << 8U) +#define FLAGS_LONG_LONG (1U << 9U) #define FLAGS_PRECISION (1U << 10U) #define FLAGS_ADAPT_EXP (1U << 11U) - // import float.h for DBL_MAX #if defined(PRINTF_SUPPORT_FLOAT) #include #endif - // output function type -typedef void (*out_fct_type)(char character, void* buffer, size_t idx, size_t maxlen); - +typedef void ( + *out_fct_type)(char character, void *buffer, size_t idx, size_t maxlen); // wrapper (used as buffer) for output function type typedef struct { - void (*fct)(char character, void* arg); - void* arg; + void (*fct)(char character, void *arg); + void *arg; } out_fct_wrap_type; - // internal buffer output -static inline void _out_buffer(char character, void* buffer, size_t idx, size_t maxlen) +static inline void _out_buffer( + char character, + void *buffer, + size_t idx, + size_t maxlen) { - if (idx < maxlen) { - ((char*)buffer)[idx] = character; - } + if (idx < maxlen) { + ((char *)buffer)[idx] = character; + } } - // internal null output -static inline void _out_null(char character, void* buffer, size_t idx, size_t maxlen) +static inline void _out_null( + char character, + void *buffer, + size_t idx, + size_t maxlen) { - (void)character; (void)buffer; (void)idx; (void)maxlen; + (void)character; + (void)buffer; + (void)idx; + (void)maxlen; } - // internal output function wrapper -static inline void _out_fct(char character, void* buffer, size_t idx, size_t maxlen) +static inline void _out_fct( + char character, + void *buffer, + size_t idx, + size_t maxlen) { - (void)idx; (void)maxlen; - if (character) { - // buffer is the output fct pointer - ((out_fct_wrap_type*)buffer)->fct(character, ((out_fct_wrap_type*)buffer)->arg); - } + (void)idx; + (void)maxlen; + if (character) { + // buffer is the output fct pointer + ((out_fct_wrap_type *)buffer) + ->fct(character, ((out_fct_wrap_type *)buffer)->arg); + } } - // internal secure strlen -// \return The length of the string (excluding the terminating 0) limited by 'maxsize' -static inline unsigned int _strnlen_s(const char* str, size_t maxsize) +// \return The length of the string (excluding the terminating 0) limited by +// 'maxsize' +static inline unsigned int _strnlen_s(const char *str, size_t maxsize) { - const char* s; - for (s = str; *s && maxsize--; ++s); - return (unsigned int)(s - str); + const char *s; + for (s = str; *s && maxsize--; ++s) + ; + return (unsigned int)(s - str); } - // internal test if char is a digit (0-9) // \return true if char is a digit static inline bool _is_digit(char ch) { - return (ch >= '0') && (ch <= '9'); + return (ch >= '0') && (ch <= '9'); } - // internal ASCII string to unsigned int conversion -static unsigned int _atoi(const char** str) +static unsigned int _atoi(const char **str) { - unsigned int i = 0U; - while (_is_digit(**str)) { - i = i * 10U + (unsigned int)(*((*str)++) - '0'); - } - return i; + unsigned int i = 0U; + while (_is_digit(**str)) { + i = i * 10U + (unsigned int)(*((*str)++) - '0'); + } + return i; } - // output the specified string in reverse, taking care of any zero-padding -static size_t _out_rev(out_fct_type out, char* buffer, size_t idx, size_t maxlen, const char* buf, size_t len, unsigned int width, unsigned int flags) +static size_t _out_rev( + out_fct_type out, + char *buffer, + size_t idx, + size_t maxlen, + const char *buf, + size_t len, + unsigned int width, + unsigned int flags) { - const size_t start_idx = idx; + const size_t start_idx = idx; - // pad spaces up to given width - if (!(flags & FLAGS_LEFT) && !(flags & FLAGS_ZEROPAD)) { - for (size_t i = len; i < width; i++) { - out(' ', buffer, idx++, maxlen); - } - } + // pad spaces up to given width + if (!(flags & FLAGS_LEFT) && !(flags & FLAGS_ZEROPAD)) { + for (size_t i = len; i < width; i++) { + out(' ', buffer, idx++, maxlen); + } + } - // reverse string - while (len) { - out(buf[--len], buffer, idx++, maxlen); - } + // reverse string + while (len) { + out(buf[--len], buffer, idx++, maxlen); + } - // append pad spaces up to given width - if (flags & FLAGS_LEFT) { - while (idx - start_idx < width) { - out(' ', buffer, idx++, maxlen); - } - } + // append pad spaces up to given width + if (flags & FLAGS_LEFT) { + while (idx - start_idx < width) { + out(' ', buffer, idx++, maxlen); + } + } - return idx; + return idx; } - // internal itoa format -static size_t _ntoa_format(out_fct_type out, char* buffer, size_t idx, size_t maxlen, char* buf, size_t len, bool negative, unsigned int base, unsigned int prec, unsigned int width, unsigned int flags) +static size_t _ntoa_format( + out_fct_type out, + char *buffer, + size_t idx, + size_t maxlen, + char *buf, + size_t len, + bool negative, + unsigned int base, + unsigned int prec, + unsigned int width, + unsigned int flags) { - // pad leading zeros - if (!(flags & FLAGS_LEFT)) { - if (width && (flags & FLAGS_ZEROPAD) && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) { - width--; - } - while ((len < prec) && (len < PRINTF_NTOA_BUFFER_SIZE)) { - buf[len++] = '0'; - } - while ((flags & FLAGS_ZEROPAD) && (len < width) && (len < PRINTF_NTOA_BUFFER_SIZE)) { - buf[len++] = '0'; - } - } + // pad leading zeros + if (!(flags & FLAGS_LEFT)) { + if (width && (flags & FLAGS_ZEROPAD) + && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) { + width--; + } + while ((len < prec) && (len < PRINTF_NTOA_BUFFER_SIZE)) { + buf[len++] = '0'; + } + while ((flags & FLAGS_ZEROPAD) && (len < width) + && (len < PRINTF_NTOA_BUFFER_SIZE)) { + buf[len++] = '0'; + } + } - // handle hash - if (flags & FLAGS_HASH) { - if (!(flags & FLAGS_PRECISION) && len && ((len == prec) || (len == width))) { - len--; - if (len && (base == 16U)) { - len--; - } - } - if ((base == 16U) && !(flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) { - buf[len++] = 'x'; - } - else if ((base == 16U) && (flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) { - buf[len++] = 'X'; - } - else if ((base == 2U) && (len < PRINTF_NTOA_BUFFER_SIZE)) { - buf[len++] = 'b'; - } - if (len < PRINTF_NTOA_BUFFER_SIZE) { - buf[len++] = '0'; - } - } + // handle hash + if (flags & FLAGS_HASH) { + if (!(flags & FLAGS_PRECISION) && len + && ((len == prec) || (len == width))) { + len--; + if (len && (base == 16U)) { + len--; + } + } + if ((base == 16U) && !(flags & FLAGS_UPPERCASE) + && (len < PRINTF_NTOA_BUFFER_SIZE)) { + buf[len++] = 'x'; + } else if ( + (base == 16U) && (flags & FLAGS_UPPERCASE) + && (len < PRINTF_NTOA_BUFFER_SIZE)) { + buf[len++] = 'X'; + } else if ((base == 2U) && (len < PRINTF_NTOA_BUFFER_SIZE)) { + buf[len++] = 'b'; + } + if (len < PRINTF_NTOA_BUFFER_SIZE) { + buf[len++] = '0'; + } + } - if (len < PRINTF_NTOA_BUFFER_SIZE) { - if (negative) { - buf[len++] = '-'; - } - else if (flags & FLAGS_PLUS) { - buf[len++] = '+'; // ignore the space if the '+' exists - } - else if (flags & FLAGS_SPACE) { - buf[len++] = ' '; - } - } + if (len < PRINTF_NTOA_BUFFER_SIZE) { + if (negative) { + buf[len++] = '-'; + } else if (flags & FLAGS_PLUS) { + buf[len++] + = '+'; // ignore the space if the '+' exists + } else if (flags & FLAGS_SPACE) { + buf[len++] = ' '; + } + } - return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags); + return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags); } - // internal itoa for 'long' type -static size_t _ntoa_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long value, bool negative, unsigned long base, unsigned int prec, unsigned int width, unsigned int flags) +static size_t _ntoa_long( + out_fct_type out, + char *buffer, + size_t idx, + size_t maxlen, + unsigned long value, + bool negative, + unsigned long base, + unsigned int prec, + unsigned int width, + unsigned int flags) { - char buf[PRINTF_NTOA_BUFFER_SIZE]; - size_t len = 0U; + char buf[PRINTF_NTOA_BUFFER_SIZE]; + size_t len = 0U; - // no hash for 0 values - if (!value) { - flags &= ~FLAGS_HASH; - } + // no hash for 0 values + if (!value) { + flags &= ~FLAGS_HASH; + } - // write if precision != 0 and value is != 0 - if (!(flags & FLAGS_PRECISION) || value) { - do { - const char digit = (char)(value % base); - buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; - value /= base; - } while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); - } + // write if precision != 0 and value is != 0 + if (!(flags & FLAGS_PRECISION) || value) { + do { + const char digit = (char)(value % base); + buf[len++] + = digit < 10 + ? '0' + digit + : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + + digit - 10; + value /= base; + } while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); + } - return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags); + return _ntoa_format( + out, + buffer, + idx, + maxlen, + buf, + len, + negative, + (unsigned int)base, + prec, + width, + flags); } - // internal itoa for 'long long' type #if defined(PRINTF_SUPPORT_LONG_LONG) -static size_t _ntoa_long_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long long value, bool negative, unsigned long long base, unsigned int prec, unsigned int width, unsigned int flags) +static size_t _ntoa_long_long( + out_fct_type out, + char *buffer, + size_t idx, + size_t maxlen, + unsigned long long value, + bool negative, + unsigned long long base, + unsigned int prec, + unsigned int width, + unsigned int flags) { - char buf[PRINTF_NTOA_BUFFER_SIZE]; - size_t len = 0U; + char buf[PRINTF_NTOA_BUFFER_SIZE]; + size_t len = 0U; - // no hash for 0 values - if (!value) { - flags &= ~FLAGS_HASH; - } + // no hash for 0 values + if (!value) { + flags &= ~FLAGS_HASH; + } - // write if precision != 0 and value is != 0 - if (!(flags & FLAGS_PRECISION) || value) { - do { - const char digit = (char)(value % base); - buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; - value /= base; - } while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); - } + // write if precision != 0 and value is != 0 + if (!(flags & FLAGS_PRECISION) || value) { + do { + const char digit = (char)(value % base); + buf[len++] + = digit < 10 + ? '0' + digit + : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + + digit - 10; + value /= base; + } while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); + } - return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags); + return _ntoa_format( + out, + buffer, + idx, + maxlen, + buf, + len, + negative, + (unsigned int)base, + prec, + width, + flags); } -#endif // PRINTF_SUPPORT_LONG_LONG - +#endif // PRINTF_SUPPORT_LONG_LONG #if defined(PRINTF_SUPPORT_FLOAT) #if defined(PRINTF_SUPPORT_EXPONENTIAL) -// forward declaration so that _ftoa can switch to exp notation for values > PRINTF_MAX_FLOAT -static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags); +// forward declaration so that _ftoa can switch to exp notation for values > +// PRINTF_MAX_FLOAT +static size_t _etoa( + out_fct_type out, + char *buffer, + size_t idx, + size_t maxlen, + double value, + unsigned int prec, + unsigned int width, + unsigned int flags); #endif - // internal ftoa for fixed decimal floating point -static size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags) +static size_t _ftoa( + out_fct_type out, + char *buffer, + size_t idx, + size_t maxlen, + double value, + unsigned int prec, + unsigned int width, + unsigned int flags) { - char buf[PRINTF_FTOA_BUFFER_SIZE]; - size_t len = 0U; - double diff = 0.0; + char buf[PRINTF_FTOA_BUFFER_SIZE]; + size_t len = 0U; + double diff = 0.0; - // powers of 10 - static const double pow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 }; + // powers of 10 + static const double pow10[] + = {1, + 10, + 100, + 1000, + 10000, + 100000, + 1000000, + 10000000, + 100000000, + 1000000000}; - // test for special values - if (value != value) - return _out_rev(out, buffer, idx, maxlen, "nan", 3, width, flags); - if (value < -DBL_MAX) - return _out_rev(out, buffer, idx, maxlen, "fni-", 4, width, flags); - if (value > DBL_MAX) - return _out_rev(out, buffer, idx, maxlen, (flags & FLAGS_PLUS) ? "fni+" : "fni", (flags & FLAGS_PLUS) ? 4U : 3U, width, flags); + // test for special values + if (value != value) + return _out_rev( + out, + buffer, + idx, + maxlen, + "nan", + 3, + width, + flags); + if (value < -DBL_MAX) + return _out_rev( + out, + buffer, + idx, + maxlen, + "fni-", + 4, + width, + flags); + if (value > DBL_MAX) + return _out_rev( + out, + buffer, + idx, + maxlen, + (flags & FLAGS_PLUS) ? "fni+" : "fni", + (flags & FLAGS_PLUS) ? 4U : 3U, + width, + flags); - // test for very large values - // standard printf behavior is to print EVERY whole number digit -- which could be 100s of characters overflowing your buffers == bad - if ((value > PRINTF_MAX_FLOAT) || (value < -PRINTF_MAX_FLOAT)) { + // test for very large values + // standard printf behavior is to print EVERY whole number digit -- + // which could be 100s of characters overflowing your buffers == bad + if ((value > PRINTF_MAX_FLOAT) || (value < -PRINTF_MAX_FLOAT)) { #if defined(PRINTF_SUPPORT_EXPONENTIAL) - return _etoa(out, buffer, idx, maxlen, value, prec, width, flags); + return _etoa( + out, + buffer, + idx, + maxlen, + value, + prec, + width, + flags); #else - return 0U; + return 0U; #endif - } + } - // test for negative - bool negative = false; - if (value < 0) { - negative = true; - value = 0 - value; - } + // test for negative + bool negative = false; + if (value < 0) { + negative = true; + value = 0 - value; + } - // set default precision, if not set explicitly - if (!(flags & FLAGS_PRECISION)) { - prec = PRINTF_DEFAULT_FLOAT_PRECISION; - } - // limit precision to 9, cause a prec >= 10 can lead to overflow errors - while ((len < PRINTF_FTOA_BUFFER_SIZE) && (prec > 9U)) { - buf[len++] = '0'; - prec--; - } + // set default precision, if not set explicitly + if (!(flags & FLAGS_PRECISION)) { + prec = PRINTF_DEFAULT_FLOAT_PRECISION; + } + // limit precision to 9, cause a prec >= 10 can lead to overflow errors + while ((len < PRINTF_FTOA_BUFFER_SIZE) && (prec > 9U)) { + buf[len++] = '0'; + prec--; + } - int whole = (int)value; - double tmp = (value - whole) * pow10[prec]; - unsigned long frac = (unsigned long)tmp; - diff = tmp - frac; + int whole = (int)value; + double tmp = (value - whole) * pow10[prec]; + unsigned long frac = (unsigned long)tmp; + diff = tmp - frac; - if (diff > 0.5) { - ++frac; - // handle rollover, e.g. case 0.99 with prec 1 is 1.0 - if (frac >= pow10[prec]) { - frac = 0; - ++whole; - } - } - else if (diff < 0.5) { - } - else if ((frac == 0U) || (frac & 1U)) { - // if halfway, round up if odd OR if last digit is 0 - ++frac; - } + if (diff > 0.5) { + ++frac; + // handle rollover, e.g. case 0.99 with prec 1 is 1.0 + if (frac >= pow10[prec]) { + frac = 0; + ++whole; + } + } else if (diff < 0.5) { + } else if ((frac == 0U) || (frac & 1U)) { + // if halfway, round up if odd OR if last digit is 0 + ++frac; + } - if (prec == 0U) { - diff = value - (double)whole; - if ((!(diff < 0.5) || (diff > 0.5)) && (whole & 1)) { - // exactly 0.5 and ODD, then round up - // 1.5 -> 2, but 2.5 -> 2 - ++whole; - } - } - else { - unsigned int count = prec; - // now do fractional part, as an unsigned number - while (len < PRINTF_FTOA_BUFFER_SIZE) { - --count; - buf[len++] = (char)(48U + (frac % 10U)); - if (!(frac /= 10U)) { - break; - } - } - // add extra 0s - while ((len < PRINTF_FTOA_BUFFER_SIZE) && (count-- > 0U)) { - buf[len++] = '0'; - } - if (len < PRINTF_FTOA_BUFFER_SIZE) { - // add decimal - buf[len++] = '.'; - } - } + if (prec == 0U) { + diff = value - (double)whole; + if ((!(diff < 0.5) || (diff > 0.5)) && (whole & 1)) { + // exactly 0.5 and ODD, then round up + // 1.5 -> 2, but 2.5 -> 2 + ++whole; + } + } else { + unsigned int count = prec; + // now do fractional part, as an unsigned number + while (len < PRINTF_FTOA_BUFFER_SIZE) { + --count; + buf[len++] = (char)(48U + (frac % 10U)); + if (!(frac /= 10U)) { + break; + } + } + // add extra 0s + while ((len < PRINTF_FTOA_BUFFER_SIZE) && (count-- > 0U)) { + buf[len++] = '0'; + } + if (len < PRINTF_FTOA_BUFFER_SIZE) { + // add decimal + buf[len++] = '.'; + } + } - // do whole part, number is reversed - while (len < PRINTF_FTOA_BUFFER_SIZE) { - buf[len++] = (char)(48 + (whole % 10)); - if (!(whole /= 10)) { - break; - } - } + // do whole part, number is reversed + while (len < PRINTF_FTOA_BUFFER_SIZE) { + buf[len++] = (char)(48 + (whole % 10)); + if (!(whole /= 10)) { + break; + } + } - // pad leading zeros - if (!(flags & FLAGS_LEFT) && (flags & FLAGS_ZEROPAD)) { - if (width && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) { - width--; - } - while ((len < width) && (len < PRINTF_FTOA_BUFFER_SIZE)) { - buf[len++] = '0'; - } - } + // pad leading zeros + if (!(flags & FLAGS_LEFT) && (flags & FLAGS_ZEROPAD)) { + if (width + && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) { + width--; + } + while ((len < width) && (len < PRINTF_FTOA_BUFFER_SIZE)) { + buf[len++] = '0'; + } + } - if (len < PRINTF_FTOA_BUFFER_SIZE) { - if (negative) { - buf[len++] = '-'; - } - else if (flags & FLAGS_PLUS) { - buf[len++] = '+'; // ignore the space if the '+' exists - } - else if (flags & FLAGS_SPACE) { - buf[len++] = ' '; - } - } + if (len < PRINTF_FTOA_BUFFER_SIZE) { + if (negative) { + buf[len++] = '-'; + } else if (flags & FLAGS_PLUS) { + buf[len++] + = '+'; // ignore the space if the '+' exists + } else if (flags & FLAGS_SPACE) { + buf[len++] = ' '; + } + } - return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags); + return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags); } - #if defined(PRINTF_SUPPORT_EXPONENTIAL) -// internal ftoa variant for exponential floating-point type, contributed by Martijn Jasperse -static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags) +// internal ftoa variant for exponential floating-point type, contributed by +// Martijn Jasperse +static size_t _etoa( + out_fct_type out, + char *buffer, + size_t idx, + size_t maxlen, + double value, + unsigned int prec, + unsigned int width, + unsigned int flags) { - // check for NaN and special values - if ((value != value) || (value > DBL_MAX) || (value < -DBL_MAX)) { - return _ftoa(out, buffer, idx, maxlen, value, prec, width, flags); - } + // check for NaN and special values + if ((value != value) || (value > DBL_MAX) || (value < -DBL_MAX)) { + return _ftoa( + out, + buffer, + idx, + maxlen, + value, + prec, + width, + flags); + } - // determine the sign - const bool negative = value < 0; - if (negative) { - value = -value; - } + // determine the sign + const bool negative = value < 0; + if (negative) { + value = -value; + } - // default precision - if (!(flags & FLAGS_PRECISION)) { - prec = PRINTF_DEFAULT_FLOAT_PRECISION; - } + // default precision + if (!(flags & FLAGS_PRECISION)) { + prec = PRINTF_DEFAULT_FLOAT_PRECISION; + } - // determine the decimal exponent - // based on the algorithm by David Gay (https://www.ampl.com/netlib/fp/dtoa.c) - union { - uint64_t U; - double F; - } conv; + // determine the decimal exponent + // based on the algorithm by David Gay + // (https://www.ampl.com/netlib/fp/dtoa.c) + union { + uint64_t U; + double F; + } conv; - conv.F = value; - int exp2 = (int)((conv.U >> 52U) & 0x07FFU) - 1023; // effectively log2 - conv.U = (conv.U & ((1ULL << 52U) - 1U)) | (1023ULL << 52U); // drop the exponent so conv.F is now in [1,2) - // now approximate log10 from the log2 integer part and an expansion of ln around 1.5 - int expval = (int)(0.1760912590558 + exp2 * 0.301029995663981 + (conv.F - 1.5) * 0.289529654602168); - // now we want to compute 10^expval but we want to be sure it won't overflow - exp2 = (int)(expval * 3.321928094887362 + 0.5); - const double z = expval * 2.302585092994046 - exp2 * 0.6931471805599453; - const double z2 = z * z; - conv.U = (uint64_t)(exp2 + 1023) << 52U; - // compute exp(z) using continued fractions, see https://en.wikipedia.org/wiki/Exponential_function#Continued_fractions_for_ex - conv.F *= 1 + 2 * z / (2 - z + (z2 / (6 + (z2 / (10 + z2 / 14))))); - // correct for rounding errors - if (value < conv.F) { - expval--; - conv.F /= 10; - } + conv.F = value; + int exp2 + = (int)((conv.U >> 52U) & 0x07FFU) - 1023; // effectively log2 + conv.U = (conv.U & ((1ULL << 52U) - 1U)) + | (1023ULL + << 52U); // drop the exponent so conv.F is now in [1,2) + // now approximate log10 from the log2 integer part and an expansion of + // ln around 1.5 + int expval = (int)(0.1760912590558 + exp2 * 0.301029995663981 + + (conv.F - 1.5) * 0.289529654602168); + // now we want to compute 10^expval but we want to be sure it won't + // overflow + exp2 = (int)(expval * 3.321928094887362 + 0.5); + const double z = expval * 2.302585092994046 - exp2 * 0.6931471805599453; + const double z2 = z * z; + conv.U = (uint64_t)(exp2 + 1023) << 52U; + // compute exp(z) using continued fractions, see + // https://en.wikipedia.org/wiki/Exponential_function#Continued_fractions_for_ex + conv.F *= 1 + 2 * z / (2 - z + (z2 / (6 + (z2 / (10 + z2 / 14))))); + // correct for rounding errors + if (value < conv.F) { + expval--; + conv.F /= 10; + } - // the exponent format is "%+03d" and largest value is "307", so set aside 4-5 characters - unsigned int minwidth = ((expval < 100) && (expval > -100)) ? 4U : 5U; + // the exponent format is "%+03d" and largest value is "307", so set + // aside 4-5 characters + unsigned int minwidth = ((expval < 100) && (expval > -100)) ? 4U : 5U; - // in "%g" mode, "prec" is the number of *significant figures* not decimals - if (flags & FLAGS_ADAPT_EXP) { - // do we want to fall-back to "%f" mode? - if ((value >= 1e-4) && (value < 1e6)) { - if ((int)prec > expval) { - prec = (unsigned)((int)prec - expval - 1); - } - else { - prec = 0; - } - flags |= FLAGS_PRECISION; // make sure _ftoa respects precision - // no characters in exponent - minwidth = 0U; - expval = 0; - } - else { - // we use one sigfig for the whole part - if ((prec > 0) && (flags & FLAGS_PRECISION)) { - --prec; - } - } - } + // in "%g" mode, "prec" is the number of *significant figures* not + // decimals + if (flags & FLAGS_ADAPT_EXP) { + // do we want to fall-back to "%f" mode? + if ((value >= 1e-4) && (value < 1e6)) { + if ((int)prec > expval) { + prec = (unsigned)((int)prec - expval - 1); + } else { + prec = 0; + } + flags |= FLAGS_PRECISION; // make sure _ftoa respects + // precision + // no characters in exponent + minwidth = 0U; + expval = 0; + } else { + // we use one sigfig for the whole part + if ((prec > 0) && (flags & FLAGS_PRECISION)) { + --prec; + } + } + } - // will everything fit? - unsigned int fwidth = width; - if (width > minwidth) { - // we didn't fall-back so subtract the characters required for the exponent - fwidth -= minwidth; - } else { - // not enough characters, so go back to default sizing - fwidth = 0U; - } - if ((flags & FLAGS_LEFT) && minwidth) { - // if we're padding on the right, DON'T pad the floating part - fwidth = 0U; - } + // will everything fit? + unsigned int fwidth = width; + if (width > minwidth) { + // we didn't fall-back so subtract the characters required for + // the exponent + fwidth -= minwidth; + } else { + // not enough characters, so go back to default sizing + fwidth = 0U; + } + if ((flags & FLAGS_LEFT) && minwidth) { + // if we're padding on the right, DON'T pad the floating part + fwidth = 0U; + } - // rescale the float value - if (expval) { - value /= conv.F; - } + // rescale the float value + if (expval) { + value /= conv.F; + } - // output the floating part - const size_t start_idx = idx; - idx = _ftoa(out, buffer, idx, maxlen, negative ? -value : value, prec, fwidth, flags & ~FLAGS_ADAPT_EXP); + // output the floating part + const size_t start_idx = idx; + idx + = _ftoa(out, + buffer, + idx, + maxlen, + negative ? -value : value, + prec, + fwidth, + flags & ~FLAGS_ADAPT_EXP); - // output the exponent part - if (minwidth) { - // output the exponential symbol - out((flags & FLAGS_UPPERCASE) ? 'E' : 'e', buffer, idx++, maxlen); - // output the exponent value - idx = _ntoa_long(out, buffer, idx, maxlen, (expval < 0) ? -expval : expval, expval < 0, 10, 0, minwidth-1, FLAGS_ZEROPAD | FLAGS_PLUS); - // might need to right-pad spaces - if (flags & FLAGS_LEFT) { - while (idx - start_idx < width) out(' ', buffer, idx++, maxlen); - } - } - return idx; + // output the exponent part + if (minwidth) { + // output the exponential symbol + out((flags & FLAGS_UPPERCASE) ? 'E' : 'e', + buffer, + idx++, + maxlen); + // output the exponent value + idx = _ntoa_long( + out, + buffer, + idx, + maxlen, + (expval < 0) ? -expval : expval, + expval < 0, + 10, + 0, + minwidth - 1, + FLAGS_ZEROPAD | FLAGS_PLUS); + // might need to right-pad spaces + if (flags & FLAGS_LEFT) { + while (idx - start_idx < width) + out(' ', buffer, idx++, maxlen); + } + } + return idx; } -#endif // PRINTF_SUPPORT_EXPONENTIAL -#endif // PRINTF_SUPPORT_FLOAT - +#endif // PRINTF_SUPPORT_EXPONENTIAL +#endif // PRINTF_SUPPORT_FLOAT // internal vsnprintf -static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const char* format, va_list va) +static int _vsnprintf( + out_fct_type out, + char *buffer, + const size_t maxlen, + const char *format, + va_list va) { - unsigned int flags, width, precision, n; - size_t idx = 0U; + unsigned int flags, width, precision, n; + size_t idx = 0U; - if (!buffer) { - // use null output function - out = _out_null; - } + if (!buffer) { + // use null output function + out = _out_null; + } - while (*format) - { - // format specifier? %[flags][width][.precision][length] - if (*format != '%') { - // no - out(*format, buffer, idx++, maxlen); - format++; - continue; - } - else { - // yes, evaluate it - format++; - } + while (*format) { + // format specifier? %[flags][width][.precision][length] + if (*format != '%') { + // no + out(*format, buffer, idx++, maxlen); + format++; + continue; + } else { + // yes, evaluate it + format++; + } - // evaluate flags - flags = 0U; - do { - switch (*format) { - case '0': flags |= FLAGS_ZEROPAD; format++; n = 1U; break; - case '-': flags |= FLAGS_LEFT; format++; n = 1U; break; - case '+': flags |= FLAGS_PLUS; format++; n = 1U; break; - case ' ': flags |= FLAGS_SPACE; format++; n = 1U; break; - case '#': flags |= FLAGS_HASH; format++; n = 1U; break; - default : n = 0U; break; - } - } while (n); + // evaluate flags + flags = 0U; + do { + switch (*format) { + case '0': + flags |= FLAGS_ZEROPAD; + format++; + n = 1U; + break; + case '-': + flags |= FLAGS_LEFT; + format++; + n = 1U; + break; + case '+': + flags |= FLAGS_PLUS; + format++; + n = 1U; + break; + case ' ': + flags |= FLAGS_SPACE; + format++; + n = 1U; + break; + case '#': + flags |= FLAGS_HASH; + format++; + n = 1U; + break; + default: + n = 0U; + break; + } + } while (n); - // evaluate width field - width = 0U; - if (_is_digit(*format)) { - width = _atoi(&format); - } - else if (*format == '*') { - const int w = va_arg(va, int); - if (w < 0) { - flags |= FLAGS_LEFT; // reverse padding - width = (unsigned int)-w; - } - else { - width = (unsigned int)w; - } - format++; - } + // evaluate width field + width = 0U; + if (_is_digit(*format)) { + width = _atoi(&format); + } else if (*format == '*') { + const int w = va_arg(va, int); + if (w < 0) { + flags |= FLAGS_LEFT; // reverse padding + width = (unsigned int)-w; + } else { + width = (unsigned int)w; + } + format++; + } - // evaluate precision field - precision = 0U; - if (*format == '.') { - flags |= FLAGS_PRECISION; - format++; - if (_is_digit(*format)) { - precision = _atoi(&format); - } - else if (*format == '*') { - const int prec = (int)va_arg(va, int); - precision = prec > 0 ? (unsigned int)prec : 0U; - format++; - } - } + // evaluate precision field + precision = 0U; + if (*format == '.') { + flags |= FLAGS_PRECISION; + format++; + if (_is_digit(*format)) { + precision = _atoi(&format); + } else if (*format == '*') { + const int prec = (int)va_arg(va, int); + precision = prec > 0 ? (unsigned int)prec : 0U; + format++; + } + } - // evaluate length field - switch (*format) { - case 'l' : - flags |= FLAGS_LONG; - format++; - if (*format == 'l') { - flags |= FLAGS_LONG_LONG; - format++; - } - break; - case 'h' : - flags |= FLAGS_SHORT; - format++; - if (*format == 'h') { - flags |= FLAGS_CHAR; - format++; - } - break; + // evaluate length field + switch (*format) { + case 'l': + flags |= FLAGS_LONG; + format++; + if (*format == 'l') { + flags |= FLAGS_LONG_LONG; + format++; + } + break; + case 'h': + flags |= FLAGS_SHORT; + format++; + if (*format == 'h') { + flags |= FLAGS_CHAR; + format++; + } + break; #if defined(PRINTF_SUPPORT_PTRDIFF_T) - case 't' : - flags |= (sizeof(ptrdiff_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); - format++; - break; + case 't': + flags + |= (sizeof(ptrdiff_t) == sizeof(long) + ? FLAGS_LONG + : FLAGS_LONG_LONG); + format++; + break; #endif - case 'j' : - flags |= (sizeof(intmax_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); - format++; - break; - case 'z' : - flags |= (sizeof(size_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); - format++; - break; - default : - break; - } + case 'j': + flags + |= (sizeof(intmax_t) == sizeof(long) + ? FLAGS_LONG + : FLAGS_LONG_LONG); + format++; + break; + case 'z': + flags + |= (sizeof(size_t) == sizeof(long) + ? FLAGS_LONG + : FLAGS_LONG_LONG); + format++; + break; + default: + break; + } - // evaluate specifier - switch (*format) { - case 'd' : - case 'i' : - case 'u' : - case 'x' : - case 'X' : - case 'o' : - case 'b' : { - // set the base - unsigned int base; - if (*format == 'x' || *format == 'X') { - base = 16U; - } - else if (*format == 'o') { - base = 8U; - } - else if (*format == 'b') { - base = 2U; - } - else { - base = 10U; - flags &= ~FLAGS_HASH; // no hash for dec format - } - // uppercase - if (*format == 'X') { - flags |= FLAGS_UPPERCASE; - } + // evaluate specifier + switch (*format) { + case 'd': + case 'i': + case 'u': + case 'x': + case 'X': + case 'o': + case 'b': { + // set the base + unsigned int base; + if (*format == 'x' || *format == 'X') { + base = 16U; + } else if (*format == 'o') { + base = 8U; + } else if (*format == 'b') { + base = 2U; + } else { + base = 10U; + flags &= ~FLAGS_HASH; // no hash for dec + // format + } + // uppercase + if (*format == 'X') { + flags |= FLAGS_UPPERCASE; + } - // no plus or space flag for u, x, X, o, b - if ((*format != 'i') && (*format != 'd')) { - flags &= ~(FLAGS_PLUS | FLAGS_SPACE); - } + // no plus or space flag for u, x, X, o, b + if ((*format != 'i') && (*format != 'd')) { + flags &= ~(FLAGS_PLUS | FLAGS_SPACE); + } - // ignore '0' flag when precision is given - if (flags & FLAGS_PRECISION) { - flags &= ~FLAGS_ZEROPAD; - } + // ignore '0' flag when precision is given + if (flags & FLAGS_PRECISION) { + flags &= ~FLAGS_ZEROPAD; + } - // convert the integer - if ((*format == 'i') || (*format == 'd')) { - // signed - if (flags & FLAGS_LONG_LONG) { + // convert the integer + if ((*format == 'i') || (*format == 'd')) { + // signed + if (flags & FLAGS_LONG_LONG) { #if defined(PRINTF_SUPPORT_LONG_LONG) - const long long value = va_arg(va, long long); - idx = _ntoa_long_long(out, buffer, idx, maxlen, (unsigned long long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); + const long long value + = va_arg(va, long long); + idx = _ntoa_long_long( + out, + buffer, + idx, + maxlen, + (unsigned long long)(value > 0 + ? value + : 0 - value), + value < 0, + base, + precision, + width, + flags); #endif - } - else if (flags & FLAGS_LONG) { - const long value = va_arg(va, long); - idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); - } - else { - const int value = (flags & FLAGS_CHAR) ? (char)va_arg(va, int) : (flags & FLAGS_SHORT) ? (short int)va_arg(va, int) : va_arg(va, int); - idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned int)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); - } - } - else { - // unsigned - if (flags & FLAGS_LONG_LONG) { + } else if (flags & FLAGS_LONG) { + const long value = va_arg(va, long); + idx = _ntoa_long( + out, + buffer, + idx, + maxlen, + (unsigned long)(value > 0 + ? value + : 0 - value), + value < 0, + base, + precision, + width, + flags); + } else { + const int value + = (flags & FLAGS_CHAR) + ? (char)va_arg(va, int) + : (flags & FLAGS_SHORT) + ? (short int)va_arg( + va, + int) + : va_arg(va, int); + idx = _ntoa_long( + out, + buffer, + idx, + maxlen, + (unsigned int)(value > 0 + ? value + : 0 - value), + value < 0, + base, + precision, + width, + flags); + } + } else { + // unsigned + if (flags & FLAGS_LONG_LONG) { #if defined(PRINTF_SUPPORT_LONG_LONG) - idx = _ntoa_long_long(out, buffer, idx, maxlen, va_arg(va, unsigned long long), false, base, precision, width, flags); + idx = _ntoa_long_long( + out, + buffer, + idx, + maxlen, + va_arg(va, unsigned long long), + false, + base, + precision, + width, + flags); #endif - } - else if (flags & FLAGS_LONG) { - idx = _ntoa_long(out, buffer, idx, maxlen, va_arg(va, unsigned long), false, base, precision, width, flags); - } - else { - const unsigned int value = (flags & FLAGS_CHAR) ? (unsigned char)va_arg(va, unsigned int) : (flags & FLAGS_SHORT) ? (unsigned short int)va_arg(va, unsigned int) : va_arg(va, unsigned int); - idx = _ntoa_long(out, buffer, idx, maxlen, value, false, base, precision, width, flags); - } - } - format++; - break; - } + } else if (flags & FLAGS_LONG) { + idx = _ntoa_long( + out, + buffer, + idx, + maxlen, + va_arg(va, unsigned long), + false, + base, + precision, + width, + flags); + } else { + const unsigned int value + = (flags & FLAGS_CHAR) + ? (unsigned char)va_arg( + va, + unsigned int) + : (flags & FLAGS_SHORT) + ? (unsigned short int)va_arg( + va, + unsigned int) + : va_arg(va, + unsigned int); + idx = _ntoa_long( + out, + buffer, + idx, + maxlen, + value, + false, + base, + precision, + width, + flags); + } + } + format++; + break; + } #if defined(PRINTF_SUPPORT_FLOAT) - case 'f' : - case 'F' : - if (*format == 'F') flags |= FLAGS_UPPERCASE; - idx = _ftoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags); - format++; - break; + case 'f': + case 'F': + if (*format == 'F') + flags |= FLAGS_UPPERCASE; + idx + = _ftoa(out, + buffer, + idx, + maxlen, + va_arg(va, double), + precision, + width, + flags); + format++; + break; #if defined(PRINTF_SUPPORT_EXPONENTIAL) - case 'e': - case 'E': - case 'g': - case 'G': - if ((*format == 'g')||(*format == 'G')) flags |= FLAGS_ADAPT_EXP; - if ((*format == 'E')||(*format == 'G')) flags |= FLAGS_UPPERCASE; - idx = _etoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags); - format++; - break; -#endif // PRINTF_SUPPORT_EXPONENTIAL -#endif // PRINTF_SUPPORT_FLOAT - case 'c' : { - unsigned int l = 1U; - // pre padding - if (!(flags & FLAGS_LEFT)) { - while (l++ < width) { - out(' ', buffer, idx++, maxlen); - } - } - // char output - out((char)va_arg(va, int), buffer, idx++, maxlen); - // post padding - if (flags & FLAGS_LEFT) { - while (l++ < width) { - out(' ', buffer, idx++, maxlen); - } - } - format++; - break; - } + case 'e': + case 'E': + case 'g': + case 'G': + if ((*format == 'g') || (*format == 'G')) + flags |= FLAGS_ADAPT_EXP; + if ((*format == 'E') || (*format == 'G')) + flags |= FLAGS_UPPERCASE; + idx + = _etoa(out, + buffer, + idx, + maxlen, + va_arg(va, double), + precision, + width, + flags); + format++; + break; +#endif // PRINTF_SUPPORT_EXPONENTIAL +#endif // PRINTF_SUPPORT_FLOAT + case 'c': { + unsigned int l = 1U; + // pre padding + if (!(flags & FLAGS_LEFT)) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); + } + } + // char output + out((char)va_arg(va, int), buffer, idx++, maxlen); + // post padding + if (flags & FLAGS_LEFT) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); + } + } + format++; + break; + } - case 's' : { - const char* p = va_arg(va, char*); - unsigned int l = _strnlen_s(p, precision ? precision : (size_t)-1); - // pre padding - if (flags & FLAGS_PRECISION) { - l = (l < precision ? l : precision); - } - if (!(flags & FLAGS_LEFT)) { - while (l++ < width) { - out(' ', buffer, idx++, maxlen); - } - } - // string output - while ((*p != 0) && (!(flags & FLAGS_PRECISION) || precision--)) { - out(*(p++), buffer, idx++, maxlen); - } - // post padding - if (flags & FLAGS_LEFT) { - while (l++ < width) { - out(' ', buffer, idx++, maxlen); - } - } - format++; - break; - } + case 's': { + const char *p = va_arg(va, char *); + unsigned int l = _strnlen_s( + p, + precision ? precision : (size_t)-1); + // pre padding + if (flags & FLAGS_PRECISION) { + l = (l < precision ? l : precision); + } + if (!(flags & FLAGS_LEFT)) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); + } + } + // string output + while ((*p != 0) + && (!(flags & FLAGS_PRECISION) || precision--)) { + out(*(p++), buffer, idx++, maxlen); + } + // post padding + if (flags & FLAGS_LEFT) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); + } + } + format++; + break; + } - case 'p' : { - width = sizeof(void*) * 2U; - flags |= FLAGS_ZEROPAD | FLAGS_UPPERCASE; + case 'p': { + width = sizeof(void *) * 2U; + flags |= FLAGS_ZEROPAD | FLAGS_UPPERCASE; #if defined(PRINTF_SUPPORT_LONG_LONG) - const bool is_ll = sizeof(uintptr_t) == sizeof(long long); - if (is_ll) { - idx = _ntoa_long_long(out, buffer, idx, maxlen, (uintptr_t)va_arg(va, void*), false, 16U, precision, width, flags); - } - else { + const bool is_ll + = sizeof(uintptr_t) == sizeof(long long); + if (is_ll) { + idx = _ntoa_long_long( + out, + buffer, + idx, + maxlen, + (uintptr_t)va_arg(va, void *), + false, + 16U, + precision, + width, + flags); + } else { #endif - idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)((uintptr_t)va_arg(va, void*)), false, 16U, precision, width, flags); + idx = _ntoa_long( + out, + buffer, + idx, + maxlen, + (unsigned long)(( + uintptr_t)va_arg(va, void *)), + false, + 16U, + precision, + width, + flags); #if defined(PRINTF_SUPPORT_LONG_LONG) - } + } #endif - format++; - break; - } + format++; + break; + } - case '%' : - out('%', buffer, idx++, maxlen); - format++; - break; + case '%': + out('%', buffer, idx++, maxlen); + format++; + break; - default : - out(*format, buffer, idx++, maxlen); - format++; - break; - } - } + default: + out(*format, buffer, idx++, maxlen); + format++; + break; + } + } - // termination - out((char)0, buffer, idx < maxlen ? idx : maxlen - 1U, maxlen); + // termination + out((char)0, buffer, idx < maxlen ? idx : maxlen - 1U, maxlen); - // return written chars without terminating \0 - return (int)idx; + // return written chars without terminating \0 + return (int)idx; } - /////////////////////////////////////////////////////////////////////////////// -int snprintf(char* buffer, size_t count, const char* format, ...) +int snprintf(char *buffer, size_t count, const char *format, ...) { - va_list va; - va_start(va, format); - const int ret = _vsnprintf(_out_buffer, buffer, count, format, va); - va_end(va); - return ret; + va_list va; + va_start(va, format); + const int ret = _vsnprintf(_out_buffer, buffer, count, format, va); + va_end(va); + return ret; } -int vsnprintf(char* buffer, size_t count, const char* format, va_list va) +int vsnprintf(char *buffer, size_t count, const char *format, va_list va) { - return _vsnprintf(_out_buffer, buffer, count, format, va); + return _vsnprintf(_out_buffer, buffer, count, format, va); } -int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...) +int fctprintf( + void (*out)(char character, void *arg), + void *arg, + const char *format, + ...) { - va_list va; - va_start(va, format); - const out_fct_wrap_type out_fct_wrap = { out, arg }; - const int ret = _vsnprintf(_out_fct, (char*)(uintptr_t)&out_fct_wrap, (size_t)-1, format, va); - va_end(va); - return ret; + va_list va; + va_start(va, format); + const out_fct_wrap_type out_fct_wrap = {out, arg}; + const int ret = _vsnprintf( + _out_fct, + (char *)(uintptr_t)&out_fct_wrap, + (size_t)-1, + format, + va); + va_end(va); + return ret; } diff --git a/libc/string/memmove.c b/libc/string/memmove.c index 652fe5b..76c85b8 100644 --- a/libc/string/memmove.c +++ b/libc/string/memmove.c @@ -1,5 +1,5 @@ #include -#include +#include static void *memcpy_r(void *dest, const void *src, size_t sz) { diff --git a/libc/string/memset.c b/libc/string/memset.c index ea5d117..aa205b9 100644 --- a/libc/string/memset.c +++ b/libc/string/memset.c @@ -2,12 +2,12 @@ void *memset(void *str, int c, size_t n) { - unsigned char val = (unsigned char)c; - unsigned char *buf = str; + unsigned char val = (unsigned char)c; + unsigned char *buf = str; - for (size_t i = 0; i < n; i++) { - buf[i] = val; - } + for (size_t i = 0; i < n; i++) { + buf[i] = val; + } - return str; + return str; } diff --git a/libc/string/strcat.c b/libc/string/strcat.c index 519a8c7..cc6043c 100644 --- a/libc/string/strcat.c +++ b/libc/string/strcat.c @@ -1,4 +1,4 @@ -#include +#include char *strcat(char *dest, const char *src) { size_t start = strlen(dest), i = 0; diff --git a/libc/string/strcmp.c b/libc/string/strcmp.c index f35df9b..fd09551 100644 --- a/libc/string/strcmp.c +++ b/libc/string/strcmp.c @@ -1,19 +1,21 @@ int strcmp(const char *s1, const char *s2) { - int i; - for (i = 0; s1[i] == s2[i]; i++) - if (s1[i] == '\0') - return 0; + int i; + for (i = 0; s1[i] == s2[i]; i++) + if (s1[i] == '\0') + return 0; - return s1[i] - s2[i]; + return s1[i] - s2[i]; } int strncmp(const char *s1, const char *s2, unsigned long n) { - for (; n > 0; s1++, s2++, --n) - if (*s1 != *s2) - return ((*(unsigned char *)s1 < *(unsigned char *)s2) ? -1 : 1); - else if (*s1 == '\0') - return 0; - return 0; + for (; n > 0; s1++, s2++, --n) + if (*s1 != *s2) + return ((*(unsigned char *)s1 < *(unsigned char *)s2) + ? -1 + : 1); + else if (*s1 == '\0') + return 0; + return 0; } diff --git a/libc/string/strcpy.c b/libc/string/strcpy.c index 793f83b..18c0823 100644 --- a/libc/string/strcpy.c +++ b/libc/string/strcpy.c @@ -1,4 +1,4 @@ -#include +#include char *strcpy(char *output, const char *input) { diff --git a/libc/string/strlen.c b/libc/string/strlen.c index 77b661b..524fa0e 100644 --- a/libc/string/strlen.c +++ b/libc/string/strlen.c @@ -1,10 +1,11 @@ -#include +#include -size_t strlen(const char *str) { +size_t strlen(const char *str) +{ size_t res = 0; while (str[res]) { res++; } - + return res; } diff --git a/libc/string/strrchr.c b/libc/string/strrchr.c index 459a8fe..a6dff49 100644 --- a/libc/string/strrchr.c +++ b/libc/string/strrchr.c @@ -1,4 +1,4 @@ -#include +#include char *strrchr(const char *str, int c) { size_t len = strlen(str); diff --git a/libc/string/strtok.c b/libc/string/strtok.c index d8da72c..f0a613e 100644 --- a/libc/string/strtok.c +++ b/libc/string/strtok.c @@ -1,5 +1,5 @@ #include -#include +#include #define ALIGN (sizeof(size_t)) #define ONES ((size_t)-1 / UCHAR_MAX) diff --git a/include/mango/status.h b/libmango/include/mango/status.h similarity index 83% rename from include/mango/status.h rename to libmango/include/mango/status.h index bd05211..94f91bb 100644 --- a/include/mango/status.h +++ b/libmango/include/mango/status.h @@ -16,7 +16,8 @@ typedef unsigned int kern_status_t; #define KERN_DEVICE_STUCK (10) #define KERN_IO_ERROR (11) #define KERN_FATAL_ERROR (12) - -extern const char *kern_status_string(kern_status_t status); +#define KERN_BAD_STATE (13) +#define KERN_MEMORY_FAULT (14) +#define KERN_ACCESS_DENIED (15) #endif diff --git a/libmango/include/mango/syscall.h b/libmango/include/mango/syscall.h new file mode 100644 index 0000000..2d17fcb --- /dev/null +++ b/libmango/include/mango/syscall.h @@ -0,0 +1,35 @@ +#ifndef MANGO_SYSCALL_H_ +#define MANGO_SYSCALL_H_ + +#define SYS_TASK_EXIT 1 +#define SYS_TASK_CREATE 2 +#define SYS_TASK_CREATE_THREAD 3 +#define SYS_THREAD_START 30 +#define SYS_VM_OBJECT_CREATE 4 +#define SYS_VM_OBJECT_READ 5 +#define SYS_VM_OBJECT_WRITE 6 +#define SYS_VM_OBJECT_COPY 29 +#define SYS_VM_REGION_CREATE 7 +#define SYS_VM_REGION_READ 8 +#define SYS_VM_REGION_WRITE 9 +#define SYS_VM_REGION_MAP_ABSOLUTE 10 +#define SYS_VM_REGION_MAP_RELATIVE 11 +#define SYS_VM_REGION_UNMAP_ABSOLUTE 12 +#define SYS_VM_REGION_UNMAP_RELATIVE 13 +#define SYS_KERN_LOG 14 +#define SYS_KERN_HANDLE_CLOSE 15 +#define SYS_KERN_CONFIG_GET 16 +#define SYS_KERN_CONFIG_SET 17 +#define SYS_MSG_SEND 18 +#define SYS_MSG_RECV 19 +#define SYS_MSG_REPLY 20 +#define SYS_MSG_READ 21 +#define SYS_MSG_READ_HANDLES 22 +#define SYS_MSG_WRITE 23 +#define SYS_MSG_WRITE_HANDLES 24 +#define SYS_CHANNEL_CREATE 25 +#define SYS_PORT_CREATE 26 +#define SYS_PORT_CONNECT 27 +#define SYS_PORT_DISCONNECT 28 + +#endif diff --git a/libmango/include/mango/types.h b/libmango/include/mango/types.h new file mode 100644 index 0000000..bea455f --- /dev/null +++ b/libmango/include/mango/types.h @@ -0,0 +1,62 @@ +#ifndef MANGO_TYPES_H_ +#define MANGO_TYPES_H_ + +#include +#include + +#define VM_PROT_READ 0x01u +#define VM_PROT_WRITE 0x02u +#define VM_PROT_EXEC 0x04u +#define VM_PROT_USER 0x08u +#define VM_PROT_SVR 0x10u +#define VM_PROT_NOCACHE 0x10u +#define VM_PROT_MAP_SPECIFIC 0x40u + +/* if this flag is set, other tasks can connect to this channel using + * the port_connect_* syscalls. + * if this flag is NOT set, only threads in the task that owns the channel + * can create ports connecting to it. */ +#define CHANNEL_F_ALLOW_DIRECT_CONNECTIONS 0x01u + +/* msg_reply: once the reply has been sent, disconnect the port that sent the + * original message */ +#define MSG_F_DISCONNECT_AFTER_REPLY 0x01u + +#define VM_REGION_ANY_OFFSET ((off_t) - 1) +#define KERN_HANDLE_INVALID ((kern_handle_t)0xFFFFFFFF) + +#define KERN_CFG_INVALID 0x00u +#define KERN_CFG_PAGE_SIZE 0x01u + +typedef uintptr_t phys_addr_t; +typedef uintptr_t virt_addr_t; +typedef uint64_t msgid_t; +typedef uint64_t off_t; +typedef unsigned int tid_t; +typedef uint32_t kern_handle_t; +typedef uint32_t kern_config_key_t; +typedef uint32_t vm_prot_t; +typedef uint32_t channel_flags_t; +typedef uint32_t msg_flags_t; + +typedef unsigned int umode_t; + +struct iovec { + virt_addr_t io_base; + size_t io_len; +}; + +struct handle_list { + kern_handle_t *l_handles; + size_t l_nr_handles; +}; + +struct msg { + struct iovec *msg_data; + size_t msg_data_count; + + struct handle_list *msg_handles; + size_t msg_handles_count; +}; + +#endif diff --git a/sched/core.c b/sched/core.c index da0ff23..21d0fb4 100644 --- a/sched/core.c +++ b/sched/core.c @@ -1,10 +1,10 @@ -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include extern kern_status_t setup_kernel_task(void); extern kern_status_t setup_idle_task(void); diff --git a/sched/runqueue.c b/sched/runqueue.c index 512df7b..168db04 100644 --- a/sched/runqueue.c +++ b/sched/runqueue.c @@ -1,6 +1,6 @@ -#include -#include -#include +#include +#include +#include #define PRIO_MASK(p) (((uint32_t)1) << (p)) #define FIRST_PRIO(m) (m > 0 ? (PRIO_MAX - __builtin_clz(m) - 1) : -1) diff --git a/sched/task.c b/sched/task.c index 5122ab3..fc39780 100644 --- a/sched/task.c +++ b/sched/task.c @@ -1,12 +1,14 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #define TASK_CAST(p) OBJECT_C_CAST(struct task, t_base, &task_type, p) diff --git a/sched/thread.c b/sched/thread.c index d2d637d..36c73eb 100644 --- a/sched/thread.c +++ b/sched/thread.c @@ -1,8 +1,8 @@ -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #define THREAD_CAST(p) OBJECT_C_CAST(struct thread, thr_base, &thread_type, p) diff --git a/sched/timer.c b/sched/timer.c index 5e93e09..67055b8 100644 --- a/sched/timer.c +++ b/sched/timer.c @@ -1,7 +1,7 @@ -#include -#include -#include -#include +#include +#include +#include +#include static void timeout_expiry(struct timer *timer) { diff --git a/sched/wait.c b/sched/wait.c index d4b6661..90249c7 100644 --- a/sched/wait.c +++ b/sched/wait.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include void wait_item_init(struct wait_item *item, struct thread *thr) { diff --git a/sched/workqueue.c b/sched/workqueue.c index f567157..7374e81 100644 --- a/sched/workqueue.c +++ b/sched/workqueue.c @@ -1,7 +1,7 @@ -#include -#include -#include -#include +#include +#include +#include +#include static struct worker_pool *__global_worker_pool = NULL; diff --git a/syscall/dispatch.c b/syscall/dispatch.c index a07ab57..17bd11e 100644 --- a/syscall/dispatch.c +++ b/syscall/dispatch.c @@ -1,6 +1,6 @@ -#include -#include -#include +#include +#include +#include #define SYSCALL_TABLE_ENTRY(id, p) [SYS_##id] = (virt_addr_t)(sys_##p) diff --git a/test/obj.c b/test/obj.c index 420d8a5..5d76c35 100644 --- a/test/obj.c +++ b/test/obj.c @@ -1,7 +1,7 @@ -#include -#include -#include -#include +#include +#include +#include +#include #define TEST_CAST(p) OBJECT_C_CAST(struct test_object, base, &test_type, p) diff --git a/test/test.c b/test/test.c index 166be5c..38d3a7b 100644 --- a/test/test.c +++ b/test/test.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include int run_all_tests(void) { diff --git a/util/data_size.c b/util/data_size.c index 6d373a6..b5a4310 100644 --- a/util/data_size.c +++ b/util/data_size.c @@ -1,5 +1,5 @@ #include -#include +#include struct magnitude { size_t threshold; diff --git a/util/endian.c b/util/endian.c index 9119a27..985e7b2 100644 --- a/util/endian.c +++ b/util/endian.c @@ -1,4 +1,4 @@ -#include +#include #include static uint16_t swap_uint16( uint16_t val ) diff --git a/util/random.c b/util/random.c index eb7243c..8066477 100644 --- a/util/random.c +++ b/util/random.c @@ -1,4 +1,4 @@ -#include +#include static unsigned int random_seed = 53455346; diff --git a/vm/bootstrap.c b/vm/bootstrap.c index 3e7b319..d228c84 100644 --- a/vm/bootstrap.c +++ b/vm/bootstrap.c @@ -1,11 +1,11 @@ #include -#include -#include -#include +#include +#include +#include #include -#include -#include -#include +#include +#include +#include #include #include diff --git a/vm/cache.c b/vm/cache.c index 7dee14a..70b7f25 100644 --- a/vm/cache.c +++ b/vm/cache.c @@ -1,8 +1,8 @@ -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include #define FREELIST_END ((unsigned int)-1) diff --git a/vm/flat.c b/vm/flat.c index df33ee9..ab762e3 100644 --- a/vm/flat.c +++ b/vm/flat.c @@ -15,9 +15,9 @@ memory outstripts free memory), the sparse memory model may be a better choice. */ -#include -#include -#include +#include +#include +#include /* array of pages, one for each physical page frame present in RAM */ static struct vm_page *page_array = NULL; diff --git a/vm/kmalloc.c b/vm/kmalloc.c index afb9219..04e419a 100644 --- a/vm/kmalloc.c +++ b/vm/kmalloc.c @@ -1,8 +1,8 @@ -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #define SIZE_N_CACHE(s) \ { .c_name = "size-" # s, .c_obj_size = s, .c_page_order = VM_PAGE_16K } diff --git a/vm/memblock.c b/vm/memblock.c index 51891ab..86f0263 100644 --- a/vm/memblock.c +++ b/vm/memblock.c @@ -20,9 +20,9 @@ software without specific prior written permission. */ #include -#include -#include -#include +#include +#include +#include #include #define MIN(a, b) ((a) < (b) ? (a) : (b)) diff --git a/vm/model.c b/vm/model.c index 63009fc..12d2d0c 100644 --- a/vm/model.c +++ b/vm/model.c @@ -1,4 +1,4 @@ -#include +#include static enum vm_model model; diff --git a/vm/page.c b/vm/page.c index 3ce268c..1e18cc4 100644 --- a/vm/page.c +++ b/vm/page.c @@ -1,8 +1,8 @@ -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include /* Pre-calculated page order -> size conversion table */ static size_t page_order_bytes[] = { diff --git a/vm/sparse.c b/vm/sparse.c index f0663c2..14f0d77 100644 --- a/vm/sparse.c +++ b/vm/sparse.c @@ -22,14 +22,14 @@ of the sparse memory model may be outweighed by the extra overhead, and the flat memory model may be a better choice. */ -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include static struct vm_sector *sector_array = NULL; static size_t sector_array_count = 0; diff --git a/vm/vm-object.c b/vm/vm-object.c index bf6df7a..ae3ae7d 100644 --- a/vm/vm-object.c +++ b/vm/vm-object.c @@ -1,5 +1,6 @@ -#include -#include +#include +#include +#include #define VM_OBJECT_CAST(p) \ OBJECT_C_CAST(struct vm_object, vo_base, &vm_object_type, p) diff --git a/vm/vm-region.c b/vm/vm-region.c index a76a710..49c1e55 100644 --- a/vm/vm-region.c +++ b/vm/vm-region.c @@ -1,11 +1,12 @@ -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include -#include -#include /*** STATIC DATA + MACROS *****************************************************/ diff --git a/vm/zone.c b/vm/zone.c index 75782a5..fc7d012 100644 --- a/vm/zone.c +++ b/vm/zone.c @@ -1,12 +1,12 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include static struct vm_page *group_pages_into_block(struct vm_zone *z, phys_addr_t base, phys_addr_t limit, int order) {