ARM Packages: Fixed line endings

This large code change only modifies the line endings to be CRLF to be
compliant with the EDK2 coding convention document.



git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14088 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
oliviermartin
2013-01-25 11:28:06 +00:00
parent 5767f22fca
commit 1e57a46299
280 changed files with 48862 additions and 48862 deletions

View File

@@ -1,376 +1,376 @@
/** @file
Copyright (c) 2011, ARM Ltd. All rights reserved.<BR>
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/BaseMemoryLib.h>
#include <Library/DevicePathLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Guid/GlobalVariable.h>
#include "LcdGraphicsOutputDxe.h"
/**********************************************************************
*
* This file implements the Graphics Output protocol on ArmVersatileExpress
* using the Lcd controller
*
**********************************************************************/
//
// Global variables
//
BOOLEAN mDisplayInitialized = FALSE;
LCD_INSTANCE mLcdTemplate = {
LCD_INSTANCE_SIGNATURE,
NULL, // Handle
{ // ModeInfo
0, // Version
0, // HorizontalResolution
0, // VerticalResolution
PixelBltOnly, // PixelFormat
0, // PixelInformation
0, // PixelsPerScanLine
},
{
0, // MaxMode;
0, // Mode;
NULL, // Info;
0, // SizeOfInfo;
0, // FrameBufferBase;
0 // FrameBufferSize;
},
{ // Gop
LcdGraphicsQueryMode, // QueryMode
LcdGraphicsSetMode, // SetMode
LcdGraphicsBlt, // Blt
NULL // *Mode
},
{ // DevicePath
{
{
HARDWARE_DEVICE_PATH, HW_VENDOR_DP,
(UINT8) (sizeof(VENDOR_DEVICE_PATH)),
(UINT8) ((sizeof(VENDOR_DEVICE_PATH)) >> 8),
},
// Hardware Device Path for Lcd
EFI_CALLER_ID_GUID // Use the driver's GUID
},
{
END_DEVICE_PATH_TYPE,
END_ENTIRE_DEVICE_PATH_SUBTYPE,
sizeof(EFI_DEVICE_PATH_PROTOCOL),
0
}
},
(EFI_EVENT) NULL // ExitBootServicesEvent
};
EFI_STATUS
LcdInstanceContructor (
OUT LCD_INSTANCE** NewInstance
)
{
LCD_INSTANCE* Instance;
Instance = AllocateCopyPool (sizeof(LCD_INSTANCE), &mLcdTemplate);
if (Instance == NULL) {
return EFI_OUT_OF_RESOURCES;
}
Instance->Gop.Mode = &Instance->Mode;
Instance->Gop.Mode->MaxMode = LcdPlatformGetMaxMode ();
Instance->Mode.Info = &Instance->ModeInfo;
*NewInstance = Instance;
return EFI_SUCCESS;
}
//
// Function Definitions
//
EFI_STATUS
InitializeDisplay (
IN LCD_INSTANCE* Instance
)
{
EFI_STATUS Status = EFI_SUCCESS;
EFI_PHYSICAL_ADDRESS VramBaseAddress;
UINTN VramSize;
Status = LcdPlatformGetVram (&VramBaseAddress, &VramSize);
if (EFI_ERROR(Status)) {
return Status;
}
// Setup the LCD
Status = LcdInitialize (VramBaseAddress);
if (EFI_ERROR(Status)) {
goto EXIT_ERROR_LCD_SHUTDOWN;
}
Status = LcdPlatformInitializeDisplay (Instance->Handle);
if (EFI_ERROR(Status)) {
goto EXIT_ERROR_LCD_SHUTDOWN;
}
// Setup all the relevant mode information
Instance->Gop.Mode->SizeOfInfo = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
Instance->Gop.Mode->FrameBufferBase = VramBaseAddress;
Instance->Gop.Mode->FrameBufferSize = VramSize;
// Set the flag before changing the mode, to avoid infinite loops
mDisplayInitialized = TRUE;
// All is ok, so don't deal with any errors
goto EXIT;
EXIT_ERROR_LCD_SHUTDOWN:
DEBUG((DEBUG_ERROR, "InitializeDisplay: ERROR - Can not initialise the display. Exit Status=%r\n", Status));
LcdShutdown ();
EXIT:
return Status;
}
EFI_STATUS
EFIAPI
LcdGraphicsOutputDxeInitialize (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status = EFI_SUCCESS;
LCD_INSTANCE* Instance;
Status = LcdInstanceContructor (&Instance);
if (EFI_ERROR(Status)) {
goto EXIT;
}
// Install the Graphics Output Protocol and the Device Path
Status = gBS->InstallMultipleProtocolInterfaces(
&Instance->Handle,
&gEfiGraphicsOutputProtocolGuid, &Instance->Gop,
&gEfiDevicePathProtocolGuid, &Instance->DevicePath,
NULL
);
if (EFI_ERROR(Status)) {
DEBUG((DEBUG_ERROR, "GraphicsOutputDxeInitialize: Can not install the protocol. Exit Status=%r\n", Status));
goto EXIT;
}
// Register for an ExitBootServicesEvent
// When ExitBootServices starts, this function here will make sure that the graphics driver will shut down properly,
// i.e. it will free up all allocated memory and perform any necessary hardware re-configuration.
Status = gBS->CreateEvent (
EVT_SIGNAL_EXIT_BOOT_SERVICES,
TPL_NOTIFY,
LcdGraphicsExitBootServicesEvent, NULL,
&Instance->ExitBootServicesEvent
);
if (EFI_ERROR(Status)) {
DEBUG((DEBUG_ERROR, "GraphicsOutputDxeInitialize: Can not install the ExitBootServicesEvent handler. Exit Status=%r\n", Status));
goto EXIT_ERROR_UNINSTALL_PROTOCOL;
}
// To get here, everything must be fine, so just exit
goto EXIT;
EXIT_ERROR_UNINSTALL_PROTOCOL:
/* The following function could return an error message,
* however, to get here something must have gone wrong already,
* so preserve the original error, i.e. don't change
* the Status variable, even it fails to uninstall the protocol.
*/
gBS->UninstallMultipleProtocolInterfaces (
Instance->Handle,
&gEfiGraphicsOutputProtocolGuid, &Instance->Gop, // Uninstall Graphics Output protocol
&gEfiDevicePathProtocolGuid, &Instance->DevicePath, // Uninstall device path
NULL
);
EXIT:
return Status;
}
/***************************************
* This function should be called
* on Event: ExitBootServices
* to free up memory, stop the driver
* and uninstall the protocols
***************************************/
VOID
LcdGraphicsExitBootServicesEvent (
IN EFI_EVENT Event,
IN VOID *Context
)
{
//TODO: Implement me
}
/***************************************
* GraphicsOutput Protocol function, mapping to
* EFI_GRAPHICS_OUTPUT_PROTOCOL.QueryMode
***************************************/
EFI_STATUS
EFIAPI
LcdGraphicsQueryMode (
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
IN UINT32 ModeNumber,
OUT UINTN *SizeOfInfo,
OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info
)
{
EFI_STATUS Status = EFI_SUCCESS;
LCD_INSTANCE *Instance;
Instance = LCD_INSTANCE_FROM_GOP_THIS(This);
// Setup the hardware if not already done
if( !mDisplayInitialized ) {
Status = InitializeDisplay(Instance);
if (EFI_ERROR(Status)) {
goto EXIT;
}
}
// Error checking
if ( (This == NULL) || (Info == NULL) || (SizeOfInfo == NULL) || (ModeNumber >= This->Mode->MaxMode) ) {
DEBUG((DEBUG_ERROR, "LcdGraphicsQueryMode: ERROR - For mode number %d : Invalid Parameter.\n", ModeNumber ));
Status = EFI_INVALID_PARAMETER;
goto EXIT;
}
*Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));
if (*Info == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto EXIT;
}
*SizeOfInfo = sizeof( EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
Status = LcdPlatformQueryMode (ModeNumber,*Info);
if (EFI_ERROR(Status)) {
FreePool(*Info);
}
EXIT:
return Status;
}
/***************************************
* GraphicsOutput Protocol function, mapping to
* EFI_GRAPHICS_OUTPUT_PROTOCOL.SetMode
***************************************/
EFI_STATUS
EFIAPI
LcdGraphicsSetMode (
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
IN UINT32 ModeNumber
)
{
EFI_STATUS Status = EFI_SUCCESS;
EFI_GRAPHICS_OUTPUT_BLT_PIXEL FillColour;
LCD_INSTANCE* Instance;
Instance = LCD_INSTANCE_FROM_GOP_THIS (This);
// Setup the hardware if not already done
if(!mDisplayInitialized) {
Status = InitializeDisplay (Instance);
if (EFI_ERROR(Status)) {
goto EXIT;
}
}
// Check if this mode is supported
if( ModeNumber >= This->Mode->MaxMode ) {
DEBUG((DEBUG_ERROR, "LcdGraphicsSetMode: ERROR - Unsupported mode number %d .\n", ModeNumber ));
Status = EFI_UNSUPPORTED;
goto EXIT;
}
// Set the oscillator frequency to support the new mode
Status = LcdPlatformSetMode (ModeNumber);
if (EFI_ERROR(Status)) {
Status = EFI_DEVICE_ERROR;
goto EXIT;
}
// Update the UEFI mode information
This->Mode->Mode = ModeNumber;
LcdPlatformQueryMode (ModeNumber,&Instance->ModeInfo);
// Set the hardware to the new mode
Status = LcdSetMode (ModeNumber);
if (EFI_ERROR(Status)) {
Status = EFI_DEVICE_ERROR;
goto EXIT;
}
// The UEFI spec requires that we now clear the visible portions of the output display to black.
// Set the fill colour to black
SetMem (&FillColour, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);
// Fill the entire visible area with the same colour.
Status = This->Blt (
This,
&FillColour,
EfiBltVideoFill,
0,
0,
0,
0,
This->Mode->Info->HorizontalResolution,
This->Mode->Info->VerticalResolution,
0);
EXIT:
return Status;
}
UINTN
GetBytesPerPixel (
IN LCD_BPP Bpp
)
{
switch(Bpp) {
case LCD_BITS_PER_PIXEL_24:
return 4;
case LCD_BITS_PER_PIXEL_16_565:
case LCD_BITS_PER_PIXEL_16_555:
case LCD_BITS_PER_PIXEL_12_444:
return 2;
case LCD_BITS_PER_PIXEL_8:
case LCD_BITS_PER_PIXEL_4:
case LCD_BITS_PER_PIXEL_2:
case LCD_BITS_PER_PIXEL_1:
return 1;
default:
return 0;
}
}
/** @file
Copyright (c) 2011, ARM Ltd. All rights reserved.<BR>
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/BaseMemoryLib.h>
#include <Library/DevicePathLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Guid/GlobalVariable.h>
#include "LcdGraphicsOutputDxe.h"
/**********************************************************************
*
* This file implements the Graphics Output protocol on ArmVersatileExpress
* using the Lcd controller
*
**********************************************************************/
//
// Global variables
//
BOOLEAN mDisplayInitialized = FALSE;
LCD_INSTANCE mLcdTemplate = {
LCD_INSTANCE_SIGNATURE,
NULL, // Handle
{ // ModeInfo
0, // Version
0, // HorizontalResolution
0, // VerticalResolution
PixelBltOnly, // PixelFormat
0, // PixelInformation
0, // PixelsPerScanLine
},
{
0, // MaxMode;
0, // Mode;
NULL, // Info;
0, // SizeOfInfo;
0, // FrameBufferBase;
0 // FrameBufferSize;
},
{ // Gop
LcdGraphicsQueryMode, // QueryMode
LcdGraphicsSetMode, // SetMode
LcdGraphicsBlt, // Blt
NULL // *Mode
},
{ // DevicePath
{
{
HARDWARE_DEVICE_PATH, HW_VENDOR_DP,
(UINT8) (sizeof(VENDOR_DEVICE_PATH)),
(UINT8) ((sizeof(VENDOR_DEVICE_PATH)) >> 8),
},
// Hardware Device Path for Lcd
EFI_CALLER_ID_GUID // Use the driver's GUID
},
{
END_DEVICE_PATH_TYPE,
END_ENTIRE_DEVICE_PATH_SUBTYPE,
sizeof(EFI_DEVICE_PATH_PROTOCOL),
0
}
},
(EFI_EVENT) NULL // ExitBootServicesEvent
};
EFI_STATUS
LcdInstanceContructor (
OUT LCD_INSTANCE** NewInstance
)
{
LCD_INSTANCE* Instance;
Instance = AllocateCopyPool (sizeof(LCD_INSTANCE), &mLcdTemplate);
if (Instance == NULL) {
return EFI_OUT_OF_RESOURCES;
}
Instance->Gop.Mode = &Instance->Mode;
Instance->Gop.Mode->MaxMode = LcdPlatformGetMaxMode ();
Instance->Mode.Info = &Instance->ModeInfo;
*NewInstance = Instance;
return EFI_SUCCESS;
}
//
// Function Definitions
//
EFI_STATUS
InitializeDisplay (
IN LCD_INSTANCE* Instance
)
{
EFI_STATUS Status = EFI_SUCCESS;
EFI_PHYSICAL_ADDRESS VramBaseAddress;
UINTN VramSize;
Status = LcdPlatformGetVram (&VramBaseAddress, &VramSize);
if (EFI_ERROR(Status)) {
return Status;
}
// Setup the LCD
Status = LcdInitialize (VramBaseAddress);
if (EFI_ERROR(Status)) {
goto EXIT_ERROR_LCD_SHUTDOWN;
}
Status = LcdPlatformInitializeDisplay (Instance->Handle);
if (EFI_ERROR(Status)) {
goto EXIT_ERROR_LCD_SHUTDOWN;
}
// Setup all the relevant mode information
Instance->Gop.Mode->SizeOfInfo = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
Instance->Gop.Mode->FrameBufferBase = VramBaseAddress;
Instance->Gop.Mode->FrameBufferSize = VramSize;
// Set the flag before changing the mode, to avoid infinite loops
mDisplayInitialized = TRUE;
// All is ok, so don't deal with any errors
goto EXIT;
EXIT_ERROR_LCD_SHUTDOWN:
DEBUG((DEBUG_ERROR, "InitializeDisplay: ERROR - Can not initialise the display. Exit Status=%r\n", Status));
LcdShutdown ();
EXIT:
return Status;
}
EFI_STATUS
EFIAPI
LcdGraphicsOutputDxeInitialize (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status = EFI_SUCCESS;
LCD_INSTANCE* Instance;
Status = LcdInstanceContructor (&Instance);
if (EFI_ERROR(Status)) {
goto EXIT;
}
// Install the Graphics Output Protocol and the Device Path
Status = gBS->InstallMultipleProtocolInterfaces(
&Instance->Handle,
&gEfiGraphicsOutputProtocolGuid, &Instance->Gop,
&gEfiDevicePathProtocolGuid, &Instance->DevicePath,
NULL
);
if (EFI_ERROR(Status)) {
DEBUG((DEBUG_ERROR, "GraphicsOutputDxeInitialize: Can not install the protocol. Exit Status=%r\n", Status));
goto EXIT;
}
// Register for an ExitBootServicesEvent
// When ExitBootServices starts, this function here will make sure that the graphics driver will shut down properly,
// i.e. it will free up all allocated memory and perform any necessary hardware re-configuration.
Status = gBS->CreateEvent (
EVT_SIGNAL_EXIT_BOOT_SERVICES,
TPL_NOTIFY,
LcdGraphicsExitBootServicesEvent, NULL,
&Instance->ExitBootServicesEvent
);
if (EFI_ERROR(Status)) {
DEBUG((DEBUG_ERROR, "GraphicsOutputDxeInitialize: Can not install the ExitBootServicesEvent handler. Exit Status=%r\n", Status));
goto EXIT_ERROR_UNINSTALL_PROTOCOL;
}
// To get here, everything must be fine, so just exit
goto EXIT;
EXIT_ERROR_UNINSTALL_PROTOCOL:
/* The following function could return an error message,
* however, to get here something must have gone wrong already,
* so preserve the original error, i.e. don't change
* the Status variable, even it fails to uninstall the protocol.
*/
gBS->UninstallMultipleProtocolInterfaces (
Instance->Handle,
&gEfiGraphicsOutputProtocolGuid, &Instance->Gop, // Uninstall Graphics Output protocol
&gEfiDevicePathProtocolGuid, &Instance->DevicePath, // Uninstall device path
NULL
);
EXIT:
return Status;
}
/***************************************
* This function should be called
* on Event: ExitBootServices
* to free up memory, stop the driver
* and uninstall the protocols
***************************************/
VOID
LcdGraphicsExitBootServicesEvent (
IN EFI_EVENT Event,
IN VOID *Context
)
{
//TODO: Implement me
}
/***************************************
* GraphicsOutput Protocol function, mapping to
* EFI_GRAPHICS_OUTPUT_PROTOCOL.QueryMode
***************************************/
EFI_STATUS
EFIAPI
LcdGraphicsQueryMode (
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
IN UINT32 ModeNumber,
OUT UINTN *SizeOfInfo,
OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info
)
{
EFI_STATUS Status = EFI_SUCCESS;
LCD_INSTANCE *Instance;
Instance = LCD_INSTANCE_FROM_GOP_THIS(This);
// Setup the hardware if not already done
if( !mDisplayInitialized ) {
Status = InitializeDisplay(Instance);
if (EFI_ERROR(Status)) {
goto EXIT;
}
}
// Error checking
if ( (This == NULL) || (Info == NULL) || (SizeOfInfo == NULL) || (ModeNumber >= This->Mode->MaxMode) ) {
DEBUG((DEBUG_ERROR, "LcdGraphicsQueryMode: ERROR - For mode number %d : Invalid Parameter.\n", ModeNumber ));
Status = EFI_INVALID_PARAMETER;
goto EXIT;
}
*Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));
if (*Info == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto EXIT;
}
*SizeOfInfo = sizeof( EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
Status = LcdPlatformQueryMode (ModeNumber,*Info);
if (EFI_ERROR(Status)) {
FreePool(*Info);
}
EXIT:
return Status;
}
/***************************************
* GraphicsOutput Protocol function, mapping to
* EFI_GRAPHICS_OUTPUT_PROTOCOL.SetMode
***************************************/
EFI_STATUS
EFIAPI
LcdGraphicsSetMode (
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
IN UINT32 ModeNumber
)
{
EFI_STATUS Status = EFI_SUCCESS;
EFI_GRAPHICS_OUTPUT_BLT_PIXEL FillColour;
LCD_INSTANCE* Instance;
Instance = LCD_INSTANCE_FROM_GOP_THIS (This);
// Setup the hardware if not already done
if(!mDisplayInitialized) {
Status = InitializeDisplay (Instance);
if (EFI_ERROR(Status)) {
goto EXIT;
}
}
// Check if this mode is supported
if( ModeNumber >= This->Mode->MaxMode ) {
DEBUG((DEBUG_ERROR, "LcdGraphicsSetMode: ERROR - Unsupported mode number %d .\n", ModeNumber ));
Status = EFI_UNSUPPORTED;
goto EXIT;
}
// Set the oscillator frequency to support the new mode
Status = LcdPlatformSetMode (ModeNumber);
if (EFI_ERROR(Status)) {
Status = EFI_DEVICE_ERROR;
goto EXIT;
}
// Update the UEFI mode information
This->Mode->Mode = ModeNumber;
LcdPlatformQueryMode (ModeNumber,&Instance->ModeInfo);
// Set the hardware to the new mode
Status = LcdSetMode (ModeNumber);
if (EFI_ERROR(Status)) {
Status = EFI_DEVICE_ERROR;
goto EXIT;
}
// The UEFI spec requires that we now clear the visible portions of the output display to black.
// Set the fill colour to black
SetMem (&FillColour, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);
// Fill the entire visible area with the same colour.
Status = This->Blt (
This,
&FillColour,
EfiBltVideoFill,
0,
0,
0,
0,
This->Mode->Info->HorizontalResolution,
This->Mode->Info->VerticalResolution,
0);
EXIT:
return Status;
}
UINTN
GetBytesPerPixel (
IN LCD_BPP Bpp
)
{
switch(Bpp) {
case LCD_BITS_PER_PIXEL_24:
return 4;
case LCD_BITS_PER_PIXEL_16_565:
case LCD_BITS_PER_PIXEL_16_555:
case LCD_BITS_PER_PIXEL_12_444:
return 2;
case LCD_BITS_PER_PIXEL_8:
case LCD_BITS_PER_PIXEL_4:
case LCD_BITS_PER_PIXEL_2:
case LCD_BITS_PER_PIXEL_1:
return 1;
default:
return 0;
}
}

