get device caps from CSRs
This commit is contained in:
@@ -1,17 +1,24 @@
|
||||
#include <stdint.h>
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <cstdlib>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
#include <cmath>
|
||||
#include <uuid/uuid.h>
|
||||
#include <opae/fpga.h>
|
||||
#include <vortex.h>
|
||||
#include <VX_config.h>
|
||||
#include "vortex_afu.h"
|
||||
#ifdef SCOPE
|
||||
#include "scope.h"
|
||||
#endif
|
||||
|
||||
#define CACHE_LINESIZE 64
|
||||
#define ALLOC_BASE_ADDR 0x10000000
|
||||
#define LOCAL_MEM_SIZE 0xffffffff
|
||||
|
||||
#define CHECK_RES(_expr) \
|
||||
do { \
|
||||
fpga_result res = _expr; \
|
||||
@@ -24,22 +31,31 @@
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define CMD_TYPE_READ AFU_IMAGE_CMD_TYPE_READ
|
||||
#define CMD_TYPE_WRITE AFU_IMAGE_CMD_TYPE_WRITE
|
||||
#define CMD_TYPE_RUN AFU_IMAGE_CMD_TYPE_RUN
|
||||
#define CMD_TYPE_CLFLUSH AFU_IMAGE_CMD_TYPE_CLFLUSH
|
||||
#define CMD_MEM_READ AFU_IMAGE_CMD_MEM_READ
|
||||
#define CMD_MEM_WRITE AFU_IMAGE_CMD_MEM_WRITE
|
||||
#define CMD_RUN AFU_IMAGE_CMD_RUN
|
||||
#define CMD_CLFLUSH AFU_IMAGE_CMD_CLFLUSH
|
||||
#define CMD_CSR_READ AFU_IMAGE_CMD_CSR_READ
|
||||
#define CMD_CSR_WRITE AFU_IMAGE_CMD_CSR_WRITE
|
||||
|
||||
#define MMIO_CSR_CMD (AFU_IMAGE_MMIO_CSR_CMD * 4)
|
||||
#define MMIO_CSR_IO_ADDR (AFU_IMAGE_MMIO_CSR_IO_ADDR * 4)
|
||||
#define MMIO_CSR_MEM_ADDR (AFU_IMAGE_MMIO_CSR_MEM_ADDR * 4)
|
||||
#define MMIO_CSR_DATA_SIZE (AFU_IMAGE_MMIO_CSR_DATA_SIZE * 4)
|
||||
#define MMIO_CSR_STATUS (AFU_IMAGE_MMIO_CSR_STATUS * 4)
|
||||
#define MMIO_CMD_TYPE (AFU_IMAGE_MMIO_CMD_TYPE * 4)
|
||||
#define MMIO_IO_ADDR (AFU_IMAGE_MMIO_IO_ADDR * 4)
|
||||
#define MMIO_MEM_ADDR (AFU_IMAGE_MMIO_MEM_ADDR * 4)
|
||||
#define MMIO_DATA_SIZE (AFU_IMAGE_MMIO_DATA_SIZE * 4)
|
||||
#define MMIO_STATUS (AFU_IMAGE_MMIO_STATUS * 4)
|
||||
#define MMIO_CSR_ADDR (AFU_IMAGE_MMIO_CSR_ADDR * 4)
|
||||
#define MMIO_CSR_DATA (AFU_IMAGE_MMIO_CSR_DATA * 4)
|
||||
#define MMIO_CSR_READ (AFU_IMAGE_MMIO_CSR_READ * 4)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct vx_device_ {
|
||||
fpga_handle fpga;
|
||||
size_t mem_allocation;
|
||||
int implementation_id;
|
||||
int num_cores;
|
||||
int num_warps;
|
||||
int num_threads;
|
||||
} vx_device_t;
|
||||
|
||||
typedef struct vx_buffer_ {
|
||||
@@ -62,21 +78,58 @@ inline bool is_aligned(size_t addr, size_t alignment) {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern int vx_dev_caps(vx_device_h hdevice, unsigned caps_id, unsigned *value) {
|
||||
if (nullptr == hdevice)
|
||||
return -1;
|
||||
|
||||
vx_device_t *device = ((vx_device_t*)hdevice);
|
||||
|
||||
switch (caps_id) {
|
||||
case VX_CAPS_VERSION:
|
||||
*value = device->implementation_id;
|
||||
break;
|
||||
case VX_CAPS_MAX_CORES:
|
||||
*value = device->num_cores;
|
||||
break;
|
||||
case VX_CAPS_MAX_WARPS:
|
||||
*value = device->num_warps;
|
||||
break;
|
||||
case VX_CAPS_MAX_THREADS:
|
||||
*value = device->num_threads;
|
||||
break;
|
||||
case VX_CAPS_CACHE_LINESIZE:
|
||||
*value = CACHE_LINESIZE;
|
||||
break;
|
||||
case VX_CAPS_LOCAL_MEM_SIZE:
|
||||
*value = LOCAL_MEM_SIZE;
|
||||
break;
|
||||
case VX_CAPS_ALLOC_BASE_ADDR:
|
||||
*value = ALLOC_BASE_ADDR;
|
||||
break;
|
||||
case VX_CAPS_KERNEL_BASE_ADDR:
|
||||
*value = STARTUP_ADDR;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "invalid caps id: %d\n", caps_id);
|
||||
std::abort();
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern int vx_dev_open(vx_device_h* hdevice) {
|
||||
if (nullptr == hdevice)
|
||||
return -1;
|
||||
|
||||
fpga_properties filter = nullptr;
|
||||
fpga_result res;
|
||||
fpga_guid guid;
|
||||
fpga_token accel_token;
|
||||
uint32_t num_matches;
|
||||
fpga_handle accel_handle;
|
||||
vx_device_t* device;
|
||||
|
||||
if (nullptr == hdevice)
|
||||
return -1;
|
||||
|
||||
// ensure that the block size 64
|
||||
assert(64 == vx_dev_caps(VX_CAPS_CACHE_LINESIZE));
|
||||
|
||||
vx_device_t* device;
|
||||
|
||||
// Set up a filter that will search for an accelerator
|
||||
fpgaGetProperties(nullptr, &filter);
|
||||
fpgaPropertiesSetObjectType(filter, FPGA_ACCELERATOR);
|
||||
@@ -114,17 +167,32 @@ extern int vx_dev_open(vx_device_h* hdevice) {
|
||||
}
|
||||
|
||||
device->fpga = accel_handle;
|
||||
device->mem_allocation = vx_dev_caps(VX_CAPS_ALLOC_BASE_ADDR);
|
||||
device->mem_allocation = ALLOC_BASE_ADDR;
|
||||
|
||||
*hdevice = device;
|
||||
{
|
||||
// Load device CAPS
|
||||
int ret = 0;
|
||||
ret |= vx_csr_get(device, CSR_IMPL_ID, &device->implementation_id);
|
||||
ret |= vx_csr_get(device, CSR_NC, &device->num_cores);
|
||||
ret |= vx_csr_get(device, CSR_NW, &device->num_warps);
|
||||
ret |= vx_csr_get(device, CSR_NT, &device->num_threads);
|
||||
if (ret != 0) {
|
||||
fpgaClose(accel_handle);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SCOPE
|
||||
{
|
||||
int ret = vx_scope_start(device->fpga, 0);
|
||||
if (ret != 0)
|
||||
int ret = vx_scope_start(accel_handle, 0);
|
||||
if (ret != 0) {
|
||||
fpgaClose(accel_handle);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
*hdevice = device;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -154,10 +222,8 @@ extern int vx_alloc_dev_mem(vx_device_h hdevice, size_t size, size_t* dev_maddr)
|
||||
|
||||
vx_device_t *device = ((vx_device_t*)hdevice);
|
||||
|
||||
int line_size = vx_dev_caps(VX_CAPS_CACHE_LINESIZE);
|
||||
size_t dev_mem_size = vx_dev_caps(VX_CAPS_LOCAL_MEM_SIZE);
|
||||
|
||||
size_t asize = align_size(size, line_size);
|
||||
size_t dev_mem_size = LOCAL_MEM_SIZE;
|
||||
size_t asize = align_size(size, CACHE_LINESIZE);
|
||||
|
||||
if (device->mem_allocation + asize > dev_mem_size)
|
||||
return -1;
|
||||
@@ -182,9 +248,7 @@ extern int vx_alloc_shared_mem(vx_device_h hdevice, size_t size, vx_buffer_h* hb
|
||||
|
||||
vx_device_t *device = ((vx_device_t*)hdevice);
|
||||
|
||||
int line_size = vx_dev_caps(VX_CAPS_CACHE_LINESIZE);
|
||||
|
||||
size_t asize = align_size(size, line_size);
|
||||
size_t asize = align_size(size, CACHE_LINESIZE);
|
||||
|
||||
res = fpgaPrepareBuffer(device->fpga, asize, &host_ptr, &wsid, 0);
|
||||
if (FPGA_OK != res) {
|
||||
@@ -260,7 +324,7 @@ extern int vx_ready_wait(vx_device_h hdevice, long long timeout) {
|
||||
long long sleep_time_ms = (sleep_time.tv_sec * 1000) + (sleep_time.tv_nsec / 1000000);
|
||||
|
||||
for (;;) {
|
||||
CHECK_RES(fpgaReadMMIO64(device->fpga, 0, MMIO_CSR_STATUS, &data));
|
||||
CHECK_RES(fpgaReadMMIO64(device->fpga, 0, MMIO_STATUS, &data));
|
||||
if (0 == data || 0 == timeout) {
|
||||
if (data != 0) {
|
||||
fprintf(stdout, "ready-wait timed out: status=%ld\n", data);
|
||||
@@ -282,17 +346,15 @@ extern int vx_copy_to_dev(vx_buffer_h hbuffer, size_t dev_maddr, size_t size, si
|
||||
vx_buffer_t *buffer = ((vx_buffer_t*)hbuffer);
|
||||
vx_device_t *device = ((vx_device_t*)buffer->hdevice);
|
||||
|
||||
int line_size = vx_dev_caps(VX_CAPS_CACHE_LINESIZE);
|
||||
size_t dev_mem_size = vx_dev_caps(VX_CAPS_LOCAL_MEM_SIZE);
|
||||
|
||||
size_t asize = align_size(size, line_size);
|
||||
size_t dev_mem_size = LOCAL_MEM_SIZE;
|
||||
size_t asize = align_size(size, CACHE_LINESIZE);
|
||||
|
||||
// check alignment
|
||||
if (!is_aligned(dev_maddr, line_size))
|
||||
if (!is_aligned(dev_maddr, CACHE_LINESIZE))
|
||||
return -1;
|
||||
if (!is_aligned(buffer->io_addr + src_offset, line_size))
|
||||
if (!is_aligned(buffer->io_addr + src_offset, CACHE_LINESIZE))
|
||||
return -1;
|
||||
|
||||
|
||||
// bound checking
|
||||
if (src_offset + asize > buffer->size)
|
||||
return -1;
|
||||
@@ -303,12 +365,12 @@ extern int vx_copy_to_dev(vx_buffer_h hbuffer, size_t dev_maddr, size_t size, si
|
||||
if (vx_ready_wait(buffer->hdevice, -1) != 0)
|
||||
return -1;
|
||||
|
||||
auto ls_shift = (int)std::log2(line_size);
|
||||
auto ls_shift = (int)std::log2(CACHE_LINESIZE);
|
||||
|
||||
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_CSR_IO_ADDR, (buffer->io_addr + src_offset) >> ls_shift));
|
||||
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_CSR_MEM_ADDR, dev_maddr >> ls_shift));
|
||||
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_CSR_DATA_SIZE, asize >> ls_shift));
|
||||
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_CSR_CMD, CMD_TYPE_WRITE));
|
||||
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_IO_ADDR, (buffer->io_addr + src_offset) >> ls_shift));
|
||||
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_MEM_ADDR, dev_maddr >> ls_shift));
|
||||
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_DATA_SIZE, asize >> ls_shift));
|
||||
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_CMD_TYPE, CMD_MEM_WRITE));
|
||||
|
||||
// Wait for the write operation to finish
|
||||
if (vx_ready_wait(buffer->hdevice, -1) != 0)
|
||||
@@ -325,15 +387,13 @@ extern int vx_copy_from_dev(vx_buffer_h hbuffer, size_t dev_maddr, size_t size,
|
||||
vx_buffer_t *buffer = ((vx_buffer_t*)hbuffer);
|
||||
vx_device_t *device = ((vx_device_t*)buffer->hdevice);
|
||||
|
||||
int line_size = vx_dev_caps(VX_CAPS_CACHE_LINESIZE);
|
||||
size_t dev_mem_size = vx_dev_caps(VX_CAPS_LOCAL_MEM_SIZE);
|
||||
|
||||
size_t asize = align_size(size, line_size);
|
||||
size_t dev_mem_size = LOCAL_MEM_SIZE;
|
||||
size_t asize = align_size(size, CACHE_LINESIZE);
|
||||
|
||||
// check alignment
|
||||
if (!is_aligned(dev_maddr, line_size))
|
||||
if (!is_aligned(dev_maddr, CACHE_LINESIZE))
|
||||
return -1;
|
||||
if (!is_aligned(buffer->io_addr + dest_offset, line_size))
|
||||
if (!is_aligned(buffer->io_addr + dest_offset, CACHE_LINESIZE))
|
||||
return -1;
|
||||
|
||||
// bound checking
|
||||
@@ -346,12 +406,12 @@ extern int vx_copy_from_dev(vx_buffer_h hbuffer, size_t dev_maddr, size_t size,
|
||||
if (vx_ready_wait(buffer->hdevice, -1) != 0)
|
||||
return -1;
|
||||
|
||||
auto ls_shift = (int)std::log2(line_size);
|
||||
auto ls_shift = (int)std::log2(CACHE_LINESIZE);
|
||||
|
||||
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_CSR_IO_ADDR, (buffer->io_addr + dest_offset) >> ls_shift));
|
||||
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_CSR_MEM_ADDR, dev_maddr >> ls_shift));
|
||||
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_CSR_DATA_SIZE, asize >> ls_shift));
|
||||
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_CSR_CMD, CMD_TYPE_READ));
|
||||
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_IO_ADDR, (buffer->io_addr + dest_offset) >> ls_shift));
|
||||
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_MEM_ADDR, dev_maddr >> ls_shift));
|
||||
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_DATA_SIZE, asize >> ls_shift));
|
||||
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_CMD_TYPE, CMD_MEM_READ));
|
||||
|
||||
// Wait for the write operation to finish
|
||||
if (vx_ready_wait(buffer->hdevice, -1) != 0)
|
||||
@@ -367,23 +427,21 @@ extern int vx_flush_caches(vx_device_h hdevice, size_t dev_maddr, size_t size) {
|
||||
|
||||
vx_device_t* device = ((vx_device_t*)hdevice);
|
||||
|
||||
int line_size = vx_dev_caps(VX_CAPS_CACHE_LINESIZE);
|
||||
|
||||
size_t asize = align_size(size, line_size);
|
||||
size_t asize = align_size(size, CACHE_LINESIZE);
|
||||
|
||||
// check alignment
|
||||
if (!is_aligned(dev_maddr, line_size))
|
||||
if (!is_aligned(dev_maddr, CACHE_LINESIZE))
|
||||
return -1;
|
||||
|
||||
// Ensure ready for new command
|
||||
if (vx_ready_wait(hdevice, -1) != 0)
|
||||
return -1;
|
||||
|
||||
auto ls_shift = (int)std::log2(line_size);
|
||||
auto ls_shift = (int)std::log2(CACHE_LINESIZE);
|
||||
|
||||
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_CSR_MEM_ADDR, dev_maddr >> ls_shift));
|
||||
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_CSR_DATA_SIZE, asize >> ls_shift));
|
||||
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_CSR_CMD, CMD_TYPE_CLFLUSH));
|
||||
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_MEM_ADDR, dev_maddr >> ls_shift));
|
||||
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_DATA_SIZE, asize >> ls_shift));
|
||||
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_CMD_TYPE, CMD_CLFLUSH));
|
||||
|
||||
// Wait for the write operation to finish
|
||||
if (vx_ready_wait(hdevice, -1) != 0)
|
||||
@@ -396,13 +454,59 @@ extern int vx_start(vx_device_h hdevice) {
|
||||
if (nullptr == hdevice)
|
||||
return -1;
|
||||
|
||||
vx_device_t *device = ((vx_device_t*)hdevice);
|
||||
|
||||
// Ensure ready for new command
|
||||
if (vx_ready_wait(hdevice, -1) != 0)
|
||||
return -1;
|
||||
|
||||
// start execution
|
||||
// start execution
|
||||
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_CMD_TYPE, CMD_RUN));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// set device constant registers
|
||||
extern int vx_csr_set(vx_device_h hdevice, int address, int value) {
|
||||
if (nullptr == hdevice)
|
||||
return -1;
|
||||
|
||||
vx_device_t *device = ((vx_device_t*)hdevice);
|
||||
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_CSR_CMD, CMD_TYPE_RUN));
|
||||
|
||||
// Ensure ready for new command
|
||||
if (vx_ready_wait(hdevice, -1) != 0)
|
||||
return -1;
|
||||
|
||||
// write CSR value
|
||||
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_CSR_ADDR, address));
|
||||
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_CSR_DATA, value));
|
||||
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_CMD_TYPE, CMD_CSR_WRITE));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// get device constant registers
|
||||
extern int vx_csr_get(vx_device_h hdevice, int address, int* value) {
|
||||
if (nullptr == hdevice || nullptr == value)
|
||||
return -1;
|
||||
|
||||
vx_device_t *device = ((vx_device_t*)hdevice);
|
||||
|
||||
// Ensure ready for new command
|
||||
if (vx_ready_wait(hdevice, -1) != 0)
|
||||
return -1;
|
||||
|
||||
// write CSR value
|
||||
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_CSR_ADDR, address));
|
||||
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_CMD_TYPE, CMD_CSR_READ));
|
||||
|
||||
// Ensure ready for new command
|
||||
if (vx_ready_wait(hdevice, -1) != 0)
|
||||
return -1;
|
||||
|
||||
uint64_t value64;
|
||||
CHECK_RES(fpgaReadMMIO64(device->fpga, 0, MMIO_CSR_READ, &value64));
|
||||
*value = (int)value64;
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user