⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hal.c

📁 Freescale ARM11系列CPU MX31的WINCE 5.0下的BSP
💻 C
📖 第 1 页 / 共 5 页
字号:
            {
                if ( ulLength > psDownload->ulSizeXferArea )
                {
                    ulLength = psDownload->ulSizeXferArea;
                }

                
                vHALwriteIMem( psHAL, 
                               psDownload->ulAddrXferArea + HAL_IMEM_BASE, 
                               (PULONG)&psDownload->paucImage[psDownload->ulOffset], 
                               ulLength );

                
                ulValue = HAL_BYTES_TO_DWORDS(ulLength);
                vHALwriteMailbox( psHAL, CHI_ADDR_XFER_LEN, &ulValue, sizeof(ULONG) );

                ulValue = CHI_BOOT_DATA;
                vHALwriteMailbox( psHAL, CHI_ADDR_XFER_CTRL(psDownload->ulCPU), &ulValue, sizeof(ULONG) );

                // Release mailbox semaphore.
                vHALreleaseSemaphore( psHAL, HAL_MAILBOX_0 );

                psDownload->ulOffset += ulLength;

                DBG_LEV2(("Transferred %ld bytes to IMEM.\n", ulLength));
            }
        }
        else if ( ulXferCtrl == CHI_BOOT_DATA )
        {
            vHALreleaseSemaphore( psHAL, HAL_MAILBOX_0 );
            DBG_LEV0(("Target still processing - no action\n"));
        }
        else
        {
            // Release mailbox semaphore.
            vHALreleaseSemaphore( psHAL, HAL_MAILBOX_0 );

            DBG_LEV0(("ERROR: Device not ready or processing: %lu.\n", ulXferCtrl));

            vHALstop( psHAL );
        }
    }
}


//-----------------------------------------------------------------------------
//
// NAME     vHALcheckForBootWaiting
//
// PARAMETERS  psHAL    Pointer to HAL context.
//
// DESCRIPTION This handler is called from interrupt DPC in 'starting' state.
//
//-----------------------------------------------------------------------------
VOID
vHALcheckForBootWaiting( IN PHAL_CONTEXT psHAL )
{
    ULONG   ulXferCtrl, ulValue;

    DBG_LEV1(("vHALcheckForBootWaiting()\n"));

    // Acquire semaphore before accessing mailbox.
    if ( boHALacquireSemaphore( psHAL, HAL_MAILBOX_0 ) )
    {
        vHALreadMailbox( psHAL, CHI_ADDR_XFER_CTRL(CHI_UPPER_CPU), &ulXferCtrl, sizeof(ULONG) );

        if ( ulXferCtrl == CHI_BOOT_WAITING )
        {
            psHAL->eState = HAL_AWAITING_CHI_MAGIC;

            /*
            * We have receive boot waiting from all processors that we have enabled.
            * Now write boot go to the transfer control and wait for the HIM to set
            * up the Host Interface area.
            */
            ulValue = CHI_BOOT_GO;
            vHALwriteMailbox( psHAL, CHI_ADDR_XFER_CTRL(CHI_UPPER_CPU), &ulValue, sizeof(ULONG) );

            // Release mailbox semaphore.
            vHALreleaseSemaphore( psHAL, HAL_MAILBOX_0 );
        }
        else
        {
            // Release mailbox semaphore.
            vHALreleaseSemaphore( psHAL, HAL_MAILBOX_0 );

            DBG_LEV0(("ERROR: Couldn't read boot waiting from device.\n"));

            vHALstop( psHAL );
        }
    }
}


