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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
 
2
/******************************************************************************
3
 *
4
 * Module Name: exnames - interpreter/scanner name load/execute
5
 *
6
 *****************************************************************************/
7
 
8
/*
9
 * Copyright (C) 2000 - 2004, R. Byron Moore
10
 * All rights reserved.
11
 *
12
 * Redistribution and use in source and binary forms, with or without
13
 * modification, are permitted provided that the following conditions
14
 * are met:
15
 * 1. Redistributions of source code must retain the above copyright
16
 *    notice, this list of conditions, and the following disclaimer,
17
 *    without modification.
18
 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19
 *    substantially similar to the "NO WARRANTY" disclaimer below
20
 *    ("Disclaimer") and any redistribution must be conditioned upon
21
 *    including a substantially similar Disclaimer requirement for further
22
 *    binary redistribution.
23
 * 3. Neither the names of the above-listed copyright holders nor the names
24
 *    of any contributors may be used to endorse or promote products derived
25
 *    from this software without specific prior written permission.
26
 *
27
 * Alternatively, this software may be distributed under the terms of the
28
 * GNU General Public License ("GPL") version 2 as published by the Free
29
 * Software Foundation.
30
 *
31
 * NO WARRANTY
32
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36
 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42
 * POSSIBILITY OF SUCH DAMAGES.
43
 */
44
 
45
 
46
#include <acpi/acpi.h>
47
#include <acpi/acinterp.h>
48
#include <acpi/amlcode.h>
49
 
50
#define _COMPONENT          ACPI_EXECUTER
51
         ACPI_MODULE_NAME    ("exnames")
52
 
53
 
54
/* AML Package Length encodings */
55
 
56
#define ACPI_AML_PACKAGE_TYPE1   0x40
57
#define ACPI_AML_PACKAGE_TYPE2   0x4000
58
#define ACPI_AML_PACKAGE_TYPE3   0x400000
59
#define ACPI_AML_PACKAGE_TYPE4   0x40000000
60
 
61
 
62
/*******************************************************************************
63
 *
64
 * FUNCTION:    acpi_ex_allocate_name_string
65
 *
66
 * PARAMETERS:  prefix_count        - Count of parent levels. Special cases:
67
 *                                    (-1) = root,  0 = none
68
 *              num_name_segs       - count of 4-character name segments
69
 *
70
 * RETURN:      A pointer to the allocated string segment.  This segment must
71
 *              be deleted by the caller.
72
 *
73
 * DESCRIPTION: Allocate a buffer for a name string. Ensure allocated name
74
 *              string is long enough, and set up prefix if any.
75
 *
76
 ******************************************************************************/
77
 
78
char *
79
acpi_ex_allocate_name_string (
80
        u32                             prefix_count,
81
        u32                             num_name_segs)
82
{
83
        char                            *temp_ptr;
84
        char                            *name_string;
85
        u32                              size_needed;
86
 
87
        ACPI_FUNCTION_TRACE ("ex_allocate_name_string");
88
 
89
 
90
        /*
91
         * Allow room for all \ and ^ prefixes, all segments, and a multi_name_prefix.
92
         * Also, one byte for the null terminator.
93
         * This may actually be somewhat longer than needed.
94
         */
95
        if (prefix_count == ACPI_UINT32_MAX) {
96
                /* Special case for root */
97
 
98
                size_needed = 1 + (ACPI_NAME_SIZE * num_name_segs) + 2 + 1;
99
        }
100
        else {
101
                size_needed = prefix_count + (ACPI_NAME_SIZE * num_name_segs) + 2 + 1;
102
        }
103
 
104
        /*
105
         * Allocate a buffer for the name.
106
         * This buffer must be deleted by the caller!
107
         */
108
        name_string = ACPI_MEM_ALLOCATE (size_needed);
109
        if (!name_string) {
110
                ACPI_REPORT_ERROR (("ex_allocate_name_string: Could not allocate size %d\n", size_needed));
111
                return_PTR (NULL);
112
        }
113
 
114
        temp_ptr = name_string;
115
 
116
        /* Set up Root or Parent prefixes if needed */
117
 
118
        if (prefix_count == ACPI_UINT32_MAX) {
119
                *temp_ptr++ = AML_ROOT_PREFIX;
120
        }
121
        else {
122
                while (prefix_count--) {
123
                        *temp_ptr++ = AML_PARENT_PREFIX;
124
                }
125
        }
126
 
127
 
128
        /* Set up Dual or Multi prefixes if needed */
129
 
130
        if (num_name_segs > 2) {
131
                /* Set up multi prefixes   */
132
 
133
                *temp_ptr++ = AML_MULTI_NAME_PREFIX_OP;
134
                *temp_ptr++ = (char) num_name_segs;
135
        }
136
        else if (2 == num_name_segs) {
137
                /* Set up dual prefixes */
138
 
139
                *temp_ptr++ = AML_DUAL_NAME_PREFIX;
140
        }
141
 
142
        /*
143
         * Terminate string following prefixes. acpi_ex_name_segment() will
144
         * append the segment(s)
145
         */
146
        *temp_ptr = 0;
147
 
148
        return_PTR (name_string);
149
}
150
 
