create MADT tables, too.
authorStefan Reinauer <stepan@openbios.org>
Tue, 3 Feb 2004 16:11:35 +0000 (16:11 +0000)
committerStefan Reinauer <stepan@openbios.org>
Tue, 3 Feb 2004 16:11:35 +0000 (16:11 +0000)
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1366 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1

src/arch/i386/boot/acpi.c
src/arch/i386/include/arch/acpi.h

index 271de845de5fe2128175274411115918d7aa9a46..ca9b66f7443a333ca7547dedd4efc80cc7b6a783 100644 (file)
 
 #define RSDT_NAME             "RSDT"
 #define HPET_NAME             "HPET"
-#define RSDT_TABLE            "  RSDT  "
+#define MADT_NAME             "APIC"
+
+#define RSDT_TABLE            "RSDT    "
 #define HPET_TABLE            "AMD64   "
+#define MADT_TABLE            "MADT    "
 
 #define OEM_ID                "LXBIOS"
 #define ASLC                  "NONE"
@@ -29,6 +32,10 @@ static u8 acpi_checksum(u8 *table, u32 length)
        return -ret;
 }
 
+/*
+ * add an acpi table to rsdt structure, and recalculate checksum
+ */
+
 static void acpi_add_table(acpi_rsdt_t *rsdt, void *table)
 {
        int i;
@@ -50,6 +57,99 @@ static void acpi_add_table(acpi_rsdt_t *rsdt, void *table)
        printk_warning("ACPI: could not ACPI table. failed.\n");
 }
 
+
+static int acpi_create_madt_lapic(acpi_madt_lapic_t *lapic, u8 cpu, u8 apic)
+{
+       lapic->type=0;
+       lapic->length=sizeof(acpi_madt_lapic_t);
+       lapic->flags=1;
+       
+       lapic->processor_id=cpu;
+       lapic->apic_id=apic;
+       
+       return(lapic->length);
+}
+
+static int acpi_create_madt_ioapic(acpi_madt_ioapic_t *ioapic, u8 id, u32 addr) 
+{
+       ioapic->type=1;
+       ioapic->length=sizeof(acpi_madt_ioapic_t);
+       ioapic->reserved=0x00;
+       ioapic->gsi_base=0x00000000;
+       
+       ioapic->ioapic_id=id;
+       ioapic->ioapic_addr=addr;
+       
+       return(ioapic->length);
+}
+
+static int acpi_create_madt_irqoverride(acpi_madt_irqoverride_t *irqoverride,
+               u8 bus, u8 source, u32 gsirq, u16 flags)
+{
+       irqoverride->type=2;
+       irqoverride->length=sizeof(acpi_madt_irqoverride_t);
+       irqoverride->flags=0x0001;
+       
+       irqoverride->bus=bus;
+       irqoverride->source=source;
+       irqoverride->gsirq=gsirq;
+       irqoverride->flags=flags;
+       
+       return(irqoverride->length);
+}
+
+static int acpi_create_madt_lapic_nmi(acpi_madt_lapic_nmi_t *lapic_nmi, u8 cpu,
+               u16 flags, u8 lint)
+{
+       lapic_nmi->type=4;
+       lapic_nmi->length=sizeof(acpi_madt_lapic_nmi_t);
+       
+       lapic_nmi->flags=flags;
+       lapic_nmi->processor_id=cpu;
+       lapic_nmi->lint=lint;
+       
+       return(lapic_nmi->length);
+}
+
+static void acpi_create_madt(acpi_madt_t *madt)
+{
+#define LOCAL_APIC_ADDR        0xfee00000ULL
+#define IO_APIC_ADDR   0xfec00000UL
+       acpi_header_t *header=&(madt->header);
+       unsigned long current=(unsigned long)madt+sizeof(acpi_madt_t);
+       
+       memset((void *)madt, 0, sizeof(acpi_madt_t));
+       
+       /* fill out header fields */
+       memcpy(header->signature, MADT_NAME, 4);
+       memcpy(header->oem_id, OEM_ID, 6);
+       memcpy(header->oem_table_id, MADT_TABLE, 8);
+       memcpy(header->asl_compiler_id, ASLC, 4);
+       
+       header->length = sizeof(acpi_madt_t);
+       header->revision = 1;
+
+       madt->lapic_addr= LOCAL_APIC_ADDR;
+       madt->flags     = 0x1; /* PCAT_COMPAT */
+       
+       /* create all subtables for 1p */
+       current += acpi_create_madt_lapic((acpi_madt_lapic_t *)current, 0, 0);
+       current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *)current, 2,
+                       IO_APIC_ADDR);
+       current += acpi_create_madt_irqoverride( (acpi_madt_irqoverride_t *)
+                       current, 0, 0, 2, 1 /* active high */);
+       current += acpi_create_madt_irqoverride( (acpi_madt_irqoverride_t *)
+                       current, 0, 9, 9, 0xf /* active low, level triggered */);
+       current += acpi_create_madt_lapic_nmi( (acpi_madt_lapic_nmi_t *)
+                       current, 0, 5, 1);
+
+       /* recalculate length */
+       header->length= current - (unsigned long)madt;
+       
+       header->checksum        = acpi_checksum((void *)madt, header->length);
+}
+
+
 static void acpi_create_hpet(acpi_hpet_t *hpet)
 {
 #define HPET_ADDR  0xfed00000ULL
@@ -121,6 +221,7 @@ unsigned long write_acpi_tables(unsigned long start)
        acpi_rsdp_t *rsdp;
        acpi_rsdt_t *rsdt;
        acpi_hpet_t *hpet;
+       acpi_madt_t *madt;
        
        /* Align ACPI tables to 16byte */
        start   = ( start + 0x0f ) & -0x10;
@@ -151,6 +252,16 @@ unsigned long write_acpi_tables(unsigned long start)
        current += sizeof(acpi_hpet_t);
        acpi_create_hpet(hpet);
        acpi_add_table(rsdt,hpet);
+
+       /* If we want to use HPET Timers Linux wants an MADT */
+       printk_debug("ACPI:    * MADT\n");
+
+       madt = (acpi_madt_t *) current;
+       acpi_create_madt(madt);
+       current+=madt->header.length;
+       acpi_add_table(rsdt,madt);
+
+
 #endif
        printk_info("ACPI: done.\n");
        return current;
index 6b6965684c99c9a65526efb2ffdc4be29b2dee21..e840d42195ed28758844c342fa75bb08b1b00276 100644 (file)
@@ -80,6 +80,62 @@ typedef struct acpi_hpet {
        u8 attributes;
 } __attribute__ ((packed)) acpi_hpet_t;
 
+typedef struct acpi_madt {
+       struct acpi_table_header header;
+       u32 lapic_addr;
+       u32 flags;
+} __attribute__ ((packed)) acpi_madt_t;
+
+enum acpi_apic_types {
+       LocalApic               = 0,
+       IOApic                  = 1,
+       IRQSourceOverride       = 2,
+       NMI                     = 3,
+       LocalApicNMI            = 4,
+       LApicAddressOverride    = 5,
+       IOSApic                 = 6,
+       LocalSApic              = 7,
+       PlatformIRQSources      = 8
+};
+
+typedef struct acpi_madt_lapic {
+       u8 type;
+       u8 length;
+       u8 processor_id;
+       u8 apic_id;
+       u32 flags;
+} __attribute__ ((packed)) acpi_madt_lapic_t;
+
+typedef struct acpi_madt_lapic_nmi {
+       u8 type;
+       u8 length;
+       u8 processor_id;
+       u16 flags;
+       u8 lint;
+} __attribute__ ((packed)) acpi_madt_lapic_nmi_t;
+
+
+typedef struct acpi_madt_ioapic {
+       u8 type;
+       u8 length;
+       u8 ioapic_id;
+       u8 reserved;
+       u32 ioapic_addr;
+       u32 gsi_base;
+} __attribute__ ((packed)) acpi_madt_ioapic_t;
+
+typedef struct acpi_madt_irqoverride {
+       u8 type;
+       u8 length;
+       u8 bus;
+       u8 source;
+       u32 gsirq;
+       u16 flags;
+} __attribute__ ((packed)) acpi_madt_irqoverride_t;
+
+
+
+
 
 unsigned long write_acpi_tables(unsigned long addr);