diff options
Diffstat (limited to 'src/northbridge/amd/gx2/northbridgeinit.c')
-rw-r--r-- | src/northbridge/amd/gx2/northbridgeinit.c | 673 |
1 files changed, 0 insertions, 673 deletions
diff --git a/src/northbridge/amd/gx2/northbridgeinit.c b/src/northbridge/amd/gx2/northbridgeinit.c deleted file mode 100644 index 3b020165b3..0000000000 --- a/src/northbridge/amd/gx2/northbridgeinit.c +++ /dev/null @@ -1,673 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Advanced Micro Devices, Inc. - * Copyright (C) 2010 Nils Jacobs - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include <console/console.h> -#include <arch/io.h> -#include <stdint.h> -#include <device/device.h> -#include <device/pci.h> -#include <device/pci_ids.h> -#include <stdlib.h> -#include <string.h> -#include "northbridge.h" -#include <cpu/amd/gx2def.h> -#include <cpu/x86/msr.h> -#include <cpu/x86/cache.h> - -struct gliutable -{ - unsigned long desc_name; - unsigned short desc_type; - unsigned long hi, lo; -}; - -struct gliutable gliu0table[] = { - {.desc_name = GLIU0_P2D_BM_0, .desc_type= BM,.hi= MSR_MC + 0x0,.lo= 0x0FFF80}, /* 0-7FFFF to MC */ - {.desc_name = GLIU0_P2D_BM_1, .desc_type= BM,.hi= MSR_MC + 0x0,.lo=(0x80 << 20) + 0x0FFFE0}, /* 80000-9ffff to Mc */ - {.desc_name = GLIU0_P2D_SC_0, .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 = GLIU0_P2D_R_0, .desc_type= R_SYSMEM,.hi= MSR_MC,.lo= 0x0}, /* Catch and fix dynamicly. */ - {.desc_name = GLIU0_P2D_BMO_0, .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}, -}; - -struct gliutable gliu1table[] = { - {.desc_name = GLIU1_P2D_BM_0, .desc_type= BM,.hi= MSR_GL0 + 0x0,.lo= 0x0FFF80}, /* 0-7FFFF to MC */ - {.desc_name = GLIU1_P2D_BM_1, .desc_type= BM,.hi= MSR_GL0 + 0x0,.lo= (0x80 << 20) + 0x0FFFE0},/* 80000-9ffff to Mc */ - {.desc_name = GLIU1_P2D_SC_0, .desc_type= SC_SHADOW,.hi= MSR_GL0 + 0x0,.lo= 0x03}, /* C0000-Fffff split to MC and PCI (sub decode) */ - {.desc_name = GLIU1_P2D_R_0, .desc_type= R_SYSMEM,.hi= MSR_GL0,.lo= 0x0}, /* Catch and fix dynamicly. */ - {.desc_name = GLIU1_P2D_BM_3, .desc_type= BM_SMM,.hi= MSR_GL0,.lo= 0x0}, /* Catch and fix dynamicly. */ - {.desc_name = GLIU1_GLD_MSR_COH, .desc_type= OTHER,.hi= 0x0,.lo= GL1_GLIU0}, - {.desc_name = GLIU1_IOD_SC_0, .desc_type= SCIO,.hi= (GL1_GLCP << 29) + 0x0,.lo= 0x033000F0}, /* FooGlue FPU 0xF0 */ - {.desc_name = GL_END, .desc_type= GL_END,.hi= 0x0,.lo= 0x0}, -}; - -struct gliutable *gliutables[] = { gliu0table, gliu1table, 0 }; - -struct msrinit -{ - unsigned long msrnum; - msr_t msr; -}; - -struct msrinit ClockGatingDefault[] = { - {GLIU0_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0005}}, - /* MC must stay off in SDR mode. It is turned on in CPUBug??? lotus #77.142 */ - {MC_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0000}}, - {GLIU1_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0005}}, - {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}}, - {GLPCI_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0015}}, - {FG_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0000}}, /* Always on */ - {0xffffffff, {0xffffffff, 0xffffffff}}, -}; - -/* All On */ -struct msrinit ClockGatingAllOn[] = { - {GLIU0_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0FFFFFFFF}}, - {MC_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0FFFFFFFF}}, - {GLIU1_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0FFFFFFFF}}, - {VG_GLD_MSR_PM, {.hi = 0x00, .lo = 0x00}}, - {GP_GLD_MSR_PM, {.hi = 0x00,.lo = 0x000000001}}, - {DF_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0FFFFFFFF}}, - {GLCP_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0FFFFFFFF}}, - {GLPCI_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0FFFFFFFF}}, - {FG_GLD_MSR_PM, {.hi = 0x00,.lo = 0x0000}}, - {0xffffffff, {0xffffffff, 0xffffffff}}, -}; - -/* Performance */ -struct msrinit ClockGatingPerformance[] = { - {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}}, - {0xffffffff, {0xffffffff, 0xffffffff}}, -}; - -/* 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 = 0x0027}}, /* GLPCI Priority + PID */ - {GLCP_GLD_MSR_CONF, {.hi = 0x00,.lo = 0x0001}}, /* GLCP Priority + PID */ - {FG_GLD_MSR_CONFIG, {.hi = 0x00,.lo = 0x0622}}, /* FG PID */ - {0x0FFFFFFFF, {0x0FFFFFFFF, 0x0FFFFFFFF}}, /* END */ -}; - -static void writeglmsr(struct gliutable *gl) -{ - msr_t msr; - - msr.lo = gl->lo; - msr.hi = gl->hi; - wrmsr(gl->desc_name, msr); /* MSR - see table above */ - printk(BIOS_DEBUG, "%s: MSR 0x%08lx, val 0x%08x:0x%08x\n", __func__, gl->desc_name, msr.hi, msr.lo); -} - -static void ShadowInit(struct gliutable *gl) -{ - msr_t msr; - - msr = rdmsr(gl->desc_name); - - if (msr.lo == 0) { - writeglmsr(gl); - } -} - -static void 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 now and Frame Buffer later. - */ - sizembytes = sizeram(); - printk(BIOS_DEBUG, "%s: enable for %dMBytes\n", __func__, sizembytes); - sizebytes = sizembytes << 20; - - sizebytes -= ((SMM_SIZE * 1024) + 1); - - /* 20 bit address The bottom 12 bits go into bits 20-31 in msr.lo - The top 8 bits go into 0-7 of msr.hi. */ - sizebytes --; - msr.hi = (gl->hi & 0xFFFFFF00) | (sizebytes >> 24); - sizebytes <<= 8; /* move bits 23:12 in bits 31:20. */ - sizebytes &= 0xfff00000; - sizebytes |= 0x100; /* start at 1MB */ - msr.lo = sizebytes; - wrmsr(gl->desc_name, msr); /* MSR - see table above */ - printk(BIOS_DEBUG, "%s: MSR 0x%08lx, val 0x%08x:0x%08x\n", __func__, - gl->desc_name, msr.hi, msr.lo); -} - -static void SMMGL0Init(struct gliutable *gl) -{ - msr_t msr; - int sizebytes = sizeram() << 20; - long offset; - - sizebytes -= (SMM_SIZE * 1024); - - printk(BIOS_DEBUG, "%s: %d bytes\n", __func__, sizebytes); - - offset = sizebytes - SMM_OFFSET; - offset = (offset >> 12) & 0x000fffff; - printk(BIOS_DEBUG, "%s: offset is 0x%08x\n", __func__, SMM_OFFSET); - - msr.hi = offset << 8 | gl->hi; - msr.hi |= SMM_OFFSET >> 24; - - msr.lo = (SMM_OFFSET & 0x00ffffff) << 8; - msr.lo |= ((~(SMM_SIZE * 1024) + 1) >> 12) & 0xfffff; - - wrmsr(gl->desc_name, msr); /* MSR - See table above */ - printk(BIOS_DEBUG, "%s: MSR 0x%08lx, val 0x%08x:0x%08x\n", __func__, gl->desc_name, msr.hi, msr.lo); -} - -static void SMMGL1Init(struct gliutable *gl) -{ - msr_t msr; - printk(BIOS_DEBUG, "%s:\n", __func__); - - msr.hi = gl->hi; - /* I don't think this is needed */ - msr.hi &= 0xffffff00; - msr.hi |= (SMM_OFFSET >> 24); - msr.lo = (SMM_OFFSET & 0x00fff000) << 8; - msr.lo |= ((~(SMM_SIZE * 1024) + 1) >> 12) & 0xfffff; - - wrmsr(gl->desc_name, msr); /* MSR - See table above */ - printk(BIOS_DEBUG, "%s: MSR 0x%08lx, val 0x%08x:0x%08x\n", __func__, gl->desc_name, msr.hi, msr.lo); -} - -static void GLIUInit(struct gliutable *gl) -{ - while (gl->desc_type != GL_END) { - switch (gl->desc_type) { - default: - writeglmsr(gl); - case SC_SHADOW: /* Check for a Shadow entry */ - ShadowInit(gl); - break; - - case R_SYSMEM: /* check for a SYSMEM entry */ - SysmemInit(gl); - break; - - case BMO_SMM: /* check for a SMM entry */ - SMMGL0Init(gl); - break; - - case BM_SMM: /* check for a SMM entry */ - SMMGL1Init(gl); - break; - } - gl++; - } -} - -/* Set up GLPCI settings for reads/write into memory. - * - * R0: 0-640KB, - * R1: 1MB - Top of System Memory - * R2: SMM Memory - * R3: Framebuffer? - not set up yet - * R4: ?? - */ -static void GLPCIInit(void) -{ - struct gliutable *gl = 0; - int i; - msr_t msr; - int msrnum; - - /* R0 - GLPCI settings for Conventional Memory space. */ - msr.hi = (0x09F000 >> 12) << GLPCI_RC_UPPER_TOP_SHIFT; /* 640 */ - 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); - - /* R1 - GLPCI settings for SysMem space. */ - /* Get systop from GLIU0 SYSTOP Descriptor */ - for (i = 0; gliu0table[i].desc_name != GL_END; i++) { - if (gliu0table[i].desc_type == R_SYSMEM) { - gl = &gliu0table[i]; - break; - } - } - if (gl) { - unsigned long pah, pal; - msrnum = gl->desc_name; - msr = rdmsr(msrnum); - /* example R_SYSMEM value: 20:00:00:0f:fb:f0:01:00 - * translates to a base of 0x00100000 and top of 0xffbf0000 - * base of 1M and top of around 256M - */ - /* we have to create a page-aligned (4KB page) address for base and top - * 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 - */ - pah = ((msr.hi & 0xff) << 12) | ((msr.lo >> 20) & 0xfff); - /* we have the page address. Now make it a page-aligned address */ - pah <<= 12; - - pal = msr.lo << 12; - msr.hi = pah; - msr.lo = pal; - msr.lo |= GLPCI_RC_LOWER_EN_SET | GLPCI_RC_LOWER_PF_SET | GLPCI_RC_LOWER_WC_SET; - printk(BIOS_DEBUG, "GLPCI R1: system msr.lo 0x%08x msr.hi 0x%08x\n", msr.lo, msr.hi); - msrnum = GLPCI_RC1; - wrmsr(msrnum, msr); - } - - /* R2 - GLPCI settings for SMM space. */ - msr.hi = ((SMM_OFFSET + (SMM_SIZE * 1024 - 1)) >> 12) << GLPCI_RC_UPPER_TOP_SHIFT; - msr.lo = (SMM_OFFSET >> 12) << GLPCI_RC_LOWER_BASE_SHIFT; - msr.lo |= GLPCI_RC_LOWER_EN_SET | GLPCI_RC_LOWER_PF_SET; - printk(BIOS_DEBUG, "GLPCI R2: system msr.lo 0x%08x msr.hi 0x%08x\n", msr.lo, msr.hi); - msrnum = GLPCI_RC2; - wrmsr(msrnum, msr); - - /* this is done elsewhere already, but it does no harm to do it more than once */ - /* write serialize memory hole to PCI. Need to unWS when something is shadowed regardless of cachablility. */ - msr.lo = 0x021212121; /* cache disabled and write serialized */ - msr.hi = 0x021212121; /* cache disabled and write serialized */ - - msrnum = CPU_RCONF_A0_BF; - wrmsr(msrnum, msr); - - msrnum = CPU_RCONF_C0_DF; - wrmsr(msrnum, msr); - - msrnum = CPU_RCONF_E0_FF; - wrmsr(msrnum, msr); - - /* Set Non-Cacheable Read Only for NorthBound Transactions to Memory. The Enable bit is handled in the Shadow setup. */ - msrnum = GLPCI_A0_BF; - msr.hi = 0x35353535; - msr.lo = 0x35353535; - wrmsr(msrnum, msr); - - msrnum = GLPCI_C0_DF; - msr.hi = 0x35353535; - msr.lo = 0x35353535; - wrmsr(msrnum, msr); - - msrnum = GLPCI_E0_FF; - msr.hi = 0x35353535; - msr.lo = 0x35353535; - wrmsr(msrnum, msr); - - /* Set WSREQ */ - msrnum = CPU_DM_CONFIG0; - msr = rdmsr(msrnum); - msr.hi &= ~(7 << DM_CONFIG0_UPPER_WSREQ_SHIFT); - msr.hi |= 2 << DM_CONFIG0_UPPER_WSREQ_SHIFT ; /* reduce to 1 for safe mode. */ - wrmsr(msrnum, msr); - - /* we are ignoring the 5530 case for now, and perhaps forever. */ - - /* 553X NB Init */ - - /* Arbiter setup */ - msrnum = GLPCI_ARB; - msr = rdmsr(msrnum); - msr.hi |= GLPCI_ARB_UPPER_PRE0_SET | GLPCI_ARB_UPPER_PRE1_SET; - msr.lo |= GLPCI_ARB_LOWER_IIE_SET; - wrmsr(msrnum, msr); - - msrnum = GLPCI_CTRL; - msr = rdmsr(msrnum); - - msr.lo |= GLPCI_CTRL_LOWER_ME_SET | GLPCI_CTRL_LOWER_OWC_SET | GLPCI_CTRL_LOWER_PCD_SET; /* (Out will be disabled in CPUBUG649 for < 2.0 parts .) */ - msr.lo |= GLPCI_CTRL_LOWER_LDE_SET; - - msr.lo &= ~(0x03 << GLPCI_CTRL_LOWER_IRFC_SHIFT); - msr.lo |= 0x02 << GLPCI_CTRL_LOWER_IRFC_SHIFT; - - msr.lo &= ~(0x07 << GLPCI_CTRL_LOWER_IRFT_SHIFT); - msr.lo |= 0x06 << GLPCI_CTRL_LOWER_IRFT_SHIFT; - - msr.hi &= ~(0x0f << GLPCI_CTRL_UPPER_FTH_SHIFT); - msr.hi |= 0x0F << GLPCI_CTRL_UPPER_FTH_SHIFT; - - msr.hi &= ~(0x0f << GLPCI_CTRL_UPPER_RTH_SHIFT); - msr.hi |= 0x0F << GLPCI_CTRL_UPPER_RTH_SHIFT; - - msr.hi &= ~(0x0f << GLPCI_CTRL_UPPER_SBRTH_SHIFT); - msr.hi |= 0x0F << GLPCI_CTRL_UPPER_SBRTH_SHIFT; - - msr.hi &= ~(0x03 << GLPCI_CTRL_UPPER_WTO_SHIFT); - msr.hi |= 0x06 << GLPCI_CTRL_UPPER_WTO_SHIFT; - - msr.hi &= ~(0x03 << GLPCI_CTRL_UPPER_ILTO_SHIFT); - msr.hi |= 0x00 << GLPCI_CTRL_UPPER_ILTO_SHIFT; - wrmsr(msrnum, msr); - - /* Set GLPCI Latency Timer. */ - msrnum = GLPCI_CTRL; - msr = rdmsr(msrnum); - msr.hi |= 0x1F << GLPCI_CTRL_UPPER_LAT_SHIFT; /* Change once 1.x is gone. */ - wrmsr(msrnum, msr); - - /* GLPCI_SPARE */ - msrnum = GLPCI_SPARE; - msr = rdmsr(msrnum); - msr.lo &= ~0x7; - msr.lo |= GLPCI_SPARE_LOWER_AILTO_SET | GLPCI_SPARE_LOWER_PPD_SET | GLPCI_SPARE_LOWER_PPC_SET | GLPCI_SPARE_LOWER_MPC_SET | GLPCI_SPARE_LOWER_NSE_SET | GLPCI_SPARE_LOWER_SUPO_SET; - wrmsr(msrnum, msr); -} - -/* Enable Clock Gating. */ -static void ClockGatingInit(void) -{ - msr_t msr; - struct msrinit *gating = ClockGatingDefault; - int i; - - for (i = 0; gating->msrnum != 0xffffffff; i++) { - msr = rdmsr(gating->msrnum); - msr.hi |= gating->msr.hi; - msr.lo |= gating->msr.lo; - wrmsr(gating->msrnum, msr); /* MSR - See the table above */ - gating += 1; - } -} - -static void GeodeLinkPriority(void) -{ - msr_t msr = { 0, 0 }; - - struct msrinit *prio = GeodeLinkPriorityTable; - int i; - - for (i = 0; prio->msrnum != 0xffffffff; i++) { - msr = rdmsr(prio->msrnum); - msr.hi |= prio->msr.hi; - msr.lo &= ~0xfff; - msr.lo |= prio->msr.lo; - wrmsr(prio->msrnum, msr); /* MSR - See the table above */ - prio += 1; - } -} - -/* 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 = { 0, 0 }; - - msr = rdmsr(GLIU0_P2D_SC_0); - 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 = { 0, 0 }; - 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 */ - - } - } - } -} - -static void rom_shadow_settings(void) -{ - uint64_t shadowSettings = getShadow(); - shadowSettings &= (uint64_t) 0xFFFF00000000FFFFULL; /* Disable read & writes */ - shadowSettings |= (uint64_t) 0x0000FFFFFFFF0000ULL; /* Enable reads for C0000-FFFFF */ - setShadow(shadowSettings); -} - -/* 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 0x21ul -#define ROMBASE_RCONF_DEFAULT 0xFFFC0000 -#define ROMRC_RCONF_DEFAULT 0x25 - -static void enable_L_cache(void) -{ - struct gliutable *gl = 0; - int i; - msr_t msr; - uint8_t SysMemCacheProp; - - /* 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: */ - 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; /* NOT writethrough == writeback 8 (or ~8) */ - - /* Set PCI space cache properties */ - msr.hi = (DEVRC_RCONF_DEFAULT >> 4); /* setting is split betwwen hi and lo... */ - 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); - printk(BIOS_DEBUG, "CPU_RCONF_DEFAULT (1808): 0x%08X:0x%08X\n", msr.hi, msr.lo); - - /* RCONF_BYPASS: Cache tablewalk properties and SMM 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); - printk(BIOS_DEBUG, "CPU_RCONF_BYPASS (180A): 0x%08x : 0x%08x\n", msr.hi, msr.lo); -} - -static void setup_gx2_cache(void) -{ - msr_t msr; - - enable_L_cache(); - - /* Make sure all INVD instructions are treated as WBINVD. We do this - * because we've found some programs which require this behavior. - */ - msr = rdmsr(CPU_DM_CONFIG0); - msr.lo |= DM_CONFIG0_LOWER_WBINVD_SET; - wrmsr(CPU_DM_CONFIG0, msr); - - x86_enable_cache(); - wbinvd(); -} - -uint32_t get_systop(void) -{ - struct gliutable *gl = 0; - uint32_t systop; - msr_t msr; - int i; - - for (i = 0; gliu0table[i].desc_name != GL_END; i++) { - if (gliu0table[i].desc_type == R_SYSMEM) { - gl = &gliu0table[i]; - break; - } - } - if (gl) { - msr = rdmsr(gl->desc_name); - systop = ((msr.hi & 0xFF) << 24) | ((msr.lo & 0xFFF00000) >> 8); - systop += 0x1000; /* 4K */ - } else { - systop = - ((sizeram() - CONFIG_VIDEO_MB) * 1024) - SMM_SIZE - 1024; - } - return systop; -} - -/* Core Logic initialization: Host bridge. */ -void northbridge_init_early(void) -{ - int i; - printk(BIOS_DEBUG, "Enter %s\n", __func__); - - for (i = 0; gliutables[i]; i++) - GLIUInit(gliutables[i]); - - /* Now that the descriptor to memory is set up. */ - /* The memory controller needs one read to synch its lines before it can be used. */ - read32(zeroptr); - - GeodeLinkPriority(); - - setup_gx2_cache(); - - rom_shadow_settings(); - - GLPCIInit(); - - ClockGatingInit(); - - __asm__ __volatile__("FINIT\n"); - printk(BIOS_DEBUG, "Exit %s\n", __func__); -} |