• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <types.h>
4 #include <arch/io.h>
5 #include <device/pci_ops.h>
6 #include <console/console.h>
7 #include <cpu/x86/cache.h>
8 #include <device/pci_def.h>
9 #include <cpu/x86/smm.h>
10 #include <cpu/intel/em64t101_save_state.h>
11 #include <elog.h>
12 #include <halt.h>
13 #include <option.h>
14 #include <southbridge/intel/common/finalize.h>
15 #include <northbridge/intel/haswell/haswell.h>
16 #include <cpu/intel/haswell/haswell.h>
17 #include <soc/nvs.h>
18 #include <smmstore.h>
19 #include "me.h"
20 #include "pch.h"
21 
22 /**
23  * @brief Set the EOS bit
24  */
southbridge_smi_set_eos(void)25 void southbridge_smi_set_eos(void)
26 {
27 	enable_smi(EOS);
28 }
29 
busmaster_disable_on_bus(int bus)30 static void busmaster_disable_on_bus(int bus)
31 {
32 	int slot, func;
33 	unsigned int val;
34 	unsigned char hdr;
35 
36 	for (slot = 0; slot < 0x20; slot++) {
37 		for (func = 0; func < 8; func++) {
38 			pci_devfn_t dev = PCI_DEV(bus, slot, func);
39 
40 			val = pci_read_config32(dev, PCI_VENDOR_ID);
41 
42 			if (val == 0xffffffff || val == 0x00000000 ||
43 			    val == 0x0000ffff || val == 0xffff0000)
44 				continue;
45 
46 			/* Disable Bus Mastering for this one device */
47 			pci_and_config16(dev, PCI_COMMAND, ~PCI_COMMAND_MASTER);
48 
49 			/* If this is a bridge, then follow it. */
50 			hdr = pci_read_config8(dev, PCI_HEADER_TYPE);
51 			hdr &= 0x7f;
52 			if (hdr == PCI_HEADER_TYPE_BRIDGE ||
53 			    hdr == PCI_HEADER_TYPE_CARDBUS) {
54 				unsigned int buses;
55 				buses = pci_read_config32(dev, PCI_PRIMARY_BUS);
56 				busmaster_disable_on_bus((buses >> 8) & 0xff);
57 			}
58 		}
59 	}
60 }
61 
power_on_after_fail(void)62 static int power_on_after_fail(void)
63 {
64 	/* save and recover RTC port values */
65 	u8 tmp70, tmp72;
66 	tmp70 = inb(0x70);
67 	tmp72 = inb(0x72);
68 	const unsigned int s5pwr = get_uint_option("power_on_after_fail",
69 					 CONFIG_MAINBOARD_POWER_FAILURE_STATE);
70 	outb(tmp70, 0x70);
71 	outb(tmp72, 0x72);
72 
73 	/* For "KEEP", switch to "OFF" - KEEP is software emulated. */
74 	return (s5pwr == MAINBOARD_POWER_ON);
75 }
76 
southbridge_smi_sleep(void)77 static void southbridge_smi_sleep(void)
78 {
79 	u32 reg32;
80 	u8 slp_typ;
81 	u16 pmbase = get_pmbase();
82 
83 	/* First, disable further SMIs */
84 	disable_smi(SLP_SMI_EN);
85 
86 	/* Figure out SLP_TYP */
87 	reg32 = inl(pmbase + PM1_CNT);
88 	printk(BIOS_SPEW, "SMI#: SLP = 0x%08x\n", reg32);
89 	slp_typ = acpi_sleep_from_pm1(reg32);
90 
91 	/* Do any mainboard sleep handling */
92 	mainboard_smi_sleep(slp_typ);
93 
94 	/* USB sleep preparations */
95 #if !CONFIG(FINALIZE_USB_ROUTE_XHCI)
96 	usb_ehci_sleep_prepare(PCH_EHCI1_DEV, slp_typ);
97 	usb_ehci_sleep_prepare(PCH_EHCI2_DEV, slp_typ);
98 #endif
99 	usb_xhci_sleep_prepare(PCH_XHCI_DEV, slp_typ);
100 
101 	/* Log S3, S4, and S5 entry */
102 	if (slp_typ >= ACPI_S3)
103 		elog_gsmi_add_event_byte(ELOG_TYPE_ACPI_ENTER, slp_typ);
104 
105 	/* Next, do the deed.
106 	 */
107 
108 	switch (slp_typ) {
109 	case ACPI_S0:
110 		printk(BIOS_DEBUG, "SMI#: Entering S0 (On)\n");
111 		break;
112 	case ACPI_S1:
113 		printk(BIOS_DEBUG, "SMI#: Entering S1 (Assert STPCLK#)\n");
114 		break;
115 	case ACPI_S3:
116 		printk(BIOS_DEBUG, "SMI#: Entering S3 (Suspend-To-RAM)\n");
117 
118 		/* Invalidate the cache before going to S3 */
119 		wbinvd();
120 		break;
121 	case ACPI_S4:
122 		printk(BIOS_DEBUG, "SMI#: Entering S4 (Suspend-To-Disk)\n");
123 		break;
124 	case ACPI_S5:
125 		printk(BIOS_DEBUG, "SMI#: Entering S5 (Soft Power off)\n");
126 
127 		/* Disable all GPE */
128 		disable_all_gpe();
129 
130 		/* Always set the flag in case CMOS was changed on runtime. */
131 		if (power_on_after_fail())
132 			pci_and_config8(PCH_LPC_DEV, GEN_PMCON_3, ~1);
133 		else
134 			pci_or_config8(PCH_LPC_DEV, GEN_PMCON_3, 1);
135 
136 		/* also iterates over all bridges on bus 0 */
137 		busmaster_disable_on_bus(0);
138 		break;
139 	default:
140 		printk(BIOS_DEBUG, "SMI#: ERROR: SLP_TYP reserved\n");
141 		break;
142 	}
143 
144 	/*
145 	 * Write back to the SLP register to cause the originally intended
146 	 * event again. We need to set BIT13 (SLP_EN) though to make the
147 	 * sleep happen.
148 	 */
149 	enable_pm1_control(SLP_EN);
150 
151 	/* Make sure to stop executing code here for S3/S4/S5 */
152 	if (slp_typ >= ACPI_S3)
153 		halt();
154 
155 	/*
156 	 * In most sleep states, the code flow of this function ends at
157 	 * the line above. However, if we entered sleep state S1 and wake
158 	 * up again, we will continue to execute code in this function.
159 	 */
160 	reg32 = inl(pmbase + PM1_CNT);
161 	if (reg32 & SCI_EN) {
162 		/* The OS is not an ACPI OS, so we set the state to S0 */
163 		disable_pm1_control(SLP_EN | SLP_TYP);
164 	}
165 }
166 
167 /*
168  * Look for Synchronous IO SMI and use save state from that
169  * core in case we are not running on the same core that
170  * initiated the IO transaction.
171  */
smi_apmc_find_state_save(u8 cmd)172 static em64t101_smm_state_save_area_t *smi_apmc_find_state_save(u8 cmd)
173 {
174 	em64t101_smm_state_save_area_t *state;
175 	int node;
176 
177 	/* Check all nodes looking for the one that issued the IO */
178 	for (node = 0; node < CONFIG_MAX_CPUS; node++) {
179 		state = smm_get_save_state(node);
180 
181 		/* Check for Synchronous IO (bit0 == 1) */
182 		if (!(state->io_misc_info & (1 << 0)))
183 			continue;
184 
185 		/* Make sure it was a write (bit4 == 0) */
186 		if (state->io_misc_info & (1 << 4))
187 			continue;
188 
189 		/* Check for APMC IO port */
190 		if (((state->io_misc_info >> 16) & 0xff) != APM_CNT)
191 			continue;
192 
193 		/* Check AX against the requested command */
194 		if ((state->rax & 0xff) != cmd)
195 			continue;
196 
197 		return state;
198 	}
199 
200 	return NULL;
201 }
202 
southbridge_smi_gsmi(void)203 static void southbridge_smi_gsmi(void)
204 {
205 	u32 *ret, *param;
206 	u8 sub_command;
207 	em64t101_smm_state_save_area_t *io_smi =
208 		smi_apmc_find_state_save(APM_CNT_ELOG_GSMI);
209 
210 	if (!io_smi)
211 		return;
212 
213 	/* Command and return value in EAX */
214 	ret = (u32 *)&io_smi->rax;
215 	sub_command = (u8)(*ret >> 8);
216 
217 	/* Parameter buffer in EBX */
218 	param = (u32 *)&io_smi->rbx;
219 
220 	/* drivers/elog/gsmi.c */
221 	*ret = gsmi_exec(sub_command, param);
222 }
223 
southbridge_smi_store(void)224 static void southbridge_smi_store(void)
225 {
226 	u8 sub_command, ret;
227 	em64t101_smm_state_save_area_t *io_smi =
228 		smi_apmc_find_state_save(APM_CNT_SMMSTORE);
229 	uint32_t reg_ebx;
230 
231 	if (!io_smi)
232 		return;
233 	/* Command and return value in EAX */
234 	sub_command = (io_smi->rax >> 8) & 0xff;
235 
236 	/* Parameter buffer in EBX */
237 	reg_ebx = io_smi->rbx;
238 
239 	/* drivers/smmstore/smi.c */
240 	ret = smmstore_exec(sub_command, (void *)reg_ebx);
241 	io_smi->rax = ret;
242 }
243 
southbridge_smi_apmc(void)244 static void southbridge_smi_apmc(void)
245 {
246 	u8 reg8;
247 	static int chipset_finalized = 0;
248 
249 	reg8 = apm_get_apmc();
250 	switch (reg8) {
251 	case APM_CNT_FINALIZE:
252 		if (chipset_finalized) {
253 			printk(BIOS_DEBUG, "SMI#: Already finalized\n");
254 			return;
255 		}
256 
257 		intel_pch_finalize_smm();
258 		intel_cpu_haswell_finalize_smm();
259 
260 		chipset_finalized = 1;
261 		break;
262 	case APM_CNT_ACPI_DISABLE:
263 		disable_pm1_control(SCI_EN);
264 		break;
265 	case APM_CNT_ACPI_ENABLE:
266 		enable_pm1_control(SCI_EN);
267 		break;
268 	case APM_CNT_ROUTE_ALL_XHCI:
269 		usb_xhci_route_all();
270 		break;
271 	case APM_CNT_ELOG_GSMI:
272 		if (CONFIG(ELOG_GSMI))
273 			southbridge_smi_gsmi();
274 		break;
275 	case APM_CNT_SMMSTORE:
276 		if (CONFIG(SMMSTORE))
277 			southbridge_smi_store();
278 		break;
279 	}
280 
281 	mainboard_smi_apmc(reg8);
282 }
283 
southbridge_smi_pm1(void)284 static void southbridge_smi_pm1(void)
285 {
286 	u16 pm1_sts = clear_pm1_status();
287 
288 	/* While OSPM is not active, poweroff immediately
289 	 * on a power button event.
290 	 */
291 	if (pm1_sts & PWRBTN_STS) {
292 		/* power button pressed */
293 		elog_gsmi_add_event(ELOG_TYPE_POWER_BUTTON);
294 		disable_pm1_control(-1);
295 		enable_pm1_control(SLP_EN | (SLP_TYP_S5 << 10));
296 	}
297 }
298 
southbridge_smi_gpe0(void)299 static void southbridge_smi_gpe0(void)
300 {
301 	clear_gpe_status();
302 }
303 
southbridge_smi_gpi(void)304 static void southbridge_smi_gpi(void)
305 {
306 	mainboard_smi_gpi(clear_alt_smi_status());
307 
308 	/* Clear again after mainboard handler */
309 	clear_alt_smi_status();
310 }
311 
southbridge_smi_mc(void)312 static void southbridge_smi_mc(void)
313 {
314 	u32 reg32 = inl(get_pmbase() + SMI_EN);
315 
316 	/* Are microcontroller SMIs enabled? */
317 	if ((reg32 & MCSMI_EN) == 0)
318 		return;
319 
320 	printk(BIOS_DEBUG, "Microcontroller SMI.\n");
321 }
322 
southbridge_smi_tco(void)323 static void southbridge_smi_tco(void)
324 {
325 	u32 tco_sts = clear_tco_status();
326 
327 	/* Any TCO event? */
328 	if (!tco_sts)
329 		return;
330 
331 	// BIOSWR
332 	if (tco_sts & (1 << 8)) {
333 		u8 bios_cntl = pci_read_config8(PCH_LPC_DEV, BIOS_CNTL);
334 
335 		if (bios_cntl & 1) {
336 			/*
337 			 * BWE is RW, so the SMI was caused by a
338 			 * write to BWE, not by a write to the BIOS
339 			 *
340 			 * This is the place where we notice someone
341 			 * is trying to tinker with the BIOS. We are
342 			 * trying to be nice and just ignore it. A more
343 			 * resolute answer would be to power down the
344 			 * box.
345 			 */
346 			printk(BIOS_DEBUG, "Switching back to RO\n");
347 			pci_write_config8(PCH_LPC_DEV, BIOS_CNTL, (bios_cntl & ~1));
348 		} /* No else for now? */
349 	} else if (tco_sts & (1 << 3)) { /* TIMEOUT */
350 		/* Handle TCO timeout */
351 		printk(BIOS_DEBUG, "TCO Timeout.\n");
352 	}
353 }
354 
southbridge_smi_periodic(void)355 static void southbridge_smi_periodic(void)
356 {
357 	u32 reg32 = inl(get_pmbase() + SMI_EN);
358 
359 	/* Are periodic SMIs enabled? */
360 	if ((reg32 & PERIODIC_EN) == 0)
361 		return;
362 
363 	printk(BIOS_DEBUG, "Periodic SMI.\n");
364 }
365 
southbridge_smi_monitor(void)366 static void southbridge_smi_monitor(void)
367 {
368 #define IOTRAP(x) (trap_sts & (1 << x))
369 	u32 trap_sts, trap_cycle;
370 	u32 mask = 0;
371 	int i;
372 
373 	trap_sts = RCBA32(0x1e00); // TRSR - Trap Status Register
374 	RCBA32(0x1e00) = trap_sts; // Clear trap(s) in TRSR
375 
376 	trap_cycle = RCBA32(0x1e10);
377 	for (i = 16; i < 20; i++) {
378 		if (trap_cycle & (1 << i))
379 			mask |= (0xff << ((i - 16) << 3));
380 	}
381 
382 	/* IOTRAP(3) SMI function call */
383 	if (IOTRAP(3)) {
384 		if (gnvs && gnvs->smif)
385 			io_trap_handler(gnvs->smif); // call function smif
386 		return;
387 	}
388 
389 	/* IOTRAP(2) currently unused
390 	 * IOTRAP(1) currently unused */
391 
392 	/* IOTRAP(0) SMIC */
393 	if (IOTRAP(0)) {
394 		// It's a write
395 		if (!(trap_cycle & (1 << 24))) {
396 			printk(BIOS_DEBUG, "SMI1 command\n");
397 			(void)RCBA32(0x1e18);
398 			// data = RCBA32(0x1e18);
399 			// data &= mask;
400 			// if (smi1)
401 			//	southbridge_smi_command(data);
402 			// return;
403 		}
404 		// Fall through to debug
405 	}
406 
407 	printk(BIOS_DEBUG, "  trapped io address = 0x%x\n",
408 	       trap_cycle & 0xfffc);
409 	for (i = 0; i < 4; i++)
410 		if (IOTRAP(i))
411 			printk(BIOS_DEBUG, "  TRAP = %d\n", i);
412 	printk(BIOS_DEBUG, "  AHBE = %x\n", (trap_cycle >> 16) & 0xf);
413 	printk(BIOS_DEBUG, "  MASK = 0x%08x\n", mask);
414 	printk(BIOS_DEBUG, "  read/write: %s\n",
415 	       (trap_cycle & (1 << 24)) ? "read" : "write");
416 
417 	if (!(trap_cycle & (1 << 24))) {
418 		/* Write Cycle */
419 		printk(BIOS_DEBUG, "  iotrap written data = 0x%08x\n", RCBA32(0x1e18));
420 	}
421 #undef IOTRAP
422 }
423 
424 typedef void (*smi_handler_t)(void);
425 
426 static smi_handler_t southbridge_smi[32] = {
427 	NULL,			  //  [0] reserved
428 	NULL,			  //  [1] reserved
429 	NULL,			  //  [2] BIOS_STS
430 	NULL,			  //  [3] LEGACY_USB_STS
431 	southbridge_smi_sleep,	  //  [4] SLP_SMI_STS
432 	southbridge_smi_apmc,	  //  [5] APM_STS
433 	NULL,			  //  [6] SWSMI_TMR_STS
434 	NULL,			  //  [7] reserved
435 	southbridge_smi_pm1,	  //  [8] PM1_STS
436 	southbridge_smi_gpe0,	  //  [9] GPE0_STS
437 	southbridge_smi_gpi,	  // [10] GPI_STS
438 	southbridge_smi_mc,	  // [11] MCSMI_STS
439 	NULL,			  // [12] DEVMON_STS
440 	southbridge_smi_tco,	  // [13] TCO_STS
441 	southbridge_smi_periodic, // [14] PERIODIC_STS
442 	NULL,			  // [15] SERIRQ_SMI_STS
443 	NULL,			  // [16] SMBUS_SMI_STS
444 	NULL,			  // [17] LEGACY_USB2_STS
445 	NULL,			  // [18] INTEL_USB2_STS
446 	NULL,			  // [19] reserved
447 	NULL,			  // [20] PCI_EXP_SMI_STS
448 	southbridge_smi_monitor,  // [21] MONITOR_STS
449 	NULL,			  // [22] reserved
450 	NULL,			  // [23] reserved
451 	NULL,			  // [24] reserved
452 	NULL,			  // [25] EL_SMI_STS
453 	NULL,			  // [26] SPI_STS
454 	NULL,			  // [27] reserved
455 	NULL,			  // [28] reserved
456 	NULL,			  // [29] reserved
457 	NULL,			  // [30] reserved
458 	NULL			  // [31] reserved
459 };
460 
461 /**
462  * @brief Interrupt handler for SMI#
463  */
southbridge_smi_handler(void)464 void southbridge_smi_handler(void)
465 {
466 	int i;
467 	u32 smi_sts;
468 
469 	/* We need to clear the SMI status registers, or we won't see what's
470 	 * happening in the following calls.
471 	 */
472 	smi_sts = clear_smi_status();
473 
474 	/* Call SMI sub handler for each of the status bits */
475 	for (i = 0; i < 31; i++) {
476 		if (smi_sts & (1 << i)) {
477 			if (southbridge_smi[i]) {
478 				southbridge_smi[i]();
479 			} else {
480 				printk(BIOS_DEBUG,
481 				       "SMI_STS[%d] occurred, but no "
482 				       "handler available.\n", i);
483 			}
484 		}
485 	}
486 }
487