refactor: put KERNEL_TABLES under a lock
This commit is contained in:
parent
a8a6192627
commit
98816e0ebc
32
Cargo.lock
generated
32
Cargo.lock
generated
@ -17,7 +17,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.87",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
@ -168,7 +168,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.87",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -179,7 +179,7 @@ checksum = "99e1aca718ea7b89985790c94aad72d77533063fe00bc497bb79a7c2dae6a661"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.87",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -266,7 +266,7 @@ checksum = "bcfcc3cd946cb52f0bbfdbbcfa2f4e24f75ebb6c0e1002f7c25904fada18b9ec"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.87",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -337,7 +337,7 @@ dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.87",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -405,7 +405,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.87",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -473,7 +473,7 @@ checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.87",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -686,7 +686,7 @@ checksum = "53010ccb100b96a67bc32c0175f0ed1426b31b655d562898e57325f81c023ac0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.87",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1266,7 +1266,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.87",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1522,7 +1522,7 @@ checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.87",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1586,9 +1586,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.85"
|
||||
version = "2.0.87"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56"
|
||||
checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -1642,7 +1642,7 @@ checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.87",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1834,7 +1834,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.87",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
@ -1856,7 +1856,7 @@ checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.87",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
@ -2309,5 +2309,5 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.87",
|
||||
]
|
||||
|
@ -9,12 +9,12 @@ use core::{
|
||||
use aarch64_cpu::registers::{TTBR0_EL1, TTBR1_EL1};
|
||||
use kernel_arch_interface::{
|
||||
mem::{DeviceMemoryAttributes, KernelTableManager, RawDeviceMemoryMapping},
|
||||
sync::split_spinlock,
|
||||
KERNEL_VIRT_OFFSET,
|
||||
};
|
||||
use libk_mm_interface::{
|
||||
address::PhysicalAddress,
|
||||
table::{page_index, EntryLevel, EntryLevelExt},
|
||||
KernelImageObject,
|
||||
};
|
||||
use memtables::aarch64::{FixedTables, KERNEL_L3_COUNT};
|
||||
use static_assertions::const_assert_eq;
|
||||
@ -66,9 +66,15 @@ static mut DEVICE_MAPPING_L3S: [PageTable<L3>; DEVICE_MAPPING_L3_COUNT] =
|
||||
pub const RAM_MAPPING_OFFSET: usize = MAPPING_OFFSET | (RAM_MAPPING_START_L1I * L1::SIZE);
|
||||
pub static MEMORY_LIMIT: AtomicUsize = AtomicUsize::new(0);
|
||||
|
||||
split_spinlock! {
|
||||
use crate::ArchitectureImpl;
|
||||
use crate::mem::FixedTables;
|
||||
use libk_mm_interface::KernelImageObject;
|
||||
|
||||
#[link_section = ".data.tables"]
|
||||
pub static mut KERNEL_TABLES: KernelImageObject<FixedTables> =
|
||||
static KERNEL_TABLES<lock: ArchitectureImpl>: KernelImageObject<FixedTables> =
|
||||
unsafe { KernelImageObject::new(FixedTables::zeroed()) };
|
||||
}
|
||||
|
||||
impl KernelTableManager for KernelTableManagerImpl {
|
||||
fn virtualize(address: u64) -> usize {
|
||||
@ -221,9 +227,10 @@ pub unsafe fn map_ram_l1(index: usize) {
|
||||
if index >= RAM_MAPPING_L1_COUNT {
|
||||
todo!()
|
||||
}
|
||||
assert_eq!(KERNEL_TABLES.l1.data[index + RAM_MAPPING_START_L1I], 0);
|
||||
let mut tables = KERNEL_TABLES.lock();
|
||||
assert_eq!(tables.l1.data[index + RAM_MAPPING_START_L1I], 0);
|
||||
|
||||
KERNEL_TABLES.l1.data[index + RAM_MAPPING_START_L1I] =
|
||||
tables.l1.data[index + RAM_MAPPING_START_L1I] =
|
||||
((index * L1::SIZE) as u64) | ram_block_flags().bits();
|
||||
}
|
||||
|
||||
@ -363,8 +370,7 @@ pub fn tlb_flush_vaae1(mut page: usize) {
|
||||
///
|
||||
/// Unsafe, must only be called by BSP during its early init while still in "lower-half"
|
||||
pub unsafe fn load_fixed_tables() {
|
||||
#[allow(static_mut_refs)]
|
||||
let ttbr0 = KERNEL_TABLES.l1.data.as_ptr() as u64;
|
||||
let ttbr0 = KERNEL_TABLES.lock().l1.data.as_ptr().addr() as u64;
|
||||
TTBR0_EL1.set(ttbr0);
|
||||
TTBR1_EL1.set(ttbr0);
|
||||
}
|
||||
@ -376,6 +382,7 @@ pub unsafe fn load_fixed_tables() {
|
||||
/// Unsafe, must only be called by BSP during its early init, must already be in "higher-half"
|
||||
pub unsafe fn init_fixed_tables() {
|
||||
// TODO this could be built in compile-time too?
|
||||
let mut tables = KERNEL_TABLES.lock();
|
||||
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;
|
||||
|
||||
@ -386,11 +393,11 @@ pub unsafe fn init_fixed_tables() {
|
||||
DEVICE_MAPPING_L2[i] = PageEntry::table(device_mapping_l3_phys, PageAttributes::empty());
|
||||
}
|
||||
|
||||
assert_eq!(KERNEL_TABLES.l2.data[EARLY_MAPPING_L2I], 0);
|
||||
KERNEL_TABLES.l2.data[EARLY_MAPPING_L2I] =
|
||||
assert_eq!(tables.l2.data[EARLY_MAPPING_L2I], 0);
|
||||
tables.l2.data[EARLY_MAPPING_L2I] =
|
||||
(early_mapping_l3_phys as u64) | kernel_table_flags().bits();
|
||||
|
||||
assert_eq!(KERNEL_TABLES.l1.data[DEVICE_MAPPING_L1I], 0);
|
||||
KERNEL_TABLES.l1.data[DEVICE_MAPPING_L1I] =
|
||||
assert_eq!(tables.l1.data[DEVICE_MAPPING_L1I], 0);
|
||||
tables.l1.data[DEVICE_MAPPING_L1I] =
|
||||
(device_mapping_l2_phys as u64) | kernel_table_flags().bits();
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ use yggdrasil_abi::{arch::SavedFrame, error::Error};
|
||||
|
||||
use crate::{
|
||||
gdt::{self, TSS},
|
||||
mem::kernel_tables,
|
||||
mem::KERNEL_TABLES,
|
||||
};
|
||||
|
||||
#[allow(unused)]
|
||||
@ -156,7 +156,8 @@ impl<K: KernelTableManager, PA: PhysicalMemoryAllocator<Address = PhysicalAddres
|
||||
|
||||
let sp = stack.build();
|
||||
let cr3 = unsafe {
|
||||
kernel_tables()
|
||||
KERNEL_TABLES
|
||||
.lock()
|
||||
.as_physical_address()
|
||||
.try_into_u32()
|
||||
.unwrap()
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(never_type, naked_functions)]
|
||||
#![feature(never_type, naked_functions, trace_macros)]
|
||||
#![no_std]
|
||||
|
||||
extern crate alloc;
|
||||
|
@ -8,8 +8,8 @@ use crate::{
|
||||
};
|
||||
|
||||
use super::{
|
||||
kernel_tables,
|
||||
table::{PageEntry, PageTable, L0, L3},
|
||||
KERNEL_TABLES,
|
||||
};
|
||||
|
||||
pub const KERNEL_SPLIT_L0: usize = KERNEL_VIRT_OFFSET >> 22;
|
||||
@ -130,7 +130,7 @@ impl KernelDynamic {
|
||||
}
|
||||
|
||||
pub fn clone_kernel_tables(dst: &mut PageTable<L0>) {
|
||||
let tables = kernel_tables();
|
||||
let tables = KERNEL_TABLES.lock();
|
||||
for (i, entry) in tables.l0.kernel.iter().enumerate() {
|
||||
dst[i + KERNEL_SPLIT_L0] = *entry;
|
||||
}
|
||||
|
@ -1,18 +1,12 @@
|
||||
use core::{
|
||||
cell::UnsafeCell,
|
||||
ops::{Deref, DerefMut},
|
||||
};
|
||||
|
||||
use fixed::FixedTables;
|
||||
use kernel_arch_interface::{
|
||||
mem::{DeviceMemoryAttributes, KernelTableManager, RawDeviceMemoryMapping},
|
||||
sync::{IrqSafeSpinlock, IrqSafeSpinlockGuard},
|
||||
sync::split_spinlock,
|
||||
KERNEL_VIRT_OFFSET,
|
||||
};
|
||||
use libk_mm_interface::{
|
||||
address::{AsPhysicalAddress, PhysicalAddress},
|
||||
table::{page_count, EntryLevel},
|
||||
KernelImageObject,
|
||||
};
|
||||
use table::{PageAttributes, PageEntry, L0, L3};
|
||||
use yggdrasil_abi::error::Error;
|
||||
@ -23,59 +17,18 @@ pub mod table;
|
||||
|
||||
pub use process::ProcessAddressSpaceImpl;
|
||||
|
||||
use crate::ArchitectureImpl;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct KernelTableManagerImpl;
|
||||
|
||||
split_spinlock! {
|
||||
use libk_mm_interface::KernelImageObject;
|
||||
use crate::mem::FixedTables;
|
||||
use crate::ArchitectureImpl;
|
||||
|
||||
#[link_section = ".data.tables"]
|
||||
pub static KERNEL_TABLES: KernelTablesInner = KernelTablesInner::new();
|
||||
static KERNEL_TABLES_LOCK: IrqSafeSpinlock<ArchitectureImpl, ()> = IrqSafeSpinlock::new(());
|
||||
|
||||
#[repr(C, align(0x1000))]
|
||||
pub struct KernelTablesInner {
|
||||
inner: UnsafeCell<KernelImageObject<FixedTables>>,
|
||||
}
|
||||
|
||||
impl KernelTablesInner {
|
||||
const fn new() -> Self {
|
||||
Self {
|
||||
inner: unsafe { UnsafeCell::new(KernelImageObject::new(FixedTables::zeroed())) },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Sync for KernelTablesInner {}
|
||||
|
||||
pub struct KernelTablesGuard<'a> {
|
||||
inner: &'a KernelTablesInner,
|
||||
_guard: IrqSafeSpinlockGuard<'a, ArchitectureImpl, ()>,
|
||||
}
|
||||
|
||||
pub fn kernel_tables<'a>() -> KernelTablesGuard<'a> {
|
||||
let _guard = KERNEL_TABLES_LOCK.lock();
|
||||
let inner = &KERNEL_TABLES;
|
||||
KernelTablesGuard { inner, _guard }
|
||||
}
|
||||
|
||||
impl AsPhysicalAddress for KernelTablesGuard<'_> {
|
||||
unsafe fn as_physical_address(&self) -> PhysicalAddress {
|
||||
(*self.inner.inner.get()).as_physical_address()
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for KernelTablesGuard<'_> {
|
||||
type Target = KernelImageObject<FixedTables>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
unsafe { &*self.inner.inner.get() }
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for KernelTablesGuard<'_> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
unsafe { &mut *self.inner.inner.get() }
|
||||
}
|
||||
static KERNEL_TABLES<lock: ArchitectureImpl>: KernelImageObject<FixedTables> = unsafe {
|
||||
KernelImageObject::new(FixedTables::zeroed())
|
||||
};
|
||||
}
|
||||
|
||||
impl KernelTableManager for KernelTableManagerImpl {
|
||||
@ -97,7 +50,7 @@ impl KernelTableManager for KernelTableManagerImpl {
|
||||
assert_eq!(base & 0xFFF, 0);
|
||||
log::info!("map_device_pages({:#x}, {})", base, count);
|
||||
let page_count = page_count::<L3>(count);
|
||||
let virt = kernel_tables().map_dynamic_memory(base, page_count)?;
|
||||
let virt = KERNEL_TABLES.lock().map_dynamic_memory(base, page_count)?;
|
||||
|
||||
Ok(RawDeviceMemoryMapping::from_raw_parts(
|
||||
virt, virt, page_count, 0,
|
||||
@ -110,11 +63,14 @@ impl KernelTableManager for KernelTableManagerImpl {
|
||||
}
|
||||
|
||||
fn virtualize(phys: u64) -> usize {
|
||||
kernel_tables().virtualize(PhysicalAddress::from_u64(phys))
|
||||
KERNEL_TABLES
|
||||
.lock()
|
||||
.virtualize(PhysicalAddress::from_u64(phys))
|
||||
}
|
||||
|
||||
fn physicalize(virt: usize) -> u64 {
|
||||
kernel_tables()
|
||||
KERNEL_TABLES
|
||||
.lock()
|
||||
.physicalize(virt)
|
||||
.expect("Invalid virtual address")
|
||||
.into_u64()
|
||||
@ -137,7 +93,7 @@ impl KernelTableManager for KernelTableManagerImpl {
|
||||
///
|
||||
/// Only meant to be called once during early OS init.
|
||||
pub unsafe fn init_fixed_tables() {
|
||||
let mut tables = kernel_tables();
|
||||
let mut tables = KERNEL_TABLES.lock();
|
||||
|
||||
// Unmap lower stuff
|
||||
for (i, entry) in tables.l0.lower.iter_mut().enumerate() {
|
||||
|
@ -1,5 +1,5 @@
|
||||
#![no_std]
|
||||
#![feature(step_trait, const_trait_impl, never_type)]
|
||||
#![feature(step_trait, const_trait_impl, never_type, decl_macro)]
|
||||
#![allow(clippy::new_without_default)]
|
||||
|
||||
use alloc::vec::Vec;
|
||||
|
@ -153,3 +153,67 @@ impl<'a, A: Architecture, T> DerefMut for IrqSafeSpinlockGuard<'a, A, T> {
|
||||
self.inner.deref_mut()
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper macro to implement "split" locks. This may be needed when a very specific storage
|
||||
/// layout for the locked type is required.
|
||||
pub macro split_spinlock(
|
||||
$(use $use:path;)*
|
||||
|
||||
$(#[$meta:meta])*
|
||||
static $name:ident<$lock:ident: $arch:ty>: $ty:ty = $init:expr;
|
||||
) {
|
||||
pub use $name::$name;
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub mod $name {
|
||||
$(use $use;)*
|
||||
|
||||
use core::cell::UnsafeCell;
|
||||
use core::marker::PhantomData;
|
||||
use core::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
$(#[$meta])*
|
||||
pub static $name: __Wrapper = __Wrapper {
|
||||
inner: UnsafeCell::new($init)
|
||||
};
|
||||
static __LOCK: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct __Wrapper {
|
||||
inner: UnsafeCell<$ty>
|
||||
}
|
||||
pub struct __Guard($crate::guard::IrqGuard<$arch>);
|
||||
|
||||
impl __Wrapper {
|
||||
pub fn $lock(&self) -> __Guard {
|
||||
let irq = $crate::guard::IrqGuard::acquire();
|
||||
while __LOCK.compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed).is_err() {
|
||||
core::hint::spin_loop();
|
||||
}
|
||||
__Guard(irq)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Sync for __Wrapper {}
|
||||
|
||||
impl core::ops::Deref for __Guard {
|
||||
type Target = $ty;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
unsafe { &*$name.inner.get() }
|
||||
}
|
||||
}
|
||||
|
||||
impl core::ops::DerefMut for __Guard {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
unsafe { &mut *$name.inner.get() }
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for __Guard {
|
||||
fn drop(&mut self) {
|
||||
__LOCK.store(false, Ordering::Release)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -423,10 +423,7 @@ impl<K: KernelTableManager, PA: PhysicalMemoryAllocator<Address = PhysicalAddres
|
||||
setup_common_context(
|
||||
&mut stack,
|
||||
__x86_64_task_enter_kernel as _,
|
||||
#[allow(static_mut_refs)]
|
||||
unsafe {
|
||||
KERNEL_TABLES.as_physical_address().into_u64()
|
||||
},
|
||||
unsafe { KERNEL_TABLES.lock().as_physical_address() }.into(),
|
||||
0,
|
||||
);
|
||||
|
||||
|
@ -5,14 +5,14 @@ use core::{
|
||||
sync::atomic::{AtomicUsize, Ordering},
|
||||
};
|
||||
|
||||
use kernel_arch_interface::mem::{
|
||||
DeviceMemoryAttributes, KernelTableManager, RawDeviceMemoryMapping,
|
||||
use kernel_arch_interface::{
|
||||
mem::{DeviceMemoryAttributes, KernelTableManager, RawDeviceMemoryMapping},
|
||||
sync::split_spinlock,
|
||||
};
|
||||
use kernel_arch_x86::registers::CR3;
|
||||
use libk_mm_interface::{
|
||||
address::PhysicalAddress,
|
||||
table::{page_index, EntryLevel, EntryLevelExt},
|
||||
KernelImageObject,
|
||||
};
|
||||
use memtables::x86_64::FixedTables;
|
||||
use static_assertions::{const_assert_eq, const_assert_ne};
|
||||
@ -50,9 +50,15 @@ const RAM_MAPPING_L0I: usize = KERNEL_L0_INDEX - 1;
|
||||
|
||||
const DEVICE_MAPPING_L3_COUNT: usize = 4;
|
||||
|
||||
split_spinlock! {
|
||||
use crate::ArchitectureImpl;
|
||||
use crate::mem::FixedTables;
|
||||
use libk_mm_interface::KernelImageObject;
|
||||
|
||||
#[link_section = ".data.tables"]
|
||||
pub static mut KERNEL_TABLES: KernelImageObject<FixedTables> =
|
||||
static KERNEL_TABLES<lock: ArchitectureImpl>: KernelImageObject<FixedTables> =
|
||||
unsafe { KernelImageObject::new(FixedTables::zeroed()) };
|
||||
}
|
||||
|
||||
// 2MiB for early mappings
|
||||
const EARLY_MAPPING_OFFSET: usize = CANONICAL_ADDRESS_MASK
|
||||
@ -336,9 +342,10 @@ impl<'a, T: ?Sized> Drop for EarlyMapping<'a, T> {
|
||||
}
|
||||
|
||||
pub fn clone_kernel_tables(dst: &mut PageTable<L0>) {
|
||||
let tables = KERNEL_TABLES.lock();
|
||||
unsafe {
|
||||
dst[KERNEL_L0_INDEX] = PageEntry::from_raw(KERNEL_TABLES.l0.data[KERNEL_L0_INDEX]);
|
||||
dst[RAM_MAPPING_L0I] = PageEntry::from_raw(KERNEL_TABLES.l0.data[RAM_MAPPING_L0I]);
|
||||
dst[KERNEL_L0_INDEX] = PageEntry::from_raw(tables.l0.data[KERNEL_L0_INDEX]);
|
||||
dst[RAM_MAPPING_L0I] = PageEntry::from_raw(tables.l0.data[RAM_MAPPING_L0I]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -359,6 +366,7 @@ 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;
|
||||
@ -371,20 +379,20 @@ pub unsafe fn init_fixed_tables() {
|
||||
DEVICE_MAPPING_L2[i] = PageEntry::table(device_mapping_l3_phys, PageAttributes::WRITABLE);
|
||||
}
|
||||
|
||||
assert_eq!(KERNEL_TABLES.kernel_l2.data[EARLY_MAPPING_L2I], 0);
|
||||
KERNEL_TABLES.kernel_l2.data[EARLY_MAPPING_L2I] = (early_mapping_l3_phys as u64)
|
||||
assert_eq!(tables.kernel_l2.data[EARLY_MAPPING_L2I], 0);
|
||||
tables.kernel_l2.data[EARLY_MAPPING_L2I] = (early_mapping_l3_phys as u64)
|
||||
| (PageAttributes::WRITABLE | PageAttributes::PRESENT).bits();
|
||||
|
||||
assert_eq!(KERNEL_TABLES.kernel_l1.data[DEVICE_MAPPING_L1I], 0);
|
||||
KERNEL_TABLES.kernel_l1.data[DEVICE_MAPPING_L1I] = (device_mapping_l2_phys as u64)
|
||||
assert_eq!(tables.kernel_l1.data[DEVICE_MAPPING_L1I], 0);
|
||||
tables.kernel_l1.data[DEVICE_MAPPING_L1I] = (device_mapping_l2_phys as u64)
|
||||
| (PageAttributes::WRITABLE | PageAttributes::PRESENT).bits();
|
||||
|
||||
assert_eq!(KERNEL_TABLES.l0.data[RAM_MAPPING_L0I], 0);
|
||||
KERNEL_TABLES.l0.data[RAM_MAPPING_L0I] =
|
||||
assert_eq!(tables.l0.data[RAM_MAPPING_L0I], 0);
|
||||
tables.l0.data[RAM_MAPPING_L0I] =
|
||||
(ram_mapping_l1_phys as u64) | (PageAttributes::WRITABLE | PageAttributes::PRESENT).bits();
|
||||
|
||||
// TODO ENABLE EFER.NXE
|
||||
let cr3 = &raw const KERNEL_TABLES.l0 as usize - KERNEL_VIRT_OFFSET;
|
||||
let cr3 = (&raw const tables.l0).addr() - KERNEL_VIRT_OFFSET;
|
||||
CR3.set_address(cr3);
|
||||
}
|
||||
|
||||
|
@ -14,18 +14,6 @@ use kernel_arch_interface::mem::KernelTableManager;
|
||||
#[repr(transparent)]
|
||||
pub struct PhysicalAddress(pub(crate) u64);
|
||||
|
||||
// /// Interface for converting addresses from their raw values to more specific types
|
||||
// pub trait FromRaw<T> {
|
||||
// /// Converts a raw value into the address wrapper type
|
||||
// fn from_raw(value: T) -> Self;
|
||||
// }
|
||||
//
|
||||
// /// Interface for converting wrapper types into their raw address representations
|
||||
// pub trait IntoRaw<T> {
|
||||
// /// Converts a wrapper type value into its raw address
|
||||
// fn into_raw(self) -> T;
|
||||
// }
|
||||
|
||||
/// Interface for obtaining physical addresses of values
|
||||
pub trait AsPhysicalAddress {
|
||||
/// Returns the value's physical address.
|
||||
|
@ -1,9 +1,10 @@
|
||||
use core::{arch::global_asm, ptr::addr_of};
|
||||
use core::arch::global_asm;
|
||||
|
||||
use abi::{primitive_enum, process::Signal, SyscallFunction};
|
||||
use kernel_arch_i686::context::{ExceptionFrame, SyscallFrame};
|
||||
use kernel_arch_x86::registers::{CR2, CR3};
|
||||
use libk::task::thread::Thread;
|
||||
use libk_util::sync::spin_rwlock::IrqSafeRwLock;
|
||||
use tock_registers::interfaces::Readable;
|
||||
|
||||
use crate::{arch::x86::peripherals::i8259, syscall};
|
||||
@ -147,7 +148,7 @@ impl Entry {
|
||||
}
|
||||
}
|
||||
|
||||
static mut IDT: [Entry; SIZE] = [Entry::NULL; SIZE];
|
||||
static IDT: IrqSafeRwLock<[Entry; SIZE]> = IrqSafeRwLock::new([Entry::NULL; SIZE]);
|
||||
|
||||
fn dump_user_exception(kind: ExceptionKind, frame: &ExceptionFrame) {
|
||||
let thread = Thread::current();
|
||||
@ -267,11 +268,13 @@ pub unsafe fn init_exceptions() {
|
||||
fn __i686_syscall_vector();
|
||||
}
|
||||
|
||||
let mut idt = IDT.write();
|
||||
|
||||
for (i, &entry) in __i686_exception_vectors.iter().enumerate() {
|
||||
IDT[i] = Entry::new(entry, 0x08, Entry::PRESENT | Entry::INT32);
|
||||
idt[i] = Entry::new(entry, 0x08, Entry::PRESENT | Entry::INT32);
|
||||
}
|
||||
|
||||
for entry in IDT.iter_mut().skip(32) {
|
||||
for entry in idt.iter_mut().skip(32) {
|
||||
*entry = Entry::new(
|
||||
__i686_dummy_vector as usize,
|
||||
0x08,
|
||||
@ -279,17 +282,17 @@ pub unsafe fn init_exceptions() {
|
||||
);
|
||||
}
|
||||
|
||||
i8259::setup_vectors(&mut IDT[32..]);
|
||||
i8259::setup_vectors(&mut idt[32..]);
|
||||
|
||||
IDT[0x80] = Entry::new(
|
||||
idt[0x80] = Entry::new(
|
||||
__i686_syscall_vector as usize,
|
||||
0x08,
|
||||
Entry::PRESENT | Entry::INT32 | Entry::DPL3,
|
||||
);
|
||||
|
||||
let idtr = Pointer {
|
||||
limit: (IDT.len() * size_of::<Entry>()) as u16 - 1,
|
||||
offset: addr_of!(IDT) as usize,
|
||||
limit: (idt.len() * size_of::<Entry>()) as u16 - 1,
|
||||
offset: idt.as_ptr().addr(),
|
||||
};
|
||||
|
||||
core::arch::asm!("wbinvd; lidt ({0})", in(reg) &idtr, options(att_syntax));
|
||||
|
@ -1,10 +1,11 @@
|
||||
//! x86-64 exception and interrupt handling
|
||||
use core::{arch::global_asm, mem::size_of, ptr::addr_of};
|
||||
use core::{arch::global_asm, mem::size_of};
|
||||
|
||||
use abi::{primitive_enum, process::Signal};
|
||||
use kernel_arch_x86::registers::{CR2, CR3};
|
||||
use kernel_arch_x86_64::context::ExceptionFrame;
|
||||
use libk::{arch::Cpu, task::thread::Thread};
|
||||
use libk_util::sync::spin_rwlock::IrqSafeRwLock;
|
||||
use tock_registers::interfaces::Readable;
|
||||
|
||||
use crate::arch::x86_64::apic;
|
||||
@ -111,7 +112,7 @@ impl Entry {
|
||||
}
|
||||
}
|
||||
|
||||
static mut IDT: [Entry; SIZE] = [Entry::NULL; SIZE];
|
||||
static IDT: IrqSafeRwLock<[Entry; SIZE]> = IrqSafeRwLock::new([Entry::NULL; SIZE]);
|
||||
|
||||
fn dump_user_exception(kind: ExceptionKind, frame: &ExceptionFrame) {
|
||||
let thread = Thread::current();
|
||||
@ -215,20 +216,22 @@ extern "C" fn __x86_64_exception_handler(frame: *mut ExceptionFrame) {
|
||||
/// Only meant to be called once per each CPU during their init.
|
||||
pub unsafe fn init_exceptions(cpu_index: usize) {
|
||||
if cpu_index == 0 {
|
||||
let mut idt = IDT.write();
|
||||
extern "C" {
|
||||
static __x86_64_exception_vectors: [usize; 32];
|
||||
}
|
||||
|
||||
for (i, &entry) in __x86_64_exception_vectors.iter().enumerate() {
|
||||
IDT[i] = Entry::new(entry, 0x08, Entry::PRESENT | Entry::INT32);
|
||||
idt[i] = Entry::new(entry, 0x08, Entry::PRESENT | Entry::INT32);
|
||||
}
|
||||
|
||||
apic::setup_vectors(&mut IDT[32..]);
|
||||
apic::setup_vectors(&mut idt[32..]);
|
||||
}
|
||||
|
||||
let idt = IDT.read();
|
||||
let idtr = Pointer {
|
||||
limit: (IDT.len() * size_of::<Entry>()) as u16 - 1,
|
||||
offset: addr_of!(IDT) as usize,
|
||||
limit: (idt.len() * size_of::<Entry>()) as u16 - 1,
|
||||
offset: idt.as_ptr().addr(),
|
||||
};
|
||||
|
||||
core::arch::asm!("wbinvd; lidt ({0})", in(reg) &idtr, options(att_syntax));
|
||||
|
@ -44,7 +44,7 @@ unsafe fn start_ap_core(apic_id: u32) {
|
||||
let bsp_cpu = Cpu::local();
|
||||
let bsp_apic = bsp_cpu.local_apic();
|
||||
|
||||
let cr3 = KERNEL_TABLES.as_physical_address();
|
||||
let cr3 = KERNEL_TABLES.lock().as_physical_address();
|
||||
let stack_base = phys::alloc_pages_contiguous(AP_STACK_PAGES)
|
||||
.unwrap()
|
||||
.virtualize();
|
||||
@ -93,9 +93,12 @@ pub unsafe fn start_ap_cores(info: &ProcessorInfo<AcpiAllocator>) {
|
||||
PageEntry::<L1>::table(identity_l2.as_physical_address(), PageAttributes::WRITABLE);
|
||||
identity_l2[0] = PageEntry::<L2>::block(PhysicalAddress::ZERO, PageAttributes::WRITABLE);
|
||||
|
||||
assert_eq!(KERNEL_TABLES.l0.data[0], 0);
|
||||
KERNEL_TABLES.l0.data[0] = identity_l1.as_physical_address().into_u64()
|
||||
{
|
||||
let mut tables = KERNEL_TABLES.lock();
|
||||
assert_eq!(tables.l0.data[0], 0);
|
||||
tables.l0.data[0] = identity_l1.as_physical_address().into_u64()
|
||||
| (PageAttributes::WRITABLE | PageAttributes::PRESENT).bits();
|
||||
}
|
||||
|
||||
// Load AP_BOOTSTRAP_CODE
|
||||
let mut code_ref = PhysicalRefMut::map_slice(AP_BOOTSTRAP_CODE, AP_BOOTSTRAP_BIN.len());
|
||||
@ -110,7 +113,7 @@ pub unsafe fn start_ap_cores(info: &ProcessorInfo<AcpiAllocator>) {
|
||||
// Remove the identity-map
|
||||
identity_l2[0] = PageEntry::INVALID;
|
||||
flush_tlb_entry(0);
|
||||
KERNEL_TABLES.l0.data[0] = 0;
|
||||
KERNEL_TABLES.lock().l0.data[0] = 0;
|
||||
|
||||
PageTable::free::<TableAllocatorImpl>(identity_l1);
|
||||
PageTable::free::<TableAllocatorImpl>(identity_l2);
|
||||
|
@ -33,8 +33,6 @@
|
||||
#![deny(missing_docs)]
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
// XXX FIXME TODO
|
||||
#![allow(static_mut_refs)]
|
||||
|
||||
use arch::Platform;
|
||||
use kernel_arch::{Architecture, ArchitectureImpl};
|
||||
|
Loading…
x
Reference in New Issue
Block a user