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
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* 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);
|
||||
|
|
|
@ -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*/
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -75,22 +75,22 @@
|
|||
#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_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
|
||||
#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_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.*/
|
||||
|
||||
|
||||
|
@ -485,7 +485,7 @@
|
|||
|
||||
/* 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
|
||||
|
@ -706,14 +706,14 @@
|
|||
|
||||
/* 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*/
|
||||
|
|
|
@ -2,3 +2,4 @@ config chip.h
|
|||
object northbridge.o
|
||||
object northbridgeinit.o
|
||||
object chipsetinit.o
|
||||
object grphinit.o
|
||||
|
|
|
@ -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,15 +229,16 @@ 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);
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,14 +13,11 @@
|
|||
#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 = {
|
||||
|
|
|
@ -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__);
|
||||
|
||||
|
@ -559,9 +786,24 @@ northbridgeinit(void)
|
|||
|
||||
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();
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#include <cpu/amd/gx2def.h>
|
||||
|
||||
/*
|
||||
*
|
||||
* cs5536_early_setup.c: Early chipset initialization for CS5536 companion device
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue