Subversion Repositories Kolibri OS

Rev

Rev 1498 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1498 serge 1
/******************************************************************************
2
 *
3
 * Module Name: dmrestag - Add tags to resource descriptors (Application-level)
4
 *
5
 *****************************************************************************/
6
 
7
/******************************************************************************
8
 *
9
 * 1. Copyright Notice
10
 *
2216 Serge 11
 * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
1498 serge 12
 * All rights reserved.
13
 *
14
 * 2. License
15
 *
16
 * 2.1. This is your license from Intel Corp. under its intellectual property
17
 * rights.  You may have additional license terms from the party that provided
18
 * you this software, covering your right to use that party's intellectual
19
 * property rights.
20
 *
21
 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22
 * copy of the source code appearing in this file ("Covered Code") an
23
 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24
 * base code distributed originally by Intel ("Original Intel Code") to copy,
25
 * make derivatives, distribute, use and display any portion of the Covered
26
 * Code in any form, with the right to sublicense such rights; and
27
 *
28
 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29
 * license (with the right to sublicense), under only those claims of Intel
30
 * patents that are infringed by the Original Intel Code, to make, use, sell,
31
 * offer to sell, and import the Covered Code and derivative works thereof
32
 * solely to the minimum extent necessary to exercise the above copyright
33
 * license, and in no event shall the patent license extend to any additions
34
 * to or modifications of the Original Intel Code.  No other license or right
35
 * is granted directly or by implication, estoppel or otherwise;
36
 *
37
 * The above copyright and patent license is granted only if the following
38
 * conditions are met:
39
 *
40
 * 3. Conditions
41
 *
42
 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43
 * Redistribution of source code of any substantial portion of the Covered
44
 * Code or modification with rights to further distribute source must include
45
 * the above Copyright Notice, the above License, this list of Conditions,
46
 * and the following Disclaimer and Export Compliance provision.  In addition,
47
 * Licensee must cause all Covered Code to which Licensee contributes to
48
 * contain a file documenting the changes Licensee made to create that Covered
49
 * Code and the date of any change.  Licensee must include in that file the
50
 * documentation of any changes made by any predecessor Licensee.  Licensee
51
 * must include a prominent statement that the modification is derived,
52
 * directly or indirectly, from Original Intel Code.
53
 *
54
 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55
 * Redistribution of source code of any substantial portion of the Covered
56
 * Code or modification without rights to further distribute source must
57
 * include the following Disclaimer and Export Compliance provision in the
58
 * documentation and/or other materials provided with distribution.  In
59
 * addition, Licensee may not authorize further sublicense of source of any
60
 * portion of the Covered Code, and must include terms to the effect that the
61
 * license from Licensee to its licensee is limited to the intellectual
62
 * property embodied in the software Licensee provides to its licensee, and
63
 * not to intellectual property embodied in modifications its licensee may
64
 * make.
65
 *
66
 * 3.3. Redistribution of Executable. Redistribution in executable form of any
67
 * substantial portion of the Covered Code or modification must reproduce the
68
 * above Copyright Notice, and the following Disclaimer and Export Compliance
69
 * provision in the documentation and/or other materials provided with the
70
 * distribution.
71
 *
72
 * 3.4. Intel retains all right, title, and interest in and to the Original
73
 * Intel Code.
74
 *
75
 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76
 * Intel shall be used in advertising or otherwise to promote the sale, use or
77
 * other dealings in products derived from or relating to the Covered Code
78
 * without prior written authorization from Intel.
79
 *
80
 * 4. Disclaimer and Export Compliance
81
 *
82
 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83
 * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84
 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
85
 * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
86
 * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
87
 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88
 * PARTICULAR PURPOSE.
89
 *
90
 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91
 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92
 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93
 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94
 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95
 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
96
 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97
 * LIMITED REMEDY.
98
 *
99
 * 4.3. Licensee shall not export, either directly or indirectly, any of this
100
 * software or system incorporating such software without first obtaining any
101
 * required license or other approval from the U. S. Department of Commerce or
102
 * any other agency or department of the United States Government.  In the
103
 * event Licensee exports any such software from the United States or
104
 * re-exports any such software from a foreign destination, Licensee shall
105
 * ensure that the distribution and export/re-export of the software is in
106
 * compliance with all laws, regulations, orders, or other restrictions of the
107
 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108
 * any of its subsidiaries will export/re-export any technical data, process,
109
 * software, or service, directly or indirectly, to any country for which the
110
 * United States government or any agency thereof requires an export license,
111
 * other governmental approval, or letter of assurance, without first obtaining
112
 * such license, approval or letter.
113
 *
114
 *****************************************************************************/
115
 
116
 
117
#include "acpi.h"
118
#include "accommon.h"
119
#include "acparser.h"
120
#include "acdisasm.h"
121
#include "acnamesp.h"
122
#include "amlcode.h"
123
 
124
/* This module used for application-level code only */
125
 
126
#define _COMPONENT          ACPI_CA_DISASSEMBLER
127
        ACPI_MODULE_NAME    ("dmrestag")
128
 
129
/* Local prototypes */
130
 
131
static void
132
AcpiDmUpdateResourceName (
133
    ACPI_NAMESPACE_NODE     *ResourceNode);
