blob: 70ba301c38fd2c0c69f5bc8b7606d2d64987cffd [file] [log] [blame]
Stefan Reinauer8e073822012-04-04 00:07:22 +02001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2011 The Chromium OS Authors. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; version 2 of
9 * the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
Stefan Reinauer8e073822012-04-04 00:07:22 +020015 */
16
17/*
18 * This is a ramstage driver for the Intel Management Engine found in the
19 * 6-series chipset. It handles the required boot-time messages over the
20 * MMIO-based Management Engine Interface to tell the ME that the BIOS is
21 * finished with POST. Additional messages are defined for debug but are
22 * not used unless the console loglevel is high enough.
23 */
24
25#include <arch/acpi.h>
Stefan Reinauer8e073822012-04-04 00:07:22 +020026#include <arch/io.h>
27#include <console/console.h>
28#include <device/pci_ids.h>
29#include <device/pci_def.h>
30#include <string.h>
31#include <delay.h>
Duncan Lauriec1c94352012-07-13 10:11:54 -070032#include <elog.h>
Patrick Georgi546953c2014-11-29 10:38:17 +010033#include <halt.h>
Stefan Reinauer8e073822012-04-04 00:07:22 +020034
35#ifdef __SMM__
Kyösti Mälkkib4a45dc2013-07-26 08:53:59 +030036#include <arch/io.h>
Stefan Reinauer8e073822012-04-04 00:07:22 +020037#else
38# include <device/device.h>
39# include <device/pci.h>
40#endif
41
42#include "me.h"
43#include "pch.h"
44
Martin Roth7a1a3ad2017-06-24 21:29:38 -060045#if IS_ENABLED(CONFIG_CHROMEOS)
Stefan Reinauer8e073822012-04-04 00:07:22 +020046#include <vendorcode/google/chromeos/gnvs.h>
47#endif
48
49#ifndef __SMM__
50/* Path that the BIOS should take based on ME state */
51static const char *me_bios_path_values[] = {
52 [ME_NORMAL_BIOS_PATH] = "Normal",
53 [ME_S3WAKE_BIOS_PATH] = "S3 Wake",
54 [ME_ERROR_BIOS_PATH] = "Error",
55 [ME_RECOVERY_BIOS_PATH] = "Recovery",
56 [ME_DISABLE_BIOS_PATH] = "Disable",
57 [ME_FIRMWARE_UPDATE_BIOS_PATH] = "Firmware Update",
58};
59#endif
60
61/* MMIO base address for MEI interface */
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080062static u32 *mei_base_address;
Stefan Reinauer8e073822012-04-04 00:07:22 +020063
Martin Roth7a1a3ad2017-06-24 21:29:38 -060064#if IS_ENABLED(CONFIG_DEBUG_INTEL_ME)
Stefan Reinauer8e073822012-04-04 00:07:22 +020065static void mei_dump(void *ptr, int dword, int offset, const char *type)
66{
67 struct mei_csr *csr;
68
69 printk(BIOS_SPEW, "%-9s[%02x] : ", type, offset);
70
71 switch (offset) {
72 case MEI_H_CSR:
73 case MEI_ME_CSR_HA:
74 csr = ptr;
75 if (!csr) {
76 printk(BIOS_SPEW, "ERROR: 0x%08x\n", dword);
77 break;
78 }
79 printk(BIOS_SPEW, "cbd=%u cbrp=%02u cbwp=%02u ready=%u "
80 "reset=%u ig=%u is=%u ie=%u\n", csr->buffer_depth,
81 csr->buffer_read_ptr, csr->buffer_write_ptr,
82 csr->ready, csr->reset, csr->interrupt_generate,
83 csr->interrupt_status, csr->interrupt_enable);
84 break;
85 case MEI_ME_CB_RW:
86 case MEI_H_CB_WW:
87 printk(BIOS_SPEW, "CB: 0x%08x\n", dword);
88 break;
89 default:
90 printk(BIOS_SPEW, "0x%08x\n", offset);
91 break;
92 }
93}
94#else
95# define mei_dump(ptr,dword,offset,type) do {} while (0)
96#endif
97
98/*
99 * ME/MEI access helpers using memcpy to avoid aliasing.
100 */
101
102static inline void mei_read_dword_ptr(void *ptr, int offset)
103{
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800104 u32 dword = read32(mei_base_address + (offset/sizeof(u32)));
Stefan Reinauer8e073822012-04-04 00:07:22 +0200105 memcpy(ptr, &dword, sizeof(dword));
106 mei_dump(ptr, dword, offset, "READ");
107}
108
109static inline void mei_write_dword_ptr(void *ptr, int offset)
110{
111 u32 dword = 0;
112 memcpy(&dword, ptr, sizeof(dword));
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800113 write32(mei_base_address + (offset/sizeof(u32)), dword);
Stefan Reinauer8e073822012-04-04 00:07:22 +0200114 mei_dump(ptr, dword, offset, "WRITE");
115}
116
117#ifndef __SMM__
118static inline void pci_read_dword_ptr(device_t dev, void *ptr, int offset)
119{
120 u32 dword = pci_read_config32(dev, offset);
121 memcpy(ptr, &dword, sizeof(dword));
122 mei_dump(ptr, dword, offset, "PCI READ");
123}
124#endif
125
126static inline void read_host_csr(struct mei_csr *csr)
127{
128 mei_read_dword_ptr(csr, MEI_H_CSR);
129}
130
131static inline void write_host_csr(struct mei_csr *csr)
132{
133 mei_write_dword_ptr(csr, MEI_H_CSR);
134}
135
136static inline void read_me_csr(struct mei_csr *csr)
137{
138 mei_read_dword_ptr(csr, MEI_ME_CSR_HA);
139}
140
141static inline void write_cb(u32 dword)
142{
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800143 write32(mei_base_address + (MEI_H_CB_WW/sizeof(u32)), dword);
Stefan Reinauer8e073822012-04-04 00:07:22 +0200144 mei_dump(NULL, dword, MEI_H_CB_WW, "WRITE");
145}
146
147static inline u32 read_cb(void)
148{
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800149 u32 dword = read32(mei_base_address + (MEI_ME_CB_RW/sizeof(u32)));
Stefan Reinauer8e073822012-04-04 00:07:22 +0200150 mei_dump(NULL, dword, MEI_ME_CB_RW, "READ");
151 return dword;
152}
153
154/* Wait for ME ready bit to be asserted */
155static int mei_wait_for_me_ready(void)
156{
157 struct mei_csr me;
158 unsigned try = ME_RETRY;
159
160 while (try--) {
161 read_me_csr(&me);
162 if (me.ready)
163 return 0;
164 udelay(ME_DELAY);
165 }
166
167 printk(BIOS_ERR, "ME: failed to become ready\n");
168 return -1;
169}
170
171static void mei_reset(void)
172{
173 struct mei_csr host;
174
175 if (mei_wait_for_me_ready() < 0)
176 return;
177
178 /* Reset host and ME circular buffers for next message */
179 read_host_csr(&host);
180 host.reset = 1;
181 host.interrupt_generate = 1;
182 write_host_csr(&host);
183
184 if (mei_wait_for_me_ready() < 0)
185 return;
186
187 /* Re-init and indicate host is ready */
188 read_host_csr(&host);
189 host.interrupt_generate = 1;
190 host.ready = 1;
191 host.reset = 0;
192 write_host_csr(&host);
193}
194
195static int mei_send_msg(struct mei_header *mei, struct mkhi_header *mkhi,
196 void *req_data)
197{
198 struct mei_csr host;
199 unsigned ndata, n;
200 u32 *data;
201
202 /* Number of dwords to write, ignoring MKHI */
203 ndata = mei->length >> 2;
204
205 /* Pad non-dword aligned request message length */
206 if (mei->length & 3)
207 ndata++;
208 if (!ndata) {
209 printk(BIOS_DEBUG, "ME: request does not include MKHI\n");
210 return -1;
211 }
212 ndata++; /* Add MEI header */
213
214 /*
215 * Make sure there is still room left in the circular buffer.
216 * Reset the buffer pointers if the requested message will not fit.
217 */
218 read_host_csr(&host);
219 if ((host.buffer_depth - host.buffer_write_ptr) < ndata) {
220 printk(BIOS_ERR, "ME: circular buffer full, resetting...\n");
221 mei_reset();
222 read_host_csr(&host);
223 }
224
225 /*
226 * This implementation does not handle splitting large messages
227 * across multiple transactions. Ensure the requested length
228 * will fit in the available circular buffer depth.
229 */
230 if ((host.buffer_depth - host.buffer_write_ptr) < ndata) {
231 printk(BIOS_ERR, "ME: message (%u) too large for buffer (%u)\n",
232 ndata + 2, host.buffer_depth);
233 return -1;
234 }
235
236 /* Write MEI header */
237 mei_write_dword_ptr(mei, MEI_H_CB_WW);
238 ndata--;
239
240 /* Write MKHI header */
241 mei_write_dword_ptr(mkhi, MEI_H_CB_WW);
242 ndata--;
243
244 /* Write message data */
245 data = req_data;
246 for (n = 0; n < ndata; ++n)
247 write_cb(*data++);
248
249 /* Generate interrupt to the ME */
250 read_host_csr(&host);
251 host.interrupt_generate = 1;
252 write_host_csr(&host);
253
254 /* Make sure ME is ready after sending request data */
255 return mei_wait_for_me_ready();
256}
257
258static int mei_recv_msg(struct mei_header *mei, struct mkhi_header *mkhi,
259 void *rsp_data, int rsp_bytes)
260{
261 struct mei_header mei_rsp;
262 struct mkhi_header mkhi_rsp;
263 struct mei_csr me, host;
264 unsigned ndata, n;
265 unsigned expected;
266 u32 *data;
267
268 /* Total number of dwords to read from circular buffer */
269 expected = (rsp_bytes + sizeof(mei_rsp) + sizeof(mkhi_rsp)) >> 2;
270 if (rsp_bytes & 3)
271 expected++;
272
273 /*
274 * The interrupt status bit does not appear to indicate that the
275 * message has actually been received. Instead we wait until the
276 * expected number of dwords are present in the circular buffer.
277 */
278 for (n = ME_RETRY; n; --n) {
279 read_me_csr(&me);
280 if ((me.buffer_write_ptr - me.buffer_read_ptr) >= expected)
281 break;
282 udelay(ME_DELAY);
283 }
284 if (!n) {
285 printk(BIOS_ERR, "ME: timeout waiting for data: expected "
286 "%u, available %u\n", expected,
287 me.buffer_write_ptr - me.buffer_read_ptr);
288 return -1;
289 }
290
291 /* Read and verify MEI response header from the ME */
292 mei_read_dword_ptr(&mei_rsp, MEI_ME_CB_RW);
293 if (!mei_rsp.is_complete) {
294 printk(BIOS_ERR, "ME: response is not complete\n");
295 return -1;
296 }
297
298 /* Handle non-dword responses and expect at least MKHI header */
299 ndata = mei_rsp.length >> 2;
300 if (mei_rsp.length & 3)
301 ndata++;
302 if (ndata != (expected - 1)) {
303 printk(BIOS_ERR, "ME: response is missing data\n");
304 return -1;
305 }
306
307 /* Read and verify MKHI response header from the ME */
308 mei_read_dword_ptr(&mkhi_rsp, MEI_ME_CB_RW);
309 if (!mkhi_rsp.is_response ||
310 mkhi->group_id != mkhi_rsp.group_id ||
311 mkhi->command != mkhi_rsp.command) {
312 printk(BIOS_ERR, "ME: invalid response, group %u ?= %u, "
313 "command %u ?= %u, is_response %u\n", mkhi->group_id,
314 mkhi_rsp.group_id, mkhi->command, mkhi_rsp.command,
315 mkhi_rsp.is_response);
316 return -1;
317 }
318 ndata--; /* MKHI header has been read */
319
320 /* Make sure caller passed a buffer with enough space */
321 if (ndata != (rsp_bytes >> 2)) {
322 printk(BIOS_ERR, "ME: not enough room in response buffer: "
323 "%u != %u\n", ndata, rsp_bytes >> 2);
324 return -1;
325 }
326
327 /* Read response data from the circular buffer */
328 data = rsp_data;
329 for (n = 0; n < ndata; ++n)
330 *data++ = read_cb();
331
332 /* Tell the ME that we have consumed the response */
333 read_host_csr(&host);
334 host.interrupt_status = 1;
335 host.interrupt_generate = 1;
336 write_host_csr(&host);
337
338 return mei_wait_for_me_ready();
339}
340
341static inline int mei_sendrecv(struct mei_header *mei, struct mkhi_header *mkhi,
342 void *req_data, void *rsp_data, int rsp_bytes)
343{
344 if (mei_send_msg(mei, mkhi, req_data) < 0)
345 return -1;
346 if (mei_recv_msg(mei, mkhi, rsp_data, rsp_bytes) < 0)
347 return -1;
348 return 0;
349}
350
Stefan Reinauer998f3a22012-06-11 15:15:46 -0700351#ifdef __SMM__
Stefan Reinauer8e073822012-04-04 00:07:22 +0200352/* Send END OF POST message to the ME */
Stefan Reinauer998f3a22012-06-11 15:15:46 -0700353static int mkhi_end_of_post(void)
Stefan Reinauer8e073822012-04-04 00:07:22 +0200354{
355 struct mkhi_header mkhi = {
356 .group_id = MKHI_GROUP_ID_GEN,
357 .command = MKHI_END_OF_POST,
358 };
359 struct mei_header mei = {
360 .is_complete = 1,
361 .host_address = MEI_HOST_ADDRESS,
362 .client_address = MEI_ADDRESS_MKHI,
363 .length = sizeof(mkhi),
364 };
365
366 /* Send request and wait for response */
367 if (mei_sendrecv(&mei, &mkhi, NULL, NULL, 0) < 0) {
368 printk(BIOS_ERR, "ME: END OF POST message failed\n");
369 return -1;
370 }
371
372 printk(BIOS_INFO, "ME: END OF POST message successful\n");
373 return 0;
374}
Stefan Reinauer998f3a22012-06-11 15:15:46 -0700375#endif
Stefan Reinauer8e073822012-04-04 00:07:22 +0200376
377#if (CONFIG_DEFAULT_CONSOLE_LOGLEVEL >= BIOS_DEBUG) && !defined(__SMM__)
378/* Get ME firmware version */
379static int mkhi_get_fw_version(void)
380{
381 struct me_fw_version version;
382 struct mkhi_header mkhi = {
383 .group_id = MKHI_GROUP_ID_GEN,
384 .command = MKHI_GET_FW_VERSION,
385 };
386 struct mei_header mei = {
387 .is_complete = 1,
388 .host_address = MEI_HOST_ADDRESS,
389 .client_address = MEI_ADDRESS_MKHI,
390 .length = sizeof(mkhi),
391 };
392
393 /* Send request and wait for response */
394 if (mei_sendrecv(&mei, &mkhi, NULL, &version, sizeof(version)) < 0) {
395 printk(BIOS_ERR, "ME: GET FW VERSION message failed\n");
396 return -1;
397 }
398
399 printk(BIOS_INFO, "ME: Firmware Version %u.%u.%u.%u (code) "
400 "%u.%u.%u.%u (recovery)\n",
401 version.code_major, version.code_minor,
402 version.code_build_number, version.code_hot_fix,
403 version.recovery_major, version.recovery_minor,
404 version.recovery_build_number, version.recovery_hot_fix);
405
406 return 0;
407}
408
409static inline void print_cap(const char *name, int state)
410{
411 printk(BIOS_DEBUG, "ME Capability: %-30s : %sabled\n",
412 name, state ? "en" : "dis");
413}
414
415/* Get ME Firmware Capabilities */
416static int mkhi_get_fwcaps(void)
417{
418 u32 rule_id = 0;
419 struct me_fwcaps cap;
420 struct mkhi_header mkhi = {
421 .group_id = MKHI_GROUP_ID_FWCAPS,
422 .command = MKHI_FWCAPS_GET_RULE,
423 };
424 struct mei_header mei = {
425 .is_complete = 1,
426 .host_address = MEI_HOST_ADDRESS,
427 .client_address = MEI_ADDRESS_MKHI,
428 .length = sizeof(mkhi) + sizeof(rule_id),
429 };
430
431 /* Send request and wait for response */
432 if (mei_sendrecv(&mei, &mkhi, &rule_id, &cap, sizeof(cap)) < 0) {
433 printk(BIOS_ERR, "ME: GET FWCAPS message failed\n");
434 return -1;
435 }
436
437 print_cap("Full Network manageability", cap.caps_sku.full_net);
438 print_cap("Regular Network manageability", cap.caps_sku.std_net);
439 print_cap("Manageability", cap.caps_sku.manageability);
440 print_cap("Small business technology", cap.caps_sku.small_business);
441 print_cap("Level III manageability", cap.caps_sku.l3manageability);
442 print_cap("IntelR Anti-Theft (AT)", cap.caps_sku.intel_at);
443 print_cap("IntelR Capability Licensing Service (CLS)",
444 cap.caps_sku.intel_cls);
445 print_cap("IntelR Power Sharing Technology (MPC)",
446 cap.caps_sku.intel_mpc);
447 print_cap("ICC Over Clocking", cap.caps_sku.icc_over_clocking);
Elyes HAOUASba28e8d2016-08-31 19:22:16 +0200448 print_cap("Protected Audio Video Path (PAVP)", cap.caps_sku.pavp);
Stefan Reinauer8e073822012-04-04 00:07:22 +0200449 print_cap("IPV6", cap.caps_sku.ipv6);
450 print_cap("KVM Remote Control (KVM)", cap.caps_sku.kvm);
451 print_cap("Outbreak Containment Heuristic (OCH)", cap.caps_sku.och);
452 print_cap("Virtual LAN (VLAN)", cap.caps_sku.vlan);
453 print_cap("TLS", cap.caps_sku.tls);
454 print_cap("Wireless LAN (WLAN)", cap.caps_sku.wlan);
455
456 return 0;
457}
458#endif
459
Martin Roth7a1a3ad2017-06-24 21:29:38 -0600460#if IS_ENABLED(CONFIG_CHROMEOS) && 0 /* DISABLED */
Stefan Reinauer8e073822012-04-04 00:07:22 +0200461/* Tell ME to issue a global reset */
462int mkhi_global_reset(void)
463{
464 struct me_global_reset reset = {
465 .request_origin = GLOBAL_RESET_BIOS_POST,
466 .reset_type = CBM_RR_GLOBAL_RESET,
467 };
468 struct mkhi_header mkhi = {
469 .group_id = MKHI_GROUP_ID_CBM,
470 .command = MKHI_GLOBAL_RESET,
471 };
472 struct mei_header mei = {
473 .is_complete = 1,
474 .length = sizeof(mkhi) + sizeof(reset),
475 .host_address = MEI_HOST_ADDRESS,
476 .client_address = MEI_ADDRESS_MKHI,
477 };
478
479 printk(BIOS_NOTICE, "ME: Requesting global reset\n");
480
481 /* Send request and wait for response */
482 if (mei_sendrecv(&mei, &mkhi, &reset, NULL, 0) < 0) {
483 /* No response means reset will happen shortly... */
Patrick Georgi546953c2014-11-29 10:38:17 +0100484 halt();
Stefan Reinauer8e073822012-04-04 00:07:22 +0200485 }
486
487 /* If the ME responded it rejected the reset request */
488 printk(BIOS_ERR, "ME: Global Reset failed\n");
489 return -1;
490}
Stefan Reinauer998f3a22012-06-11 15:15:46 -0700491#endif
Stefan Reinauer8e073822012-04-04 00:07:22 +0200492
493#ifdef __SMM__
Stefan Reinauer998f3a22012-06-11 15:15:46 -0700494static void intel_me7_finalize_smm(void)
Stefan Reinauer8e073822012-04-04 00:07:22 +0200495{
496 struct me_hfs hfs;
497 u32 reg32;
498
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800499 mei_base_address = (u32 *)
500 (pci_read_config32(PCH_ME_DEV, PCI_BASE_ADDRESS_0) & ~0xf);
Stefan Reinauer8e073822012-04-04 00:07:22 +0200501
502 /* S3 path will have hidden this device already */
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800503 if (!mei_base_address || mei_base_address == (u32 *)0xfffffff0)
Stefan Reinauer8e073822012-04-04 00:07:22 +0200504 return;
505
506 /* Make sure ME is in a mode that expects EOP */
Kyösti Mälkkifd98c652013-07-26 08:50:53 +0300507 reg32 = pci_read_config32(PCH_ME_DEV, PCI_ME_HFS);
Stefan Reinauer8e073822012-04-04 00:07:22 +0200508 memcpy(&hfs, &reg32, sizeof(u32));
509
510 /* Abort and leave device alone if not normal mode */
511 if (hfs.fpt_bad ||
512 hfs.working_state != ME_HFS_CWS_NORMAL ||
513 hfs.operation_mode != ME_HFS_MODE_NORMAL)
514 return;
515
516 /* Try to send EOP command so ME stops accepting other commands */
517 mkhi_end_of_post();
518
519 /* Make sure IO is disabled */
Kyösti Mälkkifd98c652013-07-26 08:50:53 +0300520 reg32 = pci_read_config32(PCH_ME_DEV, PCI_COMMAND);
Stefan Reinauer8e073822012-04-04 00:07:22 +0200521 reg32 &= ~(PCI_COMMAND_MASTER |
522 PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
Kyösti Mälkkifd98c652013-07-26 08:50:53 +0300523 pci_write_config32(PCH_ME_DEV, PCI_COMMAND, reg32);
Stefan Reinauer8e073822012-04-04 00:07:22 +0200524
525 /* Hide the PCI device */
526 RCBA32_OR(FD2, PCH_DISABLE_MEI1);
527}
528
Stefan Reinauer998f3a22012-06-11 15:15:46 -0700529void intel_me_finalize_smm(void)
530{
Kyösti Mälkkifd98c652013-07-26 08:50:53 +0300531 u32 did = pci_read_config32(PCH_ME_DEV, PCI_VENDOR_ID);
Stefan Reinauer998f3a22012-06-11 15:15:46 -0700532 switch (did) {
Duncan Laurie708f7312012-07-10 15:15:41 -0700533 case 0x1c3a8086:
Stefan Reinauer998f3a22012-06-11 15:15:46 -0700534 intel_me7_finalize_smm();
535 break;
Duncan Laurie708f7312012-07-10 15:15:41 -0700536 case 0x1e3a8086:
Stefan Reinauer998f3a22012-06-11 15:15:46 -0700537 intel_me8_finalize_smm();
538 break;
539 default:
540 printk(BIOS_ERR, "No finalize handler for ME %08x.\n", did);
541 }
542}
Stefan Reinauer8e073822012-04-04 00:07:22 +0200543#else /* !__SMM__ */
544
545/* Determine the path that we should take based on ME status */
546static me_bios_path intel_me_path(device_t dev)
547{
548 me_bios_path path = ME_DISABLE_BIOS_PATH;
549 struct me_hfs hfs;
550 struct me_gmes gmes;
551
Stefan Reinauer8e073822012-04-04 00:07:22 +0200552 /* S3 wake skips all MKHI messages */
Kyösti Mälkkic3ed8862014-06-19 19:50:51 +0300553 if (acpi_is_wakeup_s3())
Stefan Reinauer8e073822012-04-04 00:07:22 +0200554 return ME_S3WAKE_BIOS_PATH;
Stefan Reinauer8e073822012-04-04 00:07:22 +0200555
556 pci_read_dword_ptr(dev, &hfs, PCI_ME_HFS);
557 pci_read_dword_ptr(dev, &gmes, PCI_ME_GMES);
558
559 /* Check and dump status */
560 intel_me_status(&hfs, &gmes);
561
Stefan Reinauer8e073822012-04-04 00:07:22 +0200562 /* Check Current Working State */
563 switch (hfs.working_state) {
564 case ME_HFS_CWS_NORMAL:
565 path = ME_NORMAL_BIOS_PATH;
566 break;
567 case ME_HFS_CWS_REC:
568 path = ME_RECOVERY_BIOS_PATH;
569 break;
570 default:
571 path = ME_DISABLE_BIOS_PATH;
572 break;
573 }
574
575 /* Check Current Operation Mode */
576 switch (hfs.operation_mode) {
577 case ME_HFS_MODE_NORMAL:
578 break;
579 case ME_HFS_MODE_DEBUG:
580 case ME_HFS_MODE_DIS:
581 case ME_HFS_MODE_OVER_JMPR:
582 case ME_HFS_MODE_OVER_MEI:
583 default:
584 path = ME_DISABLE_BIOS_PATH;
585 break;
586 }
587
Duncan Laurie5c88c6f2012-09-01 14:00:23 -0700588 /* Check for any error code and valid firmware */
589 if (hfs.error_code || hfs.fpt_bad)
Stefan Reinauer8e073822012-04-04 00:07:22 +0200590 path = ME_ERROR_BIOS_PATH;
591
Martin Roth7a1a3ad2017-06-24 21:29:38 -0600592#if IS_ENABLED(CONFIG_ELOG)
Duncan Laurie5c88c6f2012-09-01 14:00:23 -0700593 if (path != ME_NORMAL_BIOS_PATH) {
594 struct elog_event_data_me_extended data = {
595 .current_working_state = hfs.working_state,
596 .operation_state = hfs.operation_state,
597 .operation_mode = hfs.operation_mode,
598 .error_code = hfs.error_code,
599 .progress_code = gmes.progress_code,
600 .current_pmevent = gmes.current_pmevent,
601 .current_state = gmes.current_state,
602 };
603 elog_add_event_byte(ELOG_TYPE_MANAGEMENT_ENGINE, path);
604 elog_add_event_raw(ELOG_TYPE_MANAGEMENT_ENGINE_EXT,
605 &data, sizeof(data));
606 }
607#endif
608
Stefan Reinauer8e073822012-04-04 00:07:22 +0200609 return path;
610}
611
612/* Prepare ME for MEI messages */
613static int intel_mei_setup(device_t dev)
614{
615 struct resource *res;
616 struct mei_csr host;
617 u32 reg32;
618
619 /* Find the MMIO base for the ME interface */
620 res = find_resource(dev, PCI_BASE_ADDRESS_0);
621 if (!res || res->base == 0 || res->size == 0) {
622 printk(BIOS_DEBUG, "ME: MEI resource not present!\n");
623 return -1;
624 }
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800625 mei_base_address = (u32*)(uintptr_t)res->base;
Stefan Reinauer8e073822012-04-04 00:07:22 +0200626
627 /* Ensure Memory and Bus Master bits are set */
628 reg32 = pci_read_config32(dev, PCI_COMMAND);
629 reg32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
630 pci_write_config32(dev, PCI_COMMAND, reg32);
631
632 /* Clean up status for next message */
633 read_host_csr(&host);
634 host.interrupt_generate = 1;
635 host.ready = 1;
636 host.reset = 0;
637 write_host_csr(&host);
638
639 return 0;
640}
641
642/* Read the Extend register hash of ME firmware */
643static int intel_me_extend_valid(device_t dev)
644{
645 struct me_heres status;
Stefan Reinauer49058c02012-06-11 14:13:09 -0700646 u32 extend[8] = {0};
Stefan Reinauer8e073822012-04-04 00:07:22 +0200647 int i, count = 0;
648
649 pci_read_dword_ptr(dev, &status, PCI_ME_HERES);
650 if (!status.extend_feature_present) {
651 printk(BIOS_ERR, "ME: Extend Feature not present\n");
652 return -1;
653 }
654
655 if (!status.extend_reg_valid) {
656 printk(BIOS_ERR, "ME: Extend Register not valid\n");
657 return -1;
658 }
659
660 switch (status.extend_reg_algorithm) {
661 case PCI_ME_EXT_SHA1:
662 count = 5;
663 printk(BIOS_DEBUG, "ME: Extend SHA-1: ");
664 break;
665 case PCI_ME_EXT_SHA256:
666 count = 8;
667 printk(BIOS_DEBUG, "ME: Extend SHA-256: ");
668 break;
669 default:
670 printk(BIOS_ERR, "ME: Extend Algorithm %d unknown\n",
671 status.extend_reg_algorithm);
672 return -1;
673 }
674
675 for (i = 0; i < count; ++i) {
676 extend[i] = pci_read_config32(dev, PCI_ME_HER(i));
677 printk(BIOS_DEBUG, "%08x", extend[i]);
678 }
679 printk(BIOS_DEBUG, "\n");
680
Martin Roth7a1a3ad2017-06-24 21:29:38 -0600681#if IS_ENABLED(CONFIG_CHROMEOS)
Stefan Reinauer8e073822012-04-04 00:07:22 +0200682 /* Save hash in NVS for the OS to verify */
683 chromeos_set_me_hash(extend, count);
684#endif
685
686 return 0;
687}
688
689/* Hide the ME virtual PCI devices */
690static void intel_me_hide(device_t dev)
691{
692 dev->enabled = 0;
693 pch_enable(dev);
694}
695
696/* Check whether ME is present and do basic init */
697static void intel_me_init(device_t dev)
698{
699 me_bios_path path = intel_me_path(dev);
700
701 /* Do initial setup and determine the BIOS path */
702 printk(BIOS_NOTICE, "ME: BIOS path: %s\n", me_bios_path_values[path]);
703
704 switch (path) {
705 case ME_S3WAKE_BIOS_PATH:
706 intel_me_hide(dev);
707 break;
708
709 case ME_NORMAL_BIOS_PATH:
710 /* Validate the extend register */
711 if (intel_me_extend_valid(dev) < 0)
712 break; /* TODO: force recovery mode */
713
714 /* Prepare MEI MMIO interface */
715 if (intel_mei_setup(dev) < 0)
716 break;
717
718#if (CONFIG_DEFAULT_CONSOLE_LOGLEVEL >= BIOS_DEBUG)
719 /* Print ME firmware version */
720 mkhi_get_fw_version();
721 /* Print ME firmware capabilities */
722 mkhi_get_fwcaps();
723#endif
724
725 /*
726 * Leave the ME unlocked in this path.
727 * It will be locked via SMI command later.
728 */
729 break;
730
731 case ME_ERROR_BIOS_PATH:
732 case ME_RECOVERY_BIOS_PATH:
733 case ME_DISABLE_BIOS_PATH:
734 case ME_FIRMWARE_UPDATE_BIOS_PATH:
Stefan Reinauer8e073822012-04-04 00:07:22 +0200735 break;
736 }
737}
738
739static void set_subsystem(device_t dev, unsigned vendor, unsigned device)
740{
741 if (!vendor || !device) {
742 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
743 pci_read_config32(dev, PCI_VENDOR_ID));
744 } else {
745 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
746 ((device & 0xffff) << 16) | (vendor & 0xffff));
747 }
748}
749
750static struct pci_operations pci_ops = {
751 .set_subsystem = set_subsystem,
752};
753
754static struct device_operations device_ops = {
755 .read_resources = pci_dev_read_resources,
756 .set_resources = pci_dev_set_resources,
757 .enable_resources = pci_dev_enable_resources,
758 .init = intel_me_init,
Stefan Reinauer8e073822012-04-04 00:07:22 +0200759 .ops_pci = &pci_ops,
760};
761
762static const struct pci_driver intel_me __pci_driver = {
763 .ops = &device_ops,
764 .vendor = PCI_VENDOR_ID_INTEL,
765 .device = 0x1c3a,
766};
767
768#endif /* !__SMM__ */