Chris Metcalf | bce5bbb | 2012-04-07 16:53:03 -0400 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2012 Tilera Corporation. All Rights Reserved. |
| 3 | * |
| 4 | * This program is free software; you can redistribute it and/or |
| 5 | * modify it under the terms of the GNU General Public License |
| 6 | * as published by the Free Software Foundation, version 2. |
| 7 | * |
| 8 | * This program is distributed in the hope that it will be useful, but |
| 9 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
| 10 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or |
| 11 | * NON INFRINGEMENT. See the GNU General Public License for |
| 12 | * more details. |
| 13 | */ |
| 14 | |
| 15 | /* |
| 16 | * |
| 17 | * An API for allocating, configuring, and manipulating TRIO hardware |
| 18 | * resources |
| 19 | */ |
| 20 | |
| 21 | /* |
| 22 | * |
| 23 | * The TILE-Gx TRIO shim provides connections to external devices via |
| 24 | * PCIe or other transaction IO standards. The gxio_trio_ API, |
| 25 | * declared in <gxio/trio.h>, allows applications to allocate and |
| 26 | * configure TRIO IO resources like DMA command rings, memory map |
| 27 | * windows, and device interrupts. The following sections introduce |
| 28 | * the various components of the API. We strongly recommend reading |
| 29 | * the TRIO section of the IO Device Guide (UG404) before working with |
| 30 | * this API. |
| 31 | * |
| 32 | * @section trio__ingress TRIO Ingress Hardware Resources |
| 33 | * |
| 34 | * The TRIO ingress hardware is responsible for examining incoming |
| 35 | * PCIe or StreamIO packets and choosing a processing mechanism based |
| 36 | * on the packets' bus address. The gxio_trio_ API can be used to |
| 37 | * configure different handlers for different ranges of bus address |
| 38 | * space. The user can configure "mapped memory" and "scatter queue" |
| 39 | * regions to match incoming packets within 4kB-aligned ranges of bus |
| 40 | * addresses. Each range specifies a different set of mapping |
| 41 | * parameters to be applied when handling the ingress packet. The |
| 42 | * following sections describe how to work with MapMem and scatter |
| 43 | * queue regions. |
| 44 | * |
| 45 | * @subsection trio__mapmem TRIO MapMem Regions |
| 46 | * |
| 47 | * TRIO mapped memory (or MapMem) regions allow the user to map |
| 48 | * incoming read and write requests directly to the application's |
| 49 | * memory space. MapMem regions are allocated via |
| 50 | * gxio_trio_alloc_memory_maps(). Given an integer MapMem number, |
| 51 | * applications can use gxio_trio_init_memory_map() to specify the |
| 52 | * range of bus addresses that will match the region and the range of |
| 53 | * virtual addresses to which those packets will be applied. |
| 54 | * |
| 55 | * As with many other gxio APIs, the programmer must be sure to |
| 56 | * register memory pages that will be used with MapMem regions. Pages |
| 57 | * can be registered with TRIO by allocating an ASID (address space |
| 58 | * identifier) and then using gxio_trio_register_page() to register up to |
| 59 | * 16 pages with the hardware. The initialization functions for |
| 60 | * resources that require registered memory (MapMem, scatter queues, |
| 61 | * push DMA, and pull DMA) then take an 'asid' parameter in order to |
| 62 | * configure which set of registered pages is used by each resource. |
| 63 | * |
| 64 | * @subsection trio__scatter_queue TRIO Scatter Queues |
| 65 | * |
| 66 | * The TRIO shim's scatter queue regions allow users to dynamically |
| 67 | * map buffers from a large address space into a small range of bus |
| 68 | * addresses. This is particularly helpful for PCIe endpoint devices, |
| 69 | * where the host generally limits the size of BARs to tens of |
| 70 | * megabytes. |
| 71 | * |
| 72 | * Each scatter queue consists of a memory map region, a queue of |
| 73 | * tile-side buffer VAs to be mapped to that region, and a bus-mapped |
| 74 | * "doorbell" register that the remote endpoint can write to trigger a |
| 75 | * dequeue of the current buffer VA, thus swapping in a new buffer. |
| 76 | * The VAs pushed onto a scatter queue must be 4kB aligned, so |
| 77 | * applications may need to use higher-level protocols to inform |
| 78 | * remote entities that they should apply some additional, sub-4kB |
| 79 | * offset when reading or writing the scatter queue region. For more |
| 80 | * information, see the IO Device Guide (UG404). |
| 81 | * |
| 82 | * @section trio__egress TRIO Egress Hardware Resources |
| 83 | * |
| 84 | * The TRIO shim supports two mechanisms for egress packet generation: |
| 85 | * programmed IO (PIO) and push/pull DMA. PIO allows applications to |
| 86 | * create MMIO mappings for PCIe or StreamIO address space, such that |
| 87 | * the application can generate word-sized read or write transactions |
| 88 | * by issuing load or store instructions. Push and pull DMA are tuned |
| 89 | * for larger transactions; they use specialized hardware engines to |
| 90 | * transfer large blocks of data at line rate. |
| 91 | * |
| 92 | * @subsection trio__pio TRIO Programmed IO |
| 93 | * |
| 94 | * Programmed IO allows applications to create MMIO mappings for PCIe |
| 95 | * or StreamIO address space. The hardware PIO regions support access |
| 96 | * to PCIe configuration, IO, and memory space, but the gxio_trio API |
| 97 | * only supports memory space accesses. PIO regions are allocated |
| 98 | * with gxio_trio_alloc_pio_regions() and initialized via |
| 99 | * gxio_trio_init_pio_region(). Once a region is bound to a range of |
| 100 | * bus address via the initialization function, the application can |
| 101 | * use gxio_trio_map_pio_region() to create MMIO mappings from its VA |
| 102 | * space onto the range of bus addresses supported by the PIO region. |
| 103 | * |
| 104 | * @subsection trio_dma TRIO Push and Pull DMA |
| 105 | * |
| 106 | * The TRIO push and pull DMA engines allow users to copy blocks of |
| 107 | * data between application memory and the bus. Push DMA generates |
| 108 | * write packets that copy from application memory to the bus and pull |
| 109 | * DMA generates read packets that copy from the bus into application |
| 110 | * memory. The DMA engines are managed via an API that is very |
| 111 | * similar to the mPIPE eDMA interface. For a detailed explanation of |
| 112 | * the eDMA queue API, see @ref gxio_mpipe_wrappers. |
| 113 | * |
| 114 | * Push and pull DMA queues are allocated via |
| 115 | * gxio_trio_alloc_push_dma_ring() / gxio_trio_alloc_pull_dma_ring(). |
| 116 | * Once allocated, users generally use a ::gxio_trio_dma_queue_t |
| 117 | * object to manage the queue, providing easy wrappers for reserving |
| 118 | * command slots in the DMA command ring, filling those slots, and |
| 119 | * waiting for commands to complete. DMA queues can be initialized |
| 120 | * via gxio_trio_init_push_dma_queue() or |
| 121 | * gxio_trio_init_pull_dma_queue(). |
| 122 | * |
| 123 | * See @ref trio/push_dma/app.c for an example of how to use push DMA. |
| 124 | * |
| 125 | * @section trio_shortcomings Plans for Future API Revisions |
| 126 | * |
| 127 | * The simulation framework is incomplete. Future features include: |
| 128 | * |
| 129 | * - Support for reset and deallocation of resources. |
| 130 | * |
| 131 | * - Support for pull DMA. |
| 132 | * |
| 133 | * - Support for interrupt regions and user-space interrupt delivery. |
| 134 | * |
| 135 | * - Support for getting BAR mappings and reserving regions of BAR |
| 136 | * address space. |
| 137 | */ |
| 138 | #ifndef _GXIO_TRIO_H_ |
| 139 | #define _GXIO_TRIO_H_ |
| 140 | |
| 141 | #include <linux/types.h> |
| 142 | |
David Howells | a1ce392 | 2012-10-02 18:01:25 +0100 | [diff] [blame] | 143 | #include <gxio/common.h> |
| 144 | #include <gxio/dma_queue.h> |
Chris Metcalf | bce5bbb | 2012-04-07 16:53:03 -0400 | [diff] [blame] | 145 | |
| 146 | #include <arch/trio_constants.h> |
| 147 | #include <arch/trio.h> |
| 148 | #include <arch/trio_pcie_intfc.h> |
| 149 | #include <arch/trio_pcie_rc.h> |
| 150 | #include <arch/trio_shm.h> |
| 151 | #include <hv/drv_trio_intf.h> |
| 152 | #include <hv/iorpc.h> |
| 153 | |
| 154 | /* A context object used to manage TRIO hardware resources. */ |
| 155 | typedef struct { |
| 156 | |
| 157 | /* File descriptor for calling up to Linux (and thus the HV). */ |
| 158 | int fd; |
| 159 | |
| 160 | /* The VA at which the MAC MMIO registers are mapped. */ |
| 161 | char *mmio_base_mac; |
| 162 | |
| 163 | /* The VA at which the PIO config space are mapped for each PCIe MAC. |
| 164 | Gx36 has max 3 PCIe MACs per TRIO shim. */ |
| 165 | char *mmio_base_pio_cfg[TILEGX_TRIO_PCIES]; |
| 166 | |
| 167 | #ifdef USE_SHARED_PCIE_CONFIG_REGION |
| 168 | /* Index of the shared PIO region for PCI config access. */ |
| 169 | int pio_cfg_index; |
| 170 | #else |
| 171 | /* Index of the PIO region for PCI config access per MAC. */ |
| 172 | int pio_cfg_index[TILEGX_TRIO_PCIES]; |
| 173 | #endif |
| 174 | |
| 175 | /* The VA at which the push DMA MMIO registers are mapped. */ |
| 176 | char *mmio_push_dma[TRIO_NUM_PUSH_DMA_RINGS]; |
| 177 | |
| 178 | /* The VA at which the pull DMA MMIO registers are mapped. */ |
| 179 | char *mmio_pull_dma[TRIO_NUM_PUSH_DMA_RINGS]; |
| 180 | |
| 181 | /* Application space ID. */ |
| 182 | unsigned int asid; |
| 183 | |
| 184 | } gxio_trio_context_t; |
| 185 | |
| 186 | /* Command descriptor for push or pull DMA. */ |
| 187 | typedef TRIO_DMA_DESC_t gxio_trio_dma_desc_t; |
| 188 | |
| 189 | /* A convenient, thread-safe interface to an eDMA ring. */ |
| 190 | typedef struct { |
| 191 | |
| 192 | /* State object for tracking head and tail pointers. */ |
| 193 | __gxio_dma_queue_t dma_queue; |
| 194 | |
| 195 | /* The ring entries. */ |
| 196 | gxio_trio_dma_desc_t *dma_descs; |
| 197 | |
| 198 | /* The number of entries minus one. */ |
| 199 | unsigned long mask_num_entries; |
| 200 | |
| 201 | /* The log2() of the number of entries. */ |
| 202 | unsigned int log2_num_entries; |
| 203 | |
| 204 | } gxio_trio_dma_queue_t; |
| 205 | |
| 206 | /* Initialize a TRIO context. |
| 207 | * |
| 208 | * This function allocates a TRIO "service domain" and maps the MMIO |
| 209 | * registers into the the caller's VA space. |
| 210 | * |
| 211 | * @param trio_index Which TRIO shim; Gx36 must pass 0. |
| 212 | * @param context Context object to be initialized. |
| 213 | */ |
| 214 | extern int gxio_trio_init(gxio_trio_context_t *context, |
| 215 | unsigned int trio_index); |
| 216 | |
| 217 | /* This indicates that an ASID hasn't been allocated. */ |
| 218 | #define GXIO_ASID_NULL -1 |
| 219 | |
| 220 | /* Ordering modes for map memory regions and scatter queue regions. */ |
| 221 | typedef enum gxio_trio_order_mode_e { |
| 222 | /* Writes are not ordered. Reads always wait for previous writes. */ |
| 223 | GXIO_TRIO_ORDER_MODE_UNORDERED = |
| 224 | TRIO_MAP_MEM_SETUP__ORDER_MODE_VAL_UNORDERED, |
| 225 | /* Both writes and reads wait for previous transactions to complete. */ |
| 226 | GXIO_TRIO_ORDER_MODE_STRICT = |
| 227 | TRIO_MAP_MEM_SETUP__ORDER_MODE_VAL_STRICT, |
| 228 | /* Writes are ordered unless the incoming packet has the |
| 229 | relaxed-ordering attributes set. */ |
| 230 | GXIO_TRIO_ORDER_MODE_OBEY_PACKET = |
| 231 | TRIO_MAP_MEM_SETUP__ORDER_MODE_VAL_REL_ORD |
| 232 | } gxio_trio_order_mode_t; |
| 233 | |
| 234 | /* Initialize a memory mapping region. |
| 235 | * |
| 236 | * @param context An initialized TRIO context. |
| 237 | * @param map A Memory map region allocated by gxio_trio_alloc_memory_map(). |
| 238 | * @param target_mem VA of backing memory, should be registered via |
| 239 | * gxio_trio_register_page() and aligned to 4kB. |
| 240 | * @param target_size Length of the memory mapping, must be a multiple |
| 241 | * of 4kB. |
| 242 | * @param asid ASID to be used for Tile-side address translation. |
| 243 | * @param mac MAC number. |
| 244 | * @param bus_address Bus address at which the mapping starts. |
| 245 | * @param order_mode Memory ordering mode for this mapping. |
| 246 | * @return Zero on success, else ::GXIO_TRIO_ERR_BAD_MEMORY_MAP, |
| 247 | * GXIO_TRIO_ERR_BAD_ASID, or ::GXIO_TRIO_ERR_BAD_BUS_RANGE. |
| 248 | */ |
| 249 | extern int gxio_trio_init_memory_map(gxio_trio_context_t *context, |
| 250 | unsigned int map, void *target_mem, |
| 251 | size_t target_size, unsigned int asid, |
| 252 | unsigned int mac, uint64_t bus_address, |
| 253 | gxio_trio_order_mode_t order_mode); |
| 254 | |
| 255 | /* Flags that can be passed to resource allocation functions. */ |
| 256 | enum gxio_trio_alloc_flags_e { |
| 257 | GXIO_TRIO_ALLOC_FIXED = HV_TRIO_ALLOC_FIXED, |
| 258 | }; |
| 259 | |
| 260 | /* Flags that can be passed to memory registration functions. */ |
| 261 | enum gxio_trio_mem_flags_e { |
| 262 | /* Do not fill L3 when writing, and invalidate lines upon egress. */ |
| 263 | GXIO_TRIO_MEM_FLAG_NT_HINT = IORPC_MEM_BUFFER_FLAG_NT_HINT, |
| 264 | |
| 265 | /* L3 cache fills should only populate IO cache ways. */ |
| 266 | GXIO_TRIO_MEM_FLAG_IO_PIN = IORPC_MEM_BUFFER_FLAG_IO_PIN, |
| 267 | }; |
| 268 | |
| 269 | /* Flag indicating a request generator uses a special traffic |
| 270 | class. */ |
| 271 | #define GXIO_TRIO_FLAG_TRAFFIC_CLASS(N) HV_TRIO_FLAG_TC(N) |
| 272 | |
| 273 | /* Flag indicating a request generator uses a virtual function |
| 274 | number. */ |
| 275 | #define GXIO_TRIO_FLAG_VFUNC(N) HV_TRIO_FLAG_VFUNC(N) |
| 276 | |
| 277 | /***************************************************************** |
| 278 | * Memory Registration * |
| 279 | ******************************************************************/ |
| 280 | |
| 281 | /* Allocate Application Space Identifiers (ASIDs). Each ASID can |
| 282 | * register up to 16 page translations. ASIDs are used by memory map |
| 283 | * regions, scatter queues, and DMA queues to translate application |
| 284 | * VAs into memory system PAs. |
| 285 | * |
| 286 | * @param context An initialized TRIO context. |
| 287 | * @param count Number of ASIDs required. |
| 288 | * @param first Index of first ASID if ::GXIO_TRIO_ALLOC_FIXED flag |
| 289 | * is set, otherwise ignored. |
| 290 | * @param flags Flag bits, including bits from ::gxio_trio_alloc_flags_e. |
| 291 | * @return Index of first ASID, or ::GXIO_TRIO_ERR_NO_ASID if allocation |
| 292 | * failed. |
| 293 | */ |
| 294 | extern int gxio_trio_alloc_asids(gxio_trio_context_t *context, |
| 295 | unsigned int count, unsigned int first, |
| 296 | unsigned int flags); |
| 297 | |
| 298 | #endif /* ! _GXIO_TRIO_H_ */ |