forked from probe-rs/probe-rs
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #130 from bugadani/xtensa-me
Xtensa: Implement instruction execution and memory access
- Loading branch information
Showing
9 changed files
with
1,198 additions
and
172 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
pub const fn rsr(opcode: u32, rs: u8, t: u8) -> u32 { | ||
opcode | (rs as u32) << 8 | (t as u32 & 0x0F) << 4 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
use crate::architecture::xtensa::arch::{CpuRegister, SpecialRegister}; | ||
|
||
pub mod format; | ||
|
||
#[derive(Clone, Copy, PartialEq, Debug)] | ||
pub enum Instruction { | ||
/// Loads a 32-bit word from the address in `src` into `DDR` | ||
/// Note: this is an illegal instruction when the processor is not in On-Chip Debug Mode | ||
Lddr32P(CpuRegister), | ||
|
||
/// Reads `SpecialRegister` into `CpuRegister` | ||
Rsr(SpecialRegister, CpuRegister), | ||
|
||
/// Writes `CpuRegister` into `SpecialRegister` | ||
Wsr(SpecialRegister, CpuRegister), | ||
|
||
/// Returns the Core to the Running state | ||
Rfdo(u8), | ||
} | ||
|
||
/// The architecture supports multi-word instructions. This enum represents the different encodings | ||
// ... but we only support narrow ones for now | ||
pub enum InstructionEncoding { | ||
/// Instruction encoding is narrow enough to fit into DIR0/DIR0EXEC | ||
Narrow(u32), | ||
} | ||
|
||
impl Instruction { | ||
pub fn encode(self) -> InstructionEncoding { | ||
let narrow = match self { | ||
Instruction::Lddr32P(src) => 0x0070E0 | (src.address() as u32 & 0x0F) << 8, | ||
Instruction::Rsr(sr, t) => format::rsr(0x030000, sr.address(), t.address()), | ||
Instruction::Wsr(sr, t) => format::rsr(0x130000, sr.address(), t.address()), | ||
Instruction::Rfdo(_) => 0xF1E000, | ||
}; | ||
|
||
InstructionEncoding::Narrow(narrow) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
#![allow(unused)] // TODO remove | ||
|
||
pub mod instruction; | ||
|
||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] | ||
pub enum Register { | ||
Cpu(CpuRegister), | ||
Special(SpecialRegister), | ||
} | ||
|
||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] | ||
pub enum CpuRegister { | ||
A0 = 0, | ||
A1 = 1, | ||
A2 = 2, | ||
A3 = 3, | ||
A4 = 4, | ||
A5 = 5, | ||
A6 = 6, | ||
A7 = 7, | ||
A8 = 8, | ||
A9 = 9, | ||
A10 = 10, | ||
A11 = 11, | ||
A12 = 12, | ||
A13 = 13, | ||
A14 = 14, | ||
A15 = 15, | ||
} | ||
|
||
impl CpuRegister { | ||
pub const fn scratch() -> Self { | ||
Self::A3 | ||
} | ||
|
||
pub const fn address(self) -> u8 { | ||
self as u8 | ||
} | ||
} | ||
|
||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] | ||
pub enum SpecialRegister { | ||
Lbeg = 0, | ||
Lend = 1, | ||
Lcount = 2, | ||
Sar = 3, | ||
Br = 4, | ||
Litbase = 5, | ||
Scompare1 = 12, | ||
AccLo = 16, | ||
AccHi = 17, | ||
M0 = 32, | ||
M1 = 33, | ||
M2 = 34, | ||
M3 = 35, | ||
Windowbase = 72, | ||
Windowstart = 73, | ||
PteVAddr = 83, | ||
RAsid = 90, | ||
// MpuEnB = 90, | ||
ITlbCfg = 91, | ||
DTlbCfg = 92, | ||
// MpuCfg = 92, | ||
ERAccess = 95, | ||
IBreakEnable = 96, | ||
Memctl = 97, | ||
CacheAdrDis = 98, | ||
AtomCtl = 99, | ||
Ddr = 104, | ||
Mepc = 106, | ||
Meps = 107, | ||
Mesave = 108, | ||
Mesr = 109, | ||
Mecr = 110, | ||
MeVAddr = 111, | ||
IBreakA0 = 128, | ||
IBreakA1 = 129, | ||
DBreakA0 = 144, | ||
DBreakA1 = 145, | ||
DBreakC0 = 160, | ||
DBreakC1 = 161, | ||
Epc1 = 177, | ||
Epc2 = 178, | ||
Epc3 = 179, | ||
Epc4 = 180, | ||
Epc5 = 181, | ||
Epc6 = 182, | ||
Epc7 = 183, | ||
IBreakC0 = 192, | ||
IBreakC1 = 193, | ||
// Depc = 192, | ||
Eps2 = 194, | ||
Eps3 = 195, | ||
Eps4 = 196, | ||
Eps5 = 197, | ||
Eps6 = 198, | ||
Eps7 = 199, | ||
ExcSave1 = 209, | ||
ExcSave2 = 210, | ||
ExcSave3 = 211, | ||
ExcSave4 = 212, | ||
ExcSave5 = 213, | ||
ExcSave6 = 214, | ||
ExcSave7 = 215, | ||
CpEnable = 224, | ||
// Interrupt = 226, | ||
IntSet = 226, | ||
IntClear = 227, | ||
IntEnable = 228, | ||
Ps = 230, | ||
VecBase = 231, | ||
ExcCause = 232, | ||
DebugCause = 233, | ||
CCount = 234, | ||
Prid = 235, | ||
ICount = 236, | ||
ICountLevel = 237, | ||
ExcVaddr = 238, | ||
CCompare0 = 240, | ||
CCompare1 = 241, | ||
CCompare2 = 242, | ||
Misc0 = 244, | ||
Misc1 = 245, | ||
Misc2 = 246, | ||
Misc3 = 247, | ||
} | ||
|
||
#[allow(non_upper_case_globals)] // Aliasses have same style as other register names | ||
impl SpecialRegister { | ||
// Aliasses | ||
pub const MpuEnB: Self = Self::RAsid; | ||
pub const MpuCfg: Self = Self::DTlbCfg; | ||
pub const Depc: Self = Self::IBreakC0; | ||
pub const Interrupt: Self = Self::IntSet; | ||
|
||
pub const fn address(self) -> u8 { | ||
self as u8 | ||
} | ||
} |
Oops, something went wrong.