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

156
include/x86/apic.h Normal file
View File

@@ -0,0 +1,156 @@
#pragma once
#include <stdint.h>
enum apic_delivery_mode_t
{
APIC_DELIVERY_MODE_FIXED = 0b000,
APIC_DELIVERY_MODE_LOWEST_PRIORITY = 0b001,
APIC_DELIVERY_MODE_SMI = 0b010,
APIC_DELIVERY_MODE_NMI = 0b100,
APIC_DELIVERY_MODE_INIT = 0b101,
APIC_DELIVERY_MODE_SIPI = 0b110,
APIV_DELIVERY_MODE_EXTINIT = 0b111
};
enum apic_destination_mode_t
{
APIC_DESTINATION_MODE_PHYSICAL = 0,
APIC_DESTINATION_MODE_LOGICAL = 1
};
enum apic_level_t
{
APIC_LEVEL_DEASSERT = 0,
APIC_LEVEL_ASSERT = 1
};
enum apic_trigger_mode_t
{
APIC_TRIGGER_MODE_EDGE = 0,
APIC_TRIGGER_MODE_LEVEL = 1
};
enum apic_destination_shorthand_t
{
APIC_DEST_SHORTHAND_NONE = 0,
APIC_DEST_SHORTHAND_SELF = 1,
APIC_DEST_SHORTHAND_ALL = 2,
APIC_DEST_SHORTHAND_OTHERS = 3
};
enum apic_divide_mode_t
{
APIC_DIVIDE_1 = 0b1011,
APIC_DIVIDE_2 = 0b0000,
APIC_DIVIDE_4 = 0b0001,
APIC_DIVIDE_8 = 0b0010,
APIC_DIVIDE_16 = 0b0011,
APIC_DIVIDE_32 = 0b1000,
APIC_DIVIDE_64 = 0b1001,
APIC_DIVIDE_128 = 0b1011
};
enum apic_timer_mode_t
{
APIC_TIMER_ONESHOT = 0,
APIC_TIMER_PERIODIC = 1,
APIC_TIMER_TSCDEADLINE = 2
};
struct apic_register_t
{
uint32_t value;
uint32_t padding[3];
};
struct apic_lapic_version_t
{
uint32_t version : 8;
uint32_t reserved_1 : 8;
uint32_t max_lvt_entry : 8;
uint32_t suppress_eoi_broadcast : 1;
uint32_t reserved_2 : 7;
uint32_t padding[3];
};
struct apic_lvt_t
{
uint32_t vector: 8;
uint32_t delivery_mode : 3;
uint32_t reserved_1 : 1;
uint32_t delivery_status : 1;
uint32_t pin_polarity : 1;
uint32_t remote_irr : 1;
uint32_t trigger_mode : 1;
uint32_t mask : 1;
uint32_t timer_mode : 2;
uint32_t reserved_2 : 13;
uint32_t padding[3];
};
struct apic_icr_t
{
uint32_t vector : 8;
uint32_t delivery_mode : 3;
uint32_t destination_mode : 1;
uint32_t delivery_status : 1;
uint32_t reserved_1 : 1;
uint32_t level : 1;
uint32_t trigger_mode : 1;
uint32_t reserved_2 : 2;
uint32_t destination_shorthand : 2;
uint32_t reserved_3 : 12;
uint32_t padding_1[3];
uint32_t reserved : 24;
uint32_t destination : 8;
uint32_t padding_2[3];
};
struct apic_registers_t
{
struct apic_register_t reserved_1[2];
struct apic_register_t lapic_id;
struct apic_lapic_version_t lapic_version;
struct apic_register_t reserved_2[4];
struct apic_register_t task_priority;
struct apic_register_t arbitration_priority;
struct apic_register_t processor_priority;
struct apic_register_t eoi;
struct apic_register_t remote_read;
struct apic_register_t logical_destination;
struct apic_register_t destination_format;
struct apic_register_t spurious_iv;
struct apic_register_t in_service[8];
struct apic_register_t trigger_mode[8];
struct apic_register_t interrupt_request[8];
struct apic_register_t error_status;
struct apic_register_t reserved_3[6];
struct apic_lvt_t lvt_cmci;
struct apic_icr_t interrput_command;
struct apic_lvt_t lvt_timer;
struct apic_lvt_t lvt_thermal_sensor;
struct apic_lvt_t lvt_performance_counters;
struct apic_lvt_t lvt_lint0;
struct apic_lvt_t lvt_lint1;
struct apic_lvt_t lvt_error;
struct apic_register_t initial_count;
struct apic_register_t current_count;
struct apic_register_t reserved_4[4];
struct apic_register_t divide_config;
struct apic_register_t reserved_5;
};
extern struct apic_registers_t volatile *apic_registers;
void apic_enable();
void apic_eoi();
void apic_send_ipi(
uint32_t vector,
enum apic_delivery_mode_t delivery_mode,
enum apic_destination_mode_t destination_mode,
enum apic_level_t level,
enum apic_trigger_mode_t trigger_mode,
enum apic_destination_shorthand_t shorthand,
uint32_t destination);

44
include/x86/interrupts.h Normal file
View File

