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