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->RSDT->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->FACP->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->SsdtPointer = null;
76 acpi_tables->XsdtPointer = null;
77 acpi_tables->FacpPointer64 = null;
78 }
79
80 // Find the RSDT pointer by scanning EBDA/E000/F000 segments.
81
82 // Init memory address as EBDA and scan 1KB region
83 success = GetRsdtPointer((void *)(((U32) * (U16 *) 0x40E) << 4), 0x400, acpi_tables);
84
85 // Init memory address as E000 segment and scan 64KB region
86 if (!success)
87 success = GetRsdtPointer((void *)0x0E0000, 0x10000, acpi_tables);
88
89 // Init memory address as F000 segment and scan 64KB region
90 if (!success)
91 success = GetRsdtPointer((void *)0x0F0000, 0x10000, acpi_tables);
92
93 if (!success)
94 return (0ul);
95
96 GetXsdtPointer(acpi_tables);
97
98 // Find FACP table pointer which is one of table pointers in the RDST
99 acpi_tables->FacpPointer = (ACPI_TABLE_FADT *)
100 GetTablePtr(acpi_tables->RsdtPointer, NAMESEG("FACP"));
101 if (acpi_tables->FacpPointer == 0ul)
102 return (0ul);
103
104 // Find FACP(64) table pointer which is one of table pointers in the XDST
105 acpi_tables->FacpPointer64 = (ACPI_TABLE_FADT *)
106 GetTablePtr64(acpi_tables->XsdtPointer, NAMESEG("FACP"));
107
108 // Find the DSDT which is included in the FACP table
109 acpi_tables->DsdtPointer = (ACPI_TABLE_DSDT *) acpi_tables->FacpPointer->Dsdt;
110 if ((*(U32 *) (acpi_tables->DsdtPointer->Header.Signature) != NAMESEG("DSDT")) ||
111 (GetChecksum(acpi_tables->DsdtPointer, acpi_tables->DsdtPointer->Header.Length) != 0))
112 return (0ul);
113
114{
115// Find the XDSDT which is included in the FACP(64) table
116ACPI_TABLE_DSDT *DsdtPointer64 = (ACPI_TABLE_DSDT *)((U32)acpi_tables->FacpPointer64->XDsdt);
117if ((*(U32*) (DsdtPointer64->Header.Signature) == NAMESEG("DSDT")) &&
118(GetChecksum(DsdtPointer64, DsdtPointer64->Header.Length) == 0))
119acpi_tables->DsdtPointer64 = (ACPI_TABLE_DSDT *) DsdtPointer64;
120}
121
122 // Find the FACS which is included in the FACP table
123 acpi_tables->FacsPointer = (ACPI_TABLE_FACS *) acpi_tables->FacpPointer->Facs;
124 if (*(U32 *) (acpi_tables->FacsPointer->Signature) != NAMESEG("FACS"))
125 return (0ul);
126
127{
128// Find the XFACS which is included in the FACP(64) table
129ACPI_TABLE_FACS *FacsPointer64 = (ACPI_TABLE_FACS *)((U32)acpi_tables->FacpPointer64->XFacs);
130if (*(U32*) (FacsPointer64->Signature) == NAMESEG("FACS"))
131acpi_tables->FacsPointer64 = (ACPI_TABLE_FACS *) FacsPointer64;
132}
133
134 // Find the MADT table which is one of the table pointers in the RSDT
135 acpi_tables->MadtPointer = (ACPI_TABLE_MADT *) GetTablePtr(acpi_tables->RsdtPointer, NAMESEG("APIC"));
136 if (acpi_tables->MadtPointer == 0ul)
137 return (0ul);
138
139// Find the MADT(64) table which is one of the table pointers in the XSDT
140 acpi_tables->MadtPointer64 = (ACPI_TABLE_MADT *) GetTablePtr64(acpi_tables->XsdtPointer, NAMESEG("APIC"));
141
142 return (1ul);
143}
144
145//-----------------------------------------------------------------------------
146U32 get_num_tables(ACPI_TABLE_RSDT * rsdt)
147{
148 // Compute number of table pointers included in RSDT
149 return ((rsdt->Header.Length - sizeof(ACPI_TABLE_HEADER))
150 / sizeof(ACPI_TABLE_HEADER *));
151}
152
153//-----------------------------------------------------------------------------
154U32 get_num_tables64(ACPI_TABLE_XSDT * xsdt)
155{
156 {
157 void *null = 0ul;
158 if (xsdt == null)
159 return 0ul;
160 }
161
162 // Compute number of table pointers included in XSDT
163 return ((xsdt->Header.Length - sizeof(ACPI_TABLE_HEADER))
164 / sizeof(U64));
165}
166
167//-------------------------------------------------------------------------------
168//
169// Procedure: GetTablePtr - Find ACPI table in RSDT with input signature.
170//
171//-------------------------------------------------------------------------------
172static ACPI_TABLE_HEADER *GetTablePtr(ACPI_TABLE_RSDT * rsdt, U32 signature)
173{
174 U32 index;
175 U32 num_tables;
176 ACPI_TABLE_HEADER **table_array = (ACPI_TABLE_HEADER **) rsdt->TableOffsetEntry;
177
178 // Compute number of table pointers included in RSDT
179 num_tables = get_num_tables(rsdt);
180
181 for (index = 0; index < num_tables; index++) {
182 if ((*(U32 *) (table_array[index]->Signature) == signature) &&
183 (GetChecksum(table_array[index], table_array[index]->Length) == 0)) {
184 return (table_array[index]);
185 }
186 }
187 return (0);
188}
189
190//-------------------------------------------------------------------------------
191//
192// Procedure: GetTablePtr64 - Find ACPI table in XSDT with input signature.
193//
194//-------------------------------------------------------------------------------
195#if 0
196static ACPI_TABLE_HEADER *GetTablePtr64(ACPI_TABLE_XSDT * xsdt, U32 signature)
197{
198 U32 index;
199 U32 num_tables;
200 ACPI_TABLE_HEADER *table = (ACPI_TABLE_HEADER *) xsdt->TableOffsetEntry;
201
202 // Compute number of table pointers included in XSDT
203 num_tables = get_num_tables64(xsdt);
204
205 for (index = 0; index < num_tables; index++) {
206 if (((U32) (table->Signature) == signature) &&
207 (GetChecksum(table, table->Length) == 0)) {
208 return (table);
209 }
210 // Move array pointer to next 64-bit pointer
211 table = (ACPI_TABLE_HEADER *) ((U32) table + sizeof(U64));
212 }
213 return (0);
214}
215#else
216static ACPI_TABLE_HEADER *GetTablePtr64(ACPI_TABLE_XSDT * xsdt, U32 signature)
217{
218 U32 index;
219 U32 num_tables;
220
221 // Compute number of table pointers included in XSDT
222 num_tables = get_num_tables64(xsdt);
223
224 for (index = 0; index < num_tables; index++) {
225U64 ptr = xsdt->TableOffsetEntry[index];
226
227 if ((*(U32 *) ((ACPI_TABLE_HEADER *) (unsigned long)ptr)->Signature == signature) &&
228 (GetChecksum(((ACPI_TABLE_HEADER *) (unsigned long)ptr), ((ACPI_TABLE_HEADER *) (unsigned long)ptr)->Length) == 0)) {
229 return (((ACPI_TABLE_HEADER *) (unsigned long)ptr));
230 }
231 }
232 return (0);
233}
234#endif
235
236
237//-------------------------------------------------------------------------------
238//
239// Procedure: GetChecksum - Performs byte checksum
240//
241//-------------------------------------------------------------------------------
242U8 GetChecksum(void *mem_addr, U32 mem_size)
243{
244 U8 *current = mem_addr;
245 U8 *end = current + mem_size;
246 U8 checksum = 0;
247
248 for (; current < end; current++)
249 checksum = checksum + *current;
250
251 return (checksum);
252}
253
254/*==========================================================================
255 * Function to map 32 bit physical address to 64 bit virtual address
256 */
257
258
259//-------------------------------------------------------------------------------
260//
261// Procedure: GetRsdtPointer - Scans given segment for RSDT pointer
262//
263// Description: Scans for root system description table pointer signature
264// ('RSD PTR ') , verifies checksum, and returns pointer to
265// RSDT table if found.
266//
267//-------------------------------------------------------------------------------
268static U32 GetRsdtPointer(void *mem_addr, U32 mem_size, ACPI_TABLES * acpi_tables)
269{
270 U8 *current = mem_addr;
271 U8 *end = current + mem_size;
272
273 // Quick sanity check for a valid start address
274 if (current == 0ul)
275 return (0ul);
276
277 for (; current < end; current += 16) {
278 if (*(volatile U64 *)current == NAMESEG64("RSD PTR ")) {
279 if (GetChecksum(current, ACPI_RSDP_REV0_SIZE) == 0) {
280 // RSD pointer structure checksum okay, lookup the RSDT pointer.
281 acpi_tables->RsdPointer = (ACPI_TABLE_RSDP *)current;
282 acpi_tables->RsdtPointer = (ACPI_TABLE_RSDT *) acpi_tables->RsdPointer->RsdtPhysicalAddress;
283 if ((acpi_tables->RsdPointer != (void*)0ul) && (acpi_tables->RsdtPointer != (void*)0ul))
284 return (1ul);
285 else
286 return (0ul);
287 }
288 }
289 }
290
291 return (0);
292}
293
294//-------------------------------------------------------------------------------
295//
296// Procedure: GetXsdtPointer
297//
298//-------------------------------------------------------------------------------
299static U32 GetXsdtPointer(ACPI_TABLES * acpi_tables)
300{
301 if ((GetChecksum(acpi_tables->RsdPointer, sizeof(ACPI_TABLE_RSDP)) == 0) &&
302 (acpi_tables->RsdPointer->Revision == 2) &&
303 (acpi_tables->RsdPointer->Length == sizeof(ACPI_TABLE_RSDP))) {
304 // RSD pointer structure checksum okay, lookup the XSDT pointer.
305 acpi_tables->XsdtPointer = (ACPI_TABLE_XSDT *) (U32) acpi_tables->RsdPointer->XsdtPhysicalAddress;
306 return (1ul);
307 }
308
309 return (0ul);
310}
311

Archive Download this file

Revision: 1525