soc/mediatek/mt8196: Initialize SSPM
[coreboot2.git] / src / drivers / intel / fsp1_1 / cache_as_ram.S
blobc8eae7fdc15caf0898efbfb8c6926d8b48d5427c
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <cpu/x86/mtrr.h>
4 #include <cpu/x86/cache.h>
5 #include <cpu/x86/post_code.h>
7 /*
8  * Replacement for cache_as_ram.inc when using the FSP binary.  This code
9  * locates the FSP binary, initializes the cache as RAM and performs the
10  * first stage of initialization.  Next this code switches the stack from
11  * the cache to RAM and then disables the cache as RAM.  Finally this code
12  * performs the final stage of initialization.
13  */
15 #define LHLT_DELAY      0x50000 /* I/O delay between post codes on failure */
17 .section .init, "ax", @progbits
19 .global bootblock_pre_c_entry
20 bootblock_pre_c_entry:
21         /*
22          * Per FSP1.1 specs, following registers are preserved:
23          * EBX, EDI, ESI, EBP, MM0, MM1
24          *
25          * Shift values to release MM2.
26          * mm0 -> ebx:  BIST value
27          * mm1 -> mm0:  low 32-bits of TSC value
28          * mm2 -> mm1:  high 32-bits of TSC value
29          */
30         movd    %mm0, %ebx
31         movd    %mm1, %eax
32         movd    %eax, %mm0
33         movd    %mm2, %eax
34         movd    %eax, %mm1
36 cache_as_ram:
37         post_code(POSTCODE_BOOTBLOCK_CAR)
39         /* Cache the rom and update the microcode */
40 cache_rom:
41         /* Disable cache */
42         movl    %cr0, %eax
43         orl     $CR0_CacheDisable, %eax
44         movl    %eax, %cr0
46         movl    $MTRR_PHYS_BASE(1), %ecx
47         xorl    %edx, %edx
48         movl    $(CACHE_ROM_BASE | MTRR_TYPE_WRPROT), %eax
49         wrmsr
51         movl    $MTRR_PHYS_MASK(1), %ecx
52         rdmsr
53         movl    $(~(CACHE_ROM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
54         wrmsr
56         /* Enable cache */
57         movl    %cr0, %eax
58         andl    $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
59         invd
60         movl    %eax, %cr0
62         /* Enable MTRR. */
63         movl    $MTRR_DEF_TYPE_MSR, %ecx
64         rdmsr
65         orl     $MTRR_DEF_TYPE_EN, %eax
66         wrmsr
68         /* The Google FSP release for Braswell has broken microcode update
69            code and FSP needs the installed microcode revision to be non zero.
70            It is better to have coreboot do it instead of relying on a fragile
71            blob. */
72 update_microcode:
73         /* put the return address in %esp */
74         movl    $end_microcode_update, %esp
75         jmp     update_bsp_microcode
76 end_microcode_update:
78         /*
79          * Find the FSP binary in cbfs.
80          * Make a fake stack that has the return value back to this code.
81          */
82         lea     fake_fsp_stack, %esp
83         jmp     find_fsp
84 find_fsp_ret:
85         /* Save the FSP location */
86         mov     %eax, %ebp
88         /*
89          * Only when a valid FSP binary is found at CONFIG_FSP_LOC is
90          * the returned FSP_INFO_HEADER structure address above the base
91          * address of FSP binary specified by the CONFIG_FSP_LOC value.
92          * All of the error values are in the 0x8xxxxxxx range which are
93          * below the CONFIG_FSP_LOC value.
94          */
95         cmp     $CONFIG_FSP_LOC, %eax
96         jbe     halt1
98         post_code(POSTCODE_FSP_TEMP_RAM_INIT)
100         /* Calculate entry into FSP */
101         mov     0x30(%ebp), %eax        /* Load TempRamInitEntry */
102         add     0x1c(%ebp), %eax        /* add in the offset for FSP */
104         /*
105          * Pass early init variables on a fake stack (no memory yet)
106          * as well as the return location
107          */
108         lea     CAR_init_stack, %esp
110         /*
111          *       BIST value is zero
112          * eax:  TempRamInitApi address
113          * ebx:  BIST value
114          * ebp:  FSP_INFO_HEADER address
115          * esi:  Not used
116          * mm0:  low 32-bits of TSC value
117          * mm1:  high 32-bits of TSC value
118          */
120         /* call FSP binary to setup temporary stack */
121         jmp     *%eax
123 CAR_init_done:
125         /*
126          * ebp:  FSP_INFO_HEADER address
127          * ebx:  BIST value
128          * ecx:  Temp RAM base
129          * edx:  Temp RAM top
130          * mm0:  low 32-bits of TSC value
131          * mm1:  high 32-bits of TSC value
132          */
134         cmp     $0, %eax
135         jne     halt2
137         /* Setup bootblock stack */
138         movl    $_ecar_stack, %esp
140         /*
141          * ebp:  FSP_INFO_HEADER address
142          * ebx:  BIST value
143          * ecx:  Temp RAM base
144          * edx:  Temp RAM top
145          * esp:  Top of stack in temp RAM
146          * mm0:  low 32-bits of TSC value
147          * mm1:  high 32-bits of TSC value
148          */
150         /*
151          * temp_memory_start/end reside in the .bss section, which gets cleared
152          * below. Save the FSP return value to the stack before writing those
153          * variables.
154          */
155         push    %ecx
156         push    %edx
158         /* clear .bss section */
159         cld
160         xor     %eax, %eax
161         movl    $(_ebss), %ecx
162         movl    $(_bss), %edi
163         sub     %edi, %ecx
164         shrl    $2, %ecx
165         rep     stosl
167         pop     %edx
168         movl    %edx, temp_memory_end
169         pop     %ecx
170         movl    %ecx, temp_memory_start
172         /* Need to align stack to 16 bytes at call instruction. Account for
173         the pushes below. */
174         andl    $0xfffffff0, %esp
175         subl    $8, %esp
177         /* Push initial timestamp on the stack */
178         movd    %mm1, %eax
179         pushl   %eax    /* tsc[63:32] */
180         movd    %mm0, %eax
181         pushl   %eax    /* tsc[31:0] */
183         /* Copy .data section content to Cache-As-Ram */
184 #include <cpu/x86/copy_data_section.inc>
186 before_romstage:
187         /* Call bootblock_c_entry(uint64_t base_timestamp) */
188         call    bootblock_c_entry
190         /* Never reached */
192 halt1:
193         /*
194          * Failures for postcode 0xBA - failed in fsp_fih_early_find()
195          *
196          * Values are:
197          * 0x01 - FV signature, "_FVH" not present
198          * 0x02 - FFS GUID not present
199          * 0x03 - FSP INFO Header not found
200          * 0x04 - ImageBase does not equal CONFIG_FSP_LOC - Is the FSP rebased
201          *        to a different location, or does it need to be?
202          * 0x05 - FSP INFO Header signature "FSPH" not found
203          * 0x06 - FSP Image ID is not the expected ID.
204          */
205         movb    $0xBA, %ah
206         jmp     .Lhlt
208 halt2:
209         /*
210          * Failures for postcode 0xBB - failed in the FSP:
211          *
212          * 0x00 - FSP_SUCCESS: Temp RAM was initialized successfully.
213          * 0x02 - FSP_INVALID_PARAMETER: Input parameters are invalid.
214          * 0x03 - FSP_UNSUPPORTED: The FSP calling conditions were not met.
215          * 0x07 - FSP_DEVICE_ERROR: Temp RAM initialization failed
216          * 0x0E - FSP_NOT_FOUND: No valid microcode was found in the microcode
217          *        region.
218          * 0x14 - FSP_ALREADY_STARTED: Temp RAM initialization has been invoked
219          */
220         movb    $0xBB, %ah
221         jmp     .Lhlt
223 .Lhlt:
224         xchg    %al, %ah
225 #if CONFIG(POST_IO)
226         outb    %al, $CONFIG_POST_IO_PORT
227 #else
228         post_code(POSTCODE_DEAD_CODE)
229 #endif
230         movl    $LHLT_DELAY, %ecx
231 .Lhlt_Delay:
232         outb    %al, $0xED
233         loop    .Lhlt_Delay
234         jmp     .Lhlt
237  * esp is set to this location so that the call into and return from the FSP
238  * in find_fsp will work.
239  */
240         .align 4
241 fake_fsp_stack:
242         .long   find_fsp_ret
243         .long   CONFIG_FSP_LOC          /* FSP base address */
245 CAR_init_params:
246         .long   fake_microcode                          /* Microcode Location */
247         .long   fake_microcode_end - fake_microcode     /* Microcode Length */
248         .long   0xFFFFFFFF - CONFIG_ROM_SIZE + 1        /* Firmware Location */
249         .long   CONFIG_ROM_SIZE                         /* Firmware Length */
251 CAR_init_stack:
252         .long   CAR_init_done
253         .long   CAR_init_params
255         /* coreboot updates microcode itself. FSP still needs a pointer
256            to something that looks like microcode, so provide it with fake
257            microcode. */
258 fake_microcode:
259 fake_microcode_header_start:
260         .long   1               /* Header Version */
261         .long   1               /* Microcode revision */
262         .long   0x10232019      /* Date: Time of writing 23-10-2019 */
263         .long   0x00010ff0      /* Sig: (non existing) Family: 0xf, Model: 0x1f, stepping: 0 */
264         .long   0               /* Checksum: not checked by FSP, so won't care */
265         .long   1               /* Loader Revision */
266         .long   1               /* Processor Flags */
267         .long   fake_microcode_end - fake_microcode_header_end  /* Data Size */
268         .long   fake_microcode_end - fake_microcode     /* Total Size */
269         .space  12              /* Reserved */
270 fake_microcode_header_end:
271         .space 0x10     /* 16 bytes of empty data */
272 fake_microcode_end: