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

📄 cfw_platform.c

📁 CIRRUS 公司EP93XX系列CPU的WINCE下的BSP
💻 C
字号:
//**********************************************************************
//                                                                      
// Filename: cfw_platform.c
//                                                                      
// Description:  This file implements the NK kernel interfaces for 
//               firmware interrupt support on a template ARM board.
//
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Use of this source code is subject to the terms of the Cirrus end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to 
// use this source code. For a copy of the EULA, please see the 
// EULA.RTF on your install media.
//
// Copyright(c) Cirrus Logic Corporation 2002, All Rights Reserved                       
//                                                                      
//**********************************************************************
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/* -*-C-*-
 *
 *
 *  Module Name: cfw_platform.c
 *
 *  Abstract:
 *      This file implements the NK kernel interfaces for firmware interrupt
 *      support on a template ARM board.
 *
 * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
 * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
 * PARTICULAR PURPOSE.
 *
 * Copyright (c) 1999, 2000 ARM Limited
 * All Rights Reserved
 */

#include <windows.h>
#include <nkintr.h>
#include <oalintr.h>
#include <drv_glob.h>
#include <pehdr.h>
#include <romldr.h>
#include <ceddk.h>
#include <memory.h>
#include <memorymap.h>
#include <debugtimer.h>
#include <clocks.h>
#include "eeinfo.h"
//#include <Oemwake.h> // remove warning
extern DWORD OEMPowerManagerInit(void); // remove warning

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

//#include <win_plat.h>

/*
 * @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>
 */

extern DWORD idleconv;          // translation constant in 1 ms units
extern DWORD curridlehigh, curridlelow; // 64-bit idle time in ms
extern DWORD CurMSec;

extern DWORD MainMemoryEndAddress;  // exported by kernel
DWORD (*pNKEnumExtensionDRAM)( PMEMORY_SECTION pMemSections, DWORD cMemSections );

extern int IntrTimeISR(void);
void InitClock(void);
void OEMInitInterrupts(void);
int OEMInterruptHandler(unsigned int ra);
DWORD OEMTranslateIrq(DWORD Irq);
DWORD OEMTranslateSysIntr(DWORD SysIntr);
DWORD OEMRequestSysIntr(DWORD Irq);
void InitTransport(void);
void InitDebugEther(void);
DWORD OEMEnumExtensionDRAM( PMEMORY_SECTION pMemSections, DWORD cMemSections );
extern BOOL CPUHasVFP (void);

//
// Need to clear the magic numbers
//
typedef struct 
{
    DWORD version;      // version of this structure, must stay as first DWORD
    DWORD magic1;       // LOG_MAGIC if memory tables valid
    DWORD magic2;       // LOG_MAGIC if heap initialized
} fstemp;
extern ROMHDR * const volatile pTOC;

