Style: harmonize formatting

Thanks to: "clang-format -i -style=file **/*.{c,h}"
This commit is contained in:
Mathieu Maret 2020-04-27 00:14:37 +02:00
parent fd6551e90c
commit 3b97d0307d
40 changed files with 1405 additions and 1458 deletions

View File

@ -1,22 +1,24 @@
#pragma once #pragma once
#include "stack.h"
#include "klibc.h" #include "klibc.h"
#include "stack.h"
#define assert(p) do { \ #define assert(p) \
do { \
if (!(p)) { \ if (!(p)) { \
printf("BUG at %s:%d assert(%s)\n", \ printf("BUG at %s:%d assert(%s)\n", __FILE__, __LINE__, #p); \
__FILE__, __LINE__, #p); \
printStackTrace(5); \ printStackTrace(5); \
while(1){} \ while (1) { \
} \
} \ } \
} while (0) } while (0)
#define assertmsg(p, ...) do { \ #define assertmsg(p, ...) \
do { \
if (!(p)) { \ if (!(p)) { \
printf("BUG at %s:%d assert(%s)\n", \ printf("BUG at %s:%d assert(%s)\n", __FILE__, __LINE__, #p); \
__FILE__, __LINE__, #p); \
printf(__VA_ARGS__); \ printf(__VA_ARGS__); \
printStackTrace(5); \ printStackTrace(5); \
while(1){} \ while (1) { \
} \
} \ } \
} while (0) } while (0)

View File

@ -236,6 +236,7 @@ vaddr_t cpu_context_get_SP(const struct cpu_state *ctxt)
void cpu_context_dump(const struct cpu_state *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, 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, (unsigned)ctxt->eflags,
(unsigned)ctxt->ds, (unsigned)ctxt->cpl0_ss, (unsigned)ctxt->error_code); (unsigned)GET_CPU_CS_REGISTER_VALUE(ctxt->cs), (unsigned)ctxt->ds,
(unsigned)ctxt->cpl0_ss, (unsigned)ctxt->error_code);
} }

View File

@ -25,10 +25,9 @@
* be some kind of architecture-independent. * be some kind of architecture-independent.
*/ */
#include "errno.h"
#include "stdarg.h" #include "stdarg.h"
#include "types.h" #include "types.h"
#include "errno.h"
/** /**
* Opaque structure storing the CPU context of an inactive kernel or * Opaque structure storing the CPU context of an inactive kernel or
@ -41,14 +40,12 @@
*/ */
struct cpu_state; struct cpu_state;
/** /**
* The type of the functions passed as arguments to the Kernel thread * The type of the functions passed as arguments to the Kernel thread
* related functions. * 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 * Function to create an initial context for a kernel thread starting
* its execution at function start_func with the argument initial_arg, * its execution at function start_func with the argument initial_arg,
@ -83,14 +80,9 @@ typedef void (cpu_kstate_function_arg1_t(void * arg1));
* *
* @note the newly created context is INTERRUPTIBLE by default ! * @note the newly created context is INTERRUPTIBLE by default !
*/ */
int cpu_kstate_init(struct cpu_state **kctxt, int cpu_kstate_init(struct cpu_state **kctxt, cpu_kstate_function_arg1_t *start_func,
cpu_kstate_function_arg1_t *start_func, vaddr_t start_arg, vaddr_t stack_bottom, size_t stack_size,
vaddr_t start_arg, cpu_kstate_function_arg1_t *exit_func, vaddr_t exit_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 * 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 * @param to_ctxt The CPU will resume its execution with the struct
* cpu_state located at this address. Must NOT be NULL. * cpu_state located at this address. Must NOT be NULL.
*/ */
void cpu_context_switch(struct cpu_state **from_ctxt, void cpu_context_switch(struct cpu_state **from_ctxt, struct cpu_state *to_ctxt);
struct cpu_state *to_ctxt);
/* /*
* Switch to the new given context (of a kernel/user thread) without * 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 * called after having changed the stack, but before restoring the CPU
* context to switch_to_ctxt. * context to switch_to_ctxt.
*/ */
void void cpu_context_exit_to(struct cpu_state *switch_to_ctxt,
cpu_context_exit_to(struct cpu_state *switch_to_ctxt, cpu_kstate_function_arg1_t *reclaiming_func, uint32_t reclaiming_arg)
cpu_kstate_function_arg1_t *reclaiming_func, __attribute__((noreturn));
uint32_t reclaiming_arg) __attribute__((noreturn));
/* ======================================================================= /* =======================================================================
* Public Accessor functions * Public Accessor functions
*/ */
/** /**
* Return Program Counter stored in the saved kernel/user context * Return Program Counter stored in the saved kernel/user context
*/ */
vaddr_t cpu_context_get_PC(const struct cpu_state *ctxt); vaddr_t cpu_context_get_PC(const struct cpu_state *ctxt);
/** /**
* Return Stack Pointer stored in the saved kernel/user context * Return Stack Pointer stored in the saved kernel/user context
*/ */
vaddr_t cpu_context_get_SP(const struct cpu_state *ctxt); vaddr_t cpu_context_get_SP(const struct cpu_state *ctxt);
/** /**
* Dump the contents of the CPU context (bochs + x86_videomem) * Dump the contents of the CPU context (bochs + x86_videomem)
*/ */
void cpu_context_dump(const struct cpu_state *ctxt); void cpu_context_dump(const struct cpu_state *ctxt);
/* ======================================================================= /* =======================================================================
* Public Accessor functions TO BE USED ONLY BY Exception handlers * Public Accessor functions TO BE USED ONLY BY Exception handlers
*/ */
/** /**
* Return the argument passed by the CPU upon exception, as stored in the * Return the argument passed by the CPU upon exception, as stored in the
* saved context * saved context
*/ */
uint32_t cpu_context_get_EX_info(const struct cpu_state *ctxt); uint32_t cpu_context_get_EX_info(const struct cpu_state *ctxt);
/** /**
* Return the faulting address of the exception * Return the faulting address of the exception
*/ */
vaddr_t vaddr_t cpu_context_get_EX_faulting_vaddr(const struct cpu_state *ctxt);
cpu_context_get_EX_faulting_vaddr(const struct cpu_state *ctxt);
/* ======================================================================= /* =======================================================================
* Macros controlling stack poisoning. * Macros controlling stack poisoning.
@ -193,16 +174,14 @@ cpu_context_get_EX_faulting_vaddr(const struct cpu_state *ctxt);
/* #undef CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW */ /* #undef CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW */
#if defined(CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW) #if defined(CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW)
void void cpu_state_prepare_detect_kernel_stack_overflow(const struct cpu_state *ctxt,
cpu_state_prepare_detect_kernel_stack_overflow(const struct cpu_state *ctxt,
vaddr_t kernel_stack_bottom, vaddr_t kernel_stack_bottom,
size_t kernel_stack_size); size_t kernel_stack_size);
void cpu_state_detect_kernel_stack_overflow(const struct cpu_state *ctxt, void cpu_state_detect_kernel_stack_overflow(const struct cpu_state *ctxt,
vaddr_t kernel_stack_bottom, vaddr_t kernel_stack_bottom,
size_t kernel_stack_size); size_t kernel_stack_size);
#else #else
# define cpu_state_prepare_detect_kernel_stack_overflow(ctxt,stkbottom,stksize) \ #define cpu_state_prepare_detect_kernel_stack_overflow(ctxt, stkbottom, stksize) ({/* nop \
({ /* nop */ }) */})
# define cpu_state_detect_kernel_stack_overflow(ctxt,stkbottom,stksize) \ #define cpu_state_detect_kernel_stack_overflow(ctxt, stkbottom, stksize) ({/* nop */})
({ /* nop */ })
#endif #endif

