firmware: rewrite cache flushing code in Rust.

This commit is contained in:
whitequark 2017-01-24 23:07:22 +00:00
parent 209be73204
commit 2de3770c06
6 changed files with 154 additions and 15 deletions

View File

@ -0,0 +1,44 @@
use spr::{self, mfspr, mtspr};
use csr;
use mem;
pub fn flush_cpu_icache() {
unsafe {
let iccfgr = mfspr(spr::SPR_ICCFGR);
let ways = 1 << (iccfgr & spr::SPR_ICCFGR_NCW);
let set_size = 1 << ((iccfgr & spr::SPR_ICCFGR_NCS) >> 3);
let block_size = if iccfgr & spr::SPR_ICCFGR_CBS != 0 { 32 } else { 16 };
let size = set_size * ways * block_size;
let mut i = 0;
while i < size {
mtspr(spr::SPR_ICBIR, i);
i += block_size;
}
}
}
pub fn flush_cpu_dcache() {
unsafe {
let dccfgr = mfspr(spr::SPR_DCCFGR);
let ways = 1 << (dccfgr & spr::SPR_ICCFGR_NCW);
let set_size = 1 << ((dccfgr & spr::SPR_DCCFGR_NCS) >> 3);
let block_size = if dccfgr & spr::SPR_DCCFGR_CBS != 0 { 32 } else { 16 };
let size = set_size * ways * block_size;
let mut i = 0;
while i < size {
mtspr(spr::SPR_DCBIR, i);
i += block_size;
}
}
}
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;
asm!("l.lwz r0, 0($1)"::"r"(addr):"r0":"volatile")
}
}
}

View File

@ -10,6 +10,7 @@ include!(concat!(env!("BUILDINC_DIRECTORY"), "/generated/mem.rs"));
include!(concat!(env!("BUILDINC_DIRECTORY"), "/generated/csr.rs"));
pub mod spr;
pub mod irq;
pub mod cache;
pub mod clock;
pub mod uart;
#[cfg(feature = "uart_console")]
@ -34,11 +35,6 @@ pub mod ad9154;
#[cfg(feature = "uart_console")]
pub use uart_console::Console;
extern {
pub fn flush_cpu_dcache();
pub fn flush_l2_cache();
}
pub fn ident(buf: &mut [u8]) -> &str {
unsafe {
let len = ptr::read_volatile(csr::IDENTIFIER_MEM_BASE);

View File

@ -57,6 +57,28 @@ 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]
/* PIC group */
@ -89,3 +111,80 @@ 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;

View File

@ -1,5 +1,5 @@
use std::io::{self, Write};
use board::{self, csr};
use board::{csr, cache};
use sched::{Io, TcpSocket};
use analyzer_proto::*;
@ -35,8 +35,8 @@ fn disarm() {
unsafe {
csr::rtio_analyzer::enable_write(0);
while csr::rtio_analyzer::busy_read() != 0 {}
board::flush_cpu_dcache();
board::flush_l2_cache();
cache::flush_cpu_dcache();
cache::flush_l2_cache();
}
}

View File

@ -1,7 +1,7 @@
use core::ptr::{read_volatile, write_volatile};
use board;
use board::{mem, cache};
const MAILBOX: *mut usize = board::mem::MAILBOX_BASE as *mut usize;
const MAILBOX: *mut usize = mem::MAILBOX_BASE as *mut usize;
static mut LAST: usize = 0;
pub unsafe fn send(data: usize) {
@ -23,7 +23,7 @@ pub fn receive() -> usize {
0
} else {
if data != 0 {
board::flush_cpu_dcache()
cache::flush_cpu_dcache()
}
data
}

View File

@ -2,10 +2,10 @@
use core::ptr::{read_volatile, write_volatile};
use core::slice;
use board;
use board::{mem, cache};
const SEND_MAILBOX: *mut usize = (board::mem::MAILBOX_BASE + 4) as *mut usize;
const RECV_MAILBOX: *mut usize = (board::mem::MAILBOX_BASE + 8) as *mut usize;
const SEND_MAILBOX: *mut usize = (mem::MAILBOX_BASE + 4) as *mut usize;
const RECV_MAILBOX: *mut usize = (mem::MAILBOX_BASE + 8) as *mut usize;
const QUEUE_BEGIN: usize = 0x40400000;
const QUEUE_END: usize = 0x407fff80;
@ -51,7 +51,7 @@ pub fn dequeue<T, E, F>(f: F) -> Result<T, E>
debug_assert!(!empty());
unsafe {
board::flush_cpu_dcache();
cache::flush_cpu_dcache();
let slice = slice::from_raw_parts_mut(read_volatile(RECV_MAILBOX) as *mut u8, QUEUE_CHUNK);
f(slice).and_then(|x| {
write_volatile(RECV_MAILBOX, next(read_volatile(RECV_MAILBOX)));