Blame samples/hello_fpga/hello_fpga.c

Packit 534379
// Copyright(c) 2017-2020, Intel Corporation
Packit 534379
//
Packit 534379
// Redistribution  and  use  in source  and  binary  forms,  with  or  without
Packit 534379
// modification, are permitted provided that the following conditions are met:
Packit 534379
//
Packit 534379
// * Redistributions of  source code  must retain the  above copyright notice,
Packit 534379
//   this list of conditions and the following disclaimer.
Packit 534379
// * Redistributions in binary form must reproduce the above copyright notice,
Packit 534379
//   this list of conditions and the following disclaimer in the documentation
Packit 534379
//   and/or other materials provided with the distribution.
Packit 534379
// * Neither the name  of Intel Corporation  nor the names of its contributors
Packit 534379
//   may be used to  endorse or promote  products derived  from this  software
Packit 534379
//   without specific prior written permission.
Packit 534379
//
Packit 534379
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
Packit 534379
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,  BUT NOT LIMITED TO,  THE
Packit 534379
// IMPLIED WARRANTIES OF  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Packit 534379
// ARE DISCLAIMED.  IN NO EVENT  SHALL THE COPYRIGHT OWNER  OR CONTRIBUTORS BE
Packit 534379
// LIABLE  FOR  ANY  DIRECT,  INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR
Packit 534379
// CONSEQUENTIAL  DAMAGES  (INCLUDING,  BUT  NOT LIMITED  TO,  PROCUREMENT  OF
Packit 534379
// SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE,  DATA, OR PROFITS;  OR BUSINESS
Packit 534379
// INTERRUPTION)  HOWEVER CAUSED  AND ON ANY THEORY  OF LIABILITY,  WHETHER IN
Packit 534379
// CONTRACT,  STRICT LIABILITY,  OR TORT  (INCLUDING NEGLIGENCE  OR OTHERWISE)
Packit 534379
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  EVEN IF ADVISED OF THE
Packit 534379
// POSSIBILITY OF SUCH DAMAGE.
Packit 534379
Packit 534379
/**
Packit 534379
 * @file hello_fpga.c
Packit 534379
 * @brief A code sample illustrates the basic usage of the OPAE C API.
Packit 534379
 *
Packit 534379
 * The sample is a host application that demonstrates the basic steps of
Packit 534379
 * interacting with FPGA using the OPAE library. These steps include:
Packit 534379
 *
Packit 534379
 *  - FPGA enumeration
Packit 534379
 *  - Resource acquiring and releasing
Packit 534379
 *  - Managing shared memory buffer
Packit 534379
 *  - MMIO read and write
Packit 534379
 *
Packit 534379
 * The sample also demonstrates OPAE's object model, such as tokens, handles,
Packit 534379
 * and properties.
Packit 534379
 *
Packit 534379
 * The sample requires a native loopback mode (NLB) test image to be loaded on
Packit 534379
 * the FPGA. Refer to
Packit 534379
 * Quick
Packit 534379
 * Start Guide for full instructions on building, configuring, and running
Packit 534379
 * this code sample.
Packit 534379
 *
Packit 534379
 */
