@@ -28,6 +28,8 @@ use crate::vstate::memory::{Address, GuestMemory, GuestMemoryMmap};
2828const GIC_PHANDLE : u32 = 1 ;
2929// This is a value for uniquely identifying the FDT node containing the clock definition.
3030const CLOCK_PHANDLE : u32 = 2 ;
31+ // This is a value for uniquely identifying the FDT node declaring the MSI controller.
32+ const MSI_PHANDLE : u32 = 3 ;
3133// You may be wondering why this big value?
3234// This phandle is used to uniquely identify the FDT nodes containing cache information. Each cpu
3335// can have a variable number of caches, some of these caches may be shared with other cpus.
@@ -302,6 +304,16 @@ fn create_gic_node(fdt: &mut FdtWriter, gic_device: &GICDevice) -> Result<(), Fd
302304 ] ;
303305
304306 fdt. property_array_u32 ( "interrupts" , & gic_intr) ?;
307+
308+ if let Some ( msi_properties) = gic_device. msi_properties ( ) {
309+ let msic_node = fdt. begin_node ( "msic" ) ?;
310+ fdt. property_string ( "compatible" , "arm,gic-v3-its" ) ?;
311+ fdt. property_null ( "msi-controller" ) ?;
312+ fdt. property_u32 ( "phandle" , MSI_PHANDLE ) ?;
313+ fdt. property_array_u64 ( "reg" , msi_properties) ?;
314+ fdt. end_node ( msic_node) ?;
315+ }
316+
305317 fdt. end_node ( interrupt) ?;
306318
307319 Ok ( ( ) )
@@ -471,6 +483,21 @@ fn create_pci_nodes(fdt: &mut FdtWriter, pci_devices: &PciDevices) -> Result<(),
471483 ( MEM_64BIT_DEVICES_SIZE >> 32 ) as u32 , // Range size
472484 ( ( MEM_64BIT_DEVICES_SIZE & 0xffff_ffff ) >> 32 ) as u32 ,
473485 ] ;
486+
487+ // See kernel document Documentation/devicetree/bindings/pci/pci-msi.txt
488+ let msi_map = [
489+ // rid-base: A single cell describing the first RID matched by the entry.
490+ 0x0 ,
491+ // msi-controller: A single phandle to an MSI controller.
492+ MSI_PHANDLE ,
493+ // msi-base: An msi-specifier describing the msi-specifier produced for the
494+ // first RID matched by the entry.
495+ segment. id as u32 ,
496+ // length: A single cell describing how many consecutive RIDs are matched
497+ // following the rid-base.
498+ 0x100 ,
499+ ] ;
500+
474501 let pci_node = fdt. begin_node ( & pci_node_name) ?;
475502
476503 fdt. property_string ( "compatible" , "pci-host-ecam-generic" ) ?;
@@ -491,6 +518,9 @@ fn create_pci_nodes(fdt: &mut FdtWriter, pci_devices: &PciDevices) -> Result<(),
491518 fdt. property_null ( "interrupt-map" ) ?;
492519 fdt. property_null ( "interrupt-map-mask" ) ?;
493520 fdt. property_null ( "dma-coherent" ) ?;
521+ fdt. property_array_u32 ( "msi-map" , & msi_map) ?;
522+ fdt. property_u32 ( "msi-parent" , MSI_PHANDLE ) ?;
523+
494524 Ok ( fdt. end_node ( pci_node) ?)
495525}
496526
0 commit comments