Author: mjones
Date: 2009-02-10 23:40:10 +0100 (Tue, 10 Feb 2009)
New Revision: 1128
Modified:
coreboot-v3/arch/x86/amd/k8/stage1.c
coreboot-v3/arch/x86/amd/model_fxx/init_cpus.c
coreboot-v3/arch/x86/stage1_mtrr.c
coreboot-v3/include/arch/x86/amd/k8/k8.h
coreboot-v3/include/arch/x86/cpu.h
coreboot-v3/include/arch/x86/mtrr.h
Log:
Setup the MTRRs in stage1 so that memory and cache are available throughout
stage2. This fixes problems with VGA graphics ROMs access to 0xA0000-0xBFFFF.
It also sets all system memory to WriteBack cached and sets the ROM
area to cached.
Signed-off-by: Marc Jones <marcj303(a)gmail.com>
Acked-by: Peter Stuge <peter(a)stuge.se>
Modified: coreboot-v3/arch/x86/amd/k8/stage1.c
===================================================================
--- coreboot-v3/arch/x86/amd/k8/stage1.c 2009-02-10 22:35:49 UTC (rev 1127)
+++ coreboot-v3/arch/x86/amd/k8/stage1.c 2009-02-10 22:40:10 UTC (rev 1128)
@@ -2,6 +2,7 @@
* This file is part of the coreboot project.
*
* Copyright (C) 2007 Advanced Micro Devices, Inc.
+ * Copyright (C) 2009 Marc Jones <marcj303(a)gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,31 +30,136 @@
#include <stage1.h>
/**
- * Set the MTRR for initial ram access.
- * be warned, this will be used by core other than core 0/node 0 or core0/node0 when cpu_reset.
- * This warning has some significance I don't yet understand.
+ * Set the MTRRs of the current core for initial ram access.
+ * Be warned, this function is used by the BSP and all AP cores. TOM and TOM2
+ * of the calling core must be setup. This function may be called several times
+ * depending on MEM_TRAIN_SEQ.
*/
-void set_init_ram_access(void)
+void set_mtrr_ram_access(void)
{
- stage1_set_var_mtrr(0, 0x00000000, CONFIG_CBMEMK << 10, MTRR_TYPE_WRBACK);
+ struct msr msr;
+
+ disable_cache();
+
+ /* 0 - 640KB */
+ stage1_set_fix_mtrr(MTRRfix64K_00000_MSR,
+ MTRR_READ_MEM | MTRR_WRITE_MEM | MTRR_TYPE_WRBACK);
+ stage1_set_fix_mtrr(MTRRfix16K_80000_MSR,
+ MTRR_READ_MEM | MTRR_WRITE_MEM | MTRR_TYPE_WRBACK);
+
+ /* 0xA0000 - 0xC0000 (UC to video card) */
+ stage1_set_fix_mtrr(MTRRfix16K_A0000_MSR, MTRR_TYPE_UNCACHEABLE);
+
+ /* 0xC0000 - 1MB */
+ stage1_set_fix_mtrr(MTRRfix4K_C0000_MSR,
+ MTRR_READ_MEM | MTRR_WRITE_MEM | MTRR_TYPE_WRBACK);
+ stage1_set_fix_mtrr(MTRRfix4K_C8000_MSR,
+ MTRR_READ_MEM | MTRR_WRITE_MEM | MTRR_TYPE_WRBACK);
+ stage1_set_fix_mtrr(MTRRfix4K_D0000_MSR,
+ MTRR_READ_MEM | MTRR_WRITE_MEM | MTRR_TYPE_WRBACK);
+ stage1_set_fix_mtrr(MTRRfix4K_D8000_MSR,
+ MTRR_READ_MEM | MTRR_WRITE_MEM | MTRR_TYPE_WRBACK);
+ stage1_set_fix_mtrr(MTRRfix4K_E0000_MSR,
+ MTRR_READ_MEM | MTRR_WRITE_MEM | MTRR_TYPE_WRBACK);
+ stage1_set_fix_mtrr(MTRRfix4K_E8000_MSR,
+ MTRR_READ_MEM | MTRR_WRITE_MEM | MTRR_TYPE_WRBACK);
+ stage1_set_fix_mtrr(MTRRfix4K_F0000_MSR,
+ MTRR_READ_MEM | MTRR_WRITE_MEM | MTRR_TYPE_WRBACK);
+ stage1_set_fix_mtrr(MTRRfix4K_F8000_MSR,
+ MTRR_READ_MEM | MTRR_WRITE_MEM | MTRR_TYPE_WRBACK);
+
+ /* 1MB - TOM */
+ msr = rdmsr(TOP_MEM);
+ stage1_set_var_mtrr_x(0, 0x00100000, 0x0, msr.lo, msr.hi, MTRR_TYPE_WRBACK);
+
+ /* System ROM (Assume 1MB) */
+ stage1_set_var_mtrr(1, 0xFFFFFFFF - (u32)((CONFIG_COREBOOT_ROMSIZE_KB << 10) - 1),
+ CONFIG_COREBOOT_ROMSIZE_KB << 10, MTRR_TYPE_WRTHROUGH);
+
+ /* 4GB - TOM2 */
+ msr = rdmsr(SYSCFG_MSR);
+ if (msr.lo & SYSCFG_MSR_TOM2En) {
+ msr = rdmsr(TOP_MEM2);
+ stage1_set_var_mtrr_x(2, 0x0, 0x00000001, msr.lo, msr.hi,
+ MTRR_TYPE_WRBACK);
+ }
+
+ /* Enable Fixed and Variable MTRRs MSRs*/
+ msr = rdmsr(SYSCFG_MSR);
+ msr.lo |= (SYSCFG_MSR_MtrrVarDramEn | SYSCFG_MSR_MtrrFixDramEn);
+ wrmsr(SYSCFG_MSR, msr);
+
+ /* Enable Fixed and Variable MTRRs */
+ msr = rdmsr(MTRRdefType_MSR);
+ msr.lo |= 0xC00;
+ wrmsr(MTRRdefType_MSR, msr);
+
+ enable_cache();
}
+
+/* This function MUST be inlined as we can not use a stack -- CAR or real ram */
+/* By yhlu 6.2005 */
+/* Be warned, this function is used by both the BSP and APs to disable the
+ * fixed MTRRs used for CAR.
+ */
+inline __attribute__((always_inline)) void disable_cache_as_ram(void)
+{
+ __asm__ volatile (
+
+ /* Disable the cache while we change MTRRs */
+ " movl %cr0, %eax \n"
+ " orl $(0x1<<30),%eax \n"
+ " movl %eax, %cr0 \n"
+
+ /* clear sth */
+ " movl $0x269, %ecx \n" /* fix4k_c8000 */
+ " xorl %edx, %edx \n"
+ " xorl %eax, %eax \n"
+ " wrmsr\n\t"
+#if CONFIG_CARSIZE > 0x8000
+ " movl $0x268, %ecx \n" /* fix4k_c0000 */
+ " wrmsr \n"
+#endif
+ /* disable fixed mtrr for now, it will be enabled by coreboot_ram again*/
+ " movl $0xC0010010, %ecx \n" /*SYSCFG_MSR */
+ " rdmsr \n"
+ " andl $(~(3<<18)), %eax \n" /*~(MtrrFixDramModEn | MtrrFixDramEn) */
+ " wrmsr \n"
+
+ /* Set the default memory type to UC, disable fixed MTRRs,
+ * and leave variable MTRRs enabled */
+ " movl $0x2ff, %ecx \n" /* $MTRRdefType_MSR */
+ " xorl %edx, %edx \n"
+ " movl $0x00000800, %eax \n"
+ " wrmsr \n"
+
+ /* enable cache */
+ " movl %cr0, %eax \n"
+ " andl $0x9fffffff,%eax \n"
+ " movl %eax, %cr0 \n"
+ );
+}
+
+
/**
* Disable Cache As RAM (CAR) after memory is setup.
*
- * Unknown how to do this just yet.
*/
void disable_car(void)
{
- /* call the inlined function */
+ /* inlined function that disables the fixed MTRRs that
+ * are used for CAR stack space. The cache tags are still
+ * valid and the stack data is still in place. */
disable_cache_as_ram();
- /* The BKDG says that a WBINVD will not flush CAR to RAM (because the
+ /* Now we need to get the cached data to RAM.
+ * The BKDG says that a WBINVD will not flush CAR to RAM (because the
* cache tags are not dirty).
* Solution:
* - Two subsequent memcpy in the same inline asm block, one from stack
* to backup, one from backup to stack.
- * The solution for geode of using a inline asm memcpy of the stack
+ * The solution for Geode of using a inline asm memcpy of the stack
* onto itself will not mark the cache tags as dirty on K8.
*/
__asm__ __volatile__(
@@ -71,8 +177,10 @@
[carsizequads] "i" (CONFIG_CARSIZE/4)
: "memory", "%edi", "%esi", "%ecx");
banner(BIOS_DEBUG, "Disable_car: done wbinvd");
- /* we're now running in ram. Although this will be called again, it does no harm to call it here. */
- set_init_ram_access();
+
+ /* We're now running in ram.
+ * Setup the cache for normal operation. */
+ set_mtrr_ram_access();
banner(BIOS_DEBUG, "disable_car: done");
stage1_phase3();
}
Modified: coreboot-v3/arch/x86/amd/model_fxx/init_cpus.c
===================================================================
--- coreboot-v3/arch/x86/amd/model_fxx/init_cpus.c 2009-02-10 22:35:49 UTC (rev 1127)
+++ coreboot-v3/arch/x86/amd/model_fxx/init_cpus.c 2009-02-10 22:40:10 UTC (rev 1128)
@@ -246,28 +246,7 @@
}
}
-/**
- * disable cache as ram on a BSP.
- * For reasons not totally known we are saving ecx and edx.
- * That will work on k8 as we copy the stack and return in the same stack frame.
- */
-void disable_cache_as_ram_bsp(void)
-{
- __asm__ volatile (
-// "pushl %eax\n\t"
- "pushl %edx\n\t"
- "pushl %ecx\n\t"
- );
- disable_cache_as_ram();
- __asm__ volatile (
- "popl %ecx\n\t"
- "popl %edx\n\t"
-// "popl %eax\n\t"
- );
-}
-
-
/**
* wait for all apics to start. Make sure we don't wait on ourself.
* @param bsp_apicid The BSP APIC ID
@@ -291,7 +270,7 @@
void STOP_CAR_AND_CPU(void)
{
disable_cache_as_ram(); // inline
- stop_this_cpu(); // inline, it will stop all cores except node0/core0 the bsp ....
+ stop_this_cpu(); // inline
}
#ifndef MEM_TRAIN_SEQ
@@ -470,13 +449,18 @@
printk(BIOS_DEBUG, "while waiting for BSP signal to STOP, timeout in ap 0x%08x\n",
apicid);
}
+
/* indicate that we are in state 44 as well. We are catching up to the BSP. */
- // old comment follows -- not sure what this means yet.
- // bsp can not check it before stop_this_cpu
lapic_write(LAPIC_MSG_REG, (apicid << 24) | 0x44);
- /* Now set up so we can use RAM. This will be low memory, i.e. BSP memory, already working. */
- set_init_ram_access();
- /* this is not done on Serengeti. */
+
+ /* Now set up so we can use RAM.
+ * This will be low memory, i.e. BSP memory, already working.
+ */
+ /* Keep the ap's tom consistent with bsp's */
+ set_top_mem_ap(sysinfo->tom_k, sysinfo->tom2_k);
+ set_mtrr_ram_access();
+
+ /* This is not done on Serengeti. */
#if MEM_TRAIN_SEQ == 1
train_ram_on_node(id.nodeid, id.coreid, sysinfo,
(void *)STOP_CAR_AND_CPU);
Modified: coreboot-v3/arch/x86/stage1_mtrr.c
===================================================================
--- coreboot-v3/arch/x86/stage1_mtrr.c 2009-02-10 22:35:49 UTC (rev 1127)
+++ coreboot-v3/arch/x86/stage1_mtrr.c 2009-02-10 22:40:10 UTC (rev 1128)
@@ -40,25 +40,46 @@
wrmsr(MTRRphysMask_MSR(reg), maskm);
}
-void set_var_mtrr_x(
- unsigned long reg, u32 base_lo, u32 base_hi, u32 size_lo, u32 size_hi, unsigned long type)
+void stage1_set_var_mtrr_x(
+ unsigned long reg, u32 base_lo, u32 base_hi, u32 size_lo, u32 size_hi, unsigned long type)
{
- /* Bit Bit 32-35 of MTRRphysMask should be set to 1 */
- struct msr basem, maskm;
- basem.lo = (base_lo & 0xfffff000) | type;
- basem.hi = base_hi & ((1<<(CPU_ADDR_BITS-32))-1);
- wrmsr(MTRRphysBase_MSR(reg), basem);
- maskm.hi = (1<<(CPU_ADDR_BITS-32))-1;
+ /* Bit Bit 32-35 of MTRRphysMask should be set to 1 */
+ struct msr basem, maskm;
+ basem.lo = (base_lo & 0xfffff000) | type;
+ basem.hi = base_hi & ((1<<(CPU_ADDR_BITS-32))-1);
+ wrmsr(MTRRphysBase_MSR(reg), basem);
+ maskm.hi = (1<<(CPU_ADDR_BITS-32))-1;
if(size_lo) {
- maskm.lo = ~(size_lo - 1) | 0x800;
+ maskm.lo = ~(size_lo - 1) | 0x800;
} else {
maskm.lo = 0x800;
maskm.hi &= ~(size_hi - 1);
}
- wrmsr(MTRRphysMask_MSR(reg), maskm);
+ wrmsr(MTRRphysMask_MSR(reg), maskm);
}
+/* Sets the entire fixed mtrr to a cache type. */
+void stage1_set_fix_mtrr(u32 reg, u8 type)
+{
+ struct msr msr;
+
+ /* Enable Modify Extended RdMem and WrMem settings */
+ msr = rdmsr(SYSCFG_MSR);
+ msr.lo |= SYSCFG_MSR_MtrrFixDramModEn;
+ wrmsr(SYSCFG_MSR, msr);
+
+ msr.lo = (type << 24) | (type << 16) | (type << 8) | type;
+ msr.hi = (type << 24) | (type << 16) | (type << 8) | type;
+ wrmsr(reg, msr);
+
+ /* Disable Modify Extended RdMem and WrMem settings */
+ msr = rdmsr(SYSCFG_MSR);
+ msr.lo &= ~SYSCFG_MSR_MtrrFixDramModEn;
+ wrmsr(SYSCFG_MSR, msr);
+
+}
+
void cache_cbmem(int type)
{
/* Enable caching for 0 - 1MB using variable mtrr */
@@ -92,7 +113,7 @@
wrmsr(msr_nr, msr);
}
-#warning fix the XIP bits in stage1_mtrr.c that enable write through caching so we can do execute in place on the flash rom.
+#warning fix the XIP bits in stage1_mtrr.c that enable write through caching so we can do execute in place on the flash rom.
#if 0
#if defined(XIP_ROM_SIZE)
/* enable write through caching so we can do execute in place
Modified: coreboot-v3/include/arch/x86/amd/k8/k8.h
===================================================================
--- coreboot-v3/include/arch/x86/amd/k8/k8.h 2009-02-10 22:35:49 UTC (rev 1127)
+++ coreboot-v3/include/arch/x86/amd/k8/k8.h 2009-02-10 22:40:10 UTC (rev 1128)
@@ -695,56 +695,9 @@
/* k8/reset_test.c */
void distinguish_cpu_resets(unsigned nodeid);
-/* These are functions that MUST be inlined as we can not use a stack -- CAR or real ram */
-/* by yhlu 6.2005 */
-/* be warned, this file will be used other cores and core 0 / node 0 */
-static inline __attribute__((always_inline)) void disable_cache_as_ram(void)
-{
+inline __attribute__((always_inline)) void disable_cache_as_ram(void);
- __asm__ volatile (
-
- /* We don't need cache as ram for now on */
- /* disable cache */
- "movl %cr0, %eax\n\t"
- "orl $(0x1<<30),%eax\n\t"
- "movl %eax, %cr0\n\t"
-
- /* clear sth */
- "movl $0x269, %ecx\n\t" /* fix4k_c8000*/
- "xorl %edx, %edx\n\t"
- "xorl %eax, %eax\n\t"
- "wrmsr\n\t"
-#if CONFIG_CARSIZE > 0x8000
- "movl $0x268, %ecx\n\t" /* fix4k_c0000*/
- "wrmsr\n\t"
-#endif
-
- /* disable fixed mtrr from now on, it will be enabled by coreboot_ram again*/
- "movl $0xC0010010, %ecx\n\t"
-// "movl $SYSCFG_MSR, %ecx\n\t"
- "rdmsr\n\t"
- "andl $(~(3<<18)), %eax\n\t"
-// "andl $(~(SYSCFG_MSR_MtrrFixDramModEn | SYSCFG_MSR_MtrrFixDramEn)), %eax\n\t"
- "wrmsr\n\t"
-
- /* Set the default memory type and disable fixed and enable variable MTRRs */
- "movl $0x2ff, %ecx\n\t"
-// "movl $MTRRdefType_MSR, %ecx\n\t"
- "xorl %edx, %edx\n\t"
- /* Enable Variable and Disable Fixed MTRRs */
- "movl $0x00000800, %eax\n\t"
- "wrmsr\n\t"
-
- /* enable cache */
- "movl %cr0, %eax\n\t"
- "andl $0x9fffffff,%eax\n\t"
- "movl %eax, %cr0\n\t"
-
- );
-}
-
-void disable_cache_as_ram_bsp(void);
-
+void set_top_mem_ap(unsigned tom_k, unsigned tom2_k);
#endif /* ! ASSEMBLY */
#endif /* AMD_K8_H */
Modified: coreboot-v3/include/arch/x86/cpu.h
===================================================================
--- coreboot-v3/include/arch/x86/cpu.h 2009-02-10 22:35:49 UTC (rev 1127)
+++ coreboot-v3/include/arch/x86/cpu.h 2009-02-10 22:40:10 UTC (rev 1128)
@@ -267,7 +267,7 @@
}
-void set_init_ram_access(void);
+void set_mtrr_ram_access(void);
void * bottom_of_stack(void);
EXPORT_SYMBOL(bottom_of_stack);
Modified: coreboot-v3/include/arch/x86/mtrr.h
===================================================================
--- coreboot-v3/include/arch/x86/mtrr.h 2009-02-10 22:35:49 UTC (rev 1127)
+++ coreboot-v3/include/arch/x86/mtrr.h 2009-02-10 22:40:10 UTC (rev 1128)
@@ -37,7 +37,11 @@
int x86_mtrr_check(void);
void stage1_set_var_mtrr(unsigned long reg, unsigned long base,
unsigned long size, unsigned long type);
+void stage1_set_fix_mtrr(u32 reg, u8 type);
+void stage1_set_var_mtrr_x(unsigned long reg, u32 base_lo, u32 base_hi,
+ u32 size_lo, u32 size_hi, unsigned long type);
+
#endif
#endif /* ARCH_X86_MTRR_H */