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] [pushed] [ppc] U4 DART enablement for JS21

changeset:   9958:786d4a84bdad6467f780967e7725581f44678d9a
user:        jimix@xxxxxxxxxxxxxxxxxxxxx
date:        Fri Apr 28 17:44:52 2006 -0400
files:       xen/arch/ppc/Makefile xen/arch/ppc/boot_of.c xen/arch/ppc/dart.c 
xen/arch/ppc/dart.h xen/arch/ppc/dart_u4.c xen/arch/ppc/iommu_u3.c
description:
[ppc] U4 DART enablement for JS21
  - discover the DART and model from the devtree
  - place common code in single file
  - isolate U3 DART code
  - write U4 DART code
  - rewrite invalidate retry code so it actually makes sense


diff -r ffa41af2e455738f8fe3a0af8ae8952e9d4cc47c -r 
786d4a84bdad6467f780967e7725581f44678d9a xen/arch/ppc/Makefile
--- a/xen/arch/ppc/Makefile     Thu Apr 27 14:40:10 2006 -0400
+++ b/xen/arch/ppc/Makefile     Fri Apr 28 17:44:52 2006 -0400
@@ -8,6 +8,8 @@ obj-y += audit.o
 obj-y += audit.o
 obj-y += bitops.o
 obj-y += boot_of.o
+obj-y += dart.o
+obj-y += dart_u4.o
 obj-y += delay.o
 obj-y += dom0_ops.o
 obj-y += domain_build.o
diff -r ffa41af2e455738f8fe3a0af8ae8952e9d4cc47c -r 
786d4a84bdad6467f780967e7725581f44678d9a xen/arch/ppc/boot_of.c
--- a/xen/arch/ppc/boot_of.c    Thu Apr 27 14:40:10 2006 -0400
+++ b/xen/arch/ppc/boot_of.c    Fri Apr 28 17:44:52 2006 -0400
@@ -24,6 +24,7 @@
 #include <xen/compile.h>
 #include <public/of-devtree.h>
 #include <asm/page.h>
+#include "dart.h"
 
 static ulong of_vec;
 static ulong of_msr;
@@ -824,15 +825,12 @@ static void boot_of_module(ulong r3, ulo
     mbi->flags |= MBI_MODULES;
     mbi->mods_count = 2;
     mbi->mods_addr = (u32)mods;
-
 }
 
 
 static int __init boot_of_serial(void)
 {
-    /* right now we are punting and using mambo writes which is the
-     * hardcoded setup */
-
+    /* fill this in */
     return 1;
 }
 
@@ -889,6 +887,35 @@ static void __init boot_of_pic(void)
         opic_addr |= addr[1];
     }
     of_printf("OF: found OpenPIC at: 0x%lx\n", opic_addr);
