aboutsummaryrefslogtreecommitdiff
path: root/src/soc/intel/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc/intel/common')
-rw-r--r--src/soc/intel/common/Makefile.inc2
-rw-r--r--src/soc/intel/common/block/include/intelblocks/smihandler.h (renamed from src/soc/intel/common/smi.h)49
-rw-r--r--src/soc/intel/common/block/include/intelblocks/smm.h34
-rw-r--r--src/soc/intel/common/block/smm/Kconfig4
-rw-r--r--src/soc/intel/common/block/smm/Makefile.inc2
-rw-r--r--src/soc/intel/common/block/smm/smihandler.c (renamed from src/soc/intel/common/smihandler.c)31
-rw-r--r--src/soc/intel/common/block/smm/smm.c78
7 files changed, 168 insertions, 32 deletions
diff --git a/src/soc/intel/common/Makefile.inc b/src/soc/intel/common/Makefile.inc
index 340e001d2d..110977585d 100644
--- a/src/soc/intel/common/Makefile.inc
+++ b/src/soc/intel/common/Makefile.inc
@@ -31,8 +31,6 @@ ramstage-$(CONFIG_SOC_INTEL_COMMON_GFX_OPREGION) += opregion.c
ramstage-$(CONFIG_SOC_INTEL_COMMON_ACPI) += ./acpi/acpi.c
ramstage-$(CONFIG_SOC_INTEL_COMMON_NHLT) += nhlt.c
-smm-$(CONFIG_SOC_INTEL_COMMON_SMI) += smihandler.c
-
bootblock-$(CONFIG_MAINBOARD_HAS_TPM_CR50) += tpm_tis.c
verstage-$(CONFIG_MAINBOARD_HAS_TPM_CR50) += tpm_tis.c
romstage-$(CONFIG_MAINBOARD_HAS_TPM_CR50) += tpm_tis.c
diff --git a/src/soc/intel/common/smi.h b/src/soc/intel/common/block/include/intelblocks/smihandler.h
index 22c510435b..b587bb136d 100644
--- a/src/soc/intel/common/smi.h
+++ b/src/soc/intel/common/block/include/intelblocks/smihandler.h
@@ -13,8 +13,13 @@
* GNU General Public License for more details.
*/
-#ifndef _INTEL_COMMON_SMI_H_
-#define _INTEL_COMMON_SMI_H_
+#ifndef SOC_INTEL_COMMON_BLOCK_SMI_HANDLER_H
+#define SOC_INTEL_COMMON_BLOCK_SMI_HANDLER_H
+
+#include <stdint.h>
+
+struct gpi_status;
+struct global_nvs_t;
/*
* The register value is used with get_reg and set_reg
@@ -26,8 +31,7 @@ enum smm_reg {
RDX,
};
-
-struct smm_save_state_ops {
+struct smm_save_state_ops {
/* return io_misc_info from SMM Save State Area */
uint32_t (*get_io_misc_info)(void *state);
@@ -50,63 +54,72 @@ const struct smm_save_state_ops *get_smm_save_state_ops(void);
/*
* southbridge_smi should be defined inside SOC specific code and should have
* handlers for any SMI events that need to be handled. Default handlers
- * for some SMI events are provided in soc/intel/common/smihandler.c
+ * for some SMI events are provided in soc/intel/common/block/smm/smihandler.c
*/
extern const smi_handler_t southbridge_smi[32];
/*
* This function should be implemented in SOC specific code to handle
* the SMI event on SLP_EN. The default functionality is provided in
- * soc/intel/common/smihandler.c
+ * soc/intel/common/block/smm/smihandler.c
*/
-void southbridge_smi_sleep(const struct smm_save_state_ops *save_state_ops);
+void smihandler_southbridge_sleep(
+ const struct smm_save_state_ops *save_state_ops);
/*
* This function should be implemented in SOC specific code to handle
* SMI_APM event. The default functionality is provided in
- * soc/intel/common/smihandler.c
+ * soc/intel/common/block/smm/smihandler.c
*/
-void southbridge_smi_apmc(const struct smm_save_state_ops *save_state_ops);
+void smihandler_southbridge_apmc(
+ const struct smm_save_state_ops *save_state_ops);
/*
* This function should be implemented in SOC specific code to handle
* SMI_PM1 event. The default functionality is provided in
- * soc/intel/common/smihandler.c
+ * soc/intel/common/block/smm/smihandler.c
*/
-void southbridge_smi_pm1(const struct smm_save_state_ops *save_state_ops);
+void smihandler_southbridge_pm1(
+ const struct smm_save_state_ops *save_state_ops);
/*
* This function should be implemented in SOC specific code to handle
* SMI_GPE0 event. The default functionality is provided in
- * soc/intel/common/smihandler.c
+ * soc/intel/common/block/smm/smihandler.c
*/
-void southbridge_smi_gpe0(const struct smm_save_state_ops *save_state_ops);
+void smihandler_southbridge_gpe0(
+ const struct smm_save_state_ops *save_state_ops);
/*
* This function should be implemented in SOC specific code to handle
* SMI_TCO event. The default functionality is provided in
- * soc/intel/common/smihandler.c
+ * soc/intel/common/block/smm/smihandler.c
*/
-void southbridge_smi_tco(const struct smm_save_state_ops *save_state_ops);
+void smihandler_southbridge_tco(
+ const struct smm_save_state_ops *save_state_ops);
/*
* This function should be implemented in SOC specific code to handle
* SMI PERIODIC_STS event. The default functionality is provided in
- * soc/intel/common/smihandler.c
+ * soc/intel/common/block/smm/smihandler.c
*/
-void southbridge_smi_periodic(const struct smm_save_state_ops *save_state_ops);
+void smihandler_southbridge_periodic(
+ const struct smm_save_state_ops *save_state_ops);
/*
* This function returns a 1 or 0 depending on whether disable_busmaster
* needs to be done for the specified device on S5 entry
*/
-int smm_disable_busmaster(device_t dev);
+int smihandler_disable_busmaster(device_t dev);
/*
* Returns gnvs pointer within SMM context
*/
struct global_nvs_t *smm_get_gnvs(void);
+/* Mainboard handler for GPI SMIs */
+void mainboard_smi_gpi_handler(const struct gpi_status *sts);
+
extern const struct smm_save_state_ops em64t100_smm_ops;
extern const struct smm_save_state_ops em64t101_smm_ops;
diff --git a/src/soc/intel/common/block/include/intelblocks/smm.h b/src/soc/intel/common/block/include/intelblocks/smm.h
new file mode 100644
index 0000000000..09378b9463
--- /dev/null
+++ b/src/soc/intel/common/block/include/intelblocks/smm.h
@@ -0,0 +1,34 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 201 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef SOC_INTEL_COMMON_BLOCK_SMM_H
+#define SOC_INTEL_COMMON_BLOCK_SMM_H
+
+/*
+ * This common code block relies on each specific SOC defining the macro
+ * ENABLE_SMI_PARAMS for the values needed for SMI enabling on the
+ * specific SOC
+ */
+
+/*
+ * The initialization of the southbridge is split into 2 compoments. One is
+ * for clearing the state in the SMM registers. The other is for enabling
+ * SMIs.
+ */
+void smm_southbridge_clear_state(void);
+void smm_southbridge_enable(void);
+
+#endif
diff --git a/src/soc/intel/common/block/smm/Kconfig b/src/soc/intel/common/block/smm/Kconfig
new file mode 100644
index 0000000000..003fc24cd8
--- /dev/null
+++ b/src/soc/intel/common/block/smm/Kconfig
@@ -0,0 +1,4 @@
+config SOC_INTEL_COMMON_BLOCK_SMM
+ bool
+ help
+ Intel Processor common SMM support
diff --git a/src/soc/intel/common/block/smm/Makefile.inc b/src/soc/intel/common/block/smm/Makefile.inc
new file mode 100644
index 0000000000..13793ee891
--- /dev/null
+++ b/src/soc/intel/common/block/smm/Makefile.inc
@@ -0,0 +1,2 @@
+ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_SMM) += smm.c
+smm-$(CONFIG_SOC_INTEL_COMMON_BLOCK_SMM) += smihandler.c
diff --git a/src/soc/intel/common/smihandler.c b/src/soc/intel/common/block/smm/smihandler.c
index 88ea819012..b620ff9f1e 100644
--- a/src/soc/intel/common/smihandler.c
+++ b/src/soc/intel/common/block/smm/smihandler.c
@@ -21,6 +21,7 @@
#include <cpu/x86/smm.h>
#include <device/pci_def.h>
#include <elog.h>
+#include <intelblocks/smihandler.h>
#include <soc/nvs.h>
#include <soc/pm.h>
#include <soc/gpio.h>
@@ -28,18 +29,17 @@
#include <spi-generic.h>
#include <stdint.h>
#include <stdlib.h>
-#include "smi.h"
/* GNVS needs to be set by coreboot initiating a software SMI. */
static struct global_nvs_t *gnvs;
-__attribute__((weak)) int smm_disable_busmaster(device_t dev)
+__attribute__((weak)) int smihandler_disable_busmaster(device_t dev)
{
return 1;
}
static void *find_save_state(const struct smm_save_state_ops *save_state_ops,
- int cmd)
+ int cmd)
{
int node;
void *state = NULL;
@@ -70,6 +70,7 @@ static void *find_save_state(const struct smm_save_state_ops *save_state_ops,
return state;
}
+/* Inherited from cpu/x86/smm.h resulting in a different signature */
void southbridge_smi_set_eos(void)
{
enable_smi(EOS);
@@ -91,7 +92,7 @@ static void busmaster_disable_on_bus(int bus)
u32 reg32;
device_t dev = PCI_DEV(bus, slot, func);
- if (!smm_disable_busmaster(dev))
+ if (!smihandler_disable_busmaster(dev))
continue;
val = pci_read_config32(dev, PCI_VENDOR_ID);
@@ -127,7 +128,8 @@ static void busmaster_disable_on_bus(int bus)
}
-void southbridge_smi_sleep(const struct smm_save_state_ops *save_state_ops)
+void smihandler_southbridge_sleep(
+ const struct smm_save_state_ops *save_state_ops)
{
uint32_t reg32;
uint8_t slp_typ;
@@ -205,8 +207,8 @@ void southbridge_smi_sleep(const struct smm_save_state_ops *save_state_ops)
}
}
-static void southbridge_smi_gsmi(const struct
- smm_save_state_ops *save_state_ops)
+static void southbridge_smi_gsmi(
+ const struct smm_save_state_ops *save_state_ops)
{
u8 sub_command, ret;
void *io_smi = NULL;
@@ -239,7 +241,8 @@ static void finalize(void)
}
-void southbridge_smi_apmc(const struct smm_save_state_ops *save_state_ops)
+void smihandler_southbridge_apmc(
+ const struct smm_save_state_ops *save_state_ops)
{
uint8_t reg8;
void *state = NULL;
@@ -300,7 +303,8 @@ void southbridge_smi_apmc(const struct smm_save_state_ops *save_state_ops)
mainboard_smi_apmc(reg8);
}
-void southbridge_smi_pm1(const struct smm_save_state_ops *save_state_ops)
+void smihandler_southbridge_pm1(
+ const struct smm_save_state_ops *save_state_ops)
{
uint16_t pm1_sts = clear_pm1_status();
@@ -317,12 +321,14 @@ void southbridge_smi_pm1(const struct smm_save_state_ops *save_state_ops)
}
}
-void southbridge_smi_gpe0(const struct smm_save_state_ops *save_state_ops)
+void smihandler_southbridge_gpe0(
+ const struct smm_save_state_ops *save_state_ops)
{
clear_gpe_status();
}
-void southbridge_smi_tco(const struct smm_save_state_ops *save_state_ops)
+void smihandler_southbridge_tco(
+ const struct smm_save_state_ops *save_state_ops)
{
uint32_t tco_sts = clear_tco_status();
@@ -336,7 +342,8 @@ void southbridge_smi_tco(const struct smm_save_state_ops *save_state_ops)
}
}
-void southbridge_smi_periodic(const struct smm_save_state_ops *save_state_ops)
+void smihandler_southbridge_periodic(
+ const struct smm_save_state_ops *save_state_ops)
{
uint32_t reg32;
diff --git a/src/soc/intel/common/block/smm/smm.c b/src/soc/intel/common/block/smm/smm.c
new file mode 100644
index 0000000000..ab60af615d
--- /dev/null
+++ b/src/soc/intel/common/block/smm/smm.c
@@ -0,0 +1,78 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <console/console.h>
+#include <cpu/x86/smm.h>
+#include <intelblocks/smm.h>
+#include <soc/pm.h>
+
+void smm_southbridge_clear_state(void)
+{
+ printk(BIOS_DEBUG, "Clearing SMI status registers\n");
+
+ if (get_smi_en() & APMC_EN) {
+ printk(BIOS_INFO, "SMI# handler already enabled?\n");
+ return;
+ }
+
+ /* Dump and clear status registers */
+ clear_smi_status();
+ clear_pm1_status();
+ clear_tco_status();
+ clear_gpe_status();
+}
+
+void smm_southbridge_enable(void)
+{
+ printk(BIOS_DEBUG, "Enabling SMIs.\n");
+ /* Configure events */
+ enable_pm1(PWRBTN_EN | GBL_EN);
+ disable_gpe(PME_B0_EN);
+
+ /*
+ * Enable SMI generation:
+ * - on APMC writes (io 0xb2)
+ * - on writes to SLP_EN (sleep states)
+ * - on writes to GBL_RLS (bios commands)
+ * - on eSPI events (does nothing on LPC systems)
+ * No SMIs:
+ * - on microcontroller writes (io 0x62/0x66)
+ * - on TCO events
+ */
+
+ /* Enable SMI generation: */
+ enable_smi(ENABLE_SMI_PARAMS);
+}
+
+void smm_setup_structures(void *gnvs, void *tcg, void *smi1)
+{
+ /*
+ * Issue SMI to set the gnvs pointer in SMM.
+ * tcg and smi1 are unused.
+ *
+ * EAX = APM_CNT_GNVS_UPDATE
+ * EBX = gnvs pointer
+ * EDX = APM_CNT
+ */
+ asm volatile (
+ "outb %%al, %%dx\n\t"
+ : /* ignore result */
+ : "a" (APM_CNT_GNVS_UPDATE),
+ "b" ((u32)gnvs),
+ "d" (APM_CNT)
+ );
+}