b10b73b3b6da5463eabb37c710dcfd57184bb47a
[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
19 #define DUMP_ACPI_TABLES 0
20
21 #if DUMP_ACPI_TABLES == 1
22 static void dump_mem(unsigned start, unsigned end)
23 {
24
25         unsigned i;
26         print_debug("dump_mem:");
27         for (i = start; i < end; i++) {
28                 if ((i & 0xf) == 0) {
29                         printk_debug("\n%08x:", i);
30                 }
31                 printk_debug(" %02x",
32                              (unsigned char) *((unsigned char *) i));
33         }
34         print_debug("\n");
35 }
36 #endif
37
38 #define HC_POSSIBLE_NUM 8
39 extern unsigned char AmlCode[];
40 extern unsigned char AmlCode_ssdt[];
41
42 #if ACPI_SSDTX_NUM >= 1
43 extern unsigned char AmlCode_ssdt2[];
44 extern unsigned char AmlCode_ssdt3[];
45 extern unsigned char AmlCode_ssdt4[];
46 //extern unsigned char AmlCode_ssdt5[];
47 //extern unsigned char AmlCode_ssdt6[];
48 //extern unsigned char AmlCode_ssdt7[];
49 //extern unsigned char AmlCode_ssdt8[];
50 #endif
51
52 #define IO_APIC_ADDR    0xfec00000UL
53
54 extern unsigned char bus_isa;
55 extern unsigned char bus_8111_0;
56 extern unsigned char bus_8111_1;
57 extern unsigned char bus_8131[7][3];    // another 6 8131
58 extern unsigned apicid_8111;
59 extern unsigned apicid_8131[7][2];
60
61 extern unsigned pci1234[];
62 extern unsigned hc_possible_num;
63 extern unsigned sblk;
64 extern unsigned sbdn;
65 extern unsigned hcdn[];
66 extern unsigned sbdnx[7];       // for all 8131
67
68 unsigned long acpi_fill_mcfg(unsigned long current)
69 {
70         /* Just a dummy */
71         return current;
72 }
73
74 unsigned long acpi_fill_madt(unsigned long current)
75 {
76         unsigned int gsi_base = 0x18;
77
78         /* create all subtables for processors */
79         current = acpi_create_madt_lapics(current);
80
81         /* Write 8111 IOAPIC */
82         current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, 
83                         apicid_8111, IO_APIC_ADDR, 0);
84
85         /* Write all 8131/8132 IOAPICs */
86         {
87                 device_t dev;
88                 struct resource *res;
89                 dev = dev_find_slot(bus_8131[0][0], PCI_DEVFN(sbdnx[0], 1));
90
91                 if (dev) {
92                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
93                         if (res) {
94                                 current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, 
95                                                 apicid_8131[0][0], res->base, gsi_base);
96                                 gsi_base += 4;
97
98                         }
99                 }
100                 dev = dev_find_slot(bus_8131[0][0], PCI_DEVFN(sbdnx[0] + 1, 1));
101                 if (dev) {
102                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
103                         if (res) {
104                                 current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, 
105                                                 apicid_8131[0][1], res->base, gsi_base);
106                                 gsi_base += 4;
107                         }
108                 }
109         }
110
111         int i;
112         for (i = 1; i < hc_possible_num; i++) 
113         {       // 0: is hc sblink
114                 device_t dev;
115                 int j;
116                 struct resource *res;
117                 
118                 if ((pci1234[i] & 1) != 1)
119                         continue;
120         
121                 j = (i - 1) * 2 + 1;
122                 dev = dev_find_slot(bus_8131[j][0], PCI_DEVFN(sbdnx[j], 1));
123
124                 if (dev) {
125                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
126                         if (res) {
127                                 current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, 
128                                                 apicid_8131[j][0], res->base, gsi_base);
129                                 gsi_base += 4;
130
131                         }
132                 }
133                 dev =
134                     dev_find_slot(bus_8131[j][0],
135                                   PCI_DEVFN(sbdnx[j] + 1, 1));
136                 if (dev) 
137                 {
138                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
139                         if (res) {
140                                 current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, 
141                                                 apicid_8131[j][1], res->base, gsi_base);
142                                 gsi_base += 4;
143                         }
144                 }
145
146                 dev =
147                     dev_find_slot(bus_8131[j + 1][0],
148                                   PCI_DEVFN(sbdnx[j + 1], 1));
149
150                 if (dev) 
151                 {
152                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
153                         if (res) {
154                                 current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, 
155                                                 apicid_8131[j + 1][0], res->base, gsi_base);
156                                 gsi_base += 4;
157
158                         }
159                 }
160                 dev = dev_find_slot(bus_8131[j + 1][0], PCI_DEVFN(sbdnx[j + 1] + 1, 1));
161                 if (dev) 
162                 {
163                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
164                         if (res) {
165                                 current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, 
166                                                 apicid_8131[j + 1][1], res->base, gsi_base);
167                                 gsi_base += 4;
168                         }
169                 }
170
171
172         }
173
174
175         current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *) current, 0, 0, 2, 5);
176         /* 0: mean bus 0--->ISA */
177         /* 0: PIC 0 */
178         /* 2: APIC 2 */
179         /* 5 mean: 0101 --> Edige-triggered, Active high */
180
181
182         /* create all subtables for processors */
183         current = acpi_create_madt_lapic_nmis(current, 5, 1);
184         /* 1: LINT1 connect to NMI */
185
186
187         return current;
188 }
189
190 //FIXME: next could be moved to northbridge/amd/amdk8/amdk8_acpi.c or cpu/amd/k8/k8_acpi.c begin
191 static void int_to_stream(uint32_t val, uint8_t * dest)
192 {
193         int i;
194         for (i = 0; i < 4; i++) {
195                 *(dest + i) = (val >> (8 * i)) & 0xff;
196         }
197 }
198
199 extern void get_bus_conf(void);
200
201 static void update_ssdt(void *ssdt)
202 {
203         uint8_t *BUSN;
204         uint8_t *MMIO;
205         uint8_t *PCIO;
206         uint8_t *SBLK;
207         uint8_t *TOM1;
208         uint8_t *HCLK;
209         uint8_t *SBDN;
210         uint8_t *HCDN;
211         int i;
212         device_t dev;
213         uint32_t dword;
214         msr_t msr;
215
216         BUSN = ssdt + 0x3a;     //+5 will be next BUSN
217         MMIO = ssdt + 0x57;     //+5 will be next MMIO
218         PCIO = ssdt + 0xaf;     //+5 will be next PCIO
219         SBLK = ssdt + 0xdc;     // one byte
220         TOM1 = ssdt + 0xe3;     //
221         HCLK = ssdt + 0xfa;     //+5 will be next HCLK
222         SBDN = ssdt + 0xed;     //
223         HCDN = ssdt + 0x12a;    //+5 will be next HCDN
224
225         dev = dev_find_slot(0, PCI_DEVFN(0x18, 1));
226
227         for (i = 0; i < 4; i++) {
228                 dword = pci_read_config32(dev, 0xe0 + i * 4);
229                 int_to_stream(dword, BUSN + i * 5);
230         }
231
232         for (i = 0; i < 0x10; i++) {
233                 dword = pci_read_config32(dev, 0x80 + i * 4);
234                 int_to_stream(dword, MMIO + i * 5);
235         }
236
237         for (i = 0; i < 0x08; i++) {
238                 dword = pci_read_config32(dev, 0xc0 + i * 4);
239                 int_to_stream(dword, PCIO + i * 5);
240         }
241
242         *SBLK = (uint8_t) (sblk);
243
244         msr = rdmsr(TOP_MEM);
245         int_to_stream(msr.lo, TOM1);
246
247         for (i = 0; i < hc_possible_num; i++) {
248                 int_to_stream(pci1234[i], HCLK + i * 5);
249                 int_to_stream(hcdn[i], HCDN + i * 5);
250         }
251         for (i = hc_possible_num; i < HC_POSSIBLE_NUM; i++) {   // in case we set array size to other than 8
252                 int_to_stream(0x00000000, HCLK + i * 5);
253                 int_to_stream(hcdn[i], HCDN + i * 5);
254         }
255
256         int_to_stream(sbdn, SBDN);
257
258 }
259
260 //end
261
262 unsigned long write_acpi_tables(unsigned long start)
263 {
264         unsigned long current;
265         acpi_rsdp_t *rsdp;
266         acpi_rsdt_t *rsdt;
267         acpi_hpet_t *hpet;
268         acpi_madt_t *madt;
269         acpi_srat_t *srat;
270         acpi_fadt_t *fadt;
271         acpi_facs_t *facs;
272         acpi_header_t *dsdt;
273         acpi_header_t *ssdt;
274         acpi_header_t *ssdtx;
275
276         unsigned char *AmlCode_ssdtx[HC_POSSIBLE_NUM];
277
278         int i;
279
280         /* Align ACPI tables to 16byte */
281         start = (start + 0x0f) & -0x10;
282         current = start;
283
284         printk_info("ACPI: Writing ACPI tables at %lx...\n", start);
285
286         /* We need at least an RSDP and an RSDT Table */
287         rsdp = (acpi_rsdp_t *) current;
288         current += sizeof(acpi_rsdp_t);
289         rsdt = (acpi_rsdt_t *) current;
290         current += sizeof(acpi_rsdt_t);
291
292         /* clear all table memory */
293         memset((void *) start, 0, current - start);
294
295         acpi_write_rsdp(rsdp, rsdt);
296         acpi_write_rsdt(rsdt);
297
298         get_bus_conf();         // get sblk, pci1234, and sbdn
299
300         /*
301          * We explicitly add these tables later on:
302          */
303         printk_debug("ACPI:    * HPET\n");
304         hpet = (acpi_hpet_t *) current;
305         current += sizeof(acpi_hpet_t);
306         acpi_create_hpet(hpet);
307         acpi_add_table(rsdt, hpet);
308
309         /* If we want to use HPET Timers Linux wants an MADT */
310         printk_debug("ACPI:    * MADT\n");
311         madt = (acpi_madt_t *) current;
312         acpi_create_madt(madt);
313         current += madt->header.length;
314         acpi_add_table(rsdt, madt);
315
316         /* SRAT */
317         printk_debug("ACPI:    * SRAT\n");
318         srat = (acpi_srat_t *) current;
319         acpi_create_srat(srat);
320         current += srat->header.length;
321         acpi_add_table(rsdt, srat);
322
323         /* SSDT */
324         printk_debug("ACPI:    * SSDT\n");
325         ssdt = (acpi_header_t *) current;
326         current += ((acpi_header_t *) AmlCode_ssdt)->length;
327         memcpy((void *) ssdt, (void *) AmlCode_ssdt,
328                ((acpi_header_t *) AmlCode_ssdt)->length);
329         //Here you need to set value in pci1234, sblk and sbdn in get_bus_conf.c
330         update_ssdt((void *) ssdt);
331         /* recalculate checksum */
332         ssdt->checksum = 0;
333         ssdt->checksum =
334             acpi_checksum((unsigned char *) ssdt, ssdt->length);
335         acpi_add_table(rsdt, ssdt);
336
337 #if ACPI_SSDTX_NUM >= 1
338         // we need to make ssdt2 match to PCI2 in pci2.asl,... pci1234[1] 
339         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
340         AmlCode_ssdtx[2] = AmlCode_ssdt3;
341         AmlCode_ssdtx[3] = AmlCode_ssdt4;
342 //      AmlCode_ssdtx[4] = AmlCode_ssdt5;
343 //      AmlCode_ssdtx[5] = AmlCode_ssdt6;
344 //      AmlCode_ssdtx[6] = AmlCode_ssdt7;
345 //      AmlCode_ssdtx[7] = AmlCode_ssdt8;
346
347         //same htio, but different possition? We may have to copy, change HCIN, and recalculate the checknum and add_table
348
349         for (i = 1; i < hc_possible_num; i++) { // 0: is hc sblink
350                 if ((pci1234[i] & 1) != 1)
351                         continue;
352                 printk_debug("ACPI:    * SSDT for PCI%d\n", i + 1);     //pci0 and pci1 are in dsdt
353                 ssdtx = (acpi_header_t *) current;
354                 current += ((acpi_header_t *) AmlCode_ssdtx[i])->length;
355                 memcpy((void *) ssdtx, (void *) AmlCode_ssdtx[i],
356                        ((acpi_header_t *) AmlCode_ssdtx[i])->length);
357                 acpi_add_table(rsdt, ssdtx);
358         }
359 #endif
360
361
362         /* FACS */
363         printk_debug("ACPI:    * FACS\n");
364         facs = (acpi_facs_t *) current;
365         current += sizeof(acpi_facs_t);
366         acpi_create_facs(facs);
367
368         /* DSDT */
369         printk_debug("ACPI:    * DSDT\n");
370         dsdt = (acpi_header_t *) current;
371         current += ((acpi_header_t *) AmlCode)->length;
372         memcpy((void *) dsdt, (void *) AmlCode,
373                ((acpi_header_t *) AmlCode)->length);
374         printk_debug("ACPI:    * DSDT @ %08x Length %x\n", dsdt,
375                      dsdt->length);
376
377         /* FDAT */
378         printk_debug("ACPI:    * FADT\n");
379         fadt = (acpi_fadt_t *) current;
380         current += sizeof(acpi_fadt_t);
381
382         acpi_create_fadt(fadt, facs, dsdt);
383         acpi_add_table(rsdt, fadt);
384
385 #if DUMP_ACPI_TABLES == 1
386         printk_debug("rsdp\n");
387         dump_mem(rsdp, ((void *) rsdp) + sizeof(acpi_rsdp_t));
388
389         printk_debug("rsdt\n");
390         dump_mem(rsdt, ((void *) rsdt) + sizeof(acpi_rsdt_t));
391
392         printk_debug("madt\n");
393         dump_mem(madt, ((void *) madt) + madt->header.length);
394
395         printk_debug("srat\n");
396         dump_mem(srat, ((void *) srat) + srat->header.length);
397
398         printk_debug("ssdt\n");
399         dump_mem(ssdt, ((void *) ssdt) + ssdt->length);
400
401         printk_debug("fadt\n");
402         dump_mem(fadt, ((void *) fadt) + fadt->header.length);
403 #endif
404
405         printk_info("ACPI: done.\n");
406         return current;
407 }