//-----------------------------------------------------------------------------
//
// NAME     vHALcheckForChiMagic
//
// PARAMETERS  psHAL    Pointer to HAL context.
//
// DESCRIPTION This handler is called from interrupt DPC in the state 
//          'awaiting chi magic'.
//
//-----------------------------------------------------------------------------
VOID
vHALcheckForChiMagic( IN PHAL_CONTEXT psHAL )
{
    ULONG         ulN, ulMagic;
    PHAL_CHI      psCHI = &psHAL->sCHI;
    PEND_CONTEXT  psAdapter = psHAL->psAdapter;

    DBG_LEV1(("vHALcheckForChiMagic()\n"));

    // Acquire semaphore before accessing mailbox.
    if ( boHALacquireSemaphore( psHAL, HAL_MAILBOX_0 ) )
    {
        vHALreadMailbox( psHAL, CHI_ADDR_MAGIC, &ulMagic, sizeof(ULONG) );

        if ( ulMagic == HOST_MAGIC )
        {
            vHALreadMailbox( psHAL, CHI_ADDR_N, &ulN, sizeof(ULONG) );

            // Release mailbox semaphore.
            vHALreleaseSemaphore( psHAL, HAL_MAILBOX_0 );

            psCHI->ulN = ulN;
            psCHI->ulAddrReqResHead = CHI_ADDR_REQ_RES_HEAD(0, ulN);
            psCHI->ulAddrReqResTail = CHI_ADDR_REQ_RES_TAIL(0, ulN);
            psCHI->ulAddrReqResQ = CHI_ADDR_REQ_RES_Q(0, ulN);
            psCHI->ulAddrCfmIndHead = CHI_ADDR_CFM_IND_HEAD(0, ulN);
            psCHI->ulAddrCfmIndTail = CHI_ADDR_CFM_IND_TAIL(0, ulN);
            psCHI->ulAddrCfmIndQ = CHI_ADDR_CFM_IND_Q(0, ulN);

            psCHI->ulReqResTail = 0;
            psCHI->ulCfmIndHead = 0;

            DBG_LEV2(("CFHI Area N = %ld\n", psCHI->ulN));

            // Tx, Rx buffer configuration (0, 1, 2).
            psHAL->ulTxRxBufConfig = psAdapter->sCFG.ulBufferConfig;

            psHAL->ulRxBufNum = aTxRxBufCfg[ psHAL->ulTxRxBufConfig ][0];
            psHAL->ulTxBufNum = aTxRxBufCfg[ psHAL->ulTxRxBufConfig ][1];
            psHAL->ulTxRxBufSize = aTxRxBufCfg[ psHAL->ulTxRxBufConfig ][2];

            // Initialize Tx and Rx buffer.
            vHALinitTxRxBuffer( psHAL );

            psHAL->eState = HAL_RUNNING;

            // Now check for message.
            while (bHALreceiveMessage( psHAL ) == TRUE);
        }
        else
        {
            vHALreleaseSemaphore( psHAL, HAL_MAILBOX_0 );
            DBG_LEV0(("Target still processing - no action\n"));
        }
    }
}


//-----------------------------------------------------------------------------
//
// NAME     boHALdownload
//
// PARAMETERS  psHAL    Pointer to HAL context.
//
// RETURNS     TRUE if downloaded F/W successfully; FALSE otherwise.
//
// DESCRIPTION This function downloads F/W to Target.
//
//-----------------------------------------------------------------------------
BOOLEAN
boHALdownload( IN PHAL_CONTEXT psHAL, IN BOOLEAN boStart )
{
    ULONG   i, ulValue, ulTimeout, ulDelay;
    BOOLEAN boStatus = FALSE;

    // Begin to download the first F/W.
    vHALbeginDownload( psHAL, CHI_UPPER_CPU );

    // The value of ulDelay should never be greater than 50 (microseconds).
    ulDelay = 1;
    ulTimeout = END_INITIAL_TIMEOUT * (1000 / ulDelay);

    for ( i=0; i<ulTimeout; i++ )
    {
        OS_DELAY_MS( ulDelay );

        // Read interrupt status.
        vHALreadRegister( psHAL, HAL_ADDR_interrput_arm_to_host, &ulValue );

        if ( ulValue & HAL_MASK_interrupt_arm_to_host )
        {
            // Clear interrupt status.
            vHALwriteRegister( psHAL, HAL_ADDR_interrput_arm_to_host, ulValue );

            switch ( psHAL->eState )
            {
                case HAL_STOPPED:
                case HAL_READY_TO_DOWNLOAD_1ST:
                case HAL_READY_TO_DOWNLOAD_NTH:
                DBG_LEV1(("WARNING: Got interrupt in unexpected state, %d\n", psHAL->eState));
                break;

                case HAL_AWAITING_BOOT_MAGIC:
                vHALcheckForBootMagic( psHAL );
                break;

                case HAL_DOWNLOADING:
                vHALcontinueDownload( psHAL );
                break;

                case HAL_STARTING:
                vHALcheckForBootWaiting( psHAL );
                break;

                case HAL_AWAITING_CHI_MAGIC:
                    vHALcheckForChiMagic( psHAL );
                break;

                case HAL_RUNNING:
                    while (bHALreceiveMessage( psHAL ) == TRUE);
                break;
            }

            if ( psHAL->eState == HAL_STOPPED || 
                 (psHAL->eState == HAL_RUNNING && psHAL->psAdapter->boGetPermanentAddress) )
                break;
        }
        else if ((boStart != TRUE) && (psHAL->eState == HAL_AWAITING_CHI_MAGIC))
        {
            boStatus = TRUE;
            break;
        }
    }

    if ( psHAL->eState == HAL_RUNNING )
        boStatus = TRUE;

    DBG_LEV1(("Download delay time = %ld microseconds, HAL state = %d.\n", i*ulDelay, psHAL->eState));

    return( boStatus );
}


