📄 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 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 + -