diff --git a/app/demo-stm32h7-nucleo/app-h753.toml b/app/demo-stm32h7-nucleo/app-h753.toml index f88658be3..efa28c158 100644 --- a/app/demo-stm32h7-nucleo/app-h753.toml +++ b/app/demo-stm32h7-nucleo/app-h753.toml @@ -25,7 +25,7 @@ request_reset = ["hiffy"] [tasks.sys] name = "drv-stm32xx-sys" -features = ["h753", "exti"] +features = ["h753", "exti", "no-panic"] priority = 1 uses = ["rcc", "gpios", "system_flash", "syscfg", "exti"] start = true diff --git a/drv/stm32xx-sys/Cargo.toml b/drv/stm32xx-sys/Cargo.toml index 9ed1aee85..706b2c6fc 100644 --- a/drv/stm32xx-sys/Cargo.toml +++ b/drv/stm32xx-sys/Cargo.toml @@ -37,6 +37,7 @@ g070 = ["family-stm32g0", "stm32g0/stm32g070", "drv-stm32xx-sys-api/g070", "drv- g0b1 = ["family-stm32g0", "stm32g0/stm32g0b1", "drv-stm32xx-sys-api/g0b1", "drv-stm32xx-gpio-common/model-stm32g0b1"] no-ipc-counters = ["idol/no-counters"] +no-panic = ["userlib/no-panic"] # Enable external interrupt controller support. exti = ["dep:hubris-num-tasks", "dep:counters"] diff --git a/drv/stm32xx-sys/src/main.rs b/drv/stm32xx-sys/src/main.rs index 96595fd00..58f4436da 100644 --- a/drv/stm32xx-sys/src/main.rs +++ b/drv/stm32xx-sys/src/main.rs @@ -397,7 +397,13 @@ fn main() -> ! { // API the way we use peripherals. let syscfg = unsafe { &*device::SYSCFG::ptr() }; - for (i, entry) in generated::EXTI_DISPATCH_TABLE.iter().enumerate() { + for i in 0..16 { + // TODO: this sure looks like it should be using + // iter.enumerate, doesn't it? Unfortunately that's not + // currently getting inlined by rustc, resulting in rather + // silly code containing panics. This is significantly + // smaller. + let entry = &generated::EXTI_DISPATCH_TABLE[i]; // Process entries that are filled in... if let &Some(ExtiDispatch { port, .. }) = entry { let register = i >> 2; @@ -685,7 +691,7 @@ impl idl::InOrderSysImpl for ServerImpl<'_> { for (i, _) in exti_dispatch_for(rm.sender, mask) { // What bit do we touch for this entry? - let bit = 1 << i; + let bit = 1 << (i & 0xF); // Record that these bits meant something. slot_mask |= bit; @@ -774,15 +780,17 @@ impl idl::InOrderSysImpl for ServerImpl<'_> { let mut used_bits = 0u32; for (i, entry) in exti_dispatch_for(rm.sender, mask) { + let imask = 1 << (i & 0xF); + used_bits |= entry.mask; // Set or clear Rising Trigger Selection // Register bit according to the rising flag self.exti.rtsr1.modify(|r, w| { let new_value = if edge.is_rising() { - r.bits() | (1 << i) + r.bits() | imask } else { - r.bits() & !(1 << i) + r.bits() & !imask }; unsafe { w.bits(new_value) @@ -793,9 +801,9 @@ impl idl::InOrderSysImpl for ServerImpl<'_> { // Register bit according to the rising flag self.exti.ftsr1.modify(|r, w| { let new_value = if edge.is_falling() { - r.bits() | (1 << i) + r.bits() | imask } else { - r.bits() & !(1 << i) + r.bits() & !imask }; unsafe { w.bits(new_value) @@ -849,9 +857,12 @@ fn exti_dispatch_for( task: TaskId, mask: u32, ) -> impl Iterator { - generated::EXTI_DISPATCH_TABLE - .iter() - .enumerate() + // This is semantically equivalent to iter.enumerate, but winds up handing + // the compiler very different code that avoids an otherwise-difficult panic + // site on an apparently-overflowing addition (that was not actually capable + // of overflowing). + (0..generated::EXTI_DISPATCH_TABLE.len()) + .zip(&generated::EXTI_DISPATCH_TABLE) .filter_map(move |(i, entry)| { let entry = entry.as_ref()?; if task.index() == entry.task.index() && mask & entry.mask != 0 { @@ -898,9 +909,13 @@ impl NotificationHandler for ServerImpl<'_> { let mut bits_to_acknowledge = 0u16; - for (pin_idx, entry) in - generated::EXTI_DISPATCH_TABLE.iter().enumerate() - { + for pin_idx in 0..16 { + // TODO: this sure looks like it should be using + // iter.enumerate, doesn't it? Unfortunately that's not + // currently getting inlined by rustc, resulting in rather + // silly code containing panics. This is significantly + // smaller. + let entry = &generated::EXTI_DISPATCH_TABLE[pin_idx]; if pending_and_enabled & 1 << pin_idx != 0 { // A channel is pending! We need to handle this // basically like the kernel handles native hardware