[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Commit-gnuradio] r7665 - in gnuradio/branches/developers/eb/gcell/src:
From: |
eb |
Subject: |
[Commit-gnuradio] r7665 - in gnuradio/branches/developers/eb/gcell/src: lib lib/spu spu-include |
Date: |
Wed, 13 Feb 2008 16:05:10 -0700 (MST) |
Author: eb
Date: 2008-02-13 16:05:09 -0700 (Wed, 13 Feb 2008)
New Revision: 7665
Added:
gnuradio/branches/developers/eb/gcell/src/lib/spu/gcell_spu_main.c
Removed:
gnuradio/branches/developers/eb/gcell/src/lib/spu/test_spu.c
Modified:
gnuradio/branches/developers/eb/gcell/src/lib/gc_job_manager_impl.cc
gnuradio/branches/developers/eb/gcell/src/lib/spu/Makefile.am
gnuradio/branches/developers/eb/gcell/src/lib/spu/gc_spu_jd_queue.c
gnuradio/branches/developers/eb/gcell/src/spu-include/gc_jd_queue.h
Log:
now using Lock-Line Reservation Lost event
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-13 21:27:15 UTC (rev 7664)
+++ gnuradio/branches/developers/eb/gcell/src/lib/gc_job_manager_impl.cc
2008-02-13 23:05:09 UTC (rev 7665)
@@ -216,7 +216,7 @@
// get a handle to the spe program
// FIXME pass this in (or something)
- const char *spu_progname = "../lib/spu/test_spu";
+ const char *spu_progname = "../lib/spu/gcell_spu_main";
spe_program_handle_t *spe_image = spe_image_open(spu_progname);
if (spe_image == 0){
Modified: gnuradio/branches/developers/eb/gcell/src/lib/spu/Makefile.am
===================================================================
--- gnuradio/branches/developers/eb/gcell/src/lib/spu/Makefile.am
2008-02-13 21:27:15 UTC (rev 7664)
+++ gnuradio/branches/developers/eb/gcell/src/lib/spu/Makefile.am
2008-02-13 23:05:09 UTC (rev 7665)
@@ -54,4 +54,4 @@
LDADD = libgcell_spu.a
noinst_PROGRAMS = \
- test_spu
+ gcell_spu_main
Modified: gnuradio/branches/developers/eb/gcell/src/lib/spu/gc_spu_jd_queue.c
===================================================================
--- gnuradio/branches/developers/eb/gcell/src/lib/spu/gc_spu_jd_queue.c
2008-02-13 21:27:15 UTC (rev 7664)
+++ gnuradio/branches/developers/eb/gcell/src/lib/spu/gc_spu_jd_queue.c
2008-02-13 23:05:09 UTC (rev 7665)
@@ -81,3 +81,16 @@
return true;
}
+
+void
+gc_jd_queue_getllar(gc_eaddr_t q)
+{
+ // get reservation that includes the tail of the queue
+ gc_eaddr_t tail = q + offsetof(gc_jd_queue_t, tail);
+
+ char _tmp[256];
+ char *buf = (char *) ALIGN(_tmp, 128); // get cache-aligned buffer
+
+ mfc_getllar(buf, ALIGN128_EA(tail), 0, 0);
+ spu_readch(MFC_RdAtomicStat);
+}
Copied: gnuradio/branches/developers/eb/gcell/src/lib/spu/gcell_spu_main.c
(from rev 7662, gnuradio/branches/developers/eb/gcell/src/lib/spu/test_spu.c)
===================================================================
--- gnuradio/branches/developers/eb/gcell/src/lib/spu/gcell_spu_main.c
(rev 0)
+++ gnuradio/branches/developers/eb/gcell/src/lib/spu/gcell_spu_main.c
2008-02-13 23:05:09 UTC (rev 7665)
@@ -0,0 +1,283 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdio.h>
+#include <spu_intrinsics.h>
+#include <spu_mfcio.h>
+#include <sync_utils.h>
+#include "gc_spu_args.h"
+#include "gc_job_desc.h"
+#include "gc_mbox.h"
+#include "sys_tags.h"
+#include "gc_jd_queue.h"
+#include "gc_methods.h"
+#include "gc_delay.h"
+
+static gc_spu_args_t spu_args;
+
+// our working copy of the completion info
+static gc_comp_info_t comp_info = {
+ .in_use = 1,
+ .ncomplete = 0
+};
+
+static int ci_idx = 0; // index of current comp_info
+static int ci_tags; // two consecutive dma tags
+
+// ------------------------------------------------------------------------
+
+/*
+ * Wait until EA copy of comp_info[idx].in_use is 0
+ */
+static void
+wait_for_ppe_to_be_done_with_comp_info(int idx)
+{
+ char _tmp[256];
+ char *buf = (char *) ALIGN(_tmp, 128); // get cache-aligned buffer
+ gc_comp_info_t *p = (gc_comp_info_t *) buf;
+
+ do {
+ mfc_getllar(buf, spu_args.comp_info[idx], 0, 0);
+ spu_readch(MFC_RdAtomicStat);
+ if (p->in_use == 0)
+ return;
+
+ gc_udelay(5); // FIXME use the "lock-line reservation lost" event
+
+ } while (1);
+}
+
+static void
+flush_completion_info(void)
+{
+ if (comp_info.ncomplete == 0)
+ return;
+
+ if (0){
+ static int total_jobs = 0;
+ static int total_msgs = 0;
+ total_msgs++;
+ total_jobs += comp_info.ncomplete;
+ printf("spe[%2d]: tj = %6d tm = %6d\n", spu_args.spu_idx,
+ total_jobs, total_msgs);
+ }
+
+ // ensure that PPE is done with the buffer we're about to overwrite
+ wait_for_ppe_to_be_done_with_comp_info(ci_idx);
+
+ // dma the comp_info out to PPE
+ int tag = ci_tags + ci_idx;
+ mfc_putf(&comp_info, spu_args.comp_info[ci_idx], sizeof(gc_comp_info_t),
tag, 0, 0);
+ mfc_write_tag_mask(1 << tag); // the tag we're interested in
+ mfc_read_tag_status_all(); // wait for DMA to complete
+
+ // send it a message
+ spu_writech(SPU_WrOutIntrMbox, MK_MBOX_MSG(OP_JOBS_DONE, ci_idx));
+
+ ci_idx ^= 0x1; // switch buffers
+ comp_info.in_use = 1;
+ comp_info.ncomplete = 0;
+}
+
+// ------------------------------------------------------------------------
+
+static unsigned int backoff; // current backoff value in clock cycles
+static unsigned int _backoff_start;
+static unsigned int _backoff_cap;
+
+/*
+ * For 3.2 GHz SPE
+ *
+ * 12 4095 cycles 1.3 us
+ * 13 8191 cycles 2.6 us
+ * 14 16383 cycles 5.1 us
+ * 15 32767 cycles 10.2 us
+ * 16 20.4 us
+ * 17 40.8 us
+ * 18 81.9 us
+ * 19 163.8 us
+ * 20 327.7 us
+ * 21 655.4 us
+ */
+static unsigned char log2_backoff_start[16] = {
+ 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 16, 16
+};
+
+static unsigned char log2_backoff_cap[16] = {
+ 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 21, 21
+};
+
+void
+backoff_init(void)
+{
+ _backoff_cap = (1 << (log2_backoff_cap[(spu_args.nspus - 1) & 0xf])) - 1;
+ _backoff_start = (1 << (log2_backoff_start[(spu_args.nspus - 1) & 0xf])) - 1;
+
+ backoff = _backoff_start;
+}
+
+void
+backoff_reset(void)
+{
+ backoff = _backoff_start;
+}
+
+void
+backoff_delay(void)
+{
+ gc_cdelay(backoff);
+
+ // capped exponential backoff
+ backoff = ((backoff << 1) + 1) & _backoff_cap;
+}
+
+// ------------------------------------------------------------------------
+
+void
+process_job(gc_eaddr_t jd_ea, gc_job_desc_t *jd)
+{
+ // FIXME do something useful ;)
+
+ if (0){
+ static int total_jobs = 0;
+ total_jobs++;
+ printf("spe[%2d]: tij =%6d\n", spu_args.spu_idx, total_jobs);
+ }
+
+ if (0)
+ printf("spu[%d]: job_id = %3d client_id = %3d\n",
+ spu_args.spu_idx, jd->sys.job_id, jd->sys.client_id);
+
+ jd->status = JS_OK; // assume success
+
+ switch(jd->method){ // FIXME lookup method
+
+ case GCM_NOP:
+ break;
+
+ case GCM_UDELAY:
+ gc_udelay(jd->input.dir_val[0].u32);
+ break;
+
+ default:
+ jd->status = JS_UNKNOWN_METHOD;
+ break;
+ }
+
+ // FIXME copy indirect args in
+ // FIXME invoke method
+ // FIXME copy indirect args out
+ // FIXME copy jd back out
+
+
+ // Tell PPE we're done with the job.
+ //
+ // We queue these up until we run out of room, or until we can send
+ // the info to the PPE w/o blocking. The blocking check is in
+ // main_loop
+
+ comp_info.job_id[comp_info.ncomplete++] = jd->sys.job_id;
+
+ if (comp_info.ncomplete == GC_CI_NJOBS)
+ flush_completion_info();
+}
+
+void
+main_loop(void)
+{
+ static gc_job_desc_t jd; // static gets us proper alignment
+ gc_eaddr_t jd_ea;
+
+ // setup events
+ spu_writech(SPU_WrEventMask, MFC_LLR_LOST_EVENT);
+ gc_jd_queue_getllar(spu_args.queue); // get a line reservation on the queue
+
+ while (1){
+
+ if (unlikely(spu_readchcnt(SPU_RdEventStat))){
+ //
+ // execute standard event handling protocol prologue
+ //
+ int status = spu_readch(SPU_RdEventStat);
+ int mask = spu_readch(SPU_RdEventMask);
+ spu_writech(SPU_WrEventMask, mask & ~status); // disable active events
+ spu_writech(SPU_WrEventAck, status); // ack active events
+
+ // execute per-event actions
+
+ if (status & MFC_LLR_LOST_EVENT){
+ //
+ // We've lost a line reservation. This is most likely caused
+ // by somebody doing something to the queue. Go look and see
+ // if there's anything for us.
+ //
+ if (gc_jd_queue_dequeue(spu_args.queue, &jd_ea, &jd))
+ process_job(jd_ea, &jd);
+
+ gc_jd_queue_getllar(spu_args.queue); // get a new reservation
+ }
+
+ //
+ // execute standard event handling protocol epilogue
+ //
+ spu_writech(SPU_WrEventMask, mask); // restore event mask
+ }
+
+ // FIXME we could handle these via events too
+
+ // any msgs for us?
+
+ if (unlikely(spu_readchcnt(SPU_RdInMbox))){
+ int msg = spu_readch(SPU_RdInMbox);
+ // printf("spu[%d] mbox_msg: 0x%08x\n", spu_args.spu_idx, msg);
+ if (MBOX_MSG_OP(msg) == OP_EXIT){
+ flush_completion_info();
+ return;
+ }
+ }
+
+ // If we've got job completion info for the PPE and we can send a
+ // message without blocking, do it.
+
+ if (comp_info.ncomplete != 0 && spu_readchcnt(SPU_WrOutIntrMbox) != 0)
+ flush_completion_info();
+ }
+}
+
+
+int
+main(unsigned long long spe_id __attribute__((unused)),
+ unsigned long long argp,
+ unsigned long long envp __attribute__((unused)))
+{
+ sys_tags_init();
+ ci_tags = mfc_multi_tag_reserve(2);
+
+ // dma the args in
+ mfc_get(&spu_args, argp, sizeof(spu_args), sys_tag, 0, 0);
+ mfc_write_tag_mask(1 << sys_tag); // the tag we're interested in
+ mfc_read_tag_status_all(); // wait for DMA to complete
+
+ backoff_init(); // initialize backoff parameters
+
+ main_loop();
+ return 0;
+}
Deleted: gnuradio/branches/developers/eb/gcell/src/lib/spu/test_spu.c
Modified: gnuradio/branches/developers/eb/gcell/src/spu-include/gc_jd_queue.h
===================================================================
--- gnuradio/branches/developers/eb/gcell/src/spu-include/gc_jd_queue.h
2008-02-13 21:27:15 UTC (rev 7664)
+++ gnuradio/branches/developers/eb/gcell/src/spu-include/gc_jd_queue.h
2008-02-13 23:05:09 UTC (rev 7665)
@@ -42,6 +42,15 @@
bool
gc_jd_queue_dequeue(gc_eaddr_t q, gc_eaddr_t *item_ea, gc_job_desc_t *item);
+
+/*!
+ * \brief Get a line reservation on the queue
+ *
+ * \param[in] q is EA address of queue structure.
+ */
+void
+gc_jd_queue_getllar(gc_eaddr_t q);
+
__GC_END_DECLS
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Commit-gnuradio] r7665 - in gnuradio/branches/developers/eb/gcell/src: lib lib/spu spu-include,
eb <=