diff --git a/core/alloc.c b/core/alloc.c index c838bfb..4b4cb44 100644 --- a/core/alloc.c +++ b/core/alloc.c @@ -18,208 +18,208 @@ static int formatPage(struct slabEntry *desc, size_t size, int selfContained); int allocInit(void) { - uint start = log2(sizeof(void *)); - list_init(slub); - int ret; - if ((ret = allocBookSlab(sizeof(struct slabDesc), 1))) { - pr_devel("Fail to allocBookSlab %d for slabDesc :( \n", ret); - return ret; + uint start = log2(sizeof(void *)); + list_init(slub); + int ret; + if ((ret = allocBookSlab(sizeof(struct slabDesc), 1))) { + pr_devel("Fail to allocBookSlab %d for slabDesc :( \n", ret); + return ret; + } + if ((ret = allocBookSlab(sizeof(struct slabEntry), 1))) { + pr_devel("Fail to allocBookSlab %d for slabEntry :( \n", ret); + return ret; + } + for (uint i = start; i <= SLUB_SIZE; i++) { + if ((ret = allocBookSlab(1U << i, 0))) { + if (ret == -EEXIST) + continue; + pr_devel("Fail to allocBookSlab %d for %d \n", ret, (1U << i)); + return ret; } - if ((ret = allocBookSlab(sizeof(struct slabEntry), 1))) { - pr_devel("Fail to allocBookSlab %d for slabEntry :( \n", ret); - return ret; - } - for (uint i = start; i <= SLUB_SIZE; i++) { - if ((ret = allocBookSlab(1U << i, 0))) { - if(ret == -EEXIST) - continue; - pr_devel("Fail to allocBookSlab %d for %d \n", ret, (1U << i)); - return ret; - } - } - return 0; + } + return 0; } int allocBookSlab(size_t size, int selfContained) { - pr_devel("%s for size %d is self %d\n", __func__, size, selfContained); - struct slabDesc *slab = NULL; - int slabIdx; - int ret; - list_foreach(slub, slab, slabIdx) - { - if (slab->size == size) { - return -EEXIST; - } - if (slab->size > size) { - break; - } + pr_devel("%s for size %d is self %d\n", __func__, size, selfContained); + struct slabDesc *slab = NULL; + int slabIdx; + int ret; + list_foreach(slub, slab, slabIdx) + { + if (slab->size == size) { + return -EEXIST; } - struct slabDesc *newSlab; - if ((ret = allocSlab(&newSlab, size, selfContained))) - return ret; - if (list_foreach_early_break(slub, slab, slabIdx)) { - list_insert_before(slub, slab, newSlab); - } else { - list_add_tail(slub, newSlab); + if (slab->size > size) { + break; } - return 0; + } + struct slabDesc *newSlab; + if ((ret = allocSlab(&newSlab, size, selfContained))) + return ret; + if (list_foreach_early_break(slub, slab, slabIdx)) { + list_insert_before(slub, slab, newSlab); + } else { + list_add_tail(slub, newSlab); + } + return 0; } int allocSlab(struct slabDesc **desc, size_t size, int selfContained) { - // pr_devel("%s for size %d is self %d\n", __func__, size, selfContained); - if (size > PAGE_SIZE) - return -ENOENT; - paddr_t alloc = allocPhyPage(); - if (alloc == (paddr_t)NULL) - return -ENOMEM; - if (pageMap((vaddr_t)alloc, alloc, PAGING_MEM_WRITE)) - return -ENOMEM; + // pr_devel("%s for size %d is self %d\n", __func__, size, selfContained); + if (size > PAGE_SIZE) + return -ENOENT; + paddr_t alloc = allocPhyPage(); + if (alloc == (paddr_t)NULL) + return -ENOMEM; + if (pageMap((vaddr_t)alloc, alloc, PAGING_MEM_WRITE)) + return -ENOMEM; - if (selfContained) { - *desc = (struct slabDesc *)alloc; - ((*desc)->slab).freeEl = (char *)(*desc) + sizeof(struct slabDesc); - } else { - *desc = malloc(sizeof(struct slabDesc)); - (*desc)->slab.freeEl = (void *)alloc; - } - struct slabEntry *slab = &(*desc)->slab; - list_singleton(slab, slab); - slab->page = (vaddr_t)alloc; - slab->full = 0; - (*desc)->size = size; - // pr_devel("got page %d for size %d first %d", alloc, size, (*desc)->slab.freeEl); - return formatPage(&(*desc)->slab, size, selfContained); + if (selfContained) { + *desc = (struct slabDesc *)alloc; + ((*desc)->slab).freeEl = (char *)(*desc) + sizeof(struct slabDesc); + } else { + *desc = malloc(sizeof(struct slabDesc)); + (*desc)->slab.freeEl = (void *)alloc; + } + struct slabEntry *slab = &(*desc)->slab; + list_singleton(slab, slab); + slab->page = (vaddr_t)alloc; + slab->full = 0; + (*desc)->size = size; + // pr_devel("got page %d for size %d first %d", alloc, size, (*desc)->slab.freeEl); + return formatPage(&(*desc)->slab, size, selfContained); } int allocSlabEntry(struct slabEntry **desc, size_t size, int selfContained) { - pr_devel("%s for size %d is self %d\n", __func__, size, selfContained); - if (size > PAGE_SIZE) - return -ENOENT; - paddr_t alloc = allocPhyPage(); - if (alloc == (paddr_t)NULL) - return -ENOMEM; - if (pageMap((vaddr_t)alloc, alloc, PAGING_MEM_WRITE)) - return -ENOMEM; + pr_devel("%s for size %d is self %d\n", __func__, size, selfContained); + if (size > PAGE_SIZE) + return -ENOENT; + paddr_t alloc = allocPhyPage(); + if (alloc == (paddr_t)NULL) + return -ENOMEM; + if (pageMap((vaddr_t)alloc, alloc, PAGING_MEM_WRITE)) + return -ENOMEM; - if (selfContained) { - *desc = (struct slabEntry *)alloc; - (*desc)->freeEl = (char *)(*desc) + sizeof(struct slabEntry); - } else { - *desc = malloc(sizeof(struct slabEntry)); - (*desc)->freeEl = (void *)alloc; - } - list_singleton(*desc, *desc); - (*desc)->page = (vaddr_t)alloc; - (*desc)->full = 0; - // pr_devel("got page %d for size %d first %d", alloc, size, (*desc)->freeEl); - return formatPage((*desc), size, selfContained); + if (selfContained) { + *desc = (struct slabEntry *)alloc; + (*desc)->freeEl = (char *)(*desc) + sizeof(struct slabEntry); + } else { + *desc = malloc(sizeof(struct slabEntry)); + (*desc)->freeEl = (void *)alloc; + } + list_singleton(*desc, *desc); + (*desc)->page = (vaddr_t)alloc; + (*desc)->full = 0; + // pr_devel("got page %d for size %d first %d", alloc, size, (*desc)->freeEl); + return formatPage((*desc), size, selfContained); } static int formatPage(struct slabEntry *desc, size_t size, int selfContained) { - char *cur = desc->freeEl; - ulong nbEl = PAGE_SIZE / size - 1; - if (selfContained) - nbEl = (PAGE_SIZE - sizeof(struct slabDesc)) / size - 1; - ulong i; - for (i = 0; i < nbEl; i++) { - *((vaddr_t *)cur) = (vaddr_t)cur + size; - cur += size; - } - *((vaddr_t *)cur) = (vaddr_t)NULL; - // pr_devel("last at %d allocated %d\n", cur, i + 1); - return 0; + char *cur = desc->freeEl; + ulong nbEl = PAGE_SIZE / size - 1; + if (selfContained) + nbEl = (PAGE_SIZE - sizeof(struct slabDesc)) / size - 1; + ulong i; + for (i = 0; i < nbEl; i++) { + *((vaddr_t *)cur) = (vaddr_t)cur + size; + cur += size; + } + *((vaddr_t *)cur) = (vaddr_t)NULL; + // pr_devel("last at %d allocated %d\n", cur, i + 1); + return 0; } static void *allocFromSlab(struct slabEntry *slab) { - vaddr_t *next = slab->freeEl; - if (*next == (vaddr_t)NULL) { - pr_devel("Slab @%d is now full\n", slab); - slab->full = 1; - } else { - slab->freeEl = (void *)(*next); - } - return (void *)next; + vaddr_t *next = slab->freeEl; + if (*next == (vaddr_t)NULL) { + pr_devel("Slab @%d is now full\n", slab); + slab->full = 1; + } else { + slab->freeEl = (void *)(*next); + } + return (void *)next; } void *malloc(size_t size) { - if (size > (1U << SLUB_SIZE)) { - printf("implement malloc for big size\n"); - return NULL; - } - struct slabDesc *slab; - uint slubIdx; - list_foreach(slub, slab, slubIdx) - { - if (size <= slab->size) - break; - } - struct slabEntry *slabEntry; - int slabIdx; - list_foreach(&slab->slab, slabEntry, slabIdx) - { - if (!slabEntry->full) { - // pr_devel("found place in slub %d at idx %d for size %d\n", slubIdx, - // slabIdx, size); - return allocFromSlab(slabEntry); - } + if (size > (1U << SLUB_SIZE)) { + printf("implement malloc for big size\n"); + return NULL; + } + struct slabDesc *slab; + uint slubIdx; + list_foreach(slub, slab, slubIdx) + { + if (size <= slab->size) + break; + } + struct slabEntry *slabEntry; + int slabIdx; + list_foreach(&slab->slab, slabEntry, slabIdx) + { + if (!slabEntry->full) { + // pr_devel("found place in slub %d at idx %d for size %d\n", slubIdx, + // slabIdx, size); + return allocFromSlab(slabEntry); } + } - // No room found - struct slabEntry *newSlabEntry; - struct slabEntry *slabList = &slab->slab; - int ret; - if ((ret = allocSlabEntry(&newSlabEntry, slab->size, IS_SELF_CONTAINED(&slab->slab)))) { - pr_devel("Fail to allocSlabEntry %d\n", ret); - return NULL; - } - pr_devel("Allocate new slab for object of size %d\n", slab->size); - list_add_tail(slabList, newSlabEntry); - return allocFromSlab(newSlabEntry); + // No room found + struct slabEntry *newSlabEntry; + struct slabEntry *slabList = &slab->slab; + int ret; + if ((ret = allocSlabEntry(&newSlabEntry, slab->size, IS_SELF_CONTAINED(&slab->slab)))) { + pr_devel("Fail to allocSlabEntry %d\n", ret); + return NULL; + } + pr_devel("Allocate new slab for object of size %d\n", slab->size); + list_add_tail(slabList, newSlabEntry); + return allocFromSlab(newSlabEntry); } int freeFromSlab(void *ptr, struct slabEntry *slab) { - struct slabEntry *slabEntry; - int slabIdx; - list_foreach(slab, slabEntry, slabIdx) - { - if ((slabEntry->page <= (vaddr_t)ptr) && - ((vaddr_t)ptr < (slabEntry->page + PAGE_SIZE))) { - // pr_devel("free place! was %d is now %d\n", slabEntry->freeEl, ptr); - if (slabEntry->full) { - *((vaddr_t *)ptr) = (vaddr_t)NULL; - } else { - *((vaddr_t *)ptr) = (vaddr_t)slabEntry->freeEl; - } - slabEntry->freeEl = ptr; - slabEntry->full = 0; - return 1; - } + struct slabEntry *slabEntry; + int slabIdx; + list_foreach(slab, slabEntry, slabIdx) + { + if ((slabEntry->page <= (vaddr_t)ptr) && + ((vaddr_t)ptr < (slabEntry->page + PAGE_SIZE))) { + // pr_devel("free place! was %d is now %d\n", slabEntry->freeEl, ptr); + if (slabEntry->full) { + *((vaddr_t *)ptr) = (vaddr_t)NULL; + } else { + *((vaddr_t *)ptr) = (vaddr_t)slabEntry->freeEl; + } + slabEntry->freeEl = ptr; + slabEntry->full = 0; + return 1; } - return 0; + } + return 0; } void free(void *ptr) { - if (!ptr) - return; + if (!ptr) + return; - struct slabDesc *slab; - int slabIdx; - list_foreach(slub, slab, slabIdx) + struct slabDesc *slab; + int slabIdx; + list_foreach(slub, slab, slabIdx) + { + struct slabEntry *slabEntry; + int entryIdx; + list_foreach(&slab->slab, slabEntry, entryIdx) { - struct slabEntry *slabEntry; - int entryIdx; - list_foreach(&slab->slab, slabEntry, entryIdx) - { - if (freeFromSlab(ptr, slabEntry)) - return; - } + if (freeFromSlab(ptr, slabEntry)) + return; } - pr_devel("free: slab not found\n"); + } + pr_devel("free: slab not found\n"); } diff --git a/core/alloc.h b/core/alloc.h index 216b8f1..f1e41a2 100644 --- a/core/alloc.h +++ b/core/alloc.h @@ -3,21 +3,21 @@ #include "stdarg.h" struct slabEntry { - vaddr_t page; - void *freeEl; - char full; - struct slabEntry *next; - struct slabEntry *prev; + vaddr_t page; + void *freeEl; + char full; + struct slabEntry *next; + struct slabEntry *prev; }; struct slabDesc { - struct slabEntry slab; - size_t size; - struct slabDesc *next; - struct slabDesc *prev; + struct slabEntry slab; + size_t size; + struct slabDesc *next; + struct slabDesc *prev; }; int allocInit(void); int allocBookSlab(size_t size, int selfContained); void *malloc(size_t size); -void free(void* ptr); +void free(void *ptr); diff --git a/core/assert.h b/core/assert.h index 1064a4d..a48a58e 100644 --- a/core/assert.h +++ b/core/assert.h @@ -1,22 +1,24 @@ #pragma once -#include "stack.h" #include "klibc.h" +#include "stack.h" -#define assert(p) do { \ - if (!(p)) { \ - printf("BUG at %s:%d assert(%s)\n", \ - __FILE__, __LINE__, #p); \ - printStackTrace(5); \ - while(1){} \ - } \ -} while (0) +#define assert(p) \ + do { \ + if (!(p)) { \ + printf("BUG at %s:%d assert(%s)\n", __FILE__, __LINE__, #p); \ + printStackTrace(5); \ + while (1) { \ + } \ + } \ + } while (0) -#define assertmsg(p, ...) do { \ - if (!(p)) { \ - printf("BUG at %s:%d assert(%s)\n", \ - __FILE__, __LINE__, #p); \ - printf(__VA_ARGS__); \ - printStackTrace(5); \ - while(1){} \ - } \ -} while (0) +#define assertmsg(p, ...) \ + do { \ + if (!(p)) { \ + printf("BUG at %s:%d assert(%s)\n", __FILE__, __LINE__, #p); \ + printf(__VA_ARGS__); \ + printStackTrace(5); \ + while (1) { \ + } \ + } \ + } while (0) diff --git a/core/cpu_context.c b/core/cpu_context.c index c4f376c..a1126b1 100644 --- a/core/cpu_context.c +++ b/core/cpu_context.c @@ -24,34 +24,34 @@ * irq_wrappers.S/exception_wrappers.S !!! Hence the constraint above. */ struct cpu_state { - /* (Lower addresses) */ + /* (Lower addresses) */ - /* These are Matos/SOS convention */ - uint16_t gs; - uint16_t fs; - uint16_t es; - uint16_t ds; - uint16_t cpl0_ss; /* This is ALWAYS the Stack Segment of the - Kernel context (CPL0) of the interrupted - thread, even for a user thread */ - uint16_t alignment_padding; /* unused */ - uint32_t eax; - uint32_t ecx; - uint32_t edx; - uint32_t ebx; - uint32_t ebp; - uint32_t esp; - uint32_t esi; - uint32_t edi; + /* These are Matos/SOS convention */ + uint16_t gs; + uint16_t fs; + uint16_t es; + uint16_t ds; + uint16_t cpl0_ss; /* This is ALWAYS the Stack Segment of the + Kernel context (CPL0) of the interrupted + thread, even for a user thread */ + uint16_t alignment_padding; /* unused */ + uint32_t eax; + uint32_t ecx; + uint32_t edx; + uint32_t ebx; + uint32_t ebp; + uint32_t esp; + uint32_t esi; + uint32_t edi; - /* MUST NEVER CHANGE (dependent on the IA32 iret instruction) */ - uint32_t error_code; - vaddr_t eip; - uint32_t cs; /* 32bits according to the specs ! However, the CS - register is really 16bits long */ - uint32_t eflags; + /* MUST NEVER CHANGE (dependent on the IA32 iret instruction) */ + uint32_t error_code; + vaddr_t eip; + uint32_t cs; /* 32bits according to the specs ! However, the CS + register is really 16bits long */ + uint32_t eflags; - /* (Higher addresses) */ + /* (Higher addresses) */ } __attribute__((packed)); /** @@ -73,7 +73,7 @@ struct cpu_state { * Structure of an interrupted Kernel thread's context */ struct cpu_kstate { - struct cpu_state regs; + struct cpu_state regs; } __attribute__((packed)); /** @@ -88,125 +88,125 @@ static void core_routine(cpu_kstate_function_arg1_t *start_func, void *start_arg static void core_routine(cpu_kstate_function_arg1_t *start_func, void *start_arg, cpu_kstate_function_arg1_t *exit_func, void *exit_arg) { - start_func(start_arg); - exit_func(exit_arg); + start_func(start_arg); + exit_func(exit_arg); - assert(!"The exit function of the thread should NOT return !"); - for (;;) - ; + assert(!"The exit function of the thread should NOT return !"); + for (;;) + ; } int cpu_kstate_init(struct cpu_state **ctxt, cpu_kstate_function_arg1_t *start_func, vaddr_t start_arg, vaddr_t stack_bottom, size_t stack_size, cpu_kstate_function_arg1_t *exit_func, vaddr_t exit_arg) { - /* We are initializing a Kernel thread's context */ - struct cpu_kstate *kctxt; + /* We are initializing a Kernel thread's context */ + struct cpu_kstate *kctxt; - /* This is a critical internal function, so that it is assumed that - the caller knows what he does: we legitimally assume that values - for ctxt, start_func, stack_* and exit_func are allways VALID ! */ + /* This is a critical internal function, so that it is assumed that + the caller knows what he does: we legitimally assume that values + for ctxt, start_func, stack_* and exit_func are allways VALID ! */ - /* Setup the stack. - * - * On x86, the stack goes downward. Each frame is configured this - * way (higher addresses first): - * - * - (optional unused space. As of gcc 3.3, this space is 24 bytes) - * - arg n - * - arg n-1 - * - ... - * - arg 1 - * - return instruction address: The address the function returns to - * once finished - * - local variables - * - * The remaining of the code should be read from the end upward to - * understand how the processor will handle it. - */ + /* Setup the stack. + * + * On x86, the stack goes downward. Each frame is configured this + * way (higher addresses first): + * + * - (optional unused space. As of gcc 3.3, this space is 24 bytes) + * - arg n + * - arg n-1 + * - ... + * - arg 1 + * - return instruction address: The address the function returns to + * once finished + * - local variables + * + * The remaining of the code should be read from the end upward to + * understand how the processor will handle it. + */ - vaddr_t tmp_vaddr = stack_bottom + stack_size; - uint32_t *stack = (uint32_t *)tmp_vaddr; + vaddr_t tmp_vaddr = stack_bottom + stack_size; + uint32_t *stack = (uint32_t *)tmp_vaddr; - /* If needed, poison the stack */ + /* If needed, poison the stack */ #ifdef CPU_STATE_DETECT_UNINIT_KERNEL_VARS - memset((void *)stack_bottom, CPU_STATE_STACK_POISON, stack_size); + memset((void *)stack_bottom, CPU_STATE_STACK_POISON, stack_size); #elif defined(CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW) - cpu_state_prepare_detect_kernel_stack_overflow(stack_bottom, stack_size); + cpu_state_prepare_detect_kernel_stack_overflow(stack_bottom, stack_size); #endif - /* Simulate a call to the core_routine() function: prepare its - arguments */ - *(--stack) = exit_arg; - *(--stack) = (uint32_t)exit_func; - *(--stack) = start_arg; - *(--stack) = (uint32_t)start_func; - *(--stack) = 0; /* Return address of core_routine => force page fault */ + /* Simulate a call to the core_routine() function: prepare its + arguments */ + *(--stack) = exit_arg; + *(--stack) = (uint32_t)exit_func; + *(--stack) = start_arg; + *(--stack) = (uint32_t)start_func; + *(--stack) = 0; /* Return address of core_routine => force page fault */ - /* - * Setup the initial context structure, so that the CPU will execute - * the function core_routine() once this new context has been - * restored on CPU - */ + /* + * Setup the initial context structure, so that the CPU will execute + * the function core_routine() once this new context has been + * restored on CPU + */ - /* Compute the base address of the structure, which must be located - below the previous elements */ - tmp_vaddr = ((vaddr_t)stack) - sizeof(struct cpu_kstate); - kctxt = (struct cpu_kstate *)tmp_vaddr; + /* Compute the base address of the structure, which must be located + below the previous elements */ + tmp_vaddr = ((vaddr_t)stack) - sizeof(struct cpu_kstate); + kctxt = (struct cpu_kstate *)tmp_vaddr; - /* Initialize the CPU context structure */ - memset(kctxt, 0x0, sizeof(struct cpu_kstate)); + /* Initialize the CPU context structure */ + memset(kctxt, 0x0, sizeof(struct cpu_kstate)); - /* Tell the CPU context structure that the first instruction to - execute will be that of the core_routine() function */ - kctxt->regs.eip = (uint32_t)core_routine; + /* Tell the CPU context structure that the first instruction to + execute will be that of the core_routine() function */ + kctxt->regs.eip = (uint32_t)core_routine; - /* Setup the segment registers */ - kctxt->regs.cs = BUILD_SEGMENT_REG_VALUE(0, FALSE, SEG_KCODE); /* Code */ - kctxt->regs.ds = BUILD_SEGMENT_REG_VALUE(0, FALSE, SEG_KDATA); /* Data */ - kctxt->regs.es = BUILD_SEGMENT_REG_VALUE(0, FALSE, SEG_KDATA); /* Data */ - kctxt->regs.cpl0_ss = BUILD_SEGMENT_REG_VALUE(0, FALSE, SEG_KDATA); /* Stack */ - /* fs and gs unused for the moment. */ + /* Setup the segment registers */ + kctxt->regs.cs = BUILD_SEGMENT_REG_VALUE(0, FALSE, SEG_KCODE); /* Code */ + kctxt->regs.ds = BUILD_SEGMENT_REG_VALUE(0, FALSE, SEG_KDATA); /* Data */ + kctxt->regs.es = BUILD_SEGMENT_REG_VALUE(0, FALSE, SEG_KDATA); /* Data */ + kctxt->regs.cpl0_ss = BUILD_SEGMENT_REG_VALUE(0, FALSE, SEG_KDATA); /* Stack */ + /* fs and gs unused for the moment. */ - /* The newly created context is initially interruptible */ - kctxt->regs.eflags = (1 << 9); /* set IF bit */ + /* The newly created context is initially interruptible */ + kctxt->regs.eflags = (1 << 9); /* set IF bit */ - /* Finally, update the generic kernel/user thread context */ - *ctxt = (struct cpu_state *)kctxt; + /* Finally, update the generic kernel/user thread context */ + *ctxt = (struct cpu_state *)kctxt; - return 0; + return 0; } #if defined(CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW) void cpu_state_prepare_detect_kernel_stack_overflow(const struct cpu_state *ctxt, vaddr_t stack_bottom, size_t stack_size) { - (void)ctxt; - size_t poison_size = CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW; - if (poison_size > stack_size) - poison_size = stack_size; + (void)ctxt; + size_t poison_size = CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW; + if (poison_size > stack_size) + poison_size = stack_size; - memset((void *)stack_bottom, CPU_STATE_STACK_POISON, poison_size); + memset((void *)stack_bottom, CPU_STATE_STACK_POISON, poison_size); } void cpu_state_detect_kernel_stack_overflow(const struct cpu_state *ctxt, vaddr_t stack_bottom, size_t stack_size) { - unsigned char *c; - size_t i; + unsigned char *c; + size_t i; - /* On Matos/SOS, "ctxt" corresponds to the address of the esp register of - the saved context in Kernel mode (always, even for the interrupted - context of a user thread). Here we make sure that this stack - pointer is within the allowed stack area */ - assert(((vaddr_t)ctxt) >= stack_bottom); - assert(((vaddr_t)ctxt) + sizeof(struct cpu_kstate) <= stack_bottom + stack_size); + /* On Matos/SOS, "ctxt" corresponds to the address of the esp register of + the saved context in Kernel mode (always, even for the interrupted + context of a user thread). Here we make sure that this stack + pointer is within the allowed stack area */ + assert(((vaddr_t)ctxt) >= stack_bottom); + assert(((vaddr_t)ctxt) + sizeof(struct cpu_kstate) <= stack_bottom + stack_size); - /* Check that the bottom of the stack has not been altered */ - for (c = (unsigned char *)stack_bottom, i = 0; - (i < CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW) && (i < stack_size); c++, i++) { - assert(CPU_STATE_STACK_POISON == *c); - } + /* Check that the bottom of the stack has not been altered */ + for (c = (unsigned char *)stack_bottom, i = 0; + (i < CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW) && (i < stack_size); c++, i++) { + assert(CPU_STATE_STACK_POISON == *c); + } } #endif @@ -216,26 +216,27 @@ void cpu_state_detect_kernel_stack_overflow(const struct cpu_state *ctxt, vaddr_ vaddr_t cpu_context_get_PC(const struct cpu_state *ctxt) { - assert(NULL != ctxt); + assert(NULL != ctxt); - /* This is the PC of the interrupted context (ie kernel or user - context). */ - return ctxt->eip; + /* This is the PC of the interrupted context (ie kernel or user + context). */ + return ctxt->eip; } vaddr_t cpu_context_get_SP(const struct cpu_state *ctxt) { - assert(NULL != ctxt); + assert(NULL != ctxt); - /* On Matos/SOS, "ctxt" corresponds to the address of the esp register of - the saved context in Kernel mode (always, even for the interrupted - context of a user thread). */ - return (vaddr_t)ctxt; + /* On Matos/SOS, "ctxt" corresponds to the address of the esp register of + the saved context in Kernel mode (always, even for the interrupted + context of a user thread). */ + return (vaddr_t)ctxt; } void cpu_context_dump(const struct cpu_state *ctxt) { - printf("CPU: eip=%x esp=%x eflags=%x cs=%x ds=%x ss=%x err=%x", (unsigned)ctxt->eip, - (unsigned)ctxt, (unsigned)ctxt->eflags, (unsigned)GET_CPU_CS_REGISTER_VALUE(ctxt->cs), - (unsigned)ctxt->ds, (unsigned)ctxt->cpl0_ss, (unsigned)ctxt->error_code); + printf("CPU: eip=%x esp=%x eflags=%x cs=%x ds=%x ss=%x err=%x", (unsigned)ctxt->eip, + (unsigned)ctxt, (unsigned)ctxt->eflags, + (unsigned)GET_CPU_CS_REGISTER_VALUE(ctxt->cs), (unsigned)ctxt->ds, + (unsigned)ctxt->cpl0_ss, (unsigned)ctxt->error_code); } diff --git a/core/cpu_context.h b/core/cpu_context.h index a5cb684..d719a1d 100644 --- a/core/cpu_context.h +++ b/core/cpu_context.h @@ -5,16 +5,16 @@ modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. + USA. */ #pragma once @@ -25,10 +25,9 @@ * be some kind of architecture-independent. */ +#include "errno.h" #include "stdarg.h" #include "types.h" -#include "errno.h" - /** * Opaque structure storing the CPU context of an inactive kernel or @@ -41,13 +40,11 @@ */ struct cpu_state; - /** * The type of the functions passed as arguments to the Kernel thread * related functions. */ -typedef void (cpu_kstate_function_arg1_t(void * arg1)); - +typedef void(cpu_kstate_function_arg1_t(void *arg1)); /** * Function to create an initial context for a kernel thread starting @@ -83,14 +80,9 @@ typedef void (cpu_kstate_function_arg1_t(void * arg1)); * * @note the newly created context is INTERRUPTIBLE by default ! */ -int cpu_kstate_init(struct cpu_state **kctxt, - cpu_kstate_function_arg1_t *start_func, - vaddr_t start_arg, - vaddr_t stack_bottom, - size_t stack_size, - cpu_kstate_function_arg1_t *exit_func, - vaddr_t exit_arg); - +int cpu_kstate_init(struct cpu_state **kctxt, cpu_kstate_function_arg1_t *start_func, + vaddr_t start_arg, vaddr_t stack_bottom, size_t stack_size, + cpu_kstate_function_arg1_t *exit_func, vaddr_t exit_arg); /** * Function that performs an immediate context-switch from one @@ -103,9 +95,7 @@ int cpu_kstate_init(struct cpu_state **kctxt, * @param to_ctxt The CPU will resume its execution with the struct * cpu_state located at this address. Must NOT be NULL. */ -void cpu_context_switch(struct cpu_state **from_ctxt, - struct cpu_state *to_ctxt); - +void cpu_context_switch(struct cpu_state **from_ctxt, struct cpu_state *to_ctxt); /* * Switch to the new given context (of a kernel/user thread) without @@ -121,52 +111,43 @@ void cpu_context_switch(struct cpu_state **from_ctxt, * called after having changed the stack, but before restoring the CPU * context to switch_to_ctxt. */ -void -cpu_context_exit_to(struct cpu_state *switch_to_ctxt, - cpu_kstate_function_arg1_t *reclaiming_func, - uint32_t reclaiming_arg) __attribute__((noreturn)); +void cpu_context_exit_to(struct cpu_state *switch_to_ctxt, + cpu_kstate_function_arg1_t *reclaiming_func, uint32_t reclaiming_arg) + __attribute__((noreturn)); /* ======================================================================= * Public Accessor functions */ - /** * Return Program Counter stored in the saved kernel/user context */ vaddr_t cpu_context_get_PC(const struct cpu_state *ctxt); - /** * Return Stack Pointer stored in the saved kernel/user context */ vaddr_t cpu_context_get_SP(const struct cpu_state *ctxt); - /** * Dump the contents of the CPU context (bochs + x86_videomem) */ void cpu_context_dump(const struct cpu_state *ctxt); - /* ======================================================================= * Public Accessor functions TO BE USED ONLY BY Exception handlers */ - /** * Return the argument passed by the CPU upon exception, as stored in the * saved context */ uint32_t cpu_context_get_EX_info(const struct cpu_state *ctxt); - /** * Return the faulting address of the exception */ -vaddr_t -cpu_context_get_EX_faulting_vaddr(const struct cpu_state *ctxt); - +vaddr_t cpu_context_get_EX_faulting_vaddr(const struct cpu_state *ctxt); /* ======================================================================= * Macros controlling stack poisoning. @@ -189,20 +170,18 @@ cpu_context_get_EX_faulting_vaddr(const struct cpu_state *ctxt); * probable stack overflow. Its value indicates the number of bytes * used for this detection. */ -#define CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW 64 +#define CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW 64 /* #undef CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW */ #if defined(CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW) -void -cpu_state_prepare_detect_kernel_stack_overflow(const struct cpu_state *ctxt, - vaddr_t kernel_stack_bottom, - size_t kernel_stack_size); +void cpu_state_prepare_detect_kernel_stack_overflow(const struct cpu_state *ctxt, + vaddr_t kernel_stack_bottom, + size_t kernel_stack_size); void cpu_state_detect_kernel_stack_overflow(const struct cpu_state *ctxt, - vaddr_t kernel_stack_bottom, - size_t kernel_stack_size); + vaddr_t kernel_stack_bottom, + size_t kernel_stack_size); #else -# define cpu_state_prepare_detect_kernel_stack_overflow(ctxt,stkbottom,stksize) \ - ({ /* nop */ }) -# define cpu_state_detect_kernel_stack_overflow(ctxt,stkbottom,stksize) \ - ({ /* nop */ }) +#define cpu_state_prepare_detect_kernel_stack_overflow(ctxt, stkbottom, stksize) ({/* nop \ + */}) +#define cpu_state_detect_kernel_stack_overflow(ctxt, stkbottom, stksize) ({/* nop */}) #endif diff --git a/core/errno.h b/core/errno.h index c805673..f601c56 100644 --- a/core/errno.h +++ b/core/errno.h @@ -1,37 +1,36 @@ #pragma once -#define EPERM 1 /* Operation not permitted */ -#define ENOENT 2 /* No such file or directory */ -#define ESRCH 3 /* No such process */ -#define EINTR 4 /* Interrupted system call */ -#define EIO 5 /* I/O error */ -#define ENXIO 6 /* No such device or address */ -#define E2BIG 7 /* Argument list too long */ -#define ENOEXEC 8 /* Exec format error */ -#define EBADF 9 /* Bad file number */ -#define ECHILD 10 /* No child processes */ -#define EAGAIN 11 /* Try again */ -#define ENOMEM 12 /* Out of memory */ -#define EACCES 13 /* Permission denied */ -#define EFAULT 14 /* Bad address */ -#define ENOTBLK 15 /* Block device required */ -#define EBUSY 16 /* Device or resource busy */ -#define EEXIST 17 /* File exists */ -#define EXDEV 18 /* Cross-device link */ -#define ENODEV 19 /* No such device */ -#define ENOTDIR 20 /* Not a directory */ -#define EISDIR 21 /* Is a directory */ -#define EINVAL 22 /* Invalid argument */ -#define ENFILE 23 /* File table overflow */ -#define EMFILE 24 /* Too many open files */ -#define ENOTTY 25 /* Not a typewriter */ -#define ETXTBSY 26 /* Text file busy */ -#define EFBIG 27 /* File too large */ -#define ENOSPC 28 /* No space left on device */ -#define ESPIPE 29 /* Illegal seek */ -#define EROFS 30 /* Read-only file system */ -#define EMLINK 31 /* Too many links */ -#define EPIPE 32 /* Broken pipe */ -#define EDOM 33 /* Math argument out of domain of func */ -#define ERANGE 34 /* Math result not representable */ - +#define EPERM 1 /* Operation not permitted */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* I/O error */ +#define ENXIO 6 /* No such device or address */ +#define E2BIG 7 /* Argument list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file number */ +#define ECHILD 10 /* No child processes */ +#define EAGAIN 11 /* Try again */ +#define ENOMEM 12 /* Out of memory */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Device or resource busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* File table overflow */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Not a typewriter */ +#define ETXTBSY 26 /* Text file busy */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ +#define EDOM 33 /* Math argument out of domain of func */ +#define ERANGE 34 /* Math result not representable */ diff --git a/core/exception.c b/core/exception.c index d2743dc..fe452d3 100644 --- a/core/exception.c +++ b/core/exception.c @@ -9,16 +9,15 @@ exception_handler exception_handler_array[EXCEPTION_NUM] = { int exceptionSetRoutine(int exception, exception_handler handler) { - uint32_t flags; - if ((exception < 0) || exception >= EXCEPTION_NUM) - return -1; + uint32_t flags; + if ((exception < 0) || exception >= EXCEPTION_NUM) + return -1; - disable_IRQs(flags); + disable_IRQs(flags); - exception_handler_array[exception] = handler; + exception_handler_array[exception] = handler; - idt_set_handler(EXCEPTION_INTERRUPT_BASE_ADDRESS + exception, (unsigned int)handler, - 0); - restore_IRQs(flags); - return 0; + idt_set_handler(EXCEPTION_INTERRUPT_BASE_ADDRESS + exception, (unsigned int)handler, 0); + restore_IRQs(flags); + return 0; } diff --git a/core/exception.h b/core/exception.h index 8ff1c20..36bee46 100644 --- a/core/exception.h +++ b/core/exception.h @@ -41,6 +41,5 @@ #define EXCEPTION_NUM 32 -typedef void (*exception_handler) (struct interrupt_frame *frame, ulong error_code); +typedef void (*exception_handler)(struct interrupt_frame *frame, ulong error_code); int exceptionSetRoutine(int exception, exception_handler handler); - diff --git a/core/exception_handler.c b/core/exception_handler.c index e8d218a..46cf9fc 100644 --- a/core/exception_handler.c +++ b/core/exception_handler.c @@ -6,16 +6,16 @@ // Need GCC > 6 #define DEFINE_INTERRUPT(int_nb) \ - __attribute__((interrupt)) void print_handler_##int_nb(struct interrupt_frame *frame, \ - ulong error_code) \ - { \ - int intNbInt = int_nb; \ - printStringDetails("EXCEPTION ", RED, BLACK, 0, VGA_HEIGHT - 1); \ - printIntDetails(intNbInt, RED, BLACK, 11, VGA_HEIGHT - 1); \ - printIntDetails(error_code, RED, BLACK, 14, VGA_HEIGHT - 1); \ - printf("Exception %d (Err %d) at 0x%x\n", int_nb, error_code, frame->eip); \ - asm("hlt"); \ - } + __attribute__((interrupt)) void print_handler_##int_nb(struct interrupt_frame *frame, \ + ulong error_code) \ + { \ + int intNbInt = int_nb; \ + printStringDetails("EXCEPTION ", RED, BLACK, 0, VGA_HEIGHT - 1); \ + printIntDetails(intNbInt, RED, BLACK, 11, VGA_HEIGHT - 1); \ + printIntDetails(error_code, RED, BLACK, 14, VGA_HEIGHT - 1); \ + printf("Exception %d (Err %d) at 0x%x\n", int_nb, error_code, frame->eip); \ + asm("hlt"); \ + } DEFINE_INTERRUPT(EXCEPTION_DOUBLE_FAULT) DEFINE_INTERRUPT(EXCEPTION_DIVIDE_ZERO) @@ -56,14 +56,14 @@ DEFINE_INTERRUPT(EXCEPTION_RESERVED_11) __attribute__((interrupt)) void pagefault_handler(struct interrupt_frame *frame, ulong error_code) { - // A page fault has occurred. - // The faulting address is stored in the CR2 register. - uint32_t faulting_address; - asm volatile("mov %%cr2, %0" : "=r"(faulting_address)); + // A page fault has occurred. + // The faulting address is stored in the CR2 register. + uint32_t faulting_address; + asm volatile("mov %%cr2, %0" : "=r"(faulting_address)); - printStringDetails("PAGE FAULT", RED, BLACK, 0, VGA_HEIGHT - 1); - printIntDetails(error_code, RED, BLACK, 11, VGA_HEIGHT - 1); - (void)faulting_address; - (void)frame; - (void)error_code; + printStringDetails("PAGE FAULT", RED, BLACK, 0, VGA_HEIGHT - 1); + printIntDetails(error_code, RED, BLACK, 11, VGA_HEIGHT - 1); + (void)faulting_address; + (void)frame; + (void)error_code; } diff --git a/core/gdt.c b/core/gdt.c index 2897b30..7737611 100644 --- a/core/gdt.c +++ b/core/gdt.c @@ -75,33 +75,32 @@ struct x86_gdt_register { * 0..4GB addresses to be mapped to the linear 0..4GB linear * addresses. */ -#define BUILD_GDTE(descr_privilege_level, is_code) \ - ((struct x86_segment_descriptor){ \ - .limit_15_0 = 0xffff, \ - .base_paged_addr_15_0 = 0, \ - .base_paged_addr_23_16 = 0, \ - .segment_type = \ - ((is_code) ? 0xb : 0x3), /* With descriptor_type (below) = 1 (code/data), \ - * see Figure 3-1 of section 3.4.3.1 in Intel \ - * x86 vol 3: \ - * - Code (bit 3 = 1): \ - * bit 0: 1=Accessed \ - * bit 1: 1=Readable \ - * bit 2: 0=Non-Conforming \ - * - Data (bit 3 = 0): \ - * bit 0: 1=Accessed \ - * bit 1: 1=Writable \ - * bit 2: 0=Expand up (stack-related) \ - * For Conforming/non conforming segments, see \ - * Intel x86 Vol 3 section 4.8.1.1 \ - */ \ - .descriptor_type = 1, /* 1=Code/Data */ \ - .dpl = ((descr_privilege_level)&0x3), \ - .present = 1, \ - .limit_19_16 = 0xf, \ - .custom = 0, \ - .op_size = 1, /* 32 bits instr/data */ \ - .granularity = 1 /* limit is in 4kB Pages */ \ +#define BUILD_GDTE(descr_privilege_level, is_code) \ + ((struct x86_segment_descriptor){ \ + .limit_15_0 = 0xffff, \ + .base_paged_addr_15_0 = 0, \ + .base_paged_addr_23_16 = 0, \ + .segment_type = ((is_code) ? 0xb : 0x3), /* With descriptor_type (below) = 1 \ + * (code/data), see Figure 3-1 of \ + * section 3.4.3.1 in Intel x86 vol 3: \ + * - Code (bit 3 = 1): \ + * bit 0: 1=Accessed \ + * bit 1: 1=Readable \ + * bit 2: 0=Non-Conforming \ + * - Data (bit 3 = 0): \ + * bit 0: 1=Accessed \ + * bit 1: 1=Writable \ + * bit 2: 0=Expand up (stack-related) \ + * For Conforming/non conforming segments, \ + * see Intel x86 Vol 3 section 4.8.1.1 \ + */ \ + .descriptor_type = 1, /* 1=Code/Data */ \ + .dpl = ((descr_privilege_level)&0x3), \ + .present = 1, \ + .limit_19_16 = 0xf, \ + .custom = 0, \ + .op_size = 1, /* 32 bits instr/data */ \ + .granularity = 1 /* limit is in 4kB Pages */ \ }) /** The actual GDT */ diff --git a/core/gdt.h b/core/gdt.h index b3cf7c5..d61885a 100644 --- a/core/gdt.h +++ b/core/gdt.h @@ -5,16 +5,16 @@ modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. + USA. */ #pragma once @@ -34,4 +34,3 @@ * address space (ie "flat" virtual space). */ int gdtSetup(void); - diff --git a/core/idt.h b/core/idt.h index ce8491d..79730c3 100644 --- a/core/idt.h +++ b/core/idt.h @@ -13,16 +13,16 @@ #define SEGMENT_IDX_DATA 2 struct idtEntry { - uint16_t offset_low; - uint16_t seg_sel; - uint8_t reserved : 5; - uint8_t flags : 3; - uint8_t type : 3; - uint8_t op_size : 1; - uint8_t zero : 1; - uint8_t dpl : 2; - uint8_t present : 1; - uint16_t offset_high; + uint16_t offset_low; + uint16_t seg_sel; + uint8_t reserved : 5; + uint8_t flags : 3; + uint8_t type : 3; + uint8_t op_size : 1; + uint8_t zero : 1; + uint8_t dpl : 2; + uint8_t present : 1; + uint16_t offset_high; } __attribute__((packed)); /** @@ -32,14 +32,13 @@ struct idtEntry { * @see Intel x86 doc vol 3, section 2.4, figure 2-4 */ struct idtRegister { - uint16_t limit; - uint32_t base_addr; + uint16_t limit; + uint32_t base_addr; } __attribute__((packed, aligned(8))); /* Build segment http://wiki.osdev.org/Selector*/ -#define BUILD_SEGMENT_SELECTOR(desc_privilege, in_ldt, index) \ - ((((desc_privilege)&0x3) << 0) | (((in_ldt) ? 1 : 0) << 2) | \ - ((index) << 3)) +#define BUILD_SEGMENT_SELECTOR(desc_privilege, in_ldt, index) \ + ((((desc_privilege)&0x3) << 0) | (((in_ldt) ? 1 : 0) << 2) | ((index) << 3)) int idtSetup(); int idt_set_handler(int index, unsigned int addr, int priviledge); diff --git a/core/interrupt.h b/core/interrupt.h index e6f638c..0be216b 100644 --- a/core/interrupt.h +++ b/core/interrupt.h @@ -1,20 +1,19 @@ #pragma once #include "stdarg.h" - // c.f. intel software-developer-vol-1 6.4.1 struct interrupt_frame { - uint32_t eip; - uint32_t cs; - uint32_t eflags; - uint32_t esp; - uint32_t ss; + uint32_t eip; + uint32_t cs; + uint32_t eflags; + uint32_t esp; + uint32_t ss; }; // Exception // Exception #define DECLARE_INTERRUPT(int_nb) \ - void print_handler_##int_nb(struct interrupt_frame *frame, ulong error_code); + void print_handler_##int_nb(struct interrupt_frame *frame, ulong error_code); #define ACCESS_INTERRUPT(int_nb) print_handler_##int_nb diff --git a/core/io.h b/core/io.h index 9e7b50a..5db61c7 100644 --- a/core/io.h +++ b/core/io.h @@ -4,18 +4,17 @@ // NIH http://wiki.osdev.org/Inline_Assembly/Examples#I.2FO_access static inline void outb(uint16_t port, uint8_t val) { - asm volatile ( "outb %0, %1" : : "a"(val), "Nd"(port) ); - /* There's an outb %al, $imm8 encoding, for compile-time constant port numbers that fit in 8b. (N constraint). - * Wider immediate constants would be truncated at assemble-time (e.g. "i" constraint). - * The outb %al, %dx encoding is the only option for all other cases. - * %1 expands to %dx because port is a uint16_t. %w1 could be used if we had the port number a wider C type */ + asm volatile("outb %0, %1" : : "a"(val), "Nd"(port)); + /* There's an outb %al, $imm8 encoding, for compile-time constant port numbers that fit in + * 8b. (N constraint). Wider immediate constants would be truncated at assemble-time (e.g. + * "i" constraint). The outb %al, %dx encoding is the only option for all other cases. + * %1 expands to %dx because port is a uint16_t. %w1 could be used if we had the port + * number a wider C type */ } static inline uint8_t inb(uint16_t port) { uint8_t ret; - asm volatile ( "inb %1, %0" - : "=a"(ret) - : "Nd"(port) ); + asm volatile("inb %1, %0" : "=a"(ret) : "Nd"(port)); return ret; } diff --git a/core/irq.c b/core/irq.c index 2809f6d..9b57d1e 100644 --- a/core/irq.c +++ b/core/irq.c @@ -5,11 +5,13 @@ int irqSetup() { - initPic(); - return 0; + initPic(); + return 0; } -irq_handler irq_handler_array[IRQ_NUM] = {NULL, }; +irq_handler irq_handler_array[IRQ_NUM] = { + NULL, +}; int irqSetRoutine(int irq, irq_handler handler) { @@ -22,8 +24,8 @@ int irqSetRoutine(int irq, irq_handler handler) irq_handler_array[irq] = handler; if (handler != NULL) { - int ret = - idt_set_handler(IRQ_INTERRUPT_BASE_ADDRESS + irq, (unsigned int)irq_handler_array[irq], 0); + int ret = idt_set_handler(IRQ_INTERRUPT_BASE_ADDRESS + irq, + (unsigned int)irq_handler_array[irq], 0); if (!ret) enableIrq(irq); } diff --git a/core/irq.h b/core/irq.h index aab25f0..1bbebd5 100644 --- a/core/irq.h +++ b/core/irq.h @@ -11,29 +11,29 @@ }) #define restore_IRQs(flags) restore_flags(flags) - -#define IRQ_TIMER 0 // MASTER IRQ -#define IRQ_KEYBOARD 1 -#define IRQ_SLAVE_PIC 2 -#define IRQ_COM2 3 -#define IRQ_COM1 4 -#define IRQ_LPT2 5 -#define IRQ_FLOPPY 6 -#define IRQ_LPT1 7 +#define IRQ_TIMER 0 // MASTER IRQ +#define IRQ_KEYBOARD 1 +#define IRQ_SLAVE_PIC 2 +#define IRQ_COM2 3 +#define IRQ_COM1 4 +#define IRQ_LPT2 5 +#define IRQ_FLOPPY 6 +#define IRQ_LPT1 7 #define IRQ_8_NOT_DEFINED 8 // SLAVE -#define IRQ_RESERVED_1 9 // SLAVE IRQ -#define IRQ_RESERVED_2 10 -#define IRQ_RESERVED_3 11 -#define IRQ_RESERVED_4 12 -#define IRQ_COPROCESSOR 13 -#define IRQ_HARDDISK 14 -#define IRQ_RESERVED_5 15 +#define IRQ_RESERVED_1 9 // SLAVE IRQ +#define IRQ_RESERVED_2 10 +#define IRQ_RESERVED_3 11 +#define IRQ_RESERVED_4 12 +#define IRQ_COPROCESSOR 13 +#define IRQ_HARDDISK 14 +#define IRQ_RESERVED_5 15 #define IRQ_INTERRUPT_BASE_ADDRESS 0x20 #define IRQ_NUM 16 -// An handler should finish by the iret opcode -> https://wiki.osdev.org/Interrupt_Service_Routines -// That's why we use wrapper around them or the gcc interrupt attribut +// An handler should finish by the iret opcode -> +// https://wiki.osdev.org/Interrupt_Service_Routines That's why we use wrapper around them or +// the gcc interrupt attribut // __attribute__((interrupt)) void (*irq_handler)(int irq); typedef void (*irq_handler)(struct interrupt_frame *frame); int irqSetup(); diff --git a/core/irq_handler.c b/core/irq_handler.c index e5f9331..aa242d0 100644 --- a/core/irq_handler.c +++ b/core/irq_handler.c @@ -9,21 +9,21 @@ // Need GCC > 6 __attribute__((interrupt)) void keyboard_handler(struct interrupt_frame *frame) { - EOIIrq(IRQ_KEYBOARD); - keyboard_do_irq(); - (void)frame; + EOIIrq(IRQ_KEYBOARD); + keyboard_do_irq(); + (void)frame; } __attribute__((interrupt)) void timer_handler(struct interrupt_frame *frame) { - static int timeCnt = 0; - EOIIrq(IRQ_TIMER); - printIntDetails(timeCnt++, RED, BLACK, 20, VGA_HEIGHT - 1); - (void)frame; + static int timeCnt = 0; + EOIIrq(IRQ_TIMER); + printIntDetails(timeCnt++, RED, BLACK, 20, VGA_HEIGHT - 1); + (void)frame; } __attribute__((interrupt)) void serial_handler(struct interrupt_frame *frame) { - EOIIrq(IRQ_COM1); - serialDoIrq(frame); + EOIIrq(IRQ_COM1); + serialDoIrq(frame); } diff --git a/core/klibc.h b/core/klibc.h index e50b33e..67a1d76 100644 --- a/core/klibc.h +++ b/core/klibc.h @@ -1,13 +1,13 @@ #pragma once #include "stdarg.h" -#define islower(c) (('a' <= (c)) && ((c) <= 'z')) -#define isupper(c) (('A' <= (c)) && ((c) <= 'Z')) -#define isdigit(c) (('0' <= (c)) && ((c) <= '9')) -#define isspace(c) (((c) == ' ') || ((c) == '\t') || \ - ((c) == '\f') || ((c) == '\n') || \ - ((c) == '\r') || ((c) == '\v')) -#define isprint(c) ((' ' <= (c)) && ((c) <= '~')) +#define islower(c) (('a' <= (c)) && ((c) <= 'z')) +#define isupper(c) (('A' <= (c)) && ((c) <= 'Z')) +#define isdigit(c) (('0' <= (c)) && ((c) <= '9')) +#define isspace(c) \ + (((c) == ' ') || ((c) == '\t') || ((c) == '\f') || ((c) == '\n') || ((c) == '\r') || \ + ((c) == '\v')) +#define isprint(c) ((' ' <= (c)) && ((c) <= '~')) int memcmp(const void *s1, const void *s2, size_t n); void *memcpy(void *dest, const void *src, size_t n); @@ -15,7 +15,7 @@ void *memset(void *s, int c, size_t n); char *itoa(int value, char *str, int base); void reverse(char s[]); int strlen(const char s[]); -unsigned int strnlen(const char * s, size_t count); +unsigned int strnlen(const char *s, size_t count); int strcmp(const char s1[], const char s2[]); char *strzcpy(char *dst, const char *src, int len); void puts(const char *str); @@ -28,20 +28,17 @@ void printf(const char *format, ...); * Dummy printk for disabled debugging statements to use whilst maintaining * gcc's format checking. */ -#define no_printf(fmt, ...) \ -({ \ - if (0) \ - printf(fmt, ##__VA_ARGS__); \ - 0; \ -}) +#define no_printf(fmt, ...) \ + ({ \ + if (0) \ + printf(fmt, ##__VA_ARGS__); \ + 0; \ + }) #ifdef DEBUG -#define pr_devel(fmt, ...) \ - printf(pr_fmt(fmt), ##__VA_ARGS__) +#define pr_devel(fmt, ...) printf(pr_fmt(fmt), ##__VA_ARGS__) #else -#define pr_devel(fmt, ...) \ - no_printf(pr_fmt(fmt), ##__VA_ARGS__) +#define pr_devel(fmt, ...) no_printf(pr_fmt(fmt), ##__VA_ARGS__) #endif -#define pr_info(fmt, ...) \ - printf(pr_fmt(fmt), ##__VA_ARGS__) +#define pr_info(fmt, ...) printf(pr_fmt(fmt), ##__VA_ARGS__) diff --git a/core/kthread.c b/core/kthread.c index 56b5934..339d794 100644 --- a/core/kthread.c +++ b/core/kthread.c @@ -10,96 +10,96 @@ static struct kthread *currentThread; void kthreadExit() { - uint32_t flags; - disable_IRQs(flags); - struct kthread *current = currentThread; - struct kthread *next = kthreadSelectNext(); - if (next == current) - assert("cannot exit thread"); - currentThread = next; - cpu_context_exit_to(next->cpuState, (cpu_kstate_function_arg1_t *)kthreadDelete, - (uint32_t)current); - restore_IRQs(flags); - return; + uint32_t flags; + disable_IRQs(flags); + struct kthread *current = currentThread; + struct kthread *next = kthreadSelectNext(); + if (next == current) + assert("cannot exit thread"); + currentThread = next; + cpu_context_exit_to(next->cpuState, (cpu_kstate_function_arg1_t *)kthreadDelete, + (uint32_t)current); + restore_IRQs(flags); + return; } int kthreadSetup(vaddr_t mainStack, size_t mainStackSize) { - struct kthread *current = (struct kthread *)malloc(sizeof(struct kthread)); - strzcpy(current->name, "[KINIT]", KTHREAD_NAME_MAX_LENGTH); - current->stackAddr = mainStack; - current->stackSize = mainStackSize; + struct kthread *current = (struct kthread *)malloc(sizeof(struct kthread)); + strzcpy(current->name, "[KINIT]", KTHREAD_NAME_MAX_LENGTH); + current->stackAddr = mainStack; + current->stackSize = mainStackSize; - list_singleton(currentThread, current); + list_singleton(currentThread, current); - return 0; + return 0; } struct kthread *kthreadCreate(const char *name, cpu_kstate_function_arg1_t func, void *args) { - struct kthread *thread = (struct kthread *)malloc(sizeof(struct kthread)); - if (!thread) - return NULL; - - thread->stackAddr = (vaddr_t)malloc(KTHREAD_DEFAULT_STACK_SIZE); - printf("Alloc stask at 0x%x strcut at 0x%x\n", thread->stackAddr, thread); - thread->stackSize = KTHREAD_DEFAULT_STACK_SIZE; - - if (!thread->stackAddr) - goto free_mem; - - if (name) - strzcpy(thread->name, name, KTHREAD_NAME_MAX_LENGTH); - else - strzcpy(thread->name, "[UNKNOW]", KTHREAD_NAME_MAX_LENGTH); - - if (cpu_kstate_init(&thread->cpuState, (cpu_kstate_function_arg1_t *)func, - (vaddr_t)args, thread->stackAddr, thread->stackSize, - (cpu_kstate_function_arg1_t *)kthreadExit, 0)) - goto free_mem; - - list_add_tail(currentThread, thread); - return thread; -free_mem: - free((void *)thread->stackAddr); - free((void *)thread); + struct kthread *thread = (struct kthread *)malloc(sizeof(struct kthread)); + if (!thread) return NULL; + + thread->stackAddr = (vaddr_t)malloc(KTHREAD_DEFAULT_STACK_SIZE); + printf("Alloc stask at 0x%x strcut at 0x%x\n", thread->stackAddr, thread); + thread->stackSize = KTHREAD_DEFAULT_STACK_SIZE; + + if (!thread->stackAddr) + goto free_mem; + + if (name) + strzcpy(thread->name, name, KTHREAD_NAME_MAX_LENGTH); + else + strzcpy(thread->name, "[UNKNOW]", KTHREAD_NAME_MAX_LENGTH); + + if (cpu_kstate_init(&thread->cpuState, (cpu_kstate_function_arg1_t *)func, (vaddr_t)args, + thread->stackAddr, thread->stackSize, + (cpu_kstate_function_arg1_t *)kthreadExit, 0)) + goto free_mem; + + list_add_tail(currentThread, thread); + return thread; +free_mem: + free((void *)thread->stackAddr); + free((void *)thread); + return NULL; } void kthreadDelete(struct kthread *thread) { - list_delete(currentThread, thread); + list_delete(currentThread, thread); - free((void *)thread->stackAddr); - free((void *)thread); + free((void *)thread->stackAddr); + free((void *)thread); } struct kthread *kthreadSelectNext() { - struct kthread *nextThread = currentThread->next; - return nextThread; + struct kthread *nextThread = currentThread->next; + return nextThread; } struct cpu_state *switchKthread(struct cpu_state *prevCpu) { - uint32_t flags; - disable_IRQs(flags); - currentThread->cpuState = prevCpu; - struct kthread *nextThread = kthreadSelectNext(); - printStringDetails(nextThread->name, RED, BLACK, 40, VGA_HEIGHT - 1); - currentThread = nextThread; - restore_IRQs(flags); - return nextThread->cpuState; + uint32_t flags; + disable_IRQs(flags); + currentThread->cpuState = prevCpu; + struct kthread *nextThread = kthreadSelectNext(); + printStringDetails(nextThread->name, RED, BLACK, 40, VGA_HEIGHT - 1); + currentThread = nextThread; + restore_IRQs(flags); + return nextThread->cpuState; } int kthreadYield() { - uint32_t flags; - disable_IRQs(flags); - struct kthread *next = kthreadSelectNext(); - struct kthread *current = currentThread; - currentThread = next; - cpu_context_switch(¤t->cpuState, next->cpuState); - restore_IRQs(flags); - return 0; + uint32_t flags; + disable_IRQs(flags); + struct kthread *next = kthreadSelectNext(); + struct kthread *current = currentThread; + currentThread = next; + cpu_context_switch(¤t->cpuState, next->cpuState); + restore_IRQs(flags); + return 0; } diff --git a/core/kthread.h b/core/kthread.h index 128bb8f..d2279f9 100644 --- a/core/kthread.h +++ b/core/kthread.h @@ -7,12 +7,12 @@ #define KTHREAD_DEFAULT_STACK_SIZE PAGE_SIZE struct kthread { - char name[KTHREAD_NAME_MAX_LENGTH]; - struct cpu_state *cpuState; - vaddr_t stackAddr; - size_t stackSize; - struct kthread *next; - struct kthread *prev; + char name[KTHREAD_NAME_MAX_LENGTH]; + struct cpu_state *cpuState; + vaddr_t stackAddr; + size_t stackSize; + struct kthread *next; + struct kthread *prev; }; int kthreadSetup(vaddr_t mainStack, size_t mainStackSize); diff --git a/core/list.h b/core/list.h index 1f4b4d1..a0ec773 100644 --- a/core/list.h +++ b/core/list.h @@ -1,15 +1,15 @@ /* Copyright (C) 2001 David Decotigny - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, @@ -25,170 +25,165 @@ * macros */ - /* *_named are used when next and prev links are not exactly next and prev. For instance when we have next_in_team, prev_in_team, prev_global and next_global */ -#define list_init_named(list,prev,next) \ - ((list) = NULL) +#define list_init_named(list, prev, next) ((list) = NULL) -#define list_singleton_named(list,item,prev,next) ({ \ - (item)->next = (item)->prev = (item); \ - (list) = (item); \ -}) +#define list_singleton_named(list, item, prev, next) \ + ({ \ + (item)->next = (item)->prev = (item); \ + (list) = (item); \ + }) -#define list_is_empty_named(list,prev,next) \ - ((list) == NULL) +#define list_is_empty_named(list, prev, next) ((list) == NULL) -#define list_is_singleton_named(list,prev,next) \ - ( ((list) != NULL) && ((list)->prev == (list)->next) && ((list) == (list)->next) ) +#define list_is_singleton_named(list, prev, next) \ + (((list) != NULL) && ((list)->prev == (list)->next) && ((list) == (list)->next)) -#define list_get_head_named(list,prev,next) \ - (list) +#define list_get_head_named(list, prev, next) (list) -#define list_get_tail_named(list,prev,next) \ - ((list)?((list)->prev):NULL) +#define list_get_tail_named(list, prev, next) ((list) ? ((list)->prev) : NULL) /* Internal macro : insert before the head == insert at tail */ -#define __list_insert_atleft_named(before_this,item,prev,next) ({ \ - (before_this)->prev->next = (item); \ - (item)->prev = (before_this)->prev; \ - (before_this)->prev = (item); \ - (item)->next = (before_this); \ -}) +#define __list_insert_atleft_named(before_this, item, prev, next) \ + ({ \ + (before_this)->prev->next = (item); \ + (item)->prev = (before_this)->prev; \ + (before_this)->prev = (item); \ + (item)->next = (before_this); \ + }) /* @note Before_this and item are expected to be valid ! */ -#define list_insert_before_named(list,before_this,item,prev,next) ({ \ - __list_insert_atleft_named(before_this,item,prev,next); \ - if ((list) == (before_this)) (list) = (item); \ -}) +#define list_insert_before_named(list, before_this, item, prev, next) \ + ({ \ + __list_insert_atleft_named(before_this, item, prev, next); \ + if ((list) == (before_this)) \ + (list) = (item); \ + }) /** @note After_this and item are expected to be valid ! */ -#define list_insert_after_named(list,after_this,item,prev,next) ({ \ - (after_this)->next->prev = (item); \ - (item)->next = (after_this)->next; \ - (after_this)->next = (item); \ - (item)->prev = (after_this); \ -}) +#define list_insert_after_named(list, after_this, item, prev, next) \ + ({ \ + (after_this)->next->prev = (item); \ + (item)->next = (after_this)->next; \ + (after_this)->next = (item); \ + (item)->prev = (after_this); \ + }) -#define list_add_head_named(list,item,prev,next) ({ \ - if (list) \ - list_insert_before_named(list,list,item,prev,next); \ - else \ - list_singleton_named(list,item,prev,next); \ - (list) = (item); \ -}) +#define list_add_head_named(list, item, prev, next) \ + ({ \ + if (list) \ + list_insert_before_named(list, list, item, prev, next); \ + else \ + list_singleton_named(list, item, prev, next); \ + (list) = (item); \ + }) -#define list_add_tail_named(list,item,prev,next) ({ \ - if (list) \ - __list_insert_atleft_named(list,item,prev,next); \ - else \ - list_singleton_named(list,item,prev,next); \ -}) +#define list_add_tail_named(list, item, prev, next) \ + ({ \ + if (list) \ + __list_insert_atleft_named(list, item, prev, next); \ + else \ + list_singleton_named(list, item, prev, next); \ + }) /** @note NO check whether item really is in list ! */ -#define list_delete_named(list,item,prev,next) ({ \ - if ( ((item)->next == (item)) && ((item)->prev == (item)) ) \ - (item)->next = (item)->prev = (list) = NULL; \ - else { \ - (item)->prev->next = (item)->next; \ - (item)->next->prev = (item)->prev; \ - if ((item) == (list)) (list) = (item)->next; \ - (item)->prev = (item)->next = NULL; \ - } \ -}) +#define list_delete_named(list, item, prev, next) \ + ({ \ + if (((item)->next == (item)) && ((item)->prev == (item))) \ + (item)->next = (item)->prev = (list) = NULL; \ + else { \ + (item)->prev->next = (item)->next; \ + (item)->next->prev = (item)->prev; \ + if ((item) == (list)) \ + (list) = (item)->next; \ + (item)->prev = (item)->next = NULL; \ + } \ + }) -#define list_pop_head_named(list,prev,next) ({ \ - typeof(list) __ret_elt = (list); \ - list_delete_named(list,__ret_elt,prev,next); \ - __ret_elt; }) +#define list_pop_head_named(list, prev, next) \ + ({ \ + typeof(list) __ret_elt = (list); \ + list_delete_named(list, __ret_elt, prev, next); \ + __ret_elt; \ + }) /** Loop statement that iterates through all of its elements, from head to tail */ -#define list_foreach_forward_named(list,iterator,nb_elements,prev,next) \ - for (nb_elements=0, (iterator) = (list) ; \ - (iterator) && (!nb_elements || ((iterator) != (list))) ; \ - nb_elements++, (iterator) = (iterator)->next ) +#define list_foreach_forward_named(list, iterator, nb_elements, prev, next) \ + for (nb_elements = 0, (iterator) = (list); \ + (iterator) && (!nb_elements || ((iterator) != (list))); \ + nb_elements++, (iterator) = (iterator)->next) /** Loop statement that iterates through all of its elements, from tail back to head */ -#define list_foreach_backward_named(list,iterator,nb_elements,prev,next) \ - for (nb_elements=0, (iterator) = list_get_tail_named(list,prev,next) ; \ - (iterator) && (!nb_elements || \ - ((iterator) != list_get_tail_named(list,prev,next))) ; \ - nb_elements++, (iterator) = (iterator)->prev ) +#define list_foreach_backward_named(list, iterator, nb_elements, prev, next) \ + for (nb_elements = 0, (iterator) = list_get_tail_named(list, prev, next); \ + (iterator) && \ + (!nb_elements || ((iterator) != list_get_tail_named(list, prev, next))); \ + nb_elements++, (iterator) = (iterator)->prev) #define list_foreach_named list_foreach_forward_named /** True when we exitted early from the foreach loop (ie break) */ -#define list_foreach_early_break(list,iterator,nb_elements) \ - ((list) && ( \ - ((list) != (iterator)) || \ - ( ((list) == (iterator)) && (nb_elements == 0)) )) +#define list_foreach_early_break(list, iterator, nb_elements) \ + ((list) && (((list) != (iterator)) || (((list) == (iterator)) && (nb_elements == 0)))) /** Loop statement that also removes the item at each iteration. The body of the loop is allowed to delete the iterator element from memory. */ -#define list_collapse_named(list,iterator,prev,next) \ - for ( ; ({ ((iterator) = (list)) ; \ - if (list) list_delete_named(list,iterator,prev,next) ; \ - (iterator); }) ; ) - +#define list_collapse_named(list, iterator, prev, next) \ + for (; ({ \ + ((iterator) = (list)); \ + if (list) \ + list_delete_named(list, iterator, prev, next); \ + (iterator); \ + });) /* * the same macros : assume that the prev and next fields are really * named "prev" and "next" */ -#define list_init(list) \ - list_init_named(list,prev,next) +#define list_init(list) list_init_named(list, prev, next) -#define list_singleton(list,item) \ - list_singleton_named(list,item,prev,next) +#define list_singleton(list, item) list_singleton_named(list, item, prev, next) -#define list_is_empty(list) \ - list_is_empty_named(list,prev,next) +#define list_is_empty(list) list_is_empty_named(list, prev, next) -#define list_is_singleton(list) \ - list_is_singleton_named(list,prev,next) +#define list_is_singleton(list) list_is_singleton_named(list, prev, next) -#define list_get_head(list) \ - list_get_head_named(list,prev,next) \ +#define list_get_head(list) list_get_head_named(list, prev, next) -#define list_get_tail(list) \ - list_get_tail_named(list,prev,next) \ +#define list_get_tail(list) list_get_tail_named(list, prev, next) /* @note Before_this and item are expected to be valid ! */ -#define list_insert_after(list,after_this,item) \ - list_insert_after_named(list,after_this,item,prev,next) +#define list_insert_after(list, after_this, item) \ + list_insert_after_named(list, after_this, item, prev, next) /* @note After_this and item are expected to be valid ! */ -#define list_insert_before(list,before_this,item) \ - list_insert_before_named(list,before_this,item,prev,next) +#define list_insert_before(list, before_this, item) \ + list_insert_before_named(list, before_this, item, prev, next) -#define list_add_head(list,item) \ - list_add_head_named(list,item,prev,next) +#define list_add_head(list, item) list_add_head_named(list, item, prev, next) -#define list_add_tail(list,item) \ - list_add_tail_named(list,item,prev,next) +#define list_add_tail(list, item) list_add_tail_named(list, item, prev, next) /* @note NO check whether item really is in list ! */ -#define list_delete(list,item) \ - list_delete_named(list,item,prev,next) +#define list_delete(list, item) list_delete_named(list, item, prev, next) -#define list_pop_head(list) \ - list_pop_head_named(list,prev,next) +#define list_pop_head(list) list_pop_head_named(list, prev, next) -#define list_foreach_forward(list,iterator,nb_elements) \ - list_foreach_forward_named(list,iterator,nb_elements,prev,next) +#define list_foreach_forward(list, iterator, nb_elements) \ + list_foreach_forward_named(list, iterator, nb_elements, prev, next) -#define list_foreach_backward(list,iterator,nb_elements) \ - list_foreach_backward_named(list,iterator,nb_elements,prev,next) +#define list_foreach_backward(list, iterator, nb_elements) \ + list_foreach_backward_named(list, iterator, nb_elements, prev, next) #define list_foreach list_foreach_forward -#define list_collapse(list,iterator) \ - list_collapse_named(list,iterator,prev,next) +#define list_collapse(list, iterator) list_collapse_named(list, iterator, prev, next) #endif /* _SOS_LIST_H_ */ diff --git a/core/main.c b/core/main.c index b93ee9b..03c8ce4 100644 --- a/core/main.c +++ b/core/main.c @@ -26,14 +26,14 @@ void cpuid(int code, uint32_t *a, uint32_t *d) asm volatile("cpuid" : "=a"(*a), "=d"(*d) : "0"(code) : "ebx", "ecx"); } -void idleThread(void *arg){ +void idleThread(void *arg) +{ (void)arg; int count = 0; - while(1) + while (1) printIntDetails(count++, GREEN, BLACK, 0, VGA_HEIGHT - 1); } - // Multiboot information available here : // https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#kernel_002ec // https://www.gnu.org/software/grub/manual/multiboot/html_node/Boot-information-format.html#Boot%20information%20format @@ -83,7 +83,7 @@ void kmain(unsigned long magic, unsigned long addr) struct multiboot_mmap_entry *mmap = (struct multiboot_mmap_entry *)mbi->mmap_addr; uint size = mbi->mmap_length / sizeof(struct multiboot_mmap_entry); pr_devel("mmap buffer at %d size %d %d\n", mbi->mmap_addr, mbi->mmap_length, - sizeof(multiboot_memory_map_t)); + sizeof(multiboot_memory_map_t)); for (uint i = 0; i < size; i++) { printf("base_addr 0x%x 0x%x, length = 0x%x 0x%x, type = 0x%x\n", (unsigned)(mmap[i].addr >> 32), (unsigned)(mmap[i].addr & 0xffffffff), @@ -112,8 +112,8 @@ void kmain(unsigned long magic, unsigned long addr) printf("Enabling HW interrupts\n"); exceptionSetRoutine(EXCEPTION_DOUBLE_FAULT, ACCESS_INTERRUPT(EXCEPTION_DOUBLE_FAULT)); exceptionSetRoutine(EXCEPTION_DIVIDE_ZERO, ACCESS_INTERRUPT(EXCEPTION_DIVIDE_ZERO)); - //Used by the DBG - //exceptionSetRoutine(EXCEPTION_DEBUG, ACCESS_INTERRUPT(EXCEPTION_DEBUG)); + // Used by the DBG + // exceptionSetRoutine(EXCEPTION_DEBUG, ACCESS_INTERRUPT(EXCEPTION_DEBUG)); exceptionSetRoutine(EXCEPTION_NMI, ACCESS_INTERRUPT(EXCEPTION_NMI)); exceptionSetRoutine(EXCEPTION_BREAKPOINT, ACCESS_INTERRUPT(EXCEPTION_BREAKPOINT)); exceptionSetRoutine(EXCEPTION_OVERFLOW, ACCESS_INTERRUPT(EXCEPTION_OVERFLOW)); diff --git a/core/math.c b/core/math.c index a6b13e5..bdc8c74 100644 --- a/core/math.c +++ b/core/math.c @@ -1,11 +1,9 @@ #include "math.h" -inline uint32_t log2(const uint32_t x) { - uint32_t y; - // Get the highest set bit - asm ( "\tbsr %1, %0\n" - : "=r"(y) - : "r" (x) - ); - return y; +inline uint32_t log2(const uint32_t x) +{ + uint32_t y; + // Get the highest set bit + asm("\tbsr %1, %0\n" : "=r"(y) : "r"(x)); + return y; } diff --git a/core/mem.c b/core/mem.c index cd8c32d..589ab23 100644 --- a/core/mem.c +++ b/core/mem.c @@ -1,7 +1,7 @@ #include "mem.h" +#include "klibc.h" #include "list.h" #include "types.h" -#include "klibc.h" static struct mem_desc *page_desc = (struct mem_desc *)&__ld_kernel_end; static struct mem_desc *free_page; @@ -13,89 +13,88 @@ static unsigned long allocatedPage = 0; int memSetup(paddr_t upperMem, paddr_t *lastUsedOut) { - // Align upper mem (in kB) on page size even if it does loose a page - upperMem = ALIGN_DOWN(upperMem, PAGE_SIZE / 1024); + // Align upper mem (in kB) on page size even if it does loose a page + upperMem = ALIGN_DOWN(upperMem, PAGE_SIZE / 1024); - printf("Available Mem from 0x%x to 0x%x: %dMB \n", &__ld_kernel_end, upperMem * 1024, - (upperMem * 1024 - (uint32_t)&__ld_kernel_end) / (1024*1024)); - // Memory description is stored after the kernel. We need some place to store it - unsigned long memdesc_end = - (unsigned long)page_desc + - ((upperMem) / (PAGE_SIZE / 1024)) * sizeof(struct mem_desc); - uint lastUsed = (memdesc_end >> PAGE_SHIFT) + 1; - list_init(free_page); - list_init(used_page); - bottom_mem = lastUsed; - *lastUsedOut = memdesc_end; - top_mem = upperMem * 1024; - for (uint i = 0; i < (upperMem / (PAGE_SIZE / 1024)); i++) { - struct mem_desc *mem = &page_desc[i]; - if (i < lastUsed) { - mem->ref = 1; - list_add_tail(used_page, mem); - } else { - mem->ref = 0; - list_add_tail(free_page, mem); - } - mem->phy_addr = i * PAGE_SIZE; - } - return 0; + printf("Available Mem from 0x%x to 0x%x: %dMB \n", &__ld_kernel_end, upperMem * 1024, + (upperMem * 1024 - (uint32_t)&__ld_kernel_end) / (1024 * 1024)); + // Memory description is stored after the kernel. We need some place to store it + unsigned long memdesc_end = + (unsigned long)page_desc + ((upperMem) / (PAGE_SIZE / 1024)) * sizeof(struct mem_desc); + uint lastUsed = (memdesc_end >> PAGE_SHIFT) + 1; + list_init(free_page); + list_init(used_page); + bottom_mem = lastUsed; + *lastUsedOut = memdesc_end; + top_mem = upperMem * 1024; + for (uint i = 0; i < (upperMem / (PAGE_SIZE / 1024)); i++) { + struct mem_desc *mem = &page_desc[i]; + if (i < lastUsed) { + mem->ref = 1; + list_add_tail(used_page, mem); + } else { + mem->ref = 0; + list_add_tail(free_page, mem); + } + mem->phy_addr = i * PAGE_SIZE; + } + return 0; } struct mem_desc *addr2memDesc(paddr_t addr) { - if (addr > top_mem || addr < bottom_mem) - return NULL; + if (addr > top_mem || addr < bottom_mem) + return NULL; - int idx = addr >> PAGE_SHIFT; - return page_desc + idx; + int idx = addr >> PAGE_SHIFT; + return page_desc + idx; } paddr_t allocPhyPage(void) { - if (list_is_empty(free_page)) { - return (unsigned long)NULL; - } - struct mem_desc *mem = list_pop_head(free_page); - mem->ref = 1; - list_add_tail(used_page, mem); - allocatedPage++; - return mem->phy_addr; + if (list_is_empty(free_page)) { + return (unsigned long)NULL; + } + struct mem_desc *mem = list_pop_head(free_page); + mem->ref = 1; + list_add_tail(used_page, mem); + allocatedPage++; + return mem->phy_addr; } int unrefPhyPage(paddr_t addr) { - struct mem_desc *mem = addr2memDesc(addr); - if (!mem) { - return -1; - } - mem->ref--; - if (mem->ref == 0) { - allocatedPage--; - list_delete(used_page, mem); - list_add_tail(free_page, mem); - } + struct mem_desc *mem = addr2memDesc(addr); + if (!mem) { + return -1; + } + mem->ref--; + if (mem->ref == 0) { + allocatedPage--; + list_delete(used_page, mem); + list_add_tail(free_page, mem); + } - return mem->ref; + return mem->ref; } int refPhyPage(paddr_t addr) { - struct mem_desc *mem = addr2memDesc(addr); - if (!mem) { - return -1; - } - mem->ref++; - if (mem->ref == 1) { - allocatedPage++; - list_add_tail(used_page, mem); - list_delete(free_page, mem); - } + struct mem_desc *mem = addr2memDesc(addr); + if (!mem) { + return -1; + } + mem->ref++; + if (mem->ref == 1) { + allocatedPage++; + list_add_tail(used_page, mem); + list_delete(free_page, mem); + } - return 0; + return 0; } unsigned long getNbAllocatedPage(void) { - return allocatedPage; + return allocatedPage; } diff --git a/core/mem.h b/core/mem.h index 1652b78..339f1d5 100644 --- a/core/mem.h +++ b/core/mem.h @@ -1,7 +1,6 @@ #pragma once -#include "types.h" #include "stdarg.h" - +#include "types.h" #define PAGE_SHIFT 12U #define PAGE_SIZE (1U << PAGE_SHIFT) @@ -10,13 +9,12 @@ extern uint32_t __ld_kernel_begin; extern uint32_t __ld_kernel_end; -struct mem_desc{ - paddr_t phy_addr; - long ref; - struct mem_desc *next, *prev; +struct mem_desc { + paddr_t phy_addr; + long ref; + struct mem_desc *next, *prev; }; - int memSetup(paddr_t upperMem, paddr_t *lastUsed); paddr_t allocPhyPage(void); int unrefPhyPage(paddr_t addr); diff --git a/core/multiboot.h b/core/multiboot.h index 0ee4acc..f19a919 100644 --- a/core/multiboot.h +++ b/core/multiboot.h @@ -98,164 +98,164 @@ typedef unsigned int multiboot_uint32_t; typedef unsigned long long multiboot_uint64_t; struct multiboot_header { - /* Must be MULTIBOOT_MAGIC - see above. */ - multiboot_uint32_t magic; + /* Must be MULTIBOOT_MAGIC - see above. */ + multiboot_uint32_t magic; - /* Feature flags. */ - multiboot_uint32_t flags; + /* Feature flags. */ + multiboot_uint32_t flags; - /* The above fields plus this one must equal 0 mod 2^32. */ - multiboot_uint32_t checksum; + /* The above fields plus this one must equal 0 mod 2^32. */ + multiboot_uint32_t checksum; - /* These are only valid if MULTIBOOT_AOUT_KLUDGE is set. */ - multiboot_uint32_t header_addr; - multiboot_uint32_t load_addr; - multiboot_uint32_t load_end_addr; - multiboot_uint32_t bss_end_addr; - multiboot_uint32_t entry_addr; + /* These are only valid if MULTIBOOT_AOUT_KLUDGE is set. */ + multiboot_uint32_t header_addr; + multiboot_uint32_t load_addr; + multiboot_uint32_t load_end_addr; + multiboot_uint32_t bss_end_addr; + multiboot_uint32_t entry_addr; - /* These are only valid if MULTIBOOT_VIDEO_MODE is set. */ - multiboot_uint32_t mode_type; - multiboot_uint32_t width; - multiboot_uint32_t height; - multiboot_uint32_t depth; + /* These are only valid if MULTIBOOT_VIDEO_MODE is set. */ + multiboot_uint32_t mode_type; + multiboot_uint32_t width; + multiboot_uint32_t height; + multiboot_uint32_t depth; }; /* The symbol table for a.out. */ struct multiboot_aout_symbol_table { - multiboot_uint32_t tabsize; - multiboot_uint32_t strsize; - multiboot_uint32_t addr; - multiboot_uint32_t reserved; + multiboot_uint32_t tabsize; + multiboot_uint32_t strsize; + multiboot_uint32_t addr; + multiboot_uint32_t reserved; }; typedef struct multiboot_aout_symbol_table multiboot_aout_symbol_table_t; /* The section header table for ELF. */ struct multiboot_elf_section_header_table { - multiboot_uint32_t num; - multiboot_uint32_t size; - multiboot_uint32_t addr; - multiboot_uint32_t shndx; + multiboot_uint32_t num; + multiboot_uint32_t size; + multiboot_uint32_t addr; + multiboot_uint32_t shndx; }; typedef struct multiboot_elf_section_header_table multiboot_elf_section_header_table_t; struct multiboot_info { - /* Multiboot info version number */ - multiboot_uint32_t flags; + /* Multiboot info version number */ + multiboot_uint32_t flags; - /* Available memory from BIOS */ - multiboot_uint32_t mem_lower; - multiboot_uint32_t mem_upper; + /* Available memory from BIOS */ + multiboot_uint32_t mem_lower; + multiboot_uint32_t mem_upper; - /* "root" partition */ - multiboot_uint32_t boot_device; + /* "root" partition */ + multiboot_uint32_t boot_device; - /* Kernel command line */ - multiboot_uint32_t cmdline; + /* Kernel command line */ + multiboot_uint32_t cmdline; - /* Boot-Module list */ - multiboot_uint32_t mods_count; - multiboot_uint32_t mods_addr; + /* Boot-Module list */ + multiboot_uint32_t mods_count; + multiboot_uint32_t mods_addr; - union { - multiboot_aout_symbol_table_t aout_sym; - multiboot_elf_section_header_table_t elf_sec; - } u; + union { + multiboot_aout_symbol_table_t aout_sym; + multiboot_elf_section_header_table_t elf_sec; + } u; - /* Memory Mapping buffer */ - multiboot_uint32_t mmap_length; - multiboot_uint32_t mmap_addr; + /* Memory Mapping buffer */ + multiboot_uint32_t mmap_length; + multiboot_uint32_t mmap_addr; - /* Drive Info buffer */ - multiboot_uint32_t drives_length; - multiboot_uint32_t drives_addr; + /* Drive Info buffer */ + multiboot_uint32_t drives_length; + multiboot_uint32_t drives_addr; - /* ROM configuration table */ - multiboot_uint32_t config_table; + /* ROM configuration table */ + multiboot_uint32_t config_table; - /* Boot Loader Name */ - multiboot_uint32_t boot_loader_name; + /* Boot Loader Name */ + multiboot_uint32_t boot_loader_name; - /* APM table */ - multiboot_uint32_t apm_table; + /* APM table */ + multiboot_uint32_t apm_table; - /* Video */ - multiboot_uint32_t vbe_control_info; - multiboot_uint32_t vbe_mode_info; - multiboot_uint16_t vbe_mode; - multiboot_uint16_t vbe_interface_seg; - multiboot_uint16_t vbe_interface_off; - multiboot_uint16_t vbe_interface_len; + /* Video */ + multiboot_uint32_t vbe_control_info; + multiboot_uint32_t vbe_mode_info; + multiboot_uint16_t vbe_mode; + multiboot_uint16_t vbe_interface_seg; + multiboot_uint16_t vbe_interface_off; + multiboot_uint16_t vbe_interface_len; - multiboot_uint64_t framebuffer_addr; - multiboot_uint32_t framebuffer_pitch; - multiboot_uint32_t framebuffer_width; - multiboot_uint32_t framebuffer_height; - multiboot_uint8_t framebuffer_bpp; + multiboot_uint64_t framebuffer_addr; + multiboot_uint32_t framebuffer_pitch; + multiboot_uint32_t framebuffer_width; + multiboot_uint32_t framebuffer_height; + multiboot_uint8_t framebuffer_bpp; #define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 #define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 #define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2 - multiboot_uint8_t framebuffer_type; - union { - struct { - multiboot_uint32_t framebuffer_palette_addr; - multiboot_uint16_t framebuffer_palette_num_colors; + multiboot_uint8_t framebuffer_type; + union { + struct { + multiboot_uint32_t framebuffer_palette_addr; + multiboot_uint16_t framebuffer_palette_num_colors; + }; + struct { + multiboot_uint8_t framebuffer_red_field_position; + multiboot_uint8_t framebuffer_red_mask_size; + multiboot_uint8_t framebuffer_green_field_position; + multiboot_uint8_t framebuffer_green_mask_size; + multiboot_uint8_t framebuffer_blue_field_position; + multiboot_uint8_t framebuffer_blue_mask_size; + }; }; - struct { - multiboot_uint8_t framebuffer_red_field_position; - multiboot_uint8_t framebuffer_red_mask_size; - multiboot_uint8_t framebuffer_green_field_position; - multiboot_uint8_t framebuffer_green_mask_size; - multiboot_uint8_t framebuffer_blue_field_position; - multiboot_uint8_t framebuffer_blue_mask_size; - }; - }; }; typedef struct multiboot_info multiboot_info_t; struct multiboot_color { - multiboot_uint8_t red; - multiboot_uint8_t green; - multiboot_uint8_t blue; + multiboot_uint8_t red; + multiboot_uint8_t green; + multiboot_uint8_t blue; }; struct multiboot_mmap_entry { - multiboot_uint32_t size; - multiboot_uint64_t addr; - multiboot_uint64_t len; + multiboot_uint32_t size; + multiboot_uint64_t addr; + multiboot_uint64_t len; #define MULTIBOOT_MEMORY_AVAILABLE 1 #define MULTIBOOT_MEMORY_RESERVED 2 #define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3 #define MULTIBOOT_MEMORY_NVS 4 #define MULTIBOOT_MEMORY_BADRAM 5 - multiboot_uint32_t type; + multiboot_uint32_t type; } __attribute__((packed)); typedef struct multiboot_mmap_entry multiboot_memory_map_t; struct multiboot_mod_list { - /* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */ - multiboot_uint32_t mod_start; - multiboot_uint32_t mod_end; + /* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */ + multiboot_uint32_t mod_start; + multiboot_uint32_t mod_end; - /* Module command line */ - multiboot_uint32_t cmdline; + /* Module command line */ + multiboot_uint32_t cmdline; - /* padding to take it to 16 bytes (must be zero) */ - multiboot_uint32_t pad; + /* padding to take it to 16 bytes (must be zero) */ + multiboot_uint32_t pad; }; typedef struct multiboot_mod_list multiboot_module_t; /* APM BIOS info. */ struct multiboot_apm_info { - multiboot_uint16_t version; - multiboot_uint16_t cseg; - multiboot_uint32_t offset; - multiboot_uint16_t cseg_16; - multiboot_uint16_t dseg; - multiboot_uint16_t flags; - multiboot_uint16_t cseg_len; - multiboot_uint16_t cseg_16_len; - multiboot_uint16_t dseg_len; + multiboot_uint16_t version; + multiboot_uint16_t cseg; + multiboot_uint32_t offset; + multiboot_uint16_t cseg_16; + multiboot_uint16_t dseg; + multiboot_uint16_t flags; + multiboot_uint16_t cseg_len; + multiboot_uint16_t cseg_16_len; + multiboot_uint16_t dseg_len; }; #endif /* ! ASM_FILE */ diff --git a/core/paging.c b/core/paging.c index c2ed93b..9da3fb2 100644 --- a/core/paging.c +++ b/core/paging.c @@ -26,181 +26,179 @@ static unsigned long mappedPage = 0; struct pde { - uint32_t present : 1; - uint32_t write : 1; // 0 read - 1 RW - uint32_t user : 1; // 0 supervisor - 1 user - uint32_t write_through : 1; // 0 write-back - 1 write_through - uint32_t cache_disable : 1; - uint32_t access : 1; // have been accessed - uint32_t zero : 1; // Not used - uint32_t size : 1; // 0 for 4Kb 1 for 4Mb - uint32_t ignored : 1; - uint32_t available : 3; - uint32_t pt_addr : 20; + uint32_t present : 1; + uint32_t write : 1; // 0 read - 1 RW + uint32_t user : 1; // 0 supervisor - 1 user + uint32_t write_through : 1; // 0 write-back - 1 write_through + uint32_t cache_disable : 1; + uint32_t access : 1; // have been accessed + uint32_t zero : 1; // Not used + uint32_t size : 1; // 0 for 4Kb 1 for 4Mb + uint32_t ignored : 1; + uint32_t available : 3; + uint32_t pt_addr : 20; } __attribute__((packed)); struct pte { - uint32_t present : 1; - uint32_t write : 1; // 0 read - 1 RW - uint32_t user : 1; // 0 supervisor - 1 user - uint32_t write_through : 1; // 0 write-back - 1 write_through - uint32_t cache_disable : 1; - uint32_t access : 1; // have been accessed - uint32_t dirty : 1; // if set, indicates that page has been written to. This flag is - // not updated by the CPU, and once set will not unset itself. - uint32_t zero : 1; // if PAT is supported, shall indicate the memory type. Otherwise, - // it must be 0. - uint32_t global : 1; // if set, prevents the TLB from updating the address in its cache - // if CR3 is reset. Note, that the page global enable bit in CR4 - // must be set to enable this feature. - uint32_t available : 3; - uint32_t paddr : 20; + uint32_t present : 1; + uint32_t write : 1; // 0 read - 1 RW + uint32_t user : 1; // 0 supervisor - 1 user + uint32_t write_through : 1; // 0 write-back - 1 write_through + uint32_t cache_disable : 1; + uint32_t access : 1; // have been accessed + uint32_t dirty : 1; // if set, indicates that page has been written to. This flag is + // not updated by the CPU, and once set will not unset itself. + uint32_t zero : 1; // if PAT is supported, shall indicate the memory type. Otherwise, + // it must be 0. + uint32_t global : 1; // if set, prevents the TLB from updating the address in its cache + // if CR3 is reset. Note, that the page global enable bit in CR4 + // must be set to enable this feature. + uint32_t available : 3; + uint32_t paddr : 20; } __attribute__((packed)); struct pdbr { - uint32_t zero1 : 3; // reserved - uint32_t write_through : 1; // 0 write-back - 1 write-through - uint32_t cache_disabled : 1; // 1=cache disabled - uint32_t zero2 : 7; // reserved - uint32_t pd_paddr : 20; + uint32_t zero1 : 3; // reserved + uint32_t write_through : 1; // 0 write-back - 1 write-through + uint32_t cache_disabled : 1; // 1=cache disabled + uint32_t zero2 : 7; // reserved + uint32_t pd_paddr : 20; } __attribute__((packed)); // invalidate the TLB entry for the page located at the given virtual address static inline void __native_flush_tlb_single(unsigned long addr) { - asm volatile("invlpg (%0)" ::"r"(addr) : "memory"); + asm volatile("invlpg (%0)" ::"r"(addr) : "memory"); } int pagingSetup(paddr_t upperKernelAddr) { - struct pdbr cr3; + struct pdbr cr3; - // x86 got 1024 of pde for 4Byte each: 4ko ! - struct pde *pd = (struct pde *)allocPhyPage(); + // x86 got 1024 of pde for 4Byte each: 4ko ! + struct pde *pd = (struct pde *)allocPhyPage(); - memset(pd, 0, PAGE_SIZE); - memset(&cr3, 0x0, sizeof(struct pdbr)); + memset(pd, 0, PAGE_SIZE); + memset(&cr3, 0x0, sizeof(struct pdbr)); - cr3.pd_paddr = ((paddr_t)pd) >> 12; + cr3.pd_paddr = ((paddr_t)pd) >> 12; - // MMU not enabled for the moment. No need to use mirroring - // Identity mapping up to upperKernelAddr - for (paddr_t i = 0; i < upperKernelAddr; i += PAGE_SIZE) { - uint pdEntry = i >> (PD_SHIFT); - uint ptEntry = (i >> PT_SHIFT) & PTE_MASK; - struct pte *pt; - if (pd[pdEntry].present) { - pt = (struct pte *)(pd[pdEntry].pt_addr << PT_SHIFT); - refPhyPage((paddr_t)pt); - } else { - pt = (struct pte *)allocPhyPage(); + // MMU not enabled for the moment. No need to use mirroring + // Identity mapping up to upperKernelAddr + for (paddr_t i = 0; i < upperKernelAddr; i += PAGE_SIZE) { + uint pdEntry = i >> (PD_SHIFT); + uint ptEntry = (i >> PT_SHIFT) & PTE_MASK; + struct pte *pt; + if (pd[pdEntry].present) { + pt = (struct pte *)(pd[pdEntry].pt_addr << PT_SHIFT); + refPhyPage((paddr_t)pt); + } else { + pt = (struct pte *)allocPhyPage(); - memset(pt, 0, PAGE_SIZE); - pd[pdEntry].present = 1; - pd[pdEntry].write = 1; - pd[pdEntry].pt_addr = ((paddr_t)pt >> PT_SHIFT); - } + memset(pt, 0, PAGE_SIZE); + pd[pdEntry].present = 1; + pd[pdEntry].write = 1; + pd[pdEntry].pt_addr = ((paddr_t)pt >> PT_SHIFT); + } - pt[ptEntry].present = 1; - pt[ptEntry].write = 1; // TODO set Kernel code as RO - pt[ptEntry].paddr = i >> PAGE_SHIFT; - } + pt[ptEntry].present = 1; + pt[ptEntry].write = 1; // TODO set Kernel code as RO + pt[ptEntry].paddr = i >> PAGE_SHIFT; + } - // Setup mirroring - pd[PD_MIRROR_PAGE_IDX].present = 1; - pd[PD_MIRROR_PAGE_IDX].write = 1; - pd[PD_MIRROR_PAGE_IDX].pt_addr = ((paddr_t)pd >> PT_SHIFT); + // Setup mirroring + pd[PD_MIRROR_PAGE_IDX].present = 1; + pd[PD_MIRROR_PAGE_IDX].write = 1; + pd[PD_MIRROR_PAGE_IDX].pt_addr = ((paddr_t)pd >> PT_SHIFT); - // Loading of the PDBR in the MMU: - asm volatile("movl %0,%%cr3\n\t" - "movl %%cr0,%%eax\n\t" - "orl $0x80010000, %%eax\n\t" /* bit 31 | bit 16 */ - "movl %%eax,%%cr0\n\t" - "jmp 1f\n\t" - "1:\n\t" - "movl $2f, %%eax\n\t" - "jmp *%%eax\n\t" - "2:\n\t" ::"r"(cr3) - : "memory", "eax"); - return 0; + // Loading of the PDBR in the MMU: + asm volatile("movl %0,%%cr3\n\t" + "movl %%cr0,%%eax\n\t" + "orl $0x80010000, %%eax\n\t" /* bit 31 | bit 16 */ + "movl %%eax,%%cr0\n\t" + "jmp 1f\n\t" + "1:\n\t" + "movl $2f, %%eax\n\t" + "jmp *%%eax\n\t" + "2:\n\t" ::"r"(cr3) + : "memory", "eax"); + return 0; } int pageMap(vaddr_t vaddr, paddr_t paddr, int flags) { - uint pdEntry = vaddr >> (PD_SHIFT); - uint ptEntry = (vaddr >> PT_SHIFT) & PTE_MASK; + uint pdEntry = vaddr >> (PD_SHIFT); + uint ptEntry = (vaddr >> PT_SHIFT) & PTE_MASK; - // Thank to mirroring, we can access the PD - struct pde *pd = (struct pde *)((PD_MIRROR_PAGE_IDX << PD_SHIFT) + - (PD_MIRROR_PAGE_IDX << PT_SHIFT)); + // Thank to mirroring, we can access the PD + struct pde *pd = + (struct pde *)((PD_MIRROR_PAGE_IDX << PD_SHIFT) + (PD_MIRROR_PAGE_IDX << PT_SHIFT)); - struct pte *pt = - (struct pte *)((PD_MIRROR_PAGE_IDX << PD_SHIFT) + (pdEntry << PT_SHIFT)); + struct pte *pt = (struct pte *)((PD_MIRROR_PAGE_IDX << PD_SHIFT) + (pdEntry << PT_SHIFT)); - if (!pd[pdEntry].present) { - paddr_t ptPhy = allocPhyPage(); - if (ptPhy == (vaddr_t)NULL) - return -ENOMEM; + if (!pd[pdEntry].present) { + paddr_t ptPhy = allocPhyPage(); + if (ptPhy == (vaddr_t)NULL) + return -ENOMEM; - pd[pdEntry].user = (flags & PAGING_MEM_USER) ? 1 : 0; - pd[pdEntry].present = 1; - pd[pdEntry].write = 1; - pd[pdEntry].pt_addr = (ptPhy >> PT_SHIFT); + pd[pdEntry].user = (flags & PAGING_MEM_USER) ? 1 : 0; + pd[pdEntry].present = 1; + pd[pdEntry].write = 1; + pd[pdEntry].pt_addr = (ptPhy >> PT_SHIFT); - __native_flush_tlb_single((vaddr_t)pt); - memset((void *)pt, 0, PAGE_SIZE); - } else { + __native_flush_tlb_single((vaddr_t)pt); + memset((void *)pt, 0, PAGE_SIZE); + } else { - // Already mapped ? Remove old mapping - if (pt[ptEntry].present) { - unrefPhyPage(pt[ptEntry].paddr << PAGE_SHIFT); - } // PTE not already used ? We will use it ! So increase the PT ref count - else { - refPhyPage(pd[pdEntry].pt_addr << PAGE_SHIFT); - } - } + // Already mapped ? Remove old mapping + if (pt[ptEntry].present) { + unrefPhyPage(pt[ptEntry].paddr << PAGE_SHIFT); + } // PTE not already used ? We will use it ! So increase the PT ref count + else { + refPhyPage(pd[pdEntry].pt_addr << PAGE_SHIFT); + } + } - pt[ptEntry].user = (flags & PAGING_MEM_USER) ? 1 : 0; - pt[ptEntry].present = 1; - pt[ptEntry].write = (flags & PAGING_MEM_WRITE) ? 1 : 0; - pt[ptEntry].paddr = paddr >> PAGE_SHIFT; - refPhyPage(paddr); + pt[ptEntry].user = (flags & PAGING_MEM_USER) ? 1 : 0; + pt[ptEntry].present = 1; + pt[ptEntry].write = (flags & PAGING_MEM_WRITE) ? 1 : 0; + pt[ptEntry].paddr = paddr >> PAGE_SHIFT; + refPhyPage(paddr); - __native_flush_tlb_single(vaddr); - mappedPage++; - return 0; + __native_flush_tlb_single(vaddr); + mappedPage++; + return 0; } int pageUnmap(vaddr_t vaddr) { - uint pdEntry = vaddr >> (PD_SHIFT); - uint ptEntry = (vaddr >> PT_SHIFT) & PTE_MASK; + uint pdEntry = vaddr >> (PD_SHIFT); + uint ptEntry = (vaddr >> PT_SHIFT) & PTE_MASK; - // Thank to mirroring, we can access the PD - struct pde *pd = (struct pde *)((PD_MIRROR_PAGE_IDX << PD_SHIFT) + - (PD_MIRROR_PAGE_IDX << PT_SHIFT)); + // Thank to mirroring, we can access the PD + struct pde *pd = + (struct pde *)((PD_MIRROR_PAGE_IDX << PD_SHIFT) + (PD_MIRROR_PAGE_IDX << PT_SHIFT)); - struct pte *pt = - (struct pte *)((PD_MIRROR_PAGE_IDX << PD_SHIFT) + (pdEntry << PT_SHIFT)); - if (!pd[pdEntry].present) - return -EINVAL; - if (!pt[ptEntry].present) - return -EINVAL; + struct pte *pt = (struct pte *)((PD_MIRROR_PAGE_IDX << PD_SHIFT) + (pdEntry << PT_SHIFT)); + if (!pd[pdEntry].present) + return -EINVAL; + if (!pt[ptEntry].present) + return -EINVAL; - unrefPhyPage(pt[ptEntry].paddr << PAGE_SHIFT); - pt[ptEntry].present = 0; + unrefPhyPage(pt[ptEntry].paddr << PAGE_SHIFT); + pt[ptEntry].present = 0; - // PTE not used. Decrease refcount on it. Is PT not used anymore ? - if (unrefPhyPage(pd[pdEntry].pt_addr << PT_SHIFT) == 0) { - pd[pdEntry].present = 0; - __native_flush_tlb_single((vaddr_t)pt); - } - __native_flush_tlb_single(vaddr); - mappedPage--; - return 0; + // PTE not used. Decrease refcount on it. Is PT not used anymore ? + if (unrefPhyPage(pd[pdEntry].pt_addr << PT_SHIFT) == 0) { + pd[pdEntry].present = 0; + __native_flush_tlb_single((vaddr_t)pt); + } + __native_flush_tlb_single(vaddr); + mappedPage--; + return 0; } unsigned long getNbMappedPage(void) { - return mappedPage; + return mappedPage; } diff --git a/core/segment.h b/core/segment.h index 570464b..a548b1c 100644 --- a/core/segment.h +++ b/core/segment.h @@ -5,16 +5,16 @@ modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. + USA. */ #pragma once @@ -36,19 +36,15 @@ * * @see gdt.h */ -#define SEG_NULL 0 /* NULL segment, unused by the procesor */ +#define SEG_NULL 0 /* NULL segment, unused by the procesor */ #define SEG_KCODE 1 /* Kernel code segment */ #define SEG_KDATA 2 /* Kernel data segment */ - /** * Helper macro that builds a segment register's value */ -#define BUILD_SEGMENT_REG_VALUE(desc_privilege,in_ldt,seg_index) \ - ( (((desc_privilege) & 0x3) << 0) \ - | (((in_ldt)?1:0) << 2) \ - | ((seg_index) << 3) ) - +#define BUILD_SEGMENT_REG_VALUE(desc_privilege, in_ldt, seg_index) \ + ((((desc_privilege)&0x3) << 0) | (((in_ldt) ? 1 : 0) << 2) | ((seg_index) << 3)) /* * Local segment selectors (LDT) for SOS/x86 diff --git a/core/stack.c b/core/stack.c index e29037f..9a7d9ff 100644 --- a/core/stack.c +++ b/core/stack.c @@ -1,48 +1,47 @@ #include "stack.h" -#include "types.h" #include "klibc.h" +#include "types.h" void printStackTrace(unsigned int maxFrames) { #ifdef DEBUG - // Now on Stack: - // ( potential second function argument ) - // first function argument (maxFrames) - // return address from caller - // EBP (Extended Base Pointer) of calling function - // - // retrace function from address could done by optaining function address with gdb or - // objdump -S kernel - unsigned int *ebp = __builtin_frame_address(0); - for (unsigned int frame = 0; frame < maxFrames; frame++) { - unsigned int eip = ebp[1]; - if (eip == 0) { - // No caller on stack - break; - } - unsigned int *arguments = ebp + 2; - printf("[%d] 0x%x (", frame, eip); - int nbArg = 0; - do { - if ((_stack_bottom <= (vaddr_t)arguments) && - ((vaddr_t)arguments <= _stack_top)) { - printf(" 0x%x", *arguments); - arguments += 1; - } else { - break; - } - nbArg++; - if (nbArg >= 4) { - break; - } - } while (1); - printf(")\n"); - ebp = (unsigned int *)(ebp[0]); - } + // Now on Stack: + // ( potential second function argument ) + // first function argument (maxFrames) + // return address from caller + // EBP (Extended Base Pointer) of calling function + // + // retrace function from address could done by optaining function address with gdb or + // objdump -S kernel + unsigned int *ebp = __builtin_frame_address(0); + for (unsigned int frame = 0; frame < maxFrames; frame++) { + unsigned int eip = ebp[1]; + if (eip == 0) { + // No caller on stack + break; + } + unsigned int *arguments = ebp + 2; + printf("[%d] 0x%x (", frame, eip); + int nbArg = 0; + do { + if ((_stack_bottom <= (vaddr_t)arguments) && ((vaddr_t)arguments <= _stack_top)) { + printf(" 0x%x", *arguments); + arguments += 1; + } else { + break; + } + nbArg++; + if (nbArg >= 4) { + break; + } + } while (1); + printf(")\n"); + ebp = (unsigned int *)(ebp[0]); + } #else - printf("Must be compiled with -fno-omit-frame-pointer for full stack\n"); - unsigned int *ebp = &maxFrames - 2; - unsigned int eip = ebp[1]; - printf("[0] 0x%x\n", eip); + printf("Must be compiled with -fno-omit-frame-pointer for full stack\n"); + unsigned int *ebp = &maxFrames - 2; + unsigned int eip = ebp[1]; + printf("[0] 0x%x\n", eip); #endif } diff --git a/core/stdarg.h b/core/stdarg.h index 36589ef..c006082 100644 --- a/core/stdarg.h +++ b/core/stdarg.h @@ -18,37 +18,37 @@ typedef unsigned long long __u64; #endif /* sysv */ -typedef unsigned char unchar; -typedef unsigned short ushort; -typedef unsigned int uint; -typedef unsigned long ulong; +typedef unsigned char unchar; +typedef unsigned short ushort; +typedef unsigned int uint; +typedef unsigned long ulong; -typedef __s8 int8_t; -typedef __s16 int16_t; -typedef __s32 int32_t; +typedef __s8 int8_t; +typedef __s16 int16_t; +typedef __s32 int32_t; -typedef __u8 uint8_t; -typedef __u16 uint16_t; -typedef __u32 uint32_t; +typedef __u8 uint8_t; +typedef __u16 uint16_t; +typedef __u32 uint32_t; -typedef __u64 uint64_t; -typedef __u64 u_int64_t; -typedef __s64 int64_t; +typedef __u64 uint64_t; +typedef __u64 u_int64_t; +typedef __s64 int64_t; -typedef enum { FALSE=0, TRUE } bool_t; -#define NULL ((void*)0) +typedef enum { FALSE = 0, TRUE } bool_t; +#define NULL ((void *)0) #if __x86_64__ typedef unsigned long size_t; typedef long ssize_t; -typedef unsigned long int uintptr_t; +typedef unsigned long int uintptr_t; #else typedef unsigned int size_t; typedef int ssize_t; -typedef unsigned int uintptr_t; +typedef unsigned int uintptr_t; #endif typedef void *va_list; #define va_start(v, l) ((v) = (va_list) & (l) + sizeof(l)) #define va_end(v) ((v) = NULL) -#define va_arg(v, type) (*(type *)(((v)+=sizeof(type))-sizeof(type))) +#define va_arg(v, type) (*(type *)(((v) += sizeof(type)) - sizeof(type))) diff --git a/core/types.h b/core/types.h index 5272ab7..c544ce3 100644 --- a/core/types.h +++ b/core/types.h @@ -1,32 +1,32 @@ #pragma once -#define USHRT_MAX ((u16)(~0U)) -#define SHRT_MAX ((s16)(USHRT_MAX>>1)) -#define SHRT_MIN ((s16)(-SHRT_MAX - 1)) -#define INT_MAX ((int)(~0U>>1)) -#define INT_MIN (-INT_MAX - 1) -#define UINT_MAX (~0U) -#define LONG_MAX ((long)(~0UL>>1)) -#define LONG_MIN (-LONG_MAX - 1) -#define ULONG_MAX (~0UL) -#define LLONG_MAX ((long long)(~0ULL>>1)) -#define LLONG_MIN (-LLONG_MAX - 1) -#define ULLONG_MAX (~0ULL) -#define SIZE_MAX (~(size_t)0) -#define PHYS_ADDR_MAX (~(phys_addr_t)0) +#define USHRT_MAX ((u16)(~0U)) +#define SHRT_MAX ((s16)(USHRT_MAX >> 1)) +#define SHRT_MIN ((s16)(-SHRT_MAX - 1)) +#define INT_MAX ((int)(~0U >> 1)) +#define INT_MIN (-INT_MAX - 1) +#define UINT_MAX (~0U) +#define LONG_MAX ((long)(~0UL >> 1)) +#define LONG_MIN (-LONG_MAX - 1) +#define ULONG_MAX (~0UL) +#define LLONG_MAX ((long long)(~0ULL >> 1)) +#define LLONG_MIN (-LLONG_MAX - 1) +#define ULLONG_MAX (~0ULL) +#define SIZE_MAX (~(size_t)0) +#define PHYS_ADDR_MAX (~(phys_addr_t)0) -#define U8_MAX ((u8)~0U) -#define S8_MAX ((s8)(U8_MAX>>1)) -#define S8_MIN ((s8)(-S8_MAX - 1)) -#define U16_MAX ((u16)~0U) -#define S16_MAX ((s16)(U16_MAX>>1)) -#define S16_MIN ((s16)(-S16_MAX - 1)) -#define U32_MAX ((u32)~0U) -#define S32_MAX ((s32)(U32_MAX>>1)) -#define S32_MIN ((s32)(-S32_MAX - 1)) -#define U64_MAX ((u64)~0ULL) -#define S64_MAX ((s64)(U64_MAX>>1)) -#define S64_MIN ((s64)(-S64_MAX - 1)) +#define U8_MAX ((u8)~0U) +#define S8_MAX ((s8)(U8_MAX >> 1)) +#define S8_MIN ((s8)(-S8_MAX - 1)) +#define U16_MAX ((u16)~0U) +#define S16_MAX ((s16)(U16_MAX >> 1)) +#define S16_MIN ((s16)(-S16_MAX - 1)) +#define U32_MAX ((u32)~0U) +#define S32_MAX ((s32)(U32_MAX >> 1)) +#define S32_MIN ((s32)(-S32_MAX - 1)) +#define U64_MAX ((u64)~0ULL) +#define S64_MAX ((s64)(U64_MAX >> 1)) +#define S64_MIN ((s64)(-S64_MAX - 1)) #define __ALIGN_KERNEL(x, a) __ALIGN_KERNEL_MASK(x, (typeof(x))(a)-1) #define __ALIGN_KERNEL_MASK(x, mask) (((x) + (mask)) & ~(mask)) diff --git a/drivers/keyboard.c b/drivers/keyboard.c index d6e2e0d..d64600c 100644 --- a/drivers/keyboard.c +++ b/drivers/keyboard.c @@ -1,6 +1,6 @@ #include "keyboard.h" -#include "klibc.h" #include "io.h" +#include "klibc.h" const char *scancode[128] = { /* 0 */ 0, @@ -61,7 +61,7 @@ const char *scancode[128] = { /* 55 */ "*", /* 56 */ 0, /* left alt*/ /* 57 */ " ", - /* 58 */ 0, /* caps Lock */ + /* 58 */ 0, /* caps Lock */ /* 59 */ "\eOP", /* F1 */ /* 60 */ "\eOQ", /* F2 */ /* 61 */ "\eOR", /* F3 */ @@ -72,7 +72,7 @@ const char *scancode[128] = { /* 66 */ "\e[19~", /* F8 */ /* 67 */ "\e[20~", /* F9 */ /* 68 */ "\e[21~", /* F10 */ - /* 69 */ 0, /* VerrNum*/ + /* 69 */ 0, /* VerrNum*/ /* 70 */ 0, /* 71 */ "7", /* 72 */ "8", @@ -264,50 +264,50 @@ const char *scancode_shift[128] = { void keyboard_do_irq() { - static int lshift = 0; - static int rshift = 0; - static int capslock = 0; - static int isExt = 0; - unsigned char c = inb(KEYBOARD_DATA_PORT); - const char *key = NULL; - if (c > 0) { - if (c == 0xE0) { // non printable such as page up/down ... See https://wiki.osdev.org/Keyboard - isExt = 1; - } else if (isExt) { - isExt = 0; - return; - } - if (c < BREAK_CODE) { - switch (c) { - case 42: - lshift = 1; - break; - case 54: - rshift = 1; - break; - case 58: - capslock = 1 - capslock; - break; - default: - if ((lshift || rshift) ^ capslock) { - key = scancode_shift[(int)c]; - } else { - key = scancode[(int)c]; - } - } - } else { - c = c - BREAK_CODE; - switch (c) { - case 42: - lshift = 0; - break; - case 54: - rshift = 0; - } - } - } + static int lshift = 0; + static int rshift = 0; + static int capslock = 0; + static int isExt = 0; + unsigned char c = inb(KEYBOARD_DATA_PORT); + const char *key = NULL; + if (c > 0) { + if (c == 0xE0) { // non printable such as page up/down ... See + // https://wiki.osdev.org/Keyboard + isExt = 1; + } else if (isExt) { + isExt = 0; + return; + } + if (c < BREAK_CODE) { + switch (c) { + case 42: + lshift = 1; + break; + case 54: + rshift = 1; + break; + case 58: + capslock = 1 - capslock; + break; + default: + if ((lshift || rshift) ^ capslock) { + key = scancode_shift[(int)c]; + } else { + key = scancode[(int)c]; + } + } + } else { + c = c - BREAK_CODE; + switch (c) { + case 42: + lshift = 0; + break; + case 54: + rshift = 0; + } + } + } - if (key) - printf(key); + if (key) + printf(key); } - diff --git a/drivers/pic.c b/drivers/pic.c index bdae842..707ebc9 100644 --- a/drivers/pic.c +++ b/drivers/pic.c @@ -16,58 +16,58 @@ void initPic(void) { - /* Send CMD: Init + sequence in 4 DATA */ - outb(PIC_MASTER_CMD, ICW1_INIT + ICW1_ICW4); - outb(PIC_SLAVE_CMD, ICW1_INIT + ICW1_ICW4); + /* Send CMD: Init + sequence in 4 DATA */ + outb(PIC_MASTER_CMD, ICW1_INIT + ICW1_ICW4); + outb(PIC_SLAVE_CMD, ICW1_INIT + ICW1_ICW4); - /* Send ICW2: ctrl base address. Remap IRQ from interupt range 0x0-0xF to 0x20-0x2F as - * intel - * reserve interupt 0x0-0x1F in protected mode (e.g. 0-7 are CPU exception) */ - outb(PIC_MASTER_DATA, IRQ_INTERRUPT_BASE_ADDRESS); - outb(PIC_SLAVE_DATA, IRQ_INTERRUPT_BASE_ADDRESS + 8); + /* Send ICW2: ctrl base address. Remap IRQ from interupt range 0x0-0xF to 0x20-0x2F as + * intel + * reserve interupt 0x0-0x1F in protected mode (e.g. 0-7 are CPU exception) */ + outb(PIC_MASTER_DATA, IRQ_INTERRUPT_BASE_ADDRESS); + outb(PIC_SLAVE_DATA, IRQ_INTERRUPT_BASE_ADDRESS + 8); - /* Send ICW3 master: mask where slaves are connected */ - outb(PIC_MASTER_DATA, 0x4); - /* Send ICW3 slave: index where the slave is connected on master */ - outb(PIC_SLAVE_DATA, 0x2); + /* Send ICW3 master: mask where slaves are connected */ + outb(PIC_MASTER_DATA, 0x4); + /* Send ICW3 slave: index where the slave is connected on master */ + outb(PIC_SLAVE_DATA, 0x2); - /* Send ICW4: 8086 mode, fully nested, not buffered, no implicit EOI */ - outb(PIC_MASTER_DATA, ICW4_8086); - outb(PIC_SLAVE_DATA, ICW4_8086); + /* Send ICW4: 8086 mode, fully nested, not buffered, no implicit EOI */ + outb(PIC_MASTER_DATA, ICW4_8086); + outb(PIC_SLAVE_DATA, ICW4_8086); - /* Send OCW1: - * Closing all IRQs : waiting for a correct handler The only IRQ - * enabled is the cascade (that's why we use 0xFB for the master) */ - outb(PIC_MASTER_DATA, 0xFB); - outb(PIC_SLAVE_DATA, 0xFF); + /* Send OCW1: + * Closing all IRQs : waiting for a correct handler The only IRQ + * enabled is the cascade (that's why we use 0xFB for the master) */ + outb(PIC_MASTER_DATA, 0xFB); + outb(PIC_SLAVE_DATA, 0xFF); } void EOIIrq(int irq) { - if (irq >= 8) - outb(PIC_SLAVE_CMD, PIC_EOI); + if (irq >= 8) + outb(PIC_SLAVE_CMD, PIC_EOI); - outb(PIC_MASTER_CMD, PIC_EOI); + outb(PIC_MASTER_CMD, PIC_EOI); } void disableIrq(int irq) { - if (irq < 8) { - uint8_t status = inb(PIC_MASTER_DATA); - outb(PIC_MASTER_DATA, (status | (1 << irq))); - } else { - uint8_t status = inb(PIC_SLAVE_DATA); - outb(PIC_SLAVE_DATA, (status | (1 << (irq - 8)))); - } + if (irq < 8) { + uint8_t status = inb(PIC_MASTER_DATA); + outb(PIC_MASTER_DATA, (status | (1 << irq))); + } else { + uint8_t status = inb(PIC_SLAVE_DATA); + outb(PIC_SLAVE_DATA, (status | (1 << (irq - 8)))); + } } void enableIrq(int irq) { - if (irq < 8) { - uint8_t status = inb(PIC_MASTER_DATA); - outb(PIC_MASTER_DATA, (status & ~(1 << irq))); - } else { - uint8_t status = inb(PIC_SLAVE_DATA); - outb(PIC_SLAVE_DATA, (status & ~(1 << (irq - 8)))); - } + if (irq < 8) { + uint8_t status = inb(PIC_MASTER_DATA); + outb(PIC_MASTER_DATA, (status & ~(1 << irq))); + } else { + uint8_t status = inb(PIC_SLAVE_DATA); + outb(PIC_SLAVE_DATA, (status & ~(1 << (irq - 8)))); + } } diff --git a/drivers/pic.h b/drivers/pic.h index da6f99d..d8770ed 100644 --- a/drivers/pic.h +++ b/drivers/pic.h @@ -14,7 +14,6 @@ #define PIC_SLAVE_DATA 0xa1 #define PIC_EOI 0x20 /* End-of-interrupt command code */ - void EOIIrq(int irq); void initPic(void); void enableIrq(int irq); diff --git a/drivers/pit.c b/drivers/pit.c index c600a3e..f0a3fdf 100644 --- a/drivers/pit.c +++ b/drivers/pit.c @@ -4,12 +4,12 @@ int pitSetup(unsigned int freq) { - unsigned int divisor = PIT_FREQ / freq; - if (divisor > 65535) - divisor = 0; // Used to represent 35536 - outb(PIT_CMD, 0x34); // chan 0; low then high; mode 2 - outb(PIT_CHAN_0, divisor & 0xFF); - outb(PIT_CHAN_0, divisor >> 8u); + unsigned int divisor = PIT_FREQ / freq; + if (divisor > 65535) + divisor = 0; // Used to represent 35536 + outb(PIT_CMD, 0x34); // chan 0; low then high; mode 2 + outb(PIT_CHAN_0, divisor & 0xFF); + outb(PIT_CHAN_0, divisor >> 8u); - return 0; + return 0; } diff --git a/drivers/pit.h b/drivers/pit.h index e2901b0..c72a257 100644 --- a/drivers/pit.h +++ b/drivers/pit.h @@ -13,4 +13,3 @@ // 3 -> low then high 3-1: mode. See https://wiki.osdev.org/PIT int pitSetup(unsigned int freq); - diff --git a/drivers/serial.c b/drivers/serial.c index bc9b11e..03586de 100644 --- a/drivers/serial.c +++ b/drivers/serial.c @@ -22,34 +22,35 @@ void serialSetup(int speed) { - unsigned short div = SERIAL_MAX_SPEED / speed; - outb(PORT + 1, 0x00); // Disable all interrupts - outb(PORT + 3, 0x80); // Enable DLAB (set baud rate divisor) - outb(PORT + 0, div & 0xFF); // Set divisor lo byte - outb(PORT + 1, div >> 8); // Set divisor hi byte - outb(PORT + 3, - UART_NO_PARITY | UART_8BITS_WORD | UART_1_STOP_BIT); // 8 bits, no parity, one stop bit - outb(PORT + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold - outb(PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set - irqSetRoutine(IRQ_COM1, serial_handler); + unsigned short div = SERIAL_MAX_SPEED / speed; + outb(PORT + 1, 0x00); // Disable all interrupts + outb(PORT + 3, 0x80); // Enable DLAB (set baud rate divisor) + outb(PORT + 0, div & 0xFF); // Set divisor lo byte + outb(PORT + 1, div >> 8); // Set divisor hi byte + outb(PORT + 3, + UART_NO_PARITY | UART_8BITS_WORD | + UART_1_STOP_BIT); // 8 bits, no parity, one stop bit + outb(PORT + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold + outb(PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set + irqSetRoutine(IRQ_COM1, serial_handler); } int isTransmitEmpty() { - return (inb(PORT + 5) & 0x20); + return (inb(PORT + 5) & 0x20); } void serialPutc(char a) { - while (isTransmitEmpty() == 0) - ; + while (isTransmitEmpty() == 0) + ; - outb(PORT, a); + outb(PORT, a); } void serialDoIrq(struct interrupt_frame *level) { - (void)level; - char c = inb(PORT); - serialPutc(c); + (void)level; + char c = inb(PORT); + serialPutc(c); } diff --git a/drivers/vga.c b/drivers/vga.c index b6be891..a391992 100644 --- a/drivers/vga.c +++ b/drivers/vga.c @@ -8,146 +8,142 @@ static int line, col; int VGASetup(uint bgColor, uint color) { - vgaBgColor = bgColor; - vgaColor = color; - clearScreen(bgColor); - line = 0; - col = 0; - return 0; + vgaBgColor = bgColor; + vgaColor = color; + clearScreen(bgColor); + line = 0; + col = 0; + return 0; } void clearScreen(uint bgColor) { - volatile short *vga = (short *)VGA_ADDR; - long int colorAttr = bgColor << 12; - for (int i = 0; i < VGA_WIDTH * VGA_HEIGHT; i++) { - vga[i] = colorAttr; - } + volatile short *vga = (short *)VGA_ADDR; + long int colorAttr = bgColor << 12; + for (int i = 0; i < VGA_WIDTH * VGA_HEIGHT; i++) { + vga[i] = colorAttr; + } } void clearScreenLine(uint bgColor, uint line) { - volatile short *vga = (short *)VGA_ADDR; - long int colorAttr = bgColor << 12; - for (uint i = VGA_WIDTH * line; i < VGA_WIDTH * (line + 1); i++) { - vga[i] = colorAttr; - } + volatile short *vga = (short *)VGA_ADDR; + long int colorAttr = bgColor << 12; + for (uint i = VGA_WIDTH * line; i < VGA_WIDTH * (line + 1); i++) { + vga[i] = colorAttr; + } } void printIntDetails(int integer, uint color, uint bgColor, int startX, int startY) { - char num[sizeof(int) * - 3]; // int max is 2^(sizeof(int)*8) which is (2^3)^(sizeof(int)*8/3) = - // 8^(sizeof(int)*8/3) ~ 10^(sizeof(int)*8/3) - int x = startX; - int i = 0, k = 0; - if (integer < 0) { - printCharDetails('-', color, bgColor, x++, startY); - } - if (integer == 0) { - num[i++] = 0; - } - while (integer != 0) { - int digit = integer % 10; - num[i++] = (digit > 0) ? digit : -digit; - integer = integer / 10; - } - for (k = i - 1; k >= 0; k--) { - printCharDetails(num[k] + '0', color, bgColor, x++, startY); - } + char num[sizeof(int) * 3]; // int max is 2^(sizeof(int)*8) which is (2^3)^(sizeof(int)*8/3) + // = 8^(sizeof(int)*8/3) ~ 10^(sizeof(int)*8/3) + int x = startX; + int i = 0, k = 0; + if (integer < 0) { + printCharDetails('-', color, bgColor, x++, startY); + } + if (integer == 0) { + num[i++] = 0; + } + while (integer != 0) { + int digit = integer % 10; + num[i++] = (digit > 0) ? digit : -digit; + integer = integer / 10; + } + for (k = i - 1; k >= 0; k--) { + printCharDetails(num[k] + '0', color, bgColor, x++, startY); + } } void printCharDetails(const char str, uint color, uint bgColor, int startX, int startY) { - volatile short *vga = (short *)VGA_ADDR; - long int colorAttr = (bgColor << 4 | (color & 0x0f)) << 8; - vga[VGA_WIDTH * startY + startX] = colorAttr | str; + volatile short *vga = (short *)VGA_ADDR; + long int colorAttr = (bgColor << 4 | (color & 0x0f)) << 8; + vga[VGA_WIDTH * startY + startX] = colorAttr | str; } void vgaScrollUp(void) { - long int colorAttr = vgaBgColor << 12; - volatile short *vga = (short *)VGA_ADDR; - for (int i = 1; i < VGA_HEIGHT - 1; - i++) { // last line is status line. Do not scroll it - memcpy((void *)&vga[VGA_WIDTH * (i - 1)], (void *)&vga[VGA_WIDTH * i], - VGA_WIDTH * sizeof(short)); - } - for (int i = 0; i < VGA_WIDTH; i++) { - vga[(VGA_HEIGHT - 2) * VGA_WIDTH + i] = colorAttr; - } + long int colorAttr = vgaBgColor << 12; + volatile short *vga = (short *)VGA_ADDR; + for (int i = 1; i < VGA_HEIGHT - 1; i++) { // last line is status line. Do not scroll it + memcpy((void *)&vga[VGA_WIDTH * (i - 1)], (void *)&vga[VGA_WIDTH * i], + VGA_WIDTH * sizeof(short)); + } + for (int i = 0; i < VGA_WIDTH; i++) { + vga[(VGA_HEIGHT - 2) * VGA_WIDTH + i] = colorAttr; + } } - - void VGAputc(const char str) { - if (str == '\n') { - line++; - col = 0; - if (line >= VGA_HEIGHT - 1) { - vgaScrollUp(); - line--; - } - } else if (str == '\r') { - col = 0; - } else if (str == '\b') { - col--; - if (col < 0) { - col = VGA_WIDTH - 1; - line--; - } - printCharDetails(' ', vgaColor, vgaBgColor, col, line); - } else { - printCharDetails(str, vgaColor, vgaBgColor, col++, line); - if (col == VGA_WIDTH) { - col = 0; - line++; - } - if (line >= VGA_HEIGHT - 1) { - vgaScrollUp(); - line--; - } - } - cursorMove(col, line); + if (str == '\n') { + line++; + col = 0; + if (line >= VGA_HEIGHT - 1) { + vgaScrollUp(); + line--; + } + } else if (str == '\r') { + col = 0; + } else if (str == '\b') { + col--; + if (col < 0) { + col = VGA_WIDTH - 1; + line--; + } + printCharDetails(' ', vgaColor, vgaBgColor, col, line); + } else { + printCharDetails(str, vgaColor, vgaBgColor, col++, line); + if (col == VGA_WIDTH) { + col = 0; + line++; + } + if (line >= VGA_HEIGHT - 1) { + vgaScrollUp(); + line--; + } + } + cursorMove(col, line); } void printStringDetails(const char *str, uint color, uint bgColor, int startX, int startY) { - volatile short *vga = (short *)VGA_ADDR; - int i = 0; - long int colorAttr = (bgColor << 4 | (color & 0x0f)) << 8; - while (*str) { - vga[VGA_WIDTH * startY + startX + i] = colorAttr | *str; - str++; - i++; - } + volatile short *vga = (short *)VGA_ADDR; + int i = 0; + long int colorAttr = (bgColor << 4 | (color & 0x0f)) << 8; + while (*str) { + vga[VGA_WIDTH * startY + startX + i] = colorAttr | *str; + str++; + i++; + } } void cursorEnable(uint8_t cursor_start, uint8_t cursor_end) { - outb(0x3D4, 0x0A); - outb(0x3D5, (inb(0x3D5) & 0xC0) | cursor_start); + outb(0x3D4, 0x0A); + outb(0x3D5, (inb(0x3D5) & 0xC0) | cursor_start); - outb(0x3D4, 0x0B); - outb(0x3D5, (inb(0x3D5) & 0xE0) | cursor_end); + outb(0x3D4, 0x0B); + outb(0x3D5, (inb(0x3D5) & 0xE0) | cursor_end); } void cursorDisable(void) { - outb(0x3D4, 0x0A); - outb(0x3D5, 0x20); + outb(0x3D4, 0x0A); + outb(0x3D5, 0x20); } void cursorMove(int x, int y) { - volatile short *vga = (short *)VGA_ADDR; - long int colorAttr = (vgaBgColor << 4 | (vgaColor & 0x0f)) << 8; - uint16_t pos = y * VGA_WIDTH + x; - vga[pos] = colorAttr; + volatile short *vga = (short *)VGA_ADDR; + long int colorAttr = (vgaBgColor << 4 | (vgaColor & 0x0f)) << 8; + uint16_t pos = y * VGA_WIDTH + x; + vga[pos] = colorAttr; - outb(0x3D4, 0x0F); - outb(0x3D5, (uint8_t)(pos & 0xFF)); - outb(0x3D4, 0x0E); - outb(0x3D5, (uint8_t)((pos >> 8) & 0xFF)); + outb(0x3D4, 0x0F); + outb(0x3D5, (uint8_t)(pos & 0xFF)); + outb(0x3D4, 0x0E); + outb(0x3D5, (uint8_t)((pos >> 8) & 0xFF)); } diff --git a/drivers/vga.h b/drivers/vga.h index c575b40..f76ec1b 100644 --- a/drivers/vga.h +++ b/drivers/vga.h @@ -3,18 +3,18 @@ #include "types.h" // https://wiki.osdev.org/Text_UI -#define BLACK 0x00 -#define BLUE 0x01 -#define GREEN 0x02 -#define CYAN 0x03 -#define RED 0x04 +#define BLACK 0x00 +#define BLUE 0x01 +#define GREEN 0x02 +#define CYAN 0x03 +#define RED 0x04 #define MAGENTA 0x05 -#define BROWN 0x06 -#define GREY 0x07 -#define WHITE 0x0F +#define BROWN 0x06 +#define GREY 0x07 +#define WHITE 0x0F -#define VGA_ADDR 0xB8000 -#define VGA_WIDTH 80 +#define VGA_ADDR 0xB8000 +#define VGA_WIDTH 80 #define VGA_HEIGHT 25 #ifndef pr_fmt @@ -32,4 +32,3 @@ void vgaScrollUp(void); void cursorEnable(uint8_t cursor_start, uint8_t cursor_end); void cursorDisable(void); void cursorMove(int x, int y); - diff --git a/tests/test.c b/tests/test.c index c970349..681bb09 100644 --- a/tests/test.c +++ b/tests/test.c @@ -11,135 +11,131 @@ void testPhymem(void) { - printf("Testing memory PHY\n"); - struct mem_desc *allocated_page_list; - struct mem_desc - *page; // Cast in mem_desc to use it. In fact it's the addr of 4K free memory - list_init(allocated_page_list); - int allocCount = 0; - int freeCount = 0; + printf("Testing memory PHY\n"); + struct mem_desc *allocated_page_list; + struct mem_desc + *page; // Cast in mem_desc to use it. In fact it's the addr of 4K free memory + list_init(allocated_page_list); + int allocCount = 0; + int freeCount = 0; - while ((page = (struct mem_desc *)allocPhyPage()) != NULL) { - page->phy_addr = allocCount; - allocCount++; - list_add_tail(allocated_page_list, page); - } - printf("%d pages allocated\n", allocCount); + while ((page = (struct mem_desc *)allocPhyPage()) != NULL) { + page->phy_addr = allocCount; + allocCount++; + list_add_tail(allocated_page_list, page); + } + printf("%d pages allocated\n", allocCount); - while ((page = list_pop_head(allocated_page_list)) != NULL) { - assertmsg(page->phy_addr == (ulong)freeCount, "page %d modified", page); - assertmsg(unrefPhyPage((ulong)page) >= 0, "Failed to free page %d\n", - (ulong)page); - freeCount++; - } - printf("%d pages freed\n", freeCount); + while ((page = list_pop_head(allocated_page_list)) != NULL) { + assertmsg(page->phy_addr == (ulong)freeCount, "page %d modified", page); + assertmsg(unrefPhyPage((ulong)page) >= 0, "Failed to free page %d\n", (ulong)page); + freeCount++; + } + printf("%d pages freed\n", freeCount); - assertmsg((page = (struct mem_desc *)allocPhyPage()) != NULL, - "Cannot allocate memory\n"); - unrefPhyPage((ulong)page); + assertmsg((page = (struct mem_desc *)allocPhyPage()) != NULL, "Cannot allocate memory\n"); + unrefPhyPage((ulong)page); } static void *testAllocNSet(size_t size) { - void *allocated = malloc(size); - assert(allocated); - memset(allocated, size, size); - return allocated; + void *allocated = malloc(size); + assert(allocated); + memset(allocated, size, size); + return allocated; } static void testAlloc(void) { - for (uint i = 0; i < PAGE_SIZE / (sizeof(struct slabEntry)); i++) { - malloc(sizeof(struct slabEntry)); - } - for (uint i = 0; i < PAGE_SIZE / (sizeof(struct slabDesc)); i++) { - malloc(sizeof(struct slabDesc)); - } - assert(malloc(1)); - assert(malloc(2)); - assert(malloc(3)); - assert(malloc(4)); - void *malloc1 = malloc(sizeof(void *)); - void *malloc2 = malloc(sizeof(void *)); - assert((char *)malloc2 == ((char *)malloc1 + sizeof(void *))); - free(malloc2); - void *malloc3 = malloc(sizeof(void *)); - assertmsg((char *)malloc2 == (char *)malloc3, " %d %d\n", malloc2, malloc3); - void *alloc1 = testAllocNSet(1024); - void *alloc2 = testAllocNSet(1024); - void *alloc3 = testAllocNSet(1024); - void *alloc4 = testAllocNSet(1024); - void *alloc5 = testAllocNSet(1024); - void *alloc6 = testAllocNSet(1024); - void *alloc7 = testAllocNSet(4096); - free(alloc1); - free(alloc2); - free(alloc3); - free(alloc4); - free(alloc5); - free(alloc6); - free(alloc7); - void *alloc11 = testAllocNSet(1024); - void *alloc12 = testAllocNSet(1024); - void *alloc13 = testAllocNSet(1024); - void *alloc14 = testAllocNSet(1024); - void *alloc15 = testAllocNSet(1024); - void *alloc16 = testAllocNSet(1024); - free(alloc11); - free(alloc12); - free(alloc13); - free(alloc14); - free(alloc15); - free(alloc16); + for (uint i = 0; i < PAGE_SIZE / (sizeof(struct slabEntry)); i++) { + malloc(sizeof(struct slabEntry)); + } + for (uint i = 0; i < PAGE_SIZE / (sizeof(struct slabDesc)); i++) { + malloc(sizeof(struct slabDesc)); + } + assert(malloc(1)); + assert(malloc(2)); + assert(malloc(3)); + assert(malloc(4)); + void *malloc1 = malloc(sizeof(void *)); + void *malloc2 = malloc(sizeof(void *)); + assert((char *)malloc2 == ((char *)malloc1 + sizeof(void *))); + free(malloc2); + void *malloc3 = malloc(sizeof(void *)); + assertmsg((char *)malloc2 == (char *)malloc3, " %d %d\n", malloc2, malloc3); + void *alloc1 = testAllocNSet(1024); + void *alloc2 = testAllocNSet(1024); + void *alloc3 = testAllocNSet(1024); + void *alloc4 = testAllocNSet(1024); + void *alloc5 = testAllocNSet(1024); + void *alloc6 = testAllocNSet(1024); + void *alloc7 = testAllocNSet(4096); + free(alloc1); + free(alloc2); + free(alloc3); + free(alloc4); + free(alloc5); + free(alloc6); + free(alloc7); + void *alloc11 = testAllocNSet(1024); + void *alloc12 = testAllocNSet(1024); + void *alloc13 = testAllocNSet(1024); + void *alloc14 = testAllocNSet(1024); + void *alloc15 = testAllocNSet(1024); + void *alloc16 = testAllocNSet(1024); + free(alloc11); + free(alloc12); + free(alloc13); + free(alloc14); + free(alloc15); + free(alloc16); } static void testPaging(void) { - printf("Testing paging\n"); - struct mem_desc *allocated_page_list; - struct mem_desc - *page; // Cast in mem_desc to use it. In fact it's the addr of 4K free memory - list_init(allocated_page_list); - int allocCount = 0; - int freeCount = 0; + printf("Testing paging\n"); + struct mem_desc *allocated_page_list; + struct mem_desc + *page; // Cast in mem_desc to use it. In fact it's the addr of 4K free memory + list_init(allocated_page_list); + int allocCount = 0; + int freeCount = 0; - while ((page = (struct mem_desc *)allocPhyPage()) != NULL) { - assertmsg(pageMap((vaddr_t)page, (paddr_t)page, PAGING_MEM_WRITE) == 0, - "Fail to map page %d\n", allocCount); - memset(page, allocCount, PAGE_SIZE); - allocCount++; - list_add_tail(allocated_page_list, page); - } - printf("%d pages allocated\n", allocCount); + while ((page = (struct mem_desc *)allocPhyPage()) != NULL) { + assertmsg(pageMap((vaddr_t)page, (paddr_t)page, PAGING_MEM_WRITE) == 0, + "Fail to map page %d\n", allocCount); + memset(page, allocCount, PAGE_SIZE); + allocCount++; + list_add_tail(allocated_page_list, page); + } + printf("%d pages allocated\n", allocCount); - while ((page = list_pop_head(allocated_page_list)) != NULL) { - assertmsg((char)page->phy_addr == (char)freeCount, - "page modified %d but is %d\n", freeCount, page->phy_addr); - assertmsg(unrefPhyPage((ulong)page) >= 0, "Failed to free page %d\n", - (ulong)page); - pageUnmap((vaddr_t)page); - freeCount++; - } - printf("%d pages freed\n", freeCount); + while ((page = list_pop_head(allocated_page_list)) != NULL) { + assertmsg((char)page->phy_addr == (char)freeCount, "page modified %d but is %d\n", + freeCount, page->phy_addr); + assertmsg(unrefPhyPage((ulong)page) >= 0, "Failed to free page %d\n", (ulong)page); + pageUnmap((vaddr_t)page); + freeCount++; + } + printf("%d pages freed\n", freeCount); - assertmsg((page = (struct mem_desc *)allocPhyPage()) != NULL, - "Cannot allocate memory\n"); - unrefPhyPage((ulong)page); + assertmsg((page = (struct mem_desc *)allocPhyPage()) != NULL, "Cannot allocate memory\n"); + unrefPhyPage((ulong)page); } static void test_backtrace_2(int a, int b) { - printStackTrace(a + b); + printStackTrace(a + b); } static void test_backtrace_1(int a) { - test_backtrace_2(a, 3); + test_backtrace_2(a, 3); } void test_backtrace() { - test_backtrace_1(2); + test_backtrace_1(2); } /* ====================================================================== @@ -155,14 +151,15 @@ struct cpu_state *ctxt_hello2; struct cpu_state *ctxt_main; vaddr_t hello1_stack, hello2_stack; -static void reclaim_stack(void * stack_vaddr) +static void reclaim_stack(void *stack_vaddr) { free(stack_vaddr); } -static void exit_hello12(void * stack_vaddr) +static void exit_hello12(void *stack_vaddr) { - cpu_context_exit_to(ctxt_main, (cpu_kstate_function_arg1_t *)reclaim_stack, (vaddr_t)stack_vaddr); + cpu_context_exit_to(ctxt_main, (cpu_kstate_function_arg1_t *)reclaim_stack, + (vaddr_t)stack_vaddr); } static void hello1(void *strIn) @@ -224,7 +221,7 @@ static void kthread1(void *strIn) printf("\nkth1: %s\n", (char *)strIn); for (; *str != '\n'; str++) { printf("kth1_: %c\n", *str); - kthreadYield(); + kthreadYield(); } } @@ -234,28 +231,28 @@ static void kthread2(void *strIn) printf("\nkth2: %s\n", (char *)strIn); for (; *str != '\n'; str++) { printf("kth2_: %c\n", *str); - kthreadYield(); + kthreadYield(); } } void testKthread() { - kthreadCreate("Test1", (cpu_kstate_function_arg1_t *)kthread1, (void *)"Hlowrd\n"); - kthreadCreate("Test2", (cpu_kstate_function_arg1_t *)kthread2, (void *)"el ol\n"); + kthreadCreate("Test1", (cpu_kstate_function_arg1_t *)kthread1, (void *)"Hlowrd\n"); + kthreadCreate("Test2", (cpu_kstate_function_arg1_t *)kthread2, (void *)"el ol\n"); } void run_test(void) { - testPaging(); - printf("Testing Serial\n"); - serialPutc('h'); - serialPutc('e'); - serialPutc('l'); - serialPutc('l'); - serialPutc('o'); - testAlloc(); - printf("Testing backtrace\n"); - test_backtrace(); - testCoroutine(); - testKthread(); + testPaging(); + printf("Testing Serial\n"); + serialPutc('h'); + serialPutc('e'); + serialPutc('l'); + serialPutc('l'); + serialPutc('o'); + testAlloc(); + printf("Testing backtrace\n"); + test_backtrace(); + testCoroutine(); + testKthread(); }