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