Move switching stuff to the scheduler

This commit is contained in:
Baptiste Wicht 2014-01-26 19:27:38 +01:00
parent 342d40c6f4
commit 5f88766c83
4 changed files with 54 additions and 16 deletions

View File

@ -25,6 +25,9 @@ struct process_t {
bool system;
uint16_t code_selector;
uint16_t data_selector;
size_t physical_cr3;
size_t paging_size;

View File

@ -8,6 +8,8 @@
#ifndef SCHEDULER_H
#define SCHEDULER_H
#include "process.hpp"
namespace scheduler {
void init();
@ -17,6 +19,9 @@ void kill_current_process();
void reschedule();
process_t new_process();
void queue_process(process_t&& p);
} //end of namespace scheduler
#endif

View File

@ -6,9 +6,9 @@
//=======================================================================
#include "scheduler.hpp"
#include "process.hpp"
#include "paging.hpp"
#include "assert.hpp"
#include "gdt.hpp"
#include "console.hpp"
@ -46,6 +46,9 @@ void create_idle_task(){
idle_process.user_rsp = reinterpret_cast<size_t>(&idle_stack[63]);
idle_process.kernel_rsp = reinterpret_cast<size_t>(&idle_kernel_stack[4095]);
idle_process.code_selector = gdt::LONG_SELECTOR;
idle_process.data_selector = gdt::DATA_SELECTOR;
processes.push_back(std::move(idle_process));
rounds.push_back(0);
}
@ -55,7 +58,24 @@ void switch_to_process(size_t index){
k_printf("Switched to %u\n", index);
//TODO
//TODO Move that to scheduler
auto& process = processes[current_index];
gdt::tss.rsp0_low = process.kernel_rsp & 0xFFFFFFFF;
gdt::tss.rsp0_high = process.kernel_rsp >> 32;
asm volatile("mov ax, %0; mov ds, ax; mov es, ax; mov fs, ax; mov gs, ax;"
: //No outputs
: "r" (process.data_selector)
: "rax");
asm volatile("mov cr3, %0" : : "r" (process.physical_cr3) : "memory");
//TODO Check if user_rsp is correctly passed
asm volatile("xor rax, rax; mov ax, %0; push rax; mov rax, %1; push rax; pushfq; xor rax, rax; mov ax, %2; push rax; mov rax, %3; push rax; iretq"
: //No outputs
: "r" (process.data_selector), "r" (process.user_rsp), "r" (process.code_selector), "r" (process.rip)
: "rax");
}
size_t select_next_process(){
@ -89,6 +109,8 @@ void scheduler::kill_current_process(){
}
void scheduler::reschedule(){
k_print_line("RS");
//Test if the current process just got killed
if(current_index == processes.size()){
current_index = 0;
@ -108,3 +130,17 @@ void scheduler::reschedule(){
//At this point we just have to return to the current process
}
scheduler::process_t scheduler::new_process(){
process_t p;
p.system = false;
p.pid = next_pid++;
return std::move(p);
}
void scheduler::queue_process(process_t&& p){
processes.push_back(std::forward<scheduler::process_t>(p));
rounds.push_back(0);
}

View File

@ -880,30 +880,24 @@ void exec_command(const std::vector<std::string>& params){
auto buffer = content->c_str();
auto header = reinterpret_cast<elf::elf_header*>(buffer);
scheduler::process_t process;
auto process = scheduler::new_process();
if(!create_paging(buffer, process)){
k_print_line("Impossible to initialize paging");
return;
}
gdt::tss.rsp0_low = scheduler::kernel_rsp & 0xFFFFFFFF;
gdt::tss.rsp0_high = scheduler::kernel_rsp >> 32;
process.kernel_rsp = scheduler::kernel_rsp;
process.user_rsp = scheduler::user_rsp;
asm volatile("mov ax, %0; mov ds, ax; mov es, ax; mov fs, ax; mov gs, ax;"
: //No outputs
: "i" (gdt::USER_DATA_SELECTOR + 3)
: "rax");
process.rip = header->e_entry;
asm volatile("mov cr3, %0" : : "r" (process.physical_cr3) : "memory");
process.code_selector = gdt::USER_CODE_SELECTOR + 3;
process.data_selector = gdt::USER_DATA_SELECTOR + 3;
//TODO Check if user_rsp is correctly passed
asm volatile("push %0; push %1; pushfq; push %2; push %3; iretq"
: //No outputs
: "i" (gdt::USER_DATA_SELECTOR + 3), "r" (scheduler::user_rsp), "i" (gdt::USER_CODE_SELECTOR + 3), "r" (header->e_entry)
: "rax");
scheduler::queue_process(std::move(process));
//TODO Release all physical memory
scheduler::start();
}
void vesainfo_command(const std::vector<std::string>&){