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