All pastes #912800 Raw Edit

Someone

public text v1 · immutable
·published 2008-02-21 17:22 UTC
rendered paste body
/*
 * amd.c
 *
 * Reference documents:
 * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/20734.pdf
 *
 */

#include "cpuid.h"

char *AMDfeature_flags[] = {
  "Floating Point Unit",
  "Virtual Mode Extensions",
  "Debugging Extensions",
  "Page Size Extensions",
  "Time Stamp Counter (with RDTSC and CR4 disable bit)",
  "Model Specific Registers with RDMSR & WRMSR",
  "PAE - Page Address Extensions",
  "Machine Check Exception",
  "COMPXCHG8B Instruction",
  "APIC",
  "10 - Reserved",
  "SYSCALL/SYSRET or SYSENTER/SYSEXIT instructions",
  "MTRR - Memory Type Range Registers",
  "Global paging extension",
  "Machine Check Architecture",
  "Conditional Move Instruction",
  "PAT - Page Attribute Table",
  "PSE-36 - Page Size Extensions",
  "18 - reserved",
  "19 - reserved",
  "20 - reserved",
  "21 - reserved",
  "AMD MMX Instruction Extensions",
  "MMX instructions",
  "FXSAVE/FXRSTOR",
  "25 - reserved",
  "26 - reserved",
  "27 - reserved",
  "28 - reserved",
  "29 - reserved",
  "3DNow! Instruction Extensions",
  "3DNow instructions",
};

char *Assoc[] = {
  "L2 off",
  "Direct mapped",
  "2-way",
  "reserved",
  "4-way",
  "reserved",
  "8-way",
  "reserved",
  "16-way",
  "reserved",
  "reserved",
  "reserved",
  "reserved",
  "reserved",
  "reserved",
  "full",
};