View File

@ -34,4 +34,3 @@
#define EPIPE 32 /* Broken pipe */ #define EPIPE 32 /* Broken pipe */
#define EDOM 33 /* Math argument out of domain of func */ #define EDOM 33 /* Math argument out of domain of func */
#define ERANGE 34 /* Math result not representable */ #define ERANGE 34 /* Math result not representable */

View File

@ -17,8 +17,7 @@ int exceptionSetRoutine(int exception, exception_handler handler)
exception_handler_array[exception] = handler; exception_handler_array[exception] = handler;
idt_set_handler(EXCEPTION_INTERRUPT_BASE_ADDRESS + exception, (unsigned int)handler, idt_set_handler(EXCEPTION_INTERRUPT_BASE_ADDRESS + exception, (unsigned int)handler, 0);
0);
restore_IRQs(flags); restore_IRQs(flags);
return 0; return 0;
} }

View File

@ -43,4 +43,3 @@
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); int exceptionSetRoutine(int exception, exception_handler handler);

View File

@ -80,10 +80,9 @@ struct x86_gdt_register {
.limit_15_0 = 0xffff, \ .limit_15_0 = 0xffff, \
.base_paged_addr_15_0 = 0, \ .base_paged_addr_15_0 = 0, \
.base_paged_addr_23_16 = 0, \ .base_paged_addr_23_16 = 0, \
.segment_type = \ .segment_type = ((is_code) ? 0xb : 0x3), /* With descriptor_type (below) = 1 \
((is_code) ? 0xb : 0x3), /* With descriptor_type (below) = 1 (code/data), \ * (code/data), see Figure 3-1 of \
* see Figure 3-1 of section 3.4.3.1 in Intel \ * section 3.4.3.1 in Intel x86 vol 3: \
* x86 vol 3: \
* - Code (bit 3 = 1): \ * - Code (bit 3 = 1): \
* bit 0: 1=Accessed \ * bit 0: 1=Accessed \
* bit 1: 1=Readable \ * bit 1: 1=Readable \
@ -92,8 +91,8 @@ struct x86_gdt_register {
* bit 0: 1=Accessed \ * bit 0: 1=Accessed \
* bit 1: 1=Writable \ * bit 1: 1=Writable \
* bit 2: 0=Expand up (stack-related) \ * bit 2: 0=Expand up (stack-related) \
* For Conforming/non conforming segments, see \ * For Conforming/non conforming segments, \
* Intel x86 Vol 3 section 4.8.1.1 \ * see Intel x86 Vol 3 section 4.8.1.1 \
*/ \ */ \
.descriptor_type = 1, /* 1=Code/Data */ \ .descriptor_type = 1, /* 1=Code/Data */ \
.dpl = ((descr_privilege_level)&0x3), \ .dpl = ((descr_privilege_level)&0x3), \

View File

@ -34,4 +34,3 @@
* address space (ie "flat" virtual space). * address space (ie "flat" virtual space).
*/ */
int gdtSetup(void); int gdtSetup(void);

View File

@ -38,8 +38,7 @@ struct idtRegister {
/* Build segment http://wiki.osdev.org/Selector*/ /* Build segment http://wiki.osdev.org/Selector*/
#define BUILD_SEGMENT_SELECTOR(desc_privilege, in_ldt, index) \ #define BUILD_SEGMENT_SELECTOR(desc_privilege, in_ldt, index) \
((((desc_privilege)&0x3) << 0) | (((in_ldt) ? 1 : 0) << 2) | \ ((((desc_privilege)&0x3) << 0) | (((in_ldt) ? 1 : 0) << 2) | ((index) << 3))
((index) << 3))
int idtSetup(); int idtSetup();
int idt_set_handler(int index, unsigned int addr, int priviledge); int idt_set_handler(int index, unsigned int addr, int priviledge);

View File

@ -1,7 +1,6 @@
#pragma once #pragma once
#include "stdarg.h" #include "stdarg.h"
// c.f. intel software-developer-vol-1 6.4.1 // c.f. intel software-developer-vol-1 6.4.1
struct interrupt_frame { struct interrupt_frame {
uint32_t eip; uint32_t eip;

View File

@ -5,17 +5,16 @@
static inline void outb(uint16_t port, uint8_t val) static inline void outb(uint16_t port, uint8_t val)
{ {
asm volatile("outb %0, %1" : : "a"(val), "Nd"(port)); 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). /* There's an outb %al, $imm8 encoding, for compile-time constant port numbers that fit in
* Wider immediate constants would be truncated at assemble-time (e.g. "i" constraint). * 8b. (N constraint). Wider immediate constants would be truncated at assemble-time (e.g.
* The outb %al, %dx encoding is the only option for all other cases. * "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 */ * %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) static inline uint8_t inb(uint16_t port)
{ {
uint8_t ret; uint8_t ret;
asm volatile ( "inb %1, %0" asm volatile("inb %1, %0" : "=a"(ret) : "Nd"(port));
: "=a"(ret)
: "Nd"(port) );
return ret; return ret;
} }

View File

@ -9,7 +9,9 @@ int irqSetup()
return 0; 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) int irqSetRoutine(int irq, irq_handler handler)
{ {
@ -22,8 +24,8 @@ int irqSetRoutine(int irq, irq_handler handler)
irq_handler_array[irq] = handler; irq_handler_array[irq] = handler;
if (handler != NULL) { if (handler != NULL) {
int ret = int ret = idt_set_handler(IRQ_INTERRUPT_BASE_ADDRESS + irq,
idt_set_handler(IRQ_INTERRUPT_BASE_ADDRESS + irq, (unsigned int)irq_handler_array[irq], 0); (unsigned int)irq_handler_array[irq], 0);
if (!ret) if (!ret)
enableIrq(irq); enableIrq(irq);
} }

View File

@ -11,7 +11,6 @@
}) })
#define restore_IRQs(flags) restore_flags(flags) #define restore_IRQs(flags) restore_flags(flags)
#define IRQ_TIMER 0 // MASTER IRQ #define IRQ_TIMER 0 // MASTER IRQ
#define IRQ_KEYBOARD 1 #define IRQ_KEYBOARD 1
#define IRQ_SLAVE_PIC 2 #define IRQ_SLAVE_PIC 2
@ -32,8 +31,9 @@
#define IRQ_INTERRUPT_BASE_ADDRESS 0x20 #define IRQ_INTERRUPT_BASE_ADDRESS 0x20
#define IRQ_NUM 16 #define IRQ_NUM 16
// An handler should finish by the iret opcode -> https://wiki.osdev.org/Interrupt_Service_Routines // An handler should finish by the iret opcode ->
// That's why we use wrapper around them or the gcc interrupt attribut // 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); // __attribute__((interrupt)) void (*irq_handler)(int irq);
typedef void (*irq_handler)(struct interrupt_frame *frame); typedef void (*irq_handler)(struct interrupt_frame *frame);
int irqSetup(); int irqSetup();

View File

@ -4,9 +4,9 @@
#define islower(c) (('a' <= (c)) && ((c) <= 'z')) #define islower(c) (('a' <= (c)) && ((c) <= 'z'))
#define isupper(c) (('A' <= (c)) && ((c) <= 'Z')) #define isupper(c) (('A' <= (c)) && ((c) <= 'Z'))
#define isdigit(c) (('0' <= (c)) && ((c) <= '9')) #define isdigit(c) (('0' <= (c)) && ((c) <= '9'))
#define isspace(c) (((c) == ' ') || ((c) == '\t') || \ #define isspace(c) \
((c) == '\f') || ((c) == '\n') || \ (((c) == ' ') || ((c) == '\t') || ((c) == '\f') || ((c) == '\n') || ((c) == '\r') || \
((c) == '\r') || ((c) == '\v')) ((c) == '\v'))
#define isprint(c) ((' ' <= (c)) && ((c) <= '~')) #define isprint(c) ((' ' <= (c)) && ((c) <= '~'))
int memcmp(const void *s1, const void *s2, size_t n); int memcmp(const void *s1, const void *s2, size_t n);
@ -36,12 +36,9 @@ void printf(const char *format, ...);
}) })
#ifdef DEBUG #ifdef DEBUG
#define pr_devel(fmt, ...) \ #define pr_devel(fmt, ...) printf(pr_fmt(fmt), ##__VA_ARGS__)
printf(pr_fmt(fmt), ##__VA_ARGS__)
#else #else
#define pr_devel(fmt, ...) \ #define pr_devel(fmt, ...) no_printf(pr_fmt(fmt), ##__VA_ARGS__)
no_printf(pr_fmt(fmt), ##__VA_ARGS__)
#endif #endif
#define pr_info(fmt, ...) \ #define pr_info(fmt, ...) printf(pr_fmt(fmt), ##__VA_ARGS__)
printf(pr_fmt(fmt), ##__VA_ARGS__)

View File

@ -53,8 +53,8 @@ struct kthread *kthreadCreate(const char *name, cpu_kstate_function_arg1_t func,
else else
strzcpy(thread->name, "[UNKNOW]", KTHREAD_NAME_MAX_LENGTH); strzcpy(thread->name, "[UNKNOW]", KTHREAD_NAME_MAX_LENGTH);
if (cpu_kstate_init(&thread->cpuState, (cpu_kstate_function_arg1_t *)func, if (cpu_kstate_init(&thread->cpuState, (cpu_kstate_function_arg1_t *)func, (vaddr_t)args,
(vaddr_t)args, thread->stackAddr, thread->stackSize, thread->stackAddr, thread->stackSize,
(cpu_kstate_function_arg1_t *)kthreadExit, 0)) (cpu_kstate_function_arg1_t *)kthreadExit, 0))
goto free_mem; goto free_mem;

View File

@ -25,33 +25,30 @@
* macros * macros
*/ */
/* *_named are used when next and prev links are not exactly next /* *_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, and prev. For instance when we have next_in_team, prev_in_team,
prev_global and next_global */ prev_global and next_global */
#define list_init_named(list,prev,next) \ #define list_init_named(list, prev, next) ((list) = NULL)
((list) = NULL)
#define list_singleton_named(list,item,prev,next) ({ \ #define list_singleton_named(list, item, prev, next) \
({ \
(item)->next = (item)->prev = (item); \ (item)->next = (item)->prev = (item); \
(list) = (item); \ (list) = (item); \
}) })
#define list_is_empty_named(list,prev,next) \ #define list_is_empty_named(list, prev, next) ((list) == NULL)
((list) == NULL)
#define list_is_singleton_named(list, prev, next) \ #define list_is_singleton_named(list, prev, next) \
(((list) != NULL) && ((list)->prev == (list)->next) && ((list) == (list)->next)) (((list) != NULL) && ((list)->prev == (list)->next) && ((list) == (list)->next))
#define list_get_head_named(list,prev,next) \ #define list_get_head_named(list, prev, next) (list)
(list)
#define list_get_tail_named(list,prev,next) \ #define list_get_tail_named(list, prev, next) ((list) ? ((list)->prev) : NULL)
((list)?((list)->prev):NULL)
/* Internal macro : insert before the head == insert at tail */ /* Internal macro : insert before the head == insert at tail */
#define __list_insert_atleft_named(before_this,item,prev,next) ({ \ #define __list_insert_atleft_named(before_this, item, prev, next) \
({ \
(before_this)->prev->next = (item); \ (before_this)->prev->next = (item); \
(item)->prev = (before_this)->prev; \ (item)->prev = (before_this)->prev; \
(before_this)->prev = (item); \ (before_this)->prev = (item); \
@ -59,20 +56,24 @@
}) })
/* @note Before_this and item are expected to be valid ! */ /* @note Before_this and item are expected to be valid ! */
#define list_insert_before_named(list,before_this,item,prev,next) ({ \ #define list_insert_before_named(list, before_this, item, prev, next) \
({ \
__list_insert_atleft_named(before_this, item, prev, next); \ __list_insert_atleft_named(before_this, item, prev, next); \
if ((list) == (before_this)) (list) = (item); \ if ((list) == (before_this)) \
(list) = (item); \
}) })
/** @note After_this and item are expected to be valid ! */ /** @note After_this and item are expected to be valid ! */
#define list_insert_after_named(list,after_this,item,prev,next) ({ \ #define list_insert_after_named(list, after_this, item, prev, next) \
({ \
(after_this)->next->prev = (item); \ (after_this)->next->prev = (item); \
(item)->next = (after_this)->next; \ (item)->next = (after_this)->next; \
(after_this)->next = (item); \ (after_this)->next = (item); \
(item)->prev = (after_this); \ (item)->prev = (after_this); \
}) })
#define list_add_head_named(list,item,prev,next) ({ \ #define list_add_head_named(list, item, prev, next) \
({ \
if (list) \ if (list) \
list_insert_before_named(list, list, item, prev, next); \ list_insert_before_named(list, list, item, prev, next); \
else \ else \
@ -80,7 +81,8 @@
(list) = (item); \ (list) = (item); \
}) })
#define list_add_tail_named(list,item,prev,next) ({ \ #define list_add_tail_named(list, item, prev, next) \
({ \
if (list) \ if (list) \
__list_insert_atleft_named(list, item, prev, next); \ __list_insert_atleft_named(list, item, prev, next); \
else \ else \
@ -88,21 +90,25 @@
}) })
/** @note NO check whether item really is in list ! */ /** @note NO check whether item really is in list ! */
#define list_delete_named(list,item,prev,next) ({ \ #define list_delete_named(list, item, prev, next) \
({ \
if (((item)->next == (item)) && ((item)->prev == (item))) \ if (((item)->next == (item)) && ((item)->prev == (item))) \
(item)->next = (item)->prev = (list) = NULL; \ (item)->next = (item)->prev = (list) = NULL; \
else { \ else { \
(item)->prev->next = (item)->next; \ (item)->prev->next = (item)->next; \
(item)->next->prev = (item)->prev; \ (item)->next->prev = (item)->prev; \
if ((item) == (list)) (list) = (item)->next; \ if ((item) == (list)) \
(list) = (item)->next; \
(item)->prev = (item)->next = NULL; \ (item)->prev = (item)->next = NULL; \
} \ } \
}) })
#define list_pop_head_named(list,prev,next) ({ \ #define list_pop_head_named(list, prev, next) \
({ \
typeof(list) __ret_elt = (list); \ typeof(list) __ret_elt = (list); \
list_delete_named(list, __ret_elt, prev, next); \ list_delete_named(list, __ret_elt, prev, next); \
__ret_elt; }) __ret_elt; \
})
/** Loop statement that iterates through all of its elements, from /** Loop statement that iterates through all of its elements, from
head to tail */ head to tail */
@ -115,49 +121,43 @@
tail back to head */ tail back to head */
#define list_foreach_backward_named(list, iterator, nb_elements, prev, next) \ #define list_foreach_backward_named(list, iterator, nb_elements, prev, next) \
for (nb_elements = 0, (iterator) = list_get_tail_named(list, prev, next); \ for (nb_elements = 0, (iterator) = list_get_tail_named(list, prev, next); \
(iterator) && (!nb_elements || \ (iterator) && \
((iterator) != list_get_tail_named(list,prev,next))) ; \ (!nb_elements || ((iterator) != list_get_tail_named(list, prev, next))); \
nb_elements++, (iterator) = (iterator)->prev) nb_elements++, (iterator) = (iterator)->prev)
#define list_foreach_named list_foreach_forward_named #define list_foreach_named list_foreach_forward_named
/** True when we exitted early from the foreach loop (ie break) */ /** True when we exitted early from the foreach loop (ie break) */
#define list_foreach_early_break(list, iterator, nb_elements) \ #define list_foreach_early_break(list, iterator, nb_elements) \
((list) && ( \ ((list) && (((list) != (iterator)) || (((list) == (iterator)) && (nb_elements == 0))))
((list) != (iterator)) || \
( ((list) == (iterator)) && (nb_elements == 0)) ))
/** Loop statement that also removes the item at each iteration. The /** Loop statement that also removes the item at each iteration. The
body of the loop is allowed to delete the iterator element from body of the loop is allowed to delete the iterator element from
memory. */ memory. */
#define list_collapse_named(list, iterator, prev, next) \ #define list_collapse_named(list, iterator, prev, next) \
for ( ; ({ ((iterator) = (list)) ; \ for (; ({ \
if (list) list_delete_named(list,iterator,prev,next) ; \ ((iterator) = (list)); \
(iterator); }) ; ) if (list) \
list_delete_named(list, iterator, prev, next); \
(iterator); \
});)
/* /*
* the same macros : assume that the prev and next fields are really * the same macros : assume that the prev and next fields are really
* named "prev" and "next" * named "prev" and "next"
*/ */
#define list_init(list) \ #define list_init(list) list_init_named(list, prev, next)
list_init_named(list,prev,next)
#define list_singleton(list,item) \ #define list_singleton(list, item) list_singleton_named(list, item, prev, next)
list_singleton_named(list,item,prev,next)
#define list_is_empty(list) \ #define list_is_empty(list) list_is_empty_named(list, prev, next)
list_is_empty_named(list,prev,next)
#define list_is_singleton(list) \ #define list_is_singleton(list) list_is_singleton_named(list, prev, next)
list_is_singleton_named(list,prev,next)
#define list_get_head(list) \ #define list_get_head(list) list_get_head_named(list, prev, next)
list_get_head_named(list,prev,next) \
#define list_get_tail(list) \ #define list_get_tail(list) list_get_tail_named(list, prev, next)
list_get_tail_named(list,prev,next) \
/* @note Before_this and item are expected to be valid ! */ /* @note Before_this and item are expected to be valid ! */
#define list_insert_after(list, after_this, item) \ #define list_insert_after(list, after_this, item) \
@ -167,18 +167,14 @@
#define list_insert_before(list, before_this, item) \ #define list_insert_before(list, before_this, item) \
list_insert_before_named(list, before_this, item, prev, next) list_insert_before_named(list, before_this, item, prev, next)
#define list_add_head(list,item) \ #define list_add_head(list, item) list_add_head_named(list, item, prev, next)
list_add_head_named(list,item,prev,next)
#define list_add_tail(list,item) \ #define list_add_tail(list, item) list_add_tail_named(list, item, prev, next)
list_add_tail_named(list,item,prev,next)
/* @note NO check whether item really is in list ! */ /* @note NO check whether item really is in list ! */
#define list_delete(list,item) \ #define list_delete(list, item) list_delete_named(list, item, prev, next)
list_delete_named(list,item,prev,next)
#define list_pop_head(list) \ #define list_pop_head(list) list_pop_head_named(list, prev, next)
list_pop_head_named(list,prev,next)
#define list_foreach_forward(list, iterator, nb_elements) \ #define list_foreach_forward(list, iterator, nb_elements) \
list_foreach_forward_named(list, iterator, nb_elements, prev, next) list_foreach_forward_named(list, iterator, nb_elements, prev, next)
@ -188,7 +184,6 @@
#define list_foreach list_foreach_forward #define list_foreach list_foreach_forward
#define list_collapse(list,iterator) \ #define list_collapse(list, iterator) list_collapse_named(list, iterator, prev, next)
list_collapse_named(list,iterator,prev,next)
#endif /* _SOS_LIST_H_ */ #endif /* _SOS_LIST_H_ */

