blob: e87d12c641673e645da7ae4b6f49e17ac231c3b7 [file] [log] [blame]
/* SPDX-License-Identifier: GPL-2.0-only */
#include <console/console.h>
#include <cpu/amd/amd64_save_state.h>
#include <cpu/amd/msr.h>
#include <amdblocks/smm.h>
#include <cpu/cpu.h>
#include <cpu/x86/msr.h>
#include <stdint.h>
/*
* For data stored in TSEG, ensure TValid is clear so R/W access can reach
* the DRAM when not in SMM.
*/
void clear_tvalid(void)
{
msr_t hwcr = rdmsr(HWCR_MSR);
msr_t mask = rdmsr(SMM_MASK_MSR);
int tvalid = !!(mask.lo & SMM_TSEG_VALID);
if (hwcr.lo & SMM_LOCK) {
if (!tvalid) /* not valid but locked means still accessible */
return;
printk(BIOS_ERR, "can't clear TValid, already locked\n");
return;
}
mask.lo &= ~SMM_TSEG_VALID;
wrmsr(SMM_MASK_MSR, mask);
}
void tseg_valid(void)
{
msr_t mask = rdmsr(SMM_MASK_MSR);
mask.lo |= SMM_TSEG_VALID;
wrmsr(SMM_MASK_MSR, mask);
}
bool is_smm_locked(void)
{
msr_t hwcr = rdmsr(HWCR_MSR);
return hwcr.lo & SMM_LOCK ? true : false;
}
void lock_smm(void)
{
msr_t hwcr = rdmsr(HWCR_MSR);
hwcr.lo |= SMM_LOCK;
wrmsr(HWCR_MSR, hwcr);
}