smm: Update rev 0x30101 SMM revision save state
According to both Haswell and the SandyBridge/Ivybridge BWGs the save state area actually starts at 0x7c00 offset from 0x8000. Update the em64t101_smm_state_save_area_t structure and introduce a define for the offset. Note: I have no idea what eptp is. It's just listed in the haswell BWG. The offsets should not be changed. Change-Id: I38d1d1469e30628a83f10b188ab2fe53d5a50e5a Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: http://review.coreboot.org/2515 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net> Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
This commit is contained in:
parent
da3087f67d
commit
62f100b028
|
@ -107,6 +107,12 @@ static void smi_restore_pci_address(void)
|
||||||
outl(pci_orig, 0xcf8);
|
outl(pci_orig, 0xcf8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void *smm_save_state(u32 base, int arch_offset, int node)
|
||||||
|
{
|
||||||
|
base += SMM_SAVE_STATE_BEGIN(arch_offset) - (node * 0x400);
|
||||||
|
return (void *)base;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Interrupt handler for SMI#
|
* @brief Interrupt handler for SMI#
|
||||||
*
|
*
|
||||||
|
@ -117,13 +123,13 @@ void smi_handler(u32 smm_revision)
|
||||||
{
|
{
|
||||||
unsigned int node;
|
unsigned int node;
|
||||||
smm_state_save_area_t state_save;
|
smm_state_save_area_t state_save;
|
||||||
u32 smm_base = 0xa8000; /* ASEG */
|
u32 smm_base = 0xa0000; /* ASEG */
|
||||||
|
|
||||||
#if CONFIG_SMM_TSEG
|
#if CONFIG_SMM_TSEG
|
||||||
/* Update global variable TSEG base */
|
/* Update global variable TSEG base */
|
||||||
if (!smi_get_tseg_base())
|
if (!smi_get_tseg_base())
|
||||||
return;
|
return;
|
||||||
smm_base = smi_get_tseg_base() + 0x8000;
|
smm_base = smi_get_tseg_base();
|
||||||
#else
|
#else
|
||||||
/* Are we ok to execute the handler? */
|
/* Are we ok to execute the handler? */
|
||||||
if (!smi_obtain_lock()) {
|
if (!smi_obtain_lock()) {
|
||||||
|
@ -151,24 +157,23 @@ void smi_handler(u32 smm_revision)
|
||||||
case 0x00030002:
|
case 0x00030002:
|
||||||
case 0x00030007:
|
case 0x00030007:
|
||||||
state_save.type = LEGACY;
|
state_save.type = LEGACY;
|
||||||
state_save.legacy_state_save = (legacy_smm_state_save_area_t *)
|
state_save.legacy_state_save =
|
||||||
(smm_base + 0x7e00 - (node * 0x400));
|
smm_save_state(smm_base, 0x7e00, node);
|
||||||
break;
|
break;
|
||||||
case 0x00030100:
|
case 0x00030100:
|
||||||
state_save.type = EM64T;
|
state_save.type = EM64T;
|
||||||
state_save.em64t_state_save = (em64t_smm_state_save_area_t *)
|
state_save.em64t_state_save =
|
||||||
(smm_base + 0x7d00 - (node * 0x400));
|
smm_save_state(smm_base, 0x7d00, node);
|
||||||
break;
|
case 0x00030101: /* SandyBridge, IvyBridge, and Haswell */
|
||||||
case 0x00030101: /* SandyBridge/IvyBridge */
|
|
||||||
state_save.type = EM64T101;
|
state_save.type = EM64T101;
|
||||||
state_save.em64t101_state_save =
|
state_save.em64t101_state_save =
|
||||||
(em64t101_smm_state_save_area_t *)
|
smm_save_state(smm_base,
|
||||||
(smm_base + 0x7d00 - (node * 0x400));
|
SMM_EM64T101_ARCH_OFFSET, node);
|
||||||
break;
|
break;
|
||||||
case 0x00030064:
|
case 0x00030064:
|
||||||
state_save.type = AMD64;
|
state_save.type = AMD64;
|
||||||
state_save.amd64_state_save = (amd64_smm_state_save_area_t *)
|
state_save.amd64_state_save =
|
||||||
(smm_base + 0x7e00 - (node * 0x400));
|
smm_save_state(smm_base, 0x7e00, node);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printk(BIOS_DEBUG, "smm_revision: 0x%08x\n", smm_revision);
|
printk(BIOS_DEBUG, "smm_revision: 0x%08x\n", smm_revision);
|
||||||
|
|
|
@ -27,6 +27,9 @@
|
||||||
/* used only by C programs so far */
|
/* used only by C programs so far */
|
||||||
#define SMM_BASE 0xa0000
|
#define SMM_BASE 0xa0000
|
||||||
|
|
||||||
|
#define SMM_ENTRY_OFFSET 0x8000
|
||||||
|
#define SMM_SAVE_STATE_BEGIN(x) (SMM_ENTRY_OFFSET + (x))
|
||||||
|
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u16 es_selector;
|
u16 es_selector;
|
||||||
|
@ -202,11 +205,17 @@ typedef struct {
|
||||||
|
|
||||||
|
|
||||||
/* Intel Revision 30101 SMM State-Save Area
|
/* Intel Revision 30101 SMM State-Save Area
|
||||||
* Used in SandyBridge/IvyBridge architecture
|
* The following processor architectures use this:
|
||||||
* starts @ 0x7d00
|
* - SandyBridge
|
||||||
|
* - IvyBridge
|
||||||
|
* - Haswell
|
||||||
*/
|
*/
|
||||||
|
#define SMM_EM64T101_ARCH_OFFSET 0x7c00
|
||||||
|
#define SMM_EM64T101_SAVE_STATE_OFFSET \
|
||||||
|
SMM_SAVE_STATE_BEGIN(SMM_EM64T101_ARCH_OFFSET)
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u8 reserved0[208];
|
u8 reserved0[256];
|
||||||
|
u8 reserved1[208];
|
||||||
|
|
||||||
u32 gdtr_upper_base;
|
u32 gdtr_upper_base;
|
||||||
u32 ldtr_upper_base;
|
u32 ldtr_upper_base;
|
||||||
|
@ -219,25 +228,29 @@ typedef struct {
|
||||||
u64 io_rcx;
|
u64 io_rcx;
|
||||||
u64 io_rsi;
|
u64 io_rsi;
|
||||||
|
|
||||||
u8 reserved1[52];
|
u8 reserved2[52];
|
||||||
u32 shutdown_auto_restart;
|
u32 shutdown_auto_restart;
|
||||||
u8 reserved2[8];
|
u8 reserved3[8];
|
||||||
u32 cr4;
|
u32 cr4;
|
||||||
|
|
||||||
u8 reserved3[72];
|
u8 reserved4[72];
|
||||||
|
|
||||||
u32 gdtr_base;
|
u32 gdtr_base;
|
||||||
u8 reserved4[4];
|
|
||||||
u32 idtr_base;
|
|
||||||
u8 reserved5[4];
|
u8 reserved5[4];
|
||||||
|
u32 idtr_base;
|
||||||
|
u8 reserved6[4];
|
||||||
u32 ldtr_base;
|
u32 ldtr_base;
|
||||||
|
|
||||||
u8 reserved6[68];
|
u8 reserved7[56];
|
||||||
|
/* EPTP fields are only on Haswell according to BWGs, but Intel was
|
||||||
|
* wise and reused the same revision number. */
|
||||||
|
u64 eptp;
|
||||||
|
u32 eptp_en;
|
||||||
u32 cs_base;
|
u32 cs_base;
|
||||||
u8 reserved7[4];
|
u8 reserved8[4];
|
||||||
u32 iedbase;
|
u32 iedbase;
|
||||||
|
|
||||||
u8 reserved8[8];
|
u8 reserved9[8];
|
||||||
|
|
||||||
u32 smbase;
|
u32 smbase;
|
||||||
u32 smm_revision;
|
u32 smm_revision;
|
||||||
|
@ -245,7 +258,7 @@ typedef struct {
|
||||||
u16 io_restart;
|
u16 io_restart;
|
||||||
u16 autohalt_restart;
|
u16 autohalt_restart;
|
||||||
|
|
||||||
u8 reserved9[24];
|
u8 reserved10[24];
|
||||||
|
|
||||||
u64 r15;
|
u64 r15;
|
||||||
u64 r14;
|
u64 r14;
|
||||||
|
|
|
@ -432,7 +432,7 @@ static void southbridge_smi_sleep(unsigned int node, smm_state_save_area_t *stat
|
||||||
static em64t101_smm_state_save_area_t *smi_apmc_find_state_save(u8 cmd)
|
static em64t101_smm_state_save_area_t *smi_apmc_find_state_save(u8 cmd)
|
||||||
{
|
{
|
||||||
em64t101_smm_state_save_area_t *state;
|
em64t101_smm_state_save_area_t *state;
|
||||||
u32 base = smi_get_tseg_base() + 0x8000 + 0x7d00;
|
u32 base = smi_get_tseg_base() + SMM_EM64T101_SAVE_STATE_OFFSET;
|
||||||
int node;
|
int node;
|
||||||
|
|
||||||
/* Check all nodes looking for the one that issued the IO */
|
/* Check all nodes looking for the one that issued the IO */
|
||||||
|
|
Loading…
Reference in New Issue