1 /*
2 * Licensed under the terms of the GNU GPL License version 2.
3 *
4 * FreeBSD Routines for retrieving cpuid registers.
5 * Originally submitted by Stanislav Sedov <stas@FreeBSD.org>
6 */
7
8 #if defined(__FreeBSD__) || defined(__DragonFly__)
9 #include <sys/types.h>
10 #include <sys/param.h>
11 #include <sys/fcntl.h>
12 #include <sys/ioctl.h>
13 #include <sys/cpuctl.h>
14 #ifdef __DragonFly__
15 #include <sched.h>
16 #include <string.h>
17 #else
18 #include <sys/cpuset.h>
19 #endif
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <unistd.h>
23
24 #include <x86info.h>
25
26 #ifdef __DragonFly__
bind_cpu(unsigned int cpunr)27 void bind_cpu(unsigned int cpunr)
28 {
29 int ret;
30 cpu_set_t set;
31 cpu_set_t tmp_set;
32
33 ret = sched_getaffinity(getpid(), sizeof(set), &set);
34 if (ret)
35 return;
36
37 memcpy(&tmp_set, &set, sizeof(cpu_set_t));
38 CPU_ZERO(&set);
39 CPU_SET(cpunr, &set);
40 sched_setaffinity(getpid(), sizeof(set), &set);
41 return;
42 }
43 #else
bind_cpu(unsigned int cpunr)44 void bind_cpu(unsigned int cpunr)
45 {
46 cpuset_t mask;
47
48 CPU_ZERO(&mask);
49 CPU_SET(cpunr, &mask);
50 (void) cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1,
51 sizeof(mask), &mask);
52 }
53 #endif
54
55 static const char *NATIVE_CPUID_FAILED_MSG = "WARNING: Native cpuid failed\n";
56
cpuid(unsigned int CPU_number,unsigned long long idx,unsigned int * eax,unsigned int * ebx,unsigned int * ecx,unsigned int * edx)57 void cpuid(unsigned int CPU_number, unsigned long long idx,
58 unsigned int *eax,
59 unsigned int *ebx,
60 unsigned int *ecx,
61 unsigned int *edx)
62 {
63 static int nodriver=0;
64 char cpuname[20];
65 int fh;
66 cpuctl_cpuid_count_args_t args;
67
68 if (nodriver == 1) {
69 if (native_cpuid(CPU_number, idx, eax,ebx,ecx,edx))
70 printf("%s", NATIVE_CPUID_FAILED_MSG);
71 return;
72 }
73
74 args.level = idx;
75 args.level_type = idx >> 32;
76 /* Ok, use the /dev/CPU interface in preference to the _up code. */
77 (void)snprintf(cpuname, sizeof(cpuname), "/dev/cpuctl%u", CPU_number);
78 fh = open(cpuname, O_RDONLY);
79 if (fh != -1) {
80 if (ioctl(fh, CPUCTL_CPUID_COUNT, &args) != 0) {
81 perror(cpuname);
82 exit(EXIT_FAILURE);
83 }
84 if (eax!=0) *eax = args.data[0];
85 if (ebx!=0) *ebx = args.data[1];
86 if (ecx!=0) *ecx = args.data[2];
87 if (edx!=0) *edx = args.data[3];
88 #ifdef __DragonFly__
89 close(fh);
90 #else
91 if (close(fh) == -1) {
92 perror("close");
93 exit(EXIT_FAILURE);
94 }
95 #endif
96 } else {
97 /* Something went wrong, just do UP and hope for the best. */
98 nodriver = 1;
99 if (nrCPUs != 1)
100 perror(cpuname);
101 if (native_cpuid(CPU_number, idx, eax,ebx,ecx,edx))
102 printf("%s", NATIVE_CPUID_FAILED_MSG);
103
104 return;
105 }
106 }
107
108 #endif /* __FreeBSD__ */
109