2 * LinuxBIOS 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
13 * Each system port implementing ACPI has to provide two functions:
18 * See Solo or Epia port on more details.
21 #include <console/console.h>
23 #include <arch/acpi.h>
24 #include <device/pci.h>
26 u8 acpi_checksum(u8 *table, u32 length)
37 * add an acpi table to rsdt structure, and recalculate checksum
40 void acpi_add_table(acpi_rsdt_t *rsdt, void *table)
45 if(rsdt->entry[i]==0) {
46 rsdt->entry[i]=(u32)table;
47 /* fix length to stop kernel winging about invalid entries */
48 rsdt->header.length = sizeof(acpi_header_t) + (sizeof(u32) * (i+1));
50 /* hope this won't get optimized away */
51 rsdt->header.checksum=0;
52 rsdt->header.checksum=acpi_checksum((u8 *)rsdt,
55 printk_debug("ACPI: added table %d/8 Length now %d\n",i+1,rsdt->header.length);
60 printk_warning("ACPI: could not add ACPI table to RSDT. failed.\n");
64 int acpi_create_madt_lapic(acpi_madt_lapic_t *lapic, u8 cpu, u8 apic)
67 lapic->length=sizeof(acpi_madt_lapic_t);
70 lapic->processor_id=cpu;
73 return(lapic->length);
76 int acpi_create_madt_ioapic(acpi_madt_ioapic_t *ioapic, u8 id, u32 addr,u32 gsi_base)
79 ioapic->length=sizeof(acpi_madt_ioapic_t);
80 ioapic->reserved=0x00;
81 ioapic->gsi_base=gsi_base;
84 ioapic->ioapic_addr=addr;
86 return(ioapic->length);
89 int acpi_create_madt_irqoverride(acpi_madt_irqoverride_t *irqoverride,
90 u8 bus, u8 source, u32 gsirq, u16 flags)
93 irqoverride->length=sizeof(acpi_madt_irqoverride_t);
95 irqoverride->source=source;
96 irqoverride->gsirq=gsirq;
97 irqoverride->flags=flags;
99 return(irqoverride->length);
102 int acpi_create_madt_lapic_nmi(acpi_madt_lapic_nmi_t *lapic_nmi, u8 cpu,
106 lapic_nmi->length=sizeof(acpi_madt_lapic_nmi_t);
108 lapic_nmi->flags=flags;
109 lapic_nmi->processor_id=cpu;
110 lapic_nmi->lint=lint;
112 return(lapic_nmi->length);
115 void acpi_create_madt(acpi_madt_t *madt)
117 #define LOCAL_APIC_ADDR 0xfee00000ULL
119 acpi_header_t *header=&(madt->header);
120 unsigned long current=(unsigned long)madt+sizeof(acpi_madt_t);
122 memset((void *)madt, 0, sizeof(acpi_madt_t));
124 /* fill out header fields */
125 memcpy(header->signature, MADT_NAME, 4);
126 memcpy(header->oem_id, OEM_ID, 6);
127 memcpy(header->oem_table_id, MADT_TABLE, 8);
128 memcpy(header->asl_compiler_id, ASLC, 4);
130 header->length = sizeof(acpi_madt_t);
131 header->revision = 1;
133 madt->lapic_addr= LOCAL_APIC_ADDR;
134 madt->flags = 0x1; /* PCAT_COMPAT */
136 current = acpi_dump_apics(current);
138 /* recalculate length */
139 header->length= current - (unsigned long)madt;
141 header->checksum = acpi_checksum((void *)madt, header->length);
144 void acpi_create_hpet(acpi_hpet_t *hpet)
146 #define HPET_ADDR 0xfed00000ULL
147 acpi_header_t *header=&(hpet->header);
148 acpi_addr_t *addr=&(hpet->addr);
150 memset((void *)hpet, 0, sizeof(acpi_hpet_t));
152 /* fill out header fields */
153 memcpy(header->signature, HPET_NAME, 4);
154 memcpy(header->oem_id, OEM_ID, 6);
155 memcpy(header->oem_table_id, HPET_TABLE, 8);
156 memcpy(header->asl_compiler_id, ASLC, 4);
158 header->length = sizeof(acpi_hpet_t);
159 header->revision = 1;
161 /* fill out HPET address */
162 addr->space_id = 0; /* Memory */
163 addr->bit_width = 64;
164 addr->bit_offset = 0;
165 addr->addrl = HPET_ADDR & 0xffffffff;
166 addr->addrh = HPET_ADDR >> 32;
168 hpet->id = 0x102282a0; /* AMD ? */
170 hpet->min_tick = 4096;
172 header->checksum = acpi_checksum((void *)hpet, sizeof(acpi_hpet_t));
175 void acpi_create_facs(acpi_facs_t *facs)
177 memset( (void *)facs,0, sizeof(acpi_facs_t));
179 memcpy(facs->signature,"FACS",4);
180 facs->length = sizeof(acpi_facs_t);
181 facs->hardware_signature = 0;
182 facs->firmware_waking_vector = 0;
183 facs->global_lock = 0;
185 facs->x_firmware_waking_vector_l = 0;
186 facs->x_firmware_waking_vector_h = 0;
190 void acpi_write_rsdt(acpi_rsdt_t *rsdt)
192 acpi_header_t *header=&(rsdt->header);
194 /* fill out header fields */
195 memcpy(header->signature, RSDT_NAME, 4);
196 memcpy(header->oem_id, OEM_ID, 6);
197 memcpy(header->oem_table_id, RSDT_TABLE, 8);
198 memcpy(header->asl_compiler_id, ASLC, 4);
200 header->length = sizeof(acpi_rsdt_t);
201 header->revision = 1;
203 /* fill out entries */
205 // entries are filled in later, we come with an empty set.
209 header->checksum = acpi_checksum((void *)rsdt, sizeof(acpi_rsdt_t));
212 void acpi_write_rsdp(acpi_rsdp_t *rsdp, acpi_rsdt_t *rsdt)
214 memcpy(rsdp->signature, RSDP_SIG, 8);
215 memcpy(rsdp->oem_id, OEM_ID, 6);
217 rsdp->length = sizeof(acpi_rsdp_t);
218 rsdp->rsdt_address = (u32)rsdt;
219 rsdp->checksum = acpi_checksum((void *)rsdp, 20);
220 rsdp->ext_checksum = acpi_checksum((void *)rsdp, sizeof(acpi_rsdp_t));