Skip to content

Commit

Permalink
185 user mode settings (#187)
Browse files Browse the repository at this point in the history
* Allocate rsp0

* When switching tasks make sure to update the rsp0 in the kernel_tss struct.

* move some code around in order to get ready to enable user mode

* Refactor files structure

* Fix tests

* Add parameter to map_vaddress function

* Fix kheap

* use hhdm for task vm initialization

* Add page root hhdm
  • Loading branch information
dreamos82 authored Nov 8, 2023
1 parent 6664d72 commit df48ecf
Show file tree
Hide file tree
Showing 32 changed files with 342 additions and 258 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ gdb: $(BUILD_FOLDER)/$(ISO_IMAGE_FILENAME)
$(QEMU_SYSTEM) -cdrom $(BUILD_FOLDER)/$(ISO_IMAGE_FILENAME) -monitor unix:qemu-monitor-socket,server,nowait -serial file:dreamos64.log -m 1G -d int -no-reboot -no-shutdown -s -S

tests:
rm -f tests/*.o
$(X_CC) ${TESTFLAGS} tests/test_mem.c tests/test_common.c src/kernel/mem/bitmap.c src/kernel/mem/vmm_util.c src/kernel/mem/pmm.c src/kernel/mem/mmap.c -o tests/test_mem.o
$(X_CC) ${TESTFLAGS} tests/test_number_conversion.c tests/test_common.c src/base/numbers.c -o tests/test_number_conversion.o
$(X_CC) ${TESTFLAGS} tests/test_kheap.c tests/test_common.c src/kernel/mem/kheap.c src/kernel/mem/bitmap.c src/kernel/mem/pmm.c src/kernel/mem/mmap.c src/kernel/mem/vmm_util.c -o tests/test_kheap.o
Expand Down
9 changes: 6 additions & 3 deletions build/Common.mk
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ CFLAGS := -std=gnu99 \
-I src/include/base \
-I src/include/kernel \
-I src/include/kernel/mem \
-I src/include/kernel/x86_64 \
-I src/include/kernel/arch/x86_64 \
-I src/include/kernel/arch/common \
-I src/include/kernel/arch/common/mem \
-I src/include/kernel/hardware \
-I src/include/kernel/scheduling \
-I src/include/libc \
Expand All @@ -20,7 +22,7 @@ CFLAGS := -std=gnu99 \
-mno-sse \
-mcmodel=large \
-fno-stack-protector

CFLAGS += $(DEF_FLAGS)

TESTFLAGS := -std=gnu99 \
Expand All @@ -31,7 +33,8 @@ TESTFLAGS := -std=gnu99 \
-I src/include/fs \
-I src/include/drivers/fs \
-I src/include/kernel \
-I src/include/kernel/x86_64 \
-I src/include/kernel/arch/x86_64 \
-I src/include/kernel/arch/common/mem \
-I src/include/sys \
-DSMALL_PAGES=$(SMALL_PAGES) \
-D_TEST_=1
Expand Down
11 changes: 11 additions & 0 deletions src/include/kernel/arch/common/mem/vmm_mapping.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#ifndef _VMM_MAPPING_H_
#define _VMM_MAPPING_H_

void *map_phys_to_virt_addr(void* physical_address, void* address, size_t flags, uint64_t *pml4_root);
void identity_map_phys_address(void *pyhysical_address, size_t flags);
void map_vaddress_range(void *virtual_address, size_t flags, size_t required_pages, uint64_t *pml4_root);

void *map_vaddress(void *address, size_t flags, uint64_t *pml4_root);
int unmap_vaddress(void *address);

#endif
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
9 changes: 9 additions & 0 deletions src/include/kernel/mem/hh_direct_map.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#ifndef __HH_DIRECT_MAP__
#define __HH_DIRECT_MAP__

#include <stddef.h>

void *hhdm_get_variable ( size_t phys_address );
void hhdm_map_physical_memory();

#endif
10 changes: 4 additions & 6 deletions src/include/kernel/mem/vmm.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ typedef struct VmmInfo {

size_t start_of_vmm_space; /**< The starting addres ofthe vmm space */

uintptr_t root_table_hhdm;

struct VmmStatus {
size_t vmm_items_per_page; /**< Number of page items contained in one page */
size_t vmm_cur_index; /**< Current position inside the array */
Expand All @@ -68,6 +70,8 @@ typedef struct VmmInfo {
} status;
} VmmInfo;

//uint64_t memory_size_in_bytes;
extern uint64_t end_of_mapped_memory;
extern uint64_t end_of_vmm_space;
extern VmmInfo vmm_info;
extern uintptr_t higherHalfDirectMapBase; /**< The start of the physical memory direct mapping */
Expand All @@ -77,12 +81,6 @@ void vmm_init(vmm_level_t vmm_level, VmmInfo *vmm_info);
void *vmm_alloc(size_t size, size_t flags, VmmInfo *vmm_info);
void vmm_free(void *address);

void *map_vaddress(void *address, size_t flags);
int unmap_vaddress(void *address);

void *map_phys_to_virt_addr(void* physical_address, void* address, size_t flags);
void identity_map_phys_address(void *pyhysical_address, size_t flags);
void map_vaddress_range(void *virtual_address, size_t flags, size_t required_pages);
uint8_t is_phyisical_address_mapped(uintptr_t physical_address, uintptr_t virtual_address);
uint8_t check_virt_address_status(uint64_t virtual_address);
void vmm_direct_map_physical_memory();
Expand Down
4 changes: 2 additions & 2 deletions src/include/kernel/scheduling/thread.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#ifndef _THREAD_H_
#define _THREAD_H_

#include <cpu.h>
#include <stdint.h>
#include <stddef.h>
#include <cpu.h>

#define THREAD_NAME_MAX_LEN 32
#define THREAD_MAX_ID (uint16_t-1)
Expand Down Expand Up @@ -35,7 +35,7 @@ struct thread_t {
size_t wakeup_time;
thread_t* next_sibling;
thread_t* next;
uint64_t* rsp0;
uintptr_t* rsp0;
};


Expand Down
41 changes: 21 additions & 20 deletions src/kernel/arch/x86_64/cpu/acpi.c
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
#include <cpu.h>
#include <acpi.h>
#include <video.h>
#include <bitmap.h>
#include <cpu.h>
#include <framebuffer.h>
#include <stdio.h>
#include <kheap.h>
#include <logging.h>
#include <numbers.h>
#include <rsdt.h>
#include <stdio.h>
#include <stddef.h>
#include <string.h>
#include <numbers.h>
#include <vmm.h>
#include <kheap.h>
#include <video.h>
#include <vm.h>
#include <bitmap.h>
#include <logging.h>
#include <vmm.h>
#include <vmm_mapping.h>

RSDT* rsdt_root = NULL;
XSDT* xsdt_root = NULL;
Expand All @@ -24,13 +25,13 @@ void parse_SDT(uint64_t address, uint8_t type) {
parse_RSDT((RSDPDescriptor *) address);
} else if ( type == RSDT_V2 ) {
parse_RSDTv2((RSDPDescriptor20 *) address);
}
}
}

