1 /* This file is part of the coreboot project. */
2 /* SPDX-License-Identifier: GPL-2.0-or-later */
5 * SMI handler for Hudson southbridges
8 #include <amdblocks/acpimmio.h>
10 #include <cpu/x86/smm.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 hudson_apmc_smi_handler(void)
29 const uint8_t cmd
= inb(ACPI_SMI_CTL_PORT
);
32 case ACPI_SMI_CMD_ENABLE
:
33 reg32
= inl(ACPI_PM1_CNT_BLK
);
34 reg32
|= (1 << 0); /* SCI_EN */
35 outl(reg32
, ACPI_PM1_CNT_BLK
);
37 case ACPI_SMI_CMD_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 hudson_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
);