debuggers.hg

view xen/arch/powerpc/ofd_fixup.c @ 13702:d2784d93e760

ia64 and ppc: Remove uses of strcpy and strncpy.
Signed-off-by: Christoph Egger <Christoph.Egger@amd.com>
author kfraser@localhost.localdomain
date Mon Jan 29 15:01:33 2007 +0000 (2007-01-29)
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 /* Since we are not MP yet we prune all but the booting cpu */
182 if (c == ofd_boot_cpu) {
183 ibm_pft_size[1] = d->arch.htab.log_num_ptes + LOG_PTE_SIZE;
184 ofd_prop_add(m, c, "ibm,pft-size",
185 ibm_pft_size, sizeof (ibm_pft_size));
187 /* FIXME: Check the the "l2-cache" property who's
188 * contents is an orphaned phandle? */
189 } else
190 ofd_node_prune(m, c);
192 c = ofd_node_find_next(m, c);
193 }
195 return n;
196 }
198 #ifdef ADD_XICS
199 static ofdn_t ofd_xics_props(void *m)
200 {
201 ofdn_t n;
202 static const char path[] = "/interrupt-controller";
203 static const char compat[] = "IBM,ppc-xicp";
204 static const char model[] = "IBM, BoaC, PowerPC-PIC, 00";
205 static const char dtype[] =
206 "PowerPC-External-Interrupt-Presentation";
207 /*
208 * I don't think these are used for anything but linux wants
209 * it. I seems to describe some per processor location for
210 * IPIs but that is a complete guess.
211 */
212 static const u32 reg[] = {
213 0x000003e0, 0x0f000000, 0x00000000, 0x00001000,
214 0x000003e0, 0x0f001000, 0x00000000, 0x00001000,
215 0x000003e0, 0x0f002000, 0x00000000, 0x00001000,
216 0x000003e0, 0x0f003000, 0x00000000, 0x00001000,
217 0x000003e0, 0x0f004000, 0x00000000, 0x00001000,
218 0x000003e0, 0x0f005000, 0x00000000, 0x00001000,
219 0x000003e0, 0x0f006000, 0x00000000, 0x00001000,
220 0x000003e0, 0x0f007000, 0x00000000, 0x00001000,
221 0x000003e0, 0x0f008000, 0x00000000, 0x00001000,
222 0x000003e0, 0x0f009000, 0x00000000, 0x00001000,
223 0x000003e0, 0x0f00a000, 0x00000000, 0x00001000,
224 0x000003e0, 0x0f00b000, 0x00000000, 0x00001000,
225 0x000003e0, 0x0f00c000, 0x00000000, 0x00001000,
226 0x000003e0, 0x0f00d000, 0x00000000, 0x00001000,
227 0x000003e0, 0x0f00e000, 0x00000000, 0x00001000,
228 0x000003e0, 0x0f00f000, 0x00000000, 0x00001000,
229 };
231 n = ofd_node_find(m, path);
232 if (n == 0) {
233 n = ofd_node_add(m, OFD_ROOT, path, sizeof (path));
234 ofd_prop_add(m, n, "name",
235 &path[1], sizeof (path) - 1);
236 }
237 ofd_prop_add(m, n, "built-in", NULL, 0);
238 ofd_prop_add(m, n, "compatible", compat, sizeof(compat));
239 ofd_prop_add(m, n, "device_type", dtype, sizeof(dtype));
240 ofd_prop_add(m, n, "model", model, sizeof(model));
241 ofd_prop_add(m, n, "reg", reg, sizeof(reg));
243 return n;
244 }
245 #endif
247 /*
248 * Good things you can stick here:
249 * init=/bin/bash ip=dhcp root=/dev/hda2 ide=nodma
250 */
251 static char default_bootargs[] = "";
253 static ofdn_t ofd_chosen_props(void *m, const char *cmdline)
254 {
255 ofdn_t n;
256 ofdn_t p;
257 static const char path[] = "/chosen";
258 char bootargs[256];
259 int bsz;
260 int sz;
261 int rm;
263 n = ofd_node_find(m, path);
264 if (n == 0) {
265 n = ofd_node_add(m, OFD_ROOT, path, sizeof (path));
266 ofd_prop_add(m, n, "name",
267 &path[1], sizeof (path) - 1);
268 }
270 strlcpy(bootargs, cmdline, sizeof(bootargs));
271 bsz = strlen(bootargs) + 1;
272 rm = sizeof (bootargs) - bsz;
274 if (default_bootargs != NULL) {
275 sz = strlen(default_bootargs);
276 if (sz > rm) {
277 panic("default_bootargs is too big: 0x%x > 0x%x\n",
278 sz, rm);
279 } else if (sz > 0) {
280 memcpy(&bootargs[bsz - 1], default_bootargs, sz + 1);
281 bsz += sz;
282 rm -= sz;
283 }
284 }
286 printk("DOM0 bootargs: %s\n", bootargs);
287 ofd_prop_add(m, n, "bootargs", bootargs, bsz);
289 ofd_prop_add(m, n, "bootpath", NULL, 0);
291 printk("Remove /chosen/mmu, stub will replace\n");
292 p = ofd_prop_find(m, n, "mmu");
293 if (p > 0) {
294 ofd_prop_remove(m, n, p);
295 }
297 return n;
298 }
300 #ifdef RTAS
301 static ofdn_t ofd_rtas_props(void *m)
302 {
303 static const char path[] = "/rtas";
304 static const char hypertas[] = "dummy";
305 ofdn_t p;
306 ofdn_t n;
308 /* just enough to make linux think its on LPAR */
310 p = ofd_node_find(m, "/");
312 n = ofd_node_add(m, p, path, sizeof(path));
313 ofd_prop_add(m, n, "name", &path[1], sizeof (path) - 1);
314 ofd_prop_add(m, n, "ibm,hypertas-functions", hypertas, sizeof (hypertas));
316 return n;
317 }
318 #endif
320 static ofdn_t ofd_xen_props(void *m, struct domain *d, start_info_t *si)
321 {
322 ofdn_t n;
323 static const char path[] = "/xen";
324 static const char console[] = "/xen/console";
326 n = ofd_node_add(m, OFD_ROOT, path, sizeof (path));
327 if (n > 0) {
328 char xen[256];
329 int xl;
330 u64 val[2];
331 s32 dom_id;
333 dom_id = d->domain_id;
335 ofd_prop_add(m, n, "reg", &dom_id, sizeof (dom_id));
336 ofd_prop_add(m, n, "name", &path[1], sizeof (path) - 1);
338 xl = snprintf(xen, sizeof (xen), "Xen-%d.%d%s",
339 xen_major_version(), xen_minor_version(), xen_extra_version());
340 ASSERT(xl < sizeof (xen));
341 ofd_prop_add(m, n, "version", xen, xl + 1);
343 val[0] = (ulong)si - page_to_maddr(d->arch.rma_page);
344 val[1] = PAGE_SIZE;
345 ofd_prop_add(m, n, "start-info", val, sizeof (val));
347 val[1] = RMA_LAST_DOM0 * PAGE_SIZE;
348 val[0] = rma_size(d->arch.rma_order) - val[1];
349 ofd_prop_add(m, n, "reserved", val, sizeof (val));
351 /* tell dom0 that Xen depends on it to have power control */
352 if (!rtas_entry)
353 ofd_prop_add(m, n, "power-control", NULL, 0);
355 /* tell dom0 where ranted pages go in the linear map */
356 val[0] = cpu_foreign_map_order();
357 val[1] = d->arch.foreign_mfn_count;
358 ofd_prop_add(m, n, "foreign-map", val, sizeof (val));
360 n = ofd_node_add(m, n, console, sizeof (console));
361 if (n > 0) {
362 val[0] = 0;
363 ofd_prop_add(m, n, "interrupts", &val[0], sizeof (val[0]));
364 }
365 }
366 return n;
367 }
369 int ofd_dom0_fixup(struct domain *d, ulong mem, start_info_t *si)
370 {
371 void *m;
372 const ofdn_t n = OFD_ROOT;
373 ofdn_t r;
375 m = (void *)mem;
377 #ifdef PAPR_VDEVICE
378 printk("Add /vdevice\n");
379 ofd_vdevice(m, d);
381 printk("Add /aliases props\n");
382 ofd_aliases_props(m);
383 #endif
385 printk("Add /openprom props\n");
386 ofd_openprom_props(m);
388 printk("Add /options props\n");
389 ofd_options_props(m);
391 printk("Add /cpus props\n");
392 ofd_cpus_props(m, d);
394 printk("Add /chosen props\n");
395 ofd_chosen_props(m, (char *)si->cmd_line);
397 printk("fix /memory props\n");
398 ofd_memory_props(m, d);
400 printk("fix /xen props\n");
401 ofd_xen_props(m, d, si);
403 printk("Remove original /dart\n");
404 ofd_prune_path(m, "/dart");
406 printk("Remove original /rtas\n");
407 ofd_prune_path(m, "/rtas");
409 #ifdef RTAS
410 printk("Create a new RTAS with just enough stuff to convince "
411 "Linux that its on LPAR\n");
412 ofd_rtas_props(m);
413 #endif
414 #ifdef FIX_COMPAT
415 const char compat[] = "Hypervisor,Maple";
416 r = ofd_prop_add(m, n, "compatible", compat, sizeof (compat));
417 ASSERT( r > 0 );
418 #endif
420 u32 did = d->domain_id;
421 r = ofd_prop_add(m, n, "ibm,partition-no", &did, sizeof(did));
422 ASSERT( r > 0 );
424 const char d0[] = "dom0";
425 r = ofd_prop_add(m, n, "ibm,partition-name", d0, sizeof (d0));
426 ASSERT( r > 0 );
429 #ifdef DEBUG
430 ofd_walk(m, __func__, OFD_ROOT, ofd_dump_props, OFD_DUMP_ALL);
431 #endif
432 return 1;
433 }