diff options
65 files changed, 6060 insertions, 2271 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 2b64fb221790..c6e72ee53903 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -214,6 +214,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
214 | unusable. The "log_buf_len" parameter may be useful | 214 | unusable. The "log_buf_len" parameter may be useful |
215 | if you need to capture more output. | 215 | if you need to capture more output. |
216 | 216 | ||
217 | acpi_force_table_verification [HW,ACPI] | ||
218 | Enable table checksum verification during early stage. | ||
219 | By default, this is disabled due to x86 early mapping | ||
220 | size limitation. | ||
221 | |||
217 | acpi_irq_balance [HW,ACPI] | 222 | acpi_irq_balance [HW,ACPI] |
218 | ACPI will balance active IRQs | 223 | ACPI will balance active IRQs |
219 | default in APIC mode | 224 | default in APIC mode |
@@ -237,7 +242,15 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
237 | This feature is enabled by default. | 242 | This feature is enabled by default. |
238 | This option allows to turn off the feature. | 243 | This option allows to turn off the feature. |
239 | 244 | ||
240 | acpi_no_auto_ssdt [HW,ACPI] Disable automatic loading of SSDT | 245 | acpi_no_static_ssdt [HW,ACPI] |
246 | Disable installation of static SSDTs at early boot time | ||
247 | By default, SSDTs contained in the RSDT/XSDT will be | ||
248 | installed automatically and they will appear under | ||
249 | /sys/firmware/acpi/tables. | ||
250 | This option turns off this feature. | ||
251 | Note that specifying this option does not affect | ||
252 | dynamic table installation which will install SSDT | ||
253 | tables to /sys/firmware/acpi/tables/dynamic. | ||
241 | 254 | ||
242 | acpica_no_return_repair [HW, ACPI] | 255 | acpica_no_return_repair [HW, ACPI] |
243 | Disable AML predefined validation mechanism | 256 | Disable AML predefined validation mechanism |
diff --git a/arch/ia64/include/asm/acenv.h b/arch/ia64/include/asm/acenv.h new file mode 100644 index 000000000000..3f9eaeec9873 --- /dev/null +++ b/arch/ia64/include/asm/acenv.h | |||
@@ -0,0 +1,56 @@ | |||
1 | /* | ||
2 | * IA64 specific ACPICA environments and implementation | ||
3 | * | ||
4 | * Copyright (C) 2014, Intel Corporation | ||
5 | * Author: Lv Zheng <lv.zheng@intel.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #ifndef _ASM_IA64_ACENV_H | ||
13 | #define _ASM_IA64_ACENV_H | ||
14 | |||
15 | #include <asm/intrinsics.h> | ||
16 | |||
17 | #define COMPILER_DEPENDENT_INT64 long | ||
18 | #define COMPILER_DEPENDENT_UINT64 unsigned long | ||
19 | |||
20 | /* Asm macros */ | ||
21 | |||
22 | #ifdef CONFIG_ACPI | ||
23 | |||
24 | static inline int | ||
25 | ia64_acpi_acquire_global_lock(unsigned int *lock) | ||
26 | { | ||
27 | unsigned int old, new, val; | ||
28 | do { | ||
29 | old = *lock; | ||
30 | new = (((old & ~0x3) + 2) + ((old >> 1) & 0x1)); | ||
31 | val = ia64_cmpxchg4_acq(lock, new, old); | ||
32 | } while (unlikely (val != old)); | ||
33 | return (new < 3) ? -1 : 0; | ||
34 | } | ||
35 | |||
36 | static inline int | ||
37 | ia64_acpi_release_global_lock(unsigned int *lock) | ||
38 | { | ||
39 | unsigned int old, new, val; | ||
40 | do { | ||
41 | old = *lock; | ||
42 | new = old & ~0x3; | ||
43 | val = ia64_cmpxchg4_acq(lock, new, old); | ||
44 | } while (unlikely (val != old)); | ||
45 | return old & 0x1; | ||
46 | } | ||
47 | |||
48 | #define ACPI_ACQUIRE_GLOBAL_LOCK(facs, Acq) \ | ||
49 | ((Acq) = ia64_acpi_acquire_global_lock(&facs->global_lock)) | ||
50 | |||
51 | #define ACPI_RELEASE_GLOBAL_LOCK(facs, Acq) \ | ||
52 | ((Acq) = ia64_acpi_release_global_lock(&facs->global_lock)) | ||
53 | |||
54 | #endif | ||
55 | |||
56 | #endif /* _ASM_IA64_ACENV_H */ | ||
diff --git a/arch/ia64/include/asm/acpi.h b/arch/ia64/include/asm/acpi.h index 2e73dffa16af..75dc59a793d6 100644 --- a/arch/ia64/include/asm/acpi.h +++ b/arch/ia64/include/asm/acpi.h | |||
@@ -34,56 +34,6 @@ | |||
34 | #include <linux/numa.h> | 34 | #include <linux/numa.h> |
35 | #include <asm/numa.h> | 35 | #include <asm/numa.h> |
36 | 36 | ||
37 | #define COMPILER_DEPENDENT_INT64 long | ||
38 | #define COMPILER_DEPENDENT_UINT64 unsigned long | ||
39 | |||
40 | /* | ||
41 | * Calling conventions: | ||
42 | * | ||
43 | * ACPI_SYSTEM_XFACE - Interfaces to host OS (handlers, threads) | ||
44 | * ACPI_EXTERNAL_XFACE - External ACPI interfaces | ||
45 | * ACPI_INTERNAL_XFACE - Internal ACPI interfaces | ||
46 | * ACPI_INTERNAL_VAR_XFACE - Internal variable-parameter list interfaces | ||
47 | */ | ||
48 | #define ACPI_SYSTEM_XFACE | ||
49 | #define ACPI_EXTERNAL_XFACE | ||
50 | #define ACPI_INTERNAL_XFACE | ||
51 | #define ACPI_INTERNAL_VAR_XFACE | ||
52 | |||
53 | /* Asm macros */ | ||
54 | |||
55 | #define ACPI_FLUSH_CPU_CACHE() | ||
56 | |||
57 | static inline int | ||
58 | ia64_acpi_acquire_global_lock (unsigned int *lock) | ||
59 | { | ||
60 | unsigned int old, new, val; | ||
61 | do { | ||
62 | old = *lock; | ||
63 | new = (((old & ~0x3) + 2) + ((old >> 1) & 0x1)); | ||
64 | val = ia64_cmpxchg4_acq(lock, new, old); | ||
65 | } while (unlikely (val != old)); | ||
66 | return (new < 3) ? -1 : 0; | ||
67 | } | ||
68 | |||
69 | static inline int | ||
70 | ia64_acpi_release_global_lock (unsigned int *lock) | ||
71 | { | ||
72 | unsigned int old, new, val; | ||
73 | do { | ||
74 | old = *lock; | ||
75 | new = old & ~0x3; | ||
76 | val = ia64_cmpxchg4_acq(lock, new, old); | ||
77 | } while (unlikely (val != old)); | ||
78 | return old & 0x1; | ||
79 | } | ||
80 | |||
81 | #define ACPI_ACQUIRE_GLOBAL_LOCK(facs, Acq) \ | ||
82 | ((Acq) = ia64_acpi_acquire_global_lock(&facs->global_lock)) | ||
83 | |||
84 | #define ACPI_RELEASE_GLOBAL_LOCK(facs, Acq) \ | ||
85 | ((Acq) = ia64_acpi_release_global_lock(&facs->global_lock)) | ||
86 | |||
87 | #ifdef CONFIG_ACPI | 37 | #ifdef CONFIG_ACPI |
88 | extern int acpi_lapic; | 38 | extern int acpi_lapic; |
89 | #define acpi_disabled 0 /* ACPI always enabled on IA64 */ | 39 | #define acpi_disabled 0 /* ACPI always enabled on IA64 */ |
diff --git a/arch/x86/include/asm/acenv.h b/arch/x86/include/asm/acenv.h new file mode 100644 index 000000000000..66873297e9f5 --- /dev/null +++ b/arch/x86/include/asm/acenv.h | |||
@@ -0,0 +1,49 @@ | |||
1 | /* | ||
2 | * X86 specific ACPICA environments and implementation | ||
3 | * | ||
4 | * Copyright (C) 2014, Intel Corporation | ||
5 | * Author: Lv Zheng <lv.zheng@intel.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #ifndef _ASM_X86_ACENV_H | ||
13 | #define _ASM_X86_ACENV_H | ||
14 | |||
15 | #include <asm/special_insns.h> | ||
16 | |||
17 | /* Asm macros */ | ||
18 | |||
19 | #define ACPI_FLUSH_CPU_CACHE() wbinvd() | ||
20 | |||
21 | #ifdef CONFIG_ACPI | ||
22 | |||
23 | int __acpi_acquire_global_lock(unsigned int *lock); | ||
24 | int __acpi_release_global_lock(unsigned int *lock); | ||
25 | |||
26 | #define ACPI_ACQUIRE_GLOBAL_LOCK(facs, Acq) \ | ||
27 | ((Acq) = __acpi_acquire_global_lock(&facs->global_lock)) | ||
28 | |||
29 | #define ACPI_RELEASE_GLOBAL_LOCK(facs, Acq) \ | ||
30 | ((Acq) = __acpi_release_global_lock(&facs->global_lock)) | ||
31 | |||
32 | /* | ||
33 | * Math helper asm macros | ||
34 | */ | ||
35 | #define ACPI_DIV_64_BY_32(n_hi, n_lo, d32, q32, r32) \ | ||
36 | asm("divl %2;" \ | ||
37 | : "=a"(q32), "=d"(r32) \ | ||
38 | : "r"(d32), \ | ||
39 | "0"(n_lo), "1"(n_hi)) | ||
40 | |||
41 | #define ACPI_SHIFT_RIGHT_64(n_hi, n_lo) \ | ||
42 | asm("shrl $1,%2 ;" \ | ||
43 | "rcrl $1,%3;" \ | ||
44 | : "=r"(n_hi), "=r"(n_lo) \ | ||
45 | : "0"(n_hi), "1"(n_lo)) | ||
46 | |||
47 | #endif | ||
48 | |||
49 | #endif /* _ASM_X86_ACENV_H */ | ||
diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index c8c1e700c26e..e06225eda635 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h | |||
@@ -32,51 +32,6 @@ | |||
32 | #include <asm/mpspec.h> | 32 | #include <asm/mpspec.h> |
33 | #include <asm/realmode.h> | 33 | #include <asm/realmode.h> |
34 | 34 | ||
35 | #define COMPILER_DEPENDENT_INT64 long long | ||
36 | #define COMPILER_DEPENDENT_UINT64 unsigned long long | ||
37 | |||
38 | /* | ||
39 | * Calling conventions: | ||
40 | * | ||
41 | * ACPI_SYSTEM_XFACE - Interfaces to host OS (handlers, threads) | ||
42 | * ACPI_EXTERNAL_XFACE - External ACPI interfaces | ||
43 | * ACPI_INTERNAL_XFACE - Internal ACPI interfaces | ||
44 | * ACPI_INTERNAL_VAR_XFACE - Internal variable-parameter list interfaces | ||
45 | */ | ||
46 | #define ACPI_SYSTEM_XFACE | ||
47 | #define ACPI_EXTERNAL_XFACE | ||
48 | #define ACPI_INTERNAL_XFACE | ||
49 | #define ACPI_INTERNAL_VAR_XFACE | ||
50 | |||
51 | /* Asm macros */ | ||
52 | |||
53 | #define ACPI_FLUSH_CPU_CACHE() wbinvd() | ||
54 | |||
55 | int __acpi_acquire_global_lock(unsigned int *lock); | ||
56 | int __acpi_release_global_lock(unsigned int *lock); | ||
57 | |||
58 | #define ACPI_ACQUIRE_GLOBAL_LOCK(facs, Acq) \ | ||
59 | ((Acq) = __acpi_acquire_global_lock(&facs->global_lock)) | ||
60 | |||
61 | #define ACPI_RELEASE_GLOBAL_LOCK(facs, Acq) \ | ||
62 | ((Acq) = __acpi_release_global_lock(&facs->global_lock)) | ||
63 | |||
64 | /* | ||
65 | * Math helper asm macros | ||
66 | */ | ||
67 | #define ACPI_DIV_64_BY_32(n_hi, n_lo, d32, q32, r32) \ | ||
68 | asm("divl %2;" \ | ||
69 | : "=a"(q32), "=d"(r32) \ | ||
70 | : "r"(d32), \ | ||
71 | "0"(n_lo), "1"(n_hi)) | ||
72 | |||
73 | |||
74 | #define ACPI_SHIFT_RIGHT_64(n_hi, n_lo) \ | ||
75 | asm("shrl $1,%2 ;" \ | ||
76 | "rcrl $1,%3;" \ | ||
77 | : "=r"(n_hi), "=r"(n_lo) \ | ||
78 | : "0"(n_hi), "1"(n_lo)) | ||
79 | |||
80 | #ifdef CONFIG_ACPI | 35 | #ifdef CONFIG_ACPI |
81 | extern int acpi_lapic; | 36 | extern int acpi_lapic; |
82 | extern int acpi_ioapic; | 37 | extern int acpi_ioapic; |
diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c index c4a5d87ede7e..185334114d71 100644 --- a/drivers/acpi/acpi_extlog.c +++ b/drivers/acpi/acpi_extlog.c | |||
@@ -220,13 +220,13 @@ static int __init extlog_init(void) | |||
220 | goto err; | 220 | goto err; |
221 | } | 221 | } |
222 | 222 | ||
223 | extlog_l1_hdr = acpi_os_map_memory(l1_dirbase, l1_hdr_size); | 223 | extlog_l1_hdr = acpi_os_map_iomem(l1_dirbase, l1_hdr_size); |
224 | l1_head = (struct extlog_l1_head *)extlog_l1_hdr; | 224 | l1_head = (struct extlog_l1_head *)extlog_l1_hdr; |
225 | l1_size = l1_head->total_len; | 225 | l1_size = l1_head->total_len; |
226 | l1_percpu_entry = l1_head->entries; | 226 | l1_percpu_entry = l1_head->entries; |
227 | elog_base = l1_head->elog_base; | 227 | elog_base = l1_head->elog_base; |
228 | elog_size = l1_head->elog_len; | 228 | elog_size = l1_head->elog_len; |
229 | acpi_os_unmap_memory(extlog_l1_hdr, l1_hdr_size); | 229 | acpi_os_unmap_iomem(extlog_l1_hdr, l1_hdr_size); |
230 | release_mem_region(l1_dirbase, l1_hdr_size); | 230 | release_mem_region(l1_dirbase, l1_hdr_size); |
231 | 231 | ||
232 | /* remap L1 header again based on completed information */ | 232 | /* remap L1 header again based on completed information */ |
@@ -237,7 +237,7 @@ static int __init extlog_init(void) | |||
237 | (unsigned long long)l1_dirbase + l1_size); | 237 | (unsigned long long)l1_dirbase + l1_size); |
238 | goto err; | 238 | goto err; |
239 | } | 239 | } |
240 | extlog_l1_addr = acpi_os_map_memory(l1_dirbase, l1_size); | 240 | extlog_l1_addr = acpi_os_map_iomem(l1_dirbase, l1_size); |
241 | l1_entry_base = (u64 *)((u8 *)extlog_l1_addr + l1_hdr_size); | 241 | l1_entry_base = (u64 *)((u8 *)extlog_l1_addr + l1_hdr_size); |
242 | 242 | ||
243 | /* remap elog table */ | 243 | /* remap elog table */ |
@@ -248,7 +248,7 @@ static int __init extlog_init(void) | |||
248 | (unsigned long long)elog_base + elog_size); | 248 | (unsigned long long)elog_base + elog_size); |
249 | goto err_release_l1_dir; | 249 | goto err_release_l1_dir; |
250 | } | 250 | } |
251 | elog_addr = acpi_os_map_memory(elog_base, elog_size); | 251 | elog_addr = acpi_os_map_iomem(elog_base, elog_size); |
252 | 252 | ||
253 | rc = -ENOMEM; | 253 | rc = -ENOMEM; |
254 | /* allocate buffer to save elog record */ | 254 | /* allocate buffer to save elog record */ |
@@ -270,11 +270,11 @@ static int __init extlog_init(void) | |||
270 | 270 | ||
271 | err_release_elog: | 271 | err_release_elog: |
272 | if (elog_addr) | 272 | if (elog_addr) |
273 | acpi_os_unmap_memory(elog_addr, elog_size); | 273 | acpi_os_unmap_iomem(elog_addr, elog_size); |
274 | release_mem_region(elog_base, elog_size); | 274 | release_mem_region(elog_base, elog_size); |
275 | err_release_l1_dir: | 275 | err_release_l1_dir: |
276 | if (extlog_l1_addr) | 276 | if (extlog_l1_addr) |
277 | acpi_os_unmap_memory(extlog_l1_addr, l1_size); | 277 | acpi_os_unmap_iomem(extlog_l1_addr, l1_size); |
278 | release_mem_region(l1_dirbase, l1_size); | 278 | release_mem_region(l1_dirbase, l1_size); |
279 | err: | 279 | err: |
280 | pr_warn(FW_BUG "Extended error log disabled because of problems parsing f/w tables\n"); | 280 | pr_warn(FW_BUG "Extended error log disabled because of problems parsing f/w tables\n"); |
@@ -287,9 +287,9 @@ static void __exit extlog_exit(void) | |||
287 | mce_unregister_decode_chain(&extlog_mce_dec); | 287 | mce_unregister_decode_chain(&extlog_mce_dec); |
288 | ((struct extlog_l1_head *)extlog_l1_addr)->flags &= ~FLAG_OS_OPTIN; | 288 | ((struct extlog_l1_head *)extlog_l1_addr)->flags &= ~FLAG_OS_OPTIN; |
289 | if (extlog_l1_addr) | 289 | if (extlog_l1_addr) |
290 | acpi_os_unmap_memory(extlog_l1_addr, l1_size); | 290 | acpi_os_unmap_iomem(extlog_l1_addr, l1_size); |
291 | if (elog_addr) | 291 | if (elog_addr) |
292 | acpi_os_unmap_memory(elog_addr, elog_size); | 292 | acpi_os_unmap_iomem(elog_addr, elog_size); |
293 | release_mem_region(elog_base, elog_size); | 293 | release_mem_region(elog_base, elog_size); |
294 | release_mem_region(l1_dirbase, l1_size); | 294 | release_mem_region(l1_dirbase, l1_size); |
295 | kfree(elog_buf); | 295 | kfree(elog_buf); |
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index b7ed86a20427..8bb43f06e11f 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile | |||
@@ -135,6 +135,7 @@ acpi-y += \ | |||
135 | rsxface.o | 135 | rsxface.o |
136 | 136 | ||
137 | acpi-y += \ | 137 | acpi-y += \ |
138 | tbdata.o \ | ||
138 | tbfadt.o \ | 139 | tbfadt.o \ |
139 | tbfind.o \ | 140 | tbfind.o \ |
140 | tbinstal.o \ | 141 | tbinstal.o \ |
diff --git a/drivers/acpi/acpica/acapps.h b/drivers/acpi/acpica/acapps.h new file mode 100644 index 000000000000..8698ffba6f39 --- /dev/null +++ b/drivers/acpi/acpica/acapps.h | |||
@@ -0,0 +1,170 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: acapps - common include for ACPI applications/tools | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2014, 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 | #ifndef _ACAPPS | ||
45 | #define _ACAPPS | ||
46 | |||
47 | /* Common info for tool signons */ | ||
48 | |||
49 | #define ACPICA_NAME "Intel ACPI Component Architecture" | ||
50 | #define ACPICA_COPYRIGHT "Copyright (c) 2000 - 2014 Intel Corporation" | ||
51 | |||
52 | #if ACPI_MACHINE_WIDTH == 64 | ||
53 | #define ACPI_WIDTH "-64" | ||
54 | |||
55 | #elif ACPI_MACHINE_WIDTH == 32 | ||
56 | #define ACPI_WIDTH "-32" | ||
57 | |||
58 | #else | ||
59 | #error unknown ACPI_MACHINE_WIDTH | ||
60 | #define ACPI_WIDTH "-??" | ||
61 | |||
62 | #endif | ||
63 | |||
64 | /* Macros for signons and file headers */ | ||
65 | |||
66 | #define ACPI_COMMON_SIGNON(utility_name) \ | ||
67 | "\n%s\n%s version %8.8X%s [%s]\n%s\n\n", \ | ||
68 | ACPICA_NAME, \ | ||
69 | utility_name, ((u32) ACPI_CA_VERSION), ACPI_WIDTH, __DATE__, \ | ||
70 | ACPICA_COPYRIGHT | ||
71 | |||
72 | #define ACPI_COMMON_HEADER(utility_name, prefix) \ | ||
73 | "%s%s\n%s%s version %8.8X%s [%s]\n%s%s\n%s\n", \ | ||
74 | prefix, ACPICA_NAME, \ | ||
75 | prefix, utility_name, ((u32) ACPI_CA_VERSION), ACPI_WIDTH, __DATE__, \ | ||
76 | prefix, ACPICA_COPYRIGHT, \ | ||
77 | prefix | ||
78 | |||
79 | /* Macros for usage messages */ | ||
80 | |||
81 | #define ACPI_USAGE_HEADER(usage) \ | ||
82 | printf ("Usage: %s\nOptions:\n", usage); | ||
83 | |||
84 | #define ACPI_OPTION(name, description) \ | ||
85 | printf (" %-18s%s\n", name, description); | ||
86 | |||
87 | #define FILE_SUFFIX_DISASSEMBLY "dsl" | ||
88 | #define ACPI_TABLE_FILE_SUFFIX ".dat" | ||
89 | |||
90 | /* | ||
91 | * getopt | ||
92 | */ | ||
93 | int acpi_getopt(int argc, char **argv, char *opts); | ||
94 | |||
95 | int acpi_getopt_argument(int argc, char **argv); | ||
96 | |||
97 | extern int acpi_gbl_optind; | ||
98 | extern int acpi_gbl_opterr; | ||
99 | extern int acpi_gbl_sub_opt_char; | ||
100 | extern char *acpi_gbl_optarg; | ||
101 | |||
102 | /* | ||
103 | * cmfsize - Common get file size function | ||
104 | */ | ||
105 | u32 cm_get_file_size(FILE * file); | ||
106 | |||
107 | #ifndef ACPI_DUMP_APP | ||
108 | /* | ||
109 | * adisasm | ||
110 | */ | ||
111 | acpi_status | ||
112 | ad_aml_disassemble(u8 out_to_file, | ||
113 | char *filename, char *prefix, char **out_filename); | ||
114 | |||
115 | void ad_print_statistics(void); | ||
116 | |||
117 | acpi_status ad_find_dsdt(u8 **dsdt_ptr, u32 *dsdt_length); | ||
118 | |||
119 | void ad_dump_tables(void); | ||
120 | |||
121 | acpi_status ad_get_local_tables(void); | ||
122 | |||
123 | acpi_status | ||
124 | ad_parse_table(struct acpi_table_header *table, | ||
125 | acpi_owner_id * owner_id, u8 load_table, u8 external); | ||
126 | |||
127 | acpi_status ad_display_tables(char *filename, struct acpi_table_header *table); | ||
128 | |||
129 | acpi_status ad_display_statistics(void); | ||
130 | |||
131 | /* | ||
132 | * adwalk | ||
133 | */ | ||
134 | void | ||
135 | acpi_dm_cross_reference_namespace(union acpi_parse_object *parse_tree_root, | ||
136 | struct acpi_namespace_node *namespace_root, | ||
137 | acpi_owner_id owner_id); | ||
138 | |||
139 | void acpi_dm_dump_tree(union acpi_parse_object *origin); | ||
140 | |||
141 | void acpi_dm_find_orphan_methods(union acpi_parse_object *origin); | ||
142 | |||
143 | void | ||
144 | acpi_dm_finish_namespace_load(union acpi_parse_object *parse_tree_root, | ||
145 | struct acpi_namespace_node *namespace_root, | ||
146 | acpi_owner_id owner_id); | ||
147 | |||
148 | void | ||
149 | acpi_dm_convert_resource_indexes(union acpi_parse_object *parse_tree_root, | ||
150 | struct acpi_namespace_node *namespace_root); | ||
151 | |||
152 | /* | ||
153 | * adfile | ||
154 | */ | ||
155 | acpi_status ad_initialize(void); | ||
156 | |||
157 | char *fl_generate_filename(char *input_filename, char *suffix); | ||
158 | |||
159 | acpi_status | ||
160 | fl_split_input_pathname(char *input_path, | ||
161 | char **out_directory_path, char **out_filename); | ||
162 | |||
163 | char *ad_generate_filename(char *prefix, char *table_id); | ||
164 | |||
165 | void | ||
166 | ad_write_table(struct acpi_table_header *table, | ||
167 | u32 length, char *table_name, char *oem_table_id); | ||
168 | #endif | ||
169 | |||
170 | #endif /* _ACAPPS */ | ||
diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index 68ec61fff188..7a7811a9fc26 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h | |||
@@ -104,9 +104,10 @@ acpi_status acpi_ev_finish_gpe(struct acpi_gpe_event_info *gpe_event_info); | |||
104 | */ | 104 | */ |
105 | acpi_status | 105 | acpi_status |
106 | acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, | 106 | acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, |
107 | struct acpi_generic_address *gpe_block_address, | 107 | u64 address, |
108 | u8 space_id, | ||
108 | u32 register_count, | 109 | u32 register_count, |
109 | u8 gpe_block_base_number, | 110 | u16 gpe_block_base_number, |
110 | u32 interrupt_number, | 111 | u32 interrupt_number, |
111 | struct acpi_gpe_block_info **return_gpe_block); | 112 | struct acpi_gpe_block_info **return_gpe_block); |
112 | 113 | ||
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index a08a448068dd..115eedcade1e 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h | |||
@@ -44,144 +44,14 @@ | |||
44 | #ifndef __ACGLOBAL_H__ | 44 | #ifndef __ACGLOBAL_H__ |
45 | #define __ACGLOBAL_H__ | 45 | #define __ACGLOBAL_H__ |
46 | 46 | ||
47 | /* | ||
48 | * Ensure that the globals are actually defined and initialized only once. | ||
49 | * | ||
50 | * The use of these macros allows a single list of globals (here) in order | ||
51 | * to simplify maintenance of the code. | ||
52 | */ | ||
53 | #ifdef DEFINE_ACPI_GLOBALS | ||
54 | #define ACPI_GLOBAL(type,name) \ | ||
55 | extern type name; \ | ||
56 | type name | ||
57 | |||
58 | #define ACPI_INIT_GLOBAL(type,name,value) \ | ||
59 | type name=value | ||
60 | |||
61 | #else | ||
62 | #define ACPI_GLOBAL(type,name) \ | ||
63 | extern type name | ||
64 | |||
65 | #define ACPI_INIT_GLOBAL(type,name,value) \ | ||
66 | extern type name | ||
67 | #endif | ||
68 | |||
69 | #ifdef DEFINE_ACPI_GLOBALS | ||
70 | |||
71 | /* Public globals, available from outside ACPICA subsystem */ | ||
72 | |||
73 | /***************************************************************************** | 47 | /***************************************************************************** |
74 | * | 48 | * |
75 | * Runtime configuration (static defaults that can be overriden at runtime) | 49 | * Globals related to the ACPI tables |
76 | * | 50 | * |
77 | ****************************************************************************/ | 51 | ****************************************************************************/ |
78 | 52 | ||
79 | /* | 53 | /* Master list of all ACPI tables that were found in the RSDT/XSDT */ |
80 | * Enable "slack" in the AML interpreter? Default is FALSE, and the | ||
81 | * interpreter strictly follows the ACPI specification. Setting to TRUE | ||
82 | * allows the interpreter to ignore certain errors and/or bad AML constructs. | ||
83 | * | ||
84 | * Currently, these features are enabled by this flag: | ||
85 | * | ||
86 | * 1) Allow "implicit return" of last value in a control method | ||
87 | * 2) Allow access beyond the end of an operation region | ||
88 | * 3) Allow access to uninitialized locals/args (auto-init to integer 0) | ||
89 | * 4) Allow ANY object type to be a source operand for the Store() operator | ||
90 | * 5) Allow unresolved references (invalid target name) in package objects | ||
91 | * 6) Enable warning messages for behavior that is not ACPI spec compliant | ||
92 | */ | ||
93 | ACPI_INIT_GLOBAL(u8, acpi_gbl_enable_interpreter_slack, FALSE); | ||
94 | 54 | ||
95 | /* | ||
96 | * Automatically serialize all methods that create named objects? Default | ||
97 | * is TRUE, meaning that all non_serialized methods are scanned once at | ||
98 | * table load time to determine those that create named objects. Methods | ||
99 | * that create named objects are marked Serialized in order to prevent | ||
100 | * possible run-time problems if they are entered by more than one thread. | ||
101 | */ | ||
102 | ACPI_INIT_GLOBAL(u8, acpi_gbl_auto_serialize_methods, TRUE); | ||
103 | |||
104 | /* | ||
105 | * Create the predefined _OSI method in the namespace? Default is TRUE | ||
106 | * because ACPI CA is fully compatible with other ACPI implementations. | ||
107 | * Changing this will revert ACPI CA (and machine ASL) to pre-OSI behavior. | ||
108 | */ | ||
109 | ACPI_INIT_GLOBAL(u8, acpi_gbl_create_osi_method, TRUE); | ||
110 | |||
111 | /* | ||
112 | * Optionally use default values for the ACPI register widths. Set this to | ||
113 | * TRUE to use the defaults, if an FADT contains incorrect widths/lengths. | ||
114 | */ | ||
115 | ACPI_INIT_GLOBAL(u8, acpi_gbl_use_default_register_widths, TRUE); | ||
116 | |||
117 | /* | ||
118 | * Optionally enable output from the AML Debug Object. | ||
119 | */ | ||
120 | ACPI_INIT_GLOBAL(u8, acpi_gbl_enable_aml_debug_object, FALSE); | ||
121 | |||
122 | /* | ||
123 | * Optionally copy the entire DSDT to local memory (instead of simply | ||
124 | * mapping it.) There are some BIOSs that corrupt or replace the original | ||
125 | * DSDT, creating the need for this option. Default is FALSE, do not copy | ||
126 | * the DSDT. | ||
127 | */ | ||
128 | ACPI_INIT_GLOBAL(u8, acpi_gbl_copy_dsdt_locally, FALSE); | ||
129 | |||
130 | /* | ||
131 | * Optionally ignore an XSDT if present and use the RSDT instead. | ||
132 | * Although the ACPI specification requires that an XSDT be used instead | ||
133 | * of the RSDT, the XSDT has been found to be corrupt or ill-formed on | ||
134 | * some machines. Default behavior is to use the XSDT if present. | ||
135 | */ | ||
136 | ACPI_INIT_GLOBAL(u8, acpi_gbl_do_not_use_xsdt, FALSE); | ||
137 | |||
138 | /* | ||
139 | * Optionally use 32-bit FADT addresses if and when there is a conflict | ||
140 | * (address mismatch) between the 32-bit and 64-bit versions of the | ||
141 | * address. Although ACPICA adheres to the ACPI specification which | ||
142 | * requires the use of the corresponding 64-bit address if it is non-zero, | ||
143 | * some machines have been found to have a corrupted non-zero 64-bit | ||
144 | * address. Default is TRUE, favor the 32-bit addresses. | ||
145 | */ | ||
146 | ACPI_INIT_GLOBAL(u8, acpi_gbl_use32_bit_fadt_addresses, TRUE); | ||
147 | |||
148 | /* | ||
149 | * Optionally truncate I/O addresses to 16 bits. Provides compatibility | ||
150 | * with other ACPI implementations. NOTE: During ACPICA initialization, | ||
151 | * this value is set to TRUE if any Windows OSI strings have been | ||
152 | * requested by the BIOS. | ||
153 | */ | ||
154 | ACPI_INIT_GLOBAL(u8, acpi_gbl_truncate_io_addresses, FALSE); | ||
155 | |||
156 | /* | ||
157 | * Disable runtime checking and repair of values returned by control methods. | ||
158 | * Use only if the repair is causing a problem on a particular machine. | ||
159 | */ | ||
160 | ACPI_INIT_GLOBAL(u8, acpi_gbl_disable_auto_repair, FALSE); | ||
161 | |||
162 | /* | ||
163 | * Optionally do not load any SSDTs from the RSDT/XSDT during initialization. | ||
164 | * This can be useful for debugging ACPI problems on some machines. | ||
165 | */ | ||
166 | ACPI_INIT_GLOBAL(u8, acpi_gbl_disable_ssdt_table_load, FALSE); | ||
167 | |||
168 | /* | ||
169 | * We keep track of the latest version of Windows that has been requested by | ||
170 | * the BIOS. | ||
171 | */ | ||
172 | ACPI_INIT_GLOBAL(u8, acpi_gbl_osi_data, 0); | ||
173 | |||
174 | #endif /* DEFINE_ACPI_GLOBALS */ | ||
175 | |||
176 | /***************************************************************************** | ||
177 | * | ||
178 | * ACPI Table globals | ||
179 | * | ||
180 | ****************************************************************************/ | ||
181 | |||
182 | /* | ||
183 | * Master list of all ACPI tables that were found in the RSDT/XSDT. | ||
184 | */ | ||
185 | ACPI_GLOBAL(struct acpi_table_list, acpi_gbl_root_table_list); | 55 | ACPI_GLOBAL(struct acpi_table_list, acpi_gbl_root_table_list); |
186 | 56 | ||
187 | /* DSDT information. Used to check for DSDT corruption */ | 57 | /* DSDT information. Used to check for DSDT corruption */ |
@@ -279,7 +149,6 @@ ACPI_GLOBAL(acpi_exception_handler, acpi_gbl_exception_handler); | |||
279 | ACPI_GLOBAL(acpi_init_handler, acpi_gbl_init_handler); | 149 | ACPI_GLOBAL(acpi_init_handler, acpi_gbl_init_handler); |
280 | ACPI_GLOBAL(acpi_table_handler, acpi_gbl_table_handler); | 150 | ACPI_GLOBAL(acpi_table_handler, acpi_gbl_table_handler); |
281 | ACPI_GLOBAL(void *, acpi_gbl_table_handler_context); | 151 | ACPI_GLOBAL(void *, acpi_gbl_table_handler_context); |
282 | ACPI_GLOBAL(struct acpi_walk_state *, acpi_gbl_breakpoint_walk); | ||
283 | ACPI_GLOBAL(acpi_interface_handler, acpi_gbl_interface_handler); | 152 | ACPI_GLOBAL(acpi_interface_handler, acpi_gbl_interface_handler); |
284 | ACPI_GLOBAL(struct acpi_sci_handler_info *, acpi_gbl_sci_handler_list); | 153 | ACPI_GLOBAL(struct acpi_sci_handler_info *, acpi_gbl_sci_handler_list); |
285 | 154 | ||
@@ -296,7 +165,6 @@ ACPI_GLOBAL(u8, acpi_gbl_reg_methods_executed); | |||
296 | /* Misc */ | 165 | /* Misc */ |
297 | 166 | ||
298 | ACPI_GLOBAL(u32, acpi_gbl_original_mode); | 167 | ACPI_GLOBAL(u32, acpi_gbl_original_mode); |
299 | ACPI_GLOBAL(u32, acpi_gbl_rsdp_original_location); | ||
300 | ACPI_GLOBAL(u32, acpi_gbl_ns_lookup_count); | 168 | ACPI_GLOBAL(u32, acpi_gbl_ns_lookup_count); |
301 | ACPI_GLOBAL(u32, acpi_gbl_ps_find_count); | 169 | ACPI_GLOBAL(u32, acpi_gbl_ps_find_count); |
302 | ACPI_GLOBAL(u16, acpi_gbl_pm1_enable_register_save); | 170 | ACPI_GLOBAL(u16, acpi_gbl_pm1_enable_register_save); |
@@ -483,11 +351,6 @@ ACPI_GLOBAL(u16, acpi_gbl_node_type_count_misc); | |||
483 | ACPI_GLOBAL(u32, acpi_gbl_num_nodes); | 351 | ACPI_GLOBAL(u32, acpi_gbl_num_nodes); |
484 | ACPI_GLOBAL(u32, acpi_gbl_num_objects); | 352 | ACPI_GLOBAL(u32, acpi_gbl_num_objects); |
485 | 353 | ||
486 | ACPI_GLOBAL(u32, acpi_gbl_size_of_parse_tree); | ||
487 | ACPI_GLOBAL(u32, acpi_gbl_size_of_method_trees); | ||
488 | ACPI_GLOBAL(u32, acpi_gbl_size_of_node_entries); | ||
489 | ACPI_GLOBAL(u32, acpi_gbl_size_of_acpi_objects); | ||
490 | |||
491 | #endif /* ACPI_DEBUGGER */ | 354 | #endif /* ACPI_DEBUGGER */ |
492 | 355 | ||
493 | /***************************************************************************** | 356 | /***************************************************************************** |
@@ -509,5 +372,6 @@ ACPI_INIT_GLOBAL(ACPI_FILE, acpi_gbl_debug_file, NULL); | |||
509 | ****************************************************************************/ | 372 | ****************************************************************************/ |
510 | 373 | ||
511 | extern const struct ah_predefined_name asl_predefined_info[]; | 374 | extern const struct ah_predefined_name asl_predefined_info[]; |
375 | extern const struct ah_device_id asl_device_ids[]; | ||
512 | 376 | ||
513 | #endif /* __ACGLOBAL_H__ */ | 377 | #endif /* __ACGLOBAL_H__ */ |
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 52a21dafb540..91f801a2e689 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h | |||
@@ -450,9 +450,9 @@ struct acpi_gpe_event_info { | |||
450 | struct acpi_gpe_register_info { | 450 | struct acpi_gpe_register_info { |
451 | struct acpi_generic_address status_address; /* Address of status reg */ | 451 | struct acpi_generic_address status_address; /* Address of status reg */ |
452 | struct acpi_generic_address enable_address; /* Address of enable reg */ | 452 | struct acpi_generic_address enable_address; /* Address of enable reg */ |
453 | u16 base_gpe_number; /* Base GPE number for this register */ | ||
453 | u8 enable_for_wake; /* GPEs to keep enabled when sleeping */ | 454 | u8 enable_for_wake; /* GPEs to keep enabled when sleeping */ |
454 | u8 enable_for_run; /* GPEs to keep enabled when running */ | 455 | u8 enable_for_run; /* GPEs to keep enabled when running */ |
455 | u8 base_gpe_number; /* Base GPE number for this register */ | ||
456 | }; | 456 | }; |
457 | 457 | ||
458 | /* | 458 | /* |
@@ -466,11 +466,12 @@ struct acpi_gpe_block_info { | |||
466 | struct acpi_gpe_xrupt_info *xrupt_block; /* Backpointer to interrupt block */ | 466 | struct acpi_gpe_xrupt_info *xrupt_block; /* Backpointer to interrupt block */ |
467 | struct acpi_gpe_register_info *register_info; /* One per GPE register pair */ | 467 | struct acpi_gpe_register_info *register_info; /* One per GPE register pair */ |
468 | struct acpi_gpe_event_info *event_info; /* One for each GPE */ | 468 | struct acpi_gpe_event_info *event_info; /* One for each GPE */ |
469 | struct acpi_generic_address block_address; /* Base address of the block */ | 469 | u64 address; /* Base address of the block */ |
470 | u32 register_count; /* Number of register pairs in block */ | 470 | u32 register_count; /* Number of register pairs in block */ |
471 | u16 gpe_count; /* Number of individual GPEs in block */ | 471 | u16 gpe_count; /* Number of individual GPEs in block */ |
472 | u8 block_base_number; /* Base GPE number for this block */ | 472 | u16 block_base_number; /* Base GPE number for this block */ |
473 | u8 initialized; /* TRUE if this block is initialized */ | 473 | u8 space_id; |
474 | u8 initialized; /* TRUE if this block is initialized */ | ||
474 | }; | 475 | }; |
475 | 476 | ||
476 | /* Information about GPE interrupt handlers, one per each interrupt level used for GPEs */ | 477 | /* Information about GPE interrupt handlers, one per each interrupt level used for GPEs */ |
@@ -733,7 +734,8 @@ union acpi_parse_value { | |||
733 | #define ACPI_DASM_MATCHOP 0x06 /* Parent opcode is a Match() operator */ | 734 | #define ACPI_DASM_MATCHOP 0x06 /* Parent opcode is a Match() operator */ |
734 | #define ACPI_DASM_LNOT_PREFIX 0x07 /* Start of a Lnot_equal (etc.) pair of opcodes */ | 735 | #define ACPI_DASM_LNOT_PREFIX 0x07 /* Start of a Lnot_equal (etc.) pair of opcodes */ |
735 | #define ACPI_DASM_LNOT_SUFFIX 0x08 /* End of a Lnot_equal (etc.) pair of opcodes */ | 736 | #define ACPI_DASM_LNOT_SUFFIX 0x08 /* End of a Lnot_equal (etc.) pair of opcodes */ |
736 | #define ACPI_DASM_IGNORE 0x09 /* Not used at this time */ | 737 | #define ACPI_DASM_HID_STRING 0x09 /* String is a _HID or _CID */ |
738 | #define ACPI_DASM_IGNORE 0x0A /* Not used at this time */ | ||
737 | 739 | ||
738 | /* | 740 | /* |
739 | * Generic operation (for example: If, While, Store) | 741 | * Generic operation (for example: If, While, Store) |
@@ -1147,4 +1149,9 @@ struct ah_predefined_name { | |||
1147 | #endif | 1149 | #endif |
1148 | }; | 1150 | }; |
1149 | 1151 | ||
1152 | struct ah_device_id { | ||
1153 | char *name; | ||
1154 | char *description; | ||
1155 | }; | ||
1156 | |||
1150 | #endif /* __ACLOCAL_H__ */ | 1157 | #endif /* __ACLOCAL_H__ */ |
diff --git a/drivers/acpi/acpica/acpredef.h b/drivers/acpi/acpica/acpredef.h index a48d713e9599..bd08817cafd8 100644 --- a/drivers/acpi/acpica/acpredef.h +++ b/drivers/acpi/acpica/acpredef.h | |||
@@ -586,6 +586,10 @@ const union acpi_predefined_info acpi_gbl_predefined_methods[] = { | |||
586 | {{"_LID", METHOD_0ARGS, | 586 | {{"_LID", METHOD_0ARGS, |
587 | METHOD_RETURNS(ACPI_RTYPE_INTEGER)}}, | 587 | METHOD_RETURNS(ACPI_RTYPE_INTEGER)}}, |
588 | 588 | ||
589 | {{"_LPD", METHOD_0ARGS, | ||
590 | METHOD_RETURNS(ACPI_RTYPE_PACKAGE)}}, /* Variable-length (1 Int(rev), n Pkg (2 Int) */ | ||
591 | PACKAGE_INFO(ACPI_PTYPE2_REV_FIXED, ACPI_RTYPE_INTEGER, 2, 0, 0, 0), | ||
592 | |||
589 | {{"_MAT", METHOD_0ARGS, | 593 | {{"_MAT", METHOD_0ARGS, |
590 | METHOD_RETURNS(ACPI_RTYPE_BUFFER)}}, | 594 | METHOD_RETURNS(ACPI_RTYPE_BUFFER)}}, |
591 | 595 | ||
@@ -698,12 +702,6 @@ const union acpi_predefined_info acpi_gbl_predefined_methods[] = { | |||
698 | METHOD_RETURNS(ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Refs) */ | 702 | METHOD_RETURNS(ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Refs) */ |
699 | PACKAGE_INFO(ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0), | 703 | PACKAGE_INFO(ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0), |
700 | 704 | ||
701 | {{"_PRP", METHOD_0ARGS, | ||
702 | METHOD_RETURNS(ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Pkgs) each: 1 Str, 1 Int/Str/Pkg */ | ||
703 | PACKAGE_INFO(ACPI_PTYPE2, ACPI_RTYPE_STRING, 1, | ||
704 | ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | | ||
705 | ACPI_RTYPE_PACKAGE | ACPI_RTYPE_REFERENCE, 1, 0), | ||
706 | |||
707 | {{"_PRS", METHOD_0ARGS, | 705 | {{"_PRS", METHOD_0ARGS, |
708 | METHOD_RETURNS(ACPI_RTYPE_BUFFER)}}, | 706 | METHOD_RETURNS(ACPI_RTYPE_BUFFER)}}, |
709 | 707 | ||
diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h index 5fa4b2027697..f14882788eee 100644 --- a/drivers/acpi/acpica/actables.h +++ b/drivers/acpi/acpica/actables.h | |||
@@ -54,6 +54,31 @@ acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp); | |||
54 | u8 *acpi_tb_scan_memory_for_rsdp(u8 *start_address, u32 length); | 54 | u8 *acpi_tb_scan_memory_for_rsdp(u8 *start_address, u32 length); |
55 | 55 | ||
56 | /* | 56 | /* |
57 | * tbdata - table data structure management | ||
58 | */ | ||
59 | acpi_status acpi_tb_get_next_root_index(u32 *table_index); | ||
60 | |||
61 | void | ||
62 | acpi_tb_init_table_descriptor(struct acpi_table_desc *table_desc, | ||
63 | acpi_physical_address address, | ||
64 | u8 flags, struct acpi_table_header *table); | ||
65 | |||
66 | acpi_status | ||
67 | acpi_tb_acquire_temp_table(struct acpi_table_desc *table_desc, | ||
68 | acpi_physical_address address, u8 flags); | ||
69 | |||
70 | void acpi_tb_release_temp_table(struct acpi_table_desc *table_desc); | ||
71 | |||
72 | acpi_status acpi_tb_validate_temp_table(struct acpi_table_desc *table_desc); | ||
73 | |||
74 | acpi_status | ||
75 | acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc, char *signature); | ||
76 | |||
77 | u8 acpi_tb_is_table_loaded(u32 table_index); | ||
78 | |||
79 | void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded); | ||
80 | |||
81 | /* | ||
57 | * tbfadt - FADT parse/convert/validate | 82 | * tbfadt - FADT parse/convert/validate |
58 | */ | 83 | */ |
59 | void acpi_tb_parse_fadt(u32 table_index); | 84 | void acpi_tb_parse_fadt(u32 table_index); |
@@ -72,22 +97,32 @@ acpi_tb_find_table(char *signature, | |||
72 | */ | 97 | */ |
73 | acpi_status acpi_tb_resize_root_table_list(void); | 98 | acpi_status acpi_tb_resize_root_table_list(void); |
74 | 99 | ||
75 | acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc); | 100 | acpi_status acpi_tb_validate_table(struct acpi_table_desc *table_desc); |
101 | |||
102 | void acpi_tb_invalidate_table(struct acpi_table_desc *table_desc); | ||
103 | |||
104 | void acpi_tb_override_table(struct acpi_table_desc *old_table_desc); | ||
76 | 105 | ||
77 | struct acpi_table_header *acpi_tb_table_override(struct acpi_table_header | 106 | acpi_status |
78 | *table_header, | 107 | acpi_tb_acquire_table(struct acpi_table_desc *table_desc, |
79 | struct acpi_table_desc | 108 | struct acpi_table_header **table_ptr, |
80 | *table_desc); | 109 | u32 *table_length, u8 *table_flags); |
110 | |||
111 | void | ||
112 | acpi_tb_release_table(struct acpi_table_header *table, | ||
113 | u32 table_length, u8 table_flags); | ||
81 | 114 | ||
82 | acpi_status | 115 | acpi_status |
83 | acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index); | 116 | acpi_tb_install_standard_table(acpi_physical_address address, |
117 | u8 flags, | ||
118 | u8 reload, u8 override, u32 *table_index); | ||
84 | 119 | ||
85 | acpi_status | 120 | acpi_status |
86 | acpi_tb_store_table(acpi_physical_address address, | 121 | acpi_tb_store_table(acpi_physical_address address, |
87 | struct acpi_table_header *table, | 122 | struct acpi_table_header *table, |
88 | u32 length, u8 flags, u32 *table_index); | 123 | u32 length, u8 flags, u32 *table_index); |
89 | 124 | ||
90 | void acpi_tb_delete_table(struct acpi_table_desc *table_desc); | 125 | void acpi_tb_uninstall_table(struct acpi_table_desc *table_desc); |
91 | 126 | ||
92 | void acpi_tb_terminate(void); | 127 | void acpi_tb_terminate(void); |
93 | 128 | ||
@@ -99,10 +134,6 @@ acpi_status acpi_tb_release_owner_id(u32 table_index); | |||
99 | 134 | ||
100 | acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id *owner_id); | 135 | acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id *owner_id); |
101 | 136 | ||
102 | u8 acpi_tb_is_table_loaded(u32 table_index); | ||
103 | |||
104 | void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded); | ||
105 | |||
106 | /* | 137 | /* |
107 | * tbutils - table manager utilities | 138 | * tbutils - table manager utilities |
108 | */ | 139 | */ |
@@ -124,8 +155,13 @@ void acpi_tb_check_dsdt_header(void); | |||
124 | struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index); | 155 | struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index); |
125 | 156 | ||
126 | void | 157 | void |
127 | acpi_tb_install_table(acpi_physical_address address, | 158 | acpi_tb_install_table_with_override(u32 table_index, |
128 | char *signature, u32 table_index); | 159 | struct acpi_table_desc *new_table_desc, |
160 | u8 override); | ||
161 | |||
162 | acpi_status | ||
163 | acpi_tb_install_fixed_table(acpi_physical_address address, | ||
164 | char *signature, u32 table_index); | ||
129 | 165 | ||
130 | acpi_status acpi_tb_parse_root_table(acpi_physical_address rsdp_address); | 166 | acpi_status acpi_tb_parse_root_table(acpi_physical_address rsdp_address); |
131 | 167 | ||
diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index ceeec0b7ccb1..1e256c5bda20 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h | |||
@@ -176,8 +176,7 @@ acpi_status acpi_ut_init_globals(void); | |||
176 | 176 | ||
177 | char *acpi_ut_get_mutex_name(u32 mutex_id); | 177 | char *acpi_ut_get_mutex_name(u32 mutex_id); |
178 | 178 | ||
179 | const char *acpi_ut_get_notify_name(u32 notify_value); | 179 | const char *acpi_ut_get_notify_name(u32 notify_value, acpi_object_type type); |
180 | |||
181 | #endif | 180 | #endif |
182 | 181 | ||
183 | char *acpi_ut_get_type_name(acpi_object_type type); | 182 | char *acpi_ut_get_type_name(acpi_object_type type); |
@@ -737,4 +736,11 @@ acpi_ut_method_error(const char *module_name, | |||
737 | struct acpi_namespace_node *node, | 736 | struct acpi_namespace_node *node, |
738 | const char *path, acpi_status lookup_status); | 737 | const char *path, acpi_status lookup_status); |
739 | 738 | ||
739 | /* | ||
740 | * Utility functions for ACPI names and IDs | ||
741 | */ | ||
742 | const struct ah_predefined_name *acpi_ah_match_predefined_name(char *nameseg); | ||
743 | |||
744 | const struct ah_device_id *acpi_ah_match_hardware_id(char *hid); | ||
745 | |||
740 | #endif /* _ACUTILS_H */ | 746 | #endif /* _ACUTILS_H */ |
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index 955f83da68a5..48f70013b488 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c | |||
@@ -383,7 +383,7 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) | |||
383 | if (!(gpe_register_info->enable_for_run | | 383 | if (!(gpe_register_info->enable_for_run | |
384 | gpe_register_info->enable_for_wake)) { | 384 | gpe_register_info->enable_for_wake)) { |
385 | ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS, | 385 | ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS, |
386 | "Ignore disabled registers for GPE%02X-GPE%02X: " | 386 | "Ignore disabled registers for GPE %02X-%02X: " |
387 | "RunEnable=%02X, WakeEnable=%02X\n", | 387 | "RunEnable=%02X, WakeEnable=%02X\n", |
388 | gpe_register_info-> | 388 | gpe_register_info-> |
389 | base_gpe_number, | 389 | base_gpe_number, |
@@ -416,7 +416,7 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) | |||
416 | } | 416 | } |
417 | 417 | ||
418 | ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS, | 418 | ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS, |
419 | "Read registers for GPE%02X-GPE%02X: Status=%02X, Enable=%02X, " | 419 | "Read registers for GPE %02X-%02X: Status=%02X, Enable=%02X, " |
420 | "RunEnable=%02X, WakeEnable=%02X\n", | 420 | "RunEnable=%02X, WakeEnable=%02X\n", |
421 | gpe_register_info->base_gpe_number, | 421 | gpe_register_info->base_gpe_number, |
422 | gpe_register_info->base_gpe_number + | 422 | gpe_register_info->base_gpe_number + |
@@ -706,7 +706,8 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, | |||
706 | status = acpi_hw_clear_gpe(gpe_event_info); | 706 | status = acpi_hw_clear_gpe(gpe_event_info); |
707 | if (ACPI_FAILURE(status)) { | 707 | if (ACPI_FAILURE(status)) { |
708 | ACPI_EXCEPTION((AE_INFO, status, | 708 | ACPI_EXCEPTION((AE_INFO, status, |
709 | "Unable to clear GPE%02X", gpe_number)); | 709 | "Unable to clear GPE %02X", |
710 | gpe_number)); | ||
710 | return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); | 711 | return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); |
711 | } | 712 | } |
712 | } | 713 | } |
@@ -723,7 +724,7 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, | |||
723 | status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE); | 724 | status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE); |
724 | if (ACPI_FAILURE(status)) { | 725 | if (ACPI_FAILURE(status)) { |
725 | ACPI_EXCEPTION((AE_INFO, status, | 726 | ACPI_EXCEPTION((AE_INFO, status, |
726 | "Unable to disable GPE%02X", gpe_number)); | 727 | "Unable to disable GPE %02X", gpe_number)); |
727 | return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); | 728 | return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); |
728 | } | 729 | } |
729 | 730 | ||
@@ -764,7 +765,7 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, | |||
764 | gpe_event_info); | 765 | gpe_event_info); |
765 | if (ACPI_FAILURE(status)) { | 766 | if (ACPI_FAILURE(status)) { |
766 | ACPI_EXCEPTION((AE_INFO, status, | 767 | ACPI_EXCEPTION((AE_INFO, status, |
767 | "Unable to queue handler for GPE%02X - event disabled", | 768 | "Unable to queue handler for GPE %02X - event disabled", |
768 | gpe_number)); | 769 | gpe_number)); |
769 | } | 770 | } |
770 | break; | 771 | break; |
@@ -776,7 +777,7 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, | |||
776 | * a GPE to be enabled if it has no handler or method. | 777 | * a GPE to be enabled if it has no handler or method. |
777 | */ | 778 | */ |
778 | ACPI_ERROR((AE_INFO, | 779 | ACPI_ERROR((AE_INFO, |
779 | "No handler or method for GPE%02X, disabling event", | 780 | "No handler or method for GPE %02X, disabling event", |
780 | gpe_number)); | 781 | gpe_number)); |
781 | 782 | ||
782 | break; | 783 | break; |
diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c index caaed3c673fd..d86699eea33c 100644 --- a/drivers/acpi/acpica/evgpeblk.c +++ b/drivers/acpi/acpica/evgpeblk.c | |||
@@ -252,21 +252,17 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block) | |||
252 | 252 | ||
253 | /* Init the register_info for this GPE register (8 GPEs) */ | 253 | /* Init the register_info for this GPE register (8 GPEs) */ |
254 | 254 | ||
255 | this_register->base_gpe_number = | 255 | this_register->base_gpe_number = (u16) |
256 | (u8) (gpe_block->block_base_number + | 256 | (gpe_block->block_base_number + |
257 | (i * ACPI_GPE_REGISTER_WIDTH)); | 257 | (i * ACPI_GPE_REGISTER_WIDTH)); |
258 | 258 | ||
259 | this_register->status_address.address = | 259 | this_register->status_address.address = gpe_block->address + i; |
260 | gpe_block->block_address.address + i; | ||
261 | 260 | ||
262 | this_register->enable_address.address = | 261 | this_register->enable_address.address = |
263 | gpe_block->block_address.address + i + | 262 | gpe_block->address + i + gpe_block->register_count; |
264 | gpe_block->register_count; | ||
265 | 263 | ||
266 | this_register->status_address.space_id = | 264 | this_register->status_address.space_id = gpe_block->space_id; |
267 | gpe_block->block_address.space_id; | 265 | this_register->enable_address.space_id = gpe_block->space_id; |
268 | this_register->enable_address.space_id = | ||
269 | gpe_block->block_address.space_id; | ||
270 | this_register->status_address.bit_width = | 266 | this_register->status_address.bit_width = |
271 | ACPI_GPE_REGISTER_WIDTH; | 267 | ACPI_GPE_REGISTER_WIDTH; |
272 | this_register->enable_address.bit_width = | 268 | this_register->enable_address.bit_width = |
@@ -334,9 +330,10 @@ error_exit: | |||
334 | 330 | ||
335 | acpi_status | 331 | acpi_status |
336 | acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, | 332 | acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, |
337 | struct acpi_generic_address *gpe_block_address, | 333 | u64 address, |
334 | u8 space_id, | ||
338 | u32 register_count, | 335 | u32 register_count, |
339 | u8 gpe_block_base_number, | 336 | u16 gpe_block_base_number, |
340 | u32 interrupt_number, | 337 | u32 interrupt_number, |
341 | struct acpi_gpe_block_info **return_gpe_block) | 338 | struct acpi_gpe_block_info **return_gpe_block) |
342 | { | 339 | { |
@@ -359,15 +356,14 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, | |||
359 | 356 | ||
360 | /* Initialize the new GPE block */ | 357 | /* Initialize the new GPE block */ |
361 | 358 | ||
359 | gpe_block->address = address; | ||
360 | gpe_block->space_id = space_id; | ||
362 | gpe_block->node = gpe_device; | 361 | gpe_block->node = gpe_device; |
363 | gpe_block->gpe_count = (u16)(register_count * ACPI_GPE_REGISTER_WIDTH); | 362 | gpe_block->gpe_count = (u16)(register_count * ACPI_GPE_REGISTER_WIDTH); |
364 | gpe_block->initialized = FALSE; | 363 | gpe_block->initialized = FALSE; |
365 | gpe_block->register_count = register_count; | 364 | gpe_block->register_count = register_count; |
366 | gpe_block->block_base_number = gpe_block_base_number; | 365 | gpe_block->block_base_number = gpe_block_base_number; |
367 | 366 | ||
368 | ACPI_MEMCPY(&gpe_block->block_address, gpe_block_address, | ||
369 | sizeof(struct acpi_generic_address)); | ||
370 | |||
371 | /* | 367 | /* |
372 | * Create the register_info and event_info sub-structures | 368 | * Create the register_info and event_info sub-structures |
373 | * Note: disables and clears all GPEs in the block | 369 | * Note: disables and clears all GPEs in the block |
@@ -408,12 +404,14 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, | |||
408 | } | 404 | } |
409 | 405 | ||
410 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, | 406 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, |
411 | " Initialized GPE %02X to %02X [%4.4s] %u regs on interrupt 0x%X\n", | 407 | " Initialized GPE %02X to %02X [%4.4s] %u regs on interrupt 0x%X%s\n", |
412 | (u32)gpe_block->block_base_number, | 408 | (u32)gpe_block->block_base_number, |
413 | (u32)(gpe_block->block_base_number + | 409 | (u32)(gpe_block->block_base_number + |
414 | (gpe_block->gpe_count - 1)), | 410 | (gpe_block->gpe_count - 1)), |
415 | gpe_device->name.ascii, gpe_block->register_count, | 411 | gpe_device->name.ascii, gpe_block->register_count, |
416 | interrupt_number)); | 412 | interrupt_number, |
413 | interrupt_number == | ||
414 | acpi_gbl_FADT.sci_interrupt ? " (SCI)" : "")); | ||
417 | 415 | ||
418 | /* Update global count of currently available GPEs */ | 416 | /* Update global count of currently available GPEs */ |
419 | 417 | ||
diff --git a/drivers/acpi/acpica/evgpeinit.c b/drivers/acpi/acpica/evgpeinit.c index ae779c1e871d..49fc7effd961 100644 --- a/drivers/acpi/acpica/evgpeinit.c +++ b/drivers/acpi/acpica/evgpeinit.c | |||
@@ -131,8 +131,10 @@ acpi_status acpi_ev_gpe_initialize(void) | |||
131 | /* Install GPE Block 0 */ | 131 | /* Install GPE Block 0 */ |
132 | 132 | ||
133 | status = acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device, | 133 | status = acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device, |
134 | &acpi_gbl_FADT.xgpe0_block, | 134 | acpi_gbl_FADT.xgpe0_block. |
135 | register_count0, 0, | 135 | address, |
136 | acpi_gbl_FADT.xgpe0_block. | ||
137 | space_id, register_count0, 0, | ||
136 | acpi_gbl_FADT.sci_interrupt, | 138 | acpi_gbl_FADT.sci_interrupt, |
137 | &acpi_gbl_gpe_fadt_blocks[0]); | 139 | &acpi_gbl_gpe_fadt_blocks[0]); |
138 | 140 | ||
@@ -169,8 +171,10 @@ acpi_status acpi_ev_gpe_initialize(void) | |||
169 | 171 | ||
170 | status = | 172 | status = |
171 | acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device, | 173 | acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device, |
172 | &acpi_gbl_FADT.xgpe1_block, | 174 | acpi_gbl_FADT.xgpe1_block. |
173 | register_count1, | 175 | address, |
176 | acpi_gbl_FADT.xgpe1_block. | ||
177 | space_id, register_count1, | ||
174 | acpi_gbl_FADT.gpe1_base, | 178 | acpi_gbl_FADT.gpe1_base, |
175 | acpi_gbl_FADT. | 179 | acpi_gbl_FADT. |
176 | sci_interrupt, | 180 | sci_interrupt, |
diff --git a/drivers/acpi/acpica/evmisc.c b/drivers/acpi/acpica/evmisc.c index 5d594eb2e5ec..24ea3424981b 100644 --- a/drivers/acpi/acpica/evmisc.c +++ b/drivers/acpi/acpica/evmisc.c | |||
@@ -167,7 +167,8 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node, | |||
167 | "Dispatching Notify on [%4.4s] (%s) Value 0x%2.2X (%s) Node %p\n", | 167 | "Dispatching Notify on [%4.4s] (%s) Value 0x%2.2X (%s) Node %p\n", |
168 | acpi_ut_get_node_name(node), | 168 | acpi_ut_get_node_name(node), |
169 | acpi_ut_get_type_name(node->type), notify_value, | 169 | acpi_ut_get_type_name(node->type), notify_value, |
170 | acpi_ut_get_notify_name(notify_value), node)); | 170 | acpi_ut_get_notify_name(notify_value, ACPI_TYPE_ANY), |
171 | node)); | ||
171 | 172 | ||
172 | status = acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_notify_dispatch, | 173 | status = acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_notify_dispatch, |
173 | info); | 174 | info); |
diff --git a/drivers/acpi/acpica/evsci.c b/drivers/acpi/acpica/evsci.c index 4d8a709c1fc4..29630e303829 100644 --- a/drivers/acpi/acpica/evsci.c +++ b/drivers/acpi/acpica/evsci.c | |||
@@ -117,7 +117,7 @@ static u32 ACPI_SYSTEM_XFACE acpi_ev_sci_xrupt_handler(void *context) | |||
117 | ACPI_FUNCTION_TRACE(ev_sci_xrupt_handler); | 117 | ACPI_FUNCTION_TRACE(ev_sci_xrupt_handler); |
118 | 118 | ||
119 | /* | 119 | /* |
120 | * We are guaranteed by the ACPI CA initialization/shutdown code that | 120 | * We are guaranteed by the ACPICA initialization/shutdown code that |
121 | * if this interrupt handler is installed, ACPI is enabled. | 121 | * if this interrupt handler is installed, ACPI is enabled. |
122 | */ | 122 | */ |
123 | 123 | ||
diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c index a734b27da061..11e5803b8b41 100644 --- a/drivers/acpi/acpica/evxface.c +++ b/drivers/acpi/acpica/evxface.c | |||
@@ -239,7 +239,7 @@ acpi_remove_notify_handler(acpi_handle device, | |||
239 | union acpi_operand_object *obj_desc; | 239 | union acpi_operand_object *obj_desc; |
240 | union acpi_operand_object *handler_obj; | 240 | union acpi_operand_object *handler_obj; |
241 | union acpi_operand_object *previous_handler_obj; | 241 | union acpi_operand_object *previous_handler_obj; |
242 | acpi_status status; | 242 | acpi_status status = AE_OK; |
243 | u32 i; | 243 | u32 i; |
244 | 244 | ||
245 | ACPI_FUNCTION_TRACE(acpi_remove_notify_handler); | 245 | ACPI_FUNCTION_TRACE(acpi_remove_notify_handler); |
@@ -251,20 +251,17 @@ acpi_remove_notify_handler(acpi_handle device, | |||
251 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 251 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
252 | } | 252 | } |
253 | 253 | ||
254 | /* Make sure all deferred notify tasks are completed */ | ||
255 | |||
256 | acpi_os_wait_events_complete(); | ||
257 | |||
258 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
259 | if (ACPI_FAILURE(status)) { | ||
260 | return_ACPI_STATUS(status); | ||
261 | } | ||
262 | |||
263 | /* Root Object. Global handlers are removed here */ | 254 | /* Root Object. Global handlers are removed here */ |
264 | 255 | ||
265 | if (device == ACPI_ROOT_OBJECT) { | 256 | if (device == ACPI_ROOT_OBJECT) { |
266 | for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) { | 257 | for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) { |
267 | if (handler_type & (i + 1)) { | 258 | if (handler_type & (i + 1)) { |
259 | status = | ||
260 | acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
261 | if (ACPI_FAILURE(status)) { | ||
262 | return_ACPI_STATUS(status); | ||
263 | } | ||
264 | |||
268 | if (!acpi_gbl_global_notify[i].handler || | 265 | if (!acpi_gbl_global_notify[i].handler || |
269 | (acpi_gbl_global_notify[i].handler != | 266 | (acpi_gbl_global_notify[i].handler != |
270 | handler)) { | 267 | handler)) { |
@@ -277,31 +274,40 @@ acpi_remove_notify_handler(acpi_handle device, | |||
277 | 274 | ||
278 | acpi_gbl_global_notify[i].handler = NULL; | 275 | acpi_gbl_global_notify[i].handler = NULL; |
279 | acpi_gbl_global_notify[i].context = NULL; | 276 | acpi_gbl_global_notify[i].context = NULL; |
277 | |||
278 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
279 | |||
280 | /* Make sure all deferred notify tasks are completed */ | ||
281 | |||
282 | acpi_os_wait_events_complete(); | ||
280 | } | 283 | } |
281 | } | 284 | } |
282 | 285 | ||
283 | goto unlock_and_exit; | 286 | return_ACPI_STATUS(AE_OK); |
284 | } | 287 | } |
285 | 288 | ||
286 | /* All other objects: Are Notifies allowed on this object? */ | 289 | /* All other objects: Are Notifies allowed on this object? */ |
287 | 290 | ||
288 | if (!acpi_ev_is_notify_object(node)) { | 291 | if (!acpi_ev_is_notify_object(node)) { |
289 | status = AE_TYPE; | 292 | return_ACPI_STATUS(AE_TYPE); |
290 | goto unlock_and_exit; | ||
291 | } | 293 | } |
292 | 294 | ||
293 | /* Must have an existing internal object */ | 295 | /* Must have an existing internal object */ |
294 | 296 | ||
295 | obj_desc = acpi_ns_get_attached_object(node); | 297 | obj_desc = acpi_ns_get_attached_object(node); |
296 | if (!obj_desc) { | 298 | if (!obj_desc) { |
297 | status = AE_NOT_EXIST; | 299 | return_ACPI_STATUS(AE_NOT_EXIST); |
298 | goto unlock_and_exit; | ||
299 | } | 300 | } |
300 | 301 | ||
301 | /* Internal object exists. Find the handler and remove it */ | 302 | /* Internal object exists. Find the handler and remove it */ |
302 | 303 | ||
303 | for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) { | 304 | for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) { |
304 | if (handler_type & (i + 1)) { | 305 | if (handler_type & (i + 1)) { |
306 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
307 | if (ACPI_FAILURE(status)) { | ||
308 | return_ACPI_STATUS(status); | ||
309 | } | ||
310 | |||
305 | handler_obj = obj_desc->common_notify.notify_list[i]; | 311 | handler_obj = obj_desc->common_notify.notify_list[i]; |
306 | previous_handler_obj = NULL; | 312 | previous_handler_obj = NULL; |
307 | 313 | ||
@@ -329,10 +335,17 @@ acpi_remove_notify_handler(acpi_handle device, | |||
329 | handler_obj->notify.next[i]; | 335 | handler_obj->notify.next[i]; |
330 | } | 336 | } |
331 | 337 | ||
338 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
339 | |||
340 | /* Make sure all deferred notify tasks are completed */ | ||
341 | |||
342 | acpi_os_wait_events_complete(); | ||
332 | acpi_ut_remove_reference(handler_obj); | 343 | acpi_ut_remove_reference(handler_obj); |
333 | } | 344 | } |
334 | } | 345 | } |
335 | 346 | ||
347 | return_ACPI_STATUS(status); | ||
348 | |||
336 | unlock_and_exit: | 349 | unlock_and_exit: |
337 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 350 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
338 | return_ACPI_STATUS(status); | 351 | return_ACPI_STATUS(status); |
@@ -457,6 +470,8 @@ exit: | |||
457 | return_ACPI_STATUS(status); | 470 | return_ACPI_STATUS(status); |
458 | } | 471 | } |
459 | 472 | ||
473 | ACPI_EXPORT_SYMBOL(acpi_install_sci_handler) | ||
474 | |||
460 | /******************************************************************************* | 475 | /******************************************************************************* |
461 | * | 476 | * |
462 | * FUNCTION: acpi_remove_sci_handler | 477 | * FUNCTION: acpi_remove_sci_handler |
@@ -468,7 +483,6 @@ exit: | |||
468 | * DESCRIPTION: Remove a handler for a System Control Interrupt. | 483 | * DESCRIPTION: Remove a handler for a System Control Interrupt. |
469 | * | 484 | * |
470 | ******************************************************************************/ | 485 | ******************************************************************************/ |
471 | |||
472 | acpi_status acpi_remove_sci_handler(acpi_sci_handler address) | 486 | acpi_status acpi_remove_sci_handler(acpi_sci_handler address) |
473 | { | 487 | { |
474 | struct acpi_sci_handler_info *prev_sci_handler; | 488 | struct acpi_sci_handler_info *prev_sci_handler; |
@@ -522,6 +536,8 @@ unlock_and_exit: | |||
522 | return_ACPI_STATUS(status); | 536 | return_ACPI_STATUS(status); |
523 | } | 537 | } |
524 | 538 | ||
539 | ACPI_EXPORT_SYMBOL(acpi_remove_sci_handler) | ||
540 | |||
525 | /******************************************************************************* | 541 | /******************************************************************************* |
526 | * | 542 | * |
527 | * FUNCTION: acpi_install_global_event_handler | 543 | * FUNCTION: acpi_install_global_event_handler |
@@ -537,7 +553,6 @@ unlock_and_exit: | |||
537 | * Can be used to update event counters, etc. | 553 | * Can be used to update event counters, etc. |
538 | * | 554 | * |
539 | ******************************************************************************/ | 555 | ******************************************************************************/ |
540 | |||
541 | acpi_status | 556 | acpi_status |
542 | acpi_install_global_event_handler(acpi_gbl_event_handler handler, void *context) | 557 | acpi_install_global_event_handler(acpi_gbl_event_handler handler, void *context) |
543 | { | 558 | { |
@@ -840,10 +855,6 @@ acpi_remove_gpe_handler(acpi_handle gpe_device, | |||
840 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 855 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
841 | } | 856 | } |
842 | 857 | ||
843 | /* Make sure all deferred GPE tasks are completed */ | ||
844 | |||
845 | acpi_os_wait_events_complete(); | ||
846 | |||
847 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | 858 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); |
848 | if (ACPI_FAILURE(status)) { | 859 | if (ACPI_FAILURE(status)) { |
849 | return_ACPI_STATUS(status); | 860 | return_ACPI_STATUS(status); |
@@ -895,9 +906,17 @@ acpi_remove_gpe_handler(acpi_handle gpe_device, | |||
895 | (void)acpi_ev_add_gpe_reference(gpe_event_info); | 906 | (void)acpi_ev_add_gpe_reference(gpe_event_info); |
896 | } | 907 | } |
897 | 908 | ||
909 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
910 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
911 | |||
912 | /* Make sure all deferred GPE tasks are completed */ | ||
913 | |||
914 | acpi_os_wait_events_complete(); | ||
915 | |||
898 | /* Now we can free the handler object */ | 916 | /* Now we can free the handler object */ |
899 | 917 | ||
900 | ACPI_FREE(handler); | 918 | ACPI_FREE(handler); |
919 | return_ACPI_STATUS(status); | ||
901 | 920 | ||
902 | unlock_and_exit: | 921 | unlock_and_exit: |
903 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | 922 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); |
diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c index 20a1392ffe06..cb534faf5369 100644 --- a/drivers/acpi/acpica/evxfgpe.c +++ b/drivers/acpi/acpica/evxfgpe.c | |||
@@ -599,9 +599,10 @@ acpi_install_gpe_block(acpi_handle gpe_device, | |||
599 | * For user-installed GPE Block Devices, the gpe_block_base_number | 599 | * For user-installed GPE Block Devices, the gpe_block_base_number |
600 | * is always zero | 600 | * is always zero |
601 | */ | 601 | */ |
602 | status = | 602 | status = acpi_ev_create_gpe_block(node, gpe_block_address->address, |
603 | acpi_ev_create_gpe_block(node, gpe_block_address, register_count, 0, | 603 | gpe_block_address->space_id, |
604 | interrupt_number, &gpe_block); | 604 | register_count, 0, interrupt_number, |
605 | &gpe_block); | ||
605 | if (ACPI_FAILURE(status)) { | 606 | if (ACPI_FAILURE(status)) { |
606 | goto unlock_and_exit; | 607 | goto unlock_and_exit; |
607 | } | 608 | } |
diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c index 8ba1464efd11..7d2949420db7 100644 --- a/drivers/acpi/acpica/exconfig.c +++ b/drivers/acpi/acpica/exconfig.c | |||
@@ -343,16 +343,14 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
343 | struct acpi_walk_state *walk_state) | 343 | struct acpi_walk_state *walk_state) |
344 | { | 344 | { |
345 | union acpi_operand_object *ddb_handle; | 345 | union acpi_operand_object *ddb_handle; |
346 | struct acpi_table_header *table_header; | ||
346 | struct acpi_table_header *table; | 347 | struct acpi_table_header *table; |
347 | struct acpi_table_desc table_desc; | ||
348 | u32 table_index; | 348 | u32 table_index; |
349 | acpi_status status; | 349 | acpi_status status; |
350 | u32 length; | 350 | u32 length; |
351 | 351 | ||
352 | ACPI_FUNCTION_TRACE(ex_load_op); | 352 | ACPI_FUNCTION_TRACE(ex_load_op); |
353 | 353 | ||
354 | ACPI_MEMSET(&table_desc, 0, sizeof(struct acpi_table_desc)); | ||
355 | |||
356 | /* Source Object can be either an op_region or a Buffer/Field */ | 354 | /* Source Object can be either an op_region or a Buffer/Field */ |
357 | 355 | ||
358 | switch (obj_desc->common.type) { | 356 | switch (obj_desc->common.type) { |
@@ -380,17 +378,17 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
380 | 378 | ||
381 | /* Get the table header first so we can get the table length */ | 379 | /* Get the table header first so we can get the table length */ |
382 | 380 | ||
383 | table = ACPI_ALLOCATE(sizeof(struct acpi_table_header)); | 381 | table_header = ACPI_ALLOCATE(sizeof(struct acpi_table_header)); |
384 | if (!table) { | 382 | if (!table_header) { |
385 | return_ACPI_STATUS(AE_NO_MEMORY); | 383 | return_ACPI_STATUS(AE_NO_MEMORY); |
386 | } | 384 | } |
387 | 385 | ||
388 | status = | 386 | status = |
389 | acpi_ex_region_read(obj_desc, | 387 | acpi_ex_region_read(obj_desc, |
390 | sizeof(struct acpi_table_header), | 388 | sizeof(struct acpi_table_header), |
391 | ACPI_CAST_PTR(u8, table)); | 389 | ACPI_CAST_PTR(u8, table_header)); |
392 | length = table->length; | 390 | length = table_header->length; |
393 | ACPI_FREE(table); | 391 | ACPI_FREE(table_header); |
394 | 392 | ||
395 | if (ACPI_FAILURE(status)) { | 393 | if (ACPI_FAILURE(status)) { |
396 | return_ACPI_STATUS(status); | 394 | return_ACPI_STATUS(status); |
@@ -420,22 +418,19 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
420 | 418 | ||
421 | /* Allocate a buffer for the table */ | 419 | /* Allocate a buffer for the table */ |
422 | 420 | ||
423 | table_desc.pointer = ACPI_ALLOCATE(length); | 421 | table = ACPI_ALLOCATE(length); |
424 | if (!table_desc.pointer) { | 422 | if (!table) { |
425 | return_ACPI_STATUS(AE_NO_MEMORY); | 423 | return_ACPI_STATUS(AE_NO_MEMORY); |
426 | } | 424 | } |
427 | 425 | ||
428 | /* Read the entire table */ | 426 | /* Read the entire table */ |
429 | 427 | ||
430 | status = acpi_ex_region_read(obj_desc, length, | 428 | status = acpi_ex_region_read(obj_desc, length, |
431 | ACPI_CAST_PTR(u8, | 429 | ACPI_CAST_PTR(u8, table)); |
432 | table_desc.pointer)); | ||
433 | if (ACPI_FAILURE(status)) { | 430 | if (ACPI_FAILURE(status)) { |
434 | ACPI_FREE(table_desc.pointer); | 431 | ACPI_FREE(table); |
435 | return_ACPI_STATUS(status); | 432 | return_ACPI_STATUS(status); |
436 | } | 433 | } |
437 | |||
438 | table_desc.address = obj_desc->region.address; | ||
439 | break; | 434 | break; |
440 | 435 | ||
441 | case ACPI_TYPE_BUFFER: /* Buffer or resolved region_field */ | 436 | case ACPI_TYPE_BUFFER: /* Buffer or resolved region_field */ |
@@ -452,10 +447,10 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
452 | 447 | ||
453 | /* Get the actual table length from the table header */ | 448 | /* Get the actual table length from the table header */ |
454 | 449 | ||
455 | table = | 450 | table_header = |
456 | ACPI_CAST_PTR(struct acpi_table_header, | 451 | ACPI_CAST_PTR(struct acpi_table_header, |
457 | obj_desc->buffer.pointer); | 452 | obj_desc->buffer.pointer); |
458 | length = table->length; | 453 | length = table_header->length; |
459 | 454 | ||
460 | /* Table cannot extend beyond the buffer */ | 455 | /* Table cannot extend beyond the buffer */ |
461 | 456 | ||
@@ -470,13 +465,12 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
470 | * Copy the table from the buffer because the buffer could be modified | 465 | * Copy the table from the buffer because the buffer could be modified |
471 | * or even deleted in the future | 466 | * or even deleted in the future |
472 | */ | 467 | */ |
473 | table_desc.pointer = ACPI_ALLOCATE(length); | 468 | table = ACPI_ALLOCATE(length); |
474 | if (!table_desc.pointer) { | 469 | if (!table) { |
475 | return_ACPI_STATUS(AE_NO_MEMORY); | 470 | return_ACPI_STATUS(AE_NO_MEMORY); |
476 | } | 471 | } |
477 | 472 | ||
478 | ACPI_MEMCPY(table_desc.pointer, table, length); | 473 | ACPI_MEMCPY(table, table_header, length); |
479 | table_desc.address = ACPI_TO_INTEGER(table_desc.pointer); | ||
480 | break; | 474 | break; |
481 | 475 | ||
482 | default: | 476 | default: |
@@ -484,27 +478,32 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
484 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); | 478 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); |
485 | } | 479 | } |
486 | 480 | ||
487 | /* Validate table checksum (will not get validated in tb_add_table) */ | 481 | /* Install the new table into the local data structures */ |
488 | |||
489 | status = acpi_tb_verify_checksum(table_desc.pointer, length); | ||
490 | if (ACPI_FAILURE(status)) { | ||
491 | ACPI_FREE(table_desc.pointer); | ||
492 | return_ACPI_STATUS(status); | ||
493 | } | ||
494 | |||
495 | /* Complete the table descriptor */ | ||
496 | 482 | ||
497 | table_desc.length = length; | 483 | ACPI_INFO((AE_INFO, "Dynamic OEM Table Load:")); |
498 | table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED; | 484 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
499 | 485 | ||
500 | /* Install the new table into the local data structures */ | 486 | status = acpi_tb_install_standard_table(ACPI_PTR_TO_PHYSADDR(table), |
487 | ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, | ||
488 | TRUE, TRUE, &table_index); | ||
501 | 489 | ||
502 | status = acpi_tb_add_table(&table_desc, &table_index); | 490 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
503 | if (ACPI_FAILURE(status)) { | 491 | if (ACPI_FAILURE(status)) { |
504 | 492 | ||
505 | /* Delete allocated table buffer */ | 493 | /* Delete allocated table buffer */ |
506 | 494 | ||
507 | acpi_tb_delete_table(&table_desc); | 495 | ACPI_FREE(table); |
496 | return_ACPI_STATUS(status); | ||
497 | } | ||
498 | |||
499 | /* | ||
500 | * Note: Now table is "INSTALLED", it must be validated before | ||
501 | * loading. | ||
502 | */ | ||
503 | status = | ||
504 | acpi_tb_validate_table(&acpi_gbl_root_table_list. | ||
505 | tables[table_index]); | ||
506 | if (ACPI_FAILURE(status)) { | ||
508 | return_ACPI_STATUS(status); | 507 | return_ACPI_STATUS(status); |
509 | } | 508 | } |
510 | 509 | ||
@@ -536,9 +535,6 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
536 | return_ACPI_STATUS(status); | 535 | return_ACPI_STATUS(status); |
537 | } | 536 | } |
538 | 537 | ||
539 | ACPI_INFO((AE_INFO, "Dynamic OEM Table Load:")); | ||
540 | acpi_tb_print_table_header(0, table_desc.pointer); | ||
541 | |||
542 | /* Remove the reference by added by acpi_ex_store above */ | 538 | /* Remove the reference by added by acpi_ex_store above */ |
543 | 539 | ||
544 | acpi_ut_remove_reference(ddb_handle); | 540 | acpi_ut_remove_reference(ddb_handle); |
@@ -546,8 +542,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
546 | /* Invoke table handler if present */ | 542 | /* Invoke table handler if present */ |
547 | 543 | ||
548 | if (acpi_gbl_table_handler) { | 544 | if (acpi_gbl_table_handler) { |
549 | (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, | 545 | (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table, |
550 | table_desc.pointer, | ||
551 | acpi_gbl_table_handler_context); | 546 | acpi_gbl_table_handler_context); |
552 | } | 547 | } |
553 | 548 | ||
@@ -576,6 +571,13 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) | |||
576 | ACPI_FUNCTION_TRACE(ex_unload_table); | 571 | ACPI_FUNCTION_TRACE(ex_unload_table); |
577 | 572 | ||
578 | /* | 573 | /* |
574 | * Temporarily emit a warning so that the ASL for the machine can be | ||
575 | * hopefully obtained. This is to say that the Unload() operator is | ||
576 | * extremely rare if not completely unused. | ||
577 | */ | ||
578 | ACPI_WARNING((AE_INFO, "Received request to unload an ACPI table")); | ||
579 | |||
580 | /* | ||
579 | * Validate the handle | 581 | * Validate the handle |
580 | * Although the handle is partially validated in acpi_ex_reconfiguration() | 582 | * Although the handle is partially validated in acpi_ex_reconfiguration() |
581 | * when it calls acpi_ex_resolve_operands(), the handle is more completely | 583 | * when it calls acpi_ex_resolve_operands(), the handle is more completely |
diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c index 973fdae00f94..925202acc3e4 100644 --- a/drivers/acpi/acpica/exdump.c +++ b/drivers/acpi/acpica/exdump.c | |||
@@ -134,9 +134,11 @@ static struct acpi_exdump_info acpi_ex_dump_method[9] = { | |||
134 | {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(method.aml_start), "Aml Start"} | 134 | {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(method.aml_start), "Aml Start"} |
135 | }; | 135 | }; |
136 | 136 | ||
137 | static struct acpi_exdump_info acpi_ex_dump_mutex[5] = { | 137 | static struct acpi_exdump_info acpi_ex_dump_mutex[6] = { |
138 | {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_mutex), NULL}, | 138 | {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_mutex), NULL}, |
139 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(mutex.sync_level), "Sync Level"}, | 139 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(mutex.sync_level), "Sync Level"}, |
140 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(mutex.original_sync_level), | ||
141 | "Original Sync Level"}, | ||
140 | {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.owner_thread), "Owner Thread"}, | 142 | {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.owner_thread), "Owner Thread"}, |
141 | {ACPI_EXD_UINT16, ACPI_EXD_OFFSET(mutex.acquisition_depth), | 143 | {ACPI_EXD_UINT16, ACPI_EXD_OFFSET(mutex.acquisition_depth), |
142 | "Acquire Depth"}, | 144 | "Acquire Depth"}, |
diff --git a/drivers/acpi/acpica/hwpci.c b/drivers/acpi/acpica/hwpci.c index e701d8c33dbf..6aade8e1d2a1 100644 --- a/drivers/acpi/acpica/hwpci.c +++ b/drivers/acpi/acpica/hwpci.c | |||
@@ -140,11 +140,12 @@ acpi_hw_derive_pci_id(struct acpi_pci_id *pci_id, | |||
140 | /* Walk the list, updating the PCI device/function/bus numbers */ | 140 | /* Walk the list, updating the PCI device/function/bus numbers */ |
141 | 141 | ||
142 | status = acpi_hw_process_pci_list(pci_id, list_head); | 142 | status = acpi_hw_process_pci_list(pci_id, list_head); |
143 | } | ||
144 | 143 | ||
145 | /* Always delete the list */ | 144 | /* Delete the list */ |
145 | |||
146 | acpi_hw_delete_pci_list(list_head); | ||
147 | } | ||
146 | 148 | ||
147 | acpi_hw_delete_pci_list(list_head); | ||
148 | return_ACPI_STATUS(status); | 149 | return_ACPI_STATUS(status); |
149 | } | 150 | } |
150 | 151 | ||
@@ -187,6 +188,10 @@ acpi_hw_build_pci_list(acpi_handle root_pci_device, | |||
187 | while (1) { | 188 | while (1) { |
188 | status = acpi_get_parent(current_device, &parent_device); | 189 | status = acpi_get_parent(current_device, &parent_device); |
189 | if (ACPI_FAILURE(status)) { | 190 | if (ACPI_FAILURE(status)) { |
191 | |||
192 | /* Must delete the list before exit */ | ||
193 | |||
194 | acpi_hw_delete_pci_list(*return_list_head); | ||
190 | return (status); | 195 | return (status); |
191 | } | 196 | } |
192 | 197 | ||
@@ -199,6 +204,10 @@ acpi_hw_build_pci_list(acpi_handle root_pci_device, | |||
199 | 204 | ||
200 | list_element = ACPI_ALLOCATE(sizeof(struct acpi_pci_device)); | 205 | list_element = ACPI_ALLOCATE(sizeof(struct acpi_pci_device)); |
201 | if (!list_element) { | 206 | if (!list_element) { |
207 | |||
208 | /* Must delete the list before exit */ | ||
209 | |||
210 | acpi_hw_delete_pci_list(*return_list_head); | ||
202 | return (AE_NO_MEMORY); | 211 | return (AE_NO_MEMORY); |
203 | } | 212 | } |
204 | 213 | ||
diff --git a/drivers/acpi/acpica/rscreate.c b/drivers/acpi/acpica/rscreate.c index 75d369050657..049d9c22a0f9 100644 --- a/drivers/acpi/acpica/rscreate.c +++ b/drivers/acpi/acpica/rscreate.c | |||
@@ -72,6 +72,8 @@ acpi_buffer_to_resource(u8 *aml_buffer, | |||
72 | void *resource; | 72 | void *resource; |
73 | void *current_resource_ptr; | 73 | void *current_resource_ptr; |
74 | 74 | ||
75 | ACPI_FUNCTION_TRACE(acpi_buffer_to_resource); | ||
76 | |||
75 | /* | 77 | /* |
76 | * Note: we allow AE_AML_NO_RESOURCE_END_TAG, since an end tag | 78 | * Note: we allow AE_AML_NO_RESOURCE_END_TAG, since an end tag |
77 | * is not required here. | 79 | * is not required here. |
@@ -85,7 +87,7 @@ acpi_buffer_to_resource(u8 *aml_buffer, | |||
85 | status = AE_OK; | 87 | status = AE_OK; |
86 | } | 88 | } |
87 | if (ACPI_FAILURE(status)) { | 89 | if (ACPI_FAILURE(status)) { |
88 | return (status); | 90 | return_ACPI_STATUS(status); |
89 | } | 91 | } |
90 | 92 | ||
91 | /* Allocate a buffer for the converted resource */ | 93 | /* Allocate a buffer for the converted resource */ |
@@ -93,7 +95,7 @@ acpi_buffer_to_resource(u8 *aml_buffer, | |||
93 | resource = ACPI_ALLOCATE_ZEROED(list_size_needed); | 95 | resource = ACPI_ALLOCATE_ZEROED(list_size_needed); |
94 | current_resource_ptr = resource; | 96 | current_resource_ptr = resource; |
95 | if (!resource) { | 97 | if (!resource) { |
96 | return (AE_NO_MEMORY); | 98 | return_ACPI_STATUS(AE_NO_MEMORY); |
97 | } | 99 | } |
98 | 100 | ||
99 | /* Perform the AML-to-Resource conversion */ | 101 | /* Perform the AML-to-Resource conversion */ |
@@ -110,9 +112,11 @@ acpi_buffer_to_resource(u8 *aml_buffer, | |||
110 | *resource_ptr = resource; | 112 | *resource_ptr = resource; |
111 | } | 113 | } |
112 | 114 | ||
113 | return (status); | 115 | return_ACPI_STATUS(status); |
114 | } | 116 | } |
115 | 117 | ||
118 | ACPI_EXPORT_SYMBOL(acpi_buffer_to_resource) | ||
119 | |||
116 | /******************************************************************************* | 120 | /******************************************************************************* |
117 | * | 121 | * |
118 | * FUNCTION: acpi_rs_create_resource_list | 122 | * FUNCTION: acpi_rs_create_resource_list |
@@ -130,10 +134,9 @@ acpi_buffer_to_resource(u8 *aml_buffer, | |||
130 | * of device resources. | 134 | * of device resources. |
131 | * | 135 | * |
132 | ******************************************************************************/ | 136 | ******************************************************************************/ |
133 | |||
134 | acpi_status | 137 | acpi_status |
135 | acpi_rs_create_resource_list(union acpi_operand_object *aml_buffer, | 138 | acpi_rs_create_resource_list(union acpi_operand_object *aml_buffer, |
136 | struct acpi_buffer * output_buffer) | 139 | struct acpi_buffer *output_buffer) |
137 | { | 140 | { |
138 | 141 | ||
139 | acpi_status status; | 142 | acpi_status status; |
diff --git a/drivers/acpi/acpica/tbdata.c b/drivers/acpi/acpica/tbdata.c new file mode 100644 index 000000000000..f499c10ceb4a --- /dev/null +++ b/drivers/acpi/acpica/tbdata.c | |||
@@ -0,0 +1,760 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: tbdata - Table manager data structure functions | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2014, 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 <acpi/acpi.h> | ||
45 | #include "accommon.h" | ||
46 | #include "acnamesp.h" | ||
47 | #include "actables.h" | ||
48 | |||
49 | #define _COMPONENT ACPI_TABLES | ||
50 | ACPI_MODULE_NAME("tbdata") | ||
51 | |||
52 | /******************************************************************************* | ||
53 | * | ||
54 | * FUNCTION: acpi_tb_init_table_descriptor | ||
55 | * | ||
56 | * PARAMETERS: table_desc - Table descriptor | ||
57 | * address - Physical address of the table | ||
58 | * flags - Allocation flags of the table | ||
59 | * table - Pointer to the table | ||
60 | * | ||
61 | * RETURN: None | ||
62 | * | ||
63 | * DESCRIPTION: Initialize a new table descriptor | ||
64 | * | ||
65 | ******************************************************************************/ | ||
66 | void | ||
67 | acpi_tb_init_table_descriptor(struct acpi_table_desc *table_desc, | ||
68 | acpi_physical_address address, | ||
69 | u8 flags, struct acpi_table_header *table) | ||
70 | { | ||
71 | |||
72 | /* | ||
73 | * Initialize the table descriptor. Set the pointer to NULL, since the | ||
74 | * table is not fully mapped at this time. | ||
75 | */ | ||
76 | ACPI_MEMSET(table_desc, 0, sizeof(struct acpi_table_desc)); | ||
77 | table_desc->address = address; | ||
78 | table_desc->length = table->length; | ||
79 | table_desc->flags = flags; | ||
80 | ACPI_MOVE_32_TO_32(table_desc->signature.ascii, table->signature); | ||
81 | } | ||
82 | |||
83 | /******************************************************************************* | ||
84 | * | ||
85 | * FUNCTION: acpi_tb_acquire_table | ||
86 | * | ||
87 | * PARAMETERS: table_desc - Table descriptor | ||
88 | * table_ptr - Where table is returned | ||
89 | * table_length - Where table length is returned | ||
90 | * table_flags - Where table allocation flags are returned | ||
91 | * | ||
92 | * RETURN: Status | ||
93 | * | ||
94 | * DESCRIPTION: Acquire an ACPI table. It can be used for tables not | ||
95 | * maintained in the acpi_gbl_root_table_list. | ||
96 | * | ||
97 | ******************************************************************************/ | ||
98 | |||
99 | acpi_status | ||
100 | acpi_tb_acquire_table(struct acpi_table_desc *table_desc, | ||
101 | struct acpi_table_header **table_ptr, | ||
102 | u32 *table_length, u8 *table_flags) | ||
103 | { | ||
104 | struct acpi_table_header *table = NULL; | ||
105 | |||
106 | switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) { | ||
107 | case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: | ||
108 | |||
109 | table = | ||
110 | acpi_os_map_memory(table_desc->address, table_desc->length); | ||
111 | break; | ||
112 | |||
113 | case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: | ||
114 | case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: | ||
115 | |||
116 | table = | ||
117 | ACPI_CAST_PTR(struct acpi_table_header, | ||
118 | table_desc->address); | ||
119 | break; | ||
120 | |||
121 | default: | ||
122 | |||
123 | break; | ||
124 | } | ||
125 | |||
126 | /* Table is not valid yet */ | ||
127 | |||
128 | if (!table) { | ||
129 | return (AE_NO_MEMORY); | ||
130 | } | ||
131 | |||
132 | /* Fill the return values */ | ||
133 | |||
134 | *table_ptr = table; | ||
135 | *table_length = table_desc->length; | ||
136 | *table_flags = table_desc->flags; | ||
137 | return (AE_OK); | ||
138 | } | ||
139 | |||
140 | /******************************************************************************* | ||
141 | * | ||
142 | * FUNCTION: acpi_tb_release_table | ||
143 | * | ||
144 | * PARAMETERS: table - Pointer for the table | ||
145 | * table_length - Length for the table | ||
146 | * table_flags - Allocation flags for the table | ||
147 | * | ||
148 | * RETURN: None | ||
149 | * | ||
150 | * DESCRIPTION: Release a table. The inverse of acpi_tb_acquire_table(). | ||
151 | * | ||
152 | ******************************************************************************/ | ||
153 | |||
154 | void | ||
155 | acpi_tb_release_table(struct acpi_table_header *table, | ||
156 | u32 table_length, u8 table_flags) | ||
157 | { | ||
158 | |||
159 | switch (table_flags & ACPI_TABLE_ORIGIN_MASK) { | ||
160 | case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: | ||
161 | |||
162 | acpi_os_unmap_memory(table, table_length); | ||
163 | break; | ||
164 | |||
165 | case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: | ||
166 | case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: | ||
167 | default: | ||
168 | |||
169 | break; | ||
170 | } | ||
171 | } | ||
172 | |||
173 | /******************************************************************************* | ||
174 | * | ||
175 | * FUNCTION: acpi_tb_acquire_temp_table | ||
176 | * | ||
177 | * PARAMETERS: table_desc - Table descriptor to be acquired | ||
178 | * address - Address of the table | ||
179 | * flags - Allocation flags of the table | ||
180 | * | ||
181 | * RETURN: Status | ||
182 | * | ||
183 | * DESCRIPTION: This function validates the table header to obtain the length | ||
184 | * of a table and fills the table descriptor to make its state as | ||
185 | * "INSTALLED". Such a table descriptor is only used for verified | ||
186 | * installation. | ||
187 | * | ||
188 | ******************************************************************************/ | ||
189 | |||
190 | acpi_status | ||
191 | acpi_tb_acquire_temp_table(struct acpi_table_desc *table_desc, | ||
192 | acpi_physical_address address, u8 flags) | ||
193 | { | ||
194 | struct acpi_table_header *table_header; | ||
195 | |||
196 | switch (flags & ACPI_TABLE_ORIGIN_MASK) { | ||
197 | case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: | ||
198 | |||
199 | /* Get the length of the full table from the header */ | ||
200 | |||
201 | table_header = | ||
202 | acpi_os_map_memory(address, | ||
203 | sizeof(struct acpi_table_header)); | ||
204 | if (!table_header) { | ||
205 | return (AE_NO_MEMORY); | ||
206 | } | ||
207 | |||
208 | acpi_tb_init_table_descriptor(table_desc, address, flags, | ||
209 | table_header); | ||
210 | acpi_os_unmap_memory(table_header, | ||
211 | sizeof(struct acpi_table_header)); | ||
212 | return (AE_OK); | ||
213 | |||
214 | case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: | ||
215 | case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: | ||
216 | |||
217 | table_header = ACPI_CAST_PTR(struct acpi_table_header, address); | ||
218 | if (!table_header) { | ||
219 | return (AE_NO_MEMORY); | ||
220 | } | ||
221 | |||
222 | acpi_tb_init_table_descriptor(table_desc, address, flags, | ||
223 | table_header); | ||
224 | return (AE_OK); | ||
225 | |||
226 | default: | ||
227 | |||
228 | break; | ||
229 | } | ||
230 | |||
231 | /* Table is not valid yet */ | ||
232 | |||
233 | return (AE_NO_MEMORY); | ||
234 | } | ||
235 | |||
236 | /******************************************************************************* | ||
237 | * | ||
238 | * FUNCTION: acpi_tb_release_temp_table | ||
239 | * | ||
240 | * PARAMETERS: table_desc - Table descriptor to be released | ||
241 | * | ||
242 | * RETURN: Status | ||
243 | * | ||
244 | * DESCRIPTION: The inverse of acpi_tb_acquire_temp_table(). | ||
245 | * | ||
246 | *****************************************************************************/ | ||
247 | |||
248 | void acpi_tb_release_temp_table(struct acpi_table_desc *table_desc) | ||
249 | { | ||
250 | |||
251 | /* | ||
252 | * Note that the .Address is maintained by the callers of | ||
253 | * acpi_tb_acquire_temp_table(), thus do not invoke acpi_tb_uninstall_table() | ||
254 | * where .Address will be freed. | ||
255 | */ | ||
256 | acpi_tb_invalidate_table(table_desc); | ||
257 | } | ||
258 | |||
259 | /****************************************************************************** | ||
260 | * | ||
261 | * FUNCTION: acpi_tb_validate_table | ||
262 | * | ||
263 | * PARAMETERS: table_desc - Table descriptor | ||
264 | * | ||
265 | * RETURN: Status | ||
266 | * | ||
267 | * DESCRIPTION: This function is called to validate the table, the returned | ||
268 | * table descriptor is in "VALIDATED" state. | ||
269 | * | ||
270 | *****************************************************************************/ | ||
271 | |||
272 | acpi_status acpi_tb_validate_table(struct acpi_table_desc *table_desc) | ||
273 | { | ||
274 | acpi_status status = AE_OK; | ||
275 | |||
276 | ACPI_FUNCTION_TRACE(tb_validate_table); | ||
277 | |||
278 | /* Validate the table if necessary */ | ||
279 | |||
280 | if (!table_desc->pointer) { | ||
281 | status = acpi_tb_acquire_table(table_desc, &table_desc->pointer, | ||
282 | &table_desc->length, | ||
283 | &table_desc->flags); | ||
284 | if (!table_desc->pointer) { | ||
285 | status = AE_NO_MEMORY; | ||
286 | } | ||
287 | } | ||
288 | |||
289 | return_ACPI_STATUS(status); | ||
290 | } | ||
291 | |||
292 | /******************************************************************************* | ||
293 | * | ||
294 | * FUNCTION: acpi_tb_invalidate_table | ||
295 | * | ||
296 | * PARAMETERS: table_desc - Table descriptor | ||
297 | * | ||
298 | * RETURN: None | ||
299 | * | ||
300 | * DESCRIPTION: Invalidate one internal ACPI table, this is the inverse of | ||
301 | * acpi_tb_validate_table(). | ||
302 | * | ||
303 | ******************************************************************************/ | ||
304 | |||
305 | void acpi_tb_invalidate_table(struct acpi_table_desc *table_desc) | ||
306 | { | ||
307 | |||
308 | ACPI_FUNCTION_TRACE(tb_invalidate_table); | ||
309 | |||
310 | /* Table must be validated */ | ||
311 | |||
312 | if (!table_desc->pointer) { | ||
313 | return_VOID; | ||
314 | } | ||
315 | |||
316 | acpi_tb_release_table(table_desc->pointer, table_desc->length, | ||
317 | table_desc->flags); | ||
318 | table_desc->pointer = NULL; | ||
319 | |||
320 | return_VOID; | ||
321 | } | ||
322 | |||
323 | /****************************************************************************** | ||
324 | * | ||
325 | * FUNCTION: acpi_tb_validate_temp_table | ||
326 | * | ||
327 | * PARAMETERS: table_desc - Table descriptor | ||
328 | * | ||
329 | * RETURN: Status | ||
330 | * | ||
331 | * DESCRIPTION: This function is called to validate the table, the returned | ||
332 | * table descriptor is in "VALIDATED" state. | ||
333 | * | ||
334 | *****************************************************************************/ | ||
335 | |||
336 | acpi_status acpi_tb_validate_temp_table(struct acpi_table_desc *table_desc) | ||
337 | { | ||
338 | |||
339 | if (!table_desc->pointer && !acpi_gbl_verify_table_checksum) { | ||
340 | /* | ||
341 | * Only validates the header of the table. | ||
342 | * Note that Length contains the size of the mapping after invoking | ||
343 | * this work around, this value is required by | ||
344 | * acpi_tb_release_temp_table(). | ||
345 | * We can do this because in acpi_init_table_descriptor(), the Length | ||
346 | * field of the installed descriptor is filled with the actual | ||
347 | * table length obtaining from the table header. | ||
348 | */ | ||
349 | table_desc->length = sizeof(struct acpi_table_header); | ||
350 | } | ||
351 | |||
352 | return (acpi_tb_validate_table(table_desc)); | ||
353 | } | ||
354 | |||
355 | /****************************************************************************** | ||
356 | * | ||
357 | * FUNCTION: acpi_tb_verify_temp_table | ||
358 | * | ||
359 | * PARAMETERS: table_desc - Table descriptor | ||
360 | * signature - Table signature to verify | ||
361 | * | ||
362 | * RETURN: Status | ||
363 | * | ||
364 | * DESCRIPTION: This function is called to validate and verify the table, the | ||
365 | * returned table descriptor is in "VALIDATED" state. | ||
366 | * | ||
367 | *****************************************************************************/ | ||
368 | |||
369 | acpi_status | ||
370 | acpi_tb_verify_temp_table(struct acpi_table_desc * table_desc, char *signature) | ||
371 | { | ||
372 | acpi_status status = AE_OK; | ||
373 | |||
374 | ACPI_FUNCTION_TRACE(tb_verify_temp_table); | ||
375 | |||
376 | /* Validate the table */ | ||
377 | |||
378 | status = acpi_tb_validate_temp_table(table_desc); | ||
379 | if (ACPI_FAILURE(status)) { | ||
380 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
381 | } | ||
382 | |||
383 | /* If a particular signature is expected (DSDT/FACS), it must match */ | ||
384 | |||
385 | if (signature && !ACPI_COMPARE_NAME(&table_desc->signature, signature)) { | ||
386 | ACPI_BIOS_ERROR((AE_INFO, | ||
387 | "Invalid signature 0x%X for ACPI table, expected [%s]", | ||
388 | table_desc->signature.integer, signature)); | ||
389 | status = AE_BAD_SIGNATURE; | ||
390 | goto invalidate_and_exit; | ||
391 | } | ||
392 | |||
393 | /* Verify the checksum */ | ||
394 | |||
395 | if (acpi_gbl_verify_table_checksum) { | ||
396 | status = | ||
397 | acpi_tb_verify_checksum(table_desc->pointer, | ||
398 | table_desc->length); | ||
399 | if (ACPI_FAILURE(status)) { | ||
400 | ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, | ||
401 | "%4.4s " ACPI_PRINTF_UINT | ||
402 | " Attempted table install failed", | ||
403 | acpi_ut_valid_acpi_name(table_desc-> | ||
404 | signature. | ||
405 | ascii) ? | ||
406 | table_desc->signature.ascii : "????", | ||
407 | ACPI_FORMAT_TO_UINT(table_desc-> | ||
408 | address))); | ||
409 | goto invalidate_and_exit; | ||
410 | } | ||
411 | } | ||
412 | |||
413 | return_ACPI_STATUS(AE_OK); | ||
414 | |||
415 | invalidate_and_exit: | ||
416 | acpi_tb_invalidate_table(table_desc); | ||
417 | return_ACPI_STATUS(status); | ||
418 | } | ||
419 | |||
420 | /******************************************************************************* | ||
421 | * | ||
422 | * FUNCTION: acpi_tb_resize_root_table_list | ||
423 | * | ||
424 | * PARAMETERS: None | ||
425 | * | ||
426 | * RETURN: Status | ||
427 | * | ||
428 | * DESCRIPTION: Expand the size of global table array | ||
429 | * | ||
430 | ******************************************************************************/ | ||
431 | |||
432 | acpi_status acpi_tb_resize_root_table_list(void) | ||
433 | { | ||
434 | struct acpi_table_desc *tables; | ||
435 | u32 table_count; | ||
436 | |||
437 | ACPI_FUNCTION_TRACE(tb_resize_root_table_list); | ||
438 | |||
439 | /* allow_resize flag is a parameter to acpi_initialize_tables */ | ||
440 | |||
441 | if (!(acpi_gbl_root_table_list.flags & ACPI_ROOT_ALLOW_RESIZE)) { | ||
442 | ACPI_ERROR((AE_INFO, | ||
443 | "Resize of Root Table Array is not allowed")); | ||
444 | return_ACPI_STATUS(AE_SUPPORT); | ||
445 | } | ||
446 | |||
447 | /* Increase the Table Array size */ | ||
448 | |||
449 | if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { | ||
450 | table_count = acpi_gbl_root_table_list.max_table_count; | ||
451 | } else { | ||
452 | table_count = acpi_gbl_root_table_list.current_table_count; | ||
453 | } | ||
454 | |||
455 | tables = ACPI_ALLOCATE_ZEROED(((acpi_size) table_count + | ||
456 | ACPI_ROOT_TABLE_SIZE_INCREMENT) * | ||
457 | sizeof(struct acpi_table_desc)); | ||
458 | if (!tables) { | ||
459 | ACPI_ERROR((AE_INFO, | ||
460 | "Could not allocate new root table array")); | ||
461 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
462 | } | ||
463 | |||
464 | /* Copy and free the previous table array */ | ||
465 | |||
466 | if (acpi_gbl_root_table_list.tables) { | ||
467 | ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, | ||
468 | (acpi_size) table_count * | ||
469 | sizeof(struct acpi_table_desc)); | ||
470 | |||
471 | if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { | ||
472 | ACPI_FREE(acpi_gbl_root_table_list.tables); | ||
473 | } | ||
474 | } | ||
475 | |||
476 | acpi_gbl_root_table_list.tables = tables; | ||
477 | acpi_gbl_root_table_list.max_table_count = | ||
478 | table_count + ACPI_ROOT_TABLE_SIZE_INCREMENT; | ||
479 | acpi_gbl_root_table_list.flags |= ACPI_ROOT_ORIGIN_ALLOCATED; | ||
480 | |||
481 | return_ACPI_STATUS(AE_OK); | ||
482 | } | ||
483 | |||
484 | /******************************************************************************* | ||
485 | * | ||
486 | * FUNCTION: acpi_tb_get_next_root_index | ||
487 | * | ||
488 | * PARAMETERS: table_index - Where table index is returned | ||
489 | * | ||
490 | * RETURN: Status and table index. | ||
491 | * | ||
492 | * DESCRIPTION: Allocate a new ACPI table entry to the global table list | ||
493 | * | ||
494 | ******************************************************************************/ | ||
495 | |||
496 | acpi_status acpi_tb_get_next_root_index(u32 *table_index) | ||
497 | { | ||
498 | acpi_status status; | ||
499 | |||
500 | /* Ensure that there is room for the table in the Root Table List */ | ||
501 | |||
502 | if (acpi_gbl_root_table_list.current_table_count >= | ||
503 | acpi_gbl_root_table_list.max_table_count) { | ||
504 | status = acpi_tb_resize_root_table_list(); | ||
505 | if (ACPI_FAILURE(status)) { | ||
506 | return (status); | ||
507 | } | ||
508 | } | ||
509 | |||
510 | *table_index = acpi_gbl_root_table_list.current_table_count; | ||
511 | acpi_gbl_root_table_list.current_table_count++; | ||
512 | return (AE_OK); | ||
513 | } | ||
514 | |||
515 | /******************************************************************************* | ||
516 | * | ||
517 | * FUNCTION: acpi_tb_terminate | ||
518 | * | ||
519 | * PARAMETERS: None | ||
520 | * | ||
521 | * RETURN: None | ||
522 | * | ||
523 | * DESCRIPTION: Delete all internal ACPI tables | ||
524 | * | ||
525 | ******************************************************************************/ | ||
526 | |||
527 | void acpi_tb_terminate(void) | ||
528 | { | ||
529 | u32 i; | ||
530 | |||
531 | ACPI_FUNCTION_TRACE(tb_terminate); | ||
532 | |||
533 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
534 | |||
535 | /* Delete the individual tables */ | ||
536 | |||
537 | for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) { | ||
538 | acpi_tb_uninstall_table(&acpi_gbl_root_table_list.tables[i]); | ||
539 | } | ||
540 | |||
541 | /* | ||
542 | * Delete the root table array if allocated locally. Array cannot be | ||
543 | * mapped, so we don't need to check for that flag. | ||
544 | */ | ||
545 | if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { | ||
546 | ACPI_FREE(acpi_gbl_root_table_list.tables); | ||
547 | } | ||
548 | |||
549 | acpi_gbl_root_table_list.tables = NULL; | ||
550 | acpi_gbl_root_table_list.flags = 0; | ||
551 | acpi_gbl_root_table_list.current_table_count = 0; | ||
552 | |||
553 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n")); | ||
554 | |||
555 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
556 | return_VOID; | ||
557 | } | ||
558 | |||
559 | /******************************************************************************* | ||
560 | * | ||
561 | * FUNCTION: acpi_tb_delete_namespace_by_owner | ||
562 | * | ||
563 | * PARAMETERS: table_index - Table index | ||
564 | * | ||
565 | * RETURN: Status | ||
566 | * | ||
567 | * DESCRIPTION: Delete all namespace objects created when this table was loaded. | ||
568 | * | ||
569 | ******************************************************************************/ | ||
570 | |||
571 | acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index) | ||
572 | { | ||
573 | acpi_owner_id owner_id; | ||
574 | acpi_status status; | ||
575 | |||
576 | ACPI_FUNCTION_TRACE(tb_delete_namespace_by_owner); | ||
577 | |||
578 | status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
579 | if (ACPI_FAILURE(status)) { | ||
580 | return_ACPI_STATUS(status); | ||
581 | } | ||
582 | |||
583 | if (table_index >= acpi_gbl_root_table_list.current_table_count) { | ||
584 | |||
585 | /* The table index does not exist */ | ||
586 | |||
587 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
588 | return_ACPI_STATUS(AE_NOT_EXIST); | ||
589 | } | ||
590 | |||
591 | /* Get the owner ID for this table, used to delete namespace nodes */ | ||
592 | |||
593 | owner_id = acpi_gbl_root_table_list.tables[table_index].owner_id; | ||
594 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
595 | |||
596 | /* | ||
597 | * Need to acquire the namespace writer lock to prevent interference | ||
598 | * with any concurrent namespace walks. The interpreter must be | ||
599 | * released during the deletion since the acquisition of the deletion | ||
600 | * lock may block, and also since the execution of a namespace walk | ||
601 | * must be allowed to use the interpreter. | ||
602 | */ | ||
603 | (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); | ||
604 | status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock); | ||
605 | |||
606 | acpi_ns_delete_namespace_by_owner(owner_id); | ||
607 | if (ACPI_FAILURE(status)) { | ||
608 | return_ACPI_STATUS(status); | ||
609 | } | ||
610 | |||
611 | acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock); | ||
612 | |||
613 | status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); | ||
614 | return_ACPI_STATUS(status); | ||
615 | } | ||
616 | |||
617 | /******************************************************************************* | ||
618 | * | ||
619 | * FUNCTION: acpi_tb_allocate_owner_id | ||
620 | * | ||
621 | * PARAMETERS: table_index - Table index | ||
622 | * | ||
623 | * RETURN: Status | ||
624 | * | ||
625 | * DESCRIPTION: Allocates owner_id in table_desc | ||
626 | * | ||
627 | ******************************************************************************/ | ||
628 | |||
629 | acpi_status acpi_tb_allocate_owner_id(u32 table_index) | ||
630 | { | ||
631 | acpi_status status = AE_BAD_PARAMETER; | ||
632 | |||
633 | ACPI_FUNCTION_TRACE(tb_allocate_owner_id); | ||
634 | |||
635 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
636 | if (table_index < acpi_gbl_root_table_list.current_table_count) { | ||
637 | status = | ||
638 | acpi_ut_allocate_owner_id(& | ||
639 | (acpi_gbl_root_table_list. | ||
640 | tables[table_index].owner_id)); | ||
641 | } | ||
642 | |||
643 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
644 | return_ACPI_STATUS(status); | ||
645 | } | ||
646 | |||
647 | /******************************************************************************* | ||
648 | * | ||
649 | * FUNCTION: acpi_tb_release_owner_id | ||
650 | * | ||
651 | * PARAMETERS: table_index - Table index | ||
652 | * | ||
653 | * RETURN: Status | ||
654 | * | ||
655 | * DESCRIPTION: Releases owner_id in table_desc | ||
656 | * | ||
657 | ******************************************************************************/ | ||
658 | |||
659 | acpi_status acpi_tb_release_owner_id(u32 table_index) | ||
660 | { | ||
661 | acpi_status status = AE_BAD_PARAMETER; | ||
662 | |||
663 | ACPI_FUNCTION_TRACE(tb_release_owner_id); | ||
664 | |||
665 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
666 | if (table_index < acpi_gbl_root_table_list.current_table_count) { | ||
667 | acpi_ut_release_owner_id(& | ||
668 | (acpi_gbl_root_table_list. | ||
669 | tables[table_index].owner_id)); | ||
670 | status = AE_OK; | ||
671 | } | ||
672 | |||
673 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
674 | return_ACPI_STATUS(status); | ||
675 | } | ||
676 | |||
677 | /******************************************************************************* | ||
678 | * | ||
679 | * FUNCTION: acpi_tb_get_owner_id | ||
680 | * | ||
681 | * PARAMETERS: table_index - Table index | ||
682 | * owner_id - Where the table owner_id is returned | ||
683 | * | ||
684 | * RETURN: Status | ||
685 | * | ||
686 | * DESCRIPTION: returns owner_id for the ACPI table | ||
687 | * | ||
688 | ******************************************************************************/ | ||
689 | |||
690 | acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id * owner_id) | ||
691 | { | ||
692 | acpi_status status = AE_BAD_PARAMETER; | ||
693 | |||
694 | ACPI_FUNCTION_TRACE(tb_get_owner_id); | ||
695 | |||
696 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
697 | if (table_index < acpi_gbl_root_table_list.current_table_count) { | ||
698 | *owner_id = | ||
699 | acpi_gbl_root_table_list.tables[table_index].owner_id; | ||
700 | status = AE_OK; | ||
701 | } | ||
702 | |||
703 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
704 | return_ACPI_STATUS(status); | ||
705 | } | ||
706 | |||
707 | /******************************************************************************* | ||
708 | * | ||
709 | * FUNCTION: acpi_tb_is_table_loaded | ||
710 | * | ||
711 | * PARAMETERS: table_index - Index into the root table | ||
712 | * | ||
713 | * RETURN: Table Loaded Flag | ||
714 | * | ||
715 | ******************************************************************************/ | ||
716 | |||
717 | u8 acpi_tb_is_table_loaded(u32 table_index) | ||
718 | { | ||
719 | u8 is_loaded = FALSE; | ||
720 | |||
721 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
722 | if (table_index < acpi_gbl_root_table_list.current_table_count) { | ||
723 | is_loaded = (u8) | ||
724 | (acpi_gbl_root_table_list.tables[table_index].flags & | ||
725 | ACPI_TABLE_IS_LOADED); | ||
726 | } | ||
727 | |||
728 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
729 | return (is_loaded); | ||
730 | } | ||
731 | |||
732 | /******************************************************************************* | ||
733 | * | ||
734 | * FUNCTION: acpi_tb_set_table_loaded_flag | ||
735 | * | ||
736 | * PARAMETERS: table_index - Table index | ||
737 | * is_loaded - TRUE if table is loaded, FALSE otherwise | ||
738 | * | ||
739 | * RETURN: None | ||
740 | * | ||
741 | * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE. | ||
742 | * | ||
743 | ******************************************************************************/ | ||
744 | |||
745 | void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded) | ||
746 | { | ||
747 | |||
748 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
749 | if (table_index < acpi_gbl_root_table_list.current_table_count) { | ||
750 | if (is_loaded) { | ||
751 | acpi_gbl_root_table_list.tables[table_index].flags |= | ||
752 | ACPI_TABLE_IS_LOADED; | ||
753 | } else { | ||
754 | acpi_gbl_root_table_list.tables[table_index].flags &= | ||
755 | ~ACPI_TABLE_IS_LOADED; | ||
756 | } | ||
757 | } | ||
758 | |||
759 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
760 | } | ||
diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c index ec14588254d4..41519a958083 100644 --- a/drivers/acpi/acpica/tbfadt.c +++ b/drivers/acpi/acpica/tbfadt.c | |||
@@ -52,7 +52,8 @@ ACPI_MODULE_NAME("tbfadt") | |||
52 | static void | 52 | static void |
53 | acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, | 53 | acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, |
54 | u8 space_id, | 54 | u8 space_id, |
55 | u8 byte_width, u64 address, char *register_name); | 55 | u8 byte_width, |
56 | u64 address, char *register_name, u8 flags); | ||
56 | 57 | ||
57 | static void acpi_tb_convert_fadt(void); | 58 | static void acpi_tb_convert_fadt(void); |
58 | 59 | ||
@@ -69,13 +70,14 @@ typedef struct acpi_fadt_info { | |||
69 | u16 address32; | 70 | u16 address32; |
70 | u16 length; | 71 | u16 length; |
71 | u8 default_length; | 72 | u8 default_length; |
72 | u8 type; | 73 | u8 flags; |
73 | 74 | ||
74 | } acpi_fadt_info; | 75 | } acpi_fadt_info; |
75 | 76 | ||
76 | #define ACPI_FADT_OPTIONAL 0 | 77 | #define ACPI_FADT_OPTIONAL 0 |
77 | #define ACPI_FADT_REQUIRED 1 | 78 | #define ACPI_FADT_REQUIRED 1 |
78 | #define ACPI_FADT_SEPARATE_LENGTH 2 | 79 | #define ACPI_FADT_SEPARATE_LENGTH 2 |
80 | #define ACPI_FADT_GPE_REGISTER 4 | ||
79 | 81 | ||
80 | static struct acpi_fadt_info fadt_info_table[] = { | 82 | static struct acpi_fadt_info fadt_info_table[] = { |
81 | {"Pm1aEventBlock", | 83 | {"Pm1aEventBlock", |
@@ -125,14 +127,14 @@ static struct acpi_fadt_info fadt_info_table[] = { | |||
125 | ACPI_FADT_OFFSET(gpe0_block), | 127 | ACPI_FADT_OFFSET(gpe0_block), |
126 | ACPI_FADT_OFFSET(gpe0_block_length), | 128 | ACPI_FADT_OFFSET(gpe0_block_length), |
127 | 0, | 129 | 0, |
128 | ACPI_FADT_SEPARATE_LENGTH}, | 130 | ACPI_FADT_SEPARATE_LENGTH | ACPI_FADT_GPE_REGISTER}, |
129 | 131 | ||
130 | {"Gpe1Block", | 132 | {"Gpe1Block", |
131 | ACPI_FADT_OFFSET(xgpe1_block), | 133 | ACPI_FADT_OFFSET(xgpe1_block), |
132 | ACPI_FADT_OFFSET(gpe1_block), | 134 | ACPI_FADT_OFFSET(gpe1_block), |
133 | ACPI_FADT_OFFSET(gpe1_block_length), | 135 | ACPI_FADT_OFFSET(gpe1_block_length), |
134 | 0, | 136 | 0, |
135 | ACPI_FADT_SEPARATE_LENGTH} | 137 | ACPI_FADT_SEPARATE_LENGTH | ACPI_FADT_GPE_REGISTER} |
136 | }; | 138 | }; |
137 | 139 | ||
138 | #define ACPI_FADT_INFO_ENTRIES \ | 140 | #define ACPI_FADT_INFO_ENTRIES \ |
@@ -189,19 +191,29 @@ static struct acpi_fadt_pm_info fadt_pm_info_table[] = { | |||
189 | static void | 191 | static void |
190 | acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, | 192 | acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, |
191 | u8 space_id, | 193 | u8 space_id, |
192 | u8 byte_width, u64 address, char *register_name) | 194 | u8 byte_width, |
195 | u64 address, char *register_name, u8 flags) | ||
193 | { | 196 | { |
194 | u8 bit_width; | 197 | u8 bit_width; |
195 | 198 | ||
196 | /* Bit width field in the GAS is only one byte long, 255 max */ | 199 | /* |
197 | 200 | * Bit width field in the GAS is only one byte long, 255 max. | |
201 | * Check for bit_width overflow in GAS. | ||
202 | */ | ||
198 | bit_width = (u8)(byte_width * 8); | 203 | bit_width = (u8)(byte_width * 8); |
199 | 204 | if (byte_width > 31) { /* (31*8)=248, (32*8)=256 */ | |
200 | if (byte_width > 31) { /* (31*8)=248 */ | 205 | /* |
201 | ACPI_ERROR((AE_INFO, | 206 | * No error for GPE blocks, because we do not use the bit_width |
202 | "%s - 32-bit FADT register is too long (%u bytes, %u bits) " | 207 | * for GPEs, the legacy length (byte_width) is used instead to |
203 | "to convert to GAS struct - 255 bits max, truncating", | 208 | * allow for a large number of GPEs. |
204 | register_name, byte_width, (byte_width * 8))); | 209 | */ |
210 | if (!(flags & ACPI_FADT_GPE_REGISTER)) { | ||
211 | ACPI_ERROR((AE_INFO, | ||
212 | "%s - 32-bit FADT register is too long (%u bytes, %u bits) " | ||
213 | "to convert to GAS struct - 255 bits max, truncating", | ||
214 | register_name, byte_width, | ||
215 | (byte_width * 8))); | ||
216 | } | ||
205 | 217 | ||
206 | bit_width = 255; | 218 | bit_width = 255; |
207 | } | 219 | } |
@@ -332,15 +344,15 @@ void acpi_tb_parse_fadt(u32 table_index) | |||
332 | 344 | ||
333 | /* Obtain the DSDT and FACS tables via their addresses within the FADT */ | 345 | /* Obtain the DSDT and FACS tables via their addresses within the FADT */ |
334 | 346 | ||
335 | acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt, | 347 | acpi_tb_install_fixed_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt, |
336 | ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT); | 348 | ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT); |
337 | 349 | ||
338 | /* If Hardware Reduced flag is set, there is no FACS */ | 350 | /* If Hardware Reduced flag is set, there is no FACS */ |
339 | 351 | ||
340 | if (!acpi_gbl_reduced_hardware) { | 352 | if (!acpi_gbl_reduced_hardware) { |
341 | acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT. | 353 | acpi_tb_install_fixed_table((acpi_physical_address) |
342 | Xfacs, ACPI_SIG_FACS, | 354 | acpi_gbl_FADT.Xfacs, ACPI_SIG_FACS, |
343 | ACPI_TABLE_INDEX_FACS); | 355 | ACPI_TABLE_INDEX_FACS); |
344 | } | 356 | } |
345 | } | 357 | } |
346 | 358 | ||
@@ -450,6 +462,7 @@ static void acpi_tb_convert_fadt(void) | |||
450 | struct acpi_generic_address *address64; | 462 | struct acpi_generic_address *address64; |
451 | u32 address32; | 463 | u32 address32; |
452 | u8 length; | 464 | u8 length; |
465 | u8 flags; | ||
453 | u32 i; | 466 | u32 i; |
454 | 467 | ||
455 | /* | 468 | /* |
@@ -515,6 +528,7 @@ static void acpi_tb_convert_fadt(void) | |||
515 | fadt_info_table[i].length); | 528 | fadt_info_table[i].length); |
516 | 529 | ||
517 | name = fadt_info_table[i].name; | 530 | name = fadt_info_table[i].name; |
531 | flags = fadt_info_table[i].flags; | ||
518 | 532 | ||
519 | /* | 533 | /* |
520 | * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X" | 534 | * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X" |
@@ -554,7 +568,7 @@ static void acpi_tb_convert_fadt(void) | |||
554 | [i]. | 568 | [i]. |
555 | length), | 569 | length), |
556 | (u64)address32, | 570 | (u64)address32, |
557 | name); | 571 | name, flags); |
558 | } else if (address64->address != (u64)address32) { | 572 | } else if (address64->address != (u64)address32) { |
559 | 573 | ||
560 | /* Address mismatch */ | 574 | /* Address mismatch */ |
@@ -582,7 +596,8 @@ static void acpi_tb_convert_fadt(void) | |||
582 | length), | 596 | length), |
583 | (u64) | 597 | (u64) |
584 | address32, | 598 | address32, |
585 | name); | 599 | name, |
600 | flags); | ||
586 | } | 601 | } |
587 | } | 602 | } |
588 | } | 603 | } |
@@ -603,7 +618,7 @@ static void acpi_tb_convert_fadt(void) | |||
603 | address64->bit_width)); | 618 | address64->bit_width)); |
604 | } | 619 | } |
605 | 620 | ||
606 | if (fadt_info_table[i].type & ACPI_FADT_REQUIRED) { | 621 | if (fadt_info_table[i].flags & ACPI_FADT_REQUIRED) { |
607 | /* | 622 | /* |
608 | * Field is required (Pm1a_event, Pm1a_control). | 623 | * Field is required (Pm1a_event, Pm1a_control). |
609 | * Both the address and length must be non-zero. | 624 | * Both the address and length must be non-zero. |
@@ -617,7 +632,7 @@ static void acpi_tb_convert_fadt(void) | |||
617 | address), | 632 | address), |
618 | length)); | 633 | length)); |
619 | } | 634 | } |
620 | } else if (fadt_info_table[i].type & ACPI_FADT_SEPARATE_LENGTH) { | 635 | } else if (fadt_info_table[i].flags & ACPI_FADT_SEPARATE_LENGTH) { |
621 | /* | 636 | /* |
622 | * Field is optional (Pm2_control, GPE0, GPE1) AND has its own | 637 | * Field is optional (Pm2_control, GPE0, GPE1) AND has its own |
623 | * length field. If present, both the address and length must | 638 | * length field. If present, both the address and length must |
@@ -726,7 +741,7 @@ static void acpi_tb_setup_fadt_registers(void) | |||
726 | (fadt_pm_info_table[i]. | 741 | (fadt_pm_info_table[i]. |
727 | register_num * | 742 | register_num * |
728 | pm1_register_byte_width), | 743 | pm1_register_byte_width), |
729 | "PmRegisters"); | 744 | "PmRegisters", 0); |
730 | } | 745 | } |
731 | } | 746 | } |
732 | } | 747 | } |
diff --git a/drivers/acpi/acpica/tbfind.c b/drivers/acpi/acpica/tbfind.c index c12003947bd5..cb947700206c 100644 --- a/drivers/acpi/acpica/tbfind.c +++ b/drivers/acpi/acpica/tbfind.c | |||
@@ -99,8 +99,8 @@ acpi_tb_find_table(char *signature, | |||
99 | /* Table is not currently mapped, map it */ | 99 | /* Table is not currently mapped, map it */ |
100 | 100 | ||
101 | status = | 101 | status = |
102 | acpi_tb_verify_table(&acpi_gbl_root_table_list. | 102 | acpi_tb_validate_table(&acpi_gbl_root_table_list. |
103 | tables[i]); | 103 | tables[i]); |
104 | if (ACPI_FAILURE(status)) { | 104 | if (ACPI_FAILURE(status)) { |
105 | return_ACPI_STATUS(status); | 105 | return_ACPI_STATUS(status); |
106 | } | 106 | } |
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c index e3040947e9a0..755b90c40ddf 100644 --- a/drivers/acpi/acpica/tbinstal.c +++ b/drivers/acpi/acpica/tbinstal.c | |||
@@ -43,688 +43,483 @@ | |||
43 | 43 | ||
44 | #include <acpi/acpi.h> | 44 | #include <acpi/acpi.h> |
45 | #include "accommon.h" | 45 | #include "accommon.h" |
46 | #include "acnamesp.h" | ||
47 | #include "actables.h" | 46 | #include "actables.h" |
48 | 47 | ||
49 | #define _COMPONENT ACPI_TABLES | 48 | #define _COMPONENT ACPI_TABLES |
50 | ACPI_MODULE_NAME("tbinstal") | 49 | ACPI_MODULE_NAME("tbinstal") |
51 | 50 | ||
52 | /****************************************************************************** | 51 | /* Local prototypes */ |
52 | static u8 | ||
53 | acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index); | ||
54 | |||
55 | /******************************************************************************* | ||
53 | * | 56 | * |
54 | * FUNCTION: acpi_tb_verify_table | 57 | * FUNCTION: acpi_tb_compare_tables |
55 | * | 58 | * |
56 | * PARAMETERS: table_desc - table | 59 | * PARAMETERS: table_desc - Table 1 descriptor to be compared |
60 | * table_index - Index of table 2 to be compared | ||
57 | * | 61 | * |
58 | * RETURN: Status | 62 | * RETURN: TRUE if both tables are identical. |
59 | * | 63 | * |
60 | * DESCRIPTION: this function is called to verify and map table | 64 | * DESCRIPTION: This function compares a table with another table that has |
65 | * already been installed in the root table list. | ||
61 | * | 66 | * |
62 | *****************************************************************************/ | 67 | ******************************************************************************/ |
63 | acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc) | 68 | |
69 | static u8 | ||
70 | acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index) | ||
64 | { | 71 | { |
65 | acpi_status status = AE_OK; | 72 | acpi_status status = AE_OK; |
73 | u8 is_identical; | ||
74 | struct acpi_table_header *table; | ||
75 | u32 table_length; | ||
76 | u8 table_flags; | ||
66 | 77 | ||
67 | ACPI_FUNCTION_TRACE(tb_verify_table); | 78 | status = |
68 | 79 | acpi_tb_acquire_table(&acpi_gbl_root_table_list.tables[table_index], | |
69 | /* Map the table if necessary */ | 80 | &table, &table_length, &table_flags); |
70 | 81 | if (ACPI_FAILURE(status)) { | |
71 | if (!table_desc->pointer) { | 82 | return (FALSE); |
72 | if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) == | ||
73 | ACPI_TABLE_ORIGIN_MAPPED) { | ||
74 | table_desc->pointer = | ||
75 | acpi_os_map_memory(table_desc->address, | ||
76 | table_desc->length); | ||
77 | } | ||
78 | if (!table_desc->pointer) { | ||
79 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
80 | } | ||
81 | } | 83 | } |
82 | 84 | ||
83 | /* Always calculate checksum, ignore bad checksum if requested */ | 85 | /* |
86 | * Check for a table match on the entire table length, | ||
87 | * not just the header. | ||
88 | */ | ||
89 | is_identical = (u8)((table_desc->length != table_length || | ||
90 | ACPI_MEMCMP(table_desc->pointer, table, | ||
91 | table_length)) ? FALSE : TRUE); | ||
84 | 92 | ||
85 | status = | 93 | /* Release the acquired table */ |
86 | acpi_tb_verify_checksum(table_desc->pointer, table_desc->length); | ||
87 | 94 | ||
88 | return_ACPI_STATUS(status); | 95 | acpi_tb_release_table(table, table_length, table_flags); |
96 | return (is_identical); | ||
89 | } | 97 | } |
90 | 98 | ||
91 | /******************************************************************************* | 99 | /******************************************************************************* |
92 | * | 100 | * |
93 | * FUNCTION: acpi_tb_add_table | 101 | * FUNCTION: acpi_tb_install_table_with_override |
94 | * | 102 | * |
95 | * PARAMETERS: table_desc - Table descriptor | 103 | * PARAMETERS: table_index - Index into root table array |
96 | * table_index - Where the table index is returned | 104 | * new_table_desc - New table descriptor to install |
105 | * override - Whether override should be performed | ||
97 | * | 106 | * |
98 | * RETURN: Status | 107 | * RETURN: None |
99 | * | 108 | * |
100 | * DESCRIPTION: This function is called to add an ACPI table. It is used to | 109 | * DESCRIPTION: Install an ACPI table into the global data structure. The |
101 | * dynamically load tables via the Load and load_table AML | 110 | * table override mechanism is called to allow the host |
102 | * operators. | 111 | * OS to replace any table before it is installed in the root |
112 | * table array. | ||
103 | * | 113 | * |
104 | ******************************************************************************/ | 114 | ******************************************************************************/ |
105 | 115 | ||
106 | acpi_status | 116 | void |
107 | acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) | 117 | acpi_tb_install_table_with_override(u32 table_index, |
118 | struct acpi_table_desc *new_table_desc, | ||
119 | u8 override) | ||
108 | { | 120 | { |
109 | u32 i; | ||
110 | acpi_status status = AE_OK; | ||
111 | 121 | ||
112 | ACPI_FUNCTION_TRACE(tb_add_table); | 122 | if (table_index >= acpi_gbl_root_table_list.current_table_count) { |
113 | 123 | return; | |
114 | if (!table_desc->pointer) { | ||
115 | status = acpi_tb_verify_table(table_desc); | ||
116 | if (ACPI_FAILURE(status) || !table_desc->pointer) { | ||
117 | return_ACPI_STATUS(status); | ||
118 | } | ||
119 | } | 124 | } |
120 | 125 | ||
121 | /* | 126 | /* |
122 | * Validate the incoming table signature. | 127 | * ACPI Table Override: |
123 | * | 128 | * |
124 | * 1) Originally, we checked the table signature for "SSDT" or "PSDT". | 129 | * Before we install the table, let the host OS override it with a new |
125 | * 2) We added support for OEMx tables, signature "OEM". | 130 | * one if desired. Any table within the RSDT/XSDT can be replaced, |
126 | * 3) Valid tables were encountered with a null signature, so we just | 131 | * including the DSDT which is pointed to by the FADT. |
127 | * gave up on validating the signature, (05/2008). | ||
128 | * 4) We encountered non-AML tables such as the MADT, which caused | ||
129 | * interpreter errors and kernel faults. So now, we once again allow | ||
130 | * only "SSDT", "OEMx", and now, also a null signature. (05/2011). | ||
131 | */ | 132 | */ |
132 | if ((table_desc->pointer->signature[0] != 0x00) && | 133 | if (override) { |
133 | (!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_SSDT)) | 134 | acpi_tb_override_table(new_table_desc); |
134 | && (ACPI_STRNCMP(table_desc->pointer->signature, "OEM", 3))) { | ||
135 | ACPI_BIOS_ERROR((AE_INFO, | ||
136 | "Table has invalid signature [%4.4s] (0x%8.8X), " | ||
137 | "must be SSDT or OEMx", | ||
138 | acpi_ut_valid_acpi_name(table_desc->pointer-> | ||
139 | signature) ? | ||
140 | table_desc->pointer->signature : "????", | ||
141 | *(u32 *)table_desc->pointer->signature)); | ||
142 | |||
143 | return_ACPI_STATUS(AE_BAD_SIGNATURE); | ||
144 | } | 135 | } |
145 | 136 | ||
146 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | 137 | acpi_tb_init_table_descriptor(&acpi_gbl_root_table_list. |
138 | tables[table_index], | ||
139 | new_table_desc->address, | ||
140 | new_table_desc->flags, | ||
141 | new_table_desc->pointer); | ||
147 | 142 | ||
148 | /* Check if table is already registered */ | 143 | acpi_tb_print_table_header(new_table_desc->address, |
144 | new_table_desc->pointer); | ||
149 | 145 | ||
150 | for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) { | 146 | /* Set the global integer width (based upon revision of the DSDT) */ |
151 | if (!acpi_gbl_root_table_list.tables[i].pointer) { | ||
152 | status = | ||
153 | acpi_tb_verify_table(&acpi_gbl_root_table_list. | ||
154 | tables[i]); | ||
155 | if (ACPI_FAILURE(status) | ||
156 | || !acpi_gbl_root_table_list.tables[i].pointer) { | ||
157 | continue; | ||
158 | } | ||
159 | } | ||
160 | 147 | ||
161 | /* | 148 | if (table_index == ACPI_TABLE_INDEX_DSDT) { |
162 | * Check for a table match on the entire table length, | 149 | acpi_ut_set_integer_width(new_table_desc->pointer->revision); |
163 | * not just the header. | ||
164 | */ | ||
165 | if (table_desc->length != | ||
166 | acpi_gbl_root_table_list.tables[i].length) { | ||
167 | continue; | ||
168 | } | ||
169 | |||
170 | if (ACPI_MEMCMP(table_desc->pointer, | ||
171 | acpi_gbl_root_table_list.tables[i].pointer, | ||
172 | acpi_gbl_root_table_list.tables[i].length)) { | ||
173 | continue; | ||
174 | } | ||
175 | |||
176 | /* | ||
177 | * Note: the current mechanism does not unregister a table if it is | ||
178 | * dynamically unloaded. The related namespace entries are deleted, | ||
179 | * but the table remains in the root table list. | ||
180 | * | ||
181 | * The assumption here is that the number of different tables that | ||
182 | * will be loaded is actually small, and there is minimal overhead | ||
183 | * in just keeping the table in case it is needed again. | ||
184 | * | ||
185 | * If this assumption changes in the future (perhaps on large | ||
186 | * machines with many table load/unload operations), tables will | ||
187 | * need to be unregistered when they are unloaded, and slots in the | ||
188 | * root table list should be reused when empty. | ||
189 | */ | ||
190 | |||
191 | /* | ||
192 | * Table is already registered. | ||
193 | * We can delete the table that was passed as a parameter. | ||
194 | */ | ||
195 | acpi_tb_delete_table(table_desc); | ||
196 | *table_index = i; | ||
197 | |||
198 | if (acpi_gbl_root_table_list.tables[i]. | ||
199 | flags & ACPI_TABLE_IS_LOADED) { | ||
200 | |||
201 | /* Table is still loaded, this is an error */ | ||
202 | |||
203 | status = AE_ALREADY_EXISTS; | ||
204 | goto release; | ||
205 | } else { | ||
206 | /* Table was unloaded, allow it to be reloaded */ | ||
207 | |||
208 | table_desc->pointer = | ||
209 | acpi_gbl_root_table_list.tables[i].pointer; | ||
210 | table_desc->address = | ||
211 | acpi_gbl_root_table_list.tables[i].address; | ||
212 | status = AE_OK; | ||
213 | goto print_header; | ||
214 | } | ||
215 | } | 150 | } |
216 | |||
217 | /* | ||
218 | * ACPI Table Override: | ||
219 | * Allow the host to override dynamically loaded tables. | ||
220 | * NOTE: the table is fully mapped at this point, and the mapping will | ||
221 | * be deleted by tb_table_override if the table is actually overridden. | ||
222 | */ | ||
223 | (void)acpi_tb_table_override(table_desc->pointer, table_desc); | ||
224 | |||
225 | /* Add the table to the global root table list */ | ||
226 | |||
227 | status = acpi_tb_store_table(table_desc->address, table_desc->pointer, | ||
228 | table_desc->length, table_desc->flags, | ||
229 | table_index); | ||
230 | if (ACPI_FAILURE(status)) { | ||
231 | goto release; | ||
232 | } | ||
233 | |||
234 | print_header: | ||
235 | acpi_tb_print_table_header(table_desc->address, table_desc->pointer); | ||
236 | |||
237 | release: | ||
238 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
239 | return_ACPI_STATUS(status); | ||
240 | } | 151 | } |
241 | 152 | ||
242 | /******************************************************************************* | 153 | /******************************************************************************* |
243 | * | 154 | * |
244 | * FUNCTION: acpi_tb_table_override | 155 | * FUNCTION: acpi_tb_install_fixed_table |
245 | * | 156 | * |
246 | * PARAMETERS: table_header - Header for the original table | 157 | * PARAMETERS: address - Physical address of DSDT or FACS |
247 | * table_desc - Table descriptor initialized for the | 158 | * signature - Table signature, NULL if no need to |
248 | * original table. May or may not be mapped. | 159 | * match |
160 | * table_index - Index into root table array | ||
249 | * | 161 | * |
250 | * RETURN: Pointer to the entire new table. NULL if table not overridden. | 162 | * RETURN: Status |
251 | * If overridden, installs the new table within the input table | ||
252 | * descriptor. | ||
253 | * | 163 | * |
254 | * DESCRIPTION: Attempt table override by calling the OSL override functions. | 164 | * DESCRIPTION: Install a fixed ACPI table (DSDT/FACS) into the global data |
255 | * Note: If the table is overridden, then the entire new table | 165 | * structure. |
256 | * is mapped and returned by this function. | ||
257 | * | 166 | * |
258 | ******************************************************************************/ | 167 | ******************************************************************************/ |
259 | 168 | ||
260 | struct acpi_table_header *acpi_tb_table_override(struct acpi_table_header | 169 | acpi_status |
261 | *table_header, | 170 | acpi_tb_install_fixed_table(acpi_physical_address address, |
262 | struct acpi_table_desc | 171 | char *signature, u32 table_index) |
263 | *table_desc) | ||
264 | { | 172 | { |
173 | struct acpi_table_desc new_table_desc; | ||
265 | acpi_status status; | 174 | acpi_status status; |
266 | struct acpi_table_header *new_table = NULL; | ||
267 | acpi_physical_address new_address = 0; | ||
268 | u32 new_table_length = 0; | ||
269 | u8 new_flags; | ||
270 | char *override_type; | ||
271 | 175 | ||
272 | /* (1) Attempt logical override (returns a logical address) */ | 176 | ACPI_FUNCTION_TRACE(tb_install_fixed_table); |
273 | 177 | ||
274 | status = acpi_os_table_override(table_header, &new_table); | 178 | if (!address) { |
275 | if (ACPI_SUCCESS(status) && new_table) { | 179 | ACPI_ERROR((AE_INFO, |
276 | new_address = ACPI_PTR_TO_PHYSADDR(new_table); | 180 | "Null physical address for ACPI table [%s]", |
277 | new_table_length = new_table->length; | 181 | signature)); |
278 | new_flags = ACPI_TABLE_ORIGIN_OVERRIDE; | 182 | return (AE_NO_MEMORY); |
279 | override_type = "Logical"; | ||
280 | goto finish_override; | ||
281 | } | 183 | } |
282 | 184 | ||
283 | /* (2) Attempt physical override (returns a physical address) */ | 185 | /* Fill a table descriptor for validation */ |
284 | 186 | ||
285 | status = acpi_os_physical_table_override(table_header, | 187 | status = acpi_tb_acquire_temp_table(&new_table_desc, address, |
286 | &new_address, | 188 | ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL); |
287 | &new_table_length); | 189 | if (ACPI_FAILURE(status)) { |
288 | if (ACPI_SUCCESS(status) && new_address && new_table_length) { | 190 | ACPI_ERROR((AE_INFO, "Could not acquire table length at %p", |
289 | 191 | ACPI_CAST_PTR(void, address))); | |
290 | /* Map the entire new table */ | 192 | return_ACPI_STATUS(status); |
291 | |||
292 | new_table = acpi_os_map_memory(new_address, new_table_length); | ||
293 | if (!new_table) { | ||
294 | ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, | ||
295 | "%4.4s " ACPI_PRINTF_UINT | ||
296 | " Attempted physical table override failed", | ||
297 | table_header->signature, | ||
298 | ACPI_FORMAT_TO_UINT(table_desc-> | ||
299 | address))); | ||
300 | return (NULL); | ||
301 | } | ||
302 | |||
303 | override_type = "Physical"; | ||
304 | new_flags = ACPI_TABLE_ORIGIN_MAPPED; | ||
305 | goto finish_override; | ||
306 | } | 193 | } |
307 | 194 | ||
308 | return (NULL); /* There was no override */ | 195 | /* Validate and verify a table before installation */ |
309 | |||
310 | finish_override: | ||
311 | |||
312 | ACPI_INFO((AE_INFO, "%4.4s " ACPI_PRINTF_UINT | ||
313 | " %s table override, new table: " ACPI_PRINTF_UINT, | ||
314 | table_header->signature, | ||
315 | ACPI_FORMAT_TO_UINT(table_desc->address), | ||
316 | override_type, ACPI_FORMAT_TO_UINT(new_table))); | ||
317 | 196 | ||
318 | /* We can now unmap/delete the original table (if fully mapped) */ | 197 | status = acpi_tb_verify_temp_table(&new_table_desc, signature); |
198 | if (ACPI_FAILURE(status)) { | ||
199 | goto release_and_exit; | ||
200 | } | ||
319 | 201 | ||
320 | acpi_tb_delete_table(table_desc); | 202 | acpi_tb_install_table_with_override(table_index, &new_table_desc, TRUE); |
321 | 203 | ||
322 | /* Setup descriptor for the new table */ | 204 | release_and_exit: |
323 | 205 | ||
324 | table_desc->address = new_address; | 206 | /* Release the temporary table descriptor */ |
325 | table_desc->pointer = new_table; | ||
326 | table_desc->length = new_table_length; | ||
327 | table_desc->flags = new_flags; | ||
328 | 207 | ||
329 | return (new_table); | 208 | acpi_tb_release_temp_table(&new_table_desc); |
209 | return_ACPI_STATUS(status); | ||
330 | } | 210 | } |
331 | 211 | ||
332 | /******************************************************************************* | 212 | /******************************************************************************* |
333 | * | 213 | * |
334 | * FUNCTION: acpi_tb_resize_root_table_list | 214 | * FUNCTION: acpi_tb_install_standard_table |
335 | * | 215 | * |
336 | * PARAMETERS: None | 216 | * PARAMETERS: address - Address of the table (might be a virtual |
217 | * address depending on the table_flags) | ||
218 | * flags - Flags for the table | ||
219 | * reload - Whether reload should be performed | ||
220 | * override - Whether override should be performed | ||
221 | * table_index - Where the table index is returned | ||
337 | * | 222 | * |
338 | * RETURN: Status | 223 | * RETURN: Status |
339 | * | 224 | * |
340 | * DESCRIPTION: Expand the size of global table array | 225 | * DESCRIPTION: This function is called to install an ACPI table that is |
226 | * neither DSDT nor FACS (a "standard" table.) | ||
227 | * When this function is called by "Load" or "LoadTable" opcodes, | ||
228 | * or by acpi_load_table() API, the "Reload" parameter is set. | ||
229 | * After sucessfully returning from this function, table is | ||
230 | * "INSTALLED" but not "VALIDATED". | ||
341 | * | 231 | * |
342 | ******************************************************************************/ | 232 | ******************************************************************************/ |
343 | 233 | ||
344 | acpi_status acpi_tb_resize_root_table_list(void) | 234 | acpi_status |
235 | acpi_tb_install_standard_table(acpi_physical_address address, | ||
236 | u8 flags, | ||
237 | u8 reload, u8 override, u32 *table_index) | ||
345 | { | 238 | { |
346 | struct acpi_table_desc *tables; | 239 | u32 i; |
347 | u32 table_count; | 240 | acpi_status status = AE_OK; |
348 | 241 | struct acpi_table_desc new_table_desc; | |
349 | ACPI_FUNCTION_TRACE(tb_resize_root_table_list); | ||
350 | |||
351 | /* allow_resize flag is a parameter to acpi_initialize_tables */ | ||
352 | 242 | ||
353 | if (!(acpi_gbl_root_table_list.flags & ACPI_ROOT_ALLOW_RESIZE)) { | 243 | ACPI_FUNCTION_TRACE(tb_install_standard_table); |
354 | ACPI_ERROR((AE_INFO, | ||
355 | "Resize of Root Table Array is not allowed")); | ||
356 | return_ACPI_STATUS(AE_SUPPORT); | ||
357 | } | ||
358 | 244 | ||
359 | /* Increase the Table Array size */ | 245 | /* Acquire a temporary table descriptor for validation */ |
360 | 246 | ||
361 | if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { | 247 | status = acpi_tb_acquire_temp_table(&new_table_desc, address, flags); |
362 | table_count = acpi_gbl_root_table_list.max_table_count; | 248 | if (ACPI_FAILURE(status)) { |
363 | } else { | 249 | ACPI_ERROR((AE_INFO, "Could not acquire table length at %p", |
364 | table_count = acpi_gbl_root_table_list.current_table_count; | 250 | ACPI_CAST_PTR(void, address))); |
251 | return_ACPI_STATUS(status); | ||
365 | } | 252 | } |
366 | 253 | ||
367 | tables = ACPI_ALLOCATE_ZEROED(((acpi_size) table_count + | 254 | /* |
368 | ACPI_ROOT_TABLE_SIZE_INCREMENT) * | 255 | * Optionally do not load any SSDTs from the RSDT/XSDT. This can |
369 | sizeof(struct acpi_table_desc)); | 256 | * be useful for debugging ACPI problems on some machines. |
370 | if (!tables) { | 257 | */ |
371 | ACPI_ERROR((AE_INFO, | 258 | if (!reload && |
372 | "Could not allocate new root table array")); | 259 | acpi_gbl_disable_ssdt_table_install && |
373 | return_ACPI_STATUS(AE_NO_MEMORY); | 260 | ACPI_COMPARE_NAME(&new_table_desc.signature, ACPI_SIG_SSDT)) { |
261 | ACPI_INFO((AE_INFO, "Ignoring installation of %4.4s at %p", | ||
262 | new_table_desc.signature.ascii, ACPI_CAST_PTR(void, | ||
263 | address))); | ||
264 | goto release_and_exit; | ||
374 | } | 265 | } |
375 | 266 | ||
376 | /* Copy and free the previous table array */ | 267 | /* Validate and verify a table before installation */ |
377 | |||
378 | if (acpi_gbl_root_table_list.tables) { | ||
379 | ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, | ||
380 | (acpi_size) table_count * | ||
381 | sizeof(struct acpi_table_desc)); | ||
382 | 268 | ||
383 | if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { | 269 | status = acpi_tb_verify_temp_table(&new_table_desc, NULL); |
384 | ACPI_FREE(acpi_gbl_root_table_list.tables); | 270 | if (ACPI_FAILURE(status)) { |
385 | } | 271 | goto release_and_exit; |
386 | } | 272 | } |
387 | 273 | ||
388 | acpi_gbl_root_table_list.tables = tables; | 274 | if (reload) { |
389 | acpi_gbl_root_table_list.max_table_count = | 275 | /* |
390 | table_count + ACPI_ROOT_TABLE_SIZE_INCREMENT; | 276 | * Validate the incoming table signature. |
391 | acpi_gbl_root_table_list.flags |= ACPI_ROOT_ORIGIN_ALLOCATED; | 277 | * |
392 | 278 | * 1) Originally, we checked the table signature for "SSDT" or "PSDT". | |
393 | return_ACPI_STATUS(AE_OK); | 279 | * 2) We added support for OEMx tables, signature "OEM". |
394 | } | 280 | * 3) Valid tables were encountered with a null signature, so we just |
395 | 281 | * gave up on validating the signature, (05/2008). | |
396 | /******************************************************************************* | 282 | * 4) We encountered non-AML tables such as the MADT, which caused |
397 | * | 283 | * interpreter errors and kernel faults. So now, we once again allow |
398 | * FUNCTION: acpi_tb_store_table | 284 | * only "SSDT", "OEMx", and now, also a null signature. (05/2011). |
399 | * | 285 | */ |
400 | * PARAMETERS: address - Table address | 286 | if ((new_table_desc.signature.ascii[0] != 0x00) && |
401 | * table - Table header | 287 | (!ACPI_COMPARE_NAME |
402 | * length - Table length | 288 | (&new_table_desc.signature, ACPI_SIG_SSDT)) |
403 | * flags - flags | 289 | && (ACPI_STRNCMP(new_table_desc.signature.ascii, "OEM", 3))) |
404 | * | 290 | { |
405 | * RETURN: Status and table index. | 291 | ACPI_BIOS_ERROR((AE_INFO, |
406 | * | 292 | "Table has invalid signature [%4.4s] (0x%8.8X), " |
407 | * DESCRIPTION: Add an ACPI table to the global table list | 293 | "must be SSDT or OEMx", |
408 | * | 294 | acpi_ut_valid_acpi_name(new_table_desc. |
409 | ******************************************************************************/ | 295 | signature. |
296 | ascii) ? | ||
297 | new_table_desc.signature. | ||
298 | ascii : "????", | ||
299 | new_table_desc.signature.integer)); | ||
300 | |||
301 | status = AE_BAD_SIGNATURE; | ||
302 | goto release_and_exit; | ||
303 | } | ||
410 | 304 | ||
411 | acpi_status | 305 | /* Check if table is already registered */ |
412 | acpi_tb_store_table(acpi_physical_address address, | ||
413 | struct acpi_table_header *table, | ||
414 | u32 length, u8 flags, u32 *table_index) | ||
415 | { | ||
416 | acpi_status status; | ||
417 | struct acpi_table_desc *new_table; | ||
418 | 306 | ||
419 | /* Ensure that there is room for the table in the Root Table List */ | 307 | for (i = 0; i < acpi_gbl_root_table_list.current_table_count; |
308 | ++i) { | ||
309 | /* | ||
310 | * Check for a table match on the entire table length, | ||
311 | * not just the header. | ||
312 | */ | ||
313 | if (!acpi_tb_compare_tables(&new_table_desc, i)) { | ||
314 | continue; | ||
315 | } | ||
420 | 316 | ||
421 | if (acpi_gbl_root_table_list.current_table_count >= | 317 | /* |
422 | acpi_gbl_root_table_list.max_table_count) { | 318 | * Note: the current mechanism does not unregister a table if it is |
423 | status = acpi_tb_resize_root_table_list(); | 319 | * dynamically unloaded. The related namespace entries are deleted, |
424 | if (ACPI_FAILURE(status)) { | 320 | * but the table remains in the root table list. |
425 | return (status); | 321 | * |
322 | * The assumption here is that the number of different tables that | ||
323 | * will be loaded is actually small, and there is minimal overhead | ||
324 | * in just keeping the table in case it is needed again. | ||
325 | * | ||
326 | * If this assumption changes in the future (perhaps on large | ||
327 | * machines with many table load/unload operations), tables will | ||
328 | * need to be unregistered when they are unloaded, and slots in the | ||
329 | * root table list should be reused when empty. | ||
330 | */ | ||
331 | if (acpi_gbl_root_table_list.tables[i]. | ||
332 | flags & ACPI_TABLE_IS_LOADED) { | ||
333 | |||
334 | /* Table is still loaded, this is an error */ | ||
335 | |||
336 | status = AE_ALREADY_EXISTS; | ||
337 | goto release_and_exit; | ||
338 | } else { | ||
339 | /* | ||
340 | * Table was unloaded, allow it to be reloaded. | ||
341 | * As we are going to return AE_OK to the caller, we should | ||
342 | * take the responsibility of freeing the input descriptor. | ||
343 | * Refill the input descriptor to ensure | ||
344 | * acpi_tb_install_table_with_override() can be called again to | ||
345 | * indicate the re-installation. | ||
346 | */ | ||
347 | acpi_tb_uninstall_table(&new_table_desc); | ||
348 | *table_index = i; | ||
349 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
350 | return_ACPI_STATUS(AE_OK); | ||
351 | } | ||
426 | } | 352 | } |
427 | } | 353 | } |
428 | 354 | ||
429 | new_table = | 355 | /* Add the table to the global root table list */ |
430 | &acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list. | ||
431 | current_table_count]; | ||
432 | |||
433 | /* Initialize added table */ | ||
434 | |||
435 | new_table->address = address; | ||
436 | new_table->pointer = table; | ||
437 | new_table->length = length; | ||
438 | new_table->owner_id = 0; | ||
439 | new_table->flags = flags; | ||
440 | |||
441 | ACPI_MOVE_32_TO_32(&new_table->signature, table->signature); | ||
442 | |||
443 | *table_index = acpi_gbl_root_table_list.current_table_count; | ||
444 | acpi_gbl_root_table_list.current_table_count++; | ||
445 | return (AE_OK); | ||
446 | } | ||
447 | |||
448 | /******************************************************************************* | ||
449 | * | ||
450 | * FUNCTION: acpi_tb_delete_table | ||
451 | * | ||
452 | * PARAMETERS: table_index - Table index | ||
453 | * | ||
454 | * RETURN: None | ||
455 | * | ||
456 | * DESCRIPTION: Delete one internal ACPI table | ||
457 | * | ||
458 | ******************************************************************************/ | ||
459 | 356 | ||
460 | void acpi_tb_delete_table(struct acpi_table_desc *table_desc) | 357 | status = acpi_tb_get_next_root_index(&i); |
461 | { | 358 | if (ACPI_FAILURE(status)) { |
462 | /* Table must be mapped or allocated */ | 359 | goto release_and_exit; |
463 | if (!table_desc->pointer) { | ||
464 | return; | ||
465 | } | 360 | } |
466 | switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) { | ||
467 | case ACPI_TABLE_ORIGIN_MAPPED: | ||
468 | |||
469 | acpi_os_unmap_memory(table_desc->pointer, table_desc->length); | ||
470 | break; | ||
471 | |||
472 | case ACPI_TABLE_ORIGIN_ALLOCATED: | ||
473 | 361 | ||
474 | ACPI_FREE(table_desc->pointer); | 362 | *table_index = i; |
475 | break; | 363 | acpi_tb_install_table_with_override(i, &new_table_desc, override); |
476 | 364 | ||
477 | /* Not mapped or allocated, there is nothing we can do */ | 365 | release_and_exit: |
478 | 366 | ||
479 | default: | 367 | /* Release the temporary table descriptor */ |
480 | 368 | ||
481 | return; | 369 | acpi_tb_release_temp_table(&new_table_desc); |
482 | } | 370 | return_ACPI_STATUS(status); |
483 | |||
484 | table_desc->pointer = NULL; | ||
485 | } | 371 | } |
486 | 372 | ||
487 | /******************************************************************************* | 373 | /******************************************************************************* |
488 | * | 374 | * |
489 | * FUNCTION: acpi_tb_terminate | 375 | * FUNCTION: acpi_tb_override_table |
490 | * | 376 | * |
491 | * PARAMETERS: None | 377 | * PARAMETERS: old_table_desc - Validated table descriptor to be |
378 | * overridden | ||
492 | * | 379 | * |
493 | * RETURN: None | 380 | * RETURN: None |
494 | * | 381 | * |
495 | * DESCRIPTION: Delete all internal ACPI tables | 382 | * DESCRIPTION: Attempt table override by calling the OSL override functions. |
383 | * Note: If the table is overridden, then the entire new table | ||
384 | * is acquired and returned by this function. | ||
385 | * Before/after invocation, the table descriptor is in a state | ||
386 | * that is "VALIDATED". | ||
496 | * | 387 | * |
497 | ******************************************************************************/ | 388 | ******************************************************************************/ |
498 | 389 | ||
499 | void acpi_tb_terminate(void) | 390 | void acpi_tb_override_table(struct acpi_table_desc *old_table_desc) |
500 | { | 391 | { |
501 | u32 i; | 392 | acpi_status status; |
502 | 393 | char *override_type; | |
503 | ACPI_FUNCTION_TRACE(tb_terminate); | 394 | struct acpi_table_desc new_table_desc; |
504 | 395 | struct acpi_table_header *table; | |
505 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | 396 | acpi_physical_address address; |
506 | 397 | u32 length; | |
507 | /* Delete the individual tables */ | ||
508 | 398 | ||
509 | for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) { | 399 | /* (1) Attempt logical override (returns a logical address) */ |
510 | acpi_tb_delete_table(&acpi_gbl_root_table_list.tables[i]); | ||
511 | } | ||
512 | 400 | ||
513 | /* | 401 | status = acpi_os_table_override(old_table_desc->pointer, &table); |
514 | * Delete the root table array if allocated locally. Array cannot be | 402 | if (ACPI_SUCCESS(status) && table) { |
515 | * mapped, so we don't need to check for that flag. | 403 | acpi_tb_acquire_temp_table(&new_table_desc, |
516 | */ | 404 | ACPI_PTR_TO_PHYSADDR(table), |
517 | if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { | 405 | ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL); |
518 | ACPI_FREE(acpi_gbl_root_table_list.tables); | 406 | override_type = "Logical"; |
407 | goto finish_override; | ||
519 | } | 408 | } |
520 | 409 | ||
521 | acpi_gbl_root_table_list.tables = NULL; | 410 | /* (2) Attempt physical override (returns a physical address) */ |
522 | acpi_gbl_root_table_list.flags = 0; | ||
523 | acpi_gbl_root_table_list.current_table_count = 0; | ||
524 | 411 | ||
525 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n")); | 412 | status = acpi_os_physical_table_override(old_table_desc->pointer, |
526 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 413 | &address, &length); |
414 | if (ACPI_SUCCESS(status) && address && length) { | ||
415 | acpi_tb_acquire_temp_table(&new_table_desc, address, | ||
416 | ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL); | ||
417 | override_type = "Physical"; | ||
418 | goto finish_override; | ||
419 | } | ||
527 | 420 | ||
528 | return_VOID; | 421 | return; /* There was no override */ |
529 | } | ||
530 | 422 | ||
531 | /******************************************************************************* | 423 | finish_override: |
532 | * | ||
533 | * FUNCTION: acpi_tb_delete_namespace_by_owner | ||
534 | * | ||
535 | * PARAMETERS: table_index - Table index | ||
536 | * | ||
537 | * RETURN: Status | ||
538 | * | ||
539 | * DESCRIPTION: Delete all namespace objects created when this table was loaded. | ||
540 | * | ||
541 | ******************************************************************************/ | ||
542 | |||
543 | acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index) | ||
544 | { | ||
545 | acpi_owner_id owner_id; | ||
546 | acpi_status status; | ||
547 | 424 | ||
548 | ACPI_FUNCTION_TRACE(tb_delete_namespace_by_owner); | 425 | /* Validate and verify a table before overriding */ |
549 | 426 | ||
550 | status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | 427 | status = acpi_tb_verify_temp_table(&new_table_desc, NULL); |
551 | if (ACPI_FAILURE(status)) { | 428 | if (ACPI_FAILURE(status)) { |
552 | return_ACPI_STATUS(status); | 429 | return; |
553 | } | 430 | } |
554 | 431 | ||
555 | if (table_index >= acpi_gbl_root_table_list.current_table_count) { | 432 | ACPI_INFO((AE_INFO, "%4.4s " ACPI_PRINTF_UINT |
556 | 433 | " %s table override, new table: " ACPI_PRINTF_UINT, | |
557 | /* The table index does not exist */ | 434 | old_table_desc->signature.ascii, |
558 | 435 | ACPI_FORMAT_TO_UINT(old_table_desc->address), | |
559 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 436 | override_type, ACPI_FORMAT_TO_UINT(new_table_desc.address))); |
560 | return_ACPI_STATUS(AE_NOT_EXIST); | ||
561 | } | ||
562 | 437 | ||
563 | /* Get the owner ID for this table, used to delete namespace nodes */ | 438 | /* We can now uninstall the original table */ |
564 | 439 | ||
565 | owner_id = acpi_gbl_root_table_list.tables[table_index].owner_id; | 440 | acpi_tb_uninstall_table(old_table_desc); |
566 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
567 | 441 | ||
568 | /* | 442 | /* |
569 | * Need to acquire the namespace writer lock to prevent interference | 443 | * Replace the original table descriptor and keep its state as |
570 | * with any concurrent namespace walks. The interpreter must be | 444 | * "VALIDATED". |
571 | * released during the deletion since the acquisition of the deletion | ||
572 | * lock may block, and also since the execution of a namespace walk | ||
573 | * must be allowed to use the interpreter. | ||
574 | */ | 445 | */ |
575 | (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); | 446 | acpi_tb_init_table_descriptor(old_table_desc, new_table_desc.address, |
576 | status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock); | 447 | new_table_desc.flags, |
448 | new_table_desc.pointer); | ||
449 | acpi_tb_validate_temp_table(old_table_desc); | ||
577 | 450 | ||
578 | acpi_ns_delete_namespace_by_owner(owner_id); | 451 | /* Release the temporary table descriptor */ |
579 | if (ACPI_FAILURE(status)) { | ||
580 | return_ACPI_STATUS(status); | ||
581 | } | ||
582 | 452 | ||
583 | acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock); | 453 | acpi_tb_release_temp_table(&new_table_desc); |
584 | |||
585 | status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); | ||
586 | return_ACPI_STATUS(status); | ||
587 | } | 454 | } |
588 | 455 | ||
589 | /******************************************************************************* | 456 | /******************************************************************************* |
590 | * | 457 | * |
591 | * FUNCTION: acpi_tb_allocate_owner_id | 458 | * FUNCTION: acpi_tb_store_table |
592 | * | 459 | * |
593 | * PARAMETERS: table_index - Table index | 460 | * PARAMETERS: address - Table address |
461 | * table - Table header | ||
462 | * length - Table length | ||
463 | * flags - Install flags | ||
464 | * table_index - Where the table index is returned | ||
594 | * | 465 | * |
595 | * RETURN: Status | 466 | * RETURN: Status and table index. |
596 | * | 467 | * |
597 | * DESCRIPTION: Allocates owner_id in table_desc | 468 | * DESCRIPTION: Add an ACPI table to the global table list |
598 | * | 469 | * |
599 | ******************************************************************************/ | 470 | ******************************************************************************/ |
600 | 471 | ||
601 | acpi_status acpi_tb_allocate_owner_id(u32 table_index) | 472 | acpi_status |
473 | acpi_tb_store_table(acpi_physical_address address, | ||
474 | struct acpi_table_header * table, | ||
475 | u32 length, u8 flags, u32 *table_index) | ||
602 | { | 476 | { |
603 | acpi_status status = AE_BAD_PARAMETER; | 477 | acpi_status status; |
604 | 478 | struct acpi_table_desc *table_desc; | |
605 | ACPI_FUNCTION_TRACE(tb_allocate_owner_id); | ||
606 | 479 | ||
607 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | 480 | status = acpi_tb_get_next_root_index(table_index); |
608 | if (table_index < acpi_gbl_root_table_list.current_table_count) { | 481 | if (ACPI_FAILURE(status)) { |
609 | status = acpi_ut_allocate_owner_id | 482 | return (status); |
610 | (&(acpi_gbl_root_table_list.tables[table_index].owner_id)); | ||
611 | } | 483 | } |
612 | 484 | ||
613 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 485 | /* Initialize added table */ |
614 | return_ACPI_STATUS(status); | ||
615 | } | ||
616 | |||
617 | /******************************************************************************* | ||
618 | * | ||
619 | * FUNCTION: acpi_tb_release_owner_id | ||
620 | * | ||
621 | * PARAMETERS: table_index - Table index | ||
622 | * | ||
623 | * RETURN: Status | ||
624 | * | ||
625 | * DESCRIPTION: Releases owner_id in table_desc | ||
626 | * | ||
627 | ******************************************************************************/ | ||
628 | |||
629 | acpi_status acpi_tb_release_owner_id(u32 table_index) | ||
630 | { | ||
631 | acpi_status status = AE_BAD_PARAMETER; | ||
632 | |||
633 | ACPI_FUNCTION_TRACE(tb_release_owner_id); | ||
634 | |||
635 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
636 | if (table_index < acpi_gbl_root_table_list.current_table_count) { | ||
637 | acpi_ut_release_owner_id(& | ||
638 | (acpi_gbl_root_table_list. | ||
639 | tables[table_index].owner_id)); | ||
640 | status = AE_OK; | ||
641 | } | ||
642 | 486 | ||
643 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 487 | table_desc = &acpi_gbl_root_table_list.tables[*table_index]; |
644 | return_ACPI_STATUS(status); | 488 | acpi_tb_init_table_descriptor(table_desc, address, flags, table); |
489 | table_desc->pointer = table; | ||
490 | return (AE_OK); | ||
645 | } | 491 | } |
646 | 492 | ||
647 | /******************************************************************************* | 493 | /******************************************************************************* |
648 | * | 494 | * |
649 | * FUNCTION: acpi_tb_get_owner_id | 495 | * FUNCTION: acpi_tb_uninstall_table |
650 | * | 496 | * |
651 | * PARAMETERS: table_index - Table index | 497 | * PARAMETERS: table_desc - Table descriptor |
652 | * owner_id - Where the table owner_id is returned | ||
653 | * | 498 | * |
654 | * RETURN: Status | 499 | * RETURN: None |
655 | * | 500 | * |
656 | * DESCRIPTION: returns owner_id for the ACPI table | 501 | * DESCRIPTION: Delete one internal ACPI table |
657 | * | 502 | * |
658 | ******************************************************************************/ | 503 | ******************************************************************************/ |
659 | 504 | ||
660 | acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id *owner_id) | 505 | void acpi_tb_uninstall_table(struct acpi_table_desc *table_desc) |
661 | { | 506 | { |
662 | acpi_status status = AE_BAD_PARAMETER; | ||
663 | |||
664 | ACPI_FUNCTION_TRACE(tb_get_owner_id); | ||
665 | 507 | ||
666 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | 508 | ACPI_FUNCTION_TRACE(tb_uninstall_table); |
667 | if (table_index < acpi_gbl_root_table_list.current_table_count) { | ||
668 | *owner_id = | ||
669 | acpi_gbl_root_table_list.tables[table_index].owner_id; | ||
670 | status = AE_OK; | ||
671 | } | ||
672 | 509 | ||
673 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 510 | /* Table must be installed */ |
674 | return_ACPI_STATUS(status); | ||
675 | } | ||
676 | |||
677 | /******************************************************************************* | ||
678 | * | ||
679 | * FUNCTION: acpi_tb_is_table_loaded | ||
680 | * | ||
681 | * PARAMETERS: table_index - Table index | ||
682 | * | ||
683 | * RETURN: Table Loaded Flag | ||
684 | * | ||
685 | ******************************************************************************/ | ||
686 | 511 | ||
687 | u8 acpi_tb_is_table_loaded(u32 table_index) | 512 | if (!table_desc->address) { |
688 | { | 513 | return_VOID; |
689 | u8 is_loaded = FALSE; | ||
690 | |||
691 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
692 | if (table_index < acpi_gbl_root_table_list.current_table_count) { | ||
693 | is_loaded = (u8) | ||
694 | (acpi_gbl_root_table_list.tables[table_index].flags & | ||
695 | ACPI_TABLE_IS_LOADED); | ||
696 | } | 514 | } |
697 | 515 | ||
698 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 516 | acpi_tb_invalidate_table(table_desc); |
699 | return (is_loaded); | ||
700 | } | ||
701 | |||
702 | /******************************************************************************* | ||
703 | * | ||
704 | * FUNCTION: acpi_tb_set_table_loaded_flag | ||
705 | * | ||
706 | * PARAMETERS: table_index - Table index | ||
707 | * is_loaded - TRUE if table is loaded, FALSE otherwise | ||
708 | * | ||
709 | * RETURN: None | ||
710 | * | ||
711 | * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE. | ||
712 | * | ||
713 | ******************************************************************************/ | ||
714 | |||
715 | void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded) | ||
716 | { | ||
717 | 517 | ||
718 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | 518 | if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) == |
719 | if (table_index < acpi_gbl_root_table_list.current_table_count) { | 519 | ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL) { |
720 | if (is_loaded) { | 520 | ACPI_FREE(ACPI_CAST_PTR(void, table_desc->address)); |
721 | acpi_gbl_root_table_list.tables[table_index].flags |= | ||
722 | ACPI_TABLE_IS_LOADED; | ||
723 | } else { | ||
724 | acpi_gbl_root_table_list.tables[table_index].flags &= | ||
725 | ~ACPI_TABLE_IS_LOADED; | ||
726 | } | ||
727 | } | 521 | } |
728 | 522 | ||
729 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 523 | table_desc->address = ACPI_PTR_TO_PHYSADDR(NULL); |
524 | return_VOID; | ||
730 | } | 525 | } |
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c index 9fb85f38de90..6b1ca9991b90 100644 --- a/drivers/acpi/acpica/tbutils.c +++ b/drivers/acpi/acpica/tbutils.c | |||
@@ -49,8 +49,6 @@ | |||
49 | ACPI_MODULE_NAME("tbutils") | 49 | ACPI_MODULE_NAME("tbutils") |
50 | 50 | ||
51 | /* Local prototypes */ | 51 | /* Local prototypes */ |
52 | static acpi_status acpi_tb_validate_xsdt(acpi_physical_address address); | ||
53 | |||
54 | static acpi_physical_address | 52 | static acpi_physical_address |
55 | acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size); | 53 | acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size); |
56 | 54 | ||
@@ -178,9 +176,13 @@ struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index) | |||
178 | } | 176 | } |
179 | 177 | ||
180 | ACPI_MEMCPY(new_table, table_desc->pointer, table_desc->length); | 178 | ACPI_MEMCPY(new_table, table_desc->pointer, table_desc->length); |
181 | acpi_tb_delete_table(table_desc); | 179 | acpi_tb_uninstall_table(table_desc); |
182 | table_desc->pointer = new_table; | 180 | |
183 | table_desc->flags = ACPI_TABLE_ORIGIN_ALLOCATED; | 181 | acpi_tb_init_table_descriptor(&acpi_gbl_root_table_list. |
182 | tables[ACPI_TABLE_INDEX_DSDT], | ||
183 | ACPI_PTR_TO_PHYSADDR(new_table), | ||
184 | ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, | ||
185 | new_table); | ||
184 | 186 | ||
185 | ACPI_INFO((AE_INFO, | 187 | ACPI_INFO((AE_INFO, |
186 | "Forced DSDT copy: length 0x%05X copied locally, original unmapped", | 188 | "Forced DSDT copy: length 0x%05X copied locally, original unmapped", |
@@ -191,116 +193,6 @@ struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index) | |||
191 | 193 | ||
192 | /******************************************************************************* | 194 | /******************************************************************************* |
193 | * | 195 | * |
194 | * FUNCTION: acpi_tb_install_table | ||
195 | * | ||
196 | * PARAMETERS: address - Physical address of DSDT or FACS | ||
197 | * signature - Table signature, NULL if no need to | ||
198 | * match | ||
199 | * table_index - Index into root table array | ||
200 | * | ||
201 | * RETURN: None | ||
202 | * | ||
203 | * DESCRIPTION: Install an ACPI table into the global data structure. The | ||
204 | * table override mechanism is called to allow the host | ||
205 | * OS to replace any table before it is installed in the root | ||
206 | * table array. | ||
207 | * | ||
208 | ******************************************************************************/ | ||
209 | |||
210 | void | ||
211 | acpi_tb_install_table(acpi_physical_address address, | ||
212 | char *signature, u32 table_index) | ||
213 | { | ||
214 | struct acpi_table_header *table; | ||
215 | struct acpi_table_header *final_table; | ||
216 | struct acpi_table_desc *table_desc; | ||
217 | |||
218 | if (!address) { | ||
219 | ACPI_ERROR((AE_INFO, | ||
220 | "Null physical address for ACPI table [%s]", | ||
221 | signature)); | ||
222 | return; | ||
223 | } | ||
224 | |||
225 | /* Map just the table header */ | ||
226 | |||
227 | table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); | ||
228 | if (!table) { | ||
229 | ACPI_ERROR((AE_INFO, | ||
230 | "Could not map memory for table [%s] at %p", | ||
231 | signature, ACPI_CAST_PTR(void, address))); | ||
232 | return; | ||
233 | } | ||
234 | |||
235 | /* If a particular signature is expected (DSDT/FACS), it must match */ | ||
236 | |||
237 | if (signature && !ACPI_COMPARE_NAME(table->signature, signature)) { | ||
238 | ACPI_BIOS_ERROR((AE_INFO, | ||
239 | "Invalid signature 0x%X for ACPI table, expected [%s]", | ||
240 | *ACPI_CAST_PTR(u32, table->signature), | ||
241 | signature)); | ||
242 | goto unmap_and_exit; | ||
243 | } | ||
244 | |||
245 | /* | ||
246 | * Initialize the table entry. Set the pointer to NULL, since the | ||
247 | * table is not fully mapped at this time. | ||
248 | */ | ||
249 | table_desc = &acpi_gbl_root_table_list.tables[table_index]; | ||
250 | |||
251 | table_desc->address = address; | ||
252 | table_desc->pointer = NULL; | ||
253 | table_desc->length = table->length; | ||
254 | table_desc->flags = ACPI_TABLE_ORIGIN_MAPPED; | ||
255 | ACPI_MOVE_32_TO_32(table_desc->signature.ascii, table->signature); | ||
256 | |||
257 | /* | ||
258 | * ACPI Table Override: | ||
259 | * | ||
260 | * Before we install the table, let the host OS override it with a new | ||
261 | * one if desired. Any table within the RSDT/XSDT can be replaced, | ||
262 | * including the DSDT which is pointed to by the FADT. | ||
263 | * | ||
264 | * NOTE: If the table is overridden, then final_table will contain a | ||
265 | * mapped pointer to the full new table. If the table is not overridden, | ||
266 | * or if there has been a physical override, then the table will be | ||
267 | * fully mapped later (in verify table). In any case, we must | ||
268 | * unmap the header that was mapped above. | ||
269 | */ | ||
270 | final_table = acpi_tb_table_override(table, table_desc); | ||
271 | if (!final_table) { | ||
272 | final_table = table; /* There was no override */ | ||
273 | } | ||
274 | |||
275 | acpi_tb_print_table_header(table_desc->address, final_table); | ||
276 | |||
277 | /* Set the global integer width (based upon revision of the DSDT) */ | ||
278 | |||
279 | if (table_index == ACPI_TABLE_INDEX_DSDT) { | ||
280 | acpi_ut_set_integer_width(final_table->revision); | ||
281 | } | ||
282 | |||
283 | /* | ||
284 | * If we have a physical override during this early loading of the ACPI | ||
285 | * tables, unmap the table for now. It will be mapped again later when | ||
286 | * it is actually used. This supports very early loading of ACPI tables, | ||
287 | * before virtual memory is fully initialized and running within the | ||
288 | * host OS. Note: A logical override has the ACPI_TABLE_ORIGIN_OVERRIDE | ||
289 | * flag set and will not be deleted below. | ||
290 | */ | ||
291 | if (final_table != table) { | ||
292 | acpi_tb_delete_table(table_desc); | ||
293 | } | ||
294 | |||
295 | unmap_and_exit: | ||
296 | |||
297 | /* Always unmap the table header that we mapped above */ | ||
298 | |||
299 | acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); | ||
300 | } | ||
301 | |||
302 | /******************************************************************************* | ||
303 | * | ||
304 | * FUNCTION: acpi_tb_get_root_table_entry | 196 | * FUNCTION: acpi_tb_get_root_table_entry |
305 | * | 197 | * |
306 | * PARAMETERS: table_entry - Pointer to the RSDT/XSDT table entry | 198 | * PARAMETERS: table_entry - Pointer to the RSDT/XSDT table entry |
@@ -357,87 +249,6 @@ acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size) | |||
357 | 249 | ||
358 | /******************************************************************************* | 250 | /******************************************************************************* |
359 | * | 251 | * |
360 | * FUNCTION: acpi_tb_validate_xsdt | ||
361 | * | ||
362 | * PARAMETERS: address - Physical address of the XSDT (from RSDP) | ||
363 | * | ||
364 | * RETURN: Status. AE_OK if the table appears to be valid. | ||
365 | * | ||
366 | * DESCRIPTION: Validate an XSDT to ensure that it is of minimum size and does | ||
367 | * not contain any NULL entries. A problem that is seen in the | ||
368 | * field is that the XSDT exists, but is actually useless because | ||
369 | * of one or more (or all) NULL entries. | ||
370 | * | ||
371 | ******************************************************************************/ | ||
372 | |||
373 | static acpi_status acpi_tb_validate_xsdt(acpi_physical_address xsdt_address) | ||
374 | { | ||
375 | struct acpi_table_header *table; | ||
376 | u8 *next_entry; | ||
377 | acpi_physical_address address; | ||
378 | u32 length; | ||
379 | u32 entry_count; | ||
380 | acpi_status status; | ||
381 | u32 i; | ||
382 | |||
383 | /* Get the XSDT length */ | ||
384 | |||
385 | table = | ||
386 | acpi_os_map_memory(xsdt_address, sizeof(struct acpi_table_header)); | ||
387 | if (!table) { | ||
388 | return (AE_NO_MEMORY); | ||
389 | } | ||
390 | |||
391 | length = table->length; | ||
392 | acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); | ||
393 | |||
394 | /* | ||
395 | * Minimum XSDT length is the size of the standard ACPI header | ||
396 | * plus one physical address entry | ||
397 | */ | ||
398 | if (length < (sizeof(struct acpi_table_header) + ACPI_XSDT_ENTRY_SIZE)) { | ||
399 | return (AE_INVALID_TABLE_LENGTH); | ||
400 | } | ||
401 | |||
402 | /* Map the entire XSDT */ | ||
403 | |||
404 | table = acpi_os_map_memory(xsdt_address, length); | ||
405 | if (!table) { | ||
406 | return (AE_NO_MEMORY); | ||
407 | } | ||
408 | |||
409 | /* Get the number of entries and pointer to first entry */ | ||
410 | |||
411 | status = AE_OK; | ||
412 | next_entry = ACPI_ADD_PTR(u8, table, sizeof(struct acpi_table_header)); | ||
413 | entry_count = (u32)((table->length - sizeof(struct acpi_table_header)) / | ||
414 | ACPI_XSDT_ENTRY_SIZE); | ||
415 | |||
416 | /* Validate each entry (physical address) within the XSDT */ | ||
417 | |||
418 | for (i = 0; i < entry_count; i++) { | ||
419 | address = | ||
420 | acpi_tb_get_root_table_entry(next_entry, | ||
421 | ACPI_XSDT_ENTRY_SIZE); | ||
422 | if (!address) { | ||
423 | |||
424 | /* Detected a NULL entry, XSDT is invalid */ | ||
425 | |||
426 | status = AE_NULL_ENTRY; | ||
427 | break; | ||
428 | } | ||
429 | |||
430 | next_entry += ACPI_XSDT_ENTRY_SIZE; | ||
431 | } | ||
432 | |||
433 | /* Unmap table */ | ||
434 | |||
435 | acpi_os_unmap_memory(table, length); | ||
436 | return (status); | ||
437 | } | ||
438 | |||
439 | /******************************************************************************* | ||
440 | * | ||
441 | * FUNCTION: acpi_tb_parse_root_table | 252 | * FUNCTION: acpi_tb_parse_root_table |
442 | * | 253 | * |
443 | * PARAMETERS: rsdp - Pointer to the RSDP | 254 | * PARAMETERS: rsdp - Pointer to the RSDP |
@@ -461,10 +272,10 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address) | |||
461 | u32 table_count; | 272 | u32 table_count; |
462 | struct acpi_table_header *table; | 273 | struct acpi_table_header *table; |
463 | acpi_physical_address address; | 274 | acpi_physical_address address; |
464 | acpi_physical_address rsdt_address; | ||
465 | u32 length; | 275 | u32 length; |
466 | u8 *table_entry; | 276 | u8 *table_entry; |
467 | acpi_status status; | 277 | acpi_status status; |
278 | u32 table_index; | ||
468 | 279 | ||
469 | ACPI_FUNCTION_TRACE(tb_parse_root_table); | 280 | ACPI_FUNCTION_TRACE(tb_parse_root_table); |
470 | 281 | ||
@@ -489,14 +300,11 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address) | |||
489 | * as per the ACPI specification. | 300 | * as per the ACPI specification. |
490 | */ | 301 | */ |
491 | address = (acpi_physical_address) rsdp->xsdt_physical_address; | 302 | address = (acpi_physical_address) rsdp->xsdt_physical_address; |
492 | rsdt_address = | ||
493 | (acpi_physical_address) rsdp->rsdt_physical_address; | ||
494 | table_entry_size = ACPI_XSDT_ENTRY_SIZE; | 303 | table_entry_size = ACPI_XSDT_ENTRY_SIZE; |
495 | } else { | 304 | } else { |
496 | /* Root table is an RSDT (32-bit physical addresses) */ | 305 | /* Root table is an RSDT (32-bit physical addresses) */ |
497 | 306 | ||
498 | address = (acpi_physical_address) rsdp->rsdt_physical_address; | 307 | address = (acpi_physical_address) rsdp->rsdt_physical_address; |
499 | rsdt_address = address; | ||
500 | table_entry_size = ACPI_RSDT_ENTRY_SIZE; | 308 | table_entry_size = ACPI_RSDT_ENTRY_SIZE; |
501 | } | 309 | } |
502 | 310 | ||
@@ -506,24 +314,6 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address) | |||
506 | */ | 314 | */ |
507 | acpi_os_unmap_memory(rsdp, sizeof(struct acpi_table_rsdp)); | 315 | acpi_os_unmap_memory(rsdp, sizeof(struct acpi_table_rsdp)); |
508 | 316 | ||
509 | /* | ||
510 | * If it is present and used, validate the XSDT for access/size | ||
511 | * and ensure that all table entries are at least non-NULL | ||
512 | */ | ||
513 | if (table_entry_size == ACPI_XSDT_ENTRY_SIZE) { | ||
514 | status = acpi_tb_validate_xsdt(address); | ||
515 | if (ACPI_FAILURE(status)) { | ||
516 | ACPI_BIOS_WARNING((AE_INFO, | ||
517 | "XSDT is invalid (%s), using RSDT", | ||
518 | acpi_format_exception(status))); | ||
519 | |||
520 | /* Fall back to the RSDT */ | ||
521 | |||
522 | address = rsdt_address; | ||
523 | table_entry_size = ACPI_RSDT_ENTRY_SIZE; | ||
524 | } | ||
525 | } | ||
526 | |||
527 | /* Map the RSDT/XSDT table header to get the full table length */ | 317 | /* Map the RSDT/XSDT table header to get the full table length */ |
528 | 318 | ||
529 | table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); | 319 | table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); |
@@ -576,55 +366,36 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address) | |||
576 | /* Initialize the root table array from the RSDT/XSDT */ | 366 | /* Initialize the root table array from the RSDT/XSDT */ |
577 | 367 | ||
578 | for (i = 0; i < table_count; i++) { | 368 | for (i = 0; i < table_count; i++) { |
579 | if (acpi_gbl_root_table_list.current_table_count >= | ||
580 | acpi_gbl_root_table_list.max_table_count) { | ||
581 | |||
582 | /* There is no more room in the root table array, attempt resize */ | ||
583 | |||
584 | status = acpi_tb_resize_root_table_list(); | ||
585 | if (ACPI_FAILURE(status)) { | ||
586 | ACPI_WARNING((AE_INFO, | ||
587 | "Truncating %u table entries!", | ||
588 | (unsigned) (table_count - | ||
589 | (acpi_gbl_root_table_list. | ||
590 | current_table_count - | ||
591 | 2)))); | ||
592 | break; | ||
593 | } | ||
594 | } | ||
595 | 369 | ||
596 | /* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */ | 370 | /* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */ |
597 | 371 | ||
598 | acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list. | 372 | address = |
599 | current_table_count].address = | ||
600 | acpi_tb_get_root_table_entry(table_entry, table_entry_size); | 373 | acpi_tb_get_root_table_entry(table_entry, table_entry_size); |
601 | 374 | ||
602 | table_entry += table_entry_size; | 375 | /* Skip NULL entries in RSDT/XSDT */ |
603 | acpi_gbl_root_table_list.current_table_count++; | ||
604 | } | ||
605 | |||
606 | /* | ||
607 | * It is not possible to map more than one entry in some environments, | ||
608 | * so unmap the root table here before mapping other tables | ||
609 | */ | ||
610 | acpi_os_unmap_memory(table, length); | ||
611 | 376 | ||
612 | /* | 377 | if (!address) { |
613 | * Complete the initialization of the root table array by examining | 378 | goto next_table; |
614 | * the header of each table | 379 | } |
615 | */ | ||
616 | for (i = 2; i < acpi_gbl_root_table_list.current_table_count; i++) { | ||
617 | acpi_tb_install_table(acpi_gbl_root_table_list.tables[i]. | ||
618 | address, NULL, i); | ||
619 | 380 | ||
620 | /* Special case for FADT - validate it then get the DSDT and FACS */ | 381 | status = acpi_tb_install_standard_table(address, |
382 | ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL, | ||
383 | FALSE, TRUE, | ||
384 | &table_index); | ||
621 | 385 | ||
622 | if (ACPI_COMPARE_NAME | 386 | if (ACPI_SUCCESS(status) && |
623 | (&acpi_gbl_root_table_list.tables[i].signature, | 387 | ACPI_COMPARE_NAME(&acpi_gbl_root_table_list. |
624 | ACPI_SIG_FADT)) { | 388 | tables[table_index].signature, |
625 | acpi_tb_parse_fadt(i); | 389 | ACPI_SIG_FADT)) { |
390 | acpi_tb_parse_fadt(table_index); | ||
626 | } | 391 | } |
392 | |||
393 | next_table: | ||
394 | |||
395 | table_entry += table_entry_size; | ||
627 | } | 396 | } |
628 | 397 | ||
398 | acpi_os_unmap_memory(table, length); | ||
399 | |||
629 | return_ACPI_STATUS(AE_OK); | 400 | return_ACPI_STATUS(AE_OK); |
630 | } | 401 | } |
diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c index a1593159d9ea..6482b0ded652 100644 --- a/drivers/acpi/acpica/tbxface.c +++ b/drivers/acpi/acpica/tbxface.c | |||
@@ -206,8 +206,8 @@ acpi_status | |||
206 | acpi_get_table_header(char *signature, | 206 | acpi_get_table_header(char *signature, |
207 | u32 instance, struct acpi_table_header *out_table_header) | 207 | u32 instance, struct acpi_table_header *out_table_header) |
208 | { | 208 | { |
209 | u32 i; | 209 | u32 i; |
210 | u32 j; | 210 | u32 j; |
211 | struct acpi_table_header *header; | 211 | struct acpi_table_header *header; |
212 | 212 | ||
213 | /* Parameter validation */ | 213 | /* Parameter validation */ |
@@ -233,7 +233,7 @@ acpi_get_table_header(char *signature, | |||
233 | if (!acpi_gbl_root_table_list.tables[i].pointer) { | 233 | if (!acpi_gbl_root_table_list.tables[i].pointer) { |
234 | if ((acpi_gbl_root_table_list.tables[i].flags & | 234 | if ((acpi_gbl_root_table_list.tables[i].flags & |
235 | ACPI_TABLE_ORIGIN_MASK) == | 235 | ACPI_TABLE_ORIGIN_MASK) == |
236 | ACPI_TABLE_ORIGIN_MAPPED) { | 236 | ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL) { |
237 | header = | 237 | header = |
238 | acpi_os_map_memory(acpi_gbl_root_table_list. | 238 | acpi_os_map_memory(acpi_gbl_root_table_list. |
239 | tables[i].address, | 239 | tables[i].address, |
@@ -321,8 +321,8 @@ acpi_get_table_with_size(char *signature, | |||
321 | u32 instance, struct acpi_table_header **out_table, | 321 | u32 instance, struct acpi_table_header **out_table, |
322 | acpi_size *tbl_size) | 322 | acpi_size *tbl_size) |
323 | { | 323 | { |
324 | u32 i; | 324 | u32 i; |
325 | u32 j; | 325 | u32 j; |
326 | acpi_status status; | 326 | acpi_status status; |
327 | 327 | ||
328 | /* Parameter validation */ | 328 | /* Parameter validation */ |
@@ -346,7 +346,7 @@ acpi_get_table_with_size(char *signature, | |||
346 | } | 346 | } |
347 | 347 | ||
348 | status = | 348 | status = |
349 | acpi_tb_verify_table(&acpi_gbl_root_table_list.tables[i]); | 349 | acpi_tb_validate_table(&acpi_gbl_root_table_list.tables[i]); |
350 | if (ACPI_SUCCESS(status)) { | 350 | if (ACPI_SUCCESS(status)) { |
351 | *out_table = acpi_gbl_root_table_list.tables[i].pointer; | 351 | *out_table = acpi_gbl_root_table_list.tables[i].pointer; |
352 | *tbl_size = acpi_gbl_root_table_list.tables[i].length; | 352 | *tbl_size = acpi_gbl_root_table_list.tables[i].length; |
@@ -390,7 +390,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_table) | |||
390 | * | 390 | * |
391 | ******************************************************************************/ | 391 | ******************************************************************************/ |
392 | acpi_status | 392 | acpi_status |
393 | acpi_get_table_by_index(u32 table_index, struct acpi_table_header **table) | 393 | acpi_get_table_by_index(u32 table_index, struct acpi_table_header ** table) |
394 | { | 394 | { |
395 | acpi_status status; | 395 | acpi_status status; |
396 | 396 | ||
@@ -416,8 +416,8 @@ acpi_get_table_by_index(u32 table_index, struct acpi_table_header **table) | |||
416 | /* Table is not mapped, map it */ | 416 | /* Table is not mapped, map it */ |
417 | 417 | ||
418 | status = | 418 | status = |
419 | acpi_tb_verify_table(&acpi_gbl_root_table_list. | 419 | acpi_tb_validate_table(&acpi_gbl_root_table_list. |
420 | tables[table_index]); | 420 | tables[table_index]); |
421 | if (ACPI_FAILURE(status)) { | 421 | if (ACPI_FAILURE(status)) { |
422 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 422 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
423 | return_ACPI_STATUS(status); | 423 | return_ACPI_STATUS(status); |
diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c index 0909420fc776..ab5308b81aa8 100644 --- a/drivers/acpi/acpica/tbxfload.c +++ b/drivers/acpi/acpica/tbxfload.c | |||
@@ -117,7 +117,7 @@ static acpi_status acpi_tb_load_namespace(void) | |||
117 | tables[ACPI_TABLE_INDEX_DSDT].signature), | 117 | tables[ACPI_TABLE_INDEX_DSDT].signature), |
118 | ACPI_SIG_DSDT) | 118 | ACPI_SIG_DSDT) |
119 | || | 119 | || |
120 | ACPI_FAILURE(acpi_tb_verify_table | 120 | ACPI_FAILURE(acpi_tb_validate_table |
121 | (&acpi_gbl_root_table_list. | 121 | (&acpi_gbl_root_table_list. |
122 | tables[ACPI_TABLE_INDEX_DSDT]))) { | 122 | tables[ACPI_TABLE_INDEX_DSDT]))) { |
123 | status = AE_NO_ACPI_TABLES; | 123 | status = AE_NO_ACPI_TABLES; |
@@ -128,7 +128,7 @@ static acpi_status acpi_tb_load_namespace(void) | |||
128 | * Save the DSDT pointer for simple access. This is the mapped memory | 128 | * Save the DSDT pointer for simple access. This is the mapped memory |
129 | * address. We must take care here because the address of the .Tables | 129 | * address. We must take care here because the address of the .Tables |
130 | * array can change dynamically as tables are loaded at run-time. Note: | 130 | * array can change dynamically as tables are loaded at run-time. Note: |
131 | * .Pointer field is not validated until after call to acpi_tb_verify_table. | 131 | * .Pointer field is not validated until after call to acpi_tb_validate_table. |
132 | */ | 132 | */ |
133 | acpi_gbl_DSDT = | 133 | acpi_gbl_DSDT = |
134 | acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer; | 134 | acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer; |
@@ -174,24 +174,11 @@ static acpi_status acpi_tb_load_namespace(void) | |||
174 | (acpi_gbl_root_table_list.tables[i]. | 174 | (acpi_gbl_root_table_list.tables[i]. |
175 | signature), ACPI_SIG_PSDT)) | 175 | signature), ACPI_SIG_PSDT)) |
176 | || | 176 | || |
177 | ACPI_FAILURE(acpi_tb_verify_table | 177 | ACPI_FAILURE(acpi_tb_validate_table |
178 | (&acpi_gbl_root_table_list.tables[i]))) { | 178 | (&acpi_gbl_root_table_list.tables[i]))) { |
179 | continue; | 179 | continue; |
180 | } | 180 | } |
181 | 181 | ||
182 | /* | ||
183 | * Optionally do not load any SSDTs from the RSDT/XSDT. This can | ||
184 | * be useful for debugging ACPI problems on some machines. | ||
185 | */ | ||
186 | if (acpi_gbl_disable_ssdt_table_load) { | ||
187 | ACPI_INFO((AE_INFO, "Ignoring %4.4s at %p", | ||
188 | acpi_gbl_root_table_list.tables[i].signature. | ||
189 | ascii, ACPI_CAST_PTR(void, | ||
190 | acpi_gbl_root_table_list. | ||
191 | tables[i].address))); | ||
192 | continue; | ||
193 | } | ||
194 | |||
195 | /* Ignore errors while loading tables, get as many as possible */ | 182 | /* Ignore errors while loading tables, get as many as possible */ |
196 | 183 | ||
197 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 184 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
@@ -208,6 +195,45 @@ unlock_and_exit: | |||
208 | 195 | ||
209 | /******************************************************************************* | 196 | /******************************************************************************* |
210 | * | 197 | * |
198 | * FUNCTION: acpi_install_table | ||
199 | * | ||
200 | * PARAMETERS: address - Address of the ACPI table to be installed. | ||
201 | * physical - Whether the address is a physical table | ||
202 | * address or not | ||
203 | * | ||
204 | * RETURN: Status | ||
205 | * | ||
206 | * DESCRIPTION: Dynamically install an ACPI table. | ||
207 | * Note: This function should only be invoked after | ||
208 | * acpi_initialize_tables() and before acpi_load_tables(). | ||
209 | * | ||
210 | ******************************************************************************/ | ||
211 | |||
212 | acpi_status __init | ||
213 | acpi_install_table(acpi_physical_address address, u8 physical) | ||
214 | { | ||
215 | acpi_status status; | ||
216 | u8 flags; | ||
217 | u32 table_index; | ||
218 | |||
219 | ACPI_FUNCTION_TRACE(acpi_install_table); | ||
220 | |||
221 | if (physical) { | ||
222 | flags = ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL; | ||
223 | } else { | ||
224 | flags = ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL; | ||
225 | } | ||
226 | |||
227 | status = acpi_tb_install_standard_table(address, flags, | ||
228 | FALSE, FALSE, &table_index); | ||
229 | |||
230 | return_ACPI_STATUS(status); | ||
231 | } | ||
232 | |||
233 | ACPI_EXPORT_SYMBOL_INIT(acpi_install_table) | ||
234 | |||
235 | /******************************************************************************* | ||
236 | * | ||
211 | * FUNCTION: acpi_load_table | 237 | * FUNCTION: acpi_load_table |
212 | * | 238 | * |
213 | * PARAMETERS: table - Pointer to a buffer containing the ACPI | 239 | * PARAMETERS: table - Pointer to a buffer containing the ACPI |
@@ -222,11 +248,9 @@ unlock_and_exit: | |||
222 | * to ensure that the table is not deleted or unmapped. | 248 | * to ensure that the table is not deleted or unmapped. |
223 | * | 249 | * |
224 | ******************************************************************************/ | 250 | ******************************************************************************/ |
225 | |||
226 | acpi_status acpi_load_table(struct acpi_table_header *table) | 251 | acpi_status acpi_load_table(struct acpi_table_header *table) |
227 | { | 252 | { |
228 | acpi_status status; | 253 | acpi_status status; |
229 | struct acpi_table_desc table_desc; | ||
230 | u32 table_index; | 254 | u32 table_index; |
231 | 255 | ||
232 | ACPI_FUNCTION_TRACE(acpi_load_table); | 256 | ACPI_FUNCTION_TRACE(acpi_load_table); |
@@ -237,14 +261,6 @@ acpi_status acpi_load_table(struct acpi_table_header *table) | |||
237 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 261 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
238 | } | 262 | } |
239 | 263 | ||
240 | /* Init local table descriptor */ | ||
241 | |||
242 | ACPI_MEMSET(&table_desc, 0, sizeof(struct acpi_table_desc)); | ||
243 | table_desc.address = ACPI_PTR_TO_PHYSADDR(table); | ||
244 | table_desc.pointer = table; | ||
245 | table_desc.length = table->length; | ||
246 | table_desc.flags = ACPI_TABLE_ORIGIN_UNKNOWN; | ||
247 | |||
248 | /* Must acquire the interpreter lock during this operation */ | 264 | /* Must acquire the interpreter lock during this operation */ |
249 | 265 | ||
250 | status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); | 266 | status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); |
@@ -255,7 +271,24 @@ acpi_status acpi_load_table(struct acpi_table_header *table) | |||
255 | /* Install the table and load it into the namespace */ | 271 | /* Install the table and load it into the namespace */ |
256 | 272 | ||
257 | ACPI_INFO((AE_INFO, "Host-directed Dynamic ACPI Table Load:")); | 273 | ACPI_INFO((AE_INFO, "Host-directed Dynamic ACPI Table Load:")); |
258 | status = acpi_tb_add_table(&table_desc, &table_index); | 274 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
275 | |||
276 | status = acpi_tb_install_standard_table(ACPI_PTR_TO_PHYSADDR(table), | ||
277 | ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL, | ||
278 | TRUE, FALSE, &table_index); | ||
279 | |||
280 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
281 | if (ACPI_FAILURE(status)) { | ||
282 | goto unlock_and_exit; | ||
283 | } | ||
284 | |||
285 | /* | ||
286 | * Note: Now table is "INSTALLED", it must be validated before | ||
287 | * using. | ||
288 | */ | ||
289 | status = | ||
290 | acpi_tb_validate_table(&acpi_gbl_root_table_list. | ||
291 | tables[table_index]); | ||
259 | if (ACPI_FAILURE(status)) { | 292 | if (ACPI_FAILURE(status)) { |
260 | goto unlock_and_exit; | 293 | goto unlock_and_exit; |
261 | } | 294 | } |
diff --git a/drivers/acpi/acpica/utdecode.c b/drivers/acpi/acpica/utdecode.c index fbfa9eca011f..90ec37c473c6 100644 --- a/drivers/acpi/acpica/utdecode.c +++ b/drivers/acpi/acpica/utdecode.c | |||
@@ -462,7 +462,7 @@ char *acpi_ut_get_mutex_name(u32 mutex_id) | |||
462 | 462 | ||
463 | /* Names for Notify() values, used for debug output */ | 463 | /* Names for Notify() values, used for debug output */ |
464 | 464 | ||
465 | static const char *acpi_gbl_notify_value_names[ACPI_NOTIFY_MAX + 1] = { | 465 | static const char *acpi_gbl_generic_notify[ACPI_NOTIFY_MAX + 1] = { |
466 | /* 00 */ "Bus Check", | 466 | /* 00 */ "Bus Check", |
467 | /* 01 */ "Device Check", | 467 | /* 01 */ "Device Check", |
468 | /* 02 */ "Device Wake", | 468 | /* 02 */ "Device Wake", |
@@ -473,23 +473,75 @@ static const char *acpi_gbl_notify_value_names[ACPI_NOTIFY_MAX + 1] = { | |||
473 | /* 07 */ "Power Fault", | 473 | /* 07 */ "Power Fault", |
474 | /* 08 */ "Capabilities Check", | 474 | /* 08 */ "Capabilities Check", |
475 | /* 09 */ "Device PLD Check", | 475 | /* 09 */ "Device PLD Check", |
476 | /* 10 */ "Reserved", | 476 | /* 0A */ "Reserved", |
477 | /* 11 */ "System Locality Update", | 477 | /* 0B */ "System Locality Update", |
478 | /* 12 */ "Shutdown Request" | 478 | /* 0C */ "Shutdown Request" |
479 | }; | 479 | }; |
480 | 480 | ||
481 | const char *acpi_ut_get_notify_name(u32 notify_value) | 481 | static const char *acpi_gbl_device_notify[4] = { |
482 | /* 80 */ "Status Change", | ||
483 | /* 81 */ "Information Change", | ||
484 | /* 82 */ "Device-Specific Change", | ||
485 | /* 83 */ "Device-Specific Change" | ||
486 | }; | ||
487 | |||
488 | static const char *acpi_gbl_processor_notify[4] = { | ||
489 | /* 80 */ "Performance Capability Change", | ||
490 | /* 81 */ "C-State Change", | ||
491 | /* 82 */ "Throttling Capability Change", | ||
492 | /* 83 */ "Device-Specific Change" | ||
493 | }; | ||
494 | |||
495 | static const char *acpi_gbl_thermal_notify[4] = { | ||
496 | /* 80 */ "Thermal Status Change", | ||
497 | /* 81 */ "Thermal Trip Point Change", | ||
498 | /* 82 */ "Thermal Device List Change", | ||
499 | /* 83 */ "Thermal Relationship Change" | ||
500 | }; | ||
501 | |||
502 | const char *acpi_ut_get_notify_name(u32 notify_value, acpi_object_type type) | ||
482 | { | 503 | { |
483 | 504 | ||
505 | /* 00 - 0C are common to all object types */ | ||
506 | |||
484 | if (notify_value <= ACPI_NOTIFY_MAX) { | 507 | if (notify_value <= ACPI_NOTIFY_MAX) { |
485 | return (acpi_gbl_notify_value_names[notify_value]); | 508 | return (acpi_gbl_generic_notify[notify_value]); |
486 | } else if (notify_value <= ACPI_MAX_SYS_NOTIFY) { | 509 | } |
510 | |||
511 | /* 0D - 7F are reserved */ | ||
512 | |||
513 | if (notify_value <= ACPI_MAX_SYS_NOTIFY) { | ||
487 | return ("Reserved"); | 514 | return ("Reserved"); |
488 | } else if (notify_value <= ACPI_MAX_DEVICE_SPECIFIC_NOTIFY) { | ||
489 | return ("Device Specific"); | ||
490 | } else { | ||
491 | return ("Hardware Specific"); | ||
492 | } | 515 | } |
516 | |||
517 | /* 80 - 83 are per-object-type */ | ||
518 | |||
519 | if (notify_value <= 0x83) { | ||
520 | switch (type) { | ||
521 | case ACPI_TYPE_ANY: | ||
522 | case ACPI_TYPE_DEVICE: | ||
523 | return (acpi_gbl_device_notify[notify_value - 0x80]); | ||
524 | |||
525 | case ACPI_TYPE_PROCESSOR: | ||
526 | return (acpi_gbl_processor_notify[notify_value - 0x80]); | ||
527 | |||
528 | case ACPI_TYPE_THERMAL: | ||
529 | return (acpi_gbl_thermal_notify[notify_value - 0x80]); | ||
530 | |||
531 | default: | ||
532 | return ("Target object type does not support notifies"); | ||
533 | } | ||
534 | } | ||
535 | |||
536 | /* 84 - BF are device-specific */ | ||
537 | |||
538 | if (notify_value <= ACPI_MAX_DEVICE_SPECIFIC_NOTIFY) { | ||
539 | return ("Device-Specific"); | ||
540 | } | ||
541 | |||
542 | /* C0 and above are hardware-specific */ | ||
543 | |||
544 | return ("Hardware-Specific"); | ||
493 | } | 545 | } |
494 | #endif | 546 | #endif |
495 | 547 | ||
diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index f3abeae9d2f8..d69be3cb3fae 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c | |||
@@ -55,28 +55,7 @@ ACPI_MODULE_NAME("utglobal") | |||
55 | * Static global variable initialization. | 55 | * Static global variable initialization. |
56 | * | 56 | * |
57 | ******************************************************************************/ | 57 | ******************************************************************************/ |
58 | /* Debug output control masks */ | ||
59 | u32 acpi_dbg_level = ACPI_DEBUG_DEFAULT; | ||
60 | |||
61 | u32 acpi_dbg_layer = 0; | ||
62 | |||
63 | /* acpi_gbl_FADT is a local copy of the FADT, converted to a common format. */ | ||
64 | |||
65 | struct acpi_table_fadt acpi_gbl_FADT; | ||
66 | u32 acpi_gbl_trace_flags; | ||
67 | acpi_name acpi_gbl_trace_method_name; | ||
68 | u8 acpi_gbl_system_awake_and_running; | ||
69 | u32 acpi_current_gpe_count; | ||
70 | |||
71 | /* | ||
72 | * ACPI 5.0 introduces the concept of a "reduced hardware platform", meaning | ||
73 | * that the ACPI hardware is no longer required. A flag in the FADT indicates | ||
74 | * a reduced HW machine, and that flag is duplicated here for convenience. | ||
75 | */ | ||
76 | u8 acpi_gbl_reduced_hardware; | ||
77 | |||
78 | /* Various state name strings */ | 58 | /* Various state name strings */ |
79 | |||
80 | const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT] = { | 59 | const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT] = { |
81 | "\\_S0_", | 60 | "\\_S0_", |
82 | "\\_S1_", | 61 | "\\_S1_", |
@@ -337,7 +316,6 @@ acpi_status acpi_ut_init_globals(void) | |||
337 | acpi_gbl_acpi_hardware_present = TRUE; | 316 | acpi_gbl_acpi_hardware_present = TRUE; |
338 | acpi_gbl_last_owner_id_index = 0; | 317 | acpi_gbl_last_owner_id_index = 0; |
339 | acpi_gbl_next_owner_id_offset = 0; | 318 | acpi_gbl_next_owner_id_offset = 0; |
340 | acpi_gbl_trace_method_name = 0; | ||
341 | acpi_gbl_trace_dbg_level = 0; | 319 | acpi_gbl_trace_dbg_level = 0; |
342 | acpi_gbl_trace_dbg_layer = 0; | 320 | acpi_gbl_trace_dbg_layer = 0; |
343 | acpi_gbl_debugger_configuration = DEBUGGER_THREADING; | 321 | acpi_gbl_debugger_configuration = DEBUGGER_THREADING; |
@@ -377,9 +355,7 @@ acpi_status acpi_ut_init_globals(void) | |||
377 | acpi_gbl_disable_mem_tracking = FALSE; | 355 | acpi_gbl_disable_mem_tracking = FALSE; |
378 | #endif | 356 | #endif |
379 | 357 | ||
380 | #ifdef ACPI_DEBUGGER | 358 | ACPI_DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = FALSE); |
381 | acpi_gbl_db_terminate_threads = FALSE; | ||
382 | #endif | ||
383 | 359 | ||
384 | return_ACPI_STATUS(AE_OK); | 360 | return_ACPI_STATUS(AE_OK); |
385 | } | 361 | } |
diff --git a/drivers/acpi/acpica/utstring.c b/drivers/acpi/acpica/utstring.c index 77219336c7e0..6dc54b3c28b0 100644 --- a/drivers/acpi/acpica/utstring.c +++ b/drivers/acpi/acpica/utstring.c | |||
@@ -353,7 +353,7 @@ void acpi_ut_print_string(char *string, u16 max_length) | |||
353 | } | 353 | } |
354 | 354 | ||
355 | acpi_os_printf("\""); | 355 | acpi_os_printf("\""); |
356 | for (i = 0; string[i] && (i < max_length); i++) { | 356 | for (i = 0; (i < max_length) && string[i]; i++) { |
357 | 357 | ||
358 | /* Escape sequences */ | 358 | /* Escape sequences */ |
359 | 359 | ||
diff --git a/drivers/acpi/acpica/utxferror.c b/drivers/acpi/acpica/utxferror.c index edd861102f1b..88ef77f3cf88 100644 --- a/drivers/acpi/acpica/utxferror.c +++ b/drivers/acpi/acpica/utxferror.c | |||
@@ -53,6 +53,7 @@ ACPI_MODULE_NAME("utxferror") | |||
53 | * This module is used for the in-kernel ACPICA as well as the ACPICA | 53 | * This module is used for the in-kernel ACPICA as well as the ACPICA |
54 | * tools/applications. | 54 | * tools/applications. |
55 | */ | 55 | */ |
56 | #ifndef ACPI_NO_ERROR_MESSAGES /* Entire module */ | ||
56 | /******************************************************************************* | 57 | /******************************************************************************* |
57 | * | 58 | * |
58 | * FUNCTION: acpi_error | 59 | * FUNCTION: acpi_error |
@@ -249,3 +250,4 @@ acpi_bios_warning(const char *module_name, | |||
249 | } | 250 | } |
250 | 251 | ||
251 | ACPI_EXPORT_SYMBOL(acpi_bios_warning) | 252 | ACPI_EXPORT_SYMBOL(acpi_bios_warning) |
253 | #endif /* ACPI_NO_ERROR_MESSAGES */ | ||
diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c index 1be6f5564485..a095d4f858da 100644 --- a/drivers/acpi/apei/einj.c +++ b/drivers/acpi/apei/einj.c | |||
@@ -202,7 +202,7 @@ static void check_vendor_extension(u64 paddr, | |||
202 | 202 | ||
203 | if (!offset) | 203 | if (!offset) |
204 | return; | 204 | return; |
205 | v = acpi_os_map_memory(paddr + offset, sizeof(*v)); | 205 | v = acpi_os_map_iomem(paddr + offset, sizeof(*v)); |
206 | if (!v) | 206 | if (!v) |
207 | return; | 207 | return; |
208 | sbdf = v->pcie_sbdf; | 208 | sbdf = v->pcie_sbdf; |
@@ -210,7 +210,7 @@ static void check_vendor_extension(u64 paddr, | |||
210 | sbdf >> 24, (sbdf >> 16) & 0xff, | 210 | sbdf >> 24, (sbdf >> 16) & 0xff, |
211 | (sbdf >> 11) & 0x1f, (sbdf >> 8) & 0x7, | 211 | (sbdf >> 11) & 0x1f, (sbdf >> 8) & 0x7, |
212 | v->vendor_id, v->device_id, v->rev_id); | 212 | v->vendor_id, v->device_id, v->rev_id); |
213 | acpi_os_unmap_memory(v, sizeof(*v)); | 213 | acpi_os_unmap_iomem(v, sizeof(*v)); |
214 | } | 214 | } |
215 | 215 | ||
216 | static void *einj_get_parameter_address(void) | 216 | static void *einj_get_parameter_address(void) |
@@ -236,7 +236,7 @@ static void *einj_get_parameter_address(void) | |||
236 | if (pa_v5) { | 236 | if (pa_v5) { |
237 | struct set_error_type_with_address *v5param; | 237 | struct set_error_type_with_address *v5param; |
238 | 238 | ||
239 | v5param = acpi_os_map_memory(pa_v5, sizeof(*v5param)); | 239 | v5param = acpi_os_map_iomem(pa_v5, sizeof(*v5param)); |
240 | if (v5param) { | 240 | if (v5param) { |
241 | acpi5 = 1; | 241 | acpi5 = 1; |
242 | check_vendor_extension(pa_v5, v5param); | 242 | check_vendor_extension(pa_v5, v5param); |
@@ -246,11 +246,11 @@ static void *einj_get_parameter_address(void) | |||
246 | if (param_extension && pa_v4) { | 246 | if (param_extension && pa_v4) { |
247 | struct einj_parameter *v4param; | 247 | struct einj_parameter *v4param; |
248 | 248 | ||
249 | v4param = acpi_os_map_memory(pa_v4, sizeof(*v4param)); | 249 | v4param = acpi_os_map_iomem(pa_v4, sizeof(*v4param)); |
250 | if (!v4param) | 250 | if (!v4param) |
251 | return NULL; | 251 | return NULL; |
252 | if (v4param->reserved1 || v4param->reserved2) { | 252 | if (v4param->reserved1 || v4param->reserved2) { |
253 | acpi_os_unmap_memory(v4param, sizeof(*v4param)); | 253 | acpi_os_unmap_iomem(v4param, sizeof(*v4param)); |
254 | return NULL; | 254 | return NULL; |
255 | } | 255 | } |
256 | return v4param; | 256 | return v4param; |
@@ -794,7 +794,7 @@ err_unmap: | |||
794 | sizeof(struct set_error_type_with_address) : | 794 | sizeof(struct set_error_type_with_address) : |
795 | sizeof(struct einj_parameter); | 795 | sizeof(struct einj_parameter); |
796 | 796 | ||
797 | acpi_os_unmap_memory(einj_param, size); | 797 | acpi_os_unmap_iomem(einj_param, size); |
798 | } | 798 | } |
799 | apei_exec_post_unmap_gars(&ctx); | 799 | apei_exec_post_unmap_gars(&ctx); |
800 | err_release: | 800 | err_release: |
@@ -816,7 +816,7 @@ static void __exit einj_exit(void) | |||
816 | sizeof(struct set_error_type_with_address) : | 816 | sizeof(struct set_error_type_with_address) : |
817 | sizeof(struct einj_parameter); | 817 | sizeof(struct einj_parameter); |
818 | 818 | ||
819 | acpi_os_unmap_memory(einj_param, size); | 819 | acpi_os_unmap_iomem(einj_param, size); |
820 | } | 820 | } |
821 | einj_exec_ctx_init(&ctx); | 821 | einj_exec_ctx_init(&ctx); |
822 | apei_exec_post_unmap_gars(&ctx); | 822 | apei_exec_post_unmap_gars(&ctx); |
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 4ce0ea1e5a4e..c5bc8cfe09fa 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -489,6 +489,9 @@ void __init acpi_early_init(void) | |||
489 | 489 | ||
490 | printk(KERN_INFO PREFIX "Core revision %08x\n", ACPI_CA_VERSION); | 490 | printk(KERN_INFO PREFIX "Core revision %08x\n", ACPI_CA_VERSION); |
491 | 491 | ||
492 | /* It's safe to verify table checksums during late stage */ | ||
493 | acpi_gbl_verify_table_checksum = TRUE; | ||
494 | |||
492 | /* enable workarounds, unless strict ACPI spec. compliance */ | 495 | /* enable workarounds, unless strict ACPI spec. compliance */ |
493 | if (!acpi_strict) | 496 | if (!acpi_strict) |
494 | acpi_gbl_enable_interpreter_slack = TRUE; | 497 | acpi_gbl_enable_interpreter_slack = TRUE; |
diff --git a/drivers/acpi/nvs.c b/drivers/acpi/nvs.c index de4fe03873c5..85287b8fe3aa 100644 --- a/drivers/acpi/nvs.c +++ b/drivers/acpi/nvs.c | |||
@@ -139,8 +139,8 @@ void suspend_nvs_free(void) | |||
139 | iounmap(entry->kaddr); | 139 | iounmap(entry->kaddr); |
140 | entry->unmap = false; | 140 | entry->unmap = false; |
141 | } else { | 141 | } else { |
142 | acpi_os_unmap_memory(entry->kaddr, | 142 | acpi_os_unmap_iomem(entry->kaddr, |
143 | entry->size); | 143 | entry->size); |
144 | } | 144 | } |
145 | entry->kaddr = NULL; | 145 | entry->kaddr = NULL; |
146 | } | 146 | } |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 6776c599816f..147bc1b91b42 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -355,7 +355,7 @@ static void acpi_unmap(acpi_physical_address pg_off, void __iomem *vaddr) | |||
355 | } | 355 | } |
356 | 356 | ||
357 | void __iomem *__init_refok | 357 | void __iomem *__init_refok |
358 | acpi_os_map_memory(acpi_physical_address phys, acpi_size size) | 358 | acpi_os_map_iomem(acpi_physical_address phys, acpi_size size) |
359 | { | 359 | { |
360 | struct acpi_ioremap *map; | 360 | struct acpi_ioremap *map; |
361 | void __iomem *virt; | 361 | void __iomem *virt; |
@@ -401,10 +401,17 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size) | |||
401 | 401 | ||
402 | list_add_tail_rcu(&map->list, &acpi_ioremaps); | 402 | list_add_tail_rcu(&map->list, &acpi_ioremaps); |
403 | 403 | ||
404 | out: | 404 | out: |
405 | mutex_unlock(&acpi_ioremap_lock); | 405 | mutex_unlock(&acpi_ioremap_lock); |
406 | return map->virt + (phys - map->phys); | 406 | return map->virt + (phys - map->phys); |
407 | } | 407 | } |
408 | EXPORT_SYMBOL_GPL(acpi_os_map_iomem); | ||
409 | |||
410 | void *__init_refok | ||
411 | acpi_os_map_memory(acpi_physical_address phys, acpi_size size) | ||
412 | { | ||
413 | return (void *)acpi_os_map_iomem(phys, size); | ||
414 | } | ||
408 | EXPORT_SYMBOL_GPL(acpi_os_map_memory); | 415 | EXPORT_SYMBOL_GPL(acpi_os_map_memory); |
409 | 416 | ||
410 | static void acpi_os_drop_map_ref(struct acpi_ioremap *map) | 417 | static void acpi_os_drop_map_ref(struct acpi_ioremap *map) |
@@ -422,7 +429,7 @@ static void acpi_os_map_cleanup(struct acpi_ioremap *map) | |||
422 | } | 429 | } |
423 | } | 430 | } |
424 | 431 | ||
425 | void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size) | 432 | void __ref acpi_os_unmap_iomem(void __iomem *virt, acpi_size size) |
426 | { | 433 | { |
427 | struct acpi_ioremap *map; | 434 | struct acpi_ioremap *map; |
428 | 435 | ||
@@ -443,6 +450,12 @@ void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size) | |||
443 | 450 | ||
444 | acpi_os_map_cleanup(map); | 451 | acpi_os_map_cleanup(map); |
445 | } | 452 | } |
453 | EXPORT_SYMBOL_GPL(acpi_os_unmap_iomem); | ||
454 | |||
455 | void __ref acpi_os_unmap_memory(void *virt, acpi_size size) | ||
456 | { | ||
457 | return acpi_os_unmap_iomem((void __iomem *)virt, size); | ||
458 | } | ||
446 | EXPORT_SYMBOL_GPL(acpi_os_unmap_memory); | 459 | EXPORT_SYMBOL_GPL(acpi_os_unmap_memory); |
447 | 460 | ||
448 | void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size) | 461 | void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size) |
@@ -464,7 +477,7 @@ int acpi_os_map_generic_address(struct acpi_generic_address *gas) | |||
464 | if (!addr || !gas->bit_width) | 477 | if (!addr || !gas->bit_width) |
465 | return -EINVAL; | 478 | return -EINVAL; |
466 | 479 | ||
467 | virt = acpi_os_map_memory(addr, gas->bit_width / 8); | 480 | virt = acpi_os_map_iomem(addr, gas->bit_width / 8); |
468 | if (!virt) | 481 | if (!virt) |
469 | return -EIO; | 482 | return -EIO; |
470 | 483 | ||
@@ -1770,16 +1783,15 @@ acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object) | |||
1770 | } | 1783 | } |
1771 | #endif | 1784 | #endif |
1772 | 1785 | ||
1773 | static int __init acpi_no_auto_ssdt_setup(char *s) | 1786 | static int __init acpi_no_static_ssdt_setup(char *s) |
1774 | { | 1787 | { |
1775 | printk(KERN_NOTICE PREFIX "SSDT auto-load disabled\n"); | 1788 | acpi_gbl_disable_ssdt_table_install = TRUE; |
1789 | pr_info("ACPI: static SSDT installation disabled\n"); | ||
1776 | 1790 | ||
1777 | acpi_gbl_disable_ssdt_table_load = TRUE; | 1791 | return 0; |
1778 | |||
1779 | return 1; | ||
1780 | } | 1792 | } |
1781 | 1793 | ||
1782 | __setup("acpi_no_auto_ssdt", acpi_no_auto_ssdt_setup); | 1794 | early_param("acpi_no_static_ssdt", acpi_no_static_ssdt_setup); |
1783 | 1795 | ||
1784 | static int __init acpi_disable_return_repair(char *s) | 1796 | static int __init acpi_disable_return_repair(char *s) |
1785 | { | 1797 | { |
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index 21782290df41..05550ba44d32 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c | |||
@@ -44,6 +44,12 @@ static struct acpi_table_desc initial_tables[ACPI_MAX_TABLES] __initdata; | |||
44 | 44 | ||
45 | static int acpi_apic_instance __initdata; | 45 | static int acpi_apic_instance __initdata; |
46 | 46 | ||
47 | /* | ||
48 | * Disable table checksum verification for the early stage due to the size | ||
49 | * limitation of the current x86 early mapping implementation. | ||
50 | */ | ||
51 | static bool acpi_verify_table_checksum __initdata = false; | ||
52 | |||
47 | void acpi_table_print_madt_entry(struct acpi_subtable_header *header) | 53 | void acpi_table_print_madt_entry(struct acpi_subtable_header *header) |
48 | { | 54 | { |
49 | if (!header) | 55 | if (!header) |
@@ -333,6 +339,14 @@ int __init acpi_table_init(void) | |||
333 | { | 339 | { |
334 | acpi_status status; | 340 | acpi_status status; |
335 | 341 | ||
342 | if (acpi_verify_table_checksum) { | ||
343 | pr_info("Early table checksum verification enabled\n"); | ||
344 | acpi_gbl_verify_table_checksum = TRUE; | ||
345 | } else { | ||
346 | pr_info("Early table checksum verification disabled\n"); | ||
347 | acpi_gbl_verify_table_checksum = FALSE; | ||
348 | } | ||
349 | |||
336 | status = acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0); | 350 | status = acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0); |
337 | if (ACPI_FAILURE(status)) | 351 | if (ACPI_FAILURE(status)) |
338 | return -EINVAL; | 352 | return -EINVAL; |
@@ -354,3 +368,12 @@ static int __init acpi_parse_apic_instance(char *str) | |||
354 | } | 368 | } |
355 | 369 | ||
356 | early_param("acpi_apic_instance", acpi_parse_apic_instance); | 370 | early_param("acpi_apic_instance", acpi_parse_apic_instance); |
371 | |||
372 | static int __init acpi_force_table_verification_setup(char *s) | ||
373 | { | ||
374 | acpi_verify_table_checksum = true; | ||
375 | |||
376 | return 0; | ||
377 | } | ||
378 | |||
379 | early_param("acpi_force_table_verification", acpi_force_table_verification_setup); | ||
diff --git a/drivers/char/tpm/tpm_acpi.c b/drivers/char/tpm/tpm_acpi.c index b9a57fa4b710..565a9478cb94 100644 --- a/drivers/char/tpm/tpm_acpi.c +++ b/drivers/char/tpm/tpm_acpi.c | |||
@@ -95,7 +95,7 @@ int read_log(struct tpm_bios_log *log) | |||
95 | 95 | ||
96 | log->bios_event_log_end = log->bios_event_log + len; | 96 | log->bios_event_log_end = log->bios_event_log + len; |
97 | 97 | ||
98 | virt = acpi_os_map_memory(start, len); | 98 | virt = acpi_os_map_iomem(start, len); |
99 | if (!virt) { | 99 | if (!virt) { |
100 | kfree(log->bios_event_log); | 100 | kfree(log->bios_event_log); |
101 | printk("%s: ERROR - Unable to map memory\n", __func__); | 101 | printk("%s: ERROR - Unable to map memory\n", __func__); |
@@ -104,6 +104,6 @@ int read_log(struct tpm_bios_log *log) | |||
104 | 104 | ||
105 | memcpy_fromio(log->bios_event_log, virt, len); | 105 | memcpy_fromio(log->bios_event_log, virt, len); |
106 | 106 | ||
107 | acpi_os_unmap_memory(virt, len); | 107 | acpi_os_unmap_iomem(virt, len); |
108 | return 0; | 108 | return 0; |
109 | } | 109 | } |
diff --git a/include/acpi/acpi.h b/include/acpi/acpi.h index ca0cb603b171..a08e55a263c9 100644 --- a/include/acpi/acpi.h +++ b/include/acpi/acpi.h | |||
@@ -62,8 +62,6 @@ | |||
62 | #include <acpi/acrestyp.h> /* Resource Descriptor structs */ | 62 | #include <acpi/acrestyp.h> /* Resource Descriptor structs */ |
63 | #include <acpi/acpiosxf.h> /* OSL interfaces (ACPICA-to-OS) */ | 63 | #include <acpi/acpiosxf.h> /* OSL interfaces (ACPICA-to-OS) */ |
64 | #include <acpi/acpixf.h> /* ACPI core subsystem external interfaces */ | 64 | #include <acpi/acpixf.h> /* ACPI core subsystem external interfaces */ |
65 | #ifdef ACPI_NATIVE_INTERFACE_HEADER | 65 | #include <acpi/platform/acenvex.h> /* Extra environment-specific items */ |
66 | #include ACPI_NATIVE_INTERFACE_HEADER | ||
67 | #endif | ||
68 | 66 | ||
69 | #endif /* __ACPI_H__ */ | 67 | #endif /* __ACPI_H__ */ |
diff --git a/include/acpi/acpi_io.h b/include/acpi/acpi_io.h index 2be858018c7f..444671e9c65d 100644 --- a/include/acpi/acpi_io.h +++ b/include/acpi/acpi_io.h | |||
@@ -9,6 +9,9 @@ static inline void __iomem *acpi_os_ioremap(acpi_physical_address phys, | |||
9 | return ioremap_cache(phys, size); | 9 | return ioremap_cache(phys, size); |
10 | } | 10 | } |
11 | 11 | ||
12 | void __iomem *__init_refok | ||
13 | acpi_os_map_iomem(acpi_physical_address phys, acpi_size size); | ||
14 | void __ref acpi_os_unmap_iomem(void __iomem *virt, acpi_size size); | ||
12 | void __iomem *acpi_os_get_iomem(acpi_physical_address phys, unsigned int size); | 15 | void __iomem *acpi_os_get_iomem(acpi_physical_address phys, unsigned int size); |
13 | 16 | ||
14 | int acpi_os_map_generic_address(struct acpi_generic_address *addr); | 17 | int acpi_os_map_generic_address(struct acpi_generic_address *addr); |
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 44f5e9749601..35b525c19711 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h | |||
@@ -46,7 +46,7 @@ | |||
46 | 46 | ||
47 | /* Current ACPICA subsystem version in YYYYMMDD format */ | 47 | /* Current ACPICA subsystem version in YYYYMMDD format */ |
48 | 48 | ||
49 | #define ACPI_CA_VERSION 0x20140214 | 49 | #define ACPI_CA_VERSION 0x20140424 |
50 | 50 | ||
51 | #include <acpi/acconfig.h> | 51 | #include <acpi/acconfig.h> |
52 | #include <acpi/actypes.h> | 52 | #include <acpi/actypes.h> |
@@ -55,233 +55,478 @@ | |||
55 | 55 | ||
56 | extern u8 acpi_gbl_permanent_mmap; | 56 | extern u8 acpi_gbl_permanent_mmap; |
57 | 57 | ||
58 | /***************************************************************************** | ||
59 | * | ||
60 | * Macros used for ACPICA globals and configuration | ||
61 | * | ||
62 | ****************************************************************************/ | ||
63 | |||
58 | /* | 64 | /* |
59 | * Globals that are publically available | 65 | * Ensure that global variables are defined and initialized only once. |
66 | * | ||
67 | * The use of these macros allows for a single list of globals (here) | ||
68 | * in order to simplify maintenance of the code. | ||
60 | */ | 69 | */ |
61 | extern u32 acpi_current_gpe_count; | 70 | #ifdef DEFINE_ACPI_GLOBALS |
62 | extern struct acpi_table_fadt acpi_gbl_FADT; | 71 | #define ACPI_GLOBAL(type,name) \ |
63 | extern u8 acpi_gbl_system_awake_and_running; | 72 | extern type name; \ |
64 | extern u8 acpi_gbl_reduced_hardware; /* ACPI 5.0 */ | 73 | type name |
65 | extern u8 acpi_gbl_osi_data; | ||
66 | 74 | ||
67 | /* Runtime configuration of debug print levels */ | 75 | #define ACPI_INIT_GLOBAL(type,name,value) \ |
76 | type name=value | ||
68 | 77 | ||
69 | extern u32 acpi_dbg_level; | 78 | #else |
70 | extern u32 acpi_dbg_layer; | 79 | #ifndef ACPI_GLOBAL |
71 | 80 | #define ACPI_GLOBAL(type,name) \ | |
72 | /* ACPICA runtime options */ | 81 | extern type name |
82 | #endif | ||
73 | 83 | ||
74 | extern u8 acpi_gbl_auto_serialize_methods; | 84 | #ifndef ACPI_INIT_GLOBAL |
75 | extern u8 acpi_gbl_copy_dsdt_locally; | 85 | #define ACPI_INIT_GLOBAL(type,name,value) \ |
76 | extern u8 acpi_gbl_create_osi_method; | 86 | extern type name |
77 | extern u8 acpi_gbl_disable_auto_repair; | 87 | #endif |
78 | extern u8 acpi_gbl_disable_ssdt_table_load; | 88 | #endif |
79 | extern u8 acpi_gbl_do_not_use_xsdt; | ||
80 | extern u8 acpi_gbl_enable_aml_debug_object; | ||
81 | extern u8 acpi_gbl_enable_interpreter_slack; | ||
82 | extern u32 acpi_gbl_trace_flags; | ||
83 | extern acpi_name acpi_gbl_trace_method_name; | ||
84 | extern u8 acpi_gbl_truncate_io_addresses; | ||
85 | extern u8 acpi_gbl_use32_bit_fadt_addresses; | ||
86 | extern u8 acpi_gbl_use_default_register_widths; | ||
87 | 89 | ||
88 | /* | 90 | /* |
89 | * Hardware-reduced prototypes. All interfaces that use these macros will | 91 | * These macros configure the various ACPICA interfaces. They are |
90 | * be configured out of the ACPICA build if the ACPI_REDUCED_HARDWARE flag | 92 | * useful for generating stub inline functions for features that are |
91 | * is set to TRUE. | 93 | * configured out of the current kernel or ACPICA application. |
92 | */ | 94 | */ |
93 | #if (!ACPI_REDUCED_HARDWARE) | 95 | #ifndef ACPI_EXTERNAL_RETURN_STATUS |
94 | #define ACPI_HW_DEPENDENT_RETURN_STATUS(prototype) \ | 96 | #define ACPI_EXTERNAL_RETURN_STATUS(prototype) \ |
95 | prototype; | 97 | prototype; |
98 | #endif | ||
96 | 99 | ||
97 | #define ACPI_HW_DEPENDENT_RETURN_OK(prototype) \ | 100 | #ifndef ACPI_EXTERNAL_RETURN_OK |
101 | #define ACPI_EXTERNAL_RETURN_OK(prototype) \ | ||
98 | prototype; | 102 | prototype; |
103 | #endif | ||
99 | 104 | ||
100 | #define ACPI_HW_DEPENDENT_RETURN_VOID(prototype) \ | 105 | #ifndef ACPI_EXTERNAL_RETURN_VOID |
106 | #define ACPI_EXTERNAL_RETURN_VOID(prototype) \ | ||
101 | prototype; | 107 | prototype; |
108 | #endif | ||
102 | 109 | ||
103 | #else | 110 | #ifndef ACPI_EXTERNAL_RETURN_UINT32 |
104 | #define ACPI_HW_DEPENDENT_RETURN_STATUS(prototype) \ | 111 | #define ACPI_EXTERNAL_RETURN_UINT32(prototype) \ |
105 | static ACPI_INLINE prototype {return(AE_NOT_CONFIGURED);} | 112 | prototype; |
106 | 113 | #endif | |
107 | #define ACPI_HW_DEPENDENT_RETURN_OK(prototype) \ | ||
108 | static ACPI_INLINE prototype {return(AE_OK);} | ||
109 | 114 | ||
110 | #define ACPI_HW_DEPENDENT_RETURN_VOID(prototype) \ | 115 | #ifndef ACPI_EXTERNAL_RETURN_PTR |
111 | static ACPI_INLINE prototype {return;} | 116 | #define ACPI_EXTERNAL_RETURN_PTR(prototype) \ |
117 | prototype; | ||
118 | #endif | ||
112 | 119 | ||
113 | #endif /* !ACPI_REDUCED_HARDWARE */ | 120 | /***************************************************************************** |
121 | * | ||
122 | * Public globals and runtime configuration options | ||
123 | * | ||
124 | ****************************************************************************/ | ||
114 | 125 | ||
115 | /* | 126 | /* |
116 | * Initialization | 127 | * Enable "slack mode" of the AML interpreter? Default is FALSE, and the |
128 | * interpreter strictly follows the ACPI specification. Setting to TRUE | ||
129 | * allows the interpreter to ignore certain errors and/or bad AML constructs. | ||
130 | * | ||
131 | * Currently, these features are enabled by this flag: | ||
132 | * | ||
133 | * 1) Allow "implicit return" of last value in a control method | ||
134 | * 2) Allow access beyond the end of an operation region | ||
135 | * 3) Allow access to uninitialized locals/args (auto-init to integer 0) | ||
136 | * 4) Allow ANY object type to be a source operand for the Store() operator | ||
137 | * 5) Allow unresolved references (invalid target name) in package objects | ||
138 | * 6) Enable warning messages for behavior that is not ACPI spec compliant | ||
117 | */ | 139 | */ |
118 | acpi_status __init | 140 | ACPI_INIT_GLOBAL(u8, acpi_gbl_enable_interpreter_slack, FALSE); |
119 | acpi_initialize_tables(struct acpi_table_desc *initial_storage, | ||
120 | u32 initial_table_count, u8 allow_resize); | ||
121 | |||
122 | acpi_status __init acpi_initialize_subsystem(void); | ||
123 | 141 | ||
124 | acpi_status __init acpi_enable_subsystem(u32 flags); | 142 | /* |
125 | 143 | * Automatically serialize all methods that create named objects? Default | |
126 | acpi_status __init acpi_initialize_objects(u32 flags); | 144 | * is TRUE, meaning that all non_serialized methods are scanned once at |
145 | * table load time to determine those that create named objects. Methods | ||
146 | * that create named objects are marked Serialized in order to prevent | ||
147 | * possible run-time problems if they are entered by more than one thread. | ||
148 | */ | ||
149 | ACPI_INIT_GLOBAL(u8, acpi_gbl_auto_serialize_methods, TRUE); | ||
127 | 150 | ||
128 | acpi_status __init acpi_terminate(void); | 151 | /* |
152 | * Create the predefined _OSI method in the namespace? Default is TRUE | ||
153 | * because ACPICA is fully compatible with other ACPI implementations. | ||
154 | * Changing this will revert ACPICA (and machine ASL) to pre-OSI behavior. | ||
155 | */ | ||
156 | ACPI_INIT_GLOBAL(u8, acpi_gbl_create_osi_method, TRUE); | ||
129 | 157 | ||
130 | /* | 158 | /* |
131 | * Miscellaneous global interfaces | 159 | * Optionally use default values for the ACPI register widths. Set this to |
160 | * TRUE to use the defaults, if an FADT contains incorrect widths/lengths. | ||
132 | */ | 161 | */ |
133 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_enable(void)) | 162 | ACPI_INIT_GLOBAL(u8, acpi_gbl_use_default_register_widths, TRUE); |
134 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_disable(void)) | ||
135 | #ifdef ACPI_FUTURE_USAGE | ||
136 | acpi_status acpi_subsystem_status(void); | ||
137 | #endif | ||
138 | 163 | ||
139 | #ifdef ACPI_FUTURE_USAGE | 164 | /* |
140 | acpi_status acpi_get_system_info(struct acpi_buffer *ret_buffer); | 165 | * Whether or not to verify the table checksum before installation. Set |
141 | #endif | 166 | * this to TRUE to verify the table checksum before install it to the table |
167 | * manager. Note that enabling this option causes errors to happen in some | ||
168 | * OSPMs during early initialization stages. Default behavior is to do such | ||
169 | * verification. | ||
170 | */ | ||
171 | ACPI_INIT_GLOBAL(u8, acpi_gbl_verify_table_checksum, TRUE); | ||
142 | 172 | ||
143 | acpi_status acpi_get_statistics(struct acpi_statistics *stats); | 173 | /* |
174 | * Optionally enable output from the AML Debug Object. | ||
175 | */ | ||
176 | ACPI_INIT_GLOBAL(u8, acpi_gbl_enable_aml_debug_object, FALSE); | ||
144 | 177 | ||
145 | const char *acpi_format_exception(acpi_status exception); | 178 | /* |
179 | * Optionally copy the entire DSDT to local memory (instead of simply | ||
180 | * mapping it.) There are some BIOSs that corrupt or replace the original | ||
181 | * DSDT, creating the need for this option. Default is FALSE, do not copy | ||
182 | * the DSDT. | ||
183 | */ | ||
184 | ACPI_INIT_GLOBAL(u8, acpi_gbl_copy_dsdt_locally, FALSE); | ||
146 | 185 | ||
147 | acpi_status acpi_purge_cached_objects(void); | 186 | /* |
187 | * Optionally ignore an XSDT if present and use the RSDT instead. | ||
188 | * Although the ACPI specification requires that an XSDT be used instead | ||
189 | * of the RSDT, the XSDT has been found to be corrupt or ill-formed on | ||
190 | * some machines. Default behavior is to use the XSDT if present. | ||
191 | */ | ||
192 | ACPI_INIT_GLOBAL(u8, acpi_gbl_do_not_use_xsdt, FALSE); | ||
148 | 193 | ||
149 | acpi_status acpi_install_interface(acpi_string interface_name); | 194 | /* |
195 | * Optionally use 32-bit FADT addresses if and when there is a conflict | ||
196 | * (address mismatch) between the 32-bit and 64-bit versions of the | ||
197 | * address. Although ACPICA adheres to the ACPI specification which | ||
198 | * requires the use of the corresponding 64-bit address if it is non-zero, | ||
199 | * some machines have been found to have a corrupted non-zero 64-bit | ||
200 | * address. Default is TRUE, favor the 32-bit addresses. | ||
201 | */ | ||
202 | ACPI_INIT_GLOBAL(u8, acpi_gbl_use32_bit_fadt_addresses, TRUE); | ||
150 | 203 | ||
151 | acpi_status acpi_remove_interface(acpi_string interface_name); | 204 | /* |
205 | * Optionally truncate I/O addresses to 16 bits. Provides compatibility | ||
206 | * with other ACPI implementations. NOTE: During ACPICA initialization, | ||
207 | * this value is set to TRUE if any Windows OSI strings have been | ||
208 | * requested by the BIOS. | ||
209 | */ | ||
210 | ACPI_INIT_GLOBAL(u8, acpi_gbl_truncate_io_addresses, FALSE); | ||
152 | 211 | ||
153 | acpi_status acpi_update_interfaces(u8 action); | 212 | /* |
213 | * Disable runtime checking and repair of values returned by control methods. | ||
214 | * Use only if the repair is causing a problem on a particular machine. | ||
215 | */ | ||
216 | ACPI_INIT_GLOBAL(u8, acpi_gbl_disable_auto_repair, FALSE); | ||
154 | 217 | ||
155 | u32 | 218 | /* |
156 | acpi_check_address_range(acpi_adr_space_type space_id, | 219 | * Optionally do not install any SSDTs from the RSDT/XSDT during initialization. |
157 | acpi_physical_address address, | 220 | * This can be useful for debugging ACPI problems on some machines. |
158 | acpi_size length, u8 warn); | 221 | */ |
222 | ACPI_INIT_GLOBAL(u8, acpi_gbl_disable_ssdt_table_install, FALSE); | ||
159 | 223 | ||
160 | acpi_status | 224 | /* |
161 | acpi_decode_pld_buffer(u8 *in_buffer, | 225 | * We keep track of the latest version of Windows that has been requested by |
162 | acpi_size length, struct acpi_pld_info **return_buffer); | 226 | * the BIOS. ACPI 5.0. |
227 | */ | ||
228 | ACPI_INIT_GLOBAL(u8, acpi_gbl_osi_data, 0); | ||
163 | 229 | ||
164 | /* | 230 | /* |
165 | * ACPI table load/unload interfaces | 231 | * ACPI 5.0 introduces the concept of a "reduced hardware platform", meaning |
232 | * that the ACPI hardware is no longer required. A flag in the FADT indicates | ||
233 | * a reduced HW machine, and that flag is duplicated here for convenience. | ||
166 | */ | 234 | */ |
167 | acpi_status acpi_load_table(struct acpi_table_header *table); | 235 | ACPI_INIT_GLOBAL(u8, acpi_gbl_reduced_hardware, FALSE); |
168 | 236 | ||
169 | acpi_status acpi_unload_parent_table(acpi_handle object); | 237 | /* |
238 | * This mechanism is used to trace a specified AML method. The method is | ||
239 | * traced each time it is executed. | ||
240 | */ | ||
241 | ACPI_INIT_GLOBAL(u32, acpi_gbl_trace_flags, 0); | ||
242 | ACPI_INIT_GLOBAL(acpi_name, acpi_gbl_trace_method_name, 0); | ||
170 | 243 | ||
171 | acpi_status __init acpi_load_tables(void); | 244 | /* |
245 | * Runtime configuration of debug output control masks. We want the debug | ||
246 | * switches statically initialized so they are already set when the debugger | ||
247 | * is entered. | ||
248 | */ | ||
249 | ACPI_INIT_GLOBAL(u32, acpi_dbg_level, ACPI_DEBUG_DEFAULT); | ||
250 | ACPI_INIT_GLOBAL(u32, acpi_dbg_layer, 0); | ||
172 | 251 | ||
173 | /* | 252 | /* |
174 | * ACPI table manipulation interfaces | 253 | * Other miscellaneous globals |
175 | */ | 254 | */ |
176 | acpi_status __init acpi_reallocate_root_table(void); | 255 | ACPI_GLOBAL(struct acpi_table_fadt, acpi_gbl_FADT); |
256 | ACPI_GLOBAL(u32, acpi_current_gpe_count); | ||
257 | ACPI_GLOBAL(u8, acpi_gbl_system_awake_and_running); | ||
177 | 258 | ||
178 | acpi_status __init acpi_find_root_pointer(acpi_size *rsdp_address); | 259 | /***************************************************************************** |
260 | * | ||
261 | * ACPICA public interface configuration. | ||
262 | * | ||
263 | * Interfaces that are configured out of the ACPICA build are replaced | ||
264 | * by inlined stubs by default. | ||
265 | * | ||
266 | ****************************************************************************/ | ||
179 | 267 | ||
180 | acpi_status acpi_unload_table_id(acpi_owner_id id); | 268 | /* |
269 | * Hardware-reduced prototypes (default: Not hardware reduced). | ||
270 | * | ||
271 | * All ACPICA hardware-related interfaces that use these macros will be | ||
272 | * configured out of the ACPICA build if the ACPI_REDUCED_HARDWARE flag | ||
273 | * is set to TRUE. | ||
274 | * | ||
275 | * Note: This static build option for reduced hardware is intended to | ||
276 | * reduce ACPICA code size if desired or necessary. However, even if this | ||
277 | * option is not specified, the runtime behavior of ACPICA is dependent | ||
278 | * on the actual FADT reduced hardware flag (HW_REDUCED_ACPI). If set, | ||
279 | * the flag will enable similar behavior -- ACPICA will not attempt | ||
280 | * to access any ACPI-relate hardware (SCI, GPEs, Fixed Events, etc.) | ||
281 | */ | ||
282 | #if (!ACPI_REDUCED_HARDWARE) | ||
283 | #define ACPI_HW_DEPENDENT_RETURN_STATUS(prototype) \ | ||
284 | ACPI_EXTERNAL_RETURN_STATUS(prototype) | ||
181 | 285 | ||
182 | acpi_status | 286 | #define ACPI_HW_DEPENDENT_RETURN_OK(prototype) \ |
183 | acpi_get_table_header(acpi_string signature, | 287 | ACPI_EXTERNAL_RETURN_OK(prototype) |
184 | u32 instance, struct acpi_table_header *out_table_header); | ||
185 | 288 | ||
186 | acpi_status | 289 | #define ACPI_HW_DEPENDENT_RETURN_VOID(prototype) \ |
187 | acpi_get_table_with_size(acpi_string signature, | 290 | ACPI_EXTERNAL_RETURN_VOID(prototype) |
188 | u32 instance, struct acpi_table_header **out_table, | ||
189 | acpi_size *tbl_size); | ||
190 | 291 | ||
191 | acpi_status | 292 | #else |
192 | acpi_get_table(acpi_string signature, | 293 | #define ACPI_HW_DEPENDENT_RETURN_STATUS(prototype) \ |
193 | u32 instance, struct acpi_table_header **out_table); | 294 | static ACPI_INLINE prototype {return(AE_NOT_CONFIGURED);} |
194 | 295 | ||
195 | acpi_status | 296 | #define ACPI_HW_DEPENDENT_RETURN_OK(prototype) \ |
196 | acpi_get_table_by_index(u32 table_index, struct acpi_table_header **out_table); | 297 | static ACPI_INLINE prototype {return(AE_OK);} |
197 | 298 | ||
198 | acpi_status | 299 | #define ACPI_HW_DEPENDENT_RETURN_VOID(prototype) \ |
199 | acpi_install_table_handler(acpi_table_handler handler, void *context); | 300 | static ACPI_INLINE prototype {return;} |
200 | 301 | ||
201 | acpi_status acpi_remove_table_handler(acpi_table_handler handler); | 302 | #endif /* !ACPI_REDUCED_HARDWARE */ |
202 | 303 | ||
203 | /* | 304 | /* |
204 | * Namespace and name interfaces | 305 | * Error message prototypes (default: error messages enabled). |
306 | * | ||
307 | * All interfaces related to error and warning messages | ||
308 | * will be configured out of the ACPICA build if the | ||
309 | * ACPI_NO_ERROR_MESSAGE flag is defined. | ||
205 | */ | 310 | */ |
206 | acpi_status | 311 | #ifndef ACPI_NO_ERROR_MESSAGES |
207 | acpi_walk_namespace(acpi_object_type type, | 312 | #define ACPI_MSG_DEPENDENT_RETURN_VOID(prototype) \ |
208 | acpi_handle start_object, | 313 | prototype; |
209 | u32 max_depth, | ||
210 | acpi_walk_callback descending_callback, | ||
211 | acpi_walk_callback ascending_callback, | ||
212 | void *context, void **return_value); | ||
213 | 314 | ||
214 | acpi_status | 315 | #else |
215 | acpi_get_devices(const char *HID, | 316 | #define ACPI_MSG_DEPENDENT_RETURN_VOID(prototype) \ |
216 | acpi_walk_callback user_function, | 317 | static ACPI_INLINE prototype {return;} |
217 | void *context, void **return_value); | ||
218 | 318 | ||
219 | acpi_status | 319 | #endif /* ACPI_NO_ERROR_MESSAGES */ |
220 | acpi_get_name(acpi_handle object, | ||
221 | u32 name_type, struct acpi_buffer *ret_path_ptr); | ||
222 | 320 | ||
223 | acpi_status | 321 | /* |
224 | acpi_get_handle(acpi_handle parent, | 322 | * Debugging output prototypes (default: no debug output). |
225 | acpi_string pathname, acpi_handle * ret_handle); | 323 | * |
324 | * All interfaces related to debug output messages | ||
325 | * will be configured out of the ACPICA build unless the | ||
326 | * ACPI_DEBUG_OUTPUT flag is defined. | ||
327 | */ | ||
328 | #ifdef ACPI_DEBUG_OUTPUT | ||
329 | #define ACPI_DBG_DEPENDENT_RETURN_VOID(prototype) \ | ||
330 | prototype; | ||
226 | 331 | ||
227 | acpi_status | 332 | #else |
228 | acpi_attach_data(acpi_handle object, acpi_object_handler handler, void *data); | 333 | #define ACPI_DBG_DEPENDENT_RETURN_VOID(prototype) \ |
334 | static ACPI_INLINE prototype {return;} | ||
229 | 335 | ||
230 | acpi_status acpi_detach_data(acpi_handle object, acpi_object_handler handler); | 336 | #endif /* ACPI_DEBUG_OUTPUT */ |
231 | 337 | ||
232 | acpi_status | 338 | /***************************************************************************** |
233 | acpi_get_data_full(acpi_handle object, acpi_object_handler handler, void **data, | 339 | * |
234 | void (*callback)(void *)); | 340 | * ACPICA public interface prototypes |
341 | * | ||
342 | ****************************************************************************/ | ||
235 | 343 | ||
236 | acpi_status | 344 | /* |
237 | acpi_get_data(acpi_handle object, acpi_object_handler handler, void **data); | 345 | * Initialization |
346 | */ | ||
347 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status __init | ||
348 | acpi_initialize_tables(struct acpi_table_desc | ||
349 | *initial_storage, | ||
350 | u32 initial_table_count, | ||
351 | u8 allow_resize)) | ||
352 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status __init acpi_initialize_subsystem(void)) | ||
238 | 353 | ||
239 | acpi_status | 354 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status __init acpi_enable_subsystem(u32 flags)) |
240 | acpi_debug_trace(char *name, u32 debug_level, u32 debug_layer, u32 flags); | 355 | |
356 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status __init | ||
357 | acpi_initialize_objects(u32 flags)) | ||
358 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status __init acpi_terminate(void)) | ||
241 | 359 | ||
242 | /* | 360 | /* |
243 | * Object manipulation and enumeration | 361 | * Miscellaneous global interfaces |
244 | */ | 362 | */ |
245 | acpi_status | 363 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_enable(void)) |
246 | acpi_evaluate_object(acpi_handle object, | 364 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_disable(void)) |
247 | acpi_string pathname, | 365 | #ifdef ACPI_FUTURE_USAGE |
248 | struct acpi_object_list *parameter_objects, | 366 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status acpi_subsystem_status(void)) |
249 | struct acpi_buffer *return_object_buffer); | 367 | #endif |
250 | 368 | ||
251 | acpi_status | 369 | #ifdef ACPI_FUTURE_USAGE |
252 | acpi_evaluate_object_typed(acpi_handle object, | 370 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status |
253 | acpi_string pathname, | 371 | acpi_get_system_info(struct acpi_buffer |
254 | struct acpi_object_list *external_params, | 372 | *ret_buffer)) |
255 | struct acpi_buffer *return_buffer, | 373 | #endif |
256 | acpi_object_type return_type); | 374 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status |
375 | acpi_get_statistics(struct acpi_statistics *stats)) | ||
376 | ACPI_EXTERNAL_RETURN_PTR(const char | ||
377 | *acpi_format_exception(acpi_status exception)) | ||
378 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status acpi_purge_cached_objects(void)) | ||
379 | |||
380 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status | ||
381 | acpi_install_interface(acpi_string interface_name)) | ||
382 | |||
383 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status | ||
384 | acpi_remove_interface(acpi_string interface_name)) | ||
385 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status acpi_update_interfaces(u8 action)) | ||
386 | |||
387 | ACPI_EXTERNAL_RETURN_UINT32(u32 | ||
388 | acpi_check_address_range(acpi_adr_space_type | ||
389 | space_id, | ||
390 | acpi_physical_address | ||
391 | address, acpi_size length, | ||
392 | u8 warn)) | ||
393 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status | ||
394 | acpi_decode_pld_buffer(u8 *in_buffer, | ||
395 | acpi_size length, | ||
396 | struct acpi_pld_info | ||
397 | **return_buffer)) | ||
257 | 398 | ||
258 | acpi_status | 399 | /* |
259 | acpi_get_object_info(acpi_handle object, | 400 | * ACPI table load/unload interfaces |
260 | struct acpi_device_info **return_buffer); | 401 | */ |
402 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status __init | ||
403 | acpi_install_table(acpi_physical_address address, | ||
404 | u8 physical)) | ||
261 | 405 | ||
262 | acpi_status acpi_install_method(u8 *buffer); | 406 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status |
407 | acpi_load_table(struct acpi_table_header *table)) | ||
263 | 408 | ||
264 | acpi_status | 409 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status |
265 | acpi_get_next_object(acpi_object_type type, | 410 | acpi_unload_parent_table(acpi_handle object)) |
266 | acpi_handle parent, | 411 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status __init acpi_load_tables(void)) |
267 | acpi_handle child, acpi_handle * out_handle); | ||
268 | 412 | ||
269 | acpi_status acpi_get_type(acpi_handle object, acpi_object_type * out_type); | 413 | /* |
414 | * ACPI table manipulation interfaces | ||
415 | */ | ||
416 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status __init acpi_reallocate_root_table(void)) | ||
417 | |||
418 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status __init | ||
419 | acpi_find_root_pointer(acpi_size * rsdp_address)) | ||
420 | |||
421 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status | ||
422 | acpi_get_table_header(acpi_string signature, | ||
423 | u32 instance, | ||
424 | struct acpi_table_header | ||
425 | *out_table_header)) | ||
426 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status | ||
427 | acpi_get_table(acpi_string signature, u32 instance, | ||
428 | struct acpi_table_header | ||
429 | **out_table)) | ||
430 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status | ||
431 | acpi_get_table_by_index(u32 table_index, | ||
432 | struct acpi_table_header | ||
433 | **out_table)) | ||
434 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status | ||
435 | acpi_install_table_handler(acpi_table_handler | ||
436 | handler, void *context)) | ||
437 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status | ||
438 | acpi_remove_table_handler(acpi_table_handler | ||
439 | handler)) | ||
270 | 440 | ||
271 | acpi_status acpi_get_id(acpi_handle object, acpi_owner_id * out_type); | 441 | /* |
442 | * Namespace and name interfaces | ||
443 | */ | ||
444 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status | ||
445 | acpi_walk_namespace(acpi_object_type type, | ||
446 | acpi_handle start_object, | ||
447 | u32 max_depth, | ||
448 | acpi_walk_callback | ||
449 | descending_callback, | ||
450 | acpi_walk_callback | ||
451 | ascending_callback, | ||
452 | void *context, | ||
453 | void **return_value)) | ||
454 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status | ||
455 | acpi_get_devices(const char *HID, | ||
456 | acpi_walk_callback user_function, | ||
457 | void *context, | ||
458 | void **return_value)) | ||
459 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status | ||
460 | acpi_get_name(acpi_handle object, u32 name_type, | ||
461 | struct acpi_buffer *ret_path_ptr)) | ||
462 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status | ||
463 | acpi_get_handle(acpi_handle parent, | ||
464 | acpi_string pathname, | ||
465 | acpi_handle * ret_handle)) | ||
466 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status | ||
467 | acpi_attach_data(acpi_handle object, | ||
468 | acpi_object_handler handler, | ||
469 | void *data)) | ||
470 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status | ||
471 | acpi_detach_data(acpi_handle object, | ||
472 | acpi_object_handler handler)) | ||
473 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status | ||
474 | acpi_get_data(acpi_handle object, | ||
475 | acpi_object_handler handler, | ||
476 | void **data)) | ||
477 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status | ||
478 | acpi_debug_trace(char *name, u32 debug_level, | ||
479 | u32 debug_layer, u32 flags)) | ||
272 | 480 | ||
273 | acpi_status acpi_get_parent(acpi_handle object, acpi_handle * out_handle); | 481 | /* |
482 | * Object manipulation and enumeration | ||
483 | */ | ||
484 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status | ||
485 | acpi_evaluate_object(acpi_handle object, | ||
486 | acpi_string pathname, | ||
487 | struct acpi_object_list | ||
488 | *parameter_objects, | ||
489 | struct acpi_buffer | ||
490 | *return_object_buffer)) | ||
491 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status | ||
492 | acpi_evaluate_object_typed(acpi_handle object, | ||
493 | acpi_string pathname, | ||
494 | struct acpi_object_list | ||
495 | *external_params, | ||
496 | struct acpi_buffer | ||
497 | *return_buffer, | ||
498 | acpi_object_type | ||
499 | return_type)) | ||
500 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status | ||
501 | acpi_get_object_info(acpi_handle object, | ||
502 | struct acpi_device_info | ||
503 | **return_buffer)) | ||
504 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status acpi_install_method(u8 *buffer)) | ||
505 | |||
506 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status | ||
507 | acpi_get_next_object(acpi_object_type type, | ||
508 | acpi_handle parent, | ||
509 | acpi_handle child, | ||
510 | acpi_handle * out_handle)) | ||
511 | |||
512 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status | ||
513 | acpi_get_type(acpi_handle object, | ||
514 | acpi_object_type * out_type)) | ||
515 | |||
516 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status | ||
517 | acpi_get_parent(acpi_handle object, | ||
518 | acpi_handle * out_handle)) | ||
274 | 519 | ||
275 | /* | 520 | /* |
276 | * Handler interfaces | 521 | * Handler interfaces |
277 | */ | 522 | */ |
278 | acpi_status | 523 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status |
279 | acpi_install_initialization_handler(acpi_init_handler handler, u32 function); | 524 | acpi_install_initialization_handler |
280 | 525 | (acpi_init_handler handler, u32 function)) | |
281 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | 526 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status |
282 | acpi_install_sci_handler(acpi_sci_handler | 527 | acpi_install_sci_handler(acpi_sci_handler |
283 | address, | 528 | address, |
284 | void *context)) | 529 | void *context)) |
285 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | 530 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status |
286 | acpi_remove_sci_handler(acpi_sci_handler | 531 | acpi_remove_sci_handler(acpi_sci_handler |
287 | address)) | 532 | address)) |
@@ -313,30 +558,42 @@ ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | |||
313 | u32 gpe_number, | 558 | u32 gpe_number, |
314 | acpi_gpe_handler | 559 | acpi_gpe_handler |
315 | address)) | 560 | address)) |
316 | acpi_status acpi_install_notify_handler(acpi_handle device, u32 handler_type, | 561 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status |
317 | acpi_notify_handler handler, | 562 | acpi_install_notify_handler(acpi_handle device, |
318 | void *context); | 563 | u32 handler_type, |
319 | 564 | acpi_notify_handler | |
320 | acpi_status | 565 | handler, |
321 | acpi_remove_notify_handler(acpi_handle device, | 566 | void *context)) |
322 | u32 handler_type, acpi_notify_handler handler); | 567 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status |
323 | 568 | acpi_remove_notify_handler(acpi_handle device, | |
324 | acpi_status | 569 | u32 handler_type, |
325 | acpi_install_address_space_handler(acpi_handle device, | 570 | acpi_notify_handler |
326 | acpi_adr_space_type space_id, | 571 | handler)) |
327 | acpi_adr_space_handler handler, | 572 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status |
328 | acpi_adr_space_setup setup, void *context); | 573 | acpi_install_address_space_handler(acpi_handle |
329 | 574 | device, | |
330 | acpi_status | 575 | acpi_adr_space_type |
331 | acpi_remove_address_space_handler(acpi_handle device, | 576 | space_id, |
332 | acpi_adr_space_type space_id, | 577 | acpi_adr_space_handler |
333 | acpi_adr_space_handler handler); | 578 | handler, |
334 | 579 | acpi_adr_space_setup | |
580 | setup, | ||
581 | void *context)) | ||
582 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status | ||
583 | acpi_remove_address_space_handler(acpi_handle | ||
584 | device, | ||
585 | acpi_adr_space_type | ||
586 | space_id, | ||
587 | acpi_adr_space_handler | ||
588 | handler)) | ||
335 | #ifdef ACPI_FUTURE_USAGE | 589 | #ifdef ACPI_FUTURE_USAGE |
336 | acpi_status acpi_install_exception_handler(acpi_exception_handler handler); | 590 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status |
591 | acpi_install_exception_handler | ||
592 | (acpi_exception_handler handler)) | ||
337 | #endif | 593 | #endif |
338 | 594 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status | |
339 | acpi_status acpi_install_interface_handler(acpi_interface_handler handler); | 595 | acpi_install_interface_handler |
596 | (acpi_interface_handler handler)) | ||
340 | 597 | ||
341 | /* | 598 | /* |
342 | * Global Lock interfaces | 599 | * Global Lock interfaces |
@@ -351,10 +608,14 @@ ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | |||
351 | /* | 608 | /* |
352 | * Interfaces to AML mutex objects | 609 | * Interfaces to AML mutex objects |
353 | */ | 610 | */ |
354 | acpi_status | 611 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status |
355 | acpi_acquire_mutex(acpi_handle handle, acpi_string pathname, u16 timeout); | 612 | acpi_acquire_mutex(acpi_handle handle, |
613 | acpi_string pathname, | ||
614 | u16 timeout)) | ||
356 | 615 | ||
357 | acpi_status acpi_release_mutex(acpi_handle handle, acpi_string pathname); | 616 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status |
617 | acpi_release_mutex(acpi_handle handle, | ||
618 | acpi_string pathname)) | ||
358 | 619 | ||
359 | /* | 620 | /* |
360 | * Fixed Event interfaces | 621 | * Fixed Event interfaces |
@@ -434,57 +695,69 @@ typedef | |||
434 | acpi_status(*acpi_walk_resource_callback) (struct acpi_resource * resource, | 695 | acpi_status(*acpi_walk_resource_callback) (struct acpi_resource * resource, |
435 | void *context); | 696 | void *context); |
436 | 697 | ||
437 | acpi_status | 698 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status |
438 | acpi_get_vendor_resource(acpi_handle device, | 699 | acpi_get_vendor_resource(acpi_handle device, |
439 | char *name, | 700 | char *name, |
440 | struct acpi_vendor_uuid *uuid, | 701 | struct acpi_vendor_uuid |
441 | struct acpi_buffer *ret_buffer); | 702 | *uuid, |
442 | 703 | struct acpi_buffer | |
443 | acpi_status | 704 | *ret_buffer)) |
444 | acpi_get_current_resources(acpi_handle device, struct acpi_buffer *ret_buffer); | 705 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status |
445 | 706 | acpi_get_current_resources(acpi_handle device, | |
707 | struct acpi_buffer | ||
708 | *ret_buffer)) | ||
446 | #ifdef ACPI_FUTURE_USAGE | 709 | #ifdef ACPI_FUTURE_USAGE |
447 | acpi_status | 710 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status |
448 | acpi_get_possible_resources(acpi_handle device, struct acpi_buffer *ret_buffer); | 711 | acpi_get_possible_resources(acpi_handle device, |
712 | struct acpi_buffer | ||
713 | *ret_buffer)) | ||
449 | #endif | 714 | #endif |
450 | 715 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status | |
451 | acpi_status | 716 | acpi_get_event_resources(acpi_handle device_handle, |
452 | acpi_get_event_resources(acpi_handle device_handle, | 717 | struct acpi_buffer |
453 | struct acpi_buffer *ret_buffer); | 718 | *ret_buffer)) |
454 | 719 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status | |
455 | acpi_status | 720 | acpi_walk_resource_buffer(struct acpi_buffer |
456 | acpi_walk_resource_buffer(struct acpi_buffer *buffer, | 721 | *buffer, |
457 | acpi_walk_resource_callback user_function, | 722 | acpi_walk_resource_callback |
458 | void *context); | 723 | user_function, |
459 | 724 | void *context)) | |
460 | acpi_status | 725 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status |
461 | acpi_walk_resources(acpi_handle device, | 726 | acpi_walk_resources(acpi_handle device, char *name, |
462 | char *name, | 727 | acpi_walk_resource_callback |
463 | acpi_walk_resource_callback user_function, void *context); | 728 | user_function, void *context)) |
464 | 729 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status | |
465 | acpi_status | 730 | acpi_set_current_resources(acpi_handle device, |
466 | acpi_set_current_resources(acpi_handle device, struct acpi_buffer *in_buffer); | 731 | struct acpi_buffer |
467 | 732 | *in_buffer)) | |
468 | acpi_status | 733 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status |
469 | acpi_get_irq_routing_table(acpi_handle device, struct acpi_buffer *ret_buffer); | 734 | acpi_get_irq_routing_table(acpi_handle device, |
470 | 735 | struct acpi_buffer | |
471 | acpi_status | 736 | *ret_buffer)) |
472 | acpi_resource_to_address64(struct acpi_resource *resource, | 737 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status |
473 | struct acpi_resource_address64 *out); | 738 | acpi_resource_to_address64(struct acpi_resource |
474 | 739 | *resource, | |
475 | acpi_status | 740 | struct |
476 | acpi_buffer_to_resource(u8 *aml_buffer, | 741 | acpi_resource_address64 |
477 | u16 aml_buffer_length, | 742 | *out)) |
478 | struct acpi_resource **resource_ptr); | 743 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status |
744 | acpi_buffer_to_resource(u8 *aml_buffer, | ||
745 | u16 aml_buffer_length, | ||
746 | struct acpi_resource | ||
747 | **resource_ptr)) | ||
479 | 748 | ||
480 | /* | 749 | /* |
481 | * Hardware (ACPI device) interfaces | 750 | * Hardware (ACPI device) interfaces |
482 | */ | 751 | */ |
483 | acpi_status acpi_reset(void); | 752 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status acpi_reset(void)) |
484 | 753 | ||
485 | acpi_status acpi_read(u64 *value, struct acpi_generic_address *reg); | 754 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status |
755 | acpi_read(u64 *value, | ||
756 | struct acpi_generic_address *reg)) | ||
486 | 757 | ||
487 | acpi_status acpi_write(u64 value, struct acpi_generic_address *reg); | 758 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status |
759 | acpi_write(u64 value, | ||
760 | struct acpi_generic_address *reg)) | ||
488 | 761 | ||
489 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | 762 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status |
490 | acpi_read_bit_register(u32 register_id, | 763 | acpi_read_bit_register(u32 register_id, |
@@ -497,18 +770,20 @@ ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | |||
497 | /* | 770 | /* |
498 | * Sleep/Wake interfaces | 771 | * Sleep/Wake interfaces |
499 | */ | 772 | */ |
500 | acpi_status | 773 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status |
501 | acpi_get_sleep_type_data(u8 sleep_state, u8 *slp_typ_a, u8 *slp_typ_b); | 774 | acpi_get_sleep_type_data(u8 sleep_state, |
502 | 775 | u8 *slp_typ_a, | |
503 | acpi_status acpi_enter_sleep_state_prep(u8 sleep_state); | 776 | u8 *slp_typ_b)) |
504 | 777 | ||
505 | acpi_status acpi_enter_sleep_state(u8 sleep_state); | 778 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status |
779 | acpi_enter_sleep_state_prep(u8 sleep_state)) | ||
780 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status acpi_enter_sleep_state(u8 sleep_state)) | ||
506 | 781 | ||
507 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_enter_sleep_state_s4bios(void)) | 782 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_enter_sleep_state_s4bios(void)) |
508 | 783 | ||
509 | acpi_status acpi_leave_sleep_state_prep(u8 sleep_state); | 784 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status |
510 | 785 | acpi_leave_sleep_state_prep(u8 sleep_state)) | |
511 | acpi_status acpi_leave_sleep_state(u8 sleep_state); | 786 | ACPI_EXTERNAL_RETURN_STATUS(acpi_status acpi_leave_sleep_state(u8 sleep_state)) |
512 | 787 | ||
513 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | 788 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status |
514 | acpi_set_firmware_waking_vector(u32 | 789 | acpi_set_firmware_waking_vector(u32 |
@@ -535,53 +810,72 @@ ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status | |||
535 | /* | 810 | /* |
536 | * Error/Warning output | 811 | * Error/Warning output |
537 | */ | 812 | */ |
538 | ACPI_PRINTF_LIKE(3) | 813 | ACPI_MSG_DEPENDENT_RETURN_VOID(ACPI_PRINTF_LIKE(3) |
539 | void ACPI_INTERNAL_VAR_XFACE | 814 | void ACPI_INTERNAL_VAR_XFACE |
540 | acpi_error(const char *module_name, u32 line_number, const char *format, ...); | 815 | acpi_error(const char *module_name, |
541 | 816 | u32 line_number, | |
542 | ACPI_PRINTF_LIKE(4) | 817 | const char *format, ...)) |
543 | void ACPI_INTERNAL_VAR_XFACE | 818 | ACPI_MSG_DEPENDENT_RETURN_VOID(ACPI_PRINTF_LIKE(4) |
544 | acpi_exception(const char *module_name, | 819 | void ACPI_INTERNAL_VAR_XFACE |
545 | u32 line_number, acpi_status status, const char *format, ...); | 820 | acpi_exception(const char *module_name, |
546 | 821 | u32 line_number, | |
547 | ACPI_PRINTF_LIKE(3) | 822 | acpi_status status, |
548 | void ACPI_INTERNAL_VAR_XFACE | 823 | const char *format, ...)) |
549 | acpi_warning(const char *module_name, u32 line_number, const char *format, ...); | 824 | ACPI_MSG_DEPENDENT_RETURN_VOID(ACPI_PRINTF_LIKE(3) |
550 | 825 | void ACPI_INTERNAL_VAR_XFACE | |
551 | ACPI_PRINTF_LIKE(3) | 826 | acpi_warning(const char *module_name, |
552 | void ACPI_INTERNAL_VAR_XFACE | 827 | u32 line_number, |
553 | acpi_info(const char *module_name, u32 line_number, const char *format, ...); | 828 | const char *format, ...)) |
554 | 829 | ACPI_MSG_DEPENDENT_RETURN_VOID(ACPI_PRINTF_LIKE(3) | |
555 | ACPI_PRINTF_LIKE(3) | 830 | void ACPI_INTERNAL_VAR_XFACE |
556 | void ACPI_INTERNAL_VAR_XFACE | 831 | acpi_info(const char *module_name, |
557 | acpi_bios_error(const char *module_name, | 832 | u32 line_number, |
558 | u32 line_number, const char *format, ...); | 833 | const char *format, ...)) |
559 | 834 | ACPI_MSG_DEPENDENT_RETURN_VOID(ACPI_PRINTF_LIKE(3) | |
560 | ACPI_PRINTF_LIKE(3) | 835 | void ACPI_INTERNAL_VAR_XFACE |
561 | void ACPI_INTERNAL_VAR_XFACE | 836 | acpi_bios_error(const char *module_name, |
562 | acpi_bios_warning(const char *module_name, | 837 | u32 line_number, |
563 | u32 line_number, const char *format, ...); | 838 | const char *format, ...)) |
839 | ACPI_MSG_DEPENDENT_RETURN_VOID(ACPI_PRINTF_LIKE(3) | ||
840 | void ACPI_INTERNAL_VAR_XFACE | ||
841 | acpi_bios_warning(const char *module_name, | ||
842 | u32 line_number, | ||
843 | const char *format, ...)) | ||
564 | 844 | ||
565 | /* | 845 | /* |
566 | * Debug output | 846 | * Debug output |
567 | */ | 847 | */ |
568 | #ifdef ACPI_DEBUG_OUTPUT | 848 | ACPI_DBG_DEPENDENT_RETURN_VOID(ACPI_PRINTF_LIKE(6) |
849 | void ACPI_INTERNAL_VAR_XFACE | ||
850 | acpi_debug_print(u32 requested_debug_level, | ||
851 | u32 line_number, | ||
852 | const char *function_name, | ||
853 | const char *module_name, | ||
854 | u32 component_id, | ||
855 | const char *format, ...)) | ||
856 | ACPI_DBG_DEPENDENT_RETURN_VOID(ACPI_PRINTF_LIKE(6) | ||
857 | void ACPI_INTERNAL_VAR_XFACE | ||
858 | acpi_debug_print_raw(u32 requested_debug_level, | ||
859 | u32 line_number, | ||
860 | const char *function_name, | ||
861 | const char *module_name, | ||
862 | u32 component_id, | ||
863 | const char *format, ...)) | ||
569 | 864 | ||
570 | ACPI_PRINTF_LIKE(6) | 865 | /* |
571 | void ACPI_INTERNAL_VAR_XFACE | 866 | * Divergences |
572 | acpi_debug_print(u32 requested_debug_level, | 867 | */ |
573 | u32 line_number, | 868 | acpi_status acpi_get_id(acpi_handle object, acpi_owner_id * out_type); |
574 | const char *function_name, | 869 | |
575 | const char *module_name, | 870 | acpi_status acpi_unload_table_id(acpi_owner_id id); |
576 | u32 component_id, const char *format, ...); | 871 | |
577 | 872 | acpi_status | |
578 | ACPI_PRINTF_LIKE(6) | 873 | acpi_get_table_with_size(acpi_string signature, |
579 | void ACPI_INTERNAL_VAR_XFACE | 874 | u32 instance, struct acpi_table_header **out_table, |
580 | acpi_debug_print_raw(u32 requested_debug_level, | 875 | acpi_size *tbl_size); |
581 | u32 line_number, | 876 | |
582 | const char *function_name, | 877 | acpi_status |
583 | const char *module_name, | 878 | acpi_get_data_full(acpi_handle object, acpi_object_handler handler, void **data, |
584 | u32 component_id, const char *format, ...); | 879 | void (*callback)(void *)); |
585 | #endif | ||
586 | 880 | ||
587 | #endif /* __ACXFACE_H__ */ | 881 | #endif /* __ACXFACE_H__ */ |
diff --git a/include/acpi/actbl.h b/include/acpi/actbl.h index 3b30e36b53b5..1cc7ef13c01a 100644 --- a/include/acpi/actbl.h +++ b/include/acpi/actbl.h | |||
@@ -367,12 +367,11 @@ struct acpi_table_desc { | |||
367 | 367 | ||
368 | /* Masks for Flags field above */ | 368 | /* Masks for Flags field above */ |
369 | 369 | ||
370 | #define ACPI_TABLE_ORIGIN_UNKNOWN (0) | 370 | #define ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL (0) /* Virtual address, external maintained */ |
371 | #define ACPI_TABLE_ORIGIN_MAPPED (1) | 371 | #define ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL (1) /* Physical address, internally mapped */ |
372 | #define ACPI_TABLE_ORIGIN_ALLOCATED (2) | 372 | #define ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL (2) /* Virtual address, internallly allocated */ |
373 | #define ACPI_TABLE_ORIGIN_OVERRIDE (4) | 373 | #define ACPI_TABLE_ORIGIN_MASK (3) |
374 | #define ACPI_TABLE_ORIGIN_MASK (7) | 374 | #define ACPI_TABLE_IS_LOADED (8) |
375 | #define ACPI_TABLE_IS_LOADED (8) | ||
376 | 375 | ||
377 | /* | 376 | /* |
378 | * Get the remaining ACPI tables | 377 | * Get the remaining ACPI tables |
diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h index 212c65de75df..4ad7da805180 100644 --- a/include/acpi/actbl1.h +++ b/include/acpi/actbl1.h | |||
@@ -675,7 +675,7 @@ enum acpi_madt_type { | |||
675 | }; | 675 | }; |
676 | 676 | ||
677 | /* | 677 | /* |
678 | * MADT Sub-tables, correspond to Type in struct acpi_subtable_header | 678 | * MADT Subtables, correspond to Type in struct acpi_subtable_header |
679 | */ | 679 | */ |
680 | 680 | ||
681 | /* 0: Processor Local APIC */ | 681 | /* 0: Processor Local APIC */ |
@@ -918,7 +918,7 @@ enum acpi_srat_type { | |||
918 | }; | 918 | }; |
919 | 919 | ||
920 | /* | 920 | /* |
921 | * SRAT Sub-tables, correspond to Type in struct acpi_subtable_header | 921 | * SRAT Subtables, correspond to Type in struct acpi_subtable_header |
922 | */ | 922 | */ |
923 | 923 | ||
924 | /* 0: Processor Local APIC/SAPIC Affinity */ | 924 | /* 0: Processor Local APIC/SAPIC Affinity */ |
diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h index c8adad9c6b6a..860e5c883eb3 100644 --- a/include/acpi/actbl2.h +++ b/include/acpi/actbl2.h | |||
@@ -70,6 +70,7 @@ | |||
70 | #define ACPI_SIG_HPET "HPET" /* High Precision Event Timer table */ | 70 | #define ACPI_SIG_HPET "HPET" /* High Precision Event Timer table */ |
71 | #define ACPI_SIG_IBFT "IBFT" /* iSCSI Boot Firmware Table */ | 71 | #define ACPI_SIG_IBFT "IBFT" /* iSCSI Boot Firmware Table */ |
72 | #define ACPI_SIG_IVRS "IVRS" /* I/O Virtualization Reporting Structure */ | 72 | #define ACPI_SIG_IVRS "IVRS" /* I/O Virtualization Reporting Structure */ |
73 | #define ACPI_SIG_LPIT "LPIT" /* Low Power Idle Table */ | ||
73 | #define ACPI_SIG_MCFG "MCFG" /* PCI Memory Mapped Configuration table */ | 74 | #define ACPI_SIG_MCFG "MCFG" /* PCI Memory Mapped Configuration table */ |
74 | #define ACPI_SIG_MCHI "MCHI" /* Management Controller Host Interface table */ | 75 | #define ACPI_SIG_MCHI "MCHI" /* Management Controller Host Interface table */ |
75 | #define ACPI_SIG_MTMR "MTMR" /* MID Timer table */ | 76 | #define ACPI_SIG_MTMR "MTMR" /* MID Timer table */ |
@@ -456,7 +457,7 @@ struct acpi_dmar_pci_path { | |||
456 | }; | 457 | }; |
457 | 458 | ||
458 | /* | 459 | /* |
459 | * DMAR Sub-tables, correspond to Type in struct acpi_dmar_header | 460 | * DMAR Subtables, correspond to Type in struct acpi_dmar_header |
460 | */ | 461 | */ |
461 | 462 | ||
462 | /* 0: Hardware Unit Definition */ | 463 | /* 0: Hardware Unit Definition */ |
@@ -820,7 +821,71 @@ struct acpi_ivrs_memory { | |||
820 | 821 | ||
821 | /******************************************************************************* | 822 | /******************************************************************************* |
822 | * | 823 | * |
823 | * MCFG - PCI Memory Mapped Configuration table and sub-table | 824 | * LPIT - Low Power Idle Table |
825 | * | ||
826 | * Conforms to "ACPI Low Power Idle Table (LPIT) and _LPD Proposal (DRAFT)" | ||
827 | * | ||
828 | ******************************************************************************/ | ||
829 | |||
830 | struct acpi_table_lpit { | ||
831 | struct acpi_table_header header; /* Common ACPI table header */ | ||
832 | }; | ||
833 | |||
834 | /* LPIT subtable header */ | ||
835 | |||
836 | struct acpi_lpit_header { | ||
837 | u32 type; /* Subtable type */ | ||
838 | u32 length; /* Subtable length */ | ||
839 | u16 unique_id; | ||
840 | u16 reserved; | ||
841 | u32 flags; | ||
842 | }; | ||
843 | |||
844 | /* Values for subtable Type above */ | ||
845 | |||
846 | enum acpi_lpit_type { | ||
847 | ACPI_LPIT_TYPE_NATIVE_CSTATE = 0x00, | ||
848 | ACPI_LPIT_TYPE_SIMPLE_IO = 0x01 | ||
849 | }; | ||
850 | |||
851 | /* Masks for Flags field above */ | ||
852 | |||
853 | #define ACPI_LPIT_STATE_DISABLED (1) | ||
854 | #define ACPI_LPIT_NO_COUNTER (1<<1) | ||
855 | |||
856 | /* | ||
857 | * LPIT subtables, correspond to Type in struct acpi_lpit_header | ||
858 | */ | ||
859 | |||
860 | /* 0x00: Native C-state instruction based LPI structure */ | ||
861 | |||
862 | struct acpi_lpit_native { | ||
863 | struct acpi_lpit_header header; | ||
864 | struct acpi_generic_address entry_trigger; | ||
865 | u32 residency; | ||
866 | u32 latency; | ||
867 | struct acpi_generic_address residency_counter; | ||
868 | u64 counter_frequency; | ||
869 | }; | ||
870 | |||
871 | /* 0x01: Simple I/O based LPI structure */ | ||
872 | |||
873 | struct acpi_lpit_io { | ||
874 | struct acpi_lpit_header header; | ||
875 | struct acpi_generic_address entry_trigger; | ||
876 | u32 trigger_action; | ||
877 | u64 trigger_value; | ||
878 | u64 trigger_mask; | ||
879 | struct acpi_generic_address minimum_idle_state; | ||
880 | u32 residency; | ||
881 | u32 latency; | ||
882 | struct acpi_generic_address residency_counter; | ||
883 | u64 counter_frequency; | ||
884 | }; | ||
885 | |||
886 | /******************************************************************************* | ||
887 | * | ||
888 | * MCFG - PCI Memory Mapped Configuration table and subtable | ||
824 | * Version 1 | 889 | * Version 1 |
825 | * | 890 | * |
826 | * Conforms to "PCI Firmware Specification", Revision 3.0, June 20, 2005 | 891 | * Conforms to "PCI Firmware Specification", Revision 3.0, June 20, 2005 |
@@ -923,7 +988,7 @@ enum acpi_slic_type { | |||
923 | }; | 988 | }; |
924 | 989 | ||
925 | /* | 990 | /* |
926 | * SLIC Sub-tables, correspond to Type in struct acpi_slic_header | 991 | * SLIC Subtables, correspond to Type in struct acpi_slic_header |
927 | */ | 992 | */ |
928 | 993 | ||
929 | /* 0: Public Key Structure */ | 994 | /* 0: Public Key Structure */ |
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index e76356574374..19b26bb69a70 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h | |||
@@ -329,6 +329,15 @@ typedef u32 acpi_physical_address; | |||
329 | * | 329 | * |
330 | ******************************************************************************/ | 330 | ******************************************************************************/ |
331 | 331 | ||
332 | #ifdef ACPI_NO_MEM_ALLOCATIONS | ||
333 | |||
334 | #define ACPI_ALLOCATE(a) NULL | ||
335 | #define ACPI_ALLOCATE_ZEROED(a) NULL | ||
336 | #define ACPI_FREE(a) | ||
337 | #define ACPI_MEM_TRACKING(a) | ||
338 | |||
339 | #else /* ACPI_NO_MEM_ALLOCATIONS */ | ||
340 | |||
332 | #ifdef ACPI_DBG_TRACK_ALLOCATIONS | 341 | #ifdef ACPI_DBG_TRACK_ALLOCATIONS |
333 | /* | 342 | /* |
334 | * Memory allocation tracking (used by acpi_exec to detect memory leaks) | 343 | * Memory allocation tracking (used by acpi_exec to detect memory leaks) |
@@ -350,6 +359,8 @@ typedef u32 acpi_physical_address; | |||
350 | 359 | ||
351 | #endif /* ACPI_DBG_TRACK_ALLOCATIONS */ | 360 | #endif /* ACPI_DBG_TRACK_ALLOCATIONS */ |
352 | 361 | ||
362 | #endif /* ACPI_NO_MEM_ALLOCATIONS */ | ||
363 | |||
353 | /****************************************************************************** | 364 | /****************************************************************************** |
354 | * | 365 | * |
355 | * ACPI Specification constants (Do not change unless the specification changes) | 366 | * ACPI Specification constants (Do not change unless the specification changes) |
@@ -928,9 +939,19 @@ struct acpi_object_list { | |||
928 | * Miscellaneous common Data Structures used by the interfaces | 939 | * Miscellaneous common Data Structures used by the interfaces |
929 | */ | 940 | */ |
930 | #define ACPI_NO_BUFFER 0 | 941 | #define ACPI_NO_BUFFER 0 |
942 | |||
943 | #ifdef ACPI_NO_MEM_ALLOCATIONS | ||
944 | |||
945 | #define ACPI_ALLOCATE_BUFFER (acpi_size) (0) | ||
946 | #define ACPI_ALLOCATE_LOCAL_BUFFER (acpi_size) (0) | ||
947 | |||
948 | #else /* ACPI_NO_MEM_ALLOCATIONS */ | ||
949 | |||
931 | #define ACPI_ALLOCATE_BUFFER (acpi_size) (-1) /* Let ACPICA allocate buffer */ | 950 | #define ACPI_ALLOCATE_BUFFER (acpi_size) (-1) /* Let ACPICA allocate buffer */ |
932 | #define ACPI_ALLOCATE_LOCAL_BUFFER (acpi_size) (-2) /* For internal use only (enables tracking) */ | 951 | #define ACPI_ALLOCATE_LOCAL_BUFFER (acpi_size) (-2) /* For internal use only (enables tracking) */ |
933 | 952 | ||
953 | #endif /* ACPI_NO_MEM_ALLOCATIONS */ | ||
954 | |||
934 | struct acpi_buffer { | 955 | struct acpi_buffer { |
935 | acpi_size length; /* Length in bytes of the buffer */ | 956 | acpi_size length; /* Length in bytes of the buffer */ |
936 | void *pointer; /* pointer to buffer */ | 957 | void *pointer; /* pointer to buffer */ |
diff --git a/include/acpi/platform/acenvex.h b/include/acpi/platform/acenvex.h new file mode 100644 index 000000000000..2b612384c994 --- /dev/null +++ b/include/acpi/platform/acenvex.h | |||
@@ -0,0 +1,63 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Name: acenvex.h - Extra host and compiler configuration | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2014, 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 | #ifndef __ACENVEX_H__ | ||
45 | #define __ACENVEX_H__ | ||
46 | |||
47 | /*! [Begin] no source code translation */ | ||
48 | |||
49 | /****************************************************************************** | ||
50 | * | ||
51 | * Extra host configuration files. All ACPICA headers are included before | ||
52 | * including these files. | ||
53 | * | ||
54 | *****************************************************************************/ | ||
55 | |||
56 | #if defined(_LINUX) || defined(__linux__) | ||
57 | #include <acpi/platform/aclinuxex.h> | ||
58 | |||
59 | #endif | ||
60 | |||
61 | /*! [End] no source code translation !*/ | ||
62 | |||
63 | #endif /* __ACENVEX_H__ */ | ||
diff --git a/include/acpi/platform/acgcc.h b/include/acpi/platform/acgcc.h index a476b9118b49..384875da3713 100644 --- a/include/acpi/platform/acgcc.h +++ b/include/acpi/platform/acgcc.h | |||
@@ -64,4 +64,15 @@ | |||
64 | */ | 64 | */ |
65 | #define ACPI_UNUSED_VAR __attribute__ ((unused)) | 65 | #define ACPI_UNUSED_VAR __attribute__ ((unused)) |
66 | 66 | ||
67 | /* | ||
68 | * Some versions of gcc implement strchr() with a buggy macro. So, | ||
69 | * undef it here. Prevents error messages of this form (usually from the | ||
70 | * file getopt.c): | ||
71 | * | ||
72 | * error: logical '&&' with non-zero constant will always evaluate as true | ||
73 | */ | ||
74 | #ifdef strchr | ||
75 | #undef strchr | ||
76 | #endif | ||
77 | |||
67 | #endif /* __ACGCC_H__ */ | 78 | #endif /* __ACGCC_H__ */ |
diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h index 93c55ed7c53d..cd1f052d55bb 100644 --- a/include/acpi/platform/aclinux.h +++ b/include/acpi/platform/aclinux.h | |||
@@ -48,7 +48,6 @@ | |||
48 | 48 | ||
49 | #define ACPI_USE_SYSTEM_CLIBRARY | 49 | #define ACPI_USE_SYSTEM_CLIBRARY |
50 | #define ACPI_USE_DO_WHILE_0 | 50 | #define ACPI_USE_DO_WHILE_0 |
51 | #define ACPI_MUTEX_TYPE ACPI_BINARY_SEMAPHORE | ||
52 | 51 | ||
53 | #ifdef __KERNEL__ | 52 | #ifdef __KERNEL__ |
54 | 53 | ||
@@ -71,169 +70,65 @@ | |||
71 | #ifdef EXPORT_ACPI_INTERFACES | 70 | #ifdef EXPORT_ACPI_INTERFACES |
72 | #include <linux/export.h> | 71 | #include <linux/export.h> |
73 | #endif | 72 | #endif |
74 | #include <asm/acpi.h> | 73 | #include <asm/acenv.h> |
75 | 74 | ||
76 | /* Host-dependent types and defines for in-kernel ACPICA */ | 75 | #ifndef CONFIG_ACPI |
77 | 76 | ||
78 | #define ACPI_MACHINE_WIDTH BITS_PER_LONG | 77 | /* External globals for __KERNEL__, stubs is needed */ |
79 | #define ACPI_EXPORT_SYMBOL(symbol) EXPORT_SYMBOL(symbol); | ||
80 | #define strtoul simple_strtoul | ||
81 | 78 | ||
82 | #define acpi_cache_t struct kmem_cache | 79 | #define ACPI_GLOBAL(t,a) |
83 | #define acpi_spinlock spinlock_t * | 80 | #define ACPI_INIT_GLOBAL(t,a,b) |
84 | #define acpi_cpu_flags unsigned long | ||
85 | 81 | ||
86 | #else /* !__KERNEL__ */ | 82 | /* Generating stubs for configurable ACPICA macros */ |
87 | 83 | ||
88 | #include <stdarg.h> | 84 | #define ACPI_NO_MEM_ALLOCATIONS |
89 | #include <string.h> | ||
90 | #include <stdlib.h> | ||
91 | #include <ctype.h> | ||
92 | #include <unistd.h> | ||
93 | 85 | ||
94 | /* Disable kernel specific declarators */ | 86 | /* Generating stubs for configurable ACPICA functions */ |
95 | 87 | ||
96 | #ifndef __init | 88 | #define ACPI_NO_ERROR_MESSAGES |
97 | #define __init | 89 | #undef ACPI_DEBUG_OUTPUT |
98 | #endif | ||
99 | |||
100 | #ifndef __iomem | ||
101 | #define __iomem | ||
102 | #endif | ||
103 | 90 | ||
104 | /* Host-dependent types and defines for user-space ACPICA */ | 91 | /* External interface for __KERNEL__, stub is needed */ |
105 | |||
106 | #define ACPI_FLUSH_CPU_CACHE() | ||
107 | #define ACPI_CAST_PTHREAD_T(pthread) ((acpi_thread_id) (pthread)) | ||
108 | 92 | ||
109 | #if defined(__ia64__) || defined(__x86_64__) || defined(__aarch64__) | 93 | #define ACPI_EXTERNAL_RETURN_STATUS(prototype) \ |
110 | #define ACPI_MACHINE_WIDTH 64 | 94 | static ACPI_INLINE prototype {return(AE_NOT_CONFIGURED);} |
111 | #define COMPILER_DEPENDENT_INT64 long | 95 | #define ACPI_EXTERNAL_RETURN_OK(prototype) \ |
112 | #define COMPILER_DEPENDENT_UINT64 unsigned long | 96 | static ACPI_INLINE prototype {return(AE_OK);} |
113 | #else | 97 | #define ACPI_EXTERNAL_RETURN_VOID(prototype) \ |
114 | #define ACPI_MACHINE_WIDTH 32 | 98 | static ACPI_INLINE prototype {return;} |
115 | #define COMPILER_DEPENDENT_INT64 long long | 99 | #define ACPI_EXTERNAL_RETURN_UINT32(prototype) \ |
116 | #define COMPILER_DEPENDENT_UINT64 unsigned long long | 100 | static ACPI_INLINE prototype {return(0);} |
117 | #define ACPI_USE_NATIVE_DIVIDE | 101 | #define ACPI_EXTERNAL_RETURN_PTR(prototype) \ |
118 | #endif | 102 | static ACPI_INLINE prototype {return(NULL);} |
119 | 103 | ||
120 | #ifndef __cdecl | 104 | #endif /* CONFIG_ACPI */ |
121 | #define __cdecl | ||
122 | #endif | ||
123 | 105 | ||
124 | #endif /* __KERNEL__ */ | 106 | /* Host-dependent types and defines for in-kernel ACPICA */ |
125 | 107 | ||
126 | /* Linux uses GCC */ | 108 | #define ACPI_MACHINE_WIDTH BITS_PER_LONG |
109 | #define ACPI_EXPORT_SYMBOL(symbol) EXPORT_SYMBOL(symbol); | ||
110 | #define strtoul simple_strtoul | ||
127 | 111 | ||
128 | #include <acpi/platform/acgcc.h> | 112 | #define acpi_cache_t struct kmem_cache |
113 | #define acpi_spinlock spinlock_t * | ||
114 | #define acpi_cpu_flags unsigned long | ||
129 | 115 | ||
130 | #ifdef __KERNEL__ | 116 | /* Use native linux version of acpi_os_allocate_zeroed */ |
131 | 117 | ||
132 | /* | 118 | #define USE_NATIVE_ALLOCATE_ZEROED |
133 | * FIXME: Inclusion of actypes.h | ||
134 | * Linux kernel need this before defining inline OSL interfaces as | ||
135 | * actypes.h need to be included to find ACPICA type definitions. | ||
136 | * Since from ACPICA's perspective, the actypes.h should be included after | ||
137 | * acenv.h (aclinux.h), this leads to a inclusion mis-ordering issue. | ||
138 | */ | ||
139 | #include <acpi/actypes.h> | ||
140 | 119 | ||
141 | /* | 120 | /* |
142 | * Overrides for in-kernel ACPICA | 121 | * Overrides for in-kernel ACPICA |
143 | */ | 122 | */ |
144 | acpi_status __init acpi_os_initialize(void); | ||
145 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_initialize | 123 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_initialize |
146 | |||
147 | acpi_status acpi_os_terminate(void); | ||
148 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_terminate | 124 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_terminate |
149 | |||
150 | /* | ||
151 | * Memory allocation/deallocation | ||
152 | */ | ||
153 | |||
154 | /* | ||
155 | * The irqs_disabled() check is for resume from RAM. | ||
156 | * Interrupts are off during resume, just like they are for boot. | ||
157 | * However, boot has (system_state != SYSTEM_RUNNING) | ||
158 | * to quiet __might_sleep() in kmalloc() and resume does not. | ||
159 | */ | ||
160 | static inline void *acpi_os_allocate(acpi_size size) | ||
161 | { | ||
162 | return kmalloc(size, irqs_disabled()? GFP_ATOMIC : GFP_KERNEL); | ||
163 | } | ||
164 | |||
165 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_allocate | 125 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_allocate |
166 | |||
167 | /* Use native linux version of acpi_os_allocate_zeroed */ | ||
168 | |||
169 | static inline void *acpi_os_allocate_zeroed(acpi_size size) | ||
170 | { | ||
171 | return kzalloc(size, irqs_disabled()? GFP_ATOMIC : GFP_KERNEL); | ||
172 | } | ||
173 | |||
174 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_allocate_zeroed | 126 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_allocate_zeroed |
175 | #define USE_NATIVE_ALLOCATE_ZEROED | ||
176 | |||
177 | static inline void acpi_os_free(void *memory) | ||
178 | { | ||
179 | kfree(memory); | ||
180 | } | ||
181 | |||
182 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_free | 127 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_free |
183 | |||
184 | static inline void *acpi_os_acquire_object(acpi_cache_t * cache) | ||
185 | { | ||
186 | return kmem_cache_zalloc(cache, | ||
187 | irqs_disabled()? GFP_ATOMIC : GFP_KERNEL); | ||
188 | } | ||
189 | |||
190 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_acquire_object | 128 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_acquire_object |
191 | |||
192 | static inline acpi_thread_id acpi_os_get_thread_id(void) | ||
193 | { | ||
194 | return (acpi_thread_id) (unsigned long)current; | ||
195 | } | ||
196 | |||
197 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_thread_id | 129 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_thread_id |
198 | |||
199 | #ifndef CONFIG_PREEMPT | ||
200 | |||
201 | /* | ||
202 | * Used within ACPICA to show where it is safe to preempt execution | ||
203 | * when CONFIG_PREEMPT=n | ||
204 | */ | ||
205 | #define ACPI_PREEMPTION_POINT() \ | ||
206 | do { \ | ||
207 | if (!irqs_disabled()) \ | ||
208 | cond_resched(); \ | ||
209 | } while (0) | ||
210 | |||
211 | #endif | ||
212 | |||
213 | /* | ||
214 | * When lockdep is enabled, the spin_lock_init() macro stringifies it's | ||
215 | * argument and uses that as a name for the lock in debugging. | ||
216 | * By executing spin_lock_init() in a macro the key changes from "lock" for | ||
217 | * all locks to the name of the argument of acpi_os_create_lock(), which | ||
218 | * prevents lockdep from reporting false positives for ACPICA locks. | ||
219 | */ | ||
220 | #define acpi_os_create_lock(__handle) \ | ||
221 | ({ \ | ||
222 | spinlock_t *lock = ACPI_ALLOCATE(sizeof(*lock)); \ | ||
223 | if (lock) { \ | ||
224 | *(__handle) = lock; \ | ||
225 | spin_lock_init(*(__handle)); \ | ||
226 | } \ | ||
227 | lock ? AE_OK : AE_NO_MEMORY; \ | ||
228 | }) | ||
229 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_create_lock | 130 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_create_lock |
230 | 131 | ||
231 | void __iomem *acpi_os_map_memory(acpi_physical_address where, acpi_size length); | ||
232 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_map_memory | ||
233 | |||
234 | void acpi_os_unmap_memory(void __iomem * logical_address, acpi_size size); | ||
235 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_unmap_memory | ||
236 | |||
237 | /* | 132 | /* |
238 | * OSL interfaces used by debugger/disassembler | 133 | * OSL interfaces used by debugger/disassembler |
239 | */ | 134 | */ |
@@ -252,11 +147,45 @@ void acpi_os_unmap_memory(void __iomem * logical_address, acpi_size size); | |||
252 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_next_filename | 147 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_next_filename |
253 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_close_directory | 148 | #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_close_directory |
254 | 149 | ||
255 | /* | 150 | #else /* !__KERNEL__ */ |
256 | * OSL interfaces added by Linux | 151 | |
257 | */ | 152 | #include <stdarg.h> |
258 | void early_acpi_os_unmap_memory(void __iomem * virt, acpi_size size); | 153 | #include <string.h> |
154 | #include <stdlib.h> | ||
155 | #include <ctype.h> | ||
156 | #include <unistd.h> | ||
157 | |||
158 | /* Define/disable kernel-specific declarators */ | ||
159 | |||
160 | #ifndef __init | ||
161 | #define __init | ||
162 | #endif | ||
163 | |||
164 | /* Host-dependent types and defines for user-space ACPICA */ | ||
165 | |||
166 | #define ACPI_FLUSH_CPU_CACHE() | ||
167 | #define ACPI_CAST_PTHREAD_T(pthread) ((acpi_thread_id) (pthread)) | ||
168 | |||
169 | #if defined(__ia64__) || defined(__x86_64__) ||\ | ||
170 | defined(__aarch64__) || defined(__PPC64__) | ||
171 | #define ACPI_MACHINE_WIDTH 64 | ||
172 | #define COMPILER_DEPENDENT_INT64 long | ||
173 | #define COMPILER_DEPENDENT_UINT64 unsigned long | ||
174 | #else | ||
175 | #define ACPI_MACHINE_WIDTH 32 | ||
176 | #define COMPILER_DEPENDENT_INT64 long long | ||
177 | #define COMPILER_DEPENDENT_UINT64 unsigned long long | ||
178 | #define ACPI_USE_NATIVE_DIVIDE | ||
179 | #endif | ||
180 | |||
181 | #ifndef __cdecl | ||
182 | #define __cdecl | ||
183 | #endif | ||
259 | 184 | ||
260 | #endif /* __KERNEL__ */ | 185 | #endif /* __KERNEL__ */ |
261 | 186 | ||
187 | /* Linux uses GCC */ | ||
188 | |||
189 | #include <acpi/platform/acgcc.h> | ||
190 | |||
262 | #endif /* __ACLINUX_H__ */ | 191 | #endif /* __ACLINUX_H__ */ |
diff --git a/include/acpi/platform/aclinuxex.h b/include/acpi/platform/aclinuxex.h new file mode 100644 index 000000000000..191e741cfa0e --- /dev/null +++ b/include/acpi/platform/aclinuxex.h | |||
@@ -0,0 +1,112 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Name: aclinuxex.h - Extra OS specific defines, etc. for Linux | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2014, 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 | #ifndef __ACLINUXEX_H__ | ||
45 | #define __ACLINUXEX_H__ | ||
46 | |||
47 | #ifdef __KERNEL__ | ||
48 | |||
49 | /* | ||
50 | * Overrides for in-kernel ACPICA | ||
51 | */ | ||
52 | acpi_status __init acpi_os_initialize(void); | ||
53 | |||
54 | acpi_status acpi_os_terminate(void); | ||
55 | |||
56 | /* | ||
57 | * The irqs_disabled() check is for resume from RAM. | ||
58 | * Interrupts are off during resume, just like they are for boot. | ||
59 | * However, boot has (system_state != SYSTEM_RUNNING) | ||
60 | * to quiet __might_sleep() in kmalloc() and resume does not. | ||
61 | */ | ||
62 | static inline void *acpi_os_allocate(acpi_size size) | ||
63 | { | ||
64 | return kmalloc(size, irqs_disabled()? GFP_ATOMIC : GFP_KERNEL); | ||
65 | } | ||
66 | |||
67 | static inline void *acpi_os_allocate_zeroed(acpi_size size) | ||
68 | { | ||
69 | return kzalloc(size, irqs_disabled()? GFP_ATOMIC : GFP_KERNEL); | ||
70 | } | ||
71 | |||
72 | static inline void acpi_os_free(void *memory) | ||
73 | { | ||
74 | kfree(memory); | ||
75 | } | ||
76 | |||
77 | static inline void *acpi_os_acquire_object(acpi_cache_t * cache) | ||
78 | { | ||
79 | return kmem_cache_zalloc(cache, | ||
80 | irqs_disabled()? GFP_ATOMIC : GFP_KERNEL); | ||
81 | } | ||
82 | |||
83 | static inline acpi_thread_id acpi_os_get_thread_id(void) | ||
84 | { | ||
85 | return (acpi_thread_id) (unsigned long)current; | ||
86 | } | ||
87 | |||
88 | /* | ||
89 | * When lockdep is enabled, the spin_lock_init() macro stringifies it's | ||
90 | * argument and uses that as a name for the lock in debugging. | ||
91 | * By executing spin_lock_init() in a macro the key changes from "lock" for | ||
92 | * all locks to the name of the argument of acpi_os_create_lock(), which | ||
93 | * prevents lockdep from reporting false positives for ACPICA locks. | ||
94 | */ | ||
95 | #define acpi_os_create_lock(__handle) \ | ||
96 | ({ \ | ||
97 | spinlock_t *lock = ACPI_ALLOCATE(sizeof(*lock)); \ | ||
98 | if (lock) { \ | ||
99 | *(__handle) = lock; \ | ||
100 | spin_lock_init(*(__handle)); \ | ||
101 | } \ | ||
102 | lock ? AE_OK : AE_NO_MEMORY; \ | ||
103 | }) | ||
104 | |||
105 | /* | ||
106 | * OSL interfaces added by Linux | ||
107 | */ | ||
108 | void early_acpi_os_unmap_memory(void __iomem * virt, acpi_size size); | ||
109 | |||
110 | #endif /* __KERNEL__ */ | ||
111 | |||
112 | #endif /* __ACLINUXEX_H__ */ | ||
diff --git a/tools/power/acpi/Makefile b/tools/power/acpi/Makefile index c2c0f20067a5..7ac578019ea9 100644 --- a/tools/power/acpi/Makefile +++ b/tools/power/acpi/Makefile | |||
@@ -68,7 +68,8 @@ WARNINGS += $(call cc-supports,-Wstrict-prototypes) | |||
68 | WARNINGS += $(call cc-supports,-Wdeclaration-after-statement) | 68 | WARNINGS += $(call cc-supports,-Wdeclaration-after-statement) |
69 | 69 | ||
70 | KERNEL_INCLUDE := ../../../include | 70 | KERNEL_INCLUDE := ../../../include |
71 | CFLAGS += -D_LINUX -DDEFINE_ALTERNATE_TYPES -I$(KERNEL_INCLUDE) | 71 | ACPICA_INCLUDE := ../../../drivers/acpi/acpica |
72 | CFLAGS += -D_LINUX -I$(KERNEL_INCLUDE) -I$(ACPICA_INCLUDE) | ||
72 | CFLAGS += $(WARNINGS) | 73 | CFLAGS += $(WARNINGS) |
73 | 74 | ||
74 | ifeq ($(strip $(V)),false) | 75 | ifeq ($(strip $(V)),false) |
@@ -92,10 +93,29 @@ endif | |||
92 | # --- ACPIDUMP BEGIN --- | 93 | # --- ACPIDUMP BEGIN --- |
93 | 94 | ||
94 | vpath %.c \ | 95 | vpath %.c \ |
95 | tools/acpidump | 96 | ../../../drivers/acpi/acpica\ |
97 | tools/acpidump\ | ||
98 | common\ | ||
99 | os_specific/service_layers | ||
100 | |||
101 | CFLAGS += -DACPI_DUMP_APP -Itools/acpidump | ||
96 | 102 | ||
97 | DUMP_OBJS = \ | 103 | DUMP_OBJS = \ |
98 | acpidump.o | 104 | apdump.o\ |
105 | apfiles.o\ | ||
106 | apmain.o\ | ||
107 | osunixdir.o\ | ||
108 | osunixmap.o\ | ||
109 | tbprint.o\ | ||
110 | tbxfroot.o\ | ||
111 | utbuffer.o\ | ||
112 | utexcep.o\ | ||
113 | utmath.o\ | ||
114 | utstring.o\ | ||
115 | utxferror.o\ | ||
116 | oslinuxtbl.o\ | ||
117 | cmfsize.o\ | ||
118 | getopt.o | ||
99 | 119 | ||
100 | DUMP_OBJS := $(addprefix $(OUTPUT)tools/acpidump/,$(DUMP_OBJS)) | 120 | DUMP_OBJS := $(addprefix $(OUTPUT)tools/acpidump/,$(DUMP_OBJS)) |
101 | 121 | ||
diff --git a/tools/power/acpi/common/cmfsize.c b/tools/power/acpi/common/cmfsize.c new file mode 100644 index 000000000000..5140e5edae1f --- /dev/null +++ b/tools/power/acpi/common/cmfsize.c | |||
@@ -0,0 +1,101 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: cfsize - Common get file size function | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2014, 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 <acpi/acpi.h> | ||
45 | #include "accommon.h" | ||
46 | #include "acapps.h" | ||
47 | #include <stdio.h> | ||
48 | |||
49 | #define _COMPONENT ACPI_TOOLS | ||
50 | ACPI_MODULE_NAME("cmfsize") | ||
51 | |||
52 | /******************************************************************************* | ||
53 | * | ||
54 | * FUNCTION: cm_get_file_size | ||
55 | * | ||
56 | * PARAMETERS: file - Open file descriptor | ||
57 | * | ||
58 | * RETURN: File Size. On error, -1 (ACPI_UINT32_MAX) | ||
59 | * | ||
60 | * DESCRIPTION: Get the size of a file. Uses seek-to-EOF. File must be open. | ||
61 | * Does not disturb the current file pointer. Uses perror for | ||
62 | * error messages. | ||
63 | * | ||
64 | ******************************************************************************/ | ||
65 | u32 cm_get_file_size(FILE * file) | ||
66 | { | ||
67 | long file_size; | ||
68 | long current_offset; | ||
69 | |||
70 | /* Save the current file pointer, seek to EOF to obtain file size */ | ||
71 | |||
72 | current_offset = ftell(file); | ||
73 | if (current_offset < 0) { | ||
74 | goto offset_error; | ||
75 | } | ||
76 | |||
77 | if (fseek(file, 0, SEEK_END)) { | ||
78 | goto seek_error; | ||
79 | } | ||
80 | |||
81 | file_size = ftell(file); | ||
82 | if (file_size < 0) { | ||
83 | goto offset_error; | ||
84 | } | ||
85 | |||
86 | /* Restore original file pointer */ | ||
87 | |||
88 | if (fseek(file, current_offset, SEEK_SET)) { | ||
89 | goto seek_error; | ||
90 | } | ||
91 | |||
92 | return ((u32)file_size); | ||
93 | |||
94 | offset_error: | ||
95 | perror("Could not get file offset"); | ||
96 | return (ACPI_UINT32_MAX); | ||
97 | |||
98 | seek_error: | ||
99 | perror("Could not seek file"); | ||
100 | return (ACPI_UINT32_MAX); | ||
101 | } | ||
diff --git a/tools/power/acpi/common/getopt.c b/tools/power/acpi/common/getopt.c new file mode 100644 index 000000000000..a302f52e4fd3 --- /dev/null +++ b/tools/power/acpi/common/getopt.c | |||
@@ -0,0 +1,239 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: getopt | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2014, 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 | /* | ||
45 | * ACPICA getopt() implementation | ||
46 | * | ||
47 | * Option strings: | ||
48 | * "f" - Option has no arguments | ||
49 | * "f:" - Option requires an argument | ||
50 | * "f^" - Option has optional single-char sub-options | ||
51 | * "f|" - Option has required single-char sub-options | ||
52 | */ | ||
53 | |||
54 | #include <stdio.h> | ||
55 | #include <string.h> | ||
56 | #include <acpi/acpi.h> | ||
57 | #include "accommon.h" | ||
58 | #include "acapps.h" | ||
59 | |||
60 | #define ACPI_OPTION_ERROR(msg, badchar) \ | ||
61 | if (acpi_gbl_opterr) {fprintf (stderr, "%s%c\n", msg, badchar);} | ||
62 | |||
63 | int acpi_gbl_opterr = 1; | ||
64 | int acpi_gbl_optind = 1; | ||
65 | int acpi_gbl_sub_opt_char = 0; | ||
66 | char *acpi_gbl_optarg; | ||
67 | |||
68 | static int current_char_ptr = 1; | ||
69 | |||
70 | /******************************************************************************* | ||
71 | * | ||
72 | * FUNCTION: acpi_getopt_argument | ||
73 | * | ||
74 | * PARAMETERS: argc, argv - from main | ||
75 | * | ||
76 | * RETURN: 0 if an argument was found, -1 otherwise. Sets acpi_gbl_Optarg | ||
77 | * to point to the next argument. | ||
78 | * | ||
79 | * DESCRIPTION: Get the next argument. Used to obtain arguments for the | ||
80 | * two-character options after the original call to acpi_getopt. | ||
81 | * Note: Either the argument starts at the next character after | ||
82 | * the option, or it is pointed to by the next argv entry. | ||
83 | * (After call to acpi_getopt, we need to backup to the previous | ||
84 | * argv entry). | ||
85 | * | ||
86 | ******************************************************************************/ | ||
87 | |||
88 | int acpi_getopt_argument(int argc, char **argv) | ||
89 | { | ||
90 | acpi_gbl_optind--; | ||
91 | current_char_ptr++; | ||
92 | |||
93 | if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') { | ||
94 | acpi_gbl_optarg = | ||
95 | &argv[acpi_gbl_optind++][(int)(current_char_ptr + 1)]; | ||
96 | } else if (++acpi_gbl_optind >= argc) { | ||
97 | ACPI_OPTION_ERROR("Option requires an argument: -", 'v'); | ||
98 | |||
99 | current_char_ptr = 1; | ||
100 | return (-1); | ||
101 | } else { | ||
102 | acpi_gbl_optarg = argv[acpi_gbl_optind++]; | ||
103 | } | ||
104 | |||
105 | current_char_ptr = 1; | ||
106 | return (0); | ||
107 | } | ||
108 | |||
109 | /******************************************************************************* | ||
110 | * | ||
111 | * FUNCTION: acpi_getopt | ||
112 | * | ||
113 | * PARAMETERS: argc, argv - from main | ||
114 | * opts - options info list | ||
115 | * | ||
116 | * RETURN: Option character or EOF | ||
117 | * | ||
118 | * DESCRIPTION: Get the next option | ||
119 | * | ||
120 | ******************************************************************************/ | ||
121 | |||
122 | int acpi_getopt(int argc, char **argv, char *opts) | ||
123 | { | ||
124 | int current_char; | ||
125 | char *opts_ptr; | ||
126 | |||
127 | if (current_char_ptr == 1) { | ||
128 | if (acpi_gbl_optind >= argc || | ||
129 | argv[acpi_gbl_optind][0] != '-' || | ||
130 | argv[acpi_gbl_optind][1] == '\0') { | ||
131 | return (EOF); | ||
132 | } else if (strcmp(argv[acpi_gbl_optind], "--") == 0) { | ||
133 | acpi_gbl_optind++; | ||
134 | return (EOF); | ||
135 | } | ||
136 | } | ||
137 | |||
138 | /* Get the option */ | ||
139 | |||
140 | current_char = argv[acpi_gbl_optind][current_char_ptr]; | ||
141 | |||
142 | /* Make sure that the option is legal */ | ||
143 | |||
144 | if (current_char == ':' || | ||
145 | (opts_ptr = strchr(opts, current_char)) == NULL) { | ||
146 | ACPI_OPTION_ERROR("Illegal option: -", current_char); | ||
147 | |||
148 | if (argv[acpi_gbl_optind][++current_char_ptr] == '\0') { | ||
149 | acpi_gbl_optind++; | ||
150 | current_char_ptr = 1; | ||
151 | } | ||
152 | |||
153 | return ('?'); | ||
154 | } | ||
155 | |||
156 | /* Option requires an argument? */ | ||
157 | |||
158 | if (*++opts_ptr == ':') { | ||
159 | if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') { | ||
160 | acpi_gbl_optarg = | ||
161 | &argv[acpi_gbl_optind++][(int) | ||
162 | (current_char_ptr + 1)]; | ||
163 | } else if (++acpi_gbl_optind >= argc) { | ||
164 | ACPI_OPTION_ERROR("Option requires an argument: -", | ||
165 | current_char); | ||
166 | |||
167 | current_char_ptr = 1; | ||
168 | return ('?'); | ||
169 | } else { | ||
170 | acpi_gbl_optarg = argv[acpi_gbl_optind++]; | ||
171 | } | ||
172 | |||
173 | current_char_ptr = 1; | ||
174 | } | ||
175 | |||
176 | /* Option has an optional argument? */ | ||
177 | |||
178 | else if (*opts_ptr == '+') { | ||
179 | if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') { | ||
180 | acpi_gbl_optarg = | ||
181 | &argv[acpi_gbl_optind++][(int) | ||
182 | (current_char_ptr + 1)]; | ||
183 | } else if (++acpi_gbl_optind >= argc) { | ||
184 | acpi_gbl_optarg = NULL; | ||
185 | } else { | ||
186 | acpi_gbl_optarg = argv[acpi_gbl_optind++]; | ||
187 | } | ||
188 | |||
189 | current_char_ptr = 1; | ||
190 | } | ||
191 | |||
192 | /* Option has optional single-char arguments? */ | ||
193 | |||
194 | else if (*opts_ptr == '^') { | ||
195 | if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') { | ||
196 | acpi_gbl_optarg = | ||
197 | &argv[acpi_gbl_optind][(int)(current_char_ptr + 1)]; | ||
198 | } else { | ||
199 | acpi_gbl_optarg = "^"; | ||
200 | } | ||
201 | |||
202 | acpi_gbl_sub_opt_char = acpi_gbl_optarg[0]; | ||
203 | acpi_gbl_optind++; | ||
204 | current_char_ptr = 1; | ||
205 | } | ||
206 | |||
207 | /* Option has a required single-char argument? */ | ||
208 | |||
209 | else if (*opts_ptr == '|') { | ||
210 | if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') { | ||
211 | acpi_gbl_optarg = | ||
212 | &argv[acpi_gbl_optind][(int)(current_char_ptr + 1)]; | ||
213 | } else { | ||
214 | ACPI_OPTION_ERROR | ||
215 | ("Option requires a single-character suboption: -", | ||
216 | current_char); | ||
217 | |||
218 | current_char_ptr = 1; | ||
219 | return ('?'); | ||
220 | } | ||
221 | |||
222 | acpi_gbl_sub_opt_char = acpi_gbl_optarg[0]; | ||
223 | acpi_gbl_optind++; | ||
224 | current_char_ptr = 1; | ||
225 | } | ||
226 | |||
227 | /* Option with no arguments */ | ||
228 | |||
229 | else { | ||
230 | if (argv[acpi_gbl_optind][++current_char_ptr] == '\0') { | ||
231 | current_char_ptr = 1; | ||
232 | acpi_gbl_optind++; | ||
233 | } | ||
234 | |||
235 | acpi_gbl_optarg = NULL; | ||
236 | } | ||
237 | |||
238 | return (current_char); | ||
239 | } | ||
diff --git a/tools/power/acpi/man/acpidump.8 b/tools/power/acpi/man/acpidump.8 index adfa99166e5e..38f095d86b52 100644 --- a/tools/power/acpi/man/acpidump.8 +++ b/tools/power/acpi/man/acpidump.8 | |||
@@ -1,18 +1,64 @@ | |||
1 | .TH ACPIDUMP 8 | 1 | .TH ACPIDUMP 8 |
2 | .SH NAME | 2 | .SH NAME |
3 | acpidump \- Dump system's ACPI tables to an ASCII file. | 3 | acpidump \- dump a system's ACPI tables to an ASCII file |
4 | |||
4 | .SH SYNOPSIS | 5 | .SH SYNOPSIS |
5 | .ft B | 6 | .B acpidump |
6 | .B acpidump > acpidump.out | 7 | .RI [ options ] |
8 | .br | ||
9 | |||
7 | .SH DESCRIPTION | 10 | .SH DESCRIPTION |
8 | \fBacpidump \fP dumps the systems ACPI tables to an ASCII file | 11 | .B acpidump |
9 | appropriate for attaching to a bug report. | 12 | dumps the systems ACPI tables to an ASCII file appropriate for |
13 | attaching to a bug report. | ||
10 | 14 | ||
11 | Subsequently, they can be processed by utilities in the ACPICA package. | 15 | Subsequently, they can be processed by utilities in the ACPICA package. |
12 | .SS Options | 16 | |
13 | no options worth worrying about. | 17 | .SH OPTIONS |
14 | .PP | 18 | acpidump options are as follow: |
15 | .SH EXAMPLE | 19 | .TP |
20 | .B Options | ||
21 | .TP | ||
22 | .B \-b | ||
23 | Dump tables to binary files | ||
24 | .TP | ||
25 | .B \-c | ||
26 | Dump customized tables | ||
27 | .TP | ||
28 | .B \-h \-? | ||
29 | This help message | ||
30 | .TP | ||
31 | .B \-o <File> | ||
32 | Redirect output to file | ||
33 | .TP | ||
34 | .B \-r <Address> | ||
35 | Dump tables from specified RSDP | ||
36 | .TP | ||
37 | .B \-s | ||
38 | Print table summaries only | ||
39 | .TP | ||
40 | .B \-v | ||
41 | Display version information | ||
42 | .TP | ||
43 | .B \-z | ||
44 | Verbose mode | ||
45 | .TP | ||
46 | .B Table Options | ||
47 | .TP | ||
48 | .B \-a <Address> | ||
49 | Get table via a physical address | ||
50 | .TP | ||
51 | .B \-f <BinaryFile> | ||
52 | Get table via a binary file | ||
53 | .TP | ||
54 | .B \-n <Signature> | ||
55 | Get table via a name/signature | ||
56 | .TP | ||
57 | Invocation without parameters dumps all available tables | ||
58 | .TP | ||
59 | Multiple mixed instances of -a, -f, and -n are supported | ||
60 | |||
61 | .SH EXAMPLES | ||
16 | 62 | ||
17 | .nf | 63 | .nf |
18 | # acpidump > acpidump.out | 64 | # acpidump > acpidump.out |
@@ -50,10 +96,25 @@ ACPICA: https://acpica.org/ | |||
50 | .ta | 96 | .ta |
51 | .nf | 97 | .nf |
52 | /dev/mem | 98 | /dev/mem |
99 | /sys/firmware/acpi/tables/* | ||
53 | /sys/firmware/acpi/tables/dynamic/* | 100 | /sys/firmware/acpi/tables/dynamic/* |
101 | /sys/firmware/efi/systab | ||
54 | .fi | 102 | .fi |
55 | 103 | ||
56 | .PP | ||
57 | .SH AUTHOR | 104 | .SH AUTHOR |
58 | .nf | 105 | .TP |
59 | Written by Len Brown <len.brown@intel.com> | 106 | Original by: |
107 | Len Brown <len.brown@intel.com> | ||
108 | .TP | ||
109 | Written by: | ||
110 | Chao Guan <chao.guan@intel.com> | ||
111 | .TP | ||
112 | Updated by: | ||
113 | Bob Moore <robert.moore@intel.com> | ||
114 | Lv Zheng <lv.zheng@intel.com> | ||
115 | |||
116 | .SH SEE ALSO | ||
117 | \&\fIacpixtract\fR\|(8), \fIiasl\fR\|(8). | ||
118 | |||
119 | .SH COPYRIGHT | ||
120 | COPYRIGHT (c) 2013, Intel Corporation. | ||
diff --git a/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c b/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c new file mode 100644 index 000000000000..28c52008e854 --- /dev/null +++ b/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c | |||
@@ -0,0 +1,1329 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: oslinuxtbl - Linux OSL for obtaining ACPI tables | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2014, 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 "acpidump.h" | ||
45 | |||
46 | #define _COMPONENT ACPI_OS_SERVICES | ||
47 | ACPI_MODULE_NAME("oslinuxtbl") | ||
48 | |||
49 | #ifndef PATH_MAX | ||
50 | #define PATH_MAX 256 | ||
51 | #endif | ||
52 | /* List of information about obtained ACPI tables */ | ||
53 | typedef struct osl_table_info { | ||
54 | struct osl_table_info *next; | ||
55 | u32 instance; | ||
56 | char signature[ACPI_NAME_SIZE]; | ||
57 | |||
58 | } osl_table_info; | ||
59 | |||
60 | /* Local prototypes */ | ||
61 | |||
62 | static acpi_status osl_table_initialize(void); | ||
63 | |||
64 | static acpi_status | ||
65 | osl_table_name_from_file(char *filename, char *signature, u32 *instance); | ||
66 | |||
67 | static acpi_status osl_add_table_to_list(char *signature, u32 instance); | ||
68 | |||
69 | static acpi_status | ||
70 | osl_read_table_from_file(char *filename, | ||
71 | acpi_size file_offset, | ||
72 | char *signature, struct acpi_table_header **table); | ||
73 | |||
74 | static acpi_status | ||
75 | osl_map_table(acpi_size address, | ||
76 | char *signature, struct acpi_table_header **table); | ||
77 | |||
78 | static void osl_unmap_table(struct acpi_table_header *table); | ||
79 | |||
80 | static acpi_physical_address osl_find_rsdp_via_efi(void); | ||
81 | |||
82 | static acpi_status osl_load_rsdp(void); | ||
83 | |||
84 | static acpi_status osl_list_customized_tables(char *directory); | ||
85 | |||
86 | static acpi_status | ||
87 | osl_get_customized_table(char *pathname, | ||
88 | char *signature, | ||
89 | u32 instance, | ||
90 | struct acpi_table_header **table, | ||
91 | acpi_physical_address * address); | ||
92 | |||
93 | static acpi_status osl_list_bios_tables(void); | ||
94 | |||
95 | static acpi_status | ||
96 | osl_get_bios_table(char *signature, | ||
97 | u32 instance, | ||
98 | struct acpi_table_header **table, | ||
99 | acpi_physical_address * address); | ||
100 | |||
101 | static acpi_status osl_get_last_status(acpi_status default_status); | ||
102 | |||
103 | /* File locations */ | ||
104 | |||
105 | #define DYNAMIC_TABLE_DIR "/sys/firmware/acpi/tables/dynamic" | ||
106 | #define STATIC_TABLE_DIR "/sys/firmware/acpi/tables" | ||
107 | #define EFI_SYSTAB "/sys/firmware/efi/systab" | ||
108 | |||
109 | /* Should we get dynamically loaded SSDTs from DYNAMIC_TABLE_DIR? */ | ||
110 | |||
111 | u8 gbl_dump_dynamic_tables = TRUE; | ||
112 | |||
113 | /* Initialization flags */ | ||
114 | |||
115 | u8 gbl_table_list_initialized = FALSE; | ||
116 | |||
117 | /* Local copies of main ACPI tables */ | ||
118 | |||
119 | struct acpi_table_rsdp gbl_rsdp; | ||
120 | struct acpi_table_fadt *gbl_fadt = NULL; | ||
121 | struct acpi_table_rsdt *gbl_rsdt = NULL; | ||
122 | struct acpi_table_xsdt *gbl_xsdt = NULL; | ||
123 | |||
124 | /* Table addresses */ | ||
125 | |||
126 | acpi_physical_address gbl_fadt_address = 0; | ||
127 | acpi_physical_address gbl_rsdp_address = 0; | ||
128 | |||
129 | /* Revision of RSD PTR */ | ||
130 | |||
131 | u8 gbl_revision = 0; | ||
132 | |||
133 | struct osl_table_info *gbl_table_list_head = NULL; | ||
134 | u32 gbl_table_count = 0; | ||
135 | |||
136 | /****************************************************************************** | ||
137 | * | ||
138 | * FUNCTION: osl_get_last_status | ||
139 | * | ||
140 | * PARAMETERS: default_status - Default error status to return | ||
141 | * | ||
142 | * RETURN: Status; Converted from errno. | ||
143 | * | ||
144 | * DESCRIPTION: Get last errno and conver it to acpi_status. | ||
145 | * | ||
146 | *****************************************************************************/ | ||
147 | |||
148 | static acpi_status osl_get_last_status(acpi_status default_status) | ||
149 | { | ||
150 | |||
151 | switch (errno) { | ||
152 | case EACCES: | ||
153 | case EPERM: | ||
154 | |||
155 | return (AE_ACCESS); | ||
156 | |||
157 | case ENOENT: | ||
158 | |||
159 | return (AE_NOT_FOUND); | ||
160 | |||
161 | case ENOMEM: | ||
162 | |||
163 | return (AE_NO_MEMORY); | ||
164 | |||
165 | default: | ||
166 | |||
167 | return (default_status); | ||
168 | } | ||
169 | } | ||
170 | |||
171 | /****************************************************************************** | ||
172 | * | ||
173 | * FUNCTION: acpi_os_get_table_by_address | ||
174 | * | ||
175 | * PARAMETERS: address - Physical address of the ACPI table | ||
176 | * table - Where a pointer to the table is returned | ||
177 | * | ||
178 | * RETURN: Status; Table buffer is returned if AE_OK. | ||
179 | * AE_NOT_FOUND: A valid table was not found at the address | ||
180 | * | ||
181 | * DESCRIPTION: Get an ACPI table via a physical memory address. | ||
182 | * | ||
183 | *****************************************************************************/ | ||
184 | |||
185 | acpi_status | ||
186 | acpi_os_get_table_by_address(acpi_physical_address address, | ||
187 | struct acpi_table_header ** table) | ||
188 | { | ||
189 | u32 table_length; | ||
190 | struct acpi_table_header *mapped_table; | ||
191 | struct acpi_table_header *local_table = NULL; | ||
192 | acpi_status status = AE_OK; | ||
193 | |||
194 | /* Get main ACPI tables from memory on first invocation of this function */ | ||
195 | |||
196 | status = osl_table_initialize(); | ||
197 | if (ACPI_FAILURE(status)) { | ||
198 | return (status); | ||
199 | } | ||
200 | |||
201 | /* Map the table and validate it */ | ||
202 | |||
203 | status = osl_map_table(address, NULL, &mapped_table); | ||
204 | if (ACPI_FAILURE(status)) { | ||
205 | return (status); | ||
206 | } | ||
207 | |||
208 | /* Copy table to local buffer and return it */ | ||
209 | |||
210 | table_length = ap_get_table_length(mapped_table); | ||
211 | if (table_length == 0) { | ||
212 | status = AE_BAD_HEADER; | ||
213 | goto exit; | ||
214 | } | ||
215 | |||
216 | local_table = calloc(1, table_length); | ||
217 | if (!local_table) { | ||
218 | status = AE_NO_MEMORY; | ||
219 | goto exit; | ||
220 | } | ||
221 | |||
222 | ACPI_MEMCPY(local_table, mapped_table, table_length); | ||
223 | |||
224 | exit: | ||
225 | osl_unmap_table(mapped_table); | ||
226 | *table = local_table; | ||
227 | return (status); | ||
228 | } | ||
229 | |||
230 | /****************************************************************************** | ||
231 | * | ||
232 | * FUNCTION: acpi_os_get_table_by_name | ||
233 | * | ||
234 | * PARAMETERS: signature - ACPI Signature for desired table. Must be | ||
235 | * a null terminated 4-character string. | ||
236 | * instance - Multiple table support for SSDT/UEFI (0...n) | ||
237 | * Must be 0 for other tables. | ||
238 | * table - Where a pointer to the table is returned | ||
239 | * address - Where the table physical address is returned | ||
240 | * | ||
241 | * RETURN: Status; Table buffer and physical address returned if AE_OK. | ||
242 | * AE_LIMIT: Instance is beyond valid limit | ||
243 | * AE_NOT_FOUND: A table with the signature was not found | ||
244 | * | ||
245 | * NOTE: Assumes the input signature is uppercase. | ||
246 | * | ||
247 | *****************************************************************************/ | ||
248 | |||
249 | acpi_status | ||
250 | acpi_os_get_table_by_name(char *signature, | ||
251 | u32 instance, | ||
252 | struct acpi_table_header ** table, | ||
253 | acpi_physical_address * address) | ||
254 | { | ||
255 | acpi_status status; | ||
256 | |||
257 | /* Get main ACPI tables from memory on first invocation of this function */ | ||
258 | |||
259 | status = osl_table_initialize(); | ||
260 | if (ACPI_FAILURE(status)) { | ||
261 | return (status); | ||
262 | } | ||
263 | |||
264 | /* Not a main ACPI table, attempt to extract it from the RSDT/XSDT */ | ||
265 | |||
266 | if (!gbl_dump_customized_tables) { | ||
267 | |||
268 | /* Attempt to get the table from the memory */ | ||
269 | |||
270 | status = | ||
271 | osl_get_bios_table(signature, instance, table, address); | ||
272 | } else { | ||
273 | /* Attempt to get the table from the static directory */ | ||
274 | |||
275 | status = osl_get_customized_table(STATIC_TABLE_DIR, signature, | ||
276 | instance, table, address); | ||
277 | } | ||
278 | |||
279 | if (ACPI_FAILURE(status) && status == AE_LIMIT) { | ||
280 | if (gbl_dump_dynamic_tables) { | ||
281 | |||
282 | /* Attempt to get a dynamic table */ | ||
283 | |||
284 | status = | ||
285 | osl_get_customized_table(DYNAMIC_TABLE_DIR, | ||
286 | signature, instance, table, | ||
287 | address); | ||
288 | } | ||
289 | } | ||
290 | |||
291 | return (status); | ||
292 | } | ||
293 | |||
294 | /****************************************************************************** | ||
295 | * | ||
296 | * FUNCTION: osl_add_table_to_list | ||
297 | * | ||
298 | * PARAMETERS: signature - Table signature | ||
299 | * instance - Table instance | ||
300 | * | ||
301 | * RETURN: Status; Successfully added if AE_OK. | ||
302 | * AE_NO_MEMORY: Memory allocation error | ||
303 | * | ||
304 | * DESCRIPTION: Insert a table structure into OSL table list. | ||
305 | * | ||
306 | *****************************************************************************/ | ||
307 | |||
308 | static acpi_status osl_add_table_to_list(char *signature, u32 instance) | ||
309 | { | ||
310 | struct osl_table_info *new_info; | ||
311 | struct osl_table_info *next; | ||
312 | u32 next_instance = 0; | ||
313 | u8 found = FALSE; | ||
314 | |||
315 | new_info = calloc(1, sizeof(struct osl_table_info)); | ||
316 | if (!new_info) { | ||
317 | return (AE_NO_MEMORY); | ||
318 | } | ||
319 | |||
320 | ACPI_MOVE_NAME(new_info->signature, signature); | ||
321 | |||
322 | if (!gbl_table_list_head) { | ||
323 | gbl_table_list_head = new_info; | ||
324 | } else { | ||
325 | next = gbl_table_list_head; | ||
326 | while (1) { | ||
327 | if (ACPI_COMPARE_NAME(next->signature, signature)) { | ||
328 | if (next->instance == instance) { | ||
329 | found = TRUE; | ||
330 | } | ||
331 | if (next->instance >= next_instance) { | ||
332 | next_instance = next->instance + 1; | ||
333 | } | ||
334 | } | ||
335 | |||
336 | if (!next->next) { | ||
337 | break; | ||
338 | } | ||
339 | next = next->next; | ||
340 | } | ||
341 | next->next = new_info; | ||
342 | } | ||
343 | |||
344 | if (found) { | ||
345 | if (instance) { | ||
346 | fprintf(stderr, | ||
347 | "%4.4s: Warning unmatched table instance %d, expected %d\n", | ||
348 | signature, instance, next_instance); | ||
349 | } | ||
350 | instance = next_instance; | ||
351 | } | ||
352 | |||
353 | new_info->instance = instance; | ||
354 | gbl_table_count++; | ||
355 | |||
356 | return (AE_OK); | ||
357 | } | ||
358 | |||
359 | /****************************************************************************** | ||
360 | * | ||
361 | * FUNCTION: acpi_os_get_table_by_index | ||
362 | * | ||
363 | * PARAMETERS: index - Which table to get | ||
364 | * table - Where a pointer to the table is returned | ||
365 | * instance - Where a pointer to the table instance no. is | ||
366 | * returned | ||
367 | * address - Where the table physical address is returned | ||
368 | * | ||
369 | * RETURN: Status; Table buffer and physical address returned if AE_OK. | ||
370 | * AE_LIMIT: Index is beyond valid limit | ||
371 | * | ||
372 | * DESCRIPTION: Get an ACPI table via an index value (0 through n). Returns | ||
373 | * AE_LIMIT when an invalid index is reached. Index is not | ||
374 | * necessarily an index into the RSDT/XSDT. | ||
375 | * | ||
376 | *****************************************************************************/ | ||
377 | |||
378 | acpi_status | ||
379 | acpi_os_get_table_by_index(u32 index, | ||
380 | struct acpi_table_header ** table, | ||
381 | u32 *instance, acpi_physical_address * address) | ||
382 | { | ||
383 | struct osl_table_info *info; | ||
384 | acpi_status status; | ||
385 | u32 i; | ||
386 | |||
387 | /* Get main ACPI tables from memory on first invocation of this function */ | ||
388 | |||
389 | status = osl_table_initialize(); | ||
390 | if (ACPI_FAILURE(status)) { | ||
391 | return (status); | ||
392 | } | ||
393 | |||
394 | /* Validate Index */ | ||
395 | |||
396 | if (index >= gbl_table_count) { | ||
397 | return (AE_LIMIT); | ||
398 | } | ||
399 | |||
400 | /* Point to the table list entry specified by the Index argument */ | ||
401 | |||
402 | info = gbl_table_list_head; | ||
403 | for (i = 0; i < index; i++) { | ||
404 | info = info->next; | ||
405 | } | ||
406 | |||
407 | /* Now we can just get the table via the signature */ | ||
408 | |||
409 | status = acpi_os_get_table_by_name(info->signature, info->instance, | ||
410 | table, address); | ||
411 | |||
412 | if (ACPI_SUCCESS(status)) { | ||
413 | *instance = info->instance; | ||
414 | } | ||
415 | return (status); | ||
416 | } | ||
417 | |||
418 | /****************************************************************************** | ||
419 | * | ||
420 | * FUNCTION: osl_find_rsdp_via_efi | ||
421 | * | ||
422 | * PARAMETERS: None | ||
423 | * | ||
424 | * RETURN: RSDP address if found | ||
425 | * | ||
426 | * DESCRIPTION: Find RSDP address via EFI. | ||
427 | * | ||
428 | *****************************************************************************/ | ||
429 | |||
430 | static acpi_physical_address osl_find_rsdp_via_efi(void) | ||
431 | { | ||
432 | FILE *file; | ||
433 | char buffer[80]; | ||
434 | unsigned long address = 0; | ||
435 | |||
436 | file = fopen(EFI_SYSTAB, "r"); | ||
437 | if (file) { | ||
438 | while (fgets(buffer, 80, file)) { | ||
439 | if (sscanf(buffer, "ACPI20=0x%lx", &address) == 1) { | ||
440 | break; | ||
441 | } | ||
442 | } | ||
443 | fclose(file); | ||
444 | } | ||
445 | |||
446 | return ((acpi_physical_address) (address)); | ||
447 | } | ||
448 | |||
449 | /****************************************************************************** | ||
450 | * | ||
451 | * FUNCTION: osl_load_rsdp | ||
452 | * | ||
453 | * PARAMETERS: None | ||
454 | * | ||
455 | * RETURN: Status | ||
456 | * | ||
457 | * DESCRIPTION: Scan and load RSDP. | ||
458 | * | ||
459 | *****************************************************************************/ | ||
460 | |||
461 | static acpi_status osl_load_rsdp(void) | ||
462 | { | ||
463 | struct acpi_table_header *mapped_table; | ||
464 | u8 *rsdp_address; | ||
465 | acpi_physical_address rsdp_base; | ||
466 | acpi_size rsdp_size; | ||
467 | |||
468 | /* Get RSDP from memory */ | ||
469 | |||
470 | rsdp_size = sizeof(struct acpi_table_rsdp); | ||
471 | if (gbl_rsdp_base) { | ||
472 | rsdp_base = gbl_rsdp_base; | ||
473 | } else { | ||
474 | rsdp_base = osl_find_rsdp_via_efi(); | ||
475 | } | ||
476 | |||
477 | if (!rsdp_base) { | ||
478 | rsdp_base = ACPI_HI_RSDP_WINDOW_BASE; | ||
479 | rsdp_size = ACPI_HI_RSDP_WINDOW_SIZE; | ||
480 | } | ||
481 | |||
482 | rsdp_address = acpi_os_map_memory(rsdp_base, rsdp_size); | ||
483 | if (!rsdp_address) { | ||
484 | return (osl_get_last_status(AE_BAD_ADDRESS)); | ||
485 | } | ||
486 | |||
487 | /* Search low memory for the RSDP */ | ||
488 | |||
489 | mapped_table = ACPI_CAST_PTR(struct acpi_table_header, | ||
490 | acpi_tb_scan_memory_for_rsdp(rsdp_address, | ||
491 | rsdp_size)); | ||
492 | if (!mapped_table) { | ||
493 | acpi_os_unmap_memory(rsdp_address, rsdp_size); | ||
494 | return (AE_NOT_FOUND); | ||
495 | } | ||
496 | |||
497 | gbl_rsdp_address = | ||
498 | rsdp_base + (ACPI_CAST8(mapped_table) - rsdp_address); | ||
499 | |||
500 | ACPI_MEMCPY(&gbl_rsdp, mapped_table, sizeof(struct acpi_table_rsdp)); | ||
501 | acpi_os_unmap_memory(rsdp_address, rsdp_size); | ||
502 | |||
503 | return (AE_OK); | ||
504 | } | ||
505 | |||
506 | /****************************************************************************** | ||
507 | * | ||
508 | * FUNCTION: osl_can_use_xsdt | ||
509 | * | ||
510 | * PARAMETERS: None | ||
511 | * | ||
512 | * RETURN: TRUE if XSDT is allowed to be used. | ||
513 | * | ||
514 | * DESCRIPTION: This function collects logic that can be used to determine if | ||
515 | * XSDT should be used instead of RSDT. | ||
516 | * | ||
517 | *****************************************************************************/ | ||
518 | |||
519 | static u8 osl_can_use_xsdt(void) | ||
520 | { | ||
521 | if (gbl_revision && !acpi_gbl_do_not_use_xsdt) { | ||
522 | return (TRUE); | ||
523 | } else { | ||
524 | return (FALSE); | ||
525 | } | ||
526 | } | ||
527 | |||
528 | /****************************************************************************** | ||
529 | * | ||
530 | * FUNCTION: osl_table_initialize | ||
531 | * | ||
532 | * PARAMETERS: None | ||
533 | * | ||
534 | * RETURN: Status | ||
535 | * | ||
536 | * DESCRIPTION: Initialize ACPI table data. Get and store main ACPI tables to | ||
537 | * local variables. Main ACPI tables include RSDT, FADT, RSDT, | ||
538 | * and/or XSDT. | ||
539 | * | ||
540 | *****************************************************************************/ | ||
541 | |||
542 | static acpi_status osl_table_initialize(void) | ||
543 | { | ||
544 | acpi_status status; | ||
545 | acpi_physical_address address; | ||
546 | |||
547 | if (gbl_table_list_initialized) { | ||
548 | return (AE_OK); | ||
549 | } | ||
550 | |||
551 | /* Get RSDP from memory */ | ||
552 | |||
553 | status = osl_load_rsdp(); | ||
554 | if (ACPI_FAILURE(status)) { | ||
555 | return (status); | ||
556 | } | ||
557 | |||
558 | /* Get XSDT from memory */ | ||
559 | |||
560 | if (gbl_rsdp.revision && !gbl_do_not_dump_xsdt) { | ||
561 | if (gbl_xsdt) { | ||
562 | free(gbl_xsdt); | ||
563 | gbl_xsdt = NULL; | ||
564 | } | ||
565 | |||
566 | gbl_revision = 2; | ||
567 | status = osl_get_bios_table(ACPI_SIG_XSDT, 0, | ||
568 | ACPI_CAST_PTR(struct | ||
569 | acpi_table_header *, | ||
570 | &gbl_xsdt), &address); | ||
571 | if (ACPI_FAILURE(status)) { | ||
572 | return (status); | ||
573 | } | ||
574 | } | ||
575 | |||
576 | /* Get RSDT from memory */ | ||
577 | |||
578 | if (gbl_rsdp.rsdt_physical_address) { | ||
579 | if (gbl_rsdt) { | ||
580 | free(gbl_rsdt); | ||
581 | gbl_rsdt = NULL; | ||
582 | } | ||
583 | |||
584 | status = osl_get_bios_table(ACPI_SIG_RSDT, 0, | ||
585 | ACPI_CAST_PTR(struct | ||
586 | acpi_table_header *, | ||
587 | &gbl_rsdt), &address); | ||
588 | if (ACPI_FAILURE(status)) { | ||
589 | return (status); | ||
590 | } | ||
591 | } | ||
592 | |||
593 | /* Get FADT from memory */ | ||
594 | |||
595 | if (gbl_fadt) { | ||
596 | free(gbl_fadt); | ||
597 | gbl_fadt = NULL; | ||
598 | } | ||
599 | |||
600 | status = osl_get_bios_table(ACPI_SIG_FADT, 0, | ||
601 | ACPI_CAST_PTR(struct acpi_table_header *, | ||
602 | &gbl_fadt), | ||
603 | &gbl_fadt_address); | ||
604 | if (ACPI_FAILURE(status)) { | ||
605 | return (status); | ||
606 | } | ||
607 | |||
608 | if (!gbl_dump_customized_tables) { | ||
609 | |||
610 | /* Add mandatory tables to global table list first */ | ||
611 | |||
612 | status = osl_add_table_to_list(ACPI_RSDP_NAME, 0); | ||
613 | if (ACPI_FAILURE(status)) { | ||
614 | return (status); | ||
615 | } | ||
616 | |||
617 | status = osl_add_table_to_list(ACPI_SIG_RSDT, 0); | ||
618 | if (ACPI_FAILURE(status)) { | ||
619 | return (status); | ||
620 | } | ||
621 | |||
622 | if (gbl_revision == 2) { | ||
623 | status = osl_add_table_to_list(ACPI_SIG_XSDT, 0); | ||
624 | if (ACPI_FAILURE(status)) { | ||
625 | return (status); | ||
626 | } | ||
627 | } | ||
628 | |||
629 | status = osl_add_table_to_list(ACPI_SIG_DSDT, 0); | ||
630 | if (ACPI_FAILURE(status)) { | ||
631 | return (status); | ||
632 | } | ||
633 | |||
634 | status = osl_add_table_to_list(ACPI_SIG_FACS, 0); | ||
635 | if (ACPI_FAILURE(status)) { | ||
636 | return (status); | ||
637 | } | ||
638 | |||
639 | /* Add all tables found in the memory */ | ||
640 | |||
641 | status = osl_list_bios_tables(); | ||
642 | if (ACPI_FAILURE(status)) { | ||
643 | return (status); | ||
644 | } | ||
645 | } else { | ||
646 | /* Add all tables found in the static directory */ | ||
647 | |||
648 | status = osl_list_customized_tables(STATIC_TABLE_DIR); | ||
649 | if (ACPI_FAILURE(status)) { | ||
650 | return (status); | ||
651 | } | ||
652 | } | ||
653 | |||
654 | if (gbl_dump_dynamic_tables) { | ||
655 | |||
656 | /* Add all dynamically loaded tables in the dynamic directory */ | ||
657 | |||
658 | status = osl_list_customized_tables(DYNAMIC_TABLE_DIR); | ||
659 | if (ACPI_FAILURE(status)) { | ||
660 | return (status); | ||
661 | } | ||
662 | } | ||
663 | |||
664 | gbl_table_list_initialized = TRUE; | ||
665 | return (AE_OK); | ||
666 | } | ||
667 | |||
668 | /****************************************************************************** | ||
669 | * | ||
670 | * FUNCTION: osl_list_bios_tables | ||
671 | * | ||
672 | * PARAMETERS: None | ||
673 | * | ||
674 | * RETURN: Status; Table list is initialized if AE_OK. | ||
675 | * | ||
676 | * DESCRIPTION: Add ACPI tables to the table list from memory. | ||
677 | * | ||
678 | * NOTE: This works on Linux as table customization does not modify the | ||
679 | * addresses stored in RSDP/RSDT/XSDT/FADT. | ||
680 | * | ||
681 | *****************************************************************************/ | ||
682 | |||
683 | static acpi_status osl_list_bios_tables(void) | ||
684 | { | ||
685 | struct acpi_table_header *mapped_table = NULL; | ||
686 | u8 *table_data; | ||
687 | u8 number_of_tables; | ||
688 | u8 item_size; | ||
689 | acpi_physical_address table_address = 0; | ||
690 | acpi_status status = AE_OK; | ||
691 | u32 i; | ||
692 | |||
693 | if (osl_can_use_xsdt()) { | ||
694 | item_size = sizeof(u64); | ||
695 | table_data = | ||
696 | ACPI_CAST8(gbl_xsdt) + sizeof(struct acpi_table_header); | ||
697 | number_of_tables = | ||
698 | (u8)((gbl_xsdt->header.length - | ||
699 | sizeof(struct acpi_table_header)) | ||
700 | / item_size); | ||
701 | } else { /* Use RSDT if XSDT is not available */ | ||
702 | |||
703 | item_size = sizeof(u32); | ||
704 | table_data = | ||
705 | ACPI_CAST8(gbl_rsdt) + sizeof(struct acpi_table_header); | ||
706 | number_of_tables = | ||
707 | (u8)((gbl_rsdt->header.length - | ||
708 | sizeof(struct acpi_table_header)) | ||
709 | / item_size); | ||
710 | } | ||
711 | |||
712 | /* Search RSDT/XSDT for the requested table */ | ||
713 | |||
714 | for (i = 0; i < number_of_tables; ++i, table_data += item_size) { | ||
715 | if (osl_can_use_xsdt()) { | ||
716 | table_address = | ||
717 | (acpi_physical_address) (*ACPI_CAST64(table_data)); | ||
718 | } else { | ||
719 | table_address = | ||
720 | (acpi_physical_address) (*ACPI_CAST32(table_data)); | ||
721 | } | ||
722 | |||
723 | /* Skip NULL entries in RSDT/XSDT */ | ||
724 | |||
725 | if (!table_address) { | ||
726 | continue; | ||
727 | } | ||
728 | |||
729 | status = osl_map_table(table_address, NULL, &mapped_table); | ||
730 | if (ACPI_FAILURE(status)) { | ||
731 | return (status); | ||
732 | } | ||
733 | |||
734 | osl_add_table_to_list(mapped_table->signature, 0); | ||
735 | osl_unmap_table(mapped_table); | ||
736 | } | ||
737 | |||
738 | return (AE_OK); | ||
739 | } | ||
740 | |||
741 | /****************************************************************************** | ||
742 | * | ||
743 | * FUNCTION: osl_get_bios_table | ||
744 | * | ||
745 | * PARAMETERS: signature - ACPI Signature for common table. Must be | ||
746 | * a null terminated 4-character string. | ||
747 | * instance - Multiple table support for SSDT/UEFI (0...n) | ||
748 | * Must be 0 for other tables. | ||
749 | * table - Where a pointer to the table is returned | ||
750 | * address - Where the table physical address is returned | ||
751 | * | ||
752 | * RETURN: Status; Table buffer and physical address returned if AE_OK. | ||
753 | * AE_LIMIT: Instance is beyond valid limit | ||
754 | * AE_NOT_FOUND: A table with the signature was not found | ||
755 | * | ||
756 | * DESCRIPTION: Get a BIOS provided ACPI table | ||
757 | * | ||
758 | * NOTE: Assumes the input signature is uppercase. | ||
759 | * | ||
760 | *****************************************************************************/ | ||
761 | |||
762 | static acpi_status | ||
763 | osl_get_bios_table(char *signature, | ||
764 | u32 instance, | ||
765 | struct acpi_table_header **table, | ||
766 | acpi_physical_address * address) | ||
767 | { | ||
768 | struct acpi_table_header *local_table = NULL; | ||
769 | struct acpi_table_header *mapped_table = NULL; | ||
770 | u8 *table_data; | ||
771 | u8 number_of_tables; | ||
772 | u8 item_size; | ||
773 | u32 current_instance = 0; | ||
774 | acpi_physical_address table_address = 0; | ||
775 | u32 table_length = 0; | ||
776 | acpi_status status = AE_OK; | ||
777 | u32 i; | ||
778 | |||
779 | /* Handle special tables whose addresses are not in RSDT/XSDT */ | ||
780 | |||
781 | if (ACPI_COMPARE_NAME(signature, ACPI_RSDP_NAME) || | ||
782 | ACPI_COMPARE_NAME(signature, ACPI_SIG_RSDT) || | ||
783 | ACPI_COMPARE_NAME(signature, ACPI_SIG_XSDT) || | ||
784 | ACPI_COMPARE_NAME(signature, ACPI_SIG_DSDT) || | ||
785 | ACPI_COMPARE_NAME(signature, ACPI_SIG_FACS)) { | ||
786 | if (instance > 0) { | ||
787 | return (AE_LIMIT); | ||
788 | } | ||
789 | |||
790 | /* | ||
791 | * Get the appropriate address, either 32-bit or 64-bit. Be very | ||
792 | * careful about the FADT length and validate table addresses. | ||
793 | * Note: The 64-bit addresses have priority. | ||
794 | */ | ||
795 | if (ACPI_COMPARE_NAME(signature, ACPI_SIG_DSDT)) { | ||
796 | if ((gbl_fadt->header.length >= MIN_FADT_FOR_XDSDT) && | ||
797 | gbl_fadt->Xdsdt) { | ||
798 | table_address = | ||
799 | (acpi_physical_address) gbl_fadt->Xdsdt; | ||
800 | } else | ||
801 | if ((gbl_fadt->header.length >= MIN_FADT_FOR_DSDT) | ||
802 | && gbl_fadt->dsdt) { | ||
803 | table_address = | ||
804 | (acpi_physical_address) gbl_fadt->dsdt; | ||
805 | } | ||
806 | } else if (ACPI_COMPARE_NAME(signature, ACPI_SIG_FACS)) { | ||
807 | if ((gbl_fadt->header.length >= MIN_FADT_FOR_XFACS) && | ||
808 | gbl_fadt->Xfacs) { | ||
809 | table_address = | ||
810 | (acpi_physical_address) gbl_fadt->Xfacs; | ||
811 | } else | ||
812 | if ((gbl_fadt->header.length >= MIN_FADT_FOR_FACS) | ||
813 | && gbl_fadt->facs) { | ||
814 | table_address = | ||
815 | (acpi_physical_address) gbl_fadt->facs; | ||
816 | } | ||
817 | } else if (ACPI_COMPARE_NAME(signature, ACPI_SIG_XSDT)) { | ||
818 | if (!gbl_revision) { | ||
819 | return (AE_BAD_SIGNATURE); | ||
820 | } | ||
821 | table_address = | ||
822 | (acpi_physical_address) gbl_rsdp. | ||
823 | xsdt_physical_address; | ||
824 | } else if (ACPI_COMPARE_NAME(signature, ACPI_SIG_RSDT)) { | ||
825 | table_address = | ||
826 | (acpi_physical_address) gbl_rsdp. | ||
827 | rsdt_physical_address; | ||
828 | } else { | ||
829 | table_address = | ||
830 | (acpi_physical_address) gbl_rsdp_address; | ||
831 | signature = ACPI_SIG_RSDP; | ||
832 | } | ||
833 | |||
834 | /* Now we can get the requested special table */ | ||
835 | |||
836 | status = osl_map_table(table_address, signature, &mapped_table); | ||
837 | if (ACPI_FAILURE(status)) { | ||
838 | return (status); | ||
839 | } | ||
840 | |||
841 | table_length = ap_get_table_length(mapped_table); | ||
842 | } else { /* Case for a normal ACPI table */ | ||
843 | |||
844 | if (osl_can_use_xsdt()) { | ||
845 | item_size = sizeof(u64); | ||
846 | table_data = | ||
847 | ACPI_CAST8(gbl_xsdt) + | ||
848 | sizeof(struct acpi_table_header); | ||
849 | number_of_tables = | ||
850 | (u8)((gbl_xsdt->header.length - | ||
851 | sizeof(struct acpi_table_header)) | ||
852 | / item_size); | ||
853 | } else { /* Use RSDT if XSDT is not available */ | ||
854 | |||
855 | item_size = sizeof(u32); | ||
856 | table_data = | ||
857 | ACPI_CAST8(gbl_rsdt) + | ||
858 | sizeof(struct acpi_table_header); | ||
859 | number_of_tables = | ||
860 | (u8)((gbl_rsdt->header.length - | ||
861 | sizeof(struct acpi_table_header)) | ||
862 | / item_size); | ||
863 | } | ||
864 | |||
865 | /* Search RSDT/XSDT for the requested table */ | ||
866 | |||
867 | for (i = 0; i < number_of_tables; ++i, table_data += item_size) { | ||
868 | if (osl_can_use_xsdt()) { | ||
869 | table_address = | ||
870 | (acpi_physical_address) (*ACPI_CAST64 | ||
871 | (table_data)); | ||
872 | } else { | ||
873 | table_address = | ||
874 | (acpi_physical_address) (*ACPI_CAST32 | ||
875 | (table_data)); | ||
876 | } | ||
877 | |||
878 | /* Skip NULL entries in RSDT/XSDT */ | ||
879 | |||
880 | if (!table_address) { | ||
881 | continue; | ||
882 | } | ||
883 | |||
884 | status = | ||
885 | osl_map_table(table_address, NULL, &mapped_table); | ||
886 | if (ACPI_FAILURE(status)) { | ||
887 | return (status); | ||
888 | } | ||
889 | table_length = mapped_table->length; | ||
890 | |||
891 | /* Does this table match the requested signature? */ | ||
892 | |||
893 | if (!ACPI_COMPARE_NAME | ||
894 | (mapped_table->signature, signature)) { | ||
895 | osl_unmap_table(mapped_table); | ||
896 | mapped_table = NULL; | ||
897 | continue; | ||
898 | } | ||
899 | |||
900 | /* Match table instance (for SSDT/UEFI tables) */ | ||
901 | |||
902 | if (current_instance != instance) { | ||
903 | osl_unmap_table(mapped_table); | ||
904 | mapped_table = NULL; | ||
905 | current_instance++; | ||
906 | continue; | ||
907 | } | ||
908 | |||
909 | break; | ||
910 | } | ||
911 | } | ||
912 | |||
913 | if (!mapped_table) { | ||
914 | return (AE_LIMIT); | ||
915 | } | ||
916 | |||
917 | if (table_length == 0) { | ||
918 | status = AE_BAD_HEADER; | ||
919 | goto exit; | ||
920 | } | ||
921 | |||
922 | /* Copy table to local buffer and return it */ | ||
923 | |||
924 | local_table = calloc(1, table_length); | ||
925 | if (!local_table) { | ||
926 | status = AE_NO_MEMORY; | ||
927 | goto exit; | ||
928 | } | ||
929 | |||
930 | ACPI_MEMCPY(local_table, mapped_table, table_length); | ||
931 | *address = table_address; | ||
932 | *table = local_table; | ||
933 | |||
934 | exit: | ||
935 | osl_unmap_table(mapped_table); | ||
936 | return (status); | ||
937 | } | ||
938 | |||
939 | /****************************************************************************** | ||
940 | * | ||
941 | * FUNCTION: osl_list_customized_tables | ||
942 | * | ||
943 | * PARAMETERS: directory - Directory that contains the tables | ||
944 | * | ||
945 | * RETURN: Status; Table list is initialized if AE_OK. | ||
946 | * | ||
947 | * DESCRIPTION: Add ACPI tables to the table list from a directory. | ||
948 | * | ||
949 | *****************************************************************************/ | ||
950 | |||
951 | static acpi_status osl_list_customized_tables(char *directory) | ||
952 | { | ||
953 | void *table_dir; | ||
954 | u32 instance; | ||
955 | char temp_name[ACPI_NAME_SIZE]; | ||
956 | char *filename; | ||
957 | acpi_status status = AE_OK; | ||
958 | |||
959 | /* Open the requested directory */ | ||
960 | |||
961 | table_dir = acpi_os_open_directory(directory, "*", REQUEST_FILE_ONLY); | ||
962 | if (!table_dir) { | ||
963 | return (osl_get_last_status(AE_NOT_FOUND)); | ||
964 | } | ||
965 | |||
966 | /* Examine all entries in this directory */ | ||
967 | |||
968 | while ((filename = acpi_os_get_next_filename(table_dir))) { | ||
969 | |||
970 | /* Extract table name and instance number */ | ||
971 | |||
972 | status = | ||
973 | osl_table_name_from_file(filename, temp_name, &instance); | ||
974 | |||
975 | /* Ignore meaningless files */ | ||
976 | |||
977 | if (ACPI_FAILURE(status)) { | ||
978 | continue; | ||
979 | } | ||
980 | |||
981 | /* Add new info node to global table list */ | ||
982 | |||
983 | status = osl_add_table_to_list(temp_name, instance); | ||
984 | if (ACPI_FAILURE(status)) { | ||
985 | break; | ||
986 | } | ||
987 | } | ||
988 | |||
989 | acpi_os_close_directory(table_dir); | ||
990 | return (status); | ||
991 | } | ||
992 | |||
993 | /****************************************************************************** | ||
994 | * | ||
995 | * FUNCTION: osl_map_table | ||
996 | * | ||
997 | * PARAMETERS: address - Address of the table in memory | ||
998 | * signature - Optional ACPI Signature for desired table. | ||
999 | * Null terminated 4-character string. | ||
1000 | * table - Where a pointer to the mapped table is | ||
1001 | * returned | ||
1002 | * | ||
1003 | * RETURN: Status; Mapped table is returned if AE_OK. | ||
1004 | * AE_NOT_FOUND: A valid table was not found at the address | ||
1005 | * | ||
1006 | * DESCRIPTION: Map entire ACPI table into caller's address space. | ||
1007 | * | ||
1008 | *****************************************************************************/ | ||
1009 | |||
1010 | static acpi_status | ||
1011 | osl_map_table(acpi_size address, | ||
1012 | char *signature, struct acpi_table_header **table) | ||
1013 | { | ||
1014 | struct acpi_table_header *mapped_table; | ||
1015 | u32 length; | ||
1016 | |||
1017 | if (!address) { | ||
1018 | return (AE_BAD_ADDRESS); | ||
1019 | } | ||
1020 | |||
1021 | /* | ||
1022 | * Map the header so we can get the table length. | ||
1023 | * Use sizeof (struct acpi_table_header) as: | ||
1024 | * 1. it is bigger than 24 to include RSDP->Length | ||
1025 | * 2. it is smaller than sizeof (struct acpi_table_rsdp) | ||
1026 | */ | ||
1027 | mapped_table = | ||
1028 | acpi_os_map_memory(address, sizeof(struct acpi_table_header)); | ||
1029 | if (!mapped_table) { | ||
1030 | fprintf(stderr, "Could not map table header at 0x%8.8X%8.8X\n", | ||
1031 | ACPI_FORMAT_UINT64(address)); | ||
1032 | return (osl_get_last_status(AE_BAD_ADDRESS)); | ||
1033 | } | ||
1034 | |||
1035 | /* If specified, signature must match */ | ||
1036 | |||
1037 | if (signature) { | ||
1038 | if (ACPI_VALIDATE_RSDP_SIG(signature)) { | ||
1039 | if (!ACPI_VALIDATE_RSDP_SIG(mapped_table->signature)) { | ||
1040 | acpi_os_unmap_memory(mapped_table, | ||
1041 | sizeof(struct | ||
1042 | acpi_table_header)); | ||
1043 | return (AE_BAD_SIGNATURE); | ||
1044 | } | ||
1045 | } else | ||
1046 | if (!ACPI_COMPARE_NAME(signature, mapped_table->signature)) | ||
1047 | { | ||
1048 | acpi_os_unmap_memory(mapped_table, | ||
1049 | sizeof(struct acpi_table_header)); | ||
1050 | return (AE_BAD_SIGNATURE); | ||
1051 | } | ||
1052 | } | ||
1053 | |||
1054 | /* Map the entire table */ | ||
1055 | |||
1056 | length = ap_get_table_length(mapped_table); | ||
1057 | acpi_os_unmap_memory(mapped_table, sizeof(struct acpi_table_header)); | ||
1058 | if (length == 0) { | ||
1059 | return (AE_BAD_HEADER); | ||
1060 | } | ||
1061 | |||
1062 | mapped_table = acpi_os_map_memory(address, length); | ||
1063 | if (!mapped_table) { | ||
1064 | fprintf(stderr, | ||
1065 | "Could not map table at 0x%8.8X%8.8X length %8.8X\n", | ||
1066 | ACPI_FORMAT_UINT64(address), length); | ||
1067 | return (osl_get_last_status(AE_INVALID_TABLE_LENGTH)); | ||
1068 | } | ||
1069 | |||
1070 | (void)ap_is_valid_checksum(mapped_table); | ||
1071 | |||
1072 | *table = mapped_table; | ||
1073 | return (AE_OK); | ||
1074 | } | ||
1075 | |||
1076 | /****************************************************************************** | ||
1077 | * | ||
1078 | * FUNCTION: osl_unmap_table | ||
1079 | * | ||
1080 | * PARAMETERS: table - A pointer to the mapped table | ||
1081 | * | ||
1082 | * RETURN: None | ||
1083 | * | ||
1084 | * DESCRIPTION: Unmap entire ACPI table. | ||
1085 | * | ||
1086 | *****************************************************************************/ | ||
1087 | |||
1088 | static void osl_unmap_table(struct acpi_table_header *table) | ||
1089 | { | ||
1090 | if (table) { | ||
1091 | acpi_os_unmap_memory(table, ap_get_table_length(table)); | ||
1092 | } | ||
1093 | } | ||
1094 | |||
1095 | /****************************************************************************** | ||
1096 | * | ||
1097 | * FUNCTION: osl_table_name_from_file | ||
1098 | * | ||
1099 | * PARAMETERS: filename - File that contains the desired table | ||
1100 | * signature - Pointer to 4-character buffer to store | ||
1101 | * extracted table signature. | ||
1102 | * instance - Pointer to integer to store extracted | ||
1103 | * table instance number. | ||
1104 | * | ||
1105 | * RETURN: Status; Table name is extracted if AE_OK. | ||
1106 | * | ||
1107 | * DESCRIPTION: Extract table signature and instance number from a table file | ||
1108 | * name. | ||
1109 | * | ||
1110 | *****************************************************************************/ | ||
1111 | |||
1112 | static acpi_status | ||
1113 | osl_table_name_from_file(char *filename, char *signature, u32 *instance) | ||
1114 | { | ||
1115 | |||
1116 | /* Ignore meaningless files */ | ||
1117 | |||
1118 | if (strlen(filename) < ACPI_NAME_SIZE) { | ||
1119 | return (AE_BAD_SIGNATURE); | ||
1120 | } | ||
1121 | |||
1122 | /* Extract instance number */ | ||
1123 | |||
1124 | if (isdigit((int)filename[ACPI_NAME_SIZE])) { | ||
1125 | sscanf(&filename[ACPI_NAME_SIZE], "%d", instance); | ||
1126 | } else if (strlen(filename) != ACPI_NAME_SIZE) { | ||
1127 | return (AE_BAD_SIGNATURE); | ||
1128 | } else { | ||
1129 | *instance = 0; | ||
1130 | } | ||
1131 | |||
1132 | /* Extract signature */ | ||
1133 | |||
1134 | ACPI_MOVE_NAME(signature, filename); | ||
1135 | return (AE_OK); | ||
1136 | } | ||
1137 | |||
1138 | /****************************************************************************** | ||
1139 | * | ||
1140 | * FUNCTION: osl_read_table_from_file | ||
1141 | * | ||
1142 | * PARAMETERS: filename - File that contains the desired table | ||
1143 | * file_offset - Offset of the table in file | ||
1144 | * signature - Optional ACPI Signature for desired table. | ||
1145 | * A null terminated 4-character string. | ||
1146 | * table - Where a pointer to the table is returned | ||
1147 | * | ||
1148 | * RETURN: Status; Table buffer is returned if AE_OK. | ||
1149 | * | ||
1150 | * DESCRIPTION: Read a ACPI table from a file. | ||
1151 | * | ||
1152 | *****************************************************************************/ | ||
1153 | |||
1154 | static acpi_status | ||
1155 | osl_read_table_from_file(char *filename, | ||
1156 | acpi_size file_offset, | ||
1157 | char *signature, struct acpi_table_header **table) | ||
1158 | { | ||
1159 | FILE *table_file; | ||
1160 | struct acpi_table_header header; | ||
1161 | struct acpi_table_header *local_table = NULL; | ||
1162 | u32 table_length; | ||
1163 | s32 count; | ||
1164 | acpi_status status = AE_OK; | ||
1165 | |||
1166 | /* Open the file */ | ||
1167 | |||
1168 | table_file = fopen(filename, "rb"); | ||
1169 | if (table_file == NULL) { | ||
1170 | fprintf(stderr, "Could not open table file: %s\n", filename); | ||
1171 | return (osl_get_last_status(AE_NOT_FOUND)); | ||
1172 | } | ||
1173 | |||
1174 | fseek(table_file, file_offset, SEEK_SET); | ||
1175 | |||
1176 | /* Read the Table header to get the table length */ | ||
1177 | |||
1178 | count = fread(&header, 1, sizeof(struct acpi_table_header), table_file); | ||
1179 | if (count != sizeof(struct acpi_table_header)) { | ||
1180 | fprintf(stderr, "Could not read table header: %s\n", filename); | ||
1181 | status = AE_BAD_HEADER; | ||
1182 | goto exit; | ||
1183 | } | ||
1184 | |||
1185 | /* If signature is specified, it must match the table */ | ||
1186 | |||
1187 | if (signature) { | ||
1188 | if (ACPI_VALIDATE_RSDP_SIG(signature)) { | ||
1189 | if (!ACPI_VALIDATE_RSDP_SIG(header.signature)) { | ||
1190 | fprintf(stderr, | ||
1191 | "Incorrect RSDP signature: found %8.8s\n", | ||
1192 | header.signature); | ||
1193 | status = AE_BAD_SIGNATURE; | ||
1194 | goto exit; | ||
1195 | } | ||
1196 | } else if (!ACPI_COMPARE_NAME(signature, header.signature)) { | ||
1197 | fprintf(stderr, | ||
1198 | "Incorrect signature: Expecting %4.4s, found %4.4s\n", | ||
1199 | signature, header.signature); | ||
1200 | status = AE_BAD_SIGNATURE; | ||
1201 | goto exit; | ||
1202 | } | ||
1203 | } | ||
1204 | |||
1205 | table_length = ap_get_table_length(&header); | ||
1206 | if (table_length == 0) { | ||
1207 | status = AE_BAD_HEADER; | ||
1208 | goto exit; | ||
1209 | } | ||
1210 | |||
1211 | /* Read the entire table into a local buffer */ | ||
1212 | |||
1213 | local_table = calloc(1, table_length); | ||
1214 | if (!local_table) { | ||
1215 | fprintf(stderr, | ||
1216 | "%4.4s: Could not allocate buffer for table of length %X\n", | ||
1217 | header.signature, table_length); | ||
1218 | status = AE_NO_MEMORY; | ||
1219 | goto exit; | ||
1220 | } | ||
1221 | |||
1222 | fseek(table_file, file_offset, SEEK_SET); | ||
1223 | |||
1224 | count = fread(local_table, 1, table_length, table_file); | ||
1225 | if (count != table_length) { | ||
1226 | fprintf(stderr, "%4.4s: Could not read table content\n", | ||
1227 | header.signature); | ||
1228 | status = AE_INVALID_TABLE_LENGTH; | ||
1229 | goto exit; | ||
1230 | } | ||
1231 | |||
1232 | /* Validate checksum */ | ||
1233 | |||
1234 | (void)ap_is_valid_checksum(local_table); | ||
1235 | |||
1236 | exit: | ||
1237 | fclose(table_file); | ||
1238 | *table = local_table; | ||
1239 | return (status); | ||
1240 | } | ||
1241 | |||
1242 | /****************************************************************************** | ||
1243 | * | ||
1244 | * FUNCTION: osl_get_customized_table | ||
1245 | * | ||
1246 | * PARAMETERS: pathname - Directory to find Linux customized table | ||
1247 | * signature - ACPI Signature for desired table. Must be | ||
1248 | * a null terminated 4-character string. | ||
1249 | * instance - Multiple table support for SSDT/UEFI (0...n) | ||
1250 | * Must be 0 for other tables. | ||
1251 | * table - Where a pointer to the table is returned | ||
1252 | * address - Where the table physical address is returned | ||
1253 | * | ||
1254 | * RETURN: Status; Table buffer is returned if AE_OK. | ||
1255 | * AE_LIMIT: Instance is beyond valid limit | ||
1256 | * AE_NOT_FOUND: A table with the signature was not found | ||
1257 | * | ||
1258 | * DESCRIPTION: Get an OS customized table. | ||
1259 | * | ||
1260 | *****************************************************************************/ | ||
1261 | |||
1262 | static acpi_status | ||
1263 | osl_get_customized_table(char *pathname, | ||
1264 | char *signature, | ||
1265 | u32 instance, | ||
1266 | struct acpi_table_header **table, | ||
1267 | acpi_physical_address * address) | ||
1268 | { | ||
1269 | void *table_dir; | ||
1270 | u32 current_instance = 0; | ||
1271 | char temp_name[ACPI_NAME_SIZE]; | ||
1272 | char table_filename[PATH_MAX]; | ||
1273 | char *filename; | ||
1274 | acpi_status status; | ||
1275 | |||
1276 | /* Open the directory for customized tables */ | ||
1277 | |||
1278 | table_dir = acpi_os_open_directory(pathname, "*", REQUEST_FILE_ONLY); | ||
1279 | if (!table_dir) { | ||
1280 | return (osl_get_last_status(AE_NOT_FOUND)); | ||
1281 | } | ||
1282 | |||
1283 | /* Attempt to find the table in the directory */ | ||
1284 | |||
1285 | while ((filename = acpi_os_get_next_filename(table_dir))) { | ||
1286 | |||
1287 | /* Ignore meaningless files */ | ||
1288 | |||
1289 | if (!ACPI_COMPARE_NAME(filename, signature)) { | ||
1290 | continue; | ||
1291 | } | ||
1292 | |||
1293 | /* Extract table name and instance number */ | ||
1294 | |||
1295 | status = | ||
1296 | osl_table_name_from_file(filename, temp_name, | ||
1297 | ¤t_instance); | ||
1298 | |||
1299 | /* Ignore meaningless files */ | ||
1300 | |||
1301 | if (ACPI_FAILURE(status) || current_instance != instance) { | ||
1302 | continue; | ||
1303 | } | ||
1304 | |||
1305 | /* Create the table pathname */ | ||
1306 | |||
1307 | if (instance != 0) { | ||
1308 | sprintf(table_filename, "%s/%4.4s%d", pathname, | ||
1309 | temp_name, instance); | ||
1310 | } else { | ||
1311 | sprintf(table_filename, "%s/%4.4s", pathname, | ||
1312 | temp_name); | ||
1313 | } | ||
1314 | break; | ||
1315 | } | ||
1316 | |||
1317 | acpi_os_close_directory(table_dir); | ||
1318 | |||
1319 | if (!filename) { | ||
1320 | return (AE_LIMIT); | ||
1321 | } | ||
1322 | |||
1323 | /* There is no physical address saved for customized tables, use zero */ | ||
1324 | |||
1325 | *address = 0; | ||
1326 | status = osl_read_table_from_file(table_filename, 0, NULL, table); | ||
1327 | |||
1328 | return (status); | ||
1329 | } | ||
diff --git a/tools/power/acpi/os_specific/service_layers/osunixdir.c b/tools/power/acpi/os_specific/service_layers/osunixdir.c new file mode 100644 index 000000000000..733f9e490fc4 --- /dev/null +++ b/tools/power/acpi/os_specific/service_layers/osunixdir.c | |||
@@ -0,0 +1,204 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: osunixdir - Unix directory access interfaces | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2014, 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 <acpi/acpi.h> | ||
45 | |||
46 | #include <stdio.h> | ||
47 | #include <stdlib.h> | ||
48 | #include <string.h> | ||
49 | #include <dirent.h> | ||
50 | #include <fnmatch.h> | ||
51 | #include <ctype.h> | ||
52 | #include <sys/stat.h> | ||
53 | |||
54 | /* | ||
55 | * Allocated structure returned from os_open_directory | ||
56 | */ | ||
57 | typedef struct external_find_info { | ||
58 | char *dir_pathname; | ||
59 | DIR *dir_ptr; | ||
60 | char temp_buffer[256]; | ||
61 | char *wildcard_spec; | ||
62 | char requested_file_type; | ||
63 | |||
64 | } external_find_info; | ||
65 | |||
66 | /******************************************************************************* | ||
67 | * | ||
68 | * FUNCTION: acpi_os_open_directory | ||
69 | * | ||
70 | * PARAMETERS: dir_pathname - Full pathname to the directory | ||
71 | * wildcard_spec - string of the form "*.c", etc. | ||
72 | * | ||
73 | * RETURN: A directory "handle" to be used in subsequent search operations. | ||
74 | * NULL returned on failure. | ||
75 | * | ||
76 | * DESCRIPTION: Open a directory in preparation for a wildcard search | ||
77 | * | ||
78 | ******************************************************************************/ | ||
79 | |||
80 | void *acpi_os_open_directory(char *dir_pathname, | ||
81 | char *wildcard_spec, char requested_file_type) | ||
82 | { | ||
83 | struct external_find_info *external_info; | ||
84 | DIR *dir; | ||
85 | |||
86 | /* Allocate the info struct that will be returned to the caller */ | ||
87 | |||
88 | external_info = calloc(1, sizeof(struct external_find_info)); | ||
89 | if (!external_info) { | ||
90 | return (NULL); | ||
91 | } | ||
92 | |||
93 | /* Get the directory stream */ | ||
94 | |||
95 | dir = opendir(dir_pathname); | ||
96 | if (!dir) { | ||
97 | fprintf(stderr, "Cannot open directory - %s\n", dir_pathname); | ||
98 | free(external_info); | ||
99 | return (NULL); | ||
100 | } | ||
101 | |||
102 | /* Save the info in the return structure */ | ||
103 | |||
104 | external_info->wildcard_spec = wildcard_spec; | ||
105 | external_info->requested_file_type = requested_file_type; | ||
106 | external_info->dir_pathname = dir_pathname; | ||
107 | external_info->dir_ptr = dir; | ||
108 | return (external_info); | ||
109 | } | ||
110 | |||
111 | /******************************************************************************* | ||
112 | * | ||
113 | * FUNCTION: acpi_os_get_next_filename | ||
114 | * | ||
115 | * PARAMETERS: dir_handle - Created via acpi_os_open_directory | ||
116 | * | ||
117 | * RETURN: Next filename matched. NULL if no more matches. | ||
118 | * | ||
119 | * DESCRIPTION: Get the next file in the directory that matches the wildcard | ||
120 | * specification. | ||
121 | * | ||
122 | ******************************************************************************/ | ||
123 | |||
124 | char *acpi_os_get_next_filename(void *dir_handle) | ||
125 | { | ||
126 | struct external_find_info *external_info = dir_handle; | ||
127 | struct dirent *dir_entry; | ||
128 | char *temp_str; | ||
129 | int str_len; | ||
130 | struct stat temp_stat; | ||
131 | int err; | ||
132 | |||
133 | while ((dir_entry = readdir(external_info->dir_ptr))) { | ||
134 | if (!fnmatch | ||
135 | (external_info->wildcard_spec, dir_entry->d_name, 0)) { | ||
136 | if (dir_entry->d_name[0] == '.') { | ||
137 | continue; | ||
138 | } | ||
139 | |||
140 | str_len = strlen(dir_entry->d_name) + | ||
141 | strlen(external_info->dir_pathname) + 2; | ||
142 | |||
143 | temp_str = calloc(str_len, 1); | ||
144 | if (!temp_str) { | ||
145 | fprintf(stderr, | ||
146 | "Could not allocate buffer for temporary string\n"); | ||
147 | return (NULL); | ||
148 | } | ||
149 | |||
150 | strcpy(temp_str, external_info->dir_pathname); | ||
151 | strcat(temp_str, "/"); | ||
152 | strcat(temp_str, dir_entry->d_name); | ||
153 | |||
154 | err = stat(temp_str, &temp_stat); | ||
155 | if (err == -1) { | ||
156 | fprintf(stderr, | ||
157 | "Cannot stat file (should not happen) - %s\n", | ||
158 | temp_str); | ||
159 | free(temp_str); | ||
160 | return (NULL); | ||
161 | } | ||
162 | |||
163 | free(temp_str); | ||
164 | |||
165 | if ((S_ISDIR(temp_stat.st_mode) | ||
166 | && (external_info->requested_file_type == | ||
167 | REQUEST_DIR_ONLY)) | ||
168 | || ((!S_ISDIR(temp_stat.st_mode) | ||
169 | && external_info->requested_file_type == | ||
170 | REQUEST_FILE_ONLY))) { | ||
171 | |||
172 | /* copy to a temp buffer because dir_entry struct is on the stack */ | ||
173 | |||
174 | strcpy(external_info->temp_buffer, | ||
175 | dir_entry->d_name); | ||
176 | return (external_info->temp_buffer); | ||
177 | } | ||
178 | } | ||
179 | } | ||
180 | |||
181 | return (NULL); | ||
182 | } | ||
183 | |||
184 | /******************************************************************************* | ||
185 | * | ||
186 | * FUNCTION: acpi_os_close_directory | ||
187 | * | ||
188 | * PARAMETERS: dir_handle - Created via acpi_os_open_directory | ||
189 | * | ||
190 | * RETURN: None. | ||
191 | * | ||
192 | * DESCRIPTION: Close the open directory and cleanup. | ||
193 | * | ||
194 | ******************************************************************************/ | ||
195 | |||
196 | void acpi_os_close_directory(void *dir_handle) | ||
197 | { | ||
198 | struct external_find_info *external_info = dir_handle; | ||
199 | |||
200 | /* Close the directory and free allocations */ | ||
201 | |||
202 | closedir(external_info->dir_ptr); | ||
203 | free(dir_handle); | ||
204 | } | ||
diff --git a/tools/power/acpi/os_specific/service_layers/osunixmap.c b/tools/power/acpi/os_specific/service_layers/osunixmap.c new file mode 100644 index 000000000000..99b47b6194a3 --- /dev/null +++ b/tools/power/acpi/os_specific/service_layers/osunixmap.c | |||
@@ -0,0 +1,151 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: osunixmap - Unix OSL for file mappings | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2014, 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 "acpidump.h" | ||
45 | #include <unistd.h> | ||
46 | #include <sys/mman.h> | ||
47 | #ifdef _free_BSD | ||
48 | #include <sys/param.h> | ||
49 | #endif | ||
50 | |||
51 | #define _COMPONENT ACPI_OS_SERVICES | ||
52 | ACPI_MODULE_NAME("osunixmap") | ||
53 | |||
54 | #ifndef O_BINARY | ||
55 | #define O_BINARY 0 | ||
56 | #endif | ||
57 | #ifdef _free_BSD | ||
58 | #define MMAP_FLAGS MAP_SHARED | ||
59 | #else | ||
60 | #define MMAP_FLAGS MAP_PRIVATE | ||
61 | #endif | ||
62 | #define SYSTEM_MEMORY "/dev/mem" | ||
63 | /******************************************************************************* | ||
64 | * | ||
65 | * FUNCTION: acpi_os_get_page_size | ||
66 | * | ||
67 | * PARAMETERS: None | ||
68 | * | ||
69 | * RETURN: Page size of the platform. | ||
70 | * | ||
71 | * DESCRIPTION: Obtain page size of the platform. | ||
72 | * | ||
73 | ******************************************************************************/ | ||
74 | static acpi_size acpi_os_get_page_size(void) | ||
75 | { | ||
76 | |||
77 | #ifdef PAGE_SIZE | ||
78 | return PAGE_SIZE; | ||
79 | #else | ||
80 | return sysconf(_SC_PAGESIZE); | ||
81 | #endif | ||
82 | } | ||
83 | |||
84 | /****************************************************************************** | ||
85 | * | ||
86 | * FUNCTION: acpi_os_map_memory | ||
87 | * | ||
88 | * PARAMETERS: where - Physical address of memory to be mapped | ||
89 | * length - How much memory to map | ||
90 | * | ||
91 | * RETURN: Pointer to mapped memory. Null on error. | ||
92 | * | ||
93 | * DESCRIPTION: Map physical memory into local address space. | ||
94 | * | ||
95 | *****************************************************************************/ | ||
96 | |||
97 | void *acpi_os_map_memory(acpi_physical_address where, acpi_size length) | ||
98 | { | ||
99 | u8 *mapped_memory; | ||
100 | acpi_physical_address offset; | ||
101 | acpi_size page_size; | ||
102 | int fd; | ||
103 | |||
104 | fd = open(SYSTEM_MEMORY, O_RDONLY | O_BINARY); | ||
105 | if (fd < 0) { | ||
106 | fprintf(stderr, "Cannot open %s\n", SYSTEM_MEMORY); | ||
107 | return (NULL); | ||
108 | } | ||
109 | |||
110 | /* Align the offset to use mmap */ | ||
111 | |||
112 | page_size = acpi_os_get_page_size(); | ||
113 | offset = where % page_size; | ||
114 | |||
115 | /* Map the table header to get the length of the full table */ | ||
116 | |||
117 | mapped_memory = mmap(NULL, (length + offset), PROT_READ, MMAP_FLAGS, | ||
118 | fd, (where - offset)); | ||
119 | if (mapped_memory == MAP_FAILED) { | ||
120 | fprintf(stderr, "Cannot map %s\n", SYSTEM_MEMORY); | ||
121 | close(fd); | ||
122 | return (NULL); | ||
123 | } | ||
124 | |||
125 | close(fd); | ||
126 | return (ACPI_CAST8(mapped_memory + offset)); | ||
127 | } | ||
128 | |||
129 | /****************************************************************************** | ||
130 | * | ||
131 | * FUNCTION: acpi_os_unmap_memory | ||
132 | * | ||
133 | * PARAMETERS: where - Logical address of memory to be unmapped | ||
134 | * length - How much memory to unmap | ||
135 | * | ||
136 | * RETURN: None. | ||
137 | * | ||
138 | * DESCRIPTION: Delete a previously created mapping. Where and Length must | ||
139 | * correspond to a previous mapping exactly. | ||
140 | * | ||
141 | *****************************************************************************/ | ||
142 | |||
143 | void acpi_os_unmap_memory(void *where, acpi_size length) | ||
144 | { | ||
145 | acpi_physical_address offset; | ||
146 | acpi_size page_size; | ||
147 | |||
148 | page_size = acpi_os_get_page_size(); | ||
149 | offset = (acpi_physical_address) where % page_size; | ||
150 | munmap((u8 *)where - offset, (length + offset)); | ||
151 | } | ||
diff --git a/tools/power/acpi/tools/acpidump/acpidump.c b/tools/power/acpi/tools/acpidump/acpidump.c deleted file mode 100644 index a84553a0e0df..000000000000 --- a/tools/power/acpi/tools/acpidump/acpidump.c +++ /dev/null | |||
@@ -1,559 +0,0 @@ | |||
1 | /* | ||
2 | * (c) Alexey Starikovskiy, Intel, 2005-2006. | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
8 | * 1. Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions, and the following disclaimer, | ||
10 | * without modification. | ||
11 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
12 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
13 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
14 | * including a substantially similar Disclaimer requirement for further | ||
15 | * binary redistribution. | ||
16 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
17 | * of any contributors may be used to endorse or promote products derived | ||
18 | * from this software without specific prior written permission. | ||
19 | * | ||
20 | * Alternatively, this software may be distributed under the terms of the | ||
21 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
22 | * Software Foundation. | ||
23 | * | ||
24 | * NO WARRANTY | ||
25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
28 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
29 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
31 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
32 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
33 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
34 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
35 | * POSSIBILITY OF SUCH DAMAGES. | ||
36 | */ | ||
37 | |||
38 | #ifdef DEFINE_ALTERNATE_TYPES | ||
39 | /* hack to enable building old application with new headers -lenb */ | ||
40 | #define acpi_fadt_descriptor acpi_table_fadt | ||
41 | #define acpi_rsdp_descriptor acpi_table_rsdp | ||
42 | #define DSDT_SIG ACPI_SIG_DSDT | ||
43 | #define FACS_SIG ACPI_SIG_FACS | ||
44 | #define FADT_SIG ACPI_SIG_FADT | ||
45 | #define xfirmware_ctrl Xfacs | ||
46 | #define firmware_ctrl facs | ||
47 | |||
48 | typedef int s32; | ||
49 | typedef unsigned char u8; | ||
50 | typedef unsigned short u16; | ||
51 | typedef unsigned int u32; | ||
52 | typedef unsigned long long u64; | ||
53 | typedef long long s64; | ||
54 | #endif | ||
55 | |||
56 | #include <sys/mman.h> | ||
57 | #include <sys/types.h> | ||
58 | #include <sys/stat.h> | ||
59 | #include <fcntl.h> | ||
60 | #include <stdio.h> | ||
61 | #include <string.h> | ||
62 | #include <unistd.h> | ||
63 | #include <getopt.h> | ||
64 | |||
65 | #include <dirent.h> | ||
66 | |||
67 | #include <acpi/acconfig.h> | ||
68 | #include <acpi/platform/acenv.h> | ||
69 | #include <acpi/actypes.h> | ||
70 | #include <acpi/actbl.h> | ||
71 | |||
72 | static inline u8 checksum(u8 * buffer, u32 length) | ||
73 | { | ||
74 | u8 sum = 0, *i = buffer; | ||
75 | buffer += length; | ||
76 | for (; i < buffer; sum += *(i++)); | ||
77 | return sum; | ||
78 | } | ||
79 | |||
80 | static unsigned long psz, addr, length; | ||
81 | static int print, connect, skip; | ||
82 | static u8 select_sig[4]; | ||
83 | |||
84 | static unsigned long read_efi_systab( void ) | ||
85 | { | ||
86 | char buffer[80]; | ||
87 | unsigned long addr; | ||
88 | FILE *f = fopen("/sys/firmware/efi/systab", "r"); | ||
89 | if (f) { | ||
90 | while (fgets(buffer, 80, f)) { | ||
91 | if (sscanf(buffer, "ACPI20=0x%lx", &addr) == 1) | ||
92 | return addr; | ||
93 | } | ||
94 | fclose(f); | ||
95 | } | ||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | static u8 *acpi_map_memory(unsigned long where, unsigned length) | ||
100 | { | ||
101 | unsigned long offset; | ||
102 | u8 *there; | ||
103 | int fd = open("/dev/mem", O_RDONLY); | ||
104 | if (fd < 0) { | ||
105 | fprintf(stderr, "acpi_os_map_memory: cannot open /dev/mem\n"); | ||
106 | exit(1); | ||
107 | } | ||
108 | offset = where % psz; | ||
109 | there = mmap(NULL, length + offset, PROT_READ, MAP_PRIVATE, | ||
110 | fd, where - offset); | ||
111 | close(fd); | ||
112 | if (there == MAP_FAILED) return 0; | ||
113 | return (there + offset); | ||
114 | } | ||
115 | |||
116 | static void acpi_unmap_memory(u8 * there, unsigned length) | ||
117 | { | ||
118 | unsigned long offset = (unsigned long)there % psz; | ||
119 | munmap(there - offset, length + offset); | ||
120 | } | ||
121 | |||
122 | static struct acpi_table_header *acpi_map_table(unsigned long where, char *sig) | ||
123 | { | ||
124 | unsigned size; | ||
125 | struct acpi_table_header *tbl = (struct acpi_table_header *) | ||
126 | acpi_map_memory(where, sizeof(struct acpi_table_header)); | ||
127 | if (!tbl || (sig && memcmp(sig, tbl->signature, 4))) return 0; | ||
128 | size = tbl->length; | ||
129 | acpi_unmap_memory((u8 *) tbl, sizeof(struct acpi_table_header)); | ||
130 | return (struct acpi_table_header *)acpi_map_memory(where, size); | ||
131 | } | ||
132 | |||
133 | static void acpi_unmap_table(struct acpi_table_header *tbl) | ||
134 | { | ||
135 | acpi_unmap_memory((u8 *)tbl, tbl->length); | ||
136 | } | ||
137 | |||
138 | static struct acpi_rsdp_descriptor *acpi_scan_for_rsdp(u8 *begin, u32 length) | ||
139 | { | ||
140 | struct acpi_rsdp_descriptor *rsdp; | ||
141 | u8 *i, *end = begin + length; | ||
142 | /* Search from given start address for the requested length */ | ||
143 | for (i = begin; i < end; i += ACPI_RSDP_SCAN_STEP) { | ||
144 | /* The signature and checksum must both be correct */ | ||
145 | if (memcmp((char *)i, "RSD PTR ", 8)) continue; | ||
146 | rsdp = (struct acpi_rsdp_descriptor *)i; | ||
147 | /* Signature matches, check the appropriate checksum */ | ||
148 | if (!checksum((u8 *) rsdp, (rsdp->revision < 2) ? | ||
149 | ACPI_RSDP_CHECKSUM_LENGTH : | ||
150 | ACPI_RSDP_XCHECKSUM_LENGTH)) | ||
151 | /* Checksum valid, we have found a valid RSDP */ | ||
152 | return rsdp; | ||
153 | } | ||
154 | /* Searched entire block, no RSDP was found */ | ||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | /* | ||
159 | * Output data | ||
160 | */ | ||
161 | static void acpi_show_data(int fd, u8 * data, int size) | ||
162 | { | ||
163 | char buffer[256]; | ||
164 | int len; | ||
165 | int i, remain = size; | ||
166 | while (remain > 0) { | ||
167 | len = snprintf(buffer, 256, " %04x:", size - remain); | ||
168 | for (i = 0; i < 16 && i < remain; i++) { | ||
169 | len += | ||
170 | snprintf(&buffer[len], 256 - len, " %02x", data[i]); | ||
171 | } | ||
172 | for (; i < 16; i++) { | ||
173 | len += snprintf(&buffer[len], 256 - len, " "); | ||
174 | } | ||
175 | len += snprintf(&buffer[len], 256 - len, " "); | ||
176 | for (i = 0; i < 16 && i < remain; i++) { | ||
177 | buffer[len++] = (isprint(data[i])) ? data[i] : '.'; | ||
178 | } | ||
179 | buffer[len++] = '\n'; | ||
180 | write(fd, buffer, len); | ||
181 | data += 16; | ||
182 | remain -= 16; | ||
183 | } | ||
184 | } | ||
185 | |||
186 | /* | ||
187 | * Output ACPI table | ||
188 | */ | ||
189 | static void acpi_show_table(int fd, struct acpi_table_header *table, unsigned long addr) | ||
190 | { | ||
191 | char buff[80]; | ||
192 | int len = snprintf(buff, 80, "%.4s @ %p\n", table->signature, (void *)addr); | ||
193 | write(fd, buff, len); | ||
194 | acpi_show_data(fd, (u8 *) table, table->length); | ||
195 | buff[0] = '\n'; | ||
196 | write(fd, buff, 1); | ||
197 | } | ||
198 | |||
199 | static void write_table(int fd, struct acpi_table_header *tbl, unsigned long addr) | ||
200 | { | ||
201 | static int select_done = 0; | ||
202 | if (!select_sig[0]) { | ||
203 | if (print) { | ||
204 | acpi_show_table(fd, tbl, addr); | ||
205 | } else { | ||
206 | write(fd, tbl, tbl->length); | ||
207 | } | ||
208 | } else if (!select_done && !memcmp(select_sig, tbl->signature, 4)) { | ||
209 | if (skip > 0) { | ||
210 | --skip; | ||
211 | return; | ||
212 | } | ||
213 | if (print) { | ||
214 | acpi_show_table(fd, tbl, addr); | ||
215 | } else { | ||
216 | write(fd, tbl, tbl->length); | ||
217 | } | ||
218 | select_done = 1; | ||
219 | } | ||
220 | } | ||
221 | |||
222 | static void acpi_dump_FADT(int fd, struct acpi_table_header *tbl, unsigned long xaddr) { | ||
223 | struct acpi_fadt_descriptor x; | ||
224 | unsigned long addr; | ||
225 | size_t len = sizeof(struct acpi_fadt_descriptor); | ||
226 | if (len > tbl->length) len = tbl->length; | ||
227 | memcpy(&x, tbl, len); | ||
228 | x.header.length = len; | ||
229 | if (checksum((u8 *)tbl, len)) { | ||
230 | fprintf(stderr, "Wrong checksum for FADT!\n"); | ||
231 | } | ||
232 | if (x.header.length >= 148 && x.Xdsdt) { | ||
233 | addr = (unsigned long)x.Xdsdt; | ||
234 | if (connect) { | ||
235 | x.Xdsdt = lseek(fd, 0, SEEK_CUR); | ||
236 | } | ||
237 | } else if (x.header.length >= 44 && x.dsdt) { | ||
238 | addr = (unsigned long)x.dsdt; | ||
239 | if (connect) { | ||
240 | x.dsdt = lseek(fd, 0, SEEK_CUR); | ||
241 | } | ||
242 | } else { | ||
243 | fprintf(stderr, "No DSDT in FADT!\n"); | ||
244 | goto no_dsdt; | ||
245 | } | ||
246 | tbl = acpi_map_table(addr, DSDT_SIG); | ||
247 | if (!tbl) goto no_dsdt; | ||
248 | if (checksum((u8 *)tbl, tbl->length)) | ||
249 | fprintf(stderr, "Wrong checksum for DSDT!\n"); | ||
250 | write_table(fd, tbl, addr); | ||
251 | acpi_unmap_table(tbl); | ||
252 | no_dsdt: | ||
253 | if (x.header.length >= 140 && x.xfirmware_ctrl) { | ||
254 | addr = (unsigned long)x.xfirmware_ctrl; | ||
255 | if (connect) { | ||
256 | x.xfirmware_ctrl = lseek(fd, 0, SEEK_CUR); | ||
257 | } | ||
258 | } else if (x.header.length >= 40 && x.firmware_ctrl) { | ||
259 | addr = (unsigned long)x.firmware_ctrl; | ||
260 | if (connect) { | ||
261 | x.firmware_ctrl = lseek(fd, 0, SEEK_CUR); | ||
262 | } | ||
263 | } else { | ||
264 | fprintf(stderr, "No FACS in FADT!\n"); | ||
265 | goto no_facs; | ||
266 | } | ||
267 | tbl = acpi_map_table(addr, FACS_SIG); | ||
268 | if (!tbl) goto no_facs; | ||
269 | /* do not checksum FACS */ | ||
270 | write_table(fd, tbl, addr); | ||
271 | acpi_unmap_table(tbl); | ||
272 | no_facs: | ||
273 | write_table(fd, (struct acpi_table_header *)&x, xaddr); | ||
274 | } | ||
275 | |||
276 | static int acpi_dump_SDT(int fd, struct acpi_rsdp_descriptor *rsdp) | ||
277 | { | ||
278 | struct acpi_table_header *sdt, *tbl = 0; | ||
279 | int xsdt = 1, i, num; | ||
280 | char *offset; | ||
281 | unsigned long addr; | ||
282 | if (rsdp->revision > 1 && rsdp->xsdt_physical_address) { | ||
283 | tbl = acpi_map_table(rsdp->xsdt_physical_address, "XSDT"); | ||
284 | } | ||
285 | if (!tbl && rsdp->rsdt_physical_address) { | ||
286 | xsdt = 0; | ||
287 | tbl = acpi_map_table(rsdp->rsdt_physical_address, "RSDT"); | ||
288 | } | ||
289 | if (!tbl) return 0; | ||
290 | sdt = malloc(tbl->length); | ||
291 | memcpy(sdt, tbl, tbl->length); | ||
292 | acpi_unmap_table(tbl); | ||
293 | if (checksum((u8 *)sdt, sdt->length)) | ||
294 | fprintf(stderr, "Wrong checksum for %s!\n", (xsdt)?"XSDT":"RSDT"); | ||
295 | num = (sdt->length - sizeof(struct acpi_table_header))/((xsdt)?sizeof(u64):sizeof(u32)); | ||
296 | offset = (char *)sdt + sizeof(struct acpi_table_header); | ||
297 | for (i = 0; i < num; ++i, offset += ((xsdt) ? sizeof(u64) : sizeof(u32))) { | ||
298 | addr = (xsdt) ? (unsigned long)(*(u64 *)offset): | ||
299 | (unsigned long)(*(u32 *)offset); | ||
300 | if (!addr) continue; | ||
301 | tbl = acpi_map_table(addr, 0); | ||
302 | if (!tbl) continue; | ||
303 | if (!memcmp(tbl->signature, FADT_SIG, 4)) { | ||
304 | acpi_dump_FADT(fd, tbl, addr); | ||
305 | } else { | ||
306 | if (checksum((u8 *)tbl, tbl->length)) | ||
307 | fprintf(stderr, "Wrong checksum for generic table!\n"); | ||
308 | write_table(fd, tbl, addr); | ||
309 | } | ||
310 | acpi_unmap_table(tbl); | ||
311 | if (connect) { | ||
312 | if (xsdt) | ||
313 | (*(u64*)offset) = lseek(fd, 0, SEEK_CUR); | ||
314 | else | ||
315 | (*(u32*)offset) = lseek(fd, 0, SEEK_CUR); | ||
316 | } | ||
317 | } | ||
318 | if (xsdt) { | ||
319 | addr = (unsigned long)rsdp->xsdt_physical_address; | ||
320 | if (connect) { | ||
321 | rsdp->xsdt_physical_address = lseek(fd, 0, SEEK_CUR); | ||
322 | } | ||
323 | } else { | ||
324 | addr = (unsigned long)rsdp->rsdt_physical_address; | ||
325 | if (connect) { | ||
326 | rsdp->rsdt_physical_address = lseek(fd, 0, SEEK_CUR); | ||
327 | } | ||
328 | } | ||
329 | write_table(fd, sdt, addr); | ||
330 | free (sdt); | ||
331 | return 1; | ||
332 | } | ||
333 | |||
334 | #define DYNAMIC_SSDT "/sys/firmware/acpi/tables/dynamic" | ||
335 | |||
336 | static void acpi_dump_dynamic_SSDT(int fd) | ||
337 | { | ||
338 | struct stat file_stat; | ||
339 | char filename[256], *ptr; | ||
340 | DIR *tabledir; | ||
341 | struct dirent *entry; | ||
342 | FILE *fp; | ||
343 | int count, readcount, length; | ||
344 | struct acpi_table_header table_header, *ptable; | ||
345 | |||
346 | if (stat(DYNAMIC_SSDT, &file_stat) == -1) { | ||
347 | /* The directory doesn't exist */ | ||
348 | return; | ||
349 | } | ||
350 | tabledir = opendir(DYNAMIC_SSDT); | ||
351 | if(!tabledir){ | ||
352 | /*can't open the directory */ | ||
353 | return; | ||
354 | } | ||
355 | |||
356 | while ((entry = readdir(tabledir)) != 0){ | ||
357 | /* skip the file of . /.. */ | ||
358 | if (entry->d_name[0] == '.') | ||
359 | continue; | ||
360 | |||
361 | sprintf(filename, "%s/%s", DYNAMIC_SSDT, entry->d_name); | ||
362 | fp = fopen(filename, "r"); | ||
363 | if (fp == NULL) { | ||
364 | fprintf(stderr, "Can't open the file of %s\n", | ||
365 | filename); | ||
366 | continue; | ||
367 | } | ||
368 | /* Read the Table header to parse the table length */ | ||
369 | count = fread(&table_header, 1, sizeof(struct acpi_table_header), fp); | ||
370 | if (count < sizeof(table_header)) { | ||
371 | /* the length is lessn than ACPI table header. skip it */ | ||
372 | fclose(fp); | ||
373 | continue; | ||
374 | } | ||
375 | length = table_header.length; | ||
376 | ptr = malloc(table_header.length); | ||
377 | fseek(fp, 0, SEEK_SET); | ||
378 | readcount = 0; | ||
379 | while(!feof(fp) && readcount < length) { | ||
380 | count = fread(ptr + readcount, 1, 256, fp); | ||
381 | readcount += count; | ||
382 | } | ||
383 | fclose(fp); | ||
384 | ptable = (struct acpi_table_header *) ptr; | ||
385 | if (checksum((u8 *) ptable, ptable->length)) | ||
386 | fprintf(stderr, "Wrong checksum " | ||
387 | "for dynamic SSDT table!\n"); | ||
388 | write_table(fd, ptable, 0); | ||
389 | free(ptr); | ||
390 | } | ||
391 | closedir(tabledir); | ||
392 | return; | ||
393 | } | ||
394 | |||
395 | static void usage(const char *progname) | ||
396 | { | ||
397 | puts("Usage:"); | ||
398 | printf("%s [--addr 0x1234][--table DSDT][--output filename]" | ||
399 | "[--binary][--length 0x456][--help]\n", progname); | ||
400 | puts("\t--addr 0x1234 or -a 0x1234 -- look for tables at this physical address"); | ||
401 | puts("\t--table DSDT or -t DSDT -- only dump table with DSDT signature"); | ||
402 | puts("\t--output filename or -o filename -- redirect output from stdin to filename"); | ||
403 | puts("\t--binary or -b -- dump data in binary form rather than in hex-dump format"); | ||
404 | puts("\t--length 0x456 or -l 0x456 -- works only with --addr, dump physical memory" | ||
405 | "\n\t\tregion without trying to understand it's contents"); | ||
406 | puts("\t--skip 2 or -s 2 -- skip 2 tables of the given name and output only 3rd one"); | ||
407 | puts("\t--help or -h -- this help message"); | ||
408 | exit(0); | ||
409 | } | ||
410 | |||
411 | static struct option long_options[] = { | ||
412 | {"addr", 1, 0, 0}, | ||
413 | {"table", 1, 0, 0}, | ||
414 | {"output", 1, 0, 0}, | ||
415 | {"binary", 0, 0, 0}, | ||
416 | {"length", 1, 0, 0}, | ||
417 | {"skip", 1, 0, 0}, | ||
418 | {"help", 0, 0, 0}, | ||
419 | {0, 0, 0, 0} | ||
420 | }; | ||
421 | int main(int argc, char **argv) | ||
422 | { | ||
423 | int option_index, c, fd; | ||
424 | u8 *raw; | ||
425 | struct acpi_rsdp_descriptor rsdpx, *x = 0; | ||
426 | char *filename = 0; | ||
427 | char buff[80]; | ||
428 | memset(select_sig, 0, 4); | ||
429 | print = 1; | ||
430 | connect = 0; | ||
431 | addr = length = 0; | ||
432 | skip = 0; | ||
433 | while (1) { | ||
434 | option_index = 0; | ||
435 | c = getopt_long(argc, argv, "a:t:o:bl:s:h", | ||
436 | long_options, &option_index); | ||
437 | if (c == -1) | ||
438 | break; | ||
439 | |||
440 | switch (c) { | ||
441 | case 0: | ||
442 | switch (option_index) { | ||
443 | case 0: | ||
444 | addr = strtoul(optarg, (char **)NULL, 16); | ||
445 | break; | ||
446 | case 1: | ||
447 | memcpy(select_sig, optarg, 4); | ||
448 | break; | ||
449 | case 2: | ||
450 | filename = optarg; | ||
451 | break; | ||
452 | case 3: | ||
453 | print = 0; | ||
454 | break; | ||
455 | case 4: | ||
456 | length = strtoul(optarg, (char **)NULL, 16); | ||
457 | break; | ||
458 | case 5: | ||
459 | skip = strtoul(optarg, (char **)NULL, 10); | ||
460 | break; | ||
461 | case 6: | ||
462 | usage(argv[0]); | ||
463 | exit(0); | ||
464 | } | ||
465 | break; | ||
466 | case 'a': | ||
467 | addr = strtoul(optarg, (char **)NULL, 16); | ||
468 | break; | ||
469 | case 't': | ||
470 | memcpy(select_sig, optarg, 4); | ||
471 | break; | ||
472 | case 'o': | ||
473 | filename = optarg; | ||
474 | break; | ||
475 | case 'b': | ||
476 | print = 0; | ||
477 | break; | ||
478 | case 'l': | ||
479 | length = strtoul(optarg, (char **)NULL, 16); | ||
480 | break; | ||
481 | case 's': | ||
482 | skip = strtoul(optarg, (char **)NULL, 10); | ||
483 | break; | ||
484 | case 'h': | ||
485 | usage(argv[0]); | ||
486 | exit(0); | ||
487 | default: | ||
488 | printf("Unknown option!\n"); | ||
489 | usage(argv[0]); | ||
490 | exit(0); | ||
491 | } | ||
492 | } | ||
493 | |||
494 | fd = STDOUT_FILENO; | ||
495 | if (filename) { | ||
496 | fd = creat(filename, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); | ||
497 | if (fd < 0) | ||
498 | return fd; | ||
499 | } | ||
500 | |||
501 | if (!select_sig[0] && !print) { | ||
502 | connect = 1; | ||
503 | } | ||
504 | |||
505 | psz = sysconf(_SC_PAGESIZE); | ||
506 | if (length && addr) { | ||
507 | /* We know length and address, it means we just want a memory dump */ | ||
508 | if (!(raw = acpi_map_memory(addr, length))) | ||
509 | goto not_found; | ||
510 | write(fd, raw, length); | ||
511 | acpi_unmap_memory(raw, length); | ||
512 | close(fd); | ||
513 | return 0; | ||
514 | } | ||
515 | |||
516 | length = sizeof(struct acpi_rsdp_descriptor); | ||
517 | if (!addr) { | ||
518 | addr = read_efi_systab(); | ||
519 | if (!addr) { | ||
520 | addr = ACPI_HI_RSDP_WINDOW_BASE; | ||
521 | length = ACPI_HI_RSDP_WINDOW_SIZE; | ||
522 | } | ||
523 | } | ||
524 | |||
525 | if (!(raw = acpi_map_memory(addr, length)) || | ||
526 | !(x = acpi_scan_for_rsdp(raw, length))) | ||
527 | goto not_found; | ||
528 | |||
529 | /* Find RSDP and print all found tables */ | ||
530 | memcpy(&rsdpx, x, sizeof(struct acpi_rsdp_descriptor)); | ||
531 | acpi_unmap_memory(raw, length); | ||
532 | if (connect) { | ||
533 | lseek(fd, sizeof(struct acpi_rsdp_descriptor), SEEK_SET); | ||
534 | } | ||
535 | if (!acpi_dump_SDT(fd, &rsdpx)) | ||
536 | goto not_found; | ||
537 | if (connect) { | ||
538 | lseek(fd, 0, SEEK_SET); | ||
539 | write(fd, x, (rsdpx.revision < 2) ? | ||
540 | ACPI_RSDP_CHECKSUM_LENGTH : ACPI_RSDP_XCHECKSUM_LENGTH); | ||
541 | } else if (!select_sig[0] || !memcmp("RSD PTR ", select_sig, 4)) { | ||
542 | addr += (long)x - (long)raw; | ||
543 | length = snprintf(buff, 80, "RSD PTR @ %p\n", (void *)addr); | ||
544 | write(fd, buff, length); | ||
545 | acpi_show_data(fd, (u8 *) & rsdpx, (rsdpx.revision < 2) ? | ||
546 | ACPI_RSDP_CHECKSUM_LENGTH : ACPI_RSDP_XCHECKSUM_LENGTH); | ||
547 | buff[0] = '\n'; | ||
548 | write(fd, buff, 1); | ||
549 | } | ||
550 | acpi_dump_dynamic_SSDT(fd); | ||
551 | close(fd); | ||
552 | return 0; | ||
553 | not_found: | ||
554 | close(fd); | ||
555 | fprintf(stderr, "ACPI tables were not found. If you know location " | ||
556 | "of RSD PTR table (from dmesg, etc), " | ||
557 | "supply it with either --addr or -a option\n"); | ||
558 | return 1; | ||
559 | } | ||
diff --git a/tools/power/acpi/tools/acpidump/acpidump.h b/tools/power/acpi/tools/acpidump/acpidump.h new file mode 100644 index 000000000000..46f519597fe5 --- /dev/null +++ b/tools/power/acpi/tools/acpidump/acpidump.h | |||
@@ -0,0 +1,130 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: acpidump.h - Include file for acpi_dump utility | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2014, 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 | /* | ||
45 | * Global variables. Defined in main.c only, externed in all other files | ||
46 | */ | ||
47 | #ifdef _DECLARE_GLOBALS | ||
48 | #define EXTERN | ||
49 | #define INIT_GLOBAL(a,b) a=b | ||
50 | #define DEFINE_ACPI_GLOBALS 1 | ||
51 | #else | ||
52 | #define EXTERN extern | ||
53 | #define INIT_GLOBAL(a,b) a | ||
54 | #endif | ||
55 | |||
56 | #include <acpi/acpi.h> | ||
57 | #include "accommon.h" | ||
58 | #include "actables.h" | ||
59 | |||
60 | #include <stdio.h> | ||
61 | #include <fcntl.h> | ||
62 | #include <errno.h> | ||
63 | #include <sys/stat.h> | ||
64 | |||
65 | /* Globals */ | ||
66 | |||
67 | EXTERN u8 INIT_GLOBAL(gbl_summary_mode, FALSE); | ||
68 | EXTERN u8 INIT_GLOBAL(gbl_verbose_mode, FALSE); | ||
69 | EXTERN u8 INIT_GLOBAL(gbl_binary_mode, FALSE); | ||
70 | EXTERN u8 INIT_GLOBAL(gbl_dump_customized_tables, FALSE); | ||
71 | EXTERN u8 INIT_GLOBAL(gbl_do_not_dump_xsdt, FALSE); | ||
72 | EXTERN FILE INIT_GLOBAL(*gbl_output_file, NULL); | ||
73 | EXTERN char INIT_GLOBAL(*gbl_output_filename, NULL); | ||
74 | EXTERN u64 INIT_GLOBAL(gbl_rsdp_base, 0); | ||
75 | |||
76 | /* Globals required for use with ACPICA modules */ | ||
77 | |||
78 | #ifdef _DECLARE_GLOBALS | ||
79 | u8 acpi_gbl_integer_byte_width = 8; | ||
80 | #endif | ||
81 | |||
82 | /* Action table used to defer requested options */ | ||
83 | |||
84 | struct ap_dump_action { | ||
85 | char *argument; | ||
86 | u32 to_be_done; | ||
87 | }; | ||
88 | |||
89 | #define AP_MAX_ACTIONS 32 | ||
90 | |||
91 | #define AP_DUMP_ALL_TABLES 0 | ||
92 | #define AP_DUMP_TABLE_BY_ADDRESS 1 | ||
93 | #define AP_DUMP_TABLE_BY_NAME 2 | ||
94 | #define AP_DUMP_TABLE_BY_FILE 3 | ||
95 | |||
96 | #define AP_MAX_ACPI_FILES 256 /* Prevent infinite loops */ | ||
97 | |||
98 | /* Minimum FADT sizes for various table addresses */ | ||
99 | |||
100 | #define MIN_FADT_FOR_DSDT (ACPI_FADT_OFFSET (dsdt) + sizeof (u32)) | ||
101 | #define MIN_FADT_FOR_FACS (ACPI_FADT_OFFSET (facs) + sizeof (u32)) | ||
102 | #define MIN_FADT_FOR_XDSDT (ACPI_FADT_OFFSET (Xdsdt) + sizeof (u64)) | ||
103 | #define MIN_FADT_FOR_XFACS (ACPI_FADT_OFFSET (Xfacs) + sizeof (u64)) | ||
104 | |||
105 | /* | ||
106 | * apdump - Table get/dump routines | ||
107 | */ | ||
108 | int ap_dump_table_from_file(char *pathname); | ||
109 | |||
110 | int ap_dump_table_by_name(char *signature); | ||
111 | |||
112 | int ap_dump_table_by_address(char *ascii_address); | ||
113 | |||
114 | int ap_dump_all_tables(void); | ||
115 | |||
116 | u8 ap_is_valid_header(struct acpi_table_header *table); | ||
117 | |||
118 | u8 ap_is_valid_checksum(struct acpi_table_header *table); | ||
119 | |||
120 | u32 ap_get_table_length(struct acpi_table_header *table); | ||
121 | |||
122 | /* | ||
123 | * apfiles - File I/O utilities | ||
124 | */ | ||
125 | int ap_open_output_file(char *pathname); | ||
126 | |||
127 | int ap_write_to_binary_file(struct acpi_table_header *table, u32 instance); | ||
128 | |||
129 | struct acpi_table_header *ap_get_table_from_file(char *pathname, | ||
130 | u32 *file_size); | ||
diff --git a/tools/power/acpi/tools/acpidump/apdump.c b/tools/power/acpi/tools/acpidump/apdump.c new file mode 100644 index 000000000000..3cac12378366 --- /dev/null +++ b/tools/power/acpi/tools/acpidump/apdump.c | |||
@@ -0,0 +1,451 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: apdump - Dump routines for ACPI tables (acpidump) | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2014, 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 "acpidump.h" | ||
45 | |||
46 | /* Local prototypes */ | ||
47 | |||
48 | static int | ||
49 | ap_dump_table_buffer(struct acpi_table_header *table, | ||
50 | u32 instance, acpi_physical_address address); | ||
51 | |||
52 | /****************************************************************************** | ||
53 | * | ||
54 | * FUNCTION: ap_is_valid_header | ||
55 | * | ||
56 | * PARAMETERS: table - Pointer to table to be validated | ||
57 | * | ||
58 | * RETURN: TRUE if the header appears to be valid. FALSE otherwise | ||
59 | * | ||
60 | * DESCRIPTION: Check for a valid ACPI table header | ||
61 | * | ||
62 | ******************************************************************************/ | ||
63 | |||
64 | u8 ap_is_valid_header(struct acpi_table_header *table) | ||
65 | { | ||
66 | |||
67 | if (!ACPI_VALIDATE_RSDP_SIG(table->signature)) { | ||
68 | |||
69 | /* Make sure signature is all ASCII and a valid ACPI name */ | ||
70 | |||
71 | if (!acpi_ut_valid_acpi_name(table->signature)) { | ||
72 | fprintf(stderr, | ||
73 | "Table signature (0x%8.8X) is invalid\n", | ||
74 | *(u32 *)table->signature); | ||
75 | return (FALSE); | ||
76 | } | ||
77 | |||
78 | /* Check for minimum table length */ | ||
79 | |||
80 | if (table->length < sizeof(struct acpi_table_header)) { | ||
81 | fprintf(stderr, "Table length (0x%8.8X) is invalid\n", | ||
82 | table->length); | ||
83 | return (FALSE); | ||
84 | } | ||
85 | } | ||
86 | |||
87 | return (TRUE); | ||
88 | } | ||
89 | |||
90 | /****************************************************************************** | ||
91 | * | ||
92 | * FUNCTION: ap_is_valid_checksum | ||
93 | * | ||
94 | * PARAMETERS: table - Pointer to table to be validated | ||
95 | * | ||
96 | * RETURN: TRUE if the checksum appears to be valid. FALSE otherwise. | ||
97 | * | ||
98 | * DESCRIPTION: Check for a valid ACPI table checksum. | ||
99 | * | ||
100 | ******************************************************************************/ | ||
101 | |||
102 | u8 ap_is_valid_checksum(struct acpi_table_header *table) | ||
103 | { | ||
104 | acpi_status status; | ||
105 | struct acpi_table_rsdp *rsdp; | ||
106 | |||
107 | if (ACPI_VALIDATE_RSDP_SIG(table->signature)) { | ||
108 | /* | ||
109 | * Checksum for RSDP. | ||
110 | * Note: Other checksums are computed during the table dump. | ||
111 | */ | ||
112 | rsdp = ACPI_CAST_PTR(struct acpi_table_rsdp, table); | ||
113 | status = acpi_tb_validate_rsdp(rsdp); | ||
114 | } else { | ||
115 | status = acpi_tb_verify_checksum(table, table->length); | ||
116 | } | ||
117 | |||
118 | if (ACPI_FAILURE(status)) { | ||
119 | fprintf(stderr, "%4.4s: Warning: wrong checksum in table\n", | ||
120 | table->signature); | ||
121 | } | ||
122 | |||
123 | return (AE_OK); | ||
124 | } | ||
125 | |||
126 | /****************************************************************************** | ||
127 | * | ||
128 | * FUNCTION: ap_get_table_length | ||
129 | * | ||
130 | * PARAMETERS: table - Pointer to the table | ||
131 | * | ||
132 | * RETURN: Table length | ||
133 | * | ||
134 | * DESCRIPTION: Obtain table length according to table signature. | ||
135 | * | ||
136 | ******************************************************************************/ | ||
137 | |||
138 | u32 ap_get_table_length(struct acpi_table_header *table) | ||
139 | { | ||
140 | struct acpi_table_rsdp *rsdp; | ||
141 | |||
142 | /* Check if table is valid */ | ||
143 | |||
144 | if (!ap_is_valid_header(table)) { | ||
145 | return (0); | ||
146 | } | ||
147 | |||
148 | if (ACPI_VALIDATE_RSDP_SIG(table->signature)) { | ||
149 | rsdp = ACPI_CAST_PTR(struct acpi_table_rsdp, table); | ||
150 | return (rsdp->length); | ||
151 | } | ||
152 | |||
153 | /* Normal ACPI table */ | ||
154 | |||
155 | return (table->length); | ||
156 | } | ||
157 | |||
158 | /****************************************************************************** | ||
159 | * | ||
160 | * FUNCTION: ap_dump_table_buffer | ||
161 | * | ||
162 | * PARAMETERS: table - ACPI table to be dumped | ||
163 | * instance - ACPI table instance no. to be dumped | ||
164 | * address - Physical address of the table | ||
165 | * | ||
166 | * RETURN: None | ||
167 | * | ||
168 | * DESCRIPTION: Dump an ACPI table in standard ASCII hex format, with a | ||
169 | * header that is compatible with the acpi_xtract utility. | ||
170 | * | ||
171 | ******************************************************************************/ | ||
172 | |||
173 | static int | ||
174 | ap_dump_table_buffer(struct acpi_table_header *table, | ||
175 | u32 instance, acpi_physical_address address) | ||
176 | { | ||
177 | u32 table_length; | ||
178 | |||
179 | table_length = ap_get_table_length(table); | ||
180 | |||
181 | /* Print only the header if requested */ | ||
182 | |||
183 | if (gbl_summary_mode) { | ||
184 | acpi_tb_print_table_header(address, table); | ||
185 | return (0); | ||
186 | } | ||
187 | |||
188 | /* Dump to binary file if requested */ | ||
189 | |||
190 | if (gbl_binary_mode) { | ||
191 | return (ap_write_to_binary_file(table, instance)); | ||
192 | } | ||
193 | |||
194 | /* | ||
195 | * Dump the table with header for use with acpixtract utility. | ||
196 | * Note: simplest to just always emit a 64-bit address. acpi_xtract | ||
197 | * utility can handle this. | ||
198 | */ | ||
199 | printf("%4.4s @ 0x%8.8X%8.8X\n", table->signature, | ||
200 | ACPI_FORMAT_UINT64(address)); | ||
201 | |||
202 | acpi_ut_dump_buffer(ACPI_CAST_PTR(u8, table), table_length, | ||
203 | DB_BYTE_DISPLAY, 0); | ||
204 | printf("\n"); | ||
205 | return (0); | ||
206 | } | ||
207 | |||
208 | /****************************************************************************** | ||
209 | * | ||
210 | * FUNCTION: ap_dump_all_tables | ||
211 | * | ||
212 | * PARAMETERS: None | ||
213 | * | ||
214 | * RETURN: Status | ||
215 | * | ||
216 | * DESCRIPTION: Get all tables from the RSDT/XSDT (or at least all of the | ||
217 | * tables that we can possibly get). | ||
218 | * | ||
219 | ******************************************************************************/ | ||
220 | |||
221 | int ap_dump_all_tables(void) | ||
222 | { | ||
223 | struct acpi_table_header *table; | ||
224 | u32 instance = 0; | ||
225 | acpi_physical_address address; | ||
226 | acpi_status status; | ||
227 | int table_status; | ||
228 | u32 i; | ||
229 | |||
230 | /* Get and dump all available ACPI tables */ | ||
231 | |||
232 | for (i = 0; i < AP_MAX_ACPI_FILES; i++) { | ||
233 | status = | ||
234 | acpi_os_get_table_by_index(i, &table, &instance, &address); | ||
235 | if (ACPI_FAILURE(status)) { | ||
236 | |||
237 | /* AE_LIMIT means that no more tables are available */ | ||
238 | |||
239 | if (status == AE_LIMIT) { | ||
240 | return (0); | ||
241 | } else if (i == 0) { | ||
242 | fprintf(stderr, | ||
243 | "Could not get ACPI tables, %s\n", | ||
244 | acpi_format_exception(status)); | ||
245 | return (-1); | ||
246 | } else { | ||
247 | fprintf(stderr, | ||
248 | "Could not get ACPI table at index %u, %s\n", | ||
249 | i, acpi_format_exception(status)); | ||
250 | continue; | ||
251 | } | ||
252 | } | ||
253 | |||
254 | table_status = ap_dump_table_buffer(table, instance, address); | ||
255 | free(table); | ||
256 | |||
257 | if (table_status) { | ||
258 | break; | ||
259 | } | ||
260 | } | ||
261 | |||
262 | /* Something seriously bad happened if the loop terminates here */ | ||
263 | |||
264 | return (-1); | ||
265 | } | ||
266 | |||
267 | /****************************************************************************** | ||
268 | * | ||
269 | * FUNCTION: ap_dump_table_by_address | ||
270 | * | ||
271 | * PARAMETERS: ascii_address - Address for requested ACPI table | ||
272 | * | ||
273 | * RETURN: Status | ||
274 | * | ||
275 | * DESCRIPTION: Get an ACPI table via a physical address and dump it. | ||
276 | * | ||
277 | ******************************************************************************/ | ||
278 | |||
279 | int ap_dump_table_by_address(char *ascii_address) | ||
280 | { | ||
281 | acpi_physical_address address; | ||
282 | struct acpi_table_header *table; | ||
283 | acpi_status status; | ||
284 | int table_status; | ||
285 | u64 long_address; | ||
286 | |||
287 | /* Convert argument to an integer physical address */ | ||
288 | |||
289 | status = acpi_ut_strtoul64(ascii_address, 0, &long_address); | ||
290 | if (ACPI_FAILURE(status)) { | ||
291 | fprintf(stderr, "%s: Could not convert to a physical address\n", | ||
292 | ascii_address); | ||
293 | return (-1); | ||
294 | } | ||
295 | |||
296 | address = (acpi_physical_address) long_address; | ||
297 | status = acpi_os_get_table_by_address(address, &table); | ||
298 | if (ACPI_FAILURE(status)) { | ||
299 | fprintf(stderr, "Could not get table at 0x%8.8X%8.8X, %s\n", | ||
300 | ACPI_FORMAT_UINT64(address), | ||
301 | acpi_format_exception(status)); | ||
302 | return (-1); | ||
303 | } | ||
304 | |||
305 | table_status = ap_dump_table_buffer(table, 0, address); | ||
306 | free(table); | ||
307 | return (table_status); | ||
308 | } | ||
309 | |||
310 | /****************************************************************************** | ||
311 | * | ||
312 | * FUNCTION: ap_dump_table_by_name | ||
313 | * | ||
314 | * PARAMETERS: signature - Requested ACPI table signature | ||
315 | * | ||
316 | * RETURN: Status | ||
317 | * | ||
318 | * DESCRIPTION: Get an ACPI table via a signature and dump it. Handles | ||
319 | * multiple tables with the same signature (SSDTs). | ||
320 | * | ||
321 | ******************************************************************************/ | ||
322 | |||
323 | int ap_dump_table_by_name(char *signature) | ||
324 | { | ||
325 | char local_signature[ACPI_NAME_SIZE + 1]; | ||
326 | u32 instance; | ||
327 | struct acpi_table_header *table; | ||
328 | acpi_physical_address address; | ||
329 | acpi_status status; | ||
330 | int table_status; | ||
331 | |||
332 | if (strlen(signature) != ACPI_NAME_SIZE) { | ||
333 | fprintf(stderr, | ||
334 | "Invalid table signature [%s]: must be exactly 4 characters\n", | ||
335 | signature); | ||
336 | return (-1); | ||
337 | } | ||
338 | |||
339 | /* Table signatures are expected to be uppercase */ | ||
340 | |||
341 | strcpy(local_signature, signature); | ||
342 | acpi_ut_strupr(local_signature); | ||
343 | |||
344 | /* To be friendly, handle tables whose signatures do not match the name */ | ||
345 | |||
346 | if (ACPI_COMPARE_NAME(local_signature, "FADT")) { | ||
347 | strcpy(local_signature, ACPI_SIG_FADT); | ||
348 | } else if (ACPI_COMPARE_NAME(local_signature, "MADT")) { | ||
349 | strcpy(local_signature, ACPI_SIG_MADT); | ||
350 | } | ||
351 | |||
352 | /* Dump all instances of this signature (to handle multiple SSDTs) */ | ||
353 | |||
354 | for (instance = 0; instance < AP_MAX_ACPI_FILES; instance++) { | ||
355 | status = acpi_os_get_table_by_name(local_signature, instance, | ||
356 | &table, &address); | ||
357 | if (ACPI_FAILURE(status)) { | ||
358 | |||
359 | /* AE_LIMIT means that no more tables are available */ | ||
360 | |||
361 | if (status == AE_LIMIT) { | ||
362 | return (0); | ||
363 | } | ||
364 | |||
365 | fprintf(stderr, | ||
366 | "Could not get ACPI table with signature [%s], %s\n", | ||
367 | local_signature, acpi_format_exception(status)); | ||
368 | return (-1); | ||
369 | } | ||
370 | |||
371 | table_status = ap_dump_table_buffer(table, instance, address); | ||
372 | free(table); | ||
373 | |||
374 | if (table_status) { | ||
375 | break; | ||
376 | } | ||
377 | } | ||
378 | |||
379 | /* Something seriously bad happened if the loop terminates here */ | ||
380 | |||
381 | return (-1); | ||
382 | } | ||
383 | |||
384 | /****************************************************************************** | ||
385 | * | ||
386 | * FUNCTION: ap_dump_table_from_file | ||
387 | * | ||
388 | * PARAMETERS: pathname - File containing the binary ACPI table | ||
389 | * | ||
390 | * RETURN: Status | ||
391 | * | ||
392 | * DESCRIPTION: Dump an ACPI table from a binary file | ||
393 | * | ||
394 | ******************************************************************************/ | ||
395 | |||
396 | int ap_dump_table_from_file(char *pathname) | ||
397 | { | ||
398 | struct acpi_table_header *table; | ||
399 | u32 file_size = 0; | ||
400 | int table_status = -1; | ||
401 | |||
402 | /* Get the entire ACPI table from the file */ | ||
403 | |||
404 | table = ap_get_table_from_file(pathname, &file_size); | ||
405 | if (!table) { | ||
406 | return (-1); | ||
407 | } | ||
408 | |||
409 | /* File must be at least as long as the table length */ | ||
410 | |||
411 | if (table->length > file_size) { | ||
412 | fprintf(stderr, | ||
413 | "Table length (0x%X) is too large for input file (0x%X) %s\n", | ||
414 | table->length, file_size, pathname); | ||
415 | goto exit; | ||
416 | } | ||
417 | |||
418 | if (gbl_verbose_mode) { | ||
419 | fprintf(stderr, | ||
420 | "Input file: %s contains table [%4.4s], 0x%X (%u) bytes\n", | ||
421 | pathname, table->signature, file_size, file_size); | ||
422 | } | ||
423 | |||
424 | table_status = ap_dump_table_buffer(table, 0, 0); | ||
425 | |||
426 | exit: | ||
427 | free(table); | ||
428 | return (table_status); | ||
429 | } | ||
430 | |||
431 | /****************************************************************************** | ||
432 | * | ||
433 | * FUNCTION: acpi_os* print functions | ||
434 | * | ||
435 | * DESCRIPTION: Used for linkage with ACPICA modules | ||
436 | * | ||
437 | ******************************************************************************/ | ||
438 | |||
439 | void ACPI_INTERNAL_VAR_XFACE acpi_os_printf(const char *fmt, ...) | ||
440 | { | ||
441 | va_list args; | ||
442 | |||
443 | va_start(args, fmt); | ||
444 | vfprintf(stdout, fmt, args); | ||
445 | va_end(args); | ||
446 | } | ||
447 | |||
448 | void acpi_os_vprintf(const char *fmt, va_list args) | ||
449 | { | ||
450 | vfprintf(stdout, fmt, args); | ||
451 | } | ||
diff --git a/tools/power/acpi/tools/acpidump/apfiles.c b/tools/power/acpi/tools/acpidump/apfiles.c new file mode 100644 index 000000000000..4488accc010b --- /dev/null +++ b/tools/power/acpi/tools/acpidump/apfiles.c | |||
@@ -0,0 +1,228 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: apfiles - File-related functions for acpidump utility | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2014, 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 "acpidump.h" | ||
45 | #include "acapps.h" | ||
46 | |||
47 | /****************************************************************************** | ||
48 | * | ||
49 | * FUNCTION: ap_open_output_file | ||
50 | * | ||
51 | * PARAMETERS: pathname - Output filename | ||
52 | * | ||
53 | * RETURN: Open file handle | ||
54 | * | ||
55 | * DESCRIPTION: Open a text output file for acpidump. Checks if file already | ||
56 | * exists. | ||
57 | * | ||
58 | ******************************************************************************/ | ||
59 | |||
60 | int ap_open_output_file(char *pathname) | ||
61 | { | ||
62 | struct stat stat_info; | ||
63 | FILE *file; | ||
64 | |||
65 | /* If file exists, prompt for overwrite */ | ||
66 | |||
67 | if (!stat(pathname, &stat_info)) { | ||
68 | fprintf(stderr, | ||
69 | "Target path already exists, overwrite? [y|n] "); | ||
70 | |||
71 | if (getchar() != 'y') { | ||
72 | return (-1); | ||
73 | } | ||
74 | } | ||
75 | |||
76 | /* Point stdout to the file */ | ||
77 | |||
78 | file = freopen(pathname, "w", stdout); | ||
79 | if (!file) { | ||
80 | perror("Could not open output file"); | ||
81 | return (-1); | ||
82 | } | ||
83 | |||
84 | /* Save the file and path */ | ||
85 | |||
86 | gbl_output_file = file; | ||
87 | gbl_output_filename = pathname; | ||
88 | return (0); | ||
89 | } | ||
90 | |||
91 | /****************************************************************************** | ||
92 | * | ||
93 | * FUNCTION: ap_write_to_binary_file | ||
94 | * | ||
95 | * PARAMETERS: table - ACPI table to be written | ||
96 | * instance - ACPI table instance no. to be written | ||
97 | * | ||
98 | * RETURN: Status | ||
99 | * | ||
100 | * DESCRIPTION: Write an ACPI table to a binary file. Builds the output | ||
101 | * filename from the table signature. | ||
102 | * | ||
103 | ******************************************************************************/ | ||
104 | |||
105 | int ap_write_to_binary_file(struct acpi_table_header *table, u32 instance) | ||
106 | { | ||
107 | char filename[ACPI_NAME_SIZE + 16]; | ||
108 | char instance_str[16]; | ||
109 | FILE *file; | ||
110 | size_t actual; | ||
111 | u32 table_length; | ||
112 | |||
113 | /* Obtain table length */ | ||
114 | |||
115 | table_length = ap_get_table_length(table); | ||
116 | |||
117 | /* Construct lower-case filename from the table local signature */ | ||
118 | |||
119 | if (ACPI_VALIDATE_RSDP_SIG(table->signature)) { | ||
120 | ACPI_MOVE_NAME(filename, ACPI_RSDP_NAME); | ||
121 | } else { | ||
122 | ACPI_MOVE_NAME(filename, table->signature); | ||
123 | } | ||
124 | filename[0] = (char)ACPI_TOLOWER(filename[0]); | ||
125 | filename[1] = (char)ACPI_TOLOWER(filename[1]); | ||
126 | filename[2] = (char)ACPI_TOLOWER(filename[2]); | ||
127 | filename[3] = (char)ACPI_TOLOWER(filename[3]); | ||
128 | filename[ACPI_NAME_SIZE] = 0; | ||
129 | |||
130 | /* Handle multiple SSDts - create different filenames for each */ | ||
131 | |||
132 | if (instance > 0) { | ||
133 | sprintf(instance_str, "%u", instance); | ||
134 | strcat(filename, instance_str); | ||
135 | } | ||
136 | |||
137 | strcat(filename, ACPI_TABLE_FILE_SUFFIX); | ||
138 | |||
139 | if (gbl_verbose_mode) { | ||
140 | fprintf(stderr, | ||
141 | "Writing [%4.4s] to binary file: %s 0x%X (%u) bytes\n", | ||
142 | table->signature, filename, table->length, | ||
143 | table->length); | ||
144 | } | ||
145 | |||
146 | /* Open the file and dump the entire table in binary mode */ | ||
147 | |||
148 | file = fopen(filename, "wb"); | ||
149 | if (!file) { | ||
150 | perror("Could not open output file"); | ||
151 | return (-1); | ||
152 | } | ||
153 | |||
154 | actual = fwrite(table, 1, table_length, file); | ||
155 | if (actual != table_length) { | ||
156 | perror("Error writing binary output file"); | ||
157 | fclose(file); | ||
158 | return (-1); | ||
159 | } | ||
160 | |||
161 | fclose(file); | ||
162 | return (0); | ||
163 | } | ||
164 | |||
165 | /****************************************************************************** | ||
166 | * | ||
167 | * FUNCTION: ap_get_table_from_file | ||
168 | * | ||
169 | * PARAMETERS: pathname - File containing the binary ACPI table | ||
170 | * out_file_size - Where the file size is returned | ||
171 | * | ||
172 | * RETURN: Buffer containing the ACPI table. NULL on error. | ||
173 | * | ||
174 | * DESCRIPTION: Open a file and read it entirely into a new buffer | ||
175 | * | ||
176 | ******************************************************************************/ | ||
177 | |||
178 | struct acpi_table_header *ap_get_table_from_file(char *pathname, | ||
179 | u32 *out_file_size) | ||
180 | { | ||
181 | struct acpi_table_header *buffer = NULL; | ||
182 | FILE *file; | ||
183 | u32 file_size; | ||
184 | size_t actual; | ||
185 | |||
186 | /* Must use binary mode */ | ||
187 | |||
188 | file = fopen(pathname, "rb"); | ||
189 | if (!file) { | ||
190 | perror("Could not open input file"); | ||
191 | return (NULL); | ||
192 | } | ||
193 | |||
194 | /* Need file size to allocate a buffer */ | ||
195 | |||
196 | file_size = cm_get_file_size(file); | ||
197 | if (file_size == ACPI_UINT32_MAX) { | ||
198 | fprintf(stderr, | ||
199 | "Could not get input file size: %s\n", pathname); | ||
200 | goto cleanup; | ||
201 | } | ||
202 | |||
203 | /* Allocate a buffer for the entire file */ | ||
204 | |||
205 | buffer = calloc(1, file_size); | ||
206 | if (!buffer) { | ||
207 | fprintf(stderr, | ||
208 | "Could not allocate file buffer of size: %u\n", | ||
209 | file_size); | ||
210 | goto cleanup; | ||
211 | } | ||
212 | |||
213 | /* Read the entire file */ | ||
214 | |||
215 | actual = fread(buffer, 1, file_size, file); | ||
216 | if (actual != file_size) { | ||
217 | fprintf(stderr, "Could not read input file: %s\n", pathname); | ||
218 | free(buffer); | ||
219 | buffer = NULL; | ||
220 | goto cleanup; | ||
221 | } | ||
222 | |||
223 | *out_file_size = file_size; | ||
224 | |||
225 | cleanup: | ||
226 | fclose(file); | ||
227 | return (buffer); | ||
228 | } | ||
diff --git a/tools/power/acpi/tools/acpidump/apmain.c b/tools/power/acpi/tools/acpidump/apmain.c new file mode 100644 index 000000000000..51e8d638db18 --- /dev/null +++ b/tools/power/acpi/tools/acpidump/apmain.c | |||
@@ -0,0 +1,351 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: apmain - Main module for the acpidump utility | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2014, 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 _DECLARE_GLOBALS | ||
45 | #include "acpidump.h" | ||
46 | #include "acapps.h" | ||
47 | |||
48 | /* | ||
49 | * acpidump - A portable utility for obtaining system ACPI tables and dumping | ||
50 | * them in an ASCII hex format suitable for binary extraction via acpixtract. | ||
51 | * | ||
52 | * Obtaining the system ACPI tables is an OS-specific operation. | ||
53 | * | ||
54 | * This utility can be ported to any host operating system by providing a | ||
55 | * module containing system-specific versions of these interfaces: | ||
56 | * | ||
57 | * acpi_os_get_table_by_address | ||
58 | * acpi_os_get_table_by_index | ||
59 | * acpi_os_get_table_by_name | ||
60 | * | ||
61 | * See the ACPICA Reference Guide for the exact definitions of these | ||
62 | * interfaces. Also, see these ACPICA source code modules for example | ||
63 | * implementations: | ||
64 | * | ||
65 | * source/os_specific/service_layers/oswintbl.c | ||
66 | * source/os_specific/service_layers/oslinuxtbl.c | ||
67 | */ | ||
68 | |||
69 | /* Local prototypes */ | ||
70 | |||
71 | static void ap_display_usage(void); | ||
72 | |||
73 | static int ap_do_options(int argc, char **argv); | ||
74 | |||
75 | static void ap_insert_action(char *argument, u32 to_be_done); | ||
76 | |||
77 | /* Table for deferred actions from command line options */ | ||
78 | |||
79 | struct ap_dump_action action_table[AP_MAX_ACTIONS]; | ||
80 | u32 current_action = 0; | ||
81 | |||
82 | #define AP_UTILITY_NAME "ACPI Binary Table Dump Utility" | ||
83 | #define AP_SUPPORTED_OPTIONS "?a:bcf:hn:o:r:svxz" | ||
84 | |||
85 | /****************************************************************************** | ||
86 | * | ||
87 | * FUNCTION: ap_display_usage | ||
88 | * | ||
89 | * DESCRIPTION: Usage message for the acpi_dump utility | ||
90 | * | ||
91 | ******************************************************************************/ | ||
92 | |||
93 | static void ap_display_usage(void) | ||
94 | { | ||
95 | |||
96 | ACPI_USAGE_HEADER("acpidump [options]"); | ||
97 | |||
98 | ACPI_OPTION("-b", "Dump tables to binary files"); | ||
99 | ACPI_OPTION("-c", "Dump customized tables"); | ||
100 | ACPI_OPTION("-h -?", "This help message"); | ||
101 | ACPI_OPTION("-o <File>", "Redirect output to file"); | ||
102 | ACPI_OPTION("-r <Address>", "Dump tables from specified RSDP"); | ||
103 | ACPI_OPTION("-s", "Print table summaries only"); | ||
104 | ACPI_OPTION("-v", "Display version information"); | ||
105 | ACPI_OPTION("-z", "Verbose mode"); | ||
106 | |||
107 | printf("\nTable Options:\n"); | ||
108 | |||
109 | ACPI_OPTION("-a <Address>", "Get table via a physical address"); | ||
110 | ACPI_OPTION("-f <BinaryFile>", "Get table via a binary file"); | ||
111 | ACPI_OPTION("-n <Signature>", "Get table via a name/signature"); | ||
112 | ACPI_OPTION("-x", "Do not use but dump XSDT"); | ||
113 | ACPI_OPTION("-x -x", "Do not use or dump XSDT"); | ||
114 | |||
115 | printf("\n" | ||
116 | "Invocation without parameters dumps all available tables\n" | ||
117 | "Multiple mixed instances of -a, -f, and -n are supported\n\n"); | ||
118 | } | ||
119 | |||
120 | /****************************************************************************** | ||
121 | * | ||
122 | * FUNCTION: ap_insert_action | ||
123 | * | ||
124 | * PARAMETERS: argument - Pointer to the argument for this action | ||
125 | * to_be_done - What to do to process this action | ||
126 | * | ||
127 | * RETURN: None. Exits program if action table becomes full. | ||
128 | * | ||
129 | * DESCRIPTION: Add an action item to the action table | ||
130 | * | ||
131 | ******************************************************************************/ | ||
132 | |||
133 | static void ap_insert_action(char *argument, u32 to_be_done) | ||
134 | { | ||
135 | |||
136 | /* Insert action and check for table overflow */ | ||
137 | |||
138 | action_table[current_action].argument = argument; | ||
139 | action_table[current_action].to_be_done = to_be_done; | ||
140 | |||
141 | current_action++; | ||
142 | if (current_action > AP_MAX_ACTIONS) { | ||
143 | fprintf(stderr, "Too many table options (max %u)\n", | ||
144 | AP_MAX_ACTIONS); | ||
145 | exit(-1); | ||
146 | } | ||
147 | } | ||
148 | |||
149 | /****************************************************************************** | ||
150 | * | ||
151 | * FUNCTION: ap_do_options | ||
152 | * | ||
153 | * PARAMETERS: argc/argv - Standard argc/argv | ||
154 | * | ||
155 | * RETURN: Status | ||
156 | * | ||
157 | * DESCRIPTION: Command line option processing. The main actions for getting | ||
158 | * and dumping tables are deferred via the action table. | ||
159 | * | ||
160 | *****************************************************************************/ | ||
161 | |||
162 | static int ap_do_options(int argc, char **argv) | ||
163 | { | ||
164 | int j; | ||
165 | acpi_status status; | ||
166 | |||
167 | /* Command line options */ | ||
168 | |||
169 | while ((j = acpi_getopt(argc, argv, AP_SUPPORTED_OPTIONS)) != EOF) | ||
170 | switch (j) { | ||
171 | /* | ||
172 | * Global options | ||
173 | */ | ||
174 | case 'b': /* Dump all input tables to binary files */ | ||
175 | |||
176 | gbl_binary_mode = TRUE; | ||
177 | continue; | ||
178 | |||
179 | case 'c': /* Dump customized tables */ | ||
180 | |||
181 | gbl_dump_customized_tables = TRUE; | ||
182 | continue; | ||
183 | |||
184 | case 'h': | ||
185 | case '?': | ||
186 | |||
187 | ap_display_usage(); | ||
188 | exit(0); | ||
189 | |||
190 | case 'o': /* Redirect output to a single file */ | ||
191 | |||
192 | if (ap_open_output_file(acpi_gbl_optarg)) { | ||
193 | exit(-1); | ||
194 | } | ||
195 | continue; | ||
196 | |||
197 | case 'r': /* Dump tables from specified RSDP */ | ||
198 | |||
199 | status = | ||
200 | acpi_ut_strtoul64(acpi_gbl_optarg, 0, | ||
201 | &gbl_rsdp_base); | ||
202 | if (ACPI_FAILURE(status)) { | ||
203 | fprintf(stderr, | ||
204 | "%s: Could not convert to a physical address\n", | ||
205 | acpi_gbl_optarg); | ||
206 | exit(-1); | ||
207 | } | ||
208 | continue; | ||
209 | |||
210 | case 's': /* Print table summaries only */ | ||
211 | |||
212 | gbl_summary_mode = TRUE; | ||
213 | continue; | ||
214 | |||
215 | case 'x': /* Do not use XSDT */ | ||
216 | |||
217 | if (!acpi_gbl_do_not_use_xsdt) { | ||
218 | acpi_gbl_do_not_use_xsdt = TRUE; | ||
219 | } else { | ||
220 | gbl_do_not_dump_xsdt = TRUE; | ||
221 | } | ||
222 | continue; | ||
223 | |||
224 | case 'v': /* Revision/version */ | ||
225 | |||
226 | printf(ACPI_COMMON_SIGNON(AP_UTILITY_NAME)); | ||
227 | exit(0); | ||
228 | |||
229 | case 'z': /* Verbose mode */ | ||
230 | |||
231 | gbl_verbose_mode = TRUE; | ||
232 | fprintf(stderr, ACPI_COMMON_SIGNON(AP_UTILITY_NAME)); | ||
233 | continue; | ||
234 | |||
235 | /* | ||
236 | * Table options | ||
237 | */ | ||
238 | case 'a': /* Get table by physical address */ | ||
239 | |||
240 | ap_insert_action(acpi_gbl_optarg, | ||
241 | AP_DUMP_TABLE_BY_ADDRESS); | ||
242 | break; | ||
243 | |||
244 | case 'f': /* Get table from a file */ | ||
245 | |||
246 | ap_insert_action(acpi_gbl_optarg, | ||
247 | AP_DUMP_TABLE_BY_FILE); | ||
248 | break; | ||
249 | |||
250 | case 'n': /* Get table by input name (signature) */ | ||
251 | |||
252 | ap_insert_action(acpi_gbl_optarg, | ||
253 | AP_DUMP_TABLE_BY_NAME); | ||
254 | break; | ||
255 | |||
256 | default: | ||
257 | |||
258 | ap_display_usage(); | ||
259 | exit(-1); | ||
260 | } | ||
261 | |||
262 | /* If there are no actions, this means "get/dump all tables" */ | ||
263 | |||
264 | if (current_action == 0) { | ||
265 | ap_insert_action(NULL, AP_DUMP_ALL_TABLES); | ||
266 | } | ||
267 | |||
268 | return (0); | ||
269 | } | ||
270 | |||
271 | /****************************************************************************** | ||
272 | * | ||
273 | * FUNCTION: main | ||
274 | * | ||
275 | * PARAMETERS: argc/argv - Standard argc/argv | ||
276 | * | ||
277 | * RETURN: Status | ||
278 | * | ||
279 | * DESCRIPTION: C main function for acpidump utility | ||
280 | * | ||
281 | ******************************************************************************/ | ||
282 | |||
283 | int ACPI_SYSTEM_XFACE main(int argc, char *argv[]) | ||
284 | { | ||
285 | int status = 0; | ||
286 | struct ap_dump_action *action; | ||
287 | u32 file_size; | ||
288 | u32 i; | ||
289 | |||
290 | ACPI_DEBUG_INITIALIZE(); /* For debug version only */ | ||
291 | |||
292 | /* Process command line options */ | ||
293 | |||
294 | if (ap_do_options(argc, argv)) { | ||
295 | return (-1); | ||
296 | } | ||
297 | |||
298 | /* Get/dump ACPI table(s) as requested */ | ||
299 | |||
300 | for (i = 0; i < current_action; i++) { | ||
301 | action = &action_table[i]; | ||
302 | switch (action->to_be_done) { | ||
303 | case AP_DUMP_ALL_TABLES: | ||
304 | |||
305 | status = ap_dump_all_tables(); | ||
306 | break; | ||
307 | |||
308 | case AP_DUMP_TABLE_BY_ADDRESS: | ||
309 | |||
310 | status = ap_dump_table_by_address(action->argument); | ||
311 | break; | ||
312 | |||
313 | case AP_DUMP_TABLE_BY_NAME: | ||
314 | |||
315 | status = ap_dump_table_by_name(action->argument); | ||
316 | break; | ||
317 | |||
318 | case AP_DUMP_TABLE_BY_FILE: | ||
319 | |||
320 | status = ap_dump_table_from_file(action->argument); | ||
321 | break; | ||
322 | |||
323 | default: | ||
324 | |||
325 | fprintf(stderr, | ||
326 | "Internal error, invalid action: 0x%X\n", | ||
327 | action->to_be_done); | ||
328 | return (-1); | ||
329 | } | ||
330 | |||
331 | if (status) { | ||
332 | return (status); | ||
333 | } | ||
334 | } | ||
335 | |||
336 | if (gbl_output_file) { | ||
337 | if (gbl_verbose_mode) { | ||
338 | |||
339 | /* Summary for the output file */ | ||
340 | |||
341 | file_size = cm_get_file_size(gbl_output_file); | ||
342 | fprintf(stderr, | ||
343 | "Output file %s contains 0x%X (%u) bytes\n\n", | ||
344 | gbl_output_filename, file_size, file_size); | ||
345 | } | ||
346 | |||
347 | fclose(gbl_output_file); | ||
348 | } | ||
349 | |||
350 | return (status); | ||
351 | } | ||