mirror of
https://github.com/vortexgpgpu/vortex.git
synced 2025-04-24 05:47:35 -04:00
minor update
This commit is contained in:
parent
3a93e004d4
commit
8b863dfc6e
9 changed files with 494 additions and 376 deletions
|
@ -247,6 +247,7 @@ module VX_afu_ctrl #(
|
|||
dcra_r <= '0;
|
||||
dcrv_r <= '0;
|
||||
dcr_wr_valid_r <= 0;
|
||||
mem_r <= '0;
|
||||
end else if (clk_en) begin
|
||||
if (ap_ready)
|
||||
ap_start_r <= auto_restart_r;
|
||||
|
|
|
@ -43,6 +43,7 @@ module VX_avs_adapter #(
|
|||
localparam DATA_SIZE = DATA_WIDTH/8;
|
||||
localparam RD_QUEUE_ADDR_WIDTH = $clog2(RD_QUEUE_SIZE+1);
|
||||
localparam BANK_ADDRW = `LOG2UP(NUM_BANKS);
|
||||
localparam LOG2_NUM_BANKS = $clog2(NUM_BANKS);
|
||||
|
||||
// Requests handling //////////////////////////////////////////////////////
|
||||
|
||||
|
@ -123,7 +124,7 @@ module VX_avs_adapter #(
|
|||
|
||||
assign avs_read[i] = valid_out && ~rw_out;
|
||||
assign avs_write[i] = valid_out && rw_out;
|
||||
assign avs_address[i] = (addr_out >> BANK_ADDRW);
|
||||
assign avs_address[i] = (addr_out >> LOG2_NUM_BANKS);
|
||||
assign avs_byteenable[i] = byteen_out;
|
||||
assign avs_writedata[i] = data_out;
|
||||
assign avs_burstcount[i] = BURST_WIDTH'(1);
|
||||
|
|
|
@ -77,7 +77,8 @@ module VX_axi_adapter #(
|
|||
input wire [1:0] m_axi_rresp [NUM_BANKS]
|
||||
);
|
||||
localparam AXSIZE = $clog2(DATA_WIDTH/8);
|
||||
localparam BANK_ADDRW = `LOG2UP(NUM_BANKS);
|
||||
localparam BANK_ADDRW = `LOG2UP(NUM_BANKS);
|
||||
localparam LOG2_NUM_BANKS = $clog2(NUM_BANKS);
|
||||
|
||||
wire [BANK_ADDRW-1:0] req_bank_sel;
|
||||
|
||||
|
@ -130,7 +131,7 @@ module VX_axi_adapter #(
|
|||
// AXI write request address channel
|
||||
for (genvar i = 0; i < NUM_BANKS; ++i) begin
|
||||
assign m_axi_awvalid[i] = mem_req_valid && mem_req_rw && (req_bank_sel == i) && ~m_axi_aw_ack[i];
|
||||
assign m_axi_awaddr[i] = (ADDR_WIDTH'(mem_req_addr) >> BANK_ADDRW) << AXSIZE;
|
||||
assign m_axi_awaddr[i] = (ADDR_WIDTH'(mem_req_addr) >> LOG2_NUM_BANKS) << AXSIZE;
|
||||
assign m_axi_awid[i] = mem_req_tag;
|
||||
assign m_axi_awlen[i] = 8'b00000000;
|
||||
assign m_axi_awsize[i] = 3'(AXSIZE);
|
||||
|
@ -162,7 +163,7 @@ module VX_axi_adapter #(
|
|||
// AXI read request channel
|
||||
for (genvar i = 0; i < NUM_BANKS; ++i) begin
|
||||
assign m_axi_arvalid[i] = mem_req_valid && ~mem_req_rw && (req_bank_sel == i);
|
||||
assign m_axi_araddr[i] = (ADDR_WIDTH'(mem_req_addr) >> BANK_ADDRW) << AXSIZE;
|
||||
assign m_axi_araddr[i] = (ADDR_WIDTH'(mem_req_addr) >> LOG2_NUM_BANKS) << AXSIZE;
|
||||
assign m_axi_arid[i] = mem_req_tag;
|
||||
assign m_axi_arlen[i] = 8'b00000000;
|
||||
assign m_axi_arsize[i] = 3'(AXSIZE);
|
||||
|
|
|
@ -93,7 +93,7 @@ else ifeq ($(DEV_ARCH), versal)
|
|||
# versal
|
||||
else
|
||||
# alveo
|
||||
VPP_FLAGS += --connectivity.sp vortex_afu_1.m0_axi_mem:HBM[0:15]
|
||||
VPP_FLAGS += --connectivity.sp vortex_afu_1.m_axi_mem_0:HBM[0:15]
|
||||
endif
|
||||
|
||||
VPP_FLAGS += --report_level 2
|
||||
|
@ -156,8 +156,8 @@ scope-json: $(BUILD_DIR)/scope.json
|
|||
$(BUILD_DIR)/scope.json: $(BUILD_DIR)/vortex.xml
|
||||
mkdir -p $(BUILD_DIR); cd $(BUILD_DIR); $(SCRIPT_DIR)/scope.py vortex.xml -o scope.json
|
||||
|
||||
$(XO_CONTAINER): $(BUILD_DIR)/sources.txt ./kernel.xml
|
||||
mkdir -p $(BUILD_DIR); cd $(BUILD_DIR); $(VIVADO) -mode batch -source ../scripts/gen_xo.tcl -tclargs ../$(XO_CONTAINER) vortex_afu sources.txt ../kernel.xml $(SCRIPT_DIR) ../$(BUILD_DIR)
|
||||
$(XO_CONTAINER): $(BUILD_DIR)/sources.txt
|
||||
mkdir -p $(BUILD_DIR); cd $(BUILD_DIR); $(VIVADO) -mode batch -source ../scripts/gen_xo.tcl -tclargs ../$(XO_CONTAINER) vortex_afu sources.txt $(SCRIPT_DIR) ../$(BUILD_DIR)
|
||||
|
||||
$(XCLBIN_CONTAINER): $(XO_CONTAINER) $(SCOPE_JSON)
|
||||
mkdir -p $(BIN_DIR); cd $(BUILD_DIR); $(VPP) $(VPP_FLAGS) -o ../$(XCLBIN_CONTAINER) ../$(XO_CONTAINER)
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<root versionMajor="1" versionMinor="6">
|
||||
<kernel name="vortex_afu" language="ip_c" vlnv="xilinx.com:RTLKernel:vortex_afu:1.0" attributes="" preferredWorkGroupSizeMultiple="0" workGroupSize="1" interrupt="true" hwControlProtocol="user_managed">
|
||||
<ports>
|
||||
<port name="s_axi_ctrl" mode="slave" range="0x1000" dataWidth="32" portType="addressable" base="0x0"/>
|
||||
<port name="m0_axi_mem" mode="master" range="0xFFFFFFFFFFFFFFFF" dataWidth="512" portType="addressable" base="0x0"/>
|
||||
</ports>
|
||||
<args>
|
||||
<arg id="0" name="DEV" addressQualifier="0" port="s_axi_ctrl" size="0x8" offset="0x10" type="uint" hostOffset="0x0" hostSize="0x8"/>
|
||||
<arg id="1" name="ISA" addressQualifier="0" port="s_axi_ctrl" size="0x8" offset="0x1C" type="uint" hostOffset="0x0" hostSize="0x8"/>
|
||||
<arg id="2" name="DCR" addressQualifier="0" port="s_axi_ctrl" size="0x8" offset="0x28" type="uint" hostOffset="0x0" hostSize="0x8"/>
|
||||
<arg id="3" name="SCP" addressQualifier="0" port="s_axi_ctrl" size="0x8" offset="0x34" type="uint" hostOffset="0x0" hostSize="0x8"/>
|
||||
<arg id="4" name="MEM" addressQualifier="1" port="m0_axi_mem" size="0x8" offset="0x40" type="void*" hostOffset="0x0" hostSize="0x8"/>
|
||||
</args>
|
||||
</kernel>
|
||||
</root>
|
|
@ -1,15 +1,14 @@
|
|||
if { $::argc != 6 } {
|
||||
puts "ERROR: Program \"$::argv0\" requires 5 arguments!\n"
|
||||
puts "Usage: $::argv0 <xoname> <krnl_name> <vcs_file> <kernel_xml> <tool_dir> <build_dir>\n"
|
||||
if { $::argc != 5 } {
|
||||
puts "ERROR: Program \"$::argv0\" requires 4 arguments!\n"
|
||||
puts "Usage: $::argv0 <xoname> <krnl_name> <vcs_file> <tool_dir> <build_dir>\n"
|
||||
exit
|
||||
}
|
||||
|
||||
set xoname [lindex $::argv 0]
|
||||
set krnl_name [lindex $::argv 1]
|
||||
set vcs_file [lindex $::argv 2]
|
||||
set krnl_xml [lindex $::argv 3]
|
||||
set tool_dir [lindex $::argv 4]
|
||||
set build_dir [lindex $::argv 5]
|
||||
set tool_dir [lindex $::argv 3]
|
||||
set build_dir [lindex $::argv 4]
|
||||
|
||||
set script_path [ file dirname [ file normalize [ info script ] ] ]
|
||||
|
||||
|
@ -25,4 +24,4 @@ set argv [list ${krnl_name} ${vcs_file} ${tool_dir} ${build_dir}]
|
|||
set argc 4
|
||||
source ${script_path}/package_kernel.tcl
|
||||
|
||||
package_xo -xo_path ${xoname} -kernel_name ${krnl_name} -ip_directory "${build_dir}/xo/packaged_kernel" -kernel_xml ${krnl_xml}
|
||||
package_xo -xo_path ${xoname} -kernel_name ${krnl_name} -ip_directory "${build_dir}/xo/packaged_kernel"
|
||||
|
|
|
@ -141,13 +141,115 @@ foreach up [ipx::get_user_parameters] {
|
|||
}
|
||||
|
||||
ipx::associate_bus_interfaces -busif s_axi_ctrl -clock ap_clk $core
|
||||
ipx::associate_bus_interfaces -busif m0_axi_mem -clock ap_clk $core
|
||||
|
||||
for {set i 0} {$i < 1} {incr i} {
|
||||
ipx::associate_bus_interfaces -busif m_axi_mem_$i -clock ap_clk $core
|
||||
}
|
||||
|
||||
set mem_map [::ipx::add_memory_map -quiet "s_axi_ctrl" $core]
|
||||
set addr_block [::ipx::add_address_block -quiet "reg0" $mem_map]
|
||||
|
||||
set reg [::ipx::add_register "CTRL" $addr_block]
|
||||
set_property description "Control signals" $reg
|
||||
set_property address_offset 0x000 $reg
|
||||
set_property size 32 $reg
|
||||
|
||||
set field [ipx::add_field AP_START $reg]
|
||||
set_property ACCESS {read-write} $field
|
||||
set_property BIT_OFFSET {0} $field
|
||||
set_property BIT_WIDTH {1} $field
|
||||
set_property DESCRIPTION {Control signal Register for 'ap_start'.} $field
|
||||
set_property MODIFIED_WRITE_VALUE {modify} $field
|
||||
|
||||
set field [ipx::add_field AP_DONE $reg]
|
||||
set_property ACCESS {read-only} $field
|
||||
set_property BIT_OFFSET {1} $field
|
||||
set_property BIT_WIDTH {1} $field
|
||||
set_property DESCRIPTION {Control signal Register for 'ap_done'.} $field
|
||||
set_property READ_ACTION {modify} $field
|
||||
|
||||
set field [ipx::add_field AP_IDLE $reg]
|
||||
set_property ACCESS {read-only} $field
|
||||
set_property BIT_OFFSET {2} $field
|
||||
set_property BIT_WIDTH {1} $field
|
||||
set_property DESCRIPTION {Control signal Register for 'ap_idle'.} $field
|
||||
set_property READ_ACTION {modify} $field
|
||||
|
||||
set field [ipx::add_field AP_READY $reg]
|
||||
set_property ACCESS {read-only} $field
|
||||
set_property BIT_OFFSET {3} $field
|
||||
set_property BIT_WIDTH {1} $field
|
||||
set_property DESCRIPTION {Control signal Register for 'ap_ready'.} $field
|
||||
set_property READ_ACTION {modify} $field
|
||||
|
||||
set field [ipx::add_field RESERVED_1 $reg]
|
||||
set_property ACCESS {read-only} $field
|
||||
set_property BIT_OFFSET {4} $field
|
||||
set_property BIT_WIDTH {3} $field
|
||||
set_property DESCRIPTION {Reserved. 0s on read.} $field
|
||||
set_property READ_ACTION {modify} $field
|
||||
|
||||
set field [ipx::add_field AUTO_RESTART $reg]
|
||||
set_property ACCESS {read-write} $field
|
||||
set_property BIT_OFFSET {7} $field
|
||||
set_property BIT_WIDTH {1} $field
|
||||
set_property DESCRIPTION {Control signal Register for 'auto_restart'.} $field
|
||||
set_property MODIFIED_WRITE_VALUE {modify} $field
|
||||
|
||||
set field [ipx::add_field RESERVED_2 $reg]
|
||||
set_property ACCESS {read-only} $field
|
||||
set_property BIT_OFFSET {8} $field
|
||||
set_property BIT_WIDTH {24} $field
|
||||
set_property DESCRIPTION {Reserved. 0s on read.} $field
|
||||
set_property READ_ACTION {modify} $field
|
||||
|
||||
set reg [::ipx::add_register "GIER" $addr_block]
|
||||
set_property description "Global Interrupt Enable Register" $reg
|
||||
set_property address_offset 0x004 $reg
|
||||
set_property size 32 $reg
|
||||
|
||||
set reg [::ipx::add_register "IP_IER" $addr_block]
|
||||
set_property description "IP Interrupt Enable Register" $reg
|
||||
set_property address_offset 0x008 $reg
|
||||
set_property size 32 $reg
|
||||
|
||||
set reg [::ipx::add_register "IP_ISR" $addr_block]
|
||||
set_property description "IP Interrupt Status Register" $reg
|
||||
set_property address_offset 0x00C $reg
|
||||
set_property size 32 $reg
|
||||
|
||||
set reg [::ipx::add_register -quiet "DEV" $addr_block]
|
||||
set_property address_offset 0x010 $reg
|
||||
set_property size [expr {8*8}] $reg
|
||||
|
||||
set reg [::ipx::add_register -quiet "ISA" $addr_block]
|
||||
set_property address_offset 0x01C $reg
|
||||
set_property size [expr {8*8}] $reg
|
||||
|
||||
set reg [::ipx::add_register -quiet "DCR" $addr_block]
|
||||
set_property address_offset 0x028 $reg
|
||||
set_property size [expr {8*8}] $reg
|
||||
|
||||
set reg [::ipx::add_register -quiet "SCP" $addr_block]
|
||||
set_property address_offset 0x034 $reg
|
||||
set_property size [expr {8*8}] $reg
|
||||
|
||||
for {set i 0} {$i < 1} {incr i} {
|
||||
set reg [::ipx::add_register -quiet "MEM_$i" $addr_block]
|
||||
set_property address_offset 0x040 $reg
|
||||
set_property size [expr {8*8}] $reg
|
||||
set regparam [::ipx::add_register_parameter -quiet {ASSOCIATED_BUSIF} $reg]
|
||||
set_property value m_axi_mem_$i $regparam
|
||||
}
|
||||
|
||||
set_property slave_memory_map_ref "s_axi_ctrl" [::ipx::get_bus_interfaces -of $core "s_axi_ctrl"]
|
||||
|
||||
set_property xpm_libraries {XPM_CDC XPM_MEMORY XPM_FIFO} $core
|
||||
set_property sdx_kernel true $core
|
||||
set_property sdx_kernel_type rtl $core
|
||||
set_property supported_families { } $core
|
||||
set_property auto_family_support_level level_2 $core
|
||||
|
||||
ipx::create_xgui_files $core
|
||||
ipx::update_checksums $core
|
||||
ipx::check_integrity -kernel $core
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[connectivity]
|
||||
#nk=vortex_afu:1
|
||||
#sp=vortex_afu_1.m0_axi_mem:HBM[0:15]
|
||||
#sp=vortex_afu_1.m_axi_mem_0:HBM[0:15]
|
||||
|
||||
[vivado]
|
||||
#prop=fileset.sim_1.xsim.elaborate.debug_level=all
|
||||
|
|
|
@ -20,12 +20,15 @@
|
|||
#include "experimental/xrt_xclbin.h"
|
||||
#include "experimental/xrt_error.h"
|
||||
|
||||
#define CPP_API
|
||||
//#define BANK_INTERLEAVE
|
||||
|
||||
#define MMIO_CTL_ADDR 0x00
|
||||
#define MMIO_DEV_ADDR 0x10
|
||||
#define MMIO_ISA_ADDR 0x1C
|
||||
#define MMIO_DCR_ADDR 0x28
|
||||
#define MMIO_MEM_ADDR 0x34
|
||||
#define MMIO_SCP_ADDR 0x40
|
||||
#define MMIO_SCP_ADDR 0x34
|
||||
#define MMIO_MEM_ADDR 0x40
|
||||
|
||||
#define CTL_AP_START (1<<0)
|
||||
#define CTL_AP_DONE (1<<1)
|
||||
|
@ -36,16 +39,16 @@
|
|||
|
||||
struct platform_info_t {
|
||||
const char* prefix_name;
|
||||
uint32_t num_banks;
|
||||
uint8_t lg2_num_banks;
|
||||
uint8_t lg2_bank_size;
|
||||
uint64_t mem_base;
|
||||
uint64_t bank_size;
|
||||
};
|
||||
|
||||
static const platform_info_t g_platforms [] = {
|
||||
{"xilinx_u50", 32, 0x0, 0x10000000},
|
||||
{"xilinx_u200", 32, 0x0, 0x10000000},
|
||||
{"xilinx_u280", 32, 0x0, 0x10000000},
|
||||
{"xilinx_vck5000", 1, 0xC000000000, 0x200000000},
|
||||
{"xilinx_u50", 4, 0x1C, 0x0},
|
||||
{"xilinx_u200", 4, 0x1C, 0x0},
|
||||
{"xilinx_u280", 4, 0x1C, 0x0},
|
||||
{"xilinx_vck5000", 0, 0x21, 0xC000000000},
|
||||
};
|
||||
|
||||
#ifdef CPP_API
|
||||
|
@ -110,7 +113,7 @@ static int get_platform_info(const std::string& device_name, platform_info_t* pl
|
|||
for (size_t i = 0; i < (sizeof(g_platforms)/sizeof(platform_info_t)); ++i) {
|
||||
auto& platform = g_platforms[i];
|
||||
if (device_name.rfind(platform.prefix_name, 0) == 0) {
|
||||
*platform_info = platform;;
|
||||
*platform_info = platform;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -124,164 +127,7 @@ static int get_platform_info(const std::string& device_name, platform_info_t* pl
|
|||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class vx_device {
|
||||
public:
|
||||
|
||||
vx_device(xrt_device_t& device, xrt_kernel_t& kernel, uint32_t num_banks, uint64_t bank_size)
|
||||
: xrtDevice(device)
|
||||
, xrtKernel(kernel)
|
||||
, num_banks_(num_banks)
|
||||
, bank_size_(bank_size)
|
||||
, mem_allocator_(
|
||||
ALLOC_BASE_ADDR,
|
||||
ALLOC_MAX_ADDR,
|
||||
4096,
|
||||
CACHE_BLOCK_SIZE)
|
||||
{}
|
||||
|
||||
#ifndef CPP_API
|
||||
|
||||
~vx_device() {
|
||||
for (auto it : xrtBuffers_) {
|
||||
xrtBOFree(it.second.xrtBuffer);
|
||||
}
|
||||
if (this->xrtKernel) {
|
||||
xrtKernelClose(this->xrtKernel);
|
||||
}
|
||||
if (this->xrtDevice) {
|
||||
xrtDeviceClose(this->xrtDevice);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int mem_alloc(uint64_t size, uint64_t* dev_maddr) {
|
||||
uint64_t asize = aligned_size(size, CACHE_BLOCK_SIZE);
|
||||
|
||||
uint64_t addr;
|
||||
|
||||
CHECK_ERR(mem_allocator_.allocate(asize, &addr), {
|
||||
return -1;
|
||||
});
|
||||
|
||||
uint32_t bank_id;
|
||||
|
||||
CHECK_ERR(this->get_bank_info(addr, &bank_id, nullptr), {
|
||||
return -1;
|
||||
});
|
||||
|
||||
CHECK_ERR(get_buffer(bank_id, nullptr), {
|
||||
return -1;
|
||||
});
|
||||
|
||||
*dev_maddr = addr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mem_free(uint64_t dev_maddr) {
|
||||
|
||||
uint32_t bank_id;
|
||||
|
||||
CHECK_ERR(this->get_bank_info(dev_maddr, &bank_id, nullptr), {
|
||||
return -1;
|
||||
});
|
||||
|
||||
auto it = xrtBuffers_.find(bank_id);
|
||||
if (it != xrtBuffers_.end()) {
|
||||
auto count = --it->second.count;
|
||||
if (0 == count) {
|
||||
printf("freeing bank%d...\n", bank_id);
|
||||
#ifndef CPP_API
|
||||
xrtBOFree(it->second.xrtBuffer);
|
||||
#endif
|
||||
xrtBuffers_.erase(it);
|
||||
}
|
||||
CHECK_ERR(mem_allocator_.release(dev_maddr), {
|
||||
return -1;
|
||||
});
|
||||
} else {
|
||||
fprintf(stderr, "[VXDRV] Error: invalid device memory address: 0x%lx\n", dev_maddr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t mem_used() const {
|
||||
return mem_allocator_.allocated();
|
||||
}
|
||||
|
||||
int get_buffer(uint32_t bank_id, xrt_buffer_t* pBuf) {
|
||||
auto it = xrtBuffers_.find(bank_id);
|
||||
if (it != xrtBuffers_.end()) {
|
||||
if (pBuf) {
|
||||
*pBuf = it->second.xrtBuffer;
|
||||
} else {
|
||||
printf("reusing bank%d...\n", bank_id);
|
||||
++it->second.count;
|
||||
}
|
||||
} else {
|
||||
printf("allocating bank%d...\n", bank_id);
|
||||
#ifdef CPP_API
|
||||
xrt::bo xrtBuffer(xrtDevice, bank_size_, xrt::bo::flags::normal, bank_id);
|
||||
#else
|
||||
CHECK_HANDLE(xrtBuffer, xrtBOAlloc(xrtDevice, bank_size_, XRT_BO_FLAGS_NONE, bank_id), {
|
||||
return -1;
|
||||
});
|
||||
#endif
|
||||
xrtBuffers_.insert({bank_id, {xrtBuffer, 1}});
|
||||
if (pBuf) {
|
||||
*pBuf = xrtBuffer;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_bank_info(uint64_t addr, uint32_t* pIdx, uint64_t* pOff) {
|
||||
uint32_t index = addr / bank_size_;
|
||||
uint64_t offset = addr % bank_size_;
|
||||
|
||||
printf("get_bank_info(addr=0x%lx, bank=%d, offset=0x%lx\n", addr, index, offset);
|
||||
|
||||
if (index > num_banks_) {
|
||||
fprintf(stderr, "[VXDRV] Error: address out of range: 0x%lx\n", addr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pIdx) {
|
||||
*pIdx = index;
|
||||
}
|
||||
|
||||
if (pOff) {
|
||||
*pOff = offset;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
xrt_device_t xrtDevice;
|
||||
xrt_kernel_t xrtKernel;
|
||||
|
||||
struct buf_cnt_t {
|
||||
xrt_buffer_t xrtBuffer;
|
||||
uint32_t count;
|
||||
};
|
||||
|
||||
uint32_t num_banks_;
|
||||
uint64_t bank_size_;
|
||||
|
||||
DeviceConfig dcrs;
|
||||
uint64_t dev_caps;
|
||||
uint64_t isa_caps;
|
||||
|
||||
private:
|
||||
|
||||
std::unordered_map<uint32_t, buf_cnt_t> xrtBuffers_;
|
||||
vortex::MemoryAllocator mem_allocator_;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class vx_device;
|
||||
|
||||
class vx_buffer {
|
||||
public:
|
||||
|
@ -304,6 +150,337 @@ public:
|
|||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class vx_device {
|
||||
public:
|
||||
|
||||
vx_device(xrt_device_t& device, xrt_kernel_t& kernel, const platform_info_t& platform)
|
||||
: xrtDevice_(device)
|
||||
, xrtKernel_(kernel)
|
||||
, platform_(platform)
|
||||
, mem_allocator_(
|
||||
ALLOC_BASE_ADDR,
|
||||
ALLOC_MAX_ADDR,
|
||||
RAM_PAGE_SIZE,
|
||||
CACHE_BLOCK_SIZE)
|
||||
{}
|
||||
|
||||
#ifndef CPP_API
|
||||
|
||||
~vx_device() {
|
||||
for (auto& entry : xrtBuffers_) {
|
||||
#ifdef BANK_INTERLEAVE
|
||||
xrtBOFree(entry);
|
||||
#else
|
||||
xrtBOFree(entry.second.xrtBuffer);
|
||||
#endif
|
||||
}
|
||||
if (xrtKernel_) {
|
||||
xrtKernelClose(xrtKernel_);
|
||||
}
|
||||
if (xrtDevice_) {
|
||||
xrtDeviceClose(xrtDevice_);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int init() {
|
||||
CHECK_ERR(this->write_register(MMIO_CTL_ADDR, CTL_AP_RESET), {
|
||||
return -1;
|
||||
});
|
||||
|
||||
CHECK_ERR(this->write_register(MMIO_MEM_ADDR, platform_.mem_base & 0xffffffff), {
|
||||
return -1;
|
||||
});
|
||||
|
||||
CHECK_ERR(this->write_register(MMIO_MEM_ADDR + 4, (platform_.mem_base >> 32) & 0xffffffff), {
|
||||
return -1;
|
||||
});
|
||||
|
||||
CHECK_ERR(this->read_register(MMIO_DEV_ADDR, (uint32_t*)&this->dev_caps), {
|
||||
return -1;
|
||||
});
|
||||
|
||||
CHECK_ERR(this->read_register(MMIO_DEV_ADDR + 4, (uint32_t*)&this->dev_caps + 1), {
|
||||
return -1;
|
||||
});
|
||||
|
||||
CHECK_ERR(this->read_register(MMIO_ISA_ADDR, (uint32_t*)&this->isa_caps), {
|
||||
return -1;
|
||||
});
|
||||
|
||||
CHECK_ERR(this->read_register(MMIO_ISA_ADDR + 4, (uint32_t*)&this->isa_caps + 1), {
|
||||
return -1;
|
||||
});
|
||||
|
||||
#ifdef BANK_INTERLEAVE
|
||||
uint32_t num_banks = 1 << platform_.lg2_num_banks;
|
||||
uint64_t bank_size = 1ull << platform_.lg2_bank_size;
|
||||
xrtBuffers_.reserve(num_banks);
|
||||
for (uint32_t i = 0; i < num_banks; ++i) {
|
||||
#ifdef CPP_API
|
||||
xrtBuffers_.emplace_back(xrtDevice_, bank_size, xrt::bo::flags::normal, i);
|
||||
#else
|
||||
CHECK_HANDLE(xrtBuffer, xrtBOAlloc(xrtDevice_, bank_size, XRT_BO_FLAGS_NONE, i), {
|
||||
return -1;
|
||||
});
|
||||
xrtBuffers_.push_back(xrtBuffer);
|
||||
#endif
|
||||
printf("*** allocated bank%u/%u, size=%lu\n", i, num_banks, bank_size);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mem_alloc(uint64_t size, uint64_t* dev_maddr) {
|
||||
uint64_t asize = aligned_size(size, CACHE_BLOCK_SIZE);
|
||||
uint64_t addr;
|
||||
CHECK_ERR(mem_allocator_.allocate(asize, &addr), {
|
||||
return -1;
|
||||
});
|
||||
#ifndef BANK_INTERLEAVE
|
||||
uint32_t bank_id;
|
||||
CHECK_ERR(this->get_bank_info(addr, &bank_id, nullptr), {
|
||||
return -1;
|
||||
});
|
||||
CHECK_ERR(get_buffer(bank_id, nullptr), {
|
||||
return -1;
|
||||
});
|
||||
#endif
|
||||
*dev_maddr = addr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mem_free(uint64_t dev_maddr) {
|
||||
CHECK_ERR(mem_allocator_.release(dev_maddr), {
|
||||
return -1;
|
||||
});
|
||||
#ifdef BANK_INTERLEAVE
|
||||
if (0 == mem_allocator_.allocated()) {
|
||||
#ifndef CPP_API
|
||||
for (auto& entry : xrtBuffers_) {
|
||||
xrtBOFree(entry);
|
||||
}
|
||||
#endif
|
||||
xrtBuffers_.clear();
|
||||
}
|
||||
#else
|
||||
uint32_t bank_id;
|
||||
CHECK_ERR(this->get_bank_info(dev_maddr, &bank_id, nullptr), {
|
||||
return -1;
|
||||
});
|
||||
auto it = xrtBuffers_.find(bank_id);
|
||||
if (it != xrtBuffers_.end()) {
|
||||
auto count = --it->second.count;
|
||||
if (0 == count) {
|
||||
printf("freeing bank%d...\n", bank_id);
|
||||
#ifndef CPP_API
|
||||
xrtBOFree(it->second.xrtBuffer);
|
||||
#endif
|
||||
xrtBuffers_.erase(it);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "[VXDRV] Error: invalid device memory address: 0x%lx\n", dev_maddr);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int write_register(uint32_t addr, uint32_t value) {
|
||||
#ifdef CPP_API
|
||||
xrtKernel_.write_register(addr, value);
|
||||
#else
|
||||
CHECK_ERR(xrtKernelWriteRegister(xrtKernel_, addr, value), {
|
||||
dump_xrt_error(xrtDevice_, err);
|
||||
return -1;
|
||||
});
|
||||
#endif
|
||||
DBGPRINT("*** write_register: addr=0x%x, value=0x%x\n", addr, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int read_register(uint32_t addr, uint32_t* value) {
|
||||
#ifdef CPP_API
|
||||
*value = xrtKernel_.read_register(addr);
|
||||
#else
|
||||
CHECK_ERR(xrtKernelReadRegister(xrtKernel_, addr, value), {
|
||||
dump_xrt_error(xrtDevice_, err);
|
||||
return -1;
|
||||
});
|
||||
#endif
|
||||
DBGPRINT("*** read_register: addr=0x%x, value=0x%x\n", addr, *value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int copy_to_dev(void* host_ptr, uint64_t dev_maddr, uint64_t asize) {
|
||||
for (uint64_t end = dev_maddr + asize; dev_maddr < end; dev_maddr += CACHE_BLOCK_SIZE) {
|
||||
#ifdef BANK_INTERLEAVE
|
||||
asize = CACHE_BLOCK_SIZE;
|
||||
#else
|
||||
end = 0;
|
||||
#endif
|
||||
uint32_t bo_index;
|
||||
uint64_t bo_offset;
|
||||
CHECK_ERR(this->get_bank_info(dev_maddr, &bo_index, &bo_offset), {
|
||||
return -1;
|
||||
});
|
||||
xrt_buffer_t xrtBuffer;
|
||||
CHECK_ERR(this->get_buffer(bo_index, &xrtBuffer), {
|
||||
return -1;
|
||||
});
|
||||
#ifdef CPP_API
|
||||
xrtBuffer.write(host_ptr, asize, bo_offset);
|
||||
xrtBuffer.sync(XCL_BO_SYNC_BO_TO_DEVICE, asize, bo_offset);
|
||||
#else
|
||||
CHECK_ERR(xrtBOWrite(xrtBuffer, host_ptr, asize, bo_offset), {
|
||||
dump_xrt_error(xrtDevice_, err);
|
||||
return -1;
|
||||
});
|
||||
CHECK_ERR(xrtBOSync(xrtBuffer, XCL_BO_SYNC_BO_TO_DEVICE, asize, bo_offset), {
|
||||
dump_xrt_error(xrtDevice_, err);
|
||||
return -1;
|
||||
});
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int copy_from_dev(void* host_ptr, uint64_t dev_maddr, uint64_t asize) {
|
||||
for (uint64_t end = dev_maddr + asize; dev_maddr < end; dev_maddr += CACHE_BLOCK_SIZE) {
|
||||
#ifdef BANK_INTERLEAVE
|
||||
asize = CACHE_BLOCK_SIZE;
|
||||
#else
|
||||
end = 0;
|
||||
#endif
|
||||
uint32_t bo_index;
|
||||
uint64_t bo_offset;
|
||||
CHECK_ERR(this->get_bank_info(dev_maddr, &bo_index, &bo_offset), {
|
||||
return -1;
|
||||
});
|
||||
xrt_buffer_t xrtBuffer;
|
||||
CHECK_ERR(this->get_buffer(bo_index, &xrtBuffer), {
|
||||
return -1;
|
||||
});
|
||||
#ifdef CPP_API
|
||||
xrtBuffer.sync(XCL_BO_SYNC_BO_FROM_DEVICE, asize, bo_offset);
|
||||
xrtBuffer.read(host_ptr, asize, bo_offset);
|
||||
#else
|
||||
CHECK_ERR(xrtBOSync(xrtBuffer, XCL_BO_SYNC_BO_FROM_DEVICE, asize, bo_offset), {
|
||||
dump_xrt_error(xrtDevice_, err);
|
||||
return -1;
|
||||
});
|
||||
CHECK_ERR(xrtBORead(xrtBuffer, host_ptr, asize, bo_offset), {
|
||||
dump_xrt_error(xrtDevice_, err);
|
||||
return -1;
|
||||
});
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t mem_used() const {
|
||||
return mem_allocator_.allocated();
|
||||
}
|
||||
|
||||
DeviceConfig dcrs;
|
||||
uint64_t dev_caps;
|
||||
uint64_t isa_caps;
|
||||
|
||||
private:
|
||||
|
||||
xrt_device_t xrtDevice_;
|
||||
xrt_kernel_t xrtKernel_;
|
||||
const platform_info_t platform_;
|
||||
vortex::MemoryAllocator mem_allocator_;
|
||||
|
||||
#ifdef BANK_INTERLEAVE
|
||||
|
||||
std::vector<xrt_buffer_t> xrtBuffers_;
|
||||
|
||||
int get_bank_info(uint64_t addr, uint32_t* pIdx, uint64_t* pOff) {
|
||||
uint32_t num_banks = 1 << platform_.lg2_num_banks;
|
||||
uint64_t block_addr = addr / CACHE_BLOCK_SIZE;
|
||||
uint32_t index = block_addr & (num_banks-1);
|
||||
uint64_t offset = (block_addr >> platform_.lg2_num_banks) * CACHE_BLOCK_SIZE;
|
||||
if (pIdx) {
|
||||
*pIdx = index;
|
||||
}
|
||||
if (pOff) {
|
||||
*pOff = offset;
|
||||
}
|
||||
printf("get_bank_info(addr=0x%lx, bank=%d, offset=0x%lx\n", addr, index, offset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_buffer(uint32_t bank_id, xrt_buffer_t* pBuf) {
|
||||
if (pBuf) {
|
||||
*pBuf = xrtBuffers_.at(bank_id);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
struct buf_cnt_t {
|
||||
xrt_buffer_t xrtBuffer;
|
||||
uint32_t count;
|
||||
};
|
||||
|
||||
std::unordered_map<uint32_t, buf_cnt_t> xrtBuffers_;
|
||||
|
||||
int get_bank_info(uint64_t addr, uint32_t* pIdx, uint64_t* pOff) {
|
||||
uint32_t num_banks = 1 << platform_.lg2_num_banks;
|
||||
uint64_t bank_size = 1ull << platform_.lg2_bank_size;
|
||||
uint32_t index = addr >> platform_.lg2_bank_size;
|
||||
uint64_t offset = addr & (bank_size-1);
|
||||
if (index > num_banks) {
|
||||
fprintf(stderr, "[VXDRV] Error: address out of range: 0x%lx\n", addr);
|
||||
return -1;
|
||||
}
|
||||
if (pIdx) {
|
||||
*pIdx = index;
|
||||
}
|
||||
if (pOff) {
|
||||
*pOff = offset;
|
||||
}
|
||||
printf("get_bank_info(addr=0x%lx, bank=%d, offset=0x%lx\n", addr, index, offset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_buffer(uint32_t bank_id, xrt_buffer_t* pBuf) {
|
||||
auto it = xrtBuffers_.find(bank_id);
|
||||
if (it != xrtBuffers_.end()) {
|
||||
if (pBuf) {
|
||||
*pBuf = it->second.xrtBuffer;
|
||||
} else {
|
||||
printf("reusing bank%d...\n", bank_id);
|
||||
++it->second.count;
|
||||
}
|
||||
} else {
|
||||
printf("allocating bank%d...\n", bank_id);
|
||||
uint64_t bank_size = 1ull << platform_.lg2_bank_size;
|
||||
#ifdef CPP_API
|
||||
xrt::bo xrtBuffer(xrtDevice_, bank_size, xrt::bo::flags::normal, bank_id);
|
||||
#else
|
||||
CHECK_HANDLE(xrtBuffer, xrtBOAlloc(xrtDevice_, bank_size, XRT_BO_FLAGS_NONE, bank_id), {
|
||||
return -1;
|
||||
});
|
||||
#endif
|
||||
xrtBuffers_.insert({bank_id, {xrtBuffer, 1}});
|
||||
if (pBuf) {
|
||||
*pBuf = xrtBuffer;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern int vx_dev_caps(vx_device_h hdevice, uint32_t caps_id, uint64_t *value) {
|
||||
if (nullptr == hdevice)
|
||||
return -1;
|
||||
|
@ -420,24 +597,10 @@ extern int vx_dev_open(vx_device_h* hdevice) {
|
|||
return -1;
|
||||
});
|
||||
|
||||
CHECK_HANDLE(device, new vx_device(xrtDevice, xrtKernel, platform_info.num_banks, platform_info.bank_size), {
|
||||
CHECK_HANDLE(device, new vx_device(xrtDevice, xrtKernel, platform_info), {
|
||||
return -1;
|
||||
});
|
||||
|
||||
xrtKernel.write_register(MMIO_CTL_ADDR, CTL_AP_RESET);
|
||||
|
||||
xrtKernel.write_register(MMIO_MEM_ADDR, platform_info.mem_base & 0xffffffff);
|
||||
xrtKernel.write_register(MMIO_MEM_ADDR + 4, (platform_info.mem_base >> 32) & 0xffffffff);
|
||||
|
||||
auto dev_caps_lo = xrtKernel.read_register(MMIO_DEV_ADDR);
|
||||
auto dev_caps_hi = xrtKernel.read_register(MMIO_DEV_ADDR + 4);
|
||||
|
||||
auto isa_caps_lo = xrtKernel.read_register(MMIO_ISA_ADDR);
|
||||
auto isa_caps_hi = xrtKernel.read_register(MMIO_ISA_ADDR + 4);
|
||||
|
||||
device->dev_caps = (uint64_t(dev_caps_hi) << 32) | dev_caps_lo;
|
||||
device->isa_caps = (uint64_t(isa_caps_hi) << 32) | isa_caps_lo;
|
||||
|
||||
#else
|
||||
|
||||
CHECK_HANDLE(xrtDevice, xrtDeviceOpen(device_index), {
|
||||
|
@ -474,53 +637,19 @@ extern int vx_dev_open(vx_device_h* hdevice) {
|
|||
return -1;
|
||||
});
|
||||
|
||||
CHECK_HANDLE(device, new vx_device(xrtDevice, xrtKernel, platform_info.num_banks, platform_info.bank_size), {
|
||||
CHECK_HANDLE(device, new vx_device(xrtDevice, xrtKernel, platform_info), {
|
||||
xrtKernelClose(xrtKernel);
|
||||
xrtDeviceClose(xrtDevice);
|
||||
return -1;
|
||||
});
|
||||
|
||||
CHECK_ERR(xrtKernelWriteRegister(device->xrtKernel, MMIO_CTL_ADDR, CTL_AP_RESET), {
|
||||
dump_xrt_error(xrtDevice, err);
|
||||
return -1;
|
||||
});
|
||||
#endif
|
||||
|
||||
CHECK_ERR(xrtKernelWriteRegister(device->xrtKernel, MMIO_MEM_ADDR, platform_info.mem_base & 0xffffffff), {
|
||||
dump_xrt_error(xrtDevice, err);
|
||||
// initialize device
|
||||
CHECK_ERR(device->init(), {
|
||||
return -1;
|
||||
});
|
||||
|
||||
CHECK_ERR(xrtKernelWriteRegister(device->xrtKernel, MMIO_MEM_ADDR + 4, (platform_info.mem_base >> 32) & 0xffffffff), {
|
||||
dump_xrt_error(xrtDevice, err);
|
||||
return -1;
|
||||
});
|
||||
|
||||
CHECK_ERR(xrtKernelReadRegister(device->xrtKernel, MMIO_DEV_ADDR, (uint32_t*)&device->dev_caps), {
|
||||
dump_xrt_error(xrtDevice, err);
|
||||
delete device;
|
||||
return -1;
|
||||
});
|
||||
|
||||
CHECK_ERR(xrtKernelReadRegister(device->xrtKernel, MMIO_DEV_ADDR + 4, (uint32_t*)&device->dev_caps + 1), {
|
||||
dump_xrt_error(xrtDevice, err);
|
||||
delete device;
|
||||
return -1;
|
||||
});
|
||||
|
||||
CHECK_ERR(xrtKernelReadRegister(device->xrtKernel, MMIO_ISA_ADDR, (uint32_t*)&device->isa_caps), {
|
||||
dump_xrt_error(xrtDevice, err);
|
||||
delete device;
|
||||
return -1;
|
||||
});
|
||||
|
||||
CHECK_ERR(xrtKernelReadRegister(device->xrtKernel, MMIO_ISA_ADDR + 4, (uint32_t*)&device->isa_caps + 1), {
|
||||
dump_xrt_error(xrtDevice, err);
|
||||
delete device;
|
||||
return -1;
|
||||
});
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef SCOPE
|
||||
{
|
||||
scope_callback_t callback;
|
||||
|
@ -528,37 +657,23 @@ extern int vx_dev_open(vx_device_h* hdevice) {
|
|||
auto device = (vx_device*)hdevice;
|
||||
uint32_t value_lo = (uint32_t)(value);
|
||||
uint32_t value_hi = (uint32_t)(value >> 32);
|
||||
#ifdef CPP_API
|
||||
device->xrtKernel.write_register(MMIO_SCP_ADDR, value_lo);
|
||||
device->xrtKernel.write_register(MMIO_SCP_ADDR + 4, value_hi);
|
||||
#else
|
||||
CHECK_ERR(xrtKernelWriteRegister(device->xrtKernel, MMIO_SCP_ADDR, value_lo), {
|
||||
dump_xrt_error(device->xrtDevice, err);
|
||||
CHECK_ERR(device->write_register(MMIO_SCP_ADDR, value_lo), {
|
||||
return -1;
|
||||
});
|
||||
CHECK_ERR(xrtKernelWriteRegister(device->xrtKernel, MMIO_SCP_ADDR + 4, value_hi), {
|
||||
dump_xrt_error(device->xrtDevice, err);
|
||||
CHECK_ERR(device->write_register(MMIO_SCP_ADDR + 4, value_hi), {
|
||||
return -1;
|
||||
});
|
||||
#endif
|
||||
});
|
||||
return 0;
|
||||
};
|
||||
callback.registerRead = [](vx_device_h hdevice, uint64_t* value)->int {
|
||||
auto device = (vx_device*)hdevice;
|
||||
uint32_t value_lo, value_hi;
|
||||
#ifdef CPP_API
|
||||
device->xrtKernel.read_register(MMIO_SCP_ADDR, &value_lo);
|
||||
device->xrtKernel.read_register(MMIO_SCP_ADDR + 4, &value_hi);
|
||||
#else
|
||||
CHECK_ERR(xrtKernelReadRegister(device->xrtKernel, MMIO_SCP_ADDR, &value_lo), {
|
||||
dump_xrt_error(device->xrtDevice, err);
|
||||
CHECK_ERR(device->read_register(MMIO_SCP_ADDR, &value_lo), {
|
||||
return -1;
|
||||
});
|
||||
CHECK_ERR(xrtKernelReadRegister(device->xrtKernel, MMIO_SCP_ADDR + 4, &value_hi), {
|
||||
dump_xrt_error(device->xrtDevice, err);
|
||||
CHECK_ERR(device->read_register(MMIO_SCP_ADDR + 4, &value_hi), {
|
||||
return -1;
|
||||
});
|
||||
#endif
|
||||
*value = (((uint64_t)value_hi) << 32) | value_lo;
|
||||
return 0;
|
||||
};
|
||||
|
@ -678,13 +793,8 @@ extern int vx_buf_free(vx_buffer_h hbuffer) {
|
|||
extern int vx_copy_to_dev(vx_buffer_h hbuffer, uint64_t dev_maddr, uint64_t size, uint64_t src_offset) {
|
||||
if (nullptr == hbuffer)
|
||||
return -1;
|
||||
|
||||
uint64_t dev_mem_size = LOCAL_MEM_SIZE;
|
||||
int64_t asize = aligned_size(size, CACHE_BLOCK_SIZE);
|
||||
|
||||
|
||||
auto buffer = (vx_buffer*)hbuffer;
|
||||
auto device = buffer->device;
|
||||
|
||||
auto host_ptr = buffer->host_ptr + src_offset;
|
||||
|
||||
// check alignment
|
||||
|
@ -693,55 +803,28 @@ extern int vx_copy_to_dev(vx_buffer_h hbuffer, uint64_t dev_maddr, uint64_t size
|
|||
if (!is_aligned((uintptr_t)host_ptr, CACHE_BLOCK_SIZE))
|
||||
return -1;
|
||||
|
||||
uint64_t asize = aligned_size(size, CACHE_BLOCK_SIZE);
|
||||
uint64_t dev_mem_size = LOCAL_MEM_SIZE;
|
||||
|
||||
// bound checking
|
||||
if (src_offset + asize > buffer->size)
|
||||
return -1;
|
||||
if (dev_maddr + asize > dev_mem_size)
|
||||
return -1;
|
||||
|
||||
uint32_t bo_index;
|
||||
uint64_t bo_offset;
|
||||
CHECK_ERR(device->get_bank_info(dev_maddr, &bo_index, &bo_offset), {
|
||||
|
||||
auto device = buffer->device;
|
||||
|
||||
CHECK_ERR(device->copy_to_dev(host_ptr, dev_maddr, asize), {
|
||||
return -1;
|
||||
});
|
||||
|
||||
xrt_buffer_t xrtBuffer;
|
||||
CHECK_ERR(device->get_buffer(bo_index, &xrtBuffer), {
|
||||
return -1;
|
||||
});
|
||||
|
||||
|
||||
#ifdef CPP_API
|
||||
|
||||
xrtBuffer.write(host_ptr, asize, bo_offset);
|
||||
xrtBuffer.sync(XCL_BO_SYNC_BO_TO_DEVICE, asize, bo_offset);
|
||||
|
||||
#else
|
||||
|
||||
CHECK_ERR(xrtBOWrite(xrtBuffer, host_ptr, asize, bo_offset), {
|
||||
dump_xrt_error(device->xrtDevice, err);
|
||||
return -1;
|
||||
});
|
||||
|
||||
CHECK_ERR(xrtBOSync(xrtBuffer, XCL_BO_SYNC_BO_TO_DEVICE, asize, bo_offset), {
|
||||
dump_xrt_error(device->xrtDevice, err);
|
||||
return -1;
|
||||
});
|
||||
|
||||
#endif
|
||||
|
||||
DBGPRINT("COPY_TO_DEV: dev_addr=0x%lx, host_addr=0x%lx, size=%ld, bank=%d, offset=0x%lx\n", dev_maddr, (uintptr_t)host_ptr, size, bo_index, bo_offset);
|
||||
DBGPRINT("COPY_TO_DEV: dev_addr=0x%lx, host_addr=0x%lx, size=%ld\n", dev_maddr, (uintptr_t)host_ptr, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern int vx_copy_from_dev(vx_buffer_h hbuffer, uint64_t dev_maddr, uint64_t size, uint64_t dest_offset) {
|
||||
auto buffer = (vx_buffer*)hbuffer;
|
||||
auto device = buffer->device;
|
||||
|
||||
uint64_t dev_mem_size = LOCAL_MEM_SIZE;
|
||||
int64_t asize = aligned_size(size, CACHE_BLOCK_SIZE);
|
||||
|
||||
auto host_ptr = buffer->host_ptr + dest_offset;
|
||||
|
||||
// check alignment
|
||||
|
@ -750,43 +833,22 @@ extern int vx_copy_from_dev(vx_buffer_h hbuffer, uint64_t dev_maddr, uint64_t si
|
|||
if (!is_aligned((uintptr_t)host_ptr, CACHE_BLOCK_SIZE))
|
||||
return -1;
|
||||
|
||||
uint64_t asize = aligned_size(size, CACHE_BLOCK_SIZE);
|
||||
uint64_t dev_mem_size = LOCAL_MEM_SIZE;
|
||||
|
||||
// bound checking
|
||||
if (dest_offset + asize > buffer->size)
|
||||
return -1;
|
||||
if (dev_maddr + asize > dev_mem_size)
|
||||
return -1;
|
||||
|
||||
uint32_t bo_index;
|
||||
uint64_t bo_offset;
|
||||
CHECK_ERR(device->get_bank_info(dev_maddr, &bo_index, &bo_offset), {
|
||||
return -1;
|
||||
});
|
||||
auto device = buffer->device;
|
||||
|
||||
xrt_buffer_t xrtBuffer;
|
||||
CHECK_ERR(device->get_buffer(bo_index, &xrtBuffer), {
|
||||
CHECK_ERR(device->copy_from_dev(host_ptr, dev_maddr, asize), {
|
||||
return -1;
|
||||
});
|
||||
|
||||
#ifdef CPP_API
|
||||
|
||||
xrtBuffer.sync(XCL_BO_SYNC_BO_FROM_DEVICE, asize, bo_offset);
|
||||
xrtBuffer.read(host_ptr, asize, bo_offset);
|
||||
|
||||
#else
|
||||
|
||||
CHECK_ERR(xrtBOSync(xrtBuffer, XCL_BO_SYNC_BO_FROM_DEVICE, asize, bo_offset), {
|
||||
dump_xrt_error(device->xrtDevice, err);
|
||||
return -1;
|
||||
});
|
||||
|
||||
CHECK_ERR(xrtBORead(xrtBuffer, host_ptr, asize, bo_offset), {
|
||||
dump_xrt_error(device->xrtDevice, err);
|
||||
return -1;
|
||||
});
|
||||
|
||||
#endif
|
||||
|
||||
DBGPRINT("COPY_FROM_DEV: dev_addr=0x%lx, host_addr=0x%lx, size=%ld, bank=%d, offset=0x%lx\n", dev_maddr, (uintptr_t)host_ptr, asize, bo_index, bo_offset);
|
||||
DBGPRINT("COPY_FROM_DEV: dev_addr=0x%lx, host_addr=0x%lx, size=%ld\n", dev_maddr, (uintptr_t)host_ptr, asize);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -799,20 +861,11 @@ extern int vx_start(vx_device_h hdevice) {
|
|||
|
||||
//wait_for_enter("\nPress ENTER to continue after setting up ILA trigger...");
|
||||
|
||||
#ifdef CPP_API
|
||||
|
||||
device->xrtKernel.write_register(MMIO_CTL_ADDR, CTL_AP_START);
|
||||
|
||||
#else
|
||||
|
||||
CHECK_ERR(xrtKernelWriteRegister(device->xrtKernel, MMIO_CTL_ADDR, CTL_AP_START), {
|
||||
dump_xrt_error(device->xrtDevice, err);
|
||||
CHECK_ERR(device->write_register(MMIO_CTL_ADDR, CTL_AP_START), {
|
||||
return -1;
|
||||
});
|
||||
|
||||
#endif
|
||||
|
||||
DBGPRINT("START");
|
||||
DBGPRINT("START\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -838,25 +891,13 @@ extern int vx_ready_wait(vx_device_h hdevice, uint64_t timeout) {
|
|||
|
||||
for (;;) {
|
||||
uint32_t status = 0;
|
||||
|
||||
#ifdef CPP_API
|
||||
|
||||
status = device->xrtKernel.read_register(MMIO_CTL_ADDR);
|
||||
|
||||
#else
|
||||
|
||||
CHECK_ERR(xrtKernelReadRegister(device->xrtKernel, MMIO_CTL_ADDR, &status), {
|
||||
dump_xrt_error(device->xrtDevice, err);
|
||||
CHECK_ERR(device->read_register(MMIO_CTL_ADDR, &status), {
|
||||
return -1;
|
||||
});
|
||||
|
||||
#endif
|
||||
|
||||
bool is_done = (status & CTL_AP_DONE) == CTL_AP_DONE;
|
||||
if (is_done || 0 == timeout) {
|
||||
break;
|
||||
}
|
||||
|
||||
nanosleep(&sleep_time, nullptr);
|
||||
timeout -= sleep_time_ms;
|
||||
};
|
||||
|
@ -869,25 +910,14 @@ extern int vx_dcr_write(vx_device_h hdevice, uint32_t addr, uint64_t value) {
|
|||
return -1;
|
||||
|
||||
auto device = (vx_device*)hdevice;
|
||||
|
||||
#ifdef CPP_API
|
||||
|
||||
device->xrtKernel.write_register(MMIO_DCR_ADDR, addr);
|
||||
device->xrtKernel.write_register(MMIO_DCR_ADDR + 4, value);
|
||||
|
||||
#else
|
||||
|
||||
CHECK_ERR(xrtKernelWriteRegister(device->xrtKernel, MMIO_DCR_ADDR, addr), {
|
||||
dump_xrt_error(device->xrtDevice, err);
|
||||
CHECK_ERR(device->write_register(MMIO_DCR_ADDR, addr), {
|
||||
return -1;
|
||||
});
|
||||
|
||||
CHECK_ERR(xrtKernelWriteRegister(device->xrtKernel, MMIO_DCR_ADDR + 4, value), {
|
||||
dump_xrt_error(device->xrtDevice, err);
|
||||
CHECK_ERR(device->write_register(MMIO_DCR_ADDR + 4, value), {
|
||||
return -1;
|
||||
});
|
||||
|
||||
#endif
|
||||
|
||||
// save the value
|
||||
DBGPRINT("DCR_WRITE: addr=0x%x, value=0x%lx\n", addr, value);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue