📄 cfw_platform.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 2005, 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 EULA.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 <oal_cache.h>
#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
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);
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;
//functions and variables for QueryPerformanceCounter
extern BOOL OEMQueryPerformanceFrequency( LARGE_INTEGER *lpliPerformanceFreq );
extern BOOL OEMQueryPerformanceCounter( LARGE_INTEGER *lpliPerformanceCount );
extern BOOL (*pQueryPerformanceCounter)(LARGE_INTEGER *lpliPerformanceCount);
extern BOOL (*pQueryPerformanceFrequency)(LARGE_INTEGER *lpliPerformanceFreq);
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;
extern DWORD OEMPowerManagerInit(void);
/*
* @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;
//
// Set memory size for DrWatson kernel support
//
dwNKDrWatsonSize = 128 * 1024;
//
// Initialize the Global Cache.
//
OALCacheGlobalsInit();
//
// 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();
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
pQueryPerformanceCounter =OEMQueryPerformanceCounter;
pQueryPerformanceFrequency =OEMQueryPerformanceFrequency;
//
// Print out the current clock rates to the debug port.
//
NKDbgPrintfW
(
L"Processor = %dMhz, Bus = %dMhz \r\n",
(REAL_FCLOCK/1000000),
(REAL_HCLOCK/1000000)
);
}
/*
* 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)
{
BOOL bRet=FALSE;
//Only implemented for EDB9307A as a sample, please double check config.bib before changing
//this function.
//#ifdef EDB9307A
#ifdef IMGFLASH
*lpMemStart = (SDRAM_VIRTUAL_MEMORY + 0x2000000);
*lpMemLen = 0x2000000;
bRet=TRUE;
lpWriteDebugStringFunc(TEXT("OEMGetExtensionDRAM(XIP)\r\n"));
/*
#else
*lpMemStart = (SDRAM_VIRTUAL_MEMORY + 0x1200000);
*lpMemLen = 0xE00000;
bRet=TRUE;
#endif
#else
*/
#endif
return bRet;
}
//****************************************************************************
// 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 */
// History :
// History : Revision 1.1 2006/12/15 10:00 Xieyes
// History : Enabled OEMGetExtensionDRAM for XIP
// History :
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -