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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*******************************************************************************
2
 *
3
 * Module Name: rsirq - IRQ resource descriptors
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    ("rsirq")
50
 
51
 
52
/*******************************************************************************
53
 *
54
 * FUNCTION:    acpi_rs_irq_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_irq_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
        u16                             temp16 = 0;
83
        u8                              temp8 = 0;
84
        u8                              index;
85
        u8                              i;
86
        acpi_size                       struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_irq);
87
 
88
 
89
        ACPI_FUNCTION_TRACE ("rs_irq_resource");
90
 
91
 
92
        /*
93
         * The number of bytes consumed are contained in the descriptor
94
         *  (Bits:0-1)
95
         */
96
        temp8 = *buffer;
97
        *bytes_consumed = (temp8 & 0x03) + 1;
98
        output_struct->id = ACPI_RSTYPE_IRQ;
99
 
100
        /*
101
         * Point to the 16-bits of Bytes 1 and 2
102
         */
103
        buffer += 1;
104
        ACPI_MOVE_16_TO_16 (&temp16, buffer);
105
 
106
        output_struct->data.irq.number_of_interrupts = 0;
107
 
108
        /* Decode the IRQ bits */
109
 
110
        for (i = 0, index = 0; index < 16; index++) {
111
                if ((temp16 >> index) & 0x01) {
112
                        output_struct->data.irq.interrupts[i] = index;
113
                        i++;
114
                }
115
        }
116
 
117
        /* Zero interrupts is valid */
118
 
119
        output_struct->data.irq.number_of_interrupts = i;
120
        if (i > 0) {
121
                /*
122
                 * Calculate the structure size based upon the number of interrupts
123
                 */
124
                struct_size += ((acpi_size) i - 1) * 4;
125
        }
126
 
127
        /*
128
         * Point to Byte 3 if it is used
129
         */
130
        if (4 == *bytes_consumed) {
131
                buffer += 2;
132
                temp8 = *buffer;
133
 
134
                /*
135
                 * Check for HE, LL interrupts
136
                 */
137
                switch (temp8 & 0x09) {
138
                case 0x01: /* HE */
139
                        output_struct->data.irq.edge_level = ACPI_EDGE_SENSITIVE;
140
                        output_struct->data.irq.active_high_low = ACPI_ACTIVE_HIGH;
141
                        break;
142
 
143
                case 0x08: /* LL */
144
                        output_struct->data.irq.edge_level = ACPI_LEVEL_SENSITIVE;
145
                        output_struct->data.irq.active_high_low = ACPI_ACTIVE_LOW;
146
                        break;
147
 
148
                default:
149
                        /*
150
                         * Only _LL and _HE polarity/trigger interrupts
151
                         * are allowed (ACPI spec, section "IRQ Format")
152
                         * so 0x00 and 0x09 are illegal.
153
                         */
154
                        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
155
                                "Invalid interrupt polarity/trigger in resource list, %X\n", temp8));
156
                        return_ACPI_STATUS (AE_BAD_DATA);
157
                }
158
 
159
                /*
160
                 * Check for sharable
161
                 */
162
                output_struct->data.irq.shared_exclusive = (temp8 >> 3) & 0x01;
163
        }
164
        else {
165
                /*
166
                 * Assume Edge Sensitive, Active High, Non-Sharable
167
                 * per ACPI Specification
168
                 */
169
                output_struct->data.irq.edge_level = ACPI_EDGE_SENSITIVE;
170
                output_struct->data.irq.active_high_low = ACPI_ACTIVE_HIGH;
171
                output_struct->data.irq.shared_exclusive = ACPI_EXCLUSIVE;
172
        }
173
 
174
        /*
175
         * Set the Length parameter
176
         */
177
        output_struct->length = (u32) struct_size;
178
 
179
        /*
180
         * Return the final size of the structure
181
         */
182
        *structure_size = struct_size;
183
        return_ACPI_STATUS (AE_OK);
184
}
185
 
186
 
187
/*******************************************************************************
188
 *
189
 * FUNCTION:    acpi_rs_irq_stream
190
 *
191
 * PARAMETERS:  linked_list             - Pointer to the resource linked list
192
 *              output_buffer           - Pointer to the user's return buffer
193
 *              bytes_consumed          - Pointer to where the number of bytes
194
 *                                        used in the output_buffer is returned
195
 *
196
 * RETURN:      Status
197
 *
198
 * DESCRIPTION: Take the linked list resource structure and fills in the
199
 *              the appropriate bytes in a byte stream
200
 *
201
 ******************************************************************************/
