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

Subversion Repositories eco32

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

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

powered by: WebSVN 2.1.0

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