1 /*
2 * ARM Specific Low-Level ACPI Boot Support
3 *
4 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
5 * Copyright (C) 2001 Jun Nakajima <jun.nakajima@intel.com>
6 * Copyright (C) 2014, Naresh Bhat <naresh.bhat@linaro.org>
7 * Copyright (C) 2015, Shannon Zhao <shannon.zhao@linaro.org>
8 *
9 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
26 */
27
28 #include <xen/init.h>
29 #include <xen/acpi.h>
30 #include <xen/errno.h>
31 #include <acpi/actables.h>
32 #include <xen/mm.h>
33 #include <xen/param.h>
34 #include <xen/device_tree.h>
35
36 #include <asm/acpi.h>
37 #include <asm/smp.h>
38 #include <asm/setup.h>
39
40 /* Processors with enabled flag and sane MPIDR */
41 static unsigned int __initdata enabled_cpus = 1;
42 static bool __initdata bootcpu_valid;
43
44 /* total number of cpus in this system */
45 static unsigned int __initdata total_cpus;
46
47 /*
48 * acpi_map_gic_cpu_interface - generates a logical cpu number
49 * and map to MPIDR represented by GICC structure
50 */
51 static void __init
acpi_map_gic_cpu_interface(struct acpi_madt_generic_interrupt * processor)52 acpi_map_gic_cpu_interface(struct acpi_madt_generic_interrupt *processor)
53 {
54 int i;
55 int rc;
56 u64 mpidr = processor->arm_mpidr & MPIDR_HWID_MASK;
57 bool enabled = processor->flags & ACPI_MADT_ENABLED;
58
59 if ( mpidr == MPIDR_INVALID )
60 {
61 printk("Skip MADT cpu entry with invalid MPIDR\n");
62 return;
63 }
64
65 total_cpus++;
66 if ( !enabled )
67 {
68 printk("Skipping disabled CPU entry with 0x%"PRIx64" MPIDR\n", mpidr);
69 return;
70 }
71
72 if ( enabled_cpus >= NR_CPUS )
73 {
74 printk("NR_CPUS limit of %d reached, Processor %d/0x%"PRIx64" ignored.\n",
75 NR_CPUS, total_cpus, mpidr);
76 return;
77 }
78
79 /* Check if GICC structure of boot CPU is available in the MADT */
80 if ( cpu_logical_map(0) == mpidr )
81 {
82 if ( bootcpu_valid )
83 {
84 printk("Firmware bug, duplicate boot CPU MPIDR: 0x%"PRIx64" in MADT\n",
85 mpidr);
86 return;
87 }
88 bootcpu_valid = true;
89 return;
90 }
91
92 /*
93 * Duplicate MPIDRs are a recipe for disaster. Scan
94 * all initialized entries and check for
95 * duplicates. If any is found just ignore the CPU.
96 */
97 for ( i = 1; i < enabled_cpus; i++ )
98 {
99 if ( cpu_logical_map(i) == mpidr )
100 {
101 printk("Firmware bug, duplicate CPU MPIDR: 0x%"PRIx64" in MADT\n",
102 mpidr);
103 return;
104 }
105 }
106
107 if ( !acpi_psci_present() )
108 {
109 printk("PSCI not present, skipping CPU MPIDR 0x%"PRIx64"\n",
110 mpidr);
111 return;
112 }
113
114 if ( (rc = arch_cpu_init(enabled_cpus, NULL)) < 0 )
115 {
116 printk("cpu%d: init failed (0x%"PRIx64" MPIDR): %d\n",
117 enabled_cpus, mpidr, rc);
118 return;
119 }
120
121 /* map the logical cpu id to cpu MPIDR */
122 cpu_logical_map(enabled_cpus) = mpidr;
123
124 enabled_cpus++;
125 }
126
127 static int __init
acpi_parse_gic_cpu_interface(struct acpi_subtable_header * header,const unsigned long end)128 acpi_parse_gic_cpu_interface(struct acpi_subtable_header *header,
129 const unsigned long end)
130 {
131 struct acpi_madt_generic_interrupt *processor =
132 container_of(header, struct acpi_madt_generic_interrupt, header);
133
134 if ( BAD_MADT_ENTRY(processor, end) )
135 return -EINVAL;
136
137 acpi_table_print_madt_entry(header);
138 acpi_map_gic_cpu_interface(processor);
139 return 0;
140 }
141
142 /* Parse GIC cpu interface entries in MADT for SMP init */
acpi_smp_init_cpus(void)143 void __init acpi_smp_init_cpus(void)
144 {
145 int count, i;
146
147 /*
148 * do a partial walk of MADT to determine how many CPUs
149 * we have including disabled CPUs, and get information
150 * we need for SMP init
151 */
152 count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT,
153 acpi_parse_gic_cpu_interface, 0);
154
155 if ( count <= 0 )
156 {
157 printk("Error parsing GIC CPU interface entry\n");
158 return;
159 }
160
161 if ( !bootcpu_valid )
162 {
163 printk("MADT missing boot CPU MPIDR, not enabling secondaries\n");
164 return;
165 }
166
167 for ( i = 0; i < enabled_cpus; i++ )
168 cpumask_set_cpu(i, &cpu_possible_map);
169
170 /* Make boot-up look pretty */
171 printk("%d CPUs enabled, %d CPUs total\n", enabled_cpus, total_cpus);
172 }
173
acpi_parse_fadt(struct acpi_table_header * table)174 static int __init acpi_parse_fadt(struct acpi_table_header *table)
175 {
176 struct acpi_table_fadt *fadt = (struct acpi_table_fadt *)table;
177
178 /*
179 * Revision in table header is the FADT Major revision, and there
180 * is a minor revision of FADT which was introduced by ACPI 6.0,
181 * we only deal with ACPI 6.0 or newer revision to get GIC and SMP
182 * boot protocol configuration data, or we will disable ACPI.
183 */
184 if ( table->revision > 6
185 || (table->revision == 6 && fadt->minor_revision >= 0) )
186 return 0;
187
188 printk("Unsupported FADT revision %d.%d, should be 6.0+, will disable ACPI\n",
189 table->revision, fadt->minor_revision);
190
191 return -EINVAL;
192 }
193
194 static bool __initdata param_acpi_off;
195 static bool __initdata param_acpi_force;
196
parse_acpi_param(const char * arg)197 static int __init parse_acpi_param(const char *arg)
198 {
199 if ( !arg )
200 return -EINVAL;
201
202 /* Interpret the parameter for use within Xen. */
203 if ( !parse_bool(arg, NULL) )
204 param_acpi_off = true;
205 else if ( !strcmp(arg, "force") ) /* force ACPI to be enabled */
206 param_acpi_force = true;
207 else
208 return -EINVAL;
209
210 return 0;
211 }
212 custom_param("acpi", parse_acpi_param);
213
dt_scan_depth1_nodes(const void * fdt,int node,const char * uname,int depth,u32 address_cells,u32 size_cells,void * data)214 static int __init dt_scan_depth1_nodes(const void *fdt, int node,
215 const char *uname, int depth,
216 u32 address_cells, u32 size_cells,
217 void *data)
218 {
219 /*
220 * Return 1 as soon as we encounter a node at depth 1 that is
221 * not the /chosen node.
222 */
223 if (depth == 1 && (strcmp(uname, "chosen") != 0))
224 return 1;
225 return 0;
226 }
227
228 /*
229 * acpi_boot_table_init() called from setup_arch(), always.
230 * 1. find RSDP and get its address, and then find XSDT
231 * 2. extract all tables and checksums them all
232 *
233 * return value: (currently ignored)
234 * 0: success
235 * !0: failure
236 *
237 * We can parse ACPI boot-time tables such as FADT, MADT after
238 * this function is called.
239 */
acpi_boot_table_init(void)240 int __init acpi_boot_table_init(void)
241 {
242 int error = 0;
243
244 /*
245 * Enable ACPI instead of device tree unless
246 * - ACPI has been disabled explicitly (acpi=off), or
247 * - the device tree is not empty (it has more than just a /chosen node)
248 * and ACPI has not been force enabled (acpi=force)
249 */
250 if ( param_acpi_off)
251 goto disable;
252 if ( !param_acpi_force &&
253 device_tree_for_each_node(device_tree_flattened, 0,
254 dt_scan_depth1_nodes, NULL) )
255 goto disable;
256
257 /*
258 * ACPI is disabled at this point. Enable it in order to parse
259 * the ACPI tables.
260 */
261 enable_acpi();
262
263 /* Initialize the ACPI boot-time table parser. */
264 error = acpi_table_init();
265 if ( error )
266 {
267 printk("%s: Unable to initialize table parser (%d)\n",
268 __FUNCTION__, error);
269 goto disable;
270 }
271
272 error = acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt);
273 if ( error )
274 {
275 printk("%s: FADT not found (%d)\n", __FUNCTION__, error);
276 goto disable;
277 }
278
279 return 0;
280
281 disable:
282 disable_acpi();
283
284 return error;
285 }
286