refactor: unsafe only in adapter + libkos; forbid(unsafe_code) everywhere else; libkos Window (volatile, bounds-checked MMIO/DMA/shared mem), entry!, thread::spawn; MapRegion returns pages; kernel const-built (with_cores/install_platform); newtype addrs
This commit is contained in:
@@ -16,6 +16,16 @@ struct Node {
|
||||
next: Option<u16>,
|
||||
}
|
||||
|
||||
impl Node {
|
||||
const EMPTY: Self = Self {
|
||||
live: false,
|
||||
parent: None,
|
||||
first_child: None,
|
||||
prev: None,
|
||||
next: None,
|
||||
};
|
||||
}
|
||||
|
||||
pub struct CapTree<const N: usize> {
|
||||
nodes: [Node; N],
|
||||
}
|
||||
@@ -31,9 +41,9 @@ fn id(i: usize) -> Option<u16> {
|
||||
}
|
||||
|
||||
impl<const N: usize> CapTree<N> {
|
||||
pub fn new() -> Self {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
nodes: [Node::default(); N],
|
||||
nodes: [Node::EMPTY; N],
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ pub struct EndpointTable {
|
||||
}
|
||||
|
||||
impl EndpointTable {
|
||||
pub fn new() -> Self {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
endpoints: [const { None }; MAX_ENDPOINTS],
|
||||
generations: SlotGenerations::new(),
|
||||
|
||||
@@ -10,7 +10,7 @@ pub struct WaitQueue<const N: usize = MAX_WAITERS> {
|
||||
}
|
||||
|
||||
impl<const N: usize> WaitQueue<N> {
|
||||
pub fn new() -> Self {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
entries: [None; N],
|
||||
len: 0,
|
||||
|
||||
@@ -12,7 +12,7 @@ pub struct SlotGenerations<const N: usize> {
|
||||
}
|
||||
|
||||
impl<const N: usize> SlotGenerations<N> {
|
||||
pub fn new() -> Self {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
gens: [Some(Generation::initial()); N],
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ pub struct IrqRoutingTable {
|
||||
}
|
||||
|
||||
impl IrqRoutingTable {
|
||||
pub fn new() -> Self {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
routes: [None; MAX_IRQS],
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#![no_std]
|
||||
#![forbid(unsafe_code)]
|
||||
// A kernel panic takes the whole system down, so kernel code may not
|
||||
// contain any way to panic. Tests and proofs are exempt.
|
||||
#![cfg_attr(
|
||||
|
||||
@@ -55,8 +55,8 @@ pub struct FrameTable<const N: usize = MAX_FRAMES> {
|
||||
}
|
||||
|
||||
impl<const N: usize> FrameTable<N> {
|
||||
pub fn new(base: PhysicalAddress, total: usize) -> Self {
|
||||
let total = total.min(N);
|
||||
pub const fn new(base: PhysicalAddress, total: usize) -> Self {
|
||||
let total = if total < N { total } else { N };
|
||||
Self {
|
||||
base,
|
||||
total,
|
||||
|
||||
@@ -122,7 +122,7 @@ pub struct RegionTable {
|
||||
}
|
||||
|
||||
impl RegionTable {
|
||||
pub fn new() -> Self {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
regions: [const { None }; MAX_REGIONS],
|
||||
generations: SlotGenerations::new(),
|
||||
|
||||
@@ -133,7 +133,7 @@ pub struct NotificationTable {
|
||||
}
|
||||
|
||||
impl NotificationTable {
|
||||
pub fn new() -> Self {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
slots: [const { None }; MAX_NOTIFICATIONS],
|
||||
generations: SlotGenerations::new(),
|
||||
|
||||
@@ -80,7 +80,7 @@ pub struct ProcessTable {
|
||||
}
|
||||
|
||||
impl ProcessTable {
|
||||
pub fn new() -> Self {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
processes: [const { None }; MAX_PROCESSES],
|
||||
generations: SlotGenerations::new(),
|
||||
|
||||
@@ -21,11 +21,23 @@ pub struct MultiCoreScheduler {
|
||||
}
|
||||
|
||||
impl MultiCoreScheduler {
|
||||
pub fn new(num_cores: u8) -> Self {
|
||||
let cores = core::array::from_fn(|i| PerCoreScheduler::new(CoreId::from_raw(i as u8)));
|
||||
pub const fn new(num_cores: u8) -> Self {
|
||||
let mut cores = [const { PerCoreScheduler::new(CoreId::from_raw(0)) }; MAX_CORES];
|
||||
// Each core numbered by its place (a const fn cannot index or map).
|
||||
let mut rest: &mut [PerCoreScheduler] = &mut cores;
|
||||
let mut id = 0u8;
|
||||
while let Some((core, tail)) = rest.split_first_mut() {
|
||||
*core = PerCoreScheduler::new(CoreId::from_raw(id));
|
||||
rest = tail;
|
||||
id += 1;
|
||||
}
|
||||
Self {
|
||||
cores,
|
||||
num_cores: num_cores.min(MAX_CORES as u8),
|
||||
num_cores: if num_cores < MAX_CORES as u8 {
|
||||
num_cores
|
||||
} else {
|
||||
MAX_CORES as u8
|
||||
},
|
||||
placements: [const { None }; MAX_SCHEDULED_THREADS],
|
||||
}
|
||||
}
|
||||
@@ -47,6 +59,12 @@ impl MultiCoreScheduler {
|
||||
self.placements.get(thread.raw() as usize)?.as_ref()
|
||||
}
|
||||
|
||||
/// How many cores to schedule on, once the platform knows; before any
|
||||
/// thread is placed.
|
||||
pub fn set_num_cores(&mut self, num_cores: u8) {
|
||||
self.num_cores = num_cores.min(MAX_CORES as u8);
|
||||
}
|
||||
|
||||
pub fn num_cores(&self) -> u8 {
|
||||
self.num_cores
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ pub struct PerCoreScheduler {
|
||||
}
|
||||
|
||||
impl PerCoreScheduler {
|
||||
pub fn new(core: CoreId) -> Self {
|
||||
pub const fn new(core: CoreId) -> Self {
|
||||
Self {
|
||||
core,
|
||||
queue: PriorityQueue::new(),
|
||||
|
||||
@@ -25,7 +25,7 @@ pub struct PriorityQueue {
|
||||
}
|
||||
|
||||
impl PriorityQueue {
|
||||
pub fn new() -> Self {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
lists: [ListEnds {
|
||||
head: None,
|
||||
|
||||
@@ -18,7 +18,7 @@ pub struct ThreadTable {
|
||||
}
|
||||
|
||||
impl ThreadTable {
|
||||
pub fn new() -> Self {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
threads: [const { None }; MAX_THREADS],
|
||||
generations: SlotGenerations::new(),
|
||||
|
||||
Reference in New Issue
Block a user