This is the mail archive of the ecos-bugs@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug 19695] New: Different semantics of cache lock feature of TX39


http://bugs.ecos.sourceware.org/show_bug.cgi?id=19695

           Summary: Different semantics of cache lock feature of TX39
           Product: eCos
           Version: 0.2
          Platform: jmr3904 (Toshiba JMR-TX3904 board)
        OS/Version: MIPS
            Status: ASSIGNED
          Severity: normal
          Priority: normal
         Component: Other
        AssignedTo: nickg at ecoscentric dot com
        ReportedBy: support at ecoscentric dot com
                CC: akira dot yokosawa at toshiba dot co dot jp


This was found while I was checking output of kcache2.c

I wondered why numbers of dcache-locked and -unlocked differ only a
little.  Looking at kcache2.c, I found that TX39's dcache lock feature
can not be tested this way.  I also wondered why this test is placed
in kernel/tests.

TX39's dcache lock feature has a different semantics than is assumed
in kcache2.

Attached please find a program that can exhibit the effect of dcache
lock of TX39.

There are a few points I want to clarify:  (See Section 7.2.1 of Users 
Manual of TLCS-R3900 Family --- I admit that the description here is
not easy to understand)

1) Instruction cache of TX3904 does not have lock feature.

2) Cache lock can only be enabled/disabled in the Cache register.

  After one of two ways of one cache set is locked, no more locks 
can be set at the cache set.  (sorry I use "set" in two meanings here)

In other words, you can't explicitly specify an address range you want
to lock.  You have to access the region after enabling lock.

3) Once a lock is established, write operation to that line only
modifies the cache without doing memory access.

4) When you want to clear a lock, you have to use the "cache"
instruction of IndexLockBitClear.  But clearing the lock doesn't
synchronize the memory.  You have to 

    o  Read data in a line from cache memory
    o  Clear the Lock bit
    o  Store the data to memory

Care must to be taken since a Lock bit corresponds to a 16 byte cache
line.  You need to read all the 16 byte data before clearing the lock
bit.  Otherwise, the data in cache line might be lost.

To make matters worse, there is no way to know the address of a locked 
cache line.

It seems that the expected way of using this feature is to lock
critical data once at boot time.  I can't think of any way to swap
locks between multiple purposes.  

------
/* dcache lock test program */
#include <cyg/kernel/kapi.h>
#include <cyg/infra/diag.h>
#include <cyg/infra/testcase.h>
#include <pkgconf/hal.h>
#include <cyg/hal/hal_cache.h>

#define DCACHE_SIZE 1024/4
#define LOOPS 10000

int data1[DCACHE_SIZE];
int data2[2*DCACHE_SIZE];
int loops = LOOPS;
int k = 0;
cyg_uint32 tick_acc;

void dloop1(){  // read --- write --- invalidate
    int i,j;
    cyg_uint32 tick0, tick1, delta;
    for (j=0; j<loops; j++){
	for (i=0; i<DCACHE_SIZE; i++){
	    k += data1[i];
	}
	HAL_CLOCK_READ(&tick0);
	for (i=0; i<DCACHE_SIZE; i++){
	    data1[i] = i;
	}
	HAL_CLOCK_READ(&tick1);
	for (i=0; i<2*DCACHE_SIZE; i++){
	    k += data2[i];  // intend to invalidate data1[] in dcache
	}
	if (tick1 < tick0) {
	    delta = (tick1 + CYGNUM_KERNEL_COUNTERS_RTC_PERIOD) - tick0;
	} else {
	    delta = tick1 - tick0;
	}
	tick_acc += delta;
    }
}

void dloop2(){   // write --- read --- invalidate
    int i,j;
    cyg_uint32 tick0, tick1, delta;
    for (j=0; j<loops; j++){
	HAL_CLOCK_READ(&tick0);
	for (i=0; i<DCACHE_SIZE; i++){
	    data1[i] = i;
	}
	HAL_CLOCK_READ(&tick1);
	for (i=0; i<DCACHE_SIZE; i++){
	    k += data1[i];
	}
	for (i=0; i<2*DCACHE_SIZE; i++){
	    k += data2[i];  // intend to invalidate data1[] in dcache
	}
	if (tick1 < tick0) {
	    delta = (tick1 + CYGNUM_KERNEL_COUNTERS_RTC_PERIOD) - tick0;
	} else {
	    delta = tick1 - tick0;
	}
	tick_acc += delta;
    }
}