134
 
135
static char *
136
AcpiDmSearchTagList (
137
    UINT32                  BitIndex,
138
    ACPI_RESOURCE_TAG       *TagList);
139
 
140
static char *
141
AcpiDmGetResourceTag (
142
    UINT32                  BitIndex,
143
    AML_RESOURCE            *Resource,
144
    UINT8                   ResourceIndex);
145
 
146
static char *
147
AcpiGetTagPathname (
148
    ACPI_NAMESPACE_NODE     *BufferNode,
149
    ACPI_NAMESPACE_NODE     *ResourceNode,
150
    UINT32                  BitIndex);
151
 
152
static ACPI_NAMESPACE_NODE *
153
AcpiDmGetResourceNode (
154
    ACPI_NAMESPACE_NODE     *BufferNode,
155
    UINT32                  BitIndex);
156
 
157
static ACPI_STATUS
158
AcpiDmAddResourceToNamespace (
159
    UINT8                   *Aml,
160
    UINT32                  Length,
161
    UINT32                  Offset,
162
    UINT8                   ResourceIndex,
163
    void                    *Context);
164
 
165
static void
166
AcpiDmAddResourcesToNamespace (
167
    ACPI_NAMESPACE_NODE     *BufferNode,
168
    ACPI_PARSE_OBJECT       *Op);
169
 
170
 
171
/******************************************************************************
172
 *
173
 * Resource Tag tables
174
 *
175
 * These are the predefined tags that refer to elements of a resource
176
 * descriptor. Each name and offset is defined in the ACPI specification.
177
 *
178
 * Each table entry contains the bit offset of the field and the associated
179
 * name.
180
 *
181
 ******************************************************************************/
182
 
183
static ACPI_RESOURCE_TAG        AcpiDmIrqTags[] =
184
{
185
    {( 1 * 8),      ACPI_RESTAG_INTERRUPT},
186
    {( 3 * 8) + 0,  ACPI_RESTAG_INTERRUPTTYPE},
187
    {( 3 * 8) + 3,  ACPI_RESTAG_INTERRUPTLEVEL},
188
    {( 3 * 8) + 4,  ACPI_RESTAG_INTERRUPTSHARE},
189
    {0,             NULL}
190
};
191
 
192
static ACPI_RESOURCE_TAG        AcpiDmDmaTags[] =
193
{
194
    {( 1 * 8),      ACPI_RESTAG_DMA},
195
    {( 2 * 8) + 0,  ACPI_RESTAG_XFERTYPE},
196
    {( 2 * 8) + 2,  ACPI_RESTAG_BUSMASTER},
197
    {( 2 * 8) + 5,  ACPI_RESTAG_DMATYPE},
198
    {0,             NULL}
199
};
200
 
201
static ACPI_RESOURCE_TAG        AcpiDmIoTags[] =
202
{
203
    {( 1 * 8) + 0,  ACPI_RESTAG_DECODE},
204
    {( 2 * 8),      ACPI_RESTAG_MINADDR},
205
    {( 4 * 8),      ACPI_RESTAG_MAXADDR},
206
    {( 6 * 8),      ACPI_RESTAG_ALIGNMENT},
207
    {( 7 * 8),      ACPI_RESTAG_LENGTH},
208
    {0,             NULL}
209
};
210
 
211
static ACPI_RESOURCE_TAG        AcpiDmFixedIoTags[] =
212
{
213
    {( 1 * 8),      ACPI_RESTAG_BASEADDRESS},
214
    {( 3 * 8),      ACPI_RESTAG_LENGTH},
215
    {0,             NULL}
216
};
217
 
218
static ACPI_RESOURCE_TAG        AcpiDmMemory24Tags[] =
219
{
220
    {( 3 * 8) + 0,  ACPI_RESTAG_READWRITETYPE},
221
    {( 4 * 8),      ACPI_RESTAG_MINADDR},
222
    {( 6 * 8),      ACPI_RESTAG_MAXADDR},
223
    {( 8 * 8),      ACPI_RESTAG_ALIGNMENT},
224
    {(10 * 8),      ACPI_RESTAG_LENGTH},
225
    {0,             NULL}
226
};
227
 
228
static ACPI_RESOURCE_TAG        AcpiDmRegisterTags[] =
229
{
230
    {( 3 * 8),      ACPI_RESTAG_ADDRESSSPACE},
231
    {( 4 * 8),      ACPI_RESTAG_REGISTERBITWIDTH},
232
    {( 5 * 8),      ACPI_RESTAG_REGISTERBITOFFSET},
233
    {( 6 * 8),      ACPI_RESTAG_ACCESSSIZE},
234
    {( 7 * 8),      ACPI_RESTAG_ADDRESS},
235
    {0,             NULL}
236
};
237
 
238
static ACPI_RESOURCE_TAG        AcpiDmMemory32Tags[] =
239
{
240
    {( 3 * 8) + 0,  ACPI_RESTAG_READWRITETYPE},
241
    {( 4 * 8),      ACPI_RESTAG_MINADDR},
242
    {( 8 * 8),      ACPI_RESTAG_MAXADDR},
243
    {(12 * 8),      ACPI_RESTAG_ALIGNMENT},
244
    {(16 * 8),      ACPI_RESTAG_LENGTH},
245
    {0,             NULL}
246
};
247
 
