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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [sim/] [arm/] [armvirt.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/*  armvirt.c -- ARMulator virtual memory interace:  ARM6 Instruction Emulator.
2
    Copyright (C) 1994 Advanced RISC Machines Ltd.
3
 
4
    This program is free software; you can redistribute it and/or modify
5
    it under the terms of the GNU General Public License as published by
6
    the Free Software Foundation; either version 2 of the License, or
7
    (at your option) any later version.
8
 
9
    This program is distributed in the hope that it will be useful,
10
    but WITHOUT ANY WARRANTY; without even the implied warranty of
11
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
    GNU General Public License for more details.
13
 
14
    You should have received a copy of the GNU General Public License
15
    along with this program; if not, write to the Free Software
16
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
 
18
/* This file contains a complete ARMulator memory model, modelling a
19
"virtual memory" system. A much simpler model can be found in armfast.c,
20
and that model goes faster too, but has a fixed amount of memory. This
21
model's memory has 64K pages, allocated on demand from a 64K entry page
22
table. The routines PutWord and GetWord implement this. Pages are never
23
freed as they might be needed again. A single area of memory may be
24
defined to generate aborts. */
25
 
26
#include "armopts.h"
27
#include "armos.h"
28
#include "armdefs.h"
29
#include "ansidecl.h"
30
 
31
#ifdef VALIDATE                 /* for running the validate suite */
32
#define TUBE 48 * 1024 * 1024   /* write a char on the screen */
33
#define ABORTS 1
34
#endif
35
 
36
/* #define ABORTS */
37
 
38
#ifdef ABORTS                   /* the memory system will abort */
39
/* For the old test suite Abort between 32 Kbytes and 32 Mbytes
40
   For the new test suite Abort between 8 Mbytes and 26 Mbytes */
41
/* #define LOWABORT 32 * 1024
42
#define HIGHABORT 32 * 1024 * 1024 */
43
#define LOWABORT 8 * 1024 * 1024
44
#define HIGHABORT 26 * 1024 * 1024
45
 
46
#endif
47
 
48
#define NUMPAGES 64 * 1024
49
#define PAGESIZE 64 * 1024
50
#define PAGEBITS 16
51
#define OFFSETBITS 0xffff
52
 
53
int SWI_vector_installed = FALSE;
54
 
55
/***************************************************************************\
56
*        Get a Word from Virtual Memory, maybe allocating the page          *
57
\***************************************************************************/
58
 
59
static ARMword
60
GetWord (ARMul_State * state, ARMword address, int check)
61
{
62
  ARMword page;
63
  ARMword offset;
64
  ARMword **pagetable;
65
  ARMword *pageptr;
66
 
67
  XScale_check_memacc (state, &address, 0);
68
 
69
  page = address >> PAGEBITS;
70
  offset = (address & OFFSETBITS) >> 2;
71
  pagetable = (ARMword **) state->MemDataPtr;
72
  pageptr = *(pagetable + page);
73
 
74
  if (pageptr == NULL)
75
    {
76
      pageptr = (ARMword *) malloc (PAGESIZE);
77
 
78
      if (pageptr == NULL)
79
        {
80
          perror ("ARMulator can't allocate VM page");
81
          exit (12);
82
        }
83
 
84
      *(pagetable + page) = pageptr;
85
    }
86
 
87
  return *(pageptr + offset);
88
}
89
 
90
/***************************************************************************\
91
*        Put a Word into Virtual Memory, maybe allocating the page          *
92
\***************************************************************************/
93
 
94
static void
95
PutWord (ARMul_State * state, ARMword address, ARMword data, int check)
96
{
97
  ARMword page;
98
  ARMword offset;
99
  ARMword **pagetable;
100
  ARMword *pageptr;
101
 
102
  XScale_check_memacc (state, &address, 1);
103
 
104
  page = address >> PAGEBITS;
105
  offset = (address & OFFSETBITS) >> 2;
106
  pagetable = (ARMword **) state->MemDataPtr;
107
  pageptr = *(pagetable + page);
108
 
109
  if (pageptr == NULL)
110
    {
111
      pageptr = (ARMword *) malloc (PAGESIZE);
112
      if (pageptr == NULL)
113
        {
114
          perror ("ARMulator can't allocate VM page");
115
          exit (13);
116
        }
117
 
118
      *(pagetable + page) = pageptr;
119
    }
120
 
121
  if (address == 0x8)
122
    SWI_vector_installed = TRUE;
123
 
124
  *(pageptr + offset) = data;
125
}
126
 
127
/***************************************************************************\
128
*                      Initialise the memory interface                      *
129
\***************************************************************************/
130
 
131
unsigned
132
ARMul_MemoryInit (ARMul_State * state, unsigned long initmemsize)
133
{
134
  ARMword **pagetable;
135
  unsigned page;
136
 
137
  if (initmemsize)
138
    state->MemSize = initmemsize;
139
 
140
  pagetable = (ARMword **) malloc (sizeof (ARMword) * NUMPAGES);
141
 
142
  if (pagetable == NULL)
143
    return FALSE;
144
 
145
  for (page = 0; page < NUMPAGES; page++)
146
    *(pagetable + page) = NULL;
147
 
148
  state->MemDataPtr = (unsigned char *) pagetable;
149
 
150
  ARMul_ConsolePrint (state, ", 4 Gb memory");
151
 
152
  return TRUE;
153
}
154
 
155
/***************************************************************************\
156
*                         Remove the memory interface                       *
157
\***************************************************************************/
158
 
159
void
160
ARMul_MemoryExit (ARMul_State * state)
161
{
162
  ARMword page;
163
  ARMword **pagetable;
164
  ARMword *pageptr;
165
 
166
  pagetable = (ARMword **) state->MemDataPtr;
167
  for (page = 0; page < NUMPAGES; page++)
168
    {
169
      pageptr = *(pagetable + page);
170
      if (pageptr != NULL)
171
        free ((char *) pageptr);
172
    }
173
  free ((char *) pagetable);
174
  return;
175
}
176
 
177
/***************************************************************************\
178
*                   ReLoad Instruction                                     *
179
\***************************************************************************/
180
 
181
ARMword
182
ARMul_ReLoadInstr (ARMul_State * state, ARMword address, ARMword isize)
183
{
184
#ifdef ABORTS
185
  if (address >= LOWABORT && address < HIGHABORT)
186
    {
187
      ARMul_PREFETCHABORT (address);
188
      return ARMul_ABORTWORD;
189
    }
190
  else
191
    {
192
      ARMul_CLEARABORT;
193
    }
194
#endif
195
 
196
  if ((isize == 2) && (address & 0x2))
197
    {
198
      /* We return the next two halfwords: */
199
      ARMword lo = GetWord (state, address, FALSE);
200
      ARMword hi = GetWord (state, address + 4, FALSE);
201
 
202
      if (state->bigendSig == HIGH)
203
        return (lo << 16) | (hi >> 16);
204
      else
205
        return ((hi & 0xFFFF) << 16) | (lo >> 16);
206
    }
207
 
208
  return GetWord (state, address, TRUE);
209
}
210
 
211
/***************************************************************************\
212
*                   Load Instruction, Sequential Cycle                      *
213
\***************************************************************************/
214
 
215
ARMword ARMul_LoadInstrS (ARMul_State * state, ARMword address, ARMword isize)
216
{
217
  state->NumScycles++;
218
 
219
#ifdef HOURGLASS
220
  if ((state->NumScycles & HOURGLASS_RATE) == 0)
221
    {
222
      HOURGLASS;
223
    }
224
#endif
225
 
226
  return ARMul_ReLoadInstr (state, address, isize);
227
}
228
 
229
/***************************************************************************\
230
*                 Load Instruction, Non Sequential Cycle                    *
231
\***************************************************************************/
232
 
233
ARMword ARMul_LoadInstrN (ARMul_State * state, ARMword address, ARMword isize)
234
{
235
  state->NumNcycles++;
236
 
237
  return ARMul_ReLoadInstr (state, address, isize);
238
}
239
 
240
/***************************************************************************\
241
*                      Read Word (but don't tell anyone!)                   *
242
\***************************************************************************/
243
 
244
ARMword ARMul_ReadWord (ARMul_State * state, ARMword address)
245
{
246
#ifdef ABORTS
247
  if (address >= LOWABORT && address < HIGHABORT)
248
    {
249
      ARMul_DATAABORT (address);
250
      return ARMul_ABORTWORD;
251
    }
252
  else
253
    {
254
      ARMul_CLEARABORT;
255
    }
256
#endif
257
 
258
  return GetWord (state, address, TRUE);
259
}
260
 
261
/***************************************************************************\
262
*                        Load Word, Sequential Cycle                        *
263
\***************************************************************************/
264
 
265
ARMword ARMul_LoadWordS (ARMul_State * state, ARMword address)
266
{
267
  state->NumScycles++;
268
 
269
  return ARMul_ReadWord (state, address);
270
}
271
 
272
/***************************************************************************\
273
*                      Load Word, Non Sequential Cycle                      *
274
\***************************************************************************/
275
 
276
ARMword ARMul_LoadWordN (ARMul_State * state, ARMword address)
277
{
278
  state->NumNcycles++;
279
 
280
  return ARMul_ReadWord (state, address);
281
}
282
 
283
/***************************************************************************\
284
*                     Load Halfword, (Non Sequential Cycle)                 *
285
\***************************************************************************/
286
 
287
ARMword ARMul_LoadHalfWord (ARMul_State * state, ARMword address)
288
{
289
  ARMword temp, offset;
290
 
291
  state->NumNcycles++;
292
 
293
  temp = ARMul_ReadWord (state, address);
294
  offset = (((ARMword) state->bigendSig * 2) ^ (address & 2)) << 3;     /* bit offset into the word */
295
 
296
  return (temp >> offset) & 0xffff;
297
}
298
 
299
/***************************************************************************\
300
*                      Read Byte (but don't tell anyone!)                   *
301
\***************************************************************************/
302
 
303
ARMword ARMul_ReadByte (ARMul_State * state, ARMword address)
304
{
305
  ARMword temp, offset;
306
 
307
  temp = ARMul_ReadWord (state, address);
308
  offset = (((ARMword) state->bigendSig * 3) ^ (address & 3)) << 3;     /* bit offset into the word */
309
 
310
  return (temp >> offset & 0xffL);
311
}
312
 
313
/***************************************************************************\
314
*                     Load Byte, (Non Sequential Cycle)                     *
315
\***************************************************************************/
316
 
317
ARMword ARMul_LoadByte (ARMul_State * state, ARMword address)
318
{
319
  state->NumNcycles++;
320
 
321
  return ARMul_ReadByte (state, address);
322
}
323
 
324
/***************************************************************************\
325
*                     Write Word (but don't tell anyone!)                   *
326
\***************************************************************************/
327
 
328
void
329
ARMul_WriteWord (ARMul_State * state, ARMword address, ARMword data)
330
{
331
#ifdef ABORTS
332
  if (address >= LOWABORT && address < HIGHABORT)
333
    {
334
      ARMul_DATAABORT (address);
335
      return;
336
    }
337
  else
338
    {
339
      ARMul_CLEARABORT;
340
    }
341
#endif
342
 
343
  PutWord (state, address, data, TRUE);
344
}
345
 
346
/***************************************************************************\
347
*                       Store Word, Sequential Cycle                        *
348
\***************************************************************************/
349
 
350
void
351
ARMul_StoreWordS (ARMul_State * state, ARMword address, ARMword data)
352
{
353
  state->NumScycles++;
354
 
355
  ARMul_WriteWord (state, address, data);
356
}
357
 
358
/***************************************************************************\
359
*                       Store Word, Non Sequential Cycle                        *
360
\***************************************************************************/
361
 
362
void
363
ARMul_StoreWordN (ARMul_State * state, ARMword address, ARMword data)
364
{
365
  state->NumNcycles++;
366
 
367
  ARMul_WriteWord (state, address, data);
368
}
369
 
370
/***************************************************************************\
371
*                    Store HalfWord, (Non Sequential Cycle)                 *
372
\***************************************************************************/
373
 
374
void
375
ARMul_StoreHalfWord (ARMul_State * state, ARMword address, ARMword data)
376
{
377
  ARMword temp, offset;
378
 
379
  state->NumNcycles++;
380
 
381
#ifdef VALIDATE
382
  if (address == TUBE)
383
    {
384
      if (data == 4)
385
        state->Emulate = FALSE;
386
      else
387
        (void) putc ((char) data, stderr);      /* Write Char */
388
      return;
389
    }
390
#endif
391
 
392
  temp = ARMul_ReadWord (state, address);
393
  offset = (((ARMword) state->bigendSig * 2) ^ (address & 2)) << 3;     /* bit offset into the word */
394
 
395
  PutWord (state, address,
396
           (temp & ~(0xffffL << offset)) | ((data & 0xffffL) << offset),
397
           TRUE);
398
}
399
 
400
/***************************************************************************\
401
*                     Write Byte (but don't tell anyone!)                   *
402
\***************************************************************************/
403
 
404
void
405
ARMul_WriteByte (ARMul_State * state, ARMword address, ARMword data)
406
{
407
  ARMword temp, offset;
408
 
409
  temp = ARMul_ReadWord (state, address);
410
  offset = (((ARMword) state->bigendSig * 3) ^ (address & 3)) << 3;     /* bit offset into the word */
411
 
412
  PutWord (state, address,
413
           (temp & ~(0xffL << offset)) | ((data & 0xffL) << offset),
414
           TRUE);
415
}
416
 
417
/***************************************************************************\
418
*                    Store Byte, (Non Sequential Cycle)                     *
419
\***************************************************************************/
420
 
421
void
422
ARMul_StoreByte (ARMul_State * state, ARMword address, ARMword data)
423
{
424
  state->NumNcycles++;
425
 
426
#ifdef VALIDATE
427
  if (address == TUBE)
428
    {
429
      if (data == 4)
430
        state->Emulate = FALSE;
431
      else
432
        (void) putc ((char) data, stderr);      /* Write Char */
433
      return;
434
    }
435
#endif
436
 
437
  ARMul_WriteByte (state, address, data);
438
}
439
 
440
/***************************************************************************\
441
*                   Swap Word, (Two Non Sequential Cycles)                  *
442
\***************************************************************************/
443
 
444
ARMword ARMul_SwapWord (ARMul_State * state, ARMword address, ARMword data)
445
{
446
  ARMword temp;
447
 
448
  state->NumNcycles++;
449
 
450
  temp = ARMul_ReadWord (state, address);
451
 
452
  state->NumNcycles++;
453
 
454
  PutWord (state, address, data, TRUE);
455
 
456
  return temp;
457
}
458
 
459
/***************************************************************************\
460
*                   Swap Byte, (Two Non Sequential Cycles)                  *
461
\***************************************************************************/
462
 
463
ARMword ARMul_SwapByte (ARMul_State * state, ARMword address, ARMword data)
464
{
465
  ARMword temp;
466
 
467
  temp = ARMul_LoadByte (state, address);
468
  ARMul_StoreByte (state, address, data);
469
 
470
  return temp;
471
}
472
 
473
/***************************************************************************\
474
*                             Count I Cycles                                *
475
\***************************************************************************/
476
 
477
void
478
ARMul_Icycles (ARMul_State * state, unsigned number, ARMword address ATTRIBUTE_UNUSED)
479
{
480
  state->NumIcycles += number;
481
  ARMul_CLEARABORT;
482
}
483
 
484
/***************************************************************************\
485
*                             Count C Cycles                                *
486
\***************************************************************************/
487
 
488
void
489
ARMul_Ccycles (ARMul_State * state, unsigned number, ARMword address ATTRIBUTE_UNUSED)
490
{
491
  state->NumCcycles += number;
492
  ARMul_CLEARABORT;
493
}
494
 
495
 
496
/* Read a byte.  Do not check for alignment or access errors.  */
497
 
498
ARMword
499
ARMul_SafeReadByte (ARMul_State * state, ARMword address)
500
{
501
  ARMword temp, offset;
502
 
503
  temp = GetWord (state, address, FALSE);
504
  offset = (((ARMword) state->bigendSig * 3) ^ (address & 3)) << 3;
505
 
506
  return (temp >> offset & 0xffL);
507
}
508
 
509
void
510
ARMul_SafeWriteByte (ARMul_State * state, ARMword address, ARMword data)
511
{
512
  ARMword temp, offset;
513
 
514
  temp = GetWord (state, address, FALSE);
515
  offset = (((ARMword) state->bigendSig * 3) ^ (address & 3)) << 3;
516
 
517
  PutWord (state, address,
518
           (temp & ~(0xffL << offset)) | ((data & 0xffL) << offset),
519
           FALSE);
520
}

powered by: WebSVN 2.1.0

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