]>
Commit | Line | Data |
---|---|---|
5ba3f43e A |
1 | /* |
2 | * Copyright (c) 2003-2007 Apple Inc. All rights reserved. | |
3 | */ | |
4 | #include <sys/param.h> | |
5 | #include <sys/kernel.h> | |
6 | #include <sys/sysctl.h> | |
7 | ||
8 | #include <machine/machine_routines.h> | |
9 | ||
d9a64523 A |
10 | #include <mach/host_info.h> |
11 | #include <mach/mach_host.h> | |
12 | #include <arm/cpuid.h> | |
13 | #include <libkern/libkern.h> | |
14 | ||
5ba3f43e A |
15 | extern uint64_t wake_abstime; |
16 | ||
17 | static | |
18 | SYSCTL_QUAD(_machdep, OID_AUTO, wake_abstime, | |
19 | CTLFLAG_RD, &wake_abstime, | |
20 | "Absolute Time at the last wakeup"); | |
21 | ||
22 | static int | |
23 | sysctl_time_since_reset SYSCTL_HANDLER_ARGS | |
24 | { | |
25 | #pragma unused(arg1, arg2, oidp) | |
26 | int error = 0; | |
27 | uint64_t return_value = 0; | |
28 | ||
29 | return_value = ml_get_time_since_reset(); | |
30 | ||
31 | SYSCTL_OUT(req, &return_value, sizeof(return_value)); | |
32 | ||
33 | return error; | |
34 | } | |
35 | ||
36 | SYSCTL_PROC(_machdep, OID_AUTO, time_since_reset, | |
37 | CTLFLAG_RD | CTLTYPE_QUAD | CTLFLAG_LOCKED, | |
38 | 0, 0, sysctl_time_since_reset, "I", | |
39 | "Continuous time since last SOC boot/wake started"); | |
40 | ||
41 | static int | |
42 | sysctl_wake_conttime SYSCTL_HANDLER_ARGS | |
43 | { | |
44 | #pragma unused(arg1, arg2, oidp) | |
45 | int error = 0; | |
46 | uint64_t return_value = 0; | |
47 | ||
48 | return_value = ml_get_conttime_wake_time(); | |
49 | ||
50 | SYSCTL_OUT(req, &return_value, sizeof(return_value)); | |
51 | ||
52 | return error; | |
53 | } | |
54 | ||
55 | SYSCTL_PROC(_machdep, OID_AUTO, wake_conttime, | |
56 | CTLFLAG_RD | CTLTYPE_QUAD | CTLFLAG_LOCKED, | |
57 | 0, 0, sysctl_wake_conttime, "I", | |
58 | "Continuous Time at the last wakeup"); | |
59 | ||
60 | ||
d9a64523 A |
61 | /* |
62 | * For source compatibility, here's some machdep.cpu mibs that | |
63 | * use host_info() to simulate reasonable answers. | |
64 | */ | |
65 | ||
66 | SYSCTL_NODE(_machdep, OID_AUTO, cpu, CTLFLAG_RW|CTLFLAG_LOCKED, 0, | |
67 | "CPU info"); | |
68 | ||
69 | static int | |
70 | arm_host_info SYSCTL_HANDLER_ARGS | |
71 | { | |
72 | __unused struct sysctl_oid *unused_oidp = oidp; | |
73 | ||
74 | host_basic_info_data_t hinfo; | |
75 | mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT; | |
76 | #define BSD_HOST 1 | |
77 | kern_return_t kret = host_info((host_t)BSD_HOST, | |
78 | HOST_BASIC_INFO, (host_info_t)&hinfo, &count); | |
79 | if (KERN_SUCCESS != kret) | |
80 | return (EINVAL); | |
81 | ||
82 | if (sizeof (uint32_t) != arg2) | |
83 | panic("size mismatch"); | |
84 | ||
85 | uintptr_t woffset = (uintptr_t)arg1 / sizeof (uint32_t); | |
86 | uint32_t datum = *(uint32_t *)(((uint32_t *)&hinfo) + woffset); | |
87 | return (SYSCTL_OUT(req, &datum, sizeof (datum))); | |
88 | } | |
89 | ||
90 | /* | |
91 | * machdep.cpu.cores_per_package | |
92 | * | |
93 | * x86: derived from CPUID data. | |
94 | * ARM: how many physical cores we have in the AP; aka hw.physicalcpu_max | |
95 | */ | |
96 | static | |
97 | SYSCTL_PROC(_machdep_cpu, OID_AUTO, cores_per_package, | |
98 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, | |
99 | (void *)offsetof(host_basic_info_data_t, physical_cpu_max), | |
100 | sizeof (integer_t), | |
101 | arm_host_info, "I", "CPU cores per package"); | |
102 | ||
103 | /* | |
104 | * machdep.cpu.core_count | |
105 | * | |
106 | * x86: derived from CPUID data. | |
107 | * ARM: # active physical cores in the AP; aka hw.physicalcpu | |
108 | */ | |
109 | static | |
110 | SYSCTL_PROC(_machdep_cpu, OID_AUTO, core_count, | |
111 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, | |
112 | (void *)offsetof(host_basic_info_data_t, physical_cpu), | |
113 | sizeof (integer_t), | |
114 | arm_host_info, "I", "Number of enabled cores per package"); | |
115 | ||
116 | /* | |
117 | * machdep.cpu.logical_per_package | |
118 | * | |
119 | * x86: derived from CPUID data. Returns ENOENT if HTT bit not set, but | |
120 | * most x64 CPUs have that, so assume it's available. | |
121 | * ARM: total # logical cores in the AP; aka hw.logicalcpu_max | |
122 | */ | |
123 | static | |
124 | SYSCTL_PROC(_machdep_cpu, OID_AUTO, logical_per_package, | |
125 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, | |
126 | (void *)offsetof(host_basic_info_data_t, logical_cpu_max), | |
127 | sizeof (integer_t), | |
128 | arm_host_info, "I", "CPU logical cpus per package"); | |
129 | ||
130 | /* | |
131 | * machdep.cpu.thread_count | |
132 | * | |
133 | * x86: derived from CPUID data. | |
134 | * ARM: # active logical cores in the AP; aka hw.logicalcpu | |
135 | */ | |
136 | static | |
137 | SYSCTL_PROC(_machdep_cpu, OID_AUTO, thread_count, | |
138 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, | |
139 | (void *)offsetof(host_basic_info_data_t, logical_cpu), | |
140 | sizeof (integer_t), | |
141 | arm_host_info, "I", "Number of enabled threads per package"); | |
142 | ||
143 | /* | |
144 | * machdep.cpu.brand_string | |
145 | * | |
146 | * x86: derived from CPUID data. | |
147 | * ARM: cons something up from the CPUID register. Could include cpufamily | |
148 | * here and map it to a "marketing" name, but there's no obvious need; | |
149 | * the value is already exported via the commpage. So keep it simple. | |
150 | */ | |
151 | static int | |
152 | make_brand_string SYSCTL_HANDLER_ARGS | |
153 | { | |
154 | __unused struct sysctl_oid *unused_oidp = oidp; | |
155 | __unused void *unused_arg1 = arg1; | |
156 | __unused int unused_arg2 = arg2; | |
157 | ||
158 | const char *impl; | |
159 | ||
160 | switch (cpuid_info()->arm_info.arm_implementor) { | |
161 | case CPU_VID_APPLE: | |
162 | impl = "Apple"; | |
163 | break; | |
164 | case CPU_VID_ARM: | |
165 | impl = "ARM"; | |
166 | break; | |
167 | default: | |
168 | impl = "ARM architecture"; | |
169 | break; | |
170 | } | |
171 | char buf[80]; | |
172 | snprintf(buf, sizeof (buf), "%s processor", impl); | |
173 | return (SYSCTL_OUT(req, buf, strlen(buf) + 1)); | |
174 | } | |
175 | ||
176 | SYSCTL_PROC(_machdep_cpu, OID_AUTO, brand_string, | |
177 | CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_LOCKED, | |
178 | 0, 0, make_brand_string, "A", "CPU brand string"); |