x86: chromebook_link: Implement CAR support (cache as RAM)
Add support for CAR so that we have memory to use prior to DRAM init. On link there is a total of 128KB of CAR available, although some is used for the memory reference code. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
d1cd045982
commit
70a09c6c3d
@ -34,6 +34,22 @@ config TARGET_CHROMEBOOK_LINK
|
||||
|
||||
endchoice
|
||||
|
||||
config RAMBASE
|
||||
hex
|
||||
default 0x100000
|
||||
|
||||
config RAMTOP
|
||||
hex
|
||||
default 0x200000
|
||||
|
||||
config XIP_ROM_SIZE
|
||||
hex
|
||||
default 0x10000
|
||||
|
||||
config CPU_ADDR_BITS
|
||||
int
|
||||
default 36
|
||||
|
||||
config ROM_SIZE
|
||||
hex
|
||||
default 0x800000
|
||||
|
@ -12,9 +12,167 @@
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/mtrr.h>
|
||||
#include <asm/post.h>
|
||||
#include <asm/processor-flags.h>
|
||||
|
||||
/* Note: ebp must not be touched in this code */
|
||||
#define MTRR_PHYS_BASE_MSR(reg) (0x200 + 2 * (reg))
|
||||
#define MTRR_PHYS_MASK_MSR(reg) (0x200 + 2 * (reg) + 1)
|
||||
|
||||
#define CACHE_AS_RAM_SIZE CONFIG_DCACHE_RAM_SIZE
|
||||
#define CACHE_AS_RAM_BASE CONFIG_DCACHE_RAM_BASE
|
||||
|
||||
/* Cache 4GB - MRC_SIZE_KB for MRC */
|
||||
#define CACHE_MRC_BYTES ((CONFIG_CACHE_MRC_SIZE_KB << 10) - 1)
|
||||
#define CACHE_MRC_BASE (0xFFFFFFFF - CACHE_MRC_BYTES)
|
||||
#define CACHE_MRC_MASK (~CACHE_MRC_BYTES)
|
||||
|
||||
#define CPU_PHYSMASK_HI (1 << (CONFIG_CPU_ADDR_BITS - 32) - 1)
|
||||
|
||||
#define NOEVICTMOD_MSR 0x2e0
|
||||
|
||||
/*
|
||||
* Note: ebp must not be touched in this code as it holds the BIST
|
||||
* value (built-in self test). We preserve this value until it can
|
||||
* be written to global_data when CAR is ready for use.
|
||||
*/
|
||||
.globl car_init
|
||||
car_init:
|
||||
/* TODO: Add cache-as-RAM init here */
|
||||
post_code(POST_CAR_START)
|
||||
|
||||
/* Send INIT IPI to all excluding ourself */
|
||||
movl $0x000C4500, %eax
|
||||
movl $0xFEE00300, %esi
|
||||
movl %eax, (%esi)
|
||||
|
||||
post_code(POST_CAR_SIPI)
|
||||
/* Zero out all fixed range and variable range MTRRs */
|
||||
movl $mtrr_table, %esi
|
||||
movl $((mtrr_table_end - mtrr_table) / 2), %edi
|
||||
xorl %eax, %eax
|
||||
xorl %edx, %edx
|
||||
clear_mtrrs:
|
||||
movw (%esi), %bx
|
||||
movzx %bx, %ecx
|
||||
wrmsr
|
||||
add $2, %esi
|
||||
dec %edi
|
||||
jnz clear_mtrrs
|
||||
|
||||
post_code(POST_CAR_MTRR)
|
||||
/* Configure the default memory type to uncacheable */
|
||||
movl $MTRRdefType_MSR, %ecx
|
||||
rdmsr
|
||||
andl $(~0x00000cff), %eax
|
||||
wrmsr
|
||||
|
||||
post_code(POST_CAR_UNCACHEABLE)
|
||||
/* Set Cache-as-RAM base address */
|
||||
movl $(MTRR_PHYS_BASE_MSR(0)), %ecx
|
||||
movl $(CACHE_AS_RAM_BASE | MTRR_TYPE_WRBACK), %eax
|
||||
xorl %edx, %edx
|
||||
wrmsr
|
||||
|
||||
post_code(POST_CAR_BASE_ADDRESS)
|
||||
/* Set Cache-as-RAM mask */
|
||||
movl $(MTRR_PHYS_MASK_MSR(0)), %ecx
|
||||
movl $(~(CACHE_AS_RAM_SIZE - 1) | MTRRphysMaskValid), %eax
|
||||
movl $CPU_PHYSMASK_HI, %edx
|
||||
wrmsr
|
||||
|
||||
post_code(POST_CAR_MASK)
|
||||
|
||||
/* Enable MTRR */
|
||||
movl $MTRRdefType_MSR, %ecx
|
||||
rdmsr
|
||||
orl $MTRRdefTypeEn, %eax
|
||||
wrmsr
|
||||
|
||||
/* Enable cache (CR0.CD = 0, CR0.NW = 0) */
|
||||
movl %cr0, %eax
|
||||
andl $(~(X86_CR0_CD | X86_CR0_NW)), %eax
|
||||
invd
|
||||
movl %eax, %cr0
|
||||
|
||||
/* enable the 'no eviction' mode */
|
||||
movl $NOEVICTMOD_MSR, %ecx
|
||||
rdmsr
|
||||
orl $1, %eax
|
||||
andl $~2, %eax
|
||||
wrmsr
|
||||
|
||||
/* Clear the cache memory region. This will also fill up the cache */
|
||||
movl $CACHE_AS_RAM_BASE, %esi
|
||||
movl %esi, %edi
|
||||
movl $(CACHE_AS_RAM_SIZE / 4), %ecx
|
||||
xorl %eax, %eax
|
||||
rep stosl
|
||||
|
||||
/* enable the 'no eviction run' state */
|
||||
movl $NOEVICTMOD_MSR, %ecx
|
||||
rdmsr
|
||||
orl $3, %eax
|
||||
wrmsr
|
||||
|
||||
post_code(POST_CAR_FILL)
|
||||
/* Enable Cache-as-RAM mode by disabling cache */
|
||||
movl %cr0, %eax
|
||||
orl $X86_CR0_CD, %eax
|
||||
movl %eax, %cr0
|
||||
|
||||
/* Enable cache for our code in Flash because we do XIP here */
|
||||
movl $MTRR_PHYS_BASE_MSR(1), %ecx
|
||||
xorl %edx, %edx
|
||||
movl $car_init_ret, %eax
|
||||
andl $(~(CONFIG_XIP_ROM_SIZE - 1)), %eax
|
||||
orl $MTRR_TYPE_WRPROT, %eax
|
||||
wrmsr
|
||||
|
||||
movl $MTRR_PHYS_MASK_MSR(1), %ecx
|
||||
movl $CPU_PHYSMASK_HI, %edx
|
||||
movl $(~(CONFIG_XIP_ROM_SIZE - 1) | MTRRphysMaskValid), %eax
|
||||
wrmsr
|
||||
|
||||
post_code(POST_CAR_ROM_CACHE)
|
||||
#ifdef CONFIG_CACHE_MRC_BIN
|
||||
/* Enable caching for ram init code to run faster */
|
||||
movl $MTRR_PHYS_BASE_MSR(2), %ecx
|
||||
movl $(CACHE_MRC_BASE | MTRR_TYPE_WRPROT), %eax
|
||||
xorl %edx, %edx
|
||||
wrmsr
|
||||
movl $MTRR_PHYS_MASK_MSR(2), %ecx
|
||||
movl $(CACHE_MRC_MASK | MTRRphysMaskValid), %eax
|
||||
movl $CPU_PHYSMASK_HI, %edx
|
||||
wrmsr
|
||||
#endif
|
||||
|
||||
post_code(POST_CAR_MRC_CACHE)
|
||||
/* Enable cache */
|
||||
movl %cr0, %eax
|
||||
andl $(~(X86_CR0_CD | X86_CR0_NW)), %eax
|
||||
movl %eax, %cr0
|
||||
|
||||
post_code(POST_CAR_CPU_CACHE)
|
||||
|
||||
/* All CPUs need to be in Wait for SIPI state */
|
||||
wait_for_sipi:
|
||||
movl (%esi), %eax
|
||||
bt $12, %eax
|
||||
jc wait_for_sipi
|
||||
|
||||
/* return */
|
||||
jmp car_init_ret
|
||||
|
||||
mtrr_table:
|
||||
/* Fixed MTRRs */
|
||||
.word 0x250, 0x258, 0x259
|
||||
.word 0x268, 0x269, 0x26A
|
||||
.word 0x26B, 0x26C, 0x26D
|
||||
.word 0x26E, 0x26F
|
||||
/* Variable MTRRs */
|
||||
.word 0x200, 0x201, 0x202, 0x203
|
||||
.word 0x204, 0x205, 0x206, 0x207
|
||||
.word 0x208, 0x209, 0x20A, 0x20B
|
||||
.word 0x20C, 0x20D, 0x20E, 0x20F
|
||||
.word 0x210, 0x211, 0x212, 0x213
|
||||
mtrr_table_end:
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/post.h>
|
||||
#include <asm/processor.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
@ -20,6 +21,7 @@ int arch_cpu_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
post_code(POST_CPU_INIT);
|
||||
timer_set_base(rdtsc());
|
||||
|
||||
ret = x86_cpu_init_f();
|
||||
|
121
arch/x86/include/asm/mtrr.h
Normal file
121
arch/x86/include/asm/mtrr.h
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Google, Inc
|
||||
*
|
||||
* From Coreboot file of the same name
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef _ASM_MTRR_H
|
||||
#define _ASM_MTRR_H
|
||||
|
||||
/* These are the region types */
|
||||
#define MTRR_TYPE_UNCACHEABLE 0
|
||||
#define MTRR_TYPE_WRCOMB 1
|
||||
/*#define MTRR_TYPE_ 2*/
|
||||
/*#define MTRR_TYPE_ 3*/
|
||||
#define MTRR_TYPE_WRTHROUGH 4
|
||||
#define MTRR_TYPE_WRPROT 5
|
||||
#define MTRR_TYPE_WRBACK 6
|
||||
#define MTRR_NUM_TYPES 7
|
||||
|
||||
#define MTRRcap_MSR 0x0fe
|
||||
#define MTRRdefType_MSR 0x2ff
|
||||
|
||||
#define MTRRdefTypeEn (1 << 11)
|
||||
#define MTRRdefTypeFixEn (1 << 10)
|
||||
|
||||
#define SMRRphysBase_MSR 0x1f2
|
||||
#define SMRRphysMask_MSR 0x1f3
|
||||
|
||||
#define MTRRphysBase_MSR(reg) (0x200 + 2 * (reg))
|
||||
#define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1)
|
||||
|
||||
#define MTRRphysMaskValid (1 << 11)
|
||||
|
||||
#define NUM_FIXED_RANGES 88
|
||||
#define RANGES_PER_FIXED_MTRR 8
|
||||
#define MTRRfix64K_00000_MSR 0x250
|
||||
#define MTRRfix16K_80000_MSR 0x258
|
||||
#define MTRRfix16K_A0000_MSR 0x259
|
||||
#define MTRRfix4K_C0000_MSR 0x268
|
||||
#define MTRRfix4K_C8000_MSR 0x269
|
||||
#define MTRRfix4K_D0000_MSR 0x26a
|
||||
#define MTRRfix4K_D8000_MSR 0x26b
|
||||
#define MTRRfix4K_E0000_MSR 0x26c
|
||||
#define MTRRfix4K_E8000_MSR 0x26d
|
||||
#define MTRRfix4K_F0000_MSR 0x26e
|
||||
#define MTRRfix4K_F8000_MSR 0x26f
|
||||
|
||||
#if !defined(__ASSEMBLER__)
|
||||
|
||||
/*
|
||||
* The MTRR code has some side effects that the callers should be aware for.
|
||||
* 1. The call sequence matters. x86_setup_mtrrs() calls
|
||||
* x86_setup_fixed_mtrrs_no_enable() then enable_fixed_mtrrs() (equivalent
|
||||
* of x86_setup_fixed_mtrrs()) then x86_setup_var_mtrrs(). If the callers
|
||||
* want to call the components of x86_setup_mtrrs() because of other
|
||||
* rquirements the ordering should still preserved.
|
||||
* 2. enable_fixed_mtrr() will enable both variable and fixed MTRRs because
|
||||
* of the nature of the global MTRR enable flag. Therefore, all direct
|
||||
* or indirect callers of enable_fixed_mtrr() should ensure that the
|
||||
* variable MTRR MSRs do not contain bad ranges.
|
||||
* 3. If CONFIG_CACHE_ROM is selected an MTRR is allocated for enabling
|
||||
* the caching of the ROM. However, it is set to uncacheable (UC). It
|
||||
* is the responsiblity of the caller to enable it by calling
|
||||
* x86_mtrr_enable_rom_caching().
|
||||
*/
|
||||
void x86_setup_mtrrs(void);
|
||||
/*
|
||||
* x86_setup_var_mtrrs() parameters:
|
||||
* address_bits - number of physical address bits supported by cpu
|
||||
* above4gb - 2 means dynamically detect number of variable MTRRs available.
|
||||
* non-zero means handle memory ranges above 4GiB.
|
||||
* 0 means ignore memory ranges above 4GiB
|
||||
*/
|
||||
void x86_setup_var_mtrrs(unsigned int address_bits, unsigned int above4gb);
|
||||
void enable_fixed_mtrr(void);
|
||||
void x86_setup_fixed_mtrrs(void);
|
||||
/* Set up fixed MTRRs but do not enable them. */
|
||||
void x86_setup_fixed_mtrrs_no_enable(void);
|
||||
int x86_mtrr_check(void);
|
||||
/* ROM caching can be used after variable MTRRs are set up. Beware that
|
||||
* enabling CONFIG_CACHE_ROM will eat through quite a few MTRRs based on
|
||||
* one's IO hole size and WRCOMB resources. Be sure to check the console
|
||||
* log when enabling CONFIG_CACHE_ROM or adding WRCOMB resources. Beware that
|
||||
* on CPUs with core-scoped MTRR registers such as hyperthreaded CPUs the
|
||||
* rom caching will be disabled if all threads run the MTRR code. Therefore,
|
||||
* one needs to call x86_mtrr_enable_rom_caching() after all threads of the
|
||||
* same core have run the MTRR code. */
|
||||
#if CONFIG_CACHE_ROM
|
||||
void x86_mtrr_enable_rom_caching(void);
|
||||
void x86_mtrr_disable_rom_caching(void);
|
||||
/* Return the variable range MTRR index of the ROM cache. */
|
||||
long x86_mtrr_rom_cache_var_index(void);
|
||||
#else
|
||||
static inline void x86_mtrr_enable_rom_caching(void) {}
|
||||
static inline void x86_mtrr_disable_rom_caching(void) {}
|
||||
static inline long x86_mtrr_rom_cache_var_index(void) { return -1; }
|
||||
#endif /* CONFIG_CACHE_ROM */
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_RAMTOP)
|
||||
# error "CONFIG_RAMTOP not defined"
|
||||
#endif
|
||||
|
||||
#if ((CONFIG_XIP_ROM_SIZE & (CONFIG_XIP_ROM_SIZE - 1)) != 0)
|
||||
# error "CONFIG_XIP_ROM_SIZE is not a power of 2"
|
||||
#endif
|
||||
|
||||
#if ((CONFIG_CACHE_ROM_SIZE & (CONFIG_CACHE_ROM_SIZE - 1)) != 0)
|
||||
# error "CONFIG_CACHE_ROM_SIZE is not a power of 2"
|
||||
#endif
|
||||
|
||||
#define CACHE_ROM_BASE (((1 << 20) - (CONFIG_CACHE_ROM_SIZE >> 12)) << 12)
|
||||
|
||||
#if (CONFIG_RAMTOP & (CONFIG_RAMTOP - 1)) != 0
|
||||
# error "CONFIG_RAMTOP must be a power of 2"
|
||||
#endif
|
||||
|
||||
#endif
|
@ -13,9 +13,18 @@
|
||||
/* post codes which represent various stages of init */
|
||||
#define POST_START 0x1e
|
||||
#define POST_CAR_START 0x1f
|
||||
|
||||
#define POST_CAR_SIPI 0x20
|
||||
#define POST_CAR_MTRR 0x21
|
||||
#define POST_CAR_UNCACHEABLE 0x22
|
||||
#define POST_CAR_BASE_ADDRESS 0x23
|
||||
#define POST_CAR_MASK 0x24
|
||||
#define POST_CAR_FILL 0x25
|
||||
#define POST_CAR_ROM_CACHE 0x26
|
||||
#define POST_CAR_MRC_CACHE 0x27
|
||||
#define POST_CAR_CPU_CACHE 0x28
|
||||
#define POST_START_STACK 0x29
|
||||
#define POST_START_DONE 0x2a
|
||||
#define POST_CPU_INIT 0x2b
|
||||
|
||||
/* Output a post code using al - value must be 0 to 0xff */
|
||||
#ifdef __ASSEMBLY__
|
||||
@ -23,6 +32,8 @@
|
||||
movb $value, %al; \
|
||||
outb %al, $POST_PORT
|
||||
#else
|
||||
#include <asm/io.h>
|
||||
|
||||
static inline void post_code(int code)
|
||||
{
|
||||
outb(code, POST_PORT);
|
||||
|
@ -12,6 +12,18 @@ config SYS_SOC
|
||||
config SYS_CONFIG_NAME
|
||||
default "chromebook_link"
|
||||
|
||||
config BOARD_SPECIFIC_OPTIONS # dummy
|
||||
def_bool y
|
||||
select CPU_INTEL_SOCKET_RPGA989
|
||||
select NORTHBRIDGE_INTEL_IVYBRIDGE
|
||||
select SOUTHBRIDGE_INTEL_C216
|
||||
select HAVE_ACPI_RESUME
|
||||
select MARK_GRAPHICS_MEM_WRCOMB
|
||||
|
||||
config MMCONF_BASE_ADDRESS
|
||||
hex
|
||||
default 0xf0000000
|
||||
|
||||
config EARLY_POST_CROS_EC
|
||||
bool "Enable early post to Chrome OS EC"
|
||||
default y
|
||||
|
Loading…
Reference in New Issue
Block a user