From 0e8860c719e96c211bbb1292ffcec9b8e34f6232 Mon Sep 17 00:00:00 2001 From: Mark Poliakov Date: Thu, 4 Jan 2024 23:04:34 +0200 Subject: [PATCH] arch/aarch64: fix aarch64 build --- Cargo.toml | 6 +- src/arch/aarch64/boot/mod.rs | 12 ++- src/arch/aarch64/cpu.rs | 138 ++++++++++++++++++++------------ src/arch/aarch64/exception.rs | 10 +-- src/arch/aarch64/gic/gicc.rs | 3 +- src/arch/aarch64/gic/gicd.rs | 3 +- src/arch/aarch64/gic/mod.rs | 18 +++-- src/arch/aarch64/mem/mod.rs | 34 ++++---- src/arch/aarch64/mem/process.rs | 28 ++++--- src/arch/aarch64/mem/table.rs | 28 ++++--- src/arch/aarch64/mod.rs | 56 ++++++------- src/arch/aarch64/timer.rs | 4 +- src/arch/mod.rs | 16 +++- src/device/devtree.rs | 6 +- src/device/serial/pl011.rs | 23 ++++-- src/task/sched.rs | 1 + 16 files changed, 228 insertions(+), 158 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b51c072b..cf505ff5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,9 +19,6 @@ vmalloc = { path = "lib/vmalloc" } device-api-macros = { path = "lib/device-api/macros" } # Drivers -ygg_driver_pci = { path = "driver/bus/pci" } -ygg_driver_nvme = { path = "driver/block/nvme" } -ygg_driver_ahci = { path = "driver/block/ahci" } ygg_driver_block = { path = "driver/block/core" } kernel-fs = { path = "driver/fs/kernel-fs" } memfs = { path = "driver/fs/memfs" } @@ -57,6 +54,9 @@ acpi_lib = { git = "https://github.com/alnyan/acpi.git", package = "acpi", branc acpi-system = { git = "https://github.com/alnyan/acpi-system.git" } # TODO currently only supported here xhci_lib = { git = "https://github.com/rust-osdev/xhci.git", package = "xhci" } +ygg_driver_pci = { path = "driver/bus/pci" } +ygg_driver_nvme = { path = "driver/block/nvme" } +ygg_driver_ahci = { path = "driver/block/ahci" } [features] default = ["fb_console"] diff --git a/src/arch/aarch64/boot/mod.rs b/src/arch/aarch64/boot/mod.rs index 65adfc33..734e41b8 100644 --- a/src/arch/aarch64/boot/mod.rs +++ b/src/arch/aarch64/boot/mod.rs @@ -5,6 +5,14 @@ use aarch64_cpu::{ asm::barrier, registers::{CPACR_EL1, ID_AA64MMFR0_EL1, MAIR_EL1, SCTLR_EL1, TCR_EL1, TTBR0_EL1}, }; +use kernel_fs::devfs; +use kernel_util::{ + mem::{ + address::{IntoRaw, PhysicalAddress}, + table::EntryLevel, + }, + runtime, +}; use tock_registers::interfaces::{ReadWriteable, Readable, Writeable}; use super::{ @@ -13,10 +21,8 @@ use super::{ }; use crate::{ arch::{aarch64::mem::table::L3, Architecture}, - fs::devfs, kernel_main, kernel_secondary_main, - mem::{address::IntoRaw, phys, table::EntryLevel, PhysicalAddress, KERNEL_VIRT_OFFSET}, - task::runtime, + mem::{phys, KERNEL_VIRT_OFFSET}, }; unsafe fn pre_init_mmu() { diff --git a/src/arch/aarch64/cpu.rs b/src/arch/aarch64/cpu.rs index 177927d2..70c46a8c 100644 --- a/src/arch/aarch64/cpu.rs +++ b/src/arch/aarch64/cpu.rs @@ -1,12 +1,22 @@ //! Per-CPU data structures -use core::sync::atomic::Ordering; +use core::{ + ops::{Deref, DerefMut}, + sync::atomic::Ordering, +}; use aarch64_cpu::registers::{MPIDR_EL1, TPIDR_EL1}; use alloc::{boxed::Box, vec::Vec}; -use kernel_util::{sync::IrqSafeSpinlock, util::OneTimeInit}; +use kernel_util::{ + sync::{IrqGuard, IrqSafeSpinlock}, + util::OneTimeInit, +}; use tock_registers::interfaces::{Readable, Writeable}; -use crate::{arch::CpuMessage, panic, task::sched::CpuQueue}; +use crate::{ + arch::{CpuAccess, CpuMessage, LocalCpuAccess}, + panic, + task::{sched::CpuQueue, thread::ThreadId}, +}; use super::smp::CPU_COUNT; @@ -18,8 +28,17 @@ pub struct Cpu { id: u32, queue: OneTimeInit<&'static CpuQueue>, + thread_id: Option, } +/// Handle allowing safe access to the local CPU. +/// +/// # Note +/// +/// Obtaining this handle prevents IRQs from being delivered to ensure the context having this +/// struct cannot be interrupted by another (which could obtain it as well). +pub struct LocalCpu(&'static mut Cpu, IrqGuard); + struct IpiQueue { data: IrqSafeSpinlock>, } @@ -47,17 +66,11 @@ impl IpiQueue { } impl Cpu { - /// Returns a safe reference to the local CPU's private data structure - #[inline(always)] - pub fn local<'a>() -> &'a Self { - Self::get_local().unwrap() - } - - /// Returns the local CPU data structure reference, if it was set up - #[inline(always)] - pub fn get_local<'a>() -> Option<&'a Self> { - let tpidr = TPIDR_EL1.get() as *mut Cpu; - unsafe { tpidr.as_ref() } + /// Sets up global list of interprocessor message queues + pub fn init_ipi_queues() { + IPI_QUEUES.init(Vec::from_iter( + (0..CPU_COUNT.load(Ordering::Acquire)).map(|_| IpiQueue::new()), + )); } /// Sets up the local CPU's private data structure. @@ -69,60 +82,81 @@ impl Cpu { let this = Box::new(Cpu { id: Self::local_id(), queue: OneTimeInit::new(), + thread_id: None, }); TPIDR_EL1.set(Box::into_raw(this) as _); } +} - /// Sets up the local CPU's execution queue. - pub fn init_queue(&self, queue: &'static CpuQueue) { - self.queue.init(queue); +impl CpuAccess for Cpu { + type Local = LocalCpu; + + fn id(&self) -> u32 { + self.id } - /// Returns the local CPU's execution queue. - pub fn queue(&self) -> &'static CpuQueue { - self.queue.get() - } - - /// Returns the index of the local CPU - #[inline(always)] - pub fn local_id() -> u32 { + fn local_id() -> u32 { (MPIDR_EL1.get() & 0xFF) as _ } - /// Inserts an IPI message to the back of the target CPU's message queue - pub fn push_ipi_queue(cpu_id: u32, msg: CpuMessage) { - let ipi_queue = &IPI_QUEUES.get()[cpu_id as usize]; - ipi_queue.push(msg); + fn try_local() -> Option { + let guard = IrqGuard::acquire(); + let tpidr = TPIDR_EL1.get() as *mut Cpu; + unsafe { tpidr.as_mut() }.map(|cpu| LocalCpu(cpu, guard)) } - /// Pops the first IPI message received for this CPU. - /// - /// # Note - /// - /// Currently the queue consists of only one entry, so the CPU will only receive the last one. - pub fn get_ipi(&self) -> Option { - let ipi_queue = &IPI_QUEUES.get()[self.id as usize]; - ipi_queue.pop() + fn get_queue(&self) -> Option<&'static CpuQueue> { + self.queue.try_get().copied() } - /// Sets up global list of interprocessor message queues - pub fn init_ipi_queues() { - IPI_QUEUES.init(Vec::from_iter( - (0..CPU_COUNT.load(Ordering::Acquire)).map(|_| IpiQueue::new()), - )); + fn init_queue(&mut self, queue: &'static CpuQueue) { + self.queue.init(queue); } - /// Gets an IPI message from the processor's queue and takes corresponding actions. If there is - /// none, this is treated as a spurious IPI and ignored. See [CpuMessage]. - pub fn handle_ipi(&self) { - let Some(msg) = self.get_ipi() else { - warnln!("Spurious IPI in cpu{}", self.id); - return; - }; + unsafe fn set_current_thread_id(&mut self, id: Option) { + self.thread_id = id; + } - match msg { - CpuMessage::Panic => panic::panic_secondary(), - CpuMessage::Shutdown => todo!(), + fn current_thread_id(&self) -> Option { + self.thread_id + } + + fn push_ipi(id: u32, msg: CpuMessage) { + if let Some(q) = IPI_QUEUES.try_get().and_then(|q| q.get(id as usize)) { + q.push(msg); + } + } + + fn handle_ipi(&mut self) { + if let Some(ipi) = IPI_QUEUES + .try_get() + .and_then(|q| q.get(self.id() as usize)) + .and_then(|q| q.pop()) + { + match ipi { + CpuMessage::Panic => panic::panic_secondary(), + CpuMessage::Shutdown => todo!(), + } } } } + +impl LocalCpuAccess for LocalCpu { + fn into_guard(self) -> IrqGuard { + self.1 + } +} + +impl Deref for LocalCpu { + type Target = Cpu; + + fn deref(&self) -> &Self::Target { + self.0 + } +} + +impl DerefMut for LocalCpu { + fn deref_mut(&mut self) -> &mut Self::Target { + self.0 + } +} diff --git a/src/arch/aarch64/exception.rs b/src/arch/aarch64/exception.rs index 6984c228..50152751 100644 --- a/src/arch/aarch64/exception.rs +++ b/src/arch/aarch64/exception.rs @@ -323,11 +323,7 @@ fn el0_sync_inner(frame: &mut ExceptionFrame) { // BRK in AArch64 0b111100 => { let thread = Thread::current(); - warnln!( - "Thread {} {:?} hit a breakpoint", - thread.id(), - thread.name() - ); + warnln!("Thread {} {:?} hit a breakpoint", thread.id, thread.name); thread.raise_signal(Signal::Aborted); } _ => { @@ -337,8 +333,8 @@ fn el0_sync_inner(frame: &mut ExceptionFrame) { let thread = Thread::current(); warnln!( "Data abort in {} {:?} at {:#x} with address {:#x}", - thread.id(), - thread.name(), + thread.id, + thread.name, ELR_EL1.get(), FAR_EL1.get() ); diff --git a/src/arch/aarch64/gic/gicc.rs b/src/arch/aarch64/gic/gicc.rs index 1f11d485..745c236c 100644 --- a/src/arch/aarch64/gic/gicc.rs +++ b/src/arch/aarch64/gic/gicc.rs @@ -1,12 +1,11 @@ //! ARM GICv2 CPU registers +use kernel_util::mem::device::DeviceMemoryIo; use tock_registers::{ interfaces::{Readable, Writeable}, register_bitfields, register_structs, registers::ReadWrite, }; -use crate::mem::device::DeviceMemoryIo; - register_bitfields! { u32, CTLR [ diff --git a/src/arch/aarch64/gic/gicd.rs b/src/arch/aarch64/gic/gicd.rs index 60314cc8..dc1aaf2c 100644 --- a/src/arch/aarch64/gic/gicd.rs +++ b/src/arch/aarch64/gic/gicd.rs @@ -1,5 +1,6 @@ //! ARM GICv2 Distributor registers use device_api::interrupt::IpiDeliveryTarget; +use kernel_util::mem::device::DeviceMemoryIo; use spinning_top::Spinlock; use tock_registers::{ interfaces::{ReadWriteable, Readable, Writeable}, @@ -7,8 +8,6 @@ use tock_registers::{ registers::{ReadOnly, ReadWrite, WriteOnly}, }; -use crate::mem::device::DeviceMemoryIo; - register_bitfields! { u32, CTLR [ diff --git a/src/arch/aarch64/gic/mod.rs b/src/arch/aarch64/gic/mod.rs index f912f143..bad6b6b9 100644 --- a/src/arch/aarch64/gic/mod.rs +++ b/src/arch/aarch64/gic/mod.rs @@ -12,17 +12,19 @@ use device_api::{ }, Device, }; -use kernel_util::{sync::IrqSafeSpinlock, util::OneTimeInit}; +use kernel_util::{ + mem::{ + address::{FromRaw, PhysicalAddress}, + device::{DeviceMemoryIo, RawDeviceMemoryMapping}, + }, + sync::IrqSafeSpinlock, + util::OneTimeInit, +}; use crate::{ - arch::{aarch64::IrqNumber, Architecture, CpuMessage}, + arch::{aarch64::IrqNumber, Architecture, CpuAccess, CpuMessage}, device::devtree::{self, DevTreeIndexPropExt}, device_tree_driver, - mem::{ - address::FromRaw, - device::{DeviceMemoryIo, RawDeviceMemoryMapping}, - PhysicalAddress, - }, }; use self::{gicc::Gicc, gicd::Gicd}; @@ -141,7 +143,7 @@ impl LocalInterruptController for Gic { let local = Cpu::local_id(); for i in 0..CPU_COUNT.load(Ordering::Acquire) { if i != local as usize { - Cpu::push_ipi_queue(i as u32, msg); + Cpu::push_ipi(i as u32, msg); } } } diff --git a/src/arch/aarch64/mem/mod.rs b/src/arch/aarch64/mem/mod.rs index e607f048..b596b426 100644 --- a/src/arch/aarch64/mem/mod.rs +++ b/src/arch/aarch64/mem/mod.rs @@ -6,19 +6,21 @@ use core::{ use abi::error::Error; use cfg_if::cfg_if; -use kernel_util::util::OneTimeInit; +use kernel_util::{ + mem::{ + address::{FromRaw, PhysicalAddress}, + device::RawDeviceMemoryMapping, + table::{EntryLevel, EntryLevelExt}, + }, + util::OneTimeInit, +}; use memtables::aarch64::{FixedTables, KERNEL_L3_COUNT}; use aarch64_cpu::registers::{TTBR0_EL1, TTBR1_EL1}; use static_assertions::const_assert_eq; use tock_registers::interfaces::Writeable; -use crate::mem::{ - address::{FromRaw, IntoRaw, KernelImageObject}, - device::RawDeviceMemoryMapping, - table::EntryLevel, - PhysicalAddress, KERNEL_VIRT_OFFSET, -}; +use crate::mem::{address::KernelImageObject, KERNEL_VIRT_OFFSET}; use self::table::{PageAttributes, PageEntry, PageTable, L1, L2, L3}; @@ -36,8 +38,8 @@ cfg_if! { } // Precomputed mappings -const KERNEL_L1_INDEX: usize = L1::index(KERNEL_VIRT_OFFSET + KERNEL_PHYS_BASE); -const KERNEL_START_L2_INDEX: usize = L2::index(KERNEL_VIRT_OFFSET + KERNEL_PHYS_BASE); +const KERNEL_L1_INDEX: usize = (KERNEL_VIRT_OFFSET + KERNEL_PHYS_BASE).page_index::(); +const KERNEL_START_L2_INDEX: usize = (KERNEL_VIRT_OFFSET + KERNEL_PHYS_BASE).page_index::(); const KERNEL_END_L2_INDEX: usize = KERNEL_START_L2_INDEX + KERNEL_L3_COUNT; // Must not be zero, should be at 4MiB @@ -177,7 +179,7 @@ unsafe fn unmap_early_page(address: usize) { panic!("Tried to unmap invalid early mapping: {:#x}", address); } - let l3i = L3::index(address - EARLY_MAPPING_OFFSET); + let l3i = (address - EARLY_MAPPING_OFFSET).page_index::(); assert!(EARLY_MAPPING_L3[l3i].is_present()); EARLY_MAPPING_L3[l3i] = PageEntry::INVALID; @@ -262,14 +264,14 @@ pub(super) unsafe fn map_device_memory( ) -> Result { // debugln!("Map {}B @ {:#x}", size, base); let l3_aligned = base.page_align_down::(); - let l3_offset = L3::page_offset(base.into_raw()); - let page_count = (l3_offset + size + L3::SIZE - 1) / L3::SIZE; + let l3_offset = base.page_offset::(); + let page_count = (l3_offset + size).page_count::(); if page_count > 256 { // Large mapping, use L2 mapping instead let l2_aligned = base.page_align_down::(); - let l2_offset = L2::page_offset(base.into_raw()); - let page_count = (l2_offset + size + L2::SIZE - 1) / L2::SIZE; + let l2_offset = base.page_offset::(); + let page_count = (l2_offset + size).page_count::(); let base_address = map_device_memory_l2(l2_aligned, page_count)?; let address = base_address + l2_offset; @@ -304,8 +306,8 @@ pub(super) unsafe fn unmap_device_memory(map: &RawDeviceMemoryMapping) { L3::SIZE => { for i in 0..map.page_count { let page = map.base_address + i * L3::SIZE; - let l2i = L2::index(page); - let l3i = L3::index(page); + let l2i = page.page_index::(); + let l3i = page.page_index::(); assert!(DEVICE_MAPPING_L3S[l2i][l3i].is_present()); DEVICE_MAPPING_L3S[l2i][l3i] = PageEntry::INVALID; diff --git a/src/arch/aarch64/mem/process.rs b/src/arch/aarch64/mem/process.rs index 51f740c6..bedc8b8e 100644 --- a/src/arch/aarch64/mem/process.rs +++ b/src/arch/aarch64/mem/process.rs @@ -2,14 +2,16 @@ use core::sync::atomic::{AtomicU8, Ordering}; use abi::error::Error; +use kernel_util::mem::{ + address::{AsPhysicalAddress, PhysicalAddress}, + pointer::PhysicalRefMut, + table::{EntryLevel, EntryLevelExt}, +}; use crate::mem::{ - address::AsPhysicalAddress, phys, - pointer::PhysicalRefMut, process::ProcessAddressSpaceManager, - table::{EntryLevel, MapAttributes, NextPageTable}, - PhysicalAddress, + table::{MapAttributes, NextPageTable}, }; use super::table::{PageEntry, PageTable, L1, L2, L3}; @@ -75,9 +77,9 @@ impl ProcessAddressSpaceImpl { entry: PageEntry, overwrite: bool, ) -> Result<(), Error> { - let l1i = L1::index(virt); - let l2i = L2::index(virt); - let l3i = L3::index(virt); + let l1i = virt.page_index::(); + let l2i = virt.page_index::(); + let l3i = virt.page_index::(); let mut l2 = self.l1.get_mut_or_alloc(l1i)?; let mut l3 = l2.get_mut_or_alloc(l2i)?; @@ -93,9 +95,9 @@ impl ProcessAddressSpaceImpl { } fn pop_l3_entry(&mut self, virt: usize) -> Result { - let l1i = L1::index(virt); - let l2i = L2::index(virt); - let l3i = L3::index(virt); + let l1i = virt.page_index::(); + let l2i = virt.page_index::(); + let l3i = virt.page_index::(); // TODO somehow drop tables if they're known to be empty? let mut l2 = self.l1.get_mut(l1i).ok_or(Error::DoesNotExist)?; @@ -110,9 +112,9 @@ impl ProcessAddressSpaceImpl { } fn read_l3_entry(&self, virt: usize) -> Option<(PhysicalAddress, MapAttributes)> { - let l1i = L1::index(virt); - let l2i = L2::index(virt); - let l3i = L3::index(virt); + let l1i = virt.page_index::(); + let l2i = virt.page_index::(); + let l3i = virt.page_index::(); let l2 = self.l1.get(l1i)?; let l3 = l2.get(l2i)?; diff --git a/src/arch/aarch64/mem/table.rs b/src/arch/aarch64/mem/table.rs index 36daff94..f61f2c32 100644 --- a/src/arch/aarch64/mem/table.rs +++ b/src/arch/aarch64/mem/table.rs @@ -5,13 +5,15 @@ use core::{ use abi::error::Error; use bitflags::bitflags; +use kernel_util::mem::{ + address::{AsPhysicalAddress, FromRaw, IntoRaw, PhysicalAddress}, + pointer::{PhysicalRef, PhysicalRefMut}, + table::EntryLevel, +}; use crate::mem::{ - address::{AsPhysicalAddress, FromRaw, IntoRaw}, phys, - pointer::{PhysicalRef, PhysicalRefMut}, - table::{EntryLevel, MapAttributes, NextPageTable, NonTerminalEntryLevel}, - PhysicalAddress, + table::{MapAttributes, NextPageTable, NonTerminalEntryLevel}, }; bitflags! { @@ -60,23 +62,23 @@ pub struct L2; #[derive(Clone, Copy)] pub struct L3; -impl const EntryLevel for L1 { - const SHIFT: usize = 30; -} - impl NonTerminalEntryLevel for L1 { type NextLevel = L2; } -impl const EntryLevel for L2 { - const SHIFT: usize = 21; -} - impl NonTerminalEntryLevel for L2 { type NextLevel = L3; } -impl const EntryLevel for L3 { +impl EntryLevel for L1 { + const SHIFT: usize = 30; +} + +impl EntryLevel for L2 { + const SHIFT: usize = 21; +} + +impl EntryLevel for L3 { const SHIFT: usize = 12; } diff --git a/src/arch/aarch64/mod.rs b/src/arch/aarch64/mod.rs index 5f3b3ddf..d76beadd 100644 --- a/src/arch/aarch64/mod.rs +++ b/src/arch/aarch64/mod.rs @@ -13,7 +13,15 @@ use device_api::{ }; use fdt_rs::base::DevTree; use git_version::git_version; -use kernel_util::util::OneTimeInit; +use kernel_util::{ + mem::{ + address::{FromRaw, IntoRaw, PhysicalAddress}, + device::RawDeviceMemoryMapping, + pointer::PhysicalRef, + table::{EntryLevel, EntryLevelExt}, + }, + util::OneTimeInit, +}; use tock_registers::interfaces::{ReadWriteable, Readable, Writeable}; use crate::{ @@ -29,13 +37,8 @@ use crate::{ }, fs::{Initrd, INITRD_DATA}, mem::{ - address::{FromRaw, IntoRaw}, - device::RawDeviceMemoryMapping, heap, phys::{self, reserved::reserve_region, PhysicalMemoryRegion}, - pointer::PhysicalRef, - table::EntryLevel, - PhysicalAddress, }, }; @@ -80,6 +83,8 @@ impl Architecture for AArch64 { type IrqNumber = IrqNumber; + type L3 = L3; + unsafe fn start_application_processors(&self) { let dt = self.dt.get(); if let Err(error) = smp::start_ap_cores(dt) { @@ -125,7 +130,7 @@ impl Architecture for AArch64 { _memory_start: PhysicalAddress, memory_end: PhysicalAddress, ) -> Result<(), Error> { - let end_l1i = L1::index(memory_end.page_align_up::().into_raw()); + let end_l1i = memory_end.page_align_up::().page_index::(); if end_l1i > mem::RAM_MAPPING_L1_COUNT { todo!() } @@ -142,25 +147,23 @@ impl Architecture for AArch64 { Ok(()) } - fn virtualize(address: PhysicalAddress) -> Result { - let raw: usize = address.into_raw(); - if raw < *mem::MEMORY_LIMIT.get() { - Ok(raw + mem::RAM_MAPPING_OFFSET) + fn virtualize(address: u64) -> usize { + let address = address as usize; + if address < *mem::MEMORY_LIMIT.get() { + address + mem::RAM_MAPPING_OFFSET } else { - errorln!("Invalid physical address: {:#x}", address); - Err(Error::InvalidMemoryOperation) + panic!("Invalid physical address: {:#x}", address); } } - fn physicalize(address: usize) -> Result { + fn physicalize(address: usize) -> u64 { if address < mem::RAM_MAPPING_OFFSET || address - mem::RAM_MAPPING_OFFSET >= *mem::MEMORY_LIMIT.get() { - errorln!("Not a virtualized physical address: {:#x}", address); - return Err(Error::InvalidMemoryOperation); + panic!("Not a virtualized physical address: {:#x}", address); } - Ok(PhysicalAddress::from_raw(address - mem::RAM_MAPPING_OFFSET)) + (address - mem::RAM_MAPPING_OFFSET) as _ } fn local_interrupt_controller( @@ -362,23 +365,22 @@ impl AArch64 { infoln!("Initializing aarch64 platform"); let nodes = dt.root().children(); - if let Err(error) = devtree::enumerate_dt( - address_cells, - size_cells, - nodes, - |_, probe| { + if let Err(error) = + devtree::enumerate_dt(address_cells, size_cells, nodes, |_, probe| { // Skip chosen-stdout, already initialized - if let Some(ref chosen_stdout) = chosen_stdout && chosen_stdout.name() == probe.node.name() { - return Ok(()); - } + if let Some(ref chosen_stdout) = chosen_stdout + && chosen_stdout.name() == probe.node.name() + { + return Ok(()); + } if let Some((device, _)) = devtree::probe_dt_node(&probe) { device.init()?; } Ok(()) - }, - ) { + }) + { warnln!( "{} errors encountered when initializing platform devices", error diff --git a/src/arch/aarch64/timer.rs b/src/arch/aarch64/timer.rs index 9a7fe43e..6c463b53 100644 --- a/src/arch/aarch64/timer.rs +++ b/src/arch/aarch64/timer.rs @@ -6,12 +6,12 @@ use aarch64_cpu::registers::{CNTFRQ_EL0, CNTPCT_EL0, CNTP_CTL_EL0, CNTP_TVAL_EL0 use abi::error::Error; use alloc::boxed::Box; use device_api::{interrupt::InterruptHandler, timer::MonotonicTimestampProviderDevice, Device}; +use kernel_util::runtime; use tock_registers::interfaces::{ReadWriteable, Readable, Writeable}; use crate::{ - arch::{aarch64::IrqNumber, Architecture, ARCHITECTURE}, + arch::{aarch64::IrqNumber, Architecture, CpuAccess, ARCHITECTURE}, device_tree_driver, - task::runtime, }; use super::cpu::Cpu; diff --git a/src/arch/mod.rs b/src/arch/mod.rs index 58b7c2c3..2332174f 100644 --- a/src/arch/mod.rs +++ b/src/arch/mod.rs @@ -251,7 +251,9 @@ pub trait CpuAccess: Sized { } /// Returns the ID of the local processor or 0 if the processor has not yet been initialized - fn local_id() -> u32; + fn local_id() -> u32 { + Self::try_local().map(|cpu| cpu.id()).unwrap_or(0) + } /// Initializes the CPU's scheduling queue. /// @@ -281,6 +283,18 @@ pub trait CpuAccess: Sized { /// /// Only meant to be called from within the scheduler. unsafe fn set_current_thread_id(&mut self, id: Option); + + /// Push an IPI message to the CPU's queue + fn push_ipi(id: u32, msg: CpuMessage) { + let _ = id; + let _ = msg; + // Not implemented by default + } + + /// Pops an IPI message (if any is present) from the CPU's queue and handles it + fn handle_ipi(&mut self) { + // Not implemented by default + } } // External API for architecture specifics diff --git a/src/device/devtree.rs b/src/device/devtree.rs index 3009ceaa..19733857 100644 --- a/src/device/devtree.rs +++ b/src/device/devtree.rs @@ -9,11 +9,9 @@ use fdt_rs::{ index::{iters::DevTreeIndexNodeSiblingIter, DevTreeIndex, DevTreeIndexNode, DevTreeIndexProp}, prelude::PropReader, }; +use kernel_util::mem::address::{FromRaw, PhysicalAddress}; -use crate::{ - debug::LogLevel, - mem::{address::FromRaw, phys::PhysicalMemoryRegion, PhysicalAddress}, -}; +use crate::{debug::LogLevel, mem::phys::PhysicalMemoryRegion}; use super::register_device; diff --git a/src/device/serial/pl011.rs b/src/device/serial/pl011.rs index 58910108..4114bb20 100644 --- a/src/device/serial/pl011.rs +++ b/src/device/serial/pl011.rs @@ -2,25 +2,32 @@ use abi::{error::Error, io::DeviceRequest}; use alloc::boxed::Box; use device_api::{interrupt::InterruptHandler, serial::SerialDevice, Device}; -use kernel_util::{sync::IrqSafeSpinlock, util::OneTimeInit}; +use futures_util::task::{Context, Poll}; +use kernel_fs::devfs::{self, CharDeviceType}; +use kernel_util::{ + block, + mem::{ + address::{FromRaw, PhysicalAddress}, + device::DeviceMemoryIo, + }, + sync::IrqSafeSpinlock, + util::OneTimeInit, +}; use tock_registers::{ interfaces::{ReadWriteable, Readable, Writeable}, register_bitfields, register_structs, registers::{ReadOnly, ReadWrite, WriteOnly}, }; -use vfs::CharDevice; +use vfs::{CharDevice, FileReadiness}; use crate::{ arch::{aarch64::IrqNumber, Architecture, ARCHITECTURE}, - block, debug::{self, DebugSink, LogLevel}, device::{ devtree::{self, DevTreeIndexPropExt}, tty::{TtyContext, TtyDevice}, }, device_tree_driver, - fs::devfs::{self, CharDeviceType}, - mem::{address::FromRaw, device::DeviceMemoryIo, PhysicalAddress}, task::process::ProcessId, }; @@ -108,6 +115,12 @@ impl TtyDevice for Pl011 { } } +impl FileReadiness for Pl011 { + fn poll_read(&self, _cx: &mut Context<'_>) -> Poll> { + todo!() + } +} + // impl CharDevice for Pl011 { // fn write(&self, blocking: bool, data: &[u8]) -> Result { // assert!(blocking); diff --git a/src/task/sched.rs b/src/task/sched.rs index 1398f96a..c19eb529 100644 --- a/src/task/sched.rs +++ b/src/task/sched.rs @@ -214,5 +214,6 @@ static QUEUES: OneTimeInit> = OneTimeInit::new(); /// Initializes the global queue list pub fn init_queues(queues: Vec) { + debugln!("init_queues!!!"); QUEUES.init(queues); }