diff options
Diffstat (limited to 'controller.c')
-rw-r--r-- | controller.c | 876 |
1 files changed, 524 insertions, 352 deletions
diff --git a/controller.c b/controller.c index ed38e12..5d98e74 100644 --- a/controller.c +++ b/controller.c @@ -3,7 +3,7 @@ * Released under version 2 of the Gnu Public License. * By Chris Brady, cbrady@sgi.com * ---------------------------------------------------- - * MemTest86+ V1.40 Specific code (GPL V2.0) + * MemTest86+ V1.41 Specific code (GPL V2.0) * By Samuel DEMEULEMEESTER, sdemeule@memtest.org * http://www.x86-secret.com - http://www.memtest.org */ @@ -20,12 +20,12 @@ extern ulong extclock; extern struct cpu_ident cpu_id; #define rdmsr(msr,val1,val2) \ - __asm__ __volatile__("rdmsr" \ + __asm__ __volatile__("rdmsr" \ : "=a" (val1), "=d" (val2) \ : "c" (msr)) #define wrmsr(msr,val1,val2) \ - __asm__ __volatile__("wrmsr" \ + __asm__ __volatile__("wrmsr" \ : /* no outputs */ \ : "c" (msr), "a" (val1), "d" (val2)) @@ -40,7 +40,7 @@ extern struct cpu_ident cpu_id; #define ECC_UNKNOWN (~0UL) /* Unknown error correcting ability/status */ #define ECC_NONE 0 /* Doesnt support ECC (or is BIOS disabled) */ #define ECC_RESERVED __ECC_UNEXPECTED /* Reserved ECC type */ -#define ECC_DETECT __ECC_DETECT +#define ECC_DETECT __ECC_DETECT #define ECC_CORRECT (__ECC_DETECT | __ECC_CORRECT) #define ECC_CHIPKILL (__ECC_DETECT | __ECC_CORRECT | __ECC_CHIPKILL) #define ECC_SCRUB (__ECC_DETECT | __ECC_CORRECT | __ECC_SCRUB) @@ -54,12 +54,12 @@ static struct ecc_info { unsigned fn; unsigned cap; unsigned mode; -} ctrl = +} ctrl = { .index = 0, /* I know of no case where the memory controller is not on the * host bridge, and the host bridge is not on bus 0 device 0 - * fn 0. But just in case leave these as variables. + * fn 0. But just in case leave these as variables. */ .bus = 0, .dev = 0, @@ -69,19 +69,30 @@ static struct ecc_info { .mode = ECC_UNKNOWN, }; +struct pci_memory_controller { + unsigned vendor; + unsigned device; + char *name; + int tested; + void (*poll_fsb)(void); + void (*poll_timings)(void); + void (*setup_ecc)(void); + void (*poll_errors)(void); +}; + void print_timings_info(float cas, int rcd, int rp, int ras) { /* Now, we could print some additionnals timings infos) */ cprint(LINE_CPU+5, col2 +1, "/ CAS : "); col2 += 9; - + // CAS Latency (tCAS) if (cas == 1.5) { - cprint(LINE_CPU+5, col2, "1.5"); col2 += 3; + cprint(LINE_CPU+5, col2, "1.5"); col2 += 3; } else if (cas == 2.5) { - cprint(LINE_CPU+5, col2, "2.5"); col2 += 3; + cprint(LINE_CPU+5, col2, "2.5"); col2 += 3; } else { - dprint(LINE_CPU+5, col2, cas, 1, 0); col2 += 1; + dprint(LINE_CPU+5, col2, cas, 1, 0); col2 += 1; } cprint(LINE_CPU+5, col2, "-"); col2 += 1; @@ -94,14 +105,14 @@ void print_timings_info(float cas, int rcd, int rp, int ras) { dprint(LINE_CPU+5, col2, rp, 1, 0); cprint(LINE_CPU+5, col2+1, "-"); col2 +=2; - + // RAS Active to precharge (tRAS) if (ras < 9) { - dprint(LINE_CPU+5, col2, ras, 1, 0); - col2 += 2; + dprint(LINE_CPU+5, col2, ras, 1, 0); + col2 += 2; } else { - dprint(LINE_CPU+5, col2, ras, 2, 0); - col2 += 3; + dprint(LINE_CPU+5, col2, ras, 2, 0); + col2 += 3; } } @@ -122,7 +133,7 @@ void print_fsb_info(float val, const char *text_fsb) { dprint(LINE_CPU+5, col2, val*2 ,3 ,0); col2 += 3; cprint(LINE_CPU+5, col2, ")"); - col2 += 1; + col2 += 1; } static void poll_fsb_nothing(void) @@ -148,26 +159,26 @@ static void poll_nothing(void) { /* Code to run when we don't know how, or can't ask the memory * controller about memory errors. - */ + */ return; } static void setup_amd64(void) { - + static const int ddim[] = { ECC_NONE, ECC_CORRECT, ECC_RESERVED, ECC_CHIPKILL }; unsigned long nbxcfg; unsigned int mcgsrl; unsigned int mcgsth; unsigned long mcanb; unsigned long dramcl; - + /* All AMD64 support Chipkill */ ctrl.cap = ECC_CHIPKILL; - + /* Check First if ECC DRAM Modules are used */ pci_conf_read(0, 24, 2, 0x90, 4, &dramcl); - + if ((dramcl >> 17)&1){ /* Fill in the correct memory capabilites */ pci_conf_read(0, 24, 3, 0x44, 4, &nbxcfg); @@ -178,7 +189,7 @@ static void setup_amd64(void) /* Enable NB ECC Logging by MSR Write */ rdmsr(0x017B, mcgsrl, mcgsth); wrmsr(0x017B, 0x10, mcgsth); - + /* Clear any previous error */ pci_conf_read(0, 24, 3, 0x4C, 4, &mcanb); pci_conf_write(0, 24, 3, 0x4C, 4, mcanb & 0x7F801EFC ); @@ -187,30 +198,30 @@ static void setup_amd64(void) static void poll_amd64(void) { - + unsigned long mcanb; unsigned long page, offset; unsigned long celog_syndrome; unsigned long mcanb_add; - + pci_conf_read(0, 24, 3, 0x4C, 4, &mcanb); - + if (((mcanb >> 31)&1) && ((mcanb >> 14)&1)) { /* Find out about the first correctable error */ /* Syndrome code -> bits use a complex matrix. Will add this later */ /* Read the error location */ pci_conf_read(0, 24, 3, 0x50, 4, &mcanb_add); - + /* Read the syndrome */ celog_syndrome = (mcanb >> 15)&0xFF; /* Parse the error location */ page = (mcanb_add >> 12); offset = (mcanb_add >> 3) & 0xFFF; - + /* Report the error */ print_ecc_err(page, offset, 1, celog_syndrome, 0); - + /* Clear the error registers */ pci_conf_write(0, 24, 3, 0x4C, 4, mcanb & 0x7F801EFC ); } @@ -222,13 +233,13 @@ static void poll_amd64(void) /* Parse the error location */ page = (mcanb_add >> 12); offset = (mcanb_add >> 3) & 0xFFF; - + /* Report the error */ print_ecc_err(page, offset, 0, 0, 0); - + /* Clear the error registers */ pci_conf_write(0, 24, 3, 0x4C, 4, mcanb & 0x7F801EFC ); - + } } @@ -261,33 +272,33 @@ static void poll_amd751(void) } /* Find the bank the error occured on */ bank_addr = 0x40 + (i << 1); - + /* Now get the information on the erroring bank */ pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, bank_addr, 2, &bank_info); - + /* Parse the error location and error type */ page = (bank_info & 0xFF80) << 4; bits = (((ecc_status >> 8) &3) == 2)?1:2; - + /* Report the error */ print_ecc_err(page, 0, bits==1?1:0, 0, 0); - + } - + /* Clear the error status */ pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0x58, 2, 0); } } -/* Still waiting for the CORRECT intel datasheet +/* Still waiting for the CORRECT intel datasheet static void setup_i85x(void) { - ctrl.cap = ECC_CORRECT; - unsigned long drc; - - pci_conf_read(ctrl.bus, ctrl.dev, 1, 0x70, 4, &drc); - ctrl.mode = ((drc>>20)&1)?ECC_CORRECT:ECC_NONE; - + unsigned long drc; + ctrl.cap = ECC_CORRECT; + + pci_conf_read(ctrl.bus, ctrl.dev, 1, 0x70, 4, &drc); + ctrl.mode = ((drc>>20)&1)?ECC_CORRECT:ECC_NONE; + } */ @@ -299,7 +310,7 @@ static void setup_amd76x(void) /* Fill in the correct memory capabilites */ pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x48, 4, &ecc_mode_status); ctrl.cap = ECC_CORRECT; - ctrl.mode = ddim[(ecc_mode_status >> 10)&3]; + ctrl.mode = ddim[(ecc_mode_status >> 10)&3]; } static void poll_amd76x(void) @@ -363,60 +374,94 @@ static void setup_iE7xxx(void) unsigned long drc; unsigned long device; unsigned long dvnp; - + /* Read the hardare capabilities */ pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x52, 2, &mchcfgns); pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x7C, 4, &drc); /* This is a check for E7205 */ pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x02, 2, &device); - + /* Fill in the correct memory capabilities */ ctrl.mode = 0; ctrl.cap = ECC_CORRECT; - + /* checking and correcting enabled */ - if (((drc >> 20) & 3) == 2) { + if (((drc >> 20) & 3) == 2) { ctrl.mode |= ECC_CORRECT; } - + /* E7205 doesn't support scrubbing */ if (device != 0x255d) { - /* scrub enabled */ - /* For E7501, valid SCRUB operations is bit 0 / D0:F0:R70-73 */ + /* scrub enabled */ + /* For E7501, valid SCRUB operations is bit 0 / D0:F0:R70-73 */ ctrl.cap = ECC_SCRUB; if (mchcfgns & 1) { ctrl.mode |= __ECC_SCRUB; } - - /* Now, we can active Dev1/Fun1 */ - /* Thanks to Tyan for providing us the board to solve this */ - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xE0, 2, &dvnp); - pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn , 0xE0, 2, (dvnp & 0xFE)); - + + /* Now, we can active Dev1/Fun1 */ + /* Thanks to Tyan for providing us the board to solve this */ + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xE0, 2, &dvnp); + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn , 0xE0, 2, (dvnp & 0xFE)); + } - + /* Clear any prexisting error reports */ pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x80, 1, 3); pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x82, 1, 3); - + } +static void setup_iE7520(void) +{ + unsigned long mchscrb; + unsigned long drc; + unsigned long dvnp1; + + /* Read the hardare capabilities */ + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x52, 2, &mchscrb); + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x7C, 4, &drc); + + /* Fill in the correct memory capabilities */ + ctrl.mode = 0; + ctrl.cap = ECC_CORRECT; + + /* Checking and correcting enabled */ + if (((drc >> 20) & 3) != 0) { + ctrl.mode |= ECC_CORRECT; + } + + /* scrub enabled */ + ctrl.cap = ECC_SCRUB; + if ((mchscrb & 3) == 2) { + ctrl.mode |= __ECC_SCRUB; + } + + /* Now, we can activate Fun1 */ + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xF4, 1, &dvnp1); + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn , 0xF4, 1, (dvnp1 | 0x20)); + + /* Clear any prexisting error reports */ + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x80, 2, 0x4747); + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x82, 2, 0x4747); +} + static void poll_iE7xxx(void) { unsigned long ferr; unsigned long nerr; - + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x80, 1, &ferr); pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x82, 1, &nerr); - + if (ferr & 1) { /* Find out about the first correctable error */ unsigned long celog_add; unsigned long celog_syndrome; unsigned long page; - + /* Read the error location */ pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn +1, 0xA0, 4, &celog_add); /* Read the syndrome */ @@ -424,37 +469,37 @@ static void poll_iE7xxx(void) /* Parse the error location */ page = (celog_add & 0x0FFFFFC0) >> 6; - + /* Report the error */ print_ecc_err(page, 0, 1, celog_syndrome, 0); - + /* Clear Bit */ pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x80, 1, ferr & 3); } - + if (ferr & 2) { /* Found out about the first uncorrectable error */ unsigned long uccelog_add; unsigned long page; - + /* Read the error location */ pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn +1, 0xB0, 4, &uccelog_add); /* Parse the error location */ page = (uccelog_add & 0x0FFFFFC0) >> 6; - + /* Report the error */ print_ecc_err(page, 0, 0, 0, 0); - + /* Clear Bit */ pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x80, 1, ferr & 3); } - + /* Check if DRAM_NERR contains data */ if (nerr & 3) { pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x82, 1, nerr & 3); } - + } static void setup_i440gx(void) @@ -496,7 +541,7 @@ static void poll_i440gx(void) pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0x91, 2, 0x11); pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0x80, 4, 3); } - + } static void setup_i840(void) { @@ -506,7 +551,7 @@ static void setup_i840(void) /* Fill in the correct memory capabilites */ pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x50, 2, &mchcfg); ctrl.cap = ECC_CORRECT; - ctrl.mode = ddim[(mchcfg >> 7)&3]; + ctrl.mode = ddim[(mchcfg >> 7)&3]; } static void poll_i840(void) @@ -549,25 +594,25 @@ static void setup_i875(void) ctrl.cap = ECC_CORRECT; ctrl.mode = ECC_NONE; - + /* From my article : http://www.x86-secret.com/articles/tweak/pat/patsecrets-2.htm */ /* Activate Device 6 */ pci_conf_read( 0, 0, 0, 0xF4, 1, &dev0); pci_conf_write( 0, 0, 0, 0xF4, 1, (dev0 | 0x2)); - + /* Activate Device 6 MMR */ pci_conf_read( 0, 6, 0, 0x04, 2, &dev6); pci_conf_write( 0, 6, 0, 0x04, 2, (dev6 | 0x2)); - + /* Read the MMR Base Address & Define the pointer*/ pci_conf_read( 0, 6, 0, 0x10, 4, &dev6); ptr=(long*)(dev6+0x68); - + if (((*ptr >> 18)&1) == 1) { ctrl.mode = ECC_CORRECT; } - + /* Reseting state */ pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, 0x81); - + } static void setup_i925(void) @@ -575,15 +620,23 @@ static void setup_i925(void) // Activate MMR I/O ulong dev0; - + long tolm; + // Current stepping of i925X does not support ECC ctrl.cap = ECC_CORRECT; ctrl.mode = ECC_NONE; - - pci_conf_read( 0, 0, 0, 0x54, 4, &dev0); + + pci_conf_read( 0, 0, 0, 0x54, 4, &dev0); dev0 = dev0 | 0x10000000; - pci_conf_write( 0, 0, 0, 0x54, 4, dev0); - + pci_conf_write( 0, 0, 0, 0x54, 4, dev0); + + // CDH start + pci_conf_read( 0, 0, 0, 0x44, 4, &dev0); + if (!(dev0 & 0xFFFFC000)) { + pci_conf_read( 0, 0, 0, 0x9C, 1, &tolm); + pci_conf_write( 0, 0, 0, 0x47, 1, tolm & 0xF8); + } + // CDH end } @@ -604,7 +657,7 @@ static void poll_i875(void) pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x58, 4, &eap); pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x5C, 1, &derrsyn); pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x5D, 1, &des); - + /* Parse the error location and error type */ page = (eap & 0xFFFFF000) >> 12; syndrome = derrsyn; @@ -703,7 +756,7 @@ static void setup_i850(void) /* Fill in the correct memory capabilites */ pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x50, 2, &mchcfg); ctrl.cap = ECC_CORRECT; - ctrl.mode = ddim[(mchcfg >> 7)&3]; + ctrl.mode = ddim[(mchcfg >> 7)&3]; } static void poll_i850(void) @@ -745,10 +798,10 @@ static void setup_i860(void) /* Fill in the correct memory capabilites */ pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0x50, 2, &mchcfg); ctrl.cap = ECC_CORRECT; - ctrl.mode = ddim[(mchcfg >> 7)&3]; + ctrl.mode = ddim[(mchcfg >> 7)&3]; /* Clear any prexisting error reports */ - pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, &errsts); + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, &errsts); pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn, 0xC8, 2, errsts & 3); } @@ -782,10 +835,62 @@ static void poll_i860(void) } } -/* ------------------ Here the code for FSB detection ------------------ */ -/* --------------------------------------------------------------------- */ +static void poll_iE7520(void) +{ + unsigned long ferr; + unsigned long nerr; + + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x80, 2, &ferr); + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x82, 2, &nerr); + if (ferr & 0x0101) { + /* Find out about the first correctable error */ + unsigned long celog_add; + unsigned long celog_syndrome; + unsigned long page; + /* Read the error location */ + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn +1, 0xA0, 4,&celog_add); + /* Read the syndrome */ + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn +1, 0xC4, 2, &celog_syndrome); + + /* Parse the error location */ + page = (celog_add & 0x7FFFFFFC) >> 2; + + /* Report the error */ + print_ecc_err(page, 0, 1, celog_syndrome, 0); + + /* Clear Bit */ + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x80, 2, ferr& 0x0101); + } + + if (ferr & 0x4646) { + /* Found out about the first uncorrectable error */ + unsigned long uccelog_add; + unsigned long page; + + /* Read the error location */ + pci_conf_read(ctrl.bus, ctrl.dev, ctrl.fn +1, 0xA4, 4, &uccelog_add); + + /* Parse the error location */ + page = (uccelog_add & 0x7FFFFFFC) >> 2; + + /* Report the error */ + print_ecc_err(page, 0, 0, 0, 0); + + /* Clear Bit */ + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x80, 2, ferr & 0x4646); + } + + /* Check if DRAM_NERR contains data */ + if (nerr & 0x4747) { + pci_conf_write(ctrl.bus, ctrl.dev, ctrl.fn +1, 0x82, 2, nerr & 0x4747); + } +} + + +/* ------------------ Here the code for FSB detection ------------------ */ +/* --------------------------------------------------------------------- */ static float athloncoef[] = {11, 11.5, 12.0, 12.5, 5.0, 5.5, 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5, 10.0, 10.5}; static float athloncoef2[] = {12, 19.0, 12.0, 20.0, 13.0, 13.5, 14.0, 21.0, 15.0, 22, 16.0, 16.5, 17.0, 18.0, 23.0, 24.0}; @@ -796,23 +901,23 @@ static int getP4PMmultiplier(void) unsigned int msr_lo, msr_hi; int coef; /* Find multiplier (by MSR) */ - - if (cpu_id.type == 6) { + + if (cpu_id.type == 6) { rdmsr(0x2A, msr_lo, msr_hi); coef = (msr_lo >> 22) & 0x1F; - } - else + } + else { - if (cpu_id.model < 2) + if (cpu_id.model < 2) { - rdmsr(0x2A, msr_lo, msr_hi); - coef = (msr_lo >> 8) & 0xF; - coef = p4model1ratios[coef]; - } - else + rdmsr(0x2A, msr_lo, msr_hi); + coef = (msr_lo >> 8) & 0xF; + coef = p4model1ratios[coef]; + } + else { - rdmsr(0x2C, msr_lo, msr_hi); - coef = (msr_lo >> 24) & 0x1F; + rdmsr(0x2C, msr_lo, msr_hi); + coef = (msr_lo >> 24) & 0x1F; } } return coef; @@ -829,28 +934,28 @@ static void poll_fsb_amd64(void) { float coef; coef = 10; - + /* First, got the FID by MSR */ /* First look if Cool 'n Quiet is supported to choose the best msr */ if (((cpu_id.pwrcap >> 1) & 1) == 1) { - rdmsr(0xc0010042, mcgsrl, mcgsth); - fid = (mcgsrl & 0x3F); + rdmsr(0xc0010042, mcgsrl, mcgsth); + fid = (mcgsrl & 0x3F); } else { - rdmsr(0xc0010015, mcgsrl, mcgsth); - fid = ((mcgsrl >> 24)& 0x3F); + rdmsr(0xc0010015, mcgsrl, mcgsth); + fid = ((mcgsrl >> 24)& 0x3F); } - + /* Extreme simplification. */ coef = ( fid / 2 ) + 4.0; - - /* Support for .5 coef */ - if ((fid & 1) == 1) { coef = coef + 0.5; } - + + /* Support for .5 coef */ + if ((fid & 1) == 1) { coef = coef + 0.5; } + /* Next, we need the clock ratio */ pci_conf_read(0, 24, 2, 0x94, 4, &dramchr); temp2 = (dramchr >> 20) & 0x7; clockratio = 1; - + switch (temp2) { case 0x0: clockratio = 0.5; @@ -867,48 +972,60 @@ static void poll_fsb_amd64(void) { case 0x7: clockratio = 1; break; - } - + } + /* Compute the final DRAM Clock */ dramclock = ((extclock /1000) / coef) * clockratio; - + /* ...and print */ print_fsb_info(dramclock, "RAM : "); - + } static void poll_fsb_i925(void) { double dramclock, dramratio, fsb; - unsigned long mchcfg, mchcfg2, dev0; + unsigned long mchcfg, mchcfg2, dev0, drc, idetect; int coef = getP4PMmultiplier(); long *ptr; + pci_conf_read( 0, 0, 0, 0x02, 2, &idetect); + /* Find dramratio */ pci_conf_read( 0, 0, 0, 0x44, 4, &dev0); dev0 = dev0 & 0xFFFFC000; ptr=(long*)(dev0+0xC00); mchcfg = *ptr & 0xFFFF; + ptr=(long*)(dev0+0x120); + drc = *ptr & 0xFFFF; dramratio = 1; mchcfg2 = (mchcfg >> 4)&3; - if ((mchcfg >> 2)&1) { - if (mchcfg2 == 2) { dramratio = 0.75; } else { dramratio = 1; } + if ((drc&3) != 2) { + // We are in DDR1 Mode + if (mchcfg2 == 1) { dramratio = 0.8; } else { dramratio = 1; } } else { - switch (mchcfg2) { - case 1: - dramratio = 0.66667; - break; - case 2: - dramratio = 1; - break; - case 3: - if ((mchcfg & 1) == 0) { dramratio = 1.33334; } - else { dramratio = 1.5; } + // We are in DDR2 Mode + if ((mchcfg >> 2)&1) { + // We are in FSB1066 Mode + if (mchcfg2 == 2) { dramratio = 0.75; } else { dramratio = 1; } + } else { + switch (mchcfg2) { + case 1: + dramratio = 0.66667; + break; + case 2: + if (idetect != 0x2590) { dramratio = 1; } else { dramratio = 1.5; } + break; + case 3: + // Checking for FSB533 Mode & Alviso + if ((mchcfg & 1) == 0) { dramratio = 1.33334; } + else if (idetect == 0x2590) { dramratio = 2; } + else { dramratio = 1.5; } + } } } - // Compute RAM Frequency fsb = ((extclock / 1000) / coef); dramclock = fsb * dramratio; @@ -926,18 +1043,64 @@ static void poll_fsb_i925(void) { } +static void poll_fsb_i945(void) { + + double dramclock, dramratio, fsb; + unsigned long mchcfg, dev0; + int coef = getP4PMmultiplier(); + long *ptr; + + /* Find dramratio */ + pci_conf_read( 0, 0, 0, 0x44, 4, &dev0); + dev0 &= 0xFFFFC000; + ptr=(long*)(dev0+0xC00); + mchcfg = *ptr & 0xFFFF; + dramratio = 1; + + switch ((mchcfg >> 4)&7) { + case 1: + dramratio = 1.0; + break; + case 2: + dramratio = 1.33334; + break; + case 3: + dramratio = 1.66667; + break; + case 4: + dramratio = 2.0; + break; + } + + // Compute RAM Frequency + fsb = ((extclock / 1000) / coef); + dramclock = fsb * dramratio; + + // Print DRAM Freq + print_fsb_info(dramclock, "RAM : "); + + /* Print FSB (only if ECC is not enabled) */ + cprint(LINE_CPU+4, col +1, "- FSB : "); + col += 9; + dprint(LINE_CPU+4, col, fsb, 3,0); + col += 3; + cprint(LINE_CPU+4, col +1, "Mhz"); + col += 4; + +} + static void poll_fsb_i875(void) { double dramclock, dramratio, fsb; unsigned long mchcfg, smfs; int coef = getP4PMmultiplier(); - + /* Find dramratio */ pci_conf_read(0, 0, 0, 0xC6, 2, &mchcfg); smfs = (mchcfg >> 10)&3; dramratio = 1; - - if ((mchcfg&3) == 3) { dramratio = 1; } + + if ((mchcfg&3) == 3) { dramratio = 1; } if ((mchcfg&3) == 2) { if (smfs == 2) { dramratio = 1; } if (smfs == 1) { dramratio = 1.25; } @@ -948,25 +1111,25 @@ static void poll_fsb_i875(void) { if (smfs == 1) { dramratio = 0.8; } if (smfs == 0) { dramratio = 1; } } - if ((mchcfg&3) == 0) { dramratio = 0.75; } + if ((mchcfg&3) == 0) { dramratio = 0.75; } + - /* Compute RAM Frequency */ dramclock = ((extclock /1000) / coef) / dramratio; fsb = ((extclock /1000) / coef); - + /* Print DRAM Freq */ print_fsb_info(dramclock, "RAM : "); - + /* Print FSB (only if ECC is not enabled) */ - if ( ctrl.mode == ECC_NONE ) { - cprint(LINE_CPU+4, col +1, "- FSB : "); - col += 9; - dprint(LINE_CPU+4, col, fsb, 3,0); - col += 3; - cprint(LINE_CPU+4, col +1, "Mhz"); - col += 4; - } + if ( ctrl.mode == ECC_NONE ) { + cprint(LINE_CPU+4, col +1, "- FSB : "); + col += 9; + dprint(LINE_CPU+4, col, fsb, 3,0); + col += 3; + cprint(LINE_CPU+4, col +1, "Mhz"); + col += 4; + } } static void poll_fsb_p4(void) { @@ -983,11 +1146,11 @@ static void poll_fsb_p4(void) { col += 3; cprint(LINE_CPU+4, col +1, "Mhz"); col += 4; - + /* For synchro only chipsets */ pci_conf_read( 0, 0, 0, 0x02, 2, &idetect); if (idetect == 0x2540 || idetect == 0x254C) { - print_fsb_info(fsb, "RAM : "); + print_fsb_info(fsb, "RAM : "); } } @@ -998,26 +1161,26 @@ static void poll_fsb_i855(void) { unsigned int msr_lo, msr_hi; ulong mchcfg, centri, idetect; int coef; - + pci_conf_read( 0, 0, 0, 0x02, 2, &idetect); - + /* Find multiplier (by MSR) */ - + /* Is it a Pentium M ? */ if (cpu_id.type == 6) { - rdmsr(0x2A, msr_lo, msr_hi); - coef = (msr_lo >> 22) & 0x1F; - - /* Is it an i855GM or PM ? */ - if (idetect == 0x3580) { - cprint(LINE_CPU+4, col-1, "i855GM/GME "); - col += 10; } - + rdmsr(0x2A, msr_lo, msr_hi); + coef = (msr_lo >> 22) & 0x1F; + + /* Is it an i855GM or PM ? */ + if (idetect == 0x3580) { + cprint(LINE_CPU+4, col-1, "i855GM/GME "); + col += 10; + } } else { - rdmsr(0x2C, msr_lo, msr_hi); - coef = (msr_lo >> 24) & 0x1F; - cprint(LINE_CPU+4, col-1, "i852PM/GM "); - col += 9; + rdmsr(0x2C, msr_lo, msr_hi); + coef = (msr_lo >> 24) & 0x1F; + cprint(LINE_CPU+4, col-1, "i852PM/GM "); + col += 9; } fsb = ((extclock /1000) / coef); @@ -1028,31 +1191,32 @@ static void poll_fsb_i855(void) { cprint(LINE_CPU+4, col +1, "Mhz"); col += 4; /* Is it a Centrino platform or only an i855 platform ? */ - pci_conf_read( 2, 2, 0, 0x02, 2, ¢ri); + pci_conf_read( 2, 2, 0, 0x02, 2, ¢ri); if (centri == 0x1043) { cprint(LINE_CPU+4, col +1, "/ Centrino Mobile Platform"); } - else { cprint(LINE_CPU+4, col +1, "/ Mobile Platform"); } - + else { cprint(LINE_CPU+4, col +1, "/ Mobile Platform"); } + /* Compute DRAM Clock */ dramratio = 1; if (idetect == 0x3580) { pci_conf_read( 0, 0, 3, 0xC0, 2, &mchcfg); mchcfg = mchcfg & 0x7; - + if (mchcfg == 1 || mchcfg == 2 || mchcfg == 4 || mchcfg == 5) { dramratio = 1; } - if (mchcfg == 0 || mchcfg == 3) { dramratio = 1.333333333; } - if (mchcfg == 6) { dramratio = 1.25; } - if (mchcfg == 7) { dramratio = 1.666666667; } - + if (mchcfg == 0 || mchcfg == 3) { dramratio = 1.333333333; } + if (mchcfg == 6) { dramratio = 1.25; } + if (mchcfg == 7) { dramratio = 1.666666667; } + } else { pci_conf_read( 0, 0, 0, 0xC6, 2, &mchcfg); - if (((mchcfg >> 11)&1) == 0) { dramratio = 1; } + if (((mchcfg >> 10)&3) == 0) { dramratio = 1; } + else if (((mchcfg >> 10)&3) == 0) { dramratio = 1.666667; } else { dramratio = 1.333333333; } } - - + + dramclock = fsb * dramratio; - + /* ...and print */ print_fsb_info(dramclock, "RAM : "); @@ -1065,18 +1229,18 @@ static void poll_fsb_amd32(void) { unsigned long temp; double dramclock; double coef2; - + /* First, got the FID */ rdmsr(0x0c0010015, mcgsrl, mcgsth); temp = (mcgsrl >> 24)&0x0F; - + if ((mcgsrl >> 19)&1) { coef2 = athloncoef2[temp]; } else { coef2 = athloncoef[temp]; } - + if (coef2 == 0) { coef2 = 1; }; - + /* Compute the final FSB Clock */ - dramclock = (extclock /1000) / coef2; + dramclock = (extclock /1000) / coef2; /* ...and print */ print_fsb_info(dramclock, "FSB : "); @@ -1092,55 +1256,55 @@ static void poll_fsb_nf2(void) { double mem_m, mem_n; float coef; coef = 10; - + /* First, got the FID */ rdmsr(0x0c0010015, mcgsrl, mcgsth); temp = (mcgsrl >> 24)&0x0F; - + if ((mcgsrl >> 19)&1) { coef = athloncoef2[temp]; } else { coef = athloncoef[temp]; } - + /* Get the coef (COEF = N/M) - Here is for Crush17 */ pci_conf_read(0, 0, 3, 0x70, 4, &mempll); mem_m = (mempll&0x0F); mem_n = ((mempll >> 4) & 0x0F); - + /* If something goes wrong, the chipset is probably a Crush18 */ if ( mem_m == 0 || mem_n == 0 ) { pci_conf_read(0, 0, 3, 0x7C, 4, &mempll); mem_m = (mempll&0x0F); mem_n = ((mempll >> 4) & 0x0F); } - + /* Compute the final FSB Clock */ - dramclock = ((extclock /1000) / coef) * (mem_n/mem_m); + dramclock = ((extclock /1000) / coef) * (mem_n/mem_m); fsb = ((extclock /1000) / coef); - + /* ...and print */ - + cprint(LINE_CPU+4, col, "/ FSB : "); col += 8; dprint(LINE_CPU+4, col, fsb, 3,0); col += 3; cprint(LINE_CPU+4, col +1, "Mhz"); - + print_fsb_info(dramclock, "RAM : "); - + } /* ------------------ Here the code for Timings detection ------------------ */ /* ------------------------------------------------------------------------- */ static void poll_timings_i925(void) { - ulong dev0, mch, drt, drc, dcc, temp; + // Thanks for CDH optis + ulong dev0, drt, drc, dcc, idetect, temp; long *ptr; - - //Read Offset 9C - pci_conf_read( 0, 0, 0, 0x9C, 1, &mch); - + //Now, read MMR Base Address pci_conf_read( 0, 0, 0, 0x44, 4, &dev0); - + pci_conf_read( 0, 0, 0, 0x02, 2, &idetect); + dev0 &= 0xFFFFC000; + //Set pointer for DRT ptr=(long*)(dev0+0x114); drt = *ptr & 0xFFFFFFFF; @@ -1154,61 +1318,59 @@ static void poll_timings_i925(void) { dcc = *ptr & 0xFFFFFFFF; //Determine DDR or DDR-II - if ((drc & 3) == 2) { - cprint(LINE_CPU+4, col +1, "- Type : DDR-II"); + cprint(LINE_CPU+4, col +1, "- Type : DDR-II"); } else { - cprint(LINE_CPU+4, col +1, "- Type : DDR-I"); + cprint(LINE_CPU+4, col +1, "- Type : DDR-I"); } // Now, detect timings cprint(LINE_CPU+5, col2 +1, "/ CAS : "); col2 += 9; - + // CAS Latency (tCAS) temp = ((drt >> 8)& 0x3); if ((drc & 3) == 2){ // Timings DDR-II - if (temp == 0x0) { cprint(LINE_CPU+5, col2, "5-"); } + if (temp == 0x0) { cprint(LINE_CPU+5, col2, "5-"); } else if (temp == 0x1) { cprint(LINE_CPU+5, col2, "4-"); } - else { cprint(LINE_CPU+5, col2, "3-"); } + else { cprint(LINE_CPU+5, col2, "3-"); } } else { // Timings DDR-I - if (temp == 0x0) { cprint(LINE_CPU+5, col2, "3-"); } + if (temp == 0x0) { cprint(LINE_CPU+5, col2, "3-"); } else if (temp == 0x1) { cprint(LINE_CPU+5, col2, "2.5-"); col2 +=2;} - else { cprint(LINE_CPU+5, col2, "2-"); } + else { cprint(LINE_CPU+5, col2, "2-"); } } col2 +=2; - + // RAS-To-CAS (tRCD) - temp = ((drt >> 4)& 0x3); - if (temp == 0x0) { cprint(LINE_CPU+5, col2, "2-"); } - else if (temp == 0x1) { cprint(LINE_CPU+5, col2, "3-"); } - else if (temp == 0x2) { cprint(LINE_CPU+5, col2, "4-"); } - else { cprint(LINE_CPU+5, col2, "5-"); } + dprint(LINE_CPU+5, col2, ((drt >> 4)& 0x3)+2, 1 ,0); + cprint(LINE_CPU+5, col2+1, "-"); col2 +=2; // RAS Precharge (tRP) - temp = (drt&0x3); - if (temp == 0x0) { cprint(LINE_CPU+5, col2, "2-"); } - else if (temp == 0x1) { cprint(LINE_CPU+5, col2, "3-"); } - else if (temp == 0x2) { cprint(LINE_CPU+5, col2, "4-"); } - else { cprint(LINE_CPU+5, col2, "5-"); } + dprint(LINE_CPU+5, col2, (drt&0x3)+2, 1 ,0); + cprint(LINE_CPU+5, col2+1, "-"); col2 +=2; - + // RAS Active to precharge (tRAS) - temp = ((drt >> 20)& 0xF); + // If Lakeport, than change tRAS computation (Thanks to CDH, again) + if (idetect == 0x2770) + temp = ((drt >> 19)& 0x1F); + else + temp = ((drt >> 20)& 0x0F); + dprint(LINE_CPU+5, col2, temp , 1 ,0); (temp < 10)?(col2 += 1):(col2 += 2); - + cprint(LINE_CPU+5, col2+1, "/"); col2 +=2; - + temp = (dcc&0x3); - if (temp == 1) { cprint(LINE_CPU+5, col2, " Dual Channel (Asymmetric)"); } + if (temp == 1) { cprint(LINE_CPU+5, col2, " Dual Channel (Asymmetric)"); } else if (temp == 2) { cprint(LINE_CPU+5, col2, " Dual Channel (Interleaved)"); } - else { cprint(LINE_CPU+5, col2, " Single Channel (64 bits)"); } - + else { cprint(LINE_CPU+5, col2, " Single Channel (64 bits)"); } + } static void poll_timings_i875(void) { @@ -1218,14 +1380,14 @@ static void poll_timings_i875(void) { float cas; int rcd, rp, ras; long *ptr, *ptr2; - + /* Read the MMR Base Address & Define the pointer */ pci_conf_read( 0, 6, 0, 0x10, 4, &dev6); - + /* Now, the PAT ritual ! (Kant and Luciano will love this) */ pci_conf_read( 0, 6, 0, 0x40, 4, &dev62); ptr2=(long*)(dev6+0x68); - + if ((dev62&0x3) == 0 && ((*ptr2 >> 14)&1) == 1) { cprint(LINE_CPU+4, col +1, "- PAT : Enabled"); } else { @@ -1233,12 +1395,12 @@ static void poll_timings_i875(void) { } /* Now, we could check some additionnals timings infos) */ - + ptr=(long*)(dev6+0x60); // CAS Latency (tCAS) temp = ((*ptr >> 5)& 0x3); if (temp == 0x0) { cas = 2.5; } else if (temp == 0x1) { cas = 2; } else { cas = 3; } - + // RAS-To-CAS (tRCD) temp = ((*ptr >> 2)& 0x3); if (temp == 0x0) { rcd = 4; } else if (temp == 0x1) { rcd = 3; } else { rcd = 2; } @@ -1246,32 +1408,56 @@ static void poll_timings_i875(void) { // RAS Precharge (tRP) temp = (*ptr&0x3); if (temp == 0x0) { rp = 4; } else if (temp == 0x1) { rp = 3; } else { rp = 2; } - + // RAS Active to precharge (tRAS) temp = ((*ptr >> 7)& 0x7); ras = 10 - temp; - + // Print timings print_timings_info(cas, rcd, rp, ras); - + // Print 64 or 128 bits mode - if (((*ptr2 >> 21)&1) == 1) { - cprint(LINE_CPU+5, col2, "/ Dual Channel (128 bits)"); + if (((*ptr2 >> 21)&3) > 1) { + cprint(LINE_CPU+5, col2, "/ Dual Channel (128 bits)"); } else { - cprint(LINE_CPU+5, col2, "/ Single Channel (64 bits)"); + cprint(LINE_CPU+5, col2, "/ Single Channel (64 bits)"); } } +static void poll_timings_E7520(void) { + + ulong drt, ddrcsr; + float cas; + int rcd, rp, ras; + + pci_conf_read( 0, 0, 0, 0x78, 4, &drt); + pci_conf_read( 0, 0, 0, 0x9A, 2, &ddrcsr); + + cas = ((drt >> 2) & 3) + 2; + rcd = ((drt >> 10) & 1) + 3; + rp = ((drt >> 9) & 1) + 3; + ras = ((drt >> 14) & 3) + 11; + + print_timings_info(cas, rcd, rp, ras); + + if ((ddrcsr & 0xF) >= 0xC) { + cprint(LINE_CPU+5, col2, "/ Dual Channel (128 bits)"); + } else { + cprint(LINE_CPU+5, col2, "/ Single Channel (64 bits)"); + } +} + + static void poll_timings_i855(void) { ulong drt, temp; pci_conf_read( 0, 0, 0, 0x78, 4, &drt); - + /* Now, we could print some additionnals timings infos) */ cprint(LINE_CPU+5, col2 +1, "/ CAS : "); col2 += 9; - + // CAS Latency (tCAS) temp = ((drt >> 4)&0x1); if (temp == 0x0) { cprint(LINE_CPU+5, col2, "2.5-"); col2 += 4; } @@ -1288,12 +1474,12 @@ static void poll_timings_i855(void) { if (temp == 0x0) { cprint(LINE_CPU+5, col2, "3-"); } else { cprint(LINE_CPU+5, col2, "2-"); } col2 +=2; - + // RAS Active to precharge (tRAS) - temp = ((drt >> 9)& 0x3); - if (temp == 0x0) { cprint(LINE_CPU+5, col2, "10"); col2 +=7; } - if (temp == 0x1) { cprint(LINE_CPU+5, col2, "9"); col2 +=6; } - if (temp == 0x2) { cprint(LINE_CPU+5, col2, "8"); col2 +=5; } + temp = 7-((drt >> 9)& 0x3); + if (temp == 0x0) { cprint(LINE_CPU+5, col2, "7"); } + if (temp == 0x1) { cprint(LINE_CPU+5, col2, "6"); } + if (temp == 0x2) { cprint(LINE_CPU+5, col2, "5"); } col2 +=1; } @@ -1303,23 +1489,23 @@ static void poll_timings_E750x(void) { ulong drt, drc, temp; float cas; int rcd, rp, ras; - + pci_conf_read( 0, 0, 0, 0x78, 4, &drt); pci_conf_read( 0, 0, 0, 0x7C, 4, &drc); - + if ((drt >> 4) & 1) { cas = 2; } else { cas = 2.5; }; if ((drt >> 1) & 1) { rcd = 2; } else { rcd = 3; }; if (drt & 1) { rp = 2; } else { rp = 3; }; temp = ((drt >> 9) & 3); if (temp == 2) { ras = 5; } else if (temp == 1) { ras = 6; } else { ras = 7; } - + print_timings_info(cas, rcd, rp, ras); - + if (((drc >> 22)&1) == 1) { - cprint(LINE_CPU+5, col2, "/ Dual Channel (128 bits)"); + cprint(LINE_CPU+5, col2, "/ Dual Channel (128 bits)"); } else { - cprint(LINE_CPU+5, col2, "/ Single Channel (64 bits)"); + cprint(LINE_CPU+5, col2, "/ Single Channel (64 bits)"); } } @@ -1333,7 +1519,7 @@ static void poll_timings_i852(void) { /* Now, we could print some additionnals timings infos) */ cprint(LINE_CPU+5, col2 +1, "/ CAS : "); col2 += 9; - + // CAS Latency (tCAS) temp = ((drt >> 5)&0x1); if (temp == 0x0) { cprint(LINE_CPU+5, col2, "2.5-"); col2 += 4; } @@ -1352,7 +1538,7 @@ static void poll_timings_i852(void) { if (temp == 0x1) { cprint(LINE_CPU+5, col2, "3-"); } else { cprint(LINE_CPU+5, col2, "2-"); } col2 +=2; - + // RAS Active to precharge (tRAS) temp = ((drt >> 9)& 0x3); if (temp == 0x0) { cprint(LINE_CPU+5, col2, "8"); col2 +=7; } @@ -1368,19 +1554,19 @@ static void poll_timings_amd64(void) { ulong dramtlr, dramclr; int temp; int trcd, trp, tras ; - + cprint(LINE_CPU+5, col2 +1, "/ CAS : "); col2 += 9; - + pci_conf_read(0, 24, 2, 0x88, 4, &dramtlr); pci_conf_read(0, 24, 2, 0x90, 4, &dramclr); - + // CAS Latency (tCAS) temp = (dramtlr & 0x7); if (temp == 0x1) { cprint(LINE_CPU+5, col2, "2-"); col2 +=2; } if (temp == 0x2) { cprint(LINE_CPU+5, col2, "3-"); col2 +=2; } if (temp == 0x5) { cprint(LINE_CPU+5, col2, "2.5-"); col2 +=4; } - + // RAS-To-CAS (tRCD) trcd = ((dramtlr >> 12) & 0x7); dprint(LINE_CPU+5, col2, trcd , 1 ,0); @@ -1390,23 +1576,23 @@ static void poll_timings_amd64(void) { trp = ((dramtlr >> 24) & 0x7); dprint(LINE_CPU+5, col2, trp , 1 ,0); cprint(LINE_CPU+5, col2 +1, "-"); col2 +=2; - + // RAS Active to precharge (tRAS) tras = ((dramtlr >> 20) & 0xF); if (tras < 10){ dprint(LINE_CPU+5, col2, tras , 1 ,0); col2 += 1; } else { - dprint(LINE_CPU+5, col2, tras , 2 ,0); col2 += 2; + dprint(LINE_CPU+5, col2, tras , 2 ,0); col2 += 2; } cprint(LINE_CPU+5, col2+1, "/"); col2 +=2; - + // Print 64 or 128 bits mode - + if (((dramclr >> 16)&1) == 1) { - cprint(LINE_CPU+5, col2, " Dual Channel (128 bits)"); + cprint(LINE_CPU+5, col2, " Dual Channel (128 bits)"); col2 +=24; } else { - cprint(LINE_CPU+5, col2, " Single Channel (64 bits)"); + cprint(LINE_CPU+5, col2, " Single Channel (64 bits)"); col2 +=15; } } @@ -1415,7 +1601,7 @@ static void poll_timings_nf2(void) { ulong dramtlr, dramtlr2, dramtlr3, temp; ulong dimm1p, dimm2p, dimm3p; - + pci_conf_read(0, 0, 1, 0x90, 4, &dramtlr); pci_conf_read(0, 0, 1, 0xA0, 4, &dramtlr2); pci_conf_read(0, 0, 1, 0x84, 4, &dramtlr3); @@ -1425,40 +1611,40 @@ static void poll_timings_nf2(void) { cprint(LINE_CPU+5, col2 +1, "/ CAS : "); col2 += 9; - + // CAS Latency (tCAS) temp = ((dramtlr2 >> 4) & 0x7); if (temp == 0x2) { cprint(LINE_CPU+5, col2, "2-"); col2 +=2; } if (temp == 0x3) { cprint(LINE_CPU+5, col2, "3-"); col2 +=2; } if (temp == 0x6) { cprint(LINE_CPU+5, col2, "2.5-"); col2 +=4; } - + // RAS-To-CAS (tRCD) temp = ((dramtlr >> 20) & 0xF); dprint(LINE_CPU+5, col2, temp , 1 ,0); cprint(LINE_CPU+5, col2 +1, "-"); col2 +=2; - + // RAS Precharge (tRP) temp = ((dramtlr >> 28) & 0xF); dprint(LINE_CPU+5, col2, temp , 1 ,0); cprint(LINE_CPU+5, col2 +1, "-"); col2 +=2; - + // RAS Active to precharge (tRAS) temp = ((dramtlr >> 15) & 0xF); if (temp < 10){ - dprint(LINE_CPU+5, col2, temp , 1 ,0); col2 += 1; + dprint(LINE_CPU+5, col2, temp , 1 ,0); col2 += 1; } else { - dprint(LINE_CPU+5, col2, temp , 2 ,0); col2 += 2; + dprint(LINE_CPU+5, col2, temp , 2 ,0); col2 += 2; } - cprint(LINE_CPU+5, col2+1, "/"); col2 +=2; - + cprint(LINE_CPU+5, col2+1, "/"); col2 +=2; + // Print 64 or 128 bits mode // If DIMM1 & DIMM3 or DIMM1 & DIMM2 populated, than Dual Channel. - + if ((dimm3p&1) + (dimm2p&1) == 2 || (dimm3p&1) + (dimm1p&1) == 2 ) { - cprint(LINE_CPU+5, col2, " Dual Channel (128 bits)"); + cprint(LINE_CPU+5, col2, " Dual Channel (128 bits)"); col2 +=24; } else { - cprint(LINE_CPU+5, col2, " Single Channel (64 bits)"); + cprint(LINE_CPU+5, col2, " Single Channel (64 bits)"); col2 +=15; } @@ -1467,50 +1653,50 @@ static void poll_timings_nf2(void) { /* static void poll_timings_kt266(void) { - ulong dramtlr, dramtlr2, temp; + ulong dramtlr, dramtlr2, temp; pci_conf_read(0, 0, 0, 0x64, 1, &dramtlr); pci_conf_read(0, 0, 0, 0x02, 2, &dramtlr2); - cprint(LINE_CPU+5, col2 +1, "/ CAS : "); - col2 += 9; - - // CAS Latency (tCAS) - temp = ((dramtlr >> 4)&3); - if (temp == 0x0) { cprint(LINE_CPU+5, col2, "1-"); col2 +=2; } - if (temp == 0x1) { cprint(LINE_CPU+5, col2, "2-"); col2 +=2; } - if (temp == 0x3) { cprint(LINE_CPU+5, col2, "3-"); col2 +=2; } - if (temp == 0x2) { cprint(LINE_CPU+5, col2, "2.5-"); col2 +=4; } - - // RAS-To-CAS (tRCD) - if (((dramtlr >> 2)&1) == 0) { cprint(LINE_CPU+5, col2, "2-"); } - else { cprint(LINE_CPU+5, col2, "3-"); } - col2 +=2; - - // RAS Precharge (tRP) - if (((dramtlr >> 7)&1) == 0) { cprint(LINE_CPU+5, col2, "2-"); } - else { cprint(LINE_CPU+5, col2, "3-"); } - col2 +=2; - - // RAS Active to precharge (tRAS) - if (dramtlr2 == 0x3099) { - if (((dramtlr >> 6)&1) == 0) { - cprint(LINE_CPU+5, col2, "5"); } - else { cprint(LINE_CPU+5, col2, "6"); } - } else { - if (((dramtlr >> 6)&1) == 0) { - cprint(LINE_CPU+5, col2, "6"); } - else { cprint(LINE_CPU+5, col2, "7"); } - } - col2 +=1; - - - cprint(LINE_CPU+5, col2+1, "/ Interleave : "); col2 +=16; - temp = dramtlr&3; - - if (temp == 0) { cprint(LINE_CPU+5, col2, "Disabled"); } - if (temp == 1) { cprint(LINE_CPU+5, col2, "2-Way"); } - if (temp == 2) { cprint(LINE_CPU+5, col2, "4-Way"); } + cprint(LINE_CPU+5, col2 +1, "/ CAS : "); + col2 += 9; + + // CAS Latency (tCAS) + temp = ((dramtlr >> 4)&3); + if (temp == 0x0) { cprint(LINE_CPU+5, col2, "1-"); col2 +=2; } + if (temp == 0x1) { cprint(LINE_CPU+5, col2, "2-"); col2 +=2; } + if (temp == 0x3) { cprint(LINE_CPU+5, col2, "3-"); col2 +=2; } + if (temp == 0x2) { cprint(LINE_CPU+5, col2, "2.5-"); col2 +=4; } + + // RAS-To-CAS (tRCD) + if (((dramtlr >> 2)&1) == 0) { cprint(LINE_CPU+5, col2, "2-"); } + else { cprint(LINE_CPU+5, col2, "3-"); } + col2 +=2; + + // RAS Precharge (tRP) + if (((dramtlr >> 7)&1) == 0) { cprint(LINE_CPU+5, col2, "2-"); } + else { cprint(LINE_CPU+5, col2, "3-"); } + col2 +=2; + + // RAS Active to precharge (tRAS) + if (dramtlr2 == 0x3099) { + if (((dramtlr >> 6)&1) == 0) { + cprint(LINE_CPU+5, col2, "5"); } + else { cprint(LINE_CPU+5, col2, "6"); } + } else { + if (((dramtlr >> 6)&1) == 0) { + cprint(LINE_CPU+5, col2, "6"); } + else { cprint(LINE_CPU+5, col2, "7"); } + } + col2 +=1; + + + cprint(LINE_CPU+5, col2+1, "/ Interleave : "); col2 +=16; + temp = dramtlr&3; + + if (temp == 0) { cprint(LINE_CPU+5, col2, "Disabled"); } + if (temp == 1) { cprint(LINE_CPU+5, col2, "2-Way"); } + if (temp == 2) { cprint(LINE_CPU+5, col2, "4-Way"); } } */ @@ -1518,53 +1704,35 @@ static void poll_timings_kt266(void) { /* ------------------ Let's continue ------------------ */ /* ---------------------------------------------------- */ - -struct pci_memory_controller { - unsigned vendor; - unsigned device; - char *name; - int tested; - void (*poll_fsb)(void); - void (*poll_timings)(void); - void (*setup_ecc)(void); - void (*poll_errors)(void); -}; - static struct pci_memory_controller controllers[] = { /* Default unknown chipset */ { 0, 0, "", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - + /* AMD */ { 0x1022, 0x7006, "AMD 751", 0, poll_fsb_nothing, poll_timings_nothing, setup_amd751, poll_amd751 }, { 0x1022, 0x700c, "AMD 762", 0, poll_fsb_nothing, poll_timings_nothing, setup_amd76x, poll_amd76x }, { 0x1022, 0x700e, "AMD 761", 0, poll_fsb_nothing, poll_timings_nothing, setup_amd76x, poll_amd76x }, { 0x1022, 0x1100, "AMD 8000", 0, poll_fsb_amd64, poll_timings_amd64, setup_amd64, poll_amd64 }, { 0x1022, 0x7454, "AMD 8000", 0, poll_fsb_amd64, poll_timings_amd64, setup_amd64, poll_amd64 }, - - /* Motorola */ - { 0x1057, 0x4802, "Falcon", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - - /* Apple */ - { 0x106b, 0x0001, "Bandit", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - + /* SiS */ { 0x1039, 0x0600, "SiS 600", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, { 0x1039, 0x0620, "SiS 620", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, { 0x1039, 0x5600, "SiS 5600", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0645, "SiS 645", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0646, "SiS 645DX", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0630, "SiS 630", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0650, "SiS 650", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0651, "SiS 651", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0730, "SiS 730", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0735, "SiS 735", 0, poll_fsb_amd32, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0740, "SiS 740", 0, poll_fsb_amd32, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0745, "SiS 745", 0, poll_fsb_amd32, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0755, "SiS 755", 0, poll_fsb_amd64, poll_timings_amd64, setup_amd64, poll_amd64 }, - { 0x1039, 0x0748, "SiS 748", 0, poll_fsb_amd32, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0655, "SiS 655", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0648, "SiS 648", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, - { 0x1039, 0x0661, "SiS 661", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0645, "SiS 645", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0646, "SiS 645DX", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0630, "SiS 630", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0650, "SiS 650", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0651, "SiS 651", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0730, "SiS 730", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0735, "SiS 735", 0, poll_fsb_amd32, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0740, "SiS 740", 0, poll_fsb_amd32, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0745, "SiS 745", 0, poll_fsb_amd32, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0755, "SiS 755", 0, poll_fsb_amd64, poll_timings_amd64, setup_amd64, poll_amd64 }, + { 0x1039, 0x0748, "SiS 748", 0, poll_fsb_amd32, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0655, "SiS 655", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0648, "SiS 648", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, + { 0x1039, 0x0661, "SiS 661", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, /* ALi */ { 0x10b9, 0x1531, "Aladdin 4", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, @@ -1576,14 +1744,14 @@ static struct pci_memory_controller controllers[] = { { 0x1002, 0x5831, "ATi Radeon 9100 IGP", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, { 0x1002, 0x5832, "ATi Radeon 9100 IGP", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, { 0x1002, 0x5833, "ATi Radeon 9100 IGP", 0, poll_fsb_p4, poll_timings_nothing, setup_nothing, poll_nothing }, - + /* nVidia */ { 0x10de, 0x01A4, "nVidia nForce", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, { 0x10de, 0x01E0, "nVidia nForce2 SPP", 0, poll_fsb_nf2, poll_timings_nf2, setup_nothing, poll_nothing }, { 0x10de, 0x00D1, "nVidia nForce3", 0, poll_fsb_amd64, poll_timings_amd64, setup_amd64, poll_amd64 }, { 0x10de, 0x00E1, "nForce3 250", 0, poll_fsb_amd64, poll_timings_amd64, setup_amd64, poll_amd64 }, { 0x10de, 0x005E, "nVidia nForce4", 0, poll_fsb_amd64, poll_timings_amd64, setup_amd64, poll_amd64 }, - + /* VIA */ { 0x1106, 0x0305, "VIA KT133/KT133A", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, { 0x1106, 0x0391, "vt8371", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, @@ -1618,7 +1786,7 @@ static struct pci_memory_controller controllers[] = { { 0x8086, 0x1250, "Intel i430hx", 0, poll_fsb_nothing, poll_timings_nothing, setup_nothing, poll_nothing }, { 0x8086, 0x1A21, "Intel i840", 0, poll_fsb_nothing, poll_timings_nothing, setup_i840, poll_i840 }, { 0x8086, 0x1A30, "Intel i845", 0, poll_fsb_p4, poll_timings_nothing, setup_i845, poll_i845 }, - { 0x8086, 0x2560, "Intel i845E/G/PE/GE", 0, poll_fsb_p4, poll_timings_nothing, setup_i845, poll_i845 }, + { 0x8086, 0x2560, "Intel i845E/G/PE/GE", 0, poll_fsb_p4, poll_timings_nothing, setup_i845, poll_i845 }, { 0x8086, 0x2500, "Intel i820", 0, poll_fsb_nothing, poll_timings_nothing, setup_i820, poll_i820 }, { 0x8086, 0x2530, "Intel i850", 0, poll_fsb_p4, poll_timings_nothing, setup_i850, poll_i850 }, { 0x8086, 0x2531, "Intel i860", 1, poll_fsb_nothing, poll_timings_nothing, setup_i860, poll_i860 }, @@ -1635,26 +1803,30 @@ static struct pci_memory_controller controllers[] = { { 0x8086, 0x2540, "Intel E7500", 1, poll_fsb_p4, poll_timings_E750x, setup_iE7xxx, poll_iE7xxx }, { 0x8086, 0x254C, "Intel E7501", 1, poll_fsb_p4, poll_timings_E750x, setup_iE7xxx, poll_iE7xxx }, { 0x8086, 0x255d, "Intel E7205", 0, poll_fsb_p4, poll_timings_nothing, setup_iE7xxx, poll_iE7xxx }, + { 0x8086, 0x3592, "Intel E7320", 1, poll_fsb_p4, poll_timings_E7520, setup_iE7520, poll_iE7520 }, + { 0x8086, 0x3590, "Intel E7520", 1, poll_fsb_p4, poll_timings_E7520, setup_iE7520, poll_iE7520 }, { 0x8086, 0x2570, "Intel i848/i865", 0, poll_fsb_i875, poll_timings_i875, setup_i875, poll_nothing }, - { 0x8086, 0x2578, "Intel i875P", 0, poll_fsb_i875, poll_timings_i875, setup_i875, poll_i875 }, + { 0x8086, 0x2578, "Intel i875P", 0, poll_fsb_i875, poll_timings_i875, setup_i875, poll_i875 }, { 0x8086, 0x2550, "Intel E7505", 0, poll_fsb_p4, poll_timings_nothing, setup_iE7xxx, poll_iE7xxx }, { 0x8086, 0x3580, "Intel ", 0, poll_fsb_i855, poll_timings_i852, setup_nothing, poll_nothing }, { 0x8086, 0x3340, "Intel i855PM", 0, poll_fsb_i855, poll_timings_i855, setup_nothing, poll_nothing }, { 0x8086, 0x2580, "Intel i915P/G", 0, poll_fsb_i925, poll_timings_i925, setup_i925, poll_nothing }, + { 0x8086, 0x2590, "Intel i915PM/GM", 0, poll_fsb_i925, poll_timings_i925, setup_i925, poll_nothing }, { 0x8086, 0x2584, "Intel i925X/XE", 0, poll_fsb_i925, poll_timings_i925, setup_i925, poll_nothing }, + { 0x8086, 0x2770, "Intel i945P/G", 0, poll_fsb_i945, poll_timings_i925, setup_i925, poll_nothing }, }; static void print_memory_controller(void) { /* Print memory controller info */ - + int d; char *name; if (ctrl.index == 0) { return; } - + /* Print the controller name */ name = controllers[ctrl.index].name; col = 10; @@ -1662,7 +1834,7 @@ static void print_memory_controller(void) /* Now figure out how much I just printed */ while(name[col - 10] != '\0') { col++; - } + } /* Now print the memory controller capabilities */ cprint(LINE_CPU+4, col, " "); col++; if (ctrl.cap == ECC_UNKNOWN) { @@ -1709,8 +1881,8 @@ static void print_memory_controller(void) cprint(LINE_CPU+4, col +7, on?"+ ":"- "); col += 9; } - - + + /* Print advanced caracteristics */ col2 = 0; d = get_key(); |