Skip to content

Commit

Permalink
kernel: add iface query-by-type interface v0
Browse files Browse the repository at this point in the history
  • Loading branch information
Qix- committed Jan 21, 2025
1 parent 58f175a commit 06dcfed
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 41 deletions.
64 changes: 64 additions & 0 deletions oro-kernel/src/iface/kernel/iface_query_by_type_v0.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
//! Kernel interface for querying the ring's interfaces
//! based on the interface type.
use oro_sysabi::syscall::Error as SysError;

use super::KernelInterface;
use crate::{
arch::Arch,
syscall::{InterfaceResponse, SystemCallResponse},
tab::Tab,
thread::Thread,
};

/// Version 0 of the thread control kernel interface.
#[repr(transparent)]
pub struct IfaceQueryByTypeV0;

impl KernelInterface for IfaceQueryByTypeV0 {
const TYPE_ID: u64 = oro_sysabi::id::iface::KERNEL_IFACE_QUERY_BY_TYPE_V0;

fn get<A: Arch>(thread: &Tab<Thread<A>>, index: u64, key: u64) -> InterfaceResponse {
let ring = thread.with(|t| t.ring());

ring.with(|ring| {
let interfaces = ring.interfaces_by_type();

if let Some(iface_list) = interfaces.get(index) {
if key == 0 {
InterfaceResponse::Immediate(SystemCallResponse {
error: SysError::Ok,
ret: iface_list.len() as u64,
})
} else if let Some(iface) = iface_list.get(key as usize - 1) {
InterfaceResponse::Immediate(SystemCallResponse {
error: SysError::Ok,
ret: iface.id(),
})
} else {
InterfaceResponse::Immediate(SystemCallResponse {
error: SysError::BadKey,
ret: 0,
})
}
} else {
InterfaceResponse::Immediate(SystemCallResponse {
error: SysError::BadIndex,
ret: 0,
})
}
})
}

fn set<A: Arch>(
_thread: &Tab<Thread<A>>,
_index: u64,
_key: u64,
_value: u64,
) -> InterfaceResponse {
InterfaceResponse::Immediate(SystemCallResponse {
error: SysError::ReadOnly,
ret: 0,
})
}
}
6 changes: 4 additions & 2 deletions oro-kernel/src/iface/kernel/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
use crate::{arch::Arch, syscall::InterfaceResponse, tab::Tab, thread::Thread};

mod iface_query_by_type_v0;
mod thread_v0;

