5 // Copyright (c) 2019 Apple Inc. All rights reserved.
17 typedef char *kobject_description_t
[512];
18 #include <mach/mach.h>
22 printf("usage: cpuctl [ list ]\n");
23 printf(" cpuctl { offline | online } <cpu> [ <cpu>... ]\n");
27 static void fetch_cpu_info(host_t
*priv_port
,
28 processor_port_array_t proc_ports
,
29 mach_msg_type_number_t proc_count
,
30 processor_basic_info_data_t
*cpus
)
32 for (int i
= 0; i
< proc_count
; i
++) {
33 mach_msg_type_number_t info_count
= PROCESSOR_BASIC_INFO_COUNT
;
35 if (processor_info(proc_ports
[i
], PROCESSOR_BASIC_INFO
, priv_port
,
36 (processor_info_t
)&cpus
[i
], &info_count
) != KERN_SUCCESS
) {
37 errx(EX_OSERR
, "processor_info(%d) failed", i
);
42 static int do_cmd_list(mach_msg_type_number_t proc_count
, processor_basic_info_data_t
*cpus
)
45 for (int i
= 0; i
< proc_count
; i
++) {
46 int lowest_slot
= INT_MAX
;
48 for (int j
= 0; j
< proc_count
; j
++) {
49 int slot
= cpus
[j
].slot_num
;
50 if (slot
> prev_lowest
&& slot
< lowest_slot
) {
56 errx(EX_OSERR
, "slot numbers are out of range");
58 processor_basic_info_data_t
*cpu
= &cpus
[lowest_idx
];
59 printf("CPU%d: %-7s type=%x,%x master=%d\n",
61 cpu
->running
? "online" : "offline",
66 prev_lowest
= lowest_slot
;
71 static int find_cpu_by_slot(mach_msg_type_number_t proc_count
,
72 processor_basic_info_data_t
*cpus
,
75 for (int i
= 0; i
< proc_count
; i
++) {
76 if (cpus
[i
].slot_num
== slot
)
82 int main(int argc
, char **argv
)
86 while ((opt
= getopt(argc
, argv
, "h")) != -1) {
94 if (host_get_host_priv_port(mach_host_self(), &priv_port
) != KERN_SUCCESS
)
95 errx(EX_OSERR
, "host_get_host_priv_port() failed");
97 processor_port_array_t proc_ports
;
98 mach_msg_type_number_t proc_count
;
99 if (host_processors(priv_port
, &proc_ports
, &proc_count
) != KERN_SUCCESS
)
100 errx(EX_OSERR
, "host_processors() failed");
102 processor_basic_info_data_t
*cpus
= calloc(proc_count
, sizeof(*cpus
));
104 errx(EX_OSERR
, "calloc() failed");
105 fetch_cpu_info(&priv_port
, proc_ports
, proc_count
, cpus
);
108 return do_cmd_list(proc_count
, cpus
);
110 const char *cmd
= argv
[optind
];
113 if (!strcmp(cmd
, "list"))
114 return do_cmd_list(proc_count
, cpus
);
117 if (!strncmp(cmd
, "off", 3))
119 else if (strncmp(cmd
, "on", 2))
126 for (; optind
< argc
; optind
++) {
128 int slot
= (int)strtoul(argv
[optind
], &endp
, 0);
132 int cpu
= find_cpu_by_slot(proc_count
, cpus
, slot
);
134 errx(EX_USAGE
, "Invalid CPU ID %d", slot
);
137 if (processor_start(proc_ports
[cpu
]) != KERN_SUCCESS
)
138 errx(EX_OSERR
, "processor_start(%u) failed", cpu
);
140 if (processor_exit(proc_ports
[cpu
]) != KERN_SUCCESS
)
141 errx(EX_OSERR
, "processor_exit(%u) failed", cpu
);