20#include "experimental/xrt_bo.h"
21#include "experimental/xrt_device.h"
22#include "experimental/xrt_ip.h"
23#include "experimental/xrt_xclbin.h"
39std::unique_ptr<AcceleratorConnection>
42 std::string device_id;
45 constexpr char SEP =
';';
47 constexpr char SEP =
':';
50 size_t sep = connectionString.find(SEP);
51 if (sep == std::string::npos) {
52 xclbin = connectionString;
54 xclbin = connectionString.substr(0, sep);
55 device_id = connectionString.substr(sep + 1);
60 throw std::runtime_error(
61 std::string(
"connection string must be of the form ") +
"'<xclbin>[" +
62 SEP +
"<device_id>]': xclbin path cannot be empty");
63 if (sep != std::string::npos && device_id.empty())
64 throw std::runtime_error(
65 std::string(
"connection string must be of the form ") +
"'<xclbin>[" +
66 SEP +
"<device_id>]': device_id cannot be empty");
68 return make_unique<XrtAccelerator>(
ctxt, xclbin, device_id);
74 Impl(std::string xclbin, std::string device_id) {
75 if (device_id.empty())
78 device = ::xrt::device(device_id);
81 ::xrt::xclbin xcl(xclbin);
82 std::optional<::xrt::xclbin::mem> host_mem;
83 for (
auto mem : xcl.get_mems()) {
86 if (mem.get_tag().starts_with(
"HOST")) {
87 if (host_mem.has_value())
88 throw std::runtime_error(
"Multiple host memories found in xclbin");
94 throw std::runtime_error(
"No host memory found in xclbin");
98 auto uuid =
device.load_xclbin(xcl);
109 std::string device_id)
111 impl = make_unique<Impl>(xclbin, device_id);
119class XrtMMIO :
public MMIO {
122 constexpr static uint32_t IndirectLocation = 0x18;
125 constexpr static uint32_t IndirectMMIOReg = 0x20;
130 :
MMIO(conn, idPath, clients), ip(ip) {}
132 uint64_t read(uint32_t addr)
const override {
133 std::lock_guard<std::mutex> lock(m);
136 xrt_write(IndirectLocation, addr);
138 uint64_t ret = xrt_read(IndirectMMIOReg);
140 getConnection().getLogger().debug(
141 [addr, ret](std::string &subsystem, std::string &msg,
142 std::unique_ptr<std::map<std::string, std::any>> &details) {
143 subsystem =
"xrt_mmio";
144 msg =
"MMIO[0x" +
toHex(addr) +
"] = 0x" +
toHex(ret);
148 void write(uint32_t addr, uint64_t data)
override {
149 std::lock_guard<std::mutex> lock(m);
152 xrt_write(IndirectLocation, addr);
154 xrt_write(IndirectMMIOReg, data);
156 conn.getLogger().debug(
158 data](std::string &subsystem, std::string &msg,
159 std::unique_ptr<std::map<std::string, std::any>> &details) {
160 subsystem =
"xrt_mmio";
161 msg =
"MMIO[0x" +
toHex(addr) +
"] <- 0x" +
toHex(data);
166 uint64_t xrt_read(uint32_t addr)
const {
167 auto lo =
static_cast<uint64_t
>(ip.read_register(addr));
168 auto hi =
static_cast<uint64_t
>(ip.read_register(addr + 0x4));
169 return (hi << 32) | lo;
172 void xrt_write(uint32_t addr, uint64_t data)
const {
173 ip.write_register(addr, data);
174 ip.write_register(addr + 0x4, data >> 32);
179 mutable std::mutex m;
185class XrtHostMem :
public HostMem {
187 XrtHostMem(
XrtAccelerator &conn, ::xrt::device &device, int32_t memoryGroup)
188 :
HostMem(
conn), device(device), memoryGroup(memoryGroup) {}
190 struct XrtHostMemRegion :
public HostMemRegion {
191 XrtHostMemRegion(::xrt::device &device, std::size_t size,
193 bo = ::xrt::bo(device, size, ::xrt::bo::flags::host_only, memoryGroup);
198 virtual void *getPtr()
const override {
return ptr; }
201 virtual void *getDevicePtr()
const override {
return (
void *)bo.address(); }
202 virtual std::size_t getSize()
const override {
return bo.size(); }
205 virtual void flush()
override { bo.sync(XCL_BO_SYNC_BO_TO_DEVICE); }
212 std::unique_ptr<HostMemRegion>
214 return std::unique_ptr<HostMemRegion>(
215 new XrtHostMemRegion(device, size, opts, memoryGroup));
219 ::xrt::device &device;
225 std::string implName,
228 if (svcType ==
typeid(
MMIO))
229 return new XrtMMIO(*
this,
impl->ip,
id, clients);
230 else if (svcType ==
typeid(
HostMem))
231 return new XrtHostMem(*
this,
impl->device,
impl->memoryGroup);
232 else if (svcType ==
typeid(
SysInfo))
#define REGISTER_ACCELERATOR(Name, TAccelerator)
Abstract class representing a connection to an accelerator.
Context & ctxt
ESI accelerator context.
virtual void disconnect()
Disconnect from the accelerator cleanly.
AcceleratorConnections, Accelerators, and Manifests must all share a context.
Connect to an ESI simulation.
XrtAccelerator(Context &, std::string xclbin, std::string kernelName)
Construct and connect to a cosim server.
static std::unique_ptr< AcceleratorConnection > connect(Context &, std::string connectionString)
Parse the connection std::string and instantiate the accelerator.
std::unique_ptr< Impl > impl
virtual Service * createService(Service::Type service, AppIDPath path, std::string implName, const ServiceImplDetails &details, const HWClientDetails &clients) override
Called by getServiceImpl exclusively.
Implement the SysInfo API for a standard MMIO protocol.
Parent class of all APIs modeled as 'services'.
const std::type_info & Type
Information about the Accelerator system.
std::map< std::string, std::any > ServiceImplDetails
std::string toHex(void *val)
std::vector< HWClientDetail > HWClientDetails
static constexpr char kernel_name[]
Impl(std::string xclbin, std::string device_id)
Options for allocating host memory.