<p>Arthur Heymans has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/27091">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">[WIP]src/cpu/intel/car: Update microcode before setting up CARe<br><br>This reuses cbfstool adding a FIT table with pointers to microcode<br>headers meant for later Intel CPUs.<br><br>Change-Id: I8bd192f3f345651db0010239f99293ae63b00652<br>Signed-off-by: Arthur Heymans <arthur@aheymans.xyz><br>---<br>M src/cpu/intel/car/p4-netburst/cache_as_ram_bootblock.S<br>A src/cpu/intel/microcode/microcode.S<br>M src/cpu/intel/socket_LGA775/Kconfig<br>M src/cpu/intel/socket_LGA775/Makefile.inc<br>4 files changed, 157 insertions(+), 6 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/91/27091/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/cpu/intel/car/p4-netburst/cache_as_ram_bootblock.S b/src/cpu/intel/car/p4-netburst/cache_as_ram_bootblock.S</span><br><span>index 351f98c..40b7733 100644</span><br><span>--- a/src/cpu/intel/car/p4-netburst/cache_as_ram_bootblock.S</span><br><span>+++ b/src/cpu/intel/car/p4-netburst/cache_as_ram_bootblock.S</span><br><span>@@ -28,13 +28,9 @@</span><br><span> #define CACHE_AS_RAM_SIZE CONFIG_DCACHE_RAM_SIZE</span><br><span> #define CACHE_AS_RAM_BASE CONFIG_DCACHE_RAM_BASE</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-.global bootblock_pre_c_entry</span><br><span style="color: hsl(120, 100%, 40%);">+.global setup_car</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-.code32</span><br><span style="color: hsl(0, 100%, 40%);">-bootblock_pre_c_entry:</span><br><span style="color: hsl(0, 100%, 40%);">-_cache_as_ram_setup:</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+setup_car:</span><br><span> cache_as_ram:</span><br><span>    post_code(0x20)</span><br><span> </span><br><span>diff --git a/src/cpu/intel/microcode/microcode.S b/src/cpu/intel/microcode/microcode.S</span><br><span>new file mode 100644</span><br><span>index 0000000..5114069</span><br><span>--- /dev/null</span><br><span>+++ b/src/cpu/intel/microcode/microcode.S</span><br><span>@@ -0,0 +1,149 @@</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) 2018 Arthur Heymans <arthur@aheymans.xyz></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 <cpu/x86/post_code.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+.global bootblock_pre_c_entry</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+.code32</span><br><span style="color: hsl(120, 100%, 40%);">+bootblock_pre_c_entry:</span><br><span style="color: hsl(120, 100%, 40%);">+_update_bsp_microcode:</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Follow the _FIT_ pointer */</span><br><span style="color: hsl(120, 100%, 40%);">+        movl    $0xffffffc0, %edi</span><br><span style="color: hsl(120, 100%, 40%);">+     cmpl    $0, (%edi)</span><br><span style="color: hsl(120, 100%, 40%);">+    je      end_microcode_update</span><br><span style="color: hsl(120, 100%, 40%);">+        /* %edi points at the start of the FIT table */</span><br><span style="color: hsl(120, 100%, 40%);">+        movl     (%edi), %eax</span><br><span style="color: hsl(120, 100%, 40%);">+        movl      %eax, %edi</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+check_fit_header:</span><br><span style="color: hsl(120, 100%, 40%);">+        /* Check if the FIT table starts with "_FIT_   " */</span><br><span style="color: hsl(120, 100%, 40%);">+        movl    0(%edi), %ebx</span><br><span style="color: hsl(120, 100%, 40%);">+ cmpl    %ebx, fit_header</span><br><span style="color: hsl(120, 100%, 40%);">+      jne     end_microcode_update</span><br><span style="color: hsl(120, 100%, 40%);">+  movl    4(%edi), %ebx</span><br><span style="color: hsl(120, 100%, 40%);">+ cmpl    %ebx, fit_header+4</span><br><span style="color: hsl(120, 100%, 40%);">+    jne     end_microcode_update</span><br><span style="color: hsl(120, 100%, 40%);">+        </span><br><span style="color: hsl(120, 100%, 40%);">+check_fit_entry_checksum_valid:</span><br><span style="color: hsl(120, 100%, 40%);">+       movb    14(%edi), %bl</span><br><span style="color: hsl(120, 100%, 40%);">+ cmpb    $0x80, %bl</span><br><span style="color: hsl(120, 100%, 40%);">+    jne     end_microcode_update</span><br><span style="color: hsl(120, 100%, 40%);">+        </span><br><span style="color: hsl(120, 100%, 40%);">+check_fit_checksum:</span><br><span style="color: hsl(120, 100%, 40%);">+        /* All bytes of the table must add up to a 0 byte */</span><br><span style="color: hsl(120, 100%, 40%);">+     movl    8(%edi), %ecx</span><br><span style="color: hsl(120, 100%, 40%);">+ shl     $4, %ecx</span><br><span style="color: hsl(120, 100%, 40%);">+      movl    %edi, %esi</span><br><span style="color: hsl(120, 100%, 40%);">+    movb    $0, %al</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+1:</span><br><span style="color: hsl(120, 100%, 40%);">+ movb    (%esi), %dl</span><br><span style="color: hsl(120, 100%, 40%);">+   addb    %dl, %al</span><br><span style="color: hsl(120, 100%, 40%);">+      inc     %esi</span><br><span style="color: hsl(120, 100%, 40%);">+  dec     %ecx</span><br><span style="color: hsl(120, 100%, 40%);">+  jnz     1b</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        cmp       $0, %al</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        jne  end_microcode_update</span><br><span style="color: hsl(120, 100%, 40%);">+        </span><br><span style="color: hsl(120, 100%, 40%);">+        mov     $CONFIG_CPU_INTEL_NUM_FIT_ENTRIES, %ecx</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%);">+ * The microcode header is 24 bytes wide and has the following</span><br><span style="color: hsl(120, 100%, 40%);">+ * structure:</span><br><span style="color: hsl(120, 100%, 40%);">+ *   Header Version      : 32bit</span><br><span style="color: hsl(120, 100%, 40%);">+ *   Update Revision     : 32bit</span><br><span style="color: hsl(120, 100%, 40%);">+ *   Date                : 32bit </span><br><span style="color: hsl(120, 100%, 40%);">+ *   Processor Signature : 32bit</span><br><span style="color: hsl(120, 100%, 40%);">+ *   Checksum            : 32bit</span><br><span style="color: hsl(120, 100%, 40%);">+ *   Loader Revision     : 32bit</span><br><span style="color: hsl(120, 100%, 40%);">+ *   Processor Flags     : 32bit</span><br><span style="color: hsl(120, 100%, 40%);">+ *   Data Size           : 32bit</span><br><span style="color: hsl(120, 100%, 40%);">+ *   Total Size          : 32bit</span><br><span style="color: hsl(120, 100%, 40%);">+ *   Reserved            : 96bit</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * We only check if the Processor signature and flags match and check</span><br><span style="color: hsl(120, 100%, 40%);">+ * if the revision of the update is newer than what is installed</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%);">+check_microcode_entry:</span><br><span style="color: hsl(120, 100%, 40%);">+        /* Save %ecx for loop, we need it for wrmsr */</span><br><span style="color: hsl(120, 100%, 40%);">+        movl     %ecx, %ebp</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        /* Go to the next FIT entry */</span><br><span style="color: hsl(120, 100%, 40%);">+        add       $16, %edi</span><br><span style="color: hsl(120, 100%, 40%);">+        /* empty entry */</span><br><span style="color: hsl(120, 100%, 40%);">+        cmpl      $0, (%edi)</span><br><span style="color: hsl(120, 100%, 40%);">+        je  end_microcode_update</span><br><span style="color: hsl(120, 100%, 40%);">+        /* Check fit entry for microcode type */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        cmpb  $0x01, 14(%edi)</span><br><span style="color: hsl(120, 100%, 40%);">+        jne    end_microcode_update</span><br><span style="color: hsl(120, 100%, 40%);">+        </span><br><span style="color: hsl(120, 100%, 40%);">+        /* ESI holds the microcode pointer */</span><br><span style="color: hsl(120, 100%, 40%);">+        movl     0(%edi), %esi</span><br><span style="color: hsl(120, 100%, 40%);">+        </span><br><span style="color: hsl(120, 100%, 40%);">+        /* Processor family+model signature=cpuid_eax(1) */</span><br><span style="color: hsl(120, 100%, 40%);">+        movl      $1, %eax</span><br><span style="color: hsl(120, 100%, 40%);">+        cpuid</span><br><span style="color: hsl(120, 100%, 40%);">+        cmpl   12(%esi), %eax</span><br><span style="color: hsl(120, 100%, 40%);">+        jne     next_entry</span><br><span style="color: hsl(120, 100%, 40%);">+        </span><br><span style="color: hsl(120, 100%, 40%);">+        /* Processor flags</span><br><span style="color: hsl(120, 100%, 40%);">+           rdmsr 0x17</span><br><span style="color: hsl(120, 100%, 40%);">+           pf = 1 << ((msr.hi >> 18) & 7) */</span><br><span style="color: hsl(120, 100%, 40%);">+        movl     $0x17, %ecx</span><br><span style="color: hsl(120, 100%, 40%);">+        rdmsr</span><br><span style="color: hsl(120, 100%, 40%);">+        shr $18, %edx</span><br><span style="color: hsl(120, 100%, 40%);">+        andl $7, %edx</span><br><span style="color: hsl(120, 100%, 40%);">+        movl  $1, %eax</span><br><span style="color: hsl(120, 100%, 40%);">+        /* needs to be %cl for shl */</span><br><span style="color: hsl(120, 100%, 40%);">+        mov    %edx, %ecx</span><br><span style="color: hsl(120, 100%, 40%);">+        shl %cl, %eax</span><br><span style="color: hsl(120, 100%, 40%);">+        cmpl %eax, 24(%esi)</span><br><span style="color: hsl(120, 100%, 40%);">+        jnz     next_entry</span><br><span style="color: hsl(120, 100%, 40%);">+        </span><br><span style="color: hsl(120, 100%, 40%);">+        /* Check if revision is higher than current */</span><br><span style="color: hsl(120, 100%, 40%);">+        movl      $0x8b, %ecx</span><br><span style="color: hsl(120, 100%, 40%);">+        rdmsr</span><br><span style="color: hsl(120, 100%, 40%);">+        cmpl        4(%esi), %edx</span><br><span style="color: hsl(120, 100%, 40%);">+        /* Don't upgrade if already greater or equal */</span><br><span style="color: hsl(120, 100%, 40%);">+        jge end_microcode_update</span><br><span style="color: hsl(120, 100%, 40%);">+        </span><br><span style="color: hsl(120, 100%, 40%);">+        /* do actual update */</span><br><span style="color: hsl(120, 100%, 40%);">+        mov     %esi, %eax</span><br><span style="color: hsl(120, 100%, 40%);">+        add $48, %eax</span><br><span style="color: hsl(120, 100%, 40%);">+        xorl %edx, %edx</span><br><span style="color: hsl(120, 100%, 40%);">+        movl        $0x79, %ecx</span><br><span style="color: hsl(120, 100%, 40%);">+        wrmsr</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        jmp       end_microcode_update</span><br><span style="color: hsl(120, 100%, 40%);">+        </span><br><span style="color: hsl(120, 100%, 40%);">+next_entry:</span><br><span style="color: hsl(120, 100%, 40%);">+        movl       %ebp, %ecx</span><br><span style="color: hsl(120, 100%, 40%);">+        dec %ecx</span><br><span style="color: hsl(120, 100%, 40%);">+        jnz       check_microcode_entry</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%);">+end_microcode_update:</span><br><span style="color: hsl(120, 100%, 40%);">+     jmp      setup_car</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+_update_bsp_microcode_end:</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+fit_header:</span><br><span style="color: hsl(120, 100%, 40%);">+       .ascii "_FIT_   "</span><br><span>diff --git a/src/cpu/intel/socket_LGA775/Kconfig b/src/cpu/intel/socket_LGA775/Kconfig</span><br><span>index 9fec0d2..98d73d0 100644</span><br><span>--- a/src/cpu/intel/socket_LGA775/Kconfig</span><br><span>+++ b/src/cpu/intel/socket_LGA775/Kconfig</span><br><span>@@ -14,6 +14,11 @@</span><br><span>    select MMX</span><br><span>   select SSE</span><br><span>   select SIPI_VECTOR_IN_ROM</span><br><span style="color: hsl(120, 100%, 40%);">+     select CPU_INTEL_FIRMWARE_INTERFACE_TABLE</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+config CPU_INTEL_NUM_FIT_ENTRIES</span><br><span style="color: hsl(120, 100%, 40%);">+ int</span><br><span style="color: hsl(120, 100%, 40%);">+   default 45</span><br><span> </span><br><span> config DCACHE_RAM_SIZE</span><br><span>     hex</span><br><span>diff --git a/src/cpu/intel/socket_LGA775/Makefile.inc b/src/cpu/intel/socket_LGA775/Makefile.inc</span><br><span>index a37a1ca..34afb74 100644</span><br><span>--- a/src/cpu/intel/socket_LGA775/Makefile.inc</span><br><span>+++ b/src/cpu/intel/socket_LGA775/Makefile.inc</span><br><span>@@ -16,6 +16,7 @@</span><br><span> ifneq ($(CONFIG_C_ENVIRONMENT_BOOTBLOCK),y)</span><br><span> cpu_incs-y += $(src)/cpu/intel/car/p4-netburst/cache_as_ram.S</span><br><span> else</span><br><span style="color: hsl(120, 100%, 40%);">+bootblock-y += ../microcode/microcode.S</span><br><span> bootblock-y += ../car/p4-netburst/cache_as_ram_bootblock.S</span><br><span> bootblock-y += ../car/bootblock.c</span><br><span> endif</span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/27091">change 27091</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/27091"/><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: I8bd192f3f345651db0010239f99293ae63b00652 </div>
<div style="display:none"> Gerrit-Change-Number: 27091 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Arthur Heymans <arthur@aheymans.xyz> </div>