AMD Rev F support
[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
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 //extern unsigned char AmlCode_ssdt5[];
48 //extern unsigned char AmlCode_ssdt6[];
49 //extern unsigned char AmlCode_ssdt7[];
50 //extern unsigned char AmlCode_ssdt8[];
51 #endif
52
53 #define IO_APIC_ADDR    0xfec00000UL
54
55 unsigned long acpi_fill_madt(unsigned long current)
56 {
57         unsigned int gsi_base=0x18;
58
59         struct mb_sysconf_t *m;
60
61         m = sysconf.mb;
62  
63         /* create all subtables for processors */
64         current = acpi_create_madt_lapics(current);
65         
66         /* Write 8111 IOAPIC */
67         current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *)current, m->apicid_8111,
68                         IO_APIC_ADDR, 0);
69
70         /* Write all 8131 IOAPICs */
71         {
72                 device_t dev;
73                 struct resource *res;
74                 dev = dev_find_slot(m->bus_8132_0, PCI_DEVFN((sysconf.hcdn[0]&0xff), 1));
75                 if (dev) {
76                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
77                         if (res) {
78                                 current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *)current, m->apicid_8132_1,
79                                         res->base, gsi_base );
80                                 gsi_base+=7;
81
82                         }
83                 }
84                 dev = dev_find_slot(m->bus_8132_0, PCI_DEVFN((sysconf.hcdn[0] & 0xff)+1, 1));
85                 if (dev) {
86                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
87                         if (res) {
88                                 current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *)current, m->apicid_8132_2,
89                                         res->base, gsi_base );
90                                 gsi_base+=7;
91                         }
92                 }
93         }
94
95         current += acpi_create_madt_irqoverride( (acpi_madt_irqoverride_t *)
96                         current, 0, 0, 2, 5 );
97                 /* 0: mean bus 0--->ISA */
98                 /* 0: PIC 0 */
99                 /* 2: APIC 2 */ 
100                 /* 5 mean: 0101 --> Edige-triggered, Active high*/
101
102
103                 /* create all subtables for processors */
104         current = acpi_create_madt_lapic_nmis(current, 5, 1);
105                 /* 1: LINT1 connect to NMI */
106
107
108         return current;
109 }
110
111 extern void get_bus_conf(void);
112
113 extern void update_ssdt(void *ssdt);
114
115 unsigned long write_acpi_tables(unsigned long start)
116 {
117         unsigned long current;
118         acpi_rsdp_t *rsdp;
119         acpi_rsdt_t *rsdt;
120         acpi_hpet_t *hpet;
121         acpi_madt_t *madt;
122         acpi_srat_t *srat;
123         acpi_slit_t *slit;
124         acpi_fadt_t *fadt;
125         acpi_facs_t *facs;
126         acpi_header_t *dsdt;
127         acpi_header_t *ssdt;
128         acpi_header_t *ssdtx;
129
130         unsigned char *AmlCode_ssdtx[HC_POSSIBLE_NUM];
131
132         int i;
133
134         get_bus_conf(); //it will get sblk, pci1234, hcdn, and sbdn
135
136         /* Align ACPI tables to 16byte */
137         start   = ( start + 0x0f ) & -0x10;
138         current = start;
139         
140         printk_info("ACPI: Writing ACPI tables at %lx...\n", start);
141
142         /* We need at least an RSDP and an RSDT Table */
143         rsdp = (acpi_rsdp_t *) current;
144         current += sizeof(acpi_rsdp_t);
145         rsdt = (acpi_rsdt_t *) current;
146         current += sizeof(acpi_rsdt_t);
147
148         /* clear all table memory */
149         memset((void *)start, 0, current - start);
150         
151         acpi_write_rsdp(rsdp, rsdt);
152         acpi_write_rsdt(rsdt);
153
154         /*
155          * We explicitly add these tables later on:
156          */
157         printk_debug("ACPI:    * HPET\n");
158         hpet = (acpi_hpet_t *) current;
159         current += sizeof(acpi_hpet_t);
160         acpi_create_hpet(hpet);
161         acpi_add_table(rsdt,hpet);
162
163         /* If we want to use HPET Timers Linux wants an MADT */
164         printk_debug("ACPI:    * MADT\n");
165         madt = (acpi_madt_t *) current;
166         acpi_create_madt(madt);
167         current+=madt->header.length;
168         acpi_add_table(rsdt,madt);
169
170
171         /* SRAT */
172         printk_debug("ACPI:    * SRAT\n");
173         srat = (acpi_srat_t *) current;
174         acpi_create_srat(srat);
175         current+=srat->header.length;
176         acpi_add_table(rsdt,srat);
177
178         /* SLIT */
179         printk_debug("ACPI:    * SLIT\n");
180         slit = (acpi_slit_t *) current;
181         acpi_create_slit(slit);
182         current+=slit->header.length;
183         acpi_add_table(rsdt,slit);
184
185         /* SSDT */
186         printk_debug("ACPI:    * SSDT\n");
187         ssdt = (acpi_header_t *)current;
188         current += ((acpi_header_t *)AmlCode_ssdt)->length;
189         memcpy((void *)ssdt, (void *)AmlCode_ssdt, ((acpi_header_t *)AmlCode_ssdt)->length);
190         //Here you need to set value in pci1234, sblk and sbdn in get_bus_conf.c
191         update_ssdt((void*)ssdt);
192         /* recalculate checksum */
193         ssdt->checksum = 0;
194         ssdt->checksum = acpi_checksum((unsigned char *)ssdt,ssdt->length);
195         acpi_add_table(rsdt,ssdt);
196
197 #if ACPI_SSDTX_NUM >= 1
198         // we need to make ssdt2 match to PCI2 in pci2.asl,... pci1234[1] 
199         AmlCode_ssdtx[1] = AmlCode_ssdt2;
200 //      AmlCode_ssdtx[2] = AmlCode_ssdt3;
201 //      AmlCode_ssdtx[3] = AmlCode_ssdt4;
202 //      AmlCode_ssdtx[4] = AmlCode_ssdt5;
203 //      AmlCode_ssdtx[5] = AmlCode_ssdt6;
204 //      AmlCode_ssdtx[6] = AmlCode_ssdt7;
205 //      AmlCode_ssdtx[7] = AmlCode_ssdt8;
206
207         //same htio, but different possition? We may have to copy, change HCIN, and recalculate the checknum and add_table
208         
209         for(i=1;i<sysconf.hc_possible_num;i++) {  // 0: is hc sblink
210                 if((sysconf.pci1234[i] & 1) != 1 ) continue;
211                 printk_debug("ACPI:    * SSDT for PCI%d\n", i+1); //pci0 and pci1 are in dsdt
212                 ssdtx = (acpi_header_t *)current;
213                 current += ((acpi_header_t *)AmlCode_ssdtx[i])->length;
214                 memcpy((void *)ssdtx, (void *)AmlCode_ssdtx[i], ((acpi_header_t *)AmlCode_ssdtx[i])->length);
215                 acpi_add_table(rsdt,ssdtx);
216         }
217 #endif
218
219
220         /* FACS */
221         printk_debug("ACPI:    * FACS\n");
222         facs = (acpi_facs_t *) current;
223         current += sizeof(acpi_facs_t);
224         acpi_create_facs(facs);
225
226         /* DSDT */
227         printk_debug("ACPI:    * DSDT\n");
228         dsdt = (acpi_header_t *)current;
229         current += ((acpi_header_t *)AmlCode)->length;
230         memcpy((void *)dsdt,(void *)AmlCode, \
231                         ((acpi_header_t *)AmlCode)->length);
232         printk_debug("ACPI:    * DSDT @ %08x Length %x\n",dsdt,dsdt->length);
233
234         /* FDAT */
235         printk_debug("ACPI:    * FADT\n");
236         fadt = (acpi_fadt_t *) current;
237         current += sizeof(acpi_fadt_t);
238
239         acpi_create_fadt(fadt,facs,dsdt);
240         acpi_add_table(rsdt,fadt);
241
242 #if DUMP_ACPI_TABLES == 1
243         printk_debug("rsdp\n");
244         dump_mem(rsdp, ((void *)rsdp) + sizeof(acpi_rsdp_t));
245
246         printk_debug("rsdt\n");
247         dump_mem(rsdt, ((void *)rsdt) + sizeof(acpi_rsdt_t));
248
249         printk_debug("madt\n");
250         dump_mem(madt, ((void *)madt) + madt->header.length);
251
252         printk_debug("srat\n");
253         dump_mem(srat, ((void *)srat) + srat->header.length);
254
255         printk_debug("slit\n");
256         dump_mem(slit, ((void *)slit) + slit->header.length);
257
258         printk_debug("ssdt\n");
259         dump_mem(ssdt, ((void *)ssdt) + ssdt->length);
260
261         printk_debug("fadt\n");
262         dump_mem(fadt, ((void *)fadt) + fadt->header.length);
263 #endif
264
265         printk_info("ACPI: done.\n");
266         return current;
267 }
268