1/*******************************************************************************
2 *
3 * Module Name: rsaddr - Address resource descriptors (16/32/64)
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#include "acpi.h"
45#include "accommon.h"
46#include "acresrc.h"
47
48#define _COMPONENT          ACPI_RESOURCES
49        ACPI_MODULE_NAME    ("rsaddr")
50
51
52/*******************************************************************************
53 *
54 * AcpiRsConvertAddress16 - All WORD (16-bit) address resources
55 *
56 ******************************************************************************/
57
58ACPI_RSCONVERT_INFO     AcpiRsConvertAddress16[5] =
59{
60    {ACPI_RSC_INITGET,  ACPI_RESOURCE_TYPE_ADDRESS16,
61                        ACPI_RS_SIZE (ACPI_RESOURCE_ADDRESS16),
62                        ACPI_RSC_TABLE_SIZE (AcpiRsConvertAddress16)},
63
64    {ACPI_RSC_INITSET,  ACPI_RESOURCE_NAME_ADDRESS16,
65                        sizeof (AML_RESOURCE_ADDRESS16),
66                        0},
67
68    /* Resource Type, General Flags, and Type-Specific Flags */
69
70    {ACPI_RSC_ADDRESS,  0, 0, 0},
71
72    /*
73     * These fields are contiguous in both the source and destination:
74     * Address Granularity
75     * Address Range Minimum
76     * Address Range Maximum
77     * Address Translation Offset
78     * Address Length
79     */
80    {ACPI_RSC_MOVE16,   ACPI_RS_OFFSET (Data.Address16.Address.Granularity),
81                        AML_OFFSET (Address16.Granularity),
82                        5},
83
84    /* Optional ResourceSource (Index and String) */
85
86    {ACPI_RSC_SOURCE,   ACPI_RS_OFFSET (Data.Address16.ResourceSource),
87                        0,
88                        sizeof (AML_RESOURCE_ADDRESS16)}
89};
90
91
92/*******************************************************************************
93 *
94 * AcpiRsConvertAddress32 - All DWORD (32-bit) address resources
95 *
96 ******************************************************************************/
97
98ACPI_RSCONVERT_INFO     AcpiRsConvertAddress32[5] =
99{
100    {ACPI_RSC_INITGET,  ACPI_RESOURCE_TYPE_ADDRESS32,
101                        ACPI_RS_SIZE (ACPI_RESOURCE_ADDRESS32),
102                        ACPI_RSC_TABLE_SIZE (AcpiRsConvertAddress32)},
103
104    {ACPI_RSC_INITSET,  ACPI_RESOURCE_NAME_ADDRESS32,
105                        sizeof (AML_RESOURCE_ADDRESS32),
106                        0},
107
108    /* Resource Type, General Flags, and Type-Specific Flags */
109
110    {ACPI_RSC_ADDRESS,  0, 0, 0},
111
112    /*
113     * These fields are contiguous in both the source and destination:
114     * Address Granularity
115     * Address Range Minimum
116     * Address Range Maximum
117     * Address Translation Offset
118     * Address Length
119     */
120    {ACPI_RSC_MOVE32,   ACPI_RS_OFFSET (Data.Address32.Address.Granularity),
121                        AML_OFFSET (Address32.Granularity),
122                        5},
123
124    /* Optional ResourceSource (Index and String) */
125
126    {ACPI_RSC_SOURCE,   ACPI_RS_OFFSET (Data.Address32.ResourceSource),
127                        0,
128                        sizeof (AML_RESOURCE_ADDRESS32)}
129};
130
131
132/*******************************************************************************
133 *
134 * AcpiRsConvertAddress64 - All QWORD (64-bit) address resources
135 *
136 ******************************************************************************/
137
138ACPI_RSCONVERT_INFO     AcpiRsConvertAddress64[5] =
139{
140    {ACPI_RSC_INITGET,  ACPI_RESOURCE_TYPE_ADDRESS64,
141                        ACPI_RS_SIZE (ACPI_RESOURCE_ADDRESS64),
142                        ACPI_RSC_TABLE_SIZE (AcpiRsConvertAddress64)},
143
144    {ACPI_RSC_INITSET,  ACPI_RESOURCE_NAME_ADDRESS64,
145                        sizeof (AML_RESOURCE_ADDRESS64),
146                        0},
147
148    /* Resource Type, General Flags, and Type-Specific Flags */
149
150    {ACPI_RSC_ADDRESS,  0, 0, 0},
151
152    /*
153     * These fields are contiguous in both the source and destination:
154     * Address Granularity
155     * Address Range Minimum
156     * Address Range Maximum
157     * Address Translation Offset
158     * Address Length
159     */
160    {ACPI_RSC_MOVE64,   ACPI_RS_OFFSET (Data.Address64.Address.Granularity),
161                        AML_OFFSET (Address64.Granularity),
162                        5},
163
164    /* Optional ResourceSource (Index and String) */
165
166    {ACPI_RSC_SOURCE,   ACPI_RS_OFFSET (Data.Address64.ResourceSource),
167                        0,
168                        sizeof (AML_RESOURCE_ADDRESS64)}
169};
170
171
172/*******************************************************************************
173 *
174 * AcpiRsConvertExtAddress64 - All Extended (64-bit) address resources
175 *
176 ******************************************************************************/
177
178ACPI_RSCONVERT_INFO     AcpiRsConvertExtAddress64[5] =
179{
180    {ACPI_RSC_INITGET,  ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64,
181                        ACPI_RS_SIZE (ACPI_RESOURCE_EXTENDED_ADDRESS64),
182                        ACPI_RSC_TABLE_SIZE (AcpiRsConvertExtAddress64)},
183
184    {ACPI_RSC_INITSET,  ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64,
185                        sizeof (AML_RESOURCE_EXTENDED_ADDRESS64),
186                        0},
187
188    /* Resource Type, General Flags, and Type-Specific Flags */
189
190    {ACPI_RSC_ADDRESS,  0, 0, 0},
191
192    /* Revision ID */
193
194    {ACPI_RSC_MOVE8,    ACPI_RS_OFFSET (Data.ExtAddress64.RevisionID),
195                        AML_OFFSET (ExtAddress64.RevisionID),
196                        1},
197    /*
198     * These fields are contiguous in both the source and destination:
199     * Address Granularity
200     * Address Range Minimum
201     * Address Range Maximum
202     * Address Translation Offset
203     * Address Length
204     * Type-Specific Attribute
205     */
206    {ACPI_RSC_MOVE64,   ACPI_RS_OFFSET (Data.ExtAddress64.Address.Granularity),
207                        AML_OFFSET (ExtAddress64.Granularity),
208                        6}
209};
210
211
212/*******************************************************************************
213 *
214 * AcpiRsConvertGeneralFlags - Flags common to all address descriptors
215 *
216 ******************************************************************************/
217
218static ACPI_RSCONVERT_INFO  AcpiRsConvertGeneralFlags[6] =
219{
220    {ACPI_RSC_FLAGINIT, 0, AML_OFFSET (Address.Flags),
221                        ACPI_RSC_TABLE_SIZE (AcpiRsConvertGeneralFlags)},
222
223    /* Resource Type (Memory, Io, BusNumber, etc.) */
224
225    {ACPI_RSC_MOVE8,    ACPI_RS_OFFSET (Data.Address.ResourceType),
226                        AML_OFFSET (Address.ResourceType),
227                        1},
228
229    /* General Flags - Consume, Decode, MinFixed, MaxFixed */
230
231    {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.Address.ProducerConsumer),
232                        AML_OFFSET (Address.Flags),
233                        0},
234
235    {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.Address.Decode),
236                        AML_OFFSET (Address.Flags),
237                        1},
238
239    {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.Address.MinAddressFixed),
240                        AML_OFFSET (Address.Flags),
241                        2},
242
243    {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.Address.MaxAddressFixed),
244                        AML_OFFSET (Address.Flags),
245                        3}
246};
247
248
249/*******************************************************************************
250 *
251 * AcpiRsConvertMemFlags - Flags common to Memory address descriptors
252 *
253 ******************************************************************************/
254
255static ACPI_RSCONVERT_INFO  AcpiRsConvertMemFlags[5] =
256{
257    {ACPI_RSC_FLAGINIT, 0, AML_OFFSET (Address.SpecificFlags),
258                        ACPI_RSC_TABLE_SIZE (AcpiRsConvertMemFlags)},
259
260    /* Memory-specific flags */
261
262    {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.Address.Info.Mem.WriteProtect),
263                        AML_OFFSET (Address.SpecificFlags),
264                        0},
265
266    {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET (Data.Address.Info.Mem.Caching),
267                        AML_OFFSET (Address.SpecificFlags),
268                        1},
269
270    {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET (Data.Address.Info.Mem.RangeType),
271                        AML_OFFSET (Address.SpecificFlags),
272                        3},
273
274    {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.Address.Info.Mem.Translation),
275                        AML_OFFSET (Address.SpecificFlags),
276                        5}
277};
278
279
280/*******************************************************************************
281 *
282 * AcpiRsConvertIoFlags - Flags common to I/O address descriptors
283 *
284 ******************************************************************************/
285
286static ACPI_RSCONVERT_INFO  AcpiRsConvertIoFlags[4] =
287{
288    {ACPI_RSC_FLAGINIT, 0, AML_OFFSET (Address.SpecificFlags),
289                        ACPI_RSC_TABLE_SIZE (AcpiRsConvertIoFlags)},
290
291    /* I/O-specific flags */
292
293    {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET (Data.Address.Info.Io.RangeType),
294                        AML_OFFSET (Address.SpecificFlags),
295                        0},
296
297    {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.Address.Info.Io.Translation),
298                        AML_OFFSET (Address.SpecificFlags),
299                        4},
300
301    {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET (Data.Address.Info.Io.TranslationType),
302                        AML_OFFSET (Address.SpecificFlags),
303                        5}
304};
305
306
307/*******************************************************************************
308 *
309 * FUNCTION:    AcpiRsGetAddressCommon
310 *
311 * PARAMETERS:  Resource            - Pointer to the internal resource struct
312 *              Aml                 - Pointer to the AML resource descriptor
313 *
314 * RETURN:      TRUE if the ResourceType field is OK, FALSE otherwise
315 *
316 * DESCRIPTION: Convert common flag fields from a raw AML resource descriptor
317 *              to an internal resource descriptor
318 *
319 ******************************************************************************/
320
321BOOLEAN
322AcpiRsGetAddressCommon (
323    ACPI_RESOURCE           *Resource,
324    AML_RESOURCE            *Aml)
325{
326
327    /* Avoid undefined behavior: member access within misaligned address */
328
329    AML_RESOURCE_ADDRESS Address;
330    memcpy(&Address, Aml, sizeof(Address));
331    ACPI_FUNCTION_ENTRY();
332
333    /* Validate the Resource Type */
334
335    if ((Address.ResourceType > 2) &&
336        (Address.ResourceType < 0xC0))
337    {
338        return (FALSE);
339    }
340
341    /* Get the Resource Type and General Flags */
342
343    (void) AcpiRsConvertAmlToResource (
344        Resource, Aml, AcpiRsConvertGeneralFlags);
345
346    /* Get the Type-Specific Flags (Memory and I/O descriptors only) */
347
348    if (Resource->Data.Address.ResourceType == ACPI_MEMORY_RANGE)
349    {
350        (void) AcpiRsConvertAmlToResource (
351            Resource, Aml, AcpiRsConvertMemFlags);
352    }
353    else if (Resource->Data.Address.ResourceType == ACPI_IO_RANGE)
354    {
355        (void) AcpiRsConvertAmlToResource (
356            Resource, Aml, AcpiRsConvertIoFlags);
357    }
358    else
359    {
360        /* Generic resource type, just grab the TypeSpecific byte */
361
362        Resource->Data.Address.Info.TypeSpecific =
363            Address.SpecificFlags;
364    }
365
366    return (TRUE);
367}
368
369
370/*******************************************************************************
371 *
372 * FUNCTION:    AcpiRsSetAddressCommon
373 *
374 * PARAMETERS:  Aml                 - Pointer to the AML resource descriptor
375 *              Resource            - Pointer to the internal resource struct
376 *
377 * RETURN:      None
378 *
379 * DESCRIPTION: Convert common flag fields from a resource descriptor to an
380 *              AML descriptor
381 *
382 ******************************************************************************/
383
384void
385AcpiRsSetAddressCommon (
386    AML_RESOURCE            *Aml,
387    ACPI_RESOURCE           *Resource)
388{
389    ACPI_FUNCTION_ENTRY ();
390
391
392    /* Set the Resource Type and General Flags */
393
394    (void) AcpiRsConvertResourceToAml (
395        Resource, Aml, AcpiRsConvertGeneralFlags);
396
397    /* Set the Type-Specific Flags (Memory and I/O descriptors only) */
398
399    if (Resource->Data.Address.ResourceType == ACPI_MEMORY_RANGE)
400    {
401        (void) AcpiRsConvertResourceToAml (
402            Resource, Aml, AcpiRsConvertMemFlags);
403    }
404    else if (Resource->Data.Address.ResourceType == ACPI_IO_RANGE)
405    {
406        (void) AcpiRsConvertResourceToAml (
407            Resource, Aml, AcpiRsConvertIoFlags);
408    }
409    else
410    {
411        /* Generic resource type, just copy the TypeSpecific byte */
412
413        Aml->Address.SpecificFlags =
414            Resource->Data.Address.Info.TypeSpecific;
415    }
416}
417