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 <[email protected]>
Acked-by: Peter Stuge <[email protected]>



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 <[email protected]>
  *
  * 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 */


--
coreboot mailing list: [email protected]
http://www.coreboot.org/mailman/listinfo/coreboot

Reply via email to