diff --git a/app/demo-stm32h7-nucleo/app-h743.toml b/app/demo-stm32h7-nucleo/app-h743.toml index db1a02786..a8834160d 100644 --- a/app/demo-stm32h7-nucleo/app-h743.toml +++ b/app/demo-stm32h7-nucleo/app-h743.toml @@ -75,7 +75,7 @@ uses = ["eth", "eth_dma", "tim16"] start = true notifications = ["eth-irq", "mdio-timer-irq", "wake-timer"] interrupts = {"eth.irq" = "eth-irq", "tim16.irq" = "mdio-timer-irq"} -task-slots = ["sys"] +task-slots = ["sys", "jefe"] [tasks.user_leds] name = "drv-user-leds" diff --git a/app/demo-stm32h7-nucleo/app-h753.toml b/app/demo-stm32h7-nucleo/app-h753.toml index 7382c7d47..fb5b7dc9f 100644 --- a/app/demo-stm32h7-nucleo/app-h753.toml +++ b/app/demo-stm32h7-nucleo/app-h753.toml @@ -83,7 +83,7 @@ uses = ["eth", "eth_dma", "tim16"] start = true notifications = ["eth-irq", "mdio-timer-irq", "wake-timer"] interrupts = {"eth.irq" = "eth-irq", "tim16.irq" = "mdio-timer-irq"} -task-slots = ["sys"] +task-slots = ["sys", "jefe"] [tasks.user_leds] name = "drv-user-leds" diff --git a/app/gimletlet/app-mgmt.toml b/app/gimletlet/app-mgmt.toml index f441a846f..b96cb00a6 100644 --- a/app/gimletlet/app-mgmt.toml +++ b/app/gimletlet/app-mgmt.toml @@ -58,7 +58,7 @@ sections = {eth_bulk = "sram1"} uses = ["eth", "eth_dma", "tim16", "spi2"] start = true notifications = ["eth-irq", "mdio-timer-irq", "spi-irq", "wake-timer"] -task-slots = ["sys", "user_leds"] +task-slots = ["sys", "user_leds", "jefe"] [tasks.net.interrupts] "eth.irq" = "eth-irq" diff --git a/app/gimletlet/app.toml b/app/gimletlet/app.toml index a567206a3..60047353b 100644 --- a/app/gimletlet/app.toml +++ b/app/gimletlet/app.toml @@ -179,7 +179,7 @@ max-sizes = {flash = 131072, ram = 65536, sram1 = 16384} sections = {eth_bulk = "sram1"} uses = ["eth", "eth_dma", "tim16", "spi4"] start = true -task-slots = ["sys"] +task-slots = ["sys", "jefe"] notifications = ["eth-irq", "mdio-timer-irq", "spi-irq", "wake-timer"] [tasks.net.interrupts] diff --git a/app/sidecar/rev-b.toml b/app/sidecar/rev-b.toml index a894b2b9d..bddb21f72 100644 --- a/app/sidecar/rev-b.toml +++ b/app/sidecar/rev-b.toml @@ -72,7 +72,7 @@ sections = {eth_bulk = "sram1"} uses = ["eth", "eth_dma", "tim16", "spi3"] start = true notifications = ["eth-irq", "mdio-timer-irq", "spi-irq", "wake-timer"] -task-slots = ["sys", "packrat", { seq = "sequencer" }] +task-slots = ["sys", "packrat", { seq = "sequencer" }, "jefe"] [tasks.net.interrupts] "eth.irq" = "eth-irq" diff --git a/app/sidecar/rev-c.toml b/app/sidecar/rev-c.toml index 4615a0b83..5fd1aea32 100644 --- a/app/sidecar/rev-c.toml +++ b/app/sidecar/rev-c.toml @@ -72,7 +72,7 @@ sections = {eth_bulk = "sram1"} uses = ["eth", "eth_dma", "tim16", "spi3"] start = true notifications = ["eth-irq", "mdio-timer-irq", "spi-irq", "wake-timer"] -task-slots = ["sys", "packrat", { seq = "sequencer" }] +task-slots = ["sys", "packrat", { seq = "sequencer" }, "jefe"] [tasks.net.interrupts] "eth.irq" = "eth-irq" diff --git a/idl/jefe.idol b/idl/jefe.idol index 9cad3aed2..97f17dae6 100644 --- a/idl/jefe.idol +++ b/idl/jefe.idol @@ -94,5 +94,17 @@ Interface( ), encoding: Hubpack, ), + + // Note: this is the "raw" API; there is a nice wrapper in the client + // crate. + "restart_me_raw": ( + description: "restarts the caller without recording a fault", + args: {}, + // Note: this will not actually return, but Idol can't currently + // describe a noreturn IPC, so, we have a placeholder: + reply: Simple("()"), + encoding: Hubpack, + idempotent: true, + ), }, ) diff --git a/task/jefe-api/src/lib.rs b/task/jefe-api/src/lib.rs index b48136491..7ac9b6985 100644 --- a/task/jefe-api/src/lib.rs +++ b/task/jefe-api/src/lib.rs @@ -34,4 +34,13 @@ pub enum DumpAreaError { AlreadyInUse, } +impl Jefe { + /// Asks the supervisor to restart the current task without recording a + /// fault. + pub fn restart_me(&self) -> ! { + self.restart_me_raw(); + unreachable!() + } +} + include!(concat!(env!("OUT_DIR"), "/client_stub.rs")); diff --git a/task/jefe/src/main.rs b/task/jefe/src/main.rs index e6504e0e7..ad2eb7d97 100644 --- a/task/jefe/src/main.rs +++ b/task/jefe/src/main.rs @@ -207,6 +207,19 @@ impl idl::InOrderJefeImpl for ServerImpl<'_> { Ok(()) } + fn restart_me_raw( + &mut self, + msg: &userlib::RecvMessage, + ) -> Result<(), RequestError> { + kipc::restart_task(msg.sender.index(), true); + + // Note: the returned value here won't go anywhere because we just + // unblocked the caller. So this is doing a small amount of unnecessary + // work. This is a compromise because Idol can't easily describe an IPC + // that won't return at this time. + Ok(()) + } + cfg_if::cfg_if! { if #[cfg(feature = "dump")] { fn get_dump_area( diff --git a/task/net/src/bsp/gimlet_bcd.rs b/task/net/src/bsp/gimlet_bcd.rs index e8e25d880..ad9a22c8f 100644 --- a/task/net/src/bsp/gimlet_bcd.rs +++ b/task/net/src/bsp/gimlet_bcd.rs @@ -17,11 +17,9 @@ use task_jefe_api::Jefe; use task_net_api::{ ManagementCounters, ManagementLinkStatus, MgmtError, PhyError, }; -use userlib::{sys_recv_closed, task_slot, FromPrimitive, TaskId}; +use userlib::{sys_recv_closed, FromPrimitive, TaskId}; use vsc7448_pac::types::PhyRegisterAddress; -task_slot!(JEFE, jefe); - //////////////////////////////////////////////////////////////////////////////// pub struct BspImpl(mgmt::Bsp); @@ -56,7 +54,7 @@ impl crate::bsp_support::Bsp for BspImpl { fn preinit() { // Wait for the sequencer to turn on the clock. This requires that Jefe // state change notifications are routed to our notification bit 3. - let jefe = Jefe::from(JEFE.get_task_id()); + let jefe = Jefe::from(crate::JEFE.get_task_id()); loop { // This laborious list is intended to ensure that new power states diff --git a/task/net/src/bsp/psc_a.rs b/task/net/src/bsp/psc_a.rs index 1d512e942..b8ad78eca 100644 --- a/task/net/src/bsp/psc_a.rs +++ b/task/net/src/bsp/psc_a.rs @@ -17,11 +17,9 @@ use task_jefe_api::Jefe; use task_net_api::{ ManagementCounters, ManagementLinkStatus, MgmtError, PhyError, }; -use userlib::{sys_recv_closed, task_slot, FromPrimitive, TaskId}; +use userlib::{sys_recv_closed, FromPrimitive, TaskId}; use vsc7448_pac::types::PhyRegisterAddress; -task_slot!(JEFE, jefe); - //////////////////////////////////////////////////////////////////////////////// pub struct BspImpl(mgmt::Bsp); @@ -55,7 +53,7 @@ impl bsp_support::Bsp for BspImpl { fn preinit() { // Wait for the sequencer to turn read our VPD. - let jefe = Jefe::from(JEFE.get_task_id()); + let jefe = Jefe::from(crate::JEFE.get_task_id()); loop { // This laborious list is intended to ensure that new power states diff --git a/task/net/src/bsp/psc_bc.rs b/task/net/src/bsp/psc_bc.rs index c60b2fb7b..ad56af1fb 100644 --- a/task/net/src/bsp/psc_bc.rs +++ b/task/net/src/bsp/psc_bc.rs @@ -17,11 +17,9 @@ use task_jefe_api::Jefe; use task_net_api::{ ManagementCounters, ManagementLinkStatus, MgmtError, PhyError, }; -use userlib::{sys_recv_closed, task_slot, FromPrimitive, TaskId}; +use userlib::{sys_recv_closed, FromPrimitive, TaskId}; use vsc7448_pac::types::PhyRegisterAddress; -task_slot!(JEFE, jefe); - //////////////////////////////////////////////////////////////////////////////// pub struct BspImpl(mgmt::Bsp); @@ -60,7 +58,7 @@ impl bsp_support::Bsp for BspImpl { fn preinit() { // Wait for the sequencer to turn read our VPD. - let jefe = Jefe::from(JEFE.get_task_id()); + let jefe = Jefe::from(crate::JEFE.get_task_id()); loop { // This laborious list is intended to ensure that new power states diff --git a/task/net/src/main.rs b/task/net/src/main.rs index e224d6857..e550eb2af 100644 --- a/task/net/src/main.rs +++ b/task/net/src/main.rs @@ -59,6 +59,7 @@ use core::sync::atomic::{AtomicU32, Ordering}; use enum_map::Enum; use multitimer::{Multitimer, Repeat}; use task_net_api::MacAddressBlock; +use task_jefe_api::Jefe; use zerocopy::{AsBytes, U16}; #[cfg(feature = "h743")] @@ -74,6 +75,7 @@ use crate::bsp::BspImpl; use crate::bsp_support::Bsp; task_slot!(SYS, sys); +task_slot!(JEFE, jefe); #[cfg(feature = "vpd-mac")] task_slot!(PACKRAT, packrat); @@ -153,6 +155,7 @@ static ITER_COUNT: AtomicU32 = AtomicU32::new(0); fn main() -> ! { let sys = SYS.get_task_id(); let sys = Sys::from(sys); + let jefe = Jefe::from(JEFE.get_task_id()); // Do any preinit tasks specific to this board. For hardware which requires // explicit clock configuration, this is where the `net` tasks waits for @@ -265,7 +268,9 @@ fn main() -> ! { server.wake(); // timer is set to auto-repeat } - Timers::Watchdog => panic!("MAC RX watchdog"), + Timers::Watchdog => { + jefe.restart_me(); + } } } let mut msgbuf = [0u8; idl::INCOMING_SIZE];