aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/tables/tbxface.c
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2007-02-02 11:48:18 -0500
committerLen Brown <len.brown@intel.com>2007-02-02 21:14:21 -0500
commitf3d2e7865c816258c699ff965768e46b50d536d3 (patch)
tree83d21269e506109275b77d3ed161883bba8a39cf /drivers/acpi/tables/tbxface.c
parent2e42005bcdb4f63bed1cea7f537a5534d4bd7a57 (diff)
ACPICA: Implement simplified Table Manager
The Table Manager component has been completely redesigned and reimplemented. The new design is much simpler, and reduces the overall code and data size of the kernel-resident ACPICA by approximately 5%. Also, it is now possible to obtain the ACPI tables very early during kernel initialization, even before dynamic memory management is initialized. Signed-off-by: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/tables/tbxface.c')
-rw-r--r--drivers/acpi/tables/tbxface.c620
1 files changed, 351 insertions, 269 deletions
diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c
index 5ba9303293ad..77439fc36c32 100644
--- a/drivers/acpi/tables/tbxface.c
+++ b/drivers/acpi/tables/tbxface.c
@@ -49,80 +49,146 @@
49#define _COMPONENT ACPI_TABLES 49#define _COMPONENT ACPI_TABLES
50ACPI_MODULE_NAME("tbxface") 50ACPI_MODULE_NAME("tbxface")
51 51
52/* Local prototypes */
53static acpi_status acpi_tb_load_namespace(void);
54
52/******************************************************************************* 55/*******************************************************************************
53 * 56 *
54 * FUNCTION: acpi_load_tables 57 * FUNCTION: acpi_initialize_tables
55 * 58 *
56 * PARAMETERS: None 59 * PARAMETERS: initial_table_array - Pointer to an array of pre-allocated
60 * struct acpi_table_desc structures. If NULL, the
61 * array is dynamically allocated.
62 * initial_table_count - Size of initial_table_array, in number of
63 * struct acpi_table_desc structures
64 * allow_realloc - Flag to tell Table Manager if resize of
65 * pre-allocated array is allowed. Ignored
66 * if initial_table_array is NULL.
57 * 67 *
58 * RETURN: Status 68 * RETURN: Status
59 * 69 *
60 * DESCRIPTION: This function is called to load the ACPI tables from the 70 * DESCRIPTION: Initialize the table manager, get the RSDP and RSDT/XSDT.
61 * provided RSDT 71 *
72 * NOTE: Allows static allocation of the initial table array in order
73 * to avoid the use of dynamic memory in confined environments
74 * such as the kernel boot sequence where it may not be available.
75 *
76 * If the host OS memory managers are initialized, use NULL for
77 * initial_table_array, and the table will be dynamically allocated.
62 * 78 *
63 ******************************************************************************/ 79 ******************************************************************************/
64acpi_status acpi_load_tables(void) 80
81acpi_status
82acpi_initialize_tables(struct acpi_table_desc *initial_table_array,
83 u32 initial_table_count, u8 allow_resize)
65{ 84{
66 struct acpi_pointer rsdp_address; 85 acpi_physical_address address;
67 acpi_status status; 86 acpi_status status;
87 struct acpi_table_rsdp *rsdp;
68 88
69 ACPI_FUNCTION_TRACE(acpi_load_tables); 89 ACPI_FUNCTION_TRACE(acpi_initialize_tables);
70 90
71 /* Get the RSDP */ 91 /*
92 * Set up the Root Table Array
93 * Allocate the table array if requested
94 */
95 if (!initial_table_array) {
96 acpi_gbl_root_table_list.size = initial_table_count;
97 acpi_gbl_root_table_list.flags = ACPI_TABLE_FLAGS_ALLOW_RESIZE;
72 98
73 status = acpi_os_get_root_pointer(ACPI_LOGICAL_ADDRESSING, 99 status = acpi_tb_resize_root_table_list();
74 &rsdp_address); 100 if (ACPI_FAILURE(status)) {
75 if (ACPI_FAILURE(status)) { 101 return_ACPI_STATUS(status);
76 ACPI_EXCEPTION((AE_INFO, status, "Could not get the RSDP")); 102 }
77 goto error_exit; 103 } else {
104 /* Root Table Array has been statically allocated by the host */
105
106 acpi_gbl_root_table_list.tables = initial_table_array;
107 acpi_gbl_root_table_list.size = initial_table_count;
108 acpi_gbl_root_table_list.flags = ACPI_TABLE_ORIGIN_UNKNOWN;
109 if (allow_resize) {
110 acpi_gbl_root_table_list.flags =
111 ACPI_TABLE_FLAGS_ALLOW_RESIZE;
112 }
78 } 113 }
79 114
80 /* Map and validate the RSDP */ 115 /* Get the RSDP and map it */
81 116
82 acpi_gbl_table_flags = rsdp_address.pointer_type; 117 address = acpi_os_get_root_pointer();
118 if (!address) {
119 return_ACPI_STATUS(AE_NOT_FOUND);
120 }
83 121
84 status = acpi_tb_verify_rsdp(&rsdp_address); 122 rsdp = acpi_os_map_memory(address, sizeof(struct acpi_table_rsdp));
85 if (ACPI_FAILURE(status)) { 123 if (!rsdp) {
86 ACPI_EXCEPTION((AE_INFO, status, "During RSDP validation")); 124 return_ACPI_STATUS(AE_NO_MEMORY);
87 goto error_exit;
88 } 125 }
89 126
90 /* Get the RSDT via the RSDP */ 127 ACPI_INFO((AE_INFO, "%.8s @ 0x%p",
128 rsdp->signature, ACPI_CAST_PTR(void, address)));
91 129
92 status = acpi_tb_get_table_rsdt(); 130 /*
93 if (ACPI_FAILURE(status)) { 131 * Get the root table (RSDT or XSDT) and extract all entries to the local
94 ACPI_EXCEPTION((AE_INFO, status, "Could not load RSDT")); 132 * Root Table Array. This array contains the information of the RSDT/XSDT
95 goto error_exit; 133 * in a common, more useable format.
96 } 134 */
135 status = acpi_tb_parse_root_table(rsdp, ACPI_TABLE_ORIGIN_MAPPED);
136 acpi_os_unmap_memory(rsdp, sizeof(struct acpi_table_rsdp));
137 return_ACPI_STATUS(status);
138}
97 139
98 /* Now get the tables needed by this subsystem (FADT, DSDT, etc.) */ 140ACPI_EXPORT_SYMBOL(acpi_initialize_tables)
99 141
100 status = acpi_tb_get_required_tables(); 142/*******************************************************************************
101 if (ACPI_FAILURE(status)) { 143 *
102 ACPI_EXCEPTION((AE_INFO, status, 144 * FUNCTION: acpi_reallocate_root_table
103 "Could not get all required tables (DSDT/FADT/FACS)")); 145 *
104 goto error_exit; 146 * PARAMETERS: None
147 *
148 * RETURN: Status
149 *
150 * DESCRIPTION: Reallocate Root Table List into dynamic memory. Copies the
151 * root list from the previously provided scratch area. Should
152 * be called once dynamic memory allocation is available in the
153 * kernel
154 *
155 ******************************************************************************/
156acpi_status acpi_reallocate_root_table(void)
157{
158 struct acpi_table_desc *tables;
159 acpi_size new_size;
160
161 ACPI_FUNCTION_TRACE(acpi_reallocate_root_table);
162
163 /*
164 * Only reallocate the root table if the host provided a static buffer
165 * for the table array in the call to acpi_initialize_tables.
166 */
167 if ((acpi_gbl_root_table_list.flags & ACPI_TABLE_ORIGIN_MASK) !=
168 ACPI_TABLE_ORIGIN_UNKNOWN) {
169 return_ACPI_STATUS(AE_SUPPORT);
105 } 170 }
106 171
107 ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI Tables successfully acquired\n")); 172 new_size =
173 (acpi_gbl_root_table_list.count +
174 ACPI_ROOT_TABLE_SIZE_INCREMENT) * sizeof(struct acpi_table_desc);
108 175
109 /* Load the namespace from the tables */ 176 /* Create new array and copy the old array */
110 177
111 status = acpi_ns_load_namespace(); 178 tables = ACPI_ALLOCATE_ZEROED(new_size);
112 if (ACPI_FAILURE(status)) { 179 if (!tables) {
113 ACPI_EXCEPTION((AE_INFO, status, "Could not load namespace")); 180 return_ACPI_STATUS(AE_NO_MEMORY);
114 goto error_exit;
115 } 181 }
116 182
117 return_ACPI_STATUS(AE_OK); 183 ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, new_size);
118 184
119 error_exit: 185 acpi_gbl_root_table_list.size = acpi_gbl_root_table_list.count;
120 ACPI_EXCEPTION((AE_INFO, status, "Could not load tables")); 186 acpi_gbl_root_table_list.tables = tables;
121 return_ACPI_STATUS(status); 187 acpi_gbl_root_table_list.flags =
122} 188 ACPI_TABLE_ORIGIN_ALLOCATED | ACPI_TABLE_FLAGS_ALLOW_RESIZE;
123
124ACPI_EXPORT_SYMBOL(acpi_load_tables)
125 189
190 return_ACPI_STATUS(AE_OK);
191}
126/******************************************************************************* 192/*******************************************************************************
127 * 193 *
128 * FUNCTION: acpi_load_table 194 * FUNCTION: acpi_load_table
@@ -141,342 +207,358 @@ ACPI_EXPORT_SYMBOL(acpi_load_tables)
141acpi_status acpi_load_table(struct acpi_table_header *table_ptr) 207acpi_status acpi_load_table(struct acpi_table_header *table_ptr)
142{ 208{
143 acpi_status status; 209 acpi_status status;
144 struct acpi_table_desc table_info; 210 acpi_native_uint table_index;
145 struct acpi_pointer address;
146
147 ACPI_FUNCTION_TRACE(acpi_load_table);
148
149 if (!table_ptr) {
150 return_ACPI_STATUS(AE_BAD_PARAMETER);
151 }
152 211
153 /* Copy the table to a local buffer */ 212 /*
154 213 * Install the new table into the local data structures
155 address.pointer_type = ACPI_LOGICAL_POINTER | ACPI_LOGICAL_ADDRESSING; 214 */
156 address.pointer.logical = table_ptr; 215 status = acpi_tb_add_table(table_ptr, &table_index);
157
158 status = acpi_tb_get_table_body(&address, table_ptr, &table_info);
159 if (ACPI_FAILURE(status)) {
160 return_ACPI_STATUS(status);
161 }
162
163 /* Check signature for a valid table type */
164
165 status = acpi_tb_recognize_table(&table_info, ACPI_TABLE_ALL);
166 if (ACPI_FAILURE(status)) { 216 if (ACPI_FAILURE(status)) {
167 return_ACPI_STATUS(status); 217 return_ACPI_STATUS(status);
168 } 218 }
219 status = acpi_ns_load_table(table_index, acpi_gbl_root_node);
220 return_ACPI_STATUS(status);
221}
169 222
170 /* Install the new table into the local data structures */ 223ACPI_EXPORT_SYMBOL(acpi_load_table)
171
172 status = acpi_tb_install_table(&table_info);
173 if (ACPI_FAILURE(status)) {
174 if (status == AE_ALREADY_EXISTS) {
175 224
176 /* Table already exists, no error */ 225/******************************************************************************
226 *
227 * FUNCTION: acpi_get_table_header
228 *
229 * PARAMETERS: Signature - ACPI signature of needed table
230 * Instance - Which instance (for SSDTs)
231 * out_table_header - Where the pointer to the table header
232 * is returned
233 *
234 * RETURN: Status and pointer to mapped table header
235 *
236 * DESCRIPTION: Finds an ACPI table header.
237 *
238 * NOTE: Caller is responsible in unmapping the header with
239 * acpi_os_unmap_memory
240 *
241 *****************************************************************************/
242acpi_status
243acpi_get_table_header(char *signature,
244 acpi_native_uint instance,
245 struct acpi_table_header **out_table_header)
246{
247 acpi_native_uint i;
248 acpi_native_uint j;
177 249
178 status = AE_OK; 250 /*
251 * Walk the root table list
252 */
253 for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) {
254 if (!ACPI_COMPARE_NAME
255 (&(acpi_gbl_root_table_list.tables[i].signature),
256 signature)) {
257 continue;
179 } 258 }
180 259
181 /* Free table allocated by acpi_tb_get_table_body */ 260 if (++j < instance) {
182 261 continue;
183 acpi_tb_delete_single_table(&table_info); 262 }
184 return_ACPI_STATUS(status);
185 }
186
187 /* Convert the table to common format if necessary */
188
189 switch (table_info.type) {
190 case ACPI_TABLE_ID_FADT:
191
192 status = acpi_tb_convert_table_fadt();
193 break;
194
195 case ACPI_TABLE_ID_FACS:
196
197 status = acpi_tb_build_common_facs(&table_info);
198 break;
199
200 default:
201 /* Load table into namespace if it contains executable AML */
202
203 status =
204 acpi_ns_load_table(table_info.installed_desc,
205 acpi_gbl_root_node);
206 break;
207 }
208 263
209 if (ACPI_FAILURE(status)) { 264 *out_table_header =
265 acpi_tb_map(acpi_gbl_root_table_list.tables[i].address,
266 (u32) sizeof(struct acpi_table_header),
267 acpi_gbl_root_table_list.tables[i].
268 flags & ACPI_TABLE_ORIGIN_MASK);
210 269
211 /* Uninstall table and free the buffer */ 270 if (!out_table_header) {
271 return (AE_NO_MEMORY);
272 }
212 273
213 (void)acpi_tb_uninstall_table(table_info.installed_desc); 274 return (AE_OK);
214 } 275 }
215 276
216 return_ACPI_STATUS(status); 277 return (AE_NOT_FOUND);
217} 278}
218 279
219ACPI_EXPORT_SYMBOL(acpi_load_table) 280ACPI_EXPORT_SYMBOL(acpi_get_table_header)
220 281
221/******************************************************************************* 282
283/******************************************************************************
222 * 284 *
223 * FUNCTION: acpi_unload_table_id 285 * FUNCTION: acpi_unload_table_id
224 * 286 *
225 * PARAMETERS: table_type - Type of table to be unloaded 287 * PARAMETERS: id - Owner ID of the table to be removed.
226 * id - Owner ID of the table to be removed.
227 * 288 *
228 * RETURN: Status 289 * RETURN: Status
229 * 290 *
230 * DESCRIPTION: This routine is used to force the unload of a table (by id) 291 * DESCRIPTION: This routine is used to force the unload of a table (by id)
231 * 292 *
232 ******************************************************************************/ 293 ******************************************************************************/
233acpi_status acpi_unload_table_id(acpi_table_type table_type, acpi_owner_id id) 294acpi_status acpi_unload_table_id(acpi_owner_id id)
234{ 295{
235 struct acpi_table_desc *table_desc; 296 int i;
236 acpi_status status; 297 acpi_status status = AE_NOT_EXIST;
237 298
238 ACPI_FUNCTION_TRACE(acpi_unload_table); 299 ACPI_FUNCTION_TRACE(acpi_unload_table);
239 300
240 /* Parameter validation */
241 if (table_type > ACPI_TABLE_ID_MAX)
242 return_ACPI_STATUS(AE_BAD_PARAMETER);
243
244 /* Find table from the requested type list */ 301 /* Find table from the requested type list */
245 table_desc = acpi_gbl_table_lists[table_type].next; 302 for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
246 while (table_desc && table_desc->owner_id != id) 303 if (id != acpi_gbl_root_table_list.tables[i].owner_id) {
247 table_desc = table_desc->next; 304 continue;
248 305 }
249 if (!table_desc) 306 /*
250 return_ACPI_STATUS(AE_NOT_EXIST); 307 * Delete all namespace objects owned by this table. Note that these
251 308 * objects can appear anywhere in the namespace by virtue of the AML
252 /* 309 * "Scope" operator. Thus, we need to track ownership by an ID, not
253 * Delete all namespace objects owned by this table. Note that these 310 * simply a position within the hierarchy
254 * objects can appear anywhere in the namespace by virtue of the AML 311 */
255 * "Scope" operator. Thus, we need to track ownership by an ID, not 312 acpi_tb_delete_namespace_by_owner(i);
256 * simply a position within the hierarchy 313 acpi_tb_release_owner_id(i);
257 */ 314 acpi_tb_set_table_loaded_flag(i, FALSE);
258 acpi_ns_delete_namespace_by_owner(table_desc->owner_id); 315 }
259 316 return_ACPI_STATUS(status);
260 status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
261 if (ACPI_FAILURE(status))
262 return_ACPI_STATUS(status);
263
264 (void)acpi_tb_uninstall_table(table_desc);
265
266 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
267
268 return_ACPI_STATUS(AE_OK);
269} 317}
270 318
271ACPI_EXPORT_SYMBOL(acpi_unload_table_id) 319ACPI_EXPORT_SYMBOL(acpi_unload_table_id)
272 320
273#ifdef ACPI_FUTURE_USAGE
274/******************************************************************************* 321/*******************************************************************************
275 * 322 *
276 * FUNCTION: acpi_unload_table 323 * FUNCTION: acpi_get_table
277 * 324 *
278 * PARAMETERS: table_type - Type of table to be unloaded 325 * PARAMETERS: Signature - ACPI signature of needed table
326 * Instance - Which instance (for SSDTs)
327 * out_table - Where the pointer to the table is returned
279 * 328 *
280 * RETURN: Status 329 * RETURN: Status and pointer to table
281 * 330 *
282 * DESCRIPTION: This routine is used to force the unload of a table 331 * DESCRIPTION: Finds and verifies an ACPI table.
283 * 332 *
284 ******************************************************************************/ 333 *****************************************************************************/
285acpi_status acpi_unload_table(acpi_table_type table_type) 334acpi_status
335acpi_get_table(char *signature,
336 acpi_native_uint instance, struct acpi_table_header ** out_table)
286{ 337{
287 struct acpi_table_desc *table_desc; 338 acpi_native_uint i;
288 339 acpi_native_uint j;
289 ACPI_FUNCTION_TRACE(acpi_unload_table); 340 acpi_status status;
290
291 /* Parameter validation */
292 341
293 if (table_type > ACPI_TABLE_ID_MAX) { 342 /*
294 return_ACPI_STATUS(AE_BAD_PARAMETER); 343 * Walk the root table list
295 } 344 */
345 for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) {
346 if (!ACPI_COMPARE_NAME
347 (&(acpi_gbl_root_table_list.tables[i].signature),
348 signature)) {
349 continue;
350 }
296 351
297 /* Find all tables of the requested type */ 352 if (++j < instance) {
353 continue;
354 }
298 355
299 table_desc = acpi_gbl_table_lists[table_type].next; 356 status =
300 if (!table_desc) { 357 acpi_tb_verify_table(&acpi_gbl_root_table_list.tables[i]);
301 return_ACPI_STATUS(AE_NOT_EXIST); 358 if (ACPI_SUCCESS(status)) {
302 } 359 *out_table = acpi_gbl_root_table_list.tables[i].pointer;
360 }
303 361
304 while (table_desc) { 362 return (status);
305 /*
306 * Delete all namespace objects owned by this table. Note that these
307 * objects can appear anywhere in the namespace by virtue of the AML
308 * "Scope" operator. Thus, we need to track ownership by an ID, not
309 * simply a position within the hierarchy
310 */
311 acpi_ns_delete_namespace_by_owner(table_desc->owner_id);
312 table_desc = table_desc->next;
313 } 363 }
314 364
315 /* Delete (or unmap) all tables of this type */ 365 return (AE_NOT_FOUND);
316
317 acpi_tb_delete_tables_by_type(table_type);
318 return_ACPI_STATUS(AE_OK);
319} 366}
320 367
321ACPI_EXPORT_SYMBOL(acpi_unload_table) 368ACPI_EXPORT_SYMBOL(acpi_get_table)
322 369
323/******************************************************************************* 370/*******************************************************************************
324 * 371 *
325 * FUNCTION: acpi_get_table_header 372 * FUNCTION: acpi_get_table_by_index
326 * 373 *
327 * PARAMETERS: table_type - one of the defined table types 374 * PARAMETERS: table_index - Table index
328 * Instance - the non zero instance of the table, allows 375 * Table - Where the pointer to the table is returned
329 * support for multiple tables of the same type
330 * see acpi_gbl_acpi_table_flag
331 * out_table_header - pointer to the struct acpi_table_header if successful
332 * 376 *
333 * DESCRIPTION: This function is called to get an ACPI table header. The caller 377 * RETURN: Status and pointer to the table
334 * supplies an pointer to a data area sufficient to contain an ACPI
335 * struct acpi_table_header structure.
336 * 378 *
337 * The header contains a length field that can be used to determine 379 * DESCRIPTION: Obtain a table by an index into the global table list.
338 * the size of the buffer needed to contain the entire table. This
339 * function is not valid for the RSD PTR table since it does not
340 * have a standard header and is fixed length.
341 * 380 *
342 ******************************************************************************/ 381 ******************************************************************************/
343acpi_status 382acpi_status
344acpi_get_table_header(acpi_table_type table_type, 383acpi_get_table_by_index(acpi_native_uint table_index,
345 u32 instance, struct acpi_table_header *out_table_header) 384 struct acpi_table_header ** table)
346{ 385{
347 struct acpi_table_header *tbl_ptr;
348 acpi_status status; 386 acpi_status status;
349 387
350 ACPI_FUNCTION_TRACE(acpi_get_table_header); 388 ACPI_FUNCTION_TRACE(acpi_get_table_by_index);
351 389
352 if ((instance == 0) || 390 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
353 (table_type == ACPI_TABLE_ID_RSDP) || (!out_table_header)) {
354 return_ACPI_STATUS(AE_BAD_PARAMETER);
355 }
356 391
357 /* Check the table type and instance */ 392 /* Validate index */
358 393
359 if ((table_type > ACPI_TABLE_ID_MAX) || 394 if (table_index >= acpi_gbl_root_table_list.count) {
360 (ACPI_IS_SINGLE_TABLE(acpi_gbl_table_data[table_type].flags) && 395 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
361 instance > 1)) {
362 return_ACPI_STATUS(AE_BAD_PARAMETER); 396 return_ACPI_STATUS(AE_BAD_PARAMETER);
363 } 397 }
364 398
365 /* Get a pointer to the entire table */ 399 if (!acpi_gbl_root_table_list.tables[table_index].pointer) {
366 400
367 status = acpi_tb_get_table_ptr(table_type, instance, &tbl_ptr); 401 /* Table is not mapped, map it */
368 if (ACPI_FAILURE(status)) {
369 return_ACPI_STATUS(status);
370 }
371 402
372 /* The function will return a NULL pointer if the table is not loaded */ 403 status =
373 404 acpi_tb_verify_table(&acpi_gbl_root_table_list.
374 if (tbl_ptr == NULL) { 405 tables[table_index]);
375 return_ACPI_STATUS(AE_NOT_EXIST); 406 if (ACPI_FAILURE(status)) {
407 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
408 return_ACPI_STATUS(status);
409 }
376 } 410 }
377 411
378 /* Copy the header to the caller's buffer */ 412 *table = acpi_gbl_root_table_list.tables[table_index].pointer;
379 413 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
380 ACPI_MEMCPY(ACPI_CAST_PTR(void, out_table_header), 414 return_ACPI_STATUS(AE_OK);
381 ACPI_CAST_PTR(void, tbl_ptr),
382 sizeof(struct acpi_table_header));
383
384 return_ACPI_STATUS(status);
385} 415}
386 416
387ACPI_EXPORT_SYMBOL(acpi_get_table_header) 417ACPI_EXPORT_SYMBOL(acpi_get_table_by_index)
388#endif /* ACPI_FUTURE_USAGE */
389 418
390/******************************************************************************* 419/*******************************************************************************
391 * 420 *
392 * FUNCTION: acpi_get_table 421 * FUNCTION: acpi_tb_load_namespace
393 * 422 *
394 * PARAMETERS: table_type - one of the defined table types 423 * PARAMETERS: None
395 * Instance - the non zero instance of the table, allows
396 * support for multiple tables of the same type
397 * see acpi_gbl_acpi_table_flag
398 * ret_buffer - pointer to a structure containing a buffer to
399 * receive the table
400 * 424 *
401 * RETURN: Status 425 * RETURN: Status
402 * 426 *
403 * DESCRIPTION: This function is called to get an ACPI table. The caller 427 * DESCRIPTION: Load the namespace from the DSDT and all SSDTs/PSDTs found in
404 * supplies an out_buffer large enough to contain the entire ACPI 428 * the RSDT/XSDT.
405 * table. The caller should call the acpi_get_table_header function
406 * first to determine the buffer size needed. Upon completion
407 * the out_buffer->Length field will indicate the number of bytes
408 * copied into the out_buffer->buf_ptr buffer. This table will be
409 * a complete table including the header.
410 * 429 *
411 ******************************************************************************/ 430 ******************************************************************************/
412acpi_status 431static acpi_status acpi_tb_load_namespace(void)
413acpi_get_table(acpi_table_type table_type,
414 u32 instance, struct acpi_buffer *ret_buffer)
415{ 432{
416 struct acpi_table_header *tbl_ptr;
417 acpi_status status; 433 acpi_status status;
418 acpi_size table_length; 434 struct acpi_table_header *table;
435 acpi_native_uint i;
419 436
420 ACPI_FUNCTION_TRACE(acpi_get_table); 437 ACPI_FUNCTION_TRACE(tb_load_namespace);
421 438
422 /* Parameter validation */ 439 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
423 440
424 if (instance == 0) { 441 /*
425 return_ACPI_STATUS(AE_BAD_PARAMETER); 442 * Load the namespace. The DSDT is required, but any SSDT and PSDT tables
443 * are optional.
444 */
445 if (!acpi_gbl_root_table_list.count ||
446 !ACPI_COMPARE_NAME(&
447 (acpi_gbl_root_table_list.
448 tables[ACPI_TABLE_INDEX_DSDT].signature),
449 ACPI_SIG_DSDT)
450 ||
451 ACPI_FAILURE(acpi_tb_verify_table
452 (&acpi_gbl_root_table_list.
453 tables[ACPI_TABLE_INDEX_DSDT]))) {
454 status = AE_NO_ACPI_TABLES;
455 goto unlock_and_exit;
426 } 456 }
427 457
428 status = acpi_ut_validate_buffer(ret_buffer); 458 /*
429 if (ACPI_FAILURE(status)) { 459 * Find DSDT table
430 return_ACPI_STATUS(status); 460 */
461 status =
462 acpi_os_table_override(acpi_gbl_root_table_list.
463 tables[ACPI_TABLE_INDEX_DSDT].pointer,
464 &table);
465 if (ACPI_SUCCESS(status) && table) {
466 /*
467 * DSDT table has been found
468 */
469 acpi_tb_delete_table(ACPI_TABLE_INDEX_DSDT);
470 acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer =
471 table;
472 acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].length =
473 table->length;
474 acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].flags =
475 ACPI_TABLE_ORIGIN_UNKNOWN;
476
477 ACPI_INFO((AE_INFO, "Table DSDT replaced by host OS"));
478 acpi_tb_print_table_header(0, table);
431 } 479 }
432 480
433 /* Check the table type and instance */ 481 status =
482 acpi_tb_verify_table(&acpi_gbl_root_table_list.
483 tables[ACPI_TABLE_INDEX_DSDT]);
484 if (ACPI_FAILURE(status)) {
485
486 /* A valid DSDT is required */
434 487
435 if ((table_type > ACPI_TABLE_ID_MAX) || 488 status = AE_NO_ACPI_TABLES;
436 (ACPI_IS_SINGLE_TABLE(acpi_gbl_table_data[table_type].flags) && 489 goto unlock_and_exit;
437 instance > 1)) {
438 return_ACPI_STATUS(AE_BAD_PARAMETER);
439 } 490 }
440 491
441 /* Get a pointer to the entire table */ 492 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
442 493
443 status = acpi_tb_get_table_ptr(table_type, instance, &tbl_ptr); 494 /*
495 * Load and parse tables.
496 */
497 status = acpi_ns_load_table(ACPI_TABLE_INDEX_DSDT, acpi_gbl_root_node);
444 if (ACPI_FAILURE(status)) { 498 if (ACPI_FAILURE(status)) {
445 return_ACPI_STATUS(status); 499 return_ACPI_STATUS(status);
446 } 500 }
447 501
448 /* 502 /*
449 * acpi_tb_get_table_ptr will return a NULL pointer if the 503 * Load any SSDT or PSDT tables. Note: Loop leaves tables locked
450 * table is not loaded.
451 */ 504 */
452 if (tbl_ptr == NULL) { 505 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
453 return_ACPI_STATUS(AE_NOT_EXIST); 506 for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
507 if ((!ACPI_COMPARE_NAME
508 (&(acpi_gbl_root_table_list.tables[i].signature),
509 ACPI_SIG_SSDT)
510 &&
511 !ACPI_COMPARE_NAME(&
512 (acpi_gbl_root_table_list.tables[i].
513 signature), ACPI_SIG_PSDT))
514 ||
515 ACPI_FAILURE(acpi_tb_verify_table
516 (&acpi_gbl_root_table_list.tables[i]))) {
517 continue;
518 }
519
520 /* Ignore errors while loading tables, get as many as possible */
521
522 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
523 (void)acpi_ns_load_table(i, acpi_gbl_root_node);
524 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
454 } 525 }
455 526
456 /* Get the table length */ 527 ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI Tables successfully acquired\n"));
457 528
458 if (table_type == ACPI_TABLE_ID_RSDP) { 529 unlock_and_exit:
530 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
531 return_ACPI_STATUS(status);
532}
459 533
460 /* RSD PTR is the only "table" without a header */ 534/*******************************************************************************
535 *
536 * FUNCTION: acpi_load_tables
537 *
538 * PARAMETERS: None
539 *
540 * RETURN: Status
541 *
542 * DESCRIPTION: Load the ACPI tables from the RSDT/XSDT
543 *
544 ******************************************************************************/
461 545
462 table_length = sizeof(struct rsdp_descriptor); 546acpi_status acpi_load_tables(void)
463 } else { 547{
464 table_length = (acpi_size) tbl_ptr->length; 548 acpi_status status;
465 }
466 549
467 /* Validate/Allocate/Clear caller buffer */ 550 ACPI_FUNCTION_TRACE(acpi_load_tables);
468 551
469 status = acpi_ut_initialize_buffer(ret_buffer, table_length); 552 /*
553 * Load the namespace from the tables
554 */
555 status = acpi_tb_load_namespace();
470 if (ACPI_FAILURE(status)) { 556 if (ACPI_FAILURE(status)) {
471 return_ACPI_STATUS(status); 557 ACPI_EXCEPTION((AE_INFO, status,
558 "While loading namespace from ACPI tables"));
472 } 559 }
473 560
474 /* Copy the table to the buffer */ 561 return_ACPI_STATUS(status);
475
476 ACPI_MEMCPY(ACPI_CAST_PTR(void, ret_buffer->pointer),
477 ACPI_CAST_PTR(void, tbl_ptr), table_length);
478
479 return_ACPI_STATUS(AE_OK);
480} 562}
481 563
482ACPI_EXPORT_SYMBOL(acpi_get_table) 564ACPI_EXPORT_SYMBOL(acpi_load_tables)