| * Generic PCI host controller |
| |
| Firmware-initialised PCI host controllers and PCI emulations, such as the |
| virtio-pci implementations found in kvmtool and other para-virtualised |
| systems, do not require driver support for complexities such as regulator |
| and clock management. In fact, the controller may not even require the |
| configuration of a control interface by the operating system, instead |
| presenting a set of fixed windows describing a subset of IO, Memory and |
| Configuration Spaces. |
| |
| Such a controller can be described purely in terms of the standardized device |
| tree bindings communicated in pci.txt: |
| |
| |
| Properties of the host controller node: |
| |
| - compatible : Must be "pci-host-cam-generic" or "pci-host-ecam-generic" |
| depending on the layout of configuration space (CAM vs |
| ECAM respectively). |
| |
| - device_type : Must be "pci". |
| |
| - ranges : As described in IEEE Std 1275-1994, but must provide |
| at least a definition of non-prefetchable memory. One |
| or both of prefetchable Memory and IO Space may also |
| be provided. |
| |
| - bus-range : Optional property (also described in IEEE Std 1275-1994) |
| to indicate the range of bus numbers for this controller. |
| If absent, defaults to <0 255> (i.e. all buses). |
| |
| - #address-cells : Must be 3. |
| |
| - #size-cells : Must be 2. |
| |
| - reg : The Configuration Space base address and size, as accessed |
| from the parent bus. The base address corresponds to |
| the first bus in the "bus-range" property. If no |
| "bus-range" is specified, this will be bus 0 (the default). |
| |
| Properties of the /chosen node: |
| |
| - linux,pci-probe-only |
| : Optional property which takes a single-cell argument. |
| If '0', then Linux will assign devices in its usual manner, |
| otherwise it will not try to assign devices and instead use |
| them as they are configured already. |
| |
| Configuration Space is assumed to be memory-mapped (as opposed to being |
| accessed via an ioport) and laid out with a direct correspondence to the |
| geography of a PCI bus address by concatenating the various components to |
| form an offset. |
| |
| For CAM, this 24-bit offset is: |
| |
| cfg_offset(bus, device, function, register) = |
| bus << 16 | device << 11 | function << 8 | register |
| |
| Whilst ECAM extends this by 4 bits to accommodate 4k of function space: |
| |
| cfg_offset(bus, device, function, register) = |
| bus << 20 | device << 15 | function << 12 | register |
| |
| Interrupt mapping is exactly as described in `Open Firmware Recommended |
| Practice: Interrupt Mapping' and requires the following properties: |
| |
| - #interrupt-cells : Must be 1 |
| |
| - interrupt-map : <see aforementioned specification> |
| |
| - interrupt-map-mask : <see aforementioned specification> |
| |
| |
| Example: |
| |
| pci { |
| compatible = "pci-host-cam-generic" |
| device_type = "pci"; |
| #address-cells = <3>; |
| #size-cells = <2>; |
| bus-range = <0x0 0x1>; |
| |
| // CPU_PHYSICAL(2) SIZE(2) |
| reg = <0x0 0x40000000 0x0 0x1000000>; |
| |
| // BUS_ADDRESS(3) CPU_PHYSICAL(2) SIZE(2) |
| ranges = <0x01000000 0x0 0x01000000 0x0 0x01000000 0x0 0x00010000>, |
| <0x02000000 0x0 0x41000000 0x0 0x41000000 0x0 0x3f000000>; |
| |
| |
| #interrupt-cells = <0x1>; |
| |
| // PCI_DEVICE(3) INT#(1) CONTROLLER(PHANDLE) CONTROLLER_DATA(3) |
| interrupt-map = < 0x0 0x0 0x0 0x1 &gic 0x0 0x4 0x1 |
| 0x800 0x0 0x0 0x1 &gic 0x0 0x5 0x1 |
| 0x1000 0x0 0x0 0x1 &gic 0x0 0x6 0x1 |
| 0x1800 0x0 0x0 0x1 &gic 0x0 0x7 0x1>; |
| |
| // PCI_DEVICE(3) INT#(1) |
| interrupt-map-mask = <0xf800 0x0 0x0 0x7>; |
| } |