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