diff --git a/src/cpu/amd/model_gx2/vsmsetup.c b/src/cpu/amd/model_gx2/vsmsetup.c index f981932a7b..69470d5b2b 100644 --- a/src/cpu/amd/model_gx2/vsmsetup.c +++ b/src/cpu/amd/model_gx2/vsmsetup.c @@ -194,8 +194,9 @@ static void real_mode_switch_call_vsm(unsigned long smm, unsigned long sysm) /* Dump zeros in the other segregs */ " mov %ax, %es \n" - " mov %ax, %fs \n" - " mov %ax, %gs \n" + /* FixMe: Big real mode for gs, fs? */ + //" mov %ax, %fs \n" + //" mov %ax, %gs \n" " mov $0x40, %ax \n" " mov %ax, %ds \n" " mov %cx, %ax \n" @@ -256,13 +257,18 @@ void do_vsmbios(void) /* this is the base of rom on the GX2 at present. At some point, this has to be * much better parameterized */ - rom = 0xfff80000; + //rom = 0xfff80000; + rom = 0xfffc0000; buf = (unsigned char *) rom; - printk_debug("buf %p *buf %d buf[256k] %d\n", buf, buf[0], buf[256*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, don't bother. */ - if ((buf[0x20] != 0xb0) || (buf[0x21] != 0x10) || (buf[0x22] != 0xe6) || (buf[0x23] != 0x80)) { + printk_debug("buf %p *buf %d buf[256k] %d\n", + buf, buf[0], buf[256*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, + don't bother. */ + if ((buf[0x20] != 0xb0) || (buf[0x21] != 0x10) || + (buf[0x22] != 0xe6) || (buf[0x23] != 0x80)) { printk_err("do_vsmbios: no vsainit.bin signature, skipping!\n"); return; } @@ -272,7 +278,6 @@ void do_vsmbios(void) /* ecx gets smm, edx gets sysm */ printk_err("Call real_mode_switch_call_vsm\n"); real_mode_switch_call_vsm(0x10000026, 0x10000028); - } @@ -351,7 +356,7 @@ void callbiosint(void) // - provides us with a temp for the %cr0 mods. " pushl %eax \n" " movb $0xbb, %al\n" - " outb %al, $0x80\n" + " outb %al, $0x80\n" " movl %cr0, %eax\n" " orl $0x00000001, %eax\n" /* PE = 1 */ " movl %eax, %cr0\n" @@ -365,8 +370,8 @@ void callbiosint(void) " mov %ax, %fs \n" " mov %ax, %gs \n" " mov %ax, %ss \n" - " lidt idtarg \n" - " call biosint \n" + " lidt idtarg \n" + " call biosint \n" // back to real mode ... " ljmp $0x28, $__rms_16bit2\n" "__rms_16bit2: \n" @@ -454,7 +459,7 @@ int biosint(unsigned long intnumber, unsigned long cs; unsigned long flags; int ret = -1; - + ip = cs_ip & 0xffff; cs = cs_ip >> 16; flags = stackflags; @@ -466,6 +471,8 @@ int biosint(unsigned long intnumber, ebp, esp, edi, esi); printk_debug("biosint: ip 0x%x cs 0x%x flags 0x%x\n", ip, cs, flags); + printk_debug("biosint: gs 0x%x fs 0x%x ds 0x%x es 0x%x\n", + gsfs >> 16, gsfs & 0xffff, dses >> 16, dses & 0xffff); // cases in a good compiler are just as good as your own tables. switch (intnumber) { diff --git a/src/mainboard/amd/rumba/auto.c b/src/mainboard/amd/rumba/auto.c index 15b3606f0e..84c837bcc2 100644 --- a/src/mainboard/amd/rumba/auto.c +++ b/src/mainboard/amd/rumba/auto.c @@ -26,20 +26,70 @@ static inline int spd_read_byte(unsigned device, unsigned address) #include "northbridge/amd/gx2/raminit.h" -static void sdram_set_spd_registers(const struct mem_controller *ctrl) { +static inline unsigned int fls(unsigned int x) +{ + int r; + + __asm__("bsfl %1,%0\n\t" + "jnz 1f\n\t" + "movl $32,%0\n" + "1:" : "=r" (r) : "g" (x)); + return r; +} + +static void sdram_set_spd_registers(const struct mem_controller *ctrl) +{ + /* Total size of DIMM = 2^row address (byte 3) * 2^col address (byte 4) * + * component Banks (byte 17) * module banks, side (byte 5) * + * width in bits (byte 6,7) + * = Density per side (byte 31) * number of sides (byte 5) */ + /* 1. Initialize GLMC registers base on SPD values, do one DIMM for now */ msr_t msr; - /* 1. Initialize GLMC registers base on SPD values, - * Hard coded as XpressROM for now */ - //print_debug("sdram_enable step 1\r\n"); - msr = rdmsr(0x20000018); - msr.hi = 0x10076013; + unsigned char module_banks, val; + + msr = rdmsr(MC_CF07_DATA); + + /* get module banks (sides) per dimm, SPD byte 5 */ + module_banks = spd_read_byte(0xA0, 5); + if (module_banks < 1 || module_banks > 2) + print_err("Module banks per dimm\r\n"); + module_banks >>= 1; + msr.hi &= ~(1 << CF07_UPPER_D0_MB_SHIFT); + msr.hi |= (module_banks << CF07_UPPER_D0_MB_SHIFT); + + /* get component banks per module bank, SPD byte 17 */ + val = spd_read_byte(0xA0, 17); + if (val < 2 || val > 4) + print_err("Component banks per module bank\r\n"); + val >>= 2; + msr.hi &= ~(0x1 << CF07_UPPER_D0_CB_SHIFT); + msr.hi |= (val << CF07_UPPER_D0_CB_SHIFT); + + /* get the module bank density, SPD byte 31 */ + val = spd_read_byte(0xA0, 31); + val = fls(val); + val <<= module_banks; + msr.hi &= ~(0xf << CF07_UPPER_D0_SZ_SHIFT); + msr.hi |= (val << CF07_UPPER_D0_SZ_SHIFT); + + /* page size = 2^col address */ + val = spd_read_byte(0xA0, 4); + val -= 7; + msr.hi &= ~(0x7 << CF07_UPPER_D0_PSZ_SHIFT); + msr.hi |= (val << CF07_UPPER_D0_PSZ_SHIFT); + + print_debug("computed msr.hi "); + print_debug_hex32(msr.hi); + print_debug("\r\n"); + msr.lo = 0x00003000; - wrmsr(0x20000018, msr); + wrmsr(MC_CF07_DATA, msr); msr = rdmsr(0x20000019); msr.hi = 0x18000108; msr.lo = 0x696332a3; - wrmsr(0x20000019, msr); + wrmsr(0x20000019, msr); + } #include "northbridge/amd/gx2/raminit.c" @@ -100,6 +150,5 @@ static void main(unsigned long bist) /* Check all of memory */ - ram_check(0x00000000, 640*1024); - + //ram_check(0x00000000, 640*1024); } diff --git a/src/northbridge/amd/gx2/northbridge.c b/src/northbridge/amd/gx2/northbridge.c index 85961f48b7..fb3cb1c1e0 100644 --- a/src/northbridge/amd/gx2/northbridge.c +++ b/src/northbridge/amd/gx2/northbridge.c @@ -155,11 +155,16 @@ setup_gx2_cache(void) wbinvd(); return sizembytes; } + +#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; msr_t msr; unsigned long sizem, membytes; @@ -169,10 +174,10 @@ setup_gx2(void) /* we need to set 0x10000028 and 0x40000029 */ printk_debug("sizem 0x%x, membytes 0x%x\n", sizem, membytes); - msr.hi = 0x20000000 | membytes >>24; + msr.hi = 0x20000000 | membytes>>24; msr.lo = 0x100 | ( ((membytes >>12) & 0xfff) << 20); wrmsr(0x10000028, msr); - msr.hi = 0x20000000 | membytes >>24; + msr.hi = 0x20000000 | membytes>>24; msr.lo = 0x100 | ( ((membytes >>12) & 0xfff) << 20); wrmsr(0x40000029, msr); msr = rdmsr(0x10000028); @@ -181,6 +186,22 @@ setup_gx2(void) printk_debug("MSR 0x%x is now 0x%x:0x%x\n", 0x40000029, msr.hi,msr.lo); + /* fixme: SMM MSR 0x10000026 and 0x400000023 */ + /* calculate the OFFSET field */ + tmp = membytes - SMM_OFFSET; + tmp >>= 12; + tmp <<= 8; + tmp |= 0x20000000; + tmp |= (SMM_OFFSET >> 24); + + /* calculate the PBASE and PMASK fields */ + tmp2 = (SMM_OFFSET << 8) & 0xFFF00000; /* shift right 12 then left 20 == left 8 */ + tmp2 |= (((~(SMM_SIZE * 1024) + 1) >> 12) & 0xfffff); + printk_debug("MSR 0x%x is now 0x%x:0x%x\n", 0x10000026, tmp, tmp2); + msr.hi = tmp; + msr.lo = tmp2; + wrmsr(0x10000026, msr); + /* now do the default MSR values */ for(i = 0; msr_defaults[i].msr_no; i++) { msr_t msr; @@ -383,11 +404,11 @@ static void enable_dev(struct device *dev) cpubug(); setup_gx2(); /* do this here for now -- this chip really breaks our device model */ + setup_realmode_idt(); do_vsmbios(); dev->ops = &pci_domain_ops; pci_set_method(dev); - } - 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"); dev->ops = &cpu_bus_ops; diff --git a/src/northbridge/amd/gx2/pll_reset.c b/src/northbridge/amd/gx2/pll_reset.c index e1696fd703..ea54c49277 100644 --- a/src/northbridge/amd/gx2/pll_reset.c +++ b/src/northbridge/amd/gx2/pll_reset.c @@ -86,17 +86,6 @@ static const unsigned char fbdiv2plldiv[] = { 49, 40, 19, 59, 32, 54, 35, 0, 41, 60, 55, 0, 61, 0, 0, 0 }; -static const unsigned char pci33_sdr_crt [] = { - /* FbDIV, VDIV, MDIV CPU/GeodeLink */ - 12, 2, 4, // 200/100 - 16, 2, 4, // 266/133 - 18, 2, 5, // 300/120 - 20, 2, 5, // 333/133 - 22, 2, 6, // 366/122 - 24, 2, 6, // 400/133 - 26, 2, 6 // 433/144 -}; - static const unsigned char pci33_ddr_crt [] = { /* FbDIV, VDIV, MDIV CPU/GeodeLink */ 12, 2, 3, // 200/133 diff --git a/src/northbridge/amd/gx2/raminit.c b/src/northbridge/amd/gx2/raminit.c index f0156c3183..636c60b9d2 100644 --- a/src/northbridge/amd/gx2/raminit.c +++ b/src/northbridge/amd/gx2/raminit.c @@ -4,19 +4,6 @@ static void sdram_set_registers(const struct mem_controller *ctrl) { } -#if 0 -static void sdram_set_spd_registers(const struct mem_controller *ctrl) -{ - msr_t mst; - unsigned char val; - - /* get module banks per dimm, SPD byte 5 */ - val = spd_read_byte(0xA0, 5); - if (val < 1 || val > 2) - print_err("Module banks per dimm"); - -} -#endif /* Section 6.1.3, LX processor databooks, BIOS Initialization Sequence * Section 4.1.4, GX/CS5535 GeodeROM Porting guide */ static void sdram_enable(int controllers, const struct mem_controller *ctrl) diff --git a/src/southbridge/amd/cs5535/cs5535_early_setup.c b/src/southbridge/amd/cs5535/cs5535_early_setup.c index a1cab08c88..e6b36435b2 100644 --- a/src/southbridge/amd/cs5535/cs5535_early_setup.c +++ b/src/southbridge/amd/cs5535/cs5535_early_setup.c @@ -97,7 +97,7 @@ static int cs5535_early_setup(void) cs5535_setup_extmsr(); - msr = rdmsr(0x4c000014); + msr = rdmsr(GLCP_SYS_RSTPLL); if (msr.lo & (0x3f << 26)) { /* PLL is already set and we are reboot from PLL reset */ print_debug("reboot from BIOS reset\n\r");