202
 
203
acpi_status
204
acpi_rs_irq_stream (
205
        struct acpi_resource            *linked_list,
206
        u8                              **output_buffer,
207
        acpi_size                       *bytes_consumed)
208
{
209
        u8                              *buffer = *output_buffer;
210
        u16                             temp16 = 0;
211
        u8                              temp8 = 0;
212
        u8                              index;
213
        u8                              IRqinfo_byte_needed;
214
 
215
 
216
        ACPI_FUNCTION_TRACE ("rs_irq_stream");
217
 
218
 
219
        /*
220
         * The descriptor field is set based upon whether a third byte is
221
         * needed to contain the IRQ Information.
222
         */
223
        if (ACPI_EDGE_SENSITIVE == linked_list->data.irq.edge_level &&
224
                ACPI_ACTIVE_HIGH == linked_list->data.irq.active_high_low &&
225
                ACPI_EXCLUSIVE == linked_list->data.irq.shared_exclusive) {
226
                *buffer = 0x22;
227
                IRqinfo_byte_needed = FALSE;
228
        }
229
        else {
230
                *buffer = 0x23;
231
                IRqinfo_byte_needed = TRUE;
232
        }
233
 
234
        buffer += 1;
235
        temp16 = 0;
236
 
237
        /*
238
         * Loop through all of the interrupts and set the mask bits
239
         */
240
        for(index = 0;
241
                index < linked_list->data.irq.number_of_interrupts;
242
                index++) {
243
                temp8 = (u8) linked_list->data.irq.interrupts[index];
244
                temp16 |= 0x1 << temp8;
245
        }
246
 
247
        ACPI_MOVE_16_TO_16 (buffer, &temp16);
248
        buffer += 2;
249
 
250
        /*
251
         * Set the IRQ Info byte if needed.
252
         */
253
        if (IRqinfo_byte_needed) {
254
                temp8 = 0;
255
                temp8 = (u8) ((linked_list->data.irq.shared_exclusive &
256
                                 0x01) << 4);
257
 
258
                if (ACPI_LEVEL_SENSITIVE == linked_list->data.irq.edge_level &&
259
                        ACPI_ACTIVE_LOW == linked_list->data.irq.active_high_low) {
260
                        temp8 |= 0x08;
261
                }
262
                else {
263
                        temp8 |= 0x01;
264
                }
265
 
266
                *buffer = temp8;
267
                buffer += 1;
268
        }
269
 
270
        /*
271
         * Return the number of bytes consumed in this operation
272
         */
273
        *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
274
        return_ACPI_STATUS (AE_OK);
275
}
276
 
277
 
278
/*******************************************************************************
279
 *
280
 * FUNCTION:    acpi_rs_extended_irq_resource
281
 *
282
 * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
283
 *                                        stream
284
 *              bytes_consumed          - Pointer to where the number of bytes
285
 *                                        consumed the byte_stream_buffer is
286
 *                                        returned
287
 *              output_buffer           - Pointer to the return data buffer
288
 *              structure_size          - Pointer to where the number of bytes
289
 *                                        in the return data struct is returned
290
 *
291
 * RETURN:      Status
292
 *
293
 * DESCRIPTION: Take the resource byte stream and fill out the appropriate
294
 *              structure pointed to by the output_buffer. Return the
295
 *              number of bytes consumed from the byte stream.
296
 *
297
 ******************************************************************************/
298
 
299
acpi_status
300
acpi_rs_extended_irq_resource (
301
        u8                              *byte_stream_buffer,
302
        acpi_size                       *bytes_consumed,
303
        u8                              **output_buffer,
304
        acpi_size                       *structure_size)
305
{
306
        u8                              *buffer = byte_stream_buffer;
307
        struct acpi_resource            *output_struct = (void *) *output_buffer;
308
        u16                             temp16 = 0;
309
        u8                              temp8 = 0;
310
        u8                              *temp_ptr;
311
        u8                              index;
312
        acpi_size                       struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_ext_irq);
313
 
314
 
315
        ACPI_FUNCTION_TRACE ("rs_extended_irq_resource");
316
 
317
 
318
        /*
319
         * Point past the Descriptor to get the number of bytes consumed
320
         */
321
        buffer += 1;
322
        ACPI_MOVE_16_TO_16 (&temp16, buffer);
323
 
324
        /* Validate minimum descriptor length */
325
 
326
        if (temp16 < 6) {
327
                return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
328
        }
329
 