extern void (* pOEMSaveCoProcRegister)    (LPBYTE);
extern void (* pOEMRestoreCoProcRegister) (LPBYTE);
extern void (* pOEMInitCoProcRegisterSavedArea) (LPBYTE pArea); 
void    OEMSaveCoProcRegister (LPBYTE);
void    OEMRestoreCoProcRegister (LPBYTE);
void    OEMInitCoProcRegisterSavedArea (LPBYTE pArea); 
extern  DWORD cbNKCoProcRegSize;
extern  DWORD fNKSaveCoProcReg;
/*
 * @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)
{
    fstemp  *LogPtr;

    // 
    // Added EnumExtensionDRAM to add memory
    //
    pNKEnumExtensionDRAM = OEMEnumExtensionDRAM;

    //
    // Initialize the debug timer first.
    //
    DebugTimerInit();

    //
    // Get the board information. Requires debug timer so we must put
    // it after getting the boardinformation.
    //
    GetBoardInformation();

    //
    // Initialize the debug serial port.
    //
    OEMInitDebugSerial();
    

#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
    OEMWriteDebugLED(0, 0);

    //
    // Always boot from clean memory configuration.
    // This is a hack, but I want to make sure that memory is cleared before 
    // booting.
    //
    LogPtr = (fstemp *)(pTOC->ulRAMFree | 0x20000000);
    LogPtr->version = LogPtr->magic1 = LogPtr->magic2 = 0;


    //DEBUGMSG(1, (TEXT("Boot Args @0x%x, signature 0x%08x\r\n"),
    //             pBootArgs, pBootArgs->dwSig));
    
    /*
     * 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;

    //dpCurSettings.ulZoneMask =  0x8100;  //20 turn on loader zones



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

    //
    // Start up the scheduling timer.
    //
    lpWriteDebugStringFunc(TEXT("InitClock...\r\n"));
    InitClock();

    //
    // Initialize interrupts.
    //
    OEMInitInterrupts();

    //
    // Initialize the power managment routines.
    //
    OEMPowerManagerInit();


    // Only support one core module (0) under CE - interrupts come in on IRQ0.
    // ARM doesn't use HookInterrupt - OEMInterruptHandler called by kernel
    // instead.

#ifdef DEBUG
    //      dpCurSettings.ulZoneMask = 0xffffffff;
    lpWriteDebugStringFunc(TEXT("Firmware Init Done.\r\n"));
#endif

    //
    // Initialize EDBG/KITL if a bootloader started us.
    //
    //if (pBootArgs->ucLoaderFlags & LDRFL_USE_EDBG)
    //    InitDebugEther();

    if((DRIVER_GLOBALS_POINTER)->eth.EbootMagicNum == EBOOT_MAGIC_NUM ||
       (DRIVER_GLOBALS_POINTER)->eth.EbootMagicNum == PARALLEL_MAGIC_NUM)
    {
        InitDebugEther();
    }

#ifdef  EP93XX_CRUNCH
    //
    // Set up the coprocessor environment variables.
    //
    cbNKCoProcRegSize               = 0xB8;
    fNKSaveCoProcReg                = 1;
    pOEMSaveCoProcRegister          = OEMSaveCoProcRegister;
    pOEMRestoreCoProcRegister       = OEMRestoreCoProcRegister;
    pOEMInitCoProcRegisterSavedArea = OEMInitCoProcRegisterSavedArea;

#endif // EP93XX_CRUNCH

    //
    // Print out the current clock rates to the debug port.
    //
    NKDbgPrintfW
    (
        L"Processor = %dMhz, Bus = %dMhz \r\n", 
        (REAL_FCLOCK/1000000), 
        (REAL_HCLOCK/1000000)
    );


}

//****************************************************************************
// OEMEnumExtensionDRAM
//****************************************************************************
// Allows to map extra memory.
// 
//
DWORD OEMEnumExtensionDRAM( PMEMORY_SECTION pMemSections, DWORD cMemSections )
{


    if ( (cMemSections >=1) &&
        (MainMemoryEndAddress == (SDRAM_VIRTUAL_MEMORY + SDRAM_MAIN_BLOCK_SIZE)) )
    {
        pMemSections[0].dwFlags = 0;
        pMemSections[0].dwStart = SDRAM_VIRTUAL_MEMORY + SDRAM_MAIN_BLOCK_SIZE; 
        pMemSections[0].dwLen   = SDRAM_MAIN_BLOCK_SIZE;

        return(1);
    } 
    return 0;
}

/*
 * OEMGetExtensionDRAM
 *
 * For systems with memory sockets which may add more ram, here's where
 * Windows CE finds out about it.
 */
BOOL OEMGetExtensionDRAM(LPDWORD lpMemStart, LPDWORD lpMemLen)
{
    //if(MainMemoryEndAddress == (SDRAM_VIRTUAL_MEMORY + SDRAM_MAIN_BLOCK_SIZE))
    //{
    //    *lpMemStart = (SDRAM_VIRTUAL_MEMORY + SDRAM_MAIN_BLOCK_SIZE);
    //    *lpMemLen   = SDRAM_MAIN_BLOCK_SIZE;
    //    return TRUE;
    //}
    return FALSE;
}


//****************************************************************************
// OEMTranslateIrq
//****************************************************************************
//  Lets not use this function.  It is made for devices that have a real
//  bus like PCI or ISA.  Just return the input value for now.
// 
//
DWORD OEMTranslateIrq
(
    DWORD Irq 
)
{
    return Irq;
}


//****************************************************************************
// OEMTranslateSysIntr
//****************************************************************************
//  Lets not use this function.  It is made for devices that have a real
//  bus like PCI or ISA.  Just return the input value for now.
// 
//
DWORD OEMTranslateSysIntr
(
    DWORD SysIntr 
)
{
    return SysIntr;
}

//****************************************************************************
// OEMRequestSysIntr
//****************************************************************************
// There are no interrupts that are available.  All interrupts are for
// specified devices.
// 
//
DWORD OEMRequestSysIntr
(
    DWORD Irq 
)
{
    return Irq;
}
//****************************************************************************
// OEMGetInterrupt
//****************************************************************************
// We don't have a PCI bus so return failure.
// 
//
BOOL OEMGetInterrupt
(
    PDEVICE_LOCATION pDevLoc,
    PDWORD pIrq
)
{
    return FALSE;
}
/* EOF cfw_platform.c */

⌨️ 快捷键说明

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