目录
系统枚举伪代码
主机枚举
邻居节点枚举
系统枚举伪代码
// System enumeration and initialization using the power-on device ID as the hostDeviceID // —Discover the host first // —Discover the host’s neighbor recursively STATUS rioSystemEnumerate (hostDeviceID) { // Discover the host first. status = rioEnumerateHost (hostDeviceID); if (status == ERR_SLAVE) { rioClearUp (hostDeviceID); return ERR_SLAVE; } // Discover the host neighbor status = rioEnumerateNeighbor (hostDeviceID, hopCount = 1); if (status == ERR_SLAVE) { rioClearUp (hostDeviceID); return ERR_SLAVE; } // If the code advances to this point successfully, the host must acquire the // HostBaseDeviceIdLock for all devices in the system. When this is done, the Discovered bit // Master Enable bit, etc. can be set for all devices. } // end rioSystemEnumerate
主机枚举
STATUS rioEnumerateHost (hostDeviceID)
{ // Try to acquire the lock rioAcquireDeviceLock (0, hostDeviceID, 0, hostDeviceID); while (HostBaseDeviceIdLockCSR.HostBaseDeviceID < hostDeviceID) { // Delay for a while rioDelay (); // Retry lock acquisition rioAcquireDeviceLock (0, hostDeviceID, 0, hostDeviceID, &lockingHost); } // Check to see if there is a master with a larger host device ID if (HostBaseDeviceIdLock.HostBaseDeviceID > hostDeviceID) { // Release the current lock rioReleaseDeviceLock (0, hostDeviceID, 0, hostDeviceID); return ERR_SLAVE; } // Lock has been acquired so enumeration can begin // Assign the default host ID to the host rioSetBaseDeviceId (0, hostDeviceID, hostDeviceID); // Increment the available device ID if (DeviceID == hostDeviceID) { DeviceID ++; } return RIO_SUCCESS; } // end rioEnumerateHost
邻居节点枚举
STATUS rioEnumerateNeighbor (hostDeviceID, hopCount) { // The host has already discovered this node if it currently owns the lock rioGetCurHostLock (0, 0, 0, &owner_device_id); if (owner_device_id == hostDeviceID) { return RIO_SUCCESS; } // Try to acquire the lock rioAcquireDeviceLock (0, RIO_GEN_DFLT_DID, hopCount, hostDeviceID, &lockingHost); while (HostBaseDeviceIdLockCSR.HostBaseDeviceID < hostDeviceID) { // Delay for a while rioDelay (); // Retry lock acquisition rioAcquireDeviceLock(0, RIO_GEN_DFLT_DID, hopCount, hostDeviceID,&lockingHost); } // Check to see if there is a master with a larger host device ID if (HostBaseDeviceIdLock.HostBaseDeviceID > hostDeviceID) { return ERR_SLAVE; } // Lock has been acquired so enumeration can begin // Check Source Operation CAR and Destination Operation CAR to see if a Device ID can be // assigned rioGetSourceOps (0, RIO_GEN_DFLT_DID, hopCount, &SourceOperationCAR); rioGetDestOps (0, RIO_GEN_DFLT_DID, hopCount, &DestinationOperationCAR); if ( (SourceOperationCAR.Read || Write || Atomic) && (DestinationOperationCAR.Read || Write || Atomic)) { // Set the device ID rioSetBaseDeviceId (0, RIO_GEN_DFLT_DID, DeviceID); // Increment the available device ID DeviceID ++; if (DeviceID == hostDeviceID) { DeviceID ++; } } // Check to see if the device is a switch rioGetFeatures (0, RIO_GEN_DFLT_DID, hopCount, &ProcessingElementFeatureCAR); if (ProcessingElementFeatureCAR.Switch == TRUE) { // Read the switch information rioGetSwitchPortInfo (0, RIO_GEN_DFLT_DID, hopCount,&SwitchPortInformationCAR); // Record the switch device identity Switches[SwitchID].SwitchIdentity = DeviceIdentityCAR.DeviceIdentity; // Bookkeeping for the current switch ID curSwitchID = SwitchID; // Increment the available switch ID SwitchID ++; // Initialize the current switch routing table to add entries for all previously discovered // devices so that they are routed correctly. Start with the host device ID (0x00) and end with // DeviceID-1. for (each deviceID in [0..DeviceID-1]) { rioRouteAddEntry (0, RIO_GEN_DFLT_DID, hopCount, RIO_GEN_DFLT_DID, deviceID, SwitchPortInformationCAR.PortNumber, NULL); } // Synchronize the current switch routing table with the global table for (each deviceID in [0.. DeviceID-1]) { Switches[curSwitchID].RouteTable.LFT[deviceID] = SwitchPortInformationCAR.PortNumber; } // Update the hopCount to reach the current switch Switches[curSwitchID].HopCount = hopCount; for (each portNum in SwitchPortInformationCAR.PortTotal) { if (SwitchPortInformationCAR.PortNumber == portNum) { continue; }、 // Bookkeeping for the current available device ID curDeviceID = DeviceID; rioGetPortErrStatus (0, RIO_GEN_DFLT_DID, hopCount, &PortErrorStatusCSR[portNum]); // Check if it is possible to have a neighbor if (PortErrorStatusCSR[portNum].PortUninitialized == TRUE) { continue; } else if (PortErrorStatusCSR[portNum].PortOK == TRUE) { // Check if it is an enumeration boundary port if (PortControlCSR[portNum].PortEnumerationBoundary == TRUE) { continue; } rioRouteAddEntry(0, RIO_GEN_DFLT_DID, hopCount, RIO_GEN_DFLT_DID, 0, portNumber, NULL); // Discover the neighbor recursively if (status = rioEnumerateNeighbor(hopCount + 1) != RIO_SUCCESS) { return status; } // If more than one end point device was found, update the current switch routing table // entries beginning with the curDeviceID entry and ending with the DeviceID-1 // entry. if (DeviceID > curDeviceID) { for (each deviceID in [curDeviceID..DeviceID-1]) { rioRouteAddEntry(0, RIO_GEN_DFLT_DID, hopCount, deviceID,portNumber); } // Synchronize the current switch routing table with the global table for (each deviceID in [curDeviceID..DeviceID-1]) { Switches[curSwitchID].RouteTable.LFT[deviceID] = portNumber; } // Update the associated Device ID in the path. Switches[curSwitchID].DeviceID = curDeviceID; } // end if } // end else if } // end for } // end if (ProcessingElementFeatureCAR.Switch == TRUE) return RIO_SUCCESS; } // end rioEnumerateNeighbor