blob: 6e0db96c0162bcd8440efa10ed3bc5657b45e981 [file] [log] [blame]
Simon Glass0b36ecd2014-11-12 22:42:07 -07001/*
2 * Copyright (c) 2014 Google, Inc
3 *
4 * From Coreboot file cpu/intel/model_206ax/cache_as_ram.inc
5 *
6 * Copyright (C) 2000,2007 Ronald G. Minnich <rminnich@gmail.com>
7 * Copyright (C) 2005 Tyan (written by Yinghai Lu for Tyan)
8 * Copyright (C) 2007-2008 coresystems GmbH
9 * Copyright (C) 2012 Kyösti Mälkki <kyosti.malkki@gmail.com>
10 *
11 * SPDX-License-Identifier: GPL-2.0
12 */
13
14#include <common.h>
Simon Glass2df61882016-03-11 22:06:54 -070015#include <asm/microcode.h>
Simon Glass9281eb52015-01-01 16:18:14 -070016#include <asm/msr-index.h>
Simon Glass98f139b2014-11-12 22:42:10 -070017#include <asm/mtrr.h>
18#include <asm/post.h>
Simon Glassa9a44262015-04-29 22:25:59 -060019#include <asm/processor.h>
Simon Glass98f139b2014-11-12 22:42:10 -070020#include <asm/processor-flags.h>
Simon Glass0b36ecd2014-11-12 22:42:07 -070021
Simon Glass98f139b2014-11-12 22:42:10 -070022#define MTRR_PHYS_BASE_MSR(reg) (0x200 + 2 * (reg))
23#define MTRR_PHYS_MASK_MSR(reg) (0x200 + 2 * (reg) + 1)
24
25#define CACHE_AS_RAM_SIZE CONFIG_DCACHE_RAM_SIZE
26#define CACHE_AS_RAM_BASE CONFIG_DCACHE_RAM_BASE
27
28/* Cache 4GB - MRC_SIZE_KB for MRC */
29#define CACHE_MRC_BYTES ((CONFIG_CACHE_MRC_SIZE_KB << 10) - 1)
30#define CACHE_MRC_BASE (0xFFFFFFFF - CACHE_MRC_BYTES)
31#define CACHE_MRC_MASK (~CACHE_MRC_BYTES)
32
33#define CPU_PHYSMASK_HI (1 << (CONFIG_CPU_ADDR_BITS - 32) - 1)
34
35#define NOEVICTMOD_MSR 0x2e0
36
37 /*
38 * Note: ebp must not be touched in this code as it holds the BIST
39 * value (built-in self test). We preserve this value until it can
40 * be written to global_data when CAR is ready for use.
41 */
Simon Glass0b36ecd2014-11-12 22:42:07 -070042.globl car_init
43car_init:
Simon Glass98f139b2014-11-12 22:42:10 -070044 post_code(POST_CAR_START)
45
46 /* Send INIT IPI to all excluding ourself */
47 movl $0x000C4500, %eax
48 movl $0xFEE00300, %esi
49 movl %eax, (%esi)
50
Simon Glass9281eb52015-01-01 16:18:14 -070051 /* TODO: Load microcode later - the 'no eviction' mode breaks this */
52 movl $MSR_IA32_UCODE_WRITE, %ecx
53 xorl %edx, %edx
54 movl $_dt_ucode_base_size, %eax
55 movl (%eax), %eax
56 addl $UCODE_HEADER_LEN, %eax
57 wrmsr
58
Simon Glass98f139b2014-11-12 22:42:10 -070059 post_code(POST_CAR_SIPI)
60 /* Zero out all fixed range and variable range MTRRs */
61 movl $mtrr_table, %esi
62 movl $((mtrr_table_end - mtrr_table) / 2), %edi
63 xorl %eax, %eax
64 xorl %edx, %edx
65clear_mtrrs:
66 movw (%esi), %bx
67 movzx %bx, %ecx
68 wrmsr
69 add $2, %esi
70 dec %edi
71 jnz clear_mtrrs
72
73 post_code(POST_CAR_MTRR)
74 /* Configure the default memory type to uncacheable */
Simon Glass7bf5b9e2015-01-01 16:18:07 -070075 movl $MTRR_DEF_TYPE_MSR, %ecx
Simon Glass98f139b2014-11-12 22:42:10 -070076 rdmsr
77 andl $(~0x00000cff), %eax
78 wrmsr
79
80 post_code(POST_CAR_UNCACHEABLE)
81 /* Set Cache-as-RAM base address */
82 movl $(MTRR_PHYS_BASE_MSR(0)), %ecx
83 movl $(CACHE_AS_RAM_BASE | MTRR_TYPE_WRBACK), %eax
84 xorl %edx, %edx
85 wrmsr
86
87 post_code(POST_CAR_BASE_ADDRESS)
88 /* Set Cache-as-RAM mask */
89 movl $(MTRR_PHYS_MASK_MSR(0)), %ecx
Simon Glass7bf5b9e2015-01-01 16:18:07 -070090 movl $(~(CACHE_AS_RAM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
Simon Glass98f139b2014-11-12 22:42:10 -070091 movl $CPU_PHYSMASK_HI, %edx
92 wrmsr
93
94 post_code(POST_CAR_MASK)
95
96 /* Enable MTRR */
Simon Glass7bf5b9e2015-01-01 16:18:07 -070097 movl $MTRR_DEF_TYPE_MSR, %ecx
Simon Glass98f139b2014-11-12 22:42:10 -070098 rdmsr
Simon Glass7bf5b9e2015-01-01 16:18:07 -070099 orl $MTRR_DEF_TYPE_EN, %eax
Simon Glass98f139b2014-11-12 22:42:10 -0700100 wrmsr
101
102 /* Enable cache (CR0.CD = 0, CR0.NW = 0) */
103 movl %cr0, %eax
104 andl $(~(X86_CR0_CD | X86_CR0_NW)), %eax
105 invd
106 movl %eax, %cr0
107
108 /* enable the 'no eviction' mode */
109 movl $NOEVICTMOD_MSR, %ecx
110 rdmsr
111 orl $1, %eax
112 andl $~2, %eax
113 wrmsr
114
115 /* Clear the cache memory region. This will also fill up the cache */
116 movl $CACHE_AS_RAM_BASE, %esi
117 movl %esi, %edi
118 movl $(CACHE_AS_RAM_SIZE / 4), %ecx
119 xorl %eax, %eax
120 rep stosl
121
122 /* enable the 'no eviction run' state */
123 movl $NOEVICTMOD_MSR, %ecx
124 rdmsr
125 orl $3, %eax
126 wrmsr
127
128 post_code(POST_CAR_FILL)
129 /* Enable Cache-as-RAM mode by disabling cache */
130 movl %cr0, %eax
131 orl $X86_CR0_CD, %eax
132 movl %eax, %cr0
133
134 /* Enable cache for our code in Flash because we do XIP here */
135 movl $MTRR_PHYS_BASE_MSR(1), %ecx
136 xorl %edx, %edx
137 movl $car_init_ret, %eax
138 andl $(~(CONFIG_XIP_ROM_SIZE - 1)), %eax
139 orl $MTRR_TYPE_WRPROT, %eax
140 wrmsr
141
142 movl $MTRR_PHYS_MASK_MSR(1), %ecx
143 movl $CPU_PHYSMASK_HI, %edx
Simon Glass7bf5b9e2015-01-01 16:18:07 -0700144 movl $(~(CONFIG_XIP_ROM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
Simon Glass98f139b2014-11-12 22:42:10 -0700145 wrmsr
146
147 post_code(POST_CAR_ROM_CACHE)
148#ifdef CONFIG_CACHE_MRC_BIN
149 /* Enable caching for ram init code to run faster */
150 movl $MTRR_PHYS_BASE_MSR(2), %ecx
151 movl $(CACHE_MRC_BASE | MTRR_TYPE_WRPROT), %eax
152 xorl %edx, %edx
153 wrmsr
154 movl $MTRR_PHYS_MASK_MSR(2), %ecx
Simon Glass7bf5b9e2015-01-01 16:18:07 -0700155 movl $(CACHE_MRC_MASK | MTRR_PHYS_MASK_VALID), %eax
Simon Glass98f139b2014-11-12 22:42:10 -0700156 movl $CPU_PHYSMASK_HI, %edx
157 wrmsr
158#endif
159
160 post_code(POST_CAR_MRC_CACHE)
161 /* Enable cache */
162 movl %cr0, %eax
163 andl $(~(X86_CR0_CD | X86_CR0_NW)), %eax
164 movl %eax, %cr0
165
166 post_code(POST_CAR_CPU_CACHE)
167
168 /* All CPUs need to be in Wait for SIPI state */
169wait_for_sipi:
170 movl (%esi), %eax
171 bt $12, %eax
172 jc wait_for_sipi
173
174 /* return */
Simon Glass0b36ecd2014-11-12 22:42:07 -0700175 jmp car_init_ret
Simon Glass98f139b2014-11-12 22:42:10 -0700176
Simon Glasse5911012015-01-01 16:18:12 -0700177.globl car_uninit
178car_uninit:
179 /* Disable cache */
180 movl %cr0, %eax
181 orl $X86_CR0_CD, %eax
182 movl %eax, %cr0
183
184 /* Disable MTRRs */
185 movl $MTRR_DEF_TYPE_MSR, %ecx
186 rdmsr
187 andl $(~MTRR_DEF_TYPE_EN), %eax
188 wrmsr
189
190 /* Disable the no-eviction run state */
Simon Glass5d129802015-10-18 15:55:35 -0600191 movl $NOEVICTMOD_MSR, %ecx
Simon Glasse5911012015-01-01 16:18:12 -0700192 rdmsr
193 andl $~2, %eax
194 wrmsr
195
196 invd
197
198 /* Disable the no-eviction mode */
199 rdmsr
200 andl $~1, %eax
201 wrmsr
202
203#ifdef CONFIG_CACHE_MRC_BIN
204 /* Clear the MTRR that was used to cache MRC */
205 xorl %eax, %eax
206 xorl %edx, %edx
207 movl $MTRR_PHYS_BASE_MSR(2), %ecx
208 wrmsr
209 movl $MTRR_PHYS_MASK_MSR(2), %ecx
210 wrmsr
211#endif
212
213 /* Enable MTRRs */
214 movl $MTRR_DEF_TYPE_MSR, %ecx
215 rdmsr
216 orl $MTRR_DEF_TYPE_EN, %eax
217 wrmsr
218
219 invd
220
221 ret
222
Simon Glass98f139b2014-11-12 22:42:10 -0700223mtrr_table:
224 /* Fixed MTRRs */
225 .word 0x250, 0x258, 0x259
226 .word 0x268, 0x269, 0x26A
227 .word 0x26B, 0x26C, 0x26D
228 .word 0x26E, 0x26F
229 /* Variable MTRRs */
230 .word 0x200, 0x201, 0x202, 0x203
231 .word 0x204, 0x205, 0x206, 0x207
232 .word 0x208, 0x209, 0x20A, 0x20B
233 .word 0x20C, 0x20D, 0x20E, 0x20F
234 .word 0x210, 0x211, 0x212, 0x213
235mtrr_table_end:
Simon Glass9281eb52015-01-01 16:18:14 -0700236
237 .align 4
238_dt_ucode_base_size:
239 /* These next two fields are filled in by ifdtool */
Simon Glass8dda5872016-03-11 22:07:11 -0700240.globl ucode_base
241ucode_base: /* Declared in microcode.h */
Simon Glass9281eb52015-01-01 16:18:14 -0700242 .long 0 /* microcode base */
243 .long 0 /* microcode size */