|
1 | 1 | //! Kernel configuration
|
2 | 2 | use crate::{
|
3 | 3 | kernel::{hook, interrupt, raw, raw_cfg},
|
4 |
| - utils::{ComptimeVec, Init, PhantomInvariant}, |
| 4 | + utils::{ComptimeVec, ConstAllocator, Frozen, Init, PhantomInvariant}, |
5 | 5 | };
|
6 | 6 |
|
7 | 7 | macro overview_ref() {
|
@@ -29,37 +29,49 @@ enum CfgSt {
|
29 | 29 |
|
30 | 30 | impl<'c, C: raw_cfg::CfgBase> Cfg<'c, C> {
|
31 | 31 | /// Construct `Cfg`.
|
32 |
| - const fn new(raw: &'c mut C, st: CfgSt) -> Self { |
| 32 | + const fn new(raw: &'c mut C, allocator: &'c ConstAllocator, st: CfgSt) -> Self { |
33 | 33 | Self {
|
34 | 34 | raw,
|
35 | 35 | st,
|
36 |
| - startup_hooks: ComptimeVec::new(), |
| 36 | + startup_hooks: ComptimeVec::new_in(allocator.clone()), |
37 | 37 | hunk_pool_len: 0,
|
38 | 38 | hunk_pool_align: 1,
|
39 |
| - interrupt_lines: ComptimeVec::new(), |
40 |
| - interrupt_handlers: ComptimeVec::new(), |
| 39 | + interrupt_lines: ComptimeVec::new_in(allocator.clone()), |
| 40 | + interrupt_handlers: ComptimeVec::new_in(allocator.clone()), |
41 | 41 | }
|
42 | 42 | }
|
43 | 43 |
|
44 | 44 | #[doc(hidden)]
|
45 |
| - pub const fn __internal_new_phase1(raw: &'c mut C, _dummy: &'c mut ()) -> Self { |
46 |
| - Self::new(raw, CfgSt::Phase1) |
| 45 | + pub const fn __internal_new_phase1( |
| 46 | + raw: &'c mut C, |
| 47 | + allocator: &'c ConstAllocator, |
| 48 | + _dummy: &'c mut (), |
| 49 | + ) -> Self { |
| 50 | + Self::new(raw, allocator, CfgSt::Phase1) |
47 | 51 | }
|
48 | 52 |
|
49 | 53 | #[doc(hidden)]
|
50 |
| - pub const fn __internal_new_phase2(raw: &'c mut C, _dummy: &'c mut ()) -> Self |
| 54 | + pub const fn __internal_new_phase2( |
| 55 | + raw: &'c mut C, |
| 56 | + allocator: &'c ConstAllocator, |
| 57 | + _dummy: &'c mut (), |
| 58 | + ) -> Self |
51 | 59 | where
|
52 | 60 | C::System: CfgPhase1,
|
53 | 61 | {
|
54 |
| - Self::new(raw, CfgSt::Phase2) |
| 62 | + Self::new(raw, allocator, CfgSt::Phase2) |
55 | 63 | }
|
56 | 64 |
|
57 | 65 | #[doc(hidden)]
|
58 |
| - pub const fn __internal_new_phase3(raw: &'c mut C, _dummy: &'c mut ()) -> Self |
| 66 | + pub const fn __internal_new_phase3( |
| 67 | + raw: &'c mut C, |
| 68 | + allocator: &'c ConstAllocator, |
| 69 | + _dummy: &'c mut (), |
| 70 | + ) -> Self |
59 | 71 | where
|
60 | 72 | C::System: CfgPhase2,
|
61 | 73 | {
|
62 |
| - Self::new(raw, CfgSt::Phase3 { interrupts: false }) |
| 74 | + Self::new(raw, allocator, CfgSt::Phase3 { interrupts: false }) |
63 | 75 | }
|
64 | 76 |
|
65 | 77 | /// Mutably borrow the underlying `C`.
|
@@ -104,10 +116,12 @@ impl<'c, C: raw_cfg::CfgBase> Cfg<'c, C> {
|
104 | 116 |
|
105 | 117 | CfgPhase1Data {
|
106 | 118 | _phantom: Init::INIT,
|
107 |
| - startup_hooks: self.startup_hooks.map(hook::CfgStartupHook::to_attr), |
| 119 | + startup_hooks: Frozen::leak_slice( |
| 120 | + &self.startup_hooks.map(hook::CfgStartupHook::to_attr), |
| 121 | + ), |
108 | 122 | hunk_pool_len: self.hunk_pool_len,
|
109 | 123 | hunk_pool_align: self.hunk_pool_align,
|
110 |
| - interrupt_handlers: self.interrupt_handlers, |
| 124 | + interrupt_handlers: Frozen::leak_slice(&self.interrupt_handlers), |
111 | 125 | }
|
112 | 126 | }
|
113 | 127 |
|
@@ -186,8 +200,8 @@ impl<'c, C: raw_cfg::CfgBase> Cfg<'c, C> {
|
186 | 200 |
|
187 | 201 | // Clear these fields to indicate that this method has been called
|
188 | 202 | // as required
|
189 |
| - self.interrupt_lines = ComptimeVec::new(); |
190 |
| - self.interrupt_handlers = ComptimeVec::new(); |
| 203 | + self.interrupt_lines.clear(); |
| 204 | + self.interrupt_handlers.clear(); |
191 | 205 | }
|
192 | 206 |
|
193 | 207 | /// Finalize `self` for the phase 3 configuration.
|
@@ -238,10 +252,10 @@ impl<'c, C: raw_cfg::CfgBase> Cfg<'c, C> {
|
238 | 252 | #[doc = overview_ref!()]
|
239 | 253 | pub struct CfgPhase1Data<System> {
|
240 | 254 | _phantom: PhantomInvariant<System>,
|
241 |
| - pub startup_hooks: ComptimeVec<hook::StartupHookAttr>, |
| 255 | + pub startup_hooks: &'static [Frozen<hook::StartupHookAttr>], |
242 | 256 | pub hunk_pool_len: usize,
|
243 | 257 | pub hunk_pool_align: usize,
|
244 |
| - pub interrupt_handlers: ComptimeVec<interrupt::CfgInterruptHandler>, |
| 258 | + pub interrupt_handlers: &'static [Frozen<interrupt::CfgInterruptHandler>], |
245 | 259 | }
|
246 | 260 |
|
247 | 261 | /// The inputs to [`attach_phase2!`].
|
@@ -504,28 +518,45 @@ where
|
504 | 518 |
|
505 | 519 | /// Construct [`Cfg`]`<$RawCfg>` for the phase 3 configuration.
|
506 | 520 | ///
|
| 521 | +/// - `$raw_cfg: &mut impl `[`CfgBase`][] |
| 522 | +/// - `$allocator: &`[`ConstAllocator`][] |
| 523 | +/// |
507 | 524 | /// `<$RawCfg as `[`CfgBase`][]`>::System` must implement [`CfgPhase2`][].
|
508 | 525 | ///
|
509 | 526 | /// [`CfgBase`]: raw_cfg::CfgBase
|
510 |
| -pub macro cfg_phase3(let mut $cfg:ident = Cfg::<$RawCfg:ty>::new($raw_cfg:expr)) { |
| 527 | +pub macro cfg_phase3( |
| 528 | + let mut $cfg:ident = Cfg::<$RawCfg:ty>::new($raw_cfg:expr, $allocator:expr) |
| 529 | +) { |
511 | 530 | let mut dummy = ();
|
512 |
| - let mut $cfg = Cfg::<$RawCfg>::__internal_new_phase3(&mut *$raw_cfg, &mut dummy); |
| 531 | + let mut $cfg = Cfg::<$RawCfg>::__internal_new_phase3(&mut *$raw_cfg, $allocator, &mut dummy); |
513 | 532 | }
|
514 | 533 |
|
515 | 534 | /// Construct [`Cfg`]`<$RawCfg>` for the phase 2 configuration.
|
516 | 535 | ///
|
| 536 | +/// - `$raw_cfg: &mut impl `[`CfgBase`][] |
| 537 | +/// - `$allocator: &`[`ConstAllocator`][] |
| 538 | +/// |
517 | 539 | /// `<$RawCfg as `[`CfgBase`][]`>::System` must implement [`CfgPhase1`][].
|
518 | 540 | ///
|
519 | 541 | /// [`CfgBase`]: raw_cfg::CfgBase
|
520 |
| -pub macro cfg_phase2(let mut $cfg:ident = Cfg::<$RawCfg:ty>::new($raw_cfg:expr)) { |
| 542 | +pub macro cfg_phase2( |
| 543 | + let mut $cfg:ident = Cfg::<$RawCfg:ty>::new($raw_cfg:expr, $allocator:expr) |
| 544 | +) { |
521 | 545 | let mut dummy = ();
|
522 |
| - let mut $cfg = Cfg::<$RawCfg>::__internal_new_phase2(&mut *$raw_cfg, &mut dummy); |
| 546 | + let mut $cfg = Cfg::<$RawCfg>::__internal_new_phase2(&mut *$raw_cfg, $allocator, &mut dummy); |
523 | 547 | }
|
524 | 548 |
|
525 | 549 | /// Construct [`Cfg`]`<$RawCfg>` for the phase 1 configuration.
|
526 |
| -pub macro cfg_phase1(let mut $cfg:ident = Cfg::<$RawCfg:ty>::new($raw_cfg:expr)) { |
| 550 | +/// |
| 551 | +/// - `$raw_cfg: &mut impl `[`CfgBase`][] |
| 552 | +/// - `$allocator: &`[`ConstAllocator`][] |
| 553 | +/// |
| 554 | +/// [`CfgBase`]: raw_cfg::CfgBase |
| 555 | +pub macro cfg_phase1( |
| 556 | + let mut $cfg:ident = Cfg::<$RawCfg:ty>::new($raw_cfg:expr, $allocator:expr) |
| 557 | +) { |
527 | 558 | let mut dummy = ();
|
528 |
| - let mut $cfg = Cfg::<$RawCfg>::__internal_new_phase1(&mut *$raw_cfg, &mut dummy); |
| 559 | + let mut $cfg = Cfg::<$RawCfg>::__internal_new_phase1(&mut *$raw_cfg, $allocator, &mut dummy); |
529 | 560 | }
|
530 | 561 |
|
531 | 562 | /// Implement [`KernelStatic`] on `$Ty` using the given `$params:
|
@@ -590,13 +621,15 @@ pub macro attach_phase1($params:expr, impl CfgPhase1<$System:ty> for $Ty:ty $(,)
|
590 | 621 | array_item_from_fn! {
|
591 | 622 | const STARTUP_HOOKS: [hook::StartupHookAttr; _] =
|
592 | 623 | (0..STATIC_PARAMS.startup_hooks.len())
|
593 |
| - .map(|i| STATIC_PARAMS.startup_hooks[i]); |
| 624 | + .map(|i| STATIC_PARAMS.startup_hooks[i].get()); |
594 | 625 | }
|
595 | 626 |
|
596 | 627 | // Consturct a table of combined second-level interrupt handlers
|
597 |
| - const INTERRUPT_HANDLERS: [interrupt::CfgInterruptHandler; { |
598 |
| - STATIC_PARAMS.interrupt_handlers.len() |
599 |
| - }] = STATIC_PARAMS.interrupt_handlers.to_array(); |
| 628 | + array_item_from_fn! { |
| 629 | + const INTERRUPT_HANDLERS: [interrupt::CfgInterruptHandler; _] = |
| 630 | + (0..STATIC_PARAMS.interrupt_handlers.len()) |
| 631 | + .map(|i| STATIC_PARAMS.interrupt_handlers[i].get()); |
| 632 | + } |
600 | 633 | const NUM_INTERRUPT_HANDLERS: usize = INTERRUPT_HANDLERS.len();
|
601 | 634 | const NUM_INTERRUPT_LINES: usize =
|
602 | 635 | interrupt::num_required_interrupt_line_slots(&INTERRUPT_HANDLERS);
|
|
0 commit comments