#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub enum BootSentinel {
PreClockInit,
PostClockInit,
PostSafeStop,
PostSdramInit,
PostDisplayInit,
}
impl BootSentinel {
#[inline]
pub const fn raw(self) -> u32 {
match self {
BootSentinel::PreClockInit => 0xA11C_0010,
BootSentinel::PostClockInit => 0xA11C_0020,
BootSentinel::PostSafeStop => 0xA11C_0030,
BootSentinel::PostSdramInit => 0xA11C_0040,
BootSentinel::PostDisplayInit => 0xA11C_0050,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
const ALL: &[BootSentinel] = &[
BootSentinel::PreClockInit,
BootSentinel::PostClockInit,
BootSentinel::PostSafeStop,
BootSentinel::PostSdramInit,
BootSentinel::PostDisplayInit,
];
#[test]
fn raw_values_match_dpr02_section_5_2() {
assert_eq!(BootSentinel::PreClockInit.raw(), 0xA11C_0010);
assert_eq!(BootSentinel::PostClockInit.raw(), 0xA11C_0020);
assert_eq!(BootSentinel::PostSafeStop.raw(), 0xA11C_0030);
assert_eq!(BootSentinel::PostSdramInit.raw(), 0xA11C_0040);
assert_eq!(BootSentinel::PostDisplayInit.raw(), 0xA11C_0050);
}
#[test]
fn raw_values_share_alic_prefix() {
for s in ALL {
let v = s.raw();
assert_eq!(
v & 0xFFFF_0000,
0xA11C_0000,
"{s:?} = 0x{v:08x} does not carry the 0xA11C prefix",
);
}
}
#[test]
fn raw_values_are_unique() {
for (i, a) in ALL.iter().enumerate() {
for (j, b) in ALL.iter().enumerate() {
if i == j {
continue;
}
assert_ne!(
a.raw(),
b.raw(),
"sentinels {a:?} and {b:?} both resolve to 0x{:08x}",
a.raw()
);
}
}
}
#[test]
fn raw_values_are_monotonic_in_boot_order() {
let mut prev = 0u32;
for s in ALL {
let v = s.raw();
assert!(
v > prev,
"{s:?} = 0x{v:08x} is not greater than the previous sentinel 0x{prev:08x}",
);
prev = v;
}
}
}