update for HEAD-2003091401
[reactos.git] / drivers / bus / acpi / utils / cmobject.c
1 /******************************************************************************
2  *
3  * Module Name: cmobject - ACPI object create/delete/size/cache routines
4  *              $Revision$
5  *
6  *****************************************************************************/
7
8 /*
9  *  Copyright (C) 2000, 2001 R. Byron Moore
10  *
11  *  This program is free software; you can redistribute it and/or modify
12  *  it under the terms of the GNU General Public License as published by
13  *  the Free Software Foundation; either version 2 of the License, or
14  *  (at your option) any later version.
15  *
16  *  This program is distributed in the hope that it will be useful,
17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *  GNU General Public License for more details.
20  *
21  *  You should have received a copy of the GNU General Public License
22  *  along with this program; if not, write to the Free Software
23  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24  */
25
26
27 #include "acpi.h"
28 #include "acinterp.h"
29 #include "acnamesp.h"
30 #include "actables.h"
31 #include "amlcode.h"
32
33
34 #define _COMPONENT          ACPI_UTILITIES
35          MODULE_NAME         ("cmobject")
36
37
38 /*******************************************************************************
39  *
40  * FUNCTION:    _Cm_create_internal_object
41  *
42  * PARAMETERS:  Address             - Address of the memory to deallocate
43  *              Component           - Component type of caller
44  *              Module              - Source file name of caller
45  *              Line                - Line number of caller
46  *              Type                - ACPI Type of the new object
47  *
48  * RETURN:      Object              - The new object.  Null on failure
49  *
50  * DESCRIPTION: Create and initialize a new internal object.
51  *
52  * NOTE:        We always allocate the worst-case object descriptor because
53  *              these objects are cached, and we want them to be
54  *              one-size-satisifies-any-request.  This in itself may not be
55  *              the most memory efficient, but the efficiency of the object
56  *              cache should more than make up for this!
57  *
58  ******************************************************************************/
59
60 ACPI_OPERAND_OBJECT  *
61 _cm_create_internal_object (
62         NATIVE_CHAR             *module_name,
63         u32                     line_number,
64         u32                     component_id,
65         OBJECT_TYPE_INTERNAL    type)
66 {
67         ACPI_OPERAND_OBJECT     *object;
68
69
70         /* Allocate the raw object descriptor */
71
72         object = _cm_allocate_object_desc (module_name, line_number, component_id);
73         if (!object) {
74                 /* Allocation failure */
75
76                 return (NULL);
77         }
78
79         /* Save the object type in the object descriptor */
80
81         object->common.type = type;
82
83         /* Init the reference count */
84
85         object->common.reference_count = 1;
86
87         /* Any per-type initialization should go here */
88
89
90         return (object);
91 }
92
93
94 /*******************************************************************************
95  *
96  * FUNCTION:    Acpi_cm_valid_internal_object
97  *
98  * PARAMETERS:  Operand             - Object to be validated
99  *
100  * RETURN:      Validate a pointer to be an ACPI_OPERAND_OBJECT
101  *
102  ******************************************************************************/
103
104 u8
105 acpi_cm_valid_internal_object (
106         void                    *object)
107 {
108
109         /* Check for a null pointer */
110
111         if (!object) {
112                 return (FALSE);
113         }
114
115         /* Check for a pointer within one of the ACPI tables */
116
117         if (acpi_tb_system_table_pointer (object)) {
118                 return (FALSE);
119         }
120
121         /* Check the descriptor type field */
122
123         if (!VALID_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_INTERNAL)) {
124                 /* Not an ACPI internal object, do some further checking */
125
126
127
128
129                 return (FALSE);
130         }
131
132
133         /* The object appears to be a valid ACPI_OPERAND_OBJECT  */
134
135         return (TRUE);
136 }
137
138
139 /*******************************************************************************
140  *
141  * FUNCTION:    _Cm_allocate_object_desc
142  *
143  * PARAMETERS:  Module_name         - Caller's module name (for error output)
144  *              Line_number         - Caller's line number (for error output)
145  *              Component_id        - Caller's component ID (for error output)
146  *              Message             - Error message to use on failure
147  *
148  * RETURN:      Pointer to newly allocated object descriptor.  Null on error
149  *
150  * DESCRIPTION: Allocate a new object descriptor.  Gracefully handle
151  *              error conditions.
152  *
153  ******************************************************************************/
154
155 void *
156 _cm_allocate_object_desc (
157         NATIVE_CHAR             *module_name,
158         u32                     line_number,
159         u32                     component_id)
160 {
161         ACPI_OPERAND_OBJECT     *object;
162
163
164         acpi_cm_acquire_mutex (ACPI_MTX_CACHES);
165
166         acpi_gbl_object_cache_requests++;
167
168         /* Check the cache first */
169
170         if (acpi_gbl_object_cache) {
171                 /* There is an object available, use it */
172
173                 object = acpi_gbl_object_cache;
174                 acpi_gbl_object_cache = object->cache.next;
175                 object->cache.next = NULL;
176
177                 acpi_gbl_object_cache_hits++;
178                 acpi_gbl_object_cache_depth--;
179
180                 acpi_cm_release_mutex (ACPI_MTX_CACHES);
181         }
182
183         else {
184                 /* The cache is empty, create a new object */
185
186                 acpi_cm_release_mutex (ACPI_MTX_CACHES);
187
188                 /* Attempt to allocate new descriptor */
189
190                 object = _cm_callocate (sizeof (ACPI_OPERAND_OBJECT), component_id,
191                                   module_name, line_number);
192                 if (!object) {
193                         /* Allocation failed */
194
195                         _REPORT_ERROR (module_name, line_number, component_id,
196                                           ("Could not allocate an object descriptor\n"));
197
198                         return (NULL);
199                 }
200
201                 /* Memory allocation metrics - compiled out in non debug mode. */
202
203                 INCREMENT_OBJECT_METRICS (sizeof (ACPI_OPERAND_OBJECT));
204         }
205
206         /* Mark the descriptor type */
207
208         object->common.data_type = ACPI_DESC_TYPE_INTERNAL;
209
210         return (object);
211 }
212
213
214 /*******************************************************************************
215  *
216  * FUNCTION:    Acpi_cm_delete_object_desc
217  *
218  * PARAMETERS:  Object          - Acpi internal object to be deleted
219  *
220  * RETURN:      None.
221  *
222  * DESCRIPTION: Free an ACPI object descriptor or add it to the object cache
223  *
224  ******************************************************************************/
225
226 void
227 acpi_cm_delete_object_desc (
228         ACPI_OPERAND_OBJECT     *object)
229 {
230
231
232         /* Make sure that the object isn't already in the cache */
233
234         if (object->common.data_type == (ACPI_DESC_TYPE_INTERNAL | ACPI_CACHED_OBJECT)) {
235                 return;
236         }
237
238         /* Object must be an ACPI_OPERAND_OBJECT  */
239
240         if (object->common.data_type != ACPI_DESC_TYPE_INTERNAL) {
241                 return;
242         }
243
244
245         /* If cache is full, just free this object */
246
247         if (acpi_gbl_object_cache_depth >= MAX_OBJECT_CACHE_DEPTH) {
248                 /*
249                  * Memory allocation metrics.  Call the macro here since we only
250                  * care about dynamically allocated objects.
251                  */
252                 DECREMENT_OBJECT_METRICS (sizeof (ACPI_OPERAND_OBJECT));
253
254                 acpi_cm_free (object);
255                 return;
256         }
257
258         acpi_cm_acquire_mutex (ACPI_MTX_CACHES);
259
260         /* Clear the entire object.  This is important! */
261
262         MEMSET (object, 0, sizeof (ACPI_OPERAND_OBJECT));
263         object->common.data_type = ACPI_DESC_TYPE_INTERNAL | ACPI_CACHED_OBJECT;
264
265         /* Put the object at the head of the global cache list */
266
267         object->cache.next = acpi_gbl_object_cache;
268         acpi_gbl_object_cache = object;
269         acpi_gbl_object_cache_depth++;
270
271
272         acpi_cm_release_mutex (ACPI_MTX_CACHES);
273         return;
274 }
275
276
277 /*******************************************************************************
278  *
279  * FUNCTION:    Acpi_cm_delete_object_cache
280  *
281  * PARAMETERS:  None
282  *
283  * RETURN:      Status
284  *
285  * DESCRIPTION: Purge the global state object cache.  Used during subsystem
286  *              termination.
287  *
288  ******************************************************************************/
289
290 void
291 acpi_cm_delete_object_cache (
292         void)
293 {
294         ACPI_OPERAND_OBJECT     *next;
295
296
297         /* Traverse the global cache list */
298
299         while (acpi_gbl_object_cache) {
300                 /* Delete one cached state object */
301
302                 next = acpi_gbl_object_cache->cache.next;
303                 acpi_gbl_object_cache->cache.next = NULL;
304
305                 /*
306                  * Memory allocation metrics.  Call the macro here since we only
307                  * care about dynamically allocated objects.
308                  */
309                 DECREMENT_OBJECT_METRICS (sizeof (ACPI_OPERAND_OBJECT));
310
311                 acpi_cm_free (acpi_gbl_object_cache);
312                 acpi_gbl_object_cache = next;
313                 acpi_gbl_object_cache_depth--;
314         }
315
316         return;
317 }
318
319
320 /*******************************************************************************
321  *
322  * FUNCTION:    Acpi_cm_init_static_object
323  *
324  * PARAMETERS:  Obj_desc            - Pointer to a "static" object - on stack
325  *                                    or in the data segment.
326  *
327  * RETURN:      None.
328  *
329  * DESCRIPTION: Initialize a static object.  Sets flags to disallow dynamic
330  *              deletion of the object.
331  *
332  ******************************************************************************/
333
334 void
335 acpi_cm_init_static_object (
336         ACPI_OPERAND_OBJECT     *obj_desc)
337 {
338
339
340         if (!obj_desc) {
341                 return;
342         }
343
344
345         /*
346          * Clear the entire descriptor
347          */
348         MEMSET ((void *) obj_desc, 0, sizeof (ACPI_OPERAND_OBJECT));
349
350
351         /*
352          * Initialize the header fields
353          * 1) This is an ACPI_OPERAND_OBJECT  descriptor
354          * 2) The size is the full object (worst case)
355          * 3) The flags field indicates static allocation
356          * 4) Reference count starts at one (not really necessary since the
357          *    object can't be deleted, but keeps everything sane)
358          */
359
360         obj_desc->common.data_type      = ACPI_DESC_TYPE_INTERNAL;
361         obj_desc->common.flags          = AOPOBJ_STATIC_ALLOCATION;
362         obj_desc->common.reference_count = 1;
363
364         return;
365 }
366
367
368 /*******************************************************************************
369  *
370  * FUNCTION:    Acpi_cm_get_simple_object_size
371  *
372  * PARAMETERS:  *Internal_object    - Pointer to the object we are examining
373  *              *Ret_length         - Where the length is returned
374  *
375  * RETURN:      Status
376  *
377  * DESCRIPTION: This function is called to determine the space required to
378  *              contain a simple object for return to an API user.
379  *
380  *              The length includes the object structure plus any additional
381  *              needed space.
382  *
383  ******************************************************************************/
384
385 ACPI_STATUS
386 acpi_cm_get_simple_object_size (
387         ACPI_OPERAND_OBJECT     *internal_object,
388         u32                     *obj_length)
389 {
390         u32                     length;
391         ACPI_STATUS             status = AE_OK;
392
393
394         /* Handle a null object (Could be a uninitialized package element -- which is legal) */
395
396         if (!internal_object) {
397                 *obj_length = 0;
398                 return (AE_OK);
399         }
400
401
402         /* Start with the length of the Acpi object */
403
404         length = sizeof (ACPI_OBJECT);
405
406         if (VALID_DESCRIPTOR_TYPE (internal_object, ACPI_DESC_TYPE_NAMED)) {
407                 /* Object is a named object (reference), just return the length */
408
409                 *obj_length = (u32) ROUND_UP_TO_NATIVE_WORD (length);
410                 return (status);
411         }
412
413
414         /*
415          * The final length depends on the object type
416          * Strings and Buffers are packed right up against the parent object and
417          * must be accessed bytewise or there may be alignment problems on
418          * certain processors
419          */
420
421         switch (internal_object->common.type) {
422
423         case ACPI_TYPE_STRING:
424
425                 length += internal_object->string.length + 1;
426                 break;
427
428
429         case ACPI_TYPE_BUFFER:
430
431                 length += internal_object->buffer.length;
432                 break;
433
434
435         case ACPI_TYPE_INTEGER:
436         case ACPI_TYPE_PROCESSOR:
437         case ACPI_TYPE_POWER:
438
439                 /*
440                  * No extra data for these types
441                  */
442                 break;
443
444
445         case INTERNAL_TYPE_REFERENCE:
446
447                 /*
448                  * The only type that should be here is opcode AML_NAMEPATH_OP -- since
449                  * this means an object reference
450                  */
451                 if (internal_object->reference.opcode != AML_NAMEPATH_OP) {
452                         status = AE_TYPE;
453                 }
454
455                 else {
456                         /*
457                          * Get the actual length of the full pathname to this object.
458                          * The reference will be converted to the pathname to the object
459                          */
460                         length += ROUND_UP_TO_NATIVE_WORD (acpi_ns_get_pathname_length (internal_object->reference.node));
461                 }
462                 break;
463
464
465         default:
466
467                 status = AE_TYPE;
468                 break;
469         }
470
471
472         /*
473          * Account for the space required by the object rounded up to the next
474          * multiple of the machine word size.  This keeps each object aligned
475          * on a machine word boundary. (preventing alignment faults on some
476          * machines.)
477          */
478         *obj_length = (u32) ROUND_UP_TO_NATIVE_WORD (length);
479
480         return (status);
481 }
482
483
484 /*******************************************************************************
485  *
486  * FUNCTION:    Acpi_cm_get_element_length
487  *
488  * PARAMETERS:  ACPI_PKG_CALLBACK
489  *
490  * RETURN:      Status          - the status of the call
491  *
492  * DESCRIPTION: Get the length of one package element.
493  *
494  ******************************************************************************/
495
496 ACPI_STATUS
497 acpi_cm_get_element_length (
498         u8                      object_type,
499         ACPI_OPERAND_OBJECT     *source_object,
500         ACPI_GENERIC_STATE      *state,
501         void                    *context)
502 {
503         ACPI_STATUS             status = AE_OK;
504         ACPI_PKG_INFO           *info = (ACPI_PKG_INFO *) context;
505         u32                     object_space;
506
507
508         switch (object_type) {
509         case 0:
510
511                 /*
512                  * Simple object - just get the size (Null object/entry is handled
513                  * here also) and sum it into the running package length
514                  */
515                 status = acpi_cm_get_simple_object_size (source_object, &object_space);
516                 if (ACPI_FAILURE (status)) {
517                         return (status);
518                 }
519
520                 info->length += object_space;
521                 break;
522
523
524         case 1:
525                 /* Package - nothing much to do here, let the walk handle it */
526
527                 info->num_packages++;
528                 state->pkg.this_target_obj = NULL;
529                 break;
530
531         default:
532                 return (AE_BAD_PARAMETER);
533         }
534
535
536         return (status);
537 }
538
539
540 /*******************************************************************************
541  *
542  * FUNCTION:    Acpi_cm_get_package_object_size
543  *
544  * PARAMETERS:  *Internal_object    - Pointer to the object we are examining
545  *              *Ret_length         - Where the length is returned
546  *
547  * RETURN:      Status
548  *
549  * DESCRIPTION: This function is called to determine the space required to
550  *              contain a package object for return to an API user.
551  *
552  *              This is moderately complex since a package contains other
553  *              objects including packages.
554  *
555  ******************************************************************************/
556
557 ACPI_STATUS
558 acpi_cm_get_package_object_size (
559         ACPI_OPERAND_OBJECT     *internal_object,
560         u32                     *obj_length)
561 {
562         ACPI_STATUS             status;
563         ACPI_PKG_INFO           info;
564
565
566         info.length      = 0;
567         info.object_space = 0;
568         info.num_packages = 1;
569
570         status = acpi_cm_walk_package_tree (internal_object, NULL,
571                          acpi_cm_get_element_length, &info);
572
573         /*
574          * We have handled all of the objects in all levels of the package.
575          * just add the length of the package objects themselves.
576          * Round up to the next machine word.
577          */
578         info.length += ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT)) *
579                           info.num_packages;
580
581         /* Return the total package length */
582
583         *obj_length = info.length;
584         return (status);
585 }
586
587
588 /*******************************************************************************
589  *
590  * FUNCTION:    Acpi_cm_get_object_size
591  *
592  * PARAMETERS:  *Internal_object    - Pointer to the object we are examining
593  *              *Ret_length         - Where the length will be returned
594  *
595  * RETURN:      Status
596  *
597  * DESCRIPTION: This function is called to determine the space required to
598  *              contain an object for return to an API user.
599  *
600  ******************************************************************************/
601
602 ACPI_STATUS
603 acpi_cm_get_object_size(
604         ACPI_OPERAND_OBJECT     *internal_object,
605         u32                     *obj_length)
606 {
607         ACPI_STATUS             status;
608
609
610         if ((VALID_DESCRIPTOR_TYPE (internal_object, ACPI_DESC_TYPE_INTERNAL)) &&
611                 (IS_THIS_OBJECT_TYPE (internal_object, ACPI_TYPE_PACKAGE))) {
612                 status = acpi_cm_get_package_object_size (internal_object, obj_length);
613         }
614
615         else {
616                 status = acpi_cm_get_simple_object_size (internal_object, obj_length);
617         }
618
619         return (status);
620 }
621
622