mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-29 16:44:10 +02:00
Remove Template stuff and teach people with BeagleBoard
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9876 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
e70c379327
commit
76a689b573
@ -1,183 +0,0 @@
|
||||
/** @file
|
||||
The entry of the embedded BDS. This BDS does not follow the Boot Manager requirements
|
||||
of the UEFI specification as it is designed to implement an embedded systmes
|
||||
propriatary boot scheme.
|
||||
|
||||
This template assume a DXE driver produces a SerialIo protocol not using the EFI
|
||||
driver module and it will attempt to connect a console on top of this.
|
||||
|
||||
Copyright (c) 2008-2009, Apple Inc. All rights reserved.
|
||||
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include "BdsEntry.h"
|
||||
|
||||
|
||||
BOOLEAN gConsolePresent = FALSE;
|
||||
|
||||
|
||||
EFI_HANDLE mBdsImageHandle = NULL;
|
||||
EFI_BDS_ARCH_PROTOCOL gBdsProtocol = {
|
||||
BdsEntry,
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
This function uses policy data from the platform to determine what operating
|
||||
system or system utility should be loaded and invoked. This function call
|
||||
also optionally make the use of user input to determine the operating system
|
||||
or system utility to be loaded and invoked. When the DXE Core has dispatched
|
||||
all the drivers on the dispatch queue, this function is called. This
|
||||
function will attempt to connect the boot devices required to load and invoke
|
||||
the selected operating system or system utility. During this process,
|
||||
additional firmware volumes may be discovered that may contain addition DXE
|
||||
drivers that can be dispatched by the DXE Core. If a boot device cannot be
|
||||
fully connected, this function calls the DXE Service Dispatch() to allow the
|
||||
DXE drivers from any newly discovered firmware volumes to be dispatched.
|
||||
Then the boot device connection can be attempted again. If the same boot
|
||||
device connection operation fails twice in a row, then that boot device has
|
||||
failed, and should be skipped. This function should never return.
|
||||
|
||||
@param This The EFI_BDS_ARCH_PROTOCOL instance.
|
||||
|
||||
@return None.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
BdsEntry (
|
||||
IN EFI_BDS_ARCH_PROTOCOL *This
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN NoHandles;
|
||||
EFI_HANDLE *Buffer;
|
||||
UINTN Index;
|
||||
EFI_HANDLE FvHandle;
|
||||
EFI_GUID *NameGuid;
|
||||
|
||||
//
|
||||
// This code assumes that a DXE driver produces a SerialIo protocol not following the EFI
|
||||
// driver model. At a minimum we need to connect an EFI driver model terminal driver on top
|
||||
// of the serial driver.
|
||||
//
|
||||
Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiSerialIoProtocolGuid, NULL, &NoHandles, &Buffer);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
for (Index = 0; Index < NoHandles; Index++) {
|
||||
// For every Serial IO protocol in the system connect EFI drivers to it.
|
||||
// This should cause the terminal driver to bind to the Serial IO protocol and produce a
|
||||
// child handle that produces SimpleTextOut & SImpleTextIn protocols
|
||||
gBS->ConnectController (Buffer[Index], NULL, NULL, TRUE);
|
||||
}
|
||||
|
||||
FreePool (Buffer);
|
||||
}
|
||||
|
||||
//
|
||||
// Now we need to setup the EFI System Table with information about the console devices.
|
||||
// This code is normally in the console spliter driver on platforms that support multiple
|
||||
// consoles at the same time
|
||||
//
|
||||
Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiSimpleTextOutProtocolGuid, NULL, &NoHandles, &Buffer);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
// Use the first SimpleTextOut we find and update the EFI System Table
|
||||
gST->ConsoleOutHandle = Buffer[0];
|
||||
gST->StandardErrorHandle = Buffer[0];
|
||||
Status = gBS->HandleProtocol (Buffer[0], &gEfiSimpleTextOutProtocolGuid, (VOID **)&gST->ConOut);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
gST->StdErr = gST->ConOut;
|
||||
|
||||
FreePool (Buffer);
|
||||
|
||||
gConsolePresent = TRUE;
|
||||
}
|
||||
|
||||
Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiSimpleTextInProtocolGuid, NULL, &NoHandles, &Buffer);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
// Use the first SimpleTextIn we find and update the EFI System Table
|
||||
gST->ConsoleInHandle = Buffer[0];
|
||||
Status = gBS->HandleProtocol (Buffer[0], &gEfiSimpleTextInProtocolGuid, (VOID **)&gST->ConIn);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
FreePool (Buffer);
|
||||
}
|
||||
|
||||
//
|
||||
// We now have EFI Consoles up and running. Print () will work now. DEBUG () and ASSERT () worked
|
||||
// prior to this point as they were configured to use a more primative output scheme.
|
||||
//
|
||||
|
||||
|
||||
//
|
||||
// Platform specific stuff goes here
|
||||
//
|
||||
|
||||
|
||||
//
|
||||
// Normal UEFI behavior is to process Globally Defined Variables as defined in Chapter 3
|
||||
// (Boot Manager) of the UEFI specification. For this embedded system we don't do this.
|
||||
//
|
||||
|
||||
//
|
||||
// Search all the FVs for an application with a UI Section of Ebl. A .FDF file can be used
|
||||
// to control the names of UI sections in an FV.
|
||||
//
|
||||
Status = FindApplicationMatchingUiSection (L"Ebl", &FvHandle, &NameGuid);
|
||||
if (EFI_ERROR (Status)) {
|
||||
//
|
||||
// Just load the first application we find reguardless of name.
|
||||
// This is the fallback path.
|
||||
//
|
||||
Status = FindApplicationMatchingUiSection (NULL, &FvHandle, &NameGuid);
|
||||
// Nothing to boot
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
|
||||
Status = LoadPeCoffSectionFromFv (FvHandle, NameGuid);
|
||||
|
||||
//
|
||||
// EFI does not define the bavior if all boot attemps fail and the last one returns.
|
||||
// So we make a policy choice to reset the system since this BDS does not have a UI.
|
||||
//
|
||||
gRT->ResetSystem (EfiResetCold, Status, 0, NULL);
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
BdsInitialize (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
mBdsImageHandle = ImageHandle;
|
||||
|
||||
//
|
||||
// Install protocol interface
|
||||
//
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&mBdsImageHandle,
|
||||
&gEfiBdsArchProtocolGuid, &gBdsProtocol,
|
||||
NULL
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -1,62 +0,0 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2008-2009 Apple Inc. All rights reserved.<BR>
|
||||
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
|
||||
#ifndef __BDS_ENTRY_H__
|
||||
#define __BDS_ENTRY_H__
|
||||
|
||||
#include <PiDxe.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/PrintLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/DxeServicesTableLib.h>
|
||||
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||
#include <Library/HobLib.h>
|
||||
#include <Library/DevicePathLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
|
||||
#include <Protocol/Bds.h>
|
||||
#include <Protocol/SerialIo.h>
|
||||
#include <Protocol/FirmwareVolume2.h>
|
||||
#include <Protocol/SimpleTextIn.h>
|
||||
#include <Protocol/SimpleTextOut.h>
|
||||
|
||||
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
LoadPeCoffSectionFromFv (
|
||||
IN EFI_HANDLE FvHandle,
|
||||
IN EFI_GUID *NameGuid
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
FindApplicationMatchingUiSection (
|
||||
IN CHAR16 *UiString,
|
||||
OUT EFI_HANDLE *FvHandle,
|
||||
OUT EFI_GUID **NameGuid
|
||||
);
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
BdsEntry (
|
||||
IN EFI_BDS_ARCH_PROTOCOL *This
|
||||
);
|
||||
|
||||
#endif
|
||||
|
@ -1,160 +0,0 @@
|
||||
/** @file
|
||||
The entry of the embedded BDS. This BDS does not follow the Boot Manager requirements
|
||||
of the UEFI specification as it is designed to implement an embedded systmes
|
||||
propriatary boot scheme.
|
||||
|
||||
This template assume a DXE driver produces a SerialIo protocol not using the EFI
|
||||
driver module and it will attempt to connect a console on top of this.
|
||||
|
||||
Copyright (c) 2008-2009, Apple Inc. All rights reserved.
|
||||
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include "BdsEntry.h"
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
FindApplicationMatchingUiSection (
|
||||
IN CHAR16 *UiString,
|
||||
OUT EFI_HANDLE *FvHandle,
|
||||
OUT EFI_GUID **NameGuid
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_STATUS NextStatus;
|
||||
UINTN NoHandles;
|
||||
EFI_HANDLE *Buffer;
|
||||
UINTN Index;
|
||||
EFI_FV_FILETYPE FileType;
|
||||
EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
|
||||
VOID *Key;
|
||||
EFI_FV_FILE_ATTRIBUTES Attributes;
|
||||
UINTN Size;
|
||||
UINTN UiStringLen;
|
||||
CHAR16 *UiSection;
|
||||
UINT32 Authentication;
|
||||
|
||||
|
||||
UiStringLen = 0;
|
||||
if (UiString != NULL) {
|
||||
UiStringLen = StrLen (UiString);
|
||||
}
|
||||
|
||||
Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiFirmwareVolume2ProtocolGuid, NULL, &NoHandles, &Buffer);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
for (Index = 0; Index < NoHandles; Index++) {
|
||||
Status = gBS->HandleProtocol (Buffer[Index], &gEfiFirmwareVolume2ProtocolGuid, (VOID **)&Fv);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Key = AllocatePool (Fv->KeySize);
|
||||
FileType = EFI_FV_FILETYPE_APPLICATION;
|
||||
|
||||
do {
|
||||
NextStatus = Fv->GetNextFile (Fv, Key, &FileType, *NameGuid, &Attributes, &Size);
|
||||
if (!EFI_ERROR (NextStatus)) {
|
||||
if (UiString == NULL) {
|
||||
//
|
||||
// If UiString is NULL match first application we find.
|
||||
//
|
||||
*FvHandle = Buffer[Index];
|
||||
FreePool (Key);
|
||||
return Status;
|
||||
}
|
||||
|
||||
UiSection = NULL;
|
||||
Status = Fv->ReadSection (
|
||||
Fv,
|
||||
*NameGuid,
|
||||
EFI_SECTION_USER_INTERFACE,
|
||||
0,
|
||||
(VOID **)&UiSection,
|
||||
&Size,
|
||||
&Authentication
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
if (StrnCmp (UiString, UiSection, UiStringLen)) {
|
||||
//
|
||||
// We found a UiString match.
|
||||
//
|
||||
*FvHandle = Buffer[Index];
|
||||
FreePool (Key);
|
||||
FreePool (UiSection);
|
||||
return Status;
|
||||
}
|
||||
FreePool (UiSection);
|
||||
}
|
||||
}
|
||||
} while (!EFI_ERROR (NextStatus));
|
||||
|
||||
FreePool (Key);
|
||||
}
|
||||
}
|
||||
|
||||
FreePool (Buffer);
|
||||
}
|
||||
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
EFI_DEVICE_PATH *
|
||||
FvFileDevicePath (
|
||||
IN EFI_HANDLE FvHandle,
|
||||
IN EFI_GUID *NameGuid
|
||||
)
|
||||
{
|
||||
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
||||
MEDIA_FW_VOL_FILEPATH_DEVICE_PATH NewNode;
|
||||
|
||||
DevicePath = DevicePathFromHandle (FvHandle);
|
||||
|
||||
EfiInitializeFwVolDevicepathNode (&NewNode, NameGuid);
|
||||
|
||||
return AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&NewNode);
|
||||
}
|
||||
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
LoadPeCoffSectionFromFv (
|
||||
IN EFI_HANDLE FvHandle,
|
||||
IN EFI_GUID *NameGuid
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
|
||||
VOID *Buffer;
|
||||
UINTN BufferSize;
|
||||
UINT32 Authentication;
|
||||
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
||||
EFI_HANDLE ImageHandle;
|
||||
|
||||
Status = gBS->HandleProtocol (FvHandle, &gEfiFirmwareVolume2ProtocolGuid, (VOID **)&Fv);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = Fv->ReadSection (Fv, NameGuid, EFI_SECTION_PE32, 0, &Buffer, &BufferSize, &Authentication);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
DevicePath = FvFileDevicePath (FvHandle, NameGuid);
|
||||
Status = gBS->LoadImage (TRUE, gImageHandle, DevicePath, Buffer, BufferSize, &ImageHandle);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
// ExitData is NULL so we need to pass in a size of zero
|
||||
BufferSize = 0;
|
||||
Status = gBS->StartImage (ImageHandle, &BufferSize, NULL);
|
||||
}
|
||||
|
||||
FreePool (Buffer);
|
||||
}
|
||||
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
@ -1,67 +0,0 @@
|
||||
#/** @file
|
||||
#
|
||||
# Component discription file for Bds module
|
||||
#
|
||||
# Copyright (c) 2008, Intel Corporation. <BR>
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
#**/
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = TemplateBds
|
||||
FILE_GUID = 3C85595C-70FD-447D-B0CB-7F6BBA9C9BEB
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
|
||||
ENTRY_POINT = BdsInitialize
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
|
||||
#
|
||||
|
||||
[Sources.common]
|
||||
BdsEntry.c
|
||||
FirmwareVolume.c
|
||||
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
DevicePathLib
|
||||
BaseLib
|
||||
HobLib
|
||||
UefiRuntimeServicesTableLib
|
||||
ReportStatusCodeLib
|
||||
PerformanceLib
|
||||
DxeServicesTableLib
|
||||
MemoryAllocationLib
|
||||
UefiLib
|
||||
UefiBootServicesTableLib
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
PrintLib
|
||||
UefiDriverEntryPoint
|
||||
|
||||
[Guids]
|
||||
|
||||
|
||||
[Protocols]
|
||||
gEfiBdsArchProtocolGuid
|
||||
gEfiSimpleTextInProtocolGuid
|
||||
gEfiSimpleTextOutProtocolGuid
|
||||
gEfiSerialIoProtocolGuid
|
||||
gEfiDevicePathProtocolGuid
|
||||
gEfiFirmwareVolume2ProtocolGuid
|
||||
|
||||
[depex]
|
||||
TRUE
|
@ -1,250 +0,0 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2008-2009, Apple Inc. All rights reserved.
|
||||
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include <CpuDxe.h>
|
||||
#include <Library/CacheMaintenanceLib.h>
|
||||
|
||||
VOID
|
||||
ExceptionHandlersStart (
|
||||
VOID
|
||||
);
|
||||
|
||||
VOID
|
||||
ExceptionHandlersEnd (
|
||||
VOID
|
||||
);
|
||||
|
||||
VOID
|
||||
CommonExceptionEntry (
|
||||
VOID
|
||||
);
|
||||
|
||||
VOID
|
||||
AsmCommonExceptionEntry (
|
||||
VOID
|
||||
);
|
||||
|
||||
|
||||
EFI_EXCEPTION_CALLBACK gExceptionHandlers[MAX_ARM_EXCEPTION + 1];
|
||||
|
||||
|
||||
/**
|
||||
This function registers and enables the handler specified by InterruptHandler for a processor
|
||||
interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the
|
||||
handler for the processor interrupt or exception type specified by InterruptType is uninstalled.
|
||||
The installed handler is called once for each processor interrupt or exception.
|
||||
|
||||
@param InterruptType A pointer to the processor's current interrupt state. Set to TRUE if interrupts
|
||||
are enabled and FALSE if interrupts are disabled.
|
||||
@param InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called
|
||||
when a processor interrupt occurs. If this parameter is NULL, then the handler
|
||||
will be uninstalled.
|
||||
|
||||
@retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled.
|
||||
@retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was
|
||||
previously installed.
|
||||
@retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not
|
||||
previously installed.
|
||||
@retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
RegisterInterruptHandler (
|
||||
IN EFI_EXCEPTION_TYPE InterruptType,
|
||||
IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
|
||||
)
|
||||
{
|
||||
if (InterruptType > MAX_ARM_EXCEPTION) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if ((InterruptHandler == NULL) && (gExceptionHandlers[InterruptType] == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((InterruptHandler != NULL) && (gExceptionHandlers[InterruptType] != NULL)) {
|
||||
return EFI_ALREADY_STARTED;
|
||||
}
|
||||
|
||||
gExceptionHandlers[InterruptType] = InterruptHandler;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
DefaultSWIExceptionHandler(
|
||||
IN EFI_EXCEPTION_TYPE ExceptionType,
|
||||
IN OUT EFI_SYSTEM_CONTEXT SystemContext
|
||||
)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
DefaultExceptionHandler(
|
||||
IN EFI_EXCEPTION_TYPE ExceptionType,
|
||||
IN OUT EFI_SYSTEM_CONTEXT SystemContext
|
||||
)
|
||||
{
|
||||
DEBUG ((EFI_D_ERROR, "Exception %d from %x\n", ExceptionType, SystemContext.SystemContextArm->PC));
|
||||
ASSERT (FALSE);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
InitializeExceptions (
|
||||
IN EFI_CPU_ARCH_PROTOCOL *Cpu
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status = EFI_SUCCESS;
|
||||
UINTN Offset;
|
||||
UINTN Length;
|
||||
UINTN Index;
|
||||
BOOLEAN Enabled;
|
||||
|
||||
//
|
||||
// Disable interrupts
|
||||
//
|
||||
Cpu->GetInterruptState (Cpu, &Enabled);
|
||||
Cpu->DisableInterrupt (Cpu);
|
||||
|
||||
//
|
||||
// Initialize the C entry points for interrupts
|
||||
//
|
||||
for (Index = 0; Index <= MAX_ARM_EXCEPTION; Index++) {
|
||||
if (Index == EXCEPT_ARM_SOFTWARE_INTERRUPT) {
|
||||
Status = Cpu->RegisterInterruptHandler (Cpu, Index, DefaultSWIExceptionHandler);
|
||||
} else {
|
||||
Status = Cpu->RegisterInterruptHandler (Cpu, Index, DefaultExceptionHandler);
|
||||
}
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
|
||||
//
|
||||
// Copy an implementation of the ARM exception vectors to 0x0.
|
||||
//
|
||||
Length = (UINTN)ExceptionHandlersEnd - (UINTN)ExceptionHandlersStart;
|
||||
|
||||
CopyMem ((VOID *)(UINTN)PcdGet32 (PcdCpuVectorBaseAddress), (VOID *)ExceptionHandlersStart, Length);
|
||||
|
||||
//
|
||||
// Patch in the common Assembly exception handler
|
||||
//
|
||||
Offset = (UINTN)CommonExceptionEntry - (UINTN)ExceptionHandlersStart;
|
||||
*(UINTN *) ((UINT8 *)(UINTN)PcdGet32 (PcdCpuVectorBaseAddress) + Offset) = (UINTN)AsmCommonExceptionEntry;
|
||||
|
||||
//
|
||||
// Flush Caches since we updated executable stuff
|
||||
//
|
||||
InvalidateInstructionCache ();
|
||||
|
||||
if (Enabled) {
|
||||
//
|
||||
// Restore interrupt state
|
||||
//
|
||||
Status = Cpu->EnableInterrupt (Cpu);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
This function reads the processor timer specified by TimerIndex and returns it in TimerValue.
|
||||
|
||||
@param TimerIndex Specifies which processor timer is to be returned in TimerValue. This parameter
|
||||
must be between 0 and NumberOfTimers-1.
|
||||
@param TimerValue Pointer to the returned timer value.
|
||||
@param TimerPeriod A pointer to the amount of time that passes in femtoseconds for each increment
|
||||
of TimerValue.
|
||||
|
||||
@retval EFI_SUCCESS The processor timer value specified by TimerIndex was returned in TimerValue.
|
||||
@retval EFI_DEVICE_ERROR An error occurred attempting to read one of the processor's timers.
|
||||
@retval EFI_INVALID_PARAMETER TimerValue is NULL or TimerIndex is not valid.
|
||||
@retval EFI_UNSUPPORTED The processor does not have any readable timers.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GetTimerValue (
|
||||
IN UINT32 TimerIndex,
|
||||
OUT UINT64 *TimerValue,
|
||||
OUT UINT64 *TimerPeriod OPTIONAL
|
||||
)
|
||||
{
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function flushes the range of addresses from Start to Start+Length
|
||||
from the processor's data cache. If Start is not aligned to a cache line
|
||||
boundary, then the bytes before Start to the preceding cache line boundary
|
||||
are also flushed. If Start+Length is not aligned to a cache line boundary,
|
||||
then the bytes past Start+Length to the end of the next cache line boundary
|
||||
are also flushed. The FlushType of EfiCpuFlushTypeWriteBackInvalidate must be
|
||||
supported. If the data cache is fully coherent with all DMA operations, then
|
||||
this function can just return EFI_SUCCESS. If the processor does not support
|
||||
flushing a range of the data cache, then the entire data cache can be flushed.
|
||||
|
||||
@param Start The beginning physical address to flush from the processor's data
|
||||
cache.
|
||||
@param Length The number of bytes to flush from the processor's data cache. This
|
||||
function may flush more bytes than Length specifies depending upon
|
||||
the granularity of the flush operation that the processor supports.
|
||||
@param FlushType Specifies the type of flush operation to perform.
|
||||
|
||||
@retval EFI_SUCCESS The address range from Start to Start+Length was flushed from
|
||||
the processor's data cache.
|
||||
@retval EFI_UNSUPPORTED The processor does not support the cache flush type specified
|
||||
by FlushType.
|
||||
@retval EFI_DEVICE_ERROR The address range from Start to Start+Length could not be flushed
|
||||
from the processor's data cache.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FlushCpuDataCache (
|
||||
IN EFI_PHYSICAL_ADDRESS Start,
|
||||
IN UINT64 Length,
|
||||
IN EFI_CPU_FLUSH_TYPE FlushType
|
||||
)
|
||||
{
|
||||
if (FlushType == EfiCpuFlushTypeWriteBackInvalidate) {
|
||||
WriteBackInvalidateDataCacheRange((VOID *)(UINTN)Start, (UINTN)Length);
|
||||
return EFI_SUCCESS;
|
||||
} else if (FlushType == EfiCpuFlushTypeInvalidate) {
|
||||
InvalidateDataCacheRange((VOID *)(UINTN)Start, (UINTN)Length);
|
||||
return EFI_SUCCESS;
|
||||
} else if (FlushType == EfiCpuFlushTypeWriteBack) {
|
||||
WriteBackDataCacheRange((VOID *)(UINTN)Start, (UINTN)Length);
|
||||
return EFI_SUCCESS;
|
||||
} else {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -1,158 +0,0 @@
|
||||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (c) 2008-2009 Apple Inc. All rights reserved.
|
||||
#
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
.text
|
||||
.align 2
|
||||
|
||||
.globl _ExceptionHandlersStart
|
||||
.globl _ExceptionHandlersEnd
|
||||
.globl _CommonExceptionEntry
|
||||
.globl _AsmCommonExceptionEntry
|
||||
.globl _gExceptionHandlers
|
||||
|
||||
_ExceptionHandlersStart:
|
||||
|
||||
_Reset:
|
||||
b _ResetEntry
|
||||
|
||||
_UndefinedInstruction:
|
||||
b _UndefinedInstructionEntry
|
||||
|
||||
_SoftwareInterrupt:
|
||||
b _SoftwareInterruptEntry
|
||||
|
||||
_PrefetchAbort:
|
||||
b _PrefetchAbortEntry
|
||||
|
||||
_DataAbort:
|
||||
b _DataAbortEntry
|
||||
|
||||
_ReservedException:
|
||||
b _ReservedExceptionEntry
|
||||
|
||||
_Irq:
|
||||
b _IrqEntry
|
||||
|
||||
_Fiq:
|
||||
b _FiqEntry
|
||||
|
||||
_ResetEntry:
|
||||
stmfd sp!,{r0-r1}
|
||||
mov r0,#0
|
||||
ldr r1,_CommonExceptionEntry
|
||||
bx r1
|
||||
|
||||
_UndefinedInstructionEntry:
|
||||
stmfd sp!,{r0-r1}
|
||||
mov r0,#1
|
||||
ldr r1,_CommonExceptionEntry
|
||||
bx r1
|
||||
|
||||
_SoftwareInterruptEntry:
|
||||
stmfd sp!,{r0-r1}
|
||||
mov r0,#2
|
||||
ldr r1,_CommonExceptionEntry
|
||||
bx r1
|
||||
|
||||
_PrefetchAbortEntry:
|
||||
stmfd sp!,{r0-r1}
|
||||
mov r0,#3
|
||||
sub lr,lr,#4
|
||||
ldr r1,_CommonExceptionEntry
|
||||
bx r1
|
||||
|
||||
_DataAbortEntry:
|
||||
stmfd sp!,{r0-r1}
|
||||
mov r0,#4
|
||||
sub lr,lr,#8
|
||||
ldr r1,_CommonExceptionEntry
|
||||
bx r1
|
||||
|
||||
_ReservedExceptionEntry:
|
||||
stmfd sp!,{r0-r1}
|
||||
mov r0,#5
|
||||
ldr r1,_CommonExceptionEntry
|
||||
bx r1
|
||||
|
||||
_IrqEntry:
|
||||
stmfd sp!,{r0-r1}
|
||||
mov r0,#6
|
||||
sub lr,lr,#4
|
||||
ldr r1,_CommonExceptionEntry
|
||||
bx r1
|
||||
|
||||
_FiqEntry:
|
||||
stmfd sp!,{r0-r1}
|
||||
mov r0,#7
|
||||
sub lr,lr,#4
|
||||
ldr r1,_CommonExceptionEntry
|
||||
bx r1
|
||||
|
||||
_CommonExceptionEntry:
|
||||
.byte 0x12
|
||||
.byte 0x34
|
||||
.byte 0x56
|
||||
.byte 0x78
|
||||
|
||||
_ExceptionHandlersEnd:
|
||||
|
||||
LIndirectgExceptionHandlers:
|
||||
.long _gExceptionHandlers
|
||||
|
||||
_AsmCommonExceptionEntry:
|
||||
mrc p15, 0, r1, c6, c0, 2 @ Read IFAR
|
||||
stmfd sp!,{r1} @ Store the IFAR
|
||||
|
||||
mrc p15, 0, r1, c5, c0, 1 @ Read IFSR
|
||||
stmfd sp!,{r1} @ Store the IFSR
|
||||
|
||||
mrc p15, 0, r1, c6, c0, 0 @ Read DFAR
|
||||
stmfd sp!,{r1} @ Store the DFAR
|
||||
|
||||
mrc p15, 0, r1, c5, c0, 0 @ Read DFSR
|
||||
stmfd sp!,{r1} @ Store the DFSR
|
||||
|
||||
mrs r1,spsr @ Read SPSR (which is the pre-exception CPSR)
|
||||
stmfd sp!,{r1} @ Store the SPSR
|
||||
|
||||
stmfd sp!,{lr} @ Store the link register (which is the pre-exception PC)
|
||||
stmfd sp,{sp,lr}^ @ Store user/system mode stack pointer and link register
|
||||
nop @ Required by ARM architecture
|
||||
sub sp,sp,#0x08 @ Adjust stack pointer
|
||||
stmfd sp!,{r2-r12} @ Store general purpose registers
|
||||
|
||||
ldr r3,[sp,#0x40] @ Read saved R1 from the stack (it was saved by the exception entry routine)
|
||||
ldr r2,[sp,#0x3C] @ Read saved R0 from the stack (it was saved by the exception entry routine)
|
||||
stmfd sp!,{r2-r3} @ Store general purpose registers R0 and R1
|
||||
|
||||
mov r1,sp @ Prepare System Context pointer as an argument for the exception handler
|
||||
|
||||
ldr r2,LIndirectgExceptionHandlers @ Offset to 32-bit address of exception handler
|
||||
ldr r2,[r2] @ Load exception handler table
|
||||
ldr r3,[r2,r0,lsl #2] @ Index to find the handler for this exception
|
||||
|
||||
// blx r3 @ Call exception handler
|
||||
bx r3 @ Call exception handler
|
||||
|
||||
ldr r2,[sp,#0x40] @ Load CPSR from context, in case it has changed
|
||||
msr SPSR_cxsf,r2 @ Store it back to the SPSR to be restored when exiting this handler
|
||||
|
||||
ldmfd sp!,{r0-r12} @ Restore general purpose registers
|
||||
ldmia sp,{sp,lr}^ @ Restore user/system mode stack pointer and link register
|
||||
nop @ Required by ARM architecture
|
||||
add sp,sp,#0x08 @ Adjust stack pointer
|
||||
ldmfd sp!,{lr} @ Restore the link register (which is the pre-exception PC)
|
||||
add sp,sp,#0x1C @ Clear out the remaining stack space
|
||||
movs pc,lr @ Return from exception
|
||||
|
@ -1,152 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2008-2009 Apple Inc. All rights reserved.
|
||||
//
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are licensed and made available under the terms and conditions of the BSD License
|
||||
// which accompanies this distribution. The full text of the license may be found at
|
||||
// http://opensource.org/licenses/bsd-license.php
|
||||
//
|
||||
// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
EXPORT ExceptionHandlersStart
|
||||
EXPORT ExceptionHandlersEnd
|
||||
EXPORT CommonExceptionEntry
|
||||
EXPORT AsmCommonExceptionEntry
|
||||
IMPORT gExceptionHandlers
|
||||
|
||||
AREA DxeExceptionHandlers, CODE, READONLY
|
||||
|
||||
ExceptionHandlersStart
|
||||
|
||||
Reset
|
||||
B ResetEntry
|
||||
|
||||
UndefinedInstruction
|
||||
B UndefinedInstructionEntry
|
||||
|
||||
SoftwareInterrupt
|
||||
B SoftwareInterruptEntry
|
||||
|
||||
PrefetchAbort
|
||||
B PrefetchAbortEntry
|
||||
|
||||
DataAbort
|
||||
B DataAbortEntry
|
||||
|
||||
ReservedException
|
||||
B ReservedExceptionEntry
|
||||
|
||||
Irq
|
||||
B IrqEntry
|
||||
|
||||
Fiq
|
||||
B FiqEntry
|
||||
|
||||
ResetEntry
|
||||
STMFD SP!,{R0-R1}
|
||||
MOV R0,#0
|
||||
LDR R1,CommonExceptionEntry
|
||||
BX R1
|
||||
|
||||
UndefinedInstructionEntry
|
||||
STMFD SP!,{R0-R1}
|
||||
MOV R0,#1
|
||||
LDR R1,CommonExceptionEntry
|
||||
BX R1
|
||||
|
||||
SoftwareInterruptEntry
|
||||
STMFD SP!,{R0-R1}
|
||||
MOV R0,#2
|
||||
LDR R1,CommonExceptionEntry
|
||||
BX R1
|
||||
|
||||
PrefetchAbortEntry
|
||||
STMFD SP!,{R0-R1}
|
||||
MOV R0,#3
|
||||
SUB LR,LR,#4
|
||||
LDR R1,CommonExceptionEntry
|
||||
BX R1
|
||||
|
||||
DataAbortEntry
|
||||
STMFD SP!,{R0-R1}
|
||||
MOV R0,#4
|
||||
SUB LR,LR,#8
|
||||
LDR R1,CommonExceptionEntry
|
||||
BX R1
|
||||
|
||||
ReservedExceptionEntry
|
||||
STMFD SP!,{R0-R1}
|
||||
MOV R0,#5
|
||||
LDR R1,CommonExceptionEntry
|
||||
BX R1
|
||||
|
||||
IrqEntry
|
||||
STMFD SP!,{R0-R1}
|
||||
MOV R0,#6
|
||||
SUB LR,LR,#4
|
||||
LDR R1,CommonExceptionEntry
|
||||
BX R1
|
||||
|
||||
FiqEntry
|
||||
STMFD SP!,{R0-R1}
|
||||
MOV R0,#7
|
||||
SUB LR,LR,#4
|
||||
LDR R1,CommonExceptionEntry
|
||||
BX R1
|
||||
|
||||
CommonExceptionEntry
|
||||
DCD 0x12345678
|
||||
|
||||
ExceptionHandlersEnd
|
||||
|
||||
AsmCommonExceptionEntry
|
||||
MRC p15, 0, r1, c6, c0, 2 ; Read IFAR
|
||||
STMFD SP!,{R1} ; Store the IFAR
|
||||
|
||||
MRC p15, 0, r1, c5, c0, 1 ; Read IFSR
|
||||
STMFD SP!,{R1} ; Store the IFSR
|
||||
|
||||
MRC p15, 0, r1, c6, c0, 0 ; Read DFAR
|
||||
STMFD SP!,{R1} ; Store the DFAR
|
||||
|
||||
MRC p15, 0, r1, c5, c0, 0 ; Read DFSR
|
||||
STMFD SP!,{R1} ; Store the DFSR
|
||||
|
||||
MRS R1,SPSR ; Read SPSR (which is the pre-exception CPSR)
|
||||
STMFD SP!,{R1} ; Store the SPSR
|
||||
|
||||
STMFD SP!,{LR} ; Store the link register (which is the pre-exception PC)
|
||||
STMFD SP,{SP,LR}^ ; Store user/system mode stack pointer and link register
|
||||
NOP ; Required by ARM architecture
|
||||
SUB SP,SP,#0x08 ; Adjust stack pointer
|
||||
STMFD SP!,{R2-R12} ; Store general purpose registers
|
||||
|
||||
LDR R3,[SP,#0x40] ; Read saved R1 from the stack (it was saved by the exception entry routine)
|
||||
LDR R2,[SP,#0x3C] ; Read saved R0 from the stack (it was saved by the exception entry routine)
|
||||
STMFD SP!,{R2-R3} ; Store general purpose registers R0 and R1
|
||||
|
||||
MOV R1,SP ; Prepare System Context pointer as an argument for the exception handler
|
||||
|
||||
LDR R2,=gExceptionHandlers ; Load exception handler table
|
||||
LDR R3,[R2,R0,LSL #2] ; Index to find the handler for this exception
|
||||
|
||||
BLX R3 ; Call exception handler
|
||||
|
||||
LDR R2,[SP,#0x40] ; Load CPSR from context, in case it has changed
|
||||
MSR SPSR_cxsf,R2 ; Store it back to the SPSR to be restored when exiting this handler
|
||||
|
||||
LDMFD SP!,{R0-R12} ; Restore general purpose registers
|
||||
LDM SP,{SP,LR}^ ; Restore user/system mode stack pointer and link register
|
||||
NOP ; Required by ARM architecture
|
||||
ADD SP,SP,#0x08 ; Adjust stack pointer
|
||||
LDMFD SP!,{LR} ; Restore the link register (which is the pre-exception PC)
|
||||
ADD SP,SP,#0x1C ; Clear out the remaining stack space
|
||||
MOVS PC,LR ; Return from exception
|
||||
|
||||
END
|
||||
|
||||
|
@ -1,323 +0,0 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2008-2009, Apple Inc. All rights reserved.
|
||||
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include "CpuDxe.h"
|
||||
|
||||
|
||||
|
||||
/**
|
||||
This function flushes the range of addresses from Start to Start+Length
|
||||
from the processor's data cache. If Start is not aligned to a cache line
|
||||
boundary, then the bytes before Start to the preceding cache line boundary
|
||||
are also flushed. If Start+Length is not aligned to a cache line boundary,
|
||||
then the bytes past Start+Length to the end of the next cache line boundary
|
||||
are also flushed. The FlushType of EfiCpuFlushTypeWriteBackInvalidate must be
|
||||
supported. If the data cache is fully coherent with all DMA operations, then
|
||||
this function can just return EFI_SUCCESS. If the processor does not support
|
||||
flushing a range of the data cache, then the entire data cache can be flushed.
|
||||
|
||||
@param This The EFI_CPU_ARCH_PROTOCOL instance.
|
||||
@param Start The beginning physical address to flush from the processor's data
|
||||
cache.
|
||||
@param Length The number of bytes to flush from the processor's data cache. This
|
||||
function may flush more bytes than Length specifies depending upon
|
||||
the granularity of the flush operation that the processor supports.
|
||||
@param FlushType Specifies the type of flush operation to perform.
|
||||
|
||||
@retval EFI_SUCCESS The address range from Start to Start+Length was flushed from
|
||||
the processor's data cache.
|
||||
@retval EFI_UNSUPPORTED The processor does not support the cache flush type specified
|
||||
by FlushType.
|
||||
@retval EFI_DEVICE_ERROR The address range from Start to Start+Length could not be flushed
|
||||
from the processor's data cache.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuFlushCpuDataCache (
|
||||
IN EFI_CPU_ARCH_PROTOCOL *This,
|
||||
IN EFI_PHYSICAL_ADDRESS Start,
|
||||
IN UINT64 Length,
|
||||
IN EFI_CPU_FLUSH_TYPE FlushType
|
||||
)
|
||||
{
|
||||
return FlushCpuDataCache (Start, Length, FlushType);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function enables interrupt processing by the processor.
|
||||
|
||||
@param This The EFI_CPU_ARCH_PROTOCOL instance.
|
||||
|
||||
@retval EFI_SUCCESS Interrupts are enabled on the processor.
|
||||
@retval EFI_DEVICE_ERROR Interrupts could not be enabled on the processor.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuEnableInterrupt (
|
||||
IN EFI_CPU_ARCH_PROTOCOL *This
|
||||
)
|
||||
{
|
||||
EnableInterrupts ();
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function disables interrupt processing by the processor.
|
||||
|
||||
@param This The EFI_CPU_ARCH_PROTOCOL instance.
|
||||
|
||||
@retval EFI_SUCCESS Interrupts are disabled on the processor.
|
||||
@retval EFI_DEVICE_ERROR Interrupts could not be disabled on the processor.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuDisableInterrupt (
|
||||
IN EFI_CPU_ARCH_PROTOCOL *This
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Disables CPU interrupts.
|
||||
|
||||
Arguments:
|
||||
This - Protocol instance structure
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - If interrupts were disabled in the CPU.
|
||||
EFI_DEVICE_ERROR - If interrupts could not be disabled on the CPU.
|
||||
|
||||
--*/
|
||||
{
|
||||
DisableInterrupts ();
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function retrieves the processor's current interrupt state a returns it in
|
||||
State. If interrupts are currently enabled, then TRUE is returned. If interrupts
|
||||
are currently disabled, then FALSE is returned.
|
||||
|
||||
@param This The EFI_CPU_ARCH_PROTOCOL instance.
|
||||
@param State A pointer to the processor's current interrupt state. Set to TRUE if
|
||||
interrupts are enabled and FALSE if interrupts are disabled.
|
||||
|
||||
@retval EFI_SUCCESS The processor's current interrupt state was returned in State.
|
||||
@retval EFI_INVALID_PARAMETER State is NULL.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuGetInterruptState (
|
||||
IN EFI_CPU_ARCH_PROTOCOL *This,
|
||||
OUT BOOLEAN *State
|
||||
)
|
||||
{
|
||||
if (State == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
*State = GetInterruptState ();
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function generates an INIT on the processor. If this function succeeds, then the
|
||||
processor will be reset, and control will not be returned to the caller. If InitType is
|
||||
not supported by this processor, or the processor cannot programmatically generate an
|
||||
INIT without help from external hardware, then EFI_UNSUPPORTED is returned. If an error
|
||||
occurs attempting to generate an INIT, then EFI_DEVICE_ERROR is returned.
|
||||
|
||||
@param This The EFI_CPU_ARCH_PROTOCOL instance.
|
||||
@param InitType The type of processor INIT to perform.
|
||||
|
||||
@retval EFI_SUCCESS The processor INIT was performed. This return code should never be seen.
|
||||
@retval EFI_UNSUPPORTED The processor INIT operation specified by InitType is not supported
|
||||
by this processor.
|
||||
@retval EFI_DEVICE_ERROR The processor INIT failed.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuInit (
|
||||
IN EFI_CPU_ARCH_PROTOCOL *This,
|
||||
IN EFI_CPU_INIT_TYPE InitType
|
||||
)
|
||||
{
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function registers and enables the handler specified by InterruptHandler for a processor
|
||||
interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the
|
||||
handler for the processor interrupt or exception type specified by InterruptType is uninstalled.
|
||||
The installed handler is called once for each processor interrupt or exception.
|
||||
|
||||
@param This The EFI_CPU_ARCH_PROTOCOL instance.
|
||||
@param InterruptType A pointer to the processor's current interrupt state. Set to TRUE if interrupts
|
||||
are enabled and FALSE if interrupts are disabled.
|
||||
@param InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called
|
||||
when a processor interrupt occurs. If this parameter is NULL, then the handler
|
||||
will be uninstalled.
|
||||
|
||||
@retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled.
|
||||
@retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was
|
||||
previously installed.
|
||||
@retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not
|
||||
previously installed.
|
||||
@retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuRegisterInterruptHandler (
|
||||
IN EFI_CPU_ARCH_PROTOCOL *This,
|
||||
IN EFI_EXCEPTION_TYPE InterruptType,
|
||||
IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
|
||||
)
|
||||
{
|
||||
return RegisterInterruptHandler (InterruptType, InterruptHandler);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function reads the processor timer specified by TimerIndex and returns it in TimerValue.
|
||||
|
||||
@param This The EFI_CPU_ARCH_PROTOCOL instance.
|
||||
@param TimerIndex Specifies which processor timer is to be returned in TimerValue. This parameter
|
||||
must be between 0 and NumberOfTimers-1.
|
||||
@param TimerValue Pointer to the returned timer value.
|
||||
@param TimerPeriod A pointer to the amount of time that passes in femtoseconds for each increment
|
||||
of TimerValue.
|
||||
|
||||
@retval EFI_SUCCESS The processor timer value specified by TimerIndex was returned in TimerValue.
|
||||
@retval EFI_DEVICE_ERROR An error occurred attempting to read one of the processor's timers.
|
||||
@retval EFI_INVALID_PARAMETER TimerValue is NULL or TimerIndex is not valid.
|
||||
@retval EFI_UNSUPPORTED The processor does not have any readable timers.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuGetTimerValue (
|
||||
IN EFI_CPU_ARCH_PROTOCOL *This,
|
||||
IN UINT32 TimerIndex,
|
||||
OUT UINT64 *TimerValue,
|
||||
OUT UINT64 *TimerPeriod OPTIONAL
|
||||
)
|
||||
{
|
||||
return GetTimerValue (TimerIndex, TimerValue, TimerPeriod);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function modifies the attributes for the memory region specified by BaseAddress and
|
||||
Length from their current attributes to the attributes specified by Attributes.
|
||||
|
||||
@param This The EFI_CPU_ARCH_PROTOCOL instance.
|
||||
@param BaseAddress The physical address that is the start address of a memory region.
|
||||
@param Length The size in bytes of the memory region.
|
||||
@param Attributes The bit mask of attributes to set for the memory region.
|
||||
|
||||
@retval EFI_SUCCESS The attributes were set for the memory region.
|
||||
@retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by
|
||||
BaseAddress and Length cannot be modified.
|
||||
@retval EFI_INVALID_PARAMETER Length is zero.
|
||||
@retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of
|
||||
the memory resource range.
|
||||
@retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory
|
||||
resource range specified by BaseAddress and Length.
|
||||
The bit mask of attributes is not support for the memory resource
|
||||
range specified by BaseAddress and Length.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuSetMemoryAttributes (
|
||||
IN EFI_CPU_ARCH_PROTOCOL *This,
|
||||
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||
IN UINT64 Length,
|
||||
IN UINT64 Attributes
|
||||
)
|
||||
{
|
||||
//
|
||||
// This is used to set cachability via the MMU on ARM
|
||||
//
|
||||
// This more about optimization and we can usually run fine if the default
|
||||
// settings for cachability are good.
|
||||
//
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Globals used to initialize the protocol
|
||||
//
|
||||
EFI_HANDLE mCpuHandle = NULL;
|
||||
EFI_CPU_ARCH_PROTOCOL mCpu = {
|
||||
CpuFlushCpuDataCache,
|
||||
CpuEnableInterrupt,
|
||||
CpuDisableInterrupt,
|
||||
CpuGetInterruptState,
|
||||
CpuInit,
|
||||
CpuRegisterInterruptHandler,
|
||||
CpuGetTimerValue,
|
||||
CpuSetMemoryAttributes,
|
||||
0, // NumberOfTimers
|
||||
4, // DmaBufferAlignment
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Initialize the state information for the CPU Architectural Protocol
|
||||
|
||||
@param ImageHandle of the loaded driver
|
||||
@param SystemTable Pointer to the System Table
|
||||
|
||||
@retval EFI_SUCCESS Protocol registered
|
||||
@retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure
|
||||
@retval EFI_DEVICE_ERROR Hardware problems
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
CpuDxeInitialize (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
InitializeExceptions (&mCpu);
|
||||
|
||||
//
|
||||
// Install CPU Architectural Protocol and the thunk protocol
|
||||
//
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&mCpuHandle,
|
||||
&gEfiCpuArchProtocolGuid, &mCpu,
|
||||
NULL
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
@ -1,124 +0,0 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2006 - 2008, Intel Corporation <BR>
|
||||
Portions copyright (c) 2008-2009 Apple Inc. All rights reserved.
|
||||
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
|
||||
#include <PiDxe.h>
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/DxeServicesTableLib.h>
|
||||
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
|
||||
#include <Protocol/Cpu.h>
|
||||
#include <Protocol/DebugSupport.h>
|
||||
|
||||
|
||||
|
||||
/**
|
||||
This function registers and enables the handler specified by InterruptHandler for a processor
|
||||
interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the
|
||||
handler for the processor interrupt or exception type specified by InterruptType is uninstalled.
|
||||
The installed handler is called once for each processor interrupt or exception.
|
||||
|
||||
@param InterruptType A pointer to the processor's current interrupt state. Set to TRUE if interrupts
|
||||
are enabled and FALSE if interrupts are disabled.
|
||||
@param InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called
|
||||
when a processor interrupt occurs. If this parameter is NULL, then the handler
|
||||
will be uninstalled.
|
||||
|
||||
@retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled.
|
||||
@retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was
|
||||
previously installed.
|
||||
@retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not
|
||||
previously installed.
|
||||
@retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
RegisterInterruptHandler (
|
||||
IN EFI_EXCEPTION_TYPE InterruptType,
|
||||
IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
|
||||
);
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
InitializeExceptions (
|
||||
IN EFI_CPU_ARCH_PROTOCOL *Cpu
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
This function reads the processor timer specified by TimerIndex and returns it in TimerValue.
|
||||
|
||||
@param TimerIndex Specifies which processor timer is to be returned in TimerValue. This parameter
|
||||
must be between 0 and NumberOfTimers-1.
|
||||
@param TimerValue Pointer to the returned timer value.
|
||||
@param TimerPeriod A pointer to the amount of time that passes in femtoseconds for each increment
|
||||
of TimerValue.
|
||||
|
||||
@retval EFI_SUCCESS The processor timer value specified by TimerIndex was returned in TimerValue.
|
||||
@retval EFI_DEVICE_ERROR An error occurred attempting to read one of the processor's timers.
|
||||
@retval EFI_INVALID_PARAMETER TimerValue is NULL or TimerIndex is not valid.
|
||||
@retval EFI_UNSUPPORTED The processor does not have any readable timers.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
GetTimerValue (
|
||||
IN UINT32 TimerIndex,
|
||||
OUT UINT64 *TimerValue,
|
||||
OUT UINT64 *TimerPeriod OPTIONAL
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
This function flushes the range of addresses from Start to Start+Length
|
||||
from the processor's data cache. If Start is not aligned to a cache line
|
||||
boundary, then the bytes before Start to the preceding cache line boundary
|
||||
are also flushed. If Start+Length is not aligned to a cache line boundary,
|
||||
then the bytes past Start+Length to the end of the next cache line boundary
|
||||
are also flushed. The FlushType of EfiCpuFlushTypeWriteBackInvalidate must be
|
||||
supported. If the data cache is fully coherent with all DMA operations, then
|
||||
this function can just return EFI_SUCCESS. If the processor does not support
|
||||
flushing a range of the data cache, then the entire data cache can be flushed.
|
||||
|
||||
@param Start The beginning physical address to flush from the processor's data
|
||||
cache.
|
||||
@param Length The number of bytes to flush from the processor's data cache. This
|
||||
function may flush more bytes than Length specifies depending upon
|
||||
the granularity of the flush operation that the processor supports.
|
||||
@param FlushType Specifies the type of flush operation to perform.
|
||||
|
||||
@retval EFI_SUCCESS The address range from Start to Start+Length was flushed from
|
||||
the processor's data cache.
|
||||
@retval EFI_UNSUPPORTED The processor does not support the cache flush type specified
|
||||
by FlushType.
|
||||
@retval EFI_DEVICE_ERROR The address range from Start to Start+Length could not be flushed
|
||||
from the processor's data cache.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FlushCpuDataCache (
|
||||
IN EFI_PHYSICAL_ADDRESS Start,
|
||||
IN UINT64 Length,
|
||||
IN EFI_CPU_FLUSH_TYPE FlushType
|
||||
);
|
||||
|
||||
|
@ -1,183 +0,0 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2008-2009, Apple Inc. All rights reserved.
|
||||
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include <CpuDxe.h>
|
||||
|
||||
|
||||
EFI_EXCEPTION_CALLBACK gExceptionHandlers[0x100];
|
||||
|
||||
|
||||
/**
|
||||
This function registers and enables the handler specified by InterruptHandler for a processor
|
||||
interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the
|
||||
handler for the processor interrupt or exception type specified by InterruptType is uninstalled.
|
||||
The installed handler is called once for each processor interrupt or exception.
|
||||
|
||||
@param InterruptType A pointer to the processor's current interrupt state. Set to TRUE if interrupts
|
||||
are enabled and FALSE if interrupts are disabled.
|
||||
@param InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called
|
||||
when a processor interrupt occurs. If this parameter is NULL, then the handler
|
||||
will be uninstalled.
|
||||
|
||||
@retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled.
|
||||
@retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was
|
||||
previously installed.
|
||||
@retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not
|
||||
previously installed.
|
||||
@retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
RegisterInterruptHandler (
|
||||
IN EFI_EXCEPTION_TYPE InterruptType,
|
||||
IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
|
||||
)
|
||||
{
|
||||
if (InterruptType > 0xFF) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if ((InterruptHandler == NULL) && (gExceptionHandlers[InterruptType] == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((InterruptHandler != NULL) && (gExceptionHandlers[InterruptType] != NULL)) {
|
||||
return EFI_ALREADY_STARTED;
|
||||
}
|
||||
|
||||
gExceptionHandlers[InterruptType] = InterruptHandler;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
DefaultExceptionHandler (
|
||||
IN EFI_EXCEPTION_TYPE ExceptionType,
|
||||
IN OUT EFI_SYSTEM_CONTEXT SystemContext
|
||||
)
|
||||
{
|
||||
DEBUG ((EFI_D_ERROR, "Exception %d from %x\n", ExceptionType, SystemContext.SystemContextIa32->Eip));
|
||||
ASSERT (FALSE);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
InitializeExceptions (
|
||||
IN EFI_CPU_ARCH_PROTOCOL *Cpu
|
||||
)
|
||||
{
|
||||
// You need to initialize gExceptionHandlers[] to point to DefaultExceptionHandler()
|
||||
// and write all the assembly to handle the interrupts.
|
||||
ASSERT (FALSE);
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
This function reads the processor timer specified by TimerIndex and returns it in TimerValue.
|
||||
|
||||
@param TimerIndex Specifies which processor timer is to be returned in TimerValue. This parameter
|
||||
must be between 0 and NumberOfTimers-1.
|
||||
@param TimerValue Pointer to the returned timer value.
|
||||
@param TimerPeriod A pointer to the amount of time that passes in femtoseconds for each increment
|
||||
of TimerValue.
|
||||
|
||||
@retval EFI_SUCCESS The processor timer value specified by TimerIndex was returned in TimerValue.
|
||||
@retval EFI_DEVICE_ERROR An error occurred attempting to read one of the processor's timers.
|
||||
@retval EFI_INVALID_PARAMETER TimerValue is NULL or TimerIndex is not valid.
|
||||
@retval EFI_UNSUPPORTED The processor does not have any readable timers.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GetTimerValue (
|
||||
IN UINT32 TimerIndex,
|
||||
OUT UINT64 *TimerValue,
|
||||
OUT UINT64 *TimerPeriod OPTIONAL
|
||||
)
|
||||
{
|
||||
if (TimerValue == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (TimerIndex == 0) {
|
||||
*TimerValue = AsmReadTsc ();
|
||||
if (TimerPeriod != NULL) {
|
||||
//
|
||||
// BugBug: Hard coded. Don't know how to do this generically
|
||||
//
|
||||
*TimerPeriod = 1000000000;
|
||||
}
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function flushes the range of addresses from Start to Start+Length
|
||||
from the processor's data cache. If Start is not aligned to a cache line
|
||||
boundary, then the bytes before Start to the preceding cache line boundary
|
||||
are also flushed. If Start+Length is not aligned to a cache line boundary,
|
||||
then the bytes past Start+Length to the end of the next cache line boundary
|
||||
are also flushed. The FlushType of EfiCpuFlushTypeWriteBackInvalidate must be
|
||||
supported. If the data cache is fully coherent with all DMA operations, then
|
||||
this function can just return EFI_SUCCESS. If the processor does not support
|
||||
flushing a range of the data cache, then the entire data cache can be flushed.
|
||||
|
||||
@param Start The beginning physical address to flush from the processor's data
|
||||
cache.
|
||||
@param Length The number of bytes to flush from the processor's data cache. This
|
||||
function may flush more bytes than Length specifies depending upon
|
||||
the granularity of the flush operation that the processor supports.
|
||||
@param FlushType Specifies the type of flush operation to perform.
|
||||
|
||||
@retval EFI_SUCCESS The address range from Start to Start+Length was flushed from
|
||||
the processor's data cache.
|
||||
@retval EFI_UNSUPPORTED The processor does not support the cache flush type specified
|
||||
by FlushType.
|
||||
@retval EFI_DEVICE_ERROR The address range from Start to Start+Length could not be flushed
|
||||
from the processor's data cache.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FlushCpuDataCache (
|
||||
IN EFI_PHYSICAL_ADDRESS Start,
|
||||
IN UINT64 Length,
|
||||
IN EFI_CPU_FLUSH_TYPE FlushType
|
||||
)
|
||||
{
|
||||
if (FlushType == EfiCpuFlushTypeWriteBackInvalidate) {
|
||||
AsmWbinvd ();
|
||||
return EFI_SUCCESS;
|
||||
} else if (FlushType == EfiCpuFlushTypeInvalidate) {
|
||||
AsmInvd ();
|
||||
return EFI_SUCCESS;
|
||||
} else {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -1,70 +0,0 @@
|
||||
#/** @file
|
||||
#
|
||||
# Component discription file for Bds module
|
||||
#
|
||||
# Copyright (c) 2008, Intel Corporation. <BR>
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
#**/
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = TemplateCpuDxe
|
||||
FILE_GUID = CB6DC1E4-5B27-41E8-BC27-9AA50B62081E
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
|
||||
ENTRY_POINT = CpuDxeInitialize
|
||||
|
||||
|
||||
[Sources.common]
|
||||
CpuDxe.c
|
||||
|
||||
[Sources.ARM]
|
||||
Arm/Exception.c
|
||||
Arm/Exceptions.asm
|
||||
Arm/Exceptions.S
|
||||
|
||||
[Sources.IA32]
|
||||
IA32/Exception.c
|
||||
|
||||
[Sources.X64]
|
||||
X64/Exception.c
|
||||
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
EmbeddedPkg/EmbeddedPkg.dec
|
||||
|
||||
[Packages.ARM]
|
||||
ArmPkg/ArmPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
UefiRuntimeServicesTableLib
|
||||
ReportStatusCodeLib
|
||||
PerformanceLib
|
||||
DxeServicesTableLib
|
||||
MemoryAllocationLib
|
||||
UefiLib
|
||||
UefiBootServicesTableLib
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
UefiDriverEntryPoint
|
||||
CacheMaintenanceLib
|
||||
|
||||
[Protocols]
|
||||
gEfiCpuArchProtocolGuid
|
||||
|
||||
[Pcd.ARM]
|
||||
gArmTokenSpaceGuid.PcdCpuVectorBaseAddress
|
||||
|
||||
|
||||
[depex]
|
||||
TRUE
|
@ -1,183 +0,0 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2008-2009, Apple Inc. All rights reserved.
|
||||
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include <CpuDxe.h>
|
||||
|
||||
|
||||
EFI_EXCEPTION_CALLBACK gExceptionHandlers[0x100];
|
||||
|
||||
|
||||
/**
|
||||
This function registers and enables the handler specified by InterruptHandler for a processor
|
||||
interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the
|
||||
handler for the processor interrupt or exception type specified by InterruptType is uninstalled.
|
||||
The installed handler is called once for each processor interrupt or exception.
|
||||
|
||||
@param InterruptType A pointer to the processor's current interrupt state. Set to TRUE if interrupts
|
||||
are enabled and FALSE if interrupts are disabled.
|
||||
@param InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called
|
||||
when a processor interrupt occurs. If this parameter is NULL, then the handler
|
||||
will be uninstalled.
|
||||
|
||||
@retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled.
|
||||
@retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was
|
||||
previously installed.
|
||||
@retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not
|
||||
previously installed.
|
||||
@retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
RegisterInterruptHandler (
|
||||
IN EFI_EXCEPTION_TYPE InterruptType,
|
||||
IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
|
||||
)
|
||||
{
|
||||
if (InterruptType > 0xFF) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if ((InterruptHandler == NULL) && (gExceptionHandlers[InterruptType] == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((InterruptHandler != NULL) && (gExceptionHandlers[InterruptType] != NULL)) {
|
||||
return EFI_ALREADY_STARTED;
|
||||
}
|
||||
|
||||
gExceptionHandlers[InterruptType] = InterruptHandler;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
DefaultExceptionHandler (
|
||||
IN EFI_EXCEPTION_TYPE ExceptionType,
|
||||
IN OUT EFI_SYSTEM_CONTEXT SystemContext
|
||||
)
|
||||
{
|
||||
DEBUG ((EFI_D_ERROR, "Exception %d from %x\n", ExceptionType, SystemContext.SystemContextX64->Rip));
|
||||
ASSERT (FALSE);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
InitializeExceptions (
|
||||
IN EFI_CPU_ARCH_PROTOCOL *Cpu
|
||||
)
|
||||
{
|
||||
// You need to initialize gExceptionHandlers[] to point to DefaultExceptionHandler()
|
||||
// and write all the assembly to handle the interrupts.
|
||||
ASSERT (FALSE);
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
This function reads the processor timer specified by TimerIndex and returns it in TimerValue.
|
||||
|
||||
@param TimerIndex Specifies which processor timer is to be returned in TimerValue. This parameter
|
||||
must be between 0 and NumberOfTimers-1.
|
||||
@param TimerValue Pointer to the returned timer value.
|
||||
@param TimerPeriod A pointer to the amount of time that passes in femtoseconds for each increment
|
||||
of TimerValue.
|
||||
|
||||
@retval EFI_SUCCESS The processor timer value specified by TimerIndex was returned in TimerValue.
|
||||
@retval EFI_DEVICE_ERROR An error occurred attempting to read one of the processor's timers.
|
||||
@retval EFI_INVALID_PARAMETER TimerValue is NULL or TimerIndex is not valid.
|
||||
@retval EFI_UNSUPPORTED The processor does not have any readable timers.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GetTimerValue (
|
||||
IN UINT32 TimerIndex,
|
||||
OUT UINT64 *TimerValue,
|
||||
OUT UINT64 *TimerPeriod OPTIONAL
|
||||
)
|
||||
{
|
||||
if (TimerValue == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (TimerIndex == 0) {
|
||||
*TimerValue = AsmReadTsc ();
|
||||
if (TimerPeriod != NULL) {
|
||||
//
|
||||
// BugBug: Hard coded. Don't know how to do this generically
|
||||
//
|
||||
*TimerPeriod = 1000000000;
|
||||
}
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function flushes the range of addresses from Start to Start+Length
|
||||
from the processor's data cache. If Start is not aligned to a cache line
|
||||
boundary, then the bytes before Start to the preceding cache line boundary
|
||||
are also flushed. If Start+Length is not aligned to a cache line boundary,
|
||||
then the bytes past Start+Length to the end of the next cache line boundary
|
||||
are also flushed. The FlushType of EfiCpuFlushTypeWriteBackInvalidate must be
|
||||
supported. If the data cache is fully coherent with all DMA operations, then
|
||||
this function can just return EFI_SUCCESS. If the processor does not support
|
||||
flushing a range of the data cache, then the entire data cache can be flushed.
|
||||
|
||||
@param Start The beginning physical address to flush from the processor's data
|
||||
cache.
|
||||
@param Length The number of bytes to flush from the processor's data cache. This
|
||||
function may flush more bytes than Length specifies depending upon
|
||||
the granularity of the flush operation that the processor supports.
|
||||
@param FlushType Specifies the type of flush operation to perform.
|
||||
|
||||
@retval EFI_SUCCESS The address range from Start to Start+Length was flushed from
|
||||
the processor's data cache.
|
||||
@retval EFI_UNSUPPORTED The processor does not support the cache flush type specified
|
||||
by FlushType.
|
||||
@retval EFI_DEVICE_ERROR The address range from Start to Start+Length could not be flushed
|
||||
from the processor's data cache.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FlushCpuDataCache (
|
||||
IN EFI_PHYSICAL_ADDRESS Start,
|
||||
IN UINT64 Length,
|
||||
IN EFI_CPU_FLUSH_TYPE FlushType
|
||||
)
|
||||
{
|
||||
if (FlushType == EfiCpuFlushTypeWriteBackInvalidate) {
|
||||
AsmWbinvd ();
|
||||
return EFI_SUCCESS;
|
||||
} else if (FlushType == EfiCpuFlushTypeInvalidate) {
|
||||
AsmInvd ();
|
||||
return EFI_SUCCESS;
|
||||
} else {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -1,55 +0,0 @@
|
||||
#/** @file
|
||||
#
|
||||
# Component discription file for Bds module
|
||||
#
|
||||
# Copyright (c) 2008, Apple Inc. <BR>
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
#**/
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = TemplateTimerDxe
|
||||
FILE_GUID = E697928E-7C98-4501-8406-21F5509549CC
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
|
||||
ENTRY_POINT = TimerInitialize
|
||||
|
||||
[Sources.common]
|
||||
Timer.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
EmbeddedPkg/EmbeddedPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
UefiRuntimeServicesTableLib
|
||||
PerformanceLib
|
||||
UefiLib
|
||||
UefiBootServicesTableLib
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
UefiDriverEntryPoint
|
||||
IoLib
|
||||
|
||||
[Guids]
|
||||
|
||||
[Protocols]
|
||||
gEfiTimerArchProtocolGuid
|
||||
gHardwareInterruptProtocolGuid
|
||||
|
||||
[Pcd.common]
|
||||
gEmbeddedTokenSpaceGuid.PcdTimerBaseAddress
|
||||
gEmbeddedTokenSpaceGuid.PcdTimerVector
|
||||
gEmbeddedTokenSpaceGuid.PcdTimerPeriod
|
||||
|
||||
[Depex]
|
||||
gHardwareInterruptProtocolGuid
|
@ -1,377 +0,0 @@
|
||||
/** @file
|
||||
Template for Timer Architecture Protocol driver of the ARM flavor
|
||||
|
||||
Copyright (c) 2008-2009, Apple Inc. All rights reserved.
|
||||
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
|
||||
#include <PiDxe.h>
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
#include <Library/IoLib.h>
|
||||
|
||||
#include <Protocol/Timer.h>
|
||||
#include <Protocol/HardwareInterrupt.h>
|
||||
|
||||
//
|
||||
// Get Base Address of timer block from platform .DSC file
|
||||
//
|
||||
#define TIMER_BASE ((UINTN)FixedPcdGet32 (PcdTimerBaseAddress) + 0x00c0)
|
||||
|
||||
|
||||
#define TIMER_CMD ((UINTN)FixedPcdGet32 (PcdTimerBaseAddress) + 0x00000004)
|
||||
#define TIMER_DATA ((UINTN)FixedPcdGet32 (PcdTimerBaseAddress) + 0x00000008)
|
||||
|
||||
//
|
||||
// The notification function to call on every timer interrupt.
|
||||
// A bug in the compiler prevents us from initializing this here.
|
||||
//
|
||||
volatile EFI_TIMER_NOTIFY mTimerNotifyFunction;
|
||||
|
||||
//
|
||||
// The current period of the timer interrupt
|
||||
//
|
||||
volatile UINT64 mTimerPeriod = 0;
|
||||
|
||||
//
|
||||
// Cached copy of the Hardware Interrupt protocol instance
|
||||
//
|
||||
EFI_HARDWARE_INTERRUPT_PROTOCOL *gInterrupt = NULL;
|
||||
|
||||
|
||||
/**
|
||||
C Interrupt Handler calledin the interrupt context when Source interrupt is active.
|
||||
|
||||
@param Source Source of the interrupt. Hardware routing off a specific platform defines
|
||||
what source means.
|
||||
@param SystemContext Pointer to system register context. Mostly used by debuggers and will
|
||||
update the system context after the return from the interrupt if
|
||||
modified. Don't change these values unless you know what you are doing
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
TimerInterruptHandler (
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source,
|
||||
IN EFI_SYSTEM_CONTEXT SystemContext
|
||||
)
|
||||
{
|
||||
EFI_TPL OriginalTPL;
|
||||
|
||||
//
|
||||
// DXE core uses this callback for the EFI timer tick. The DXE core uses locks
|
||||
// that raise to TPL_HIGH and then restore back to current level. Thus we need
|
||||
// to make sure TPL level is set to TPL_HIGH while we are handling the timer tick.
|
||||
//
|
||||
OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
|
||||
|
||||
MmioWrite32 (TIMER_CMD, 0);
|
||||
|
||||
if (mTimerNotifyFunction) {
|
||||
mTimerNotifyFunction (mTimerPeriod);
|
||||
}
|
||||
|
||||
// restore state
|
||||
gBS->RestoreTPL (OriginalTPL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
This function registers the handler NotifyFunction so it is called every time
|
||||
the timer interrupt fires. It also passes the amount of time since the last
|
||||
handler call to the NotifyFunction. If NotifyFunction is NULL, then the
|
||||
handler is unregistered. If the handler is registered, then EFI_SUCCESS is
|
||||
returned. If the CPU does not support registering a timer interrupt handler,
|
||||
then EFI_UNSUPPORTED is returned. If an attempt is made to register a handler
|
||||
when a handler is already registered, then EFI_ALREADY_STARTED is returned.
|
||||
If an attempt is made to unregister a handler when a handler is not registered,
|
||||
then EFI_INVALID_PARAMETER is returned. If an error occurs attempting to
|
||||
register the NotifyFunction with the timer interrupt, then EFI_DEVICE_ERROR
|
||||
is returned.
|
||||
|
||||
@param This The EFI_TIMER_ARCH_PROTOCOL instance.
|
||||
@param NotifyFunction The function to call when a timer interrupt fires. This
|
||||
function executes at TPL_HIGH_LEVEL. The DXE Core will
|
||||
register a handler for the timer interrupt, so it can know
|
||||
how much time has passed. This information is used to
|
||||
signal timer based events. NULL will unregister the handler.
|
||||
|
||||
@retval EFI_SUCCESS The timer handler was registered.
|
||||
@retval EFI_UNSUPPORTED The platform does not support timer interrupts.
|
||||
@retval EFI_ALREADY_STARTED NotifyFunction is not NULL, and a handler is already
|
||||
registered.
|
||||
@retval EFI_INVALID_PARAMETER NotifyFunction is NULL, and a handler was not
|
||||
previously registered.
|
||||
@retval EFI_DEVICE_ERROR The timer handler could not be registered.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TimerDriverRegisterHandler (
|
||||
IN EFI_TIMER_ARCH_PROTOCOL *This,
|
||||
IN EFI_TIMER_NOTIFY NotifyFunction
|
||||
)
|
||||
{
|
||||
//
|
||||
// Check for invalid parameters
|
||||
//
|
||||
if (NotifyFunction == NULL && mTimerNotifyFunction == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (NotifyFunction != NULL && mTimerNotifyFunction != NULL) {
|
||||
return EFI_ALREADY_STARTED;
|
||||
}
|
||||
|
||||
mTimerNotifyFunction = NotifyFunction;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
This function adjusts the period of timer interrupts to the value specified
|
||||
by TimerPeriod. If the timer period is updated, then the selected timer
|
||||
period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned. If
|
||||
the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.
|
||||
If an error occurs while attempting to update the timer period, then the
|
||||
timer hardware will be put back in its state prior to this call, and
|
||||
EFI_DEVICE_ERROR is returned. If TimerPeriod is 0, then the timer interrupt
|
||||
is disabled. This is not the same as disabling the CPU's interrupts.
|
||||
Instead, it must either turn off the timer hardware, or it must adjust the
|
||||
interrupt controller so that a CPU interrupt is not generated when the timer
|
||||
interrupt fires.
|
||||
|
||||
@param This The EFI_TIMER_ARCH_PROTOCOL instance.
|
||||
@param TimerPeriod The rate to program the timer interrupt in 100 nS units. If
|
||||
the timer hardware is not programmable, then EFI_UNSUPPORTED is
|
||||
returned. If the timer is programmable, then the timer period
|
||||
will be rounded up to the nearest timer period that is supported
|
||||
by the timer hardware. If TimerPeriod is set to 0, then the
|
||||
timer interrupts will be disabled.
|
||||
|
||||
@retval EFI_SUCCESS The timer period was changed.
|
||||
@retval EFI_UNSUPPORTED The platform cannot change the period of the timer interrupt.
|
||||
@retval EFI_DEVICE_ERROR The timer period could not be changed due to a device error.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TimerDriverSetTimerPeriod (
|
||||
IN EFI_TIMER_ARCH_PROTOCOL *This,
|
||||
IN UINT64 TimerPeriod
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT64 TimerCount;
|
||||
|
||||
if (TimerPeriod == 0) {
|
||||
//
|
||||
// Disable interrupt 0 and timer
|
||||
//
|
||||
MmioAnd32 (TIMER_DATA, 0);
|
||||
|
||||
Status = gInterrupt->DisableInterruptSource (gInterrupt, FixedPcdGet32 (PcdTimerVector));
|
||||
} else {
|
||||
//
|
||||
// Convert TimerPeriod into Timer F counts
|
||||
//
|
||||
TimerCount = DivU64x32 (TimerPeriod + 5, 10);
|
||||
|
||||
//
|
||||
// Program Timer F with the new count value
|
||||
//
|
||||
MmioWrite32 (TIMER_DATA, (UINT32)TimerCount);
|
||||
|
||||
//
|
||||
// Enable interrupt and initialize and enable timer.
|
||||
//
|
||||
MmioOr32 (TIMER_CMD, 0x11);
|
||||
|
||||
Status = gInterrupt->EnableInterruptSource (gInterrupt, FixedPcdGet32 (PcdTimerVector));
|
||||
}
|
||||
|
||||
//
|
||||
// Save the new timer period
|
||||
//
|
||||
mTimerPeriod = TimerPeriod;
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function retrieves the period of timer interrupts in 100 ns units,
|
||||
returns that value in TimerPeriod, and returns EFI_SUCCESS. If TimerPeriod
|
||||
is NULL, then EFI_INVALID_PARAMETER is returned. If a TimerPeriod of 0 is
|
||||
returned, then the timer is currently disabled.
|
||||
|
||||
@param This The EFI_TIMER_ARCH_PROTOCOL instance.
|
||||
@param TimerPeriod A pointer to the timer period to retrieve in 100 ns units. If
|
||||
0 is returned, then the timer is currently disabled.
|
||||
|
||||
@retval EFI_SUCCESS The timer period was returned in TimerPeriod.
|
||||
@retval EFI_INVALID_PARAMETER TimerPeriod is NULL.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TimerDriverGetTimerPeriod (
|
||||
IN EFI_TIMER_ARCH_PROTOCOL *This,
|
||||
OUT UINT64 *TimerPeriod
|
||||
)
|
||||
{
|
||||
if (TimerPeriod == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
*TimerPeriod = mTimerPeriod;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
This function generates a soft timer interrupt. If the platform does not support soft
|
||||
timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCESS is returned.
|
||||
If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.RegisterHandler()
|
||||
service, then a soft timer interrupt will be generated. If the timer interrupt is
|
||||
enabled when this service is called, then the registered handler will be invoked. The
|
||||
registered handler should not be able to distinguish a hardware-generated timer
|
||||
interrupt from a software-generated timer interrupt.
|
||||
|
||||
@param This The EFI_TIMER_ARCH_PROTOCOL instance.
|
||||
|
||||
@retval EFI_SUCCESS The soft timer interrupt was generated.
|
||||
@retval EFI_UNSUPPORTED The platform does not support the generation of soft timer interrupts.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TimerDriverGenerateSoftInterrupt (
|
||||
IN EFI_TIMER_ARCH_PROTOCOL *This
|
||||
)
|
||||
{
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Interface stucture for the Timer Architectural Protocol.
|
||||
|
||||
@par Protocol Description:
|
||||
This protocol provides the services to initialize a periodic timer
|
||||
interrupt, and to register a handler that is called each time the timer
|
||||
interrupt fires. It may also provide a service to adjust the rate of the
|
||||
periodic timer interrupt. When a timer interrupt occurs, the handler is
|
||||
passed the amount of time that has passed since the previous timer
|
||||
interrupt.
|
||||
|
||||
@param RegisterHandler
|
||||
Registers a handler that will be called each time the
|
||||
timer interrupt fires. TimerPeriod defines the minimum
|
||||
time between timer interrupts, so TimerPeriod will also
|
||||
be the minimum time between calls to the registered
|
||||
handler.
|
||||
|
||||
@param SetTimerPeriod
|
||||
Sets the period of the timer interrupt in 100 nS units.
|
||||
This function is optional, and may return EFI_UNSUPPORTED.
|
||||
If this function is supported, then the timer period will
|
||||
be rounded up to the nearest supported timer period.
|
||||
|
||||
@param GetTimerPeriod
|
||||
Retrieves the period of the timer interrupt in 100 nS units.
|
||||
|
||||
@param GenerateSoftInterrupt
|
||||
Generates a soft timer interrupt that simulates the firing of
|
||||
the timer interrupt. This service can be used to invoke the
|
||||
registered handler if the timer interrupt has been masked for
|
||||
a period of time.
|
||||
|
||||
**/
|
||||
EFI_TIMER_ARCH_PROTOCOL gTimer = {
|
||||
TimerDriverRegisterHandler,
|
||||
TimerDriverSetTimerPeriod,
|
||||
TimerDriverGetTimerPeriod,
|
||||
TimerDriverGenerateSoftInterrupt
|
||||
};
|
||||
|
||||
EFI_HANDLE gTimerHandle = NULL;
|
||||
|
||||
|
||||
/**
|
||||
Initialize the state information for the Timer Architectural Protocol
|
||||
|
||||
@param ImageHandle of the loaded driver
|
||||
@param SystemTable Pointer to the System Table
|
||||
|
||||
@retval EFI_SUCCESS Protocol registered
|
||||
@retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure
|
||||
@retval EFI_DEVICE_ERROR Hardware problems
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TimerInitialize (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// Find the interrupt controller protocol. ASSERT if not found.
|
||||
//
|
||||
Status = gBS->LocateProtocol (&gHardwareInterruptProtocolGuid, NULL, ( VOID ** )&gInterrupt);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
MmioWrite32 (TIMER_CMD, 0x01);
|
||||
|
||||
//
|
||||
// Force the timer to be disabled
|
||||
//
|
||||
Status = TimerDriverSetTimerPeriod (&gTimer, 0);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// Install interrupt handler
|
||||
//
|
||||
Status = gInterrupt->RegisterInterruptSource (gInterrupt, FixedPcdGet32 (PcdTimerVector), TimerInterruptHandler);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// Force the timer to be enabled at its default period
|
||||
//
|
||||
Status = TimerDriverSetTimerPeriod (&gTimer, FixedPcdGet32 (PcdTimerPeriod));
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
|
||||
//
|
||||
// Install the Timer Architectural Protocol onto a new handle
|
||||
//
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&gTimerHandle,
|
||||
&gEfiTimerArchProtocolGuid, &gTimer,
|
||||
NULL
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user