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 <soc/nvs.h>
9 #include <ec/acpi/ec.h>
10 #include <option.h>
11 #include <ec/lenovo/h8/h8.h>
12 #include <delay.h>
13 #include "dock.h"
14 #include "smi.h"
15 
16 #define GPE_EC_SCI 12
17 
18 static void mainboard_smi_save_cmos(void)
19 {
20  u8 tmp70, tmp72;
21 
22  tmp70 = inb(0x70);
23  tmp72 = inb(0x72);
24 
25  set_uint_option("tft_brightness", pci_read_config8(PCI_DEV(0, 2, 1), 0xf4));
27 
28  outb(tmp70, 0x70);
29  outb(tmp72, 0x72);
30 }
31 
33 {
34  switch (smif) {
35  case SMI_DOCK_CONNECT:
36  ec_clr_bit(0x03, 2);
37  mdelay(250);
38  if (!dock_connect()) {
39  ec_set_bit(0x03, 2);
40  /* set dock LED to indicate status */
41  ec_write(0x0c, 0x09);
42  ec_write(0x0c, 0x88);
43  } else {
44  /* blink dock LED to indicate failure */
45  ec_write(0x0c, 0x08);
46  ec_write(0x0c, 0xc9);
47  }
48  break;
49 
51  ec_clr_bit(0x03, 2);
53  break;
54 
55  case SMI_SAVE_CMOS:
57  break;
58  default:
59  return 0;
60  }
61 
62  /* On success, the IO Trap Handler returns 1
63  * On failure, the IO Trap Handler returns a value != 1 */
64  return 1;
65 }
66 
67 static void mainboard_smi_brightness_up(void)
68 {
69  u8 value;
70 
71  if ((value = pci_read_config8(PCI_DEV(0, 2, 1), 0xf4)) < 0xf0)
72  pci_write_config8(PCI_DEV(0, 2, 1), 0xf4, (value + 0x10) | 0xf);
73 }
74 
76 {
77  u8 value;
78 
79  if ((value = pci_read_config8(PCI_DEV(0, 2, 1), 0xf4)) > 0x10)
80  pci_write_config8(PCI_DEV(0, 2, 1), 0xf4, (value - 0x10) & 0xf0);
81 }
82 
83 static void mainboard_smi_handle_ec_sci(void)
84 {
85  u8 status = inb(EC_SC);
86  u8 event;
87 
88  if (!(status & EC_SCI_EVT))
89  return;
90 
91  event = ec_query();
92  printk(BIOS_DEBUG, "EC event %#02x\n", event);
93 
94  switch (event) {
95  /* brightness up */
96  case 0x14:
99  break;
100  /* brightness down */
101  case 0x15:
104  break;
105  /* Fn-F9 key */
106  case 0x18:
107  /* Power loss */
108  case 0x27:
109  /* Undock Key */
110  case 0x50:
112  break;
113  /* Dock Event */
114  case 0x37:
115  case 0x58:
117  break;
118  default:
119  break;
120  }
121 }
122 
124 {
125  if (gpi & (1 << GPE_EC_SCI))
127 }
128 
130 {
131  switch (data) {
132  case APM_CNT_ACPI_ENABLE:
133  /* use 0x1600/0x1604 to prevent races with userspace */
134  ec_set_ports(0x1604, 0x1600);
135  /* route H8SCI to SCI */
137  /* discard all events, and enable attention */
138  ec_write(0x80, 0x01);
139  break;
141  /* we have to use port 0x62/0x66, as 0x1600/0x1604 doesn't
142  provide a EC query function */
143  ec_set_ports(0x66, 0x62);
144  /* route H8SCI# to SMI */
146  /* discard all events, and enable attention */
147  ec_write(0x80, 0x01);
148  break;
149  default:
150  break;
151  }
152  return 0;
153 }
pte_t value
Definition: mmu.c:91
#define printk(level,...)
Definition: stdlib.h:16
int __weak mainboard_smi_apmc(u8 data)
Definition: smihandler.c:209
void __weak mainboard_smi_gpi(u32 gpi_sts)
Definition: smihandler.c:208
int __weak mainboard_io_trap_handler(int smif)
Definition: smihandler.c:206
void mdelay(unsigned int msecs)
Definition: delay.c:2
u8 inb(u16 port)
void outb(u8 val, 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 H8_VOLUME_CONTROL
Definition: h8.h:94
#define APM_CNT_ACPI_DISABLE
Definition: smm.h:21
#define APM_CNT_ACPI_ENABLE
Definition: smm.h:22
static __always_inline u8 pci_read_config8(const struct device *dev, u16 reg)
Definition: pci_ops.h:46
static __always_inline void pci_write_config8(const struct device *dev, u16 reg, u8 val)
Definition: pci_ops.h:64
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define GPI_IS_SMI
Definition: smihandler.c:34
#define GPI_IS_SCI
Definition: smihandler.c:35
#define SMI_DOCK_DISCONNECT
Definition: smi.h:7
#define SMI_DOCK_CONNECT
Definition: smi.h:6
#define SMI_SAVE_CMOS
Definition: smi.h:8
static void mainboard_smi_save_cmos(void)
Definition: smihandler.c:18
static void mainboard_smi_handle_ec_sci(void)
Definition: smihandler.c:83
static void mainboard_smi_brightness_up(void)
Definition: smihandler.c:67
static void mainboard_smi_brightness_down(void)
Definition: smihandler.c:75
#define GPE_EC_SCI
Definition: smihandler.c:16
enum cb_err set_uint_option(const char *name, unsigned int value)
Definition: option.c:189
#define PCI_DEV(SEGBUS, DEV, FN)
Definition: pci_type.h:14
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