WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-ppc-devel

[XenPPC] [PATCH rfc] serial device detection, nohv mode detection, early

To: xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
Subject: [XenPPC] [PATCH rfc] serial device detection, nohv mode detection, early zilog device driver
From: Maria Butrico <butrico@xxxxxxxxxxxxxx>
Date: Thu, 04 May 2006 13:26:34 -0400
Delivery-date: Thu, 04 May 2006 11:32:46 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-ppc-devel-request@lists.xensource.com?subject=help>
List-id: Xen PPC development <xen-ppc-devel.lists.xensource.com>
List-post: <mailto:xen-ppc-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-ppc-devel>, <mailto:xen-ppc-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-ppc-devel>, <mailto:xen-ppc-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-ppc-devel-bounces@xxxxxxxxxxxxxxxxxxx
Signed-off-by: Maria Butrico <butrico@xxxxxxxxxxxxxx>

summary:     RFC: serial device detection, nohv mode detection, early zilog 
device driver

        The device driver was patched from rhype, linux and the ns 
        device code.  This patch cannot be applied to tip.  Code
        execution stops, on a g5, in the vicinity of mpic.


diff -r 56e1802303e5 xen/arch/ppc/boot_of.c
--- a/xen/arch/ppc/boot_of.c    Wed Apr 12 15:41:55 2006 -0500
+++ b/xen/arch/ppc/boot_of.c    Thu May  4 13:19:28 2006 -0400
@@ -24,6 +24,11 @@
 #include <xen/compile.h>
 #include <public/of-devtree.h>
 #include <asm/page.h>
+#include <xen/string.h>
+#include <xen/serial.h>
+#include "platform.h"
+
+struct global_hardware_stuff global_hs;
 
 static ulong of_vec;
 static ulong of_msr;
@@ -32,8 +37,6 @@ static char bootargs[256];
 static char bootargs[256];
 static char dom0args[256];
 
-extern unsigned int timebase_freq;
-
 #undef OF_DEBUG
 
 #ifdef OF_DEBUG
@@ -44,6 +47,11 @@ extern unsigned int timebase_freq;
 
 #define of_panic(MSG...) \
     do { of_printf(MSG); of_printf("\nHANG\n"); for (;;); } while (0)
