coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
me_common.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <device/mmio.h>
4 #include <device/device.h>
5 #include <device/pci.h>
6 #include <device/pci_ops.h>
7 #include <console/console.h>
8 #include <device/pci_ids.h>
9 #include <device/pci_def.h>
10 #include <string.h>
11 #include <delay.h>
12 #include <halt.h>
13 #include <timer.h>
14 
15 #include "me.h"
16 #include "pch.h"
17 
18 #include <vendorcode/google/chromeos/chromeos.h>
19 
20 /* Path that the BIOS should take based on ME state */
21 static const char *const me_bios_path_values[] = {
22  [ME_NORMAL_BIOS_PATH] = "Normal",
23  [ME_S3WAKE_BIOS_PATH] = "S3 Wake",
24  [ME_ERROR_BIOS_PATH] = "Error",
25  [ME_RECOVERY_BIOS_PATH] = "Recovery",
26  [ME_DISABLE_BIOS_PATH] = "Disable",
27  [ME_FIRMWARE_UPDATE_BIOS_PATH] = "Firmware Update",
28 };
29 
30 const char *const me_get_bios_path_string(int path)
31 {
32  return me_bios_path_values[path];
33 }
34 
35 /* MMIO base address for MEI interface */
37 
38 static void mei_dump(void *ptr, int dword, int offset, const char *type)
39 {
40  struct mei_csr *csr;
41 
42  if (!CONFIG(DEBUG_INTEL_ME))
43  return;
44 
45  printk(BIOS_SPEW, "%-9s[%02x] : ", type, offset);
46 
47  switch (offset) {
48  case MEI_H_CSR:
49  case MEI_ME_CSR_HA:
50  csr = ptr;
51  if (!csr) {
52  printk(BIOS_SPEW, "ERROR: 0x%08x\n", dword);
53  break;
54  }
55  printk(BIOS_SPEW, "cbd=%u cbrp=%02u cbwp=%02u ready=%u "
56  "reset=%u ig=%u is=%u ie=%u\n", csr->buffer_depth,
58  csr->ready, csr->reset, csr->interrupt_generate,
60  break;
61  case MEI_ME_CB_RW:
62  case MEI_H_CB_WW:
63  printk(BIOS_SPEW, "CB: 0x%08x\n", dword);
64  break;
65  default:
66  printk(BIOS_SPEW, "0x%08x\n", offset);
67  break;
68  }
69 }
70 
71 /*
72  * ME/MEI access helpers using memcpy to avoid aliasing.
73  */
74 
75 void mei_read_dword_ptr(void *ptr, int offset)
76 {
77  u32 dword = read32(mei_base_address + (offset / sizeof(u32)));
78  memcpy(ptr, &dword, sizeof(dword));
79  mei_dump(ptr, dword, offset, "READ");
80 }
81 
82 void mei_write_dword_ptr(void *ptr, int offset)
83 {
84  u32 dword = 0;
85  memcpy(&dword, ptr, sizeof(dword));
86  write32(mei_base_address + (offset / sizeof(u32)), dword);
87  mei_dump(ptr, dword, offset, "WRITE");
88 }
89 
90 void read_host_csr(struct mei_csr *csr)
91 {
93 }
94 
95 void write_host_csr(struct mei_csr *csr)
96 {
98 }
99 
100 void read_me_csr(struct mei_csr *csr)
101 {
103 }
104 
105 void write_cb(u32 dword)
106 {
107  write32(mei_base_address + (MEI_H_CB_WW / sizeof(u32)), dword);
108  mei_dump(NULL, dword, MEI_H_CB_WW, "WRITE");
109 }
110 
112 {
113  u32 dword = read32(mei_base_address + (MEI_ME_CB_RW / sizeof(u32)));
114  mei_dump(NULL, dword, MEI_ME_CB_RW, "READ");
115  return dword;
116 }
117 
118 /* Wait for ME ready bit to be asserted */
119 static int mei_wait_for_me_ready(void)
120 {
121  struct mei_csr me;
122  unsigned int try = ME_RETRY;
123 
124  while (try--) {
125  read_me_csr(&me);
126  if (me.ready)
127  return 0;
128  udelay(ME_DELAY);
129  }
130 
131  printk(BIOS_ERR, "ME: failed to become ready\n");
132  return -1;
133 }
134 
135 static void mei_reset(void)
136 {
137  struct mei_csr host;
138 
139  if (mei_wait_for_me_ready() < 0)
140  return;
141 
142  /* Reset host and ME circular buffers for next message */
143  read_host_csr(&host);
144  host.reset = 1;
145  host.interrupt_generate = 1;
146  write_host_csr(&host);
147 
148  if (mei_wait_for_me_ready() < 0)
149  return;
150 
151  /* Re-init and indicate host is ready */
152  read_host_csr(&host);
153  host.interrupt_generate = 1;
154  host.ready = 1;
155  host.reset = 0;
156  write_host_csr(&host);
157 }
158 
159 static int mei_send_msg(struct mei_header *mei, struct mkhi_header *mkhi, void *req_data)
160 {
161  struct mei_csr host;
162  unsigned int ndata, n;
163  u32 *data;
164 
165  /* Number of dwords to write, ignoring MKHI */
166  ndata = mei->length >> 2;
167 
168  /* Pad non-dword aligned request message length */
169  if (mei->length & 3)
170  ndata++;
171 
172  if (!ndata) {
173  printk(BIOS_DEBUG, "ME: request does not include MKHI\n");
174  return -1;
175  }
176  ndata++; /* Add MEI header */
177 
178  /*
179  * Make sure there is still room left in the circular buffer.
180  * Reset the buffer pointers if the requested message will not fit.
181  */
182  read_host_csr(&host);
183  if ((host.buffer_depth - host.buffer_write_ptr) < ndata) {
184  printk(BIOS_ERR, "ME: circular buffer full, resetting...\n");
185  mei_reset();
186  read_host_csr(&host);
187  }
188 
189  /*
190  * This implementation does not handle splitting large messages
191  * across multiple transactions. Ensure the requested length
192  * will fit in the available circular buffer depth.
193  */
194  if ((host.buffer_depth - host.buffer_write_ptr) < ndata) {
195  printk(BIOS_ERR, "ME: message (%u) too large for buffer (%u)\n",
196  ndata + 2, host.buffer_depth);
197  return -1;
198  }
199 
200  /* Write MEI header */
202  ndata--;
203 
204  /* Write MKHI header */
206  ndata--;
207 
208  /* Write message data */
209  data = req_data;
210  for (n = 0; n < ndata; ++n)
211  write_cb(*data++);
212 
213  /* Generate interrupt to the ME */
214  read_host_csr(&host);
215  host.interrupt_generate = 1;
216  write_host_csr(&host);
217 
218  /* Make sure ME is ready after sending request data */
219  return mei_wait_for_me_ready();
220 }
221 
222 static int mei_recv_msg(struct mkhi_header *mkhi, void *rsp_data, int rsp_bytes)
223 {
224  struct mei_header mei_rsp;
225  struct mkhi_header mkhi_rsp;
226  struct mei_csr me, host;
227  unsigned int ndata, n;
228  unsigned int expected;
229  u32 *data;
230 
231  /* Total number of dwords to read from circular buffer */
232  expected = (rsp_bytes + sizeof(mei_rsp) + sizeof(mkhi_rsp)) >> 2;
233  if (rsp_bytes & 3)
234  expected++;
235 
236  /*
237  * The interrupt status bit does not appear to indicate that the
238  * message has actually been received. Instead we wait until the
239  * expected number of dwords are present in the circular buffer.
240  */
241  for (n = ME_RETRY; n; --n) {
242  read_me_csr(&me);
243  if ((me.buffer_write_ptr - me.buffer_read_ptr) >= expected)
244  break;
245  udelay(ME_DELAY);
246  }
247 
248  if (!n) {
249  printk(BIOS_ERR, "ME: timeout waiting for data: expected %u, available %u\n",
250  expected, me.buffer_write_ptr - me.buffer_read_ptr);
251  return -1;
252  }
253 
254  /* Read and verify MEI response header from the ME */
255  mei_read_dword_ptr(&mei_rsp, MEI_ME_CB_RW);
256  if (!mei_rsp.is_complete) {
257  printk(BIOS_ERR, "ME: response is not complete\n");
258  return -1;
259  }
260 
261  /* Handle non-dword responses and expect at least MKHI header */
262  ndata = mei_rsp.length >> 2;
263  if (mei_rsp.length & 3)
264  ndata++;
265 
266  if (ndata != (expected - 1)) {
267  printk(BIOS_ERR, "ME: response is missing data %d != %d\n",
268  ndata, (expected - 1));
269  return -1;
270  }
271 
272  /* Read and verify MKHI response header from the ME */
273  mei_read_dword_ptr(&mkhi_rsp, MEI_ME_CB_RW);
274  if (!mkhi_rsp.is_response ||
275  mkhi->group_id != mkhi_rsp.group_id ||
276  mkhi->command != mkhi_rsp.command) {
277  printk(BIOS_ERR, "ME: invalid response, group %u ?= %u, "
278  "command %u ?= %u, is_response %u\n", mkhi->group_id,
279  mkhi_rsp.group_id, mkhi->command, mkhi_rsp.command,
280  mkhi_rsp.is_response);
281  return -1;
282  }
283  ndata--; /* MKHI header has been read */
284 
285  /* Make sure caller passed a buffer with enough space */
286  if (ndata != (rsp_bytes >> 2)) {
287  printk(BIOS_ERR, "ME: not enough room in response buffer: %u != %u\n",
288  ndata, rsp_bytes >> 2);
289  return -1;
290  }
291 
292  /* Read response data from the circular buffer */
293  data = rsp_data;
294  for (n = 0; n < ndata; ++n)
295  *data++ = read_cb();
296 
297  /* Tell the ME that we have consumed the response */
298  read_host_csr(&host);
299  host.interrupt_status = 1;
300  host.interrupt_generate = 1;
301  write_host_csr(&host);
302 
303  return mei_wait_for_me_ready();
304 }
305 
306 int mei_sendrecv(struct mei_header *mei, struct mkhi_header *mkhi,
307  void *req_data, void *rsp_data, int rsp_bytes)
308 {
309  if (mei_send_msg(mei, mkhi, req_data) < 0)
310  return -1;
311  if (mei_recv_msg(mkhi, rsp_data, rsp_bytes) < 0)
312  return -1;
313  return 0;
314 }
315 
316 #ifdef __SIMPLE_DEVICE__
317 
318 void update_mei_base_address(void)
319 {
321  mei_base_address = (u32 *)(uintptr_t)reg32;
322 }
323 
324 bool is_mei_base_address_valid(void)
325 {
326  return mei_base_address && mei_base_address != (u32 *)0xfffffff0;
327 }
328 
329 #else
330 
331 /* Prepare ME for MEI messages */
332 int intel_mei_setup(struct device *dev)
333 {
334  struct resource *res;
335  struct mei_csr host;
336 
337  /* Find the MMIO base for the ME interface */
339  if (!res || res->base == 0 || res->size == 0) {
340  printk(BIOS_DEBUG, "ME: MEI resource not present!\n");
341  return -1;
342  }
343  mei_base_address = (u32 *)(uintptr_t)res->base;
344 
345  /* Ensure Memory and Bus Master bits are set */
347 
348  /* Clean up status for next message */
349  read_host_csr(&host);
350  host.interrupt_generate = 1;
351  host.ready = 1;
352  host.reset = 0;
353  write_host_csr(&host);
354 
355  return 0;
356 }
357 
358 /* Read the Extend register hash of ME firmware */
360 {
361  union me_heres status;
362  u32 extend[8] = {0};
363  int i, count = 0;
364 
365  status.raw = pci_read_config32(dev, PCI_ME_HERES);
366  if (!status.extend_feature_present) {
367  printk(BIOS_ERR, "ME: Extend Feature not present\n");
368  return -1;
369  }
370 
371  if (!status.extend_reg_valid) {
372  printk(BIOS_ERR, "ME: Extend Register not valid\n");
373  return -1;
374  }
375 
376  switch (status.extend_reg_algorithm) {
377  case PCI_ME_EXT_SHA1:
378  count = 5;
379  printk(BIOS_DEBUG, "ME: Extend SHA-1: ");
380  break;
381  case PCI_ME_EXT_SHA256:
382  count = 8;
383  printk(BIOS_DEBUG, "ME: Extend SHA-256: ");
384  break;
385  default:
386  printk(BIOS_ERR, "ME: Extend Algorithm %d unknown\n",
387  status.extend_reg_algorithm);
388  return -1;
389  }
390 
391  for (i = 0; i < count; ++i) {
392  extend[i] = pci_read_config32(dev, PCI_ME_HER(i));
393  printk(BIOS_DEBUG, "%08x", extend[i]);
394  }
395  printk(BIOS_DEBUG, "\n");
396 
397  /* Save hash in NVS for the OS to verify */
398  if (CONFIG(CHROMEOS_NVS))
399  chromeos_set_me_hash(extend, count);
400 
401  return 0;
402 }
403 
404 /* Hide the ME virtual PCI devices */
405 void intel_me_hide(struct device *dev)
406 {
407  dev->enabled = 0;
408  pch_enable(dev);
409 }
410 
412 {
413  /* The binary sequence for the disable command was found by PT in some vendor BIOS */
414  struct me_disable message = {
416  .data = 0x01,
417  };
418  struct mkhi_header mkhi = {
420  .command = MKHI_FWCAPS_SET_RULE,
421  };
422  struct mei_header mei = {
423  .is_complete = 1,
424  .length = sizeof(mkhi) + sizeof(message),
425  .host_address = MEI_HOST_ADDRESS,
426  .client_address = MEI_ADDRESS_MKHI,
427  };
428  u32 resp;
429 
430  if (mei_sendrecv(&mei, &mkhi, &message, &resp, sizeof(resp)) < 0
431  || resp != MKHI_DISABLE_RULE_ID) {
432  printk(BIOS_WARNING, "ME: disable command failed\n");
433  return false;
434  }
435 
436  return true;
437 }
438 
440 {
441  /*
442  * TODO: Find smarter way to determine when we're ready to reboot.
443  *
444  * There has to be some bit in some register, or something, that indicates that ME has
445  * finished doing its thing and we're ready to reboot.
446  *
447  * It was not found yet, though, and waiting for a response after the disable command is
448  * not enough. If we reboot too early, ME will not be disabled on next boot. For now,
449  * let's just wait for 1 second here.
450  */
451  mdelay(1000);
452 }
453 
455 {
456  /* To bring ME out of Soft Temporary Disable Mode, host writes 0x20000000 to H_GS */
457  pci_write_config32(dev, PCI_ME_H_GS, 0x2 << 28);
458 }
459 
461 {
462  union me_hfs hfs;
463  struct stopwatch sw;
464 
466 
467  /**
468  * Wait for fw_init_complete. Check every 50 ms, give up after 20 sec.
469  * This is what vendor BIOS does. Usually it takes 1.5 seconds or so.
470  */
471  do {
472  mdelay(50);
473  hfs.raw = pci_read_config32(dev, PCI_ME_HFS);
474  if (hfs.fw_init_complete)
475  break;
476  } while (!stopwatch_expired(&sw));
477 
478  if (!hfs.fw_init_complete)
479  printk(BIOS_ERR, "ME: giving up on waiting for fw_init_complete\n");
480  else
481  printk(BIOS_NOTICE, "ME: took %lums to complete initialization\n",
483 }
484 
485 #endif
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
static uint32_t read32(const void *addr)
Definition: mmio.h:22
void * memcpy(void *dest, const void *src, size_t n)
Definition: memcpy.c:7
#define printk(level,...)
Definition: stdlib.h:16
void mdelay(unsigned int msecs)
Definition: delay.c:2
struct resource * probe_resource(const struct device *dev, unsigned int index)
See if a resource structure already exists for a given index.
Definition: device_util.c:323
@ CONFIG
Definition: dsi_common.h:201
static size_t offset
Definition: flashconsole.c:16
static __always_inline void pci_write_config32(const struct device *dev, u16 reg, u32 val)
Definition: pci_ops.h:76
static __always_inline void pci_or_config16(const struct device *dev, u16 reg, u16 ormask)
Definition: pci_ops.h:180
static __always_inline u32 pci_read_config32(const struct device *dev, u16 reg)
Definition: pci_ops.h:58
static int stopwatch_expired(struct stopwatch *sw)
Definition: timer.h:152
static long stopwatch_duration_msecs(struct stopwatch *sw)
Definition: timer.h:182
static void stopwatch_init_msecs_expire(struct stopwatch *sw, long ms)
Definition: timer.h:133
unsigned int type
Definition: edid.c:57
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define BIOS_NOTICE
BIOS_NOTICE - Unexpected but relatively insignificant.
Definition: loglevel.h:100
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
#define BIOS_SPEW
BIOS_SPEW - Excessively verbose output.
Definition: loglevel.h:142
#define BIOS_WARNING
BIOS_WARNING - Bad configuration.
Definition: loglevel.h:86
u32 read_cb(void)
Definition: me_common.c:111
static void mei_dump(void *ptr, int dword, int offset, const char *type)
Definition: me_common.c:38
int intel_mei_setup(struct device *dev)
Definition: me_common.c:332
void exit_soft_temp_disable(struct device *dev)
Definition: me_common.c:454
static int mei_wait_for_me_ready(void)
Definition: me_common.c:119
static int mei_send_msg(struct mei_header *mei, struct mkhi_header *mkhi, void *req_data)
Definition: me_common.c:159
const char *const me_get_bios_path_string(int path)
Definition: me_common.c:30
int intel_me_extend_valid(struct device *dev)
Definition: me_common.c:359
void write_host_csr(struct mei_csr *csr)
Definition: me_common.c:95
void intel_me_hide(struct device *dev)
Definition: me_common.c:405
void write_cb(u32 dword)
Definition: me_common.c:105
void mei_read_dword_ptr(void *ptr, int offset)
Definition: me_common.c:75
static void mei_reset(void)
Definition: me_common.c:135
void read_host_csr(struct mei_csr *csr)
Definition: me_common.c:90
static int mei_recv_msg(struct mkhi_header *mkhi, void *rsp_data, int rsp_bytes)
Definition: me_common.c:222
bool enter_soft_temp_disable(void)
Definition: me_common.c:411
static u32 * mei_base_address
Definition: me_common.c:36
void mei_write_dword_ptr(void *ptr, int offset)
Definition: me_common.c:82
int mei_sendrecv(struct mei_header *mei, struct mkhi_header *mkhi, void *req_data, void *rsp_data, int rsp_bytes)
Definition: me_common.c:306
void exit_soft_temp_disable_wait(struct device *dev)
Definition: me_common.c:460
void enter_soft_temp_disable_wait(void)
Definition: me_common.c:439
static const char *const me_bios_path_values[]
Definition: me_common.c:21
void read_me_csr(struct mei_csr *csr)
Definition: me_common.c:100
#define PCI_COMMAND_MASTER
Definition: pci_def.h:13
#define PCI_COMMAND_MEMORY
Definition: pci_def.h:12
#define PCI_BASE_ADDRESS_0
Definition: pci_def.h:63
#define PCI_COMMAND
Definition: pci_def.h:10
#define ME_RETRY
Definition: me.h:8
#define PCI_ME_HERES
Definition: me.h:192
#define ME_DELAY
Definition: me.h:9
#define MEI_H_CSR
Definition: me.h:209
#define MKHI_GROUP_ID_FWCAPS
Definition: me.h:245
#define MEI_ME_CSR_HA
Definition: me.h:211
#define MEI_ADDRESS_MKHI
Definition: me.h:229
#define PCI_ME_HFS
Definition: me.h:18
#define MEI_ME_CB_RW
Definition: me.h:210
#define PCI_ME_HER(x)
Definition: me.h:195
#define PCI_ME_EXT_SHA256
Definition: me.h:194
#define MEI_HOST_ADDRESS
Definition: me.h:233
@ ME_ERROR_BIOS_PATH
Definition: me.h:313
@ ME_RECOVERY_BIOS_PATH
Definition: me.h:314
@ ME_DISABLE_BIOS_PATH
Definition: me.h:315
@ ME_FIRMWARE_UPDATE_BIOS_PATH
Definition: me.h:316
@ ME_S3WAKE_BIOS_PATH
Definition: me.h:312
@ ME_NORMAL_BIOS_PATH
Definition: me.h:311
#define PCI_ME_H_GS
Definition: me.h:77
#define MEI_H_CB_WW
Definition: me.h:208
#define PCI_ME_EXT_SHA1
Definition: me.h:193
bool is_mei_base_address_valid(void)
void update_mei_base_address(void)
#define MKHI_FWCAPS_SET_RULE
Definition: me.h:192
#define MKHI_DISABLE_RULE_ID
Definition: me.h:194
#define ME_ENABLE_TIMEOUT
Definition: me.h:202
void pch_enable(struct device *dev)
Definition: pch.c:404
#define PCH_ME_DEV
Definition: pch.h:79
#define NULL
Definition: stddef.h:19
unsigned int uint32_t
Definition: stdint.h:14
uint32_t u32
Definition: stdint.h:51
unsigned long uintptr_t
Definition: stdint.h:21
Definition: device.h:107
unsigned int enabled
Definition: device.h:122
Definition: me.h:204
u32 rule_id
Definition: me.h:205
Definition: me.h:197
u32 extend_reg_valid
Definition: me.h:201
u32 raw
Definition: me.h:142
u32 extend_reg_algorithm
Definition: me.h:198
u32 extend_feature_present
Definition: me.h:200
Definition: me.h:51
u32 raw
Definition: me.h:69
u32 fw_init_complete
Definition: me.h:56
Definition: me.h:213
u32 interrupt_enable
Definition: me.h:214
u32 buffer_read_ptr
Definition: me.h:220
u32 interrupt_status
Definition: me.h:215
u32 buffer_depth
Definition: me.h:222
u32 reset
Definition: me.h:218
u32 interrupt_generate
Definition: me.h:216
u32 ready
Definition: me.h:217
u32 buffer_write_ptr
Definition: me.h:221
Definition: me.h:235
u32 is_complete
Definition: me.h:240
u32 length
Definition: me.h:238
u32 is_response
Definition: me.h:261
u32 group_id
Definition: me.h:259
u32 command
Definition: me.h:260
resource_t base
Definition: resource.h:45
resource_t size
Definition: resource.h:46
void udelay(uint32_t us)
Definition: udelay.c:15
#define count