blob: fae7899e17e2d0ce0caf5b69fe64bb2dc7c42766 [file] [log] [blame]
Patrick Georgi11f00792020-03-04 15:10:45 +01001/* SPDX-License-Identifier: GPL-2.0-only */
Aaron Durbin7f8afe02016-03-18 12:21:23 -05002
3#include <cpu/x86/mtrr.h>
4#include <cpu/x86/cr.h>
Arthur Heymansa6a2f932019-11-25 19:58:36 +01005#include <cpu/x86/cache.h>
Aaron Durbin7f8afe02016-03-18 12:21:23 -05006
7.section ".module_parameters", "aw", @progbits
8/* stack_top indicates the stack to pull MTRR information from. */
Brenton Dongc9b39812016-10-18 13:57:54 -07009.global post_car_stack_top
10post_car_stack_top:
Aaron Durbin7f8afe02016-03-18 12:21:23 -050011.long 0
12.long 0
13
Patrick Rudolph8daa12f2018-12-26 15:12:32 +010014#if defined(__x86_64__)
15.code64
16.macro pop_eax_edx
17 pop %rax
18 mov %rax, %rdx
19 shr $32, %rdx
20.endm
21.macro pop_ebx_esi
22 pop %rbx
23 mov %rbx, %rsi
24 shr $32, %rsi
25.endm
26#else
27.code32
28.macro pop_eax_edx
29 pop %eax
30 pop %edx
31.endm
32.macro pop_ebx_esi
33 pop %ebx
34 pop %esi
35.endm
36#endif
37
Aaron Durbin7f8afe02016-03-18 12:21:23 -050038.text
39.global _start
40_start:
Aaron Durbin028e18f2017-06-23 11:14:58 -050041 /* Assume stack alignment doesn't matter here as chipset_teardown_car
42 is expected to be implemented in assembly. */
43
Hannah Williamsd3c0c0c2018-04-27 09:09:04 -070044 /* Migrate GDT to this text segment */
Patrick Rudolph8daa12f2018-12-26 15:12:32 +010045#if defined(__x86_64__)
46 call gdt_init64
47#else
Hannah Williamsd3c0c0c2018-04-27 09:09:04 -070048 call gdt_init
Patrick Rudolph8daa12f2018-12-26 15:12:32 +010049#endif
Hannah Williamsd3c0c0c2018-04-27 09:09:04 -070050
Arthur Heymans7c9a0e82019-10-23 17:02:50 +020051#ifdef __x86_64__
52 mov %rdi, _cbmem_top_ptr
53#else
54 /* The return argument is at 0(%esp), the calling argument at 4(%esp) */
55 movl 4(%esp), %eax
56 movl %eax, _cbmem_top_ptr
57#endif
Arthur Heymansa6a2f932019-11-25 19:58:36 +010058 /* Make sure _cbmem_top_ptr hits dram before invd */
59 movl $1, %eax
60 cpuid
61 btl $CPUID_FEATURE_CLFLUSH_BIT, %edx
Arthur Heymans014c8892020-08-29 08:21:49 +020062 jnc skip_clflush
Arthur Heymansa6a2f932019-11-25 19:58:36 +010063 clflush _cbmem_top_ptr
Arthur Heymans7c9a0e82019-10-23 17:02:50 +020064
Arthur Heymansa6a2f932019-11-25 19:58:36 +010065skip_clflush:
Aaron Durbin7f8afe02016-03-18 12:21:23 -050066 /* chipset_teardown_car() is expected to disable cache-as-ram. */
67 call chipset_teardown_car
68
69 /* Enable caching if not already enabled. */
Patrick Rudolph8daa12f2018-12-26 15:12:32 +010070#ifdef __x86_64__
71 mov %cr0, %rax
72 and $(~(CR0_CD | CR0_NW)), %eax
73 mov %rax, %cr0
74#else
Aaron Durbin7f8afe02016-03-18 12:21:23 -050075 mov %cr0, %eax
76 and $(~(CR0_CD | CR0_NW)), %eax
77 mov %eax, %cr0
Patrick Rudolph8daa12f2018-12-26 15:12:32 +010078#endif
Aaron Durbin7f8afe02016-03-18 12:21:23 -050079 /* Ensure cache is clean. */
80 invd
81
82 /* Set up new stack. */
Brenton Dongc9b39812016-10-18 13:57:54 -070083 mov post_car_stack_top, %esp
Aaron Durbin7f8afe02016-03-18 12:21:23 -050084
85 /*
86 * Honor variable MTRR information pushed on the stack with the
87 * following layout:
88 *
89 * Offset: Value
90 * ...
91 * 0x14: MTRR mask 0 63:32
92 * 0x10: MTRR mask 0 31:0
93 * 0x0c: MTRR base 0 63:32
94 * 0x08: MTRR base 0 31:0
95 * 0x04: Number of variable MTRRs to set
96 * 0x00: Number of variable MTRRs to clear
97 */
98
Julius Wernercd49cce2019-03-05 16:53:33 -080099#if CONFIG(SOC_SETS_MSRS)
Aaron Durbin028e18f2017-06-23 11:14:58 -0500100
101 mov %esp, %ebp
102 /* Need to align stack to 16 bytes at the call instruction. Therefore
103 account for the 1 push. */
104 andl $0xfffffff0, %esp
Patrick Rudolph8daa12f2018-12-26 15:12:32 +0100105#if defined(__x86_64__)
106 mov %rbp, %rdi
107#else
Aaron Durbin028e18f2017-06-23 11:14:58 -0500108 sub $12, %esp
109 push %ebp
Patrick Rudolph8daa12f2018-12-26 15:12:32 +0100110#endif
111
Lee Leahy5f4b4c42016-07-24 08:09:40 -0700112 call soc_set_mtrrs
Aaron Durbin028e18f2017-06-23 11:14:58 -0500113 /* Ignore fixing up %esp since we're setting it a new value. */
Lee Leahy5f4b4c42016-07-24 08:09:40 -0700114
115 /* eax: new top_of_stack with setup_stack_and_mtrrs data removed */
116 movl %eax, %esp
Aaron Durbin028e18f2017-06-23 11:14:58 -0500117 /* Align stack to 16 bytes at call instruction. */
118 andl $0xfffffff0, %esp
Lee Leahy5f4b4c42016-07-24 08:09:40 -0700119 call soc_enable_mtrrs
120#else /* CONFIG_SOC_SETS_MSRS */
Aaron Durbin7f8afe02016-03-18 12:21:23 -0500121 /* Clear variable MTRRs. */
Patrick Rudolph8daa12f2018-12-26 15:12:32 +0100122 pop_ebx_esi /* ebx: Number to clear, esi: Number to set */
Aaron Durbin7f8afe02016-03-18 12:21:23 -0500123 test %ebx, %ebx
124 jz 2f
125 xor %eax, %eax
126 xor %edx, %edx
127 mov $(MTRR_PHYS_BASE(0)), %ecx
1281:
129 wrmsr
130 inc %ecx
131 wrmsr
132 inc %ecx
133 dec %ebx
134 jnz 1b
1352:
136
137 /* Set Variable MTRRs based on stack contents. */
Patrick Rudolph8daa12f2018-12-26 15:12:32 +0100138 test %esi, %esi
Aaron Durbin7f8afe02016-03-18 12:21:23 -0500139 jz 2f
140 mov $(MTRR_PHYS_BASE(0)), %ecx
1411:
142 /* Write MTRR base. */
Patrick Rudolph8daa12f2018-12-26 15:12:32 +0100143 pop_eax_edx
Aaron Durbin7f8afe02016-03-18 12:21:23 -0500144 wrmsr
145 inc %ecx
146 /* Write MTRR mask. */
Patrick Rudolph8daa12f2018-12-26 15:12:32 +0100147 pop_eax_edx
Aaron Durbin7f8afe02016-03-18 12:21:23 -0500148 wrmsr
149 inc %ecx
150
Patrick Rudolph8daa12f2018-12-26 15:12:32 +0100151 dec %esi
Aaron Durbin7f8afe02016-03-18 12:21:23 -0500152 jnz 1b
1532:
154
155 /* Enable MTRR. */
156 mov $(MTRR_DEF_TYPE_MSR), %ecx
157 rdmsr
158 /* Make default type uncacheable. */
159 and $(~(MTRR_DEF_TYPE_MASK)), %eax
160 or $(MTRR_DEF_TYPE_EN), %eax
161 wrmsr
Lee Leahy5f4b4c42016-07-24 08:09:40 -0700162#endif /* CONFIG_SOC_SETS_MSRS */
Aaron Durbin7f8afe02016-03-18 12:21:23 -0500163
Aaron Durbin028e18f2017-06-23 11:14:58 -0500164 /* Align stack to 16 bytes at call instruction. */
165 andl $0xfffffff0, %esp
Aaron Durbin6b0cebc2016-09-16 16:15:14 -0500166 /* Call into main for postcar. */
167 call main
Aaron Durbin7f8afe02016-03-18 12:21:23 -0500168 /* Should never return. */
1691:
170 jmp 1b