use bitfield::bitfield;
use std::mem::size_of;
use crate::{core::BreakpointCause, HaltReason};
pub trait Armv8DebugRegister {
const NUMBER: usize;
const NAME: &'static str;
fn get_mmio_address(base_address: u64) -> u64 {
base_address + (Self::NUMBER * size_of::<u32>()) as u64
}
}
bitfield! {
#[derive(Copy, Clone)]
pub struct Edscr(u32);
impl Debug;
pub tfo, set_tfo: 31;
pub rxfull, set_rxfull: 30;
pub txfull, set_txfull: 29;
pub ito, _: 28;
pub rxo, _: 27;
pub txu, _: 26;
pub pipeadv, _: 25;
pub ite, set_ite: 24;
pub intdis, set_intdis: 23, 22;
pub tda, set_tda: 21;
pub ma, set_ma: 20;
pub sc2, set_sc2: 19;
pub ns, _: 18;
pub sdd, _: 16;
pub hde, set_hde: 14;
pub rw, set_rw: 13, 10;
pub el, _: 9, 8;
pub a, _: 7;
pub err, _: 6;
pub status, set_status: 5, 0;
}
impl Edscr {
pub fn currently_64_bit(&self) -> bool {
self.rw() & (1 << self.el()) > 0
}
pub fn halted(&self) -> bool {
match self.status() {
0b000001 => false,
0b000010 => false,
0b000111 => true,
0b010011 => true,
0b011011 => true,
0b011111 => true,
0b100011 => true,
0b100111 => true,
0b101011 => true,
0b101111 => true,
0b110011 => true,
0b110111 => true,
0b111011 => true,
_ => false,
}
}
pub fn halt_reason(&self) -> HaltReason {
match self.status() {
0b000111 => HaltReason::Breakpoint(BreakpointCause::Unknown),
0b010011 => HaltReason::Request,
0b011011 => HaltReason::Step,
0b011111 => HaltReason::Step,
0b111011 => HaltReason::Step,
0b100011 => HaltReason::Exception,
0b100111 => HaltReason::Exception,
0b101011 => HaltReason::Watchpoint,
0b101111 => HaltReason::Breakpoint(BreakpointCause::Software),
0b110011 => HaltReason::Exception,
0b110111 => HaltReason::Exception,
_ => HaltReason::Unknown,
}
}
}
impl Armv8DebugRegister for Edscr {
const NUMBER: usize = 34;
const NAME: &'static str = "EDSCR";
}
impl From<u32> for Edscr {
fn from(value: u32) -> Self {
Self(value)
}
}
impl From<Edscr> for u32 {
fn from(value: Edscr) -> Self {
value.0
}
}
bitfield! {
#[derive(Copy, Clone)]
pub struct Edlar(u32);
impl Debug;
pub value, set_value : 31, 0;
}
impl Armv8DebugRegister for Edlar {
const NUMBER: usize = 1004;
const NAME: &'static str = "EDLAR";
}
impl From<u32> for Edlar {
fn from(value: u32) -> Self {
Self(value)
}
}
impl From<Edlar> for u32 {
fn from(value: Edlar) -> Self {
value.0
}
}
bitfield! {
#[derive(Copy, Clone)]
pub struct Dbgbvr(u32);
impl Debug;
pub value, set_value : 31, 0;
}
impl Armv8DebugRegister for Dbgbvr {
const NUMBER: usize = 256;
const NAME: &'static str = "DBGBVR";
}
impl From<u32> for Dbgbvr {
fn from(value: u32) -> Self {
Self(value)
}
}
impl From<Dbgbvr> for u32 {
fn from(value: Dbgbvr) -> Self {
value.0
}
}
bitfield! {
#[derive(Copy, Clone)]
pub struct Dbgbcr(u32);
impl Debug;
pub bt, set_bt : 23, 20;
pub lbn, set_lbn : 19, 16;
pub ssc, set_ssc : 15, 14;
pub hmc, set_hmc: 13;
pub bas, set_bas: 8, 5;
pub pmc, set_pmc: 2, 1;
pub e, set_e: 0;
}
impl Armv8DebugRegister for Dbgbcr {
const NUMBER: usize = 258;
const NAME: &'static str = "DBGBCR";
}
impl From<u32> for Dbgbcr {
fn from(value: u32) -> Self {
Self(value)
}
}
impl From<Dbgbcr> for u32 {
fn from(value: Dbgbcr) -> Self {
value.0
}
}
bitfield! {
#[derive(Copy, Clone)]
pub struct Eddfr(u32);
impl Debug;
pub ctx_cmps, _: 31, 28;
pub wrps, _: 23, 20;
pub brps, set_brps: 15, 12;
pub pmuver, _: 11, 8;
pub tracever, _: 7, 4;
}
impl Armv8DebugRegister for Eddfr {
const NUMBER: usize = 842;
const NAME: &'static str = "EDDFR";
}
impl From<u32> for Eddfr {
fn from(value: u32) -> Self {
Self(value)
}
}
impl From<Eddfr> for u32 {
fn from(value: Eddfr) -> Self {
value.0
}
}
bitfield! {
#[derive(Copy, Clone)]
pub struct Editr(u32);
impl Debug;
pub value, set_value: 31, 0;
}
impl Armv8DebugRegister for Editr {
const NUMBER: usize = 33;
const NAME: &'static str = "EDITR";
}
impl From<u32> for Editr {
fn from(value: u32) -> Self {
Self(value)
}
}
impl From<Editr> for u32 {
fn from(value: Editr) -> Self {
value.0
}
}
bitfield! {
#[derive(Copy, Clone)]
pub struct Edrcr(u32);
impl Debug;
pub cbrrq, set_cbrrq: 4;
pub cpsa, set_cpsa: 3;
pub cse, set_cse: 2;
}
impl Armv8DebugRegister for Edrcr {
const NUMBER: usize = 36;
const NAME: &'static str = "EDRCR";
}
impl From<u32> for Edrcr {
fn from(value: u32) -> Self {
Self(value)
}
}
impl From<Edrcr> for u32 {
fn from(value: Edrcr) -> Self {
value.0
}
}
bitfield! {
#[derive(Copy, Clone)]
pub struct Edecr(u32);
impl Debug;
pub ss, set_ss : 2;
pub rce, set_rce : 1;
pub osuce, set_osuce : 0;
}
impl Armv8DebugRegister for Edecr {
const NUMBER: usize = 9;
const NAME: &'static str = "EDECR";
}
impl From<u32> for Edecr {
fn from(value: u32) -> Self {
Self(value)
}
}
impl From<Edecr> for u32 {
fn from(value: Edecr) -> Self {
value.0
}
}
bitfield! {
#[derive(Copy, Clone)]
pub struct Edprcr(u32);
impl Debug;
pub corepurq, set_corepurq : 3;
pub cwrr, set_cwrr : 1;
pub corenpdrq, set_corenpdrq : 0;
}
impl Armv8DebugRegister for Edprcr {
const NUMBER: usize = 196;
const NAME: &'static str = "EDPRCR";
}
impl From<u32> for Edprcr {
fn from(value: u32) -> Self {
Self(value)
}
}
impl From<Edprcr> for u32 {
fn from(value: Edprcr) -> Self {
value.0
}
}
bitfield! {
#[derive(Copy, Clone)]
pub struct Dbgdtrtx(u32);
impl Debug;
pub value, set_value: 31, 0;
}
impl Armv8DebugRegister for Dbgdtrtx {
const NUMBER: usize = 35;
const NAME: &'static str = "DBGDTRTX";
}
impl From<u32> for Dbgdtrtx {
fn from(value: u32) -> Self {
Self(value)
}
}
impl From<Dbgdtrtx> for u32 {
fn from(value: Dbgdtrtx) -> Self {
value.0
}
}
bitfield! {
#[derive(Copy, Clone)]
pub struct Dbgdtrrx(u32);
impl Debug;
pub value, set_value: 31, 0;
}
impl Armv8DebugRegister for Dbgdtrrx {
const NUMBER: usize = 32;
const NAME: &'static str = "DBGDTRRX";
}
impl From<u32> for Dbgdtrrx {
fn from(value: u32) -> Self {
Self(value)
}
}
impl From<Dbgdtrrx> for u32 {
fn from(value: Dbgdtrrx) -> Self {
value.0
}
}
bitfield! {
#[derive(Copy, Clone)]
pub struct Edprsr(u32);
impl Debug;
pub sdr, set_sdr: 11;
pub spmad, _: 10;
pub epmad, _: 9;
pub sdad, _: 8;
pub edad, _: 7;
pub dlk, _: 6;
pub oslk, _: 5;
pub halted, _: 4;
pub sr, _: 3;
pub r, _: 2;
pub spd, _: 1;
pub pu, _: 0;
}
impl Armv8DebugRegister for Edprsr {
const NUMBER: usize = 197;
const NAME: &'static str = "EDPRSR";
}
impl From<u32> for Edprsr {
fn from(value: u32) -> Self {
Self(value)
}
}
impl From<Edprsr> for u32 {
fn from(value: Edprsr) -> Self {
value.0
}
}
bitfield! {
#[derive(Copy, Clone)]
pub struct CtiControl(u32);
impl Debug;
pub glben, set_glben : 0;
}
impl Armv8DebugRegister for CtiControl {
const NUMBER: usize = 0;
const NAME: &'static str = "CTICONTROL";
}
impl From<u32> for CtiControl {
fn from(value: u32) -> Self {
Self(value)
}
}
impl From<CtiControl> for u32 {
fn from(value: CtiControl) -> Self {
value.0
}
}
bitfield! {
#[derive(Copy, Clone)]
pub struct CtiGate(u32);
impl Debug;
pub en, set_en : 0, 0, 32;
}
impl Armv8DebugRegister for CtiGate {
const NUMBER: usize = 80;
const NAME: &'static str = "CTIGATE";
}
impl From<u32> for CtiGate {
fn from(value: u32) -> Self {
Self(value)
}
}
impl From<CtiGate> for u32 {
fn from(value: CtiGate) -> Self {
value.0
}
}
bitfield! {
#[derive(Copy, Clone)]
pub struct CtiOuten(u32);
impl Debug;
pub outen, set_outen : 0, 0, 32;
}
impl Armv8DebugRegister for CtiOuten {
const NUMBER: usize = 40;
const NAME: &'static str = "CTIOUTEN";
}
impl From<u32> for CtiOuten {
fn from(value: u32) -> Self {
Self(value)
}
}
impl From<CtiOuten> for u32 {
fn from(value: CtiOuten) -> Self {
value.0
}
}
bitfield! {
#[derive(Copy, Clone)]
pub struct CtiApppulse(u32);
impl Debug;
pub apppulse, set_apppulse : 0, 0, 32;
}
impl Armv8DebugRegister for CtiApppulse {
const NUMBER: usize = 7;
const NAME: &'static str = "CTIAPPPULSE";
}
impl From<u32> for CtiApppulse {
fn from(value: u32) -> Self {
Self(value)
}
}
impl From<CtiApppulse> for u32 {
fn from(value: CtiApppulse) -> Self {
value.0
}
}
bitfield! {
#[derive(Copy, Clone)]
pub struct CtiIntack(u32);
impl Debug;
pub ack, set_ack : 0, 0, 32;
}
impl Armv8DebugRegister for CtiIntack {
const NUMBER: usize = 4;
const NAME: &'static str = "CTIINTACK";
}
impl From<u32> for CtiIntack {
fn from(value: u32) -> Self {
Self(value)
}
}
impl From<CtiIntack> for u32 {
fn from(value: CtiIntack) -> Self {
value.0
}
}
bitfield! {
#[derive(Copy, Clone)]
pub struct CtiTrigoutstatus(u32);
impl Debug;
pub status, _ : 0, 0, 32;
}
impl Armv8DebugRegister for CtiTrigoutstatus {
const NUMBER: usize = 77;
const NAME: &'static str = "CTITRIGOUTSTATUS";
}
impl From<u32> for CtiTrigoutstatus {
fn from(value: u32) -> Self {
Self(value)
}
}
impl From<CtiTrigoutstatus> for u32 {
fn from(value: CtiTrigoutstatus) -> Self {
value.0
}
}