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

📄 cfw_platform.c

📁 ARM9基于WINDOWSCE的BSP源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*   The content of this file or document is CONFIDENTIAL and PROPRIETARY
*   to Jade Technologies Co., Ltd.  It is subjected to the terms of a
*   License Agreement between Licensee and Jade Technologies Co., Ltd.
*   restricting among other things, the use, reproduction, distribution
*   and transfer.  Each of the embodiments, including this information 
*   and any derivative work shall retain this copyright notice.
* 
*   Copyright (c) 2004 - 2005 Jade Technologies Co., Ltd. 
*   All rights reserved.
 * ----------------------------------------------------------------
 * File:     cfw_platform.c,v
 * Revision: 1.0
 * ----------------------------------------------------------------
 * $
 *
 */

#include <windows.h>
#include <nkintr.h>
#include <oalintr.h>
#include <drv_glob.h>
#include <ceddk.h>
#include <arm_ddk.h>
#include <memory.h>
#include <pehdr.h>
#include <romldr.h>
#include <oemwake.h>
#include <win_plat.h> /* This also 'includes' platform.h */
#include <oalfuncs.h>
#include <flash_lib.h>
#include <pl190.h>
#include <dma.h>

#include "dmakern.h"
#include "vfp.h"

#ifdef MODULE_CERTIFY
/*
 * OEMLoadInit/OEMLoadModule implementation and the public
 * key used for module signature verification
 */
# include "key1024.c"
#endif

// Define this to override the 926 processor type and so allow 
//  eMbedded Visual C++ to connect to WinCE 
#define PROCESSOR_ID_FIX

#ifdef PROCESSOR_ID_FIX
extern CEProcessorType;
#endif

/*
 * @doc    EXTERNAL KERNEL HAL
 *
 * @module cfw_platform.c - ARM Template HW Support
 *         OEM support Functions for the Windows CE ARM Platform.
 *
 * @xref
 *         OEMInit
 *         OEMInterruptEnable
 *         OEMInterruptDisable
 *         OEMInterruptDone
 *         HAL Overview.Windows CE Kernel OEM Interface
 *         Interrupt Support Overview.Kernel Interrupt Support
 *
 * @topic Windows CE Kernel OEM Interface
 *
 *         This defines the HAL layer - OEM and platform dependent pieces of
 *         code which we expect the OEM to deliver to us. There are three
 *         pieces of OEM deliverable code  - the bootstrap loader & monitor
 *         (for  debugging), the HAL portions which are interfaces between
 *         the kernel and the firmware, and the driver interface. This
 *         topic covers just  the HAL portion.
 *         
 *         The philosophy is to keep the HAL layer as simple as possible.
 *         The HAL should not be confused with the machine or CPU
 *         independence. HAL  is specific for a particular CPU and
 *         platform. It includes interfaces  for the following devices:
 *         
 *          -  Real Time Clock
 *          -  Interval Timer (used for the scheduler operation)
 *          -  Interrupt handlers and support
 *
 *   Note that it does not include abstractions for devices like the DMA
 *   controller etc. since the kernel does not use one. Also note that the
 *   list could change for different CPU's and platforms - for instance,
 *   some chips might include a lot of peripheral devices (like the
 *   interval timer) on the CPU chip itself, removing the need for a
 *   separate interface for them.
 *
 *   The interfaces for the real time clock and interval timer are still
 *   being developed. But they should in general be extremely simple and
 *   straightforward. For details on the interrupt support model in the
 *   kernel look at <l Interrupt Support Overview.Kernel Interrupt Support>
 */

// Watermark info
const PTCHAR part_name = { TEXT("Windows CE .NET OAL (OEM Adaptation Layer)") };
const PTCHAR part_num = { TEXT("OS005-SW-70002-r0p0-00REL0") };

extern DWORD idleconv;          // translation constant in 1 ms units
extern DWORD MainMemoryEndAddress;  // exported by kernel
extern ROMHDR * volatile const pTOC;

void OEMInitInterrupts(HARP_BOOT_ARGS *pBootArgs);
extern void InitDebugEther(HARP_BOOT_ARGS *pBootArgs);

/* Pointer to the DMA controller registers */
static volatile PDMAC_REGS  pDMACRegs = (PDMAC_REGS)DMAC_BASE;  

HARP_BOOT_ARGS *pBootArgs = &(((PDRIVER_GLOBALS)(DRIVER_GLOBALS_PHYSICAL_MEMORY_START))->eth);

ULONG Logic2SysIntr[LOGINTR_MAX+1];
ULONG SysIntr2Logic[SYSINTR_MAXIMUM];
ULONG LogIntrOpenStatus[LOGINTR_MAX];

