[syslinux:master] acpi: more work on the madt structures

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


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

acpi: more work on the madt structures

Impact: under dev.

Fixing madt structure & parsing


---
 com32/gplinclude/acpi/acpi.h |   26 ++-------
 com32/gplinclude/acpi/madt.h |   55 +++++++++++++++++++
 com32/gpllib/acpi/acpi.c     |   76 +++-----------------------
 com32/gpllib/acpi/madt.c     |  124 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 192 insertions(+), 89 deletions(-)

diff --git a/com32/gplinclude/acpi/acpi.h b/com32/gplinclude/acpi/acpi.h
index 979c454..53e5b67 100644
--- a/com32/gplinclude/acpi/acpi.h
+++ b/com32/gplinclude/acpi/acpi.h
@@ -14,25 +14,9 @@
 #define ACPI_H
 #include <inttypes.h>
 #include <stdbool.h>
+#include <acpi/madt.h>
 
-enum { ACPI_FOUND, ENO_ACPI, MADT_FOUND, ENO_MADT};
-
-#define WORD(x) (uint16_t)(*(const uint16_t *)(x))
-#define DWORD(x) (uint32_t)(*(const uint32_t *)(x))
-#define QWORD(x) (*(const uint64_t *)(x))
-
-typedef struct {
-    int8_t signature[4+1];
-    int32_t length;
-    int8_t  revision;
-    int8_t  checksum;
-    int8_t  oem_id[6+1];
-    int8_t  oem_table_id[8+1];
-    int32_t oem_revision;
-    int8_t  creator_id[4+1];
-    int32_t creator_revision;
-    uint32_t local_apic_address;
-} s_madt;
+enum { ACPI_FOUND, ENO_ACPI, MADT_FOUND, ENO_MADT };
 
 typedef struct {
     s_madt madt;
@@ -42,7 +26,7 @@ typedef struct {
     bool acpi_valid;
 } s_acpi;
 
-int search_acpi(s_acpi *acpi);
-int search_madt(s_acpi *acpi);
-void print_madt(s_acpi *acpi);
+int search_acpi(s_acpi * acpi);
+int search_madt(s_acpi * acpi);
+void print_madt(s_acpi * acpi);
 #endif
diff --git a/com32/gplinclude/acpi/madt.h b/com32/gplinclude/acpi/madt.h
new file mode 100644
index 0000000..30969f2
--- /dev/null
+++ b/com32/gplinclude/acpi/madt.h
@@ -0,0 +1,55 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2006 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
+ *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
+ *   Boston MA 02111-1307, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef MADT_H
+#define MADT_H
+#include <inttypes.h>
+#include <stdbool.h>
+
+enum {
+    PROCESSOR_LOCAL_APIC = 0,
+    IO_APIC = 1,
+    INTERRUPT_SOURCE_OVERRIDE = 2,
+    NMI = 3,
+    LOCAL_APIC_NMI_STRUCTURE = 4,
+    LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE = 5,
+    IO_SAPIC = 6,
+    LOCAL_SAPIC = 7,
+    PLATEFORM_INTERRUPT_SOURCES = 8
+};
+
+#define MAX_SLP 255
+
+typedef struct {
+    uint8_t length;
+    uint8_t acpi_id;
+    uint8_t apic_id;
+    uint32_t flags;
+} s_processor_local_apic;
+
+typedef struct {
+    uint8_t signature[4 + 1];
+    uint32_t length;
+    uint8_t revision;
+    uint8_t checksum;
+    uint8_t oem_id[6 + 1];
+    uint8_t oem_table_id[8 + 1];
+    uint32_t oem_revision;
+    uint8_t creator_id[4 + 1];
+    uint32_t creator_revision;
+    uint32_t local_apic_address;
+    uint32_t flags;
+    s_processor_local_apic processor_local_apic[MAX_SLP];
+    uint8_t processor_local_apic_count;
+} s_madt;
+
+#endif
diff --git a/com32/gpllib/acpi/acpi.c b/com32/gpllib/acpi/acpi.c
index 4e29bed..a87e472 100644
--- a/com32/gpllib/acpi/acpi.c
+++ b/com32/gpllib/acpi/acpi.c
@@ -31,18 +31,12 @@
 #include <memory.h>
 #include "acpi/acpi.h"
 
-void init_acpi(s_acpi *acpi)
+void init_acpi(s_acpi * acpi)
 {
-   acpi->acpi_valid=false;
-   acpi->madt_valid=false;
-   memset(acpi->madt.oem_id,0,sizeof(acpi->madt.oem_id));
-   memset(acpi->madt.oem_table_id,0,sizeof(acpi->madt.oem_table_id));
-   memset(acpi->madt.oem_revision,0,sizeof(acpi->madt.oem_revision));
-   memset(acpi->madt.creator_id,0,sizeof(acpi->madt.creator_id));
-   memset(acpi->madt.creator_revision,0,sizeof(acpi->madt.creator_revision));
+    memset(acpi, 0, sizeof(s_acpi));
 }
 
-int search_acpi(s_acpi *acpi)
+int search_acpi(s_acpi * acpi)
 {
     init_acpi(acpi);
     struct e820entry map[E820MAX];
@@ -55,65 +49,11 @@ int search_acpi(s_acpi *acpi)
     for (int i = 0; i < nr; i++) {
 	/* Type is ACPI Reclaim */
 	if (nm[i].type == E820_ACPI) {
-		printf("ACPI Table Found\n");
-		acpi->base_address=nm[i].addr;
-		acpi->size=nm[i].size;
-		acpi->acpi_valid=true;
-		return ACPI_FOUND;
+	    acpi->base_address = nm[i].addr;
+	    acpi->size = nm[i].size;
+	    acpi->acpi_valid = true;
+	    return ACPI_FOUND;
 	}
     }
-   return -ENO_ACPI;
-}
-
-#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;
-    if (!acpi->acpi_valid) return -ENO_ACPI;
-
-    p = (uint64_t *) acpi->base_address;	/* The start address to look at the dmi table */
-    /* The anchor-string is 16-bytes aligned */
-    for (q = p; q < p + acpi->size; q += 1) {
-	/* To validate the presence of SMBIOS:
-	 * + the overall checksum must be correct
-	 * + the intermediate anchor-string must be _DMI_
-	 * + the intermediate checksum must be correct
-	 */
-	if (memcmp(q, "APIC", 4) == 0) {
-	    /* Do not return, legacy_decode will need to be called
-	     * on the intermediate structure to get the table length
-	     * and address
-	     */
-	     s_madt *m = &acpi->madt;
-	     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);
-	     acpi->madt_valid=true;
-	return MADT_FOUND;
-	}
-    }
-   return -ENO_MADT;
-}
-
-void print_madt(s_acpi *acpi)
-{
-   if (!acpi->madt_valid) return;
-   printf("MADT\n");
-   printf(" signature      : %s\n",acpi->madt.signature);
-   printf(" length         : %d\n",acpi->madt.length);
-   printf(" revision       : %d\n",acpi->madt.revision);
-   printf(" checksum       : %d\n",acpi->madt.checksum);
-   printf(" oem id         : %s\n",acpi->madt.oem_id);
-   printf(" oem table id   : %s\n",acpi->madt.oem_table_id);
-   printf(" oem revision   : %d\n",acpi->madt.oem_revision);
-   printf(" oem creator id : %s\n",acpi->madt.creator_id);
-   printf(" oem creator rev: %d\n",acpi->madt.creator_revision);
+    return -ENO_ACPI;
 }
