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:
2021-04-19 03:40:33 -05:00
parent 086dfe546a
commit 5efc389935
22 changed files with 246 additions and 162 deletions

View File

@@ -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);
}