use core::option::Option;
use axaddrspace::{GuestPhysAddr, HostPhysAddr};
use bitmaps::Bitmap;
use spin::Mutex;
use crate::consts::*;
pub struct VPlicGlobal {
pub addr: GuestPhysAddr,
pub size: usize,
pub contexts_num: usize,
pub assigned_irqs: Mutex<Bitmap<{ PLIC_NUM_SOURCES }>>,
pub pending_irqs: Mutex<Bitmap<{ PLIC_NUM_SOURCES }>>,
pub active_irqs: Mutex<Bitmap<{ PLIC_NUM_SOURCES }>>,
pub host_plic_addr: HostPhysAddr,
}
impl VPlicGlobal {
pub fn new(addr: GuestPhysAddr, size: Option<usize>, contexts_num: usize) -> Self {
let addr_end = addr.as_usize()
+ contexts_num * PLIC_CONTEXT_STRIDE
+ PLIC_CONTEXT_CTRL_OFFSET
+ PLIC_CONTEXT_CLAIM_COMPLETE_OFFSET;
let size = size.expect("Size must be specified for VPlicGlobal");
assert!(
addr.as_usize() + size > addr_end,
"End address 0x{:x} exceeds region [0x{:x}, 0x{:x}) ",
addr_end,
addr.as_usize(),
addr.as_usize() + size,
);
Self {
addr,
size,
assigned_irqs: Mutex::new(Bitmap::new()),
pending_irqs: Mutex::new(Bitmap::new()),
active_irqs: Mutex::new(Bitmap::new()),
contexts_num,
host_plic_addr: HostPhysAddr::from_usize(addr.as_usize()),
}
}
}