Merge branch 'master' of git://git.denx.de/u-boot-mpc85xx
[oweals/u-boot.git] / arch / x86 / cpu / ivybridge / car.S
1 /*
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>
15 #include <asm/mtrr.h>
16 #include <asm/post.h>
17 #include <asm/processor-flags.h>
18
19 #define MTRR_PHYS_BASE_MSR(reg) (0x200 + 2 * (reg))
20 #define MTRR_PHYS_MASK_MSR(reg) (0x200 + 2 * (reg) + 1)
21
22 #define CACHE_AS_RAM_SIZE       CONFIG_DCACHE_RAM_SIZE
23 #define CACHE_AS_RAM_BASE       CONFIG_DCACHE_RAM_BASE
24
25 /* Cache 4GB - MRC_SIZE_KB for MRC */
26 #define CACHE_MRC_BYTES ((CONFIG_CACHE_MRC_SIZE_KB << 10) - 1)
27 #define CACHE_MRC_BASE          (0xFFFFFFFF - CACHE_MRC_BYTES)
28 #define CACHE_MRC_MASK          (~CACHE_MRC_BYTES)
29
30 #define CPU_PHYSMASK_HI (1 << (CONFIG_CPU_ADDR_BITS - 32) - 1)
31
32 #define NOEVICTMOD_MSR  0x2e0
33
34         /*
35          * Note: ebp must not be touched in this code as it holds the BIST
36          * value (built-in self test). We preserve this value until it can
37          * be written to global_data when CAR is ready for use.
38          */
39 .globl car_init
40 car_init:
41         post_code(POST_CAR_START)
42
43         /* Send INIT IPI to all excluding ourself */
44         movl    $0x000C4500, %eax
45         movl    $0xFEE00300, %esi
46         movl    %eax, (%esi)
47
48         post_code(POST_CAR_SIPI)
49         /* Zero out all fixed range and variable range MTRRs */
50         movl    $mtrr_table, %esi
51         movl    $((mtrr_table_end - mtrr_table) / 2), %edi
52         xorl    %eax, %eax
53         xorl    %edx, %edx
54 clear_mtrrs:
55         movw    (%esi), %bx
56         movzx   %bx, %ecx
57         wrmsr
58         add     $2, %esi
59         dec     %edi
60         jnz     clear_mtrrs
61
62         post_code(POST_CAR_MTRR)
63         /* Configure the default memory type to uncacheable */
64         movl    $MTRRdefType_MSR, %ecx
65         rdmsr
66         andl    $(~0x00000cff), %eax
67         wrmsr
68
69         post_code(POST_CAR_UNCACHEABLE)
70         /* Set Cache-as-RAM base address */
71         movl    $(MTRR_PHYS_BASE_MSR(0)), %ecx
72         movl    $(CACHE_AS_RAM_BASE | MTRR_TYPE_WRBACK), %eax
73         xorl    %edx, %edx
74         wrmsr
75
76         post_code(POST_CAR_BASE_ADDRESS)
77         /* Set Cache-as-RAM mask */
78         movl    $(MTRR_PHYS_MASK_MSR(0)), %ecx
79         movl    $(~(CACHE_AS_RAM_SIZE - 1) | MTRRphysMaskValid), %eax
80         movl    $CPU_PHYSMASK_HI, %edx
81         wrmsr
82
83         post_code(POST_CAR_MASK)
84
85         /* Enable MTRR */
86         movl    $MTRRdefType_MSR, %ecx
87         rdmsr
88         orl     $MTRRdefTypeEn, %eax
89         wrmsr
90
91         /* Enable cache (CR0.CD = 0, CR0.NW = 0) */
92         movl    %cr0, %eax
93         andl    $(~(X86_CR0_CD | X86_CR0_NW)), %eax
94         invd
95         movl    %eax, %cr0
96
97         /* enable the 'no eviction' mode */
98         movl    $NOEVICTMOD_MSR, %ecx
99         rdmsr
100         orl     $1, %eax
101         andl    $~2, %eax
102         wrmsr
103
104        /* Clear the cache memory region. This will also fill up the cache */
105         movl    $CACHE_AS_RAM_BASE, %esi
106         movl    %esi, %edi
107         movl    $(CACHE_AS_RAM_SIZE / 4), %ecx
108         xorl    %eax, %eax
109         rep     stosl
110
111         /* enable the 'no eviction run' state */
112         movl    $NOEVICTMOD_MSR, %ecx
113         rdmsr
114         orl     $3, %eax
115         wrmsr
116
117         post_code(POST_CAR_FILL)
118         /* Enable Cache-as-RAM mode by disabling cache */
119         movl    %cr0, %eax
120         orl     $X86_CR0_CD, %eax
121         movl    %eax, %cr0
122
123         /* Enable cache for our code in Flash because we do XIP here */
124         movl    $MTRR_PHYS_BASE_MSR(1), %ecx
125         xorl    %edx, %edx
126         movl    $car_init_ret, %eax
127         andl    $(~(CONFIG_XIP_ROM_SIZE - 1)), %eax
128         orl     $MTRR_TYPE_WRPROT, %eax
129         wrmsr
130
131         movl    $MTRR_PHYS_MASK_MSR(1), %ecx
132         movl    $CPU_PHYSMASK_HI, %edx
133         movl    $(~(CONFIG_XIP_ROM_SIZE - 1) | MTRRphysMaskValid), %eax
134         wrmsr
135
136         post_code(POST_CAR_ROM_CACHE)
137 #ifdef CONFIG_CACHE_MRC_BIN
138         /* Enable caching for ram init code to run faster */
139         movl    $MTRR_PHYS_BASE_MSR(2), %ecx
140         movl    $(CACHE_MRC_BASE | MTRR_TYPE_WRPROT), %eax
141         xorl    %edx, %edx
142         wrmsr
143         movl    $MTRR_PHYS_MASK_MSR(2), %ecx
144         movl    $(CACHE_MRC_MASK | MTRRphysMaskValid), %eax
145         movl    $CPU_PHYSMASK_HI, %edx
146         wrmsr
147 #endif
148
149         post_code(POST_CAR_MRC_CACHE)
150         /* Enable cache */
151         movl    %cr0, %eax
152         andl    $(~(X86_CR0_CD | X86_CR0_NW)), %eax
153         movl    %eax, %cr0
154
155         post_code(POST_CAR_CPU_CACHE)
156
157         /* All CPUs need to be in Wait for SIPI state */
158 wait_for_sipi:
159         movl    (%esi), %eax
160         bt      $12, %eax
161         jc      wait_for_sipi
162
163         /* return */
164         jmp     car_init_ret
165
166 mtrr_table:
167         /* Fixed MTRRs */
168         .word 0x250, 0x258, 0x259
169         .word 0x268, 0x269, 0x26A
170         .word 0x26B, 0x26C, 0x26D
171         .word 0x26E, 0x26F
172         /* Variable MTRRs */
173         .word 0x200, 0x201, 0x202, 0x203
174         .word 0x204, 0x205, 0x206, 0x207
175         .word 0x208, 0x209, 0x20A, 0x20B
176         .word 0x20C, 0x20D, 0x20E, 0x20F
177         .word 0x210, 0x211, 0x212, 0x213
178 mtrr_table_end: