firmware: purge or1k

This commit is contained in:
occheung 2021-08-24 17:43:36 +08:00
parent af263ffe1f
commit 61b0170a12
8 changed files with 2 additions and 835 deletions

View File

@ -7,10 +7,6 @@ extern crate log;
#[cfg(feature = "smoltcp")] #[cfg(feature = "smoltcp")]
extern crate smoltcp; extern crate smoltcp;
#[cfg(target_arch = "or1k")]
#[path = "or1k/mod.rs"]
mod arch;
#[cfg(target_arch = "riscv32")] #[cfg(target_arch = "riscv32")]
#[path = "riscv32imac/mod.rs"] #[path = "riscv32imac/mod.rs"]
mod arch; mod arch;

View File

@ -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 {}
}

View File

@ -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);
}
}
}

View File

@ -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
}

View File

@ -1,4 +0,0 @@
pub mod spr;
pub mod irq;
pub mod cache;
pub mod boot;

View File

@ -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 */

View File

@ -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

View File

@ -141,9 +141,6 @@ impl<'a> Library<'a> {
pub unsafe fn rebind(&self, name: &[u8], addr: Elf32_Word) -> Result<(), Error<'a>> { pub unsafe fn rebind(&self, name: &[u8], addr: Elf32_Word) -> Result<(), Error<'a>> {
for rela in self.pltrel.iter() { for rela in self.pltrel.iter() {
match (ELF32_R_TYPE(rela.r_info), self.arch) { 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_32, Arch::RiscV) |
(R_RISCV_JUMP_SLOT, Arch::RiscV) => { (R_RISCV_JUMP_SLOT, Arch::RiscV) => {
let sym = self.symtab.get(ELF32_R_SYM(rela.r_info) as usize) let sym = self.symtab.get(ELF32_R_SYM(rela.r_info) as usize)
@ -174,15 +171,12 @@ impl<'a> Library<'a> {
let value; let value;
match (ELF32_R_TYPE(rela.r_info), self.arch) { 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(()), 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, 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_32, Arch::RiscV) |
(R_RISCV_JUMP_SLOT, Arch::RiscV) => { (R_RISCV_JUMP_SLOT, Arch::RiscV) => {
let sym = sym.ok_or("relocation requires an associated symbol")?; 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> { 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] = [ const IDENT_RISCV: [u8; EI_NIDENT] = [
ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3, ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3,
ELFCLASS32, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE, ELFCLASS32, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE,
@ -356,9 +345,6 @@ fn arch(ehdr: &Elf32_Ehdr) -> Option<Arch> {
#[cfg(target_arch = "riscv32")] #[cfg(target_arch = "riscv32")]
(IDENT_RISCV, EM_RISCV) => Some(Arch::RiscV), (IDENT_RISCV, EM_RISCV) => Some(Arch::RiscV),
#[cfg(target_arch = "or1k")]
(IDENT_OPENRISC, EM_OPENRISC) => Some(Arch::OpenRisc),
_ => None, _ => None,
} }
} }