View File

@@ -1,56 +1,56 @@
#/** @file
#
# Component description file for PL111LcdGraphicsOutputDxe module
#
# Copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>
# 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 = PL111LcdGraphicsDxe
FILE_GUID = 407B4008-BF5B-11DF-9547-CF16E0D72085
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = LcdGraphicsOutputDxeInitialize
[Sources.common]
LcdGraphicsOutputDxe.c
LcdGraphicsOutputBlt.c
PL111Lcd.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
ArmPkg/ArmPkg.dec
ArmPlatformPkg/ArmVExpressPkg/ArmVExpressPkg.dec
ArmPlatformPkg/ArmPlatformPkg.dec
[LibraryClasses]
ArmLib
UefiLib
BaseLib
DebugLib
TimerLib
UefiDriverEntryPoint
UefiBootServicesTableLib
IoLib
BaseMemoryLib
LcdPlatformLib
[Protocols]
gEfiDevicePathProtocolGuid
gEfiGraphicsOutputProtocolGuid
[FixedPcd]
gArmPlatformTokenSpaceGuid.PcdPL111LcdBase
[Depex]
gEfiCpuArchProtocolGuid
#/** @file
#
# Component description file for PL111LcdGraphicsOutputDxe module
#
# Copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>
# 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 = PL111LcdGraphicsDxe
FILE_GUID = 407B4008-BF5B-11DF-9547-CF16E0D72085
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = LcdGraphicsOutputDxeInitialize
[Sources.common]
LcdGraphicsOutputDxe.c
LcdGraphicsOutputBlt.c
PL111Lcd.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
ArmPkg/ArmPkg.dec
ArmPlatformPkg/ArmVExpressPkg/ArmVExpressPkg.dec
ArmPlatformPkg/ArmPlatformPkg.dec
[LibraryClasses]
ArmLib
UefiLib
BaseLib
DebugLib
TimerLib
UefiDriverEntryPoint
UefiBootServicesTableLib
IoLib
BaseMemoryLib
LcdPlatformLib
[Protocols]
gEfiDevicePathProtocolGuid
gEfiGraphicsOutputProtocolGuid
[FixedPcd]
gArmPlatformTokenSpaceGuid.PcdPL111LcdBase
[Depex]
gEfiCpuArchProtocolGuid

View File