151
/*******************************************************************************
152
 *
153
 * FUNCTION:    acpi_ex_name_segment
154
 *
155
 * PARAMETERS:  interpreter_mode    - Current running mode (load1/Load2/Exec)
156
 *
157
 * RETURN:      Status
158
 *
159
 * DESCRIPTION: Execute a name segment (4 bytes)
160
 *
161
 ******************************************************************************/
162
 
163
acpi_status
164
acpi_ex_name_segment (
165
        u8                              **in_aml_address,
166
        char                            *name_string)
167
{
168
        char                            *aml_address = (void *) *in_aml_address;
169
        acpi_status                     status = AE_OK;
170
        u32                             index;
171
        char                            char_buf[5];
172
 
173
 
174
        ACPI_FUNCTION_TRACE ("ex_name_segment");
175
 
176
 
177
        /*
178
         * If first character is a digit, then we know that we aren't looking at a
179
         * valid name segment
180
         */
181
        char_buf[0] = *aml_address;
182
 
183
        if ('0' <= char_buf[0] && char_buf[0] <= '9') {
184
                ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "leading digit: %c\n", char_buf[0]));
185
                return_ACPI_STATUS (AE_CTRL_PENDING);
186
        }
187
 
188
        ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Bytes from stream:\n"));
189
 
190
        for (index = 0;
191
                (index < ACPI_NAME_SIZE) && (acpi_ut_valid_acpi_character (*aml_address));
192
                index++) {
193
                char_buf[index] = *aml_address++;
194
                ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "%c\n", char_buf[index]));
195
        }
196
 
197
 
198
        /* Valid name segment  */
199
 
200
        if (index == 4) {
201
                /* Found 4 valid characters */
202
 
203
                char_buf[4] = '\0';
204
 
205
                if (name_string) {
206
                        ACPI_STRCAT (name_string, char_buf);
207
                        ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
208
                                "Appended to - %s \n", name_string));
209
                }
210
                else {
211
                        ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
212
                                "No Name string - %s \n", char_buf));
213
                }
214
        }
215
        else if (index == 0) {
216
                /*
217
                 * First character was not a valid name character,
218
                 * so we are looking at something other than a name.
219
                 */
220
                ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
221
                        "Leading character is not alpha: %02Xh (not a name)\n",
222
                        char_buf[0]));
223
                status = AE_CTRL_PENDING;
224
        }
225
        else {
226
                /* Segment started with one or more valid characters, but fewer than 4 */
227
 
228
                status = AE_AML_BAD_NAME;
229
                ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Bad character %02x in name, at %p\n",
230
                        *aml_address, aml_address));
231
        }
232
 
233
        *in_aml_address = (u8 *) aml_address;
234
        return_ACPI_STATUS (status);
235
}
236
 
237
 
238
/*******************************************************************************
239
 *
240
 * FUNCTION:    acpi_ex_get_name_string
241
 *
242
 * PARAMETERS:  data_type           - Data type to be associated with this name
243
 *
244
 * RETURN:      Status
245
 *
246
 * DESCRIPTION: Get a name, including any prefixes.
247
 *
248
 ******************************************************************************/
249
 
250
acpi_status
251
acpi_ex_get_name_string (
252
        acpi_object_type                data_type,
253
        u8                              *in_aml_address,
254
        char                            **out_name_string,
255
        u32                             *out_name_length)
