summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErwan Velu <erwan.velu@free.fr>2009-12-03 21:53:54 +0100
committerErwan Velu <erwan.velu@free.fr>2009-12-04 10:19:02 +0100
commit005e71b7ec54bae2aa9d3a03fbae4f544d1e46ef (patch)
treef34664ca7f50d5fa0f937a7729f2df4f343721d3
parente7135fcc3f39bd43dfc1e20e61dcd9241cad03a2 (diff)
downloadsyslinux-005e71b7ec54bae2aa9d3a03fbae4f544d1e46ef.tar.gz
acpi: Adding FACS, fixing DSDT detection
Impact: Adding FACS, fixing DSDT detection Adding FACS, fixing DSDT detection via FADT
-rw-r--r--com32/gplinclude/acpi/acpi.h3
-rw-r--r--com32/gplinclude/acpi/dsdt.h1
-rw-r--r--com32/gplinclude/acpi/facs.h41
-rw-r--r--com32/gpllib/acpi/dsdt.c46
-rw-r--r--com32/gpllib/acpi/facs.c50
-rw-r--r--com32/gpllib/acpi/xsdt.c160
6 files changed, 241 insertions, 60 deletions
diff --git a/com32/gplinclude/acpi/acpi.h b/com32/gplinclude/acpi/acpi.h
index 0ce43f54..664306b8 100644
--- a/com32/gplinclude/acpi/acpi.h
+++ b/com32/gplinclude/acpi/acpi.h
@@ -24,13 +24,13 @@
#include <acpi/ssdt.h>
#include <acpi/sbst.h>
#include <acpi/ecdt.h>
+#include <acpi/facs.h>
enum { ACPI_FOUND, ENO_ACPI, MADT_FOUND, ENO_MADT };
#define MAX_SSDT 128
/* Some other description HEADERS : ACPI doc: 5.2.6*/
-#define FACS "FACS"
#define OEMX "OEMx"
#define SRAR "SRAT"
#define BERT "BERT"
@@ -69,6 +69,7 @@ typedef struct {
uint8_t ssdt_count;
s_sbst sbst;
s_ecdt ecdt;
+ s_facs facs;
} s_acpi;
int parse_acpi(s_acpi * acpi);
diff --git a/com32/gplinclude/acpi/dsdt.h b/com32/gplinclude/acpi/dsdt.h
index 219cb1ee..fcb6280d 100644
--- a/com32/gplinclude/acpi/dsdt.h
+++ b/com32/gplinclude/acpi/dsdt.h
@@ -24,4 +24,5 @@ typedef struct {
bool valid;
} s_dsdt;
+void parse_dsdt(s_dsdt *dsdt);
#endif
diff --git a/com32/gplinclude/acpi/facs.h b/com32/gplinclude/acpi/facs.h
new file mode 100644
index 00000000..4435eab4
--- /dev/null
+++ b/com32/gplinclude/acpi/facs.h
@@ -0,0 +1,41 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * 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
+ * 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 FACS_H
+#define FACS_H
+#include <inttypes.h>
+#include <stdbool.h>
+
+#define FACS "FACS"
+
+/* Features Flags for "flags" */
+#define S4BIOS_F 1
+
+/* Features flags for global_lock */
+#define PENDING 1
+#define OWNED 1<<1
+
+typedef struct {
+ uint64_t address;
+ uint8_t signature[4+1];
+ uint8_t length;
+ uint32_t hardware_signature;
+ uint32_t firmware_waking_vector;
+ uint32_t global_lock;
+ uint32_t flags;
+ uint64_t x_firmware_waking_vector;
+ uint8_t version;
+ bool valid;
+} s_facs;
+
+void parse_facs(s_facs *facs);
+#endif
diff --git a/com32/gpllib/acpi/dsdt.c b/com32/gpllib/acpi/dsdt.c
new file mode 100644
index 00000000..3c6e1774
--- /dev/null
+++ b/com32/gpllib/acpi/dsdt.c
@@ -0,0 +1,46 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * 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"
+
+void parse_dsdt(s_dsdt * d)
+{
+ uint8_t *q;
+ q = (uint64_t *) (d->address+ACPI_HEADER_SIZE);
+
+ /* Searching how much definition blocks we must copy */
+ uint32_t definition_block_size=d->header.length-ACPI_HEADER_SIZE;
+ if ((d->definition_block=malloc(definition_block_size)) != NULL) {
+ memcpy(d->definition_block,(uint64_t *)(d->address+ACPI_HEADER_SIZE),definition_block_size);
+ }
+
+}
diff --git a/com32/gpllib/acpi/facs.c b/com32/gpllib/acpi/facs.c
new file mode 100644
index 00000000..0fc0b6bd
--- /dev/null
+++ b/com32/gpllib/acpi/facs.c
@@ -0,0 +1,50 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * 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"
+
+void parse_facs(s_facs * f)
+{
+ uint8_t *q;
+ q = (uint64_t *) (f->address + ACPI_HEADER_SIZE);
+ if (memcmp(q, FACS, sizeof(FACS) - 1) == 0) {
+ f->valid = true;
+ cp_str_struct(f->signature);
+ cp_struct(&f->length);
+ cp_struct(&f->hardware_signature);
+ cp_struct(&f->firmware_waking_vector);
+ cp_struct(&f->global_lock);
+ cp_struct(&f->flags);
+ cp_struct(&f->x_firmware_waking_vector);
+ cp_struct(&f->version);
+ }
+}
diff --git a/com32/gpllib/acpi/xsdt.c b/com32/gpllib/acpi/xsdt.c
index d9e1b8cb..ff222b0c 100644
--- a/com32/gpllib/acpi/xsdt.c
+++ b/com32/gpllib/acpi/xsdt.c
@@ -41,7 +41,7 @@ int parse_xsdt(s_acpi * acpi)
q = (uint64_t *) acpi->xsdt.address;
/* Searching for MADT with APIC signature */
- if (memcmp(q, XSDT, sizeof(XSDT)-1) == 0) {
+ if (memcmp(q, XSDT, sizeof(XSDT) - 1) == 0) {
s_xsdt *x = &acpi->xsdt;
x->valid = true;
get_acpi_description_header(q, &x->header);
@@ -58,67 +58,109 @@ int parse_xsdt(s_acpi * acpi)
get_acpi_description_header((uint8_t *) * p, &adh);
/* Trying to determine the pointed table */
- /* Looking for MADT*/
- if (memcmp(adh.signature, FACP, sizeof(FACP)-1) == 0) {
- s_fadt *f = &acpi->fadt;
- /* This structure is valid, let's fill it */
- f->valid=true;
- f->address=*p;
- memcpy(&f->header,&adh,sizeof(adh));
- parse_fadt(f);
- /* Looking for MADT */
- } else if (memcmp(adh.signature, APIC, sizeof(APIC)-1) == 0) {
- s_madt *m = &acpi->madt;
- /* This structure is valid, let's fill it */
- m->valid=true;
- m->address=*p;
- memcpy(&m->header,&adh,sizeof(adh));
- parse_madt(acpi);
- } else if (memcmp(adh.signature, DSDT, sizeof(DSDT)-1) == 0) {
- s_dsdt *d = &acpi->dsdt;
- /* This structure is valid, let's fill it */
- d->valid=true;
- d->address=*p;
- memcpy(&d->header,&adh,sizeof(adh));
- /* Searching how much definition blocks we must copy */
- uint32_t definition_block_size=adh.length-ACPI_HEADER_SIZE;
- if ((d->definition_block=malloc(definition_block_size)) != NULL) {
- memcpy(d->definition_block,(uint64_t *)(d->address+ACPI_HEADER_SIZE),definition_block_size);
- }
- /* PSDT have to be considered as SSDT. Intel ACPI Spec @ 5.2.11.3 */
- } else if ((memcmp(adh.signature, SSDT, sizeof(SSDT)-1) == 0) || (memcmp(adh.signature, PSDT, sizeof(PSDT)-1))) {
- if ((acpi->ssdt_count >= MAX_SSDT-1)) break;
+ /* Looking for FADT */
+ if (memcmp(adh.signature, FACP, sizeof(FACP) - 1) == 0) {
+ s_fadt *f = &acpi->fadt;
+ s_facs *fa = &acpi->facs;
+ s_dsdt *d = &acpi->dsdt;
+ /* This structure is valid, let's fill it */
+ f->valid = true;
+ f->address = *p;
+ memcpy(&f->header, &adh, sizeof(adh));
+ parse_fadt(f);
- /* We can have many SSDT, so let's allocate a new one */
- if ((acpi->ssdt[acpi->ssdt_count]=malloc(sizeof(s_ssdt))) == NULL) break;
- s_ssdt *s = acpi->ssdt[acpi->ssdt_count];
+ /* FACS wasn't already detected
+ * FADT points to it, let's try to detect it */
+ if (fa->valid == false) {
+ fa->address = f->x_firmware_ctrl;
+ parse_facs(fa);
+ if (fa->valid == false) {
+ /* Let's try again */
+ fa->address = f->firmware_ctrl;
+ parse_facs(fa);
+ }
+ }
- /* This structure is valid, let's fill it */
- s->valid=true;
- s->address=*p;
- memcpy(&s->header,&adh,sizeof(adh));
-
- /* Searching how much definition blocks we must copy */
- uint32_t definition_block_size=adh.length-ACPI_HEADER_SIZE;
- if ((s->definition_block=malloc(definition_block_size)) != NULL) {
- memcpy(s->definition_block,(uint64_t *)(s->address+ACPI_HEADER_SIZE),definition_block_size);
+ /* DSDT wasn't already detected
+ * FADT points to it, let's try to detect it */
+ if (d->valid == false) {
+ s_acpi_description_header new_adh;
+ get_acpi_description_header((uint8_t *) f->x_dsdt,
+ &new_adh);
+ if (memcmp(new_adh.signature, DSDT, sizeof(DSDT) - 1) == 0) {
+ d->valid = true;
+ d->address = f->x_dsdt;
+ memcpy(&d->header, &new_adh, sizeof(new_adh));
+ parse_dsdt(d);
+ } else {
+ /* Let's try again */
+ get_acpi_description_header((uint8_t *) f->dsdt_address,
+ &new_adh);
+ if (memcmp(new_adh.signature, DSDT, sizeof(DSDT) - 1) ==
+ 0) {
+ d->valid = true;
+ d->address = f->dsdt_address;
+ memcpy(&d->header, &new_adh, sizeof(new_adh));
+ parse_dsdt(d);
+ }
}
- /* Increment the number of ssdt we have */
- acpi->ssdt_count++;
- } else if (memcmp(adh.signature, SBST, sizeof(SBST)-1) == 0) {
- s_sbst *s = &acpi->sbst;
- /* This structure is valid, let's fill it */
- s->valid=true;
- s->address=*p;
- memcpy(&s->header,&adh,sizeof(adh));
- parse_sbst(s);
- } else if (memcmp(adh.signature, ECDT, sizeof(ECDT)-1) == 0) {
- s_ecdt *e = &acpi->ecdt;
- /* This structure is valid, let's fill it */
- e->valid=true;
- e->address=*p;
- memcpy(&e->header,&adh,sizeof(adh));
- parse_ecdt(e);
+ }
+ } /* Looking for MADT */
+ else if (memcmp(adh.signature, APIC, sizeof(APIC) - 1) == 0) {
+ s_madt *m = &acpi->madt;
+ /* This structure is valid, let's fill it */
+ m->valid = true;
+ m->address = *p;
+ memcpy(&m->header, &adh, sizeof(adh));
+ parse_madt(acpi);
+ } else if (memcmp(adh.signature, DSDT, sizeof(DSDT) - 1) == 0) {
+ s_dsdt *d = &acpi->dsdt;
+ /* This structure is valid, let's fill it */
+ d->valid = true;
+ d->address = *p;
+ memcpy(&d->header, &adh, sizeof(adh));
+ parse_dsdt(d);
+ /* PSDT have to be considered as SSDT. Intel ACPI Spec @ 5.2.11.3 */
+ } else if ((memcmp(adh.signature, SSDT, sizeof(SSDT) - 1) == 0)
+ || (memcmp(adh.signature, PSDT, sizeof(PSDT) - 1))) {
+ if ((acpi->ssdt_count >= MAX_SSDT - 1))
+ break;
+
+ /* We can have many SSDT, so let's allocate a new one */
+ if ((acpi->ssdt[acpi->ssdt_count] =
+ malloc(sizeof(s_ssdt))) == NULL)
+ break;
+ s_ssdt *s = acpi->ssdt[acpi->ssdt_count];
+
+ /* This structure is valid, let's fill it */
+ s->valid = true;
+ s->address = *p;
+ memcpy(&s->header, &adh, sizeof(adh));
+
+ /* Searching how much definition blocks we must copy */
+ uint32_t definition_block_size = adh.length - ACPI_HEADER_SIZE;
+ if ((s->definition_block =
+ malloc(definition_block_size)) != NULL) {
+ memcpy(s->definition_block,
+ (uint64_t *) (s->address + ACPI_HEADER_SIZE),
+ definition_block_size);
+ }
+ /* Increment the number of ssdt we have */
+ acpi->ssdt_count++;
+ } else if (memcmp(adh.signature, SBST, sizeof(SBST) - 1) == 0) {
+ s_sbst *s = &acpi->sbst;
+ /* This structure is valid, let's fill it */
+ s->valid = true;
+ s->address = *p;
+ memcpy(&s->header, &adh, sizeof(adh));
+ parse_sbst(s);
+ } else if (memcmp(adh.signature, ECDT, sizeof(ECDT) - 1) == 0) {
+ s_ecdt *e = &acpi->ecdt;
+ /* This structure is valid, let's fill it */
+ e->valid = true;
+ e->address = *p;
+ memcpy(&e->header, &adh, sizeof(adh));
+ parse_ecdt(e);
}
x->entry_count++;
}