diff options
Diffstat (limited to 'drivers/acpi/resources/rsaddr.c')
-rw-r--r-- | drivers/acpi/resources/rsaddr.c | 1164 |
1 files changed, 213 insertions, 951 deletions
diff --git a/drivers/acpi/resources/rsaddr.c b/drivers/acpi/resources/rsaddr.c index 23b54baa0cb2..8fa3213ce000 100644 --- a/drivers/acpi/resources/rsaddr.c +++ b/drivers/acpi/resources/rsaddr.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2005, R. Byron Moore | 8 | * Copyright (C) 2000 - 2006, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -47,1072 +47,334 @@ | |||
47 | #define _COMPONENT ACPI_RESOURCES | 47 | #define _COMPONENT ACPI_RESOURCES |
48 | ACPI_MODULE_NAME("rsaddr") | 48 | ACPI_MODULE_NAME("rsaddr") |
49 | 49 | ||
50 | /* Local prototypes */ | ||
51 | static void | ||
52 | acpi_rs_decode_general_flags(union acpi_resource_data *resource, u8 flags); | ||
53 | |||
54 | static u8 acpi_rs_encode_general_flags(union acpi_resource_data *resource); | ||
55 | |||
56 | static void | ||
57 | acpi_rs_decode_specific_flags(union acpi_resource_data *resource, u8 flags); | ||
58 | |||
59 | static u8 acpi_rs_encode_specific_flags(union acpi_resource_data *resource); | ||
60 | |||
61 | /******************************************************************************* | 50 | /******************************************************************************* |
62 | * | 51 | * |
63 | * FUNCTION: acpi_rs_decode_general_flags | 52 | * acpi_rs_convert_address16 - All WORD (16-bit) address resources |
64 | * | ||
65 | * PARAMETERS: Resource - Address resource data struct | ||
66 | * Flags - Actual flag byte | ||
67 | * | ||
68 | * RETURN: Decoded flag bits in resource struct | ||
69 | * | ||
70 | * DESCRIPTION: Decode a general flag byte to an address resource struct | ||
71 | * | 53 | * |
72 | ******************************************************************************/ | 54 | ******************************************************************************/ |
55 | struct acpi_rsconvert_info acpi_rs_convert_address16[5] = { | ||
56 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS16, | ||
57 | ACPI_RS_SIZE(struct acpi_resource_address16), | ||
58 | ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address16)}, | ||
73 | 59 | ||
74 | static void | 60 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS16, |
75 | acpi_rs_decode_general_flags(union acpi_resource_data *resource, u8 flags) | 61 | sizeof(struct aml_resource_address16), |
76 | { | 62 | 0}, |
77 | ACPI_FUNCTION_ENTRY(); | ||
78 | |||
79 | /* Producer / Consumer - flag bit[0] */ | ||
80 | |||
81 | resource->address.producer_consumer = (u32) (flags & 0x01); | ||
82 | 63 | ||
83 | /* Decode (_DEC) - flag bit[1] */ | 64 | /* Resource Type, General Flags, and Type-Specific Flags */ |
84 | 65 | ||
85 | resource->address.decode = (u32) ((flags >> 1) & 0x01); | 66 | {ACPI_RSC_ADDRESS, 0, 0, 0}, |
86 | 67 | ||
87 | /* Min Address Fixed (_MIF) - flag bit[2] */ | 68 | /* |
69 | * These fields are contiguous in both the source and destination: | ||
70 | * Address Granularity | ||
71 | * Address Range Minimum | ||
72 | * Address Range Maximum | ||
73 | * Address Translation Offset | ||
74 | * Address Length | ||
75 | */ | ||
76 | {ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.address16.granularity), | ||
77 | AML_OFFSET(address16.granularity), | ||
78 | 5}, | ||
88 | 79 | ||
89 | resource->address.min_address_fixed = (u32) ((flags >> 2) & 0x01); | 80 | /* Optional resource_source (Index and String) */ |
90 | 81 | ||
91 | /* Max Address Fixed (_MAF) - flag bit[3] */ | 82 | {ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address16.resource_source), |
92 | 83 | 0, | |
93 | resource->address.max_address_fixed = (u32) ((flags >> 3) & 0x01); | 84 | sizeof(struct aml_resource_address16)} |
94 | } | 85 | }; |
95 | 86 | ||
96 | /******************************************************************************* | 87 | /******************************************************************************* |
97 | * | 88 | * |
98 | * FUNCTION: acpi_rs_encode_general_flags | 89 | * acpi_rs_convert_address32 - All DWORD (32-bit) address resources |
99 | * | ||
100 | * PARAMETERS: Resource - Address resource data struct | ||
101 | * | ||
102 | * RETURN: Encoded general flag byte | ||
103 | * | ||
104 | * DESCRIPTION: Construct a general flag byte from an address resource struct | ||
105 | * | 90 | * |
106 | ******************************************************************************/ | 91 | ******************************************************************************/ |
107 | 92 | ||
108 | static u8 acpi_rs_encode_general_flags(union acpi_resource_data *resource) | 93 | struct acpi_rsconvert_info acpi_rs_convert_address32[5] = { |
109 | { | 94 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS32, |
110 | u8 flags; | 95 | ACPI_RS_SIZE(struct acpi_resource_address32), |
111 | 96 | ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address32)}, | |
112 | ACPI_FUNCTION_ENTRY(); | ||
113 | |||
114 | /* Producer / Consumer - flag bit[0] */ | ||
115 | |||
116 | flags = (u8) (resource->address.producer_consumer & 0x01); | ||
117 | |||
118 | /* Decode (_DEC) - flag bit[1] */ | ||
119 | |||
120 | flags |= (u8) ((resource->address.decode & 0x01) << 1); | ||
121 | |||
122 | /* Min Address Fixed (_MIF) - flag bit[2] */ | ||
123 | |||
124 | flags |= (u8) ((resource->address.min_address_fixed & 0x01) << 2); | ||
125 | 97 | ||
126 | /* Max Address Fixed (_MAF) - flag bit[3] */ | 98 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS32, |
99 | sizeof(struct aml_resource_address32), | ||
100 | 0}, | ||
127 | 101 | ||
128 | flags |= (u8) ((resource->address.max_address_fixed & 0x01) << 3); | 102 | /* Resource Type, General Flags, and Type-Specific Flags */ |
129 | 103 | ||
130 | return (flags); | 104 | {ACPI_RSC_ADDRESS, 0, 0, 0}, |
131 | } | ||
132 | |||
133 | /******************************************************************************* | ||
134 | * | ||
135 | * FUNCTION: acpi_rs_decode_specific_flags | ||
136 | * | ||
137 | * PARAMETERS: Resource - Address resource data struct | ||
138 | * Flags - Actual flag byte | ||
139 | * | ||
140 | * RETURN: Decoded flag bits in attribute struct | ||
141 | * | ||
142 | * DESCRIPTION: Decode a type-specific flag byte to an attribute struct. | ||
143 | * Type-specific flags are only defined for the Memory and IO | ||
144 | * resource types. | ||
145 | * | ||
146 | ******************************************************************************/ | ||
147 | 105 | ||
148 | static void | 106 | /* |
149 | acpi_rs_decode_specific_flags(union acpi_resource_data *resource, u8 flags) | 107 | * These fields are contiguous in both the source and destination: |
150 | { | 108 | * Address Granularity |
151 | ACPI_FUNCTION_ENTRY(); | 109 | * Address Range Minimum |
152 | 110 | * Address Range Maximum | |
153 | if (resource->address.resource_type == ACPI_MEMORY_RANGE) { | 111 | * Address Translation Offset |
154 | /* Write Status (_RW) - flag bit[0] */ | 112 | * Address Length |
155 | 113 | */ | |
156 | resource->address.attribute.memory.read_write_attribute = | 114 | {ACPI_RSC_MOVE32, ACPI_RS_OFFSET(data.address32.granularity), |
157 | (u16) (flags & 0x01); | 115 | AML_OFFSET(address32.granularity), |
158 | 116 | 5}, | |
159 | /* Memory Attributes (_MEM) - flag bits[2:1] */ | ||
160 | |||
161 | resource->address.attribute.memory.cache_attribute = | ||
162 | (u16) ((flags >> 1) & 0x03); | ||
163 | } else if (resource->address.resource_type == ACPI_IO_RANGE) { | ||
164 | /* Ranges (_RNG) - flag bits[1:0] */ | ||
165 | |||
166 | resource->address.attribute.io.range_attribute = | ||
167 | (u16) (flags & 0x03); | ||
168 | 117 | ||
169 | /* Translations (_TTP and _TRS) - flag bits[5:4] */ | 118 | /* Optional resource_source (Index and String) */ |
170 | 119 | ||
171 | resource->address.attribute.io.translation_attribute = | 120 | {ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address32.resource_source), |
172 | (u16) ((flags >> 4) & 0x03); | 121 | 0, |
173 | } | 122 | sizeof(struct aml_resource_address32)} |
174 | } | 123 | }; |
175 | 124 | ||
176 | /******************************************************************************* | 125 | /******************************************************************************* |
177 | * | 126 | * |
178 | * FUNCTION: acpi_rs_encode_specific_flags | 127 | * acpi_rs_convert_address64 - All QWORD (64-bit) address resources |
179 | * | ||
180 | * PARAMETERS: Resource - Address resource data struct | ||
181 | * | ||
182 | * RETURN: Encoded type-specific flag byte | ||
183 | * | ||
184 | * DESCRIPTION: Construct a type-specific flag byte from an attribute struct. | ||
185 | * Type-specific flags are only defined for the Memory and IO | ||
186 | * resource types. | ||
187 | * | 128 | * |
188 | ******************************************************************************/ | 129 | ******************************************************************************/ |
189 | 130 | ||
190 | static u8 acpi_rs_encode_specific_flags(union acpi_resource_data *resource) | 131 | struct acpi_rsconvert_info acpi_rs_convert_address64[5] = { |
191 | { | 132 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS64, |
192 | u8 flags = 0; | 133 | ACPI_RS_SIZE(struct acpi_resource_address64), |
193 | 134 | ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address64)}, | |
194 | ACPI_FUNCTION_ENTRY(); | ||
195 | |||
196 | if (resource->address.resource_type == ACPI_MEMORY_RANGE) { | ||
197 | /* Write Status (_RW) - flag bit[0] */ | ||
198 | 135 | ||
199 | flags = (u8) | 136 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS64, |
200 | (resource->address.attribute.memory. | 137 | sizeof(struct aml_resource_address64), |
201 | read_write_attribute & 0x01); | 138 | 0}, |
202 | 139 | ||
203 | /* Memory Attributes (_MEM) - flag bits[2:1] */ | 140 | /* Resource Type, General Flags, and Type-Specific Flags */ |
204 | 141 | ||
205 | flags |= (u8) | 142 | {ACPI_RSC_ADDRESS, 0, 0, 0}, |
206 | ((resource->address.attribute.memory. | ||
207 | cache_attribute & 0x03) << 1); | ||
208 | } else if (resource->address.resource_type == ACPI_IO_RANGE) { | ||
209 | /* Ranges (_RNG) - flag bits[1:0] */ | ||
210 | 143 | ||
211 | flags = (u8) | 144 | /* |
212 | (resource->address.attribute.io.range_attribute & 0x03); | 145 | * These fields are contiguous in both the source and destination: |
146 | * Address Granularity | ||
147 | * Address Range Minimum | ||
148 | * Address Range Maximum | ||
149 | * Address Translation Offset | ||
150 | * Address Length | ||
151 | */ | ||
152 | {ACPI_RSC_MOVE64, ACPI_RS_OFFSET(data.address64.granularity), | ||
153 | AML_OFFSET(address64.granularity), | ||
154 | 5}, | ||
213 | 155 | ||
214 | /* Translations (_TTP and _TRS) - flag bits[5:4] */ | 156 | /* Optional resource_source (Index and String) */ |
215 | 157 | ||
216 | flags |= (u8) | 158 | {ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address64.resource_source), |
217 | ((resource->address.attribute.io. | 159 | 0, |
218 | translation_attribute & 0x03) << 4); | 160 | sizeof(struct aml_resource_address64)} |
219 | } | 161 | }; |
220 | |||
221 | return (flags); | ||
222 | } | ||
223 | 162 | ||
224 | /******************************************************************************* | 163 | /******************************************************************************* |
225 | * | 164 | * |
226 | * FUNCTION: acpi_rs_address16_resource | 165 | * acpi_rs_convert_ext_address64 - All Extended (64-bit) address resources |
227 | * | ||
228 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | ||
229 | * stream | ||
230 | * bytes_consumed - Pointer to where the number of bytes | ||
231 | * consumed the byte_stream_buffer is | ||
232 | * returned | ||
233 | * output_buffer - Pointer to the return data buffer | ||
234 | * structure_size - Pointer to where the number of bytes | ||
235 | * in the return data struct is returned | ||
236 | * | ||
237 | * RETURN: Status | ||
238 | * | ||
239 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | ||
240 | * structure pointed to by the output_buffer. Return the | ||
241 | * number of bytes consumed from the byte stream. | ||
242 | * | 166 | * |
243 | ******************************************************************************/ | 167 | ******************************************************************************/ |
244 | 168 | ||
245 | acpi_status | 169 | struct acpi_rsconvert_info acpi_rs_convert_ext_address64[5] = { |
246 | acpi_rs_address16_resource(u8 * byte_stream_buffer, | 170 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64, |
247 | acpi_size * bytes_consumed, | 171 | ACPI_RS_SIZE(struct acpi_resource_extended_address64), |
248 | u8 ** output_buffer, acpi_size * structure_size) | 172 | ACPI_RSC_TABLE_SIZE(acpi_rs_convert_ext_address64)}, |
249 | { | ||
250 | u32 index; | ||
251 | u16 temp16; | ||
252 | u8 temp8; | ||
253 | u8 *temp_ptr; | ||
254 | u8 *buffer = byte_stream_buffer; | ||
255 | struct acpi_resource *output_struct = (void *)*output_buffer; | ||
256 | acpi_size struct_size = | ||
257 | ACPI_SIZEOF_RESOURCE(struct acpi_resource_address16); | ||
258 | |||
259 | ACPI_FUNCTION_TRACE("rs_address16_resource"); | ||
260 | |||
261 | /* Get the Descriptor Length field */ | ||
262 | |||
263 | buffer += 1; | ||
264 | ACPI_MOVE_16_TO_16(&temp16, buffer); | ||
265 | |||
266 | /* Validate minimum descriptor length */ | ||
267 | |||
268 | if (temp16 < 13) { | ||
269 | return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); | ||
270 | } | ||
271 | |||
272 | *bytes_consumed = temp16 + 3; | ||
273 | output_struct->id = ACPI_RSTYPE_ADDRESS16; | ||
274 | |||
275 | /* Get the Resource Type (Byte3) */ | ||
276 | 173 | ||
277 | buffer += 2; | 174 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64, |
278 | temp8 = *buffer; | 175 | sizeof(struct aml_resource_extended_address64), |
176 | 0}, | ||
279 | 177 | ||
280 | /* Values 0-2 and 0xC0-0xFF are valid */ | 178 | /* Resource Type, General Flags, and Type-Specific Flags */ |
281 | 179 | ||
282 | if ((temp8 > 2) && (temp8 < 0xC0)) { | 180 | {ACPI_RSC_ADDRESS, 0, 0, 0}, |
283 | return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); | ||
284 | } | ||
285 | |||
286 | output_struct->data.address16.resource_type = temp8; | ||
287 | |||
288 | /* Get the General Flags (Byte4) */ | ||
289 | |||
290 | buffer += 1; | ||
291 | acpi_rs_decode_general_flags(&output_struct->data, *buffer); | ||
292 | |||
293 | /* Get the Type Specific Flags (Byte5) */ | ||
294 | |||
295 | buffer += 1; | ||
296 | acpi_rs_decode_specific_flags(&output_struct->data, *buffer); | ||
297 | |||
298 | /* Get Granularity (Bytes 6-7) */ | ||
299 | |||
300 | buffer += 1; | ||
301 | ACPI_MOVE_16_TO_32(&output_struct->data.address16.granularity, buffer); | ||
302 | |||
303 | /* Get min_address_range (Bytes 8-9) */ | ||
304 | 181 | ||
305 | buffer += 2; | 182 | /* Revision ID */ |
306 | ACPI_MOVE_16_TO_32(&output_struct->data.address16.min_address_range, | ||
307 | buffer); | ||
308 | |||
309 | /* Get max_address_range (Bytes 10-11) */ | ||
310 | |||
311 | buffer += 2; | ||
312 | ACPI_MOVE_16_TO_32(&output_struct->data.address16.max_address_range, | ||
313 | buffer); | ||
314 | |||
315 | /* Get address_translation_offset (Bytes 12-13) */ | ||
316 | |||
317 | buffer += 2; | ||
318 | ACPI_MOVE_16_TO_32(&output_struct->data.address16. | ||
319 | address_translation_offset, buffer); | ||
320 | |||
321 | /* Get address_length (Bytes 14-15) */ | ||
322 | |||
323 | buffer += 2; | ||
324 | ACPI_MOVE_16_TO_32(&output_struct->data.address16.address_length, | ||
325 | buffer); | ||
326 | |||
327 | /* Resource Source Index (if present) */ | ||
328 | |||
329 | buffer += 2; | ||
330 | 183 | ||
184 | {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.ext_address64.revision_iD), | ||
185 | AML_OFFSET(ext_address64.revision_iD), | ||
186 | 1}, | ||
331 | /* | 187 | /* |
332 | * This will leave us pointing to the Resource Source Index | 188 | * These fields are contiguous in both the source and destination: |
333 | * If it is present, then save it off and calculate the | 189 | * Address Granularity |
334 | * pointer to where the null terminated string goes: | 190 | * Address Range Minimum |
335 | * Each Interrupt takes 32-bits + the 5 bytes of the | 191 | * Address Range Maximum |
336 | * stream that are default. | 192 | * Address Translation Offset |
337 | * | 193 | * Address Length |
338 | * Note: Some resource descriptors will have an additional null, so | 194 | * Type-Specific Attribute |
339 | * we add 1 to the length. | ||
340 | */ | 195 | */ |
341 | if (*bytes_consumed > (16 + 1)) { | 196 | {ACPI_RSC_MOVE64, ACPI_RS_OFFSET(data.ext_address64.granularity), |
342 | /* Dereference the Index */ | 197 | AML_OFFSET(ext_address64.granularity), |
343 | 198 | 6} | |
344 | output_struct->data.address16.resource_source.index = | 199 | }; |
345 | (u32) * buffer; | ||
346 | |||
347 | /* Point to the String */ | ||
348 | |||
349 | buffer += 1; | ||
350 | |||
351 | /* Point the String pointer to the end of this structure */ | ||
352 | |||
353 | output_struct->data.address16.resource_source.string_ptr = | ||
354 | (char *)((u8 *) output_struct + struct_size); | ||
355 | |||
356 | temp_ptr = (u8 *) | ||
357 | output_struct->data.address16.resource_source.string_ptr; | ||
358 | |||
359 | /* Copy the resource_source string into the buffer */ | ||
360 | |||
361 | index = 0; | ||
362 | while (*buffer) { | ||
363 | *temp_ptr = *buffer; | ||
364 | |||
365 | temp_ptr++; | ||
366 | buffer++; | ||
367 | index++; | ||
368 | } | ||
369 | |||
370 | /* Add the terminating null and set the string length */ | ||
371 | |||
372 | *temp_ptr = 0; | ||
373 | output_struct->data.address16.resource_source.string_length = | ||
374 | index + 1; | ||
375 | |||
376 | /* | ||
377 | * In order for the struct_size to fall on a 32-bit boundary, | ||
378 | * calculate the length of the string and expand the | ||
379 | * struct_size to the next 32-bit boundary. | ||
380 | */ | ||
381 | temp8 = (u8) (index + 1); | ||
382 | struct_size += ACPI_ROUND_UP_to_32_bITS(temp8); | ||
383 | } else { | ||
384 | output_struct->data.address16.resource_source.index = 0; | ||
385 | output_struct->data.address16.resource_source.string_length = 0; | ||
386 | output_struct->data.address16.resource_source.string_ptr = NULL; | ||
387 | } | ||
388 | |||
389 | /* Set the Length parameter */ | ||
390 | |||
391 | output_struct->length = (u32) struct_size; | ||
392 | |||
393 | /* Return the final size of the structure */ | ||
394 | |||
395 | *structure_size = struct_size; | ||
396 | return_ACPI_STATUS(AE_OK); | ||
397 | } | ||
398 | 200 | ||
399 | /******************************************************************************* | 201 | /******************************************************************************* |
400 | * | 202 | * |
401 | * FUNCTION: acpi_rs_address16_stream | 203 | * acpi_rs_convert_general_flags - Flags common to all address descriptors |
402 | * | ||
403 | * PARAMETERS: linked_list - Pointer to the resource linked list | ||
404 | * output_buffer - Pointer to the user's return buffer | ||
405 | * bytes_consumed - Pointer to where the number of bytes | ||
406 | * used in the output_buffer is returned | ||
407 | * | ||
408 | * RETURN: Status | ||
409 | * | ||
410 | * DESCRIPTION: Take the linked list resource structure and fills in the | ||
411 | * the appropriate bytes in a byte stream | ||
412 | * | 204 | * |
413 | ******************************************************************************/ | 205 | ******************************************************************************/ |
414 | 206 | ||
415 | acpi_status | 207 | static struct acpi_rsconvert_info acpi_rs_convert_general_flags[6] = { |
416 | acpi_rs_address16_stream(struct acpi_resource *linked_list, | 208 | {ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.flags), |
417 | u8 ** output_buffer, acpi_size * bytes_consumed) | 209 | ACPI_RSC_TABLE_SIZE(acpi_rs_convert_general_flags)}, |
418 | { | ||
419 | u8 *buffer = *output_buffer; | ||
420 | u8 *length_field; | ||
421 | acpi_size actual_bytes; | ||
422 | |||
423 | ACPI_FUNCTION_TRACE("rs_address16_stream"); | ||
424 | |||
425 | /* Set the Descriptor Type field */ | ||
426 | |||
427 | *buffer = ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE; | ||
428 | buffer += 1; | ||
429 | |||
430 | /* Save a pointer to the Length field - to be filled in later */ | ||
431 | |||
432 | length_field = buffer; | ||
433 | buffer += 2; | ||
434 | |||
435 | /* Set the Resource Type (Memory, Io, bus_number) */ | ||
436 | |||
437 | *buffer = (u8) (linked_list->data.address16.resource_type & 0x03); | ||
438 | buffer += 1; | ||
439 | |||
440 | /* Set the general flags */ | ||
441 | |||
442 | *buffer = acpi_rs_encode_general_flags(&linked_list->data); | ||
443 | buffer += 1; | ||
444 | |||
445 | /* Set the type specific flags */ | ||
446 | |||
447 | *buffer = acpi_rs_encode_specific_flags(&linked_list->data); | ||
448 | buffer += 1; | ||
449 | |||
450 | /* Set the address space granularity */ | ||
451 | |||
452 | ACPI_MOVE_32_TO_16(buffer, &linked_list->data.address16.granularity); | ||
453 | buffer += 2; | ||
454 | |||
455 | /* Set the address range minimum */ | ||
456 | 210 | ||
457 | ACPI_MOVE_32_TO_16(buffer, | 211 | /* Resource Type (Memory, Io, bus_number, etc.) */ |
458 | &linked_list->data.address16.min_address_range); | ||
459 | buffer += 2; | ||
460 | 212 | ||
461 | /* Set the address range maximum */ | 213 | {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.address.resource_type), |
214 | AML_OFFSET(address.resource_type), | ||
215 | 1}, | ||
462 | 216 | ||
463 | ACPI_MOVE_32_TO_16(buffer, | 217 | /* General Flags - Consume, Decode, min_fixed, max_fixed */ |
464 | &linked_list->data.address16.max_address_range); | ||
465 | buffer += 2; | ||
466 | 218 | ||
467 | /* Set the address translation offset */ | 219 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.producer_consumer), |
220 | AML_OFFSET(address.flags), | ||
221 | 0}, | ||
468 | 222 | ||
469 | ACPI_MOVE_32_TO_16(buffer, | 223 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.decode), |
470 | &linked_list->data.address16. | 224 | AML_OFFSET(address.flags), |
471 | address_translation_offset); | 225 | 1}, |
472 | buffer += 2; | ||
473 | 226 | ||
474 | /* Set the address length */ | 227 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.min_address_fixed), |
228 | AML_OFFSET(address.flags), | ||
229 | 2}, | ||
475 | 230 | ||
476 | ACPI_MOVE_32_TO_16(buffer, &linked_list->data.address16.address_length); | 231 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.max_address_fixed), |
477 | buffer += 2; | 232 | AML_OFFSET(address.flags), |
478 | 233 | 3} | |
479 | /* Resource Source Index and Resource Source are optional */ | 234 | }; |
480 | |||
481 | if (linked_list->data.address16.resource_source.string_length) { | ||
482 | *buffer = | ||
483 | (u8) linked_list->data.address16.resource_source.index; | ||
484 | buffer += 1; | ||
485 | |||
486 | /* Copy the resource_source string */ | ||
487 | |||
488 | ACPI_STRCPY((char *)buffer, | ||
489 | linked_list->data.address16.resource_source. | ||
490 | string_ptr); | ||
491 | |||
492 | /* | ||
493 | * Buffer needs to be set to the length of the string + one for the | ||
494 | * terminating null | ||
495 | */ | ||
496 | buffer += | ||
497 | (acpi_size) (ACPI_STRLEN | ||
498 | (linked_list->data.address16.resource_source. | ||
499 | string_ptr) + 1); | ||
500 | } | ||
501 | |||
502 | /* Return the number of bytes consumed in this operation */ | ||
503 | |||
504 | actual_bytes = ACPI_PTR_DIFF(buffer, *output_buffer); | ||
505 | *bytes_consumed = actual_bytes; | ||
506 | |||
507 | /* | ||
508 | * Set the length field to the number of bytes consumed | ||
509 | * minus the header size (3 bytes) | ||
510 | */ | ||
511 | actual_bytes -= 3; | ||
512 | ACPI_MOVE_SIZE_TO_16(length_field, &actual_bytes); | ||
513 | return_ACPI_STATUS(AE_OK); | ||
514 | } | ||
515 | 235 | ||
516 | /******************************************************************************* | 236 | /******************************************************************************* |
517 | * | 237 | * |
518 | * FUNCTION: acpi_rs_address32_resource | 238 | * acpi_rs_convert_mem_flags - Flags common to Memory address descriptors |
519 | * | ||
520 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | ||
521 | * stream | ||
522 | * bytes_consumed - Pointer to where the number of bytes | ||
523 | * consumed the byte_stream_buffer is | ||
524 | * returned | ||
525 | * output_buffer - Pointer to the return data buffer | ||
526 | * structure_size - Pointer to where the number of bytes | ||
527 | * in the return data struct is returned | ||
528 | * | ||
529 | * RETURN: Status | ||
530 | * | ||
531 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | ||
532 | * structure pointed to by the output_buffer. Return the | ||
533 | * number of bytes consumed from the byte stream. | ||
534 | * | 239 | * |
535 | ******************************************************************************/ | 240 | ******************************************************************************/ |
536 | 241 | ||
537 | acpi_status | 242 | static struct acpi_rsconvert_info acpi_rs_convert_mem_flags[5] = { |
538 | acpi_rs_address32_resource(u8 * byte_stream_buffer, | 243 | {ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.specific_flags), |
539 | acpi_size * bytes_consumed, | 244 | ACPI_RSC_TABLE_SIZE(acpi_rs_convert_mem_flags)}, |
540 | u8 ** output_buffer, acpi_size * structure_size) | ||
541 | { | ||
542 | u16 temp16; | ||
543 | u8 temp8; | ||
544 | u8 *temp_ptr; | ||
545 | u32 index; | ||
546 | u8 *buffer = byte_stream_buffer; | ||
547 | struct acpi_resource *output_struct = (void *)*output_buffer; | ||
548 | acpi_size struct_size = | ||
549 | ACPI_SIZEOF_RESOURCE(struct acpi_resource_address32); | ||
550 | 245 | ||
551 | ACPI_FUNCTION_TRACE("rs_address32_resource"); | 246 | /* Memory-specific flags */ |
552 | 247 | ||
553 | /* Get the Descriptor Length field */ | 248 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.write_protect), |
249 | AML_OFFSET(address.specific_flags), | ||
250 | 0}, | ||
554 | 251 | ||
555 | buffer += 1; | 252 | {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.caching), |
556 | ACPI_MOVE_16_TO_16(&temp16, buffer); | 253 | AML_OFFSET(address.specific_flags), |
254 | 1}, | ||
557 | 255 | ||
558 | /* Validate minimum descriptor length */ | 256 | {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.range_type), |
257 | AML_OFFSET(address.specific_flags), | ||
258 | 3}, | ||
559 | 259 | ||
560 | if (temp16 < 23) { | 260 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.translation), |
561 | return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); | 261 | AML_OFFSET(address.specific_flags), |
562 | } | 262 | 5} |
563 | 263 | }; | |
564 | *bytes_consumed = temp16 + 3; | ||
565 | output_struct->id = ACPI_RSTYPE_ADDRESS32; | ||
566 | |||
567 | /* Get the Resource Type (Byte3) */ | ||
568 | |||
569 | buffer += 2; | ||
570 | temp8 = *buffer; | ||
571 | |||
572 | /* Values 0-2 and 0xC0-0xFF are valid */ | ||
573 | |||
574 | if ((temp8 > 2) && (temp8 < 0xC0)) { | ||
575 | return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); | ||
576 | } | ||
577 | |||
578 | output_struct->data.address32.resource_type = temp8; | ||
579 | |||
580 | /* Get the General Flags (Byte4) */ | ||
581 | |||
582 | buffer += 1; | ||
583 | acpi_rs_decode_general_flags(&output_struct->data, *buffer); | ||
584 | |||
585 | /* Get the Type Specific Flags (Byte5) */ | ||
586 | |||
587 | buffer += 1; | ||
588 | acpi_rs_decode_specific_flags(&output_struct->data, *buffer); | ||
589 | |||
590 | /* Get Granularity (Bytes 6-9) */ | ||
591 | |||
592 | buffer += 1; | ||
593 | ACPI_MOVE_32_TO_32(&output_struct->data.address32.granularity, buffer); | ||
594 | |||
595 | /* Get min_address_range (Bytes 10-13) */ | ||
596 | |||
597 | buffer += 4; | ||
598 | ACPI_MOVE_32_TO_32(&output_struct->data.address32.min_address_range, | ||
599 | buffer); | ||
600 | |||
601 | /* Get max_address_range (Bytes 14-17) */ | ||
602 | |||
603 | buffer += 4; | ||
604 | ACPI_MOVE_32_TO_32(&output_struct->data.address32.max_address_range, | ||
605 | buffer); | ||
606 | |||
607 | /* Get address_translation_offset (Bytes 18-21) */ | ||
608 | |||
609 | buffer += 4; | ||
610 | ACPI_MOVE_32_TO_32(&output_struct->data.address32. | ||
611 | address_translation_offset, buffer); | ||
612 | |||
613 | /* Get address_length (Bytes 22-25) */ | ||
614 | |||
615 | buffer += 4; | ||
616 | ACPI_MOVE_32_TO_32(&output_struct->data.address32.address_length, | ||
617 | buffer); | ||
618 | |||
619 | /* Resource Source Index (if present) */ | ||
620 | |||
621 | buffer += 4; | ||
622 | |||
623 | /* | ||
624 | * This will leave us pointing to the Resource Source Index | ||
625 | * If it is present, then save it off and calculate the | ||
626 | * pointer to where the null terminated string goes: | ||
627 | * | ||
628 | * Note: Some resource descriptors will have an additional null, so | ||
629 | * we add 1 to the length. | ||
630 | */ | ||
631 | if (*bytes_consumed > (26 + 1)) { | ||
632 | /* Dereference the Index */ | ||
633 | |||
634 | output_struct->data.address32.resource_source.index = | ||
635 | (u32) * buffer; | ||
636 | |||
637 | /* Point to the String */ | ||
638 | |||
639 | buffer += 1; | ||
640 | |||
641 | /* Point the String pointer to the end of this structure */ | ||
642 | |||
643 | output_struct->data.address32.resource_source.string_ptr = | ||
644 | (char *)((u8 *) output_struct + struct_size); | ||
645 | |||
646 | temp_ptr = (u8 *) | ||
647 | output_struct->data.address32.resource_source.string_ptr; | ||
648 | |||
649 | /* Copy the resource_source string into the buffer */ | ||
650 | |||
651 | index = 0; | ||
652 | while (*buffer) { | ||
653 | *temp_ptr = *buffer; | ||
654 | |||
655 | temp_ptr++; | ||
656 | buffer++; | ||
657 | index++; | ||
658 | } | ||
659 | |||
660 | /* Add the terminating null and set the string length */ | ||
661 | |||
662 | *temp_ptr = 0; | ||
663 | output_struct->data.address32.resource_source.string_length = | ||
664 | index + 1; | ||
665 | |||
666 | /* | ||
667 | * In order for the struct_size to fall on a 32-bit boundary, | ||
668 | * calculate the length of the string and expand the | ||
669 | * struct_size to the next 32-bit boundary. | ||
670 | */ | ||
671 | temp8 = (u8) (index + 1); | ||
672 | struct_size += ACPI_ROUND_UP_to_32_bITS(temp8); | ||
673 | } else { | ||
674 | output_struct->data.address32.resource_source.index = 0; | ||
675 | output_struct->data.address32.resource_source.string_length = 0; | ||
676 | output_struct->data.address32.resource_source.string_ptr = NULL; | ||
677 | } | ||
678 | |||
679 | /* Set the Length parameter */ | ||
680 | |||
681 | output_struct->length = (u32) struct_size; | ||
682 | |||
683 | /* Return the final size of the structure */ | ||
684 | |||
685 | *structure_size = struct_size; | ||
686 | return_ACPI_STATUS(AE_OK); | ||
687 | } | ||
688 | 264 | ||
689 | /******************************************************************************* | 265 | /******************************************************************************* |
690 | * | 266 | * |
691 | * FUNCTION: acpi_rs_address32_stream | 267 | * acpi_rs_convert_io_flags - Flags common to I/O address descriptors |
692 | * | ||
693 | * PARAMETERS: linked_list - Pointer to the resource linked list | ||
694 | * output_buffer - Pointer to the user's return buffer | ||
695 | * bytes_consumed - Pointer to where the number of bytes | ||
696 | * used in the output_buffer is returned | ||
697 | * | ||
698 | * RETURN: Status | ||
699 | * | ||
700 | * DESCRIPTION: Take the linked list resource structure and fills in the | ||
701 | * the appropriate bytes in a byte stream | ||
702 | * | 268 | * |
703 | ******************************************************************************/ | 269 | ******************************************************************************/ |
704 | 270 | ||
705 | acpi_status | 271 | static struct acpi_rsconvert_info acpi_rs_convert_io_flags[4] = { |
706 | acpi_rs_address32_stream(struct acpi_resource *linked_list, | 272 | {ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.specific_flags), |
707 | u8 ** output_buffer, acpi_size * bytes_consumed) | 273 | ACPI_RSC_TABLE_SIZE(acpi_rs_convert_io_flags)}, |
708 | { | ||
709 | u8 *buffer; | ||
710 | u16 *length_field; | ||
711 | |||
712 | ACPI_FUNCTION_TRACE("rs_address32_stream"); | ||
713 | |||
714 | buffer = *output_buffer; | ||
715 | |||
716 | /* Set the Descriptor Type field */ | ||
717 | |||
718 | *buffer = ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE; | ||
719 | buffer += 1; | ||
720 | |||
721 | /* Save a pointer to the Length field - to be filled in later */ | ||
722 | |||
723 | length_field = ACPI_CAST_PTR(u16, buffer); | ||
724 | buffer += 2; | ||
725 | |||
726 | /* Set the Resource Type (Memory, Io, bus_number) */ | ||
727 | |||
728 | *buffer = (u8) (linked_list->data.address32.resource_type & 0x03); | ||
729 | buffer += 1; | ||
730 | |||
731 | /* Set the general flags */ | ||
732 | |||
733 | *buffer = acpi_rs_encode_general_flags(&linked_list->data); | ||
734 | buffer += 1; | ||
735 | |||
736 | /* Set the type specific flags */ | ||
737 | |||
738 | *buffer = acpi_rs_encode_specific_flags(&linked_list->data); | ||
739 | buffer += 1; | ||
740 | |||
741 | /* Set the address space granularity */ | ||
742 | |||
743 | ACPI_MOVE_32_TO_32(buffer, &linked_list->data.address32.granularity); | ||
744 | buffer += 4; | ||
745 | |||
746 | /* Set the address range minimum */ | ||
747 | |||
748 | ACPI_MOVE_32_TO_32(buffer, | ||
749 | &linked_list->data.address32.min_address_range); | ||
750 | buffer += 4; | ||
751 | |||
752 | /* Set the address range maximum */ | ||
753 | |||
754 | ACPI_MOVE_32_TO_32(buffer, | ||
755 | &linked_list->data.address32.max_address_range); | ||
756 | buffer += 4; | ||
757 | |||
758 | /* Set the address translation offset */ | ||
759 | |||
760 | ACPI_MOVE_32_TO_32(buffer, | ||
761 | &linked_list->data.address32. | ||
762 | address_translation_offset); | ||
763 | buffer += 4; | ||
764 | |||
765 | /* Set the address length */ | ||
766 | |||
767 | ACPI_MOVE_32_TO_32(buffer, &linked_list->data.address32.address_length); | ||
768 | buffer += 4; | ||
769 | 274 | ||
770 | /* Resource Source Index and Resource Source are optional */ | 275 | /* I/O-specific flags */ |
771 | 276 | ||
772 | if (linked_list->data.address32.resource_source.string_length) { | 277 | {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.io.range_type), |
773 | *buffer = | 278 | AML_OFFSET(address.specific_flags), |
774 | (u8) linked_list->data.address32.resource_source.index; | 279 | 0}, |
775 | buffer += 1; | ||
776 | 280 | ||
777 | /* Copy the resource_source string */ | 281 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.io.translation), |
282 | AML_OFFSET(address.specific_flags), | ||
283 | 4}, | ||
778 | 284 | ||
779 | ACPI_STRCPY((char *)buffer, | 285 | {ACPI_RSC_1BITFLAG, |
780 | linked_list->data.address32.resource_source. | 286 | ACPI_RS_OFFSET(data.address.info.io.translation_type), |
781 | string_ptr); | 287 | AML_OFFSET(address.specific_flags), |
782 | 288 | 5} | |
783 | /* | 289 | }; |
784 | * Buffer needs to be set to the length of the string + one for the | ||
785 | * terminating null | ||
786 | */ | ||
787 | buffer += | ||
788 | (acpi_size) (ACPI_STRLEN | ||
789 | (linked_list->data.address32.resource_source. | ||
790 | string_ptr) + 1); | ||
791 | } | ||
792 | |||
793 | /* Return the number of bytes consumed in this operation */ | ||
794 | |||
795 | *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); | ||
796 | |||
797 | /* | ||
798 | * Set the length field to the number of bytes consumed | ||
799 | * minus the header size (3 bytes) | ||
800 | */ | ||
801 | *length_field = (u16) (*bytes_consumed - 3); | ||
802 | return_ACPI_STATUS(AE_OK); | ||
803 | } | ||
804 | 290 | ||
805 | /******************************************************************************* | 291 | /******************************************************************************* |
806 | * | 292 | * |
807 | * FUNCTION: acpi_rs_address64_resource | 293 | * FUNCTION: acpi_rs_get_address_common |
808 | * | 294 | * |
809 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | 295 | * PARAMETERS: Resource - Pointer to the internal resource struct |
810 | * stream | 296 | * Aml - Pointer to the AML resource descriptor |
811 | * bytes_consumed - Pointer to where the number of bytes | ||
812 | * consumed the byte_stream_buffer is | ||
813 | * returned | ||
814 | * output_buffer - Pointer to the return data buffer | ||
815 | * structure_size - Pointer to where the number of bytes | ||
816 | * in the return data struct is returned | ||
817 | * | 297 | * |
818 | * RETURN: Status | 298 | * RETURN: TRUE if the resource_type field is OK, FALSE otherwise |
819 | * | 299 | * |
820 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | 300 | * DESCRIPTION: Convert common flag fields from a raw AML resource descriptor |
821 | * structure pointed to by the output_buffer. Return the | 301 | * to an internal resource descriptor |
822 | * number of bytes consumed from the byte stream. | ||
823 | * | 302 | * |
824 | ******************************************************************************/ | 303 | ******************************************************************************/ |
825 | 304 | ||
826 | acpi_status | 305 | u8 |
827 | acpi_rs_address64_resource(u8 * byte_stream_buffer, | 306 | acpi_rs_get_address_common(struct acpi_resource *resource, |
828 | acpi_size * bytes_consumed, | 307 | union aml_resource *aml) |
829 | u8 ** output_buffer, acpi_size * structure_size) | ||
830 | { | 308 | { |
831 | u16 temp16; | 309 | ACPI_FUNCTION_ENTRY(); |
832 | u8 temp8; | ||
833 | u8 resource_type; | ||
834 | u8 *temp_ptr; | ||
835 | u32 index; | ||
836 | u8 *buffer = byte_stream_buffer; | ||
837 | struct acpi_resource *output_struct = (void *)*output_buffer; | ||
838 | acpi_size struct_size = | ||
839 | ACPI_SIZEOF_RESOURCE(struct acpi_resource_address64); | ||
840 | |||
841 | ACPI_FUNCTION_TRACE("rs_address64_resource"); | ||
842 | |||
843 | /* Get the Descriptor Type */ | ||
844 | |||
845 | resource_type = *buffer; | ||
846 | |||
847 | /* Get the Descriptor Length field */ | ||
848 | |||
849 | buffer += 1; | ||
850 | ACPI_MOVE_16_TO_16(&temp16, buffer); | ||
851 | |||
852 | /* Validate minimum descriptor length */ | ||
853 | |||
854 | if (temp16 < 43) { | ||
855 | return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); | ||
856 | } | ||
857 | |||
858 | *bytes_consumed = temp16 + 3; | ||
859 | output_struct->id = ACPI_RSTYPE_ADDRESS64; | ||
860 | |||
861 | /* Get the Resource Type (Byte3) */ | ||
862 | |||
863 | buffer += 2; | ||
864 | temp8 = *buffer; | ||
865 | |||
866 | /* Values 0-2 and 0xC0-0xFF are valid */ | ||
867 | |||
868 | if ((temp8 > 2) && (temp8 < 0xC0)) { | ||
869 | return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); | ||
870 | } | ||
871 | |||
872 | output_struct->data.address64.resource_type = temp8; | ||
873 | |||
874 | /* Get the General Flags (Byte4) */ | ||
875 | |||
876 | buffer += 1; | ||
877 | acpi_rs_decode_general_flags(&output_struct->data, *buffer); | ||
878 | |||
879 | /* Get the Type Specific Flags (Byte5) */ | ||
880 | |||
881 | buffer += 1; | ||
882 | acpi_rs_decode_specific_flags(&output_struct->data, *buffer); | ||
883 | 310 | ||
884 | if (resource_type == ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE) { | 311 | /* Validate the Resource Type */ |
885 | /* Move past revision_id and Reserved byte */ | ||
886 | 312 | ||
887 | buffer += 2; | 313 | if ((aml->address.resource_type > 2) |
314 | && (aml->address.resource_type < 0xC0)) { | ||
315 | return (FALSE); | ||
888 | } | 316 | } |
889 | 317 | ||
890 | /* Get Granularity (Bytes 6-13) or (Bytes 8-15) */ | 318 | /* Get the Resource Type and General Flags */ |
891 | |||
892 | buffer += 1; | ||
893 | ACPI_MOVE_64_TO_64(&output_struct->data.address64.granularity, buffer); | ||
894 | |||
895 | /* Get min_address_range (Bytes 14-21) or (Bytes 16-23) */ | ||
896 | |||
897 | buffer += 8; | ||
898 | ACPI_MOVE_64_TO_64(&output_struct->data.address64.min_address_range, | ||
899 | buffer); | ||
900 | |||
901 | /* Get max_address_range (Bytes 22-29) or (Bytes 24-31) */ | ||
902 | |||
903 | buffer += 8; | ||
904 | ACPI_MOVE_64_TO_64(&output_struct->data.address64.max_address_range, | ||
905 | buffer); | ||
906 | |||
907 | /* Get address_translation_offset (Bytes 30-37) or (Bytes 32-39) */ | ||
908 | |||
909 | buffer += 8; | ||
910 | ACPI_MOVE_64_TO_64(&output_struct->data.address64. | ||
911 | address_translation_offset, buffer); | ||
912 | 319 | ||
913 | /* Get address_length (Bytes 38-45) or (Bytes 40-47) */ | 320 | (void)acpi_rs_convert_aml_to_resource(resource, aml, |
321 | acpi_rs_convert_general_flags); | ||
914 | 322 | ||
915 | buffer += 8; | 323 | /* Get the Type-Specific Flags (Memory and I/O descriptors only) */ |
916 | ACPI_MOVE_64_TO_64(&output_struct->data.address64.address_length, | ||
917 | buffer); | ||
918 | 324 | ||
919 | output_struct->data.address64.resource_source.index = 0; | 325 | if (resource->data.address.resource_type == ACPI_MEMORY_RANGE) { |
920 | output_struct->data.address64.resource_source.string_length = 0; | 326 | (void)acpi_rs_convert_aml_to_resource(resource, aml, |
921 | output_struct->data.address64.resource_source.string_ptr = NULL; | 327 | acpi_rs_convert_mem_flags); |
922 | 328 | } else if (resource->data.address.resource_type == ACPI_IO_RANGE) { | |
923 | if (resource_type == ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE) { | 329 | (void)acpi_rs_convert_aml_to_resource(resource, aml, |
924 | /* Get type_specific_attribute (Bytes 48-55) */ | 330 | acpi_rs_convert_io_flags); |
925 | |||
926 | buffer += 8; | ||
927 | ACPI_MOVE_64_TO_64(&output_struct->data.address64. | ||
928 | type_specific_attributes, buffer); | ||
929 | } else { | 331 | } else { |
930 | output_struct->data.address64.type_specific_attributes = 0; | 332 | /* Generic resource type, just grab the type_specific byte */ |
931 | |||
932 | /* Resource Source Index (if present) */ | ||
933 | |||
934 | buffer += 8; | ||
935 | |||
936 | /* | ||
937 | * This will leave us pointing to the Resource Source Index | ||
938 | * If it is present, then save it off and calculate the | ||
939 | * pointer to where the null terminated string goes: | ||
940 | * Each Interrupt takes 32-bits + the 5 bytes of the | ||
941 | * stream that are default. | ||
942 | * | ||
943 | * Note: Some resource descriptors will have an additional null, so | ||
944 | * we add 1 to the length. | ||
945 | */ | ||
946 | if (*bytes_consumed > (46 + 1)) { | ||
947 | /* Dereference the Index */ | ||
948 | |||
949 | output_struct->data.address64.resource_source.index = | ||
950 | (u32) * buffer; | ||
951 | |||
952 | /* Point to the String */ | ||
953 | |||
954 | buffer += 1; | ||
955 | |||
956 | /* Point the String pointer to the end of this structure */ | ||
957 | |||
958 | output_struct->data.address64.resource_source. | ||
959 | string_ptr = | ||
960 | (char *)((u8 *) output_struct + struct_size); | ||
961 | |||
962 | temp_ptr = (u8 *) | ||
963 | output_struct->data.address64.resource_source. | ||
964 | string_ptr; | ||
965 | |||
966 | /* Copy the resource_source string into the buffer */ | ||
967 | |||
968 | index = 0; | ||
969 | while (*buffer) { | ||
970 | *temp_ptr = *buffer; | ||
971 | |||
972 | temp_ptr++; | ||
973 | buffer++; | ||
974 | index++; | ||
975 | } | ||
976 | |||
977 | /* | ||
978 | * Add the terminating null and set the string length | ||
979 | */ | ||
980 | *temp_ptr = 0; | ||
981 | output_struct->data.address64.resource_source. | ||
982 | string_length = index + 1; | ||
983 | |||
984 | /* | ||
985 | * In order for the struct_size to fall on a 32-bit boundary, | ||
986 | * calculate the length of the string and expand the | ||
987 | * struct_size to the next 32-bit boundary. | ||
988 | */ | ||
989 | temp8 = (u8) (index + 1); | ||
990 | struct_size += ACPI_ROUND_UP_to_32_bITS(temp8); | ||
991 | } | ||
992 | } | ||
993 | |||
994 | /* Set the Length parameter */ | ||
995 | |||
996 | output_struct->length = (u32) struct_size; | ||
997 | 333 | ||
998 | /* Return the final size of the structure */ | 334 | resource->data.address.info.type_specific = |
335 | aml->address.specific_flags; | ||
336 | } | ||
999 | 337 | ||
1000 | *structure_size = struct_size; | 338 | return (TRUE); |
1001 | return_ACPI_STATUS(AE_OK); | ||
1002 | } | 339 | } |
1003 | 340 | ||
1004 | /******************************************************************************* | 341 | /******************************************************************************* |
1005 | * | 342 | * |
1006 | * FUNCTION: acpi_rs_address64_stream | 343 | * FUNCTION: acpi_rs_set_address_common |
1007 | * | 344 | * |
1008 | * PARAMETERS: linked_list - Pointer to the resource linked list | 345 | * PARAMETERS: Aml - Pointer to the AML resource descriptor |
1009 | * output_buffer - Pointer to the user's return buffer | 346 | * Resource - Pointer to the internal resource struct |
1010 | * bytes_consumed - Pointer to where the number of bytes | ||
1011 | * used in the output_buffer is returned | ||
1012 | * | 347 | * |
1013 | * RETURN: Status | 348 | * RETURN: None |
1014 | * | 349 | * |
1015 | * DESCRIPTION: Take the linked list resource structure and fills in the | 350 | * DESCRIPTION: Convert common flag fields from a resource descriptor to an |
1016 | * the appropriate bytes in a byte stream | 351 | * AML descriptor |
1017 | * | 352 | * |
1018 | ******************************************************************************/ | 353 | ******************************************************************************/ |
1019 | 354 | ||
1020 | acpi_status | 355 | void |
1021 | acpi_rs_address64_stream(struct acpi_resource *linked_list, | 356 | acpi_rs_set_address_common(union aml_resource *aml, |
1022 | u8 ** output_buffer, acpi_size * bytes_consumed) | 357 | struct acpi_resource *resource) |
1023 | { | 358 | { |
1024 | u8 *buffer; | 359 | ACPI_FUNCTION_ENTRY(); |
1025 | u16 *length_field; | ||
1026 | |||
1027 | ACPI_FUNCTION_TRACE("rs_address64_stream"); | ||
1028 | |||
1029 | buffer = *output_buffer; | ||
1030 | |||
1031 | /* Set the Descriptor Type field */ | ||
1032 | |||
1033 | *buffer = ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE; | ||
1034 | buffer += 1; | ||
1035 | |||
1036 | /* Save a pointer to the Length field - to be filled in later */ | ||
1037 | |||
1038 | length_field = ACPI_CAST_PTR(u16, buffer); | ||
1039 | buffer += 2; | ||
1040 | |||
1041 | /* Set the Resource Type (Memory, Io, bus_number) */ | ||
1042 | |||
1043 | *buffer = (u8) (linked_list->data.address64.resource_type & 0x03); | ||
1044 | buffer += 1; | ||
1045 | |||
1046 | /* Set the general flags */ | ||
1047 | |||
1048 | *buffer = acpi_rs_encode_general_flags(&linked_list->data); | ||
1049 | buffer += 1; | ||
1050 | |||
1051 | /* Set the type specific flags */ | ||
1052 | |||
1053 | *buffer = acpi_rs_encode_specific_flags(&linked_list->data); | ||
1054 | buffer += 1; | ||
1055 | |||
1056 | /* Set the address space granularity */ | ||
1057 | |||
1058 | ACPI_MOVE_64_TO_64(buffer, &linked_list->data.address64.granularity); | ||
1059 | buffer += 8; | ||
1060 | |||
1061 | /* Set the address range minimum */ | ||
1062 | |||
1063 | ACPI_MOVE_64_TO_64(buffer, | ||
1064 | &linked_list->data.address64.min_address_range); | ||
1065 | buffer += 8; | ||
1066 | |||
1067 | /* Set the address range maximum */ | ||
1068 | |||
1069 | ACPI_MOVE_64_TO_64(buffer, | ||
1070 | &linked_list->data.address64.max_address_range); | ||
1071 | buffer += 8; | ||
1072 | |||
1073 | /* Set the address translation offset */ | ||
1074 | |||
1075 | ACPI_MOVE_64_TO_64(buffer, | ||
1076 | &linked_list->data.address64. | ||
1077 | address_translation_offset); | ||
1078 | buffer += 8; | ||
1079 | |||
1080 | /* Set the address length */ | ||
1081 | |||
1082 | ACPI_MOVE_64_TO_64(buffer, &linked_list->data.address64.address_length); | ||
1083 | buffer += 8; | ||
1084 | 360 | ||
1085 | /* Resource Source Index and Resource Source are optional */ | 361 | /* Set the Resource Type and General Flags */ |
1086 | 362 | ||
1087 | if (linked_list->data.address64.resource_source.string_length) { | 363 | (void)acpi_rs_convert_resource_to_aml(resource, aml, |
1088 | *buffer = | 364 | acpi_rs_convert_general_flags); |
1089 | (u8) linked_list->data.address64.resource_source.index; | ||
1090 | buffer += 1; | ||
1091 | 365 | ||
1092 | /* Copy the resource_source string */ | 366 | /* Set the Type-Specific Flags (Memory and I/O descriptors only) */ |
1093 | 367 | ||
1094 | ACPI_STRCPY((char *)buffer, | 368 | if (resource->data.address.resource_type == ACPI_MEMORY_RANGE) { |
1095 | linked_list->data.address64.resource_source. | 369 | (void)acpi_rs_convert_resource_to_aml(resource, aml, |
1096 | string_ptr); | 370 | acpi_rs_convert_mem_flags); |
371 | } else if (resource->data.address.resource_type == ACPI_IO_RANGE) { | ||
372 | (void)acpi_rs_convert_resource_to_aml(resource, aml, | ||
373 | acpi_rs_convert_io_flags); | ||
374 | } else { | ||
375 | /* Generic resource type, just copy the type_specific byte */ | ||
1097 | 376 | ||
1098 | /* | 377 | aml->address.specific_flags = |
1099 | * Buffer needs to be set to the length of the string + one for the | 378 | resource->data.address.info.type_specific; |
1100 | * terminating null | ||
1101 | */ | ||
1102 | buffer += | ||
1103 | (acpi_size) (ACPI_STRLEN | ||
1104 | (linked_list->data.address64.resource_source. | ||
1105 | string_ptr) + 1); | ||
1106 | } | 379 | } |
1107 | |||
1108 | /* Return the number of bytes consumed in this operation */ | ||
1109 | |||
1110 | *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer); | ||
1111 | |||
1112 | /* | ||
1113 | * Set the length field to the number of bytes consumed | ||
1114 | * minus the header size (3 bytes) | ||
1115 | */ | ||
1116 | *length_field = (u16) (*bytes_consumed - 3); | ||
1117 | return_ACPI_STATUS(AE_OK); | ||
1118 | } | 380 | } |