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