Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6595 serge 1
/*******************************************************************************
2
 *
3
 * Module Name: utmisc - common utility procedures
4
 *
5
 ******************************************************************************/
6
 
7
/*
8
 * Copyright (C) 2000 - 2015, Intel Corp.
9
 * All rights reserved.
10
 *
11
 * Redistribution and use in source and binary forms, with or without
12
 * modification, are permitted provided that the following conditions
13
 * are met:
14
 * 1. Redistributions of source code must retain the above copyright
15
 *    notice, this list of conditions, and the following disclaimer,
16
 *    without modification.
17
 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18
 *    substantially similar to the "NO WARRANTY" disclaimer below
19
 *    ("Disclaimer") and any redistribution must be conditioned upon
20
 *    including a substantially similar Disclaimer requirement for further
21
 *    binary redistribution.
22
 * 3. Neither the names of the above-listed copyright holders nor the names
23
 *    of any contributors may be used to endorse or promote products derived
24
 *    from this software without specific prior written permission.
25
 *
26
 * Alternatively, this software may be distributed under the terms of the
27
 * GNU General Public License ("GPL") version 2 as published by the Free
28
 * Software Foundation.
29
 *
30
 * NO WARRANTY
31
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35
 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41
 * POSSIBILITY OF SUCH DAMAGES.
42
 */
43
 
44
#include 
45
#include "accommon.h"
46
#include "acnamesp.h"
47
 
48
#define _COMPONENT          ACPI_UTILITIES
49
ACPI_MODULE_NAME("utmisc")
50
 
51
/*******************************************************************************
52
 *
53
 * FUNCTION:    acpi_ut_is_pci_root_bridge
54
 *
55
 * PARAMETERS:  id              - The HID/CID in string format
56
 *
57
 * RETURN:      TRUE if the Id is a match for a PCI/PCI-Express Root Bridge
58
 *
59
 * DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID.
60
 *
61
 ******************************************************************************/
62
u8 acpi_ut_is_pci_root_bridge(char *id)
63
{
64
 
65
	/*
66
	 * Check if this is a PCI root bridge.
67
	 * ACPI 3.0+: check for a PCI Express root also.
68
	 */
69
	if (!(strcmp(id,
70
		     PCI_ROOT_HID_STRING)) ||
71
	    !(strcmp(id, PCI_EXPRESS_ROOT_HID_STRING))) {
72
		return (TRUE);
73
	}
74
 
75
	return (FALSE);
76
}
77
 
78
#if (defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP || defined ACPI_NAMES_APP)
79
/*******************************************************************************
80
 *
81
 * FUNCTION:    acpi_ut_is_aml_table
82
 *
83
 * PARAMETERS:  table               - An ACPI table
84
 *
85
 * RETURN:      TRUE if table contains executable AML; FALSE otherwise
86
 *
87
 * DESCRIPTION: Check ACPI Signature for a table that contains AML code.
88
 *              Currently, these are DSDT,SSDT,PSDT. All other table types are
89
 *              data tables that do not contain AML code.
90
 *
91
 ******************************************************************************/
92
 
93
u8 acpi_ut_is_aml_table(struct acpi_table_header *table)
94
{
95
 
96
	/* These are the only tables that contain executable AML */
97
 
98
	if (ACPI_COMPARE_NAME(table->signature, ACPI_SIG_DSDT) ||
99
	    ACPI_COMPARE_NAME(table->signature, ACPI_SIG_PSDT) ||
100
	    ACPI_COMPARE_NAME(table->signature, ACPI_SIG_SSDT) ||
101
	    ACPI_COMPARE_NAME(table->signature, ACPI_SIG_OSDT)) {
102
		return (TRUE);
103
	}
104
 
105
	return (FALSE);
106
}
107
#endif
108
 
109
/*******************************************************************************
110
 *
111
 * FUNCTION:    acpi_ut_dword_byte_swap
112
 *
113
 * PARAMETERS:  value           - Value to be converted
114
 *
115
 * RETURN:      u32 integer with bytes swapped
116
 *
117
 * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes)
118
 *
119
 ******************************************************************************/
120
 
121
u32 acpi_ut_dword_byte_swap(u32 value)
122
{
123
	union {
124
		u32 value;
125
		u8 bytes[4];
126
	} out;
127
	union {
128
		u32 value;
129
		u8 bytes[4];
130
	} in;
131
 
132
	ACPI_FUNCTION_ENTRY();
133
 
134
	in.value = value;
135
 
136
	out.bytes[0] = in.bytes[3];
137
	out.bytes[1] = in.bytes[2];
138
	out.bytes[2] = in.bytes[1];
139
	out.bytes[3] = in.bytes[0];
140
 
141
	return (out.value);
142
}
143
 
