trio.h 11.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
/*
 * Copyright 2012 Tilera Corporation. All Rights Reserved.
 *
 *   This program is free software; you can redistribute it and/or
 *   modify it under the terms of the GNU General Public License
 *   as published by the Free Software Foundation, version 2.
 *
 *   This program is distributed in the hope that it will be useful, but
 *   WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
 *   NON INFRINGEMENT.  See the GNU General Public License for
 *   more details.
 */

/*
 *
 * An API for allocating, configuring, and manipulating TRIO hardware
 * resources
 */

/*
 *
 * The TILE-Gx TRIO shim provides connections to external devices via
 * PCIe or other transaction IO standards.  The gxio_trio_ API,
 * declared in <gxio/trio.h>, allows applications to allocate and
 * configure TRIO IO resources like DMA command rings, memory map
 * windows, and device interrupts.  The following sections introduce
 * the various components of the API.  We strongly recommend reading
 * the TRIO section of the IO Device Guide (UG404) before working with
 * this API.
 *
 * @section trio__ingress TRIO Ingress Hardware Resources
 *
 * The TRIO ingress hardware is responsible for examining incoming
 * PCIe or StreamIO packets and choosing a processing mechanism based
 * on the packets' bus address.  The gxio_trio_ API can be used to
 * configure different handlers for different ranges of bus address
 * space.  The user can configure "mapped memory" and "scatter queue"
 * regions to match incoming packets within 4kB-aligned ranges of bus
 * addresses.  Each range specifies a different set of mapping
 * parameters to be applied when handling the ingress packet.  The
 * following sections describe how to work with MapMem and scatter
 * queue regions.
 *
 * @subsection trio__mapmem TRIO MapMem Regions
 *
 * TRIO mapped memory (or MapMem) regions allow the user to map
 * incoming read and write requests directly to the application's
 * memory space.  MapMem regions are allocated via
 * gxio_trio_alloc_memory_maps().  Given an integer MapMem number,
 * applications can use gxio_trio_init_memory_map() to specify the
 * range of bus addresses that will match the region and the range of
 * virtual addresses to which those packets will be applied.
 *
 * As with many other gxio APIs, the programmer must be sure to
 * register memory pages that will be used with MapMem regions.  Pages
 * can be registered with TRIO by allocating an ASID (address space
 * identifier) and then using gxio_trio_register_page() to register up to
 * 16 pages with the hardware.  The initialization functions for
 * resources that require registered memory (MapMem, scatter queues,
 * push DMA, and pull DMA) then take an 'asid' parameter in order to
 * configure which set of registered pages is used by each resource.
 *
 * @subsection trio__scatter_queue TRIO Scatter Queues
 *
 * The TRIO shim's scatter queue regions allow users to dynamically
 * map buffers from a large address space into a small range of bus
 * addresses.  This is particularly helpful for PCIe endpoint devices,
 * where the host generally limits the size of BARs to tens of
 * megabytes.
 *
 * Each scatter queue consists of a memory map region, a queue of
 * tile-side buffer VAs to be mapped to that region, and a bus-mapped
 * "doorbell" register that the remote endpoint can write to trigger a
 * dequeue of the current buffer VA, thus swapping in a new buffer.
 * The VAs pushed onto a scatter queue must be 4kB aligned, so
 * applications may need to use higher-level protocols to inform
 * remote entities that they should apply some additional, sub-4kB
 * offset when reading or writing the scatter queue region.  For more
 * information, see the IO Device Guide (UG404).
 *
 * @section trio__egress TRIO Egress Hardware Resources
 *
 * The TRIO shim supports two mechanisms for egress packet generation:
 * programmed IO (PIO) and push/pull DMA.  PIO allows applications to
 * create MMIO mappings for PCIe or StreamIO address space, such that
 * the application can generate word-sized read or write transactions
 * by issuing load or store instructions.  Push and pull DMA are tuned
 * for larger transactions; they use specialized hardware engines to
 * transfer large blocks of data at line rate.
 *
 * @subsection trio__pio TRIO Programmed IO
 *
 * Programmed IO allows applications to create MMIO mappings for PCIe
 * or StreamIO address space.  The hardware PIO regions support access
 * to PCIe configuration, IO, and memory space, but the gxio_trio API
 * only supports memory space accesses.  PIO regions are allocated
 * with gxio_trio_alloc_pio_regions() and initialized via
 * gxio_trio_init_pio_region().  Once a region is bound to a range of
 * bus address via the initialization function, the application can
 * use gxio_trio_map_pio_region() to create MMIO mappings from its VA
 * space onto the range of bus addresses supported by the PIO region.
 *
 * @subsection trio_dma TRIO Push and Pull DMA
 *
 * The TRIO push and pull DMA engines allow users to copy blocks of
 * data between application memory and the bus.  Push DMA generates
 * write packets that copy from application memory to the bus and pull
 * DMA generates read packets that copy from the bus into application
 * memory.  The DMA engines are managed via an API that is very
 * similar to the mPIPE eDMA interface.  For a detailed explanation of
 * the eDMA queue API, see @ref gxio_mpipe_wrappers.
 *
 * Push and pull DMA queues are allocated via
 * gxio_trio_alloc_push_dma_ring() / gxio_trio_alloc_pull_dma_ring().
 * Once allocated, users generally use a ::gxio_trio_dma_queue_t
 * object to manage the queue, providing easy wrappers for reserving
 * command slots in the DMA command ring, filling those slots, and
 * waiting for commands to complete.  DMA queues can be initialized
 * via gxio_trio_init_push_dma_queue() or
 * gxio_trio_init_pull_dma_queue().
 *
 * See @ref trio/push_dma/app.c for an example of how to use push DMA.
 *
 * @section trio_shortcomings Plans for Future API Revisions
 *
 * The simulation framework is incomplete.  Future features include:
 *
 * - Support for reset and deallocation of resources.
 *
 * - Support for pull DMA.
 *
 * - Support for interrupt regions and user-space interrupt delivery.
 *
 * - Support for getting BAR mappings and reserving regions of BAR
 *   address space.
 */
