Skip to content

Commit

Permalink
wip - cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
lzrd committed Feb 3, 2025
1 parent fc601ba commit 5b84222
Show file tree
Hide file tree
Showing 7 changed files with 550 additions and 494 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

3 changes: 2 additions & 1 deletion app/oxide-rot-1/app-dev.toml
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,11 @@ priority = 4
max-sizes = {flash = 32768, ram = 9120}
uses = ["flexcomm5", "iocon"]
start = true
stacksize = 1536
stacksize = 1280
task-slots = ["gpio_driver", "syscon_driver", "attest"]
notifications = ["spi-irq", "timer", "sp_reset-irq", "jtag_detect-irq"]
interrupts = {"flexcomm5.irq" = "spi-irq", "pint.irq0" = "sp_reset-irq", "pint.irq1" = "jtag_detect-irq" }
features = ["enable_ext_sp_reset"]

[tasks.swd.config]
# MOSI = PIO0_8
Expand Down
2 changes: 2 additions & 0 deletions drv/lpc55-swd/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ idol-runtime = { workspace = true }
lpc55-pac = { workspace = true }
num-traits = { workspace = true }
zerocopy = { workspace = true }
bitflags = { workspace = true }

attest-api = { path = "../../task/attest-api" }
drv-lpc55-gpio-api = { path = "../lpc55-gpio-api" }
Expand All @@ -35,6 +36,7 @@ serde = { workspace = true }

[features]
no-ipc-counters = ["idol/no-counters"]
enable_ext_sp_reset = []

# This section is here to discourage RLS/rust-analyzer from doing test builds,
# since test builds don't work for cross compilation.
Expand Down
31 changes: 12 additions & 19 deletions drv/lpc55-swd/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use anyhow::{bail, Context, Result};
use build_lpc55pins::PinConfig;
use call_rustfmt::rustfmt;
use endoscope_abi::{LOAD_SYMBOL, RESET_VECTOR_SYMBOL, SHARED_STRUCT_SYMBOL};
use endoscope_abi::{LOAD_SYMBOL, SHARED_STRUCT_SYMBOL};
use goblin::container::Container;
use goblin::elf::section_header::{SectionHeader, SHF_ALLOC, SHT_PROGBITS};
use goblin::elf::Elf;
Expand Down Expand Up @@ -97,18 +97,11 @@ fn generate_swd_functions(config: &TaskConfig) -> Result<()> {
Ok(())
}

fn get_endoscope_path() -> PathBuf {
const KEY: &str = "CARGO_BIN_FILE_ENDOSCOPE";
for (key, value) in std::env::vars() {
if key == KEY {
return PathBuf::from(value);
}
}
panic!("No environment variable named {KEY}");
}

