1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 /* 27 * ACPI CA OSL for Solaris x86 28 */ 29 30 #include <sys/types.h> 31 #include <sys/kmem.h> 32 #include <sys/psm.h> 33 #include <sys/pci_cfgspace.h> 34 #include <sys/ddi.h> 35 #include <sys/sunndi.h> 36 #include <sys/pci.h> 37 #include <sys/kobj.h> 38 #include <sys/taskq.h> 39 #include <sys/strlog.h> 40 #include <sys/note.h> 41 42 #include <sys/acpi/acpi.h> 43 #include <sys/acpica.h> 44 #include <sys/acpi/acinterp.h> 45 46 #define MAX_DAT_FILE_SIZE (64*1024) 47 48 /* local functions */ 49 static int CompressEisaID(char *np); 50 51 static void scan_d2a_map(void); 52 static void scan_d2a_subtree(dev_info_t *dip, ACPI_HANDLE acpiobj, int bus); 53 static void acpica_tag_devinfo(dev_info_t *dip, ACPI_HANDLE acpiobj); 54 55 static int acpica_query_bbn_problem(void); 56 static int acpica_find_pcibus(int busno, ACPI_HANDLE *rh); 57 static int acpica_eval_hid(ACPI_HANDLE dev, char *method, int *rint); 58 static ACPI_STATUS acpica_set_devinfo(ACPI_HANDLE, dev_info_t *); 59 static void acpica_devinfo_handler(ACPI_HANDLE, UINT32, void *); 60 61 /* 62 * Event queue vars 63 */ 64 int acpica_eventq_init = 0; 65 ddi_taskq_t *osl_eventq[OSL_EC_BURST_HANDLER+1]; 66 67 /* 68 * Priorities relative to minclsyspri that each taskq 69 * run at; OSL_NOTIFY_HANDLER needs to run at a higher 70 * priority than OSL_GPE_HANDLER. There's an implicit 71 * assumption that no priority here results in exceeding 72 * maxclsyspri. 73 * Note: these initializations need to match the order of 74 * ACPI_EXECUTE_TYPE. 75 */ 76 int osl_eventq_pri_delta[OSL_EC_BURST_HANDLER+1] = { 77 0, /* OSL_GLOBAL_LOCK_HANDLER */ 78 2, /* OSL_NOTIFY_HANDLER */ 79 0, /* OSL_GPE_HANDLER */ 80 0, /* OSL_DEBUGGER_THREAD */ 81 0, /* OSL_EC_POLL_HANDLER */ 82 0 /* OSL_EC_BURST_HANDLER */ 83 }; 84 85 /* 86 * Note, if you change this path, you need to update 87 * /boot/grub/filelist.ramdisk and pkg SUNWckr/prototype_i386 88 */ 89 static char *acpi_table_path = "/boot/acpi/tables/"; 90 91 /* non-zero while scan_d2a_map() is working */ 92 static int scanning_d2a_map = 0; 93 static int d2a_done = 0; 94 95 /* set by acpi_poweroff() in PSMs and appm_ioctl() in acpippm for S3 */ 96 int acpica_use_safe_delay = 0; 97 98 /* CPU mapping data */ 99 struct cpu_map_item { 100 UINT32 proc_id; 101 ACPI_HANDLE obj; 102 }; 103 104 static struct cpu_map_item **cpu_map = NULL; 105 static int cpu_map_count = 0; 106 static int cpu_map_built = 0; 107 108 static int acpi_has_broken_bbn = -1; 109 110 /* buffer for AcpiOsVprintf() */ 111 #define ACPI_OSL_PR_BUFLEN 1024 112 static char *acpi_osl_pr_buffer = NULL; 113 static int acpi_osl_pr_buflen; 114 115 #define D2A_DEBUG 116 117 /* 118 * 119 */ 120 static void 121 discard_event_queues() 122 { 123 int i; 124 125 /* 126 * destroy event queues 127 */ 128 for (i = OSL_GLOBAL_LOCK_HANDLER; i <= OSL_EC_BURST_HANDLER; i++) { 129 if (osl_eventq[i]) 130 ddi_taskq_destroy(osl_eventq[i]); 131 } 132 } 133 134 135 /* 136 * 137 */ 138 static ACPI_STATUS 139 init_event_queues() 140 { 141 char namebuf[32]; 142 int i, error = 0; 143 144 /* 145 * Initialize event queues 146 */ 147 148 /* Always allocate only 1 thread per queue to force FIFO execution */ 149 for (i = OSL_GLOBAL_LOCK_HANDLER; i <= OSL_EC_BURST_HANDLER; i++) { 150 snprintf(namebuf, 32, "ACPI%d", i); 151 osl_eventq[i] = ddi_taskq_create(NULL, namebuf, 1, 152 osl_eventq_pri_delta[i] + minclsyspri, 0); 153 if (osl_eventq[i] == NULL) 154 error++; 155 } 156 157 if (error != 0) { 158 discard_event_queues(); 159 #ifdef DEBUG 160 cmn_err(CE_WARN, "!acpica: could not initialize event queues"); 161 #endif 162 return (AE_ERROR); 163 } 164 165 acpica_eventq_init = 1; 166 return (AE_OK); 167 } 168 169 /* 170 * One-time initialization of OSL layer 171 */ 172 ACPI_STATUS 173 AcpiOsInitialize(void) 174 { 175 /* 176 * Allocate buffer for AcpiOsVprintf() here to avoid 177 * kmem_alloc()/kmem_free() at high PIL 178 */ 179 acpi_osl_pr_buffer = kmem_alloc(ACPI_OSL_PR_BUFLEN, KM_SLEEP); 180 if (acpi_osl_pr_buffer != NULL) 181 acpi_osl_pr_buflen = ACPI_OSL_PR_BUFLEN; 182 183 return (AE_OK); 184 } 185 186 /* 187 * One-time shut-down of OSL layer 188 */ 189 ACPI_STATUS 190 AcpiOsTerminate(void) 191 { 192 193 if (acpi_osl_pr_buffer != NULL) 194 kmem_free(acpi_osl_pr_buffer, acpi_osl_pr_buflen); 195 196 discard_event_queues(); 197 return (AE_OK); 198 } 199 200 201 ACPI_PHYSICAL_ADDRESS 202 AcpiOsGetRootPointer() 203 { 204 ACPI_PHYSICAL_ADDRESS Address; 205 206 /* 207 * For EFI firmware, the root pointer is defined in EFI systab. 208 * The boot code process the table and put the physical address 209 * in the acpi-root-tab property. 210 */ 211 Address = ddi_prop_get_int(DDI_DEV_T_ANY, ddi_root_node(), 0, 212 "acpi-root-tab", NULL); 213 214 if ((Address == NULL) && ACPI_FAILURE(AcpiFindRootPointer(&Address))) 215 Address = NULL; 216 217 return (Address); 218 } 219 220 /*ARGSUSED*/ 221 ACPI_STATUS 222 AcpiOsPredefinedOverride(const ACPI_PREDEFINED_NAMES *InitVal, 223 ACPI_STRING *NewVal) 224 { 225 226 *NewVal = 0; 227 return (AE_OK); 228 } 229 230 static void 231 acpica_strncpy(char *dest, const char *src, int len) 232 { 233 234 /*LINTED*/ 235 while ((*dest++ = *src++) && (--len > 0)) 236 /* copy the string */; 237 *dest = '\0'; 238 } 239 240 ACPI_STATUS 241 AcpiOsTableOverride(ACPI_TABLE_HEADER *ExistingTable, 242 ACPI_TABLE_HEADER **NewTable) 243 { 244 char signature[5]; 245 char oemid[7]; 246 char oemtableid[9]; 247 struct _buf *file; 248 char *buf1, *buf2; 249 int count; 250 char acpi_table_loc[128]; 251 252 acpica_strncpy(signature, ExistingTable->Signature, 4); 253 acpica_strncpy(oemid, ExistingTable->OemId, 6); 254 acpica_strncpy(oemtableid, ExistingTable->OemTableId, 8); 255 256 #ifdef DEBUG 257 cmn_err(CE_NOTE, "!acpica: table [%s] v%d OEM ID [%s]" 258 " OEM TABLE ID [%s] OEM rev %x", 259 signature, ExistingTable->Revision, oemid, oemtableid, 260 ExistingTable->OemRevision); 261 #endif 262 263 /* File name format is "signature_oemid_oemtableid.dat" */ 264 (void) strcpy(acpi_table_loc, acpi_table_path); 265 (void) strcat(acpi_table_loc, signature); /* for example, DSDT */ 266 (void) strcat(acpi_table_loc, "_"); 267 (void) strcat(acpi_table_loc, oemid); /* for example, IntelR */ 268 (void) strcat(acpi_table_loc, "_"); 269 (void) strcat(acpi_table_loc, oemtableid); /* for example, AWRDACPI */ 270 (void) strcat(acpi_table_loc, ".dat"); 271 272 file = kobj_open_file(acpi_table_loc); 273 if (file == (struct _buf *)-1) { 274 *NewTable = 0; 275 return (AE_OK); 276 } else { 277 buf1 = (char *)kmem_alloc(MAX_DAT_FILE_SIZE, KM_SLEEP); 278 count = kobj_read_file(file, buf1, MAX_DAT_FILE_SIZE-1, 0); 279 if (count >= MAX_DAT_FILE_SIZE) { 280 cmn_err(CE_WARN, "!acpica: table %s file size too big", 281 acpi_table_loc); 282 *NewTable = 0; 283 } else { 284 buf2 = (char *)kmem_alloc(count, KM_SLEEP); 285 (void) memcpy(buf2, buf1, count); 286 *NewTable = (ACPI_TABLE_HEADER *)buf2; 287 cmn_err(CE_NOTE, "!acpica: replacing table: %s", 288 acpi_table_loc); 289 } 290 } 291 kobj_close_file(file); 292 kmem_free(buf1, MAX_DAT_FILE_SIZE); 293 294 return (AE_OK); 295 } 296 297 298 /* 299 * ACPI semaphore implementation 300 */ 301 typedef struct { 302 kmutex_t mutex; 303 kcondvar_t cv; 304 uint32_t available; 305 uint32_t initial; 306 uint32_t maximum; 307 } acpi_sema_t; 308 309 /* 310 * 311 */ 312 void 313 acpi_sema_init(acpi_sema_t *sp, unsigned max, unsigned count) 314 { 315 mutex_init(&sp->mutex, NULL, MUTEX_DRIVER, NULL); 316 cv_init(&sp->cv, NULL, CV_DRIVER, NULL); 317 /* no need to enter mutex here at creation */ 318 sp->available = count; 319 sp->initial = count; 320 sp->maximum = max; 321 } 322 323 /* 324 * 325 */ 326 void 327 acpi_sema_destroy(acpi_sema_t *sp) 328 { 329 330 cv_destroy(&sp->cv); 331 mutex_destroy(&sp->mutex); 332 } 333 334 /* 335 * 336 */ 337 ACPI_STATUS 338 acpi_sema_p(acpi_sema_t *sp, unsigned count, uint16_t wait_time) 339 { 340 ACPI_STATUS rv = AE_OK; 341 clock_t deadline; 342 343 mutex_enter(&sp->mutex); 344 345 if (sp->available >= count) { 346 /* 347 * Enough units available, no blocking 348 */ 349 sp->available -= count; 350 mutex_exit(&sp->mutex); 351 return (rv); 352 } else if (wait_time == 0) { 353 /* 354 * Not enough units available and timeout 355 * specifies no blocking 356 */ 357 rv = AE_TIME; 358 mutex_exit(&sp->mutex); 359 return (rv); 360 } 361 362 /* 363 * Not enough units available and timeout specifies waiting 364 */ 365 if (wait_time != ACPI_WAIT_FOREVER) 366 deadline = ddi_get_lbolt() + 367 (clock_t)drv_usectohz(wait_time * 1000); 368 369 do { 370 if (wait_time == ACPI_WAIT_FOREVER) 371 cv_wait(&sp->cv, &sp->mutex); 372 else if (cv_timedwait(&sp->cv, &sp->mutex, deadline) < 0) { 373 rv = AE_TIME; 374 break; 375 } 376 } while (sp->available < count); 377 378 /* if we dropped out of the wait with AE_OK, we got the units */ 379 if (rv == AE_OK) 380 sp->available -= count; 381 382 mutex_exit(&sp->mutex); 383 return (rv); 384 } 385 386 /* 387 * 388 */ 389 void 390 acpi_sema_v(acpi_sema_t *sp, unsigned count) 391 { 392 mutex_enter(&sp->mutex); 393 sp->available += count; 394 cv_broadcast(&sp->cv); 395 mutex_exit(&sp->mutex); 396 } 397 398 399 ACPI_STATUS 400 AcpiOsCreateSemaphore(UINT32 MaxUnits, UINT32 InitialUnits, 401 ACPI_HANDLE *OutHandle) 402 { 403 acpi_sema_t *sp; 404 405 if ((OutHandle == NULL) || (InitialUnits > MaxUnits)) 406 return (AE_BAD_PARAMETER); 407 408 sp = (acpi_sema_t *)kmem_alloc(sizeof (acpi_sema_t), KM_SLEEP); 409 acpi_sema_init(sp, MaxUnits, InitialUnits); 410 *OutHandle = (ACPI_HANDLE)sp; 411 return (AE_OK); 412 } 413 414 415 ACPI_STATUS 416 AcpiOsDeleteSemaphore(ACPI_HANDLE Handle) 417 { 418 419 if (Handle == NULL) 420 return (AE_BAD_PARAMETER); 421 422 acpi_sema_destroy((acpi_sema_t *)Handle); 423 kmem_free((void *)Handle, sizeof (acpi_sema_t)); 424 return (AE_OK); 425 } 426 427 ACPI_STATUS 428 AcpiOsWaitSemaphore(ACPI_HANDLE Handle, UINT32 Units, UINT16 Timeout) 429 { 430 431 if ((Handle == NULL) || (Units < 1)) 432 return (AE_BAD_PARAMETER); 433 434 return (acpi_sema_p((acpi_sema_t *)Handle, Units, Timeout)); 435 } 436 437 ACPI_STATUS 438 AcpiOsSignalSemaphore(ACPI_HANDLE Handle, UINT32 Units) 439 { 440 441 if ((Handle == NULL) || (Units < 1)) 442 return (AE_BAD_PARAMETER); 443 444 acpi_sema_v((acpi_sema_t *)Handle, Units); 445 return (AE_OK); 446 } 447 448 ACPI_STATUS 449 AcpiOsCreateLock(ACPI_HANDLE *OutHandle) 450 { 451 kmutex_t *mp; 452 453 if (OutHandle == NULL) 454 return (AE_BAD_PARAMETER); 455 456 mp = (kmutex_t *)kmem_alloc(sizeof (kmutex_t), KM_SLEEP); 457 mutex_init(mp, NULL, MUTEX_DRIVER, NULL); 458 *OutHandle = (ACPI_HANDLE)mp; 459 return (AE_OK); 460 } 461 462 void 463 AcpiOsDeleteLock(ACPI_HANDLE Handle) 464 { 465 466 if (Handle == NULL) 467 return; 468 469 mutex_destroy((kmutex_t *)Handle); 470 kmem_free((void *)Handle, sizeof (kmutex_t)); 471 } 472 473 ACPI_CPU_FLAGS 474 AcpiOsAcquireLock(ACPI_HANDLE Handle) 475 { 476 477 478 if (Handle == NULL) 479 return (AE_BAD_PARAMETER); 480 481 if (curthread == CPU->cpu_idle_thread) { 482 while (!mutex_tryenter((kmutex_t *)Handle)) 483 /* spin */; 484 } else 485 mutex_enter((kmutex_t *)Handle); 486 return (AE_OK); 487 } 488 489 void 490 AcpiOsReleaseLock(ACPI_HANDLE Handle, ACPI_CPU_FLAGS Flags) 491 { 492 _NOTE(ARGUNUSED(Flags)) 493 494 mutex_exit((kmutex_t *)Handle); 495 } 496 497 498 void * 499 AcpiOsAllocate(ACPI_SIZE Size) 500 { 501 ACPI_SIZE *tmp_ptr; 502 503 Size += sizeof (Size); 504 tmp_ptr = (ACPI_SIZE *)kmem_zalloc(Size, KM_SLEEP); 505 *tmp_ptr++ = Size; 506 return (tmp_ptr); 507 } 508 509 void 510 AcpiOsFree(void *Memory) 511 { 512 ACPI_SIZE size, *tmp_ptr; 513 514 tmp_ptr = (ACPI_SIZE *)Memory; 515 tmp_ptr -= 1; 516 size = *tmp_ptr; 517 kmem_free(tmp_ptr, size); 518 } 519 520 void * 521 AcpiOsMapMemory(ACPI_PHYSICAL_ADDRESS PhysicalAddress, ACPI_SIZE Size) 522 { 523 /* FUTUREWORK: test PhysicalAddress for > 32 bits */ 524 return (psm_map_new((paddr_t)PhysicalAddress, 525 (size_t)Size, PSM_PROT_WRITE | PSM_PROT_READ)); 526 } 527 528 void 529 AcpiOsUnmapMemory(void *LogicalAddress, ACPI_SIZE Size) 530 { 531 532 psm_unmap((caddr_t)LogicalAddress, (size_t)Size); 533 } 534 535 /*ARGSUSED*/ 536 ACPI_STATUS 537 AcpiOsGetPhysicalAddress(void *LogicalAddress, 538 ACPI_PHYSICAL_ADDRESS *PhysicalAddress) 539 { 540 541 /* UNIMPLEMENTED: not invoked by ACPI CA code */ 542 return (AE_NOT_IMPLEMENTED); 543 } 544 545 546 ACPI_OSD_HANDLER acpi_isr; 547 void *acpi_isr_context; 548 549 uint_t 550 acpi_wrapper_isr(char *arg) 551 { 552 _NOTE(ARGUNUSED(arg)) 553 554 int status; 555 556 status = (*acpi_isr)(acpi_isr_context); 557 558 if (status == ACPI_INTERRUPT_HANDLED) { 559 return (DDI_INTR_CLAIMED); 560 } else { 561 return (DDI_INTR_UNCLAIMED); 562 } 563 } 564 565 static int acpi_intr_hooked = 0; 566 567 ACPI_STATUS 568 AcpiOsInstallInterruptHandler(UINT32 InterruptNumber, 569 ACPI_OSD_HANDLER ServiceRoutine, 570 void *Context) 571 { 572 _NOTE(ARGUNUSED(InterruptNumber)) 573 574 int retval; 575 int sci_vect; 576 iflag_t sci_flags; 577 578 acpi_isr = ServiceRoutine; 579 acpi_isr_context = Context; 580 581 /* 582 * Get SCI (adjusted for PIC/APIC mode if necessary) 583 */ 584 if (acpica_get_sci(&sci_vect, &sci_flags) != AE_OK) { 585 return (AE_ERROR); 586 } 587 588 #ifdef DEBUG 589 cmn_err(CE_NOTE, "!acpica: attaching SCI %d", sci_vect); 590 #endif 591 592 retval = add_avintr(NULL, SCI_IPL, (avfunc)acpi_wrapper_isr, 593 "ACPI SCI", sci_vect, NULL, NULL, NULL, NULL); 594 if (retval) { 595 acpi_intr_hooked = 1; 596 return (AE_OK); 597 } else 598 return (AE_BAD_PARAMETER); 599 } 600 601 ACPI_STATUS 602 AcpiOsRemoveInterruptHandler(UINT32 InterruptNumber, 603 ACPI_OSD_HANDLER ServiceRoutine) 604 { 605 _NOTE(ARGUNUSED(ServiceRoutine)) 606 607 #ifdef DEBUG 608 cmn_err(CE_NOTE, "!acpica: detaching SCI %d", InterruptNumber); 609 #endif 610 if (acpi_intr_hooked) { 611 rem_avintr(NULL, LOCK_LEVEL - 1, (avfunc)acpi_wrapper_isr, 612 InterruptNumber); 613 acpi_intr_hooked = 0; 614 } 615 return (AE_OK); 616 } 617 618 619 ACPI_THREAD_ID 620 AcpiOsGetThreadId(void) 621 { 622 /* 623 * ACPI CA regards thread ID as an error, but it's valid 624 * on Solaris during kernel initialization. Thus, 1 is added 625 * to the kernel thread ID to avoid returning 0 626 */ 627 return (ddi_get_kt_did() + 1); 628 } 629 630 /* 631 * 632 */ 633 ACPI_STATUS 634 AcpiOsExecute(ACPI_EXECUTE_TYPE Type, ACPI_OSD_EXEC_CALLBACK Function, 635 void *Context) 636 { 637 638 if (!acpica_eventq_init) { 639 /* 640 * Create taskqs for event handling 641 */ 642 if (init_event_queues() != AE_OK) 643 return (AE_ERROR); 644 } 645 646 if (ddi_taskq_dispatch(osl_eventq[Type], Function, Context, 647 DDI_NOSLEEP) == DDI_FAILURE) { 648 #ifdef DEBUG 649 cmn_err(CE_WARN, "!acpica: unable to dispatch event"); 650 #endif 651 return (AE_ERROR); 652 } 653 return (AE_OK); 654 655 } 656 657 void 658 AcpiOsSleep(ACPI_INTEGER Milliseconds) 659 { 660 /* 661 * During kernel startup, before the first tick interrupt 662 * has taken place, we can't call delay; very late in 663 * kernel shutdown or suspend/resume, clock interrupts 664 * are blocked, so delay doesn't work then either. 665 * So we busy wait if lbolt == 0 (kernel startup) 666 * or if acpica_use_safe_delay has been set to a 667 * non-zero value. 668 */ 669 if ((ddi_get_lbolt() == 0) || acpica_use_safe_delay) 670 drv_usecwait(Milliseconds * 1000); 671 else 672 delay(drv_usectohz(Milliseconds * 1000)); 673 } 674 675 void 676 AcpiOsStall(UINT32 Microseconds) 677 { 678 drv_usecwait(Microseconds); 679 } 680 681 682 /* 683 * Implementation of "Windows 2001" compatible I/O permission map 684 * 685 */ 686 #define OSL_IO_NONE (0) 687 #define OSL_IO_READ (1<<0) 688 #define OSL_IO_WRITE (1<<1) 689 #define OSL_IO_RW (OSL_IO_READ | OSL_IO_WRITE) 690 #define OSL_IO_TERM (1<<2) 691 #define OSL_IO_DEFAULT OSL_IO_RW 692 693 static struct io_perm { 694 ACPI_IO_ADDRESS low; 695 ACPI_IO_ADDRESS high; 696 uint8_t perm; 697 } osl_io_perm[] = { 698 { 0xcf8, 0xd00, OSL_IO_NONE | OSL_IO_TERM } 699 }; 700 701 702 /* 703 * 704 */ 705 static struct io_perm * 706 osl_io_find_perm(ACPI_IO_ADDRESS addr) 707 { 708 struct io_perm *p; 709 710 p = osl_io_perm; 711 while (p != NULL) { 712 if ((p->low <= addr) && (addr <= p->high)) 713 break; 714 p = (p->perm & OSL_IO_TERM) ? NULL : p+1; 715 } 716 717 return (p); 718 } 719 720 /* 721 * 722 */ 723 ACPI_STATUS 724 AcpiOsReadPort(ACPI_IO_ADDRESS Address, UINT32 *Value, UINT32 Width) 725 { 726 struct io_perm *p; 727 728 /* verify permission */ 729 p = osl_io_find_perm(Address); 730 if (p && (p->perm & OSL_IO_READ) == 0) { 731 cmn_err(CE_WARN, "!AcpiOsReadPort: %lx %u not permitted", 732 (long)Address, Width); 733 *Value = 0xffffffff; 734 return (AE_ERROR); 735 } 736 737 switch (Width) { 738 case 8: 739 *Value = inb(Address); 740 break; 741 case 16: 742 *Value = inw(Address); 743 break; 744 case 32: 745 *Value = inl(Address); 746 break; 747 default: 748 cmn_err(CE_WARN, "!AcpiOsReadPort: %lx %u failed", 749 (long)Address, Width); 750 return (AE_BAD_PARAMETER); 751 } 752 return (AE_OK); 753 } 754 755 ACPI_STATUS 756 AcpiOsWritePort(ACPI_IO_ADDRESS Address, UINT32 Value, UINT32 Width) 757 { 758 struct io_perm *p; 759 760 /* verify permission */ 761 p = osl_io_find_perm(Address); 762 if (p && (p->perm & OSL_IO_WRITE) == 0) { 763 cmn_err(CE_WARN, "!AcpiOsWritePort: %lx %u not permitted", 764 (long)Address, Width); 765 return (AE_ERROR); 766 } 767 768 switch (Width) { 769 case 8: 770 outb(Address, Value); 771 break; 772 case 16: 773 outw(Address, Value); 774 break; 775 case 32: 776 outl(Address, Value); 777 break; 778 default: 779 cmn_err(CE_WARN, "!AcpiOsWritePort: %lx %u failed", 780 (long)Address, Width); 781 return (AE_BAD_PARAMETER); 782 } 783 return (AE_OK); 784 } 785 786 787 /* 788 * 789 */ 790 791 #define OSL_RW(ptr, val, type, rw) \ 792 { if (rw) *((type *)(ptr)) = *((type *) val); \ 793 else *((type *) val) = *((type *)(ptr)); } 794 795 796 static void 797 osl_rw_memory(ACPI_PHYSICAL_ADDRESS Address, UINT32 *Value, 798 UINT32 Width, int write) 799 { 800 size_t maplen = Width / 8; 801 caddr_t ptr; 802 803 ptr = psm_map_new((paddr_t)Address, maplen, 804 PSM_PROT_WRITE | PSM_PROT_READ); 805 806 switch (maplen) { 807 case 1: 808 OSL_RW(ptr, Value, uint8_t, write); 809 break; 810 case 2: 811 OSL_RW(ptr, Value, uint16_t, write); 812 break; 813 case 4: 814 OSL_RW(ptr, Value, uint32_t, write); 815 break; 816 default: 817 cmn_err(CE_WARN, "!osl_rw_memory: invalid size %d", 818 Width); 819 break; 820 } 821 822 psm_unmap(ptr, maplen); 823 } 824 825 ACPI_STATUS 826 AcpiOsReadMemory(ACPI_PHYSICAL_ADDRESS Address, 827 UINT32 *Value, UINT32 Width) 828 { 829 osl_rw_memory(Address, Value, Width, 0); 830 return (AE_OK); 831 } 832 833 ACPI_STATUS 834 AcpiOsWriteMemory(ACPI_PHYSICAL_ADDRESS Address, 835 UINT32 Value, UINT32 Width) 836 { 837 osl_rw_memory(Address, &Value, Width, 1); 838 return (AE_OK); 839 } 840 841 842 ACPI_STATUS 843 AcpiOsReadPciConfiguration(ACPI_PCI_ID *PciId, UINT32 Register, 844 void *Value, UINT32 Width) 845 { 846 847 switch (Width) { 848 case 8: 849 *((UINT64 *)Value) = (UINT64)(*pci_getb_func) 850 (PciId->Bus, PciId->Device, PciId->Function, Register); 851 break; 852 case 16: 853 *((UINT64 *)Value) = (UINT64)(*pci_getw_func) 854 (PciId->Bus, PciId->Device, PciId->Function, Register); 855 break; 856 case 32: 857 *((UINT64 *)Value) = (UINT64)(*pci_getl_func) 858 (PciId->Bus, PciId->Device, PciId->Function, Register); 859 break; 860 case 64: 861 default: 862 cmn_err(CE_WARN, "!AcpiOsReadPciConfiguration: %x %u failed", 863 Register, Width); 864 return (AE_BAD_PARAMETER); 865 } 866 return (AE_OK); 867 } 868 869 /* 870 * 871 */ 872 int acpica_write_pci_config_ok = 1; 873 874 ACPI_STATUS 875 AcpiOsWritePciConfiguration(ACPI_PCI_ID *PciId, UINT32 Register, 876 ACPI_INTEGER Value, UINT32 Width) 877 { 878 879 if (!acpica_write_pci_config_ok) { 880 cmn_err(CE_NOTE, "!write to PCI cfg %x/%x/%x %x" 881 " %lx %d not permitted", PciId->Bus, PciId->Device, 882 PciId->Function, Register, (long)Value, Width); 883 return (AE_OK); 884 } 885 886 switch (Width) { 887 case 8: 888 (*pci_putb_func)(PciId->Bus, PciId->Device, PciId->Function, 889 Register, (uint8_t)Value); 890 break; 891 case 16: 892 (*pci_putw_func)(PciId->Bus, PciId->Device, PciId->Function, 893 Register, (uint16_t)Value); 894 break; 895 case 32: 896 (*pci_putl_func)(PciId->Bus, PciId->Device, PciId->Function, 897 Register, (uint32_t)Value); 898 break; 899 case 64: 900 default: 901 cmn_err(CE_WARN, "!AcpiOsWritePciConfiguration: %x %u failed", 902 Register, Width); 903 return (AE_BAD_PARAMETER); 904 } 905 return (AE_OK); 906 } 907 908 /* 909 * Called with ACPI_HANDLEs for both a PCI Config Space 910 * OpRegion and (what ACPI CA thinks is) the PCI device 911 * to which this ConfigSpace OpRegion belongs. Since 912 * ACPI CA depends on a valid _BBN object being present 913 * and this is not always true (one old x86 had broken _BBN), 914 * we go ahead and get the correct PCI bus number using the 915 * devinfo mapping (which compensates for broken _BBN). 916 * 917 * Default values for bus, segment, device and function are 918 * all 0 when ACPI CA can't figure them out. 919 * 920 * Some BIOSes implement _BBN() by reading PCI config space 921 * on bus #0 - which means that we'll recurse when we attempt 922 * to create the devinfo-to-ACPI map. If Derive is called during 923 * scan_d2a_map, we don't translate the bus # and return. 924 * 925 * We get the parent of the OpRegion, which must be a PCI 926 * node, fetch the associated devinfo node and snag the 927 * b/d/f from it. 928 */ 929 void 930 AcpiOsDerivePciId(ACPI_HANDLE rhandle, ACPI_HANDLE chandle, 931 ACPI_PCI_ID **PciId) 932 { 933 ACPI_HANDLE handle; 934 dev_info_t *dip; 935 int bus, device, func, devfn; 936 937 938 /* 939 * See above - avoid recursing during scanning_d2a_map. 940 */ 941 if (scanning_d2a_map) 942 return; 943 944 /* 945 * Get the OpRegion's parent 946 */ 947 if (AcpiGetParent(chandle, &handle) != AE_OK) 948 return; 949 950 /* 951 * If we've mapped the ACPI node to the devinfo 952 * tree, use the devinfo reg property 953 */ 954 if (acpica_get_devinfo(handle, &dip) == AE_OK) { 955 (void) acpica_get_bdf(dip, &bus, &device, &func); 956 (*PciId)->Bus = bus; 957 (*PciId)->Device = device; 958 (*PciId)->Function = func; 959 } else if (acpica_eval_int(handle, "_ADR", &devfn) == AE_OK) { 960 /* no devinfo node - just confirm the d/f */ 961 (*PciId)->Device = (devfn >> 16) & 0xFFFF; 962 (*PciId)->Function = devfn & 0xFFFF; 963 } 964 } 965 966 967 /*ARGSUSED*/ 968 BOOLEAN 969 AcpiOsReadable(void *Pointer, ACPI_SIZE Length) 970 { 971 972 /* Always says yes; all mapped memory assumed readable */ 973 return (1); 974 } 975 976 /*ARGSUSED*/ 977 BOOLEAN 978 AcpiOsWritable(void *Pointer, ACPI_SIZE Length) 979 { 980 981 /* Always says yes; all mapped memory assumed writable */ 982 return (1); 983 } 984 985 UINT64 986 AcpiOsGetTimer(void) 987 { 988 /* gethrtime() returns 1nS resolution; convert to 100nS granules */ 989 return ((gethrtime() + 50) / 100); 990 } 991 992 /*ARGSUSED*/ 993 ACPI_STATUS 994 AcpiOsValidateInterface(char *interface) 995 { 996 return (AE_SUPPORT); 997 } 998 999 /*ARGSUSED*/ 1000 ACPI_STATUS 1001 AcpiOsValidateAddress(UINT8 spaceid, ACPI_PHYSICAL_ADDRESS addr, 1002 ACPI_SIZE length) 1003 { 1004 return (AE_OK); 1005 } 1006 1007 ACPI_STATUS 1008 AcpiOsSignal(UINT32 Function, void *Info) 1009 { 1010 _NOTE(ARGUNUSED(Function, Info)) 1011 1012 /* FUTUREWORK: debugger support */ 1013 1014 cmn_err(CE_NOTE, "!OsSignal unimplemented"); 1015 return (AE_OK); 1016 } 1017 1018 void ACPI_INTERNAL_VAR_XFACE 1019 AcpiOsPrintf(const char *Format, ...) 1020 { 1021 va_list ap; 1022 1023 va_start(ap, Format); 1024 AcpiOsVprintf(Format, ap); 1025 va_end(ap); 1026 } 1027 1028 /* 1029 * When != 0, sends output to console 1030 * Patchable with kmdb or /etc/system. 1031 */ 1032 int acpica_console_out = 0; 1033 1034 #define ACPICA_OUTBUF_LEN 160 1035 char acpica_outbuf[ACPICA_OUTBUF_LEN]; 1036 int acpica_outbuf_offset; 1037 1038 /* 1039 * 1040 */ 1041 static void 1042 acpica_pr_buf(char *buf) 1043 { 1044 char c, *bufp, *outp; 1045 int out_remaining; 1046 1047 /* 1048 * copy the supplied buffer into the output buffer 1049 * when we hit a '\n' or overflow the output buffer, 1050 * output and reset the output buffer 1051 */ 1052 bufp = buf; 1053 outp = acpica_outbuf + acpica_outbuf_offset; 1054 out_remaining = ACPICA_OUTBUF_LEN - acpica_outbuf_offset - 1; 1055 while (c = *bufp++) { 1056 *outp++ = c; 1057 if (c == '\n' || --out_remaining == 0) { 1058 *outp = '\0'; 1059 if (acpica_console_out) 1060 printf(acpica_outbuf); 1061 else 1062 (void) strlog(0, 0, 0, 1063 SL_CONSOLE | SL_NOTE | SL_LOGONLY, 1064 acpica_outbuf); 1065 acpica_outbuf_offset = 0; 1066 outp = acpica_outbuf; 1067 out_remaining = ACPICA_OUTBUF_LEN - 1; 1068 } 1069 } 1070 1071 acpica_outbuf_offset = outp - acpica_outbuf; 1072 } 1073 1074 void 1075 AcpiOsVprintf(const char *Format, va_list Args) 1076 { 1077 1078 /* 1079 * If AcpiOsInitialize() failed to allocate a string buffer, 1080 * resort to vprintf(). 1081 */ 1082 if (acpi_osl_pr_buffer == NULL) { 1083 vprintf(Format, Args); 1084 return; 1085 } 1086 1087 /* 1088 * It is possible that a very long debug output statement will 1089 * be truncated; this is silently ignored. 1090 */ 1091 (void) vsnprintf(acpi_osl_pr_buffer, acpi_osl_pr_buflen, Format, Args); 1092 acpica_pr_buf(acpi_osl_pr_buffer); 1093 } 1094 1095 void 1096 AcpiOsRedirectOutput(void *Destination) 1097 { 1098 _NOTE(ARGUNUSED(Destination)) 1099 1100 /* FUTUREWORK: debugger support */ 1101 1102 #ifdef DEBUG 1103 cmn_err(CE_WARN, "!acpica: AcpiOsRedirectOutput called"); 1104 #endif 1105 } 1106 1107 1108 UINT32 1109 AcpiOsGetLine(char *Buffer) 1110 { 1111 _NOTE(ARGUNUSED(Buffer)) 1112 1113 /* FUTUREWORK: debugger support */ 1114 1115 return (0); 1116 } 1117 1118 1119 1120 1121 /* 1122 * Device tree binding 1123 */ 1124 1125 static int 1126 acpica_find_pcibus(int busno, ACPI_HANDLE *rh) 1127 { 1128 ACPI_HANDLE sbobj, busobj; 1129 int hid, bbn; 1130 1131 /* initialize static flag by querying ACPI namespace for bug */ 1132 if (acpi_has_broken_bbn == -1) 1133 acpi_has_broken_bbn = acpica_query_bbn_problem(); 1134 1135 busobj = NULL; 1136 AcpiGetHandle(NULL, "\\_SB", &sbobj); 1137 while (AcpiGetNextObject(ACPI_TYPE_DEVICE, sbobj, busobj, 1138 &busobj) == AE_OK) { 1139 if (acpica_eval_hid(busobj, "_HID", &hid) == AE_OK && 1140 (hid == HID_PCI_BUS || hid == HID_PCI_EXPRESS_BUS)) { 1141 if (acpi_has_broken_bbn) { 1142 ACPI_BUFFER rb; 1143 rb.Pointer = NULL; 1144 rb.Length = ACPI_ALLOCATE_BUFFER; 1145 1146 /* Decree _BBN == n from PCI<n> */ 1147 if (AcpiGetName(busobj, ACPI_SINGLE_NAME, &rb) 1148 != AE_OK) { 1149 return (AE_ERROR); 1150 } 1151 bbn = ((char *)rb.Pointer)[3] - '0'; 1152 AcpiOsFree(rb.Pointer); 1153 if (bbn == busno || busno == 0) { 1154 *rh = busobj; 1155 return (AE_OK); 1156 } 1157 } else { 1158 if (acpica_eval_int(busobj, "_BBN", &bbn) == 1159 AE_OK) { 1160 if (bbn == busno) { 1161 *rh = busobj; 1162 return (AE_OK); 1163 } 1164 } else if (busno == 0) { 1165 *rh = busobj; 1166 return (AE_OK); 1167 } 1168 } 1169 } 1170 } 1171 return (AE_ERROR); 1172 } 1173 1174 1175 /* 1176 * Look for ACPI problem where _BBN is zero for multiple PCI buses 1177 * This is a clear ACPI bug, but we have a workaround in acpica_find_pcibus() 1178 * below if it exists. 1179 */ 1180 static int 1181 acpica_query_bbn_problem(void) 1182 { 1183 ACPI_HANDLE sbobj, busobj; 1184 int hid, bbn; 1185 int zerobbncnt; 1186 1187 busobj = NULL; 1188 zerobbncnt = 0; 1189 1190 AcpiGetHandle(NULL, "\\_SB", &sbobj); 1191 1192 while (AcpiGetNextObject(ACPI_TYPE_DEVICE, sbobj, busobj, 1193 &busobj) == AE_OK) { 1194 if ((acpica_eval_hid(busobj, "_HID", &hid) == AE_OK) && 1195 (hid == HID_PCI_BUS || hid == HID_PCI_EXPRESS_BUS) && 1196 (acpica_eval_int(busobj, "_BBN", &bbn) == AE_OK)) { 1197 if (bbn == 0) { 1198 /* 1199 * If we find more than one bus with a 0 _BBN 1200 * we have the problem that BigBear's BIOS shows 1201 */ 1202 if (++zerobbncnt > 1) 1203 return (1); 1204 } 1205 } 1206 } 1207 return (0); 1208 } 1209 1210 static const char hextab[] = "0123456789ABCDEF"; 1211 1212 static int 1213 hexdig(int c) 1214 { 1215 /* 1216 * Get hex digit: 1217 * 1218 * Returns the 4-bit hex digit named by the input character. Returns 1219 * zero if the input character is not valid hex! 1220 */ 1221 1222 int x = ((c < 'a') || (c > 'z')) ? c : (c - ' '); 1223 int j = sizeof (hextab); 1224 1225 while (--j && (x != hextab[j])) { 1226 } 1227 return (j); 1228 } 1229 1230 static int 1231 CompressEisaID(char *np) 1232 { 1233 /* 1234 * Compress an EISA device name: 1235 * 1236 * This routine converts a 7-byte ASCII device name into the 4-byte 1237 * compressed form used by EISA (50 bytes of ROM to save 1 byte of 1238 * NV-RAM!) 1239 */ 1240 1241 union { char octets[4]; int retval; } myu; 1242 1243 myu.octets[0] = ((np[0] & 0x1F) << 2) + ((np[1] >> 3) & 0x03); 1244 myu.octets[1] = ((np[1] & 0x07) << 5) + (np[2] & 0x1F); 1245 myu.octets[2] = (hexdig(np[3]) << 4) + hexdig(np[4]); 1246 myu.octets[3] = (hexdig(np[5]) << 4) + hexdig(np[6]); 1247 1248 return (myu.retval); 1249 } 1250 1251 ACPI_STATUS 1252 acpica_eval_int(ACPI_HANDLE dev, char *method, int *rint) 1253 { 1254 ACPI_STATUS status; 1255 ACPI_BUFFER rb; 1256 ACPI_OBJECT ro; 1257 1258 rb.Pointer = &ro; 1259 rb.Length = sizeof (ro); 1260 if ((status = AcpiEvaluateObjectTyped(dev, method, NULL, &rb, 1261 ACPI_TYPE_INTEGER)) == AE_OK) 1262 *rint = ro.Integer.Value; 1263 1264 return (status); 1265 } 1266 1267 static int 1268 acpica_eval_hid(ACPI_HANDLE dev, char *method, int *rint) 1269 { 1270 ACPI_BUFFER rb; 1271 ACPI_OBJECT *rv; 1272 1273 rb.Pointer = NULL; 1274 rb.Length = ACPI_ALLOCATE_BUFFER; 1275 if (AcpiEvaluateObject(dev, method, NULL, &rb) == AE_OK && 1276 rb.Length != 0) { 1277 rv = rb.Pointer; 1278 if (rv->Type == ACPI_TYPE_INTEGER) { 1279 *rint = rv->Integer.Value; 1280 AcpiOsFree(rv); 1281 return (AE_OK); 1282 } else if (rv->Type == ACPI_TYPE_STRING) { 1283 char *stringData; 1284 1285 /* Convert the string into an EISA ID */ 1286 if (rv->String.Pointer == NULL) { 1287 AcpiOsFree(rv); 1288 return (AE_ERROR); 1289 } 1290 1291 stringData = rv->String.Pointer; 1292 1293 /* 1294 * If the string is an EisaID, it must be 7 1295 * characters; if it's an ACPI ID, it will be 8 1296 * (and we don't care about ACPI ids here). 1297 */ 1298 if (strlen(stringData) != 7) { 1299 AcpiOsFree(rv); 1300 return (AE_ERROR); 1301 } 1302 1303 *rint = CompressEisaID(stringData); 1304 AcpiOsFree(rv); 1305 return (AE_OK); 1306 } else 1307 AcpiOsFree(rv); 1308 } 1309 return (AE_ERROR); 1310 } 1311 1312 /* 1313 * Create linkage between devinfo nodes and ACPI nodes 1314 */ 1315 static void 1316 acpica_tag_devinfo(dev_info_t *dip, ACPI_HANDLE acpiobj) 1317 { 1318 ACPI_STATUS status; 1319 ACPI_BUFFER rb; 1320 1321 /* 1322 * Tag the ACPI node with the dip 1323 */ 1324 status = acpica_set_devinfo(acpiobj, dip); 1325 ASSERT(status == AE_OK); 1326 1327 /* 1328 * Tag the devinfo node with the ACPI name 1329 */ 1330 rb.Pointer = NULL; 1331 rb.Length = ACPI_ALLOCATE_BUFFER; 1332 if (AcpiGetName(acpiobj, ACPI_FULL_PATHNAME, &rb) == AE_OK) { 1333 (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip, 1334 "acpi-namespace", (char *)rb.Pointer); 1335 AcpiOsFree(rb.Pointer); 1336 } else { 1337 cmn_err(CE_WARN, "acpica: could not get ACPI path!"); 1338 } 1339 } 1340 1341 static void 1342 acpica_add_processor_to_map(UINT32 acpi_id, ACPI_HANDLE obj) 1343 { 1344 int cpu_id; 1345 1346 /* 1347 * Special case: if we're a uppc system, there won't be 1348 * a CPU map yet. So we create one and use the passed-in 1349 * processor as CPU 0 1350 */ 1351 if (cpu_map == NULL) { 1352 cpu_map = kmem_zalloc(sizeof (cpu_map[0]) * NCPU, KM_SLEEP); 1353 cpu_map[0] = kmem_zalloc(sizeof (*cpu_map[0]), KM_SLEEP); 1354 cpu_map[0]->obj = obj; 1355 cpu_map_count = 1; 1356 return; 1357 } 1358 1359 for (cpu_id = 0; cpu_id < NCPU; cpu_id++) { 1360 if (cpu_map[cpu_id] == NULL) 1361 continue; 1362 1363 if (cpu_map[cpu_id]->proc_id == acpi_id) { 1364 if (cpu_map[cpu_id]->obj == NULL) 1365 cpu_map[cpu_id]->obj = obj; 1366 break; 1367 } 1368 } 1369 1370 } 1371 1372 /* 1373 * Return the ACPI device node matching the CPU dev_info node. 1374 */ 1375 ACPI_STATUS 1376 acpica_get_handle_cpu(int cpu_id, ACPI_HANDLE *rh) 1377 { 1378 /* 1379 * if cpu_map itself is NULL, we're a uppc system and 1380 * acpica_build_processor_map() hasn't been called yet. 1381 * So call it here 1382 */ 1383 if (cpu_map == NULL) { 1384 (void) acpica_build_processor_map(); 1385 if (cpu_map == NULL) 1386 return (AE_ERROR); 1387 } 1388 1389 if ((cpu_id < 0) || (cpu_map[cpu_id] == NULL) || 1390 (cpu_map[cpu_id]->obj == NULL)) 1391 return (AE_ERROR); 1392 1393 *rh = cpu_map[cpu_id]->obj; 1394 return (AE_OK); 1395 } 1396 1397 /* 1398 * Convert CPU device _UID strings into unique integers 1399 * ACPI 3.0 spec 6.1.9 permits _UID to be either 1400 * an arbitrary string or numeric value. ACPI CA converts 1401 * numeric types to a string, providing a consistent API, 1402 * but it can not be assumed that _UID is always numeric. 1403 * Keep a private list of CPU _UIDs and convert them to 1404 * an integer representation. 1405 */ 1406 1407 struct acpica_cpu_uid { 1408 struct acpica_cpu_uid *next; 1409 char *uid; 1410 }; 1411 1412 static struct acpica_cpu_uid *acpica_cpu_uid_list = NULL; 1413 1414 static UINT32 1415 acpica_cpu_uid_str_to_uint(char *uidstr) 1416 { 1417 UINT32 n; 1418 struct acpica_cpu_uid *current, **tail; 1419 1420 ASSERT(uidstr != NULL); 1421 1422 n = 0; 1423 current = acpica_cpu_uid_list; 1424 tail = &acpica_cpu_uid_list; 1425 while (current != NULL) { 1426 if (strcmp(current->uid, uidstr) == 0) 1427 break; 1428 n++; 1429 tail = ¤t->next; 1430 current = current->next; 1431 } 1432 1433 /* 1434 * failed to find a matching element; create it here 1435 */ 1436 if (current == NULL) { 1437 /* allocate new list element as current one */ 1438 current = (struct acpica_cpu_uid *)kmem_zalloc( 1439 sizeof (struct acpica_cpu_uid), KM_SLEEP); 1440 1441 /* allocate storage for the device ID string */ 1442 current->uid = (char *)kmem_zalloc(strlen(uidstr) + 1, 1443 KM_SLEEP); 1444 1445 strcpy(current->uid, uidstr); 1446 *tail = current; 1447 } 1448 1449 /* 1450 * 'n' correctly contains the index for either 1451 * a new element or an existing element 1452 */ 1453 return (n); 1454 } 1455 1456 /* 1457 * Determine if this object is a processor 1458 */ 1459 static ACPI_STATUS 1460 acpica_probe_processor(ACPI_HANDLE obj, UINT32 level, void *ctx, void **rv) 1461 { 1462 ACPI_STATUS status; 1463 ACPI_OBJECT_TYPE objtype; 1464 UINT32 acpi_id; 1465 ACPI_BUFFER rb; 1466 1467 if (AcpiGetType(obj, &objtype) != AE_OK) 1468 return (AE_OK); 1469 1470 if (objtype == ACPI_TYPE_PROCESSOR) { 1471 /* process a Processor */ 1472 rb.Pointer = NULL; 1473 rb.Length = ACPI_ALLOCATE_BUFFER; 1474 status = AcpiEvaluateObjectTyped(obj, NULL, NULL, &rb, 1475 ACPI_TYPE_PROCESSOR); 1476 if (status != AE_OK) { 1477 cmn_err(CE_WARN, "acpica: error probing Processor"); 1478 return (status); 1479 } 1480 acpi_id = ((ACPI_OBJECT *)rb.Pointer)->Processor.ProcId; 1481 AcpiOsFree(rb.Pointer); 1482 } else if (objtype == ACPI_TYPE_DEVICE) { 1483 /* process a processor Device */ 1484 rb.Pointer = NULL; 1485 rb.Length = ACPI_ALLOCATE_BUFFER; 1486 status = AcpiGetObjectInfo(obj, &rb); 1487 if (status != AE_OK) { 1488 cmn_err(CE_WARN, 1489 "acpica: error probing Processor Device\n"); 1490 return (status); 1491 } 1492 ASSERT(((ACPI_OBJECT *)rb.Pointer)->Type == 1493 ACPI_TYPE_DEVICE); 1494 acpi_id = acpica_cpu_uid_str_to_uint( 1495 ((ACPI_DEVICE_INFO *)rb.Pointer)->UniqueId.Value); 1496 AcpiOsFree(rb.Pointer); 1497 } 1498 1499 acpica_add_processor_to_map(acpi_id, obj); 1500 return (AE_OK); 1501 } 1502 1503 1504 static void 1505 scan_d2a_map(void) 1506 { 1507 dev_info_t *dip, *cdip; 1508 ACPI_HANDLE acpiobj; 1509 char *device_type_prop; 1510 int bus; 1511 static int map_error = 0; 1512 1513 if (map_error) 1514 return; 1515 1516 scanning_d2a_map = 1; 1517 1518 /* 1519 * Find all child-of-root PCI buses, and find their corresponding 1520 * ACPI child-of-root PCI nodes. For each one, add to the 1521 * d2a table. 1522 */ 1523 1524 for (dip = ddi_get_child(ddi_root_node()); 1525 dip != NULL; 1526 dip = ddi_get_next_sibling(dip)) { 1527 1528 /* prune non-PCI nodes */ 1529 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, 0, 1530 "device_type", &device_type_prop) != DDI_PROP_SUCCESS) 1531 continue; 1532 1533 if ((strcmp("pci", device_type_prop) != 0) && 1534 (strcmp("pciex", device_type_prop) != 0)) { 1535 ddi_prop_free(device_type_prop); 1536 continue; 1537 } 1538 1539 ddi_prop_free(device_type_prop); 1540 1541 /* 1542 * To get bus number of dip, get first child and get its 1543 * bus number. If NULL, just continue, because we don't 1544 * care about bus nodes with no children anyway. 1545 */ 1546 if ((cdip = ddi_get_child(dip)) == NULL) 1547 continue; 1548 1549 if (acpica_get_bdf(cdip, &bus, NULL, NULL) < 0) { 1550 #ifdef D2ADEBUG 1551 cmn_err(CE_WARN, "Can't get bus number of PCI child?"); 1552 #endif 1553 map_error = 1; 1554 scanning_d2a_map = 0; 1555 d2a_done = 1; 1556 return; 1557 } 1558 1559 if (acpica_find_pcibus(bus, &acpiobj) == AE_ERROR) { 1560 #ifdef D2ADEBUG 1561 cmn_err(CE_WARN, "No ACPI bus obj for bus %d?\n", bus); 1562 #endif 1563 map_error = 1; 1564 continue; 1565 } 1566 1567 acpica_tag_devinfo(dip, acpiobj); 1568 1569 /* call recursively to enumerate subtrees */ 1570 scan_d2a_subtree(dip, acpiobj, bus); 1571 } 1572 1573 scanning_d2a_map = 0; 1574 d2a_done = 1; 1575 } 1576 1577 /* 1578 * For all acpi child devices of acpiobj, find their matching 1579 * dip under "dip" argument. (matching means "matches dev/fn"). 1580 * bus is assumed to already be a match from caller, and is 1581 * used here only to record in the d2a entry. Recurse if necessary. 1582 */ 1583 static void 1584 scan_d2a_subtree(dev_info_t *dip, ACPI_HANDLE acpiobj, int bus) 1585 { 1586 int acpi_devfn, hid; 1587 ACPI_HANDLE acld; 1588 dev_info_t *dcld; 1589 int dcld_b, dcld_d, dcld_f; 1590 int dev, func; 1591 char *device_type_prop; 1592 1593 acld = NULL; 1594 while (AcpiGetNextObject(ACPI_TYPE_DEVICE, acpiobj, acld, &acld) 1595 == AE_OK) { 1596 /* get the dev/func we're looking for in the devinfo tree */ 1597 if (acpica_eval_int(acld, "_ADR", &acpi_devfn) != AE_OK) 1598 continue; 1599 dev = (acpi_devfn >> 16) & 0xFFFF; 1600 func = acpi_devfn & 0xFFFF; 1601 1602 /* look through all the immediate children of dip */ 1603 for (dcld = ddi_get_child(dip); dcld != NULL; 1604 dcld = ddi_get_next_sibling(dcld)) { 1605 if (acpica_get_bdf(dcld, &dcld_b, &dcld_d, &dcld_f) < 0) 1606 continue; 1607 1608 /* dev must match; function must match or wildcard */ 1609 if (dcld_d != dev || 1610 (func != 0xFFFF && func != dcld_f)) 1611 continue; 1612 bus = dcld_b; 1613 1614 /* found a match, record it */ 1615 acpica_tag_devinfo(dcld, acld); 1616 1617 /* if we find a bridge, recurse from here */ 1618 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dcld, 0, 1619 "device_type", &device_type_prop) == 1620 DDI_PROP_SUCCESS) { 1621 if ((strcmp("pci", device_type_prop) == 0) || 1622 (strcmp("pciex", device_type_prop) == 0)) 1623 scan_d2a_subtree(dcld, acld, bus); 1624 ddi_prop_free(device_type_prop); 1625 } 1626 1627 /* done finding a match, so break now */ 1628 break; 1629 } 1630 } 1631 } 1632 1633 /* 1634 * Return bus/dev/fn for PCI dip (note: not the parent "pci" node). 1635 */ 1636 int 1637 acpica_get_bdf(dev_info_t *dip, int *bus, int *device, int *func) 1638 { 1639 pci_regspec_t *pci_rp; 1640 int len; 1641 1642 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 1643 "reg", (int **)&pci_rp, (uint_t *)&len) != DDI_SUCCESS) 1644 return (-1); 1645 1646 if (len < (sizeof (pci_regspec_t) / sizeof (int))) { 1647 ddi_prop_free(pci_rp); 1648 return (-1); 1649 } 1650 if (bus != NULL) 1651 *bus = (int)PCI_REG_BUS_G(pci_rp->pci_phys_hi); 1652 if (device != NULL) 1653 *device = (int)PCI_REG_DEV_G(pci_rp->pci_phys_hi); 1654 if (func != NULL) 1655 *func = (int)PCI_REG_FUNC_G(pci_rp->pci_phys_hi); 1656 ddi_prop_free(pci_rp); 1657 return (0); 1658 } 1659 1660 /* 1661 * Return the ACPI device node matching this dev_info node, if it 1662 * exists in the ACPI tree. 1663 */ 1664 ACPI_STATUS 1665 acpica_get_handle(dev_info_t *dip, ACPI_HANDLE *rh) 1666 { 1667 ACPI_STATUS status; 1668 char *acpiname; 1669 1670 if (!d2a_done) 1671 scan_d2a_map(); 1672 1673 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 1674 "acpi-namespace", &acpiname) != DDI_PROP_SUCCESS) { 1675 return (AE_ERROR); 1676 } 1677 1678 status = AcpiGetHandle(NULL, acpiname, rh); 1679 ddi_prop_free((void *)acpiname); 1680 return (status); 1681 } 1682 1683 1684 1685 /* 1686 * Manage OS data attachment to ACPI nodes 1687 */ 1688 1689 /* 1690 * Return the (dev_info_t *) associated with the ACPI node. 1691 */ 1692 ACPI_STATUS 1693 acpica_get_devinfo(ACPI_HANDLE obj, dev_info_t **dipp) 1694 { 1695 ACPI_STATUS status; 1696 void *ptr; 1697 1698 status = AcpiGetData(obj, acpica_devinfo_handler, &ptr); 1699 if (status == AE_OK) 1700 *dipp = (dev_info_t *)ptr; 1701 1702 return (status); 1703 } 1704 1705 /* 1706 * Set the dev_info_t associated with the ACPI node. 1707 */ 1708 static ACPI_STATUS 1709 acpica_set_devinfo(ACPI_HANDLE obj, dev_info_t *dip) 1710 { 1711 ACPI_STATUS status; 1712 1713 status = AcpiAttachData(obj, acpica_devinfo_handler, (void *)dip); 1714 return (status); 1715 } 1716 1717 1718 /* 1719 * 1720 */ 1721 void 1722 acpica_devinfo_handler(ACPI_HANDLE obj, UINT32 func, void *data) 1723 { 1724 /* noop */ 1725 } 1726 1727 1728 /* 1729 * 1730 */ 1731 void 1732 acpica_map_cpu(processorid_t cpuid, UINT32 proc_id) 1733 { 1734 struct cpu_map_item *item; 1735 1736 if (cpu_map == NULL) 1737 cpu_map = kmem_zalloc(sizeof (item) * NCPU, KM_SLEEP); 1738 1739 item = kmem_zalloc(sizeof (*item), KM_SLEEP); 1740 item->proc_id = proc_id; 1741 item->obj = NULL; 1742 cpu_map[cpuid] = item; 1743 cpu_map_count++; 1744 } 1745 1746 void 1747 acpica_build_processor_map() 1748 { 1749 ACPI_STATUS status; 1750 void *rv; 1751 1752 /* 1753 * shouldn't be called more than once anyway 1754 */ 1755 if (cpu_map_built) 1756 return; 1757 1758 /* 1759 * Look for Processor objects 1760 */ 1761 status = AcpiWalkNamespace(ACPI_TYPE_PROCESSOR, 1762 ACPI_ROOT_OBJECT, 1763 4, 1764 acpica_probe_processor, 1765 NULL, 1766 &rv); 1767 ASSERT(status == AE_OK); 1768 1769 /* 1770 * Look for processor Device objects 1771 */ 1772 status = AcpiGetDevices("ACPI0007", 1773 acpica_probe_processor, 1774 NULL, 1775 &rv); 1776 ASSERT(status == AE_OK); 1777 cpu_map_built = 1; 1778 } 1779 1780 void 1781 acpica_get_global_FADT(ACPI_TABLE_FADT **gbl_FADT) 1782 { 1783 *gbl_FADT = &AcpiGbl_FADT; 1784 } 1785