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[B_MAX_CPU_COUNT]; 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 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 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 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 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 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 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 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 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 return B_ERROR; 276 } 277 278 if (object->data.package.count != 4) { 279 dprintf("invalid _CST number\n"); 280 return B_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 return B_ERROR; 288 } 289 uint32 n = pointer->data.integer; 290 if (n < 1 || n > 3) { 291 dprintf("invalid _CST elem value\n"); 292 return B_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 return B_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 return B_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 return B_ERROR; 322 } 323 if (pointer->data.buffer.length < 15) { 324 dprintf("invalid _CST elem length\n"); 325 return B_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 return B_ERROR; 335 } 336 if (reg->reg_bitwidth != 8) { 337 dprintf("invalid source length\n"); 338 return B_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 } 365 366 367 static void 368 acpi_cstate_quirks(acpi_cpuidle_driver_info *device) 369 { 370 cpu_ent *cpu = get_cpu_struct(); 371 // Calculated Model Value: M = (Extended Model << 4) + Model 372 uint32 model = (cpu->arch.extended_model << 4) + cpu->arch.model; 373 374 // On all recent Intel platforms, ARB_DIS is not necessary 375 if (cpu->arch.vendor != VENDOR_INTEL) 376 return; 377 if (cpu->arch.family > 0xf || (cpu->arch.family == 6 && model >= 0xf)) 378 device->flags &= ~ACPI_FLAG_C_ARB; 379 } 380 381 382 static status_t 383 acpi_cpuidle_setup(acpi_cpuidle_driver_info *device) 384 { 385 // _PDC is deprecated in the ACPI 3.0, we will try _OSC firstly 386 // and fall back to _PDC if _OSC fail 387 status_t status = acpi_eval_osc(device); 388 if (status != B_OK) 389 status = acpi_eval_pdc(device); 390 if (status != B_OK) { 391 dprintf("failed to eval _OSC and _PDC\n"); 392 return status; 393 } 394 395 acpi_data buffer; 396 buffer.pointer = NULL; 397 buffer.length = ACPI_ALLOCATE_BUFFER; 398 399 dprintf("evaluate _CST @%p\n", device->acpi_cookie); 400 status = device->acpi->evaluate_method(device->acpi_cookie, "_CST", NULL, 401 &buffer); 402 if (status != B_OK) { 403 dprintf("failed to get _CST\n"); 404 return B_IO_ERROR; 405 } 406 407 acpi_object_type *object = (acpi_object_type *)buffer.pointer; 408 if (object->object_type != ACPI_TYPE_PACKAGE) 409 dprintf("invalid _CST type\n"); 410 if (object->data.package.count < 2) 411 dprintf("invalid _CST count\n"); 412 413 acpi_object_type *pointer = object->data.package.objects; 414 if (pointer[0].object_type != ACPI_TYPE_INTEGER) 415 dprintf("invalid _CST type 2\n"); 416 uint32 n = pointer[0].data.integer; 417 if (n != object->data.package.count - 1) 418 dprintf("invalid _CST count 2\n"); 419 if (n > 8) 420 dprintf("_CST has too many states\n"); 421 dprintf("cpuidle found %" B_PRId32 " cstates\n", n); 422 uint32 count = 1; 423 for (uint32 i = 1; i <= n; i++) { 424 pointer = &object->data.package.objects[i]; 425 if (acpi_cstate_add(pointer, &sAcpiDevice.cStates[count]) == B_OK) 426 ++count; 427 } 428 sAcpiDevice.cStateCount = count; 429 free(buffer.pointer); 430 431 // TODO we assume BM is a must and ARB_DIS is always available 432 device->flags |= ACPI_FLAG_C_ARB | ACPI_FLAG_C_BM; 433 434 acpi_cstate_quirks(device); 435 436 return B_OK; 437 } 438 439 440 static status_t 441 acpi_cpuidle_init(void) 442 { 443 dprintf("acpi_cpuidle_init\n"); 444 445 for (int32 i = 0; i < smp_get_num_cpus(); i++) 446 if (acpi_cpuidle_setup(sAcpiProcessor[i]) != B_OK) 447 return B_ERROR; 448 449 status_t status = gIdle->AddDevice(&sAcpiDevice); 450 if (status == B_OK) 451 dprintf("using acpi idle\n"); 452 return status; 453 } 454 455 456 static status_t 457 acpi_processor_init(acpi_cpuidle_driver_info *device) 458 { 459 // get the CPU index 460 dprintf("get acpi processor @%p\n", device->acpi_cookie); 461 462 acpi_data buffer; 463 buffer.pointer = NULL; 464 buffer.length = ACPI_ALLOCATE_BUFFER; 465 status_t status = device->acpi->evaluate_method(device->acpi_cookie, NULL, 466 NULL, &buffer); 467 if (status != B_OK) { 468 dprintf("failed to get processor obj\n"); 469 return status; 470 } 471 472 acpi_object_type *object = (acpi_object_type *)buffer.pointer; 473 dprintf("acpi cpu%" B_PRId32 ": P_BLK at %#x/%lu\n", 474 object->data.processor.cpu_id, 475 object->data.processor.pblk_address, 476 object->data.processor.pblk_length); 477 478 int32 cpuIndex = object->data.processor.cpu_id; 479 free(buffer.pointer); 480 481 if (cpuIndex < 0 || cpuIndex >= smp_get_num_cpus()) 482 return B_ERROR; 483 484 device->cpuIndex = cpuIndex; 485 sAcpiProcessor[cpuIndex] = device; 486 487 // If nodes for all processors have been registered, init the idle callback. 488 for (int32 i = smp_get_num_cpus() - 1; i >= 0; i--) { 489 if (sAcpiProcessor[i] == NULL) 490 return B_OK; 491 } 492 493 if (intel_cpuidle_init() == B_OK) 494 return B_OK; 495 496 status = acpi_cpuidle_init(); 497 if (status != B_OK) 498 sAcpiProcessor[cpuIndex] = NULL; 499 500 return status; 501 } 502 503 504 static float 505 acpi_cpuidle_support(device_node *parent) 506 { 507 const char *bus; 508 uint32 device_type; 509 510 dprintf("acpi_cpuidle_support\n"); 511 // make sure parent is really the ACPI bus manager 512 if (sDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false)) 513 return -1; 514 515 if (strcmp(bus, "acpi") != 0) 516 return 0.0; 517 518 // check whether it's really a cpu Device 519 if (sDeviceManager->get_attr_uint32(parent, ACPI_DEVICE_TYPE_ITEM, 520 &device_type, false) != B_OK 521 || device_type != ACPI_TYPE_PROCESSOR) { 522 return 0.0; 523 } 524 525 return 0.6; 526 } 527 528 529 static status_t 530 acpi_cpuidle_register_device(device_node *node) 531 { 532 device_attr attrs[] = { 533 { B_DEVICE_PRETTY_NAME, B_STRING_TYPE, { string: "ACPI CPU IDLE" }}, 534 { NULL } 535 }; 536 537 dprintf("acpi_cpuidle_register_device\n"); 538 return sDeviceManager->register_node(node, ACPI_CPUIDLE_MODULE_NAME, attrs, 539 NULL, NULL); 540 } 541 542 543 static status_t 544 acpi_cpuidle_init_driver(device_node *node, void **driverCookie) 545 { 546 dprintf("acpi_cpuidle_init_driver\n"); 547 acpi_cpuidle_driver_info *device; 548 device = (acpi_cpuidle_driver_info *)calloc(1, sizeof(*device)); 549 if (device == NULL) 550 return B_NO_MEMORY; 551 552 device->node = node; 553 554 device_node *parent; 555 parent = sDeviceManager->get_parent_node(node); 556 sDeviceManager->get_driver(parent, (driver_module_info **)&device->acpi, 557 (void **)&device->acpi_cookie); 558 sDeviceManager->put_node(parent); 559 560 status_t status = acpi_processor_init(device); 561 if (status != B_OK) { 562 free(device); 563 return status; 564 } 565 566 *driverCookie = device; 567 return B_OK; 568 } 569 570 571 static void 572 acpi_cpuidle_uninit_driver(void *driverCookie) 573 { 574 dprintf("acpi_cpuidle_uninit_driver"); 575 acpi_cpuidle_driver_info *device = (acpi_cpuidle_driver_info *)driverCookie; 576 // TODO: When the first device to be unregistered, we'd need to balance the 577 // gIdle->AddDevice() call, but ATM isn't any API for that. 578 sAcpiProcessor[device->cpuIndex] = NULL; 579 free(device); 580 } 581 582 583 module_dependency module_dependencies[] = { 584 { B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&sDeviceManager }, 585 { B_ACPI_MODULE_NAME, (module_info **)&sAcpi}, 586 { B_CPUIDLE_MODULE_NAME, (module_info **)&gIdle }, 587 {} 588 }; 589 590 591 static driver_module_info sAcpiidleModule = { 592 { 593 ACPI_CPUIDLE_MODULE_NAME, 594 0, 595 NULL 596 }, 597 598 acpi_cpuidle_support, 599 acpi_cpuidle_register_device, 600 acpi_cpuidle_init_driver, 601 acpi_cpuidle_uninit_driver, 602 NULL, 603 NULL, // rescan 604 NULL, // removed 605 }; 606 607 608 module_info *modules[] = { 609 (module_info *)&sAcpiidleModule, 610 NULL 611 }; 612