Skip to content

Commit

Permalink
kernel: initial Oro kernel data structures"
Browse files Browse the repository at this point in the history
  • Loading branch information
Qix- committed Sep 12, 2024
1 parent 687bf3e commit 7eb72c2
Show file tree
Hide file tree
Showing 5 changed files with 349 additions and 44 deletions.
30 changes: 23 additions & 7 deletions oro-kernel/src/instance.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
//! Module instance types and functionality.
use crate::{module::Module, registry::Handle, ring::Ring};
use crate::{
module::Module,
registry::{Handle, Item, ItemIterEx},
ring::Ring,
thread::Thread,
};
use oro_mem::mapper::AddressSpace;
use oro_sync::spinlock::unfair_critical::InterruptController;

/// A singular module instance.
///
Expand Down Expand Up @@ -31,16 +38,18 @@ use crate::{module::Module, registry::Handle, ring::Ring};
/// to interact with the kernel directly via the built-in modules, and
/// from there can spawn additional rings and instances as needed to
/// bootstrap the rest of the system as they see fit.
pub struct Instance {
pub struct Instance<AddrSpace: AddressSpace> {
/// The module instance ID.
id: usize,
pub(crate) id: usize,
/// The module from which this instance was spawned.
module: Handle<Module>,
pub(crate) module: Handle<Module>,
/// The ring on which this instance resides.
ring: Handle<Ring>,
pub(crate) ring: Handle<Ring<AddrSpace>>,
/// The root thread item of the instance.
pub(crate) root_thread: Option<Handle<Item<Thread<AddrSpace>>>>,
}

impl Instance {
impl<AddrSpace: AddressSpace> Instance<AddrSpace> {
/// Returns the instance ID.
///
/// # Safety
Expand All @@ -61,7 +70,14 @@ impl Instance {
}

/// The [`Handle`] to the ring on which this instance resides.
pub fn ring(&self) -> Handle<Ring> {
pub fn ring(&self) -> Handle<Ring<AddrSpace>> {
self.ring.clone()
}

/// Gets an iterator over all threads in this instance.
pub fn threads<IntCtrl: InterruptController>(
&self,
) -> impl Iterator<Item = Handle<Item<Thread<AddrSpace>>>> {
self.root_thread.iter_all::<IntCtrl>()
}
}
56 changes: 30 additions & 26 deletions oro-kernel/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,6 @@
// NOTE(qix-): https://github.com/rust-lang/rust/issues/95174
#![feature(adt_const_params)]

use oro_macro::assert;
use oro_mem::{
mapper::{AddressSegment, AddressSpace, MapError},
pfa::alloc::Alloc,
translate::Translator,
};
use oro_sync::spinlock::unfair_critical::{InterruptController, UnfairCriticalSpinlock};

pub mod id;
pub mod instance;
pub mod module;
Expand All @@ -25,6 +17,15 @@ pub mod registry;
pub mod ring;
pub mod thread;

use self::registry::Handle;
use oro_macro::assert;
use oro_mem::{
mapper::{AddressSegment, AddressSpace, MapError},
pfa::alloc::Alloc,
translate::Translator,
};
use oro_sync::spinlock::unfair_critical::{InterruptController, UnfairCriticalSpinlock};

/// Core-local instance of the Oro kernel.
///
/// This object's constructor sets up a core-local
Expand Down Expand Up @@ -126,7 +127,7 @@ where
/// The physical address translator.
pat: Pat,
/// Ring registry.
ring_registry: registry::Registry<ring::Ring, IntCtrl, AddrSpace, Pat>,
ring_registry: registry::Registry<ring::Ring<AddrSpace>, IntCtrl, AddrSpace, Pat>,
}

impl<Pfa, Pat, AddrSpace, IntCtrl> KernelState<Pfa, Pat, AddrSpace, IntCtrl>
Expand Down Expand Up @@ -167,8 +168,9 @@ where
let root_ring_id = ring_registry.insert_permanent(
&pfa,
ring::Ring {
id: 0,
id: 0,
parent: None,
root_instance: None,
},
)?;
assert_eq!(root_ring_id, 0, "root ring ID must be 0");
Expand Down Expand Up @@ -198,27 +200,29 @@ where
/// In almost all cases, you should be using [`registry::Handle`]s
/// directly. They are also easier to work with than calling
/// this function.
pub unsafe fn ring_by_id(&'static self, id: usize) -> Option<registry::Handle<ring::Ring>> {
pub unsafe fn ring_by_id(&'static self, id: usize) -> Option<Handle<ring::Ring<AddrSpace>>> {
self.ring_registry.get(id)
}

/// Inserts a [`ring::Ring`] into the registry and returns
/// its [`registry::Handle`].
///
/// `ring.id` will be set to the allocated ID, and is ignored
/// when passed in.
///
/// Note that the returned handle is reference counted; dropping
/// it will drop the ring from the registry. If the ring is
/// intended to be kept alive, it should be added to a scheduler.
pub fn insert_ring(
/// Creates a new ring and returns a [`registry::Handle`] to it.
pub fn create_ring(
&'static self,
ring: ring::Ring,
) -> Result<registry::Handle<ring::Ring>, MapError> {
let handle = self.ring_registry.insert(&self.pfa, ring)?;
parent: Handle<ring::Ring<AddrSpace>>,
) -> Result<Handle<ring::Ring<AddrSpace>>, MapError> {
let ring = self.ring_registry.insert(
&self.pfa,
ring::Ring {
id: usize::MAX, // placeholder
parent: Some(parent),
root_instance: None,
},
)?;

// SAFETY(qix-): Will not panic.
unsafe {
handle.lock::<IntCtrl>().id = handle.id();
ring.lock::<IntCtrl>().id = ring.id();
}
Ok(handle)

Ok(ring)
}
}
Loading

0 comments on commit 7eb72c2

Please sign in to comment.