[coreboot-gerrit] Patch set updated for coreboot: cpu/amd/microcode: Update parser to use stock microcode blobs

Audrey Pearson (apearson@raptorengineeringinc.com) gerrit at coreboot.org
Fri Oct 9 21:03:07 CEST 2015


Audrey Pearson (apearson at raptorengineeringinc.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11829

-gerrit

commit fc9b5edd95bfbcc8d010997abe0f0b1a373c000f
Author: Audrey Pearson <apearson at raptorengineeringinc.com>
Date:   Thu Oct 8 12:47:24 2015 -0500

    cpu/amd/microcode: Update parser to use stock microcode blobs
    
    The existing microcode update system used custom, manually generated microcode
    blob files.  This made updates very difficult.  Update parser to use stock
    microcode update files as provided by AMD.
    
    Change-Id: I772b264ad167f2a5d629dab5d64d9b0ccab3a053
    Signed-off-by: Audrey Pearson <apearson at raptorengineeringinc.com>
---
 src/cpu/amd/microcode/microcode.c | 174 ++++++++++++++++++++++++++++++--------
 1 file changed, 140 insertions(+), 34 deletions(-)

diff --git a/src/cpu/amd/microcode/microcode.c b/src/cpu/amd/microcode/microcode.c
index 45e4bf0..7eb5c16 100644
--- a/src/cpu/amd/microcode/microcode.c
+++ b/src/cpu/amd/microcode/microcode.c
@@ -2,6 +2,7 @@
  * This file is part of the coreboot project.
  *
  * Copyright (C) 2007 Advanced Micro Devices, Inc.
+ * Copyright (C) 2015 Raptor Engineering
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -22,37 +23,96 @@
 #include <cpu/x86/msr.h>
 #include <cpu/amd/microcode.h>
 #include <cbfs.h>
+#include <device/pci.h>
 
 #define UCODE_DEBUG(fmt, args...)	\
 	do { printk(BIOS_DEBUG, "[microcode] "fmt, ##args); } while(0)
 
+#define UCODE_MAGIC			0x00414d44
+#define UCODE_EQUIV_CPU_TABLE_TYPE	0x00000000
+#define UCODE_SECTION_START_ID		0x00000001
+#define UCODE_MAGIC			0x00414d44
+
+#define F1XH_MPB_MAX_SIZE 	2048
+#define F15H_MPB_MAX_SIZE 	4096
+#define CONT_HDR 		12
+#define SECT_HDR		8
+
+/*
+ * STRUCTURE OF A MICROCODE (UCODE) FILE
+ * 	Container Header
+ *	Section Header
+ *	Microcode Header
+ *	Microcode "Blob"
+ *	Section Header
+ *	Microcode Header
+ *	Microcode "Blob"
+ *	...
+ *	...
+ *	(end of file)
+ *
+ *
+ * CONTAINER HEADER (offset 0 bytes from start of file)
+ * Total size = fixed size (12 bytes) + variable size
+ *	[0:3]  32-bit unique ID
+ *	[4:7]  don't-care
+ *	[8-11] Size (n) in bytes of variable portion of container header
+ *	[12-n] don't-care
+ *
+ * SECTION HEADER (offset += 12+n)
+ * Total size = 8 bytes
+ * 	[0:3] Unique identifier signaling start of section (0x00000001)
+ * 	[4:7] Total size (m) of following microcode section, including microcode header
+ *
+ * MICROCODE HEADER (offset += 8)
+ * Total size = 64 bytes
+ * 	[0:3]	Data code		(32 bits)
+ *	[4:7]	Patch ID		(32 bits)
+ * 	[8:9]	Microcode patch data ID (16 bits)
+ * 	[10]	c patch data length	(8  bits)
+ * 	[11]	init flag		(8 bits)
+ * 	[12:15]	ucode patch data cksum	(32 bits)
+ * 	[16:19]	nb dev ID		(32 bits)
+ * 	[20:23]	sb dev ID		(32 bits)
+ * 	[24:25]	Processor rev ID	(16 bits)
+ * 	[26]	nb revision ID		(8 bits)
+ * 	[27]	sb revision ID		(8 bits)
+ * 	[28]	BIOS API revision	(8 bits)
+ * 	[29-31]	Reserved 1 (array of three 8-bit values)
+ * 	[32-63]	Match reg (array of eight 32-bit values)
+ *
+ * MICROCODE BLOB (offset += 64)
+ * Total size = m bytes
+ *
+ */
+
 struct microcode {
-	u32 date_code;
-	u32 patch_id;
+	uint32_t data_code;
+	uint32_t patch_id;
 
-	u16 m_patch_data_id;
-	u8 m_patch_data_len;
-	u8 init_flag;
+	uint16_t mc_patch_data_id;
+	uint8_t	mc_patch_data_len;
+	uint8_t	init_flag;
 
-	u32 m_patch_data_cksum;
+	uint32_t mc_patch_data_checksum;
 
-	u32 nb_dev_id;
-	u32 ht_io_hub_dev_id;
+	uint32_t nb_dev_id;
+	uint32_t sb_dev_id;
 
-	u16 processor_rev_id;
-	u8 ht_io_hub_rev_id;
-	u8 nb_rev_id;
+	uint16_t processor_rev_id;
+	uint8_t	nb_rev_id;
+	uint8_t	sb_rev_id;
 
-	u8 bios_api_rev;
-	u8 resv1[3];
+	uint8_t	bios_api_rev;
+	uint8_t	reserved1[3];
 
-	u32 match_reg[8];
+	uint32_t match_reg[8];
 
-	u8 m_patch_data[896];
-	u8 resv2[896];
+	uint8_t	m_patch_data[896];
+	uint8_t	resv2[896];
 
-	u8 x86_code_present;
-	u8 x86_code_entry[191];
+	uint8_t	x86_code_present;
+	uint8_t	x86_code_entry[191];
 };
 
 static void apply_microcode_patch(const struct microcode *m)
@@ -82,35 +142,81 @@ static void amd_update_microcode(const void *ucode,  size_t ucode_len,
 	const struct microcode *m;
 	const uint8_t *c = ucode;
 	const uint8_t *ucode_end = (uint8_t*)ucode + ucode_len;
+	const uint8_t *cur_section_hdr;
+
+	uint32_t offset = 0;
+	uint32_t container_hdr_id;
+	uint32_t container_hdr_size;
+	uint32_t blob_size;
+	uint32_t sec_hdr_id;
+
+	/* Container Header */
+	container_hdr_id = read32(c);
+	if (container_hdr_id != UCODE_MAGIC) {
+		UCODE_DEBUG("Invalid container header ID\n");
+		return;
+	}
+	offset += 8;
+
+	container_hdr_size = read32(c + 8);
+	offset += (4 + container_hdr_size);
+	cur_section_hdr = c + CONT_HDR + container_hdr_size;
+
+	/* Read in first section header ID */
+	sec_hdr_id = read32(cur_section_hdr);
+	offset += 4;
+
+	/* Loop through sections */
+	while (sec_hdr_id == UCODE_SECTION_START_ID &&
+		c <= (ucode_end - F15H_MPB_MAX_SIZE)) {
+
+		blob_size = read32(c + offset);
+		offset += 4;
+
+		m = (struct microcode *)(c + offset);
 
-	while (c <= (ucode_end - 2048)) {
-		m = (struct microcode *)c;
 		if (m->processor_rev_id == equivalent_processor_rev_id) {
 			apply_microcode_patch(m);
 			break;
 		}
-		c += 2048;
+
+		offset += blob_size;
+
+		cur_section_hdr = c + offset;
+		sec_hdr_id = read32(cur_section_hdr);
+		offset += 4;
 	}
 }
 
-#define MICROCODE_CBFS_FILE "cpu_microcode_blob.bin"
+static const char *microcode_cbfs_file[] = {
+	"microcode_amd.bin",
+	"microcode_amd_fam15h.bin",
+};
 
-void amd_update_microcode_from_cbfs(u32 equivalent_processor_rev_id)
+void amd_update_microcode_from_cbfs(uint32_t equivalent_processor_rev_id)
 {
 	const void *ucode;
 	size_t ucode_len;
 
-	if (equivalent_processor_rev_id == 0) {
-		UCODE_DEBUG("rev id not found. Skipping microcode patch!\n");
-		return;
-	}
+	uint32_t i = 0;
 
-	ucode = cbfs_boot_map_with_leak(MICROCODE_CBFS_FILE,
-					CBFS_TYPE_MICROCODE, &ucode_len);
-	if (!ucode) {
-		UCODE_DEBUG("microcode file not found. Skipping updates.\n");
-		return;
-	}
+	while (i < ARRAY_SIZE(microcode_cbfs_file))
+	{
+		if (equivalent_processor_rev_id == 0) {
+			UCODE_DEBUG("rev id not found. Skipping microcode patch!\n");
+			return;
+		}
 
-	amd_update_microcode(ucode, ucode_len, equivalent_processor_rev_id);
+		ucode = cbfs_boot_map_with_leak(microcode_cbfs_file[i],
+						CBFS_TYPE_MICROCODE, &ucode_len);
+		if (!ucode) {
+			UCODE_DEBUG("microcode file not found. Skipping updates.\n");
+
+			return;
+		}
+
+		amd_update_microcode(ucode, ucode_len, equivalent_processor_rev_id);
+
+		i++;
+	}
 }



More information about the coreboot-gerrit mailing list