diff --git a/emulation/soc/renode.svd b/emulation/soc/renode.svd index abb9485fc..0cfe8a7c1 100644 --- a/emulation/soc/renode.svd +++ b/emulation/soc/renode.svd @@ -3,7 +3,7 @@ litex SOC - + 8 32 @@ -1162,7 +1162,7 @@ register to disable individual events.]]> GIT_MAJOR +``v0.8.1``, so this value is ``0``.]]> 0x0008 0x00 32 @@ -1178,9 +1178,9 @@ register to disable individual events.]]> GIT_MINOR +``v0.8.1``, so this value is ``8``.]]> 0x000c - 0x00 + 0x08 32 @@ -1194,9 +1194,9 @@ register to disable individual events.]]> GIT_REVISION +``v0.8.1``, so this value is ``1``.]]> 0x0010 - 0x00 + 0x01 32 @@ -1210,10 +1210,10 @@ register to disable individual events.]]> GIT_GITREV 0x0014 - 0x9e77f50e + 0xcf5b40e6 32 @@ -2657,10 +2657,112 @@ sources (power, sha512, and engine25519)]]> + + WAKEUP_SOURCE + 0x0008 + 0xff + 32 + + + kbd + 0 + [0:0] + 0 + + + + ticktimer + 1 + [1:1] + 1 + + + + timer0 + 2 + [2:2] + 2 + + + + usb + 3 + [3:3] + 3 + + + + audio + 4 + [4:4] + 4 + + + + com + 5 + [5:5] + 5 + + + + rtc + 6 + [6:6] + 6 + + + + console + 7 + [7:7] + 7 + + + + + + ACTIVITY_RATE + 0x000c + 0x00 + 32 + + + counts_awake + 30 + [30:0] + 0 + + + + + + SAMPLING_PERIOD + 0x0010 + 0x00 + 32 + + + sample_period + 30 + [30:0] + 0 + + + + kill_sampler + 31 + [31:31] + 31 + + + + VIBE - 0x0008 + 0x0014 0x00 32 @@ -2675,8 +2777,8 @@ sources (power, sha512, and engine25519)]]> EV_STATUS - - 0x000c + + 0x0018 0x00 32 @@ -2687,12 +2789,19 @@ sources (power, sha512, and engine25519)]]> 0 + + activity_update + 1 + [1:1] + 1 + + EV_PENDING - - 0x0010 + + 0x001c 0x00 32 @@ -2703,12 +2812,19 @@ sources (power, sha512, and engine25519)]]> 0 + + activity_update + 1 + [1:1] + 1 + + EV_ENABLE - - 0x0014 + + 0x0020 0x00 32 @@ -2719,12 +2835,19 @@ sources (power, sha512, and engine25519)]]> 0 + + activity_update + 1 + [1:1] + 1 + + 0 - 0x18 + 0x24 registers @@ -3316,7 +3439,7 @@ inject too fast.]]> SEED1 0x0000 - 0x56f38707 + 0x742b5c26 32 @@ -3331,7 +3454,7 @@ inject too fast.]]> SEED0 0x0004 - 0x400f5344 + 0x645c9ef4 32 diff --git a/precursors/soc.svd b/precursors/soc.svd index 877033b9d..0cfe8a7c1 100644 --- a/precursors/soc.svd +++ b/precursors/soc.svd @@ -3,7 +3,7 @@ litex SOC - + 8 32 @@ -1244,7 +1244,7 @@ beyond the tag indicated in `MAJOR`, `MINOR`, and `REVISION`.]]> GIT_DIRTY 0x001c - 0x00 + 0x01 32 @@ -2657,10 +2657,112 @@ sources (power, sha512, and engine25519)]]> + + WAKEUP_SOURCE + 0x0008 + 0xff + 32 + + + kbd + 0 + [0:0] + 0 + + + + ticktimer + 1 + [1:1] + 1 + + + + timer0 + 2 + [2:2] + 2 + + + + usb + 3 + [3:3] + 3 + + + + audio + 4 + [4:4] + 4 + + + + com + 5 + [5:5] + 5 + + + + rtc + 6 + [6:6] + 6 + + + + console + 7 + [7:7] + 7 + + + + + + ACTIVITY_RATE + 0x000c + 0x00 + 32 + + + counts_awake + 30 + [30:0] + 0 + + + + + + SAMPLING_PERIOD + 0x0010 + 0x00 + 32 + + + sample_period + 30 + [30:0] + 0 + + + + kill_sampler + 31 + [31:31] + 31 + + + + VIBE - 0x0008 + 0x0014 0x00 32 @@ -2675,8 +2777,8 @@ sources (power, sha512, and engine25519)]]> EV_STATUS - - 0x000c + + 0x0018 0x00 32 @@ -2687,12 +2789,19 @@ sources (power, sha512, and engine25519)]]> 0 + + activity_update + 1 + [1:1] + 1 + + EV_PENDING - - 0x0010 + + 0x001c 0x00 32 @@ -2703,12 +2812,19 @@ sources (power, sha512, and engine25519)]]> 0 + + activity_update + 1 + [1:1] + 1 + + EV_ENABLE - - 0x0014 + + 0x0020 0x00 32 @@ -2719,12 +2835,19 @@ sources (power, sha512, and engine25519)]]> 0 + + activity_update + 1 + [1:1] + 1 + + 0 - 0x18 + 0x24 registers @@ -3316,7 +3439,7 @@ inject too fast.]]> SEED1 0x0000 - 0x178b8559 + 0x742b5c26 32 @@ -3331,7 +3454,7 @@ inject too fast.]]> SEED0 0x0004 - 0x1c2378e2 + 0x645c9ef4 32 diff --git a/precursors/soc_csr.bin b/precursors/soc_csr.bin index af692e96e..fbe583ff8 100644 Binary files a/precursors/soc_csr.bin and b/precursors/soc_csr.bin differ diff --git a/services/gam/src/status.rs b/services/gam/src/status.rs index 9dda17458..9bcf9b311 100644 --- a/services/gam/src/status.rs +++ b/services/gam/src/status.rs @@ -225,8 +225,11 @@ pub fn status_thread(canvas_gid_0: usize, canvas_gid_1: usize, canvas_gid_2: usi }; write!(&mut uptime_tv, "{:02}:{:02} {} {}/{}", dt.hours, dt.minutes, day, dt.months, dt.days).unwrap(); } else { - write!(&mut uptime_tv, "Up {:02}:{:02}:{:02}", - (elapsed_time / 3_600_000), (elapsed_time / 60_000) % 60, now_seconds).expect("|status: can't write string"); + let (latest_activity, period) = llio.activity_instantaneous().expect("couldn't get CPU activity"); + write!(&mut uptime_tv, "Up {}:{:02}:{:02} {:.0}%", + (elapsed_time / 3_600_000), (elapsed_time / 60_000) % 60, now_seconds, + ((latest_activity as f32) / (period as f32)) * 100.0 + ).expect("|status: can't write string"); } log::trace!("|status: requesting draw of '{}'", uptime_tv); gam.post_textview(&mut uptime_tv).expect("|status: can't draw uptime"); diff --git a/services/llio/src/api.rs b/services/llio/src/api.rs index 023ad9afd..42523c6f7 100644 --- a/services/llio/src/api.rs +++ b/services/llio/src/api.rs @@ -188,6 +188,7 @@ pub(crate) enum Opcode { PowerCryptoStatus, WfiOverride, DebugPowerdown, + GetActivity, DebugWakeup, EcSnoopAllow, //(bool), EcReset, @@ -215,6 +216,7 @@ pub(crate) enum Opcode { EventComEnable, //(bool), EventRtcEnable, //(bool), EventUsbAttachEnable, //(bool), + EventActivityHappened, /// internal from handler to main loop EventComHappened, diff --git a/services/llio/src/lib.rs b/services/llio/src/lib.rs index b48667158..fe64bdf5b 100644 --- a/services/llio/src/lib.rs +++ b/services/llio/src/lib.rs @@ -511,6 +511,18 @@ impl Llio { Message::new_scalar(Opcode::DebugWakeup.to_usize().unwrap(), arg, 0, 0, 0) ).map(|_| ()) } + pub fn activity_instantaneous(&self) -> Result<(u32, u32), xous::Error> { + let response = send_message(self.conn, + Message::new_blocking_scalar(Opcode::GetActivity.to_usize().unwrap(), 0, 0, 0, 0))?; + if let xous::Result::Scalar2(active, total) = response { + Ok( + (active as u32, total as u32) + ) + } else { + log::error!("LLIO: unexpected return value: {:#?}", response); + Err(xous::Error::InternalError) + } + } } diff --git a/services/llio/src/main.rs b/services/llio/src/main.rs index 1c5e4a21c..b5d56b1a0 100644 --- a/services/llio/src/main.rs +++ b/services/llio/src/main.rs @@ -42,6 +42,7 @@ mod implementation { power_susres: RegManager::<{utra::power::POWER_NUMREGS}>, xadc_csr: utralib::CSR, // be careful with this as XADC is shared with TRNG ticktimer: ticktimer_server::Ticktimer, + activity_period: u32, // 12mhz clock cycles over which to sample activity destruct_armed: bool, } @@ -81,12 +82,23 @@ mod implementation { } fn handle_power_irq(_irq_no: usize, arg: *mut usize) { let xl = unsafe { &mut *(arg as *mut Llio) }; - if let Some(conn) = xl.handler_conn { - xous::try_send_message(conn, - xous::Message::new_scalar(Opcode::EventUsbHappened.to_usize().unwrap(), - 0, 0, 0, 0)).map(|_|()).unwrap(); - } else { - log::error!("|handle_event_irq: USB interrupt, but no connection for notification!") + if xl.power_csr.rf(utra::power::EV_PENDING_USB_ATTACH) != 0 { + if let Some(conn) = xl.handler_conn { + xous::try_send_message(conn, + xous::Message::new_scalar(Opcode::EventUsbHappened.to_usize().unwrap(), + 0, 0, 0, 0)).map(|_|()).unwrap(); + } else { + log::error!("|handle_event_irq: USB interrupt, but no connection for notification!") + } + } else if xl.power_csr.rf(utra::power::EV_PENDING_ACTIVITY_UPDATE) != 0 { + if let Some(conn) = xl.handler_conn { + let activity = xl.power_csr.rf(utra::power::ACTIVITY_RATE_COUNTS_AWAKE); + xous::try_send_message(conn, + xous::Message::new_scalar(Opcode::EventActivityHappened.to_usize().unwrap(), + activity as usize, 0, 0, 0)).map(|_|()).unwrap(); + } else { + log::error!("|handle_event_irq: activity interrupt, but no connection for notification!") + } } xl.power_csr .wo(utra::power::EV_PENDING, xl.power_csr.r(utra::power::EV_PENDING)); @@ -167,6 +179,7 @@ mod implementation { power_susres: RegManager::new(power_csr.as_mut_ptr() as *mut u32), xadc_csr: CSR::new(xadc_csr.as_mut_ptr() as *mut u32), ticktimer, + activity_period: 24_000_000, // 2 second interval initially destruct_armed: false, }; @@ -205,6 +218,12 @@ mod implementation { xl.power_csr.rmwf(utra::power::POWER_CRYPTO_ON, 0); // save power on crypto block xl.power_susres.push(RegOrField::Reg(utra::power::POWER), None); xl.power_susres.push(RegOrField::Reg(utra::power::VIBE), None); + + xl.power_csr.wfo(utra::power::SAMPLING_PERIOD_SAMPLE_PERIOD, xl.activity_period); // 2 second sampling intervals + xl.power_susres.push(RegOrField::Reg(utra::power::SAMPLING_PERIOD), None); + xl.power_csr.wfo(utra::power::EV_PENDING_ACTIVITY_UPDATE, 1); + xl.power_csr.rmwf(utra::power::EV_ENABLE_ACTIVITY_UPDATE, 1); + xl.power_susres.push_fixed_value(RegOrField::Reg(utra::power::EV_PENDING), 0xFFFF_FFFF); xl.power_susres.push(RegOrField::Reg(utra::power::EV_ENABLE), None); @@ -225,6 +244,14 @@ mod implementation { self.event_susres.resume(); self.gpio_susres.resume(); } + #[allow(dead_code)] + pub fn activity_set_period(&mut self, period: u32) { + self.activity_period = period; + self.power_csr.wfo(utra::power::SAMPLING_PERIOD_SAMPLE_PERIOD, period); + } + pub fn activity_get_period(&mut self) -> u32 { + self.activity_period + } pub fn gpio_dout(&mut self, d: u32) { self.gpio_csr.wfo(utra::gpio::OUTPUT_OUTPUT, d); @@ -598,6 +625,7 @@ fn xmain() -> ! { // register a suspend/resume listener let sr_cid = xous::connect(llio_sid).expect("couldn't create suspend callback connection"); let mut susres = susres::Susres::new(&xns, Opcode::SuspendResume as u32, sr_cid).expect("couldn't create suspend/resume object"); + let mut latest_activity = 0; let mut usb_cb_conns: [Option; 32] = [None; 32]; let mut com_cb_conns: [Option; 32] = [None; 32]; @@ -810,6 +838,15 @@ fn xmain() -> ! { Some(Opcode::GpioIntHappened) => msg_scalar_unpack!(msg, channel, _, _, _, { send_event(&gpio_cb_conns, channel as usize); }), + Some(Opcode::EventActivityHappened) => msg_scalar_unpack!(msg, activity, _, _, _, { + log::debug!("activity: {}", activity); + latest_activity = activity as u32; + }), + Some(Opcode::GetActivity) => msg_blocking_scalar_unpack!(msg, _, _, _, _, { + let period = llio.activity_get_period() as u32; + log::debug!("activity/period: {}/{}, {:.2}%", latest_activity, period, (latest_activity as f32 / period as f32) * 100.0); + xous::return_scalar2(msg.sender, latest_activity as usize, period as usize).expect("couldn't return activity"); + }), Some(Opcode::Quit) => { log::info!("Received quit opcode, exiting."); let dropconn = xous::connect(i2c_sid).unwrap(); diff --git a/svd2utra/examples/soc.svd b/svd2utra/examples/soc.svd index abb9485fc..0cfe8a7c1 100644 --- a/svd2utra/examples/soc.svd +++ b/svd2utra/examples/soc.svd @@ -3,7 +3,7 @@ litex SOC - + 8 32 @@ -1162,7 +1162,7 @@ register to disable individual events.]]> GIT_MAJOR +``v0.8.1``, so this value is ``0``.]]> 0x0008 0x00 32 @@ -1178,9 +1178,9 @@ register to disable individual events.]]> GIT_MINOR +``v0.8.1``, so this value is ``8``.]]> 0x000c - 0x00 + 0x08 32 @@ -1194,9 +1194,9 @@ register to disable individual events.]]> GIT_REVISION +``v0.8.1``, so this value is ``1``.]]> 0x0010 - 0x00 + 0x01 32 @@ -1210,10 +1210,10 @@ register to disable individual events.]]> GIT_GITREV 0x0014 - 0x9e77f50e + 0xcf5b40e6 32 @@ -2657,10 +2657,112 @@ sources (power, sha512, and engine25519)]]> + + WAKEUP_SOURCE + 0x0008 + 0xff + 32 + + + kbd + 0 + [0:0] + 0 + + + + ticktimer + 1 + [1:1] + 1 + + + + timer0 + 2 + [2:2] + 2 + + + + usb + 3 + [3:3] + 3 + + + + audio + 4 + [4:4] + 4 + + + + com + 5 + [5:5] + 5 + + + + rtc + 6 + [6:6] + 6 + + + + console + 7 + [7:7] + 7 + + + + + + ACTIVITY_RATE + 0x000c + 0x00 + 32 + + + counts_awake + 30 + [30:0] + 0 + + + + + + SAMPLING_PERIOD + 0x0010 + 0x00 + 32 + + + sample_period + 30 + [30:0] + 0 + + + + kill_sampler + 31 + [31:31] + 31 + + + + VIBE - 0x0008 + 0x0014 0x00 32 @@ -2675,8 +2777,8 @@ sources (power, sha512, and engine25519)]]> EV_STATUS - - 0x000c + + 0x0018 0x00 32 @@ -2687,12 +2789,19 @@ sources (power, sha512, and engine25519)]]> 0 + + activity_update + 1 + [1:1] + 1 + + EV_PENDING - - 0x0010 + + 0x001c 0x00 32 @@ -2703,12 +2812,19 @@ sources (power, sha512, and engine25519)]]> 0 + + activity_update + 1 + [1:1] + 1 + + EV_ENABLE - - 0x0014 + + 0x0020 0x00 32 @@ -2719,12 +2835,19 @@ sources (power, sha512, and engine25519)]]> 0 + + activity_update + 1 + [1:1] + 1 + + 0 - 0x18 + 0x24 registers @@ -3316,7 +3439,7 @@ inject too fast.]]> SEED1 0x0000 - 0x56f38707 + 0x742b5c26 32 @@ -3331,7 +3454,7 @@ inject too fast.]]> SEED0 0x0004 - 0x400f5344 + 0x645c9ef4 32