summaryrefslogtreecommitdiffstats
path: root/init.c
diff options
context:
space:
mode:
Diffstat (limited to 'init.c')
-rw-r--r--init.c1933
1 files changed, 841 insertions, 1092 deletions
diff --git a/init.c b/init.c
index f7f43c1..754b8d7 100644
--- a/init.c
+++ b/init.c
@@ -1,59 +1,82 @@
-/* init.c - MemTest-86 Version 3.0
- *
- * Released under version 2 of the Gnu Public License.
- * By Chris Brady, cbrady@sgi.com
- * ----------------------------------------------------
- * MemTest86+ V4.20 Specific code (GPL V2.0)
+/*
+ * MemTest86+ V5 Specific code (GPL V2.0)
* By Samuel DEMEULEMEESTER, sdemeule@memtest.org
* http://www.canardpc.com - http://www.memtest.org
+ * ------------------------------------------------
+ * init.c - MemTest-86 Version 3.6
+ *
+ * Released under version 2 of the Gnu Public License.
+ * By Chris Brady
*/
+
+#include "stdin.h"
+#include "stddef.h"
#include "test.h"
#include "defs.h"
#include "config.h"
-#include "controller.h"
-#include "pci.h"
+#include "cpuid.h"
+#include "smp.h"
#include "io.h"
#include "spd.h"
-
-#define rdmsr(msr,val1,val2) \
- __asm__ __volatile__("rdmsr" \
- : "=a" (val1), "=d" (val2) \
- : "c" (msr))
+#include "pci.h"
+#include "controller.h"
extern struct tseq tseq[];
extern short memsz_mode;
-extern short firmware;
-extern short dmi_initialized;
-extern int dmi_err_cnts[MAX_DMI_MEMDEVS];
-
-struct cpu_ident cpu_id;
-ulong st_low, st_high;
-ulong end_low, end_high;
-ulong cal_low, cal_high;
-ulong extclock;
+extern int num_cpus;
+extern int act_cpus;
+extern int found_cpus;
unsigned long imc_type = 0;
+extern int maxcpus;
+extern char cpu_mask[];
+extern void initialise_cpus();
+
+/* Here we store all of the cpuid data */
+extern struct cpu_ident cpu_id;
-int l1_cache, l2_cache, l3_cache;
+int l1_cache=0, l2_cache=0, l3_cache=0;
int tsc_invariable = 0;
+ulong extclock;
-ulong memspeed(ulong src, ulong len, int iter, int type);
+ulong memspeed(ulong src, ulong len, int iter);
static void cpu_type(void);
-static void cacheable(void);
static int cpuspeed(void);
-int beepmode, fail_safe;
+static void get_cache_size();
+static void cpu_cache_speed();
+void get_cpuid();
+int beepmode;
+extern short dmi_initialized;
+extern int dmi_err_cnts[MAX_DMI_MEMDEVS];
/* Failsafe function */
/* msec: number of ms to wait - scs: scancode expected to stop */
+/* bits: 0 = extended detection - 1: SMP - 2: Temp Check */
+/* 3: MP SMP - 4-7: RSVD */
void failsafe(int msec, int scs)
{
- int ip;
+ int i;
ulong sh, sl, l, h, t;
unsigned char c;
+ volatile char *pp;
- cprint(18, 22, "Press *F1* to enter Fail-Safe Mode");
+ for(i=0, pp=(char *)(SCREEN_ADR+(18*160)+(18*2)+1); i<40; i++, pp+=2) {
+ *pp = 0x1E;
+ }
+ for(i=0, pp=(char *)(SCREEN_ADR+(18*160)+(18*2)+1); i<3; i++, pp+=2) {
+ *pp = 0x9E;
+ }
+ for(i=0, pp=(char *)(SCREEN_ADR+(18*160)+(55*2)+1); i<3; i++, pp+=2) {
+ *pp = 0x9E;
+ }
- ip = 0;
+ cprint(18, 18, "==> Press F1 to enter Fail-Safe Mode <==");
+
+ if(v->fail_safe & 2)
+ {
+ cprint(19, 15, "==> Press F2 to force Multi-Threading (SMP) <==");
+ }
+
/* save the starting time */
asm __volatile__(
"rdtsc":"=a" (sl),"=d" (sh));
@@ -73,34 +96,63 @@ void failsafe(int msec, int scs)
t += (l / v->clks_msec);
/* Is the time up? */
- if (t >= msec) {
- cprint(18, 22, " ");
- break;
- }
+ if (t >= msec) { break; }
/* Is expected Scan code pressed? */
c = get_key();
c &= 0x7f;
- if(c == scs) {
- fail_safe = 1;
- cprint(18, 22, " ");
+ /* F1 */
+ if(c == scs) { v->fail_safe |= 1; break; }
+
+ /* F2 */
+ if(c == scs+1)
+ {
+ v->fail_safe ^= 2;
break;
- }
+
+ }
+
+ /* F3 */
+ if(c == scs+2)
+ {
+ if(v->fail_safe & 2) { v->fail_safe ^= 2; }
+ v->fail_safe |= 8;
+ break;
+ }
+
}
+
+ cprint(18, 18, " ");
+ cprint(19, 15, " ");
+
+ for(i=0, pp=(char *)(SCREEN_ADR+(18*160)+(18*2)+1); i<40; i++, pp+=2) {
+ *pp = 0x17;
+ }
+
}
+
+
static void display_init(void)
{
int i;
volatile char *pp;
+
+ /* Set HW cursor out of screen boundaries */
+ __outb(0x0F, 0x03D4);
+ __outb(0xFF, 0x03D5);
+
+ __outb(0x0E, 0x03D4);
+ __outb(0xFF, 0x03D5);
+
serial_echo_init();
- serial_echo_print("\x1B[LINE_SCROLL;24r"); /* Set scroll area row 7-23 */
- serial_echo_print("\x1B[H\x1B[2J"); /* Clear Screen */
- serial_echo_print("\x1B[37m\x1B[44m");
- serial_echo_print("\x1B[0m");
- serial_echo_print("\x1B[37m\x1B[44m");
+ serial_echo_print("INE_SCROLL;24r"); /* Set scroll area row 7-23 */
+ serial_echo_print(""); /* Clear Screen */
+ serial_echo_print("");
+ serial_echo_print("");
+ serial_echo_print("");
/* Clear screen & set background to blue */
for(i=0, pp=(char *)(SCREEN_ADR); i<80*24; i++) {
@@ -108,12 +160,13 @@ static void display_init(void)
*pp++ = 0x17;
}
- /* Make the name background red */
+ /* Make the name background green */
for(i=0, pp=(char *)(SCREEN_ADR+1); i<TITLE_WIDTH; i++, pp+=2) {
*pp = 0x20;
}
- cprint(0, 0, " Memtest86 v4.20 ");
+ cprint(0, 0, " Memtest86 5.01 ");
+ /* Set Blinking "+" */
for(i=0, pp=(char *)(SCREEN_ADR+1); i<2; i++, pp+=30) {
*pp = 0xA4;
}
@@ -124,7 +177,7 @@ static void display_init(void)
*pp = 0x71;
}
- serial_echo_print("\x1B[0m");
+ serial_echo_print("");
}
/*
@@ -142,31 +195,49 @@ void init(void)
/* Setup the display */
display_init();
-
- /* Determine the memory map */
- if ((firmware == FIRMWARE_UNKNOWN) &&
- (memsz_mode != SZ_MODE_PROBE)) {
- if (query_linuxbios()) {
- firmware = FIRMWARE_LINUXBIOS;
- }
- else if (query_pcbios()) {
- firmware = FIRMWARE_PCBIOS;
- }
+ cprint(5, 60, "| Time: 0:00:00");
+ cprint(1, COL_MID,"Pass %");
+ cprint(2, COL_MID,"Test %");
+ cprint(3, COL_MID,"Test #");
+ cprint(4, COL_MID,"Testing: ");
+ cprint(5, COL_MID,"Pattern: ");
+ cprint(1, 0, "CLK: (32b Mode)");
+ cprint(2, 0, "L1 Cache: Unknown ");
+ cprint(3, 0, "L2 Cache: Unknown ");
+ cprint(4, 0, "L3 Cache: None ");
+ cprint(5, 0, "Memory : ");
+ cprint(6, 0, "------------------------------------------------------------------------------");
+ cprint(7, 0, "Core#:");
+ cprint(8, 0, "State:");
+ cprint(9, 0, "Cores: Active / Total (Run: All) | Pass: 0 Errors: 0 ");
+ cprint(10, 0, "------------------------------------------------------------------------------");
+
+ /*
+ for(i=0, pp=(char *)(SCREEN_ADR+(5*160)+(53*2)+1); i<20; i++, pp+=2) {
+ *pp = 0x92;
}
- mem_size();
+ for(i=0, pp=(char *)(SCREEN_ADR+0*160+1); i<80; i++, pp+=2) {
+ *pp = 0x47;
+ }
+ */
+
+ cprint(7, 39, "| Chipset : Unknown");
+ cprint(8, 39, "| Memory Type : Unknown");
+
- /* setup pci */
- pci_init();
+ for(i=0; i < 6; i++) {
+ cprint(i, COL_MID-2, "| ");
+ }
+
+ footer();
- /* setup beep mode */
- beepmode = BEEP_MODE;
+ aprint(5, 10, v->test_pages);
- v->test = 0;
- v->pass = 0;
- v->msg_line = 0;
- v->ecount = 0;
- v->ecc_ecount = 0;
+ v->pass = 0;
+ v->msg_line = 0;
+ v->ecount = 0;
+ v->ecc_ecount = 0;
v->testsel = -1;
v->msg_line = LINE_SCROLL-1;
v->scroll_start = v->msg_line * 160;
@@ -183,7 +254,7 @@ void init(void)
v->erri.ebits = 0;
v->erri.hdr_flag = 0;
v->erri.tbits = 0;
- for (i=0; tseq[i].msg != 0; i++) {
+ for (i=0; tseq[i].msg != NULL; i++) {
tseq[i].errors = 0;
}
if (dmi_initialized) {
@@ -193,984 +264,727 @@ void init(void)
}
}
}
+
+ /* setup beep mode */
+ beepmode = BEEP_MODE;
+
+ /* Get the cpu and cache information */
+ get_cpuid();
+
+ /* setup pci */
+ pci_init();
- cprint(LINE_CPU+1, 0, "L1 Cache: Unknown ");
- cprint(LINE_CPU+2, 0, "L2 Cache: Unknown ");
- cprint(LINE_CPU+3, 0, "L3 Cache: None ");
- cprint(LINE_CPU+4, 0, "Memory : |-------------------------------------------------");
- aprint(LINE_CPU+4, 10, v->test_pages);
- cprint(LINE_CPU+5, 0, "Chipset : ");
+ get_cache_size();
cpu_type();
- /* Check fail safe */
- failsafe(2000, 0x3B);
+ cpu_cache_speed();
- /* Find the memory controller */
- find_controller();
+ /* Check fail safe */
+ failsafe(5000, 0x3B);
- /* Find Memory Specs */
- if(fail_safe == 0) { get_spd_spec(); }
+ /* Initalize SMP */
+ initialise_cpus();
+
+ for (i = 0; i <num_cpus; i++) {
+ dprint(7, i+7, i%10, 1, 0);
+ cprint(8, i+7, "S");
+ }
- if (v->rdtsc) {
- cacheable();
- cprint(LINE_TIME, COL_TIME+4, ": :");
+ dprint(9, 19, num_cpus, 2, 0);
+
+ if((v->fail_safe & 3) == 2)
+ {
+ cprint(LINE_CPU,9, "(SMP: Disabled)");
+ cprint(LINE_RAM,9, "Running...");
}
- cprint(0, COL_MID,"Pass %");
- cprint(1, COL_MID,"Test %");
- cprint(2, COL_MID,"Test #");
- cprint(3, COL_MID,"Testing: ");
- cprint(4, COL_MID,"Pattern: ");
- cprint(LINE_INFO-2, 0, " WallTime Cached RsvdMem MemMap Cache ECC Test Pass Errors ECC Errs");
- cprint(LINE_INFO-1, 0, " --------- ------ ------- -------- ----- --- ---- ---- ------ --------");
- cprint(LINE_INFO, COL_TST, " Std");
- cprint(LINE_INFO, COL_PASS, " 0");
- cprint(LINE_INFO, COL_ERR, " 0");
- cprint(LINE_INFO+1, 0, " -----------------------------------------------------------------------------");
-
+ // dprint(10, 5, found_cpus, 2, 0);
- for(i=0; i < 5; i++) {
- cprint(i, COL_MID-2, "| ");
+ /* Find Memory Specs */
+ if(v->fail_safe & 1)
+ {
+ cprint(LINE_CPU, COL_SPEC, " **** FAIL SAFE **** FAIL SAFE **** ");
+ cprint(LINE_RAM, COL_SPEC, " No detection, same reliability ");
+ } else {
+ find_controller();
+ get_spd_spec();
+ if(num_cpus <= 16 && !(v->fail_safe & 4)) { coretemp(); }
+ }
+
+ if(v->check_temp > 0 && !(v->fail_safe & 4))
+ {
+ cprint(LINE_CPU, 26, "| CPU Temp");
+ cprint(LINE_CPU+1, 26, "| øC");
}
- footer();
- // Default Print Mode
- // v->printmode=PRINTMODE_SUMMARY;
+
+ beep(600);
+ beep(1000);
+
+ /* Record the start time */
+ asm __volatile__ ("rdtsc":"=a" (v->startl),"=d" (v->starth));
+ v->snapl = v->startl;
+ v->snaph = v->starth;
+ if (l1_cache == 0) { l1_cache = 64; }
+ if (l2_cache == 0) { l1_cache = 512; }
v->printmode=PRINTMODE_ADDRESSES;
v->numpatn=0;
-
-}
-
-#define FLAT 0
-
-static unsigned long mapped_window = 1;
-void paging_off(void)
-{
- if (!v->pae)
- return;
- mapped_window = 1;
- __asm__ __volatile__ (
- /* Disable paging */
- "movl %%cr0, %%eax\n\t"
- "andl $0x7FFFFFFF, %%eax\n\t"
- "movl %%eax, %%cr0\n\t"
- /* Disable pae and pse */
- "movl %%cr4, %%eax\n\t"
- "and $0xCF, %%al\n\t"
- "movl %%eax, %%cr4\n\t"
- :
- :
- : "ax"
- );
}
-static void paging_on(void *pdp)
+/* Get cache sizes for most AMD and Intel CPUs, exceptions for old CPUs are
+ * handled in CPU detection */
+void get_cache_size()
{
- if (!v->pae)
- return;
- __asm__ __volatile__(
- /* Load the page table address */
- "movl %0, %%cr3\n\t"
- /* Enable pae */
- "movl %%cr4, %%eax\n\t"
- "orl $0x00000020, %%eax\n\t"
- "movl %%eax, %%cr4\n\t"
- /* Enable paging */
- "movl %%cr0, %%eax\n\t"
- "orl $0x80000000, %%eax\n\t"
- "movl %%eax, %%cr0\n\t"
- :
- : "r" (pdp)
- : "ax"
- );
-}
-
-int map_page(unsigned long page)
-{
- unsigned long i;
- struct pde {
- unsigned long addr_lo;
- unsigned long addr_hi;
- };
- extern unsigned char pdp[];
- extern struct pde pd2[];
- unsigned long window = page >> 19;
- if (FLAT || (window == mapped_window)) {
- return 0;
- }
- if (window == 0) {
- return 0;
- }
- if (!v->pae || (window >= 32)) {
- /* Fail either we don't have pae support
- * or we want an address that is out of bounds
- * even for pae.
- */
- return -1;
- }
- /* Compute the page table entries... */
- for(i = 0; i < 1024; i++) {
- /*-----------------10/30/2004 12:37PM---------------
- * 0xE3 --
- * Bit 0 = Present bit. 1 = PDE is present
- * Bit 1 = Read/Write. 1 = memory is writable
- * Bit 2 = Supervisor/User. 0 = Supervisor only (CPL 0-2)
- * Bit 3 = Writethrough. 0 = writeback cache policy
- * Bit 4 = Cache Disable. 0 = page level cache enabled
- * Bit 5 = Accessed. 1 = memory has been accessed.
- * Bit 6 = Dirty. 1 = memory has been written to.
- * Bit 7 = Page Size. 1 = page size is 2 MBytes
- * --------------------------------------------------*/
- pd2[i].addr_lo = ((window & 1) << 31) + ((i & 0x3ff) << 21) + 0xE3;
- pd2[i].addr_hi = (window >> 1);
- }
- paging_off();
- if (window > 1) {
- paging_on(pdp);
- }
- mapped_window = window;
- return 0;
-}
+ int i, j, n, size;
+ unsigned int v[4];
+ unsigned char *dp = (unsigned char *)v;
+ struct cpuid4_eax *eax = (struct cpuid4_eax *)&v[0];
+ struct cpuid4_ebx *ebx = (struct cpuid4_ebx *)&v[1];
+ struct cpuid4_ecx *ecx = (struct cpuid4_ecx *)&v[2];
+
+ switch(cpu_id.vend_id.char_array[0]) {
+ /* AMD Processors */
+ case 'A':
+ //l1_cache = cpu_id.cache_info.amd.l1_i_sz;
+ l1_cache = cpu_id.cache_info.amd.l1_d_sz;
+ l2_cache = cpu_id.cache_info.amd.l2_sz;
+ l3_cache = cpu_id.cache_info.amd.l3_sz;
+ l3_cache *= 512;
+ break;
+ case 'G':
+ /* Intel Processors */
+ l1_cache = 0;
+ l2_cache = 0;
+ l3_cache = 0;
+
+ /* Use CPUID(4) if it is available */
+ if (cpu_id.max_cpuid > 3) {
+
+ /* figure out how many cache leaves */
+ n = -1;
+ do
+ {
+ ++n;
+ /* Do cpuid(4) loop to find out num_cache_leaves */
+ cpuid_count(4, n, &v[0], &v[1], &v[2], &v[3]);
+ } while ((eax->ctype) != 0);
+
+ /* loop through all of the leaves */
+ for (i=0; i<n; i++)
+ {
+ cpuid_count(4, i, &v[0], &v[1], &v[2], &v[3]);
+
+ /* Check for a valid cache type */
+ if (eax->ctype == 1 || eax->ctype == 3)
+ {
+
+ /* Compute the cache size */
+ size = (ecx->number_of_sets + 1) *
+ (ebx->coherency_line_size + 1) *
+ (ebx->physical_line_partition + 1) *
+ (ebx->ways_of_associativity + 1);
+ size /= 1024;
+
+ switch (eax->level)
+ {
+ case 1:
+ l1_cache += size;
+ break;
+ case 2:
+ l2_cache += size;
+ break;
+ case 3:
+ l3_cache += size;
+ break;
+ }
+ }
+ }
+ return;
+ }
-void *mapping(unsigned long page_addr)
-{
- void *result;
- if (FLAT || (page_addr < 0x80000)) {
- /* If the address is less that 1GB directly use the address */
- result = (void *)(page_addr << 12);
- }
- else {
- unsigned long alias;
- alias = page_addr & 0x7FFFF;
- alias += 0x80000;
- result = (void *)(alias << 12);
+ /* No CPUID(4) so we use the older CPUID(2) method */
+ /* Get number of times to iterate */
+ cpuid(2, &v[0], &v[1], &v[2], &v[3]);
+ n = v[0] & 0xff;
+ for (i=0 ; i<n ; i++) {
+ cpuid(2, &v[0], &v[1], &v[2], &v[3]);
+
+ /* If bit 31 is set, this is an unknown format */
+ for (j=0 ; j<3 ; j++) {
+ if (v[j] & (1 << 31)) {
+ v[j] = 0;
+ }
+ }
+
+ /* Byte 0 is level count, not a descriptor */
+ for (j = 1 ; j < 16 ; j++) {
+ switch(dp[j]) {
+ case 0x6:
+ case 0xa:
+ case 0x66:
+ l1_cache += 8;
+ break;
+ case 0x8:
+ case 0xc:
+ case 0xd:
+ case 0x60:
+ case 0x67:
+ l1_cache += 16;
+ break;
+ case 0xe:
+ l1_cache += 24;
+ break;
+ case 0x9:
+ case 0x2c:
+ case 0x30:
+ case 0x68:
+ l1_cache += 32;
+ break;
+ case 0x39:
+ case 0x3b:
+ case 0x41:
+ case 0x79:
+ l2_cache += 128;
+ break;
+ case 0x3a:
+ l2_cache += 192;
+ break;
+ case 0x21:
+ case 0x3c:
+ case 0x3f:
+ case 0x42:
+ case 0x7a:
+ case 0x82:
+ l2_cache += 256;
+ break;
+ case 0x3d:
+ l2_cache += 384;
+ break;
+ case 0x3e:
+ case 0x43:
+ case 0x7b:
+ case 0x7f:
+ case 0x80:
+ case 0x83:
+ case 0x86:
+ l2_cache += 512;
+ break;
+ case 0x44:
+ case 0x78:
+ case 0x7c:
+ case 0x84:
+ case 0x87:
+ l2_cache += 1024;
+ break;
+ case 0x45:
+ case 0x7d:
+ case 0x85:
+ l2_cache += 2048;
+ break;
+ case 0x48:
+ l2_cache += 3072;
+ break;
+ case 0x4e:
+ l2_cache += 6144;
+ break;
+ case 0x23:
+ case 0xd0:
+ l3_cache += 512;
+ break;
+ case 0xd1:
+ case 0xd6:
+ l3_cache += 1024;
+ break;
+ case 0x25:
+ case 0xd2:
+ case 0xd7:
+ case 0xdc:
+ case 0xe2:
+ l3_cache += 2048;
+ break;
+ case 0x29:
+ case 0x46:
+ case 0x49:
+ case 0xd8:
+ case 0xdd:
+ case 0xe3:
+ l3_cache += 4096;
+ break;
+ case 0x4a:
+ l3_cache += 6144;
+ break;
+ case 0x47:
+ case 0x4b:
+ case 0xde:
+ case 0xe4:
+ l3_cache += 8192;
+ break;
+ case 0x4c:
+ case 0xea:
+ l3_cache += 12288;
+ break;
+ case 0x4d:
+ l3_cache += 16384;
+ break;
+ case 0xeb:
+ l3_cache += 18432;
+ break;
+ case 0xec:
+ l3_cache += 24576;
+ break;
+ } /* end switch */
+ } /* end for 1-16 */
+ } /* end for 0 - n */
}
- return result;
}
-void *emapping(unsigned long page_addr)
+/*
+ * Find IMC type and set global variables accordingly
+ */
+void detect_imc(void)
{
- void *result;
- result = mapping(page_addr -1);
- /* The result needs to be 256 byte alinged... */
- result = ((unsigned char *)result) + 0xf00;
- return result;
+ // Check AMD IMC
+ if(cpu_id.vend_id.char_array[0] == 'A' && cpu_id.vers.bits.family == 0xF)
+ {
+ switch(cpu_id.vers.bits.extendedFamily)
+ {
+ case 0x0:
+ imc_type = 0x0100; // Old K8
+ break;
+ case 0x1:
+ case 0x2:
+ imc_type = 0x0101; // K10 (Family 10h & 11h)
+ break;
+ case 0x3:
+ imc_type = 0x0102; // A-Series APU (Family 12h)
+ break;
+ case 0x5:
+ imc_type = 0x0103; // C- / E- / Z- Series APU (Family 14h)
+ break;
+ case 0x6:
+ imc_type = 0x0104; // FX Series (Family 15h)
+ break;
+ case 0x7:
+ imc_type = 0x0105; // Kabini & related (Family 16h)
+ break;
+ }
+ return;
+ }
+
+ // Check Intel IMC
+ if(cpu_id.vend_id.char_array[0] == 'G' && cpu_id.vers.bits.family == 6 && cpu_id.vers.bits.extendedModel)
+ {
+ switch(cpu_id.vers.bits.model)
+ {
+ case 0x5:
+ if(cpu_id.vers.bits.extendedModel == 2) { imc_type = 0x0003; } // Core i3/i5 1st Gen 45 nm (NHM)
+ if(cpu_id.vers.bits.extendedModel == 3) { v->fail_safe |= 4; } // Atom Clover Trail
+ if(cpu_id.vers.bits.extendedModel == 4) { imc_type = 0x0007; } // HSW-ULT
+ break;
+ case 0x6:
+ if(cpu_id.vers.bits.extendedModel == 3) {
+ imc_type = 0x0009; // Atom Cedar Trail
+ v->fail_safe |= 4; // Disable Core temp
+ }
+ break;
+ case 0xA:
+ switch(cpu_id.vers.bits.extendedModel)
+ {
+ case 0x1:
+ imc_type = 0x0001; // Core i7 1st Gen 45 nm (NHME)
+ break;
+ case 0x2:
+ imc_type = 0x0004; // Core 2nd Gen (SNB)
+ break;
+ case 0x3:
+ imc_type = 0x0006; // Core 3nd Gen (IVB)
+ break;
+ }
+ break;
+ case 0xC:
+ switch(cpu_id.vers.bits.extendedModel)
+ {
+ case 0x1:
+ if(cpu_id.vers.bits.stepping > 9) { imc_type = 0x0008; } // Atom PineView
+ v->fail_safe |= 4; // Disable Core temp
+ break;
+ case 0x2:
+ imc_type = 0x0002; // Core i7 1st Gen 32 nm (WMR)
+ break;
+ case 0x3:
+ imc_type = 0x0007; // Core 4nd Gen (HSW)
+ break;
+ }
+ break;
+ case 0xD:
+ imc_type = 0x0005; // SNB-E
+ break;
+ case 0xE:
+ imc_type = 0x0001; // Core i7 1st Gen 45 nm (NHM)
+ break;
+ }
+
+ if(imc_type) { tsc_invariable = 1; }
+ return;
+ }
}
-unsigned long page_of(void *addr)
+void smp_default_mode(void)
{
- unsigned long page;
- page = ((unsigned long)addr) >> 12;
- if (!FLAT && (page >= 0x80000)) {
- page &= 0x7FFFF;
- page += mapped_window << 19;
- }
-#if 0
- cprint(LINE_SCROLL -2, 0, "page_of( )-> ");
- hprint(LINE_SCROLL -2, 8, ((unsigned long)addr));
- hprint(LINE_SCROLL -2, 20, page);
-#endif
- return page;
+ int i, result;
+ char *cpupsn = cpu_id.brand_id.char_array;
+ char *disabledcpu[] = { "Opteron", "Xeon", "Genuine Intel" };
+
+ for(i = 0; i < 3; i++)
+ {
+ result = strstr(cpupsn , disabledcpu[i]);
+ if(result != -1) { v->fail_safe |= 0b10; }
+ }
+
+ // For 5.01 release, SMP disabled by defualt by config.h toggle
+ if(CONSERVATIVE_SMP) { v->fail_safe |= 0b10; }
+
}
-
/*
- * Find CPU type and cache sizes
+ * Find CPU type
*/
-
-
void cpu_type(void)
{
- int i, off=0;
- int l1_cache=0, l2_cache=0, l3_cache=0;
- ulong speed;
-
- v->rdtsc = 0;
- v->pae = 0;
-
-#ifdef CPUID_DEBUG
- dprint(9,0,cpu_id.type,3,1);
- dprint(10,0,cpu_id.model,3,1);
- dprint(11,0,cpu_id.cpuid,3,1);
-#endif
-
- /* If the CPUID instruction is not supported then this is */
- /* a 386, 486 or one of the early Cyrix CPU's */
- if (cpu_id.cpuid < 1) {
- switch (cpu_id.type) {
- case 2:
- /* This is a Cyrix CPU without CPUID */
- i = getCx86(0xfe);
- i &= 0xf0;
- i >>= 4;
- switch(i) {
- case 0:
- case 1:
- cprint(LINE_CPU, 0, "Cyrix Cx486");
- break;
- case 2:
- cprint(LINE_CPU, 0,"Cyrix 5x86");
- break;
- case 3:
- cprint(LINE_CPU, 0,"Cyrix 6x86");
- break;
- case 4:
- cprint(LINE_CPU, 0,"Cyrix MediaGX");
- break;
- case 5:
- cprint(LINE_CPU, 0,"Cyrix 6x86MX");
- break;
- case 6:
- cprint(LINE_CPU, 0,"Cyrix MII");
- break;
- default:
- cprint(LINE_CPU, 0,"Cyrix ???");
- break;
- }
- break;
- case 3:
- cprint(LINE_CPU, 0, "386");
- break;
-
- case 4:
- cprint(LINE_CPU, 0, "486");
- l1_cache = 8;
- break;
- }
+ /* If we can get a brand string use it, and we are done */
+ if (cpu_id.max_xcpuid >= 0x80000004) {
+ cprint(0, COL_MID, cpu_id.brand_id.char_array);
+ //If we have a brand string, maybe we have an IMC. Check that.
+ detect_imc();
+ smp_default_mode();
return;
}
- /* We have cpuid so we can see if we have pae support */
- if (cpu_id.capability & (1 << X86_FEATURE_PAE)) {
- v->pae = 1;
- }
- switch(cpu_id.vend_id[0]) {
+ /* The brand string is not available so we need to figure out
+ * CPU what we have */
+ switch(cpu_id.vend_id.char_array[0]) {
/* AMD Processors */
case 'A':
- switch(cpu_id.type) {
+ switch(cpu_id.vers.bits.family) {
case 4:
- switch(cpu_id.model) {
+ switch(cpu_id.vers.bits.model) {
case 3:
- cprint(LINE_CPU, 0, "AMD 486DX2");
+ cprint(0, COL_MID, "AMD 486DX2");
break;
case 7:
- cprint(LINE_CPU, 0, "AMD 486DX2-WB");
+ cprint(0, COL_MID, "AMD 486DX2-WB");
break;
case 8:
- cprint(LINE_CPU, 0, "AMD 486DX4");
+ cprint(0, COL_MID, "AMD 486DX4");
break;
case 9:
- cprint(LINE_CPU, 0, "AMD 486DX4-WB");
+ cprint(0, COL_MID, "AMD 486DX4-WB");
break;
case 14:
- cprint(LINE_CPU, 0, "AMD 5x86-WT");
+ cprint(0, COL_MID, "AMD 5x86-WT");
+ break;
+ case 15:
+ cprint(0, COL_MID, "AMD 5x86-WB");
break;
}
/* Since we can't get CPU speed or cache info return */
return;
case 5:
- switch(cpu_id.model) {
+ switch(cpu_id.vers.bits.model) {
case 0:
case 1:
case 2:
case 3:
- cprint(LINE_CPU, 0, "AMD K5");
+ cprint(0, COL_MID, "AMD K5");
l1_cache = 8;
- off = 6;
break;
case 6:
case 7:
- cprint(LINE_CPU, 0, "AMD K6");
- off = 6;
- l1_cache = cpu_id.cache_info[3];
- l1_cache += cpu_id.cache_info[7];
+ cprint(0, COL_MID, "AMD K6");
break;
case 8:
- cprint(LINE_CPU, 0, "AMD K6-2");
- off = 8;
- l1_cache = cpu_id.cache_info[3];
- l1_cache += cpu_id.cache_info[7];
+ cprint(0, COL_MID, "AMD K6-2");
break;
case 9:
- cprint(LINE_CPU, 0, "AMD K6-III");
- off = 10;
- l1_cache = cpu_id.cache_info[3];
- l1_cache += cpu_id.cache_info[7];
- l2_cache = (cpu_id.cache_info[11] << 8);
- l2_cache += cpu_id.cache_info[10];
+ cprint(0, COL_MID, "AMD K6-III");
break;
- case 10:
- cprint(LINE_CPU, 0, "AMD Geode LX");
- off = 12;
- l1_cache = cpu_id.cache_info[3];
- l1_cache += cpu_id.cache_info[7];
- l2_cache = (cpu_id.cache_info[11] << 8);
- l2_cache += cpu_id.cache_info[10];
- break;
- case 13:
- cprint(LINE_CPU, 0, "AMD K6-III+");
- off = 11;
- l1_cache = cpu_id.cache_info[3];
- l1_cache += cpu_id.cache_info[7];
- l2_cache = (cpu_id.cache_info[11] << 8);
- l2_cache += cpu_id.cache_info[10];
+ case 13:
+ cprint(0, COL_MID, "AMD K6-III+");
break;
}
break;
case 6:
- switch(cpu_id.model) {
+
+ switch(cpu_id.vers.bits.model) {
case 1:
- cprint(LINE_CPU, 0, "AMD Athlon (0.25)");
- off = 17;
- l2_cache = (cpu_id.cache_info[11] << 8);
- l2_cache += cpu_id.cache_info[10];
+ cprint(0, COL_MID, "AMD Athlon (0.25)");
break;
case 2:
case 4:
- cprint(LINE_CPU, 0, "AMD Athlon (0.18)");
- off = 17;
- l2_cache = (cpu_id.cache_info[11] << 8);
- l2_cache += cpu_id.cache_info[10];
+ cprint(0, COL_MID, "AMD Athlon (0.18)");
break;
case 6:
- l2_cache = (cpu_id.cache_info[11] << 8);
- l2_cache += cpu_id.cache_info[10];
if (l2_cache == 64) {
- cprint(LINE_CPU, 0, "AMD Duron (0.18)");
+ cprint(0, COL_MID, "AMD Duron (0.18)");
} else {
- cprint(LINE_CPU, 0, "Athlon XP (0.18)");
+ cprint(0, COL_MID, "Athlon XP (0.18)");
}
- off = 16;
break;
case 8:
case 10:
- l2_cache = (cpu_id.cache_info[11] << 8);
- l2_cache += cpu_id.cache_info[10];
if (l2_cache == 64) {
- cprint(LINE_CPU, 0, "AMD Duron (0.13)");
+ cprint(0, COL_MID, "AMD Duron (0.13)");
} else {
- cprint(LINE_CPU, 0, "Athlon XP (0.13)");
+ cprint(0, COL_MID, "Athlon XP (0.13)");
}
- off = 16;
break;
case 3:
case 7:
- cprint(LINE_CPU, 0, "AMD Duron");
- off = 9;
+ cprint(0, COL_MID, "AMD Duron");
/* Duron stepping 0 CPUID for L2 is broken */
/* (AMD errata T13)*/
- if (cpu_id.step == 0) { /* stepping 0 */
- /* Hard code the right size*/
+ if (cpu_id.vers.bits.stepping == 0) { /* stepping 0 */
+ /* Hard code the right L2 size */
l2_cache = 64;
} else {
- l2_cache = (cpu_id.cache_info[11] << 8);
- l2_cache += cpu_id.cache_info[10];
}
break;
}
- l1_cache = cpu_id.cache_info[3];
- l1_cache += cpu_id.cache_info[7];
break;
- case 15:
- l1_cache = cpu_id.cache_info[3];
- l2_cache = (cpu_id.cache_info[11] << 8);
- l2_cache += cpu_id.cache_info[10];
- imc_type = 0x0100;
- if(((cpu_id.ext >> 16) & 0xFF) < 0x10) {
- // Here if CPUID.EXT < 0x10h (old K8/K10)
- switch(cpu_id.model) {
- default:
- cprint(LINE_CPU, 0, "AMD K8");
- off = 6;
- break;
- case 1:
- case 5:
- if (((cpu_id.ext >> 16) & 0xF) != 0) {
- cprint(LINE_CPU, 0, "AMD Opteron (0.09)");
- } else {
- cprint(LINE_CPU, 0, "AMD Opteron (0.13)");
- }
- off = 18;
- break;
- case 3:
- case 11:
- cprint(LINE_CPU, 0, "Athlon 64 X2");
- off = 12;
- break;
- case 8:
- cprint(LINE_CPU, 0, "Turion 64 X2");
- off = 12;
- break;
- case 4:
- case 7:
- case 12:
- case 14:
- case 15:
- if (((cpu_id.ext >> 16) & 0xF) != 0) {
- if (l2_cache > 256) {
- cprint(LINE_CPU, 0, "Athlon 64 (0.09)");
- } else {
- cprint(LINE_CPU, 0, "Sempron (0.09)");
- }
- } else {
- if (l2_cache > 256) {
- cprint(LINE_CPU, 0, "Athlon 64 (0.13)");
- } else {
- cprint(LINE_CPU, 0, "Sempron (0.13)");
- }
- }
- off = 16;
- break;
- }
- break;
- } else {
- // Here if CPUID.EXT >= 0x10h (new K10)
- l3_cache = (cpu_id.cache_info[15] << 8);
- l3_cache += (cpu_id.cache_info[14] >> 2);
- l3_cache *= 512;
- switch(cpu_id.model) {
- case 1:
- imc_type = 0x0102;
- cprint(LINE_CPU, 0, "AMD Fusion @");
- off = 12;
- break;
- default:
- case 2:
- imc_type = 0x0101;
- cprint(LINE_CPU, 0, "AMD K10 (65nm) @");
- off = 16;
- break;
- case 4:
- imc_type = 0x0101;
- cprint(LINE_CPU, 0, "AMD K10 (45nm) @");
- off = 16;
- break;
- case 9:
- imc_type = 0x0101;
- cprint(LINE_CPU, 0, "AMD Magny-Cours");
- off = 15;
- break;
- }
- break;
- }
+
+ /* All AMD family values >= 10 have the Brand ID
+ * feature so we don't need to find the CPU type */
}
break;
/* Intel or Transmeta Processors */
case 'G':
- if ( cpu_id.vend_id[7] == 'T' ) { /* GenuineTMx86 */
- if (cpu_id.type == 5) {
- cprint(LINE_CPU, 0, "TM 5x00");
- off = 7;
- } else if (cpu_id.type == 15) {
- cprint(LINE_CPU, 0, "TM 8x00");
- off = 7;
+ if ( cpu_id.vend_id.char_array[7] == 'T' ) { /* GenuineTMx86 */
+ if (cpu_id.vers.bits.family == 5) {
+ cprint(0, COL_MID, "TM 5x00");
+ } else if (cpu_id.vers.bits.family == 15) {
+ cprint(0, COL_MID, "TM 8x00");
}
- l1_cache = cpu_id.cache_info[3] + cpu_id.cache_info[7];
- l2_cache = (cpu_id.cache_info[11]*256) + cpu_id.cache_info[10];
+ l1_cache = cpu_id.cache_info.ch[3] + cpu_id.cache_info.ch[7];
+ l2_cache = (cpu_id.cache_info.ch[11]*256) + cpu_id.cache_info.ch[10];
} else { /* GenuineIntel */
- if (cpu_id.type == 4) {
- switch(cpu_id.model) {
- case 0:
- case 1:
- cprint(LINE_CPU, 0, "Intel 486DX");
- off = 11;
- break;
- case 2:
- cprint(LINE_CPU, 0, "Intel 486SX");
- off = 11;
- break;
- case 3:
- cprint(LINE_CPU, 0, "Intel 486DX2");
- off = 12;
- break;
- case 4:
- cprint(LINE_CPU, 0, "Intel 486SL");
- off = 11;
- break;
- case 5:
- cprint(LINE_CPU, 0, "Intel 486SX2");
- off = 12;
- break;
- case 7:
- cprint(LINE_CPU, 0, "Intel 486DX2-WB");
- off = 15;
- break;
- case 8:
- cprint(LINE_CPU, 0, "Intel 486DX4");
- off = 12;
- break;
- case 9:
- cprint(LINE_CPU, 0, "Intel 486DX4-WB");
- off = 15;
- break;
- }
- /* Since we can't get CPU speed or cache info return */
- return;
+ if (cpu_id.vers.bits.family == 4) {
+ switch(cpu_id.vers.bits.model) {
+ case 0:
+ case 1:
+ cprint(0, COL_MID, "Intel 486DX");
+ break;
+ case 2:
+ cprint(0, COL_MID, "Intel 486SX");
+ break;
+ case 3:
+ cprint(0, COL_MID, "Intel 486DX2");
+ break;
+ case 4:
+ cprint(0, COL_MID, "Intel 486SL");
+ break;
+ case 5:
+ cprint(0, COL_MID, "Intel 486SX2");
+ break;
+ case 7:
+ cprint(0, COL_MID, "Intel 486DX2-WB");
+ break;
+ case 8:
+ cprint(0, COL_MID, "Intel 486DX4");
+ break;
+ case 9:
+ cprint(0, COL_MID, "Intel 486DX4-WB");
+ break;
}
+ /* Since we can't get CPU speed or cache info return */
+ return;
+ }
- /* Get the cache info */
- for (i=0; i<16; i++) {
-#ifdef CPUID_DEBUG
- dprint(12,i*3,cpu_id.cache_info[i],2,1);
-#endif
- switch(cpu_id.cache_info[i]) {
- case 0x6:
- case 0xa:
- case 0x66:
+
+ switch(cpu_id.vers.bits.family) {
+ case 5:
+ switch(cpu_id.vers.bits.model) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 7:
+ cprint(0, COL_MID, "Pentium");
+ if (l1_cache == 0) {
l1_cache = 8;
- break;
- case 0x8:
- case 0xc:
- case 0x67:
- case 0x60:
+ }
+ break;
+ case 4:
+ case 8:
+ cprint(0, COL_MID, "Pentium-MMX");
+ if (l1_cache == 0) {
l1_cache = 16;
- break;
- case 0x9:
- case 0xd:
- case 0x68:
- case 0x2c:
- case 0x30:
- l1_cache = 32;
- break;
- case 0x40:
- l2_cache = 0;
- break;
- case 0x41:
- case 0x79:
- case 0x39:
- case 0x3b:
- l2_cache = 128;
- break;
- case 0x3a:
- l2_cache = 192;
- break;
- case 0x21:
- case 0x42:
- case 0x7a:
- case 0x82:
- case 0x3c:
- case 0x3f:
- l2_cache = 256;
- break;
- case 0x3d:
- l2_cache = 384;
- break;
- case 0x43:
- case 0x7b:
- case 0x83:
- case 0x86:
- case 0x3e:
- case 0x7f:
- case 0x80:
- l2_cache = 512;
- break;
- case 0x44:
- case 0x7c:
- case 0x84:
- case 0x87:
- case 0x78:
- l2_cache = 1024;
- break;
- case 0x45:
- case 0x7d:
- case 0x85:
- l2_cache = 2048;
- break;
- case 0x48:
- l2_cache = 3072;
- break;
- case 0x49:
- l2_cache = 4096;
- break;
- case 0x4e:
- l2_cache = 6144;
- break;
- case 0x22:
- case 0xd0:
- l3_cache = 512;
- case 0x23:
- case 0xd1:
- case 0xd6:
- l3_cache = 1024;
- break;
- case 0xdc:
- l3_cache = 1536;
- break;
- case 0x25:
- case 0xd2:
- case 0xd7:
- case 0xe2:
- l3_cache = 2048;
- break;
- case 0xdd:
- l3_cache = 3072;
- break;
- case 0x29:
- case 0x46:
- case 0xd8:
- case 0xe3:
- l3_cache = 4096;
- break;
- case 0x4a:
- case 0xde:
- l3_cache = 6144;
- break;
- case 0x47:
- case 0x4b:
- case 0xe4:
- l3_cache = 8192;
- break;
- case 0x4c:
- case 0xea:
- l3_cache = 12288;
- break;
- case 0x4d:
- l3_cache = 16374;
- break;
- case 0xeb:
- l3_cache = 18432;
- break;
- case 0xec:
- l3_cache = 24576;
- break;
}
+ break;
}
-
- // If no cache found, check if deterministic cache info are available
- if(l1_cache == 0 && ((cpu_id.dcache0_eax >> 5) & 7) == 1)
- {
-
- long dcache[] = { cpu_id.dcache0_eax, cpu_id.dcache0_ebx, cpu_id.dcache0_ecx, cpu_id.dcache0_edx,
- cpu_id.dcache1_eax, cpu_id.dcache1_ebx, cpu_id.dcache1_ecx, cpu_id.dcache1_edx,
- cpu_id.dcache2_eax, cpu_id.dcache2_ebx, cpu_id.dcache2_ecx, cpu_id.dcache2_edx,
- cpu_id.dcache3_eax, cpu_id.dcache3_ebx, cpu_id.dcache3_ecx, cpu_id.dcache3_edx
- };
-
- for(i=0; i<4; i++)
- {
- switch((dcache[i*4] >> 5) & 7)
- {
- case 1:
- // We don't want L1 I-Cache, only L1 D-Cache
- if((dcache[i*4] & 3) != 2)
- {
- l1_cache = (((dcache[i*4+1] >> 22) & 0x3FF) + 1) * (((dcache[i*4+1] >> 12) & 0x3FF) + 1);
- l1_cache *= ((dcache[i*4+1] & 0xFFF) + 1) * (dcache[i*4+2] + 1) / 1024;
- }
- break;
- case 2:
- l2_cache = (((dcache[i*4+1] >> 22) & 0x3FF) + 1) * (((dcache[i*4+1] >> 12) & 0x3FF) + 1);
- l2_cache *= ((dcache[i*4+1] & 0xFFF) + 1) * (dcache[i*4+2] + 1) / 1024;
- break;
- case 3:
- l3_cache = (((dcache[i*4+1] >> 22) & 0x3FF) + 1) * (((dcache[i*4+1] >> 12) & 0x3FF) + 1);
- l3_cache *= ((dcache[i*4+1] & 0xFFF) + 1) * (dcache[i*4+2] + 1) / 1024;
- break;
- }
- }
- }
-
-
- switch(cpu_id.type) {
+ break;
+ case 6:
+ switch(cpu_id.vers.bits.model) {
+ case 0:
+ case 1:
+ cprint(0, COL_MID, "Pentium Pro");
+ break;
+ case 3:
+ case 4:
+ cprint(0, COL_MID, "Pentium II");
+ break;
case 5:
- switch(cpu_id.model) {
- case 0:
- case 1:
- case 2:
- case 3:
- case 7:
- cprint(LINE_CPU, 0, "Pentium");
- if (l1_cache == 0) {
- l1_cache = 8;
- }
- off = 7;
- break;
- case 4:
- case 8:
- cprint(LINE_CPU, 0, "Pentium-MMX");
- if (l1_cache == 0) {
- l1_cache = 16;
- }
- off = 11;
- break;
+ if (l2_cache == 0) {
+ cprint(0, COL_MID, "Celeron");
+ } else {
+ cprint(0, COL_MID, "Pentium II");
}
break;
case 6:
- switch(cpu_id.model) {
- case 0:
- case 1:
- cprint(LINE_CPU, 0, "Pentium Pro");
- off = 11;
- break;
- case 3:
- cprint(LINE_CPU, 0, "Pentium II");
- off = 10;
- break;
- case 5:
- if ((cpu_id.ext >> 16) & 0xF) {
- if(((cpu_id.ext >> 16) & 0xF) > 1) {
- cprint(LINE_CPU, 0, "Intel Core i3/i5");
- tsc_invariable = 1;
- imc_type = 0x0003;
- off = 16;
- } else {
- cprint(LINE_CPU, 0, "Intel EP80579");
- if (l2_cache == 0) { l2_cache = 256; }
- off = 13;
- }
+ if (l2_cache == 128) {
+ cprint(0, COL_MID, "Celeron");
+ } else {
+ cprint(0, COL_MID, "Pentium II");
+ }
+ }
+ break;
+ case 7:
+ case 8:
+ case 11:
+ if (l2_cache == 128) {
+ cprint(0, COL_MID, "Celeron");
} else {
- if (l2_cache == 0) {
- cprint(LINE_CPU, 0, "Celeron");
- off = 7;
- } else {
- cprint(LINE_CPU, 0, "Pentium II");
- off = 10;
- }
- }
- break;
- case 6:
- if (l2_cache == 128) {
- cprint(LINE_CPU, 0, "Celeron");
- off = 7;
- } else {
- cprint(LINE_CPU, 0, "Pentium II");
- off = 10;
- }
- break;
- case 7:
- case 8:
- case 11:
- if (((cpu_id.ext >> 16) & 0xF) != 0) {
- tsc_invariable = 1;
- if (l2_cache < 1024) {
- cprint(LINE_CPU, 0, "Celeron");
- off = 7;
- } else {
- cprint(LINE_CPU, 0, "Intel Core 2");
- off = 12;
- }
- } else {
- if (l2_cache == 128) {
- cprint(LINE_CPU, 0, "Celeron");
- off = 7;
- } else {
- cprint(LINE_CPU, 0, "Pentium III");
- off = 11;
- }
- }
- break;
- case 9:
- if (l2_cache == 512) {
- cprint(LINE_CPU, 0, "Celeron M (0.13)");
- } else {
- cprint(LINE_CPU, 0, "Pentium M (0.13)");
- }
- off = 16;
- break;
- case 10:
- if (((cpu_id.ext >> 16) & 0xF) != 0) {
- tsc_invariable = 1;
- if(((cpu_id.ext >> 16) & 0xF) > 1) {
- cprint(LINE_CPU, 0, "Intel Core Gen2");
- imc_type = 0x0004;
- off = 15;
- } else {
- imc_type = 0x0001;
- cprint(LINE_CPU, 0, "Intel Core i7");
- off = 13;
- }
- } else {
- cprint(LINE_CPU, 0, "Pentium III Xeon");
- off = 16;
- }
- break;
- case 12:
- if (((cpu_id.ext >> 16) & 0xF) > 1) {
- cprint(LINE_CPU, 0, "Core i7 (32nm)");
- tsc_invariable = 1;
- imc_type = 0x0002;
- off = 14;
- } else {
- l1_cache = 24;
- cprint(LINE_CPU, 0, "Atom (0.045)");
- off = 12;
- }
- break;
- case 13:
- if (l2_cache == 1024) {
- cprint(LINE_CPU, 0, "Celeron M (0.09)");
- } else {
- cprint(LINE_CPU, 0, "Pentium M (0.09)");
- }
- off = 16;
- break;
- case 14:
- if (((cpu_id.ext >> 16) & 0xF) != 0) {
- tsc_invariable = 1;
- imc_type = 0x0001;
- cprint(LINE_CPU, 0, "Intel Core i5/i7");
- off = 16;
- } else {
- cprint(LINE_CPU, 0, "Intel Core");
- off = 10;
- }
- break;
- case 15:
- if (l2_cache == 1024) {
- cprint(LINE_CPU, 0, "Pentium E");
- off = 9;
- } else {
- cprint(LINE_CPU, 0, "Intel Core 2");
- off = 12;
- }
- tsc_invariable = 1;
- break;
+ cprint(0, COL_MID, "Pentium III");
+ }
+ break;
+ case 9:
+ if (l2_cache == 512) {
+ cprint(0, COL_MID, "Celeron M (0.13)");
+ } else {
+ cprint(0, COL_MID, "Pentium M (0.13)");
+ }
+ break;
+ case 10:
+ cprint(0, COL_MID, "Pentium III Xeon");
+ break;
+ case 12:
+ l1_cache = 24;
+ cprint(0, COL_MID, "Atom (0.045)");
+ break;
+ case 13:
+ if (l2_cache == 1024) {
+ cprint(0, COL_MID, "Celeron M (0.09)");
+ } else {
+ cprint(0, COL_MID, "Pentium M (0.09)");
}
break;
+ case 14:
+ cprint(0, COL_MID, "Intel Core");
+ break;
case 15:
- switch(cpu_id.model) {
- case 0:
- case 1:
- if (l2_cache == 128) {
- cprint(LINE_CPU, 0, "Celeron (0.18)");
- off = 14;
- } else if (cpu_id.pwrcap == 0x0B) {
- cprint(LINE_CPU, 0, "Xeon DP (0.18)");
- off = 14;
- } else if (cpu_id.pwrcap == 0x0C) {
- cprint(LINE_CPU, 0, "Xeon MP (0.18)");
- off = 14;
- } else {
- cprint(LINE_CPU, 0, "Pentium 4 (0.18)");
- off = 16;
- }
- break;
- case 2:
- if (l2_cache == 128) {
- cprint(LINE_CPU, 0, "Celeron (0.13)");
- off = 14;
- } else if (cpu_id.pwrcap == 0x0B) {
- cprint(LINE_CPU, 0, "Xeon DP (0.13)");
- off = 14;
- } else if (cpu_id.pwrcap == 0x0C) {
- cprint(LINE_CPU, 0, "Xeon MP (0.13)");
- off = 14;
- } else {
- cprint(LINE_CPU, 0, "Pentium 4 (0.13)");
- off = 16;
- }
- break;
- case 3:
- case 4:
- if (l2_cache == 256) {
- cprint(LINE_CPU, 0, "Celeron (0.09)");
- off = 14;
- } else if (cpu_id.pwrcap == 0x0B) {
- cprint(LINE_CPU, 0, "Xeon DP (0.09)");
- off = 14;
- } else if (cpu_id.pwrcap == 0x0C) {
- cprint(LINE_CPU, 0, "Xeon MP (0.09)");
- off = 14;
- } else if ((cpu_id.step == 0x4 || cpu_id.step == 0x7) && cpu_id.model == 0x4) {
- cprint(LINE_CPU, 0, "Pentium D (0.09)");
- off = 16;
- } else {
- cprint(LINE_CPU, 0, "Pentium 4 (0.09)");
- off = 16;
- }
- break;
- case 6:
- cprint(LINE_CPU, 0, "Pentium D (65nm)");
- off = 16;
- break;
- default:
- cprint(LINE_CPU, 0, "Unknown Intel");
- off = 13;
- break;
+ if (l2_cache == 1024) {
+ cprint(0, COL_MID, "Pentium E");
+ } else {
+ cprint(0, COL_MID, "Intel Core 2");
}
break;
}
+ break;
+ case 15:
+ switch(cpu_id.vers.bits.model) {
+ case 0:
+ case 1:
+ case 2:
+ if (l2_cache == 128) {
+ cprint(0, COL_MID, "Celeron");
+ } else {
+ cprint(0, COL_MID, "Pentium 4");
+ }
+ break;
+ case 3:
+ case 4:
+ if (l2_cache == 256) {
+ cprint(0, COL_MID, "Celeron (0.09)");
+ } else {
+ cprint(0, COL_MID, "Pentium 4 (0.09)");
+ }
+ break;
+ case 6:
+ cprint(0, COL_MID, "Pentium D (65nm)");
+ break;
+ default:
+ cprint(0, COL_MID, "Unknown Intel");
+ break;
+ break;
+ }
+
}
break;
/* VIA/Cyrix/Centaur Processors with CPUID */
case 'C':
- if ( cpu_id.vend_id[1] == 'e' ) { /* CentaurHauls */
- l1_cache = cpu_id.cache_info[3] + cpu_id.cache_info[7];
- l2_cache = cpu_id.cache_info[11];
- switch(cpu_id.type){
+ if ( cpu_id.vend_id.char_array[1] == 'e' ) { /* CentaurHauls */
+ l1_cache = cpu_id.cache_info.ch[3] + cpu_id.cache_info.ch[7];
+ l2_cache = cpu_id.cache_info.ch[11];
+ switch(cpu_id.vers.bits.family){
case 5:
- cprint(LINE_CPU, 0, "Centaur 5x86");
- off = 12;
+ cprint(0, COL_MID, "Centaur 5x86");
break;
case 6: // VIA C3
- switch(cpu_id.model){
- default:
- if (cpu_id.step < 8) {
- cprint(LINE_CPU, 0, "VIA C3 Samuel2");
- off = 14;
- } else {
- cprint(LINE_CPU, 0, "VIA C3 Eden");
- off = 11;
- }
- break;
- case 10:
- cprint(LINE_CPU, 0, "VIA C7 (C5J)");
- l1_cache = 64;
- l2_cache = 128;
- off = 16;
- break;
- case 13:
- cprint(LINE_CPU, 0, "VIA C7 (C5R)");
- l1_cache = 64;
- l2_cache = 128;
- off = 12;
- break;
- case 15:
- cprint(LINE_CPU, 0, "VIA Isaiah (CN)");
- l1_cache = 64;
- l2_cache = 1024;
- off = 15;
- break;
+ switch(cpu_id.vers.bits.model){
+ default:
+ if (cpu_id.vers.bits.stepping < 8) {
+ cprint(0, COL_MID, "VIA C3 Samuel2");
+ } else {
+ cprint(0, COL_MID, "VIA C3 Eden");
+ }
+ break;
+ case 10:
+ cprint(0, COL_MID, "VIA C7 (C5J)");
+ l1_cache = 64;
+ l2_cache = 128;
+ break;
+ case 13:
+ cprint(0, COL_MID, "VIA C7 (C5R)");
+ l1_cache = 64;
+ l2_cache = 128;
+ break;
+ case 15:
+ cprint(0, COL_MID, "VIA Isaiah (CN)");
+ l1_cache = 64;
+ l2_cache = 128;
+ break;
}
}
} else { /* CyrixInstead */
- switch(cpu_id.type) {
+ switch(cpu_id.vers.bits.family) {
case 5:
- switch(cpu_id.model) {
+ switch(cpu_id.vers.bits.model) {
case 0:
- cprint(LINE_CPU, 0, "Cyrix 6x86MX/MII");
- off = 16;
+ cprint(0, COL_MID, "Cyrix 6x86MX/MII");
break;
case 4:
- cprint(LINE_CPU, 0, "Cyrix GXm");
- off = 9;
+ cprint(0, COL_MID, "Cyrix GXm");
break;
}
return;
case 6: // VIA C3
- switch(cpu_id.model) {
+ switch(cpu_id.vers.bits.model) {
case 6:
- cprint(LINE_CPU, 0, "Cyrix III");
- off = 9;
+ cprint(0, COL_MID, "Cyrix III");
break;
case 7:
- if (cpu_id.step < 8) {
- cprint(LINE_CPU, 0, "VIA C3 Samuel2");
- off = 14;
+ if (cpu_id.vers.bits.stepping < 8) {
+ cprint(0, COL_MID, "VIA C3 Samuel2");
} else {
- cprint(LINE_CPU, 0, "VIA C3 Ezra-T");
- off = 13;
+ cprint(0, COL_MID, "VIA C3 Ezra-T");
}
break;
case 8:
- cprint(LINE_CPU, 0, "VIA C3 Ezra-T");
- off = 13;
+ cprint(0, COL_MID, "VIA C3 Ezra-T");
break;
case 9:
- cprint(LINE_CPU, 0, "VIA C3 Nehemiah");
- off = 15;
+ cprint(0, COL_MID, "VIA C3 Nehemiah");
break;
}
// L1 = L2 = 64 KB from Cyrix III to Nehemiah
@@ -1180,34 +994,40 @@ void cpu_type(void)
}
}
break;
-
/* Unknown processor */
default:
- off = 3;
/* Make a guess at the family */
- switch(cpu_id.type) {
+ switch(cpu_id.vers.bits.family) {
case 5:
- cprint(LINE_CPU, 0, "586");
- return;
+ cprint(0, COL_MID, "586");
case 6:
- cprint(LINE_CPU, 0, "686");
- return;
+ cprint(0, COL_MID, "686");
+ default:
+ cprint(0, COL_MID, "Unidentified Processor");
}
}
+}
+
+#define STEST_ADDR 0x100000 /* Measure memory speed starting at 1MB */
+
+/* Measure and display CPU and cache sizes and speeds */
+void cpu_cache_speed()
+{
+ int i, off = 4;
+ ulong speed;
- /* We are here only if the CPU type supports the rdtsc instruction */
/* Print CPU speed */
if ((speed = cpuspeed()) > 0) {
- if (speed < 1000000-50) {
+ if (speed < 999499) {
speed += 50; /* for rounding */
- cprint(LINE_CPU, off, " . MHz");
- dprint(LINE_CPU, off+1, speed/1000, 3, 1);
- dprint(LINE_CPU, off+5, (speed/100)%10, 1, 0);
+ cprint(1, off, " . MHz");
+ dprint(1, off+1, speed/1000, 3, 1);
+ dprint(1, off+5, (speed/100)%10, 1, 0);
} else {
speed += 500; /* for rounding */
- cprint(LINE_CPU, off, " MHz");
- dprint(LINE_CPU, off, speed/1000, 5, 0);
+ cprint(1, off, " MHz");
+ dprint(1, off, speed/1000, 5, 0);
}
extclock = speed;
}
@@ -1216,11 +1036,11 @@ void cpu_type(void)
/* To measure L1 cache speed we use a block size that is 1/4th */
/* of the total L1 cache size since half of it is for instructions */
if (l1_cache) {
- cprint(LINE_CPU+1, 0, "L1 Cache: K ");
- dprint(LINE_CPU+1, 11, l1_cache, 3, 0);
- if ((speed=memspeed((ulong)mapping(0x100), (l1_cache / 4) * 1024, 200, MS_COPY))) {
- cprint(LINE_CPU+1, 16, " MB/s");
- dprint(LINE_CPU+1, 16, speed, 6, 0);
+ cprint(2, 0, "L1 Cache: K ");
+ dprint(2, 11, l1_cache, 3, 0);
+ if ((speed=memspeed(STEST_ADDR, (l1_cache/2)*1024, 200))) {
+ cprint(2, 16, " MB/s");
+ dprint(2, 16, speed, 6, 0);
}
}
@@ -1229,119 +1049,84 @@ void cpu_type(void)
/* the size of the L1 cache. We have to fudge if the L1 */
/* cache is bigger than the L2 */
if (l2_cache) {
- cprint(LINE_CPU+2, 0, "L2 Cache: K ");
- dprint(LINE_CPU+2, 10, l2_cache, 4, 0);
- dprint(LINE_CPU+2, 10, l2_cache, 4, 0);
+ cprint(3, 0, "L2 Cache: K ");
+ dprint(3, 10, l2_cache, 4, 0);
if (l2_cache < l1_cache) {
i = l1_cache / 4 + l2_cache / 4;
} else {
i = l1_cache;
}
- if ((speed=memspeed((ulong)mapping(0x100), i*1024, 200, MS_COPY))) {
- cprint(LINE_CPU+2, 16, " MB/s");
- dprint(LINE_CPU+2, 16, speed, 6, 0);
+ if ((speed=memspeed(STEST_ADDR, i*1024, 200))) {
+ cprint(3, 16, " MB/s");
+ dprint(3, 16, speed, 6, 0);
}
}
-
/* Print out L3 cache info */
/* We measure the L3 cache speed by using a block size that is */
- /* the size of the L2 cache. */
-
- if (l3_cache) {
- cprint(LINE_CPU+3, 0, "L3 Cache: K ");
- dprint(LINE_CPU+3, 10, l3_cache, 4, 0);
- dprint(LINE_CPU+3, 10, l3_cache, 4, 0);
-
- i = l2_cache*2;
+ /* 2X the size of the L2 cache. */
+
+ if (l3_cache)
+ {
+ cprint(4, 0, "L3 Cache: K ");
+ aprint(4, 10, l3_cache/4);
+ //dprint(4, 10, l3_cache, 4, 0);
+
+ i = l2_cache*2;
+
+ if ((speed=memspeed(STEST_ADDR, i*1024, 150))) {
+ cprint(4, 16, " MB/s");
+ dprint(4, 16, speed, 6, 0);
+ }
+ }
+}
- if ((speed=memspeed((ulong)mapping(0x100), i*1024, 150, MS_COPY))) {
- cprint(LINE_CPU+3, 16, " MB/s");
- dprint(LINE_CPU+3, 16, speed, 6, 0);
- }
- }
+/* Measure and display memory speed, multitasked using all CPUs */
+ulong spd[MAX_CPUS];
+void get_mem_speed(int me, int ncpus)
+{
+ int i;
+ ulong speed=0;
+ /* Determine memory speed. To find the memory speed we use
+ * A block size that is the sum of all the L1, L2 & L3 caches
+ * in all cpus * 6 */
+ i = (l3_cache + l2_cache + l1_cache) * 4;
- /* Determine memory speed. To find the memory speed we use */
- /* A block size that is 5x the sum of the L1, L2 & L3 caches */
- i = (l3_cache + l2_cache + l1_cache) * 5;
-
/* Make sure that we have enough memory to do the test */
+ /* If not use all we have */
if ((1 + (i * 2)) > (v->plim_upper << 2)) {
i = ((v->plim_upper <<2) - 1) / 2;
}
- if((speed = memspeed((ulong)mapping(0x100), i*1024, 50, MS_COPY))) {
- cprint(LINE_CPU+4, 16, " MB/s");
- dprint(LINE_CPU+4, 16, speed, 6, 0);
- }
-
- /* Record the starting time */
- asm __volatile__ ("rdtsc":"=a" (v->startl),"=d" (v->starth));
- v->snapl = v->startl;
- v->snaph = v->starth;
- v->rdtsc = 1;
- if (l1_cache == 0) { l1_cache = 66; }
- if (l2_cache == 0) { l1_cache = 666; }
-}
-
-/* Find cache-able memory size */
-static void cacheable(void)
-{
- ulong speed, pspeed;
- ulong paddr, mem_top, cached;
-
- mem_top = v->pmap[v->msegs - 1].end;
- cached = v->test_pages;
- pspeed = 0;
- for (paddr=0x200; paddr <= mem_top - 64; paddr+=0x400) {
- int i;
- int found;
- /* See if the paddr is at a testable location */
- found = 0;
- for(i = 0; i < v->msegs; i++) {
- if ((v->pmap[i].start >= paddr) &&
- (v->pmap[i].end <= (paddr + 32))) {
- found = 1;
- break;
- }
- }
- if (!found) {
- continue;
- }
- /* Map the range and perform the test */
- map_page(paddr);
- speed = memspeed((ulong)mapping(paddr), 32*4096, 1, MS_READ);
- if (pspeed) {
- if (speed < pspeed) {
- cached -= 32;
- }
- pspeed = (ulong)((float)speed * 0.7);
- }
- }
- aprint(LINE_INFO, COL_CACHE_TOP, cached);
- /* Ensure the default set of pages are mapped */
- map_page(0);
- map_page(0x80000);
+
+ speed = memspeed(STEST_ADDR, i * 1024, 100);
+ cprint(5, 16, " MB/s");
+ dprint(5, 16, speed, 6, 0);
+
}
-
/* #define TICKS 5 * 11832 (count = 6376)*/
/* #define TICKS (65536 - 12752) */
-/* #define TICKS (65536 - 8271) */
-#define TICKS 59659 /* Program counter to 50 ms = 59659 clks */
+#define TICKS 59659 /* 50 ms */
/* Returns CPU clock in khz */
+ulong stlow, sthigh;
static int cpuspeed(void)
{
int loops;
+ ulong end_low, end_high;
+
+ if (cpu_id.fid.bits.rdtsc == 0 ) {
+ return(-1);
+ }
/* Setup timer */
outb((inb(0x61) & ~0x02) | 0x01, 0x61);
- outb(0xb0, 0x43);
+ outb(0xb0, 0x43);
outb(TICKS & 0xff, 0x42);
outb(TICKS >> 8, 0x42);
- asm __volatile__ ("rdtsc":"=a" (st_low),"=d" (st_high));
+ asm __volatile__ ("rdtsc":"=a" (stlow),"=d" (sthigh));
loops = 0;
do {
@@ -1350,8 +1135,8 @@ static int cpuspeed(void)
asm __volatile__ (
"rdtsc\n\t" \
- "subl st_low,%%eax\n\t" \
- "sbbl st_high,%%edx\n\t" \
+ "subl stlow,%%eax\n\t" \
+ "sbbl sthigh,%%edx\n\t" \
:"=a" (end_low), "=d" (end_high)
);
@@ -1359,20 +1144,27 @@ static int cpuspeed(void)
if (loops < 4 || end_low < 50000) {
return(-1);
}
+ v->clks_msec = end_low/50;
- if(tsc_invariable){ end_low = correct_tsc(end_low); }
+ if (tsc_invariable) end_low = correct_tsc(end_low);
- v->clks_msec = end_low/50;
return(v->clks_msec);
}
-/* Measure cache/memory speed by copying a block of memory. */
+/* Measure cache speed by copying a block of memory. */
/* Returned value is kbytes/second */
-ulong memspeed(ulong src, ulong len, int iter, int type)
+ulong memspeed(ulong src, ulong len, int iter)
{
- ulong dst;
- ulong wlen;
int i;
+ ulong dst, wlen;
+ ulong st_low, st_high;
+ ulong end_low, end_high;
+ ulong cal_low, cal_high;
+
+ if (cpu_id.fid.bits.rdtsc == 0 ) {
+ return(-1);
+ }
+ if (len == 0) return(-2);
dst = src + len;
wlen = len / 4; /* Length is bytes */
@@ -1382,12 +1174,12 @@ ulong memspeed(ulong src, ulong len, int iter, int type)
for (i=0; i<iter; i++) {
asm __volatile__ (
"movl %0,%%esi\n\t" \
- "movl %1,%%edi\n\t" \
- "movl %2,%%ecx\n\t" \
- "cld\n\t" \
- "rep\n\t" \
- "movsl\n\t" \
- :: "g" (src), "g" (dst), "g" (0)
+ "movl %1,%%edi\n\t" \
+ "movl %2,%%ecx\n\t" \
+ "cld\n\t" \
+ "rep\n\t" \
+ "movsl\n\t" \
+ :: "g" (src), "g" (dst), "g" (0)
: "esi", "edi", "ecx"
);
}
@@ -1404,76 +1196,31 @@ ulong memspeed(ulong src, ulong len, int iter, int type)
/* Now measure the speed */
- switch (type) {
- case MS_COPY:
- /* Do the first copy to prime the cache */
- asm __volatile__ (
+ /* Do the first copy to prime the cache */
+ asm __volatile__ (
+ "movl %0,%%esi\n\t" \
+ "movl %1,%%edi\n\t" \
+ "movl %2,%%ecx\n\t" \
+ "cld\n\t" \
+ "rep\n\t" \
+ "movsl\n\t" \
+ :: "g" (src), "g" (dst), "g" (wlen)
+ : "esi", "edi", "ecx"
+ );
+ asm __volatile__ ("rdtsc":"=a" (st_low),"=d" (st_high));
+ for (i=0; i<iter; i++) {
+ asm __volatile__ (
"movl %0,%%esi\n\t" \
"movl %1,%%edi\n\t" \
- "movl %2,%%ecx\n\t" \
- "cld\n\t" \
- "rep\n\t" \
- "movsl\n\t" \
+ "movl %2,%%ecx\n\t" \
+ "cld\n\t" \
+ "rep\n\t" \
+ "movsl\n\t" \
:: "g" (src), "g" (dst), "g" (wlen)
: "esi", "edi", "ecx"
);
- asm __volatile__ ("rdtsc":"=a" (st_low),"=d" (st_high));
- for (i=0; i<iter; i++) {
- asm __volatile__ (
- "movl %0,%%esi\n\t" \
- "movl %1,%%edi\n\t" \
- "movl %2,%%ecx\n\t" \
- "cld\n\t" \
- "rep\n\t" \
- "movsl\n\t" \
- :: "g" (src), "g" (dst), "g" (wlen)
- : "esi", "edi", "ecx"
- );
- }
- asm __volatile__ ("rdtsc":"=a" (end_low),"=d" (end_high));
- break;
- case MS_WRITE:
- asm __volatile__ ("rdtsc":"=a" (st_low),"=d" (st_high));
- for (i=0; i<iter; i++) {
- asm __volatile__ (
- "movl %0,%%ecx\n\t" \
- "movl %1,%%edi\n\t" \
- "movl %2,%%eax\n\t" \
- "rep\n\t" \
- "stosl\n\t"
- :: "g" (wlen), "g" (dst), "g" (0)
- : "edi", "ecx", "eax"
- );
- }
- asm __volatile__ ("rdtsc":"=a" (end_low),"=d" (end_high));
- break;
- case MS_READ:
- asm __volatile__ (
- "movl %0,%%esi\n\t" \
- "movl %1,%%ecx\n\t" \
- "cld\n\t" \
- "L1:\n\t" \
- "lodsl\n\t" \
- "loop L1\n\t" \
- :: "g" (src), "g" (wlen)
- : "esi", "ecx"
- );
- asm __volatile__ ("rdtsc":"=a" (st_low),"=d" (st_high));
- for (i=0; i<iter; i++) {
- asm __volatile__ (
- "movl %0,%%esi\n\t" \
- "movl %1,%%ecx\n\t" \
- "cld\n\t" \
- "L2:\n\t" \
- "lodsl\n\t" \
- "loop L2\n\t" \
- :: "g" (src), "g" (wlen)
- : "esi", "ecx", "eax"
- );
- }
- asm __volatile__ ("rdtsc":"=a" (end_low),"=d" (end_high));
- break;
}
+ asm __volatile__ ("rdtsc":"=a" (end_low),"=d" (end_high));
/* Compute the elapsed time */
asm __volatile__ (
@@ -1493,32 +1240,35 @@ ulong memspeed(ulong src, ulong len, int iter, int type)
);
/* Make sure that the result fits in 32 bits */
+ //hprint(11,40,end_high);
if (end_high) {
- return(0);
- }
-
- /* If this was a copy adjust the time */
- if (type == MS_COPY) {
- end_low /= 2;
+ return(-3);
}
+ end_low /= 2;
/* Convert to clocks/KB */
end_low /= len;
end_low *= 1024;
end_low /= iter;
if (end_low == 0) {
- return(0);
+ return(-4);
}
- if(tsc_invariable){ end_low = correct_tsc(end_low); }
-
/* Convert to kbytes/sec */
+
+ if (tsc_invariable) end_low = correct_tsc(end_low);
+
return((v->clks_msec)/end_low);
}
+#define rdmsr(msr,val1,val2) \
+ __asm__ __volatile__("rdmsr" \
+ : "=a" (val1), "=d" (val2) \
+ : "c" (msr))
+
+
ulong correct_tsc(ulong el_org)
{
-
float coef_now, coef_max;
int msr_lo, msr_hi, is_xe;
@@ -1535,7 +1285,7 @@ ulong correct_tsc(ulong el_org)
if ((msr_lo >> 14) & 0x1) { coef_max = coef_max + 0.5f; }
}
- if((cpu_id.feature_flag >> 7) & 1) {
+ if(cpu_id.fid.bits.eist) {
rdmsr(0x198, msr_lo, msr_hi);
coef_now = ((msr_lo >> 8) & 0x1F);
if ((msr_lo >> 14) & 0x1) { coef_now = coef_now + 0.5f; }
@@ -1543,10 +1293,9 @@ ulong correct_tsc(ulong el_org)
rdmsr(0x2A, msr_lo, msr_hi);
coef_now = (msr_lo >> 22) & 0x1F;
}
-
- if(coef_max && coef_now) { el_org = (ulong)(el_org * coef_now / coef_max); }
-
+ if(coef_max && coef_now) {
+ el_org = (ulong)(el_org * coef_now / coef_max);
+ }
return el_org;
-
}