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