coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
smm.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <arch/io.h>
4 #include <device/mmio.h>
5 #include <console/console.h>
6 #include <cpu/x86/smm.h>
7 #include <cpu/intel/smm_reloc.h>
8 #include <device/device.h>
9 #include <device/pci.h>
10 #include <soc/iomap.h>
11 #include <soc/pm.h>
12 #include <soc/smm.h>
13 
14 /* Save settings which will be committed in SMI functions. */
16 
18 {
19  smm_save_params[param] = data;
20 }
21 
23 {
24  uint32_t smi_en;
25 
26  /* Log events from chipset before clearing */
27  if (CONFIG(ELOG))
29 
30  printk(BIOS_DEBUG, "Initializing Southbridge SMI...");
31  printk(BIOS_SPEW, " pmbase = 0x%04x\n", get_pmbase());
32 
33  smi_en = inl(get_pmbase() + SMI_EN);
34  if (smi_en & APMC_EN) {
35  printk(BIOS_INFO, "SMI# handler already enabled?\n");
36  return;
37  }
38 
39  /* Dump and clear status registers */
46 }
47 
49 {
50  void *gpio_rout = (void *)(PMC_BASE_ADDRESS + GPIO_ROUT);
51  const unsigned short alt_gpio_smi = ACPI_BASE_ADDRESS + ALT_GPIO_SMI;
52  uint32_t alt_gpio_reg = 0;
54  int i;
55 
56  printk(BIOS_DEBUG, "GPIO_ROUT = %08x\n", route_reg);
57 
58  /* Start the routing for the specific gpios. */
59  write32(gpio_rout, route_reg);
60 
61  /* Enable SMIs for the gpios that are set to trigger the SMI. */
62  for (i = 0; i < 16; i++) {
63  if ((route_reg & ROUTE_MASK) == ROUTE_SMI)
64  alt_gpio_reg |= (1 << i);
65 
66  route_reg >>= 2;
67  }
68  printk(BIOS_DEBUG, "ALT_GPIO_SMI = %08x\n", alt_gpio_reg);
69 
70  outl(alt_gpio_reg, alt_gpio_smi);
71 }
72 
73 static void smm_southbridge_enable(uint16_t pm1_events)
74 {
75 
76  printk(BIOS_DEBUG, "Enabling SMIs.\n");
78  pm1_events |= PCIEXPWAK_DIS;
79 
80  enable_pm1(pm1_events);
82 
83  /* Set up the GPIO route. */
85 
86  /*
87  * Enable SMI generation:
88  * - on APMC writes (io 0xb2)
89  * - on writes to SLP_EN (sleep states)
90  * - on writes to GBL_RLS (bios commands)
91  * No SMIs:
92  * - on TCO events
93  * - on microcontroller writes (io 0x62/0x66)
94  */
96 }
97 
99 {
101 }
uint16_t get_pmbase(void)
Definition: pmutil.c:254
#define GBL_SMI_EN
Definition: pm.h:49
#define APMC_EN
Definition: pm.h:44
#define SLP_SMI_EN
Definition: pm.h:45
#define PME_B0_EN
Definition: pm.h:104
#define SMI_EN
Definition: pm.h:32
#define EOS
Definition: pm.h:48
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
#define GPIO_ROUT
Definition: pm.h:96
void enable_pm1(uint16_t events)
Definition: pmutil.c:157
uint16_t clear_pm1_status(void)
Definition: pmutil.c:152
#define ALT_GPIO_SMI
Definition: pm.h:220
uint32_t clear_alt_status(void)
Definition: pmutil.c:312
void enable_smi(uint32_t mask)
Definition: pmutil.c:89
#define ROUTE_MASK
Definition: pm.h:97
void clear_pmc_status(void)
Definition: pmutil.c:317
uint32_t clear_gpe_status(void)
Definition: pmutil.c:265
uint32_t clear_tco_status(void)
Definition: pmutil.c:189
uint32_t clear_smi_status(void)
Definition: pmutil.c:84
void disable_gpe(uint32_t mask)
Definition: pmutil.c:202
#define ROUTE_SMI
Definition: pm.h:99
void smm_southcluster_save_param(int param, uint32_t data)
Definition: smm.c:17
void global_smi_enable(void)
Set the EOS bit and enable SMI generation from southbridge.
Definition: smm.c:98
void smm_southbridge_clear_state(void)
Definition: smm.c:22
static void smm_southbridge_enable(uint16_t pm1_events)
Definition: smm.c:73
static uint32_t smm_save_params[SMM_SAVE_PARAM_COUNT]
Definition: smm.c:15
static void smm_southcluster_route_gpios(void)
Definition: smm.c:48
#define PWRBTN_EN
Definition: southbridge.h:36
#define GBL_EN
Definition: southbridge.h:37
#define PCIEXPWAK_DIS
Definition: southbridge.h:34
#define printk(level,...)
Definition: stdlib.h:16
u32 inl(u16 port)
void outl(u32 val, u16 port)
@ CONFIG
Definition: dsi_common.h:201
#define ACPI_BASE_ADDRESS
Definition: iomap.h:99
#define PMC_BASE_ADDRESS
Definition: iomap.h:15
#define BIOS_INFO
BIOS_INFO - Expected events.
Definition: loglevel.h:113
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define BIOS_SPEW
BIOS_SPEW - Excessively verbose output.
Definition: loglevel.h:142
void southcluster_log_state(void)
Definition: elog.c:76
@ SMM_SAVE_PARAM_COUNT
Definition: smm.h:11
@ SMM_SAVE_PARAM_GPIO_ROUTE
Definition: smm.h:9
@ SMM_SAVE_PARAM_PCIE_WAKE_ENABLE
Definition: smm.h:10
unsigned short uint16_t
Definition: stdint.h:11
unsigned int uint32_t
Definition: stdint.h:14