Exemple #1
0
/**
*
* Read the specified number of bytes from the data buffer of the ACE
* controller. The data buffer, which is 32 bytes, can only be read two bytes
* at a time.  Once the data buffer is read, we wait for it to be filled again
* before reading the next buffer's worth of data.
*
* @param BaseAddress is the base address of the device
* @param BufferPtr is a pointer to a buffer in which to store data.
* @param Size is the number of bytes to read
*
* @return
*
* The total number of bytes read, or 0 if an error occurred.
*
* @note
*
* If Size is not aligned with the size of the data buffer (32 bytes), this
* function will read the entire data buffer, dropping the extra bytes on the
* floor since the user did not request them. This is necessary to get the
* data buffer to be ready again.
*
******************************************************************************/
int XSysAce_ReadDataBuffer(Xuint32 BaseAddress, Xuint8 *BufferPtr, int Size)
{
    int DataBytes;         /* number of data bytes written */
    int BufferBytes;
    Xuint16 Data;

    /*
     * Read data two bytes at a time. We need to wait for the data
     * buffer to be ready before reading the buffer.
     */
    BufferBytes = 0;
    for (DataBytes = 0; DataBytes < Size;)
    {
        /*
         * If at any point during this read an error occurs, exit early
         */
        if (XSysAce_mGetErrorReg(BaseAddress) != 0)
        {
            return 0;
        }

        if (BufferBytes == 0)
        {
            /*
             * Wait for CF data buffer to ready, then reset buffer byte count
             */
            while ((XSysAce_mGetStatusReg(BaseAddress)
                    & XSA_SR_DATABUFRDY_MASK) == 0);

            BufferBytes = XSA_DATA_BUFFER_SIZE;
        }

        /*
         * Need to read two bytes. Put the first one in the output buffer
         * because if we're here we know one more is needed. Put the second one
         * in the output buffer if there is still room, or just drop it on the
         * floor if the requested number of bytes have already been read.
         */
        Data = XSysAce_RegRead16(BaseAddress + XSA_DBR_OFFSET);
        *BufferPtr++ = (Xuint8)Data;
        DataBytes++;

        if (DataBytes < Size)
        {
            /* Still more room in the output buffer */
            *BufferPtr++ = (Xuint8)(Data >> 8);
            DataBytes++;
        }

        BufferBytes -= 2;
    }
Exemple #2
0
static unsigned int XSysAce_GetCfgAddr(XSysAce * InstancePtr)
{
	u32 Status;

	XASSERT_NONVOID(InstancePtr != NULL);
	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);

	Status = XSysAce_mGetControlReg(InstancePtr->BaseAddress);
	if (!(Status & XSA_CR_FORCECFGADDR_MASK))
		Status = XSysAce_mGetStatusReg(InstancePtr->BaseAddress);

	return (unsigned int)((Status & XSA_SR_CFGADDR_MASK) >>
			      XSA_CR_CFGADDR_SHIFT);
}
Exemple #3
0
/**
*
* The interrupt handler for the System ACE driver. This handler must be
* connected by the user to an interrupt controller or source. This function
* does not save or restore context.
*
* This function continues reading or writing to the compact flash if such an
* operation is in progress, and notifies the upper layer software through
* the event handler once the operation is complete or an error occurs. On an
* error, any command currently in progress is aborted.
*
* @param InstancePtr is a pointer to the XSysAce instance that just interrupted.
*
* @return
*
* None.
*
* @note
*
* None.
*
******************************************************************************/
void
XSysAce_InterruptHandler(void *InstancePtr)
{
	u32 StatusReg;
	XSysAce *AcePtr = (XSysAce *) InstancePtr;

	XASSERT_VOID(InstancePtr != NULL);

	/*
	 * Get the status in order to process each interrupt that has occurred
	 */
	StatusReg = XSysAce_mGetStatusReg(AcePtr->BaseAddress);

	/*
	 * Reset the interrupt line to effectively clear the interrupt conditions.
	 * We need to set the bit to clear the interrupts, then clear the bit so
	 * that new interrupts can be generated.
	 */
	XSysAce_mOrControlReg(AcePtr->BaseAddress, XSA_CR_RESETIRQ_MASK);
	XSysAce_mAndControlReg(AcePtr->BaseAddress, ~XSA_CR_RESETIRQ_MASK);

	/*
	 * Check for data buffer ready, which means an operation (either read or
	 * write) is in progress.
	 */
	if (StatusReg & XSA_SR_DATABUFRDY_MASK) {
		/*
		 * Handles the data buffer, and invokes the callback to the user for
		 * data transfer completion.
		 */
		HandleDataBuffer(AcePtr, StatusReg);
	}

	/*
	 * Check for completion of JTAG configuration and report the event up.
	 * We only do this if the CFGDONE interrupt is enabled since the CFGDONE
	 * status only gets cleared when the confguration controller is reset,
	 * which we do not do unless requested by the user because it may cause
	 * a configuration process to start. We could have gotten into this
	 * interrupt handler by another interrupt, yet have a leftover CFGDONE
	 * status from an earlier configuration process.
	 */
	if ((StatusReg & XSA_SR_CFGDONE_MASK) &&
	    (XSysAce_mGetControlReg(AcePtr->BaseAddress) &
	     XSA_CR_CFGDONEIRQ_MASK)) {
		/*
		 * Clear the bit indicating MPU is the source of configuration data
		 * since we're done configuring from the MPU for now. Also clear the
		 * force CFGMODE bit and the CFGSTART bit, basically undoing what was
		 * done in XSysAce_ProgramChain(). Disable the interrupts since the
		 * CFGDONE status does not get cleared unless a reset occurs - and in
		 * the meantime we may get into this interrupt handler again.
		 */
		XSysAce_mAndControlReg(AcePtr->BaseAddress,
				       ~(XSA_CR_CFGSEL_MASK |
					 XSA_CR_CFGSTART_MASK |
					 XSA_CR_CFGDONEIRQ_MASK |
					 XSA_CR_DATARDYIRQ_MASK |
					 XSA_CR_FORCECFGMODE_MASK));

		AcePtr->EventHandler(AcePtr->EventRef, XSA_EVENT_CFG_DONE);
	}

	/*
	 * Check for errors and report the event (the user is responsible for
	 * retrieving and interpreting the errors). We only do this if the error
	 * interrupt is enabled since the error status only gets cleared when the
	 * CompactFlash or confguration controller is reset, which we do not do
	 * because it may cause a configuration process to start. We could have
	 * entered this interrupt handler by another interrupt and have a leftover
	 * error status from a previous error.
	 */
	if ((StatusReg & (XSA_SR_CFGERROR_MASK | XSA_SR_CFCERROR_MASK)) &&
	    (XSysAce_mGetControlReg(AcePtr->BaseAddress) &
	     XSA_CR_ERRORIRQ_MASK)) {
		/* Clear the transfer state to effectively abort the operation */
		AcePtr->NumRequested = 0;
		AcePtr->NumRemaining = 0;
		AcePtr->BufferPtr = NULL;

		/*
		 * Disable the error interrupt since the only way to clear the
		 * error status is to reset the CF or the configuration controller,
		 * neither of which we want to do here since the consequences may
		 * be undesirable (i.e., may cause a reconfiguration). The user
		 * will need to perform the reset based on the error event.
		 */
		XSysAce_mAndControlReg(AcePtr->BaseAddress,
				       ~XSA_CR_ERRORIRQ_MASK);

		AcePtr->EventHandler(AcePtr->EventRef, XSA_EVENT_ERROR);
	}
}
Exemple #4
0
/**
*
* Attempt to lock access to the CompactFlash. The CompactFlash may be accessed
* by the MPU port as well as the JTAG configuration port within the System ACE
* device. This function requests exclusive access to the CompactFlash for the
* MPU port. This is a non-blocking request. If access cannot be locked
* (because the configuration controller has the lock), an appropriate status is
* returned. In this case, the user should call this function again until
* successful.
*
* If the user requests a forced lock, the JTAG configuration controller will
* be put into a reset state in case it currently has a lock on the CompactFlash.
* This effectively aborts any operation the configuration controller had in
* progress and makes the configuration controller restart its process the
* next time it is able to get a lock.
*
* A lock must be granted to the user before attempting to read or write the
* CompactFlash device.
*
* @param InstancePtr is a pointer to the XSysAce instance to be worked on.
* @param Force is a boolean value that, when set to TRUE, will force the MPU
*        lock to occur in the System ACE.  When set to FALSE, the lock is
*        requested and the device arbitrates between the MPU request and
*        JTAG requests. Forcing the MPU lock resets the configuration
*        controller, thus aborting any configuration operations in progress.
*
* @return
*
* XST_SUCCESS if the lock was granted, or XST_DEVICE_BUSY if the lock was
* not granted because the configuration controller currently has access to
* the CompactFlash.
*
* @note
*
* If the lock is not granted to the MPU immediately, this function removes its
* request for a lock so that a lock is not later granted at a time when the
* application is (a) not ready for the lock, or (b) cannot be informed
* asynchronously about the granted lock since there is no such interrupt event.
*
******************************************************************************/
XStatus XSysAce_Lock(XSysAce * InstancePtr, u32 Force)
{
	u32 IsLocked;

	XASSERT_NONVOID(InstancePtr != NULL);
	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);

	/*
	 * Check to see if the configuration controller currently has the lock
	 */
	IsLocked = (XSysAce_mGetStatusReg(InstancePtr->BaseAddress) &
		    XSA_SR_CFGLOCK_MASK);

	if (Force) {
		/*
		 * Reset the configuration controller if it has the lock. Per ASIC
		 * designer, this eliminates a potential deadlock if the FORCELOCK and
		 * LOCKREQ bits are both set and the RDYFORCFCMD is not set.
		 */
		if (IsLocked) {
			/* Reset the configuration controller */
			XSysAce_mOrControlReg(InstancePtr->BaseAddress,
					      XSA_CR_CFGRESET_MASK);
		}

		/* Force the MPU lock. The lock will occur immediately. */
		XSysAce_mOrControlReg(InstancePtr->BaseAddress,
				      XSA_CR_LOCKREQ_MASK |
				      XSA_CR_FORCELOCK_MASK);
	} else {
		/*
		 * Check to see if the configuration controller has the lock. If so,
		 * return a busy status.
		 */
		if (IsLocked) {
			return XST_DEVICE_BUSY;
		}

		/* Request the lock, but do not force it */
		XSysAce_mOrControlReg(InstancePtr->BaseAddress,
				      XSA_CR_LOCKREQ_MASK);
	}

	/*
	 * See if the lock was granted. Note that it is guaranteed to occur if
	 * the user forced it.
	 */
	if (!XSysAce_mIsMpuLocked(InstancePtr->BaseAddress)) {
		/* Lock was not granted, so remove request and return a busy */
		XSysAce_mAndControlReg(InstancePtr->BaseAddress,
				       ~(XSA_CR_LOCKREQ_MASK |
					 XSA_CR_FORCELOCK_MASK));

		return XST_DEVICE_BUSY;
	}

	/*
	 * Lock has been granted.
	 *
	 * If the configuration controller had the lock and has been reset,
	 * go ahead and release it from reset as it will not be able to get
	 * the lock again until the MPU lock is released.
	 */
	if (IsLocked && Force) {
		/* Release the reset of the configuration controller */
		XSysAce_mAndControlReg(InstancePtr->BaseAddress,
				       ~XSA_CR_CFGRESET_MASK);
	}

	return XST_SUCCESS;
}