[syslinux:master] acpi: Adding FACS, fixing DSDT detection

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


Commit-ID:  005e71b7ec54bae2aa9d3a03fbae4f544d1e46ef
Gitweb:     http://syslinux.zytor.com/commit/005e71b7ec54bae2aa9d3a03fbae4f544d1e46ef
Author:     Erwan Velu <erwan.velu at free.fr>
AuthorDate: Thu, 3 Dec 2009 21:53:54 +0100
Committer:  Erwan Velu <erwan.velu at free.fr>
CommitDate: Fri, 4 Dec 2009 10:19:02 +0100

acpi: Adding FACS, fixing DSDT detection

Impact: Adding FACS, fixing DSDT detection

Adding FACS, fixing DSDT detection via FADT


---
 com32/gplinclude/acpi/acpi.h             |    3 +-
 com32/gplinclude/acpi/dsdt.h             |    1 +
 com32/gplinclude/acpi/{rsdp.h => facs.h} |   33 ++++---
 com32/gpllib/acpi/{sbst.c => dsdt.c}     |   14 ++-
 com32/gpllib/acpi/{sbst.c => facs.c}     |   20 +++--
 com32/gpllib/acpi/xsdt.c                 |  160 +++++++++++++++++++-----------
 6 files changed, 143 insertions(+), 88 deletions(-)

diff --git a/com32/gplinclude/acpi/acpi.h b/com32/gplinclude/acpi/acpi.h
index 0ce43f5..664306b 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 219cb1e..fcb6280 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/rsdp.h b/com32/gplinclude/acpi/facs.h
similarity index 60%
copy from com32/gplinclude/acpi/rsdp.h
copy to com32/gplinclude/acpi/facs.h
index 1d8126c..4435eab 100644
--- a/com32/gplinclude/acpi/rsdp.h
+++ b/com32/gplinclude/acpi/facs.h
@@ -10,29 +10,32 @@
  *
  * ----------------------------------------------------------------------- */
 
-#ifndef RSDP_H
-#define RSDP_H
+#ifndef FACS_H
+#define FACS_H
 #include <inttypes.h>
 #include <stdbool.h>
 
-#define RSDP_MIN_ADDRESS 0x0E0000
-#define RSDP_MAX_ADDRESS 0x0FFFFF
+#define FACS "FACS"
 
-#define RSDP "RSD PTR"
+/* Features Flags for "flags" */
+#define S4BIOS_F 1
 
-enum { RSDP_TABLE_FOUND };
+/* Features flags for global_lock */
+#define PENDING 1
+#define OWNED 1<<1
 
 typedef struct {
     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;
+    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_rsdp;
+} s_facs;
 
+void parse_facs(s_facs *facs);
 #endif
diff --git a/com32/gpllib/acpi/sbst.c b/com32/gpllib/acpi/dsdt.c
similarity index 79%
copy from com32/gpllib/acpi/sbst.c
copy to com32/gpllib/acpi/dsdt.c
index 6a41168..3c6e177 100644
--- a/com32/gpllib/acpi/sbst.c
+++ b/com32/gpllib/acpi/dsdt.c
@@ -32,13 +32,15 @@
 #include <dprintf.h>
 #include "acpi/acpi.h"
 
-void parse_sbst(s_sbst * s)
+void parse_dsdt(s_dsdt * d)
 {
     uint8_t *q;
-    q = (uint64_t *) (s->address+ACPI_HEADER_SIZE);
+    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);
+    }
 
-    /* Copying remaining structs */
-    cp_struct(&s->warning_energy_level);
-    cp_struct(&s->low_energy_level);
-    cp_struct(&s->critical_energy_level);
 }
diff --git a/com32/gpllib/acpi/sbst.c b/com32/gpllib/acpi/facs.c
similarity index 78%
copy from com32/gpllib/acpi/sbst.c
copy to com32/gpllib/acpi/facs.c
index 6a41168..0fc0b6b 100644
--- a/com32/gpllib/acpi/sbst.c
+++ b/com32/gpllib/acpi/facs.c
@@ -32,13 +32,19 @@
 #include <dprintf.h>
 #include "acpi/acpi.h"
 
-void parse_sbst(s_sbst * s)
+void parse_facs(s_facs * f)
 {
     uint8_t *q;
-    q = (uint64_t *) (s->address+ACPI_HEADER_SIZE);
-
-    /* Copying remaining structs */
-    cp_struct(&s->warning_energy_level);
-    cp_struct(&s->low_energy_level);
-    cp_struct(&s->critical_energy_level);
+    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 d9e1b8c..ff222b0 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++;
 	}



More information about the Syslinux-commits mailing list