xref: /aosp_15_r20/external/coreboot/src/soc/intel/common/block/smm/smitraphandler.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <arch/io.h>
4 #include <console/console.h>
5 #include <cpu/x86/smm.h>
6 #include <intelblocks/fast_spi.h>
7 #include <intelblocks/pcr.h>
8 #include <intelblocks/smihandler.h>
9 #include <soc/gpio.h>
10 #include <soc/iomap.h>
11 #include <soc/nvs.h>
12 #include <soc/pcr_ids.h>
13 #include <soc/pm.h>
14 #include <soc/pmc.h>
15 
16 /* IO Trap PCRs */
17 /* Trap status Register */
18 #define PCR_PSTH_TRPST  0x1E00
19 /* Trapped cycle */
20 #define PCR_PSTH_TRPC   0x1E10
21 /* Trapped write data */
22 #define PCR_PSTH_TRPD   0x1E18
23 
24 
smihandler_southbridge_mc(const struct smm_save_state_ops * save_state_ops)25 void smihandler_southbridge_mc(
26 	const struct smm_save_state_ops *save_state_ops)
27 {
28 	u32 reg32 = inl(ACPI_BASE_ADDRESS + SMI_EN);
29 
30 	/* Are microcontroller SMIs enabled? */
31 	if ((reg32 & MCSMI_EN) == 0)
32 		return;
33 
34 	printk(BIOS_DEBUG, "Microcontroller SMI.\n");
35 }
36 
smihandler_southbridge_monitor(const struct smm_save_state_ops * save_state_ops)37 void smihandler_southbridge_monitor(
38 	const struct smm_save_state_ops *save_state_ops)
39 {
40 #define IOTRAP(x) (trap_sts & (1 << x))
41 	u32 trap_cycle;
42 	u32 data, mask = 0;
43 	u8 trap_sts;
44 	int i;
45 
46 	/* TRSR - Trap Status Register */
47 	trap_sts = pcr_read8(PID_PSTH, PCR_PSTH_TRPST);
48 	/* Clear trap(s) in TRSR */
49 	pcr_write8(PID_PSTH, PCR_PSTH_TRPST, trap_sts);
50 
51 	/* TRPC - Trapped cycle */
52 	trap_cycle = pcr_read32(PID_PSTH, PCR_PSTH_TRPC);
53 	for (i = 16; i < 20; i++) {
54 		if (trap_cycle & (1 << i))
55 			mask |= (0xff << ((i - 16) << 3));
56 	}
57 
58 	/* IOTRAP(3) SMI function call */
59 	if (IOTRAP(3)) {
60 		if (gnvs && gnvs->smif)
61 			io_trap_handler(gnvs->smif);
62 		return;
63 	}
64 
65 	/*
66 	 * IOTRAP(2) currently unused
67 	 * IOTRAP(1) currently unused
68 	 */
69 
70 	/* IOTRAP(0) SMIC */
71 	if (IOTRAP(0)) {
72 		if (!(trap_cycle & (1 << 24))) { /* It's a write */
73 			printk(BIOS_DEBUG, "SMI1 command\n");
74 			/* Trapped write data */
75 			data = pcr_read32(PID_PSTH, PCR_PSTH_TRPD);
76 			data &= mask;
77 			printk(BIOS_DEBUG, "  iotrap read data = 0x%08x\n", data);
78 		}
79 	}
80 
81 	printk(BIOS_DEBUG, "  trapped io address = 0x%x\n",
82 		trap_cycle & 0xfffc);
83 	for (i = 0; i < 4; i++)
84 		if (IOTRAP(i))
85 			printk(BIOS_DEBUG, "  TRAP = %d\n", i);
86 	printk(BIOS_DEBUG, "  AHBE = %x\n", (trap_cycle >> 16) & 0xf);
87 	printk(BIOS_DEBUG, "  MASK = 0x%08x\n", mask);
88 	printk(BIOS_DEBUG, "  read/write: %s\n",
89 		(trap_cycle & (1 << 24)) ? "read" : "write");
90 
91 	if (!(trap_cycle & (1 << 24))) {
92 		/* Write Cycle */
93 		data = pcr_read32(PID_PSTH, PCR_PSTH_TRPD);
94 		printk(BIOS_DEBUG, "  iotrap written data = 0x%08x\n", data);
95 	}
96 #undef IOTRAP
97 }
98