changes from AMD for making OLPC video work.
authorRonald G. Minnich <rminnich@gmail.com>
Sat, 10 Jun 2006 22:57:15 +0000 (22:57 +0000)
committerRonald G. Minnich <rminnich@gmail.com>
Sat, 10 Jun 2006 22:57:15 +0000 (22:57 +0000)
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@2316 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1

src/cpu/amd/model_gx2/cpubug.c
src/cpu/amd/model_gx2/cpureginit.c
src/cpu/amd/model_gx2/vsmsetup.c
src/include/cpu/amd/gx2def.h
src/mainboard/olpc/rev_a/auto.c
src/northbridge/amd/gx2/Config.lb
src/northbridge/amd/gx2/chipsetinit.c
src/northbridge/amd/gx2/northbridge.c
src/northbridge/amd/gx2/northbridgeinit.c
src/southbridge/amd/cs5536/cs5536_early_setup.c
targets/olpc/rev_a/Config.lb

index 3c512089384451e5f396c9317d2aa2001f859a1f..e38bbfbaa3853e17ca12643b6837b997b53b1b85 100644 (file)
@@ -31,25 +31,46 @@ bug573(void){
 }
 #endif
 
+/**************************************************************************
+ *
+ *     pcideadlock
+ *
+ *     Bugtool #465 and #609
+ *     PCI cache deadlock
+ *     There is also fix code in cache and PCI functions. This bug is very is pervasive.
+ *
+ *     Entry:
+ *     Exit:
+ *     Modified:
+ *
+ **************************************************************************/
 static void
 pcideadlock(void)
 {
        msr_t msr;
 
+       /*
+        * forces serialization of all load misses. Setting this bit prevents the 
+        * DM pipe from backing up if a read request has to be held up waiting 
+        * for PCI writes to complete.
+       */
        msr = rdmsr(CPU_DM_CONFIG0);
        msr.hi &= ~(7<<DM_CONFIG0_UPPER_WSREQ_SHIFT);
        msr.hi |= (2<<DM_CONFIG0_UPPER_WSREQ_SHIFT);
        msr.lo |= DM_CONFIG0_LOWER_MISSER_SET;
        wrmsr(CPU_DM_CONFIG0, msr);
 
+       /* interlock instruction fetches to WS regions with data accesses.
+        * This prevents an instruction fetch from going out to PCI if the 
+        * data side is about to make a request.
+        */
        msr = rdmsr(CPU_IM_CONFIG);
-       msr.lo |= IM_CONFIG_LOWER_QWT_SET;      /* interlock instruction fetches to WS regions with data accesses.
-                                                * This prevents in instruction fetch from going out to PCI if the 
-                                                * data side is about to make a request.
-                                                */
+       msr.lo |= IM_CONFIG_LOWER_QWT_SET;
        wrmsr(CPU_IM_CONFIG, msr);
-       /* write serialize memory hole to PCI. Need to to unWS when something is shadowed regardless of cachablility.*/
-
+       
+       /* write serialize memory hole to PCI. Need to unWS when something is 
+        * shadowed regardless of cachablility.
+        */
        msr.lo = 0x021212121;
        msr.hi = 0x021212121;
        wrmsr( CPU_RCONF_A0_BF, msr);
@@ -57,18 +78,18 @@ pcideadlock(void)
        wrmsr( CPU_RCONF_E0_FF, msr);
 }
 
-/****************************************************************************/
-/***/
-/**    CPUbug784*/
-/***/
-/**    Bugtool #784 + #792*/
-/***/
-/**    Fix CPUID instructions for < 3.0 CPUs*/
-/***/
-/**    Entry:*/
-/**    Exit:*/
-/**    Modified:*/
-/***/
+/**************************************************************************** 
+ *
+ *     CPUbug784
+ *
+ *     Bugtool #784 + #792
+ *
+ *     Fix CPUID instructions for < 3.0 CPUs
+ *
+ *     Entry:
+ *     Exit:
+ *     Modified:
+ *
 /****************************************************************************/
 
 void bug784(void)
@@ -99,18 +120,31 @@ void bug784(void)
 }
 
 /* cpubug 1398: enable MC if we KNOW we have DDR*/
