blob: fc6f1863ae56ac1de148e89a47cb68aae483ac9a [file] [log] [blame]
Wang Qing Pei0ede4c02010-08-17 15:19:32 +00001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2010 Wang Qing Pei <wangqingpei@gmail.com>
5 * Copyright (C) 2010 Advanced Micro Devices, Inc.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
Paul Menzela46a7122013-02-23 18:37:27 +010018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Wang Qing Pei0ede4c02010-08-17 15:19:32 +000019 */
20
21#include <console/console.h>
22#include <string.h>
23#include <arch/acpi.h>
Uwe Hermann74d1a6e2010-10-12 17:34:08 +000024#include <arch/ioapic.h>
Wang Qing Pei0ede4c02010-08-17 15:19:32 +000025#include <device/pci.h>
26#include <device/pci_ids.h>
27#include <cpu/x86/msr.h>
28#include <cpu/amd/mtrr.h>
29#include <cpu/amd/amdfam10_sysconf.h>
30
Wang Qing Pei0ede4c02010-08-17 15:19:32 +000031extern const unsigned char AmlCode[];
32extern const unsigned char AmlCode_ssdt[];
33
34#if CONFIG_ACPI_SSDTX_NUM >= 1
35extern const unsigned char AmlCode_ssdt2[];
36extern const unsigned char AmlCode_ssdt3[];
37extern const unsigned char AmlCode_ssdt4[];
38extern const unsigned char AmlCode_ssdt5[];
39#endif
40
Wang Qing Pei0ede4c02010-08-17 15:19:32 +000041unsigned long acpi_fill_mcfg(unsigned long current)
42{
43 /* Just a dummy */
44 return current;
45}
46
47unsigned long acpi_fill_madt(unsigned long current)
48{
49 /* create all subtables for processors */
50 current = acpi_create_madt_lapics(current);
51
52 /* Write SB700 IOAPIC, only one */
53 current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, 2,
54 IO_APIC_ADDR, 0);
55
56 current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *)
57 current, 0, 0, 2, 0);
58 current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *)
59 current, 0, 9, 9, 0xF);
60 /* 0: mean bus 0--->ISA */
61 /* 0: PIC 0 */
62 /* 2: APIC 2 */
Kyösti Mälkkid8747572014-06-26 05:30:54 +030063 /* 5 mean: 0101 --> Edge-triggered, Active high */
Wang Qing Pei0ede4c02010-08-17 15:19:32 +000064
65 /* create all subtables for processors */
66 /* current = acpi_create_madt_lapic_nmis(current, 5, 1); */
67 /* 1: LINT1 connect to NMI */
68
69 return current;
70}
71
72unsigned long write_acpi_tables(unsigned long start)
73{
74 unsigned long current;
75 acpi_rsdp_t *rsdp;
76 acpi_rsdt_t *rsdt;
77 acpi_hpet_t *hpet;
78 acpi_madt_t *madt;
79 acpi_srat_t *srat;
80 acpi_slit_t *slit;
81 acpi_fadt_t *fadt;
82 acpi_facs_t *facs;
83 acpi_header_t *dsdt;
84 acpi_header_t *ssdt;
85#if CONFIG_ACPI_SSDTX_NUM >= 1
86 acpi_header_t *ssdtx;
87 void *p;
88 int i;
89#endif
90
91 get_bus_conf(); /* it will get sblk, pci1234, hcdn, and sbdn */
92
93 /* Align ACPI tables to 16 bytes */
Patrick Georgi26b00e62012-04-20 19:19:47 +020094 start = ALIGN(start, 16);
Wang Qing Pei0ede4c02010-08-17 15:19:32 +000095 current = start;
96
97 printk(BIOS_INFO, "ACPI: Writing ACPI tables at %lx...\n", start);
98
99 /* We need at least an RSDP and an RSDT Table */
100 rsdp = (acpi_rsdp_t *) current;
101 current += sizeof(acpi_rsdp_t);
102 rsdt = (acpi_rsdt_t *) current;
103 current += sizeof(acpi_rsdt_t);
104
105 /* clear all table memory */
106 memset((void *)start, 0, current - start);
107
108 acpi_write_rsdp(rsdp, rsdt, NULL);
109 acpi_write_rsdt(rsdt);
110
111 /*
112 * We explicitly add these tables later on:
113 */
Patrick Georgi26b00e62012-04-20 19:19:47 +0200114 current = ALIGN(current, 8);
Wang Qing Pei0ede4c02010-08-17 15:19:32 +0000115 printk(BIOS_DEBUG, "ACPI: * HPET at %lx\n", current);
116 hpet = (acpi_hpet_t *) current;
117 current += sizeof(acpi_hpet_t);
118 acpi_create_hpet(hpet);
119 acpi_add_table(rsdp, hpet);
120
121 /* If we want to use HPET Timers Linux wants an MADT */
Patrick Georgi26b00e62012-04-20 19:19:47 +0200122 current = ALIGN(current, 8);
Wang Qing Pei0ede4c02010-08-17 15:19:32 +0000123 printk(BIOS_DEBUG, "ACPI: * MADT at %lx\n",current);
124 madt = (acpi_madt_t *) current;
125 acpi_create_madt(madt);
126 current += madt->header.length;
127 acpi_add_table(rsdp, madt);
128
129 /* SRAT */
Patrick Georgi26b00e62012-04-20 19:19:47 +0200130 current = ALIGN(current, 8);
Wang Qing Pei0ede4c02010-08-17 15:19:32 +0000131 printk(BIOS_DEBUG, "ACPI: * SRAT at %lx\n", current);
132 srat = (acpi_srat_t *) current;
133 acpi_create_srat(srat);
134 current += srat->header.length;
135 acpi_add_table(rsdp, srat);
136
137 /* SLIT */
Patrick Georgi26b00e62012-04-20 19:19:47 +0200138 current = ALIGN(current, 8);
Wang Qing Pei0ede4c02010-08-17 15:19:32 +0000139 printk(BIOS_DEBUG, "ACPI: * SLIT at %lx\n", current);
140 slit = (acpi_slit_t *) current;
141 acpi_create_slit(slit);
142 current += slit->header.length;
143 acpi_add_table(rsdp, slit);
144
145 /* SSDT */
Patrick Georgi26b00e62012-04-20 19:19:47 +0200146 current = ALIGN(current, 16);
Wang Qing Pei0ede4c02010-08-17 15:19:32 +0000147 printk(BIOS_DEBUG, "ACPI: * SSDT at %lx\n", current);
148 ssdt = (acpi_header_t *)current;
149 memcpy(ssdt, &AmlCode_ssdt, sizeof(acpi_header_t));
150 current += ssdt->length;
151 memcpy(ssdt, &AmlCode_ssdt, ssdt->length);
152 //Here you need to set value in pci1234, sblk and sbdn in get_bus_conf.c
153 update_ssdt((void*)ssdt);
154 /* recalculate checksum */
155 ssdt->checksum = 0;
156 ssdt->checksum = acpi_checksum((unsigned char *)ssdt,ssdt->length);
157 acpi_add_table(rsdp,ssdt);
158
159 printk(BIOS_DEBUG, "ACPI: * SSDT for PState at %lx\n", current);
160 current = acpi_add_ssdt_pstates(rsdp, current);
161
162#if CONFIG_ACPI_SSDTX_NUM >= 1
163
164 /* same htio, but different position? We may have to copy,
165 change HCIN, and recalculate the checknum and add_table */
166
167 for(i=1;i<sysconf.hc_possible_num;i++) { // 0: is hc sblink
168 if((sysconf.pci1234[i] & 1) != 1 ) continue;
169 u8 c;
170 if (i < 7) {
171 c = (u8) ('4' + i - 1);
172 } else {
173 c = (u8) ('A' + i - 1 - 6);
174 }
Patrick Georgi26b00e62012-04-20 19:19:47 +0200175 current = ALIGN(current, 8);
Wang Qing Pei0ede4c02010-08-17 15:19:32 +0000176 printk(BIOS_DEBUG, "ACPI: * SSDT for PCI%c at %lx\n", c, current); //pci0 and pci1 are in dsdt
177 ssdtx = (acpi_header_t *)current;
178 switch (sysconf.hcid[i]) {
179 case 1:
180 p = &AmlCode_ssdt2;
181 break;
182 case 2:
183 p = &AmlCode_ssdt3;
184 break;
185 case 3: /* 8131 */
186 p = &AmlCode_ssdt4;
187 break;
188 default:
189 /* HTX no io apic */
190 p = &AmlCode_ssdt5;
191 break;
192 }
193 memcpy(ssdtx, p, sizeof(acpi_header_t));
194 current += ssdtx->length;
195 memcpy(ssdtx, p, ssdtx->length);
196 update_ssdtx((void *)ssdtx, i);
197 ssdtx->checksum = 0;
198 ssdtx->checksum = acpi_checksum((u8 *)ssdtx, ssdtx->length);
199 acpi_add_table(rsdp, ssdtx);
200 }
201#endif
202
203 /* DSDT */
Patrick Georgi26b00e62012-04-20 19:19:47 +0200204 current = ALIGN(current, 8);
Wang Qing Pei0ede4c02010-08-17 15:19:32 +0000205 printk(BIOS_DEBUG, "ACPI: * DSDT at %lx\n", current);
206 dsdt = (acpi_header_t *)current; // it will used by fadt
207 memcpy(dsdt, &AmlCode, sizeof(acpi_header_t));
208 current += dsdt->length;
209 memcpy(dsdt, &AmlCode, dsdt->length);
210 printk(BIOS_DEBUG, "ACPI: * DSDT @ %p Length %x\n",dsdt,dsdt->length);
211
212 /* FACS */ // it needs 64 bit alignment
Patrick Georgi26b00e62012-04-20 19:19:47 +0200213 current = ALIGN(current, 8);
Wang Qing Pei0ede4c02010-08-17 15:19:32 +0000214 printk(BIOS_DEBUG, "ACPI: * FACS at %lx\n", current);
215 facs = (acpi_facs_t *) current; // it will be used by fadt
216 current += sizeof(acpi_facs_t);
217 acpi_create_facs(facs);
218
Zheng Bao7f20d732010-12-07 06:27:44 +0000219 /* FADT */
Patrick Georgi26b00e62012-04-20 19:19:47 +0200220 current = ALIGN(current, 8);
Wang Qing Pei0ede4c02010-08-17 15:19:32 +0000221 printk(BIOS_DEBUG, "ACPI: * FADT at %lx\n", current);
222 fadt = (acpi_fadt_t *) current;
223 current += sizeof(acpi_fadt_t);
224
225 acpi_create_fadt(fadt, facs, dsdt);
226 acpi_add_table(rsdp, fadt);
227
Wang Qing Pei0ede4c02010-08-17 15:19:32 +0000228 printk(BIOS_INFO, "ACPI: done.\n");
229 return current;
230}