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 <console/console.h>
5 #include <cpu/x86/smm.h>
8 #include <ec/acpi/ec.h>
9 #include <ec/lenovo/h8/h8.h>
10 #include <delay.h>
11 #include "dock.h"
12 
13 #define GPE_EC_SCI 1
14 #define GPE_EC_WAKE 13
15 
16 static void mainboard_smi_handle_ec_sci(void)
17 {
18  u8 status = inb(EC_SC);
19  u8 event;
20 
21  if (!(status & EC_SCI_EVT))
22  return;
23 
24  event = ec_query();
25  printk(BIOS_DEBUG, "EC event %#02x\n", event);
26 
27  switch (event) {
28  case 0x18:
29  /* Fn-F9 key */
30  case 0x27:
31  /* Power loss */
32  case 0x50:
33  /* Undock Key */
34  ec_clr_bit(0x03, 2);
36  break;
37  case 0x37:
38  case 0x58:
39  /* Dock Event */
40  ec_clr_bit(0x03, 2);
41  mdelay(250);
42  dock_connect();
43  ec_set_bit(0x03, 2);
44  /* set dock LED to indicate status */
45  ec_write(0x0c, 0x09);
46  ec_write(0x0c, 0x88);
47  break;
48  default:
49  break;
50  }
51 }
52 
53 void mainboard_smi_gpi(u32 gpi_sts)
54 {
55  if (gpi_sts & (1 << GPE_EC_SCI))
57 }
58 
60 {
61  switch (data) {
63  /* use 0x1600/0x1604 to prevent races with userspace */
64  ec_set_ports(0x1604, 0x1600);
65  /* route H8SCI to SCI */
67  /* discard all events, and enable attention */
68  ec_write(0x80, 0x01);
69  break;
71  /* we have to use port 0x62/0x66, as 0x1600/0x1604 doesn't
72  provide a EC query function */
73  ec_set_ports(0x66, 0x62);
74  /* route H8SCI# to SMI */
76  /* discard all events, and enable attention */
77  ec_write(0x80, 0x01);
78  break;
79  default:
80  break;
81  }
82  return 0;
83 }
84 
85 void mainboard_smi_sleep(u8 slp_typ)
86 {
87  if (slp_typ == 3) {
88  u8 ec_wake = ec_read(0x32);
89  /* If EC wake events are enabled, enable wake on EC WAKE GPE. */
90  if (ec_wake & 0x14) {
91  /* Redirect EC WAKE GPE to SCI. */
93  }
94  }
95 }
#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
void mdelay(unsigned int msecs)
Definition: delay.c:2
u8 inb(u16 port)
void ec_set_bit(u8 addr, u8 bit)
Definition: ec.c:133
u8 ec_read(u8 addr)
Definition: ec.c:107
void ec_clr_bit(u8 addr, u8 bit)
Definition: ec.c:138
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
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
static void mainboard_smi_handle_ec_sci(void)
Definition: smihandler.c:16
#define GPE_EC_WAKE
Definition: smihandler.c:14
#define GPE_EC_SCI
Definition: smihandler.c:13
#define GPI_IS_SMI
Definition: smihandler.c:34
#define GPI_IS_SCI
Definition: smihandler.c:35
void gpi_route_interrupt(u8 gpi, u8 mode)
Definition: smihandler.c:25
uint32_t u32
Definition: stdint.h:51
uint8_t u8
Definition: stdint.h:45
void dock_connect(void)
Definition: dock.c:215
void dock_disconnect(void)
Definition: dock.c:234