aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.target1
-rw-r--r--dcache.c334
-rw-r--r--dcache.h31
-rw-r--r--target-arm/translate.c2
-rw-r--r--trace.c101
-rw-r--r--trace.h97
-rw-r--r--vl-android.c8
7 files changed, 103 insertions, 471 deletions
diff --git a/Makefile.target b/Makefile.target
index 6cf2283..aa3824b 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -137,7 +137,6 @@ LOCAL_SRC_FILES += \
translate-all.c \
trace.c \
varint.c \
- dcache.c \
softmmu_outside_jit.c \
##############################################################################
diff --git a/dcache.c b/dcache.c
deleted file mode 100644
index 7cce505..0000000
--- a/dcache.c
+++ /dev/null
@@ -1,334 +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)
-{
- //printf("st %lld 0x%08x val 0x%x\n", sim_time, addr, val);
-
- 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);
-}
diff --git a/dcache.h b/dcache.h
deleted file mode 100644
index 8857600..0000000
--- a/dcache.h
+++ /dev/null
@@ -1,31 +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.
-*/
-#ifndef DCACHE_H
-#define DCACHE_H
-
-#include <inttypes.h>
-
-// Define constants for the replacement policies
-#define kPolicyRoundRobin 1
-#define kPolicyRandom 2
-
-extern int dcache_size;
-extern int dcache_ways;
-extern int dcache_line_size;
-extern int dcache_replace_policy;
-extern int dcache_load_miss_penalty;
-extern int dcache_store_miss_penalty;
-
-extern void dcache_init(int size, int ways, int line_size, int replace_policy,
- int load_miss_penalty, int store_miss_penalty);
-
-#endif /* DCACHE_H */
diff --git a/target-arm/translate.c b/target-arm/translate.c
index f93a0cd..93ff4ea 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -8909,7 +8909,7 @@ static inline void gen_intermediate_code_internal(CPUState *env,
gen_icount_start();
#ifdef CONFIG_TRACE
if (tracing) {
- gen_traceBB(trace_static.bb_num, tb);
+ gen_traceBB(trace_static_bb_num(), tb);
trace_bb_start(dc->pc);
}
#endif
diff --git a/trace.c b/trace.c
index 9eb8f5f..74c94d5 100644
--- a/trace.c
+++ b/trace.c
@@ -26,6 +26,102 @@
#include "varint.h"
#include "android/utils/path.h"
+// For tracing dynamic execution of basic blocks
+typedef struct TraceBB {
+ char *filename;
+ FILE *fstream;
+ BBRec buffer[kMaxNumBasicBlocks];
+ BBRec *next; // points to next record in buffer
+ uint64_t flush_time; // time of last buffer flush
+ char compressed[kCompressedSize];
+ char *compressed_ptr;
+ char *high_water_ptr;
+ int64_t prev_bb_num;
+ uint64_t prev_bb_time;
+ uint64_t current_bb_num;
+ uint64_t current_bb_start_time;
+ uint64_t recnum; // counts number of trace records
+ uint32_t current_bb_addr;
+ int num_insns;
+} TraceBB;
+
+// For tracing simuation start times of instructions
+typedef struct TraceInsn {
+ char *filename;
+ FILE *fstream;
+ InsnRec dummy; // this is here so we can use buffer[-1]
+ InsnRec buffer[kInsnBufferSize];
+ InsnRec *current;
+ uint64_t prev_time; // time of last instruction start
+ char compressed[kCompressedSize];
+ char *compressed_ptr;
+ char *high_water_ptr;
+} TraceInsn;
+
+// For tracing the static information about a basic block
+typedef struct TraceStatic {
+ char *filename;
+ FILE *fstream;
+ uint32_t insns[kMaxInsnPerBB];
+ int next_insn;
+ uint64_t bb_num;
+ uint32_t bb_addr;
+ int is_thumb;
+} TraceStatic;
+
+// For tracing load and store addresses
+typedef struct TraceAddr {
+ char *filename;
+ FILE *fstream;
+ AddrRec buffer[kMaxNumAddrs];
+ AddrRec *next;
+ char compressed[kCompressedSize];
+ char *compressed_ptr;
+ char *high_water_ptr;
+ uint32_t prev_addr;
+ uint64_t prev_time;
+} TraceAddr;
+
+// For tracing exceptions
+typedef struct TraceExc {
+ char *filename;
+ FILE *fstream;
+ char compressed[kCompressedSize];
+ char *compressed_ptr;
+ char *high_water_ptr;
+ uint64_t prev_time;
+ uint64_t prev_bb_recnum;
+} TraceExc;
+
+// For tracing process id changes
+typedef struct TracePid {
+ char *filename;
+ FILE *fstream;
+ char compressed[kCompressedSize];
+ char *compressed_ptr;
+ uint64_t prev_time;
+} TracePid;
+
+// For tracing Dalvik VM method enter and exit
+typedef struct TraceMethod {
+ char *filename;
+ FILE *fstream;
+ char compressed[kCompressedSize];
+ char *compressed_ptr;
+ uint64_t prev_time;
+ uint32_t prev_addr;
+ int32_t prev_pid;
+} TraceMethod;
+
+extern TraceBB trace_bb;
+extern TraceInsn trace_insn;
+extern TraceStatic trace_static;
+extern TraceAddr trace_load;
+extern TraceAddr trace_store;
+extern TraceExc trace_exc;
+extern TracePid trace_pid;
+extern TraceMethod trace_method;
+
TraceBB trace_bb;
TraceInsn trace_insn;
TraceStatic trace_static;
@@ -1878,3 +1974,8 @@ void trace_interpreted_method(uint32_t addr, int call_type)
comp_ptr = varint_encode(call_type, comp_ptr);
trace_method.compressed_ptr = comp_ptr;
}
+
+uint64_t trace_static_bb_num(void)
+{
+ return trace_static.bb_num;
+}
diff --git a/trace.h b/trace.h
index 59c5ba9..81b622f 100644
--- a/trace.h
+++ b/trace.h
@@ -22,104 +22,9 @@ extern uint64_t Now();
struct TranslationBlock;
-// For tracing dynamic execution of basic blocks
-typedef struct TraceBB {
- char *filename;
- FILE *fstream;
- BBRec buffer[kMaxNumBasicBlocks];
- BBRec *next; // points to next record in buffer
- uint64_t flush_time; // time of last buffer flush
- char compressed[kCompressedSize];
- char *compressed_ptr;
- char *high_water_ptr;
- int64_t prev_bb_num;
- uint64_t prev_bb_time;
- uint64_t current_bb_num;
- uint64_t current_bb_start_time;
- uint64_t recnum; // counts number of trace records
- uint32_t current_bb_addr;
- int num_insns;
-} TraceBB;
-
-// For tracing simuation start times of instructions
-typedef struct TraceInsn {
- char *filename;
- FILE *fstream;
- InsnRec dummy; // this is here so we can use buffer[-1]
- InsnRec buffer[kInsnBufferSize];
- InsnRec *current;
- uint64_t prev_time; // time of last instruction start
- char compressed[kCompressedSize];
- char *compressed_ptr;
- char *high_water_ptr;
-} TraceInsn;
-
-// For tracing the static information about a basic block
-typedef struct TraceStatic {
- char *filename;
- FILE *fstream;
- uint32_t insns[kMaxInsnPerBB];
- int next_insn;
- uint64_t bb_num;
- uint32_t bb_addr;
- int is_thumb;
-} TraceStatic;
-
-// For tracing load and store addresses
-typedef struct TraceAddr {
- char *filename;
- FILE *fstream;
- AddrRec buffer[kMaxNumAddrs];
- AddrRec *next;
- char compressed[kCompressedSize];
- char *compressed_ptr;
- char *high_water_ptr;
- uint32_t prev_addr;
- uint64_t prev_time;
-} TraceAddr;
-
-// For tracing exceptions
-typedef struct TraceExc {
- char *filename;
- FILE *fstream;
- char compressed[kCompressedSize];
- char *compressed_ptr;
- char *high_water_ptr;
- uint64_t prev_time;
- uint64_t prev_bb_recnum;
-} TraceExc;
-
-// For tracing process id changes
-typedef struct TracePid {
- char *filename;
- FILE *fstream;
- char compressed[kCompressedSize];
- char *compressed_ptr;
- uint64_t prev_time;
-} TracePid;
-
-// For tracing Dalvik VM method enter and exit
-typedef struct TraceMethod {
- char *filename;
- FILE *fstream;
- char compressed[kCompressedSize];
- char *compressed_ptr;
- uint64_t prev_time;
- uint32_t prev_addr;
- int32_t prev_pid;
-} TraceMethod;
-
-extern TraceBB trace_bb;
-extern TraceInsn trace_insn;
-extern TraceStatic trace_static;
-extern TraceAddr trace_load;
-extern TraceAddr trace_store;
-extern TraceExc trace_exc;
-extern TracePid trace_pid;
-extern TraceMethod trace_method;
-
// The simulated time, in clock ticks, starting with one.
extern uint64_t sim_time;
+extern uint64_t trace_static_bb_num(void);;
// This variable == 1 if we are currently tracing, otherwise == 0.
extern int tracing;
diff --git a/vl-android.c b/vl-android.c
index 08515cb..2c33092 100644
--- a/vl-android.c
+++ b/vl-android.c
@@ -226,7 +226,6 @@ extern void android_emulator_set_base_port(int port);
#ifdef CONFIG_TRACE
#include "trace.h"
-#include "dcache.h"
#endif
#include "qemu_socket.h"
@@ -5607,13 +5606,6 @@ int main(int argc, char **argv, char **envp)
#ifdef CONFIG_TRACE
if (trace_filename) {
trace_init(trace_filename);
-#if 0
- // We don't need the dcache code until we can get load and store tracing
- // working again.
- dcache_init(dcache_size, dcache_ways, dcache_line_size,
- dcache_replace_policy, dcache_load_miss_penalty,
- dcache_store_miss_penalty);
-#endif
fprintf(stderr, "-- When done tracing, exit the emulator. --\n");
}
#endif