changes from AMD for making OLPC video work.
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@2316 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
parent
890ee09a32
commit
fb93749642
|
@ -31,25 +31,46 @@ bug573(void){
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
static void
|
||||||
pcideadlock(void)
|
pcideadlock(void)
|
||||||
{
|
{
|
||||||
msr_t msr;
|
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 = rdmsr(CPU_DM_CONFIG0);
|
||||||
msr.hi &= ~(7<<DM_CONFIG0_UPPER_WSREQ_SHIFT);
|
msr.hi &= ~(7<<DM_CONFIG0_UPPER_WSREQ_SHIFT);
|
||||||
msr.hi |= (2<<DM_CONFIG0_UPPER_WSREQ_SHIFT);
|
msr.hi |= (2<<DM_CONFIG0_UPPER_WSREQ_SHIFT);
|
||||||
msr.lo |= DM_CONFIG0_LOWER_MISSER_SET;
|
msr.lo |= DM_CONFIG0_LOWER_MISSER_SET;
|
||||||
wrmsr(CPU_DM_CONFIG0, msr);
|
wrmsr(CPU_DM_CONFIG0, msr);
|
||||||
|
|
||||||
msr = rdmsr(CPU_IM_CONFIG);
|
/* interlock instruction fetches to WS regions with data accesses.
|
||||||
msr.lo |= IM_CONFIG_LOWER_QWT_SET; /* interlock instruction fetches to WS regions with data accesses.
|
* This prevents an instruction fetch from going out to PCI if the
|
||||||
* This prevents in instruction fetch from going out to PCI if the
|
|
||||||
* data side is about to make a request.
|
* data side is about to make a request.
|
||||||
*/
|
*/
|
||||||
|
msr = rdmsr(CPU_IM_CONFIG);
|
||||||
|
msr.lo |= IM_CONFIG_LOWER_QWT_SET;
|
||||||
wrmsr(CPU_IM_CONFIG, msr);
|
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.lo = 0x021212121;
|
||||||
msr.hi = 0x021212121;
|
msr.hi = 0x021212121;
|
||||||
wrmsr( CPU_RCONF_A0_BF, msr);
|
wrmsr( CPU_RCONF_A0_BF, msr);
|
||||||
|
@ -57,18 +78,18 @@ pcideadlock(void)
|
||||||
wrmsr( CPU_RCONF_E0_FF, msr);
|
wrmsr( CPU_RCONF_E0_FF, msr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************
|
||||||
/***/
|
*
|
||||||
/** CPUbug784*/
|
* CPUbug784
|
||||||
/***/
|
*
|
||||||
/** Bugtool #784 + #792*/
|
* Bugtool #784 + #792
|
||||||
/***/
|
*
|
||||||
/** Fix CPUID instructions for < 3.0 CPUs*/
|
* Fix CPUID instructions for < 3.0 CPUs
|
||||||
/***/
|
*
|
||||||
/** Entry:*/
|
* Entry:
|
||||||
/** Exit:*/
|
* Exit:
|
||||||
/** Modified:*/
|
* Modified:
|
||||||
/***/
|
*
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
|
|
||||||
void bug784(void)
|
void bug784(void)
|
||||||
|
@ -99,18 +120,31 @@ void bug784(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* cpubug 1398: enable MC if we KNOW we have DDR*/
|
/* 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)
|
void eng1398(void)
|
||||||
{
|
{
|
||||||
msr_t msr;
|
msr_t msr;
|
||||||
|
|
||||||
msr = rdmsr(MSR_GLCP+0x17);
|
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);
|
msr = rdmsr(GLCP_SYS_RSTPLL);
|
||||||
if (msr.lo & (1<<RSTPPL_LOWER_SDRMODE_SHIFT))
|
if (msr.lo & (1<<RSTPPL_LOWER_SDRMODE_SHIFT))
|
||||||
return;
|
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 = rdmsr(MC_GLD_MSR_PM);
|
||||||
msr.lo |= 3; /* enable MC clock gating.*/
|
msr.lo |= 3; /* enable MC clock gating.*/
|
||||||
wrmsr(MC_GLD_MSR_PM, msr);
|
wrmsr(MC_GLD_MSR_PM, msr);
|
||||||
|
|
|
@ -80,7 +80,10 @@ cpuRegInit (void){
|
||||||
msr_t msr;
|
msr_t msr;
|
||||||
/* Turn on BTM for early debug based on setup. */
|
/* Turn on BTM for early debug based on setup. */
|
||||||
/*if (getnvram( TOKEN_BTM_DIAG_MODE) & 3) {*/
|
/*if (getnvram( TOKEN_BTM_DIAG_MODE) & 3) {*/
|
||||||
{
|
/*
|
||||||
|
* The following is only for diagnostics mode; do not use for OLPC
|
||||||
|
*/
|
||||||
|
if (0) {
|
||||||
/* Set Diagnostic Mode */
|
/* Set Diagnostic Mode */
|
||||||
msrnum = CPU_GLD_MSR_DIAG;
|
msrnum = CPU_GLD_MSR_DIAG;
|
||||||
msr.hi = 0;
|
msr.hi = 0;
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#undef __KERNEL__
|
#undef __KERNEL__
|
||||||
#include <arch/io.h>
|
#include <arch/io.h>
|
||||||
#include <string.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
|
/* 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
|
* was done, but can't fix it yet. RGM
|
||||||
|
@ -335,7 +336,7 @@ void do_vsmbios(void)
|
||||||
unsigned long busdevfn;
|
unsigned long busdevfn;
|
||||||
unsigned int rom = 0;
|
unsigned int rom = 0;
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
unsigned int size = 256*1024;
|
unsigned int size = SMM_SIZE*1024;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
printk_err("do_vsmbios\n");
|
printk_err("do_vsmbios\n");
|
||||||
|
@ -353,12 +354,12 @@ void do_vsmbios(void)
|
||||||
//rom = 0xfff80000;
|
//rom = 0xfff80000;
|
||||||
//rom = 0xfffc0000;
|
//rom = 0xfffc0000;
|
||||||
/* the VSA starts at the base of rom - 64 */
|
/* 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;
|
buf = (unsigned char *) 0x60000;
|
||||||
unrv2b((uint8_t *)rom, buf);
|
unrv2b((uint8_t *)rom, buf);
|
||||||
printk_debug("buf %p *buf %d buf[256k] %d\n",
|
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",
|
printk_debug("buf[0x20] signature is %x:%x:%x:%x\n",
|
||||||
buf[0x20] ,buf[0x21] ,buf[0x22],buf[0x23]);
|
buf[0x20] ,buf[0x21] ,buf[0x22],buf[0x23]);
|
||||||
/* check for post code at start of vsainit.bin. If you don't see it,
|
/* check for post code at start of vsainit.bin. If you don't see it,
|
||||||
|
|
|
@ -75,22 +75,22 @@
|
||||||
#define GL1_VIP 5
|
#define GL1_VIP 5
|
||||||
#define GL1_AES 6
|
#define GL1_AES 6
|
||||||
|
|
||||||
#define MSR_GLIU0 (GL0_GLIU0 << 29) + (1 << 28) /* To get on GeodeLink one bit has to be set */
|
#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)
|
#define MSR_MC (GL0_MC << 29) /* 2000xxxx */
|
||||||
#define MSR_GLIU1 (GL0_GLIU1 << 29)
|
#define MSR_GLIU1 (GL0_GLIU1 << 29) /* 4000xxxx */
|
||||||
#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_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)
|
#define MSR_VG (GL0_VG << 29) /* 8000xxxx */
|
||||||
#define MSR_GP (GL0_GP << 29)
|
#define MSR_GP (GL0_GP << 29) /* A000xxxx */
|
||||||
#define MSR_DF (GL0_DF << 29)
|
#define MSR_DF (GL0_DF << 29) /* C000xxxx */
|
||||||
|
|
||||||
#define MSR_GLCP (GL1_GLCP << 26) + MSR_GLIU1
|
#define MSR_GLCP (GL1_GLCP << 26) + MSR_GLIU1 /* 4C00xxxx */
|
||||||
#define MSR_PCI (GL1_PCI << 26) + MSR_GLIU1
|
#define MSR_PCI (GL1_PCI << 26) + MSR_GLIU1 /* 5000xxxx */
|
||||||
#define MSR_FG (GL1_FG << 26) + MSR_GLIU1
|
#define MSR_FG (GL1_FG << 26) + MSR_GLIU1 /* 5400xxxx */
|
||||||
#define MSR_VIP ((GL1_VIP << 26) + MSR_GLIU1)
|
#define MSR_VIP ((GL1_VIP << 26) + MSR_GLIU1) /* 5400xxxx */
|
||||||
#define MSR_AES ((GL1_AES << 26) + MSR_GLIU1)
|
#define MSR_AES ((GL1_AES << 26) + MSR_GLIU1) /* 5800xxxx */
|
||||||
/* South Bridge*/
|
/* South Bridge*/
|
||||||
#define SB_PORT 2 /* port of the SouthBridge */
|
#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.*/
|
#define SB_SHIFT 20 /* 29 -> 26 -> 23 -> 20...... When making a SB address uses this shift.*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -485,7 +485,7 @@
|
||||||
|
|
||||||
/* definitions that are "once you are mostly up, start VSA" type things */
|
/* definitions that are "once you are mostly up, start VSA" type things */
|
||||||
#define SMM_OFFSET 0x40400000
|
#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_OFFSET 0x0C0000000
|
||||||
#define DMM_SIZE 128
|
#define DMM_SIZE 128
|
||||||
#define FB_OFFSET 0x41000000
|
#define FB_OFFSET 0x41000000
|
||||||
|
@ -706,14 +706,14 @@
|
||||||
|
|
||||||
/* SouthBridge Equates*/
|
/* SouthBridge Equates*/
|
||||||
/* MSR_SB and SB_SHIFT are located in CPU.inc*/
|
/* 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_GLIU ((9 << 14) + MSR_SB) /* 51024xxx or 510*xxxx - fake out just like GL0 on CPU. */
|
||||||
#define MSR_SB_GLPCI ( MSR_SB /* don't go to the GLIU*/)
|
#define MSR_SB_GLPCI (MSR_SB) /* 5100xxxx - don't go to the GLIU */
|
||||||
#define MSR_SB_USB2 ( (2 << SB_SHIFT) + MSR_SB)
|
#define MSR_SB_USB2 ((2 << SB_SHIFT) + MSR_SB) /* 5120xxxx */
|
||||||
#define MSR_SB_ATA ( (3 << SB_SHIFT) + MSR_SB)
|
#define MSR_SB_ATA ((3 << SB_SHIFT) + MSR_SB) /* 5130xxxx */
|
||||||
#define MSR_SB_MDD ( (4 << SB_SHIFT) + MSR_SB)
|
#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)
|
#define MSR_SB_AC97 ((5 << SB_SHIFT) + MSR_SB) /* 5150xxxx */
|
||||||
#define MSR_SB_USB1 ( (6 << SB_SHIFT) + MSR_SB)
|
#define MSR_SB_USB1 ((6 << SB_SHIFT) + MSR_SB) /* 5160xxxx */
|
||||||
#define MSR_SB_GLCP ( (7 << SB_SHIFT) + MSR_SB)
|
#define MSR_SB_GLCP ((7 << SB_SHIFT) + MSR_SB) /* 5170xxxx */
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
/* GLIU*/
|
/* GLIU*/
|
||||||
|
|
|
@ -2,3 +2,4 @@ config chip.h
|
||||||
object northbridge.o
|
object northbridge.o
|
||||||
object northbridgeinit.o
|
object northbridgeinit.o
|
||||||
object chipsetinit.o
|
object chipsetinit.o
|
||||||
|
object grphinit.o
|
||||||
|
|
|
@ -210,7 +210,6 @@ chipsetinit (void){
|
||||||
|
|
||||||
outb( P80_CHIPSET_INIT, 0x80);
|
outb( P80_CHIPSET_INIT, 0x80);
|
||||||
ChipsetGeodeLinkInit();
|
ChipsetGeodeLinkInit();
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* we hope NEVER to be in linuxbios when S3 resumes
|
/* we hope NEVER to be in linuxbios when S3 resumes
|
||||||
if (! IsS3Resume()) */
|
if (! IsS3Resume()) */
|
||||||
|
@ -230,8 +229,8 @@ chipsetinit (void){
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* for later ... if 5536 set_usb_20(); */
|
|
||||||
|
|
||||||
|
if (!is_5536()) {
|
||||||
/* Setup USB. Need more details. #118.18*/
|
/* Setup USB. Need more details. #118.18*/
|
||||||
msrnum = MSR_SB_USB1 + 8;
|
msrnum = MSR_SB_USB1 + 8;
|
||||||
msr.lo = 0x00012090;
|
msr.lo = 0x00012090;
|
||||||
|
@ -239,6 +238,7 @@ chipsetinit (void){
|
||||||
wrmsr(msrnum, msr);
|
wrmsr(msrnum, msr);
|
||||||
msrnum = MSR_SB_USB2 + 8;
|
msrnum = MSR_SB_USB2 + 8;
|
||||||
wrmsr(msrnum, msr);
|
wrmsr(msrnum, msr);
|
||||||
|
}
|
||||||
|
|
||||||
/* set hd IRQ */
|
/* set hd IRQ */
|
||||||
outl (GPIOL_2_SET, GPIOL_INPUT_ENABLE);
|
outl (GPIOL_2_SET, GPIOL_INPUT_ENABLE);
|
||||||
|
@ -270,7 +270,7 @@ chipsetinit (void){
|
||||||
for(; csi->msrnum; csi++){
|
for(; csi->msrnum; csi++){
|
||||||
msr.lo = csi->msr.lo;
|
msr.lo = csi->msr.lo;
|
||||||
msr.hi = csi->msr.hi;
|
msr.hi = csi->msr.hi;
|
||||||
wrmsr(csi->msrnum, msr);
|
wrmsr(csi->msrnum, msr); // MSR - see table above
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -293,7 +293,7 @@ chipsetinit (void){
|
||||||
for(; csi->msrnum; csi++){
|
for(; csi->msrnum; csi++){
|
||||||
msr.lo = csi->msr.lo;
|
msr.lo = csi->msr.lo;
|
||||||
msr.hi = csi->msr.hi;
|
msr.hi = csi->msr.hi;
|
||||||
wrmsr(csi->msrnum, msr);
|
wrmsr(csi->msrnum, msr); // MSR - see table above
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,14 +13,11 @@
|
||||||
#include <cpu/x86/msr.h>
|
#include <cpu/x86/msr.h>
|
||||||
#include <cpu/x86/cache.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.
|
extern void graphics_init(void);
|
||||||
* FIXME -- make this configurable
|
|
||||||
*/
|
#define NORTHBRIDGE_FILE "northbridge.c"
|
||||||
#define RAMADJUSTMB 9
|
|
||||||
/*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* todo: add a resource record. We don't do this here because this may be called when
|
/* 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.
|
* very little of the platform is actually working.
|
||||||
|
@ -115,24 +112,31 @@ struct msr_defaults {
|
||||||
/* GLIU0 */
|
/* GLIU0 */
|
||||||
P2D_BM(0x10000020, 0x1, 0x0, 0x0, 0xfff80),
|
P2D_BM(0x10000020, 0x1, 0x0, 0x0, 0xfff80),
|
||||||
P2D_BM(0x10000021, 0x1, 0x0, 0x80000, 0xfffe0),
|
P2D_BM(0x10000021, 0x1, 0x0, 0x80000, 0xfffe0),
|
||||||
P2D_SC(0x1000002c, 0x1, 0x0, 0x0, 0xff03, 0x3),
|
P2D_SC(0x1000002c, 0x1, 0x0, 0x0, 0xff03, 0xC0000),
|
||||||
/* GLIU1 */
|
/* GLIU1 */
|
||||||
P2D_BM(0x40000020, 0x1, 0x0, 0x0, 0xfff80),
|
P2D_BM(0x40000020, 0x1, 0x0, 0x0, 0xfff80),
|
||||||
P2D_BM(0x40000021, 0x1, 0x0, 0x80000, 0xfffe0),
|
P2D_BM(0x40000021, 0x1, 0x0, 0x80000, 0xfffe0),
|
||||||
P2D_SC(0x4000002d, 0x1, 0x0, 0x0, 0xff03, 0x3),
|
P2D_SC(0x4000002d, 0x1, 0x0, 0x0, 0xff03, 0xC0000),
|
||||||
{0}
|
{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
|
static int
|
||||||
setup_gx2_cache(void)
|
setup_gx2_cache(void)
|
||||||
{
|
{
|
||||||
msr_t msr;
|
msr_t msr;
|
||||||
unsigned long long val;
|
unsigned long long val;
|
||||||
int sizembytes, sizereg;
|
int sizekbytes, sizereg;
|
||||||
|
|
||||||
sizembytes = sizeram();
|
sizekbytes = sizeram() * 1024;
|
||||||
printk_debug("enable_cache: enable for %dm bytes\n", sizembytes);
|
printk_debug("setup_gx2_cache: enable for %d KB\n", sizekbytes);
|
||||||
/* build up the rconf word. */
|
/* build up the rconf word. */
|
||||||
/* the SYSTOP bits 27:8 are actually the top bits from 31:12. Book fails to say that */
|
/* the SYSTOP bits 27:8 are actually the top bits from 31:12. Book fails to say that */
|
||||||
/* set romrp */
|
/* set romrp */
|
||||||
|
@ -142,54 +146,58 @@ setup_gx2_cache(void)
|
||||||
val |= ((unsigned long long) 0xfff00)<<36;
|
val |= ((unsigned long long) 0xfff00)<<36;
|
||||||
/* set the devrp properties */
|
/* set the devrp properties */
|
||||||
val |= ((unsigned long long) DEVICE_PROPERTIES) << 28;
|
val |= ((unsigned long long) DEVICE_PROPERTIES) << 28;
|
||||||
/* sigh. Take our TOM, RIGHT shift 12, since it page-aligned, then LEFT-shift 8 for reg. */
|
/* 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 */
|
/* yank off memory for the SMM handler */
|
||||||
sizembytes -= RAMADJUSTMB;
|
sizekbytes -= SMM_SIZE;
|
||||||
sizereg = sizembytes;
|
sizereg = sizekbytes;
|
||||||
sizereg *= 0x100000;
|
sizereg *= 1024; // convert to bytes
|
||||||
sizereg >>= 12;
|
sizereg >>= 12;
|
||||||
sizereg <<= 8;
|
sizereg <<= 8;
|
||||||
val |= sizereg;
|
val |= sizereg;
|
||||||
val |= RAM_PROPERTIES;
|
val |= RAM_PROPERTIES;
|
||||||
msr.lo = val;
|
msr.lo = val;
|
||||||
msr.hi = (val >> 32);
|
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);
|
wrmsr(CPU_RCONF_DEFAULT, msr);
|
||||||
|
|
||||||
enable_cache();
|
enable_cache();
|
||||||
wbinvd();
|
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 */
|
/* we have to do this here. We have not found a nicer way to do it */
|
||||||
void
|
void
|
||||||
setup_gx2(void)
|
setup_gx2(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
unsigned long tmp, tmp2, tmp3;
|
unsigned long tmp, tmp2;
|
||||||
msr_t msr;
|
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!
|
/* NOTE! setup_gx2_cache returns the SIZE OF RAM - RAMADJUST!
|
||||||
* so it is safe to use. You should NOT at this point call
|
* so it is safe to use. You should NOT at this point call
|
||||||
* sizeram() directly.
|
* sizeram() directly.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* we need to set 0x10000028 and 0x40000029 */
|
/* 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.hi = 0x20000000 | membytes>>24;
|
||||||
msr.lo = 0x100 | ( ((membytes >>12) & 0xfff) << 20);
|
msr.lo = 0x100 | ( ((membytes >>12) & 0xfff) << 20);
|
||||||
wrmsr(0x10000028, msr);
|
wrmsr(0x10000028, msr);
|
||||||
msr.hi = 0x20000000 | membytes>>24;
|
msr.hi = 0x20000000 | membytes>>24;
|
||||||
msr.lo = 0x100 | ( ((membytes >>12) & 0xfff) << 20);
|
msr.lo = 0x100 | ( ((membytes >>12) & 0xfff) << 20);
|
||||||
wrmsr(0x40000029, msr);
|
wrmsr(0x40000029, msr);
|
||||||
|
#endif
|
||||||
msr = rdmsr(0x10000028);
|
msr = rdmsr(0x10000028);
|
||||||
printk_debug("MSR 0x%x is now 0x%x:0x%x\n", 0x10000028, msr.hi,msr.lo);
|
printk_debug("MSR 0x%x is now 0x%x:0x%x\n", 0x10000028, msr.hi,msr.lo);
|
||||||
msr = rdmsr(0x40000029);
|
msr = rdmsr(0x40000029);
|
||||||
|
@ -227,13 +235,15 @@ setup_gx2(void)
|
||||||
msr = rdmsr(0x1808);
|
msr = rdmsr(0x1808);
|
||||||
printk_debug("MSR 0x%x is now 0x%x:0x%x\n", 0x1808, msr.hi, msr.lo);
|
printk_debug("MSR 0x%x is now 0x%x:0x%x\n", 0x1808, msr.hi, msr.lo);
|
||||||
#endif
|
#endif
|
||||||
|
#if 0 // SDG - don't do this
|
||||||
/* now do the default MSR values */
|
/* now do the default MSR values */
|
||||||
for(i = 0; msr_defaults[i].msr_no; i++) {
|
for(i = 0; msr_defaults[i].msr_no; i++) {
|
||||||
msr_t msr;
|
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);
|
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)
|
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)
|
static void pci_domain_set_resources(device_t dev)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
device_t mc_dev;
|
device_t mc_dev;
|
||||||
uint32_t pci_tolm;
|
uint32_t pci_tolm;
|
||||||
#if 0
|
|
||||||
pci_tolm = find_pci_tolm(&dev->link[0]);
|
pci_tolm = find_pci_tolm(&dev->link[0]);
|
||||||
mc_dev = dev->link[0].children;
|
mc_dev = dev->link[0].children;
|
||||||
if (mc_dev) {
|
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 */
|
/* do this here for now -- this chip really breaks our device model */
|
||||||
setup_realmode_idt();
|
setup_realmode_idt();
|
||||||
do_vsmbios();
|
do_vsmbios();
|
||||||
|
graphics_init();
|
||||||
dev->ops = &pci_domain_ops;
|
dev->ops = &pci_domain_ops;
|
||||||
pci_set_method(dev);
|
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) {
|
} else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) {
|
||||||
printk_debug("DEVICE_PATH_APIC_CLUSTER\n");
|
printk_debug("DEVICE_PATH_APIC_CLUSTER\n");
|
||||||
dev->ops = &cpu_bus_ops;
|
dev->ops = &cpu_bus_ops;
|
||||||
}
|
}
|
||||||
|
printk_debug("gx2 north: end enable_dev\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
struct chip_operations northbridge_amd_gx2_ops = {
|
struct chip_operations northbridge_amd_gx2_ops = {
|
||||||
|
|
|
@ -111,11 +111,11 @@ writeglmsr(struct gliutable *gl){
|
||||||
|
|
||||||
msr.lo = gl->lo;
|
msr.lo = gl->lo;
|
||||||
msr.hi = gl->hi;
|
msr.hi = gl->hi;
|
||||||
wrmsr(gl->desc_name, msr);
|
wrmsr(gl->desc_name, msr); // MSR - see table above
|
||||||
printk_debug("%s: write msr 0x%x, val 0x%x:0x%x\n", __FUNCTION__, gl->desc_name, msr.hi, msr.lo);
|
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 */
|
/* they do this, so we do this */
|
||||||
msr = rdmsr(gl->desc_name);
|
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
|
static void
|
||||||
|
@ -142,6 +142,10 @@ SysmemInit(struct gliutable *gl)
|
||||||
msr_t msr;
|
msr_t msr;
|
||||||
int sizembytes, sizebytes;
|
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();
|
sizembytes = sizeram();
|
||||||
printk_debug("%s: enable for %dm bytes\n", __FUNCTION__, sizembytes);
|
printk_debug("%s: enable for %dm bytes\n", __FUNCTION__, sizembytes);
|
||||||
sizebytes = sizembytes << 20;
|
sizebytes = sizembytes << 20;
|
||||||
|
@ -152,15 +156,15 @@ SysmemInit(struct gliutable *gl)
|
||||||
sizebytes -= DMM_SIZE * 1024 + 1;
|
sizebytes -= DMM_SIZE * 1024 + 1;
|
||||||
|
|
||||||
sizebytes -= 1;
|
sizebytes -= 1;
|
||||||
msr.hi = gl->hi | (sizebytes >> 24);
|
msr.hi = (gl->hi & 0xFFFFFF00) | (sizebytes >> 24);
|
||||||
/* set up sizebytes to fit into msr.lo */
|
/* 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 &= 0xfff00000;
|
||||||
sizebytes |= 0x100;
|
sizebytes |= 0x100;
|
||||||
msr.lo = sizebytes;
|
msr.lo = sizebytes;
|
||||||
wrmsr(gl->desc_name, msr);
|
wrmsr(gl->desc_name, msr); // MSR - see table above
|
||||||
msr = rdmsr(gl->desc_name);
|
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);
|
gl->desc_name, msr.hi, msr.lo);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -177,7 +181,7 @@ DMMGL0Init(struct gliutable *gl) {
|
||||||
|
|
||||||
sizebytes -= DMM_SIZE*1024;
|
sizebytes -= DMM_SIZE*1024;
|
||||||
offset = sizebytes - DMM_OFFSET;
|
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;
|
offset >>= 12;
|
||||||
msr.hi = (gl->hi) | (offset << 8);
|
msr.hi = (gl->hi) | (offset << 8);
|
||||||
/* I don't think this is needed */
|
/* I don't think this is needed */
|
||||||
|
@ -186,9 +190,9 @@ DMMGL0Init(struct gliutable *gl) {
|
||||||
msr.lo = DMM_OFFSET << 8;
|
msr.lo = DMM_OFFSET << 8;
|
||||||
msr.lo |= ((~(DMM_SIZE*1024)+1)>>12)&0xfffff;
|
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);
|
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
|
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__);
|
printk_err("%s: warning, using DMM_SIZE even though AMD used SMM_SIZE\n", __FUNCTION__);
|
||||||
msr.lo |= ((~(DMM_SIZE*1024)+1)>>12)&0xfffff;
|
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);
|
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
|
static void
|
||||||
SMMGL0Init(struct gliutable *gl) {
|
SMMGL0Init(struct gliutable *gl) {
|
||||||
|
@ -227,7 +231,7 @@ SMMGL0Init(struct gliutable *gl) {
|
||||||
printk_debug("%s: %d bytes\n", __FUNCTION__, sizebytes);
|
printk_debug("%s: %d bytes\n", __FUNCTION__, sizebytes);
|
||||||
|
|
||||||
offset = sizebytes - SMM_OFFSET;
|
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;
|
offset >>= 12;
|
||||||
|
|
||||||
msr.hi = offset << 8;
|
msr.hi = offset << 8;
|
||||||
|
@ -236,9 +240,9 @@ SMMGL0Init(struct gliutable *gl) {
|
||||||
msr.lo = SMM_OFFSET << 8;
|
msr.lo = SMM_OFFSET << 8;
|
||||||
msr.lo |= ((~(SMM_SIZE*1024)+1)>>12)&0xfffff;
|
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);
|
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
|
static void
|
||||||
SMMGL1Init(struct gliutable *gl) {
|
SMMGL1Init(struct gliutable *gl) {
|
||||||
|
@ -252,9 +256,9 @@ SMMGL1Init(struct gliutable *gl) {
|
||||||
msr.lo = SMM_OFFSET << 8;
|
msr.lo = SMM_OFFSET << 8;
|
||||||
msr.lo |= ((~(SMM_SIZE*1024)+1)>>12)&0xfffff;
|
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);
|
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
|
static void
|
||||||
|
@ -263,11 +267,15 @@ GLIUInit(struct gliutable *gl){
|
||||||
while (gl->desc_type != GL_END){
|
while (gl->desc_type != GL_END){
|
||||||
switch(gl->desc_type){
|
switch(gl->desc_type){
|
||||||
default:
|
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__,
|
printk_err("%s: name %x, type %x, hi %x, lo %x: unsupported type: ", __FUNCTION__,
|
||||||
gl->desc_name, gl->desc_type, gl->hi, gl->hi);
|
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,
|
printk_err("Must be %x, %x, %x, %x, %x, or %x\n", SC_SHADOW,R_SYSMEM,BMO_DMM,
|
||||||
BM_DMM, BMO_SMM,BM_SMM);
|
BM_DMM, BMO_SMM,BM_SMM);
|
||||||
|
#endif
|
||||||
case SC_SHADOW: /* Check for a Shadow entry*/
|
case SC_SHADOW: /* Check for a Shadow entry*/
|
||||||
ShadowInit(gl);
|
ShadowInit(gl);
|
||||||
break;
|
break;
|
||||||
|
@ -317,7 +325,7 @@ static void GLPCIInit(void){
|
||||||
int i;
|
int i;
|
||||||
msr_t msr;
|
msr_t msr;
|
||||||
int msrnum;
|
int msrnum;
|
||||||
unsigned long val;
|
|
||||||
/* */
|
/* */
|
||||||
/* R0 - GLPCI settings for Conventional Memory space.*/
|
/* R0 - GLPCI settings for Conventional Memory space.*/
|
||||||
/* */
|
/* */
|
||||||
|
@ -349,7 +357,7 @@ static void GLPCIInit(void){
|
||||||
/* So we need a high page aligned addresss (pah) and low page aligned address (pal)
|
/* 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 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);
|
pah = ((msr.hi &0xff) << 12) | ((msr.lo >> 20) & 0xfff);
|
||||||
/* we have the page address. Now make it a page-aligned address */
|
/* we have the page address. Now make it a page-aligned address */
|
||||||
pah <<= 12;
|
pah <<= 12;
|
||||||
|
@ -358,7 +366,7 @@ static void GLPCIInit(void){
|
||||||
msr.hi = pah;
|
msr.hi = pah;
|
||||||
msr.lo = pal;
|
msr.lo = pal;
|
||||||
msr.lo |= GLPCI_RC_LOWER_EN_SET | GLPCI_RC_LOWER_PF_SET | GLPCI_RC_LOWER_WC_SET;
|
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;
|
msrnum = GLPCI_RC1;
|
||||||
wrmsr(msrnum, msr);
|
wrmsr(msrnum, msr);
|
||||||
}
|
}
|
||||||
|
@ -506,12 +514,12 @@ performance:
|
||||||
|
|
||||||
for(i = 0; gating->msrnum != 0xffffffff; i++) {
|
for(i = 0; gating->msrnum != 0xffffffff; i++) {
|
||||||
msr = rdmsr(gating->msrnum);
|
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.hi |= gating->msr.hi;
|
||||||
msr.lo |= gating->msr.lo;
|
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);
|
gating->msrnum, msr.hi, msr.lo);
|
||||||
wrmsr(gating->msrnum, msr);
|
wrmsr(gating->msrnum, msr); // MSR - See the table above
|
||||||
gating +=1;
|
gating +=1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -525,17 +533,235 @@ GeodeLinkPriority(void){
|
||||||
|
|
||||||
for(i = 0; prio->msrnum != 0xffffffff; i++) {
|
for(i = 0; prio->msrnum != 0xffffffff; i++) {
|
||||||
msr = rdmsr(prio->msrnum);
|
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.hi |= prio->msr.hi;
|
||||||
msr.lo &= ~0xfff;
|
msr.lo &= ~0xfff;
|
||||||
msr.lo |= prio->msr.lo;
|
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);
|
prio->msrnum, msr.hi, msr.lo);
|
||||||
wrmsr(prio->msrnum, msr);
|
wrmsr(prio->msrnum, msr); // MSR - See the table above
|
||||||
prio +=1;
|
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;
|
||||||
|
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*/
|
/* * northBridgeInit*/
|
||||||
|
@ -551,6 +777,7 @@ GeodeLinkPriority(void){
|
||||||
void
|
void
|
||||||
northbridgeinit(void)
|
northbridgeinit(void)
|
||||||
{
|
{
|
||||||
|
msr_t msr;
|
||||||
int i;
|
int i;
|
||||||
printk_debug("Enter %s\n", __FUNCTION__);
|
printk_debug("Enter %s\n", __FUNCTION__);
|
||||||
|
|
||||||
|
@ -559,9 +786,24 @@ northbridgeinit(void)
|
||||||
|
|
||||||
GeodeLinkPriority();
|
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.*/
|
/* 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;
|
i = *(int *) 0;
|
||||||
|
|
||||||
GLPCIInit();
|
GLPCIInit();
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#include <cpu/amd/gx2def.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* cs5536_early_setup.c: Early chipset initialization for CS5536 companion device
|
* cs5536_early_setup.c: Early chipset initialization for CS5536 companion device
|
||||||
|
|
|
@ -4,15 +4,15 @@ target rev_a
|
||||||
mainboard olpc/rev_a
|
mainboard olpc/rev_a
|
||||||
|
|
||||||
# leave 64k for vsa
|
# leave 64k for vsa
|
||||||
#option CONFIG_COMPRESSED_ROM_STREAM=1
|
option CONFIG_COMPRESSED_ROM_STREAM=0
|
||||||
option ROM_SIZE=1024*512-35*1024
|
option ROM_SIZE=1024*512-64*1024
|
||||||
option FALLBACK_SIZE=ROM_SIZE
|
option FALLBACK_SIZE=ROM_SIZE
|
||||||
|
|
||||||
option DEFAULT_CONSOLE_LOGLEVEL = 8
|
option DEFAULT_CONSOLE_LOGLEVEL = 11
|
||||||
option MAXIMUM_CONSOLE_LOGLEVEL = 8
|
option MAXIMUM_CONSOLE_LOGLEVEL = 11
|
||||||
romimage "fallback"
|
romimage "fallback"
|
||||||
option USE_FALLBACK_IMAGE=1
|
option USE_FALLBACK_IMAGE=1
|
||||||
option ROM_IMAGE_SIZE=28*1024
|
option ROM_IMAGE_SIZE=32*1024
|
||||||
option LINUXBIOS_EXTRA_VERSION=".0Fallback"
|
option LINUXBIOS_EXTRA_VERSION=".0Fallback"
|
||||||
payload /tmp/olpcpayload.elf
|
payload /tmp/olpcpayload.elf
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue