[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