2 * SMI handler for Hudson southbridges
4 * Copyright (C) 2014 Alexandru Gagniuc <mr.nuke.me@gmail.com>
5 * Subject to the GNU GPL v2, or (at your option) any later version.
8 #include <console/console.h>
9 #include <cpu/x86/smm.h>
12 #include <soc/southbridge.h>
15 #define SMI_0x88_ACPI_COMMAND (1 << 11)
18 SMI_SOURCE_SCI
= (1 << 0),
19 SMI_SOURCE_GPE
= (1 << 1),
20 SMI_SOURCE_0x84
= (1 << 2),
21 SMI_SOURCE_0x88
= (1 << 3),
22 SMI_SOURCE_IRQ_TRAP
= (1 << 4),
23 SMI_SOURCE_0x90
= (1 << 5)
26 static void sb_apmc_smi_handler(void)
29 const uint8_t cmd
= inb(pm_acpi_smi_cmd_port());
32 case APM_CNT_ACPI_ENABLE
:
33 reg32
= inl(ACPI_PM1_CNT_BLK
);
34 reg32
|= (1 << 0); /* SCI_EN */
35 outl(reg32
, ACPI_PM1_CNT_BLK
);
37 case APM_CNT_ACPI_DISABLE
:
38 reg32
= inl(ACPI_PM1_CNT_BLK
);
39 reg32
&= ~(1 << 0); /* clear SCI_EN */
40 outl(ACPI_PM1_CNT_BLK
, reg32
);
44 mainboard_smi_apmc(cmd
);
47 int southbridge_io_trap_handler(int smif
)
52 static void process_smi_sci(void)
54 const uint32_t status
= smi_read32(0x10);
56 /* Clear events to prevent re-entering SMI if event isn't handled */
57 smi_write32(0x10, status
);
60 static void process_gpe_smi(void)
62 const uint32_t status
= smi_read32(0x80);
63 const uint32_t gevent_mask
= (1 << 24) - 1;
65 /* Only Bits [23:0] indicate GEVENT SMIs. */
66 if (status
& gevent_mask
) {
67 /* A GEVENT SMI occurred */
68 mainboard_smi_gpi(status
& gevent_mask
);
71 /* Clear events to prevent re-entering SMI if event isn't handled */
72 smi_write32(0x80, status
);
75 static void process_smi_0x84(void)
77 const uint32_t status
= smi_read32(0x84);
79 /* Clear events to prevent re-entering SMI if event isn't handled */
80 smi_write32(0x84, status
);
83 static void process_smi_0x88(void)
85 const uint32_t status
= smi_read32(0x88);
87 if (status
& SMI_0x88_ACPI_COMMAND
) {
88 /* Command received via ACPI SMI command port */
89 sb_apmc_smi_handler();
91 /* Clear events to prevent re-entering SMI if event isn't handled */
92 smi_write32(0x88, status
);
95 static void process_smi_0x8c(void)
97 const uint32_t status
= smi_read32(0x8c);
99 /* Clear events to prevent re-entering SMI if event isn't handled */
100 smi_write32(0x8c, status
);
103 static void process_smi_0x90(void)
105 const uint32_t status
= smi_read32(0x90);
107 /* Clear events to prevent re-entering SMI if event isn't handled */
108 smi_write32(0x90, status
);
111 void southbridge_smi_handler(void)
113 const uint16_t smi_src
= smi_read16(0x94);
115 if (smi_src
& SMI_SOURCE_SCI
)
117 if (smi_src
& SMI_SOURCE_GPE
)
119 if (smi_src
& SMI_SOURCE_0x84
)
121 if (smi_src
& SMI_SOURCE_0x88
)
123 if (smi_src
& SMI_SOURCE_IRQ_TRAP
)
125 if (smi_src
& SMI_SOURCE_0x90
)
129 void southbridge_smi_set_eos(void)
131 uint32_t reg
= smi_read32(SMI_REG_SMITRIG0
);
133 smi_write32(SMI_REG_SMITRIG0
, reg
);