Packit 534379
Packit 534379
#ifdef HAVE_CONFIG_H
Packit 534379
#include <config.h>
Packit 534379
#endif // HAVE_CONFIG_H
Packit 534379
#include <stdio.h>
Packit 534379
#include <stdlib.h>
Packit 534379
#include <string.h>
Packit 534379
#include <stdint.h>
Packit 534379
#include <getopt.h>
Packit 534379
#include <unistd.h>
Packit 534379
Packit 534379
#include <uuid/uuid.h>
Packit 534379
#include <opae/fpga.h>
Packit 534379
Packit 534379
int usleep(unsigned);
Packit 534379
Packit 534379
#ifndef TEST_TIMEOUT
Packit 534379
#define TEST_TIMEOUT 30000
Packit 534379
#endif // TEST_TIMEOUT
Packit 534379
Packit 534379
#ifndef CL
Packit 534379
# define CL(x)                       ((x) * 64)
Packit 534379
#endif // CL
Packit 534379
#ifndef LOG2_CL
Packit 534379
# define LOG2_CL                     6
Packit 534379
#endif // LOG2_CL
Packit 534379
#ifndef MB
Packit 534379
# define MB(x)                       ((x) * 1024 * 1024)
Packit 534379
#endif // MB
Packit 534379
Packit 534379
#define CACHELINE_ALIGNED_ADDR(p) ((p) >> LOG2_CL)
Packit 534379
Packit 534379
#define LPBK1_BUFFER_SIZE            MB(1)
Packit 534379
#define LPBK1_BUFFER_ALLOCATION_SIZE MB(2)
Packit 534379
#define LPBK1_DSM_SIZE               MB(2)
Packit 534379
#define CSR_SRC_ADDR                 0x0120
Packit 534379
#define CSR_DST_ADDR                 0x0128
Packit 534379
#define CSR_CTL                      0x0138
Packit 534379
#define CSR_STATUS1                  0x0168
Packit 534379
#define CSR_CFG                      0x0140
Packit 534379
#define CSR_NUM_LINES                0x0130
Packit 534379
#define DSM_STATUS_TEST_COMPLETE     0x40
Packit 534379
#define CSR_AFU_DSM_BASEL            0x0110
Packit 534379
Packit 534379
/* NLB0 AFU_ID */
Packit 534379
#define NLB0_AFUID "D8424DC4-A4A3-C413-F89E-433683F9040B"
Packit 534379
Packit 534379
Packit 534379
/*
Packit 534379
 * macro to check return codes, print error message, and goto cleanup label
Packit 534379
 * NOTE: this changes the program flow (uses goto)!
Packit 534379
 */
Packit 534379
#define ON_ERR_GOTO(res, label, desc)              \
Packit 534379
	do {                                       \
Packit 534379
		if ((res) != FPGA_OK) {            \
Packit 534379
			print_err((desc), (res));  \
Packit 534379
			goto label;                \
Packit 534379
		}                                  \
Packit 534379
	} while (0)
Packit 534379
Packit 534379
/* Type definitions */
Packit 534379
typedef struct {
Packit 534379
	uint32_t uint[16];
Packit 534379
} cache_line;
Packit 534379
Packit 534379
void print_err(const char *s, fpga_result res)
Packit 534379
{
Packit 534379
	fprintf(stderr, "Error %s: %s\n", s, fpgaErrStr(res));
Packit 534379
}
Packit 534379
Packit 534379
/*
Packit 534379
 * Global configuration of bus, set during parse_args()
Packit 534379
 * */
