📄 controller.c
字号:
if ((drc & 3) == 2) { cprint(LINE_CPU+5, col +1, "- Type : DDR-II"); } else { cprint(LINE_CPU+5, col +1, "- Type : DDR-I"); } // Now, detect timings cprint(LINE_CPU+6, 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+6, col2, "5-"); } else if (temp == 0x1) { cprint(LINE_CPU+6, col2, "4-"); } else if (temp == 0x2) { cprint(LINE_CPU+6, col2, "3-"); } else { cprint(LINE_CPU+6, col2, "6-"); } } else { // Timings DDR-I if (temp == 0x0) { cprint(LINE_CPU+6, col2, "3-"); } else if (temp == 0x1) { cprint(LINE_CPU+6, col2, "2.5-"); col2 +=2;} else { cprint(LINE_CPU+6, col2, "2-"); } } col2 +=2; // RAS-To-CAS (tRCD) dprint(LINE_CPU+6, col2, ((drt >> 4)& 0x3)+2, 1 ,0); cprint(LINE_CPU+6, col2+1, "-"); col2 +=2; // RAS Precharge (tRP) dprint(LINE_CPU+6, col2, (drt&0x3)+2, 1 ,0); cprint(LINE_CPU+6, col2+1, "-"); col2 +=2; // RAS Active to precharge (tRAS) // If Lakeport, than change tRAS computation (Thanks to CDH, again) if (idetect > 0x2700) temp = ((drt >> 19)& 0x1F); else temp = ((drt >> 20)& 0x0F); dprint(LINE_CPU+6, col2, temp , 1 ,0); (temp < 10)?(col2 += 1):(col2 += 2); cprint(LINE_CPU+6, col2+1, "/"); col2 +=2; temp = (dcc&0x3); if (temp == 1) { cprint(LINE_CPU+6, col2, " Dual Channel (Asymmetric)"); } else if (temp == 2) { cprint(LINE_CPU+6, col2, " Dual Channel (Interleaved)"); } else { cprint(LINE_CPU+6, col2, " Single Channel (64 bits)"); }}static void poll_timings_i965(void) { // Thanks for CDH optis ulong dev0, temp, c0ckectrl, c1ckectrl, offset; ulong ODT_Control_Register, Precharge_Register, ACT_Register, Read_Register, Misc_Register; long *ptr; //Now, read MMR Base Address pci_conf_read( 0, 0, 0, 0x48, 4, &dev0); dev0 &= 0xFFFFC000; ptr = (long*)(dev0+0x260); c0ckectrl = *ptr & 0xFFFFFFFF; ptr = (long*)(dev0+0x660); c1ckectrl = *ptr & 0xFFFFFFFF; // If DIMM 0 not populated, check DIMM 1 ((c0ckectrl) >> 20 & 0xF)?(offset = 0):(offset = 0x400); ptr = (long*)(dev0+offset+0x29C); ODT_Control_Register = *ptr & 0xFFFFFFFF; ptr = (long*)(dev0+offset+0x250); Precharge_Register = *ptr & 0xFFFFFFFF; ptr = (long*)(dev0+offset+0x252); ACT_Register = *ptr & 0xFFFFFFFF; ptr = (long*)(dev0+offset+0x258); Read_Register = *ptr & 0xFFFFFFFF; ptr = (long*)(dev0+offset+0x244); Misc_Register = *ptr & 0xFFFFFFFF; //Intel 965 Series only support DDR2 cprint(LINE_CPU+5, col +1, "- Type : DDR-II"); // Now, detect timings cprint(LINE_CPU+6, col2 +1, "/ CAS : "); col2 += 9; // CAS Latency (tCAS) temp = ((ODT_Control_Register >> 17)& 7) + 3.0f; dprint(LINE_CPU+6, col2, temp, 1 ,0); cprint(LINE_CPU+6, col2+1, "-"); (temp < 10)?(col2 += 2):(col2 += 3); // RAS-To-CAS (tRCD) temp = (Read_Register >> 16) & 0xF; dprint(LINE_CPU+6, col2, temp, 1 ,0); cprint(LINE_CPU+6, col2+1, "-"); (temp < 10)?(col2 += 2):(col2 += 3); // RAS Precharge (tRP) temp = (ACT_Register >> 13) & 0xF; dprint(LINE_CPU+6, col2, temp, 1 ,0); cprint(LINE_CPU+6, col2+1, "-"); (temp < 10)?(col2 += 2):(col2 += 3); // RAS Active to precharge (tRAS) temp = (Precharge_Register >> 11) & 0x1F; dprint(LINE_CPU+6, col2, temp, 1 ,0); (temp < 10)?(col2 += 1):(col2 += 2); cprint(LINE_CPU+6, col2+1, "/"); col2 +=2; if ((c0ckectrl >> 20 & 0xF) && (c1ckectrl >> 20 & 0xF)) { cprint(LINE_CPU+6, col2+1, "Dual Channel"); } else { cprint(LINE_CPU+6, col2+1, "Single Channel"); }}static void poll_timings_im965(void) { // Thanks for CDH optis ulong dev0, temp, c0ckectrl, c1ckectrl, offset; ulong ODT_Control_Register, Precharge_Register; long *ptr; //Now, read MMR Base Address pci_conf_read( 0, 0, 0, 0x48, 4, &dev0); dev0 &= 0xFFFFC000; ptr = (long*)(dev0+0x1200); c0ckectrl = *ptr & 0xFFFFFFFF; ptr = (long*)(dev0+0x1300); c1ckectrl = *ptr & 0xFFFFFFFF; // If DIMM 0 not populated, check DIMM 1 ((c0ckectrl) >> 20 & 0xF)?(offset = 0):(offset = 0x100); ptr = (long*)(dev0+offset+0x121C); ODT_Control_Register = *ptr & 0xFFFFFFFF; ptr = (long*)(dev0+offset+0x1214); Precharge_Register = *ptr & 0xFFFFFFFF; //Intel 965 Series only support DDR2 cprint(LINE_CPU+5, col+1, "- Type : DDR-II"); // Now, detect timings cprint(LINE_CPU+6, col2 +1, "/ CAS : "); col2 += 9; // CAS Latency (tCAS) temp = ((ODT_Control_Register >> 23)& 7) + 3.0f; dprint(LINE_CPU+6, col2, temp, 1 ,0); cprint(LINE_CPU+6, col2+1, "-"); (temp < 10)?(col2 += 2):(col2 += 3); // RAS-To-CAS (tRCD) temp = ((Precharge_Register >> 5)& 7) + 2.0f; dprint(LINE_CPU+6, col2, temp, 1 ,0); cprint(LINE_CPU+6, col2+1, "-"); (temp < 10)?(col2 += 2):(col2 += 3); // RAS Precharge (tRP) temp = (Precharge_Register & 7) + 2.0f; dprint(LINE_CPU+6, col2, temp, 1 ,0); cprint(LINE_CPU+6, col2+1, "-"); (temp < 10)?(col2 += 2):(col2 += 3); // RAS Active to precharge (tRAS) temp = (Precharge_Register >> 21) & 0x1F; dprint(LINE_CPU+6, col2, temp, 1 ,0); (temp < 10)?(col2 += 1):(col2 += 2); cprint(LINE_CPU+6, col2+1, "/"); col2 +=2; if ((c0ckectrl >> 20 & 0xF) && (c1ckectrl >> 20 & 0xF)) { cprint(LINE_CPU+6, col2+1, "Dual Channel"); } else { cprint(LINE_CPU+6, col2+1, "Single Channel"); }}static void poll_timings_p35(void) { // Thanks for CDH optis float cas; int rcd, rp, ras; ulong dev0, Device_ID, Memory_Check, c0ckectrl, c1ckectrl, offset; ulong ODT_Control_Register, Precharge_Register, ACT_Register, Read_Register, Misc_Register; long *ptr; pci_conf_read( 0, 0, 0, 0x02, 2, &Device_ID); Device_ID &= 0xFFFF; //Now, read MMR Base Address pci_conf_read( 0, 0, 0, 0x48, 4, &dev0); dev0 &= 0xFFFFC000; ptr = (long*)(dev0+0x260); c0ckectrl = *ptr & 0xFFFFFFFF; ptr = (long*)(dev0+0x660); c1ckectrl = *ptr & 0xFFFFFFFF; // If DIMM 0 not populated, check DIMM 1 ((c0ckectrl) >> 20 & 0xF)?(offset = 0):(offset = 0x400); ptr = (long*)(dev0+offset+0x265); ODT_Control_Register = *ptr & 0xFFFFFFFF; ptr = (long*)(dev0+offset+0x25D); Precharge_Register = *ptr & 0xFFFFFFFF; ptr = (long*)(dev0+offset+0x252); ACT_Register = *ptr & 0xFFFFFFFF; ptr = (long*)(dev0+offset+0x258); Read_Register = *ptr & 0xFFFFFFFF; ptr = (long*)(dev0+offset+0x244); Misc_Register = *ptr & 0xFFFFFFFF; // On P45, check 1A8 if(Device_ID > 0x2E00) { ptr = (long*)(dev0+offset+0x1A8); Memory_Check = *ptr & 0xFFFFFFFF; Memory_Check >>= 2; Memory_Check &= 1; Memory_Check = !Memory_Check; } else { ptr = (long*)(dev0+offset+0x1E8); Memory_Check = *ptr & 0xFFFFFFFF; } //Determine DDR-II or DDR-III if (Memory_Check & 1) { cprint(LINE_CPU+5, col +1, "- Type : DDR2"); } else { cprint(LINE_CPU+5, col +1, "- Type : DDR3"); } // CAS Latency (tCAS) if(Device_ID > 0x2E00) { cas = ((ODT_Control_Register >> 8)& 0x3F) - 6.0f; } else { cas = ((ODT_Control_Register >> 8)& 0x3F) - 9.0f; } // RAS-To-CAS (tRCD) rcd = (Read_Register >> 17) & 0xF; // RAS Precharge (tRP) rp = (ACT_Register >> 13) & 0xF; // RAS Active to precharge (tRAS) ras = Precharge_Register & 0x3F; print_timings_info(cas, rcd, rp, ras); cprint(LINE_CPU+6, col2+1, "/"); col2 +=2; if ((c0ckectrl >> 20 & 0xF) && (c1ckectrl >> 20 & 0xF)) { cprint(LINE_CPU+6, col2+1, "Dual Channel"); } else { cprint(LINE_CPU+6, col2+1, "Single Channel"); }}static void poll_timings_5400(void) { // Thanks for CDH optis ulong ambase, mtr1, mtr2, offset, mca, temp; long *ptr; //Hard-coded Ambase value (should not be realocated by software when using Memtest86+ ambase = 0xFE000000; offset = mtr1 = mtr2 = 0; // Will loop until a valid populated channel is found // Bug : DIMM 0 must be populated or it will fall in an endless loop while(((mtr2 & 0xF) < 3) || ((mtr2 & 0xF) > 6)) { ptr = (long*)(ambase+0x378+offset); mtr1 = *ptr & 0xFFFFFFFF; ptr = (long*)(ambase+0x37C+offset); mtr2 = *ptr & 0xFFFFFFFF; offset += 0x8000; } pci_conf_read( 0, 16, 1, 0x58, 4, &mca); //This chipset only supports FB-DIMM (Removed => too long) //cprint(LINE_CPU+5, col +1, "- Type : FBD"); // Now, detect timings cprint(LINE_CPU+6, col2 +1, "/ CAS : "); col2 += 9; // CAS Latency (tCAS) temp = mtr2 & 0xF; dprint(LINE_CPU+6, col2, temp, 1 ,0); cprint(LINE_CPU+6, col2+1, "-"); col2 += 2; // RAS-To-CAS (tRCD) temp = 6 - ((mtr1 >> 10) & 3); dprint(LINE_CPU+6, col2, temp, 1 ,0); cprint(LINE_CPU+6, col2+1, "-"); col2 += 2; // RAS Precharge (tRP) temp = 6 - ((mtr1 >> 8) & 3); dprint(LINE_CPU+6, col2, temp, 1 ,0); cprint(LINE_CPU+6, col2+1, "-"); col2 += 2; // RAS Active to precharge (tRAS) temp = 16 - (3 * ((mtr1 >> 29) & 3)) + ((mtr1 >> 12) & 3); if(((mtr1 >> 12) & 3) == 3 && ((mtr1 >> 29) & 3) == 2) { temp = 9; } dprint(LINE_CPU+6, col2, temp, 1 ,0); (temp < 10)?(col2 += 1):(col2 += 2); cprint(LINE_CPU+6, col2+1, "/"); col2 +=2; if ((mca >> 14) & 1) { cprint(LINE_CPU+6, col2+1, "Single Channel"); } else { cprint(LINE_CPU+6, col2+1, "Dual Channel"); }}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+6, col2, "/ Dual Channel (128 bits)"); } else { cprint(LINE_CPU+6, 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+6, col2 +1, "/ CAS : "); col2 += 9; // CAS Latency (tCAS) temp = ((drt >> 4)&0x1); if (temp == 0x0) { cprint(LINE_CPU+6, col2, "2.5-"); col2 += 4; } else { cprint(LINE_CPU+6, col2, "2-"); col2 +=2; } // RAS-To-CAS (tRCD) temp = ((drt >> 2)& 0x1); if (temp == 0x0) { cprint(LINE_CPU+6, col2, "3-"); } else { cprint(LINE_CPU+6, col2, "2-"); } col2 +=2; // RAS Precharge (tRP) temp = (drt&0x1); if (temp == 0x0) { cprint(LINE_CPU+6, col2, "3-"); } else { cprint(LINE_CPU+6, col2, "2-"); } col2 +=2; // RAS Active to precharge (tRAS) temp = 7-((drt >> 9)& 0x3); if (temp == 0x0) { cprint(LINE_CPU+6, col2, "7"); } if (temp == 0x1) { cprint(LINE_CPU+6, col2, "6"); } if (temp == 0x2) { cprint(LINE_CPU+6, col2, "5"); } col2 +=1;}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+6, col2, "/ Dual Channel (128 bits)"); } else { cprint(LINE_CPU+6, col2, "/ Single Channel (64 bits)"); }}static void poll_timings_i852(void) { ulong drt, temp; pci_conf_read( 0, 0, 1, 0x60, 4, &drt); /* Now, we could print some additionnals timings infos) */ cprint(LINE_CPU+6, col2 +1, "/ CAS : "); col2 += 9; // CAS Latency (tCAS) temp = ((drt >> 5)&0x1); if (temp == 0x0) { cprint(LINE_CPU+6, col2, "2.5-"); col2 += 4; } else { cprint(LINE_CPU+6, col2, "2-"); col2 +=2; } // RAS-To-CAS (tRCD) temp = ((drt >> 2)& 0x3); if (temp == 0x0) { cprint(LINE_CPU+6, col2, "4-"); } if (temp == 0x1) { cprint(LINE_CPU+6, col2, "3-"); } else { cprint(LINE_CPU+6, col2, "2-"); } col2 +=2; // RAS Precharge (tRP) temp = (drt&0x3); if (temp == 0x0) { cprint(LINE_CPU+6, col2, "4-"); } if (temp == 0x1) { cprint(LINE_CPU+6, col2, "3-"); } else { cprint(LINE_CPU+6, col2, "2-"); } col2 +=2; // RAS Active to precharge (tRAS) temp = ((drt >> 9)& 0x3); if (temp == 0x0) { cprint(LINE_CPU+6, col2, "8"); col2 +=7; } if (temp == 0x1) { cprint(LINE_CPU+6, col2, "7"); col2 +=6; } if (temp == 0x2) { cprint(LINE_CPU+6, col2, "6"); col2 +=5; } if (temp == 0x3) { cprint(LINE_CPU+6, col2, "5"); col2 +=5; } col2 +=1;}static void poll_timings_amd64(void) { ulong dramtlr, dramclr; int temp; int trcd, trp, tras ; cprint(LINE_CPU+6, col2 +1, "/ CAS : "); col2 += 9; pci_conf_read(0, 24, 2, 0x88, 4, &dramtlr); pci_conf_read(0, 24, 2, 0x90, 4, &dramclr); if (((cpu_id.ext >> 16) & 0xF) >= 4) { /* NEW K8 0Fh Family 90 nm (DDR2) */ // CAS Latency (tCAS) temp = (dramtlr & 0x7) + 1; dprint(LINE_CPU+6, col2, temp , 1 ,0); cprint(LINE_CPU+6, col2 +1, "-"); col2 +=2; // RAS-To-CAS (tRCD) trcd = ((dramtlr >> 4) & 0x3) + 3; dprint(LINE_CPU+6, col2, trcd , 1 ,0); cprint(LINE_CPU+6, col2 +1, "-"); col2 +=2; // RAS Precharge (tRP) trp = ((dramtlr >> 8) & 0x3) + 3; dprint(LINE_CPU+6, col2, trp , 1 ,0); cprint(LINE_CPU+6, col2 +1, "-"); col2 +=2; // RAS Active to precharge (tRAS) tras = ((dramtlr >> 12) & 0xF) + 3; if (tras < 10){ dprint(LINE_CPU+6, col2, tras , 1 ,0); col2 += 1; } else { dprint(LINE_CPU+6, col2, tras , 2 ,0); col2 += 2; } cprint(LINE_CPU+6, col2+1, "/"); col2 +=2; // Print 64 or 128 bits mode if ((dramclr >> 11)&1) { cprint(LINE_CPU+6, col2, " DDR-2 (128 bits)"); col2 +=17; } else { cprint(LINE_CPU+6, col2, " DDR-2 (64 bits)"); col2 +=16; } } else { /* OLD K8 (DDR1) */ // CAS Latency (tCAS) temp = (dramtlr & 0x7); if (temp == 0x1) { cprint(LINE_CPU+6, col2, "2-"); col2 +=2; } if (temp == 0x2) { cprint(LINE_CPU+6, col2, "3-"); col2 +=2; } if (temp == 0x5) { cprint(LINE_CPU+6, col2, "2.5-"); col2 +=4; } // RAS-To-CAS (tRCD) trcd = ((dramtlr >> 12) & 0x7); dprint(LINE_CPU+6, col2, trcd , 1 ,0); cprint(LINE_CPU+6, col2 +1, "-"); col2 +=2; // RAS Precharge (tRP) trp = ((dramtlr >> 24) & 0x7);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -