cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

pciebus-howto.rst (8417B)


      1.. SPDX-License-Identifier: GPL-2.0
      2.. include:: <isonum.txt>
      3
      4===========================================
      5The PCI Express Port Bus Driver Guide HOWTO
      6===========================================
      7
      8:Author: Tom L Nguyen tom.l.nguyen@intel.com 11/03/2004
      9:Copyright: |copy| 2004 Intel Corporation
     10
     11About this guide
     12================
     13
     14This guide describes the basics of the PCI Express Port Bus driver
     15and provides information on how to enable the service drivers to
     16register/unregister with the PCI Express Port Bus Driver.
     17
     18
     19What is the PCI Express Port Bus Driver
     20=======================================
     21
     22A PCI Express Port is a logical PCI-PCI Bridge structure. There
     23are two types of PCI Express Port: the Root Port and the Switch
     24Port. The Root Port originates a PCI Express link from a PCI Express
     25Root Complex and the Switch Port connects PCI Express links to
     26internal logical PCI buses. The Switch Port, which has its secondary
     27bus representing the switch's internal routing logic, is called the
     28switch's Upstream Port. The switch's Downstream Port is bridging from
     29switch's internal routing bus to a bus representing the downstream
     30PCI Express link from the PCI Express Switch.
     31
     32A PCI Express Port can provide up to four distinct functions,
     33referred to in this document as services, depending on its port type.
     34PCI Express Port's services include native hotplug support (HP),
     35power management event support (PME), advanced error reporting
     36support (AER), and virtual channel support (VC). These services may
     37be handled by a single complex driver or be individually distributed
     38and handled by corresponding service drivers.
     39
     40Why use the PCI Express Port Bus Driver?
     41========================================
     42
     43In existing Linux kernels, the Linux Device Driver Model allows a
     44physical device to be handled by only a single driver. The PCI
     45Express Port is a PCI-PCI Bridge device with multiple distinct
     46services. To maintain a clean and simple solution each service
     47may have its own software service driver. In this case several
     48service drivers will compete for a single PCI-PCI Bridge device.
     49For example, if the PCI Express Root Port native hotplug service
     50driver is loaded first, it claims a PCI-PCI Bridge Root Port. The
     51kernel therefore does not load other service drivers for that Root
     52Port. In other words, it is impossible to have multiple service
     53drivers load and run on a PCI-PCI Bridge device simultaneously
     54using the current driver model.
     55
     56To enable multiple service drivers running simultaneously requires
     57having a PCI Express Port Bus driver, which manages all populated
     58PCI Express Ports and distributes all provided service requests
     59to the corresponding service drivers as required. Some key
     60advantages of using the PCI Express Port Bus driver are listed below:
     61
     62  - Allow multiple service drivers to run simultaneously on
     63    a PCI-PCI Bridge Port device.
     64
     65  - Allow service drivers implemented in an independent
     66    staged approach.
     67
     68  - Allow one service driver to run on multiple PCI-PCI Bridge
     69    Port devices.
     70
     71  - Manage and distribute resources of a PCI-PCI Bridge Port
     72    device to requested service drivers.
     73
     74Configuring the PCI Express Port Bus Driver vs. Service Drivers
     75===============================================================
     76
     77Including the PCI Express Port Bus Driver Support into the Kernel
     78-----------------------------------------------------------------
     79
     80Including the PCI Express Port Bus driver depends on whether the PCI
     81Express support is included in the kernel config. The kernel will
     82automatically include the PCI Express Port Bus driver as a kernel
     83driver when the PCI Express support is enabled in the kernel.
     84
     85Enabling Service Driver Support
     86-------------------------------
     87
     88PCI device drivers are implemented based on Linux Device Driver Model.
     89All service drivers are PCI device drivers. As discussed above, it is
     90impossible to load any service driver once the kernel has loaded the
     91PCI Express Port Bus Driver. To meet the PCI Express Port Bus Driver
     92Model requires some minimal changes on existing service drivers that
     93imposes no impact on the functionality of existing service drivers.
     94
     95A service driver is required to use the two APIs shown below to
     96register its service with the PCI Express Port Bus driver (see
     97section 5.2.1 & 5.2.2). It is important that a service driver
     98initializes the pcie_port_service_driver data structure, included in
     99header file /include/linux/pcieport_if.h, before calling these APIs.
    100Failure to do so will result an identity mismatch, which prevents
    101the PCI Express Port Bus driver from loading a service driver.
    102
    103pcie_port_service_register
    104~~~~~~~~~~~~~~~~~~~~~~~~~~
    105::
    106
    107  int pcie_port_service_register(struct pcie_port_service_driver *new)
    108
    109This API replaces the Linux Driver Model's pci_register_driver API. A
    110service driver should always calls pcie_port_service_register at
    111module init. Note that after service driver being loaded, calls
    112such as pci_enable_device(dev) and pci_set_master(dev) are no longer
    113necessary since these calls are executed by the PCI Port Bus driver.
    114
    115pcie_port_service_unregister
    116~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    117::
    118
    119  void pcie_port_service_unregister(struct pcie_port_service_driver *new)
    120
    121pcie_port_service_unregister replaces the Linux Driver Model's
    122pci_unregister_driver. It's always called by service driver when a
    123module exits.
    124
    125Sample Code
    126~~~~~~~~~~~
    127
    128Below is sample service driver code to initialize the port service
    129driver data structure.
    130::
    131
    132  static struct pcie_port_service_id service_id[] = { {
    133    .vendor = PCI_ANY_ID,
    134    .device = PCI_ANY_ID,
    135    .port_type = PCIE_RC_PORT,
    136    .service_type = PCIE_PORT_SERVICE_AER,
    137    }, { /* end: all zeroes */ }
    138  };
    139
    140  static struct pcie_port_service_driver root_aerdrv = {
    141    .name		= (char *)device_name,
    142    .id_table	= &service_id[0],
    143
    144    .probe		= aerdrv_load,
    145    .remove		= aerdrv_unload,
    146
    147    .suspend	= aerdrv_suspend,
    148    .resume		= aerdrv_resume,
    149  };
    150
    151Below is a sample code for registering/unregistering a service
    152driver.
    153::
    154
    155  static int __init aerdrv_service_init(void)
    156  {
    157    int retval = 0;
    158
    159    retval = pcie_port_service_register(&root_aerdrv);
    160    if (!retval) {
    161      /*
    162      * FIX ME
    163      */
    164    }
    165    return retval;
    166  }
    167
    168  static void __exit aerdrv_service_exit(void)
    169  {
    170    pcie_port_service_unregister(&root_aerdrv);
    171  }
    172
    173  module_init(aerdrv_service_init);
    174  module_exit(aerdrv_service_exit);
    175
    176Possible Resource Conflicts
    177===========================
    178
    179Since all service drivers of a PCI-PCI Bridge Port device are
    180allowed to run simultaneously, below lists a few of possible resource
    181conflicts with proposed solutions.
    182
    183MSI and MSI-X Vector Resource
    184-----------------------------
    185
    186Once MSI or MSI-X interrupts are enabled on a device, it stays in this
    187mode until they are disabled again.  Since service drivers of the same
    188PCI-PCI Bridge port share the same physical device, if an individual
    189service driver enables or disables MSI/MSI-X mode it may result
    190unpredictable behavior.
    191
    192To avoid this situation all service drivers are not permitted to
    193switch interrupt mode on its device. The PCI Express Port Bus driver
    194is responsible for determining the interrupt mode and this should be
    195transparent to service drivers. Service drivers need to know only
    196the vector IRQ assigned to the field irq of struct pcie_device, which
    197is passed in when the PCI Express Port Bus driver probes each service
    198driver. Service drivers should use (struct pcie_device*)dev->irq to
    199call request_irq/free_irq. In addition, the interrupt mode is stored
    200in the field interrupt_mode of struct pcie_device.
    201
    202PCI Memory/IO Mapped Regions
    203----------------------------
    204
    205Service drivers for PCI Express Power Management (PME), Advanced
    206Error Reporting (AER), Hot-Plug (HP) and Virtual Channel (VC) access
    207PCI configuration space on the PCI Express port. In all cases the
    208registers accessed are independent of each other. This patch assumes
    209that all service drivers will be well behaved and not overwrite
    210other service driver's configuration settings.
    211
    212PCI Config Registers
    213--------------------
    214
    215Each service driver runs its PCI config operations on its own
    216capability structure except the PCI Express capability structure, in
    217which Root Control register and Device Control register are shared
    218between PME and AER. This patch assumes that all service drivers
    219will be well behaved and not overwrite other service driver's
    220configuration settings.