diff options
author | Ulrich Weigand <uweigand@de.ibm.com> | 2008-08-25 01:29:38 +0000 |
---|---|---|
committer | Ben Elliston <bje@au.ibm.com> | 2008-08-25 01:29:38 +0000 |
commit | 6fd1a617c27239058fd06aa4da81c48c4506fa5e (patch) | |
tree | 5ff002cab95157a66601fbb1250c1f4c33e2e282 | |
parent | 325cb4d4afbfa7d4f6a4cd26bd6d7fd027f2b81c (diff) |
* gcc/config/spu/cachemgr.c: Make interrupt safe and respect tag
mask policy.
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/cell-4_3-branch@139555 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | ChangeLog.cell | 5 | ||||
-rw-r--r-- | gcc/config/spu/cachemgr.c | 44 |
2 files changed, 44 insertions, 5 deletions
diff --git a/ChangeLog.cell b/ChangeLog.cell index 811020bd66a..11ec3eddc03 100644 --- a/ChangeLog.cell +++ b/ChangeLog.cell @@ -1,3 +1,8 @@ +2008-08-25 Ulrich Weigand <uweigand@de.ibm.com> + + * gcc/config/spu/cachemgr.c: Make interrupt safe and respect tag + mask policy. + 2008-08-20 Ben Elliston <bje@au.ibm.com> Backport from FSF mainline: diff --git a/gcc/config/spu/cachemgr.c b/gcc/config/spu/cachemgr.c index d2e87ea69f2..96d6e821a84 100644 --- a/gcc/config/spu/cachemgr.c +++ b/gcc/config/spu/cachemgr.c @@ -121,16 +121,28 @@ __cache_evict_entry (struct __cache_tag_array *entry, int way) if ((CHECK_DIRTY (entry->dirty_bits[way])) && (!CHECK_IS_LS (entry, way))) { -/* Non-atomic writes. */ #ifdef NONATOMIC + /* Non-atomic writes. */ + unsigned int oldmask, mach_stat; char *line = ((void *) 0); + /* Enter critical section. */ + mach_stat = spu_readch (SPU_RdMachStat); + spu_idisable (); + + /* Issue DMA request. */ line = GET_CACHE_LINE (entry->tag_lo[way], way); mfc_put (line, tag, LINE_SIZE, dma_tag, 0, 0); /* Wait for DMA completion. */ + oldmask = mfc_read_tag_mask (); mfc_write_tag_mask (1 << dma_tag); mfc_read_tag_status_all (); + mfc_write_tag_mask (oldmask); + + /* Leave critical section. */ + if (__builtin_expect (mach_stat & 1, 0)) + spu_ienable (); #else /* Allocate a buffer large enough that we know it has 128 bytes that are 128 byte aligned (for DMA). */ @@ -139,6 +151,11 @@ __cache_evict_entry (struct __cache_tag_array *entry, int way) qword *buf_ptr = (qword *) (((unsigned int) (buffer) + 127) & ~127); qword *line = GET_CACHE_LINE (entry->tag_lo[way], way); qword bits; + unsigned int mach_stat; + + /* Enter critical section. */ + mach_stat = spu_readch (SPU_RdMachStat); + spu_idisable (); do { @@ -183,6 +200,10 @@ __cache_evict_entry (struct __cache_tag_array *entry, int way) mfc_putllc (buf_ptr, tag, 0, 0); } while (mfc_read_atomic_status ()); + + /* Leave critical section. */ + if (__builtin_expect (mach_stat & 1, 0)) + spu_ienable (); #endif } @@ -213,18 +234,31 @@ __cache_evict (__ea void *ea) static void * __cache_fill (int way, addr tag) { + unsigned int oldmask, mach_stat; char *line = ((void *) 0); - line = GET_CACHE_LINE (tag, way); - - /* This will use DMA to fill the cache line. */ - + /* Reserve our DMA tag. */ if (dma_tag == 32) dma_tag = mfc_tag_reserve (); + /* Enter critical section. */ + mach_stat = spu_readch (SPU_RdMachStat); + spu_idisable (); + + /* Issue DMA request. */ + line = GET_CACHE_LINE (tag, way); mfc_get (line, tag, LINE_SIZE, dma_tag, 0, 0); + + /* Wait for DMA completion. */ + oldmask = mfc_read_tag_mask (); mfc_write_tag_mask (1 << dma_tag); mfc_read_tag_status_all (); + mfc_write_tag_mask (oldmask); + + /* Leave critical section. */ + if (__builtin_expect (mach_stat & 1, 0)) + spu_ienable (); + return (void *) line; } |