This commit is contained in:
parent
a6a88e7f3b
commit
6aa70f2012
6 changed files with 25 additions and 7 deletions
|
@ -23,9 +23,9 @@ extern "C" fn ap_main() -> ! {
|
||||||
setup_gdt();
|
setup_gdt();
|
||||||
setup_idt();
|
setup_idt();
|
||||||
setup_lapic(0);
|
setup_lapic(0);
|
||||||
|
set_cpu_flags();
|
||||||
// TODO: Also calibrate other cores
|
// TODO: Also calibrate other cores
|
||||||
setup_lapic_timer(false);
|
setup_lapic_timer(false);
|
||||||
set_cpu_flags();
|
|
||||||
unsafe {
|
unsafe {
|
||||||
sti();
|
sti();
|
||||||
}
|
}
|
||||||
|
@ -37,8 +37,10 @@ pub fn set_cpu_flags() {
|
||||||
let features = cpuid.get_feature_info().unwrap();
|
let features = cpuid.get_feature_info().unwrap();
|
||||||
let extended_features = cpuid.get_extended_feature_info().unwrap();
|
let extended_features = cpuid.get_extended_feature_info().unwrap();
|
||||||
unsafe {
|
unsafe {
|
||||||
// Time Stamp Disable, SMEP and SMAP
|
// Numeric Error
|
||||||
asm!("mov rax, cr4; bts rax, 2; bts rax, 20; bts rax, 21; mov cr4, rax", out("rax") _);
|
asm!("mov rax, cr0; bts rax, 5; mov cr0, rax", out("rax") _);
|
||||||
|
// Time Stamp Disable, OSFXSR, OSXMMEXCPT, SMEP and SMAP
|
||||||
|
asm!("mov rax, cr4; bts rax, 2; bts rax, 9; bts rax, 10; bts rax, 20; bts rax, 21; mov cr4, rax", out("rax") _);
|
||||||
if features.has_mce() {
|
if features.has_mce() {
|
||||||
asm!("mov rax, cr4; bts rax, 6; mov cr4, rax", out("rax") _);
|
asm!("mov rax, cr4; bts rax, 6; mov cr4, rax", out("rax") _);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,4 +30,5 @@ jump_usermode:
|
||||||
xor %r13, %r13
|
xor %r13, %r13
|
||||||
xor %r14, %r14
|
xor %r14, %r14
|
||||||
xor %r15, %r15
|
xor %r15, %r15
|
||||||
|
fninit
|
||||||
iretq
|
iretq
|
||||||
|
|
|
@ -95,12 +95,12 @@ extern "C" fn early_main(temp_loader_struct: *const LoaderStruct) -> ! {
|
||||||
}
|
}
|
||||||
parse_madt(&early_acpi_tables);
|
parse_madt(&early_acpi_tables);
|
||||||
setup_hpet(&early_acpi_tables);
|
setup_hpet(&early_acpi_tables);
|
||||||
|
set_cpu_flags();
|
||||||
setup_lapic_timer(true);
|
setup_lapic_timer(true);
|
||||||
setup_multitasking();
|
setup_multitasking();
|
||||||
}
|
}
|
||||||
fn main() {
|
fn main() {
|
||||||
info!("Starting main kernel task...");
|
info!("Starting main kernel task...");
|
||||||
set_cpu_flags();
|
|
||||||
let mut status = unsafe { AcpiInitializeSubsystem() };
|
let mut status = unsafe { AcpiInitializeSubsystem() };
|
||||||
assert_eq!(status, AE_OK);
|
assert_eq!(status, AE_OK);
|
||||||
status = unsafe { AcpiInitializeTables(null_mut(), 0, 0) };
|
status = unsafe { AcpiInitializeTables(null_mut(), 0, 0) };
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
use core::sync::atomic::{AtomicBool, AtomicI64, AtomicU64, AtomicUsize, Ordering};
|
use core::{
|
||||||
|
arch::x86_64::{_fxrstor64, _fxsave64},
|
||||||
|
sync::atomic::{AtomicBool, AtomicI64, AtomicU64, AtomicUsize, Ordering},
|
||||||
|
};
|
||||||
|
|
||||||
use alloc::{sync::Arc, vec, vec::Vec};
|
use alloc::{boxed::Box, sync::Arc, vec, vec::Vec};
|
||||||
use kernel_common::instructions::{cli, get_rflags, hlt, pause, sti};
|
use kernel_common::instructions::{cli, get_rflags, hlt, pause, sti};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -30,6 +33,9 @@ pub enum TaskState {
|
||||||
SemaphoreBlocked,
|
SemaphoreBlocked,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(align(16))]
|
||||||
|
struct FXSaveRegion([u8; 512]);
|
||||||
|
|
||||||
pub struct Task {
|
pub struct Task {
|
||||||
pub id: usize,
|
pub id: usize,
|
||||||
pub process: Arc<Spinlock<Process>>,
|
pub process: Arc<Spinlock<Process>>,
|
||||||
|
@ -41,6 +47,7 @@ pub struct Task {
|
||||||
pub block_on_semaphore: Option<Arc<RawSemaphore>>,
|
pub block_on_semaphore: Option<Arc<RawSemaphore>>,
|
||||||
pub semaphore_requested_count: usize,
|
pub semaphore_requested_count: usize,
|
||||||
user_stack: u64,
|
user_stack: u64,
|
||||||
|
fxsave_region: Box<FXSaveRegion>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
@ -69,6 +76,9 @@ pub fn switch_task(current_state: &mut ISRState, new_task: Task) {
|
||||||
if let Some(mut current_task) = current_tasks[lapic_id].take() {
|
if let Some(mut current_task) = current_tasks[lapic_id].take() {
|
||||||
current_task.state = *current_state;
|
current_task.state = *current_state;
|
||||||
current_task.user_stack = cpu_data.user_stack;
|
current_task.user_stack = cpu_data.user_stack;
|
||||||
|
unsafe {
|
||||||
|
_fxsave64(current_task.fxsave_region.0.as_mut_ptr());
|
||||||
|
}
|
||||||
if current_task.task_state == TaskState::Terminated {
|
if current_task.task_state == TaskState::Terminated {
|
||||||
unsafe {
|
unsafe {
|
||||||
get_kernel_process().lock().address_space.switch();
|
get_kernel_process().lock().address_space.switch();
|
||||||
|
@ -95,6 +105,9 @@ pub fn switch_task(current_state: &mut ISRState, new_task: Task) {
|
||||||
let kernel_stack = new_task.kernel_stack.as_ptr() as u64 + STACK_SIZE as u64;
|
let kernel_stack = new_task.kernel_stack.as_ptr() as u64 + STACK_SIZE as u64;
|
||||||
cpu_data.kernel_stack = kernel_stack;
|
cpu_data.kernel_stack = kernel_stack;
|
||||||
cpu_data.user_stack = new_task.user_stack;
|
cpu_data.user_stack = new_task.user_stack;
|
||||||
|
unsafe {
|
||||||
|
_fxrstor64(new_task.fxsave_region.0.as_ptr());
|
||||||
|
}
|
||||||
current_tasks[get_current_lapic_id()] = Some(new_task);
|
current_tasks[get_current_lapic_id()] = Some(new_task);
|
||||||
schedule_timer_interrupt();
|
schedule_timer_interrupt();
|
||||||
}
|
}
|
||||||
|
@ -135,6 +148,7 @@ pub fn create_task(process: Arc<Spinlock<Process>>, func: fn()) -> Task {
|
||||||
block_on_semaphore: None,
|
block_on_semaphore: None,
|
||||||
semaphore_requested_count: 0,
|
semaphore_requested_count: 0,
|
||||||
user_stack: 0,
|
user_stack: 0,
|
||||||
|
fxsave_region: Box::new(FXSaveRegion([0; 512])),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn create_idle_task() {
|
fn create_idle_task() {
|
||||||
|
|
|
@ -58,6 +58,7 @@ fn main() -> Status {
|
||||||
let extended_features = cpuid.get_extended_feature_info().unwrap();
|
let extended_features = cpuid.get_extended_feature_info().unwrap();
|
||||||
assert!(extended_features.has_smap());
|
assert!(extended_features.has_smap());
|
||||||
assert!(extended_features.has_smep());
|
assert!(extended_features.has_smep());
|
||||||
|
assert!(features.has_sse42());
|
||||||
assert!(cpuid.get_extended_processor_and_feature_identifiers().unwrap().has_syscall_sysret());
|
assert!(cpuid.get_extended_processor_and_feature_identifiers().unwrap().has_syscall_sysret());
|
||||||
let (kernel_start, kernel_entry) = load_kernel(KERNEL);
|
let (kernel_start, kernel_entry) = load_kernel(KERNEL);
|
||||||
let heap_start = allocate_pages(AllocateType::AnyPages, MemoryType::LOADER_DATA, KERNEL_HEAP_INITIAL_SIZE / 0x1000).unwrap().as_ptr() as u64;
|
let heap_start = allocate_pages(AllocateType::AnyPages, MemoryType::LOADER_DATA, KERNEL_HEAP_INITIAL_SIZE / 0x1000).unwrap().as_ptr() as u64;
|
||||||
|
|
2
qemu.sh
2
qemu.sh
|
@ -2,4 +2,4 @@
|
||||||
# shellcheck disable=SC2068
|
# shellcheck disable=SC2068
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
./build.py
|
./build.py
|
||||||
qemu-system-x86_64 -M q35 -accel kvm -cpu qemu64,rdrand,smap,smep,umip -smp 4 -m 256M -L /usr/share/OVMF -bios OVMF_CODE.fd -drive file=img/os.img,format=raw $@
|
qemu-system-x86_64 -M q35 -accel kvm -cpu host -smp 4 -m 256M -L /usr/share/OVMF -bios OVMF_CODE.fd -drive file=img/os.img,format=raw $@
|
||||||
|
|
Loading…
Add table
Reference in a new issue