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

[XenPPC] [xenppc-unstable] [ppc] DART devtree, discovery improvements



# HG changeset patch
# User Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
# Node ID 049e669e6a8abb8b2f0c7dced3c8ff53a9d9b21f
# Parent  6fb6d6cd599ef26f142f20215a4819df94347913
[ppc] DART devtree, discovery improvements

This patch moves the creation of the "/ht/ibm,dma-window" property to
the DART specific code.  The discovery of the DART is a lot smarter,
depending on the presence of the hypertransport node and using its
features to try and figure out if the is even a U3/U4 based machine.
Rename a bunch of variable so that they actually make sense (I hope)
and use less global variables.
---
 xen/arch/ppc/dart.c      |  206 +++++++++++++++++++++++++++--------------------
 xen/arch/ppc/ofd_fixup.c |   17 ---
 2 files changed, 122 insertions(+), 101 deletions(-)

diff -r 6fb6d6cd599e -r 049e669e6a8a xen/arch/ppc/dart.c
--- a/xen/arch/ppc/dart.c       Mon Jun 26 05:01:36 2006 -0400
+++ b/xen/arch/ppc/dart.c       Mon Jun 26 13:09:11 2006 -0400
@@ -41,10 +41,9 @@ static int dbg_after;
 #define DBG_AFTER(fmt...)
 #endif
 
-#define U3_LOG_MAX  21
-
-int dart_model;
-unsigned long dart_address;
+/* Max size of 512 pages */
+#define U3_LOG_MAX_PAGES 9
+
 #define DART_DEF_BASE   0xf8033000UL
 #define DART_NONE 0
 #define DART_U3 3
@@ -53,40 +52,54 @@ unsigned long dart_address;
 #define DART_READ 0x2
 
 static ulong dummy_page;
+static ulong dart_entries;
 static struct dart_ops *dops;
 static u32 *dart_table;
 
-union dart_tce {
-    u32 dt_word;
+union dart_entry {
+    u32 de_word;
     struct {
-        u32 dt_v:1;             /* valid */
-        u32 dt_rp:1;             /* read protected*/
-        u32 dt_wp:1;             /* write protected*/
-        u32 _dt_res:5;
-        u32 dt_ppn:24;         /* 24 bit Physical Page Number
+        u32 de_v:1;             /* valid */
+        u32 de_rp:1;             /* read protected*/
+        u32 de_wp:1;             /* write protected*/
+        u32 _de_res:5;
+        u32 de_ppn:24;         /* 24 bit Physical Page Number
                                  * representing address [28:51] */
-    } dt_bits;
+    } de_bits;
+};
+
+struct dma_window {
+    u32 dw_liobn;
+    u32 dw_base_hi;
+    u64 dw_base;
+    u64 dw_size;
+};
+
+struct dart_info {
+    struct dma_window di_window;
+    ulong di_base;
+    int di_model;
 };
 
 static u32 dart_encode(int perm, ulong rpn)
 {
-    union dart_tce tce;
-
-    tce.dt_word = 0;
-    tce.dt_bits.dt_v = 1;
-    tce.dt_bits.dt_ppn = rpn;
+    union dart_entry e;
+
+    e.de_word = 0;
+    e.de_bits.de_v = 1;
+    e.de_bits.de_ppn = rpn;
 
     /* protect the page */
-    tce.dt_bits.dt_rp = 1;
-    tce.dt_bits.dt_wp = 1;
+    e.de_bits.de_rp = 1;
+    e.de_bits.de_wp = 1;
     if (perm & DART_READ) {
-        tce.dt_bits.dt_rp = 0;
+        e.de_bits.de_rp = 0;
     }
     if (perm & DART_WRITE) {
-        tce.dt_bits.dt_wp = 0;
-    }
-
-    return tce.dt_word;
+        e.de_bits.de_wp = 0;
+    }
+
+    return e.de_word;
 }
 
 static void dart_fill(ulong index, int perm, ulong rpg, ulong num_pg)
