forked from M-Labs/artiq
firmware: purge or1k
This commit is contained in:
parent
af263ffe1f
commit
61b0170a12
|
@ -7,10 +7,6 @@ extern crate log;
|
|||
#[cfg(feature = "smoltcp")]
|
||||
extern crate smoltcp;
|
||||
|
||||
#[cfg(target_arch = "or1k")]
|
||||
#[path = "or1k/mod.rs"]
|
||||
mod arch;
|
||||
|
||||
#[cfg(target_arch = "riscv32")]
|
||||
#[path = "riscv32imac/mod.rs"]
|
||||
mod arch;
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
use super::{irq, cache};
|
||||
|
||||
pub unsafe fn jump(addr: usize) -> ! {
|
||||
irq::set_ie(false);
|
||||
cache::flush_cpu_icache();
|
||||
asm!(r#"
|
||||
l.jr $0
|
||||
l.nop
|
||||
"# : : "r"(addr) : : "volatile");
|
||||
loop {}
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
#[cfg(has_ddrphy)]
|
||||
use core::ptr;
|
||||
use super::spr::*;
|
||||
#[cfg(has_ddrphy)]
|
||||
use csr;
|
||||
#[cfg(has_ddrphy)]
|
||||
use mem;
|
||||
|
||||
pub fn flush_cpu_icache() {
|
||||
unsafe {
|
||||
let iccfgr = mfspr(SPR_ICCFGR);
|
||||
let ways = 1 << (iccfgr & SPR_ICCFGR_NCW);
|
||||
let set_size = 1 << ((iccfgr & SPR_ICCFGR_NCS) >> 3);
|
||||
let block_size = if iccfgr & SPR_ICCFGR_CBS != 0 { 32 } else { 16 };
|
||||
let size = set_size * ways * block_size;
|
||||
|
||||
let mut i = 0;
|
||||
while i < size {
|
||||
mtspr(SPR_ICBIR, i);
|
||||
i += block_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn flush_cpu_dcache() {
|
||||
unsafe {
|
||||
let dccfgr = mfspr(SPR_DCCFGR);
|
||||
let ways = 1 << (dccfgr & SPR_ICCFGR_NCW);
|
||||
let set_size = 1 << ((dccfgr & SPR_DCCFGR_NCS) >> 3);
|
||||
let block_size = if dccfgr & SPR_DCCFGR_CBS != 0 { 32 } else { 16 };
|
||||
let size = set_size * ways * block_size;
|
||||
|
||||
let mut i = 0;
|
||||
while i < size {
|
||||
mtspr(SPR_DCBIR, i);
|
||||
i += block_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(has_ddrphy)]
|
||||
pub fn flush_l2_cache() {
|
||||
unsafe {
|
||||
for i in 0..2 * (csr::CONFIG_L2_SIZE as usize) / 4 {
|
||||
let addr = mem::MAIN_RAM_BASE + i * 4;
|
||||
ptr::read_volatile(addr as *const usize);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,107 +0,0 @@
|
|||
use core::{fmt, convert};
|
||||
|
||||
use super::spr::*;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum Exception {
|
||||
Reset = 0x1,
|
||||
BusError = 0x2,
|
||||
DataPageFault = 0x3,
|
||||
InsnPageFault = 0x4,
|
||||
Tick = 0x5,
|
||||
Alignment = 0x6,
|
||||
IllegalInsn = 0x7,
|
||||
Interrupt = 0x8,
|
||||
DtlbMiss = 0x9,
|
||||
ItlbMiss = 0xa,
|
||||
Range = 0xb,
|
||||
Syscall = 0xc,
|
||||
FloatingPoint = 0xd,
|
||||
Trap = 0xe,
|
||||
}
|
||||
|
||||
impl fmt::Display for Exception {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Exception::Reset => write!(f, "reset"),
|
||||
Exception::BusError => write!(f, "bus error"),
|
||||
Exception::DataPageFault => write!(f, "data page fault"),
|
||||
Exception::InsnPageFault => write!(f, "instruction page fault"),
|
||||
Exception::Tick => write!(f, "tick"),
|
||||
Exception::Alignment => write!(f, "alignment"),
|
||||
Exception::IllegalInsn => write!(f, "illegal instruction"),
|
||||
Exception::Interrupt => write!(f, "interrupt"),
|
||||
Exception::DtlbMiss => write!(f, "D-TLB miss"),
|
||||
Exception::ItlbMiss => write!(f, "I-TLB miss"),
|
||||
Exception::Range => write!(f, "range"),
|
||||
Exception::Syscall => write!(f, "system call"),
|
||||
Exception::FloatingPoint => write!(f, "floating point"),
|
||||
Exception::Trap => write!(f, "trap"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl convert::TryFrom<u32> for Exception {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(num: u32) -> Result<Self, Self::Error> {
|
||||
match num {
|
||||
0x1 => Ok(Exception::Reset),
|
||||
0x2 => Ok(Exception::BusError),
|
||||
0x3 => Ok(Exception::DataPageFault),
|
||||
0x4 => Ok(Exception::InsnPageFault),
|
||||
0x5 => Ok(Exception::Tick),
|
||||
0x6 => Ok(Exception::Alignment),
|
||||
0x7 => Ok(Exception::IllegalInsn),
|
||||
0x8 => Ok(Exception::Interrupt),
|
||||
0x9 => Ok(Exception::DtlbMiss),
|
||||
0xa => Ok(Exception::ItlbMiss),
|
||||
0xb => Ok(Exception::Range),
|
||||
0xc => Ok(Exception::Syscall),
|
||||
0xd => Ok(Exception::FloatingPoint),
|
||||
0xe => Ok(Exception::Trap),
|
||||
_ => Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_ie() -> bool {
|
||||
unsafe { mfspr(SPR_SR) & SPR_SR_IEE != 0 }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_ie(ie: bool) {
|
||||
if ie {
|
||||
unsafe { mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_IEE) }
|
||||
} else {
|
||||
unsafe { mtspr(SPR_SR, mfspr(SPR_SR) & !SPR_SR_IEE) }
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_mask() -> u32 {
|
||||
unsafe { mfspr(SPR_PICMR) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_mask(mask: u32) {
|
||||
unsafe { mtspr(SPR_PICMR, mask) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn pending_mask() -> u32 {
|
||||
unsafe { mfspr(SPR_PICSR) }
|
||||
}
|
||||
|
||||
pub fn enable(irq: u32) {
|
||||
set_mask(get_mask() | (1 << irq))
|
||||
}
|
||||
|
||||
pub fn disable(irq: u32) {
|
||||
set_mask(get_mask() & !(1 << irq))
|
||||
}
|
||||
|
||||
pub fn is_pending(irq: u32) -> bool {
|
||||
get_mask() & (1 << irq) != 0
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
pub mod spr;
|
||||
pub mod irq;
|
||||
pub mod cache;
|
||||
pub mod boot;
|
|
@ -1,231 +0,0 @@
|
|||
#[inline(always)]
|
||||
pub unsafe fn mfspr(reg: u32) -> u32 {
|
||||
let value: u32;
|
||||
asm!("l.mfspr $0, $1, 0" : "=r"(value) : "r"(reg) : : "volatile");
|
||||
value
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn mtspr(reg: u32, value: u32) {
|
||||
asm!("l.mtspr $0, $1, 0" : : "r"(reg), "r"(value) : : "volatile")
|
||||
}
|
||||
|
||||
/* Definition of special-purpose registers (SPRs). */
|
||||
|
||||
pub const MAX_GRPS: u32 = 32;
|
||||
pub const MAX_SPRS_PER_GRP_BITS: u32 = 11;
|
||||
pub const MAX_SPRS_PER_GRP: u32 = 1 << MAX_SPRS_PER_GRP_BITS;
|
||||
pub const MAX_SPRS: u32 = 0x10000;
|
||||
|
||||
/* Base addresses for the groups */
|
||||
pub const SPRGROUP_SYS: u32 = 0 << MAX_SPRS_PER_GRP_BITS;
|
||||
pub const SPRGROUP_DMMU: u32 = 1 << MAX_SPRS_PER_GRP_BITS;
|
||||
pub const SPRGROUP_IMMU: u32 = 2 << MAX_SPRS_PER_GRP_BITS;
|
||||
pub const SPRGROUP_DC: u32 = 3 << MAX_SPRS_PER_GRP_BITS;
|
||||
pub const SPRGROUP_IC: u32 = 4 << MAX_SPRS_PER_GRP_BITS;
|
||||
pub const SPRGROUP_MAC: u32 = 5 << MAX_SPRS_PER_GRP_BITS;
|
||||
pub const SPRGROUP_D: u32 = 6 << MAX_SPRS_PER_GRP_BITS;
|
||||
pub const SPRGROUP_PC: u32 = 7 << MAX_SPRS_PER_GRP_BITS;
|
||||
pub const SPRGROUP_PM: u32 = 8 << MAX_SPRS_PER_GRP_BITS;
|
||||
pub const SPRGROUP_PIC: u32 = 9 << MAX_SPRS_PER_GRP_BITS;
|
||||
pub const SPRGROUP_TT: u32 = 10 << MAX_SPRS_PER_GRP_BITS;
|
||||
pub const SPRGROUP_FP: u32 = 11 << MAX_SPRS_PER_GRP_BITS;
|
||||
|
||||
/* System control and status group */
|
||||
pub const SPR_VR: u32 = SPRGROUP_SYS + 0;
|
||||
pub const SPR_UPR: u32 = SPRGROUP_SYS + 1;
|
||||
pub const SPR_CPUCFGR: u32 = SPRGROUP_SYS + 2;
|
||||
pub const SPR_DMMUCFGR: u32 = SPRGROUP_SYS + 3;
|
||||
pub const SPR_IMMUCFGR: u32 = SPRGROUP_SYS + 4;
|
||||
pub const SPR_DCCFGR: u32 = SPRGROUP_SYS + 5;
|
||||
pub const SPR_ICCFGR: u32 = SPRGROUP_SYS + 6;
|
||||
pub const SPR_DCFGR: u32 = SPRGROUP_SYS + 7;
|
||||
pub const SPR_PCCFGR: u32 = SPRGROUP_SYS + 8;
|
||||
pub const SPR_VR2: u32 = SPRGROUP_SYS + 9;
|
||||
pub const SPR_AVR: u32 = SPRGROUP_SYS + 10;
|
||||
pub const SPR_EVBAR: u32 = SPRGROUP_SYS + 11;
|
||||
pub const SPR_AECR: u32 = SPRGROUP_SYS + 12;
|
||||
pub const SPR_AESR: u32 = SPRGROUP_SYS + 13;
|
||||
pub const SPR_NPC: u32 = SPRGROUP_SYS + 16; /* CZ 21/06/01 */
|
||||
pub const SPR_SR: u32 = SPRGROUP_SYS + 17; /* CZ 21/06/01 */
|
||||
pub const SPR_PPC: u32 = SPRGROUP_SYS + 18; /* CZ 21/06/01 */
|
||||
pub const SPR_FPCSR: u32 = SPRGROUP_SYS + 20; /* CZ 21/06/01 */
|
||||
pub const SPR_ISR_BASE: u32 = SPRGROUP_SYS + 21;
|
||||
pub const SPR_EPCR_BASE: u32 = SPRGROUP_SYS + 32; /* CZ 21/06/01 */
|
||||
pub const SPR_EPCR_LAST: u32 = SPRGROUP_SYS + 47; /* CZ 21/06/01 */
|
||||
pub const SPR_EEAR_BASE: u32 = SPRGROUP_SYS + 48;
|
||||
pub const SPR_EEAR_LAST: u32 = SPRGROUP_SYS + 63;
|
||||
pub const SPR_ESR_BASE: u32 = SPRGROUP_SYS + 64;
|
||||
pub const SPR_ESR_LAST: u32 = SPRGROUP_SYS + 79;
|
||||
pub const SPR_GPR_BASE: u32 = SPRGROUP_SYS + 1024;
|
||||
|
||||
/* Data MMU group */
|
||||
pub const SPR_DMMUCR: u32 = SPRGROUP_DMMU + 0;
|
||||
pub const SPR_DTLBEIR: u32 = SPRGROUP_DMMU + 2;
|
||||
|
||||
/* Instruction MMU group */
|
||||
pub const SPR_IMMUCR: u32 = SPRGROUP_IMMU + 0;
|
||||
pub const SPR_ITLBEIR: u32 = SPRGROUP_IMMU + 2;
|
||||
|
||||
/* Data cache group */
|
||||
pub const SPR_DCCR: u32 = SPRGROUP_DC + 0;
|
||||
pub const SPR_DCBPR: u32 = SPRGROUP_DC + 1;
|
||||
pub const SPR_DCBFR: u32 = SPRGROUP_DC + 2;
|
||||
pub const SPR_DCBIR: u32 = SPRGROUP_DC + 3;
|
||||
pub const SPR_DCBWR: u32 = SPRGROUP_DC + 4;
|
||||
pub const SPR_DCBLR: u32 = SPRGROUP_DC + 5;
|
||||
|
||||
/* Instruction cache group */
|
||||
pub const SPR_ICCR: u32 = SPRGROUP_IC + 0;
|
||||
pub const SPR_ICBPR: u32 = SPRGROUP_IC + 1;
|
||||
pub const SPR_ICBIR: u32 = SPRGROUP_IC + 2;
|
||||
pub const SPR_ICBLR: u32 = SPRGROUP_IC + 3;
|
||||
|
||||
// [snip]
|
||||
|
||||
/* Performance counters group */
|
||||
pub const SPR_PCCR0: u32 = SPRGROUP_PC + 0;
|
||||
pub const SPR_PCCR1: u32 = SPRGROUP_PC + 1;
|
||||
pub const SPR_PCCR2: u32 = SPRGROUP_PC + 2;
|
||||
pub const SPR_PCCR3: u32 = SPRGROUP_PC + 3;
|
||||
pub const SPR_PCCR4: u32 = SPRGROUP_PC + 4;
|
||||
pub const SPR_PCCR5: u32 = SPRGROUP_PC + 5;
|
||||
pub const SPR_PCCR6: u32 = SPRGROUP_PC + 6;
|
||||
pub const SPR_PCCR7: u32 = SPRGROUP_PC + 7;
|
||||
pub const SPR_PCMR0: u32 = SPRGROUP_PC + 8;
|
||||
pub const SPR_PCMR1: u32 = SPRGROUP_PC + 9;
|
||||
pub const SPR_PCMR2: u32 = SPRGROUP_PC + 10;
|
||||
pub const SPR_PCMR3: u32 = SPRGROUP_PC + 11;
|
||||
pub const SPR_PCMR4: u32 = SPRGROUP_PC + 12;
|
||||
pub const SPR_PCMR5: u32 = SPRGROUP_PC + 13;
|
||||
pub const SPR_PCMR6: u32 = SPRGROUP_PC + 14;
|
||||
pub const SPR_PCMR7: u32 = SPRGROUP_PC + 15;
|
||||
|
||||
/* PIC group */
|
||||
pub const SPR_PICMR: u32 = SPRGROUP_PIC + 0;
|
||||
pub const SPR_PICPR: u32 = SPRGROUP_PIC + 1;
|
||||
pub const SPR_PICSR: u32 = SPRGROUP_PIC + 2;
|
||||
|
||||
// [snip]
|
||||
|
||||
/*
|
||||
* Bit definitions for the Supervision Register
|
||||
*
|
||||
*/
|
||||
pub const SPR_SR_SM: u32 = 0x00000001; /* Supervisor Mode */
|
||||
pub const SPR_SR_TEE: u32 = 0x00000002; /* Tick timer Exception Enable */
|
||||
pub const SPR_SR_IEE: u32 = 0x00000004; /* Interrupt Exception Enable */
|
||||
pub const SPR_SR_DCE: u32 = 0x00000008; /* Data Cache Enable */
|
||||
pub const SPR_SR_ICE: u32 = 0x00000010; /* Instruction Cache Enable */
|
||||
pub const SPR_SR_DME: u32 = 0x00000020; /* Data MMU Enable */
|
||||
pub const SPR_SR_IME: u32 = 0x00000040; /* Instruction MMU Enable */
|
||||
pub const SPR_SR_LEE: u32 = 0x00000080; /* Little Endian Enable */
|
||||
pub const SPR_SR_CE: u32 = 0x00000100; /* CID Enable */
|
||||
pub const SPR_SR_F: u32 = 0x00000200; /* Condition Flag */
|
||||
pub const SPR_SR_CY: u32 = 0x00000400; /* Carry flag */
|
||||
pub const SPR_SR_OV: u32 = 0x00000800; /* Overflow flag */
|
||||
pub const SPR_SR_OVE: u32 = 0x00001000; /* Overflow flag Exception */
|
||||
pub const SPR_SR_DSX: u32 = 0x00002000; /* Delay Slot Exception */
|
||||
pub const SPR_SR_EPH: u32 = 0x00004000; /* Exception Prefix High */
|
||||
pub const SPR_SR_FO: u32 = 0x00008000; /* Fixed one */
|
||||
pub const SPR_SR_SUMRA: u32 = 0x00010000; /* Supervisor SPR read access */
|
||||
pub const SPR_SR_RES: u32 = 0x0ffe0000; /* Reserved */
|
||||
pub const SPR_SR_CID: u32 = 0xf0000000; /* Context ID */
|
||||
|
||||
/*
|
||||
* Bit definitions for Data Cache Control register
|
||||
*
|
||||
*/
|
||||
pub const SPR_DCCR_EW: u32 = 0x000000ff; /* Enable ways */
|
||||
|
||||
/*
|
||||
* Bit definitions for Insn Cache Control register
|
||||
*
|
||||
*/
|
||||
pub const SPR_ICCR_EW: u32 = 0x000000ff; /* Enable ways */
|
||||
|
||||
/*
|
||||
* Bit definitions for Data Cache Configuration Register
|
||||
*
|
||||
*/
|
||||
pub const SPR_DCCFGR_NCW: u32 = 0x00000007;
|
||||
pub const SPR_DCCFGR_NCS: u32 = 0x00000078;
|
||||
pub const SPR_DCCFGR_CBS: u32 = 0x00000080;
|
||||
pub const SPR_DCCFGR_CWS: u32 = 0x00000100;
|
||||
pub const SPR_DCCFGR_CCRI: u32 = 0x00000200;
|
||||
pub const SPR_DCCFGR_CBIRI: u32 = 0x00000400;
|
||||
pub const SPR_DCCFGR_CBPRI: u32 = 0x00000800;
|
||||
pub const SPR_DCCFGR_CBLRI: u32 = 0x00001000;
|
||||
pub const SPR_DCCFGR_CBFRI: u32 = 0x00002000;
|
||||
pub const SPR_DCCFGR_CBWBRI: u32 = 0x00004000;
|
||||
|
||||
pub const SPR_DCCFGR_NCW_OFF: u32 = 0;
|
||||
pub const SPR_DCCFGR_NCS_OFF: u32 = 3;
|
||||
pub const SPR_DCCFGR_CBS_OFF: u32 = 7;
|
||||
|
||||
/*
|
||||
* Bit definitions for Instruction Cache Configuration Register
|
||||
*
|
||||
*/
|
||||
pub const SPR_ICCFGR_NCW: u32 = 0x00000007;
|
||||
pub const SPR_ICCFGR_NCS: u32 = 0x00000078;
|
||||
pub const SPR_ICCFGR_CBS: u32 = 0x00000080;
|
||||
pub const SPR_ICCFGR_CCRI: u32 = 0x00000200;
|
||||
pub const SPR_ICCFGR_CBIRI: u32 = 0x00000400;
|
||||
pub const SPR_ICCFGR_CBPRI: u32 = 0x00000800;
|
||||
pub const SPR_ICCFGR_CBLRI: u32 = 0x00001000;
|
||||
|
||||
pub const SPR_ICCFGR_NCW_OFF: u32 = 0;
|
||||
pub const SPR_ICCFGR_NCS_OFF: u32 = 3;
|
||||
pub const SPR_ICCFGR_CBS_OFF: u32 = 7;
|
||||
|
||||
/*
|
||||
* Bit definitions for Data MMU Configuration Register
|
||||
*
|
||||
*/
|
||||
pub const SPR_DMMUCFGR_NTW: u32 = 0x00000003;
|
||||
pub const SPR_DMMUCFGR_NTS: u32 = 0x0000001C;
|
||||
pub const SPR_DMMUCFGR_NAE: u32 = 0x000000E0;
|
||||
pub const SPR_DMMUCFGR_CRI: u32 = 0x00000100;
|
||||
pub const SPR_DMMUCFGR_PRI: u32 = 0x00000200;
|
||||
pub const SPR_DMMUCFGR_TEIRI: u32 = 0x00000400;
|
||||
pub const SPR_DMMUCFGR_HTR: u32 = 0x00000800;
|
||||
|
||||
pub const SPR_DMMUCFGR_NTW_OFF: u32 = 0;
|
||||
pub const SPR_DMMUCFGR_NTS_OFF: u32 = 2;
|
||||
|
||||
/*
|
||||
* Bit definitions for Instruction MMU Configuration Register
|
||||
*
|
||||
*/
|
||||
pub const SPR_IMMUCFGR_NTW: u32 = 0x00000003;
|
||||
pub const SPR_IMMUCFGR_NTS: u32 = 0x0000001C;
|
||||
pub const SPR_IMMUCFGR_NAE: u32 = 0x000000E0;
|
||||
pub const SPR_IMMUCFGR_CRI: u32 = 0x00000100;
|
||||
pub const SPR_IMMUCFGR_PRI: u32 = 0x00000200;
|
||||
pub const SPR_IMMUCFGR_TEIRI: u32 = 0x00000400;
|
||||
pub const SPR_IMMUCFGR_HTR: u32 = 0x00000800;
|
||||
|
||||
pub const SPR_IMMUCFGR_NTW_OFF: u32 = 0;
|
||||
pub const SPR_IMMUCFGR_NTS_OFF: u32 = 2;
|
||||
|
||||
/*
|
||||
* Bit definitions for Performance counters mode registers
|
||||
*
|
||||
*/
|
||||
pub const SPR_PCMR_CP: u32 = 0x00000001; /* Counter present */
|
||||
pub const SPR_PCMR_UMRA: u32 = 0x00000002; /* User mode read access */
|
||||
pub const SPR_PCMR_CISM: u32 = 0x00000004; /* Count in supervisor mode */
|
||||
pub const SPR_PCMR_CIUM: u32 = 0x00000008; /* Count in user mode */
|
||||
pub const SPR_PCMR_LA: u32 = 0x00000010; /* Load access event */
|
||||
pub const SPR_PCMR_SA: u32 = 0x00000020; /* Store access event */
|
||||
pub const SPR_PCMR_IF: u32 = 0x00000040; /* Instruction fetch event*/
|
||||
pub const SPR_PCMR_DCM: u32 = 0x00000080; /* Data cache miss event */
|
||||
pub const SPR_PCMR_ICM: u32 = 0x00000100; /* Insn cache miss event */
|
||||
pub const SPR_PCMR_IFS: u32 = 0x00000200; /* Insn fetch stall event */
|
||||
pub const SPR_PCMR_LSUS: u32 = 0x00000400; /* LSU stall event */
|
||||
pub const SPR_PCMR_BS: u32 = 0x00000800; /* Branch stall event */
|
||||
pub const SPR_PCMR_DTLBM: u32 = 0x00001000; /* DTLB miss event */
|
||||
pub const SPR_PCMR_ITLBM: u32 = 0x00002000; /* ITLB miss event */
|
||||
pub const SPR_PCMR_DDS: u32 = 0x00004000; /* Data dependency stall event */
|
||||
pub const SPR_PCMR_WPE: u32 = 0x03ff8000; /* Watchpoint events */
|
|
@ -1,413 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2012, Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <spr-defs.h>
|
||||
|
||||
/*
|
||||
* OR1K Architecture has a 128 byte "red zone" after the stack that can not be
|
||||
* touched by exception handlers. GCC uses this red zone for locals and
|
||||
* temps without needing to change the stack pointer.
|
||||
*/
|
||||
#define OR1K_RED_ZONE_SIZE 128
|
||||
|
||||
/*
|
||||
* We need 4 bytes (32 bits) * 32 registers space on the stack to save all the
|
||||
* registers.
|
||||
*/
|
||||
#define EXCEPTION_STACK_SIZE ((4*32) + OR1K_RED_ZONE_SIZE)
|
||||
|
||||
#define HANDLE_EXCEPTION ; \
|
||||
l.addi r1, r1, -EXCEPTION_STACK_SIZE ; \
|
||||
l.sw 0x1c(r1), r9 ; \
|
||||
l.jal _exception_handler ; \
|
||||
l.nop ; \
|
||||
l.lwz r9, 0x1c(r1) ; \
|
||||
l.addi r1, r1, EXCEPTION_STACK_SIZE ; \
|
||||
l.rfe ; \
|
||||
l.nop
|
||||
|
||||
|
||||
.section .vectors, "ax", @progbits
|
||||
.global _reset_handler
|
||||
_reset_handler:
|
||||
l.movhi r0, 0
|
||||
l.movhi r1, 0
|
||||
l.movhi r2, 0
|
||||
l.movhi r3, 0
|
||||
l.movhi r4, 0
|
||||
l.movhi r5, 0
|
||||
l.movhi r6, 0
|
||||
l.movhi r7, 0
|
||||
l.movhi r8, 0
|
||||
l.movhi r9, 0
|
||||
l.movhi r10, 0
|
||||
l.movhi r11, 0
|
||||
l.movhi r12, 0
|
||||
l.movhi r13, 0
|
||||
l.movhi r14, 0
|
||||
l.movhi r15, 0
|
||||
l.movhi r16, 0
|
||||
l.movhi r17, 0
|
||||
l.movhi r18, 0
|
||||
l.movhi r19, 0
|
||||
l.movhi r20, 0
|
||||
l.movhi r21, 0
|
||||
l.movhi r22, 0
|
||||
l.movhi r23, 0
|
||||
l.movhi r24, 0
|
||||
l.movhi r25, 0
|
||||
l.movhi r26, 0
|
||||
l.movhi r27, 0
|
||||
l.movhi r28, 0
|
||||
l.movhi r29, 0
|
||||
l.movhi r30, 0
|
||||
l.movhi r31, 0
|
||||
|
||||
l.ori r21, r0, SPR_SR_SM
|
||||
l.mtspr r0, r21, SPR_SR
|
||||
l.movhi r21, hi(_reset_handler)
|
||||
l.ori r21, r21, lo(_reset_handler)
|
||||
l.mtspr r0, r21, SPR_EVBAR
|
||||
/* enable caches */
|
||||
l.jal _cache_init
|
||||
l.nop
|
||||
l.j _crt0
|
||||
l.nop
|
||||
|
||||
/* bus error */
|
||||
.org 0x200
|
||||
HANDLE_EXCEPTION
|
||||
|
||||
/* data page fault */
|
||||
.org 0x300
|
||||
HANDLE_EXCEPTION
|
||||
|
||||
/* instruction page fault */
|
||||
.org 0x400
|
||||
HANDLE_EXCEPTION
|
||||
|
||||
/* tick timer */
|
||||
.org 0x500
|
||||
HANDLE_EXCEPTION
|
||||
|
||||
/* alignment */
|
||||
.org 0x600
|
||||
HANDLE_EXCEPTION
|
||||
|
||||
/* illegal instruction */
|
||||
.org 0x700
|
||||
HANDLE_EXCEPTION
|
||||
|
||||
/* external interrupt */
|
||||
.org 0x800
|
||||
HANDLE_EXCEPTION
|
||||
|
||||
/* D-TLB miss */
|
||||
.org 0x900
|
||||
HANDLE_EXCEPTION
|
||||
|
||||
/* I-TLB miss */
|
||||
.org 0xa00
|
||||
HANDLE_EXCEPTION
|
||||
|
||||
/* range */
|
||||
.org 0xb00
|
||||
HANDLE_EXCEPTION
|
||||
|
||||
/* system call */
|
||||
.org 0xc00
|
||||
HANDLE_EXCEPTION
|
||||
|
||||
/* floating point */
|
||||
.org 0xd00
|
||||
HANDLE_EXCEPTION
|
||||
|
||||
/* trap */
|
||||
.org 0xe00
|
||||
HANDLE_EXCEPTION
|
||||
|
||||
/* reserved */
|
||||
.org 0xf00
|
||||
HANDLE_EXCEPTION
|
||||
|
||||
.org 0x1000
|
||||
_crt0:
|
||||
/* Setup stack and global pointer */
|
||||
l.movhi r1, hi(_fstack)
|
||||
l.ori r1, r1, lo(_fstack)
|
||||
|
||||
/* Clear BSS */
|
||||
l.movhi r21, hi(_fbss)
|
||||
l.ori r21, r21, lo(_fbss)
|
||||
l.movhi r3, hi(_ebss)
|
||||
l.ori r3, r3, lo(_ebss)
|
||||
.clearBSS:
|
||||
l.sfeq r21, r3
|
||||
l.bf .callMain
|
||||
l.nop
|
||||
l.sw 0(r21), r0
|
||||
l.addi r21, r21, 4
|
||||
l.j .clearBSS
|
||||
l.nop
|
||||
|
||||
.callMain:
|
||||
l.j main
|
||||
l.nop
|
||||
|
||||
_exception_handler:
|
||||
.cfi_startproc
|
||||
.cfi_return_column 32
|
||||
.cfi_signal_frame
|
||||
.cfi_def_cfa_offset EXCEPTION_STACK_SIZE
|
||||
l.sw 0x00(r1), r2
|
||||
.cfi_offset 2, 0x00-EXCEPTION_STACK_SIZE
|
||||
l.sw 0x04(r1), r3
|
||||
.cfi_offset 3, 0x04-EXCEPTION_STACK_SIZE
|
||||
l.sw 0x08(r1), r4
|
||||
.cfi_offset 4, 0x08-EXCEPTION_STACK_SIZE
|
||||
l.sw 0x0c(r1), r5
|
||||
.cfi_offset 5, 0x0c-EXCEPTION_STACK_SIZE
|
||||
l.sw 0x10(r1), r6
|
||||
.cfi_offset 6, 0x10-EXCEPTION_STACK_SIZE
|
||||
l.sw 0x14(r1), r7
|
||||
.cfi_offset 7, 0x14-EXCEPTION_STACK_SIZE
|
||||
l.sw 0x18(r1), r8
|
||||
.cfi_offset 8, 0x18-EXCEPTION_STACK_SIZE
|
||||
/* r9 saved in HANDLE_EXCEPTION */
|
||||
.cfi_offset 9, 0x1c-EXCEPTION_STACK_SIZE
|
||||
l.sw 0x20(r1), r10
|
||||
.cfi_offset 10, 0x20-EXCEPTION_STACK_SIZE
|
||||
l.sw 0x24(r1), r11
|
||||
.cfi_offset 11, 0x24-EXCEPTION_STACK_SIZE
|
||||
l.sw 0x28(r1), r12
|
||||
.cfi_offset 12, 0x28-EXCEPTION_STACK_SIZE
|
||||
l.sw 0x2c(r1), r13
|
||||
.cfi_offset 13, 0x2c-EXCEPTION_STACK_SIZE
|
||||
l.sw 0x30(r1), r14
|
||||
.cfi_offset 14, 0x30-EXCEPTION_STACK_SIZE
|
||||
l.sw 0x34(r1), r15
|
||||
.cfi_offset 15, 0x34-EXCEPTION_STACK_SIZE
|
||||
l.sw 0x38(r1), r16
|
||||
.cfi_offset 16, 0x38-EXCEPTION_STACK_SIZE
|
||||
l.sw 0x3c(r1), r17
|
||||
.cfi_offset 17, 0x3c-EXCEPTION_STACK_SIZE
|
||||
l.sw 0x40(r1), r18
|
||||
.cfi_offset 18, 0x40-EXCEPTION_STACK_SIZE
|
||||
l.sw 0x44(r1), r19
|
||||
.cfi_offset 19, 0x44-EXCEPTION_STACK_SIZE
|
||||
l.sw 0x48(r1), r20
|
||||
.cfi_offset 20, 0x48-EXCEPTION_STACK_SIZE
|
||||
l.sw 0x4c(r1), r21
|
||||
.cfi_offset 21, 0x4c-EXCEPTION_STACK_SIZE
|
||||
l.sw 0x50(r1), r22
|
||||
.cfi_offset 22, 0x50-EXCEPTION_STACK_SIZE
|
||||
l.sw 0x54(r1), r23
|
||||
.cfi_offset 23, 0x54-EXCEPTION_STACK_SIZE
|
||||
l.sw 0x58(r1), r24
|
||||
.cfi_offset 24, 0x58-EXCEPTION_STACK_SIZE
|
||||
l.sw 0x5c(r1), r25
|
||||
.cfi_offset 25, 0x5c-EXCEPTION_STACK_SIZE
|
||||
l.sw 0x60(r1), r26
|
||||
.cfi_offset 26, 0x60-EXCEPTION_STACK_SIZE
|
||||
l.sw 0x64(r1), r27
|
||||
.cfi_offset 27, 0x64-EXCEPTION_STACK_SIZE
|
||||
l.sw 0x68(r1), r28
|
||||
.cfi_offset 28, 0x68-EXCEPTION_STACK_SIZE
|
||||
l.sw 0x6c(r1), r29
|
||||
.cfi_offset 29, 0x6c-EXCEPTION_STACK_SIZE
|
||||
l.sw 0x70(r1), r30
|
||||
.cfi_offset 30, 0x70-EXCEPTION_STACK_SIZE
|
||||
l.sw 0x74(r1), r31
|
||||
.cfi_offset 31, 0x74-EXCEPTION_STACK_SIZE
|
||||
|
||||
/* Save return address */
|
||||
l.or r14, r0, r9
|
||||
/* Calculate exception vector from handler address */
|
||||
l.andi r3, r9, 0xf00
|
||||
l.srli r3, r3, 8
|
||||
/* Pass saved register state */
|
||||
l.or r4, r0, r1
|
||||
/* Extract exception PC */
|
||||
l.mfspr r5, r0, SPR_EPCR_BASE
|
||||
/* Tell exception PC to the unwinder */
|
||||
l.sw 0x78(r1), r5
|
||||
.cfi_offset 32, 0x78-EXCEPTION_STACK_SIZE
|
||||
/* Extract exception effective address */
|
||||
l.mfspr r6, r0, SPR_EEAR_BASE
|
||||
/* Extract exception SR */
|
||||
l.mfspr r7, r0, SPR_ESR_BASE
|
||||
/* Call exception handler with the link address as argument */
|
||||
l.jal exception
|
||||
l.nop
|
||||
|
||||
/* Load return address */
|
||||
l.or r9, r0, r14
|
||||
/* Restore state */
|
||||
l.lwz r2, 0x00(r1)
|
||||
l.lwz r3, 0x04(r1)
|
||||
l.lwz r4, 0x08(r1)
|
||||
l.lwz r5, 0x0c(r1)
|
||||
l.lwz r6, 0x10(r1)
|
||||
l.lwz r7, 0x14(r1)
|
||||
l.lwz r8, 0x18(r1)
|
||||
l.lwz r10, 0x20(r1)
|
||||
l.lwz r11, 0x24(r1)
|
||||
l.lwz r12, 0x28(r1)
|
||||
l.lwz r13, 0x2c(r1)
|
||||
l.lwz r14, 0x30(r1)
|
||||
l.lwz r15, 0x34(r1)
|
||||
l.lwz r16, 0x38(r1)
|
||||
l.lwz r17, 0x3c(r1)
|
||||
l.lwz r18, 0x40(r1)
|
||||
l.lwz r19, 0x44(r1)
|
||||
l.lwz r20, 0x48(r1)
|
||||
l.lwz r21, 0x4c(r1)
|
||||
l.lwz r22, 0x50(r1)
|
||||
l.lwz r23, 0x54(r1)
|
||||
l.lwz r24, 0x58(r1)
|
||||
l.lwz r25, 0x5c(r1)
|
||||
l.lwz r26, 0x60(r1)
|
||||
l.lwz r27, 0x64(r1)
|
||||
l.lwz r28, 0x68(r1)
|
||||
l.lwz r29, 0x6c(r1)
|
||||
l.lwz r30, 0x70(r1)
|
||||
l.lwz r31, 0x74(r1)
|
||||
l.jr r9
|
||||
l.nop
|
||||
.cfi_endproc
|
||||
|
||||
.global _cache_init
|
||||
_cache_init:
|
||||
/*
|
||||
This function is to be used ONLY during reset, before main() is called.
|
||||
TODO: Perhaps break into individual enable instruction/data cache
|
||||
sections functions, and provide disable functions, also, all
|
||||
callable from C
|
||||
*/
|
||||
|
||||
/* Instruction cache enable */
|
||||
/* Check if IC present and skip enabling otherwise */
|
||||
#if 1
|
||||
.L6:
|
||||
l.mfspr r3,r0,SPR_UPR
|
||||
l.andi r7,r3,SPR_UPR_ICP
|
||||
l.sfeq r7,r0
|
||||
l.bf .L8
|
||||
l.nop
|
||||
|
||||
/* Disable IC */
|
||||
l.mfspr r6,r0,SPR_SR
|
||||
l.addi r5,r0,-1
|
||||
l.xori r5,r5,SPR_SR_ICE
|
||||
l.and r5,r6,r5
|
||||
l.mtspr r0,r5,SPR_SR
|
||||
|
||||
/* Establish cache block size
|
||||
If BS=0, 16;
|
||||
If BS=1, 32;
|
||||
r14 contain block size
|
||||
*/
|
||||
l.mfspr r3,r0,SPR_ICCFGR
|
||||
l.andi r7,r3,SPR_ICCFGR_CBS
|
||||
l.srli r8,r7,7
|
||||
l.ori r4,r0,16
|
||||
l.sll r14,r4,r8
|
||||
|
||||
/* Establish number of cache sets
|
||||
r10 contains number of cache sets
|
||||
r8 contains log(# of cache sets)
|
||||
*/
|
||||
l.andi r7,r3,SPR_ICCFGR_NCS
|
||||
l.srli r8,r7,3
|
||||
l.ori r4,r0,1
|
||||
l.sll r10,r4,r8
|
||||
|
||||
/* Invalidate IC */
|
||||
l.addi r6,r0,0
|
||||
l.sll r5,r14,r8
|
||||
|
||||
.L7: l.mtspr r0,r6,SPR_ICBIR
|
||||
l.sfne r6,r5
|
||||
l.bf .L7
|
||||
l.add r6,r6,r14
|
||||
|
||||
/* Enable IC */
|
||||
l.mfspr r6,r0,SPR_SR
|
||||
l.ori r6,r6,SPR_SR_ICE
|
||||
l.mtspr r0,r6,SPR_SR
|
||||
l.nop
|
||||
l.nop
|
||||
l.nop
|
||||
l.nop
|
||||
l.nop
|
||||
l.nop
|
||||
l.nop
|
||||
l.nop
|
||||
/* Data cache enable */
|
||||
/* Check if DC present and skip enabling otherwise */
|
||||
#endif
|
||||
.L8:
|
||||
#if 1
|
||||
l.mfspr r3,r0,SPR_UPR
|
||||
l.andi r7,r3,SPR_UPR_DCP
|
||||
l.sfeq r7,r0
|
||||
l.bf .L10
|
||||
l.nop
|
||||
/* Disable DC */
|
||||
l.mfspr r6,r0,SPR_SR
|
||||
l.addi r5,r0,-1
|
||||
l.xori r5,r5,SPR_SR_DCE
|
||||
l.and r5,r6,r5
|
||||
l.mtspr r0,r5,SPR_SR
|
||||
/* Establish cache block size
|
||||
If BS=0, 16;
|
||||
If BS=1, 32;
|
||||
r14 contain block size
|
||||
*/
|
||||
l.mfspr r3,r0,SPR_DCCFGR
|
||||
l.andi r7,r3,SPR_DCCFGR_CBS
|
||||
l.srli r8,r7,7
|
||||
l.ori r4,r0,16
|
||||
l.sll r14,r4,r8
|
||||
/* Establish number of cache sets
|
||||
r10 contains number of cache sets
|
||||
r8 contains log(# of cache sets)
|
||||
*/
|
||||
l.andi r7,r3,SPR_DCCFGR_NCS
|
||||
l.srli r8,r7,3
|
||||
l.ori r4,r0,1
|
||||
l.sll r10,r4,r8
|
||||
/* Invalidate DC */
|
||||
l.addi r6,r0,0
|
||||
l.sll r5,r14,r8
|
||||
|
||||
.L9:
|
||||
l.mtspr r0,r6,SPR_DCBIR
|
||||
l.sfne r6,r5
|
||||
l.bf .L9
|
||||
l.add r6,r6,r14
|
||||
/* Enable DC */
|
||||
l.mfspr r6,r0,SPR_SR
|
||||
l.ori r6,r6,SPR_SR_DCE
|
||||
l.mtspr r0,r6,SPR_SR
|
||||
#endif
|
||||
.L10:
|
||||
/* Return */
|
||||
l.jr r9
|
||||
l.nop
|
|
@ -141,9 +141,6 @@ impl<'a> Library<'a> {
|
|||
pub unsafe fn rebind(&self, name: &[u8], addr: Elf32_Word) -> Result<(), Error<'a>> {
|
||||
for rela in self.pltrel.iter() {
|
||||
match (ELF32_R_TYPE(rela.r_info), self.arch) {
|
||||
(R_OR1K_32, Arch::OpenRisc) |
|
||||
(R_OR1K_GLOB_DAT, Arch::OpenRisc) |
|
||||
(R_OR1K_JMP_SLOT, Arch::OpenRisc) |
|
||||
(R_RISCV_32, Arch::RiscV) |
|
||||
(R_RISCV_JUMP_SLOT, Arch::RiscV) => {
|
||||
let sym = self.symtab.get(ELF32_R_SYM(rela.r_info) as usize)
|
||||
|
@ -174,15 +171,12 @@ impl<'a> Library<'a> {
|
|||
|
||||
let value;
|
||||
match (ELF32_R_TYPE(rela.r_info), self.arch) {
|
||||
(R_OR1K_NONE, Arch::OpenRisc) | (R_RISCV_NONE, Arch::RiscV) =>
|
||||
(R_RISCV_NONE, Arch::RiscV) =>
|
||||
return Ok(()),
|
||||
|
||||
(R_OR1K_RELATIVE, Arch::OpenRisc) | (R_RISCV_RELATIVE, Arch::RiscV) =>
|
||||
(R_RISCV_RELATIVE, Arch::RiscV) =>
|
||||
value = self.image_off + rela.r_addend as Elf32_Word,
|
||||
|
||||
(R_OR1K_32, Arch::OpenRisc) |
|
||||
(R_OR1K_GLOB_DAT, Arch::OpenRisc) |
|
||||
(R_OR1K_JMP_SLOT, Arch::OpenRisc) |
|
||||
(R_RISCV_32, Arch::RiscV) |
|
||||
(R_RISCV_JUMP_SLOT, Arch::RiscV) => {
|
||||
let sym = sym.ok_or("relocation requires an associated symbol")?;
|
||||
|
@ -342,11 +336,6 @@ impl<'a> Library<'a> {
|
|||
}
|
||||
|
||||
fn arch(ehdr: &Elf32_Ehdr) -> Option<Arch> {
|
||||
const IDENT_OPENRISC: [u8; EI_NIDENT] = [
|
||||
ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3,
|
||||
ELFCLASS32, ELFDATA2MSB, EV_CURRENT, ELFOSABI_NONE,
|
||||
/* ABI version */ 0, /* padding */ 0, 0, 0, 0, 0, 0, 0
|
||||
];
|
||||
const IDENT_RISCV: [u8; EI_NIDENT] = [
|
||||
ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3,
|
||||
ELFCLASS32, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE,
|
||||
|
@ -356,9 +345,6 @@ fn arch(ehdr: &Elf32_Ehdr) -> Option<Arch> {
|
|||
#[cfg(target_arch = "riscv32")]
|
||||
(IDENT_RISCV, EM_RISCV) => Some(Arch::RiscV),
|
||||
|
||||
#[cfg(target_arch = "or1k")]
|
||||
(IDENT_OPENRISC, EM_OPENRISC) => Some(Arch::OpenRisc),
|
||||
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue