Implement all of the FVB protocol functions on top of the SmmStore as a library. The library consumes the introduced gEfiSmmStoreInfoHobGuid. The SMI handler uses a fixed communication buffer in reserved DRAM. To initiate a transaction you must write to the I/O APM_CNT port. Tests on Intel(R) Xeon(R) E-2288G CPU @ 3.70G showed that the SMI isn't triggered with a probability of 1:40 of all cases when called in a tight loop. The CPU continues running and the SMI is triggeres asynchronously a few clock cycles later. coreboot only handels synchronous APM request and does nothing on asynchronous APM triggers. As there's no livesign from SMM it's impossible to tell if the handler has run. Just wait a bit and try again to trigger a synchronous SMI. Tests confirmed that out of 5 million tries the SMI is now always handled. When a synchronous SMI happens with the correct write to the APM_CNT port, the ebx register is checked first that it doesn't point to SMRAM. If it doesn't it's used to read in the arguments that define a SmmStore transaction. The SMI handler will only operate on a predefined and memory mapped region in the boot media. Cc: Guo Dong <guo.dong@intel.com> Cc: Ray Ni <ray.ni@intel.com> Cc: Maurice Ma <maurice.ma@intel.com> Cc: Benjamin You <benjamin.you@intel.com> Cc: Sean Rhodes <sean@starlabs.systems> Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com> Change-Id: Id4182623e4198c6512d3fe6ec20adf6738586d9b
121 lines
2.5 KiB
C
121 lines
2.5 KiB
C
/** @file SmmStoreLib.h
|
|
|
|
Copyright (c) 2022, 9elements GmbH<BR>
|
|
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
|
**/
|
|
|
|
#ifndef SMM_STORE_LIB_H_
|
|
#define SMM_STORE_LIB_H_
|
|
|
|
#include <Base.h>
|
|
#include <Uefi/UefiBaseType.h>
|
|
#include <Guid/SmmStoreInfoGuid.h>
|
|
|
|
#define SMMSTORE_COMBUF_SIZE 16
|
|
|
|
/**
|
|
Get the SmmStore block size
|
|
|
|
@param BlockSize The pointer to store the block size in.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
SmmStoreLibGetBlockSize (
|
|
OUT UINTN *BlockSize
|
|
);
|
|
|
|
/**
|
|
Get the SmmStore number of blocks
|
|
|
|
@param NumBlocks The pointer to store the number of blocks in.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
SmmStoreLibGetNumBlocks (
|
|
OUT UINTN *NumBlocks
|
|
);
|
|
|
|
/**
|
|
Get the SmmStore MMIO address
|
|
|
|
@param MmioAddress The pointer to store the address in.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
SmmStoreLibGetMmioAddress (
|
|
OUT EFI_PHYSICAL_ADDRESS *MmioAddress
|
|
);
|
|
|
|
/**
|
|
Read from SmmStore
|
|
|
|
@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
|
|
SmmStoreLibRead (
|
|
IN EFI_LBA Lba,
|
|
IN UINTN Offset,
|
|
IN UINTN *NumBytes,
|
|
IN UINT8 *Buffer
|
|
);
|
|
|
|
/**
|
|
Write to SmmStore
|
|
|
|
@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
|
|
SmmStoreLibWrite (
|
|
IN EFI_LBA Lba,
|
|
IN UINTN Offset,
|
|
IN UINTN *NumBytes,
|
|
IN UINT8 *Buffer
|
|
);
|
|
|
|
/**
|
|
Erase a block using the SmmStore
|
|
|
|
@param Lba The logical block index to erase.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
SmmStoreLibEraseBlock (
|
|
IN EFI_LBA Lba
|
|
);
|
|
|
|
/**
|
|
Initializes SmmStore support
|
|
|
|
@retval EFI_WRITE_PROTECTED The SmmStore is not present.
|
|
@retval EFI_UNSUPPORTED The SmmStoreInfo HOB wasn't found.
|
|
@retval EFI_SUCCESS The SmmStore is supported.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
SmmStoreLibInitialize (
|
|
VOID
|
|
);
|
|
|
|
/**
|
|
Denitializes SmmStore support
|
|
**/
|
|
VOID
|
|
EFIAPI
|
|
SmmStoreLibDeinitialize (
|
|
VOID
|
|
);
|
|
|
|
#endif /* SMM_STORE_LIB_H_ */
|