/* AMD-specific information */
void doamd(int maxi){
  uint32_t maxei, xcpuid[4];
  int family = 0;

  printf("AMD-specific functions\n");

  /* Do standard stuff */
  if(maxi >= 1){
	uint32_t xcpuid[4];
	int stepping,model,reserved;

	do_cpuid(1,xcpuid);
	stepping = xcpuid[0] & 0xf;
	model = (xcpuid[0] >> 4) & 0xf;
	family = (xcpuid[0] >> 8) & 0xf;
	reserved = xcpuid[0] >> 12;

	printf("Version %08x:\n",xcpuid[0]);
	printf("Family: %d Model: %d [",family,model);
	switch(family){
	case 4:
		printf("486 model %d",model);
		break;
	case 5:
		switch(model){
		case 0:
		case 1:
		case 2:
		case 3:
		case 6:
		case 7:
	printf("K6 Model %d",model);
	break;
		case 8:
	printf("K6-2 Model 8");
	break;
		case 9:
	printf("K6-III Model 9");
	break;
		default:
	printf("K5/K6 model %d",model);
	break;
		}
		break;
	case 6:
		switch(model){
		case 1:
		case 2:
		case 4:
	printf("Athlon model %d",model);
	break;
		case 3:
	printf("Duron model 3");
	break;
		case 6:
	printf("Athlon MP/Mobile Athlon model 6");
	break;
		case 7:
	printf("Mobile Duron Model 7");
	break;
		default:
	printf("Duron/Athlon model %d",model);
	break;
		}

		break;
	}
	printf("]\n\n");
	{
		int i;

		printf("Standard feature flags %08x:\n",xcpuid[3]);
		for(i=0;i<32;i++){
	if(family == 5 && model == 0){
		if(i == 9)
		printf("Global Paging Extensions\n");
		else if(i == 13)
		printf("13 - reserved\n");
	} else {
		if(xcpuid[3] & (1<<i)){
		printf("%s\n",AMDfeature_flags[i]);
		}
	}
		}
	}
  }
  /* Check for presence of extended info */
  do_cpuid(0x80000000,xcpuid);
  maxei = xcpuid[0];
  if(maxei == 0)
	return;

  if(maxei >= 0x80000001){
	uint32_t xcpuid[4];
	int stepping,model,generation,reserved;
	int i;

	do_cpuid(0x80000001,xcpuid);
	stepping = xcpuid[0] & 0xf;
	model = (xcpuid[0] >> 4) & 0xf;
	generation = (xcpuid[0] >> 8) & 0xf;
	reserved = xcpuid[0] >> 12;

	printf("Generation: %d Model: %d\n",generation,model);
	printf("Extended feature flags %08x:\n",xcpuid[3]);
	for(i=0;i<32;i++){
		if(family == 5 && model == 0 && i == 9){
	printf("Global Paging Extensions\n");
		} else {
	if(xcpuid[3] & (1<<i)){
		printf("%s\n",AMDfeature_flags[i]);
	}
		}
	}
  }
  printf("\n");
  if(maxei >= 0x80000002){
	/* Processor identification string */
	int j;
	printf("Processor name string: ");
	for(j=0x80000002;j<=0x80000004;j++){
		uint32_t xcpuid[4];

		do_cpuid(j,xcpuid);
		printregs(xcpuid);
	}
	printf("\n");
  }
  if(maxei >= 0x80000005){
	/* TLB and cache info */
	uint32_t xcpuid[4];

	do_cpuid(0x80000005,xcpuid);
	printf("L1 Cache Information:\n");
	if(family >= 6){
		printf("2/4-MB Pages:\n");
		printf("   Data TLB: associativity %d-way #entries %d\n",
		 (xcpuid[0] >> 24) & 0xff,(xcpuid[0] >> 16) & 0xff);
		printf("   Instruction TLB: associativity %d-way #entries %d\n",
		 (xcpuid[0] >> 8) & 0xff,xcpuid[0] & 0xff);
	}
	printf("4-KB Pages:\n");	
	printf("   Data TLB: associativity %d-way #entries %d\n",
		 (xcpuid[1] >> 24) & 0xff,(xcpuid[1] >> 16) & 0xff);
	printf("   Instruction TLB: associativity %d-way #entries %d\n",
		 (xcpuid[1] >> 8) & 0xff,xcpuid[1] & 0xff);

	printf("L1 Data cache:\n");
	printf("   size %d KB associativity %x-way lines per tag %d line size %d\n",
		 xcpuid[2] >> 24,(xcpuid[2]>>16) & 0xff,(xcpuid[2] >> 8)&0xff,xcpuid[2]&0xff);

	printf("L1 Instruction cache:\n");
	printf("   size %d KB associativity %x-way lines per tag %d line size %d\n",
		 xcpuid[3] >> 24,(xcpuid[3]>>16) & 0xff,(xcpuid[3] >> 8)&0xff,xcpuid[3]&0xff);
	printf("\n");
  }
  
  /* check K6-III (and later?) on-chip L2 cache size */
  if (maxei >= 0x80000006) {
	uint32_t xcpuid[4];
	int assoc;

	do_cpuid(0x80000006,xcpuid);
	printf("L2 Cache Information:\n");
	if(family >= 6){
		printf("2/4-MB Pages:\n");
		assoc = (xcpuid[0] >> 24) & 0xff;
		if(assoc == 6)
	assoc = 8;
		printf("   Data TLB: associativity %s #entries %d\n",
		 Assoc[(xcpuid[0] >> 24) & 0xf],(xcpuid[0] >> 16) & 0xff);
		assoc = (xcpuid[0] >> 16) & 0xff;
		printf("   Instruction TLB: associativity %s #entries %d\n",
		 Assoc[(xcpuid[0] >> 8) & 0xf],xcpuid[0] & 0xff);
		
		printf("4-KB Pages:\n");	
		printf("   Data TLB: associativity %s #entries %d\n",
		 Assoc[(xcpuid[1] >> 24) & 0xf],(xcpuid[1] >> 16) & 0xff);
		printf("   Instruction TLB: associativity %s #entries %d\n",
		 Assoc[(xcpuid[1] >> 8) & 0xf],xcpuid[1] & 0xff);
	}
	printf("   size %d KB associativity %s lines per tag %d line size %d\n",
		 xcpuid[2] >> 24,Assoc[(xcpuid[2]>>16) & 0xf],(xcpuid[2] >> 8)&0xff,xcpuid[2]&0xff);

	printf("\n");
  }
  /* Check power management feature flags */
  if(maxei >= 0x80000007){
	uint32_t xcpuid[4];

	printf("Advanced Power Management Feature Flags\n");
	do_cpuid(0x80000007,xcpuid);
	if(xcpuid[3] & 1)
		printf("Has temperature sensing diode\n");
	if(xcpuid[3] & 2)
		printf("Supports Frequency ID control\n");
	if(xcpuid[3] & 4)
		printf("Supports Voltage ID control\n");
  }
  /* Check phys address & linear address size */
  if(maxei >= 0x80000008){
	uint32_t xcpuid[4];

	do_cpuid(0x80000008,xcpuid);
	printf("Maximum linear address: %d; maximum phys address %d\n",
		 (xcpuid[0]>>8) & 0xff,xcpuid[0]&0xff);
  }
}