View File

@ -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"); asm volatile("cpuid" : "=a"(*a), "=d"(*d) : "0"(code) : "ebx", "ecx");
} }
void idleThread(void *arg){ void idleThread(void *arg)
{
(void)arg; (void)arg;
int count = 0; int count = 0;
while (1) while (1)
printIntDetails(count++, GREEN, BLACK, 0, VGA_HEIGHT - 1); printIntDetails(count++, GREEN, BLACK, 0, VGA_HEIGHT - 1);
} }
// Multiboot information available here : // Multiboot information available here :
// https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#kernel_002ec // 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 // https://www.gnu.org/software/grub/manual/multiboot/html_node/Boot-information-format.html#Boot%20information%20format

View File

@ -1,11 +1,9 @@
#include "math.h" #include "math.h"
inline uint32_t log2(const uint32_t x) { inline uint32_t log2(const uint32_t x)
{
uint32_t y; uint32_t y;
// Get the highest set bit // Get the highest set bit
asm ( "\tbsr %1, %0\n" asm("\tbsr %1, %0\n" : "=r"(y) : "r"(x));
: "=r"(y)
: "r" (x)
);
return y; return y;
} }

View File

@ -1,7 +1,7 @@
#include "mem.h" #include "mem.h"
#include "klibc.h"
#include "list.h" #include "list.h"
#include "types.h" #include "types.h"
#include "klibc.h"
static struct mem_desc *page_desc = (struct mem_desc *)&__ld_kernel_end; static struct mem_desc *page_desc = (struct mem_desc *)&__ld_kernel_end;
static struct mem_desc *free_page; static struct mem_desc *free_page;
@ -20,8 +20,7 @@ int memSetup(paddr_t upperMem, paddr_t *lastUsedOut)
(upperMem * 1024 - (uint32_t)&__ld_kernel_end) / (1024 * 1024)); (upperMem * 1024 - (uint32_t)&__ld_kernel_end) / (1024 * 1024));
// Memory description is stored after the kernel. We need some place to store it // Memory description is stored after the kernel. We need some place to store it
unsigned long memdesc_end = unsigned long memdesc_end =
(unsigned long)page_desc + (unsigned long)page_desc + ((upperMem) / (PAGE_SIZE / 1024)) * sizeof(struct mem_desc);
((upperMem) / (PAGE_SIZE / 1024)) * sizeof(struct mem_desc);
uint lastUsed = (memdesc_end >> PAGE_SHIFT) + 1; uint lastUsed = (memdesc_end >> PAGE_SHIFT) + 1;
list_init(free_page); list_init(free_page);
list_init(used_page); list_init(used_page);

