please forgive me... ;)
authorStefan Reinauer <stepan@openbios.org>
Wed, 28 Jan 2004 16:56:14 +0000 (16:56 +0000)
committerStefan Reinauer <stepan@openbios.org>
Wed, 28 Jan 2004 16:56:14 +0000 (16:56 +0000)
 * initial acpi support code
 * fix header

git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1358 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1

src/arch/i386/boot/Config.lb
src/arch/i386/boot/acpi.c [new file with mode: 0644]
src/arch/i386/boot/tables.c
src/arch/i386/include/arch/acpi.h [new file with mode: 0644]
src/config/Options.lb
src/northbridge/amd/amdk8/coherent_ht.c

index ddbfa7b79eb9bc3e281fcbb3dee4e25c4e89d20a..c5a14d0f78d2986c54ed9cb902055bb4714e59f3 100644 (file)
@@ -1,4 +1,5 @@
 uses HAVE_PIRQ_TABLE
+uses HAVE_ACPI_TABLES
 
 object boot.o
 object linuxbios_table.o
@@ -6,4 +7,7 @@ object tables.o
 if HAVE_PIRQ_TABLE
 object pirq_routing.o 
 end
+if HAVE_ACPI_TABLES
+object acpi.o
+end
 
diff --git a/src/arch/i386/boot/acpi.c b/src/arch/i386/boot/acpi.c
new file mode 100644 (file)
index 0000000..6afcd9c
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * LinuxBIOS ACPI Table support
+ * written by Stefan Reinauer <stepan@openbios.org>
+ * (C) 2004 SUSE LINUX AG
+ */
+
+#include <console/console.h>
+#include <string.h>
+#include <arch/acpi.h>
+
+#define RSDP_SIG              "RSD PTR "  /* RSDT Pointer signature */
+#define RSDP_NAME             "RSDP"
+
+#define RSDT_NAME             "RSDT"
+#define HPET_NAME             "HPET"
+#define RSDT_TABLE            "  RSDT  "
+#define HPET_TABLE            "AMD64   "
+
+#define OEM_ID                "LXBIOS"
+#define ASLC                  "NONE"
+
+static u8 acpi_checksum(u8 *table, u32 length)
+{
+       u8 ret=0;
+       while (length--) {
+               ret += *table;
+               table++;
+       }
+       return ret;
+}
+
+static void acpi_add_table(acpi_rsdt_t *rsdt, void *table)
+{
+       int i;
+
+       for (i=0; i<8; i++) {
+               if(rsdt->entry[i]==0) {
+                       rsdt->entry[i]=(u32)table;
+                       /* fix checksum */
+                       /* hope this won't get optimized away */
+                       rsdt->header.checksum=0;
+                       rsdt->header.checksum=acpi_checksum((u8 *)rsdt,
+                                       rsdt->header.length);
+                       
+                       printk_debug("ACPI: added table %d/8\n",i);
+                       return;
+               }
+       }
+
+       printk_warning("ACPI: could not ACPI table. failed.\n");
+}
+
+static void acpi_create_hpet(acpi_hpet_t *hpet)
+{
+#define HPET_ADDR  0xfed00000ULL
+       acpi_header_t *header=&(hpet->header);
+       acpi_addr_t *addr=&(hpet->addr);
+       
+       /* fill out header fields */
+       memcpy(header->signature, HPET_NAME, 4);
+       memcpy(header->oem_id, OEM_ID, 6);
+       memcpy(header->oem_table_id, HPET_TABLE, 8);
+       memcpy(header->asl_compiler_id, ASLC, 4);
+       
+       header->length = sizeof(acpi_hpet_t);
+       header->revision = 1;
+
+       /* fill out HPET address */
+       addr->space_id          = 0; /* Memory */
+       addr->bit_width         = 64;
+       addr->bit_offset        = 0;
+       addr->addrl             = HPET_ADDR & 0xffffffff;
+       addr->addrh             = HPET_ADDR >> 32;
+
+       hpet->id        = 0x102282a0; /* AMD ? */
+       hpet->number    = 0;
+       hpet->min_tick  = 4096;
+       
+}
+
+static void acpi_write_rsdt(acpi_rsdt_t *rsdt)
+{ 
+       acpi_header_t *header=&(rsdt->header);
+       
+       /* fill out header fields */
+       memcpy(header->signature, RSDT_NAME, 4);
+       memcpy(header->oem_id, OEM_ID, 6);
+       memcpy(header->oem_table_id, RSDT_TABLE, 8);
+       memcpy(header->asl_compiler_id, ASLC, 4);
+       
+       header->length = sizeof(acpi_rsdt_t);
+       header->revision = 1;
+       
+       /* fill out entries */
+
+       // entries are filled in later, we come with an empty set.
+       
+       /* fix checksum */
+       
+       header->checksum        = acpi_checksum((void *)rsdt, sizeof(acpi_rsdt_t));
+}
+
+static void acpi_write_rsdp(acpi_rsdp_t *rsdp, acpi_rsdt_t *rsdt)
+{
+       memcpy(rsdp->signature, RSDP_SIG, 8);
+       memcpy(rsdp->oem_id, OEM_ID, 6);
+       
+       rsdp->length            = sizeof(acpi_rsdp_t);
+       rsdp->rsdt_address      = (u32)rsdt;
+       rsdp->checksum          = acpi_checksum((void *)rsdp, sizeof(acpi_rsdp_t));
+       
+}
+
+unsigned long write_acpi_tables(unsigned long start)
+{
+       unsigned long current = start;
+       acpi_rsdp_t *rsdp;
+       acpi_rsdt_t *rsdt;
+       acpi_hpet_t *hpet;
+       
+       printk_info("ACPI: Writing ACPI tables at %lx...\n", start);
+
+       /* We need at least an RSDP and an RSDT Table */
+       rsdp = (acpi_rsdp_t *) current;
+       current += sizeof(acpi_rsdp_t);
+       rsdt = (acpi_rsdt_t *) current;
+       current += sizeof(acpi_rsdt_t);
+
+       /* clear all table memory */
+       memset((void *)start, 0, current - start);
+       
+       acpi_write_rsdp(rsdp, rsdt);
+       acpi_write_rsdt(rsdt);
+       
+       /*
+        * We explicitly add these tables later on:
+        */
+#define HAVE_ACPI_HPET
+#ifdef HAVE_ACPI_HPET
+       printk_debug("ACPI:    * HPET\n");
+
+       hpet = (acpi_hpet_t *) current;
+       current += sizeof(acpi_hpet_t);
+       
+       acpi_create_hpet(hpet);
+       acpi_add_table(rsdt,hpet);
+#endif
+       printk_info("ACPI: done.\n");
+       return current;
+}
+
index 513167188cbb08c589a139c0517d6d0be21d833c..b0fdd23105c37f3f997f36806c35366100148468 100644 (file)
@@ -5,6 +5,7 @@
 #include <boot/linuxbios_tables.h>
 #include <arch/pirq_routing.h>
 #include <arch/smp/mpspec.h>
+#include <arch/acpi.h>
 #include "linuxbios_table.h"
 
 #if CONFIG_SMP && CONFIG_MAX_PHYSICAL_CPUS && (CONFIG_MAX_PHYSICAL_CPUS < CONFIG_MAX_CPUS)
@@ -61,6 +62,10 @@ struct lb_memory *write_tables(struct mem_range *mem, unsigned long *processor_m
        if (low_table_end < 0x500) {
                low_table_end = 0x500;
        }
+
+       /* Write ACPI tables */
+       low_table_end = write_acpi_tables(low_table_end);
+       
        /* The linuxbios table must be in 0-4K or 960K-1M */
        write_linuxbios_table(processor_map, mem,
                              low_table_start, low_table_end,
diff --git a/src/arch/i386/include/arch/acpi.h b/src/arch/i386/include/arch/acpi.h
new file mode 100644 (file)
index 0000000..6b69656
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Initial LinuxBIOS ACPI Support - headers and defines.
+ * 
+ * written by Stefan Reinauer <stepan@openbios.org>
+ * (C) 2004 SUSE LINUX AG
+ *
+ * The ACPI table structs are based on the Linux kernel sources.
+ * 
+ */
+
+
+#ifndef __ASM_ACPI_H
+#define __ASM_ACPI_H
+
+#if HAVE_ACPI_TABLES==1
+
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned int u32;
+typedef unsigned long long u64;
+
+#define RSDP_NAME               "RSDP"
+#define RSDP_SIG                "RSD PTR "  /* RSDT Pointer signature */
+
+/* ACPI 2.0 table RSDP */
+
+typedef struct acpi_rsdp {
+       char  signature[8];
+       u8    checksum;
+       char  oem_id[6];
+       u8    revision;
+       u32   rsdt_address;
+       u32   length;
+       u64   xsdt_address;
+       u8    ext_checksum;
+       u8    reserved[3];
+} __attribute__((packed)) acpi_rsdp_t;
+
+/* Generic Address Container */
+
+typedef struct acpi_gen_regaddr {
+       u8  space_id;
+       u8  bit_width;
+       u8  bit_offset;
+       u8  resv;
+       u32 addrl;
+       u32 addrh;
+} __attribute__ ((packed)) acpi_addr_t;
+
+/* Generic ACPI Header, provided by (almost) all tables */
+
+typedef struct acpi_table_header         /* ACPI common table header */
+{
+       char signature [4];          /* ACPI signature (4 ASCII characters) */\
+       u32  length;                 /* Length of table, in bytes, including header */\
+       u8   revision;               /* ACPI Specification minor version # */\
+       u8   checksum;               /* To make sum of entire table == 0 */\
+       char oem_id [6];             /* OEM identification */\
+       char oem_table_id [8];       /* OEM table identification */\
+       u32  oem_revision;           /* OEM revision number */\
+       char asl_compiler_id [4];    /* ASL compiler vendor ID */\
+       u32  asl_compiler_revision;  /* ASL compiler revision number */
+} __attribute__ ((packed)) acpi_header_t;
+
+/* RSDT */
+
+typedef struct acpi_rsdt {
+       struct acpi_table_header header;
+       u32 entry[8];
+} __attribute__ ((packed)) acpi_rsdt_t;
+
+/* HPET TIMERS */
+
+typedef struct acpi_hpet {
+       struct acpi_table_header header;
+       u32 id;
+       struct acpi_gen_regaddr addr;
+       u8 number;
+       u16 min_tick;
+       u8 attributes;
+} __attribute__ ((packed)) acpi_hpet_t;
+
+
+unsigned long write_acpi_tables(unsigned long addr);
+
+#else // HAVE_ACPI_TABLES
+
+#define write_acpi_tables(start) (start)
+
+#endif
+
+#endif
index 2c12cf62c89890ee7cf4978689df6f749f543d64..936f9c3727fbfb6dc88a2a6d7c382a9874bce274 100644 (file)
@@ -641,6 +641,13 @@ define FAKE_SPDROM
        comment "Use this to fake spd rom values"
 end
 
+define HAVE_ACPI_TABLES
+       default 0
+       export always
+       comment "Define to build ACPI tables"
+end
+
+
 ###############################################
 # Board specific options
 ###############################################
index f05ee3d22db4c584748a4ac01d520befeccb4a95..61880ec5f606b1701c9443095525e81696c61581 100644 (file)
@@ -1,5 +1,5 @@
 /* coherent hypertransport initialization for AMD64 
- * written by Stefan Reinauer <stepan@openbios.info>
+ * written by Stefan Reinauer <stepan@openbios.org>
  * (c) 2003 by SuSE Linux AG
  *
  * This code is licensed under GPL.