248
static ACPI_RESOURCE_TAG        AcpiDmFixedMemory32Tags[] =
249
{
250
    {( 3 * 8) + 0,  ACPI_RESTAG_READWRITETYPE},
251
    {( 4 * 8),      ACPI_RESTAG_BASEADDRESS},
252
    {( 8 * 8),      ACPI_RESTAG_LENGTH},
253
    {0,             NULL}
254
};
255
 
256
static ACPI_RESOURCE_TAG        AcpiDmInterruptTags[] =
257
{
258
    {( 3 * 8) + 1,  ACPI_RESTAG_INTERRUPTTYPE},
259
    {( 3 * 8) + 2,  ACPI_RESTAG_INTERRUPTLEVEL},
260
    {( 3 * 8) + 3,  ACPI_RESTAG_INTERRUPTSHARE},
261
    {( 5 * 8),      ACPI_RESTAG_INTERRUPT},
262
    {0,             NULL}
263
};
264
 
265
static ACPI_RESOURCE_TAG        AcpiDmAddress16Tags[] =
266
{
267
    {( 4 * 8) + 1,  ACPI_RESTAG_DECODE},
268
    {( 4 * 8) + 2,  ACPI_RESTAG_MINTYPE},
269
    {( 4 * 8) + 3,  ACPI_RESTAG_MAXTYPE},
270
    {( 6 * 8),      ACPI_RESTAG_GRANULARITY},
271
    {( 8 * 8),      ACPI_RESTAG_MINADDR},
272
    {(10 * 8),      ACPI_RESTAG_MAXADDR},
273
    {(12 * 8),      ACPI_RESTAG_TRANSLATION},
274
    {(14 * 8),      ACPI_RESTAG_LENGTH},
275
    {0,             NULL}
276
};
277
 
278
static ACPI_RESOURCE_TAG        AcpiDmAddress32Tags[] =
279
{
280
    {( 4 * 8) + 1,  ACPI_RESTAG_DECODE},
281
    {( 4 * 8) + 2,  ACPI_RESTAG_MINTYPE},
282
    {( 4 * 8) + 3,  ACPI_RESTAG_MAXTYPE},
283
    {( 6 * 8),      ACPI_RESTAG_GRANULARITY},
284
    {(10 * 8),      ACPI_RESTAG_MINADDR},
285
    {(14 * 8),      ACPI_RESTAG_MAXADDR},
286
    {(18 * 8),      ACPI_RESTAG_TRANSLATION},
287
    {(22 * 8),      ACPI_RESTAG_LENGTH},
288
    {0,             NULL}
289
};
290
 
291
static ACPI_RESOURCE_TAG        AcpiDmAddress64Tags[] =
292
{
293
    {( 4 * 8) + 1,  ACPI_RESTAG_DECODE},
294
    {( 4 * 8) + 2,  ACPI_RESTAG_MINTYPE},
295
    {( 4 * 8) + 3,  ACPI_RESTAG_MAXTYPE},
296
    {( 6 * 8),      ACPI_RESTAG_GRANULARITY},
297
    {(14 * 8),      ACPI_RESTAG_MINADDR},
298
    {(22 * 8),      ACPI_RESTAG_MAXADDR},
299
    {(30 * 8),      ACPI_RESTAG_TRANSLATION},
300
    {(38 * 8),      ACPI_RESTAG_LENGTH},
301
    {0,             NULL}
302
};
303
 
304
static ACPI_RESOURCE_TAG        AcpiDmExtendedAddressTags[] =
305
{
306
    {( 4 * 8) + 1,  ACPI_RESTAG_DECODE},
307
    {( 4 * 8) + 2,  ACPI_RESTAG_MINTYPE},
308
    {( 4 * 8) + 3,  ACPI_RESTAG_MAXTYPE},
309
    {( 8 * 8),      ACPI_RESTAG_GRANULARITY},
310
    {(16 * 8),      ACPI_RESTAG_MINADDR},
311
    {(24 * 8),      ACPI_RESTAG_MAXADDR},
312
    {(32 * 8),      ACPI_RESTAG_TRANSLATION},
313
    {(40 * 8),      ACPI_RESTAG_LENGTH},
314
    {(48 * 8),      ACPI_RESTAG_TYPESPECIFICATTRIBUTES},
315
    {0,             NULL}
316
};
317
 
318
/* Special-case tables for the type-specific flags */
319
 
320
static ACPI_RESOURCE_TAG        AcpiDmMemoryFlagTags[] =
321
{
322
    {( 5 * 8) + 0,  ACPI_RESTAG_READWRITETYPE},
323
    {( 5 * 8) + 1,  ACPI_RESTAG_MEMTYPE},
324
    {( 5 * 8) + 3,  ACPI_RESTAG_MEMATTRIBUTES},
325
    {( 5 * 8) + 5,  ACPI_RESTAG_TYPE},
326
    {0,             NULL}
327
};
328
 
