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.
This commit is contained in:
@@ -40,6 +40,7 @@ add_executable(${kernel_exe_name}
|
|||||||
target_include_directories(${kernel_exe_name} PRIVATE
|
target_include_directories(${kernel_exe_name} PRIVATE
|
||||||
include
|
include
|
||||||
libc/include
|
libc/include
|
||||||
|
libmango/include
|
||||||
arch/${kernel_arch}/include)
|
arch/${kernel_arch}/include)
|
||||||
target_compile_options(${kernel_exe_name} PRIVATE
|
target_compile_options(${kernel_exe_name} PRIVATE
|
||||||
-nostdlib -ffreestanding
|
-nostdlib -ffreestanding
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <mango/machine/cpu.h>
|
#include <kernel/machine/cpu.h>
|
||||||
|
|
||||||
int ml_init_bootcpu(void)
|
int ml_init_bootcpu(void)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#include <mango/machine/hwlock.h>
|
#include <kernel/machine/hwlock.h>
|
||||||
#include <mango/compiler.h>
|
#include <kernel/compiler.h>
|
||||||
|
|
||||||
void ml_hwlock_lock(ml_hwlock_t *lck)
|
void ml_hwlock_lock(ml_hwlock_t *lck)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <mango/init.h>
|
#include <kernel/init.h>
|
||||||
#include <mango/memblock.h>
|
#include <kernel/memblock.h>
|
||||||
#include <mango/vm.h>
|
#include <kernel/vm.h>
|
||||||
#include <mango/object.h>
|
#include <kernel/object.h>
|
||||||
#include <mango/printk.h>
|
#include <kernel/printk.h>
|
||||||
#include <arch/stdcon.h>
|
#include <arch/stdcon.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#include <mango/init.h>
|
#include <kernel/init.h>
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
extern char __start_initcall0[] __asm("section$start$__DATA$__initcall0.init");
|
extern char __start_initcall0[] __asm("section$start$__DATA$__initcall0.init");
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
#include <mango/libc/string.h>
|
#include <kernel/libc/string.h>
|
||||||
#include <mango/libc/ctype.h>
|
#include <kernel/libc/ctype.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <mango/console.h>
|
#include <kernel/console.h>
|
||||||
#include <mango/vm.h>
|
#include <kernel/vm.h>
|
||||||
#include <mango/printk.h>
|
#include <kernel/printk.h>
|
||||||
|
|
||||||
static void stdcon_write(struct console *con, const char *s, unsigned int len)
|
static void stdcon_write(struct console *con, const char *s, unsigned int len)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#include <mango/sched.h>
|
#include <kernel/sched.h>
|
||||||
#include <mango/compiler.h>
|
#include <kernel/compiler.h>
|
||||||
|
|
||||||
//size_t THREAD_sp = offsetof(struct thread, tr_sp);
|
//size_t THREAD_sp = offsetof(struct thread, tr_sp);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#include <arch/msr.h>
|
#include <arch/msr.h>
|
||||||
#include <mango/machine/cpu.h>
|
#include <kernel/machine/cpu.h>
|
||||||
|
|
||||||
int ml_cpu_block_init(ml_cpu_block *p)
|
int ml_cpu_block_init(ml_cpu_block *p)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#include "mango/types.h"
|
|
||||||
#include <mango/memblock.h>
|
|
||||||
#include <mango/printk.h>
|
|
||||||
#include <mango/util.h>
|
|
||||||
#include <arch/e820.h>
|
#include <arch/e820.h>
|
||||||
|
#include <kernel/memblock.h>
|
||||||
|
#include <kernel/printk.h>
|
||||||
|
#include <kernel/types.h>
|
||||||
|
#include <kernel/util.h>
|
||||||
|
|
||||||
void e820_scan(multiboot_memory_map_t *mmap, size_t len)
|
void e820_scan(multiboot_memory_map_t *mmap, size_t len)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#include <arch/gdt.h>
|
#include <arch/gdt.h>
|
||||||
#include <arch/tss.h>
|
#include <arch/tss.h>
|
||||||
#include <mango/libc/string.h>
|
#include <kernel/libc/string.h>
|
||||||
#include <mango/types.h>
|
#include <kernel/types.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
static void init_entry(struct gdt_entry *entry, int access, int flags)
|
static void init_entry(struct gdt_entry *entry, int access, int flags)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
#define ARCH_GDT_H_
|
#define ARCH_GDT_H_
|
||||||
|
|
||||||
#include <arch/tss.h>
|
#include <arch/tss.h>
|
||||||
#include <mango/compiler.h>
|
#include <kernel/compiler.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#ifndef ARCH_IRQ_H_
|
#ifndef ARCH_IRQ_H_
|
||||||
#define ARCH_IRQ_H_
|
#define ARCH_IRQ_H_
|
||||||
|
|
||||||
#include <mango/compiler.h>
|
#include <kernel/compiler.h>
|
||||||
#include <mango/queue.h>
|
#include <kernel/queue.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#ifndef ARCH_PAGING_H_
|
#ifndef ARCH_PAGING_H_
|
||||||
#define ARCH_PAGING_H_
|
#define ARCH_PAGING_H_
|
||||||
|
|
||||||
#include <mango/types.h>
|
#include <kernel/types.h>
|
||||||
#include <mango/compiler.h>
|
#include <kernel/compiler.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#ifndef ARCH_TSS_H_
|
#ifndef ARCH_TSS_H_
|
||||||
#define ARCH_TSS_H_
|
#define ARCH_TSS_H_
|
||||||
|
|
||||||
#include <mango/compiler.h>
|
#include <kernel/compiler.h>
|
||||||
#include <mango/types.h>
|
#include <kernel/types.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define TSS_GDT_INDEX 5
|
#define TSS_GDT_INDEX 5
|
||||||
|
|||||||
@@ -1,73 +0,0 @@
|
|||||||
#ifndef MANGO_X86_64_CPU_H_
|
|
||||||
#define MANGO_X86_64_CPU_H_
|
|
||||||
|
|
||||||
#include <arch/gdt.h>
|
|
||||||
#include <arch/irq.h>
|
|
||||||
#include <arch/tss.h>
|
|
||||||
#include <mango/types.h>
|
|
||||||
|
|
||||||
#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
|
|
||||||
@@ -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
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
#ifndef MANGO_X86_64_INIT_H_
|
|
||||||
#define MANGO_X86_64_INIT_H_
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#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
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
#ifndef MANGO_X86_64_IRQ_H_
|
|
||||||
#define MANGO_X86_64_IRQ_H_
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
#ifndef MANGO_X86_64_PANIC_H_
|
|
||||||
#define MANGO_X86_64_PANIC_H_
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
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
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
#ifndef MANGO_X86_64_PMAP_H_
|
|
||||||
#define MANGO_X86_64_PMAP_H_
|
|
||||||
|
|
||||||
#include <arch/paging.h>
|
|
||||||
|
|
||||||
#define ML_PMAP_INVALID ((uintptr_t)-1)
|
|
||||||
|
|
||||||
typedef pml4t_ptr_t ml_pmap_t;
|
|
||||||
typedef uint64_t ml_pfn_t;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
#ifndef MANGO_X86_64_THREAD_H_
|
|
||||||
#define MANGO_X86_64_THREAD_H_
|
|
||||||
|
|
||||||
#include <mango/sched.h>
|
|
||||||
|
|
||||||
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
|
|
||||||
@@ -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
|
|
||||||
@@ -2,21 +2,21 @@
|
|||||||
#include <arch/pit.h>
|
#include <arch/pit.h>
|
||||||
#include <arch/serial.h>
|
#include <arch/serial.h>
|
||||||
#include <arch/vgacon.h>
|
#include <arch/vgacon.h>
|
||||||
#include <mango/arg.h>
|
#include <kernel/arg.h>
|
||||||
#include <mango/bsp.h>
|
#include <kernel/bsp.h>
|
||||||
#include <mango/clock.h>
|
#include <kernel/clock.h>
|
||||||
#include <mango/console.h>
|
#include <kernel/console.h>
|
||||||
#include <mango/cpu.h>
|
#include <kernel/cpu.h>
|
||||||
#include <mango/init.h>
|
#include <kernel/init.h>
|
||||||
#include <mango/libc/stdio.h>
|
#include <kernel/libc/stdio.h>
|
||||||
#include <mango/machine/cpu.h>
|
#include <kernel/machine/cpu.h>
|
||||||
#include <mango/memblock.h>
|
#include <kernel/memblock.h>
|
||||||
#include <mango/object.h>
|
#include <kernel/object.h>
|
||||||
#include <mango/percpu.h>
|
#include <kernel/percpu.h>
|
||||||
#include <mango/pmap.h>
|
#include <kernel/pmap.h>
|
||||||
#include <mango/printk.h>
|
#include <kernel/printk.h>
|
||||||
#include <mango/types.h>
|
#include <kernel/types.h>
|
||||||
#include <mango/vm.h>
|
#include <kernel/vm.h>
|
||||||
|
|
||||||
#define PTR32(x) ((void *)((uintptr_t)(x)))
|
#define PTR32(x) ((void *)((uintptr_t)(x)))
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#include <mango/init.h>
|
#include <kernel/init.h>
|
||||||
|
|
||||||
extern char __initcall0_start[];
|
extern char __initcall0_start[];
|
||||||
extern char __initcall1_start[];
|
extern char __initcall1_start[];
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
#include <arch/irq.h>
|
#include <arch/irq.h>
|
||||||
#include <arch/msr.h>
|
#include <arch/msr.h>
|
||||||
#include <arch/ports.h>
|
#include <arch/ports.h>
|
||||||
#include <mango/cpu.h>
|
#include <kernel/cpu.h>
|
||||||
#include <mango/libc/string.h>
|
#include <kernel/libc/string.h>
|
||||||
#include <mango/machine/cpu.h>
|
#include <kernel/machine/cpu.h>
|
||||||
#include <mango/machine/irq.h>
|
#include <kernel/machine/irq.h>
|
||||||
#include <mango/panic.h>
|
#include <kernel/panic.h>
|
||||||
#include <mango/sched.h>
|
#include <kernel/sched.h>
|
||||||
#include <mango/syscall.h>
|
#include <kernel/syscall.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#define MAX_ISR_HANDLERS 16
|
#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)
|
static void set_syscall_gate(uintptr_t rip)
|
||||||
{
|
{
|
||||||
uint64_t user_cs = 0x13;
|
uint64_t user_cs = 0x13;
|
||||||
uint64_t kernel_cs = 0x8;
|
uint64_t kernel_cs = 0x08;
|
||||||
|
|
||||||
uintptr_t star_reg = 0xC0000081;
|
uintptr_t star_reg = 0xC0000081;
|
||||||
uintptr_t lstar_reg = 0xC0000082;
|
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();
|
virt_addr_t fault_ptr = pf_faultptr();
|
||||||
|
|
||||||
kern_status_t status = KERN_FATAL_ERROR;
|
kern_status_t status = pmap_handle_fault(fault_ptr, fault_flags);
|
||||||
|
|
||||||
if (regs->err_no & PF_USER) {
|
|
||||||
status = pmap_handle_fault(fault_ptr, fault_flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status == KERN_OK) {
|
if (status == KERN_OK) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
#include <arch/irq.h>
|
#include <arch/irq.h>
|
||||||
#include <mango/libc/stdio.h>
|
#include <kernel/libc/stdio.h>
|
||||||
#include <mango/machine/cpu.h>
|
#include <kernel/machine/cpu.h>
|
||||||
#include <mango/machine/panic.h>
|
#include <kernel/machine/panic.h>
|
||||||
#include <mango/printk.h>
|
#include <kernel/printk.h>
|
||||||
#include <mango/vm.h>
|
#include <kernel/vm.h>
|
||||||
|
|
||||||
#define R_CF 0
|
#define R_CF 0
|
||||||
#define R_PF 2
|
#define R_PF 2
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#include <arch/irq.h>
|
#include <arch/irq.h>
|
||||||
#include <arch/ports.h>
|
#include <arch/ports.h>
|
||||||
#include <mango/clock.h>
|
#include <kernel/clock.h>
|
||||||
#include <mango/cpu.h>
|
#include <kernel/cpu.h>
|
||||||
#include <mango/printk.h>
|
#include <kernel/printk.h>
|
||||||
|
|
||||||
#define PIT_COUNTER0 0x40
|
#define PIT_COUNTER0 0x40
|
||||||
#define PIT_CMD 0x43
|
#define PIT_CMD 0x43
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
#include <mango/compiler.h>
|
#include <kernel/compiler.h>
|
||||||
#include <mango/libc/stdio.h>
|
#include <kernel/libc/stdio.h>
|
||||||
#include <mango/memblock.h>
|
#include <kernel/memblock.h>
|
||||||
#include <mango/pmap.h>
|
#include <kernel/pmap.h>
|
||||||
#include <mango/printk.h>
|
#include <kernel/printk.h>
|
||||||
#include <mango/sched.h>
|
#include <kernel/sched.h>
|
||||||
|
#include <kernel/types.h>
|
||||||
|
#include <kernel/vm-object.h>
|
||||||
|
#include <kernel/vm-region.h>
|
||||||
|
#include <kernel/vm.h>
|
||||||
#include <mango/status.h>
|
#include <mango/status.h>
|
||||||
#include <mango/types.h>
|
|
||||||
#include <mango/vm-object.h>
|
|
||||||
#include <mango/vm-region.h>
|
|
||||||
#include <mango/vm.h>
|
|
||||||
|
|
||||||
/* some helpful datasize constants */
|
/* some helpful datasize constants */
|
||||||
#define C_1GiB 0x40000000ULL
|
#define C_1GiB 0x40000000ULL
|
||||||
@@ -43,7 +43,7 @@ static pmap_t alloc_pmap(void)
|
|||||||
return vm_virt_to_phys(p);
|
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;
|
pte_t v = pfn;
|
||||||
|
|
||||||
@@ -139,7 +139,7 @@ static kern_status_t do_pmap_add(
|
|||||||
pmap_t pmap,
|
pmap_t pmap,
|
||||||
virt_addr_t pv,
|
virt_addr_t pv,
|
||||||
pfn_t pfn,
|
pfn_t pfn,
|
||||||
enum vm_prot prot,
|
vm_prot_t prot,
|
||||||
enum page_size size)
|
enum page_size size)
|
||||||
{
|
{
|
||||||
unsigned int pml4t_index = BAD_INDEX, pdpt_index = BAD_INDEX,
|
unsigned int pml4t_index = BAD_INDEX, pdpt_index = BAD_INDEX,
|
||||||
@@ -371,7 +371,7 @@ kern_status_t pmap_add(
|
|||||||
pmap_t pmap,
|
pmap_t pmap,
|
||||||
virt_addr_t p,
|
virt_addr_t p,
|
||||||
pfn_t pfn,
|
pfn_t pfn,
|
||||||
enum vm_prot prot,
|
vm_prot_t prot,
|
||||||
enum pmap_flags flags)
|
enum pmap_flags flags)
|
||||||
{
|
{
|
||||||
enum page_size ps = PS_4K;
|
enum page_size ps = PS_4K;
|
||||||
@@ -387,7 +387,7 @@ kern_status_t pmap_add_block(
|
|||||||
virt_addr_t p,
|
virt_addr_t p,
|
||||||
pfn_t pfn,
|
pfn_t pfn,
|
||||||
size_t len,
|
size_t len,
|
||||||
enum vm_prot prot,
|
vm_prot_t prot,
|
||||||
enum pmap_flags flags)
|
enum pmap_flags flags)
|
||||||
{
|
{
|
||||||
return KERN_OK;
|
return KERN_OK;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#include <arch/irq.h>
|
#include <arch/irq.h>
|
||||||
#include <arch/ports.h>
|
#include <arch/ports.h>
|
||||||
#include <arch/serial.h>
|
#include <arch/serial.h>
|
||||||
#include <mango/libc/stdio.h>
|
#include <kernel/libc/stdio.h>
|
||||||
#include <mango/printk.h>
|
#include <kernel/printk.h>
|
||||||
|
|
||||||
#define COM1 0x3F8
|
#define COM1 0x3F8
|
||||||
#define COM2 0x2F8
|
#define COM2 0x2F8
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#include <mango/machine/cpu.h>
|
#include <kernel/machine/cpu.h>
|
||||||
#include <mango/machine/thread.h>
|
#include <kernel/machine/thread.h>
|
||||||
|
|
||||||
/* this is the context information restored by ml_thread_switch.
|
/* this is the context information restored by ml_thread_switch.
|
||||||
* since ml_thread_switch only jumps to kernel-mode, IRETQ isn't used,
|
* since ml_thread_switch only jumps to kernel-mode, IRETQ isn't used,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include <arch/gdt.h>
|
#include <arch/gdt.h>
|
||||||
#include <arch/tss.h>
|
#include <arch/tss.h>
|
||||||
#include <mango/libc/string.h>
|
#include <kernel/libc/string.h>
|
||||||
|
|
||||||
static void tss_flush(int index)
|
static void tss_flush(int index)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
#include <arch/irq.h>
|
#include <arch/irq.h>
|
||||||
#include <arch/ports.h>
|
#include <arch/ports.h>
|
||||||
#include <arch/serial.h>
|
#include <arch/serial.h>
|
||||||
#include <mango/libc/stdio.h>
|
#include <kernel/libc/stdio.h>
|
||||||
#include <mango/machine/vm.h>
|
#include <kernel/machine/vm.h>
|
||||||
#include <mango/printk.h>
|
#include <kernel/printk.h>
|
||||||
|
|
||||||
struct vga_console {
|
struct vga_console {
|
||||||
uint16_t *vga_framebuffer;
|
uint16_t *vga_framebuffer;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#include <mango/bitmap.h>
|
#include <kernel/bitmap.h>
|
||||||
#include <mango/libc/string.h>
|
#include <kernel/libc/string.h>
|
||||||
|
|
||||||
void bitmap_zero(unsigned long *map, unsigned long nbits)
|
void bitmap_zero(unsigned long *map, unsigned long nbits)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -57,7 +57,7 @@
|
|||||||
provide a comparator function.
|
provide a comparator function.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <mango/btree.h>
|
#include <kernel/btree.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#include <mango/queue.h>
|
#include <kernel/queue.h>
|
||||||
|
|
||||||
size_t queue_length(struct queue *q)
|
size_t queue_length(struct queue *q)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#include <mango/ringbuffer.h>
|
#include <kernel/ringbuffer.h>
|
||||||
#include <mango/sched.h>
|
#include <kernel/sched.h>
|
||||||
|
|
||||||
size_t ringbuffer_unread(struct ringbuffer *ring_buffer)
|
size_t ringbuffer_unread(struct ringbuffer *ring_buffer)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
#ifndef MANGO_ARG_H_
|
|
||||||
#define MANGO_ARG_H_
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <mango/status.h>
|
|
||||||
|
|
||||||
#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
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
#ifndef MANGO_BITMAP_H_
|
|
||||||
#define MANGO_BITMAP_H_
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#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
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
#ifndef MANGO_BSP_H_
|
|
||||||
#define MANGO_BSP_H_
|
|
||||||
|
|
||||||
#include <mango/compiler.h>
|
|
||||||
#include <mango/status.h>
|
|
||||||
#include <mango/types.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#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
|
|
||||||
@@ -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 <stdint.h>
|
|
||||||
|
|
||||||
#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
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
#ifndef MANGO_CLOCK_H_
|
|
||||||
#define MANGO_CLOCK_H_
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#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
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
#ifndef MANGO_COMPILER_H_
|
|
||||||
#define MANGO_COMPILER_H_
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
template <typename T>
|
|
||||||
T read_once(const volatile T *ptr)
|
|
||||||
{
|
|
||||||
return *ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
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
|
|
||||||
@@ -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 <mango/queue.h>
|
|
||||||
#include <mango/locks.h>
|
|
||||||
#include <mango/status.h>
|
|
||||||
|
|
||||||
#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
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
#ifndef MANGO_CPU_H_
|
|
||||||
#define MANGO_CPU_H_
|
|
||||||
|
|
||||||
#include <mango/types.h>
|
|
||||||
#include <mango/machine/cpu.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <mango/sched.h>
|
|
||||||
|
|
||||||
#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
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
#ifndef MANGO_FB_H_
|
|
||||||
#define MANGO_FB_H_
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
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
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
#ifndef MANGO_FLAGS_H_
|
|
||||||
#define MANGO_FLAGS_H_
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
S_NORMAL = 0x00u,
|
|
||||||
S_NOBLOCK = 0x01u,
|
|
||||||
} mango_flags_t;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
#ifndef MANGO_HANDLE_H_
|
|
||||||
#define MANGO_HANDLE_H_
|
|
||||||
|
|
||||||
#include <mango/bitmap.h>
|
|
||||||
#include <mango/status.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
/* 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
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
#ifndef MANGO_INIT_H_
|
|
||||||
#define MANGO_INIT_H_
|
|
||||||
|
|
||||||
#include <mango/compiler.h>
|
|
||||||
#include <mango/machine/init.h>
|
|
||||||
|
|
||||||
#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
|
|
||||||
@@ -1,184 +0,0 @@
|
|||||||
#ifndef MANGO_INPUT_H_
|
|
||||||
#define MANGO_INPUT_H_
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <mango/queue.h>
|
|
||||||
#include <mango/status.h>
|
|
||||||
|
|
||||||
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
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
#ifndef MANGO_LOCKS_H_
|
|
||||||
#define MANGO_LOCKS_H_
|
|
||||||
|
|
||||||
#include <mango/compiler.h>
|
|
||||||
#include <mango/machine/hwlock.h>
|
|
||||||
|
|
||||||
#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
|
|
||||||
@@ -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 <limits.h>
|
|
||||||
#include <mango/types.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#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
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
#ifndef MANGO_OBJECT_H_
|
|
||||||
#define MANGO_OBJECT_H_
|
|
||||||
|
|
||||||
#include <mango/flags.h>
|
|
||||||
#include <mango/locks.h>
|
|
||||||
#include <mango/status.h>
|
|
||||||
#include <mango/vm.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#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
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
#ifndef MANGO_PANIC_H_
|
|
||||||
#define MANGO_PANIC_H_
|
|
||||||
|
|
||||||
#include <mango/compiler.h>
|
|
||||||
|
|
||||||
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
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
#ifndef MANGO_PERCPU_H_
|
|
||||||
#define MANGO_PERCPU_H_
|
|
||||||
|
|
||||||
#include <mango/status.h>
|
|
||||||
#include <mango/compiler.h>
|
|
||||||
#include <mango/sched.h>
|
|
||||||
|
|
||||||
#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
|
|
||||||
@@ -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 <mango/machine/pmap.h>
|
|
||||||
#include <mango/status.h>
|
|
||||||
#include <mango/vm.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#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
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
#ifndef MANGO_PRINTK_H_
|
|
||||||
#define MANGO_PRINTK_H_
|
|
||||||
|
|
||||||
#include <mango/console.h>
|
|
||||||
|
|
||||||
#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
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
#ifndef MANGO_QUEUE_H_
|
|
||||||
#define MANGO_QUEUE_H_
|
|
||||||
|
|
||||||
#include <mango/libc/string.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#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
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
#ifndef MANGO_RINGBUFFER_H_
|
|
||||||
#define MANGO_RINGBUFFER_H_
|
|
||||||
|
|
||||||
#include <mango/locks.h>
|
|
||||||
#include <mango/sched.h>
|
|
||||||
|
|
||||||
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
|
|
||||||
@@ -1,250 +0,0 @@
|
|||||||
#ifndef MANGO_SCHED_H_
|
|
||||||
#define MANGO_SCHED_H_
|
|
||||||
|
|
||||||
#include <mango/btree.h>
|
|
||||||
#include <mango/locks.h>
|
|
||||||
#include <mango/object.h>
|
|
||||||
#include <mango/pmap.h>
|
|
||||||
#include <mango/queue.h>
|
|
||||||
#include <mango/status.h>
|
|
||||||
|
|
||||||
#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
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
#ifndef MANGO_SYSCALL_H_
|
|
||||||
#define MANGO_SYSCALL_H_
|
|
||||||
|
|
||||||
#include <mango/handle.h>
|
|
||||||
#include <mango/status.h>
|
|
||||||
#include <mango/vm.h>
|
|
||||||
|
|
||||||
#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
|
|
||||||
@@ -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
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
#ifndef MANGO_TYPES_H_
|
|
||||||
#define MANGO_TYPES_H_
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#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
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
#ifndef MANGO_UTIL_H_
|
|
||||||
#define MANGO_UTIL_H_
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#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
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
#ifndef MANGO_VM_OBJECT_H_
|
|
||||||
#define MANGO_VM_OBJECT_H_
|
|
||||||
|
|
||||||
#include <mango/locks.h>
|
|
||||||
#include <mango/object.h>
|
|
||||||
|
|
||||||
#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
|
|
||||||
@@ -1,115 +0,0 @@
|
|||||||
#ifndef MANGO_VM_REGION_H_
|
|
||||||
#define MANGO_VM_REGION_H_
|
|
||||||
|
|
||||||
#include <mango/object.h>
|
|
||||||
#include <mango/pmap.h>
|
|
||||||
#include <mango/vm.h>
|
|
||||||
|
|
||||||
#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
|
|
||||||
@@ -1,367 +0,0 @@
|
|||||||
#ifndef MANGO_VM_H_
|
|
||||||
#define MANGO_VM_H_
|
|
||||||
|
|
||||||
#include <mango/bitmap.h>
|
|
||||||
#include <mango/btree.h>
|
|
||||||
#include <mango/locks.h>
|
|
||||||
#include <mango/machine/vm.h>
|
|
||||||
#include <mango/queue.h>
|
|
||||||
#include <mango/status.h>
|
|
||||||
#include <mango/types.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#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
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
#include <mango/init.h>
|
#include <kernel/init.h>
|
||||||
|
|
||||||
|
|
||||||
int do_initcalls(void)
|
int do_initcalls(void)
|
||||||
{
|
{
|
||||||
|
|||||||
32
init/main.c
32
init/main.c
@@ -1,18 +1,20 @@
|
|||||||
#include <mango/arg.h>
|
#include <kernel/arg.h>
|
||||||
#include <mango/bsp.h>
|
#include <kernel/bsp.h>
|
||||||
#include <mango/clock.h>
|
#include <kernel/channel.h>
|
||||||
#include <mango/cpu.h>
|
#include <kernel/clock.h>
|
||||||
#include <mango/handle.h>
|
#include <kernel/cpu.h>
|
||||||
#include <mango/init.h>
|
#include <kernel/handle.h>
|
||||||
#include <mango/input.h>
|
#include <kernel/init.h>
|
||||||
#include <mango/libc/stdio.h>
|
#include <kernel/input.h>
|
||||||
#include <mango/machine/init.h>
|
#include <kernel/libc/stdio.h>
|
||||||
#include <mango/object.h>
|
#include <kernel/machine/init.h>
|
||||||
#include <mango/panic.h>
|
#include <kernel/object.h>
|
||||||
#include <mango/printk.h>
|
#include <kernel/panic.h>
|
||||||
#include <mango/sched.h>
|
#include <kernel/port.h>
|
||||||
#include <mango/test.h>
|
#include <kernel/printk.h>
|
||||||
#include <mango/vm-object.h>
|
#include <kernel/sched.h>
|
||||||
|
#include <kernel/test.h>
|
||||||
|
#include <kernel/vm-object.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
extern unsigned long get_rflags(void);
|
extern unsigned long get_rflags(void);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#include <mango/arg.h>
|
#include <kernel/arg.h>
|
||||||
#include <mango/libc/string.h>
|
#include <kernel/libc/string.h>
|
||||||
#include <mango/libc/ctype.h>
|
#include <kernel/libc/ctype.h>
|
||||||
|
|
||||||
static char g_cmdline[CMDLINE_MAX + 1] = {0};
|
static char g_cmdline[CMDLINE_MAX + 1] = {0};
|
||||||
|
|
||||||
|
|||||||
13
kernel/bsp.c
13
kernel/bsp.c
@@ -1,9 +1,10 @@
|
|||||||
#include <mango/bsp.h>
|
#include <kernel/bsp.h>
|
||||||
#include <mango/printk.h>
|
#include <kernel/handle.h>
|
||||||
#include <mango/sched.h>
|
#include <kernel/printk.h>
|
||||||
#include <mango/util.h>
|
#include <kernel/sched.h>
|
||||||
#include <mango/vm-object.h>
|
#include <kernel/util.h>
|
||||||
#include <mango/vm-region.h>
|
#include <kernel/vm-object.h>
|
||||||
|
#include <kernel/vm-region.h>
|
||||||
|
|
||||||
#define BOOTSTRAP_STACK_SIZE 0x10000
|
#define BOOTSTRAP_STACK_SIZE 0x10000
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#include <mango/clock.h>
|
#include <kernel/clock.h>
|
||||||
#include <mango/printk.h>
|
#include <kernel/printk.h>
|
||||||
#include <mango/compiler.h>
|
#include <kernel/compiler.h>
|
||||||
|
|
||||||
static clock_ticks_t ticks_per_sec = 0;
|
static clock_ticks_t ticks_per_sec = 0;
|
||||||
volatile clock_ticks_t clock_ticks = 0;
|
volatile clock_ticks_t clock_ticks = 0;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#include <mango/console.h>
|
#include <kernel/console.h>
|
||||||
#include <mango/queue.h>
|
#include <kernel/queue.h>
|
||||||
#include <mango/locks.h>
|
#include <kernel/locks.h>
|
||||||
#include <mango/libc/string.h>
|
#include <kernel/libc/string.h>
|
||||||
|
|
||||||
static struct queue consoles;
|
static struct queue consoles;
|
||||||
static spin_lock_t consoles_lock = SPIN_LOCK_INIT;
|
static spin_lock_t consoles_lock = SPIN_LOCK_INIT;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#include <mango/cpu.h>
|
#include <kernel/cpu.h>
|
||||||
#include <mango/percpu.h>
|
#include <kernel/percpu.h>
|
||||||
#include <mango/bitmap.h>
|
#include <kernel/bitmap.h>
|
||||||
|
|
||||||
DECLARE_BITMAP(cpu_available, CPU_MAX);
|
DECLARE_BITMAP(cpu_available, CPU_MAX);
|
||||||
DECLARE_BITMAP(cpu_online, CPU_MAX);
|
DECLARE_BITMAP(cpu_online, CPU_MAX);
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
#include <mango/handle.h>
|
#include <kernel/handle.h>
|
||||||
#include <mango/libc/string.h>
|
#include <kernel/libc/string.h>
|
||||||
#include <mango/object.h>
|
#include <kernel/object.h>
|
||||||
#include <mango/vm.h>
|
#include <kernel/sched.h>
|
||||||
|
#include <kernel/util.h>
|
||||||
|
#include <kernel/vm.h>
|
||||||
|
|
||||||
/* depth=3 gives a maximum of ~66.6 million handles */
|
/* depth=3 gives a maximum of ~66.6 million handles */
|
||||||
#define MAX_TABLE_DEPTH 3
|
#define MAX_TABLE_DEPTH 3
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#include <mango/locks.h>
|
#include <kernel/locks.h>
|
||||||
#include <mango/object.h>
|
#include <kernel/object.h>
|
||||||
#include <mango/queue.h>
|
#include <kernel/queue.h>
|
||||||
|
|
||||||
#define HAS_OP(obj, opname) ((obj)->ob_type->ob_ops.opname)
|
#define HAS_OP(obj, opname) ((obj)->ob_type->ob_ops.opname)
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#include <mango/cpu.h>
|
#include <kernel/cpu.h>
|
||||||
#include <mango/libc/stdio.h>
|
#include <kernel/libc/stdio.h>
|
||||||
#include <mango/machine/panic.h>
|
#include <kernel/machine/panic.h>
|
||||||
#include <mango/printk.h>
|
#include <kernel/printk.h>
|
||||||
#include <mango/sched.h>
|
#include <kernel/sched.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
static int has_panicked = 0;
|
static int has_panicked = 0;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#include <mango/percpu.h>
|
#include <kernel/percpu.h>
|
||||||
#include <mango/cpu.h>
|
#include <kernel/cpu.h>
|
||||||
#include <mango/vm.h>
|
#include <kernel/vm.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#include <mango/printk.h>
|
#include <kernel/printk.h>
|
||||||
#include <mango/locks.h>
|
#include <kernel/locks.h>
|
||||||
#include <mango/console.h>
|
#include <kernel/console.h>
|
||||||
#include <mango/libc/stdio.h>
|
#include <kernel/libc/stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
#define LOG_BUFFER_SIZE 0x40000
|
#define LOG_BUFFER_SIZE 0x40000
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
#ifndef MANGO_STDIO_H_
|
|
||||||
#define MANGO_STDIO_H_
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#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
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
#ifndef MANGO_LIBC_STRING_H_
|
|
||||||
#define MANGO_LIBC_STRING_H_
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#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
|
|
||||||
1616
libc/stdio/printf.c
1616
libc/stdio/printf.c
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <mango/libc/string.h>
|
#include <kernel/libc/string.h>
|
||||||
|
|
||||||
static void *memcpy_r(void *dest, const void *src, size_t sz)
|
static void *memcpy_r(void *dest, const void *src, size_t sz)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,12 +2,12 @@
|
|||||||
|
|
||||||
void *memset(void *str, int c, size_t n)
|
void *memset(void *str, int c, size_t n)
|
||||||
{
|
{
|
||||||
unsigned char val = (unsigned char)c;
|
unsigned char val = (unsigned char)c;
|
||||||
unsigned char *buf = str;
|
unsigned char *buf = str;
|
||||||
|
|
||||||
for (size_t i = 0; i < n; i++) {
|
for (size_t i = 0; i < n; i++) {
|
||||||
buf[i] = val;
|
buf[i] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#include <mango/libc/string.h>
|
#include <kernel/libc/string.h>
|
||||||
|
|
||||||
char *strcat(char *dest, const char *src) {
|
char *strcat(char *dest, const char *src) {
|
||||||
size_t start = strlen(dest), i = 0;
|
size_t start = strlen(dest), i = 0;
|
||||||
|
|||||||
@@ -1,19 +1,21 @@
|
|||||||
int strcmp(const char *s1, const char *s2)
|
int strcmp(const char *s1, const char *s2)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; s1[i] == s2[i]; i++)
|
for (i = 0; s1[i] == s2[i]; i++)
|
||||||
if (s1[i] == '\0')
|
if (s1[i] == '\0')
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return s1[i] - s2[i];
|
return s1[i] - s2[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
int strncmp(const char *s1, const char *s2, unsigned long n)
|
int strncmp(const char *s1, const char *s2, unsigned long n)
|
||||||
{
|
{
|
||||||
for (; n > 0; s1++, s2++, --n)
|
for (; n > 0; s1++, s2++, --n)
|
||||||
if (*s1 != *s2)
|
if (*s1 != *s2)
|
||||||
return ((*(unsigned char *)s1 < *(unsigned char *)s2) ? -1 : 1);
|
return ((*(unsigned char *)s1 < *(unsigned char *)s2)
|
||||||
else if (*s1 == '\0')
|
? -1
|
||||||
return 0;
|
: 1);
|
||||||
return 0;
|
else if (*s1 == '\0')
|
||||||
|
return 0;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#include <mango/libc/string.h>
|
#include <kernel/libc/string.h>
|
||||||
|
|
||||||
char *strcpy(char *output, const char *input)
|
char *strcpy(char *output, const char *input)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
#include <mango/libc/string.h>
|
#include <kernel/libc/string.h>
|
||||||
|
|
||||||
size_t strlen(const char *str) {
|
size_t strlen(const char *str)
|
||||||
|
{
|
||||||
size_t res = 0;
|
size_t res = 0;
|
||||||
while (str[res]) {
|
while (str[res]) {
|
||||||
res++;
|
res++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#include <mango/libc/string.h>
|
#include <kernel/libc/string.h>
|
||||||
|
|
||||||
char *strrchr(const char *str, int c) {
|
char *strrchr(const char *str, int c) {
|
||||||
size_t len = strlen(str);
|
size_t len = strlen(str);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <mango/libc/string.h>
|
#include <kernel/libc/string.h>
|
||||||
|
|
||||||
#define ALIGN (sizeof(size_t))
|
#define ALIGN (sizeof(size_t))
|
||||||
#define ONES ((size_t)-1 / UCHAR_MAX)
|
#define ONES ((size_t)-1 / UCHAR_MAX)
|
||||||
|
|||||||
@@ -16,7 +16,8 @@ typedef unsigned int kern_status_t;
|
|||||||
#define KERN_DEVICE_STUCK (10)
|
#define KERN_DEVICE_STUCK (10)
|
||||||
#define KERN_IO_ERROR (11)
|
#define KERN_IO_ERROR (11)
|
||||||
#define KERN_FATAL_ERROR (12)
|
#define KERN_FATAL_ERROR (12)
|
||||||
|
#define KERN_BAD_STATE (13)
|
||||||
extern const char *kern_status_string(kern_status_t status);
|
#define KERN_MEMORY_FAULT (14)
|
||||||
|
#define KERN_ACCESS_DENIED (15)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
35
libmango/include/mango/syscall.h
Normal file
35
libmango/include/mango/syscall.h
Normal file
@@ -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
|
||||||
62
libmango/include/mango/types.h
Normal file
62
libmango/include/mango/types.h
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
#ifndef MANGO_TYPES_H_
|
||||||
|
#define MANGO_TYPES_H_
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#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
|
||||||
14
sched/core.c
14
sched/core.c
@@ -1,10 +1,10 @@
|
|||||||
#include <mango/clock.h>
|
#include <kernel/clock.h>
|
||||||
#include <mango/cpu.h>
|
#include <kernel/cpu.h>
|
||||||
#include <mango/machine/thread.h>
|
#include <kernel/machine/thread.h>
|
||||||
#include <mango/object.h>
|
#include <kernel/object.h>
|
||||||
#include <mango/printk.h>
|
#include <kernel/printk.h>
|
||||||
#include <mango/sched.h>
|
#include <kernel/sched.h>
|
||||||
#include <mango/vm-region.h>
|
#include <kernel/vm-region.h>
|
||||||
|
|
||||||
extern kern_status_t setup_kernel_task(void);
|
extern kern_status_t setup_kernel_task(void);
|
||||||
extern kern_status_t setup_idle_task(void);
|
extern kern_status_t setup_idle_task(void);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#include <mango/sched.h>
|
#include <kernel/sched.h>
|
||||||
#include <mango/percpu.h>
|
#include <kernel/percpu.h>
|
||||||
#include <mango/cpu.h>
|
#include <kernel/cpu.h>
|
||||||
|
|
||||||
#define PRIO_MASK(p) (((uint32_t)1) << (p))
|
#define PRIO_MASK(p) (((uint32_t)1) << (p))
|
||||||
#define FIRST_PRIO(m) (m > 0 ? (PRIO_MAX - __builtin_clz(m) - 1) : -1)
|
#define FIRST_PRIO(m) (m > 0 ? (PRIO_MAX - __builtin_clz(m) - 1) : -1)
|
||||||
|
|||||||
20
sched/task.c
20
sched/task.c
@@ -1,12 +1,14 @@
|
|||||||
#include <mango/clock.h>
|
#include <kernel/channel.h>
|
||||||
#include <mango/cpu.h>
|
#include <kernel/clock.h>
|
||||||
#include <mango/handle.h>
|
#include <kernel/cpu.h>
|
||||||
#include <mango/libc/stdio.h>
|
#include <kernel/handle.h>
|
||||||
#include <mango/locks.h>
|
#include <kernel/libc/stdio.h>
|
||||||
#include <mango/object.h>
|
#include <kernel/locks.h>
|
||||||
#include <mango/printk.h>
|
#include <kernel/object.h>
|
||||||
#include <mango/sched.h>
|
#include <kernel/printk.h>
|
||||||
#include <mango/vm-region.h>
|
#include <kernel/sched.h>
|
||||||
|
#include <kernel/util.h>
|
||||||
|
#include <kernel/vm-region.h>
|
||||||
|
|
||||||
#define TASK_CAST(p) OBJECT_C_CAST(struct task, t_base, &task_type, p)
|
#define TASK_CAST(p) OBJECT_C_CAST(struct task, t_base, &task_type, p)
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#include <mango/bitmap.h>
|
#include <kernel/bitmap.h>
|
||||||
#include <mango/cpu.h>
|
#include <kernel/cpu.h>
|
||||||
#include <mango/machine/thread.h>
|
#include <kernel/machine/thread.h>
|
||||||
#include <mango/object.h>
|
#include <kernel/object.h>
|
||||||
#include <mango/sched.h>
|
#include <kernel/sched.h>
|
||||||
|
|
||||||
#define THREAD_CAST(p) OBJECT_C_CAST(struct thread, thr_base, &thread_type, p)
|
#define THREAD_CAST(p) OBJECT_C_CAST(struct thread, thr_base, &thread_type, p)
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#include <mango/sched.h>
|
#include <kernel/sched.h>
|
||||||
#include <mango/printk.h>
|
#include <kernel/printk.h>
|
||||||
#include <mango/cpu.h>
|
#include <kernel/cpu.h>
|
||||||
#include <mango/clock.h>
|
#include <kernel/clock.h>
|
||||||
|
|
||||||
static void timeout_expiry(struct timer *timer)
|
static void timeout_expiry(struct timer *timer)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#include <mango/sched.h>
|
#include <kernel/cpu.h>
|
||||||
#include <mango/cpu.h>
|
#include <kernel/sched.h>
|
||||||
|
|
||||||
void wait_item_init(struct wait_item *item, struct thread *thr)
|
void wait_item_init(struct wait_item *item, struct thread *thr)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#include <mango/sched.h>
|
#include <kernel/sched.h>
|
||||||
#include <mango/vm.h>
|
#include <kernel/vm.h>
|
||||||
#include <mango/util.h>
|
#include <kernel/util.h>
|
||||||
#include <mango/cpu.h>
|
#include <kernel/cpu.h>
|
||||||
|
|
||||||
static struct worker_pool *__global_worker_pool = NULL;
|
static struct worker_pool *__global_worker_pool = NULL;
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user