diff --git a/.gitignore b/.gitignore index f13790c..34d23ea 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,4 @@ build/ iso_root/ limine/ test/ -include/uACPI \ No newline at end of file +include/uacpi \ No newline at end of file diff --git a/Makefile b/Makefile index 5e11acb..1d3fa47 100644 --- a/Makefile +++ b/Makefile @@ -3,12 +3,12 @@ CC = gcc AS = nasm LD = ld -SRC_DIR := src build/uACPI/source build +SRC_DIR := src build/flanterm C_SOURCES := $(shell find $(SRC_DIR) -type f -name '*.c') C_OBJECTS := $(patsubst %.c,$(BUILD_DIR)/%.o,$(C_SOURCES)) ASM_SOURCES := $(shell find $(SRC_DIR) -type f -name '*.asm') -ASM_OBJECTS := $(patsubst %.asm,$(BUILD_DIR)/%.o,$(ASM_SOURCES)) +ASM_OBJECTS := $(patsubst %.asm,$(BUILD_DIR)/%asm.o,$(ASM_SOURCES)) CFLAGS += -Wall \ -Wextra \ @@ -43,7 +43,7 @@ NASMFLAGS = -f elf64 -g -F dwarf all: amd64 -dependencies: +deps: mkdir -p $(BUILD_DIR) || true rm -rf build/limine git clone https://github.com/limine-bootloader/limine.git --branch=v8.x-binary --depth=1 build/limine @@ -56,13 +56,13 @@ dependencies: mkdir include/uACPI - cp -r build/uACPI/include/ include/ + cp -r build/uACPI/include/* include/ $(BUILD_DIR)/%.o: %.c mkdir -p $(dir $@) $(CC) -c $< -o $@ $(CFLAGS) -$(BUILD_DIR)/%.o: %.asm +$(BUILD_DIR)/%asm.o: %.asm mkdir -p $(dir $@) $(AS) $< -o $@ $(NASMFLAGS) diff --git a/include/error.h b/include/error.h index 87c2e26..06a1fd0 100644 --- a/include/error.h +++ b/include/error.h @@ -5,6 +5,9 @@ typedef enum { /* Success */ KERNEL_STATUS_SUCCESS, + KERNEL_MUTEX_ACQUIRED, + KERNEL_MUTEX_LOCKED, + /* General error */ KERNEL_STATUS_ERROR, } kstatus; diff --git a/include/lock.h b/include/lock.h index 1bb2aea..f647705 100644 --- a/include/lock.h +++ b/include/lock.h @@ -1,9 +1,23 @@ +#include #include +#include #ifndef SPINLOCK_H #define SPINLOCK_H +struct mutex { + atomic_flag lock; + bool locked; + struct thread *holder; +}; + void acquire_spinlock(atomic_flag *lock); void free_spinlock(atomic_flag *lock); +struct mutex *init_mutex(); +kstatus acquire_mutex(struct mutex *mut); +void free_mutex(struct mutex *mut); +kstatus try_mutex(struct mutex *mut); + + #endif \ No newline at end of file diff --git a/include/scheduler/sched.h b/include/scheduler/sched.h index 2a2e105..975c1a0 100644 --- a/include/scheduler/sched.h +++ b/include/scheduler/sched.h @@ -3,6 +3,7 @@ #pragma once typedef enum proc_state { + ZOMBIE = 4, RUNNING = 3, READY = 2, SLEEPING = 1, diff --git a/include/sys/time.h b/include/sys/time.h new file mode 100644 index 0000000..1aa683b --- /dev/null +++ b/include/sys/time.h @@ -0,0 +1,3 @@ +#include +uint64_t get_timestamp_ns(); +void sleep(int ms); \ No newline at end of file diff --git a/src/arch/amd64/hal/timer.c b/src/arch/amd64/hal/timer.c index e11e3c4..12876ee 100644 --- a/src/arch/amd64/hal/timer.c +++ b/src/arch/amd64/hal/timer.c @@ -19,9 +19,4 @@ void timer_init(void){ }else{ calibration_timer = PMT; } -} - -void sleep(int ms){ - /* Eventually fix this */ - apic_sleep(ms); } \ No newline at end of file diff --git a/src/arch/amd64/sched.asm b/src/arch/amd64/sched.asm index 87c9c4f..3bbae15 100644 --- a/src/arch/amd64/sched.asm +++ b/src/arch/amd64/sched.asm @@ -22,5 +22,6 @@ switch_context: pop r12 pop rbp pop rbx + sti ret diff --git a/src/lib/lock.c b/src/lib/lock.c new file mode 100644 index 0000000..9fdcf0b --- /dev/null +++ b/src/lib/lock.c @@ -0,0 +1,58 @@ +#include "arch/amd64/hal/smp.h" +#include "error.h" +#include +#include +#include +#include +#include + +struct ma_cache *mutex_cache; + +void acquire_spinlock(atomic_flag *lock){ + + while(atomic_flag_test_and_set_explicit(lock, memory_order_acquire)){ + asm volatile("pause"); + } + + atomic_thread_fence(memory_order_acquire); +} + +void free_spinlock(atomic_flag *lock){ + atomic_flag_clear_explicit(lock, memory_order_release); +} + +struct mutex *init_mutex(){ + struct mutex *ret = ma_cache_alloc(mutex_cache, 0); + memset(ret, 0, sizeof(struct mutex)); + return ret; +} + +kstatus try_mutex(struct mutex *mut){ + if(!atomic_flag_test_and_set_explicit(&mut->lock, memory_order_acquire)){ + mut->holder = get_cpu_struct()->current_process; + mut->locked = true; + return KERNEL_MUTEX_ACQUIRED; + } + + return KERNEL_MUTEX_LOCKED; + +} + +kstatus acquire_mutex(struct mutex *mut){ + + if(get_cpu_struct()->current_process == mut->holder){ + klog(__func__, "Holder attempted to acquire mutex"); + return KERNEL_STATUS_ERROR; + } + + kstatus ret; + if((ret = try_mutex(mut)) == KERNEL_MUTEX_ACQUIRED){ + return ret; + } + + + + + + +} \ No newline at end of file diff --git a/src/lib/spinlock.c b/src/lib/spinlock.c deleted file mode 100644 index 8dafc4b..0000000 --- a/src/lib/spinlock.c +++ /dev/null @@ -1,15 +0,0 @@ -#include -#include -#include - -void acquire_spinlock(atomic_flag *lock){ - while(atomic_flag_test_and_set_explicit(lock, memory_order_acquire)){ - asm volatile("nop"); - } - - atomic_thread_fence(memory_order_acquire); -} - -void free_spinlock(atomic_flag *lock){ - atomic_flag_clear_explicit(lock, memory_order_release); -} \ No newline at end of file diff --git a/src/mm/slab.c b/src/mm/slab.c index 712bacd..db0c23c 100644 --- a/src/mm/slab.c +++ b/src/mm/slab.c @@ -72,6 +72,9 @@ kstatus _ma_alloc_slab(struct ma_cache *kcache){ // Put the addresses in the slab structure into the bufctls if(kcache->objsize >= 512){ + /* Here we store the bufctls seperately from the actual objects + * + */ slab_structure->free = (struct ma_bufctl*)(va_alloc_contigious_pages(1)); // Store the bufctls off-page memset(slab_structure->free, 0, 4096); @@ -93,7 +96,7 @@ kstatus _ma_alloc_slab(struct ma_cache *kcache){ /* In this case the objects acts as bufctl structures. Small downside: there will always be a max of 252 objects per slab, no matter the size of the object, since * they have to have enough space to store a bufctl structure (16 bytes). * - * Their startaddr is the same as the address of the bufctl, since the objects act as the bufctls. + * Their startaddr is the same as the address of the bufctl, since the objects act as the bufctls */ slab_structure->free = va_alloc_contigious_pages(kcache->slabsize); @@ -105,6 +108,7 @@ kstatus _ma_alloc_slab(struct ma_cache *kcache){ for(size_t i = 0; i < kcache->num; i++){ ((struct ma_bufctl*)((uint64_t)slab_structure->free + size*i))->startaddr = (size_t*)((uint64_t)slab_structure->free + i * size); + serial_kprintf("{s}: Adding 0x{x} to freelist\n", kcache->name, (size_t*)((uint64_t)slab_structure->free + i * size)); if(i+1 < kcache->num){ ((struct ma_bufctl*)((uint64_t)slab_structure->free + size*i))->next = (struct ma_bufctl*)((uint64_t)slab_structure->free + size*(i+1)); }else{ @@ -112,6 +116,8 @@ kstatus _ma_alloc_slab(struct ma_cache *kcache){ } } + + //memcpy(get_page(slab_structure->free)->bufctls, slab_structure->free, kcache->slabsize * PAGE_SIZE); } //asm("int $1"); @@ -130,10 +136,8 @@ kstatus _ma_alloc_slab(struct ma_cache *kcache){ return KERNEL_STATUS_SUCCESS; } -// fix this complicated POS +// TODO: fix this complicated POS void _ma_move_slab(struct ma_slab *slab, enum SLAB_STATE newstate){ - - struct ma_cache *cache = slab->cache; struct ma_slab *sb = 0; switch (newstate) { @@ -313,6 +317,7 @@ void *ma_cache_alloc(struct ma_cache *kcache, uint32_t flags){ uint64_t *addr = _ma_slab_get_free_obj(slab); + // If there's no free object then allocate new slab if(addr == NULL){ slab->free = NULL; @@ -406,6 +411,10 @@ struct ma_bufctl *addr_to_bufctl(void *object){ return NULL; } + if(slab->cache->objsize < 512){ + return (struct ma_bufctl*)object; + } + struct ma_bufctl *bufs = get_page(object)->bufctls; if(bufs == NULL){ @@ -413,7 +422,12 @@ struct ma_bufctl *addr_to_bufctl(void *object){ } for(size_t i = 0; i < slab->cache->num; i++){ + if((bufs + i)->startaddr != 0){ + kprintf("addr_to_bufctl: we're looking at 0x{x}\n", (bufs + i)->startaddr); + } + if((bufs + i)->startaddr == object){ + //kprintf("addr_to_bufctl: we're looking at 0x{x}\n", (bufs + i)->startaddr); return (bufs + i); } } @@ -456,6 +470,8 @@ kstatus ma_cache_dealloc(void *object){ } extern struct ma_cache *thread_cache; +extern struct ma_cache *mutex_cache; void create_base_caches(){ thread_cache = ma_cache_create("thread", sizeof(struct thread), 0, NULL, NULL); + mutex_cache = ma_cache_create("mutex", sizeof(struct mutex), 0, NULL, NULL); } diff --git a/src/mm/vmm.c b/src/mm/vmm.c index 02443c1..063f79f 100644 --- a/src/mm/vmm.c +++ b/src/mm/vmm.c @@ -304,7 +304,7 @@ int vmm_map_contigious_pages(uint64_t *page_map, uint64_t virt_addr, uint64_t ph return 0; } -#define VA_BASE 0x800815000 +#define VA_BASE 0x900915000 uint64_t va_base = VA_BASE; atomic_flag va_lock = ATOMIC_FLAG_INIT; diff --git a/src/scheduler/sched.c b/src/scheduler/sched.c index bc5fe80..25dcf24 100644 --- a/src/scheduler/sched.c +++ b/src/scheduler/sched.c @@ -39,46 +39,31 @@ void thread_exit(){ cpu_state *cpu = get_cpu_struct(); struct thread *p = cpu->current_process; - kprintf("hi"); - - // Remove process from circular linked list - p->prev->next = p->next; - if(p == p->next){ - cpu->current_process = idle; - } + // If this is the only thread in the queue then set cpu->head to NULL, so scheduler knows to idle + cpu->head = NULL; + }else{ + // Remove process from circular linked list + p->next->prev = p->prev; + p->prev->next = p->next; - if(p == cpu->head){ + if(p == cpu->head){ + //cpu->head = p->next; + } } - ma_cache_dealloc(p); // KILL the thread + p->state = ZOMBIE; - sched(); + // Switch to scheduler + yield(); } /* Setup a process structure */ struct thread *alloc_thread(void){ - struct cpu_state *cpu = get_cpu_struct(); - struct thread *head = get_cpu_struct()->head; - struct thread *base = get_cpu_struct()->base; - struct thread *t = ma_cache_alloc(thread_cache, 0); memset(t, 0, sizeof(struct thread)); - if(base == NULL){ - t->next = t; - t->prev = t; - cpu->base = t; - cpu->head = t; - } else { - t->prev = head; - t->next = base; - head->next = t; - base->prev = t; - cpu->head = t; - } - t->state = READY; t->kstack = kzalloc(8 * 4096); @@ -100,36 +85,61 @@ struct thread *alloc_thread(void){ } -struct thread *add_process(uint64_t *entry){ - struct thread *proc = alloc_thread(); +struct thread *add_thread(uint64_t *entry){ + struct thread *t = alloc_thread(); - if (proc == NULL) { - klog(__func__, "proc == null!"); - kkill(); + assert(t != NULL && "Thread allocation failed!"); + + struct cpu_state *cpu = get_cpu_struct(); + struct thread *head = get_cpu_struct()->head; + struct thread *base = get_cpu_struct()->base; + + // Manage circley linked list + if(base == NULL){ + t->next = t; + t->prev = t; + cpu->base = t; + cpu->head = t; + } else { + t->prev = head; + t->next = base; + head->next = t; + base->prev = t; + cpu->head = t; } - proc->context->rip = (uint64_t)entry; + t->context->rip = (uint64_t)entry; - //kprintf("entry: 0x{xn}", entry); - - return proc; + return t; } [[noreturn]] void sched(){ - cpu_state *cpu = get_cpu_struct(); + for(;;){ + asm("cli"); // we sti at the end of switch_context + cpu_state *cpu = get_cpu_struct(); + struct thread *prev = cpu->current_process; - asm("cli"); + if(prev->state == ZOMBIE){ + kprintf("we are freeing allocated thread 0x{x}\n", prev); + ma_cache_dealloc(prev); + }else{ + prev->state = READY; + } - struct thread *prev = cpu->current_process; - prev->state = READY; - - cpu->current_process = prev->next; - - cpu->current_process->state = RUNNING; - asm("sti"); - switch_context(&(get_cpu_struct()->scheduler_context), get_cpu_struct()->current_process->context); - + if(cpu->head == NULL){ + cpu->current_process = idle; + }else{ + if(prev->next){ + cpu->current_process = prev->next; + }else{ + cpu->current_process = cpu->head; + } + } + + cpu->current_process->state = RUNNING; + switch_context(&(get_cpu_struct()->scheduler_context), get_cpu_struct()->current_process->context); + } } void scheduler_init(){ @@ -142,11 +152,11 @@ void scheduler_init(){ return; } - idle = add_process((uint64_t*)idle_task); + idle = alloc_thread(); + idle->context->rip = (uint64_t)idle; assert(idle != NULL && "Failed to allocate idle task!"); - cpu->current_process = idle; cpu->scheduler_stack = kzalloc(4096); @@ -154,9 +164,9 @@ void scheduler_init(){ cpu->scheduler_context->rbp = (uint64_t)cpu->scheduler_context; cpu->scheduler_context->rip = (uint64_t)sched; - add_process((uint64_t*)test_task); + add_thread((uint64_t*)test_task); - add_process((uint64_t *)best_task); + add_thread((uint64_t *)best_task); // Initialize scheduler -> we will now get timer interrupts to switch us into sched() cpu->scheduler_initialized = true; diff --git a/src/sys/time.c b/src/sys/time.c index 60ca444..3f3b743 100644 --- a/src/sys/time.c +++ b/src/sys/time.c @@ -2,7 +2,9 @@ #include #include -uint64_t kernel_get_timestamp(){ +#include + +uint64_t get_timestamp_ns(){ uint64_t ret = 0; uint64_t tsc = tsc_get_timestamp(); @@ -13,4 +15,8 @@ uint64_t kernel_get_timestamp(){ return tsc; +} + +void sleep(int ms){ + apic_sleep(ms); } \ No newline at end of file diff --git a/src/uacpi_kernel_api.c b/src/uacpi_kernel_api.c deleted file mode 100644 index 83433bc..0000000 --- a/src/uacpi_kernel_api.c +++ /dev/null @@ -1,141 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -uacpi_status uacpi_kernel_get_rsdp(uacpi_phys_addr *out_rsdp_address){ - extern struct limine_rsdp_request rsdp_request; - out_rsdp_address = (uacpi_phys_addr*)rsdp_request.response->address; - return UACPI_STATUS_OK; -} - -uacpi_status uacpi_kernel_pci_device_open(uacpi_pci_address address, uacpi_handle *out_handle){ - - if(address.segment != 0){ - klog(LOG_ERROR, __func__, "Multiple segments not implemented!"); - return UACPI_STATUS_UNIMPLEMENTED; - } - - l84_pci_function_return ret = check_device(address.bus, address.device); - - return ret.func_addr[address.function]; -} - -void uacpi_kernel_pci_device_close(uacpi_handle handle){ - return; -} - -uacpi_status uacpi_kernel_pci_read(uacpi_handle device, uacpi_size offset, uacpi_u8 byte_width, uacpi_u64 *value){ - if(byte_width == 1){ - uint8_t read = *(uint8_t*)((uint64_t)device + offset); - *value = read; - }else if(byte_width == 2){ - uint16_t read = *(uint16_t*)((uint64_t)device + offset); - *value = read; - }else if(byte_width == 4){ - uint32_t read = *(uint32_t*)((uint64_t)device + offset); - *value = read; - }else{ - return UACPI_STATUS_INTERNAL_ERROR; - } - - return UACPI_STATUS_OK; -}; - -uacpi_status uacpi_kernel_pci_write(uacpi_handle device, uacpi_size offset, uacpi_u8 byte_width, uacpi_u64 value){ - if(byte_width == 1){ - *(uint8_t*)((uint64_t)device + offset) = value; - }else if(byte_width == 2){ - *(uint16_t*)((uint64_t)device + offset) = value; - }else if(byte_width == 4){ - *(uint32_t*)((uint64_t)device + offset) = value; - }else{ - return UACPI_STATUS_INTERNAL_ERROR; - } - - return UACPI_STATUS_OK; -} - -uacpi_status uacpi_kernel_io_map(uacpi_io_addr base, uacpi_size len, uacpi_handle *out_handle){ - return UACPI_STATUS_UNIMPLEMENTED; -} - -void uacpi_kernel_io_unmap(uacpi_handle handle){ - asm("nop"); -} - -uacpi_status uacpi_kernel_io_read(uacpi_handle handle, uacpi_size offset, uacpi_u8 byte_width, uacpi_u64 *value){ - if(byte_width == 1){ - *value = inb((uint16_t)offset); - }else if(byte_width == 2){ - *value = inw((uint16_t)offset); - }else if(byte_width == 4){ - *value = inl((uint16_t)offset); - }else{ - return UACPI_STATUS_INTERNAL_ERROR; - } - - return UACPI_STATUS_OK; -} - -uacpi_status uacpi_kernel_io_write(uacpi_handle handle, uacpi_size offset, uacpi_u8 byte_width, uacpi_u64 value){ - if(byte_width == 1){ - outb((uint16_t)offset, value); - }else if(byte_width == 2){ - outw((uint16_t)offset, value); - }else if(byte_width == 4){ - outl((uint16_t)offset, value); - }else{ - return UACPI_STATUS_INTERNAL_ERROR; - } - - return UACPI_STATUS_OK; -} - -void *uacpi_kernel_map(uacpi_phys_addr addr, uacpi_size len){ - kernel_map_pages((void*)addr, len, PTE_BIT_RW); - return (void*)addr; -} - -void uacpi_kernel_unmap(void *addr, uacpi_size len){ - kernel_unmap_pages(addr, len); -} - -void *uacpi_kernel_alloc(uacpi_size size){ - void *ret = kmalloc(size); - - if(ret == NULL){ - klog(LOG_ERROR, __func__, "OOM"); - kkill(); - } - - return ret; - -} - -void uacpi_kernel_free(void *mem){ - - if(mem == NULL){ - return; - } - - kfree(mem); -} - -void uacpi_kernel_log(uacpi_log_level level, const uacpi_char *str){ - switch(level){ - case UACPI_LOG_ERROR: - kprintf("uacpi: error: %s\n", str); - case UACPI_LOG_WARN: - kprintf("uacpi: warn: %s\n", str); - case UACPI_LOG_INFO: - kprintf("uacpi: info: %s\n", str); - default: - asm("nop"); - - } -} \ No newline at end of file diff --git a/uacpi_kernel_api.c b/uacpi_kernel_api.c new file mode 100644 index 0000000..cdf25ce --- /dev/null +++ b/uacpi_kernel_api.c @@ -0,0 +1,216 @@ +#include "arch/amd64/hal/smp.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern uint64_t hhdmoffset; + +uacpi_status uacpi_kernel_get_rsdp(uacpi_phys_addr *out_rsdp_address){ + extern struct limine_rsdp_request rsdp_request; + assert(rsdp_request.response != NULL); + out_rsdp_address = (uacpi_phys_addr*)rsdp_request.response->address; + return UACPI_STATUS_OK; +} + +void uacpi_kernel_log(uacpi_log_level l, const uacpi_char* str){ + char* level; + + switch(l){ + case UACPI_LOG_ERROR: + kprintf("{k}[uACPI] {sk}\n", ANSI_COLOR_RED, str, ANSI_COLOR_RESET); + break; + case UACPI_LOG_WARN: + kprintf("{k}[uACPI] {sk}\n", ANSI_COLOR_YELLOW, str, ANSI_COLOR_RESET); + break; + case UACPI_LOG_INFO: + kprintf("{k}[uACPI]{k} {s}\n", ANSI_COLOR_MAGENTA, ANSI_COLOR_RESET, str); + break; + default: + kprintf("[uACPI] {s}\n", str); + } + +} + +uacpi_status uacpi_kernel_pci_device_open(uacpi_pci_address address, uacpi_handle *out_handle){ + + *out_handle = kzalloc(sizeof(uacpi_pci_address)); + + memcpy(*out_handle, &address, sizeof(uacpi_pci_address)); + + return UACPI_STATUS_OK; +} + +void uacpi_kernel_pci_device_close(uacpi_handle handle){ + free(handle); + return; +} + +uacpi_status uacpi_kernel_pci_read8(uacpi_handle device, uacpi_size offset, uacpi_u8 *value){ + *value = *(uint8_t*)((uint64_t)device + offset); + return UACPI_STATUS_OK; +} + +uacpi_status uacpi_kernel_pci_read16(uacpi_handle device, uacpi_size offset, uacpi_u16 *value){ + *value = *(uint16_t*)((uint64_t)device + offset); + return UACPI_STATUS_OK; +} + +uacpi_status uacpi_kernel_pci_read32(uacpi_handle device, uacpi_size offset, uacpi_u32 *value){ + *value = *(uint32_t*)((uint64_t)device + offset); + return UACPI_STATUS_OK; +} + +uacpi_status uacpi_kernel_pci_write8(uacpi_handle device, uacpi_size offset, uacpi_u8 value){ + *(uint8_t*)((uint64_t)device + offset + hhdmoffset) = value; + return UACPI_STATUS_OK; +} + +uacpi_status uacpi_kernel_pci_write16(uacpi_handle device, uacpi_size offset, uacpi_u16 value){ + *(uint16_t*)((uint64_t)device + offset + hhdmoffset) = value; + return UACPI_STATUS_OK; +} + +uacpi_status uacpi_kernel_pci_write32(uacpi_handle device, uacpi_size offset, uacpi_u32 value){ + *(uint32_t*)((uint64_t)device + offset + hhdmoffset) = value; + return UACPI_STATUS_OK; +} + +uacpi_status uacpi_kernel_io_map(uacpi_io_addr base, uacpi_size len, uacpi_handle *out_handle){ + return UACPI_STATUS_UNIMPLEMENTED; +} + +void uacpi_kernel_io_unmap(uacpi_handle handle){ + asm("nop"); +} + +uacpi_status uacpi_kernel_io_read8(uacpi_handle handle, uacpi_size offset, uacpi_u8 *out_value){ + *out_value = inb(((uint16_t)handle + offset)); + return UACPI_STATUS_OK; +} + + +uacpi_status uacpi_kernel_io_read16(uacpi_handle handle, uacpi_size offset, uacpi_u16 *out_value){ + *out_value = inw(((uint16_t)handle + offset)); + return UACPI_STATUS_OK; +} + + +uacpi_status uacpi_kernel_io_read32(uacpi_handle handle, uacpi_size offset, uacpi_u32 *out_value){ + *out_value = inl(((uint16_t)handle + offset)); + return UACPI_STATUS_OK; +} + + +uacpi_status uacpi_kernel_io_write8(uacpi_handle handle, uacpi_size offset, uacpi_u8 in_value){ + outb(((uint16_t)handle + offset), in_value); + return UACPI_STATUS_OK; +} + +uacpi_status uacpi_kernel_io_write16(uacpi_handle handle, uacpi_size offset, uacpi_u16 in_value){ + outw(((uint16_t)handle + offset), in_value); + return UACPI_STATUS_OK; +} + +uacpi_status uacpi_kernel_io_write32(uacpi_handle handle, uacpi_size offset, uacpi_u32 in_value){ + outb(((uint16_t)handle + offset), in_value); + return UACPI_STATUS_OK; +} + + +uacpi_status uacpi_kernel_io_write(uacpi_handle handle, uacpi_size offset, uacpi_u8 byte_width, uacpi_u64 value){ + if(byte_width == 1){ + outb((uint16_t)offset, value); + }else if(byte_width == 2){ + outw((uint16_t)offset, value); + }else if(byte_width == 4){ + outl((uint16_t)offset, value); + }else{ + return UACPI_STATUS_INTERNAL_ERROR; + } + + return UACPI_STATUS_OK; +} + +void *uacpi_kernel_map(uacpi_phys_addr addr, uacpi_size len){ + uint64_t offset = addr % PAGE_SIZE; + kmap_pages((void*)addr, len, 0); + return (void*)addr + hhdmoffset + offset; +} + +void uacpi_kernel_unmap(void *addr, uacpi_size len){ + kunmap_pages(addr, len); +} + +void *uacpi_kernel_alloc(uacpi_size size){ + void *ret = kmalloc(size); + + if(ret == NULL){ + klog(__func__, "Unable to kmalloc!"); + } + + return ret; + +} + +void uacpi_kernel_free(void *mem){ + + if(mem == NULL){ + return; + } + + kfree(mem); +} + +uacpi_u64 uacpi_kernel_get_nanoseconds_since_boot(void){ + return get_timestamp_ns(); +} + +void uacpi_kernel_stall(uacpi_u8 usec){ + sleep(usec / 1000); +} + +void uacpi_kernel_sleep(uacpi_u64 msec){ + sleep(msec ); +} + +uacpi_handle uacpi_kernel_create_mutex(){ + return kmalloc(sizeof(atomic_flag)); +} + +void uacpi_kernel_free_mutex(uacpi_handle handle){ + free(handle); + return; +} + +uacpi_handle uacpi_kernel_create_event(void){ + return kmalloc(sizeof(uint64_t)); +} + +void uacpi_kernel_free_event(uacpi_handle handle){ + kfree(handle); +} + +uacpi_thread_id uacpi_kernel_get_thread_id(void){ + return get_cpu_struct(); +} + +uacpi_status uacpi_kernel_acquire_mutex(uacpi_handle handle, uacpi_u16 t){ + atomic_flag *flg = handle; + +} +