Skip to content

Commit ad1d617

Browse files
committed
emulate ICC_SGI1R_EL1
1 parent f8e6514 commit ad1d617

File tree

2 files changed

+49
-11
lines changed

2 files changed

+49
-11
lines changed

src/gic/mod.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ extern crate alloc;
33
use core::result;
44

55
use alloc::{sync::Arc, vec, vec::Vec};
6-
use arm_vgic::{v3::{gits::Gits, vgicd::VGicD, vgicr::VGicR}, vgic};
6+
use arm_vgic::{
7+
v3::{gits::Gits, vgicd::VGicD, vgicr::VGicR},
8+
vgic,
9+
};
710
use axaddrspace::{GuestPhysAddr, HostPhysAddr};
811
use axdevice_base::BaseMmioDeviceOps;
912

@@ -44,7 +47,11 @@ pub fn get_gic_devices(config: GicDeviceConfig) -> Vec<Arc<dyn BaseMmioDeviceOps
4447
let mut gicd = VGicD::new(config.gicd_base, None);
4548

4649
for assigned_spi in config.assigned_spis {
47-
gicd.assign_irq(assigned_spi.spi, assigned_spi.target_cpu_phys_id, assigned_spi.target_cpu_affinity);
50+
gicd.assign_irq(
51+
assigned_spi.spi,
52+
assigned_spi.target_cpu_phys_id,
53+
assigned_spi.target_cpu_affinity,
54+
);
4855
}
4956

5057
results.push(Arc::new(gicd));
@@ -62,13 +69,11 @@ pub fn get_gic_devices(config: GicDeviceConfig) -> Vec<Arc<dyn BaseMmioDeviceOps
6269

6370
results
6471

65-
6672
// let mut vgicd = VGicD::new(0x0800_0000.into(), None);
6773

6874
// vgicd.assigned_irqs.set(0x28, true);
6975
// // vgicd.assigned_irqs.set(0x1, true);
7076

71-
7277
// let vgicr0 = VGicR::new(0x080a_0000.into(), None, 0);
7378
// let vgicr1 = VGicR::new(0x080c_0000.into(), None, 1);
7479
// let vgicr2 = VGicR::new(0x080e_0000.into(), None, 2);

src/vcpu.rs

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use core::marker::PhantomData;
22

33
use aarch64_cpu::registers::{CNTHCTL_EL2, HCR_EL2, SP_EL0, SPSR_EL1, VTCR_EL2};
4+
use axaddrspace::device::SysRegAddr;
45
use tock_registers::interfaces::{ReadWriteable, Readable, Writeable};
56

67
use crate::TrapFrame;
@@ -303,14 +304,46 @@ impl<H: AxVCpuHal> Aarch64VCpu<H> {
303304
_ => panic!("Unhandled exception {:?}", exit_reason),
304305
};
305306

307+
const SYSREG_ICC_SGI1R_EL1: SysRegAddr = SysRegAddr::new(0x3A_3016); // ICC_SGI1R_EL1
306308
match result {
307-
Ok(AxVCpuExitReason::MmioRead {
308-
addr,
309-
width,
310-
reg,
311-
reg_width,
312-
}) if false => {}
313-
Ok(AxVCpuExitReason::MmioWrite { addr, width, data }) if false => {}
309+
Ok(AxVCpuExitReason::SysRegWrite { addr, value }) if addr == SYSREG_ICC_SGI1R_EL1 => {
310+
debug!("arm_vcpu ICC_SGI1R_EL1 write: {:#x}", value);
311+
312+
// TODO: support RangeSelector
313+
314+
let intid = (value >> 24) & 0b1111;
315+
let irm = ((value >> 40) & 0b1) != 0;
316+
317+
// IRM == 1 => send to all except self
318+
if irm {
319+
debug!("arm_vcpu ICC_SGI1R_EL1 write: irm == 1, send to all except self");
320+
321+
return Ok(AxVCpuExitReason::SendIPI {
322+
target_cpu: 0,
323+
target_cpu_aux: 0,
324+
send_to_all: true,
325+
send_to_self: false,
326+
vector: intid,
327+
});
328+
}
329+
330+
let aff3 = (value >> 48) & 0xff;
331+
let aff2 = (value >> 32) & 0xff;
332+
let aff1 = (value >> 16) & 0xff;
333+
let target_list = (value & 0xffff);
334+
335+
debug!(
336+
"arm_vcpu ICC_SGI1R_EL1 write: aff3:{:#x} aff2:{:#x} aff1:{:#x} intid:{:#x} target_list:{:#x}",
337+
aff3, aff2, aff1, intid, target_list
338+
);
339+
return Ok(AxVCpuExitReason::SendIPI {
340+
target_cpu: (aff3 << 24) | (aff2 << 16) | (aff1 << 8),
341+
target_cpu_aux: target_list,
342+
send_to_all: false,
343+
send_to_self: false,
344+
vector: intid,
345+
});
346+
}
314347
r => return r,
315348
}
316349

0 commit comments

Comments
 (0)