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 <acpi/acpi.h>
4 #include <arch/io.h>
5 #include <device/mmio.h>
6 #include <console/console.h>
7 #include <cpu/x86/smm.h>
8 #include "ec.h"
10 #include <elog.h>
11 #include <soc/nvs.h>
12 #include <soc/pm.h>
13 #include <soc/gpio.h>
14 
15 #include <variant/onboard.h>
16 
17 /* The wake gpio is SUS_GPIO[0]. */
18 #define WAKE_GPIO_EN SUS_GPIO_EN0
19 #define GPIO_SUS7_WAKE_MASK (1 << 12)
20 #define GPIO_SUS1_WAKE_MASK (1 << 13)
21 
23 {
24  switch (smif) {
25  case 0x99:
26  printk(BIOS_DEBUG, "Sample\n");
27  gnvs->smif = 0;
28  break;
29  default:
30  return 0;
31  }
32 
33  /*
34  * On success, the IO Trap Handler returns 0
35  * On failure, the IO Trap Handler returns a value != 0
36  *
37  * For now, we force the return value to 0 and log all traps to
38  * see what's going on.
39  */
40  //gnvs->smif = 0;
41  return 1;
42 }
43 
45 {
48  uint32_t pm1_cnt;
49 
50  /* Log this event */
51  if (cmd)
53 
54  switch (cmd) {
56  printk(BIOS_DEBUG, "LID CLOSED, SHUTDOWN\n");
57 
58  /* Go to S5 */
59  pm1_cnt = inl(pmbase + PM1_CNT);
60  pm1_cnt |= SLP_EN | (SLP_TYP_S5 << SLP_TYP_SHIFT);
61  outl(pm1_cnt, pmbase + PM1_CNT);
62  break;
63  }
64 
65  return cmd;
66 }
67 
68 /*
69  * The entire 32-bit ALT_GPIO_SMI register is passed as a parameter. Note, that
70  * this includes the enable bits in the lower 16 bits.
71  */
72 void mainboard_smi_gpi(uint32_t alt_gpio_smi)
73 {
74  if (alt_gpio_smi & (1 << EC_SMI_GPI)) {
75  /* Process all pending events */
76  while (mainboard_smi_ec() != 0)
77  ;
78  }
79 }
80 
82 {
83  void *addr;
84  uint32_t mask;
85 
86  /* Disable USB charging if required */
87  switch (slp_typ) {
88  case ACPI_S3:
89  if (gnvs->s3u0 == 0)
92  if (gnvs->s3u1 == 0)
95 
96  /* Enable wake events */
98  /* Enable wake pin in GPE block. */
100  break;
101  case ACPI_S5:
102  if (gnvs->s5u0 == 0)
105  if (gnvs->s5u1 == 0)
108 
109  /* Enable wake events */
111 
112  /* Disabling wake from SUS_GPIO1 (TOUCH INT) and
113  * SUS_GPIO7 (TRACKPAD INT) in North bank as they are not
114  * valid S5 wake sources
115  */
119  write32(addr, read32(addr) & mask);
120 
121  break;
122  }
123 
124  /* Disable SCI and SMI events */
127 
128  /* Clear pending events that may trigger immediate wake */
130  ;
131 
132  /* Set LPC lines to low power in S3/S5. */
133  if ((slp_typ == ACPI_S3) || (slp_typ == ACPI_S5)) {
135  }
136 }
137 
139 {
140  switch (apmc) {
141  case APM_CNT_ACPI_ENABLE:
143  /* Clear all pending events */
145  ;
147  break;
150  /* Clear all pending events */
152  ;
154  break;
155  }
156  return 0;
157 }
#define PM1_CNT
Definition: pm.h:27
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
static uint32_t read32(const void *addr)
Definition: mmio.h:22
void enable_gpe(uint32_t mask)
Definition: pmutil.c:194
static u32 addr
Definition: cirrus.c:14
#define ELOG_TYPE_EC_EVENT
Definition: elog.h:90
#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
int __weak mainboard_io_trap_handler(int smif)
Definition: smihandler.c:206
u32 inl(u16 port)
void outl(u32 val, u16 port)
int google_chromeec_set_wake_mask(uint64_t mask)
Definition: ec.c:1131
int google_chromeec_set_smi_mask(uint64_t mask)
Definition: ec.c:1125
int google_chromeec_set_usb_charge_mode(uint8_t port_id, enum usb_charge_mode mode)
Definition: ec.c:1143
int google_chromeec_set_sci_mask(uint64_t mask)
Definition: ec.c:1119
enum host_event_code google_chromeec_get_event(void)
Definition: ec_i2c.c:242
@ EC_HOST_EVENT_NONE
Definition: ec_commands.h:654
@ EC_HOST_EVENT_LID_CLOSED
Definition: ec_commands.h:655
@ USB_CHARGE_MODE_DISABLED
Definition: ec_commands.h:3240
@ ACPI_S5
Definition: acpi.h:1385
@ ACPI_S3
Definition: acpi.h:1383
#define APM_CNT_ACPI_DISABLE
Definition: smm.h:21
#define APM_CNT_ACPI_ENABLE
Definition: smm.h:22
static int elog_gsmi_add_event_byte(u8 event_type, u8 data)
Definition: elog.h:46
#define IO_BASE_ADDRESS
Definition: iomap.h:19
#define COMMUNITY_OFFSET_GPNORTH
Definition: iomap.h:22
#define SLP_EN
Definition: pmc.h:62
#define SLP_TYP_S5
Definition: pmc.h:69
#define SLP_TYP_SHIFT
Definition: pmc.h:63
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define MAINBOARD_EC_S5_WAKE_EVENTS
Definition: ec.h:32
#define MAINBOARD_EC_SCI_EVENTS
Definition: ec.h:12
#define MAINBOARD_EC_SMI_EVENTS
Definition: ec.h:28
#define EC_SMI_GPI
Definition: ec.h:10
#define MAINBOARD_EC_S3_WAKE_EVENTS
Definition: ec.h:37
static uint8_t mainboard_smi_ec(void)
Definition: smihandler.c:44
#define GPIO_SUS1_WAKE_MASK
Definition: smihandler.c:20
#define GPIO_SUS7_WAKE_MASK
Definition: smihandler.c:19
#define WAKE_GPIO_EN
Definition: smihandler.c:18
struct global_nvs * gnvs
#define GPIO_WAKE_MASK_REG0
Definition: gpio.h:104
void lpc_set_low_power(void)
Definition: lpc_init.c:82
static const int mask[4]
Definition: gpio.c:308
u16 get_pmbase(void)
Definition: smihandler.c:20
u16 pmbase
Definition: smihandler.c:25
unsigned short uint16_t
Definition: stdint.h:11
unsigned int uint32_t
Definition: stdint.h:14
unsigned char uint8_t
Definition: stdint.h:8
u8 s5u1
Definition: nvs.h:33
u8 s3u0
Definition: nvs.h:34
u8 s3u1
Definition: nvs.h:35
u8 s5u0
Definition: nvs.h:32
u8 smif
Definition: nvs.h:11