x86_64: fix L2 RAM mapping issue + incorrect CR3 write
This commit is contained in:
parent
76f1872764
commit
46854c0f81
@ -230,6 +230,9 @@ fn enable_features(ecx: EcxFeatures, edx: EdxFeatures) {
|
||||
if ecx.contains(EcxFeatures::PCID) {
|
||||
CR4.modify(CR4::PCIDE::SET);
|
||||
}
|
||||
if edx.contains(EdxFeatures::PSE) {
|
||||
CR4.modify(CR4::PSE::SET);
|
||||
}
|
||||
|
||||
CR0.modify(CR0::TS::CLEAR);
|
||||
}
|
||||
|
@ -146,7 +146,7 @@ mod cr2 {
|
||||
}
|
||||
|
||||
mod cr3 {
|
||||
use tock_registers::{interfaces::ReadWriteable, register_bitfields};
|
||||
use tock_registers::{interfaces::Writeable, register_bitfields};
|
||||
|
||||
register_bitfields! {
|
||||
usize,
|
||||
@ -164,7 +164,7 @@ mod cr3 {
|
||||
impl Reg {
|
||||
pub fn set_address(&self, address: usize) {
|
||||
assert_eq!(address & 0xFFF, 0);
|
||||
self.modify(CR3::ADDR.val(address >> 12))
|
||||
self.write(CR3::ADDR.val(address >> 12))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
use core::{
|
||||
alloc::Layout,
|
||||
ops::{Deref, DerefMut},
|
||||
ptr::addr_of,
|
||||
sync::atomic::{AtomicUsize, Ordering},
|
||||
};
|
||||
|
||||
@ -128,6 +127,7 @@ unsafe fn map_early_pages(physical: PhysicalAddress, count: usize) -> Result<usi
|
||||
// TODO NX, NC
|
||||
EARLY_MAPPING_L3[i + l3i] =
|
||||
PageEntry::page(physical.add(i * L3::SIZE), PageAttributes::WRITABLE);
|
||||
flush_tlb_entry(EARLY_MAPPING_OFFSET + (i + l3i) * L3::SIZE);
|
||||
}
|
||||
|
||||
return Ok(EARLY_MAPPING_OFFSET + l3i * L3::SIZE);
|
||||
@ -336,6 +336,15 @@ pub fn clone_kernel_tables(dst: &mut PageTable<L0>) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn auto_address<T>(pointer: *const T) -> usize {
|
||||
let address = pointer.addr();
|
||||
if address < KERNEL_VIRT_OFFSET {
|
||||
address
|
||||
} else {
|
||||
address - KERNEL_VIRT_OFFSET
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets up the following memory map:
|
||||
/// ...: KERNEL_TABLES.l0:
|
||||
/// * 0xFFFFFF0000000000 .. 0xFFFFFFFF8000000000 : RAM_MAPPING_L1
|
||||
@ -354,15 +363,15 @@ pub fn clone_kernel_tables(dst: &mut PageTable<L0>) {
|
||||
/// Unsafe, must only be called by BSP during its early init, must already be in "higher-half"
|
||||
pub unsafe fn init_fixed_tables() {
|
||||
let mut tables = KERNEL_TABLES.lock();
|
||||
|
||||
// TODO this could be built in compile-time too?
|
||||
let early_mapping_l3_phys = addr_of!(EARLY_MAPPING_L3) as usize - KERNEL_VIRT_OFFSET;
|
||||
let device_mapping_l2_phys = addr_of!(DEVICE_MAPPING_L2) as usize - KERNEL_VIRT_OFFSET;
|
||||
let ram_mapping_l1_phys = addr_of!(RAM_MAPPING_L1) as usize - KERNEL_VIRT_OFFSET;
|
||||
let early_mapping_l3_phys = auto_address(&raw const EARLY_MAPPING_L3);
|
||||
let device_mapping_l2_phys = auto_address(&raw const DEVICE_MAPPING_L2);
|
||||
let ram_mapping_l1_phys = auto_address(&raw const RAM_MAPPING_L1);
|
||||
|
||||
for i in 0..DEVICE_MAPPING_L3_COUNT {
|
||||
let device_mapping_l3_phys = PhysicalAddress::from_usize(
|
||||
&DEVICE_MAPPING_L3S[i] as *const _ as usize - KERNEL_VIRT_OFFSET,
|
||||
);
|
||||
let device_mapping_l3_phys =
|
||||
PhysicalAddress::from_usize(auto_address(&raw const DEVICE_MAPPING_L3S[i]));
|
||||
DEVICE_MAPPING_L2[i] = PageEntry::table(device_mapping_l3_phys, PageAttributes::WRITABLE);
|
||||
}
|
||||
|
||||
@ -379,7 +388,7 @@ pub unsafe fn init_fixed_tables() {
|
||||
(ram_mapping_l1_phys as u64) | (PageAttributes::WRITABLE | PageAttributes::PRESENT).bits();
|
||||
|
||||
// TODO ENABLE EFER.NXE
|
||||
let cr3 = (&raw const tables.l0).addr() - KERNEL_VIRT_OFFSET;
|
||||
let cr3 = auto_address(&raw const tables.l0);
|
||||
CR3.set_address(cr3);
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,6 @@ use libk::vfs::Metadata;
|
||||
use yggdrasil_abi::{
|
||||
bitflags,
|
||||
io::{FileMode, FileType, GroupId, UserId},
|
||||
time::SystemTime,
|
||||
};
|
||||
|
||||
use crate::Ext2Fs;
|
||||
|
@ -10,7 +10,7 @@ use alloc::{
|
||||
use libk_util::sync::IrqSafeSpinlock;
|
||||
use yggdrasil_abi::{
|
||||
error::Error,
|
||||
io::{FileMode, FileType, GroupId, OpenOptions, UserId},
|
||||
io::{FileMode, FileType, OpenOptions},
|
||||
};
|
||||
|
||||
use crate::vfs::{DirectoryOpenPosition, InstanceData};
|
||||
|
@ -15,7 +15,6 @@ use yggdrasil_abi::{
|
||||
bitflags,
|
||||
error::Error,
|
||||
io::{FileMode, FileType, GroupId, UserId},
|
||||
time::SystemTime,
|
||||
};
|
||||
|
||||
mod access;
|
||||
|
@ -13,9 +13,9 @@ use kernel_arch_x86::{
|
||||
};
|
||||
use kernel_arch_x86_64::{
|
||||
mem::{
|
||||
init_fixed_tables,
|
||||
flush_tlb_entry, init_fixed_tables,
|
||||
table::{PageAttributes, PageEntry, PageTable, L1, L2, L3},
|
||||
EarlyMapping, MEMORY_LIMIT, RAM_MAPPING_L1,
|
||||
EarlyMapping, MEMORY_LIMIT, RAM_MAPPING_L1, RAM_MAPPING_OFFSET,
|
||||
},
|
||||
PerCpuData,
|
||||
};
|
||||
@ -203,9 +203,11 @@ impl X86_64 {
|
||||
RAM_MAPPING_L1[l1i] = PageEntry::<L1>::table(l2_phys_addr, PageAttributes::WRITABLE)
|
||||
};
|
||||
|
||||
unsafe { flush_tlb_entry(RAM_MAPPING_OFFSET + (l1i << L1::SHIFT)) };
|
||||
intrinsics::flush_cpu_cache();
|
||||
// The EarlyMapping is then dropped
|
||||
}
|
||||
|
||||
// }
|
||||
|
||||
Ok(())
|
||||
@ -246,13 +248,15 @@ impl X86_64 {
|
||||
}
|
||||
|
||||
unsafe fn init_platform(&'static self, cpu_id: usize) -> Result<(), Error> {
|
||||
let (available_features, enabled_features) = self.init_cpu_features();
|
||||
|
||||
if cpu_id == 0 {
|
||||
PLATFORM
|
||||
.init_memory_management()
|
||||
.expect("Could not initialize memory management");
|
||||
}
|
||||
|
||||
self.init_local_cpu(cpu_id);
|
||||
self.init_local_cpu(cpu_id, available_features, enabled_features);
|
||||
|
||||
if cpu_id == 0 {
|
||||
x86::register_pci_drivers();
|
||||
@ -293,11 +297,7 @@ impl X86_64 {
|
||||
Ok(timer)
|
||||
}
|
||||
|
||||
unsafe fn init_local_cpu(&self, cpu_id: usize) {
|
||||
let local_apic = Box::new(LocalApic::new());
|
||||
let tss_address = gdt::init();
|
||||
exception::init_exceptions(cpu_id);
|
||||
|
||||
unsafe fn init_cpu_features(&self) -> (CpuFeatures, CpuFeatures) {
|
||||
let (have_features, will_features) = cpuid::setup_features(
|
||||
CpuFeatures {
|
||||
ecx: EcxFeatures::SSE3
|
||||
@ -317,13 +317,26 @@ impl X86_64 {
|
||||
);
|
||||
let will_features = will_features.expect("Could not initialize CPU features");
|
||||
|
||||
(have_features, will_features)
|
||||
}
|
||||
|
||||
unsafe fn init_local_cpu(
|
||||
&self,
|
||||
cpu_id: usize,
|
||||
available_features: CpuFeatures,
|
||||
enabled_features: CpuFeatures,
|
||||
) {
|
||||
let local_apic = Box::new(LocalApic::new());
|
||||
let tss_address = gdt::init();
|
||||
exception::init_exceptions(cpu_id);
|
||||
|
||||
let cpu_data = PerCpuData {
|
||||
this: null_mut(),
|
||||
tss_address,
|
||||
tmp_address: 0,
|
||||
local_apic,
|
||||
available_features: have_features,
|
||||
enabled_features: will_features,
|
||||
available_features,
|
||||
enabled_features,
|
||||
};
|
||||
|
||||
Cpu::init_local(Some(cpu_id as _), cpu_data);
|
||||
|
Loading…
x
Reference in New Issue
Block a user