smmstorev2: Load the communication buffer at SMM setup

This removes the runtime SMI call to set up the communication buffer
for SMMSTORE in favor of setting this buffer up during the installation
of the smihandler.

The reason is that it's less code in the handler and a time costly SMI
is also avoided in ramstage.

Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
Change-Id: I94dce77711f37f87033530f5ae48cb850a39341b
Reviewed-on: https://review.coreboot.org/c/coreboot/+/79738
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Rudolph <patrick.rudolph@9elements.com>
This commit is contained in:
Arthur Heymans
2023-12-27 20:54:19 +01:00
parent c72a65dccd
commit d57d5e3b37
8 changed files with 48 additions and 79 deletions

View File

@@ -124,25 +124,9 @@ additional calling arguments are passed via `%ebx`.
**NOTE**: The size of the struct entries are in the native word size of **NOTE**: The size of the struct entries are in the native word size of
smihandler. This means 32 bits in almost all cases. smihandler. This means 32 bits in almost all cases.
#### - SMMSTORE_CMD_INIT = 4 #### - SMMSTORE_CMD_INIT_DEPRECATED = 4
This installs the communication buffer to use and thus enables the Unused, returns SMMSTORE_REG_UNSUPPORTED.
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 #### - SMMSTORE_CMD_RAW_READ = 5

View File

@@ -60,6 +60,12 @@ int get_console_loglevel(void)
} }
#endif #endif
void smm_get_smmstore_com_buffer(uintptr_t *base, size_t *size)
{
*base = smm_runtime.smmstore_com_buffer_base;
*size = smm_runtime.smmstore_com_buffer_size;
}
void smm_get_cbmemc_buffer(void **buffer_out, size_t *size_out) void smm_get_cbmemc_buffer(void **buffer_out, size_t *size_out)
{ {
*buffer_out = smm_runtime.cbmemc; *buffer_out = smm_runtime.cbmemc;

View File

@@ -10,6 +10,7 @@
#include <device/device.h> #include <device/device.h>
#include <device/mmio.h> #include <device/mmio.h>
#include <rmodule.h> #include <rmodule.h>
#include <smmstore.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <types.h> #include <types.h>
@@ -350,6 +351,22 @@ static void setup_smihandler_params(struct smm_runtime *mod_params,
if (CONFIG(SMM_PCI_RESOURCE_STORE)) if (CONFIG(SMM_PCI_RESOURCE_STORE))
smm_pci_resource_store_init(mod_params); smm_pci_resource_store_init(mod_params);
if (CONFIG(SMMSTORE_V2)) {
struct smmstore_params_info info;
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;
}
mod_params->smmstore_com_buffer_base = (uintptr_t)ptr;
mod_params->smmstore_com_buffer_size = info.block_size;
}
} }
static void print_region(const char *name, const struct region region) static void print_region(const char *name, const struct region region)

View File

