Commit 8e04f43d authored by Stefan Lankes's avatar Stefan Lankes Committed by Stefan Lankes
Browse files

separate virtual from physical addresses

- the logical address space is completly separate from the physical
- consequently, different names are used
parent 57961f76
......@@ -17,7 +17,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cc"
version = "1.0.54"
version = "1.0.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
......@@ -66,7 +66,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
......@@ -111,7 +111,7 @@ name = "proc-macro2"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
......@@ -124,11 +124,11 @@ dependencies = [
[[package]]
name = "raw-cpuid"
version = "8.1.0"
version = "8.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.54 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
......@@ -168,17 +168,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "syn"
version = "1.0.31"
version = "1.0.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-xid"
version = "0.2.0"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
......@@ -188,14 +188,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bit_field 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"raw-cpuid 8.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"raw-cpuid 8.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[metadata]
"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
"checksum bit_field 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a165d606cf084741d4ac3a28fb6e9b1eb0bd31f6cd999098cfddb0b2ab381dc0"
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
"checksum cc 1.0.54 (registry+https://github.com/rust-lang/crates.io-index)" = "7bbb73db36c1246e9034e307d0fba23f9a2e251faa47ade70c1bd252220c8311"
"checksum cc 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)" = "f9a06fb2e53271d7c279ec1efea6ab691c35a2ae67ec0d91d7acec0caf13b518"
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
"checksum multiboot 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "745e351d4f128ea9e266fe2dd04a1bd7349c60441d45ec8677520bae08e25d43"
......@@ -208,10 +208,10 @@ dependencies = [
"checksum num-traits 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611"
"checksum proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa"
"checksum quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
"checksum raw-cpuid 8.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ab01b333691cd32fa882476c0fd735e98a85bf080853728936210562d0cdca6"
"checksum raw-cpuid 8.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0cee2c7710d96f9f90f56824fca5438b301dc0fb49ece4cf9dfa044e54067e10"
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"checksum syn 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)" = "b5304cfdf27365b7585c25d4af91b35016ed21ef88f17ced89c7093b43dba8b6"
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
"checksum syn 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)" = "e8d5d96e8cbb005d6959f119f773bfaebb5684296108fb32600c00cde305b2cd"
"checksum unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
"checksum x86 0.34.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c146cbc47471e076987378c159a7aa8fa434680c6fbddca59fe6f40f1591c819"
......@@ -7,19 +7,20 @@
use crate::arch::x86_64::mm::paging::{BasePageSize, PageSize, PageTableEntryFlags};
use crate::arch::x86_64::mm::{paging, virtualmem};
use crate::arch::x86_64::mm::{PhysAddr, VirtAddr};
use crate::x86::io::*;
use core::{mem, slice, str};
/// Memory at this physical address is supposed to contain a pointer to the Extended BIOS Data Area (EBDA).
const EBDA_PTR_LOCATION: usize = 0x0000_040E;
const EBDA_PTR_LOCATION: PhysAddr = PhysAddr(0x0000_040E);
/// Minimum physical address where a valid EBDA must be located.
const EBDA_MINIMUM_ADDRESS: usize = 0x400;
const EBDA_MINIMUM_ADDRESS: PhysAddr = PhysAddr(0x400);
/// The size of the EBDA window that is searched for an ACPI RSDP.
const EBDA_WINDOW_SIZE: usize = 1024;
/// The lower bound of the other address range, where the ACPI RSDP could be located.
const RSDP_SEARCH_ADDRESS_LOW: usize = 0xE_0000;
const RSDP_SEARCH_ADDRESS_LOW: PhysAddr = PhysAddr(0xE_0000);
/// The upper bound of the other address range, where the ACPI RSDP could be located.
const RSDP_SEARCH_ADDRESS_HIGH: usize = 0xF_FFFF;
const RSDP_SEARCH_ADDRESS_HIGH: PhysAddr = PhysAddr(0xF_FFFF);
/// Length in bytes of the structure, over which the basic (ACPI 1.0) checksum is calculated.
const RSDP_CHECKSUM_LENGTH: usize = 20;
/// Length in byte sof the structure, over which the extended (ACPI 2.0+) checksum is calculated.
......@@ -94,12 +95,12 @@ impl AcpiSdtHeader {
/// Maps a single table to memory and frees the memory when a variable of this structure goes out of scope.
pub struct AcpiTable<'a> {
header: &'a AcpiSdtHeader,
allocated_virtual_address: usize,
allocated_virtual_address: VirtAddr,
allocated_length: usize,
}
impl<'a> AcpiTable<'a> {
fn map(physical_address: usize) -> Self {
fn map(physical_address: PhysAddr) -> Self {
let mut flags = PageTableEntryFlags::empty();
flags.normal().read_only().execute_disable();
......@@ -109,13 +110,13 @@ impl<'a> AcpiTable<'a> {
let mut allocated_length = 2 * BasePageSize::SIZE;
let mut count = allocated_length / BasePageSize::SIZE;
let physical_map_address = align_down!(physical_address, BasePageSize::SIZE);
let offset = physical_address - physical_map_address;
let physical_map_address = physical_address.align_down_to_base_page();
let offset: usize = (physical_address - physical_map_address).into();
let mut virtual_address = virtualmem::allocate(allocated_length).unwrap();
paging::map::<BasePageSize>(virtual_address, physical_map_address, count, flags);
// Get a pointer to the header and query the table length.
let mut header_ptr = (virtual_address + offset) as *const AcpiSdtHeader;
let mut header_ptr: *const AcpiSdtHeader = (virtual_address + offset).as_ptr();
let table_length = unsafe { (*header_ptr).length } as usize;
// Remap if the length exceeds what we've allocated.
......@@ -128,7 +129,7 @@ impl<'a> AcpiTable<'a> {
virtual_address = virtualmem::allocate(allocated_length).unwrap();
paging::map::<BasePageSize>(virtual_address, physical_map_address, count, flags);
header_ptr = (virtual_address + offset) as *const AcpiSdtHeader;
header_ptr = (virtual_address + offset).as_ptr();
}
// Return the table.
......@@ -252,16 +253,19 @@ fn verify_checksum(start_address: usize, length: usize) -> Result<(), ()> {
/// Tries to find the ACPI RSDP within the specified address range.
/// Returns a reference to it within the Ok() if successful or an empty Err() on failure.
fn detect_rsdp(start_address: usize, end_address: usize) -> Result<&'static AcpiRsdp, ()> {
fn detect_rsdp(start_address: PhysAddr, end_address: PhysAddr) -> Result<&'static AcpiRsdp, ()> {
// Trigger page mapping in the first iteration!
let mut current_page = 0;
// Look for the ACPI RSDP in all possible 16-byte aligned addresses within this range.
for current_address in (start_address..end_address).step_by(16) {
for current_address in (start_address.as_usize()..end_address.as_usize()).step_by(16) {
// Have we crossed a page boundary in the last iteration?
if current_address / BasePageSize::SIZE > current_page {
// Identity-map this possible page of the RSDP.
paging::identity_map(current_address, current_address);
paging::identity_map(
PhysAddr::from(current_address),
PhysAddr::from(current_address),
);
current_page = current_address / BasePageSize::SIZE;
}
......@@ -308,8 +312,9 @@ fn detect_rsdp(start_address: usize, end_address: usize) -> Result<&'static Acpi
fn detect_acpi() -> Result<&'static AcpiRsdp, ()> {
// Get the address of the EBDA.
paging::identity_map(EBDA_PTR_LOCATION, EBDA_PTR_LOCATION);
let ebda_ptr_location = unsafe { &*(EBDA_PTR_LOCATION as *const u16) };
let ebda_address = (*ebda_ptr_location as usize) << 4;
let ebda_ptr_location: &u16 =
unsafe { &*(VirtAddr::from(EBDA_PTR_LOCATION.as_u64()).as_ptr()) };
let ebda_address = PhysAddr((*ebda_ptr_location as u64) << 4);
// Check if the pointed address is valid. This check is also done in ACPICA.
if ebda_address > EBDA_MINIMUM_ADDRESS {
......@@ -409,9 +414,9 @@ fn parse_fadt(fadt: AcpiTable<'_>) {
// TODO: This must not require "unsafe", see https://github.com/rust-lang/rust/issues/46043#issuecomment-393072398
let x_dsdt_field_address = unsafe { &fadt_table.x_dsdt as *const _ as usize };
let dsdt_address = if x_dsdt_field_address < fadt.table_end_address() && fadt_table.x_dsdt > 0 {
fadt_table.x_dsdt as usize
PhysAddr(fadt_table.x_dsdt)
} else {
fadt_table.dsdt as usize
PhysAddr(fadt_table.dsdt.into())
};
let dsdt = AcpiTable::map(dsdt_address);
......@@ -468,9 +473,9 @@ pub fn init() {
// Both are called RSDT in the following.
let rsdp = detect_acpi().expect("HermitCore requires an ACPI-compliant system");
let rsdt_physical_address = if rsdp.revision >= 2 {
rsdp.xsdt_physical_address as usize
PhysAddr(rsdp.xsdt_physical_address)
} else {
rsdp.rsdt_physical_address as usize
PhysAddr(rsdp.rsdt_physical_address.into())
};
// Map the RSDT.
......@@ -483,11 +488,11 @@ pub fn init() {
// Depending on the RSDP revision, either an XSDT or an RSDT has been chosen above.
// The XSDT contains 64-bit pointers whereas the RSDT has 32-bit pointers.
let table_physical_address = if rsdp.revision >= 2 {
let address = unsafe { *(current_address as *const u64) } as usize;
let address = PhysAddr(unsafe { *(current_address as *const u64) });
current_address += mem::size_of::<u64>();
address
} else {
let address = unsafe { *(current_address as *const u32) } as usize;
let address = PhysAddr((unsafe { *(current_address as *const u32) }).into());
current_address += mem::size_of::<u32>();
address
};
......
......@@ -14,6 +14,7 @@ use crate::arch::x86_64::kernel::smp_boot_code::SMP_BOOT_CODE;
use crate::arch::x86_64::kernel::IRQ_COUNTERS;
use crate::arch::x86_64::mm::paging::{BasePageSize, PageSize, PageTableEntryFlags};
use crate::arch::x86_64::mm::{paging, virtualmem};
use crate::arch::x86_64::mm::{PhysAddr, VirtAddr};
use crate::collections::CachePadded;
use crate::config::*;
use crate::environment;
......@@ -62,7 +63,7 @@ const SPURIOUS_INTERRUPT_NUMBER: u8 = 127;
/// While our boot processor is already in x86-64 mode, application processors boot up in 16-bit real mode
/// and need an address in the CS:IP addressing scheme to jump to.
/// The CS:IP addressing scheme is limited to 2^20 bytes (= 1 MiB).
const SMP_BOOT_CODE_ADDRESS: usize = 0x8000;
const SMP_BOOT_CODE_ADDRESS: VirtAddr = VirtAddr(0x8000);
const SMP_BOOT_CODE_OFFSET_PML4: usize = 0x18;
const SMP_BOOT_CODE_OFFSET_ENTRY: usize = 0x08;
......@@ -70,8 +71,8 @@ const SMP_BOOT_CODE_OFFSET_BOOTINFO: usize = 0x10;
const X2APIC_ENABLE: u64 = 1 << 10;
static mut LOCAL_APIC_ADDRESS: usize = 0;
static mut IOAPIC_ADDRESS: usize = 0;
static mut LOCAL_APIC_ADDRESS: VirtAddr = VirtAddr(0);
static mut IOAPIC_ADDRESS: VirtAddr = VirtAddr(0);
/// Stores the Local APIC IDs of all CPUs. The index equals the Core ID.
/// Both numbers often match, but don't need to (e.g. when a core has been disabled).
......@@ -184,7 +185,7 @@ fn detect_from_acpi() -> Result<usize, ()> {
}
#[cfg(feature = "acpi")]
fn detect_from_acpi() -> Result<usize, ()> {
fn detect_from_acpi() -> Result<PhysAddr, ()> {
// Get the Multiple APIC Description Table (MADT) from the ACPI information and its specific table header.
let madt = acpi::get_madt().expect("HermitCore requires a MADT in the ACPI tables");
let madt_header = unsafe { &*(madt.table_start_address() as *const AcpiMadtHeader) };
......@@ -227,7 +228,7 @@ fn detect_from_acpi() -> Result<usize, ()> {
flags.device().writable().execute_disable();
paging::map::<BasePageSize>(
IOAPIC_ADDRESS,
ioapic_record.address as usize,
PhysAddr(ioapic_record.address.into()),
1,
flags,
);
......@@ -243,12 +244,12 @@ fn detect_from_acpi() -> Result<usize, ()> {
// Successfully derived all information from the MADT.
// Return the physical address of the Local APIC.
Ok(madt_header.local_apic_address as usize)
Ok(PhysAddr(madt_header.local_apic_address.into()))
}
fn detect_from_uhyve() -> Result<usize, ()> {
fn detect_from_uhyve() -> Result<PhysAddr, ()> {
if environment::is_uhyve() {
let defaullt_address = 0xFEC0_0000usize;
let defaullt_address = PhysAddr(0xFEC0_0000);
unsafe {
IOAPIC_ADDRESS = virtualmem::allocate(BasePageSize::SIZE).unwrap();
......@@ -262,7 +263,7 @@ fn detect_from_uhyve() -> Result<usize, ()> {
paging::map::<BasePageSize>(IOAPIC_ADDRESS, defaullt_address, 1, flags);
}
return Ok(0xFEE0_0000usize);
return Ok(PhysAddr(0xFEE0_0000));
}
Err(())
......@@ -503,7 +504,7 @@ pub fn init_next_processor_variables(core_id: CoreId) {
IRQ_COUNTERS.insert(core_id, &(*boxed_irq_raw));
boxed_percore.irq_statistics = PerCoreVariable::new(boxed_irq_raw);
core::ptr::write_volatile(&mut (*BOOT_INFO).current_stack_address, stack as u64);
core::ptr::write_volatile(&mut (*BOOT_INFO).current_stack_address, stack.as_u64());
core::ptr::write_volatile(
&mut (*BOOT_INFO).current_percore_address,
Box::into_raw(boxed_percore) as u64,
......@@ -537,27 +538,32 @@ pub fn boot_application_processors() {
);
let mut flags = PageTableEntryFlags::empty();
flags.normal().writable();
paging::map::<BasePageSize>(SMP_BOOT_CODE_ADDRESS, SMP_BOOT_CODE_ADDRESS, 1, flags);
paging::map::<BasePageSize>(
SMP_BOOT_CODE_ADDRESS,
PhysAddr(SMP_BOOT_CODE_ADDRESS.as_u64()),
1,
flags,
);
unsafe {
ptr::copy_nonoverlapping(
&SMP_BOOT_CODE as *const u8,
SMP_BOOT_CODE_ADDRESS as *mut u8,
SMP_BOOT_CODE_ADDRESS.as_mut_ptr(),
SMP_BOOT_CODE.len(),
);
}
unsafe {
// Pass the PML4 page table address to the boot code.
*((SMP_BOOT_CODE_ADDRESS + SMP_BOOT_CODE_OFFSET_PML4) as *mut u32) = cr3() as u32;
*((SMP_BOOT_CODE_ADDRESS + SMP_BOOT_CODE_OFFSET_PML4).as_mut_ptr::<u32>()) =
cr3().try_into().unwrap();
// Set entry point
debug!(
"Set entry point for application processor to 0x{:x}",
arch::x86_64::kernel::start::_start as usize
arch::x86_64::kernel::start::_start as u64
);
*((SMP_BOOT_CODE_ADDRESS + SMP_BOOT_CODE_OFFSET_ENTRY) as *mut usize) =
arch::x86_64::kernel::start::_start as usize;
*((SMP_BOOT_CODE_ADDRESS + SMP_BOOT_CODE_OFFSET_BOOTINFO) as *mut usize) =
BOOT_INFO as usize;
*((SMP_BOOT_CODE_ADDRESS + SMP_BOOT_CODE_OFFSET_ENTRY).as_mut_ptr()) =
arch::x86_64::kernel::start::_start as u64;
*((SMP_BOOT_CODE_ADDRESS + SMP_BOOT_CODE_OFFSET_BOOTINFO).as_mut_ptr()) = BOOT_INFO as u64;
}
// Now wake up each application processor.
......@@ -599,7 +605,7 @@ pub fn boot_application_processors() {
IA32_X2APIC_ICR,
destination
| APIC_ICR_DELIVERY_MODE_STARTUP
| ((SMP_BOOT_CODE_ADDRESS as u64) >> 12),
| ((SMP_BOOT_CODE_ADDRESS.as_u64()) >> 12),
);
debug!("Waiting for it to respond");
......@@ -656,8 +662,8 @@ pub fn wakeup_core(core_id_to_wakeup: CoreId) {
/// Translate the x2APIC MSR into an xAPIC memory address.
#[inline]
fn translate_x2apic_msr_to_xapic_address(x2apic_msr: u32) -> usize {
unsafe { LOCAL_APIC_ADDRESS + ((x2apic_msr as usize & 0xFF) << 4) }
fn translate_x2apic_msr_to_xapic_address(x2apic_msr: u32) -> VirtAddr {
unsafe { LOCAL_APIC_ADDRESS + ((x2apic_msr as u64 & 0xFF) << 4) }
}
fn local_apic_read(x2apic_msr: u32) -> u32 {
......@@ -665,15 +671,15 @@ fn local_apic_read(x2apic_msr: u32) -> u32 {
// x2APIC is simple, we can just read from the given MSR.
unsafe { rdmsr(x2apic_msr) as u32 }
} else {
unsafe { *(translate_x2apic_msr_to_xapic_address(x2apic_msr) as *const u32) }
unsafe { *(translate_x2apic_msr_to_xapic_address(x2apic_msr).as_ptr::<u32>()) }
}
}
fn ioapic_write(reg: u32, value: u32) {
unsafe {
core::ptr::write_volatile(IOAPIC_ADDRESS as *mut u32, reg);
core::ptr::write_volatile(IOAPIC_ADDRESS.as_mut_ptr::<u32>(), reg);
core::ptr::write_volatile(
(IOAPIC_ADDRESS + 4 * mem::size_of::<u32>()) as *mut u32,
(IOAPIC_ADDRESS + 4 * mem::size_of::<u32>()).as_mut_ptr::<u32>(),
value,
);
}
......@@ -683,9 +689,9 @@ fn ioapic_read(reg: u32) -> u32 {
let value;
unsafe {
core::ptr::write_volatile(IOAPIC_ADDRESS as *mut u32, reg);
core::ptr::write_volatile(IOAPIC_ADDRESS.as_mut_ptr::<u32>(), reg);
value =
core::ptr::read_volatile((IOAPIC_ADDRESS + 4 * mem::size_of::<u32>()) as *const u32);
core::ptr::read_volatile((IOAPIC_ADDRESS + 4 * mem::size_of::<u32>()).as_ptr::<u32>());
}
value
......@@ -710,15 +716,16 @@ fn local_apic_write(x2apic_msr: u32, value: u64) {
// Instead of a single 64-bit ICR register, xAPIC has two 32-bit registers (ICR1 and ICR2).
// There is a gap between them and the destination field in ICR2 is also 8 bits instead of 32 bits.
let destination = ((value >> 8) & 0xFF00_0000) as u32;
let icr2 = unsafe { &mut *((LOCAL_APIC_ADDRESS + APIC_ICR2) as *mut u32) };
let icr2 = unsafe { &mut *((LOCAL_APIC_ADDRESS + APIC_ICR2).as_mut_ptr::<u32>()) };
*icr2 = destination;
// The remaining data without the destination will now be written into ICR1.
}
// Write the value.
let value_ref =
unsafe { &mut *(translate_x2apic_msr_to_xapic_address(x2apic_msr) as *mut u32) };
let value_ref = unsafe {
&mut *(translate_x2apic_msr_to_xapic_address(x2apic_msr).as_mut_ptr::<u32>())
};
*value_ref = value as u32;
if x2apic_msr == IA32_X2APIC_ICR {
......
......@@ -44,7 +44,7 @@ struct Gdt {
pub fn init() {
unsafe {
// Dynamically allocate memory for the GDT.
GDT = crate::mm::allocate(mem::size_of::<Gdt>(), false) as *mut Gdt;
GDT = crate::mm::allocate(mem::size_of::<Gdt>(), false).as_mut_ptr::<Gdt>();
// The NULL descriptor is always the first entry.
(*GDT).entries[GDT_NULL as usize] = Descriptor::NULL;
......@@ -90,14 +90,14 @@ pub fn add_current_core() {
// When switching to another task on this core, this entry is replaced.
boxed_tss.rsp[0] = unsafe { core::ptr::read_volatile(&(*BOOT_INFO).current_stack_address) }
+ KERNEL_STACK_SIZE as u64
- 0x10;
- 0x10u64;
set_kernel_stack(boxed_tss.rsp[0] as u64);
// Allocate all ISTs for this core.
// Every task later gets its own IST1, so the IST1 allocated here is only used by the Idle task.
for i in 0..IST_ENTRIES {
let ist = crate::mm::allocate(KERNEL_STACK_SIZE, true);
boxed_tss.ist[i] = (ist + KERNEL_STACK_SIZE - 0x10) as u64;
boxed_tss.ist[i] = ist.as_u64() + KERNEL_STACK_SIZE as u64 - 0x10u64;
}
unsafe {
......
......@@ -35,6 +35,7 @@ pub mod virtio;
pub mod virtio_fs;
pub mod virtio_net;
use crate::arch::mm::VirtAddr;
use crate::arch::x86_64::kernel::irq::{get_irq_name, IrqStatistics};
use crate::arch::x86_64::kernel::percore::*;
use crate::arch::x86_64::kernel::serial::SerialPort;
......@@ -166,8 +167,8 @@ pub unsafe extern "C" fn sys_uhyve_get_mask(mask: *mut u8) {
switch_to_user!();
}
pub fn get_base_address() -> usize {
unsafe { core::ptr::read_volatile(&(*BOOT_INFO).base) as usize }
pub fn get_base_address() -> VirtAddr {
unsafe { VirtAddr(core::ptr::read_volatile(&(*BOOT_INFO).base)) }
}
pub fn get_image_size() -> usize {
......@@ -178,8 +179,8 @@ pub fn get_limit() -> usize {
unsafe { core::ptr::read_volatile(&(*BOOT_INFO).limit) as usize }
}
pub fn get_tls_start() -> usize {
unsafe { core::ptr::read_volatile(&(*BOOT_INFO).tls_start) as usize }
pub fn get_tls_start() -> VirtAddr {
unsafe { VirtAddr(core::ptr::read_volatile(&(*BOOT_INFO).tls_start)) }
}
pub fn get_tls_filesz() -> usize {
......@@ -190,8 +191,8 @@ pub fn get_tls_memsz() -> usize {
unsafe { core::ptr::read_volatile(&(*BOOT_INFO).tls_memsz) as usize }
}
pub fn get_mbinfo() -> usize {
unsafe { core::ptr::read_volatile(&(*BOOT_INFO).mb_info) as usize }
pub fn get_mbinfo() -> VirtAddr {
unsafe { VirtAddr(core::ptr::read_volatile(&(*BOOT_INFO).mb_info)) }
}
pub fn get_processor_count() -> u32 {
......@@ -216,8 +217,8 @@ pub fn get_cmdsize() -> usize {
unsafe { core::ptr::read_volatile(&(*BOOT_INFO).cmdsize) as usize }
}
pub fn get_cmdline() -> usize {
unsafe { core::ptr::read_volatile(&(*BOOT_INFO).cmdline) as usize }
pub fn get_cmdline() -> VirtAddr {
unsafe { VirtAddr(core::ptr::read_volatile(&(*BOOT_INFO).cmdline)) }
}
/// Earliest initialization function called by the Boot Processor.
......
......@@ -10,6 +10,7 @@ use crate::arch::x86_64::kernel::pci_ids::{CLASSES, VENDORS};
use crate::arch::x86_64::kernel::virtio;
use crate::arch::x86_64::kernel::virtio_fs::VirtioFsDriver;
use crate::arch::x86_64::kernel::virtio_net::VirtioNetDriver;
use crate::arch::x86_64::mm::{PhysAddr, VirtAddr};
use crate::synch::spinlock::SpinlockIrqSave;
use crate::x86::io::*;
use alloc::rc::Rc;
......@@ -314,7 +315,7 @@ impl PciAdapter {
/// Memory maps pci bar with specified index to identical location in virtual memory.
/// no_cache determines if we set the `Cache Disable` flag in the page-table-entry.
/// Returns (virtual-pointer, size) if successful, else None (if bar non-existent or IOSpace)
pub fn memory_map_bar(&self, index: u8, no_cache: bool) -> Option<(usize, usize)> {
pub fn memory_map_bar(&self, index: u8, no_cache: bool) -> Option<(VirtAddr, usize)> {
let pci_bar = match self.get_bar(index) {
Some(PciBar::IO(_)) => {
warn!("Cannot map IOBar!");
......@@ -344,7 +345,13 @@ impl PciAdapter {
// We therefore do not need to reserve any additional memory in our kernel.
// Map bar into RW^X virtual memory
let physical_address = pci_bar.addr;
let virtual_address = crate::mm::map(physical_address, pci_bar.size, true, false, no_cache);
let virtual_address = crate::mm::map(
PhysAddr::from(physical_address),
pci_bar.size,
true,
false,
no_cache,
);
Some((virtual_address, pci_bar.size))
}
......
......@@ -9,6 +9,7 @@
//! Architecture dependent interface to initialize a task
use alloc::alloc::{alloc, dealloc, Layout};
use core::convert::TryInto;
use core::{mem, ptr};
use crate::arch::x86_64::kernel::apic;
......@@ -16,6 +17,7 @@ use crate::arch::x86_64::kernel::idt;
use crate::arch::x86_64::kernel::irq;
use crate::arch::x86_64::kernel::percore::*;
use crate::arch::x86_64::mm::paging::{BasePageSize, PageSize, PageTableEntryFlags};
use crate::arch::x86_64::mm::{PhysAddr, VirtAddr};
use crate::config::*;
use crate::environment;
use crate::scheduler::task::{Task, TaskFrame};
......@@ -23,55 +25,55 @@ use crate::scheduler::task::{Task, TaskFrame};
#[repr(C, packed)]
struct State {
/// FS register for TLS support
fs: usize,
fs: u64,
/// R15 register
r15: usize,
r15: u64,
/// R14 register
r14: usize,
r14: u64,
/// R13 register
r13: usize,
r13: u64,
/// R12 register
r12: usize,
r12: u64,
/// R11 register
r11: usize,
r11: u64,
/// R10 register
r10: usize,
r10: u64,
/// R9 register
r9: usize,
r9: u64,
/// R8 register
r8: usize,
r8: u64,
/// RDI register
rdi: usize,
rdi: u64,
/// RSI register
rsi: usize,
rsi: u64,
/// RBP register
rbp: usize,
rbp: u64,
/// RBX register
rbx: usize,
rbx: u64,
/// RDX register
rdx: usize,
rdx: u64,
/// RCX register
rcx: usize,
rcx: u64,
/// RAX register
rax: usize,
rax: u64,
/// status flags
rflags: usize,
rflags: u64,
/// instruction pointer
rip: usize,
rip: u64,
}
pub struct BootStack {
/// stack for kernel tasks
stack: usize,
stack: VirtAddr,