acpi: Adding madt apic structures
authorErwan Velu <erwan.velu@free.fr>
Fri, 4 Dec 2009 11:30:19 +0000 (12:30 +0100)
committerErwan Velu <erwan.velu@free.fr>
Fri, 4 Dec 2009 11:30:19 +0000 (12:30 +0100)
Impact: Adding more madt apic structures

Adding IO_APIC, INTERRUPT_SOURCE_OVERRIDE, NMI,
LOCAL_APIC_NMI_STRUCTURE,  LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE,
IO_SAPIC, LOCAL_SAPIC

com32/gplinclude/acpi/madt.h
com32/gpllib/acpi/madt.c

index 8627edd..d918a2f 100644 (file)
@@ -30,24 +30,127 @@ enum {
     PLATEFORM_INTERRUPT_SOURCES = 8
 };
 
-#define MAX_SLP 255
+/* Features flags for 
+ * - processor_local_apic flags
+ * - local sapic flags
+ */
+#define PROCESSOR_LOCAL_APIC_ENABLE 1
 
+#define MAX_S_L_P 255
 typedef struct {
+    uint8_t type;
     uint8_t length;
     uint8_t acpi_id;
     uint8_t apic_id;
     uint32_t flags;
 } __attribute__ ((packed)) s_processor_local_apic;
 
+#define MAX_IO_APIC 255
+typedef struct {
+    uint8_t type;
+    uint8_t length;
+    uint8_t io_apic_id;
+    uint8_t reserved;
+    uint32_t io_apic_address;
+    uint32_t global_system_interrupt_base;
+} __attribute__ ((packed)) s_io_apic;
+
+/* Features flags for
+ * - interrupt_source_override
+ * - nmi
+ */
+/* Bits 1&2 must be set to 0 */
+#define POLARITY_CONFORM_MASK 0x0
+#define POLARITY_ACTIVE_HIGH 0x1
+#define POLARITY_RESERVED 0x2
+#define POLARITY_ACTIVE_LOW 0x3
+/* Bits 3&4 must be set to 0 */
+#define TRIGGER_CONFORM_MASK 0x3
+#define TRIGGER_EDGE 0x4
+#define TRIGGER_RESERVED 0x8
+#define TRIGGER_LEVEL 0xA
+
+#define MAX_I_S_O 255
+typedef struct {
+    uint8_t type;
+    uint8_t length;
+    uint8_t bus;
+    uint8_t source;
+    uint32_t global_system_interrupt;
+    uint16_t flags;
+} __attribute__ ((packed)) s_interrupt_source_override;
+
+typedef struct {
+    uint8_t type;
+    uint8_t length;
+    uint8_t flags;
+    uint32_t global_system_interrupt;
+} __attribute__ ((packed)) s_nmi;
+
+#define MAX_LOCAL_APIC_NMI 255
+typedef struct {
+    uint8_t type;
+    uint8_t length;
+    uint8_t acpi_processor_id;
+    uint16_t flags;
+    uint8_t local_apic_lint;
+} __attribute__ ((packed)) s_local_apic_nmi;
+
+#define MAX_L_A_A_O 255
+typedef struct {
+    uint8_t type;
+    uint8_t length;
+    uint16_t reserved;
+    uint64_t local_apic_address;
+} __attribute__ ((packed)) s_local_apic_address_override;
+
+#define MAX_IO_SAPIC 255
+typedef struct {
+    uint8_t type;
+    uint8_t length;
+    uint8_t io_apic_id;
+    uint8_t reserved;
+    uint32_t global_system_interrupt_base;
+    uint64_t io_sapic_address;
+} __attribute__ ((packed)) s_io_sapic;
+
+#define ACPI_PROCESSOR_UID_STRING_OFFSET 16
+#define MAX_LOCAL_SAPIC 255
+typedef struct {
+    uint8_t type;
+    uint8_t length;
+    uint8_t acpi_processor_id;
+    uint8_t local_sapic_id;
+    uint8_t local_sapic_eid;
+    uint8_t reserved[3];
+    uint32_t flags;
+    uint32_t acpi_processor_uid_value;
+    char *acpi_processor_uid_string;
+} __attribute__ ((packed)) s_local_sapic;
+
 typedef struct {
     uint64_t address;
     s_acpi_description_header header;
     uint32_t local_apic_address;
     uint32_t flags;
-    s_processor_local_apic processor_local_apic[MAX_SLP];
+    s_processor_local_apic processor_local_apic[MAX_S_L_P];
     uint8_t processor_local_apic_count;
+    s_io_apic io_apic[MAX_IO_APIC];
+    uint8_t io_apic_count;
+    s_interrupt_source_override interrupt_source_override[MAX_I_S_O];
+    uint8_t interrupt_source_override_count;
+    s_nmi nmi[MAX_I_S_O];
+    uint8_t nmi_count;
+    s_local_apic_nmi local_apic_nmi[MAX_LOCAL_APIC_NMI];
+    uint8_t local_apic_nmi_count;
+    s_local_apic_address_override local_apic_address_override[MAX_L_A_A_O];
+    uint8_t local_apic_address_override_count;
+    s_io_sapic io_sapic[MAX_IO_SAPIC];
+    uint8_t io_sapic_count;
+    s_local_sapic local_sapic[MAX_LOCAL_SAPIC];
+    uint8_t local_sapic_count;
     bool valid;
 } s_madt;
 
-void print_madt(s_madt *madt);
+void print_madt(s_madt * madt);
 #endif
index d71aecc..d0bf69d 100644 (file)
@@ -47,22 +47,107 @@ static uint8_t *add_apic_structure(s_acpi * acpi, uint8_t * q)
     uint8_t length = *q;
     q++;
     s_processor_local_apic *sla;
