Add support for blacklisting ACPI BIOS implementations by year. By default,

don't use ACPI on BIOS which advertise release years <= 2000. This
can be changed by setting option ACPI_BLACKLIST_YEAR=0 or by setting
acpi_force_load=1.
This commit is contained in:
jmcneill 2010-09-06 15:54:26 +00:00
parent 192b53ec54
commit eb0e82d870
5 changed files with 96 additions and 8 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: platform.c,v 1.8 2009/02/17 21:15:19 ad Exp $ */
/* $NetBSD: platform.c,v 1.9 2010/09/06 15:54:27 jmcneill Exp $ */
/*-
* Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca>
@ -29,7 +29,7 @@
#include "isa.h"
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: platform.c,v 1.8 2009/02/17 21:15:19 ad Exp $");
__KERNEL_RCSID(0, "$NetBSD: platform.c,v 1.9 2010/09/06 15:54:27 jmcneill Exp $");
#include <sys/types.h>
#include <sys/param.h>
@ -42,6 +42,7 @@ __KERNEL_RCSID(0, "$NetBSD: platform.c,v 1.8 2009/02/17 21:15:19 ad Exp $");
void platform_init(void); /* XXX */
static void platform_add(struct smbtable *, const char *, int);
static void platform_add_date(struct smbtable *, const char *, int);
static void platform_print(void);
void
@ -49,6 +50,7 @@ platform_init(void)
{
struct smbtable smbios;
struct smbios_sys *psys;
struct smbios_struct_bios *pbios;
struct smbios_slot *pslot;
int nisa, nother;
@ -62,6 +64,15 @@ platform_init(void)
platform_add(&smbios, "system-serial-number", psys->serial);
}
smbios.cookie = 0;
if (smbios_find_table(SMBIOS_TYPE_BIOS, &smbios)) {
pbios = smbios.tblhdr;
platform_add(&smbios, "firmware-vendor", pbios->vendor);
platform_add(&smbios, "firmware-version", pbios->version);
platform_add_date(&smbios, "firmware-date", pbios->release);
}
smbios.cookie = 0;
nisa = 0;
nother = 0;
@ -118,3 +129,46 @@ platform_add(struct smbtable *tbl, const char *key, int idx)
if (smbios_get_string(tbl, idx, tmpbuf, 128) != NULL)
pmf_set_platform(key, tmpbuf);
}
static int
platform_scan_date(char *buf, unsigned int *month, unsigned int *day,
unsigned int *year)
{
char *p, *s;
s = buf;
p = strchr(s, '/');
if (p) *p = '\0';
*month = strtoul(s, NULL, 10);
if (!p) return 1;
s = p + 1;
p = strchr(s, '/');
if (p) *p = '\0';
*day = strtoul(s, NULL, 10);
if (!p) return 2;
s = p + 1;
*year = strtoul(s, NULL, 10);
return 3;
}
static void
platform_add_date(struct smbtable *tbl, const char *key, int idx)
{
unsigned int month, day, year;
char tmpbuf[128], datestr[9];
if (smbios_get_string(tbl, idx, tmpbuf, 128) == NULL)
return;
if (platform_scan_date(tmpbuf, &month, &day, &year) != 3)
return;
if (month == 0 || month > 12 || day == 0 || day > 31)
return;
if (year < 100)
year += 1900;
if (year > 9999)
return;
sprintf(datestr, "%04u%02u%02u", year, month, day);
pmf_set_platform(key, datestr);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: acpi.c,v 1.218 2010/08/24 04:36:02 pgoyette Exp $ */
/* $NetBSD: acpi.c,v 1.219 2010/09/06 15:54:26 jmcneill Exp $ */
/*-
* Copyright (c) 2003, 2007 The NetBSD Foundation, Inc.
@ -100,7 +100,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.218 2010/08/24 04:36:02 pgoyette Exp $");
__KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.219 2010/09/06 15:54:26 jmcneill Exp $");
#include "opt_acpi.h"
#include "opt_pcifixup.h"
@ -333,6 +333,13 @@ acpi_probe(void)
AcpiTerminate();
return 0;
}
if (acpi_force_load == 0 && (acpi_find_quirks() & ACPI_QUIRK_OLDBIOS)) {
aprint_normal("ACPI: BIOS is too old (%s). Set acpi_force_load to use.\n",
pmf_get_platform("firmware-date"));
acpi_unmap_rsdt(rsdt);
AcpiTerminate();
return 0;
}
acpi_unmap_rsdt(rsdt);

View File

@ -1,4 +1,4 @@
/* $NetBSD: acpi_quirks.c,v 1.17 2010/09/06 14:09:54 jakllsch Exp $ */
/* $NetBSD: acpi_quirks.c,v 1.18 2010/09/06 15:54:27 jmcneill Exp $ */
/*
* Copyright 2002 Wasabi Systems, Inc.
@ -37,7 +37,7 @@
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: acpi_quirks.c,v 1.17 2010/09/06 14:09:54 jakllsch Exp $");
__KERNEL_RCSID(0, "$NetBSD: acpi_quirks.c,v 1.18 2010/09/06 15:54:27 jmcneill Exp $");
#include "opt_acpi.h"
@ -106,6 +106,25 @@ acpi_rev_cmp(uint32_t tabval, uint32_t wanted, int op)
return 1;
}
#ifdef ACPI_BLACKLIST_YEAR
static int
acpi_find_bios_year(void)
{
const char *datestr = pmf_get_platform("firmware-date");
unsigned long date;
if (datestr == NULL)
return -1;
date = strtoul(datestr, NULL, 10);
if (date == 0 || date == ULONG_MAX)
return -1;
if (date < 19000000 || date > 99999999)
return -1;
return date / 10000;
}
#endif
/*
* Simple function to search the quirk table. Only to be used after
* AcpiLoadTables has been successfully called.
@ -116,6 +135,12 @@ acpi_find_quirks(void)
int i, nquirks;
struct acpi_quirk *aqp;
ACPI_TABLE_HEADER fadt, dsdt, xsdt, *hdr;
#ifdef ACPI_BLACKLIST_YEAR
int year = acpi_find_bios_year();
if (year != -1 && year <= ACPI_BLACKLIST_YEAR)
return ACPI_QUIRK_OLDBIOS;
#endif
nquirks = __arraycount(acpi_quirks);

View File

@ -1,4 +1,4 @@
/* $NetBSD: acpivar.h,v 1.61 2010/08/07 20:07:25 jruoho Exp $ */
/* $NetBSD: acpivar.h,v 1.62 2010/09/06 15:54:27 jmcneill Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@ -328,6 +328,7 @@ struct acpi_quirk {
#define ACPI_QUIRK_BADPCI 0x00000002 /* bad PCI hierarchy */
#define ACPI_QUIRK_BADBBN 0x00000004 /* _BBN broken */
#define ACPI_QUIRK_IRQ0 0x00000008 /* bad 0->2 irq override */
#define ACPI_QUIRK_OLDBIOS 0x00000010 /* BIOS date blacklisted */
int acpi_find_quirks(void);

View File

@ -1,10 +1,11 @@
# $NetBSD: files.acpi,v 1.79 2010/08/13 16:21:50 jruoho Exp $
# $NetBSD: files.acpi,v 1.80 2010/09/06 15:54:27 jmcneill Exp $
include "dev/acpi/acpica/files.acpica"
defflag opt_acpi.h ACPIVERBOSE ACPI_DEBUG ACPI_ACTIVATE_DEV
ACPI_DSDT_OVERRIDE ACPI_SCANPCI ACPI_BREAKPOINT
defparam opt_acpi.h ACPI_DSDT_FILE := "\"/dev/null\""
defparam opt_acpi.h ACPI_BLACKLIST_YEAR = 2000
define acpiapmbus { }
define acpinodebus { }