329
static ACPI_RESOURCE_TAG        AcpiDmIoFlagTags[] =
330
{
331
    {( 5 * 8) + 0,  ACPI_RESTAG_RANGETYPE},
332
    {( 5 * 8) + 4,  ACPI_RESTAG_TYPE},
333
    {( 5 * 8) + 5,  ACPI_RESTAG_TRANSTYPE},
334
    {0,             NULL}
335
};
336
 
337
 
338
/* Dispatch table used to obtain the correct tag table for a descriptor */
339
 
340
static ACPI_RESOURCE_TAG        *AcpiGbl_ResourceTags [] =
341
{
342
    /* Small descriptors */
343
 
344
    NULL,                           /* 0x00, Reserved */
345
    NULL,                           /* 0x01, Reserved */
346
    NULL,                           /* 0x02, Reserved */
347
    NULL,                           /* 0x03, Reserved */
348
    AcpiDmIrqTags,                  /* 0x04, ACPI_RESOURCE_NAME_IRQ_FORMAT */
349
    AcpiDmDmaTags,                  /* 0x05, ACPI_RESOURCE_NAME_DMA_FORMAT */
350
    NULL,                           /* 0x06, ACPI_RESOURCE_NAME_START_DEPENDENT */
351
    NULL,                           /* 0x07, ACPI_RESOURCE_NAME_END_DEPENDENT */
352
    AcpiDmIoTags,                   /* 0x08, ACPI_RESOURCE_NAME_IO_PORT */
353
    AcpiDmFixedIoTags,              /* 0x09, ACPI_RESOURCE_NAME_FIXED_IO_PORT */
354
    NULL,                           /* 0x0A, Reserved */
355
    NULL,                           /* 0x0B, Reserved */
356
    NULL,                           /* 0x0C, Reserved */
357
    NULL,                           /* 0x0D, Reserved */
358
    NULL,                           /* 0x0E, ACPI_RESOURCE_NAME_SMALL_VENDOR */
359
    NULL,                           /* 0x0F, ACPI_RESOURCE_NAME_END_TAG (not used) */
360
 
361
    /* Large descriptors */
362
 
363
    NULL,                           /* 0x00, Reserved */
364
    AcpiDmMemory24Tags,             /* 0x01, ACPI_RESOURCE_NAME_MEMORY_24 */
365
    AcpiDmRegisterTags,             /* 0x02, ACPI_RESOURCE_NAME_GENERIC_REGISTER */
366
    NULL,                           /* 0x03, Reserved */
367
    NULL,                           /* 0x04, ACPI_RESOURCE_NAME_LARGE_VENDOR */
368
    AcpiDmMemory32Tags,             /* 0x05, ACPI_RESOURCE_NAME_MEMORY_32 */
369
    AcpiDmFixedMemory32Tags,        /* 0x06, ACPI_RESOURCE_NAME_FIXED_MEMORY_32 */
370
    AcpiDmAddress32Tags,            /* 0x07, ACPI_RESOURCE_NAME_DWORD_ADDRESS_SPACE */
371
    AcpiDmAddress16Tags,            /* 0x08, ACPI_RESOURCE_NAME_WORD_ADDRESS_SPACE */
372
    AcpiDmInterruptTags,            /* 0x09, ACPI_RESOURCE_NAME_EXTENDED_XRUPT */
373
    AcpiDmAddress64Tags,            /* 0x0A, ACPI_RESOURCE_NAME_QWORD_ADDRESS_SPACE */
374
    AcpiDmExtendedAddressTags       /* 0x0B, ACPI_RESOURCE_NAME_EXTENDED_ADDRESS_SPACE */
375
};
376
 
377
 
378
/*
379
 * Globals used to generate unique resource descriptor names. We use names that
380
 * start with underscore and a prefix letter that is not used by other ACPI
381
 * reserved names. To this, we append hex 0x00 through 0xFF. These 5 prefixes
382
 * allow for 5*256 = 1280 unique names, probably sufficient for any single ASL
383
 * file. If this becomes too small, we can use alpha+numerals for a total
384
 * of 5*36*36 = 6480.
385
 */
386
#define ACPI_NUM_RES_PREFIX     5
387
 
388
static UINT32                   AcpiGbl_NextResourceId = 0;
389
static UINT8                    AcpiGbl_NextPrefix = 0;
390
static char                     AcpiGbl_Prefix[ACPI_NUM_RES_PREFIX] =
391
                                    {'Y','Z','J','K','X'};
392
 
393
 
394
/*******************************************************************************
395
 *
396
 * FUNCTION:    AcpiDmCheckResourceReference
397
 *
398
 * PARAMETERS:  Op                  - Parse Op for the AML opcode
399
 *              WalkState           - Current walk state (with valid scope)
400
 *
401
 * RETURN:      None
402
 *
403
 * DESCRIPTION: Convert a reference to a resource descriptor to a symbolic
404
 *              reference if possible
405
 *
406
 * NOTE:        Bit index is used to transparently handle both resource bit
407
 *              fields and byte fields.
408
 *
409
 ******************************************************************************/
410
 
411
void
412
AcpiDmCheckResourceReference (
413
    ACPI_PARSE_OBJECT       *Op,
414
    ACPI_WALK_STATE         *WalkState)
