GNU Linux-libre 4.19.286-gnu1
[releases.git] / drivers / acpi / acpica / rsaddr.c
1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /*******************************************************************************
3  *
4  * Module Name: rsaddr - Address resource descriptors (16/32/64)
5  *
6  ******************************************************************************/
7
8 #include <acpi/acpi.h>
9 #include "accommon.h"
10 #include "acresrc.h"
11
12 #define _COMPONENT          ACPI_RESOURCES
13 ACPI_MODULE_NAME("rsaddr")
14
15 /*******************************************************************************
16  *
17  * acpi_rs_convert_address16 - All WORD (16-bit) address resources
18  *
19  ******************************************************************************/
20 struct acpi_rsconvert_info acpi_rs_convert_address16[5] = {
21         {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS16,
22          ACPI_RS_SIZE(struct acpi_resource_address16),
23          ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address16)},
24
25         {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS16,
26          sizeof(struct aml_resource_address16),
27          0},
28
29         /* Resource Type, General Flags, and Type-Specific Flags */
30
31         {ACPI_RSC_ADDRESS, 0, 0, 0},
32
33         /*
34          * These fields are contiguous in both the source and destination:
35          * Address Granularity
36          * Address Range Minimum
37          * Address Range Maximum
38          * Address Translation Offset
39          * Address Length
40          */
41         {ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.address16.address.granularity),
42          AML_OFFSET(address16.granularity),
43          5},
44
45         /* Optional resource_source (Index and String) */
46
47         {ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address16.resource_source),
48          0,
49          sizeof(struct aml_resource_address16)}
50 };
51
52 /*******************************************************************************
53  *
54  * acpi_rs_convert_address32 - All DWORD (32-bit) address resources
55  *
56  ******************************************************************************/
57
58 struct acpi_rsconvert_info acpi_rs_convert_address32[5] = {
59         {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS32,
60          ACPI_RS_SIZE(struct acpi_resource_address32),
61          ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address32)},
62
63         {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS32,
64          sizeof(struct aml_resource_address32),
65          0},
66
67         /* Resource Type, General Flags, and Type-Specific Flags */
68
69         {ACPI_RSC_ADDRESS, 0, 0, 0},
70
71         /*
72          * These fields are contiguous in both the source and destination:
73          * Address Granularity
74          * Address Range Minimum
75          * Address Range Maximum
76          * Address Translation Offset
77          * Address Length
78          */
79         {ACPI_RSC_MOVE32, ACPI_RS_OFFSET(data.address32.address.granularity),
80          AML_OFFSET(address32.granularity),
81          5},
82
83         /* Optional resource_source (Index and String) */
84
85         {ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address32.resource_source),
86          0,
87          sizeof(struct aml_resource_address32)}
88 };
89
90 /*******************************************************************************
91  *
92  * acpi_rs_convert_address64 - All QWORD (64-bit) address resources
93  *
94  ******************************************************************************/
95
96 struct acpi_rsconvert_info acpi_rs_convert_address64[5] = {
97         {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS64,
98          ACPI_RS_SIZE(struct acpi_resource_address64),
99          ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address64)},
100
101         {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS64,
102          sizeof(struct aml_resource_address64),
103          0},
104
105         /* Resource Type, General Flags, and Type-Specific Flags */
106
107         {ACPI_RSC_ADDRESS, 0, 0, 0},
108
109         /*
110          * These fields are contiguous in both the source and destination:
111          * Address Granularity
112          * Address Range Minimum
113          * Address Range Maximum
114          * Address Translation Offset
115          * Address Length
116          */
117         {ACPI_RSC_MOVE64, ACPI_RS_OFFSET(data.address64.address.granularity),
118          AML_OFFSET(address64.granularity),
119          5},
120
121         /* Optional resource_source (Index and String) */
122
123         {ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address64.resource_source),
124          0,
125          sizeof(struct aml_resource_address64)}
126 };
127
128 /*******************************************************************************
129  *
130  * acpi_rs_convert_ext_address64 - All Extended (64-bit) address resources
131  *
132  ******************************************************************************/
133
134 struct acpi_rsconvert_info acpi_rs_convert_ext_address64[5] = {
135         {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64,
136          ACPI_RS_SIZE(struct acpi_resource_extended_address64),
137          ACPI_RSC_TABLE_SIZE(acpi_rs_convert_ext_address64)},
138
139         {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64,
140          sizeof(struct aml_resource_extended_address64),
141          0},
142
143         /* Resource Type, General Flags, and Type-Specific Flags */
144
145         {ACPI_RSC_ADDRESS, 0, 0, 0},
146
147         /* Revision ID */
148
149         {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.ext_address64.revision_ID),
150          AML_OFFSET(ext_address64.revision_ID),
151          1},
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          * Type-Specific Attribute
160          */
161         {ACPI_RSC_MOVE64,
162          ACPI_RS_OFFSET(data.ext_address64.address.granularity),
163          AML_OFFSET(ext_address64.granularity),
164          6}
165 };
166
167 /*******************************************************************************
168  *
169  * acpi_rs_convert_general_flags - Flags common to all address descriptors
170  *
171  ******************************************************************************/
172
173 static struct acpi_rsconvert_info acpi_rs_convert_general_flags[6] = {
174         {ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.flags),
175          ACPI_RSC_TABLE_SIZE(acpi_rs_convert_general_flags)},
176
177         /* Resource Type (Memory, Io, bus_number, etc.) */
178
179         {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.address.resource_type),
180          AML_OFFSET(address.resource_type),
181          1},
182
183         /* General flags - Consume, Decode, min_fixed, max_fixed */
184
185         {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.producer_consumer),
186          AML_OFFSET(address.flags),
187          0},
188
189         {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.decode),
190          AML_OFFSET(address.flags),
191          1},
192
193         {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.min_address_fixed),
194          AML_OFFSET(address.flags),
195          2},
196
197         {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.max_address_fixed),
198          AML_OFFSET(address.flags),
199          3}
200 };
201
202 /*******************************************************************************
203  *
204  * acpi_rs_convert_mem_flags - Flags common to Memory address descriptors
205  *
206  ******************************************************************************/
207
208 static struct acpi_rsconvert_info acpi_rs_convert_mem_flags[5] = {
209         {ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.specific_flags),
210          ACPI_RSC_TABLE_SIZE(acpi_rs_convert_mem_flags)},
211
212         /* Memory-specific flags */
213
214         {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.write_protect),
215          AML_OFFSET(address.specific_flags),
216          0},
217
218         {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.caching),
219          AML_OFFSET(address.specific_flags),
220          1},
221
222         {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.range_type),
223          AML_OFFSET(address.specific_flags),
224          3},
225
226         {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.translation),
227          AML_OFFSET(address.specific_flags),
228          5}
229 };
230
231 /*******************************************************************************
232  *
233  * acpi_rs_convert_io_flags - Flags common to I/O address descriptors
234  *
235  ******************************************************************************/
236
237 static struct acpi_rsconvert_info acpi_rs_convert_io_flags[4] = {
238         {ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.specific_flags),
239          ACPI_RSC_TABLE_SIZE(acpi_rs_convert_io_flags)},
240
241         /* I/O-specific flags */
242
243         {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.io.range_type),
244          AML_OFFSET(address.specific_flags),
245          0},
246
247         {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.io.translation),
248          AML_OFFSET(address.specific_flags),
249          4},
250
251         {ACPI_RSC_1BITFLAG,
252          ACPI_RS_OFFSET(data.address.info.io.translation_type),
253          AML_OFFSET(address.specific_flags),
254          5}
255 };
256
257 /*******************************************************************************
258  *
259  * FUNCTION:    acpi_rs_get_address_common
260  *
261  * PARAMETERS:  resource            - Pointer to the internal resource struct
262  *              aml                 - Pointer to the AML resource descriptor
263  *
264  * RETURN:      TRUE if the resource_type field is OK, FALSE otherwise
265  *
266  * DESCRIPTION: Convert common flag fields from a raw AML resource descriptor
267  *              to an internal resource descriptor
268  *
269  ******************************************************************************/
270
271 u8
272 acpi_rs_get_address_common(struct acpi_resource *resource,
273                            union aml_resource *aml)
274 {
275         ACPI_FUNCTION_ENTRY();
276
277         /* Validate the Resource Type */
278
279         if ((aml->address.resource_type > 2) &&
280             (aml->address.resource_type < 0xC0)) {
281                 return (FALSE);
282         }
283
284         /* Get the Resource Type and General Flags */
285
286         (void)acpi_rs_convert_aml_to_resource(resource, aml,
287                                               acpi_rs_convert_general_flags);
288
289         /* Get the Type-Specific Flags (Memory and I/O descriptors only) */
290
291         if (resource->data.address.resource_type == ACPI_MEMORY_RANGE) {
292                 (void)acpi_rs_convert_aml_to_resource(resource, aml,
293                                                       acpi_rs_convert_mem_flags);
294         } else if (resource->data.address.resource_type == ACPI_IO_RANGE) {
295                 (void)acpi_rs_convert_aml_to_resource(resource, aml,
296                                                       acpi_rs_convert_io_flags);
297         } else {
298                 /* Generic resource type, just grab the type_specific byte */
299
300                 resource->data.address.info.type_specific =
301                     aml->address.specific_flags;
302         }
303
304         return (TRUE);
305 }
306
307 /*******************************************************************************
308  *
309  * FUNCTION:    acpi_rs_set_address_common
310  *
311  * PARAMETERS:  aml                 - Pointer to the AML resource descriptor
312  *              resource            - Pointer to the internal resource struct
313  *
314  * RETURN:      None
315  *
316  * DESCRIPTION: Convert common flag fields from a resource descriptor to an
317  *              AML descriptor
318  *
319  ******************************************************************************/
320
321 void
322 acpi_rs_set_address_common(union aml_resource *aml,
323                            struct acpi_resource *resource)
324 {
325         ACPI_FUNCTION_ENTRY();
326
327         /* Set the Resource Type and General Flags */
328
329         (void)acpi_rs_convert_resource_to_aml(resource, aml,
330                                               acpi_rs_convert_general_flags);
331
332         /* Set the Type-Specific Flags (Memory and I/O descriptors only) */
333
334         if (resource->data.address.resource_type == ACPI_MEMORY_RANGE) {
335                 (void)acpi_rs_convert_resource_to_aml(resource, aml,
336                                                       acpi_rs_convert_mem_flags);
337         } else if (resource->data.address.resource_type == ACPI_IO_RANGE) {
338                 (void)acpi_rs_convert_resource_to_aml(resource, aml,
339                                                       acpi_rs_convert_io_flags);
340         } else {
341                 /* Generic resource type, just copy the type_specific byte */
342
343                 aml->address.specific_flags =
344                     resource->data.address.info.type_specific;
345         }
346 }