This directory contains the implementation of Genode's x86 platform driver.

Behavior
--------

On startup the driver scans the PCI bus hierarchy and stores the found devices.
Per client a policy must be configured that states which client can
access certain devices to form a virtual pci bus per client. The client may
iterate through the virtual pci bus using the 'first' and 'next' methods of
the platform_session interface to discover all available devices of the virtual
bus. Non PCI devices may be discovered by using 'device' of the
platform_session interface.  As a result of the discovery a client obtains a
device capability.

With the device capability the resources of the devices can be obtained, e.g.
io_port, io_mem and irq of the platform_device interface.

Policy usage
------------

A policy may contain several nodes describing several devices. The entries of
a policy may describe PCI devices as non PCI devices. A PCI device is
explicitly configured by the triple 'bus', 'device', 'function':

!<start name="platform_drv" managing_system="yes">
! <resource name="RAM" quantum="8M"/>
! ...
! <config>
!  <policy label_prefix="usb_drv">
!   <pci bus="0" device="19" function="0"/>
!   <pci bus="0" device="18" function="3"/>
!  </policy>
! </config>
! ...

or more fuzzy by a device class alias:

!<start name="platform_drv" managing_system="yes">
! <resource name="RAM" quantum="8M"/>
! ...
! <config>
!  <policy label_prefix="usb_drv">
!   <pci class="USB"/>
!  </policy>
! </config>
! ...


Non PCI devices, as the PS2 controller are named by a "device" node in the policy:

!<start name="platform_drv" managing_system="yes">
! <resource name="RAM" quantum="8M"/>
! <config>
!  <policy label_prefix="ps2_drv">
!   <device name="PS2/>
!  </policy>
! </config>
! ...


The first entry ('pci' or 'dev') of the policy node that matches will grant
access of a device or device class to the client. Subsequent entries will not
be checked. If a 'bus', 'device', 'function' triple was specified in one of the
policies and in another policy a fuzzy pci class alias which would include
the device specified by the triple, the device will not appear during device
discovery by the client with the fuzzy pci class policy.


By default the driver will try to use first MSI-X, then MSI and finally GSI.
However, the MSI-X/MSI feature depends on the support by the used kernel and
the PCI capabilities of the device. The MSI and MSI-X feature can be disabled
explicitly by configuration, e.g.:

!<start name="platform_drv" managing_system="yes">
! <resource name="RAM" quantum="8M"/>
! <config>
!  <policy label_prefix="nic_drv" msi="false" msix="false">
!  ...
!  </policy>
! </config>
! ...

The managing_system attribute is evaluated by init. If set to "yes" it
permits a component, the platform driver, to restrict the allocation of memory to
specific physical RAM ranges. The platform driver uses this feature to ensure that
the allocation of DMA capable memory consider several restrictions. For
example, some drivers, as the UHCI controller, requires a
physical memory address below 4G. Another example is that on 32bit hosts
physical to virtual identical mappings of DMA memory for the device_pd
(required when IOMMU is used) must be below the kernel memory boundary (3G).
On some systems, e.g., base-hw kernel on certain ARM platforms, it allows the
platform driver to call system management firmware via kernel syscalls.

The platform driver waits on startup on the first valid ACPI report, typically
provided dynamically by the acpi driver.
The report contains further information about the hardware the platform driver can
not discover (e.g. IRQ re-routing information, PCI ECAM/MMCONF information).

A specific route to a report_rom service named 'acpi_report_rom' looks as
in the following:

!<start name="platform_drv">
!  ...
!  <route>
!    <service name="ROM" label="acpi">
!      <child name="acpi_report_rom"/>
!    </service>
!    ...
!  </route>
!  ...

Synchronize ACPI startup and platform driver
--------------------------------------------

If the config attribute 'acpi_ready' is set to 'yes', the platform driver
monitors a ROM in XML format named 'acpi_ready'.

!<start name="platform_drv">
!  <config acpi_ready="yes">

The platform driver will announce its service not as 'Platform', but instead
as 'Acpi' first.

An ACPI application like acpica can connect to the platform driver and may
reconfigure hardware devices according to the ACPI table findings. If the
system state changes to "acpi_ready in the XML ROM 'acpi_ready':

!<system state="acpi_ready"/>

the platform driver will announce the platform session as 'Platform', so
that drivers may start to operate with the platform driver.

Supported PCI class aliases
---------------------------

The following class names are supported which correspond to the
specified PCI base class (B), sub class (S) and programming interface
(P) combinations. ('-' matches all devices in the category)

alias       B   S   P

ALL         -   -   -
AHCI       01  06   -
AUDIO      04  01   -
ETHERNET   02  00   -
HDAUDIO    04  03   -
ISABRIDGE  06  01   -
NVME       01  08  02
USB        0c  03  00 10 20 30
USB4       0c  03  40
VGA        03  00  00
WIFI       02  80   -

Fixups for insufficient PCI BAR configuration
---------------------------------------------

If PCI devices happen to miss complete configuration after boot, the
platform driver supports <pci-fixup> nodes for concrete devices
(specified by bus-device-functions tuples). As depicted below, the
<bar> node instructs the platform driver to remap BAR id 0 to address
0x4017002000, which amends the BIOS configuration and is stringently
required for BARs with address 0.

!<pci-fixup bus="0" device="0x15" function="3">
!  <bar id="0" address="0x4017002000"/>
!</pci-fixup>


Supported non PCI devices
-------------------------

The driver provides for the PS2 and PIT device the IO_PORT and IRQ resources.

!<start name="platform_drv" managing_system="yes">
! <resource name="RAM" quantum="8M"/>
! <config>
!  <policy label_prefix="ps2_drv">
!   <dev name="PS2/>
!  </policy>
!  <policy label_prefix="pit_timer_drv">
!   <dev name="PIT/>
!  </policy>
! </config>
!</start>

Also, known ACPI device resources can be statically configured on
startup like follows.

!<config>
!  <policy label_prefix="driver">
!    <device name="INT34C5"/>
!    <device name="ACPI0000"/>
!  </policy>
!
!  <device hid="INT34C5" type="acpi">
!    <irq number="14" mode="level" polarity="low"/>
!    <io_mem address="0xfd690000" size="0x1000"/>
!    <io_mem address="0xfd6a0000" size="0x1000"/>
!    <io_mem address="0xfd6d0000" size="0x1000"/>
!    <io_mem address="0xfd6e0000" size="0x1000"/>
!  </device>
!  <device name="ACPI0000" type="acpi">
!    <irq  number="99"/>
!    <io_mem        address="0xfc000000" size="0x100000"/>
!    <io_port_range address="0x4000"     size="4"/>
!  </device>
!</config>
