📄 xopbarb.c
字号:
}/*****************************************************************************//**** Assigns a master ID to the given priority level. The use of priority levels by* the device must be suspended before calling this function. Every master ID* must be assigned to one and only one priority level. The driver enforces* this before allowing use of priority levels by the device to be resumed.** @param InstancePtr is a pointer to the XOpbArb instance to be worked on.* @param Level is the priority level being set. The level can range from* 0 (highest) to N (lowest), where N is the number of masters minus* one. The device currently supports up to 16 masters.* @param MasterId is the ID of the master being assigned to the priority* level. The ID can range from 0 to N, where N is the number of* masters minus one. The device currently supports up to 16 masters.** @return** - XST_SUCCESS if the slave is selected successfully.* - XST_OPBARB_NOT_SUSPENDED if priority levels have not been suspended.* Before modifying the priority levels, use of priority levels by the device* must be suspended.* - XST_OPBARB_NOT_FIXED_PRIORITY if the arbiter is in dynamic mode. It must* be in fixed mode to modify the priority levels.** @note** None.*******************************************************************************/XStatus XOpbArb_SetPriorityLevel(XOpbArb *InstancePtr, Xuint8 Level, Xuint8 MasterId){ Xuint32 ControlReg; Xuint32 LvlOffset; /* priority level offset */ XASSERT_NONVOID(InstancePtr != XNULL); XASSERT_NONVOID(Level < InstancePtr->NumMasters); XASSERT_NONVOID(MasterId < InstancePtr->NumMasters); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* * Verify that priority registers have been invalidated (suspended) * before allowing a level to be set. */ ControlReg = XIo_In32(InstancePtr->BaseAddress + XOA_CR_OFFSET); if (ControlReg & XOA_CR_PRIORITY_VALID_MASK) { /* * Registers are valid, so priority levels have not been suspended */ return XST_OPBARB_NOT_SUSPENDED; } /* Verify that the arbiter is not in dynamic priority mode because * the priority registers will be changing because the h/w uses them * even when the priority valid bit is not set */ if (ControlReg & XOA_CR_DYNAMIC_ENABLE_MASK) { /* * Dynamic priority mode is active, don't allow priority changes */ return XST_OPBARB_NOT_FIXED_PRIORITY; } /* * Calculate the offset of the priority level register */ LvlOffset = XOA_LVLX_OFFSET + (Level * XOA_LVLX_SIZE); /* * Set the priority level register */ XIo_Out32(InstancePtr->BaseAddress + LvlOffset, MasterId); return XST_SUCCESS;}/*****************************************************************************//**** Get the master ID at the given priority level.** @param InstancePtr is a pointer to the XOpbArb instance to be worked on.* @param Level is the priority level being retrieved. The level can range* from 0 (highest) to N (lowest), where N is the number of masters* minus one. The device currently supports up to 16 masters.** @return** The master ID assigned to the given priority level. The ID can range from* 0 to N, where N is the number of masters minus one.** @note** If the arbiter is operating in dynamic priority mode, the value returned from* this function may not be predictable because the arbiter changes the* values on the fly.*******************************************************************************/Xuint8 XOpbArb_GetPriorityLevel(XOpbArb *InstancePtr, Xuint8 Level){ Xuint32 LvlOffset; /* priority level offset */ XASSERT_NONVOID(InstancePtr != XNULL); XASSERT_NONVOID(Level < InstancePtr->NumMasters); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* * Calculate the offset of the priority level register */ LvlOffset = XOA_LVLX_OFFSET + (Level * XOA_LVLX_SIZE); /* * Get the priority level register */ return (Xuint8)XIo_In32(InstancePtr->BaseAddress + LvlOffset);}/*****************************************************************************//**** Suspends use of the priority levels by the device. Before modifying priority* levels, the application must first suspend use of the levels by the device.* This is to prevent possible OPB problems if no master is assigned a priority* during the modification of priority levels. The application must resume use* of priority levels by the device when all modifications are done. During the* time priority levels are suspended, the device reverts to its default behavior* of assigning priorities based on master IDs.** This function can be used when the device is configured for either fixed* priority arbitration or dynamic priority arbitration. When used during* dynamic priority arbitration, the application can configure the priority* levels as a starting point for the LRU algorithm.** @param InstancePtr is a pointer to the XOpbArb instance to be worked on.** @return** None.** @note** None.*******************************************************************************/void XOpbArb_SuspendPriorityLevels(XOpbArb *InstancePtr){ Xuint32 ControlReg; XASSERT_VOID(InstancePtr != XNULL); XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* * Invalidate (suspend) priority level register use by the device */ ControlReg = XIo_In32(InstancePtr->BaseAddress + XOA_CR_OFFSET); XIo_Out32(InstancePtr->BaseAddress + XOA_CR_OFFSET, ControlReg & ~XOA_CR_PRIORITY_VALID_MASK);}/*****************************************************************************//**** Resumes use of the priority levels by the device. This function is typically* called sometime after a call to SuspendPriorityLevels. The application must* resume use of priority levels by the device when all modifications are done.* If no call is made to this function after use of the priority levels has been* suspended, the device will remain in its default priority arbitration mode of* assigning priorities based on master IDs. A call to this function has no* effect if no prior call was made to suspend the use of priority levels.** Every master must be represented by one and only one fixed priority level* before the use of priority levels can be resumed.** @param InstancePtr is a pointer to the XOpbArb instance to be worked on.** @return** - XST_SUCCESS if the slave is selected successfully.* - XST_OPBARB_INVALID_PRIORITY if there is either a master that is not* assigned a priority level, or a master that is assigned two mor more* priority levels.** @note** None.*******************************************************************************/XStatus XOpbArb_ResumePriorityLevels(XOpbArb *InstancePtr){ Xuint32 ControlReg; Xuint32 LvlReg; Xuint8 Master; Xuint8 Level; Xuint8 Found; Xuint16 MasterMask; XASSERT_NONVOID(InstancePtr != XNULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* * Verify that every master has one and only one entry in the priority * level registers. Build a mask where every bit represents a master * (up to 16 masters). The bit is set to 1 if the master is found in * a priority register, and a 0 otherwise. */ MasterMask = 0; for (Level = 0; Level < InstancePtr->NumMasters; Level++) { LvlReg = XOpbArb_GetPriorityLevel(InstancePtr, Level); MasterMask |= (1 << LvlReg); } /* * Now count how many are set */ Found = 0; for (Master = 0; Master < InstancePtr->NumMasters; Master++) { if (MasterMask & (1 << Master)) { Found++; } } if (Found != InstancePtr->NumMasters) { return XST_OPBARB_INVALID_PRIORITY; } /* * Validate (resume) priority level register use by the device */ ControlReg = XIo_In32(InstancePtr->BaseAddress + XOA_CR_OFFSET); XIo_Out32(InstancePtr->BaseAddress + XOA_CR_OFFSET, ControlReg | XOA_CR_PRIORITY_VALID_MASK); return XST_SUCCESS;}/*****************************************************************************//**** Sets the master ID used for bus parking. Bus parking must be enabled and the* option to use bus parking by park ID must be set for this park ID to take* effect (see the SetOptions function). If the option to use bus parking by park* ID is set but this function is not called, bus parking defaults to master 0.** @param InstancePtr is a pointer to the XOpbArb instance to be worked on.* @param MasterId is the ID of the master that will be parked if bus parking* is enabled. This master's grant signal remains asserted as long as* no other master requests the bus. The ID can range from 0 to N,* where N is the number of masters minus one. The device currently* supports up to 16 masters.** @return** XST_SUCCESS if the park ID is successfully set, or XST_NO_FEATURE if bus* parking is not supported by the device.** @note** None.*******************************************************************************/XStatus XOpbArb_SetParkId(XOpbArb *InstancePtr, Xuint8 MasterId){ Xuint32 ControlReg; XASSERT_NONVOID(InstancePtr != XNULL); XASSERT_NONVOID(MasterId < InstancePtr->NumMasters); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* * Verify that bus parking is included in the hardware. We determine * how the hardware is parameterized based on the read/write nature of the * park enable bit in the control register. */ ControlReg = XIo_In32(InstancePtr->BaseAddress + XOA_CR_OFFSET); if ((ControlReg & XOA_CR_PARK_RW_MASK) == 0) { /* * Park Enable bit is read-only, so bus parking is not included in * the device. */ return XST_NO_FEATURE; } /* * Set the park id, which is in the LSB of the control register */ XIo_Out32(InstancePtr->BaseAddress + XOA_CR_OFFSET, ControlReg | MasterId); return XST_SUCCESS;}/*****************************************************************************//**** Gets the master ID currently used for bus parking.** @param InstancePtr is a pointer to the XOpbArb instance to be worked on.* @param MasterIdPtr is a pointer to a byte that will hold the master ID* currently used for bus parking. This is an output parameter. The* ID can range from 0 to N, where N is the number of masters minus* one. The device currently supports up to 16 masters.** @return** XST_SUCCESS if the park ID is successfully retrieved, or XST_NO_FEATURE if* bus parking is not supported by the device.** @note** None.*******************************************************************************/XStatus XOpbArb_GetParkId(XOpbArb *InstancePtr, Xuint8 *MasterIdPtr){ Xuint32 ControlReg; XASSERT_NONVOID(InstancePtr != XNULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* * Verify that bus parking is included in the hardware. We determine * how the hardware is parameterized based on the read/write nature of the * park enable bit in the control register. */ ControlReg = XIo_In32(InstancePtr->BaseAddress + XOA_CR_OFFSET); if ((ControlReg & XOA_CR_PARK_RW_MASK) == 0) { /* * Park Enable bit is read-only, so bus parking is not included in * the device. */ return XST_NO_FEATURE; } /* * Store the park id, which is stored in the LSB of the control register */ *MasterIdPtr = (Xuint8)(ControlReg & XOA_CR_PARK_ID_MASK); return XST_SUCCESS;}/*****************************************************************************//**** Looks up the device configuration based on the unique device ID. The table* OpbArbConfigTable contains the configuration info for each device in the* system.** @param DeviceId is the unique device ID to match on.** @return** A pointer to the configuration information for the matching device instance,* or XNULL if no match is found.** @note** None.*******************************************************************************/XOpbArb_Config *XOpbArb_LookupConfig(Xuint16 DeviceId){ extern XOpbArb_Config XOpbArb_ConfigTable[]; XOpbArb_Config *CfgPtr = XNULL; int i; for (i=0; i < XPAR_XOPBARB_NUM_INSTANCES; i++) { if (XOpbArb_ConfigTable[i].DeviceId == DeviceId) { CfgPtr = &XOpbArb_ConfigTable[i]; break; } } return CfgPtr;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -