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

📄 hal.c

📁 Freescale ARM11系列CPU MX31的WINCE 5.0下的BSP
💻 C
📖 第 1 页 / 共 5 页
字号:
        return;
    }

    // read info out of Mailbox 0
    vHALreadMailbox( psHAL, HAL_MAILBOX_BASE, (PULONG) pcFatalMsg, sizeof(pcFatalMsg) );
    vHALreleaseSemaphore( psHAL, HAL_MAILBOX_0 );

    OS_MEMCPY( &u16LineNum, (pcFatalMsg + (sizeof(pcFatalMsg) - 2)), sizeof(USHORT) );

    DBG_LEV1(("Device FATAL ERROR in: %s, at line: %d\n", pcFatalMsg, u16LineNum));

}


//-----------------------------------------------------------------------------
//
// NAME     vHALreceiveMessage
//
// PARAMETERS  psHAL    Pointer to HAL context.
//
// DESCRIPTION This handler is called from the interrupt DPC if a message
//    interrupt is received from the device in the running state.
//    The function reads message from device and dispatch to handle.
// 
// RETURN: returns true if message processed, false otherwise.
//
//-----------------------------------------------------------------------------
BOOLEAN
bHALreceiveMessage( IN PHAL_CONTEXT psHAL )
{
    ULONG    ulCfmIndTail=0, ulHeadAddr, ulDeviceRef, ulMsgLen, ulMailbox;
    PHAL_CHI   psCHI = &psHAL->sCHI;
    UMI_MSG    *psMsg;


    
    // Acquire semaphore before accessing mailbox.
    if ( !boHALacquireSemaphore( psHAL, HAL_MAILBOX_2 ) )
    {

        return FALSE;
    }

    // Read the tail index from device.
#ifdef CA_CE5
    // ERI Workaround for non-dw-aligned access problem 
    if((psCHI->ulAddrCfmIndTail & 0x0003) != 0) {
        ULONG value1;		
        vHALreadMailbox( psHAL, (psCHI->ulAddrCfmIndTail & 0xfffc), 
             &value1, sizeof(ULONG) );
        ulCfmIndTail = value1 >> 16;
    }
    else
    {
        vHALreadMailbox( psHAL, psCHI->ulAddrCfmIndTail, &ulCfmIndTail, sizeof(USHORT) );
    }
#else // CA_CE5
    vHALreadMailbox( psHAL, psCHI->ulAddrCfmIndTail, &ulCfmIndTail, sizeof(USHORT) );
#endif // CA_CE5

    psCHI->ulCfmIndTail = ulCfmIndTail;

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

    // Check whether queue empty ...
    if (psCHI->ulCfmIndHead == ulCfmIndTail)
    {

        // no more messages to process ...
        return FALSE;
    }
    
    if ( psHAL->eState != HAL_RUNNING )
    {
        DBG_LEV0(("ERROR: Attempt to receive message in invalid state, %d.\n", psHAL->eState));

        return FALSE;
    }
    
    // Acquire semaphore before accessing mailbox.
    if ( !boHALacquireSemaphore( psHAL, HAL_MAILBOX_2 ) )
    {

        return FALSE;
    }
    
    // Get address from IND message queue.
    ulHeadAddr = psCHI->ulAddrCfmIndQ + psCHI->ulCfmIndHead * sizeof(ULONG);
    vHALreadMailbox( psHAL, ulHeadAddr, &ulDeviceRef, sizeof(ULONG) );
    // Address from Target is relative address, need to adjust.
    ulDeviceRef += HAL_MAILBOX_BASE;
    
    // Check the validity of address and queue tail.
    if ( (ulDeviceRef >= HAL_IMEM_MAILBOX_SPACE) || (ulDeviceRef & 0x03) ||
         (ulCfmIndTail > psCHI->ulN) )
    {
        DBG_LEV0(("ERROR: address = 0x%lx, queue tail = %lu\n", ulDeviceRef, ulCfmIndTail));
        
        vHALreleaseSemaphore( psHAL, HAL_MAILBOX_2 );
        {

            return FALSE;
        }
    }

    if ( ulDeviceRef > CHI_ADDR_CFM_IND_HEAD( 0, psCHI->ulN ) )
        ulMailbox = HAL_MAILBOX_2;
    else
        ulMailbox = HAL_MAILBOX_1;

    // Release old and acquire new semaphore if necessary.
    if ( ulMailbox == HAL_MAILBOX_1 )
    {
        vHALreleaseSemaphore( psHAL, HAL_MAILBOX_2 );
        if ( !boHALacquireSemaphore( psHAL, ulMailbox ) )
        {

            return FALSE;
        }
    }

    // Get Host message buffer.
    psMsg = (UMI_MSG *)&psHAL->ucShadowPool[ ulDeviceRef ];
    // Read message header from device.
    vHALreadMailbox( psHAL, ulDeviceRef, (PULONG)psMsg, sizeof(UMI_MSG_HEADER) );
    // Get message length.
    ulMsgLen = (MSG_GET_TYPE(psMsg->u16MsgId) == MSG_MAN) ? sizeof(UMI_MAN) : sizeof(UMI_DBG);
      
    // Read message data from device.
    vHALreadMailbox( psHAL, ulDeviceRef+sizeof(UMI_MSG_HEADER), (PULONG)psMsg->abData, ulMsgLen );

    // Release old and acquire new semaphore if necessary.
    if ( ulMailbox == HAL_MAILBOX_1 )
    {
        vHALreleaseSemaphore( psHAL, ulMailbox );
        if ( !boHALacquireSemaphore( psHAL, HAL_MAILBOX_2 ) )
        {

            return FALSE;
        }
    }

    // Increase the head index and check for wrap around.
    psCHI->ulCfmIndHead++;
    if ( psCHI->ulCfmIndHead > psCHI->ulN )  psCHI->ulCfmIndHead = 0;

    // Write head index to device.
    vHALwriteMailbox( psHAL, psCHI->ulAddrCfmIndHead, &psCHI->ulCfmIndHead, sizeof(USHORT) );

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

    if ( MSG_GET_DIR(psMsg->u16MsgId) == MSG_CFM )
    {
        // Clear the Tx REQ message flag.
        psHAL->boTxReqMsgFlag = FALSE;
    }



    DBG_LEV2(("vHALreceiveMessage(): Msg 0x%lx, Id = 0x%04x\n", (ULONG)psMsg, psMsg->u16MsgId));
    TRACE(TRACE_CFSD_NDHAL, psMsg->u16MsgId);

    // Call message handler to process message.
    vHALMessageHandler( psHAL, psMsg );
    // Clear any new interrupts that were generated for messages we've just pulled
    if (psCHI->ulCfmIndHead == ulCfmIndTail)
    {
        DBG_LEV3(("Has reached the message tail, terminate it.\n "));
        return FALSE;
    }
    return TRUE;
}

