[patch] acpidump

Alex Vasylenko lxv at omut.org
Sat Apr 17 20:39:24 PDT 2004


hi,

I've upgraded a system from RELENG_5_2 to CURRENT and 'acpidump -d' broke.

As you can see in the backtrace below we get into dsdt_from_fadt with 
uninitialized fadt_revision which is handled as rev 2. Apparently my 
system has 32-bit DSTD address, so we crash. Please consider attached 
patch (it moves FADT revision detection code into a function and makes 
all users of fadt_revision call that function to get the revision)

(gdb) run -d
Starting program: /usr/obj/usr/src/usr.sbin/acpi/acpidump/acpidump -d

Program received signal SIGSEGV, Segmentation fault.
acpi_checksum (p=0x28145449, length=4294964295) at 
/usr/src/usr.sbin/acpi/acpidump/acpi.c:606
606			sum += *bp++;
(gdb) bt
#0  acpi_checksum (p=0x28145449, length=4294964295) at 
/usr/src/usr.sbin/acpi/acpidump/acpi.c:606
#1  0x0804a475 in dsdt_from_fadt (fadt=0x28145449) at 
/usr/src/usr.sbin/acpi/acpidump/acpi.c:814
#2  0x0804a9d0 in main (argc=2, argv=0xbfbfe99c) at 
/usr/src/usr.sbin/acpi/acpidump/acpidump.c:119
#3  0x08048a9a in _start ()
(gdb) frame 1
#1  0x0804a475 in dsdt_from_fadt (fadt=0x28145449) at 
/usr/src/usr.sbin/acpi/acpidump/acpi.c:814
814		if (acpi_checksum(sdt, sdt->len))
(gdb) l
809		/* Use the DSDT address if it is version 1, otherwise use X_DSDT. */
810		if (fadt_revision == 1)
811			sdt = (struct ACPIsdt *)acpi_map_sdt(fadt->dsdt_ptr);
812		else
813			sdt = (struct ACPIsdt *)acpi_map_sdt(fadt->x_dsdt_ptr);
814		if (acpi_checksum(sdt, sdt->len))
815			errx(1, "DSDT is corrupt\n");
816		return (sdt);
817	}
(gdb) print fadt_revision
$1 = 0

thanks,
--
Alex.
-------------- next part --------------
Index: acpi.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/acpi/acpidump/acpi.c,v
retrieving revision 1.22
diff -u -r1.22 acpi.c
--- acpi.c	4 Jan 2004 22:27:53 -0000	1.22
+++ acpi.c	18 Apr 2004 02:50:15 -0000
@@ -67,9 +67,6 @@
 /* Size of an address. 32-bit for ACPI 1.0, 64-bit for ACPI 2.0 and up. */
 static int addr_size;
 
-/* The FADT revision indicates whether we use the DSDT or X_DSDT addresses. */
-static int fadt_revision;
-
 static void
 acpi_print_string(char *s, size_t length)
 {
@@ -118,11 +115,11 @@
 	}
 }
 
-static void
-acpi_handle_fadt(struct FADTbody *fadt)
+/* The FADT revision indicates whether we use the DSDT or X_DSDT addresses. */
+static int
+acpi_get_fadt_revision(struct FADTbody *fadt)
 {
-	struct ACPIsdt	*dsdp;
-	struct FACSbody	*facs;
+	int fadt_revision;
 
 	/* Set the FADT revision separately from the RSDP version. */
 	if (addr_size == 8) {
@@ -141,8 +138,19 @@
 	} else {
 		fadt_revision = 1;
 	}
+	return (fadt_revision);
+}
+
+static void
+acpi_handle_fadt(struct FADTbody *fadt)
+{
+	struct ACPIsdt	*dsdp;
+	struct FACSbody	*facs;
+	int              fadt_revision;
+
 	acpi_print_fadt(fadt);
 
+	fadt_revision = acpi_get_fadt_revision(fadt);
 	if (fadt_revision == 1)
 		facs = (struct FACSbody *)acpi_map_sdt(fadt->facs_ptr);
 	else
@@ -520,7 +528,7 @@
 		acpi_print_gas(&fadt->reset_reg);
 		printf(", RESET_VALUE=%#x\n", fadt->reset_value);
 	}
-	if (fadt_revision > 1) {
+	if (acpi_get_fadt_revision(fadt) > 1) {
 		printf("\tX_FACS=0x%08lx, ", (u_long)fadt->x_facs_ptr);
 		printf("X_DSDT=0x%08lx\n", (u_long)fadt->x_dsdt_ptr);
 		printf("\tX_PM1a_EVT_BLK=");
@@ -805,7 +813,9 @@
 dsdt_from_fadt(struct FADTbody *fadt)
 {
 	struct	ACPIsdt *sdt;
+	int              fadt_revision;
 
+	fadt_revision = acpi_get_fadt_revision(fadt);
 	/* Use the DSDT address if it is version 1, otherwise use X_DSDT. */
 	if (fadt_revision == 1)
 		sdt = (struct ACPIsdt *)acpi_map_sdt(fadt->dsdt_ptr);


More information about the freebsd-acpi mailing list