Packit 534379
struct config {
Packit 534379
	struct target {
Packit 534379
		int bus;
Packit 534379
	} target;
Packit 534379
	int open_flags;
Packit 534379
}
Packit 534379
Packit 534379
config = {
Packit 534379
	.target = {
Packit 534379
		.bus = -1,
Packit 534379
	},
Packit 534379
	.open_flags = 0
Packit 534379
};
Packit 534379
Packit 534379
#define GETOPT_STRING "B:sv"
Packit 534379
fpga_result parse_args(int argc, char *argv[])
Packit 534379
{
Packit 534379
	struct option longopts[] = {
Packit 534379
		{ "bus",     required_argument, NULL, 'B' },
Packit 534379
		{ "shared",  no_argument,       NULL, 's' },
Packit 534379
		{ "version", no_argument,       NULL, 'v' },
Packit 534379
		{ NULL,      0,                 NULL,  0  }
Packit 534379
	};
Packit 534379
Packit 534379
	int getopt_ret;
Packit 534379
	int option_index;
Packit 534379
	char *endptr = NULL;
Packit 534379
	char version[32];
Packit 534379
	char build[32];
Packit 534379
Packit 534379
	while (-1 != (getopt_ret = getopt_long(argc, argv, GETOPT_STRING,
Packit 534379
						longopts, &option_index))) {
Packit 534379
		const char *tmp_optarg = optarg;
Packit 534379
		/* Checks to see if optarg is null and if not it goes to value of optarg */
Packit 534379
		if ((optarg) && ('=' == *tmp_optarg)) {
Packit 534379
			++tmp_optarg;
Packit 534379
		}
Packit 534379
Packit 534379
		switch (getopt_ret) {
Packit 534379
		case 'B': /* bus */
Packit 534379
			if (NULL == tmp_optarg) {
Packit 534379
				return FPGA_EXCEPTION;
Packit 534379
			}
Packit 534379
			endptr = NULL;
Packit 534379
			config.target.bus = (int) strtoul(tmp_optarg, &endptr, 0);
Packit 534379
			if (endptr != tmp_optarg + strnlen(tmp_optarg, 100)) {
Packit 534379
				fprintf(stderr, "invalid bus: %s\n", tmp_optarg);
Packit 534379
				return FPGA_EXCEPTION;
Packit 534379
			}
Packit 534379
			break;
Packit 534379
		case 's':
Packit 534379
			config.open_flags |= FPGA_OPEN_SHARED;
Packit 534379
			break;
Packit 534379
Packit 534379
		case 'v':
Packit 534379
			fpgaGetOPAECVersionString(version, sizeof(version));
Packit 534379
			fpgaGetOPAECBuildString(build, sizeof(build));
Packit 534379
			printf("hello_fpga %s %s\n",
Packit 534379
			       version, build);
Packit 534379
			return -1;
Packit 534379
Packit 534379
		default: /* invalid option */
Packit 534379
			fprintf(stderr, "Invalid cmdline option \n");
Packit 534379
			return FPGA_EXCEPTION;
Packit 534379
		}
Packit 534379
	}
Packit 534379
Packit 534379
	return FPGA_OK;
Packit 534379
}
Packit 534379
Packit 534379
fpga_result find_fpga(fpga_guid afu_guid,
Packit 534379
		      fpga_token *accelerator_token,
Packit 534379
		      uint32_t *num_matches_accelerators)
