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-only */
2 
3 #include <arch/io.h>
4 #include <device/pci_ops.h>
5 #include <console/console.h>
6 #include <cpu/x86/smm.h>
7 #include <ec/acpi/ec.h>
8 #include <ec/lenovo/h8/h8.h>
10 
11 #define GPE_EC_SCI 1
12 #define GPE_EC_WAKE 13
13 
14 static void mainboard_smi_handle_ec_sci(void)
15 {
16  u8 status = inb(EC_SC);
17  u8 event;
18 
19  if (!(status & EC_SCI_EVT))
20  return;
21 
22  event = ec_query();
23  printk(BIOS_DEBUG, "EC event %#02x\n", event);
24 }
25 
26 void mainboard_smi_gpi(u32 gpi_sts)
27 {
28  if (gpi_sts & (1 << GPE_EC_SCI))
30 }
31 
32 /* lynxpoint doesn't have gpi_route_interrupt, so add it */
33 #define GPI_DISABLE 0x00
34 #define GPI_IS_SMI 0x01
35 #define GPI_IS_SCI 0x02
36 #define GPI_IS_NMI 0x03
37 
38 static void gpi_route_interrupt(u8 gpi, u8 mode)
39 {
40  u32 gpi_rout;
41 
42  gpi_rout = pci_read_config32(PCI_DEV(0, 0x1f, 0), GPIO_ROUT);
43  gpi_rout &= ~(3 << (2 * gpi));
44  gpi_rout |= ((mode & 3) << (2 * gpi));
45  pci_write_config32(PCI_DEV(0, 0x1f, 0), GPIO_ROUT, gpi_rout);
46 }
47 
49 {
50  switch (data) {
52  /* use 0x1600/0x1604 to prevent races with userspace */
53  ec_set_ports(0x1604, 0x1600);
54  /* route EC_SCI to SCI */
56  /* discard all events, and enable attention */
57  ec_write(0x80, 0x01);
58  break;
60  /* we have to use port 0x62/0x66, as 0x1600/0x1604 doesn't
61  provide a EC query function */
62  ec_set_ports(0x66, 0x62);
63  /* route EC_SCI to SMI */
65  /* discard all events, and enable attention */
66  ec_write(0x80, 0x01);
67  break;
68  default:
69  break;
70  }
71  return 0;
72 }
73 
74 void mainboard_smi_sleep(u8 slp_typ)
75 {
76  if (slp_typ == 3) {
77  u8 ec_wake = ec_read(0x32);
78  /* If EC wake events are enabled,
79  * enable wake on EC WAKE GPE. */
80  if (ec_wake & 0x14) {
81  /* Redirect EC WAKE GPE to SCI. */
83  }
84  }
85 }
#define GPIO_ROUT
Definition: pm.h:96
#define printk(level,...)
Definition: stdlib.h:16
void __weak mainboard_smi_sleep(u8 slp_typ)
Definition: smihandler.c:210
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)
u8 ec_read(u8 addr)
Definition: ec.c:107
u8 ec_query(void)
Definition: ec.c:127
void ec_set_ports(u16 cmd_reg, u16 data_reg)
Definition: ec.c:143
int ec_write(u8 addr, u8 data)
Definition: ec.c:115
#define EC_SC
Definition: ec.h:9
#define EC_SCI_EVT
Definition: ec.h:13
#define APM_CNT_ACPI_DISABLE
Definition: smm.h:21
#define APM_CNT_ACPI_ENABLE
Definition: smm.h:22
static __always_inline void pci_write_config32(const struct device *dev, u16 reg, u32 val)
Definition: pci_ops.h:76
static __always_inline u32 pci_read_config32(const struct device *dev, u16 reg)
Definition: pci_ops.h:58
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
static void gpi_route_interrupt(u8 gpi, u8 mode)
Definition: smihandler.c:38
static void mainboard_smi_handle_ec_sci(void)
Definition: smihandler.c:14
#define GPI_IS_SMI
Definition: smihandler.c:34
#define GPE_EC_WAKE
Definition: smihandler.c:12
#define GPE_EC_SCI
Definition: smihandler.c:11
#define GPI_IS_SCI
Definition: smihandler.c:35
#define PCI_DEV(SEGBUS, DEV, FN)
Definition: pci_type.h:14
uint32_t u32
Definition: stdint.h:51
uint8_t u8
Definition: stdint.h:45