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