#ifndef _GXIO_TRIO_H_
#define _GXIO_TRIO_H_

#include <linux/types.h>

143 144
#include <gxio/common.h>
#include <gxio/dma_queue.h>
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298

#include <arch/trio_constants.h>
#include <arch/trio.h>
#include <arch/trio_pcie_intfc.h>
#include <arch/trio_pcie_rc.h>
#include <arch/trio_shm.h>
#include <hv/drv_trio_intf.h>
#include <hv/iorpc.h>

/* A context object used to manage TRIO hardware resources. */
typedef struct {

	/* File descriptor for calling up to Linux (and thus the HV). */
	int fd;

	/* The VA at which the MAC MMIO registers are mapped. */
	char *mmio_base_mac;

	/* The VA at which the PIO config space are mapped for each PCIe MAC.
	   Gx36 has max 3 PCIe MACs per TRIO shim. */
	char *mmio_base_pio_cfg[TILEGX_TRIO_PCIES];

#ifdef USE_SHARED_PCIE_CONFIG_REGION
	/* Index of the shared PIO region for PCI config access. */
	int pio_cfg_index;
#else
	/* Index of the PIO region for PCI config access per MAC. */
	int pio_cfg_index[TILEGX_TRIO_PCIES];
#endif

	/*  The VA at which the push DMA MMIO registers are mapped. */
	char *mmio_push_dma[TRIO_NUM_PUSH_DMA_RINGS];

	/*  The VA at which the pull DMA MMIO registers are mapped. */
	char *mmio_pull_dma[TRIO_NUM_PUSH_DMA_RINGS];

	/* Application space ID. */
	unsigned int asid;

} gxio_trio_context_t;

/* Command descriptor for push or pull DMA. */
typedef TRIO_DMA_DESC_t gxio_trio_dma_desc_t;

/* A convenient, thread-safe interface to an eDMA ring. */
typedef struct {

	/* State object for tracking head and tail pointers. */
	__gxio_dma_queue_t dma_queue;

	/* The ring entries. */
	gxio_trio_dma_desc_t *dma_descs;

	/* The number of entries minus one. */
	unsigned long mask_num_entries;

	/* The log2() of the number of entries. */
	unsigned int log2_num_entries;

} gxio_trio_dma_queue_t;

/* Initialize a TRIO context.
 *
 * This function allocates a TRIO "service domain" and maps the MMIO
 * registers into the the caller's VA space.
 *
 * @param trio_index Which TRIO shim; Gx36 must pass 0.
 * @param context Context object to be initialized.
 */