CRITICAL_SECTION csRequestSysIntr;

#define IMAGE_HEADER_SIZE   0x1000

/**********************************************************************/

void PrintBootArgs()
{
    RETAILMSG(TRUE, (TEXT("Bootargs: 0x%08x\r\n"),pBootArgs));
    RETAILMSG(TRUE, (TEXT(" Sig: %d\r\n"), pBootArgs->dwSig));
    RETAILMSG(TRUE, (TEXT(" Len: %d\r\n"), pBootArgs->dwLen));
    RETAILMSG(TRUE, (TEXT(" LoaderFlags: %d\r\n"), pBootArgs->ucLoaderFlags));
    RETAILMSG(TRUE, (TEXT(" EshellFlags: %d\r\n"), pBootArgs->ucEshellFlags));
    RETAILMSG(TRUE, (TEXT(" EdbgAdapterType: %d\r\n"), pBootArgs->ucEdbgAdapterType));
    RETAILMSG(TRUE, (TEXT(" EdbgIRQ: %d\r\n"), pBootArgs->ucEdbgIRQ));
    RETAILMSG(TRUE, (TEXT(" EdbgBaseAddr: 0x%08x\r\n"), pBootArgs->dwEdbgBaseAddr));
    RETAILMSG(TRUE, (TEXT(" EdbgDebugZone: %d\r\n"), pBootArgs->dwEdbgDebugZone));
    RETAILMSG(TRUE, (TEXT(" EdbgAddr: 0x%08x\r\n"), pBootArgs->EdbgAddr));
    
    RETAILMSG(TRUE, (TEXT(" EshellHostAddr: 0x%08x\r\n"), pBootArgs->EshellHostAddr));
    RETAILMSG(TRUE, (TEXT(" DbgHostAddr: 0x%08x\r\n"), pBootArgs->DbgHostAddr));
    RETAILMSG(TRUE, (TEXT(" CeshHostAddr: 0x%08x\r\n"), pBootArgs->CeshHostAddr));
    RETAILMSG(TRUE, (TEXT(" KdbgHostAddr: 0x%08x\r\n"), pBootArgs->KdbgHostAddr));
    RETAILMSG(TRUE, (TEXT(" DHCPLeaseTime: %d\r\n"), pBootArgs->DHCPLeaseTime));
    RETAILMSG(TRUE, (TEXT(" EdbgFlags: %d\r\n"), pBootArgs->EdbgFlags));
}

/*
 * @func   void | OEMInit | Initialize Hardware Interfaces
 * @rdesc  none
 *
 * @comm   OEMInit is called by the kernel after it has performed minimal
 *         initialization. Interrupts are disabled and the kernel is not
 *         ready to handle exceptions. The only kernel service available
 *         to this function is HookInterrupt(). This should be used to
 *         install ISR's for all the hardware interrupts to be handled by
 *         the firmware. Note that ISR's must be installed for any interrupt
 *         that is to be routed to a device driver - otherwise the
 *         InterruptInitialize() call from the driver will fail.
 *
 * @xref   Overview.Windows CE Kernel OEM Interface
 *         HookInterrupt
 *         InterruptInitialize
 */
