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/microcode.h> 16#include <asm/msr-index.h> 17#include <asm/mtrr.h> 18#include <asm/post.h> 19#include <asm/processor.h> 20#include <asm/processor-flags.h> 21 22#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 */ 42.globl car_init 43car_init: 44 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 51 /* 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 59 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 */ 75 movl $MTRR_DEF_TYPE_MSR, %ecx 76 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 90 movl $(~(CACHE_AS_RAM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax 91 movl $CPU_PHYSMASK_HI, %edx 92 wrmsr 93 94 post_code(POST_CAR_MASK) 95 96 /* Enable MTRR */ 97 movl $MTRR_DEF_TYPE_MSR, %ecx 98 rdmsr 99 orl $MTRR_DEF_TYPE_EN, %eax 100 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 144 movl $(~(CONFIG_XIP_ROM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax 145 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 155 movl $(CACHE_MRC_MASK | MTRR_PHYS_MASK_VALID), %eax 156 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 */ 175 jmp car_init_ret 176 177.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 */ 191 movl $NOEVICTMOD_MSR, %ecx 192 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 223mtrr_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: 236 237 .align 4 238_dt_ucode_base_size: 239 /* These next two fields are filled in by ifdtool */ 240.globl ucode_base 241ucode_base: /* Declared in microcode.h */ 242 .long 0 /* microcode base */ 243 .long 0 /* microcode size */ 244