refactor: Fix all clippy warnings

This commit is contained in:
Mark Poliakov 2024-03-13 01:54:00 +02:00
parent c5699db3a5
commit 55a4c89811
47 changed files with 218 additions and 90 deletions

View File

@ -115,6 +115,9 @@ pub struct EarlyMapping<'a, T: ?Sized> {
}
impl<'a, T: Sized> EarlyMapping<'a, T> {
/// # Safety
///
/// `physical` address provided must be a valid non-NULL address actually containing `T`.
pub unsafe fn map_slice(
physical: PhysicalAddress,
len: usize,
@ -216,6 +219,9 @@ unsafe fn unmap_early_page(address: usize) {
// TODO invalidate tlb
}
/// # Safety
///
/// Only meant to be used by the architecture initialization functions.
pub unsafe fn map_ram_l1(index: usize) {
if index >= RAM_MAPPING_L1_COUNT {
todo!()
@ -226,6 +232,9 @@ pub unsafe fn map_ram_l1(index: usize) {
((index * L1::SIZE) as u64) | ram_block_flags().bits();
}
/// # Safety
///
/// Only meant to be used by the architecture initialization functions.
pub unsafe fn map_heap_l2(index: usize, page: PhysicalAddress) {
if index >= 512 {
todo!()
@ -295,7 +304,7 @@ unsafe fn map_device_memory_l2(
Err(Error::OutOfMemory)
}
pub unsafe fn map_device_memory(
pub(crate) unsafe fn map_device_memory(
base: PhysicalAddress,
size: usize,
attrs: DeviceMemoryAttributes,
@ -334,7 +343,7 @@ pub unsafe fn map_device_memory(
}
}
pub unsafe fn unmap_device_memory(map: &RawDeviceMemoryMapping<KernelTableManagerImpl>) {
pub(crate) unsafe fn unmap_device_memory(map: &RawDeviceMemoryMapping<KernelTableManagerImpl>) {
// debugln!(
// "Unmap {}B @ {:#x}",
// map.page_count * map.page_size,

View File

@ -174,9 +174,6 @@ where
table_ref.drop_all::<TA>();
// Drop the table
drop(table_ref);
TA::free_page_table(table);
} else if entry.is_present() {
// Memory must've been cleared beforehand, so no non-table entries must be present

View File

@ -66,6 +66,9 @@ impl<A: Architecture, S: Scheduler + 'static> CpuImpl<A, S> {
self.scheduler.get()
}
/// # Safety
///
/// See [Architecture::set_local_cpu].
pub unsafe fn set_local(&'static mut self) {
A::set_local_cpu(self as *mut _ as *mut _)
}

View File

@ -21,9 +21,19 @@ pub trait Architecture: Sized {
type PerCpuData;
// Cpu management
/// # Safety
///
/// Precondition: this function has not yet been called on the local CPU.
unsafe fn set_local_cpu(cpu: *mut ());
fn local_cpu() -> *mut ();
/// # Safety
///
/// Precondition: this function has not yet been called on the local CPU.
unsafe fn init_ipi_queues(queues: Vec<IpiQueue<Self>>);
/// # Safety
///
/// Precondition: this function has not yet been called on the local CPU.
unsafe fn init_local_cpu<S: Scheduler + 'static>(id: Option<u32>, data: Self::PerCpuData);
fn idle_task() -> extern "C" fn(usize) -> !;
@ -33,6 +43,9 @@ pub trait Architecture: Sized {
// Interrupt management
fn interrupt_mask() -> bool;
/// # Safety
///
/// The caller must ensure it is actually safe to enable interrupts in the current context.
unsafe fn set_interrupt_mask(mask: bool) -> bool;
fn wait_for_interrupt();

View File

@ -11,6 +11,12 @@ pub trait PhysicalMemoryAllocator {
fn allocate_page() -> Result<Self::Address, Error>;
fn allocate_contiguous_pages(count: usize) -> Result<Self::Address, Error>;
/// # Safety
///
/// Preconditions:
///
/// * The page must have been obtained through [PhysicalMemoryAllocator::allocate_page] first;
/// * The caller must guarantee the page will not be used after this call.
unsafe fn free_page(page: Self::Address);
}
@ -45,11 +51,18 @@ pub trait KernelTableManager: Sized + fmt::Debug {
fn virtualize(phys: u64) -> usize;
fn physicalize(virt: usize) -> u64;
/// # Safety
///
/// The caller must ensure the `base..base + count` region is not aliased by some other code,
/// points to a valid chunk of device memory.
unsafe fn map_device_pages(
base: u64,
count: usize,
attrs: DeviceMemoryAttributes,
) -> Result<RawDeviceMemoryMapping<Self>, Error>;
/// # Safety
///
/// Only meant to be called from "safer" wrappers like [RawDeviceMemoryMapping].
unsafe fn unmap_device_pages(mapping: &RawDeviceMemoryMapping<Self>);
}
@ -87,6 +100,10 @@ impl<A: KernelTableManager> RawDeviceMemoryMapping<A> {
(address, base_address, page_count, page_size)
}
/// # Safety
///
/// Preconditions: all the fields must come from a [RawDeviceMemoryMapping::into_raw_parts]
/// call.
pub unsafe fn from_raw_parts(
address: usize,
base_address: usize,
@ -103,11 +120,11 @@ impl<A: KernelTableManager> RawDeviceMemoryMapping<A> {
}
/// "Casts" the mapping to a specific type T and returns a [NonNull] pointer to it
pub unsafe fn as_non_null<T>(&self) -> NonNull<T> {
pub fn as_non_null<T>(&self) -> NonNull<T> {
if self.page_size * self.page_count < size_of::<T>() {
panic!();
}
NonNull::new_unchecked(self.address as *mut T)
unsafe { NonNull::new_unchecked(self.address as *mut T) }
}
}

View File

@ -1,4 +1,5 @@
#![no_std]
#![allow(clippy::new_without_default)]
#![feature(
effects,
strict_provenance,

View File

@ -269,6 +269,9 @@ unsafe fn unmap_device_memory(map: &RawDeviceMemoryMapping<KernelTableManagerImp
}
}
/// # Safety
///
/// Only meant to be called from memory initialization routines.
pub unsafe fn map_heap_block(index: usize, page: PhysicalAddress) {
if !page.is_page_aligned_for::<L2>() {
panic!("Attempted to map a misaligned 2MiB page");
@ -290,6 +293,9 @@ pub struct EarlyMapping<'a, T: ?Sized> {
}
impl<'a, T: Sized> EarlyMapping<'a, T> {
/// # Safety
///
/// `physical` address provided must be a valid non-NULL address actually containing `T`.
pub unsafe fn map(physical: PhysicalAddress) -> Result<EarlyMapping<'a, T>, Error> {
let layout = Layout::new::<T>();
let aligned = physical.page_align_down::<L3>();
@ -302,6 +308,10 @@ impl<'a, T: Sized> EarlyMapping<'a, T> {
Ok(EarlyMapping { value, page_count })
}
/// # Safety
///
/// `physical` address provided must be a valid non-NULL address actually containing a `T`
/// slice of given `len`.
pub unsafe fn map_slice(
physical: PhysicalAddress,
len: usize,
@ -365,6 +375,10 @@ pub fn clone_kernel_tables(dst: &mut PageTable<L0>) {
/// * 0xFFFFFF8080000000 .. 0xFFFFFF8100000000 : DEVICE_MAPPING_L2
/// * 0xFFFFFF8080000000 .. 0xFFFFFF8080800000 : DEVICE_MAPPING_L3S
/// * 0xFFFFFF8080800000 .. 0xFFFFFF8100000000 : ...
///
/// # Safety
///
/// 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 early_mapping_l3_phys = addr_of!(EARLY_MAPPING_L3) as usize - KERNEL_VIRT_OFFSET;
@ -399,6 +413,9 @@ pub unsafe fn init_fixed_tables() {
CR3.set_address(cr3);
}
/// # Safety
///
/// `address` must be page-aligned.
#[inline]
pub unsafe fn flush_tlb_entry(address: usize) {
core::arch::asm!("invlpg ({0})", in(reg) address, options(att_syntax));

View File

@ -278,9 +278,6 @@ where
table_ref.drop_all::<TA>();
// Drop the table
drop(table_ref);
TA::free_page_table(table);
} else if entry.is_present() {
// Memory must've been cleared beforehand, so no non-table entries must be present

View File

@ -416,10 +416,16 @@ impl FpuContext {
value
}
/// # Safety
///
/// Only meant to be called from a context switch routine.
pub unsafe fn save(dst: *mut FpuContext) {
core::arch::asm!("fxsave64 ({})", in(reg) dst, options(att_syntax));
}
/// # Safety
///
/// Only meant to be called from a context switch routine.
pub unsafe fn restore(src: *mut FpuContext) {
core::arch::asm!("fxrstor64 ({})", in(reg) src, options(att_syntax));
}

View File

@ -62,7 +62,7 @@ fn main() {
let out_dir = env::var("OUT_DIR").unwrap();
let arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
generate_syscall_dispatcher(&out_dir);
generate_syscall_dispatcher(out_dir);
println!("cargo:rerun-if-changed=build.rs");

View File

@ -74,7 +74,7 @@ impl AhciController {
let mut fis_buffers = [const { None }; 16];
// Allocate FIS receive buffers for the ports
for i in 0..self.max_port_count {
for (i, fis_buffer_slot) in fis_buffers.iter_mut().enumerate().take(self.max_port_count) {
if pi & (1 << i) == 0 {
continue;
}
@ -84,7 +84,7 @@ impl AhciController {
let buffer = PageBox::new(ReceivedFis::zeroed()).map_err(AhciError::MemoryError)?;
port.set_received_fis_address_64(unsafe { buffer.as_physical_address() });
fis_buffers[i] = Some(buffer);
*fis_buffer_slot = Some(buffer);
}
self.received_fis_buffers.init(fis_buffers);

View File

@ -226,6 +226,10 @@ pub trait PciConfigurationSpace {
PciInterruptPin::try_from(self.read_u8(0x3D) as u32).ok()
}
/// # Safety
///
/// This function is only meant to be called before the device has seen any use by the OS,
/// it has not been tested outside of this use case.
unsafe fn bar_size(&self, index: usize) -> usize {
let cmd = self.command();
@ -264,6 +268,11 @@ pub trait PciConfigurationSpace {
/// The function is only valid for devices with `header_type() == 0`
///
/// The `index` corresponds to the actual configuration space BAR index.
///
/// # Safety
///
/// Precondition: the device must have memory access disabled through its command register
/// prior to setting a BAR.
unsafe fn set_bar(&self, index: usize, value: PciBaseAddress) {
assert!(index < 6);

View File

@ -64,7 +64,7 @@ async fn extract_class_info(device: &UsbDeviceAccess) -> Result<Option<UsbClassI
async fn pick_driver(
device: &UsbDeviceAccess,
) -> Result<Option<Arc<dyn UsbDriver + 'static>>, UsbError> {
let Some(class) = extract_class_info(&device).await? else {
let Some(class) = extract_class_info(device).await? else {
return Ok(None);
};
@ -184,9 +184,9 @@ pub mod hid_keyboard {
) -> usize {
let mut count = 0;
let released = self.mods & !m;
for i in 0..8 {
for (i, modifier) in MODIFIER_MAP.iter().enumerate().take(8) {
if released & (1 << i) != 0 {
events[count].write(KeyboardKeyEvent::Released(MODIFIER_MAP[i]));
events[count].write(KeyboardKeyEvent::Released(*modifier));
count += 1;
}
}
@ -201,9 +201,9 @@ pub mod hid_keyboard {
) -> usize {
let mut count = 0;
let pressed = m & !self.mods;
for i in 0..8 {
for (i, modifier) in MODIFIER_MAP.iter().enumerate().take(8) {
if pressed & (1 << i) != 0 {
events[count].write(KeyboardKeyEvent::Pressed(MODIFIER_MAP[i]));
events[count].write(KeyboardKeyEvent::Pressed(*modifier));
count += 1;
}
}
@ -218,13 +218,10 @@ pub mod hid_keyboard {
) -> usize {
let mut count = 0;
for i in 1..256 {
if self.state[i / 64] & (1 << (i % 64)) != 0 {
if !keys.contains(&(i as u8)) {
events[count]
.write(KeyboardKeyEvent::Released(Self::translate_key(i as u8)));
self.state[i / 64] &= !(1 << (i % 64));
count += 1;
}
if self.state[i / 64] & (1 << (i % 64)) != 0 && !keys.contains(&(i as u8)) {
events[count].write(KeyboardKeyEvent::Released(Self::translate_key(i as u8)));
self.state[i / 64] &= !(1 << (i % 64));
count += 1;
}
}
count

View File

@ -43,8 +43,8 @@ pub trait UsbDevice: Send + Sync {
// Endpoint "0"
fn control_pipe(&self) -> &UsbControlPipeAccess;
fn open_interrupt_in_pipe<'a>(
&'a self,
fn open_interrupt_in_pipe(
&self,
number: u8,
) -> BoxFuture<Result<UsbInterruptInPipeAccess, UsbError>> {
unimplemented!()

View File

@ -1,4 +1,5 @@
#![no_std]
#![allow(clippy::new_without_default)]
#![feature(iter_array_chunks, maybe_uninit_slice)]
extern crate alloc;

View File

@ -73,7 +73,7 @@ fn decode_usb_string(bytes: &[u8]) -> Result<String, UsbError> {
char::decode_utf16(
bytes
.into_iter()
.iter()
.array_chunks::<2>()
.map(|[&a, &b]| u16::from_le_bytes([a, b])),
)

View File

@ -119,8 +119,8 @@ impl UsbDevice for XhciBusDevice {
self.xhci
}
fn open_interrupt_in_pipe<'a>(
&'a self,
fn open_interrupt_in_pipe(
&self,
number: u8,
) -> BoxFuture<Result<UsbInterruptInPipeAccess, UsbError>> {
async move {

View File

@ -1,4 +1,5 @@
#![no_std]
#![allow(clippy::new_without_default)]
#![feature(iter_array_chunks)]
extern crate alloc;
@ -99,7 +100,7 @@ pub fn probe(info: &PciDeviceInfo) -> Result<&'static dyn Device, Error> {
cmd |= PciCommandRegister::ENABLE_MEMORY | PciCommandRegister::BUS_MASTER;
info.config_space.set_command(cmd.bits());
let regs = unsafe { xhci_lib::Registers::new(bar0.try_into().unwrap(), Mapper::new()) };
let regs = unsafe { xhci_lib::Registers::new(bar0.into(), Mapper::new()) };
let xhci = Box::leak(Box::new(Xhci::new(regs)?));
info.init_interrupts(PreferredInterruptMode::Msi)?;

View File

@ -107,8 +107,7 @@ impl CommandRing {
pub fn enqueue<C: CommandTrb>(&self, trb: C) -> PhysicalAddress {
let mut inner = self.inner.lock();
let address = inner.enqueue(trb);
address
inner.enqueue(trb)
}
pub async fn address_device<E: CommandExecutor, const N: usize>(

View File

@ -177,6 +177,9 @@ impl VirtQueue {
Self::with_capacity(transport, index, capacity, msix_vector, no_avail_irq)
}
/// # Safety
///
/// Invariants: PageBox remains valid and allocated until it is properly dequeued.
pub unsafe fn add<'a, 'b>(
&mut self,
input: &'a [&'b mut PageBox<[u8]>],
@ -288,14 +291,14 @@ impl VirtQueue {
self.last_used_idx == self.used.index()
}
pub unsafe fn pop_last_used(&mut self) -> Option<(u16, u32)> {
pub fn pop_last_used(&mut self) -> Option<(u16, u32)> {
let token = self.peek_used()?;
let len = self.pop_used(token).unwrap();
let len = unsafe { self.pop_used(token) }.unwrap();
Some((token, len))
}
pub unsafe fn peek_used(&mut self) -> Option<u16> {
fn peek_used(&mut self) -> Option<u16> {
if !self.is_used_empty() {
let last_used = self.last_used_idx % self.capacity as u16;
Some(self.used.read_slot(last_used).0 as u16)
@ -304,7 +307,7 @@ impl VirtQueue {
}
}
pub unsafe fn pop_used(&mut self, token: u16) -> Result<u32, Error> {
unsafe fn pop_used(&mut self, token: u16) -> Result<u32, Error> {
if self.is_used_empty() {
return Err(Error::QueueEmpty);
}

View File

@ -64,7 +64,7 @@ impl Queues {
pub fn try_receive(&self, _index: usize) -> Option<(u16, IrqSafeSpinlockGuard<VirtQueue>)> {
let mut queue = self.receive.lock();
// TODO use len for packet size hint
let (token, _len) = unsafe { queue.pop_last_used() }?;
let (token, _len) = queue.pop_last_used()?;
Some((token, queue))
}
}
@ -179,11 +179,8 @@ impl<T: Transport> VirtioNet<T> {
let receive_vector = if let Some(pci) = self.pci_device_info.as_ref() {
pci.init_interrupts(PreferredInterruptMode::Msi)?;
let info = pci.map_interrupt(InterruptAffinity::Any, self)?;
if let Some(info) = info {
Some(info.vector as u16)
} else {
None
}
info.map(|info| info.vector as u16)
} else {
None
};
@ -234,6 +231,7 @@ impl<T: Transport + 'static> NetworkDevice for VirtioNet<T> {
impl<T: Transport + 'static> InterruptHandler for VirtioNet<T> {
fn handle_irq(&self, vector: Option<usize>) -> bool {
#[allow(clippy::redundant_pattern_matching)]
if let Some(_) = vector {
// MSI/MSI-X
let Some(queues) = self.queues.try_get() else {

View File

@ -99,10 +99,7 @@ pub fn probe_dt_node<F: FnOnce(&'static dyn Device) -> DeviceId>(
register: F,
) -> Option<(&'static dyn Device, DeviceId)> {
// TODO use list, not just the first item
let Some(compatible) = dt.node.prop("compatible") else {
return None;
};
let compatible = dt.node.prop("compatible")?;
let probe = dt_match_compatible(compatible)?;
let device = Box::leak((probe.probe_func)(dt)?);
let id = register(device);

View File

@ -30,6 +30,7 @@ pub type TNode<'a> = DevTreeIndexNode<'a, 'a, 'a>;
pub type TProp<'a> = DevTreeIndexProp<'a, 'a, 'a>;
/// Helper trait to provide extra functionality for [DevTreeIndexProp]
#[allow(clippy::len_without_is_empty)]
pub trait DevTreeIndexPropExt {
/// Reads a cell value from single-type cell array at given cell index
fn cell1_array_item(&self, index: usize, cells: usize) -> Option<u64>;
@ -142,7 +143,14 @@ impl<'a> DeviceTree<'a> {
chosen.prop("stdout-path")
}
/// Returns the length of the header provided as a slice of bytes
/// Returns the length of the header provided as a slice of bytes.
///
/// # Safety
///
/// Preconditions:
///
/// * `header` is at least u32-aligned;
/// * `header` points to a slice of at least [DevTree::MIN_HEADER_SIZE] bytes.
pub unsafe fn read_totalsize(header: &[u8]) -> Result<usize, Error> {
DevTree::read_totalsize(header).map_err(|_| Error::InvalidArgument)
}

View File

@ -253,8 +253,8 @@ impl File {
Self::Regular(file) => Some(&file.node),
Self::Block(file) => Some(&file.node),
Self::Char(file) => Some(&file.node),
Self::PtyMaster(_, node) => Some(&node),
Self::PtySlave(_, node) => Some(&node),
Self::PtyMaster(_, node) => Some(node),
Self::PtySlave(_, node) => Some(node),
_ => None,
}
}

View File

@ -327,10 +327,10 @@ impl IoContext {
let token = self.check_access(Action::Read, at)?;
// let _path = link.imp.read_to_string()?;
match at.read_symlink_node(token) {
Ok(node) => return Ok(node),
Ok(node) => Ok(node),
// Need to read the link data and resolve it manually
Err(Error::NotImplemented) => todo!(),
Err(e) => return Err(e),
Err(e) => Err(e),
}
}
@ -437,8 +437,8 @@ mod tests {
let mut ioctx = IoContext::new(root.clone());
let uid = UserId::from(1);
let gid = GroupId::from(1);
let uid = unsafe { UserId::from_raw(1) };
let gid = unsafe { GroupId::from_raw(1) };
// 1:1
ioctx.set_uid_unchecked(uid);

View File

@ -75,7 +75,10 @@ enum NodeImpl {
Symlink(SymlinkData),
// These map transparently to other types of nodes
// TODO: implement open operation on these
#[allow(unused)]
PseudoTerminalSlave(Arc<PseudoTerminalSlave>),
#[allow(unused)]
PseudoTerminalMaster(Arc<PseudoTerminalMaster>),
}

View File

@ -42,6 +42,11 @@ pub trait ProcessAddressSpaceManager<TA: TableAllocator>: Sized {
/// Returns the implementation specific physical address of this space, with ASID applied
fn as_address_with_asid(&self) -> u64;
/// Clears the address space by dropping and non-global tables
/// Clears the address space by dropping and non-global tables.
///
/// # Safety
///
/// Meant to be called when a process is being dropped or a new image is being loaded,
/// replacing the old mappings. All the mappings become invalid after this call.
unsafe fn clear(&mut self);
}

View File

@ -15,6 +15,9 @@ pub trait EntryLevel: Copy {
pub trait TableAllocator {
fn allocate_page_table() -> Result<PhysicalAddress, Error>;
/// # Safety
///
/// `address` must point to a real translation table allocated by this trait impl.
unsafe fn free_page_table(address: PhysicalAddress);
}
@ -53,10 +56,20 @@ pub trait EntryLevelDrop {
/// Range covering the whole table
const FULL_RANGE: Range<usize>;
/// Recursively destroys the specified range within the table
/// Recursively destroys the specified range within the table.
///
/// # Safety
///
/// Caller must ensure the unmapped range is not in use by some other thread and will not be
/// referred to from this point.
unsafe fn drop_range<TA: TableAllocator>(&mut self, range: Range<usize>);
/// Recursively destroys all the entries in within the table
///
/// # Safety
///
/// Caller must ensure the unmapped range is not in use by some other thread and will not be
/// referred to from this point.
unsafe fn drop_all<TA: TableAllocator>(&mut self) {
self.drop_range::<TA>(Self::FULL_RANGE)
}

View File

@ -215,15 +215,6 @@ impl<T> PageBox<MaybeUninit<T>> {
PageBox { value, page_count }
}
pub unsafe fn into_byte_slice(self) -> PageBox<[u8]> {
let page_count = self.page_count;
let value = MaybeUninit::slice_assume_init_mut(MaybeUninit::as_bytes_mut(&mut *self.value));
core::mem::forget(self);
PageBox { value, page_count }
}
}
impl<T> PageBox<[MaybeUninit<T>]> {

View File

@ -30,6 +30,8 @@ use crate::{
pub mod elf;
pub type LoadedProcess<PM, IO> = (Arc<ProcessImpl<PM, IO>>, Arc<Thread>);
pub trait ProgramLoadSource {
type File: Seek + Read;
@ -173,7 +175,7 @@ fn setup_binary<S, PM, IO>(
image: ProcessImage,
args: &Vec<String>,
envs: &Vec<String>,
) -> Result<(Arc<ProcessImpl<PM, IO>>, Arc<Thread>), Error>
) -> Result<LoadedProcess<PM, IO>, Error>
where
S: Into<String>,
PM: ProcessManager<Process = ProcessImpl<PM, IO>>,
@ -239,7 +241,7 @@ pub fn load<PS, P, PM, IO>(
path: P,
args: &[&str],
envs: &[&str],
) -> Result<(Arc<ProcessImpl<PM, IO>>, Arc<Thread>), Error>
) -> Result<LoadedProcess<PM, IO>, Error>
where
PS: ProgramLoadSource,
P: AsRef<Path>,

View File

@ -69,7 +69,7 @@ impl<T> AsyncMutex<T> {
poll_fn(|cx| self.poll_lock(cx)).await
}
pub unsafe fn force_unlock(&self) {
unsafe fn force_unlock(&self) {
self.lock.store(false, Ordering::Release);
self.waker.wake_one();
}

View File

@ -317,6 +317,10 @@ impl Thread {
THREADS.read().get(id).cloned()
}
/// # Safety
///
/// Precondition: the caller must ensure the thread is, in fact, a current one, for example,
/// by preventing interrupts by holding an [IrqGuard].
pub unsafe fn upgrade(weak: &Weak<Self>) -> Option<CurrentThread> {
let guard = IrqGuard::acquire();
let strong = weak.upgrade()?;

View File

@ -13,6 +13,9 @@ pub struct LocalCpu<'a>(LocalCpuImpl<'a, CpuQueue>);
pub struct Cpu(CpuImpl<CpuQueue>);
impl Cpu {
/// # Safety
///
/// Precondition: this function has not yet been called on the local CPU.
pub unsafe fn init_local(
id: Option<u32>,
data: <ArchitectureImpl as Architecture>::PerCpuData,

View File

@ -210,7 +210,6 @@ fn el0_sync_inner(frame: &mut ExceptionFrame) {
dump_irrecoverable_exception(frame, ec, iss);
thread.raise_signal(Signal::MemoryAccessViolation);
return;
}
}
}

View File

@ -1,5 +1,5 @@
//! ARM PL011 driver
use abi::{error::Error, io::DeviceRequest, process::ProcessId};
use abi::{error::Error, io::DeviceRequest};
use alloc::boxed::Box;
use device_api::{
interrupt::{InterruptHandler, Irq},
@ -152,7 +152,7 @@ impl CharDevice for Pl011 {
fn device_request(&self, req: &mut DeviceRequest) -> Result<(), Error> {
match req {
&mut DeviceRequest::SetTerminalGroup(id) => {
self.set_signal_group(ProcessId::from(id));
self.set_signal_group(id);
Ok(())
}
DeviceRequest::SetTerminalOptions(config) => self.context.set_config(config),

View File

@ -233,7 +233,7 @@ mod impls {
debugln!("{} requested terminal {:?}", pid, fd);
let file = child_io.files.file(fd)?;
// let node = file.node().ok_or(Error::InvalidFile)?;
let mut req = DeviceRequest::SetTerminalGroup(child_process.group_id().into());
let mut req = DeviceRequest::SetTerminalGroup(child_process.group_id());
file.device_request(&mut req)?;
if let Some(node) = file.node() {

View File

@ -16,4 +16,8 @@ pub trait SyscallFatRegister {
fn from_syscall_registers(meta: usize, data: usize) -> Self;
}
/// # Safety
///
/// Meant for abi-generator to provide a "hint" that the type, when wrapped in an Option or Result,
/// can be fit into a single register.
pub unsafe trait ThinWrapped: SyscallRegister {}

View File

@ -40,9 +40,7 @@ impl SyscallRegister for () {
0
}
fn from_syscall_register(_value: usize) -> Self {
()
}
fn from_syscall_register(_value: usize) -> Self {}
}
impl SyscallRegister for ! {

View File

@ -7,7 +7,7 @@ use syn::{punctuated::Punctuated, spanned::Spanned, token, Token};
pub mod ty;
use crate::{
abi::ty::ComplexType,
abi::ty::{AbiPrimitive, ComplexType, SimpleType},
syntax::{
parse_abi, Attributes, BitfieldRange, BitfieldType, BitfieldTypeField,
DocumentTypeDefinition, EnumType, EnumTypeVariant, NewType, ParseError, TypeRepr,
@ -122,8 +122,25 @@ impl AbiBuilder {
let handler_fn = quote! { #impl_mod::#syscall_name };
let body = quote! {
Ok((#handler_fn(#call_args)).into_syscall_register())
let body = if syscall
.return_type
.as_ref()
.map(|p| {
matches!(
p.as_ref(),
ComplexType::Simple(SimpleType::Primitive(AbiPrimitive::Unit))
)
})
.unwrap_or(true)
{
quote! {
#handler_fn(#call_args);
Ok(0)
}
} else {
quote! {
Ok((#handler_fn(#call_args)).into_syscall_register())
}
};
let match_arm = syscall.emit_handler_branch(
@ -138,6 +155,7 @@ impl AbiBuilder {
}
let dispatcher_fn = quote! {
#[allow(clippy::unnecessary_cast, clippy::identity_op)]
pub(crate) fn #dispatcher_fn(#raw_fn: SyscallFunction, #raw_args: &[usize]) -> Result<usize, Error> {
match #raw_fn {
#branches
@ -287,6 +305,7 @@ impl GenerateTypeDefinition for EnumType {
self as #repr
}
#[allow(clippy::missing_safety_doc)]
pub const unsafe fn from_raw(value: #repr) -> Self {
core::mem::transmute(value)
}
@ -294,6 +313,7 @@ impl GenerateTypeDefinition for EnumType {
impl From<#name> for #repr {
#[inline]
#[allow(clippy::unnecessary_cast)]
fn from(value: #name) -> #repr {
value as #repr
}
@ -357,6 +377,7 @@ fn generate_transparent_struct(
self.0
}
#[allow(clippy::missing_safety_doc)]
pub const unsafe fn from_raw(value: #repr) -> Self {
Self(value)
}

View File

@ -5,7 +5,7 @@ use proc_macro2::TokenStream;
use quote::quote;
use crate::{
abi::ty::{SimpleType, Type},
abi::ty::{AbiPrimitive, SimpleType, Type},
TargetEnv,
};
@ -107,6 +107,11 @@ impl Syscall {
unreachable!()
}
}
Some(ComplexType::Simple(SimpleType::Primitive(AbiPrimitive::Unit))) => {
quote! {
#sys_call;
}
}
Some(ty) => {
let ty = ty.as_rust_type();
quote!(<#ty>::from_syscall_register(#sys_call))

View File

@ -58,7 +58,11 @@ impl Type for AbiPrimitive {
}
fn emit_to_syscall_arguments(&self, _env: &TargetEnv, value: &Ident) -> TokenStream {
quote!(#value as usize)
if *self == Self::USize {
quote!(#value)
} else {
quote!(#value as usize)
}
}
fn emit_from_syscall_arguments(

View File

@ -371,9 +371,7 @@ impl<'a, 'd> Server<'a, 'd> {
let (row, col) = self.focused_frame?;
let frame = &self.rows[row].frames[col];
let Some(window) = frame.window.and_then(|w| self.windows.get(&w)) else {
return None;
};
let window = frame.window.and_then(|w| self.windows.get(&w))?;
Some((frame, window))
}

View File

@ -183,6 +183,7 @@ fn validate_ping_reply(
l4_data == expect_l4_data
}
#[allow(clippy::too_many_arguments)]
fn ping_once(
socket: &mut RawSocket,
poll: &mut PollChannel,
@ -197,9 +198,8 @@ fn ping_once(
let source_ip = info.source_ip.into_ipv4().unwrap();
let destination_ip = info.destination_ip.into_ipv4().unwrap();
let mut l4_data = vec![];
let mut l4_data = Vec::with_capacity(data_len);
l4_data.reserve(data_len);
for _ in 0..data_len {
l4_data.push(rand::random());
}

View File

@ -167,11 +167,12 @@ fn run(mut input: Input, vars: &mut HashMap<String, String>) -> io::Result<ExitC
if input.is_interactive() {
eprintln!("Killed: {}", signal);
}
signal as i32 + 128
signal + 128
}
Ok(Outcome::Exited(code)) => code % 256,
Err(e) => {
eprintln!("{}: {}", "<command>", e);
// TODO stringify the command back
eprintln!("<command>: {}", e);
127
}
};

View File

@ -77,7 +77,7 @@ fn main() -> ExitCode {
}
if let Err(err) = login_attempt(attempt_number % 3 == 0) {
eprintln!("login: {}", err.to_string());
eprintln!("login: {}", err);
}
attempt_number += 1;
}

View File

@ -1,7 +1,11 @@
use std::{env, fs::OpenOptions, io, path::Path, process::ExitCode};
fn touch<P: AsRef<Path>>(path: P) -> Result<(), io::Error> {
OpenOptions::new().create(true).write(true).open(path)?;
OpenOptions::new()
.create(true)
.write(true)
.truncate(false)
.open(path)?;
Ok(())
}

View File

@ -1,2 +1,2 @@
[toolchain]
branch = "alnyan/v0.1.0"
branch = "alnyan/yggdrasil-master"