summaryrefslogtreecommitdiffstats
path: root/controller.c
diff options
context:
space:
mode:
Diffstat (limited to 'controller.c')
-rw-r--r--controller.c201
1 files changed, 197 insertions, 4 deletions
diff --git a/controller.c b/controller.c
index 89589ab..9009996 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+ V4.00 Specific code (GPL V2.0)
+ * MemTest86+ V4.20 Specific code (GPL V2.0)
* By Samuel DEMEULEMEESTER, sdemeule@memtest.org
* http://www.canardpc.com - http://www.memtest.org
*/
@@ -23,6 +23,7 @@ int nhm_bus = 0x3F;
extern ulong extclock;
extern unsigned long imc_type;
extern struct cpu_ident cpu_id;
+extern int fail_safe;
#define rdmsr(msr,val1,val2) \
__asm__ __volatile__("rdmsr" \
@@ -175,7 +176,13 @@ static void poll_timings_nothing(void)
return;
}
-
+static void poll_fsb_failsafe(void)
+{
+/* Code to run for no specific fsb detection */
+ cprint(LINE_CPU+5, 0, "Chipset/IMC : ***FAIL SAFE***FAIL SAFE***FAIL SAFE***FAIL SAFE***FAIL SAFE***");
+ cprint(LINE_CPU+6, 0, "*** Memtest86+ is running in fail safe mode. Same reliability, less details ***");
+ return;
+}
static void setup_nothing(void)
{
ctrl.cap = ECC_NONE;
@@ -1230,6 +1237,24 @@ static float getNHMmultiplier(void)
return coef;
}
+static float getSNBmultiplier(void)
+{
+ unsigned int msr_lo, msr_hi;
+ float coef;
+
+ rdmsr(0x198, msr_lo, msr_hi);
+ coef = (msr_lo >> 8) & 0xFF;
+ if(coef < 4)
+ {
+ rdmsr(0xCE, msr_lo, msr_hi);
+ coef = (msr_lo >> 16) & 0xFF;
+ }
+
+
+
+ return coef;
+}
+
void getIntelPNS(void)
{
@@ -1456,6 +1481,58 @@ static void poll_fsb_k10(void) {
}
+static void poll_fsb_k14(void) {
+
+ unsigned long temp2;
+ unsigned long dramchr;
+ double dramclock;
+ unsigned long pns_low;
+ unsigned long pns_high;
+ unsigned long msr_psn;
+
+
+ /* If ECC not enabled : display CPU name as IMC */
+ if(ctrl.mode == ECC_NONE)
+ {
+ cprint(LINE_CPU+5, 0, "IMC : ");
+ for(msr_psn = 0; msr_psn < 5; msr_psn++)
+ {
+ rdmsr(0xC0010030+msr_psn, pns_low, pns_high);
+ cprint(LINE_CPU+5, 6+(msr_psn*8), convert_hex_to_char(pns_low & 0xff));
+ cprint(LINE_CPU+5, 7+(msr_psn*8), convert_hex_to_char((pns_low >> 8) & 0xff));
+ cprint(LINE_CPU+5, 8+(msr_psn*8), convert_hex_to_char((pns_low >> 16) & 0xff));
+ cprint(LINE_CPU+5, 9+(msr_psn*8), convert_hex_to_char((pns_low >> 24) & 0xff));
+ cprint(LINE_CPU+5, 10+(msr_psn*8), convert_hex_to_char(pns_high & 0xff));
+ cprint(LINE_CPU+5, 11+(msr_psn*8), convert_hex_to_char((pns_high >> 8) & 0xff));
+ cprint(LINE_CPU+5, 12+(msr_psn*8), convert_hex_to_char((pns_high >> 16) & 0xff));
+ cprint(LINE_CPU+5, 13+(msr_psn*8), convert_hex_to_char((pns_high >> 24) & 0xff));
+ }
+ cprint(LINE_CPU+5, 41, "(ECC : Disabled)");
+ }
+
+ /* First, we need the clock ratio */
+ pci_conf_read(0, 24, 2, 0x94, 4, &dramchr);
+ temp2 = (dramchr & 0x1F);
+
+ switch (temp2) {
+ default:
+ case 6:
+ dramclock = 400;
+ break;
+ case 10:
+ dramclock = 533;
+ break;
+ case 14:
+ dramclock = 667;
+ break;
+ }
+
+
+ /* print */
+ print_fsb_info(dramclock, "RAM : ", "DDR-");
+
+}
+
static void poll_fsb_i925(void) {
double dramclock, dramratio, fsb;
@@ -2291,6 +2368,50 @@ static void poll_fsb_wmr(void) {
}
+static void poll_fsb_snb(void) {
+
+ double dramclock, dramratio, fsb;
+ unsigned long dev0, mchcfg;
+ float coef = getSNBmultiplier();
+ long *ptr;
+
+ fsb = ((extclock / 1000) / coef);
+
+ if(ctrl.mode == ECC_NONE)
+ {
+ col = 0;
+ cprint(LINE_CPU+5, col, "IMC : "); col += 6;
+ getIntelPNS();
+ //cprint(LINE_CPU+5, col, "(ECC : Disabled)");
+ //col += 16;
+ }
+
+ /* Print FSB */
+ cprint(LINE_CPU+5, col +1, "/ BCLK : ");
+ col += 10;
+ dprint(LINE_CPU+5, col, fsb, 3,0);
+ col += 3;
+ cprint(LINE_CPU+5, col +1, "MHz");
+ col += 4;
+
+ /* Find dramratio */
+ pci_conf_read( 0, 0, 0, 0x48, 4, &dev0);
+ dev0 &= 0xFFFFC000;
+ ptr=(long*)(dev0+0x5E04);
+ mchcfg = *ptr & 0xFFFF;
+ dramratio = 1;
+
+ /* Get the clock ratio */
+ dramratio = (float)(*ptr & 0x1F) * (133.34f / 100.0f);
+
+ // Compute RAM Frequency
+ dramclock = fsb * dramratio;
+
+ // Print DRAM Freq
+ print_fsb_info(dramclock, "RAM : ", "DDR3-");
+
+}
+
/* ------------------ Here the code for Timings detection ------------------ */
/* ------------------------------------------------------------------------- */
@@ -2747,6 +2868,52 @@ static void poll_timings_wmr(void) {
}
+static void poll_timings_snb(void) {
+
+ float cas;
+ int rcd, rp, ras;
+ ulong dev0, offset;
+ ulong IMC_Register, MCMain0_Register, MCMain1_Register;
+ long *ptr;
+
+ //Now, read MMR Base Address
+ pci_conf_read( 0, 0, 0, 0x48, 4, &dev0);
+ dev0 &= 0xFFFFC000;
+
+ offset = 0x0000;
+
+ ptr = (long*)(dev0+offset+0x4000);
+ IMC_Register = *ptr & 0xFFFFFFFF;
+
+ // CAS Latency (tCAS)
+ cas = (float)((IMC_Register >> 8) & 0x0F);
+
+ // RAS-To-CAS (tRCD)
+ rcd = IMC_Register & 0x0F;
+
+ // RAS Precharge (tRP)
+ rp = (IMC_Register >> 4) & 0x0F;
+
+ // RAS Active to precharge (tRAS)
+ ras = (IMC_Register >> 16) & 0xFF;
+
+ print_timings_info(cas, rcd, rp, ras);
+
+ cprint(LINE_CPU+6, col2+1, "/"); col2 +=2;
+
+ // Channels
+ ptr = (long*)(dev0+offset+0x5004);
+ MCMain0_Register = *ptr & 0xFFFF;
+ ptr = (long*)(dev0+offset+0x5008);
+ MCMain1_Register = *ptr & 0xFFFF;
+
+ if(MCMain0_Register == 0 || MCMain1_Register == 0) {
+ cprint(LINE_CPU+6, col2+1, "Single Channel");
+ } else {
+ cprint(LINE_CPU+6, col2+1, "Dual Channel");
+ }
+
+}
static void poll_timings_5400(void) {
@@ -3083,6 +3250,27 @@ static void poll_timings_k10(void) {
}
+static void poll_timings_k14(void) {
+
+ ulong dramt0, dramlow;
+ int cas, rcd, rp, rc, ras;
+
+ pci_conf_read(0, 24, 2, 0x88, 4, &dramlow);
+ pci_conf_write(0, 24, 2, 0xF0, 4, 0x00000040);
+ pci_conf_read(0, 24, 2, 0xF4, 4, &dramt0);
+
+ cas = (dramlow & 0xF) + 4;
+ rcd = (dramt0 & 0xF) + 5;
+ rp = ((dramt0 >> 8) & 0xF) + 5;
+ ras = ((dramt0 >> 16) & 0x1F) + 15;
+ rc = ((dramt0 >> 24) & 0x3F) + 16;
+
+ print_timings_info(cas, rcd, rp, ras);
+
+ cprint(LINE_CPU+6, col2, "/ DDR3 (64 bits)");
+
+}
+
static void poll_timings_EP80579(void) {
ulong drt1, drt2;
@@ -3380,9 +3568,13 @@ static struct pci_memory_controller controllers[] = {
{ 0xFFFF, 0x0001, "Core IMC", 0, poll_fsb_nhm, poll_timings_nhm, setup_nhm, poll_nothing},
{ 0xFFFF, 0x0002, "Core IMC 32nm", 0, poll_fsb_nhm32, poll_timings_nhm, setup_nhm32, poll_nothing},
{ 0xFFFF, 0x0003, "Core IMC 32nm", 0, poll_fsb_wmr, poll_timings_wmr, setup_wmr, poll_nothing},
+ { 0xFFFF, 0x0004, "SNB IMC 32nm", 0, poll_fsb_snb, poll_timings_snb, setup_wmr, poll_nothing},
{ 0xFFFF, 0x0100, "AMD K8 IMC", 0, poll_fsb_amd64, poll_timings_amd64, setup_amd64, poll_amd64 },
- { 0xFFFF, 0x0101, "AMD K10 IMC", 0, poll_fsb_k10, poll_timings_k10, setup_k10, poll_nothing }
-
+ { 0xFFFF, 0x0101, "AMD K10 IMC", 0, poll_fsb_k10, poll_timings_k10, setup_k10, poll_nothing },
+ { 0xFFFF, 0x0102, "AMD APU IMC", 0, poll_fsb_k14, poll_timings_k14, setup_nothing, poll_nothing },
+
+ /* Fail Safe */
+ { 0xFFFF, 0xFFFF, "", 0, poll_fsb_failsafe, poll_timings_nothing, setup_nothing, poll_nothing }
};
static void print_memory_controller(void)
@@ -3474,6 +3666,7 @@ void find_controller(void)
// Detect IMC by CPUID
if(imc_type) { vendor = 0xFFFF; device = imc_type; }
+ if(fail_safe) { vendor = 0xFFFF; device = 0xFFFF; }
ctrl.index = 0;
if (result == 0) {