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
|