Files
system76-edk2/UefiPayloadPkg/Library/SmmStoreLib/SmmStore.h
Patrick Rudolph dcdfb2f083 UefiPayloadPkg: Add SmmStoreLib
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
2022-06-03 09:03:42 -06:00

82 lines
1.8 KiB
C

/** @file SmmStore.h
Copyright (c) 2022, 9elements GmbH<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef COREBOOT_SMMSTORE_H_
#define COREBOOT_SMMSTORE_H_
#define SMMSTORE_RET_SUCCESS 0
#define SMMSTORE_RET_FAILURE 1
#define SMMSTORE_RET_UNSUPPORTED 2
/* Version 2 only */
#define SMMSTORE_CMD_INIT 4
#define SMMSTORE_CMD_RAW_READ 5
#define SMMSTORE_CMD_RAW_WRITE 6
#define SMMSTORE_CMD_RAW_CLEAR 7
/*
* This allows the payload to store raw data in the flash regions.
* This can be used by a FaultTolerantWrite implementation, that uses at least
* two regions in an A/B update scheme.
*/
#pragma pack(1)
/*
* Reads a chunk of raw data with size BufSize from the block specified by
* block_id starting at BufOffset.
* The read data is placed in buf.
*
* block_id must be less than num_blocks
* BufOffset + BufSize must be less than block_size
*/
typedef struct {
UINT32 BufSize;
UINT32 BufOffset;
UINT32 BlockId;
} SMM_STORE_PARAMS_WRITE;
/*
* Writes a chunk of raw data with size BufSize to the block specified by
* block_id starting at BufOffset.
*
* block_id must be less than num_blocks
* BufOffset + BufSize must be less than block_size
*/
typedef struct {
UINT32 BufSize;
UINT32 BufOffset;
UINT32 BlockId;
} SMM_STORE_PARAMS_READ;
/*
* Erases the specified block.
*
* block_id must be less than num_blocks
*/
typedef struct {
UINT32 BlockId;
} SMM_STORE_PARAMS_CLEAR;
typedef union {
SMM_STORE_PARAMS_WRITE Write;
SMM_STORE_PARAMS_READ Read;
SMM_STORE_PARAMS_CLEAR Clear;
} SMM_STORE_COM_BUF;
#pragma pack(0)
UINTN
EFIAPI
TriggerSmi (
IN UINTN Cmd,
IN UINTN Arg,
IN UINTN Retry
);
#endif // COREBOOT_SMMSTORE_H_