1 /*
2 * Copyright 2012, Haiku, Inc. All Rights Reserved.
3 *
4 * Distributed under the terms of the MIT License.
5 *
6 * Authors:
7 * Yongcong Du <ycdu.vmcore@gmail.com>
8 */
9
10
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14
15 #include <ACPI.h>
16 #include <Drivers.h>
17 #include <Errors.h>
18 #include <KernelExport.h>
19
20 #include <arch_system_info.h>
21 #include <cpu.h>
22 #include <cpuidle.h>
23 #include <smp.h>
24
25 #include "x86_cpuidle.h"
26
27
28 #define ACPI_PDC_REVID 0x1
29 #define ACPI_OSC_QUERY (1 << 0)
30
31 #define ACPI_PDC_P_FFH (1 << 0)
32 #define ACPI_PDC_C_C1_HALT (1 << 1)
33 #define ACPI_PDC_T_FFH (1 << 2)
34 #define ACPI_PDC_SMP_C1PT (1 << 3)
35 #define ACPI_PDC_SMP_C2C3 (1 << 4)
36 #define ACPI_PDC_SMP_P_SW (1 << 5)
37 #define ACPI_PDC_SMP_C_SW (1 << 6)
38 #define ACPI_PDC_SMP_T_SW (1 << 7)
39 #define ACPI_PDC_C_C1_FFH (1 << 8)
40 #define ACPI_PDC_C_C2C3_FFH (1 << 9)
41 #define ACPI_PDC_P_HWCOORD (1 << 11)
42
43 // Bus Master check required
44 #define ACPI_PDC_GAS_BM (1 << 1)
45
46 #define ACPI_CSTATE_HALT 0x1
47 #define ACPI_CSTATE_SYSIO 0x2
48 #define ACPI_CSTATE_FFH 0x3
49
50 // Bus Master Check
51 #define ACPI_FLAG_C_BM (1 << 0)
52 // Bus master arbitration
53 #define ACPI_FLAG_C_ARB (1 << 1)
54
55 // Copied from acpica's actypes.h, where's the best place to put?
56 #define ACPI_BITREG_BUS_MASTER_STATUS 0x01
57 #define ACPI_BITREG_BUS_MASTER_RLD 0x0F
58 #define ACPI_BITREG_ARB_DISABLE 0x13
59
60 #define ACPI_STATE_C0 (uint8) 0
61 #define ACPI_STATE_C1 (uint8) 1
62 #define ACPI_STATE_C2 (uint8) 2
63 #define ACPI_STATE_C3 (uint8) 3
64 #define ACPI_C_STATES_MAX ACPI_STATE_C3
65 #define ACPI_C_STATE_COUNT 4
66
67
68 #define ACPI_CPUIDLE_MODULE_NAME "drivers/power/x86_cpuidle/acpi/driver_v1"
69
70
71 struct acpicpu_reg {
72 uint8 reg_desc;
73 uint16 reg_reslen;
74 uint8 reg_spaceid;
75 uint8 reg_bitwidth;
76 uint8 reg_bitoffset;
77 uint8 reg_accesssize;
78 uint64 reg_addr;
79 } __attribute__((packed));
80
81 struct acpi_cpuidle_driver_info {
82 device_node *node;
83 acpi_device_module_info *acpi;
84 acpi_device acpi_cookie;
85 uint32 flags;
86 int32 cpuIndex;
87 };
88
89 struct acpi_cstate_info {
90 uint32 address;
91 uint8 skip_bm_sts;
92 uint8 method;
93 uint8 type;
94 };
95
96
97 static acpi_cpuidle_driver_info *sAcpiProcessor[SMP_MAX_CPUS];
98 static CpuidleDevice sAcpiDevice;
99 static device_manager_info *sDeviceManager;
100 static acpi_module_info *sAcpi;
101
102 CpuidleModuleInfo *gIdle;
103
104
105 static status_t
acpi_eval_pdc(acpi_cpuidle_driver_info * device)106 acpi_eval_pdc(acpi_cpuidle_driver_info *device)
107 {
108 acpi_objects arg;
109 acpi_object_type obj;
110 uint32 cap[3];
111
112 arg.count = 1;
113 arg.pointer = &obj;
114 cap[0] = 1;
115 cap[1] = 1;
116 cap[2] = ACPI_PDC_C_C1_HALT | ACPI_PDC_SMP_C1PT | ACPI_PDC_SMP_C2C3;
117 cap[2] |= ACPI_PDC_SMP_P_SW | ACPI_PDC_SMP_C_SW | ACPI_PDC_SMP_T_SW;
118 cap[2] |= ACPI_PDC_C_C1_FFH | ACPI_PDC_C_C2C3_FFH;
119 cap[2] |= ACPI_PDC_SMP_T_SW | ACPI_PDC_P_FFH | ACPI_PDC_P_HWCOORD
120 | ACPI_PDC_T_FFH;
121 obj.object_type = ACPI_TYPE_BUFFER;
122 obj.data.buffer.length = sizeof(cap);
123 obj.data.buffer.buffer = cap;
124 status_t status = device->acpi->evaluate_method(device->acpi_cookie, "_PDC",
125 &arg, NULL);
126 return status;
127 }
128
129
130 static status_t
acpi_eval_osc(acpi_cpuidle_driver_info * device)131 acpi_eval_osc(acpi_cpuidle_driver_info *device)
132 {
133 // guid for intel platform
134 dprintf("%s@%p\n", __func__, device->acpi_cookie);
135 static uint8 uuid[] = {
136 0x16, 0xA6, 0x77, 0x40, 0x0C, 0x29, 0xBE, 0x47,
137 0x9E, 0xBD, 0xD8, 0x70, 0x58, 0x71, 0x39, 0x53
138 };
139 uint32 cap[2];
140 cap[0] = 0;
141 cap[1] = ACPI_PDC_C_C1_HALT | ACPI_PDC_SMP_C1PT | ACPI_PDC_SMP_C2C3;
142 cap[1] |= ACPI_PDC_SMP_P_SW | ACPI_PDC_SMP_C_SW | ACPI_PDC_SMP_T_SW;
143 cap[1] |= ACPI_PDC_C_C1_FFH | ACPI_PDC_C_C2C3_FFH;
144 cap[1] |= ACPI_PDC_SMP_T_SW | ACPI_PDC_P_FFH | ACPI_PDC_P_HWCOORD
145 | ACPI_PDC_T_FFH;
146
147 acpi_objects arg;
148 acpi_object_type obj[4];
149
150 arg.count = 4;
151 arg.pointer = obj;
152
153 obj[0].object_type = ACPI_TYPE_BUFFER;
154 obj[0].data.buffer.length = sizeof(uuid);
155 obj[0].data.buffer.buffer = uuid;
156 obj[1].object_type = ACPI_TYPE_INTEGER;
157 obj[1].data.integer = ACPI_PDC_REVID;
158 obj[2].object_type = ACPI_TYPE_INTEGER;
159 obj[2].data.integer = sizeof(cap)/sizeof(cap[0]);
160 obj[3].object_type = ACPI_TYPE_BUFFER;
161 obj[3].data.buffer.length = sizeof(cap);
162 obj[3].data.buffer.buffer = (void *)cap;
163
164 acpi_data buf;
165 buf.pointer = NULL;
166 buf.length = ACPI_ALLOCATE_LOCAL_BUFFER;
167 status_t status = device->acpi->evaluate_method(device->acpi_cookie, "_OSC",
168 &arg, &buf);
169 if (status != B_OK)
170 return status;
171 acpi_object_type *osc = (acpi_object_type *)buf.pointer;
172 if (osc->object_type != ACPI_TYPE_BUFFER)
173 return B_BAD_TYPE;
174 if (osc->data.buffer.length != sizeof(cap))
175 return B_BUFFER_OVERFLOW;
176 return status;
177 }
178
179
180 static inline bool
acpi_cstate_bm_check(void)181 acpi_cstate_bm_check(void)
182 {
183 uint32 val;
184 sAcpi->read_bit_register(ACPI_BITREG_BUS_MASTER_STATUS, &val);
185 if (!val)
186 return false;
187 sAcpi->write_bit_register(ACPI_BITREG_BUS_MASTER_STATUS, 1);
188
189 return true;
190 }
191
192
193 static inline void
acpi_cstate_ffh_enter(CpuidleCstate * cState)194 acpi_cstate_ffh_enter(CpuidleCstate *cState)
195 {
196 cpu_ent *cpu = get_cpu_struct();
197 if (cpu->invoke_scheduler)
198 return;
199
200 x86_monitor((void *)&cpu->invoke_scheduler, 0, 0);
201 if (!cpu->invoke_scheduler)
202 x86_mwait((unsigned long)cState->pData, 1);
203 }
204
205
206 static inline void
acpi_cstate_halt(void)207 acpi_cstate_halt(void)
208 {
209 cpu_ent *cpu = get_cpu_struct();
210 if (cpu->invoke_scheduler)
211 return;
212 asm("hlt");
213 }
214
215
216 static void
acpi_cstate_enter(CpuidleCstate * cState)217 acpi_cstate_enter(CpuidleCstate *cState)
218 {
219 acpi_cstate_info *ci = (acpi_cstate_info *)cState->pData;
220 if (ci->method == ACPI_CSTATE_FFH)
221 acpi_cstate_ffh_enter(cState);
222 else if (ci->method == ACPI_CSTATE_SYSIO)
223 in8(ci->address);
224 else
225 acpi_cstate_halt();
226 }
227
228
229 static int32
acpi_cstate_idle(int32 state,CpuidleDevice * device)230 acpi_cstate_idle(int32 state, CpuidleDevice *device)
231 {
232 CpuidleCstate *cState = &device->cStates[state];
233 acpi_cstate_info *ci = (acpi_cstate_info *)cState->pData;
234 if (!ci->skip_bm_sts) {
235 // we fall back to C1 if there's bus master activity
236 if (acpi_cstate_bm_check())
237 state = 1;
238 }
239 if (ci->type != ACPI_STATE_C3)
240 acpi_cstate_enter(cState);
241
242 // set BM_RLD for Bus Master to activity to wake the system from C3
243 // With Newer chipsets BM_RLD is a NOP Since DMA is automatically handled
244 // during C3 State
245 acpi_cpuidle_driver_info *pi = sAcpiProcessor[smp_get_current_cpu()];
246 if (pi->flags & ACPI_FLAG_C_BM)
247 sAcpi->write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
248
249 // disable bus master arbitration during C3
250 if (pi->flags & ACPI_FLAG_C_ARB)
251 sAcpi->write_bit_register(ACPI_BITREG_ARB_DISABLE, 1);
252
253 acpi_cstate_enter(cState);
254
255 // clear BM_RLD and re-enable the arbiter
256 if (pi->flags & ACPI_FLAG_C_BM)
257 sAcpi->write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
258
259 if (pi->flags & ACPI_FLAG_C_ARB)
260 sAcpi->write_bit_register(ACPI_BITREG_ARB_DISABLE, 0);
261
262 return state;
263 }
264
265
266 static status_t
acpi_cstate_add(acpi_object_type * object,CpuidleCstate * cState)267 acpi_cstate_add(acpi_object_type *object, CpuidleCstate *cState)
268 {
269 acpi_cstate_info *ci = (acpi_cstate_info *)malloc(sizeof(acpi_cstate_info));
270 if (!ci)
271 return B_NO_MEMORY;
272
273 if (object->object_type != ACPI_TYPE_PACKAGE) {
274 dprintf("invalid _CST object\n");
275 goto error;
276 }
277
278 if (object->data.package.count != 4) {
279 dprintf("invalid _CST number\n");
280 goto error;
281 }
282
283 // type
284 acpi_object_type * pointer = &object->data.package.objects[1];
285 if (pointer->object_type != ACPI_TYPE_INTEGER) {
286 dprintf("invalid _CST elem type\n");
287 goto error;
288 }
289 uint32 n = pointer->data.integer;
290 if (n < 1 || n > 3) {
291 dprintf("invalid _CST elem value\n");
292 goto error;
293 }
294 ci->type = n;
295 dprintf("C%" B_PRId32 "\n", n);
296 snprintf(cState->name, sizeof(cState->name), "C%" B_PRId32, n);
297
298 // Latency
299 pointer = &object->data.package.objects[2];
300 if (pointer->object_type != ACPI_TYPE_INTEGER) {
301 dprintf("invalid _CST elem type\n");
302 goto error;
303 }
304 n = pointer->data.integer;
305 cState->latency = n;
306 dprintf("Latency: %" B_PRId32 "\n", n);
307
308 // power
309 pointer = &object->data.package.objects[3];
310 if (pointer->object_type != ACPI_TYPE_INTEGER) {
311 dprintf("invalid _CST elem type\n");
312 goto error;
313 }
314 n = pointer->data.integer;
315 dprintf("power: %" B_PRId32 "\n", n);
316
317 // register
318 pointer = &object->data.package.objects[0];
319 if (pointer->object_type != ACPI_TYPE_BUFFER) {
320 dprintf("invalid _CST elem type\n");
321 goto error;
322 }
323 if (pointer->data.buffer.length < 15) {
324 dprintf("invalid _CST elem length\n");
325 goto error;
326 }
327
328 struct acpicpu_reg *reg = (struct acpicpu_reg *)pointer->data.buffer.buffer;
329 switch (reg->reg_spaceid) {
330 case ACPI_ADR_SPACE_SYSTEM_IO:
331 dprintf("IO method\n");
332 if (reg->reg_addr == 0) {
333 dprintf("illegal address\n");
334 goto error;
335 }
336 if (reg->reg_bitwidth != 8) {
337 dprintf("invalid source length\n");
338 goto error;
339 }
340 ci->address = reg->reg_addr;
341 ci->method = ACPI_CSTATE_SYSIO;
342 break;
343 case ACPI_ADR_SPACE_FIXED_HARDWARE:
344 {
345 dprintf("FFH method\n");
346 ci->method = ACPI_CSTATE_FFH;
347 ci->address = reg->reg_addr;
348
349 // skip checking BM_STS if ACPI_PDC_GAS_BM is cleared
350 cpu_ent *cpu = get_cpu_struct();
351 if ((cpu->arch.vendor == VENDOR_INTEL) &&
352 !(reg->reg_accesssize & ACPI_PDC_GAS_BM))
353 ci->skip_bm_sts = 1;
354 break;
355 }
356 default:
357 dprintf("invalid spaceid %" B_PRId8 "\n", reg->reg_spaceid);
358 break;
359 }
360 cState->pData = ci;
361 cState->EnterIdle = acpi_cstate_idle;
362
363 return B_OK;
364 error:
365 free(ci);
366 return B_ERROR;
367 }
368
369
370 static void
acpi_cstate_quirks(acpi_cpuidle_driver_info * device)371 acpi_cstate_quirks(acpi_cpuidle_driver_info *device)
372 {
373 cpu_ent *cpu = get_cpu_struct();
374 // Calculated Model Value: M = (Extended Model << 4) + Model
375 uint32 model = (cpu->arch.extended_model << 4) + cpu->arch.model;
376
377 // On all recent Intel platforms, ARB_DIS is not necessary
378 if (cpu->arch.vendor != VENDOR_INTEL)
379 return;
380 if (cpu->arch.family > 0xf || (cpu->arch.family == 6 && model >= 0xf))
381 device->flags &= ~ACPI_FLAG_C_ARB;
382 }
383
384
385 static status_t
acpi_cpuidle_setup(acpi_cpuidle_driver_info * device)386 acpi_cpuidle_setup(acpi_cpuidle_driver_info *device)
387 {
388 // _PDC is deprecated in the ACPI 3.0, we will try _OSC firstly
389 // and fall back to _PDC if _OSC fail
390 status_t status = acpi_eval_osc(device);
391 if (status != B_OK)
392 status = acpi_eval_pdc(device);
393 if (status != B_OK) {
394 dprintf("failed to eval _OSC and _PDC\n");
395 return status;
396 }
397
398 acpi_data buffer;
399 buffer.pointer = NULL;
400 buffer.length = ACPI_ALLOCATE_BUFFER;
401
402 dprintf("evaluate _CST @%p\n", device->acpi_cookie);
403 status = device->acpi->evaluate_method(device->acpi_cookie, "_CST", NULL,
404 &buffer);
405 if (status != B_OK) {
406 dprintf("failed to get _CST\n");
407 return B_IO_ERROR;
408 }
409
410 acpi_object_type *object = (acpi_object_type *)buffer.pointer;
411 if (object->object_type != ACPI_TYPE_PACKAGE)
412 dprintf("invalid _CST type\n");
413 if (object->data.package.count < 2)
414 dprintf("invalid _CST count\n");
415
416 acpi_object_type *pointer = object->data.package.objects;
417 if (pointer[0].object_type != ACPI_TYPE_INTEGER)
418 dprintf("invalid _CST type 2\n");
419 uint32 n = pointer[0].data.integer;
420 if (n != object->data.package.count - 1)
421 dprintf("invalid _CST count 2\n");
422 if (n > 8)
423 dprintf("_CST has too many states\n");
424 dprintf("cpuidle found %" B_PRId32 " cstates\n", n);
425 uint32 count = 1;
426 for (uint32 i = 1; i <= n; i++) {
427 pointer = &object->data.package.objects[i];
428 if (acpi_cstate_add(pointer, &sAcpiDevice.cStates[count]) == B_OK)
429 ++count;
430 }
431 sAcpiDevice.cStateCount = count;
432 free(buffer.pointer);
433
434 // TODO we assume BM is a must and ARB_DIS is always available
435 device->flags |= ACPI_FLAG_C_ARB | ACPI_FLAG_C_BM;
436
437 acpi_cstate_quirks(device);
438
439 return B_OK;
440 }
441
442
443 static status_t
acpi_cpuidle_init(void)444 acpi_cpuidle_init(void)
445 {
446 dprintf("acpi_cpuidle_init\n");
447
448 for (int32 i = 0; i < smp_get_num_cpus(); i++)
449 if (acpi_cpuidle_setup(sAcpiProcessor[i]) != B_OK)
450 return B_ERROR;
451
452 status_t status = gIdle->AddDevice(&sAcpiDevice);
453 if (status == B_OK)
454 dprintf("using acpi idle\n");
455 return status;
456 }
457
458
459 static status_t
acpi_processor_init(acpi_cpuidle_driver_info * device)460 acpi_processor_init(acpi_cpuidle_driver_info *device)
461 {
462 // get the CPU index
463 dprintf("get acpi processor @%p\n", device->acpi_cookie);
464
465 acpi_data buffer;
466 buffer.pointer = NULL;
467 buffer.length = ACPI_ALLOCATE_BUFFER;
468 status_t status = device->acpi->evaluate_method(device->acpi_cookie, NULL,
469 NULL, &buffer);
470 if (status != B_OK) {
471 dprintf("failed to get processor obj\n");
472 return status;
473 }
474
475 acpi_object_type *object = (acpi_object_type *)buffer.pointer;
476 dprintf("acpi cpu%" B_PRId32 ": P_BLK at %#x/%lu\n",
477 object->data.processor.cpu_id,
478 object->data.processor.pblk_address,
479 object->data.processor.pblk_length);
480
481 int32 cpuIndex = object->data.processor.cpu_id;
482 free(buffer.pointer);
483
484 if (cpuIndex < 0 || cpuIndex >= smp_get_num_cpus())
485 return B_ERROR;
486
487 device->cpuIndex = cpuIndex;
488 sAcpiProcessor[cpuIndex] = device;
489
490 // If nodes for all processors have been registered, init the idle callback.
491 for (int32 i = smp_get_num_cpus() - 1; i >= 0; i--) {
492 if (sAcpiProcessor[i] == NULL)
493 return B_OK;
494 }
495
496 if (intel_cpuidle_init() == B_OK)
497 return B_OK;
498
499 status = acpi_cpuidle_init();
500 if (status != B_OK)
501 sAcpiProcessor[cpuIndex] = NULL;
502
503 return status;
504 }
505
506
507 static float
acpi_cpuidle_support(device_node * parent)508 acpi_cpuidle_support(device_node *parent)
509 {
510 const char *bus;
511 uint32 device_type;
512
513 dprintf("acpi_cpuidle_support\n");
514 // make sure parent is really the ACPI bus manager
515 if (sDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false))
516 return -1;
517
518 if (strcmp(bus, "acpi") != 0)
519 return 0.0;
520
521 // check whether it's really a cpu Device
522 if (sDeviceManager->get_attr_uint32(parent, ACPI_DEVICE_TYPE_ITEM,
523 &device_type, false) != B_OK
524 || device_type != ACPI_TYPE_PROCESSOR) {
525 return 0.0;
526 }
527
528 return 0.6;
529 }
530
531
532 static status_t
acpi_cpuidle_register_device(device_node * node)533 acpi_cpuidle_register_device(device_node *node)
534 {
535 device_attr attrs[] = {
536 { B_DEVICE_PRETTY_NAME, B_STRING_TYPE, { .string = "ACPI CPU IDLE" }},
537 { NULL }
538 };
539
540 dprintf("acpi_cpuidle_register_device\n");
541 return sDeviceManager->register_node(node, ACPI_CPUIDLE_MODULE_NAME, attrs,
542 NULL, NULL);
543 }
544
545
546 static status_t
acpi_cpuidle_init_driver(device_node * node,void ** driverCookie)547 acpi_cpuidle_init_driver(device_node *node, void **driverCookie)
548 {
549 dprintf("acpi_cpuidle_init_driver\n");
550 acpi_cpuidle_driver_info *device;
551 device = (acpi_cpuidle_driver_info *)calloc(1, sizeof(*device));
552 if (device == NULL)
553 return B_NO_MEMORY;
554
555 device->node = node;
556
557 device_node *parent;
558 parent = sDeviceManager->get_parent_node(node);
559 sDeviceManager->get_driver(parent, (driver_module_info **)&device->acpi,
560 (void **)&device->acpi_cookie);
561 sDeviceManager->put_node(parent);
562
563 status_t status = acpi_processor_init(device);
564 if (status != B_OK) {
565 free(device);
566 return status;
567 }
568
569 *driverCookie = device;
570 return B_OK;
571 }
572
573
574 static void
acpi_cpuidle_uninit_driver(void * driverCookie)575 acpi_cpuidle_uninit_driver(void *driverCookie)
576 {
577 dprintf("acpi_cpuidle_uninit_driver");
578 acpi_cpuidle_driver_info *device = (acpi_cpuidle_driver_info *)driverCookie;
579 // TODO: When the first device to be unregistered, we'd need to balance the
580 // gIdle->AddDevice() call, but ATM isn't any API for that.
581 sAcpiProcessor[device->cpuIndex] = NULL;
582 free(device);
583 }
584
585
586 module_dependency module_dependencies[] = {
587 { B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&sDeviceManager },
588 { B_ACPI_MODULE_NAME, (module_info **)&sAcpi},
589 { B_CPUIDLE_MODULE_NAME, (module_info **)&gIdle },
590 {}
591 };
592
593
594 static driver_module_info sAcpiidleModule = {
595 {
596 ACPI_CPUIDLE_MODULE_NAME,
597 0,
598 NULL
599 },
600
601 acpi_cpuidle_support,
602 acpi_cpuidle_register_device,
603 acpi_cpuidle_init_driver,
604 acpi_cpuidle_uninit_driver,
605 NULL,
606 NULL, // rescan
607 NULL, // removed
608 };
609
610
611 module_info *modules[] = {
612 (module_info *)&sAcpiidleModule,
613 NULL
614 };
615