415
{
416
    ACPI_STATUS             Status;
417
    ACPI_PARSE_OBJECT       *BufferNameOp;
418
    ACPI_PARSE_OBJECT       *IndexOp;
419
    ACPI_NAMESPACE_NODE     *BufferNode;
420
    ACPI_NAMESPACE_NODE     *ResourceNode;
421
    const ACPI_OPCODE_INFO  *OpInfo;
422
    char                    *Pathname;
423
    UINT32                  BitIndex;
424
 
425
 
426
    /* We are only interested in the CreateXxxxField opcodes */
427
 
428
    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
429
    if (OpInfo->Type != AML_TYPE_CREATE_FIELD)
430
    {
431
        return;
432
    }
433
 
434
    /* Get the buffer term operand */
435
 
436
    BufferNameOp = AcpiPsGetDepthNext (NULL, Op);
437
 
438
    /* Must be a named buffer, not an arg or local or method call */
439
 
440
    if (BufferNameOp->Common.AmlOpcode != AML_INT_NAMEPATH_OP)
441
    {
442
        return;
443
    }
444
 
445
    /* Get the Index term, must be an integer constant to convert */
446
 
447
    IndexOp = BufferNameOp->Common.Next;
448
    OpInfo = AcpiPsGetOpcodeInfo (IndexOp->Common.AmlOpcode);
449
    if (OpInfo->ObjectType != ACPI_TYPE_INTEGER)
450
    {
451
        return;
452
    }
453
 
454
    /* Get the bit offset of the descriptor within the buffer */
455
 
456
    if ((Op->Common.AmlOpcode == AML_CREATE_BIT_FIELD_OP) ||
457
        (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP))
458
    {
459
        /* Index operand is a bit offset */
460
 
461
        BitIndex = (UINT32) IndexOp->Common.Value.Integer;
462
    }
463
    else
464
    {
465
        /* Index operand is a byte offset, convert to bits */
466
 
467
        BitIndex = (UINT32) ACPI_MUL_8 (IndexOp->Common.Value.Integer);
468
    }
469
 
470
    /* Lookup the buffer in the namespace */
471
 
472
    Status = AcpiNsLookup (WalkState->ScopeInfo,
473
                BufferNameOp->Common.Value.String, ACPI_TYPE_BUFFER,
474
                ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, WalkState,
475
                &BufferNode);
476
    if (ACPI_FAILURE (Status))
477
    {
478
        return;
479
    }
480
 
481
    /* Validate object type, we must have a buffer */
482
 
483
    if (BufferNode->Type != ACPI_TYPE_BUFFER)
484
    {
485
        return;
486
    }
487
 
488
    /* Find the resource descriptor node corresponding to the index */
489
 
490
    ResourceNode = AcpiDmGetResourceNode (BufferNode, BitIndex);
491
    if (!ResourceNode)
492
    {
493
        return;
494
    }
495
 
496
    /* Translate the Index to a resource tag pathname */
497
 
498
    Pathname = AcpiGetTagPathname (BufferNode, ResourceNode, BitIndex);
499
    if (Pathname)
500
    {
501
        /* Complete the conversion of the Index to a symbol */
502
 
503
        IndexOp->Common.AmlOpcode = AML_INT_NAMEPATH_OP;
504
        IndexOp->Common.Value.String = Pathname;
505
    }
506
}
507
 
508
 
509
/*******************************************************************************
510
 *
511
 * FUNCTION:    AcpiDmGetResourceNode
512
 *
513
 * PARAMETERS:  BufferNode          - Node for the parent buffer
514
 *              BitIndex            - Index into the resource descriptor
515
 *
516
 * RETURN:      Namespace node for the resource descriptor. NULL if not found
517
 *
518
 * DESCRIPTION: Find a resource descriptor that corresponds to the bit index
519
 *
520
 ******************************************************************************/
521
 
522
static ACPI_NAMESPACE_NODE *
523
AcpiDmGetResourceNode (
524
    ACPI_NAMESPACE_NODE     *BufferNode,
525
    UINT32                  BitIndex)
526
{
527
    ACPI_NAMESPACE_NODE     *Node;
528
    UINT32                  ByteIndex = ACPI_DIV_8 (BitIndex);
529
 
530
 
531
    /*
532
     * Child list contains an entry for each resource descriptor. Find
533
     * the descriptor that corresponds to the Index.
534
     *
535
     * If there are no children, this is not a resource template
536
     */
537
    Node = BufferNode->Child;
538
    while (Node)
539
    {
540
        /*
541
         * Check if the Index falls within this resource.
542
         *
543
         * Value contains the resource offset, Object contains the resource
544
         * length (both in bytes)
545
         */
546
        if ((ByteIndex >= Node->Value) &&
547
            (ByteIndex < (Node->Value + Node->Length)))
548
        {
549
            return (Node);
550
        }
551
 
552
        Node = Node->Peer;
553
    }
554
 
555
    return (NULL);
556
}
557
 
558
 