void lock_data1(){
    int i;
    HAL_DCACHE_LOCK(0,0);
    for (i=0; i<DCACHE_SIZE; i++) {
	k += data1[i];
    }
    HAL_DCACHE_UNLOCK(0,0);
}

int main(void)
{
    volatile long * p1;
    int i;
    cyg_tick_count_t count0, count1;
    
#if 1
    p1 = (void *) 0xffff9100;// RCCR1
    *p1 = 0x00000500;        // force 5 wait to SRAM
#endif

    CYG_TEST_INIT();

    CYG_TEST_INFO("Now initialize data1 and data2 area");

    for (i=0; i < DCACHE_SIZE; i++) {
	data1[i] = i;
    }

    for (i=0; i < DCACHE_SIZE; i++) {
	data2[i] = data1[i];
    }
  
    HAL_DCACHE_DISABLE();

    diag_printf("Now read/write the area with d-cache OFF (%d loop)\n", loops);
    tick_acc = 0;
    count0 = cyg_current_time();
    dloop1();
    count1 = cyg_current_time();
    diag_printf("time: %d  ", (int) (count1 - count0));
    diag_printf("ticks for write: %d\n", (int) tick_acc);

    HAL_DCACHE_ENABLE();
    diag_printf("Now read/write the area with d-cache ON (%d loop)\n", loops);
    tick_acc = 0;
    count0 = cyg_current_time();
    dloop1();
    count1 = cyg_current_time();
    diag_printf("time: %d  ", (int) (count1 - count0));
    diag_printf("ticks for write: %d\n", (int) tick_acc);

    diag_printf("Now write/read the area with d-cache ON (%d loop)\n", loops);
    tick_acc = 0;
    count0 = cyg_current_time();
    dloop2();
    count1 = cyg_current_time();
    diag_printf("time: %d  ", (int) (count1 - count0));
    diag_printf("ticks for write: %d\n", (int) tick_acc);

    diag_printf("Now read/write the area with d-cache lock ON (%d loop)\n", loops);
    lock_data1();

    tick_acc = 0;
    count0 = cyg_current_time();
    dloop1();
    count1 = cyg_current_time();
    diag_printf("time: %d  ", (int) (count1 - count0));
    diag_printf("ticks for write: %d\n", (int) tick_acc);

    diag_printf("Now write/read the area with d-cache lock ON (%d loop)\n", loops);
    tick_acc = 0;
    count0 = cyg_current_time();
    dloop2();
    count1 = cyg_current_time();
    diag_printf("time: %d  ", (int) (count1 - count0));
    diag_printf("ticks for write: %d\n", (int) tick_acc);

    CYG_TEST_EXIT("done");
    return 0;
}

--------
Output example (JMR 50MHz, Tick-rate is increased x8 from default)
--------
INFO:<Now initialize data1 and data2 area>
Now read/write the area with d-cache OFF (10000 loop)
time: 632  ticks for write: 5785803
Now read/write the area with d-cache ON (10000 loop)
time: 458  ticks for write: 5774762
Now write/read the area with d-cache ON (10000 loop)
time: 459  ticks for write: 5776364
Now read/write the area with d-cache lock ON (10000 loop)
time: 305  ticks for write: 4112355
Now write/read the area with d-cache lock ON (10000 loop)
time: 306  ticks for write: 4104723
EXIT:<done>

-------------
End of PR

Originator:
Akira Yokosawa

Organization:
Toshiba

Audit-Trail:
Responsible-Changed-From-To: alexs->nickg 
Responsible-Changed-By: alexs 
Responsible-Changed-When: Fri Mar 26 03:18:29 PST 1999 
Responsible-Changed-Why:  
Nick to investigate and respond 