fn prepare_endoscope() -> Result<(), anyhow::Error> {
let elf_path = get_endoscope_path();
let key = "CARGO_BIN_FILE_ENDOSCOPE";
let elf_path = PathBuf::from(
std::env::var(key).context(format!("Cannot read env var '{}'", key))?,
);
let data = std::fs::read(&elf_path).context("could not open ELF file")?;
let elf = Elf::parse(&data).context("cannot parse ELF file")?;

Expand All @@ -133,8 +126,6 @@ fn prepare_endoscope() -> Result<(), anyhow::Error> {
(LOAD_SYMBOL, "LOAD"),
// Address of endoscope output struct
(SHARED_STRUCT_SYMBOL, "SHARED"),
// Reset vector must agree with __vector_table[1]
(RESET_VECTOR_SYMBOL, "RESET"),
]
.iter()
{
Expand Down Expand Up @@ -179,8 +170,7 @@ fn prepare_endoscope() -> Result<(), anyhow::Error> {
Ok(())
}

/// Given a reader on an ELF file and a list of symbol names, return
/// the executable image and symbol values.
/// Given a reader on an ELF file return the executable image.
pub fn get_elf<R>(mut reader: R) -> Result<Vec<u8>, anyhow::Error>
where
R: Read + Seek,
Expand Down Expand Up @@ -214,9 +204,12 @@ where
.collect();
let bin_size: usize = sections.iter().map(|sh| sh.vm_range().len()).sum();

// Clippy is ignoring the profile when building the endoscope blob
// which results in an enormous binary. Since we're not going to
// actually build the swd task, this can be ignored.
// Do a sanity check on the size of the blob based on what we've seen.
//
// Note that clippy ignores the profile (or equivalent) when building the
// endoscope blob which results in an enormous binary. Since we're not
// going to actually build the swd task when running clippy, the large
// size can be ignored.
// TODO: Track down an existing cargo or rust bug or create a new one.
#[cfg(not(clippy))]
if bin_size > 6 * 1024 {
Expand Down
189 changes: 189 additions & 0 deletions drv/lpc55-swd/src/armv7debug.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
// 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/.
//
//
// For the STM32H7xx, see ARMv7-M Architecture Reference Manual
// Part 3 Debug Arch.
// https://developer.arm.com/documentation/ddi0403/d/Debug-Architecture?lang=en

use bitflags::bitflags;

pub trait DpAddressable {
// Address for accessing a DP Register
fn addr() -> u32;
}

// For keeping track of unwinding debug actions
bitflags! {
#[derive(PartialEq, Eq, Copy, Clone)]
pub struct Undo: u8 {
// Need self.swd_finish()
const SWD = 1 << 0;
// Need self.sp_reset_leave(true)
const RESET = 1 << 1;
// Need DEMCR = 0
const VC_CORERESET = 1 << 2;
// Need to clear debug enable.
const DEBUGEN = 1 << 3;
}
}

// RW 0x00000000 Debug Halting Control and Status Register
// Some DHCSR bits have different read vs. write meanings
// Specifically, the MAGIC value enables writing other control bits
// but some of those bits are status bits when read.
bitflags! {
#[derive(PartialEq, Eq, Copy, Clone)]
pub struct Dhcsr: u32 {
// At least one reset since last DHCSR read. clear on read.
const S_RESET_ST = 1 << 25;
const S_RETIRE_ST = 1 << 24;
const S_LOCKUP = 1 << 19;
const S_SLEEP = 1 << 18;
const S_HALT = 1 << 17;
const S_REGRDY = 1 << 16;

// Magic number allows setting C_* bits.
const DBGKEY = 0xA05F << 16;

const C_SNAPSTALL = 1 << 5;
const C_MASKINTS = 1 << 3;
const C_STEP = 1 << 2;
const C_HALT = 1 << 1;
const C_DEBUGEN = 1 << 0;
const _ = !0;
}
}

impl From<u32> for Dhcsr {
fn from(v: u32) -> Self {
Self::from_bits_retain(v)
}
}

impl DpAddressable for Dhcsr {
fn addr() -> u32 {
Self::ADDRESS
}
}

impl Dhcsr {
const ADDRESS: u32 = 0xE000EDF0;
pub fn halt() -> Self {
Self::DBGKEY | Self::C_HALT | Self::C_DEBUGEN
}
pub fn resume() -> Self {
Self::DBGKEY | Self::C_DEBUGEN
}
pub fn end_debug() -> Self {
Self::DBGKEY
}
pub fn is_halted(self) -> bool {
self & Self::S_HALT == Self::S_HALT
}
pub fn is_regrdy(self) -> bool {
self & Self::S_REGRDY == Self::S_REGRDY
}
pub fn _is_lockup(self) -> bool {
self & Self::S_LOCKUP == Self::S_LOCKUP
}
}

// Debug Core Register Selector Register
pub const DCRSR: u32 = 0xE000EDF4;
// Debug Core Register Data Register
pub const DCRDR: u32 = 0xE000EDF8;

// DEMCR RW 0x00000000 Debug Exception and Monitor Control Register
bitflags! {
#[derive(PartialEq, Eq, Copy, Clone)]
pub struct Demcr: u32 {
const MON_EN = 1 << 16;
const VC_HARDERR = 1 << 10;
const VC_INTERR = 1 << 9;
const VC_BUSERR = 1 << 8;
const VC_STATERR = 1 << 7;
const VC_CHKERR = 1 << 6;
const VC_NOCPERR = 1 << 5;
const VC_MMERR = 1 << 4;
const VC_CORERESET = 1 << 0;
}
}

impl DpAddressable for Demcr {
fn addr() -> u32 {
Self::ADDRESS
}
}

impl Demcr {
const ADDRESS: u32 = 0xE000EDFC;
}

// Armv7-M Arch. Ref. Manual - C1.6.1 Debug Fault Status Register
// RW Init: 0x00000000[on power-on reset only]
bitflags! {
#[derive(PartialEq, Eq, Copy, Clone)]
pub struct Dfsr: u32 {
// Assertion of an external debug request
const EXTERNAL = 1 << 4;
// Vector catch triggered
const VCATCH = 1 << 3;
// At least one DWT event
const DWTTRAP = 1 << 2;
// Breakpoint
const BKPT = 1 << 1;
// Halt request debug event.
// • A C_HALT or C_STEP request, triggered by a write to the DHCSR,
// see Debug Halting Control and Status Register, DHCSR.
// • A step request triggered by setting DEMCR.MON_STEP to 1,
// see Debug monitor stepping on page C1-696.
const HALTED = 1 << 0;
const _ = !0;
}
}

impl DpAddressable for Dfsr {
fn addr() -> u32 {
Self::ADDRESS
}
}
impl Dfsr {
const ADDRESS: u32 = 0xE000ED30;
pub fn _is_faulted(self) -> bool {
(self
& (Self::EXTERNAL
| Self::VCATCH
| Self::DWTTRAP
| Self::BKPT
| Self::HALTED))
.bits()
!= 0
}
pub fn is_vcatch(self) -> bool {
self & Self::VCATCH == Self::VCATCH
}
}

#[derive(PartialEq, Copy, Clone)]
#[repr(u16)]
pub enum Reg {
Sp = 0b0001101,
Lr = 0b0001110,
Dr = 0b0001111, // DebugReturnAddress, see C1-704
Xpsr = 0b0010000,
Msp = 0b0010001,
Psp = 0b0010010,
Cfbp = 0b0010100, // [31:24] CONTROL, [23:15] FAULTMASK, [15:8] BASEPRI, [7:0] PRIMASK
Fpscr = 0b0100001,
}

impl From<Reg> for u16 {
fn from(r: Reg) -> u16 {
r as u16
}
}

pub const _ICSR: u32 = 0xE000ED04;
pub const VTOR: u32 = 0xE000ED08;
Loading

0 comments on commit 5b84222

Please sign in to comment.