Print this page
acpica-unix2-20130823
PANKOVs restructure


   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  * Copyright 2011 Joyent, Inc.  All rights reserved.


  26  */

  27 /*
  28  * Copyright (c) 2009-2010, Intel Corporation.
  29  * All rights reserved.
  30  */

  31 /*
  32  * ACPI CA OSL for Solaris x86
  33  */
  34 
  35 #include <sys/types.h>
  36 #include <sys/kmem.h>
  37 #include <sys/psm.h>
  38 #include <sys/pci_cfgspace.h>
  39 #include <sys/apic.h>
  40 #include <sys/ddi.h>
  41 #include <sys/sunddi.h>
  42 #include <sys/sunndi.h>
  43 #include <sys/pci.h>
  44 #include <sys/kobj.h>
  45 #include <sys/taskq.h>
  46 #include <sys/strlog.h>
  47 #include <sys/x86_archext.h>
  48 #include <sys/note.h>
  49 #include <sys/promif.h>
  50 
  51 #include <sys/acpi/accommon.h>
  52 #include <sys/acpica.h>
  53 
  54 #define MAX_DAT_FILE_SIZE       (64*1024)
  55 
  56 /* local functions */
  57 static int CompressEisaID(char *np);
  58 
  59 static void scan_d2a_subtree(dev_info_t *dip, ACPI_HANDLE acpiobj, int bus);
  60 static int acpica_query_bbn_problem(void);
  61 static int acpica_find_pcibus(int busno, ACPI_HANDLE *rh);
  62 static int acpica_eval_hid(ACPI_HANDLE dev, char *method, int *rint);
  63 static ACPI_STATUS acpica_set_devinfo(ACPI_HANDLE, dev_info_t *);
  64 static ACPI_STATUS acpica_unset_devinfo(ACPI_HANDLE);
  65 static void acpica_devinfo_handler(ACPI_HANDLE, void *);
  66 
  67 /*
  68  * Event queue vars
  69  */
  70 int acpica_eventq_init = 0;
  71 ddi_taskq_t *osl_eventq[OSL_EC_BURST_HANDLER+1];


 298                 buf1 = (char *)kmem_alloc(MAX_DAT_FILE_SIZE, KM_SLEEP);
 299                 count = kobj_read_file(file, buf1, MAX_DAT_FILE_SIZE-1, 0);
 300                 if (count >= MAX_DAT_FILE_SIZE) {
 301                         cmn_err(CE_WARN, "!acpica: table %s file size too big",
 302                             acpi_table_loc);
 303                         *NewTable = 0;
 304                 } else {
 305                         buf2 = (char *)kmem_alloc(count, KM_SLEEP);
 306                         (void) memcpy(buf2, buf1, count);
 307                         *NewTable = (ACPI_TABLE_HEADER *)buf2;
 308                         cmn_err(CE_NOTE, "!acpica: replacing table: %s",
 309                             acpi_table_loc);
 310                 }
 311         }
 312         kobj_close_file(file);
 313         kmem_free(buf1, MAX_DAT_FILE_SIZE);
 314 
 315         return (AE_OK);
 316 }
 317 






 318 
 319 /*
 320  * ACPI semaphore implementation
 321  */
 322 typedef struct {
 323         kmutex_t        mutex;
 324         kcondvar_t      cv;
 325         uint32_t        available;
 326         uint32_t        initial;
 327         uint32_t        maximum;
 328 } acpi_sema_t;
 329 
 330 /*
 331  *
 332  */
 333 void
 334 acpi_sema_init(acpi_sema_t *sp, unsigned max, unsigned count)
 335 {
 336         mutex_init(&sp->mutex, NULL, MUTEX_DRIVER, NULL);
 337         cv_init(&sp->cv, NULL, CV_DRIVER, NULL);


 727         if (!acpica_eventq_init) {
 728                 /*
 729                  * Create taskqs for event handling
 730                  */
 731                 if (init_event_queues() != AE_OK)
 732                         return (AE_ERROR);
 733         }
 734 
 735         if (ddi_taskq_dispatch(osl_eventq[Type], Function, Context,
 736             DDI_NOSLEEP) == DDI_FAILURE) {
 737 #ifdef  DEBUG
 738                 cmn_err(CE_WARN, "!acpica: unable to dispatch event");
 739 #endif
 740                 return (AE_ERROR);
 741         }
 742         return (AE_OK);
 743 
 744 }
 745 
 746 void
















 747 AcpiOsSleep(ACPI_INTEGER Milliseconds)
 748 {
 749         /*
 750          * During kernel startup, before the first tick interrupt
 751          * has taken place, we can't call delay; very late in
 752          * kernel shutdown or suspend/resume, clock interrupts
 753          * are blocked, so delay doesn't work then either.
 754          * So we busy wait if lbolt == 0 (kernel startup)
 755          * or if acpica_use_safe_delay has been set to a
 756          * non-zero value.
 757          */
 758         if ((ddi_get_lbolt() == 0) || acpica_use_safe_delay)
 759                 drv_usecwait(Milliseconds * 1000);
 760         else
 761                 delay(drv_usectohz(Milliseconds * 1000));
 762 }
 763 
 764 void
 765 AcpiOsStall(UINT32 Microseconds)
 766 {


 866                 break;
 867         default:
 868                 cmn_err(CE_WARN, "!AcpiOsWritePort: %lx %u failed",
 869                     (long)Address, Width);
 870                 return (AE_BAD_PARAMETER);
 871         }
 872         return (AE_OK);
 873 }
 874 
 875 
 876 /*
 877  *
 878  */
 879 
 880 #define OSL_RW(ptr, val, type, rw) \
 881         { if (rw) *((type *)(ptr)) = *((type *) val); \
 882             else *((type *) val) = *((type *)(ptr)); }
 883 
 884 
 885 static void
 886 osl_rw_memory(ACPI_PHYSICAL_ADDRESS Address, UINT32 *Value,
 887     UINT32 Width, int write)
 888 {
 889         size_t  maplen = Width / 8;
 890         caddr_t ptr;
 891 
 892         ptr = psm_map_new((paddr_t)Address, maplen,
 893             PSM_PROT_WRITE | PSM_PROT_READ);
 894 
 895         switch (maplen) {
 896         case 1:
 897                 OSL_RW(ptr, Value, uint8_t, write);
 898                 break;
 899         case 2:
 900                 OSL_RW(ptr, Value, uint16_t, write);
 901                 break;
 902         case 4:
 903                 OSL_RW(ptr, Value, uint32_t, write);
 904                 break;



 905         default:
 906                 cmn_err(CE_WARN, "!osl_rw_memory: invalid size %d",
 907                     Width);
 908                 break;
 909         }
 910 
 911         psm_unmap(ptr, maplen);
 912 }
 913 
 914 ACPI_STATUS
 915 AcpiOsReadMemory(ACPI_PHYSICAL_ADDRESS Address,
 916                 UINT32 *Value, UINT32 Width)
 917 {
 918         osl_rw_memory(Address, Value, Width, 0);
 919         return (AE_OK);
 920 }
 921 
 922 ACPI_STATUS
 923 AcpiOsWriteMemory(ACPI_PHYSICAL_ADDRESS Address,
 924                 UINT32 Value, UINT32 Width)
 925 {
 926         osl_rw_memory(Address, &Value, Width, 1);
 927         return (AE_OK);
 928 }
 929 
 930 
 931 ACPI_STATUS
 932 AcpiOsReadPciConfiguration(ACPI_PCI_ID *PciId, UINT32 Reg,
 933                 UINT64 *Value, UINT32 Width)
 934 {
 935 
 936         switch (Width) {
 937         case 8:
 938                 *Value = (UINT64)(*pci_getb_func)
 939                     (PciId->Bus, PciId->Device, PciId->Function, Reg);
 940                 break;
 941         case 16:
 942                 *Value = (UINT64)(*pci_getw_func)
 943                     (PciId->Bus, PciId->Device, PciId->Function, Reg);
 944                 break;




   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  * Copyright 2012 Joyent, Inc.  All rights reserved.
  26  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  27  * Copyright 2013 PALO, Richard. All rights reserved.
  28  */
  29 
  30 /*
  31  * Copyright (c) 2009-2010, Intel Corporation.
  32  * All rights reserved.
  33  */
  34 
  35 /*
  36  * x86 ACPI CA OSL
  37  */
  38 
  39 #include <sys/types.h>
  40 #include <sys/kmem.h>
  41 #include <sys/psm.h>
  42 #include <sys/pci_cfgspace.h>
  43 #include <sys/apic.h>
  44 #include <sys/ddi.h>
  45 #include <sys/sunddi.h>
  46 #include <sys/sunndi.h>
  47 #include <sys/pci.h>
  48 #include <sys/kobj.h>
  49 #include <sys/taskq.h>
  50 #include <sys/strlog.h>
  51 #include <sys/x86_archext.h>
  52 #include <sys/note.h>
  53 #include <sys/promif.h>
  54 
  55 #include <acpica/include/accommon.h>
  56 #include <sys/acpica.h>
  57 
  58 #define MAX_DAT_FILE_SIZE       (64*1024)
  59 
  60 /* local functions */
  61 static int CompressEisaID(char *np);
  62 
  63 static void scan_d2a_subtree(dev_info_t *dip, ACPI_HANDLE acpiobj, int bus);
  64 static int acpica_query_bbn_problem(void);
  65 static int acpica_find_pcibus(int busno, ACPI_HANDLE *rh);
  66 static int acpica_eval_hid(ACPI_HANDLE dev, char *method, int *rint);
  67 static ACPI_STATUS acpica_set_devinfo(ACPI_HANDLE, dev_info_t *);
  68 static ACPI_STATUS acpica_unset_devinfo(ACPI_HANDLE);
  69 static void acpica_devinfo_handler(ACPI_HANDLE, void *);
  70 
  71 /*
  72  * Event queue vars
  73  */
  74 int acpica_eventq_init = 0;
  75 ddi_taskq_t *osl_eventq[OSL_EC_BURST_HANDLER+1];


 302                 buf1 = (char *)kmem_alloc(MAX_DAT_FILE_SIZE, KM_SLEEP);
 303                 count = kobj_read_file(file, buf1, MAX_DAT_FILE_SIZE-1, 0);
 304                 if (count >= MAX_DAT_FILE_SIZE) {
 305                         cmn_err(CE_WARN, "!acpica: table %s file size too big",
 306                             acpi_table_loc);
 307                         *NewTable = 0;
 308                 } else {
 309                         buf2 = (char *)kmem_alloc(count, KM_SLEEP);
 310                         (void) memcpy(buf2, buf1, count);
 311                         *NewTable = (ACPI_TABLE_HEADER *)buf2;
 312                         cmn_err(CE_NOTE, "!acpica: replacing table: %s",
 313                             acpi_table_loc);
 314                 }
 315         }
 316         kobj_close_file(file);
 317         kmem_free(buf1, MAX_DAT_FILE_SIZE);
 318 
 319         return (AE_OK);
 320 }
 321 
 322 ACPI_STATUS
 323 AcpiOsPhysicalTableOverride(ACPI_TABLE_HEADER *ExistingTable,
 324     ACPI_PHYSICAL_ADDRESS *NewAddress, UINT32 *NewTableLength)
 325 {
 326         return (AE_SUPPORT);
 327 }
 328 
 329 /*
 330  * ACPI semaphore implementation
 331  */
 332 typedef struct {
 333         kmutex_t        mutex;
 334         kcondvar_t      cv;
 335         uint32_t        available;
 336         uint32_t        initial;
 337         uint32_t        maximum;
 338 } acpi_sema_t;
 339 
 340 /*
 341  *
 342  */
 343 void
 344 acpi_sema_init(acpi_sema_t *sp, unsigned max, unsigned count)
 345 {
 346         mutex_init(&sp->mutex, NULL, MUTEX_DRIVER, NULL);
 347         cv_init(&sp->cv, NULL, CV_DRIVER, NULL);


 737         if (!acpica_eventq_init) {
 738                 /*
 739                  * Create taskqs for event handling
 740                  */
 741                 if (init_event_queues() != AE_OK)
 742                         return (AE_ERROR);
 743         }
 744 
 745         if (ddi_taskq_dispatch(osl_eventq[Type], Function, Context,
 746             DDI_NOSLEEP) == DDI_FAILURE) {
 747 #ifdef  DEBUG
 748                 cmn_err(CE_WARN, "!acpica: unable to dispatch event");
 749 #endif
 750                 return (AE_ERROR);
 751         }
 752         return (AE_OK);
 753 
 754 }
 755 
 756 void
 757 AcpiOsWaitEventsComplete (void)
 758 {
 759         if (acpica_eventq_init) {
 760                 int     i;
 761                 /*
 762                  * blocks until all events initiated by AcpiOsExecute have completed
 763                  */
 764                 for (i = OSL_GLOBAL_LOCK_HANDLER; i <= OSL_EC_BURST_HANDLER; i++) {
 765                         if (osl_eventq[i])
 766                                 ddi_taskq_wait(osl_eventq[i]);
 767                 }
 768         }
 769     return;
 770 }
 771 
 772 void
 773 AcpiOsSleep(ACPI_INTEGER Milliseconds)
 774 {
 775         /*
 776          * During kernel startup, before the first tick interrupt
 777          * has taken place, we can't call delay; very late in
 778          * kernel shutdown or suspend/resume, clock interrupts
 779          * are blocked, so delay doesn't work then either.
 780          * So we busy wait if lbolt == 0 (kernel startup)
 781          * or if acpica_use_safe_delay has been set to a
 782          * non-zero value.
 783          */
 784         if ((ddi_get_lbolt() == 0) || acpica_use_safe_delay)
 785                 drv_usecwait(Milliseconds * 1000);
 786         else
 787                 delay(drv_usectohz(Milliseconds * 1000));
 788 }
 789 
 790 void
 791 AcpiOsStall(UINT32 Microseconds)
 792 {


 892                 break;
 893         default:
 894                 cmn_err(CE_WARN, "!AcpiOsWritePort: %lx %u failed",
 895                     (long)Address, Width);
 896                 return (AE_BAD_PARAMETER);
 897         }
 898         return (AE_OK);
 899 }
 900 
 901 
 902 /*
 903  *
 904  */
 905 
 906 #define OSL_RW(ptr, val, type, rw) \
 907         { if (rw) *((type *)(ptr)) = *((type *) val); \
 908             else *((type *) val) = *((type *)(ptr)); }
 909 
 910 
 911 static void
 912 osl_rw_memory(ACPI_PHYSICAL_ADDRESS Address, UINT64 *Value,
 913     UINT32 Width, int write)
 914 {
 915         size_t  maplen = Width / 8;
 916         caddr_t ptr;
 917 
 918         ptr = psm_map_new((paddr_t)Address, maplen,
 919             PSM_PROT_WRITE | PSM_PROT_READ);
 920 
 921         switch (maplen) {
 922         case 1:
 923                 OSL_RW(ptr, Value, uint8_t, write);
 924                 break;
 925         case 2:
 926                 OSL_RW(ptr, Value, uint16_t, write);
 927                 break;
 928         case 4:
 929                 OSL_RW(ptr, Value, uint32_t, write);
 930                 break;
 931         case 8:
 932                 OSL_RW(ptr, Value, uint64_t, write);
 933                 break;
 934         default:
 935                 cmn_err(CE_WARN, "!osl_rw_memory: invalid size %d",
 936                     Width);
 937                 break;
 938         }
 939 
 940         psm_unmap(ptr, maplen);
 941 }
 942 
 943 ACPI_STATUS
 944 AcpiOsReadMemory(ACPI_PHYSICAL_ADDRESS Address,
 945                 UINT64 *Value, UINT32 Width)
 946 {
 947         osl_rw_memory(Address, Value, Width, 0);
 948         return (AE_OK);
 949 }
 950 
 951 ACPI_STATUS
 952 AcpiOsWriteMemory(ACPI_PHYSICAL_ADDRESS Address,
 953                 UINT64 Value, UINT32 Width)
 954 {
 955         osl_rw_memory(Address, &Value, Width, 1);
 956         return (AE_OK);
 957 }
 958 
 959 
 960 ACPI_STATUS
 961 AcpiOsReadPciConfiguration(ACPI_PCI_ID *PciId, UINT32 Reg,
 962                 UINT64 *Value, UINT32 Width)
 963 {
 964 
 965         switch (Width) {
 966         case 8:
 967                 *Value = (UINT64)(*pci_getb_func)
 968                     (PciId->Bus, PciId->Device, PciId->Function, Reg);
 969                 break;
 970         case 16:
 971                 *Value = (UINT64)(*pci_getw_func)
 972                     (PciId->Bus, PciId->Device, PciId->Function, Reg);
 973                 break;