# HG changeset patch
# User Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
# Date 1181074198 14400
# Node ID 6750b1320159458c15fed78ba26d202ada818e57
# Parent 06a32f040d64a9e26d29f97bd0c48cf25724788a
[POWERPC][XEN] Set up an RTAS node for dom0 and proxy methods
If real FW supplies an RTAS layer then pass thru the methods Xen will
proxy for Dom0.
- NVRAM read/write methods work, see nvsetenv(8) or nvram(8).
- Firmware flash methods exist, but currently "chicken switched" off
for further testing.
Signed-off-by: Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
---
xen/arch/powerpc/Makefile | 2
xen/arch/powerpc/ofd_fixup.c | 37 +-------
xen/arch/powerpc/oftree.h | 4
xen/arch/powerpc/rtas.c | 151 ++++++++++++++++++++++++++++------
xen/arch/powerpc/rtas.h | 31 +++++++
xen/arch/powerpc/rtas_flash.c | 182 ++++++++++++++++++++++++++++++++++++++++++
xen/arch/powerpc/rtas_nvram.c | 129 +++++++++++++++++++++++++++++
7 files changed, 477 insertions(+), 59 deletions(-)
diff -r 06a32f040d64 -r 6750b1320159 xen/arch/powerpc/Makefile
--- a/xen/arch/powerpc/Makefile Sun Jun 03 10:39:31 2007 -0400
+++ b/xen/arch/powerpc/Makefile Tue Jun 05 16:09:58 2007 -0400
@@ -35,6 +35,8 @@ obj-y += physdev.o
obj-y += physdev.o
obj-y += platform.o
obj-y += rtas.o
+obj-y += rtas_nvram.o
+obj-y += rtas_flash.o
obj-y += setup.o
obj-y += shadow.o
obj-y += smp.o
diff -r 06a32f040d64 -r 6750b1320159 xen/arch/powerpc/ofd_fixup.c
--- a/xen/arch/powerpc/ofd_fixup.c Sun Jun 03 10:39:31 2007 -0400
+++ b/xen/arch/powerpc/ofd_fixup.c Tue Jun 05 16:09:58 2007 -0400
@@ -26,8 +26,6 @@
#include "of-devtree.h"
#include "oftree.h"
#include "rtas.h"
-
-#undef RTAS
ofdn_t ofd_boot_cpu;
@@ -307,26 +305,6 @@ static ofdn_t ofd_chosen_props(void *m,
return n;
}
-#ifdef RTAS
-static ofdn_t ofd_rtas_props(void *m)
-{
- static const char path[] = "/rtas";
- static const char hypertas[] = "dummy";
- ofdn_t p;
- ofdn_t n;
-
- /* just enough to make linux think its on LPAR */
-
- p = ofd_node_find(m, "/");
-
- n = ofd_node_add(m, p, path, sizeof(path));
- ofd_prop_add(m, n, "name", &path[1], sizeof (path) - 1);
- ofd_prop_add(m, n, "ibm,hypertas-functions", hypertas, sizeof (hypertas));
-
- return n;
-}
-#endif
-
static ofdn_t ofd_xen_props(void *m, struct domain *d, ulong shared_info)
{
ofdn_t n;
@@ -382,8 +360,8 @@ static ofdn_t ofd_xen_props(void *m, str
return n;
}
-int ofd_dom0_fixup(struct domain *d, ulong mem, const char *cmdline,
- ulong shared_info)
+ulong ofd_dom0_fixup(struct domain *d, ulong mem, const char *cmdline,
+ ulong shared_info)
{
void *m;
const ofdn_t n = OFD_ROOT;
@@ -423,11 +401,8 @@ int ofd_dom0_fixup(struct domain *d, ulo
printk("Remove original /rtas\n");
ofd_prune_path(m, "/rtas");
-#ifdef RTAS
- printk("Create a new RTAS with just enough stuff to convince "
- "Linux that its on LPAR\n");
- ofd_rtas_props(m);
-#endif
+ rtas_proxy_init(m);
+
#ifdef FIX_COMPAT
const char compat[] = "Hypervisor,Maple";
r = ofd_prop_add(m, n, "compatible", compat, sizeof (compat));
@@ -446,5 +421,5 @@ int ofd_dom0_fixup(struct domain *d, ulo
#ifdef DEBUG
ofd_walk(m, __func__, OFD_ROOT, ofd_dump_props, OFD_DUMP_ALL);
#endif
- return 1;
-}
+ return ofd_size(m);
+}
diff -r 06a32f040d64 -r 6750b1320159 xen/arch/powerpc/oftree.h
--- a/xen/arch/powerpc/oftree.h Sun Jun 03 10:39:31 2007 -0400
+++ b/xen/arch/powerpc/oftree.h Tue Jun 05 16:09:58 2007 -0400
@@ -28,8 +28,8 @@ extern ulong oftree_end;
extern ulong oftree_end;
extern ofdn_t ofd_boot_cpu;
-extern int ofd_dom0_fixup(struct domain *d, ulong mem, const char *cmdline,
- ulong shared_info);
+extern ulong ofd_dom0_fixup(struct domain *d, ulong mem, const char *cmdline,
+ ulong shared_info);
extern void ofd_memory_props(void *m, struct domain *d);
extern int firmware_image_start[0];
diff -r 06a32f040d64 -r 6750b1320159 xen/arch/powerpc/rtas.c
--- a/xen/arch/powerpc/rtas.c Sun Jun 03 10:39:31 2007 -0400
+++ b/xen/arch/powerpc/rtas.c Tue Jun 05 16:09:58 2007 -0400
@@ -13,7 +13,7 @@
* along with this program; if not, write to the Free Software
* Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
- * Copyright (C) IBM Corp. 2006
+ * Copyright (C) IBM Corp. 2006, 2007
*
* Authors: Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
*/
@@ -22,24 +22,16 @@
#include <xen/init.h>
#include <xen/lib.h>
#include <xen/errno.h>
+#include <xen/sched.h>
#include "of-devtree.h"
#include "rtas.h"
-static int rtas_halt_token = -1;
-static int rtas_reboot_token = -1;
int rtas_entry;
unsigned long rtas_msr;
unsigned long rtas_base;
unsigned long rtas_end;
-struct rtas_args {
- int ra_token;
- int ra_nargs;
- int ra_nrets;
- int ra_args[10];
-} __attribute__ ((aligned(8)));
-
-static int rtas_call(struct rtas_args *r)
+int rtas_call(void *r)
{
if (rtas_entry == 0)
return -ENOSYS;
@@ -47,11 +39,51 @@ static int rtas_call(struct rtas_args *r
return prom_call(r, rtas_base, rtas_entry, rtas_msr);
}
+/* rtas always uses physical address */
+void *rtas_remote_addr(ulong addr, ulong length)
+{
+ struct vcpu *v = get_current();
+ struct domain *d = v->domain;
+ ulong mfn;
+ ulong mfn_end;
+
+ mfn = gmfn_to_mfn(d, addr >> PAGE_SHIFT);
+ if (mfn == INVALID_MFN)
+ return NULL;
+
+ /* a little paranoid since almost everyone will pass us page
+ * bounded thingies, but just in case */
+ mfn_end = gmfn_to_mfn(d, (addr + length) >> PAGE_SHIFT);
+ if (mfn_end == INVALID_MFN)
+ return NULL;
+
+ return (void *)((mfn << PAGE_SHIFT) | (addr & (PAGE_SIZE - 1)));
+}
+
+/* these do not proxy */
+#define RTAS_HALT 0
+#define RTAS_REBOOT 1
+
+struct rtas_token rt_power_off = { .name = "power-off", .token = -1, };
+struct rtas_token rt_system_reboot = { .name = "system-reboot", .token = -1};
+
+static struct rtas_token *tokens[] = {
+ /* these do not proxy */
+ [RTAS_HALT] = &rt_power_off,
+ [RTAS_REBOOT] = &rt_system_reboot,
+ &rt_nvram_store,
+ &rt_nvram_fetch,
+ &rt_manage_flash,
+ &rt_validate_flash,
+ &rt_update_reboot_flash
+};
+
+static int rtas_proxy;
+
int __init rtas_init(void *m)
{
- static const char halt[] = "power-off";
- static const char reboot[] = "system-reboot";
ofdn_t n;
+ int i;
if (rtas_entry == 0)
return -ENOSYS;
@@ -60,22 +92,87 @@ int __init rtas_init(void *m)
if (n <= 0)
return -ENOSYS;
- ofd_getprop(m, n, halt,
- &rtas_halt_token, sizeof (rtas_halt_token));
- ofd_getprop(m, n, reboot,
- &rtas_reboot_token, sizeof (rtas_reboot_token));
+ for (i = 0; i < ARRAY_SIZE(tokens); i++) {
+ ofd_getprop(m, n, tokens[i]->name,
+ &tokens[i]->token, sizeof (tokens[i]->token));
+ if (!rtas_proxy && tokens[i]->proxy && tokens[i]->token != -1)
+ rtas_proxy = 1;
+ }
return 1;
+}
+
+int rtas_proxy_init(void *m)
+{
+ static const char path[] = "/rtas";
+ ofdn_t p;
+ ofdn_t n;
+ int i;
+
+ if (!rtas_proxy)
+ return -1;
+
+ printk("Create a new /rtas with tokens Xen is willing to proxy\n");
+
+ p = ofd_node_find(m, "/");
+
+ n = ofd_node_add(m, p, path, sizeof(path));
+ ofd_prop_add(m, n, "name", &path[1], sizeof (path) - 1);
+
+ /* and the tokens for proxy */
+ for (i = 0; i < ARRAY_SIZE(tokens); i++) {
+ if (tokens[i]->proxy && tokens[i]->token != -1)
+ ofd_prop_add(m, n, tokens[i]->name, &i, sizeof (i));
+ }
+ return n;
+}
+
+int do_rtas_proxy(ulong arg)
+{
+ struct rtas_args *r;
+ unsigned i;
+ int token;
+ ulong sz;
+
+ if (!IS_PRIV(current->domain))
+ return -EPERM;
+ if (!rtas_proxy)
+ return -ENOSYS;
+
+ /* has to be at least 5 words */
+ sz = (3 + 1 + 1) * sizeof (int);
+ r = rtas_remote_addr(arg, sz);
+ if (r == NULL) {
+ /* this is about all we can do at this point */
+ return -1;
+ }
+ /* make sure we can deal with everything */
+ sz = (3 + r->ra_nargs + r->ra_nrets) * sizeof (int);
+ if (rtas_remote_addr(arg, sz) == NULL) {
+ r->ra_args[r->ra_nargs] = RTAS_HW;
+ return -1;
+ }
+
+ i = r->ra_token;
+ token = tokens[i]->token;
+
+ if (i < ARRAY_SIZE(tokens) &&
+ tokens[i]->proxy != NULL &&
+ token != -1)
+ return tokens[i]->proxy(token, r);
+
+ return -1;
}
int
rtas_halt(void)
{
struct rtas_args r;
-
- if (rtas_halt_token == -1)
- return -1;
-
- r.ra_token = rtas_halt_token;
+ int token = tokens[RTAS_HALT]->token;
+
+ if (token == -1)
+ return -1;
+
+ r.ra_token = token;
r.ra_nargs = 2;
r.ra_nrets = 1;
r.ra_args[0] = 0;
@@ -89,10 +186,12 @@ rtas_reboot(void)
{
struct rtas_args r;
- if (rtas_reboot_token == -1)
- return -ENOSYS;
-
- r.ra_token = rtas_reboot_token;
+ int token = tokens[RTAS_REBOOT]->token;
+
+ if (token == -1)
+ return -1;
+
+ r.ra_token = token;
r.ra_nargs = 2;
r.ra_nrets = 1;
r.ra_args[0] = 0;
diff -r 06a32f040d64 -r 6750b1320159 xen/arch/powerpc/rtas.h
--- a/xen/arch/powerpc/rtas.h Sun Jun 03 10:39:31 2007 -0400
+++ b/xen/arch/powerpc/rtas.h Tue Jun 05 16:09:58 2007 -0400
@@ -26,9 +26,40 @@ extern unsigned long rtas_base;
extern unsigned long rtas_base;
extern unsigned long rtas_end;
+struct rtas_args {
+ int ra_token;
+ int ra_nargs;
+ int ra_nrets;
+ int ra_args[10];
+} __attribute__ ((aligned(8)));
+
+struct rtas_token {
+ char *name;
+ int (*proxy)(int token, struct rtas_args *r);
+ int token;
+};
+
+extern struct rtas_token rt_power_off;
+extern struct rtas_token rt_system_reboot;
+extern struct rtas_token rt_nvram_fetch;
+extern struct rtas_token rt_nvram_store;
+extern struct rtas_token rt_manage_flash;
+extern struct rtas_token rt_validate_flash;
+extern struct rtas_token rt_update_reboot_flash;
+
+/* RTAS errors */
+#define RTAS_HW -1
+#define RTAS_BUSY -2
+#define RTAS_PARAMETER -3
+
+
extern int prom_call(void *arg, unsigned base,
unsigned long func, unsigned long msr);
extern int rtas_init(void *);
extern int rtas_halt(void);
extern int rtas_reboot(void);
+extern int rtas_proxy_init(void *m);
+extern int do_rtas_proxy(ulong arg);
+extern void *rtas_remote_addr(ulong addr, ulong length);
+extern int rtas_call(void *r);
#endif
diff -r 06a32f040d64 -r 6750b1320159 xen/arch/powerpc/rtas_flash.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/powerpc/rtas_flash.c Tue Jun 05 16:09:58 2007 -0400
@@ -0,0 +1,182 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Copyright (C) IBM Corp. 2007
+ *
+ * Authors: Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
+ */
+
+#include <xen/config.h>
+#include <xen/init.h>
+#include <xen/lib.h>
+#include <xen/sched.h>
+#include "rtas.h"
+
+static int rtas_manage_flash(int token, struct rtas_args *ra)
+{
+ struct rtas_args r;
+ ulong sz = (3 + ra->ra_nargs + ra->ra_nrets) * sizeof (int);
+ int ret;
+
+ if (ra->ra_nargs != 1 || ra->ra_nrets != 1) {
+ ra->ra_args[ra->ra_nargs] = RTAS_PARAMETER;
+ return -1;
+ }
+ memcpy(&r, ra, sz);
+ r.ra_token = token;
+
+ ret = rtas_call(&r);
+ ra->ra_args[ra->ra_nargs] = r.ra_args[r.ra_nargs];
+ return ret;
+}
+struct rtas_token rt_manage_flash = {
+ .name = "ibm,manage-flash-image",
+ .proxy = rtas_manage_flash,
+ .token = -1
+};
+
+static int rtas_validate_flash(int token, struct rtas_args *ra)
+{
+ ulong length = ra->ra_args[1];
+ char *buffer;
+ char *local;
+ struct rtas_args r;
+ ulong sz = (3 + ra->ra_nargs + ra->ra_nrets) * sizeof (int);
+ int ret;
+
+ if (ra->ra_nargs != 2 || ra->ra_nrets != 2) {
+ ra->ra_args[ra->ra_nargs] = RTAS_PARAMETER;
+ return -1;
+ }
+
+ /* the original pointer can be in memory that is too high so we
+ * need to do it locally */
+ buffer = rtas_remote_addr(ra->ra_args[0], length);
+ if (buffer == NULL) {
+ ra->ra_args[ra->ra_nargs] = RTAS_PARAMETER;
+ return -1;
+ }
+
+ local = xmalloc_bytes(length);
+ if (local == NULL) {
+ printk("%s: could not allocate local buffer size: 0x%lx\n",
+ __func__, length);
+ ra->ra_args[ra->ra_nargs] = RTAS_HW;
+ return -1;
+ }
+ /* RTAS is 32bits so we need to make sure that that local
+ * buffer is in that range */
+ BUG_ON(((ulong)local + length) & ~0xffffffffUL);
+
+ /* copy the remote buffer to the local one */
+ memcpy(local, buffer, length);
+
+ memcpy(&r, ra, sz);
+ r.ra_token = token;
+ r.ra_args[0] = (unsigned)(ulong)local;
+ ret = rtas_call(&r);
+ ra->ra_args[ra->ra_nargs] = r.ra_args[r.ra_nargs];
+ ra->ra_args[ra->ra_nargs + 1] = r.ra_args[r.ra_nargs + 1];
+ xfree(local);
+ return ret;
+}
+
+struct rtas_token rt_validate_flash = {
+ .name = "ibm,validate-flash-image",
+ .proxy = rtas_validate_flash,
+ .token = -1
+};
+
+/* flash data structs */
+struct flash_block {
+ u64 addr;
+ u64 length;
+};
+struct flash_block_list {
+ struct {
+ u64 ver:8;
+ u64 bytes:56;
+ } header;
+ u64 *next;
+ struct flash_block blocks[0];
+};
+
+static int safe_to_flash;
+static int rtas_update_reboot_flash(int token, struct rtas_args *ra)
+{
+ struct rtas_args r;
+ ulong sz = (3 + ra->ra_nargs + ra->ra_nrets) * sizeof (int);
+ int ret;
+ void *local;
+ struct flash_block_list *l;
+ ulong blocks;
+
+ if (ra->ra_nargs != 1 || ra->ra_nrets != 1) {
+ ra->ra_args[ra->ra_nargs] = RTAS_PARAMETER;
+ return -1;
+ }
+
+ if (!safe_to_flash) {
+ printk("%s: this has not been fully tested yet\n", __func__);
+ ra->ra_args[ra->ra_nargs] = RTAS_HW;
+ return -1;
+ }
+
+ /* we only need to relocate the first block address to 4G, for now
+ * lets just bug on that */
+ local = rtas_remote_addr(ra->ra_args[0], 16);
+ BUG_ON((ulong)local & ~0xffffffffUL);
+
+ /* now we run through the block list and translate base addresses */
+ l = (struct flash_block_list *)local;
+
+ /* header and next count as one block */
+ blocks = (l->header.bytes / sizeof (struct flash_block)) - 1;
+ if (blocks == 0) {
+ ra->ra_args[ra->ra_nargs] = RTAS_PARAMETER;
+ return -1;
+ }
+
+ /* go thru the block lists */
+ do {
+ int i = 0;
+
+ /* go thru the block in the list */
+ for (i = 0; i < blocks; i++) {
+ void *addr;
+
+ addr = rtas_remote_addr(l->blocks[i].addr, l->blocks[i].length);
+ BUG_ON(addr == NULL);
+ l->blocks[i].addr = (u64)addr;
+ }
+ l = (struct flash_block_list *)l->next;
+ } while (l != NULL);
+
+ memcpy(&r, ra, sz);
+ r.ra_token = token;
+
+ /* this arguement is a pointer to a block list */
+ r.ra_args[0] = (unsigned)(ulong)local;
+
+ ret = rtas_call(&r);
+ ra->ra_args[ra->ra_nargs] = r.ra_args[r.ra_nargs];
+ return ret;
+}
+
+struct rtas_token rt_update_reboot_flash = {
+ .name = "ibm,update-flash-64-and-reboot",
+ .proxy = rtas_update_reboot_flash,
+ .token = -1
+};
diff -r 06a32f040d64 -r 6750b1320159 xen/arch/powerpc/rtas_nvram.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/powerpc/rtas_nvram.c Tue Jun 05 16:09:58 2007 -0400
@@ -0,0 +1,129 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Copyright (C) IBM Corp. 2007
+ *
+ * Authors: Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
+ */
+
+#include <xen/config.h>
+#include <xen/init.h>
+#include <xen/lib.h>
+#include <xen/sched.h>
+#include "rtas.h"
+
+static int rtas_nvram_store(int token, struct rtas_args *ra)
+{
+ ulong length = ra->ra_args[2];
+ char *buffer;
+ char *local;
+ struct rtas_args r;
+ ulong sz = (3 + ra->ra_nargs + ra->ra_nrets) * sizeof (int);
+ int ret;
+
+ if (ra->ra_nargs != 3 || ra->ra_nrets != 2) {
+ ra->ra_args[ra->ra_nargs] = RTAS_PARAMETER;
+ return -1;
+ }
+
+ /* the original pointer can be in memory that is too high so we
+ * need to do it locally */
+ buffer = rtas_remote_addr(ra->ra_args[1], length);
+ if (buffer == NULL) {
+ ra->ra_args[ra->ra_nargs] = RTAS_PARAMETER;
+ return -1;
+ }
+
+ local = xmalloc_bytes(length);
+ if (local == NULL) {
+ printk("%s: could not allocate local buffer size: 0x%lx\n",
+ __func__, length);
+ ra->ra_args[ra->ra_nargs] = RTAS_HW;
+ return -1;
+ }
+ /* RTAS is 32bits so we need to make sure that that local
+ * buffer is in that range */
+ BUG_ON(((ulong)local + length) & ~0xffffffffUL);
+
+ /* copy the remote buffer to the local one */
+ memcpy(local, buffer, length);
+
+ memcpy(&r, ra, sz);
+ r.ra_token = token;
+ r.ra_args[1] = (unsigned)(ulong)local;
+
+ ret = rtas_call(&r);
+ ra->ra_args[ra->ra_nargs] = r.ra_args[r.ra_nargs];
+ ra->ra_args[ra->ra_nargs + 1] = r.ra_args[r.ra_nargs + 1];
+ xfree(local);
+ return ret;
+}
+
+struct rtas_token rt_nvram_store = {
+ .name = "nvram-store",
+ .proxy = rtas_nvram_store,
+ .token = -1
+};
+
+static int rtas_nvram_fetch(int token, struct rtas_args *ra)
+{
+ ulong length = ra->ra_args[2];
+ char *buffer;
+ char *local;
+ struct rtas_args r;
+ ulong sz = (3 + ra->ra_nargs + ra->ra_nrets) * sizeof (int);
+ int ret;
+
+ if (ra->ra_nargs != 3 || ra->ra_nrets != 2) {
+ ra->ra_args[ra->ra_nargs] = RTAS_PARAMETER;
+ return -1;
+ }
+ /* the original pointer can be in ememory that is too high so
+ * we need to do it locally */
+ buffer = rtas_remote_addr(ra->ra_args[1], length);
+
+ local = xmalloc_bytes(length);
+ if (local == NULL) {
+ printk("%s: could not allocate local buffer size: 0x%lx\n",
+ __func__, length);
+ ra->ra_args[ra->ra_nargs] = RTAS_HW;
+ return -1;
+ }
+ /* RTAS is 32bits so we need to make sure that that local
+ * buffer is in that range */
+ BUG_ON(((ulong)local + length) & ~0xffffffffUL);
+
+ memcpy(&r, ra, sz);
+ r.ra_token = token;
+ r.ra_args[1] = (unsigned)(ulong)local;
+
+ ret = rtas_call(&r);
+ ra->ra_args[ra->ra_nargs] = r.ra_args[r.ra_nargs];
+ ra->ra_args[ra->ra_nargs + 1] = r.ra_args[r.ra_nargs + 1];
+ if (r.ra_args[r.ra_nargs] >= 0) {
+ /* copy from local to remote */
+ sz = r.ra_args[r.ra_nargs + 1];
+ memcpy(buffer, local, sz);
+ }
+ xfree(local);
+ return ret;
+}
+
+struct rtas_token rt_nvram_fetch = {
+ .name = "nvram-fetch",
+ .proxy = rtas_nvram_fetch,
+ .token = -1
+};
+
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|