@@ -28,6 +28,8 @@ use crate::vstate::memory::{Address, GuestMemory, GuestMemoryMmap};
28
28
const GIC_PHANDLE : u32 = 1 ;
29
29
// This is a value for uniquely identifying the FDT node containing the clock definition.
30
30
const 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 ;
31
33
// You may be wondering why this big value?
32
34
// This phandle is used to uniquely identify the FDT nodes containing cache information. Each cpu
33
35
// 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
302
304
] ;
303
305
304
306
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
+
305
317
fdt. end_node ( interrupt) ?;
306
318
307
319
Ok ( ( ) )
@@ -471,6 +483,21 @@ fn create_pci_nodes(fdt: &mut FdtWriter, pci_devices: &PciDevices) -> Result<(),
471
483
( MEM_64BIT_DEVICES_SIZE >> 32 ) as u32 , // Range size
472
484
( ( MEM_64BIT_DEVICES_SIZE & 0xffff_ffff ) >> 32 ) as u32 ,
473
485
] ;
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
+
474
501
let pci_node = fdt. begin_node ( & pci_node_name) ?;
475
502
476
503
fdt. property_string ( "compatible" , "pci-host-ecam-generic" ) ?;
@@ -491,6 +518,9 @@ fn create_pci_nodes(fdt: &mut FdtWriter, pci_devices: &PciDevices) -> Result<(),
491
518
fdt. property_null ( "interrupt-map" ) ?;
492
519
fdt. property_null ( "interrupt-map-mask" ) ?;
493
520
fdt. property_null ( "dma-coherent" ) ?;
521
+ fdt. property_array_u32 ( "msi-map" , & msi_map) ?;
522
+ fdt. property_u32 ( "msi-parent" , MSI_PHANDLE ) ?;
523
+
494
524
Ok ( fdt. end_node ( pci_node) ?)
495
525
}
496
526
0 commit comments