144
/*******************************************************************************
145
 *
146
 * FUNCTION:    acpi_ut_set_integer_width
147
 *
148
 * PARAMETERS:  Revision            From DSDT header
149
 *
150
 * RETURN:      None
151
 *
152
 * DESCRIPTION: Set the global integer bit width based upon the revision
153
 *              of the DSDT. For Revision 1 and 0, Integers are 32 bits.
154
 *              For Revision 2 and above, Integers are 64 bits. Yes, this
155
 *              makes a difference.
156
 *
157
 ******************************************************************************/
158
 
159
void acpi_ut_set_integer_width(u8 revision)
160
{
161
 
162
	if (revision < 2) {
163
 
164
		/* 32-bit case */
165
 
166
		acpi_gbl_integer_bit_width = 32;
167
		acpi_gbl_integer_nybble_width = 8;
168
		acpi_gbl_integer_byte_width = 4;
169
	} else {
170
		/* 64-bit case (ACPI 2.0+) */
171
 
172
		acpi_gbl_integer_bit_width = 64;
173
		acpi_gbl_integer_nybble_width = 16;
174
		acpi_gbl_integer_byte_width = 8;
175
	}
176
}
177
 
178
/*******************************************************************************
179
 *
180
 * FUNCTION:    acpi_ut_create_update_state_and_push
181
 *
182
 * PARAMETERS:  object          - Object to be added to the new state
183
 *              action          - Increment/Decrement
184
 *              state_list      - List the state will be added to
185
 *
186
 * RETURN:      Status
187
 *
188
 * DESCRIPTION: Create a new state and push it
189
 *
190
 ******************************************************************************/
191
 
192
acpi_status
193
acpi_ut_create_update_state_and_push(union acpi_operand_object *object,
194
				     u16 action,
195
				     union acpi_generic_state **state_list)
196
{
197
	union acpi_generic_state *state;
198
 
199
	ACPI_FUNCTION_ENTRY();
200
 
201
	/* Ignore null objects; these are expected */
202
 
203
	if (!object) {
204
		return (AE_OK);
205
	}
206
 
207
	state = acpi_ut_create_update_state(object, action);
208
	if (!state) {
209
		return (AE_NO_MEMORY);
210
	}
211
 
212
	acpi_ut_push_generic_state(state_list, state);
213
	return (AE_OK);
214
}
215
 
216
/*******************************************************************************
217
 *
218
 * FUNCTION:    acpi_ut_walk_package_tree
219
 *
220
 * PARAMETERS:  source_object       - The package to walk
221
 *              target_object       - Target object (if package is being copied)
222
 *              walk_callback       - Called once for each package element
223
 *              context             - Passed to the callback function
224
 *
225
 * RETURN:      Status
226
 *
227
 * DESCRIPTION: Walk through a package
228
 *
229
 ******************************************************************************/
230
 
231
acpi_status
232
acpi_ut_walk_package_tree(union acpi_operand_object *source_object,
233
			  void *target_object,
234
			  acpi_pkg_callback walk_callback, void *context)
