ia64/xen-unstable
changeset 12921:5b0e0c93a5bf
[XEN][POWERPC] Allow Xen to use RTAS if available
If FW provides an RTAS layer, it will be instantiated and Xen will try
to use it for power control (halt, reboot, power-off, etc). Xen will
also communicate to Dom0 (using /xen/power-control in the devtree)
when Xen cannot control power and it is hoped that the domain can,
especially useful for Maple boards running non-RTAS versions of PIBS.
Signed-off-by: Jimi Xenidis <jimix@watson.ibm.com>
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
If FW provides an RTAS layer, it will be instantiated and Xen will try
to use it for power control (halt, reboot, power-off, etc). Xen will
also communicate to Dom0 (using /xen/power-control in the devtree)
when Xen cannot control power and it is hoped that the domain can,
especially useful for Maple boards running non-RTAS versions of PIBS.
Signed-off-by: Jimi Xenidis <jimix@watson.ibm.com>
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
author | Jimi Xenidis <jimix@watson.ibm.com> |
---|---|
date | Thu Sep 28 12:34:01 2006 -0400 (2006-09-28) |
parents | 97e1d0fd7def |
children | a69f935eda6c |
files | xen/arch/powerpc/boot_of.c xen/arch/powerpc/domain.c xen/arch/powerpc/memory.c xen/arch/powerpc/ofd_fixup.c xen/arch/powerpc/rtas.c xen/arch/powerpc/rtas.h xen/arch/powerpc/setup.c xen/include/asm-powerpc/debugger.h |
line diff
1.1 --- a/xen/arch/powerpc/boot_of.c Tue Sep 26 14:01:11 2006 -0400 1.2 +++ b/xen/arch/powerpc/boot_of.c Thu Sep 28 12:34:01 2006 -0400 1.3 @@ -32,6 +32,7 @@ 1.4 #include "exceptions.h" 1.5 #include "of-devtree.h" 1.6 #include "oftree.h" 1.7 +#include "rtas.h" 1.8 1.9 /* Secondary processors use this for handshaking with main processor. */ 1.10 volatile unsigned int __spin_ack; 1.11 @@ -68,7 +69,6 @@ struct of_service { 1.12 static int bof_chosen; 1.13 1.14 static struct of_service s; 1.15 -extern s32 prom_call(void *arg, ulong rtas_base, ulong func, ulong msr); 1.16 1.17 static int __init of_call( 1.18 const char *service, u32 nargs, u32 nrets, s32 rets[], ...) 1.19 @@ -362,6 +362,14 @@ static int __init of_getparent(int ph) 1.20 return rets[0]; 1.21 } 1.22 1.23 +static int __init of_open(const char *devspec) 1.24 +{ 1.25 + int rets[1] = { OF_FAILURE }; 1.26 + 1.27 + of_call("open", 1, 1, rets, devspec); 1.28 + return rets[0]; 1.29 +} 1.30 + 1.31 static void boot_of_probemem(multiboot_info_t *mbi) 1.32 { 1.33 int root; 1.34 @@ -500,7 +508,8 @@ static int save_props(void *m, ofdn_t n, 1.35 of_panic("obj array not big enough for 0x%x\n", sz); 1.36 } 1.37 actual = of_getprop(pkg, name, obj, sz); 1.38 - if (actual > sz) of_panic("obj too small"); 1.39 + if (actual > sz) 1.40 + of_panic("obj too small"); 1.41 } 1.42 1.43 if (strncmp(name, name_str, sizeof(name_str)) == 0) { 1.44 @@ -512,7 +521,8 @@ static int save_props(void *m, ofdn_t n, 1.45 } 1.46 1.47 pos = ofd_prop_add(m, n, name, obj, actual); 1.48 - if (pos == 0) of_panic("prop_create"); 1.49 + if (pos == 0) 1.50 + of_panic("prop_create"); 1.51 } 1.52 1.53 result = of_nextprop(pkg, name, name); 1.54 @@ -536,10 +546,12 @@ retry: 1.55 1.56 if (pnext != 0) { 1.57 sz = of_package_to_path(pnext, path, psz); 1.58 - if (sz == OF_FAILURE) of_panic("bad path\n"); 1.59 + if (sz == OF_FAILURE) 1.60 + of_panic("bad path\n"); 1.61 1.62 nnext = ofd_node_child_create(m, n, path, sz); 1.63 - if (nnext == 0) of_panic("out of mem\n"); 1.64 + if (nnext == 0) 1.65 + of_panic("out of mem\n"); 1.66 1.67 do_pkg(m, nnext, pnext, path, psz); 1.68 } 1.69 @@ -551,7 +563,8 @@ retry: 1.70 sz = of_package_to_path(pnext, path, psz); 1.71 1.72 nnext = ofd_node_peer_create(m, n, path, sz); 1.73 - if (nnext <= 0) of_panic("out of space in OFD tree.\n"); 1.74 + if (nnext <= 0) 1.75 + of_panic("out of space in OFD tree.\n"); 1.76 1.77 n = nnext; 1.78 p = pnext; 1.79 @@ -570,7 +583,8 @@ static int pkg_save(void *mem) 1.80 1.81 /* get root */ 1.82 root = of_getpeer(0); 1.83 - if (root == OF_FAILURE) of_panic("no root package\n"); 1.84 + if (root == OF_FAILURE) 1.85 + of_panic("no root package\n"); 1.86 1.87 do_pkg(mem, OFD_ROOT, root, path, sizeof(path)); 1.88 1.89 @@ -604,7 +618,8 @@ static int boot_of_fixup_refs(void *mem) 1.90 char ofpath[256]; 1.91 1.92 path = ofd_node_path(mem, c); 1.93 - if (path == NULL) of_panic("no path to found prop: %s\n", name); 1.94 + if (path == NULL) 1.95 + of_panic("no path to found prop: %s\n", name); 1.96 1.97 rp = of_finddevice(path); 1.98 if (rp == OF_FAILURE) 1.99 @@ -629,13 +644,15 @@ static int boot_of_fixup_refs(void *mem) 1.100 "ref 0x%x\n", name, path, rp, ref); 1.101 1.102 dp = ofd_node_find(mem, ofpath); 1.103 - if (dp <= 0) of_panic("no ofd node for OF node[0x%x]: %s\n", 1.104 - ref, ofpath); 1.105 + if (dp <= 0) 1.106 + of_panic("no ofd node for OF node[0x%x]: %s\n", 1.107 + ref, ofpath); 1.108 1.109 ref = dp; 1.110 1.111 upd = ofd_prop_add(mem, c, name, &ref, sizeof(ref)); 1.112 - if (upd <= 0) of_panic("update failed: %s\n", name); 1.113 + if (upd <= 0) 1.114 + of_panic("update failed: %s\n", name); 1.115 1.116 #ifdef DEBUG 1.117 of_printf("%s: %s/%s -> %s\n", __func__, 1.118 @@ -658,7 +675,8 @@ static int boot_of_fixup_chosen(void *me 1.119 char ofpath[256]; 1.120 1.121 ch = of_finddevice("/chosen"); 1.122 - if (ch == OF_FAILURE) of_panic("/chosen not found\n"); 1.123 + if (ch == OF_FAILURE) 1.124 + of_panic("/chosen not found\n"); 1.125 1.126 rc = of_getprop(ch, "cpu", &val, sizeof (val)); 1.127 1.128 @@ -667,16 +685,19 @@ static int boot_of_fixup_chosen(void *me 1.129 1.130 if (rc > 0) { 1.131 dn = ofd_node_find(mem, ofpath); 1.132 - if (dn <= 0) of_panic("no node for: %s\n", ofpath); 1.133 + if (dn <= 0) 1.134 + of_panic("no node for: %s\n", ofpath); 1.135 1.136 ofd_boot_cpu = dn; 1.137 val = dn; 1.138 1.139 dn = ofd_node_find(mem, "/chosen"); 1.140 - if (dn <= 0) of_panic("no /chosen node\n"); 1.141 + if (dn <= 0) 1.142 + of_panic("no /chosen node\n"); 1.143 1.144 dc = ofd_prop_add(mem, dn, "cpu", &val, sizeof (val)); 1.145 - if (dc <= 0) of_panic("could not fix /chosen/cpu\n"); 1.146 + if (dc <= 0) 1.147 + of_panic("could not fix /chosen/cpu\n"); 1.148 rc = 1; 1.149 } else { 1.150 of_printf("*** can't find path to booting cpu, " 1.151 @@ -855,17 +876,101 @@ static int __init boot_of_serial(void *o 1.152 return 1; 1.153 } 1.154 1.155 -static void boot_of_module(ulong r3, ulong r4, multiboot_info_t *mbi) 1.156 +static int __init boot_of_rtas(module_t *mod, multiboot_info_t *mbi) 1.157 { 1.158 - static module_t mods[3]; 1.159 + int rtas_node; 1.160 + int rtas_instance; 1.161 + uint size = 0; 1.162 + int res[2]; 1.163 + int mem; 1.164 + int ret; 1.165 + 1.166 + rtas_node = of_finddevice("/rtas"); 1.167 + 1.168 + if (rtas_node <= 0) { 1.169 + of_printf("No RTAS, Xen has no power control\n"); 1.170 + return 0; 1.171 + } 1.172 + of_getprop(rtas_node, "rtas-size", &size, sizeof (size)); 1.173 + if (size == 0) { 1.174 + of_printf("RTAS, has no size\n"); 1.175 + return 0; 1.176 + } 1.177 + 1.178 + rtas_instance = of_open("/rtas"); 1.179 + if (rtas_instance == OF_FAILURE) { 1.180 + of_printf("RTAS, could not open\n"); 1.181 + return 0; 1.182 + } 1.183 + 1.184 + size = ALIGN_UP(size, PAGE_SIZE); 1.185 + 1.186 + mem = find_space(size, PAGE_SIZE, mbi); 1.187 + if (mem == 0) 1.188 + of_panic("Could not allocate RTAS tree\n"); 1.189 + 1.190 + ret = of_call("call-method", 3, 2, res, 1.191 + "instantiate-rtas", rtas_instance, mem); 1.192 + if (ret == OF_FAILURE) { 1.193 + of_printf("RTAS, could not open\n"); 1.194 + return 0; 1.195 + } 1.196 + 1.197 + rtas_entry = res[1]; 1.198 + rtas_base = mem; 1.199 + rtas_end = mem + size; 1.200 + rtas_msr = of_msr; 1.201 + 1.202 + mod->mod_start = rtas_base; 1.203 + mod->mod_end = rtas_end; 1.204 + return 1; 1.205 +} 1.206 + 1.207 +static void * __init boot_of_devtree(module_t *mod, multiboot_info_t *mbi) 1.208 +{ 1.209 void *oft; 1.210 ulong oft_sz = 48 * PAGE_SIZE; 1.211 + 1.212 + /* snapshot the tree */ 1.213 + oft = (void*)find_space(oft_sz, PAGE_SIZE, mbi); 1.214 + if (oft == 0) 1.215 + of_panic("Could not allocate OFD tree\n"); 1.216 + 1.217 + of_printf("creating oftree\n"); 1.218 + of_test("package-to-path"); 1.219 + oft = ofd_create(oft, oft_sz); 1.220 + pkg_save(oft); 1.221 + 1.222 + if (ofd_size(oft) > oft_sz) 1.223 + of_panic("Could not fit all of native devtree\n"); 1.224 + 1.225 + boot_of_fixup_refs(oft); 1.226 + boot_of_fixup_chosen(oft); 1.227 + 1.228 + if (ofd_size(oft) > oft_sz) 1.229 + of_panic("Could not fit all devtree fixups\n"); 1.230 + 1.231 + ofd_walk(oft, OFD_ROOT, /* add_hype_props */ NULL, 2); 1.232 + 1.233 + mod->mod_start = (ulong)oft; 1.234 + mod->mod_end = mod->mod_start + oft_sz; 1.235 + of_printf("%s: devtree mod @ 0x%016x[0x%x]\n", __func__, 1.236 + mod->mod_start, mod->mod_end); 1.237 + 1.238 + return oft; 1.239 +} 1.240 + 1.241 +static void * __init boot_of_module(ulong r3, ulong r4, multiboot_info_t *mbi) 1.242 +{ 1.243 + static module_t mods[4]; 1.244 ulong mod0_start; 1.245 ulong mod0_size; 1.246 static const char sepr[] = " -- "; 1.247 extern char dom0_start[] __attribute__ ((weak)); 1.248 extern char dom0_size[] __attribute__ ((weak)); 1.249 const char *p; 1.250 + int mod; 1.251 + void *oft; 1.252 1.253 if ((r3 > 0) && (r4 > 0)) { 1.254 /* was it handed to us in registers ? */ 1.255 @@ -909,50 +1014,35 @@ static void boot_of_module(ulong r3, ulo 1.256 } 1.257 1.258 space_base = (ulong)_end; 1.259 - mods[0].mod_start = mod0_start; 1.260 - mods[0].mod_end = mod0_start + mod0_size; 1.261 1.262 - of_printf("%s: mod[0] @ 0x%016x[0x%x]\n", __func__, 1.263 - mods[0].mod_start, mods[0].mod_end); 1.264 + mod = 0; 1.265 + mods[mod].mod_start = mod0_start; 1.266 + mods[mod].mod_end = mod0_start + mod0_size; 1.267 + 1.268 + of_printf("%s: dom0 mod @ 0x%016x[0x%x]\n", __func__, 1.269 + mods[mod].mod_start, mods[mod].mod_end); 1.270 p = strstr((char *)(ulong)mbi->cmdline, sepr); 1.271 if (p != NULL) { 1.272 p += sizeof (sepr) - 1; 1.273 - mods[0].string = (u32)(ulong)p; 1.274 - of_printf("%s: mod[0].string: %s\n", __func__, p); 1.275 + mods[mod].string = (u32)(ulong)p; 1.276 + of_printf("%s: dom0 mod string: %s\n", __func__, p); 1.277 } 1.278 1.279 - /* snapshot the tree */ 1.280 - oft = (void*)find_space(oft_sz, PAGE_SIZE, mbi); 1.281 - if (oft == 0) 1.282 - of_panic("Could not allocate OFD tree\n"); 1.283 - 1.284 - of_printf("creating oft\n"); 1.285 - of_test("package-to-path"); 1.286 - oft = ofd_create(oft, oft_sz); 1.287 - pkg_save(oft); 1.288 - 1.289 - if (ofd_size(oft) > oft_sz) 1.290 - of_panic("Could not fit all of native devtree\n"); 1.291 + ++mod; 1.292 + if (boot_of_rtas(&mods[mod], mbi)) 1.293 + ++mod; 1.294 1.295 - boot_of_fixup_refs(oft); 1.296 - boot_of_fixup_chosen(oft); 1.297 - 1.298 - if (ofd_size(oft) > oft_sz) 1.299 - of_panic("Could not fit all devtree fixups\n"); 1.300 + oft = boot_of_devtree(&mods[mod], mbi); 1.301 + if (oft == NULL) 1.302 + of_panic("%s: boot_of_devtree failed\n", __func__); 1.303 1.304 - ofd_walk(oft, OFD_ROOT, /* add_hype_props */ NULL, 2); 1.305 - 1.306 - mods[1].mod_start = (ulong)oft; 1.307 - mods[1].mod_end = mods[1].mod_start + oft_sz; 1.308 - of_printf("%s: mod[1] @ 0x%016x[0x%x]\n", __func__, 1.309 - mods[1].mod_start, mods[1].mod_end); 1.310 - 1.311 + ++mod; 1.312 1.313 mbi->flags |= MBI_MODULES; 1.314 - mbi->mods_count = 2; 1.315 + mbi->mods_count = mod; 1.316 mbi->mods_addr = (u32)mods; 1.317 1.318 - boot_of_serial(oft); 1.319 + return oft; 1.320 } 1.321 1.322 static int __init boot_of_cpus(void) 1.323 @@ -1075,15 +1165,11 @@ static int __init boot_of_cpus(void) 1.324 return 1; 1.325 } 1.326 1.327 -static int __init boot_of_rtas(void) 1.328 -{ 1.329 - return 1; 1.330 -} 1.331 - 1.332 multiboot_info_t __init *boot_of_init( 1.333 ulong r3, ulong r4, ulong vec, ulong r6, ulong r7, ulong orig_msr) 1.334 { 1.335 static multiboot_info_t mbi; 1.336 + void *oft; 1.337 1.338 of_vec = vec; 1.339 of_msr = orig_msr; 1.340 @@ -1112,9 +1198,9 @@ multiboot_info_t __init *boot_of_init( 1.341 boot_of_fix_maple(); 1.342 boot_of_probemem(&mbi); 1.343 boot_of_bootargs(&mbi); 1.344 - boot_of_module(r3, r4, &mbi); 1.345 + oft = boot_of_module(r3, r4, &mbi); 1.346 boot_of_cpus(); 1.347 - boot_of_rtas(); 1.348 + boot_of_serial(oft); 1.349 1.350 /* end of OF */ 1.351 of_printf("Quiescing Open Firmware ...\n");
2.1 --- a/xen/arch/powerpc/domain.c Tue Sep 26 14:01:11 2006 -0400 2.2 +++ b/xen/arch/powerpc/domain.c Thu Sep 28 12:34:01 2006 -0400 2.3 @@ -33,6 +33,7 @@ 2.4 #include <asm/htab.h> 2.5 #include <asm/current.h> 2.6 #include <asm/hcalls.h> 2.7 +#include "rtas.h" 2.8 2.9 #define next_arg(fmt, args) ({ \ 2.10 unsigned long __arg; \ 2.11 @@ -95,18 +96,27 @@ void arch_domain_destroy(struct domain * 2.12 shadow_teardown(d); 2.13 } 2.14 2.15 +static void machine_fail(const char *s) 2.16 +{ 2.17 + printf("%s failed, manual powercycle required!\n", s); 2.18 + while(1); 2.19 +} 2.20 + 2.21 void machine_halt(void) 2.22 { 2.23 - printk("machine_halt called: spinning....\n"); 2.24 console_start_sync(); 2.25 - while(1); 2.26 + printf("%s called\n", __func__); 2.27 + rtas_halt(); 2.28 + 2.29 + machine_fail(__func__); 2.30 } 2.31 2.32 void machine_restart(char * __unused) 2.33 { 2.34 - printk("machine_restart called: spinning....\n"); 2.35 console_start_sync(); 2.36 - while(1); 2.37 + printf("%s called\n", __func__); 2.38 + rtas_reboot(); 2.39 + machine_fail(__func__); 2.40 } 2.41 2.42 struct vcpu *alloc_vcpu_struct(void)
3.1 --- a/xen/arch/powerpc/memory.c Tue Sep 26 14:01:11 2006 -0400 3.2 +++ b/xen/arch/powerpc/memory.c Thu Sep 28 12:34:01 2006 -0400 3.3 @@ -22,6 +22,7 @@ 3.4 #include <xen/mm.h> 3.5 #include "of-devtree.h" 3.6 #include "oftree.h" 3.7 +#include "rtas.h" 3.8 3.9 unsigned long xenheap_phys_end; 3.10 struct membuf { 3.11 @@ -33,16 +34,29 @@ typedef void (*walk_mem_fn)(struct membu 3.12 3.13 static ulong free_xenheap(ulong start, ulong end) 3.14 { 3.15 + ulong save_start; 3.16 + ulong save_end; 3.17 + 3.18 start = ALIGN_UP(start, PAGE_SIZE); 3.19 end = ALIGN_DOWN(end, PAGE_SIZE); 3.20 3.21 printk("%s: 0x%lx - 0x%lx\n", __func__, start, end); 3.22 3.23 - if (oftree <= end && oftree >= start) { 3.24 - printk("%s: Go around the devtree: 0x%lx - 0x%lx\n", 3.25 - __func__, oftree, oftree_end); 3.26 - init_xenheap_pages(start, ALIGN_DOWN(oftree, PAGE_SIZE)); 3.27 - init_xenheap_pages(ALIGN_UP(oftree_end, PAGE_SIZE), end); 3.28 + save_start = oftree; 3.29 + save_end = oftree_end; 3.30 + if (rtas_base) { 3.31 + if (save_start > rtas_base) 3.32 + save_start = rtas_base; 3.33 + if (save_end < rtas_end) 3.34 + save_end = rtas_end; 3.35 + } 3.36 + 3.37 + /* need to do this better */ 3.38 + if (save_start <= end && save_start >= start) { 3.39 + printk("%s: Go around the saved area: 0x%lx - 0x%lx\n", 3.40 + __func__, save_start, save_end); 3.41 + init_xenheap_pages(start, ALIGN_DOWN(save_start, PAGE_SIZE)); 3.42 + init_xenheap_pages(ALIGN_UP(save_end, PAGE_SIZE), end); 3.43 } else { 3.44 init_xenheap_pages(start, end); 3.45 } 3.46 @@ -123,7 +137,7 @@ static void setup_xenheap(module_t *mod, 3.47 for (i = 0; i < mcount; i++) { 3.48 u32 s; 3.49 3.50 - if(mod[i].mod_end == mod[i].mod_start) 3.51 + if (mod[i].mod_end == mod[i].mod_start) 3.52 continue; 3.53 3.54 s = ALIGN_DOWN(mod[i].mod_start, PAGE_SIZE);
4.1 --- a/xen/arch/powerpc/ofd_fixup.c Tue Sep 26 14:01:11 2006 -0400 4.2 +++ b/xen/arch/powerpc/ofd_fixup.c Thu Sep 28 12:34:01 2006 -0400 4.3 @@ -25,6 +25,7 @@ 4.4 #include <public/xen.h> 4.5 #include "of-devtree.h" 4.6 #include "oftree.h" 4.7 +#include "rtas.h" 4.8 4.9 #undef RTAS 4.10 4.11 @@ -347,6 +348,10 @@ static ofdn_t ofd_xen_props(void *m, str 4.12 val[0] = rma_size(d->arch.rma_order) - val[1]; 4.13 ofd_prop_add(m, n, "reserved", val, sizeof (val)); 4.14 4.15 + /* tell dom0 that Xen depends on it to have power control */ 4.16 + if (!rtas_entry) 4.17 + ofd_prop_add(m, n, "power-control", NULL, 0); 4.18 + 4.19 n = ofd_node_add(m, n, console, sizeof (console)); 4.20 if (n > 0) { 4.21 val[0] = 0;
5.1 --- a/xen/arch/powerpc/rtas.c Tue Sep 26 14:01:11 2006 -0400 5.2 +++ b/xen/arch/powerpc/rtas.c Thu Sep 28 12:34:01 2006 -0400 5.3 @@ -13,12 +13,90 @@ 5.4 * along with this program; if not, write to the Free Software 5.5 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 5.6 * 5.7 - * Copyright (C) IBM Corp. 2005 5.8 + * Copyright (C) IBM Corp. 2006 5.9 * 5.10 * Authors: Jimi Xenidis <jimix@watson.ibm.com> 5.11 */ 5.12 5.13 #include <xen/config.h> 5.14 +#include <xen/init.h> 5.15 +#include <xen/lib.h> 5.16 +#include <xen/errno.h> 5.17 +#include "of-devtree.h" 5.18 +#include "rtas.h" 5.19 5.20 -int rtas_halt = -1; 5.21 -int rtas_reboot = -1; 5.22 +static int rtas_halt_token = -1; 5.23 +static int rtas_reboot_token = -1; 5.24 +int rtas_entry; 5.25 +unsigned long rtas_msr; 5.26 +unsigned long rtas_base; 5.27 +unsigned long rtas_end; 5.28 + 5.29 +struct rtas_args { 5.30 + int ra_token; 5.31 + int ra_nargs; 5.32 + int ra_nrets; 5.33 + int ra_args[10]; 5.34 +} __attribute__ ((aligned(8))); 5.35 + 5.36 +static int rtas_call(struct rtas_args *r) 5.37 +{ 5.38 + if (rtas_entry == 0) 5.39 + return -ENOSYS; 5.40 + 5.41 + return prom_call(r, rtas_base, rtas_entry, rtas_msr); 5.42 +} 5.43 + 5.44 +int __init rtas_init(void *m) 5.45 +{ 5.46 + static const char halt[] = "power-off"; 5.47 + static const char reboot[] = "system-reboot"; 5.48 + ofdn_t n; 5.49 + 5.50 + if (rtas_entry == 0) 5.51 + return -ENOSYS; 5.52 + 5.53 + n = ofd_node_find(m, "/rtas"); 5.54 + if (n <= 0) 5.55 + return -ENOSYS; 5.56 + 5.57 + ofd_getprop(m, n, halt, 5.58 + &rtas_halt_token, sizeof (rtas_halt_token)); 5.59 + ofd_getprop(m, n, reboot, 5.60 + &rtas_reboot_token, sizeof (rtas_reboot_token)); 5.61 + return 1; 5.62 +} 5.63 + 5.64 +int 5.65 +rtas_halt(void) 5.66 +{ 5.67 + struct rtas_args r; 5.68 + 5.69 + if (rtas_halt_token == -1) 5.70 + return -1; 5.71 + 5.72 + r.ra_token = rtas_halt_token; 5.73 + r.ra_nargs = 2; 5.74 + r.ra_nrets = 1; 5.75 + r.ra_args[0] = 0; 5.76 + r.ra_args[1] = 0; 5.77 + 5.78 + return rtas_call(&r); 5.79 +} 5.80 + 5.81 +int 5.82 +rtas_reboot(void) 5.83 +{ 5.84 + struct rtas_args r; 5.85 + 5.86 + if (rtas_reboot_token == -1) 5.87 + return -ENOSYS; 5.88 + 5.89 + r.ra_token = rtas_reboot_token; 5.90 + r.ra_nargs = 2; 5.91 + r.ra_nrets = 1; 5.92 + r.ra_args[0] = 0; 5.93 + r.ra_args[1] = 0; 5.94 + 5.95 + return rtas_call(&r); 5.96 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/xen/arch/powerpc/rtas.h Thu Sep 28 12:34:01 2006 -0400 6.3 @@ -0,0 +1,34 @@ 6.4 +/* 6.5 + * This program is free software; you can redistribute it and/or modify 6.6 + * it under the terms of the GNU General Public License as published by 6.7 + * the Free Software Foundation; either version 2 of the License, or 6.8 + * (at your option) any later version. 6.9 + * 6.10 + * This program is distributed in the hope that it will be useful, 6.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 6.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 6.13 + * GNU General Public License for more details. 6.14 + * 6.15 + * You should have received a copy of the GNU General Public License 6.16 + * along with this program; if not, write to the Free Software 6.17 + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 6.18 + * 6.19 + * Copyright (C) IBM Corp. 2006 6.20 + * 6.21 + * Authors: Jimi Xenidis <jimix@us.ibm.com> 6.22 + */ 6.23 + 6.24 +#ifndef _ARCH_POWERPC_RTAS_H_ 6.25 +#define _ARCH_POWERPC_RTAS_H_ 6.26 + 6.27 +extern int rtas_entry; 6.28 +extern unsigned long rtas_msr; 6.29 +extern unsigned long rtas_base; 6.30 +extern unsigned long rtas_end; 6.31 + 6.32 +extern int prom_call(void *arg, unsigned rtas_base, 6.33 + unsigned long func, unsigned long msr); 6.34 +extern int rtas_init(void *); 6.35 +extern int rtas_halt(void); 6.36 +extern int rtas_reboot(void); 6.37 +#endif
7.1 --- a/xen/arch/powerpc/setup.c Tue Sep 26 14:01:11 2006 -0400 7.2 +++ b/xen/arch/powerpc/setup.c Thu Sep 28 12:34:01 2006 -0400 7.3 @@ -47,6 +47,7 @@ 7.4 #include "exceptions.h" 7.5 #include "of-devtree.h" 7.6 #include "oftree.h" 7.7 +#include "rtas.h" 7.8 7.9 #define DEBUG 7.10 7.11 @@ -286,9 +287,8 @@ static void __init __start_xen(multiboot 7.12 serial_init_preirq(); 7.13 7.14 init_console(); 7.15 -#ifdef CONSOLE_SYNC 7.16 + /* let synchronize until we really get going */ 7.17 console_start_sync(); 7.18 -#endif 7.19 7.20 /* we give the first RMA to the hypervisor */ 7.21 xenheap_phys_end = rma_size(cpu_default_rma_order_pages()); 7.22 @@ -312,6 +312,13 @@ static void __init __start_xen(multiboot 7.23 mod[mbi->mods_count-1].mod_end = 0; 7.24 --mbi->mods_count; 7.25 7.26 + if (rtas_entry) { 7.27 + rtas_init((void *)oftree); 7.28 + /* remove rtas module from consideration */ 7.29 + mod[mbi->mods_count-1].mod_start = 0; 7.30 + mod[mbi->mods_count-1].mod_end = 0; 7.31 + --mbi->mods_count; 7.32 + } 7.33 memory_init(mod, mbi->mods_count); 7.34 7.35 #ifdef OF_DEBUG 7.36 @@ -319,7 +326,6 @@ static void __init __start_xen(multiboot 7.37 /* make sure the OF devtree is good */ 7.38 ofd_walk((void *)oftree, OFD_ROOT, ofd_dump_props, OFD_DUMP_ALL); 7.39 #endif 7.40 - 7.41 percpu_init_areas(); 7.42 7.43 init_parea(0); 7.44 @@ -395,8 +401,9 @@ static void __init __start_xen(multiboot 7.45 /* Hide UART from DOM0 if we're using it */ 7.46 serial_endboot(); 7.47 7.48 + console_end_sync(); 7.49 + 7.50 domain_unpause_by_systemcontroller(dom0); 7.51 - 7.52 startup_cpu_idle_loop(); 7.53 } 7.54
8.1 --- a/xen/include/asm-powerpc/debugger.h Tue Sep 26 14:01:11 2006 -0400 8.2 +++ b/xen/include/asm-powerpc/debugger.h Thu Sep 28 12:34:01 2006 -0400 8.3 @@ -35,10 +35,18 @@ static inline void dump_execution_state( 8.4 show_backtrace(sp, lr, lr); 8.5 } 8.6 8.7 +static inline void __force_crash(void) 8.8 +{ 8.9 + dump_execution_state(); 8.10 + __builtin_trap(); 8.11 +} 8.12 + 8.13 static inline void debugger_trap_immediate(void) 8.14 { 8.15 dump_execution_state(); 8.16 +#ifdef CRASH_DEBUG 8.17 __builtin_trap(); 8.18 +#endif 8.19 } 8.20 8.21 static inline void unimplemented(void) 8.22 @@ -57,7 +65,7 @@ extern void __warn(char *file, int line) 8.23 #define WARN() __warn(__FILE__, __LINE__) 8.24 #define WARN_ON(_p) do { if (_p) WARN(); } while ( 0 ) 8.25 8.26 -#define FORCE_CRASH() debugger_trap_immediate() 8.27 +#define FORCE_CRASH() __force_crash() 8.28 8.29 #ifdef CRASH_DEBUG 8.30