View File

@ -1,7 +1,6 @@
#pragma once #pragma once
#include "types.h"
#include "stdarg.h" #include "stdarg.h"
#include "types.h"
#define PAGE_SHIFT 12U #define PAGE_SHIFT 12U
#define PAGE_SIZE (1U << PAGE_SHIFT) #define PAGE_SIZE (1U << PAGE_SHIFT)
@ -16,7 +15,6 @@ struct mem_desc{
struct mem_desc *next, *prev; struct mem_desc *next, *prev;
}; };
int memSetup(paddr_t upperMem, paddr_t *lastUsed); int memSetup(paddr_t upperMem, paddr_t *lastUsed);
paddr_t allocPhyPage(void); paddr_t allocPhyPage(void);
int unrefPhyPage(paddr_t addr); int unrefPhyPage(paddr_t addr);

View File

@ -131,11 +131,10 @@ int pageMap(vaddr_t vaddr, paddr_t paddr, int flags)
uint ptEntry = (vaddr >> PT_SHIFT) & PTE_MASK; uint ptEntry = (vaddr >> PT_SHIFT) & PTE_MASK;
// Thank to mirroring, we can access the PD // Thank to mirroring, we can access the PD
struct pde *pd = (struct pde *)((PD_MIRROR_PAGE_IDX << PD_SHIFT) + struct pde *pd =
(PD_MIRROR_PAGE_IDX << PT_SHIFT)); (struct pde *)((PD_MIRROR_PAGE_IDX << PD_SHIFT) + (PD_MIRROR_PAGE_IDX << PT_SHIFT));
struct pte *pt = struct pte *pt = (struct pte *)((PD_MIRROR_PAGE_IDX << PD_SHIFT) + (pdEntry << PT_SHIFT));
(struct pte *)((PD_MIRROR_PAGE_IDX << PD_SHIFT) + (pdEntry << PT_SHIFT));
if (!pd[pdEntry].present) { if (!pd[pdEntry].present) {
paddr_t ptPhy = allocPhyPage(); paddr_t ptPhy = allocPhyPage();
@ -177,11 +176,10 @@ int pageUnmap(vaddr_t vaddr)
uint ptEntry = (vaddr >> PT_SHIFT) & PTE_MASK; uint ptEntry = (vaddr >> PT_SHIFT) & PTE_MASK;
// Thank to mirroring, we can access the PD // Thank to mirroring, we can access the PD
struct pde *pd = (struct pde *)((PD_MIRROR_PAGE_IDX << PD_SHIFT) + struct pde *pd =
(PD_MIRROR_PAGE_IDX << PT_SHIFT)); (struct pde *)((PD_MIRROR_PAGE_IDX << PD_SHIFT) + (PD_MIRROR_PAGE_IDX << PT_SHIFT));
struct pte *pt = struct pte *pt = (struct pte *)((PD_MIRROR_PAGE_IDX << PD_SHIFT) + (pdEntry << PT_SHIFT));
(struct pte *)((PD_MIRROR_PAGE_IDX << PD_SHIFT) + (pdEntry << PT_SHIFT));
if (!pd[pdEntry].present) if (!pd[pdEntry].present)
return -EINVAL; return -EINVAL;
if (!pt[ptEntry].present) if (!pt[ptEntry].present)

View File

@ -40,15 +40,11 @@
#define SEG_KCODE 1 /* Kernel code segment */ #define SEG_KCODE 1 /* Kernel code segment */
#define SEG_KDATA 2 /* Kernel data segment */ #define SEG_KDATA 2 /* Kernel data segment */
/** /**
* Helper macro that builds a segment register's value * Helper macro that builds a segment register's value
*/ */
#define BUILD_SEGMENT_REG_VALUE(desc_privilege, in_ldt, seg_index) \ #define BUILD_SEGMENT_REG_VALUE(desc_privilege, in_ldt, seg_index) \
( (((desc_privilege) & 0x3) << 0) \ ((((desc_privilege)&0x3) << 0) | (((in_ldt) ? 1 : 0) << 2) | ((seg_index) << 3))
| (((in_ldt)?1:0) << 2) \
| ((seg_index) << 3) )
/* /*
* Local segment selectors (LDT) for SOS/x86 * Local segment selectors (LDT) for SOS/x86

View File

@ -1,6 +1,6 @@
#include "stack.h" #include "stack.h"
#include "types.h"
#include "klibc.h" #include "klibc.h"
#include "types.h"
void printStackTrace(unsigned int maxFrames) void printStackTrace(unsigned int maxFrames)
{ {
@ -24,8 +24,7 @@ void printStackTrace(unsigned int maxFrames)
printf("[%d] 0x%x (", frame, eip); printf("[%d] 0x%x (", frame, eip);
int nbArg = 0; int nbArg = 0;
do { do {
if ((_stack_bottom <= (vaddr_t)arguments) && if ((_stack_bottom <= (vaddr_t)arguments) && ((vaddr_t)arguments <= _stack_top)) {
((vaddr_t)arguments <= _stack_top)) {
printf(" 0x%x", *arguments); printf(" 0x%x", *arguments);
arguments += 1; arguments += 1;
} else { } else {

View File

@ -1,6 +1,6 @@
#include "keyboard.h" #include "keyboard.h"
#include "klibc.h"
#include "io.h" #include "io.h"
#include "klibc.h"
const char *scancode[128] = { const char *scancode[128] = {
/* 0 */ 0, /* 0 */ 0,
@ -271,7 +271,8 @@ void keyboard_do_irq()
unsigned char c = inb(KEYBOARD_DATA_PORT); unsigned char c = inb(KEYBOARD_DATA_PORT);
const char *key = NULL; const char *key = NULL;
if (c > 0) { if (c > 0) {
if (c == 0xE0) { // non printable such as page up/down ... See https://wiki.osdev.org/Keyboard if (c == 0xE0) { // non printable such as page up/down ... See
// https://wiki.osdev.org/Keyboard
isExt = 1; isExt = 1;
} else if (isExt) { } else if (isExt) {
isExt = 0; isExt = 0;
@ -310,4 +311,3 @@ void keyboard_do_irq()
if (key) if (key)
printf(key); printf(key);
} }

View File

@ -14,7 +14,6 @@
#define PIC_SLAVE_DATA 0xa1 #define PIC_SLAVE_DATA 0xa1
#define PIC_EOI 0x20 /* End-of-interrupt command code */ #define PIC_EOI 0x20 /* End-of-interrupt command code */
void EOIIrq(int irq); void EOIIrq(int irq);
void initPic(void); void initPic(void);
void enableIrq(int irq); void enableIrq(int irq);

View File

@ -13,4 +13,3 @@
// 3 -> low then high 3-1: mode. See https://wiki.osdev.org/PIT // 3 -> low then high 3-1: mode. See https://wiki.osdev.org/PIT
int pitSetup(unsigned int freq); int pitSetup(unsigned int freq);

View File

@ -28,7 +28,8 @@ void serialSetup(int speed)
outb(PORT + 0, div & 0xFF); // Set divisor lo byte outb(PORT + 0, div & 0xFF); // Set divisor lo byte
outb(PORT + 1, div >> 8); // Set divisor hi byte outb(PORT + 1, div >> 8); // Set divisor hi byte
outb(PORT + 3, outb(PORT + 3,
UART_NO_PARITY | UART_8BITS_WORD | UART_1_STOP_BIT); // 8 bits, no parity, one stop bit 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 + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold
outb(PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set outb(PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set
irqSetRoutine(IRQ_COM1, serial_handler); irqSetRoutine(IRQ_COM1, serial_handler);

View File

@ -36,9 +36,8 @@ void clearScreenLine(uint bgColor, uint line)
void printIntDetails(int integer, uint color, uint bgColor, int startX, int startY) void printIntDetails(int integer, uint color, uint bgColor, int startX, int startY)
{ {
char num[sizeof(int) * char num[sizeof(int) * 3]; // int max is 2^(sizeof(int)*8) which is (2^3)^(sizeof(int)*8/3)
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)
// 8^(sizeof(int)*8/3) ~ 10^(sizeof(int)*8/3)
int x = startX; int x = startX;
int i = 0, k = 0; int i = 0, k = 0;
if (integer < 0) { if (integer < 0) {
@ -68,8 +67,7 @@ void vgaScrollUp(void)
{ {
long int colorAttr = vgaBgColor << 12; long int colorAttr = vgaBgColor << 12;
volatile short *vga = (short *)VGA_ADDR; volatile short *vga = (short *)VGA_ADDR;
for (int i = 1; i < VGA_HEIGHT - 1; for (int i = 1; i < VGA_HEIGHT - 1; i++) { // last line is status line. Do not scroll it
i++) { // last line is status line. Do not scroll it
memcpy((void *)&vga[VGA_WIDTH * (i - 1)], (void *)&vga[VGA_WIDTH * i], memcpy((void *)&vga[VGA_WIDTH * (i - 1)], (void *)&vga[VGA_WIDTH * i],
VGA_WIDTH * sizeof(short)); VGA_WIDTH * sizeof(short));
} }
@ -78,8 +76,6 @@ void vgaScrollUp(void)
} }
} }
void VGAputc(const char str) void VGAputc(const char str)
{ {
if (str == '\n') { if (str == '\n') {

View File

@ -32,4 +32,3 @@ void vgaScrollUp(void);
void cursorEnable(uint8_t cursor_start, uint8_t cursor_end); void cursorEnable(uint8_t cursor_start, uint8_t cursor_end);
void cursorDisable(void); void cursorDisable(void);
void cursorMove(int x, int y); void cursorMove(int x, int y);

View File

@ -28,14 +28,12 @@ void testPhymem(void)
while ((page = list_pop_head(allocated_page_list)) != NULL) { while ((page = list_pop_head(allocated_page_list)) != NULL) {
assertmsg(page->phy_addr == (ulong)freeCount, "page %d modified", page); assertmsg(page->phy_addr == (ulong)freeCount, "page %d modified", page);
assertmsg(unrefPhyPage((ulong)page) >= 0, "Failed to free page %d\n", assertmsg(unrefPhyPage((ulong)page) >= 0, "Failed to free page %d\n", (ulong)page);
(ulong)page);
freeCount++; freeCount++;
} }
printf("%d pages freed\n", freeCount); printf("%d pages freed\n", freeCount);
assertmsg((page = (struct mem_desc *)allocPhyPage()) != NULL, assertmsg((page = (struct mem_desc *)allocPhyPage()) != NULL, "Cannot allocate memory\n");
"Cannot allocate memory\n");
unrefPhyPage((ulong)page); unrefPhyPage((ulong)page);
} }
@ -113,17 +111,15 @@ static void testPaging(void)
printf("%d pages allocated\n", allocCount); printf("%d pages allocated\n", allocCount);
while ((page = list_pop_head(allocated_page_list)) != NULL) { while ((page = list_pop_head(allocated_page_list)) != NULL) {
assertmsg((char)page->phy_addr == (char)freeCount, assertmsg((char)page->phy_addr == (char)freeCount, "page modified %d but is %d\n",
"page modified %d but is %d\n", freeCount, page->phy_addr); freeCount, page->phy_addr);
assertmsg(unrefPhyPage((ulong)page) >= 0, "Failed to free page %d\n", assertmsg(unrefPhyPage((ulong)page) >= 0, "Failed to free page %d\n", (ulong)page);
(ulong)page);
pageUnmap((vaddr_t)page); pageUnmap((vaddr_t)page);
freeCount++; freeCount++;
} }
printf("%d pages freed\n", freeCount); printf("%d pages freed\n", freeCount);
assertmsg((page = (struct mem_desc *)allocPhyPage()) != NULL, assertmsg((page = (struct mem_desc *)allocPhyPage()) != NULL, "Cannot allocate memory\n");
"Cannot allocate memory\n");
unrefPhyPage((ulong)page); unrefPhyPage((ulong)page);
} }
@ -162,7 +158,8 @@ static void reclaim_stack(void * 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) static void hello1(void *strIn)