+
+#define _IF_OF_FAILURE_RET(rc)             \
+        if (unlikely((rc)==OF_FAILURE))  { \
+            return OF_FAILURE;             \
+        }
 
 struct of_service {
     u32 ofs_service;
@@ -104,9 +112,9 @@ static int __init of_write(int ih, const
     return rets[0];
 }
 
-static int of_printf(const char *fmt, ...)
+int of_printf(const char *fmt, ...)     // Maria was static
     __attribute__ ((format (printf, 1, 2)));
-static int __init of_printf(const char *fmt, ...)
+int __init of_printf(const char *fmt, ...)  // Maria was static
 {
     static char buf[1024];
     va_list args;
@@ -152,6 +160,7 @@ static int __init of_getprop(int ph, con
 
     if (rets[0] == OF_FAILURE) {
         DBG("getprop 0x%x %s -> FAILURE\n", ph, name);
+        if (buflen > 0) memset(buf, 0, 1);
         return OF_FAILURE;
     }
 
@@ -301,6 +310,7 @@ static int __init of_instance_to_package
 
     return rets[0];
 }
+#endif
 
 static int __init of_getparent(int ph)
 {
@@ -311,8 +321,6 @@ static int __init of_getparent(int ph)
     DBG("getparent 0x%x -> 0x%x\n", ph, rets[0]);
     return rets[0];
 }
-
-#endif
 
 extern char _start[];
 extern char _end[];
@@ -331,7 +339,6 @@ static void boot_of_probemem(multiboot_i
     root = of_finddevice("/");
     p = of_getchild(root);
 
-    /* code is writen to assume sizes of 1 */
     of_getprop(root, "#address-cells", &addr_cells, sizeof (addr_cells));
     of_getprop(root, "#size-cells", &size_cells, sizeof (size_cells));
     DBG("%s: address_cells=%d  size_cells=%d\n",
@@ -786,12 +793,303 @@ static void boot_of_module(ulong r3, ulo
 }
 
 
-int __init boot_of_serial(void)
-{
-    /* right now we are punting and using mambo writes which is the
-     * hardcoded setup */
-
-    return 1;
+static void search_by_property_value(int p, const char *prop_name,
+                const char *prop_value)
+{
+    int pnext;          /* of handdle */
+
+    do {
+        // does this package have the property 'prop_name' with 
+        // value "prop_value"?
+        char of_property[256];
+        of_property[0] = '\0';
+        of_getprop(p, prop_name, of_property, sizeof (of_property));
+        if (strncmp(of_property, prop_value, sizeof (prop_value)) == 0) {
+            char path[256];
+            int sz = of_package_to_path(p, path, sizeof(path));
+            of_printf("\npackage with property '%s' with value '%s' found. "
+                            "path is %s (size %d)\n", prop_name, prop_value,
+                            path, sz);
+#ifdef OF_DEBUG
+            // Print all its properties
+            char name[128];
+            int result = of_nextprop(p, 0, name);       /* first prop. */
+            while (result > 0) {
+                int sz;
+                u64 obj[1024];
+                sz = of_getproplen(p, name);
+                if (sz > 0) {
+                    int actual = of_getprop(p, name, obj, sz);
+                    of_printf("device property *%s* size %d value %s  ",
+                                        name, actual, (char*)obj);
+                    int i;
+                    for (i=0; i<=(actual/sizeof(obj[0])); i++)
+                                of_printf("0x%016lx ", obj[i]);
+                    of_printf("\n");
+                } else if (0 == sz) {
+                        of_printf("device property *%s* size 0\n",
+                                        name);
+                }
+
+                result = of_nextprop(p, name, name);
+            }
+#endif
+        }
+
+        /* do children first */
+        pnext = of_getchild(p);
+        if (pnext != 0) {
+            search_by_property_value(pnext, prop_name, prop_value);
+        }
+
+        p = of_getpeer(p);
+    } while (p != OF_FAILURE && p != 0);
+}
+
+
+struct uart uarts[] = {
+    { .type = ns16550, .p_sign = "escc", .gp_sign = "mac-io",
+              .uart_init_func = ns16550_init },
+    { .type = pmac_zilog,   
+              .uart_init_func = pmac_zilog_init },
+};
+
+/*
+ * Returns the value of the property '/#size-cells'
+ */
+int __init boot_of_get_sizecells_prop()
+{
+    int of_root;
+    u32 cell = 1;
+    
+    of_root = of_finddevice("/");
+    if (of_root == OF_FAILURE) of_panic("no root package\n");
+
+    of_getprop(of_root, "#size-cells", &cell, sizeof(cell));
+    return cell;
+}
+
+/*
+ * return 0 is a serial port that makes sense for the platform is found.
+ * OF_FAILURE if no serial port can be found
+ */
+int __init boot_of_serial()
+{
+    int p, ofout;      /* of handle */
+    int rc;
+    char of_property[256];
+    char ofout_path[256] = {0,};
+    const char serial[] = "serial";
+    const char macio[] = "mac-io";
+    const char escc[] = "escc";
+
+    #ifdef OF_DEBUG
+    {
+    p = of_finddevice("/");
+    const char device_type[] = "device_type";
+    search_by_property_value(p, device_type, serial);
+    }
+    #endif
+
+    /* copied and adapted from rhype */
+    ofout_path[0] = '\0';
+    ofout = OF_FAILURE;
+
+    /* probe /options tree */
+    rc = p = of_finddevice("/options");
+    if (p != OF_FAILURE) {
+        rc = of_getprop(p, "output-device", ofout_path, sizeof(ofout_path));
+    } 
+    if (OF_FAILURE == rc) {
+        strncpy(ofout_path, serial, sizeof(serial));
+    }
+
+    /*
+     * if the options are not a path (they do not start with '/')
+     * then they are aliases and we must look them up.  we look it
+     * up in aliases because it is possible that the OF does not
+     * support finddevice() of an alias.
+     */
+    if (ofout_path[0] != '/') {
+        p = of_finddevice("/aliases");
+        if (p != OF_FAILURE) {
+            char alias[256];
+            memcpy(alias, ofout_path, sizeof(alias));
+            rc = of_getprop(p, alias, ofout_path, sizeof (ofout_path));
+        }
+    }
+
+    if (OF_FAILURE != rc) {
+        ofout = of_finddevice(ofout_path);
+    } else {
+        s32 iout;       /* ihandle ?? */
+        /*
+         * Our last chance is to figure out the package for
+         * the current console and hopefully discover it to be
+         * a serial device.
+         */
+        p = of_finddevice("/chosen");
+        if (p != OF_FAILURE) {
+            rc = of_getprop(p, "stdout", &iout, sizeof(iout));
+        }
+        if (rc != OF_FAILURE) {
+            rc = of_instance_to_path(iout, ofout_path, sizeof(ofout_path));
+            if (rc != OF_FAILURE) 
+                ofout = of_finddevice(ofout_path);
+        }
+    }
+
+    DBG("serial port OF handle=0x%x\n", ofout);
+
+    if (OF_FAILURE == ofout) {
+        /* can try the rtas device.  Code not written yet */
+        of_printf("Could not find any serial device\n");
+        return OF_FAILURE;
+    }
+
+
+    /* Now we have the OF handle of the serial device.  Let's find out
+     * what it is and its address.
+     *
+     * The device must have of type 'serial'
+     *
+     * If the grandparent directory has the name 'mac-io', then this must
+     * be a power mac.  The serial device is a zilog.
+     *
+     * Otherwise (we are assuming that) the grandparent has the name
+     * 'pci' and the parent 'isa'.  The serial device is a NS16550.
+     *
+     * And what about the ns16750?
+     * 
+     */
+    rc = of_getprop(ofout, "device_type", of_property, sizeof(of_property));
+
+    union of_pci_hi {
+       u32 word;
+       struct {
+           u32  opa_n: 1; /* relocatable */
+           u32  opa_p: 1; /* prefetchable */
+           u32  opa_t: 1; /* aliased */
+           u32  _opa_res: 3;
+           u32  opa_s: 2; /* space code */
+           u32  opa_b: 8; /* bus number */
+           u32  opa_d: 5; /* device number */
+           u32  opa_f: 3; /* function number */
+           u32  opa_r: 8; /* register number */
+       } bits;
+    };
+    struct of_pci_addr_s {
+        union of_pci_hi opa_hi;
+        u32 opa_mid;
+        u32 opa_lo;
+    };
+
+    if (strncmp(of_property, serial, sizeof(serial))) {
+        of_printf("Serial device is not serial\n");
+        return OF_FAILURE;
+    }
+
+    int parent, grandparent;        /* of handles */
+    parent = of_getparent(ofout);
+    _IF_OF_FAILURE_RET(parent);
+    grandparent = of_getparent(parent);
+    _IF_OF_FAILURE_RET(grandparent);
+
+    of_getprop(grandparent, "name", of_property, sizeof(of_property));
+    if (0 == strncmp(of_property, macio, sizeof(macio))) {
+        struct reg_property32 {
+            u32 address;
+            u32 size;
+        } reg;
+        struct of_pci_range32_s {
+            struct of_pci_addr_s opr_addr;
+            u32 opr_phys;
+            u32 opr_size;
+        } r32;
+
+        of_getprop(parent, "device_type", of_property, sizeof(of_property));
+        if (strncmp(of_property, escc, sizeof(escc))) {
+            of_printf("Serial device parent's type is not escc\n");
+            return OF_FAILURE;
+        }
+
+        if (global_hs.platform_type != pmac) {
+           of_printf("WARNING: serial device found in path mac-io"
+                     "but we don't think this is a power mac\n");
+           return OF_FAILURE;
+        }
+
+        global_hs.uart_type = pmac_zilog;
+
+        of_getprop(grandparent , "ranges", &r32, sizeof(r32));
+        of_getprop(ofout, "reg", &reg, sizeof(reg));
+
+        of_printf("reg property address=0x%08x  size=0x%08x\n",
+                        reg.address, reg.size);
+        of_printf("ranges property %x:%x:%x %x %x\n",
+                            r32.opr_addr.opa_hi.word,
+                            r32.opr_addr.opa_mid,
+                            r32.opr_addr.opa_lo,
+                            r32.opr_phys, r32.opr_size);
+
+        global_hs.serial_port.uart_io_base = reg.address;
+        global_hs.serial_port.isa_io_base = r32.opr_phys;
+    } else {
+        /* grandparent directory is not 'mac-io'.  We are assuming 'pci/isa' */
+        struct isa_reg_property {
+            u32 space;
+            u32 address;
+            u32 size;
+        } isa_reg;
+        struct of_pci_range64_s {
+            struct of_pci_addr_s opr_addr;
+            u32 opr_phys_hi;
+            u32 opr_phys_lo;
+            u32 opr_size_hi;
+            u32 opr_size_lo;
+        } r64;
+        u32 clock;
+
+        global_hs.uart_type = ns16550;
+
+        of_getprop(grandparent , "ranges", &r64, sizeof(r64));
+        of_getprop(ofout, "clock-frequency", &clock, sizeof (clock));
+        of_getprop(ofout, "reg", &isa_reg, sizeof(isa_reg));
+
+        of_printf("reg property address=0x%08x  size=0x%08x\n",
+                        isa_reg.address, isa_reg.size);
+        of_printf("ranges property %x:%x:%x %x:%x %x:%x\n",
+                     r64.opr_addr.opa_hi.word,
+                     r64.opr_addr.opa_mid,
+                     r64.opr_addr.opa_lo,
+                     r64.opr_phys_hi,
+                     r64.opr_phys_lo,
+                     r64.opr_size_hi, r64.opr_size_lo);
+
+        global_hs.serial_port.uart_io_base = isa_reg.address;
+        global_hs.serial_port.isa_io_base = 
+               (((u64)r64.opr_phys_hi) << 32) | r64.opr_phys_lo;
+        global_hs.serial_port.clock = clock;
+    }
+
+    int i, s;
+    s = sizeof(uarts) / sizeof (struct uart);
+    for (i = 0; i < s; i++ ) {
+        if (uarts[i].type == global_hs.uart_type) {
+            global_hs.serial_port.uart_p = &(uarts[i]);
+        }
+    }
+
+    /* io_addr = isa_io_base + uart_io_base; */
+    of_printf("%s: serial type=%d  io base=0x%016lx  isa io@=0x%016lx  "
+              "clock=%d\n",
+              __func__, global_hs.uart_type,
+              global_hs.serial_port.uart_io_base,
+              global_hs.serial_port.isa_io_base,
+              global_hs.serial_port.clock
+              );
+
+    return 0;
 }
 
 int __init boot_of_cpus(void)
@@ -825,6 +1123,157 @@ int __init boot_of_rtas(void)
     return 1;
 }
 
+/*
+ * Returns the length of the OF compatible property; OF_FAILURE on error
+ * The value of the property itself is returned in the first parameter.
+ */
+int __init boot_of_get_compatible_prop(char *cstring, int cstring_size)
+{
+    int of_root;
+    int comp_length;
+    
+    of_root = of_finddevice("/");
+    if (of_root == OF_FAILURE) of_panic("no root package\n");
+
+    comp_length = of_getprop(of_root, "compatible", cstring, cstring_size);
+    #if 0
+    if (comp_length != OF_FAILURE) {
+        // null separated string yuck
+        int used_length;
+        of_printf("%s :\n", __func__);
+        for (used_length = 0; used_length < comp_length; used_length++) {
+            if (cstring[used_length] == '\0' ) {
+                of_printf("   NULL\n");
+            } else {
+                of_printf("%c", cstring[used_length]);
+            }
+        }
+    } 
+    #endif
+
+    return comp_length;
+}
+
+int pmac_init() {
+    /*
+     * Power Macintosh' do not distinguish between supervisor and
+     * hypervisor mode.  Hence, we run, if at all, with in a special
+     * mode called non-hypervisor hypervisor. (nohv)
+     */
+    of_printf("Non hypervisor hardware found.\n");
+    global_hs.hv_supported = 0;
+    return 0;
+}
+
+int maple_init() {
+    global_hs.hv_supported = 1;
+    return 0;
+}
+
+struct platform platforms[] = {
+    { .type = pmac,  .compat_s = "Power Macintosh", .init_func = pmac_init },
+    { .type = maple, .compat_s = "Momentum,Maple",  .init_func = maple_init },
+};
+
+/*
+ * Does the compatible of property indicate that the platform is a Power
+ * Macintosh, or a maple (hardware or simulated), or ..
+ * return 0 if not an known value;
+ */
+int __init boot_of_platform(char * compatible_p, int c_length)
+{
+
+    char *cmpstr;
+    int used_length;
+
+    // loop over each null terminated piece of the compatible property
+    for (cmpstr = compatible_p, used_length = 0; used_length < c_length;
+         cmpstr = &compatible_p[used_length]) {
+        int i, s;
+        s = sizeof(platforms) / sizeof(struct platform);
+        for (i = 0; i < s; i++) {
+            if (strstr(cmpstr, platforms[i].compat_s)) {
+                global_hs.platform_type = platforms[i].type;
+                return platforms[i].init_func();
+            }
+        }
+        used_length += strlen(cmpstr) + 1;
+    }
+
+    of_printf("Warning: boot_of::%s is not aware of this machine type.  "
+              "Compatible is:\n", __func__);
+    {
+    int used_length;
+    for (used_length = 0; used_length < c_length; used_length++) {
+        if (compatible_p[used_length] == '\0' ) {
+            of_printf(" NULL ");
+        } else {
+            of_printf("%c", compatible_p[used_length]);
+        }
+    }
+    }
+    of_printf("\n");
+    return OF_FAILURE;
+}
+
+void __init boot_of_hardware_specific() 
+{
+    int rc;
+    char compatible_string[256];
+    int compatible_length;
+
+    memset(&global_hs, 0, sizeof(global_hs));
+
+    compatible_length = boot_of_get_compatible_prop(compatible_string,
+                                               sizeof(compatible_string));
+
+    if (compatible_length != OF_FAILURE) {
+        rc = boot_of_platform(compatible_string, compatible_length);
+#if 0
+        cell = boot_of_get_sizecells_prop();
+        switch (rc) {
+        default:
+            of_printf("Warning: %s is not aware of this machine type %d\n",
+                            __func__, rc);
+            break;
+                
+        case 0:
+            // did not learn anything
+            break;
+
+        case PMAC_HARDWARE:
+            global_hs.platform_type = rc;
+            if (cell != 1) of_panic("powermac with cell %d\n", cell);
+
+            /*
+             * Power Macintosh' do not distinguish between supervisor and
+             * hypervisor mode.  Hence, we run, if at all, with in a special
+             * mode called non-hypervisor hypervisor. (nohv)
+             */
+            of_printf("Non hypervisor hardware found.\n");
+            global_hs.hv_supported = 0;
+            opt_nohv = 1;
+            break;
+
+        case MAPLE_GENERIC:
+            global_hs.platform_type = rc;
+            if (cell != 2) of_panic("maple like thing with cell %d\n", cell);
+            global_hs.hv_supported = 1;
+            break;
+        }
+#endif
+    }
+
+    of_printf("%s: platform type=%d  uart type=%d  hv=%d\n", __func__,
+                    global_hs.platform_type,
+                    global_hs.uart_type,
+                    global_hs.hv_supported);
+
+    boot_of_serial();
+    boot_of_rtas();
+}
+
+
 multiboot_info_t __init *boot_of_init(
         ulong r3, ulong r4, ulong vec, ulong r6, ulong r7, ulong orig_msr)
 {
@@ -858,13 +1307,20 @@ multiboot_info_t __init *boot_of_init(
     boot_of_probemem(&mbi);
     boot_of_bootargs(&mbi);
     boot_of_module(r3, r4, &mbi);
-    boot_of_serial();
     boot_of_cpus();
-    boot_of_rtas();
+
+    /* Note: serial and rtas were before cpus, but should really happen after 
hardware
+     * specific, since we want to use the machine type as a hint of where/what
+     * the serial device might be
+     *
+     * If serial initalization needs to be before cpus, then we need to move up
+     * hardware specific as well.
+     */
+    boot_of_hardware_specific();
 
     /* end of OF */
-    of_printf("closing OF stdout...\n");
-    of_call("close", 1, 0, &of_out);
+    //of_printf("closing OF stdout...\n");  Maria
+    //of_call("close", 1, 0, &of_out);  Maria
 
     of_getprop(bof_chosen, "stdin", &of_in, sizeof (of_in));
 
@@ -872,7 +1328,7 @@ multiboot_info_t __init *boot_of_init(
         of_call("close", 1, 0, &of_in);
     }
 
-    of_call("quiesce", 0, 0, NULL);
+    //of_call("quiesce", 0, 0, NULL);  Maria
 
     return &mbi;
 }
diff -r 56e1802303e5 xen/arch/ppc/setup.c
--- a/xen/arch/ppc/setup.c      Wed Apr 12 15:41:55 2006 -0500
+++ b/xen/arch/ppc/setup.c      Thu May  4 13:19:28 2006 -0400
@@ -36,12 +36,21 @@
 #include <asm/cache.h>
 #include <asm/debugger.h>
 #include <asm/delay.h>
+#include "platform.h"
 
 unsigned long xenheap_phys_end;
 
 /* opt_noht: If true, Hyperthreading is ignored. */
 int opt_noht = 0;
 boolean_param("noht", opt_noht);
+
+extern struct global_hardware_stuff global_hs;
+
+/* opt_nohv: If true, hardware has no hypervisor (HV) mode or nohv boot 
+ * parameter was specified. 
+ */
+int opt_nohv = 0;
+boolean_param("nohv", opt_nohv);
 
 int opt_earlygdb = 0;
 boolean_param("earlygdb", opt_earlygdb);
@@ -167,7 +176,10 @@ static void __init __start_xen(multiboot
         cmdline_parse(__va((ulong)mbi->cmdline));
 
     /* We initialise the serial devices very early so we can get debugging. */
-    /* XXX find this in device tree */
+    {
+    /*
+     * the type of device is recorded in the global hardware stuff struct
+     */
     struct ns16550_defaults ns16550 = {
         .baud      = BAUD_AUTO,
         .data_bits = 8,
@@ -175,9 +187,11 @@ static void __init __start_xen(multiboot
         .stop_bits = 1,
         /* On maple this is 10, but we run in poll mode at the moment */
         .irq       = 0,
-        .io_base   = 0x3f8,
     };
-    ns16550_init(0, &ns16550);
+    ns16550.io_base = global_hs.serial_port.isa_io_base +
+                      global_hs.serial_port.uart_io_base;
+    global_hs.serial_port.uart_p->uart_init_func(0, &ns16550);
+    }
     serial_init_preirq();
 
     init_console();
@@ -282,6 +296,8 @@ static void __init __start_xen(multiboot
     if (dom0 == NULL)
         panic("Error creating domain 0\n");
     set_bit(_DOMF_privileged, &dom0->domain_flags);
+    if (opt_nohv)
+       set_bit(_DOMF_prob, &dom0->domain_flags);
 
     /* Grab the DOM0 command line. Skip past the image name. */
     cmdline = (char *)(mod[0].string ? __va((ulong)mod[0].string) : NULL);
diff -r 56e1802303e5 xen/drivers/char/Makefile
--- a/xen/drivers/char/Makefile Wed Apr 12 15:41:55 2006 -0500
+++ b/xen/drivers/char/Makefile Thu May  4 13:19:28 2006 -0400
@@ -1,5 +1,6 @@ obj-y += console.o
 obj-y += console.o
 obj-y += ns16550.o
+obj-y += pmac_zilog.o
 obj-y += serial.o
 
 # Object file contains changeset and compiler information.
diff -r 56e1802303e5 xen/drivers/char/ns16550.c
--- a/xen/drivers/char/ns16550.c        Wed Apr 12 15:41:55 2006 -0500
+++ b/xen/drivers/char/ns16550.c        Thu May  4 13:19:28 2006 -0400
@@ -269,7 +269,7 @@ static struct uart_driver ns16550_driver
     .getc         = ns16550_getc
 };
 
-static int parse_parity_char(int c)
+int parse_parity_char(int c)
 {
     switch ( c )
     {
diff -r 56e1802303e5 xen/include/xen/sched.h
--- a/xen/include/xen/sched.h   Wed Apr 12 15:41:55 2006 -0500
+++ b/xen/include/xen/sched.h   Thu May  4 13:19:28 2006 -0400
@@ -392,6 +392,10 @@ extern struct domain *domain_list;
  /* Domain is being debugged by controller software. */
 #define _DOMF_debugging        4
 #define DOMF_debugging         (1UL<<_DOMF_debugging)
+ /* run domain in prob mode */
+#define _DOMF_prob      7
+#define DOMF_prob       (1UL<<_DOMF_prob)
+
 
 static inline int vcpu_runnable(struct vcpu *v)
 {
diff -r 56e1802303e5 xen/include/xen/serial.h
--- a/xen/include/xen/serial.h  Wed Apr 12 15:41:55 2006 -0500
+++ b/xen/include/xen/serial.h  Thu May  4 13:19:28 2006 -0400
@@ -8,6 +8,8 @@
 
 #ifndef __XEN_SERIAL_H__
 #define __XEN_SERIAL_H__
+
+#include <xen/spinlock.h>
 
 struct cpu_user_regs;
 
@@ -123,6 +125,7 @@ struct ns16550_defaults {
     unsigned long io_base; /* default io_base address */
 };
 void ns16550_init(int index, struct ns16550_defaults *defaults);
+void pmac_zilog_init(int index, struct ns16550_defaults *defaults);
 
 /* Baud rate was pre-configured before invoking the UART driver. */
 #define BAUD_AUTO (-1)
diff -r 56e1802303e5 xen/arch/ppc/platform.h
--- /dev/null   Thu Jan  1 00:00:00 1970 +0000
+++ b/xen/arch/ppc/platform.h   Thu May  4 13:19:28 2006 -0400
@@ -0,0 +1,33 @@
+#ifndef _PLATFORM_H
+#define _PLATFORM_H
+
+enum platform_type { pmac, maple };
+struct platform {
+    enum platform_type type;
+    char *compat_s;
+    int (*init_func)(void);
+};
+
+enum uart_type { ns16550, pmac_zilog };
+struct uart {
+    enum uart_type type;
+    char *p_sign;       // parernt directory signature
+    char *gp_sign;      // grandparent directory signature
+    void (* uart_init_func) (int i, struct ns16550_defaults * init_struct);
+};
+
+struct platform_serial_port {
+    u64 uart_io_base;
+    u64 isa_io_base;
+    struct uart *uart_p;
+    u32 clock;
+};
+
+struct global_hardware_stuff {
+    enum platform_type platform_type;
+    enum uart_type uart_type;
+
+    int hv_supported;
+    struct platform_serial_port serial_port;
+};
+#endif  /* #ifndef _PLATFORM_H */
diff -r 56e1802303e5 xen/drivers/char/pmac_zilog.c
--- /dev/null   Thu Jan  1 00:00:00 1970 +0000
+++ b/xen/drivers/char/pmac_zilog.c     Thu May  4 13:19:28 2006 -0400
@@ -0,0 +1,426 @@
+/*
+ * Copyright (C) 2005 Jimi Xenidis <jimix@xxxxxxxxxxxxxx>, IBM Corporation
+ *
+ * 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, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ * $Id: zilog.c,v 1.3 2005/05/05 20:51:04 mostrows Exp $
+ */
+
+/*
+ * linux/drivers/serial/pmac_zilog.c
+ * 
+ * Driver for PowerMac Z85c30 based ESCC cell found in the
+ * "macio" ASICs of various PowerMac models
+ * 
+ * Copyright (C) 2003 Ben. Herrenschmidt (benh@xxxxxxxxxxxxxxxxxxx)
+ *
+ * Derived from drivers/macintosh/macserial.c by Paul Mackerras
+ * and drivers/serial/sunzilog.c by David S. Miller
+ *
+ * Hrm... actually, I ripped most of sunzilog (Thanks David !) and
+ * adapted special tweaks needed for us. I don't think it's worth
+ * merging back those though. The DMA code still has to get in
+ * and once done, I expect that driver to remain fairly stable in
+ * the long term, unless we change the driver model again...
+ *
+ * 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, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * 2004-08-06 Harald Welte <laforge@xxxxxxxxxxxx>
+ *     - Enable BREAK interrupt
+ *     - Add support for sysreq
+ *
+ * TODO:   - Add DMA support
+ *         - Defer port shutdown to a few seconds after close
+ *         - maybe put something right into uap->clk_divisor
+ */
+
+/******************************************************************************
+ * pmac_zilog.c
+ * 
+ * From rhype and linux
+ *
+ */
+
+#include <xen/config.h>
+#include <xen/init.h>
+#include <xen/irq.h>
+#include <xen/sched.h>
+#include <xen/serial.h>
+#include <xen/iocap.h>
+#include <asm/io.h>
+#include <xen/delay.h>
+#include "pmac_zilog.h"
+
+int of_printf(const char *fmt, ...);
+
+/* from rhype and linux */
+
+struct uart_pmac_port uaps[MAX_ZS_PORTS];
+
+extern int parse_parity_char(int c);
+
+#define PANIC(_f)                        \
+    {                                    \
+    of_printf( "ERROR: " _f "\n");       \
+    }
+
+/* internal */
+static char pmac_zilog_read_reg(struct uart_port *uart, int reg, int verbose)
+{
+    if (verbose)
+        of_printf("%s: readb 0x%x\n", __func__, uart->remapped_io_base + reg);
+    return readb(uart->remapped_io_base + reg);
+}
+
+/* internal */
+static void pmac_zilog_write_reg(struct uart_port *uart, int reg, char c, int 
verbose)
+{
+    if (verbose)
+        of_printf("%s: writeb 0x%x  0x%02x\n", __func__, 
uart->remapped_io_base + reg, c);
+    writeb(c, uart->remapped_io_base + reg);
+}
+
+/* internal */
+/* Note this is equivalent to linux read_zsreg followed by the bit AND */
+static int pmac_zilog_chkbit(struct uart_port *ops, int reg, int bit)
+{
+    char c;
+
+    // to read any register (but 0), first write the register number to the
+    // control register, then read the control register
+    // 
+    if (reg != 0) { pmac_zilog_write_reg(ops, REG_CONTROL, reg, 0); }
+    c = pmac_zilog_read_reg(ops, REG_CONTROL, 0);
+    return (c & bit) == bit;
+}
+
+/* internal from linux */
+/* 
+ * Load all registers to reprogram the port
+ * This function must only be called when the TX is not busy.  The UART
+ * port lock must be held and local interrupts disabled.
+ */
+static void pmz_load_zsregs(struct uart_pmac_port *uap, u8 *regs)
+{
+       int i;
+
+       if (ZS_IS_ASLEEP(uap))
+               return;
+
+       /* Let pending transmits finish.  */
+       for (i = 0; i < 1000; i++) {
+               unsigned char stat = read_zsreg(uap, R1);
+               if (stat & ALL_SNT)
+                       break;
+               udelay(100);
+       }
+
+       ZS_CLEARERR(uap);
+       zssync(uap);
+       ZS_CLEARFIFO(uap);
+       zssync(uap);
+       ZS_CLEARERR(uap);
+
+       /* Disable all interrupts.  */
+       write_zsreg(uap, R1,
+                   regs[R1] & ~(RxINT_MASK | TxINT_ENAB | EXT_INT_ENAB));
+
+       /* Set parity, sync config, stop bits, and clock divisor.  */
+       write_zsreg(uap, R4, regs[R4]);
+
+       /* Set misc. TX/RX control bits.  */
+       write_zsreg(uap, R10, regs[R10]);
+
+       /* Set TX/RX controls sans the enable bits.  */
+               write_zsreg(uap, R3, regs[R3] & ~RxENABLE);
+               write_zsreg(uap, R5, regs[R5] & ~TxENABLE);
+
+       /* now set R7 "prime" on ESCC */
+       write_zsreg(uap, R15, regs[R15] | EN85C30);
+       write_zsreg(uap, R7, regs[R7P]);
+
+       /* make sure we use R7 "non-prime" on ESCC */
+       write_zsreg(uap, R15, regs[R15] & ~EN85C30);
+
+       /* Synchronous mode config.  */
+       write_zsreg(uap, R6, regs[R6]);
+       write_zsreg(uap, R7, regs[R7]);
+
+       /* Disable baud generator.  */
+       write_zsreg(uap, R14, regs[R14] & ~BRENAB);
+
+       /* Clock mode control.  */
+       write_zsreg(uap, R11, regs[R11]);
+
+       /* Lower and upper byte of baud rate generator divisor.  */
+       write_zsreg(uap, R12, regs[R12]);
+       write_zsreg(uap, R13, regs[R13]);
+       
+       /* Now rewrite R14, with BRENAB (if set).  */
+       write_zsreg(uap, R14, regs[R14]);
+
+       /* Reset external status interrupts.  */
+       write_zsreg(uap, R0, RES_EXT_INT);
+       write_zsreg(uap, R0, RES_EXT_INT);
+
+       /* Rewrite R3/R5, this time without enables masked.  */
+       write_zsreg(uap, R3, regs[R3]);
+       write_zsreg(uap, R5, regs[R5]);
+
+       /* Rewrite R1, this time without IRQ enabled masked.  */
+       write_zsreg(uap, R1, regs[R1]);
+
+       /* Enable interrupts */
+       write_zsreg(uap, R9, regs[R9]);
+}
+
+static void pmac_zilog_init_preirq(struct serial_port *port)
+{
+    struct uart_pmac_port *uap = port->uart;
+    struct uart_port *uart = &(uap->port);
+    unsigned int divisor;
+
+    uart->remapped_io_base = (char *)ioremap(uart->io_base, 8);
+
+    /* No flow ctrl: DTR and RTS are both wedged high to keep remote happy. */
+    /* parity, data bit (8 or bust) and stop bits todo */
+    
+#define LINUX_PMAC_ZILOG_INIT
+#ifdef LINUX_PMAC_ZILOG_INIT
+    /* from Linux's __pmz_startup().  Modified */
+    {
+        uap->flags = PMACZILOG_FLAG_IS_CHANNEL_A
+                | PMACZILOG_FLAG_IS_IRDA 
+                ;
+                     
+       memset(&uap->curregs, 0, sizeof(uap->curregs));
+
+       /* Power up the SCC & underlying hardware (modem/irda) */
+       //(void) pmz_set_scc_power(uap, 1);  TODO?
+
+       /* Nice buggy HW ... */
+       //pmz_fix_zero_bug_scc(uap);  TODO
+
+       /* Reset the channel */
+       uap->curregs[R9] = 0;
+       write_zsreg(uap, 9, ZS_IS_CHANNEL_A(uap) ? CHRA : CHRB);
+       zssync(uap);
+       udelay(10);
+       write_zsreg(uap, 9, 0);
+       zssync(uap);
+
+       /* Clear the interrupt registers */
+       write_zsreg(uap, R1, 0);
+       write_zsreg(uap, R0, ERR_RES);
+       write_zsreg(uap, R0, ERR_RES);
+       write_zsreg(uap, R0, RES_H_IUS);
+       write_zsreg(uap, R0, RES_H_IUS);
+
+       /* Setup some valid baud rate */
+       uap->curregs[R4] = X16CLK | SB1;
+       uap->curregs[R3] = Rx8;
+       uap->curregs[R5] = Tx8 | RTS;
+       if (!ZS_IS_IRDA(uap))
+               uap->curregs[R5] |= DTR;
+
+        /* baud divisor */
+#define UART_CLOCK_HZ 0
+        if ( uart->baud == BAUD_AUTO ) {
+           divisor = read_zsreg(uap, R12);
+            divisor |= read_zsreg(uap, R13) << 8;
+            uart->baud = UART_CLOCK_HZ / (divisor * 16);
+        } else {
+            /* Baud rate specified: program it into the divisor latch. */
+            divisor = UART_CLOCK_HZ / (uart->baud * 16);
+           uap->curregs[R12] = (char)divisor;  /* baud divisor lower byte */
+           uap->curregs[R13] = (char)(divisor >> 8);  /* upper byte */
+        }
+        
+       uap->curregs[R14] = BRENAB;
+
+       /* Clear handshaking, enable BREAK interrupts */
+       /* uap->curregs[R15] = BRKIE;  we don't want interrupts */
+
+       /* Master interrupt enable */
+       /* uap->curregs[R9] |= NV | MIE;  we don't want interrupts */
+
+       pmz_load_zsregs(uap, uap->curregs);
+
+       /* Enable receiver and transmitter.  */
+       write_zsreg(uap, R3, uap->curregs[R3] |= RxENABLE);
+       write_zsreg(uap, R5, uap->curregs[R5] |= TxENABLE);
+
+       /* Remember status for DCD/CTS changes */
+       uap->prev_status = read_zsreg(uap, R0);
+
+    }
+#endif  /* #ifdef LINUX_PMAC_ZILOG_INIT */
+
+    /* Enable and clear the FIFOs. Set a large trigger threshold. */
+    port->tx_fifo_size = 2048;
+}
+
+static void pmac_zilog_init_postirq(struct serial_port *port)
+{
+        PANIC("postirq!");
+}
+
+/* internal */
+static int pmac_zilog_write_avail(struct uart_port *ops)
+{
+    if (pmac_zilog_chkbit(ops, 0, Tx_BUF_EMP) &&
+        pmac_zilog_chkbit(ops, 1, ALL_SNT)) {
+        return 2048;
+    }
+    return 0;
+}
+
+/* Transmit FIFO ready to receive up to @tx_fifo_size characters? */
+static int pmac_zilog_tx_empty(struct serial_port *port)
+{
+    struct uart_pmac_port *uap = port->uart;
+    struct uart_port *uart = &(uap->port);
+    
+    static int call_count = 0;  // debug
+    call_count++;
+    if ((call_count < 1) ) {
+            of_printf("%s: count=%d\n", __func__, call_count);
+    }
+    
+    return pmac_zilog_write_avail(uart);
+}
+
+static void pmac_zilog_putc(struct serial_port *port, char c)
+{
+    struct uart_pmac_port *uap = port->uart;
+    struct uart_port *uart = &(uap->port);
+    
+    static int call_count = 0;  // debug
+    call_count++;
+    if ((call_count < 1 )) {
+            of_printf("%s: count=%d\n", __func__, call_count);
+    }
+
+    pmac_zilog_write_reg(uart, REG_DATA, c, 0);
+}
+
+/* internal */
+static int pmac_zilog_read_avail(struct uart_port *ops)
+{
+    char c = pmac_zilog_read_reg(ops, REG_CONTROL, 0);
+    if (c & Rx_CH_AV) {
+        return 1;
+    } else {
+        return 0;
+    }
+}
+
+/* Get a character from the serial line: returns 0 if none available. */
+static int pmac_zilog_getc(struct serial_port *port, char *pc)
+{
+    struct uart_pmac_port *uap = port->uart;
+    struct uart_port *uart = &(uap->port);
+    int rc;
+    
+    static int call_count = 0;  // debug
+    call_count++;
+    if ((call_count < 1)) {
+            of_printf("%s: count=%d\n", __func__, call_count);
+    }
+
+    if (pmac_zilog_read_avail(uart)) {
+        *pc = pmac_zilog_read_reg(uart, REG_DATA, 0);
+        rc = 1;
+    } else {
+        rc = 0;
+    }
+
+    return rc;
+}
+
+#define PARSE_ERR(_f, _a...)                 \
+    do {                                     \
+        printk( "ERROR: " _f "\n" , ## _a ); \
+        return;                              \
+    } while ( 0 )
+                                                                               
 
+static struct uart_driver pmac_zilog_driver = {
+    .init_preirq  = pmac_zilog_init_preirq,
+    .init_postirq = pmac_zilog_init_postirq,
+    .endboot      = NULL,
+    .tx_empty     = pmac_zilog_tx_empty,
+    .putc         = pmac_zilog_putc,
+    .getc         = pmac_zilog_getc
+};
+
+/* internal */
+static void pmac_zilog_parse_port_config(struct uart_port *uart, char *conf)
+{
+    /* Sanity checks. */
+    if ( (uart->baud != BAUD_AUTO) &&
+         ((uart->baud < 1200) || (uart->baud > 115200)) )
+        PARSE_ERR("Baud rate %d outside supported range.", uart->baud);
+    if ( (uart->data_bits < 5) || (uart->data_bits > 8) )
+        PARSE_ERR("%d data bits are unsupported.", uart->data_bits);
+    if ( (uart->stop_bits < 1) || (uart->stop_bits > 2) )
+        PARSE_ERR("%d stop bits are unsupported.", uart->stop_bits);
+    if ( uart->io_base == 0 )
+        PARSE_ERR("I/O base address must be specified.");
+}
+
+void pmac_zilog_init(int index, struct ns16550_defaults *defaults)
+{
+    if ( (index < 0) || (index >= MAX_ZS_PORTS) ) 
+            return;
+    
+    memset(&uaps[index], 0, sizeof(struct uart_pmac_port));
+    
+    if ( defaults != NULL )
+    {
+        uaps[index].port.baud      = defaults->baud;
+        uaps[index].port.data_bits = defaults->data_bits;
+        uaps[index].port.parity    = parse_parity_char(defaults->parity);
+        uaps[index].port.stop_bits = defaults->stop_bits;
+        uaps[index].port.irq       = defaults->irq;
+        uaps[index].port.io_base   = defaults->io_base;
+    }
+
+    pmac_zilog_parse_port_config(&(uaps[index].port), NULL);
+
+    /* Register with generic serial driver. */
+    serial_register_uart(index, &pmac_zilog_driver, &uaps[index]);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r 56e1802303e5 xen/drivers/char/pmac_zilog.h
--- /dev/null   Thu Jan  1 00:00:00 1970 +0000
+++ b/xen/drivers/char/pmac_zilog.h     Thu May  4 13:19:28 2006 -0400
@@ -0,0 +1,405 @@
+#ifndef __PMAC_ZILOG_H__
+#define __PMAC_ZILOG_H__
+/****
+ * Linux code drivers/serial/pmac_zilog.h
+ * missing copyright notice in Linux tree
+ */
+
+/* Xen additions */
+/* copy of ns16550 in ns16550.c */
+struct uart_port {
+    int baud, data_bits, parity, stop_bits, irq;
+    unsigned long io_base;   /* I/O port or memory-mapped I/O address. */
+    char *remapped_io_base;  /* Remapped virtual address of mmap I/O.  */
+    /* UART with IRQ line: interrupt-driven I/O. */
+    struct irqaction irqaction;
+    /* UART with no IRQ line: periodically-polled I/O. */
+    struct timer timer;
+};
+struct termios {
+};
+/* end Xen additions */
+
+#define pmz_debug(fmt,arg...)  dev_dbg(&uap->dev->ofdev.dev, fmt, ## arg)
+
+/*
+ * At most 2 ESCCs with 2 ports each
+ */
+#define MAX_ZS_PORTS   4
+
+/* 
+ * We wrap our port structure around the generic uart_port.
+ */
+#define NUM_ZSREGS    17
+
+struct uart_pmac_port {
+       struct uart_port                port;
+       struct uart_pmac_port           *mate;
+
+       /* macio_dev for the escc holding this port (maybe be null on
+        * early inited port)
+        */
+       struct macio_dev                *dev;
+       /* device node to this port, this points to one of 2 childs
+        * of "escc" node (ie. ch-a or ch-b)
+        */
+       struct device_node              *node;
+
+       /* Port type as obtained from device tree (IRDA, modem, ...) */
+       int                             port_type;
+       u8                              curregs[NUM_ZSREGS];
+
+       unsigned int                    flags;
+#define PMACZILOG_FLAG_IS_CONS         0x00000001
+#define PMACZILOG_FLAG_IS_KGDB         0x00000002
+#define PMACZILOG_FLAG_MODEM_STATUS    0x00000004
+#define PMACZILOG_FLAG_IS_CHANNEL_A    0x00000008
+#define PMACZILOG_FLAG_REGS_HELD       0x00000010
+#define PMACZILOG_FLAG_TX_STOPPED      0x00000020
+#define PMACZILOG_FLAG_TX_ACTIVE       0x00000040
+#define PMACZILOG_FLAG_ENABLED          0x00000080
+#define PMACZILOG_FLAG_IS_IRDA         0x00000100
+#define PMACZILOG_FLAG_IS_INTMODEM     0x00000200
+#define PMACZILOG_FLAG_HAS_DMA         0x00000400
+#define PMACZILOG_FLAG_RSRC_REQUESTED  0x00000800
+#define PMACZILOG_FLAG_IS_ASLEEP       0x00001000
+#define PMACZILOG_FLAG_IS_OPEN         0x00002000
+#define PMACZILOG_FLAG_IS_IRQ_ON       0x00004000
+#define PMACZILOG_FLAG_IS_EXTCLK       0x00008000
+#define PMACZILOG_FLAG_BREAK           0x00010000
+
+       unsigned char                   parity_mask;
+       unsigned char                   prev_status;
+
+       volatile u8                     __iomem *control_reg;
+       volatile u8                     __iomem *data_reg;
+
+       unsigned int                    tx_dma_irq;
+       unsigned int                    rx_dma_irq;
+       volatile struct dbdma_regs      __iomem *tx_dma_regs;
+       volatile struct dbdma_regs      __iomem *rx_dma_regs;
+
+       struct termios                  termios_cache;
+};
+
+#define to_pmz(p) ((struct uart_pmac_port *)(p))
+
+static inline struct uart_pmac_port *pmz_get_port_A(struct uart_pmac_port *uap)
+{
+       if (uap->flags & PMACZILOG_FLAG_IS_CHANNEL_A)
+               return uap;
+       return uap->mate;
+}
+
+/*
+ * Register acessors. Note that we don't need to enforce a recovery
+ * delay on PCI PowerMac hardware, it's dealt in HW by the MacIO chip,
+ * though if we try to use this driver on older machines, we might have
+ * to add it back
+ */
+static inline u8 read_zsreg(struct uart_pmac_port *port, u8 reg)
+{
+       if (reg != 0)
+               writeb(reg, port->control_reg);
+       return readb(port->control_reg);
+}
+
+static inline void write_zsreg(struct uart_pmac_port *port, u8 reg, u8 value)
+{
+       if (reg != 0)
+               writeb(reg, port->control_reg);
+       writeb(value, port->control_reg);
+}
+
+static inline u8 read_zsdata(struct uart_pmac_port *port)
+{
+       return readb(port->data_reg);
+}
+
+static inline void write_zsdata(struct uart_pmac_port *port, u8 data)
+{
+       writeb(data, port->data_reg);
+}
+
+static inline void zssync(struct uart_pmac_port *port)
+{
+       (void)readb(port->control_reg);
+}
+
+/* Conversion routines to/from brg time constants from/to bits
+ * per second.
+ */
+#define BRG_TO_BPS(brg, freq) ((freq) / 2 / ((brg) + 2))
+#define BPS_TO_BRG(bps, freq) ((((freq) + (bps)) / (2 * (bps))) - 2)
+
+#define ZS_CLOCK         3686400       /* Z8530 RTxC input clock rate */
+
+/* The Zilog register set */
+
+#define        FLAG    0x7e
+
+/* Write Register 0 */
+#define        R0      0               /* Register selects */
+#define        R1      1
+#define        R2      2
+#define        R3      3
+#define        R4      4
+#define        R5      5
+#define        R6      6
+#define        R7      7
+#define        R8      8
+#define        R9      9
+#define        R10     10
+#define        R11     11
+#define        R12     12
+#define        R13     13
+#define        R14     14
+#define        R15     15
+#define        R7P     16
+
+#define        NULLCODE        0       /* Null Code */
+#define        POINT_HIGH      0x8     /* Select upper half of registers */
+#define        RES_EXT_INT     0x10    /* Reset Ext. Status Interrupts */
+#define        SEND_ABORT      0x18    /* HDLC Abort */
+#define        RES_RxINT_FC    0x20    /* Reset RxINT on First Character */
+#define        RES_Tx_P        0x28    /* Reset TxINT Pending */
+#define        ERR_RES         0x30    /* Error Reset */
+#define        RES_H_IUS       0x38    /* Reset highest IUS */
+
+#define        RES_Rx_CRC      0x40    /* Reset Rx CRC Checker */
+#define        RES_Tx_CRC      0x80    /* Reset Tx CRC Checker */
+#define        RES_EOM_L       0xC0    /* Reset EOM latch */
+
+/* Write Register 1 */
+
+#define        EXT_INT_ENAB    0x1     /* Ext Int Enable */
+#define        TxINT_ENAB      0x2     /* Tx Int Enable */
+#define        PAR_SPEC        0x4     /* Parity is special condition */
+
+#define        RxINT_DISAB     0       /* Rx Int Disable */
+#define        RxINT_FCERR     0x8     /* Rx Int on First Character Only or 
Error */
+#define        INT_ALL_Rx      0x10    /* Int on all Rx Characters or error */
+#define        INT_ERR_Rx      0x18    /* Int on error only */
+#define RxINT_MASK     0x18
+
+#define        WT_RDY_RT       0x20    /* W/Req reflects recv if 1, xmit if 0 
*/
+#define        WT_FN_RDYFN     0x40    /* W/Req pin is DMA request if 1, wait 
if 0 */
+#define        WT_RDY_ENAB     0x80    /* Enable W/Req pin */
+
+/* Write Register #2 (Interrupt Vector) */
+
+/* Write Register 3 */
+
+#define        RxENABLE        0x1     /* Rx Enable */
+#define        SYNC_L_INH      0x2     /* Sync Character Load Inhibit */
+#define        ADD_SM          0x4     /* Address Search Mode (SDLC) */
+#define        RxCRC_ENAB      0x8     /* Rx CRC Enable */
+#define        ENT_HM          0x10    /* Enter Hunt Mode */
+#define        AUTO_ENAB       0x20    /* Auto Enables */
+#define        Rx5             0x0     /* Rx 5 Bits/Character */
+#define        Rx7             0x40    /* Rx 7 Bits/Character */
+#define        Rx6             0x80    /* Rx 6 Bits/Character */
+#define        Rx8             0xc0    /* Rx 8 Bits/Character */
+#define RxN_MASK       0xc0
+
+/* Write Register 4 */
+
+#define        PAR_ENAB        0x1     /* Parity Enable */
+#define        PAR_EVEN        0x2     /* Parity Even/Odd* */
+
+#define        SYNC_ENAB       0       /* Sync Modes Enable */
+#define        SB1             0x4     /* 1 stop bit/char */
+#define        SB15            0x8     /* 1.5 stop bits/char */
+#define        SB2             0xc     /* 2 stop bits/char */
+#define SB_MASK                0xc
+
+#define        MONSYNC         0       /* 8 Bit Sync character */
+#define        BISYNC          0x10    /* 16 bit sync character */
+#define        SDLC            0x20    /* SDLC Mode (01111110 Sync Flag) */
+#define        EXTSYNC         0x30    /* External Sync Mode */
+
+#define        X1CLK           0x0     /* x1 clock mode */
+#define        X16CLK          0x40    /* x16 clock mode */
+#define        X32CLK          0x80    /* x32 clock mode */
+#define        X64CLK          0xC0    /* x64 clock mode */
+#define XCLK_MASK      0xC0
+
+/* Write Register 5 */
+
+#define        TxCRC_ENAB      0x1     /* Tx CRC Enable */
+#define        RTS             0x2     /* RTS */
+#define        SDLC_CRC        0x4     /* SDLC/CRC-16 */
+#define        TxENABLE        0x8     /* Tx Enable */
+#define        SND_BRK         0x10    /* Send Break */
+#define        Tx5             0x0     /* Tx 5 bits (or less)/character */
+#define        Tx7             0x20    /* Tx 7 bits/character */
+#define        Tx6             0x40    /* Tx 6 bits/character */
+#define        Tx8             0x60    /* Tx 8 bits/character */
+#define TxN_MASK       0x60
+#define        DTR             0x80    /* DTR */
+
+/* Write Register 6 (Sync bits 0-7/SDLC Address Field) */
+
+/* Write Register 7 (Sync bits 8-15/SDLC 01111110) */
+
+/* Write Register 7' (Some enhanced feature control) */
+#define        ENEXREAD        0x40    /* Enable read of some write registers 
*/
+
+/* Write Register 8 (transmit buffer) */
+
+/* Write Register 9 (Master interrupt control) */
+#define        VIS     1       /* Vector Includes Status */
+#define        NV      2       /* No Vector */
+#define        DLC     4       /* Disable Lower Chain */
+#define        MIE     8       /* Master Interrupt Enable */
+#define        STATHI  0x10    /* Status high */
+#define        NORESET 0       /* No reset on write to R9 */
+#define        CHRB    0x40    /* Reset channel B */
+#define        CHRA    0x80    /* Reset channel A */
+#define        FHWRES  0xc0    /* Force hardware reset */
+
+/* Write Register 10 (misc control bits) */
+#define        BIT6    1       /* 6 bit/8bit sync */
+#define        LOOPMODE 2      /* SDLC Loop mode */
+#define        ABUNDER 4       /* Abort/flag on SDLC xmit underrun */
+#define        MARKIDLE 8      /* Mark/flag on idle */
+#define        GAOP    0x10    /* Go active on poll */
+#define        NRZ     0       /* NRZ mode */
+#define        NRZI    0x20    /* NRZI mode */
+#define        FM1     0x40    /* FM1 (transition = 1) */
+#define        FM0     0x60    /* FM0 (transition = 0) */
+#define        CRCPS   0x80    /* CRC Preset I/O */
+
+/* Write Register 11 (Clock Mode control) */
+#define        TRxCXT  0       /* TRxC = Xtal output */
+#define        TRxCTC  1       /* TRxC = Transmit clock */
+#define        TRxCBR  2       /* TRxC = BR Generator Output */
+#define        TRxCDP  3       /* TRxC = DPLL output */
+#define        TRxCOI  4       /* TRxC O/I */
+#define        TCRTxCP 0       /* Transmit clock = RTxC pin */
+#define        TCTRxCP 8       /* Transmit clock = TRxC pin */
+#define        TCBR    0x10    /* Transmit clock = BR Generator output */
+#define        TCDPLL  0x18    /* Transmit clock = DPLL output */
+#define        RCRTxCP 0       /* Receive clock = RTxC pin */
+#define        RCTRxCP 0x20    /* Receive clock = TRxC pin */
+#define        RCBR    0x40    /* Receive clock = BR Generator output */
+#define        RCDPLL  0x60    /* Receive clock = DPLL output */
+#define        RTxCX   0x80    /* RTxC Xtal/No Xtal */
+
+/* Write Register 12 (lower byte of baud rate generator time constant) */
+
+/* Write Register 13 (upper byte of baud rate generator time constant) */
+
+/* Write Register 14 (Misc control bits) */
+#define        BRENAB  1       /* Baud rate generator enable */
+#define        BRSRC   2       /* Baud rate generator source */
+#define        DTRREQ  4       /* DTR/Request function */
+#define        AUTOECHO 8      /* Auto Echo */
+#define        LOOPBAK 0x10    /* Local loopback */
+#define        SEARCH  0x20    /* Enter search mode */
+#define        RMC     0x40    /* Reset missing clock */
+#define        DISDPLL 0x60    /* Disable DPLL */
+#define        SSBR    0x80    /* Set DPLL source = BR generator */
+#define        SSRTxC  0xa0    /* Set DPLL source = RTxC */
+#define        SFMM    0xc0    /* Set FM mode */
+#define        SNRZI   0xe0    /* Set NRZI mode */
+
+/* Write Register 15 (external/status interrupt control) */
+#define        EN85C30 1       /* Enable some 85c30-enhanced registers */
+#define        ZCIE    2       /* Zero count IE */
+#define        ENSTFIFO 4      /* Enable status FIFO (SDLC) */
+#define        DCDIE   8       /* DCD IE */
+#define        SYNCIE  0x10    /* Sync/hunt IE */
+#define        CTSIE   0x20    /* CTS IE */
+#define        TxUIE   0x40    /* Tx Underrun/EOM IE */
+#define        BRKIE   0x80    /* Break/Abort IE */
+
+
+/* Read Register 0 */
+#define        Rx_CH_AV        0x1     /* Rx Character Available */
+#define        ZCOUNT          0x2     /* Zero count */
+#define        Tx_BUF_EMP      0x4     /* Tx Buffer empty */
+#define        DCD             0x8     /* DCD */
+#define        SYNC_HUNT       0x10    /* Sync/hunt */
+#define        CTS             0x20    /* CTS */
+#define        TxEOM           0x40    /* Tx underrun */
+#define        BRK_ABRT        0x80    /* Break/Abort */
+
+/* Read Register 1 */
+#define        ALL_SNT         0x1     /* All sent */
+/* Residue Data for 8 Rx bits/char programmed */
+#define        RES3            0x8     /* 0/3 */
+#define        RES4            0x4     /* 0/4 */
+#define        RES5            0xc     /* 0/5 */
+#define        RES6            0x2     /* 0/6 */
+#define        RES7            0xa     /* 0/7 */
+#define        RES8            0x6     /* 0/8 */
+#define        RES18           0xe     /* 1/8 */
+#define        RES28           0x0     /* 2/8 */
+/* Special Rx Condition Interrupts */
+#define        PAR_ERR         0x10    /* Parity error */
+#define        Rx_OVR          0x20    /* Rx Overrun Error */
+#define        CRC_ERR         0x40    /* CRC/Framing Error */
+#define        END_FR          0x80    /* End of Frame (SDLC) */
+
+/* Read Register 2 (channel b only) - Interrupt vector */
+#define        CHB_Tx_EMPTY    0x00
+#define        CHB_EXT_STAT    0x02
+#define        CHB_Rx_AVAIL    0x04
+#define        CHB_SPECIAL     0x06
+#define        CHA_Tx_EMPTY    0x08
+#define        CHA_EXT_STAT    0x0a
+#define        CHA_Rx_AVAIL    0x0c
+#define        CHA_SPECIAL     0x0e
+#define        STATUS_MASK     0x06
+
+/* Read Register 3 (interrupt pending register) ch a only */
+#define        CHBEXT  0x1             /* Channel B Ext/Stat IP */
+#define        CHBTxIP 0x2             /* Channel B Tx IP */
+#define        CHBRxIP 0x4             /* Channel B Rx IP */
+#define        CHAEXT  0x8             /* Channel A Ext/Stat IP */
+#define        CHATxIP 0x10            /* Channel A Tx IP */
+#define        CHARxIP 0x20            /* Channel A Rx IP */
+
+/* Read Register 8 (receive data register) */
+
+/* Read Register 10  (misc status bits) */
+#define        ONLOOP  2               /* On loop */
+#define        LOOPSEND 0x10           /* Loop sending */
+#define        CLK2MIS 0x40            /* Two clocks missing */
+#define        CLK1MIS 0x80            /* One clock missing */
+
+/* Read Register 12 (lower byte of baud rate generator constant) */
+
+/* Read Register 13 (upper byte of baud rate generator constant) */
+
+/* Read Register 15 (value of WR 15) */
+
+/* Misc macros */
+#define ZS_CLEARERR(port)    (write_zsreg(port, 0, ERR_RES))
+#define ZS_CLEARFIFO(port)   do { volatile unsigned char garbage; \
+                                    garbage = read_zsdata(port); \
+                                    garbage = read_zsdata(port); \
+                                    garbage = read_zsdata(port); \
+                               } while(0)
+
+#define ZS_IS_CONS(UP)                 ((UP)->flags & PMACZILOG_FLAG_IS_CONS)
+#define ZS_IS_KGDB(UP)                 ((UP)->flags & PMACZILOG_FLAG_IS_KGDB)
+#define ZS_IS_CHANNEL_A(UP)            ((UP)->flags & 
PMACZILOG_FLAG_IS_CHANNEL_A)
+#define ZS_REGS_HELD(UP)               ((UP)->flags & PMACZILOG_FLAG_REGS_HELD)
+#define ZS_TX_STOPPED(UP)              ((UP)->flags & 
PMACZILOG_FLAG_TX_STOPPED)
+#define ZS_TX_ACTIVE(UP)               ((UP)->flags & PMACZILOG_FLAG_TX_ACTIVE)
+#define ZS_WANTS_MODEM_STATUS(UP)      ((UP)->flags & 
PMACZILOG_FLAG_MODEM_STATUS)
+#define ZS_IS_IRDA(UP)                 ((UP)->flags & PMACZILOG_FLAG_IS_IRDA)
+#define ZS_IS_INTMODEM(UP)             ((UP)->flags & 
PMACZILOG_FLAG_IS_INTMODEM)
+#define ZS_HAS_DMA(UP)                 ((UP)->flags & PMACZILOG_FLAG_HAS_DMA)
+#define ZS_IS_ASLEEP(UP)                       ((UP)->flags & 
PMACZILOG_FLAG_IS_ASLEEP)
+#define ZS_IS_OPEN(UP)                 ((UP)->flags & PMACZILOG_FLAG_IS_OPEN)
+#define ZS_IS_IRQ_ON(UP)                       ((UP)->flags & 
PMACZILOG_FLAG_IS_IRQ_ON)
+#define ZS_IS_EXTCLK(UP)                       ((UP)->flags & 
PMACZILOG_FLAG_IS_EXTCLK)
+
+/* Xen additions */
+#define REG_CONTROL     R0
+#define REG_DATA        0x10
+/* end Xen additions */
+#endif /* __PMAC_ZILOG_H__ */

_______________________________________________
Xen-ppc-devel mailing list
Xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ppc-devel

<Prev in Thread] Current Thread [Next in Thread>