[syslinux:master] acpi: Fixing parsing

syslinux-bot for Erwan Velu erwan.velu at free.fr
Sun Feb 6 14:06:34 PST 2011


Commit-ID:  62ea3bbf5cde3a708bb95e754d6eb9d73e9ef30b
Gitweb:     http://syslinux.zytor.com/commit/62ea3bbf5cde3a708bb95e754d6eb9d73e9ef30b
Author:     Erwan Velu <erwan.velu at free.fr>
AuthorDate: Tue, 1 Dec 2009 16:26:16 +0100
Committer:  Erwan Velu <erwan.velu at free.fr>
CommitDate: Fri, 4 Dec 2009 10:19:00 +0100

acpi: Fixing parsing

Impact: none

Parsing have to be done the spec says ;)
Let's found the RSDP first


---
 com32/gplinclude/acpi/acpi.h             |   16 ++++--
 com32/gplinclude/acpi/madt.h             |    3 +-
 com32/gplinclude/acpi/{acpi.h => rsdp.h} |   31 +++++++-----
 com32/gpllib/acpi/acpi.c                 |   24 ++-------
 com32/gpllib/acpi/madt.c                 |   42 +++++++---------
 com32/gpllib/acpi/rsdp.c                 |   78 ++++++++++++++++++++++++++++++
 com32/hdt/hdt-cli.c                      |    5 +--
 7 files changed, 132 insertions(+), 67 deletions(-)

diff --git a/com32/gplinclude/acpi/acpi.h b/com32/gplinclude/acpi/acpi.h
index 53e5b67..4a83fbd 100644
--- a/com32/gplinclude/acpi/acpi.h
+++ b/com32/gplinclude/acpi/acpi.h
@@ -1,6 +1,6 @@
 /* ----------------------------------------------------------------------- *
  *
- *   Copyright 2006 Erwan Velu - All Rights Reserved
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
  *
  *   This program is free software; you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
@@ -14,19 +14,23 @@
 #define ACPI_H
 #include <inttypes.h>
 #include <stdbool.h>
+#include <acpi/rsdp.h>
 #include <acpi/madt.h>
 
 enum { ACPI_FOUND, ENO_ACPI, MADT_FOUND, ENO_MADT };
 
+/* This macro are used to extract ACPI structures 
+ * please be careful about the q (interator) naming */
+#define cp_struct(dest) memcpy(dest,q,sizeof(*dest)); q+=sizeof(*dest)
+#define cp_str_struct(dest) memcpy(dest,q,sizeof(dest)-1); dest[sizeof(dest)-1]=0;q+=sizeof(dest)-1
+
 typedef struct {
+    s_rsdp rsdp;
     s_madt madt;
-    uint64_t base_address;
-    uint64_t size;
-    bool madt_valid;
-    bool acpi_valid;
 } s_acpi;
 
-int search_acpi(s_acpi * acpi);
+int parse_acpi(s_acpi * acpi);
 int search_madt(s_acpi * acpi);
+int search_rsdp(s_acpi * acpi);
 void print_madt(s_acpi * acpi);
 #endif
diff --git a/com32/gplinclude/acpi/madt.h b/com32/gplinclude/acpi/madt.h
index 10e0d42..cb623a4 100644
--- a/com32/gplinclude/acpi/madt.h
+++ b/com32/gplinclude/acpi/madt.h
@@ -1,6 +1,6 @@
 /* ----------------------------------------------------------------------- *
  *
- *   Copyright 2006 Erwan Velu - All Rights Reserved
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
  *
  *   This program is free software; you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
@@ -51,6 +51,7 @@ typedef struct {
     uint32_t flags;
     s_processor_local_apic processor_local_apic[MAX_SLP];
     uint8_t processor_local_apic_count;
+    bool valid;
 } s_madt;
 
 #endif
diff --git a/com32/gplinclude/acpi/acpi.h b/com32/gplinclude/acpi/rsdp.h
similarity index 57%
copy from com32/gplinclude/acpi/acpi.h
copy to com32/gplinclude/acpi/rsdp.h
index 53e5b67..df4da2d 100644
--- a/com32/gplinclude/acpi/acpi.h
+++ b/com32/gplinclude/acpi/rsdp.h
@@ -1,6 +1,6 @@
 /* ----------------------------------------------------------------------- *
  *
- *   Copyright 2006 Erwan Velu - All Rights Reserved
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
  *
  *   This program is free software; you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
@@ -10,23 +10,26 @@
  *
  * ----------------------------------------------------------------------- */
 
-#ifndef ACPI_H
-#define ACPI_H
+#ifndef RSDP_H
+#define RSDP_H
 #include <inttypes.h>
 #include <stdbool.h>
-#include <acpi/madt.h>
 
-enum { ACPI_FOUND, ENO_ACPI, MADT_FOUND, ENO_MADT };
+#define RSDP_MIN_ADDRESS 0x0E0000
+#define RSDP_MAX_ADDRESS 0x0FFFFF
+enum { RSDP_TABLE_FOUND };
 
 typedef struct {
-    s_madt madt;
-    uint64_t base_address;
-    uint64_t size;
-    bool madt_valid;
-    bool acpi_valid;
-} s_acpi;
+    uint64_t address;
+    uint8_t signature[8 + 1];
+    uint8_t checksum;
+    uint8_t oem_id[6 + 1];
+    uint8_t revision;
+    uint32_t rsdt_address;
+    uint32_t length;
+    uint32_t xsdt_address;
+    uint8_t extended_checksum;
+    bool valid;
+} s_rsdp;
 
-int search_acpi(s_acpi * acpi);
-int search_madt(s_acpi * acpi);
-void print_madt(s_acpi * acpi);
 #endif
diff --git a/com32/gpllib/acpi/acpi.c b/com32/gpllib/acpi/acpi.c
index a87e472..911fd16 100644
--- a/com32/gpllib/acpi/acpi.c
+++ b/com32/gpllib/acpi/acpi.c
@@ -1,6 +1,6 @@
 /* ----------------------------------------------------------------------- *
  *
- *   Copyright 2006 Erwan Velu - All Rights Reserved
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
  *
  *   Permission is hereby granted, free of charge, to any person
  *   obtaining a copy of this software and associated documentation
@@ -36,24 +36,12 @@ void init_acpi(s_acpi * acpi)
     memset(acpi, 0, sizeof(s_acpi));
 }
 
-int search_acpi(s_acpi * acpi)
+int parse_acpi(s_acpi * acpi)
 {
+    int ret_val;
     init_acpi(acpi);
-    struct e820entry map[E820MAX];
-    struct e820entry nm[E820MAX];
-    int count = 0;
 
-    detect_memory_e820(map, E820MAX, &count);
-    /* Clean up, adjust and copy the BIOS-supplied E820-map. */
-    int nr = sanitize_e820_map(map, nm, count);
-    for (int i = 0; i < nr; i++) {
-	/* Type is ACPI Reclaim */
-	if (nm[i].type == E820_ACPI) {
-	    acpi->base_address = nm[i].addr;
-	    acpi->size = nm[i].size;
-	    acpi->acpi_valid = true;
-	    return ACPI_FOUND;
-	}
-    }
-    return -ENO_ACPI;
+    /* Let's seach for RSDT table */
+    if ((ret_val = search_rsdp(acpi)) != RSDP_TABLE_FOUND)
+	return ret_val;
 }
