📄 cfw_platform.c
字号:
/* 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 + -