@@ -1,119 +1,119 @@
/** @file NorFlashBlockIoDxe.c
Copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>
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 <Library/BaseMemoryLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include "NorFlashDxe.h"
//
// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.Reset
//
EFI_STATUS
EFIAPI
NorFlashBlockIoReset (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
)
{
NOR_FLASH_INSTANCE *Instance;
Instance = INSTANCE_FROM_BLKIO_THIS(This);
DEBUG ((DEBUG_BLKIO, "NorFlashBlockIoReset(MediaId=0x%x)\n", This->Media->MediaId));
return NorFlashReset (Instance);
}
//
// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.ReadBlocks
//
EFI_STATUS
EFIAPI
NorFlashBlockIoReadBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN UINTN BufferSizeInBytes,
OUT VOID *Buffer
)
{
NOR_FLASH_INSTANCE *Instance;
EFI_STATUS Status;
Instance = INSTANCE_FROM_BLKIO_THIS(This);
DEBUG ((DEBUG_BLKIO, "NorFlashBlockIoReadBlocks(MediaId=0x%x, Lba=%ld, BufferSize=0x%x bytes (%d kB), BufferPtr @ 0x%08x)\n", MediaId, Lba, BufferSizeInBytes, Buffer));
if( !This->Media->MediaPresent ) {
Status = EFI_NO_MEDIA;
} else if( This->Media->MediaId != MediaId ) {
Status = EFI_MEDIA_CHANGED;
} else {
Status = NorFlashReadBlocks (Instance,Lba,BufferSizeInBytes,Buffer);
}
return Status;
}
//
// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.WriteBlocks
//
EFI_STATUS
EFIAPI
NorFlashBlockIoWriteBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN UINTN BufferSizeInBytes,
IN VOID *Buffer
)
{
NOR_FLASH_INSTANCE *Instance;
EFI_STATUS Status;
Instance = INSTANCE_FROM_BLKIO_THIS(This);
DEBUG ((DEBUG_BLKIO, "NorFlashBlockIoWriteBlocks(MediaId=0x%x, Lba=%ld, BufferSize=0x%x bytes (%d kB), BufferPtr @ 0x%08x)\n", MediaId, Lba, BufferSizeInBytes, Buffer));
if( !This->Media->MediaPresent ) {
Status = EFI_NO_MEDIA;
} else if( This->Media->MediaId != MediaId ) {
Status = EFI_MEDIA_CHANGED;
} else if( This->Media->ReadOnly ) {
Status = EFI_WRITE_PROTECTED;
} else {
Status = NorFlashWriteBlocks (Instance,Lba,BufferSizeInBytes,Buffer);
}
return Status;
}
//
// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.FlushBlocks
//
EFI_STATUS
EFIAPI
NorFlashBlockIoFlushBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This
)
{
// No Flush required for the NOR Flash driver
// because cache operations are not permitted.
DEBUG ((DEBUG_BLKIO, "NorFlashBlockIoFlushBlocks: Function NOT IMPLEMENTED (not required).\n"));
// Nothing to do so just return without error
return EFI_SUCCESS;
}
/** @file NorFlashBlockIoDxe.c
Copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>
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 <Library/BaseMemoryLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include "NorFlashDxe.h"
//
// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.Reset
//
EFI_STATUS
EFIAPI
NorFlashBlockIoReset (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
)
{
NOR_FLASH_INSTANCE *Instance;
Instance = INSTANCE_FROM_BLKIO_THIS(This);
DEBUG ((DEBUG_BLKIO, "NorFlashBlockIoReset(MediaId=0x%x)\n", This->Media->MediaId));
return NorFlashReset (Instance);
}
//
// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.ReadBlocks
//
EFI_STATUS
EFIAPI
NorFlashBlockIoReadBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN UINTN BufferSizeInBytes,
OUT VOID *Buffer
)
{
NOR_FLASH_INSTANCE *Instance;
EFI_STATUS Status;
Instance = INSTANCE_FROM_BLKIO_THIS(This);
DEBUG ((DEBUG_BLKIO, "NorFlashBlockIoReadBlocks(MediaId=0x%x, Lba=%ld, BufferSize=0x%x bytes (%d kB), BufferPtr @ 0x%08x)\n", MediaId, Lba, BufferSizeInBytes, Buffer));
if( !This->Media->MediaPresent ) {
Status = EFI_NO_MEDIA;
} else if( This->Media->MediaId != MediaId ) {
Status = EFI_MEDIA_CHANGED;
} else {
Status = NorFlashReadBlocks (Instance,Lba,BufferSizeInBytes,Buffer);
}
return Status;
}
//
// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.WriteBlocks
//
EFI_STATUS
EFIAPI
NorFlashBlockIoWriteBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN UINTN BufferSizeInBytes,
IN VOID *Buffer
)
{
NOR_FLASH_INSTANCE *Instance;
EFI_STATUS Status;
Instance = INSTANCE_FROM_BLKIO_THIS(This);
DEBUG ((DEBUG_BLKIO, "NorFlashBlockIoWriteBlocks(MediaId=0x%x, Lba=%ld, BufferSize=0x%x bytes (%d kB), BufferPtr @ 0x%08x)\n", MediaId, Lba, BufferSizeInBytes, Buffer));
if( !This->Media->MediaPresent ) {
Status = EFI_NO_MEDIA;
} else if( This->Media->MediaId != MediaId ) {
Status = EFI_MEDIA_CHANGED;
} else if( This->Media->ReadOnly ) {
Status = EFI_WRITE_PROTECTED;
} else {
Status = NorFlashWriteBlocks (Instance,Lba,BufferSizeInBytes,Buffer);
}
return Status;
}
//
// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.FlushBlocks
//
EFI_STATUS
EFIAPI
NorFlashBlockIoFlushBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This
)
{
// No Flush required for the NOR Flash driver
// because cache operations are not permitted.
DEBUG ((DEBUG_BLKIO, "NorFlashBlockIoFlushBlocks: Function NOT IMPLEMENTED (not required).\n"));
// Nothing to do so just return without error
return EFI_SUCCESS;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,316 +1,316 @@
/** @file NorFlashDxe.h
Copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>
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 __NOR_FLASH_DXE_H__
#define __NOR_FLASH_DXE_H__
#include <Base.h>
#include <PiDxe.h>
#include <Protocol/BlockIo.h>
#include <Protocol/FirmwareVolumeBlock.h>
#include <Library/DebugLib.h>
#include <Library/IoLib.h>
#include <Library/NorFlashPlatformLib.h>
#include <Library/UefiLib.h>
#define NOR_FLASH_ERASE_RETRY 10
// Device access macros
// These are necessary because we use 2 x 16bit parts to make up 32bit data
#define HIGH_16_BITS 0xFFFF0000
#define LOW_16_BITS 0x0000FFFF
#define LOW_8_BITS 0x000000FF
#define FOLD_32BIT_INTO_16BIT(value) ( ( value >> 16 ) | ( value & LOW_16_BITS ) )
#define GET_LOW_BYTE(value) ( value & LOW_8_BITS )
#define GET_HIGH_BYTE(value) ( GET_LOW_BYTE( value >> 16 ) )
// Each command must be sent simultaneously to both chips,
// i.e. at the lower 16 bits AND at the higher 16 bits
#define CREATE_NOR_ADDRESS(BaseAddr,OffsetAddr) ((BaseAddr) + ((OffsetAddr) << 2))
#define CREATE_DUAL_CMD(Cmd) ( ( Cmd << 16) | ( Cmd & LOW_16_BITS) )
#define SEND_NOR_COMMAND(BaseAddr,Offset,Cmd) MmioWrite32 (CREATE_NOR_ADDRESS(BaseAddr,Offset), CREATE_DUAL_CMD(Cmd))
#define GET_NOR_BLOCK_ADDRESS(BaseAddr,Lba,LbaSize)( BaseAddr + (UINTN)((Lba) * LbaSize) )
// Status Register Bits
#define P30_SR_BIT_WRITE (BIT7 << 16 | BIT7)
#define P30_SR_BIT_ERASE_SUSPEND (BIT6 << 16 | BIT6)
#define P30_SR_BIT_ERASE (BIT5 << 16 | BIT5)
#define P30_SR_BIT_PROGRAM (BIT4 << 16 | BIT4)
#define P30_SR_BIT_VPP (BIT3 << 16 | BIT3)
#define P30_SR_BIT_PROGRAM_SUSPEND (BIT2 << 16 | BIT2)
#define P30_SR_BIT_BLOCK_LOCKED (BIT1 << 16 | BIT1)
#define P30_SR_BIT_BEFP (BIT0 << 16 | BIT0)
// Device Commands for Intel StrataFlash(R) Embedded Memory (P30) Family
// On chip buffer size for buffered programming operations
// There are 2 chips, each chip can buffer up to 32 (16-bit)words, and each word is 2 bytes.
// Therefore the total size of the buffer is 2 x 32 x 2 = 128 bytes
#define P30_MAX_BUFFER_SIZE_IN_BYTES ((UINTN)128)
#define P30_MAX_BUFFER_SIZE_IN_WORDS (P30_MAX_BUFFER_SIZE_IN_BYTES/((UINTN)4))
#define MAX_BUFFERED_PROG_ITERATIONS 10000000
#define BOUNDARY_OF_32_WORDS 0x7F
// CFI Addresses
#define P30_CFI_ADDR_QUERY_UNIQUE_QRY 0x10
#define P30_CFI_ADDR_VENDOR_ID 0x13
// CFI Data
#define CFI_QRY 0x00595251
// READ Commands
#define P30_CMD_READ_DEVICE_ID 0x0090
#define P30_CMD_READ_STATUS_REGISTER 0x0070
#define P30_CMD_CLEAR_STATUS_REGISTER 0x0050
#define P30_CMD_READ_ARRAY 0x00FF
#define P30_CMD_READ_CFI_QUERY 0x0098
// WRITE Commands
#define P30_CMD_WORD_PROGRAM_SETUP 0x0040
#define P30_CMD_ALTERNATE_WORD_PROGRAM_SETUP 0x0010
#define P30_CMD_BUFFERED_PROGRAM_SETUP 0x00E8
#define P30_CMD_BUFFERED_PROGRAM_CONFIRM 0x00D0
#define P30_CMD_BEFP_SETUP 0x0080
#define P30_CMD_BEFP_CONFIRM 0x00D0
// ERASE Commands
#define P30_CMD_BLOCK_ERASE_SETUP 0x0020
#define P30_CMD_BLOCK_ERASE_CONFIRM 0x00D0
// SUSPEND Commands
#define P30_CMD_PROGRAM_OR_ERASE_SUSPEND 0x00B0
#define P30_CMD_SUSPEND_RESUME 0x00D0
// BLOCK LOCKING / UNLOCKING Commands
#define P30_CMD_LOCK_BLOCK_SETUP 0x0060
#define P30_CMD_LOCK_BLOCK 0x0001
#define P30_CMD_UNLOCK_BLOCK 0x00D0
#define P30_CMD_LOCK_DOWN_BLOCK 0x002F
// PROTECTION Commands
#define P30_CMD_PROGRAM_PROTECTION_REGISTER_SETUP 0x00C0
// CONFIGURATION Commands
#define P30_CMD_READ_CONFIGURATION_REGISTER_SETUP 0x0060
#define P30_CMD_READ_CONFIGURATION_REGISTER 0x0003
#define NOR_FLASH_SIGNATURE SIGNATURE_32('n', 'o', 'r', '0')
#define INSTANCE_FROM_FVB_THIS(a) CR(a, NOR_FLASH_INSTANCE, FvbProtocol, NOR_FLASH_SIGNATURE)
#define INSTANCE_FROM_BLKIO_THIS(a) CR(a, NOR_FLASH_INSTANCE, BlockIoProtocol, NOR_FLASH_SIGNATURE)
typedef struct _NOR_FLASH_INSTANCE NOR_FLASH_INSTANCE;
typedef EFI_STATUS (*NOR_FLASH_INITIALIZE) (NOR_FLASH_INSTANCE* Instance);
typedef struct {
VENDOR_DEVICE_PATH Vendor;
EFI_DEVICE_PATH_PROTOCOL End;
} NOR_FLASH_DEVICE_PATH;
struct _NOR_FLASH_INSTANCE {
UINT32 Signature;
EFI_HANDLE Handle;
BOOLEAN Initialized;
NOR_FLASH_INITIALIZE Initialize;
UINTN DeviceBaseAddress;
UINTN RegionBaseAddress;
UINTN Size;
EFI_LBA StartLba;
EFI_BLOCK_IO_PROTOCOL BlockIoProtocol;
EFI_BLOCK_IO_MEDIA Media;
BOOLEAN SupportFvb;
EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol;
NOR_FLASH_DEVICE_PATH DevicePath;
};
EFI_STATUS
NorFlashReadCfiData (
IN UINTN DeviceBaseAddress,
IN UINTN CFI_Offset,
IN UINT32 NumberOfBytes,
OUT UINT32 *Data
);
EFI_STATUS
NorFlashWriteBuffer (
IN NOR_FLASH_INSTANCE *Instance,
IN UINTN TargetAddress,
IN UINTN BufferSizeInBytes,
IN UINT32 *Buffer
);
//
// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.Reset
//
EFI_STATUS
EFIAPI
NorFlashBlockIoReset (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
);
//
// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.ReadBlocks
//
EFI_STATUS
EFIAPI
NorFlashBlockIoReadBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN UINTN BufferSizeInBytes,
OUT VOID *Buffer
);
//
// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.WriteBlocks
//
EFI_STATUS
EFIAPI
NorFlashBlockIoWriteBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN UINTN BufferSizeInBytes,
IN VOID *Buffer
);
//
// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.FlushBlocks
//
EFI_STATUS
EFIAPI
NorFlashBlockIoFlushBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This
);
//
// NorFlashFvbDxe.c
//
EFI_STATUS
EFIAPI
NorFlashFvbInitialize (
IN NOR_FLASH_INSTANCE* Instance
);
EFI_STATUS
EFIAPI
FvbGetAttributes(
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
OUT EFI_FVB_ATTRIBUTES_2 *Attributes
);
EFI_STATUS
EFIAPI
FvbSetAttributes(
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes
);
EFI_STATUS
EFIAPI
FvbGetPhysicalAddress(
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
OUT EFI_PHYSICAL_ADDRESS *Address
);
EFI_STATUS
EFIAPI
FvbGetBlockSize(
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
IN EFI_LBA Lba,
OUT UINTN *BlockSize,
OUT UINTN *NumberOfBlocks
);
EFI_STATUS
EFIAPI
FvbRead(
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
IN EFI_LBA Lba,
IN UINTN Offset,
IN OUT UINTN *NumBytes,
IN OUT UINT8 *Buffer
);
EFI_STATUS
EFIAPI
FvbWrite(
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
IN EFI_LBA Lba,
IN UINTN Offset,
IN OUT UINTN *NumBytes,
IN UINT8 *Buffer
);
EFI_STATUS
EFIAPI
FvbEraseBlocks(
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
...
);
//
// NorFlashDxe.c
//
EFI_STATUS
NorFlashUnlockAndEraseSingleBlock (
IN NOR_FLASH_INSTANCE *Instance,
IN UINTN BlockAddress
);
EFI_STATUS
NorFlashWriteSingleBlock (
IN NOR_FLASH_INSTANCE *Instance,
IN EFI_LBA Lba,
IN UINT32 *DataBuffer,
IN UINT32 BlockSizeInWords
);
EFI_STATUS
NorFlashWriteBlocks (
IN NOR_FLASH_INSTANCE *Instance,
IN EFI_LBA Lba,
IN UINTN BufferSizeInBytes,
IN VOID *Buffer
);
EFI_STATUS
NorFlashReadBlocks (
IN NOR_FLASH_INSTANCE *Instance,
IN EFI_LBA Lba,
IN UINTN BufferSizeInBytes,
OUT VOID *Buffer
);
EFI_STATUS
NorFlashReset (
IN NOR_FLASH_INSTANCE *Instance
);
#endif /* __NOR_FLASH_DXE_H__ */
/** @file NorFlashDxe.h
Copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>
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 __NOR_FLASH_DXE_H__
#define __NOR_FLASH_DXE_H__
#include <Base.h>
#include <PiDxe.h>
#include <Protocol/BlockIo.h>
#include <Protocol/FirmwareVolumeBlock.h>
#include <Library/DebugLib.h>
#include <Library/IoLib.h>
#include <Library/NorFlashPlatformLib.h>
#include <Library/UefiLib.h>
#define NOR_FLASH_ERASE_RETRY 10
// Device access macros
// These are necessary because we use 2 x 16bit parts to make up 32bit data
#define HIGH_16_BITS 0xFFFF0000
#define LOW_16_BITS 0x0000FFFF
#define LOW_8_BITS 0x000000FF
#define FOLD_32BIT_INTO_16BIT(value) ( ( value >> 16 ) | ( value & LOW_16_BITS ) )
#define GET_LOW_BYTE(value) ( value & LOW_8_BITS )
#define GET_HIGH_BYTE(value) ( GET_LOW_BYTE( value >> 16 ) )
// Each command must be sent simultaneously to both chips,
// i.e. at the lower 16 bits AND at the higher 16 bits
#define CREATE_NOR_ADDRESS(BaseAddr,OffsetAddr) ((BaseAddr) + ((OffsetAddr) << 2))
#define CREATE_DUAL_CMD(Cmd) ( ( Cmd << 16) | ( Cmd & LOW_16_BITS) )
#define SEND_NOR_COMMAND(BaseAddr,Offset,Cmd) MmioWrite32 (CREATE_NOR_ADDRESS(BaseAddr,Offset), CREATE_DUAL_CMD(Cmd))
#define GET_NOR_BLOCK_ADDRESS(BaseAddr,Lba,LbaSize)( BaseAddr + (UINTN)((Lba) * LbaSize) )
// Status Register Bits
#define P30_SR_BIT_WRITE (BIT7 << 16 | BIT7)
#define P30_SR_BIT_ERASE_SUSPEND (BIT6 << 16 | BIT6)
#define P30_SR_BIT_ERASE (BIT5 << 16 | BIT5)
#define P30_SR_BIT_PROGRAM (BIT4 << 16 | BIT4)
#define P30_SR_BIT_VPP (BIT3 << 16 | BIT3)
#define P30_SR_BIT_PROGRAM_SUSPEND (BIT2 << 16 | BIT2)
#define P30_SR_BIT_BLOCK_LOCKED (BIT1 << 16 | BIT1)
#define P30_SR_BIT_BEFP (BIT0 << 16 | BIT0)
// Device Commands for Intel StrataFlash(R) Embedded Memory (P30) Family
// On chip buffer size for buffered programming operations
// There are 2 chips, each chip can buffer up to 32 (16-bit)words, and each word is 2 bytes.
// Therefore the total size of the buffer is 2 x 32 x 2 = 128 bytes
#define P30_MAX_BUFFER_SIZE_IN_BYTES ((UINTN)128)
#define P30_MAX_BUFFER_SIZE_IN_WORDS (P30_MAX_BUFFER_SIZE_IN_BYTES/((UINTN)4))
#define MAX_BUFFERED_PROG_ITERATIONS 10000000
#define BOUNDARY_OF_32_WORDS 0x7F
// CFI Addresses
#define P30_CFI_ADDR_QUERY_UNIQUE_QRY 0x10
#define P30_CFI_ADDR_VENDOR_ID 0x13
// CFI Data
#define CFI_QRY 0x00595251
// READ Commands
#define P30_CMD_READ_DEVICE_ID 0x0090
#define P30_CMD_READ_STATUS_REGISTER 0x0070
#define P30_CMD_CLEAR_STATUS_REGISTER 0x0050
#define P30_CMD_READ_ARRAY 0x00FF
#define P30_CMD_READ_CFI_QUERY 0x0098
// WRITE Commands
#define P30_CMD_WORD_PROGRAM_SETUP 0x0040
#define P30_CMD_ALTERNATE_WORD_PROGRAM_SETUP 0x0010
#define P30_CMD_BUFFERED_PROGRAM_SETUP 0x00E8
#define P30_CMD_BUFFERED_PROGRAM_CONFIRM 0x00D0
#define P30_CMD_BEFP_SETUP 0x0080
#define P30_CMD_BEFP_CONFIRM 0x00D0
// ERASE Commands
#define P30_CMD_BLOCK_ERASE_SETUP 0x0020
#define P30_CMD_BLOCK_ERASE_CONFIRM 0x00D0
// SUSPEND Commands
#define P30_CMD_PROGRAM_OR_ERASE_SUSPEND 0x00B0
#define P30_CMD_SUSPEND_RESUME 0x00D0
// BLOCK LOCKING / UNLOCKING Commands
#define P30_CMD_LOCK_BLOCK_SETUP 0x0060
#define P30_CMD_LOCK_BLOCK 0x0001
#define P30_CMD_UNLOCK_BLOCK 0x00D0
#define P30_CMD_LOCK_DOWN_BLOCK 0x002F
// PROTECTION Commands
#define P30_CMD_PROGRAM_PROTECTION_REGISTER_SETUP 0x00C0
// CONFIGURATION Commands
#define P30_CMD_READ_CONFIGURATION_REGISTER_SETUP 0x0060
#define P30_CMD_READ_CONFIGURATION_REGISTER 0x0003
#define NOR_FLASH_SIGNATURE SIGNATURE_32('n', 'o', 'r', '0')
#define INSTANCE_FROM_FVB_THIS(a) CR(a, NOR_FLASH_INSTANCE, FvbProtocol, NOR_FLASH_SIGNATURE)
#define INSTANCE_FROM_BLKIO_THIS(a) CR(a, NOR_FLASH_INSTANCE, BlockIoProtocol, NOR_FLASH_SIGNATURE)
typedef struct _NOR_FLASH_INSTANCE NOR_FLASH_INSTANCE;
typedef EFI_STATUS (*NOR_FLASH_INITIALIZE) (NOR_FLASH_INSTANCE* Instance);
typedef struct {
VENDOR_DEVICE_PATH Vendor;
EFI_DEVICE_PATH_PROTOCOL End;
} NOR_FLASH_DEVICE_PATH;
struct _NOR_FLASH_INSTANCE {
UINT32 Signature;
EFI_HANDLE Handle;
BOOLEAN Initialized;
NOR_FLASH_INITIALIZE Initialize;
UINTN DeviceBaseAddress;
UINTN RegionBaseAddress;
UINTN Size;
EFI_LBA StartLba;
EFI_BLOCK_IO_PROTOCOL BlockIoProtocol;
EFI_BLOCK_IO_MEDIA Media;
BOOLEAN SupportFvb;
EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol;
NOR_FLASH_DEVICE_PATH DevicePath;
};
EFI_STATUS
NorFlashReadCfiData (
IN UINTN DeviceBaseAddress,
IN UINTN CFI_Offset,
IN UINT32 NumberOfBytes,
OUT UINT32 *Data
);
EFI_STATUS
NorFlashWriteBuffer (
IN NOR_FLASH_INSTANCE *Instance,
IN UINTN TargetAddress,
IN UINTN BufferSizeInBytes,
IN UINT32 *Buffer
);
//
// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.Reset
//
EFI_STATUS
EFIAPI
NorFlashBlockIoReset (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
);
//
// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.ReadBlocks
//
EFI_STATUS
EFIAPI
NorFlashBlockIoReadBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN UINTN BufferSizeInBytes,
OUT VOID *Buffer
);
//
// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.WriteBlocks
//
EFI_STATUS
EFIAPI
NorFlashBlockIoWriteBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN UINTN BufferSizeInBytes,
IN VOID *Buffer
);
//
// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.FlushBlocks
//
EFI_STATUS
EFIAPI
NorFlashBlockIoFlushBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This
);
//
// NorFlashFvbDxe.c
//
EFI_STATUS
EFIAPI
NorFlashFvbInitialize (
IN NOR_FLASH_INSTANCE* Instance
);
EFI_STATUS
EFIAPI
FvbGetAttributes(
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
OUT EFI_FVB_ATTRIBUTES_2 *Attributes
);
EFI_STATUS
EFIAPI
FvbSetAttributes(
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes
);
EFI_STATUS
EFIAPI
FvbGetPhysicalAddress(
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
OUT EFI_PHYSICAL_ADDRESS *Address
);
EFI_STATUS
EFIAPI
FvbGetBlockSize(
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
IN EFI_LBA Lba,
OUT UINTN *BlockSize,
OUT UINTN *NumberOfBlocks
);
EFI_STATUS
EFIAPI
FvbRead(
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
IN EFI_LBA Lba,
IN UINTN Offset,
IN OUT UINTN *NumBytes,
IN OUT UINT8 *Buffer
);
EFI_STATUS
EFIAPI
FvbWrite(
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
IN EFI_LBA Lba,
IN UINTN Offset,
IN OUT UINTN *NumBytes,
IN UINT8 *Buffer
);
EFI_STATUS
EFIAPI
FvbEraseBlocks(
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
...
);
//
// NorFlashDxe.c
//
EFI_STATUS
NorFlashUnlockAndEraseSingleBlock (
IN NOR_FLASH_INSTANCE *Instance,
IN UINTN BlockAddress
);
EFI_STATUS
NorFlashWriteSingleBlock (
IN NOR_FLASH_INSTANCE *Instance,
IN EFI_LBA Lba,
IN UINT32 *DataBuffer,
IN UINT32 BlockSizeInWords
);
EFI_STATUS
NorFlashWriteBlocks (
IN NOR_FLASH_INSTANCE *Instance,
IN EFI_LBA Lba,
IN UINTN BufferSizeInBytes,
IN VOID *Buffer
);
EFI_STATUS
NorFlashReadBlocks (
IN NOR_FLASH_INSTANCE *Instance,
IN EFI_LBA Lba,
IN UINTN BufferSizeInBytes,
OUT VOID *Buffer
);
EFI_STATUS
NorFlashReset (
IN NOR_FLASH_INSTANCE *Instance
);
#endif /* __NOR_FLASH_DXE_H__ */

