memory.c
3.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/*************************************************************************
*
* File: memory.c
*
*
* $Header: /root/leakn64/depot/rf/sw/n64os20l/iosim/src/memory.c,v 1.2 2002/05/30 05:52:50 whs Exp $
*
*/
#include <stdio.h>
#include "sim.h"
#define DIR_LOAD 1
typedef unsigned long long physaddr_t;
static physaddr_t vtop(uint);
#define MEMSIZE (2*1024*1024)
#define ICACHESIZE (16*1024)
#define ICACHELINESIZE (32)
#define ICACHEINDEX(a) (((a)>>5)&0x1ff)
static struct {
int valid;
int ptag;
} icache[ICACHESIZE/ICACHELINESIZE];
#define DCACHESIZE (8*1024)
#define DCACHELINESIZE (16)
#define DCACHEINDEX(a) (((a)>>4)&0x1ff)
static struct {
int valid;
int dirty;
int ptag;
} dcache[DCACHESIZE/DCACHELINESIZE];
#define CACHETAG(a) (((a)>>12)&0x1fffff)
static struct {
int total; /* total accesses */
int inst; /* instruction fetches */
int insthits; /* hits in icache */
int instmisses; /* misses in icache */
int data; /* data accesses */
int loads; /* loads */
int loadhits; /* load hits in dcache */
int loadmisses; /* load misses in dcache */
int stores; /* stores */
int storehits; /* store hits in dcache */
int storemisses; /* store misses in dcache */
} stats;
void
memory_access(ulong vaddr, ref_t ref, dir_t dir, sz_t sz)
{
physaddr_t paddr;
int index, ptag;
stats.total++;
paddr = vtop(vaddr);
fprintf(stderr,
"vaddr 0x%08x 0x%09llx reference(%s)\tdirection(%s)\tsize(%d)\n",
vaddr,
paddr,
ref == REF_INST ? "instruction" : "data",
dir == DIR_LOAD ? "load" : "store",
sz);
ptag = CACHETAG(paddr);
fprintf(stderr, "ptag = %x ", ptag);
if (ref == REF_INST) {
stats.inst++;
index = ICACHEINDEX(paddr);
fprintf(stderr, "index = %x\n", index);
if (icache[index].valid) {
if (icache[index].ptag == ptag) {
stats.insthits++;
} else {
stats.instmisses++;
icache[index].ptag = ptag;
}
} else {
stats.instmisses++;
icache[index].valid = 1;
icache[index].ptag = ptag;
}
} else if (dir == DIR_LOAD) {
stats.data++;
stats.loads++;
index = DCACHEINDEX(paddr);
fprintf(stderr, "index = %x\n", index);
if (dcache[index].valid) {
if (dcache[index].ptag == ptag) {
stats.loadhits++;
} else {
stats.loadmisses++;
dcache[index].ptag = ptag;
}
} else {
stats.loadmisses++;
dcache[index].valid = 1;
dcache[index].ptag = ptag;
}
} else {
stats.data++;
stats.loads++;
index = DCACHEINDEX(paddr);
fprintf(stderr, "index = %x\n", index);
if (dcache[index].valid) {
if (dcache[index].ptag == ptag) {
stats.storehits++;
} else {
stats.storemisses++;
dcache[index].ptag = ptag;
}
} else {
stats.storemisses++;
dcache[index].valid = 1;
dcache[index].ptag = ptag;
}
}
}
void
memory_stats(void)
{
printf("\n\n");
printf("total accesses:\t\t\t%9d\n", stats.total);
printf("\tinstruction fetches:\t%9d\n", stats.inst);
printf("\t\thits:\t\t%9d\n", stats.insthits);
printf("\t\tmisses:\t\t%9d\n", stats.instmisses);
printf("\tdata accesses:\t\t%9d\n", stats.data);
printf("\t\tloads:\t\t%9d\n", stats.loads);
printf("\t\t\thits:\t%9d\n", stats.loadhits);
printf("\t\t\tmisses:\t%9d\n", stats.loadmisses);
printf("\t\tstores:\t\t%9d\n", stats.stores);
printf("\t\t\thits:\t%9d\n", stats.storehits);
printf("\t\t\tmisses:\t%9d\n", stats.storemisses);
}
static physaddr_t
vtop(uint addr)
{
return(addr & (MEMSIZE-1));
}