82195f6e01eea27ba227719a6bd040a8585a703f
[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_debug("\n%08x:", i);
34                 }
35                 printk_debug(" %02x", (unsigned char)*((unsigned char *)i));
36         }
37         print_debug("\n");
38  }
39 #endif
40
41 extern unsigned char AmlCode[];
42
43 #if CONFIG_ACPI_SSDTX_NUM >= 1
44 extern unsigned char AmlCode_ssdt2[];
45 extern unsigned char AmlCode_ssdt3[];
46 extern unsigned char AmlCode_ssdt4[];
47 extern 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 extern void get_bus_conf(void);
161
162 static void update_ssdtx(void *ssdtx, int i)
163 {
164         uint8_t *PCI;
165         uint8_t *HCIN;
166         uint8_t *UID;
167
168         PCI = ssdtx + 0x32;
169         HCIN = ssdtx + 0x39;
170         UID = ssdtx + 0x40;
171
172         if(i<7) {
173                 *PCI  = (uint8_t) ('4' + i - 1);
174         }
175         else {
176                 *PCI  = (uint8_t) ('A' + i - 1 - 6);
177         }
178         *HCIN = (uint8_t) i;
179         *UID  = (uint8_t) (i+3);
180
181         /* FIXME: need to update the GSI id in the ssdtx too */
182
183 }
184
185 unsigned long acpi_fill_ssdt_generator(unsigned long current, const char *oem_table_id) {
186         k8acpi_write_vars();
187         return (unsigned long) (acpigen_get_current());
188 }
189
190 unsigned long write_acpi_tables(unsigned long start)
191 {
192         unsigned long current;
193         acpi_rsdp_t *rsdp;
194         acpi_rsdt_t *rsdt;
195         acpi_hpet_t *hpet;
196         acpi_madt_t *madt;
197         acpi_srat_t *srat;
198         acpi_slit_t *slit;
199         acpi_fadt_t *fadt;
200         acpi_facs_t *facs;
201         acpi_header_t *dsdt;
202         acpi_header_t *ssdt;
203         acpi_header_t *ssdtx;
204         unsigned char *p;
205
206         int i;
207
208         get_bus_conf(); //it will get sblk, pci1234, hcdn, and sbdn
209
210         /* Align ACPI tables to 16byte */
211         start   = ( start + 0x0f ) & -0x10;
212         current = start;
213         
214         printk_info("ACPI: Writing ACPI tables at %lx...\n", start);
215
216         /* We need at least an RSDP and an RSDT Table */
217         rsdp = (acpi_rsdp_t *) current;
218         current += sizeof(acpi_rsdp_t);
219         rsdt = (acpi_rsdt_t *) current;
220         current += sizeof(acpi_rsdt_t);
221
222         /* clear all table memory */
223         memset((void *)start, 0, current - start);
224         
225         acpi_write_rsdp(rsdp, rsdt, NULL);
226         acpi_write_rsdt(rsdt);
227
228         /*
229          * We explicitly add these tables later on:
230          */
231         printk_debug("ACPI:    * HPET\n");
232         hpet = (acpi_hpet_t *) current;
233         current += sizeof(acpi_hpet_t);
234         acpi_create_hpet(hpet);
235         acpi_add_table(rsdp,hpet);
236
237         /* If we want to use HPET Timers Linux wants an MADT */
238         printk_debug("ACPI:    * MADT\n");
239         madt = (acpi_madt_t *) current;
240         acpi_create_madt(madt);
241         current+=madt->header.length;
242         acpi_add_table(rsdp,madt);
243
244
245         /* SRAT */
246         printk_debug("ACPI:    * SRAT\n");
247         srat = (acpi_srat_t *) current;
248         acpi_create_srat(srat);
249         current+=srat->header.length;
250         acpi_add_table(rsdp,srat);
251
252         /* SLIT */
253         printk_debug("ACPI:    * SLIT\n");
254         slit = (acpi_slit_t *) current;
255         acpi_create_slit(slit);
256         current+=slit->header.length;
257         acpi_add_table(rsdp,slit);
258
259         /* SSDT */
260         printk_debug("ACPI:    * SSDT\n");
261         ssdt = (acpi_header_t *)current;
262
263         acpi_create_ssdt_generator(ssdt, "DYNADATA");
264         current += ssdt->length;
265         acpi_add_table(rsdp, ssdt);
266
267 #if CONFIG_ACPI_SSDTX_NUM >= 1
268
269         //same htio, but different position? We may have to copy, change HCIN, and recalculate the checknum and add_table
270
271         for(i=1;i<sysconf.hc_possible_num;i++) {  // 0: is hc sblink
272                 if((sysconf.pci1234[i] & 1) != 1 ) continue;
273                 uint8_t c;
274                 if(i<7) {
275                         c  = (uint8_t) ('4' + i - 1);
276                 }
277                 else {
278                         c  = (uint8_t) ('A' + i - 1 - 6);
279                 }
280                 printk_debug("ACPI:    * SSDT for PCI%c Aka hcid = %d\n", c, sysconf.hcid[i]); //pci0 and pci1 are in dsdt
281                 current   = ( current + 0x07) & -0x08;
282                 ssdtx = (acpi_header_t *)current;
283                 switch(sysconf.hcid[i]) {
284                 case 1: //8132
285                         p = AmlCode_ssdt2;
286                         break;
287                 case 2: //8151
288                         p = AmlCode_ssdt3;
289                         break;
290                 case 3: //8131
291                         p = AmlCode_ssdt4;
292                         break;
293                 default:
294                         //HTX no io apic
295                         p = AmlCode_ssdt5;
296                         break;
297                 }
298                 current += ((acpi_header_t *)p)->length;
299                 memcpy((void *)ssdtx, (void *)p, ((acpi_header_t *)p)->length);
300                 update_ssdtx((void *)ssdtx, i);
301                 ssdtx->checksum = 0;
302                 ssdtx->checksum = acpi_checksum((unsigned char *)ssdtx,ssdtx->length);
303                 acpi_add_table(rsdp,ssdtx);
304         }
305 #endif
306
307         /* FACS */
308         printk_debug("ACPI:    * FACS\n");
309         facs = (acpi_facs_t *) current;
310         current += sizeof(acpi_facs_t);
311         acpi_create_facs(facs);
312
313         /* DSDT */
314         printk_debug("ACPI:    * DSDT\n");
315         dsdt = (acpi_header_t *)current;
316         current += ((acpi_header_t *)AmlCode)->length;
317         memcpy((void *)dsdt,(void *)AmlCode, \
318                         ((acpi_header_t *)AmlCode)->length);
319         printk_debug("ACPI:    * DSDT @ %p Length %x\n",dsdt,dsdt->length);
320
321         /* FDAT */
322         printk_debug("ACPI:    * FADT\n");
323         fadt = (acpi_fadt_t *) current;
324         current += sizeof(acpi_fadt_t);
325
326         acpi_create_fadt(fadt,facs,dsdt);
327         acpi_add_table(rsdp,fadt);
328
329 #if DUMP_ACPI_TABLES == 1
330         printk_debug("rsdp\n");
331         dump_mem(rsdp, ((void *)rsdp) + sizeof(acpi_rsdp_t));
332
333         printk_debug("rsdt\n");
334         dump_mem(rsdt, ((void *)rsdt) + sizeof(acpi_rsdt_t));
335
336         printk_debug("madt\n");
337         dump_mem(madt, ((void *)madt) + madt->header.length);
338
339         printk_debug("srat\n");
340         dump_mem(srat, ((void *)srat) + srat->header.length);
341
342         printk_debug("slit\n");
343         dump_mem(slit, ((void *)slit) + slit->header.length);
344
345         printk_debug("ssdt\n");
346         dump_mem(ssdt, ((void *)ssdt) + ssdt->length);
347
348         printk_debug("fadt\n");
349         dump_mem(fadt, ((void *)fadt) + fadt->header.length);
350 #endif
351
352         printk_info("ACPI: done.\n");
353         return current;
354 }
355