8ad3c5c3dc1523d2b7e125d3a89f5ff8d935bfc5
[dragonfly.git] / sys / contrib / dev / acpica / source / tools / acpinames / antables.c
1 /******************************************************************************
2  *
3  * Module Name: antables - ACPI table setup/install for AcpiNames utility
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2014, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43
44 #include "acpinames.h"
45
46 #define _COMPONENT          ACPI_TOOLS
47         ACPI_MODULE_NAME    ("antables")
48
49 /* Local prototypes */
50
51 ACPI_PHYSICAL_ADDRESS
52 AeLocalGetRootPointer (
53     void);
54
55 /* Non-AML tables that are constructed locally and installed */
56
57 static ACPI_TABLE_RSDP          LocalRSDP;
58 static ACPI_TABLE_FACS          LocalFACS;
59
60 /*
61  * We need a local FADT so that the hardware subcomponent will function,
62  * even though the underlying OSD HW access functions don't do anything.
63  */
64 static ACPI_TABLE_FADT          LocalFADT;
65
66 /*
67  * Use XSDT so that both 32- and 64-bit versions of this utility will
68  * function automatically.
69  */
70 static ACPI_TABLE_XSDT          *LocalXSDT;
71
72 #define BASE_XSDT_TABLES        1
73 #define BASE_XSDT_SIZE          (sizeof (ACPI_TABLE_XSDT) + \
74                                     ((BASE_XSDT_TABLES -1) * sizeof (UINT64)))
75
76 ACPI_TABLE_DESC                 Tables[ACPI_MAX_INIT_TABLES];
77
78
79 /******************************************************************************
80  *
81  * FUNCTION:    AeBuildLocalTables
82  *
83  * PARAMETERS:  TableCount      - Number of tables on the command line
84  *              TableList       - List of actual tables from files
85  *
86  * RETURN:      Status
87  *
88  * DESCRIPTION: Build a complete ACPI table chain, with a local RSDP, XSDT,
89  *              FADT, FACS, and the input DSDT/SSDT.
90  *
91  *****************************************************************************/
92
93 ACPI_STATUS
94 AeBuildLocalTables (
95     UINT32                  TableCount,
96     AE_TABLE_DESC           *TableList)
97 {
98     ACPI_PHYSICAL_ADDRESS   DsdtAddress = 0;
99     UINT32                  XsdtSize;
100     AE_TABLE_DESC           *NextTable;
101     UINT32                  NextIndex;
102     ACPI_TABLE_FADT         *ExternalFadt = NULL;
103
104
105     /*
106      * Update the table count. For DSDT, it is not put into the XSDT. For
107      * FADT, this is already accounted for since we usually install a
108      * local FADT.
109      */
110     NextTable = TableList;
111     while (NextTable)
112     {
113         if (ACPI_COMPARE_NAME (NextTable->Table->Signature, ACPI_SIG_DSDT) ||
114             ACPI_COMPARE_NAME (NextTable->Table->Signature, ACPI_SIG_FADT))
115         {
116             TableCount--;
117         }
118         NextTable = NextTable->Next;
119     }
120
121     XsdtSize = BASE_XSDT_SIZE + (TableCount * sizeof (UINT64));
122
123     /* Build an XSDT */
124
125     LocalXSDT = AcpiOsAllocate (XsdtSize);
126     if (!LocalXSDT)
127     {
128         return (AE_NO_MEMORY);
129     }
130
131     ACPI_MEMSET (LocalXSDT, 0, XsdtSize);
132     ACPI_MOVE_NAME (LocalXSDT->Header.Signature, ACPI_SIG_XSDT);
133     LocalXSDT->Header.Length = XsdtSize;
134     LocalXSDT->Header.Revision = 1;
135
136     LocalXSDT->TableOffsetEntry[0] = ACPI_PTR_TO_PHYSADDR (&LocalFADT);
137
138     /*
139      * Install the user tables. The DSDT must be installed in the FADT.
140      * All other tables are installed directly into the XSDT.
141      */
142     NextIndex = BASE_XSDT_TABLES;
143     NextTable = TableList;
144     while (NextTable)
145     {
146         /*
147          * Incoming DSDT or FADT are special cases. All other tables are
148          * just immediately installed into the XSDT.
149          */
150         if (ACPI_COMPARE_NAME (NextTable->Table->Signature, ACPI_SIG_DSDT))
151         {
152             if (DsdtAddress)
153             {
154                 printf ("Already found a DSDT, only one allowed\n");
155                 return (AE_ALREADY_EXISTS);
156             }
157
158             /* The incoming user table is a DSDT */
159
160             DsdtAddress = ACPI_PTR_TO_PHYSADDR (NextTable->Table);
161         }
162         else if (ACPI_COMPARE_NAME (NextTable->Table->Signature, ACPI_SIG_FADT))
163         {
164             ExternalFadt = ACPI_CAST_PTR (ACPI_TABLE_FADT, NextTable->Table);
165             LocalXSDT->TableOffsetEntry[2] = ACPI_PTR_TO_PHYSADDR (NextTable->Table);
166         }
167         else
168         {
169             /* Install the table in the XSDT */
170
171             LocalXSDT->TableOffsetEntry[NextIndex] = ACPI_PTR_TO_PHYSADDR (NextTable->Table);
172             NextIndex++;
173         }
174
175         NextTable = NextTable->Next;
176     }
177
178     /* Build an RSDP */
179
180     ACPI_MEMSET (&LocalRSDP, 0, sizeof (ACPI_TABLE_RSDP));
181     ACPI_MAKE_RSDP_SIG (LocalRSDP.Signature);
182     ACPI_MEMCPY (LocalRSDP.OemId, "I_TEST", 6);
183     LocalRSDP.Revision = 2;
184     LocalRSDP.XsdtPhysicalAddress = ACPI_PTR_TO_PHYSADDR (LocalXSDT);
185     LocalRSDP.Length = sizeof (ACPI_TABLE_XSDT);
186
187     /* Set checksums for both XSDT and RSDP */
188
189     LocalXSDT->Header.Checksum = (UINT8) -AcpiTbChecksum (
190         (void *) LocalXSDT, LocalXSDT->Header.Length);
191     LocalRSDP.Checksum = (UINT8) -AcpiTbChecksum (
192         (void *) &LocalRSDP, ACPI_RSDP_CHECKSUM_LENGTH);
193
194     if (!DsdtAddress)
195     {
196         return (AE_SUPPORT);
197     }
198
199     if (ExternalFadt)
200     {
201         /*
202          * Use the external FADT, but we must update the DSDT/FACS addresses
203          * as well as the checksum
204          */
205         ExternalFadt->Dsdt = DsdtAddress;
206         ExternalFadt->Facs = ACPI_PTR_TO_PHYSADDR (&LocalFACS);
207
208         if (ExternalFadt->Header.Length > ACPI_PTR_DIFF (&ExternalFadt->XDsdt, ExternalFadt))
209         {
210             ExternalFadt->XDsdt = DsdtAddress;
211             ExternalFadt->XFacs = ACPI_PTR_TO_PHYSADDR (&LocalFACS);
212         }
213         /* Complete the FADT with the checksum */
214
215         ExternalFadt->Header.Checksum = 0;
216         ExternalFadt->Header.Checksum = (UINT8) -AcpiTbChecksum (
217             (void *) ExternalFadt, ExternalFadt->Header.Length);
218     }
219     else
220     {
221         /*
222          * Build a local FADT so we can test the hardware/event init
223          */
224         ACPI_MEMSET (&LocalFADT, 0, sizeof (ACPI_TABLE_FADT));
225         ACPI_MOVE_NAME (LocalFADT.Header.Signature, ACPI_SIG_FADT);
226
227         /* Setup FADT header and DSDT/FACS addresses */
228
229         LocalFADT.Dsdt = 0;
230         LocalFADT.Facs = 0;
231
232         LocalFADT.XDsdt = DsdtAddress;
233         LocalFADT.XFacs = ACPI_PTR_TO_PHYSADDR (&LocalFACS);
234
235         LocalFADT.Header.Revision = 3;
236         LocalFADT.Header.Length = sizeof (ACPI_TABLE_FADT);
237
238         /* Miscellaneous FADT fields */
239
240         LocalFADT.Gpe0BlockLength = 16;
241         LocalFADT.Gpe0Block = 0x00001234;
242
243         LocalFADT.Gpe1BlockLength = 6;
244         LocalFADT.Gpe1Block = 0x00005678;
245         LocalFADT.Gpe1Base = 96;
246
247         LocalFADT.Pm1EventLength = 4;
248         LocalFADT.Pm1aEventBlock = 0x00001aaa;
249         LocalFADT.Pm1bEventBlock = 0x00001bbb;
250
251         LocalFADT.Pm1ControlLength = 2;
252         LocalFADT.Pm1aControlBlock = 0xB0;
253
254         LocalFADT.PmTimerLength = 4;
255         LocalFADT.PmTimerBlock = 0xA0;
256
257         LocalFADT.Pm2ControlBlock = 0xC0;
258         LocalFADT.Pm2ControlLength = 1;
259
260         /* Setup one example X-64 field */
261
262         LocalFADT.XPm1bEventBlock.SpaceId = ACPI_ADR_SPACE_SYSTEM_IO;
263         LocalFADT.XPm1bEventBlock.Address = LocalFADT.Pm1bEventBlock;
264         LocalFADT.XPm1bEventBlock.BitWidth = (UINT8) ACPI_MUL_8 (LocalFADT.Pm1EventLength);
265
266         /* Complete the FADT with the checksum */
267
268         LocalFADT.Header.Checksum = 0;
269         LocalFADT.Header.Checksum = (UINT8) -AcpiTbChecksum (
270             (void *) &LocalFADT, LocalFADT.Header.Length);
271     }
272
273     /* Build a FACS */
274
275     ACPI_MEMSET (&LocalFACS, 0, sizeof (ACPI_TABLE_FACS));
276     ACPI_MOVE_NAME (LocalFACS.Signature, ACPI_SIG_FACS);
277
278     LocalFACS.Length = sizeof (ACPI_TABLE_FACS);
279     LocalFACS.GlobalLock = 0x11AA0011;
280
281     return (AE_OK);
282 }
283
284
285 /******************************************************************************
286  *
287  * FUNCTION:    AeLocalGetRootPointer
288  *
289  * PARAMETERS:  None
290  *
291  * RETURN:      Address of the RSDP
292  *
293  * DESCRIPTION: Return a local RSDP, used to dynamically load tables via the
294  *              standard ACPI mechanism.
295  *
296  *****************************************************************************/
297
298 ACPI_PHYSICAL_ADDRESS
299 AeLocalGetRootPointer (
300     void)
301 {
302
303     return ((ACPI_PHYSICAL_ADDRESS) &LocalRSDP);
304 }