mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-10 05:46:48 +00:00
Rename structure
This commit is contained in:
parent
90a390ecda
commit
ebfb199512
@ -8,7 +8,7 @@ use volatile::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::driver::{acpi::ACPI_TABLES, ioapic};
|
use crate::driver::{acpi::ACPI_TABLES, ioapic};
|
||||||
static HPET_INSTANCE: Once<HPET> = Once::new();
|
static HPET_INSTANCE: Once<Hpet> = Once::new();
|
||||||
|
|
||||||
const OFFSET_ID_REGISTER: usize = 0x000;
|
const OFFSET_ID_REGISTER: usize = 0x000;
|
||||||
const OFFSET_CONFIGURATION_REGISTER: usize = 0x010;
|
const OFFSET_CONFIGURATION_REGISTER: usize = 0x010;
|
||||||
@ -19,22 +19,22 @@ const HPET_FREQ: usize = 1_000_000_000_000_000;
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct HPETTimerRegister {
|
struct HpetTimerRegister {
|
||||||
configuration_and_capabilities_register: u32,
|
configuration_and_capabilities_register: u32,
|
||||||
timer_compartor_value_register: u32,
|
timer_compartor_value_register: u32,
|
||||||
fsb_interrupt_route_register: u32,
|
fsb_interrupt_route_register: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct HPET {
|
struct Hpet {
|
||||||
information_register: Volatile<&'static u32, ReadOnly>,
|
information_register: Volatile<&'static u32, ReadOnly>,
|
||||||
general_configuration_register: Volatile<&'static mut u32, ReadWrite>,
|
general_configuration_register: Volatile<&'static mut u32, ReadWrite>,
|
||||||
general_interrupt_status_register: Volatile<&'static mut u32, ReadWrite>,
|
general_interrupt_status_register: Volatile<&'static mut u32, ReadWrite>,
|
||||||
|
|
||||||
timer_registers: Vec<Volatile<&'static mut HPETTimerRegister, ReadWrite>>,
|
timer_registers: Vec<Volatile<&'static mut HpetTimerRegister, ReadWrite>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HPET {
|
impl Hpet {
|
||||||
fn new(base_address: usize) -> HPET {
|
fn new(base_address: usize) -> Hpet {
|
||||||
let information_register_ref = unsafe {
|
let information_register_ref = unsafe {
|
||||||
&*(phys_to_virt(base_address + OFFSET_ID_REGISTER) as *mut usize as *mut u32)
|
&*(phys_to_virt(base_address + OFFSET_ID_REGISTER) as *mut usize as *mut u32)
|
||||||
};
|
};
|
||||||
@ -59,7 +59,7 @@ impl HPET {
|
|||||||
for i in 0..num_comparator {
|
for i in 0..num_comparator {
|
||||||
let comp = Volatile::new(unsafe {
|
let comp = Volatile::new(unsafe {
|
||||||
&mut *(phys_to_virt(base_address + 0x100 + i as usize * 0x20) as *mut usize
|
&mut *(phys_to_virt(base_address + 0x100 + i as usize * 0x20) as *mut usize
|
||||||
as *mut HPETTimerRegister)
|
as *mut HpetTimerRegister)
|
||||||
});
|
});
|
||||||
comparators.push(comp);
|
comparators.push(comp);
|
||||||
}
|
}
|
||||||
@ -74,7 +74,7 @@ impl HPET {
|
|||||||
.lock()
|
.lock()
|
||||||
.enable(vector, destination_apic_id);
|
.enable(vector, destination_apic_id);
|
||||||
|
|
||||||
HPET {
|
Hpet {
|
||||||
information_register,
|
information_register,
|
||||||
general_configuration_register,
|
general_configuration_register,
|
||||||
general_interrupt_status_register,
|
general_interrupt_status_register,
|
||||||
@ -110,7 +110,7 @@ pub fn init() -> Result<(), AcpiError> {
|
|||||||
let hpet_info = HpetInfo::new(&*c)?;
|
let hpet_info = HpetInfo::new(&*c)?;
|
||||||
|
|
||||||
// config IO APIC entry
|
// config IO APIC entry
|
||||||
let hpet = HPET::new(hpet_info.base_address);
|
let hpet = Hpet::new(hpet_info.base_address);
|
||||||
HPET_INSTANCE.call_once(|| hpet);
|
HPET_INSTANCE.call_once(|| hpet);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -9,14 +9,14 @@ pub(crate) const IA32_APIC_BASE_MSR_ENABLE: u64 = 0x800;
|
|||||||
|
|
||||||
const APIC_LVT_MASK_BITS: u32 = 1 << 16;
|
const APIC_LVT_MASK_BITS: u32 = 1 << 16;
|
||||||
|
|
||||||
pub(crate) static XAPIC_INSTANCE: Once<Mutex<XAPIC>> = Once::new();
|
pub(crate) static XAPIC_INSTANCE: Once<Mutex<Xapic>> = Once::new();
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct XAPIC {
|
pub struct Xapic {
|
||||||
mmio_region: &'static mut [u32],
|
mmio_region: &'static mut [u32],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl XAPIC {
|
impl Xapic {
|
||||||
pub fn new(address: usize) -> Self {
|
pub fn new(address: usize) -> Self {
|
||||||
let region: &'static mut [u32] = unsafe { &mut *(address as *mut [u32; 256]) };
|
let region: &'static mut [u32] = unsafe { &mut *(address as *mut [u32; 256]) };
|
||||||
Self {
|
Self {
|
||||||
@ -47,7 +47,7 @@ pub(crate) fn has_apic() -> bool {
|
|||||||
pub(crate) fn init() {
|
pub(crate) fn init() {
|
||||||
super::pic::disable_temp();
|
super::pic::disable_temp();
|
||||||
|
|
||||||
let mut apic = XAPIC::new(vm::phys_to_virt(get_apic_base_address()));
|
let mut apic = Xapic::new(vm::phys_to_virt(get_apic_base_address()));
|
||||||
// enable apic
|
// enable apic
|
||||||
set_apic_base_address(get_apic_base_address());
|
set_apic_base_address(get_apic_base_address());
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use super::page_table::{PTFlags, PageTable};
|
use super::page_table::{PageTable, PageTableFlags};
|
||||||
use crate::{
|
use crate::{
|
||||||
config::PAGE_SIZE,
|
config::PAGE_SIZE,
|
||||||
vm::is_page_aligned,
|
vm::is_page_aligned,
|
||||||
@ -11,7 +11,7 @@ use core::fmt;
|
|||||||
use super::frame_allocator;
|
use super::frame_allocator;
|
||||||
|
|
||||||
pub struct MapArea {
|
pub struct MapArea {
|
||||||
pub flags: PTFlags,
|
pub flags: PageTableFlags,
|
||||||
pub start_va: Vaddr,
|
pub start_va: Vaddr,
|
||||||
pub size: usize,
|
pub size: usize,
|
||||||
pub mapper: BTreeMap<Vaddr, VmFrame>,
|
pub mapper: BTreeMap<Vaddr, VmFrame>,
|
||||||
@ -46,9 +46,16 @@ impl MapArea {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// This function will map the vitural address to the given physical frames
|
/// This function will map the vitural address to the given physical frames
|
||||||
pub fn new(start_va: Vaddr, size: usize, flags: PTFlags, physical_frames: VmFrameVec) -> Self {
|
pub fn new(
|
||||||
|
start_va: Vaddr,
|
||||||
|
size: usize,
|
||||||
|
flags: PageTableFlags,
|
||||||
|
physical_frames: VmFrameVec,
|
||||||
|
) -> Self {
|
||||||
assert!(
|
assert!(
|
||||||
is_page_aligned(start_va) && is_page_aligned(size) && physical_frames.len() == (size / PAGE_SIZE)
|
is_page_aligned(start_va)
|
||||||
|
&& is_page_aligned(size)
|
||||||
|
&& physical_frames.len() == (size / PAGE_SIZE)
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut map_area = Self {
|
let mut map_area = Self {
|
||||||
@ -193,7 +200,7 @@ impl MemorySet {
|
|||||||
let mut offset = 0usize;
|
let mut offset = 0usize;
|
||||||
for (va, area) in self.areas.iter_mut() {
|
for (va, area) in self.areas.iter_mut() {
|
||||||
if current_addr >= *va && current_addr < area.size + va {
|
if current_addr >= *va && current_addr < area.size + va {
|
||||||
if !area.flags.contains(PTFlags::WRITABLE) {
|
if !area.flags.contains(PageTableFlags::WRITABLE) {
|
||||||
return Err(Error::PageFault);
|
return Err(Error::PageFault);
|
||||||
}
|
}
|
||||||
let write_len = remain.min(area.size + va - current_addr);
|
let write_len = remain.min(area.size + va - current_addr);
|
||||||
@ -235,7 +242,7 @@ impl MemorySet {
|
|||||||
Err(Error::PageFault)
|
Err(Error::PageFault)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn protect(&mut self, addr: Vaddr, flags: PTFlags) {
|
pub fn protect(&mut self, addr: Vaddr, flags: PageTableFlags) {
|
||||||
let va = addr;
|
let va = addr;
|
||||||
self.pt.protect(va, flags)
|
self.pt.protect(va, flags)
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,8 @@ use super::{
|
|||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
config::{ENTRY_COUNT, PAGE_SIZE, PHYS_OFFSET},
|
config::{ENTRY_COUNT, PAGE_SIZE, PHYS_OFFSET},
|
||||||
vm::VmFrame, AlignExt,
|
vm::VmFrame,
|
||||||
|
AlignExt,
|
||||||
};
|
};
|
||||||
use alloc::{collections::BTreeMap, vec, vec::Vec};
|
use alloc::{collections::BTreeMap, vec, vec::Vec};
|
||||||
use core::{fmt, panic};
|
use core::{fmt, panic};
|
||||||
@ -19,9 +20,9 @@ lazy_static! {
|
|||||||
|
|
||||||
bitflags::bitflags! {
|
bitflags::bitflags! {
|
||||||
/// Possible flags for a page table entry.
|
/// Possible flags for a page table entry.
|
||||||
pub struct PTFlags: usize {
|
pub struct PageTableFlags: usize {
|
||||||
/// Specifies whether the mapped frame or page table is loaded in memory.
|
/// Specifies whether the mapped frame or page table is loaded in memory.
|
||||||
const PRESENT = 1;
|
const PRESENT = 1 << 0;
|
||||||
/// Controls whether writes to the mapped frames are allowed.
|
/// Controls whether writes to the mapped frames are allowed.
|
||||||
const WRITABLE = 1 << 1;
|
const WRITABLE = 1 << 1;
|
||||||
/// Controls whether accesses from userspace (i.e. ring 3) are permitted.
|
/// Controls whether accesses from userspace (i.e. ring 3) are permitted.
|
||||||
@ -46,20 +47,20 @@ pub struct PageTableEntry(usize);
|
|||||||
impl PageTableEntry {
|
impl PageTableEntry {
|
||||||
const PHYS_ADDR_MASK: usize = !(PAGE_SIZE - 1);
|
const PHYS_ADDR_MASK: usize = !(PAGE_SIZE - 1);
|
||||||
|
|
||||||
pub const fn new_page(pa: Paddr, flags: PTFlags) -> Self {
|
pub const fn new_page(pa: Paddr, flags: PageTableFlags) -> Self {
|
||||||
Self((pa & Self::PHYS_ADDR_MASK) | flags.bits)
|
Self((pa & Self::PHYS_ADDR_MASK) | flags.bits)
|
||||||
}
|
}
|
||||||
const fn pa(self) -> Paddr {
|
const fn pa(self) -> Paddr {
|
||||||
self.0 as usize & Self::PHYS_ADDR_MASK
|
self.0 as usize & Self::PHYS_ADDR_MASK
|
||||||
}
|
}
|
||||||
const fn flags(self) -> PTFlags {
|
const fn flags(self) -> PageTableFlags {
|
||||||
PTFlags::from_bits_truncate(self.0)
|
PageTableFlags::from_bits_truncate(self.0)
|
||||||
}
|
}
|
||||||
const fn is_unused(self) -> bool {
|
const fn is_unused(self) -> bool {
|
||||||
self.0 == 0
|
self.0 == 0
|
||||||
}
|
}
|
||||||
const fn is_present(self) -> bool {
|
const fn is_present(self) -> bool {
|
||||||
(self.0 & PTFlags::PRESENT.bits) != 0
|
(self.0 & PageTableFlags::PRESENT.bits) != 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,7 +94,7 @@ impl PageTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn map(&mut self, va: Vaddr, pa: Paddr, flags: PTFlags) {
|
pub fn map(&mut self, va: Vaddr, pa: Paddr, flags: PageTableFlags) {
|
||||||
let entry = self.get_entry_or_create(va).unwrap();
|
let entry = self.get_entry_or_create(va).unwrap();
|
||||||
if !entry.is_unused() {
|
if !entry.is_unused() {
|
||||||
panic!("{:#x?} is mapped before mapping", va);
|
panic!("{:#x?} is mapped before mapping", va);
|
||||||
@ -109,13 +110,13 @@ impl PageTable {
|
|||||||
entry.0 = 0;
|
entry.0 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn protect(&mut self, va: Vaddr, flags: PTFlags) {
|
pub fn protect(&mut self, va: Vaddr, flags: PageTableFlags) {
|
||||||
let entry = self.get_entry_or_create(va).unwrap();
|
let entry = self.get_entry_or_create(va).unwrap();
|
||||||
if entry.is_unused() || !entry.is_present() {
|
if entry.is_unused() || !entry.is_present() {
|
||||||
panic!("{:#x?} is invalid before protect", va);
|
panic!("{:#x?} is invalid before protect", va);
|
||||||
}
|
}
|
||||||
// clear old mask
|
// clear old mask
|
||||||
let clear_flags_mask = !PTFlags::all().bits;
|
let clear_flags_mask = !PageTableFlags::all().bits;
|
||||||
entry.0 &= clear_flags_mask;
|
entry.0 &= clear_flags_mask;
|
||||||
// set new mask
|
// set new mask
|
||||||
entry.0 |= flags.bits;
|
entry.0 |= flags.bits;
|
||||||
@ -203,7 +204,10 @@ fn next_table_or_create<'a>(
|
|||||||
) -> Option<&'a mut [PageTableEntry]> {
|
) -> Option<&'a mut [PageTableEntry]> {
|
||||||
if entry.is_unused() {
|
if entry.is_unused() {
|
||||||
let pa = alloc();
|
let pa = alloc();
|
||||||
*entry = PageTableEntry::new_page(pa, PTFlags::PRESENT | PTFlags::WRITABLE | PTFlags::USER);
|
*entry = PageTableEntry::new_page(
|
||||||
|
pa,
|
||||||
|
PageTableFlags::PRESENT | PageTableFlags::WRITABLE | PageTableFlags::USER,
|
||||||
|
);
|
||||||
Some(table_of(pa))
|
Some(table_of(pa))
|
||||||
} else {
|
} else {
|
||||||
next_table(entry)
|
next_table(entry)
|
||||||
@ -242,7 +246,7 @@ pub(crate) fn init() {
|
|||||||
p4[0].0 = 0;
|
p4[0].0 = 0;
|
||||||
let mut map_pte = ALL_MAPPED_PTE.lock();
|
let mut map_pte = ALL_MAPPED_PTE.lock();
|
||||||
for i in 0..512 {
|
for i in 0..512 {
|
||||||
if p4[i].flags().contains(PTFlags::PRESENT) {
|
if p4[i].flags().contains(PageTableFlags::PRESENT) {
|
||||||
map_pte.insert(i, p4[i]);
|
map_pte.insert(i, p4[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::config::PAGE_SIZE;
|
use crate::config::PAGE_SIZE;
|
||||||
use crate::vm::page_table::PTFlags;
|
use crate::vm::page_table::PageTableFlags;
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
use core::ops::Range;
|
use core::ops::Range;
|
||||||
use spin::Mutex;
|
use spin::Mutex;
|
||||||
@ -54,7 +54,7 @@ impl VmSpace {
|
|||||||
///
|
///
|
||||||
/// For more information, see `VmMapOptions`.
|
/// For more information, see `VmMapOptions`.
|
||||||
pub fn map(&self, frames: VmFrameVec, options: &VmMapOptions) -> Result<Vaddr> {
|
pub fn map(&self, frames: VmFrameVec, options: &VmMapOptions) -> Result<Vaddr> {
|
||||||
let flags = PTFlags::from(options.perm);
|
let flags = PageTableFlags::from(options.perm);
|
||||||
if options.addr.is_none() {
|
if options.addr.is_none() {
|
||||||
return Err(Error::InvalidArgs);
|
return Err(Error::InvalidArgs);
|
||||||
}
|
}
|
||||||
@ -106,7 +106,7 @@ impl VmSpace {
|
|||||||
debug_assert!(range.end % PAGE_SIZE == 0);
|
debug_assert!(range.end % PAGE_SIZE == 0);
|
||||||
let start_page = range.start / PAGE_SIZE;
|
let start_page = range.start / PAGE_SIZE;
|
||||||
let end_page = range.end / PAGE_SIZE;
|
let end_page = range.end / PAGE_SIZE;
|
||||||
let flags = PTFlags::from(perm);
|
let flags = PageTableFlags::from(perm);
|
||||||
for page_idx in start_page..end_page {
|
for page_idx in start_page..end_page {
|
||||||
let addr = page_idx * PAGE_SIZE;
|
let addr = page_idx * PAGE_SIZE;
|
||||||
self.memory_set.lock().protect(addr, flags)
|
self.memory_set.lock().protect(addr, flags)
|
||||||
@ -238,15 +238,15 @@ impl TryFrom<u64> for VmPerm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<VmPerm> for PTFlags {
|
impl From<VmPerm> for PageTableFlags {
|
||||||
fn from(vm_perm: VmPerm) -> Self {
|
fn from(vm_perm: VmPerm) -> Self {
|
||||||
let mut flags = PTFlags::PRESENT | PTFlags::USER;
|
let mut flags = PageTableFlags::PRESENT | PageTableFlags::USER;
|
||||||
if vm_perm.contains(VmPerm::W) {
|
if vm_perm.contains(VmPerm::W) {
|
||||||
flags |= PTFlags::WRITABLE;
|
flags |= PageTableFlags::WRITABLE;
|
||||||
}
|
}
|
||||||
// FIXME: how to respect executable flags?
|
// FIXME: how to respect executable flags?
|
||||||
if !vm_perm.contains(VmPerm::X) {
|
if !vm_perm.contains(VmPerm::X) {
|
||||||
flags |= PTFlags::NO_EXECUTE;
|
flags |= PageTableFlags::NO_EXECUTE;
|
||||||
}
|
}
|
||||||
flags
|
flags
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user