mainboard: New port Packard Bell LM85.
[coreboot.git] / src / mainboard / packardbell / ms2290 / acpi_tables.c
blob165de0d404ebabca7d88665933976a402b4f1528
1 /*
2 * This file is part of the coreboot project.
4 * Copyright (C) 2007-2009 coresystems GmbH
5 * Copyright (C) 2013 Vladimir Serbinenko <phcoder@gmail.com>
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; version 2 of
10 * the License.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
20 * MA 02110-1301 USA
23 #include <string.h>
24 #include <console/console.h>
25 #include <arch/io.h>
26 #include <arch/ioapic.h>
27 #include <arch/acpi.h>
28 #include <arch/acpigen.h>
29 #include <arch/smp/mpspec.h>
30 #include <device/device.h>
31 #include <device/pci.h>
32 #include <device/pci_ids.h>
33 #include "southbridge/intel/ibexpeak/nvs.h"
35 extern const unsigned char AmlCode[];
36 #if CONFIG_HAVE_ACPI_SLIC
37 unsigned long acpi_create_slic(unsigned long current);
38 #endif
40 static void acpi_create_gnvs(global_nvs_t * gnvs)
42 memset((void *)gnvs, 0, sizeof(*gnvs));
43 gnvs->apic = 1;
44 gnvs->mpen = 1; /* Enable Multi Processing */
45 gnvs->pcnt = dev_count_cpu();
47 /* IGD Displays */
48 gnvs->ndid = 3;
49 gnvs->did[0] = 0x80000100;
50 gnvs->did[1] = 0x80000240;
51 gnvs->did[2] = 0x80000410;
52 gnvs->did[3] = 0x80000410;
53 gnvs->did[4] = 0x00000005;
56 unsigned long acpi_fill_madt(unsigned long current)
58 /* Local APICs */
59 current = acpi_create_madt_lapics(current);
61 /* IOAPIC */
62 current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current,
63 1, IO_APIC_ADDR, 0);
65 /* INT_SRC_OVR */
66 current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *)
67 current, 0, 0, 2,
68 MP_IRQ_POLARITY_DEFAULT |
69 MP_IRQ_TRIGGER_DEFAULT);
70 current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *)
71 current, 0, 9, 9,
72 MP_IRQ_POLARITY_HIGH |
73 MP_IRQ_TRIGGER_LEVEL);
75 /* LAPIC_NMI */
76 current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *)
77 current, 0,
78 MP_IRQ_POLARITY_HIGH |
79 MP_IRQ_TRIGGER_EDGE, 0x01);
80 current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *)
81 current, 1, MP_IRQ_POLARITY_HIGH |
82 MP_IRQ_TRIGGER_EDGE, 0x01);
83 current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *)
84 current, 2, MP_IRQ_POLARITY_HIGH |
85 MP_IRQ_TRIGGER_EDGE, 0x01);
86 current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *)
87 current, 3, MP_IRQ_POLARITY_HIGH |
88 MP_IRQ_TRIGGER_EDGE, 0x01);
89 return current;
92 unsigned long acpi_fill_ssdt_generator(unsigned long current,
93 const char *oem_table_id)
95 generate_cpu_entries();
96 return (unsigned long)(acpigen_get_current());
99 unsigned long acpi_fill_slit(unsigned long current)
101 /* Not implemented */
102 return current;
105 unsigned long acpi_fill_srat(unsigned long current)
107 /* No NUMA, no SRAT */
108 return current;
111 void smm_setup_structures(void *gnvs, void *tcg, void *smi1);
113 #define ALIGN_CURRENT current = (ALIGN(current, 16))
114 unsigned long write_acpi_tables(unsigned long start)
116 unsigned long current;
117 int i;
118 acpi_rsdp_t *rsdp;
119 acpi_rsdt_t *rsdt;
120 acpi_xsdt_t *xsdt;
121 acpi_hpet_t *hpet;
122 acpi_madt_t *madt;
123 acpi_mcfg_t *mcfg;
124 acpi_fadt_t *fadt;
125 acpi_facs_t *facs;
126 #if CONFIG_HAVE_ACPI_SLIC
127 acpi_header_t *slic;
128 #endif
129 acpi_header_t *ssdt;
130 acpi_header_t *dsdt;
131 void *gnvs;
133 current = start;
135 /* Align ACPI tables to 16byte */
136 ALIGN_CURRENT;
138 printk(BIOS_INFO, "ACPI: Writing ACPI tables at %lx.\n", start);
140 /* We need at least an RSDP and an RSDT Table */
141 rsdp = (acpi_rsdp_t *) current;
142 current += sizeof(acpi_rsdp_t);
143 ALIGN_CURRENT;
144 rsdt = (acpi_rsdt_t *) current;
145 current += sizeof(acpi_rsdt_t);
146 ALIGN_CURRENT;
147 xsdt = (acpi_xsdt_t *) current;
148 current += sizeof(acpi_xsdt_t);
149 ALIGN_CURRENT;
151 /* clear all table memory */
152 memset((void *)start, 0, current - start);
154 acpi_write_rsdp(rsdp, rsdt, xsdt);
155 acpi_write_rsdt(rsdt);
156 acpi_write_xsdt(xsdt);
159 * We explicitly add these tables later on:
161 printk(BIOS_DEBUG, "ACPI: * HPET\n");
163 hpet = (acpi_hpet_t *) current;
164 current += sizeof(acpi_hpet_t);
165 ALIGN_CURRENT;
166 acpi_create_hpet(hpet);
167 acpi_add_table(rsdp, hpet);
169 /* If we want to use HPET Timers Linux wants an MADT */
170 printk(BIOS_DEBUG, "ACPI: * MADT\n");
172 madt = (acpi_madt_t *) current;
173 acpi_create_madt(madt);
174 current += madt->header.length;
175 ALIGN_CURRENT;
176 acpi_add_table(rsdp, madt);
178 printk(BIOS_DEBUG, "ACPI: * MCFG\n");
179 mcfg = (acpi_mcfg_t *) current;
180 acpi_create_mcfg(mcfg);
181 current += mcfg->header.length;
182 ALIGN_CURRENT;
183 acpi_add_table(rsdp, mcfg);
185 printk(BIOS_DEBUG, "ACPI: * FACS\n");
186 facs = (acpi_facs_t *) current;
187 current += sizeof(acpi_facs_t);
188 ALIGN_CURRENT;
189 acpi_create_facs(facs);
191 dsdt = (acpi_header_t *) current;
192 memcpy(dsdt, &AmlCode, sizeof(acpi_header_t));
193 current += dsdt->length;
194 memcpy(dsdt, &AmlCode, dsdt->length);
196 /* Fix up global NVS region for SMI handler. The GNVS region lives
197 * in the (high) table area. The low memory map looks like this:
199 * 0x00000000 - 0x000003ff Real Mode IVT
200 * 0x00000400 - 0x000004ff BDA (somewhat unused)
201 * 0x00000500 - 0x0000052f Moved GDT
202 * 0x00000530 - 0x00000b64 coreboot table
203 * 0x0007c000 - 0x0007dfff OS boot sector (unused?)
204 * 0x0007e000 - 0x0007ffff free to use (so no good for acpi+smi)
205 * 0x00080000 - 0x0009fbff usable ram
206 * 0x0009fc00 - 0x0009ffff EBDA (unused?)
207 * 0x000a0000 - 0x000bffff VGA memory
208 * 0x000c0000 - 0x000cffff VGA option rom
209 * 0x000d0000 - 0x000dffff free for other option roms?
210 * 0x000e0000 - 0x000fffff SeaBIOS? (if payload is SeaBIOS it
211 overwrites those tables when
212 loading but uses tables at the RAM
213 end to put the tables again in suitable
214 place)
215 * 0x000f0000 - 0x000f03ff PIRQ table
216 * 0x000f0400 - 0x000f66?? ACPI tables
217 * 0x000f66?? - 0x000f???? DMI tables
220 ALIGN_CURRENT;
222 /* Pack GNVS into the ACPI table area */
223 for (i = 0; i < dsdt->length; i++) {
224 if (*(u32 *) (((u32) dsdt) + i) == 0xC0DEBABE) {
225 printk(BIOS_DEBUG,
226 "ACPI: Patching up global NVS in DSDT at offset 0x%04x -> 0x%08x\n",
227 i, (u32) current);
228 *(u32 *) (((u32) dsdt) + i) = current;
229 break;
233 /* And fill it */
234 acpi_create_gnvs((global_nvs_t *) current);
236 /* Keep pointer around */
237 gnvs = (void *)current;
239 current += 0x100;
240 ALIGN_CURRENT;
242 /* And tell SMI about it */
243 smm_setup_structures(gnvs, NULL, NULL);
245 /* We patched up the DSDT, so we need to recalculate the checksum */
246 dsdt->checksum = 0;
247 dsdt->checksum = acpi_checksum((void *)dsdt, dsdt->length);
249 printk(BIOS_DEBUG, "ACPI: * DSDT @ %p Length %x\n", dsdt,
250 dsdt->length);
252 #if CONFIG_HAVE_ACPI_SLIC
253 printk(BIOS_DEBUG, "ACPI: * SLIC\n");
254 slic = (acpi_header_t *) current;
255 current += acpi_create_slic(current);
256 ALIGN_CURRENT;
257 acpi_add_table(rsdp, slic);
258 #endif
260 printk(BIOS_DEBUG, "ACPI: * FADT\n");
261 fadt = (acpi_fadt_t *) current;
262 current += sizeof(acpi_fadt_t);
263 ALIGN_CURRENT;
265 acpi_create_fadt(fadt, facs, dsdt);
266 acpi_add_table(rsdp, fadt);
268 printk(BIOS_DEBUG, "ACPI: * SSDT\n");
269 ssdt = (acpi_header_t *) current;
270 acpi_create_ssdt_generator(ssdt, ACPI_TABLE_CREATOR);
271 current += ssdt->length;
272 acpi_add_table(rsdp, ssdt);
273 ALIGN_CURRENT;
275 printk(BIOS_DEBUG, "current = %lx\n", current);
276 printk(BIOS_INFO, "ACPI: done.\n");
278 /* Enable Dummy DCC ON# for DVI */
279 printk(BIOS_DEBUG, "Laptop handling...\n");
280 outb(inb(0x60f) & ~(1 << 5), 0x60f);
282 return current;