//-----------------------------------------------------------------------------
//
// NAME     vHALstart
//
// PARAMETERS  psHAL    Pointer to HAL context.
//
// RETURNS     na
//
// DESCRIPTION This function should be used after all code has been 
//    downloaded to the device to start the target code running. 
//
//-----------------------------------------------------------------------------
VOID
vHALstart( IN PHAL_CONTEXT psHAL )
{
    ULONG   ulValue;

    DBG_LEV1(("vHALstart()\n"));

    ASSERT (psHAL != NULL);

    /*
    * To start the device we go through the following steps:
    * 1. Write a BOOT_END transfer command to all processors.
    * 2. Wait for BOOT_WAITING command back from each processor.
    * 3. Write a BOOT_GO transfer command to the first processor.
    * It is assumed at this point that code has been downloaded to all
    * processors that are required and as a result of this each processor
    * will already be running.
    */
    if ( psHAL->eState != HAL_READY_TO_DOWNLOAD_NTH )
    {
        DBG_LEV0(("ERROR: Attempt to start device in invalid state, %d.\n", psHAL->eState));
    }
    else
    {
        // Acquire semaphore before accessing mailbox.
        if ( boHALacquireSemaphore( psHAL, HAL_MAILBOX_0 ) )
        {
            psHAL->eState = HAL_STARTING;

            ulValue = CHI_BOOT_END;
            vHALwriteMailbox( psHAL, CHI_ADDR_XFER_CTRL(CHI_UPPER_CPU), &ulValue, sizeof(ULONG) );
            vHALwriteMailbox( psHAL, CHI_ADDR_XFER_CTRL(CHI_UWA_CPU), &ulValue, sizeof(ULONG) );

            // Release mailbox semaphore.
            vHALreleaseSemaphore( psHAL, HAL_MAILBOX_0 );
        }
    }
}


//-----------------------------------------------------------------------------
//
// NAME     vHALstop
//
// PARAMETERS  psHAL    Pointer to HAL context.
//
// DESCRIPTION This function can be called in any state following a fatal
//    error to return the device to the halted state and clean up.
//
//-----------------------------------------------------------------------------
VOID
vHALstop( IN OUT PHAL_CONTEXT psHAL )
{
    // Clean up download structure.
    psHAL->sDownload.paucImage      = NULL;
    psHAL->sDownload.ulLength    = 0;
    psHAL->sDownload.ulOffset    = 0;
    psHAL->sDownload.ulAddrXferArea = 0;

    // Zero the CFHI area.
    psHAL->sCHI.ulN              = 0;
    psHAL->sCHI.ulAddrReqResHead = 0;
    psHAL->sCHI.ulAddrReqResTail = 0;
    psHAL->sCHI.ulAddrReqResQ    = 0;
    psHAL->sCHI.ulAddrCfmIndHead = 0;
    psHAL->sCHI.ulAddrCfmIndTail = 0;
    psHAL->sCHI.ulAddrCfmIndQ    = 0;
    psHAL->sCHI.ulReqResTail     = 0;
    psHAL->sCHI.ulCfmIndHead     = 0;

    // Change back to stopped state.
    psHAL->eState             = HAL_STOPPED;
    psHAL->ePowerState           = HAL_PS_AWAKE;
    psHAL->ulDownloadCount       = 0;
    psHAL->ulReqManMsgNum        = 0;
    psHAL->ulReqManMsgRsvdQHead     = 0;
    psHAL->ulReqManMsgRsvdQTail     = 0;
    psHAL->ulReqDbgMsgNum        = 0;
    psHAL->boTxReqMsgFlag        = FALSE;

    // Reset the device.
    vHALsoftReset( psHAL );
}


//-----------------------------------------------------------------------------
//
// NAME     vHALInitTxRxBuffer
//
// PARAMETERS  psHAL    Pointer to HAL context.
//
// DESCRIPTION Initialize the Tx & Rx buffer descriptor.
//
//-----------------------------------------------------------------------------
VOID
vHALinitTxRxBuffer( IN PHAL_CONTEXT psHAL )
{
    ULONG   i;
    PUCHAR shadowbase = (PUCHAR)(((ULONG)(psHAL->ucShadowPool0) + 31) & (~31));
    ULONG bufsize = (psHAL->ulTxRxBufSize + 31) & (~31);

    // Initialize Rx buffer descriptor.
    for ( i=0; i<psHAL->ulRxBufNum; i++ )
    {
       psHAL->aulRxBufferAddr[i] = i * psHAL->ulTxRxBufSize;  
    }

    // Point to the first Rx buffer.
    psHAL->ulRxBufferIndex = 0;

    // Initialize Tx buffer descriptor.
    for ( i=0; i<psHAL->ulTxBufNum; i++ )
    {
        psHAL->sTxBuf[i].ulBufAddr = (i+ psHAL->ulRxBufNum) *  psHAL->ulTxRxBufSize;
        psHAL->sTxBuf[i].ulBufLen = psHAL->ulTxRxBufSize;
        psHAL->sTxBuf[i].boBufAvail = TRUE;
        psHAL->sTxBuf[i].pulocalAddr = shadowbase+(i+ psHAL->ulRxBufNum)*bufsize;
    }

    // Point to the fisrt Tx buffer.
    psHAL->ulTxBufferIndex = 0;
}


//-----------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -