blob: ef80e221bc0aa5ee042c88db53083c5c905848f7 [file] [log] [blame]
/* 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);