34rpx::XvcConnection::XvcConnection(
int sd,
int wakeFd,
JtagDriver* drv, uint64_t maxVecLen)
38 maxVecLen_(maxVecLen),
41 socklen_t sz =
sizeof(peer_);
44 if ((sd_ = ::accept(sd,
reinterpret_cast<struct sockaddr*
>(&peer_), &sz)) < 0)
51 if (setsockopt(sd_, IPPROTO_TCP, TCP_NODELAY, &yes,
sizeof(yes))) {
57#if defined(__APPLE__) && defined(SO_NOSIGPIPE)
62 if (setsockopt(sd_, SOL_SOCKET, SO_NOSIGPIPE, &nosigpipe,
sizeof(nosigpipe))) {
66 "setsockopt(SO_NOSIGPIPE) failed"));
75ssize_t rpx::XvcConnection::readTo(
void* buf,
size_t count) {
76 if (sd_ < 0 || sd_ >= FD_SETSIZE || (wakeFd_ >= 0 && wakeFd_ >= FD_SETSIZE)) {
81 if (wakeFd_ >= 0 && wakeFd_ >= sd_) maxFd = wakeFd_ + 1;
94 if (wakeFd_ >= 0) FD_SET(wakeFd_, &rset);
97 nready = ::select(maxFd, &rset,
nullptr,
nullptr,
nullptr);
99 if (nready >= 0)
break;
100 if (errno == EINTR)
continue;
104 if (wakeFd_ >= 0 && FD_ISSET(wakeFd_, &rset)) {
107 if (FD_ISSET(sd_, &rset)) {
110 r = ::read(sd_, buf, count);
111 }
while (r < 0 && errno == EINTR);
120 lastErrno_ = ENODATA;
164void rpx::XvcConnection::allocBufs() {
165 uint64_t overhead = 128;
168 uint64_t tgtVecLen = drv_->query();
170 if (0 == tgtVecLen) {
172 tgtVecLen = maxVecLen_;
176 supVecLen_ = drv_->getMaxVectorSize();
178 if (supVecLen_ == 0) {
180 supVecLen_ = tgtVecLen;
181 }
else if (tgtVecLen < supVecLen_) {
182 supVecLen_ = tgtVecLen;
185 chunk_ = (2 * maxVecLen_ + overhead);
187 rxb_.resize(
static_cast<size_t>(2 * chunk_));
188 txb_.resize(
static_cast<size_t>(maxVecLen_ + overhead));
195void rpx::XvcConnection::flush() {
196 uint8_t* p = &txb_[0];
199 size_t toSend =
static_cast<size_t>(tl_);
202#if defined(__APPLE__)
203 put = ::send(sd_, p, toSend, 0);
205 put = ::send(sd_, p, toSend, MSG_NOSIGNAL);
207 }
while (put < 0 && errno == EINTR);
211 "send() failed: %s (errno %d)", strerror(e), e));
215 tl_ -=
static_cast<uint64_t
>(put);
219void rpx::XvcConnection::run() {
221 uint64_t bitsLeft = 0, bitsSent = 0;
228 while (!drv_->isDone()) {
230 ssize_t got = readTo(rp_,
static_cast<size_t>(chunk_));
235 "socket/select error: %s (errno %d)", strerror(lastErrno_), lastErrno_));
237 rl_ =
static_cast<uint64_t
>(got);
242 if (0 == ::memcmp(rp_,
"ge", 2)) {
248 reinterpret_cast<char*
>(&txb_[0]), txb_.size(),
"xvcServer_v1.0:%" PRIu64
"\n", maxVecLen_);
251 tl_ = (
static_cast<uint64_t
>(slen) < txb_.size())
252 ?
static_cast<uint64_t
>(slen)
256 }
else if (0 == ::memcmp(rp_,
"se", 2)) {
259 uint32_t requestedPeriod = (
static_cast<uint32_t
>(rp_[10]) << 24) |
260 (
static_cast<uint32_t
>(rp_[9]) << 16) |
261 (
static_cast<uint32_t
>(rp_[8]) << 8) |
262 static_cast<uint32_t
>(rp_[7]);
264 uint32_t newPeriod = drv_->setPeriodNs(requestedPeriod);
266 for (
size_t u = 0; u <
sizeof(newPeriod); u++) {
267 txb_[u] =
static_cast<uint8_t
>(newPeriod);
268 newPeriod = newPeriod >> 8;
274 }
else if (0 == ::memcmp(rp_,
"sh", 2)) {
277 bits = (
static_cast<uint32_t
>(rp_[9]) << 24) |
278 (
static_cast<uint32_t
>(rp_[8]) << 16) |
279 (
static_cast<uint32_t
>(rp_[7]) << 8) |
280 static_cast<uint32_t
>(rp_[6]);
281 bytes = (
static_cast<uint64_t
>(bits) + 7) / 8;
283 if (bytes > maxVecLen_)
289 vecLen = bytes > supVecLen_ ? supVecLen_ : bytes;
293 "supported vector length is zero — cannot chunk shift"));
299 for (off = 0, bitsLeft = bits; bitsLeft > 0; bitsLeft -= bitsSent, off += vecLen) {
300 bitsSent = 8 * vecLen;
301 if (bitsLeft < bitsSent) {
305 drv_->sendVectors(bitsSent,
306 rp_ +
static_cast<ptrdiff_t
>(off),
307 rp_ +
static_cast<ptrdiff_t
>(bytes + off),
308 &txb_[0] +
static_cast<ptrdiff_t
>(off));