commit-gnuradio
[Top][All Lists]
Advanced

[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);
            }
          }
        }





reply via email to

[Prev in Thread] Current Thread [Next in Thread]