void parse_RSDT(RSDPDescriptor *descriptor){
loglinef(Verbose, "(parse_RSDT): - Parse RSDP Descriptor");
loglinef(Verbose, "(parse_RSDT): - descriptor Address: 0x%x", descriptor->RsdtAddress);
map_phys_to_virt_addr((void *) ALIGN_PHYSADDRESS(descriptor->RsdtAddress), (void *) ensure_address_in_higher_half(descriptor->RsdtAddress), VMM_FLAGS_PRESENT | VMM_FLAGS_WRITE_ENABLE);
map_phys_to_virt_addr((void *) ALIGN_PHYSADDRESS(descriptor->RsdtAddress), (void *) ensure_address_in_higher_half(descriptor->RsdtAddress), VMM_FLAGS_PRESENT | VMM_FLAGS_WRITE_ENABLE, NULL);
_bitmap_set_bit_from_address(ALIGN_PHYSADDRESS(descriptor->RsdtAddress));
rsdt_root = (RSDT *) ensure_address_in_higher_half((uint64_t) descriptor->RsdtAddress);
ACPISDTHeader header = rsdt_root->header;
Expand All @@ -45,15 +46,15 @@ void parse_RSDT(RSDPDescriptor *descriptor){
//loglinef(Verbose, "(parse_RSDT): - RSDT_PAGES_NEEDED: %d", required_extra_pages);
for (size_t j = 1; j < required_extra_pages; j++) {
uint64_t new_physical_address = descriptor->RsdtAddress + (j * KERNEL_PAGE_SIZE);
map_phys_to_virt_addr((void *) ALIGN_PHYSADDRESS(new_physical_address), (void *) ensure_address_in_higher_half(new_physical_address), VMM_FLAGS_PRESENT | VMM_FLAGS_WRITE_ENABLE);
map_phys_to_virt_addr((void *) ALIGN_PHYSADDRESS(new_physical_address), (void *) ensure_address_in_higher_half(new_physical_address), VMM_FLAGS_PRESENT | VMM_FLAGS_WRITE_ENABLE, NULL);
_bitmap_set_bit_from_address(ALIGN_PHYSADDRESS(new_physical_address));
}
}
rsdtTablesTotal = (header.Length - sizeof(ACPISDTHeader)) / sizeof(uint32_t);
loglinef(Verbose, "(parse_RSDT): - Total rsdt Tables: %d", rsdtTablesTotal);

for(uint32_t i=0; i < rsdtTablesTotal; i++) {
map_phys_to_virt_addr((void *) ALIGN_PHYSADDRESS(rsdt_root->tables[i]), (void *) ensure_address_in_higher_half(rsdt_root->tables[i]), VMM_FLAGS_PRESENT | VMM_FLAGS_WRITE_ENABLE);
map_phys_to_virt_addr((void *) ALIGN_PHYSADDRESS(rsdt_root->tables[i]), (void *) ensure_address_in_higher_half(rsdt_root->tables[i]), VMM_FLAGS_PRESENT | VMM_FLAGS_WRITE_ENABLE, NULL);
ACPISDTHeader *tableHeader = (ACPISDTHeader *) ensure_address_in_higher_half(rsdt_root->tables[i]);
loglinef(Verbose, "(parse_RSDT): \tTable header %d: Signature: %.4s", i, tableHeader->Signature);
}
Expand All @@ -62,7 +63,7 @@ void parse_RSDT(RSDPDescriptor *descriptor){
void parse_RSDTv2(RSDPDescriptor20 *descriptor){
loglinef(Verbose, "(parse_RSDTv2): Parse RSDP v2 Descriptor\n");
loglinef(Verbose, "(parse_RSDTv2): - Descriptor physical address: 0x%x", ALIGN_PHYSADDRESS(descriptor->XsdtAddress));
map_phys_to_virt_addr((void *) ALIGN_PHYSADDRESS(descriptor->XsdtAddress), (void *) ensure_address_in_higher_half(descriptor->XsdtAddress), VMM_FLAGS_PRESENT | VMM_FLAGS_WRITE_ENABLE);
map_phys_to_virt_addr((void *) ALIGN_PHYSADDRESS(descriptor->XsdtAddress), (void *) ensure_address_in_higher_half(descriptor->XsdtAddress), VMM_FLAGS_PRESENT | VMM_FLAGS_WRITE_ENABLE, NULL);
_bitmap_set_bit_from_address(ALIGN_PHYSADDRESS(descriptor->XsdtAddress));
xsdt_root = (XSDT *) ensure_address_in_higher_half((uint64_t) descriptor->XsdtAddress);
loglinef(Verbose, "(parse_RSDTv2): - XSDT_Length: 0x%x", descriptor->Length);
Expand All @@ -75,16 +76,16 @@ void parse_RSDTv2(RSDPDescriptor20 *descriptor){
if (required_extra_pages > 1) {
for (size_t j = 1; j < required_extra_pages; j++) {
uint64_t new_physical_address = descriptor->XsdtAddress + (j * KERNEL_PAGE_SIZE);
map_phys_to_virt_addr((uint64_t *) new_physical_address, (uint64_t *) ensure_address_in_higher_half(new_physical_address), VMM_FLAGS_PRESENT | VMM_FLAGS_WRITE_ENABLE);
map_phys_to_virt_addr((uint64_t *) new_physical_address, (uint64_t *) ensure_address_in_higher_half(new_physical_address), VMM_FLAGS_PRESENT | VMM_FLAGS_WRITE_ENABLE, NULL);
_bitmap_set_bit_from_address(ALIGN_PHYSADDRESS(new_physical_address));
}
}

rsdtTablesTotal = (header.Length - sizeof(ACPISDTHeader)) / sizeof(uint64_t);
loglinef(Verbose, "(parse_RSDTv2): - Total xsdt Tables: %d", rsdtTablesTotal);

for(uint32_t i=0; i < rsdtTablesTotal; i++) {
map_phys_to_virt_addr((uint64_t *) ALIGN_PHYSADDRESS(xsdt_root->tables[i]), (uint64_t *) ensure_address_in_higher_half(xsdt_root->tables[i]), VMM_FLAGS_PRESENT | VMM_FLAGS_WRITE_ENABLE);
map_phys_to_virt_addr((uint64_t *) ALIGN_PHYSADDRESS(xsdt_root->tables[i]), (uint64_t *) ensure_address_in_higher_half(xsdt_root->tables[i]), VMM_FLAGS_PRESENT | VMM_FLAGS_WRITE_ENABLE, NULL);
_bitmap_set_bit_from_address(ALIGN_PHYSADDRESS(xsdt_root->tables[i]));
ACPISDTHeader *tableHeader = (ACPISDTHeader *) ensure_address_in_higher_half(xsdt_root->tables[i]);
loglinef(Verbose, "(parse_RSDTv2): \tTable header %d: Signature: %.4s", i, tableHeader->Signature);
Expand All @@ -96,7 +97,7 @@ void parse_RSDTv2(RSDPDescriptor20 *descriptor){
ACPISDTHeader* get_SDT_item(char* table_name) {
if((sdt_version == RSDT_V1 && rsdt_root == NULL) || (sdt_version == RSDT_V2 && xsdt_root == NULL)) {
return NULL;
}
}
for(uint32_t i=0; i < rsdtTablesTotal; i++){
ACPISDTHeader *tableItem;
switch(sdt_version) {
Expand All @@ -120,7 +121,7 @@ ACPISDTHeader* get_SDT_item(char* table_name) {
}

/*! \brief It validate the RSDP (v1 and v2) checksum
*
*
* Given the descriptor as a byte array, it sums each byte, and if the last byte of the sum is 0 this means that the structure is valid.
* @param decriptor the RSDPv1/v2 descriptor
* @param the size of the struct used by descriptor (should be the size of: RSDPDescriptor or RSDPDescriptorv2)
Expand Down
13 changes: 7 additions & 6 deletions src/kernel/arch/x86_64/cpu/ioapic.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <stdio.h>
#include <stddef.h>
#include <vmm.h>
#include <vmm_mapping.h>
#include <vm.h>
#include <logging.h>

Expand All @@ -20,16 +21,16 @@ void init_ioapic(MADT *madt_table){
loglinef(Verbose, "(init_ioapic): IOAPIC Item address: 0x%x - length: 0x%x", item, item->length);
IO_APIC_Item *ioapic_item = (IO_APIC_Item *) ( ensure_address_in_higher_half((uint64_t) item + sizeof(MADT_Item)));
if (is_phyisical_address_mapped(ALIGN_PHYSADDRESS((uint64_t) item), ensure_address_in_higher_half((uint64_t) item)) == PHYS_ADDRESS_NOT_MAPPED) {
map_phys_to_virt_addr((void *) ALIGN_PHYSADDRESS((uint64_t) item), (void *)ensure_address_in_higher_half((uint64_t) item),VMM_FLAGS_PRESENT | VMM_FLAGS_WRITE_ENABLE);
map_phys_to_virt_addr((void *) ALIGN_PHYSADDRESS((uint64_t) item), (void *)ensure_address_in_higher_half((uint64_t) item),VMM_FLAGS_PRESENT | VMM_FLAGS_WRITE_ENABLE, NULL);
}
loglinef(Verbose, "(init_ioapic): IOAPIC_ID: 0x%x, Address: 0x%x", ioapic_item->ioapic_id, ioapic_item->address );
loglinef(Verbose, "(init_ioapic): IOAPIC_ID: 0x%x, Address: 0x%x", ioapic_item->ioapic_id, ioapic_item->address );
loglinef(Verbose, "(init_ioapic): IOApic_Global_System_Interrupt_Base: 0x%x", ioapic_item->global_system_interrupt_base);
loglinef(Verbose, "(init_ioapic): IOApic Higher Half Address: 0x%x", ensure_address_in_higher_half(ioapic_item->address));
io_apic_base_address = ioapic_item->address;
io_apic_hh_base_address = ensure_address_in_higher_half(ioapic_item->address);
// This one should be mapped in the higher half ??
// This one should be mapped in the higher half ??
//map_phys_to_virt_addr(VPTR(io_apic_base_address), VPTR(io_apic_base_address), 0);
map_phys_to_virt_addr(VPTR(io_apic_base_address), (void *) io_apic_hh_base_address, VMM_FLAGS_PRESENT | VMM_FLAGS_WRITE_ENABLE);
map_phys_to_virt_addr(VPTR(io_apic_base_address), (void *) io_apic_hh_base_address, VMM_FLAGS_PRESENT | VMM_FLAGS_WRITE_ENABLE, NULL);
_bitmap_set_bit(ADDRESS_TO_BITMAP_ENTRY(io_apic_base_address));
uint32_t ioapic_version = read_io_apic_register(IO_APIC_VER_OFFSET);
loglinef(Info, "(init_ioapic): IOAPIC Version: 0x%x", ioapic_version);
Expand Down Expand Up @@ -122,7 +123,7 @@ void set_irq(uint8_t irq_type, uint8_t redirect_table_pos, uint8_t idt_entry, ui
// 1. Check if irq_type is in the Source overrides
uint8_t counter = 0;
uint8_t selected_pin = irq_type;
io_apic_redirect_entry_t entry;
io_apic_redirect_entry_t entry;
entry.raw = flags | (idt_entry & 0xFF);
while(counter < io_apic_source_override_array_size) {
// 2. If yes we need to use the gsi in the source override entry
Expand All @@ -148,7 +149,7 @@ void set_irq(uint8_t irq_type, uint8_t redirect_table_pos, uint8_t idt_entry, ui
entry.interrupt_mask = masked;
loglinef(Info, "(set_irq): Setting IRQ number: %x, to idt_entry: %x at REDTBL pos: %x - Final value: %x", irq_type, idt_entry, redirect_table_pos, entry.raw);
write_io_apic_redirect(redirect_table_pos, entry);
io_apic_redirect_entry_t read_entry;
io_apic_redirect_entry_t read_entry;
int ret_val = read_io_apic_redirect(IOREDTBL1, &read_entry);
loglinef(Verbose, "(set_irq): ret_val: %d - entry raw: %x mask: %d", ret_val, read_entry.vector, read_entry.interrupt_mask);
}
Expand Down
19 changes: 10 additions & 9 deletions src/kernel/arch/x86_64/cpu/lapic.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@
#include <cpuid.h>
#include <io.h>
#include <vmm.h>
#include <kernel.h>
#include <vmm_mapping.h>
#include <vm.h>
#include <kernel.h>
#include <logging.h>

//cpuid is non-standard header, but is supported by both gcc/clang.
Expand All @@ -38,7 +39,7 @@ void init_apic() {
uint32_t x2ApicLeaf = 0;
__get_cpuid(1, &ignored, &ignored, &x2ApicLeaf, &xApicLeaf);
(void)ignored;

if (x2ApicLeaf & (1 << 21)) {
logline(Info, "(init_apic): X2APIC available!");
apicInX2Mode = true;
Expand All @@ -54,7 +55,7 @@ void init_apic() {
kernel_settings.use_x2_apic = false;

//registers are accessed via mmio, make sure they're identity mapped
map_phys_to_virt_addr(VPTR(apic_base_address), VPTR(apic_hh_base_address), VMM_FLAGS_PRESENT | VMM_FLAGS_WRITE_ENABLE);
map_phys_to_virt_addr(VPTR(apic_base_address), VPTR(apic_hh_base_address), VMM_FLAGS_PRESENT | VMM_FLAGS_WRITE_ENABLE, NULL);
}
else {
kernel_settings.use_x2_apic = false;
Expand All @@ -65,15 +66,15 @@ void init_apic() {

uint32_t spurious_interrupt_register = read_apic_register(APIC_SPURIOUS_VECTOR_REGISTER_OFFSET);
loglinef(Verbose, "(init_apic): Apic enabled: %x - Apic BSP bit: %x", 1&(msr_output >> APIC_GLOBAL_ENABLE_BIT), 1&(msr_output >> APIC_BSP_BIT));

if(!(1&(msr_output >> APIC_GLOBAL_ENABLE_BIT))) {
logline(Info, "(init_apic): Apic disabled globally");
return;
}

//Enabling apic
write_apic_register(APIC_SPURIOUS_VECTOR_REGISTER_OFFSET, APIC_SOFTWARE_ENABLE | APIC_SPURIOUS_INTERRUPT);

if(apic_base_address < memory_size_in_bytes) {
//I think that ideally it should be relocated above the physical memory (that should be possible)
//but for now i'll mark that location as used
Expand All @@ -94,7 +95,7 @@ void disable_pic() {
//ICW_2 tells the PIC where the IRQ should be placed in the IDT (but we are not going to use them
outportb(PIC_DATA_MASTER, ICW_2_M);
outportb(PIC_DATA_SLAVE, ICW_2_S);
//ICW_3 Indicates if there is a slave connected (when is the master pic) or the slave id
//ICW_3 Indicates if there is a slave connected (when is the master pic) or the slave id
outportb(PIC_DATA_MASTER, ICW_3_M);
outportb(PIC_DATA_SLAVE, ICW_3_S);
//Set the modes of operation (we are just oging to set the 8086 mode bit.
Expand Down Expand Up @@ -126,6 +127,6 @@ uint32_t lapic_id()
}

bool lapic_is_x2()
{
return apicInX2Mode;
{
return apicInX2Mode;
}
7 changes: 4 additions & 3 deletions src/kernel/arch/x86_64/cpu/madt.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <vm.h>
#include <bitmap.h>
#include <vmm.h>
#include <vmm_mapping.h>
#include <logging.h>

bool is_madt_mapped;
Expand All @@ -16,9 +17,9 @@ void map_madt(MADT* table){
// Table is not MADT
return;
}

uint64_t madt_address = ((uint64_t) table + sizeof(MADT));
map_phys_to_virt_addr((void *) ALIGN_PHYSADDRESS(madt_address), (void *) ensure_address_in_higher_half(madt_address), VMM_FLAGS_PRESENT | VMM_FLAGS_WRITE_ENABLE);
map_phys_to_virt_addr((void *) ALIGN_PHYSADDRESS(madt_address), (void *) ensure_address_in_higher_half(madt_address), VMM_FLAGS_PRESENT | VMM_FLAGS_WRITE_ENABLE, NULL);
_bitmap_set_bit_from_address(ALIGN_PHYSADDRESS(madt_address));
loglinef(Verbose, "(map_madt): Sizeof MADT struct: 0x%x", sizeof(MADT));
madt_base = (MADT_Item *) ensure_address_in_higher_half((uint64_t)madt_address);
Expand All @@ -44,7 +45,7 @@ MADT_Item* get_MADT_item(MADT* table, uint8_t type, uint8_t offset) {
}
counter++;
}
total_length = total_length + item->length;
total_length = total_length + item->length;
item = (MADT_Item *)((uint64_t)madt_base + (uint64_t) total_length);
}
return NULL;
Expand Down
Loading

0 comments on commit df48ecf

Please sign in to comment.