Lines 257-262
Link Here
|
257 |
{ |
257 |
{ |
258 |
int i, off=0; |
258 |
int i, off=0; |
259 |
int l1_cache=0, l2_cache=0; |
259 |
int l1_cache=0, l2_cache=0; |
|
|
260 |
/* AL: use code and data cache sizes separately, if known */ |
261 |
int l1_code=0, l1_data=0; |
260 |
ulong speed; |
262 |
ulong speed; |
261 |
|
263 |
|
262 |
v->rdtsc = 0; |
264 |
v->rdtsc = 0; |
Lines 345-389
Link Here
|
345 |
case 5: |
347 |
case 5: |
346 |
switch(cpu_id.model) { |
348 |
switch(cpu_id.model) { |
347 |
case 0: |
349 |
case 0: |
|
|
350 |
cprint(LINE_CPU, 0, "AMD K5"); |
351 |
off = 6; |
352 |
break; |
348 |
case 1: |
353 |
case 1: |
349 |
case 2: |
354 |
case 2: |
350 |
case 3: |
355 |
case 3: |
351 |
cprint(LINE_CPU, 0, "AMD K5"); |
356 |
cprint(LINE_CPU, 0, "AMD K5"); |
352 |
off = 6; |
357 |
off = 6; |
|
|
358 |
l1_data = cpu_id.cache_info[3]; |
359 |
l1_code = cpu_id.cache_info[7]; |
353 |
break; |
360 |
break; |
354 |
case 6: |
361 |
case 6: |
355 |
case 7: |
362 |
case 7: |
356 |
cprint(LINE_CPU, 0, "AMD K6"); |
363 |
cprint(LINE_CPU, 0, "AMD K6"); |
357 |
off = 6; |
364 |
off = 6; |
358 |
l1_cache = cpu_id.cache_info[3]; |
365 |
l1_data = cpu_id.cache_info[3]; |
359 |
l1_cache += cpu_id.cache_info[7]; |
366 |
l1_code = cpu_id.cache_info[7]; |
360 |
break; |
367 |
break; |
361 |
case 8: |
368 |
case 8: |
362 |
cprint(LINE_CPU, 0, "AMD K6-2"); |
369 |
cprint(LINE_CPU, 0, "AMD K6-2"); |
363 |
off = 8; |
370 |
off = 8; |
364 |
l1_cache = cpu_id.cache_info[3]; |
371 |
l1_data = cpu_id.cache_info[3]; |
365 |
l1_cache += cpu_id.cache_info[7]; |
372 |
l1_code = cpu_id.cache_info[7]; |
366 |
break; |
373 |
break; |
367 |
case 9: |
374 |
case 9: |
368 |
cprint(LINE_CPU, 0, "AMD K6-III"); |
375 |
cprint(LINE_CPU, 0, "AMD K6-III"); |
369 |
off = 10; |
376 |
off = 10; |
370 |
l1_cache = cpu_id.cache_info[3]; |
377 |
l1_data = cpu_id.cache_info[3]; |
371 |
l1_cache += cpu_id.cache_info[7]; |
378 |
l1_code = cpu_id.cache_info[7]; |
372 |
l2_cache = (cpu_id.cache_info[11] << 8); |
379 |
l2_cache = (cpu_id.cache_info[11] << 8); |
373 |
l2_cache += cpu_id.cache_info[10]; |
380 |
l2_cache += cpu_id.cache_info[10]; |
374 |
break; |
381 |
break; |
375 |
} |
382 |
} |
376 |
break; |
383 |
break; |
377 |
case 6: |
384 |
case 6: |
|
|
385 |
l1_data = cpu_id.cache_info[3]; |
386 |
l1_code = cpu_id.cache_info[7]; |
387 |
l2_cache = (cpu_id.cache_info[11] << 8); |
388 |
l2_cache += cpu_id.cache_info[10]; |
378 |
switch(cpu_id.model) { |
389 |
switch(cpu_id.model) { |
379 |
case 1: |
390 |
case 1: |
380 |
case 2: |
391 |
case 2: |
381 |
case 4: |
392 |
case 4: |
382 |
case 6: |
393 |
case 6: |
|
|
394 |
case 8: |
383 |
cprint(LINE_CPU, 0, "AMD Athlon"); |
395 |
cprint(LINE_CPU, 0, "AMD Athlon"); |
384 |
off = 10; |
396 |
off = 10; |
385 |
l2_cache = (cpu_id.cache_info[11] << 8); |
|
|
386 |
l2_cache += cpu_id.cache_info[10]; |
387 |
break; |
397 |
break; |
388 |
case 3: |
398 |
case 3: |
389 |
case 7: |
399 |
case 7: |
Lines 394-407
Link Here
|
394 |
if (cpu_id.step == 0) { /* stepping 0 */ |
404 |
if (cpu_id.step == 0) { /* stepping 0 */ |
395 |
/* Hard code the right size */ |
405 |
/* Hard code the right size */ |
396 |
l2_cache = 64; |
406 |
l2_cache = 64; |
397 |
} else { |
|
|
398 |
l2_cache = (cpu_id.cache_info[11] << 8); |
399 |
l2_cache += cpu_id.cache_info[10]; |
400 |
} |
407 |
} |
401 |
break; |
408 |
break; |
402 |
} |
409 |
} |
403 |
l1_cache = cpu_id.cache_info[3]; |
|
|
404 |
l1_cache += cpu_id.cache_info[7]; |
405 |
} |
410 |
} |
406 |
break; |
411 |
break; |
407 |
|
412 |
|
Lines 448-473
Link Here
|
448 |
} |
453 |
} |
449 |
|
454 |
|
450 |
/* Get the cache info */ |
455 |
/* Get the cache info */ |
451 |
for (i=0; i<16; i++) { |
456 |
/* AL: scan from 1, because i==0 (al) -- not cache descriptor */ |
|
|
457 |
/* AL: TODO: if cache_info[0]>1, additional "cpuid 2"'s needed */ |
458 |
for (i=1; i<16; i++) { |
452 |
#ifdef CPUID_DEBUG |
459 |
#ifdef CPUID_DEBUG |
453 |
dprint(12,i*3,cpu_id.cache_info[i],2,1); |
460 |
dprint(12,i*3,cpu_id.cache_info[i],2,1); |
454 |
#endif |
461 |
#endif |
|
|
462 |
/* AL: skip reserved registers (with bit 31 ==1) */ |
463 |
if (cpu_id.cache_info[i | 3] & 0x80) |
464 |
continue; |
465 |
else |
455 |
switch(cpu_id.cache_info[i]) { |
466 |
switch(cpu_id.cache_info[i]) { |
456 |
case 0x6: |
467 |
case 0x6: |
|
|
468 |
l1_code += 8; |
469 |
break; |
457 |
case 0xa: |
470 |
case 0xa: |
458 |
case 0x66: |
471 |
case 0x66: |
459 |
l1_cache += 8; |
472 |
l1_data += 8; |
460 |
break; |
473 |
break; |
461 |
case 0x8: |
474 |
case 0x8: |
|
|
475 |
l1_code += 16; |
476 |
break; |
462 |
case 0xc: |
477 |
case 0xc: |
463 |
case 0x67: |
478 |
case 0x67: |
464 |
l1_cache += 16; |
479 |
l1_data += 16; |
|
|
480 |
break; |
481 |
case 0x30: |
482 |
l1_code += 32; |
465 |
break; |
483 |
break; |
|
|
484 |
case 0x2C: |
466 |
case 0x68: |
485 |
case 0x68: |
467 |
l1_cache += 32; |
486 |
l1_data += 32; |
468 |
break; |
487 |
break; |
469 |
case 0x40: |
488 |
case 0x40: |
470 |
l2_cache = 0; |
489 |
/* l2_cache = 0; */ /* AL: not needed -- see CPUID descr. */ |
471 |
break; |
490 |
break; |
472 |
case 0x41: |
491 |
case 0x41: |
473 |
case 0x79: |
492 |
case 0x79: |
Lines 481-502
Link Here
|
481 |
case 0x43: |
500 |
case 0x43: |
482 |
case 0x7b: |
501 |
case 0x7b: |
483 |
case 0x83: |
502 |
case 0x83: |
|
|
503 |
case 0x86: |
484 |
l2_cache = 512; |
504 |
l2_cache = 512; |
485 |
break; |
505 |
break; |
486 |
case 0x44: |
506 |
case 0x44: |
|
|
507 |
case 0x78: |
487 |
case 0x7c: |
508 |
case 0x7c: |
488 |
case 0x84: |
509 |
case 0x84: |
|
|
510 |
case 0x87: |
489 |
l2_cache = 1024; |
511 |
l2_cache = 1024; |
490 |
break; |
512 |
break; |
491 |
case 0x45: |
513 |
case 0x45: |
|
|
514 |
case 0x7D: |
492 |
case 0x85: |
515 |
case 0x85: |
493 |
l2_cache = 2048; |
516 |
l2_cache = 2048; |
494 |
break; |
517 |
break; |
495 |
} |
518 |
} |
496 |
} |
519 |
} |
497 |
|
520 |
|
498 |
switch(cpu_id.type) { |
521 |
if (cpu_id.type == 5) { |
499 |
case 5: |
|
|
500 |
switch(cpu_id.model) { |
522 |
switch(cpu_id.model) { |
501 |
case 0: |
523 |
case 0: |
502 |
case 1: |
524 |
case 1: |
Lines 504-510
Link Here
|
504 |
case 3: |
526 |
case 3: |
505 |
case 7: |
527 |
case 7: |
506 |
cprint(LINE_CPU, 0, "Pentium"); |
528 |
cprint(LINE_CPU, 0, "Pentium"); |
507 |
if (l1_cache == 0) { |
529 |
if (l1_code == 0 && l1_data == 0) { |
508 |
l1_cache = 8; |
530 |
l1_cache = 8; |
509 |
} |
531 |
} |
510 |
off = 7; |
532 |
off = 7; |
Lines 512-581
Link Here
|
512 |
case 4: |
534 |
case 4: |
513 |
case 8: |
535 |
case 8: |
514 |
cprint(LINE_CPU, 0, "Pentium-MMX"); |
536 |
cprint(LINE_CPU, 0, "Pentium-MMX"); |
515 |
if (l1_cache == 0) { |
537 |
if (l1_code == 0 && l1_data == 0) { |
516 |
l1_cache = 16; |
538 |
l1_cache = 16; |
517 |
} |
539 |
} |
518 |
off = 11; |
540 |
off = 11; |
519 |
break; |
541 |
break; |
520 |
} |
542 |
} |
521 |
break; |
543 |
} else { |
522 |
case 6: |
544 |
/* AL: if Intel CPU brand id (bl) is known -- use it */ |
523 |
switch(cpu_id.model) { |
545 |
switch(cpu_id.brand) { |
524 |
case 0: |
546 |
case 0x01: |
525 |
case 1: |
547 |
case 0x0A: |
526 |
cprint(LINE_CPU, 0, "Pentium Pro"); |
548 |
cprint(LINE_CPU, 0, "Celeron"); |
527 |
off = 11; |
549 |
off = 7; |
528 |
break; |
550 |
break; |
529 |
case 3: |
551 |
case 0x02: |
530 |
cprint(LINE_CPU, 0, "Pentium II"); |
552 |
case 0x04: |
531 |
off = 10; |
553 |
cprint(LINE_CPU, 0, "Pentium III"); |
|
|
554 |
off = 11; |
532 |
break; |
555 |
break; |
533 |
case 5: |
556 |
case 0x03: |
534 |
if (l2_cache == 0) { |
557 |
if (cpu_id.type == 6 |
|
|
558 |
&& cpu_id.model == 0xB |
559 |
&& cpu_id.step == 1) { |
535 |
cprint(LINE_CPU, 0, "Celeron"); |
560 |
cprint(LINE_CPU, 0, "Celeron"); |
536 |
off = 7; |
561 |
off = 7; |
537 |
} else { |
562 |
} else { |
538 |
cprint(LINE_CPU, 0, "Pentium II"); |
563 |
cprint(LINE_CPU, 0, "Pentium III Xeon"); |
539 |
off = 10; |
564 |
off = 16; |
540 |
} |
565 |
} |
541 |
break; |
566 |
break; |
542 |
case 6: |
567 |
case 0x06: |
543 |
if (l2_cache == 128) { |
568 |
cprint(LINE_CPU, 0, "Mobile Pentium III"); |
544 |
cprint(LINE_CPU, 0, "Celeron"); |
569 |
off = 18; |
|
|
570 |
break; |
571 |
case 0x07: |
572 |
case 0x0F: |
573 |
case 0x13: |
574 |
cprint(LINE_CPU, 0, "Mobile Celeron"); |
575 |
off = 14; |
576 |
break; |
577 |
case 0x08: |
578 |
case 0x09: |
579 |
cprint(LINE_CPU, 0, "Pentium 4"); |
580 |
off = 9; |
581 |
break; |
582 |
case 0x0B: |
583 |
if (cpu_id.type == 0xF |
584 |
&& cpu_id.model == 1 |
585 |
&& cpu_id.step == 3) { |
586 |
cprint(LINE_CPU, 0, "Xeon MP"); |
545 |
off = 7; |
587 |
off = 7; |
546 |
} else { |
588 |
} else { |
547 |
cprint(LINE_CPU, 0, "Pentium II"); |
589 |
cprint(LINE_CPU, 0, "Xeon"); |
548 |
off = 10; |
590 |
off = 4; |
549 |
} |
591 |
} |
550 |
break; |
592 |
break; |
551 |
case 7: |
593 |
case 0x0C: |
552 |
case 8: |
594 |
cprint(LINE_CPU, 0, "Xeon MP"); |
553 |
case 10: |
595 |
off = 7; |
554 |
case 11: |
596 |
break; |
555 |
cprint(LINE_CPU, 0, "Pentium III"); |
597 |
case 0x0E: |
556 |
off = 11; |
598 |
if (cpu_id.type == 0xF |
|
|
599 |
&& cpu_id.model == 1 |
600 |
&& cpu_id.step == 3) { |
601 |
cprint(LINE_CPU, 0, "Xeon"); |
602 |
off = 4; |
603 |
} else { |
604 |
cprint(LINE_CPU, 0, "Mobile Pentium 4"); |
605 |
off = 16; |
606 |
} |
607 |
break; |
608 |
case 0x16: |
609 |
cprint(LINE_CPU, 0, "Pentium M"); |
610 |
off = 9; |
611 |
break; |
612 |
/* AL: if unknown Intel CPU brand id -- drop to old code */ |
613 |
default: |
614 |
if (cpu_id.type == 6) { |
615 |
switch(cpu_id.model) { |
616 |
case 0: |
617 |
case 1: |
618 |
cprint(LINE_CPU, 0, "Pentium Pro"); |
619 |
off = 11; |
620 |
break; |
621 |
case 3: |
622 |
cprint(LINE_CPU, 0, "Pentium II"); |
623 |
off = 10; |
624 |
break; |
625 |
case 5: |
626 |
if (l2_cache == 0) { |
627 |
cprint(LINE_CPU, 0, "Celeron"); |
628 |
off = 7; |
629 |
} else { |
630 |
cprint(LINE_CPU, 0, "Pentium II"); |
631 |
off = 10; |
632 |
} |
633 |
break; |
634 |
case 6: |
635 |
if (l2_cache == 128) { |
636 |
cprint(LINE_CPU, 0, "Celeron"); |
637 |
off = 7; |
638 |
} else { |
639 |
cprint(LINE_CPU, 0, "Pentium II"); |
640 |
off = 10; |
641 |
} |
642 |
break; |
643 |
case 7: |
644 |
case 8: |
645 |
case 10: |
646 |
case 11: |
647 |
cprint(LINE_CPU, 0, "Pentium III"); |
648 |
off = 11; |
649 |
break; |
650 |
} |
651 |
} else if (cpu_id.type == 15) { |
652 |
cprint(LINE_CPU, 0, "Pentium 4"); |
653 |
off = 9; |
654 |
} |
557 |
break; |
655 |
break; |
558 |
} |
656 |
} |
559 |
break; |
|
|
560 |
case 15: |
561 |
cprint(LINE_CPU, 0, "Pentium 4"); |
562 |
off = 9; |
563 |
} |
657 |
} |
564 |
break; |
658 |
break; |
565 |
|
659 |
|
566 |
/* Cyrix Processors with CPUID */ |
660 |
/* Cyrix Processors with CPUID or VIA C3 Processors */ |
567 |
case 'C': |
661 |
case 'C': |
568 |
switch(cpu_id.model) { |
662 |
if (cpu_id.vend_id[1] == 'e') { |
569 |
case 0: |
663 |
cprint(LINE_CPU, 0, "VIA C3"); |
570 |
cprint(LINE_CPU, 0, "Cyrix 6x86MX/MII"); |
664 |
off = 6; |
571 |
off = 16; |
665 |
l1_data = cpu_id.cache_info[3]; |
572 |
break; |
666 |
l1_code = cpu_id.cache_info[7]; |
573 |
case 4: |
667 |
l2_cache = (cpu_id.cache_info[11] << 8); |
574 |
cprint(LINE_CPU, 0, "Cyrix GXm"); |
668 |
l2_cache += cpu_id.cache_info[10]; |
575 |
off = 9; |
669 |
} else { |
576 |
break; |
670 |
switch(cpu_id.model) { |
|
|
671 |
case 0: |
672 |
cprint(LINE_CPU, 0, "Cyrix 6x86MX/MII"); |
673 |
off = 16; |
674 |
break; |
675 |
case 4: |
676 |
cprint(LINE_CPU, 0, "Cyrix GXm"); |
677 |
off = 9; |
678 |
break; |
679 |
} |
680 |
return; |
577 |
} |
681 |
} |
578 |
return; |
|
|
579 |
break; |
682 |
break; |
580 |
|
683 |
|
581 |
/* Unknown processor */ |
684 |
/* Unknown processor */ |
Lines 608-621
Link Here
|
608 |
} |
711 |
} |
609 |
} |
712 |
} |
610 |
|
713 |
|
|
|
714 |
/* AL: Use half of L1 cache size for L1 code and L1 data size, */ |
715 |
/* AL: if they are not known, and set L1 cache size equal to sum */ |
716 |
/* AL: of the L1 code and L1 data in the opposite case */ |
717 |
if (l1_code == 0 && l1_data == 0) { |
718 |
l1_code = l1_data = l1_cache / 2; |
719 |
} |
720 |
if (l1_cache == 0) { |
721 |
l1_cache = l1_code + l1_data; |
722 |
} |
723 |
|
611 |
/* Print out L1 cache info */ |
724 |
/* Print out L1 cache info */ |
612 |
/* To measure L1 cache speed we use a block size that is 1/4th */ |
725 |
/* To measure L1 cache speed we use a block size that is 1/2nd */ |
613 |
/* of the total L1 cache size since half of it is for instructions */ |
726 |
/* of the L1 data cache size -1k */ |
614 |
if (l1_cache) { |
727 |
if (l1_cache) { |
615 |
cprint(LINE_CPU+1, 9, " K "); |
728 |
cprint(LINE_CPU+1, 9, " K "); |
616 |
dprint(LINE_CPU+1, 10, l1_cache, 4, 0); |
729 |
dprint(LINE_CPU+1, 10, l1_cache, 4, 0); |
617 |
if ((speed=memspeed((ulong)mapping(0x100), |
730 |
if ((i = l1_data / 2)) i--; |
618 |
(l1_cache / 4) * 1024, 50))) { |
731 |
if ((speed=memspeed((ulong)mapping(0x100), i*1024, 500))) { |
619 |
cprint(LINE_CPU+1, 15, " MB/s"); |
732 |
cprint(LINE_CPU+1, 15, " MB/s"); |
620 |
dprint(LINE_CPU+1, 15, speed, 6, 0); |
733 |
dprint(LINE_CPU+1, 15, speed, 6, 0); |
621 |
} |
734 |
} |
Lines 623-640
Link Here
|
623 |
|
736 |
|
624 |
/* Print out L2 cache info */ |
737 |
/* Print out L2 cache info */ |
625 |
/* We measure the L2 cache speed by using a block size that is */ |
738 |
/* We measure the L2 cache speed by using a block size that is */ |
626 |
/* the size of the L1 cache. We have to fudge if the L1 */ |
739 |
/* AL: 1/2nd of the L2 cache size -1k. We have to fudge if the L1 */ |
627 |
/* cache is bigger than the L2 */ |
740 |
/* data cache is bigger than the L2 */ |
628 |
if (l2_cache) { |
741 |
if (l2_cache) { |
|
|
742 |
/* AL: for exclusive L2 cache in VIA C3 */ |
743 |
int total2 = l2_cache; |
744 |
if (cpu_id.vend_id[0] == 'C') { |
745 |
total2 += l1_data; |
746 |
} |
629 |
cprint(LINE_CPU+2, 9, " K "); |
747 |
cprint(LINE_CPU+2, 9, " K "); |
630 |
cprint(LINE_CPU+2, 0, "L2 Cache ?K"); |
748 |
cprint(LINE_CPU+2, 0, "L2 Cache ?K"); |
631 |
dprint(LINE_CPU+2, 10, l2_cache, 4, 0); |
749 |
dprint(LINE_CPU+2, 10, l2_cache, 4, 0); |
632 |
|
750 |
|
633 |
if (l2_cache < l1_cache) { |
751 |
i = total2 / 2; |
634 |
i = l1_cache / 4 + l2_cache / 4; |
752 |
if (total2 < l1_data) { |
635 |
} else { |
753 |
i = l1_data / 4 + total2 / 4; |
636 |
i = l1_cache; |
|
|
637 |
} |
754 |
} |
|
|
755 |
if (i) i--; |
638 |
if ((speed=memspeed((ulong)mapping(0x100), i*1024, 50))) { |
756 |
if ((speed=memspeed((ulong)mapping(0x100), i*1024, 50))) { |
639 |
cprint(LINE_CPU+2, 15, " MB/s"); |
757 |
cprint(LINE_CPU+2, 15, " MB/s"); |
640 |
dprint(LINE_CPU+2, 15, speed, 6, 0); |
758 |
dprint(LINE_CPU+2, 15, speed, 6, 0); |
Lines 642-649
Link Here
|
642 |
} |
760 |
} |
643 |
|
761 |
|
644 |
/* Determine memory speed. To find the memory spped we use */ |
762 |
/* Determine memory speed. To find the memory spped we use */ |
645 |
/* A block size that is 5x the sum of the L1 and L2 caches */ |
763 |
/* A block size that is 5x the sum of the L1 data and L2 caches */ |
646 |
i = (l2_cache + l1_cache) * 5; |
764 |
/* AL: or 64 Kb, if sum ==0 */ |
|
|
765 |
i = (l2_cache + l1_data) * 5; |
766 |
if (i == 0) { |
767 |
i = 64; |
768 |
} |
647 |
|
769 |
|
648 |
/* Make sure that we have enough memory to do the test */ |
770 |
/* Make sure that we have enough memory to do the test */ |
649 |
if ((1 + (i * 2)) > (v->plim_upper << 2)) { |
771 |
if ((1 + (i * 2)) > (v->plim_upper << 2)) { |
Lines 728-733
Link Here
|
728 |
ulong wlen; |
850 |
ulong wlen; |
729 |
int i; |
851 |
int i; |
730 |
|
852 |
|
|
|
853 |
if (len == 0 || iter == 0) { |
854 |
return 0; |
855 |
} |
856 |
|
731 |
dst = src + len; |
857 |
dst = src + len; |
732 |
wlen = len / 4; /* Length is bytes */ |
858 |
wlen = len / 4; /* Length is bytes */ |
733 |
|
859 |
|