diff --git a/com32/gpllib/acpi/madt.c b/com32/gpllib/acpi/madt.c
index 518c541..6e8a038 100644
--- a/com32/gpllib/acpi/madt.c
+++ b/com32/gpllib/acpi/madt.c
@@ -1,6 +1,6 @@
 /* ----------------------------------------------------------------------- *
  *
- *   Copyright 2006 Erwan Velu - All Rights Reserved
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
  *
  *   Permission is hereby granted, free of charge, to any person
  *   obtaining a copy of this software and associated documentation
@@ -71,47 +71,41 @@ static uint8_t *add_apic_structure(s_acpi * acpi, uint8_t * q)
     return q;
 }
 
-#define cp_struct(dest,quantity) memcpy(dest,q,quantity); q+=quantity
-#define cp_str_struct(dest,quantity) memcpy(dest,q,quantity); dest[quantity]=0;q+=quantity
 int search_madt(s_acpi * acpi)
 {
     uint8_t *p, *q;
     s_madt *m = &acpi->madt;
-    if (!acpi->acpi_valid)
-	return -ENO_ACPI;
-
-    p = (uint64_t *) acpi->base_address;	/* The start address to look at the APIC table */
-    for (q = p; q < p + acpi->size; q += 1) {
+    
+    //p = (uint64_t *) acpi->base_address;	/* The start address to look at the APIC table */
+/*    for (q = p; q < p + acpi->size; q += 1) {
 	m->address=(uint32_t) q;
 	uint8_t *save = q;
-	/* Searching for MADT with APIC signature */
 	if (memcmp(q, "APIC", 4) == 0) {
-	    cp_str_struct(m->signature, 4);
-	    cp_struct(&m->length, 4);
-	    cp_struct(&m->revision, 1);
-	    cp_struct(&m->checksum, 1);
-	    cp_str_struct(m->oem_id, 6);
-	    cp_str_struct(m->oem_table_id, 8);
-	    cp_struct(&m->oem_revision, 4);
-	    cp_str_struct(m->creator_id, 4);
-	    cp_struct(&m->creator_revision, 4);
-	    cp_struct(&m->local_apic_address, 4);
-	    cp_struct(&m->flags, 4);
+	    cp_str_struct(m->signature);
+	    cp_struct(&m->length);
+	    cp_struct(&m->revision);
+	    cp_struct(&m->checksum);
+	    cp_str_struct(m->oem_id);
+	    cp_str_struct(m->oem_table_id);
+	    cp_struct(&m->oem_revision);
+	    cp_str_struct(m->creator_id);
+	    cp_struct(&m->creator_revision);
+	    cp_struct(&m->local_apic_address);
+	    cp_struct(&m->flags);
 
-	    /* Let's parse APIC Structures */
 	    while (q < (save + m->length)) {
 		q = add_apic_structure(acpi, q);
 	    }
-	    acpi->madt_valid = true;
+	    m->valid = true;
 	    return MADT_FOUND;
 	}
-    }
+    }*/
     return -ENO_MADT;
 }
 
 void print_madt(s_acpi * acpi)
 {
-    if (!acpi->madt_valid)
+    if (!acpi->madt.valid)
 	return;
     printf("MADT Table @ 0x%08x\n",acpi->madt.address);
     printf(" signature      : %s\n", acpi->madt.signature);
diff --git a/com32/gpllib/acpi/rsdp.c b/com32/gpllib/acpi/rsdp.c
new file mode 100644
index 0000000..66f258b
--- /dev/null
+++ b/com32/gpllib/acpi/rsdp.c
@@ -0,0 +1,78 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+#include <dprintf.h>
+#include "acpi/acpi.h"
+
+int search_rsdp(s_acpi * acpi)
+{
+    /* Let's seach for RSDT table */
+    uint8_t *p, *q;
+
+    /* Let's start for the base address */
+    p = (uint64_t *) RSDP_MIN_ADDRESS;
+    for (q = p; q < RSDP_MAX_ADDRESS; q += 16) {
+	/* Searching for MADT with APIC signature */
+	if (memcmp(q, "RSD PTR", 7) == 0) {
+	    s_rsdp *r = &acpi->rsdp;
+	    r->valid = true;
+	    r->address = (uint64_t) q;
+	    cp_str_struct(r->signature);
+	    cp_struct(&r->checksum);
+	    cp_str_struct(r->oem_id);
+	    cp_struct(&r->revision);
+	    cp_struct(&r->rsdt_address);
+	    cp_struct(&r->length);
+	    cp_struct(&r->xsdt_address);
+	    cp_struct(&r->extended_checksum);
+	    q += 3;		/* reserved field */
+	    return RSDP_TABLE_FOUND;
+	}
+    }
+    return -RSDP_TABLE_FOUND;
+}
+
+void print_rsdp(s_acpi * acpi)
+{
+    s_rsdp *r = &acpi->rsdp;
+
+    if (!r->valid)
+	return;
+    printf("RSDP Table @ 0x%016llx\n", r->address);
+    printf(" signature         : %s\n", r->signature);
+    printf(" checksum          : %u\n", r->checksum);
+    printf(" oem id            : %s\n", r->oem_id);
+    printf(" revision          : %u\n", r->revision);
+    printf(" RDST address      : 0x%08x\n", r->rsdt_address);
+    printf(" length            : %u\n", r->length);
+    printf(" XSDT address      : 0x%08x\n", r->xsdt_address);
+    printf(" extended checksum : %u\n", r->extended_checksum);
+}
diff --git a/com32/hdt/hdt-cli.c b/com32/hdt/hdt-cli.c
index 3aa9c38..146021b 100644
--- a/com32/hdt/hdt-cli.c
+++ b/com32/hdt/hdt-cli.c
@@ -827,10 +827,7 @@ void start_cli_mode(struct s_hardware *hardware)
     reset_prompt();
 
     s_acpi acpi;
-    search_acpi(&acpi);
-    if (search_madt(&acpi) == MADT_FOUND) {
-	    print_madt(&acpi);
-    };
+    parse_acpi(&acpi);
 
     while (hdt_cli.mode != EXIT_MODE) {
 



More information about the Syslinux-commits mailing list