Style: harmonize formatting
Thanks to: "clang-format -i -style=file **/*.{c,h}"
This commit is contained in:
parent
fd6551e90c
commit
3b97d0307d
@ -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)
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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 */
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
11
core/gdt.c
11
core/gdt.c
@ -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), \
|
||||||
|
@ -34,4 +34,3 @@
|
|||||||
* address space (ie "flat" virtual space).
|
* address space (ie "flat" virtual space).
|
||||||
*/
|
*/
|
||||||
int gdtSetup(void);
|
int gdtSetup(void);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
13
core/io.h
13
core/io.h
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
15
core/klibc.h
15
core/klibc.h
@ -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__)
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
97
core/list.h
97
core/list.h
@ -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_ */
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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 {
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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') {
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
19
tests/test.c
19
tests/test.c
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user