+/**************************************************************************
+ *
+ *     CPUbugIAENG1398
+ *
+ *     ClearQuest #IAENG1398
+ *     The MC can not be enabled with SDR memory but can for DDR. Enable for
+ *     DDR here if the setup token is "Default"
+ *     Add this back to core by default once 2.0 CPUs are not supported.
+ *     Entry:
+ *     Exit:
+ *     Modified:
+ *
+ **************************************************************************/
 void eng1398(void)
 {
        msr_t msr;
 
        msr = rdmsr(MSR_GLCP+0x17);
-       if ((msr.lo & 0xff) < CPU_REV_2_0) {
+       if ((msr.lo & 0xff) <= CPU_REV_2_0) {
                msr = rdmsr(GLCP_SYS_RSTPLL);
                if (msr.lo & (1<<RSTPPL_LOWER_SDRMODE_SHIFT))
                        return;
        }
 
-       /* no bios to check, we just go for it? */
+       /* no CMOS/NVRAM to check, so enable MC Clock Gating */
        msr = rdmsr(MC_GLD_MSR_PM);
        msr.lo |= 3; /* enable MC clock gating.*/
        wrmsr(MC_GLD_MSR_PM, msr);
index f2802b67ca667ba32c6e763f9fea501181280563..779669c34a583d957333f42655da4c476cc3d8c6 100644 (file)
@@ -24,8 +24,8 @@ BIST(void){
        msrnum = CPU_DM_BIST;
        wrmsr(msrnum, msr);
 
-       outb(POST_CPU_DM_BIST_FAILURE   , 0x80);                                /* 0x29*/
-       msr = rdmsr(msrnum);                                                    /* read back for pass fail*/
+       outb(POST_CPU_DM_BIST_FAILURE, 0x80);                           /* 0x29*/
+       msr = rdmsr(msrnum);                                            /* read back for pass fail*/
        msr.lo &= 0x0F3FF0000;
        if (msr.lo != 0xfeff0000)
                goto BISTFail;
@@ -80,7 +80,10 @@ cpuRegInit (void){
        msr_t msr;
        /*  Turn on BTM for early debug based on setup. */
        /*if (getnvram( TOKEN_BTM_DIAG_MODE) & 3) {*/
-       {
+       /*
+        * The following is only for diagnostics mode; do not use for OLPC
+        */
+       if (0) {
                /*  Set Diagnostic Mode */
                msrnum = CPU_GLD_MSR_DIAG;
                msr.hi =  0;
@@ -91,7 +94,7 @@ cpuRegInit (void){
                msrnum = 0x04C00000C;           /*  GLCP_DBGOUT MSR*/
                msr.hi =  0x0;
                msr.lo =  0x08;                 /*  reset value (SCOPE_SEL = 0) causes FIFO toshift out,*/
-               wrmsr(msrnum, msr);                                     /*  exchange it to anything else to prevent this*/
+               wrmsr(msrnum, msr);             /*  exchange it to anything else to prevent this*/
        
                /* ;Turn off debug clock*/
                msrnum = 0x04C000016;           /* DBG_CLK_CTL*/
@@ -108,8 +111,8 @@ cpuRegInit (void){
                /* ;Set fifo ctl to BTM bits wide*/
                msrnum = 0x04C00005E;           /*  FIFO_CTL*/
                msr.lo =  0x003880000;          /*  Bit [25:24] are size (11=BTM, 10 = 64 bit, 01= 32 bit, 00 = 16bit)*/
-               wrmsr(msrnum, msr);             /*  Bit [23:21] are position (100 = CPU downto0)*/
-                                                               /*  Bit [19] sets it up in slow data mode.*/
+               wrmsr(msrnum, msr);     /*  Bit [23:21] are position (100 = CPU downto0)*/
+                                                       /*  Bit [19] sets it up in slow data mode.*/
        
                /* ;enable fifo loading - BTM sizing will constrain*/
                /* ; only valid BTM packets to load - this action should always be on*/
index cd734f6fdb6269c77d6651def0ca118f3d7c4710..d6955e7f2f347ad18b66c586c6123b24b5fde770 100644 (file)
@@ -5,6 +5,7 @@
 #undef __KERNEL__
 #include <arch/io.h>
 #include <string.h>
+#include <cpu/amd/gx2def.h>
 
 /* what a mess this uncompress thing is. I am not at all happy about how this 
  * was done, but can't fix it yet. RGM
@@ -335,7 +336,7 @@ void do_vsmbios(void)
        unsigned long busdevfn;
        unsigned int rom = 0;
        unsigned char *buf;
-       unsigned int size = 256*1024;
+       unsigned int size = SMM_SIZE*1024;
        int i;
        
        printk_err("do_vsmbios\n");
@@ -353,12 +354,12 @@ void do_vsmbios(void)
        //rom = 0xfff80000;
        //rom = 0xfffc0000;
        /* the VSA starts at the base of rom - 64 */
-       rom = ((unsigned long) 0) - (ROM_SIZE  + 35*1024);
+       rom = ((unsigned long) 0) - (ROM_SIZE  + 64*1024);
 
        buf = (unsigned char *) 0x60000;
        unrv2b((uint8_t *)rom, buf);
        printk_debug("buf %p *buf %d buf[256k] %d\n",
-                    buf, buf[0], buf[256*1024]);
+                    buf, buf[0], buf[SMM_SIZE*1024]);
        printk_debug("buf[0x20] signature is %x:%x:%x:%x\n",
                     buf[0x20] ,buf[0x21] ,buf[0x22],buf[0x23]);
        /* check for post code at start of vsainit.bin. If you don't see it,
index 074e36110bcfd004b9853c28358a0428e1370879..fd466afe4853e4b60191b122083c7d03b8fbfb8a 100644 (file)
 #define GL1_VIP                                5
 #define GL1_AES                                6
 
-#define        MSR_GLIU0                       (GL0_GLIU0 << 29) + (1 << 28) /* To get on GeodeLink one bit has to be set */
-#define        MSR_MC                          (GL0_MC         << 29)
-#define        MSR_GLIU1                       (GL0_GLIU1      << 29)
-#define        MSR_CPU                         (GL0_CPU        << 29) /* this is not used for BIOS since code executing on CPU doesn't need to be routed*/
-#define        MSR_VG                          (GL0_VG         << 29)
-#define        MSR_GP                          (GL0_GP         << 29)
-#define        MSR_DF                          (GL0_DF         << 29)
-
-#define        MSR_GLCP                        (GL1_GLCP << 26) + MSR_GLIU1
-#define        MSR_PCI                         (GL1_PCI << 26) + MSR_GLIU1
-#define        MSR_FG                          (GL1_FG << 26) + MSR_GLIU1
-#define        MSR_VIP                         ((GL1_VIP << 26) + MSR_GLIU1)
-#define        MSR_AES                         ((GL1_AES << 26) + MSR_GLIU1)
+#define        MSR_GLIU0                       (GL0_GLIU0 << 29) + (1 << 28)   /* 1000xxxx - To get on GeodeLink one bit has to be set */
+#define        MSR_MC                          (GL0_MC         << 29)  /* 2000xxxx */
+#define        MSR_GLIU1                       (GL0_GLIU1      << 29)  /* 4000xxxx */
+#define        MSR_CPU                         (GL0_CPU        << 29)  /* 6000xxxx - this is not used for BIOS since code executing on CPU doesn't need to be routed*/
+#define        MSR_VG                          (GL0_VG         << 29)  /* 8000xxxx */
+#define        MSR_GP                          (GL0_GP         << 29)  /* A000xxxx */
+#define        MSR_DF                          (GL0_DF         << 29)  /* C000xxxx */
+
+#define        MSR_GLCP                        (GL1_GLCP << 26) + MSR_GLIU1    /* 4C00xxxx */
+#define        MSR_PCI                         (GL1_PCI << 26) + MSR_GLIU1     /* 5000xxxx */
+#define        MSR_FG                          (GL1_FG << 26) + MSR_GLIU1      /* 5400xxxx */
+#define MSR_VIP                                ((GL1_VIP << 26) + MSR_GLIU1)   /* 5400xxxx */
+#define MSR_AES                                ((GL1_AES << 26) + MSR_GLIU1)   /* 5800xxxx */
 /* South Bridge*/
 #define SB_PORT        2                       /* port of the SouthBridge */
-#define        MSR_SB                          ((SB_PORT << 23) + MSR_PCI)     /* address to the SouthBridge*/
+#define        MSR_SB                          ((SB_PORT << 23) + MSR_PCI)     /* 5100xxxx - address to the SouthBridge*/
 #define        SB_SHIFT                        20                                                      /* 29 -> 26 -> 23 -> 20...... When making a SB address uses this shift.*/
 
 
 
 /* definitions that are "once you are mostly up, start VSA" type things */
 #define SMM_OFFSET     0x40400000
-#define SMM_SIZE               256
+#define SMM_SIZE               128                     /* changed SMM_SIZE from 256 KB to 128 KB */
 #define DMM_OFFSET     0x0C0000000
 #define DMM_SIZE               128
 #define FB_OFFSET              0x41000000
 
 /*  SouthBridge Equates*/
 /*  MSR_SB and SB_SHIFT are located in CPU.inc*/
-#define MSR_SB_GLIU             (              (9 << 14) + MSR_SB                      /*  fake out just like GL0 on CPU.*/)
-#define MSR_SB_GLPCI    (              MSR_SB                                                  /*  don't go to the GLIU*/)
-#define MSR_SB_USB2             (              (2 << SB_SHIFT) + MSR_SB)
-#define MSR_SB_ATA              (              (3 << SB_SHIFT) + MSR_SB)
-#define MSR_SB_MDD              (              (4 << SB_SHIFT) + MSR_SB)
-#define MSR_SB_AC97             (              (5 << SB_SHIFT) + MSR_SB)
-#define MSR_SB_USB1             (              (6 << SB_SHIFT) + MSR_SB)
-#define MSR_SB_GLCP             (              (7 << SB_SHIFT) + MSR_SB)
+#define MSR_SB_GLIU     ((9 << 14) + MSR_SB)           /* 51024xxx or 510*xxxx - fake out just like GL0 on CPU. */
+#define MSR_SB_GLPCI    (MSR_SB)                       /* 5100xxxx - don't go to the GLIU */
+#define MSR_SB_USB2     ((2 << SB_SHIFT) + MSR_SB)     /* 5120xxxx */
+#define MSR_SB_ATA      ((3 << SB_SHIFT) + MSR_SB)     /* 5130xxxx */
+#define MSR_SB_MDD      ((4 << SB_SHIFT) + MSR_SB)     /* 5140xxxx, a.k.a. DIVIL = Diverse Integrated Logic device */
+#define MSR_SB_AC97     ((5 << SB_SHIFT) + MSR_SB)     /* 5150xxxx */
+#define MSR_SB_USB1     ((6 << SB_SHIFT) + MSR_SB)     /* 5160xxxx */
+#define MSR_SB_GLCP     ((7 << SB_SHIFT) + MSR_SB)     /* 5170xxxx */
 
 /* */
 /* GLIU*/
index 53ac114a63e0ce9ed32e8319db49a67ca953b35a..d61532f39e9867d64a975e2c6b25def7b2422b57 100644 (file)
@@ -124,7 +124,7 @@ static void sdram_set_spd_registers(const struct mem_controller *ctrl)
         */
        msr.lo = 0x286332a3;
 
-       wrmsr(0x20000019, msr);         
+       wrmsr(0x20000019, msr);
 
 }
 
index 567b5a939bc4940a5f4d2608f1084d691ea7791d..ee8cd206f936db045dda3997c6103b7be35bfc17 100644 (file)
@@ -2,3 +2,4 @@ config chip.h
 object northbridge.o
 object northbridgeinit.o
 object chipsetinit.o
+object grphinit.o
index 2a1688a01417012543014dc1c7ebbda90a60ab10..a149d626efcbf54f81bafdc2f17f2bf6e7e0583f 100644 (file)
@@ -53,7 +53,7 @@ struct msrinit CS5536_CLOCK_GATING_TABLE[] = {
        {      GLIU_SB_GLD_MSR_PM,      {.hi=0,.lo=0x000000004}},
        {      GLPCI_SB_GLD_MSR_PM,     {.hi=0,.lo=0x000000005}},
        {      GLCP_SB_GLD_MSR_PM,      {.hi=0,.lo=0x000000004}},
-       {      MDD_SB_GLD_MSR_PM,       {.hi=0,.lo=0x050554111}},       /*  SMBus clock gating errata (PBZ 2226 & SiBZ 3977)*/
+       {      MDD_SB_GLD_MSR_PM,       {.hi=0,.lo=0x050554111}}, /*  SMBus clock gating errata (PBZ 2226 & SiBZ 3977)*/
        {      ATA_SB_GLD_MSR_PM,       {.hi=0,.lo=0x000000005}},
        {      AC97_SB_GLD_MSR_PM,      {.hi=0,.lo=0x000000005}},
        {0,{0,0}}
@@ -210,7 +210,6 @@ chipsetinit (void){
 
        outb( P80_CHIPSET_INIT, 0x80);
        ChipsetGeodeLinkInit();
-
 #if 0
        /* we hope NEVER to be in linuxbios when S3 resumes 
        if (! IsS3Resume()) */
@@ -230,16 +229,17 @@ chipsetinit (void){
        }
 #endif
 
-       /* for later ... if 5536 set_usb_20(); */
-
-       /*  Setup USB. Need more details. #118.18*/
-       msrnum = MSR_SB_USB1 + 8;
-       msr.lo =  0x00012090;
-       msr.hi = 0;
-       wrmsr(msrnum, msr);
-       msrnum = MSR_SB_USB2 + 8;
-       wrmsr(msrnum, msr);
 
+       if (!is_5536()) {
+               /*  Setup USB. Need more details. #118.18*/
+               msrnum = MSR_SB_USB1 + 8;
+               msr.lo =  0x00012090;
+               msr.hi = 0;
+               wrmsr(msrnum, msr);
+               msrnum = MSR_SB_USB2 + 8;
+               wrmsr(msrnum, msr);
+       }
+       
        /* set hd IRQ */
        outl    (GPIOL_2_SET, GPIOL_INPUT_ENABLE);
        outl    (GPIOL_2_SET, GPIOL_IN_AUX1_SELECT);
@@ -270,7 +270,7 @@ chipsetinit (void){
        for(; csi->msrnum; csi++){
                msr.lo = csi->msr.lo;
                msr.hi = csi->msr.hi;
-               wrmsr(csi->msrnum, msr);
+               wrmsr(csi->msrnum, msr); // MSR - see table above
        }
 
 
@@ -288,12 +288,12 @@ chipsetinit (void){
                if (is_5536())
                        csi = CS5536_CLOCK_GATING_TABLE;
                else
-                       csi =  CS5535_CLOCK_GATING_TABLE;
+                       csi = CS5535_CLOCK_GATING_TABLE;
 
                for(; csi->msrnum; csi++){
                        msr.lo = csi->msr.lo;
                        msr.hi = csi->msr.hi;
-                       wrmsr(csi->msrnum, msr);
+                       wrmsr(csi->msrnum, msr);        // MSR - see table above
                }
        }
 
index e70938dafb81cb6151772bee6be693527a9978e2..fca31979dd95527a3f4aad7f10e3921979d4d245 100644 (file)
 #include <cpu/x86/msr.h>
 #include <cpu/x86/cache.h>
 
-#define NORTHBRIDGE_FILE "northbridge.c"
+#define VIDEO_MB 8
 
-/* number of MB to take off the top of ram for VSM and display memory. 
- * FIXME -- make this configurable
- */
-#define RAMADJUSTMB    9
-/*
-*/
+extern void graphics_init(void);
+
+#define NORTHBRIDGE_FILE "northbridge.c"
 
 /* todo: add a resource record. We don't do this here because this may be called when 
   * very little of the platform is actually working.
@@ -115,24 +112,31 @@ struct msr_defaults {
        /* GLIU0 */
        P2D_BM(0x10000020, 0x1, 0x0, 0x0, 0xfff80),
        P2D_BM(0x10000021, 0x1, 0x0, 0x80000, 0xfffe0),
-       P2D_SC(0x1000002c, 0x1, 0x0, 0x0,  0xff03, 0x3),
+       P2D_SC(0x1000002c, 0x1, 0x0, 0x0,  0xff03, 0xC0000),
        /* GLIU1 */
        P2D_BM(0x40000020, 0x1, 0x0, 0x0, 0xfff80),
        P2D_BM(0x40000021, 0x1, 0x0, 0x80000, 0xfffe0),
-       P2D_SC(0x4000002d, 0x1, 0x0, 0x0,  0xff03, 0x3),
+       P2D_SC(0x4000002d, 0x1, 0x0, 0x0,  0xff03, 0xC0000),
        {0}
 };
 
 
+/*
+ * setup_gx2_cache
+ *
+ * Returns the amount of memory (in KB) available to the system.  This is the 
+ * total amount of memory less the amount of memory reserved for SMM use.
+ *
+ */ 
 static int
 setup_gx2_cache(void)
 {
        msr_t msr;
        unsigned long long val;
-       int sizembytes, sizereg;
+       int sizekbytes, sizereg;
 
-       sizembytes = sizeram();
-       printk_debug("enable_cache: enable for %dm bytes\n", sizembytes);
+       sizekbytes = sizeram() * 1024;
+       printk_debug("setup_gx2_cache: enable for %d KB\n", sizekbytes);
        /* build up the rconf word. */
        /* the SYSTOP bits 27:8 are actually the top bits from 31:12. Book fails to say that */
        /* set romrp */
@@ -142,54 +146,58 @@ setup_gx2_cache(void)
        val |= ((unsigned long long) 0xfff00)<<36;
        /* set the devrp properties */
        val |= ((unsigned long long) DEVICE_PROPERTIES) << 28;
-       /* sigh. Take our TOM, RIGHT shift 12, since it page-aligned, then LEFT-shift 8 for reg. */
-       /* yank off 8M for frame buffer and 1M for VSA */
-       sizembytes -= RAMADJUSTMB;
-       sizereg = sizembytes;
-       sizereg *= 0x100000;
+       /* Take our TOM, RIGHT shift 12, since it page-aligned, then LEFT-shift 8 for reg. */
+       /* yank off memory for the SMM handler */
+       sizekbytes -= SMM_SIZE;
+       sizereg = sizekbytes;
+       sizereg *= 1024;        // convert to bytes
        sizereg >>= 12;
        sizereg <<= 8;
        val |= sizereg;
        val |= RAM_PROPERTIES;
        msr.lo = val;
        msr.hi = (val >> 32);
-       printk_debug("msr will be set to %x:%x\n", msr.hi, msr.lo);
+       printk_debug("msr 0x%08X will be set to %08x:%08x\n", CPU_RCONF_DEFAULT, msr.hi, msr.lo);
        wrmsr(CPU_RCONF_DEFAULT, msr);
 
        enable_cache();
        wbinvd();
-       return sizembytes;
+       return sizekbytes;
 }
 
-#define SMM_OFFSET 0x40400000
-#define SMM_SIZE   256
-
 /* we have to do this here. We have not found a nicer way to do it */
 void
 setup_gx2(void)
 {
        int i;
-       unsigned long tmp, tmp2, tmp3;
+       unsigned long tmp, tmp2;
        msr_t msr;
-       unsigned long sizem, membytes;
+       unsigned long size_kb, membytes;
 
-       sizem = setup_gx2_cache();
+       size_kb = setup_gx2_cache();
 
-       membytes = sizem * 1048576;
+       membytes = size_kb * 1024;
        /* NOTE! setup_gx2_cache returns the SIZE OF RAM - RAMADJUST!
          * so it is safe to use. You should NOT at this point call     
          * sizeram() directly. 
          */
 
-
        /* we need to set 0x10000028 and 0x40000029 */
-       printk_debug("sizem 0x%x, membytes 0x%x\n", sizem, membytes);
+       /*
+        * These two descriptors cover the range from 1 MB (0x100000) to 
+        * SYSTOP (a.k.a. TOM, or Top of Memory)
+        */
+
+#if 0
+       /* This has already been done elsewhere */
+       printk_debug("size_kb 0x%x, membytes 0x%x\n", size_kb, membytes);
        msr.hi = 0x20000000 | membytes>>24;
        msr.lo = 0x100 | ( ((membytes >>12) & 0xfff) << 20);
        wrmsr(0x10000028, msr);
        msr.hi = 0x20000000 | membytes>>24;
        msr.lo = 0x100 | ( ((membytes >>12) & 0xfff) << 20);
        wrmsr(0x40000029, msr);
+#endif
        msr = rdmsr(0x10000028);
        printk_debug("MSR 0x%x is now 0x%x:0x%x\n", 0x10000028, msr.hi,msr.lo);
        msr = rdmsr(0x40000029);
@@ -227,13 +235,15 @@ setup_gx2(void)
        msr = rdmsr(0x1808);
        printk_debug("MSR 0x%x is now 0x%x:0x%x\n", 0x1808, msr.hi, msr.lo);
 #endif
+#if 0  // SDG - don't do this
        /* now do the default MSR values */
        for(i = 0; msr_defaults[i].msr_no; i++) {
                msr_t msr;
-               wrmsr(msr_defaults[i].msr_no, msr_defaults[i].msr);
+               wrmsr(msr_defaults[i].msr_no, msr_defaults[i].msr);     // MSR - see table above
                msr = rdmsr(msr_defaults[i].msr_no);
-               printk_debug("MSR 0x%x is now 0x%x:0x%x\n", msr_defaults[i].msr_no, msr.hi,msr.lo);
+               printk_debug("MSR 0x%08X is now 0x%08X:0x%08X\n", msr_defaults[i].msr_no, msr.hi,msr.lo);
        }
+#endif
 }
 
 static void enable_shadow(device_t dev)
@@ -325,9 +335,10 @@ static uint32_t find_pci_tolm(struct bus *bus)
 
 static void pci_domain_set_resources(device_t dev)
 {
+#if 0
        device_t mc_dev;
         uint32_t pci_tolm;
-#if 0
+
         pci_tolm = find_pci_tolm(&dev->link[0]);
        mc_dev = dev->link[0].children;
        if (mc_dev) {
@@ -421,13 +432,15 @@ static void enable_dev(struct device *dev)
                /* do this here for now -- this chip really breaks our device model */
                setup_realmode_idt();
                do_vsmbios();
+               graphics_init();
                dev->ops = &pci_domain_ops;
                pci_set_method(dev);
-               ram_resource(dev, 0, 0, (sizeram() - RAMADJUSTMB)*1024);
+               ram_resource(dev, 0, 0, ((sizeram() - VIDEO_MB) * 1024) - SMM_SIZE);
         } else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) {
                printk_debug("DEVICE_PATH_APIC_CLUSTER\n");
                 dev->ops = &cpu_bus_ops;
         }
+       printk_debug("gx2 north: end enable_dev\n");
 }
 
 struct chip_operations northbridge_amd_gx2_ops = {
index 724b4de4c445f16ad4b0346077bbf98a9fbc5dca..6d32aa2a7f9b2551fd412b3d044b786550293671 100644 (file)
@@ -22,21 +22,21 @@ struct gliutable {
 };
 
 struct gliutable gliu0table[] = {
-       {.desc_name=MSR_GLIU0_BASE1, .desc_type= BM,.hi= MSR_MC + 0x0,.lo=  0x0FFF80},          /*  0-7FFFF to MC*/
-       {.desc_name=MSR_GLIU0_BASE2, .desc_type= BM,.hi= MSR_MC + 0x0,.lo=(0x80 << 20) + 0x0FFFE0},             /*  80000-9ffff to Mc*/
-       {.desc_name=MSR_GLIU0_SHADOW,.desc_type= SC_SHADOW,.hi=  MSR_MC + 0x0,.lo=  0x03},      /*  C0000-Fffff split to MC and PCI (sub decode) A0000-Bffff handled by SoftVideo*/
-       {.desc_name=MSR_GLIU0_SYSMEM,.desc_type= R_SYSMEM,.hi=  MSR_MC,.lo=  0x0},              /*  Catch and fix dynamicly.*/
-       {.desc_name=MSR_GLIU0_DMM,   .desc_type= BMO_DMM,.hi=  MSR_MC,.lo=  0x0},               /*  Catch and fix dynamicly.*/
-       {.desc_name=MSR_GLIU0_SMM,   .desc_type= BMO_SMM,.hi=  MSR_MC,.lo=  0x0},               /*  Catch and fix dynamicly.*/
+       {.desc_name=MSR_GLIU0_BASE1,  .desc_type= BM,.hi= MSR_MC + 0x0,.lo=  0x0FFF80},         /*  0-7FFFF to MC*/
+       {.desc_name=MSR_GLIU0_BASE2,  .desc_type= BM,.hi= MSR_MC + 0x0,.lo=(0x80 << 20) + 0x0FFFE0},            /*  80000-9ffff to Mc*/
+       {.desc_name=MSR_GLIU0_SHADOW, .desc_type= SC_SHADOW,.hi=  MSR_MC + 0x0,.lo=  0x03},     /*  C0000-Fffff split to MC and PCI (sub decode) A0000-Bffff handled by SoftVideo*/
+       {.desc_name=MSR_GLIU0_SYSMEM, .desc_type= R_SYSMEM,.hi=  MSR_MC,.lo=  0x0},             /*  Catch and fix dynamicly.*/
+       {.desc_name=MSR_GLIU0_DMM,    .desc_type= BMO_DMM,.hi=  MSR_MC,.lo=  0x0},              /*  Catch and fix dynamicly.*/
+       {.desc_name=MSR_GLIU0_SMM,    .desc_type= BMO_SMM,.hi=  MSR_MC,.lo=  0x0},              /*  Catch and fix dynamicly.*/
        {.desc_name=GLIU0_GLD_MSR_COH,.desc_type= OTHER,.hi= 0x0,.lo= GL0_CPU},
-       {.desc_name=GL_END,          .desc_type= GL_END,.hi= 0x0,.lo= 0x0},
+       {.desc_name=GL_END,           .desc_type= GL_END,.hi= 0x0,.lo= 0x0},
 };
 
 
 struct gliutable gliu1table[] = {
        {.desc_name=MSR_GLIU1_BASE1,.desc_type=  BM,.hi=  MSR_GL0 + 0x0,.lo=  0x0FFF80},        /*  0-7FFFF to MC*/
        {.desc_name=MSR_GLIU1_BASE2,.desc_type=  BM,.hi=  MSR_GL0 + 0x0,.lo= (0x80 << 20) +0x0FFFE0},   /*  80000-9ffff to Mc*/
-       {.desc_name=MSR_GLIU1_SHADOW,.desc_type=  SC_SHADOW,.hi=  MSR_GL0 + 0x0,.lo=  0x03},/*  C0000-Fffff split to MC and PCI (sub decode)*/
+       {.desc_name=MSR_GLIU1_SHADOW,.desc_type=  SC_SHADOW,.hi=  MSR_GL0 + 0x0,.lo=  0x03}, /*  C0000-Fffff split to MC and PCI (sub decode)*/
        {.desc_name=MSR_GLIU1_SYSMEM,.desc_type=  R_SYSMEM,.hi=  MSR_GL0,.lo=  0x0},            /*  Cat0xc and fix dynamicly.*/
        {.desc_name=MSR_GLIU1_DMM,.desc_type=  BM_DMM,.hi=  MSR_GL0,.lo=  0x0},                 /*  Cat0xc and fix dynamicly.*/
        {.desc_name=MSR_GLIU1_SMM,.desc_type=  BM_SMM,.hi=  MSR_GL0,.lo=  0x0},                 /*  Cat0xc and fix dynamicly.*/
@@ -81,7 +81,7 @@ struct msrinit ClockGatingAllOn[] = {
 
        /*  Performance*/
 struct msrinit ClockGatingPerformance[] = {
-       {VG_GLD_MSR_PM,         {.hi=0x00,.lo=0x0000}},                         /*  lotus #77.163*/
+       {VG_GLD_MSR_PM,         {.hi=0x00,.lo=0x0000}},         /*  lotus #77.163*/
        {GP_GLD_MSR_PM,         {.hi=0x00,.lo=0x0001}},
        {DF_GLD_MSR_PM,         {.hi=0x00,.lo=0x0155}},
        {GLCP_GLD_MSR_PM,       {.hi=0x00,.lo=0x0015}},
@@ -91,14 +91,14 @@ struct msrinit ClockGatingPerformance[] = {
 /*  SET GeodeLink PRIORITY*/
 /* */
 struct msrinit GeodeLinkPriorityTable [] = {
-       {CPU_GLD_MSR_CONFIG,            {.hi=0x00,.lo=0x0220}},         /*  CPU Priority.*/
-       {DF_GLD_MSR_MASTER_CONF,        {.hi=0x00,.lo=0x0000}},         /*  DF Priority.*/
-       {VG_GLD_MSR_CONFIG,             {.hi=0x00,.lo=0x0720}},         /*  VG Primary and Secondary Priority.*/
-       {GP_GLD_MSR_CONFIG,             {.hi=0x00,.lo=0x0010}},         /*  Graphics Priority.*/
-       {GLPCI_GLD_MSR_CONFIG,          {.hi=0x00,.lo=0x0017}},         /*  GLPCI Priority + PID*/
-       {GLCP_GLD_MSR_CONF,             {.hi=0x00,.lo=0x0001}},         /*  GLCP Priority + PID*/
-       {VIP_GLD_MSR_CONFIG,            {.hi=0x00,.lo=0x0622}},         /*  VIP PID*/
-       {AES_GLD_MSR_CONFIG,            {.hi=0x00,.lo=0x0013}},         /*  AES PID*/
+       {CPU_GLD_MSR_CONFIG,            {.hi=0x00,.lo=0x0220}}, /*  CPU Priority.*/
+       {DF_GLD_MSR_MASTER_CONF,        {.hi=0x00,.lo=0x0000}}, /*  DF Priority.*/
+       {VG_GLD_MSR_CONFIG,             {.hi=0x00,.lo=0x0720}}, /*  VG Primary and Secondary Priority.*/
+       {GP_GLD_MSR_CONFIG,             {.hi=0x00,.lo=0x0010}}, /*  Graphics Priority.*/
+       {GLPCI_GLD_MSR_CONFIG,          {.hi=0x00,.lo=0x0017}}, /*  GLPCI Priority + PID*/
+       {GLCP_GLD_MSR_CONF,             {.hi=0x00,.lo=0x0001}}, /*  GLCP Priority + PID*/
+       {VIP_GLD_MSR_CONFIG,            {.hi=0x00,.lo=0x0622}}, /*  VIP PID*/
+       {AES_GLD_MSR_CONFIG,            {.hi=0x00,.lo=0x0013}}, /*  AES PID*/
        {0x0FFFFFFFF,                   {0x0FFFFFFFF, 0x0FFFFFFFF}},    /*  END*/
 };
 
@@ -111,11 +111,11 @@ writeglmsr(struct gliutable *gl){
 
        msr.lo = gl->lo;
        msr.hi = gl->hi;
-       wrmsr(gl->desc_name, msr);
-       printk_debug("%s: write msr 0x%x, val 0x%x:0x%x\n", __FUNCTION__, gl->desc_name, msr.hi, msr.lo);
+       wrmsr(gl->desc_name, msr);      // MSR - see table above
+       printk_debug("%s: write msr 0x%08x, val 0x%08x:0x%08x\n", __FUNCTION__, gl->desc_name, msr.hi, msr.lo);
        /* they do this, so we do this */
        msr = rdmsr(gl->desc_name);
-       printk_debug("%s: AFTER write msr 0x%x, val 0x%x:0x%x\n", __FUNCTION__, gl->desc_name, msr.hi, msr.lo);
+       printk_debug("%s: AFTER write msr 0x%08x, val 0x%08x:0x%08x\n", __FUNCTION__, gl->desc_name, msr.hi, msr.lo);
 }
 
 static void
@@ -142,6 +142,10 @@ SysmemInit(struct gliutable *gl)
        msr_t msr;
        int sizembytes, sizebytes;
 
+       /* 
+        * Figure out how much RAM is in the machine and alocate all to the 
+        * system. We will adjust for SMM and DMM now and Frame Buffer later.
+        */
        sizembytes = sizeram();
        printk_debug("%s: enable for %dm bytes\n", __FUNCTION__, sizembytes);
        sizebytes = sizembytes << 20;
@@ -152,15 +156,15 @@ SysmemInit(struct gliutable *gl)
                sizebytes -= DMM_SIZE * 1024 + 1;
 
        sizebytes -= 1;
-       msr.hi = gl->hi | (sizebytes >> 24);
+       msr.hi = (gl->hi & 0xFFFFFF00) | (sizebytes >> 24);
        /* set up sizebytes to fit into msr.lo */
-       sizebytes <<= 8; /* what? well, we want bits 23:12 in bytes 31:20. */
+       sizebytes <<= 8; /* what? well, we want bits 23:12 in bits 31:20. */
        sizebytes &= 0xfff00000;
        sizebytes |= 0x100;
        msr.lo = sizebytes;
-       wrmsr(gl->desc_name, msr);
+       wrmsr(gl->desc_name, msr);      // MSR - see table above
        msr = rdmsr(gl->desc_name);
-       printk_debug("%s: AFTER write msr 0x%x, val 0x%x:0x%x\n", __FUNCTION__, 
+       printk_debug("%s: AFTER write msr 0x%08x, val 0x%08x:0x%08x\n", __FUNCTION__, 
                                gl->desc_name, msr.hi, msr.lo);
        
 }
@@ -177,7 +181,7 @@ DMMGL0Init(struct gliutable *gl) {
 
        sizebytes -= DMM_SIZE*1024;
        offset = sizebytes - DMM_OFFSET;
-       printk_debug("%s: offset is 0x%x\n", __FUNCTION__, offset);
+       printk_debug("%s: offset is 0x%08x\n", __FUNCTION__, offset);
        offset >>= 12;
        msr.hi = (gl->hi) | (offset << 8);
        /* I don't think this is needed */
@@ -186,9 +190,9 @@ DMMGL0Init(struct gliutable *gl) {
        msr.lo = DMM_OFFSET << 8;
        msr.lo |= ((~(DMM_SIZE*1024)+1)>>12)&0xfffff;
        
-       wrmsr(gl->desc_name, msr);
+       wrmsr(gl->desc_name, msr);      // MSR - See table above
        msr = rdmsr(gl->desc_name);
-       printk_debug("%s: AFTER write msr 0x%x, val 0x%x:0x%x\n", __FUNCTION__, gl->desc_name, msr.hi, msr.lo);
+       printk_debug("%s: AFTER write msr 0x%08x, val 0x%08x:0x%08x\n", __FUNCTION__, gl->desc_name, msr.hi, msr.lo);
        
 }
 static void
@@ -209,9 +213,9 @@ DMMGL1Init(struct gliutable *gl) {
        printk_err("%s: warning, using DMM_SIZE even though AMD used SMM_SIZE\n", __FUNCTION__);
        msr.lo |= ((~(DMM_SIZE*1024)+1)>>12)&0xfffff;
        
-       wrmsr(gl->desc_name, msr);
+       wrmsr(gl->desc_name, msr);      // MSR - See table above
        msr = rdmsr(gl->desc_name);
-       printk_debug("%s: AFTER write msr 0x%x, val 0x%x:0x%x\n", __FUNCTION__, gl->desc_name, msr.hi, msr.lo);
+       printk_debug("%s: AFTER write msr 0x%08x, val 0x%08x:0x%08x\n", __FUNCTION__, gl->desc_name, msr.hi, msr.lo);
 }
 static void
 SMMGL0Init(struct gliutable *gl) {
@@ -227,7 +231,7 @@ SMMGL0Init(struct gliutable *gl) {
        printk_debug("%s: %d bytes\n", __FUNCTION__, sizebytes);
 
        offset = sizebytes - SMM_OFFSET;
-       printk_debug("%s: offset is 0x%x\n", __FUNCTION__, offset);
+       printk_debug("%s: offset is 0x%08x\n", __FUNCTION__, offset);
        offset >>= 12;
 
        msr.hi = offset << 8;
@@ -236,9 +240,9 @@ SMMGL0Init(struct gliutable *gl) {
        msr.lo = SMM_OFFSET << 8;
        msr.lo |= ((~(SMM_SIZE*1024)+1)>>12)&0xfffff;
        
-       wrmsr(gl->desc_name, msr);
+       wrmsr(gl->desc_name, msr);      // MSR - See table above
        msr = rdmsr(gl->desc_name);
-       printk_debug("%s: AFTER write msr 0x%x, val 0x%x:0x%x\n", __FUNCTION__, gl->desc_name, msr.hi, msr.lo);
+       printk_debug("%s: AFTER write msr 0x%08x, val 0x%08x:0x%08x\n", __FUNCTION__, gl->desc_name, msr.hi, msr.lo);
 }
 static void
 SMMGL1Init(struct gliutable *gl) {
@@ -252,9 +256,9 @@ SMMGL1Init(struct gliutable *gl) {
        msr.lo = SMM_OFFSET << 8;
        msr.lo |= ((~(SMM_SIZE*1024)+1)>>12)&0xfffff;
        
-       wrmsr(gl->desc_name, msr);
+       wrmsr(gl->desc_name, msr);      // MSR - See table above
        msr = rdmsr(gl->desc_name);
-       printk_debug("%s: AFTER write msr 0x%x, val 0x%x:0x%x\n", __FUNCTION__, gl->desc_name, msr.hi, msr.lo);
+       printk_debug("%s: AFTER write msr 0x%08x, val 0x%08x:0x%08x\n", __FUNCTION__, gl->desc_name, msr.hi, msr.lo);
 }
 
 static void
@@ -263,11 +267,15 @@ GLIUInit(struct gliutable *gl){
        while (gl->desc_type != GL_END){
                switch(gl->desc_type){
                default: 
+#if 01
+                       /* For Unknown types: Write then read MSR */
+                       writeglmsr(gl);
+#else
                                printk_err("%s: name %x, type %x, hi %x, lo %x: unsupported  type: ", __FUNCTION__, 
                                                        gl->desc_name, gl->desc_type, gl->hi, gl->hi);
                                printk_err("Must be %x, %x, %x, %x, %x, or %x\n", SC_SHADOW,R_SYSMEM,BMO_DMM,
                                                                                        BM_DMM, BMO_SMM,BM_SMM);
-       
+#endif 
                case SC_SHADOW: /*  Check for a Shadow entry*/
                        ShadowInit(gl);
                        break;
@@ -276,7 +284,7 @@ GLIUInit(struct gliutable *gl){
                        SysmemInit(gl);
                        break;
        
-               case    BMO_DMM: /*  check for a DMM entry*/
+               case BMO_DMM: /*  check for a DMM entry*/
                        DMMGL0Init(gl);
                        break;
        
@@ -317,12 +325,12 @@ static void GLPCIInit(void){
        int i;
        msr_t msr;
        int msrnum;
-       unsigned long  val;
+
        /* */
        /*  R0 - GLPCI settings for Conventional Memory space.*/
        /* */
        msr.hi =  (0x09F000 >> 12) << GLPCI_RC_UPPER_TOP_SHIFT          /*  640*/;
-       msr.lo =  0                                                                                                     /*  0*/;
+       msr.lo =  0                                                     /*  0*/;
        msr.lo |= GLPCI_RC_LOWER_EN_SET+ GLPCI_RC_LOWER_PF_SET + GLPCI_RC_LOWER_WC_SET;
        msrnum = GLPCI_RC0;
        wrmsr(msrnum, msr);
@@ -349,7 +357,7 @@ static void GLPCIInit(void){
                /* So we need a high page aligned addresss (pah) and low page aligned address (pal)
                 * pah is from msr.hi << 12 | msr.low >> 20. pal is msr.lo << 12
                 */
-               printk_debug("GLPCI r1: system msr.lo 0x%x msr.hi 0x%x\n", msr.lo, msr.hi);
+               printk_debug("GLPCI r1: system msr.lo 0x%08x msr.hi 0x%08x\n", msr.lo, msr.hi);
                pah = ((msr.hi &0xff) << 12) | ((msr.lo >> 20) & 0xfff);
                /* we have the page address. Now make it a page-aligned address */
                pah <<= 12;
@@ -358,7 +366,7 @@ static void GLPCIInit(void){
                msr.hi =  pah;
                msr.lo =  pal;
                msr.lo |= GLPCI_RC_LOWER_EN_SET | GLPCI_RC_LOWER_PF_SET | GLPCI_RC_LOWER_WC_SET;
-               printk_debug("GLPCI r1: system msr.lo 0x%x msr.hi 0x%x\n", msr.lo, msr.hi);
+               printk_debug("GLPCI r1: system msr.lo 0x%08x msr.hi 0x%08x\n", msr.lo, msr.hi);
                msrnum = GLPCI_RC1;
                wrmsr(msrnum, msr);
        }
@@ -506,12 +514,12 @@ performance:
 
        for(i = 0; gating->msrnum != 0xffffffff; i++) {
                msr = rdmsr(gating->msrnum);
-               printk_debug("%s: MSR 0x%x is 0x%x:0x%x\n", __FUNCTION__, gating->msrnum, msr.hi, msr.lo);
+               printk_debug("%s: MSR 0x%08x is 0x%08x:0x%08x\n", __FUNCTION__, gating->msrnum, msr.hi, msr.lo);
                msr.hi |= gating->msr.hi;
                msr.lo |= gating->msr.lo;
-               printk_debug("%s: MSR 0x%x will be set to  0x%x:0x%x\n", __FUNCTION__, 
+               printk_debug("%s: MSR 0x%08x will be set to  0x%08x:0x%08x\n", __FUNCTION__, 
                        gating->msrnum, msr.hi, msr.lo);
-               wrmsr(gating->msrnum, msr);
+               wrmsr(gating->msrnum, msr);     // MSR - See the table above
                gating +=1;
        }
 
@@ -525,32 +533,251 @@ GeodeLinkPriority(void){
 
        for(i = 0; prio->msrnum != 0xffffffff; i++) {
                msr = rdmsr(prio->msrnum);
-               printk_debug("%s: MSR 0x%x is 0x%x:0x%x\n", __FUNCTION__, prio->msrnum, msr.hi, msr.lo);
+               printk_debug("%s: MSR 0x%08x is 0x%08x:0x%08x\n", __FUNCTION__, prio->msrnum, msr.hi, msr.lo);
                msr.hi |= prio->msr.hi;
                msr.lo &= ~0xfff;
                msr.lo |= prio->msr.lo;
-               printk_debug("%s: MSR 0x%x will be set to  0x%x:0x%x\n", __FUNCTION__, 
+               printk_debug("%s: MSR 0x%08x will be set to 0x%08x:0x%08x\n", __FUNCTION__, 
                        prio->msrnum, msr.hi, msr.lo);
-               wrmsr(prio->msrnum, msr);
+               wrmsr(prio->msrnum, msr);       // MSR - See the table above
                prio +=1;
        }
 }
+
+
        
-       /* ***************************************************************************/
-       /* **/
-       /* *    northBridgeInit*/
-       /* **/
-       /* *    Core Logic initialization:  Host bridge*/
-       /* **/
-       /* *    Entry:*/
-       /* *    Exit:*/
-       /* *    Modified:*/
-       /* **/
-       /* ***************************************************************************/
+/*
+ *     Get the GLIU0 shadow register settings
+ *     If the setShadow function is used then all shadow descriptors
+ *       will stay sync'ed.
+ */
+static uint64_t getShadow(void)
+{
+       msr_t msr;
+       msr = rdmsr(MSR_GLIU0_SHADOW);
+       return ( ( (uint64_t) msr.hi ) << 32 ) | msr.lo;
+}
+
+
+/*
+ *     Set the cache RConf registers for the memory hole.
+ *     Keeps all cache shadow descriptors sync'ed.
+ *     This is part of the PCI lockup solution
+ *     Entry: EDX:EAX is the shadow settings
+ */
+static void setShadowRCONF(uint32_t shadowHi, uint32_t shadowLo)
+{
+       // ok this is whacky bit translation time.
+       int bit;
+       uint8_t shadowByte;
+       msr_t msr;
+       shadowByte = (uint8_t) (shadowLo >> 16);
+
+       // load up D000 settings in edx.
+       for (bit = 8; (bit > 4); bit--) {
+               msr.hi <<= 8;
+               msr.hi |= 1;                                            // cache disable PCI/Shadow memory
+               if (shadowByte && (1 << bit))
+                       msr.hi |= 0x20;                                 // write serialize PCI memory
+       }
+
+       // load up C000 settings in eax.
+       for ( ; bit; bit--) {
+               msr.lo <<= 8;
+               msr.lo |= 1;                                            // cache disable PCI/Shadow memory
+               if (shadowByte && (1 << bit))
+                       msr.lo |= 0x20;                                 // write serialize PCI memory
+       }
+
+       wrmsr(CPU_RCONF_C0_DF, msr);
+
+       shadowByte = (uint8_t) (shadowLo >> 24);
+
+       // load up F000 settings in edx.
+       for (bit = 8; (bit > 4); bit--) {
+               msr.hi <<= 8;
+               msr.hi |= 1;                                            // cache disable PCI/Shadow memory
+               if (shadowByte && (1 << bit))
+                       msr.hi |= 0x20;                                 // write serialize PCI memory
+       }
+
+       // load up E000 settings in eax.
+       for ( ; bit; bit--) {
+               msr.lo <<= 8;
+               msr.lo |= 1;                                            // cache disable PCI/Shadow memory
+               if (shadowByte && (1 << bit))
+                       msr.lo |= 0x20;                                 // write serialize PCI memory
+       }
+
+       wrmsr(CPU_RCONF_E0_FF, msr);
+}
+
+
+/*
+ *     Set the GLPCI registers for the memory hole.
+ *     Keeps all cache shadow descriptors sync'ed.
+ *     Entry: EDX:EAX is the shadow settings
+ */
+static void setShadowGLPCI(uint32_t shadowHi, uint32_t shadowLo)
+{
+       msr_t msr;
+       
+// Set the Enable Register.
+
+       msr = rdmsr(GLPCI_REN);
+       msr.lo &= 0xFFFF00FF;
+       msr.lo |= ( (shadowLo & 0xFFFF0000) >> 8);
+       wrmsr(GLPCI_REN, msr);
+}
+
+
+/*
+ *     Set the GLIU SC register settings. Scans descriptor tables for SC_SHADOW.
+ *     Keeps all shadow descriptors sync'ed.
+ *     Entry: EDX:EAX is the shadow settings
+ */
+static void setShadow(uint64_t shadowSettings)
+{
+       int i;
+       msr_t msr;
+       struct gliutable* pTable;
+       uint32_t shadowLo, shadowHi;
+
+       shadowLo = (uint32_t) shadowSettings;
+       shadowHi = (uint32_t) (shadowSettings >> 32);
+
+       setShadowRCONF(shadowHi, shadowLo);
+       setShadowGLPCI(shadowHi, shadowLo);
+
+       for(i = 0; gliutables[i]; i++) {
+               for (pTable = gliutables[i]; pTable->desc_type != GL_END; pTable++) {
+                       if (pTable->desc_type == SC_SHADOW) {
+
+                               msr = rdmsr(pTable->desc_name);
+                               msr.lo = (uint32_t) shadowSettings;
+                               msr.hi &= 0xFFFF0000;           // maintain PDID in upper EDX
+                               msr.hi |= ((uint32_t) (shadowSettings >> 32)) & 0x0000FFFF;
+                               wrmsr(pTable->desc_name, msr);  // MSR - See the table above
+
+                       }
+               }
+       }
+}
+
+/**************************************************************************
+ *
+ *     shadowRom
+ *
+ *     Set up a stack for ease of further testing
+ *
+ *     Entry:
+ *     Exit:
+ *     Destroys:
+ *
+ **************************************************************************/
+static void 
+shadowRom(void)
+{
+       uint64_t shadowSettings = getShadow();
+       shadowSettings &= (uint64_t) 0xFFFF00000000FFFFULL;     // Disable read & writes
+       shadowSettings |= (uint64_t) 0x00000000F0000000ULL;     // Enable reads for F0000-FFFFF
+       setShadow(shadowSettings);
+}
+
+
+
+/***************************************************************************
+ *
+ * RCONFInit
+ *       Set up RCONF_DEFAULT and any other RCONF registers needed
+ *
+ *  DEVRC_RCONF_DEFAULT:
+ *  ROMRC(63:56) = 04h  ; write protect ROMBASE
+ *  ROMBASE(36:55) = 0FFFC0h ; Top of PCI/bottom of rom chipselect area
+ *  DEVRC(35:28) =  39h         ; cache disabled in PCI memory + WS bit on + Write Combine + write burst.
+ *  SYSTOP(27:8) = top of system memory
+ *  SYSRC(7:0) = 00h            ; writeback, can set to 08h to make writethrough 
+ *
+ ***************************************************************************/
+#define SYSMEM_RCONF_WRITETHROUGH 8
+#define DEVRC_RCONF_DEFAULT 0x21
+#define ROMBASE_RCONF_DEFAULT 0xFFFC0000
+#define ROMRC_RCONF_DEFAULT 0x25
+
+static void
+RCONFInit(void)
+{
+       struct gliutable *gl = 0;
+       int i;
+       msr_t msr;
+       uint8_t SysMemCacheProp;
+       uint8_t RegionProp;
+
+       /* Locate SYSMEM entry in GLIU0table */
+       for(i = 0; gliu0table[i].desc_name != GL_END; i++) {
+               if (gliu0table[i].desc_type == R_SYSMEM) {
+                       gl = &gliu0table[i];
+                       break;
+               }
+       }
+       if (gl == 0) {
+               post_code(0xCE);                /* POST_RCONFInitError */
+               while (1);
+       }
+
+// sysdescfound:       
+       /* found the descriptor... get its contents */
+       msr = rdmsr(gl->desc_name);
+
+       /* 20 bit address -  The bottom 12 bits go into bits 20-31 in eax, the 
+        * top 8 bits go into 0-7 of edx. 
+        */
+       msr.lo = (msr.lo & 0xFFFFFF00) | (msr.hi & 0xFF);
+       msr.lo = ((msr.lo << 12) | (msr.lo >> 20)) & 0x000FFFFF;
+       msr.lo <<= RCONF_DEFAULT_LOWER_SYSTOP_SHIFT;    // 8
+       
+       // Set Default SYSMEM region properties
+       msr.lo &= ~SYSMEM_RCONF_WRITETHROUGH;   // 8 (or ~8)
+
+       // Set PCI space cache properties
+       msr.hi = (DEVRC_RCONF_DEFAULT >> 4);    // only need the bottom bits and lets clean the rest of edx
+       msr.lo |= (DEVRC_RCONF_DEFAULT << 28);
+
+       // Set the ROMBASE. This is usually FFFC0000h
+       msr.hi |= (ROMBASE_RCONF_DEFAULT >> 12) << RCONF_DEFAULT_UPPER_ROMBASE_SHIFT;
+
+       // Set ROMBASE cache properties.
+       msr.hi |= ((ROMRC_RCONF_DEFAULT >> 8) | (ROMRC_RCONF_DEFAULT << 24));
+       
+       // now program RCONF_DEFAULT
+       wrmsr(CPU_RCONF_DEFAULT, msr);
+
+       // RCONF_BYPASS: Cache tablewalk properties and SMM/DMM header access properties.
+       // Set to match system memory cache properties.
+       msr = rdmsr(CPU_RCONF_DEFAULT);
+       SysMemCacheProp = (uint8_t) (msr.lo & 0xFF);
+       msr = rdmsr(CPU_RCONF_BYPASS);
+       msr.lo = (msr.lo & 0xFFFF0000) | (SysMemCacheProp << 8) | SysMemCacheProp;
+       wrmsr(CPU_RCONF_BYPASS, msr);
+}
+
+
+/* ***************************************************************************/
+/* **/
+/* *   northBridgeInit*/
+/* **/
+/* *   Core Logic initialization:  Host bridge*/
+/* **/
+/* *   Entry:*/
+/* *   Exit:*/
+/* *   Modified:*/
+/* **/
+/* ***************************************************************************/
 
 void
 northbridgeinit(void)
 {
+       msr_t msr;
        int i;
        printk_debug("Enter %s\n", __FUNCTION__);
 
@@ -558,10 +785,25 @@ northbridgeinit(void)
                GLIUInit(gliutables[i]);
 
        GeodeLinkPriority();
-
-
+       
+       shadowRom();
+       
+       // GeodeROM ensures that the BIOS waits the required 1 second before 
+       // allowing anything to access PCI
+       // PCIDelay();
+       
+       RCONFInit();
+       
+       // The cacheInit function in GeodeROM tests cache and, among other things,
+       // makes sure all INVD instructions are treated as WBINVD.  We do this
+       // because we've found some programs which require this behavior.
+       // That subset of cacheInit() is implemented here:
+       msr = rdmsr(CPU_DM_CONFIG0);
+       msr.lo |= DM_CONFIG0_LOWER_WBINVD_SET;
+       wrmsr(CPU_DM_CONFIG0, msr);
+       
        /*  Now that the descriptor to memory is set up.*/
-       /*  The memory controller needs one read to synch it's lines before it can be used.*/
+       /*  The memory controller needs one read to synch its lines before it can be used.*/
        i = *(int *) 0;
 
        GLPCIInit();
index 9f030c9710274249c8a9ebcd0686fc36d9c4b04e..ab9725865e86d31320fd1b3e73a54723dfc197bb 100644 (file)
@@ -1,3 +1,5 @@
+#include <cpu/amd/gx2def.h>
+
 /*
  *
  * cs5536_early_setup.c:       Early chipset initialization for CS5536 companion device
index 541e9bf1eb534a536231607ccfadda43a66c5f65..de7f94193ff4058c161ca696aa0efcdc7eb54c42 100644 (file)
@@ -4,15 +4,15 @@ target rev_a
 mainboard olpc/rev_a
 
 # leave 64k for vsa
-#option CONFIG_COMPRESSED_ROM_STREAM=1
-option ROM_SIZE=1024*512-35*1024
+option CONFIG_COMPRESSED_ROM_STREAM=0
+option ROM_SIZE=1024*512-64*1024
 option FALLBACK_SIZE=ROM_SIZE
 
-option DEFAULT_CONSOLE_LOGLEVEL = 8
-option MAXIMUM_CONSOLE_LOGLEVEL = 8
+option DEFAULT_CONSOLE_LOGLEVEL = 11
+option MAXIMUM_CONSOLE_LOGLEVEL = 11
 romimage "fallback" 
        option USE_FALLBACK_IMAGE=1
-       option ROM_IMAGE_SIZE=28*1024
+       option ROM_IMAGE_SIZE=32*1024
        option LINUXBIOS_EXTRA_VERSION=".0Fallback"
        payload /tmp/olpcpayload.elf
 end