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