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