Chameleon

Chameleon Svn Source Tree

Root/branches/cparm/i386/libsaio/acpi_tools.c

  • Property svn:executable set to *
1/*
2 Copyright (c) 2010, Intel Corporation
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7
8 * Redistributions of source code must retain the above copyright notice,
9 this list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright notice,
11 this list of conditions and the following disclaimer in the documentation
12 and/or other materials provided with the distribution.
13 * Neither the name of Intel Corporation nor the names of its contributors
14 may be used to endorse or promote products derived from this software
15 without specific prior written permission.
16
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
21 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include "datatype.h"
30#include "intel_acpi.h"
31#include "ppm.h"
32#include "acpi_tools.h"
33
34static U32 GetRsdtPointer(void *mem_addr, U32 mem_size, ACPI_TABLES * acpi_tables);
35static U32 GetXsdtPointer(ACPI_TABLES * acpi_tables);
36static ACPI_TABLE_HEADER *GetTablePtr(ACPI_TABLE_RSDT * rsdt, U32 signature);
37static ACPI_TABLE_HEADER *GetTablePtr64(ACPI_TABLE_XSDT * xsdt, U32 signature);
38
39//-------------------------------------------------------------------------------
40//
41// Procedure: FindAcpiTables - Collects addresses for RSDP, RSDT, FADT, & DSDT.
42//
43// Description: Finds the differentiated system description table pointer
44// by scanning and checking ACPI tables. This function will
45// get and store the following ACPI Table Pointers:
46// 1) RSD Pointer in RsdPointer Variable
47// 2) RSDT Pointer in RsdtPointer Variable(RSDP->RSDT)
48// 3) XSDT Pointer in XsdtPointer Variable(RSDP->XSDT)
49// 4) FACP Pointer in FacpPointer Variable(RSDP->RSDT->FACP)
50// 5) FACP(64) Pointer in FacpPointer64 Variable(RSDP->XSDT->FACP)
51// 6) DSDT Pointer in DsdtPointer Variable(RSDP->RSDT->FACP->DSDT)
52// 7) DSDT(64) Pointer in DsdtPointer64 Variable(RSDP->XSDT->FACP->XDSDT)
53// 8) FACS Pointer in FacsPointer Variable(RSDP->RSDT->FACP->FACS)
54// 9) FACS(64) Pointer in FacsPointer64 Variable(RSDP->XSDT->FACP->XFACS)
55// A) MADT Pointer in FacsPointer Variable(RSDP->RSDT->APIC)
56// B) MADT(64) Pointer in MadtPointer64 Variable(RSDP->XSDT->APIC)
57//
58//-------------------------------------------------------------------------------
59U32 FindAcpiTables(ACPI_TABLES * acpi_tables)
60{
61 U32 success = 0ul;
62
63 // Perform init of ACPI table pointers
64 {
65 void *null = 0ul;
66 acpi_tables->DsdtPointer = null;
67 acpi_tables->DsdtPointer64 = null;
68 acpi_tables->FacpPointer = null;
69 acpi_tables->FacsPointer = null;
70 acpi_tables->FacsPointer64 = null;
71 acpi_tables->RsdPointer = null;
72 acpi_tables->RsdtPointer = null;
73 acpi_tables->MadtPointer = null;
74acpi_tables->MadtPointer64 = null;
75 acpi_tables->XsdtPointer = null;
76 acpi_tables->FacpPointer64 = null;
77 }
78
79 // Find the RSDT pointer by scanning EBDA/E000/F000 segments.
80
81 // Init memory address as EBDA and scan 1KB region
82 success = GetRsdtPointer((void *)(((U32) * (U16 *) 0x40E) << 4), 0x400, acpi_tables);
83
84 // Init memory address as E000 segment and scan 64KB region
85 if (!success)
86 success = GetRsdtPointer((void *)0x0E0000, 0x10000, acpi_tables);
87
88 // Init memory address as F000 segment and scan 64KB region
89 if (!success)
90 success = GetRsdtPointer((void *)0x0F0000, 0x10000, acpi_tables);
91
92 if (!success)
93 return (0ul);
94
95 GetXsdtPointer(acpi_tables);
96
97 // Find FACP table pointer which is one of table pointers in the RDST
98 acpi_tables->FacpPointer = (ACPI_TABLE_FADT *)
99 GetTablePtr(acpi_tables->RsdtPointer, NAMESEG("FACP"));
100 if (acpi_tables->FacpPointer == 0ul)
101 return (0ul);
102
103 // Find FACP(64) table pointer which is one of table pointers in the XDST
104 acpi_tables->FacpPointer64 = (ACPI_TABLE_FADT *)
105 GetTablePtr64(acpi_tables->XsdtPointer, NAMESEG("FACP"));
106
107 // Find the DSDT which is included in the FACP table
108 acpi_tables->DsdtPointer = (ACPI_TABLE_DSDT *) acpi_tables->FacpPointer->Dsdt;
109 if ((*(U32 *) (acpi_tables->DsdtPointer->Header.Signature) != NAMESEG("DSDT")) ||
110 (GetChecksum(acpi_tables->DsdtPointer, acpi_tables->DsdtPointer->Header.Length) != 0))
111 return (0ul);
112
113{
114// Find the XDSDT which is included in the FACP(64) table
115ACPI_TABLE_DSDT *DsdtPointer64 = (ACPI_TABLE_DSDT *)((U32)acpi_tables->FacpPointer64->XDsdt);
116if ((*(U32*) (DsdtPointer64->Header.Signature) == NAMESEG("DSDT")) &&
117(GetChecksum(DsdtPointer64, DsdtPointer64->Header.Length) == 0))
118acpi_tables->DsdtPointer64 = (ACPI_TABLE_DSDT *) DsdtPointer64;
119}
120
121 // Find the FACS which is included in the FACP table
122 acpi_tables->FacsPointer = (ACPI_TABLE_FACS *) acpi_tables->FacpPointer->Facs;
123 if (*(U32 *) (acpi_tables->FacsPointer->Signature) != NAMESEG("FACS"))
124 return (0ul);
125
126{
127// Find the XFACS which is included in the FACP(64) table
128ACPI_TABLE_FACS *FacsPointer64 = (ACPI_TABLE_FACS *)((U32)acpi_tables->FacpPointer64->XFacs);
129if (*(U32*) (FacsPointer64->Signature) == NAMESEG("FACS"))
130acpi_tables->FacsPointer64 = (ACPI_TABLE_FACS *) FacsPointer64;
131}
132
133 // Find the MADT table which is one of the table pointers in the RSDT
134 acpi_tables->MadtPointer = (ACPI_TABLE_MADT *) GetTablePtr(acpi_tables->RsdtPointer, NAMESEG("APIC"));
135 if (acpi_tables->MadtPointer == 0ul)
136 return (0ul);
137
138// Find the MADT(64) table which is one of the table pointers in the XSDT
139 acpi_tables->MadtPointer64 = (ACPI_TABLE_MADT *) GetTablePtr64(acpi_tables->XsdtPointer, NAMESEG("APIC"));
140
141 return (1ul);
142}
143
144//-----------------------------------------------------------------------------
145U32 get_num_tables(ACPI_TABLE_RSDT * rsdt)
146{
147 // Compute number of table pointers included in RSDT
148 return ((rsdt->Header.Length - sizeof(ACPI_TABLE_HEADER))
149 / sizeof(ACPI_TABLE_HEADER *));
150}
151
152//-----------------------------------------------------------------------------
153U32 get_num_tables64(ACPI_TABLE_XSDT * xsdt)
154{
155 {
156 void *null = 0ul;
157 if (xsdt == null)
158 return 0ul;
159 }
160
161 // Compute number of table pointers included in XSDT
162 return ((xsdt->Header.Length - sizeof(ACPI_TABLE_HEADER))
163 / sizeof(U64));
164}
165
166//-------------------------------------------------------------------------------
167//
168// Procedure: GetTablePtr - Find ACPI table in RSDT with input signature.
169//
170//-------------------------------------------------------------------------------
171static ACPI_TABLE_HEADER *GetTablePtr(ACPI_TABLE_RSDT * rsdt, U32 signature)
172{
173 U32 index;
174 U32 num_tables;
175 ACPI_TABLE_HEADER **table_array = (ACPI_TABLE_HEADER **) rsdt->TableOffsetEntry;
176
177 // Compute number of table pointers included in RSDT
178 num_tables = get_num_tables(rsdt);
179
180 for (index = 0; index < num_tables; index++) {
181 if ((*(U32 *) (table_array[index]->Signature) == signature) &&
182 (GetChecksum(table_array[index], table_array[index]->Length) == 0)) {
183 return (table_array[index]);
184 }
185 }
186 return (0);
187}
188
189//-------------------------------------------------------------------------------
190//
191// Procedure: GetTablePtr64 - Find ACPI table in XSDT with input signature.
192//
193//-------------------------------------------------------------------------------
194#if 0
195static ACPI_TABLE_HEADER *GetTablePtr64(ACPI_TABLE_XSDT * xsdt, U32 signature)
196{
197 U32 index;
198 U32 num_tables;
199 ACPI_TABLE_HEADER *table = (ACPI_TABLE_HEADER *) xsdt->TableOffsetEntry;
200
201 // Compute number of table pointers included in XSDT
202 num_tables = get_num_tables64(xsdt);
203
204 for (index = 0; index < num_tables; index++) {
205 if (((U32) (table->Signature) == signature) &&
206 (GetChecksum(table, table->Length) == 0)) {
207 return (table);
208 }
209 // Move array pointer to next 64-bit pointer
210 table = (ACPI_TABLE_HEADER *) ((U32) table + sizeof(U64));
211 }
212 return (0);
213}
214#else
215static ACPI_TABLE_HEADER *GetTablePtr64(ACPI_TABLE_XSDT * xsdt, U32 signature)
216{
217 U32 index;
218 U32 num_tables;
219
220 // Compute number of table pointers included in XSDT
221 num_tables = get_num_tables64(xsdt);
222
223 for (index = 0; index < num_tables; index++) {
224U64 ptr = xsdt->TableOffsetEntry[index];
225
226 if ((*(U32 *) ((ACPI_TABLE_HEADER *) (unsigned long)ptr)->Signature == signature) &&
227 (GetChecksum(((ACPI_TABLE_HEADER *) (unsigned long)ptr), ((ACPI_TABLE_HEADER *) (unsigned long)ptr)->Length) == 0)) {
228 return (((ACPI_TABLE_HEADER *) (unsigned long)ptr));
229 }
230 }
231 return (0);
232}
233#endif
234
235
236//-------------------------------------------------------------------------------
237//
238// Procedure: GetChecksum - Performs byte checksum
239//
240//-------------------------------------------------------------------------------
241U8 GetChecksum(void *mem_addr, U32 mem_size)
242{
243 U8 *current = mem_addr;
244 U8 *end = current + mem_size;
245 U8 checksum = 0;
246
247 for (; current < end; current++)
248 checksum = checksum + *current;
249
250 return (checksum);
251}
252
253/*==========================================================================
254 * Function to map 32 bit physical address to 64 bit virtual address
255 */
256
257
258//-------------------------------------------------------------------------------
259//
260// Procedure: GetRsdtPointer - Scans given segment for RSDT pointer
261//
262// Description: Scans for root system description table pointer signature
263// ('RSD PTR ') , verifies checksum, and returns pointer to
264// RSDT table if found.
265//
266//-------------------------------------------------------------------------------
267static U32 GetRsdtPointer(void *mem_addr, U32 mem_size, ACPI_TABLES * acpi_tables)
268{
269 U8 *current = mem_addr;
270 U8 *end = current + mem_size;
271
272 // Quick sanity check for a valid start address
273 if (current == 0ul)
274 return (0ul);
275
276 for (; current < end; current += 16) {
277 if (*(volatile U64 *)current == NAMESEG64("RSD PTR ")) {
278 if (GetChecksum(current, ACPI_RSDP_REV0_SIZE) == 0) {
279 // RSD pointer structure checksum okay, lookup the RSDT pointer.
280 acpi_tables->RsdPointer = (ACPI_TABLE_RSDP *)current;
281 acpi_tables->RsdtPointer = (ACPI_TABLE_RSDT *) acpi_tables->RsdPointer->RsdtPhysicalAddress;
282 if ((acpi_tables->RsdPointer != (void*)0ul) && (acpi_tables->RsdtPointer != (void*)0ul))
283 return (1ul);
284 else
285 return (0ul);
286 }
287 }
288 }
289
290 return (0);
291}
292
293//-------------------------------------------------------------------------------
294//
295// Procedure: GetXsdtPointer
296//
297//-------------------------------------------------------------------------------
298static U32 GetXsdtPointer(ACPI_TABLES * acpi_tables)
299{
300 if ((GetChecksum(acpi_tables->RsdPointer, sizeof(ACPI_TABLE_RSDP)) == 0) &&
301 (acpi_tables->RsdPointer->Revision == 2) &&
302 (acpi_tables->RsdPointer->Length == sizeof(ACPI_TABLE_RSDP))) {
303 // RSD pointer structure checksum okay, lookup the XSDT pointer.
304 acpi_tables->XsdtPointer = (ACPI_TABLE_XSDT *) (U32) acpi_tables->RsdPointer->XsdtPhysicalAddress;
305 return (1ul);
306 }
307
308 return (0ul);
309}
310

Archive Download this file

Revision: 1804