[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Commit-gnuradio] r7850 - in gnuradio/branches/developers/eb/gcell/src:
From: |
eb |
Subject: |
[Commit-gnuradio] r7850 - in gnuradio/branches/developers/eb/gcell/src: include lib lib/spu |
Date: |
Tue, 26 Feb 2008 16:14:44 -0700 (MST) |
Author: eb
Date: 2008-02-26 16:14:44 -0700 (Tue, 26 Feb 2008)
New Revision: 7850
Modified:
gnuradio/branches/developers/eb/gcell/src/include/gc_proc_ids_private.h
gnuradio/branches/developers/eb/gcell/src/lib/gc_job_manager_impl.cc
gnuradio/branches/developers/eb/gcell/src/lib/qa_job_manager.cc
gnuradio/branches/developers/eb/gcell/src/lib/qa_job_manager.h
gnuradio/branches/developers/eb/gcell/src/lib/spu/gc_spu_procs.c
gnuradio/branches/developers/eb/gcell/src/lib/spu/gcell_spu_main.c
Log:
work-in-progress on SPE -> PPE args. Now passes QA
Modified:
gnuradio/branches/developers/eb/gcell/src/include/gc_proc_ids_private.h
===================================================================
--- gnuradio/branches/developers/eb/gcell/src/include/gc_proc_ids_private.h
2008-02-26 23:02:49 UTC (rev 7849)
+++ gnuradio/branches/developers/eb/gcell/src/include/gc_proc_ids_private.h
2008-02-26 23:14:44 UTC (rev 7850)
@@ -25,9 +25,10 @@
// This file will be removed as soon as we've got the real code working.
-#define GCP_QA_NOP 0 // do nothing
-#define GCP_QA_UDELAY 1 // delay by arg[0] microseconds
-#define GCP_QA_SUM_SHORTS 2 // sum elements of ea.arg[i], return
in output.arg[i].s32
+#define GCP_QA_NOP 0 // do nothing
+#define GCP_QA_UDELAY 1 // delay by arg[0] microseconds
+#define GCP_QA_SUM_SHORTS 2 // sum elements of ea.arg[i], return in
output.arg[i].s32
+#define GCP_QA_PUT_SEQ 3 // write seq of chars to ea.arg[i],
initial value in input.arg[0].s32
#define GCP_NPROC_IDS 16
Modified: gnuradio/branches/developers/eb/gcell/src/lib/gc_job_manager_impl.cc
===================================================================
--- gnuradio/branches/developers/eb/gcell/src/lib/gc_job_manager_impl.cc
2008-02-26 23:02:49 UTC (rev 7849)
+++ gnuradio/branches/developers/eb/gcell/src/lib/gc_job_manager_impl.cc
2008-02-26 23:14:44 UTC (rev 7850)
@@ -1152,7 +1152,8 @@
static struct name_map name_map[] = {
{ "qa_nop", GCP_QA_NOP },
{ "qa_udelay", GCP_QA_UDELAY },
- { "qa_sum_shorts", GCP_QA_SUM_SHORTS }
+ { "qa_sum_shorts", GCP_QA_SUM_SHORTS },
+ { "qa_put_seq", GCP_QA_PUT_SEQ }
};
static const size_t nname_map_entries = sizeof(name_map) / sizeof(name_map[0]);
Modified: gnuradio/branches/developers/eb/gcell/src/lib/qa_job_manager.cc
===================================================================
--- gnuradio/branches/developers/eb/gcell/src/lib/qa_job_manager.cc
2008-02-26 23:02:49 UTC (rev 7849)
+++ gnuradio/branches/developers/eb/gcell/src/lib/qa_job_manager.cc
2008-02-26 23:14:44 UTC (rev 7850)
@@ -101,7 +101,7 @@
void
qa_job_manager::t5()
{
- leak_check(&qa_job_manager::t5_body, "t3");
+ leak_check(&qa_job_manager::t5_body, "t5");
}
void
@@ -134,6 +134,36 @@
leak_check(&qa_job_manager::t10_body, "t10");
}
+void
+qa_job_manager::t11()
+{
+ leak_check(&qa_job_manager::t11_body, "t11");
+}
+
+void
+qa_job_manager::t12()
+{
+ leak_check(&qa_job_manager::t12_body, "t12");
+}
+
+void
+qa_job_manager::t13()
+{
+ leak_check(&qa_job_manager::t13_body, "t13");
+}
+
+void
+qa_job_manager::t14()
+{
+ leak_check(&qa_job_manager::t14_body, "t14");
+}
+
+void
+qa_job_manager::t15()
+{
+ leak_check(&qa_job_manager::t15_body, "t15");
+}
+
// ----------------------------------------------------------------
void
@@ -432,8 +462,121 @@
delete mgr;
}
+static bool
+confirm_const(const unsigned char *buf, size_t len, unsigned char v)
+{
+ bool ok = true;
+
+ for (size_t i = 0; i < len; i++){
+ if (buf[i] != v){
+ ok = false;
+ printf("confirm_const: buf[%6d] = 0x%02x, expected = 0x%02x\n",
+ i, buf[i], v);
+ }
+ }
+
+ return ok;
+}
+
+static bool
+confirm_seq(const unsigned char *buf, size_t len, unsigned char v)
+{
+ bool ok = true;
+
+ for (size_t i = 0; i < len; i++, v++){
+ if (buf[i] != v){
+ ok = false;
+ printf("confirm_seq: buf[%6d] = 0x%02x, expected = 0x%02x\n",
+ i, buf[i], v);
+ }
+ }
+
+ return ok;
+}
+
+static void
+test_put_seq(gc_job_manager *mgr, int offset, int len, int starting_val)
+{
+ gc_job_desc *jd = mgr->alloc_job_desc();
+ gc_proc_id_t gcp_qa_put_seq = mgr->lookup_proc("qa_put_seq");
+
+ unsigned char *buf = (unsigned char *) short_buf;
+ size_t buf_len = sizeof(short_buf);
+ memset(buf, 0xff, buf_len);
+
+ // two cache lines into the buffer, so we can check before and after
+ int fixed_offset = 256;
+
+ init_jd(jd, gcp_qa_put_seq);
+ jd->input.nargs = 1;
+ jd->input.arg[0].s32 = starting_val;
+ jd->eaa.nargs = 1;
+ jd->eaa.arg[0].ea_addr = ptr_to_ea(buf + fixed_offset + offset);
+ jd->eaa.arg[0].direction = GCJD_DMA_PUT;
+ jd->eaa.arg[0].put_size = len;
+
+ if (!mgr->submit_job(jd)){
+ printf("%d: submit_job(jd) failed, status = %d\n", __LINE__, jd->status);
+ }
+ else {
+ mgr->wait_job(jd);
+ CPPUNIT_ASSERT_EQUAL(JS_OK, jd->status);
+
+ // check before
+ CPPUNIT_ASSERT(confirm_const(&buf[0], fixed_offset + offset, 0xff));
+
+ // check sequence
+ CPPUNIT_ASSERT(confirm_seq(&buf[fixed_offset + offset], len,
starting_val));
+
+ // check after
+ CPPUNIT_ASSERT(confirm_const(&buf[fixed_offset + offset + len],
+ buf_len - fixed_offset - offset - len, 0xff));
+ }
+ mgr->free_job_desc(jd);
+}
+
+//
+// Test all "get" alignments and sizes
+//
void
qa_job_manager::t10_body()
{
+ gc_job_manager *mgr;
+ gc_jm_options opts;
+ int starting_val = 13;
+ opts.nspes = 1;
+ mgr = gc_make_job_manager(&opts);
+
+ for (int offset = 0; offset <= 256; offset++){
+ for (int len = 0; len <= 256; len++){
+ test_put_seq(mgr, offset, len, starting_val++);
+ }
+ }
+
+ delete mgr;
}
+void
+qa_job_manager::t11_body()
+{
+}
+
+void
+qa_job_manager::t12_body()
+{
+}
+
+void
+qa_job_manager::t13_body()
+{
+}
+
+void
+qa_job_manager::t14_body()
+{
+}
+
+void
+qa_job_manager::t15_body()
+{
+}
Modified: gnuradio/branches/developers/eb/gcell/src/lib/qa_job_manager.h
===================================================================
--- gnuradio/branches/developers/eb/gcell/src/lib/qa_job_manager.h
2008-02-26 23:02:49 UTC (rev 7849)
+++ gnuradio/branches/developers/eb/gcell/src/lib/qa_job_manager.h
2008-02-26 23:14:44 UTC (rev 7850)
@@ -42,6 +42,11 @@
CPPUNIT_TEST(t8);
CPPUNIT_TEST(t9);
CPPUNIT_TEST(t10);
+ CPPUNIT_TEST(t11);
+ CPPUNIT_TEST(t12);
+ CPPUNIT_TEST(t13);
+ CPPUNIT_TEST(t14);
+ CPPUNIT_TEST(t15);
CPPUNIT_TEST_SUITE_END();
private:
@@ -68,6 +73,16 @@
void t9_body();
void t10();
void t10_body();
+ void t11();
+ void t11_body();
+ void t12();
+ void t12_body();
+ void t13();
+ void t13_body();
+ void t14();
+ void t14_body();
+ void t15();
+ void t15_body();
};
Modified: gnuradio/branches/developers/eb/gcell/src/lib/spu/gc_spu_procs.c
===================================================================
--- gnuradio/branches/developers/eb/gcell/src/lib/spu/gc_spu_procs.c
2008-02-26 23:02:49 UTC (rev 7849)
+++ gnuradio/branches/developers/eb/gcell/src/lib/spu/gc_spu_procs.c
2008-02-26 23:14:44 UTC (rev 7850)
@@ -28,14 +28,14 @@
// FIXME move these out of here; only for QA usage
-void
+static void
gcp_qa_nop(const gc_job_direct_args_t *input _UNUSED,
gc_job_direct_args_t *output _UNUSED,
const gc_job_ea_args_t *eaa _UNUSED)
{
}
-void
+static void
gcp_qa_udelay(const gc_job_direct_args_t *input,
gc_job_direct_args_t *output _UNUSED,
const gc_job_ea_args_t *eaa _UNUSED)
@@ -53,7 +53,7 @@
return total;
}
-void
+static void
gcp_qa_sum_shorts(const gc_job_direct_args_t *input _UNUSED,
gc_job_direct_args_t *output,
const gc_job_ea_args_t *eaa)
@@ -66,10 +66,33 @@
}
}
+static void
+write_seq(unsigned char *p, int nbytes, int counter)
+{
+ for (int i = 0; i < nbytes; i++)
+ p[i] = counter++;
+}
+static void
+gcp_qa_put_seq(const gc_job_direct_args_t *input,
+ gc_job_direct_args_t *output _UNUSED,
+ const gc_job_ea_args_t *eaa)
+{
+ int counter = input->arg[0].s32;
+
+ for (unsigned int i = 0; i < eaa->nargs; i++){
+ unsigned char *p = eaa->arg[i].ls_addr;
+ int n = eaa->arg[i].put_size;
+ write_seq(p, n, counter);
+ counter += n;
+ }
+}
+
+
gc_spu_proc_t gc_proc_table[GCP_NPROC_IDS] = {
[GCP_QA_NOP] = gcp_qa_nop,
[GCP_QA_UDELAY] = gcp_qa_udelay,
[GCP_QA_SUM_SHORTS] = gcp_qa_sum_shorts,
+ [GCP_QA_PUT_SEQ] = gcp_qa_put_seq,
};
Modified: gnuradio/branches/developers/eb/gcell/src/lib/spu/gcell_spu_main.c
===================================================================
--- gnuradio/branches/developers/eb/gcell/src/lib/spu/gcell_spu_main.c
2008-02-26 23:02:49 UTC (rev 7849)
+++ gnuradio/branches/developers/eb/gcell/src/lib/spu/gcell_spu_main.c
2008-02-26 23:14:44 UTC (rev 7850)
@@ -198,6 +198,67 @@
// ------------------------------------------------------------------------
+//
+// Handle the nasty case of a dma xfer that's less than 16 bytes long
+// len is guaranteed to be in [1, 15]
+
+static inline unsigned int
+make_mask(int nbits)
+{
+ return ~(~0 << nbits);
+}
+
+// divide and conquer
+static void
+d_and_c(unsigned int work, unsigned int offset, unsigned int len,
+ int put_tag, unsigned char *ls_base, gc_eaddr_t ea_base)
+{
+ unsigned int mask = make_mask(len) << offset;
+ unsigned int t = mask & work;
+ if (t == 0) // nothing to do
+ return;
+ if (t == mask){ // got a match, generate dma
+ mfc_put(ls_base + offset, ea_base + offset, len, put_tag, 0, 0);
+ }
+ else {
+ len >>= 1;
+ d_and_c(work, offset, len, put_tag, ls_base, ea_base);
+ d_and_c(work, offset + len, len, put_tag, ls_base, ea_base);
+ }
+}
+
+static void
+handle_slow_and_tedious_dma(gc_eaddr_t ea, unsigned char *ls, unsigned int
len, int put_tag)
+{
+ unsigned int t = (((uintptr_t) ls) | len) & 0x7;
+ if (1 && t == 0){ // 8 byte aligned and len is multiple of 8
+ mfc_put(ls, ea, 8, put_tag, 0, 0);
+ }
+ else if (1 && t == 4){ // 4-byte aligned and len is a multiple of 4
+ switch (len){
+ case 12:
+ mfc_put(ls + 8, ea + 8, 4, put_tag, 0, 0);
+ case 8:
+ mfc_put(ls + 4, ea + 4, 4, put_tag, 0, 0);
+ case 4:
+ mfc_put(ls + 0, ea + 0, 4, put_tag, 0, 0);
+ break;
+ }
+ }
+ else {
+ // general case (divide and conquer)
+ unsigned int alignment = ((uintptr_t) ls) & 0x7;
+ unsigned int work = make_mask(len) << alignment;
+ unsigned char *ls_base = (unsigned char *) ROUND_DN((uintptr_t) ls, 8);
+ gc_eaddr_t ea_base = ROUND_DN(ea, (gc_eaddr_t) 8);
+
+ d_and_c(work, 0, 8, put_tag, ls_base, ea_base);
+ d_and_c(work, 8, 8, put_tag, ls_base, ea_base);
+ d_and_c(work, 16, 8, put_tag, ls_base, ea_base);
+ }
+}
+
+
void
process_job(gc_eaddr_t jd_ea, gc_job_desc_t *jd)
{
@@ -370,96 +431,105 @@
gc_eaddr_t ea;
unsigned char *ls;
- int len;
+ unsigned int len;
ea = eaa->arg[i].ea_addr;
ls = (unsigned char *) eaa->arg[i].ls_addr;
len = eaa->arg[i].put_size;
- if ((ea & 0xf) != 0){
+ if (len < 16)
+ handle_slow_and_tedious_dma(ea, ls, len, put_tag);
+
+ else {
+ if ((ea & 0xf) != 0){
- // handle the "pre-multiple-of-16" portion
- // do 1, 2, 4, or 8 byte xfers as required
+ // printf("1: ea = 0x%x len = %5d\n", (int) ea, len);
+
+ // handle the "pre-multiple-of-16" portion
+ // do 1, 2, 4, or 8 byte xfers as required
- if ((ea & 0x1) && len >= 1){ // do a 1-byte xfer
- mfc_put(ls, ea, 1, put_tag, 0, 0);
- ea += 1;
- ls += 1;
- len -= 1;
+ if (ea & 0x1){ // do a 1-byte
xfer
+ mfc_put(ls, ea, 1, put_tag, 0, 0);
+ ea += 1;
+ ls += 1;
+ len -= 1;
+ }
+ if (ea & 0x2){ // do a 2-byte
xfer
+ mfc_put(ls, ea, 2, put_tag, 0, 0);
+ ea += 2;
+ ls += 2;
+ len -= 2;
+ }
+ if (ea & 0x4){ // do a 4-byte
xfer
+ mfc_put(ls, ea, 4, put_tag, 0, 0);
+ ea += 4;
+ ls += 4;
+ len -= 4;
+ }
+ if (ea & 0x8){ // do an 8-byte
xfer
+ mfc_put(ls, ea, 8, put_tag, 0, 0);
+ ea += 8;
+ ls += 8;
+ len -= 8;
+ }
}
- if ((ea & 0x2) && len >= 2){ // do a 2-byte xfer
- mfc_put(ls, ea, 2, put_tag, 0, 0);
- ea += 2;
- ls += 2;
- len -= 2;
+
+ if (1){
+ // printf("2: ea = 0x%x len = %5d\n", (int) ea, len);
+ assert((ea & 0xf) == 0);
+ assert((((intptr_t) ls) & 0xf) == 0);
}
- if ((ea & 0x4) && len >= 4){ // do a 4-byte xfer
- mfc_put(ls, ea, 4, put_tag, 0, 0);
- ea += 4;
- ls += 4;
- len -= 4;
- }
- if ((ea & 0x8) && len >= 8){ // do an 8-byte xfer
- mfc_put(ls, ea, 8, put_tag, 0, 0);
- ea += 8;
- ls += 8;
- len -= 8;
- }
- }
- if (1){
- assert((ea & 0xf) == 0);
- assert((((intptr_t) ls) & 0xf) == 0);
- }
+ // handle the "multiple-of-16" portion
- // handle the "multiple-of-16" portion
+ int aligned_len = ROUND_DN(len, 16);
+ len = len & (16 - 1);
- int aligned_len = ROUND_DN(len, 16);
- len = len & (16 - 1);
+ while (aligned_len != 0){
+ int dma_len = MIN(aligned_len, MFC_MAX_DMA_SIZE);
+ mfc_put(ls, ea, dma_len, put_tag, 0, 0);
+ ea += dma_len;
+ ls += dma_len;
+ aligned_len -= dma_len;
+ }
- while (aligned_len != 0){
- int dma_len = MIN(aligned_len, MFC_MAX_DMA_SIZE);
- mfc_put(ls, ea, dma_len, put_tag, 0, 0);
- ea += dma_len;
- ls += dma_len;
- aligned_len -= dma_len;
- }
+ if (1){
+ // printf("3: ea = 0x%x len = %5d\n", (int)ea, len);
+ assert((ea & 0xf) == 0);
+ assert((((intptr_t) ls) & 0xf) == 0);
+ }
- if (1){
- assert((ea & 0xf) == 0);
- assert((((intptr_t) ls) & 0xf) == 0);
- }
+ // handle "post-multiple-of-16" portion
- // handle "post-multiple-of-16" portion
+ if (len != 0){
- if (len != 0){
-
- if (len >= 8){ // do an 8-byte xfer
- mfc_put(ls, ea, 8, put_tag, 0, 0);
- ea += 8;
- ls += 8;
- len -= 8;
+ if (len >= 8){ // do an 8-byte xfer
+ mfc_put(ls, ea, 8, put_tag, 0, 0);
+ ea += 8;
+ ls += 8;
+ len -= 8;
+ }
+ if (len >= 4){ // do a 4-byte xfer
+ mfc_put(ls, ea, 4, put_tag, 0, 0);
+ ea += 4;
+ ls += 4;
+ len -= 4;
+ }
+ if (len >= 2){ // do a 2-byte xfer
+ mfc_put(ls, ea, 2, put_tag, 0, 0);
+ ea += 2;
+ ls += 2;
+ len -= 2;
+ }
+ if (len >= 1){ // do a 1-byte xfer
+ mfc_put(ls, ea, 1, put_tag, 0, 0);
+ ea += 1;
+ ls += 1;
+ len -= 1;
+ }
+ if (1)
+ assert(len == 0);
}
- if (len >= 4){ // do a 4-byte xfer
- mfc_put(ls, ea, 4, put_tag, 0, 0);
- ea += 4;
- ls += 4;
- len -= 4;
- }
- if (len >= 2){ // do a 2-byte xfer
- mfc_put(ls, ea, 2, put_tag, 0, 0);
- ea += 2;
- ls += 2;
- len -= 2;
- }
- if (len >= 1){ // do a 1-byte xfer
- mfc_put(ls, ea, 1, put_tag, 0, 0);
- ea += 1;
- ls += 1;
- len -= 1;
- }
- if (1)
- assert(len == 0);
}
}
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Commit-gnuradio] r7850 - in gnuradio/branches/developers/eb/gcell/src: include lib lib/spu,
eb <=