ia64/xen-unstable

view xen/arch/powerpc/ofd_fixup.c @ 13934:b8fac1c5e6ae

[XEN][POWERPC] more ofd /cpus fixups

Correct comment on why we prune secondary processors on the devtree.
Get rid of a particularly annoying non-standard cpu property.

Signed-off-by: Jimi Xenidis <jimix@watson.ibm.com>
author Jimi Xenidis <jimix@watson.ibm.com>
date Sat Jan 20 18:59:32 2007 -0500 (2007-01-20)
parents b4594f072a89
children 978ff6fad81f
line source
1 /*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 *
16 * Copyright (C) IBM Corp. 2005, 2006
17 *
18 * Authors: Jimi Xenidis <jimix@watson.ibm.com>
19 */
21 #include <xen/config.h>
22 #include <xen/lib.h>
23 #include <xen/sched.h>
24 #include <xen/version.h>
25 #include <public/xen.h>
26 #include "of-devtree.h"
27 #include "oftree.h"
28 #include "rtas.h"
30 #undef RTAS
32 ofdn_t ofd_boot_cpu;
34 #ifdef PAPR_VTERM
35 static ofdn_t ofd_vdevice_vty(void *m, ofdn_t p, struct domain *d)
36 {
37 ofdn_t n;
38 static const char pathfmt[] = "/vdevice/vty@%x";
39 static const char name[] = "vty";
40 static const char compatible[] = "hvterm1";
41 static const char device_type[] = "serial";
42 char path[sizeof (pathfmt) + 8 - 2];
43 int client = 0;
45 snprintf(path, sizeof (path), pathfmt, client);
46 n = ofd_node_add(m, p, path, sizeof (path));
48 if (n > 0) {
49 u32 val32;
51 val32 = client;
52 ofd_prop_add(m, n, "name", name, sizeof (name));
53 ofd_prop_add(m, n, "reg", &val32, sizeof (val32));
54 ofd_prop_add(m, n, "compatible",
55 compatible, sizeof (compatible));
56 ofd_prop_add(m, n, "device_type",
57 device_type, sizeof (device_type));
58 }
60 return n;
61 }
62 #endif
64 #ifdef PAPR_VDEVICE
65 static ofdn_t ofd_vdevice(void *m, struct domain *d)
66 {
67 ofdn_t n;
68 static const char path[] = "/vdevice";
69 static const char name[] = "vdevice";
70 static const char compatible[] = "IBM,vdevice";
71 u32 val;
73 n = ofd_node_add(m, OFD_ROOT, path, sizeof (path));
75 if (n > 0) {
77 ofd_prop_add(m, n, "name", name, sizeof (name));
78 val = 1;
79 ofd_prop_add(m, n, "#address-cells", &val, sizeof (val));
80 val = 0;
81 ofd_prop_add(m, n, "#size-cells", &val, sizeof (val));
82 ofd_prop_add(m, n, "compatible",
83 compatible, sizeof (compatible));
84 ofd_prop_add(m, n, "device_type", name, sizeof (name));
85 ofd_prop_add(m, n, "interupt-controller", NULL, 0);
87 #ifdef PAPR_VDEVICE
88 ofdn_t r;
90 /* add vty */
91 r = ofd_vdevice_vty(m, n, d);
92 printk("vdevice r: %x\n", r);
93 n = r;
94 #endif
95 }
96 return n;
97 }
98 #endif
100 static ofdn_t ofd_openprom_props(void *m)
101 {
102 static const char path[] = "/openprom";
103 static const char vernum[] = "IBM,XenOF0.1";
104 ofdn_t n;
106 n = ofd_node_find(m, path);
107 if (n == 0) {
108 n = ofd_node_add(m, OFD_ROOT, path, sizeof (path));
109 ofd_prop_add(m, n, "name",
110 &path[1], sizeof (path) - 1);
111 }
112 /* I want to override */
113 ofd_prop_add(m, n, "model", vernum, sizeof(vernum));
114 ofd_prop_add(m, n, "ibm,fw-vernum_encoded", vernum, sizeof(vernum));
115 ofd_prop_add(m, n, "relative-addressing", NULL, 0);
116 return n;
118 }
120 #ifdef PAPR_VTERM
121 static ofdn_t ofd_aliases_props(void *m)
122 {
123 static const char path[] = "/aliases";
124 static const char screen[] = "/vdevice/vty@0";
125 ofdn_t n;
127 n = ofd_node_find(m, path);
128 if (n == 0) {
129 n = ofd_node_add(m, OFD_ROOT, path, sizeof (path));
130 ofd_prop_add(m, n, "name",
131 &path[1], sizeof (path) - 1);
132 }
133 ofd_prop_add(m, n, "screen", screen, sizeof(screen));
134 return n;
135 }
136 #endif
138 static ofdn_t ofd_options_props(void *m)
139 {
140 static const char path[] = "/options";
141 static const char boot[] = "true";
142 ofdn_t n;
144 n = ofd_node_find(m, path);
145 if (n == 0) {
146 n = ofd_node_add(m, OFD_ROOT, path, sizeof (path));
147 ofd_prop_add(m, n, "name",
148 &path[1], sizeof (path) - 1);
149 }
150 ofd_prop_add(m, n, "auto-boot?", boot, sizeof(boot));
151 return n;
152 }
154 static ofdn_t ofd_cpus_props(void *m, struct domain *d)
155 {
156 static const char path[] = "/cpus";
157 static const char cpu[] = "cpu";
158 u32 val = 1;
159 ofdn_t n;
160 ofdn_t c;
161 static u32 ibm_pft_size[] = { 0x0, 0x0 };
163 n = ofd_node_find(m, path);
164 if (n == 0) {
165 n = ofd_node_add(m, OFD_ROOT, path, sizeof (path));
166 ofd_prop_add(m, n, "name",
167 &path[1], sizeof (path) - 1);
168 }
169 ofd_prop_add(m, n, "#address-cells", &val, sizeof(val));
170 ofd_prop_add(m, n, "#size-cells", &val, sizeof(val));
171 ofd_prop_add(m, n, "smp-enabled", NULL, 0);
173 #ifdef HV_EXPOSE_PERFORMANCE_MONITOR
174 ofd_prop_add(m, n, "performance-monitor", NULL, 0);
175 #endif
177 c = ofd_node_find_by_prop(m, n, "device_type", cpu, sizeof (cpu));
178 if (ofd_boot_cpu == -1)
179 ofd_boot_cpu = c;
180 while (c > 0) {
181 /* We do not use the OF tree to identify secondary processors
182 * so we must prune them from the tree */
183 if (c == ofd_boot_cpu) {
184 ofdn_t p;
186 ibm_pft_size[1] = d->arch.htab.log_num_ptes + LOG_PTE_SIZE;
187 ofd_prop_add(m, c, "ibm,pft-size",
188 ibm_pft_size, sizeof (ibm_pft_size));
190 /* get rid of non-standard properties */
191 p = ofd_prop_find(m, c, "cpu#");
192 if (p > 0) {
193 ofd_prop_remove(m, c, p);
194 }
196 /* FIXME: Check the the "l2-cache" property who's
197 * contents is an orphaned phandle? */
198 } else
199 ofd_node_prune(m, c);
201 c = ofd_node_find_next(m, c);
202 }
204 return n;
205 }
207 #ifdef ADD_XICS
208 static ofdn_t ofd_xics_props(void *m)
209 {
210 ofdn_t n;
211 static const char path[] = "/interrupt-controller";
212 static const char compat[] = "IBM,ppc-xicp";
213 static const char model[] = "IBM, BoaC, PowerPC-PIC, 00";
214 static const char dtype[] =
215 "PowerPC-External-Interrupt-Presentation";
216 /*
217 * I don't think these are used for anything but linux wants
218 * it. I seems to describe some per processor location for
219 * IPIs but that is a complete guess.
220 */
221 static const u32 reg[] = {
222 0x000003e0, 0x0f000000, 0x00000000, 0x00001000,
223 0x000003e0, 0x0f001000, 0x00000000, 0x00001000,
224 0x000003e0, 0x0f002000, 0x00000000, 0x00001000,
225 0x000003e0, 0x0f003000, 0x00000000, 0x00001000,
226 0x000003e0, 0x0f004000, 0x00000000, 0x00001000,
227 0x000003e0, 0x0f005000, 0x00000000, 0x00001000,
228 0x000003e0, 0x0f006000, 0x00000000, 0x00001000,
229 0x000003e0, 0x0f007000, 0x00000000, 0x00001000,
230 0x000003e0, 0x0f008000, 0x00000000, 0x00001000,
231 0x000003e0, 0x0f009000, 0x00000000, 0x00001000,
232 0x000003e0, 0x0f00a000, 0x00000000, 0x00001000,
233 0x000003e0, 0x0f00b000, 0x00000000, 0x00001000,
234 0x000003e0, 0x0f00c000, 0x00000000, 0x00001000,
235 0x000003e0, 0x0f00d000, 0x00000000, 0x00001000,
236 0x000003e0, 0x0f00e000, 0x00000000, 0x00001000,
237 0x000003e0, 0x0f00f000, 0x00000000, 0x00001000,
238 };
240 n = ofd_node_find(m, path);
241 if (n == 0) {
242 n = ofd_node_add(m, OFD_ROOT, path, sizeof (path));
243 ofd_prop_add(m, n, "name",
244 &path[1], sizeof (path) - 1);
245 }
246 ofd_prop_add(m, n, "built-in", NULL, 0);
247 ofd_prop_add(m, n, "compatible", compat, sizeof(compat));
248 ofd_prop_add(m, n, "device_type", dtype, sizeof(dtype));
249 ofd_prop_add(m, n, "model", model, sizeof(model));
250 ofd_prop_add(m, n, "reg", reg, sizeof(reg));
252 return n;
253 }
254 #endif
256 /*
257 * Good things you can stick here:
258 * init=/bin/bash ip=dhcp root=/dev/hda2 ide=nodma
259 */
260 static char default_bootargs[] = "";
262 static ofdn_t ofd_chosen_props(void *m, const char *cmdline)
263 {
264 ofdn_t n;
265 ofdn_t p;
266 static const char path[] = "/chosen";
267 char bootargs[256];
268 int bsz;
269 int sz;
270 int rm;
272 n = ofd_node_find(m, path);
273 if (n == 0) {
274 n = ofd_node_add(m, OFD_ROOT, path, sizeof (path));
275 ofd_prop_add(m, n, "name",
276 &path[1], sizeof (path) - 1);
277 }
279 strcpy(bootargs, cmdline);
280 bsz = strlen(bootargs) + 1;
281 rm = sizeof (bootargs) - bsz;
283 if (default_bootargs != NULL) {
284 sz = strlen(default_bootargs);
285 if (sz > rm) {
286 panic("default_bootargs is too big: 0x%x > 0x%x\n",
287 sz, rm);
288 } else if (sz > 0) {
289 memcpy(&bootargs[bsz - 1], default_bootargs, sz + 1);
290 bsz += sz;
291 rm -= sz;
292 }
293 }
295 printk("DOM0 bootargs: %s\n", bootargs);
296 ofd_prop_add(m, n, "bootargs", bootargs, bsz);
298 ofd_prop_add(m, n, "bootpath", NULL, 0);
300 printk("Remove /chosen/mmu, stub will replace\n");
301 p = ofd_prop_find(m, n, "mmu");
302 if (p > 0) {
303 ofd_prop_remove(m, n, p);
304 }
306 return n;
307 }
309 #ifdef RTAS
310 static ofdn_t ofd_rtas_props(void *m)
311 {
312 static const char path[] = "/rtas";
313 static const char hypertas[] = "dummy";
314 ofdn_t p;
315 ofdn_t n;
317 /* just enough to make linux think its on LPAR */
319 p = ofd_node_find(m, "/");
321 n = ofd_node_add(m, p, path, sizeof(path));
322 ofd_prop_add(m, n, "name", &path[1], sizeof (path) - 1);
323 ofd_prop_add(m, n, "ibm,hypertas-functions", hypertas, sizeof (hypertas));
325 return n;
326 }
327 #endif
329 static ofdn_t ofd_xen_props(void *m, struct domain *d, start_info_t *si)
330 {
331 ofdn_t n;
332 static const char path[] = "/xen";
333 static const char console[] = "/xen/console";
335 n = ofd_node_add(m, OFD_ROOT, path, sizeof (path));
336 if (n > 0) {
337 char xen[256];
338 int xl;
339 u64 val[2];
340 s32 dom_id;
342 dom_id = d->domain_id;
344 ofd_prop_add(m, n, "reg", &dom_id, sizeof (dom_id));
345 ofd_prop_add(m, n, "name", &path[1], sizeof (path) - 1);
347 xl = snprintf(xen, sizeof (xen), "Xen-%d.%d%s",
348 xen_major_version(), xen_minor_version(), xen_extra_version());
349 ASSERT(xl < sizeof (xen));
350 ofd_prop_add(m, n, "version", xen, xl + 1);
352 val[0] = (ulong)si - page_to_maddr(d->arch.rma_page);
353 val[1] = PAGE_SIZE;
354 ofd_prop_add(m, n, "start-info", val, sizeof (val));
356 val[1] = RMA_LAST_DOM0 * PAGE_SIZE;
357 val[0] = rma_size(d->arch.rma_order) - val[1];
358 ofd_prop_add(m, n, "reserved", val, sizeof (val));
360 /* tell dom0 that Xen depends on it to have power control */
361 if (!rtas_entry)
362 ofd_prop_add(m, n, "power-control", NULL, 0);
364 /* tell dom0 where ranted pages go in the linear map */
365 val[0] = cpu_foreign_map_order();
366 val[1] = d->arch.foreign_mfn_count;
367 ofd_prop_add(m, n, "foreign-map", val, sizeof (val));
369 n = ofd_node_add(m, n, console, sizeof (console));
370 if (n > 0) {
371 val[0] = 0;
372 ofd_prop_add(m, n, "interrupts", &val[0], sizeof (val[0]));
373 }
374 }
375 return n;
376 }
378 int ofd_dom0_fixup(struct domain *d, ulong mem, start_info_t *si)
379 {
380 void *m;
381 const ofdn_t n = OFD_ROOT;
382 ofdn_t r;
384 m = (void *)mem;
386 #ifdef PAPR_VDEVICE
387 printk("Add /vdevice\n");
388 ofd_vdevice(m, d);
390 printk("Add /aliases props\n");
391 ofd_aliases_props(m);
392 #endif
394 printk("Add /openprom props\n");
395 ofd_openprom_props(m);
397 printk("Add /options props\n");
398 ofd_options_props(m);
400 printk("Add /cpus props\n");
401 ofd_cpus_props(m, d);
403 printk("Add /chosen props\n");
404 ofd_chosen_props(m, (char *)si->cmd_line);
406 printk("fix /memory props\n");
407 ofd_memory_props(m, d);
409 printk("fix /xen props\n");
410 ofd_xen_props(m, d, si);
412 printk("Remove original /dart\n");
413 ofd_prune_path(m, "/dart");
415 printk("Remove original /rtas\n");
416 ofd_prune_path(m, "/rtas");
418 #ifdef RTAS
419 printk("Create a new RTAS with just enough stuff to convince "
420 "Linux that its on LPAR\n");
421 ofd_rtas_props(m);
422 #endif
423 #ifdef FIX_COMPAT
424 const char compat[] = "Hypervisor,Maple";
425 r = ofd_prop_add(m, n, "compatible", compat, sizeof (compat));
426 ASSERT( r > 0 );
427 #endif
429 u32 did = d->domain_id;
430 r = ofd_prop_add(m, n, "ibm,partition-no", &did, sizeof(did));
431 ASSERT( r > 0 );
433 const char d0[] = "dom0";
434 r = ofd_prop_add(m, n, "ibm,partition-name", d0, sizeof (d0));
435 ASSERT( r > 0 );
438 #ifdef DEBUG
439 ofd_walk(m, __func__, OFD_ROOT, ofd_dump_props, OFD_DUMP_ALL);
440 #endif
441 return 1;
442 }