static uint32_t readXLinkStateReg(const Node *node, const XLink &xLink) { unsigned value = 0; if (node->getType() == Node::XS1_G) { setBitRange(value, xLink.getInterTokenDelay(), 3, 0); setBitRange(value, xLink.getInterSymbolDelay(), 11, 8); } else { setBitRange(value, xLink.getInterTokenDelay(), 10, 0); setBitRange(value, xLink.getInterSymbolDelay(), 21, 11); } bool isConnected = xLink.isConnected(); if (node->getType() != Node::XS1_G) { setBit(value, isConnected, 25); setBit(value, isConnected, 26); } setBit(value, xLink.isFiveWire(), 30); setBit(value, xLink.isEnabled(), 31); return value; }
ChanEndpoint *Node::getChanendDest(ResourceID ID) { Node *node = this; // Use Brent's algorithm to detect cycles. Node *tortoise = node; unsigned hops = 0; unsigned leapCount = 8; while (1) { unsigned destNode = ID.node() >> node->getCoreNumberBits(); unsigned diff = destNode ^ node->getNodeID(); if (diff == 0) break; // Lookup direction unsigned bit = countLeadingZeros(diff) + getNodeNumberBits() - 32; unsigned direction = directions[bit]; // Lookup Xlink. XLink *xLink = getXLinkForDirection(direction); if (!xLink || !xLink->isConnected()) return 0; node = xLink->destNode; ++hops; // Junk message if a cycle is detected. if (node == tortoise) return 0; if (hops == leapCount) { leapCount <<= 1; tortoise = node; } } if (ID.isConfig() && ID.num() == RES_CONFIG_SSCTRL) { return &node->sswitch; } unsigned destCore = ID.node() & makeMask(node->getCoreNumberBits()); if (destCore >= node->cores.size()) return 0; ChanEndpoint *dest = 0; node->getCores()[destCore]->getLocalChanendDest(ID, dest); return dest; }