1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 3 #include <amdblocks/acpimmio.h> 4 #include <console/console.h> 5 #include <amdblocks/smi.h> 6 #include <amdblocks/smm.h> 7 #include <cpu/x86/smm.h> 8 #include <soc/smi.h> 9 mainboard_handle_smi(int event)10__weak void mainboard_handle_smi(int event) 11 { 12 printk(BIOS_WARNING, "SMI event %d is missing handler\n", event); 13 } 14 process_smi_sources(uint32_t reg)15static void process_smi_sources(uint32_t reg) 16 { 17 const uint32_t status = smi_read32(reg); 18 int bit_zero = 32 / sizeof(uint32_t) * (reg - SMI_REG_SMISTS0); 19 void (*source_handler)(void); 20 int i; 21 22 for (i = 0 ; i < 32 ; i++) { 23 if (status & (1 << i)) { 24 source_handler = get_smi_source_handler(i + bit_zero); 25 if (source_handler) 26 source_handler(); 27 else if (reg != SMI_REG_SMISTS0 || (status & GEVENT_MASK) == 0) 28 mainboard_handle_smi(i + bit_zero); 29 } 30 } 31 32 if (reg == SMI_REG_SMISTS0) 33 if (status & GEVENT_MASK) 34 /* Gevent[23:0] are assumed to be mainboard-specific */ 35 mainboard_smi_gpi(status & GEVENT_MASK); 36 37 /* Clear all events in this register */ 38 smi_write32(reg, status); 39 } 40 southbridge_smi_handler(void)41void southbridge_smi_handler(void) 42 { 43 const uint16_t smi_src = smi_read16(SMI_REG_POINTER); 44 45 if (smi_src & SMI_STATUS_SRC_SCI) { 46 printk(BIOS_WARNING, "Ignoring SCI SMI: %#x\n", smi_read32(SMI_SCI_STATUS)); 47 48 /* Clear events to prevent re-entering SMI if event isn't handled */ 49 clear_smi_sci_status(); 50 } 51 if (smi_src & SMI_STATUS_SRC_0) 52 process_smi_sources(SMI_REG_SMISTS0); 53 if (smi_src & SMI_STATUS_SRC_1) 54 process_smi_sources(SMI_REG_SMISTS1); 55 if (smi_src & SMI_STATUS_SRC_2) 56 process_smi_sources(SMI_REG_SMISTS2); 57 if (smi_src & SMI_STATUS_SRC_3) 58 process_smi_sources(SMI_REG_SMISTS3); 59 if (smi_src & SMI_STATUS_SRC_4) 60 process_smi_sources(SMI_REG_SMISTS4); 61 } 62