256
{
257
        acpi_status                     status = AE_OK;
258
        u8                              *aml_address = in_aml_address;
259
        char                            *name_string = NULL;
260
        u32                             num_segments;
261
        u32                             prefix_count = 0;
262
        u8                              has_prefix = FALSE;
263
 
264
 
265
        ACPI_FUNCTION_TRACE_PTR ("ex_get_name_string", aml_address);
266
 
267
 
268
        if (ACPI_TYPE_LOCAL_REGION_FIELD == data_type  ||
269
                ACPI_TYPE_LOCAL_BANK_FIELD == data_type    ||
270
                ACPI_TYPE_LOCAL_INDEX_FIELD == data_type) {
271
                /* Disallow prefixes for types associated with field_unit names */
272
 
273
                name_string = acpi_ex_allocate_name_string (0, 1);
274
                if (!name_string) {
275
                        status = AE_NO_MEMORY;
276
                }
277
                else {
278
                        status = acpi_ex_name_segment (&aml_address, name_string);
279
                }
280
        }
281
        else {
282
                /*
283
                 * data_type is not a field name.
284
                 * Examine first character of name for root or parent prefix operators
285
                 */
286
                switch (*aml_address) {
287
                case AML_ROOT_PREFIX:
288
 
289
                        ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "root_prefix(\\) at %p\n", aml_address));
290
 
291
                        /*
292
                         * Remember that we have a root_prefix --
293
                         * see comment in acpi_ex_allocate_name_string()
294
                         */
295
                        aml_address++;
296
                        prefix_count = ACPI_UINT32_MAX;
297
                        has_prefix = TRUE;
298
                        break;
299
 
300
 
301
                case AML_PARENT_PREFIX:
302
 
303
                        /* Increment past possibly multiple parent prefixes */
304
 
305
                        do {
306
                                ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "parent_prefix (^) at %p\n", aml_address));
307
 
308
                                aml_address++;
309
                                prefix_count++;
310
 
311
                        } while (*aml_address == AML_PARENT_PREFIX);
312
 
313
                        has_prefix = TRUE;
314
                        break;
315
 
316
 
317
                default:
318
 
319
                        /* Not a prefix character */
320
 
321
                        break;
322
                }
323
 
324
 
325
                /* Examine first character of name for name segment prefix operator */
326
 
327
                switch (*aml_address) {
328
                case AML_DUAL_NAME_PREFIX:
329
 
330
                        ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "dual_name_prefix at %p\n", aml_address));
331
 
332
                        aml_address++;
333
                        name_string = acpi_ex_allocate_name_string (prefix_count, 2);
334
                        if (!name_string) {
335
                                status = AE_NO_MEMORY;
336
                                break;
337
                        }
338
 
339
                        /* Indicate that we processed a prefix */
340
 
341
                        has_prefix = TRUE;
342
 
343
                        status = acpi_ex_name_segment (&aml_address, name_string);
344
                        if (ACPI_SUCCESS (status)) {
345
                                status = acpi_ex_name_segment (&aml_address, name_string);
346
                        }
347
                        break;
348
 
349
 
350
                case AML_MULTI_NAME_PREFIX_OP:
351
 
352
                        ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "multi_name_prefix at %p\n", aml_address));
353
 
354
                        /* Fetch count of segments remaining in name path */
355
 
356
                        aml_address++;
357
                        num_segments = *aml_address;
358
 
359
                        name_string = acpi_ex_allocate_name_string (prefix_count, num_segments);
360
                        if (!name_string) {
361
                                status = AE_NO_MEMORY;
362
                                break;
363
                        }
364
 
365
                        /* Indicate that we processed a prefix */
366
 
367
                        aml_address++;
368
                        has_prefix = TRUE;
369
 
370
                        while (num_segments &&
371
                                        (status = acpi_ex_name_segment (&aml_address, name_string)) == AE_OK) {
372
                                num_segments--;
373
                        }
374
 
375
                        break;
376
 
377
 
378
                case 0:
379
 
380
                        /* null_name valid as of 8-12-98 ASL/AML Grammar Update */
381
 
382
                        if (prefix_count == ACPI_UINT32_MAX) {
383
                                ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "name_seg is \"\\\" followed by NULL\n"));
384
                        }
385
 
386
                        /* Consume the NULL byte */
387
 
388
                        aml_address++;
389
                        name_string = acpi_ex_allocate_name_string (prefix_count, 0);
390
                        if (!name_string) {
391
                                status = AE_NO_MEMORY;
392
                                break;
393
                        }
394
 
395
                        break;
396
 
397
 
398
                default:
399
 
400
                        /* Name segment string */
401
 
402
                        name_string = acpi_ex_allocate_name_string (prefix_count, 1);
403
                        if (!name_string) {
404
                                status = AE_NO_MEMORY;
405
                                break;
406
                        }
407
 
408
                        status = acpi_ex_name_segment (&aml_address, name_string);
409
                        break;
410
                }
411
        }
412
 
413
        if (AE_CTRL_PENDING == status && has_prefix) {
414
                /* Ran out of segments after processing a prefix */
415
 
416
                ACPI_REPORT_ERROR (
417
                        ("ex_do_name: Malformed Name at %p\n", name_string));
418
                status = AE_AML_BAD_NAME;
419
        }
420
 
421
        *out_name_string = name_string;
422
        *out_name_length = (u32) (aml_address - in_aml_address);
423
 
424
        return_ACPI_STATUS (status);
425
}
426
 
427
 

powered by: WebSVN 2.1.0

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