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