+    s_io_apic *sio;
+    s_interrupt_source_override *siso;
+    s_nmi *snmi;
+    s_local_apic_nmi *slan;
+    s_local_apic_address_override *slaao;
+    s_io_sapic *siosapic;
+    s_local_sapic *sls;
     s_madt *madt = &acpi->madt;
+
     switch (type) {
     case PROCESSOR_LOCAL_APIC:
-       sla=&madt->processor_local_apic[madt->processor_local_apic_count];
+       sla = &madt->processor_local_apic[madt->processor_local_apic_count];
+       sla->type = type;
        sla->length = length;
-       sla->acpi_id = *q;
-       q++;
-       sla->apic_id = *q;
-       q++;
-       memcpy(&sla->flags, q, 4);
-       q += 4;
-#ifdef DEBUG 
+       cp_struct(&sla->acpi_id);
+       cp_struct(&sla->apic_id);
+       cp_struct(&sla->flags);
+#ifdef DEBUG
        print_local_apic_structure(sla, madt->processor_local_apic_count);
 #endif
        madt->processor_local_apic_count++;
        break;
+    case IO_APIC:
+       sio = &madt->io_apic[madt->io_apic_count];
+       sio->type = type;
+       sio->length = length;
+       cp_struct(&sio->io_apic_id);
+       cp_struct(&sio->reserved);
+       cp_struct(&sio->io_apic_address);
+       cp_struct(&sio->global_system_interrupt_base);
+       madt->io_apic_count++;
+       break;
+    case INTERRUPT_SOURCE_OVERRIDE:
+       siso =
+           &madt->interrupt_source_override[madt->
+                                            interrupt_source_override_count];
+       siso->type = type;
+       siso->length = length;
+       siso->bus = *q;
+       q++;
+       siso->source = *q;
+       q++;
+       cp_struct(&siso->global_system_interrupt);
+       cp_struct(&siso->flags);
+       madt->interrupt_source_override_count++;
+       break;
+    case NMI:
+       snmi = &madt->nmi[madt->nmi_count];
+       snmi->type = type;
+       snmi->length = length;
+       cp_struct(&snmi->flags);
+       cp_struct(&snmi->global_system_interrupt);
+       madt->nmi_count++;
+       break;
+    case LOCAL_APIC_NMI_STRUCTURE:
+       slan = &madt->local_apic_nmi[madt->local_apic_nmi_count];
+       slan->type = type;
+       slan->length = length;
+       cp_struct(&slan->acpi_processor_id);
+       cp_struct(&slan->flags);
+       cp_struct(&slan->local_apic_lint);
+       madt->local_apic_nmi_count++;
+       break;
+    case LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE:
+       slaao =
+           &madt->local_apic_address_override[madt->
+                                              local_apic_address_override_count];
+       slaao->type = type;
+       slaao->length = length;
+       cp_struct(&slaao->reserved);
+       cp_struct(&slaao->local_apic_address);
+       madt->local_apic_address_override_count++;
+       break;
+    case IO_SAPIC:
+       siosapic = &madt->io_sapic[madt->io_sapic_count];
+       siosapic->type = type;
+       siosapic->length = length;
+       cp_struct(&siosapic->io_apic_id);
+       cp_struct(&siosapic->reserved);
+       cp_struct(&siosapic->global_system_interrupt_base);
+       cp_struct(&siosapic->io_sapic_address);
+       madt->io_sapic_count++;
+       break;
+    case LOCAL_SAPIC:
+       sls = &madt->local_sapic[madt->local_sapic_count];
+       sls->type = type;
+       sls->length = length;
+       cp_struct(&sls->acpi_processor_id);
+       cp_struct(&sls->local_sapic_id);
+       cp_struct(&sls->local_sapic_eid);
+       cp_struct(sls->reserved);
+       cp_struct(&sls->flags);
+       cp_struct(&sls->acpi_processor_uid_value);
+       if ((sls->acpi_processor_uid_string =
+            malloc(length - ACPI_PROCESSOR_UID_STRING_OFFSET)) != NULL) {
+           memcpy(sls->acpi_processor_uid_string, q,
+                  length - ACPI_PROCESSOR_UID_STRING_OFFSET);
+           q += length - ACPI_PROCESSOR_UID_STRING_OFFSET;
+       }
+       madt->local_sapic_count++;
+       break;
     default:
        dprintf("APIC structure type %u, size=%u \n", type, length);
        q += length - 2;
@@ -71,19 +156,19 @@ static uint8_t *add_apic_structure(s_acpi * acpi, uint8_t * q)
     return q;
 }
 
-void parse_madt(s_acpi *acpi)
+void parse_madt(s_acpi * acpi)
 {
     /* Let's seach for FADT table */
     uint8_t *q;
     s_madt *m = &acpi->madt;
 
     /* Fixing table name */
-    memcpy(m->header.signature,MADT,sizeof(MADT));
+    memcpy(m->header.signature, MADT, sizeof(MADT));
 
     /* Copying remaining structs */
-    q = (uint64_t *) (m->address+ACPI_HEADER_SIZE);
+    q = (uint64_t *) (m->address + ACPI_HEADER_SIZE);
     while (q < (m->address + m->header.length)) {
-       q=add_apic_structure(acpi, q);
+       q = add_apic_structure(acpi, q);
     }
 }
 
@@ -91,7 +176,7 @@ void print_madt(s_madt * madt)
 {
     if (!madt->valid)
        return;
-    printf("MADT Table @ 0x%016llx\n",madt->address);
+    printf("MADT Table @ 0x%016llx\n", madt->address);
     printf(" signature      : %s\n", madt->header.signature);
     printf(" length         : %d\n", madt->header.length);
     printf(" revision       : %u\n", madt->header.revision);