- Make ACPI use PCH. Cuts down compile time to 9 seconds on gcc.
[reactos.git] / reactos / drivers / bus / acpi / resource / rslist.c
1 /*******************************************************************************
2 *
3 * Module Name: rslist - Acpi_rs_byte_stream_to_list
4 * Acpi_list_to_byte_stream
5 * $Revision: 1.1 $
6 *
7 ******************************************************************************/
8
9 /*
10 * Copyright (C) 2000, 2001 R. Byron Moore
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 */
26
27
28 #include <acpi.h>
29
30 #define _COMPONENT ACPI_RESOURCES
31 MODULE_NAME ("rslist")
32
33
34 /*******************************************************************************
35 *
36 * FUNCTION: Acpi_rs_byte_stream_to_list
37 *
38 * PARAMETERS: Byte_stream_buffer - Pointer to the resource byte stream
39 * Byte_stream_buffer_length - Length of Byte_stream_buffer
40 * Output_buffer - Pointer to the buffer that will
41 * contain the output structures
42 *
43 * RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code
44 *
45 * DESCRIPTION: Takes the resource byte stream and parses it, creating a
46 * linked list of resources in the caller's output buffer
47 *
48 ******************************************************************************/
49
50 ACPI_STATUS
51 acpi_rs_byte_stream_to_list (
52 u8 *byte_stream_buffer,
53 u32 byte_stream_buffer_length,
54 u8 **output_buffer)
55 {
56 ACPI_STATUS status;
57 u32 bytes_parsed = 0;
58 u8 resource_type = 0;
59 u32 bytes_consumed = 0;
60 u8 **buffer = output_buffer;
61 u32 structure_size = 0;
62 u8 end_tag_processed = FALSE;
63
64
65 while (bytes_parsed < byte_stream_buffer_length &&
66 FALSE == end_tag_processed) {
67 /*
68 * Look at the next byte in the stream
69 */
70 resource_type = *byte_stream_buffer;
71
72 /*
73 * See if this is a small or large resource
74 */
75 if(resource_type & 0x80) {
76 /*
77 * Large Resource Type
78 */
79 switch (resource_type) {
80 case MEMORY_RANGE_24:
81 /*
82 * 24-Bit Memory Resource
83 */
84 status = acpi_rs_memory24_resource(byte_stream_buffer,
85 &bytes_consumed,
86 buffer,
87 &structure_size);
88
89 break;
90
91 case LARGE_VENDOR_DEFINED:
92 /*
93 * Vendor Defined Resource
94 */
95 status = acpi_rs_vendor_resource(byte_stream_buffer,
96 &bytes_consumed,
97 buffer,
98 &structure_size);
99
100 break;
101
102 case MEMORY_RANGE_32:
103 /*
104 * 32-Bit Memory Range Resource
105 */
106 status = acpi_rs_memory32_range_resource(byte_stream_buffer,
107 &bytes_consumed,
108 buffer,
109 &structure_size);
110
111 break;
112
113 case FIXED_MEMORY_RANGE_32:
114 /*
115 * 32-Bit Fixed Memory Resource
116 */
117 status = acpi_rs_fixed_memory32_resource(byte_stream_buffer,
118 &bytes_consumed,
119 buffer,
120 &structure_size);
121
122 break;
123
124 case DWORD_ADDRESS_SPACE:
125 /*
126 * 32-Bit Address Resource
127 */
128 status = acpi_rs_address32_resource(byte_stream_buffer,
129 &bytes_consumed,
130 buffer,
131 &structure_size);
132
133 break;
134
135 case WORD_ADDRESS_SPACE:
136 /*
137 * 16-Bit Address Resource
138 */
139 status = acpi_rs_address16_resource(byte_stream_buffer,
140 &bytes_consumed,
141 buffer,
142 &structure_size);
143
144 break;
145
146 case EXTENDED_IRQ:
147 /*
148 * Extended IRQ
149 */
150 status = acpi_rs_extended_irq_resource(byte_stream_buffer,
151 &bytes_consumed,
152 buffer,
153 &structure_size);
154
155 break;
156
157 /* TBD: [Future] 64-bit not currently supported */
158 /*
159 case 0x8A:
160 break;
161 */
162
163 default:
164 /*
165 * If we get here, everything is out of sync,
166 * so exit with an error
167 */
168 return (AE_AML_ERROR);
169 break;
170 }
171 }
172
173 else {
174 /*
175 * Small Resource Type
176 * Only bits 7:3 are valid
177 */
178 resource_type >>= 3;
179
180 switch(resource_type) {
181 case IRQ_FORMAT:
182 /*
183 * IRQ Resource
184 */
185 status = acpi_rs_irq_resource(byte_stream_buffer,
186 &bytes_consumed,
187 buffer,
188 &structure_size);
189
190 break;
191
192 case DMA_FORMAT:
193 /*
194 * DMA Resource
195 */
196 status = acpi_rs_dma_resource(byte_stream_buffer,
197 &bytes_consumed,
198 buffer,
199 &structure_size);
200
201 break;
202
203 case START_DEPENDENT_TAG:
204 /*
205 * Start Dependent Functions Resource
206 */
207 status = acpi_rs_start_dependent_functions_resource(byte_stream_buffer,
208 &bytes_consumed,
209 buffer,
210 &structure_size);
211
212 break;
213
214 case END_DEPENDENT_TAG:
215 /*
216 * End Dependent Functions Resource
217 */
218 status = acpi_rs_end_dependent_functions_resource(byte_stream_buffer,
219 &bytes_consumed,
220 buffer,
221 &structure_size);
222
223 break;
224
225 case IO_PORT_DESCRIPTOR:
226 /*
227 * IO Port Resource
228 */
229 status = acpi_rs_io_resource(byte_stream_buffer,
230 &bytes_consumed,
231 buffer,
232 &structure_size);
233
234 break;
235
236 case FIXED_LOCATION_IO_DESCRIPTOR:
237 /*
238 * Fixed IO Port Resource
239 */
240 status = acpi_rs_fixed_io_resource(byte_stream_buffer,
241 &bytes_consumed,
242 buffer,
243 &structure_size);
244
245 break;
246
247 case SMALL_VENDOR_DEFINED:
248 /*
249 * Vendor Specific Resource
250 */
251 status = acpi_rs_vendor_resource(byte_stream_buffer,
252 &bytes_consumed,
253 buffer,
254 &structure_size);
255
256 break;
257
258 case END_TAG:
259 /*
260 * End Tag
261 */
262 status = acpi_rs_end_tag_resource(byte_stream_buffer,
263 &bytes_consumed,
264 buffer,
265 &structure_size);
266 end_tag_processed = TRUE;
267
268 break;
269
270 default:
271 /*
272 * If we get here, everything is out of sync,
273 * so exit with an error
274 */
275 return (AE_AML_ERROR);
276 break;
277
278 } /* switch */
279 } /* end else */
280
281 /*
282 * Update the return value and counter
283 */
284 bytes_parsed += bytes_consumed;
285
286 /*
287 * Set the byte stream to point to the next resource
288 */
289 byte_stream_buffer += bytes_consumed;
290
291 /*
292 * Set the Buffer to the next structure
293 */
294 *buffer += structure_size;
295
296 } /* end while */
297
298 /*
299 * Check the reason for exiting the while loop
300 */
301 if (TRUE != end_tag_processed) {
302 return (AE_AML_ERROR);
303 }
304
305 return (AE_OK);
306 }
307
308
309 /*******************************************************************************
310 *
311 * FUNCTION: Acpi_rs_list_to_byte_stream
312 *
313 * PARAMETERS: Linked_list - Pointer to the resource linked list
314 * Byte_steam_size_needed - Calculated size of the byte stream
315 * needed from calling
316 * Acpi_rs_calculate_byte_stream_length()
317 * The size of the Output_buffer is
318 * guaranteed to be >=
319 * Byte_stream_size_needed
320 * Output_buffer - Pointer to the buffer that will
321 * contain the byte stream
322 *
323 * RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code
324 *
325 * DESCRIPTION: Takes the resource linked list and parses it, creating a
326 * byte stream of resources in the caller's output buffer
327 *
328 ******************************************************************************/
329
330 ACPI_STATUS
331 acpi_rs_list_to_byte_stream (
332 RESOURCE *linked_list,
333 u32 byte_stream_size_needed,
334 u8 **output_buffer)
335 {
336 ACPI_STATUS status;
337 u8 *buffer = *output_buffer;
338 u32 bytes_consumed = 0;
339 u8 done = FALSE;
340
341
342 while (!done) {
343 switch (linked_list->id) {
344 case irq:
345 /*
346 * IRQ Resource
347 */
348 status = acpi_rs_irq_stream (linked_list,
349 &buffer,
350 &bytes_consumed);
351 break;
352
353 case dma:
354 /*
355 * DMA Resource
356 */
357 status = acpi_rs_dma_stream (linked_list,
358 &buffer,
359 &bytes_consumed);
360 break;
361
362 case start_dependent_functions:
363 /*
364 * Start Dependent Functions Resource
365 */
366 status = acpi_rs_start_dependent_functions_stream (linked_list,
367 &buffer,
368 &bytes_consumed);
369 break;
370
371 case end_dependent_functions:
372 /*
373 * End Dependent Functions Resource
374 */
375 status = acpi_rs_end_dependent_functions_stream (linked_list,
376 &buffer,
377 &bytes_consumed);
378 break;
379
380 case io:
381 /*
382 * IO Port Resource
383 */
384 status = acpi_rs_io_stream (linked_list,
385 &buffer,
386 &bytes_consumed);
387 break;
388
389 case fixed_io:
390 /*
391 * Fixed IO Port Resource
392 */
393 status = acpi_rs_fixed_io_stream (linked_list,
394 &buffer,
395 &bytes_consumed);
396 break;
397
398 case vendor_specific:
399 /*
400 * Vendor Defined Resource
401 */
402 status = acpi_rs_vendor_stream (linked_list,
403 &buffer,
404 &bytes_consumed);
405 break;
406
407 case end_tag:
408 /*
409 * End Tag
410 */
411 status = acpi_rs_end_tag_stream (linked_list,
412 &buffer,
413 &bytes_consumed);
414
415 /*
416 * An End Tag indicates the end of the Resource Template
417 */
418 done = TRUE;
419 break;
420
421 case memory24:
422 /*
423 * 24-Bit Memory Resource
424 */
425 status = acpi_rs_memory24_stream (linked_list,
426 &buffer,
427 &bytes_consumed);
428 break;
429
430 case memory32:
431 /*
432 * 32-Bit Memory Range Resource
433 */
434 status = acpi_rs_memory32_range_stream (linked_list,
435 &buffer,
436 &bytes_consumed);
437 break;
438
439 case fixed_memory32:
440 /*
441 * 32-Bit Fixed Memory Resource
442 */
443 status = acpi_rs_fixed_memory32_stream (linked_list,
444 &buffer,
445 &bytes_consumed);
446 break;
447
448 case address16:
449 /*
450 * 16-Bit Address Descriptor Resource
451 */
452 status = acpi_rs_address16_stream (linked_list,
453 &buffer,
454 &bytes_consumed);
455 break;
456
457 case address32:
458 /*
459 * 32-Bit Address Descriptor Resource
460 */
461 status = acpi_rs_address32_stream (linked_list,
462 &buffer,
463 &bytes_consumed);
464 break;
465
466 case extended_irq:
467 /*
468 * Extended IRQ Resource
469 */
470 status = acpi_rs_extended_irq_stream (linked_list,
471 &buffer,
472 &bytes_consumed);
473 break;
474
475 default:
476 /*
477 * If we get here, everything is out of sync,
478 * so exit with an error
479 */
480 return (AE_BAD_DATA);
481 break;
482
483 } /* switch (Linked_list->Id) */
484
485 /*
486 * Set the Buffer to point to the open byte
487 */
488 buffer += bytes_consumed;
489
490 /*
491 * Point to the next object
492 */
493 linked_list = (RESOURCE *) ((NATIVE_UINT) linked_list +
494 (NATIVE_UINT) linked_list->length);
495 }
496
497 return (AE_OK);
498 }
499