[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[XenPPC] [pushed] [ppc] OFH: Autodetect PAPR, Dom0 and DomU console.



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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.