diff options
Diffstat (limited to '')
-rw-r--r-- | src/core/arm/interpreter/mmu/cache.cpp | 370 |
1 files changed, 0 insertions, 370 deletions
diff --git a/src/core/arm/interpreter/mmu/cache.cpp b/src/core/arm/interpreter/mmu/cache.cpp deleted file mode 100644 index f3c4e0531..000000000 --- a/src/core/arm/interpreter/mmu/cache.cpp +++ /dev/null @@ -1,370 +0,0 @@ -#include "core/arm/interpreter/armdefs.h" - -/* mmu cache init - * - * @cache_t :cache_t to init - * @width :cache line width in byte - * @way :way of each cache set - * @set :cache set num - * - * $ -1: error - * 0: sucess - */ -int -mmu_cache_init (cache_s * cache_t, int width, int way, int set, int w_mode) -{ - int i, j; - cache_set_t *sets; - cache_line_t *lines; - - /*alloc cache set */ - sets = NULL; - lines = NULL; - //fprintf(stderr, "mmu_cache_init: mallloc beg size %d,sets 0x%x\n", sizeof(cache_set_t) * set,sets); - //exit(-1); - sets = (cache_set_t *) malloc (sizeof (cache_set_t) * set); - if (sets == NULL) { - ERROR_LOG(ARM11, "set malloc size %d\n", sizeof (cache_set_t) * set); - goto sets_error; - } - //fprintf(stderr, "mmu_cache_init: mallloc end sets 0x%x\n", sets); - cache_t->sets = sets; - - /*init cache set */ - for (i = 0; i < set; i++) { - /*alloc cache line */ - lines = (cache_line_t *) malloc (sizeof (cache_line_t) * way); - if (lines == NULL) { - ERROR_LOG(ARM11, "line malloc size %d\n", - sizeof (cache_line_t) * way); - goto lines_error; - } - /*init cache line */ - for (j = 0; j < way; j++) { - lines[j].tag = 0; //invalid - lines[j].data = (ARMword *) malloc (width); - if (lines[j].data == NULL) { - ERROR_LOG(ARM11, "data alloc size %d\n", width); - goto data_error; - } - } - - sets[i].lines = lines; - sets[i].cycle = 0; - - } - cache_t->width = width; - cache_t->set = set; - cache_t->way = way; - cache_t->w_mode = w_mode; - return 0; - - data_error: - /*free data */ - while (j-- > 0) - free (lines[j].data); - /*free data error line */ - free (lines); - lines_error: - /*free lines already alloced */ - while (i-- > 0) { - for (j = 0; j < way; j++) - free (sets[i].lines[j].data); - free (sets[i].lines); - } - /*free sets */ - free (sets); - sets_error: - return -1; -}; - -/* free a cache_t's inner data, the ptr self is not freed, - * when needed do like below: - * mmu_cache_exit(cache); - * free(cache_t); - * - * @cache_t : the cache_t to free - */ - -void -mmu_cache_exit (cache_s * cache_t) -{ - int i, j; - cache_set_t *sets, *set; - cache_line_t *lines, *line; - - /*free all set */ - sets = cache_t->sets; - for (set = sets, i = 0; i < cache_t->set; i++, set++) { - /*free all line */ - lines = set->lines; - for (line = lines, j = 0; j < cache_t->way; j++, line++) - free (line->data); - free (lines); - } - free (sets); -} - -/* mmu cache search - * - * @state :ARMul_State - * @cache_t :cache_t to search - * @va :virtual address - * - * $ NULL: no cache match - * cache :cache matched - */ -cache_line_t * -mmu_cache_search (ARMul_State * state, cache_s * cache_t, ARMword va) -{ - int i; - int set = va_cache_set (va, cache_t); - ARMword tag = va_cache_align (va, cache_t); - cache_line_t *cache; - - cache_set_t *cache_set = cache_t->sets + set; - for (i = 0, cache = cache_set->lines; i < cache_t->way; i++, cache++) { - if ((cache->tag & TAG_VALID_FLAG) - && (tag == va_cache_align (cache->tag, cache_t))) - return cache; - } - return NULL; -} - -/* mmu cache search by set/index - * - * @state :ARMul_State - * @cache_t :cache_t to search - * @index :set/index value. - * - * $ NULL: no cache match - * cache :cache matched - */ -cache_line_t * -mmu_cache_search_by_index (ARMul_State * state, cache_s * cache_t, - ARMword index) -{ - int way = cache_t->way; - int set_v = index_cache_set (index, cache_t); - int i = 0, index_v = 0; - cache_set_t *set; - - while ((way >>= 1) >= 1) - i++; - index_v = index >> (32 - i); - set = cache_t->sets + set_v; - - return set->lines + index_v; -} - - -/* mmu cache alloc - * - * @state :ARMul_State - * @cache_t :cache_t to alloc from - * @va :virtual address that require cache alloc, need not cache aligned - * @pa :physical address of va - * - * $ cache_alloced, always alloc OK - */ -cache_line_t * -mmu_cache_alloc (ARMul_State * state, cache_s * cache_t, ARMword va, - ARMword pa) -{ - cache_line_t *cache; - cache_set_t *set; - int i; - - va = va_cache_align (va, cache_t); - pa = va_cache_align (pa, cache_t); - - set = &cache_t->sets[va_cache_set (va, cache_t)]; - - /*robin-round */ - cache = &set->lines[set->cycle++]; - if (set->cycle == cache_t->way) - set->cycle = 0; - - if (cache_t->w_mode == CACHE_WRITE_BACK) { - ARMword t; - - /*if cache valid, try to write back */ - if (cache->tag & TAG_VALID_FLAG) { - mmu_cache_write_back (state, cache_t, cache); - } - /*read in cache_line */ - t = pa; - for (i = 0; i < (cache_t->width >> WORD_SHT); - i++, t += WORD_SIZE) { - //cache->data[i] = mem_read_word (state, t); - bus_read(32, t, &cache->data[i]); - } - } - /*store tag and pa */ - cache->tag = va | TAG_VALID_FLAG; - cache->pa = pa; - - return cache; -}; - -/* mmu_cache_write_back write cache data to memory - * @state - * @cache_t :cache_t of the cache line - * @cache : cache line - */ -void -mmu_cache_write_back (ARMul_State * state, cache_s * cache_t, - cache_line_t * cache) -{ - ARMword pa = cache->pa; - int nw = cache_t->width >> WORD_SHT; - ARMword *data = cache->data; - int i; - int t0, t1, t2; - - if ((cache->tag & 1) == 0) - return; - - switch (cache-> - tag & ~1 & (TAG_FIRST_HALF_DIRTY | TAG_LAST_HALF_DIRTY)) { - case 0: - return; - case TAG_FIRST_HALF_DIRTY: - nw /= 2; - break; - case TAG_LAST_HALF_DIRTY: - nw /= 2; - pa += nw << WORD_SHT; - data += nw; - break; - case TAG_FIRST_HALF_DIRTY | TAG_LAST_HALF_DIRTY: - break; - } - for (i = 0; i < nw; i++, data++, pa += WORD_SIZE) - //mem_write_word (state, pa, *data); - bus_write(32, pa, *data); - - cache->tag &= ~(TAG_FIRST_HALF_DIRTY | TAG_LAST_HALF_DIRTY); -}; - - -/* mmu_cache_clean: clean a cache of va in cache_t - * - * @state :ARMul_State - * @cache_t :cache_t to clean - * @va :virtaul address - */ -void -mmu_cache_clean (ARMul_State * state, cache_s * cache_t, ARMword va) -{ - cache_line_t *cache; - - cache = mmu_cache_search (state, cache_t, va); - if (cache) - mmu_cache_write_back (state, cache_t, cache); -} - -/* mmu_cache_clean_by_index: clean a cache by set/index format value - * - * @state :ARMul_State - * @cache_t :cache_t to clean - * @va :set/index format value - */ -void -mmu_cache_clean_by_index (ARMul_State * state, cache_s * cache_t, - ARMword index) -{ - cache_line_t *cache; - - cache = mmu_cache_search_by_index (state, cache_t, index); - if (cache) - mmu_cache_write_back (state, cache_t, cache); -} - -/* mmu_cache_invalidate : invalidate a cache of va - * - * @state :ARMul_State - * @cache_t :cache_t to invalid - * @va :virt_addr to invalid - */ -void -mmu_cache_invalidate (ARMul_State * state, cache_s * cache_t, ARMword va) -{ - cache_line_t *cache; - - cache = mmu_cache_search (state, cache_t, va); - if (cache) { - mmu_cache_write_back (state, cache_t, cache); - cache->tag = 0; - } -} - -/* mmu_cache_invalidate_by_index : invalidate a cache by index format - * - * @state :ARMul_State - * @cache_t :cache_t to invalid - * @index :set/index data - */ -void -mmu_cache_invalidate_by_index (ARMul_State * state, cache_s * cache_t, - ARMword index) -{ - cache_line_t *cache; - - cache = mmu_cache_search_by_index (state, cache_t, index); - if (cache) { - mmu_cache_write_back (state, cache_t, cache); - cache->tag = 0; - } -} - -/* mmu_cache_invalidate_all - * - * @state: - * @cache_t - * */ -void -mmu_cache_invalidate_all (ARMul_State * state, cache_s * cache_t) -{ - int i, j; - cache_set_t *set; - cache_line_t *cache; - - set = cache_t->sets; - for (i = 0; i < cache_t->set; i++, set++) { - cache = set->lines; - for (j = 0; j < cache_t->way; j++, cache++) { - mmu_cache_write_back (state, cache_t, cache); - cache->tag = 0; - } - } -}; - -void -mmu_cache_soft_flush (ARMul_State * state, cache_s * cache_t, ARMword pa) -{ - ARMword set, way; - cache_line_t *cache; - pa = (pa / cache_t->width); - way = pa & (cache_t->way - 1); - set = (pa / cache_t->way) & (cache_t->set - 1); - cache = &cache_t->sets[set].lines[way]; - - mmu_cache_write_back (state, cache_t, cache); - cache->tag = 0; -} - -cache_line_t* mmu_cache_dirty_cache(ARMul_State *state,cache_s *cache){ - int i; - int j; - cache_line_t *cache_line = NULL; - cache_set_t *cache_set = cache->sets; - int sets = cache->set; - for (i = 0; i < sets; i++){ - for(j = 0,cache_line = &cache_set[i].lines[0]; j < cache->way; j++,cache_line++){ - if((cache_line->tag & TAG_FIRST_HALF_DIRTY) || (cache_line->tag & TAG_LAST_HALF_DIRTY)) - return cache_line; - } - } - return NULL; -} |