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: tbxface - ACPI table-oriented external interfaces
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
#define EXPORT_ACPI_INTERFACES
45
 
46
#include 
47
#include "accommon.h"
48
#include "actables.h"
49
 
50
#define _COMPONENT          ACPI_TABLES
51
ACPI_MODULE_NAME("tbxface")
52
 
53
/*******************************************************************************
54
 *
55
 * FUNCTION:    acpi_allocate_root_table
56
 *
57
 * PARAMETERS:  initial_table_count - Size of initial_table_array, in number of
58
 *                                    struct acpi_table_desc structures
59
 *
60
 * RETURN:      Status
61
 *
62
 * DESCRIPTION: Allocate a root table array. Used by iASL compiler and
63
 *              acpi_initialize_tables.
64
 *
65
 ******************************************************************************/
66
acpi_status acpi_allocate_root_table(u32 initial_table_count)
67
{
68
 
69
	acpi_gbl_root_table_list.max_table_count = initial_table_count;
70
	acpi_gbl_root_table_list.flags = ACPI_ROOT_ALLOW_RESIZE;
71
 
72
	return (acpi_tb_resize_root_table_list());
73
}
74
 
75
/*******************************************************************************
76
 *
77
 * FUNCTION:    acpi_initialize_tables
78
 *
79
 * PARAMETERS:  initial_table_array - Pointer to an array of pre-allocated
80
 *                                    struct acpi_table_desc structures. If NULL, the
81
 *                                    array is dynamically allocated.
82
 *              initial_table_count - Size of initial_table_array, in number of
83
 *                                    struct acpi_table_desc structures
84
 *              allow_resize        - Flag to tell Table Manager if resize of
85
 *                                    pre-allocated array is allowed. Ignored
86
 *                                    if initial_table_array is NULL.
87
 *
88
 * RETURN:      Status
89
 *
90
 * DESCRIPTION: Initialize the table manager, get the RSDP and RSDT/XSDT.
91
 *
92
 * NOTE:        Allows static allocation of the initial table array in order
93
 *              to avoid the use of dynamic memory in confined environments
94
 *              such as the kernel boot sequence where it may not be available.
95
 *
96
 *              If the host OS memory managers are initialized, use NULL for
97
 *              initial_table_array, and the table will be dynamically allocated.
98
 *
99
 ******************************************************************************/
100
 
101
acpi_status __init
102
acpi_initialize_tables(struct acpi_table_desc * initial_table_array,
103
		       u32 initial_table_count, u8 allow_resize)
104
{
105
	acpi_physical_address rsdp_address;
106
	acpi_status status;
107
 
108
	ACPI_FUNCTION_TRACE(acpi_initialize_tables);
109
 
110
	/*
111
	 * Setup the Root Table Array and allocate the table array
112
	 * if requested
113
	 */
114
	if (!initial_table_array) {
115
		status = acpi_allocate_root_table(initial_table_count);
116
		if (ACPI_FAILURE(status)) {
117
			return_ACPI_STATUS(status);
118
		}
119
	} else {
120
		/* Root Table Array has been statically allocated by the host */
121
 
122
		memset(initial_table_array, 0,
123
		       (acpi_size) initial_table_count *
124
		       sizeof(struct acpi_table_desc));
125
 
126
		acpi_gbl_root_table_list.tables = initial_table_array;
127
		acpi_gbl_root_table_list.max_table_count = initial_table_count;
128
		acpi_gbl_root_table_list.flags = ACPI_ROOT_ORIGIN_UNKNOWN;
129
		if (allow_resize) {
130
			acpi_gbl_root_table_list.flags |=
131
			    ACPI_ROOT_ALLOW_RESIZE;
132
		}
133
	}
134
 
135
	/* Get the address of the RSDP */
136
 
137
	rsdp_address = acpi_os_get_root_pointer();
138
	if (!rsdp_address) {
139
		return_ACPI_STATUS(AE_NOT_FOUND);
140
	}
141
 
142
	/*
143
	 * Get the root table (RSDT or XSDT) and extract all entries to the local
144
	 * Root Table Array. This array contains the information of the RSDT/XSDT
145
	 * in a common, more useable format.
146
	 */
147
   status = acpi_tb_parse_root_table(rsdp_address);
148
	return_ACPI_STATUS(status);
149
}
150
 
151
ACPI_EXPORT_SYMBOL_INIT(acpi_initialize_tables)
152
 
153
/*******************************************************************************
154
 *
155
 * FUNCTION:    acpi_reallocate_root_table
156
 *
157
 * PARAMETERS:  None
158
 *
159
 * RETURN:      Status
160
 *
161
 * DESCRIPTION: Reallocate Root Table List into dynamic memory. Copies the
162
 *              root list from the previously provided scratch area. Should
163
 *              be called once dynamic memory allocation is available in the
164
 *              kernel.
165
 *
166
 ******************************************************************************/
