|
1 | | -use arm_vgic::v3; |
| 1 | +use arm_gic_driver::IntId; |
| 2 | +use arm_vgic::{IrqChipOp, v3}; |
| 3 | +use axvdev::IrqNum; |
| 4 | +use rdif_intc::Intc; |
2 | 5 |
|
3 | | -use crate::{fdt::fdt_edit, vdev::VDeviceList}; |
| 6 | +use crate::{fdt::fdt_edit, hal::Ioremap, vdev::VDeviceList}; |
4 | 7 |
|
5 | 8 | pub struct PlatData { |
6 | 9 | vdev: VDeviceList, |
@@ -34,22 +37,52 @@ impl PlatData { |
34 | 37 | let gicd = regs.get(0).ok_or(anyhow!("No GICD reg"))?; |
35 | 38 | let gicr = regs.get(1).ok_or(anyhow!("No GICR reg"))?; |
36 | 39 | let plat = self.vdev.new_plat(); |
37 | | - let mut gic = v3::VGic::new(); |
38 | 40 |
|
39 | | - // self.vdev.add_device(|plat| { |
40 | | - // let gic = v3::VGic::new( |
41 | | - // (gicd.address as usize).into(), |
42 | | - // (gicr.address as usize).into(), |
43 | | - // plat.clone(), |
44 | | - // ); |
45 | | - // Ok(gic) |
46 | | - // }); |
| 41 | + let config = arm_vgic::VGicConfig::new(crate::hal::cpu::count(), &Ioremap, IrqOp {}); |
| 42 | + |
| 43 | + let mut gic = v3::VGic::new(config); |
47 | 44 |
|
48 | 45 | self.vdev.add_device(|plat| { |
49 | | - let gicd = gic.new_gicd(plat.clone(), (gicd.address as usize).into()); |
| 46 | + let gicd = gic.build_gicd(plat.clone(), (gicd.address as usize).into()); |
50 | 47 | Ok(gicd) |
51 | 48 | })?; |
52 | 49 |
|
53 | 50 | Ok(()) |
54 | 51 | } |
55 | 52 | } |
| 53 | + |
| 54 | +fn with_gicv3<F, R>(f: F) -> R |
| 55 | +where |
| 56 | + F: FnOnce(&mut arm_gic_driver::v3::Gic) -> R, |
| 57 | +{ |
| 58 | + let mut g = rdrive::get_one::<Intc>().unwrap().lock().unwrap(); |
| 59 | + let gic = g |
| 60 | + .typed_mut::<arm_gic_driver::v3::Gic>() |
| 61 | + .expect("GIC is not GICv3"); |
| 62 | + f(gic) |
| 63 | +} |
| 64 | + |
| 65 | +fn covnert_irq(irq: IrqNum) -> IntId { |
| 66 | + let id: usize = irq.into(); |
| 67 | + unsafe { IntId::raw(id as _) } |
| 68 | +} |
| 69 | + |
| 70 | +struct IrqOp {} |
| 71 | + |
| 72 | +impl IrqChipOp for IrqOp { |
| 73 | + fn get_cfg(&self, irq: IrqNum) -> arm_vgic::Trigger { |
| 74 | + let res = with_gicv3(|gic| gic.get_cfg(covnert_irq(irq))); |
| 75 | + match res { |
| 76 | + arm_gic_driver::v3::Trigger::Level => arm_vgic::Trigger::Level, |
| 77 | + arm_gic_driver::v3::Trigger::Edge => arm_vgic::Trigger::Edge, |
| 78 | + } |
| 79 | + } |
| 80 | + |
| 81 | + fn set_cfg(&self, irq: IrqNum, cfg: arm_vgic::Trigger) { |
| 82 | + let t = match cfg { |
| 83 | + arm_vgic::Trigger::Level => arm_gic_driver::v3::Trigger::Level, |
| 84 | + arm_vgic::Trigger::Edge => arm_gic_driver::v3::Trigger::Edge, |
| 85 | + }; |
| 86 | + with_gicv3(|gic| gic.set_cfg(covnert_irq(irq), t)); |
| 87 | + } |
| 88 | +} |
0 commit comments