183d290c5STom Rini/* SPDX-License-Identifier: GPL-2.0 */ 21223d737SSimon Glass/* 31223d737SSimon Glass * Copyright (c) 2014 Google, Inc 41223d737SSimon Glass * 51223d737SSimon Glass * From Coreboot file cpu/intel/model_206ax/cache_as_ram.inc 61223d737SSimon Glass * 71223d737SSimon Glass * Copyright (C) 2000,2007 Ronald G. Minnich <rminnich@gmail.com> 81223d737SSimon Glass * Copyright (C) 2005 Tyan (written by Yinghai Lu for Tyan) 91223d737SSimon Glass * Copyright (C) 2007-2008 coresystems GmbH 101223d737SSimon Glass * Copyright (C) 2012 Kyösti Mälkki <kyosti.malkki@gmail.com> 111223d737SSimon Glass */ 121223d737SSimon Glass 131223d737SSimon Glass#include <common.h> 149e66506dSSimon Glass#include <asm/microcode.h> 151223d737SSimon Glass#include <asm/msr-index.h> 161223d737SSimon Glass#include <asm/mtrr.h> 171223d737SSimon Glass#include <asm/post.h> 181223d737SSimon Glass#include <asm/processor.h> 191223d737SSimon Glass#include <asm/processor-flags.h> 201223d737SSimon Glass 211223d737SSimon Glass#define MTRR_PHYS_BASE_MSR(reg) (0x200 + 2 * (reg)) 221223d737SSimon Glass#define MTRR_PHYS_MASK_MSR(reg) (0x200 + 2 * (reg) + 1) 231223d737SSimon Glass 241223d737SSimon Glass#define CACHE_AS_RAM_SIZE CONFIG_DCACHE_RAM_SIZE 251223d737SSimon Glass#define CACHE_AS_RAM_BASE CONFIG_DCACHE_RAM_BASE 261223d737SSimon Glass 271223d737SSimon Glass/* Cache 4GB - MRC_SIZE_KB for MRC */ 281223d737SSimon Glass#define CACHE_MRC_BYTES ((CONFIG_CACHE_MRC_SIZE_KB << 10) - 1) 291223d737SSimon Glass#define CACHE_MRC_BASE (0xFFFFFFFF - CACHE_MRC_BYTES) 301223d737SSimon Glass#define CACHE_MRC_MASK (~CACHE_MRC_BYTES) 311223d737SSimon Glass 321223d737SSimon Glass#define CPU_PHYSMASK_HI (1 << (CONFIG_CPU_ADDR_BITS - 32) - 1) 331223d737SSimon Glass 341223d737SSimon Glass#define NOEVICTMOD_MSR 0x2e0 351223d737SSimon Glass 361223d737SSimon Glass /* 371223d737SSimon Glass * Note: ebp must not be touched in this code as it holds the BIST 381223d737SSimon Glass * value (built-in self test). We preserve this value until it can 391223d737SSimon Glass * be written to global_data when CAR is ready for use. 401223d737SSimon Glass */ 411223d737SSimon Glass.globl car_init 421223d737SSimon Glasscar_init: 431223d737SSimon Glass post_code(POST_CAR_START) 441223d737SSimon Glass 451223d737SSimon Glass /* Send INIT IPI to all excluding ourself */ 461223d737SSimon Glass movl $0x000C4500, %eax 471223d737SSimon Glass movl $0xFEE00300, %esi 481223d737SSimon Glass movl %eax, (%esi) 491223d737SSimon Glass 501223d737SSimon Glass /* TODO: Load microcode later - the 'no eviction' mode breaks this */ 511223d737SSimon Glass movl $MSR_IA32_UCODE_WRITE, %ecx 521223d737SSimon Glass xorl %edx, %edx 531223d737SSimon Glass movl $_dt_ucode_base_size, %eax 541223d737SSimon Glass movl (%eax), %eax 551223d737SSimon Glass addl $UCODE_HEADER_LEN, %eax 561223d737SSimon Glass wrmsr 571223d737SSimon Glass 581223d737SSimon Glass post_code(POST_CAR_SIPI) 591223d737SSimon Glass /* Zero out all fixed range and variable range MTRRs */ 601223d737SSimon Glass movl $mtrr_table, %esi 611223d737SSimon Glass movl $((mtrr_table_end - mtrr_table) / 2), %edi 621223d737SSimon Glass xorl %eax, %eax 631223d737SSimon Glass xorl %edx, %edx 641223d737SSimon Glassclear_mtrrs: 651223d737SSimon Glass movw (%esi), %bx 661223d737SSimon Glass movzx %bx, %ecx 671223d737SSimon Glass wrmsr 681223d737SSimon Glass add $2, %esi 691223d737SSimon Glass dec %edi 701223d737SSimon Glass jnz clear_mtrrs 711223d737SSimon Glass 721223d737SSimon Glass post_code(POST_CAR_MTRR) 731223d737SSimon Glass /* Configure the default memory type to uncacheable */ 741223d737SSimon Glass movl $MTRR_DEF_TYPE_MSR, %ecx 751223d737SSimon Glass rdmsr 761223d737SSimon Glass andl $(~0x00000cff), %eax 771223d737SSimon Glass wrmsr 781223d737SSimon Glass 791223d737SSimon Glass post_code(POST_CAR_UNCACHEABLE) 801223d737SSimon Glass /* Set Cache-as-RAM base address */ 811223d737SSimon Glass movl $(MTRR_PHYS_BASE_MSR(0)), %ecx 821223d737SSimon Glass movl $(CACHE_AS_RAM_BASE | MTRR_TYPE_WRBACK), %eax 831223d737SSimon Glass xorl %edx, %edx 841223d737SSimon Glass wrmsr 851223d737SSimon Glass 861223d737SSimon Glass post_code(POST_CAR_BASE_ADDRESS) 871223d737SSimon Glass /* Set Cache-as-RAM mask */ 881223d737SSimon Glass movl $(MTRR_PHYS_MASK_MSR(0)), %ecx 891223d737SSimon Glass movl $(~(CACHE_AS_RAM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax 901223d737SSimon Glass movl $CPU_PHYSMASK_HI, %edx 911223d737SSimon Glass wrmsr 921223d737SSimon Glass 931223d737SSimon Glass post_code(POST_CAR_MASK) 941223d737SSimon Glass 951223d737SSimon Glass /* Enable MTRR */ 961223d737SSimon Glass movl $MTRR_DEF_TYPE_MSR, %ecx 971223d737SSimon Glass rdmsr 981223d737SSimon Glass orl $MTRR_DEF_TYPE_EN, %eax 991223d737SSimon Glass wrmsr 1001223d737SSimon Glass 1011223d737SSimon Glass /* Enable cache (CR0.CD = 0, CR0.NW = 0) */ 1021223d737SSimon Glass movl %cr0, %eax 1031223d737SSimon Glass andl $(~(X86_CR0_CD | X86_CR0_NW)), %eax 1041223d737SSimon Glass invd 1051223d737SSimon Glass movl %eax, %cr0 1061223d737SSimon Glass 1071223d737SSimon Glass /* enable the 'no eviction' mode */ 1081223d737SSimon Glass movl $NOEVICTMOD_MSR, %ecx 1091223d737SSimon Glass rdmsr 1101223d737SSimon Glass orl $1, %eax 1111223d737SSimon Glass andl $~2, %eax 1121223d737SSimon Glass wrmsr 1131223d737SSimon Glass 1141223d737SSimon Glass /* Clear the cache memory region. This will also fill up the cache */ 1151223d737SSimon Glass movl $CACHE_AS_RAM_BASE, %esi 1161223d737SSimon Glass movl %esi, %edi 1171223d737SSimon Glass movl $(CACHE_AS_RAM_SIZE / 4), %ecx 1181223d737SSimon Glass xorl %eax, %eax 1191223d737SSimon Glass rep stosl 1201223d737SSimon Glass 1211223d737SSimon Glass /* enable the 'no eviction run' state */ 1221223d737SSimon Glass movl $NOEVICTMOD_MSR, %ecx 1231223d737SSimon Glass rdmsr 1241223d737SSimon Glass orl $3, %eax 1251223d737SSimon Glass wrmsr 1261223d737SSimon Glass 1271223d737SSimon Glass post_code(POST_CAR_FILL) 1281223d737SSimon Glass /* Enable Cache-as-RAM mode by disabling cache */ 1291223d737SSimon Glass movl %cr0, %eax 1301223d737SSimon Glass orl $X86_CR0_CD, %eax 1311223d737SSimon Glass movl %eax, %cr0 1321223d737SSimon Glass 1331223d737SSimon Glass /* Enable cache for our code in Flash because we do XIP here */ 1341223d737SSimon Glass movl $MTRR_PHYS_BASE_MSR(1), %ecx 1351223d737SSimon Glass xorl %edx, %edx 1361223d737SSimon Glass movl $car_init_ret, %eax 1371223d737SSimon Glass andl $(~(CONFIG_XIP_ROM_SIZE - 1)), %eax 1381223d737SSimon Glass orl $MTRR_TYPE_WRPROT, %eax 1391223d737SSimon Glass wrmsr 1401223d737SSimon Glass 1411223d737SSimon Glass movl $MTRR_PHYS_MASK_MSR(1), %ecx 1421223d737SSimon Glass movl $CPU_PHYSMASK_HI, %edx 1431223d737SSimon Glass movl $(~(CONFIG_XIP_ROM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax 1441223d737SSimon Glass wrmsr 1451223d737SSimon Glass 1461223d737SSimon Glass post_code(POST_CAR_ROM_CACHE) 1471223d737SSimon Glass#ifdef CONFIG_CACHE_MRC_BIN 1481223d737SSimon Glass /* Enable caching for ram init code to run faster */ 1491223d737SSimon Glass movl $MTRR_PHYS_BASE_MSR(2), %ecx 1501223d737SSimon Glass movl $(CACHE_MRC_BASE | MTRR_TYPE_WRPROT), %eax 1511223d737SSimon Glass xorl %edx, %edx 1521223d737SSimon Glass wrmsr 1531223d737SSimon Glass movl $MTRR_PHYS_MASK_MSR(2), %ecx 1541223d737SSimon Glass movl $(CACHE_MRC_MASK | MTRR_PHYS_MASK_VALID), %eax 1551223d737SSimon Glass movl $CPU_PHYSMASK_HI, %edx 1561223d737SSimon Glass wrmsr 1571223d737SSimon Glass#endif 1581223d737SSimon Glass 1591223d737SSimon Glass post_code(POST_CAR_MRC_CACHE) 1601223d737SSimon Glass /* Enable cache */ 1611223d737SSimon Glass movl %cr0, %eax 1621223d737SSimon Glass andl $(~(X86_CR0_CD | X86_CR0_NW)), %eax 1631223d737SSimon Glass movl %eax, %cr0 1641223d737SSimon Glass 1651223d737SSimon Glass post_code(POST_CAR_CPU_CACHE) 1661223d737SSimon Glass 1671223d737SSimon Glass /* All CPUs need to be in Wait for SIPI state */ 1681223d737SSimon Glasswait_for_sipi: 1691223d737SSimon Glass movl (%esi), %eax 1701223d737SSimon Glass bt $12, %eax 1711223d737SSimon Glass jc wait_for_sipi 1721223d737SSimon Glass 1731223d737SSimon Glass /* return */ 1741223d737SSimon Glass jmp car_init_ret 1751223d737SSimon Glass 1761223d737SSimon Glass.globl car_uninit 1771223d737SSimon Glasscar_uninit: 1781223d737SSimon Glass /* Disable cache */ 1791223d737SSimon Glass movl %cr0, %eax 1801223d737SSimon Glass orl $X86_CR0_CD, %eax 1811223d737SSimon Glass movl %eax, %cr0 1821223d737SSimon Glass 1831223d737SSimon Glass /* Disable MTRRs */ 1841223d737SSimon Glass movl $MTRR_DEF_TYPE_MSR, %ecx 1851223d737SSimon Glass rdmsr 1861223d737SSimon Glass andl $(~MTRR_DEF_TYPE_EN), %eax 1871223d737SSimon Glass wrmsr 1881223d737SSimon Glass 1891223d737SSimon Glass /* Disable the no-eviction run state */ 1901223d737SSimon Glass movl $NOEVICTMOD_MSR, %ecx 1911223d737SSimon Glass rdmsr 1921223d737SSimon Glass andl $~2, %eax 1931223d737SSimon Glass wrmsr 1941223d737SSimon Glass 1951223d737SSimon Glass invd 1961223d737SSimon Glass 1971223d737SSimon Glass /* Disable the no-eviction mode */ 1981223d737SSimon Glass rdmsr 1991223d737SSimon Glass andl $~1, %eax 2001223d737SSimon Glass wrmsr 2011223d737SSimon Glass 2021223d737SSimon Glass#ifdef CONFIG_CACHE_MRC_BIN 2031223d737SSimon Glass /* Clear the MTRR that was used to cache MRC */ 2041223d737SSimon Glass xorl %eax, %eax 2051223d737SSimon Glass xorl %edx, %edx 2061223d737SSimon Glass movl $MTRR_PHYS_BASE_MSR(2), %ecx 2071223d737SSimon Glass wrmsr 2081223d737SSimon Glass movl $MTRR_PHYS_MASK_MSR(2), %ecx 2091223d737SSimon Glass wrmsr 2101223d737SSimon Glass#endif 2111223d737SSimon Glass 2121223d737SSimon Glass /* Enable MTRRs */ 2131223d737SSimon Glass movl $MTRR_DEF_TYPE_MSR, %ecx 2141223d737SSimon Glass rdmsr 2151223d737SSimon Glass orl $MTRR_DEF_TYPE_EN, %eax 2161223d737SSimon Glass wrmsr 2171223d737SSimon Glass 2181223d737SSimon Glass invd 2191223d737SSimon Glass 2201223d737SSimon Glass ret 2211223d737SSimon Glass 2221223d737SSimon Glassmtrr_table: 2231223d737SSimon Glass /* Fixed MTRRs */ 2241223d737SSimon Glass .word 0x250, 0x258, 0x259 2251223d737SSimon Glass .word 0x268, 0x269, 0x26A 2261223d737SSimon Glass .word 0x26B, 0x26C, 0x26D 2271223d737SSimon Glass .word 0x26E, 0x26F 2281223d737SSimon Glass /* Variable MTRRs */ 2291223d737SSimon Glass .word 0x200, 0x201, 0x202, 0x203 2301223d737SSimon Glass .word 0x204, 0x205, 0x206, 0x207 2311223d737SSimon Glass .word 0x208, 0x209, 0x20A, 0x20B 2321223d737SSimon Glass .word 0x20C, 0x20D, 0x20E, 0x20F 2331223d737SSimon Glass .word 0x210, 0x211, 0x212, 0x213 2341223d737SSimon Glassmtrr_table_end: 2351223d737SSimon Glass 2361223d737SSimon Glass .align 4 2371223d737SSimon Glass_dt_ucode_base_size: 2381223d737SSimon Glass /* These next two fields are filled in by ifdtool */ 239e77b62e2SSimon Glass.globl ucode_base 240e77b62e2SSimon Glassucode_base: /* Declared in microcode.h */ 2411223d737SSimon Glass .long 0 /* microcode base */ 242*8199a145SIvan Gorinov.globl ucode_size 243*8199a145SIvan Gorinovucode_size: /* Declared in microcode.h */ 2441223d737SSimon Glass .long 0 /* microcode size */ 245