direct-io.hg

changeset 15492:8a8e6dfa6dea

[XEN][POWERPC] Merge with xen-unstable.hg.
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
author Hollis Blanchard <hollisb@us.ibm.com>
date Fri Jul 06 16:01:04 2007 -0500 (2007-07-06)
parents d54d47fc8c6c 6750b1320159
children 92e15a15469d
files .hgignore
line diff
     1.1 --- a/.hgignore	Thu Jul 05 10:19:25 2007 +0100
     1.2 +++ b/.hgignore	Fri Jul 06 16:01:04 2007 -0500
     1.3 @@ -233,6 +233,7 @@
     1.4  ^xen/arch/powerpc/dom0\.bin$
     1.5  ^xen/arch/powerpc/asm-offsets\.s$
     1.6  ^xen/arch/powerpc/firmware$
     1.7 +^xen/arch/powerpc/firmware.dbg$
     1.8  ^xen/arch/powerpc/firmware_image.bin$
     1.9  ^xen/arch/powerpc/xen\.lds$
    1.10  ^xen/arch/powerpc/\.xen-syms$
     2.1 --- a/xen/arch/powerpc/Makefile	Thu Jul 05 10:19:25 2007 +0100
     2.2 +++ b/xen/arch/powerpc/Makefile	Fri Jul 06 16:01:04 2007 -0500
     2.3 @@ -35,6 +35,8 @@ obj-y += ofd_fixup_memory.o
     2.4  obj-y += physdev.o
     2.5  obj-y += platform.o
     2.6  obj-y += rtas.o
     2.7 +obj-y += rtas_nvram.o
     2.8 +obj-y += rtas_flash.o
     2.9  obj-y += setup.o
    2.10  obj-y += shadow.o
    2.11  obj-y += smp.o
    2.12 @@ -63,12 +65,19 @@ CFLAGS += $(PPC_C_WARNINGS)
    2.13  # objects into a single ELF segment and to not link in any additional
    2.14  # objects that gcc would normally like to
    2.15  #
    2.16 -OMAGIC = -nodefaultlibs -nostartfiles
    2.17 +OMAGIC = -nodefaultlibs -nostartfiles -Wl,--omagic
    2.18  
    2.19  firmware: of_handler/built_in.o $(TARGET_SUBARCH)/memcpy.o of-devtree.o
    2.20  	$(CC) $(CFLAGS) $(OMAGIC) -e __ofh_start -Wl,-Ttext,0x0 $^ -o $@
    2.21  
    2.22 -firmware_image.bin: firmware
    2.23 +#
    2.24 +# Link firmware again but this time at the place we expect to load it.
    2.25 +# This makes debugging _way_ easier.
    2.26 +#
    2.27 +firmware.dbg: of_handler/built_in.o $(TARGET_SUBARCH)/memcpy.o of-devtree.o
    2.28 +	$(CC) $(CFLAGS) $(OMAGIC) -e __ofh_start -Wl,-Ttext,0x2000000 $^ -o $@
    2.29 +
    2.30 +firmware_image.bin: firmware firmware.dbg
    2.31  	$(CROSS_COMPILE)objcopy --output-target=binary $< $@
    2.32  
    2.33  #
    2.34 @@ -139,5 +148,6 @@ dom0.bin: $(DOM0_IMAGE)
    2.35  
    2.36  clean::
    2.37  	$(MAKE) -f $(BASEDIR)/Rules.mk -C of_handler clean
    2.38 -	rm -f firmware firmware_image.bin dom0.bin .xen-syms xen-syms.S \
    2.39 +	rm -f firmware firmware.dbg firmware_image.bin \
    2.40 +		dom0.bin .xen-syms xen-syms.S \
    2.41  		xen.lds asm-offsets.s cmdline.dep
     3.1 --- a/xen/arch/powerpc/boot_of.c	Thu Jul 05 10:19:25 2007 +0100
     3.2 +++ b/xen/arch/powerpc/boot_of.c	Fri Jul 06 16:01:04 2007 -0500
     3.3 @@ -1073,31 +1073,40 @@ static int __init boot_of_rtas(module_t 
     3.4  static void * __init boot_of_devtree(module_t *mod, multiboot_info_t *mbi)
     3.5  {
     3.6      void *oft;
     3.7 -    ulong oft_sz = 48 * PAGE_SIZE;
     3.8 +    ulong alloc_sz = 32 << 10;    /* 32KiB should be plenty */
     3.9 +    ulong sz;
    3.10  
    3.11      /* snapshot the tree */
    3.12 -    oft = (void *)boot_of_alloc(oft_sz);
    3.13 +    oft = (void *)boot_of_alloc(alloc_sz);
    3.14      if (oft == NULL)
    3.15          of_panic("Could not allocate OFD tree\n");
    3.16  
    3.17      of_printf("creating oftree at: 0x%p\n", oft);
    3.18      of_test("package-to-path");
    3.19 -    oft = ofd_create(oft, oft_sz);
    3.20 +    oft = ofd_create(oft, alloc_sz);
    3.21      pkg_save(oft);
    3.22 +    sz = ofd_size(oft);
    3.23  
    3.24 -    if (ofd_size(oft) > oft_sz)
    3.25 -         of_panic("Could not fit all of native devtree\n");
    3.26 +    if (sz > alloc_sz)
    3.27 +        of_panic("Could not fit all of native devtree in 0x%lx of memory\n",
    3.28 +            alloc_sz);
    3.29  
    3.30      boot_of_fixup_refs(oft);
    3.31      boot_of_fixup_chosen(oft);
    3.32  
    3.33 -    if (ofd_size(oft) > oft_sz)
    3.34 -         of_panic("Could not fit all devtree fixups\n");
    3.35 +    if (sz > alloc_sz)
    3.36 +         of_panic("Could not fit all devtree fixupsin 0x%lx of memory\n",
    3.37 +            alloc_sz);
    3.38  
    3.39      ofd_walk(oft, __func__, OFD_ROOT, /* add_hype_props */ NULL, 2);
    3.40  
    3.41      mod->mod_start = (ulong)oft;
    3.42 -    mod->mod_end = mod->mod_start + oft_sz;
    3.43 +    mod->mod_end = ALIGN_UP(mod->mod_start + sz, PAGE_SIZE);
    3.44 +
    3.45 +    if (mod->mod_end -mod->mod_start > alloc_sz)
    3.46 +        of_panic("Could not fit all devtree module in 0x%lx of memory\n",
    3.47 +            alloc_sz);
    3.48 +
    3.49      of_printf("%s: devtree mod @ 0x%016x - 0x%016x\n", __func__,
    3.50                mod->mod_start, mod->mod_end);
    3.51  
     4.1 --- a/xen/arch/powerpc/domain_build.c	Thu Jul 05 10:19:25 2007 +0100
     4.2 +++ b/xen/arch/powerpc/domain_build.c	Fri Jul 06 16:01:04 2007 -0500
     4.3 @@ -68,6 +68,7 @@ int construct_dom0(struct domain *d,
     4.4      struct vcpu *v;
     4.5      ulong dst;
     4.6      u64 *ofh_tree;
     4.7 +    ulong firmware_base;
     4.8      uint rma_nrpages = 1 << cpu_default_rma_order_pages();
     4.9      ulong rma_sz;
    4.10      ulong rma;
    4.11 @@ -78,6 +79,7 @@ int construct_dom0(struct domain *d,
    4.12      ulong mod_len = 0;
    4.13      ulong shared_info_addr;
    4.14      uint extent_size = 1 << cpu_extent_order();
    4.15 +    ulong sz;
    4.16  
    4.17      /* Sanity! */
    4.18      BUG_ON(d->domain_id != 0);
    4.19 @@ -87,26 +89,6 @@ int construct_dom0(struct domain *d,
    4.20  
    4.21      printk("*** LOADING DOMAIN 0 ***\n");
    4.22  
    4.23 -    rc = elf_init(&elf, (void *)image_start, image_len);
    4.24 -    if (rc)
    4.25 -        return rc;
    4.26 -#ifdef VERBOSE
    4.27 -    elf_set_verbose(&elf);
    4.28 -#endif
    4.29 -    elf_parse_binary(&elf);
    4.30 -    if (0 != (elf_xen_parse(&elf, &parms)))
    4.31 -        return rc;
    4.32 -
    4.33 -    printk("Dom0 kernel: %s, paddr 0x%" PRIx64 " -> 0x%" PRIx64 "\n",
    4.34 -            elf_64bit(&elf) ? "64-bit" : "32-bit",
    4.35 -            elf.pstart, elf.pend);
    4.36 -
    4.37 -    /* elf contains virtual addresses that can have the upper bits
    4.38 -     * masked while running in real mode, so we do the masking as well
    4.39 -     * as well */
    4.40 -    parms.virt_kend = RM_MASK(parms.virt_kend, 42);
    4.41 -    parms.virt_entry = RM_MASK(parms.virt_entry, 42);
    4.42 -
    4.43      /* default is the max(1/16th of memory, CONFIG_MIN_DOM0_PAGES) */
    4.44      if (dom0_nrpages == 0) {
    4.45          dom0_nrpages = total_pages >> 4;
    4.46 @@ -196,41 +178,43 @@ int construct_dom0(struct domain *d,
    4.47      v = d->vcpu[0];
    4.48      cpu_init_vcpu(v);
    4.49  
    4.50 -    /* OF usually sits here:
    4.51 -     *   - Linux needs it to be loaded before the vmlinux or initrd
    4.52 -     *   - AIX demands it to be @ 32M.
    4.53 -     */
    4.54 -    dst = (32 << 20);
    4.55 -
    4.56 -    /* Put stack below everything. */
    4.57 -    v->arch.ctxt.gprs[1] = dst - STACK_FRAME_OVERHEAD;
    4.58 -
    4.59 -    /* copy relative to Xen */
    4.60 -    dst += rma;
    4.61 +    /* convert xen pointer shared_info into guest physical */
    4.62 +    shared_info_addr = (ulong)d->shared_info - page_to_maddr(d->arch.rma_page);
    4.63  
    4.64 -    ASSERT((dst - rma) + (ulong)firmware_image_size < eomem);
    4.65 -    printk("loading OFH: 0x%lx, RMA: 0x%lx\n", dst, dst - rma);
    4.66 -    memcpy((void *)dst, firmware_image_start, (ulong)firmware_image_size);
    4.67 -
    4.68 -    v->arch.ctxt.gprs[5] = (dst - rma);
    4.69 -    ofh_tree = (u64 *)(dst + 0x10);
    4.70 -    ASSERT(*ofh_tree == 0xdeadbeef00000000);
    4.71 +    /* start loading stuff */
    4.72 +    rc = elf_init(&elf, (void *)image_start, image_len);
    4.73 +    if (rc)
    4.74 +        return rc;
    4.75 +#ifdef VERBOSE
    4.76 +    elf_set_verbose(&elf);
    4.77 +#endif
    4.78 +    elf_parse_binary(&elf);
    4.79 +    if (0 != (elf_xen_parse(&elf, &parms)))
    4.80 +        return rc;
    4.81  
    4.82 -    /* accomodate for a modest bss section */
    4.83 -    dst = ALIGN_UP(dst + (ulong)firmware_image_size + PAGE_SIZE, PAGE_SIZE);
    4.84 -    ASSERT((dst - rma) + oftree_len < eomem);
    4.85 +    printk("Dom0 kernel: %s, paddr 0x%" PRIx64 " -> 0x%" PRIx64 "\n",
    4.86 +            elf_64bit(&elf) ? "64-bit" : "32-bit",
    4.87 +            elf.pstart, elf.pend);
    4.88  
    4.89 -    *ofh_tree = dst - rma;
    4.90 -    printk("loading OFD: 0x%lx RMA: 0x%lx, 0x%lx\n", dst, dst - rma,
    4.91 -           oftree_len);
    4.92 -    memcpy((void *)dst, (void *)oftree, oftree_len);
    4.93 -    dst = ALIGN_UP(dst + oftree_len, PAGE_SIZE);
    4.94 +    /* elf contains virtual addresses that can have the upper bits
    4.95 +     * masked while running in real mode, so we do the masking as well
    4.96 +     * as well */
    4.97 +    parms.virt_kend = RM_MASK(parms.virt_kend, 42);
    4.98 +    parms.virt_entry = RM_MASK(parms.virt_entry, 42);
    4.99 +
   4.100 +    /* set the MSR bit correctly */
   4.101 +    if (elf_64bit(&elf))
   4.102 +        v->arch.ctxt.msr = MSR_SF;
   4.103 +    else
   4.104 +        v->arch.ctxt.msr = 0;
   4.105  
   4.106      /* Load the dom0 kernel. */
   4.107 -    elf.dest = (void *)dst;
   4.108 +    elf.dest = (void *)(parms.virt_kstart + rma);
   4.109 +
   4.110      elf_load_binary(&elf);
   4.111 -    v->arch.ctxt.pc = dst - rma + (parms.virt_entry - parms.virt_kstart);
   4.112 -    dst = ALIGN_UP(dst + parms.virt_kend, PAGE_SIZE);
   4.113 +    v->arch.ctxt.pc = parms.virt_entry;
   4.114 +
   4.115 +    dst = ALIGN_UP(parms.virt_kend + rma, PAGE_SIZE);
   4.116  
   4.117      /* Load the initrd. */
   4.118      if (initrd_len > 0) {
   4.119 @@ -247,15 +231,46 @@ int construct_dom0(struct domain *d,
   4.120          printk("no initrd\n");
   4.121      }
   4.122  
   4.123 -    if (elf_64bit(&elf)) {
   4.124 -        v->arch.ctxt.msr = MSR_SF;
   4.125 -    } else {
   4.126 -        v->arch.ctxt.msr = 0;
   4.127 -    }
   4.128 -    v->arch.ctxt.gprs[2] = 0;
   4.129      v->arch.ctxt.gprs[3] = mod_start;
   4.130      v->arch.ctxt.gprs[4] = mod_len;
   4.131  
   4.132 +    /* OF usually sits here:
   4.133 +     *   - Linux needs it to be loaded before the vmlinux or initrd
   4.134 +     *   - AIX demands it to be @ 32M.
   4.135 +     */
   4.136 +    firmware_base = (32 << 20);
   4.137 +    if (dst - rma > firmware_base)
   4.138 +    panic("Firmware [0x%lx] will over-write images ending: 0x%lx\n",
   4.139 +          firmware_base, dst - rma);
   4.140 +    dst = firmware_base + rma;
   4.141 +
   4.142 +    /* Put stack below firmware. */
   4.143 +    v->arch.ctxt.gprs[1] = dst - rma - STACK_FRAME_OVERHEAD;
   4.144 +    v->arch.ctxt.gprs[2] = 0;
   4.145 +
   4.146 +    ASSERT((dst - rma) + (ulong)firmware_image_size < eomem);
   4.147 +    printk("loading OFH: 0x%lx, RMA: 0x%lx\n", dst, dst - rma);
   4.148 +    memcpy((void *)dst, firmware_image_start, (ulong)firmware_image_size);
   4.149 +
   4.150 +    v->arch.ctxt.gprs[5] = (dst - rma);
   4.151 +    ofh_tree = (u64 *)(dst + 0x10);
   4.152 +    ASSERT(*ofh_tree == 0xdeadbeef00000000);
   4.153 +
   4.154 +    /* accomodate for a modest bss section */
   4.155 +    dst = ALIGN_UP(dst + (ulong)firmware_image_size + PAGE_SIZE, PAGE_SIZE);
   4.156 +
   4.157 +    ASSERT((dst - rma) + oftree_len < eomem);
   4.158 +
   4.159 +    *ofh_tree = dst - rma;
   4.160 +    printk("loading OFD: 0x%lx RMA: 0x%lx, 0x%lx\n", dst, dst - rma,
   4.161 +           oftree_len);
   4.162 +    memcpy((void *)dst, (void *)oftree, oftree_len);
   4.163 +
   4.164 +    /* fixup and add stuff for dom0 */
   4.165 +    sz = ofd_dom0_fixup(d, *ofh_tree + rma, cmdline, shared_info_addr);
   4.166 +    printk("modified OFD size: 0x%lx\n", sz);
   4.167 +    dst = ALIGN_UP(dst + sz + PAGE_SIZE, PAGE_SIZE);
   4.168 +
   4.169  	printk("dom0 initial register state:\n"
   4.170  			"    pc %016lx msr %016lx\n"
   4.171  			"    r1 %016lx r2 %016lx r3 %016lx\n"
   4.172 @@ -268,11 +283,6 @@ int construct_dom0(struct domain *d,
   4.173  			v->arch.ctxt.gprs[4],
   4.174  			v->arch.ctxt.gprs[5]);
   4.175  
   4.176 -    /* convert xen pointer shared_info into guest physical */
   4.177 -    shared_info_addr = (ulong)d->shared_info - page_to_maddr(d->arch.rma_page);
   4.178 -
   4.179 -    ofd_dom0_fixup(d, *ofh_tree + rma, cmdline, shared_info_addr);
   4.180 -
   4.181      v->is_initialised = 1;
   4.182      clear_bit(_VPF_down, &v->pause_flags);
   4.183  
     5.1 --- a/xen/arch/powerpc/of_handler/Makefile	Thu Jul 05 10:19:25 2007 +0100
     5.2 +++ b/xen/arch/powerpc/of_handler/Makefile	Fri Jul 06 16:01:04 2007 -0500
     5.3 @@ -16,6 +16,7 @@ obj-y += leap.o
     5.4  obj-y += memory.o
     5.5  obj-y += ofh.o
     5.6  obj-y += papr.o
     5.7 +obj-y += rtas.o
     5.8  obj-y += services.o
     5.9  obj-y += vdevice.o
    5.10  obj-y += xencomm.o
     6.1 --- a/xen/arch/powerpc/of_handler/head.S	Thu Jul 05 10:19:25 2007 +0100
     6.2 +++ b/xen/arch/powerpc/of_handler/head.S	Fri Jul 06 16:01:04 2007 -0500
     6.3 @@ -1,25 +1,28 @@
     6.4  /*
     6.5 - * Copyright (C) 2005 Jimi Xenidis <jimix@watson.ibm.com>, IBM Corporation
     6.6 - *
     6.7   * This program is free software; you can redistribute it and/or modify
     6.8   * it under the terms of the GNU General Public License as published by
     6.9   * the Free Software Foundation; either version 2 of the License, or
    6.10   * (at your option) any later version.
    6.11 - * 
    6.12 + *
    6.13   * This program is distributed in the hope that it will be useful,
    6.14   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    6.15   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    6.16   * GNU General Public License for more details.
    6.17 - * 
    6.18 + *
    6.19   * You should have received a copy of the GNU General Public License
    6.20   * along with this program; if not, write to the Free Software
    6.21 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
    6.22 + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    6.23 + *
    6.24 + * Copyright (C) IBM Corp. 2005, 2007
    6.25 + *
    6.26 + * Authors: Jimi Xenidis <jimix@watson.ibm.com>
    6.27   */
    6.28 +
    6.29  /*
    6.30   * Glue code for open-firmware client interface implementation.
    6.31   */
    6.32  
    6.33 -#define OF_STACK_SIZE (32*1024)
    6.34 +#define OF_STACK_SIZE (64*1024)
    6.35  
    6.36  #include <asm/config.h>
    6.37  #include <asm/processor.h>
    6.38 @@ -62,11 +65,6 @@
    6.39  	.long 0x0	
    6.40  	.long 0x0	
    6.41  	
    6.42 -	. = 0x30
    6.43 -_ofh_cih_stack_end:
    6.44 -	.space	OF_STACK_SIZE
    6.45 -_ofh_cih_stack:
    6.46 -   
    6.47  _ofh_cih_continue:
    6.48  	mflr	r12				# r12 = &_ofh_work_space
    6.49  	mr	r11, r1				# r11 = orig stk ptr
    6.50 @@ -150,3 +148,9 @@ 1:	mflr	r5
    6.51  	subf	r3,r4,r5
    6.52  	mtlr	r0
    6.53  	blr
    6.54 +
    6.55 +	.data
    6.56 +	.p2align 3
    6.57 +_ofh_cih_stack_end:
    6.58 +	.space	OF_STACK_SIZE
    6.59 +_ofh_cih_stack:
     7.1 --- a/xen/arch/powerpc/of_handler/ofh.c	Thu Jul 05 10:19:25 2007 +0100
     7.2 +++ b/xen/arch/powerpc/of_handler/ofh.c	Fri Jul 06 16:01:04 2007 -0500
     7.3 @@ -234,6 +234,7 @@ ofh_init(ulong b)
     7.4  
     7.5      ofh_service_init(b);
     7.6      ofh_chosen_init(b);
     7.7 +	ofh_rtas_init(b);
     7.8      ofh_options_init(b);
     7.9  }
    7.10  
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/xen/arch/powerpc/of_handler/rtas.c	Fri Jul 06 16:01:04 2007 -0500
     8.3 @@ -0,0 +1,82 @@
     8.4 +/*
     8.5 + * This program is free software; you can redistribute it and/or modify
     8.6 + * it under the terms of the GNU General Public License as published by
     8.7 + * the Free Software Foundation; either version 2 of the License, or
     8.8 + * (at your option) any later version.
     8.9 + *
    8.10 + * This program is distributed in the hope that it will be useful,
    8.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    8.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    8.13 + * GNU General Public License for more details.
    8.14 + *
    8.15 + * You should have received a copy of the GNU General Public License
    8.16 + * along with this program; if not, write to the Free Software
    8.17 + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    8.18 + *
    8.19 + * Copyright (C) IBM Corp. 2007
    8.20 + *
    8.21 + * Authors: Jimi Xenidis <jimix@watson.ibm.com>
    8.22 + */
    8.23 +
    8.24 +#include "ofh.h"
    8.25 +#include <stdarg.h>
    8.26 +#include <xen/lib.h>
    8.27 +extern char _rtas_image_start[];
    8.28 +extern char _rtas_image_end[];
    8.29 +
    8.30 +static int
    8.31 +rtas_instantiate_rtas(u32 nargs, u32 nrets, s32 argp[], s32 retp[], ulong b)
    8.32 +{
    8.33 +    if (nargs == 1) {
    8.34 +        if (nrets == 1) {
    8.35 +            void *rtas_base_address = (void *)(ulong)argp[0];
    8.36 +            u32 sz = (_rtas_image_end - _rtas_image_start);
    8.37 +
    8.38 +            memcpy(rtas_base_address,
    8.39 +                   DRELA(&_rtas_image_start[0], b), sz);
    8.40 +            retp[0] = (ulong)rtas_base_address;
    8.41 +
    8.42 +            return OF_SUCCESS;
    8.43 +        }
    8.44 +    }
    8.45 +    return OF_FAILURE;
    8.46 +}
    8.47 +
    8.48 +
    8.49 +static struct ofh_methods _rtas_methods[] = {
    8.50 +    { "instantiate-rtas", rtas_instantiate_rtas },
    8.51 +    { NULL, NULL},
    8.52 +};
    8.53 +
    8.54 +static struct ofh_ihandle _ih_rtas = {
    8.55 +    .ofi_methods = _rtas_methods,
    8.56 +};
    8.57 +
    8.58 +static int rtas_open(u32 b)
    8.59 +{
    8.60 +    u32 ih = DRELA((u32)&_ih_rtas, b);
    8.61 +
    8.62 +    return ih;
    8.63 +}
    8.64 +
    8.65 +void ofh_rtas_init(ulong b)
    8.66 +{
    8.67 +    static const char path[] = "/rtas";
    8.68 +    ofdn_t n;
    8.69 +    void *m = ofd_mem(b);
    8.70 +    u32 sz;
    8.71 +
    8.72 +    n = ofd_node_find(m, DRELA(&path[0], b));
    8.73 +    if (n <= 0)
    8.74 +        return;
    8.75 +
    8.76 +    sz = (_rtas_image_end - _rtas_image_start);
    8.77 +    /* Round size up to a multiple of 0x1000 */
    8.78 +    sz = ALIGN_UP(sz, PAGE_SIZE);
    8.79 +
    8.80 +    ofd_prop_add(m, n, DRELA((const char *)"rtas-size", b),
    8.81 +                 &sz, sizeof(sz));
    8.82 +
    8.83 +    /* create an IO node */
    8.84 +    ofd_io_create(m, n, (ulong)rtas_open);
    8.85 +}
     9.1 --- a/xen/arch/powerpc/of_handler/vdevice.c	Thu Jul 05 10:19:25 2007 +0100
     9.2 +++ b/xen/arch/powerpc/of_handler/vdevice.c	Fri Jul 06 16:01:04 2007 -0500
     9.3 @@ -36,7 +36,7 @@ ofh_vty_init(ofdn_t chosen, ulong b)
     9.4  
     9.5      /* find the vty */
     9.6      n = ofd_node_find(mem,
     9.7 -                        DRELA((const char *)"/vdevice/vty", b));
     9.8 +                      DRELA((const char *)"/vdevice/vty", b));
     9.9      if (n > 0) {
    9.10          /* PAPR VTERM */
    9.11          ret = ofd_getprop(mem, n, DRELA((const char *)"reg", b),
    10.1 --- a/xen/arch/powerpc/of_handler/xen_hvcall.S	Thu Jul 05 10:19:25 2007 +0100
    10.2 +++ b/xen/arch/powerpc/of_handler/xen_hvcall.S	Fri Jul 06 16:01:04 2007 -0500
    10.3 @@ -1,19 +1,21 @@
    10.4  /*
    10.5 - * Copyright (C) 2005 Jimi Xenidis <jimix@watson.ibm.com>, IBM Corporation
    10.6 - *
    10.7   * This program is free software; you can redistribute it and/or modify
    10.8   * it under the terms of the GNU General Public License as published by
    10.9   * the Free Software Foundation; either version 2 of the License, or
   10.10   * (at your option) any later version.
   10.11 - * 
   10.12 + *
   10.13   * This program is distributed in the hope that it will be useful,
   10.14   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   10.15   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   10.16   * GNU General Public License for more details.
   10.17 - * 
   10.18 + *
   10.19   * You should have received a copy of the GNU General Public License
   10.20   * along with this program; if not, write to the Free Software
   10.21 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   10.22 + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   10.23 + *
   10.24 + * Copyright (C) IBM Corp. 2005, 2007
   10.25 + *
   10.26 + * Authors: Jimi Xenidis <jimix@watson.ibm.com>
   10.27   */
   10.28  
   10.29  #include <asm/config.h>
   10.30 @@ -26,3 +28,17 @@
   10.31  _GLOBAL(xen_hvcall)
   10.32      HSC
   10.33      blr
   10.34 +
   10.35 +/* The following stub will get instantiated as RTAS in the guest */	
   10.36 +#define H_RTAS_PROXY 23
   10.37 +    .p2align 3
   10.38 +    .global _rtas_image_start
   10.39 +    .global _rtas_image_end
   10.40 +_rtas_image_start:
   10.41 +    mr	r4,r3
   10.42 +    lis	r3,0xffff
   10.43 +    ori	r3,r3,H_RTAS_PROXY
   10.44 +    HSC
   10.45 +    blr
   10.46 +    nop
   10.47 +_rtas_image_end:
    11.1 --- a/xen/arch/powerpc/ofd_fixup.c	Thu Jul 05 10:19:25 2007 +0100
    11.2 +++ b/xen/arch/powerpc/ofd_fixup.c	Fri Jul 06 16:01:04 2007 -0500
    11.3 @@ -27,8 +27,6 @@
    11.4  #include "oftree.h"
    11.5  #include "rtas.h"
    11.6  
    11.7 -#undef RTAS
    11.8 -
    11.9  ofdn_t ofd_boot_cpu;
   11.10  
   11.11  #ifdef PAPR_VTERM
   11.12 @@ -307,26 +305,6 @@ static ofdn_t ofd_chosen_props(void *m, 
   11.13      return n;
   11.14  }
   11.15  
   11.16 -#ifdef RTAS
   11.17 -static ofdn_t ofd_rtas_props(void *m)
   11.18 -{
   11.19 -    static const char path[] = "/rtas";
   11.20 -    static const char hypertas[] = "dummy";
   11.21 -    ofdn_t p;
   11.22 -    ofdn_t n;
   11.23 -
   11.24 -    /* just enough to make linux think its on LPAR */
   11.25 -
   11.26 -    p = ofd_node_find(m, "/");
   11.27 -
   11.28 -    n = ofd_node_add(m, p, path, sizeof(path));
   11.29 -    ofd_prop_add(m, n, "name", &path[1], sizeof (path) - 1);
   11.30 -    ofd_prop_add(m, n, "ibm,hypertas-functions", hypertas, sizeof (hypertas));
   11.31 -
   11.32 -    return n;
   11.33 -}
   11.34 -#endif
   11.35 -
   11.36  static ofdn_t ofd_xen_props(void *m, struct domain *d, ulong shared_info)
   11.37  {
   11.38      ofdn_t n;
   11.39 @@ -382,8 +360,8 @@ static ofdn_t ofd_xen_props(void *m, str
   11.40      return n;
   11.41  }
   11.42  
   11.43 -int ofd_dom0_fixup(struct domain *d, ulong mem, const char *cmdline,
   11.44 -                   ulong shared_info)
   11.45 +ulong ofd_dom0_fixup(struct domain *d, ulong mem, const char *cmdline,
   11.46 +                     ulong shared_info)
   11.47  {
   11.48      void *m;
   11.49      const ofdn_t n = OFD_ROOT;
   11.50 @@ -423,11 +401,8 @@ int ofd_dom0_fixup(struct domain *d, ulo
   11.51      printk("Remove original /rtas\n");
   11.52      ofd_prune_path(m, "/rtas");
   11.53  
   11.54 -#ifdef RTAS
   11.55 -    printk("Create a new RTAS with just enough stuff to convince "
   11.56 -           "Linux that its on LPAR\n");
   11.57 -    ofd_rtas_props(m);
   11.58 -#endif
   11.59 +    rtas_proxy_init(m);
   11.60 +
   11.61  #ifdef FIX_COMPAT 
   11.62      const char compat[] = "Hypervisor,Maple";
   11.63      r = ofd_prop_add(m, n, "compatible", compat, sizeof (compat));
   11.64 @@ -446,5 +421,5 @@ int ofd_dom0_fixup(struct domain *d, ulo
   11.65  #ifdef DEBUG
   11.66      ofd_walk(m, __func__, OFD_ROOT, ofd_dump_props, OFD_DUMP_ALL);
   11.67  #endif
   11.68 -    return 1;
   11.69 +    return ofd_size(m);
   11.70  }
    12.1 --- a/xen/arch/powerpc/oftree.h	Thu Jul 05 10:19:25 2007 +0100
    12.2 +++ b/xen/arch/powerpc/oftree.h	Fri Jul 06 16:01:04 2007 -0500
    12.3 @@ -28,8 +28,8 @@ extern ulong oftree_len;
    12.4  extern ulong oftree_end;
    12.5  extern ofdn_t ofd_boot_cpu;
    12.6  
    12.7 -extern int ofd_dom0_fixup(struct domain *d, ulong mem, const char *cmdline,
    12.8 -                          ulong shared_info);
    12.9 +extern ulong ofd_dom0_fixup(struct domain *d, ulong mem, const char *cmdline,
   12.10 +                            ulong shared_info);
   12.11  extern void ofd_memory_props(void *m, struct domain *d);
   12.12  
   12.13  extern int firmware_image_start[0];
    13.1 --- a/xen/arch/powerpc/powerpc64/hypercall_table.S	Thu Jul 05 10:19:25 2007 +0100
    13.2 +++ b/xen/arch/powerpc/powerpc64/hypercall_table.S	Fri Jul 06 16:01:04 2007 -0500
    13.3 @@ -27,7 +27,7 @@
    13.4          .quad do_grant_table_op     /* 20 */
    13.5          .quad do_vm_assist
    13.6          .quad 0 /* do_update_va_mapping_otherdomain */
    13.7 -        .quad 0 /* do_switch_vm86 */
    13.8 +        .quad do_rtas_proxy /* do_switch_vm86 */
    13.9          .quad do_vcpu_op
   13.10          .quad do_ni_hypercall       /* 25 */
   13.11          .quad 0 /* do_mmuext_op */
    14.1 --- a/xen/arch/powerpc/rtas.c	Thu Jul 05 10:19:25 2007 +0100
    14.2 +++ b/xen/arch/powerpc/rtas.c	Fri Jul 06 16:01:04 2007 -0500
    14.3 @@ -13,7 +13,7 @@
    14.4   * along with this program; if not, write to the Free Software
    14.5   * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    14.6   *
    14.7 - * Copyright (C) IBM Corp. 2006
    14.8 + * Copyright (C) IBM Corp. 2006, 2007
    14.9   *
   14.10   * Authors: Jimi Xenidis <jimix@watson.ibm.com>
   14.11   */
   14.12 @@ -22,24 +22,16 @@
   14.13  #include <xen/init.h>
   14.14  #include <xen/lib.h>
   14.15  #include <xen/errno.h>
   14.16 +#include <xen/sched.h>
   14.17  #include "of-devtree.h"
   14.18  #include "rtas.h"
   14.19  
   14.20 -static int rtas_halt_token = -1;
   14.21 -static int rtas_reboot_token = -1;
   14.22  int rtas_entry;
   14.23  unsigned long rtas_msr;
   14.24  unsigned long rtas_base;
   14.25  unsigned long rtas_end;
   14.26  
   14.27 -struct rtas_args {
   14.28 -    int ra_token;
   14.29 -    int ra_nargs;
   14.30 -    int ra_nrets;
   14.31 -    int ra_args[10];
   14.32 -} __attribute__ ((aligned(8)));
   14.33 -
   14.34 -static int rtas_call(struct rtas_args *r)
   14.35 +int rtas_call(void *r)
   14.36  {
   14.37      if (rtas_entry == 0)
   14.38          return -ENOSYS;
   14.39 @@ -47,11 +39,51 @@ static int rtas_call(struct rtas_args *r
   14.40      return prom_call(r, rtas_base, rtas_entry, rtas_msr);
   14.41  }
   14.42  
   14.43 +/* rtas always uses physical address */
   14.44 +void *rtas_remote_addr(ulong addr, ulong length)
   14.45 +{
   14.46 +    struct vcpu *v = get_current();
   14.47 +    struct domain *d = v->domain;
   14.48 +    ulong mfn;
   14.49 +    ulong mfn_end;
   14.50 +
   14.51 +    mfn = gmfn_to_mfn(d, addr >> PAGE_SHIFT);
   14.52 +    if (mfn == INVALID_MFN)
   14.53 +        return NULL;
   14.54 +
   14.55 +    /* a little paranoid since almost everyone will pass us page
   14.56 +     * bounded thingies, but just in case */
   14.57 +    mfn_end = gmfn_to_mfn(d, (addr + length) >> PAGE_SHIFT);
   14.58 +    if (mfn_end == INVALID_MFN)
   14.59 +        return NULL;
   14.60 +
   14.61 +    return (void *)((mfn << PAGE_SHIFT) | (addr & (PAGE_SIZE - 1)));
   14.62 +}
   14.63 +
   14.64 +/* these do not proxy */
   14.65 +#define RTAS_HALT 0
   14.66 +#define RTAS_REBOOT 1
   14.67 +
   14.68 +struct rtas_token rt_power_off = { .name = "power-off", .token = -1, };
   14.69 +struct rtas_token rt_system_reboot = { .name = "system-reboot", .token = -1};
   14.70 +
   14.71 +static struct rtas_token *tokens[] = {
   14.72 +    /* these do not proxy */
   14.73 +    [RTAS_HALT] = &rt_power_off,
   14.74 +    [RTAS_REBOOT] = &rt_system_reboot,
   14.75 +    &rt_nvram_store,
   14.76 +    &rt_nvram_fetch,
   14.77 +    &rt_manage_flash,
   14.78 +    &rt_validate_flash,
   14.79 +    &rt_update_reboot_flash
   14.80 +};
   14.81 +
   14.82 +static int rtas_proxy;
   14.83 +
   14.84  int __init rtas_init(void *m)
   14.85  {
   14.86 -    static const char halt[] = "power-off";
   14.87 -    static const char reboot[] = "system-reboot";
   14.88      ofdn_t n;
   14.89 +    int i;
   14.90  
   14.91      if (rtas_entry == 0)
   14.92          return -ENOSYS;
   14.93 @@ -60,22 +92,87 @@ int __init rtas_init(void *m)
   14.94      if (n <= 0)
   14.95          return -ENOSYS;
   14.96  
   14.97 -    ofd_getprop(m, n, halt,
   14.98 -                &rtas_halt_token, sizeof (rtas_halt_token));
   14.99 -    ofd_getprop(m, n, reboot,
  14.100 -                &rtas_reboot_token, sizeof (rtas_reboot_token));
  14.101 +    for (i = 0; i < ARRAY_SIZE(tokens); i++) {
  14.102 +        ofd_getprop(m, n, tokens[i]->name,
  14.103 +                    &tokens[i]->token, sizeof (tokens[i]->token));
  14.104 +        if (!rtas_proxy && tokens[i]->proxy && tokens[i]->token != -1)
  14.105 +            rtas_proxy = 1;
  14.106 +    }
  14.107      return 1;
  14.108  }
  14.109  
  14.110 +int rtas_proxy_init(void *m)
  14.111 +{
  14.112 +    static const char path[] = "/rtas";
  14.113 +    ofdn_t p;
  14.114 +    ofdn_t n;
  14.115 +    int i;
  14.116 +
  14.117 +    if (!rtas_proxy)
  14.118 +        return -1;
  14.119 +
  14.120 +    printk("Create a new /rtas with tokens Xen is willing to proxy\n");
  14.121 +
  14.122 +    p = ofd_node_find(m, "/");
  14.123 +
  14.124 +    n = ofd_node_add(m, p, path, sizeof(path));
  14.125 +    ofd_prop_add(m, n, "name", &path[1], sizeof (path) - 1);
  14.126 +
  14.127 +    /* and the tokens for proxy */
  14.128 +    for (i = 0; i < ARRAY_SIZE(tokens); i++) {
  14.129 +        if (tokens[i]->proxy && tokens[i]->token != -1)
  14.130 +            ofd_prop_add(m, n, tokens[i]->name, &i, sizeof (i));
  14.131 +    }
  14.132 +    return n;
  14.133 +}
  14.134 +
  14.135 +int do_rtas_proxy(ulong arg)
  14.136 +{
  14.137 +    struct rtas_args *r;
  14.138 +    unsigned i;
  14.139 +    int token;
  14.140 +    ulong sz;
  14.141 +
  14.142 +    if (!IS_PRIV(current->domain))
  14.143 +        return -EPERM;
  14.144 +    if (!rtas_proxy)
  14.145 +        return -ENOSYS;
  14.146 +
  14.147 +    /* has to be at least 5 words */
  14.148 +    sz = (3 + 1 + 1) * sizeof (int);
  14.149 +    r = rtas_remote_addr(arg, sz);
  14.150 +    if (r == NULL) {
  14.151 +        /* this is about all we can do at this point */
  14.152 +        return -1;
  14.153 +    }
  14.154 +    /* make sure we can deal with everything */
  14.155 +    sz = (3 + r->ra_nargs + r->ra_nrets) * sizeof (int);
  14.156 +    if (rtas_remote_addr(arg, sz) == NULL) {
  14.157 +        r->ra_args[r->ra_nargs] = RTAS_HW;
  14.158 +        return -1;
  14.159 +    }
  14.160 +
  14.161 +    i = r->ra_token;
  14.162 +    token = tokens[i]->token;
  14.163 +
  14.164 +    if (i < ARRAY_SIZE(tokens) &&
  14.165 +        tokens[i]->proxy != NULL &&
  14.166 +        token != -1)
  14.167 +        return tokens[i]->proxy(token, r);
  14.168 +
  14.169 +    return -1;
  14.170 +}
  14.171 +
  14.172  int
  14.173  rtas_halt(void)
  14.174  {
  14.175      struct rtas_args r;
  14.176 +    int token = tokens[RTAS_HALT]->token;
  14.177  
  14.178 -    if (rtas_halt_token == -1)
  14.179 +    if (token == -1)
  14.180          return -1;
  14.181  
  14.182 -    r.ra_token = rtas_halt_token;
  14.183 +    r.ra_token = token;
  14.184      r.ra_nargs = 2;
  14.185      r.ra_nrets = 1;
  14.186      r.ra_args[0] = 0;
  14.187 @@ -89,10 +186,12 @@ rtas_reboot(void)
  14.188  {
  14.189      struct rtas_args r;
  14.190  
  14.191 -    if (rtas_reboot_token == -1)
  14.192 -        return -ENOSYS;
  14.193 +    int token = tokens[RTAS_REBOOT]->token;
  14.194  
  14.195 -    r.ra_token = rtas_reboot_token;
  14.196 +    if (token == -1)
  14.197 +        return -1;
  14.198 +
  14.199 +    r.ra_token = token;
  14.200      r.ra_nargs = 2;
  14.201      r.ra_nrets = 1;
  14.202      r.ra_args[0] = 0;
    15.1 --- a/xen/arch/powerpc/rtas.h	Thu Jul 05 10:19:25 2007 +0100
    15.2 +++ b/xen/arch/powerpc/rtas.h	Fri Jul 06 16:01:04 2007 -0500
    15.3 @@ -26,9 +26,40 @@ extern unsigned long rtas_msr;
    15.4  extern unsigned long rtas_base;
    15.5  extern unsigned long rtas_end;
    15.6  
    15.7 +struct rtas_args {
    15.8 +    int ra_token;
    15.9 +    int ra_nargs;
   15.10 +    int ra_nrets;
   15.11 +    int ra_args[10];
   15.12 +} __attribute__ ((aligned(8)));
   15.13 +
   15.14 +struct rtas_token {
   15.15 +    char *name;
   15.16 +    int (*proxy)(int token, struct rtas_args *r);
   15.17 +    int token;
   15.18 +};
   15.19 +
   15.20 +extern struct rtas_token rt_power_off;
   15.21 +extern struct rtas_token rt_system_reboot;
   15.22 +extern struct rtas_token rt_nvram_fetch;
   15.23 +extern struct rtas_token rt_nvram_store;
   15.24 +extern struct rtas_token rt_manage_flash;
   15.25 +extern struct rtas_token rt_validate_flash;
   15.26 +extern struct rtas_token rt_update_reboot_flash;
   15.27 +
   15.28 +/* RTAS errors */
   15.29 +#define RTAS_HW -1
   15.30 +#define RTAS_BUSY -2
   15.31 +#define RTAS_PARAMETER -3
   15.32 +
   15.33 +
   15.34  extern int prom_call(void *arg, unsigned base,
   15.35                       unsigned long func, unsigned long msr);
   15.36  extern int rtas_init(void *);
   15.37  extern int rtas_halt(void);
   15.38  extern int rtas_reboot(void);
   15.39 +extern int rtas_proxy_init(void *m);
   15.40 +extern int do_rtas_proxy(ulong arg);
   15.41 +extern void *rtas_remote_addr(ulong addr, ulong length);
   15.42 +extern int rtas_call(void *r);
   15.43  #endif
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/xen/arch/powerpc/rtas_flash.c	Fri Jul 06 16:01:04 2007 -0500
    16.3 @@ -0,0 +1,182 @@
    16.4 +/*
    16.5 + * This program is free software; you can redistribute it and/or modify
    16.6 + * it under the terms of the GNU General Public License as published by
    16.7 + * the Free Software Foundation; either version 2 of the License, or
    16.8 + * (at your option) any later version.
    16.9 + *
   16.10 + * This program is distributed in the hope that it will be useful,
   16.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   16.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16.13 + * GNU General Public License for more details.
   16.14 + *
   16.15 + * You should have received a copy of the GNU General Public License
   16.16 + * along with this program; if not, write to the Free Software
   16.17 + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   16.18 + *
   16.19 + * Copyright (C) IBM Corp. 2007
   16.20 + *
   16.21 + * Authors: Jimi Xenidis <jimix@watson.ibm.com>
   16.22 + */
   16.23 +
   16.24 +#include <xen/config.h>
   16.25 +#include <xen/init.h>
   16.26 +#include <xen/lib.h>
   16.27 +#include <xen/sched.h>
   16.28 +#include "rtas.h"
   16.29 +
   16.30 +static int rtas_manage_flash(int token, struct rtas_args *ra)
   16.31 +{
   16.32 +    struct rtas_args r;
   16.33 +    ulong sz = (3 + ra->ra_nargs + ra->ra_nrets) * sizeof (int);
   16.34 +    int ret;
   16.35 +
   16.36 +    if (ra->ra_nargs != 1 || ra->ra_nrets != 1) {
   16.37 +        ra->ra_args[ra->ra_nargs] = RTAS_PARAMETER;
   16.38 +        return -1;
   16.39 +    }
   16.40 +    memcpy(&r, ra, sz);
   16.41 +    r.ra_token = token;
   16.42 +
   16.43 +    ret = rtas_call(&r);
   16.44 +    ra->ra_args[ra->ra_nargs] = r.ra_args[r.ra_nargs];
   16.45 +    return ret;
   16.46 +}
   16.47 +struct rtas_token rt_manage_flash = {
   16.48 +    .name = "ibm,manage-flash-image",
   16.49 +    .proxy = rtas_manage_flash,
   16.50 +    .token = -1
   16.51 +};
   16.52 +
   16.53 +static int rtas_validate_flash(int token, struct rtas_args *ra)
   16.54 +{
   16.55 +    ulong length = ra->ra_args[1];
   16.56 +    char *buffer;
   16.57 +    char *local;
   16.58 +    struct rtas_args r;
   16.59 +    ulong sz = (3 + ra->ra_nargs + ra->ra_nrets) * sizeof (int);
   16.60 +    int ret;
   16.61 +
   16.62 +    if (ra->ra_nargs != 2 || ra->ra_nrets != 2) {
   16.63 +        ra->ra_args[ra->ra_nargs] = RTAS_PARAMETER;
   16.64 +        return -1;
   16.65 +    }
   16.66 +
   16.67 +    /* the original pointer can be in memory that is too high so we
   16.68 +     * need to do it locally */
   16.69 +    buffer = rtas_remote_addr(ra->ra_args[0], length);
   16.70 +    if (buffer == NULL) {
   16.71 +        ra->ra_args[ra->ra_nargs] = RTAS_PARAMETER;
   16.72 +        return -1;
   16.73 +    }
   16.74 +        
   16.75 +    local = xmalloc_bytes(length);
   16.76 +    if (local == NULL) {
   16.77 +        printk("%s: could not allocate local buffer size: 0x%lx\n",
   16.78 +               __func__, length);
   16.79 +        ra->ra_args[ra->ra_nargs] = RTAS_HW;
   16.80 +        return -1;
   16.81 +    }
   16.82 +    /* RTAS is 32bits so we need to make sure that that local
   16.83 +     * buffer is in that range */
   16.84 +    BUG_ON(((ulong)local + length) & ~0xffffffffUL);
   16.85 +
   16.86 +    /* copy the remote buffer to the local one */
   16.87 +    memcpy(local, buffer, length);
   16.88 +
   16.89 +    memcpy(&r, ra, sz);
   16.90 +    r.ra_token = token;
   16.91 +    r.ra_args[0] = (unsigned)(ulong)local;
   16.92 +    ret = rtas_call(&r);
   16.93 +    ra->ra_args[ra->ra_nargs] = r.ra_args[r.ra_nargs];
   16.94 +    ra->ra_args[ra->ra_nargs + 1] = r.ra_args[r.ra_nargs + 1];
   16.95 +    xfree(local);
   16.96 +    return ret;
   16.97 +}
   16.98 +
   16.99 +struct rtas_token rt_validate_flash = {
  16.100 +    .name = "ibm,validate-flash-image",
  16.101 +    .proxy = rtas_validate_flash,
  16.102 +    .token = -1
  16.103 +};
  16.104 +
  16.105 +/* flash data structs */
  16.106 +struct flash_block {
  16.107 +    u64 addr;
  16.108 +    u64 length;
  16.109 +};
  16.110 +struct flash_block_list {
  16.111 +    struct {
  16.112 +        u64 ver:8;
  16.113 +        u64 bytes:56;
  16.114 +    } header;
  16.115 +    u64 *next;
  16.116 +    struct flash_block blocks[0];
  16.117 +};
  16.118 +
  16.119 +static int safe_to_flash;
  16.120 +static int rtas_update_reboot_flash(int token, struct rtas_args *ra)
  16.121 +{
  16.122 +    struct rtas_args r;
  16.123 +    ulong sz = (3 + ra->ra_nargs + ra->ra_nrets) * sizeof (int);
  16.124 +    int ret;
  16.125 +    void *local;
  16.126 +    struct flash_block_list *l;
  16.127 +    ulong blocks;
  16.128 +    
  16.129 +    if (ra->ra_nargs != 1 || ra->ra_nrets != 1) {
  16.130 +        ra->ra_args[ra->ra_nargs] = RTAS_PARAMETER;
  16.131 +        return -1;
  16.132 +    }
  16.133 +
  16.134 +    if (!safe_to_flash) {
  16.135 +        printk("%s: this has not been fully tested yet\n", __func__);
  16.136 +        ra->ra_args[ra->ra_nargs] = RTAS_HW;
  16.137 +        return -1;
  16.138 +    }
  16.139 +
  16.140 +    /* we only need to relocate the first block address to 4G, for now
  16.141 +     * lets just bug on that */
  16.142 +    local = rtas_remote_addr(ra->ra_args[0], 16);
  16.143 +    BUG_ON((ulong)local & ~0xffffffffUL);
  16.144 +
  16.145 +    /* now we run through the block list and translate base addresses */
  16.146 +    l = (struct flash_block_list *)local;
  16.147 +
  16.148 +    /* header and next count as one block */
  16.149 +    blocks = (l->header.bytes / sizeof (struct flash_block)) - 1;
  16.150 +    if (blocks == 0) {
  16.151 +        ra->ra_args[ra->ra_nargs] = RTAS_PARAMETER;
  16.152 +        return -1;
  16.153 +    }
  16.154 +
  16.155 +    /* go thru the block lists */
  16.156 +    do {
  16.157 +        int i = 0;
  16.158 +
  16.159 +        /* go thru the block in the list */
  16.160 +        for (i = 0; i < blocks; i++) {
  16.161 +            void *addr;
  16.162 +
  16.163 +            addr = rtas_remote_addr(l->blocks[i].addr, l->blocks[i].length);
  16.164 +            BUG_ON(addr == NULL);
  16.165 +            l->blocks[i].addr = (u64)addr;
  16.166 +        }
  16.167 +        l = (struct flash_block_list *)l->next;
  16.168 +    } while (l != NULL);
  16.169 +
  16.170 +    memcpy(&r, ra, sz);
  16.171 +    r.ra_token = token;
  16.172 +
  16.173 +    /* this arguement is a pointer to a block list */
  16.174 +    r.ra_args[0] = (unsigned)(ulong)local;
  16.175 +
  16.176 +    ret = rtas_call(&r);
  16.177 +    ra->ra_args[ra->ra_nargs] = r.ra_args[r.ra_nargs];
  16.178 +    return ret;
  16.179 +}
  16.180 +
  16.181 +struct rtas_token rt_update_reboot_flash = {
  16.182 +    .name = "ibm,update-flash-64-and-reboot",
  16.183 +    .proxy = rtas_update_reboot_flash,
  16.184 +    .token = -1
  16.185 +};
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/xen/arch/powerpc/rtas_nvram.c	Fri Jul 06 16:01:04 2007 -0500
    17.3 @@ -0,0 +1,129 @@
    17.4 +/*
    17.5 + * This program is free software; you can redistribute it and/or modify
    17.6 + * it under the terms of the GNU General Public License as published by
    17.7 + * the Free Software Foundation; either version 2 of the License, or
    17.8 + * (at your option) any later version.
    17.9 + *
   17.10 + * This program is distributed in the hope that it will be useful,
   17.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   17.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   17.13 + * GNU General Public License for more details.
   17.14 + *
   17.15 + * You should have received a copy of the GNU General Public License
   17.16 + * along with this program; if not, write to the Free Software
   17.17 + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   17.18 + *
   17.19 + * Copyright (C) IBM Corp. 2007
   17.20 + *
   17.21 + * Authors: Jimi Xenidis <jimix@watson.ibm.com>
   17.22 + */
   17.23 +
   17.24 +#include <xen/config.h>
   17.25 +#include <xen/init.h>
   17.26 +#include <xen/lib.h>
   17.27 +#include <xen/sched.h>
   17.28 +#include "rtas.h"
   17.29 +
   17.30 +static int rtas_nvram_store(int token, struct rtas_args *ra)
   17.31 +{
   17.32 +    ulong length = ra->ra_args[2];
   17.33 +    char *buffer;
   17.34 +    char *local;
   17.35 +    struct rtas_args r;
   17.36 +    ulong sz = (3 + ra->ra_nargs + ra->ra_nrets) * sizeof (int);
   17.37 +    int ret;
   17.38 +
   17.39 +    if (ra->ra_nargs != 3 || ra->ra_nrets != 2) {
   17.40 +        ra->ra_args[ra->ra_nargs] = RTAS_PARAMETER;
   17.41 +        return -1;
   17.42 +    }
   17.43 +
   17.44 +    /* the original pointer can be in memory that is too high so we
   17.45 +     * need to do it locally */
   17.46 +    buffer = rtas_remote_addr(ra->ra_args[1], length);
   17.47 +    if (buffer == NULL) {
   17.48 +        ra->ra_args[ra->ra_nargs] = RTAS_PARAMETER;
   17.49 +        return -1;
   17.50 +    }
   17.51 +        
   17.52 +    local = xmalloc_bytes(length);
   17.53 +    if (local == NULL) {
   17.54 +        printk("%s: could not allocate local buffer size: 0x%lx\n",
   17.55 +               __func__, length);
   17.56 +        ra->ra_args[ra->ra_nargs] = RTAS_HW;
   17.57 +        return -1;
   17.58 +    }
   17.59 +    /* RTAS is 32bits so we need to make sure that that local
   17.60 +     * buffer is in that range */
   17.61 +    BUG_ON(((ulong)local + length) & ~0xffffffffUL);
   17.62 +
   17.63 +    /* copy the remote buffer to the local one */
   17.64 +    memcpy(local, buffer, length);
   17.65 +
   17.66 +    memcpy(&r, ra, sz);
   17.67 +    r.ra_token = token;
   17.68 +    r.ra_args[1] = (unsigned)(ulong)local;
   17.69 +
   17.70 +    ret = rtas_call(&r);
   17.71 +    ra->ra_args[ra->ra_nargs] = r.ra_args[r.ra_nargs];
   17.72 +    ra->ra_args[ra->ra_nargs + 1] = r.ra_args[r.ra_nargs + 1];
   17.73 +    xfree(local);
   17.74 +    return ret;
   17.75 +}
   17.76 +
   17.77 +struct rtas_token rt_nvram_store = {
   17.78 +    .name = "nvram-store",
   17.79 +    .proxy = rtas_nvram_store,
   17.80 +    .token = -1
   17.81 +};
   17.82 +
   17.83 +static int rtas_nvram_fetch(int token, struct rtas_args *ra)
   17.84 +{
   17.85 +    ulong length = ra->ra_args[2];
   17.86 +    char *buffer;
   17.87 +    char *local;
   17.88 +    struct rtas_args r;
   17.89 +    ulong sz = (3 + ra->ra_nargs + ra->ra_nrets) * sizeof (int);
   17.90 +    int ret;
   17.91 +
   17.92 +    if (ra->ra_nargs != 3 || ra->ra_nrets != 2) {
   17.93 +        ra->ra_args[ra->ra_nargs] = RTAS_PARAMETER;
   17.94 +        return -1;
   17.95 +    }
   17.96 +    /* the original pointer can be in ememory that is too high so
   17.97 +     * we need to do it locally */
   17.98 +    buffer = rtas_remote_addr(ra->ra_args[1], length);
   17.99 +
  17.100 +    local = xmalloc_bytes(length);
  17.101 +    if (local == NULL) {
  17.102 +        printk("%s: could not allocate local buffer size: 0x%lx\n",
  17.103 +               __func__, length);
  17.104 +        ra->ra_args[ra->ra_nargs] = RTAS_HW;
  17.105 +        return -1;
  17.106 +    }
  17.107 +    /* RTAS is 32bits so we need to make sure that that local
  17.108 +     * buffer is in that range */
  17.109 +    BUG_ON(((ulong)local + length) & ~0xffffffffUL);
  17.110 +
  17.111 +    memcpy(&r, ra, sz);
  17.112 +    r.ra_token = token;
  17.113 +    r.ra_args[1] = (unsigned)(ulong)local;
  17.114 +
  17.115 +    ret = rtas_call(&r);
  17.116 +    ra->ra_args[ra->ra_nargs] = r.ra_args[r.ra_nargs];
  17.117 +    ra->ra_args[ra->ra_nargs + 1] = r.ra_args[r.ra_nargs + 1];
  17.118 +    if (r.ra_args[r.ra_nargs] >= 0) {
  17.119 +        /* copy from local to remote */
  17.120 +        sz = r.ra_args[r.ra_nargs + 1];
  17.121 +        memcpy(buffer, local, sz);
  17.122 +    }
  17.123 +    xfree(local);
  17.124 +    return ret;
  17.125 +}
  17.126 +
  17.127 +struct rtas_token rt_nvram_fetch = {
  17.128 +    .name = "nvram-fetch",
  17.129 +    .proxy = rtas_nvram_fetch,
  17.130 +    .token = -1
  17.131 +};
  17.132 +