OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [acpi/] [resources/] [rsaddr.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.