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;
|