Following patch converts the run-time SSDT patching via update_ssdt funtion to
[coreboot.git] / src / mainboard / agami / aruma / acpi_tables.c
1 /*
2  * Agami Aruma ACPI support
3  * 
4  *  Copyright 2005 Stefan Reinauer
5  *  Copyright 2005 AMD
6  *  
7  * written by Stefan Reinauer <stepan@openbios.org>
8  *  2005.9 yhlu modify that to more dynamic for AMD Opteron Based MB
9  */
10
11 #include <console/console.h>
12 #include <string.h>
13 #include <arch/acpi.h>
14 #include <device/pci.h>
15 #include <device/pci_ids.h>
16 #include <cpu/x86/msr.h>
17 #include <cpu/amd/mtrr.h>
18 #include <../../../northbridge/amd/amdk8/amdk8_acpi.h>
19
20 #define DUMP_ACPI_TABLES 0
21
22 #if DUMP_ACPI_TABLES == 1
23 static void dump_mem(unsigned start, unsigned end)
24 {
25
26         unsigned i;
27         print_debug("dump_mem:");
28         for (i = start; i < end; i++) {
29                 if ((i & 0xf) == 0) {
30                         printk_debug("\n%08x:", i);
31                 }
32                 printk_debug(" %02x",
33                              (unsigned char) *((unsigned char *) i));
34         }
35         print_debug("\n");
36 }
37 #endif
38
39 #define HC_POSSIBLE_NUM 8
40 extern unsigned char AmlCode[];
41 #if ACPI_SSDTX_NUM >= 1
42 extern unsigned char AmlCode_ssdt2[];
43 extern unsigned char AmlCode_ssdt3[];
44 extern unsigned char AmlCode_ssdt4[];
45 //extern unsigned char AmlCode_ssdt5[];
46 //extern unsigned char AmlCode_ssdt6[];
47 //extern unsigned char AmlCode_ssdt7[];
48 //extern unsigned char AmlCode_ssdt8[];
49 #endif
50
51 #define IO_APIC_ADDR    0xfec00000UL
52
53 extern unsigned char bus_isa;
54 extern unsigned char bus_8111_0;
55 extern unsigned char bus_8111_1;
56 extern unsigned char bus_8131[7][3];    // another 6 8131
57 extern unsigned apicid_8111;
58 extern unsigned apicid_8131[7][2];
59
60 extern unsigned pci1234[];
61 extern unsigned hc_possible_num;
62 extern unsigned sblk;
63 extern unsigned sbdn;
64 extern unsigned hcdn[];
65 extern unsigned sbdnx[7];       // for all 8131
66
67 unsigned long acpi_fill_mcfg(unsigned long current)
68 {
69         /* Just a dummy */
70         return current;
71 }
72
73 unsigned long acpi_fill_madt(unsigned long current)
74 {
75         unsigned int gsi_base = 0x18;
76
77         /* create all subtables for processors */
78         current = acpi_create_madt_lapics(current);
79
80         /* Write 8111 IOAPIC */
81         current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, 
82                         apicid_8111, IO_APIC_ADDR, 0);
83
84         /* Write all 8131/8132 IOAPICs */
85         {
86                 device_t dev;
87                 struct resource *res;
88                 dev = dev_find_slot(bus_8131[0][0], PCI_DEVFN(sbdnx[0], 1));
89
90                 if (dev) {
91                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
92                         if (res) {
93                                 current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, 
94                                                 apicid_8131[0][0], res->base, gsi_base);
95                                 gsi_base += 4;
96
97                         }
98                 }
99                 dev = dev_find_slot(bus_8131[0][0], PCI_DEVFN(sbdnx[0] + 1, 1));
100                 if (dev) {
101                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
102                         if (res) {
103                                 current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, 
104                                                 apicid_8131[0][1], res->base, gsi_base);
105                                 gsi_base += 4;
106                         }
107                 }
108         }
109
110         int i;
111         for (i = 1; i < hc_possible_num; i++) 
112         {       // 0: is hc sblink
113                 device_t dev;
114                 int j;
115                 struct resource *res;
116                 
117                 if ((pci1234[i] & 1) != 1)
118                         continue;
119         
120                 j = (i - 1) * 2 + 1;
121                 dev = dev_find_slot(bus_8131[j][0], PCI_DEVFN(sbdnx[j], 1));
122
123                 if (dev) {
124                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
125                         if (res) {
126                                 current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, 
127                                                 apicid_8131[j][0], res->base, gsi_base);
128                                 gsi_base += 4;
129
130                         }
131                 }
132                 dev =
133                     dev_find_slot(bus_8131[j][0],
134                                   PCI_DEVFN(sbdnx[j] + 1, 1));
135                 if (dev) 
136                 {
137                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
138                         if (res) {
139                                 current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, 
140                                                 apicid_8131[j][1], res->base, gsi_base);
141                                 gsi_base += 4;
142                         }
143                 }
144
145                 dev =
146                     dev_find_slot(bus_8131[j + 1][0],
147                                   PCI_DEVFN(sbdnx[j + 1], 1));
148
149                 if (dev) 
150                 {
151                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
152                         if (res) {
153                                 current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, 
154                                                 apicid_8131[j + 1][0], res->base, gsi_base);
155                                 gsi_base += 4;
156
157                         }
158                 }
159                 dev = dev_find_slot(bus_8131[j + 1][0], PCI_DEVFN(sbdnx[j + 1] + 1, 1));
160                 if (dev) 
161                 {
162                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
163                         if (res) {
164                                 current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, 
165                                                 apicid_8131[j + 1][1], res->base, gsi_base);
166                                 gsi_base += 4;
167                         }
168                 }
169
170
171         }
172
173
174         current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *) current, 0, 0, 2, 5);
175         /* 0: mean bus 0--->ISA */
176         /* 0: PIC 0 */
177         /* 2: APIC 2 */
178         /* 5 mean: 0101 --> Edige-triggered, Active high */
179
180
181         /* create all subtables for processors */
182         current = acpi_create_madt_lapic_nmis(current, 5, 1);
183         /* 1: LINT1 connect to NMI */
184
185
186         return current;
187 }
188
189 unsigned long acpi_fill_ssdt_generator(unsigned long current, char *oem_table_id) {
190         k8acpi_write_vars();
191         return (unsigned long) (acpigen_get_current());
192 }
193
194 unsigned long write_acpi_tables(unsigned long start)
195 {
196         unsigned long current;
197         acpi_rsdp_t *rsdp;
198         acpi_rsdt_t *rsdt;
199         acpi_hpet_t *hpet;
200         acpi_madt_t *madt;
201         acpi_srat_t *srat;
202         acpi_fadt_t *fadt;
203         acpi_facs_t *facs;
204         acpi_header_t *dsdt;
205         acpi_header_t *ssdt;
206         acpi_header_t *ssdtx;
207
208         unsigned char *AmlCode_ssdtx[HC_POSSIBLE_NUM];
209
210         int i;
211
212         /* Align ACPI tables to 16byte */
213         start = (start + 0x0f) & -0x10;
214         current = start;
215
216         printk_info("ACPI: Writing ACPI tables at %lx...\n", start);
217
218         /* We need at least an RSDP and an RSDT Table */
219         rsdp = (acpi_rsdp_t *) current;
220         current += sizeof(acpi_rsdp_t);
221         rsdt = (acpi_rsdt_t *) current;
222         current += sizeof(acpi_rsdt_t);
223
224         /* clear all table memory */
225         memset((void *) start, 0, current - start);
226
227         acpi_write_rsdp(rsdp, rsdt);
228         acpi_write_rsdt(rsdt);
229
230         get_bus_conf();         // get sblk, pci1234, and sbdn
231
232         /*
233          * We explicitly add these tables later on:
234          */
235         printk_debug("ACPI:    * HPET\n");
236         hpet = (acpi_hpet_t *) current;
237         current += sizeof(acpi_hpet_t);
238         acpi_create_hpet(hpet);
239         acpi_add_table(rsdt, hpet);
240
241         /* If we want to use HPET Timers Linux wants an MADT */
242         printk_debug("ACPI:    * MADT\n");
243         madt = (acpi_madt_t *) current;
244         acpi_create_madt(madt);
245         current += madt->header.length;
246         acpi_add_table(rsdt, madt);
247
248         /* SRAT */
249         printk_debug("ACPI:    * SRAT\n");
250         srat = (acpi_srat_t *) current;
251         acpi_create_srat(srat);
252         current += srat->header.length;
253         acpi_add_table(rsdt, srat);
254
255         /* SSDT */
256         printk_debug("ACPI:    * SSDT\n");
257         ssdt = (acpi_header_t *)current;
258
259         acpi_create_ssdt_generator(ssdt, "DYNADATA");
260         current += ssdt->length;
261         acpi_add_table(rsdt, ssdt);
262
263 #if ACPI_SSDTX_NUM >= 1
264         // we need to make ssdt2 match to PCI2 in pci2.asl,... pci1234[1] 
265         AmlCode_ssdtx[1] = AmlCode_ssdt2;       // if you have different HT IO card for the same ht slot, here need to check vendor id, to set coresponding SSDT
266         AmlCode_ssdtx[2] = AmlCode_ssdt3;
267         AmlCode_ssdtx[3] = AmlCode_ssdt4;
268 //      AmlCode_ssdtx[4] = AmlCode_ssdt5;
269 //      AmlCode_ssdtx[5] = AmlCode_ssdt6;
270 //      AmlCode_ssdtx[6] = AmlCode_ssdt7;
271 //      AmlCode_ssdtx[7] = AmlCode_ssdt8;
272
273         //same htio, but different possition? We may have to copy, change HCIN, and recalculate the checknum and add_table
274
275         for (i = 1; i < hc_possible_num; i++) { // 0: is hc sblink
276                 if ((pci1234[i] & 1) != 1)
277                         continue;
278                 printk_debug("ACPI:    * SSDT for PCI%d\n", i + 1);     //pci0 and pci1 are in dsdt
279                 ssdtx = (acpi_header_t *) current;
280                 current += ((acpi_header_t *) AmlCode_ssdtx[i])->length;
281                 memcpy((void *) ssdtx, (void *) AmlCode_ssdtx[i],
282                        ((acpi_header_t *) AmlCode_ssdtx[i])->length);
283                 acpi_add_table(rsdt, ssdtx);
284         }
285 #endif
286
287
288         /* FACS */
289         printk_debug("ACPI:    * FACS\n");
290         facs = (acpi_facs_t *) current;
291         current += sizeof(acpi_facs_t);
292         acpi_create_facs(facs);
293
294         /* DSDT */
295         printk_debug("ACPI:    * DSDT\n");
296         dsdt = (acpi_header_t *) current;
297         current += ((acpi_header_t *) AmlCode)->length;
298         memcpy((void *) dsdt, (void *) AmlCode,
299                ((acpi_header_t *) AmlCode)->length);
300         printk_debug("ACPI:    * DSDT @ %08x Length %x\n", dsdt,
301                      dsdt->length);
302
303         /* FDAT */
304         printk_debug("ACPI:    * FADT\n");
305         fadt = (acpi_fadt_t *) current;
306         current += sizeof(acpi_fadt_t);
307
308         acpi_create_fadt(fadt, facs, dsdt);
309         acpi_add_table(rsdt, fadt);
310
311 #if DUMP_ACPI_TABLES == 1
312         printk_debug("rsdp\n");
313         dump_mem(rsdp, ((void *) rsdp) + sizeof(acpi_rsdp_t));
314
315         printk_debug("rsdt\n");
316         dump_mem(rsdt, ((void *) rsdt) + sizeof(acpi_rsdt_t));
317
318         printk_debug("madt\n");
319         dump_mem(madt, ((void *) madt) + madt->header.length);
320
321         printk_debug("srat\n");
322         dump_mem(srat, ((void *) srat) + srat->header.length);
323
324         printk_debug("ssdt\n");
325         dump_mem(ssdt, ((void *) ssdt) + ssdt->length);
326
327         printk_debug("fadt\n");
328         dump_mem(fadt, ((void *) fadt) + fadt->header.length);
329 #endif
330
331         printk_info("ACPI: done.\n");
332         return current;
333 }