OpenCores
URL https://opencores.org/ocsvn/eco32/eco32/trunk

Subversion Repositories eco32

[/] [eco32/] [trunk/] [sim/] [mmu.c] - Blame information for rev 166

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 8 hellwig
/*
2
 * mmu.c -- MMU simulation
3
 */
4
 
5
 
6
#include <stdio.h>
7
#include <stdlib.h>
8
#include <string.h>
9
#include <setjmp.h>
10
 
11
#include "common.h"
12
#include "console.h"
13
#include "error.h"
14
#include "except.h"
15
#include "cpu.h"
16
#include "mmu.h"
17
#include "memory.h"
18
 
19
 
20
static Bool debugUse = false;
21
static Bool debugWrite = false;
22
 
23
 
24
static TLB_Entry tlb[TLB_SIZE];
25
static Word tlbIndex;
26
static Word tlbEntryHi;
27
static Word tlbEntryLo;
28 78 hellwig
static Word mmuBadAddr;
29 8 hellwig
 
30
 
31
static int assoc(Word page) {
32
  int n, i;
33
 
34
  n = -1;
35
  for (i = 0; i < TLB_SIZE; i++) {
36
    if (tlb[i].page == page) {
37
      n = i;
38
    }
39
  }
40
  return n;
41
}
42
 
43
 
44
static Word v2p(Word vAddr, Bool userMode, Bool writing) {
45
  Word pAddr;
46
  Word page, offset;
47
  int index;
48
 
49
  if (debugUse) {
50
    cPrintf("**** vAddr = 0x%08X", vAddr);
51
  }
52
  if ((vAddr & 0x80000000) != 0 && userMode) {
53
    /* trying to access a privileged address from user mode */
54 78 hellwig
    mmuBadAddr = vAddr;
55 8 hellwig
    throwException(EXC_PRV_ADDRESS);
56
  }
57
  if ((vAddr & 0xC0000000) == 0xC0000000) {
58
    /* unmapped address space */
59 166 hellwig
    /* simulate delay introduced by assoc when using mapped
60
       addresses but not experienced with unmapped addresses */
61
    assoc(0);
62 8 hellwig
    pAddr = vAddr & ~0xC0000000;
63
  } else {
64
    /* mapped address space */
65
    page = vAddr & PAGE_MASK;
66
    offset = vAddr & OFFSET_MASK;
67
    index = assoc(page);
68
    if (index == -1) {
69
      /* TLB miss exception */
70 78 hellwig
      mmuBadAddr = vAddr;
71 8 hellwig
      tlbEntryHi = page;
72
      throwException(EXC_TLB_MISS);
73
    }
74
    if (!tlb[index].valid) {
75
      /* TLB invalid exception */
76 78 hellwig
      mmuBadAddr = vAddr;
77 8 hellwig
      tlbEntryHi = page;
78
      throwException(EXC_TLB_INVALID);
79
    }
80
    if (!tlb[index].write && writing) {
81
      /* TLB write exception */
82 78 hellwig
      mmuBadAddr = vAddr;
83 8 hellwig
      tlbEntryHi = page;
84
      throwException(EXC_TLB_WRITE);
85
    }
86
    pAddr = tlb[index].frame | offset;
87
  }
88
  if (debugUse) {
89
    cPrintf(", pAddr = 0x%08X ****\n", pAddr);
90
  }
91
  return pAddr;
92
}
93
 
94
 
95
Word mmuReadWord(Word vAddr, Bool userMode) {
96
  if ((vAddr & 3) != 0) {
97
    /* throw illegal address exception */
98 78 hellwig
    mmuBadAddr = vAddr;
99 8 hellwig
    throwException(EXC_ILL_ADDRESS);
100
  }
101
  return memoryReadWord(v2p(vAddr, userMode, false));
102
}
103
 
104
 
105
Half mmuReadHalf(Word vAddr, Bool userMode) {
106
  if ((vAddr & 1) != 0) {
107
    /* throw illegal address exception */
108 78 hellwig
    mmuBadAddr = vAddr;
109 8 hellwig
    throwException(EXC_ILL_ADDRESS);
110
  }
111
  return memoryReadHalf(v2p(vAddr, userMode, false));
112
}
113
 
114
 
115
Byte mmuReadByte(Word vAddr, Bool userMode) {
116
  return memoryReadByte(v2p(vAddr, userMode, false));
117
}
118
 
119
 
120
void mmuWriteWord(Word vAddr, Word data, Bool userMode) {
121
  if ((vAddr & 3) != 0) {
122
    /* throw illegal address exception */
123 78 hellwig
    mmuBadAddr = vAddr;
124 8 hellwig
    throwException(EXC_ILL_ADDRESS);
125
  }
126
  memoryWriteWord(v2p(vAddr, userMode, true), data);
127
}
128
 
129
 
130
void mmuWriteHalf(Word vAddr, Half data, Bool userMode) {
131
  if ((vAddr & 1) != 0) {
132
    /* throw illegal address exception */
133 78 hellwig
    mmuBadAddr = vAddr;
134 8 hellwig
    throwException(EXC_ILL_ADDRESS);
135
  }
136
  memoryWriteHalf(v2p(vAddr, userMode, true), data);
137
}
138
 
139
 
140
void mmuWriteByte(Word vAddr, Byte data, Bool userMode) {
141
  memoryWriteByte(v2p(vAddr, userMode, true), data);
142
}
143
 
144
 