Packit 534379
{
Packit 534379
	fpga_properties filter = NULL;
Packit 534379
	fpga_result res1;
Packit 534379
	fpga_result res2 = FPGA_OK;
Packit 534379
Packit 534379
	res1 = fpgaGetProperties(NULL, &filter);
Packit 534379
	ON_ERR_GOTO(res1, out, "creating properties object");
Packit 534379
Packit 534379
	res1 = fpgaPropertiesSetObjectType(filter, FPGA_ACCELERATOR);
Packit 534379
	ON_ERR_GOTO(res1, out_destroy, "setting object type");
Packit 534379
Packit 534379
	res1 = fpgaPropertiesSetGUID(filter, afu_guid);
Packit 534379
	ON_ERR_GOTO(res1, out_destroy, "setting GUID");
Packit 534379
Packit 534379
	if (-1 != config.target.bus) {
Packit 534379
		res1 = fpgaPropertiesSetBus(filter, config.target.bus);
Packit 534379
		ON_ERR_GOTO(res1, out_destroy, "setting bus");
Packit 534379
	}
Packit 534379
Packit 534379
	res1 = fpgaEnumerate(&filter, 1, accelerator_token, 1, num_matches_accelerators);
Packit 534379
	ON_ERR_GOTO(res1, out_destroy, "enumerating accelerators");
Packit 534379
Packit 534379
out_destroy:
Packit 534379
	res2 = fpgaDestroyProperties(&filter);
Packit 534379
	ON_ERR_GOTO(res2, out, "destroying properties object");
Packit 534379
out:
Packit 534379
	return res1 != FPGA_OK ? res1 : res2;
Packit 534379
}
Packit 534379
Packit 534379
/* function to get the bus number when there are multiple accelerators */
Packit 534379
fpga_result get_bus(fpga_token tok, uint8_t *bus)
Packit 534379
{
Packit 534379
	fpga_result res1;
Packit 534379
	fpga_result res2 = FPGA_OK;
Packit 534379
	fpga_properties props = NULL;
Packit 534379
Packit 534379
	res1 = fpgaGetProperties(tok, &props;;
Packit 534379
	ON_ERR_GOTO(res1, out, "reading properties from Token");
Packit 534379
Packit 534379
	res1 = fpgaPropertiesGetBus(props, bus);
Packit 534379
	ON_ERR_GOTO(res1, out_destroy, "Reading bus from properties");
Packit 534379
Packit 534379
out_destroy:
Packit 534379
	res2 = fpgaDestroyProperties(&props;;
Packit 534379
	ON_ERR_GOTO(res2, out, "fpgaDestroyProps");
Packit 534379
out:
Packit 534379
	return res1 != FPGA_OK ? res1 : res2;
Packit 534379
}
Packit 534379
Packit 534379
/* Is the FPGA simulated with ASE? */
Packit 534379
bool probe_for_ase(void)
Packit 534379
{
Packit 534379
	fpga_result r = FPGA_OK;
Packit 534379
	uint16_t device_id = 0;
Packit 534379
	fpga_properties filter = NULL;
Packit 534379
	uint32_t num_matches = 1;
Packit 534379
	fpga_token fme_token;
Packit 534379
Packit 534379
	/* Connect to the FPGA management engine */
Packit 534379
	fpgaGetProperties(NULL, &filter);
Packit 534379
	fpgaPropertiesSetObjectType(filter, FPGA_DEVICE);
Packit 534379
Packit 534379
	/* Connecting to one is sufficient to find ASE */
Packit 534379
	fpgaEnumerate(&filter, 1, &fme_token, 1, &num_matches);
Packit 534379
	if (0 != num_matches) {
Packit 534379
		/* Retrieve the device ID of the FME */
Packit 534379
		fpgaDestroyProperties(&filter);
Packit 534379
		fpgaGetProperties(fme_token, &filter);
Packit 534379
		r = fpgaPropertiesGetDeviceID(filter, &device_id);
Packit 534379
		fpgaDestroyToken(&fme_token);
Packit 534379
	}
Packit 534379
	fpgaDestroyProperties(&filter);
Packit 534379
Packit 534379
	/* ASE's device ID is 0xa5e */
Packit 534379
	return ((FPGA_OK == r) && (0xa5e == device_id));
Packit 534379
}
Packit 534379
Packit 534379
int main(int argc, char *argv[])
Packit 534379
{
Packit 534379
	fpga_token         accelerator_token;
Packit 534379
	fpga_handle        accelerator_handle;
Packit 534379
	fpga_guid          guid;
Packit 534379
	uint32_t           num_matches_accelerators = 0;
Packit 534379
	uint32_t           use_ase;
Packit 534379
Packit 534379
	volatile uint64_t *dsm_ptr    = NULL;
Packit 534379
	volatile uint64_t *status_ptr = NULL;
Packit 534379
	volatile uint64_t *input_ptr  = NULL;
Packit 534379
	volatile uint64_t *output_ptr = NULL;
Packit 534379
Packit 534379
	uint64_t           dsm_wsid;
Packit 534379
	uint64_t           input_wsid;
Packit 534379
	uint64_t           output_wsid;
Packit 534379
	uint8_t            bus = 0xff;
Packit 534379
	uint32_t           i;
Packit 534379
	uint32_t           timeout;
Packit 534379
	fpga_result        res1 = FPGA_OK;
Packit 534379
	fpga_result        res2 = FPGA_OK;
Packit 534379
Packit 534379
	res1 = parse_args(argc, argv);
Packit 534379
	if ((int)res1 < 0)
Packit 534379
		goto out_exit;
Packit 534379
	ON_ERR_GOTO(res1, out_exit, "parsing arguments");
Packit 534379
Packit 534379
	if (uuid_parse(NLB0_AFUID, guid) < 0) {
Packit 534379
		res1 = FPGA_EXCEPTION;
Packit 534379
	}
Packit 534379
	ON_ERR_GOTO(res1, out_exit, "parsing guid");
Packit 534379
Packit 534379
	use_ase = probe_for_ase();
Packit 534379
	if (use_ase) {
Packit 534379
		printf("Running in ASE mode\n");
Packit 534379
	}
Packit 534379
Packit 534379
	/* Look for accelerator with NLB0_AFUID */
Packit 534379
	res1 = find_fpga(guid, &accelerator_token, &num_matches_accelerators);
Packit 534379
	ON_ERR_GOTO(res1, out_exit, "finding FPGA accelerator");
Packit 534379
Packit 534379
	if (num_matches_accelerators <= 0) {
Packit 534379
		res1 = FPGA_NOT_FOUND;
Packit 534379
	}
Packit 534379
	ON_ERR_GOTO(res1, out_exit, "no matching accelerator");
Packit 534379
Packit 534379
	if (num_matches_accelerators > 1) {
Packit 534379
		printf("Found more than one suitable accelerator. ");
Packit 534379
		res1 = get_bus(accelerator_token, &bus;;
Packit 534379
		ON_ERR_GOTO(res1, out_exit, "getting bus num");
Packit 534379
		printf("Running on bus 0x%02x.\n", bus);
Packit 534379
	}
Packit 534379
Packit 534379
Packit 534379
	/* Open accelerator and map MMIO */
Packit 534379
	res1 = fpgaOpen(accelerator_token, &accelerator_handle, config.open_flags);
Packit 534379
	ON_ERR_GOTO(res1, out_destroy_tok, "opening accelerator");
Packit 534379
Packit 534379
	res1 = fpgaMapMMIO(accelerator_handle, 0, NULL);
Packit 534379
	ON_ERR_GOTO(res1, out_close, "mapping MMIO space");
Packit 534379
Packit 534379
Packit 534379
	/* Allocate buffers */
Packit 534379
	res1 = fpgaPrepareBuffer(accelerator_handle, LPBK1_DSM_SIZE,
Packit 534379
				(void **)&dsm_ptr, &dsm_wsid, 0);
Packit 534379
	ON_ERR_GOTO(res1, out_close, "allocating DSM buffer");
Packit 534379
Packit 534379
	res1 = fpgaPrepareBuffer(accelerator_handle, LPBK1_BUFFER_ALLOCATION_SIZE,
Packit 534379
			   (void **)&input_ptr, &input_wsid, 0);
Packit 534379
	ON_ERR_GOTO(res1, out_free_dsm, "allocating input buffer");
Packit 534379
Packit 534379
	res1 = fpgaPrepareBuffer(accelerator_handle, LPBK1_BUFFER_ALLOCATION_SIZE,
Packit 534379
			   (void **)&output_ptr, &output_wsid, 0);
Packit 534379
	ON_ERR_GOTO(res1, out_free_input, "allocating output buffer");
Packit 534379
Packit 534379
	printf("Running Test\n");
Packit 534379
Packit 534379
	bus = 0xff;
Packit 534379
	res1 = get_bus(accelerator_token, &bus;;
Packit 534379
	ON_ERR_GOTO(res1, out_free_output, "getting bus num");
Packit 534379
	printf("Running on bus 0x%02x.\n", bus);
Packit 534379
Packit 534379
Packit 534379
	/* Initialize buffers */
Packit 534379
	memset((void *)dsm_ptr,    0,    LPBK1_DSM_SIZE);
Packit 534379
	memset((void *)input_ptr,  0xAF, LPBK1_BUFFER_SIZE);
Packit 534379
	memset((void *)output_ptr, 0xBE, LPBK1_BUFFER_SIZE);
Packit 534379
Packit 534379
	cache_line *cl_ptr = (cache_line *)input_ptr;
Packit 534379
	for (i = 0; i < LPBK1_BUFFER_SIZE / CL(1); ++i) {
Packit 534379
		cl_ptr[i].uint[15] = i+1; /* set the last uint in every cacheline */
Packit 534379
	}
Packit 534379
Packit 534379
Packit 534379
	/* Reset accelerator */
Packit 534379
	res1 = fpgaReset(accelerator_handle);
Packit 534379
	ON_ERR_GOTO(res1, out_free_output, "resetting accelerator");
Packit 534379
Packit 534379
Packit 534379
	/* Program DMA addresses */
Packit 534379
	uint64_t iova = 0;
Packit 534379
	res1 = fpgaGetIOAddress(accelerator_handle, dsm_wsid, &iova);
Packit 534379
	ON_ERR_GOTO(res1, out_free_output, "getting DSM IOVA");
Packit 534379
Packit 534379
	res1 = fpgaWriteMMIO64(accelerator_handle, 0, CSR_AFU_DSM_BASEL, iova);
Packit 534379
	ON_ERR_GOTO(res1, out_free_output, "writing CSR_AFU_DSM_BASEL");
Packit 534379
Packit 534379
	res1 = fpgaWriteMMIO32(accelerator_handle, 0, CSR_CTL, 0);
Packit 534379
	ON_ERR_GOTO(res1, out_free_output, "writing CSR_CFG");
Packit 534379
	res1 = fpgaWriteMMIO32(accelerator_handle, 0, CSR_CTL, 1);
Packit 534379
	ON_ERR_GOTO(res1, out_free_output, "writing CSR_CFG");
Packit 534379
Packit 534379
	res1 = fpgaGetIOAddress(accelerator_handle, input_wsid, &iova);
Packit 534379
	ON_ERR_GOTO(res1, out_free_output, "getting input IOVA");
Packit 534379
	res1 = fpgaWriteMMIO64(accelerator_handle, 0, CSR_SRC_ADDR, CACHELINE_ALIGNED_ADDR(iova));
Packit 534379
	ON_ERR_GOTO(res1, out_free_output, "writing CSR_SRC_ADDR");
Packit 534379
Packit 534379
	res1 = fpgaGetIOAddress(accelerator_handle, output_wsid, &iova);
Packit 534379
	ON_ERR_GOTO(res1, out_free_output, "getting output IOVA");
Packit 534379
	res1 = fpgaWriteMMIO64(accelerator_handle, 0, CSR_DST_ADDR, CACHELINE_ALIGNED_ADDR(iova));
Packit 534379
	ON_ERR_GOTO(res1, out_free_output, "writing CSR_DST_ADDR");
Packit 534379
Packit 534379
	res1 = fpgaWriteMMIO32(accelerator_handle, 0, CSR_NUM_LINES, LPBK1_BUFFER_SIZE / CL(1));
Packit 534379
	ON_ERR_GOTO(res1, out_free_output, "writing CSR_NUM_LINES");
Packit 534379
	res1 = fpgaWriteMMIO32(accelerator_handle, 0, CSR_CFG, 0x42000);
Packit 534379
	ON_ERR_GOTO(res1, out_free_output, "writing CSR_CFG");
Packit 534379
Packit 534379
	status_ptr = dsm_ptr + DSM_STATUS_TEST_COMPLETE/sizeof(uint64_t);
Packit 534379
Packit 534379
Packit 534379
	/* Start the test */
Packit 534379
	res1 = fpgaWriteMMIO32(accelerator_handle, 0, CSR_CTL, 3);
Packit 534379
	ON_ERR_GOTO(res1, out_free_output, "writing CSR_CFG");
Packit 534379
Packit 534379
	/* Wait for test completion */
Packit 534379
	timeout = TEST_TIMEOUT;
Packit 534379
	while (0 == ((*status_ptr) & 0x1)) {
Packit 534379
		usleep(100);
Packit 534379
		if (!use_ase && (--timeout == 0)) {
Packit 534379
			res1 = FPGA_EXCEPTION;
Packit 534379
			ON_ERR_GOTO(res1, out_free_output, "test timed out");
Packit 534379
		}
Packit 534379
	}
Packit 534379
Packit 534379
	/* Stop the device */
Packit 534379
	res1 = fpgaWriteMMIO32(accelerator_handle, 0, CSR_CTL, 7);
Packit 534379
	ON_ERR_GOTO(res1, out_free_output, "writing CSR_CFG");
Packit 534379
Packit 534379
	/* Wait for the AFU's read/write traffic to complete */
Packit 534379
	uint32_t afu_traffic_trips = 0;
Packit 534379
	while (afu_traffic_trips < 100) {
Packit 534379
		/*
Packit 534379
		 * CSR_STATUS1 holds two 32 bit values: num pending reads and writes.
Packit 534379
		 * Wait for it to be 0.
Packit 534379
		 */
Packit 534379
		uint64_t s1;
Packit 534379
		res1 = fpgaReadMMIO64(accelerator_handle, 0, CSR_STATUS1, &s1;;
Packit 534379
		ON_ERR_GOTO(res1, out_free_output, "reading CSR_STATUS1");
Packit 534379
		if (s1 == 0) {
Packit 534379
			break;
Packit 534379
		}
Packit 534379
Packit 534379
		afu_traffic_trips += 1;
Packit 534379
		usleep(1000);
Packit 534379
	}
Packit 534379
Packit 534379
	/* Check output buffer contents */
Packit 534379
	for (i = 0; i < LPBK1_BUFFER_SIZE; i++) {
Packit 534379
		if (((uint8_t *)output_ptr)[i] != ((uint8_t *)input_ptr)[i]) {
Packit 534379
			fprintf(stderr, "Output does NOT match input "
Packit 534379
				"at offset %i!\n", i);
Packit 534379
			break;
Packit 534379
		}
Packit 534379
	}
Packit 534379
Packit 534379
	printf("Done Running Test\n");
Packit 534379
Packit 534379
Packit 534379
	/* Release buffers */
Packit 534379
out_free_output:
Packit 534379
	res2 = fpgaReleaseBuffer(accelerator_handle, output_wsid);
Packit 534379
	ON_ERR_GOTO(res2, out_free_input, "releasing output buffer");
Packit 534379
out_free_input:
Packit 534379
	res2 = fpgaReleaseBuffer(accelerator_handle, input_wsid);
Packit 534379
	ON_ERR_GOTO(res2, out_free_dsm, "releasing input buffer");
Packit 534379
out_free_dsm:
Packit 534379
	res2 = fpgaReleaseBuffer(accelerator_handle, dsm_wsid);
Packit 534379
	ON_ERR_GOTO(res2, out_unmap, "releasing DSM buffer");
Packit 534379
Packit 534379
	/* Unmap MMIO space */
Packit 534379
out_unmap:
Packit 534379
	res2 = fpgaUnmapMMIO(accelerator_handle, 0);
Packit 534379
	ON_ERR_GOTO(res2, out_close, "unmapping MMIO space");
Packit 534379
Packit 534379
	/* Release accelerator */
Packit 534379
out_close:
Packit 534379
	res2 = fpgaClose(accelerator_handle);
Packit 534379
	ON_ERR_GOTO(res2, out_destroy_tok, "closing accelerator");
Packit 534379
Packit 534379
	/* Destroy token */
Packit 534379
out_destroy_tok:
Packit 534379
	res2 = fpgaDestroyToken(&accelerator_token);
Packit 534379
	ON_ERR_GOTO(res2, out_exit, "destroying token");
Packit 534379
Packit 534379
out_exit:
Packit 534379
	return res1 != FPGA_OK ? res1 : res2;
Packit 534379
}