[coreboot] r1128 - in coreboot-v3: arch/x86 arch/x86/amd/k8 arch/x86/amd/model_fxx include/arch/x86 include/arch/x86/amd/k8

svn at coreboot.org svn at coreboot.org
Tue Feb 10 23:40:10 CET 2009


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 at gmail.com>
Acked-by: Peter Stuge <peter at 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 at 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 */





More information about the coreboot mailing list