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