1 /* 2 * Copyright 2012 Haiku, Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Alexander von Gluck, kallisti5@unixzen.com 7 */ 8 9 /* 10 * Pass a standard CPUID in hex, and get out a CPUID for OS.h 11 */ 12 13 14 #include <stdio.h> 15 #include <stdlib.h> 16 #include <string.h> 17 18 19 #define EXT_FAMILY_MASK 0xF00000 20 #define EXT_MODEL_MASK 0x0F0000 21 #define FAMILY_MASK 0x000F00 22 #define MODEL_MASK 0x0000F0 23 #define STEPPING_MASK 0x00000F 24 25 26 // Converts a hexadecimal string to integer 27 static int 28 xtoi(const char* xs, unsigned int* result) 29 { 30 size_t szlen = strlen(xs); 31 int i; 32 int xv; 33 int fact; 34 35 if (szlen > 0) { 36 // Converting more than 32bit hexadecimal value? 37 if (szlen > 8) 38 return 2; 39 40 // Begin conversion here 41 *result = 0; 42 fact = 1; 43 44 // Run until no more character to convert 45 for (i = szlen - 1; i>=0; i--) { 46 if (isxdigit(*(xs + i))) { 47 if (*(xs + i) >= 97) 48 xv = (*(xs + i) - 97) + 10; 49 else if (*(xs + i) >= 65) 50 xv = (*(xs + i) - 65) + 10; 51 else 52 xv = *(xs + i) - 48; 53 54 *result += (xv * fact); 55 fact *= 16; 56 } else { 57 // Conversion was abnormally terminated 58 // by non hexadecimal digit, hence 59 // returning only the converted with 60 // an error value 4 (illegal hex character) 61 return 4; 62 } 63 } 64 } 65 66 // Nothing to convert 67 return 1; 68 } 69 70 71 int 72 main(int argc, char *argv[]) 73 { 74 if (argc != 3) { 75 printf("Provide the cpuid in hex, and you will get how we id it\n"); 76 printf("usage: cpuidhaiku <AMD|INTEL> <cpuid_hex>\n"); 77 return 1; 78 } 79 80 unsigned int cpuid = 0; 81 xtoi(argv[2], &cpuid); 82 83 printf("cpuid: 0x%X\n", cpuid); 84 85 unsigned int extFam = (cpuid & EXT_FAMILY_MASK) >> 20; 86 unsigned int extMod = (cpuid & EXT_MODEL_MASK) >> 16; 87 unsigned int family = (cpuid & FAMILY_MASK) >> 8; 88 unsigned int model = (cpuid & MODEL_MASK) >> 4; 89 unsigned int stepping = (cpuid & STEPPING_MASK); 90 91 unsigned int cpuidHaiku; 92 if (strncmp(argv[1], "AMD", 3) == 0) { 93 if (family == 0xF) { 94 cpuidHaiku = (extFam << 20) + (extMod << 16) 95 + (family << 4) + model; 96 } else 97 cpuidHaiku = (family << 4) + model; 98 cpuidHaiku += 0x1100; // AMD vendor id 99 } else if (strncmp(argv[1], "INTEL", 5) == 0) { 100 cpuidHaiku = (extFam << 20) + (extMod << 16) 101 + (family << 4) + model; 102 cpuidHaiku += 0x1000; // Intel vendor id 103 } else { 104 printf("Vendor should be AMD or INTEL\n"); 105 return 1; 106 } 107 108 printf("Haiku CPUID: 0x%lx\n", cpuidHaiku); 109 110 return 0; 111 } 112