Patrick Rudolph has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: [RFC]drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
[RFC]drivers/smmstore: Implement SMMSTORE version 2
Seperates the SMMSTORE into 64KiB blocks that can individually be read/written/erased. To be used by payloads that implement a FaultTolerant Variable store like Tianocore.
The implementation has been tested against EDK2 master.
An example EDK2 implementation can be found here: https://github.com/9elements/edk2-1/commit/c7cbcd527af397d5d8473f3e52720ffde...
Change-Id: I25e49d184135710f3e6dd1ad3bed95de950fe057 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com --- M src/drivers/smmstore/smi.c M src/drivers/smmstore/store.c M src/include/smmstore.h 3 files changed, 227 insertions(+), 1 deletion(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/20/40520/1
diff --git a/src/drivers/smmstore/smi.c b/src/drivers/smmstore/smi.c index 57f79b8..501f3d3 100644 --- a/src/drivers/smmstore/smi.c +++ b/src/drivers/smmstore/smi.c @@ -60,6 +60,47 @@ break; }
+ case SMMSTORE_CMD_INFO: { + printk(BIOS_DEBUG, "Returning SMM store info\n"); + struct smmstore_params_info *params = param; + if (smmstore_update_info(params) == 0) + ret = SMMSTORE_RET_SUCCESS; + break; + } + case SMMSTORE_CMD_RAW_READ: { + printk(BIOS_DEBUG, "Raw read from SMM store, param = %p\n", param); + struct smmstore_params_raw_read *params = param; + void *buf = (void *)(uintptr_t)params->buf; + + if (range_check(buf, params->bufsize) != 0) + break; + + if (smmstore_rawread_region(buf, params->bufoffset, + params->block_id, ¶ms->bufsize) == 0) + ret = SMMSTORE_RET_SUCCESS; + break; + } + case SMMSTORE_CMD_RAW_WRITE: { + printk(BIOS_DEBUG, "Raw write to SMM store, param = %p\n", param); + struct smmstore_params_raw_write *params = param; + void *buf = (void *)(uintptr_t)params->buf; + + if (range_check(buf, params->bufsize) != 0) + break; + + if (smmstore_rawwrite_region(buf, params->bufoffset, + params->block_id, ¶ms->bufsize) == 0) + ret = SMMSTORE_RET_SUCCESS; + break; + } + case SMMSTORE_CMD_RAW_CLEAR: { + printk(BIOS_DEBUG, "Raw clear SMM store, param = %p\n", param); + struct smmstore_params_raw_clear *params = param; + + if (smmstore_rawclear_region(params->block_id) == 0) + ret = SMMSTORE_RET_SUCCESS; + break; + } default: printk(BIOS_DEBUG, "Unknown SMM store command: 0x%02x\n", command); diff --git a/src/drivers/smmstore/store.c b/src/drivers/smmstore/store.c index dbad085..e10f133 100644 --- a/src/drivers/smmstore/store.c +++ b/src/drivers/smmstore/store.c @@ -263,3 +263,112 @@
return 0; } + + +/* implementation of Version 2 */ + +static struct smmstore_params_info info_params; + +int smmstore_update_info(struct smmstore_params_info *out) +{ + struct region_device store; + + if (!info_params.block_size) { + if (lookup_store(&store) < 0) { + printk(BIOS_WARNING, "smm store: reading region failed\n"); + return -1; + } + info_params.block_size = 64 * KiB; + info_params.num_blocks = region_device_sz(&store) / info_params.block_size; + printk(BIOS_DEBUG, "smm store: %d # blocks with size 0x%x\n", + info_params.num_blocks, info_params.block_size); + } + + out->block_size = info_params.block_size; + out->num_blocks = info_params.num_blocks; + /* FIXME: Broken EDK2 always assumes memory mapped Firmware Block Volumes */ + out->mmap_addr = (uintptr_t)rdev_mmap_full(&store); + return 0; +} + +int smmstore_rawread_region(void *buf, uint32_t offset, uint32_t block_id, uint32_t *bufsize) +{ + struct region_device store; + ssize_t ret; + + if (lookup_store(&store) < 0) { + printk(BIOS_WARNING, "reading region failed\n"); + return -1; + } + + if (offset >= info_params.block_size || block_id >= info_params.num_blocks) { + printk(BIOS_WARNING, "access out of region requested\n"); + return -1; + } + + ssize_t tx = MIN(*bufsize, (block_id + 1) * info_params.block_size - offset); + printk(BIOS_DEBUG, "smm store: reading %p block %d, offset=0x%x, size=%zx\n", + buf, block_id, offset, tx); + ret = rdev_readat(&store, buf, block_id * info_params.block_size + offset, tx); + if (ret < 0) + return -1; + + *bufsize = ret; + + return 0; +} + +int smmstore_rawwrite_region(void *buf, uint32_t offset, uint32_t block_id, uint32_t *bufsize) +{ + struct region_device store; + ssize_t ret; + + if (lookup_store(&store) < 0) { + printk(BIOS_WARNING, "writing region failed\n"); + return -1; + } + printk(BIOS_DEBUG, "smm store: writing %p block %d, offset=0x%x, size=%x\n", + buf, block_id, offset, *bufsize); + + if (offset >= info_params.block_size || block_id >= info_params.num_blocks) { + printk(BIOS_WARNING, "access out of region requested\n"); + return -1; + } + + if (rdev_chain(&store, &store, block_id * info_params.block_size + offset, *bufsize)) { + printk(BIOS_WARNING, "not enough space for new data\n"); + return -1; + } + + ret = rdev_writeat(&store, buf, 0, *bufsize); + if (ret < 0) + return -1; + + *bufsize = ret; + + return 0; +} + +int smmstore_rawclear_region(uint32_t block_id) +{ + struct region_device store; + + if (block_id >= info_params.num_blocks) { + printk(BIOS_WARNING, "access out of region requested\n"); + return -1; + } + + if (lookup_store(&store) < 0) { + printk(BIOS_WARNING, "smm store: reading region failed\n"); + return -1; + } + + ssize_t res = rdev_eraseat(&store, block_id * info_params.block_size, + info_params.block_size); + if (res != info_params.block_size) { + printk(BIOS_WARNING, "smm store: erasing block failed\n"); + return -1; + } + + return 0; +} diff --git a/src/include/smmstore.h b/src/include/smmstore.h index af07ff0..6a32008 100644 --- a/src/include/smmstore.h +++ b/src/include/smmstore.h @@ -11,10 +11,18 @@ #define SMMSTORE_RET_FAILURE 1 #define SMMSTORE_RET_UNSUPPORTED 2
+/* Version 1 */ #define SMMSTORE_CMD_CLEAR 1 #define SMMSTORE_CMD_READ 2 #define SMMSTORE_CMD_APPEND 3
+/* Version 2 */ +#define SMMSTORE_CMD_INFO 4 +#define SMMSTORE_CMD_RAW_READ 5 +#define SMMSTORE_CMD_RAW_WRITE 6 +#define SMMSTORE_CMD_RAW_CLEAR 7 + +/* Version 1 */ struct smmstore_params_read { void *buf; ssize_t bufsize; @@ -27,12 +35,80 @@ size_t valsize; };
+/* Version 2 */ +/* + * Version 2 of the SMM requires as SMMSTORE of at least 256KiB of size, that + * has to be aligned to 64KiB. + * This allows the payload to store raw data in the SMMSTORE flash region. + * This can be used by a FaultTolerantWrite implementation, that uses at least + * two regions in an A/B update scheme. + * + * The Version 2 protocol seperates the SMMSTORE into 64KiB blocks, where each block + * can be read/written/cleared in an independent manner. + * FIXME: The data format isn't specified. + * + */ +/* + * Returns the number of blocks the SMMSTORE supports and their size. + * For EDK2 this should be at least two blocks with 64KiB each. + */ +struct smmstore_params_info { + uint32_t num_blocks; + uint32_t block_size; + uint32_t mmap_addr; +} __packed; + +/* + * 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 memory pointed to by @buf. + * + * @block_id must be less than num_blocks + * @bufoffset + @bufsize must be less than block_size + */ +struct smmstore_params_raw_write { + uint32_t buf; + uint32_t bufsize; + uint32_t bufoffset; + uint32_t block_id; +} __packed; + +/* + * 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 + */ +struct smmstore_params_raw_read { + uint32_t buf; + uint32_t bufsize; + uint32_t bufoffset; + uint32_t block_id; +} __packed; + +/* + * Erases the specified block. + * + * @block_id must be less than num_blocks + */ +struct smmstore_params_raw_clear { + uint32_t block_id; +} __packed; + + /* SMM responder */ uint32_t smmstore_exec(uint8_t command, void *param);
-/* implementation */ +/* implementation of Version 1 */ int smmstore_read_region(void *buf, ssize_t *bufsize); int smmstore_append_data(void *key, uint32_t key_sz, void *value, uint32_t value_sz); int smmstore_clear_region(void); +/* implementation of Version 2 */ +int smmstore_update_info(struct smmstore_params_info *info); +int smmstore_rawread_region(void *buf, uint32_t offset, uint32_t block_id, uint32_t *bufsize); +int smmstore_rawwrite_region(void *buf, uint32_t offset, uint32_t block_id, uint32_t *bufsize); +int smmstore_rawclear_region(uint32_t block_id); + #endif
build bot (Jenkins) has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: [RFC]drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 1:
(1 comment)
https://review.coreboot.org/c/coreboot/+/40520/1/src/include/smmstore.h File src/include/smmstore.h:
https://review.coreboot.org/c/coreboot/+/40520/1/src/include/smmstore.h@46 PS1, Line 46: * The Version 2 protocol seperates the SMMSTORE into 64KiB blocks, where each block 'seperates' may be misspelled - perhaps 'separates'?
Arthur Heymans has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: [RFC]drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 1:
(5 comments)
Looks quite good to me. Don't forget Documentation/drivers/smmstore.md when it's done.
https://review.coreboot.org/c/coreboot/+/40520/1/src/drivers/smmstore/smi.c File src/drivers/smmstore/smi.c:
https://review.coreboot.org/c/coreboot/+/40520/1/src/drivers/smmstore/smi.c@... PS1, Line 63: case SMMSTORE_CMD_INFO: { Given that less SMM code is typically better/desirable, would you want to have a Kconfig option for which 'versions' you compile (1, 2 or both for max compatibility)?
https://review.coreboot.org/c/coreboot/+/40520/1/src/drivers/smmstore/store.... File src/drivers/smmstore/store.c:
https://review.coreboot.org/c/coreboot/+/40520/1/src/drivers/smmstore/store.... PS1, Line 270: static struct smmstore_params_info info_params; So smmstore_update_info has to be called before any of the other operations can be used? Would you want an error code on the other operations if that is not the case?
Can't read/write/erase ops do also that when it's not initialized by smmstore_update_info() given that the information is based on something constant (FMAP region)?
https://review.coreboot.org/c/coreboot/+/40520/1/src/drivers/smmstore/store.... PS1, Line 272: smmstore_update_info You probably want to check if the base of the region is 64KiB aligned? Maybe the erase ops of region_device already do that, not sure...
https://review.coreboot.org/c/coreboot/+/40520/1/src/drivers/smmstore/store.... PS1, Line 304: if (offset >= info_params.block_size || block_id >= info_params.num_blocks) { : printk(BIOS_WARNING, "access out of region requested\n"); Maybe some more fine grained error messages could be useful when debugging things?
https://review.coreboot.org/c/coreboot/+/40520/1/src/include/smmstore.h File src/include/smmstore.h:
https://review.coreboot.org/c/coreboot/+/40520/1/src/include/smmstore.h@40 PS1, Line 40: * Version 2 of the SMM requires as SMMSTORE of at least 256KiB of size, that : * has to be aligned to 64KiB. : * This allows the payload to store raw data in the SMMSTORE flash region. : * This can be used by a FaultTolerantWrite implementation, that uses at least : * two regions in an A/B update scheme. Why is 256KiB needed if you have A/B (2) regions of 64KiB? Or is it typical to need 2 x 64KiB region for storing things for which you want an A/B scheme?
I presume that 64KiB is because coreboot only implements 64KiB erase ops on some flashes? Might be worth mentioning that?
Patrick Rudolph has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: [RFC]drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 1:
(2 comments)
https://review.coreboot.org/c/coreboot/+/40520/1/src/drivers/smmstore/store.... File src/drivers/smmstore/store.c:
https://review.coreboot.org/c/coreboot/+/40520/1/src/drivers/smmstore/store.... PS1, Line 270: static struct smmstore_params_info info_params;
So smmstore_update_info has to be called before any of the other operations can be used? Would you w […]
Good point, I'll rework that
https://review.coreboot.org/c/coreboot/+/40520/1/src/include/smmstore.h File src/include/smmstore.h:
https://review.coreboot.org/c/coreboot/+/40520/1/src/include/smmstore.h@40 PS1, Line 40: * Version 2 of the SMM requires as SMMSTORE of at least 256KiB of size, that : * has to be aligned to 64KiB. : * This allows the payload to store raw data in the SMMSTORE flash region. : * This can be used by a FaultTolerantWrite implementation, that uses at least : * two regions in an A/B update scheme.
Why is 256KiB needed if you have A/B (2) regions of 64KiB? Or is it typical to need 2 x 64KiB region […]
64KiB is the minimum for UEFI variable store + 64KiB as FaultTolerantWrite backup. But there's also the FtwSpare Block, for which I'm not sure what it is used for. Yes it uses 64KiB as that block size should be supported by all the flash chips.
Hello Philipp Deppenwiese, build bot (Jenkins), Matt DeVillier, Jeremy Soller, Christian Walter, Arthur Heymans, Marcello Sylvester Bauer,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/40520
to look at the new patch set (#2).
Change subject: [RFC]drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
[RFC]drivers/smmstore: Implement SMMSTORE version 2
Seperates the SMMSTORE into 64KiB blocks that can individually be read/written/erased. To be used by payloads that implement a FaultTolerant Variable store like Tianocore.
The implementation has been tested against EDK2 master.
An example EDK2 implementation can be found here: https://github.com/9elements/edk2-1/commit/7c5f0f6bee86dd0a94251b82f0e6f3a10...
Change-Id: I25e49d184135710f3e6dd1ad3bed95de950fe057 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com --- M src/drivers/smmstore/smi.c M src/drivers/smmstore/store.c M src/include/smmstore.h 3 files changed, 224 insertions(+), 1 deletion(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/20/40520/2
build bot (Jenkins) has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: [RFC]drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 2:
(1 comment)
https://review.coreboot.org/c/coreboot/+/40520/2/src/include/smmstore.h File src/include/smmstore.h:
https://review.coreboot.org/c/coreboot/+/40520/2/src/include/smmstore.h@46 PS2, Line 46: * The Version 2 protocol seperates the SMMSTORE into 64KiB blocks, where each block 'seperates' may be misspelled - perhaps 'separates'?
Hello Philipp Deppenwiese, build bot (Jenkins), Matt DeVillier, Jeremy Soller, Christian Walter, Arthur Heymans, Marcello Sylvester Bauer,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/40520
to look at the new patch set (#3).
Change subject: [RFC]drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
[RFC]drivers/smmstore: Implement SMMSTORE version 2
The SMMSTORE version 2 is a complete redesign of the current driver.
Some key features: * Uses a fixed communication buffer instead writing to arbitrary ring0 memory addresses * Gives the caller full control over the used data format * Splits the store into smaller chunks to allow fault tolerant updates
Seperates the SMMSTORE into 64KiB blocks that can individually be read/written/erased. To be used by payloads that implement a FaultTolerant Variable store like Tianocore.
The implementation has been tested against EDK2 master.
An example EDK2 implementation can be found here: https://github.com/9elements/edk2-1/commit/7c5f0f6bee86dd0a94251b82f0e6f3a10...
Change-Id: I25e49d184135710f3e6dd1ad3bed95de950fe057 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com --- M payloads/libpayload/include/coreboot_tables.h M src/commonlib/include/commonlib/cbmem_id.h M src/commonlib/include/commonlib/coreboot_tables.h M src/drivers/smmstore/Kconfig M src/drivers/smmstore/Makefile.inc A src/drivers/smmstore/ramstage.c M src/drivers/smmstore/smi.c M src/drivers/smmstore/store.c M src/include/smmstore.h M src/lib/coreboot_table.c 10 files changed, 460 insertions(+), 9 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/20/40520/3
build bot (Jenkins) has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: [RFC]drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 3:
(1 comment)
https://review.coreboot.org/c/coreboot/+/40520/3/src/include/smmstore.h File src/include/smmstore.h:
https://review.coreboot.org/c/coreboot/+/40520/3/src/include/smmstore.h@52 PS3, Line 52: * The Version 2 protocol seperates the SMMSTORE into 64KiB blocks, where each block 'seperates' may be misspelled - perhaps 'separates'?
Patrick Rudolph has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: [RFC]drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 3:
(4 comments)
Rewrote everything to use a fixed communication buffer. The payload must query a coreboot table to get the communication buffer address and use that for all read/write operations.
https://review.coreboot.org/c/coreboot/+/40520/1/src/drivers/smmstore/smi.c File src/drivers/smmstore/smi.c:
https://review.coreboot.org/c/coreboot/+/40520/1/src/drivers/smmstore/smi.c@... PS1, Line 63: case SMMSTORE_CMD_INFO: {
Given that less SMM code is typically better/desirable, would you want to have a Kconfig option for […]
Added a Kconfig as the V1 API allows to write to arbitrary locations in DRAM, while V2 only allows to write to a CBMEM buffer.
https://review.coreboot.org/c/coreboot/+/40520/1/src/drivers/smmstore/store.... File src/drivers/smmstore/store.c:
https://review.coreboot.org/c/coreboot/+/40520/1/src/drivers/smmstore/store.... PS1, Line 270: static struct smmstore_params_info info_params;
Good point, I'll rework that
Done
https://review.coreboot.org/c/coreboot/+/40520/1/src/drivers/smmstore/store.... PS1, Line 272: smmstore_update_info
You probably want to check if the base of the region is 64KiB aligned? Maybe the erase ops of region […]
Done
https://review.coreboot.org/c/coreboot/+/40520/1/src/drivers/smmstore/store.... PS1, Line 304: if (offset >= info_params.block_size || block_id >= info_params.num_blocks) { : printk(BIOS_WARNING, "access out of region requested\n");
Maybe some more fine grained error messages could be useful when debugging things?
Done
Hello Philipp Deppenwiese, build bot (Jenkins), Patrick Georgi, Martin Roth, Matt DeVillier, Jeremy Soller, Christian Walter, Arthur Heymans, Marcello Sylvester Bauer,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/40520
to look at the new patch set (#4).
Change subject: [RFC]drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
[RFC]drivers/smmstore: Implement SMMSTORE version 2
The SMMSTORE version 2 is a complete redesign of the current driver.
Some key features: * Uses a fixed communication buffer instead writing to arbitrary ring0 memory addresses * Gives the caller full control over the used data format * Splits the store into smaller chunks to allow fault tolerant updates * Don't provide feedback about the actual read/written bytes * Return an error if the requested operation would overflow the communication buffer
Seperates the SMMSTORE into 64KiB blocks that can individually be read/written/erased. To be used by payloads that implement a FaultTolerant Variable store like Tianocore.
The implementation has been tested against EDK2 master.
An example EDK2 implementation can be found here: https://github.com/9elements/edk2-1/commit/7c5f0f6bee86dd0a94251b82f0e6f3a10...
Change-Id: I25e49d184135710f3e6dd1ad3bed95de950fe057 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com --- M Documentation/drivers/index.md A Documentation/drivers/smmstorev2.md M payloads/libpayload/include/coreboot_tables.h M src/commonlib/include/commonlib/cbmem_id.h M src/commonlib/include/commonlib/coreboot_tables.h M src/drivers/smmstore/Kconfig M src/drivers/smmstore/Makefile.inc A src/drivers/smmstore/ramstage.c M src/drivers/smmstore/smi.c M src/drivers/smmstore/store.c M src/include/smmstore.h M src/lib/coreboot_table.c 12 files changed, 638 insertions(+), 9 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/20/40520/4
build bot (Jenkins) has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: [RFC]drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 4:
(1 comment)
https://review.coreboot.org/c/coreboot/+/40520/4/src/include/smmstore.h File src/include/smmstore.h:
https://review.coreboot.org/c/coreboot/+/40520/4/src/include/smmstore.h@52 PS4, Line 52: * The Version 2 protocol seperates the SMMSTORE into 64KiB blocks, where each block 'seperates' may be misspelled - perhaps 'separates'?
Hello Philipp Deppenwiese, build bot (Jenkins), Patrick Georgi, Martin Roth, Matt DeVillier, Jeremy Soller, Christian Walter, Arthur Heymans, Marcello Sylvester Bauer,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/40520
to look at the new patch set (#5).
Change subject: [RFC]drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
[RFC]drivers/smmstore: Implement SMMSTORE version 2
The SMMSTORE version 2 is a complete redesign of the current driver.
Some key features: * Uses a fixed communication buffer instead writing to arbitrary ring0 memory addresses * Gives the caller full control over the used data format * Splits the store into smaller chunks to allow fault tolerant updates * Don't provide feedback about the actual read/written bytes * Return an error if the requested operation would overflow the communication buffer
Seperates the SMMSTORE into 64KiB blocks that can individually be read/written/erased. To be used by payloads that implement a FaultTolerant Variable store like Tianocore.
The implementation has been tested against EDK2 master.
An example EDK2 implementation can be found here: https://github.com/9elements/edk2-1/commit/7c5f0f6bee86dd0a94251b82f0e6f3a10...
Change-Id: I25e49d184135710f3e6dd1ad3bed95de950fe057 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com --- M Documentation/drivers/index.md A Documentation/drivers/smmstorev2.md M payloads/libpayload/include/coreboot_tables.h M src/commonlib/include/commonlib/cbmem_id.h M src/commonlib/include/commonlib/coreboot_tables.h M src/drivers/smmstore/Kconfig M src/drivers/smmstore/Makefile.inc A src/drivers/smmstore/ramstage.c M src/drivers/smmstore/smi.c M src/drivers/smmstore/store.c M src/include/smmstore.h M src/lib/coreboot_table.c 12 files changed, 638 insertions(+), 9 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/20/40520/5
build bot (Jenkins) has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: [RFC]drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 5:
(1 comment)
https://review.coreboot.org/c/coreboot/+/40520/5/src/include/smmstore.h File src/include/smmstore.h:
https://review.coreboot.org/c/coreboot/+/40520/5/src/include/smmstore.h@52 PS5, Line 52: * The Version 2 protocol seperates the SMMSTORE into 64KiB blocks, where each block 'seperates' may be misspelled - perhaps 'separates'?
Hello Philipp Deppenwiese, build bot (Jenkins), Patrick Georgi, Martin Roth, Matt DeVillier, Jeremy Soller, Christian Walter, Arthur Heymans, Marcello Sylvester Bauer,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/40520
to look at the new patch set (#6).
Change subject: [RFC]drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
[RFC]drivers/smmstore: Implement SMMSTORE version 2
The SMMSTORE version 2 is a complete redesign of the current driver.
Some key features: * Uses a fixed communication buffer instead writing to arbitrary ring0 memory addresses * Gives the caller full control over the used data format * Splits the store into smaller chunks to allow fault tolerant updates * Don't provide feedback about the actual read/written bytes * Return an error if the requested operation would overflow the communication buffer
Seperates the SMMSTORE into 64KiB blocks that can individually be read/written/erased. To be used by payloads that implement a FaultTolerant Variable store like Tianocore.
The implementation has been tested against EDK2 master.
An example EDK2 implementation can be found here: https://github.com/9elements/edk2-1/commit/7c5f0f6bee86dd0a94251b82f0e6f3a10...
Change-Id: I25e49d184135710f3e6dd1ad3bed95de950fe057 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com --- M Documentation/drivers/index.md A Documentation/drivers/smmstorev2.md M payloads/libpayload/include/coreboot_tables.h M src/commonlib/include/commonlib/cbmem_id.h M src/commonlib/include/commonlib/coreboot_tables.h M src/drivers/smmstore/Kconfig M src/drivers/smmstore/Makefile.inc A src/drivers/smmstore/ramstage.c M src/drivers/smmstore/smi.c M src/drivers/smmstore/store.c M src/include/smmstore.h M src/lib/coreboot_table.c 12 files changed, 656 insertions(+), 9 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/20/40520/6
build bot (Jenkins) has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: [RFC]drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 6:
(1 comment)
https://review.coreboot.org/c/coreboot/+/40520/6/src/include/smmstore.h File src/include/smmstore.h:
https://review.coreboot.org/c/coreboot/+/40520/6/src/include/smmstore.h@52 PS6, Line 52: * The Version 2 protocol seperates the SMMSTORE into 64KiB blocks, where each block 'seperates' may be misspelled - perhaps 'separates'?
Hello Philipp Deppenwiese, build bot (Jenkins), Patrick Georgi, Martin Roth, Matt DeVillier, Jeremy Soller, Christian Walter, Arthur Heymans, Marcello Sylvester Bauer,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/40520
to look at the new patch set (#7).
Change subject: [RFC]drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
[RFC]drivers/smmstore: Implement SMMSTORE version 2
The SMMSTORE version 2 is a complete redesign of the current driver.
Some key features: * Uses a fixed communication buffer instead writing to arbitrary ring0 memory addresses * Gives the caller full control over the used data format * Splits the store into smaller chunks to allow fault tolerant updates * Don't provide feedback about the actual read/written bytes * Return an error if the requested operation would overflow the communication buffer
Seperates the SMMSTORE into 64KiB blocks that can individually be read/written/erased. To be used by payloads that implement a FaultTolerant Variable store like Tianocore.
The implementation has been tested against EDK2 master.
An example EDK2 implementation can be found here: https://github.com/9elements/edk2-1/commit/99e5608b14d52a3354bd441ee8d14194e...
Change-Id: I25e49d184135710f3e6dd1ad3bed95de950fe057 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com --- M Documentation/drivers/index.md A Documentation/drivers/smmstorev2.md M payloads/libpayload/include/coreboot_tables.h M src/commonlib/include/commonlib/cbmem_id.h M src/commonlib/include/commonlib/coreboot_tables.h M src/drivers/smmstore/Kconfig M src/drivers/smmstore/Makefile.inc A src/drivers/smmstore/ramstage.c M src/drivers/smmstore/smi.c M src/drivers/smmstore/store.c M src/include/smmstore.h M src/lib/coreboot_table.c 12 files changed, 656 insertions(+), 9 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/20/40520/7
Arthur Heymans has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: [RFC]drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 6:
(1 comment)
https://review.coreboot.org/c/coreboot/+/40520/6/src/drivers/smmstore/smi.c File src/drivers/smmstore/smi.c:
https://review.coreboot.org/c/coreboot/+/40520/6/src/drivers/smmstore/smi.c@... PS6, Line 154: if (!CONFIG(SMMSTOREV2)) : return smmstorev1_exec(command, param); : else : return smmstorev2_exec(command, param); It should probably be mentioned in the commit message and the documentation they are mutually exclusive.
Matt DeVillier has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: [RFC]drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 7:
(2 comments)
https://review.coreboot.org/c/coreboot/+/40520/7/src/drivers/smmstore/store.... File src/drivers/smmstore/store.c:
https://review.coreboot.org/c/coreboot/+/40520/7/src/drivers/smmstore/store.... PS7, Line 307: BIOS_WARNING warning or error? I assume the latter since we're returning -1
https://review.coreboot.org/c/coreboot/+/40520/7/src/drivers/smmstore/store.... PS7, Line 315: printk(BIOS_ERR, "smm store: lookup of com buffer failed\n"); we should return -1 after this, otherwise function returns 0 and com_buffer is 0 since not initialized
Matt DeVillier has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: [RFC]drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 7:
(1 comment)
https://review.coreboot.org/c/coreboot/+/40520/7/src/drivers/smmstore/ramsta... File src/drivers/smmstore/ramstage.c:
https://review.coreboot.org/c/coreboot/+/40520/7/src/drivers/smmstore/ramsta... PS7, Line 73: BS_DEV_INIT isn't this going to run before SMM is set up, leading init to fail?
Patrick Rudolph has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: [RFC]drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 7:
(3 comments)
https://review.coreboot.org/c/coreboot/+/40520/7/src/drivers/smmstore/ramsta... File src/drivers/smmstore/ramstage.c:
https://review.coreboot.org/c/coreboot/+/40520/7/src/drivers/smmstore/ramsta... PS7, Line 73: BS_DEV_INIT
isn't this going to run before SMM is set up, leading init to fail?
No, SMM is set up in BS_DEV_INIT_CHIPS on Intel.
https://review.coreboot.org/c/coreboot/+/40520/7/src/drivers/smmstore/store.... File src/drivers/smmstore/store.c:
https://review.coreboot.org/c/coreboot/+/40520/7/src/drivers/smmstore/store.... PS7, Line 307: BIOS_WARNING
warning or error? I assume the latter since we're returning -1
Ack
https://review.coreboot.org/c/coreboot/+/40520/7/src/drivers/smmstore/store.... PS7, Line 315: printk(BIOS_ERR, "smm store: lookup of com buffer failed\n");
we should return -1 after this, otherwise function returns 0 and com_buffer is 0 since not initializ […]
If it's called from ramstage that's actually fine, as the caller knows the position and size of the com buffer. I'll guard this with if ENV_RAMSTAGE to make clear when to call it, in contrast to the other functions that should be called in SMM
Matt DeVillier has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: [RFC]drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 7:
(2 comments)
https://review.coreboot.org/c/coreboot/+/40520/7/src/drivers/smmstore/ramsta... File src/drivers/smmstore/ramstage.c:
https://review.coreboot.org/c/coreboot/+/40520/7/src/drivers/smmstore/ramsta... PS7, Line 73: BS_DEV_INIT
No, SMM is set up in BS_DEV_INIT_CHIPS on Intel.
ah, I was testing on an AMD Stoneyridge Chromebook (same one having PCI init issues w/Tiano), and there SMM appears to set up after romstage. Which is why v2 of this patchset works on it, but current does not
https://review.coreboot.org/c/coreboot/+/40520/7/src/drivers/smmstore/store.... File src/drivers/smmstore/store.c:
https://review.coreboot.org/c/coreboot/+/40520/7/src/drivers/smmstore/store.... PS7, Line 315: printk(BIOS_ERR, "smm store: lookup of com buffer failed\n");
If it's called from ramstage that's actually fine, as the caller knows the position and size of the […]
issue is with AMD Stoney not having SMM until after romstage, and thus not having a buffer
Christian Walter has uploaded a new patch set (#8) to the change originally created by Patrick Rudolph. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: [RFC]drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
[RFC]drivers/smmstore: Implement SMMSTORE version 2
The SMMSTORE version 2 is a complete redesign of the current driver.
Some key features: * Uses a fixed communication buffer instead writing to arbitrary ring0 memory addresses * Gives the caller full control over the used data format * Splits the store into smaller chunks to allow fault tolerant updates * Don't provide feedback about the actual read/written bytes * Return an error if the requested operation would overflow the communication buffer
Seperates the SMMSTORE into 64KiB blocks that can individually be read/written/erased. To be used by payloads that implement a FaultTolerant Variable store like Tianocore.
The implementation has been tested against EDK2 master.
An example EDK2 implementation can be found here: https://github.com/9elements/edk2-1/commit/99e5608b14d52a3354bd441ee8d14194e...
Change-Id: I25e49d184135710f3e6dd1ad3bed95de950fe057 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com Signed-off-by: Christian Walter christian.walter@9elements.com --- M Documentation/drivers/index.md A Documentation/drivers/smmstorev2.md M payloads/libpayload/include/coreboot_tables.h M src/commonlib/include/commonlib/cbmem_id.h M src/commonlib/include/commonlib/coreboot_tables.h M src/drivers/smmstore/Kconfig M src/drivers/smmstore/Makefile.inc A src/drivers/smmstore/ramstage.c M src/drivers/smmstore/smi.c M src/drivers/smmstore/store.c M src/include/smmstore.h M src/lib/coreboot_table.c 12 files changed, 656 insertions(+), 9 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/20/40520/8
Christian Walter has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: [RFC]drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 7:
(1 comment)
https://review.coreboot.org/c/coreboot/+/40520/7/src/drivers/smmstore/store.... File src/drivers/smmstore/store.c:
https://review.coreboot.org/c/coreboot/+/40520/7/src/drivers/smmstore/store.... PS7, Line 307: BIOS_WARNING
Ack
Done
build bot (Jenkins) has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: [RFC]drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 8:
(1 comment)
https://review.coreboot.org/c/coreboot/+/40520/8/src/include/smmstore.h File src/include/smmstore.h:
https://review.coreboot.org/c/coreboot/+/40520/8/src/include/smmstore.h@51 PS8, Line 51: * The Version 2 protocol seperates the SMMSTORE into 64KiB blocks, where each block 'seperates' may be misspelled - perhaps 'separates'?
Hello Philipp Deppenwiese, build bot (Jenkins), Patrick Georgi, Martin Roth, Matt DeVillier, Jeremy Soller, Christian Walter, Arthur Heymans, Marcello Sylvester Bauer,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/40520
to look at the new patch set (#9).
Change subject: [RFC]drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
[RFC]drivers/smmstore: Implement SMMSTORE version 2
The SMMSTORE version 2 is a complete redesign of the current driver.
Some key features: * Uses a fixed communication buffer instead writing to arbitrary ring0 memory addresses * Gives the caller full control over the used data format * Splits the store into smaller chunks to allow fault tolerant updates * Don't provide feedback about the actual read/written bytes * Return an error if the requested operation would overflow the communication buffer
Seperates the SMMSTORE into 64KiB blocks that can individually be read/written/erased. To be used by payloads that implement a FaultTolerant Variable store like Tianocore.
The implementation has been tested against EDK2 master.
An example EDK2 implementation can be found here: https://github.com/9elements/edk2-1/commit/99e5608b14d52a3354bd441ee8d14194e...
Change-Id: I25e49d184135710f3e6dd1ad3bed95de950fe057 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com Signed-off-by: Christian Walter christian.walter@9elements.com --- M Documentation/drivers/index.md A Documentation/drivers/smmstorev2.md M payloads/libpayload/include/coreboot_tables.h M src/commonlib/include/commonlib/cbmem_id.h M src/commonlib/include/commonlib/coreboot_tables.h M src/drivers/smmstore/Kconfig M src/drivers/smmstore/Makefile.inc A src/drivers/smmstore/ramstage.c M src/drivers/smmstore/smi.c M src/drivers/smmstore/store.c M src/include/smmstore.h M src/lib/coreboot_table.c 12 files changed, 686 insertions(+), 9 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/20/40520/9
build bot (Jenkins) has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: [RFC]drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 9:
(1 comment)
https://review.coreboot.org/c/coreboot/+/40520/9/src/include/smmstore.h File src/include/smmstore.h:
https://review.coreboot.org/c/coreboot/+/40520/9/src/include/smmstore.h@51 PS9, Line 51: * The Version 2 protocol seperates the SMMSTORE into 64KiB blocks, where each block 'seperates' may be misspelled - perhaps 'separates'?
Hello Philipp Deppenwiese, build bot (Jenkins), Patrick Georgi, Martin Roth, Matt DeVillier, Jeremy Soller, Christian Walter, Arthur Heymans, Marcello Sylvester Bauer,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/40520
to look at the new patch set (#10).
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
drivers/smmstore: Implement SMMSTORE version 2
The SMMSTORE version 2 is a complete redesign of the current driver. Version 2 isn't compatible with version 1 and can't be concurrently used.
Some key features: * Uses a fixed communication buffer instead writing to arbitrary ring0 memory addresses provided by untrusted ring0 code * Gives the caller full control over the used data format * Splits the store into smaller chunks to allow fault tolerant updates * Don't provide feedback about the actual read/written bytes, just return error or success in registers * Return an error if the requested operation would overflow the communication buffer
Seperates the SMMSTORE into 64KiB blocks that can individually be read/written/erased. To be used by payloads that implement a FaultTolerant Variable store like Tianocore.
The implementation has been tested against EDK2 master.
An example EDK2 implementation can be found here: https://github.com/9elements/edk2-1/commit/eb1127744a3a5d5c8ac4e8eb76f07e79c...
Change-Id: I25e49d184135710f3e6dd1ad3bed95de950fe057 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com Signed-off-by: Christian Walter christian.walter@9elements.com --- M Documentation/drivers/index.md A Documentation/drivers/smmstorev2.md M payloads/libpayload/include/coreboot_tables.h M src/commonlib/include/commonlib/cbmem_id.h M src/commonlib/include/commonlib/coreboot_tables.h M src/drivers/smmstore/Kconfig M src/drivers/smmstore/Makefile.inc A src/drivers/smmstore/ramstage.c M src/drivers/smmstore/smi.c M src/drivers/smmstore/store.c M src/include/smmstore.h M src/lib/coreboot_table.c 12 files changed, 690 insertions(+), 5 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/20/40520/10
Arthur Heymans has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 12:
(3 comments)
https://review.coreboot.org/c/coreboot/+/40520/12/Documentation/drivers/smms... File Documentation/drivers/smmstorev2.md:
https://review.coreboot.org/c/coreboot/+/40520/12/Documentation/drivers/smms... PS12, Line 116: INPUT: : - `com_buffer`: Physical address of the communication buffer (CBMEM) : - `com_buffer_size`: Size in bytes of the communication buffer I'm a bit confused by this. The coreboot table seems to provide the same thing but now you need to input this?
https://review.coreboot.org/c/coreboot/+/40520/12/src/drivers/smmstore/Kconf... File src/drivers/smmstore/Kconfig:
https://review.coreboot.org/c/coreboot/+/40520/12/src/drivers/smmstore/Kconf... PS12, Line 9: SMMSTOREV2 Maybe state that this disable v1 / that v2 and v1 are mutually exclusive? That should also be stated in the docs.
https://review.coreboot.org/c/coreboot/+/40520/12/src/drivers/smmstore/store... File src/drivers/smmstore/store.c:
https://review.coreboot.org/c/coreboot/+/40520/12/src/drivers/smmstore/store... PS12, Line 430: rdev_writeat I think the documentation should mention to clear a block before writing again at the same offset?
Patrick Rudolph has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 12:
(3 comments)
https://review.coreboot.org/c/coreboot/+/40520/12/Documentation/drivers/smms... File Documentation/drivers/smmstorev2.md:
https://review.coreboot.org/c/coreboot/+/40520/12/Documentation/drivers/smms... PS12, Line 116: INPUT: : - `com_buffer`: Physical address of the communication buffer (CBMEM) : - `com_buffer_size`: Size in bytes of the communication buffer
I'm a bit confused by this. […]
Added a note that this is called by coreboot and has no effect if called by the payload
https://review.coreboot.org/c/coreboot/+/40520/12/src/drivers/smmstore/Kconf... File src/drivers/smmstore/Kconfig:
https://review.coreboot.org/c/coreboot/+/40520/12/src/drivers/smmstore/Kconf... PS12, Line 9: SMMSTOREV2
Maybe state that this disable v1 / that v2 and v1 are mutually exclusive? That should also be stated […]
Done
https://review.coreboot.org/c/coreboot/+/40520/12/src/drivers/smmstore/store... File src/drivers/smmstore/store.c:
https://review.coreboot.org/c/coreboot/+/40520/12/src/drivers/smmstore/store... PS12, Line 430: rdev_writeat
I think the documentation should mention to clear a block before writing again at the same offset?
That's actually used for fault tolerant updates, where you write the same offset multiple times to clear status bits. Added a note to the documentation.
Hello Philipp Deppenwiese, build bot (Jenkins), Patrick Georgi, Martin Roth, Matt DeVillier, Jeremy Soller, Christian Walter, Arthur Heymans, Marcello Sylvester Bauer,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/40520
to look at the new patch set (#13).
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
drivers/smmstore: Implement SMMSTORE version 2
The SMMSTORE version 2 is a complete redesign of the current driver. Version 2 isn't compatible with version 1 and can't be concurrently used.
Some key features: * Uses a fixed communication buffer instead writing to arbitrary ring0 memory addresses provided by untrusted ring0 code * Gives the caller full control over the used data format * Splits the store into smaller chunks to allow fault tolerant updates * Don't provide feedback about the actual read/written bytes, just return error or success in registers * Return an error if the requested operation would overflow the communication buffer
Seperates the SMMSTORE into 64KiB blocks that can individually be read/written/erased. To be used by payloads that implement a FaultTolerant Variable store like Tianocore.
The implementation has been tested against EDK2 master.
An example EDK2 implementation can be found here: https://github.com/9elements/edk2-1/commit/eb1127744a3a5d5c8ac4e8eb76f07e79c...
Change-Id: I25e49d184135710f3e6dd1ad3bed95de950fe057 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com Signed-off-by: Christian Walter christian.walter@9elements.com --- M Documentation/drivers/index.md A Documentation/drivers/smmstorev2.md M payloads/libpayload/include/coreboot_tables.h M src/commonlib/include/commonlib/cbmem_id.h M src/commonlib/include/commonlib/coreboot_tables.h M src/drivers/smmstore/Kconfig M src/drivers/smmstore/Makefile.inc A src/drivers/smmstore/ramstage.c M src/drivers/smmstore/smi.c M src/drivers/smmstore/store.c M src/include/smmstore.h M src/lib/coreboot_table.c 12 files changed, 696 insertions(+), 5 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/20/40520/13
Hello Philipp Deppenwiese, build bot (Jenkins), Patrick Georgi, Martin Roth, Matt DeVillier, Jeremy Soller, Christian Walter, Arthur Heymans, Marcello Sylvester Bauer,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/40520
to look at the new patch set (#14).
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
drivers/smmstore: Implement SMMSTORE version 2
The SMMSTORE version 2 is a complete redesign of the current driver. Version 2 isn't compatible with version 1 and can't be concurrently used.
Some key features: * Uses a fixed communication buffer instead writing to arbitrary ring0 memory addresses provided by untrusted ring0 code * Gives the caller full control over the used data format * Splits the store into smaller chunks to allow fault tolerant updates * Don't provide feedback about the actual read/written bytes, just return error or success in registers * Return an error if the requested operation would overflow the communication buffer
Seperates the SMMSTORE into 64KiB blocks that can individually be read/written/erased. To be used by payloads that implement a FaultTolerant Variable store like Tianocore.
The implementation has been tested against EDK2 master.
An example EDK2 implementation can be found here: https://github.com/9elements/edk2-1/commit/eb1127744a3a5d5c8ac4e8eb76f07e79c...
Change-Id: I25e49d184135710f3e6dd1ad3bed95de950fe057 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com Signed-off-by: Christian Walter christian.walter@9elements.com --- M Documentation/drivers/index.md A Documentation/drivers/smmstorev2.md M payloads/libpayload/include/coreboot_tables.h M src/commonlib/include/commonlib/cbmem_id.h M src/commonlib/include/commonlib/coreboot_tables.h M src/drivers/smmstore/Kconfig M src/drivers/smmstore/Makefile.inc A src/drivers/smmstore/ramstage.c M src/drivers/smmstore/smi.c M src/drivers/smmstore/store.c M src/include/smmstore.h M src/lib/coreboot_table.c 12 files changed, 692 insertions(+), 5 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/20/40520/14
Patrick Rudolph has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 14:
(4 comments)
https://review.coreboot.org/c/coreboot/+/40520/7/src/drivers/smmstore/ramsta... File src/drivers/smmstore/ramstage.c:
https://review.coreboot.org/c/coreboot/+/40520/7/src/drivers/smmstore/ramsta... PS7, Line 73: BS_DEV_INIT
ah, I was testing on an AMD Stoneyridge Chromebook (same one having PCI init issues w/Tiano), and th […]
This should be fixed in latest revision
https://review.coreboot.org/c/coreboot/+/40520/1/src/drivers/smmstore/smi.c File src/drivers/smmstore/smi.c:
https://review.coreboot.org/c/coreboot/+/40520/1/src/drivers/smmstore/smi.c@... PS1, Line 63: case SMMSTORE_CMD_INFO: {
Added a Kconfig as the V1 API allows to write to arbitrary locations in DRAM, while V2 only allows t […]
Added Kconfig option
https://review.coreboot.org/c/coreboot/+/40520/6/src/drivers/smmstore/smi.c File src/drivers/smmstore/smi.c:
https://review.coreboot.org/c/coreboot/+/40520/6/src/drivers/smmstore/smi.c@... PS6, Line 154: if (!CONFIG(SMMSTOREV2)) : return smmstorev1_exec(command, param); : else : return smmstorev2_exec(command, param);
It should probably be mentioned in the commit message and the documentation they are mutually exclus […]
done
https://review.coreboot.org/c/coreboot/+/40520/7/src/drivers/smmstore/store.... File src/drivers/smmstore/store.c:
https://review.coreboot.org/c/coreboot/+/40520/7/src/drivers/smmstore/store.... PS7, Line 315: printk(BIOS_ERR, "smm store: lookup of com buffer failed\n");
issue is with AMD Stoney not having SMM until after romstage, and thus not having a buffer
That should be fixed in latest version
Matt DeVillier has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 14: Code-Review+1
I've tested this across a wide range of platforms and seems sane; any issues I've encountered have been on the edk2 side (and have left some comments on github there)
Matt DeVillier has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 14:
(1 comment)
https://review.coreboot.org/c/coreboot/+/40520/14/src/commonlib/include/comm... File src/commonlib/include/commonlib/coreboot_tables.h:
https://review.coreboot.org/c/coreboot/+/40520/14/src/commonlib/include/comm... PS14, Line 82: LB_TAG_SMMSTOREV2 = 0x0038, this will need to be adjusted via a rebase, since LB_TAG_PLATFORM_BLOB_VERSION is now 0x038
Duncan Laurie has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 14:
(4 comments)
https://review.coreboot.org/c/coreboot/+/40520/14/src/drivers/smmstore/ramst... File src/drivers/smmstore/ramstage.c:
https://review.coreboot.org/c/coreboot/+/40520/14/src/drivers/smmstore/ramst... PS14, Line 63: 0xb2 could use APM_CNT here but you'd have to pass another register like edx.
https://review.coreboot.org/c/coreboot/+/40520/14/src/drivers/smmstore/smi.c File src/drivers/smmstore/smi.c:
https://review.coreboot.org/c/coreboot/+/40520/14/src/drivers/smmstore/smi.c... PS14, Line 144: param the eventual range_check() seems like it will implicitly catch null pointers, but it might be clearer if there was a check at the start since the handlers seem to pass raw EBX values.
https://review.coreboot.org/c/coreboot/+/40520/14/src/drivers/smmstore/store... File src/drivers/smmstore/store.c:
https://review.coreboot.org/c/coreboot/+/40520/14/src/drivers/smmstore/store... PS14, Line 450: // NOTE: Not really necessarry.. agreed, none of the other functions check this so either they all should or none.
https://review.coreboot.org/c/coreboot/+/40520/14/src/include/smmstore.h File src/include/smmstore.h:
https://review.coreboot.org/c/coreboot/+/40520/14/src/include/smmstore.h@39 PS14, Line 39: SMMSTORE of at least 256KiB of size maybe add a compile time check of CONFIG_SMMSTORE_SIZE if CONFIG_SMMSTOREV2 is enabled.
Tim Wawrzynczak has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 14:
(13 comments)
https://review.coreboot.org/c/coreboot/+/40520/14/Documentation/drivers/smms... File Documentation/drivers/smmstorev2.md:
https://review.coreboot.org/c/coreboot/+/40520/14/Documentation/drivers/smms... PS14, Line 17: unformated unformatted
https://review.coreboot.org/c/coreboot/+/40520/14/Documentation/drivers/smms... PS14, Line 34: used used,
https://review.coreboot.org/c/coreboot/+/40520/14/Documentation/drivers/smms... PS14, Line 68: assuptions assumptions
https://review.coreboot.org/c/coreboot/+/40520/14/Documentation/drivers/smms... PS14, Line 82: on in
https://review.coreboot.org/c/coreboot/+/40520/14/Documentation/drivers/smms... PS14, Line 123: to write writing
https://review.coreboot.org/c/coreboot/+/40520/14/Documentation/drivers/smms... PS14, Line 124: meanful meaningful
https://review.coreboot.org/c/coreboot/+/40520/14/Documentation/drivers/smms... PS14, Line 144: to write writing
https://review.coreboot.org/c/coreboot/+/40520/14/Documentation/drivers/smms... PS14, Line 165: to clear clearing
https://review.coreboot.org/c/coreboot/+/40520/14/src/drivers/smmstore/store... File src/drivers/smmstore/store.c:
https://review.coreboot.org/c/coreboot/+/40520/14/src/drivers/smmstore/store... PS14, Line 282: ASPM APM
https://review.coreboot.org/c/coreboot/+/40520/14/src/drivers/smmstore/store... PS14, Line 416: if (offset >= region_device_sz(&com_buf)) { nit: blank line after if
https://review.coreboot.org/c/coreboot/+/40520/14/src/drivers/smmstore/store... PS14, Line 425: ptr = rdev_mmap(&com_buf, offset, bufsize); nit: blank line after if
https://review.coreboot.org/c/coreboot/+/40520/14/src/drivers/smmstore/store... PS14, Line 430: ret = rdev_writeat(&store, ptr, 0, bufsize); nit: blank line after if
https://review.coreboot.org/c/coreboot/+/40520/14/src/drivers/smmstore/store... PS14, Line 450: // NOTE: Not really necessarry..
agreed, none of the other functions check this so either they all should or none.
I think it's okay to be a little extra paranoid in SMM. Maybe all of the exported functions should check for store_initialized?
Angel Pons has uploaded a new patch set (#15) to the change originally created by Patrick Rudolph. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
drivers/smmstore: Implement SMMSTORE version 2
SMMSTORE version 2 is a complete redesign of the current driver. It is not backwards-compatible with version 1, and only one version can be used at a time.
Key features: * Use a fixed communication buffer instead of writing to arbitrary memory addresses provided by untrusted ring0 code. * Give the caller full control over the used data format. * Split the store into smaller chunks to allow fault tolerant updates. * Don't provide feedback about the actual read/written bytes, just return error or success in registers. * Return an error if the requested operation would overflow the communication buffer.
Separate the SMMSTORE into 64KiB blocks that can individually be read/written/erased. To be used by payloads that implement a FaultTolerant Variable store like TianoCore.
The implementation has been tested against EDK2 master.
An example EDK2 implementation can be found here: https://github.com/9elements/edk2-1/commit/eb1127744a3a5d5c8ac4e8eb76f07e79c...
Change-Id: I25e49d184135710f3e6dd1ad3bed95de950fe057 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com Signed-off-by: Christian Walter christian.walter@9elements.com --- M Documentation/drivers/index.md A Documentation/drivers/smmstorev2.md M payloads/libpayload/include/coreboot_tables.h M src/commonlib/include/commonlib/cbmem_id.h M src/commonlib/include/commonlib/coreboot_tables.h M src/drivers/smmstore/Kconfig M src/drivers/smmstore/Makefile.inc A src/drivers/smmstore/ramstage.c M src/drivers/smmstore/smi.c M src/drivers/smmstore/store.c M src/include/smmstore.h M src/lib/coreboot_table.c 12 files changed, 721 insertions(+), 5 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/20/40520/15
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 15:
(15 comments)
https://review.coreboot.org/c/coreboot/+/40520/14/Documentation/drivers/smms... File Documentation/drivers/smmstorev2.md:
https://review.coreboot.org/c/coreboot/+/40520/14/Documentation/drivers/smms... PS14, Line 17: unformated
unformatted
Done
https://review.coreboot.org/c/coreboot/+/40520/14/Documentation/drivers/smms... PS14, Line 34: used
used,
Done
https://review.coreboot.org/c/coreboot/+/40520/14/Documentation/drivers/smms... PS14, Line 68: assuptions
assumptions
Done
https://review.coreboot.org/c/coreboot/+/40520/14/Documentation/drivers/smms... PS14, Line 82: on
in
Done
https://review.coreboot.org/c/coreboot/+/40520/14/Documentation/drivers/smms... PS14, Line 123: to write
writing
reading, but done
https://review.coreboot.org/c/coreboot/+/40520/14/Documentation/drivers/smms... PS14, Line 124: meanful
meaningful
Done
https://review.coreboot.org/c/coreboot/+/40520/14/Documentation/drivers/smms... PS14, Line 144: to write
writing
Done
https://review.coreboot.org/c/coreboot/+/40520/14/Documentation/drivers/smms... PS14, Line 165: to clear
clearing
Done
https://review.coreboot.org/c/coreboot/+/40520/14/src/commonlib/include/comm... File src/commonlib/include/commonlib/coreboot_tables.h:
https://review.coreboot.org/c/coreboot/+/40520/14/src/commonlib/include/comm... PS14, Line 82: LB_TAG_SMMSTOREV2 = 0x0038,
this will need to be adjusted via a rebase, since LB_TAG_PLATFORM_BLOB_VERSION is now 0x038
Done
https://review.coreboot.org/c/coreboot/+/40520/14/src/drivers/smmstore/smi.c File src/drivers/smmstore/smi.c:
https://review.coreboot.org/c/coreboot/+/40520/14/src/drivers/smmstore/smi.c... PS14, Line 144: param
the eventual range_check() seems like it will implicitly catch null pointers, but it might be cleare […]
Done
https://review.coreboot.org/c/coreboot/+/40520/14/src/drivers/smmstore/store... File src/drivers/smmstore/store.c:
https://review.coreboot.org/c/coreboot/+/40520/14/src/drivers/smmstore/store... PS14, Line 282: ASPM
APM
Done
https://review.coreboot.org/c/coreboot/+/40520/14/src/drivers/smmstore/store... PS14, Line 416: if (offset >= region_device_sz(&com_buf)) {
nit: blank line after if
Done
https://review.coreboot.org/c/coreboot/+/40520/14/src/drivers/smmstore/store... PS14, Line 425: ptr = rdev_mmap(&com_buf, offset, bufsize);
nit: blank line after if
Done
https://review.coreboot.org/c/coreboot/+/40520/14/src/drivers/smmstore/store... PS14, Line 430: ret = rdev_writeat(&store, ptr, 0, bufsize);
nit: blank line after if
Done
https://review.coreboot.org/c/coreboot/+/40520/14/src/drivers/smmstore/store... PS14, Line 450: // NOTE: Not really necessarry..
I think it's okay to be a little extra paranoid in SMM. […]
I added this check to all four functions.
Matt DeVillier has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 15:
tested along with CB:41086, and not currently working on CML. Looks like the ramstage setup is failing, but need to debug a bit further:
smm store: No com buffer installed yet SMMSTORE: Failed to get meta data
...
BlSMMSTOREInitialise a: Failed to initialize SMMStore
Angel Pons has uploaded a new patch set (#16) to the change originally created by Patrick Rudolph. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
drivers/smmstore: Implement SMMSTORE version 2
SMMSTORE version 2 is a complete redesign of the current driver. It is not backwards-compatible with version 1, and only one version can be used at a time.
Key features: * Use a fixed communication buffer instead of writing to arbitrary memory addresses provided by untrusted ring0 code. * Give the caller full control over the used data format. * Split the store into smaller chunks to allow fault tolerant updates. * Don't provide feedback about the actual read/written bytes, just return error or success in registers. * Return an error if the requested operation would overflow the communication buffer.
Separate the SMMSTORE into 64KiB blocks that can individually be read/written/erased. To be used by payloads that implement a FaultTolerant Variable store like TianoCore.
The implementation has been tested against EDK2 master.
An example EDK2 implementation can be found here: https://github.com/9elements/edk2-1/commit/eb1127744a3a5d5c8ac4e8eb76f07e79c...
Change-Id: I25e49d184135710f3e6dd1ad3bed95de950fe057 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com Signed-off-by: Christian Walter christian.walter@9elements.com --- M Documentation/drivers/index.md A Documentation/drivers/smmstorev2.md M payloads/libpayload/include/coreboot_tables.h M src/commonlib/include/commonlib/cbmem_id.h M src/commonlib/include/commonlib/coreboot_tables.h M src/drivers/smmstore/Kconfig M src/drivers/smmstore/Makefile.inc A src/drivers/smmstore/ramstage.c M src/drivers/smmstore/smi.c M src/drivers/smmstore/store.c M src/include/smmstore.h M src/lib/coreboot_table.c 12 files changed, 715 insertions(+), 5 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/20/40520/16
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 16:
Patch Set 15:
tested along with CB:41086, and not currently working on CML. Looks like the ramstage setup is failing, but need to debug a bit further:
smm store: No com buffer installed yet SMMSTORE: Failed to get meta data
...
BlSMMSTOREInitialise a: Failed to initialize SMMStore
Please try again. I added some checks, but one of them is wrong.
Patrick Rudolph has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 16:
(1 comment)
https://review.coreboot.org/c/coreboot/+/40520/16/src/drivers/smmstore/store... File src/drivers/smmstore/store.c:
https://review.coreboot.org/c/coreboot/+/40520/16/src/drivers/smmstore/store... PS16, Line 350: if (!store_initialized) { that's also checked in smmstore_rdev_chain
Angel Pons has uploaded a new patch set (#17) to the change originally created by Patrick Rudolph. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
drivers/smmstore: Implement SMMSTORE version 2
SMMSTORE version 2 is a complete redesign of the current driver. It is not backwards-compatible with version 1, and only one version can be used at a time.
Key features: * Use a fixed communication buffer instead of writing to arbitrary memory addresses provided by untrusted ring0 code. * Give the caller full control over the used data format. * Split the store into smaller chunks to allow fault tolerant updates. * Don't provide feedback about the actual read/written bytes, just return error or success in registers. * Return an error if the requested operation would overflow the communication buffer.
Separate the SMMSTORE into 64KiB blocks that can individually be read/written/erased. To be used by payloads that implement a FaultTolerant Variable store like TianoCore.
The implementation has been tested against EDK2 master.
An example EDK2 implementation can be found here: https://github.com/9elements/edk2-1/commit/eb1127744a3a5d5c8ac4e8eb76f07e79c...
Change-Id: I25e49d184135710f3e6dd1ad3bed95de950fe057 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com Signed-off-by: Christian Walter christian.walter@9elements.com --- M Documentation/drivers/index.md A Documentation/drivers/smmstorev2.md M payloads/libpayload/include/coreboot_tables.h M src/commonlib/include/commonlib/cbmem_id.h M src/commonlib/include/commonlib/coreboot_tables.h M src/drivers/smmstore/Kconfig M src/drivers/smmstore/Makefile.inc A src/drivers/smmstore/ramstage.c M src/drivers/smmstore/smi.c M src/drivers/smmstore/store.c M src/include/smmstore.h M src/lib/coreboot_table.c 12 files changed, 697 insertions(+), 5 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/20/40520/17
Tim Wawrzynczak has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 16:
(4 comments)
https://review.coreboot.org/c/coreboot/+/40520/16/src/commonlib/include/comm... File src/commonlib/include/commonlib/coreboot_tables.h:
https://review.coreboot.org/c/coreboot/+/40520/16/src/commonlib/include/comm... PS16, Line 504: byte bytes
https://review.coreboot.org/c/coreboot/+/40520/16/src/commonlib/include/comm... PS16, Line 500: uint32_t num_blocks; /* Number of writeable blocks in SMM */ : uint32_t block_size; /* Size of a block in byte. Default: 64 KiB */ : uint32_t mmap_addr; /* MMIO address of the store for read only access */ : uint32_t com_buffer; /* Physical address of the communication buffer */ : uint32_t com_buffer_size; /* Size of the communication buffer in byte */ : uint8_t apm_cmd; /* The command byte to write to the APM I/O port */ : uint8_t unused[3]; /* Set to zero */ nit: line up the comments
https://review.coreboot.org/c/coreboot/+/40520/16/src/drivers/smmstore/ramst... File src/drivers/smmstore/ramstage.c:
https://review.coreboot.org/c/coreboot/+/40520/16/src/drivers/smmstore/ramst... PS16, Line 62: $0xb2 APM_CNT ?
https://review.coreboot.org/c/coreboot/+/40520/16/src/drivers/smmstore/store... File src/drivers/smmstore/store.c:
https://review.coreboot.org/c/coreboot/+/40520/16/src/drivers/smmstore/store... PS16, Line 469: /* Better safe than sorry */ : if (!store_initialized) { : printk(BIOS_ERR, "smm store: No com buffer installed yet\n"); : return -1; : } : : if (lookup_store(&store) < 0) { : printk(BIOS_ERR, "smm store: lookup failed\n"); : return -1; : } : : if ((block_id * SMM_BLOCK_SIZE) >= region_device_sz(&store)) { : printk(BIOS_ERR, "smm store: block ID out of range\n"); : return -1; : } this is repeated 3 times, consider refactoring
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 17:
(2 comments)
https://review.coreboot.org/c/coreboot/+/40520/14/src/drivers/smmstore/store... File src/drivers/smmstore/store.c:
https://review.coreboot.org/c/coreboot/+/40520/14/src/drivers/smmstore/store... PS14, Line 450: // NOTE: Not really necessarry..
I added this check to all four functions.
Actually, the checks are in smmstore_rdev_chain. This function doesn't use the com buffer, so it doesn't really matter.
https://review.coreboot.org/c/coreboot/+/40520/16/src/drivers/smmstore/store... File src/drivers/smmstore/store.c:
https://review.coreboot.org/c/coreboot/+/40520/16/src/drivers/smmstore/store... PS16, Line 350: if (!store_initialized) {
that's also checked in smmstore_rdev_chain
Done
Tim Wawrzynczak has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 17:
(1 comment)
https://review.coreboot.org/c/coreboot/+/40520/14/src/drivers/smmstore/store... File src/drivers/smmstore/store.c:
https://review.coreboot.org/c/coreboot/+/40520/14/src/drivers/smmstore/store... PS14, Line 450: // NOTE: Not really necessarry..
Actually, the checks are in smmstore_rdev_chain. […]
That's fair, store_initialized means mdev_com_buf is initialized.
Benjamin Doron has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 17:
(1 comment)
https://review.coreboot.org/c/coreboot/+/40520/17/src/drivers/smmstore/Kconf... File src/drivers/smmstore/Kconfig:
https://review.coreboot.org/c/coreboot/+/40520/17/src/drivers/smmstore/Kconf... PS17, Line 15: asumptions of the data structure stored in the store Perhaps: "assumptions on the structure of the data stored within?"
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 17:
(1 comment)
https://review.coreboot.org/c/coreboot/+/40520/17/src/drivers/smmstore/Kconf... File src/drivers/smmstore/Kconfig:
https://review.coreboot.org/c/coreboot/+/40520/17/src/drivers/smmstore/Kconf... PS17, Line 15: asumptions of the data structure stored in the store
Perhaps: "assumptions on the structure of the data stored within?"
Maybe. I just realized there's a typo, so I've got to fix it anyway 😄
Angel Pons has uploaded a new patch set (#18) to the change originally created by Patrick Rudolph. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
drivers/smmstore: Implement SMMSTORE version 2
SMMSTORE version 2 is a complete redesign of the current driver. It is not backwards-compatible with version 1, and only one version can be used at a time.
Key features: * Use a fixed communication buffer instead of writing to arbitrary memory addresses provided by untrusted ring0 code. * Give the caller full control over the used data format. * Split the store into smaller chunks to allow fault tolerant updates. * Don't provide feedback about the actual read/written bytes, just return error or success in registers. * Return an error if the requested operation would overflow the communication buffer.
Separate the SMMSTORE into 64KiB blocks that can individually be read/written/erased. To be used by payloads that implement a FaultTolerant Variable store like TianoCore.
The implementation has been tested against EDK2 master.
An example EDK2 implementation can be found here: https://github.com/9elements/edk2-1/commit/eb1127744a3a5d5c8ac4e8eb76f07e79c...
Change-Id: I25e49d184135710f3e6dd1ad3bed95de950fe057 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com Signed-off-by: Christian Walter christian.walter@9elements.com --- M Documentation/drivers/index.md A Documentation/drivers/smmstorev2.md M payloads/libpayload/include/coreboot_tables.h M src/commonlib/include/commonlib/cbmem_id.h M src/commonlib/include/commonlib/coreboot_tables.h M src/drivers/smmstore/Kconfig M src/drivers/smmstore/Makefile.inc A src/drivers/smmstore/ramstage.c M src/drivers/smmstore/smi.c M src/drivers/smmstore/store.c M src/include/smmstore.h M src/lib/coreboot_table.c 12 files changed, 697 insertions(+), 5 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/20/40520/18
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 19:
(1 comment)
https://review.coreboot.org/c/coreboot/+/40520/17/src/drivers/smmstore/Kconf... File src/drivers/smmstore/Kconfig:
https://review.coreboot.org/c/coreboot/+/40520/17/src/drivers/smmstore/Kconf... PS17, Line 15: asumptions of the data structure stored in the store
Maybe. […]
Done
Tim Wawrzynczak has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 19: Code-Review+1
Angel Pons has uploaded a new patch set (#20) to the change originally created by Patrick Rudolph. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
drivers/smmstore: Implement SMMSTORE version 2
SMMSTORE version 2 is a complete redesign of the current driver. It is not backwards-compatible with version 1, and only one version can be used at a time.
Key features: * Uses a fixed communication buffer instead of writing to arbitrary memory addresses provided by untrusted ring0 code. * Gives the caller full control over the used data format. * Splits the store into smaller chunks to allow fault tolerant updates. * Doesn't provide feedback about the actual read/written bytes, just returns error or success in registers. * Returns an error if the requested operation would overflow the communication buffer.
Separate the SMMSTORE into 64 KiB blocks that can individually be read/written/erased. To be used by payloads that implement a FaultTolerant Variable store like TianoCore.
The implementation has been tested against EDK2 master.
An example EDK2 implementation can be found here: https://github.com/9elements/edk2-1/commit/eb1127744a3a5d5c8ac4e8eb76f07e79c...
Change-Id: I25e49d184135710f3e6dd1ad3bed95de950fe057 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com Signed-off-by: Christian Walter christian.walter@9elements.com --- M Documentation/drivers/index.md A Documentation/drivers/smmstorev2.md M payloads/libpayload/include/coreboot_tables.h M src/commonlib/include/commonlib/cbmem_id.h M src/commonlib/include/commonlib/coreboot_tables.h M src/drivers/smmstore/Kconfig M src/drivers/smmstore/Makefile.inc A src/drivers/smmstore/ramstage.c M src/drivers/smmstore/smi.c M src/drivers/smmstore/store.c M src/include/smmstore.h M src/lib/coreboot_table.c 12 files changed, 702 insertions(+), 8 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/20/40520/20
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 19:
(1 comment)
https://review.coreboot.org/c/coreboot/+/40520/1/src/include/smmstore.h File src/include/smmstore.h:
https://review.coreboot.org/c/coreboot/+/40520/1/src/include/smmstore.h@40 PS1, Line 40: * Version 2 of the SMM requires as SMMSTORE of at least 256KiB of size, that : * has to be aligned to 64KiB. : * This allows the payload to store raw data in the SMMSTORE flash region. : * This can be used by a FaultTolerantWrite implementation, that uses at least : * two regions in an A/B update scheme.
64KiB is the minimum for UEFI variable store + 64KiB as FaultTolerantWrite backup. […]
Expanded the comment.
Patrick Rudolph has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 19:
(1 comment)
https://review.coreboot.org/c/coreboot/+/40520/1/src/include/smmstore.h File src/include/smmstore.h:
https://review.coreboot.org/c/coreboot/+/40520/1/src/include/smmstore.h@40 PS1, Line 40: * Version 2 of the SMM requires as SMMSTORE of at least 256KiB of size, that : * has to be aligned to 64KiB. : * This allows the payload to store raw data in the SMMSTORE flash region. : * This can be used by a FaultTolerantWrite implementation, that uses at least : * two regions in an A/B update scheme.
64KiB is the minimum for UEFI variable store + 64KiB as FaultTolerantWrite backup. […]
There are usually 3 regions used by EDK. * The variable store * The FTW spare block * The FTW working block
All regions must be block aligned. The FTW Spare size must be greater than the variable store. In this case 64KiB + 1 block. The FTW Working Size can be much smaller than 64KiB.
That sums up to: * The variable store: 1block = 64KiB * The FTW spare block: 2blocks = 2x64KiB * The FTW working block: 1block = 64KiB In total 256KiB that's required when using 64KiB block size and EDK2 variable store.
Angel Pons has uploaded a new patch set (#21) to the change originally created by Patrick Rudolph. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
drivers/smmstore: Implement SMMSTORE version 2
SMMSTORE version 2 is a complete redesign of the current driver. It is not backwards-compatible with version 1, and only one version can be used at a time.
Key features: * Uses a fixed communication buffer instead of writing to arbitrary memory addresses provided by untrusted ring0 code. * Gives the caller full control over the used data format. * Splits the store into smaller chunks to allow fault tolerant updates. * Doesn't provide feedback about the actual read/written bytes, just returns error or success in registers. * Returns an error if the requested operation would overflow the communication buffer.
Separate the SMMSTORE into 64 KiB blocks that can individually be read/written/erased. To be used by payloads that implement a FaultTolerant Variable store like TianoCore.
The implementation has been tested against EDK2 master.
An example EDK2 implementation can be found here: https://github.com/9elements/edk2-1/commit/eb1127744a3a5d5c8ac4e8eb76f07e79c...
Change-Id: I25e49d184135710f3e6dd1ad3bed95de950fe057 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com Signed-off-by: Christian Walter christian.walter@9elements.com --- M Documentation/drivers/index.md A Documentation/drivers/smmstorev2.md M payloads/libpayload/include/coreboot_tables.h M src/commonlib/include/commonlib/cbmem_id.h M src/commonlib/include/commonlib/coreboot_tables.h M src/drivers/smmstore/Kconfig M src/drivers/smmstore/Makefile.inc A src/drivers/smmstore/ramstage.c M src/drivers/smmstore/smi.c M src/drivers/smmstore/store.c M src/include/smmstore.h M src/lib/coreboot_table.c 12 files changed, 705 insertions(+), 8 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/20/40520/21
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 20:
(7 comments)
https://review.coreboot.org/c/coreboot/+/40520/16/src/commonlib/include/comm... File src/commonlib/include/commonlib/coreboot_tables.h:
https://review.coreboot.org/c/coreboot/+/40520/16/src/commonlib/include/comm... PS16, Line 504: byte
bytes
Done
https://review.coreboot.org/c/coreboot/+/40520/16/src/commonlib/include/comm... PS16, Line 500: uint32_t num_blocks; /* Number of writeable blocks in SMM */ : uint32_t block_size; /* Size of a block in byte. Default: 64 KiB */ : uint32_t mmap_addr; /* MMIO address of the store for read only access */ : uint32_t com_buffer; /* Physical address of the communication buffer */ : uint32_t com_buffer_size; /* Size of the communication buffer in byte */ : uint8_t apm_cmd; /* The command byte to write to the APM I/O port */ : uint8_t unused[3]; /* Set to zero */
nit: line up the comments
Done
https://review.coreboot.org/c/coreboot/+/40520/14/src/drivers/smmstore/ramst... File src/drivers/smmstore/ramstage.c:
https://review.coreboot.org/c/coreboot/+/40520/14/src/drivers/smmstore/ramst... PS14, Line 63: 0xb2
could use APM_CNT here but you'd have to pass another register like edx.
Done
https://review.coreboot.org/c/coreboot/+/40520/16/src/drivers/smmstore/ramst... File src/drivers/smmstore/ramstage.c:
https://review.coreboot.org/c/coreboot/+/40520/16/src/drivers/smmstore/ramst... PS16, Line 62: $0xb2
APM_CNT ?
Done
https://review.coreboot.org/c/coreboot/+/40520/16/src/drivers/smmstore/store... File src/drivers/smmstore/store.c:
https://review.coreboot.org/c/coreboot/+/40520/16/src/drivers/smmstore/store... PS16, Line 469: /* Better safe than sorry */ : if (!store_initialized) { : printk(BIOS_ERR, "smm store: No com buffer installed yet\n"); : return -1; : } : : if (lookup_store(&store) < 0) { : printk(BIOS_ERR, "smm store: lookup failed\n"); : return -1; : } : : if ((block_id * SMM_BLOCK_SIZE) >= region_device_sz(&store)) { : printk(BIOS_ERR, "smm store: block ID out of range\n"); : return -1; : }
this is repeated 3 times, consider refactoring
Done
https://review.coreboot.org/c/coreboot/+/40520/14/src/include/smmstore.h File src/include/smmstore.h:
https://review.coreboot.org/c/coreboot/+/40520/14/src/include/smmstore.h@39 PS14, Line 39: SMMSTORE of at least 256KiB of size
maybe add a compile time check of CONFIG_SMMSTORE_SIZE if CONFIG_SMMSTOREV2 is enabled.
This requirement only applies when using SMMSTOREv2 with EDK2 FaultTolerantWrite. See comment on PS1.
Turned most of the comment into documentation, and clarified this part.
https://review.coreboot.org/c/coreboot/+/40520/1/src/include/smmstore.h File src/include/smmstore.h:
https://review.coreboot.org/c/coreboot/+/40520/1/src/include/smmstore.h@40 PS1, Line 40: * Version 2 of the SMM requires as SMMSTORE of at least 256KiB of size, that : * has to be aligned to 64KiB. : * This allows the payload to store raw data in the SMMSTORE flash region. : * This can be used by a FaultTolerantWrite implementation, that uses at least : * two regions in an A/B update scheme.
There are usually 3 regions used by EDK. […]
Thank you for the explanation. I've turned the ever-growing comment into documentation.
Matt DeVillier has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 21:
(4 comments)
https://review.coreboot.org/c/coreboot/+/40520/21/Documentation/drivers/smms... File Documentation/drivers/smmstorev2.md:
https://review.coreboot.org/c/coreboot/+/40520/21/Documentation/drivers/smms... PS21, Line 1: # SMM based flash storage driver Version 2 really outstanding job here
https://review.coreboot.org/c/coreboot/+/40520/21/src/drivers/smmstore/Kconf... File src/drivers/smmstore/Kconfig:
https://review.coreboot.org/c/coreboot/+/40520/21/src/drivers/smmstore/Kconf... PS21, Line 12: default y if PAYLOAD_TIANOCORE I feel that Y isn't the best default at the present time, since neither the default Tianocore package (my fork of CorebootPayloadPkg), nor upstream edk2 (the default for UefipayloadPkg) currently support it. And 9elements' current sample implementation fails to boot on older platforms. We should default to N until there is a reasonably-well working implementation that is selectable via Tianocore's Kconfig, and probably add 'depends on !TIANOCORE_COREBOOTPAYLOAD' as well to be safe
https://review.coreboot.org/c/coreboot/+/40520/21/src/drivers/smmstore/smi.c File src/drivers/smmstore/smi.c:
https://review.coreboot.org/c/coreboot/+/40520/21/src/drivers/smmstore/smi.c... PS21, Line 144: usually usually? are there conditions under which these are not true?
https://review.coreboot.org/c/coreboot/+/40520/21/src/include/smmstore.h File src/include/smmstore.h:
https://review.coreboot.org/c/coreboot/+/40520/21/src/include/smmstore.h@43 PS21, Line 43: * FIXME: The data format isn't specified. is this needed?
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 21:
(4 comments)
https://review.coreboot.org/c/coreboot/+/40520/21/Documentation/drivers/smms... File Documentation/drivers/smmstorev2.md:
https://review.coreboot.org/c/coreboot/+/40520/21/Documentation/drivers/smms... PS21, Line 1: # SMM based flash storage driver Version 2
really outstanding job here
Thank you. I imagine this comment was meant to be resolved? (it was not)
https://review.coreboot.org/c/coreboot/+/40520/21/src/drivers/smmstore/Kconf... File src/drivers/smmstore/Kconfig:
https://review.coreboot.org/c/coreboot/+/40520/21/src/drivers/smmstore/Kconf... PS21, Line 12: default y if PAYLOAD_TIANOCORE
I feel that Y isn't the best default at the present time, since neither the default Tianocore packag […]
Good point. I'll change the default to n for now.
https://review.coreboot.org/c/coreboot/+/40520/21/src/drivers/smmstore/smi.c File src/drivers/smmstore/smi.c:
https://review.coreboot.org/c/coreboot/+/40520/21/src/drivers/smmstore/smi.c... PS21, Line 144: usually
usually? are there conditions under which these are not true?
That comment was already in the existing code. I think it can be dropped.
https://review.coreboot.org/c/coreboot/+/40520/21/src/include/smmstore.h File src/include/smmstore.h:
https://review.coreboot.org/c/coreboot/+/40520/21/src/include/smmstore.h@43 PS21, Line 43: * FIXME: The data format isn't specified.
is this needed?
I'm not sure. I think not. Patrick Rudolph, happen to know if this is needed?
Angel Pons has uploaded a new patch set (#22) to the change originally created by Patrick Rudolph. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
drivers/smmstore: Implement SMMSTORE version 2
SMMSTORE version 2 is a complete redesign of the current driver. It is not backwards-compatible with version 1, and only one version can be used at a time.
Key features: * Uses a fixed communication buffer instead of writing to arbitrary memory addresses provided by untrusted ring0 code. * Gives the caller full control over the used data format. * Splits the store into smaller chunks to allow fault tolerant updates. * Doesn't provide feedback about the actual read/written bytes, just returns error or success in registers. * Returns an error if the requested operation would overflow the communication buffer.
Separate the SMMSTORE into 64 KiB blocks that can individually be read/written/erased. To be used by payloads that implement a FaultTolerant Variable store like TianoCore.
The implementation has been tested against EDK2 master.
An example EDK2 implementation can be found here: https://github.com/9elements/edk2-1/commit/eb1127744a3a5d5c8ac4e8eb76f07e79c...
Change-Id: I25e49d184135710f3e6dd1ad3bed95de950fe057 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com Signed-off-by: Christian Walter christian.walter@9elements.com --- M Documentation/drivers/index.md A Documentation/drivers/smmstorev2.md M payloads/libpayload/include/coreboot_tables.h M src/commonlib/include/commonlib/cbmem_id.h M src/commonlib/include/commonlib/coreboot_tables.h M src/drivers/smmstore/Kconfig M src/drivers/smmstore/Makefile.inc A src/drivers/smmstore/ramstage.c M src/drivers/smmstore/smi.c M src/drivers/smmstore/store.c M src/include/smmstore.h M src/lib/coreboot_table.c 12 files changed, 704 insertions(+), 8 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/20/40520/22
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 22:
(3 comments)
https://review.coreboot.org/c/coreboot/+/40520/21/src/drivers/smmstore/Kconf... File src/drivers/smmstore/Kconfig:
https://review.coreboot.org/c/coreboot/+/40520/21/src/drivers/smmstore/Kconf... PS21, Line 12: default y if PAYLOAD_TIANOCORE
Good point. I'll change the default to n for now.
Done
https://review.coreboot.org/c/coreboot/+/40520/21/src/drivers/smmstore/smi.c File src/drivers/smmstore/smi.c:
https://review.coreboot.org/c/coreboot/+/40520/21/src/drivers/smmstore/smi.c... PS21, Line 144: usually
That comment was already in the existing code. I think it can be dropped.
Done
https://review.coreboot.org/c/coreboot/+/40520/21/src/include/smmstore.h File src/include/smmstore.h:
https://review.coreboot.org/c/coreboot/+/40520/21/src/include/smmstore.h@43 PS21, Line 43: * FIXME: The data format isn't specified.
I'm not sure. I think not. […]
This refers to the data stored within the blocks. The data format shouldn't need to be specified, as this would work like a block device.
I messaged Patrick about it, but I didn't reach any conclusions (I timed out waiting for a reply).
Michał Żygowski has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 22: Code-Review+1
(1 comment)
Very cool stuff. Works out-of-the-box with patched TianoCore.
https://review.coreboot.org/c/coreboot/+/40520/21/src/include/smmstore.h File src/include/smmstore.h:
https://review.coreboot.org/c/coreboot/+/40520/21/src/include/smmstore.h@43 PS21, Line 43: * FIXME: The data format isn't specified.
This refers to the data stored within the blocks. […]
This shouldn't be needed, because you may store any data in it (that is the purpose I think?). If anything, a driver that handles specific data format should be implemented in a separate patch IMO.
Matt DeVillier has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 22:
Patch Set 22: Code-Review+1
(1 comment)
Very cool stuff. Works out-of-the-box with patched TianoCore.
can you provide a branch/commit and platform on which you're able to verify this with this current patchset?
Michał Żygowski has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 22:
Patch Set 22:
Patch Set 22: Code-Review+1
(1 comment)
Very cool stuff. Works out-of-the-box with patched TianoCore.
can you provide a branch/commit and platform on which you're able to verify this with this current patchset?
Recently I have used this commit:
https://github.com/9elements/edk2-1/commit/59b3af6d0340ed01471018d68c693cd1d...
and built coreboot with UEFI payload and this patch. Worked perfectly on Dell OptiPlex 9010 SFF (although you cannot use TianoCore debug build, because it will cause some timing issues with SMMSTORE related SMIs - some FVB write/read protocol calls gave success, some were aborted).
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 22:
Patch Set 22:
Patch Set 22:
Patch Set 22: Code-Review+1
(1 comment)
Very cool stuff. Works out-of-the-box with patched TianoCore.
can you provide a branch/commit and platform on which you're able to verify this with this current patchset?
Recently I have used this commit:
https://github.com/9elements/edk2-1/commit/59b3af6d0340ed01471018d68c693cd1d...
and built coreboot with UEFI payload and this patch. Worked perfectly on Dell OptiPlex 9010 SFF (although you cannot use TianoCore debug build, because it will cause some timing issues with SMMSTORE related SMIs - some FVB write/read protocol calls gave success, some were aborted).
I've tried this on the Asrock B85M Pro4, and something is definitely being saved: the language setting. I think it's the simplest thing one can use to verify persistence. I've also been able to add a new boot entry and it will be saved.
Other settings such as changing the console output mode do not seem to persist across reboots, but I've no idea if they're supposed to work in the first place.
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 22:
Patch Set 22:
Patch Set 22:
Patch Set 22:
Patch Set 22: Code-Review+1
(1 comment)
Very cool stuff. Works out-of-the-box with patched TianoCore.
can you provide a branch/commit and platform on which you're able to verify this with this current patchset?
Recently I have used this commit:
https://github.com/9elements/edk2-1/commit/59b3af6d0340ed01471018d68c693cd1d...
and built coreboot with UEFI payload and this patch. Worked perfectly on Dell OptiPlex 9010 SFF (although you cannot use TianoCore debug build, because it will cause some timing issues with SMMSTORE related SMIs - some FVB write/read protocol calls gave success, some were aborted).
I've tried this on the Asrock B85M Pro4, and something is definitely being saved: the language setting. I think it's the simplest thing one can use to verify persistence. I've also been able to add a new boot entry and it will be saved.
Other settings such as changing the console output mode do not seem to persist across reboots, but I've no idea if they're supposed to work in the first place.
Forgot to mention: I've used the same TianoCore commit as Michał.
Angel Pons has uploaded a new patch set (#23) to the change originally created by Patrick Rudolph. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
drivers/smmstore: Implement SMMSTORE version 2
SMMSTORE version 2 is a complete redesign of the current driver. It is not backwards-compatible with version 1, and only one version can be used at a time.
Key features: * Uses a fixed communication buffer instead of writing to arbitrary memory addresses provided by untrusted ring0 code. * Gives the caller full control over the used data format. * Splits the store into smaller chunks to allow fault tolerant updates. * Doesn't provide feedback about the actual read/written bytes, just returns error or success in registers. * Returns an error if the requested operation would overflow the communication buffer.
Separate the SMMSTORE into 64 KiB blocks that can individually be read/written/erased. To be used by payloads that implement a FaultTolerant Variable store like TianoCore.
The implementation has been tested against EDK2 master.
An example EDK2 implementation can be found here: https://github.com/9elements/edk2-1/commit/eb1127744a3a5d5c8ac4e8eb76f07e79c...
Change-Id: I25e49d184135710f3e6dd1ad3bed95de950fe057 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com Signed-off-by: Christian Walter christian.walter@9elements.com --- M Documentation/drivers/index.md A Documentation/drivers/smmstorev2.md M payloads/libpayload/include/coreboot_tables.h M src/commonlib/include/commonlib/cbmem_id.h M src/commonlib/include/commonlib/coreboot_tables.h M src/drivers/smmstore/Kconfig M src/drivers/smmstore/Makefile.inc A src/drivers/smmstore/ramstage.c M src/drivers/smmstore/smi.c M src/drivers/smmstore/store.c M src/include/smmstore.h M src/lib/coreboot_table.c 12 files changed, 702 insertions(+), 8 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/20/40520/23
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 23:
(1 comment)
https://review.coreboot.org/c/coreboot/+/40520/21/src/include/smmstore.h File src/include/smmstore.h:
https://review.coreboot.org/c/coreboot/+/40520/21/src/include/smmstore.h@43 PS21, Line 43: * FIXME: The data format isn't specified.
This shouldn't be needed, because you may store any data in it (that is the purpose I think?). […]
Kept the sentence in the comment, but dropped the FIXME.
Tim Wawrzynczak has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 23: Code-Review+1
(1 comment)
https://review.coreboot.org/c/coreboot/+/40520/21/src/commonlib/include/comm... File src/commonlib/include/commonlib/coreboot_tables.h:
https://review.coreboot.org/c/coreboot/+/40520/21/src/commonlib/include/comm... PS21, Line 492: struct lb_smmstorev2 { : uint32_t tag; : uint32_t size; : uint32_t num_blocks; /* Number of writeable blocks in SMM */ : uint32_t block_size; /* Size of a block in byte. Default: 64 KiB */ : uint32_t mmap_addr; /* MMIO address of the store for read only access */ : uint32_t com_buffer; /* Physical address of the communication buffer */ : uint32_t com_buffer_size; /* Size of the communication buffer in bytes */ : uint8_t apm_cmd; /* The command byte to write to the APM I/O port */ : uint8_t unused[3]; /* Set to zero */ : }; should libpayload provide this struct on its end as well?
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 23:
(1 comment)
https://review.coreboot.org/c/coreboot/+/40520/21/src/commonlib/include/comm... File src/commonlib/include/commonlib/coreboot_tables.h:
https://review.coreboot.org/c/coreboot/+/40520/21/src/commonlib/include/comm... PS21, Line 492: struct lb_smmstorev2 { : uint32_t tag; : uint32_t size; : uint32_t num_blocks; /* Number of writeable blocks in SMM */ : uint32_t block_size; /* Size of a block in byte. Default: 64 KiB */ : uint32_t mmap_addr; /* MMIO address of the store for read only access */ : uint32_t com_buffer; /* Physical address of the communication buffer */ : uint32_t com_buffer_size; /* Size of the communication buffer in bytes */ : uint8_t apm_cmd; /* The command byte to write to the APM I/O port */ : uint8_t unused[3]; /* Set to zero */ : };
should libpayload provide this struct on its end as well?
Can libpayload use smmstore?
Matt DeVillier has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 23: Code-Review+2
(1 comment)
https://review.coreboot.org/c/coreboot/+/40520/23/src/drivers/smmstore/Kconf... File src/drivers/smmstore/Kconfig:
https://review.coreboot.org/c/coreboot/+/40520/23/src/drivers/smmstore/Kconf... PS23, Line 10: Implement nit: 'Use' instead of 'Implement?' Both versions are implemented / compiled into the build regardless of if V1 or V2 is selected for use
Tim Wawrzynczak has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 23:
(1 comment)
https://review.coreboot.org/c/coreboot/+/40520/21/src/commonlib/include/comm... File src/commonlib/include/commonlib/coreboot_tables.h:
https://review.coreboot.org/c/coreboot/+/40520/21/src/commonlib/include/comm... PS21, Line 492: struct lb_smmstorev2 { : uint32_t tag; : uint32_t size; : uint32_t num_blocks; /* Number of writeable blocks in SMM */ : uint32_t block_size; /* Size of a block in byte. Default: 64 KiB */ : uint32_t mmap_addr; /* MMIO address of the store for read only access */ : uint32_t com_buffer; /* Physical address of the communication buffer */ : uint32_t com_buffer_size; /* Size of the communication buffer in bytes */ : uint8_t apm_cmd; /* The command byte to write to the APM I/O port */ : uint8_t unused[3]; /* Set to zero */ : };
Can libpayload use smmstore?
I don't see an APM call right now, I guess not.
Michał Żygowski has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 23:
(1 comment)
https://review.coreboot.org/c/coreboot/+/40520/21/src/commonlib/include/comm... File src/commonlib/include/commonlib/coreboot_tables.h:
https://review.coreboot.org/c/coreboot/+/40520/21/src/commonlib/include/comm... PS21, Line 492: struct lb_smmstorev2 { : uint32_t tag; : uint32_t size; : uint32_t num_blocks; /* Number of writeable blocks in SMM */ : uint32_t block_size; /* Size of a block in byte. Default: 64 KiB */ : uint32_t mmap_addr; /* MMIO address of the store for read only access */ : uint32_t com_buffer; /* Physical address of the communication buffer */ : uint32_t com_buffer_size; /* Size of the communication buffer in bytes */ : uint8_t apm_cmd; /* The command byte to write to the APM I/O port */ : uint8_t unused[3]; /* Set to zero */ : };
I don't see an APM call right now, I guess not.
Not for now, but as a future idea it is doable. In fact, SMMSTORE is for payload and/or OS use right?
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 23:
(1 comment)
https://review.coreboot.org/c/coreboot/+/40520/21/src/commonlib/include/comm... File src/commonlib/include/commonlib/coreboot_tables.h:
https://review.coreboot.org/c/coreboot/+/40520/21/src/commonlib/include/comm... PS21, Line 492: struct lb_smmstorev2 { : uint32_t tag; : uint32_t size; : uint32_t num_blocks; /* Number of writeable blocks in SMM */ : uint32_t block_size; /* Size of a block in byte. Default: 64 KiB */ : uint32_t mmap_addr; /* MMIO address of the store for read only access */ : uint32_t com_buffer; /* Physical address of the communication buffer */ : uint32_t com_buffer_size; /* Size of the communication buffer in bytes */ : uint8_t apm_cmd; /* The command byte to write to the APM I/O port */ : uint8_t unused[3]; /* Set to zero */ : };
Not for now, but as a future idea it is doable. […]
It's meant for bootloader use, but OSes could use SMMSTORE as well. However, I imagine OSes would have better places to save stuff into than the flash chip.
Tim Wawrzynczak has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 23:
(1 comment)
https://review.coreboot.org/c/coreboot/+/40520/21/src/commonlib/include/comm... File src/commonlib/include/commonlib/coreboot_tables.h:
https://review.coreboot.org/c/coreboot/+/40520/21/src/commonlib/include/comm... PS21, Line 492: struct lb_smmstorev2 { : uint32_t tag; : uint32_t size; : uint32_t num_blocks; /* Number of writeable blocks in SMM */ : uint32_t block_size; /* Size of a block in byte. Default: 64 KiB */ : uint32_t mmap_addr; /* MMIO address of the store for read only access */ : uint32_t com_buffer; /* Physical address of the communication buffer */ : uint32_t com_buffer_size; /* Size of the communication buffer in bytes */ : uint8_t apm_cmd; /* The command byte to write to the APM I/O port */ : uint8_t unused[3]; /* Set to zero */ : };
It's meant for bootloader use, but OSes could use SMMSTORE as well. […]
Just curious, are there any other known consumers of SMMSTORE besides TianoCore?
Patrick Georgi has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 23:
(1 comment)
https://review.coreboot.org/c/coreboot/+/40520/21/src/commonlib/include/comm... File src/commonlib/include/commonlib/coreboot_tables.h:
https://review.coreboot.org/c/coreboot/+/40520/21/src/commonlib/include/comm... PS21, Line 492: struct lb_smmstorev2 { : uint32_t tag; : uint32_t size; : uint32_t num_blocks; /* Number of writeable blocks in SMM */ : uint32_t block_size; /* Size of a block in byte. Default: 64 KiB */ : uint32_t mmap_addr; /* MMIO address of the store for read only access */ : uint32_t com_buffer; /* Physical address of the communication buffer */ : uint32_t com_buffer_size; /* Size of the communication buffer in bytes */ : uint8_t apm_cmd; /* The command byte to write to the APM I/O port */ : uint8_t unused[3]; /* Set to zero */ : };
Just curious, are there any other known consumers of SMMSTORE besides TianoCore?
smmstore has been developed specifically to provide a solution for Tiano payloads that need to access flash long after the OS took over - hence the SMI backdoor. Tianocore + smmstore is coreboot (in the form of its SMM handler) and the payload doing sneaky things behind the OS' back.
For everything else I'd propose trying to keep things sane and have one and only one arbiter over hardware at any point in time: first coreboot, then the payload, then the OS.
Angel Pons has uploaded a new patch set (#24) to the change originally created by Patrick Rudolph. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
drivers/smmstore: Implement SMMSTORE version 2
SMMSTORE version 2 is a complete redesign of the current driver. It is not backwards-compatible with version 1, and only one version can be used at a time.
Key features: * Uses a fixed communication buffer instead of writing to arbitrary memory addresses provided by untrusted ring0 code. * Gives the caller full control over the used data format. * Splits the store into smaller chunks to allow fault tolerant updates. * Doesn't provide feedback about the actual read/written bytes, just returns error or success in registers. * Returns an error if the requested operation would overflow the communication buffer.
Separate the SMMSTORE into 64 KiB blocks that can individually be read/written/erased. To be used by payloads that implement a FaultTolerant Variable store like TianoCore.
The implementation has been tested against EDK2 master.
An example EDK2 implementation can be found here: https://github.com/9elements/edk2-1/commit/eb1127744a3a5d5c8ac4e8eb76f07e79c...
Change-Id: I25e49d184135710f3e6dd1ad3bed95de950fe057 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com Signed-off-by: Christian Walter christian.walter@9elements.com --- M Documentation/drivers/index.md A Documentation/drivers/smmstorev2.md M payloads/libpayload/include/coreboot_tables.h M src/commonlib/include/commonlib/cbmem_id.h M src/commonlib/include/commonlib/coreboot_tables.h M src/drivers/smmstore/Kconfig M src/drivers/smmstore/Makefile.inc A src/drivers/smmstore/ramstage.c M src/drivers/smmstore/smi.c M src/drivers/smmstore/store.c M src/include/smmstore.h M src/lib/coreboot_table.c 12 files changed, 702 insertions(+), 8 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/20/40520/24
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 24:
(2 comments)
https://review.coreboot.org/c/coreboot/+/40520/21/src/commonlib/include/comm... File src/commonlib/include/commonlib/coreboot_tables.h:
https://review.coreboot.org/c/coreboot/+/40520/21/src/commonlib/include/comm... PS21, Line 492: struct lb_smmstorev2 { : uint32_t tag; : uint32_t size; : uint32_t num_blocks; /* Number of writeable blocks in SMM */ : uint32_t block_size; /* Size of a block in byte. Default: 64 KiB */ : uint32_t mmap_addr; /* MMIO address of the store for read only access */ : uint32_t com_buffer; /* Physical address of the communication buffer */ : uint32_t com_buffer_size; /* Size of the communication buffer in bytes */ : uint8_t apm_cmd; /* The command byte to write to the APM I/O port */ : uint8_t unused[3]; /* Set to zero */ : };
smmstore has been developed specifically to provide a solution for Tiano payloads that need to acces […]
I fully agree.
https://review.coreboot.org/c/coreboot/+/40520/23/src/drivers/smmstore/Kconf... File src/drivers/smmstore/Kconfig:
https://review.coreboot.org/c/coreboot/+/40520/23/src/drivers/smmstore/Kconf... PS23, Line 10: Implement
nit: 'Use' instead of 'Implement?' Both versions are implemented / compiled into the build regardles […]
Done
Michał Żygowski has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 24: Code-Review+2
Paul Menzel has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 24:
(1 comment)
https://review.coreboot.org/c/coreboot/+/40520/21/src/commonlib/include/comm... File src/commonlib/include/commonlib/coreboot_tables.h:
https://review.coreboot.org/c/coreboot/+/40520/21/src/commonlib/include/comm... PS21, Line 492: struct lb_smmstorev2 { : uint32_t tag; : uint32_t size; : uint32_t num_blocks; /* Number of writeable blocks in SMM */ : uint32_t block_size; /* Size of a block in byte. Default: 64 KiB */ : uint32_t mmap_addr; /* MMIO address of the store for read only access */ : uint32_t com_buffer; /* Physical address of the communication buffer */ : uint32_t com_buffer_size; /* Size of the communication buffer in bytes */ : uint8_t apm_cmd; /* The command byte to write to the APM I/O port */ : uint8_t unused[3]; /* Set to zero */ : };
I fully agree.
Maybe that could be added as a note/clarification in the documentation.
Matt DeVillier has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 24: Code-Review+2
Christian Walter has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
Patch Set 24: Code-Review+2
Michał Żygowski has submitted this change. ( https://review.coreboot.org/c/coreboot/+/40520 )
Change subject: drivers/smmstore: Implement SMMSTORE version 2 ......................................................................
drivers/smmstore: Implement SMMSTORE version 2
SMMSTORE version 2 is a complete redesign of the current driver. It is not backwards-compatible with version 1, and only one version can be used at a time.
Key features: * Uses a fixed communication buffer instead of writing to arbitrary memory addresses provided by untrusted ring0 code. * Gives the caller full control over the used data format. * Splits the store into smaller chunks to allow fault tolerant updates. * Doesn't provide feedback about the actual read/written bytes, just returns error or success in registers. * Returns an error if the requested operation would overflow the communication buffer.
Separate the SMMSTORE into 64 KiB blocks that can individually be read/written/erased. To be used by payloads that implement a FaultTolerant Variable store like TianoCore.
The implementation has been tested against EDK2 master.
An example EDK2 implementation can be found here: https://github.com/9elements/edk2-1/commit/eb1127744a3a5d5c8ac4e8eb76f07e79c...
Change-Id: I25e49d184135710f3e6dd1ad3bed95de950fe057 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com Signed-off-by: Christian Walter christian.walter@9elements.com Reviewed-on: https://review.coreboot.org/c/coreboot/+/40520 Tested-by: build bot (Jenkins) no-reply@coreboot.org Reviewed-by: Michał Żygowski michal.zygowski@3mdeb.com Reviewed-by: Matt DeVillier matt.devillier@gmail.com --- M Documentation/drivers/index.md A Documentation/drivers/smmstorev2.md M payloads/libpayload/include/coreboot_tables.h M src/commonlib/include/commonlib/cbmem_id.h M src/commonlib/include/commonlib/coreboot_tables.h M src/drivers/smmstore/Kconfig M src/drivers/smmstore/Makefile.inc A src/drivers/smmstore/ramstage.c M src/drivers/smmstore/smi.c M src/drivers/smmstore/store.c M src/include/smmstore.h M src/lib/coreboot_table.c 12 files changed, 702 insertions(+), 8 deletions(-)
Approvals: build bot (Jenkins): Verified Matt DeVillier: Looks good to me, approved Michał Żygowski: Looks good to me, approved Christian Walter: Looks good to me, approved
diff --git a/Documentation/drivers/index.md b/Documentation/drivers/index.md index e215c6a..508beaf 100644 --- a/Documentation/drivers/index.md +++ b/Documentation/drivers/index.md @@ -7,3 +7,4 @@ * [IPMI KCS](ipmi_kcs.md) * [SMMSTORE](smmstore.md) * [SoundWire](soundwire.md) +* [SMMSTOREv2](smmstorev2.md) diff --git a/Documentation/drivers/smmstorev2.md b/Documentation/drivers/smmstorev2.md new file mode 100644 index 0000000..cb79b8b --- /dev/null +++ b/Documentation/drivers/smmstorev2.md @@ -0,0 +1,221 @@ +# SMM based flash storage driver Version 2 + +This documents the API exposed by the x86 system management based +storage driver. + +## SMMSTOREv2 + +SMMSTOREv2 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` and `CONFIG_SMMSTORE_V2=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. + +### Storage size and alignment + +SMMSTORE version 2 requires a minimum alignment of 64 KiB, which should +be supported by all flash chips. Not having to perform read-modify-write +operations is desired, as it reduces complexity and potential for bugs. + +This can be used by a FTW (FaultTolerantWrite) implementation that uses +at least two regions in an A/B update scheme. The FTW implementation in +EDK2 uses three different regions in the store: + +- The variable store +- The FTW spare block +- The FTW working block + +All regions must be block-aligned, and the FTW spare size must be larger +than that of the variable store. FTW working block can be much smaller. +With 64 KiB as block size, the minimum size of the FTW-enabled store is: + +- The variable store: 1 block = 64 KiB +- The FTW spare block: 2 blocks = 2 * 64 KiB +- The FTW working block: 1 block = 64 KiB + +Therefore, the minimum size for EDK2 FTW is 4 blocks, or 256 KiB. + +## API + +The API provides read and write access to an unformatted block storage. + +### Storage region + +By default SMMSTOREv2 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 mandatory to align the `SMMSTORE` region to 64KiB for +compatibility with the largest flash erase operation. + +When a default generated FMAP is used, the size of the FMAP region is +equal to `CONFIG_SMMSTORE_SIZE`. UEFI payloads expect at least 64 KiB. +To support a fault tolerant write mechanism, at least a multiple of +this size is recommended. + +### Communication buffer + +To prevent malicious ring0 code to access arbitrary memory locations, +SMMSTOREv2 uses a communication buffer in CBMEM/HOB for all transfers. +This buffer has to be at least 64 KiB in size and must be installed +before calling any of the SMMSTORE read or write operations. Usually, +coreboot will install this buffer to transfer data between ring0 and +the [SMM] handler. + +In order to get the communication buffer address, the payload or OS +has to read the coreboot table with tag `0x0039`, containing: + +```C +struct lb_smmstorev2 { + uint32_t tag; + uint32_t size; + uint32_t num_blocks; /* Number of writeable blocks in SMM */ + uint32_t block_size; /* Size of a block in byte. Default: 64 KiB */ + uint32_t mmap_addr; /* MMIO address of the store for read only access */ + uint32_t com_buffer; /* Physical address of the communication buffer */ + uint32_t com_buffer_size; /* Size of the communication buffer in byte */ + uint8_t apm_cmd; /* The command byte to write to the APM I/O port */ + uint8_t unused[3]; /* Set to zero */ +}; +``` + +The absence of this coreboot table entry indicates that there's no +SMMSTOREv2 support. + +### Blocks + +The SMMSTOREv2 splits the SMMSTORE FMAP partition into smaller chunks +called *blocks*. Every block is at least the size of 64KiB to support +arbitrary NOR flash erase ops. A payload or OS must make no further +assumptions about the block or communication buffer size. + +### Generating the SMI + +SMMSTOREv2 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 SMMSTOREv2 command. `%ebx` contains the +parameter buffer to the SMMSTOREv2 command. + +### Return values + +If a command succeeds, SMMSTOREv2 will return with +`SMMSTORE_RET_SUCCESS=0` in `%eax`. On failure SMMSTORE will return +`SMMSTORE_RET_FAILURE=1`. For unsupported SMMSTORE commands +`SMMSTORE_REG_UNSUPPORTED=2` is returned. + +**NOTE 1**: The caller **must** check the return value and should make +no assumption on the returned data if `%eax` does not contain +`SMMSTORE_RET_SUCCESS`. + +**NOTE 2**: If the SMI returns without changing `%ax`, it can be assumed +that the SMMSTOREv2 feature is not installed. + +### Calling arguments + +SMMSTOREv2 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_INIT = 4 + +This installs the communication buffer to use and thus enables the +SMMSTORE handler. This command can only be executed once and is done +by the firmware. Calling this function at runtime has no effect. + +The additional parameter buffer `%ebx` contains a pointer to the +following struct: + +```C +struct smmstore_params_init { + uint32_t com_buffer; + uint32_t com_buffer_size; +} __packed; +``` + +INPUT: +- `com_buffer`: Physical address of the communication buffer (CBMEM) +- `com_buffer_size`: Size in bytes of the communication buffer + +#### - SMMSTORE_CMD_RAW_READ = 5 + +SMMSTOREv2 allows reading arbitrary data. It is up to the caller to +initialize the store with meaningful data before using it. + +The additional parameter buffer `%ebx` contains a pointer to the +following struct: + +```C +struct smmstore_params_raw_read { + uint32_t bufsize; + uint32_t bufoffset; + uint32_t block_id; +} __packed; +``` + +INPUT: +- `bufsize`: Size of data to read within the communication buffer +- `bufoffset`: Offset within the communication buffer +- `block_id`: Block to read from + +#### - SMMSTORE_CMD_RAW_WRITE = 6 + +SMMSTOREv2 allows writing arbitrary data. It is up to the caller to +erase a block before writing it. + +The additional parameter buffer `%ebx` contains a pointer to +the following struct: + +```C +struct smmstore_params_raw_write { + uint32_t bufsize; + uint32_t bufoffset; + uint32_t block_id; +} __packed; +``` + +INPUT: +- `bufsize`: Size of data to write within the communication buffer +- `bufoffset`: Offset within the communication buffer +- `block_id`: Block to write to + +#### - SMMSTORE_CMD_RAW_CLEAR = 7 + +SMMSTOREv2 allows clearing blocks. A cleared block will read as `0xff`. +By providing multiple blocks the caller can implement a fault tolerant +write mechanism. It is up to the caller to clear blocks before writing +to them. + + +```C +struct smmstore_params_raw_clear { + uint32_t block_id; +} __packed; +``` + +INPUT: +- `block_id`: Block to erase + +#### Security + +Pointers provided by the payload or OS are checked to not overlap with +SMM. This protects the SMM handler from being compromised. + +As all information is exchanged using the communication buffer and +coreboot tables, there's no risk that a malicious application capable +of issuing SMIs could extract arbitrary data or modify the currently +running kernel. + +## 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_b...) +Note that this differs significantly from coreboot's implementation. + +[SMM]: ../security/smm.md diff --git a/payloads/libpayload/include/coreboot_tables.h b/payloads/libpayload/include/coreboot_tables.h index bf8c0d9..bfdd21e 100644 --- a/payloads/libpayload/include/coreboot_tables.h +++ b/payloads/libpayload/include/coreboot_tables.h @@ -79,6 +79,7 @@ CB_TAG_MMC_INFO = 0x0035, CB_TAG_TCPA_LOG = 0x0036, CB_TAG_FMAP = 0x0037, + CB_TAG_SMMSTOREV2 = 0x0039, CB_TAG_CMOS_OPTION_TABLE = 0x00c8, CB_TAG_OPTION = 0x00c9, CB_TAG_OPTION_ENUM = 0x00ca, diff --git a/src/commonlib/include/commonlib/cbmem_id.h b/src/commonlib/include/commonlib/cbmem_id.h index ac271a0..6b4d604 100644 --- a/src/commonlib/include/commonlib/cbmem_id.h +++ b/src/commonlib/include/commonlib/cbmem_id.h @@ -68,6 +68,7 @@ #define CBMEM_ID_ROM3 0x524f4d33 #define CBMEM_ID_FMAP 0x464d4150 #define CBMEM_ID_FSP_LOGO 0x4c4f474f +#define CBMEM_ID_SMM_COMBUFFER 0x53534d32
#define CBMEM_ID_TO_NAME_TABLE \ { CBMEM_ID_ACPI, "ACPI " }, \ diff --git a/src/commonlib/include/commonlib/coreboot_tables.h b/src/commonlib/include/commonlib/coreboot_tables.h index 6393c01..4406002 100644 --- a/src/commonlib/include/commonlib/coreboot_tables.h +++ b/src/commonlib/include/commonlib/coreboot_tables.h @@ -80,6 +80,7 @@ LB_TAG_TCPA_LOG = 0x0036, LB_TAG_FMAP = 0x0037, LB_TAG_PLATFORM_BLOB_VERSION = 0x0038, + LB_TAG_SMMSTOREV2 = 0x0039, LB_TAG_CMOS_OPTION_TABLE = 0x00c8, LB_TAG_OPTION = 0x00c9, LB_TAG_OPTION_ENUM = 0x00ca, @@ -484,4 +485,20 @@ #define CHECKSUM_PCBIOS 1 };
+/* SMMSTOREv2 record + * This record contains information to use SMMSTOREv2. + */ + +struct lb_smmstorev2 { + uint32_t tag; + uint32_t size; + uint32_t num_blocks; /* Number of writeable blocks in SMM */ + uint32_t block_size; /* Size of a block in byte. Default: 64 KiB */ + uint32_t mmap_addr; /* MMIO address of the store for read only access */ + uint32_t com_buffer; /* Physical address of the communication buffer */ + uint32_t com_buffer_size; /* Size of the communication buffer in bytes */ + uint8_t apm_cmd; /* The command byte to write to the APM I/O port */ + uint8_t unused[3]; /* Set to zero */ +}; + #endif diff --git a/src/drivers/smmstore/Kconfig b/src/drivers/smmstore/Kconfig index 7ee8676..ba8268e 100644 --- a/src/drivers/smmstore/Kconfig +++ b/src/drivers/smmstore/Kconfig @@ -6,6 +6,18 @@ default y if PAYLOAD_TIANOCORE select SPI_FLASH_SMM if BOOT_DEVICE_SPI_FLASH_RW_NOMMAP
+config SMMSTORE_V2 + bool "Use version 2 of SMMSTORE API" + depends on SMMSTORE + default n + help + Version 2 of SMMSTORE allows secure communication with SMM and + makes no assumptions on the structure of the data stored within. + It splits the store into chunks to allows fault tolerant writes. + + By using version 2 you cannot make use of software that expects + a version 1 SMMSTORE. + config SMMSTORE_IN_CBFS bool default n diff --git a/src/drivers/smmstore/Makefile.inc b/src/drivers/smmstore/Makefile.inc index 1cafe3a..90bcdec 100644 --- a/src/drivers/smmstore/Makefile.inc +++ b/src/drivers/smmstore/Makefile.inc @@ -1,3 +1,4 @@ ramstage-$(CONFIG_SMMSTORE) += store.c +ramstage-$(CONFIG_SMMSTORE_V2) += ramstage.c
smm-$(CONFIG_SMMSTORE) += store.c smi.c diff --git a/src/drivers/smmstore/ramstage.c b/src/drivers/smmstore/ramstage.c new file mode 100644 index 0000000..ef80e22 --- /dev/null +++ b/src/drivers/smmstore/ramstage.c @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <bootstate.h> +#include <cpu/x86/smm.h> +#include <commonlib/helpers.h> +#include <commonlib/region.h> +#include <console/console.h> +#include <smmstore.h> +#include <types.h> +#include <cbmem.h> + +static struct smmstore_params_info info; + +void lb_smmstorev2(struct lb_header *header) +{ + struct lb_record *rec; + struct lb_smmstorev2 *store; + const struct cbmem_entry *e; + + e = cbmem_entry_find(CBMEM_ID_SMM_COMBUFFER); + if (!e) + return; + + rec = lb_new_record(header); + store = (struct lb_smmstorev2 *)rec; + + store->tag = LB_TAG_SMMSTOREV2; + store->size = sizeof(*store); + store->com_buffer = (uintptr_t)cbmem_entry_start(e); + store->com_buffer_size = cbmem_entry_size(e); + store->mmap_addr = info.mmap_addr; + store->num_blocks = info.num_blocks; + store->block_size = info.block_size; + store->apm_cmd = APM_CNT_SMMSTORE; +} + +static void init_store(void *unused) +{ + struct smmstore_params_init args; + uint32_t eax = ~0; + uint32_t ebx; + + if (smmstore_get_info(&info) < 0) { + printk(BIOS_INFO, "SMMSTORE: Failed to get meta data\n"); + return; + } + + void *ptr = cbmem_add(CBMEM_ID_SMM_COMBUFFER, info.block_size); + if (!ptr) { + printk(BIOS_ERR, "SMMSTORE: Failed to add com buffer\n"); + return; + } + + args.com_buffer = (uintptr_t)ptr; + args.com_buffer_size = info.block_size; + ebx = (uintptr_t)&args; + + printk(BIOS_INFO, "SMMSTORE: Setting up SMI handler\n"); + + /* Issue SMI using APM to update the com buffer and to lock the SMMSTORE */ + __asm__ __volatile__ ( + "outb %%al, %%dx" + : "=a" (eax) + : "a" ((SMMSTORE_CMD_INIT << 8) | APM_CNT_SMMSTORE), + "b" (ebx), + "d" (APM_CNT) + : "memory"); + + if (eax != SMMSTORE_RET_SUCCESS) { + printk(BIOS_ERR, "SMMSTORE: Failed to install com buffer\n"); + return; + } +} + +/* The SMI APM handler is installed at DEV_INIT phase */ +BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_EXIT, init_store, NULL); diff --git a/src/drivers/smmstore/smi.c b/src/drivers/smmstore/smi.c index b21423e..b90338c 100644 --- a/src/drivers/smmstore/smi.c +++ b/src/drivers/smmstore/smi.c @@ -23,8 +23,7 @@ return 0; }
-/* Param is usually EBX, ret in EAX */ -uint32_t smmstore_exec(uint8_t command, void *param) +static uint32_t smmstorev1_exec(uint8_t command, void *param) { uint32_t ret = SMMSTORE_RET_FAILURE;
@@ -66,13 +65,89 @@ ret = SMMSTORE_RET_SUCCESS; break; } - default: printk(BIOS_DEBUG, - "Unknown SMM store command: 0x%02x\n", command); + "Unknown SMM store v1 command: 0x%02x\n", command); ret = SMMSTORE_RET_UNSUPPORTED; break; }
return ret; } + +static uint32_t smmstorev2_exec(uint8_t command, void *param) +{ + uint32_t ret = SMMSTORE_RET_FAILURE; + + switch (command) { + case SMMSTORE_CMD_INIT: { + printk(BIOS_DEBUG, "Init SMM store\n"); + struct smmstore_params_init *params = param; + + if (range_check(params, sizeof(*params)) != 0) + break; + + void *buf = (void *)(uintptr_t)params->com_buffer; + + if (range_check(buf, params->com_buffer_size) != 0) + break; + + if (smmstore_init(buf, params->com_buffer_size) == 0) + ret = SMMSTORE_RET_SUCCESS; + break; + } + case SMMSTORE_CMD_RAW_READ: { + printk(BIOS_DEBUG, "Raw read from SMM store, param = %p\n", param); + struct smmstore_params_raw_read *params = param; + + if (range_check(params, sizeof(*params)) != 0) + break; + + if (smmstore_rawread_region(params->block_id, params->bufoffset, + params->bufsize) == 0) + ret = SMMSTORE_RET_SUCCESS; + break; + } + case SMMSTORE_CMD_RAW_WRITE: { + printk(BIOS_DEBUG, "Raw write to SMM store, param = %p\n", param); + struct smmstore_params_raw_write *params = param; + + if (range_check(params, sizeof(*params)) != 0) + break; + + if (smmstore_rawwrite_region(params->block_id, params->bufoffset, + params->bufsize) == 0) + ret = SMMSTORE_RET_SUCCESS; + break; + } + case SMMSTORE_CMD_RAW_CLEAR: { + printk(BIOS_DEBUG, "Raw clear SMM store, param = %p\n", param); + struct smmstore_params_raw_clear *params = param; + + if (range_check(params, sizeof(*params)) != 0) + break; + + if (smmstore_rawclear_region(params->block_id) == 0) + ret = SMMSTORE_RET_SUCCESS; + break; + } + default: + printk(BIOS_DEBUG, + "Unknown SMM store v2 command: 0x%02x\n", command); + ret = SMMSTORE_RET_UNSUPPORTED; + break; + } + + return ret; +} + +uint32_t smmstore_exec(uint8_t command, void *param) +{ + if (!param) + return SMMSTORE_RET_FAILURE; + + if (CONFIG(SMMSTORE_V2)) + return smmstorev2_exec(command, param); + else + return smmstorev1_exec(command, param); +} diff --git a/src/drivers/smmstore/store.c b/src/drivers/smmstore/store.c index 252ea8d..9f9ab01 100644 --- a/src/drivers/smmstore/store.c +++ b/src/drivers/smmstore/store.c @@ -262,3 +262,200 @@
return 0; } + + +/* Implementation of Version 2 */ + +static bool store_initialized; +static struct mem_region_device mdev_com_buf; + +static int smmstore_rdev_chain(struct region_device *rdev) +{ + if (!store_initialized) + return -1; + + return rdev_chain_full(rdev, &mdev_com_buf.rdev); +} + +/** + * Call once before using the store. In SMM this must be called through an + * APM SMI handler providing the communication buffer address and length. + */ +int smmstore_init(void *buf, size_t len) +{ + if (!buf || len < SMM_BLOCK_SIZE) + return -1; + + if (store_initialized) + return -1; + + mem_region_device_rw_init(&mdev_com_buf, buf, len); + + store_initialized = true; + + return 0; +} + +#if ENV_RAMSTAGE +/** + * Provide metadata for the coreboot tables. + * Must only be called in ramstage, but not in SMM. + */ +int smmstore_get_info(struct smmstore_params_info *out) +{ + struct region_device store; + + if (lookup_store(&store) < 0) { + printk(BIOS_ERR, "smm store: lookup of store failed\n"); + return -1; + } + + if (!IS_ALIGNED(region_device_offset(&store), SMM_BLOCK_SIZE)) { + printk(BIOS_ERR, "smm store: store not aligned to block size\n"); + return -1; + } + + out->block_size = SMM_BLOCK_SIZE; + out->num_blocks = region_device_sz(&store) / SMM_BLOCK_SIZE; + + /* FIXME: Broken EDK2 always assumes memory mapped Firmware Block Volumes */ + out->mmap_addr = (uintptr_t)rdev_mmap_full(&store); + + printk(BIOS_DEBUG, "smm store: %d # blocks with size 0x%x\n", + out->num_blocks, out->block_size); + + return 0; +} +#endif + +/* Returns -1 on error, 0 on success */ +static int lookup_block_in_store(struct region_device *store, uint32_t block_id) +{ + if (lookup_store(store) < 0) { + printk(BIOS_ERR, "smm store: lookup of store failed\n"); + return -1; + } + + if ((block_id * SMM_BLOCK_SIZE) >= region_device_sz(store)) { + printk(BIOS_ERR, "smm store: block ID out of range\n"); + return -1; + } + + return 0; +} + +/* Returns NULL on error, pointer from rdev_mmap on success */ +static void *mmap_com_buf(struct region_device *com_buf, uint32_t offset, uint32_t bufsize) +{ + if (smmstore_rdev_chain(com_buf) < 0) { + printk(BIOS_ERR, "smm store: lookup of com buffer failed\n"); + return NULL; + } + + if (offset >= region_device_sz(com_buf)) { + printk(BIOS_ERR, "smm store: offset out of range\n"); + return NULL; + } + + void *ptr = rdev_mmap(com_buf, offset, bufsize); + if (!ptr) + printk(BIOS_ERR, "smm store: not enough space for new data\n"); + + return ptr; +} + +/** + * Reads the specified block of the SMMSTORE and places it in the communication + * buffer. + * @param block_id The id of the block to operate on + * @param offset Offset within the block. + * Must be smaller than the block size. + * @param bufsize Size of chunk to read within the block. + * Must be smaller than the block size. + + * @return Returns -1 on error, 0 on success. + */ +int smmstore_rawread_region(uint32_t block_id, uint32_t offset, uint32_t bufsize) +{ + struct region_device store; + struct region_device com_buf; + + if (lookup_block_in_store(&store, block_id) < 0) + return -1; + + void *ptr = mmap_com_buf(&com_buf, offset, bufsize); + if (!ptr) + return -1; + + printk(BIOS_DEBUG, "smm store: reading %p block %d, offset=0x%x, size=%x\n", + ptr, block_id, offset, bufsize); + + ssize_t ret = rdev_readat(&store, ptr, block_id * SMM_BLOCK_SIZE + offset, bufsize); + rdev_munmap(&com_buf, ptr); + if (ret < 0) + return -1; + + return 0; +} + +/** + * Writes the specified block of the SMMSTORE by reading it from the communication + * buffer. + * @param block_id The id of the block to operate on + * @param offset Offset within the block. + * Must be smaller than the block size. + * @param bufsize Size of chunk to read within the block. + * Must be smaller than the block size. + + * @return Returns -1 on error, 0 on success. + */ +int smmstore_rawwrite_region(uint32_t block_id, uint32_t offset, uint32_t bufsize) +{ + struct region_device store; + struct region_device com_buf; + + if (lookup_block_in_store(&store, block_id) < 0) + return -1; + + if (rdev_chain(&store, &store, block_id * SMM_BLOCK_SIZE + offset, bufsize)) { + printk(BIOS_ERR, "smm store: not enough space for new data\n"); + return -1; + } + + void *ptr = mmap_com_buf(&com_buf, offset, bufsize); + if (!ptr) + return -1; + + printk(BIOS_DEBUG, "smm store: writing %p block %d, offset=0x%x, size=%x\n", + ptr, block_id, offset, bufsize); + + ssize_t ret = rdev_writeat(&store, ptr, 0, bufsize); + rdev_munmap(&com_buf, ptr); + if (ret < 0) + return -1; + + return 0; +} + +/** + * Erases the specified block of the SMMSTORE. The communication buffer remains untouched. + * + * @param block_id The id of the block to operate on + * + * @return Returns -1 on error, 0 on success. + */ +int smmstore_rawclear_region(uint32_t block_id) +{ + struct region_device store; + + if (lookup_block_in_store(&store, block_id) < 0) + return -1; + + ssize_t ret = rdev_eraseat(&store, block_id * SMM_BLOCK_SIZE, SMM_BLOCK_SIZE); + if (ret != SMM_BLOCK_SIZE) { + printk(BIOS_ERR, "smm store: erasing block failed\n"); + return -1; + } + + return 0; +} diff --git a/src/include/smmstore.h b/src/include/smmstore.h index ff0b720..2c37ca3 100644 --- a/src/include/smmstore.h +++ b/src/include/smmstore.h @@ -10,10 +10,18 @@ #define SMMSTORE_RET_FAILURE 1 #define SMMSTORE_RET_UNSUPPORTED 2
+/* Version 1 */ #define SMMSTORE_CMD_CLEAR 1 #define SMMSTORE_CMD_READ 2 #define SMMSTORE_CMD_APPEND 3
+/* Version 2 */ +#define SMMSTORE_CMD_INIT 4 +#define SMMSTORE_CMD_RAW_READ 5 +#define SMMSTORE_CMD_RAW_WRITE 6 +#define SMMSTORE_CMD_RAW_CLEAR 7 + +/* Version 1 */ struct smmstore_params_read { void *buf; ssize_t bufsize; @@ -26,12 +34,90 @@ size_t valsize; };
-/* SMM responder */ +/* Version 2 */ +/* + * The Version 2 protocol separates the SMMSTORE into 64KiB blocks, each + * of which can be read/written/cleared in an independent manner. The + * data format isn't specified. See documentation page for more details. + */ + +#define SMM_BLOCK_SIZE (64 * KiB) + +/* + * Sets the communication buffer to use for read and write operations. + */ +struct smmstore_params_init { + uint32_t com_buffer; + uint32_t com_buffer_size; +} __packed; + +/* + * Returns the number of blocks the SMMSTORE supports and their size. + * For EDK2 this should be at least two blocks with 64 KiB each. + * The mmap_addr is set the memory mapped physical address of the SMMSTORE. + */ +struct smmstore_params_info { + uint32_t num_blocks; + uint32_t block_size; + uint32_t mmap_addr; +} __packed; + +/* + * 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 memory pointed to by @buf. + * + * @block_id must be less than num_blocks + * @bufoffset + @bufsize must be less than block_size + */ +struct smmstore_params_raw_write { + uint32_t bufsize; + uint32_t bufoffset; + uint32_t block_id; +} __packed; + +/* + * 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 + */ +struct smmstore_params_raw_read { + uint32_t bufsize; + uint32_t bufoffset; + uint32_t block_id; +} __packed; + +/* + * Erases the specified block. + * + * @block_id must be less than num_blocks + */ +struct smmstore_params_raw_clear { + uint32_t block_id; +} __packed; + + +/* SMM handler */ uint32_t smmstore_exec(uint8_t command, void *param);
-/* implementation */ +/* Implementation of Version 1 */ int smmstore_read_region(void *buf, ssize_t *bufsize); -int smmstore_append_data(void *key, uint32_t key_sz, - void *value, uint32_t value_sz); +int smmstore_append_data(void *key, uint32_t key_sz, void *value, uint32_t value_sz); int smmstore_clear_region(void); + +/* Implementation of Version 2 */ +int smmstore_init(void *buf, size_t len); +int smmstore_rawread_region(uint32_t block_id, uint32_t offset, uint32_t bufsize); +int smmstore_rawwrite_region(uint32_t block_id, uint32_t offset, uint32_t bufsize); +int smmstore_rawclear_region(uint32_t block_id); +#if ENV_RAMSTAGE +int smmstore_get_info(struct smmstore_params_info *info); +#endif + +/* Advertise SMMSTORE v2 support */ +struct lb_header; +void lb_smmstorev2(struct lb_header *header); + #endif diff --git a/src/lib/coreboot_table.c b/src/lib/coreboot_table.c index 9148405..857f5a5 100644 --- a/src/lib/coreboot_table.c +++ b/src/lib/coreboot_table.c @@ -20,6 +20,8 @@ #include <spi_flash.h> #include <security/vboot/misc.h> #include <security/vboot/vbnv_layout.h> +#include <smmstore.h> + #if CONFIG(USE_OPTION_TABLE) #include <option_table.h> #endif @@ -548,6 +550,10 @@
add_cbmem_pointers(head);
+ /* SMMSTORE v2 */ + if (CONFIG(SMMSTORE_V2)) + lb_smmstorev2(head); + /* Add board-specific table entries, if any. */ lb_board(head);