330
        *bytes_consumed = temp16 + 3;
331
        output_struct->id = ACPI_RSTYPE_EXT_IRQ;
332
 
333
        /*
334
         * Point to the Byte3
335
         */
336
        buffer += 2;
337
        temp8 = *buffer;
338
 
339
        output_struct->data.extended_irq.producer_consumer = temp8 & 0x01;
340
 
341
        /*
342
         * Check for Interrupt Mode
343
         *
344
         * The definition of an Extended IRQ changed between ACPI spec v1.0b
345
         * and ACPI spec 2.0 (section 6.4.3.6 in both).
346
         *
347
         * - Edge/Level are defined opposite in the table vs the headers
348
         */
349
        output_struct->data.extended_irq.edge_level =
350
                           (temp8 & 0x2) ? ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE;
351
 
352
        /*
353
         * Check Interrupt Polarity
354
         */
355
        output_struct->data.extended_irq.active_high_low = (temp8 >> 2) & 0x1;
356
 
357
        /*
358
         * Check for sharable
359
         */
360
        output_struct->data.extended_irq.shared_exclusive = (temp8 >> 3) & 0x01;
361
 
362
        /*
363
         * Point to Byte4 (IRQ Table length)
364
         */
365
        buffer += 1;
366
        temp8 = *buffer;
367
 
368
        /* Must have at least one IRQ */
369
 
370
        if (temp8 < 1) {
371
                return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
372
        }
373
 
374
        output_struct->data.extended_irq.number_of_interrupts = temp8;
375
 
376
        /*
377
         * Add any additional structure size to properly calculate
378
         * the next pointer at the end of this function
379
         */
380
        struct_size += (temp8 - 1) * 4;
381
 
382
        /*
383
         * Point to Byte5 (First IRQ Number)
384
         */
385
        buffer += 1;
386
 
387
        /*
388
         * Cycle through every IRQ in the table
389
         */
390
        for (index = 0; index < temp8; index++) {
391
                ACPI_MOVE_32_TO_32 (
392
                        &output_struct->data.extended_irq.interrupts[index], buffer);
393
 
394
                /* Point to the next IRQ */
395
 
396
                buffer += 4;
397
        }
398
 
399
        /*
400
         * This will leave us pointing to the Resource Source Index
401
         * If it is present, then save it off and calculate the
402
         * pointer to where the null terminated string goes:
403
         * Each Interrupt takes 32-bits + the 5 bytes of the
404
         * stream that are default.
405
         *
406
         * Note: Some resource descriptors will have an additional null, so
407
         * we add 1 to the length.
408
         */
409
        if (*bytes_consumed >
410
                ((acpi_size) output_struct->data.extended_irq.number_of_interrupts * 4) + (5 + 1)) {
411
                /* Dereference the Index */
412
 
413
                temp8 = *buffer;
414
                output_struct->data.extended_irq.resource_source.index = (u32) temp8;
415
 
416
                /* Point to the String */
417
 
418
                buffer += 1;
419
 
420
                /*
421
                 * Point the String pointer to the end of this structure.
422
                 */
423
                output_struct->data.extended_irq.resource_source.string_ptr =
424
                                (char *)((char *) output_struct + struct_size);
425
 
426
                temp_ptr = (u8 *) output_struct->data.extended_irq.resource_source.string_ptr;
427
 
428
                /* Copy the string into the buffer */
429
 
430
                index = 0;
431
                while (0x00 != *buffer) {
432
                        *temp_ptr = *buffer;
433
 
434
                        temp_ptr += 1;
435
                        buffer += 1;
436
                        index += 1;
437
                }
438
 
439
                /*
440
                 * Add the terminating null
441
                 */
442
                *temp_ptr = 0x00;
443
                output_struct->data.extended_irq.resource_source.string_length = index + 1;
444
 
445
                /*
446
                 * In order for the struct_size to fall on a 32-bit boundary,
447
                 * calculate the length of the string and expand the
448
                 * struct_size to the next 32-bit boundary.
449
                 */
450
                temp8 = (u8) (index + 1);
451
                struct_size += ACPI_ROUND_UP_to_32_bITS (temp8);
452
        }
453
        else {
454
                output_struct->data.extended_irq.resource_source.index = 0x00;
455
                output_struct->data.extended_irq.resource_source.string_length = 0;
456
                output_struct->data.extended_irq.resource_source.string_ptr = NULL;
457
        }
458
 
459
        /*
460
         * Set the Length parameter
461
         */
462
        output_struct->length = (u32) struct_size;
463
 
