coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
smihandler.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 /*
4  * SMI handler for Hudson southbridges
5  */
6 
7 #include <amdblocks/acpimmio.h>
8 #include <arch/io.h>
9 #include <cpu/x86/smm.h>
10 
11 #include "hudson.h"
12 #include "smi.h"
13 
14 #define SMI_0x88_ACPI_COMMAND (1 << 11)
15 
16 enum smi_source {
17  SMI_SOURCE_SCI = (1 << 0),
18  SMI_SOURCE_GPE = (1 << 1),
19  SMI_SOURCE_0x84 = (1 << 2),
20  SMI_SOURCE_0x88 = (1 << 3),
21  SMI_SOURCE_IRQ_TRAP = (1 << 4),
22  SMI_SOURCE_0x90 = (1 << 5)
23 };
24 
25 static void hudson_apmc_smi_handler(void)
26 {
27  u32 reg32;
28  const uint8_t cmd = inb(ACPI_SMI_CTL_PORT);
29 
30  switch (cmd) {
32  reg32 = inl(ACPI_PM1_CNT_BLK);
33  reg32 |= (1 << 0); /* SCI_EN */
34  outl(reg32, ACPI_PM1_CNT_BLK);
35  break;
37  reg32 = inl(ACPI_PM1_CNT_BLK);
38  reg32 &= ~(1 << 0); /* clear SCI_EN */
39  outl(ACPI_PM1_CNT_BLK, reg32);
40  break;
41  }
42 
43  mainboard_smi_apmc(cmd);
44 }
45 
47 {
48  return 0;
49 }
50 
51 static void process_smi_sci(void)
52 {
53  const uint32_t status = smi_read32(0x10);
54 
55  /* Clear events to prevent re-entering SMI if event isn't handled */
56  smi_write32(0x10, status);
57 }
58 
59 static void process_gpe_smi(void)
60 {
61  const uint32_t status = smi_read32(0x80);
62  const uint32_t gevent_mask = (1 << 24) - 1;
63 
64  /* Only Bits [23:0] indicate GEVENT SMIs. */
65  if (status & gevent_mask) {
66  /* A GEVENT SMI occurred */
67  mainboard_smi_gpi(status & gevent_mask);
68  }
69 
70  /* Clear events to prevent re-entering SMI if event isn't handled */
71  smi_write32(0x80, status);
72 }
73 
74 static void process_smi_0x84(void)
75 {
76  const uint32_t status = smi_read32(0x84);
77 
78  /* Clear events to prevent re-entering SMI if event isn't handled */
79  smi_write32(0x84, status);
80 }
81 
82 static void process_smi_0x88(void)
83 {
84  const uint32_t status = smi_read32(0x88);
85 
86  if (status & SMI_0x88_ACPI_COMMAND) {
87  /* Command received via ACPI SMI command port */
89  }
90  /* Clear events to prevent re-entering SMI if event isn't handled */
91  smi_write32(0x88, status);
92 }
93 
94 static void process_smi_0x8c(void)
95 {
96  const uint32_t status = smi_read32(0x8c);
97 
98  /* Clear events to prevent re-entering SMI if event isn't handled */
99  smi_write32(0x8c, status);
100 }
101 
102 static void process_smi_0x90(void)
103 {
104  const uint32_t status = smi_read32(0x90);
105 
106  /* Clear events to prevent re-entering SMI if event isn't handled */
107  smi_write32(0x90, status);
108 }
109 
111 {
112  const uint16_t smi_src = smi_read16(0x94);
113 
114  if (smi_src & SMI_SOURCE_SCI)
115  process_smi_sci();
116  if (smi_src & SMI_SOURCE_GPE)
117  process_gpe_smi();
118  if (smi_src & SMI_SOURCE_0x84)
120  if (smi_src & SMI_SOURCE_0x88)
122  if (smi_src & SMI_SOURCE_IRQ_TRAP)
124  if (smi_src & SMI_SOURCE_0x90)
126 }
127 
129 {
131  reg |= SMITRG0_EOS;
133 }
static void smi_write32(uint8_t reg, uint32_t value)
Definition: acpimmio.h:161
static uint32_t smi_read32(uint8_t reg)
Definition: acpimmio.h:146
static uint16_t smi_read16(uint8_t reg)
Definition: acpimmio.h:141
#define ACPI_SMI_CMD_ENABLE
Definition: hudson.h:29
#define ACPI_SMI_CMD_DISABLE
Definition: hudson.h:28
#define ACPI_SMI_CTL_PORT
Definition: hudson.h:25
#define ACPI_PM1_CNT_BLK
Definition: iomap.h:43
void __weak southbridge_smi_handler(void)
Definition: smihandler.c:207
int __weak mainboard_smi_apmc(u8 data)
Definition: smihandler.c:209
void __weak mainboard_smi_gpi(u32 gpi_sts)
Definition: smihandler.c:208
u8 inb(u16 port)
u32 inl(u16 port)
void outl(u32 val, u16 port)
#define SMITRG0_EOS
Definition: smi.h:165
#define SMI_REG_SMITRIG0
Definition: smi.h:163
int southbridge_io_trap_handler(int smif)
Definition: smihandler.c:131
void southbridge_smi_set_eos(void)
Definition: smihandler.c:41
static void hudson_apmc_smi_handler(void)
Definition: smihandler.c:25
static void process_smi_sci(void)
Definition: smihandler.c:51
static void process_gpe_smi(void)
Definition: smihandler.c:59
static void process_smi_0x90(void)
Definition: smihandler.c:102
smi_source
Definition: smihandler.c:16
@ SMI_SOURCE_IRQ_TRAP
Definition: smihandler.c:21
@ SMI_SOURCE_SCI
Definition: smihandler.c:17
@ SMI_SOURCE_0x88
Definition: smihandler.c:20
@ SMI_SOURCE_0x84
Definition: smihandler.c:19
@ SMI_SOURCE_GPE
Definition: smihandler.c:18
@ SMI_SOURCE_0x90
Definition: smihandler.c:22
#define SMI_0x88_ACPI_COMMAND
Definition: smihandler.c:14
static void process_smi_0x88(void)
Definition: smihandler.c:82
static void process_smi_0x8c(void)
Definition: smihandler.c:94
static void process_smi_0x84(void)
Definition: smihandler.c:74
unsigned short uint16_t
Definition: stdint.h:11
unsigned int uint32_t
Definition: stdint.h:14
uint32_t u32
Definition: stdint.h:51
unsigned char uint8_t
Definition: stdint.h:8