559
/*******************************************************************************
560
 *
561
 * FUNCTION:    AcpiGetTagPathname
562
 *
563
 * PARAMETERS:  BufferNode          - Node for the parent buffer
564
 *              ResourceNode        - Node for a resource descriptor
565
 *              BitIndex            - Index into the resource descriptor
566
 *
567
 * RETURN:      Full pathname for a resource tag. NULL if no match.
568
 *              Path is returned in AML (packed) format.
569
 *
570
 * DESCRIPTION: Convert a BitIndex into a symbolic resource tag (full pathname)
571
 *
572
 ******************************************************************************/
573
 
574
static char *
575
AcpiGetTagPathname (
576
    ACPI_NAMESPACE_NODE     *BufferNode,
577
    ACPI_NAMESPACE_NODE     *ResourceNode,
578
    UINT32                  BitIndex)
579
{
580
    ACPI_STATUS             Status;
581
    UINT32                  ResourceBitIndex;
582
    UINT8                   ResourceTableIndex;
583
    ACPI_SIZE               RequiredSize;
584
    char                    *Pathname;
585
    AML_RESOURCE            *Aml;
586
    ACPI_PARSE_OBJECT       *Op;
587
    char                    *InternalPath;
588
    char                    *Tag;
589
 
590
 
591
    /* Get the Op that contains the actual buffer data */
592
 
593
    Op = BufferNode->Op->Common.Value.Arg;
594
    Op = Op->Common.Next;
595
    if (!Op)
596
    {
597
        return (NULL);
598
    }
599
 
600
    /* Get the individual resource descriptor and validate it */
601
 
602
    Aml = ACPI_CAST_PTR (AML_RESOURCE,
603
            &Op->Named.Data[ResourceNode->Value]);
604
 
605
    Status = AcpiUtValidateResource (Aml, &ResourceTableIndex);
606
    if (ACPI_FAILURE (Status))
607
    {
608
        return (NULL);
609
    }
610
 
611
    /* Get offset into this descriptor (from offset into entire buffer) */
612
 
613
    ResourceBitIndex = BitIndex - ACPI_MUL_8 (ResourceNode->Value);
614
 
615
    /* Get the tag associated with this resource descriptor and offset */
616
 
617
    Tag = AcpiDmGetResourceTag (ResourceBitIndex, Aml, ResourceTableIndex);
618
    if (!Tag)
619
    {
620
        return (NULL);
621
    }
622
 
623
    /*
624
     * Now that we know that we have a reference that can be converted to a
625
     * symbol, change the name of the resource to a unique name.
626
     */
627
    AcpiDmUpdateResourceName (ResourceNode);
628
 
629
    /* Get the full pathname to the parent buffer */
630
 
631
    RequiredSize = AcpiNsGetPathnameLength (BufferNode);
632
    if (!RequiredSize)
633
    {
634
        return (NULL);
635
    }
636
 
637
    Pathname = ACPI_ALLOCATE_ZEROED (RequiredSize + ACPI_PATH_SEGMENT_LENGTH);
638
    if (!Pathname)
639
    {
640
        return (NULL);
641
    }
642
 
643
    Status = AcpiNsBuildExternalPath (BufferNode, RequiredSize, Pathname);
644
    if (ACPI_FAILURE (Status))
645
    {
646
        return (NULL);
647
    }
648
 
649
    /*
650
     * Create the full path to the resource and tag by: remove the buffer name,
651
     * append the resource descriptor name, append a dot, append the tag name.
652
     *
653
     * TBD: Always using the full path is a bit brute force, the path can be
654
     * often be optimized with carats (if the original buffer namepath is a
655
     * single nameseg). This doesn't really matter, because these paths do not
656
     * end up in the final compiled AML, it's just an appearance issue for the
657
     * disassembled code.
658
     */
659
    Pathname[ACPI_STRLEN (Pathname) - ACPI_NAME_SIZE] = 0;
660
    ACPI_STRNCAT (Pathname, ResourceNode->Name.Ascii, ACPI_NAME_SIZE);
661
    ACPI_STRCAT (Pathname, ".");
662
    ACPI_STRNCAT (Pathname, Tag, ACPI_NAME_SIZE);
663
 
664
    /* Internalize the namepath to AML format */
665
 
666
    AcpiNsInternalizeName (Pathname, &InternalPath);
667
    ACPI_FREE (Pathname);
668
    return (InternalPath);
669
}
670
 
671
 
672
/*******************************************************************************
673
 *
674
 * FUNCTION:    AcpiDmUpdateResourceName
675
 *
676
 * PARAMETERS:  ResourceNode        - Node for a resource descriptor
677
 *
678
 * RETURN:      Stores new name in the ResourceNode
679
 *
680
 * DESCRIPTION: Create a new, unique name for a resource descriptor. Used by
681
 *              both the disassembly of the descriptor itself and any symbolic
682
 *              references to the descriptor. Ignored if a unique name has
683
 *              already been assigned to the resource.
684
 *
685
 * NOTE: Single threaded, suitable for applications only!
686
 *
687
 ******************************************************************************/
688
 
689
static void
690
AcpiDmUpdateResourceName (
691
    ACPI_NAMESPACE_NODE     *ResourceNode)
