diff --git a/src/arch/aarch64/device/uart_pl011.rs b/src/arch/aarch64/device/uart_pl011.rs index 61315e9e21..c7431d971e 100644 --- a/src/arch/aarch64/device/uart_pl011.rs +++ b/src/arch/aarch64/device/uart_pl011.rs @@ -4,6 +4,7 @@ use crate::scheme::debug::{debug_input, debug_notify}; bitflags! { /// UARTFR + #[derive(Clone, Copy, Debug)] struct UartFrFlags: u32 { const TXFE = 1 << 7; const RXFF = 1 << 6; @@ -15,6 +16,7 @@ bitflags! { bitflags! { /// UARTCR + #[derive(Clone, Copy, Debug)] struct UartCrFlags: u32 { const RXE = 1 << 9; const TXE = 1 << 8; @@ -24,6 +26,7 @@ bitflags! { bitflags! { // UARTIMSC + #[derive(Clone, Copy, Debug)] struct UartImscFlags: u32 { const RTIM = 1 << 6; const TXIM = 1 << 5; @@ -33,6 +36,7 @@ bitflags! { bitflags! { // UARTICR + #[derive(Clone, Copy, Debug)] struct UartIcrFlags: u32 { const RTIC = 1 << 6; const TXIC = 1 << 5; @@ -42,6 +46,7 @@ bitflags! { bitflags! { // UARTRIS + #[derive(Clone, Copy, Debug)] struct UartRisFlags: u32 { const RTIS = 1 << 6; const TXIS = 1 << 5; @@ -51,6 +56,7 @@ bitflags! { bitflags! { //UARTMIS + #[derive(Clone, Copy, Debug)] struct UartMisFlags: u32 { const TXMIS = 1 << 5; const RXMIS = 1 << 4; @@ -59,6 +65,7 @@ bitflags! { bitflags! { //UARTLCR_H + #[derive(Clone, Copy, Debug)] struct UartLcrhFlags: u32 { const FEN = 1 << 4; } @@ -66,6 +73,7 @@ bitflags! { bitflags! { //UARTIFLS + #[derive(Clone, Copy, Debug)] struct UartIflsFlags: u32 { const RX1_8 = 0 << 3; const RX2_8 = 1 << 3; @@ -187,7 +195,7 @@ impl SerialPort { pub fn receive(&mut self) { let mut flags = self.intr_stats(); let chk_flags = UartRisFlags::RTIS | UartRisFlags::RXIS; - while (flags & chk_flags).bits != 0 { + while (flags & chk_flags).bits() != 0 { if self.cts_event_walkaround { self.write_reg(self.intr_clr_reg, 0x00); let _ = self.read_reg(self.intr_clr_reg); @@ -195,7 +203,7 @@ impl SerialPort { } let clr = flags & (!chk_flags); - self.write_reg(self.intr_clr_reg, clr.bits); + self.write_reg(self.intr_clr_reg, clr.bits()); for _ in 0..256 { if self.line_sts().contains(UartFrFlags::RXFE) { diff --git a/src/arch/aarch64/interrupt/mod.rs b/src/arch/aarch64/interrupt/mod.rs index 9ddc914683..58942de83c 100644 --- a/src/arch/aarch64/interrupt/mod.rs +++ b/src/arch/aarch64/interrupt/mod.rs @@ -10,7 +10,7 @@ pub mod irq; pub mod syscall; pub mod trace; -use crate::LogicalCpuId; +use crate::cpu_set::LogicalCpuId; pub use self::{handler::InterruptStack, trace::stack_trace}; diff --git a/src/arch/aarch64/ipi.rs b/src/arch/aarch64/ipi.rs index 3f8e5cd779..30c29a17d2 100644 --- a/src/arch/aarch64/ipi.rs +++ b/src/arch/aarch64/ipi.rs @@ -22,3 +22,11 @@ pub fn ipi(_kind: IpiKind, _target: IpiTarget) {} #[cfg(feature = "multi_core")] #[inline(always)] pub fn ipi(kind: IpiKind, target: IpiTarget) {} + +#[cfg(not(feature = "multi_core"))] +#[inline(always)] +pub fn ipi_single(_kind: IpiKind, _target: crate::cpu_set::LogicalCpuId) {} + +#[cfg(feature = "multi_core")] +#[inline(always)] +pub fn ipi_single(kind: IpiKind, target: crate::cpu_set::LogicalCpuId) {} diff --git a/src/arch/aarch64/misc.rs b/src/arch/aarch64/misc.rs index f2828bc6ac..ed9edbdfb2 100644 --- a/src/arch/aarch64/misc.rs +++ b/src/arch/aarch64/misc.rs @@ -1,7 +1,10 @@ +use core::cell::{Cell, RefCell}; +use core::sync::atomic::AtomicBool; + use crate::{ + cpu_set::LogicalCpuId, paging::{RmmA, RmmArch}, percpu::PercpuBlock, - LogicalCpuId, }; impl PercpuBlock { @@ -18,6 +21,9 @@ pub unsafe fn init(cpu_id: LogicalCpuId) { virt.write(PercpuBlock { cpu_id, switch_internals: crate::context::switch::ContextSwitchPercpu::default(), + current_addrsp: RefCell::new(None), + new_addrsp_tmp: Cell::new(None), + wants_tlb_shootdown: AtomicBool::new(false), }); crate::device::cpu::registers::control_regs::tpidr_el1_write(virt as u64); diff --git a/src/arch/aarch64/rmm.rs b/src/arch/aarch64/rmm.rs index 04dae8814a..51e33ed93d 100644 --- a/src/arch/aarch64/rmm.rs +++ b/src/arch/aarch64/rmm.rs @@ -9,7 +9,7 @@ use rmm::{ }; use spin::Mutex; -use crate::{init::device_tree::MEMORY_MAP, paging::entry::EntryFlags, LogicalCpuId}; +use crate::{init::device_tree::MEMORY_MAP, paging::entry::EntryFlags, cpu_set::LogicalCpuId}; use super::CurrentRmmArch as RmmA; diff --git a/src/arch/aarch64/start.rs b/src/arch/aarch64/start.rs index e47cc5c0e0..d00cda1de7 100644 --- a/src/arch/aarch64/start.rs +++ b/src/arch/aarch64/start.rs @@ -164,7 +164,7 @@ pub unsafe extern "C" fn kstart(args_ptr: *const KernelArgs) -> ! { // Initialize paging paging::init(); - crate::misc::init(crate::LogicalCpuId(0)); + crate::misc::init(crate::cpu_set::LogicalCpuId::new(0)); // Reset AP variables CPU_COUNT.store(1, Ordering::SeqCst); diff --git a/src/context/arch/aarch64.rs b/src/context/arch/aarch64.rs index 3521c9b632..86137259d5 100644 --- a/src/context/arch/aarch64.rs +++ b/src/context/arch/aarch64.rs @@ -14,6 +14,7 @@ use crate::{ paging::{RmmA, RmmArch, TableKind}, pop_scratch, push_scratch, syscall::FloatRegisters, + percpu::PercpuBlock, }; /// This must be used by the kernel to ensure that context switches are done atomically @@ -229,31 +230,7 @@ pub unsafe fn switch_to(prev: &mut super::Context, next: &mut super::Context) { ); } - match next.addr_space { - // Since Arc is essentially just wraps a pointer, in this case a regular pointer (as - // opposed to dyn or slice fat pointers), and NonNull optimization exists, map_or will - // hopefully be optimized down to checking prev and next pointers, as next cannot be null. - Some(ref next_space) => { - if prev - .addr_space - .as_ref() - .map_or(true, |prev_space| !Arc::ptr_eq(&prev_space, &next_space)) - { - // Suppose we have two sibling threads A and B. A runs on CPU 0 and B on CPU 1. A - // recently called yield and is now here about to switch back. Meanwhile, B is - // currently creating a new mapping in their shared address space, for example a - // message on a channel. - // - // Unless we acquire this lock, it may be possible that the TLB will not contain new - // entries. While this can be caught and corrected in a page fault handler, this is not - // true when entries are removed from a page table! - next_space.read().table.utable.make_current(); - } - } - None => { - RmmA::set_table(TableKind::User, empty_cr3()); - } - } + PercpuBlock::current().new_addrsp_tmp.set(next.addr_space.clone()); switch_to_inner(&mut prev.arch, &mut next.arch) } diff --git a/src/debugger.rs b/src/debugger.rs index e51872e87b..6e4a5a8c15 100644 --- a/src/debugger.rs +++ b/src/debugger.rs @@ -34,10 +34,10 @@ pub unsafe fn debugger(target_id: Option) { // Switch to context page table to ensure syscall debug and stack dump will work if let Some(ref space) = context.addr_space { - let new_as = spaces.insert(space.read().table.utable.table().phys().data()); + let new_as = spaces.insert(space.acquire_read().table.utable.table().phys().data()); - RmmA::set_table(TableKind::User, space.read().table.utable.table().phys()); - check_consistency(&mut *space.write(), new_as, &mut tree); + RmmA::set_table(TableKind::User, space.acquire_read().table.utable.table().phys()); + check_consistency(&mut *space.acquire_write(), new_as, &mut tree); if let Some((a, b, c, d, e, f)) = context.syscall { println!( @@ -47,7 +47,7 @@ pub unsafe fn debugger(target_id: Option) { } { - let space = space.read(); + let space = space.acquire_read(); if !space.grants.is_empty() { println!("grants:"); for (base, grant) in space.grants.iter() { @@ -72,7 +72,7 @@ pub unsafe fn debugger(target_id: Option) { for _ in 0..64 { if context.addr_space.as_ref().map_or(false, |space| { space - .read() + .acquire_read() .table .utable .translate(crate::paging::VirtualAddress::new(sp)) diff --git a/src/percpu.rs b/src/percpu.rs index 33f6b476c6..69e15548ef 100644 --- a/src/percpu.rs +++ b/src/percpu.rs @@ -74,7 +74,7 @@ impl PercpuBlock { // TODO: Finer-grained flush unsafe { - x86::tlb::flush_all(); + crate::paging::RmmA::invalidate_all(); } if let Some(ref addrsp) = &*self.current_addrsp.borrow() {