• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <arch/io.h>
4 #include <cf9_reset.h>
5 #include <device/pci_ops.h>
6 #include <console/console.h>
7 #include <delay.h>
8 #include <halt.h>
9 #include <timer.h>
10 #include "me.h"
11 #include "pch.h"
12 
13 static const char *me_ack_values[] = {
14 	[ME_HFS_ACK_NO_DID]	= "No DID Ack received",
15 	[ME_HFS_ACK_RESET]	= "Non-power cycle reset",
16 	[ME_HFS_ACK_PWR_CYCLE]	= "Power cycle reset",
17 	[ME_HFS_ACK_S3]		= "Go to S3",
18 	[ME_HFS_ACK_S4]		= "Go to S4",
19 	[ME_HFS_ACK_S5]		= "Go to S5",
20 	[ME_HFS_ACK_GBL_RESET]	= "Global Reset",
21 	[ME_HFS_ACK_CONTINUE]	= "Continue to boot"
22 };
23 
intel_early_me_status(void)24 void intel_early_me_status(void)
25 {
26 	union me_hfs hfs = { .raw = pci_read_config32(PCH_ME_DEV, PCI_ME_HFS) };
27 	union me_hfs2 hfs2 = { .raw = pci_read_config32(PCH_ME_DEV, PCI_ME_HFS2) };
28 
29 	intel_me_status(hfs, hfs2);
30 }
31 
intel_early_me_init(void)32 int intel_early_me_init(void)
33 {
34 	int count;
35 	union me_uma uma;
36 	union me_hfs hfs;
37 
38 	printk(BIOS_INFO, "Intel ME early init\n");
39 
40 	/* Wait for ME UMA SIZE VALID bit to be set */
41 	/* FIXME: ME9 BGW indicates a 5 sec poll timeout. */
42 	for (count = ME_RETRY; count > 0; --count) {
43 		uma.raw = pci_read_config32(PCH_ME_DEV, PCI_ME_UMA);
44 		if (uma.valid)
45 			break;
46 		udelay(ME_DELAY);
47 	}
48 	if (!count) {
49 		printk(BIOS_ERR, "ME is not ready!\n");
50 		return -1;
51 	}
52 
53 	/* Check for valid firmware */
54 	hfs.raw = pci_read_config32(PCH_ME_DEV, PCI_ME_HFS);
55 	if (hfs.fpt_bad) {
56 		printk(BIOS_WARNING, "ME has bad firmware\n");
57 		return -1;
58 	}
59 
60 	printk(BIOS_INFO, "Intel ME firmware is ready\n");
61 	return 0;
62 }
63 
intel_early_me_cpu_replacement_check(void)64 bool intel_early_me_cpu_replacement_check(void)
65 {
66 	printk(BIOS_DEBUG, "ME: Checking whether CPU was replaced... ");
67 
68 	struct stopwatch timer;
69 	stopwatch_init_msecs_expire(&timer, 50);
70 
71 	union me_hfs2 hfs2;
72 	do {
73 		hfs2.raw = pci_read_config32(PCH_ME_DEV, PCI_ME_HFS2);
74 		if (stopwatch_expired(&timer)) {
75 			/* Assume CPU was replaced just in case */
76 			printk(BIOS_DEBUG, "timed out, assuming CPU was replaced\n");
77 			return true;
78 		}
79 		udelay(ME_DELAY);
80 	} while (!hfs2.cpu_replaced_valid);
81 
82 	if (hfs2.warm_reset_request) {
83 		printk(BIOS_DEBUG, "warm reset needed for dynamic fusing\n");
84 		system_reset();
85 	}
86 
87 	printk(BIOS_DEBUG, "%sreplaced\n", hfs2.cpu_replaced_sts ? "" : "not ");
88 	return hfs2.cpu_replaced_sts;
89 }
90 
intel_early_me_uma_size(void)91 int intel_early_me_uma_size(void)
92 {
93 	union me_uma uma = { .raw = pci_read_config32(PCH_ME_DEV, PCI_ME_UMA) };
94 
95 	if (uma.valid) {
96 		printk(BIOS_DEBUG, "ME: Requested %uMB UMA\n", uma.size);
97 		return uma.size;
98 	}
99 
100 	printk(BIOS_DEBUG, "ME: Invalid UMA size\n");
101 	return 0;
102 }
103 
set_global_reset(int enable)104 static inline void set_global_reset(int enable)
105 {
106 	u32 pmir = pci_read_config32(PCH_LPC_DEV, PMIR);
107 
108 	/* CF9GR indicates a Global Reset */
109 	if (enable)
110 		pmir |= PMIR_CF9GR;
111 	else
112 		pmir &= ~PMIR_CF9GR;
113 
114 	pci_write_config32(PCH_LPC_DEV, PMIR, pmir);
115 }
116 
intel_early_me_init_done(u8 status)117 int intel_early_me_init_done(u8 status)
118 {
119 	u8 reset;
120 	int count;
121 	u32 mebase_l, mebase_h;
122 	union me_hfs hfs;
123 	union me_did did = {
124 		.init_done = ME_INIT_DONE,
125 		.status = status
126 	};
127 
128 	/* MEBASE from MESEG_BASE[35:20] */
129 	mebase_l = pci_read_config32(PCI_CPU_DEVICE, PCI_CPU_MEBASE_L);
130 	mebase_h = pci_read_config32(PCI_CPU_DEVICE, PCI_CPU_MEBASE_H) & 0xf;
131 	did.uma_base = (mebase_l >> 20) | (mebase_h << 12);
132 
133 	/* Send message to ME */
134 	printk(BIOS_DEBUG, "ME: Sending Init Done with status: %d, "
135 	       "UMA base: 0x%04x\n", status, did.uma_base);
136 
137 	pci_write_config32(PCH_ME_DEV, PCI_ME_H_GS, did.raw);
138 
139 	/*
140 	 * The ME firmware does not respond with an ACK when NOMEM or ERROR
141 	 * are sent.
142 	 */
143 	if (status == ME_INIT_STATUS_NOMEM || status == ME_INIT_STATUS_ERROR)
144 		return 0;
145 
146 	/* Must wait for ME acknowledgement */
147 	for (count = ME_RETRY; count > 0; --count) {
148 		hfs.raw = pci_read_config32(PCH_ME_DEV, PCI_ME_HFS);
149 		if (hfs.bios_msg_ack)
150 			break;
151 		udelay(ME_DELAY);
152 	}
153 	if (!count) {
154 		printk(BIOS_ERR, "ME failed to respond\n");
155 		return -1;
156 	}
157 
158 	/* Return the requested BIOS action */
159 	printk(BIOS_NOTICE, "ME: Requested BIOS Action: %s\n",
160 	       me_ack_values[hfs.ack_data]);
161 
162 	/* Check status after acknowledgement */
163 	intel_early_me_status();
164 
165 	reset = 0;
166 	switch (hfs.ack_data) {
167 	case ME_HFS_ACK_CONTINUE:
168 		/* Continue to boot */
169 		return 0;
170 	case ME_HFS_ACK_RESET:
171 		/* Non-power cycle reset */
172 		set_global_reset(0);
173 		reset = 0x06;
174 		break;
175 	case ME_HFS_ACK_PWR_CYCLE:
176 		/* Power cycle reset */
177 		set_global_reset(0);
178 		reset = 0x0e;
179 		break;
180 	case ME_HFS_ACK_GBL_RESET:
181 		/* Global reset */
182 		set_global_reset(1);
183 		reset = 0x0e;
184 		break;
185 	case ME_HFS_ACK_S3:
186 	case ME_HFS_ACK_S4:
187 	case ME_HFS_ACK_S5:
188 		break;
189 	}
190 
191 	/* Perform the requested reset */
192 	if (reset) {
193 		outb(reset, 0xcf9);
194 		halt();
195 	}
196 	return -1;
197 }
198