692
{
693
    char                    Name[ACPI_NAME_SIZE];
694
 
695
 
696
    /* Ignore if a unique name has already been assigned */
697
 
698
    if (ResourceNode->Name.Integer != ACPI_DEFAULT_RESNAME)
699
    {
700
        return;
701
    }
702
 
703
    /* Generate a new ACPI name for the descriptor */
704
 
705
    Name[0] = '_';
706
    Name[1] = AcpiGbl_Prefix[AcpiGbl_NextPrefix];
2216 Serge 707
    Name[2] = AcpiUtHexToAsciiChar ((UINT64) AcpiGbl_NextResourceId, 4);
708
    Name[3] = AcpiUtHexToAsciiChar ((UINT64) AcpiGbl_NextResourceId, 0);
1498 serge 709
 
710
    /* Update globals for next name */
711
 
712
    AcpiGbl_NextResourceId++;
713
    if (AcpiGbl_NextResourceId >= 256)
714
    {
715
        AcpiGbl_NextResourceId = 0;
716
        AcpiGbl_NextPrefix++;
717
        if (AcpiGbl_NextPrefix > ACPI_NUM_RES_PREFIX)
718
        {
719
            AcpiGbl_NextPrefix = 0;
720
        }
721
    }
722
 
723
    /* Change the resource descriptor name */
724
 
725
    ResourceNode->Name.Integer = *ACPI_CAST_PTR (UINT32, &Name[0]);
726
}
727
 
728
 
729
/*******************************************************************************
730
 *
731
 * FUNCTION:    AcpiDmGetResourceTag
732
 *
733
 * PARAMETERS:  BitIndex            - Index into the resource descriptor
734
 *              Resource            - Pointer to the raw resource data
735
 *              ResourceIndex       - Index correspoinding to the resource type
736
 *
737
 * RETURN:      Pointer to the resource tag (ACPI_NAME). NULL if no match.
738
 *
739
 * DESCRIPTION: Convert a BitIndex into a symbolic resource tag.
740
 *
741
 ******************************************************************************/
742
 
743
static char *
744
AcpiDmGetResourceTag (
745
    UINT32                  BitIndex,
746
    AML_RESOURCE            *Resource,
747
    UINT8                   ResourceIndex)
748
{
749
    ACPI_RESOURCE_TAG       *TagList;
750
    char                    *Tag = NULL;
751
 
752
 
753
    /* Get the tag list for this resource descriptor type */
754
 
755
    TagList = AcpiGbl_ResourceTags[ResourceIndex];
756
    if (!TagList)
757
    {
758
        /* There are no tags for this resource type */
759
 
760
        return (NULL);
761
    }
762
 
763
    /*
764
     * Handle the type-specific flags field for the address descriptors.
765
     * Kindof brute force, but just blindly search for an index match.
766
     */
767
    switch (Resource->DescriptorType)
768
    {
769
    case ACPI_RESOURCE_NAME_ADDRESS16:
770
    case ACPI_RESOURCE_NAME_ADDRESS32:
771
    case ACPI_RESOURCE_NAME_ADDRESS64:
772
    case ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64:
773
 
774
        if (Resource->Address.ResourceType == ACPI_ADDRESS_TYPE_MEMORY_RANGE)
775
        {
776
            Tag = AcpiDmSearchTagList (BitIndex, AcpiDmMemoryFlagTags);
777
        }
778
        else if (Resource->Address.ResourceType == ACPI_ADDRESS_TYPE_IO_RANGE)
779
        {
780
            Tag = AcpiDmSearchTagList (BitIndex, AcpiDmIoFlagTags);
781
        }
782
 
783
        /* If we found a match, all done. Else, drop to normal search below */
784
 
785
        if (Tag)
786
        {
787
            return (Tag);
788
        }
789
        break;
790
 
791
    default:
792
        break;
793
    }
794
 
795
    /* Search the tag list for this descriptor type */
796
 
797
    Tag = AcpiDmSearchTagList (BitIndex, TagList);
798
    return (Tag);
799
}
800
 
801
 
802
/*******************************************************************************
803
 *
804
 * FUNCTION:    AcpiDmSearchTagList
805
 *
806
 * PARAMETERS:  BitIndex            - Index into the resource descriptor
807
 *              TagList             - List to search
808
 *
809
 * RETURN:      Pointer to a tag (ACPI_NAME). NULL if no match found.
810
 *
811
 * DESCRIPTION: Search a tag list for a match to the input BitIndex. Matches
812
 *              a fixed offset to a symbolic resource tag name.
813
 *
814
 ******************************************************************************/
815
 
816
static char *
817
AcpiDmSearchTagList (
818
    UINT32                  BitIndex,
819
    ACPI_RESOURCE_TAG       *TagList)
820
{
821
 
822
    /*
823
     * Walk the null-terminated tag list to find a matching bit offset.
824
     * We are looking for an exact match.
825
     */
826
    for ( ; TagList->Tag; TagList++)
827
    {
828
        if (BitIndex == TagList->BitIndex)
829
        {
830
            return (TagList->Tag);
831
        }
832
    }
833
 
834
    /* A matching offset was not found */
835
 
836
    return (NULL);
837
}
838
 
839
 
