Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 12 additions & 2 deletions app/cosmo/base.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ fwid = true

[kernel]
name = "cosmo"
requires = {flash = 32768, ram = 8192}
features = ["dump"]
requires = {flash = 32768, ram = 16384}
features = ["dump", "traptrace"]

[mmio]
peripheral-region = "fmc_nor_psram_bank_1"
Expand Down Expand Up @@ -357,6 +357,16 @@ notifications = ["jefe-state-change", "timer"]
task-slots = ["jefe", "spartan7_loader", "packrat", "sensor"]
uses = ["mmio_dimms"]

[tasks.bork]
name = "task-bork"
priority = 10
max-sizes = {flash = 16384, ram = 16384 }
start = true
notifications = ["timer"]
task-slots = ["sprot", "sys"]
features = ["h753"]
uses = ["rtc"]

[tasks.auxflash]
name = "drv-auxflash-server"
priority = 3
Expand Down
23 changes: 23 additions & 0 deletions app/cosmo/src/tracing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ fn timer_isr_exit() {
}

fn context_switch(addr: usize) {
let rtc = unsafe { &*stm32h7::stm32h753::RTC::ptr() };
rtc.bkpr[0].modify(|_, w| w.bkp().bits(addr as u32));
trace(Event::ContextSwitch(addr));
}

Expand All @@ -86,5 +88,26 @@ static TRACING: kern::profiling::EventsTable = kern::profiling::EventsTable {
};

pub fn table() -> &'static kern::profiling::EventsTable {
let rtc = unsafe { &*stm32h7::stm32h753::RTC::ptr() };

// Unlock
rtc.wpr.write(|w| w.key().bits(0xca));
rtc.wpr.write(|w| w.key().bits(0x53));

// don't erase!
rtc.tampcr.modify(|_, w| {
w.tamp3noerase()
.set_bit()
.tamp2noerase()
.set_bit()
.tamp1noerase()
.set_bit()
});

// Save our last state
let last = rtc.bkpr[0].read().bkp().bits();
// And rotate
rtc.bkpr[1].modify(|_, w| w.bkp().bits(last));

&TRACING
}
2 changes: 2 additions & 0 deletions app/grapefruit/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ readme = "README.md"
version = "0.1.0"

[features]
traptrace = ["ringbuf"]
dump = ["kern/dump"]

[dependencies]
cortex-m = { workspace = true }
cortex-m-rt = { workspace = true }
cfg-if = { workspace = true }
stm32h7 = { workspace = true, features = ["rt", "stm32h753"] }
ringbuf = { path = "../../lib/ringbuf", optional = true }

drv-stm32h7-startup = { path = "../../drv/stm32h7-startup", features = ["h753"] }
kern = { path = "../../sys/kern" }
Expand Down
12 changes: 11 additions & 1 deletion app/grapefruit/base.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ register-map = "../../drv/spartan7-loader/grapefruit/gfruit_top.json"
[kernel]
name = "grapefruit"
requires = {flash = 32768, ram = 8192}
features = ["dump"]
features = ["dump", "traptrace"]

[caboose]
tasks = ["control_plane_agent"]
Expand Down Expand Up @@ -337,6 +337,16 @@ task-slots = ["hash_driver", "spartan7_loader"]
stacksize = 4000
notifications = ["timer"]

[tasks.bork]
name = "task-bork"
priority = 8
max-sizes = {flash = 16384, ram = 16384 }
start = true
notifications = ["timer"]
task-slots = ["sprot", "sys"]
features = ["h753"]
uses = ["rtc"]

[config.net]
# VLAN configuration
[config.net.vlans.sidecar1]
Expand Down
1 change: 1 addition & 0 deletions app/grapefruit/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@

fn main() {
build_util::expose_target_board();
build_util::expose_m_profile().unwrap();
}
6 changes: 6 additions & 0 deletions app/grapefruit/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,18 @@ use drv_stm32h7_startup::ClockConfig;

use cortex_m_rt::entry;

#[cfg(feature = "traptrace")]
mod tracing;

#[entry]
fn main() -> ! {
system_init();

const CYCLES_PER_MS: u32 = 400_000;

#[cfg(feature = "traptrace")]
kern::profiling::configure_events_table(tracing::table());

unsafe { kern::startup::start_kernel(CYCLES_PER_MS) }
}

Expand Down
113 changes: 113 additions & 0 deletions app/grapefruit/src/tracing.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

//
// If you are cutting-and-pasting this code into another kernel (and that
// kernel is armv6m), it is hoped that you will cut-and-paste this compile
// error along with it and take heed of its admonition!
//
#[cfg(not(any(armv7m, armv8m)))]
compile_error!("ringbuf is unsound in the kernel on armv6m");

use ringbuf::*;

#[derive(Copy, Clone, PartialEq)]
enum Event {
SyscallEnter(u32),
SyscallExit,
SecondarySyscallEnter,
SecondarySyscallExit,
IsrEnter,
IsrExit,
TimerIsrEnter,
TimerIsrExit,
ContextSwitch(usize),
}

#[derive(Copy, Clone, PartialEq)]
enum Trace {
Event(Event),
None,
}

ringbuf!(Trace, 128, Trace::None);

fn trace(event: Event) {
ringbuf_entry!(Trace::Event(event));
}

fn syscall_enter(nr: u32) {
trace(Event::SyscallEnter(nr));
}

fn syscall_exit() {
trace(Event::SyscallExit);
}

fn secondary_syscall_enter() {
trace(Event::SecondarySyscallEnter);
}

fn secondary_syscall_exit() {
trace(Event::SecondarySyscallExit);
}