//-----------------------------------------------------------------------------
//
// NAME     vHALbeginDownload
//
// PARAMETERS  psHAL    Pointer to HAL context.
//    ulCPU    The processor that code should be downloaded to:
//                   CHI_UPPER_CPU, CHI_UWA_CPU.
//
// RETURNS     na
//
// DESCRIPTION This function should be used to download an image to one of 
//    the device processors using the bootloader. 
//
//-----------------------------------------------------------------------------
VOID
vHALbeginDownload( IN PHAL_CONTEXT psHAL, IN ULONG ulCPU )
{
    PCFG_CODE_IMAGE psCode;
    PUCHAR        paucImage;
    ULONG         ulLength, ulMagic;

    // Get the F/W image to be downloaded.
    psCode = psCFGgetCodeImage( &psHAL->psAdapter->sCFG, ulCPU+1 );
    if ( psCode == NULL ) {
        DBG_LEV1(("beginDownload(), psCode = 0x%lx ... bailing out\n",
                  (ULONG)psCode));
        return;
    }
    paucImage = psCode->paucImage;
    ulLength = psCode->ulLength;

    DBG_LEV1(("boHALbeginDownload(): %s CPU, Image 0x%lx, Length 0x%lx.\n",
              (ulCPU == CHI_UPPER_CPU)? "Upper": "UWA", (ULONG)paucImage, ulLength));

    ASSERT (psHAL != NULL);

    // Acquire semaphore before accessing mailbox.
    if ( boHALacquireSemaphore( psHAL, HAL_MAILBOX_0 ) )
    {
        // F/W must be downloaded to upper CPU first.
        if ( ulCPU == CHI_UPPER_CPU )
        {
            psHAL->eState = HAL_READY_TO_DOWNLOAD_1ST;

            // Write boot magic.
            ulMagic = CHI_BOOT_MAGIC;
            vHALwriteMailbox( psHAL, CHI_ADDR_BOOT_MAGIC, &ulMagic, sizeof(ULONG) );

            ulMagic = 0;
            vHALreadMailbox( psHAL, CHI_ADDR_BOOT_MAGIC, &ulMagic, sizeof(ULONG) );
            DBG_LEV1(("Read boot magic after writing %08lx\n", ulMagic));

            psHAL->sDownload.ulCPU        = ulCPU;
            psHAL->sDownload.paucImage    = paucImage;
            psHAL->sDownload.ulLength     = ulLength;
            psHAL->sDownload.ulOffset     = 0;
            psHAL->sDownload.ulAddrXferArea = 0;
            psHAL->sDownload.ulSizeXferArea = 0;

            psHAL->eState = HAL_AWAITING_BOOT_MAGIC;

            /*
            * Because this is the first download, we must wait for the transfer
            * control structure to be initialized by the upper CPU before we
            * proceed. Specifically, we are waiting for BOOT_MAGIC.
            */
            vHALwriteMailbox( psHAL, CHI_ADDR_BOOT_NUM, &ulCPU, sizeof(ULONG) );

            // Release mailbox semaphore.
            vHALreleaseSemaphore( psHAL, HAL_MAILBOX_0 );
        }
        else if ( ulCPU == CHI_UWA_CPU )
        {
            // Write the number of CPU that is being booted to the boot number field.
            vHALwriteMailbox( psHAL, CHI_ADDR_BOOT_NUM, &ulCPU, sizeof(ULONG) );

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

            psHAL->sDownload.ulCPU        = ulCPU;
            psHAL->sDownload.paucImage    = paucImage;
            psHAL->sDownload.ulLength     = ulLength;
            psHAL->sDownload.ulOffset     = 0;

            psHAL->eState = HAL_DOWNLOADING;

            // Continue to download since the transfer control area has been initialized.
            vHALcontinueDownload( psHAL );
        }
    }
}


