diff options
Diffstat (limited to 'src/dev')
-rw-r--r-- | src/dev/arm/RealView.py | 65 | ||||
-rw-r--r-- | src/dev/pci/PciHost.py | 34 |
2 files changed, 98 insertions, 1 deletions
diff --git a/src/dev/arm/RealView.py b/src/dev/arm/RealView.py index 760c3c709..55332781f 100644 --- a/src/dev/arm/RealView.py +++ b/src/dev/arm/RealView.py @@ -118,6 +118,71 @@ class GenericArmPciHost(GenericPciHost): int_base = Param.Unsigned("PCI interrupt base") int_count = Param.Unsigned("Maximum number of interrupts used by this host") + def generateDeviceTree(self, state): + local_state = FdtState(addr_cells=3, size_cells=2, cpu_cells=1) + intterrupt_cells = 1 + + node = FdtNode("pci") + + if int(self.conf_device_bits) == 8: + node.appendCompatible("pci-host-cam-generic") + elif int(self.conf_device_bits) == 12: + node.appendCompatible("pci-host-ecam-generic") + else: + m5.fatal("No compatibility string for the set conf_device_width") + + node.append(FdtPropertyStrings("device_type", ["pci"])) + + # Cell sizes of child nodes/peripherals + node.append(local_state.addrCellsProperty()) + node.append(local_state.sizeCellsProperty()) + node.append(FdtPropertyWords("#interrupt-cells", intterrupt_cells)) + # PCI address for CPU + node.append(FdtPropertyWords("reg", + state.addrCells(self.conf_base) + + state.sizeCells(self.conf_size) )) + + # Ranges mapping + # For now some of this is hard coded, because the PCI module does not + # have a proper full understanding of the memory map, but adapting the + # PCI module is beyond the scope of what I'm trying to do here. + # Values are taken from the VExpress_GEM5_V1 platform. + ranges = [] + # Pio address range + ranges += self.pciFdtAddr(space=1, addr=0) + ranges += state.addrCells(self.pci_pio_base) + ranges += local_state.sizeCells(0x10000) # Fixed size + + # AXI memory address range + ranges += self.pciFdtAddr(space=2, addr=0) + ranges += state.addrCells(0x40000000) # Fixed offset + ranges += local_state.sizeCells(0x40000000) # Fixed size + node.append(FdtPropertyWords("ranges", ranges)) + + if str(self.int_policy) == 'ARM_PCI_INT_DEV': + int_phandle = state.phandle(self._parent.unproxy(self).gic) + # Interrupt mapping + interrupts = [] + for i in range(int(self.int_count)): + interrupts += self.pciFdtAddr(device=i, addr=0) + \ + [0x0, int_phandle, 0, int(self.int_base) - 32 + i, 1] + + node.append(FdtPropertyWords("interrupt-map", interrupts)) + + int_count = int(self.int_count) + if int_count & (int_count - 1): + fatal("PCI interrupt count should be power of 2") + + intmask = self.pciFdtAddr(device=int_count - 1, addr=0) + [0x0] + node.append(FdtPropertyWords("interrupt-map-mask", intmask)) + else: + m5.fatal("Unsupported PCI interrupt policy " + + "for Device Tree generation") + + node.append(FdtProperty("dma-coherent")) + + yield node + class RealViewCtrl(BasicPioDevice): type = 'RealViewCtrl' cxx_header = "dev/arm/rv_ctrl.hh" diff --git a/src/dev/pci/PciHost.py b/src/dev/pci/PciHost.py index f4f9e45e8..28405c198 100644 --- a/src/dev/pci/PciHost.py +++ b/src/dev/pci/PciHost.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015 ARM Limited +# Copyright (c) 2015-2016 ARM Limited # All rights reserved # # The license below extends only to copyright in the software and shall @@ -34,6 +34,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # Authors: Andreas Sandberg +# Glenn Bergmans from m5.SimObject import SimObject from m5.params import * @@ -62,3 +63,34 @@ class GenericPciHost(PciHost): pci_pio_base = Param.Addr(0, "Base address for PCI IO accesses") pci_mem_base = Param.Addr(0, "Base address for PCI memory accesses") pci_dma_base = Param.Addr(0, "Base address for DMA memory accesses") + + def pciFdtAddr(self, bus=0, device=0, function=0, register=0, space=0, + aliased=0, prefetchable=0, relocatable=0, addr=0): + + busf = bus & 0xff + devicef = device & 0x1f + functionf = function & 0x7 + registerf = register & 0xff + spacef = space & 0x3 + aliasedf = aliased & 0x1 + prefetchablef = prefetchable & 0x1 + relocatablef = relocatable & 0x1 + + if busf != bus or \ + devicef != device or \ + functionf != function or \ + registerf != register or \ + spacef != space or \ + aliasedf != aliased or \ + prefetchablef != prefetchable or \ + relocatablef != relocatable: + fatal("One of the fields for the PCI address is out of bounds") + + address = registerf | (functionf << 8) | (devicef << 11) | \ + (busf << 16) | (spacef << 24) | (aliasedf << 29) | \ + (prefetchablef << 30) | (relocatablef << 31) + + low_addr = addr & 0xffffffff + high_addr = (addr >> 32) & 0xffffffff + + return [address, high_addr, low_addr] |