1
2
3
4
5
6
7
8
9
10#include <acpi/acpi.h>
11#include "accommon.h"
12#include "actables.h"
13
14#define _COMPONENT ACPI_TABLES
15ACPI_MODULE_NAME("tbinstal")
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33void
34acpi_tb_install_table_with_override(struct acpi_table_desc *new_table_desc,
35 u8 override, u32 *table_index)
36{
37 u32 i;
38 acpi_status status;
39
40 status = acpi_tb_get_next_table_descriptor(&i, NULL);
41 if (ACPI_FAILURE(status)) {
42 return;
43 }
44
45
46
47
48
49
50
51
52 if (override) {
53 acpi_tb_override_table(new_table_desc);
54 }
55
56 acpi_tb_init_table_descriptor(&acpi_gbl_root_table_list.tables[i],
57 new_table_desc->address,
58 new_table_desc->flags,
59 new_table_desc->pointer);
60
61 acpi_tb_print_table_header(new_table_desc->address,
62 new_table_desc->pointer);
63
64
65
66 *table_index = i;
67
68
69
70 if (i == acpi_gbl_dsdt_index) {
71 acpi_ut_set_integer_width(new_table_desc->pointer->revision);
72 }
73}
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96acpi_status
97acpi_tb_install_standard_table(acpi_physical_address address,
98 u8 flags,
99 u8 reload, u8 override, u32 *table_index)
100{
101 u32 i;
102 acpi_status status = AE_OK;
103 struct acpi_table_desc new_table_desc;
104
105 ACPI_FUNCTION_TRACE(tb_install_standard_table);
106
107
108
109 status = acpi_tb_acquire_temp_table(&new_table_desc, address, flags);
110 if (ACPI_FAILURE(status)) {
111 ACPI_ERROR((AE_INFO,
112 "Could not acquire table length at %8.8X%8.8X",
113 ACPI_FORMAT_UINT64(address)));
114 return_ACPI_STATUS(status);
115 }
116
117
118
119
120
121 if (!reload &&
122 acpi_gbl_disable_ssdt_table_install &&
123 ACPI_COMPARE_NAME(&new_table_desc.signature, ACPI_SIG_SSDT)) {
124 ACPI_INFO(("Ignoring installation of %4.4s at %8.8X%8.8X",
125 new_table_desc.signature.ascii,
126 ACPI_FORMAT_UINT64(address)));
127 goto release_and_exit;
128 }
129
130
131
132 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
133
134
135
136 status = acpi_tb_verify_temp_table(&new_table_desc, NULL, &i);
137 if (ACPI_FAILURE(status)) {
138 if (status == AE_CTRL_TERMINATE) {
139
140
141
142
143
144
145
146
147 acpi_tb_uninstall_table(&new_table_desc);
148 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
149 *table_index = i;
150 return_ACPI_STATUS(AE_OK);
151 }
152 goto unlock_and_exit;
153 }
154
155
156
157 acpi_tb_install_table_with_override(&new_table_desc, override,
158 table_index);
159
160
161
162 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
163 acpi_tb_notify_table(ACPI_TABLE_EVENT_INSTALL, new_table_desc.pointer);
164 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
165
166unlock_and_exit:
167
168
169
170 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
171
172release_and_exit:
173
174
175
176 acpi_tb_release_temp_table(&new_table_desc);
177 return_ACPI_STATUS(status);
178}
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197void acpi_tb_override_table(struct acpi_table_desc *old_table_desc)
198{
199 acpi_status status;
200 struct acpi_table_desc new_table_desc;
201 struct acpi_table_header *table;
202 acpi_physical_address address;
203 u32 length;
204 ACPI_ERROR_ONLY(char *override_type);
205
206
207
208 status = acpi_os_table_override(old_table_desc->pointer, &table);
209 if (ACPI_SUCCESS(status) && table) {
210 acpi_tb_acquire_temp_table(&new_table_desc,
211 ACPI_PTR_TO_PHYSADDR(table),
212 ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL);
213 ACPI_ERROR_ONLY(override_type = "Logical");
214 goto finish_override;
215 }
216
217
218
219 status = acpi_os_physical_table_override(old_table_desc->pointer,
220 &address, &length);
221 if (ACPI_SUCCESS(status) && address && length) {
222 acpi_tb_acquire_temp_table(&new_table_desc, address,
223 ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL);
224 ACPI_ERROR_ONLY(override_type = "Physical");
225 goto finish_override;
226 }
227
228 return;
229
230finish_override:
231
232
233
234
235
236 status = acpi_tb_verify_temp_table(&new_table_desc, NULL, NULL);
237 if (ACPI_FAILURE(status)) {
238 return;
239 }
240
241 ACPI_INFO(("%4.4s 0x%8.8X%8.8X"
242 " %s table override, new table: 0x%8.8X%8.8X",
243 old_table_desc->signature.ascii,
244 ACPI_FORMAT_UINT64(old_table_desc->address),
245 override_type, ACPI_FORMAT_UINT64(new_table_desc.address)));
246
247
248
249 acpi_tb_uninstall_table(old_table_desc);
250
251
252
253
254
255 acpi_tb_init_table_descriptor(old_table_desc, new_table_desc.address,
256 new_table_desc.flags,
257 new_table_desc.pointer);
258 acpi_tb_validate_temp_table(old_table_desc);
259
260
261
262 acpi_tb_release_temp_table(&new_table_desc);
263}
264
265
266
267
268
269
270
271
272
273
274
275
276
277void acpi_tb_uninstall_table(struct acpi_table_desc *table_desc)
278{
279
280 ACPI_FUNCTION_TRACE(tb_uninstall_table);
281
282
283
284 if (!table_desc->address) {
285 return_VOID;
286 }
287
288 acpi_tb_invalidate_table(table_desc);
289
290 if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) ==
291 ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL) {
292 ACPI_FREE(ACPI_PHYSADDR_TO_PTR(table_desc->address));
293 }
294
295 table_desc->address = ACPI_PTR_TO_PHYSADDR(NULL);
296 return_VOID;
297}
298