diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:35 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:35 -0800 |
commit | f721e3ac031f892af46f255a47d7f54a91317b30 (patch) | |
tree | 4b825dc642cb6eb9a060e54bf8d69288fbee4904 /dcache.c | |
parent | bae1bc39312d5019bd9a5b8d840a529213a69a17 (diff) | |
download | external_qemu-f721e3ac031f892af46f255a47d7f54a91317b30.zip external_qemu-f721e3ac031f892af46f255a47d7f54a91317b30.tar.gz external_qemu-f721e3ac031f892af46f255a47d7f54a91317b30.tar.bz2 |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'dcache.c')
-rw-r--r-- | dcache.c | 349 |
1 files changed, 0 insertions, 349 deletions
diff --git a/dcache.c b/dcache.c deleted file mode 100644 index 56426ee..0000000 --- a/dcache.c +++ /dev/null @@ -1,349 +0,0 @@ -/* Copyright (C) 2007-2008 The Android Open Source Project -** -** This software is licensed under the terms of the GNU General Public -** License version 2, as published by the Free Software Foundation, and -** may be copied, distributed, and modified under those terms. -** -** This program 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. -*/ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include "dcache.h" -#include "cpu.h" -#include "exec-all.h" -#include "trace.h" -#include "varint.h" - -extern FILE *ftrace_debug; - -int dcache_size = 16 * 1024; -int dcache_ways = 4; -int dcache_line_size = 32; -int dcache_replace_policy = kPolicyRandom; -int dcache_load_miss_penalty = 30; -int dcache_store_miss_penalty = 5; - -typedef struct Dcache { - int size; - int ways; - int line_size; - int log_line_size; - int rows; - uint32_t addr_mask; - int replace_policy; - int next_way; - int extra_increment_counter; - int *replace; - uint32_t **table; - int load_miss_penalty; - int store_miss_penalty; - uint64_t load_hits; - uint64_t load_misses; - uint64_t store_hits; - uint64_t store_misses; -} Dcache; - -Dcache dcache; - -void dcache_cleanup(); - -// Returns the log2 of "num" rounded up to the nearest integer. -int log2_roundup(int num) -{ - int power2; - int exp; - - for (exp = 0, power2 = 1; power2 < num; power2 <<= 1) { - exp += 1; - } - return exp; -} - -void dcache_init(int size, int ways, int line_size, int replace_policy, - int load_miss_penalty, int store_miss_penalty) -{ - int ii; - - // Compute the logs of the params, rounded up - int log_size = log2_roundup(size); - int log_ways = log2_roundup(ways); - int log_line_size = log2_roundup(line_size); - - // The number of rows in the table = size / (line_size * ways) - int log_rows = log_size - log_line_size - log_ways; - - dcache.size = 1 << log_size; - dcache.ways = 1 << log_ways; - dcache.line_size = 1 << log_line_size; - dcache.log_line_size = log_line_size; - dcache.rows = 1 << log_rows; - dcache.addr_mask = (1 << log_rows) - 1; - - // Allocate an array of pointers, one for each row - uint32_t **table = malloc(sizeof(uint32_t *) << log_rows); - - // Allocate the data for the whole cache in one call to malloc() - int data_size = sizeof(uint32_t) << (log_rows + log_ways); - uint32_t *data = malloc(data_size); - - // Fill the cache with invalid addresses - memset(data, ~0, data_size); - - // Assign the pointers into the data array - int rows = dcache.rows; - for (ii = 0; ii < rows; ++ii) { - table[ii] = &data[ii << log_ways]; - } - dcache.table = table; - dcache.replace_policy = replace_policy; - dcache.next_way = 0; - dcache.extra_increment_counter = 0; - - dcache.replace = NULL; - if (replace_policy == kPolicyRoundRobin) { - dcache.replace = malloc(sizeof(int) << log_rows); - memset(dcache.replace, 0, sizeof(int) << log_rows); - } - dcache.load_miss_penalty = load_miss_penalty; - dcache.store_miss_penalty = store_miss_penalty; - dcache.load_hits = 0; - dcache.load_misses = 0; - dcache.store_hits = 0; - dcache.store_misses = 0; - - atexit(dcache_cleanup); -} - -void dcache_stats() -{ - uint64_t hits = dcache.load_hits + dcache.store_hits; - uint64_t misses = dcache.load_misses + dcache.store_misses; - uint64_t total = hits + misses; - double hit_per = 0; - double miss_per = 0; - if (total) { - hit_per = 100.0 * hits / total; - miss_per = 100.0 * misses / total; - } - printf("\n"); - printf("Dcache hits %10llu %6.2f%%\n", hits, hit_per); - printf("Dcache misses %10llu %6.2f%%\n", misses, miss_per); - printf("Dcache total %10llu\n", hits + misses); -} - -void dcache_free() -{ - free(dcache.table[0]); - free(dcache.table); - free(dcache.replace); - dcache.table = NULL; -} - -void dcache_cleanup() -{ - dcache_stats(); - dcache_free(); -} - -void compress_trace_addresses(TraceAddr *trace_addr) -{ - AddrRec *ptr; - char *comp_ptr = trace_addr->compressed_ptr; - uint32_t prev_addr = trace_addr->prev_addr; - uint64_t prev_time = trace_addr->prev_time; - AddrRec *last = &trace_addr->buffer[kMaxNumAddrs]; - for (ptr = trace_addr->buffer; ptr != last; ++ptr) { - if (comp_ptr >= trace_addr->high_water_ptr) { - uint32_t size = comp_ptr - trace_addr->compressed; - fwrite(trace_addr->compressed, sizeof(char), size, trace_addr->fstream); - comp_ptr = trace_addr->compressed; - } - - int addr_diff = ptr->addr - prev_addr; - uint64_t time_diff = ptr->time - prev_time; - prev_addr = ptr->addr; - prev_time = ptr->time; - - comp_ptr = varint_encode_signed(addr_diff, comp_ptr); - comp_ptr = varint_encode(time_diff, comp_ptr); - } - trace_addr->compressed_ptr = comp_ptr; - trace_addr->prev_addr = prev_addr; - trace_addr->prev_time = prev_time; -} - -// This function is called by the generated code to simulate -// a dcache load access. -void dcache_load(uint32_t addr) -{ - int ii; - int ways = dcache.ways; - uint32_t cache_addr = addr >> dcache.log_line_size; - int row = cache_addr & dcache.addr_mask; - //printf("ld %lld 0x%x\n", sim_time, addr); - for (ii = 0; ii < ways; ++ii) { - if (cache_addr == dcache.table[row][ii]) { - dcache.load_hits += 1; -#if 0 - printf("dcache load hit addr: 0x%x cache_addr: 0x%x row %d way %d\n", - addr, cache_addr, row, ii); -#endif - // If we are tracing all addresses, then include this in the trace. - if (trace_all_addr) { - AddrRec *next = trace_load.next; - next->addr = addr; - next->time = sim_time; - next += 1; - if (next == &trace_load.buffer[kMaxNumAddrs]) { - // Compress the trace - compress_trace_addresses(&trace_load); - next = &trace_load.buffer[0]; - } - trace_load.next = next; - } - return; - } - } - // This is a cache miss - -#if 0 - if (ftrace_debug) - fprintf(ftrace_debug, "t%lld %08x\n", sim_time, addr); -#endif - if (trace_load.fstream) { - AddrRec *next = trace_load.next; - next->addr = addr; - next->time = sim_time; - next += 1; - if (next == &trace_load.buffer[kMaxNumAddrs]) { - // Compress the trace - compress_trace_addresses(&trace_load); - next = &trace_load.buffer[0]; - } - trace_load.next = next; - } - - dcache.load_misses += 1; - sim_time += dcache.load_miss_penalty; - - // Pick a way to replace - int way; - if (dcache.replace_policy == kPolicyRoundRobin) { - // Round robin replacement policy - way = dcache.replace[row]; - int next_way = way + 1; - if (next_way == dcache.ways) - next_way = 0; - dcache.replace[row] = next_way; - } else { - // Random replacement policy - way = dcache.next_way; - dcache.next_way += 1; - if (dcache.next_way >= dcache.ways) - dcache.next_way = 0; - - // Every 13 replacements, add an extra increment to the next way - dcache.extra_increment_counter += 1; - if (dcache.extra_increment_counter == 13) { - dcache.extra_increment_counter = 0; - dcache.next_way += 1; - if (dcache.next_way >= dcache.ways) - dcache.next_way = 0; - } - } -#if 0 - printf("dcache load miss addr: 0x%x cache_addr: 0x%x row %d replacing way %d\n", - addr, cache_addr, row, way); -#endif - dcache.table[row][way] = cache_addr; -} - -// This function is called by the generated code to simulate -// a dcache store access. -void dcache_store(uint32_t addr, uint32_t val) -{ - // Check for a write to a magic address (this is a virtual address) - //printf("st %lld 0x%08x val 0x%x\n", sim_time, addr, val); - if ((addr & kMagicBaseMask) == kMagicBaseAddr) { - uint32_t offset = addr & kMagicOffsetMask; - switch (offset) { - case kMethodTraceEnterOffset: - trace_interpreted_method(val, kMethodEnter); - break; - case kMethodTraceExitOffset: - trace_interpreted_method(val, kMethodExit); - break; - case kMethodTraceExceptionOffset: - trace_interpreted_method(val, kMethodException); - break; - } - } - - int ii; - int ways = dcache.ways; - uint32_t cache_addr = addr >> dcache.log_line_size; - int row = cache_addr & dcache.addr_mask; - for (ii = 0; ii < ways; ++ii) { - if (cache_addr == dcache.table[row][ii]) { - dcache.store_hits += 1; -#if 0 - printf("dcache store hit addr: 0x%x cache_addr: 0x%x row %d way %d\n", - addr, cache_addr, row, ii); -#endif - // If we are tracing all addresses, then include this in the trace. - if (trace_all_addr) { - AddrRec *next = trace_store.next; - next->addr = addr; - next->time = sim_time; - next += 1; - if (next == &trace_store.buffer[kMaxNumAddrs]) { - // Compress the trace - compress_trace_addresses(&trace_store); - next = &trace_store.buffer[0]; - } - trace_store.next = next; - } - return; - } - } - // This is a cache miss -#if 0 - printf("dcache store miss addr: 0x%x cache_addr: 0x%x row %d\n", - addr, cache_addr, row); -#endif - -#if 0 - if (ftrace_debug) - fprintf(ftrace_debug, "t%lld %08x\n", sim_time, addr); -#endif - - if (trace_store.fstream) { - AddrRec *next = trace_store.next; - next->addr = addr; - next->time = sim_time; - next += 1; - if (next == &trace_store.buffer[kMaxNumAddrs]) { - // Compress the trace - compress_trace_addresses(&trace_store); - next = &trace_store.buffer[0]; - } - trace_store.next = next; - } - - dcache.store_misses += 1; - sim_time += dcache.store_miss_penalty; - - // Assume no write-allocate for now -} - -// This function is called by the generated code to simulate -// a dcache load and store (swp) access. -void dcache_swp(uint32_t addr) -{ - dcache_load(addr); - dcache_store(addr, 0); -} |