<p>Rizwan Qureshi has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/27369">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">soc/intel/skylake: [WIP] Add support for updating microcode in the field<br><br>Change-Id: Iab6ba36a2eb587f331fe522c778e2c430c8eb655<br>Signed-off-by: Rizwan Qureshi <rizwan.qureshi@intel.com><br>---<br>A src/soc/intel/skylake/include/soc/ucode_update.h<br>M src/soc/intel/skylake/romstage/Makefile.inc<br>A src/soc/intel/skylake/romstage/ucode_update.c<br>3 files changed, 287 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/69/27369/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/soc/intel/skylake/include/soc/ucode_update.h b/src/soc/intel/skylake/include/soc/ucode_update.h</span><br><span>new file mode 100644</span><br><span>index 0000000..4a8e67b</span><br><span>--- /dev/null</span><br><span>+++ b/src/soc/intel/skylake/include/soc/ucode_update.h</span><br><span>@@ -0,0 +1 @@</span><br><span style="color: hsl(120, 100%, 40%);">+int check_and_update_ucode(void);</span><br><span>diff --git a/src/soc/intel/skylake/romstage/Makefile.inc b/src/soc/intel/skylake/romstage/Makefile.inc</span><br><span>index 8bfbfea..aa70488 100644</span><br><span>--- a/src/soc/intel/skylake/romstage/Makefile.inc</span><br><span>+++ b/src/soc/intel/skylake/romstage/Makefile.inc</span><br><span>@@ -2,3 +2,4 @@</span><br><span> romstage-$(CONFIG_PLATFORM_USES_FSP1_1) += romstage.c</span><br><span> romstage-$(CONFIG_PLATFORM_USES_FSP2_0) += romstage_fsp20.c</span><br><span> romstage-y += systemagent.c</span><br><span style="color: hsl(120, 100%, 40%);">+romstage-y += ucode_update.c</span><br><span>diff --git a/src/soc/intel/skylake/romstage/ucode_update.c b/src/soc/intel/skylake/romstage/ucode_update.c</span><br><span>new file mode 100644</span><br><span>index 0000000..9a74c0a</span><br><span>--- /dev/null</span><br><span>+++ b/src/soc/intel/skylake/romstage/ucode_update.c</span><br><span>@@ -0,0 +1,285 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * This file is part of the coreboot project.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright (C) 2017 Intel Corp.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; version 2 of the License.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <arch/cpu.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <arch/early_variables.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <arch/io.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <arch/symbols.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <assert.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <cpu/x86/mtrr.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <cpu/x86/msr.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <cbmem.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <chip.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <console/console.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <cpu/intel/microcode.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <fmap.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <spi_flash.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <spi-generic.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <string.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdlib.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <timestamp.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <security/vboot/vboot_common.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <ec/google/chromeec/ec.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <reset.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <intelblocks/lpc_lib.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <soc/ucode_update.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <intelblocks/rtc.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <lib.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <soc/fw_update_nv.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* convert a pointer to flash area into the offset inside the flash */</span><br><span style="color: hsl(120, 100%, 40%);">+static inline u32 to_flash_offset(void *p) {</span><br><span style="color: hsl(120, 100%, 40%);">+     return ((u32)p + CONFIG_VIRTUAL_ROM_SIZE);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void _hard_reset (void){</span><br><span style="color: hsl(120, 100%, 40%);">+      hard_reset();</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int init_state_nv_storage(struct region_device *update_nv,</span><br><span style="color: hsl(120, 100%, 40%);">+ struct fw_update_nv *update_state)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ char empty_nv[FW_UPDATE_NV_DATA_SIZE];</span><br><span style="color: hsl(120, 100%, 40%);">+        int i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      if (get_update_nv_storage(update_nv)) {</span><br><span style="color: hsl(120, 100%, 40%);">+               printk (BIOS_ERR, "Update NV could not be init\n");</span><br><span style="color: hsl(120, 100%, 40%);">+         return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (get_update_state(update_nv, update_state)) {</span><br><span style="color: hsl(120, 100%, 40%);">+              printk (BIOS_ERR, "Error reading update state\n");</span><br><span style="color: hsl(120, 100%, 40%);">+          return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     /* if empty, set initial state. This should be done only during first boot */</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i=0;i<FW_UPDATE_NV_DATA_SIZE;i++)</span><br><span style="color: hsl(120, 100%, 40%);">+             empty_nv[i] = ERASE_VALUE;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  hexdump((void *)update_state, FW_UPDATE_NV_DATA_SIZE);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!memcmp((void *)&empty_nv, (void *)update_state,</span><br><span style="color: hsl(120, 100%, 40%);">+                              FW_UPDATE_NV_DATA_SIZE)) {</span><br><span style="color: hsl(120, 100%, 40%);">+            printk (BIOS_ERR, "Initializing NV\n");</span><br><span style="color: hsl(120, 100%, 40%);">+             update_state->ucode_state = UPDATE_VERIFIED;</span><br><span style="color: hsl(120, 100%, 40%);">+               update_state->cse_state = UPDATE_VERIFIED;</span><br><span style="color: hsl(120, 100%, 40%);">+         update_state->initialized = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+             if (set_update_state(update_nv, update_state)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      printk (BIOS_ERR, "Couldn't write to NV region\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                     return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int write_ucode(struct region_device *rdev, void *ucode_stage,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                 void *cbfs_ucode)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  struct spi_flash flash;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     spi_init();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (spi_flash_probe(0, 0, &flash)) {</span><br><span style="color: hsl(120, 100%, 40%);">+              printk(BIOS_DEBUG, "Could not find SPI device\n");</span><br><span style="color: hsl(120, 100%, 40%);">+          return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (spi_flash_erase(&flash,</span><br><span style="color: hsl(120, 100%, 40%);">+               to_flash_offset(ucode_stage) & 0xFFFFFF,</span><br><span style="color: hsl(120, 100%, 40%);">+                  region_device_sz(rdev))){</span><br><span style="color: hsl(120, 100%, 40%);">+             printk (BIOS_ERR,</span><br><span style="color: hsl(120, 100%, 40%);">+                     "Failed to erase staging ucode\n");</span><br><span style="color: hsl(120, 100%, 40%);">+         return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+             /*TODO: reset*/</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if(spi_flash_write(&flash,</span><br><span style="color: hsl(120, 100%, 40%);">+                to_flash_offset(ucode_stage) & 0xFFFFFF,</span><br><span style="color: hsl(120, 100%, 40%);">+                  (size_t) get_microcode_size(cbfs_ucode), cbfs_ucode)){</span><br><span style="color: hsl(120, 100%, 40%);">+                printk (BIOS_ERR,</span><br><span style="color: hsl(120, 100%, 40%);">+                     "Failed to update staging ucode\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+             /*TODO: reset*/</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void *get_ucode_staging_area(struct region_device *rdev)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    void *ucode_stage = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Get staging microcode */</span><br><span style="color: hsl(120, 100%, 40%);">+   if (fmap_locate_area_as_rdev(CONFIG_INTEL_TOP_SWAP_FIT_ENTRY,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                         rdev) == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+         ucode_stage = rdev_mmap_full(rdev);</span><br><span style="color: hsl(120, 100%, 40%);">+           if (ucode_stage == NULL )</span><br><span style="color: hsl(120, 100%, 40%);">+                     printk(BIOS_DEBUG, "ucode staging could not be mapped\n");</span><br><span style="color: hsl(120, 100%, 40%);">+  } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              printk(BIOS_ERR, "ucode stage not found");</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return ucode_stage;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#if 0</span><br><span style="color: hsl(120, 100%, 40%);">+static int is_microcode_header_empty(void * microcode)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    char empty_ucode_header[48];</span><br><span style="color: hsl(120, 100%, 40%);">+  int i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* if empty, set initial state. This should be done only during first boot */</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i = 0; i < 48; i++)</span><br><span style="color: hsl(120, 100%, 40%);">+           empty_ucode_header[i] = ERASE_VALUE;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        hexdump(microcode, 48);</span><br><span style="color: hsl(120, 100%, 40%);">+       hexdump((void*)&empty_ucode_header, 48);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (memcmp((void*)&empty_ucode_header, microcode, 48))</span><br><span style="color: hsl(120, 100%, 40%);">+            return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     else</span><br><span style="color: hsl(120, 100%, 40%);">+          return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int check_and_update_ucode(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t current_ucode, slot_rev, staging_rev, version_mismatch = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+  struct region_device rdev;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct region_device upd_state_nv;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct fw_update_nv upd_state; </span><br><span style="color: hsl(120, 100%, 40%);">+       const void *slot_microcode = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+    const void *staging_microcode = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (init_state_nv_storage(&upd_state_nv, &upd_state)){</span><br><span style="color: hsl(120, 100%, 40%);">+                die("Failed to Initialize update state NV\n");</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Get top swap status */</span><br><span style="color: hsl(120, 100%, 40%);">+     enum ts_config ts_strap = get_rtc_buc_top_swap_status(); </span><br><span style="color: hsl(120, 100%, 40%);">+     /* Get recovery mode */</span><br><span style="color: hsl(120, 100%, 40%);">+       int rec_mode = vboot_recovery_mode_enabled();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* Get Ucode versions */</span><br><span style="color: hsl(120, 100%, 40%);">+      current_ucode = get_current_microcode_rev();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        slot_microcode = intel_microcode_find();</span><br><span style="color: hsl(120, 100%, 40%);">+      slot_rev = get_microcode_rev(slot_microcode) - 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   staging_microcode = get_ucode_staging_area(&rdev);</span><br><span style="color: hsl(120, 100%, 40%);">+        if (staging_microcode == NULL)</span><br><span style="color: hsl(120, 100%, 40%);">+                return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   staging_rev = get_microcode_rev(staging_microcode) - 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     printk(BIOS_DEBUG, "Top Swap:      0x%x\n", ts_strap);</span><br><span style="color: hsl(120, 100%, 40%);">+      printk(BIOS_DEBUG, "Recovery Mode: 0x%x\n", rec_mode);</span><br><span style="color: hsl(120, 100%, 40%);">+      printk(BIOS_DEBUG, "Current ucode version: 0x%x\n", current_ucode);</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(BIOS_DEBUG, "Slot ucode version:    0x%x\n", slot_rev);</span><br><span style="color: hsl(120, 100%, 40%);">+      printk(BIOS_DEBUG, "Staging area ucode:    0x%x\n", staging_rev);</span><br><span style="color: hsl(120, 100%, 40%);">+   printk(BIOS_DEBUG, "Update State:   0x%x\n", upd_state.ucode_state);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      if (staging_rev != current_ucode || current_ucode != slot_rev ||</span><br><span style="color: hsl(120, 100%, 40%);">+                      staging_rev != slot_rev)</span><br><span style="color: hsl(120, 100%, 40%);">+              version_mismatch = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       printk(BIOS_DEBUG, "Mismatch: 0x%x\n", version_mismatch);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!rec_mode) {</span><br><span style="color: hsl(120, 100%, 40%);">+              switch (upd_state.ucode_state) {</span><br><span style="color: hsl(120, 100%, 40%);">+              case UPDATE_VERIFIED:</span><br><span style="color: hsl(120, 100%, 40%);">+                 if (version_mismatch) {</span><br><span style="color: hsl(120, 100%, 40%);">+                               if (!ts_strap) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                      /* We are using a RO ucode, switch to</span><br><span style="color: hsl(120, 100%, 40%);">+                                  * top swap FIT.</span><br><span style="color: hsl(120, 100%, 40%);">+                                       */</span><br><span style="color: hsl(120, 100%, 40%);">+                                   configure_rtc_buc_top_swap(TS_ENABLE);</span><br><span style="color: hsl(120, 100%, 40%);">+                                        _hard_reset();</span><br><span style="color: hsl(120, 100%, 40%);">+                                }</span><br><span style="color: hsl(120, 100%, 40%);">+                             /* New ucode available, start update process */</span><br><span style="color: hsl(120, 100%, 40%);">+                               upd_state.ucode_state = UPDATE_START;</span><br><span style="color: hsl(120, 100%, 40%);">+                         if (set_update_state(&upd_state_nv, &upd_state))</span><br><span style="color: hsl(120, 100%, 40%);">+                                      return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+                             if (write_ucode(&rdev, (void *)staging_microcode,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                 (void *)slot_microcode)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                    printk (BIOS_ERR, "Write failed\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                                        return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+                             }</span><br><span style="color: hsl(120, 100%, 40%);">+                             /* Finished writing, reset */</span><br><span style="color: hsl(120, 100%, 40%);">+                         upd_state.ucode_state = UPDATE_WRITE_COMPLETE;</span><br><span style="color: hsl(120, 100%, 40%);">+                                if (set_update_state(&upd_state_nv, &upd_state)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                    return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+                             }</span><br><span style="color: hsl(120, 100%, 40%);">+                             _hard_reset();</span><br><span style="color: hsl(120, 100%, 40%);">+                        }</span><br><span style="color: hsl(120, 100%, 40%);">+                     break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case UPDATE_WRITE_COMPLETE:</span><br><span style="color: hsl(120, 100%, 40%);">+                   if (version_mismatch) {</span><br><span style="color: hsl(120, 100%, 40%);">+                               if (!ts_strap) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                      /* We are using a RO ucode, switch to</span><br><span style="color: hsl(120, 100%, 40%);">+                                  * top swap FIT.</span><br><span style="color: hsl(120, 100%, 40%);">+                                       */</span><br><span style="color: hsl(120, 100%, 40%);">+                                   configure_rtc_buc_top_swap(TS_ENABLE);</span><br><span style="color: hsl(120, 100%, 40%);">+                                        _hard_reset();</span><br><span style="color: hsl(120, 100%, 40%);">+                                } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                                      /* The right ucode could not be loaded</span><br><span style="color: hsl(120, 100%, 40%);">+                                         * even after the update. Fallback to</span><br><span style="color: hsl(120, 100%, 40%);">+                                  * the previous slot.</span><br><span style="color: hsl(120, 100%, 40%);">+                                  */</span><br><span style="color: hsl(120, 100%, 40%);">+                           }</span><br><span style="color: hsl(120, 100%, 40%);">+                     } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                              /* Update is good, mark verified and continue */</span><br><span style="color: hsl(120, 100%, 40%);">+                              upd_state.ucode_state = UPDATE_VERIFIED;</span><br><span style="color: hsl(120, 100%, 40%);">+                              if (set_update_state(&upd_state_nv, &upd_state)) </span><br><span style="color: hsl(120, 100%, 40%);">+                                     return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+                     }</span><br><span style="color: hsl(120, 100%, 40%);">+                     break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case UPDATE_START:</span><br><span style="color: hsl(120, 100%, 40%);">+                    /* The previous update did not complete, retry */</span><br><span style="color: hsl(120, 100%, 40%);">+                     if (!ts_strap) {</span><br><span style="color: hsl(120, 100%, 40%);">+                              /* We are using a RO ucode, switch to</span><br><span style="color: hsl(120, 100%, 40%);">+                          * top swap FIT.</span><br><span style="color: hsl(120, 100%, 40%);">+                               */</span><br><span style="color: hsl(120, 100%, 40%);">+                           configure_rtc_buc_top_swap(TS_ENABLE);</span><br><span style="color: hsl(120, 100%, 40%);">+                                _hard_reset();</span><br><span style="color: hsl(120, 100%, 40%);">+                        } </span><br><span style="color: hsl(120, 100%, 40%);">+                    if (write_ucode(&rdev, (void *)staging_microcode,</span><br><span style="color: hsl(120, 100%, 40%);">+                                         (void *)slot_microcode)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                            printk (BIOS_ERR, "Write failed\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                                return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+                     }</span><br><span style="color: hsl(120, 100%, 40%);">+                     upd_state.ucode_state = UPDATE_WRITE_COMPLETE;</span><br><span style="color: hsl(120, 100%, 40%);">+                        if (set_update_state(&upd_state_nv, &upd_state)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                            return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+                     }</span><br><span style="color: hsl(120, 100%, 40%);">+                     _hard_reset();</span><br><span style="color: hsl(120, 100%, 40%);">+                }</span><br><span style="color: hsl(120, 100%, 40%);">+     } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              /*In recovery, make sure topswap is disabled */</span><br><span style="color: hsl(120, 100%, 40%);">+               if (ts_strap) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       configure_rtc_buc_top_swap(TS_DISABLE);</span><br><span style="color: hsl(120, 100%, 40%);">+                       _hard_reset();</span><br><span style="color: hsl(120, 100%, 40%);">+                }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Protect the RW ucode staging area */</span><br><span style="color: hsl(120, 100%, 40%);">+       if (spi_flash_ctrlr_protect_region(boot_device_spi_flash(),</span><br><span style="color: hsl(120, 100%, 40%);">+                           &rdev.region) < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+           printk(BIOS_ERR, "ERROR setting FPR for staging.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+               return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/27369">change 27369</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/27369"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: Iab6ba36a2eb587f331fe522c778e2c430c8eb655 </div>
<div style="display:none"> Gerrit-Change-Number: 27369 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Rizwan Qureshi <rizwan.qureshi@intel.com> </div>