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
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;
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);
}
}
{
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);