1 /******************************************************************************
2  *
3  * Module Name: tbinstal - ACPI table installation and removal
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2008, 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 <xen/init.h>
45 #include <acpi/acpi.h>
46 #include <acpi/actables.h>
47 
48 #define _COMPONENT          ACPI_TABLES
49 ACPI_MODULE_NAME("tbinstal")
50 
51 /******************************************************************************
52  *
53  * FUNCTION:    acpi_tb_verify_table
54  *
55  * PARAMETERS:  table_desc          - table
56  *
57  * RETURN:      Status
58  *
59  * DESCRIPTION: this function is called to verify and map table
60  *
61  *****************************************************************************/
acpi_tb_verify_table(struct acpi_table_desc * table_desc)62 acpi_status __init acpi_tb_verify_table(struct acpi_table_desc *table_desc)
63 {
64 	acpi_status status = AE_OK;
65 
66 	ACPI_FUNCTION_TRACE(tb_verify_table);
67 
68 	/* Map the table if necessary */
69 
70 	if (!table_desc->pointer) {
71 		if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) ==
72 		    ACPI_TABLE_ORIGIN_MAPPED) {
73 			table_desc->pointer =
74 			    acpi_os_map_memory(table_desc->address,
75 					       table_desc->length);
76 		}
77 		if (!table_desc->pointer) {
78 			return_ACPI_STATUS(AE_NO_MEMORY);
79 		}
80 	}
81 
82 	/* FACS is the odd table, has no standard ACPI header and no checksum */
83 
84 	if (!ACPI_COMPARE_NAME(&table_desc->signature, ACPI_SIG_FACS)) {
85 
86 		/* Always calculate checksum, ignore bad checksum if requested */
87 
88 		status =
89 		    acpi_tb_verify_checksum(table_desc->pointer,
90 					    table_desc->length);
91 	}
92 
93 	return_ACPI_STATUS(status);
94 }
95 
96 /*******************************************************************************
97  *
98  * FUNCTION:    acpi_tb_resize_root_table_list
99  *
100  * PARAMETERS:  None
101  *
102  * RETURN:      Status
103  *
104  * DESCRIPTION: Expand the size of global table array
105  *
106  ******************************************************************************/
107 
acpi_tb_resize_root_table_list(void)108 acpi_status __init acpi_tb_resize_root_table_list(void)
109 {
110 	struct acpi_table_desc *tables;
111 
112 	ACPI_FUNCTION_TRACE(tb_resize_root_table_list);
113 
114 	/* allow_resize flag is a parameter to acpi_initialize_tables */
115 
116 	if (!(acpi_gbl_root_table_list.flags & ACPI_ROOT_ALLOW_RESIZE)) {
117 		ACPI_ERROR((AE_INFO,
118 			    "Resize of Root Table Array is not allowed"));
119 		return_ACPI_STATUS(AE_SUPPORT);
120 	}
121 
122 	/* Increase the Table Array size */
123 
124 	tables = ACPI_ALLOCATE_ZEROED((acpi_gbl_root_table_list.size +
125 				       ACPI_ROOT_TABLE_SIZE_INCREMENT)
126 				      * sizeof(struct acpi_table_desc));
127 	if (!tables) {
128 		ACPI_ERROR((AE_INFO,
129 			    "Could not allocate new root table array"));
130 		return_ACPI_STATUS(AE_NO_MEMORY);
131 	}
132 
133 	/* Copy and free the previous table array */
134 
135 	if (acpi_gbl_root_table_list.tables) {
136 		ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables,
137 			    acpi_gbl_root_table_list.size *
138 			    sizeof(struct acpi_table_desc));
139 
140 		if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
141 			ACPI_FREE(acpi_gbl_root_table_list.tables);
142 		}
143 	}
144 
145 	acpi_gbl_root_table_list.tables = tables;
146 	acpi_gbl_root_table_list.size += ACPI_ROOT_TABLE_SIZE_INCREMENT;
147 	acpi_gbl_root_table_list.flags |= (u8) ACPI_ROOT_ORIGIN_ALLOCATED;
148 
149 	return_ACPI_STATUS(AE_OK);
150 }
151