@@ -133,7 +146,7 @@ static int dart_put(ulong ioba, union tc
 {
     ulong index = ioba >> PAGE_SHIFT;
 
-    if (index > (1 << U3_LOG_MAX) / sizeof(u32)) {
+    if (index > dart_entries) {
         return -1;
     }
 
@@ -170,92 +183,117 @@ static int dart_put(ulong ioba, union tc
     return 0;
 }
 
-static int find_dart_simple_probe(void *oft_p)
+static int find_dart(struct dart_info *di)
 {
     int rc;
+    void *ofd_p;
+    ofdn_t n;
     char compat[128];
-    ofdn_t dart_node;
-
-    dart_address = DART_DEF_BASE;
-    dart_model = DART_U3;
-
-    dart_node = ofd_node_find(oft_p, "/dart");
-    if (dart_node < 0) {
-        return -1;
-    }
-
-    /* if the property does not exist, then the value of dart_address is
-     * unmodified */
-    rc = ofd_getprop(oft_p, dart_node, "reg", &dart_address,
-                    sizeof (dart_address));
-
-    rc = ofd_getprop(oft_p, dart_node, "compatible", compat, sizeof (compat));
-    if ( rc > 0 ) {
-        if (strstr(compat, "u4")) {
-            dart_model = DART_U4;
-        }
-    }
-
-
-    return 0;
-}
-
-static int find_dart()
-{
-    void *oft_p;
-    int rc;
+
 
     if (on_mambo()) {
         /* mambo has no dart */
-        return -1;
-    }
-
-    dart_address = (unsigned long) -1;
-    dart_model = 0;
-
-    oft_p = (void *) oftree;
-
-    rc = find_dart_simple_probe(oft_p);
-    /* TODO: find the dart in the canonical way */
-
-    return rc;
+        DBG("%s: Mambo does not support a dart\n", __func__);
+        return -1;
+    }
+
+    ofd_p = (void *)oftree;
+    n = ofd_node_find(ofd_p, "/ht");
+    if (n <= 0)
+        return -1;
+
+    /* get the defaults from the HT node model */
+    rc = ofd_getprop(ofd_p, n, "compatible", compat, sizeof (compat));
+    if (rc <= 0)
+        return -1;
+
+    di->di_base = DART_DEF_BASE;
+
+    if (strstr(compat, "u3")) {
+        di->di_model = DART_U3;
+    } else if (strstr(compat, "u4")) {
+        di->di_model = DART_U4;
+    } else {
+        DBG("%s: not a U3 or U4\n", __func__);
+        return -1;
+    }
+    /* FIXME: this should actually be the HT reg value */
+    di->di_window.dw_liobn = 0;
+    di->di_window.dw_base_hi = 0;
+    di->di_window.dw_base = 0;
+
+    /* lets see if the devtree has more info */
+    n = ofd_node_find(ofd_p, "/dart");
+    if (n > 0) {
+        ulong base;
+
+        rc = ofd_getprop(ofd_p, n, "compatible", compat, sizeof (compat));
+        if (rc > 0) {
+            if (strstr(compat, "u4")) {
+                di->di_model = DART_U4;
+            }
+        }
+
+        rc = ofd_getprop(ofd_p, n, "reg", &base, sizeof (base));
+        if (rc > 0) {
+            di->di_base = base;
+        }
+    }
+    return 0;
 }
 
 static int init_dart(void)
 {
     ulong log_pgs;
-
-    if (find_dart())
+    void *ofd_p;
+    ofdn_t n;
+    struct dart_info di;
+
+    if (find_dart(&di))
         return 0;
 
     /* Max size of 512 pages == 2MB == 1<<21. That siz is good enough for U4 */
-    log_pgs = U3_LOG_MAX - PAGE_SHIFT;
+    log_pgs = U3_LOG_MAX_PAGES;
     dart_table = alloc_xenheap_pages(log_pgs);
+    BUG_ON(dart_table == NULL);
+
+    dart_entries = (1UL << (log_pgs + PAGE_SHIFT)) / sizeof (union dart_entry);
+    di.di_window.dw_size = dart_entries << PAGE_SHIFT;
 
     /* Linux uses a dummy page, filling "empty" DART entries with a
        reference to this page to capture stray DMA's */
-    dummy_page = (ulong)alloc_xenheap_pages(1) >> PAGE_SHIFT;
-    memset((void *)(dummy_page << PAGE_SHIFT), 0, 1 << PAGE_SHIFT);
-
-    printk("Initializing DART 0x%lx: tbl: 0x%lx[0x%lx] dummy: 0x%lx\n",
-           dart_address, (ulong)dart_table, (1 << U3_LOG_MAX) / sizeof(u32),
-           dummy_page);
+    dummy_page = (ulong)alloc_xenheap_pages(1);
+    memset((void *)dummy_page, 0, PAGE_SIZE);
+    dummy_page >>= PAGE_SHIFT;
+
+    printk("Initializing DART 0x%lx: tbl: %p[0x%lx] entries: 0x%lx\n",
+           di.di_base, dart_table, 1UL << log_pgs, dart_entries);
            
     /* register this iommu */
-    iommu_register(0, dart_put);
-
-    switch (dart_model) {
+    iommu_register(di.di_window.dw_liobn, dart_put);
+
+    switch (di.di_model) {
     case DART_U3:
-        dops = u3_init(dart_address, (ulong)dart_table, 1UL << log_pgs);
+        dops = u3_init(di.di_base, (ulong)dart_table, 1UL << log_pgs);
         break;
     case DART_U4:
-        dops = u4_init(dart_address, (ulong)dart_table, 1UL << log_pgs);
+        dops = u4_init(di.di_base, (ulong)dart_table, 1UL << log_pgs);
         break;
     }
 
-    dart_clear(0, (1 << U3_LOG_MAX) / sizeof(u32));
+    dart_clear(0, dart_entries);
     dops->do_inv_all();
-printk("%s: done!\n", __func__);
+
+    /* fix up the devtree */
+    ofd_p = (void *)oftree;
+    n = ofd_node_find(ofd_p, "/ht");
+    if (n > 0) {
+        di.di_window.dw_size = dart_entries << PAGE_SHIFT;
+        ofd_prop_add(ofd_p, n, "ibm,dma-window", &di.di_window,
+                     sizeof (di.di_window));
+    } else {
+        panic("%s: no /ht node\n", __func__);
+    }
     return 0;
 }
 __initcall(init_dart);
diff -r 6fb6d6cd599e -r 049e669e6a8a xen/arch/ppc/ofd_fixup.c
--- a/xen/arch/ppc/ofd_fixup.c  Mon Jun 26 05:01:36 2006 -0400
+++ b/xen/arch/ppc/ofd_fixup.c  Mon Jun 26 13:09:11 2006 -0400
@@ -401,20 +401,6 @@ static ofdn_t ofd_memory_props(void *m, 
     return n;
 }
 
-static ofdn_t ofd_ht_props(void *m)
-{
-    ofdn_t n;
-
-    n = ofd_node_find(m, "/ht");
-    if (n > 0) {
-        static const u32 ht_pci_dma_window[] = { 0, 0, 0, 0, 0, 1 << 31 };
-
-        ofd_prop_add(m, n, "ibm,dma-window", &ht_pci_dma_window,
-                     sizeof (ht_pci_dma_window));
-    }
-    return n;
-}
-
 static ofdn_t ofd_xen_props(void *m, struct domain *d, start_info_t *si)
 {
     ofdn_t n;
@@ -487,9 +473,6 @@ int ofd_dom0_fixup(struct domain *d, ulo
     printk("fix /memory@0 props\n");
     ofd_memory_props(m, d, eoload);
 
-    printk("fix /ht props\n");
-    ofd_ht_props(m);
-
     printk("fix /xen props\n");
     ofd_xen_props(m, d, si);
 

_______________________________________________
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®.