Minor changes to build system
This commit is contained in:
parent
f478f8d38b
commit
a7fd9ac224
16 changed files with 391 additions and 224 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -2,4 +2,4 @@ build/
|
||||||
iso_root/
|
iso_root/
|
||||||
limine/
|
limine/
|
||||||
test/
|
test/
|
||||||
include/uACPI
|
include/uacpi
|
||||||
10
Makefile
10
Makefile
|
|
@ -3,12 +3,12 @@ CC = gcc
|
||||||
AS = nasm
|
AS = nasm
|
||||||
LD = ld
|
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_SOURCES := $(shell find $(SRC_DIR) -type f -name '*.c')
|
||||||
C_OBJECTS := $(patsubst %.c,$(BUILD_DIR)/%.o,$(C_SOURCES))
|
C_OBJECTS := $(patsubst %.c,$(BUILD_DIR)/%.o,$(C_SOURCES))
|
||||||
|
|
||||||
ASM_SOURCES := $(shell find $(SRC_DIR) -type f -name '*.asm')
|
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 \
|
CFLAGS += -Wall \
|
||||||
-Wextra \
|
-Wextra \
|
||||||
|
|
@ -43,7 +43,7 @@ NASMFLAGS = -f elf64 -g -F dwarf
|
||||||
|
|
||||||
all: amd64
|
all: amd64
|
||||||
|
|
||||||
dependencies:
|
deps:
|
||||||
mkdir -p $(BUILD_DIR) || true
|
mkdir -p $(BUILD_DIR) || true
|
||||||
rm -rf build/limine
|
rm -rf build/limine
|
||||||
git clone https://github.com/limine-bootloader/limine.git --branch=v8.x-binary --depth=1 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
|
mkdir include/uACPI
|
||||||
|
|
||||||
cp -r build/uACPI/include/ include/
|
cp -r build/uACPI/include/* include/
|
||||||
|
|
||||||
$(BUILD_DIR)/%.o: %.c
|
$(BUILD_DIR)/%.o: %.c
|
||||||
mkdir -p $(dir $@)
|
mkdir -p $(dir $@)
|
||||||
$(CC) -c $< -o $@ $(CFLAGS)
|
$(CC) -c $< -o $@ $(CFLAGS)
|
||||||
|
|
||||||
$(BUILD_DIR)/%.o: %.asm
|
$(BUILD_DIR)/%asm.o: %.asm
|
||||||
mkdir -p $(dir $@)
|
mkdir -p $(dir $@)
|
||||||
$(AS) $< -o $@ $(NASMFLAGS)
|
$(AS) $< -o $@ $(NASMFLAGS)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,9 @@ typedef enum {
|
||||||
/* Success */
|
/* Success */
|
||||||
KERNEL_STATUS_SUCCESS,
|
KERNEL_STATUS_SUCCESS,
|
||||||
|
|
||||||
|
KERNEL_MUTEX_ACQUIRED,
|
||||||
|
KERNEL_MUTEX_LOCKED,
|
||||||
|
|
||||||
/* General error */
|
/* General error */
|
||||||
KERNEL_STATUS_ERROR,
|
KERNEL_STATUS_ERROR,
|
||||||
} kstatus;
|
} kstatus;
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,23 @@
|
||||||
|
#include <error.h>
|
||||||
#include <stdatomic.h>
|
#include <stdatomic.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
#ifndef SPINLOCK_H
|
#ifndef SPINLOCK_H
|
||||||
#define SPINLOCK_H
|
#define SPINLOCK_H
|
||||||
|
|
||||||
|
struct mutex {
|
||||||
|
atomic_flag lock;
|
||||||
|
bool locked;
|
||||||
|
struct thread *holder;
|
||||||
|
};
|
||||||
|
|
||||||
void acquire_spinlock(atomic_flag *lock);
|
void acquire_spinlock(atomic_flag *lock);
|
||||||
void free_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
|
#endif
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
typedef enum proc_state {
|
typedef enum proc_state {
|
||||||
|
ZOMBIE = 4,
|
||||||
RUNNING = 3,
|
RUNNING = 3,
|
||||||
READY = 2,
|
READY = 2,
|
||||||
SLEEPING = 1,
|
SLEEPING = 1,
|
||||||
|
|
|
||||||
3
include/sys/time.h
Normal file
3
include/sys/time.h
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
uint64_t get_timestamp_ns();
|
||||||
|
void sleep(int ms);
|
||||||
|
|
@ -20,8 +20,3 @@ void timer_init(void){
|
||||||
calibration_timer = PMT;
|
calibration_timer = PMT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sleep(int ms){
|
|
||||||
/* Eventually fix this */
|
|
||||||
apic_sleep(ms);
|
|
||||||
}
|
|
||||||
|
|
@ -22,5 +22,6 @@ switch_context:
|
||||||
pop r12
|
pop r12
|
||||||
pop rbp
|
pop rbp
|
||||||
pop rbx
|
pop rbx
|
||||||
|
sti
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
|
||||||
58
src/lib/lock.c
Normal file
58
src/lib/lock.c
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
#include "arch/amd64/hal/smp.h"
|
||||||
|
#include "error.h"
|
||||||
|
#include <mm/slab.h>
|
||||||
|
#include <lock.h>
|
||||||
|
#include <stdatomic.h>
|
||||||
|
#include <kprint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
#include <lock.h>
|
|
||||||
#include <stdatomic.h>
|
|
||||||
#include <kprint.h>
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
@ -72,6 +72,9 @@ kstatus _ma_alloc_slab(struct ma_cache *kcache){
|
||||||
|
|
||||||
// Put the addresses in the slab structure into the bufctls
|
// Put the addresses in the slab structure into the bufctls
|
||||||
if(kcache->objsize >= 512){
|
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
|
slab_structure->free = (struct ma_bufctl*)(va_alloc_contigious_pages(1)); // Store the bufctls off-page
|
||||||
memset(slab_structure->free, 0, 4096);
|
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
|
/* 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).
|
* 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);
|
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++){
|
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);
|
((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){
|
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));
|
((struct ma_bufctl*)((uint64_t)slab_structure->free + size*i))->next = (struct ma_bufctl*)((uint64_t)slab_structure->free + size*(i+1));
|
||||||
}else{
|
}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");
|
//asm("int $1");
|
||||||
|
|
@ -130,10 +136,8 @@ kstatus _ma_alloc_slab(struct ma_cache *kcache){
|
||||||
return KERNEL_STATUS_SUCCESS;
|
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){
|
void _ma_move_slab(struct ma_slab *slab, enum SLAB_STATE newstate){
|
||||||
|
|
||||||
|
|
||||||
struct ma_cache *cache = slab->cache;
|
struct ma_cache *cache = slab->cache;
|
||||||
struct ma_slab *sb = 0;
|
struct ma_slab *sb = 0;
|
||||||
switch (newstate) {
|
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);
|
uint64_t *addr = _ma_slab_get_free_obj(slab);
|
||||||
|
|
||||||
|
// If there's no free object then allocate new slab
|
||||||
if(addr == NULL){
|
if(addr == NULL){
|
||||||
slab->free = NULL;
|
slab->free = NULL;
|
||||||
|
|
||||||
|
|
@ -406,6 +411,10 @@ struct ma_bufctl *addr_to_bufctl(void *object){
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(slab->cache->objsize < 512){
|
||||||
|
return (struct ma_bufctl*)object;
|
||||||
|
}
|
||||||
|
|
||||||
struct ma_bufctl *bufs = get_page(object)->bufctls;
|
struct ma_bufctl *bufs = get_page(object)->bufctls;
|
||||||
|
|
||||||
if(bufs == NULL){
|
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++){
|
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){
|
if((bufs + i)->startaddr == object){
|
||||||
|
//kprintf("addr_to_bufctl: we're looking at 0x{x}\n", (bufs + i)->startaddr);
|
||||||
return (bufs + i);
|
return (bufs + i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -456,6 +470,8 @@ kstatus ma_cache_dealloc(void *object){
|
||||||
|
|
||||||
}
|
}
|
||||||
extern struct ma_cache *thread_cache;
|
extern struct ma_cache *thread_cache;
|
||||||
|
extern struct ma_cache *mutex_cache;
|
||||||
void create_base_caches(){
|
void create_base_caches(){
|
||||||
thread_cache = ma_cache_create("thread", sizeof(struct thread), 0, NULL, NULL);
|
thread_cache = ma_cache_create("thread", sizeof(struct thread), 0, NULL, NULL);
|
||||||
|
mutex_cache = ma_cache_create("mutex", sizeof(struct mutex), 0, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -304,7 +304,7 @@ int vmm_map_contigious_pages(uint64_t *page_map, uint64_t virt_addr, uint64_t ph
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define VA_BASE 0x800815000
|
#define VA_BASE 0x900915000
|
||||||
uint64_t va_base = VA_BASE;
|
uint64_t va_base = VA_BASE;
|
||||||
atomic_flag va_lock = ATOMIC_FLAG_INIT;
|
atomic_flag va_lock = ATOMIC_FLAG_INIT;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,46 +39,31 @@ void thread_exit(){
|
||||||
cpu_state *cpu = get_cpu_struct();
|
cpu_state *cpu = get_cpu_struct();
|
||||||
struct thread *p = cpu->current_process;
|
struct thread *p = cpu->current_process;
|
||||||
|
|
||||||
kprintf("hi");
|
if(p == p->next){
|
||||||
|
// 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
|
// Remove process from circular linked list
|
||||||
|
p->next->prev = p->prev;
|
||||||
p->prev->next = p->next;
|
p->prev->next = p->next;
|
||||||
|
|
||||||
if(p == p->next){
|
|
||||||
cpu->current_process = idle;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 */
|
/* Setup a process structure */
|
||||||
struct thread *alloc_thread(void){
|
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);
|
struct thread *t = ma_cache_alloc(thread_cache, 0);
|
||||||
memset(t, 0, sizeof(struct thread));
|
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->state = READY;
|
||||||
|
|
||||||
t->kstack = kzalloc(8 * 4096);
|
t->kstack = kzalloc(8 * 4096);
|
||||||
|
|
@ -100,36 +85,61 @@ struct thread *alloc_thread(void){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct thread *add_process(uint64_t *entry){
|
struct thread *add_thread(uint64_t *entry){
|
||||||
struct thread *proc = alloc_thread();
|
struct thread *t = alloc_thread();
|
||||||
|
|
||||||
if (proc == NULL) {
|
assert(t != NULL && "Thread allocation failed!");
|
||||||
klog(__func__, "proc == null!");
|
|
||||||
kkill();
|
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 t;
|
||||||
|
|
||||||
return proc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[[noreturn]] void sched(){
|
[[noreturn]] void sched(){
|
||||||
|
for(;;){
|
||||||
|
asm("cli"); // we sti at the end of switch_context
|
||||||
cpu_state *cpu = get_cpu_struct();
|
cpu_state *cpu = get_cpu_struct();
|
||||||
|
|
||||||
asm("cli");
|
|
||||||
|
|
||||||
struct thread *prev = cpu->current_process;
|
struct thread *prev = cpu->current_process;
|
||||||
prev->state = READY;
|
|
||||||
|
|
||||||
|
if(prev->state == ZOMBIE){
|
||||||
|
kprintf("we are freeing allocated thread 0x{x}\n", prev);
|
||||||
|
ma_cache_dealloc(prev);
|
||||||
|
}else{
|
||||||
|
prev->state = READY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(cpu->head == NULL){
|
||||||
|
cpu->current_process = idle;
|
||||||
|
}else{
|
||||||
|
if(prev->next){
|
||||||
cpu->current_process = prev->next;
|
cpu->current_process = prev->next;
|
||||||
|
}else{
|
||||||
|
cpu->current_process = cpu->head;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cpu->current_process->state = RUNNING;
|
cpu->current_process->state = RUNNING;
|
||||||
asm("sti");
|
|
||||||
switch_context(&(get_cpu_struct()->scheduler_context), get_cpu_struct()->current_process->context);
|
switch_context(&(get_cpu_struct()->scheduler_context), get_cpu_struct()->current_process->context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void scheduler_init(){
|
void scheduler_init(){
|
||||||
|
|
@ -142,11 +152,11 @@ void scheduler_init(){
|
||||||
return;
|
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!");
|
assert(idle != NULL && "Failed to allocate idle task!");
|
||||||
|
|
||||||
|
|
||||||
cpu->current_process = idle;
|
cpu->current_process = idle;
|
||||||
|
|
||||||
cpu->scheduler_stack = kzalloc(4096);
|
cpu->scheduler_stack = kzalloc(4096);
|
||||||
|
|
@ -154,9 +164,9 @@ void scheduler_init(){
|
||||||
cpu->scheduler_context->rbp = (uint64_t)cpu->scheduler_context;
|
cpu->scheduler_context->rbp = (uint64_t)cpu->scheduler_context;
|
||||||
cpu->scheduler_context->rip = (uint64_t)sched;
|
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()
|
// Initialize scheduler -> we will now get timer interrupts to switch us into sched()
|
||||||
cpu->scheduler_initialized = true;
|
cpu->scheduler_initialized = true;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,9 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <arch/amd64/hal/tsc.h>
|
#include <arch/amd64/hal/tsc.h>
|
||||||
uint64_t kernel_get_timestamp(){
|
#include <arch/amd64/hal/apic.h>
|
||||||
|
|
||||||
|
uint64_t get_timestamp_ns(){
|
||||||
uint64_t ret = 0;
|
uint64_t ret = 0;
|
||||||
uint64_t tsc = tsc_get_timestamp();
|
uint64_t tsc = tsc_get_timestamp();
|
||||||
|
|
||||||
|
|
@ -14,3 +16,7 @@ uint64_t kernel_get_timestamp(){
|
||||||
return tsc;
|
return tsc;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sleep(int ms){
|
||||||
|
apic_sleep(ms);
|
||||||
|
}
|
||||||
|
|
@ -1,141 +0,0 @@
|
||||||
#include <uacpi/uacpi.h>
|
|
||||||
#include <sys/pci.h>
|
|
||||||
#include <mm/vmm.h>
|
|
||||||
#include <mm/kmalloc.h>
|
|
||||||
#include <limine.h>
|
|
||||||
#include <kprint.h>
|
|
||||||
#include <neobbo.h>
|
|
||||||
#include <io.h>
|
|
||||||
|
|
||||||
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");
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
216
uacpi_kernel_api.c
Normal file
216
uacpi_kernel_api.c
Normal file
|
|
@ -0,0 +1,216 @@
|
||||||
|
#include "arch/amd64/hal/smp.h"
|
||||||
|
#include <stdatomic.h>
|
||||||
|
#include <uacpi/kernel_api.h>
|
||||||
|
#include <uacpi/log.h>
|
||||||
|
#include <uacpi/status.h>
|
||||||
|
#include <uacpi/types.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <uacpi/uacpi.h>
|
||||||
|
#include <sys/pci.h>
|
||||||
|
#include <mm/vmm.h>
|
||||||
|
#include <mm/kmalloc.h>
|
||||||
|
#include <limine.h>
|
||||||
|
#include <kprint.h>
|
||||||
|
#include <neobbo.h>
|
||||||
|
#include <io.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue