Please bear with me - another rename checkin. This qualifies as trivial, no
[coreboot.git] / src / mainboard / asus / a8v-e_se / acpi_tables.c
1 /*
2  * This file is part of the coreboot project.
3  * written by Stefan Reinauer <stepan@openbios.org>
4  * ACPI FADT, FACS, and DSDT table support added by 
5  *
6  * Copyright (C) 2004 Stefan Reinauer <stepan@openbios.org>
7  * Copyright (C) 2005 Nick Barker <nick.barker9@btinternet.com>
8  * Copyright (C) 2007 Rudolf Marek <r.marek@assembler.cz>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License v2 as published by
12  * the Free Software Foundation.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
22  */
23
24 #include <console/console.h>
25 #include <string.h>
26 #include <arch/acpi.h>
27 #include <arch/smp/mpspec.h>
28 #include <device/device.h>
29 #include <device/pci_ids.h>
30
31 #include <../../../southbridge/via/vt8237r/vt8237r.h>
32 #include <../../../southbridge/via/k8t890/k8t890.h>
33
34 extern unsigned char AmlCode[];
35
36 unsigned long acpi_fill_mcfg(unsigned long current)
37 {
38         device_t dev;
39         struct resource *res;
40         dev = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_K8T890CE_5, 0);
41         if (!dev)
42                 return current;
43
44         res = find_resource(dev, K8T890_MMCONFIG_MBAR);
45         if (res) {
46                 current += acpi_create_mcfg_mmconfig((acpi_mcfg_mmconfig_t *)
47                                 current, res->base, 0x0, 0x0, 0xff);
48         }
49         return current;
50 }
51
52 unsigned long acpi_fill_madt(unsigned long current)
53 {
54         unsigned int gsi_base = 0x18;
55
56         /* create all subtables for processors */
57         current = acpi_create_madt_lapics(current);
58
59         /* Write SB IOAPIC */
60         current +=
61             acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, VT8237R_APIC_ID,
62                                     VT8237R_APIC_BASE, 0);
63
64         /* Write NB IOAPIC */
65         current +=
66             acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, K8T890_APIC_ID,
67                                     K8T890_APIC_BASE, gsi_base);
68         /* IRQ9 ACPI active low */
69         current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *)
70                                                 current, 0, 9, 9, MP_IRQ_TRIGGER_LEVEL | MP_IRQ_POLARITY_LOW);
71
72         /* IRQ0 -> APIC IRQ2 */
73         current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *)
74                                                 current, 0, 0, 2, 0x0); 
75
76         /* create all subtables for processors */
77         current =
78             acpi_create_madt_lapic_nmis(current,
79                                         MP_IRQ_TRIGGER_EDGE |
80                                         MP_IRQ_POLARITY_HIGH, 1);
81
82         return current;
83 }
84
85
86 unsigned long write_acpi_tables(unsigned long start)
87 {
88         unsigned long current;
89         acpi_rsdp_t *rsdp;
90         acpi_srat_t *srat;
91         acpi_rsdt_t *rsdt;
92         acpi_mcfg_t *mcfg;
93         acpi_hpet_t *hpet;
94         acpi_madt_t *madt;
95         acpi_fadt_t *fadt;
96         acpi_facs_t *facs;
97         acpi_header_t *dsdt;
98
99         /* Align ACPI tables to 16byte */
100         start = (start + 0x0f) & -0x10;
101         current = start;
102
103         printk_info("ACPI: Writing ACPI tables at %lx...\n", start);
104
105         /* We need at least an RSDP and an RSDT Table */
106         rsdp = (acpi_rsdp_t *) current;
107         current += sizeof(acpi_rsdp_t);
108         rsdt = (acpi_rsdt_t *) current;
109         current += sizeof(acpi_rsdt_t);
110
111         /* clear all table memory */
112         memset((void *) start, 0, current - start);
113
114         acpi_write_rsdp(rsdp, rsdt);
115         acpi_write_rsdt(rsdt);
116
117         /*
118          * We explicitly add these tables later on:
119          */
120         printk_debug("ACPI:     * FACS\n");
121         facs = (acpi_facs_t *) current;
122         current += sizeof(acpi_facs_t);
123         acpi_create_facs(facs);
124
125         dsdt = (acpi_header_t *) current;
126         current += ((acpi_header_t *) AmlCode)->length;
127         memcpy((void *) dsdt, (void *) AmlCode,
128                ((acpi_header_t *) AmlCode)->length);
129         dsdt->checksum = 0;     // don't trust intel iasl compiler to get this right
130         dsdt->checksum = acpi_checksum(dsdt, dsdt->length);
131         printk_debug("ACPI:     * DSDT @ %08x Length %x\n", dsdt,
132                      dsdt->length);
133         printk_debug("ACPI:     * FADT\n");
134
135         fadt = (acpi_fadt_t *) current;
136         current += sizeof(acpi_fadt_t);
137
138         acpi_create_fadt(fadt, facs, dsdt);
139         acpi_add_table(rsdt, fadt);
140
141         printk_debug("ACPI:    * HPET\n");
142         hpet = (acpi_hpet_t *) current;
143         current += sizeof(acpi_hpet_t);
144         acpi_create_hpet(hpet);
145         acpi_add_table(rsdt, hpet);
146
147         /* If we want to use HPET Timers Linux wants an MADT */
148         printk_debug("ACPI:    * MADT\n");
149         madt = (acpi_madt_t *) current;
150         acpi_create_madt(madt);
151         current += madt->header.length;
152         acpi_add_table(rsdt, madt);
153
154         printk_debug("ACPI:    * MCFG\n");
155         mcfg = (acpi_mcfg_t *) current;
156         acpi_create_mcfg(mcfg);
157         current += mcfg->header.length;
158         acpi_add_table(rsdt, mcfg);
159
160         /* SRAT */
161         printk_debug("ACPI:    * SRAT\n");
162         srat = (acpi_srat_t *) current;
163         acpi_create_srat(srat);
164         current += srat->header.length;
165         acpi_add_table(rsdt, srat);
166
167         printk_info("ACPI: done.\n");
168         return current;
169 }