1 1.22 jmcneill /* $NetBSD: acpi_quirks.c,v 1.22 2020/12/06 11:38:28 jmcneill Exp $ */ 2 1.19 jruoho 3 1.19 jruoho /*- 4 1.19 jruoho * Copyright (c) 2011 The NetBSD Foundation, Inc. 5 1.19 jruoho * All rights reserved. 6 1.19 jruoho * 7 1.19 jruoho * Redistribution and use in source and binary forms, with or without 8 1.19 jruoho * modification, are permitted provided that the following conditions 9 1.19 jruoho * are met: 10 1.19 jruoho * 11 1.19 jruoho * 1. Redistributions of source code must retain the above copyright 12 1.19 jruoho * notice, this list of conditions and the following disclaimer. 13 1.19 jruoho * 2. Redistributions in binary form must reproduce the above copyright 14 1.19 jruoho * notice, this list of conditions and the following disclaimer in the 15 1.19 jruoho * documentation and/or other materials provided with the distribution. 16 1.19 jruoho * 17 1.19 jruoho * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 1.19 jruoho * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 1.19 jruoho * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 1.19 jruoho * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 1.19 jruoho * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 1.19 jruoho * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 1.19 jruoho * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 1.19 jruoho * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 1.19 jruoho * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 1.19 jruoho * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 1.19 jruoho * SUCH DAMAGE. 28 1.19 jruoho */ 29 1.1 fvdl 30 1.1 fvdl /* 31 1.1 fvdl * Copyright 2002 Wasabi Systems, Inc. 32 1.1 fvdl * All rights reserved. 33 1.1 fvdl * 34 1.1 fvdl * Written by Frank van der Linden for Wasabi Systems, Inc. 35 1.1 fvdl * 36 1.1 fvdl * Redistribution and use in source and binary forms, with or without 37 1.1 fvdl * modification, are permitted provided that the following conditions 38 1.1 fvdl * are met: 39 1.1 fvdl * 1. Redistributions of source code must retain the above copyright 40 1.1 fvdl * notice, this list of conditions and the following disclaimer. 41 1.1 fvdl * 2. Redistributions in binary form must reproduce the above copyright 42 1.1 fvdl * notice, this list of conditions and the following disclaimer in the 43 1.1 fvdl * documentation and/or other materials provided with the distribution. 44 1.1 fvdl * 3. All advertising materials mentioning features or use of this software 45 1.1 fvdl * must display the following acknowledgement: 46 1.1 fvdl * This product includes software developed for the NetBSD Project by 47 1.1 fvdl * Wasabi Systems, Inc. 48 1.1 fvdl * 4. The name of Wasabi Systems, Inc. may not be used to endorse 49 1.1 fvdl * or promote products derived from this software without specific prior 50 1.1 fvdl * written permission. 51 1.1 fvdl * 52 1.1 fvdl * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 53 1.1 fvdl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 54 1.1 fvdl * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 55 1.1 fvdl * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 56 1.1 fvdl * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 57 1.1 fvdl * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 58 1.1 fvdl * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 59 1.1 fvdl * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 60 1.1 fvdl * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 61 1.1 fvdl * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 62 1.1 fvdl * POSSIBILITY OF SUCH DAMAGE. 63 1.1 fvdl */ 64 1.1 fvdl 65 1.1 fvdl #include <sys/cdefs.h> 66 1.1 fvdl 67 1.22 jmcneill __KERNEL_RCSID(0, "$NetBSD: acpi_quirks.c,v 1.22 2020/12/06 11:38:28 jmcneill Exp $"); 68 1.1 fvdl 69 1.1 fvdl #include "opt_acpi.h" 70 1.1 fvdl 71 1.1 fvdl #include <sys/param.h> 72 1.1 fvdl 73 1.19 jruoho #include <dev/acpi/acpireg.h> 74 1.1 fvdl #include <dev/acpi/acpivar.h> 75 1.1 fvdl 76 1.19 jruoho #define _COMPONENT ACPI_UTILITIES 77 1.19 jruoho ACPI_MODULE_NAME ("acpi_quirks") 78 1.19 jruoho 79 1.12 jruoho #define AQ_GT 0 /* > */ 80 1.12 jruoho #define AQ_LT 1 /* < */ 81 1.12 jruoho #define AQ_GTE 2 /* >= */ 82 1.12 jruoho #define AQ_LTE 3 /* <= */ 83 1.12 jruoho #define AQ_EQ 4 /* == */ 84 1.12 jruoho 85 1.19 jruoho static int acpi_quirks_revcmp(uint32_t, uint32_t, int); 86 1.7 christos 87 1.21 jdolecek static const struct acpi_quirk acpi_quirks[] = { 88 1.13 jruoho 89 1.13 jruoho { ACPI_SIG_FADT, "ASUS ", 0x30303031, AQ_LTE, "CUV4X-D ", 90 1.13 jruoho ACPI_QUIRK_BROKEN }, 91 1.13 jruoho 92 1.9 jmcneill { ACPI_SIG_FADT, "PTLTD ", 0x06040000, AQ_LTE, " FACP ", 93 1.7 christos ACPI_QUIRK_BROKEN }, 94 1.13 jruoho 95 1.9 jmcneill { ACPI_SIG_FADT, "NVIDIA", 0x06040000, AQ_EQ, "CK8 ", 96 1.8 fvdl ACPI_QUIRK_IRQ0 }, 97 1.13 jruoho 98 1.10 christos { ACPI_SIG_FADT, "HP ", 0x06040012, AQ_LTE, "HWPC20F ", 99 1.10 christos ACPI_QUIRK_BROKEN }, 100 1.1 fvdl }; 101 1.1 fvdl 102 1.7 christos static int 103 1.19 jruoho acpi_quirks_revcmp(uint32_t tabval, uint32_t wanted, int op) 104 1.7 christos { 105 1.19 jruoho 106 1.7 christos switch (op) { 107 1.19 jruoho 108 1.7 christos case AQ_GT: 109 1.19 jruoho return (tabval > wanted) ? 0 : 1; 110 1.19 jruoho 111 1.7 christos case AQ_LT: 112 1.19 jruoho return (tabval < wanted) ? 0 : 1; 113 1.19 jruoho 114 1.7 christos case AQ_LTE: 115 1.19 jruoho return (tabval <= wanted) ? 0 : 1; 116 1.19 jruoho 117 1.7 christos case AQ_GTE: 118 1.19 jruoho return (tabval >= wanted) ? 0 : 1; 119 1.19 jruoho 120 1.7 christos case AQ_EQ: 121 1.19 jruoho return (tabval == wanted) ? 0 : 1; 122 1.19 jruoho 123 1.19 jruoho default: 124 1.19 jruoho return 1; 125 1.7 christos } 126 1.7 christos } 127 1.7 christos 128 1.18 jmcneill #ifdef ACPI_BLACKLIST_YEAR 129 1.18 jmcneill static int 130 1.19 jruoho acpi_quirks_bios_year(void) 131 1.18 jmcneill { 132 1.20 jmcneill const char *datestr = pmf_get_platform("bios-date"); 133 1.18 jmcneill unsigned long date; 134 1.18 jmcneill 135 1.18 jmcneill if (datestr == NULL) 136 1.18 jmcneill return -1; 137 1.18 jmcneill 138 1.18 jmcneill date = strtoul(datestr, NULL, 10); 139 1.18 jmcneill if (date == 0 || date == ULONG_MAX) 140 1.18 jmcneill return -1; 141 1.18 jmcneill if (date < 19000000 || date > 99999999) 142 1.18 jmcneill return -1; 143 1.18 jmcneill return date / 10000; 144 1.18 jmcneill } 145 1.18 jmcneill #endif 146 1.18 jmcneill 147 1.1 fvdl /* 148 1.19 jruoho * Simple function to search the quirk table. Only to be 149 1.19 jruoho * used after AcpiLoadTables() has been successfully called. 150 1.1 fvdl */ 151 1.1 fvdl int 152 1.1 fvdl acpi_find_quirks(void) 153 1.1 fvdl { 154 1.9 jmcneill ACPI_TABLE_HEADER fadt, dsdt, xsdt, *hdr; 155 1.21 jdolecek const struct acpi_quirk *aq; 156 1.19 jruoho ACPI_STATUS rv; 157 1.19 jruoho size_t i, len; 158 1.19 jruoho 159 1.18 jmcneill #ifdef ACPI_BLACKLIST_YEAR 160 1.19 jruoho int year = acpi_quirks_bios_year(); 161 1.18 jmcneill 162 1.18 jmcneill if (year != -1 && year <= ACPI_BLACKLIST_YEAR) 163 1.18 jmcneill return ACPI_QUIRK_OLDBIOS; 164 1.18 jmcneill #endif 165 1.1 fvdl 166 1.19 jruoho rv = AcpiGetTableHeader(ACPI_SIG_FADT, 0, &fadt); 167 1.19 jruoho 168 1.19 jruoho if (ACPI_FAILURE(rv)) 169 1.19 jruoho (void)memset(&fadt, 0, sizeof(fadt)); 170 1.19 jruoho 171 1.19 jruoho rv = AcpiGetTableHeader(ACPI_SIG_DSDT, 0, &dsdt); 172 1.19 jruoho 173 1.19 jruoho if (ACPI_FAILURE(rv)) 174 1.19 jruoho (void)memset(&dsdt, 0, sizeof(dsdt)); 175 1.19 jruoho 176 1.19 jruoho rv = AcpiGetTableHeader(ACPI_SIG_XSDT, 0, &xsdt); 177 1.19 jruoho 178 1.19 jruoho if (ACPI_FAILURE(rv)) 179 1.19 jruoho (void)memset(&xsdt, 0, sizeof(xsdt)); 180 1.19 jruoho 181 1.19 jruoho for (i = 0; i < __arraycount(acpi_quirks); i++) { 182 1.19 jruoho 183 1.19 jruoho aq = &acpi_quirks[i]; 184 1.1 fvdl 185 1.19 jruoho if (strncmp(aq->aq_tabletype, ACPI_SIG_DSDT, 4) == 0) 186 1.9 jmcneill hdr = &dsdt; 187 1.19 jruoho else if (strncmp(aq->aq_tabletype, ACPI_SIG_XSDT, 4) == 0) 188 1.9 jmcneill hdr = &xsdt; 189 1.19 jruoho else if (strncmp(aq->aq_tabletype, ACPI_SIG_FADT, 4) == 0) 190 1.9 jmcneill hdr = &fadt; 191 1.19 jruoho else { 192 1.7 christos continue; 193 1.19 jruoho } 194 1.19 jruoho 195 1.19 jruoho len = strlen(aq->aq_oemid); 196 1.19 jruoho 197 1.19 jruoho if (strncmp(aq->aq_oemid, hdr->OemId, len) != 0) 198 1.7 christos continue; 199 1.19 jruoho 200 1.19 jruoho if (acpi_quirks_revcmp(aq->aq_oemrev, 201 1.19 jruoho hdr->OemRevision, aq->aq_cmpop) != 0) 202 1.7 christos continue; 203 1.19 jruoho 204 1.19 jruoho len = strlen(aq->aq_tabid); 205 1.19 jruoho 206 1.19 jruoho if (strncmp(aq->aq_tabid, hdr->OemTableId, len) != 0) 207 1.7 christos continue; 208 1.19 jruoho 209 1.19 jruoho return aq->aq_quirks; 210 1.1 fvdl } 211 1.19 jruoho 212 1.1 fvdl return 0; 213 1.1 fvdl } 214