[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