rscreate.c revision 70243
1/*******************************************************************************
2 *
3 * Module Name: rscreate - AcpiRsCreateResourceList
4 *                         AcpiRsCreatePciRoutingTable
5 *                         AcpiRsCreateByteStream
6 *              $Revision: 23 $
7 *
8 ******************************************************************************/
9
10/******************************************************************************
11 *
12 * 1. Copyright Notice
13 *
14 * Some or all of this work - Copyright (c) 1999, 2000, Intel Corp.
15 * All rights reserved.
16 *
17 * 2. License
18 *
19 * 2.1. This is your license from Intel Corp. under its intellectual property
20 * rights.  You may have additional license terms from the party that provided
21 * you this software, covering your right to use that party's intellectual
22 * property rights.
23 *
24 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
25 * copy of the source code appearing in this file ("Covered Code") an
26 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
27 * base code distributed originally by Intel ("Original Intel Code") to copy,
28 * make derivatives, distribute, use and display any portion of the Covered
29 * Code in any form, with the right to sublicense such rights; and
30 *
31 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
32 * license (with the right to sublicense), under only those claims of Intel
33 * patents that are infringed by the Original Intel Code, to make, use, sell,
34 * offer to sell, and import the Covered Code and derivative works thereof
35 * solely to the minimum extent necessary to exercise the above copyright
36 * license, and in no event shall the patent license extend to any additions
37 * to or modifications of the Original Intel Code.  No other license or right
38 * is granted directly or by implication, estoppel or otherwise;
39 *
40 * The above copyright and patent license is granted only if the following
41 * conditions are met:
42 *
43 * 3. Conditions
44 *
45 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
46 * Redistribution of source code of any substantial portion of the Covered
47 * Code or modification with rights to further distribute source must include
48 * the above Copyright Notice, the above License, this list of Conditions,
49 * and the following Disclaimer and Export Compliance provision.  In addition,
50 * Licensee must cause all Covered Code to which Licensee contributes to
51 * contain a file documenting the changes Licensee made to create that Covered
52 * Code and the date of any change.  Licensee must include in that file the
53 * documentation of any changes made by any predecessor Licensee.  Licensee
54 * must include a prominent statement that the modification is derived,
55 * directly or indirectly, from Original Intel Code.
56 *
57 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
58 * Redistribution of source code of any substantial portion of the Covered
59 * Code or modification without rights to further distribute source must
60 * include the following Disclaimer and Export Compliance provision in the
61 * documentation and/or other materials provided with distribution.  In
62 * addition, Licensee may not authorize further sublicense of source of any
63 * portion of the Covered Code, and must include terms to the effect that the
64 * license from Licensee to its licensee is limited to the intellectual
65 * property embodied in the software Licensee provides to its licensee, and
66 * not to intellectual property embodied in modifications its licensee may
67 * make.
68 *
69 * 3.3. Redistribution of Executable. Redistribution in executable form of any
70 * substantial portion of the Covered Code or modification must reproduce the
71 * above Copyright Notice, and the following Disclaimer and Export Compliance
72 * provision in the documentation and/or other materials provided with the
73 * distribution.
74 *
75 * 3.4. Intel retains all right, title, and interest in and to the Original
76 * Intel Code.
77 *
78 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
79 * Intel shall be used in advertising or otherwise to promote the sale, use or
80 * other dealings in products derived from or relating to the Covered Code
81 * without prior written authorization from Intel.
82 *
83 * 4. Disclaimer and Export Compliance
84 *
85 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
86 * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
87 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
88 * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
89 * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
90 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
91 * PARTICULAR PURPOSE.
92 *
93 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
94 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
95 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
96 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
97 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
98 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
99 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
100 * LIMITED REMEDY.
101 *
102 * 4.3. Licensee shall not export, either directly or indirectly, any of this
103 * software or system incorporating such software without first obtaining any
104 * required license or other approval from the U. S. Department of Commerce or
105 * any other agency or department of the United States Government.  In the
106 * event Licensee exports any such software from the United States or
107 * re-exports any such software from a foreign destination, Licensee shall
108 * ensure that the distribution and export/re-export of the software is in
109 * compliance with all laws, regulations, orders, or other restrictions of the
110 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
111 * any of its subsidiaries will export/re-export any technical data, process,
112 * software, or service, directly or indirectly, to any country for which the
113 * United States government or any agency thereof requires an export license,
114 * other governmental approval, or letter of assurance, without first obtaining
115 * such license, approval or letter.
116 *
117 *****************************************************************************/
118
119
120#define __RSCREATE_C__
121
122#include "acpi.h"
123#include "acresrc.h"
124
125#define _COMPONENT          RESOURCE_MANAGER
126        MODULE_NAME         ("rscreate")
127
128
129/*******************************************************************************
130 *
131 * FUNCTION:    AcpiRsCreateResourceList
132 *
133 * PARAMETERS:
134 *              ByteStreamBuffer        - Pointer to the resource byte stream
135 *              OutputBuffer            - Pointer to the user's buffer
136 *              OutputBufferLength      - Pointer to the size of OutputBuffer
137 *
138 * RETURN:      Status  - AE_OK if okay, else a valid ACPI_STATUS code
139 *              If OutputBuffer is not large enough, OutputBufferLength
140 *              indicates how large OutputBuffer should be, else it
141 *              indicates how may UINT8 elements of OutputBuffer are valid.
142 *
143 * DESCRIPTION: Takes the byte stream returned from a _CRS, _PRS control method
144 *              execution and parses the stream to create a linked list
145 *              of device resources.
146 *
147 ******************************************************************************/
148
149ACPI_STATUS
150AcpiRsCreateResourceList (
151    ACPI_OPERAND_OBJECT     *ByteStreamBuffer,
152    UINT8                   *OutputBuffer,
153    UINT32                  *OutputBufferLength)
154{
155
156    ACPI_STATUS             Status;
157    UINT8                   *ByteStreamStart = NULL;
158    UINT32                  ListSizeNeeded = 0;
159    UINT32                  ByteStreamBufferLength = 0;
160
161
162    FUNCTION_TRACE ("RsCreateResourceList");
163
164
165    DEBUG_PRINT (VERBOSE_INFO, ("RsCreateResourceList: ByteStreamBuffer = %p\n",
166                 ByteStreamBuffer));
167
168    /*
169     * Params already validated, so we don't re-validate here
170     */
171
172    ByteStreamBufferLength = ByteStreamBuffer->Buffer.Length;
173    ByteStreamStart = ByteStreamBuffer->Buffer.Pointer;
174
175    /*
176     * Pass the ByteStreamBuffer into a module that can calculate
177     * the buffer size needed for the linked list
178     */
179    Status = AcpiRsCalculateListLength (ByteStreamStart,
180                                        ByteStreamBufferLength,
181                                        &ListSizeNeeded);
182
183    DEBUG_PRINT (VERBOSE_INFO,
184        ("RsCreateResourceList: Status=%X ListSizeNeeded=%X\n",
185        Status, ListSizeNeeded));
186
187    /*
188     * Exit with the error passed back
189     */
190    if (ACPI_FAILURE (Status))
191    {
192        return_ACPI_STATUS (Status);
193    }
194
195    /*
196     * If the linked list will fit into the available buffer
197     * call to fill in the list
198     */
199
200    if (ListSizeNeeded <= *OutputBufferLength)
201    {
202        /*
203         * Zero out the return buffer before proceeding
204         */
205        MEMSET (OutputBuffer, 0x00, *OutputBufferLength);
206
207        Status = AcpiRsByteStreamToList (ByteStreamStart,
208                                         ByteStreamBufferLength,
209                                         &OutputBuffer);
210
211        /*
212         * Exit with the error passed back
213         */
214        if (ACPI_FAILURE (Status))
215        {
216            return_ACPI_STATUS (Status);
217        }
218
219        DEBUG_PRINT (VERBOSE_INFO, ("RsByteStreamToList: OutputBuffer = %p\n",
220                                     OutputBuffer));
221    }
222
223    else
224    {
225        *OutputBufferLength = ListSizeNeeded;
226        return_ACPI_STATUS (AE_BUFFER_OVERFLOW);
227    }
228
229    *OutputBufferLength = ListSizeNeeded;
230    return_ACPI_STATUS (AE_OK);
231
232}
233
234
235/*******************************************************************************
236 *
237 * FUNCTION:    AcpiRsCreatePciRoutingTable
238 *
239 * PARAMETERS:
240 *              PackageObject           - Pointer to an ACPI_OPERAND_OBJECT
241 *                                          package
242 *              OutputBuffer            - Pointer to the user's buffer
243 *              OutputBufferLength      - Size of OutputBuffer
244 *
245 * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code.
246 *              If the OutputBuffer is too small, the error will be
247 *              AE_BUFFER_OVERFLOW and OutputBufferLength will point
248 *              to the size buffer needed.
249 *
250 * DESCRIPTION: Takes the ACPI_OPERAND_OBJECT  package and creates a
251 *              linked list of PCI interrupt descriptions
252 *
253 ******************************************************************************/
254
255ACPI_STATUS
256AcpiRsCreatePciRoutingTable (
257    ACPI_OPERAND_OBJECT     *PackageObject,
258    UINT8                   *OutputBuffer,
259    UINT32                  *OutputBufferLength)
260{
261    UINT8                   *Buffer = OutputBuffer;
262    ACPI_OPERAND_OBJECT     **TopObjectList = NULL;
263    ACPI_OPERAND_OBJECT     **SubObjectList = NULL;
264    ACPI_OPERAND_OBJECT     *PackageElement = NULL;
265    UINT32                  BufferSizeNeeded = 0;
266    UINT32                  NumberOfElements = 0;
267    UINT32                  Index = 0;
268    PCI_ROUTING_TABLE       *UserPrt = NULL;
269    ACPI_STATUS             Status;
270
271
272    FUNCTION_TRACE ("RsCreatePciRoutingTable");
273
274
275    /*
276     * Params already validated, so we don't re-validate here
277     */
278
279    Status = AcpiRsCalculatePciRoutingTableLength(PackageObject,
280                                                  &BufferSizeNeeded);
281
282    DEBUG_PRINT (VERBOSE_INFO,
283        ("RsCreatePciRoutingTable: BufferSizeNeeded = %X\n",
284        BufferSizeNeeded));
285
286    /*
287     * If the data will fit into the available buffer
288     * call to fill in the list
289     */
290    if (BufferSizeNeeded <= *OutputBufferLength)
291    {
292        /*
293         * Zero out the return buffer before proceeding
294         */
295        MEMSET (OutputBuffer, 0x00, *OutputBufferLength);
296
297        /*
298         * Loop through the ACPI_INTERNAL_OBJECTS - Each object should
299         * contain a UINT32 Address, a UINT8 Pin, a Name and a UINT8
300         * SourceIndex.
301         */
302        TopObjectList       = PackageObject->Package.Elements;
303        NumberOfElements    = PackageObject->Package.Count;
304        UserPrt             = (PCI_ROUTING_TABLE *) Buffer;
305
306
307        Buffer = ROUND_PTR_UP_TO_8 (Buffer, UINT8);
308
309        for (Index = 0; Index < NumberOfElements; Index++)
310        {
311            /*
312             * Point UserPrt past this current structure
313             *
314             * NOTE: On the first iteration, UserPrt->Length will
315             * be zero because we cleared the return buffer earlier
316             */
317            Buffer += UserPrt->Length;
318            UserPrt = (PCI_ROUTING_TABLE *) Buffer;
319
320
321            /*
322             * Fill in the Length field with the information we
323             * have at this point.
324             * The minus one is to subtract the size of the
325             * UINT8 Source[1] member because it is added below.
326             */
327            UserPrt->Length = (sizeof (PCI_ROUTING_TABLE) - 1);
328
329            /*
330             * Dereference the sub-package
331             */
332            PackageElement = *TopObjectList;
333
334            /*
335             * The SubObjectList will now point to an array of
336             * the four IRQ elements: Address, Pin, Source and
337             * SourceIndex
338             */
339            SubObjectList = PackageElement->Package.Elements;
340
341            /*
342             * Dereference the Address
343             */
344            if (ACPI_TYPE_NUMBER == (*SubObjectList)->Common.Type)
345            {
346                UserPrt->Data.Address =
347                        (*SubObjectList)->Number.Value;
348            }
349
350            else
351            {
352                return_ACPI_STATUS (AE_BAD_DATA);
353            }
354
355            /*
356             * Dereference the Pin
357             */
358            SubObjectList++;
359
360            if (ACPI_TYPE_NUMBER == (*SubObjectList)->Common.Type)
361            {
362                UserPrt->Data.Pin =
363                        (UINT32) (*SubObjectList)->Number.Value;
364            }
365
366            else
367            {
368                return_ACPI_STATUS (AE_BAD_DATA);
369            }
370
371            /*
372             * Dereference the Source Name
373             */
374            SubObjectList++;
375
376            if (ACPI_TYPE_STRING == (*SubObjectList)->Common.Type)
377            {
378                STRCPY (UserPrt->Data.Source,
379                      (*SubObjectList)->String.Pointer);
380
381                /*
382                 * Add to the Length field the length of the string
383                 */
384                UserPrt->Length += (*SubObjectList)->String.Length;
385            }
386
387            else
388            {
389                /*
390                 * If this is a number, then the Source Name
391                 * is NULL, since the entire buffer was zeroed
392                 * out, we can leave this alone.
393                 */
394                if (ACPI_TYPE_NUMBER == (*SubObjectList)->Common.Type)
395                {
396                    /*
397                     * Add to the Length field the length of
398                     * the UINT32 NULL
399                     */
400                    UserPrt->Length += sizeof (UINT32);
401                }
402
403                else
404                {
405                    return_ACPI_STATUS (AE_BAD_DATA);
406                }
407            }
408
409            /* Now align the current length */
410
411            UserPrt->Length = ROUND_UP_TO_64BITS (UserPrt->Length);
412
413            /*
414             * Dereference the Source Index
415             */
416            SubObjectList++;
417
418            if (ACPI_TYPE_NUMBER == (*SubObjectList)->Common.Type)
419            {
420                UserPrt->Data.SourceIndex =
421                        (UINT32) (*SubObjectList)->Number.Value;
422            }
423
424            else
425            {
426                return_ACPI_STATUS (AE_BAD_DATA);
427            }
428
429            /*
430             * Point to the next ACPI_OPERAND_OBJECT
431             */
432            TopObjectList++;
433        }
434
435        DEBUG_PRINT (VERBOSE_INFO,
436            ("RsCreatePciRoutingTable: OutputBuffer = %p\n",
437            OutputBuffer));
438    }
439
440    else
441    {
442        *OutputBufferLength = BufferSizeNeeded;
443
444        return_ACPI_STATUS (AE_BUFFER_OVERFLOW);
445    }
446
447    /*
448     * Report the amount of buffer used
449     */
450    *OutputBufferLength = BufferSizeNeeded;
451
452    return_ACPI_STATUS (AE_OK);
453}
454
455
456/*******************************************************************************
457 *
458 * FUNCTION:    AcpiRsCreateByteStream
459 *
460 * PARAMETERS:
461 *              LinkedListBuffer        - Pointer to the resource linked list
462 *              OutputBuffer            - Pointer to the user's buffer
463 *              OutputBufferLength      - Size of OutputBuffer
464 *
465 * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code.
466 *              If the OutputBuffer is too small, the error will be
467 *              AE_BUFFER_OVERFLOW and OutputBufferLength will point
468 *              to the size buffer needed.
469 *
470 * DESCRIPTION: Takes the linked list of device resources and
471 *              creates a bytestream to be used as input for the
472 *              _SRS control method.
473 *
474 ******************************************************************************/
475
476ACPI_STATUS
477AcpiRsCreateByteStream (
478    RESOURCE                *LinkedListBuffer,
479    UINT8                   *OutputBuffer,
480    UINT32                  *OutputBufferLength)
481{
482    ACPI_STATUS             Status;
483    UINT32                  ByteStreamSizeNeeded = 0;
484
485
486    FUNCTION_TRACE ("RsCreateByteStream");
487
488
489    DEBUG_PRINT (VERBOSE_INFO,
490        ("RsCreateByteStream: LinkedListBuffer = %p\n",
491        LinkedListBuffer));
492
493    /*
494     * Params already validated, so we don't re-validate here
495     *
496     * Pass the LinkedListBuffer into a module that can calculate
497     * the buffer size needed for the byte stream.
498     */
499    Status = AcpiRsCalculateByteStreamLength (LinkedListBuffer,
500                                              &ByteStreamSizeNeeded);
501
502    DEBUG_PRINT (VERBOSE_INFO,
503        ("RsCreateByteStream: ByteStreamSizeNeeded=%X, %s\n",
504        ByteStreamSizeNeeded,
505        AcpiCmFormatException (Status)));
506
507    /*
508     * Exit with the error passed back
509     */
510    if (ACPI_FAILURE (Status))
511    {
512        return_ACPI_STATUS (Status);
513    }
514
515    /*
516     * If the linked list will fit into the available buffer
517     * call to fill in the list
518     */
519
520    if (ByteStreamSizeNeeded <= *OutputBufferLength)
521    {
522        /*
523         * Zero out the return buffer before proceeding
524         */
525        MEMSET (OutputBuffer, 0x00, *OutputBufferLength);
526
527        Status = AcpiRsListToByteStream (LinkedListBuffer,
528                                         ByteStreamSizeNeeded,
529                                         &OutputBuffer);
530
531        /*
532         * Exit with the error passed back
533         */
534        if (ACPI_FAILURE (Status))
535        {
536            return_ACPI_STATUS (Status);
537        }
538
539        DEBUG_PRINT (VERBOSE_INFO,
540            ("RsListToByteStream: OutputBuffer = %p\n",
541            OutputBuffer));
542    }
543    else
544    {
545        *OutputBufferLength = ByteStreamSizeNeeded;
546        return_ACPI_STATUS (AE_BUFFER_OVERFLOW);
547    }
548
549    return_ACPI_STATUS (AE_OK);
550}
551
552