@@ -0,0 +1,44 @@
#pragma once
#include <stdint.h>
enum interrupt_code_t
{
EXCEPTION_DIV_BY_0 = 0,
EXCEPTION_DEBUG = 1,
EXCEPTION_NMI = 2,
EXCEPTION_BREAKPOINT = 3,
EXCEPTION_OVERFLOW = 4,
EXCEPTION_OUT_OF_BOUNDS = 5,
EXCEPTION_INVALID_OPCODE = 6,
EXCEPTION_DEVICE_NOT_AVAILABLE = 7,
EXCEPTION_DOUBLE_FAULT = 8,
EXCEPTION_INVALID_TSS = 10,
EXCEPTION_SEGMENT_NOT_PRESENT = 11,
EXCEPTION_STACK_SEGMENT_FAULT = 12,
EXCEPTION_GPF = 13,
EXCEPTION_PAGE_FAULT = 14,
EXCEPTION_x87_FLOATING_POINT = 16,
EXCEPTION_ALIGNMENT_CHECK = 17,
EXCEPTION_MACHINE_CHECK = 18,
EXCEPTION_SIMD_FLOATING_POINT = 19,
EXCEPTION_VIRTUALIZATION = 20,
EXCEPTION_SECURITY = 30,
ISR_APIC_TIMER = 64,
ISR_PREEMPT = 65,
ISR_AP_START = 127,
ISR_SYSCALL = 128
};
enum isr_type_t
{
INTERRPUT_TASK32 = 5,
INTERRPUT_TRAP32 = 15,
INTERRPUT_INT32 = 14,
INTERRPUT_TRAP16 = 7,
INTERRPUT_INT16 = 6
};
void initialize_gdt();
void initialize_idt();

27
include/x86/isr.h Normal file
View File

@@ -0,0 +1,27 @@
#pragma once
struct interrupt_frame_t;
__attribute__ ((interrupt))
void isr_generic(struct interrupt_frame_t *frame);
__attribute__ ((interrupt))
void isr_division_by_zero(struct interrupt_frame_t *frame);
__attribute__ ((interrupt))
void isr_gp_fault(struct interrupt_frame_t *frame, unsigned int error);
__attribute__ ((interrupt))
void isr_page_fault(struct interrupt_frame_t *frame, unsigned int error);
__attribute__ ((interrupt))
void isr_double_fault(struct interrupt_frame_t *frame, unsigned int error);
__attribute__ ((interrupt))
void isr_timer(struct interrupt_frame_t *frame);
__attribute__ ((naked))
void isr_preempt(struct interrupt_frame_t *frame);
__attribute__ ((interrupt))
void isr_syscall(struct interrupt_frame_t *frame);

22
include/x86/msr.h Normal file
View File

@@ -0,0 +1,22 @@
#pragma once
#include <stdint.h>
enum msr_id_t
{
MSR_APIC_BASE = 0x1B
};
struct msr_apic_base_t
{
uint64_t reserved_1 : 8;
uint64_t bsp : 1;
uint64_t reserved_2 : 1;
uint64_t x2apic_enable : 1;
uint64_t apic_global_enable : 1;
uint64_t apic_base : 52;
};
void read_msr(enum msr_id_t msr_addr, uint64_t *value);
void write_msr(enum msr_id_t msr_addr, uint64_t *value);

84
include/x86/multiboot2.h Normal file
View File

@@ -0,0 +1,84 @@
#pragma once
#include "memorymap.h"
#include "module.h"
#include <stddef.h>
#include <stdint.h>
#define module_limit 8
enum multiboot2_tag_types
{
MB_END_TAG = 0,
MB_BOOT_COMMAND = 1,
MB_BOOTLOADER = 2,
MB_MODULE = 3,
MB_MEMORY_INFO = 4,
MB_BIOS_BOOT_DEVICE = 5,
MB_MEMORY_MAP = 6,
MB_VBE = 7,
MB_FRAMEBUFFER = 8,
MB_ELF_SYMBOLS = 9,
MB_APM = 10,
MB_EFI32_SYSTEM_TABLE = 11,
MB_EFI64_SYSTEM_TABLE = 12,
MB_SMBIOS = 13,
MB_ACPI10_RSDP = 14,
MB_ACPT20_RSDP = 15,
MB_NETOWRK = 16,
MB_EFI_MEMORY_MAP = 17,
MB_EFI_BOOT_SERVICES = 18,
MB_EFI32_IMAGE = 19,
MB_EFI64_IMAGE = 20,
MB_LOAD_ADDRESS = 21
};
enum multiboot2_memory_types
{
MB_AVAILABLE = 1,
MB_ACPI = 3,
MB_DEFECTIVE = 5
};
struct multiboot2_string_t
{
uint32_t type;
uint32_t size;
char str;
};
struct multiboot2_module_t
{
uint32_t type;
uint32_t size;
uint32_t start;
uint32_t end;
char str;
};
struct multiboot2_map_entry_t
{
uint64_t base;
uint64_t length;
uint32_t type;
};
struct multiboot2_memory_map_t
{
uint32_t type;
uint32_t size;
uint32_t entry_size;
uint32_t entry_version;
struct multiboot2_map_entry_t entries;
};
struct boot_info_t
{
char *bootloader;
char *parameters;
size_t module_count;
struct memory_map_t map;
struct module_t modules[module_limit];
};
void *read_multiboot_table(struct boot_info_t *boot_info, void *table);

View File

@@ -0,0 +1,21 @@
#pragma once
#include <stdint.h>
#define PCB_LOCATION 0x800
struct process_state_t
{
uint32_t eax;
uint32_t ebx;
uint32_t ecx;
uint32_t edx;
uint32_t edi;
uint32_t esi;
uint32_t ebp;
uint32_t ss;
uint32_t esp;
uint32_t cs;
uint32_t eip;
uint32_t flags;
};