#![allow(dead_code)]
use core::ptr;
const ICCICR: usize = 0x000; const ICCPMR: usize = 0x004; const ICCBPR: usize = 0x008; const ICCIAR: usize = 0x00C; const ICCEOIR: usize = 0x010; const ICCRPR: usize = 0x014; const ICCHPIR: usize = 0x018; const ICCABPR: usize = 0x01c; const ICCIDR: usize = 0x0fc;
const ICDDCR: usize = 0x000; const ICDICTR: usize = 0x004; const ICDIIDR: usize = 0x008; const ICDISR: usize = 0x080; const ICDISER: usize = 0x100; const ICDICER: usize = 0x180; const ICDISPR: usize = 0x200; const ICDICPR: usize = 0x280; const ICDABR: usize = 0x300; const ICDIPR: usize = 0x400; const ICDIPTR: usize = 0x800; const ICDICFR: usize = 0xc00; const ICDSGIR: usize = 0xf00;
unsafe fn reg8_write(addr: usize, data: u8) {
let p = addr as *mut u8;
ptr::write_volatile(p, data);
}
unsafe fn reg8_read(addr: usize) -> u8 {
let p = addr as *mut u8;
ptr::read_volatile(p)
}
unsafe fn reg32_write(addr: usize, data: u32) {
let p = addr as *mut u32;
ptr::write_volatile(p, data);
}
unsafe fn reg32_read(addr: usize) -> u32 {
let p = addr as *mut u32;
ptr::read_volatile(p)
}
pub struct Pl390 {
pub icc: usize,
pub icd: usize,
}
impl Pl390 {
pub const fn new(icc: usize, icd: usize) -> Self {
Pl390 { icc: icc, icd: icd }
}
pub fn set_base_address(&mut self, icc: usize, icd: usize) {
self.icc = icc;
self.icd = icd;
}
pub unsafe fn initialize(&self) {
self.write_iccpmr(0xf8);
self.write_iccicr(0x07);
}
pub unsafe fn icd_enable(&self) {
self.write_icddcr(1);
}
pub unsafe fn icd_disable(&self) {
self.write_icddcr(0);
}
pub unsafe fn icd_set_target(&self, intno: usize, targetcpu: u8) {
self.write_icdiptr(intno, targetcpu);
}
pub unsafe fn icd_set_config(&self, intno: usize, config: u8) {
let n = intno as usize >> 4;
let s = (intno as u32 & 0x0f) * 2;
let mut val = self.read_icdicfr(n);
val &= !(0x03 << s);
val |= (config as u32 & 0x03) << s;
self.write_icdicfr(n, val);
}
pub fn interrupt_disable(&self, intno: usize) {
unsafe {
self.write_icdicer(intno >> 5, 1 << (intno & 0x1f));
}
}
pub fn interrupt_enable(&self, intno: usize) {
unsafe {
self.write_icdiser(intno as usize >> 5, 1 << (intno & 0x1f));
}
}
pub fn interrupt_set_priority(&self, intno: usize, pri: u8) {
unsafe {
self.write_icdipr(intno, pri);
}
}
pub fn interrupt_pending_clear(&self, intno: usize) {
unsafe {
self.write_icdicpr(intno / 32, 1u32 << (intno % 32));
}
}
pub unsafe fn write_iccicr(&self, data: u32) {
reg32_write(self.icc + ICCICR, data);
}
pub unsafe fn write_iccpmr(&self, data: u8) {
reg8_write(self.icc + ICCPMR, data);
}
pub unsafe fn read_iccpmr(&self) -> u8 {
reg8_read(self.icc + ICCPMR)
}
pub unsafe fn write_iccbpr(&self, data: u32) {
reg32_write(self.icc + ICCBPR, data);
}
pub unsafe fn write_icciar(&self, data: u32) {
reg32_write(self.icc + ICCIAR, data);
}
pub unsafe fn read_icciar(&self) -> u32 {
reg32_read(self.icc + ICCIAR)
}
pub unsafe fn write_icceoir(&self, data: u32) {
reg32_write(self.icc + ICCEOIR, data);
}
pub unsafe fn write_iccrpr(&self, data: u32) {
reg32_write(self.icc + ICCRPR, data);
}
pub unsafe fn write_icchpir(&self, data: u32) {
reg32_write(self.icc + ICCHPIR, data);
}
pub unsafe fn write_iccabpr(&self, data: u32) {
reg32_write(self.icc + ICCABPR, data);
}
pub unsafe fn write_iccidr(&self, data: u32) {
reg32_write(self.icc + ICCIDR, data);
}
pub unsafe fn write_icddcr(&self, data: u32) {
reg32_write(self.icd + ICDDCR, data);
}
pub unsafe fn write_icdictr(&self, data: u32) {
reg32_write(self.icd + ICDICTR, data);
}
pub unsafe fn write_icdiidr(&self, data: u32) {
reg32_write(self.icd + ICDIIDR, data);
}
pub unsafe fn write_icdisr(&self, n: usize, data: u32) {
reg32_write(self.icd + ICDISR + 4 * n, data);
}
pub unsafe fn write_icdiser(&self, n: usize, data: u32) {
reg32_write(self.icd + ICDISER + 4 * n, data);
}
pub unsafe fn write_icdicer(&self, n: usize, data: u32) {
reg32_write(self.icd + ICDICER + 4 * n, data);
}
pub unsafe fn write_icdispr(&self, n: usize, data: u32) {
reg32_write(self.icd + ICDISPR + 4 * n, data);
}
pub unsafe fn write_icdicpr(&self, n: usize, data: u32) {
reg32_write(self.icd + ICDICPR + 4 * n, data);
}
pub unsafe fn write_icdabr(&self, n: usize, data: u32) {
reg32_write(self.icd + ICDABR + 4 * n, data);
}
pub unsafe fn write_icdipr(&self, n: usize, data: u8) {
reg8_write(self.icd + ICDIPR + n, data);
}
pub unsafe fn read_icdipr(&self, n: usize) -> u8 {
reg8_read(self.icd + ICDIPR + n)
}
pub unsafe fn write_icdiptr(&self, n: usize, data: u8) {
reg8_write(self.icd + ICDIPTR + n, data);
}
pub unsafe fn write_icdicfr(&self, n: usize, data: u32) {
reg32_write(self.icd + ICDICFR + 4 * n, data);
}
pub unsafe fn read_icdicfr(&self, n: usize) -> u32 {
reg32_read(self.icd + ICDICFR + 4 * n)
}
pub unsafe fn write_icdsgir(&self, data: u32) {
reg32_write(self.icd + ICDSGIR, data);
}
}