145
Word mmuGetIndex(void) {
146
  return tlbIndex;
147
}
148
 
149
 
150
void mmuSetIndex(Word value) {
151
  tlbIndex = value & TLB_MASK;
152
}
153
 
154
 
155
Word mmuGetEntryHi(void) {
156
  return tlbEntryHi;
157
}
158
 
159
 
160
void mmuSetEntryHi(Word value) {
161
  tlbEntryHi = value & PAGE_MASK;
162
}
163
 
164
 
165
Word mmuGetEntryLo(void) {
166
  return tlbEntryLo;
167
}
168
 
169
 
170
void mmuSetEntryLo(Word value) {
171
  tlbEntryLo = value & (PAGE_MASK | TLB_WRITE | TLB_VALID);
172
}
173
 
174
 
175
Word mmuGetBadAddr(void) {
176 78 hellwig
  return mmuBadAddr;
177 8 hellwig
}
178
 
179
 
180
void mmuSetBadAddr(Word value) {
181 78 hellwig
  mmuBadAddr = value;
182 8 hellwig
}
183
 
184
 
185
void mmuTbs(void) {
186
  int index;
187
 
188
  index = assoc(tlbEntryHi & PAGE_MASK);
189
  if (index == -1) {
190
    tlbIndex = 0x80000000;
191
  } else {
192
    tlbIndex = index;
193
  }
194
}
195
 
196
 
197
void mmuTbwr(void) {
198
  int index;
199
 
200
  /* choose a random index, but don't touch fixed entries */
201
  do {
202
    index = rand() & TLB_MASK;
203
  } while (index < TLB_FIXED);
204
  tlb[index].page = tlbEntryHi & PAGE_MASK;
205
  tlb[index].frame = tlbEntryLo & PAGE_MASK;
206
  tlb[index].write = tlbEntryLo & TLB_WRITE ? true : false;
207
  tlb[index].valid = tlbEntryLo & TLB_VALID ? true : false;
208
  if (debugWrite) {
209
    cPrintf("**** TLB[%02d] <- 0x%08X 0x%08X %c %c ****\n",
210
            index, tlb[index].page, tlb[index].frame,
211
            tlb[index].write ? 'w' : '-',
212
            tlb[index].valid ? 'v' : '-');
213
  }
214
}
215
 
216
 
217
void mmuTbri(void) {
218
  int index;
219
 
220
  index = tlbIndex & TLB_MASK;
221
  tlbEntryHi = tlb[index].page;
222
  tlbEntryLo = tlb[index].frame;
223
  if (tlb[index].write) {
224
    tlbEntryLo |= TLB_WRITE;
225
  }
226
  if (tlb[index].valid) {
227
    tlbEntryLo |= TLB_VALID;
228
  }
229
}
230
 
231
 
232
void mmuTbwi(void) {
233
  int index;
234
 
235
  index = tlbIndex & TLB_MASK;
236
  tlb[index].page = tlbEntryHi & PAGE_MASK;
237
  tlb[index].frame = tlbEntryLo & PAGE_MASK;
238
  tlb[index].write = tlbEntryLo & TLB_WRITE ? true : false;
239
  tlb[index].valid = tlbEntryLo & TLB_VALID ? true : false;
240
  if (debugWrite) {
241
    cPrintf("**** TLB[%02d] <- 0x%08X 0x%08X %c %c ****\n",
242
            index, tlb[index].page, tlb[index].frame,
243
            tlb[index].write ? 'w' : '-',
244
            tlb[index].valid ? 'v' : '-');
245
  }
246
}
247
 
248
 
249
TLB_Entry mmuGetTLB(int index) {
250
  return tlb[index & TLB_MASK];
251
}
252
 
253
 
254
void mmuSetTLB(int index, TLB_Entry tlbEntry) {
255
  index &= TLB_MASK;
256
  tlb[index] = tlbEntry;
257
  if (debugWrite) {
258
    cPrintf("**** TLB[%02d] <- 0x%08X 0x%08X %c %c ****\n",
259
            index, tlb[index].page, tlb[index].frame,
260
            tlb[index].write ? 'w' : '-',
261
            tlb[index].valid ? 'v' : '-');
262
  }
263
}
264
 
265
 
266
void mmuReset(void) {
267
  int i;
268
 
269
  cPrintf("Resetting MMU...\n");
270
  for (i = 0; i < TLB_SIZE; i++) {
271
    tlb[i].page = rand() & PAGE_MASK;
272
    tlb[i].frame = rand() & PAGE_MASK;
273
    tlb[i].write = rand() & 0x1000 ? true : false;
274
    tlb[i].valid = rand() & 0x1000 ? true : false;
275
    if (debugWrite) {
276
      cPrintf("**** TLB[%02d] <- 0x%08X 0x%08X %c %c ****\n",
277
              i, tlb[i].page, tlb[i].frame,
278
              tlb[i].write ? 'w' : '-',
279
              tlb[i].valid ? 'v' : '-');
280
    }
281
  }
282
  tlbIndex = rand() & TLB_MASK;
283
  tlbEntryHi = rand() & PAGE_MASK;
284
  tlbEntryLo = rand() & (PAGE_MASK | TLB_WRITE | TLB_VALID);
285 78 hellwig
  mmuBadAddr = rand();
286 8 hellwig
}
287
 
288
 
289
void mmuInit(void) {
290
  mmuReset();
291
}
292
 
293
 
294
void mmuExit(void) {
295
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.