direct-io.hg

changeset 12918: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>
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