[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |