mirror of https://github.com/acidanthera/audk.git
OvmfPkg: Add QemuFlashFvbServicesRuntimeDxe driver
If QEMU flash is detected, this module will install FirmwareVolumeBlock support for the QEMU flash device. It will also set PCDs with the results that: 1. OvmfPkg/EmuVariableFvbRuntimeDxe will be disabled 2. MdeModulePkg variable services will read/write flash directly Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jordan Justen <jordan.l.justen@intel.com> Acked-by: Laszlo Ersek <lersek@redhat.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14839 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
4313b26de0
commit
a4ce9ffd47
|
@ -0,0 +1,137 @@
|
|||
/**@file
|
||||
|
||||
Copyright (c) 2006, Intel Corporation. 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.
|
||||
|
||||
Module Name:
|
||||
|
||||
FvbInfo.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Defines data structure that is the volume header found.These data is intent
|
||||
to decouple FVB driver with FV header.
|
||||
|
||||
**/
|
||||
|
||||
//
|
||||
// The package level header files this module uses
|
||||
//
|
||||
#include <PiDxe.h>
|
||||
//
|
||||
// The protocols, PPI and GUID defintions for this module
|
||||
//
|
||||
#include <Guid/EventGroup.h>
|
||||
#include <Guid/FirmwareFileSystem2.h>
|
||||
#include <Guid/SystemNvDataGuid.h>
|
||||
#include <Protocol/FirmwareVolumeBlock.h>
|
||||
#include <Protocol/DevicePath.h>
|
||||
//
|
||||
// The Library classes this module consumes
|
||||
//
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/UefiDriverEntryPoint.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DxeServicesTableLib.h>
|
||||
#include <Library/UefiRuntimeLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/HobLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
|
||||
typedef struct {
|
||||
UINT64 FvLength;
|
||||
EFI_FIRMWARE_VOLUME_HEADER FvbInfo;
|
||||
//
|
||||
// EFI_FV_BLOCK_MAP_ENTRY ExtraBlockMap[n];//n=0
|
||||
//
|
||||
EFI_FV_BLOCK_MAP_ENTRY End[1];
|
||||
} EFI_FVB_MEDIA_INFO;
|
||||
|
||||
EFI_FVB_MEDIA_INFO mPlatformFvbMediaInfo[] = {
|
||||
//
|
||||
// Systen NvStorage FVB
|
||||
//
|
||||
{
|
||||
FixedPcdGet32 (PcdFlashNvStorageVariableSize) +
|
||||
FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) +
|
||||
FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize) +
|
||||
FixedPcdGet32 (PcdOvmfFlashNvStorageEventLogSize),
|
||||
{
|
||||
{
|
||||
0,
|
||||
}, // ZeroVector[16]
|
||||
EFI_SYSTEM_NV_DATA_FV_GUID,
|
||||
FixedPcdGet32 (PcdFlashNvStorageVariableSize) +
|
||||
FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) +
|
||||
FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize) +
|
||||
FixedPcdGet32 (PcdOvmfFlashNvStorageEventLogSize),
|
||||
EFI_FVH_SIGNATURE,
|
||||
EFI_FVB2_MEMORY_MAPPED |
|
||||
EFI_FVB2_READ_ENABLED_CAP |
|
||||
EFI_FVB2_READ_STATUS |
|
||||
EFI_FVB2_WRITE_ENABLED_CAP |
|
||||
EFI_FVB2_WRITE_STATUS |
|
||||
EFI_FVB2_ERASE_POLARITY |
|
||||
EFI_FVB2_ALIGNMENT_16,
|
||||
sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY),
|
||||
0, // CheckSum
|
||||
0, // ExtHeaderOffset
|
||||
{
|
||||
0,
|
||||
}, // Reserved[1]
|
||||
2, // Revision
|
||||
{
|
||||
(FixedPcdGet32 (PcdFlashNvStorageVariableSize) +
|
||||
FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) +
|
||||
FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize) +
|
||||
FixedPcdGet32 (PcdOvmfFlashNvStorageEventLogSize)) / FixedPcdGet32 (PcdOvmfFirmwareBlockSize),
|
||||
FixedPcdGet32 (PcdOvmfFirmwareBlockSize),
|
||||
}
|
||||
},
|
||||
{
|
||||
0,
|
||||
0
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
EFI_STATUS
|
||||
GetFvbInfo (
|
||||
IN UINT64 FvLength,
|
||||
OUT EFI_FIRMWARE_VOLUME_HEADER **FvbInfo
|
||||
)
|
||||
{
|
||||
STATIC BOOLEAN Checksummed = FALSE;
|
||||
UINTN Index;
|
||||
|
||||
if (!Checksummed) {
|
||||
for (Index = 0; Index < sizeof (mPlatformFvbMediaInfo) / sizeof (EFI_FVB_MEDIA_INFO); Index += 1) {
|
||||
UINT16 Checksum;
|
||||
mPlatformFvbMediaInfo[Index].FvbInfo.Checksum = 0;
|
||||
Checksum = CalculateCheckSum16 (
|
||||
(UINT16*) &mPlatformFvbMediaInfo[Index].FvbInfo,
|
||||
mPlatformFvbMediaInfo[Index].FvbInfo.HeaderLength
|
||||
);
|
||||
mPlatformFvbMediaInfo[Index].FvbInfo.Checksum = Checksum;
|
||||
}
|
||||
Checksummed = TRUE;
|
||||
}
|
||||
|
||||
for (Index = 0; Index < sizeof (mPlatformFvbMediaInfo) / sizeof (EFI_FVB_MEDIA_INFO); Index += 1) {
|
||||
if (mPlatformFvbMediaInfo[Index].FvLength == FvLength) {
|
||||
*FvbInfo = &mPlatformFvbMediaInfo[Index].FvbInfo;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
## @file
|
||||
# Component description file for QEMU Flash Fimware Volume Block DXE driver module.
|
||||
#
|
||||
# This DXE runtime driver implements and produces the Fimware Volue Block Protocol
|
||||
# for a QEMU flash device.
|
||||
#
|
||||
# Copyright (c) 2006 - 2013, Intel Corporation. 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 = FvbServicesRuntimeDxe
|
||||
FILE_GUID = 733cbac2-b23f-4b92-bc8e-fb01ce5907b7
|
||||
MODULE_TYPE = DXE_RUNTIME_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
ENTRY_POINT = FvbInitialize
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32
|
||||
#
|
||||
|
||||
[Sources]
|
||||
FvbInfo.c
|
||||
FwBlockService.c
|
||||
QemuFlash.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
OvmfPkg/OvmfPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
UefiBootServicesTableLib
|
||||
MemoryAllocationLib
|
||||
BaseMemoryLib
|
||||
HobLib
|
||||
DebugLib
|
||||
UefiRuntimeLib
|
||||
DxeServicesTableLib
|
||||
BaseLib
|
||||
UefiDriverEntryPoint
|
||||
UefiLib
|
||||
PcdLib
|
||||
|
||||
[Guids]
|
||||
gEfiEventVirtualAddressChangeGuid # ALWAYS_CONSUMED Create Event: EVENT_GROUP_GUID
|
||||
|
||||
[Protocols]
|
||||
gEfiFirmwareVolumeBlockProtocolGuid # PROTOCOL SOMETIMES_PRODUCED
|
||||
gEfiDevicePathProtocolGuid # PROTOCOL SOMETIMES_PRODUCED
|
||||
|
||||
[FixedPcd]
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
|
||||
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageVariableBase
|
||||
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageFtwWorkingBase
|
||||
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageFtwSpareBase
|
||||
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogSize
|
||||
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress
|
||||
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize
|
||||
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareBlockSize
|
||||
|
||||
[Pcd]
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
|
||||
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogBase
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64
|
||||
|
||||
|
||||
[Depex]
|
||||
TRUE
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,184 @@
|
|||
/**@file
|
||||
|
||||
Copyright (c) 2006, Intel Corporation. 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.
|
||||
|
||||
Module Name:
|
||||
|
||||
FwBlockService.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Firmware volume block driver for Intel Firmware Hub (FWH) device
|
||||
|
||||
**/
|
||||
|
||||
#ifndef _FW_BLOCK_SERVICE_H
|
||||
#define _FW_BLOCK_SERVICE_H
|
||||
|
||||
//
|
||||
// BugBug: Add documentation here for data structure!!!!
|
||||
//
|
||||
#define FVB_PHYSICAL 0
|
||||
#define FVB_VIRTUAL 1
|
||||
|
||||
typedef struct {
|
||||
EFI_LOCK FvbDevLock;
|
||||
UINTN FvBase[2];
|
||||
UINTN NumOfBlocks;
|
||||
EFI_FIRMWARE_VOLUME_HEADER VolumeHeader;
|
||||
} EFI_FW_VOL_INSTANCE;
|
||||
|
||||
typedef struct {
|
||||
UINT32 NumFv;
|
||||
EFI_FW_VOL_INSTANCE *FvInstance[2];
|
||||
UINT8 *FvbScratchSpace[2];
|
||||
} ESAL_FWB_GLOBAL;
|
||||
|
||||
//
|
||||
// Fvb Protocol instance data
|
||||
//
|
||||
#define FVB_DEVICE_FROM_THIS(a) CR (a, EFI_FW_VOL_BLOCK_DEVICE, FwVolBlockInstance, FVB_DEVICE_SIGNATURE)
|
||||
#define FVB_EXTEND_DEVICE_FROM_THIS(a) CR (a, EFI_FW_VOL_BLOCK_DEVICE, FvbExtension, FVB_DEVICE_SIGNATURE)
|
||||
#define FVB_DEVICE_SIGNATURE SIGNATURE_32 ('F', 'V', 'B', 'N')
|
||||
|
||||
typedef struct {
|
||||
MEDIA_FW_VOL_DEVICE_PATH FvDevPath;
|
||||
EFI_DEVICE_PATH_PROTOCOL EndDevPath;
|
||||
} FV_PIWG_DEVICE_PATH;
|
||||
|
||||
typedef struct {
|
||||
MEMMAP_DEVICE_PATH MemMapDevPath;
|
||||
EFI_DEVICE_PATH_PROTOCOL EndDevPath;
|
||||
} FV_MEMMAP_DEVICE_PATH;
|
||||
|
||||
typedef struct {
|
||||
UINTN Signature;
|
||||
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
||||
UINTN Instance;
|
||||
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL FwVolBlockInstance;
|
||||
} EFI_FW_VOL_BLOCK_DEVICE;
|
||||
|
||||
EFI_STATUS
|
||||
GetFvbInfo (
|
||||
IN UINT64 FvLength,
|
||||
OUT EFI_FIRMWARE_VOLUME_HEADER **FvbInfo
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
FvbSetVolumeAttributes (
|
||||
IN UINTN Instance,
|
||||
IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes,
|
||||
IN ESAL_FWB_GLOBAL *Global,
|
||||
IN BOOLEAN Virtual
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
FvbGetVolumeAttributes (
|
||||
IN UINTN Instance,
|
||||
OUT EFI_FVB_ATTRIBUTES_2 *Attributes,
|
||||
IN ESAL_FWB_GLOBAL *Global,
|
||||
IN BOOLEAN Virtual
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
FvbGetPhysicalAddress (
|
||||
IN UINTN Instance,
|
||||
OUT EFI_PHYSICAL_ADDRESS *Address,
|
||||
IN ESAL_FWB_GLOBAL *Global,
|
||||
IN BOOLEAN Virtual
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FvbInitialize (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
);
|
||||
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
FvbClassAddressChangeEvent (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
FvbGetLbaAddress (
|
||||
IN UINTN Instance,
|
||||
IN EFI_LBA Lba,
|
||||
OUT UINTN *LbaAddress,
|
||||
OUT UINTN *LbaLength,
|
||||
OUT UINTN *NumOfBlocks,
|
||||
IN ESAL_FWB_GLOBAL *Global,
|
||||
IN BOOLEAN Virtual
|
||||
);
|
||||
|
||||
//
|
||||
// Protocol APIs
|
||||
//
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FvbProtocolGetAttributes (
|
||||
IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
|
||||
OUT EFI_FVB_ATTRIBUTES_2 *Attributes
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FvbProtocolSetAttributes (
|
||||
IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
|
||||
IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FvbProtocolGetPhysicalAddress (
|
||||
IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
|
||||
OUT EFI_PHYSICAL_ADDRESS *Address
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FvbProtocolGetBlockSize (
|
||||
IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
|
||||
IN CONST EFI_LBA Lba,
|
||||
OUT UINTN *BlockSize,
|
||||
OUT UINTN *NumOfBlocks
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FvbProtocolRead (
|
||||
IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
|
||||
IN CONST EFI_LBA Lba,
|
||||
IN CONST UINTN Offset,
|
||||
IN OUT UINTN *NumBytes,
|
||||
IN UINT8 *Buffer
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FvbProtocolWrite (
|
||||
IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
|
||||
IN EFI_LBA Lba,
|
||||
IN UINTN Offset,
|
||||
IN OUT UINTN *NumBytes,
|
||||
IN UINT8 *Buffer
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FvbProtocolEraseBlocks (
|
||||
IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
|
||||
...
|
||||
);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,265 @@
|
|||
/** @file
|
||||
OVMF support for QEMU system firmware flash device
|
||||
|
||||
Copyright (c) 2009 - 2013, Intel Corporation. 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/DebugLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiRuntimeLib.h>
|
||||
#include <Guid/EventGroup.h>
|
||||
|
||||
#include "QemuFlash.h"
|
||||
|
||||
#define WRITE_BYTE_CMD 0x10
|
||||
#define BLOCK_ERASE_CMD 0x20
|
||||
#define CLEAR_STATUS_CMD 0x50
|
||||
#define READ_STATUS_CMD 0x70
|
||||
#define READ_DEVID_CMD 0x90
|
||||
#define BLOCK_ERASE_CONFIRM_CMD 0xd0
|
||||
#define READ_ARRAY_CMD 0xff
|
||||
|
||||
#define CLEARED_ARRAY_STATUS 0x00
|
||||
|
||||
|
||||
STATIC UINT8 *mFlashBase = NULL;
|
||||
STATIC UINTN mFdBlockSize = 0;
|
||||
STATIC UINTN mFdBlockCount = 0;
|
||||
|
||||
|
||||
VOID
|
||||
QemuFlashConvertPointers (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EfiConvertPointer (0x0, (VOID **) &mFlashBase);
|
||||
}
|
||||
|
||||
|
||||
STATIC
|
||||
volatile UINT8*
|
||||
QemuFlashPtr (
|
||||
IN EFI_LBA Lba,
|
||||
IN UINTN Offset
|
||||
)
|
||||
{
|
||||
return mFlashBase + (Lba * mFdBlockSize) + Offset;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Determines if the QEMU flash memory device is present.
|
||||
|
||||
@retval FALSE The QEMU flash device is not present.
|
||||
@retval TRUE The QEMU flash device is present.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
BOOLEAN
|
||||
QemuFlashDetected (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
BOOLEAN FlashDetected;
|
||||
volatile UINT8 *Ptr;
|
||||
|
||||
UINTN Offset;
|
||||
UINT8 OriginalUint8;
|
||||
UINT8 ProbeUint8;
|
||||
|
||||
FlashDetected = FALSE;
|
||||
Ptr = QemuFlashPtr (0, 0);
|
||||
|
||||
for (Offset = 0; Offset < mFdBlockSize; Offset++) {
|
||||
Ptr = QemuFlashPtr (0, Offset);
|
||||
ProbeUint8 = *Ptr;
|
||||
if (ProbeUint8 != CLEAR_STATUS_CMD &&
|
||||
ProbeUint8 != READ_STATUS_CMD &&
|
||||
ProbeUint8 != CLEARED_ARRAY_STATUS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Offset >= mFdBlockSize) {
|
||||
DEBUG ((EFI_D_INFO, "QEMU Flash: Failed to find probe location\n"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DEBUG ((EFI_D_INFO, "QEMU Flash: Attempting flash detection at %p\n", Ptr));
|
||||
|
||||
OriginalUint8 = *Ptr;
|
||||
*Ptr = CLEAR_STATUS_CMD;
|
||||
ProbeUint8 = *Ptr;
|
||||
if (OriginalUint8 != CLEAR_STATUS_CMD &&
|
||||
ProbeUint8 == CLEAR_STATUS_CMD) {
|
||||
DEBUG ((EFI_D_INFO, "QemuFlashDetected => FD behaves as RAM\n"));
|
||||
*Ptr = OriginalUint8;
|
||||
} else {
|
||||
*Ptr = READ_STATUS_CMD;
|
||||
ProbeUint8 = *Ptr;
|
||||
if (ProbeUint8 == OriginalUint8) {
|
||||
DEBUG ((EFI_D_INFO, "QemuFlashDetected => FD behaves as ROM\n"));
|
||||
} else if (ProbeUint8 == READ_STATUS_CMD) {
|
||||
DEBUG ((EFI_D_INFO, "QemuFlashDetected => FD behaves as RAM\n"));
|
||||
*Ptr = OriginalUint8;
|
||||
} else if (ProbeUint8 == CLEARED_ARRAY_STATUS) {
|
||||
DEBUG ((EFI_D_INFO, "QemuFlashDetected => FD behaves as FLASH\n"));
|
||||
FlashDetected = TRUE;
|
||||
*Ptr = READ_ARRAY_CMD;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG ((EFI_D_INFO, "QemuFlashDetected => %a\n",
|
||||
FlashDetected ? "Yes" : "No"));
|
||||
return FlashDetected;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Read from QEMU Flash
|
||||
|
||||
@param[in] Lba The starting logical block index to read from.
|
||||
@param[in] Offset Offset into the block at which to begin reading.
|
||||
@param[in] NumBytes On input, indicates the requested read size. On
|
||||
output, indicates the actual number of bytes read
|
||||
@param[in] Buffer Pointer to the buffer to read into.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
QemuFlashRead (
|
||||
IN EFI_LBA Lba,
|
||||
IN UINTN Offset,
|
||||
IN UINTN *NumBytes,
|
||||
IN UINT8 *Buffer
|
||||
)
|
||||
{
|
||||
UINT8 *Ptr;
|
||||
|
||||
//
|
||||
// Only write to the first 64k. We don't bother saving the FTW Spare
|
||||
// block into the flash memory.
|
||||
//
|
||||
if (Lba >= mFdBlockCount) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Get flash address
|
||||
//
|
||||
Ptr = (UINT8*) QemuFlashPtr (Lba, Offset);
|
||||
|
||||
CopyMem (Buffer, Ptr, *NumBytes);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Write to QEMU Flash
|
||||
|
||||
@param[in] Lba The starting logical block index to write to.
|
||||
@param[in] Offset Offset into the block at which to begin writing.
|
||||
@param[in] NumBytes On input, indicates the requested write size. On
|
||||
output, indicates the actual number of bytes written
|
||||
@param[in] Buffer Pointer to the data to write.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
QemuFlashWrite (
|
||||
IN EFI_LBA Lba,
|
||||
IN UINTN Offset,
|
||||
IN UINTN *NumBytes,
|
||||
IN UINT8 *Buffer
|
||||
)
|
||||
{
|
||||
volatile UINT8 *Ptr;
|
||||
UINTN Loop;
|
||||
|
||||
//
|
||||
// Only write to the first 64k. We don't bother saving the FTW Spare
|
||||
// block into the flash memory.
|
||||
//
|
||||
if (Lba >= mFdBlockCount) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Program flash
|
||||
//
|
||||
Ptr = QemuFlashPtr (Lba, Offset);
|
||||
for (Loop = 0; Loop < *NumBytes; Loop++) {
|
||||
*Ptr = WRITE_BYTE_CMD;
|
||||
*Ptr = Buffer[Loop];
|
||||
Ptr++;
|
||||
}
|
||||
|
||||
//
|
||||
// Restore flash to read mode
|
||||
//
|
||||
if (*NumBytes > 0) {
|
||||
*Ptr = READ_ARRAY_CMD;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Erase a QEMU Flash block
|
||||
|
||||
@param Lba The logical block index to erase.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
QemuFlashEraseBlock (
|
||||
IN EFI_LBA Lba
|
||||
)
|
||||
{
|
||||
volatile UINT8 *Ptr;
|
||||
|
||||
if (Lba >= mFdBlockCount) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Ptr = QemuFlashPtr (Lba, 0);
|
||||
*Ptr = BLOCK_ERASE_CMD;
|
||||
*Ptr = BLOCK_ERASE_CONFIRM_CMD;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Initializes QEMU flash memory support
|
||||
|
||||
@retval EFI_WRITE_PROTECTED The QEMU flash device is not present.
|
||||
@retval EFI_SUCCESS The QEMU flash device is supported.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
QemuFlashInitialize (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
mFlashBase = (UINT8*)(UINTN) PcdGet32 (PcdOvmfFdBaseAddress);
|
||||
mFdBlockSize = PcdGet32 (PcdOvmfFirmwareBlockSize);
|
||||
ASSERT(PcdGet32 (PcdOvmfFirmwareFdSize) % mFdBlockSize == 0);
|
||||
mFdBlockCount = PcdGet32 (PcdOvmfFirmwareFdSize) / mFdBlockSize;
|
||||
|
||||
if (!QemuFlashDetected ()) {
|
||||
return EFI_WRITE_PROTECTED;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
/** @file
|
||||
OVMF support for QEMU system firmware flash device
|
||||
|
||||
Copyright (c) 2009 - 2013, Intel Corporation. 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 __QEMU_FLASH_H__
|
||||
#define __QEMU_FLASH_H__
|
||||
|
||||
#include <Protocol/FirmwareVolumeBlock.h>
|
||||
|
||||
/**
|
||||
Read from QEMU Flash
|
||||
|
||||
@param[in] Lba The starting logical block index to read from.
|
||||
@param[in] Offset Offset into the block at which to begin reading.
|
||||
@param[in] NumBytes On input, indicates the requested read size. On
|
||||
output, indicates the actual number of bytes read
|
||||
@param[in] Buffer Pointer to the buffer to read into.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
QemuFlashRead (
|
||||
IN EFI_LBA Lba,
|
||||
IN UINTN Offset,
|
||||
IN UINTN *NumBytes,
|
||||
IN UINT8 *Buffer
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
Write to QEMU Flash
|
||||
|
||||
@param[in] Lba The starting logical block index to write to.
|
||||
@param[in] Offset Offset into the block at which to begin writing.
|
||||
@param[in] NumBytes On input, indicates the requested write size. On
|
||||
output, indicates the actual number of bytes written
|
||||
@param[in] Buffer Pointer to the data to write.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
QemuFlashWrite (
|
||||
IN EFI_LBA Lba,
|
||||
IN UINTN Offset,
|
||||
IN UINTN *NumBytes,
|
||||
IN UINT8 *Buffer
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
Erase a QEMU Flash block
|
||||
|
||||
@param Lba The logical block index to erase.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
QemuFlashEraseBlock (
|
||||
IN EFI_LBA Lba
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
Initializes QEMU flash memory support
|
||||
|
||||
@retval EFI_WRITE_PROTECTED The QEMU flash device is not present.
|
||||
@retval EFI_SUCCESS The QEMU flash device is supported.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
QemuFlashInitialize (
|
||||
VOID
|
||||
);
|
||||
|
||||
|
||||
VOID
|
||||
QemuFlashConvertPointers (
|
||||
VOID
|
||||
);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue