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
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>
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.
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.
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
24 #include <console/console.h>
26 #include <arch/acpi.h>
27 #include <arch/smp/mpspec.h>
28 #include <device/device.h>
29 #include <device/pci_ids.h>
31 #include <../../../southbridge/via/vt8237r/vt8237r.h>
32 #include <../../../southbridge/via/k8t890/k8t890.h>
34 extern unsigned char AmlCode[];
36 unsigned long acpi_fill_mcfg(unsigned long current)
40 dev = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_K8T890CE_5, 0);
44 res = find_resource(dev, K8T890_MMCONFIG_MBAR);
46 current += acpi_create_mcfg_mmconfig((acpi_mcfg_mmconfig_t *)
47 current, res->base, 0x0, 0x0, 0xff);
52 unsigned long acpi_fill_madt(unsigned long current)
54 unsigned int gsi_base = 0x18;
56 /* create all subtables for processors */
57 current = acpi_create_madt_lapics(current);
61 acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, VT8237R_APIC_ID,
62 VT8237R_APIC_BASE, 0);
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);
72 /* IRQ0 -> APIC IRQ2 */
73 current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *)
74 current, 0, 0, 2, 0x0);
76 /* create all subtables for processors */
78 acpi_create_madt_lapic_nmis(current,
80 MP_IRQ_POLARITY_HIGH, 1);
86 unsigned long write_acpi_tables(unsigned long start)
88 unsigned long current;
99 /* Align ACPI tables to 16byte */
100 start = (start + 0x0f) & -0x10;
103 printk_info("ACPI: Writing ACPI tables at %lx...\n", start);
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);
111 /* clear all table memory */
112 memset((void *) start, 0, current - start);
114 acpi_write_rsdp(rsdp, rsdt);
115 acpi_write_rsdt(rsdt);
118 * We explicitly add these tables later on:
120 printk_debug("ACPI: * FACS\n");
121 facs = (acpi_facs_t *) current;
122 current += sizeof(acpi_facs_t);
123 acpi_create_facs(facs);
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,
133 printk_debug("ACPI: * FADT\n");
135 fadt = (acpi_fadt_t *) current;
136 current += sizeof(acpi_fadt_t);
138 acpi_create_fadt(fadt, facs, dsdt);
139 acpi_add_table(rsdt, fadt);
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);
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);
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);
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);
167 printk_info("ACPI: done.\n");