Initial work on swapping page tables per process

This commit is contained in:
Justin C. Miller
2018-08-27 09:09:56 -07:00
parent 1664566bd2
commit 647801f096
4 changed files with 97 additions and 46 deletions

View File

@@ -4,18 +4,13 @@
#include "gdt.h"
#include "interrupts.h"
#include "log.h"
#include "page_manager.h"
#include "scheduler.h"
scheduler scheduler::s_instance(nullptr);
static const uint32_t quantum = 5000000;
static const uint32_t quantum = 2000000;
const int stack_size = 0x1000;
char taskAstack0[stack_size];
char taskAstack3[stack_size];
char taskBstack0[stack_size];
char taskBstack3[stack_size];
uint64_t taskAcount = 0;
extern "C" void taskA();
extern "C" void taskB();
@@ -29,19 +24,18 @@ scheduler::scheduler(lapic *apic) :
}
static process
create_process(uint16_t pid, void *stack0, void *stack3, void (*rip)())
create_process(uint16_t pid, void (*rip)())
{
uint64_t flags;
__asm__ __volatile__ ( "pushf; pop %0" : "=r" (flags) );
// This is a hack for now, until we get a lot more set up.
// I just want to see task switching working inside ring0 first
uint16_t kcs = (1 << 3) | 0;
uint16_t cs = (5 << 3) | 3;
uint16_t kcs = (1 << 3) | 0; // Kernel CS is GDT entry 1, ring 0
uint16_t cs = (5 << 3) | 3; // User CS is GDT entry 5, ring 3
uint16_t kss = (2 << 3) | 0;
uint16_t ss = (4 << 3) | 3;
uint16_t kss = (2 << 3) | 0; // Kernel SS is GDT entry 2, ring 0
uint16_t ss = (4 << 3) | 3; // User SS is GDT entry 4, ring 3
void *stack0 = kutil::malloc(stack_size);
void *sp0 = kutil::offset_pointer(stack0, stack_size);
cpu_state *state = reinterpret_cast<cpu_state *>(sp0) - 1;
kutil::memset(state, 0, sizeof(cpu_state));
@@ -51,14 +45,15 @@ create_process(uint16_t pid, void *stack0, void *stack3, void (*rip)())
state->rflags = 0x202; // testing. TODO: 0x202
state->rip = reinterpret_cast<uint64_t>(rip);
void *sp3 = kutil::offset_pointer(stack3, stack_size);
state->user_rsp = reinterpret_cast<uint64_t>(sp3);
page_table *pml4 = page_manager::get()->create_process_map();
state->user_rsp = page_manager::initial_stack;
log::debug(logs::task, "Creating PID %d:", pid);
log::debug(logs::task, " RSP0 %016lx", state);
log::debug(logs::task, " RSP3 %016lx", sp3);
log::debug(logs::task, " RSP3 %016lx", state->user_rsp);
log::debug(logs::task, " PML4 %016lx", pml4);
return {pid, reinterpret_cast<addr_t>(state)};
return {pid, reinterpret_cast<addr_t>(state), pml4};
}
void
@@ -68,9 +63,9 @@ scheduler::start()
m_apic->enable_timer(isr::isrTimer, 128, quantum, false);
m_processes.append({0, 0}); // The kernel idle task
m_processes.append(create_process(1, &taskAstack0[0], &taskAstack3[0], &taskA));
m_processes.append(create_process(2, &taskBstack0[0], &taskBstack3[0], &taskB));
m_processes.append({0, 0, page_manager::get_pml4()}); // The kernel idle task, also the thread we're in now
m_processes.append(create_process(1, &taskA));
m_processes.append(create_process(2, &taskB));
}
addr_t
@@ -85,6 +80,10 @@ scheduler::tick(addr_t rsp0)
// Set rsp0 to after the end of the about-to-be-popped cpu state
tss_set_stack(0, rsp0 + sizeof(cpu_state));
// Swap page tables
page_table *pml4 = m_processes[m_current].pml4;
page_manager::set_pml4(pml4);
m_apic->reset_timer(quantum);
return rsp0;
}