2 * coreboot ACPI Table support
3 * written by Stefan Reinauer <stepan@openbios.org>
4 * (C) 2004 SUSE LINUX AG
5 * (C) 2005 Stefan Reinauer
7 * ACPI FADT, FACS, and DSDT table support added by
8 * Nick Barker <nick.barker9@btinternet.com>, and those portions
9 * (C) Copyright 2004 Nick Barker
11 * Copyright 2005 ADVANCED MICRO DEVICES, INC. All Rights Reserved.
12 * 2005.9 yhlu add SRAT table generation
16 * Each system port implementing ACPI has to provide two functions:
21 * See AMD Solo, Island Aruma or Via Epia-M port for more details.
24 #include <console/console.h>
26 #include <arch/acpi.h>
27 #include <device/pci.h>
29 u8 acpi_checksum(u8 *table, u32 length)
40 * add an acpi table to rsdt structure, and recalculate checksum
43 void acpi_add_table(acpi_rsdt_t *rsdt, void *table)
47 int entries_num = ARRAY_SIZE(rsdt->entry);
49 for (i=0; i<entries_num; i++) {
50 if(rsdt->entry[i]==0) {
51 rsdt->entry[i]=(u32)table;
52 /* fix length to stop kernel winging about invalid entries */
53 rsdt->header.length = sizeof(acpi_header_t) + (sizeof(u32) * (i+1));
55 /* hope this won't get optimized away */
56 rsdt->header.checksum=0;
57 rsdt->header.checksum=acpi_checksum((u8 *)rsdt,
60 printk_debug("ACPI: added table %d/%d Length now %d\n",i+1, entries_num, rsdt->header.length);
65 printk_warning("ACPI: could not add ACPI table to RSDT. failed.\n");
68 int acpi_create_mcfg_mmconfig(acpi_mcfg_mmconfig_t *mmconfig, u32 base, u16 seg_nr, u8 start, u8 end)
70 mmconfig->base_address = base;
71 mmconfig->base_reserved = 0;
72 mmconfig->pci_segment_group_number = seg_nr;
73 mmconfig->start_bus_number = start;
74 mmconfig->end_bus_number = end;
75 return (sizeof(acpi_mcfg_mmconfig_t));
79 int acpi_create_madt_lapic(acpi_madt_lapic_t *lapic, u8 cpu, u8 apic)
82 lapic->length=sizeof(acpi_madt_lapic_t);
85 lapic->processor_id=cpu;
88 return(lapic->length);
91 int acpi_create_madt_ioapic(acpi_madt_ioapic_t *ioapic, u8 id, u32 addr,u32 gsi_base)
94 ioapic->length=sizeof(acpi_madt_ioapic_t);
95 ioapic->reserved=0x00;
96 ioapic->gsi_base=gsi_base;
99 ioapic->ioapic_addr=addr;
101 return(ioapic->length);
104 int acpi_create_madt_irqoverride(acpi_madt_irqoverride_t *irqoverride,
105 u8 bus, u8 source, u32 gsirq, u16 flags)
108 irqoverride->length=sizeof(acpi_madt_irqoverride_t);
109 irqoverride->bus=bus;
110 irqoverride->source=source;
111 irqoverride->gsirq=gsirq;
112 irqoverride->flags=flags;
114 return(irqoverride->length);
117 int acpi_create_madt_lapic_nmi(acpi_madt_lapic_nmi_t *lapic_nmi, u8 cpu,
121 lapic_nmi->length=sizeof(acpi_madt_lapic_nmi_t);
123 lapic_nmi->flags=flags;
124 lapic_nmi->processor_id=cpu;
125 lapic_nmi->lint=lint;
127 return(lapic_nmi->length);
130 void acpi_create_madt(acpi_madt_t *madt)
132 #define LOCAL_APIC_ADDR 0xfee00000ULL
134 acpi_header_t *header=&(madt->header);
135 unsigned long current=(unsigned long)madt+sizeof(acpi_madt_t);
137 memset((void *)madt, 0, sizeof(acpi_madt_t));
139 /* fill out header fields */
140 memcpy(header->signature, MADT_NAME, 4);
141 memcpy(header->oem_id, OEM_ID, 6);
142 memcpy(header->oem_table_id, MADT_TABLE, 8);
143 memcpy(header->asl_compiler_id, ASLC, 4);
145 header->length = sizeof(acpi_madt_t);
146 header->revision = 1;
148 madt->lapic_addr= LOCAL_APIC_ADDR;
149 madt->flags = 0x1; /* PCAT_COMPAT */
151 current = acpi_fill_madt(current);
153 /* recalculate length */
154 header->length= current - (unsigned long)madt;
156 header->checksum = acpi_checksum((void *)madt, header->length);
159 void acpi_create_mcfg(acpi_mcfg_t *mcfg)
162 acpi_header_t *header=&(mcfg->header);
163 unsigned long current=(unsigned long)mcfg+sizeof(acpi_mcfg_t);
165 memset((void *)mcfg, 0, sizeof(acpi_mcfg_t));
167 /* fill out header fields */
168 memcpy(header->signature, MCFG_NAME, 4);
169 memcpy(header->oem_id, OEM_ID, 6);
170 memcpy(header->oem_table_id, MCFG_TABLE, 8);
171 memcpy(header->asl_compiler_id, ASLC, 4);
173 header->length = sizeof(acpi_mcfg_t);
174 header->revision = 1;
176 current = acpi_fill_mcfg(current);
178 /* recalculate length */
179 header->length= current - (unsigned long)mcfg;
181 header->checksum = acpi_checksum((void *)mcfg, header->length);
184 int acpi_create_srat_lapic(acpi_srat_lapic_t *lapic, u8 node, u8 apic)
187 lapic->length=sizeof(acpi_srat_lapic_t);
190 lapic->proximity_domain_7_0 = node;
193 return(lapic->length);
196 int acpi_create_srat_mem(acpi_srat_mem_t *mem, u8 node, u32 basek,u32 sizek, u32 flags)
199 mem->length=sizeof(acpi_srat_mem_t);
201 mem->base_address_low = (basek<<10);
202 mem->base_address_high = (basek>>(32-10));
204 mem->length_low = (sizek<<10);
205 mem->length_high = (sizek>>(32-10));
207 mem->proximity_domain = node;
214 void acpi_create_srat(acpi_srat_t *srat)
217 acpi_header_t *header=&(srat->header);
218 unsigned long current=(unsigned long)srat+sizeof(acpi_srat_t);
220 memset((void *)srat, 0, sizeof(acpi_srat_t));
222 /* fill out header fields */
223 memcpy(header->signature, SRAT_NAME, 4);
224 memcpy(header->oem_id, OEM_ID, 6);
225 memcpy(header->oem_table_id, SRAT_TABLE, 8);
226 memcpy(header->asl_compiler_id, ASLC, 4);
228 header->length = sizeof(acpi_srat_t);
229 header->revision = 1;
231 srat->resv = 0x1; /* BACK COMP */
233 current = acpi_fill_srat(current);
235 /* recalculate length */
236 header->length= current - (unsigned long)srat;
238 header->checksum = acpi_checksum((void *)srat, header->length);
241 void acpi_create_slit(acpi_slit_t *slit)
244 acpi_header_t *header=&(slit->header);
245 unsigned long current=(unsigned long)slit+sizeof(acpi_slit_t);
247 memset((void *)slit, 0, sizeof(acpi_slit_t));
249 /* fill out header fields */
250 memcpy(header->signature, SLIT_NAME, 4);
251 memcpy(header->oem_id, OEM_ID, 6);
252 memcpy(header->oem_table_id, SLIT_TABLE, 8);
253 memcpy(header->asl_compiler_id, ASLC, 4);
255 header->length = sizeof(acpi_slit_t);
256 header->revision = 1;
258 // current = acpi_fill_slit(current);
260 /* recalculate length */
261 header->length= current - (unsigned long)slit;
263 header->checksum = acpi_checksum((void *)slit, header->length);
266 void acpi_create_hpet(acpi_hpet_t *hpet)
268 #define HPET_ADDR 0xfed00000ULL
269 acpi_header_t *header=&(hpet->header);
270 acpi_addr_t *addr=&(hpet->addr);
272 memset((void *)hpet, 0, sizeof(acpi_hpet_t));
274 /* fill out header fields */
275 memcpy(header->signature, HPET_NAME, 4);
276 memcpy(header->oem_id, OEM_ID, 6);
277 memcpy(header->oem_table_id, HPET_TABLE, 8);
278 memcpy(header->asl_compiler_id, ASLC, 4);
280 header->length = sizeof(acpi_hpet_t);
281 header->revision = 1;
283 /* fill out HPET address */
284 addr->space_id = 0; /* Memory */
285 addr->bit_width = 64;
286 addr->bit_offset = 0;
287 addr->addrl = HPET_ADDR & 0xffffffff;
288 addr->addrh = HPET_ADDR >> 32;
290 hpet->id = 0x102282a0; /* AMD ? */
292 hpet->min_tick = 4096;
294 header->checksum = acpi_checksum((void *)hpet, sizeof(acpi_hpet_t));
297 void acpi_create_facs(acpi_facs_t *facs)
299 memset( (void *)facs,0, sizeof(acpi_facs_t));
301 memcpy(facs->signature,"FACS",4);
302 facs->length = sizeof(acpi_facs_t);
303 facs->hardware_signature = 0;
304 facs->firmware_waking_vector = 0;
305 facs->global_lock = 0;
307 facs->x_firmware_waking_vector_l = 0;
308 facs->x_firmware_waking_vector_h = 0;
312 void acpi_write_rsdt(acpi_rsdt_t *rsdt)
314 acpi_header_t *header=&(rsdt->header);
316 /* fill out header fields */
317 memcpy(header->signature, RSDT_NAME, 4);
318 memcpy(header->oem_id, OEM_ID, 6);
319 memcpy(header->oem_table_id, RSDT_TABLE, 8);
320 memcpy(header->asl_compiler_id, ASLC, 4);
322 header->length = sizeof(acpi_rsdt_t);
323 header->revision = 1;
325 /* fill out entries */
327 // entries are filled in later, we come with an empty set.
331 header->checksum = acpi_checksum((void *)rsdt, sizeof(acpi_rsdt_t));
334 void acpi_write_rsdp(acpi_rsdp_t *rsdp, acpi_rsdt_t *rsdt)
336 memcpy(rsdp->signature, RSDP_SIG, 8);
337 memcpy(rsdp->oem_id, OEM_ID, 6);
339 rsdp->length = sizeof(acpi_rsdp_t);
340 rsdp->rsdt_address = (u32)rsdt;
341 rsdp->checksum = acpi_checksum((void *)rsdp, 20);
342 rsdp->ext_checksum = acpi_checksum((void *)rsdp, sizeof(acpi_rsdp_t));