remove trailing whitespace
[coreboot.git] / src / mainboard / siemens / sitemp_g1p1 / acpi_tables.c
1 /*
2  * This file is part of the coreboot project.
3  *
4  * Copyright (C) 2008 Advanced Micro Devices, Inc.
5  * Copyright (C) 2010 Siemens AG, Inc.
6  * (Written by Josef Kellermann <joseph.kellermann@heitec.de> for Siemens AG, Inc.)
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; version 2 of the License.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
20  */
21
22 #include <console/console.h>
23 #include <string.h>
24 #include <arch/acpi.h>
25 #include <arch/ioapic.h>
26 #include <arch/smp/mpspec.h>
27 #include <device/pci.h>
28 #include <device/pci_ids.h>
29 #include <cpu/x86/msr.h>
30 #include <cpu/amd/mtrr.h>
31 #include <cpu/amd/amdk8_sysconf.h>
32 #include <../../../northbridge/amd/amdk8/acpi.h>
33 #include <arch/cpu.h>
34 #include <cpu/amd/model_fxx_powernow.h>
35 #include <southbridge/amd/rs690/rs690.h>
36
37 #define DUMP_ACPI_TABLES 0
38
39 #ifndef CONFIG_LINT01_CONVERSION
40 #define CONFIG_LINT01_CONVERSION 1
41 #endif
42
43 extern u16 pm_base;
44
45 /*
46 * Assume the max pstate number is 8
47 * 0x21(33 bytes) is one package length of _PSS package
48 */
49
50 #define Maxpstate 8
51 #define Defpkglength 0x21
52 #define GLOBAL_VARS_SIZE 0x100
53
54 typedef struct {
55         /* Miscellaneous */
56         u16 osys;
57         u16 linx;
58         u32     pcba;
59         u8  mpen;
60         u8 reserv[247];
61 } __attribute__((packed)) global_vars_t;
62
63 static void acpi_write_gvars(global_vars_t *gvars)
64 {
65         device_t dev;
66         struct resource *res;
67
68         memset((void *)gvars, 0, GLOBAL_VARS_SIZE);
69
70         gvars->pcba = EXT_CONF_BASE_ADDRESS;
71         dev = dev_find_slot(0, PCI_DEVFN(0,0));
72         res = probe_resource(dev, 0x1C);
73         if( res )
74                 gvars->pcba = res->base;
75
76         gvars->mpen = 1;
77 }
78
79 static void acpi_create_my_hpet(acpi_hpet_t *hpet)
80 {
81 #define HPET_ADDR  0xfed00000ULL
82         acpi_header_t *header=&(hpet->header);
83         acpi_addr_t *addr=&(hpet->addr);
84
85         memset((void *)hpet, 0, sizeof(acpi_hpet_t));
86
87         /* fill out header fields */
88         memcpy(header->signature, "HPET", 4);
89         memcpy(header->oem_id, OEM_ID, 6);
90         memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
91         memcpy(header->asl_compiler_id, ASLC, 4);
92
93         header->length = sizeof(acpi_hpet_t);
94         header->revision = 1;
95
96         /* fill out HPET address */
97         addr->space_id          = 0; /* Memory */
98         addr->bit_width         = 64;
99         addr->bit_offset        = 0;
100         addr->addrl             = HPET_ADDR & 0xffffffff;
101         addr->addrh             = HPET_ADDR >> 32;
102
103         hpet->id = 0x43538301;
104         hpet->number    = 0;
105         hpet->min_tick  = 20;
106
107         header->checksum        = acpi_checksum((void *)hpet, sizeof(acpi_hpet_t));
108 }
109
110 #if DUMP_ACPI_TABLES == 1
111 static void dump_mem(u32 start, u32 end)
112 {
113         u32 i;
114         print_debug("dump_mem:");
115         for (i = start; i < end; i++) {
116                 if ((i & 0xf) == 0) {
117                         printk(BIOS_DEBUG, "\n%08x:", i);
118                 }
119                 printk(BIOS_DEBUG, " %02x", (u8)*((u8 *)i));
120         }
121         print_debug("\n");
122 }
123 #endif
124
125 extern const unsigned char AmlCode[];
126
127 unsigned long acpi_fill_mcfg(unsigned long current)
128 {
129         struct resource *res;
130         resource_t mmconf_base = EXT_CONF_BASE_ADDRESS; // default
131
132         device_t dev = dev_find_slot(0,PCI_DEVFN(0,0));
133         // we report mmconf base
134         res = probe_resource(dev, 0x1C);
135         if( res )
136                 mmconf_base = res->base;
137
138         current += acpi_create_mcfg_mmconfig((acpi_mcfg_mmconfig_t *)current, mmconf_base, 0x0, 0x0, 0x1f); // Fix me: should i reserve 255 busses ?
139
140         return current;
141 }
142
143 unsigned long acpi_fill_madt(unsigned long current)
144 {
145         /* create all subtables for processors */
146         current = acpi_create_madt_lapics(current);
147
148         /* Write SB600 IOAPIC, only one */
149         current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, 2,
150                                            IO_APIC_ADDR, 0);
151 #if CONFIG_LINT01_CONVERSION == 0
152         current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *)
153                                                 current, 0, 0, 2, 0);
154
155         current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *)
156                                                 current, 0, 9, 9, MP_IRQ_TRIGGER_LEVEL | MP_IRQ_POLARITY_LOW);
157 #else
158                                                 /* 0: mean bus 0--->ISA */
159         /* 0: PIC 0 */
160         /* 2: APIC 2 */
161         /* 5 mean: 0101 --> Edige-triggered, Active high */
162
163         /* create all subtables for processors */
164         current = acpi_create_madt_lapic_nmis(current, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, 1);
165         /* 1: LINT1 connect to NMI */
166         set_nbcfg_enable_bits(dev_find_slot(0, PCI_DEVFN(0x18, 0)), 0x68, 1 << 16, 1 << 16); // Local Interrupt Conversion Enable
167 #endif
168         return current;
169 }
170
171 unsigned long acpi_fill_ssdt_generator(unsigned long current, const char *oem_table_id) {
172         k8acpi_write_vars();
173         amd_model_fxx_generate_powernow(pm_base + 8, 6, 1);
174         return (unsigned long) (acpigen_get_current());
175 }
176
177 #define ALIGN_CURRENT current = ((current + 0x0f) & -0x10)
178
179 unsigned long write_acpi_tables(unsigned long start)
180 {
181         unsigned long current;
182         int i;
183
184         acpi_rsdp_t *rsdp;
185         acpi_rsdt_t *rsdt;
186         acpi_srat_t *srat;
187         acpi_xsdt_t *xsdt;
188         acpi_mcfg_t *mcfg;
189         acpi_hpet_t *hpet;
190         acpi_madt_t *madt;
191         acpi_fadt_t *fadt;
192         acpi_facs_t *facs;
193         acpi_header_t *dsdt;
194         acpi_header_t *ssdt;
195
196         get_bus_conf();         /* it will get sblk, pci1234, hcdn, and sbdn */
197
198         /* Align ACPI tables to 16byte */
199         current = start;
200         ALIGN_CURRENT;
201
202         printk(BIOS_INFO, "ACPI: Writing ACPI tables at %lx...\n", start);
203
204         /* We need at least an RSDP and an RSDT Table */
205         rsdp = (acpi_rsdp_t *) current;
206         current += sizeof(acpi_rsdp_t);
207         ALIGN_CURRENT;
208         rsdt = (acpi_rsdt_t *) current;
209         current += sizeof(acpi_rsdt_t);
210         ALIGN_CURRENT;
211         xsdt = (acpi_xsdt_t *) current;
212         current += sizeof(acpi_xsdt_t);
213         ALIGN_CURRENT;
214
215         /* clear all table memory */
216         memset((void *)start, 0, current - start);
217
218         acpi_write_rsdp(rsdp, rsdt, xsdt);
219         acpi_write_rsdt(rsdt);
220         acpi_write_xsdt(xsdt);
221         /*
222          * We explicitly add these tables later on:
223          */
224         current = ALIGN(current, 64);
225         /* FACS */
226         printk(BIOS_DEBUG, "ACPI:     * FACS\n");
227         facs = (acpi_facs_t *) current;
228         acpi_create_facs(facs);
229         current += sizeof(acpi_facs_t);
230
231          /* HPET */
232         printk(BIOS_DEBUG, "ACPI:    * HPET\n");
233         hpet = (acpi_hpet_t *) current;
234         acpi_create_my_hpet(hpet);
235         current += sizeof(acpi_hpet_t);
236         acpi_add_table(rsdp, hpet);
237
238         /* If we want to use HPET Timers Linux wants an MADT */
239         printk(BIOS_DEBUG, "ACPI:    * MADT\n");
240         madt = (acpi_madt_t *) current;
241         acpi_create_madt(madt);
242         current += madt->header.length;
243         acpi_add_table(rsdp, madt);
244
245         /* MCFG */
246         printk(BIOS_DEBUG, "ACPI:    * MCFG\n");
247         mcfg = (acpi_mcfg_t *) current;
248         acpi_create_mcfg(mcfg);
249         current += mcfg->header.length;
250         acpi_add_table(rsdp, mcfg);
251
252         /* SSDT */
253         printk(BIOS_DEBUG, "ACPI:    * SSDT\n");
254         ssdt = (acpi_header_t *)current;
255         acpi_create_ssdt_generator(ssdt, ACPI_TABLE_CREATOR);
256         current += ssdt->length;
257         acpi_add_table(rsdp, ssdt);
258
259         /* DSDT */
260         printk(BIOS_DEBUG, "ACPI:    * DSDT\n");
261         dsdt = (acpi_header_t *)current;
262         memcpy(dsdt, &AmlCode, sizeof(acpi_header_t));
263         current += dsdt->length;
264         memcpy(dsdt, &AmlCode, dsdt->length);
265
266         /* Pack gvars into the ACPI table area */
267         for (i=0; i < dsdt->length; i++) {
268                 if (*(u32*)(((u32)dsdt) + i) == 0xBADEAFFE) {
269                         printk(BIOS_DEBUG, "ACPI: Patching up globals in DSDT at offset 0x%04x -> 0x%08lx\n", i, current);
270                         *(u32*)(((u32)dsdt) + i) = current;
271                         break;
272                 }
273         }
274
275         /* And fill it */
276         acpi_write_gvars((global_vars_t *)current);
277         current += GLOBAL_VARS_SIZE;
278         /* We patched up the DSDT, so we need to recalculate the checksum */
279         dsdt->checksum = 0;
280         dsdt->checksum = acpi_checksum((void *)dsdt, dsdt->length);
281         printk(BIOS_DEBUG, "ACPI:    * DSDT @ %p Length %x\n", dsdt, dsdt->length);
282
283         /* FADT */
284         printk(BIOS_DEBUG, "ACPI:    * FADT\n");
285         fadt = (acpi_fadt_t *) current;
286         current += sizeof(acpi_fadt_t);
287         acpi_create_fadt(fadt, facs, dsdt);
288         acpi_add_table(rsdp, fadt);
289
290         /* SRAT */
291         printk(BIOS_DEBUG, "ACPI:    * SRAT\n");
292         srat = (acpi_srat_t *) current;
293         acpi_create_srat(srat);
294         acpi_add_table(rsdp, srat);
295
296         printk(BIOS_DEBUG, "current = %lx\n", current);
297
298         printk(BIOS_INFO, "ACPI: done.\n");
299         return current;
300 }