changeset: 9750:e0afa5ac4a4f6e33e18a19227ae4bff6a2a29248
tag: tip
user: jimix@xxxxxxxxxxxxxxxxxxxxx
date: Mon Apr 3 13:30:03 2006 -0400
files: xen/arch/ppc/of_handler/console.c xen/arch/ppc/of_handler/head.S
xen/arch/ppc/of_handler/io.c xen/arch/ppc/of_handler/leap.S
xen/arch/ppc/of_handler/ofh.h xen/arch/ppc/of_handler/vdevice.c
description:
[ppc] OFH: Autodetect PAPR, Dom0 and DomU console.
This patch will make the Open Firmware Handler the ability to select the
console type to use.
diff -r 03bdfff6f4d3fdefd879c5058a727e6c1f54f40f -r
e0afa5ac4a4f6e33e18a19227ae4bff6a2a29248 xen/arch/ppc/of_handler/console.c
--- a/xen/arch/ppc/of_handler/console.c Mon Apr 3 13:28:06 2006 -0400
+++ b/xen/arch/ppc/of_handler/console.c Mon Apr 3 13:30:03 2006 -0400
@@ -26,35 +26,30 @@ union chpack {
char c[16];
};
-static u32 ofh_cchan;
+/* used for internal printing */
+static struct ofh_ihandle *ofh_ihp;
-static u32 ofh_papr_read(void *buf, u32 count)
+static s32 ofh_papr_read(s32 chan, void *buf, u32 count, s32 *actual)
{
s32 rc;
ulong ret[5];
ulong sz = 0;
- /* FIXME: We need to relocate ofh_cchan, but against what? */
- /* This is called via leap, but leap has not way of passing */
- /* the base value through to let us do the relocation. */
- rc = papr_get_term_char(ret, ofh_cchan);
+ rc = papr_get_term_char(ret, chan);
if (rc == H_Success && ret[0] > 0) {
sz = MIN(count, ret[0]);
memcpy(buf, &ret[1], sz);
}
- return sz;
+ *actual = sz;
+ return OF_SUCCESS;
}
-static s32 ofh_papr_write(const void *buf, u32 count)
+static s32 ofh_papr_write(s32 chan, const void *buf, u32 count, s32 *actual)
{
const char *str = (const char *)buf;
u32 i;
union chpack ch;
s32 ret;
-
- /* FIXME: We need to relocate ofh_ccchan, but against what? */
- /* This is called via leap, but leap has not way of passing */
- /* the base value through to let us do the relocation. */
for (i = 0; i < count; i++) {
int m = i % sizeof(ch);
@@ -63,13 +58,13 @@ static s32 ofh_papr_write(const void *bu
for (;;) {
if (sizeof (ulong) == sizeof (u64)) {
ret = papr_put_term_char(NULL,
- ofh_cchan,
+ chan,
m + 1,
ch.oct[0],
ch.oct[1]);
} else {
ret = papr_put_term_char(NULL,
- ofh_cchan,
+ chan,
m + 1,
ch.quad[0],
ch.quad[1],
@@ -86,7 +81,11 @@ static s32 ofh_papr_write(const void *bu
}
}
}
- return count;
+ *actual = count;
+ if (*actual == -1) {
+ return OF_FAILURE;
+ }
+ return OF_SUCCESS;
}
#define __HYPERVISOR_console_io 18
@@ -96,7 +95,7 @@ extern long xen_hvcall(ulong code, ...);
extern long xen_hvcall(ulong code, ...);
#define XENCOMM_MINI_AREA (sizeof(struct xencomm_mini) * 2)
-static s32 ofh_xen_dom0_read(void *buf, u32 count)
+static s32 ofh_xen_dom0_read(s32 chan, void *buf, u32 count, s32 *actual)
{
char __storage[XENCOMM_MINI_AREA];
struct xencomm_desc *desc;
@@ -117,10 +116,11 @@ static s32 ofh_xen_dom0_read(void *buf,
s += rc;
ret += rc;
}
- return ret;
+ *actual = ret;
+ return OF_SUCCESS;
}
-static s32 ofh_xen_dom0_write(const void *buf, u32 count)
+static s32 ofh_xen_dom0_write(s32 chan, const void *buf, u32 count, s32
*actual)
{
char __storage[XENCOMM_MINI_AREA];
struct xencomm_desc *desc;
@@ -141,44 +141,44 @@ static s32 ofh_xen_dom0_write(const void
s += rc;
ret += rc;
}
- return ret;
-}
-
-s32
-ofh_cons_read(void *buf, u32 count, s32 *actual)
-{
- /* yes we could use a pointer, but we'd have to do some majik and
- * still be relocatable, its just not worth it */
- if (0) {
- *actual = ofh_papr_read(buf, count);
- } else {
- *actual = ofh_xen_dom0_read(buf, count);
- }
- return OF_SUCCESS;
-}
-
-s32
-ofh_cons_write(const void *buf, u32 count, s32 *actual)
-{
- if (0) {
- *actual = ofh_papr_write(buf, count);
- } else {
- *actual = ofh_xen_dom0_write(buf, count);
- }
+ *actual = ret;
if (*actual == -1) {
return OF_FAILURE;
}
return OF_SUCCESS;
}
-s32
-ofh_cons_close(void)
+/* for emergency printing in the OFH */
+s32 ofh_cons_write(const void *buf, u32 count, s32 *actual)
+{
+ ulong b = get_base();
+ struct ofh_ihandle *ihp = DRELA(ofh_ihp, b);
+
+ return ihp->ofi_write(ihp->ofi_chan, buf, count, actual);
+}
+
+s32 ofh_cons_close(void)
{
return OF_SUCCESS;
}
void
-ofh_cons_init(u32 chan, ulong b)
+ofh_cons_init(s32 chan, struct ofh_ihandle *ihp, ulong b)
{
- *DRELA(&ofh_cchan, b) = chan;
+ switch (chan) {
+ case OFH_CONS_XEN_DOM0:
+ ihp->ofi_write = ofh_xen_dom0_write;
+ ihp->ofi_read = ofh_xen_dom0_read;
+ break;
+ case OFH_CONS_XEN_DOMU:
+ ihp->ofi_write = ofh_xen_dom0_write;
+ ihp->ofi_read = ofh_xen_dom0_read;
+ break;
+ default:
+ ihp->ofi_write = ofh_papr_write;
+ ihp->ofi_read = ofh_papr_read;
+ break;
+ }
+ ihp->ofi_chan = chan;
+ *DRELA(&ofh_ihp, b) = ihp;
}
diff -r 03bdfff6f4d3fdefd879c5058a727e6c1f54f40f -r
e0afa5ac4a4f6e33e18a19227ae4bff6a2a29248 xen/arch/ppc/of_handler/head.S
--- a/xen/arch/ppc/of_handler/head.S Mon Apr 3 13:28:06 2006 -0400
+++ b/xen/arch/ppc/of_handler/head.S Mon Apr 3 13:30:03 2006 -0400
@@ -141,3 +141,12 @@ _ofh_cih_orig_msr:
mtsrr1 r8
mtlr r0
blr
+
+_GLOBAL(get_base)
+ mflr r0
+ bl 1f
+1: mflr r5
+ LOADADDR(r4,1b)
+ subf r3,r4,r5
+ mtlr r0
+ blr
diff -r 03bdfff6f4d3fdefd879c5058a727e6c1f54f40f -r
e0afa5ac4a4f6e33e18a19227ae4bff6a2a29248 xen/arch/ppc/of_handler/io.c
--- a/xen/arch/ppc/of_handler/io.c Mon Apr 3 13:28:06 2006 -0400
+++ b/xen/arch/ppc/of_handler/io.c Mon Apr 3 13:30:03 2006 -0400
@@ -70,13 +70,13 @@ ofh_read(u32 nargs, u32 nrets, s32 argp[
(struct ofh_ihandle *)(ulong)argp[0];
if (ih->ofi_read != NULL) {
- u32 addr = argp[1];
+ void *addr = (void *)(ulong)argp[1];
u32 sz = argp[2];
u32 *actual = &retp[0];
void *f = ih->ofi_read;
if (f != 0) {
- return leap(addr, sz, actual, NULL,
+ return io_leap(ih->ofi_chan, addr, sz, actual,
b, f);
}
}
@@ -94,13 +94,13 @@ ofh_write(u32 nargs, u32 nrets, s32 argp
(struct ofh_ihandle *)(ulong)argp[0];
if (ih->ofi_write != NULL) {
- u32 addr = argp[1];
+ void *addr = (void *)(ulong)argp[1];
u32 sz = argp[2];
u32 *actual = &retp[0];
void *f = ih->ofi_write;
if (f != 0) {
- return leap(addr, sz, actual, NULL,
+ return io_leap(ih->ofi_chan, addr, sz, actual,
b, f);
}
}
diff -r 03bdfff6f4d3fdefd879c5058a727e6c1f54f40f -r
e0afa5ac4a4f6e33e18a19227ae4bff6a2a29248 xen/arch/ppc/of_handler/leap.S
--- a/xen/arch/ppc/of_handler/leap.S Mon Apr 3 13:28:06 2006 -0400
+++ b/xen/arch/ppc/of_handler/leap.S Mon Apr 3 13:30:03 2006 -0400
@@ -27,7 +27,7 @@
*/
-
+_GLOBAL(io_leap)
_GLOBAL(leap)
## r8 contains the base address for everyone
add r8,r8,r7 # add
diff -r 03bdfff6f4d3fdefd879c5058a727e6c1f54f40f -r
e0afa5ac4a4f6e33e18a19227ae4bff6a2a29248 xen/arch/ppc/of_handler/ofh.h
--- a/xen/arch/ppc/of_handler/ofh.h Mon Apr 3 13:28:06 2006 -0400
+++ b/xen/arch/ppc/of_handler/ofh.h Mon Apr 3 13:30:03 2006 -0400
@@ -91,11 +91,12 @@ struct ofh_methods {
struct ofh_ihandle {
s32 (*ofi_close)(void);
- s32 (*ofi_read)(void *buf, u32 count, s32 *actual);
- s32 (*ofi_write)(const void *buf, u32 count, s32 *actual);
+ s32 (*ofi_read)(s32 chan, void *buf, u32 count, s32 *actual);
+ s32 (*ofi_write)(s32 chan, const void *buf, u32 count, s32 *actual);
s32 (*ofi_seek)(u32 pos_hi, u32 pos_lo, u32 *status);
struct ofh_methods *ofi_methods;
s32 ofi_node;
+ s32 ofi_chan;
};
struct ofh_imem {
@@ -115,12 +116,17 @@ extern s32 ofh_start(struct ofh_args *);
extern s32 ofh_start(struct ofh_args *);
extern void _start(void);
-extern void ofh_cons_init(u32 chan, ulong b);
-extern s32 ofh_cons_read(void *buf, u32 count, s32 *actual);
+#define OFH_CONS_XEN_DOM0 -1
+#define OFH_CONS_XEN_DOMU -2
+extern void ofh_cons_init(s32 chan, struct ofh_ihandle *ihp, ulong b);
+extern s32 ofh_cons_read(s32 chan, void *buf, u32 count, s32 *actual);
extern s32 ofh_cons_write(const void *buf, u32 count, s32 *actual);
extern s32 ofh_cons_close(void);
extern s32 ofh_handler(struct ofh_args *args, ulong ifh_base);
extern s32 leap(u32 nargs, u32 nrets, u32 args[], u32 rets[],
+ ulong ba, void *f);
+
+extern s32 io_leap(s32 chan, void *buf, u32 sz, u32 *actual,
ulong ba, void *f);
extern void ofh_vty_init(ofdn_t chosen, ulong b);
@@ -133,6 +139,7 @@ extern void *_ofh_tree;
#else
#define DRELA(p,b) (b == b ? p : 0)
#endif
+extern ulong get_base(void);
static inline void *ofd_mem(ulong base) { return *DRELA(&_ofh_tree, base); }
diff -r 03bdfff6f4d3fdefd879c5058a727e6c1f54f40f -r
e0afa5ac4a4f6e33e18a19227ae4bff6a2a29248 xen/arch/ppc/of_handler/vdevice.c
--- a/xen/arch/ppc/of_handler/vdevice.c Mon Apr 3 13:28:06 2006 -0400
+++ b/xen/arch/ppc/of_handler/vdevice.c Mon Apr 3 13:30:03 2006 -0400
@@ -18,41 +18,47 @@
#include "ofh.h"
-static struct ofh_ihandle _ih_vty_0 = {
- .ofi_read = ofh_cons_read,
- .ofi_write = ofh_cons_write,
-};
+static struct ofh_ihandle _ih_cons;
void
ofh_vty_init(ofdn_t chosen, ulong b)
{
void *mem = ofd_mem(b);
- u32 ih = DRELA((u32)&_ih_vty_0, b);
+ u32 ih = DRELA((u32)&_ih_cons, b);
+ struct ofh_ihandle *ihp = (struct ofh_ihandle *)((ulong)ih);
+ ofdn_t n;
+ s32 ret;
+ u32 chan = 0;
-#ifdef VTY
- struct ofh_ihandle *ihp = (struct ofh_ihandle *)((ulong)ih);
- ofdn_t vty;
- s32 ret;
- u32 chan;
+ /* find the vty */
+ n = ofd_node_find(mem,
+ DRELA((const char *)"/vdevice/vty", b));
+ if (n > 0) {
+ /* PAPR VTERM */
- /* fixup the ihandle */
- vty = ofd_node_find(mem,
- DRELA((const char *)"/vdevice/vty", b));
- if (vty <= 0) {
- return -1;
+ ihp->ofi_node = n;
+
+ ret = ofd_getprop(mem, n, DRELA((const char *)"reg", b),
+ &chan, sizeof (chan));
+ if (ret != (s32)sizeof (chan)) {
+ chan = 0;
+ }
+ } else {
+ /* xen console */
+ s32 domain;
+
+ n = ofd_node_find(mem, DRELA((const char *)"/xen", b));
+ if (n > 0) {
+ ret = ofd_getprop(mem, n, DRELA((const char *)"reg", b),
+ &domain, sizeof (domain));
+ if (domain == 0) {
+ chan = OFH_CONS_XEN_DOM0;
+ } else {
+ chan = OFH_CONS_XEN_DOMU;
+ }
+ }
}
- ihp->ofi_node = vty;
-
- ret = ofd_getprop(mem, vty, DRELA((const char *)"reg", b),
- &chan, sizeof (chan));
- if (ret != (s32)sizeof (chan)) {
- chan = 0;
- }
- ofh_cons_init(chan, b);
-#else
- ofh_cons_init(0, b);
-#endif
-
+ ofh_cons_init(chan, ihp, b);
ofd_prop_add(mem, chosen, DRELA((const char *)"stdout", b),
&ih, sizeof (ih));
ofd_prop_add(mem, chosen, DRELA((const char *)"stdin", b),
_______________________________________________
Xen-ppc-devel mailing list
Xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ppc-devel
|