mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-21 22:51:37 +00:00
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
6 changed files with 323 additions and 3 deletions
|
@ -34,6 +34,22 @@ config TARGET_CHROMEBOOK_LINK
|
||||||
|
|
||||||
endchoice
|
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
|
config ROM_SIZE
|
||||||
hex
|
hex
|
||||||
default 0x800000
|
default 0x800000
|
||||||
|
|
|
@ -12,9 +12,167 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <common.h>
|
#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
|
.globl car_init
|
||||||
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
|
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 <common.h>
|
||||||
#include <asm/cpu.h>
|
#include <asm/cpu.h>
|
||||||
|
#include <asm/post.h>
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
|
|
||||||
DECLARE_GLOBAL_DATA_PTR;
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
@ -20,6 +21,7 @@ int arch_cpu_init(void)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
post_code(POST_CPU_INIT);
|
||||||
timer_set_base(rdtsc());
|
timer_set_base(rdtsc());
|
||||||
|
|
||||||
ret = x86_cpu_init_f();
|
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 */
|
/* post codes which represent various stages of init */
|
||||||
#define POST_START 0x1e
|
#define POST_START 0x1e
|
||||||
#define POST_CAR_START 0x1f
|
#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_STACK 0x29
|
||||||
#define POST_START_DONE 0x2a
|
#define POST_START_DONE 0x2a
|
||||||
|
#define POST_CPU_INIT 0x2b
|
||||||
|
|
||||||
/* Output a post code using al - value must be 0 to 0xff */
|
/* Output a post code using al - value must be 0 to 0xff */
|
||||||
#ifdef __ASSEMBLY__
|
#ifdef __ASSEMBLY__
|
||||||
|
@ -23,6 +32,8 @@
|
||||||
movb $value, %al; \
|
movb $value, %al; \
|
||||||
outb %al, $POST_PORT
|
outb %al, $POST_PORT
|
||||||
#else
|
#else
|
||||||
|
#include <asm/io.h>
|
||||||
|
|
||||||
static inline void post_code(int code)
|
static inline void post_code(int code)
|
||||||
{
|
{
|
||||||
outb(code, POST_PORT);
|
outb(code, POST_PORT);
|
||||||
|
|
|
@ -12,6 +12,18 @@ config SYS_SOC
|
||||||
config SYS_CONFIG_NAME
|
config SYS_CONFIG_NAME
|
||||||
default "chromebook_link"
|
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
|
config EARLY_POST_CROS_EC
|
||||||
bool "Enable early post to Chrome OS EC"
|
bool "Enable early post to Chrome OS EC"
|
||||||
default y
|
default y
|
||||||
|
|
Loading…
Add table
Reference in a new issue