fn isr_enter() {
trace(Event::IsrEnter);
}

fn isr_exit() {
trace(Event::IsrExit);
}

fn timer_isr_enter() {
trace(Event::TimerIsrEnter);
}

fn timer_isr_exit() {
trace(Event::TimerIsrExit);
}

fn context_switch(addr: usize) {
let rtc = unsafe { &*stm32h7::stm32h753::RTC::ptr() };
rtc.bkpr[0].modify(|_, w| w.bkp().bits(addr as u32));
trace(Event::ContextSwitch(addr));
}

static TRACING: kern::profiling::EventsTable = kern::profiling::EventsTable {
syscall_enter,
syscall_exit,
secondary_syscall_enter,
secondary_syscall_exit,
isr_enter,
isr_exit,
timer_isr_enter,
timer_isr_exit,
context_switch,
};

pub fn table() -> &'static kern::profiling::EventsTable {
let rtc = unsafe { &*stm32h7::stm32h753::RTC::ptr() };

// Unlock
rtc.wpr.write(|w| w.key().bits(0xca));
rtc.wpr.write(|w| w.key().bits(0x53));

// don't erase!
rtc.tampcr.modify(|_, w| {
w.tamp3noerase()
.set_bit()
.tamp2noerase()
.set_bit()
.tamp1noerase()
.set_bit()
});

// Save our last state
let last = rtc.bkpr[0].read().bkp().bits();
// And rotate
rtc.bkpr[1].modify(|_, w| w.bkp().bits(last));

&TRACING
}
4 changes: 4 additions & 0 deletions chips/stm32h7/chip.toml
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ address = 0x52005000
size = 4096
interrupts = { irq = 92 }

[rtc]
address = 0x58004000
size = 1024

[eth]
address = 0x40028000
size = 0x2000
Expand Down
5 changes: 5 additions & 0 deletions drv/stm32h7-startup/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ unsafe fn system_pre_init() {
// convert it to a reference. We can have a reference to PWR because it's
// hardware, and is thus not uninitialized.
let pwr = &*device::PWR::ptr();
pwr.cr1.modify(|_, w| w.dbp().set_bit());
// Poke CR3 to enable the LDO and prevent further writes.
pwr.cr3.modify(|_, w| w.ldoen().set_bit());

Expand Down Expand Up @@ -324,6 +325,10 @@ pub fn system_init_custom(
// spin
}

p.RCC.cfgr.modify(|_, w| w.rtcpre().bits(0b100));

p.RCC.bdcr.modify(|_, w| w.rtcen().set_bit().rtcsel().lse());

// set RNG clock to PLL1 clock
#[cfg(any(feature = "h743", feature = "h753"))]
p.RCC.d2ccip2r.modify(|_, w| w.rngsel().pll1_q());
Expand Down
23 changes: 23 additions & 0 deletions idl/bork.idol
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Cosmo SPD task API
//
// Right now, this doesn't actually do anything, but it lets us use the idol
// runtime for notifications / dispatch.
Interface(
name: "Bork",
ops: {
"ping": (
doc: "blocks until the server is running",
args: {},
reply: Simple("()"),
idempotent: true,
),
"wave_bye_bye": (
doc: "wave bye bye",
args: {},
reply: Simple("()"),
idempotent: true,
),

},
)

2 changes: 1 addition & 1 deletion sys/kern/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ fn generate_statics(gen: &Generated) -> Result<()> {
#[no_mangle]
pub static HUBRIS_IMAGE_ID: u64 = #image_id;

static mut HUBRIS_TASK_TABLE_SPACE:
pub(crate) static mut HUBRIS_TASK_TABLE_SPACE:
core::mem::MaybeUninit<[crate::task::Task; HUBRIS_TASK_COUNT]> =
core::mem::MaybeUninit::uninit();
},
Expand Down
21 changes: 21 additions & 0 deletions sys/kern/src/arch/arm_m.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1346,6 +1346,21 @@ enum FaultType {

#[cfg(any(armv7m, armv8m))]
global_asm! {"
.section .text.im_dead
.globl im_dead
.type im_dead,function
.cpu cortex-m4 @ least common denominator we support
im_dead:
@ lie down try not to cry cry a lot
movw r0, #0xed0c
movt r0, #0xe000
movw r1, #0x0004
movt r1, #0x05fa
str.w r1, [r0]
1:
b 1b


.section .text.configurable_fault
.globl configurable_fault
.type configurable_fault,function
Expand Down Expand Up @@ -1416,6 +1431,12 @@ global_asm! {"
.type UsageFault,function
UsageFault:
b configurable_fault

.section .text.HardFault
.globl HardFault
.type HardFault,function
HardFault:
b im_dead
",
}

Expand Down
6 changes: 5 additions & 1 deletion sys/kern/src/profiling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,11 @@ pub(crate) fn event_timer_isr_exit() {
}

pub(crate) fn event_context_switch(tcb: usize) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this change, unless it was broken before?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The existing profiling just stores the base of the task, which is both fast and may have been fine for cliff's debugging (thanks again cliff for adding this). I was struggling to figure out how to go from task base to useful information so I did the calculation here. If we really hate this, we can get humility to do this work for us.

// HACK too hard to figure out the task ID from the base of the TCB
let base = core::ptr::addr_of_mut!(crate::startup::HUBRIS_TASK_TABLE_SPACE)
as *mut u32 as u32 as usize;
let size = core::mem::size_of::<crate::task::Task>();
if let Some(t) = table() {
(t.context_switch)(tcb)
(t.context_switch)((tcb - base) / size)
}
}
Loading
Loading