/// Small helper trait for kernel interfaces, which are always
Expand All @@ -23,7 +24,7 @@ pub trait KernelInterface {

#[doc(hidden)]
macro_rules! make_dispatch {
($($iface:ty),*) => {
($($iface:ty),* $(,)?) => {
const _: () = const {
$(assert!(
(<$iface as KernelInterface>::TYPE_ID & ::oro_sysabi::id::mask::KERNEL_ID) == 0,
Expand Down Expand Up @@ -77,5 +78,6 @@ macro_rules! make_dispatch {
}

make_dispatch! {
thread_v0::ThreadV0
thread_v0::ThreadV0,
iface_query_by_type_v0::IfaceQueryByTypeV0,
}
38 changes: 14 additions & 24 deletions oro-kernel/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,35 +145,25 @@ impl<A: Arch> Kernel<A> {
.write(TicketMutex::new(Scheduler::new(&*kernel_ptr)));

if !global_state.has_initialized_root.swap(true, SeqCst) {
let ifaceid = tab::get()
.add(RingInterface::<A>::new(
self::iface::root_ring::debug_out_v0::DebugOutV0::new(),
global_state.root_ring.id(),
))
.ok_or(MapError::OutOfMemory)?;

// XXX(qix-): DEBUG
::oro_debug::dbg!("registered DebugLogV0: {}", ifaceid.id());

global_state.root_ring.with_mut(|root_ring| {
root_ring.interfaces_mut().push(ifaceid);
});

#[cfg(feature = "boot-vbuf-v0")]
{
let ifaceid = tab::get()
.add(RingInterface::<A>::new(
self::iface::root_ring::boot_vbuf_v0::BootVbufV0::new(),
root_ring
.register_interface(RingInterface::<A>::new(
self::iface::root_ring::debug_out_v0::DebugOutV0::new(),
global_state.root_ring.id(),
))
.ok_or(MapError::OutOfMemory)?;

// XXX(qix-): DEBUG
::oro_debug::dbg!("registered BootVbufV0: {}", ifaceid.id());
.ok_or(MapError::OutOfMemory)
})?;

#[cfg(feature = "boot-vbuf-v0")]
{
global_state.root_ring.with_mut(|root_ring| {
root_ring.interfaces_mut().push(ifaceid);
});
root_ring
.register_interface(RingInterface::<A>::new(
self::iface::root_ring::boot_vbuf_v0::BootVbufV0::new(),
global_state.root_ring.id(),
))
.ok_or(MapError::OutOfMemory)
})?;
}
}

Expand Down
48 changes: 33 additions & 15 deletions oro-kernel/src/ring.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@ use oro_mem::{
};

use crate::{
AddressSpace, Kernel, UserHandle, arch::Arch, instance::Instance, interface::RingInterface,
AddressSpace, Kernel, UserHandle,
arch::Arch,
instance::Instance,
interface::{Interface, RingInterface},
tab::Tab,
table::Table,
};

/// A singular ring.
Expand All @@ -33,15 +37,15 @@ use crate::{
#[non_exhaustive]
pub struct Ring<A: Arch> {
/// The parent ring handle, or `None` if this is the root ring.
parent: Option<Tab<Ring<A>>>,
parent: Option<Tab<Ring<A>>>,
/// The module [`Instance`]s on the ring.
instances: Vec<Tab<Instance<A>>>,
instances: Vec<Tab<Instance<A>>>,
/// The ring's base mapper handle.
mapper: UserHandle<A>,
mapper: UserHandle<A>,
/// The ring's child rings.
children: Vec<Tab<Ring<A>>>,
/// The interfaces exposed to the ring.
interfaces: Vec<Tab<RingInterface<A>>>,
children: Vec<Tab<Ring<A>>>,
/// The interfaces exposed to the ring, grouped by type.
interfaces_by_type: Table<Vec<Tab<RingInterface<A>>>>,
}

impl<A: Arch> Ring<A> {
Expand All @@ -58,7 +62,7 @@ impl<A: Arch> Ring<A> {
instances: Vec::new(),
mapper,
children: Vec::new(),
interfaces: Vec::new(),
interfaces_by_type: Table::new(),
})
.ok_or(MapError::OutOfMemory)?;

Expand Down Expand Up @@ -100,7 +104,7 @@ impl<A: Arch> Ring<A> {
instances: Vec::new(),
mapper,
children: Vec::new(),
interfaces: Vec::new(),
interfaces_by_type: Table::new(),
})
.ok_or(MapError::OutOfMemory)
}
Expand Down Expand Up @@ -131,15 +135,29 @@ impl<A: Arch> Ring<A> {
&mut self.instances
}

/// Returns a slice of interfaces exposed to the ring.
/// Returns a slice of interfaces exposed to the ring, grouped by type.
#[must_use]
pub fn interfaces(&self) -> &[Tab<RingInterface<A>>] {
&self.interfaces
pub fn interfaces_by_type(&self) -> &Table<Vec<Tab<RingInterface<A>>>> {
&self.interfaces_by_type
}

/// Returns a mutable reference to the interfaces vector.
/// Returns a mutable reference to the interfaces table, grouped by type.
#[must_use]
pub fn interfaces_mut(&mut self) -> &mut Vec<Tab<RingInterface<A>>> {
&mut self.interfaces
pub fn interfaces_by_type_mut(&mut self) -> &mut Table<Vec<Tab<RingInterface<A>>>> {
&mut self.interfaces_by_type
}

/// Convience function for registering an interface with the global tab
/// system as well as the ring.
///
/// Returns `None` if the addition to the tab registry failed.
/// See [`crate::tab::GlobalTable::add`] for more information.
pub fn register_interface(&mut self, iface: RingInterface<A>) -> Option<Tab<RingInterface<A>>> {
let type_id = iface.type_id();
let tab = crate::tab::get().add(iface)?;
self.interfaces_by_type
.get_or_insert_mut(type_id)
.push(tab.clone());
Some(tab)
}
}
10 changes: 10 additions & 0 deletions oro-kernel/src/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,16 @@ impl<T: Sized, Alloc: Allocator + Default> Table<T, Alloc> {
self.0.get(&id)
}

/// Gets a mutable reference to the value associated with the given ID,
/// inserting it via `Default` if it doesn't exist before returning it.
#[inline]
pub fn get_or_insert_mut(&mut self, id: u64) -> &mut T
where
T: Default,
{
self.0.entry(id).or_default()
}

/// Removes a value given its key. Returns `None` if the value didn't exist.
#[inline]
pub fn remove(&mut self, id: u64) -> Option<T> {
Expand Down
2 changes: 2 additions & 0 deletions oro-sysabi/src/id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ pub mod iface {

/// The ID of the kernel threading interface (version 0).
pub const KERNEL_THREAD_V0: u64 = KERNEL_ID_TYPE_IFACE | 0x00_0001;
/// The ID of the kernel interface-by-type query interface (version 0).
pub const KERNEL_IFACE_QUERY_BY_TYPE_V0: u64 = KERNEL_ID_TYPE_IFACE | 0x00_0002;

/// The ID of the root ring debug output interface (version 0).
pub const ROOT_DEBUG_OUT_V0: u64 = 1736981805247;
Expand Down

0 comments on commit 06dcfed

Please sign in to comment.