+}
+
+static void __init boot_of_dart(void)
+{
+    int n;
+
+    n = of_finddevice("/mambo");
+    if (n != OF_FAILURE) {
+        /* mambo had no dart */
+        return;
+    }
+
+    /* defaults */
+    dart_address = DART_DEF_BASE;
+    dart_model = DART_U3;
+
+    /* this is not great but is sufficient */
+    n = of_finddevice("/dart");
+    if (n != OF_FAILURE) {
+        char compat[128];
+
+        of_getprop(n, "reg", &dart_address, sizeof (dart_address));
+
+        compat[0] = '\0';
+        of_getprop(n, "compatible", compat, sizeof (compat));
+        if (strstr(compat, "u4")) {
+            dart_model = DART_U4;
+        }
+    }
 }
 
 multiboot_info_t __init *boot_of_init(
@@ -928,6 +955,7 @@ multiboot_info_t __init *boot_of_init(
     boot_of_cpus();
     boot_of_rtas();
     boot_of_pic();
+    boot_of_dart();
 
     /* end of OF */
     of_printf("closing OF stdout...\n");
diff -r ffa41af2e455738f8fe3a0af8ae8952e9d4cc47c -r 
786d4a84bdad6467f780967e7725581f44678d9a xen/arch/ppc/iommu_u3.c
--- a/xen/arch/ppc/iommu_u3.c   Thu Apr 27 14:40:10 2006 -0400
+++ b/xen/arch/ppc/iommu_u3.c   Fri Apr 28 17:44:52 2006 -0400
@@ -21,18 +21,13 @@
 #include <xen/config.h>
 #include <xen/types.h>
 #include <xen/sched.h>
-#include <xen/init.h>
 #include <xen/mm.h>
 #include <public/xen.h>
 #include <asm/io.h>
 #include <asm/current.h>
 #include "tce.h"
 #include "iommu.h"
-
-#define DART_VALID  0x80000000
-#define DART_MASK   0x00ffffff
-#define DART_BASE   0xf8033000UL
-#define DART_SHIFT  21
+#include "dart.h"
 
 union dart_ctl {
     u32 dc_word;
@@ -45,162 +40,67 @@ union dart_ctl {
     } reg;
 };
 
-#ifdef DEBUG
-static int first_put = 0;
-#endif
+static u32 volatile *dart_ctl_reg;
 
-static u32 *dart_table;
-static ulong dummy_page;
-static u32 *dart_ctl_reg;
+static void u3_inv_all(void)
+{
+    union dart_ctl dc;
+    ulong r = 0;
+    int l = 0;
 
-static void fill_dart(ulong index, ulong rpg, ulong num_pg)
-{
-    u32 volatile *entry = dart_table + index;
-    ulong i = 0;
-    ulong last_flush = 0;
+    for (;;) {
+        dc.dc_word = in_32(dart_ctl_reg);
+        dc.reg.dc_invtlb = 1;
+        out_32(dart_ctl_reg, dc.dc_word);
 
-    while (1) {
-        entry[i] = DART_VALID | (rpg & DART_MASK);
-        ++i;
-        ++rpg;
-        if (i == num_pg) break;
+    do {
+        dc.dc_word = in_32(dart_ctl_reg);
+        r++;
+    } while ((dc.reg.dc_invtlb == 1) && (r < (1 << l)));
 
-        if (((ulong)&entry[i]) % CACHE_LINE_SIZE == 0) {
-            last_flush = (ulong)&entry[i - 1];
-            dcbst(last_flush);
+        if (r == (1 << l)) {
+            if (l < 4) {
+                l++;
+                dc.dc_word = in_32(dart_ctl_reg);
+                dc.reg.dc_invtlb = 0;
+                out_32(dart_ctl_reg, dc.dc_word);
+                continue;
+            } else {
+                panic(" broken U3???\n");
+            }
         }
+        return;
     }
-    dcbst((ulong) &entry[i - 1]);
 }
 
-static void clear_dart(ulong index, ulong num_pg)
+static void u3_inv_entry(ulong pg)
 {
-    u32 *entry = dart_table + index;
-    ulong i = 0;
-    ulong rpg = dummy_page;
-    ulong last_flush = 0;
-
-    while (1) {
-        entry[i] = DART_VALID | (rpg & DART_MASK);
-        ++i;
-        if (i == num_pg) break;
-
-        if (((ulong)&entry[i]) % CACHE_LINE_SIZE == 0) {
-            last_flush = (ulong)&entry[i - 1];
-            dcbst(last_flush);
-        }
-    }
-    dcbst((ulong)&entry[i - 1]);
+    /* sadly single entry invalidation has been reported not to work */
+    u3_inv_all();
 }
 
-static void invtlb_dart(void)
+static struct dart_ops u3_ops = {
+    .do_inv_all = u3_inv_all,
+    .do_inv_entry = u3_inv_entry,
+};
+
+struct dart_ops *u3_init(ulong base, ulong table, ulong tpgs)
 {
     union dart_ctl dc;
-    ulong retries = 0;
 
-    dc.dc_word = in_32(dart_ctl_reg);
-    dc.reg.dc_invtlb = 1;
+    dart_ctl_reg = (u32 *)base;
+
+    dc.dc_word = 0;
+
+    dc.reg.dc_base = table >> PAGE_SHIFT;
+    dc.reg.dc_size = 1 << tpgs;
+    dc.reg.dc_enable = 1;
+
+
+    printk("Initializing DART Model U3: reg: %p word: %x\n",
+           dart_ctl_reg, dc.dc_word);
 
     out_32(dart_ctl_reg, dc.dc_word);
 
-    do {
-        union dart_ctl copy;
-
-        copy.dc_word = in_32(dart_ctl_reg);
-        if (copy.reg.dc_invtlb == 0) {
-            break;
-        }
-
-        ++retries;
-        if ((retries & 3) == 0) {
-            copy.reg.dc_invtlb = 0;
-            out_32(dart_ctl_reg, copy.dc_word);
-            copy.dc_word = in_32(dart_ctl_reg);
-            out_32(dart_ctl_reg, dc.dc_word);
-        }
-    } while (1);
+    return &u3_ops;
 }
-
-static int u3_put(ulong ioba, union tce tce)
-{
-    ulong index = ioba >> PAGE_SHIFT;
-
-    if (index > (1 << DART_SHIFT) / sizeof(u32)) {
-        return -1;
-    }
-
-    if (tce.tce_bits.tce_vlps  != 0 || tce.tce_bits.tce_lpx != 0) {
-        panic("no support for large TCEs\n");
-    }
-
-    if (tce.tce_bits.tce_read || tce.tce_bits.tce_write) {
-#ifdef DEBUG
-        printk("<DART[0x%lx]: ioba: 0x%lx rpn:0x%lx\n",
-               index, ioba, tce.tce_bits.tce_rpn);
-        first_put = 1;
-#endif
-        fill_dart(index, tce.tce_bits.tce_rpn, 1);
-    } else {
-#ifdef DEBUG
-        if (first_put) {
-            printk(">DART[0x%lx]\n", index);
-        }
-#endif
-        clear_dart(index, 1);
-    }
-    invtlb_dart();
-    
-    return 0;
-}
-
-static int init_u3(void)
-{
-    union dart_ctl dc;
-
-    if (on_mambo()) {
-        return 0;
-    }
-
-    /* SLOF doesn't provide DART address */
-    dart_ctl_reg = (u32 *)DART_BASE;
-
-    /* Max size of 512 pages == 2MB == 1<<21 */
-    dart_table = alloc_xenheap_pages(DART_SHIFT - 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);
-
-#ifdef DARB_EXAMPLE
-    if (0) {
-        ulong dabr = 0x44590b3; //0xf7fe70b3; //0xc003; // DABR 1013 DABRX 1015
-        ulong dabrx = 0xd;
-        asm volatile("mtspr 1013,%0; mtspr 1015,%1"
-                     : : "r" (dabr), "r" (dabrx) : "memory");
-    }
-#endif
-
-    clear_dart(0, (1 << DART_SHIFT) / sizeof(u32));
-
-    dc.dc_word = 0;
-
-    dc.reg.dc_base = ((ulong)dart_table) >> PAGE_SHIFT;
-    dc.reg.dc_size = 1 << (DART_SHIFT - PAGE_SHIFT);
-    dc.reg.dc_enable = 1;
-
-
-    printk("Initializing U3 DART: tbl: %p[0x%lx] ctl reg: %p word: %x "
-           "dummy: 0x%lx\n",
-           dart_table, (1 << DART_SHIFT) / sizeof(u32),
-           dart_ctl_reg, dc.dc_word, dummy_page);
-
-    out_32(dart_ctl_reg, dc.dc_word);
-
-    invtlb_dart();
-
-    iommu_register(0, u3_put);
-
-    return 0;
-}
-__initcall(init_u3);
diff -r ffa41af2e455738f8fe3a0af8ae8952e9d4cc47c -r 
786d4a84bdad6467f780967e7725581f44678d9a xen/arch/ppc/dart.c
--- /dev/null   Thu Jan  1 00:00:00 1970 +0000
+++ b/xen/arch/ppc/dart.c       Fri Apr 28 17:44:52 2006 -0400
@@ -0,0 +1,194 @@
+/*
+ * 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
+ */
+#include <xen/config.h>
+#include <xen/types.h>
+#include <xen/mm.h>
+#include <asm/cache.h>
+#include <xen/init.h>
+#include "tce.h"
+#include "iommu.h"
+#include "dart.h"
+
+#undef DEBUG
+#ifdef DEBUG
+static int first_put;
+#endif
+
+#define DART_SHIFT  21
+
+int dart_model;
+unsigned long dart_address;
+
+static ulong dummy_page;
+static struct dart_ops *dops;
+static u32 *dart_table;
+
+union dart_tce {
+    u32 dt_word;
+    struct {
+        u32 dt_v:1;             /* valid */
+        u32 dt_r:1;             /* read */
+        u32 dt_w:1;             /* write */
+        u32 _dt_res:5;
+        u32 dt_ppn:24;         /* 24 bit Physical Page Number
+                                 * representing address [28:51] */
+    } dt_bits;
+};
+
+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;
+
+    if (perm & DART_READ) {
+        tce.dt_bits.dt_r = 1;
+    }
+    if (perm & DART_WRITE) {
+        tce.dt_bits.dt_w = 1;
+    }
+
+    return tce.dt_word;
+}
+
+static void dart_fill(ulong index, int perm, ulong rpg, ulong num_pg)
+{
+    u32 volatile *entry = dart_table + index;
+    ulong i = 0;
+    ulong last_flush = 0;
+
+    while (1) {
+        entry[i] = dart_encode(perm, rpg);
+        ++i;
+        ++rpg;
+        if (i == num_pg) break;
+
+        if (((ulong)&entry[i]) % CACHE_LINE_SIZE == 0) {
+            last_flush = (ulong)&entry[i - 1];
+            dcbst(last_flush);
+        }
+    }
+    dcbst((ulong) &entry[i - 1]);
+}
+
+static void dart_clear(ulong index, ulong num_pg)
+{
+    u32 *entry = dart_table + index;
+    ulong i = 0;
+    ulong rpg = dummy_page;
+    ulong last_flush = 0;
+
+    while (1) {
+        entry[i] = dart_encode(DART_READ | DART_WRITE, rpg);
+        ++i;
+        if (i == num_pg) break;
+
+        if (((ulong)&entry[i]) % CACHE_LINE_SIZE == 0) {
+            last_flush = (ulong)&entry[i - 1];
+            dcbst(last_flush);
+        }
+    }
+    dcbst((ulong)&entry[i - 1]);
+}
+
+static int dart_put(ulong ioba, union tce tce)
+{
+    ulong index = ioba >> PAGE_SHIFT;
+    int perm = 0;
+
+    if (index > (1 << DART_SHIFT) / sizeof(u32)) {
+        return -1;
+    }
+
+    if (tce.tce_bits.tce_vlps  != 0 || tce.tce_bits.tce_lpx != 0) {
+        panic("no support for large TCEs\n");
+    }
+
+    if (tce.tce_bits.tce_read) {
+        perm |= DART_READ;
+    }
+    if (tce.tce_bits.tce_write) {
+        perm |= DART_WRITE;
+    }
+    if (perm != 0) {
+#ifdef DEBUG
+        printk("<DART[0x%lx]: ioba: 0x%lx rpn:0x%lx\n",
+               index, ioba, tce.tce_bits.tce_rpn);
+        first_put = 1;
+#endif
+        dart_fill(index, perm, tce.tce_bits.tce_rpn, 1);
+    } else {
+#ifdef DEBUG
+        if (first_put) {
+            printk(">DART[0x%lx]\n", index);
+        }
+#endif
+        dart_clear(index, 1);
+    }
+    dops->do_inv_entry(tce.tce_bits.tce_rpn);
+    
+    return 0;
+}
+
+static int init_dart(void)
+{
+    ulong tpgs;
+
+    switch (dart_model) {
+    case DART_U3: case DART_U4:
+        break;
+    default:
+        panic("unknown DART model: %d\n", dart_model);
+        /* FALLTHRU */
+    case 0:
+        return 0;
+    }
+
+    /* Max size of 512 pages == 2MB == 1<<21 */
+    tpgs = DART_SHIFT - PAGE_SHIFT;
+    dart_table = alloc_xenheap_pages(tpgs);
+
+    /* 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 << DART_SHIFT) / sizeof(u32),
+           dummy_page);
+           
+    /* register this iommu */
+    iommu_register(0, dart_put);
+
+    switch (dart_model) {
+    case DART_U3:
+        dops = u3_init(dart_address, (ulong)dart_table, tpgs);
+        break;
+    case DART_U4:
+        dops = u4_init(dart_address, (ulong)dart_table, tpgs);
+        break;
+    }
+
+    dart_clear(0, (1 << DART_SHIFT) / sizeof(u32));
+    dops->do_inv_all();
+printk("%s: done!\n", __func__);
+    return 0;
+}
+__initcall(init_dart);
diff -r ffa41af2e455738f8fe3a0af8ae8952e9d4cc47c -r 
786d4a84bdad6467f780967e7725581f44678d9a xen/arch/ppc/dart.h
--- /dev/null   Thu Jan  1 00:00:00 1970 +0000
+++ b/xen/arch/ppc/dart.h       Fri Apr 28 17:44:52 2006 -0400
@@ -0,0 +1,45 @@
+/*
+ * 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
+ *
+ */
+
+#ifndef _DART_H
+#define _DART_H
+
+#include <xen/config.h>
+#include <xen/types.h>
+
+#define DART_DEF_BASE   0xf8033000UL
+#define DART_NONE 0
+#define DART_U3 3
+#define DART_U4 4
+#define DART_WRITE 0x1
+#define DART_READ 0x2
+
+extern int dart_model;
+extern unsigned long dart_address;
+
+struct dart_ops {
+    void (*do_inv_all)(void);
+    void (*do_inv_entry)(ulong pg);
+};
+
+extern struct dart_ops *u3_init(ulong base, ulong table, ulong tpgs);
+extern struct dart_ops *u4_init(ulong base, ulong table, ulong tpgs);
+
+#endif /* _DART_H */
+
diff -r ffa41af2e455738f8fe3a0af8ae8952e9d4cc47c -r 
786d4a84bdad6467f780967e7725581f44678d9a xen/arch/ppc/dart_u4.c
--- /dev/null   Thu Jan  1 00:00:00 1970 +0000
+++ b/xen/arch/ppc/dart_u4.c    Fri Apr 28 17:44:52 2006 -0400
@@ -0,0 +1,175 @@
+/*
+ * 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
+ */
+
+#undef DEBUG
+
+#include <xen/config.h>
+#include <xen/types.h>
+#include <xen/sched.h>
+#include <xen/init.h>
+#include <xen/mm.h>
+#include <public/xen.h>
+#include <asm/io.h>
+#include <asm/current.h>
+#include "tce.h"
+#include "iommu.h"
+#include "dart.h"
+
+#define TOO_MANY_RETRIES ~0
+
+union dart_ctl {
+    u32 dc_word;
+    struct {
+        u32 dc_darten:1;      /* DART Enable (0:disabled) */
+        u32 dc_ione:1;        /* Invalidate one DART TLB entry (using ILPN) */
+        u32 dc_iall:1;        /* Invalidate all DART TLB entries */
+        u32 dc_idle:1;        /* DART is idle */
+        u32 dc_peen:1;        /* Parity Checking is enabled */
+        u32 dc_ilpn:27;       /* 27-bit Logical Page Address for 
+                               * invalidating one TLB entry */
+    } dc_bits;
+};
+
+union dart_base {
+    u32 db_word;
+    struct {
+        u32 _db_resv:8;
+        u32 db_dartbase:24;     /* Base Address of DART (4K byte Alignment) */
+    } db_bits;
+};
+
+union dart_size {
+    u32 ds_word;
+    struct {
+        u32 _ds_resv:15;
+        u32 ds_dartsize:17;     /* Size of Dart in 4K-Byte Pages */
+    } ds_bits;
+};
+
+union dart_excp {
+    u32 de_word;
+    struct {
+        u32 de_rqsrc:1;    /* Request Source.  [0:PCIE, 1:HT] */
+        u32 de_lpn:27;     /* 27Ðbit Logical Address of Exception [25:51] */
+        u32 de_rqop:1;     /* Request operation.  [0:Read, 1:Write] */
+        u32 de_xcd:3;      /* Exception code */
+    } de_bits;
+};
+
+struct dart {
+    /* 0x00 */
+    union dart_ctl d_dartcntl;
+    u32 _pad0x04_0x10[3];
+    /* 0x10 */
+    union dart_base d_dartbase;
+    u32 _pad0x14_0x20[3];
+    /* 0x20 */
+    union dart_size d_dartsize;
+    u32 _pad0x24_0x30[3];
+    /* 0x30 */
+    union dart_excp d_dartexcp;
+    u32 _pad0x34_0x40[3];
+};
+
+static volatile struct dart *dart;
+
+static void u4_inv_all(void)
+{
+    union dart_ctl dc;
+    ulong r = 0;
+    int l = 0;
+
+    for (;;) {
+        dc.dc_word = in_32(&dart->d_dartcntl.dc_word);
+        dc.dc_bits.dc_iall = 1;
+        out_32(&dart->d_dartcntl.dc_word, dc.dc_word);
+
+        do {
+            dc.dc_word = in_32(&dart->d_dartcntl.dc_word);
+            r++;
+        } while ((dc.dc_bits.dc_iall == 1) && (r < (1 << l)));
+
+        if (r == (1 << l)) {
+            if (l < 4) {
+                l++;
+                dc.dc_word = in_32(&dart->d_dartcntl.dc_word);
+                dc.dc_bits.dc_iall = 0;
+                out_32(&dart->d_dartcntl.dc_word, dc.dc_word);
+                continue;
+            } else {
+                panic(" broken U4???\n");
+            }
+        }
+        return;
+    }
+}
+
+static void u4_inv_entry(ulong pgn)
+{
+    union dart_ctl dc;
+    ulong retries = 0;
+
+    dc.dc_word = in_32(&dart->d_dartcntl.dc_word);
+    dc.dc_bits.dc_ilpn = pgn;
+    dc.dc_bits.dc_ione = 1;
+    out_32(&dart->d_dartcntl.dc_word, dc.dc_word);
+
+    /* wait for completion */
+    /* FIXME: since we do this from the HV do we need to wait?! */
+    do {
+        dc.dc_word = in_32(&dart->d_dartcntl.dc_word);
+        retries++;
+        if (retries > 1000000)
+            panic("WAY! too long\n");
+    } while (dc.dc_bits.dc_ione != 0);
+}
+
+static struct dart_ops u4_ops = {
+    .do_inv_all = u4_inv_all,
+    .do_inv_entry = u4_inv_entry,
+};
+
+struct dart_ops *u4_init(ulong base, ulong table, ulong tpgs)
+{
+    union dart_base db;
+    union dart_size ds;
+    union dart_ctl dc;
+
+    dart = (struct dart *)base;
+
+    db.db_word = 0;
+    db.db_bits.db_dartbase = table >> PAGE_SHIFT;
+
+    ds.ds_word = 0;
+    ds.ds_bits.ds_dartsize = tpgs;
+
+    dc.dc_word = 0;
+    dc.dc_bits.dc_darten = 1;
+
+    /* make sure its disabled */
+    out_32(&dart->d_dartcntl.dc_word, 0);
+
+    printk("Initializing DART Model U4: ctl: 0x%x base: 0x%x size: 0x%x\n",
+           dc.dc_word, db.db_word, ds.ds_word);
+
+    out_32(&dart->d_dartbase.db_word, db.db_word);
+    out_32(&dart->d_dartsize.ds_word, ds.ds_word);
+    out_32(&dart->d_dartcntl.dc_word, dc.dc_word);
+
+    return &u4_ops;
+}



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

<Prev in Thread] Current Thread [Next in Thread>
  • [XenPPC] [pushed] [ppc] U4 DART enablement for JS21, jimix <=