Documentation: Add SMMSTORE documentation
This documents the smmstore API. Change-Id: I992c04c0cf9b3f03755cf3fede2c82c6471a5ef4 Signed-off-by: Arthur Heymans <arthur@aheymans.xyz> Reviewed-on: https://review.coreboot.org/c/coreboot/+/37243 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Patrick Georgi <pgeorgi@google.com>
This commit is contained in:
parent
ed50d85576
commit
b52cc0e094
|
@ -5,3 +5,4 @@ and plugin devices, significantly reducing integration complexity and
|
||||||
they allow to easily reuse existing code accross platforms.
|
they allow to easily reuse existing code accross platforms.
|
||||||
|
|
||||||
* [IPMI KCS](ipmi_kcs.md)
|
* [IPMI KCS](ipmi_kcs.md)
|
||||||
|
* [SMMSTORE](smmstore.md)
|
||||||
|
|
|
@ -0,0 +1,123 @@
|
||||||
|
# SMM based flash storage driver
|
||||||
|
|
||||||
|
This documents the API exposed by the x86 system management based
|
||||||
|
storage driver.
|
||||||
|
|
||||||
|
## SMMSTORE
|
||||||
|
|
||||||
|
SMMSTORE is a SMM mediated driver to read from, write to and erase a
|
||||||
|
predefined region in flash. It can be enabled by setting
|
||||||
|
`CONFIG_SMMSTORE=y` in menuconfig.
|
||||||
|
|
||||||
|
This can be used by the OS or the payload to implement persistent
|
||||||
|
storage to hold for instance configuration data, without needing
|
||||||
|
to implement a (platform specific) storage driver in the payload
|
||||||
|
itself.
|
||||||
|
|
||||||
|
The API provides append-only semantics for key/value pairs.
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
|
### Storage region
|
||||||
|
|
||||||
|
By default SMMSTORE will operate on a separate FMAP region called
|
||||||
|
`SMMSTORE`. The default generated FMAP will include such a region.
|
||||||
|
On systems with a locked FMAP, e.g. in an existing VBOOT setup
|
||||||
|
with a locked RO region, the option exists to add a cbfsfile
|
||||||
|
called `smm_store` in the `RW_LEGACY` (if CHROMEOS) or in the
|
||||||
|
`COREBOOT` FMAP regions. It is recommended for new builds using
|
||||||
|
a handcrafted FMD that intend to make use of SMMSTORE to include a
|
||||||
|
sufficiently large `SMMSTORE` FMAP region. It is recommended to
|
||||||
|
align the `SMMSTORE` region to 64KiB for the largest flash erase
|
||||||
|
op compatibility.
|
||||||
|
|
||||||
|
When a default generated FMAP is used the size of the FMAP region
|
||||||
|
is equal to `CONFIG_SMMSTORE_SIZE`. UEFI payloads expect at least
|
||||||
|
64KiB. Given that the current implementation lacks a way to rewrite
|
||||||
|
key-value pairs at least a multiple of this is recommended.
|
||||||
|
|
||||||
|
### generating the SMI
|
||||||
|
|
||||||
|
SMMSTORE is called via an SMI, which is generated via a write to the
|
||||||
|
IO port defined in the smi_cmd entry of the FADT ACPI table. `%al`
|
||||||
|
contains `APM_CNT_SMMSTORE=0xed` and is written to the smi_cmd IO
|
||||||
|
port. `%ah` contains the SMMSTORE command. `%ebx` contains the
|
||||||
|
parameter buffer to the SMMSTORE command.
|
||||||
|
|
||||||
|
### Return values
|
||||||
|
|
||||||
|
If a command succeeds, SMMSTORE will return with
|
||||||
|
`SMMSTORE_RET_SUCCESS=0` on `%eax`. On failure SMMSTORE will return
|
||||||
|
`SMMSTORE_RET_FAILURE=1`. For unsupported SMMSTORE commands
|
||||||
|
`SMMSTORE_REG_UNSUPPORTED=2` is returned.
|
||||||
|
|
||||||
|
**NOTE1**: The caller **must** check the return value and should make
|
||||||
|
no assumption on the returned data if `%eax` does not contain
|
||||||
|
`SMMSTORE_RET_SUCCESS`.
|
||||||
|
|
||||||
|
**NOTE2**: If the SMI returns without changing `%ax` assume that the
|
||||||
|
SMMSTORE feature is not installed.
|
||||||
|
|
||||||
|
### Calling arguments
|
||||||
|
|
||||||
|
SMMSTORE supports 3 subcommands that are passed via `%ah`, the additional
|
||||||
|
calling arguments are passed via `%ebx`.
|
||||||
|
|
||||||
|
**NOTE**: The size of the struct entries are in the native word size of
|
||||||
|
smihandler. This means 32 bits in almost all cases.
|
||||||
|
|
||||||
|
|
||||||
|
#### - SMMSTORE_CMD_CLEAR = 1
|
||||||
|
|
||||||
|
This clears the `SMMSTORE` storage region. The argument in `%ebx` is
|
||||||
|
unused.
|
||||||
|
|
||||||
|
#### - SMMSTORE_CMD_READ = 2
|
||||||
|
|
||||||
|
The additional parameter buffer `%ebx` contains a pointer to
|
||||||
|
the following struct:
|
||||||
|
|
||||||
|
```C
|
||||||
|
struct smmstore_params_read {
|
||||||
|
void *buf;
|
||||||
|
ssize_t bufsize;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
INPUT:
|
||||||
|
- `buf`: is a pointer to where the data needs to be read
|
||||||
|
- `bufsize`: is the size of the buffer
|
||||||
|
|
||||||
|
OUTPUT:
|
||||||
|
- `buf`
|
||||||
|
- `bufsize`: returns the amount of data that has actually been read.
|
||||||
|
|
||||||
|
#### - SMMSTORE_CMD_APPEND = 3
|
||||||
|
|
||||||
|
SMMSTORE takes a key-value approach to appending data. key-value pairs
|
||||||
|
are never updated, they are always appended. It is up to the caller to
|
||||||
|
walk through the key-value pairs after reading SMMSTORE to find the
|
||||||
|
latest one.
|
||||||
|
|
||||||
|
The additional parameter buffer `%ebx` contains a pointer to
|
||||||
|
the following struct:
|
||||||
|
|
||||||
|
```C
|
||||||
|
struct smmstore_params_append {
|
||||||
|
void *key;
|
||||||
|
size_t keysize;
|
||||||
|
void *val;
|
||||||
|
size_t valsize;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
INPUT:
|
||||||
|
- `key`: pointer to the key data
|
||||||
|
- `keysize`: size of the key data
|
||||||
|
- `val`: pointer to the value data
|
||||||
|
- `valsize`: size of the value data
|
||||||
|
|
||||||
|
## External links
|
||||||
|
|
||||||
|
* [A Tour Beyond BIOS Implementing UEFI Authenticated Variables in SMM with EDKI](https://software.intel.com/sites/default/files/managed/cf/ea/a_tour_beyond_bios_implementing_uefi_authenticated_variables_in_smm_with_edkii.pdf)
|
||||||
|
Note, this differs significantly from coreboot's implementation.
|
Loading…
Reference in New Issue