diff --git a/com32/gpllib/acpi/madt.c b/com32/gpllib/acpi/madt.c
new file mode 100644
index 0000000..830a89d
--- /dev/null
+++ b/com32/gpllib/acpi/madt.c
@@ -0,0 +1,124 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2006 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 "acpi/acpi.h"
+
+static void print_local_apic_structure(s_processor_local_apic * sla,
+				       uint8_t index)
+{
+    printf("Local APIC Structure no%u (%03u bytes)\n", index, sla->length);
+    printf(" ACPI_ID / APIC_ID = %03u / %03u\n", sla->acpi_id, sla->apic_id);
+}
+
+/* Parse the apic structures */
+static uint8_t *add_apic_structure(s_acpi * acpi, uint8_t * q)
+{
+    uint8_t type = *q;
+    q++;
+    uint8_t length = *q;
+    q++;
+    s_processor_local_apic *sla;
+    switch (type) {
+    case PROCESSOR_LOCAL_APIC:
+	sla =
+	    &acpi->madt.processor_local_apic[acpi->madt.
+					     processor_local_apic_count];
+	sla->length = length;
+	sla->acpi_id = *q;
+	q++;
+	sla->apic_id = *q;
+	q++;
+	memcpy(&sla->flags, q, 4);
+	q += 4;
+	print_local_apic_structure(sla, acpi->madt.processor_local_apic_count);
+	acpi->madt.processor_local_apic_count++;
+	break;
+    default:
+	printf("APIC structure type %u, size=%u \n", type, length);
+	q += length - 2;
+	break;
+    }
+    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;
+    if (!acpi->acpi_valid)
+	return -ENO_ACPI;
+
+    p = (uint8_t *) acpi->base_address;	/* The start address to look at the APIC table */
+    for (q = p; q < p + acpi->size; q += 1) {
+	uint8_t *save = q;
+	/* Searching for MADT with APIC signature */
+	if (memcmp(q, "APIC", 4) == 0) {
+	    s_madt *m = &acpi->madt;
+	    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);
+
+	    /* Let's parse APIC Structures */
+	    while (q < (save + m->length)) {
+		q = add_apic_structure(acpi, q);
+	    }
+	    acpi->madt_valid = true;
+	    return MADT_FOUND;
+	}
+    }
+    return -ENO_MADT;
+}
+
+void print_madt(s_acpi * acpi)
+{
+    if (!acpi->madt_valid)
+	return;
+    printf("MADT Table\n");
+    printf(" signature      : %s\n", acpi->madt.signature);
+    printf(" length         : %d\n", acpi->madt.length);
+    printf(" revision       : %u\n", acpi->madt.revision);
+    printf(" checksum       : %u\n", acpi->madt.checksum);
+    printf(" oem id         : %s\n", acpi->madt.oem_id);
+    printf(" oem table id   : %s\n", acpi->madt.oem_table_id);
+    printf(" oem revision   : %u\n", acpi->madt.oem_revision);
+    printf(" oem creator id : %s\n", acpi->madt.creator_id);
+    printf(" oem creator rev: %u\n", acpi->madt.creator_revision);
+    printf(" APIC address   : 0x%08x\n", acpi->madt.local_apic_address);
+}



More information about the Syslinux-commits mailing list