2 * This file is part of the coreboot project.
4 * Copyright (C) 2012 Advanced Micro Devices, Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 #include <console/console.h>
22 #include <arch/acpi.h>
23 #include <arch/acpigen.h>
24 #include <arch/ioapic.h>
26 #include <device/pci.h>
27 #include <device/pci_ids.h>
28 #include <cpu/x86/msr.h>
29 #include <cpu/amd/mtrr.h>
31 #include "agesawrapper.h"
33 #define DUMP_ACPI_TABLES 0
35 #if DUMP_ACPI_TABLES == 1
36 static void dump_mem(u32 start
, u32 end
)
40 print_debug("dump_mem:");
41 for (i
= start
; i
< end
; i
++) {
43 printk(BIOS_DEBUG
, "\n%08x:", i
);
45 printk(BIOS_DEBUG
, " %02x", (u8
)*((u8
*)i
));
51 extern const unsigned char AmlCode
[];
54 unsigned long acpi_fill_mcfg(unsigned long current
)
60 unsigned long acpi_fill_madt(unsigned long current
)
69 * AGESA v5 Apply apic enumeration rules
70 * For systems with >= 16 APICs, put the IO-APICs at 0..n and
71 * put the local-APICs at m..z
72 * For systems with < 16 APICs, put the Local-APICs at 0..n and
73 * put the IO-APICs at (n + 1)..z
75 #if CONFIG_MAX_CPUS >= 16
78 apicid_sb700
= CONFIG_MAX_CPUS
+ 1
80 apicid_rd890
= apicid_sb700
+ 1;
82 /* create all subtables for processors */
83 current
= acpi_create_madt_lapics(current
);
85 /* Write sb700 IOAPIC, only one */
86 current
+= acpi_create_madt_ioapic((acpi_madt_ioapic_t
*) current
,
92 /* IOAPIC on rs5690 */
93 gsi_base
+= IO_APIC_INTERRUPTS
; /* sb700 has 24 IOAPIC entries. */
94 dev
= dev_find_slot(0, PCI_DEVFN(0, 0));
96 pci_write_config32(dev
, 0xF8, 0x1);
97 dword
= pci_read_config32(dev
, 0xFC) & 0xfffffff0;
98 current
+= acpi_create_madt_ioapic((acpi_madt_ioapic_t
*) current
,
105 current
+= acpi_create_madt_irqoverride((acpi_madt_irqoverride_t
*) current
,
112 /* 0: mean bus 0--->ISA */
115 /* 5 mean: 0101 --> Edige-triggered, Active high */
117 /* create all subtables for processors */
118 current
+= acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t
*)current
, 0, 5, 1);
119 current
+= acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t
*)current
, 1, 5, 1);
120 /* 1: LINT1 connect to NMI */
125 unsigned long acpi_fill_hest(acpi_hest_t
*hest
)
127 void *addr
, *current
;
129 /* Skip the HEST header. */
130 current
= (void *)(hest
+ 1);
132 addr
= agesawrapper_getlateinitptr(PICK_WHEA_MCE
);
134 current
+= acpi_create_hest_error_source(hest
, current
, 0, (void *)((u32
)addr
+ 2), *(UINT16
*)addr
- 2);
136 addr
= agesawrapper_getlateinitptr(PICK_WHEA_CMC
);
138 current
+= acpi_create_hest_error_source(hest
, current
, 1, (void *)((u32
)addr
+ 2), *(UINT16
*)addr
- 2);
140 return (unsigned long)current
;
143 unsigned long acpi_fill_slit(unsigned long current
)
149 unsigned long acpi_fill_srat(unsigned long current
)
151 /* No NUMA, no SRAT */
155 unsigned long acpi_fill_ssdt_generator(unsigned long current
, const char *oem_table_id
)
159 char pscope
[] = "\\_SB.PCI0";
161 lens
= acpigen_write_scope(pscope
);
162 msr
= rdmsr(TOP_MEM
);
163 lens
+= acpigen_write_name_dword("TOM1", msr
.lo
);
164 msr
= rdmsr(TOP_MEM2
);
166 * Since XP only implements parts of ACPI 2.0, we can't use a qword
168 * See http://www.acpi.info/presentations/S01USMOBS169_OS%2520new.ppt
170 * Shift value right by 20 bit to make it fit into 32bit,
171 * giving us 1MB granularity and a limit of almost 4Exabyte of memory.
173 lens
+= acpigen_write_name_dword("TOM2", (msr
.hi
<< 12) | msr
.lo
>> 20);
174 acpigen_patch_len(lens
- 1);
175 return (unsigned long) (acpigen_get_current());
178 unsigned long write_acpi_tables(unsigned long start
)
180 unsigned long current
;
191 acpi_header_t
*ssdt2
;
195 get_bus_conf(); /* it will get sblk, pci1234, hcdn, and sbdn */
197 /* Align ACPI tables to 16 bytes */
198 start
= (start
+ 0x0f) & -0x10;
201 printk(BIOS_INFO
, "ACPI: Writing ACPI tables at %lx...\n", start
);
203 /* We need at least an RSDP and an RSDT Table */
204 rsdp
= (acpi_rsdp_t
*) current
;
205 current
+= sizeof(acpi_rsdp_t
);
206 rsdt
= (acpi_rsdt_t
*) current
;
207 current
+= sizeof(acpi_rsdt_t
);
209 /* clear all table memory */
210 memset((void *)start
, 0, current
- start
);
212 acpi_write_rsdp(rsdp
, rsdt
, NULL
);
213 acpi_write_rsdt(rsdt
);
216 printk(BIOS_DEBUG
, "ACPI: * FACS\n");
217 facs
= (acpi_facs_t
*) current
;
218 current
+= sizeof(acpi_facs_t
);
219 acpi_create_facs(facs
);
222 printk(BIOS_DEBUG
, "ACPI: * DSDT\n");
223 dsdt
= (acpi_header_t
*)current
;
224 memcpy(dsdt
, &AmlCode
, sizeof(acpi_header_t
));
225 current
+= dsdt
->length
;
226 memcpy(dsdt
, &AmlCode
, dsdt
->length
);
227 printk(BIOS_DEBUG
, "ACPI: * DSDT @ %p Length %x\n", dsdt
, dsdt
->length
);
229 printk(BIOS_DEBUG
, "ACPI: * FADT\n");
230 fadt
= (acpi_fadt_t
*) current
;
231 current
+= sizeof(acpi_fadt_t
);
233 acpi_create_fadt(fadt
, facs
, dsdt
);
234 acpi_add_table(rsdp
, fadt
);
237 * We explicitly add these tables later on:
239 #ifdef UNUSED_CODE // Don't need HPET table. we have one in dsdt
240 current
= (current
+ 0x07) & -0x08;
241 printk(BIOS_DEBUG
, "ACPI: * HPET at %lx\n", current
);
242 hpet
= (acpi_hpet_t
*) current
;
243 current
+= sizeof(acpi_hpet_t
);
244 acpi_create_hpet(hpet
);
245 acpi_add_table(rsdp
, hpet
);
248 /* If we want to use HPET Timers Linux wants an MADT */
249 current
= (current
+ 0x07) & -0x08;
250 printk(BIOS_DEBUG
, "ACPI: * MADT at %lx\n",current
);
251 madt
= (acpi_madt_t
*) current
;
252 acpi_create_madt(madt
);
253 current
+= madt
->header
.length
;
254 acpi_add_table(rsdp
, madt
);
257 current
= (current
+ 0x07) & -0x08;
258 hest
= (acpi_hest_t
*)current
;
259 acpi_write_hest((void *)current
);
260 acpi_add_table(rsdp
, (void *)current
);
261 current
+= ((acpi_header_t
*)current
)->length
;
264 current
= (current
+ 0x07) & -0x08;
265 printk(BIOS_DEBUG
, "ACPI: * SRAT at %lx\n", current
);
266 srat
= (acpi_srat_t
*) agesawrapper_getlateinitptr (PICK_SRAT
);
268 memcpy((void *)current
, srat
, srat
->header
.length
);
269 srat
= (acpi_srat_t
*) current
;
270 //acpi_create_srat(srat);
271 current
+= srat
->header
.length
;
272 acpi_add_table(rsdp
, srat
);
276 current
= (current
+ 0x07) & -0x08;
277 printk(BIOS_DEBUG
, "ACPI: * SLIT at %lx\n", current
);
278 slit
= (acpi_slit_t
*) agesawrapper_getlateinitptr (PICK_SLIT
);
280 memcpy((void *)current
, slit
, slit
->header
.length
);
281 slit
= (acpi_slit_t
*) current
;
282 //acpi_create_slit(slit);
283 current
+= slit
->header
.length
;
284 acpi_add_table(rsdp
, slit
);
288 current
= (current
+ 0x0f) & -0x10;
289 printk(BIOS_DEBUG
, "ACPI: * AGESA ALIB SSDT at %lx\n", current
);
290 alib
= (acpi_header_t
*)agesawrapper_getlateinitptr (PICK_ALIB
);
292 memcpy((void *)current
, alib
, alib
->length
);
293 alib
= (acpi_header_t
*) current
;
294 current
+= alib
->length
;
295 acpi_add_table(rsdp
, (void *)alib
);
297 printk(BIOS_DEBUG
, " AGESA ALIB SSDT table NULL. Skipping.\n");
300 /* The DSDT needs additional work for the AGESA SSDT Pstate table */
301 /* Keep the comment for a while. */
302 current
= (current
+ 0x0f) & -0x10;
303 printk(BIOS_DEBUG
, "ACPI: * AGESA SSDT Pstate at %lx\n", current
);
304 ssdt
= (acpi_header_t
*)agesawrapper_getlateinitptr (PICK_PSTATE
);
306 memcpy((void *)current
, ssdt
, ssdt
->length
);
307 ssdt
= (acpi_header_t
*) current
;
308 current
+= ssdt
->length
;
309 acpi_add_table(rsdp
,ssdt
);
311 printk(BIOS_DEBUG
, " AGESA SSDT Pstate table NULL. Skipping.\n");
314 current
= (current
+ 0x0f) & -0x10;
315 printk(BIOS_DEBUG
, "ACPI: * coreboot TOM SSDT2 at %lx\n", current
);
316 ssdt2
= (acpi_header_t
*) current
;
317 acpi_create_ssdt_generator(ssdt2
, ACPI_TABLE_CREATOR
);
318 current
+= ssdt2
->length
;
319 acpi_add_table(rsdp
,ssdt2
);
321 #if DUMP_ACPI_TABLES == 1
322 printk(BIOS_DEBUG
, "rsdp\n");
323 dump_mem(rsdp
, ((void *)rsdp
) + sizeof(acpi_rsdp_t
));
325 printk(BIOS_DEBUG
, "rsdt\n");
326 dump_mem(rsdt
, ((void *)rsdt
) + sizeof(acpi_rsdt_t
));
328 printk(BIOS_DEBUG
, "madt\n");
329 dump_mem(madt
, ((void *)madt
) + madt
->header
.length
);
331 printk(BIOS_DEBUG
, "srat\n");
332 dump_mem(srat
, ((void *)srat
) + srat
->header
.length
);
334 printk(BIOS_DEBUG
, "slit\n");
335 dump_mem(slit
, ((void *)slit
) + slit
->header
.length
);
337 printk(BIOS_DEBUG
, "ssdt\n");
338 dump_mem(ssdt
, ((void *)ssdt
) + ssdt
->length
);
340 printk(BIOS_DEBUG
, "fadt\n");
341 dump_mem(fadt
, ((void *)fadt
) + fadt
->header
.length
);
343 printk(BIOS_DEBUG
, "hest\n");
344 dump_mem(hest
, ((void *)hest
) + hest
->header
.length
);
347 printk(BIOS_INFO
, "ACPI: done.\n");