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 <types.h>
4 #include <arch/io.h>
5 #include <device/pci_ops.h>
6 #include <console/console.h>
7 #include <cpu/x86/cache.h>
8 #include <cpu/x86/smm.h>
9 #include <device/pci_def.h>
10 #include "i82801dx.h"
11 
12 #define DEBUG_SMI
13 
14 /* I830M */
15 #define SMRAM 0x90
16 #define D_OPEN (1 << 6)
17 #define D_CLS (1 << 5)
18 #define D_LCK (1 << 4)
19 #define G_SMRANE (1 << 3)
20 #define C_BASE_SEG ((0 << 2) | (1 << 1) | (0 << 0))
21 
22 /* While we read PMBASE dynamically in case it changed, let's
23  * initialize it with a sane value
24  */
26 
27 /**
28  * @brief read and clear PM1_STS
29  * @return PM1_STS register
30  */
31 static u16 reset_pm1_status(void)
32 {
33  u16 reg16;
34 
35  reg16 = inw(pmbase + PM1_STS);
36  /* set status bits are cleared by writing 1 to them */
37  outw(reg16, pmbase + PM1_STS);
38 
39  return reg16;
40 }
41 
42 static void dump_pm1_status(u16 pm1_sts)
43 {
44  printk(BIOS_SPEW, "PM1_STS: ");
45  if (pm1_sts & (1 << 15)) printk(BIOS_SPEW, "WAK ");
46  if (pm1_sts & (1 << 14)) printk(BIOS_SPEW, "PCIEXPWAK ");
47  if (pm1_sts & (1 << 11)) printk(BIOS_SPEW, "PRBTNOR ");
48  if (pm1_sts & (1 << 10)) printk(BIOS_SPEW, "RTC ");
49  if (pm1_sts & (1 << 8)) printk(BIOS_SPEW, "PWRBTN ");
50  if (pm1_sts & (1 << 5)) printk(BIOS_SPEW, "GBL ");
51  if (pm1_sts & (1 << 4)) printk(BIOS_SPEW, "BM ");
52  if (pm1_sts & (1 << 0)) printk(BIOS_SPEW, "TMROF ");
53  printk(BIOS_SPEW, "\n");
54  int reg16 = inw(pmbase + PM1_EN);
55  printk(BIOS_SPEW, "PM1_EN: %x\n", reg16);
56 }
57 
58 /**
59  * @brief read and clear SMI_STS
60  * @return SMI_STS register
61  */
62 static u32 reset_smi_status(void)
63 {
64  u32 reg32;
65 
66  reg32 = inl(pmbase + SMI_STS);
67  /* set status bits are cleared by writing 1 to them */
68  outl(reg32, pmbase + SMI_STS);
69 
70  return reg32;
71 }
72 
73 static void dump_smi_status(u32 smi_sts)
74 {
75  printk(BIOS_DEBUG, "SMI_STS: ");
76  if (smi_sts & (1 << 26)) printk(BIOS_DEBUG, "SPI ");
77  if (smi_sts & (1 << 25)) printk(BIOS_DEBUG, "EL_SMI ");
78  if (smi_sts & (1 << 21)) printk(BIOS_DEBUG, "MONITOR ");
79  if (smi_sts & (1 << 20)) printk(BIOS_DEBUG, "PCI_EXP_SMI ");
80  if (smi_sts & (1 << 18)) printk(BIOS_DEBUG, "INTEL_USB2 ");
81  if (smi_sts & (1 << 17)) printk(BIOS_DEBUG, "LEGACY_USB2 ");
82  if (smi_sts & (1 << 16)) printk(BIOS_DEBUG, "SMBUS_SMI ");
83  if (smi_sts & (1 << 15)) printk(BIOS_DEBUG, "SERIRQ_SMI ");
84  if (smi_sts & (1 << 14)) printk(BIOS_DEBUG, "PERIODIC ");
85  if (smi_sts & (1 << 13)) printk(BIOS_DEBUG, "TCO ");
86  if (smi_sts & (1 << 12)) printk(BIOS_DEBUG, "DEVMON ");
87  if (smi_sts & (1 << 11)) printk(BIOS_DEBUG, "MCSMI ");
88  if (smi_sts & (1 << 10)) printk(BIOS_DEBUG, "GPI ");
89  if (smi_sts & (1 << 9)) printk(BIOS_DEBUG, "GPE0 ");
90  if (smi_sts & (1 << 8)) printk(BIOS_DEBUG, "PM1 ");
91  if (smi_sts & (1 << 6)) printk(BIOS_DEBUG, "SWSMI_TMR ");
92  if (smi_sts & (1 << 5)) printk(BIOS_DEBUG, "APM ");
93  if (smi_sts & (1 << 4)) printk(BIOS_DEBUG, "SLP_SMI ");
94  if (smi_sts & (1 << 3)) printk(BIOS_DEBUG, "LEGACY_USB ");
95  if (smi_sts & (1 << 2)) printk(BIOS_DEBUG, "BIOS ");
96  printk(BIOS_DEBUG, "\n");
97 }
98 
99 /**
100  * @brief read and clear GPE0_STS
101  * @return GPE0_STS register
102  */
103 static u32 reset_gpe0_status(void)
104 {
105  u32 reg32;
106 
107  reg32 = inl(pmbase + GPE0_STS);
108  /* set status bits are cleared by writing 1 to them */
109  outl(reg32, pmbase + GPE0_STS);
110 
111  return reg32;
112 }
113 
114 static void dump_gpe0_status(u32 gpe0_sts)
115 {
116  int i;
117  printk(BIOS_DEBUG, "GPE0_STS: ");
118  for (i=31; i>= 16; i--) {
119  if (gpe0_sts & (1 << i)) printk(BIOS_DEBUG, "GPIO%d ", (i-16));
120  }
121  if (gpe0_sts & (1 << 14)) printk(BIOS_DEBUG, "USB4 ");
122  if (gpe0_sts & (1 << 13)) printk(BIOS_DEBUG, "PME_B0 ");
123  if (gpe0_sts & (1 << 12)) printk(BIOS_DEBUG, "USB3 ");
124  if (gpe0_sts & (1 << 11)) printk(BIOS_DEBUG, "PME ");
125  if (gpe0_sts & (1 << 10)) printk(BIOS_DEBUG, "EL_SCI/BATLOW ");
126  if (gpe0_sts & (1 << 9)) printk(BIOS_DEBUG, "PCI_EXP ");
127  if (gpe0_sts & (1 << 8)) printk(BIOS_DEBUG, "RI ");
128  if (gpe0_sts & (1 << 7)) printk(BIOS_DEBUG, "SMB_WAK ");
129  if (gpe0_sts & (1 << 6)) printk(BIOS_DEBUG, "TCO_SCI ");
130  if (gpe0_sts & (1 << 5)) printk(BIOS_DEBUG, "AC97 ");
131  if (gpe0_sts & (1 << 4)) printk(BIOS_DEBUG, "USB2 ");
132  if (gpe0_sts & (1 << 3)) printk(BIOS_DEBUG, "USB1 ");
133  if (gpe0_sts & (1 << 2)) printk(BIOS_DEBUG, "HOT_PLUG ");
134  if (gpe0_sts & (1 << 0)) printk(BIOS_DEBUG, "THRM ");
135  printk(BIOS_DEBUG, "\n");
136 }
137 
138 /**
139  * @brief read and clear TCOx_STS
140  * @return TCOx_STS registers
141  */
142 static u32 reset_tco_status(void)
143 {
144  u32 tcobase = pmbase + 0x60;
145  u32 reg32;
146 
147  reg32 = inl(tcobase + 0x04);
148  /* set status bits are cleared by writing 1 to them */
149  outl(reg32 & ~(1<<18), tcobase + 0x04); // Don't clear BOOT_STS before SECOND_TO_STS
150  if (reg32 & (1 << 18))
151  outl(reg32 & (1<<18), tcobase + 0x04); // clear BOOT_STS
152 
153  return reg32;
154 }
155 
156 static void dump_tco_status(u32 tco_sts)
157 {
158  printk(BIOS_DEBUG, "TCO_STS: ");
159  if (tco_sts & (1 << 20)) printk(BIOS_DEBUG, "SMLINK_SLV ");
160  if (tco_sts & (1 << 18)) printk(BIOS_DEBUG, "BOOT ");
161  if (tco_sts & (1 << 17)) printk(BIOS_DEBUG, "SECOND_TO ");
162  if (tco_sts & (1 << 16)) printk(BIOS_DEBUG, "INTRD_DET ");
163  if (tco_sts & (1 << 12)) printk(BIOS_DEBUG, "DMISERR ");
164  if (tco_sts & (1 << 10)) printk(BIOS_DEBUG, "DMISMI ");
165  if (tco_sts & (1 << 9)) printk(BIOS_DEBUG, "DMISCI ");
166  if (tco_sts & (1 << 8)) printk(BIOS_DEBUG, "BIOSWR ");
167  if (tco_sts & (1 << 7)) printk(BIOS_DEBUG, "NEWCENTURY ");
168  if (tco_sts & (1 << 3)) printk(BIOS_DEBUG, "TIMEOUT ");
169  if (tco_sts & (1 << 2)) printk(BIOS_DEBUG, "TCO_INT ");
170  if (tco_sts & (1 << 1)) printk(BIOS_DEBUG, "SW_TCO ");
171  if (tco_sts & (1 << 0)) printk(BIOS_DEBUG, "NMI2SMI ");
172  printk(BIOS_DEBUG, "\n");
173 }
174 
175 /**
176  * @brief Set the EOS bit
177  */
179 {
180  u8 reg8;
181 
182  reg8 = inb(pmbase + SMI_EN);
183  reg8 |= EOS;
184  outb(reg8, pmbase + SMI_EN);
185 }
186 
188 {
189  int slot, func;
190  unsigned int val;
191  unsigned char hdr;
192 
193  for (slot = 0; slot < 0x20; slot++) {
194  for (func = 0; func < 8; func++) {
195  u16 reg16;
196  pci_devfn_t dev = PCI_DEV(bus, slot, func);
197 
199 
200  if (val == 0xffffffff || val == 0x00000000 ||
201  val == 0x0000ffff || val == 0xffff0000)
202  continue;
203 
204  /* Disable Bus Mastering for this one device */
205  reg16 = pci_read_config16(dev, PCI_COMMAND);
206  reg16 &= ~PCI_COMMAND_MASTER;
207  pci_write_config16(dev, PCI_COMMAND, reg16);
208 
209  /* If this is a bridge, then follow it. */
210  hdr = pci_read_config8(dev, PCI_HEADER_TYPE);
211  hdr &= 0x7f;
212  if (hdr == PCI_HEADER_TYPE_BRIDGE ||
213  hdr == PCI_HEADER_TYPE_CARDBUS) {
214  unsigned int buses;
215  buses = pci_read_config32(dev, PCI_PRIMARY_BUS);
216  busmaster_disable_on_bus((buses >> 8) & 0xff);
217  }
218  }
219  }
220 }
221 
222 static void southbridge_smi_sleep(void)
223 {
224  u8 reg8;
225  u32 reg32;
226  u8 slp_typ;
227  /* FIXME: the power state on boot should be read from
228  * CMOS or even better from GNVS. Right now it's hard
229  * coded at compile time.
230  */
231  u8 s5pwr = CONFIG_MAINBOARD_POWER_FAILURE_STATE;
232 
233  /* First, disable further SMIs */
234  reg8 = inb(pmbase + SMI_EN);
235  reg8 &= ~SLP_SMI_EN;
236  outb(reg8, pmbase + SMI_EN);
237 
238  /* Figure out SLP_TYP */
239  reg32 = inl(pmbase + PM1_CNT);
240  printk(BIOS_SPEW, "SMI#: SLP = 0x%08x\n", reg32);
241  slp_typ = acpi_sleep_from_pm1(reg32);
242 
243  /* Next, do the deed.
244  */
245 
246  switch (slp_typ) {
247  case ACPI_S0: printk(BIOS_DEBUG, "SMI#: Entering S0 (On)\n"); break;
248  case ACPI_S1: printk(BIOS_DEBUG, "SMI#: Entering S1 (Assert STPCLK#)\n"); break;
249  case ACPI_S3:
250  printk(BIOS_DEBUG, "SMI#: Entering S3 (Suspend-To-RAM)\n");
251  /* Invalidate the cache before going to S3 */
252  wbinvd();
253  break;
254  case ACPI_S4: printk(BIOS_DEBUG, "SMI#: Entering S4 (Suspend-To-Disk)\n"); break;
255  case ACPI_S5:
256  printk(BIOS_DEBUG, "SMI#: Entering S5 (Soft Power off)\n");
257 
258  outl(0, pmbase + GPE0_EN);
259 
260  /* Should we keep the power state after a power loss?
261  * In case the setting is "ON" or "OFF" we don't have
262  * to do anything. But if it's "KEEP" we have to switch
263  * to "OFF" before entering S5.
264  */
265  if (s5pwr == MAINBOARD_POWER_KEEP) {
266  reg8 = pci_read_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_3);
267  reg8 |= 1;
268  pci_write_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_3, reg8);
269  }
270 
271  /* also iterates over all bridges on bus 0 */
273  break;
274  default: printk(BIOS_DEBUG, "SMI#: ERROR: SLP_TYP reserved\n"); break;
275  }
276 
277  /* Write back to the SLP register to cause the originally intended
278  * event again. We need to set BIT13 (SLP_EN) though to make the
279  * sleep happen.
280  */
281  outl(reg32 | SLP_EN, pmbase + PM1_CNT);
282 
283  /* In most sleep states, the code flow of this function ends at
284  * the line above. However, if we entered sleep state S1 and wake
285  * up again, we will continue to execute code in this function.
286  */
287  reg32 = inl(pmbase + PM1_CNT);
288  if (reg32 & SCI_EN) {
289  /* The OS is not an ACPI OS, so we set the state to S0 */
290  reg32 &= ~(SLP_EN | SLP_TYP);
291  outl(reg32, pmbase + PM1_CNT);
292  }
293 }
294 
295 static void southbridge_smi_apmc(void)
296 {
297  u32 pmctrl;
298  u8 reg8;
299 
300  reg8 = apm_get_apmc();
301  switch (reg8) {
303  pmctrl = inl(pmbase + PM1_CNT);
304  pmctrl &= ~SCI_EN;
305  outl(pmctrl, pmbase + PM1_CNT);
306  break;
307  case APM_CNT_ACPI_ENABLE:
308  pmctrl = inl(pmbase + PM1_CNT);
309  pmctrl |= SCI_EN;
310  outl(pmctrl, pmbase + PM1_CNT);
311  break;
312  }
313 }
314 
315 static void southbridge_smi_pm1(void)
316 {
317  u16 pm1_sts;
318 
319  pm1_sts = reset_pm1_status();
320  dump_pm1_status(pm1_sts);
321 
322  /* While OSPM is not active, poweroff immediately
323  * on a power button event.
324  */
325  if (pm1_sts & PWRBTN_STS) {
326  // power button pressed
327  u32 reg32;
328  reg32 = (7 << 10) | (1 << 13);
329  outl(reg32, pmbase + PM1_CNT);
330  }
331 }
332 
333 static void southbridge_smi_gpe0(void)
334 {
335  u32 gpe0_sts;
336 
337  gpe0_sts = reset_gpe0_status();
338  dump_gpe0_status(gpe0_sts);
339 }
340 
341 static void southbridge_smi_gpi(void)
342 {
343  u16 reg16;
344  reg16 = inw(pmbase + ALT_GP_SMI_STS);
345  outl(reg16, pmbase + ALT_GP_SMI_STS);
346 
347  reg16 &= inw(pmbase + ALT_GP_SMI_EN);
348 
349  mainboard_smi_gpi(reg16);
350 
351  if (reg16)
352  printk(BIOS_DEBUG, "GPI (mask %04x)\n",reg16);
353 }
354 
355 static void southbridge_smi_mc(void)
356 {
357  u32 reg32;
358 
359  reg32 = inl(pmbase + SMI_EN);
360 
361  /* Are periodic SMIs enabled? */
362  if ((reg32 & MCSMI_EN) == 0)
363  return;
364 
365  printk(BIOS_DEBUG, "Microcontroller SMI.\n");
366 }
367 
368 static void southbridge_smi_tco(void)
369 {
370  u32 tco_sts;
371 
372  tco_sts = reset_tco_status();
373 
374  /* Any TCO event? */
375  if (!tco_sts)
376  return;
377 
378  if (tco_sts & (1 << 8)) { // BIOSWR
379  u8 bios_cntl;
380 
381  bios_cntl = pci_read_config16(PCI_DEV(0, 0x1f, 0), 0xdc);
382 
383  if (bios_cntl & 1) {
384  /* BWE is RW, so the SMI was caused by a
385  * write to BWE, not by a write to the BIOS
386  */
387 
388  /* This is the place where we notice someone
389  * is trying to tinker with the BIOS. We are
390  * trying to be nice and just ignore it. A more
391  * resolute answer would be to power down the
392  * box.
393  */
394  printk(BIOS_DEBUG, "Switching back to RO\n");
395  pci_write_config32(PCI_DEV(0, 0x1f, 0), 0xdc, (bios_cntl & ~1));
396  } /* No else for now? */
397  } else if (tco_sts & (1 << 3)) { /* TIMEOUT */
398  /* Handle TCO timeout */
399  printk(BIOS_DEBUG, "TCO Timeout.\n");
400  } else {
401  dump_tco_status(tco_sts);
402  }
403 }
404 
405 static void southbridge_smi_periodic(void)
406 {
407  u32 reg32;
408 
409  reg32 = inl(pmbase + SMI_EN);
410 
411  /* Are periodic SMIs enabled? */
412  if ((reg32 & PERIODIC_EN) == 0)
413  return;
414 
415  printk(BIOS_DEBUG, "Periodic SMI.\n");
416 }
417 
418 typedef void (*smi_handler_t)(void);
419 
421  NULL, // [0] reserved
422  NULL, // [1] reserved
423  NULL, // [2] BIOS_STS
424  NULL, // [3] LEGACY_USB_STS
425  southbridge_smi_sleep, // [4] SLP_SMI_STS
426  southbridge_smi_apmc, // [5] APM_STS
427  NULL, // [6] SWSMI_TMR_STS
428  NULL, // [7] reserved
429  southbridge_smi_pm1, // [8] PM1_STS
430  southbridge_smi_gpe0, // [9] GPE0_STS
431  southbridge_smi_gpi, // [10] GPI_STS
432  southbridge_smi_mc, // [11] MCSMI_STS
433  NULL, // [12] DEVMON_STS
434  southbridge_smi_tco, // [13] TCO_STS
435  southbridge_smi_periodic, // [14] PERIODIC_STS
436  NULL, // [15] SERIRQ_SMI_STS
437  NULL, // [16] SMBUS_SMI_STS
438  NULL, // [17] LEGACY_USB2_STS
439  NULL, // [18] INTEL_USB2_STS
440  NULL, // [19] reserved
441  NULL, // [20] PCI_EXP_SMI_STS
442  NULL, // [21] MONITOR_STS
443  NULL, // [22] reserved
444  NULL, // [23] reserved
445  NULL, // [24] reserved
446  NULL, // [25] EL_SMI_STS
447  NULL, // [26] SPI_STS
448  NULL, // [27] reserved
449  NULL, // [28] reserved
450  NULL, // [29] reserved
451  NULL, // [30] reserved
452  NULL // [31] reserved
453 };
454 
455 /**
456  * @brief Interrupt handler for SMI#
457  */
459 {
460  int i, dump = 0;
461  u32 smi_sts;
462 
463  /* Update global variable pmbase */
464  pmbase = pci_read_config16(PCI_DEV(0, 0x1f, 0), 0x40) & 0xfffc;
465 
466  /* We need to clear the SMI status registers, or we won't see what's
467  * happening in the following calls.
468  */
469  smi_sts = reset_smi_status();
470 
471  /* Filter all non-enabled SMI events */
472  // FIXME Double check, this clears MONITOR
473  // smi_sts &= inl(pmbase + SMI_EN);
474 
475  /* Call SMI sub handler for each of the status bits */
476  for (i = 0; i < 31; i++) {
477  if (smi_sts & (1 << i)) {
478  if (southbridge_smi[i]) {
479  southbridge_smi[i]();
480  } else {
481  printk(BIOS_DEBUG, "SMI_STS[%d] occurred, but no "
482  "handler available.\n", i);
483  dump = 1;
484  }
485  }
486  }
487 
488  if (dump) {
489  dump_smi_status(smi_sts);
490  }
491 }
#define PM1_EN
Definition: pm.h:21
#define SMI_STS
Definition: pm.h:50
#define SCI_EN
Definition: pm.h:30
#define GPE0_STS(x)
Definition: pm.h:81
#define MCSMI_EN
Definition: pm.h:41
#define PM1_STS
Definition: pm.h:12
#define SLP_SMI_EN
Definition: pm.h:45
#define GPE0_EN(x)
Definition: pm.h:99
#define PM1_CNT
Definition: pm.h:27
#define SMI_EN
Definition: pm.h:32
#define EOS
Definition: pm.h:48
#define PERIODIC_EN
Definition: pm.h:39
#define MAINBOARD_POWER_KEEP
Definition: pm.h:95
#define PWRBTN_STS
Definition: southbridge.h:30
#define printk(level,...)
Definition: stdlib.h:16
void __weak southbridge_smi_handler(void)
Definition: smihandler.c:207
void __weak mainboard_smi_gpi(u32 gpi_sts)
Definition: smihandler.c:208
u8 inb(u16 port)
void outb(u8 val, u16 port)
u16 inw(u16 port)
u32 inl(u16 port)
void outl(u32 val, u16 port)
void outw(u16 val, u16 port)
#define PMBASE_ADDR
Definition: i82801dx.h:58
@ ACPI_S5
Definition: acpi.h:1385
@ ACPI_S1
Definition: acpi.h:1381
@ ACPI_S4
Definition: acpi.h:1384
@ ACPI_S3
Definition: acpi.h:1383
@ ACPI_S0
Definition: acpi.h:1380
static void wbinvd(void)
Definition: cache.h:15
#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 u16 pci_read_config16(const struct device *dev, u16 reg)
Definition: pci_ops.h:52
static __always_inline u32 pci_read_config32(const struct device *dev, u16 reg)
Definition: pci_ops.h:58
static __always_inline u8 pci_read_config8(const struct device *dev, u16 reg)
Definition: pci_ops.h:46
static __always_inline void pci_write_config16(const struct device *dev, u16 reg, u16 val)
Definition: pci_ops.h:70
static __always_inline void pci_write_config8(const struct device *dev, u16 reg, u8 val)
Definition: pci_ops.h:64
#define SLP_EN
Definition: pmc.h:62
#define SLP_TYP
Definition: pmc.h:64
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define BIOS_SPEW
BIOS_SPEW - Excessively verbose output.
Definition: loglevel.h:142
#define PCI_HEADER_TYPE
Definition: pci_def.h:47
#define PCI_PRIMARY_BUS
Definition: pci_def.h:100
#define PCI_HEADER_TYPE_CARDBUS
Definition: pci_def.h:50
#define PCI_COMMAND_MASTER
Definition: pci_def.h:13
#define PCI_COMMAND
Definition: pci_def.h:10
#define PCI_HEADER_TYPE_BRIDGE
Definition: pci_def.h:49
#define PCI_VENDOR_ID
Definition: pci_def.h:8
#define PCI_DEV(SEGBUS, DEV, FN)
Definition: pci_type.h:14
u32 pci_devfn_t
Definition: pci_type.h:8
u8 apm_get_apmc(void)
Definition: smi_trigger.c:46
const smi_handler_t southbridge_smi[SMI_STS_BITS]
Definition: smihandler.c:17
void southbridge_smi_set_eos(void)
Definition: smihandler.c:41
void(* smi_handler_t)(void)
Definition: smihandler.c:361
#define GEN_PMCON_3
Definition: lpc.h:63
int dump
Definition: display.c:23
#define ALT_GP_SMI_STS
Definition: pch.h:462
#define ALT_GP_SMI_EN
Definition: pch.h:461
static void dump_gpe0_status(u32 gpe0_sts)
Definition: smihandler.c:114
static void southbridge_smi_pm1(void)
Definition: smihandler.c:315
static u16 reset_pm1_status(void)
read and clear PM1_STS
Definition: smihandler.c:31
static u32 reset_smi_status(void)
read and clear SMI_STS
Definition: smihandler.c:62
static void busmaster_disable_on_bus(int bus)
Definition: smihandler.c:187
static void dump_tco_status(u32 tco_sts)
Definition: smihandler.c:156
u16 pmbase
Definition: smihandler.c:25
static void southbridge_smi_apmc(void)
Definition: smihandler.c:295
static u32 reset_tco_status(void)
read and clear TCOx_STS
Definition: smihandler.c:142
static void southbridge_smi_periodic(void)
Definition: smihandler.c:405
static void southbridge_smi_gpe0(void)
Definition: smihandler.c:333
static u32 reset_gpe0_status(void)
read and clear GPE0_STS
Definition: smihandler.c:103
static void southbridge_smi_gpi(void)
Definition: smihandler.c:341
static void dump_smi_status(u32 smi_sts)
Definition: smihandler.c:73
static void southbridge_smi_tco(void)
Definition: smihandler.c:368
static void dump_pm1_status(u16 pm1_sts)
Definition: smihandler.c:42
static void southbridge_smi_mc(void)
Definition: smihandler.c:355
static void southbridge_smi_sleep(void)
Definition: smihandler.c:222
#define NULL
Definition: stddef.h:19
uint32_t u32
Definition: stdint.h:51
uint16_t u16
Definition: stdint.h:48
uint8_t u8
Definition: stdint.h:45
Definition: device.h:76
u8 val
Definition: sys.c:300
typedef void(X86APIP X86EMU_intrFuncs)(int num)