1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#define pr_fmt(fmt) "ACPI: " fmt
17
18#include <linux/acpi.h>
19#include <linux/bootmem.h>
20#include <linux/cpumask.h>
21#include <linux/efi.h>
22#include <linux/efi-bgrt.h>
23#include <linux/init.h>
24#include <linux/irq.h>
25#include <linux/irqdomain.h>
26#include <linux/memblock.h>
27#include <linux/of_fdt.h>
28#include <linux/smp.h>
29#include <linux/serial_core.h>
30
31#include <asm/cputype.h>
32#include <asm/cpu_ops.h>
33#include <asm/pgtable.h>
34#include <asm/smp_plat.h>
35
36int acpi_noirq = 1;
37int acpi_disabled = 1;
38EXPORT_SYMBOL(acpi_disabled);
39
40int acpi_pci_disabled = 1;
41EXPORT_SYMBOL(acpi_pci_disabled);
42
43static bool param_acpi_off __initdata;
44static bool param_acpi_on __initdata = true;
45static bool param_acpi_force __initdata;
46
47static int __init parse_acpi(char *arg)
48{
49 if (!arg)
50 return -EINVAL;
51
52
53 if (strcmp(arg, "off") == 0)
54 param_acpi_off = true;
55 else if (strcmp(arg, "on") == 0)
56 param_acpi_on = true;
57 else if (strcmp(arg, "force") == 0)
58 param_acpi_force = true;
59 else
60 return -EINVAL;
61
62 return 0;
63}
64early_param("acpi", parse_acpi);
65
66static int __init dt_scan_depth1_nodes(unsigned long node,
67 const char *uname, int depth,
68 void *data)
69{
70
71
72
73
74 if (depth != 1)
75 return 0;
76
77 if (strcmp(uname, "chosen") == 0)
78 return 0;
79
80 if (strcmp(uname, "hypervisor") == 0 &&
81 of_flat_dt_is_compatible(node, "xen,xen"))
82 return 0;
83
84
85
86
87
88 return 1;
89}
90
91
92
93
94
95void __init __iomem *__acpi_map_table(unsigned long phys, unsigned long size)
96{
97 if (!size)
98 return NULL;
99
100 return early_memremap(phys, size);
101}
102
103void __init __acpi_unmap_table(void __iomem *map, unsigned long size)
104{
105 if (!map || !size)
106 return;
107
108 early_memunmap(map, size);
109}
110
111bool __init acpi_psci_present(void)
112{
113 return acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_COMPLIANT;
114}
115
116
117bool acpi_psci_use_hvc(void)
118{
119 return acpi_gbl_FADT.arm_boot_flags & ACPI_FADT_PSCI_USE_HVC;
120}
121
122
123
124
125
126
127
128static int __init acpi_fadt_sanity_check(void)
129{
130 struct acpi_table_header *table;
131 struct acpi_table_fadt *fadt;
132 acpi_status status;
133 int ret = 0;
134
135
136
137
138
139 status = acpi_get_table(ACPI_SIG_FADT, 0, &table);
140 if (ACPI_FAILURE(status)) {
141 const char *msg = acpi_format_exception(status);
142
143 pr_err("Failed to get FADT table, %s\n", msg);
144 return -ENODEV;
145 }
146
147 fadt = (struct acpi_table_fadt *)table;
148
149
150
151
152
153
154
155 if (table->revision < 5 ||
156 (table->revision == 5 && fadt->minor_revision < 1)) {
157 pr_err("Unsupported FADT revision %d.%d, should be 5.1+\n",
158 table->revision, fadt->minor_revision);
159 ret = -EINVAL;
160 goto out;
161 }
162
163 if (!(fadt->flags & ACPI_FADT_HW_REDUCED)) {
164 pr_err("FADT not ACPI hardware reduced compliant\n");
165 ret = -EINVAL;
166 }
167
168out:
169
170
171
172
173 acpi_put_table(table);
174 return ret;
175}
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195void __init acpi_boot_table_init(void)
196{
197
198
199
200
201
202
203
204 if (param_acpi_off ||
205 (!param_acpi_on && !param_acpi_force &&
206 of_scan_flat_dt(dt_scan_depth1_nodes, NULL)))
207 goto done;
208
209
210
211
212
213 enable_acpi();
214
215
216
217
218
219
220
221
222 if (acpi_table_init() || acpi_fadt_sanity_check()) {
223 pr_err("Failed to init ACPI tables\n");
224 if (!param_acpi_force)
225 disable_acpi();
226 }
227
228done:
229 if (acpi_disabled) {
230 if (earlycon_acpi_spcr_enable)
231 early_init_dt_scan_chosen_stdout();
232 } else {
233 acpi_parse_spcr(earlycon_acpi_spcr_enable, true);
234 if (IS_ENABLED(CONFIG_ACPI_BGRT))
235 acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt);
236 }
237}
238
239pgprot_t __acpi_get_mem_attribute(phys_addr_t addr)
240{
241
242
243
244
245
246
247
248
249 u64 attr;
250
251 attr = efi_mem_attributes(addr);
252 if (attr & EFI_MEMORY_WB)
253 return PAGE_KERNEL;
254 if (attr & EFI_MEMORY_WT)
255 return __pgprot(PROT_NORMAL_WT);
256 if (attr & EFI_MEMORY_WC)
257 return __pgprot(PROT_NORMAL_NC);
258 return __pgprot(PROT_DEVICE_nGnRnE);
259}
260