464
        /*
465
         * Return the final size of the structure
466
         */
467
        *structure_size = struct_size;
468
        return_ACPI_STATUS (AE_OK);
469
}
470
 
471
 
472
/*******************************************************************************
473
 *
474
 * FUNCTION:    acpi_rs_extended_irq_stream
475
 *
476
 * PARAMETERS:  linked_list             - Pointer to the resource linked list
477
 *              output_buffer           - Pointer to the user's return buffer
478
 *              bytes_consumed          - Pointer to where the number of bytes
479
 *                                        used in the output_buffer is returned
480
 *
481
 * RETURN:      Status
482
 *
483
 * DESCRIPTION: Take the linked list resource structure and fills in the
484
 *              the appropriate bytes in a byte stream
485
 *
486
 ******************************************************************************/
487
 
488
acpi_status
489
acpi_rs_extended_irq_stream (
490
        struct acpi_resource            *linked_list,
491
        u8                              **output_buffer,
492
        acpi_size                       *bytes_consumed)
493
{
494
        u8                              *buffer = *output_buffer;
495
        u16                             *length_field;
496
        u8                              temp8 = 0;
497
        u8                              index;
498
        char                            *temp_pointer = NULL;
499
 
500
 
501
        ACPI_FUNCTION_TRACE ("rs_extended_irq_stream");
502
 
503
 
504
        /*
505
         * The descriptor field is static
506
         */
507
        *buffer = 0x89;
508
        buffer += 1;
509
 
510
        /*
511
         * Set a pointer to the Length field - to be filled in later
512
         */
513
        length_field = ACPI_CAST_PTR (u16, buffer);
514
        buffer += 2;
515
 
516
        /*
517
         * Set the Interrupt vector flags
518
         */
519
        temp8 = (u8)(linked_list->data.extended_irq.producer_consumer & 0x01);
520
        temp8 |= ((linked_list->data.extended_irq.shared_exclusive & 0x01) << 3);
521
 
522
        /*
523
         * Set the Interrupt Mode
524
         *
525
         * The definition of an Extended IRQ changed between ACPI spec v1.0b
526
         * and ACPI spec 2.0 (section 6.4.3.6 in both).  This code does not
527
         * implement the more restrictive definition of 1.0b
528
         *
529
         * - Edge/Level are defined opposite in the table vs the headers
530
         */
531
        if (ACPI_EDGE_SENSITIVE == linked_list->data.extended_irq.edge_level) {
532
                temp8 |= 0x2;
533
        }
534
 
535
        /*
536
         * Set the Interrupt Polarity
537
         */
538
        temp8 |= ((linked_list->data.extended_irq.active_high_low & 0x1) << 2);
539
 
540
        *buffer = temp8;
541
        buffer += 1;
542
 
543
        /*
544
         * Set the Interrupt table length
545
         */
546
        temp8 = (u8) linked_list->data.extended_irq.number_of_interrupts;
547
 
548
        *buffer = temp8;
549
        buffer += 1;
550
 
551
        for (index = 0; index < linked_list->data.extended_irq.number_of_interrupts;
552
                 index++) {
553
                ACPI_MOVE_32_TO_32 (buffer,
554
                                  &linked_list->data.extended_irq.interrupts[index]);
555
                buffer += 4;
556
        }
557
 
558
        /*
559
         * Resource Source Index and Resource Source are optional
560
         */
561
        if (0 != linked_list->data.extended_irq.resource_source.string_length) {
562
                *buffer = (u8) linked_list->data.extended_irq.resource_source.index;
563
                buffer += 1;
564
 
565
                temp_pointer = (char *) buffer;
566
 
567
                /*
568
                 * Copy the string
569
                 */
570
                ACPI_STRCPY (temp_pointer,
571
                        linked_list->data.extended_irq.resource_source.string_ptr);
572
 
573
                /*
574
                 * Buffer needs to be set to the length of the sting + one for the
575
                 * terminating null
576
                 */
577
                buffer += (acpi_size)(ACPI_STRLEN (linked_list->data.extended_irq.resource_source.string_ptr) + 1);
578
        }
579
 
580
        /*
581
         * Return the number of bytes consumed in this operation
582
         */
583
        *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
584
 
585
        /*
586
         * Set the length field to the number of bytes consumed
587
         * minus the header size (3 bytes)
588
         */
589
        *length_field = (u16) (*bytes_consumed - 3);
590
        return_ACPI_STATUS (AE_OK);
591
}
592
 

powered by: WebSVN 2.1.0

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