//-----------------------------------------------------------------------------
//
// NAME     vHALcheckForBootMagic
//
// PARAMETERS  psHAL    Pointer to HAL context.
//
// DESCRIPTION This function is called from the interrupt DPC in the 'waiting 
//    for boot magic' state. The function reads the value of boot 
//    magic and if it has been set by CPU 0 then the state machine 
//    can progress to the next stage of the download process.
//
//-----------------------------------------------------------------------------
VOID
vHALcheckForBootMagic( IN PHAL_CONTEXT psHAL )
{
    ULONG         ulMagic;
    PHAL_DOWNLOAD psDownload;

    DBG_LEV1(("vHALcheckForBootMagic()\n"));

    psDownload = &psHAL->sDownload;

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

        if ( ulMagic == CHI_BOOT_MAGIC )
        {
            vHALreadMailbox( psHAL, CHI_ADDR_XFER_MAX, &psDownload->ulSizeXferArea, sizeof(ULONG) );
            vHALreadMailbox( psHAL, CHI_ADDR_XFER_VECTOR, &psDownload->ulAddrXferArea, sizeof(ULONG) );

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

            // Convert size of transfer area from 32-bit DWORDs to BYTEs.
            psDownload->ulSizeXferArea = HAL_DWORDS_TO_BYTES( psDownload->ulSizeXferArea );

            psHAL->eState = HAL_DOWNLOADING;

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

            DBG_LEV0(("ERROR: Boot magic did not match.\n"));
   
            vHALstop( psHAL );
        }
    }
}


//-----------------------------------------------------------------------------
//
// NAME     vHALcontinueDownload
//
// PARAMETERS  psHAL    Pointer to HAL context.
//
// DESCRIPTION This handler is called from interrupt DPC in the 'downloading'
//    state. The function checks the state of the device and if the
//    device is ready continues the download.
//
//-----------------------------------------------------------------------------
VOID
vHALcontinueDownload( IN PHAL_CONTEXT psHAL )
{
    ULONG         ulXferCtrl, ulLength, ulValue;
    PHAL_DOWNLOAD psDownload;

    
    DBG_LEV1(("vHALcontinueDownload()\n"));

    psDownload = &psHAL->sDownload;

    // Acquire semaphore before accessing mailbox.
    if ( boHALacquireSemaphore( psHAL, HAL_MAILBOX_0 ) )
    {
        /*
        * We read the value of transfer control for the processor to which we are
        * currently downloading. If it is ready for more data then get the next
        * block of data and transfer it to the device. If we device is still busy
        * with the previous block of data we do nothing.
        */
        vHALreadMailbox( psHAL, CHI_ADDR_XFER_CTRL(psDownload->ulCPU), &ulXferCtrl, sizeof(ULONG) );

        if ( ulXferCtrl == CHI_BOOT_READY )
        {
            ulLength = psDownload->ulLength - psDownload->ulOffset;

            if (ulLength == 0)
            {
                // Release mailbox semaphore.
                vHALreleaseSemaphore( psHAL, HAL_MAILBOX_0 );

                psDownload->paucImage = NULL;
                psDownload->ulLength  = 0;
                psDownload->ulOffset  = 0;

                psHAL->eState = HAL_READY_TO_DOWNLOAD_NTH;
                psHAL->ulDownloadCount++;

                if ( psDownload->ulCPU == CHI_UPPER_CPU )
                {
                    // Begin to download the second F/W after the first one.
                    vHALbeginDownload( psHAL, CHI_UWA_CPU );
                }
                else if ( psDownload->ulCPU == CHI_UWA_CPU )
                {
                    // Start device after downloading the two F/W.
                    vHALstart( psHAL );
                }
            }
            else

⌨️ 快捷键说明

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