Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. #include "types.h"
  2. #include "CPU.h"
  3. #include "dcache.h"
  4.  
  5. //#define DCACHE_DEBUGGING
  6.  
  7.  
  8.  
  9. #ifdef DCACHE_DEBUGGING
  10.         #define _dcache_fetch_func      dcacheFetch_
  11.         #define _dcache_test_func       dcacheFetch
  12. #else
  13.         #define _dcache_fetch_func      dcacheFetch
  14.         #define _dcache_test_func       dcacheFetch_test
  15. #endif
  16.  
  17. void dcacheInval(dcache* dc){
  18.  
  19.         UInt8 i, j;
  20.        
  21.         for(i = 0; i < DCACHE_BUCKET_NUM; i++){
  22.                 for(j = 0; j < DCACHE_BUCKET_SZ; j++) dc->lines[i][j].info = 0;
  23.                 dc->ptr[i] = 0;
  24.         }
  25. }
  26.  
  27. void dcacheInit(dcache* dc, ArmCpu* cpu, ArmCpuMemF memF){
  28.  
  29.         dc->cpu = cpu;
  30.         dc->memF = memF;
  31.        
  32.         dcacheInval(dc);       
  33. }
  34.  
  35.  
  36. static UInt8 dcachePrvHash(UInt32 addr){
  37.  
  38.         addr >>= DCACHE_L;
  39.         addr &= (1UL << DCACHE_S) - 1UL;
  40.  
  41.         return addr;
  42. }
  43.  
  44. void dcacheInvalAddr(dcache* dc, UInt32 va){
  45.  
  46.         UInt32 off = va % DCACHE_LINE_SZ;
  47.         Int8 i, j, bucket;
  48.         dcacheLine* lines;
  49.        
  50.         va -= off;
  51.  
  52.         bucket = dcachePrvHash(va);
  53.         lines = dc->lines[bucket];
  54.        
  55.         for(i = 0, j = dc->ptr[bucket]; i < DCACHE_BUCKET_SZ; i++){
  56.                
  57.                 if(--j == -1) j = DCACHE_BUCKET_SZ - 1;
  58.                
  59.                 if((lines[j].info & (DCACHE_ADDR_MASK | DCACHE_USED_MASK)) == (va | DCACHE_USED_MASK)){ //found it!
  60.                
  61.                         lines[j].info = 0;
  62.                 }
  63.         }
  64. }
  65.  
  66. void dcacheFlush(dcache* dc){
  67.  
  68.                
  69. }
  70.  
  71. void dcacheFlushAddr(dcache* dc, UInt32 va){
  72.        
  73.        
  74. }
  75.  
  76. /*
  77.         we cannot have data overlap cachelines since data is self aligned (word on 4-byte boundary, halfwords on2, etc. this is enforced elsewhere
  78. */
  79.  
  80. Boolean dcacheWrite(dcache* dc, UInt32 va, UInt8 sz, Boolean priviledged, UInt8* fsrP, void* buf){
  81.  
  82.        
  83. }
  84.  
  85. Boolean _dcache_fetch_func(dcache* dc, UInt32 va, UInt8 sz, Boolean priviledged, UInt8* fsrP, void* buf){
  86.  
  87.         UInt32 off = va % DCACHE_LINE_SZ;
  88.         Int8 i, j, bucket;
  89.         dcacheLine* lines;
  90.         dcacheLine* line;
  91.        
  92.         va -= off;
  93.  
  94.         bucket = dcachePrvHash(va);
  95.         lines = dc->lines[bucket];
  96.        
  97.         for(i = 0, j = dc->ptr[bucket]; i < DCACHE_BUCKET_SZ; i++){
  98.                
  99.                 if(--j == -1) j = DCACHE_BUCKET_SZ - 1;
  100.                
  101.                 if((lines[j].info & (DCACHE_ADDR_MASK | DCACHE_USED_MASK)) == (va | DCACHE_USED_MASK)){ //found it!
  102.                
  103.                         if(sz == 4){
  104.                                 *(UInt32*)buf = *(UInt32*)(lines[j].data + off);
  105.                         }
  106.                         else if(sz == 2){
  107.                                 *(UInt16*)buf = *(UInt16*)(lines[j].data + off);
  108.                         }
  109.                         else __mem_copy(buf, lines[j].data + off, sz);
  110.                         return priviledged || !(lines[j].info & DCACHE_PRIV_MASK);     
  111.                 }
  112.         }
  113.         //if we're here, we found nothing - time to populate the cache
  114.         j = dc->ptr[bucket]++;
  115.         if(dc->ptr[bucket] == DCACHE_BUCKET_SZ) dc->ptr[bucket] = 0;
  116.         line = lines + j;
  117.        
  118.         line->info = va | (priviledged ? DCACHE_PRIV_MASK : 0);
  119.         if(!dc->memF(dc->cpu, line->data, va, DCACHE_LINE_SZ, false, priviledged, fsrP)){
  120.        
  121.                 return false;  
  122.         }
  123.         line->info |= DCACHE_USED_MASK;
  124.        
  125.         if(sz == 4){
  126.                 *(UInt32*)buf = *(UInt32*)(line->data + off);
  127.         }
  128.         else if(sz == 2){
  129.                 *(UInt16*)buf = *(UInt16*)(line->data + off);
  130.         }
  131.         else __mem_copy(buf, line->data + off, sz);
  132.         return true;
  133. }
  134.  
  135. #include "stdio.h"
  136. Boolean _dcache_test_func(dcache* dc, UInt32 va, UInt8 sz, Boolean priviledged, UInt8* fsrP, void* buf){
  137.  
  138.         UInt8 fsrO = -1, fsrT = -1;
  139.         UInt8 dataO[4] = {0}, dataT[4] = {0};
  140.         Boolean retO, retT;
  141.         UInt8 i;
  142.        
  143.         retO = _dcache_fetch_func(dc, va, sz, priviledged, &fsrO, dataO);
  144.         retT = dc->memF(dc->cpu, dataT, va, sz, false, priviledged, &fsrT);
  145.        
  146.         if((retT != retO) || (fsrT != fsrO) || (dataT[0] != dataO[0]) || (dataT[1] != dataO[1]) || (dataT[2] != dataO[2]) || (dataT[3] != dataO[3])){
  147.        
  148.                 fprintf(stderr, "dcache fail!");       
  149.         }
  150.  
  151.         for(i = 0; i < sz; i++) ((UInt8*)buf)[i] = dataT[i];
  152.         if(retT) *fsrP = fsrT;
  153.         return retT;
  154. }
  155.  
  156.