# HG changeset patch
# User Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
# Node ID f5a949e9ea5e8c5b9e1745ac798edeebf941fee3
# Parent 987eeb2da8c3a5089d03f65cd17541d542dd5e7e
[ppc] Fix U4 DART (aka RTFM)
The patch coreects the U4 DART permission bits which when set do _not_
permit acces but protect the access. This is what has caused us to
not be able to probe hardware.
We also make it clear exactly how bit the DART is to avoid future confusion.
JS21 Device discovery now works.
Signed-off-by: Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
---
xen/arch/ppc/dart.c | 84 +++++++++++++++++++++++++++++-----------------------
1 files changed, 48 insertions(+), 36 deletions(-)
diff -r 987eeb2da8c3 -r f5a949e9ea5e xen/arch/ppc/dart.c
--- a/xen/arch/ppc/dart.c Sun Jun 25 16:08:39 2006 -0400
+++ b/xen/arch/ppc/dart.c Sun Jun 25 16:16:23 2006 -0400
@@ -31,10 +31,17 @@
#undef DEBUG
#ifdef DEBUG
-static int first_put;
+#define DBG(fmt...) printk(fmt)
+static int dbg_after;
+#define DBG_SET_AFTER dbg_after = 1;
+#define DBG_AFTER(fmt...) if (dbg_after) DBG(fmt)
+#else
+#define DBG(fmt...)
+#define DBG_SET_AFTER
+#define DBG_AFTER(fmt...)
#endif
-#define DART_SHIFT 21
+#define U3_LOG_MAX 21
int dart_model;
unsigned long dart_address;
@@ -53,8 +60,8 @@ union dart_tce {
u32 dt_word;
struct {
u32 dt_v:1; /* valid */
- u32 dt_r:1; /* read */
- u32 dt_w:1; /* write */
+ 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
* representing address [28:51] */
@@ -69,11 +76,14 @@ static u32 dart_encode(int perm, ulong r
tce.dt_bits.dt_v = 1;
tce.dt_bits.dt_ppn = rpn;
+ /* protect the page */
+ tce.dt_bits.dt_rp = 1;
+ tce.dt_bits.dt_wp = 1;
if (perm & DART_READ) {
- tce.dt_bits.dt_r = 1;
+ tce.dt_bits.dt_rp = 0;
}
if (perm & DART_WRITE) {
- tce.dt_bits.dt_w = 1;
+ tce.dt_bits.dt_wp = 0;
}
return tce.dt_word;
@@ -122,9 +132,8 @@ static int dart_put(ulong ioba, union tc
static int dart_put(ulong ioba, union tce tce)
{
ulong index = ioba >> PAGE_SHIFT;
- int perm = 0;
-
- if (index > (1 << DART_SHIFT) / sizeof(u32)) {
+
+ if (index > (1 << U3_LOG_MAX) / sizeof(u32)) {
return -1;
}
@@ -132,26 +141,29 @@ static int dart_put(ulong ioba, union tc
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
+ if (tce.tce_bits.tce_read == 0 &&
+ tce.tce_bits.tce_write == 0) {
+ /* the TCE table is inited by the domain by a bunch of 0
+ * perminssion puts. We are only interesting in debugging the
+ * ones after the first put */
+ DBG_AFTER(">DART[0x%lx] clear\n", index);
+ dart_clear(index, 1);
+ } else {
+ unsigned perm = 0;
+
+ if (tce.tce_bits.tce_read)
+ perm |= DART_READ;
+ if (tce.tce_bits.tce_write)
+ perm |= DART_WRITE;
+
+ DBG("<DART[0x%lx]: ioba: 0x%lx perm:%x[%c%c] rpn:0x%lx\n",
+ index, ioba, perm,
+ (perm & DART_READ) ? 'R' : '-',
+ (perm & DART_WRITE) ? 'W' : '-',
+ (ulong)tce.tce_bits.tce_rpn);
+ DBG_SET_AFTER;
+
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);
@@ -211,14 +223,14 @@ static int find_dart()
static int init_dart(void)
{
- ulong tpgs;
+ ulong log_pgs;
if (find_dart())
return 0;
- /* Max size of 512 pages == 2MB == 1<<21 */
- tpgs = DART_SHIFT - PAGE_SHIFT;
- dart_table = alloc_xenheap_pages(tpgs);
+ /* Max size of 512 pages == 2MB == 1<<21. That siz is good enough for U4 */
+ log_pgs = U3_LOG_MAX - PAGE_SHIFT;
+ dart_table = alloc_xenheap_pages(log_pgs);
/* Linux uses a dummy page, filling "empty" DART entries with a
reference to this page to capture stray DMA's */
@@ -226,7 +238,7 @@ static int init_dart(void)
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),
+ dart_address, (ulong)dart_table, (1 << U3_LOG_MAX) / sizeof(u32),
dummy_page);
/* register this iommu */
@@ -234,14 +246,14 @@ static int init_dart(void)
switch (dart_model) {
case DART_U3:
- dops = u3_init(dart_address, (ulong)dart_table, tpgs);
+ dops = u3_init(dart_address, (ulong)dart_table, 1UL << log_pgs);
break;
case DART_U4:
- dops = u4_init(dart_address, (ulong)dart_table, tpgs);
+ dops = u4_init(dart_address, (ulong)dart_table, 1UL << log_pgs);
break;
}
- dart_clear(0, (1 << DART_SHIFT) / sizeof(u32));
+ dart_clear(0, (1 << U3_LOG_MAX) / sizeof(u32));
dops->do_inv_all();
printk("%s: done!\n", __func__);
return 0;
_______________________________________________
Xen-ppc-devel mailing list
Xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ppc-devel
|