Module Name:    src
Committed By:   jmcneill
Date:           Mon Sep  6 15:54:27 UTC 2010

Modified Files:
        src/sys/arch/x86/x86: platform.c
        src/sys/dev/acpi: acpi.c acpi_quirks.c acpivar.h files.acpi

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.8 -r1.9 src/sys/arch/x86/x86/platform.c
cvs rdiff -u -r1.218 -r1.219 src/sys/dev/acpi/acpi.c
cvs rdiff -u -r1.17 -r1.18 src/sys/dev/acpi/acpi_quirks.c
cvs rdiff -u -r1.61 -r1.62 src/sys/dev/acpi/acpivar.h
cvs rdiff -u -r1.79 -r1.80 src/sys/dev/acpi/files.acpi

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/x86/x86/platform.c
diff -u src/sys/arch/x86/x86/platform.c:1.8 src/sys/arch/x86/x86/platform.c:1.9
--- src/sys/arch/x86/x86/platform.c:1.8	Tue Feb 17 21:15:19 2009
+++ src/sys/arch/x86/x86/platform.c	Mon Sep  6 15:54:27 2010
@@ -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 <jmcne...@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 @@
 
 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 @@
 {
 	struct smbtable smbios;
 	struct smbios_sys *psys;
+	struct smbios_struct_bios *pbios;
 	struct smbios_slot *pslot;
 	int nisa, nother;
 
@@ -63,6 +65,15 @@
 	}
 
 	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;
 	while (smbios_find_table(SMBIOS_TYPE_SLOTS, &smbios)) {
@@ -118,3 +129,46 @@
 	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);
+}

Index: src/sys/dev/acpi/acpi.c
diff -u src/sys/dev/acpi/acpi.c:1.218 src/sys/dev/acpi/acpi.c:1.219
--- src/sys/dev/acpi/acpi.c:1.218	Tue Aug 24 04:36:02 2010
+++ src/sys/dev/acpi/acpi.c	Mon Sep  6 15:54:26 2010
@@ -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 @@
 		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);
 

Index: src/sys/dev/acpi/acpi_quirks.c
diff -u src/sys/dev/acpi/acpi_quirks.c:1.17 src/sys/dev/acpi/acpi_quirks.c:1.18
--- src/sys/dev/acpi/acpi_quirks.c:1.17	Mon Sep  6 14:09:54 2010
+++ src/sys/dev/acpi/acpi_quirks.c	Mon Sep  6 15:54:27 2010
@@ -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 @@
 	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 @@
 	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);
 

Index: src/sys/dev/acpi/acpivar.h
diff -u src/sys/dev/acpi/acpivar.h:1.61 src/sys/dev/acpi/acpivar.h:1.62
--- src/sys/dev/acpi/acpivar.h:1.61	Sat Aug  7 20:07:25 2010
+++ src/sys/dev/acpi/acpivar.h	Mon Sep  6 15:54:27 2010
@@ -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 @@
 #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);
 

Index: src/sys/dev/acpi/files.acpi
diff -u src/sys/dev/acpi/files.acpi:1.79 src/sys/dev/acpi/files.acpi:1.80
--- src/sys/dev/acpi/files.acpi:1.79	Fri Aug 13 16:21:50 2010
+++ src/sys/dev/acpi/files.acpi	Mon Sep  6 15:54:27 2010
@@ -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 { }

Reply via email to