soc/intel/alderlake: Add ADL-P 4+4 with 28W TDP
[coreboot.git] / src / cpu / intel / microcode / microcode_asm.S
blob28705230a2a76b73e881348a105e49849ade184b
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 /*
4  * input %esp: return address (not pointer to return address!)
5  * clobber the content of eax, ebx, ecx, edx, esi, edi, and ebp
6  */
8 #include <cpu/x86/post_code.h>
9 #include <cpu/x86/msr.h>
11 #define CBFS_FILE_MAGIC 0
12 #define CBFS_FILE_LEN (CBFS_FILE_MAGIC + 8)
13 #define CBFS_FILE_TYPE (CBFS_FILE_LEN + 4)
14 #define CBFS_FILE_CHECKSUM (CBFS_FILE_TYPE + 4)
15 #define CBFS_FILE_OFFSET (CBFS_FILE_CHECKSUM + 4)
17 #define HEADER_VER_OFFSET 0
18 #define UPDATE_VER_OFFSET 4
19 #define DATE_OFFSET 8
20 #define PROCESSOR_SIG_OFFSET 12
21 #define CHKSUM_OFFSET 16
22 #define LOADER_REV_OFFSET 20
23 #define PROCESSOR_FLAG 24
24 #define DATA_SIZE_OFFSET 28
25 #define TOTAL_OFFSET 32
26 #define HEADER_SIZE 48
29  * The microcode header is 48 bytes wide and has the following
30  * structure:
31  *   Header Version      : 32bit
32  *   Update Revision     : 32bit
33  *   Date                : 32bit
34  *   Processor Signature : 32bit
35  *   Checksum            : 32bit
36  *   Loader Revision     : 32bit
37  *   Processor Flags     : 32bit
38  *   Data Size           : 32bit
39  *   Total Size          : 32bit
40  *   Reserved            : 96bit
41  *
42  * We only check if the Processor signature and flags match and check
43  * if the revision of the update is newer than what is installed
44  */
46 .code32
47 .section .init
48 .global update_bsp_microcode
50 update_bsp_microcode:
51         /* Keep return address */
52         movl    %esp, %edx
53         /* find microcodes in cbfs */
54         leal    microcode_name, %esi
55         movl    $1f, %esp
56         jmp     walkcbfs_asm
59         /* restore return address */
60         movl    %edx, %esp
62         cmpl    $0, %eax
63         je      end_microcode_update
64         movl    CBFS_FILE_OFFSET(%eax), %ebx
65         bswap   %ebx
66         addl    %eax, %ebx
67         movl    %ebx, %esi
69         movl    CBFS_FILE_LEN(%eax), %edi
70         bswap   %edi
71         addl    %esi, %edi
73         /*
74          * Microcode revision -> %ebx
75          * Processor flags -> %ebp
76          * Current installed microcode revision -> %edx
77          */
79         /* Processor flags
80          * rdmsr 0x17
81          * pf = 1 << ((msr.hi >> 18) & 7) */
82         movl    $IA32_PLATFORM_ID, %ecx
83         rdmsr
84         shr     $18, %edx
85         andl    $7, %edx
86         movl    $1, %eax
87         /* needs to be %cl for shl */
88         movl    %edx, %ecx
89         shl     %cl, %eax
90         movl    %eax, %ebp
92         /* Fetch the current microcode revision*/
93         xorl    %eax, %eax
94         xorl    %edx, %edx
95         movl    $IA32_BIOS_SIGN_ID, %ecx
96         wrmsr
97         movl    $0x1, %eax
98         cpuid
100         /* Processor family+model signature=cpuid_eax(1) */
101         movl    %eax, %ebx
103         movl    $IA32_BIOS_SIGN_ID, %ecx
104         rdmsr
106 check_microcode_entry:
107         /* Test if header revision is non zero */
108         cmpl    $0, HEADER_VER_OFFSET(%esi)
109         je      end_microcode_update
111         /* Processor family+model signature=cpuid_eax(1) */
112         cmpl    PROCESSOR_SIG_OFFSET(%esi), %ebx
113         jne     next_entry
115         /* Processor flags */
116         test    PROCESSOR_FLAG(%esi), %ebp
117         jz      next_entry
119         /* Check if revision is higher than current */
120         cmpl    UPDATE_VER_OFFSET(%esi), %edx
121         /* Don't upgrade if already greater or equal */
122         jge     end_microcode_update
124         /* Do actual update */
125         movl    %esi, %eax
126         addl    $HEADER_SIZE, %eax
127         xorl    %edx, %edx
128         movl    $IA32_BIOS_UPDT_TRIG, %ecx
129         wrmsr
131         jmp     end_microcode_update
133 next_entry:
134         movl    TOTAL_OFFSET(%esi), %eax
135         cmpl    $0, %eax
136         jne     1f
137         /* Newer microcode updates include a size field, whereas older
138          * containers set it at 0 and are exactly 2048 bytes long */
139         addl    $2048, %esi
140         jmp     check_end
142         addl    %eax, %esi
144 check_end:
145         cmpl    %esi, %edi
146         ja      check_microcode_entry
148 end_microcode_update:
149         jmp     *%esp
151 microcode_name:
152         .string "cpu_microcode_blob.bin"
154 _update_bsp_microcode_end: