/* SPDX-License-Identifier: GPL-2.0-only */ #include #include #include #include #include #include #include #include #include #include #include #include /* IO Trap PCRs */ /* Trap status Register */ #define PCR_PSTH_TRPST 0x1E00 /* Trapped cycle */ #define PCR_PSTH_TRPC 0x1E10 /* Trapped write data */ #define PCR_PSTH_TRPD 0x1E18 /* Inherited from cpu/x86/smm.h resulting in a different signature */ int southbridge_io_trap_handler(int smif) { switch (smif) { case 0x32: printk(BIOS_DEBUG, "OS Init\n"); /* * gnvs->smif: * - On success, the IO Trap Handler returns 0 * - On failure, the IO Trap Handler returns a value != 0 */ gnvs->smif = 0; return 1; /* IO trap handled */ } /* Not handled */ return 0; } void smihandler_southbridge_mc( const struct smm_save_state_ops *save_state_ops) { u32 reg32 = inl(ACPI_BASE_ADDRESS + SMI_EN); /* Are microcontroller SMIs enabled? */ if ((reg32 & MCSMI_EN) == 0) return; printk(BIOS_DEBUG, "Microcontroller SMI.\n"); } void smihandler_southbridge_monitor( const struct smm_save_state_ops *save_state_ops) { #define IOTRAP(x) (trap_sts & (1 << x)) u32 trap_cycle; u32 data, mask = 0; u8 trap_sts; int i; /* TRSR - Trap Status Register */ trap_sts = pcr_read8(PID_PSTH, PCR_PSTH_TRPST); /* Clear trap(s) in TRSR */ pcr_write8(PID_PSTH, PCR_PSTH_TRPST, trap_sts); /* TRPC - Trapped cycle */ trap_cycle = pcr_read32(PID_PSTH, PCR_PSTH_TRPC); for (i = 16; i < 20; i++) { if (trap_cycle & (1 << i)) mask |= (0xff << ((i - 16) << 3)); } /* IOTRAP(3) SMI function call */ if (IOTRAP(3)) { if (gnvs && gnvs->smif) io_trap_handler(gnvs->smif); return; } /* * IOTRAP(2) currently unused * IOTRAP(1) currently unused */ /* IOTRAP(0) SMIC */ if (IOTRAP(0)) { if (!(trap_cycle & (1 << 24))) { /* It's a write */ printk(BIOS_DEBUG, "SMI1 command\n"); /* Trapped write data */ data = pcr_read32(PID_PSTH, PCR_PSTH_TRPD); data &= mask; printk(BIOS_DEBUG, " iotrap read data = 0x%08x\n", data); } } printk(BIOS_DEBUG, " trapped io address = 0x%x\n", trap_cycle & 0xfffc); for (i = 0; i < 4; i++) if (IOTRAP(i)) printk(BIOS_DEBUG, " TRAP = %d\n", i); printk(BIOS_DEBUG, " AHBE = %x\n", (trap_cycle >> 16) & 0xf); printk(BIOS_DEBUG, " MASK = 0x%08x\n", mask); printk(BIOS_DEBUG, " read/write: %s\n", (trap_cycle & (1 << 24)) ? "read" : "write"); if (!(trap_cycle & (1 << 24))) { /* Write Cycle */ data = pcr_read32(PID_PSTH, PCR_PSTH_TRPD); printk(BIOS_DEBUG, " iotrap written data = 0x%08x\n", data); } #undef IOTRAP }