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

men-chameleon-bus.rst (6226B)


      1=================
      2MEN Chameleon Bus
      3=================
      4
      5.. Table of Contents
      6   =================
      7   1 Introduction
      8       1.1 Scope of this Document
      9       1.2 Limitations of the current implementation
     10   2 Architecture
     11       2.1 MEN Chameleon Bus
     12       2.2 Carrier Devices
     13       2.3 Parser
     14   3 Resource handling
     15       3.1 Memory Resources
     16       3.2 IRQs
     17   4 Writing an MCB driver
     18       4.1 The driver structure
     19       4.2 Probing and attaching
     20       4.3 Initializing the driver
     21       4.4 Using DMA
     22
     23
     24Introduction
     25============
     26
     27This document describes the architecture and implementation of the MEN
     28Chameleon Bus (called MCB throughout this document).
     29
     30Scope of this Document
     31----------------------
     32
     33This document is intended to be a short overview of the current
     34implementation and does by no means describe the complete possibilities of MCB
     35based devices.
     36
     37Limitations of the current implementation
     38-----------------------------------------
     39
     40The current implementation is limited to PCI and PCIe based carrier devices
     41that only use a single memory resource and share the PCI legacy IRQ.  Not
     42implemented are:
     43
     44- Multi-resource MCB devices like the VME Controller or M-Module carrier.
     45- MCB devices that need another MCB device, like SRAM for a DMA Controller's
     46  buffer descriptors or a video controller's video memory.
     47- A per-carrier IRQ domain for carrier devices that have one (or more) IRQs
     48  per MCB device like PCIe based carriers with MSI or MSI-X support.
     49
     50Architecture
     51============
     52
     53MCB is divided into 3 functional blocks:
     54
     55- The MEN Chameleon Bus itself,
     56- drivers for MCB Carrier Devices and
     57- the parser for the Chameleon table.
     58
     59MEN Chameleon Bus
     60-----------------
     61
     62The MEN Chameleon Bus is an artificial bus system that attaches to a so
     63called Chameleon FPGA device found on some hardware produced my MEN Mikro
     64Elektronik GmbH. These devices are multi-function devices implemented in a
     65single FPGA and usually attached via some sort of PCI or PCIe link. Each
     66FPGA contains a header section describing the content of the FPGA. The
     67header lists the device id, PCI BAR, offset from the beginning of the PCI
     68BAR, size in the FPGA, interrupt number and some other properties currently
     69not handled by the MCB implementation.
     70
     71Carrier Devices
     72---------------
     73
     74A carrier device is just an abstraction for the real world physical bus the
     75Chameleon FPGA is attached to. Some IP Core drivers may need to interact with
     76properties of the carrier device (like querying the IRQ number of a PCI
     77device). To provide abstraction from the real hardware bus, an MCB carrier
     78device provides callback methods to translate the driver's MCB function calls
     79to hardware related function calls. For example a carrier device may
     80implement the get_irq() method which can be translated into a hardware bus
     81query for the IRQ number the device should use.
     82
     83Parser
     84------
     85
     86The parser reads the first 512 bytes of a Chameleon device and parses the
     87Chameleon table. Currently the parser only supports the Chameleon v2 variant
     88of the Chameleon table but can easily be adopted to support an older or
     89possible future variant. While parsing the table's entries new MCB devices
     90are allocated and their resources are assigned according to the resource
     91assignment in the Chameleon table. After resource assignment is finished, the
     92MCB devices are registered at the MCB and thus at the driver core of the
     93Linux kernel.
     94
     95Resource handling
     96=================
     97
     98The current implementation assigns exactly one memory and one IRQ resource
     99per MCB device. But this is likely going to change in the future.
    100
    101Memory Resources
    102----------------
    103
    104Each MCB device has exactly one memory resource, which can be requested from
    105the MCB bus. This memory resource is the physical address of the MCB device
    106inside the carrier and is intended to be passed to ioremap() and friends. It
    107is already requested from the kernel by calling request_mem_region().
    108
    109IRQs
    110----
    111
    112Each MCB device has exactly one IRQ resource, which can be requested from the
    113MCB bus. If a carrier device driver implements the ->get_irq() callback
    114method, the IRQ number assigned by the carrier device will be returned,
    115otherwise the IRQ number inside the Chameleon table will be returned. This
    116number is suitable to be passed to request_irq().
    117
    118Writing an MCB driver
    119=====================
    120
    121The driver structure
    122--------------------
    123
    124Each MCB driver has a structure to identify the device driver as well as
    125device ids which identify the IP Core inside the FPGA. The driver structure
    126also contains callback methods which get executed on driver probe and
    127removal from the system::
    128
    129	static const struct mcb_device_id foo_ids[] = {
    130		{ .device = 0x123 },
    131		{ }
    132	};
    133	MODULE_DEVICE_TABLE(mcb, foo_ids);
    134
    135	static struct mcb_driver foo_driver = {
    136	driver = {
    137		.name = "foo-bar",
    138		.owner = THIS_MODULE,
    139	},
    140		.probe = foo_probe,
    141		.remove = foo_remove,
    142		.id_table = foo_ids,
    143	};
    144
    145Probing and attaching
    146---------------------
    147
    148When a driver is loaded and the MCB devices it services are found, the MCB
    149core will call the driver's probe callback method. When the driver is removed
    150from the system, the MCB core will call the driver's remove callback method::
    151
    152	static init foo_probe(struct mcb_device *mdev, const struct mcb_device_id *id);
    153	static void foo_remove(struct mcb_device *mdev);
    154
    155Initializing the driver
    156-----------------------
    157
    158When the kernel is booted or your foo driver module is inserted, you have to
    159perform driver initialization. Usually it is enough to register your driver
    160module at the MCB core::
    161
    162	static int __init foo_init(void)
    163	{
    164		return mcb_register_driver(&foo_driver);
    165	}
    166	module_init(foo_init);
    167
    168	static void __exit foo_exit(void)
    169	{
    170		mcb_unregister_driver(&foo_driver);
    171	}
    172	module_exit(foo_exit);
    173
    174The module_mcb_driver() macro can be used to reduce the above code::
    175
    176	module_mcb_driver(foo_driver);
    177
    178Using DMA
    179---------
    180
    181To make use of the kernel's DMA-API's function, you will need to use the
    182carrier device's 'struct device'. Fortunately 'struct mcb_device' embeds a
    183pointer (->dma_dev) to the carrier's device for DMA purposes::
    184
    185        ret = dma_set_mask_and_coherent(&mdev->dma_dev, DMA_BIT_MASK(dma_bits));
    186        if (rc)
    187                /* Handle errors */