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