| 
									
										
										
										
											2012-04-07 16:53:03 -04:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * 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>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-02 18:01:25 +01:00
										 |  |  | #include <gxio/common.h>
 | 
					
						
							|  |  |  | #include <gxio/dma_queue.h>
 | 
					
						
							| 
									
										
										
										
											2012-04-07 16:53:03 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | #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_ */
 |