View File

@@ -1,68 +1,68 @@
#/** @file
#
# Component description file for NorFlashDxe module
#
# Copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>
#
# 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 = ArmVeNorFlashDxe
FILE_GUID = 93E34C7E-B50E-11DF-9223-2443DFD72085
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = NorFlashInitialise
[Sources.common]
NorFlashDxe.c
NorFlashFvbDxe.c
NorFlashBlockIoDxe.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
ArmPlatformPkg/ArmPlatformPkg.dec
[LibraryClasses]
IoLib
BaseLib
DebugLib
HobLib
NorFlashPlatformLib
UefiLib
UefiDriverEntryPoint
UefiBootServicesTableLib
[Guids]
gEfiSystemNvDataFvGuid
gEfiVariableGuid
[Protocols]
gEfiBlockIoProtocolGuid
gEfiDevicePathProtocolGuid
gEfiFirmwareVolumeBlockProtocolGuid
[Pcd.common]
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
gArmPlatformTokenSpaceGuid.PcdNorFlashCheckBlockLocked
[Depex]
#
# NorFlashDxe must be loaded before VariableRuntimeDxe in case empty flash needs populating with default values
#
BEFORE gVariableRuntimeDxeFileGuid
#/** @file
#
# Component description file for NorFlashDxe module
#
# Copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>
#
# 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 = ArmVeNorFlashDxe
FILE_GUID = 93E34C7E-B50E-11DF-9223-2443DFD72085
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = NorFlashInitialise
[Sources.common]
NorFlashDxe.c
NorFlashFvbDxe.c
NorFlashBlockIoDxe.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
ArmPlatformPkg/ArmPlatformPkg.dec
[LibraryClasses]
IoLib
BaseLib
DebugLib
HobLib
NorFlashPlatformLib
UefiLib
UefiDriverEntryPoint
UefiBootServicesTableLib
[Guids]
gEfiSystemNvDataFvGuid
gEfiVariableGuid
[Protocols]
gEfiBlockIoProtocolGuid
gEfiDevicePathProtocolGuid
gEfiFirmwareVolumeBlockProtocolGuid
[Pcd.common]
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
gArmPlatformTokenSpaceGuid.PcdNorFlashCheckBlockLocked
[Depex]
#
# NorFlashDxe must be loaded before VariableRuntimeDxe in case empty flash needs populating with default values
#
BEFORE gVariableRuntimeDxeFileGuid

File diff suppressed because it is too large Load Diff

View File

