# 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
|