235
{
236
	acpi_status status = AE_OK;
237
	union acpi_generic_state *state_list = NULL;
238
	union acpi_generic_state *state;
239
	u32 this_index;
240
	union acpi_operand_object *this_source_obj;
241
 
242
	ACPI_FUNCTION_TRACE(ut_walk_package_tree);
243
 
244
	state = acpi_ut_create_pkg_state(source_object, target_object, 0);
245
	if (!state) {
246
		return_ACPI_STATUS(AE_NO_MEMORY);
247
	}
248
 
249
	while (state) {
250
 
251
		/* Get one element of the package */
252
 
253
		this_index = state->pkg.index;
254
		this_source_obj = (union acpi_operand_object *)
255
		    state->pkg.source_object->package.elements[this_index];
256
 
257
		/*
258
		 * Check for:
259
		 * 1) An uninitialized package element. It is completely
260
		 *    legal to declare a package and leave it uninitialized
261
		 * 2) Not an internal object - can be a namespace node instead
262
		 * 3) Any type other than a package. Packages are handled in else
263
		 *    case below.
264
		 */
265
		if ((!this_source_obj) ||
266
		    (ACPI_GET_DESCRIPTOR_TYPE(this_source_obj) !=
267
		     ACPI_DESC_TYPE_OPERAND)
268
		    || (this_source_obj->common.type != ACPI_TYPE_PACKAGE)) {
269
			status =
270
			    walk_callback(ACPI_COPY_TYPE_SIMPLE,
271
					  this_source_obj, state, context);
272
			if (ACPI_FAILURE(status)) {
273
				return_ACPI_STATUS(status);
274
			}
275
 
276
			state->pkg.index++;
277
			while (state->pkg.index >=
278
			       state->pkg.source_object->package.count) {
279
				/*
280
				 * We've handled all of the objects at this level,  This means
281
				 * that we have just completed a package. That package may
282
				 * have contained one or more packages itself.
283
				 *
284
				 * Delete this state and pop the previous state (package).
285
				 */
286
				acpi_ut_delete_generic_state(state);
287
				state = acpi_ut_pop_generic_state(&state_list);
288
 
289
				/* Finished when there are no more states */
290
 
291
				if (!state) {
292
					/*
293
					 * We have handled all of the objects in the top level
294
					 * package just add the length of the package objects
295
					 * and exit
296
					 */
297
					return_ACPI_STATUS(AE_OK);
298
				}
299
 
300
				/*
301
				 * Go back up a level and move the index past the just
302
				 * completed package object.
303
				 */
304
				state->pkg.index++;
305
			}
306
		} else {
307
			/* This is a subobject of type package */
308
 
309
			status =
310
			    walk_callback(ACPI_COPY_TYPE_PACKAGE,
311
					  this_source_obj, state, context);
312
			if (ACPI_FAILURE(status)) {
313
				return_ACPI_STATUS(status);
314
			}
315
 
316
			/*
317
			 * Push the current state and create a new one
318
			 * The callback above returned a new target package object.
319
			 */
320
			acpi_ut_push_generic_state(&state_list, state);
321
			state = acpi_ut_create_pkg_state(this_source_obj,
322
							 state->pkg.
323
							 this_target_obj, 0);
324
			if (!state) {
325
 
326
				/* Free any stacked Update State objects */
327
 
328
				while (state_list) {
329
					state =
330
					    acpi_ut_pop_generic_state
331
					    (&state_list);
332
					acpi_ut_delete_generic_state(state);
333
				}
334
				return_ACPI_STATUS(AE_NO_MEMORY);
335
			}
336
		}
337
	}
338
 
339
	/* We should never get here */
340
 
341
	return_ACPI_STATUS(AE_AML_INTERNAL);
342
}
343
 
344
#ifdef ACPI_DEBUG_OUTPUT
345
/*******************************************************************************
346
 *
347
 * FUNCTION:    acpi_ut_display_init_pathname
348
 *
349
 * PARAMETERS:  type                - Object type of the node
350
 *              obj_handle          - Handle whose pathname will be displayed
351
 *              path                - Additional path string to be appended.
352
 *                                      (NULL if no extra path)
353
 *
354
 * RETURN:      acpi_status
355
 *
356
 * DESCRIPTION: Display full pathname of an object, DEBUG ONLY
357
 *
358
 ******************************************************************************/
359
 
360
void
361
acpi_ut_display_init_pathname(u8 type,
362
			      struct acpi_namespace_node *obj_handle,
363
			      char *path)
364
{
365
	acpi_status status;
366
	struct acpi_buffer buffer;
367
 
368
	ACPI_FUNCTION_ENTRY();
369
 
370
	/* Only print the path if the appropriate debug level is enabled */
371
 
372
	if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) {
373
		return;
374
	}
375
 
376
	/* Get the full pathname to the node */
377
 
378
	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
379
	status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE);
380
	if (ACPI_FAILURE(status)) {
381
		return;
382
	}
383
 
384
	/* Print what we're doing */
385
 
386
	switch (type) {
387
	case ACPI_TYPE_METHOD:
388
 
389
		acpi_os_printf("Executing  ");
390
		break;
391
 
392
	default:
393
 
394
		acpi_os_printf("Initializing ");
395
		break;
396
	}
397
 
398
	/* Print the object type and pathname */
399
 
400
	acpi_os_printf("%-12s %s",
401
		       acpi_ut_get_type_name(type), (char *)buffer.pointer);
402
 
403
	/* Extra path is used to append names like _STA, _INI, etc. */
404
 
405
	if (path) {
406
		acpi_os_printf(".%s", path);
407
	}
408
	acpi_os_printf("\n");
409
 
410
	ACPI_FREE(buffer.pointer);
411
}
412
#endif