void OEMInit(void)
{
    int iPos = 0;
    PDWORD pdwMemPos;
 
#ifdef PROCESSOR_ID_FIX
    CEProcessorType = PROCESSOR_ARM920; 
#endif    

#ifdef DEBUG
    // Instead of calling OEMWriteDebugString directly, call through exported
    // function pointer.  This will allow these messages to be seen if debug
    // message output is redirected to Ethernet or the parallel port.
    // Otherwise, lpWriteDebugStringFunc == OEMWriteDebugString.
    lpWriteDebugStringFunc(TEXT("Windows CE Firmware Init\r\n"));
#endif

    // Clear and set-up Char LCD
    //apCHARLCD_SetUp();

    // Uncomment this for more boot information
/*
    DEBUGMSG(1, (TEXT("Boot Args @0x%x, signature 0x%08x\r\n"),
                 pBootArgs, pBootArgs->dwSig));
    PrintBootArgs();
*/

    /*
     * Set up translation constant for GetIdleTime() (1 ms units).
     *
     * Note: Since curridlehigh, curridlelow is counting in ms, and
     * GetIdleTime() reports in ms, the conversion ratio is one. If
     * curridlehigh, curridlelow were using other units (like ticks),
     * then the conversion would be calculated from the clock frequency.
     */
    idleconv = 1;

    /*
     * Initialize timer used for delays in the HAL.
     */
#ifdef DEBUG
    lpWriteDebugStringFunc(TEXT("Initialize timer used for delays")
                           TEXT("in the HAL\r\n"));
#endif

    lpWriteDebugStringFunc(TEXT("InitClock...\r\n"));

    InitClock();
    
    lpWriteDebugStringFunc(TEXT("InitRTC...\r\n"));
    HalTimerInit();

    /*
     * Initialize driver globals area
     */
    lpWriteDebugStringFunc(TEXT("Initialize driver globals area...\r\n"));
    memset((PVOID)DRIVER_GLOBALS_ZEROINIT_START, 0,
           DRIVER_GLOBALS_ZEROINIT_SIZE);

    // Initialize interrupts.
    //
    lpWriteDebugStringFunc(TEXT("InitInterrupts...\r\n"));
    OEMInitInterrupts(pBootArgs);
    
#ifdef DEBUG
    lpWriteDebugStringFunc(TEXT("Firmware Init Done.\r\n"));
#endif

    //
    // Initialize EDBG/KITL if a bootloader started us, and check for the 
    //  correct boot signature.
    //
    
    if (pBootArgs->ucLoaderFlags & LDRFL_USE_EDBG)
    {
        DEBUGMSG(TRUE, (_T("OEMInit: Trying to start EDBG/KITL\r\n")));
        if( pBootArgs->dwSig == BOOTARG_SIG )
        {
            InitDebugEther(pBootArgs);
        }
        else
        {
            DEBUGMSG(TRUE, (_T("OEMInit: Ethernet Boot Sig does not match!\r\n")));
        }
    }
    else
    {
        DEBUGMSG(TRUE, (_T("OEMInit: EDBG/KITL not starting due to boot options\r\n")));
    }

    // Note: This is only included as an example of VFP support, and is not an
    //          indication that this BSP supports VFP
    if (CPUHasVFP ()) 
    {
        EnableVFP ();
        pOEMSaveVFPCtrlRegs    = VFP10SaveCtrlRegs;
        pOEMRestoreVFPCtrlRegs = VFP10RestoreCtrlRegs;
        pOEMHandleVFPException = VFP10HandleVFPException;
    }

    DEBUGMSG( TRUE, (TEXT("MODULE NAME: %s\r\n"),part_name) );
    DEBUGMSG( TRUE, (TEXT("MODULE VERSION: %s\r\n"),part_num) );

    DEBUGMSG(TRUE, (_T("OEMInit: MainMemoryEndAddress is 0x%08x\r\n"), 
            MainMemoryEndAddress));


    // Initialize the DMA subsystem
    InitDMA();

    // Clean the first chunk of free memory so that KernelFindMemory doesn't 
    //  examine it and decide it is already initialised correctly. Otherwise 
    //  more often than not a data abort will be triggered (which halts the 
    //  boot) due to some of the memory being corrupted after a reset. (Mainly 
    //  for flash boots)
    pdwMemPos = (PDWORD)pTOC->ulRAMFree;
    for(iPos = 0; iPos < 1024; iPos += 4)
    {
        *pdwMemPos = 0x00000000;
        pdwMemPos++;
    }

    OEMPowerManagerInit();


}

/*
 * @func   BOOL | OEMInterruptEnable | Enable a hardware interrupt
 *
 * @parms
 *         SysIntr Interrupt ID to be enabled.
 *                 See Interrupt ID's.Interrupt ID's>  for a list of
 *                 possble values.
 *
 *         pvData  ptr to data passed in in the InterruptInitialize() call
 *
 *         cbData  Size of data pointed to by pvData
 *
 * @rdesc  Returns TRUE if valid interrupt ID or FALSE if invalid ID.
 *
 * @comm   This function is called by the Kernel when a device driver
 *         calls InterruptInitialize(). The system is not preemptible
 *         when this function is called.
 *
 * @xref
 *         Overview.Windows CE Kernel OEM Interface
 *         InterruptInitialize
 */
BOOL OEMInterruptEnable(DWORD SysIntr, LPVOID pvData, DWORD cbData)
{
    BOOL bRet = FALSE;
    DWORD dwDMAchan, Irq;

    Irq = OEMTranslateSysIntr(SysIntr);

    if( Irq == LOGINTR_DMA )
    {
        /* We have a DMA interrupt being enabled */
        if(GetActiveDmaChannel(&SysIntr, &dwDMAchan)) 
        {
            bRet = TRUE;

            /* This is a dynamically mapped SYSINTR */
            switch(dwDMAchan) 

⌨️ 快捷键说明

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