coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
cse_lite.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <arch/cpu.h>
4 #include <console/console.h>
5 #include <cbfs.h>
6 #include <commonlib/region.h>
7 #include <fmap.h>
8 #include <intelblocks/cse.h>
12 #include <security/vboot/misc.h>
13 #include <soc/intel/common/reset.h>
14 
15 #define BPDT_HEADER_SZ sizeof(struct bpdt_header)
16 #define BPDT_ENTRY_SZ sizeof(struct bpdt_entry)
17 #define SUBPART_HEADER_SZ sizeof(struct subpart_hdr)
18 #define SUBPART_ENTRY_SZ sizeof(struct subpart_entry)
19 #define SUBPART_MANIFEST_HDR_SZ sizeof(struct subpart_entry_manifest_header)
20 
21 /* Converts bp index to boot partition string */
22 #define GET_BP_STR(bp_index) (bp_index ? "RW" : "RO")
23 
24 /* CSE RW boot partition signature */
25 #define CSE_RW_SIGNATURE 0x000055aa
26 
27 /* CSE RW boot partition signature size */
28 #define CSE_RW_SIGN_SIZE sizeof(uint32_t)
29 
30 /*
31  * CSE Firmware supports 3 boot partitions. For CSE Lite SKU, only 2 boot partitions are
32  * used and 3rd boot partition is set to BP_STATUS_PARTITION_NOT_PRESENT.
33  * CSE Lite SKU Image Layout:
34  * ------------- ------------------- ---------------------
35  * |CSE REGION | => | RO | RW | DATA | => | BP1 | BP2 | DATA |
36  * ------------- ------------------- ---------------------
37  */
38 #define CSE_MAX_BOOT_PARTITIONS 3
39 
40 /* CSE Lite SKU's valid bootable partition identifiers */
42  /* RO(BP1) contains recovery/minimal boot firmware */
43  RO = 0,
44 
45  /* RW(BP2) contains fully functional CSE firmware */
46  RW = 1
47 };
48 
49 /*
50  * Boot partition status.
51  * The status is returned in response to MKHI_BUP_COMMON_GET_BOOT_PARTITION_INFO cmd.
52  */
53 enum bp_status {
54  /* This value is returned when a partition has no errors */
56 
57  /*
58  * This value is returned when a partition should be present based on layout, but it is
59  * not valid.
60  */
62 
63  /* This value is returned when a partition is not present per initial image layout */
65 
66  /*
67  * This value is returned when unexpected issues are detected in CSE Data area
68  * and CSE TCB-SVN downgrade scenario.
69  */
71 };
72 
73 /*
74  * Boot Partition Info Flags
75  * The flags are returned in response to MKHI_BUP_COMMON_GET_BOOT_PARTITION_INFO cmd.
76  */
78 
79  /* Redundancy Enabled: It indicates CSE supports RO(BP1) and RW(BP2) regions */
81 
82  /* It indicates RO(BP1) supports Minimal Recovery Mode */
84 
85  /*
86  * Read-only Config Enabled: It indicates HW protection to CSE RO region is enabled.
87  * The option is relevant only if the BP_INFO_MIN_RECOV_MODE_EN flag is enabled.
88  */
90 };
91 
92 /* CSE boot partition entry info */
93 struct cse_bp_entry {
94  /* Boot partition version */
95  struct fw_version fw_ver;
96 
97  /* Boot partition status */
99 
100  /* Starting offset of the partition within CSE region */
102 
103  /* Ending offset of the partition within CSE region */
107 
108 /* CSE boot partition info */
109 struct cse_bp_info {
110  /* Number of boot partitions */
112 
113  /* Current boot partition */
115 
116  /* Next boot partition */
118 
119  /* Boot Partition Info Flags */
121 
122  /* Boot Partition Entry Info */
124 } __packed;
125 
127  struct mkhi_hdr hdr;
128  struct cse_bp_info bp_info;
129 } __packed;
130 
131 static const char * const cse_regions[] = {"RO", "RW"};
132 
134 {
135  struct cse_boot_perf_req {
136  struct mkhi_hdr hdr;
137  uint32_t reserved;
138  } __packed;
139 
140  struct cse_boot_perf_req req = {
141  .hdr.group_id = MKHI_GROUP_ID_BUP_COMMON,
142  .hdr.command = MKHI_BUP_COMMON_GET_BOOT_PERF_DATA,
143  .reserved = 0,
144  };
145 
146  size_t resp_size = sizeof(struct cse_boot_perf_rsp);
147 
148  if (heci_send_receive(&req, sizeof(req), boot_perf_rsp, &resp_size,
149  HECI_MKHI_ADDR)) {
150  printk(BIOS_ERR, "cse_lite: Could not get boot performance data\n");
151  return false;
152  }
153 
154  if (boot_perf_rsp->hdr.result) {
155  printk(BIOS_ERR, "cse_lite: Get boot performance data resp failed: %d\n",
156  boot_perf_rsp->hdr.result);
157  return false;
158  }
159 
160  return true;
161 }
162 
163 
165 {
166  return cse_bp_info->current_bp;
167 }
168 
169 static const struct cse_bp_entry *cse_get_bp_entry(enum boot_partition_id bp,
170  const struct cse_bp_info *cse_bp_info)
171 {
172  return &cse_bp_info->bp_entries[bp];
173 }
174 
176 {
177  const struct cse_bp_entry *cse_bp;
178 
179  printk(BIOS_DEBUG, "cse_lite: Number of partitions = %d\n",
181  printk(BIOS_DEBUG, "cse_lite: Current partition = %s\n",
183  printk(BIOS_DEBUG, "cse_lite: Next partition = %s\n", GET_BP_STR(cse_bp_info->next_bp));
184  printk(BIOS_DEBUG, "cse_lite: Flags = 0x%x\n", cse_bp_info->flags);
185 
186  /* Log version info of RO & RW partitions */
187  cse_bp = cse_get_bp_entry(RO, cse_bp_info);
188  printk(BIOS_DEBUG, "cse_lite: %s version = %d.%d.%d.%d (Status=0x%x, Start=0x%x, End=0x%x)\n",
189  GET_BP_STR(RO), cse_bp->fw_ver.major, cse_bp->fw_ver.minor,
190  cse_bp->fw_ver.hotfix, cse_bp->fw_ver.build,
191  cse_bp->status, cse_bp->start_offset,
192  cse_bp->end_offset);
193 
194  cse_bp = cse_get_bp_entry(RW, cse_bp_info);
195  printk(BIOS_DEBUG, "cse_lite: %s version = %d.%d.%d.%d (Status=0x%x, Start=0x%x, End=0x%x)\n",
196  GET_BP_STR(RW), cse_bp->fw_ver.major, cse_bp->fw_ver.minor,
197  cse_bp->fw_ver.hotfix, cse_bp->fw_ver.build,
198  cse_bp->status, cse_bp->start_offset,
199  cse_bp->end_offset);
200 }
201 
202 /*
203  * Checks prerequisites for MKHI_BUP_COMMON_GET_BOOT_PARTITION_INFO and
204  * MKHI_BUP_COMMON_SET_BOOT_PARTITION_INFO HECI commands.
205  * It allows execution of the Boot Partition commands in below scenarios:
206  * - When CSE boots from RW partition (COM: Normal and CWS: Normal)
207  * - When CSE boots from RO partition (COM: Soft Temp Disable and CWS: Normal)
208  * - After HMRFPO_ENABLE command is issued to CSE (COM: SECOVER_MEI_MSG and CWS: Normal)
209  * The prerequisite check should be handled in cse_get_bp_info() and
210  * cse_set_next_boot_partition() since the CSE's current operation mode is changed between these
211  * cmd handler calls.
212  */
214 {
215  if (cse_is_hfs1_cws_normal()) {
217  return true;
219  return true;
221  return true;
222  }
223  return false;
224 }
225 
226 static bool cse_get_bp_info(struct get_bp_info_rsp *bp_info_rsp)
227 {
228  struct get_bp_info_req {
229  struct mkhi_hdr hdr;
230  uint8_t reserved[4];
231  } __packed;
232 
233  struct get_bp_info_req info_req = {
234  .hdr.group_id = MKHI_GROUP_ID_BUP_COMMON,
236  .reserved = {0},
237  };
238 
240  printk(BIOS_ERR, "cse_lite: CSE does not meet prerequisites\n");
241  return false;
242  }
243 
244  size_t resp_size = sizeof(struct get_bp_info_rsp);
245 
246  if (heci_send_receive(&info_req, sizeof(info_req), bp_info_rsp, &resp_size,
247  HECI_MKHI_ADDR)) {
248  printk(BIOS_ERR, "cse_lite: Could not get partition info\n");
249  return false;
250  }
251 
252  if (bp_info_rsp->hdr.result) {
253  printk(BIOS_ERR, "cse_lite: Get partition info resp failed: %d\n",
254  bp_info_rsp->hdr.result);
255  return false;
256  }
257 
258  cse_print_boot_partition_info(&bp_info_rsp->bp_info);
259 
260  return true;
261 }
262 /*
263  * It sends HECI command to notify CSE about its next boot partition. When coreboot wants
264  * CSE to boot from certain partition (BP1 <RO> or BP2 <RW>), then this command can be used.
265  * The CSE's valid bootable partitions are BP1(RO) and BP2(RW).
266  * This function must be used before EOP.
267  * Returns false on failure and true on success.
268  */
270 {
271  struct set_boot_partition_info_req {
272  struct mkhi_hdr hdr;
273  uint8_t next_bp;
274  uint8_t reserved[3];
275  } __packed;
276 
277  struct set_boot_partition_info_req switch_req = {
278  .hdr.group_id = MKHI_GROUP_ID_BUP_COMMON,
280  .next_bp = bp,
281  .reserved = {0},
282  };
283 
284  if (bp != RO && bp != RW) {
285  printk(BIOS_ERR, "cse_lite: Incorrect partition id(%d) is provided", bp);
286  return false;
287  }
288 
289  printk(BIOS_INFO, "cse_lite: Set Boot Partition Info Command (%s)\n", GET_BP_STR(bp));
290 
292  printk(BIOS_ERR, "cse_lite: CSE does not meet prerequisites\n");
293  return false;
294  }
295 
296  struct mkhi_hdr switch_resp;
297  size_t sw_resp_sz = sizeof(struct mkhi_hdr);
298 
299  if (heci_send_receive(&switch_req, sizeof(switch_req), &switch_resp, &sw_resp_sz,
301  return false;
302 
303  if (switch_resp.result) {
304  printk(BIOS_ERR, "cse_lite: Set Boot Partition Info Response Failed: %d\n",
305  switch_resp.result);
306  return false;
307  }
308 
309  return true;
310 }
311 
313 {
314  struct data_clr_request {
315  struct mkhi_hdr hdr;
316  uint8_t reserved[4];
317  } __packed;
318 
319  struct data_clr_request data_clr_rq = {
320  .hdr.group_id = MKHI_GROUP_ID_BUP_COMMON,
321  .hdr.command = MKHI_BUP_COMMON_DATA_CLEAR,
322  .reserved = {0},
323  };
324 
327  printk(BIOS_ERR, "cse_lite: CSE doesn't meet DATA CLEAR cmd prerequisites\n");
328  return false;
329  }
330 
331  printk(BIOS_DEBUG, "cse_lite: Sending DATA CLEAR HECI command\n");
332 
333  struct mkhi_hdr data_clr_rsp;
334  size_t data_clr_rsp_sz = sizeof(data_clr_rsp);
335 
336  if (heci_send_receive(&data_clr_rq, sizeof(data_clr_rq), &data_clr_rsp,
337  &data_clr_rsp_sz, HECI_MKHI_ADDR)) {
338  return false;
339  }
340 
341  if (data_clr_rsp.result) {
342  printk(BIOS_ERR, "cse_lite: CSE DATA CLEAR command response failed: %d\n",
343  data_clr_rsp.result);
344  return false;
345  }
346 
347  return true;
348 }
349 
351 {
352  /* Default weak implementation, does nothing. */
353 }
354 
355 /* Set the CSE's next boot partition and issues system reset */
357 {
359  return false;
360 
361  /* Allow the board to perform a reset for CSE RO<->RW jump */
362  cse_board_reset();
363 
364  /* If board does not perform the reset, then perform global_reset */
365  do_global_reset();
366 
367  die("cse_lite: Failed to reset the system\n");
368 
369  /* Control never reaches here */
370  return false;
371 }
372 
373 static bool cse_boot_to_rw(const struct cse_bp_info *cse_bp_info)
374 {
376  return true;
377 
379 }
380 
381 /* Check if CSE RW data partition is valid or not */
382 static bool cse_is_rw_dp_valid(const struct cse_bp_info *cse_bp_info)
383 {
384  const struct cse_bp_entry *rw_bp;
385 
386  rw_bp = cse_get_bp_entry(RW, cse_bp_info);
387  return rw_bp->status != BP_STATUS_DATA_FAILURE;
388 }
389 
390 /*
391  * It returns true if RW partition doesn't indicate BP_STATUS_DATA_FAILURE
392  * otherwise false if any operation fails.
393  */
395 {
396  /*
397  * If RW partition status indicates BP_STATUS_DATA_FAILURE,
398  * - Send DATA CLEAR HECI command to CSE
399  * - Send SET BOOT PARTITION INFO(RW) command to set CSE's next partition
400  * - Issue GLOBAL RESET HECI command.
401  */
403  return true;
404 
406  return false;
407 
408  return cse_boot_to_rw(cse_bp_info);
409 }
410 
412  const struct cse_bp_info *bp_info)
413 {
414  const struct cse_bp_entry *cse_bp;
415 
416  cse_bp = cse_get_bp_entry(bp, bp_info);
417  return &cse_bp->fw_ver;
418 }
419 
420 static const struct fw_version *cse_get_rw_version(const struct cse_bp_info *cse_bp_info)
421 {
423 }
424 
426  enum boot_partition_id bp, uint32_t *start_offset, uint32_t *end_offset)
427 {
428  const struct cse_bp_entry *cse_bp;
429 
430  cse_bp = cse_get_bp_entry(bp, cse_bp_info);
431 
432  if (start_offset)
433  *start_offset = cse_bp->start_offset;
434 
435  if (end_offset)
436  *end_offset = cse_bp->end_offset;
437 
438 }
439 
441 {
442  const struct cse_bp_entry *rw_bp;
443 
444  rw_bp = cse_get_bp_entry(RW, cse_bp_info);
445 
446  if (rw_bp->status == BP_STATUS_PARTITION_NOT_PRESENT ||
447  rw_bp->status == BP_STATUS_GENERAL_FAILURE) {
448  printk(BIOS_ERR, "cse_lite: RW BP (status:%u) is not valid\n", rw_bp->status);
449  return false;
450  }
451  return true;
452 }
453 
454 static bool cse_boot_to_ro(const struct cse_bp_info *cse_bp_info)
455 {
457  return true;
458 
460 }
461 
462 static bool cse_get_rw_rdev(struct region_device *rdev)
463 {
464  if (fmap_locate_area_as_rdev_rw(CONFIG_SOC_INTEL_CSE_FMAP_NAME, rdev) < 0) {
465  printk(BIOS_ERR, "cse_lite: Failed to locate %s in FMAP\n",
466  CONFIG_SOC_INTEL_CSE_FMAP_NAME);
467  return false;
468  }
469 
470  return true;
471 }
472 
473 static bool cse_is_rw_bp_sign_valid(const struct region_device *target_rdev)
474 {
475  uint32_t cse_bp_sign;
476 
477  if (rdev_readat(target_rdev, &cse_bp_sign, 0, CSE_RW_SIGN_SIZE) != CSE_RW_SIGN_SIZE) {
478  printk(BIOS_ERR, "cse_lite: Failed to read RW boot partition signature\n");
479  return false;
480  }
481 
482  return cse_bp_sign == CSE_RW_SIGNATURE;
483 }
484 
485 static bool cse_get_target_rdev(const struct cse_bp_info *cse_bp_info,
486  struct region_device *target_rdev)
487 {
488  struct region_device cse_region_rdev;
489  size_t size;
490  uint32_t start_offset;
491  uint32_t end_offset;
492 
493  if (!cse_get_rw_rdev(&cse_region_rdev))
494  return false;
495 
496  cse_get_bp_entry_range(cse_bp_info, RW, &start_offset, &end_offset);
497  size = end_offset + 1 - start_offset;
498 
499  if (rdev_chain(target_rdev, &cse_region_rdev, start_offset, size))
500  return false;
501 
502  printk(BIOS_DEBUG, "cse_lite: CSE RW partition: offset = 0x%x, size = 0x%x\n",
503  (uint32_t)start_offset, (uint32_t) size);
504 
505  return true;
506 }
507 
508 static const char *cse_get_source_rdev_fmap(void)
509 {
510  struct vb2_context *ctx = vboot_get_context();
511  if (ctx == NULL)
512  return NULL;
513 
514  if (vboot_is_firmware_slot_a(ctx))
515  return CONFIG_SOC_INTEL_CSE_RW_A_FMAP_NAME;
516 
517  return CONFIG_SOC_INTEL_CSE_RW_B_FMAP_NAME;
518 }
519 
520 /*
521  * Compare versions of CSE CBFS sub-component and CSE sub-component partition
522  * In case of CSE component comparison:
523  * If ver_cmp_status = 0, no update is required
524  * If ver_cmp_status < 0, coreboot downgrades CSE RW region
525  * If ver_cmp_status > 0, coreboot upgrades CSE RW region
526  */
527 static int cse_compare_sub_part_version(const struct fw_version *a, const struct fw_version *b)
528 {
529  if (a->major != b->major)
530  return a->major - b->major;
531  else if (a->minor != b->minor)
532  return a->minor - b->minor;
533  else if (a->hotfix != b->hotfix)
534  return a->hotfix - b->hotfix;
535  else
536  return a->build - b->build;
537 }
538 
539 /* The function calculates SHA-256 of CSE RW blob and compares it with the provided SHA value */
540 static bool cse_verify_cbfs_rw_sha256(const uint8_t *expected_rw_blob_sha,
541  const void *rw_blob, const size_t rw_blob_sz)
542 
543 {
544  uint8_t rw_comp_sha[VB2_SHA256_DIGEST_SIZE];
545 
546  if (vb2_digest_buffer(rw_blob, rw_blob_sz, VB2_HASH_SHA256, rw_comp_sha,
547  VB2_SHA256_DIGEST_SIZE)) {
548  printk(BIOS_ERR, "cse_lite: CSE CBFS RW's SHA-256 calculation has failed\n");
549  return false;
550  }
551 
552  if (memcmp(expected_rw_blob_sha, rw_comp_sha, VB2_SHA256_DIGEST_SIZE)) {
553  printk(BIOS_ERR, "cse_lite: Computed CBFS RW's SHA-256 does not match with"
554  "the provided SHA in the metadata\n");
555  return false;
556  }
557  printk(BIOS_SPEW, "cse_lite: Computed SHA of CSE CBFS RW Image matches the"
558  " provided hash in the metadata\n");
559  return true;
560 }
561 
562 static bool cse_erase_rw_region(const struct region_device *target_rdev)
563 {
564  if (rdev_eraseat(target_rdev, 0, region_device_sz(target_rdev)) < 0) {
565  printk(BIOS_ERR, "cse_lite: CSE RW partition could not be erased\n");
566  return false;
567  }
568  return true;
569 }
570 
571 static bool cse_copy_rw(const struct region_device *target_rdev, const void *buf,
572  size_t offset, size_t size)
573 {
574  if (rdev_writeat(target_rdev, buf, offset, size) < 0) {
575  printk(BIOS_ERR, "cse_lite: Failed to update CSE firmware\n");
576  return false;
577  }
578 
579  return true;
580 }
581 
588 };
589 
590 static bool read_ver_field(const char *start, char **curr, size_t size, uint16_t *ver_field)
591 {
592  if ((*curr - start) >= size) {
593  printk(BIOS_ERR, "cse_lite: Version string read overflow!\n");
594  return false;
595  }
596 
597  *ver_field = skip_atoi(curr);
598  (*curr)++;
599  return true;
600 }
601 
603  struct region_device *target_rdev)
604 {
605  int ret;
606  struct fw_version cbfs_rw_version;
607  char *version_str, *ptr;
608  size_t size;
609 
610  if (!cse_is_rw_bp_sign_valid(target_rdev))
611  return CSE_UPDATE_CORRUPTED;
612 
613  ptr = version_str = cbfs_map(CONFIG_SOC_INTEL_CSE_RW_VERSION_CBFS_NAME, &size);
614  if (!version_str) {
615  printk(BIOS_ERR, "cse_lite: Failed to get %s\n",
616  CONFIG_SOC_INTEL_CSE_RW_VERSION_CBFS_NAME);
618  }
619 
620  if (!read_ver_field(version_str, &ptr, size, &cbfs_rw_version.major) ||
621  !read_ver_field(version_str, &ptr, size, &cbfs_rw_version.minor) ||
622  !read_ver_field(version_str, &ptr, size, &cbfs_rw_version.hotfix) ||
623  !read_ver_field(version_str, &ptr, size, &cbfs_rw_version.build)) {
624  cbfs_unmap(version_str);
626  }
627 
628  printk(BIOS_DEBUG, "cse_lite: CSE CBFS RW version : %d.%d.%d.%d\n",
629  cbfs_rw_version.major,
630  cbfs_rw_version.minor,
631  cbfs_rw_version.hotfix,
632  cbfs_rw_version.build);
633 
634  cbfs_unmap(version_str);
635 
637  if (ret == 0)
639  else if (ret < 0)
640  return CSE_UPDATE_DOWNGRADE;
641  else
642  return CSE_UPDATE_UPGRADE;
643 }
644 
645 static bool cse_write_rw_region(const struct region_device *target_rdev,
646  const void *cse_cbfs_rw, const size_t cse_cbfs_rw_sz)
647 {
648  /* Points to CSE CBFS RW image after boot partition signature */
649  uint8_t *cse_cbfs_rw_wo_sign = (uint8_t *)cse_cbfs_rw + CSE_RW_SIGN_SIZE;
650 
651  /* Size of CSE CBFS RW image without boot partition signature */
652  uint32_t cse_cbfs_rw_wo_sign_sz = cse_cbfs_rw_sz - CSE_RW_SIGN_SIZE;
653 
654  /* Update except CSE RW signature */
655  if (!cse_copy_rw(target_rdev, cse_cbfs_rw_wo_sign, CSE_RW_SIGN_SIZE,
656  cse_cbfs_rw_wo_sign_sz))
657  return false;
658 
659  /* Update CSE RW signature to indicate update is complete */
660  if (!cse_copy_rw(target_rdev, (void *)cse_cbfs_rw, 0, CSE_RW_SIGN_SIZE))
661  return false;
662 
663  printk(BIOS_INFO, "cse_lite: CSE RW Update Successful\n");
664  return true;
665 }
666 
667 static bool is_cse_fw_update_enabled(void)
668 {
669  if (!CONFIG(SOC_INTEL_CSE_RW_UPDATE))
670  return false;
671 
672  if (CONFIG(SOC_INTEL_COMMON_BASECODE_DEBUG_FEATURE))
674 
675  return true;
676 }
677 
678 static enum csme_failure_reason cse_update_rw(const struct cse_bp_info *cse_bp_info,
679  const void *cse_cbfs_rw, const size_t cse_blob_sz,
680  struct region_device *target_rdev)
681 {
682  if (region_device_sz(target_rdev) < cse_blob_sz) {
683  printk(BIOS_ERR, "RW update does not fit. CSE RW flash region size: %zx,"
684  "Update blob size:%zx\n", region_device_sz(target_rdev), cse_blob_sz);
686  }
687 
688  if (!cse_erase_rw_region(target_rdev))
690 
691  if (!cse_write_rw_region(target_rdev, cse_cbfs_rw, cse_blob_sz))
693 
694  return CSE_NO_ERROR;
695 }
696 
698  enum cse_update_status status)
699 {
700  /*
701  * To set CSE's operation mode to HMRFPO mode:
702  * 1. Ensure CSE to boot from RO(BP1)
703  * 2. Send HMRFPO_ENABLE command to CSE
704  */
706  return false;
707 
708  if ((status == CSE_UPDATE_DOWNGRADE) || (status == CSE_UPDATE_CORRUPTED)) {
710  printk(BIOS_ERR, "cse_lite: CSE data clear failed!\n");
711  return false;
712  }
713  }
714 
715  return cse_hmrfpo_enable();
716 }
717 
719  enum cse_update_status status,
720  struct region_device *target_rdev)
721 {
722  enum csme_failure_reason rv;
723  uint8_t *cbfs_rw_hash;
724  size_t size;
725 
726  const char *area_name = cse_get_source_rdev_fmap();
727  if (!area_name)
729 
730  void *cse_cbfs_rw = cbfs_unverified_area_map(area_name,
731  CONFIG_SOC_INTEL_CSE_RW_CBFS_NAME, &size);
732  if (!cse_cbfs_rw) {
733  printk(BIOS_ERR, "cse_lite: CSE CBFS RW blob could not be mapped\n");
735  }
736 
737  cbfs_rw_hash = cbfs_map(CONFIG_SOC_INTEL_CSE_RW_HASH_CBFS_NAME, NULL);
738  if (!cbfs_rw_hash) {
739  printk(BIOS_ERR, "cse_lite: Failed to get %s\n",
740  CONFIG_SOC_INTEL_CSE_RW_HASH_CBFS_NAME);
742  goto error_exit;
743  }
744 
745  if (!cse_verify_cbfs_rw_sha256(cbfs_rw_hash, cse_cbfs_rw, size)) {
747  goto error_exit;
748  }
749 
750  if (!cse_prep_for_rw_update(cse_bp_info, status)) {
752  goto error_exit;
753  }
754 
755  rv = cse_update_rw(cse_bp_info, cse_cbfs_rw, size, target_rdev);
756 
757 error_exit:
758  cbfs_unmap(cbfs_rw_hash);
759  cbfs_unmap(cse_cbfs_rw);
760  return rv;
761 }
762 
764 {
765  struct region_device target_rdev;
766  enum cse_update_status status;
767 
768  if (!cse_get_target_rdev(cse_bp_info, &target_rdev)) {
769  printk(BIOS_ERR, "cse_lite: Failed to get CSE RW Partition\n");
771  }
772 
773  status = cse_check_update_status(cse_bp_info, &target_rdev);
774  if (status == CSE_UPDATE_NOT_REQUIRED)
775  return CSE_NO_ERROR;
776  if (status == CSE_UPDATE_METADATA_ERROR)
778 
779  printk(BIOS_DEBUG, "cse_lite: CSE RW update is initiated\n");
780  return cse_trigger_fw_update(cse_bp_info, status, &target_rdev);
781 }
782 
783 static const char *cse_sub_part_str(enum bpdt_entry_type type)
784 {
785  switch (type) {
786  case IOM_FW:
787  return "IOM";
788  case NPHY_FW:
789  return "NPHY";
790  default:
791  return "Unknown";
792  }
793 }
794 
796  size_t bp, struct region_device *cse_rdev)
797 {
798  struct region_device cse_region_rdev;
799  uint32_t size;
800  uint32_t start_offset;
801  uint32_t end_offset;
802 
803  if (!cse_get_rw_rdev(&cse_region_rdev))
804  return false;
805 
806  if (!strcmp(cse_regions[bp], "RO"))
807  cse_get_bp_entry_range(cse_bp_info, RO, &start_offset, &end_offset);
808  else
809  cse_get_bp_entry_range(cse_bp_info, RW, &start_offset, &end_offset);
810 
811  size = end_offset + 1 - start_offset;
812 
813  if (rdev_chain(cse_rdev, &cse_region_rdev, start_offset, size))
814  return false;
815 
816  printk(BIOS_DEBUG, "cse_lite: CSE %s partition: offset = 0x%x, size = 0x%x\n",
817  cse_regions[bp], start_offset, size);
818  return true;
819 }
820 
822  struct region_device *target_rdev, size_t bp, enum bpdt_entry_type type)
823 {
824  struct bpdt_header bpdt_hdr;
825  struct region_device cse_rdev;
826  struct bpdt_entry bpdt_entries[MAX_SUBPARTS];
827  uint8_t i;
828 
829  if (!cse_locate_area_as_rdev_rw(cse_bp_info, bp, &cse_rdev)) {
830  printk(BIOS_ERR, "cse_lite: Failed to locate %s in the CSE Region\n",
831  cse_regions[bp]);
832  return false;
833  }
834 
835  if ((rdev_readat(&cse_rdev, &bpdt_hdr, 0, BPDT_HEADER_SZ)) != BPDT_HEADER_SZ) {
836  printk(BIOS_ERR, "cse_lite: Failed to read BPDT header from CSE region\n");
837  return false;
838  }
839 
840  if ((rdev_readat(&cse_rdev, bpdt_entries, BPDT_HEADER_SZ,
841  (bpdt_hdr.descriptor_count * BPDT_ENTRY_SZ))) !=
842  (bpdt_hdr.descriptor_count * BPDT_ENTRY_SZ)) {
843  printk(BIOS_ERR, "cse_lite: Failed to read BPDT entries from CSE region\n");
844  return false;
845  }
846 
847  /* walk through BPDT entries to identify sub-partition's payload offset and size */
848  for (i = 0; i < bpdt_hdr.descriptor_count; i++) {
849  if (bpdt_entries[i].type == type) {
850  printk(BIOS_INFO, "cse_lite: Sub-partition %s- offset = 0x%x,"
851  "size = 0x%x\n", cse_sub_part_str(type), bpdt_entries[i].offset,
852  bpdt_entries[i].size);
853 
854  if (rdev_chain(target_rdev, &cse_rdev, bpdt_entries[i].offset,
855  bpdt_entries[i].size))
856  return false;
857  else
858  return true;
859  }
860  }
861 
862  printk(BIOS_ERR, "cse_lite: Sub-partition %s is not found\n", cse_sub_part_str(type));
863  return false;
864 }
865 
867  const struct region_device *rdev,
868  struct fw_version *fw_ver)
869 {
871  struct subpart_entry_manifest_header man_hdr;
872 
874  != SUBPART_ENTRY_SZ) {
875  printk(BIOS_ERR, "cse_lite: Failed to read %s sub partition entry\n",
877  return false;
878  }
879 
882  printk(BIOS_ERR, "cse_lite: Failed to read %s Sub part entry #0 manifest\n",
884  return false;
885  }
886 
887  fw_ver->major = man_hdr.binary_version.major;
888  fw_ver->minor = man_hdr.binary_version.minor;
889  fw_ver->hotfix = man_hdr.binary_version.hotfix;
890  fw_ver->build = man_hdr.binary_version.build;
891 
892  return true;
893 }
894 
895 static void cse_sub_part_get_source_fw_version(void *subpart_cbfs_rw, struct fw_version *fw_ver)
896 {
897  uint8_t *ptr = (uint8_t *)subpart_cbfs_rw;
899  struct subpart_entry_manifest_header *man_hdr;
900 
901  subpart_entry = (struct subpart_entry *) (ptr + SUBPART_HEADER_SZ);
902  man_hdr = (struct subpart_entry_manifest_header *) (ptr + subpart_entry->offset_bytes);
903 
904  fw_ver->major = man_hdr->binary_version.major;
905  fw_ver->minor = man_hdr->binary_version.minor;
906  fw_ver->hotfix = man_hdr->binary_version.hotfix;
907  fw_ver->build = man_hdr->binary_version.build;
908 }
909 
911 {
912  /*
913  * To set CSE's operation mode to HMRFPO mode:
914  * 1. Ensure CSE to boot from RO(BP1)
915  * 2. Send HMRFPO_ENABLE command to CSE
916  */
918  return false;
919 
920  return cse_hmrfpo_enable();
921 }
922 
924  const void *subpart_cbfs_rw, const size_t blob_sz,
925  struct region_device *target_rdev)
926 {
927  if (region_device_sz(target_rdev) < blob_sz) {
928  printk(BIOS_ERR, "cse_lite: %s Target sub-partition size: %zx, "
929  "smaller than blob size:%zx, abort update\n",
930  cse_sub_part_str(type), region_device_sz(target_rdev), blob_sz);
932  }
933 
934  /* Erase CSE Lite sub-partition */
935  if (!cse_erase_rw_region(target_rdev))
937 
938  /* Update CSE Lite sub-partition */
939  if (!cse_copy_rw(target_rdev, (void *)subpart_cbfs_rw, 0, blob_sz))
941 
942  printk(BIOS_INFO, "cse_lite: CSE %s %s Update successful\n", GET_BP_STR(bp),
944 
946 }
947 
949 {
950  switch (rv) {
953  return rv;
954  default:
956  }
957  /* Control never reaches here */
958  return rv;
959 }
960 
962  const struct cse_bp_info *cse_bp_info, const char *name)
963 {
964  struct region_device target_rdev;
965  struct fw_version target_fw_ver, source_fw_ver;
966  enum csme_failure_reason rv;
967  size_t size;
968 
969  void *subpart_cbfs_rw = cbfs_map(name, &size);
970  if (!subpart_cbfs_rw) {
971  printk(BIOS_ERR, "cse_lite: Not able to map %s CBFS file\n",
974  }
975 
976  cse_sub_part_get_source_fw_version(subpart_cbfs_rw, &source_fw_ver);
977  printk(BIOS_INFO, "cse_lite: CBFS %s FW Version: %x.%x.%x.%x\n", cse_sub_part_str(type),
978  source_fw_ver.major, source_fw_ver.minor, source_fw_ver.hotfix,
979  source_fw_ver.build);
980 
981  /* Trigger sub-partition update in CSE RO and CSE RW */
982  for (size_t bp = 0; bp < ARRAY_SIZE(cse_regions); bp++) {
983  if (!cse_sub_part_get_target_rdev(cse_bp_info, &target_rdev, bp, type)) {
985  goto error_exit;
986  }
987 
988  if (!cse_get_sub_part_fw_version(type, &target_rdev, &target_fw_ver)) {
990  goto error_exit;
991  }
992 
993  printk(BIOS_INFO, "cse_lite: %s %s FW Version: %x.%x.%x.%x\n", cse_regions[bp],
994  cse_sub_part_str(type), target_fw_ver.major,
995  target_fw_ver.minor, target_fw_ver.hotfix, target_fw_ver.build);
996 
997  if (!cse_compare_sub_part_version(&target_fw_ver, &source_fw_ver)) {
998  printk(BIOS_INFO, "cse_lite: %s %s update is not required\n",
1001  continue;
1002  }
1003 
1004  printk(BIOS_INFO, "CSE %s %s Update initiated\n", GET_BP_STR(bp),
1006 
1009  goto error_exit;
1010  }
1011 
1012  rv = cse_sub_part_trigger_update(type, bp, subpart_cbfs_rw,
1013  size, &target_rdev);
1014 
1016  goto error_exit;
1017  }
1018 error_exit:
1019  cbfs_unmap(subpart_cbfs_rw);
1020  return rv;
1021 }
1022 
1024 {
1025  if (skip_cse_sub_part_update()) {
1026  printk(BIOS_INFO, "CSE Sub-partition update not required\n");
1028  }
1029 
1030  int rv;
1032  CONFIG_SOC_INTEL_CSE_IOM_CBFS_NAME);
1033 
1035 
1037  CONFIG_SOC_INTEL_CSE_NPHY_CBFS_NAME);
1038 
1040 }
1041 
1042 void cse_fw_sync(void)
1043 {
1044  static struct get_bp_info_rsp cse_bp_info;
1045 
1046  /*
1047  * If system is in recovery mode, skip CSE Lite update if CSE sub-partition update
1048  * is not enabled and continue to update CSE sub-partitions.
1049  */
1050  if (vboot_recovery_mode_enabled() && !CONFIG(SOC_INTEL_CSE_SUB_PART_UPDATE)) {
1051  printk(BIOS_DEBUG, "cse_lite: Skip switching to RW in the recovery path\n");
1052  return;
1053  }
1054 
1055  /* If CSE SKU type is not Lite, skip enabling CSE Lite SKU */
1056  if (!cse_is_hfs3_fw_sku_lite()) {
1057  printk(BIOS_ERR, "cse_lite: Not a CSE Lite SKU\n");
1058  return;
1059  }
1060 
1061  if (!cse_get_bp_info(&cse_bp_info)) {
1062  printk(BIOS_ERR, "cse_lite: Failed to get CSE boot partition info\n");
1063 
1064  /* If system is in recovery mode, don't trigger recovery again */
1065  if (!vboot_recovery_mode_enabled()) {
1067  } else {
1068  printk(BIOS_ERR, "cse_lite: System is already in Recovery Mode, "
1069  "so no action\n");
1070  return;
1071  }
1072  }
1073 
1074  /*
1075  * If system is in recovery mode, CSE Lite update has to be skipped but CSE
1076  * sub-partitions like NPHY and IOM have to to be updated. If CSE sub-parition update
1077  * fails during recovery, just continue to boot.
1078  */
1079  if (CONFIG(SOC_INTEL_CSE_SUB_PART_UPDATE) && vboot_recovery_mode_enabled()) {
1080  if (cse_sub_part_fw_update(&cse_bp_info.bp_info) ==
1082  cse_board_reset();
1083  do_global_reset();
1084  die("ERROR: GLOBAL RESET Failed to reset the system\n");
1085  }
1086 
1087  return;
1088  }
1089 
1090  if (!cse_fix_data_failure_err(&cse_bp_info.bp_info))
1092 
1093  /*
1094  * cse firmware update is skipped if SOC_INTEL_CSE_RW_UPDATE is not defined and
1095  * runtime debug control flag is not enabled. The driver triggers recovery if CSE CBFS
1096  * RW metadata or CSE CBFS RW blob is not available.
1097  */
1098  if (is_cse_fw_update_enabled()) {
1099  uint8_t rv;
1100  rv = cse_fw_update(&cse_bp_info.bp_info);
1101  if (rv)
1103  }
1104 
1105  if (CONFIG(SOC_INTEL_CSE_SUB_PART_UPDATE))
1107 
1108  if (!cse_is_rw_bp_status_valid(&cse_bp_info.bp_info))
1110 
1111  if (!cse_boot_to_rw(&cse_bp_info.bp_info)) {
1112  printk(BIOS_ERR, "cse_lite: Failed to switch to RW\n");
1114  }
1115 }
const char * name
Definition: mmu.c:92
#define ARRAY_SIZE(a)
Definition: helpers.h:12
void cbfs_unmap(void *mapping)
Definition: cbfs.c:86
static void * cbfs_map(const char *name, size_t *size_out)
Definition: cbfs.h:246
static void * cbfs_unverified_area_map(const char *area, const char *name, size_t *size_out)
Definition: cbfs.h:266
bool cse_is_hfs1_com_soft_temp_disable(void)
Definition: cse.c:260
bool cse_is_hfs1_cws_normal(void)
Definition: cse.c:241
bool cse_is_hfs1_com_normal(void)
Definition: cse.c:250
enum cse_tx_rx_status heci_send_receive(const void *snd_msg, size_t snd_sz, void *rcv_msg, size_t *rcv_sz, uint8_t cse_addr)
Definition: cse.c:574
bool cse_is_hfs1_com_secover_mei_msg(void)
Definition: cse.c:255
bool cse_is_hfs3_fw_sku_lite(void)
Definition: cse.c:281
void cse_trigger_vboot_recovery(enum csme_failure_reason reason)
Definition: cse.c:918
int cse_hmrfpo_enable(void)
Definition: cse.c:748
#define printk(level,...)
Definition: stdlib.h:16
void __noreturn die(const char *fmt,...)
Definition: die.c:17
#define MKHI_BUP_COMMON_GET_BOOT_PERF_DATA
Definition: cse.h:45
csme_failure_reason
Definition: cse.h:146
@ CSE_COMMUNICATION_ERROR
Definition: cse.h:166
@ CSE_LITE_SKU_SUB_PART_LAYOUT_MISMATCH_ERROR
Definition: cse.h:199
@ CSE_LITE_SKU_SUB_PART_BLOB_ACCESS_ERR
Definition: cse.h:193
@ CSE_NO_ERROR
Definition: cse.h:148
@ CSE_LITE_SKU_RW_ACCESS_ERROR
Definition: cse.h:157
@ CSE_LITE_SKU_LAYOUT_MISMATCH_ERROR
Definition: cse.h:181
@ CSE_LITE_SKU_SUB_PART_UPDATE_NOT_REQ
Definition: cse.h:196
@ CSE_LITE_SKU_FW_UPDATE_ERROR
Definition: cse.h:163
@ CSE_LITE_SKU_SUB_PART_ACCESS_ERR
Definition: cse.h:190
@ CSE_LITE_SKU_RW_SWITCH_ERROR
Definition: cse.h:160
@ CSE_LITE_SKU_RW_JUMP_ERROR
Definition: cse.h:154
@ CSE_LITE_SKU_RW_BLOB_SHA256_MISMATCH
Definition: cse.h:175
@ CSE_LITE_SKU_PART_UPDATE_SUCCESS
Definition: cse.h:202
@ CSE_LITE_SKU_RW_BLOB_NOT_FOUND
Definition: cse.h:172
@ CSE_LITE_SKU_DATA_WIPE_ERROR
Definition: cse.h:169
@ CSE_LITE_SKU_RW_METADATA_NOT_FOUND
Definition: cse.h:178
@ CSE_LITE_SKU_SUB_PART_UPDATE_FAIL
Definition: cse.h:187
#define MKHI_BUP_COMMON_GET_BOOT_PARTITION_INFO
Definition: cse.h:40
#define MKHI_BUP_COMMON_SET_BOOT_PARTITION_INFO
Definition: cse.h:41
#define HECI_MKHI_ADDR
Definition: cse.h:414
#define MKHI_GROUP_ID_BUP_COMMON
Definition: cse.h:13
#define MKHI_BUP_COMMON_DATA_CLEAR
Definition: cse.h:42
bpdt_entry_type
Definition: cse_layout.h:6
@ NPHY_FW
Definition: cse_layout.h:28
@ IOM_FW
Definition: cse_layout.h:27
@ MAX_SUBPARTS
Definition: cse_layout.h:32
static int cse_compare_sub_part_version(const struct fw_version *a, const struct fw_version *b)
Definition: cse_lite.c:527
static const char * cse_sub_part_str(enum bpdt_entry_type type)
Definition: cse_lite.c:783
bp_info_flags
Definition: cse_lite.c:77
@ BP_INFO_REDUNDANCY_EN
Definition: cse_lite.c:80
@ BP_INFO_MIN_RECOV_MODE_EN
Definition: cse_lite.c:83
@ BP_INFO_READ_ONLY_CFG
Definition: cse_lite.c:89
static bool cse_fix_data_failure_err(const struct cse_bp_info *cse_bp_info)
Definition: cse_lite.c:394
#define SUBPART_MANIFEST_HDR_SZ
Definition: cse_lite.c:19
static const char *const cse_regions[]
Definition: cse_lite.c:131
#define CSE_MAX_BOOT_PARTITIONS
Definition: cse_lite.c:38
static bool cse_boot_to_rw(const struct cse_bp_info *cse_bp_info)
Definition: cse_lite.c:373
__weak void cse_board_reset(void)
Definition: cse_lite.c:350
static bool cse_is_rw_dp_valid(const struct cse_bp_info *cse_bp_info)
Definition: cse_lite.c:382
static bool cse_copy_rw(const struct region_device *target_rdev, const void *buf, size_t offset, size_t size)
Definition: cse_lite.c:571
struct cse_bp_entry __packed
void cse_fw_sync(void)
Definition: cse_lite.c:1042
static uint8_t cse_fw_update(const struct cse_bp_info *cse_bp_info)
Definition: cse_lite.c:763
static bool cse_locate_area_as_rdev_rw(const struct cse_bp_info *cse_bp_info, size_t bp, struct region_device *cse_rdev)
Definition: cse_lite.c:795
static enum csme_failure_reason cse_trigger_fw_update(const struct cse_bp_info *cse_bp_info, enum cse_update_status status, struct region_device *target_rdev)
Definition: cse_lite.c:718
static const char * cse_get_source_rdev_fmap(void)
Definition: cse_lite.c:508
#define CSE_RW_SIGNATURE
Definition: cse_lite.c:25
static bool cse_get_bp_info(struct get_bp_info_rsp *bp_info_rsp)
Definition: cse_lite.c:226
static bool cse_set_and_boot_from_next_bp(enum boot_partition_id bp)
Definition: cse_lite.c:356
static bool is_cse_fw_update_enabled(void)
Definition: cse_lite.c:667
static uint8_t cse_sub_part_trigger_update(enum bpdt_entry_type type, uint8_t bp, const void *subpart_cbfs_rw, const size_t blob_sz, struct region_device *target_rdev)
Definition: cse_lite.c:923
static const struct fw_version * cse_get_rw_version(const struct cse_bp_info *cse_bp_info)
Definition: cse_lite.c:420
bp_status
Definition: cse_lite.c:53
@ BP_STATUS_GENERAL_FAILURE
Definition: cse_lite.c:61
@ BP_STATUS_SUCCESS
Definition: cse_lite.c:55
@ BP_STATUS_PARTITION_NOT_PRESENT
Definition: cse_lite.c:64
@ BP_STATUS_DATA_FAILURE
Definition: cse_lite.c:70
static enum csme_failure_reason cse_sub_part_fw_component_update(enum bpdt_entry_type type, const struct cse_bp_info *cse_bp_info, const char *name)
Definition: cse_lite.c:961
static bool cse_is_rw_bp_sign_valid(const struct region_device *target_rdev)
Definition: cse_lite.c:473
static void cse_sub_part_get_source_fw_version(void *subpart_cbfs_rw, struct fw_version *fw_ver)
Definition: cse_lite.c:895
static bool cse_erase_rw_region(const struct region_device *target_rdev)
Definition: cse_lite.c:562
static bool cse_boot_to_ro(const struct cse_bp_info *cse_bp_info)
Definition: cse_lite.c:454
static const struct fw_version * cse_get_bp_entry_version(enum boot_partition_id bp, const struct cse_bp_info *bp_info)
Definition: cse_lite.c:411
static uint8_t cse_sub_part_fw_update(const struct cse_bp_info *cse_bp_info)
Definition: cse_lite.c:1023
static bool cse_verify_cbfs_rw_sha256(const uint8_t *expected_rw_blob_sha, const void *rw_blob, const size_t rw_blob_sz)
Definition: cse_lite.c:540
static bool cse_is_rw_bp_status_valid(const struct cse_bp_info *cse_bp_info)
Definition: cse_lite.c:440
boot_partition_id
Definition: cse_lite.c:41
@ RO
Definition: cse_lite.c:43
@ RW
Definition: cse_lite.c:46
bool cse_get_boot_performance_data(struct cse_boot_perf_rsp *boot_perf_rsp)
Definition: cse_lite.c:133
static bool cse_sub_part_get_target_rdev(const struct cse_bp_info *cse_bp_info, struct region_device *target_rdev, size_t bp, enum bpdt_entry_type type)
Definition: cse_lite.c:821
#define SUBPART_HEADER_SZ
Definition: cse_lite.c:17
static uint8_t cse_get_current_bp(const struct cse_bp_info *cse_bp_info)
Definition: cse_lite.c:164
#define BPDT_ENTRY_SZ
Definition: cse_lite.c:16
#define CSE_RW_SIGN_SIZE
Definition: cse_lite.c:28
static enum cse_update_status cse_check_update_status(const struct cse_bp_info *cse_bp_info, struct region_device *target_rdev)
Definition: cse_lite.c:602
static bool cse_is_bp_cmd_info_possible(void)
Definition: cse_lite.c:213
static bool cse_set_next_boot_partition(enum boot_partition_id bp)
Definition: cse_lite.c:269
static bool cse_prep_for_rw_update(const struct cse_bp_info *cse_bp_info, enum cse_update_status status)
Definition: cse_lite.c:697
static bool cse_get_target_rdev(const struct cse_bp_info *cse_bp_info, struct region_device *target_rdev)
Definition: cse_lite.c:485
static bool cse_get_rw_rdev(struct region_device *rdev)
Definition: cse_lite.c:462
static enum csme_failure_reason cse_update_rw(const struct cse_bp_info *cse_bp_info, const void *cse_cbfs_rw, const size_t cse_blob_sz, struct region_device *target_rdev)
Definition: cse_lite.c:678
#define GET_BP_STR(bp_index)
Definition: cse_lite.c:22
static void cse_print_boot_partition_info(const struct cse_bp_info *cse_bp_info)
Definition: cse_lite.c:175
static bool cse_prep_for_component_update(const struct cse_bp_info *cse_bp_info)
Definition: cse_lite.c:910
#define SUBPART_ENTRY_SZ
Definition: cse_lite.c:18
cse_update_status
Definition: cse_lite.c:582
@ CSE_UPDATE_NOT_REQUIRED
Definition: cse_lite.c:583
@ CSE_UPDATE_UPGRADE
Definition: cse_lite.c:584
@ CSE_UPDATE_CORRUPTED
Definition: cse_lite.c:586
@ CSE_UPDATE_METADATA_ERROR
Definition: cse_lite.c:587
@ CSE_UPDATE_DOWNGRADE
Definition: cse_lite.c:585
static void cse_get_bp_entry_range(const struct cse_bp_info *cse_bp_info, enum boot_partition_id bp, uint32_t *start_offset, uint32_t *end_offset)
Definition: cse_lite.c:425
static bool cse_data_clear_request(const struct cse_bp_info *cse_bp_info)
Definition: cse_lite.c:312
static bool read_ver_field(const char *start, char **curr, size_t size, uint16_t *ver_field)
Definition: cse_lite.c:590
static uint8_t handle_cse_sub_part_fw_update_rv(uint8_t rv)
Definition: cse_lite.c:948
static bool cse_get_sub_part_fw_version(enum bpdt_entry_type type, const struct region_device *rdev, struct fw_version *fw_ver)
Definition: cse_lite.c:866
static bool cse_write_rw_region(const struct region_device *target_rdev, const void *cse_cbfs_rw, const size_t cse_cbfs_rw_sz)
Definition: cse_lite.c:645
static const struct cse_bp_entry * cse_get_bp_entry(enum boot_partition_id bp, const struct cse_bp_info *cse_bp_info)
Definition: cse_lite.c:169
#define BPDT_HEADER_SZ
Definition: cse_lite.c:15
bool is_debug_cse_fw_update_disable(void)
Definition: debug_feature.c:22
@ CONFIG
Definition: dsi_common.h:201
static struct region_device rdev
Definition: flashconsole.c:14
static size_t offset
Definition: flashconsole.c:16
int fmap_locate_area_as_rdev_rw(const char *name, struct region_device *area)
Definition: fmap.c:154
static uint8_t fw_ver
Definition: fw_cfg.c:21
unsigned int type
Definition: edid.c:57
#define BIOS_INFO
BIOS_INFO - Expected events.
Definition: loglevel.h:113
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#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
static uint8_t * buf
Definition: uart.c:7
static int vboot_is_firmware_slot_a(struct vb2_context *ctx)
Definition: misc.h:18
ssize_t rdev_eraseat(const struct region_device *rd, size_t offset, size_t size)
Definition: region.c:114
static size_t region_device_sz(const struct region_device *rdev)
Definition: region.h:132
ssize_t rdev_writeat(const struct region_device *rd, const void *b, size_t offset, size_t size)
Definition: region.c:94
int rdev_chain(struct region_device *child, const struct region_device *parent, size_t offset, size_t size)
Definition: region.c:136
ssize_t rdev_readat(const struct region_device *rd, void *b, size_t offset, size_t size)
Definition: region.c:77
const struct smm_save_state_ops *legacy_ops __weak
Definition: save_state.c:8
int vboot_recovery_mode_enabled(void)
Definition: bootmode.c:21
struct vb2_context * vboot_get_context(void)
Definition: common.c:28
void do_global_reset(void)
Definition: reset.c:8
bool skip_cse_sub_part_update(void)
Definition: romstage.c:29
#define NULL
Definition: stddef.h:19
unsigned short uint16_t
Definition: stdint.h:11
unsigned int uint32_t
Definition: stdint.h:14
unsigned char uint8_t
Definition: stdint.h:8
int strcmp(const char *s1, const char *s2)
Definition: string.c:103
unsigned int skip_atoi(char **s)
Definition: string.c:126
int memcmp(const void *s1, const void *s2, size_t n)
Definition: memcmp.c:3
Definition: cse_layout.h:73
uint32_t size
Definition: cse_layout.h:76
uint16_t descriptor_count
Definition: cse_layout.h:37
struct mkhi_hdr hdr
Definition: cse.h:317
Definition: cse_lite.c:93
uint8_t reserved[12]
Definition: cse_lite.c:105
struct fw_version fw_ver
Definition: cse_lite.c:95
uint32_t end_offset
Definition: cse_lite.c:104
uint32_t start_offset
Definition: cse_lite.c:101
uint32_t status
Definition: cse_lite.c:98
uint8_t total_number_of_bp
Definition: cse_lite.c:111
uint8_t next_bp
Definition: cse_lite.c:117
struct cse_bp_entry bp_entries[CSE_MAX_BOOT_PARTITIONS]
Definition: cse_lite.c:123
uint8_t current_bp
Definition: cse_lite.c:114
uint8_t flags
Definition: cse_lite.c:120
Definition: cse.h:89
uint16_t major
Definition: cse.h:90
uint16_t build
Definition: cse.h:93
uint16_t minor
Definition: cse.h:91
uint16_t hotfix
Definition: cse.h:92
struct cse_bp_info bp_info
Definition: cse_lite.c:128
struct mkhi_hdr hdr
Definition: cse_lite.c:127
Definition: cse.h:80
uint8_t result
Definition: cse.h:85
Definition: cse_layout.h:97
uint16_t hotfix
Definition: cse_layout.h:103
uint16_t major
Definition: cse_layout.h:100
uint16_t minor
Definition: cse_layout.h:101
struct subpart_entry_manifest_header::@539 binary_version
uint16_t build
Definition: cse_layout.h:102
Definition: cse_layout.h:90
uint32_t offset_bytes
Definition: cse_layout.h:92