Finished basic task switching mechansim
PCB is local to a process's address space. Context switches are written in assembly. Moved x86 headers to include/x86
This commit is contained in:
@@ -1,11 +1,14 @@
|
||||
#include "interrupts.h"
|
||||
#include "isr.h"
|
||||
#include "x86/interrupts.h"
|
||||
#include "x86/isr.h"
|
||||
#include "string.h"
|
||||
#include "system.h"
|
||||
#include <stddef.h>
|
||||
|
||||
#define idt_size 256
|
||||
#define gdt_size 6
|
||||
|
||||
extern int default_page_dir;
|
||||
|
||||
enum segment_type_t
|
||||
{
|
||||
SEGMENT_KERNEL_CODE,
|
||||
@@ -86,7 +89,7 @@ struct descriptor_table_info_t
|
||||
void load_gdt(struct gdt_entry_t *gdt)
|
||||
{
|
||||
struct descriptor_table_info_t gdt_info;
|
||||
gdt_info.size = sizeof(struct gdt_entry_t) * 6 - 1;
|
||||
gdt_info.size = sizeof(struct gdt_entry_t) * 7 - 1;
|
||||
gdt_info.location = (void *)gdt;
|
||||
asm("lgdt (%0);"
|
||||
"jmp $8, $.ldcs;"
|
||||
@@ -120,11 +123,14 @@ void load_tr(uint16_t gdt_offset)
|
||||
: "r"(gdt_offset));
|
||||
}
|
||||
|
||||
void create_interrupt_descriptor(struct interrupt_descriptor_t *descriptor, void *isr, enum isr_type_t type, uint32_t privilage)
|
||||
void create_interrupt_descriptor(struct interrupt_descriptor_t *descriptor, void *isr, enum isr_type_t type, uint32_t privilage, uint32_t selector)
|
||||
{
|
||||
descriptor->offset_1 = (uint32_t) isr & 0xFFFF;
|
||||
descriptor->offset_2 = (uint32_t) isr >> 16;
|
||||
descriptor->selector = 8;
|
||||
if(type != INTERRPUT_TASK32)
|
||||
{
|
||||
descriptor->offset_1 = (uint32_t) isr & 0xFFFF;
|
||||
descriptor->offset_2 = (uint32_t) isr >> 16;
|
||||
}
|
||||
descriptor->selector = selector;
|
||||
descriptor->zero = 0;
|
||||
descriptor->type = type;
|
||||
descriptor->storage = 0;
|
||||
@@ -207,15 +213,26 @@ void initialize_gdt()
|
||||
{
|
||||
static struct gdt_entry_t gdt[gdt_size];
|
||||
static struct tss_entry_t tss;
|
||||
static struct tss_entry_t double_fault_tss;
|
||||
memset(gdt, 0, sizeof(struct gdt_entry_t) * gdt_size);
|
||||
create_segment_descriptor(&gdt[1], 0, 0xFFFFF, SEGMENT_KERNEL_CODE);
|
||||
create_segment_descriptor(&gdt[2], 0, 0xFFFFF, SEGMENT_KERNEL_DATA);
|
||||
create_segment_descriptor(&gdt[3], 0, 0xFFFFF, SEGMENT_USER_CODE);
|
||||
create_segment_descriptor(&gdt[4], 0, 0xFFFFF, SEGMENT_USER_DATA);
|
||||
create_segment_descriptor(&gdt[5], (size_t)&tss, sizeof(struct tss_entry_t) - 1, SEGMENT_TSS);
|
||||
create_segment_descriptor(&gdt[6], (size_t)&double_fault_tss, sizeof(struct tss_entry_t) - 1, SEGMENT_TSS);
|
||||
memset(&tss, 0, sizeof(tss));
|
||||
tss.esp0 = 0xFF800000;
|
||||
memset(&double_fault_tss, 0, sizeof(tss));
|
||||
tss.esp0 = &stack_top;
|
||||
tss.ss0 = 0x10;
|
||||
double_fault_tss.esp0 = &stack_top;
|
||||
double_fault_tss.ss0 = 0x10;
|
||||
double_fault_tss.esp = &stack_top;
|
||||
double_fault_tss.cs = 0x08;
|
||||
double_fault_tss.ds = 0x10;
|
||||
double_fault_tss.ss = 0x10;
|
||||
double_fault_tss.cr3 = &default_page_dir;
|
||||
double_fault_tss.eip = (void*)isr_double_fault;
|
||||
load_gdt(gdt);
|
||||
load_tr(5 * sizeof(struct gdt_entry_t));
|
||||
}
|
||||
@@ -226,15 +243,14 @@ void initialize_idt()
|
||||
memset(idt, 0, sizeof(struct interrupt_descriptor_t) * idt_size);
|
||||
for(int i = 0; i < idt_size; i++)
|
||||
{
|
||||
create_interrupt_descriptor(&idt[i], (void*)isr_generic, INTERRPUT_INT32, 0);
|
||||
create_interrupt_descriptor(&idt[i], (void*)isr_generic, INTERRPUT_INT32, 0, 8);
|
||||
}
|
||||
create_interrupt_descriptor(&idt[EXCEPTION_DIV_BY_0], (void*)isr_division_by_zero, INTERRPUT_INT32, 0);
|
||||
create_interrupt_descriptor(&idt[EXCEPTION_GPF], (void*)isr_gp_fault, INTERRPUT_TRAP32, 0);
|
||||
create_interrupt_descriptor(&idt[EXCEPTION_PAGE_FAULT], (void*)isr_page_fault, INTERRPUT_TRAP32, 0);
|
||||
create_interrupt_descriptor(&idt[EXCEPTION_DOUBLE_FAULT], (void*)isr_double_fault, INTERRPUT_TRAP32, 0);
|
||||
create_interrupt_descriptor(&idt[ISR_PREEMPT], (void*)isr_preempt, INTERRPUT_INT32, 0);
|
||||
create_interrupt_descriptor(&idt[ISR_APIC_TIMER], (void*)isr_timer, INTERRPUT_INT32, 0);
|
||||
create_interrupt_descriptor(&idt[ISR_AP_START], (void*)isr_ap_start, INTERRPUT_INT32, 0);
|
||||
create_interrupt_descriptor(&idt[ISR_SYSCALL], (void*)isr_syscall, INTERRPUT_INT32, 0);
|
||||
create_interrupt_descriptor(&idt[EXCEPTION_DIV_BY_0], (void*)isr_division_by_zero, INTERRPUT_INT32, 0, 8);
|
||||
create_interrupt_descriptor(&idt[EXCEPTION_GPF], (void*)isr_gp_fault, INTERRPUT_TRAP32, 0, 8);
|
||||
create_interrupt_descriptor(&idt[EXCEPTION_PAGE_FAULT], (void*)isr_page_fault, INTERRPUT_TRAP32, 0, 8);
|
||||
create_interrupt_descriptor(&idt[EXCEPTION_DOUBLE_FAULT], (void*)isr_double_fault, INTERRPUT_TASK32, 0, 8 * 6);
|
||||
create_interrupt_descriptor(&idt[ISR_PREEMPT], (void*)isr_preempt, INTERRPUT_INT32, 3, 8);
|
||||
create_interrupt_descriptor(&idt[ISR_APIC_TIMER], (void*)isr_timer, INTERRPUT_INT32, 0, 8);
|
||||
create_interrupt_descriptor(&idt[ISR_SYSCALL], (void*)isr_syscall, INTERRPUT_INT32, 0, 8);
|
||||
load_idt(idt);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user