xref: /netbsd-src/sys/external/bsd/acpica/dist/compiler/dttable.c (revision 2c7d7e3ca2e4f0b675c6c58e614f6aede66c678e)
1 /******************************************************************************
2  *
3  * Module Name: dttable.c - handling for specific ACPI tables
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2023, 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 MERCHANTABILITY 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 /* Compile routines for the basic ACPI tables */
45 
46 #include "aslcompiler.h"
47 
48 #define _COMPONENT          DT_COMPILER
49         ACPI_MODULE_NAME    ("dttable")
50 
51 
52 /******************************************************************************
53  *
54  * FUNCTION:    DtCompileRsdp
55  *
56  * PARAMETERS:  PFieldList          - Current field list pointer
57  *
58  * RETURN:      Status
59  *
60  * DESCRIPTION: Compile RSDP.
61  *
62  *****************************************************************************/
63 
64 ACPI_STATUS
DtCompileRsdp(DT_FIELD ** PFieldList)65 DtCompileRsdp (
66     DT_FIELD                **PFieldList)
67 {
68     DT_SUBTABLE             *Subtable;
69     ACPI_TABLE_RSDP         *Rsdp;
70     ACPI_RSDP_EXTENSION     *RsdpExtension;
71     ACPI_STATUS             Status;
72 
73 
74     /* Compile the "common" RSDP (ACPI 1.0) */
75 
76     Status = DtCompileTable (PFieldList, AcpiDmTableInfoRsdp1,
77         &AslGbl_RootTable);
78     if (ACPI_FAILURE (Status))
79     {
80         return (Status);
81     }
82 
83     Rsdp = ACPI_CAST_PTR (ACPI_TABLE_RSDP, AslGbl_RootTable->Buffer);
84     DtSetTableChecksum (&Rsdp->Checksum);
85 
86     if (Rsdp->Revision > 0)
87     {
88         /* Compile the "extended" part of the RSDP as a subtable */
89 
90         Status = DtCompileTable (PFieldList, AcpiDmTableInfoRsdp2,
91             &Subtable);
92         if (ACPI_FAILURE (Status))
93         {
94             return (Status);
95         }
96 
97         DtInsertSubtable (AslGbl_RootTable, Subtable);
98 
99         /* Set length and extended checksum for entire RSDP */
100 
101         RsdpExtension = ACPI_CAST_PTR (ACPI_RSDP_EXTENSION, Subtable->Buffer);
102         RsdpExtension->Length = AslGbl_RootTable->Length + Subtable->Length;
103         DtSetTableChecksum (&RsdpExtension->ExtendedChecksum);
104     }
105 
106     return (AE_OK);
107 }
108 
109 
110 /******************************************************************************
111  *
112  * FUNCTION:    DtCompileFadt
113  *
114  * PARAMETERS:  List                - Current field list pointer
115  *
116  * RETURN:      Status
117  *
118  * DESCRIPTION: Compile FADT (signature FACP).
119  *
120  *****************************************************************************/
121 
122 #define ACPI_XDSDT_LOCATION_IN_LIST         11
123 
124 ACPI_STATUS
DtCompileFadt(void ** List)125 DtCompileFadt (
126     void                    **List)
127 {
128     ACPI_STATUS             Status;
129     DT_SUBTABLE             *Subtable;
130     DT_SUBTABLE             *ParentTable;
131     DT_FIELD                **PFieldList = (DT_FIELD **) List;
132     DT_FIELD                *DsdtFieldList;
133     ACPI_TABLE_FADT         *Table;
134     UINT8                   Revision;
135     UINT32                  DsdtAddress;
136     UINT64                  X_DsdtAddress;
137     UINT32                  i;
138 
139 
140     /* Get the table revision and 32-bit DSDT Address definition */
141 
142     DsdtFieldList = (*PFieldList)->Next;
143     Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt1,
144         &Subtable);
145     if (ACPI_FAILURE (Status))
146     {
147         return (Status);
148     }
149 
150     ParentTable = DtPeekSubtable ();
151     DtInsertSubtable (ParentTable, Subtable);
152 
153     Table = ACPI_CAST_PTR (ACPI_TABLE_FADT, ParentTable->Buffer);
154     Revision = Table->Header.Revision;
155     DsdtAddress = Table->Dsdt;
156 
157     /* FADT version 1 has only 32-bit addresses - error if DSDT address is NULL */
158 
159     if ((Revision == 1) && (!DsdtAddress))
160     {
161         DtError (ASL_ERROR, ASL_MSG_ZERO_VALUE, DsdtFieldList, NULL);
162     }
163 
164     if (Revision == 2)
165     {
166         Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt2,
167             &Subtable);
168         if (ACPI_FAILURE (Status))
169         {
170             return (Status);
171         }
172 
173         DtInsertSubtable (ParentTable, Subtable);
174     }
175 
176     else if (Revision > 2)
177     {
178         /*
179          * Rev 3 and greater have 64-bit addresses (as well as 32-bit).
180          * Get the 64-bit DSDT (X_DSDT) Address definition. Note: This
181          * appears at field list offset 11 within AcpiDmTableInfoFadt3.
182          */
183         DsdtFieldList = *PFieldList;
184         for (i = 0; i < ACPI_XDSDT_LOCATION_IN_LIST; i++)
185         {
186             DsdtFieldList = DsdtFieldList->Next;
187             if (!DsdtFieldList)
188             {
189                 return (ASL_MSG_BAD_PARSE_TREE);
190             }
191         }
192 
193         Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt3,
194             &Subtable);
195         if (ACPI_FAILURE (Status))
196         {
197             return (Status);
198         }
199 
200         DtInsertSubtable (ParentTable, Subtable);
201 
202         Table = ACPI_CAST_PTR (ACPI_TABLE_FADT, ParentTable->Buffer);
203         X_DsdtAddress = Table->XDsdt;
204 
205         /*
206          * Error if both the 32-bit DSDT address and the
207          * 64-bit X_DSDT address are zero.
208          */
209         if ((!X_DsdtAddress) && (!DsdtAddress))
210         {
211             DtError (ASL_ERROR, ASL_MSG_TWO_ZERO_VALUES, DsdtFieldList, NULL);
212         }
213 
214         /* Fields specific to FADT Revision 5 (appended to previous) */
215 
216         if (Revision >= 5)
217         {
218             Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt5,
219                 &Subtable);
220             if (ACPI_FAILURE (Status))
221             {
222                 return (Status);
223             }
224 
225             DtInsertSubtable (ParentTable, Subtable);
226         }
227 
228         /* Fields specific to FADT Revision 6 (appended to previous) */
229 
230         if (Revision >= 6)
231         {
232             Status = DtCompileTable (PFieldList, AcpiDmTableInfoFadt6,
233                 &Subtable);
234             if (ACPI_FAILURE (Status))
235             {
236                 return (Status);
237             }
238 
239             DtInsertSubtable (ParentTable, Subtable);
240         }
241     }
242 
243     return (AE_OK);
244 }
245 
246 
247 /******************************************************************************
248  *
249  * FUNCTION:    DtCompileFacs
250  *
251  * PARAMETERS:  PFieldList          - Current field list pointer
252  *
253  * RETURN:      Status
254  *
255  * DESCRIPTION: Compile FACS.
256  *
257  *****************************************************************************/
258 
259 ACPI_STATUS
DtCompileFacs(DT_FIELD ** PFieldList)260 DtCompileFacs (
261     DT_FIELD                **PFieldList)
262 {
263     DT_SUBTABLE             *Subtable;
264     UINT8                   *ReservedBuffer;
265     ACPI_STATUS             Status;
266     UINT32                  ReservedSize;
267 
268 
269     Status = DtCompileTable (PFieldList, AcpiDmTableInfoFacs,
270         &AslGbl_RootTable);
271     if (ACPI_FAILURE (Status))
272     {
273         return (Status);
274     }
275 
276     /* Large FACS reserved area at the end of the table */
277 
278     ReservedSize = (UINT32) sizeof (((ACPI_TABLE_FACS *) NULL)->Reserved1);
279     ReservedBuffer = UtLocalCalloc (ReservedSize);
280 
281     DtCreateSubtable (ReservedBuffer, ReservedSize, &Subtable);
282 
283     ACPI_FREE (ReservedBuffer);
284     DtInsertSubtable (AslGbl_RootTable, Subtable);
285     return (AE_OK);
286 }
287