From 5fe1fb7a5fc0c3e9ffbc30187e2a5c15f86f2a08 Mon Sep 17 00:00:00 2001 From: Kyösti Mälkki Date: Sun, 8 Dec 2013 07:21:05 +0200 Subject: cpu/amd (non-AGESA): Load microcode updates from CBFS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ic67856414ea2fea9a9eb95d72136cb05da9483fa Signed-off-by: Kyösti Mälkki Signed-off-by: Alexandru Gagniuc Reviewed-on: http://review.coreboot.org/4502 Tested-by: build bot (Jenkins) Reviewed-by: Timothy Pearson --- src/cpu/amd/microcode/microcode.c | 68 +++++++++++++++------- src/cpu/amd/model_10xxx/Kconfig | 1 + src/cpu/amd/model_10xxx/Makefile.inc | 2 + src/cpu/amd/model_10xxx/microcode_blob.c | 9 +++ src/cpu/amd/model_10xxx/update_microcode.c | 27 +-------- src/cpu/amd/model_fxx/Kconfig | 1 + src/cpu/amd/model_fxx/Makefile.inc | 2 + src/cpu/amd/model_fxx/microcode_blob.c | 13 +++++ src/cpu/amd/model_fxx/model_fxx_init.c | 2 +- src/cpu/amd/model_fxx/model_fxx_update_microcode.c | 27 ++------- 10 files changed, 81 insertions(+), 71 deletions(-) create mode 100644 src/cpu/amd/model_10xxx/microcode_blob.c create mode 100644 src/cpu/amd/model_fxx/microcode_blob.c (limited to 'src/cpu') diff --git a/src/cpu/amd/microcode/microcode.c b/src/cpu/amd/microcode/microcode.c index cdc6e4aad1..a5da75b74c 100644 --- a/src/cpu/amd/microcode/microcode.c +++ b/src/cpu/amd/microcode/microcode.c @@ -21,6 +21,10 @@ #include #include #include +#include + +#define UCODE_DEBUG(fmt, args...) \ + do { printk(BIOS_DEBUG, "[microcode] "fmt, ##args); } while(0) struct microcode { u32 date_code; @@ -51,40 +55,60 @@ struct microcode { u8 x86_code_entry[191]; }; -void amd_update_microcode(void *microcode_updates, u32 equivalent_processor_rev_id) +static void apply_microcode_patch(const struct microcode *m) { - u32 patch_id, new_patch_id; - struct microcode *m; - char *c; + uint32_t new_patch_id; msr_t msr; - msr = rdmsr(0x8b); - patch_id = msr.lo; - - printk(BIOS_DEBUG, "microcode: equivalent rev id = 0x%04x, current patch id = 0x%08x\n", equivalent_processor_rev_id, patch_id); + /* apply patch */ + msr.hi = 0; + msr.lo = (uint32_t)m; - m = microcode_updates; + wrmsr(0xc0010020, msr); - for(c = microcode_updates; m->date_code; m = (struct microcode *)c) { - - if (m->processor_rev_id == equivalent_processor_rev_id) { - //apply patch + UCODE_DEBUG("patch id to apply = 0x%08x\n", m->patch_id); - msr.hi = 0; - msr.lo = (u32)m; - - wrmsr(0xc0010020, msr); + /* read the patch_id again */ + msr = rdmsr(0x8b); + new_patch_id = msr.lo; - printk(BIOS_DEBUG, "microcode: patch id to apply = 0x%08x\n", m->patch_id); + UCODE_DEBUG("updated to patch id = 0x%08x %s\n", new_patch_id , + (new_patch_id == m->patch_id) ? "success" : "fail"); +} - //read the patch_id again - msr = rdmsr(0x8b); - new_patch_id = msr.lo; +static void amd_update_microcode(const void *ucode, size_t ucode_len, + uint32_t equivalent_processor_rev_id) +{ + const struct microcode *m; + const void *c; - printk(BIOS_DEBUG, "microcode: updated to patch id = 0x%08x %s\n", new_patch_id , (new_patch_id == m->patch_id)?" success\n":" fail\n" ); + for(m = c = ucode; m->date_code; m = c) { + if (m->processor_rev_id == equivalent_processor_rev_id) { + apply_microcode_patch(m); break; } c += 2048; } +} + +#define MICROCODE_CBFS_FILE "cpu_microcode_blob.bin" + +void amd_update_microcode_from_cbfs(u32 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; + } + + ucode = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, MICROCODE_CBFS_FILE, + 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); } diff --git a/src/cpu/amd/model_10xxx/Kconfig b/src/cpu/amd/model_10xxx/Kconfig index 09c7ec7bd8..1b79eb08d9 100644 --- a/src/cpu/amd/model_10xxx/Kconfig +++ b/src/cpu/amd/model_10xxx/Kconfig @@ -9,6 +9,7 @@ config CPU_AMD_MODEL_10XXX select MMCONF_SUPPORT_DEFAULT select TSC_SYNC_LFENCE select UDELAY_LAPIC + select SUPPORT_CPU_UCODE_IN_CBFS if CPU_AMD_MODEL_10XXX diff --git a/src/cpu/amd/model_10xxx/Makefile.inc b/src/cpu/amd/model_10xxx/Makefile.inc index 2f04762058..f5cf37514c 100644 --- a/src/cpu/amd/model_10xxx/Makefile.inc +++ b/src/cpu/amd/model_10xxx/Makefile.inc @@ -4,3 +4,5 @@ ramstage-y += processor_name.c romstage-y += update_microcode.c ramstage-$(CONFIG_HAVE_ACPI_TABLES) += powernow_acpi.c + +cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c diff --git a/src/cpu/amd/model_10xxx/microcode_blob.c b/src/cpu/amd/model_10xxx/microcode_blob.c new file mode 100644 index 0000000000..78eae36732 --- /dev/null +++ b/src/cpu/amd/model_10xxx/microcode_blob.c @@ -0,0 +1,9 @@ +unsigned char microcode[] __attribute__ ((aligned(16))) = { +#include CONFIG_AMD_UCODE_PATCH_FILE + + /* Dummy terminator */ + 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, +}; diff --git a/src/cpu/amd/model_10xxx/update_microcode.c b/src/cpu/amd/model_10xxx/update_microcode.c index 3cdf97898a..8dcd90dd1a 100644 --- a/src/cpu/amd/model_10xxx/update_microcode.c +++ b/src/cpu/amd/model_10xxx/update_microcode.c @@ -19,13 +19,8 @@ */ #include -#include #include -static const u8 microcode_updates[] __attribute__ ((aligned(16))) = { - -#ifdef __PRE_RAM__ - /* From the Revision Guide : * Equivalent Processor Table for AMD Family 10h Processors * @@ -47,16 +42,6 @@ static const u8 microcode_updates[] __attribute__ ((aligned(16))) = { * 00100FA0h (PH-E0) 10A0h 010000bfh */ -#include CONFIG_AMD_UCODE_PATCH_FILE - -#endif - /* Dummy terminator */ - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, -}; - struct id_mapping { uint32_t orig_id; uint16_t new_id; @@ -101,14 +86,6 @@ static u16 get_equivalent_processor_rev_id(u32 orig_id) { void update_microcode(u32 cpu_deviceid) { - u32 equivalent_processor_rev_id; - - /* Update the microcode */ - equivalent_processor_rev_id = get_equivalent_processor_rev_id(cpu_deviceid ); - if (equivalent_processor_rev_id != 0) { - amd_update_microcode((void *) microcode_updates, equivalent_processor_rev_id); - } else { - printk(BIOS_DEBUG, "microcode: rev id not found. Skipping microcode patch!\n"); - } - + u32 equivalent_processor_rev_id = get_equivalent_processor_rev_id(cpu_deviceid); + amd_update_microcode_from_cbfs(equivalent_processor_rev_id); } diff --git a/src/cpu/amd/model_fxx/Kconfig b/src/cpu/amd/model_fxx/Kconfig index bdcf5bb4f9..9ee2bf74cf 100644 --- a/src/cpu/amd/model_fxx/Kconfig +++ b/src/cpu/amd/model_fxx/Kconfig @@ -9,6 +9,7 @@ config CPU_AMD_MODEL_FXX select SSE2 select TSC_SYNC_LFENCE select UDELAY_LAPIC + select SUPPORT_CPU_UCODE_IN_CBFS if CPU_AMD_MODEL_FXX config UDELAY_IO diff --git a/src/cpu/amd/model_fxx/Makefile.inc b/src/cpu/amd/model_fxx/Makefile.inc index cf4ac2183f..19a6255c6b 100644 --- a/src/cpu/amd/model_fxx/Makefile.inc +++ b/src/cpu/amd/model_fxx/Makefile.inc @@ -5,3 +5,5 @@ ramstage-y += model_fxx_init.c ramstage-y += model_fxx_update_microcode.c ramstage-y += processor_name.c ramstage-$(CONFIG_HAVE_ACPI_TABLES) += powernow_acpi.c + +cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c diff --git a/src/cpu/amd/model_fxx/microcode_blob.c b/src/cpu/amd/model_fxx/microcode_blob.c new file mode 100644 index 0000000000..1b6b979cd4 --- /dev/null +++ b/src/cpu/amd/model_fxx/microcode_blob.c @@ -0,0 +1,13 @@ +unsigned char microcode[] __attribute__ ((aligned(16))) = { +#if !CONFIG_K8_REV_F_SUPPORT + #include "microcode_rev_c.h" + #include "microcode_rev_d.h" + #include "microcode_rev_e.h" +#endif + + /* Dummy terminator */ + 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, +}; diff --git a/src/cpu/amd/model_fxx/model_fxx_init.c b/src/cpu/amd/model_fxx/model_fxx_init.c index 260e83ecb0..33226d465a 100644 --- a/src/cpu/amd/model_fxx/model_fxx_init.c +++ b/src/cpu/amd/model_fxx/model_fxx_init.c @@ -468,7 +468,7 @@ static void model_fxx_init(device_t dev) x86_mtrr_check(); /* Update the microcode */ - model_fxx_update_microcode(dev->device); + update_microcode(dev->device); disable_cache(); diff --git a/src/cpu/amd/model_fxx/model_fxx_update_microcode.c b/src/cpu/amd/model_fxx/model_fxx_update_microcode.c index af10ce0670..ed673496f8 100644 --- a/src/cpu/amd/model_fxx/model_fxx_update_microcode.c +++ b/src/cpu/amd/model_fxx/model_fxx_update_microcode.c @@ -23,24 +23,6 @@ #include #include -static uint8_t microcode_updates[] __attribute__ ((aligned(16))) = { - -#if !CONFIG_K8_REV_F_SUPPORT - #include "microcode_rev_c.h" - #include "microcode_rev_d.h" - #include "microcode_rev_e.h" -#endif - -#if CONFIG_K8_REV_F_SUPPORT -// #include "microcode_rev_f.h" -#endif - /* Dummy terminator */ - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, -}; - struct id_mapping { uint32_t orig_id; uint16_t new_id; @@ -95,12 +77,11 @@ static u16 get_equivalent_processor_rev_id(u32 orig_id) { return new_id; } -void model_fxx_update_microcode(unsigned cpu_deviceid) +void update_microcode(uint32_t cpu_deviceid) { - unsigned equivalent_processor_rev_id; + uint32_t equivalent_rev_id; /* Update the microcode */ - equivalent_processor_rev_id = get_equivalent_processor_rev_id(cpu_deviceid ); - if(equivalent_processor_rev_id != 0) - amd_update_microcode(microcode_updates, equivalent_processor_rev_id); + equivalent_rev_id = get_equivalent_processor_rev_id(cpu_deviceid); + amd_update_microcode_from_cbfs(equivalent_rev_id); } -- cgit v1.2.3