From: Akira Yokosawa <akira dot yokosawa at toshiba dot co dot jp>
To: bugs at cygnus dot com
Cc: alexs at cygnus dot com
Subject: Re: ecos/19695: Different semantics of cache lock feature of TX39
Date: Mon, 29 Mar 1999 12:16:42 +0900

 The program I attached to the PR was not sorted out well, and I made 
 a mistake in DCACHE way size.  Please try this one instead.
 
 In the meantime, I found a bug in the definition of
 HAL_DCACH_INVALIDATE() in hal_cache.h.  It ended up with an infinete loop.
 
 I also added a macro called HAL_DCACHE_LOCK_CLEAR to see the effect of
 IndexLockBitClear.
 
 As for the semantics difference, I'm beginning to think that it would
 be better to use other names of macros.  Something like
 HAL_DCACHE_LOCK_ENABLE() and HAL_DCACHE_LOCK_DISABLE() would be more
 suitable than HAL_DCACHE_LOCK(_base_,_size_) and
 HAL_DCACHE_UNLOCK(_base_,_size_) for TX3904.  This idea is not yet
 reflected in the attached program.
 
 Anyway, an expected output of the program is as follows:
 
 ----
 read/write the area with d-cache OFF (10000 loops)
 time: 237, ticks for write: 1924010
 write/read the area with d-cache OFF (10000 loops)
 time: 237, ticks for write: 1921805
 read/write the area with d-cache ON (10000 loops)
 time: 174, ticks for write: 1918665
 write/read the area with d-cache ON (10000 loops)
 time: 174, ticks for write: 1916935
 read/write the area with d-cache lock ON (10000 loops)
 time: 117, ticks for write: 1316271
 write/read the area with d-cache lock ON (10000 loops)
 time: 116, ticks for write: 1310799
 write/read the area after clearing lock (10000 loops)
 time: 174, ticks for write: 1916872
 write/read the area with d-cach lock again (10000 loops)
 time: 116, ticks for write: 1311870
 write/read the area after invalidate without clearing lock (10000 loops)
 time: 143, ticks for write: 1918593
 write/read the area after clearing lock again (10000 loops)
 time: 174, ticks for write: 1916935
 EXIT:<done>
 -----
 
 You can see that invalidating without clearing lock causes the dcache
 to be in a mysterious state (undocumented).  Read access to the locked
 entry still hits, but writing to that entry causes a real memory
 access.  
 
 Here is the revised program:
 -----
 /* dcache lock test program */
 #include <cyg/kernel/kapi.h>
 #include <cyg/infra/diag.h>
 #include <cyg/infra/testcase.h>
 #include <pkgconf/hal.h>
 #include <cyg/hal/hal_cache.h>
 
 #define DCACHE_SIZE 1024/4
 #define LOOPS 10000
 
 #define DATA1_SIZE DCACHE_SIZE/2
 #define DATA2_SIZE DCACHE_SIZE
 
 int data1[DATA1_SIZE];
 int data2[DATA2_SIZE];
 int k = 0;
 cyg_uint32 tick_acc;
 cyg_tick_count_t count0, count1;
 
 void dloop1(char * message){  // read --- write --- invalidate
     int i,j;
     cyg_uint32 tick0, tick1, delta;
 
     diag_printf("%s", message);
     diag_printf(" (%d loops)\n", LOOPS);
     tick_acc = 0;
     count0 = cyg_current_time();
     for (j=0; j<LOOPS; j++){
 	for (i=0; i<DATA1_SIZE; i++){
 	    k += data1[i];
 	}
 	HAL_CLOCK_READ(&tick0);
 	for (i=0; i<DATA1_SIZE; i++){
 	    data1[i] = i;
 	}
 	HAL_CLOCK_READ(&tick1);
 	for (i=0; i<DATA2_SIZE; i++){
 	    k += data2[i];  // intend to invalidate data1[] in dcache
 	}
 	if (tick1 < tick0) {
 	    delta = (tick1 + CYGNUM_KERNEL_COUNTERS_RTC_PERIOD) - tick0;
 	} else {
 	    delta = tick1 - tick0;
 	}
 	tick_acc += delta;
     }
     count1 = cyg_current_time();
     diag_printf("time: %d, ",(int) (count1 - count0));
     diag_printf("ticks for write: %d\n", (int) tick_acc);
 }
 
 void dloop2(char * message){   // write --- read --- invalidate
     int i,j;
     cyg_uint32 tick0, tick1, delta;
 
     diag_printf("%s", message);
     diag_printf(" (%d loops)\n", LOOPS);
     tick_acc = 0;
     count0 = cyg_current_time();
     for (j=0; j<LOOPS; j++){
 	HAL_CLOCK_READ(&tick0);
 	for (i=0; i<DATA1_SIZE; i++){
 	    data1[i] = i;
 	}
 	HAL_CLOCK_READ(&tick1);
 	for (i=0; i<DATA1_SIZE; i++){
 	    k += data1[i];
 	}
 	for (i=0; i<DATA2_SIZE; i++){
 	    k += data2[i];  // intend to invalidate data1[] in dcache
 	}
 	if (tick1 < tick0) {
 	    delta = (tick1 + CYGNUM_KERNEL_COUNTERS_RTC_PERIOD) - tick0;
 	} else {
 	    delta = tick1 - tick0;
 	}
 	tick_acc += delta;
     }
     count1 = cyg_current_time();
     diag_printf("time: %d, ",(int) (count1 - count0));
     diag_printf("ticks for write: %d\n", (int) tick_acc);
 }
 
 void lock_data1(){
     int i;
     HAL_DCACHE_LOCK(0,0);
     for (i=0; i<DATA1_SIZE; i++) {
 	k += data1[i];
     }
     HAL_DCACHE_UNLOCK(0,0);
 }
 
 int main(void)
 {
     int i;
     
 #if 1
     {
         volatile long * p1;
 
         p1 = (void *) 0xffff9100;
         *p1 = 0x00000200;        // force SRAM 2 wait cycle
     }
 #endif
 
     CYG_TEST_INIT();
 
     for (i=0; i < DATA1_SIZE; i++) {
 	data1[i] = i;
     }
 
     for (i=0; i < DATA2_SIZE; i++) {
 	data2[i] = i;
     }
   
 HAL_DCACHE_DISABLE();
 
     dloop1("read/write the area with d-cache OFF");
     dloop2("write/read the area with d-cache OFF");
 
 HAL_DCACHE_ENABLE();
 
     dloop1("read/write the area with d-cache ON");
     dloop2("write/read the area with d-cache ON");
 
 lock_data1();
 
     dloop1("read/write the area with d-cache lock ON");
     dloop2("write/read the area with d-cache lock ON");
 
 HAL_DCACHE_LOCK_CLEAR( data1, 4*DATA1_SIZE);
 
     dloop2("write/read the area after clearing lock");
 
 lock_data1();
 
     dloop2("write/read the area with d-cach lock again");
 
 HAL_DCACHE_INVALIDATE( data1, 4*DATA1_SIZE);
 HAL_DCACHE_INVALIDATE( data2, 8*DATA2_SIZE);
 
     dloop2("write/read the area after invalidate without clearing lock");
 
 HAL_DCACHE_LOCK_CLEAR( data1, 4*DATA1_SIZE);
 
     dloop2("write/read the area after clearing lock again");
 
     CYG_TEST_EXIT("done");
     return 0;
 }
 ------
 
 Here is the modifications to hal_cache.h:  
 
 ------
 // Invalidate cache lines in the given range without writing to memory.
 #define HAL_DCACHE_INVALIDATE( _base_ , _asize_ )                       \
 {                                                                       \
     register CYG_ADDRESS _addr_ = (CYG_ADDRESS)(_base_);                \
     register CYG_ADDRESS _end_ = (CYG_ADDRESS)(_base_) + (_asize_);     \
     HAL_DCACHE_DISABLE();                                               \
     for( ; _addr_ <= _end_; _addr_ += HAL_DCACHE_LINE_SIZE )            \
     {                                                                   \
         asm volatile ("cache 17,0(%0)" : : "r"(_addr_) );               \
     }                                                                   \
     HAL_DCACHE_ENABLE();                                                \
 }
 
 // Clear locks of the indexes corresponding to the given range.
 #define HAL_DCACHE_LOCK_CLEAR( _base_ , _asize_ )                       \
 {                                                                       \
     register CYG_ADDRESS _addr_ = (CYG_ADDRESS)(_base_);                \
     register CYG_ADDRESS _end_ = (CYG_ADDRESS)(_base_) + (_asize_);     \
     HAL_DCACHE_DISABLE();                                               \
     for( ; _addr_ <= _end_; _addr_ += HAL_DCACHE_LINE_SIZE )            \
     {                                                                   \
          asm volatile ("cache 9,0(%0)" : : "r"(_addr_) );               \
     }                                                                   \
     HAL_DCACHE_ENABLE();                                                \
 }
 -----
 End of message
