xref: /aosp_15_r20/external/coreboot/src/mainboard/google/dedede/smihandler.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #include <baseboard/gpio.h>
4 #include <baseboard/variants.h>
5 #include <console/console.h>
6 #include <cpu/x86/smm.h>
7 #include <ec/google/chromeec/ec.h>
8 #include <ec/google/chromeec/smm.h>
9 #include <elog.h>
10 #include <gpio.h>
11 #include <intelblocks/gpio.h>
12 #include <intelblocks/smihandler.h>
13 #include <spi_flash.h>
14 #include <variant/ec.h>
15 
mainboard_smi_gpi_handler(const struct gpi_status * sts)16 void mainboard_smi_gpi_handler(const struct gpi_status *sts)
17 {
18 	/* TODO: Process SMI events from GPI */
19 }
20 
mainboard_smi_sleep(u8 slp_typ)21 void mainboard_smi_sleep(u8 slp_typ)
22 {
23 	const struct pad_config *pads;
24 	size_t num;
25 
26 	pads = variant_sleep_gpio_table(&num);
27 	gpio_configure_pads(pads, num);
28 
29 	variant_smi_sleep(slp_typ);
30 
31 	chromeec_smi_sleep(slp_typ, MAINBOARD_EC_S3_WAKE_EVENTS,
32 				MAINBOARD_EC_S5_WAKE_EVENTS);
33 }
34 
mainboard_smi_apmc(u8 apmc)35 int mainboard_smi_apmc(u8 apmc)
36 {
37 	chromeec_smi_apmc(apmc, MAINBOARD_EC_SCI_EVENTS,
38 				MAINBOARD_EC_SMI_EVENTS);
39 	return 0;
40 }
41 
elog_gsmi_cb_mainboard_log_wake_source(void)42 void elog_gsmi_cb_mainboard_log_wake_source(void)
43 {
44 	google_chromeec_log_events(MAINBOARD_EC_LOG_EVENTS | MAINBOARD_EC_S0IX_WAKE_EVENTS);
45 }
46 
mainboard_smi_espi_handler(void)47 void mainboard_smi_espi_handler(void)
48 {
49 	chromeec_smi_process_events();
50 }
51 
variant_smi_sleep(u8 slp_typ)52 void __weak variant_smi_sleep(u8 slp_typ)
53 {
54 }
55 
mainboard_config_cbi_wp(void)56 static void mainboard_config_cbi_wp(void)
57 {
58 	int hw_wp = gpio_get(GPIO_PCH_WP);
59 	const struct spi_flash *spi_flash_dev = boot_device_spi_flash();
60 	uint8_t sr1;
61 	int rv;
62 
63 	/*
64 	 * The CBI EEPROM WP should mirror our software write protect status if
65 	 * hardware write protect is set. If software write protect status is
66 	 * set at all via status register 1, that should be a sufficient signal.
67 	 * If the hardware WP is not set, or software write protect is not set
68 	 * while hardware write protect is set, deassert the CBI EEPROM WP.
69 	 *
70 	 * HW WP | SW WP | CBI WP
71 	 * ------|-------|-------
72 	 *   0   |   X   |   0
73 	 *   1   |   0   |   0
74 	 *   1   |   1   |   1
75 	 */
76 	if (spi_flash_status(spi_flash_dev, &sr1) < 0) {
77 		printk(BIOS_ERR, "MB: Failed to read SPI status register 1\n");
78 		printk(BIOS_ERR, "MB: CBI EEPROM WP cannot change!");
79 		return;
80 	}
81 
82 	/*
83 	 * Note that we are assuming that the Status Register protect bits
84 	 * are located at this index and that 1 means hardware protected.  This
85 	 * should be the case for these boards.
86 	 */
87 	const bool is_wp = !!(sr1 & 0x80) && hw_wp;
88 	printk(BIOS_INFO, "MB: SPI flash is %swrite protected\n",
89 	       is_wp ? "" : "not ");
90 
91 	/* Inverted because the signal is active low. */
92 	gpio_set(GPP_B16, !is_wp);
93 
94 	/* Lock the configuration down. */
95 	rv = gpio_lock_pad(GPP_B16, GPIO_LOCK_FULL);
96 	if (rv)
97 		printk(BIOS_ERR, "MB: Failed to lock CBI WP (rv=%d)\n",
98 		       rv);
99 }
100 
mainboard_smi_finalize(void)101 void mainboard_smi_finalize(void)
102 {
103 	if (CONFIG(BOARD_GOOGLE_BASEBOARD_DEDEDE_TPM2))
104 		mainboard_config_cbi_wp();
105 }
106