From af0214f0f65d9caaeb1a5d403380507f01196bf4 Mon Sep 17 00:00:00 2001 From: Andre Richter Date: Fri, 25 Sep 2020 22:25:22 +0200 Subject: [PATCH] State: Encapsulate state check into member function --- 14_exceptions_part2_peripheral_IRQs/README.md | 21 +++++++++++++------ .../src/bsp/device_driver/arm/gicv2/gicd.rs | 2 +- .../src/state.rs | 15 ++++++++++--- .../src/synchronization.rs | 2 +- 4 files changed, 29 insertions(+), 11 deletions(-) diff --git a/14_exceptions_part2_peripheral_IRQs/README.md b/14_exceptions_part2_peripheral_IRQs/README.md index b44b91c4..0e9bd694 100644 --- a/14_exceptions_part2_peripheral_IRQs/README.md +++ b/14_exceptions_part2_peripheral_IRQs/README.md @@ -1163,7 +1163,7 @@ diff -uNr 13_integrated_testing/src/bsp/device_driver/arm/gicv2/gicd.rs 14_excep + /// Route all SPIs to the boot core and enable the distributor. + pub fn boot_core_init(&self) { + assert!( -+ state::state_manager().state() == state::State::Init, ++ state::state_manager().is_init(), + "Only allowed during kernel init phase" + ); + @@ -2507,7 +2507,7 @@ diff -uNr 13_integrated_testing/src/main.rs 14_exceptions_part2_peripheral_IRQs/ diff -uNr 13_integrated_testing/src/state.rs 14_exceptions_part2_peripheral_IRQs/src/state.rs --- 13_integrated_testing/src/state.rs +++ 14_exceptions_part2_peripheral_IRQs/src/state.rs -@@ -0,0 +1,83 @@ +@@ -0,0 +1,92 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +// +// Copyright (c) 2020 Andre Richter @@ -2517,12 +2517,12 @@ diff -uNr 13_integrated_testing/src/state.rs 14_exceptions_part2_peripheral_IRQs +use core::sync::atomic::{AtomicU8, Ordering}; + +//-------------------------------------------------------------------------------------------------- -+// Public Definitions ++// Private Definitions +//-------------------------------------------------------------------------------------------------- + +/// Different stages in the kernel execution. +#[derive(Copy, Clone, Eq, PartialEq)] -+pub enum State { ++enum State { + /// The kernel starts booting in this state. + Init, + @@ -2535,6 +2535,10 @@ diff -uNr 13_integrated_testing/src/state.rs 14_exceptions_part2_peripheral_IRQs + MultiCoreMain, +} + ++//-------------------------------------------------------------------------------------------------- ++// Public Definitions ++//-------------------------------------------------------------------------------------------------- ++ +/// Maintains the kernel state and state transitions. +pub struct StateManager(AtomicU8); + @@ -2564,7 +2568,7 @@ diff -uNr 13_integrated_testing/src/state.rs 14_exceptions_part2_peripheral_IRQs + } + + /// Return the current state. -+ pub fn state(&self) -> State { ++ fn state(&self) -> State { + let state = self.0.load(Ordering::Acquire); + + match state { @@ -2575,6 +2579,11 @@ diff -uNr 13_integrated_testing/src/state.rs 14_exceptions_part2_peripheral_IRQs + } + } + ++ /// Return if the kernel is still in an init state. ++ pub fn is_init(&self) -> bool { ++ self.state() == State::Init ++ } ++ + /// Transition from Init to SingleCoreMain. + pub fn transition_to_single_core_main(&self) { + if self @@ -2686,7 +2695,7 @@ diff -uNr 13_integrated_testing/src/synchronization.rs 14_exceptions_part2_perip + + fn write(&mut self, f: impl FnOnce(&mut Self::Data) -> R) -> R { + assert!( -+ state::state_manager().state() == state::State::Init, ++ state::state_manager().is_init(), + "InitStateLock::write called after kernel init phase" + ); + assert!( diff --git a/14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/arm/gicv2/gicd.rs b/14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/arm/gicv2/gicd.rs index d2b6099f..b0d18215 100644 --- a/14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/arm/gicv2/gicd.rs +++ b/14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/arm/gicv2/gicd.rs @@ -144,7 +144,7 @@ impl GICD { /// Route all SPIs to the boot core and enable the distributor. pub fn boot_core_init(&self) { assert!( - state::state_manager().state() == state::State::Init, + state::state_manager().is_init(), "Only allowed during kernel init phase" ); diff --git a/14_exceptions_part2_peripheral_IRQs/src/state.rs b/14_exceptions_part2_peripheral_IRQs/src/state.rs index 5edb9fc5..af1d9348 100644 --- a/14_exceptions_part2_peripheral_IRQs/src/state.rs +++ b/14_exceptions_part2_peripheral_IRQs/src/state.rs @@ -7,12 +7,12 @@ use core::sync::atomic::{AtomicU8, Ordering}; //-------------------------------------------------------------------------------------------------- -// Public Definitions +// Private Definitions //-------------------------------------------------------------------------------------------------- /// Different stages in the kernel execution. #[derive(Copy, Clone, Eq, PartialEq)] -pub enum State { +enum State { /// The kernel starts booting in this state. Init, @@ -25,6 +25,10 @@ pub enum State { MultiCoreMain, } +//-------------------------------------------------------------------------------------------------- +// Public Definitions +//-------------------------------------------------------------------------------------------------- + /// Maintains the kernel state and state transitions. pub struct StateManager(AtomicU8); @@ -54,7 +58,7 @@ impl StateManager { } /// Return the current state. - pub fn state(&self) -> State { + fn state(&self) -> State { let state = self.0.load(Ordering::Acquire); match state { @@ -65,6 +69,11 @@ impl StateManager { } } + /// Return if the kernel is still in an init state. + pub fn is_init(&self) -> bool { + self.state() == State::Init + } + /// Transition from Init to SingleCoreMain. pub fn transition_to_single_core_main(&self) { if self diff --git a/14_exceptions_part2_peripheral_IRQs/src/synchronization.rs b/14_exceptions_part2_peripheral_IRQs/src/synchronization.rs index b519ea3e..d4bb2c23 100644 --- a/14_exceptions_part2_peripheral_IRQs/src/synchronization.rs +++ b/14_exceptions_part2_peripheral_IRQs/src/synchronization.rs @@ -130,7 +130,7 @@ impl interface::ReadWriteEx for &InitStateLock { fn write(&mut self, f: impl FnOnce(&mut Self::Data) -> R) -> R { assert!( - state::state_manager().state() == state::State::Init, + state::state_manager().is_init(), "InitStateLock::write called after kernel init phase" ); assert!(