167
acpi_status __init acpi_reallocate_root_table(void)
168
{
169
	acpi_status status;
170
 
171
	ACPI_FUNCTION_TRACE(acpi_reallocate_root_table);
172
 
173
	/*
174
	 * Only reallocate the root table if the host provided a static buffer
175
	 * for the table array in the call to acpi_initialize_tables.
176
	 */
177
	if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
178
		return_ACPI_STATUS(AE_SUPPORT);
179
	}
180
 
181
	acpi_gbl_root_table_list.flags |= ACPI_ROOT_ALLOW_RESIZE;
182
 
183
	status = acpi_tb_resize_root_table_list();
184
	return_ACPI_STATUS(status);
185
}
186
 
187
ACPI_EXPORT_SYMBOL_INIT(acpi_reallocate_root_table)
188
 
189
/*******************************************************************************
190
 *
191
 * FUNCTION:    acpi_get_table_header
192
 *
193
 * PARAMETERS:  signature           - ACPI signature of needed table
194
 *              instance            - Which instance (for SSDTs)
195
 *              out_table_header    - The pointer to the table header to fill
196
 *
197
 * RETURN:      Status and pointer to mapped table header
198
 *
199
 * DESCRIPTION: Finds an ACPI table header.
200
 *
201
 * NOTE:        Caller is responsible in unmapping the header with
202
 *              acpi_os_unmap_memory
203
 *
204
 ******************************************************************************/
205
acpi_status
206
acpi_get_table_header(char *signature,
207
		      u32 instance, struct acpi_table_header *out_table_header)
208
{
209
	u32 i;
210
	u32 j;
211
	struct acpi_table_header *header;
212
 
213
	/* Parameter validation */
214
 
215
	if (!signature || !out_table_header) {
216
		return (AE_BAD_PARAMETER);
217
	}
218
 
219
	/* Walk the root table list */
220
 
221
	for (i = 0, j = 0; i < acpi_gbl_root_table_list.current_table_count;
222
	     i++) {
223
		if (!ACPI_COMPARE_NAME
224
		    (&(acpi_gbl_root_table_list.tables[i].signature),
225
		     signature)) {
226
			continue;
227
		}
228
 
229
		if (++j < instance) {
230
			continue;
231
		}
232
 
233
		if (!acpi_gbl_root_table_list.tables[i].pointer) {
234
			if ((acpi_gbl_root_table_list.tables[i].flags &
235
			     ACPI_TABLE_ORIGIN_MASK) ==
236
			    ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL) {
237
				header =
238
				    acpi_os_map_memory(acpi_gbl_root_table_list.
239
						       tables[i].address,
240
						       sizeof(struct
241
							      acpi_table_header));
242
				if (!header) {
243
					return (AE_NO_MEMORY);
244
				}
245
 
246
				memcpy(out_table_header, header,
247
				       sizeof(struct acpi_table_header));
248
				acpi_os_unmap_memory(header,
249
						     sizeof(struct
250
							    acpi_table_header));
251
			} else {
252
				return (AE_NOT_FOUND);
253
			}
254
		} else {
255
			memcpy(out_table_header,
256
			       acpi_gbl_root_table_list.tables[i].pointer,
257
			       sizeof(struct acpi_table_header));
258
		}
259
		return (AE_OK);
260
	}
261
 
262
	return (AE_NOT_FOUND);
263
}
264
 
265
ACPI_EXPORT_SYMBOL(acpi_get_table_header)
266
 
267
/*******************************************************************************
268
 *
269
 * FUNCTION:    acpi_get_table_with_size
270
 *
271
 * PARAMETERS:  signature           - ACPI signature of needed table
272
 *              instance            - Which instance (for SSDTs)
273
 *              out_table           - Where the pointer to the table is returned
274
 *
275
 * RETURN:      Status and pointer to the requested table
276
 *
277
 * DESCRIPTION: Finds and verifies an ACPI table. Table must be in the
278
 *              RSDT/XSDT.
279
 *
280
 ******************************************************************************/
281
acpi_status
282
acpi_get_table_with_size(char *signature,
283
	       u32 instance, struct acpi_table_header **out_table,
284
	       acpi_size *tbl_size)
285
{
286
	u32 i;
287
	u32 j;
288
	acpi_status status;
289
 
290
	/* Parameter validation */
291
 
292
	if (!signature || !out_table) {
293
		return (AE_BAD_PARAMETER);
294
	}
295
 
296
	/* Walk the root table list */
297
 
298
	for (i = 0, j = 0; i < acpi_gbl_root_table_list.current_table_count;
299
	     i++) {
300
		if (!ACPI_COMPARE_NAME
301
		    (&(acpi_gbl_root_table_list.tables[i].signature),
302
		     signature)) {
303
			continue;
304
		}
305
 
306
		if (++j < instance) {
307
			continue;
308
		}
309
 
310
		status =
311
		    acpi_tb_validate_table(&acpi_gbl_root_table_list.tables[i]);
312
		if (ACPI_SUCCESS(status)) {
313
			*out_table = acpi_gbl_root_table_list.tables[i].pointer;
314
			*tbl_size = acpi_gbl_root_table_list.tables[i].length;
315
		}
316
 
317
		if (!acpi_gbl_permanent_mmap) {
318
			acpi_gbl_root_table_list.tables[i].pointer = NULL;
319
		}
320
 
321
		return (status);
322
	}
323
 
324
	return (AE_NOT_FOUND);
325
}
326
 
