Chameleon

Chameleon Commit Details

Date:2015-05-15 18:53:44 (8 years 11 months ago)
Author:ErmaC
Commit:2682
Parents: 2681
Message:Refactoring and optimization for cpu.c (Credits to Bronya)
Changes:
M/trunk/i386/libsaio/cpu.c

File differences

trunk/i386/libsaio/cpu.c
2525
2626
2727
28
28
2929
30
31
32
33
34
35
36
37
38
39
30
31
32
4033
4134
4235
......
4841
4942
5043
51
44
5245
5346
5447
......
8275
8376
8477
85
78
8679
8780
88
81
8982
9083
9184
......
214207
215208
216209
217
218210
219211
220212
......
276268
277269
278270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
279368
280369
281
370
371
372
282373
283374
284375
......
305396
306397
307398
308
309
310399
311400
312401
......
327416
328417
329418
330
331419
332
333420
334421
335
336422
337423
338424
......
342428
343429
344430
345
346431
347432
348433
......
366451
367452
368453
369
370
371
372
373
374454
375455
376456
......
385465
386466
387467
388
389
390468
391469
392470
......
398476
399477
400478
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423479
424480
425481
......
477533
478534
479535
480
481536
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497537
498538
499539
......
517557
518558
519559
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556560
557561
558562
clock_frequency_info_t gPEClockFrequencyInfo;
static inline uint32_t __unused clockspeed_rdtsc(void)
static __unused uint64_t rdtsc32(void)
{
uint32_t out;
__asm__ volatile (
"rdtsc\n"
"shl $32,%%edx\n"
"or %%edx,%%eax\n"
: "=a" (out)
:
: "%edx"
);
return out;
unsigned int lo,hi;
__asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
return ((uint64_t)hi << 32) | lo;
}
/*
static uint64_t timeRDTSC(void)
{
intattempts = 0;
uint64_t latchTime;
uint32_t latchTime;
uint64_tsaveTime,intermediate;
unsigned inttimerValue, lastValue;
//boolean_tint_enabled;
attempts++;
enable_PIT2();// turn on PIT2
set_PIT2(0);// reset timer 2 to be zero
latchTime = rdtsc64();// get the time stamp to time
latchTime = rdtsc32();// get the time stamp to time
latchTime = get_PIT2(&timerValue) - latchTime; // time how long this takes
set_PIT2(SAMPLE_CLKS_INT);// set up the timer for (almost) 1/20th a second
saveTime = rdtsc64();// now time how long a 20th a second is...
saveTime = rdtsc32();// now time how long a 20th a second is...
get_PIT2(&lastValue);
get_PIT2(&lastValue);// read twice, first value may be unreliable
do {
uint32_trtc_quant_scale;/* clock to nanos multiplier */
uint64_trtc_cyc_per_sec;/* processor cycles per sec */
uint64_trtc_cycle_count;/* clocks in 1/20th second */
//uint64_t cpuFreq;
static uint64_t rtc_set_cyc_per_sec(uint64_t cycles)
{
#define quad(hi,lo)(((uint64_t)(hi)) << 32 | (lo))
void get_cpuid(PlatformInfo_t *p)
{
charstr[128];
uint32_treg[4];
char*s= 0;
do_cpuid(0x00000000, p->CPU.CPUID[CPUID_0]); // MaxFn, Vendor
do_cpuid(0x00000001, p->CPU.CPUID[CPUID_1]); // Signature, stepping, features
do_cpuid(0x00000002, p->CPU.CPUID[CPUID_2]); // TLB/Cache/Prefetch
do_cpuid(0x00000003, p->CPU.CPUID[CPUID_3]); // S/N
do_cpuid(0x80000000, p->CPU.CPUID[CPUID_80]); // Get the max extended cpuid
if ((p->CPU.CPUID[CPUID_80][0] & 0x0000000f) >= 8)
{
do_cpuid(0x80000008, p->CPU.CPUID[CPUID_88]);
do_cpuid(0x80000001, p->CPU.CPUID[CPUID_81]);
}
else if ((p->CPU.CPUID[CPUID_80][0] & 0x0000000f) >= 1)
{
do_cpuid(0x80000001, p->CPU.CPUID[CPUID_81]);
}
// ==============================================================
/* get BrandString (if supported) */
/* Copyright: from Apple's XNU cpuid.c */
if (p->CPU.CPUID[CPUID_80][0] > 0x80000004)
{
bzero(str, 128);
/*
* The BrandString 48 bytes (max), guaranteed to
* be NULL terminated.
*/
do_cpuid(0x80000002, reg);
memcpy(&str[0], (char *)reg, 16);
do_cpuid(0x80000003, reg);
memcpy(&str[16], (char *)reg, 16);
do_cpuid(0x80000004, reg);
memcpy(&str[32], (char *)reg, 16);
for (s = str; *s != '\0'; s++)
{
if (*s != ' ')
{
break;
}
}
strlcpy(p->CPU.BrandString, s, 48);
if (!strncmp(p->CPU.BrandString, CPU_STRING_UNKNOWN, MIN(sizeof(p->CPU.BrandString), (unsigned)strlen(CPU_STRING_UNKNOWN) + 1)))
{
/*
* This string means we have a firmware-programmable brand string,
* and the firmware couldn't figure out what sort of CPU we have.
*/
p->CPU.BrandString[0] = '\0';
}
p->CPU.BrandString[47] = '\0';
//DBG("Brandstring = %s\n", p->CPU.BrandString);
}
// ==============================================================
switch(p->CPU.BrandString[0])
{
case 'A':
/* AMD Processors */
// The cache information is only in ecx and edx so only save
// those registers
do_cpuid(5, p->CPU.CPUID[CPUID_5]); // Monitor/Mwait
do_cpuid(0x80000005, p->CPU.CPUID[CPUID_85]); // TLB/Cache/Prefetch
do_cpuid(0x80000006, p->CPU.CPUID[CPUID_86]); // TLB/Cache/Prefetch
do_cpuid(0x80000008, p->CPU.CPUID[CPUID_88]);
break;
case 'G':
/* Intel Processors */
do_cpuid2(0x00000004, 0, p->CPU.CPUID[CPUID_4]); // Cache Index for Inte
if (p->CPU.CPUID[CPUID_0][0] >= 0x5)// Monitor/Mwait
{
do_cpuid(5, p->CPU.CPUID[CPUID_5]);
}
if (p->CPU.CPUID[CPUID_0][0] >= 6)// Thermal/Power
{
do_cpuid(6, p->CPU.CPUID[CPUID_6]);
}
break;
}
}
void scan_cpu(PlatformInfo_t *p)
{
//scan();
get_cpuid(p);
uint64_tbusFCvtt2n;
uint64_ttscFCvtt2n;
uint64_ttscFreq= 0;
uint8_tcpuMultN2= 0;
const char*newratio;
charstr[128];
char*s= 0;
intlen= 0;
intmyfsb= 0;
+--------+----------------+--------+----+----+--------+--------+--------+
*/
///////////////////-- MaxFn,Vendor --////////////////////////
do_cpuid(0x00000000, p->CPU.CPUID[CPUID_0]); // MaxFn, Vendor
p->CPU.Vendor= p->CPU.CPUID[CPUID_0][1];
/////////////////////////////////////////////////////////////
///////////////////-- Signature, stepping, features -- //////
do_cpuid(0x00000001, p->CPU.CPUID[CPUID_1]); // Signature, stepping, features
cpuid_features = quad(p->CPU.CPUID[CPUID_1][ecx], p->CPU.CPUID[CPUID_1][edx]);
if (bit(28) & p->CPU.CPUID[CPUID_1][edx]) // HTT/Multicore
{
{
logical_per_package = 1;
}
//printf("logical %d\n",logical_per_package);
p->CPU.Signature= p->CPU.CPUID[CPUID_1][0];
p->CPU.Stepping= (uint8_t)bitfield(p->CPU.CPUID[CPUID_1][0], 3, 0);// stepping = cpu_feat_eax & 0xF;
{
case CPUID_VENDOR_INTEL:
{
do_cpuid(0x00000002, p->CPU.CPUID[CPUID_2]); // TLB/Cache/Prefetch
do_cpuid(0x00000003, p->CPU.CPUID[CPUID_3]); // S/N
/* Based on Apple's XNU cpuid.c - Deterministic cache parameters */
if ((p->CPU.CPUID[CPUID_0][eax] > 3) && (p->CPU.CPUID[CPUID_0][eax] < 0x80000000))
{
}
}
do_cpuid2(0x00000004, 0, p->CPU.CPUID[CPUID_4]);
if (i > 0)
{
cores_per_package = bitfield(p->CPU.CPUID[CPUID_4][eax], 31, 26) + 1; // i = cache index
cores_per_package = 1;
}
if (p->CPU.CPUID[CPUID_0][0] >= 0x5)// Monitor/Mwait
{
do_cpuid(5, p->CPU.CPUID[CPUID_5]);
}
if (p->CPU.CPUID[CPUID_0][0] >= 6)// Thermal/Power
{
do_cpuid(6, p->CPU.CPUID[CPUID_6]);
}
do_cpuid(0x80000000, p->CPU.CPUID[CPUID_80]);
if ((p->CPU.CPUID[CPUID_80][0] & 0x0000000f) >= 8)
{
do_cpuid(0x80000008, p->CPU.CPUID[CPUID_88]);
do_cpuid(0x80000001, p->CPU.CPUID[CPUID_81]);
}
else if ((p->CPU.CPUID[CPUID_80][0] & 0x0000000f) >= 1)
{
do_cpuid(0x80000001, p->CPU.CPUID[CPUID_81]);
}
switch (p->CPU.Model)
{
case CPUID_MODEL_NEHALEM:
case CPUID_VENDOR_AMD:
{
do_cpuid(5, p->CPU.CPUID[CPUID_5]); // Monitor/Mwait
do_cpuid(0x80000000, p->CPU.CPUID[CPUID_80]);
if ((p->CPU.CPUID[CPUID_80][0] & 0x0000000f) >= 8)
{
do_cpuid(0x80000008, p->CPU.CPUID[CPUID_88]);
}
if ((p->CPU.CPUID[CPUID_80][0] & 0x0000000f) >= 1)
{
do_cpuid(0x80000001, p->CPU.CPUID[CPUID_81]);
}
do_cpuid(0x80000005, p->CPU.CPUID[CPUID_85]); // TLB/Cache/Prefetch
do_cpuid(0x80000006, p->CPU.CPUID[CPUID_86]); // TLB/Cache/Prefetch
do_cpuid(0x80000008, p->CPU.CPUID[CPUID_88]);
cores_per_package = bitfield(p->CPU.CPUID[CPUID_88][ecx], 7, 0) + 1;
threads_per_core = cores_per_package;
stop("Unsupported CPU detected! System halted.");
}
/* get BrandString (if supported) */
/* Copyright: from Apple's XNU cpuid.c */
if (p->CPU.CPUID[CPUID_80][0] > 0x80000004)
{
bzero(str, 128);
/*
* The BrandString 48 bytes (max), guaranteed to
* be NULL terminated.
*/
do_cpuid(0x80000002, reg);
memcpy(&str[0], (char *)reg, 16);
do_cpuid(0x80000003, reg);
memcpy(&str[16], (char *)reg, 16);
do_cpuid(0x80000004, reg);
memcpy(&str[32], (char *)reg, 16);
for (s = str; *s != '\0'; s++)
{
if (*s != ' ')
{
break;
}
}
strlcpy(p->CPU.BrandString, s, 48);
if (!strncmp(p->CPU.BrandString, CPU_STRING_UNKNOWN, MIN(sizeof(p->CPU.BrandString), (unsigned)strlen(CPU_STRING_UNKNOWN) + 1)))
{
/*
* This string means we have a firmware-programmable brand string,
* and the firmware couldn't figure out what sort of CPU we have.
*/
p->CPU.BrandString[0] = '\0';
}
p->CPU.BrandString[47] = '\0';
//DBG("Brandstring = %s\n", p->CPU.BrandString);
}
/* setup features */
if ((bit(23) & p->CPU.CPUID[CPUID_1][3]) != 0)
{

Archive Download the corresponding diff file

Revision: 2682