@@ -10,8 +10,6 @@
#include <types.h> #include <types.h>
#include <cbmem.h> #include <cbmem.h>
static struct smmstore_params_info info;
void lb_smmstorev2(struct lb_header *header) void lb_smmstorev2(struct lb_header *header)
{ {
struct lb_record *rec; struct lb_record *rec;
@@ -22,6 +20,9 @@ void lb_smmstorev2(struct lb_header *header)
if (!e) if (!e)
return; return;
struct smmstore_params_info info;
smmstore_get_info(&info);
rec = lb_new_record(header); rec = lb_new_record(header);
store = (struct lb_smmstorev2 *)rec; store = (struct lb_smmstorev2 *)rec;
@@ -34,36 +35,3 @@ void lb_smmstorev2(struct lb_header *header)
store->block_size = info.block_size; store->block_size = info.block_size;
store->apm_cmd = APM_CNT_SMMSTORE; store->apm_cmd = APM_CNT_SMMSTORE;
} }
static void init_store(void *unused)
{
struct smmstore_params_init args;
uint32_t ret = ~0;
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;
printk(BIOS_INFO, "SMMSTORE: Setting up SMI handler\n");
/* Issue SMI using APM to update the com buffer and to lock the SMMSTORE */
ret = call_smm(APM_CNT_SMMSTORE, SMMSTORE_CMD_INIT, &args);
if (ret != 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);

View File

@@ -78,24 +78,19 @@ static uint32_t smmstorev1_exec(uint8_t command, void *param)
static uint32_t smmstorev2_exec(uint8_t command, void *param) static uint32_t smmstorev2_exec(uint8_t command, void *param)
{ {
uint32_t ret = SMMSTORE_RET_FAILURE; uint32_t ret = SMMSTORE_RET_FAILURE;
static bool initialized = false;
if (!initialized) {
uintptr_t base;
size_t size;
smm_get_smmstore_com_buffer(&base, &size);
if (smmstore_init((void *)base, size))
return SMMSTORE_RET_FAILURE;
initialized = true;
}
switch (command) { 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: { case SMMSTORE_CMD_RAW_READ: {
printk(BIOS_DEBUG, "Raw read from SMM store, param = %p\n", param); printk(BIOS_DEBUG, "Raw read from SMM store, param = %p\n", param);
struct smmstore_params_raw_read *params = param; struct smmstore_params_raw_read *params = param;

View File

@@ -1,11 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
#include <boot_device.h> #include <boot_device.h>
#include <fmap.h>
#include <fmap_config.h>
#include <commonlib/helpers.h> #include <commonlib/helpers.h>
#include <commonlib/region.h> #include <commonlib/region.h>
#include <console/console.h> #include <console/console.h>
#include <cpu/x86/smm.h>
#include <fmap.h>
#include <fmap_config.h>
#include <smmstore.h> #include <smmstore.h>
#include <types.h> #include <types.h>
@@ -283,14 +284,10 @@ int smmstore_clear_region(void)
/* Implementation of Version 2 */ /* Implementation of Version 2 */
static bool store_initialized;
static struct region_device mdev_com_buf; static struct region_device mdev_com_buf;
static int smmstore_rdev_chain(struct region_device *rdev) static int smmstore_rdev_chain(struct region_device *rdev)
{ {
if (!store_initialized)
return -1;
return rdev_chain_full(rdev, &mdev_com_buf); return rdev_chain_full(rdev, &mdev_com_buf);
} }
@@ -303,13 +300,11 @@ int smmstore_init(void *buf, size_t len)
if (!buf || len < SMM_BLOCK_SIZE) if (!buf || len < SMM_BLOCK_SIZE)
return -1; return -1;
if (store_initialized) if (smm_points_to_smram(buf, len))
return -1; return -1;
rdev_chain_mem_rw(&mdev_com_buf, buf, len); rdev_chain_mem_rw(&mdev_com_buf, buf, len);
store_initialized = true;
return 0; return 0;
} }

View File

@@ -93,6 +93,8 @@ struct smm_runtime {
#endif #endif
uintptr_t save_state_top[CONFIG_MAX_CPUS]; uintptr_t save_state_top[CONFIG_MAX_CPUS];
int smm_log_level; int smm_log_level;
uintptr_t smmstore_com_buffer_base;
size_t smmstore_com_buffer_size;
} __packed; } __packed;
struct smm_module_params { struct smm_module_params {
@@ -231,4 +233,6 @@ bool smm_pci_resource_store_fill_resources(struct smm_pci_resource_info *slots,
void smm_pci_resource_store_init(struct smm_runtime *smm_runtime); void smm_pci_resource_store_init(struct smm_runtime *smm_runtime);
void smm_get_smmstore_com_buffer(uintptr_t *base, size_t *size);
#endif /* CPU_X86_SMM_H */ #endif /* CPU_X86_SMM_H */

View File

@@ -16,7 +16,7 @@
#define SMMSTORE_CMD_APPEND 3 #define SMMSTORE_CMD_APPEND 3
/* Version 2 */ /* Version 2 */
#define SMMSTORE_CMD_INIT 4 #define SMMSTORE_CMD_INIT_DEPRECATED 4
#define SMMSTORE_CMD_RAW_READ 5 #define SMMSTORE_CMD_RAW_READ 5
#define SMMSTORE_CMD_RAW_WRITE 6 #define SMMSTORE_CMD_RAW_WRITE 6
#define SMMSTORE_CMD_RAW_CLEAR 7 #define SMMSTORE_CMD_RAW_CLEAR 7