327
ACPI_EXPORT_SYMBOL(acpi_get_table_with_size)
328
 
329
acpi_status
330
acpi_get_table(char *signature,
331
	       u32 instance, struct acpi_table_header **out_table)
332
{
333
	acpi_size tbl_size;
334
 
335
	return acpi_get_table_with_size(signature,
336
		       instance, out_table, &tbl_size);
337
}
338
 
339
ACPI_EXPORT_SYMBOL(acpi_get_table)
340
 
341
/*******************************************************************************
342
 *
343
 * FUNCTION:    acpi_get_table_by_index
344
 *
345
 * PARAMETERS:  table_index         - Table index
346
 *              table               - Where the pointer to the table is returned
347
 *
348
 * RETURN:      Status and pointer to the requested table
349
 *
350
 * DESCRIPTION: Obtain a table by an index into the global table list. Used
351
 *              internally also.
352
 *
353
 ******************************************************************************/
354
acpi_status
355
acpi_get_table_by_index(u32 table_index, struct acpi_table_header ** table)
356
{
357
	acpi_status status;
358
 
359
	ACPI_FUNCTION_TRACE(acpi_get_table_by_index);
360
 
361
	/* Parameter validation */
362
 
363
	if (!table) {
364
		return_ACPI_STATUS(AE_BAD_PARAMETER);
365
	}
366
 
367
	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
368
 
369
	/* Validate index */
370
 
371
	if (table_index >= acpi_gbl_root_table_list.current_table_count) {
372
		(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
373
		return_ACPI_STATUS(AE_BAD_PARAMETER);
374
	}
375
 
376
	if (!acpi_gbl_root_table_list.tables[table_index].pointer) {
377
 
378
		/* Table is not mapped, map it */
379
 
380
		status =
381
		    acpi_tb_validate_table(&acpi_gbl_root_table_list.
382
					   tables[table_index]);
383
		if (ACPI_FAILURE(status)) {
384
			(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
385
			return_ACPI_STATUS(status);
386
		}
387
	}
388
 
389
	*table = acpi_gbl_root_table_list.tables[table_index].pointer;
390
	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
391
	return_ACPI_STATUS(AE_OK);
392
}
393
 
394
ACPI_EXPORT_SYMBOL(acpi_get_table_by_index)
395
 
396
/*******************************************************************************
397
 *
398
 * FUNCTION:    acpi_install_table_handler
399
 *
400
 * PARAMETERS:  handler         - Table event handler
401
 *              context         - Value passed to the handler on each event
402
 *
403
 * RETURN:      Status
404
 *
405
 * DESCRIPTION: Install a global table event handler.
406
 *
407
 ******************************************************************************/
408
acpi_status
409
acpi_install_table_handler(acpi_table_handler handler, void *context)
410
{
411
	acpi_status status;
412
 
413
	ACPI_FUNCTION_TRACE(acpi_install_table_handler);
414
 
415
	if (!handler) {
416
		return_ACPI_STATUS(AE_BAD_PARAMETER);
417
	}
418
 
419
	status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
420
	if (ACPI_FAILURE(status)) {
421
		return_ACPI_STATUS(status);
422
	}
423
 
424
	/* Don't allow more than one handler */
425
 
426
	if (acpi_gbl_table_handler) {
427
		status = AE_ALREADY_EXISTS;
428
		goto cleanup;
429
	}
430
 
431
	/* Install the handler */
432
 
433
	acpi_gbl_table_handler = handler;
434
	acpi_gbl_table_handler_context = context;
435
 
436
cleanup:
437
	(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
438
	return_ACPI_STATUS(status);
439
}
440
 
441
ACPI_EXPORT_SYMBOL(acpi_install_table_handler)
442
 
443
/*******************************************************************************
444
 *
445
 * FUNCTION:    acpi_remove_table_handler
446
 *
447
 * PARAMETERS:  handler         - Table event handler that was installed
448
 *                                previously.
449
 *
450
 * RETURN:      Status
451
 *
452
 * DESCRIPTION: Remove a table event handler
453
 *
454
 ******************************************************************************/
455
acpi_status acpi_remove_table_handler(acpi_table_handler handler)
456
{
457
	acpi_status status;
458
 
459
	ACPI_FUNCTION_TRACE(acpi_remove_table_handler);
460
 
461
	status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
462
	if (ACPI_FAILURE(status)) {
463
		return_ACPI_STATUS(status);
464
	}
465
 
466
	/* Make sure that the installed handler is the same */
467
 
468
	if (!handler || handler != acpi_gbl_table_handler) {
469
		status = AE_BAD_PARAMETER;
470
		goto cleanup;
471
	}
472
 
473
	/* Remove the handler */
474
 
475
	acpi_gbl_table_handler = NULL;
476
 
477
cleanup:
478
	(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
479
	return_ACPI_STATUS(status);
480
}
481
 
482
ACPI_EXPORT_SYMBOL(acpi_remove_table_handler)