OvmfPkg/VirtHstiDxe: add varstore flash check
Detects qemu config issue: vars pflash is not in secure mode (write access restricted to smm). Applies to Q35 with SMM only. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Konstantin Kostiuk <kkostiuk@redhat.com> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Jiewen Yao <Jiewen.yao@intel.com>
This commit is contained in:
committed by
mergify[bot]
parent
538b8944c1
commit
ddc43e7a41
90
OvmfPkg/VirtHstiDxe/Flash.c
Normal file
90
OvmfPkg/VirtHstiDxe/Flash.c
Normal file
@@ -0,0 +1,90 @@
|
||||
/** @file
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
|
||||
#include "VirtHstiDxe.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
|
||||
|
||||
/* based on QemuFlashDetected (QemuFlashFvbServicesRuntimeDxe) */
|
||||
UINT32
|
||||
VirtHstiQemuFirmwareFlashCheck (
|
||||
UINT32 Address
|
||||
)
|
||||
{
|
||||
volatile UINT8 *Ptr;
|
||||
|
||||
UINTN Offset;
|
||||
UINT8 OriginalUint8;
|
||||
UINT8 ProbeUint8;
|
||||
|
||||
for (Offset = 0; Offset < EFI_PAGE_SIZE; Offset++) {
|
||||
Ptr = (UINT8 *)(UINTN)(Address + Offset);
|
||||
ProbeUint8 = *Ptr;
|
||||
if ((ProbeUint8 != CLEAR_STATUS_CMD) &&
|
||||
(ProbeUint8 != READ_STATUS_CMD) &&
|
||||
(ProbeUint8 != CLEARED_ARRAY_STATUS))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Offset >= EFI_PAGE_SIZE) {
|
||||
DEBUG ((DEBUG_INFO, "%a: check failed\n", __func__));
|
||||
return QEMU_FIRMWARE_FLASH_UNKNOWN;
|
||||
}
|
||||
|
||||
OriginalUint8 = *Ptr;
|
||||
*Ptr = CLEAR_STATUS_CMD;
|
||||
ProbeUint8 = *Ptr;
|
||||
if ((OriginalUint8 != CLEAR_STATUS_CMD) &&
|
||||
(ProbeUint8 == CLEAR_STATUS_CMD))
|
||||
{
|
||||
*Ptr = OriginalUint8;
|
||||
DEBUG ((DEBUG_INFO, "%a: %p behaves as RAM\n", __func__, Ptr));
|
||||
return QEMU_FIRMWARE_FLASH_IS_RAM;
|
||||
}
|
||||
|
||||
*Ptr = READ_STATUS_CMD;
|
||||
ProbeUint8 = *Ptr;
|
||||
if (ProbeUint8 == OriginalUint8) {
|
||||
DEBUG ((DEBUG_INFO, "%a: %p behaves as ROM\n", __func__, Ptr));
|
||||
return QEMU_FIRMWARE_FLASH_IS_ROM;
|
||||
}
|
||||
|
||||
if (ProbeUint8 == READ_STATUS_CMD) {
|
||||
*Ptr = OriginalUint8;
|
||||
DEBUG ((DEBUG_INFO, "%a: %p behaves as RAM\n", __func__, Ptr));
|
||||
return QEMU_FIRMWARE_FLASH_IS_RAM;
|
||||
}
|
||||
|
||||
if (ProbeUint8 == CLEARED_ARRAY_STATUS) {
|
||||
*Ptr = WRITE_BYTE_CMD;
|
||||
*Ptr = OriginalUint8;
|
||||
*Ptr = READ_STATUS_CMD;
|
||||
ProbeUint8 = *Ptr;
|
||||
*Ptr = READ_ARRAY_CMD;
|
||||
if (ProbeUint8 & 0x10 /* programming error */) {
|
||||
DEBUG ((DEBUG_INFO, "%a: %p behaves as FLASH, write-protected\n", __func__, Ptr));
|
||||
return QEMU_FIRMWARE_FLASH_READ_ONLY;
|
||||
} else {
|
||||
DEBUG ((DEBUG_INFO, "%a: %p behaves as FLASH, writable\n", __func__, Ptr));
|
||||
return QEMU_FIRMWARE_FLASH_WRITABLE;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO, "%a: check failed\n", __func__));
|
||||
return QEMU_FIRMWARE_FLASH_UNKNOWN;
|
||||
}
|
Reference in New Issue
Block a user