<p>Philipp Deppenwiese <strong>merged</strong> this change.</p><p><a href="https://review.coreboot.org/25750">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  build bot (Jenkins): Verified
  Philipp Deppenwiese: Looks good to me, approved

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">soc/cavium: Add PCI support<br><br>* Add support for secure/unsecure split<br>* Use MMCONF to access devices in domain0<br>* Program MSIX vectors to fix a crash in GNU/Linux<br><br>Tested on Cavium CN81XX_EVB.<br><br>All PCI devices are visible.<br><br>Change-Id: I881f38a26a165e6bd965fcd73547473b5e32d4b0<br>Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com><br>Reviewed-on: https://review.coreboot.org/25750<br>Reviewed-by: Philipp Deppenwiese <zaolin.daisuki@gmail.com><br>Tested-by: build bot (Jenkins) <no-reply@coreboot.org><br>---<br>M src/mainboard/cavium/cn8100_sff_evb/devicetree.cb<br>M src/soc/cavium/cn81xx/Kconfig<br>M src/soc/cavium/cn81xx/Makefile.inc<br>A src/soc/cavium/cn81xx/ecam0.c<br>M src/soc/cavium/cn81xx/include/soc/addressmap.h<br>A src/soc/cavium/cn81xx/include/soc/ecam0.h<br>M src/soc/cavium/cn81xx/soc.c<br>A src/soc/cavium/common/pci/chip.h<br>8 files changed, 633 insertions(+), 1 deletion(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/mainboard/cavium/cn8100_sff_evb/devicetree.cb b/src/mainboard/cavium/cn8100_sff_evb/devicetree.cb</span><br><span>index cd495e1..3398e9a 100644</span><br><span>--- a/src/mainboard/cavium/cn8100_sff_evb/devicetree.cb</span><br><span>+++ b/src/mainboard/cavium/cn8100_sff_evb/devicetree.cb</span><br><span>@@ -15,4 +15,196 @@</span><br><span> </span><br><span> chip soc/cavium/cn81xx</span><br><span>    device cpu_cluster 0 on end</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ device domain 0 on</span><br><span style="color: hsl(120, 100%, 40%);">+            chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                    register "secure" = "0"</span><br><span style="color: hsl(120, 100%, 40%);">+                   device pci 01.0 on # PCI bridge</span><br><span style="color: hsl(120, 100%, 40%);">+                               chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "secure" = "0"</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pci 00.0 on end # MRML</span><br><span style="color: hsl(120, 100%, 40%);">+                         end</span><br><span style="color: hsl(120, 100%, 40%);">+                           chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "secure" = "0"</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pci 00.1 on end # RESET</span><br><span style="color: hsl(120, 100%, 40%);">+                                end</span><br><span style="color: hsl(120, 100%, 40%);">+                           chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "secure" = "1"</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pci 00.2 on end # DAP</span><br><span style="color: hsl(120, 100%, 40%);">+                          end</span><br><span style="color: hsl(120, 100%, 40%);">+                           chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "secure" = "1"</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pci 00.3 on end # MDIO</span><br><span style="color: hsl(120, 100%, 40%);">+                         end</span><br><span style="color: hsl(120, 100%, 40%);">+                           chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "secure" = "1"</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pci 00.4 on end # FUSE</span><br><span style="color: hsl(120, 100%, 40%);">+                         end</span><br><span style="color: hsl(120, 100%, 40%);">+                           chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "secure" = "0"</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pci 01.2 on end # SGPIO</span><br><span style="color: hsl(120, 100%, 40%);">+                                end</span><br><span style="color: hsl(120, 100%, 40%);">+                           chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "secure" = "0"</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pci 01.3 on end # SMI</span><br><span style="color: hsl(120, 100%, 40%);">+                          end</span><br><span style="color: hsl(120, 100%, 40%);">+                           chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "secure" = "0"</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pci 01.4 on end # MMC</span><br><span style="color: hsl(120, 100%, 40%);">+                          end</span><br><span style="color: hsl(120, 100%, 40%);">+                           chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "secure" = "1"</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pci 01.5 on end # KEY</span><br><span style="color: hsl(120, 100%, 40%);">+                          end</span><br><span style="color: hsl(120, 100%, 40%);">+                           chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "secure" = "1"</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pci 01.6 on end # BOOT BUS</span><br><span style="color: hsl(120, 100%, 40%);">+                             end</span><br><span style="color: hsl(120, 100%, 40%);">+                           chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "secure" = "0"</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pci 01.7 on end # PBUS</span><br><span style="color: hsl(120, 100%, 40%);">+                         end</span><br><span style="color: hsl(120, 100%, 40%);">+                           chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "secure" = "0"</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pci 02.0 on end # XCV</span><br><span style="color: hsl(120, 100%, 40%);">+                          end</span><br><span style="color: hsl(120, 100%, 40%);">+                           device pci 04.0 on end</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                              chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "secure" = "0"</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pci 06.0 on end # L2C-TAD</span><br><span style="color: hsl(120, 100%, 40%);">+                              end</span><br><span style="color: hsl(120, 100%, 40%);">+                           chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "secure" = "0"</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pci 07.0 on end # L2C-CBC</span><br><span style="color: hsl(120, 100%, 40%);">+                              end</span><br><span style="color: hsl(120, 100%, 40%);">+                           chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "secure" = "0"</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pci 07.4 on end # L2C-MCI</span><br><span style="color: hsl(120, 100%, 40%);">+                              end</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                         chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "secure" = "1"</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pci 08.0 on end # UUA0</span><br><span style="color: hsl(120, 100%, 40%);">+                         end</span><br><span style="color: hsl(120, 100%, 40%);">+                           chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "secure" = "1"</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pci 08.1 on end # UUA1</span><br><span style="color: hsl(120, 100%, 40%);">+                         end</span><br><span style="color: hsl(120, 100%, 40%);">+                           chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "secure" = "1"</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pci 08.2 on end # UUA2</span><br><span style="color: hsl(120, 100%, 40%);">+                         end</span><br><span style="color: hsl(120, 100%, 40%);">+                           chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "secure" = "1"</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pci 08.3 on end # UUA3</span><br><span style="color: hsl(120, 100%, 40%);">+                         end</span><br><span style="color: hsl(120, 100%, 40%);">+                           chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "secure" = "1"</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pci 08.4 on end # VRM</span><br><span style="color: hsl(120, 100%, 40%);">+                          end</span><br><span style="color: hsl(120, 100%, 40%);">+                           chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "secure" = "0"</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pci 09.0 on end # I2C0</span><br><span style="color: hsl(120, 100%, 40%);">+                         end</span><br><span style="color: hsl(120, 100%, 40%);">+                           chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "secure" = "0"</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pci 09.1 on end # I2C1</span><br><span style="color: hsl(120, 100%, 40%);">+                         end</span><br><span style="color: hsl(120, 100%, 40%);">+                           chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "secure" = "0"</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pci 0a.0 on end # PCC Bridge</span><br><span style="color: hsl(120, 100%, 40%);">+                           end</span><br><span style="color: hsl(120, 100%, 40%);">+                           chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "secure" = "1"</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pci 0b.0 on end # IOBN</span><br><span style="color: hsl(120, 100%, 40%);">+                         end</span><br><span style="color: hsl(120, 100%, 40%);">+                           chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "secure" = "0"</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pci 0c.0 on end # OCLA0</span><br><span style="color: hsl(120, 100%, 40%);">+                                end</span><br><span style="color: hsl(120, 100%, 40%);">+                           chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "secure" = "0"</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pci 0c.1 on end # OCLA1</span><br><span style="color: hsl(120, 100%, 40%);">+                                end</span><br><span style="color: hsl(120, 100%, 40%);">+                           chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "secure" = "1"</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pci 0d.0 on end</span><br><span style="color: hsl(120, 100%, 40%);">+                                end</span><br><span style="color: hsl(120, 100%, 40%);">+                           chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "secure" = "1"</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pci 0e.0 on end # PCIe0</span><br><span style="color: hsl(120, 100%, 40%);">+                                end</span><br><span style="color: hsl(120, 100%, 40%);">+                           chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "secure" = "1"</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pci 0e.1 on end # PCIe1</span><br><span style="color: hsl(120, 100%, 40%);">+                                end</span><br><span style="color: hsl(120, 100%, 40%);">+                           chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "secure" = "1"</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pci 0e.2 on end # PCIe2</span><br><span style="color: hsl(120, 100%, 40%);">+                                end</span><br><span style="color: hsl(120, 100%, 40%);">+                           chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "secure" = "0"</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pci 10.0 on end # bgx0</span><br><span style="color: hsl(120, 100%, 40%);">+                         end</span><br><span style="color: hsl(120, 100%, 40%);">+                           chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "secure" = "0"</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pci 10.1 on end # bgx1</span><br><span style="color: hsl(120, 100%, 40%);">+                         end</span><br><span style="color: hsl(120, 100%, 40%);">+                           chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "secure" = "0"</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pci 11.0 on end # rgx0</span><br><span style="color: hsl(120, 100%, 40%);">+                         end</span><br><span style="color: hsl(120, 100%, 40%);">+                           chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "secure" = "0"</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pci 12.0 on end # MAC</span><br><span style="color: hsl(120, 100%, 40%);">+                          end</span><br><span style="color: hsl(120, 100%, 40%);">+                           chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "secure" = "1"</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pci 1c.0 on end # GSER0</span><br><span style="color: hsl(120, 100%, 40%);">+                                end</span><br><span style="color: hsl(120, 100%, 40%);">+                           chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "secure" = "1"</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pci 1c.1 on end # GSER1</span><br><span style="color: hsl(120, 100%, 40%);">+                                end</span><br><span style="color: hsl(120, 100%, 40%);">+                           chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "secure" = "1"</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pci 1c.2 on end # GSER2</span><br><span style="color: hsl(120, 100%, 40%);">+                                end</span><br><span style="color: hsl(120, 100%, 40%);">+                           chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "secure" = "1"</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pci 1c.3 on end # GSER3</span><br><span style="color: hsl(120, 100%, 40%);">+                                end</span><br><span style="color: hsl(120, 100%, 40%);">+                   end</span><br><span style="color: hsl(120, 100%, 40%);">+                   chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                            register "secure" = "1"</span><br><span style="color: hsl(120, 100%, 40%);">+                           device pci 02.0 on end #SMMU</span><br><span style="color: hsl(120, 100%, 40%);">+                  end</span><br><span style="color: hsl(120, 100%, 40%);">+                   chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                            register "secure" = "1"</span><br><span style="color: hsl(120, 100%, 40%);">+                           device pci 03.0 on end #GIC</span><br><span style="color: hsl(120, 100%, 40%);">+                   end</span><br><span style="color: hsl(120, 100%, 40%);">+                   chip soc/cavium/common/pci</span><br><span style="color: hsl(120, 100%, 40%);">+                            register "secure" = "1"</span><br><span style="color: hsl(120, 100%, 40%);">+                           device pci 04.0 on end #GTI</span><br><span style="color: hsl(120, 100%, 40%);">+                   end</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                 device pci 05.0 on end # NIC</span><br><span style="color: hsl(120, 100%, 40%);">+                  device pci 06.0 on end # GPIO</span><br><span style="color: hsl(120, 100%, 40%);">+                 device pci 07.0 on end # SPI</span><br><span style="color: hsl(120, 100%, 40%);">+                  device pci 08.0 on end # MIO</span><br><span style="color: hsl(120, 100%, 40%);">+                  device pci 09.0 on end # PCI bridge</span><br><span style="color: hsl(120, 100%, 40%);">+                   device pci 0a.0 on end # PCI bridge</span><br><span style="color: hsl(120, 100%, 40%);">+                   device pci 0b.0 on end # NFC</span><br><span style="color: hsl(120, 100%, 40%);">+                  device pci 0c.0 on end # PCI bridge</span><br><span style="color: hsl(120, 100%, 40%);">+                   device pci 0d.0 on end # PCM</span><br><span style="color: hsl(120, 100%, 40%);">+                  device pci 0e.0 on end # VRM</span><br><span style="color: hsl(120, 100%, 40%);">+                  device pci 0f.0 on end # PCI bridge</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                 device pci 10.0 on end # USB0</span><br><span style="color: hsl(120, 100%, 40%);">+                 device pci 11.0 on end # USB1</span><br><span style="color: hsl(120, 100%, 40%);">+                 device pci 16.0 on end # SATA0</span><br><span style="color: hsl(120, 100%, 40%);">+                        device pci 17.0 on end # SATA1</span><br><span style="color: hsl(120, 100%, 40%);">+                end</span><br><span style="color: hsl(120, 100%, 40%);">+   end</span><br><span> end</span><br><span>diff --git a/src/soc/cavium/cn81xx/Kconfig b/src/soc/cavium/cn81xx/Kconfig</span><br><span>index 9cc7b48..3191ef3 100644</span><br><span>--- a/src/soc/cavium/cn81xx/Kconfig</span><br><span>+++ b/src/soc/cavium/cn81xx/Kconfig</span><br><span>@@ -12,6 +12,8 @@</span><br><span>      select UART_OVERRIDE_REFCLK</span><br><span>  select SOC_CAVIUM_COMMON</span><br><span>     select CAVIUM_BDK_DDR_TUNE_HW_OFFSETS</span><br><span style="color: hsl(120, 100%, 40%);">+ select MMCONF_SUPPORT</span><br><span style="color: hsl(120, 100%, 40%);">+ select PCI</span><br><span> </span><br><span> if SOC_CAVIUM_CN81XX</span><br><span> </span><br><span>@@ -25,4 +27,7 @@</span><br><span> config STACK_SIZE</span><br><span>  default 0x2000</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+config MMCONF_BASE_ADDRESS</span><br><span style="color: hsl(120, 100%, 40%);">+        default 0x848000000000</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> endif</span><br><span>diff --git a/src/soc/cavium/cn81xx/Makefile.inc b/src/soc/cavium/cn81xx/Makefile.inc</span><br><span>index 16aa4ff..b2de484 100644</span><br><span>--- a/src/soc/cavium/cn81xx/Makefile.inc</span><br><span>+++ b/src/soc/cavium/cn81xx/Makefile.inc</span><br><span>@@ -63,6 +63,7 @@</span><br><span> ramstage-y += soc.c</span><br><span> ramstage-y += cpu.c</span><br><span> ramstage-y += cpu_secondary.S</span><br><span style="color: hsl(120, 100%, 40%);">+ramstage-y += ecam0.c</span><br><span> </span><br><span> # BDK coreboot interface</span><br><span> ramstage-y += ../common/bdk-coreboot.c</span><br><span>diff --git a/src/soc/cavium/cn81xx/ecam0.c b/src/soc/cavium/cn81xx/ecam0.c</span><br><span>new file mode 100644</span><br><span>index 0000000..cff2507</span><br><span>--- /dev/null</span><br><span>+++ b/src/soc/cavium/cn81xx/ecam0.c</span><br><span>@@ -0,0 +1,374 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * This file is part of the coreboot project.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright 2018       Facebook, Inc.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright 2003-2017  Cavium Inc.  <support@cavium.com></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; version 2 of the License.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Derived from Cavium's BSD-3 Clause OCTEONTX-SDK-6.2.0.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <console/console.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <arch/io.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <device/pci.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <device/pci_ops.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <soc/addressmap.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <soc/cavium/common/pci/chip.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <assert.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define CAVM_PCCPF_XXX_VSEC_CTL 0x108</span><br><span style="color: hsl(120, 100%, 40%);">+#define CAVM_PCCPF_XXX_VSEC_SCTL 0x10c</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Hide PCI device function on BUS 1 in non secure world.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static void disable_func(unsigned int devfn)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    u64 *addr;</span><br><span style="color: hsl(120, 100%, 40%);">+    printk(BIOS_DEBUG, "PCI: 01:%02x.%x is secure\n", devfn >> 3,</span><br><span style="color: hsl(120, 100%, 40%);">+        devfn & 7);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* disable function */</span><br><span style="color: hsl(120, 100%, 40%);">+        addr = (void *)ECAM0_RSLX_SDIS;</span><br><span style="color: hsl(120, 100%, 40%);">+       u64 reg = read64(&addr[devfn]);</span><br><span style="color: hsl(120, 100%, 40%);">+   reg &= ~3;</span><br><span style="color: hsl(120, 100%, 40%);">+        reg |= 2;</span><br><span style="color: hsl(120, 100%, 40%);">+     write64(&addr[devfn], reg);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Show PCI device function on BUS 1 in non secure world.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static void enable_func(unsigned int devfn)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      u64 *addr;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  printk(BIOS_DEBUG, "PCI: 01:%02x.%x is insecure\n", devfn >> 3,</span><br><span style="color: hsl(120, 100%, 40%);">+              devfn & 7);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* enable function */</span><br><span style="color: hsl(120, 100%, 40%);">+ addr = (void *)ECAM0_RSLX_SDIS;</span><br><span style="color: hsl(120, 100%, 40%);">+       u64 reg = read64(&addr[devfn]);</span><br><span style="color: hsl(120, 100%, 40%);">+   reg &= ~3;</span><br><span style="color: hsl(120, 100%, 40%);">+        write64(&addr[devfn], reg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     addr = (void *)ECAM0_RSLX_NSDIS;</span><br><span style="color: hsl(120, 100%, 40%);">+      reg = read64(&addr[devfn]);</span><br><span style="color: hsl(120, 100%, 40%);">+       reg &= ~1;</span><br><span style="color: hsl(120, 100%, 40%);">+        write64(&addr[devfn], reg);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Hide PCI device on BUS 0 in non secure world.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static void disable_device(unsigned int dev)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      u64 *addr;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  printk(BIOS_DEBUG, "PCI: 00:%02x.0 is secure\n", dev);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* disable function */</span><br><span style="color: hsl(120, 100%, 40%);">+        addr = (void *)ECAM0_DEVX_SDIS;</span><br><span style="color: hsl(120, 100%, 40%);">+       u64 reg = read64(&addr[dev]);</span><br><span style="color: hsl(120, 100%, 40%);">+     reg &= ~3;</span><br><span style="color: hsl(120, 100%, 40%);">+        write64(&addr[dev], reg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       addr = (void *)ECAM0_DEVX_NSDIS;</span><br><span style="color: hsl(120, 100%, 40%);">+      reg = read64(&addr[dev]);</span><br><span style="color: hsl(120, 100%, 40%);">+ reg |= 1;</span><br><span style="color: hsl(120, 100%, 40%);">+     write64(&addr[dev], reg);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Show PCI device on BUS 0 in non secure world.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static void enable_device(unsigned int dev)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ u64 *addr;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  printk(BIOS_DEBUG, "PCI: 00:%02x.0 is insecure\n", dev);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* enable function */</span><br><span style="color: hsl(120, 100%, 40%);">+ addr = (void *)ECAM0_DEVX_SDIS;</span><br><span style="color: hsl(120, 100%, 40%);">+       u64 reg = read64(&addr[dev]);</span><br><span style="color: hsl(120, 100%, 40%);">+     reg &= ~3;</span><br><span style="color: hsl(120, 100%, 40%);">+        write64(&addr[dev], reg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       addr = (void *)ECAM0_DEVX_NSDIS;</span><br><span style="color: hsl(120, 100%, 40%);">+      reg = read64(&addr[dev]);</span><br><span style="color: hsl(120, 100%, 40%);">+ reg &= ~1;</span><br><span style="color: hsl(120, 100%, 40%);">+        write64(&addr[dev], reg);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void ecam0_read_resources(struct device *dev)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   /* There are no dynamic PCI resources on Cavium SoC */</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void ecam0_fix_missing_devices(struct bus *link)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       size_t i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /**</span><br><span style="color: hsl(120, 100%, 40%);">+    * Cavium thinks it's a good idea to violate the PCI spec.</span><br><span style="color: hsl(120, 100%, 40%);">+         * Disabled multi-function PCI devices might have active functions.</span><br><span style="color: hsl(120, 100%, 40%);">+    * Add devices here manually, as coreboot's PCI allocator won't find</span><br><span style="color: hsl(120, 100%, 40%);">+   * them otherwise...</span><br><span style="color: hsl(120, 100%, 40%);">+   */</span><br><span style="color: hsl(120, 100%, 40%);">+   for (i = 0; i <= PCI_DEVFN(0x1f, 7); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                struct device_path pci_path;</span><br><span style="color: hsl(120, 100%, 40%);">+          struct device *child;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+               pci_path.type = DEVICE_PATH_PCI;</span><br><span style="color: hsl(120, 100%, 40%);">+              pci_path.pci.devfn = i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+             child = find_dev_path(link, &pci_path);</span><br><span style="color: hsl(120, 100%, 40%);">+           if (!child)</span><br><span style="color: hsl(120, 100%, 40%);">+                   pci_probe_dev(NULL, link, i);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * Get PCI BAR address from cavium specific extended capability.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Use regular BAR if not found in extended capability space.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * @return The pyhsical address of the BAR, zero on error</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static uint64_t get_bar_val(struct device *dev, u8 bar)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  size_t cap_offset = pci_find_capability(dev, 0x14);</span><br><span style="color: hsl(120, 100%, 40%);">+   uint64_t h, l, ret = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+       if (cap_offset) {</span><br><span style="color: hsl(120, 100%, 40%);">+             /* Found EA */</span><br><span style="color: hsl(120, 100%, 40%);">+                u8 es, bei;</span><br><span style="color: hsl(120, 100%, 40%);">+           u8 ne = pci_read_config8(dev, cap_offset + 2) & 0x3f;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           cap_offset += 4;</span><br><span style="color: hsl(120, 100%, 40%);">+              while (ne) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  uint32_t dw0 = pci_read_config32(dev, cap_offset);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                  es = dw0 & 7;</span><br><span style="color: hsl(120, 100%, 40%);">+                     bei = (dw0 >> 4) & 0xf;</span><br><span style="color: hsl(120, 100%, 40%);">+                     if (bei == bar) {</span><br><span style="color: hsl(120, 100%, 40%);">+                             h = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+                                l = pci_read_config32(dev, cap_offset + 4);</span><br><span style="color: hsl(120, 100%, 40%);">+                           if (l & 2)</span><br><span style="color: hsl(120, 100%, 40%);">+                                        h = pci_read_config32(dev,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                          cap_offset + 12);</span><br><span style="color: hsl(120, 100%, 40%);">+                               ret = (h << 32) | (l & ~0xfull);</span><br><span style="color: hsl(120, 100%, 40%);">+                            break;</span><br><span style="color: hsl(120, 100%, 40%);">+                        }</span><br><span style="color: hsl(120, 100%, 40%);">+                     cap_offset += (es + 1) * 4;</span><br><span style="color: hsl(120, 100%, 40%);">+                   ne--;</span><br><span style="color: hsl(120, 100%, 40%);">+         }</span><br><span style="color: hsl(120, 100%, 40%);">+     } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              h = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+                l = pci_read_config32(dev, bar * 4 + PCI_BASE_ADDRESS_0);</span><br><span style="color: hsl(120, 100%, 40%);">+             if (l & 4)</span><br><span style="color: hsl(120, 100%, 40%);">+                        h = pci_read_config32(dev, bar * 4 + PCI_BASE_ADDRESS_0</span><br><span style="color: hsl(120, 100%, 40%);">+                                             + 4);</span><br><span style="color: hsl(120, 100%, 40%);">+           ret = (h << 32) | (l & ~0xfull);</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+     return ret;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * pci_enable_msix - configure device's MSI-X capability structure</span><br><span style="color: hsl(120, 100%, 40%);">+ * @dev: pointer to the pci_dev data structure of MSI-X device function</span><br><span style="color: hsl(120, 100%, 40%);">+ * @entries: pointer to an array of MSI-X entries</span><br><span style="color: hsl(120, 100%, 40%);">+ * @nvec: number of MSI-X irqs requested for allocation by device driver</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Setup the MSI-X capability structure of device function with the number</span><br><span style="color: hsl(120, 100%, 40%);">+ * of requested irqs upon its software driver call to request for</span><br><span style="color: hsl(120, 100%, 40%);">+ * MSI-X mode enabled on its hardware device function. A return of zero</span><br><span style="color: hsl(120, 100%, 40%);">+ * indicates the successful configuration of MSI-X capability structure.</span><br><span style="color: hsl(120, 100%, 40%);">+ * A return of < 0 indicates a failure.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Or a return of > 0 indicates that driver request is exceeding the number</span><br><span style="color: hsl(120, 100%, 40%);">+ * of irqs or MSI-X vectors available. Driver should use the returned value to</span><br><span style="color: hsl(120, 100%, 40%);">+ * re-send its request.</span><br><span style="color: hsl(120, 100%, 40%);">+ **/</span><br><span style="color: hsl(120, 100%, 40%);">+static size_t ecam0_pci_enable_msix(struct device *dev,</span><br><span style="color: hsl(120, 100%, 40%);">+                             struct msix_entry *entries, size_t nvec)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       struct msix_entry *msixtable;</span><br><span style="color: hsl(120, 100%, 40%);">+ u32 offset;</span><br><span style="color: hsl(120, 100%, 40%);">+   u8 bar_idx;</span><br><span style="color: hsl(120, 100%, 40%);">+   u64 bar;</span><br><span style="color: hsl(120, 100%, 40%);">+      size_t nr_entries;</span><br><span style="color: hsl(120, 100%, 40%);">+    size_t i;</span><br><span style="color: hsl(120, 100%, 40%);">+     u16 control;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!entries) {</span><br><span style="color: hsl(120, 100%, 40%);">+               printk(BIOS_ERR, "%s: No entries specified\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+           return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   const size_t pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!pos) {</span><br><span style="color: hsl(120, 100%, 40%);">+           printk(BIOS_ERR, "%s: Device not MSI-X capable\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                 dev_path(dev));</span><br><span style="color: hsl(120, 100%, 40%);">+                return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+     nr_entries = pci_msix_table_size(dev);</span><br><span style="color: hsl(120, 100%, 40%);">+        if (nvec > nr_entries) {</span><br><span style="color: hsl(120, 100%, 40%);">+           printk(BIOS_ERR, "ERROR: %s: Specified to many table entries\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                   dev_path(dev));</span><br><span style="color: hsl(120, 100%, 40%);">+                return nr_entries;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Ensure MSI-X is disabled while it is set up */</span><br><span style="color: hsl(120, 100%, 40%);">+     control = pci_read_config16(dev, pos + PCI_MSIX_FLAGS);</span><br><span style="color: hsl(120, 100%, 40%);">+       control &= ~PCI_MSIX_FLAGS_ENABLE;</span><br><span style="color: hsl(120, 100%, 40%);">+        pci_write_config16(dev, pos + PCI_MSIX_FLAGS, control);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Find MSI-X table region */</span><br><span style="color: hsl(120, 100%, 40%);">+ offset = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+   bar_idx = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+  if (pci_msix_table_bar(dev, &offset, &bar_idx)) {</span><br><span style="color: hsl(120, 100%, 40%);">+             printk(BIOS_ERR, "ERROR: %s: Failed to find MSI-X entry\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                dev_path(dev));</span><br><span style="color: hsl(120, 100%, 40%);">+                return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+     bar = get_bar_val(dev, bar_idx);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!bar) {</span><br><span style="color: hsl(120, 100%, 40%);">+           printk(BIOS_ERR, "ERROR: %s: Failed to find MSI-X bar\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                  dev_path(dev));</span><br><span style="color: hsl(120, 100%, 40%);">+                return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+     msixtable = (struct msix_entry *)((void *)bar + offset);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /*</span><br><span style="color: hsl(120, 100%, 40%);">+     * Some devices require MSI-X to be enabled before we can touch the</span><br><span style="color: hsl(120, 100%, 40%);">+    * MSI-X registers.  We need to mask all the vectors to prevent</span><br><span style="color: hsl(120, 100%, 40%);">+        * interrupts coming in before they're fully set up.</span><br><span style="color: hsl(120, 100%, 40%);">+       */</span><br><span style="color: hsl(120, 100%, 40%);">+   control |= PCI_MSIX_FLAGS_MASKALL | PCI_MSIX_FLAGS_ENABLE;</span><br><span style="color: hsl(120, 100%, 40%);">+    pci_write_config16(dev, pos + PCI_MSIX_FLAGS, control);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     for (i = 0; i < nvec; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+               write64(&msixtable[i].addr, entries[i].addr);</span><br><span style="color: hsl(120, 100%, 40%);">+             write32(&msixtable[i].data, entries[i].data);</span><br><span style="color: hsl(120, 100%, 40%);">+             write32(&msixtable[i].vec_control, entries[i].vec_control);</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   control &= ~PCI_MSIX_FLAGS_MASKALL;</span><br><span style="color: hsl(120, 100%, 40%);">+       pci_write_config16(dev, pos + PCI_MSIX_FLAGS, control);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void ecam0_init(struct device *dev)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct soc_cavium_common_pci_config *config;</span><br><span style="color: hsl(120, 100%, 40%);">+  struct device *child, *child_last;</span><br><span style="color: hsl(120, 100%, 40%);">+    size_t i;</span><br><span style="color: hsl(120, 100%, 40%);">+     u32 reg32;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  printk(BIOS_INFO, "ECAM0: init\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct device *bridge = dev_find_slot(0, PCI_DEVFN(1, 0));</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!bridge) {</span><br><span style="color: hsl(120, 100%, 40%);">+                printk(BIOS_INFO, "ECAM0: ERROR: PCI 00:01.0 not found.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+     /**</span><br><span style="color: hsl(120, 100%, 40%);">+    * Search for missing devices on BUS 1.</span><br><span style="color: hsl(120, 100%, 40%);">+        * Only required for ARI capability programming.</span><br><span style="color: hsl(120, 100%, 40%);">+       */</span><br><span style="color: hsl(120, 100%, 40%);">+   ecam0_fix_missing_devices(bridge->link_list);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Program secure ARI capability on bus 1 */</span><br><span style="color: hsl(120, 100%, 40%);">+  child_last = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+    for (i = 0; i <= PCI_DEVFN(0x1f, 7); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                child = dev_find_slot(bridge->link_list->secondary, i);</span><br><span style="color: hsl(120, 100%, 40%);">+         if (!child || !child->enabled)</span><br><span style="color: hsl(120, 100%, 40%);">+                     continue;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           if (child_last) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     /* Program ARI capability of the previous device */</span><br><span style="color: hsl(120, 100%, 40%);">+                   reg32 = pci_read_config32(child_last,</span><br><span style="color: hsl(120, 100%, 40%);">+                                           CAVM_PCCPF_XXX_VSEC_SCTL);</span><br><span style="color: hsl(120, 100%, 40%);">+                  reg32 &= ~(0xffU << 24);</span><br><span style="color: hsl(120, 100%, 40%);">+                    reg32 |= child->path.pci.devfn << 24;</span><br><span style="color: hsl(120, 100%, 40%);">+                        pci_write_config32(child_last, CAVM_PCCPF_XXX_VSEC_SCTL,</span><br><span style="color: hsl(120, 100%, 40%);">+                                         reg32);</span><br><span style="color: hsl(120, 100%, 40%);">+            }</span><br><span style="color: hsl(120, 100%, 40%);">+             child_last = child;</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Program insecure ARI capability on bus 1 */</span><br><span style="color: hsl(120, 100%, 40%);">+        child_last = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+    for (i = 0; i <= PCI_DEVFN(0x1f, 7); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                child = dev_find_slot(bridge->link_list->secondary, i);</span><br><span style="color: hsl(120, 100%, 40%);">+         if (!child)</span><br><span style="color: hsl(120, 100%, 40%);">+                   continue;</span><br><span style="color: hsl(120, 100%, 40%);">+             config = child->chip_info;</span><br><span style="color: hsl(120, 100%, 40%);">+         if (!child->enabled || (config && config->secure))</span><br><span style="color: hsl(120, 100%, 40%);">+                      continue;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           if (child_last) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     /* Program ARI capability of the previous device */</span><br><span style="color: hsl(120, 100%, 40%);">+                   reg32 = pci_read_config32(child_last,</span><br><span style="color: hsl(120, 100%, 40%);">+                                           CAVM_PCCPF_XXX_VSEC_CTL);</span><br><span style="color: hsl(120, 100%, 40%);">+                   reg32 &= ~(0xffU << 24);</span><br><span style="color: hsl(120, 100%, 40%);">+                    reg32 |= child->path.pci.devfn << 24;</span><br><span style="color: hsl(120, 100%, 40%);">+                        pci_write_config32(child_last, CAVM_PCCPF_XXX_VSEC_CTL,</span><br><span style="color: hsl(120, 100%, 40%);">+                                          reg32);</span><br><span style="color: hsl(120, 100%, 40%);">+            }</span><br><span style="color: hsl(120, 100%, 40%);">+             child_last = child;</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Enable / disable devices on bus 0 */</span><br><span style="color: hsl(120, 100%, 40%);">+       for (i = 0; i <= 0x1f; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+              child = dev_find_slot(0, PCI_DEVFN(i, 0));</span><br><span style="color: hsl(120, 100%, 40%);">+            config = child ? child->chip_info : NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+          if (child && child->enabled && config && !config->secure)</span><br><span style="color: hsl(120, 100%, 40%);">+                       enable_device(i);</span><br><span style="color: hsl(120, 100%, 40%);">+             else</span><br><span style="color: hsl(120, 100%, 40%);">+                  disable_device(i);</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Enable / disable devices and functions on bus 1 */</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i = 0; i <= PCI_DEVFN(0x1f, 7); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                child = dev_find_slot(bridge->link_list->secondary, i);</span><br><span style="color: hsl(120, 100%, 40%);">+         config = child ? child->chip_info : NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+          if (child && child->enabled &&</span><br><span style="color: hsl(120, 100%, 40%);">+                 ((config && !config->secure) || !config))</span><br><span style="color: hsl(120, 100%, 40%);">+                      enable_func(i);</span><br><span style="color: hsl(120, 100%, 40%);">+               else</span><br><span style="color: hsl(120, 100%, 40%);">+                  disable_func(i);</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Apply IRQ on PCI devices */</span><br><span style="color: hsl(120, 100%, 40%);">+        /* UUA */</span><br><span style="color: hsl(120, 100%, 40%);">+     for (i = 0; i < 4; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+          child = dev_find_slot(bridge->link_list->secondary,</span><br><span style="color: hsl(120, 100%, 40%);">+                                   PCI_DEVFN(8, i));</span><br><span style="color: hsl(120, 100%, 40%);">+               if (!child)</span><br><span style="color: hsl(120, 100%, 40%);">+                   continue;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           struct msix_entry entry[2] = {</span><br><span style="color: hsl(120, 100%, 40%);">+                        {.addr = CAVM_GICD_SETSPI_NSR, .data = 37 + i},</span><br><span style="color: hsl(120, 100%, 40%);">+                       {.addr = CAVM_GICD_CLRSPI_NSR, .data = 37 + i},</span><br><span style="color: hsl(120, 100%, 40%);">+               };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+          ecam0_pci_enable_msix(child, entry, 2);</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   printk(BIOS_INFO, "ECAM0: done\n");</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct device_operations pci_domain_ops_ecam0 = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .set_resources    = NULL,</span><br><span style="color: hsl(120, 100%, 40%);">+     .enable_resources = NULL,</span><br><span style="color: hsl(120, 100%, 40%);">+     .read_resources   = ecam0_read_resources,</span><br><span style="color: hsl(120, 100%, 40%);">+     .init             = ecam0_init,</span><br><span style="color: hsl(120, 100%, 40%);">+       .scan_bus         = pci_domain_scan_bus,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span>diff --git a/src/soc/cavium/cn81xx/include/soc/addressmap.h b/src/soc/cavium/cn81xx/include/soc/addressmap.h</span><br><span>index 938dd32..392c93f 100644</span><br><span>--- a/src/soc/cavium/cn81xx/include/soc/addressmap.h</span><br><span>+++ b/src/soc/cavium/cn81xx/include/soc/addressmap.h</span><br><span>@@ -52,6 +52,10 @@</span><br><span> </span><br><span> /* PCC */</span><br><span> #define ECAM_PF_BAR2         0x848000000000ULL</span><br><span style="color: hsl(120, 100%, 40%);">+#define ECAM0_DEVX_NSDIS     0x87e048070000ULL</span><br><span style="color: hsl(120, 100%, 40%);">+#define ECAM0_DEVX_SDIS              0x87e048060000ULL</span><br><span style="color: hsl(120, 100%, 40%);">+#define ECAM0_RSLX_NSDIS     0x87e048050000ULL</span><br><span style="color: hsl(120, 100%, 40%);">+#define ECAM0_RSLX_SDIS              0x87e048040000ULL</span><br><span> </span><br><span> /* CPT */</span><br><span> /* SLI */</span><br><span>@@ -102,6 +106,8 @@</span><br><span>        ((((x) == 0) || ((x) == 1) || ((x) == 2) || ((x) == 3)) ? \</span><br><span>   (0x87E028000000ULL + ((x) << 24)) : 0)</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#define CAVM_GICD_SETSPI_NSR 0x801000000040ULL</span><br><span style="color: hsl(120, 100%, 40%);">+#define CAVM_GICD_CLRSPI_NSR 0x801000000048ULL</span><br><span> </span><br><span> /* TWSI */</span><br><span> #define MIO_TWS0_PF_BAR0 (0x87E0D0000000ULL + (0 << 24))</span><br><span>diff --git a/src/soc/cavium/cn81xx/include/soc/ecam0.h b/src/soc/cavium/cn81xx/include/soc/ecam0.h</span><br><span>new file mode 100644</span><br><span>index 0000000..1cc249d</span><br><span>--- /dev/null</span><br><span>+++ b/src/soc/cavium/cn81xx/include/soc/ecam0.h</span><br><span>@@ -0,0 +1,21 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * This file is part of the coreboot project.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright 2018-present Facebook, Inc.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; version 2 of the License.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#ifndef __COREBOOT_SRC_SOC_CAVIUM_COMMON_INCLUDE_SOC_ECAM0_H</span><br><span style="color: hsl(120, 100%, 40%);">+#define __COREBOOT_SRC_SOC_CAVIUM_COMMON_INCLUDE_SOC_ECAM0_H</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+extern struct device_operations pci_domain_ops_ecam0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span>diff --git a/src/soc/cavium/cn81xx/soc.c b/src/soc/cavium/cn81xx/soc.c</span><br><span>index 6c68bb2..5e540a6 100644</span><br><span>--- a/src/soc/cavium/cn81xx/soc.c</span><br><span>+++ b/src/soc/cavium/cn81xx/soc.c</span><br><span>@@ -29,6 +29,7 @@</span><br><span> #include <string.h></span><br><span> #include <symbols.h></span><br><span> #include <libbdk-boot/bdk-boot.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <soc/ecam0.h></span><br><span> </span><br><span> static void soc_read_resources(device_t dev)</span><br><span> {</span><br><span>@@ -59,7 +60,12 @@</span><br><span> </span><br><span> static void enable_soc_dev(device_t dev)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-      dev->ops = &soc_ops;</span><br><span style="color: hsl(120, 100%, 40%);">+   if (dev->path.type == DEVICE_PATH_DOMAIN &&</span><br><span style="color: hsl(120, 100%, 40%);">+                dev->path.domain.domain == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+            dev->ops = &pci_domain_ops_ecam0;</span><br><span style="color: hsl(120, 100%, 40%);">+      } else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) {</span><br><span style="color: hsl(120, 100%, 40%);">+            dev->ops = &soc_ops;</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span> }</span><br><span> </span><br><span> struct chip_operations soc_cavium_cn81xx_ops = {</span><br><span>diff --git a/src/soc/cavium/common/pci/chip.h b/src/soc/cavium/common/pci/chip.h</span><br><span>new file mode 100644</span><br><span>index 0000000..0d0d33f</span><br><span>--- /dev/null</span><br><span>+++ b/src/soc/cavium/common/pci/chip.h</span><br><span>@@ -0,0 +1,27 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * This file is part of the coreboot project.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright 2018-present Facebook, Inc.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; version 2 of the License.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#ifndef __SOC_CAVIUM_COMMON_PCI_CHIP_H</span><br><span style="color: hsl(120, 100%, 40%);">+#define __SOC_CAVIUM_COMMON_PCI_CHIP_H</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct soc_cavium_common_pci_config {</span><br><span style="color: hsl(120, 100%, 40%);">+        /**</span><br><span style="color: hsl(120, 100%, 40%);">+    * Mark the PCI device as secure.</span><br><span style="color: hsl(120, 100%, 40%);">+      * It will be visible from EL3, but hidden in EL2-0.</span><br><span style="color: hsl(120, 100%, 40%);">+   */</span><br><span style="color: hsl(120, 100%, 40%);">+   u8 secure;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#endif /* __SOC_CAVIUM_COMMON_PCI_CHIP_H */</span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/25750">change 25750</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/25750"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: I881f38a26a165e6bd965fcd73547473b5e32d4b0 </div>
<div style="display:none"> Gerrit-Change-Number: 25750 </div>
<div style="display:none"> Gerrit-PatchSet: 29 </div>
<div style="display:none"> Gerrit-Owner: Patrick Rudolph <patrick.rudolph@9elements.com> </div>
<div style="display:none"> Gerrit-Reviewer: Paul Menzel <paulepanter@users.sourceforge.net> </div>
<div style="display:none"> Gerrit-Reviewer: Philipp Deppenwiese <zaolin.daisuki@gmail.com> </div>
<div style="display:none"> Gerrit-Reviewer: build bot (Jenkins) <no-reply@coreboot.org> </div>
<div style="display:none"> Gerrit-CC: Aaron Durbin <adurbin@chromium.org> </div>
<div style="display:none"> Gerrit-CC: Nico Huber <nico.h@gmx.de> </div>