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>
7 #include <soc/nvs.h>
9 #include <ec/acpi/ec.h>
10 #include "ec_oem.c"
11 
12 #define MAX_LCD_BRIGHTNESS 0xd8
13 
15 {
16  u8 reg8;
17  u32 reg32;
18 
19  switch (smif) {
20  case 0x2b:
21  printk(BIOS_DEBUG, "CPU power state switch\n");
22  // TODO, move to CPU handler?
23  break;
24  case 0x3d:
25  printk(BIOS_DEBUG, "Enable C-State SMM coordination\n");
26  // TODO, move to CPU handler?
27  break;
28  case 0x46:
29  printk(BIOS_DEBUG, "S3 DTS SMI (completely re-enable DTS)\n");
30  // TODO, move to CPU handler?
31  break;
32  case 0x47:
33  printk(BIOS_DEBUG, "S4 DTS SMI (Update NVS DTS temperature)\n");
34  // TODO, move to CPU handler?
35  break;
36  case 0xc0:
37  printk(BIOS_DEBUG, "Disable RF\n");
38  // TODO
39  break;
40  case 0xd0:
41  printk(BIOS_DEBUG, "ACBS LAN Power on\n");
42  // TODO
43  break;
44  case 0xd1:
45  printk(BIOS_DEBUG, "ACBS LAN Power off\n");
46  // TODO
47  break;
48  case 0xd2:
49  printk(BIOS_DEBUG, "Check AC status\n");
50  // TODO
51  break;
52  case 0xd3:
53  printk(BIOS_DEBUG, "Enable Bluetooth\n");
54  // TODO
55  break;
56  case 0xd4:
57  printk(BIOS_DEBUG, "Disable Bluetooth\n");
58  // TODO
59  break;
60  case 0xd5:
61  printk(BIOS_DEBUG, "Set Brightness\n");
62  reg8 = gnvs->brtl;
63  printk(BIOS_DEBUG, "brtl: %x\n", reg8);
64  ec_write(0x17, reg8);
65  break;
66  case 0xd6:
67  printk(BIOS_DEBUG, "Get Brightness\n");
68  reg8 = ec_read(0x17);
69  printk(BIOS_DEBUG, "brtl: %x\n", reg8);
70  gnvs->brtl = reg8;
71  break;
72  case 0xd7:
73  printk(BIOS_DEBUG, "Get ECO mode status\n");
74  // TODO
75  break;
76  case 0xd8:
77  printk(BIOS_DEBUG, "Get sunlight readable status\n");
78  // TODO
79  break;
80  case 0xd9:
81  printk(BIOS_DEBUG, "Get docking connection\n");
82  // TODO
83  break;
84  case 0xda:
85  printk(BIOS_DEBUG, "Power off docking\n");
86  // TODO
87  break;
88  case 0xdc:
89  printk(BIOS_DEBUG, "EC: Turn on LED on ECO enable\n");
90  // TODO
91  break;
92  case 0xdd:
93  printk(BIOS_DEBUG, "EC: Turn off LED on ECO disable\n");
94  // TODO
95  break;
96  case 0xde:
97  printk(BIOS_DEBUG, "LAN power off\n");
98  reg32 = inl(DEFAULT_GPIOBASE + GP_LVL);
99  reg32 |= (1 << 24); // Disable LAN Power
100  outl(reg32, DEFAULT_GPIOBASE + GP_LVL);
101  break;
102  case 0xdf:
103  printk(BIOS_DEBUG, "RF enable\n");
104  // TODO
105  break;
106  case 0xe0:
107  printk(BIOS_DEBUG, "Get RTC wake flag\n");
108  // TODO
109  break;
110  case 0xe1:
111  printk(BIOS_DEBUG, "Hotkey function\n");
112  // TODO
113  break;
114  case 0xe3:
115  printk(BIOS_DEBUG, "ECO disable\n");
116  // TODO
117  break;
118  default:
119  return 0;
120  }
121 
122  /* gnvs->smif:
123  * On success, the IO Trap Handler returns 0
124  * On failure, the IO Trap Handler returns a value != 0
125  */
126  gnvs->smif = 0;
127  return 1;
128 }
129 
130 static void mainboard_smi_hotkey(u8 hotkey)
131 {
132  u8 reg8;
133 
134  switch (hotkey) {
135  case 0x3b: break; // Fn+F1
136  case 0x3c: break; // Fn+F2
137  case 0x3d: break; // Fn+F3
138  case 0x3e: break; // Fn+F4
139  case 0x3f: break; // Fn+F5
140  case 0x40: // Fn+F6 (Decrease Display Brightness)
141  reg8 = ec_read(0x17);
142  reg8 = (reg8 > 8) ? (reg8 - 8) : 0;
143  ec_write(0x17, reg8);
144  return;
145  case 0x41: // Fn+F7 (Increase Display Brightness)
146  reg8 = ec_read(0x17);
147  reg8 += 8;
148  reg8 = (reg8 >= MAX_LCD_BRIGHTNESS) ? MAX_LCD_BRIGHTNESS : reg8;
149  ec_write(0x17, reg8);
150  return;
151  case 0x42: break; // Fn+F8
152  case 0x43: break; // Fn+F9
153  case 0x44: break; // Fn+F10
154  case 0x57: break; // Fn+F11
155  case 0x58: break; // Fn+F12
156  }
157  printk(BIOS_DEBUG, "EC hotkey: %02x\n", hotkey);
158 }
159 
160 void mainboard_smi_gpi(u32 gpi_sts)
161 {
162  u8 source, hotkey;
163  send_ec_oem_command(0x5c);
164  source = recv_ec_oem_data();
165 
166  switch (source) {
167  case 0:
168  // Some kind of ACK?
169  break;
170  case 1:
171  send_ec_oem_command(0x59);
172  hotkey = recv_ec_oem_data();
173  mainboard_smi_hotkey(hotkey);
174  break;
175  default:
176  printk(BIOS_DEBUG, "EC SMI source: %02x\n", source);
177  }
178 }
#define printk(level,...)
Definition: stdlib.h:16
void __weak mainboard_smi_gpi(u32 gpi_sts)
Definition: smihandler.c:208
int __weak mainboard_io_trap_handler(int smif)
Definition: smihandler.c:206
u32 inl(u16 port)
void outl(u32 val, u16 port)
u8 ec_read(u8 addr)
Definition: ec.c:107
int ec_write(u8 addr, u8 data)
Definition: ec.c:115
int send_ec_oem_command(u8 command)
Definition: ec_oem.c:9
u8 recv_ec_oem_data(void)
Definition: ec_oem.c:57
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define MAX_LCD_BRIGHTNESS
Definition: smihandler.c:12
static void mainboard_smi_hotkey(u8 hotkey)
Definition: smihandler.c:130
struct global_nvs * gnvs
#define DEFAULT_GPIOBASE
Definition: pch.h:22
#define GP_LVL
Definition: gpio.h:11
uint32_t u32
Definition: stdint.h:51
uint8_t u8
Definition: stdint.h:45
u8 brtl
Definition: nvs.h:70
u8 smif
Definition: nvs.h:11