Home | History | Annotate | Download | only in util
      1 #include <sys/types.h>
      2 #include <unistd.h>
      3 #include <stdio.h>
      4 #include <stdlib.h>
      5 #include <string.h>
      6 
      7 #include "../../util/header.h"
      8 
      9 static inline void
     10 cpuid(unsigned int op, unsigned int *a, unsigned int *b, unsigned int *c,
     11       unsigned int *d)
     12 {
     13 	__asm__ __volatile__ (".byte 0x53\n\tcpuid\n\t"
     14 			      "movl %%ebx, %%esi\n\t.byte 0x5b"
     15 			: "=a" (*a),
     16 			"=S" (*b),
     17 			"=c" (*c),
     18 			"=d" (*d)
     19 			: "a" (op));
     20 }
     21 
     22 int
     23 get_cpuid(char *buffer, size_t sz)
     24 {
     25 	unsigned int a, b, c, d, lvl;
     26 	int family = -1, model = -1, step = -1;
     27 	int nb;
     28 	char vendor[16];
     29 
     30 	cpuid(0, &lvl, &b, &c, &d);
     31 	strncpy(&vendor[0], (char *)(&b), 4);
     32 	strncpy(&vendor[4], (char *)(&d), 4);
     33 	strncpy(&vendor[8], (char *)(&c), 4);
     34 	vendor[12] = '\0';
     35 
     36 	if (lvl >= 1) {
     37 		cpuid(1, &a, &b, &c, &d);
     38 
     39 		family = (a >> 8) & 0xf;  /* bits 11 - 8 */
     40 		model  = (a >> 4) & 0xf;  /* Bits  7 - 4 */
     41 		step   = a & 0xf;
     42 
     43 		/* extended family */
     44 		if (family == 0xf)
     45 			family += (a >> 20) & 0xff;
     46 
     47 		/* extended model */
     48 		if (family >= 0x6)
     49 			model += ((a >> 16) & 0xf) << 4;
     50 	}
     51 	nb = scnprintf(buffer, sz, "%s,%u,%u,%u$", vendor, family, model, step);
     52 
     53 	/* look for end marker to ensure the entire data fit */
     54 	if (strchr(buffer, '$')) {
     55 		buffer[nb-1] = '\0';
     56 		return 0;
     57 	}
     58 	return -1;
     59 }
     60