/* SPDX-License-Identifier: GPL-2.0-only */ #include #include #include #include #include #include #include #include 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);