artiq-zynq-oxford/firmware/libboard_misoc/lib.rs

57 lines
1.7 KiB
Rust
Executable File

#![no_std]
#![feature(asm)]
include!(concat!(env!("BUILDINC_DIRECTORY"), "/generated/csr.rs"));
pub mod uart;
#[macro_use]
pub mod uart_console;
// Clean = expunge cache line with writeback
pub fn clean_data_cache(base: usize, len: usize) {
const CACHE_SYNC_OFFSET: isize = 0x0730/4; // Cache Sync
const CACHE_CLEAN_PA_OFFSET: isize = 0x7B0/4;
const L2CC_BASE: *mut u32 = 0xF8F02000 as *mut u32;
const CACHE_LINE_LENGTH: usize = 32;
let mut addr = base & !(CACHE_LINE_LENGTH-1);
loop {
if addr > base+len {break}
unsafe {
write_volatile(L2CC_BASE.offset(CACHE_CLEAN_PA_OFFSET), addr as u32);
write_volatile(L2CC_BASE.offset(CACHE_SYNC_OFFSET), 0);
// Clean data cache line by virtual address
asm!("mcr p15, 0, $0, c7, c10, 1"::"r"(addr))
}
addr += CACHE_LINE_LENGTH;
}
}
use core::ptr::write_volatile;
// Invalidate = expunge cache line without writeback
pub fn invalidate_data_cache(base: usize, len: usize) {
const CACHE_SYNC_OFFSET: isize = 0x0730/4; // Cache Sync
const CACHE_INVLD_PA_OFFSET: isize = 0x0770/4; // Cache Invalid by PA
const L2CC_BASE: *mut u32 = 0xF8F02000 as *mut u32;
const CACHE_LINE_LENGTH: usize = 32;
let mut addr = base & !(CACHE_LINE_LENGTH-1);
loop {
if addr > base+len {break}
unsafe {
write_volatile(L2CC_BASE.offset(CACHE_INVLD_PA_OFFSET), addr as u32);
write_volatile(L2CC_BASE.offset(CACHE_SYNC_OFFSET), 0);
// Invalidate data cache line by virtual address
asm!("mcr p15, 0, $0, c7, c6, 1"::"r"(addr))
}
addr += CACHE_LINE_LENGTH;
}
}