840
/*******************************************************************************
841
 *
842
 * FUNCTION:    AcpiDmFindResources
843
 *
844
 * PARAMETERS:  Root                - Root of the parse tree
845
 *
846
 * RETURN:      None
847
 *
848
 * DESCRIPTION: Add all ResourceTemplate declarations to the namespace. Each
849
 *              resource descriptor in each template is given a node -- used
850
 *              for later conversion of resource references to symbolic refs.
851
 *
852
 ******************************************************************************/
853
 
854
void
855
AcpiDmFindResources (
856
    ACPI_PARSE_OBJECT       *Root)
857
{
858
    ACPI_PARSE_OBJECT       *Op = Root;
859
    ACPI_PARSE_OBJECT       *Parent;
860
 
861
 
862
    /* Walk the entire parse tree */
863
 
864
    while (Op)
865
    {
866
        /* We are interested in Buffer() declarations */
867
 
868
        if (Op->Common.AmlOpcode == AML_BUFFER_OP)
869
        {
870
            /* And only declarations of the form Name (XXXX, Buffer()... ) */
871
 
872
            Parent = Op->Common.Parent;
873
            if (Parent->Common.AmlOpcode == AML_NAME_OP)
874
            {
875
                /*
876
                 * If the buffer is a resource template, add the individual
877
                 * resource descriptors to the namespace, as children of the
878
                 * buffer node.
879
                 */
880
                if (ACPI_SUCCESS (AcpiDmIsResourceTemplate (Op)))
881
                {
882
                    Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE;
883
                    AcpiDmAddResourcesToNamespace (Parent->Common.Node, Op);
884
                }
885
            }
886
        }
887
 
888
        Op = AcpiPsGetDepthNext (Root, Op);
889
    }
890
}
891
 
892
 
893
/*******************************************************************************
894
 *
895
 * FUNCTION:    AcpiDmAddResourcesToNamespace
896
 *
897
 * PARAMETERS:  BufferNode          - Node for the parent buffer
898
 *              Op                  - Parse op for the buffer
899
 *
900
 * RETURN:      None
901
 *
902
 * DESCRIPTION: Add an entire resource template to the namespace. Each
903
 *              resource descriptor is added as a namespace node.
904
 *
905
 ******************************************************************************/
906
 
907
static void
908
AcpiDmAddResourcesToNamespace (
909
    ACPI_NAMESPACE_NODE     *BufferNode,
910
    ACPI_PARSE_OBJECT       *Op)
911
{
912
    ACPI_PARSE_OBJECT       *NextOp;
913
 
914
 
915
    /* Get to the ByteData list */
916
 
917
    NextOp = Op->Common.Value.Arg;
918
    NextOp = NextOp->Common.Next;
919
    if (!NextOp)
920
    {
921
        return;
922
    }
923
 
924
    /* Set Node and Op to point to each other */
925
 
926
    BufferNode->Op = Op;
927
    Op->Common.Node = BufferNode;
928
 
929
    /*
930
     * Insert each resource into the namespace
931
     * NextOp contains the Aml pointer and the Aml length
932
     */
933
    AcpiUtWalkAmlResources ((UINT8 *) NextOp->Named.Data,
934
        (ACPI_SIZE) NextOp->Common.Value.Integer,
935
        AcpiDmAddResourceToNamespace, BufferNode);
936
}
937
 
938
 
939
/*******************************************************************************
940
 *
941
 * FUNCTION:    AcpiDmAddResourceToNamespace
942
 *
943
 * PARAMETERS:  ACPI_WALK_AML_CALLBACK
944
 *              BufferNode              - Node for the parent buffer
945
 *
946
 * RETURN:      Status
947
 *
948
 * DESCRIPTION: Add one resource descriptor to the namespace as a child of the
949
 *              parent buffer. The same name is used for each descriptor. This
950
 *              is changed later to a unique name if the resource is actually
951
 *              referenced by an AML operator.
952
 *
953
 ******************************************************************************/
954
 
955
static ACPI_STATUS
956
AcpiDmAddResourceToNamespace (
957
    UINT8                   *Aml,
958
    UINT32                  Length,
959
    UINT32                  Offset,
960
    UINT8                   ResourceIndex,
961
    void                    *Context)
962
{
963
    ACPI_STATUS             Status;
964
    ACPI_GENERIC_STATE      ScopeInfo;
965
    ACPI_NAMESPACE_NODE     *Node;
966
 
967
 
968
    /* TBD: Don't need to add descriptors that have no tags defined? */
969
 
970
    /* Add the resource to the namespace, as child of the buffer */
971
 
972
    ScopeInfo.Scope.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Context);
973
    Status = AcpiNsLookup (&ScopeInfo, "_TMP", ACPI_TYPE_LOCAL_RESOURCE,
974
                ACPI_IMODE_LOAD_PASS2,
975
                ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_PREFIX_IS_SCOPE,
976
                NULL, &Node);
977
    if (ACPI_FAILURE (Status))
978
    {
979
        return (AE_OK);
980
    }
981
 
982
    /* Set the name to the default, changed later if resource is referenced */
983
 
984
    Node->Name.Integer = ACPI_DEFAULT_RESNAME;
985
 
986
    /* Save the offset of the descriptor (within the original buffer) */
987
 
988
    Node->Value = Offset;
989
    Node->Length = Length;
990
    return (AE_OK);
991
}
992