State-Changed-From-To: open-analyzed 
State-Changed-By: nickg 
State-Changed-When: Mon Mar 29 10:17:15 BST 1999 
State-Changed-Why:  

I need to think about all this when I have the time and things are 
not quite so busy (fat chance!). 

Meanwhile moved PR to analyzed state to keep PRMS happy. 



From: Akira Yokosawa <akira dot yokosawa at toshiba dot co dot jp>
To: nickg at cygnus dot co dot uk
Cc: bugs at cygnus dot com
Subject: Re: ecos/19695
Date: Mon, 29 Mar 1999 19:15:20 +0900

 Hi Nick,
 
 It seems you are quite busy right now, and I'm sending what I prepared
 as a separate PR as a follow up to PR 19695 so that you won't be
 bothered by PRMS :-).  Please give considerations to them when you
 have the time.
 
 I have found several bugs in hal_cache.h other than I had reported in
 original PR 19695.
 
 1) In HAL_DCACHE_INVALIDATE_ALL(), the ROM address of 0xbfc00000 was
 used.  But this address is in kseg1 region which is un-cacheable and 
 it had no effects to the dcache.
 Use ROM address of 0x9fc00000 instead, which is mapped to the same
 physical address as 0xbfc00000.
 
 2) HAL_DCACHE_SYNC() was defined as HAL_DCACHE_INVALIDATE_ALL().  But
 when the locking feature is used, HAL_DCACHE_INVALIDATE_ALL() does not
 affect locked lines.  Once the locking feature is used, I don't think
 there is a general way to synchronize.  Or, If you make a software
 layer that wraps the dcache lock feature, it should be possible.  Then you 
 can implement HAL_DCACHE_LOCK and HAL_DCACHE_UNLOCK that have the same 
 semantics as is documented now.  This problem is not fixed in the
 attached diff.
 
 3) Disabling dcache before using "cache" instruction that manipulates
 dcache is not necessary.  Disabling is needed only when invalidating
 icache.
 
 4) When invalidating icache, cares should be taken to ensure that the
 icache is actually disabled.  In the instraction stream below, icache
 might not be disabled yet at the "cache" instruction.  
 
       MTC0    Rn, Config    (clear ICE bit)
       CACHE   IndexInvalidate,offset(base)
 
 This is because the cache state change takes effect at the end of
 current cache refill cycles.  If this "MTC0" is at 16 byte align
 boundary and is fetched from memory, icache is disabled after the
 current refill cycle ends.  The refill cycle contains the "CACHE"
 instruction.  When it gets to execution stage, the cycle might still be
 in progress.  And something weired can happen if the invalidation
 involves the cache line being filled.
 
 To avoid such a rare occasions, you need to program this way.
 
       MTC0    Rn, Config    (clear ICE bit)
       J       0f
       nop
        ...
       .balign 16
 0:    CACHE   IndexInvalidate,offset(base)
 
 In PR 19222 (report of a bug in tx39-cache.S of CygMon),
 I didn't mention the alignment of CACHE instruction.  But the
 alignment seems necessary.  I'll submit another PR of CygMon later.
 
 5) HAL_ICACHE_INVALIDATE(_base_,_asize_) looped forever.  This was the 
 same bug as I reported in the previous follow up to PR 19695.
 
 6) Locking of icache is not supported in TX3904.
 HAL_ICACHE_(LOCK|UNLOCK) shouled not be defined for TX3904.
 
 Attached is a context diff of hal_cache.h:
 
 -----
 *** hal_cache.h.orig	Tue Mar 16 03:39:40 1999
 --- hal_cache.h	Mon Mar 29 18:43:44 1999
 ***************
 *** 229,235 ****
   // most likely to be code, and will not get out of sync even if it is not.
   #define HAL_DCACHE_INVALIDATE_ALL()                                             \
   {                                                                               \
 !     CYG_BYTE volatile *addr = (CYG_BYTE *)(0xbfc00000);                         \
       CYG_BYTE volatile tmp = 0;                                                  \
       int i;                                                                      \
       for( i = 0; i < (HAL_DCACHE_SIZE*2); i += HAL_DCACHE_LINE_SIZE )            \
 --- 229,235 ----
   // most likely to be code, and will not get out of sync even if it is not.
   #define HAL_DCACHE_INVALIDATE_ALL()                                             \
   {                                                                               \
 !     CYG_BYTE volatile *addr = (CYG_BYTE *)(0x9fc00000);                         \
       CYG_BYTE volatile tmp = 0;                                                  \
       int i;                                                                      \
       for( i = 0; i < (HAL_DCACHE_SIZE*2); i += HAL_DCACHE_LINE_SIZE )            \
 ***************
 *** 294,308 ****
   #define HAL_DCACHE_INVALIDATE( _base_ , _asize_ )                       \
   {                                                                       \
       register CYG_ADDRESS _addr_ = (CYG_ADDRESS)(_base_);                \
 !     register CYG_WORD _size_ = (_asize_);                               \
 !     HAL_DCACHE_DISABLE();                                               \
 !     for( ; _addr_ <= _addr_+_size_; _addr_ += HAL_DCACHE_LINE_SIZE )    \
       {                                                                   \
           asm volatile ("cache 17,0(%0)" : : "r"(_addr_) );               \
       }                                                                   \
 -     HAL_DCACHE_ENABLE();                                                \
   }
   
   // Write dirty cache lines to memory for the given address range.
   //#define HAL_DCACHE_STORE( _base_ , _size_ )
   
 --- 294,318 ----
   #define HAL_DCACHE_INVALIDATE( _base_ , _asize_ )                       \
   {                                                                       \
       register CYG_ADDRESS _addr_ = (CYG_ADDRESS)(_base_);                \
 !     register CYG_ADDRESS _end_ = (CYG_ADDRESS)(_base_) + (_asize_);     \
 !     for( ; _addr_ <= _end_; _addr_ += HAL_DCACHE_LINE_SIZE )            \
       {                                                                   \
           asm volatile ("cache 17,0(%0)" : : "r"(_addr_) );               \
       }                                                                   \
   }
   
 + // Clear locks in the index corresponds to the given range.
 + #define HAL_DCACHE_LOCK_CLEAR( _base_ , _asize_ )                       \
 + {                                                                       \
 +     register CYG_ADDRESS _addr_ = (CYG_ADDRESS)(_base_);                \
 +     register CYG_ADDRESS _end_ = (CYG_ADDRESS)(_base_) + (_asize_);     \
 +     for( ; _addr_ < _end_; _addr_ += HAL_DCACHE_LINE_SIZE )             \
 +     {                                                                   \
 +          asm volatile ("cache 9,0(%0)" : : "r"(_addr_) );               \
 +     }                                                                   \
 + }
 + 
 + 
   // Write dirty cache lines to memory for the given address range.
   //#define HAL_DCACHE_STORE( _base_ , _size_ )
   
 ***************
 *** 340,345 ****
 --- 350,357 ----
                     "la   $3,0xFFFFFFDF;"         \
                     "and  $2,$2,$3;"              \
                     "mtc0 $2,$3;"                 \
 + 		  "j    0f;"                    \
 + 		  "0:"                          \
                     :                             \
                     :                             \
                     : "$2", "$3"                  \
 ***************
 *** 354,360 ****
       HAL_ICACHE_DISABLE();                                                       \
       for( _addr_ = 0; _addr_ < HAL_ICACHE_SIZE; _addr_ += HAL_ICACHE_LINE_SIZE ) \
       {                                                                           \
 !         asm volatile ("cache 0,0(%0)" : : "r"(_addr_) );                        \
       }                                                                           \
       HAL_ICACHE_ENABLE();                                                        \
   }
 --- 366,372 ----
       HAL_ICACHE_DISABLE();                                                       \
       for( _addr_ = 0; _addr_ < HAL_ICACHE_SIZE; _addr_ += HAL_ICACHE_LINE_SIZE ) \
       {                                                                           \
 !         asm volatile (".balign 16,0;cache 0,0(%0)" : : "r"(_addr_) );           \
       }                                                                           \
       HAL_ICACHE_ENABLE();                                                        \
   }
 ***************
 *** 367,395 ****
   
   // Load the contents of the given address range into the instruction cache
   // and then lock the cache so that it stays there.
 ! #define HAL_ICACHE_LOCK(_base_, _size_)         \
 ! {                                               \
 !     asm volatile ("mfc0 $2,$7;"                 \
 !                   "ori  $2,$2,0x0200;"          \
 !                   "mtc0 $2,$7;"                 \
 !                   :                             \
 !                   :                             \
 !                   : "$2"                        \
 !                  );                             \
 ! }
   
   // Undo a previous lock operation
 ! #define HAL_ICACHE_UNLOCK(_base_, _size_)       \
 ! {                                               \
 !     asm volatile ("mfc0 $2,$7;"                 \
 !                   "la   $3,0xFFFFFDFF;"         \
 !                   "and  $2,$2,$3;"              \
 !                   "mtc0 $2,$7;"                 \
 !                   :                             \
 !                   :                             \
 !                   : "$2", "$3"                  \
 !                  );                             \
 ! }
   
   // Unlock entire cache
   #define HAL_ICACHE_UNLOCK_ALL()
 --- 379,388 ----
   
   // Load the contents of the given address range into the instruction cache
   // and then lock the cache so that it stays there.
 ! //#define HAL_ICACHE_LOCK(_base_, _size_)
   
   // Undo a previous lock operation
 ! //#define HAL_ICACHE_UNLOCK(_base_, _size_)
   
   // Unlock entire cache
   #define HAL_ICACHE_UNLOCK_ALL()
 ***************
 *** 401,411 ****
   #define HAL_ICACHE_INVALIDATE( _base_ , _asize_ )                       \
   {                                                                       \
       register CYG_ADDRESS _addr_ = (CYG_ADDRESS)(_base_);                \
 !     register CYG_WORD _size_ = (_asize_);                               \
       HAL_ICACHE_DISABLE();                                               \
 !     for( ; _addr_ <= _addr_+_size_; _addr_ += HAL_ICACHE_LINE_SIZE )    \
       {                                                                   \
 !         asm volatile ("cache 0,0(%0)" : : "r"(_addr_) );                \
       }                                                                   \
       HAL_ICACHE_ENABLE();                                                \
   }
 --- 394,404 ----
   #define HAL_ICACHE_INVALIDATE( _base_ , _asize_ )                       \
   {                                                                       \
       register CYG_ADDRESS _addr_ = (CYG_ADDRESS)(_base_);                \
 !     register CYG_ADDRESS _end_  = (CYG_ADDRESS)(_base_) + _asize_;      \
       HAL_ICACHE_DISABLE();                                               \
 !     for( ; _addr_ <= _end_; _addr_ += HAL_ICACHE_LINE_SIZE )            \
       {                                                                   \
 !         asm volatile (".balign 16,0;cache 0,0(%0)" : : "r"(_addr_) );   \
       }                                                                   \
       HAL_ICACHE_ENABLE();                                                \
   }



------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]