aboutsummaryrefslogtreecommitdiff
path: root/src/drivers/smmstore/ramstage.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/drivers/smmstore/ramstage.c')
-rw-r--r--src/drivers/smmstore/ramstage.c76
1 files changed, 76 insertions, 0 deletions
diff --git a/src/drivers/smmstore/ramstage.c b/src/drivers/smmstore/ramstage.c
new file mode 100644
index 0000000000..ef80e221bc
--- /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);