mirror of
https://github.com/rcore-os/rCore.git
synced 2024-11-22 08:06:17 +04:00
RISC-V 64 RVM support
This commit is contained in:
parent
2d732a48d8
commit
067dc4e3f5
@ -26,6 +26,11 @@ const RVM_VCPU_READ_STATE: u32 = RVM_IO + 0x13;
|
|||||||
const RVM_VCPU_WRITE_STATE: u32 = RVM_IO + 0x14;
|
const RVM_VCPU_WRITE_STATE: u32 = RVM_IO + 0x14;
|
||||||
const RVM_VCPU_INTERRUPT: u32 = RVM_IO + 0x15;
|
const RVM_VCPU_INTERRUPT: u32 = RVM_IO + 0x15;
|
||||||
|
|
||||||
|
const RVM_RISCV_SET_SSIP: u32 = 0;
|
||||||
|
const RVM_RISCV_CLEAR_SSIP: u32 = 1;
|
||||||
|
const RVM_RISCV_SET_SEIP: u32 = 2;
|
||||||
|
const RVM_RISCV_CLEAR_SEIP: u32 = 3;
|
||||||
|
|
||||||
pub struct RvmINode {
|
pub struct RvmINode {
|
||||||
guests: RwLock<BTreeMap<usize, Guest>>,
|
guests: RwLock<BTreeMap<usize, Guest>>,
|
||||||
vcpus: RwLock<BTreeMap<usize, Vcpu>>,
|
vcpus: RwLock<BTreeMap<usize, Vcpu>>,
|
||||||
@ -44,6 +49,7 @@ struct RvmGuestAddMemoryRegionArgs {
|
|||||||
vmid: u16,
|
vmid: u16,
|
||||||
guest_start_paddr: u64,
|
guest_start_paddr: u64,
|
||||||
memory_size: u64,
|
memory_size: u64,
|
||||||
|
userspace_addr: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
@ -118,16 +124,19 @@ impl INode for RvmINode {
|
|||||||
self.guest_create().map_err(into_fs_error)
|
self.guest_create().map_err(into_fs_error)
|
||||||
}
|
}
|
||||||
RVM_GUEST_ADD_MEMORY_REGION => {
|
RVM_GUEST_ADD_MEMORY_REGION => {
|
||||||
let args = UserInPtr::<RvmGuestAddMemoryRegionArgs>::from(data)
|
let mut ptr = UserInOutPtr::<RvmGuestAddMemoryRegionArgs>::from(data);
|
||||||
.read()
|
let mut args = ptr.read().or(Err(FsError::InvalidParam))?;
|
||||||
.or(Err(FsError::InvalidParam))?;
|
|
||||||
info!("[RVM] ioctl RVM_GUEST_ADD_MEMORY_REGION {:x?}", args);
|
info!("[RVM] ioctl RVM_GUEST_ADD_MEMORY_REGION {:x?}", args);
|
||||||
self.guest_add_memory_region(
|
let userspace_addr = self
|
||||||
args.vmid as usize,
|
.guest_add_memory_region(
|
||||||
args.guest_start_paddr as usize,
|
args.vmid as usize,
|
||||||
args.memory_size as usize,
|
args.guest_start_paddr as usize,
|
||||||
)
|
args.memory_size as usize,
|
||||||
.map_err(into_fs_error)
|
)
|
||||||
|
.map_err(into_fs_error)?;
|
||||||
|
args.userspace_addr = userspace_addr as u64;
|
||||||
|
ptr.write(args).or(Err(FsError::DeviceError))?;
|
||||||
|
Ok(0)
|
||||||
}
|
}
|
||||||
RVM_GUEST_SET_TRAP => {
|
RVM_GUEST_SET_TRAP => {
|
||||||
let args = UserInPtr::<RvmGuestSetTrapArgs>::from(data)
|
let args = UserInPtr::<RvmGuestSetTrapArgs>::from(data)
|
||||||
@ -354,7 +363,7 @@ impl RvmINode {
|
|||||||
Err(RvmError::InvalidParam)
|
Err(RvmError::InvalidParam)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[cfg(any(target_arch = "x86_64"))]
|
||||||
fn vcpu_interrupt(&self, vcpu_id: usize, vector: u32) -> RvmResult<()> {
|
fn vcpu_interrupt(&self, vcpu_id: usize, vector: u32) -> RvmResult<()> {
|
||||||
if let Some(vcpu) = self.vcpus.write().get_mut(&vcpu_id) {
|
if let Some(vcpu) = self.vcpus.write().get_mut(&vcpu_id) {
|
||||||
vcpu.inner.lock().virtual_interrupt(vector)
|
vcpu.inner.lock().virtual_interrupt(vector)
|
||||||
@ -362,6 +371,25 @@ impl RvmINode {
|
|||||||
Err(RvmError::InvalidParam)
|
Err(RvmError::InvalidParam)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
|
||||||
|
fn vcpu_interrupt(&self, vcpu_id: usize, arg: u32) -> RvmResult<()> {
|
||||||
|
if let Some(vcpu) = self.vcpus.write().get_mut(&vcpu_id) {
|
||||||
|
//vcpu.inner.lock().virtual_interrupt(vector)
|
||||||
|
let irq = &vcpu.irq;
|
||||||
|
match arg {
|
||||||
|
self::RVM_RISCV_SET_SSIP => irq.set_software_interrupt(true),
|
||||||
|
self::RVM_RISCV_CLEAR_SSIP => irq.set_software_interrupt(false),
|
||||||
|
self::RVM_RISCV_SET_SEIP => irq.set_external_interrupt(true),
|
||||||
|
self::RVM_RISCV_CLEAR_SEIP => irq.set_external_interrupt(false),
|
||||||
|
_ => {
|
||||||
|
return Err(RvmError::InvalidParam);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(RvmError::InvalidParam)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: remove guest & vcpu
|
// TODO: remove guest & vcpu
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,10 @@ pub(super) struct Guest {
|
|||||||
|
|
||||||
pub(super) struct Vcpu {
|
pub(super) struct Vcpu {
|
||||||
pub(super) inner: Mutex<VcpuInner>,
|
pub(super) inner: Mutex<VcpuInner>,
|
||||||
|
//#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
|
||||||
|
//inner_id: usize,
|
||||||
|
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
|
||||||
|
pub(super) irq: Arc<rvm::InterruptState>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Guest {
|
impl Guest {
|
||||||
@ -47,8 +51,22 @@ impl Guest {
|
|||||||
|
|
||||||
impl Vcpu {
|
impl Vcpu {
|
||||||
pub fn new(entry: u64, guest: Arc<GuestInner>) -> RvmResult<Self> {
|
pub fn new(entry: u64, guest: Arc<GuestInner>) -> RvmResult<Self> {
|
||||||
Ok(Self {
|
#[cfg(any(target_arch = "x86_64"))]
|
||||||
inner: Mutex::new(VcpuInner::new(entry, guest)?),
|
{
|
||||||
})
|
Ok(Self {
|
||||||
|
inner: Mutex::new(VcpuInner::new(entry, guest)?),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
|
||||||
|
{
|
||||||
|
let inner = VcpuInner::new(entry, Arc::clone(&guest))?;
|
||||||
|
let inner_id = inner.get_id();
|
||||||
|
let irq = guest.get_irq_by_id(inner_id);
|
||||||
|
return Ok(Self {
|
||||||
|
inner: Mutex::new(inner),
|
||||||
|
//inner_id,
|
||||||
|
irq,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user