f35e7f98ec25271c2a573de2dc788fa0fdee0b2a
[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
20 #include "mb_sysconf.h"
21
22 #define DUMP_ACPI_TABLES 0
23
24 #if DUMP_ACPI_TABLES == 1
25 static void dump_mem(unsigned start, unsigned end)
26 {
27         
28         unsigned i;
29         print_debug("dump_mem:");
30         for(i=start;i<end;i++) {
31                 if((i & 0xf)==0) {
32                         printk_debug("\n%08x:", i);
33                 }
34                 printk_debug(" %02x", (unsigned char)*((unsigned char *)i));
35         }
36         print_debug("\n");
37  }
38 #endif
39
40 extern unsigned char AmlCode[];
41 extern unsigned char AmlCode_ssdt[];
42
43 #if ACPI_SSDTX_NUM >= 1
44 extern unsigned char AmlCode_ssdt2[];
45 extern unsigned char AmlCode_ssdt3[];
46 extern unsigned char AmlCode_ssdt4[];
47 #endif
48
49 #define IO_APIC_ADDR    0xfec00000UL
50
51 unsigned long acpi_fill_madt(unsigned long current)
52 {
53         unsigned int gsi_base=0x18;
54
55         struct mb_sysconf_t *m;
56
57         m = sysconf.mb;
58  
59         /* create all subtables for processors */
60         current = acpi_create_madt_lapics(current);
61         
62         /* Write 8111 IOAPIC */
63         current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *)current, m->apicid_8111,
64                         IO_APIC_ADDR, 0);
65
66         /* Write all 8131 IOAPICs */
67         {
68                 device_t dev;
69                 struct resource *res;
70                 dev = dev_find_slot(m->bus_8132_0, PCI_DEVFN((sysconf.hcdn[0]&0xff), 1));
71                 if (dev) {
72                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
73                         if (res) {
74                                 current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *)current, m->apicid_8132_1,
75                                         res->base, gsi_base );
76                                 gsi_base+=4;
77
78                         }
79                 }
80                 dev = dev_find_slot(m->bus_8132_0, PCI_DEVFN((sysconf.hcdn[0] & 0xff)+1, 1));
81                 if (dev) {
82                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
83                         if (res) {
84                                 current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *)current, m->apicid_8132_2,
85                                         res->base, gsi_base );
86                                 gsi_base+=4;
87                         }
88                 }
89
90                 int i;
91                 int j = 0;
92
93                 for(i=1; i< sysconf.hc_possible_num; i++) {
94                         unsigned d;
95                         if(!(sysconf.pci1234[i] & 0x1) ) continue;
96                         // 8131 need to use +4
97                         
98                         switch (sysconf.hcid[i]) {
99                         case 1:
100                                 d = 7;
101                                 break;
102                         case 3:
103                                 d = 4;
104                                 break;
105                         }
106                         switch (sysconf.hcid[i]) {
107                         case 1:
108                         case 3:
109                                 dev = dev_find_slot(m->bus_8132a[j][0], PCI_DEVFN(m->sbdn3a[j], 1));
110                                 if (dev) {
111                                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
112                                         if (res) {
113                                                 current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *)current, m->apicid_8132a[j][0],
114                                                         res->base, gsi_base );
115                                                 gsi_base+=d;
116                                         }
117                                 }
118                                 dev = dev_find_slot(m->bus_8132a[j][0], PCI_DEVFN(m->sbdn3a[j]+1, 1));
119                                 if (dev) {
120                                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
121                                         if (res) {
122                                                 current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *)current, m->apicid_8132a[j][1],
123                                                         res->base, gsi_base );
124                                                 gsi_base+=d;
125
126                                         }
127                                 }
128                                 break;
129                         }
130
131                         j++;
132                 }
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
149         return current;
150 }
151
152 extern void get_bus_conf(void);
153
154 extern void update_ssdt(void *ssdt);
155
156 void update_ssdtx(void *ssdtx, int i)
157 {
158         uint8_t *PCI;
159         uint8_t *HCIN;
160         uint8_t *UID;
161
162         PCI = ssdtx + 0x32;
163         HCIN = ssdtx + 0x39;
164         UID = ssdtx + 0x40;
165
166         if(i<7) {
167                 *PCI  = (uint8_t) ('4' + i - 1);
168         }
169         else {
170                 *PCI  = (uint8_t) ('A' + i - 1 - 6);
171         }
172         *HCIN = (uint8_t) i;
173         *UID  = (uint8_t) (i+3);
174
175         /* FIXME: need to update the GSI id in the ssdtx too */
176
177 }
178
179 unsigned long write_acpi_tables(unsigned long start)
180 {
181         unsigned long current;
182         acpi_rsdp_t *rsdp;
183         acpi_rsdt_t *rsdt;
184         acpi_hpet_t *hpet;
185         acpi_madt_t *madt;
186         acpi_srat_t *srat;
187         acpi_slit_t *slit;
188         acpi_fadt_t *fadt;
189         acpi_facs_t *facs;
190         acpi_header_t *dsdt;
191         acpi_header_t *ssdt;
192         acpi_header_t *ssdtx;
193         unsigned char *p;
194
195         unsigned char *AmlCode_ssdtx[HC_POSSIBLE_NUM];
196
197         int i;
198
199         get_bus_conf(); //it will get sblk, pci1234, hcdn, and sbdn
200
201         /* Align ACPI tables to 16byte */
202         start   = ( start + 0x0f ) & -0x10;
203         current = start;
204         
205         printk_info("ACPI: Writing ACPI tables at %lx...\n", start);
206
207         /* We need at least an RSDP and an RSDT Table */
208         rsdp = (acpi_rsdp_t *) current;
209         current += sizeof(acpi_rsdp_t);
210         rsdt = (acpi_rsdt_t *) current;
211         current += sizeof(acpi_rsdt_t);
212
213         /* clear all table memory */
214         memset((void *)start, 0, current - start);
215         
216         acpi_write_rsdp(rsdp, rsdt);
217         acpi_write_rsdt(rsdt);
218
219         /*
220          * We explicitly add these tables later on:
221          */
222         printk_debug("ACPI:    * HPET\n");
223         hpet = (acpi_hpet_t *) current;
224         current += sizeof(acpi_hpet_t);
225         acpi_create_hpet(hpet);
226         acpi_add_table(rsdt,hpet);
227
228         /* If we want to use HPET Timers Linux wants an MADT */
229         printk_debug("ACPI:    * MADT\n");
230         madt = (acpi_madt_t *) current;
231         acpi_create_madt(madt);
232         current+=madt->header.length;
233         acpi_add_table(rsdt,madt);
234
235
236         /* SRAT */
237         printk_debug("ACPI:    * SRAT\n");
238         srat = (acpi_srat_t *) current;
239         acpi_create_srat(srat);
240         current+=srat->header.length;
241         acpi_add_table(rsdt,srat);
242
243         /* SLIT */
244         printk_debug("ACPI:    * SLIT\n");
245         slit = (acpi_slit_t *) current;
246         acpi_create_slit(slit);
247         current+=slit->header.length;
248         acpi_add_table(rsdt,slit);
249
250         /* SSDT */
251         printk_debug("ACPI:    * SSDT\n");
252         ssdt = (acpi_header_t *)current;
253         current += ((acpi_header_t *)AmlCode_ssdt)->length;
254         memcpy((void *)ssdt, (void *)AmlCode_ssdt, ((acpi_header_t *)AmlCode_ssdt)->length);
255         //Here you need to set value in pci1234, sblk and sbdn in get_bus_conf.c
256         update_ssdt((void*)ssdt);
257         /* recalculate checksum */
258         ssdt->checksum = 0;
259         ssdt->checksum = acpi_checksum((unsigned char *)ssdt,ssdt->length);
260         acpi_add_table(rsdt,ssdt);
261
262 #if ACPI_SSDTX_NUM >= 1
263
264         //same htio, but different position? We may have to copy, change HCIN, and recalculate the checknum and add_table
265
266         for(i=1;i<sysconf.hc_possible_num;i++) {  // 0: is hc sblink
267                 if((sysconf.pci1234[i] & 1) != 1 ) continue;
268                 uint8_t c;
269                 if(i<7) {
270                         c  = (uint8_t) ('4' + i - 1);
271                 }
272                 else {
273                         c  = (uint8_t) ('A' + i - 1 - 6);
274                 }
275                 printk_debug("ACPI:    * SSDT for PCI%c Aka hcid = %d\n", c, sysconf.hcid[i]); //pci0 and pci1 are in dsdt
276                 current   = ( current + 0x07) & -0x08;
277                 ssdtx = (acpi_header_t *)current;
278                 switch(sysconf.hcid[i]) {
279                 case 1: //8132
280                         p = AmlCode_ssdt2;
281                         break;
282                 case 2: //8151
283                         p = AmlCode_ssdt3;
284                         break;
285                 case 3: //8131
286                         p = AmlCode_ssdt4;
287                         break;
288                 default:
289                         continue;
290                 }
291                 current += ((acpi_header_t *)p)->length;
292                 memcpy((void *)ssdtx, (void *)p, ((acpi_header_t *)p)->length);
293                 update_ssdtx((void *)ssdtx, i);
294                 ssdtx->checksum = 0;
295                 ssdtx->checksum = acpi_checksum((unsigned char *)ssdtx,ssdtx->length);
296                 acpi_add_table(rsdt,ssdtx);
297         }
298 #endif
299
300         /* FACS */
301         printk_debug("ACPI:    * FACS\n");
302         facs = (acpi_facs_t *) current;
303         current += sizeof(acpi_facs_t);
304         acpi_create_facs(facs);
305
306         /* DSDT */
307         printk_debug("ACPI:    * DSDT\n");
308         dsdt = (acpi_header_t *)current;
309         current += ((acpi_header_t *)AmlCode)->length;
310         memcpy((void *)dsdt,(void *)AmlCode, \
311                         ((acpi_header_t *)AmlCode)->length);
312         printk_debug("ACPI:    * DSDT @ %08x Length %x\n",dsdt,dsdt->length);
313
314         /* FDAT */
315         printk_debug("ACPI:    * FADT\n");
316         fadt = (acpi_fadt_t *) current;
317         current += sizeof(acpi_fadt_t);
318
319         acpi_create_fadt(fadt,facs,dsdt);
320         acpi_add_table(rsdt,fadt);
321
322 #if DUMP_ACPI_TABLES == 1
323         printk_debug("rsdp\n");
324         dump_mem(rsdp, ((void *)rsdp) + sizeof(acpi_rsdp_t));
325
326         printk_debug("rsdt\n");
327         dump_mem(rsdt, ((void *)rsdt) + sizeof(acpi_rsdt_t));
328
329         printk_debug("madt\n");
330         dump_mem(madt, ((void *)madt) + madt->header.length);
331
332         printk_debug("srat\n");
333         dump_mem(srat, ((void *)srat) + srat->header.length);
334
335         printk_debug("slit\n");
336         dump_mem(slit, ((void *)slit) + slit->header.length);
337
338         printk_debug("ssdt\n");
339         dump_mem(ssdt, ((void *)ssdt) + ssdt->length);
340
341         printk_debug("fadt\n");
342         dump_mem(fadt, ((void *)fadt) + fadt->header.length);
343 #endif
344
345         printk_info("ACPI: done.\n");
346         return current;
347 }
348