coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
smi.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <device/device.h>
4 #include <device/pci.h>
5 #include <console/console.h>
6 #include <cpu/x86/smm.h>
7 #include <cpu/intel/smm_reloc.h>
10 
11 #include "pmutil.h"
12 
14 {
15  return lpc_get_pmbase();
16 }
17 
18 static int smi_enabled(void)
19 {
20  u32 smi_en;
21 
22  /* Log events from chipset before clearing */
23  if (CONFIG(ELOG))
24  pch_log_state();
25 
26  printk(BIOS_DEBUG, "Initializing southbridge SMI...");
27  printk(BIOS_SPEW, " ... pmbase = 0x%04x\n", lpc_get_pmbase());
28 
29  smi_en = read_pmbase32(SMI_EN);
30  if (smi_en & APMC_EN) {
31  printk(BIOS_INFO, "SMI# handler already enabled?\n");
32  return 1;
33  }
34  printk(BIOS_DEBUG, "\n");
35  return 0;
36 }
37 
38 static void smm_southbridge_enable(uint16_t pm1_events)
39 {
40  u32 smi_en;
41  u32 gpe0_en;
42 
43  /* Disable GPE0 PME_B0 */
44  gpe0_en = read_pmbase32(GPE0_EN);
45  gpe0_en &= ~PME_B0_EN;
46  write_pmbase32(GPE0_EN, gpe0_en);
47 
48  write_pmbase16(PM1_EN, pm1_events);
49 
50  /* Enable SMI generation:
51  * - on TCO events
52  * - on APMC writes (io 0xb2)
53  * - on writes to SLP_EN (sleep states)
54  * No SMIs:
55  * - on microcontroller writes (io 0x62/0x66)
56  */
57 
58  smi_en = 0; /* reset SMI enables */
59  smi_en |= TCO_EN;
60  smi_en |= APMC_EN;
61  if (CONFIG(DEBUG_PERIODIC_SMI))
62  smi_en |= PERIODIC_EN;
63  smi_en |= SLP_SMI_EN;
64 
65  /* The following need to be on for SMIs to happen */
66  smi_en |= EOS | GBL_SMI_EN;
67 
68  write_pmbase32(SMI_EN, smi_en);
69 }
70 
72 {
73  if (smi_enabled())
74  return;
75 
78 }
79 
81 {
82  if (smi_enabled())
83  return;
84 
85  /* Dump and clear status registers */
90 }
#define PM1_EN
Definition: pm.h:21
#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 GPE0_EN(x)
Definition: pm.h:99
#define SMI_EN
Definition: pm.h:32
#define EOS
Definition: pm.h:48
#define PERIODIC_EN
Definition: pm.h:39
#define TCO_EN
Definition: pm.h:211
#define PWRBTN_EN
Definition: southbridge.h:36
#define GBL_EN
Definition: southbridge.h:37
#define printk(level,...)
Definition: stdlib.h:16
@ CONFIG
Definition: dsi_common.h:201
#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 write_pmbase16(const u8 addr, const u16 val)
Definition: pmbase.c:43
u16 lpc_get_pmbase(void)
Definition: pmbase.c:19
u32 read_pmbase32(const u8 addr)
Definition: pmbase.c:57
void write_pmbase32(const u8 addr, const u32 val)
Definition: pmbase.c:36
static void pch_log_state(void *unused)
Definition: elog.c:193
void global_smi_enable(void)
Set the EOS bit and enable SMI generation from southbridge.
Definition: smi.c:53
void smm_southbridge_clear_state(void)
Definition: smi.c:13
void dump_all_status(void)
Definition: pmutil.c:216
static int smi_enabled(void)
Definition: smi.c:18
u16 get_pmbase(void)
Definition: smi.c:13
static void smm_southbridge_enable(uint16_t pm1_events)
Definition: smi.c:38
static u16 reset_pm1_status(void)
read and clear PM1_STS
Definition: smi.c:33
static u32 reset_smi_status(void)
read and clear SMI_STS
Definition: smi.c:62
static u32 reset_tco_status(void)
read and clear TCOx_STS
Definition: smi.c:167
static u32 reset_gpe0_status(void)
read and clear GPE0_STS
Definition: smi.c:103
unsigned short uint16_t
Definition: stdint.h:11
uint32_t u32
Definition: stdint.h:51
uint16_t u16
Definition: stdint.h:48