@@ -1,344 +1,344 @@
/** @file
*
* Copyright (c) 2011, ARM Limited. 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/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/IoLib.h>
#include <Library/PcdLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Protocol/EmbeddedGpio.h>
#include <Drivers/PL061Gpio.h>
BOOLEAN mPL061Initialized = FALSE;
/**
Function implementations
**/
EFI_STATUS
PL061Identify (
VOID
)
{
// Check if this is a PrimeCell Peripheral
if ( (MmioRead8 (PL061_GPIO_PCELL_ID0) != 0x0D)
|| (MmioRead8 (PL061_GPIO_PCELL_ID1) != 0xF0)
|| (MmioRead8 (PL061_GPIO_PCELL_ID2) != 0x05)
|| (MmioRead8 (PL061_GPIO_PCELL_ID3) != 0xB1)) {
return EFI_NOT_FOUND;
}
// Check if this PrimeCell Peripheral is the PL061 GPIO
if ( (MmioRead8 (PL061_GPIO_PERIPH_ID0) != 0x61)
|| (MmioRead8 (PL061_GPIO_PERIPH_ID1) != 0x10)
|| ((MmioRead8 (PL061_GPIO_PERIPH_ID2) & 0xF) != 0x04)
|| (MmioRead8 (PL061_GPIO_PERIPH_ID3) != 0x00)) {
return EFI_NOT_FOUND;
}
return EFI_SUCCESS;
}
EFI_STATUS
PL061Initialize (
VOID
)
{
EFI_STATUS Status;
// Check if the PL061 GPIO module exists on board
Status = PL061Identify();
if (EFI_ERROR (Status)) {
Status = EFI_DEVICE_ERROR;
goto EXIT;
}
// Do other hardware initialisation things here as required
// Disable Interrupts
//if (MmioRead8 (PL061_GPIO_IE_REG) != 0) {
// // Ensure interrupts are disabled
//}
mPL061Initialized = TRUE;
EXIT:
return Status;
}
/**
Routine Description:
Gets the state of a GPIO pin
Arguments:
This - pointer to protocol
Gpio - which pin to read
Value - state of the pin
Returns:
EFI_SUCCESS - GPIO state returned in Value
EFI_INVALID_PARAMETER - Value is NULL pointer or Gpio pin is out of range
**/
EFI_STATUS
EFIAPI
Get (
IN EMBEDDED_GPIO *This,
IN EMBEDDED_GPIO_PIN Gpio,
OUT UINTN *Value
)
{
EFI_STATUS Status = EFI_SUCCESS;
if ( (Value == NULL)
|| (Gpio > LAST_GPIO_PIN))
{
return EFI_INVALID_PARAMETER;
}
// Initialize the hardware if not already done
if (!mPL061Initialized) {
Status = PL061Initialize();
if (EFI_ERROR(Status)) {
goto EXIT;
}
}
if (MmioRead8 (PL061_GPIO_DATA_REG) & GPIO_PIN_MASK_HIGH_8BIT(Gpio)) {
*Value = 1;
} else {
*Value = 0;
}
EXIT:
return Status;
}
/**
Routine Description:
Sets the state of a GPIO pin
Arguments:
This - pointer to protocol
Gpio - which pin to modify
Mode - mode to set
Returns:
EFI_SUCCESS - GPIO set as requested
EFI_UNSUPPORTED - Mode is not supported
EFI_INVALID_PARAMETER - Gpio pin is out of range
**/
EFI_STATUS
EFIAPI
Set (
IN EMBEDDED_GPIO *This,
IN EMBEDDED_GPIO_PIN Gpio,
IN EMBEDDED_GPIO_MODE Mode
)
{
EFI_STATUS Status = EFI_SUCCESS;
// Check for errors
if (Gpio > LAST_GPIO_PIN) {
Status = EFI_INVALID_PARAMETER;
goto EXIT;
}
// Initialize the hardware if not already done
if (!mPL061Initialized) {
Status = PL061Initialize();
if (EFI_ERROR(Status)) {
goto EXIT;
}
}
switch (Mode)
{
case GPIO_MODE_INPUT:
// Set the corresponding direction bit to LOW for input
MmioAnd8 (PL061_GPIO_DIR_REG, GPIO_PIN_MASK_LOW_8BIT(Gpio));
break;
case GPIO_MODE_OUTPUT_0:
// Set the corresponding data bit to LOW for 0
MmioAnd8 (PL061_GPIO_DATA_REG, GPIO_PIN_MASK_LOW_8BIT(Gpio));
// Set the corresponding direction bit to HIGH for output
MmioOr8 (PL061_GPIO_DIR_REG, GPIO_PIN_MASK_HIGH_8BIT(Gpio));
break;
case GPIO_MODE_OUTPUT_1:
// Set the corresponding data bit to HIGH for 1
MmioOr8 (PL061_GPIO_DATA_REG, GPIO_PIN_MASK_HIGH_8BIT(Gpio));
// Set the corresponding direction bit to HIGH for output
MmioOr8 (PL061_GPIO_DIR_REG, GPIO_PIN_MASK_HIGH_8BIT(Gpio));
break;
default:
// Other modes are not supported
return EFI_UNSUPPORTED;
}
EXIT:
return Status;
}
/**
Routine Description:
Gets the mode (function) of a GPIO pin
Arguments:
This - pointer to protocol
Gpio - which pin
Mode - pointer to output mode value
Returns:
EFI_SUCCESS - mode value retrieved
EFI_INVALID_PARAMETER - Mode is a null pointer or Gpio pin is out of range
**/
EFI_STATUS
EFIAPI
GetMode (
IN EMBEDDED_GPIO *This,
IN EMBEDDED_GPIO_PIN Gpio,
OUT EMBEDDED_GPIO_MODE *Mode
)
{
EFI_STATUS Status;
// Check for errors
if ( (Mode == NULL)
|| (Gpio > LAST_GPIO_PIN)) {
return EFI_INVALID_PARAMETER;
}
// Initialize the hardware if not already done
if (!mPL061Initialized) {
Status = PL061Initialize();
if (EFI_ERROR(Status)) {
return Status;
}
}
// Check if it is input or output
if (MmioRead8 (PL061_GPIO_DIR_REG) & GPIO_PIN_MASK_HIGH_8BIT(Gpio)) {
// Pin set to output
if (MmioRead8 (PL061_GPIO_DATA_REG) & GPIO_PIN_MASK_HIGH_8BIT(Gpio)) {
*Mode = GPIO_MODE_OUTPUT_1;
} else {
*Mode = GPIO_MODE_OUTPUT_0;
}
} else {
// Pin set to input
*Mode = GPIO_MODE_INPUT;
}
return EFI_SUCCESS;
}
/**
Routine Description:
Sets the pull-up / pull-down resistor of a GPIO pin
Arguments:
This - pointer to protocol
Gpio - which pin
Direction - pull-up, pull-down, or none
Returns:
EFI_UNSUPPORTED - Can not perform the requested operation
**/
EFI_STATUS
EFIAPI
SetPull (
IN EMBEDDED_GPIO *This,
IN EMBEDDED_GPIO_PIN Gpio,
IN EMBEDDED_GPIO_PULL Direction
)
{
return EFI_UNSUPPORTED;
}
/**
Protocol variable definition
**/
EMBEDDED_GPIO gGpio = {
Get,
Set,
GetMode,
SetPull
};
/**
Initialize the state information for the Embedded Gpio 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
PL061InstallProtocol (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
EFI_HANDLE Handle;
//
// Make sure the Gpio protocol has not been installed in the system yet.
//
ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEmbeddedGpioProtocolGuid);
// Install the Embedded GPIO Protocol onto a new handle
Handle = NULL;
Status = gBS->InstallMultipleProtocolInterfaces(
&Handle,
&gEmbeddedGpioProtocolGuid, &gGpio,
NULL
);
if (EFI_ERROR(Status)) {
Status = EFI_OUT_OF_RESOURCES;
}
return Status;
}
/** @file
*
* Copyright (c) 2011, ARM Limited. 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/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/IoLib.h>
#include <Library/PcdLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Protocol/EmbeddedGpio.h>
#include <Drivers/PL061Gpio.h>
BOOLEAN mPL061Initialized = FALSE;
/**
Function implementations
**/
EFI_STATUS
PL061Identify (
VOID
)
{
// Check if this is a PrimeCell Peripheral
if ( (MmioRead8 (PL061_GPIO_PCELL_ID0) != 0x0D)
|| (MmioRead8 (PL061_GPIO_PCELL_ID1) != 0xF0)
|| (MmioRead8 (PL061_GPIO_PCELL_ID2) != 0x05)
|| (MmioRead8 (PL061_GPIO_PCELL_ID3) != 0xB1)) {
return EFI_NOT_FOUND;
}
// Check if this PrimeCell Peripheral is the PL061 GPIO
if ( (MmioRead8 (PL061_GPIO_PERIPH_ID0) != 0x61)
|| (MmioRead8 (PL061_GPIO_PERIPH_ID1) != 0x10)
|| ((MmioRead8 (PL061_GPIO_PERIPH_ID2) & 0xF) != 0x04)
|| (MmioRead8 (PL061_GPIO_PERIPH_ID3) != 0x00)) {
return EFI_NOT_FOUND;
}
return EFI_SUCCESS;
}
EFI_STATUS
PL061Initialize (
VOID
)
{
EFI_STATUS Status;
// Check if the PL061 GPIO module exists on board
Status = PL061Identify();
if (EFI_ERROR (Status)) {
Status = EFI_DEVICE_ERROR;
goto EXIT;
}
// Do other hardware initialisation things here as required
// Disable Interrupts
//if (MmioRead8 (PL061_GPIO_IE_REG) != 0) {
// // Ensure interrupts are disabled
//}
mPL061Initialized = TRUE;
EXIT:
return Status;
}
/**
Routine Description:
Gets the state of a GPIO pin
Arguments:
This - pointer to protocol
Gpio - which pin to read
Value - state of the pin
Returns:
EFI_SUCCESS - GPIO state returned in Value
EFI_INVALID_PARAMETER - Value is NULL pointer or Gpio pin is out of range
**/
EFI_STATUS
EFIAPI
Get (
IN EMBEDDED_GPIO *This,
IN EMBEDDED_GPIO_PIN Gpio,
OUT UINTN *Value
)
{
EFI_STATUS Status = EFI_SUCCESS;
if ( (Value == NULL)
|| (Gpio > LAST_GPIO_PIN))
{
return EFI_INVALID_PARAMETER;
}
// Initialize the hardware if not already done
if (!mPL061Initialized) {
Status = PL061Initialize();
if (EFI_ERROR(Status)) {
goto EXIT;
}
}
if (MmioRead8 (PL061_GPIO_DATA_REG) & GPIO_PIN_MASK_HIGH_8BIT(Gpio)) {
*Value = 1;
} else {
*Value = 0;
}
EXIT:
return Status;
}
/**
Routine Description:
Sets the state of a GPIO pin
Arguments:
This - pointer to protocol
Gpio - which pin to modify
Mode - mode to set
Returns:
EFI_SUCCESS - GPIO set as requested
EFI_UNSUPPORTED - Mode is not supported
EFI_INVALID_PARAMETER - Gpio pin is out of range
**/
EFI_STATUS
EFIAPI
Set (
IN EMBEDDED_GPIO *This,
IN EMBEDDED_GPIO_PIN Gpio,
IN EMBEDDED_GPIO_MODE Mode
)
{
EFI_STATUS Status = EFI_SUCCESS;
// Check for errors
if (Gpio > LAST_GPIO_PIN) {
Status = EFI_INVALID_PARAMETER;
goto EXIT;
}
// Initialize the hardware if not already done
if (!mPL061Initialized) {
Status = PL061Initialize();
if (EFI_ERROR(Status)) {
goto EXIT;
}
}
switch (Mode)
{
case GPIO_MODE_INPUT:
// Set the corresponding direction bit to LOW for input
MmioAnd8 (PL061_GPIO_DIR_REG, GPIO_PIN_MASK_LOW_8BIT(Gpio));
break;
case GPIO_MODE_OUTPUT_0:
// Set the corresponding data bit to LOW for 0
MmioAnd8 (PL061_GPIO_DATA_REG, GPIO_PIN_MASK_LOW_8BIT(Gpio));
// Set the corresponding direction bit to HIGH for output
MmioOr8 (PL061_GPIO_DIR_REG, GPIO_PIN_MASK_HIGH_8BIT(Gpio));
break;
case GPIO_MODE_OUTPUT_1:
// Set the corresponding data bit to HIGH for 1
MmioOr8 (PL061_GPIO_DATA_REG, GPIO_PIN_MASK_HIGH_8BIT(Gpio));
// Set the corresponding direction bit to HIGH for output
MmioOr8 (PL061_GPIO_DIR_REG, GPIO_PIN_MASK_HIGH_8BIT(Gpio));
break;
default:
// Other modes are not supported
return EFI_UNSUPPORTED;
}
EXIT:
return Status;
}
/**
Routine Description:
Gets the mode (function) of a GPIO pin
Arguments:
This - pointer to protocol
Gpio - which pin
Mode - pointer to output mode value
Returns:
EFI_SUCCESS - mode value retrieved
EFI_INVALID_PARAMETER - Mode is a null pointer or Gpio pin is out of range
**/
EFI_STATUS
EFIAPI
GetMode (
IN EMBEDDED_GPIO *This,
IN EMBEDDED_GPIO_PIN Gpio,
OUT EMBEDDED_GPIO_MODE *Mode
)
{
EFI_STATUS Status;
// Check for errors
if ( (Mode == NULL)
|| (Gpio > LAST_GPIO_PIN)) {
return EFI_INVALID_PARAMETER;
}
// Initialize the hardware if not already done
if (!mPL061Initialized) {
Status = PL061Initialize();
if (EFI_ERROR(Status)) {
return Status;
}
}
// Check if it is input or output
if (MmioRead8 (PL061_GPIO_DIR_REG) & GPIO_PIN_MASK_HIGH_8BIT(Gpio)) {
// Pin set to output
if (MmioRead8 (PL061_GPIO_DATA_REG) & GPIO_PIN_MASK_HIGH_8BIT(Gpio)) {
*Mode = GPIO_MODE_OUTPUT_1;
} else {
*Mode = GPIO_MODE_OUTPUT_0;
}
} else {
// Pin set to input
*Mode = GPIO_MODE_INPUT;
}
return EFI_SUCCESS;
}
/**
Routine Description:
Sets the pull-up / pull-down resistor of a GPIO pin
Arguments:
This - pointer to protocol
Gpio - which pin
Direction - pull-up, pull-down, or none
Returns:
EFI_UNSUPPORTED - Can not perform the requested operation
**/
EFI_STATUS
EFIAPI
SetPull (
IN EMBEDDED_GPIO *This,
IN EMBEDDED_GPIO_PIN Gpio,
IN EMBEDDED_GPIO_PULL Direction
)
{
return EFI_UNSUPPORTED;
}
/**
Protocol variable definition
**/
EMBEDDED_GPIO gGpio = {
Get,
Set,
GetMode,
SetPull
};
/**
Initialize the state information for the Embedded Gpio 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
PL061InstallProtocol (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
EFI_HANDLE Handle;
//
// Make sure the Gpio protocol has not been installed in the system yet.
//
ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEmbeddedGpioProtocolGuid);
// Install the Embedded GPIO Protocol onto a new handle
Handle = NULL;
Status = gBS->InstallMultipleProtocolInterfaces(
&Handle,
&gEmbeddedGpioProtocolGuid, &gGpio,
NULL
);
if (EFI_ERROR(Status)) {
Status = EFI_OUT_OF_RESOURCES;
}
return Status;
}

View File

@@ -1,50 +1,50 @@
/** @file
*
* Copyright (c) 2011, ARM Limited. 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 = PL061GpioDxe
FILE_GUID = 5c1997d7-8d45-4f21-af3c-2206b8ed8bec
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = PL061InstallProtocol
[Sources.common]
PL061Gpio.c
[Packages]
MdePkg/MdePkg.dec
EmbeddedPkg/EmbeddedPkg.dec
ArmPkg/ArmPkg.dec
ArmPlatformPkg/ArmPlatformPkg.dec
[LibraryClasses]
BaseLib
BaseMemoryLib
DebugLib
IoLib
PcdLib
UefiBootServicesTableLib
UefiDriverEntryPoint
UefiLib
UefiRuntimeServicesTableLib
[Pcd]
gArmPlatformTokenSpaceGuid.PcdPL061GpioBase
[Protocols]
gEmbeddedGpioProtocolGuid
[Depex]
TRUE
/** @file
*
* Copyright (c) 2011, ARM Limited. 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 = PL061GpioDxe
FILE_GUID = 5c1997d7-8d45-4f21-af3c-2206b8ed8bec
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = PL061InstallProtocol
[Sources.common]
PL061Gpio.c
[Packages]
MdePkg/MdePkg.dec
EmbeddedPkg/EmbeddedPkg.dec
ArmPkg/ArmPkg.dec
ArmPlatformPkg/ArmPlatformPkg.dec
[LibraryClasses]
BaseLib
BaseMemoryLib
DebugLib
IoLib
PcdLib
UefiBootServicesTableLib
UefiDriverEntryPoint
UefiLib
UefiRuntimeServicesTableLib
[Pcd]
gArmPlatformTokenSpaceGuid.PcdPL061GpioBase
[Protocols]
gEmbeddedGpioProtocolGuid
[Depex]
TRUE

View File

@@ -1,395 +1,395 @@
/** @file
Template for Timer Architecture Protocol driver of the ARM flavor
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
Copyright (c) 2011 - 2012, ARM Ltd. All rights reserved.<BR>
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>
#include <Drivers/SP804Timer.h>
#define SP804_TIMER_PERIODIC_BASE ((UINTN)PcdGet32 (PcdSP804TimerPeriodicBase))
#define SP804_TIMER_METRONOME_BASE ((UINTN)PcdGet32 (PcdSP804TimerMetronomeBase))
#define SP804_TIMER_PERFORMANCE_BASE ((UINTN)PcdGet32 (PcdSP804TimerPerformanceBase))
// The notification function to call on every timer interrupt.
EFI_TIMER_NOTIFY mTimerNotifyFunction = (EFI_TIMER_NOTIFY)NULL;
EFI_EVENT EfiExitBootServicesEvent = (EFI_EVENT)NULL;
// The current period of the timer interrupt
UINT64 mTimerPeriod = 0;
// Cached copy of the Hardware Interrupt protocol instance
EFI_HARDWARE_INTERRUPT_PROTOCOL *gInterrupt = NULL;
// Cached interrupt vector
UINTN gVector;
/**
C Interrupt Handler called in 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);
// If the interrupt is shared then we must check if this interrupt source is the one associated to this Timer
if (MmioRead32 (SP804_TIMER_PERIODIC_BASE + SP804_TIMER_MSK_INT_STS_REG) != 0) {
// Clear the periodic interrupt
MmioWrite32 (SP804_TIMER_PERIODIC_BASE + SP804_TIMER_INT_CLR_REG, 0);
// Signal end of interrupt early to help avoid losing subsequent ticks from long duration handlers
gInterrupt->EndOfInterrupt (gInterrupt, Source);
if (mTimerNotifyFunction) {
mTimerNotifyFunction (mTimerPeriod);
}
}
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
)
{
if ((NotifyFunction == NULL) && (mTimerNotifyFunction == NULL)) {
return EFI_INVALID_PARAMETER;
}
if ((NotifyFunction != NULL) && (mTimerNotifyFunction != NULL)) {
return EFI_ALREADY_STARTED;
}
mTimerNotifyFunction = NotifyFunction;
return EFI_SUCCESS;
}
/**
Make sure all Dual Timers are disabled
**/
VOID
EFIAPI
ExitBootServicesEvent (
IN EFI_EVENT Event,
IN VOID *Context
)
{
// Disable 'Periodic Operation' timer if enabled
if (MmioRead32(SP804_TIMER_PERIODIC_BASE + SP804_TIMER_CONTROL_REG) & SP804_TIMER_CTRL_ENABLE) {
MmioAnd32 (SP804_TIMER_PERIODIC_BASE + SP804_TIMER_CONTROL_REG, 0);
}
// Disable 'Metronome/Delay' timer if enabled
if (MmioRead32(SP804_TIMER_METRONOME_BASE + SP804_TIMER_CONTROL_REG) & SP804_TIMER_CTRL_ENABLE) {
MmioAnd32 (SP804_TIMER_METRONOME_BASE + SP804_TIMER_CONTROL_REG, 0);
}
// Disable 'Performance' timer if enabled
if (MmioRead32(SP804_TIMER_PERFORMANCE_BASE + SP804_TIMER_CONTROL_REG) & SP804_TIMER_CTRL_ENABLE) {
MmioAnd32 (SP804_TIMER_PERFORMANCE_BASE + SP804_TIMER_CONTROL_REG, 0);
}
}
/**
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 TimerTicks;
// always disable the timer
MmioAnd32 (SP804_TIMER_PERIODIC_BASE + SP804_TIMER_CONTROL_REG, ~SP804_TIMER_CTRL_ENABLE);
if (TimerPeriod == 0) {
// Leave timer disabled from above, and...
// Disable timer 0/1 interrupt for a TimerPeriod of 0
Status = gInterrupt->DisableInterruptSource (gInterrupt, gVector);
} else {
// Convert TimerPeriod into 1MHz clock counts (us units = 100ns units * 10)
TimerTicks = DivU64x32 (TimerPeriod, 10);
TimerTicks = MultU64x32 (TimerTicks, PcdGet32(PcdSP804TimerFrequencyInMHz));
// if it's larger than 32-bits, pin to highest value
if (TimerTicks > 0xffffffff) {
TimerTicks = 0xffffffff;
}
// Program the SP804 timer with the new count value
MmioWrite32 (SP804_TIMER_PERIODIC_BASE + SP804_TIMER_LOAD_REG, TimerTicks);
// enable the timer
MmioOr32 (SP804_TIMER_PERIODIC_BASE + SP804_TIMER_CONTROL_REG, SP804_TIMER_CTRL_ENABLE);
// enable timer 0/1 interrupts
Status = gInterrupt->EnableInterruptSource (gInterrupt, gVector);
}
// 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 structure 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
};
/**
Initialize the state information for the Timer Architectural Protocol and
the Timer Debug support protocol that allows the debugger to break into a
running program.
@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_HANDLE Handle = NULL;
EFI_STATUS Status;
// Set the interrupt timer number
gVector = PcdGet32(PcdSP804TimerPeriodicInterruptNum);
// Find the interrupt controller protocol. ASSERT if not found.
Status = gBS->LocateProtocol (&gHardwareInterruptProtocolGuid, NULL, (VOID **)&gInterrupt);
ASSERT_EFI_ERROR (Status);
// Disable the timer
Status = TimerDriverSetTimerPeriod (&gTimer, 0);
ASSERT_EFI_ERROR (Status);
// Install interrupt handler
Status = gInterrupt->RegisterInterruptSource (gInterrupt, gVector, TimerInterruptHandler);
ASSERT_EFI_ERROR (Status);
// configure timer 0 for periodic operation, 32 bits, no prescaler, and interrupt enabled
MmioWrite32 (SP804_TIMER_PERIODIC_BASE + SP804_TIMER_CONTROL_REG, SP804_TIMER_CTRL_PERIODIC | SP804_TIMER_CTRL_32BIT | SP804_PRESCALE_DIV_1 | SP804_TIMER_CTRL_INT_ENABLE);
// Set up default timer
Status = TimerDriverSetTimerPeriod (&gTimer, FixedPcdGet32(PcdTimerPeriod)); // TIMER_DEFAULT_PERIOD
ASSERT_EFI_ERROR (Status);
// Install the Timer Architectural Protocol onto a new handle
Status = gBS->InstallMultipleProtocolInterfaces(
&Handle,
&gEfiTimerArchProtocolGuid, &gTimer,
NULL
);
ASSERT_EFI_ERROR(Status);
// Register for an ExitBootServicesEvent
Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &EfiExitBootServicesEvent);
ASSERT_EFI_ERROR (Status);
return Status;
}
/** @file
Template for Timer Architecture Protocol driver of the ARM flavor
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
Copyright (c) 2011 - 2012, ARM Ltd. All rights reserved.<BR>
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>
#include <Drivers/SP804Timer.h>
#define SP804_TIMER_PERIODIC_BASE ((UINTN)PcdGet32 (PcdSP804TimerPeriodicBase))
#define SP804_TIMER_METRONOME_BASE ((UINTN)PcdGet32 (PcdSP804TimerMetronomeBase))
#define SP804_TIMER_PERFORMANCE_BASE ((UINTN)PcdGet32 (PcdSP804TimerPerformanceBase))
// The notification function to call on every timer interrupt.
EFI_TIMER_NOTIFY mTimerNotifyFunction = (EFI_TIMER_NOTIFY)NULL;
EFI_EVENT EfiExitBootServicesEvent = (EFI_EVENT)NULL;
// The current period of the timer interrupt
UINT64 mTimerPeriod = 0;
// Cached copy of the Hardware Interrupt protocol instance
EFI_HARDWARE_INTERRUPT_PROTOCOL *gInterrupt = NULL;
// Cached interrupt vector
UINTN gVector;
/**
C Interrupt Handler called in 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);
// If the interrupt is shared then we must check if this interrupt source is the one associated to this Timer
if (MmioRead32 (SP804_TIMER_PERIODIC_BASE + SP804_TIMER_MSK_INT_STS_REG) != 0) {
// Clear the periodic interrupt
MmioWrite32 (SP804_TIMER_PERIODIC_BASE + SP804_TIMER_INT_CLR_REG, 0);
// Signal end of interrupt early to help avoid losing subsequent ticks from long duration handlers
gInterrupt->EndOfInterrupt (gInterrupt, Source);
if (mTimerNotifyFunction) {
mTimerNotifyFunction (mTimerPeriod);
}
}
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
)
{
if ((NotifyFunction == NULL) && (mTimerNotifyFunction == NULL)) {
return EFI_INVALID_PARAMETER;
}
if ((NotifyFunction != NULL) && (mTimerNotifyFunction != NULL)) {
return EFI_ALREADY_STARTED;
}
mTimerNotifyFunction = NotifyFunction;
return EFI_SUCCESS;
}
/**
Make sure all Dual Timers are disabled
**/
VOID
EFIAPI
ExitBootServicesEvent (
IN EFI_EVENT Event,
IN VOID *Context
)
{
// Disable 'Periodic Operation' timer if enabled
if (MmioRead32(SP804_TIMER_PERIODIC_BASE + SP804_TIMER_CONTROL_REG) & SP804_TIMER_CTRL_ENABLE) {
MmioAnd32 (SP804_TIMER_PERIODIC_BASE + SP804_TIMER_CONTROL_REG, 0);
}
// Disable 'Metronome/Delay' timer if enabled
if (MmioRead32(SP804_TIMER_METRONOME_BASE + SP804_TIMER_CONTROL_REG) & SP804_TIMER_CTRL_ENABLE) {
MmioAnd32 (SP804_TIMER_METRONOME_BASE + SP804_TIMER_CONTROL_REG, 0);
}
// Disable 'Performance' timer if enabled
if (MmioRead32(SP804_TIMER_PERFORMANCE_BASE + SP804_TIMER_CONTROL_REG) & SP804_TIMER_CTRL_ENABLE) {
MmioAnd32 (SP804_TIMER_PERFORMANCE_BASE + SP804_TIMER_CONTROL_REG, 0);
}
}
/**
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 TimerTicks;
// always disable the timer
MmioAnd32 (SP804_TIMER_PERIODIC_BASE + SP804_TIMER_CONTROL_REG, ~SP804_TIMER_CTRL_ENABLE);
if (TimerPeriod == 0) {
// Leave timer disabled from above, and...
// Disable timer 0/1 interrupt for a TimerPeriod of 0
Status = gInterrupt->DisableInterruptSource (gInterrupt, gVector);
} else {
// Convert TimerPeriod into 1MHz clock counts (us units = 100ns units * 10)
TimerTicks = DivU64x32 (TimerPeriod, 10);
TimerTicks = MultU64x32 (TimerTicks, PcdGet32(PcdSP804TimerFrequencyInMHz));
// if it's larger than 32-bits, pin to highest value
if (TimerTicks > 0xffffffff) {
TimerTicks = 0xffffffff;
}
// Program the SP804 timer with the new count value
MmioWrite32 (SP804_TIMER_PERIODIC_BASE + SP804_TIMER_LOAD_REG, TimerTicks);
// enable the timer
MmioOr32 (SP804_TIMER_PERIODIC_BASE + SP804_TIMER_CONTROL_REG, SP804_TIMER_CTRL_ENABLE);
// enable timer 0/1 interrupts
Status = gInterrupt->EnableInterruptSource (gInterrupt, gVector);
}
// 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 structure 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
};
/**
Initialize the state information for the Timer Architectural Protocol and
the Timer Debug support protocol that allows the debugger to break into a
running program.
@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_HANDLE Handle = NULL;
EFI_STATUS Status;
// Set the interrupt timer number
gVector = PcdGet32(PcdSP804TimerPeriodicInterruptNum);
// Find the interrupt controller protocol. ASSERT if not found.
Status = gBS->LocateProtocol (&gHardwareInterruptProtocolGuid, NULL, (VOID **)&gInterrupt);
ASSERT_EFI_ERROR (Status);
// Disable the timer
Status = TimerDriverSetTimerPeriod (&gTimer, 0);
ASSERT_EFI_ERROR (Status);
// Install interrupt handler
Status = gInterrupt->RegisterInterruptSource (gInterrupt, gVector, TimerInterruptHandler);
ASSERT_EFI_ERROR (Status);
// configure timer 0 for periodic operation, 32 bits, no prescaler, and interrupt enabled
MmioWrite32 (SP804_TIMER_PERIODIC_BASE + SP804_TIMER_CONTROL_REG, SP804_TIMER_CTRL_PERIODIC | SP804_TIMER_CTRL_32BIT | SP804_PRESCALE_DIV_1 | SP804_TIMER_CTRL_INT_ENABLE);
// Set up default timer
Status = TimerDriverSetTimerPeriod (&gTimer, FixedPcdGet32(PcdTimerPeriod)); // TIMER_DEFAULT_PERIOD
ASSERT_EFI_ERROR (Status);
// Install the Timer Architectural Protocol onto a new handle
Status = gBS->InstallMultipleProtocolInterfaces(
&Handle,
&gEfiTimerArchProtocolGuid, &gTimer,
NULL
);
ASSERT_EFI_ERROR(Status);
// Register for an ExitBootServicesEvent
Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &EfiExitBootServicesEvent);
ASSERT_EFI_ERROR (Status);
return Status;
}

View File

@@ -1,59 +1,59 @@
#/** @file
#
# Component description file for Timer module
#
# Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>
# 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 = ArmVeTimerDxe
FILE_GUID = a73d663d-a491-4278-9a69-9521be3379f2
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = TimerInitialize
[Sources.common]
SP804Timer.c
[Packages]
MdePkg/MdePkg.dec
EmbeddedPkg/EmbeddedPkg.dec
ArmPkg/ArmPkg.dec
ArmPlatformPkg/ArmPlatformPkg.dec
[LibraryClasses]
BaseLib
UefiRuntimeServicesTableLib
UefiLib
UefiBootServicesTableLib
BaseMemoryLib
DebugLib
UefiDriverEntryPoint
IoLib
[Guids]
[Protocols]
gEfiTimerArchProtocolGuid
gHardwareInterruptProtocolGuid
[Pcd.common]
gArmPlatformTokenSpaceGuid.PcdSP804TimerFrequencyInMHz
gArmPlatformTokenSpaceGuid.PcdSP804TimerPeriodicInterruptNum
gArmPlatformTokenSpaceGuid.PcdSP804TimerPeriodicBase
gArmPlatformTokenSpaceGuid.PcdSP804TimerPerformanceBase
gArmPlatformTokenSpaceGuid.PcdSP804TimerMetronomeBase
gEmbeddedTokenSpaceGuid.PcdTimerPeriod
[Depex]
gHardwareInterruptProtocolGuid
#/** @file
#
# Component description file for Timer module
#
# Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>
# 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 = ArmVeTimerDxe
FILE_GUID = a73d663d-a491-4278-9a69-9521be3379f2
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = TimerInitialize
[Sources.common]
SP804Timer.c
[Packages]
MdePkg/MdePkg.dec
EmbeddedPkg/EmbeddedPkg.dec
ArmPkg/ArmPkg.dec
ArmPlatformPkg/ArmPlatformPkg.dec
[LibraryClasses]
BaseLib
UefiRuntimeServicesTableLib
UefiLib
UefiBootServicesTableLib
BaseMemoryLib
DebugLib
UefiDriverEntryPoint
IoLib
[Guids]
[Protocols]
gEfiTimerArchProtocolGuid
gHardwareInterruptProtocolGuid
[Pcd.common]
gArmPlatformTokenSpaceGuid.PcdSP804TimerFrequencyInMHz
gArmPlatformTokenSpaceGuid.PcdSP804TimerPeriodicInterruptNum
gArmPlatformTokenSpaceGuid.PcdSP804TimerPeriodicBase
gArmPlatformTokenSpaceGuid.PcdSP804TimerPerformanceBase
gArmPlatformTokenSpaceGuid.PcdSP804TimerMetronomeBase
gEmbeddedTokenSpaceGuid.PcdTimerPeriod
[Depex]
gHardwareInterruptProtocolGuid

View File

@@ -1,387 +1,387 @@
/** @file
*
* Copyright (c) 2011-2012, ARM Limited. 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/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/IoLib.h>
#include <Library/PcdLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Protocol/WatchdogTimer.h>
#include <Drivers/SP805Watchdog.h>
EFI_EVENT EfiExitBootServicesEvent = (EFI_EVENT)NULL;
/**
Make sure the SP805 registers are unlocked for writing.
Note: The SP805 Watchdog Timer supports locking of its registers,
i.e. it inhibits all writes to avoid rogue software accidentally
corrupting their contents.
**/
inline
VOID
SP805Unlock (
VOID
)
{
if( MmioRead32(SP805_WDOG_LOCK_REG) == SP805_WDOG_LOCK_IS_LOCKED ) {
MmioWrite32(SP805_WDOG_LOCK_REG, SP805_WDOG_SPECIAL_UNLOCK_CODE);
}
}
/**
Make sure the SP805 registers are locked and can not be overwritten.
Note: The SP805 Watchdog Timer supports locking of its registers,
i.e. it inhibits all writes to avoid rogue software accidentally
corrupting their contents.
**/
inline
VOID
SP805Lock (
VOID
)
{
if( MmioRead32(SP805_WDOG_LOCK_REG) == SP805_WDOG_LOCK_IS_UNLOCKED ) {
// To lock it, just write in any number (except the special unlock code).
MmioWrite32(SP805_WDOG_LOCK_REG, SP805_WDOG_LOCK_IS_LOCKED);
}
}
/**
Stop the SP805 watchdog timer from counting down by disabling interrupts.
**/
inline
VOID
SP805Stop (
VOID
)
{
// Disable interrupts
if ( (MmioRead32(SP805_WDOG_CONTROL_REG) & SP805_WDOG_CTRL_INTEN) != 0 ) {
MmioAnd32(SP805_WDOG_CONTROL_REG, ~SP805_WDOG_CTRL_INTEN);
}
}
/**
Starts the SP805 counting down by enabling interrupts.
The count down will start from the value stored in the Load register,
not from the value where it was previously stopped.
**/
inline
VOID
SP805Start (
VOID
)
{
// Enable interrupts
if ( (MmioRead32(SP805_WDOG_CONTROL_REG) & SP805_WDOG_CTRL_INTEN) == 0 ) {
MmioOr32(SP805_WDOG_CONTROL_REG, SP805_WDOG_CTRL_INTEN);
}
}
/**
On exiting boot services we must make sure the SP805 Watchdog Timer
is stopped.
**/
VOID
EFIAPI
ExitBootServicesEvent (
IN EFI_EVENT Event,
IN VOID *Context
)
{
SP805Unlock();
SP805Stop();
SP805Lock();
}
/**
This function registers the handler NotifyFunction so it is called every time
the watchdog timer expires. It also passes the amount of time since the last
handler call to the NotifyFunction.
If NotifyFunction is not NULL and a handler is not already registered,
then the new handler is registered and EFI_SUCCESS is returned.
If NotifyFunction is NULL, and a handler is already registered,
then that handler is unregistered.
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.
@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 watchdog timer handler was registered.
@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.
**/
EFI_STATUS
EFIAPI
SP805RegisterHandler (
IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,
IN EFI_WATCHDOG_TIMER_NOTIFY NotifyFunction
)
{
// ERROR: This function is not supported.
// The hardware watchdog will reset the board
return EFI_INVALID_PARAMETER;
}
/**
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
SP805SetTimerPeriod (
IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,
IN UINT64 TimerPeriod // In 100ns units
)
{
EFI_STATUS Status = EFI_SUCCESS;
UINT64 Ticks64bit;
SP805Unlock();
if( TimerPeriod == 0 ) {
// This is a watchdog stop request
SP805Stop();
goto EXIT;
} else {
// Calculate the Watchdog ticks required for a delay of (TimerTicks * 100) nanoseconds
// The SP805 will count down to ZERO once, generate an interrupt and
// then it will again reload the initial value and start again.
// On the second time when it reaches ZERO, it will actually reset the board.
// Therefore, we need to load half the required delay.
//
// WatchdogTicks = ((TimerPeriod * 100 * SP805_CLOCK_FREQUENCY) / 1GHz) / 2 ;
//
// i.e.:
//
// WatchdogTicks = (TimerPeriod * SP805_CLOCK_FREQUENCY) / 20 MHz ;
Ticks64bit = DivU64x32(MultU64x32(TimerPeriod, (UINTN)PcdGet32(PcdSP805WatchdogClockFrequencyInHz)), 20000000);
// The registers in the SP805 are only 32 bits
if(Ticks64bit > (UINT64)0xFFFFFFFF) {
// We could load the watchdog with the maximum supported value but
// if a smaller value was requested, this could have the watchdog
// triggering before it was intended.
// Better generate an error to let the caller know.
Status = EFI_DEVICE_ERROR;
goto EXIT;
}
// Update the watchdog with a 32-bit value.
MmioWrite32(SP805_WDOG_LOAD_REG, (UINT32)Ticks64bit);
// Start the watchdog
SP805Start();
}
EXIT:
// Ensure the watchdog is locked before exiting.
SP805Lock();
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
SP805GetTimerPeriod (
IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,
OUT UINT64 *TimerPeriod
)
{
EFI_STATUS Status = EFI_SUCCESS;
UINT64 ReturnValue;
if (TimerPeriod == NULL) {
return EFI_INVALID_PARAMETER;
}
// Check if the watchdog is stopped
if ( (MmioRead32(SP805_WDOG_CONTROL_REG) & SP805_WDOG_CTRL_INTEN) == 0 ) {
// It is stopped, so return zero.
ReturnValue = 0;
} else {
// Convert the Watchdog ticks into TimerPeriod
// Ensure 64bit arithmetic throughout because the Watchdog ticks may already
// be at the maximum 32 bit value and we still need to multiply that by 600.
ReturnValue = MultU64x32( MmioRead32(SP805_WDOG_LOAD_REG), 600 );
}
*TimerPeriod = ReturnValue;
return Status;
}
/**
Interface structure for the Watchdog Architectural Protocol.
@par Protocol Description:
This protocol provides a service to set the amount of time to wait
before firing the watchdog timer, and it also provides a service to
register a handler that is invoked when the watchdog timer fires.
@par When the watchdog timer fires, control will be passed to a handler
if one has been registered. If no handler has been registered,
or the registered handler returns, then the system will be
reset by calling the Runtime Service ResetSystem().
@param RegisterHandler
Registers a handler that will be called each time the
watchdogtimer interrupt fires. TimerPeriod defines the minimum
time between timer interrupts, so TimerPeriod will also
be the minimum time between calls to the registered
handler.
NOTE: If the watchdog resets the system in hardware, then
this function will not have any chance of executing.
@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.
**/
EFI_WATCHDOG_TIMER_ARCH_PROTOCOL gWatchdogTimer = {
(EFI_WATCHDOG_TIMER_REGISTER_HANDLER) SP805RegisterHandler,
(EFI_WATCHDOG_TIMER_SET_TIMER_PERIOD) SP805SetTimerPeriod,
(EFI_WATCHDOG_TIMER_GET_TIMER_PERIOD) SP805GetTimerPeriod
};
/**
Initialize the state information for the Watchdog 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
SP805Initialize (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
EFI_HANDLE Handle;
// Unlock access to the SP805 registers
SP805Unlock ();
// Stop the watchdog from triggering unexpectedly
SP805Stop ();
// Set the watchdog to reset the board when triggered
if ((MmioRead32(SP805_WDOG_CONTROL_REG) & SP805_WDOG_CTRL_RESEN) == 0) {
MmioOr32 (SP805_WDOG_CONTROL_REG, SP805_WDOG_CTRL_RESEN);
}
// Prohibit any rogue access to SP805 registers
SP805Lock();
//
// Make sure the Watchdog Timer Architectural Protocol has not been installed in the system yet.
// This will avoid conflicts with the universal watchdog
//
ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiWatchdogTimerArchProtocolGuid);
// Register for an ExitBootServicesEvent
Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &EfiExitBootServicesEvent);
if (EFI_ERROR(Status)) {
Status = EFI_OUT_OF_RESOURCES;
goto EXIT;
}
// Install the Timer Architectural Protocol onto a new handle
Handle = NULL;
Status = gBS->InstallMultipleProtocolInterfaces(
&Handle,
&gEfiWatchdogTimerArchProtocolGuid, &gWatchdogTimer,
NULL
);
if (EFI_ERROR(Status)) {
Status = EFI_OUT_OF_RESOURCES;
goto EXIT;
}
EXIT:
if(EFI_ERROR(Status)) {
// The watchdog failed to initialize
ASSERT(FALSE);
}
return Status;
}
/** @file
*
* Copyright (c) 2011-2012, ARM Limited. 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/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/IoLib.h>
#include <Library/PcdLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Protocol/WatchdogTimer.h>
#include <Drivers/SP805Watchdog.h>
EFI_EVENT EfiExitBootServicesEvent = (EFI_EVENT)NULL;
/**
Make sure the SP805 registers are unlocked for writing.
Note: The SP805 Watchdog Timer supports locking of its registers,
i.e. it inhibits all writes to avoid rogue software accidentally
corrupting their contents.
**/
inline
VOID
SP805Unlock (
VOID
)
{
if( MmioRead32(SP805_WDOG_LOCK_REG) == SP805_WDOG_LOCK_IS_LOCKED ) {
MmioWrite32(SP805_WDOG_LOCK_REG, SP805_WDOG_SPECIAL_UNLOCK_CODE);
}
}
/**
Make sure the SP805 registers are locked and can not be overwritten.
Note: The SP805 Watchdog Timer supports locking of its registers,
i.e. it inhibits all writes to avoid rogue software accidentally
corrupting their contents.
**/
inline
VOID
SP805Lock (
VOID
)
{
if( MmioRead32(SP805_WDOG_LOCK_REG) == SP805_WDOG_LOCK_IS_UNLOCKED ) {
// To lock it, just write in any number (except the special unlock code).
MmioWrite32(SP805_WDOG_LOCK_REG, SP805_WDOG_LOCK_IS_LOCKED);
}
}
/**
Stop the SP805 watchdog timer from counting down by disabling interrupts.
**/
inline
VOID
SP805Stop (
VOID
)
{
// Disable interrupts
if ( (MmioRead32(SP805_WDOG_CONTROL_REG) & SP805_WDOG_CTRL_INTEN) != 0 ) {
MmioAnd32(SP805_WDOG_CONTROL_REG, ~SP805_WDOG_CTRL_INTEN);
}
}
/**
Starts the SP805 counting down by enabling interrupts.
The count down will start from the value stored in the Load register,
not from the value where it was previously stopped.
**/
inline
VOID
SP805Start (
VOID
)
{
// Enable interrupts
if ( (MmioRead32(SP805_WDOG_CONTROL_REG) & SP805_WDOG_CTRL_INTEN) == 0 ) {
MmioOr32(SP805_WDOG_CONTROL_REG, SP805_WDOG_CTRL_INTEN);
}
}
/**
On exiting boot services we must make sure the SP805 Watchdog Timer
is stopped.
**/
VOID
EFIAPI
ExitBootServicesEvent (
IN EFI_EVENT Event,
IN VOID *Context
)
{
SP805Unlock();
SP805Stop();
SP805Lock();
}
/**
This function registers the handler NotifyFunction so it is called every time
the watchdog timer expires. It also passes the amount of time since the last
handler call to the NotifyFunction.
If NotifyFunction is not NULL and a handler is not already registered,
then the new handler is registered and EFI_SUCCESS is returned.
If NotifyFunction is NULL, and a handler is already registered,
then that handler is unregistered.
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.
@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 watchdog timer handler was registered.
@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.
**/
EFI_STATUS
EFIAPI
SP805RegisterHandler (
IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,
IN EFI_WATCHDOG_TIMER_NOTIFY NotifyFunction
)
{
// ERROR: This function is not supported.
// The hardware watchdog will reset the board
return EFI_INVALID_PARAMETER;
}
/**
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
SP805SetTimerPeriod (
IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,
IN UINT64 TimerPeriod // In 100ns units
)
{
EFI_STATUS Status = EFI_SUCCESS;
UINT64 Ticks64bit;
SP805Unlock();
if( TimerPeriod == 0 ) {
// This is a watchdog stop request
SP805Stop();
goto EXIT;
} else {
// Calculate the Watchdog ticks required for a delay of (TimerTicks * 100) nanoseconds
// The SP805 will count down to ZERO once, generate an interrupt and
// then it will again reload the initial value and start again.
// On the second time when it reaches ZERO, it will actually reset the board.
// Therefore, we need to load half the required delay.
//
// WatchdogTicks = ((TimerPeriod * 100 * SP805_CLOCK_FREQUENCY) / 1GHz) / 2 ;
//
// i.e.:
//
// WatchdogTicks = (TimerPeriod * SP805_CLOCK_FREQUENCY) / 20 MHz ;
Ticks64bit = DivU64x32(MultU64x32(TimerPeriod, (UINTN)PcdGet32(PcdSP805WatchdogClockFrequencyInHz)), 20000000);
// The registers in the SP805 are only 32 bits
if(Ticks64bit > (UINT64)0xFFFFFFFF) {
// We could load the watchdog with the maximum supported value but
// if a smaller value was requested, this could have the watchdog
// triggering before it was intended.
// Better generate an error to let the caller know.
Status = EFI_DEVICE_ERROR;
goto EXIT;
}
// Update the watchdog with a 32-bit value.
MmioWrite32(SP805_WDOG_LOAD_REG, (UINT32)Ticks64bit);
// Start the watchdog
SP805Start();
}
EXIT:
// Ensure the watchdog is locked before exiting.
SP805Lock();
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
SP805GetTimerPeriod (
IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,
OUT UINT64 *TimerPeriod
)
{
EFI_STATUS Status = EFI_SUCCESS;
UINT64 ReturnValue;
if (TimerPeriod == NULL) {
return EFI_INVALID_PARAMETER;
}
// Check if the watchdog is stopped
if ( (MmioRead32(SP805_WDOG_CONTROL_REG) & SP805_WDOG_CTRL_INTEN) == 0 ) {
// It is stopped, so return zero.
ReturnValue = 0;
} else {
// Convert the Watchdog ticks into TimerPeriod
// Ensure 64bit arithmetic throughout because the Watchdog ticks may already
// be at the maximum 32 bit value and we still need to multiply that by 600.
ReturnValue = MultU64x32( MmioRead32(SP805_WDOG_LOAD_REG), 600 );
}
*TimerPeriod = ReturnValue;
return Status;
}
/**
Interface structure for the Watchdog Architectural Protocol.
@par Protocol Description:
This protocol provides a service to set the amount of time to wait
before firing the watchdog timer, and it also provides a service to
register a handler that is invoked when the watchdog timer fires.
@par When the watchdog timer fires, control will be passed to a handler
if one has been registered. If no handler has been registered,
or the registered handler returns, then the system will be
reset by calling the Runtime Service ResetSystem().
@param RegisterHandler
Registers a handler that will be called each time the
watchdogtimer interrupt fires. TimerPeriod defines the minimum
time between timer interrupts, so TimerPeriod will also
be the minimum time between calls to the registered
handler.
NOTE: If the watchdog resets the system in hardware, then
this function will not have any chance of executing.
@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.
**/
EFI_WATCHDOG_TIMER_ARCH_PROTOCOL gWatchdogTimer = {
(EFI_WATCHDOG_TIMER_REGISTER_HANDLER) SP805RegisterHandler,
(EFI_WATCHDOG_TIMER_SET_TIMER_PERIOD) SP805SetTimerPeriod,
(EFI_WATCHDOG_TIMER_GET_TIMER_PERIOD) SP805GetTimerPeriod
};
/**
Initialize the state information for the Watchdog 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
SP805Initialize (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
EFI_HANDLE Handle;
// Unlock access to the SP805 registers
SP805Unlock ();
// Stop the watchdog from triggering unexpectedly
SP805Stop ();
// Set the watchdog to reset the board when triggered
if ((MmioRead32(SP805_WDOG_CONTROL_REG) & SP805_WDOG_CTRL_RESEN) == 0) {
MmioOr32 (SP805_WDOG_CONTROL_REG, SP805_WDOG_CTRL_RESEN);
}
// Prohibit any rogue access to SP805 registers
SP805Lock();
//
// Make sure the Watchdog Timer Architectural Protocol has not been installed in the system yet.
// This will avoid conflicts with the universal watchdog
//
ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiWatchdogTimerArchProtocolGuid);
// Register for an ExitBootServicesEvent
Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &EfiExitBootServicesEvent);
if (EFI_ERROR(Status)) {
Status = EFI_OUT_OF_RESOURCES;
goto EXIT;
}
// Install the Timer Architectural Protocol onto a new handle
Handle = NULL;
Status = gBS->InstallMultipleProtocolInterfaces(
&Handle,
&gEfiWatchdogTimerArchProtocolGuid, &gWatchdogTimer,
NULL
);
if (EFI_ERROR(Status)) {
Status = EFI_OUT_OF_RESOURCES;
goto EXIT;
}
EXIT:
if(EFI_ERROR(Status)) {
// The watchdog failed to initialize
ASSERT(FALSE);
}
return Status;
}

View File

@@ -1,52 +1,52 @@
/** @file
*
* Copyright (c) 2011-2012, ARM Limited. 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 = SP805WatchdogDxe
FILE_GUID = ebd705fb-fa92-46a7-b32b-7f566d944614
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = SP805Initialize
[Sources.common]
SP805Watchdog.c
[Packages]
MdePkg/MdePkg.dec
EmbeddedPkg/EmbeddedPkg.dec
ArmPkg/ArmPkg.dec
ArmPlatformPkg/ArmPlatformPkg.dec
[LibraryClasses]
BaseLib
BaseMemoryLib
DebugLib
IoLib
PcdLib
UefiLib
UefiBootServicesTableLib
UefiDriverEntryPoint
UefiRuntimeServicesTableLib
[Pcd]
gArmPlatformTokenSpaceGuid.PcdSP805WatchdogBase
gArmPlatformTokenSpaceGuid.PcdSP805WatchdogClockFrequencyInHz
[Protocols]
gEfiWatchdogTimerArchProtocolGuid
[Depex]
TRUE
/** @file
*
* Copyright (c) 2011-2012, ARM Limited. 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 = SP805WatchdogDxe
FILE_GUID = ebd705fb-fa92-46a7-b32b-7f566d944614
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = SP805Initialize
[Sources.common]
SP805Watchdog.c
[Packages]
MdePkg/MdePkg.dec
EmbeddedPkg/EmbeddedPkg.dec
ArmPkg/ArmPkg.dec
ArmPlatformPkg/ArmPlatformPkg.dec
[LibraryClasses]
BaseLib
BaseMemoryLib
DebugLib
IoLib
PcdLib
UefiLib
UefiBootServicesTableLib
UefiDriverEntryPoint
UefiRuntimeServicesTableLib
[Pcd]
gArmPlatformTokenSpaceGuid.PcdSP805WatchdogBase
gArmPlatformTokenSpaceGuid.PcdSP805WatchdogClockFrequencyInHz
[Protocols]
gEfiWatchdogTimerArchProtocolGuid
[Depex]
TRUE