extern int gxio_trio_init(gxio_trio_context_t *context,
			  unsigned int trio_index);

/* This indicates that an ASID hasn't been allocated. */
#define GXIO_ASID_NULL -1

/* Ordering modes for map memory regions and scatter queue regions. */
typedef enum gxio_trio_order_mode_e {
	/* Writes are not ordered.  Reads always wait for previous writes. */
	GXIO_TRIO_ORDER_MODE_UNORDERED =
		TRIO_MAP_MEM_SETUP__ORDER_MODE_VAL_UNORDERED,
	/* Both writes and reads wait for previous transactions to complete. */
	GXIO_TRIO_ORDER_MODE_STRICT =
		TRIO_MAP_MEM_SETUP__ORDER_MODE_VAL_STRICT,
	/* Writes are ordered unless the incoming packet has the
	   relaxed-ordering attributes set. */
	GXIO_TRIO_ORDER_MODE_OBEY_PACKET =
		TRIO_MAP_MEM_SETUP__ORDER_MODE_VAL_REL_ORD
} gxio_trio_order_mode_t;

/* Initialize a memory mapping region.
 *
 * @param context An initialized TRIO context.
 * @param map A Memory map region allocated by gxio_trio_alloc_memory_map().
 * @param target_mem VA of backing memory, should be registered via
 *   gxio_trio_register_page() and aligned to 4kB.
 * @param target_size Length of the memory mapping, must be a multiple
 * of 4kB.
 * @param asid ASID to be used for Tile-side address translation.
 * @param mac MAC number.
 * @param bus_address Bus address at which the mapping starts.
 * @param order_mode Memory ordering mode for this mapping.
 * @return Zero on success, else ::GXIO_TRIO_ERR_BAD_MEMORY_MAP,
 * GXIO_TRIO_ERR_BAD_ASID, or ::GXIO_TRIO_ERR_BAD_BUS_RANGE.
 */
extern int gxio_trio_init_memory_map(gxio_trio_context_t *context,
				     unsigned int map, void *target_mem,
				     size_t target_size, unsigned int asid,
				     unsigned int mac, uint64_t bus_address,
				     gxio_trio_order_mode_t order_mode);

/* Flags that can be passed to resource allocation functions. */
enum gxio_trio_alloc_flags_e {
	GXIO_TRIO_ALLOC_FIXED = HV_TRIO_ALLOC_FIXED,
};

/* Flags that can be passed to memory registration functions. */
enum gxio_trio_mem_flags_e {
	/* Do not fill L3 when writing, and invalidate lines upon egress. */
	GXIO_TRIO_MEM_FLAG_NT_HINT = IORPC_MEM_BUFFER_FLAG_NT_HINT,

	/* L3 cache fills should only populate IO cache ways. */
	GXIO_TRIO_MEM_FLAG_IO_PIN = IORPC_MEM_BUFFER_FLAG_IO_PIN,
};

/* Flag indicating a request generator uses a special traffic
    class. */
#define GXIO_TRIO_FLAG_TRAFFIC_CLASS(N) HV_TRIO_FLAG_TC(N)

/* Flag indicating a request generator uses a virtual function
    number. */
#define GXIO_TRIO_FLAG_VFUNC(N) HV_TRIO_FLAG_VFUNC(N)

/*****************************************************************
 *                       Memory Registration                      *
 ******************************************************************/

/* Allocate Application Space Identifiers (ASIDs).  Each ASID can
 * register up to 16 page translations.  ASIDs are used by memory map
 * regions, scatter queues, and DMA queues to translate application
 * VAs into memory system PAs.
 *
 * @param context An initialized TRIO context.
 * @param count Number of ASIDs required.
 * @param first Index of first ASID if ::GXIO_TRIO_ALLOC_FIXED flag
 *   is set, otherwise ignored.
 * @param flags Flag bits, including bits from ::gxio_trio_alloc_flags_e.
 * @return Index of first ASID, or ::GXIO_TRIO_ERR_NO_ASID if allocation
 *   failed.
 */
extern int gxio_trio_alloc_asids(gxio_trio_context_t *context,
				 unsigned int count, unsigned int first,
				 unsigned int flags);

#endif /* ! _GXIO_TRIO_H_ */