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

Subversion Repositories or1k

[/] [or1k/] [branches/] [oc/] [gdb-5.0/] [sim/] [arm/] [armvirt.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 106 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 "armdefs.h"
28
#include "ansidecl.h"
29
 
30
#ifdef VALIDATE                 /* for running the validate suite */
31
#define TUBE 48 * 1024 * 1024   /* write a char on the screen */
32
#define ABORTS 1
33
#endif
34
 
35
#define ABORTS
36
 
37
#ifdef ABORTS                   /* the memory system will abort */
38
/* For the old test suite Abort between 32 Kbytes and 32 Mbytes
39
   For the new test suite Abort between 8 Mbytes and 26 Mbytes */
40
/* #define LOWABORT 32 * 1024
41
#define HIGHABORT 32 * 1024 * 1024 */
42
#define LOWABORT 8 * 1024 * 1024
43
#define HIGHABORT 26 * 1024 * 1024
44
 
45
#endif
46
 
47
#define NUMPAGES 64 * 1024
48
#define PAGESIZE 64 * 1024
49
#define PAGEBITS 16
50
#define OFFSETBITS 0xffff
51
 
52
/***************************************************************************\
53
*        Get a Word from Virtual Memory, maybe allocating the page          *
54
\***************************************************************************/
55
 
56
static ARMword
57
GetWord (ARMul_State * state, ARMword address)
58
{
59
  ARMword page;
60
  ARMword offset;
61
  ARMword **pagetable;
62
  ARMword *pageptr;
63
 
64
  page = address >> PAGEBITS;
65
  offset = (address & OFFSETBITS) >> 2;
66
  pagetable = (ARMword **) state->MemDataPtr;
67
  pageptr = *(pagetable + page);
68
 
69
  if (pageptr == NULL)
70
    {
71
      pageptr = (ARMword *) malloc (PAGESIZE);
72
 
73
      if (pageptr == NULL)
74
        {
75
          perror ("ARMulator can't allocate VM page");
76
          exit (12);
77
        }
78
 
79
      *(pagetable + page) = pageptr;
80
    }
81
 
82
  return *(pageptr + offset);
83
}
84
 
85
/***************************************************************************\
86
*        Put a Word into Virtual Memory, maybe allocating the page          *
87
\***************************************************************************/
88
 
89
static void
90
PutWord (ARMul_State * state, ARMword address, ARMword data)
91
{
92
  ARMword page;
93
  ARMword offset;
94
  ARMword **pagetable;
95
  ARMword *pageptr;
96
 
97
  page = address >> PAGEBITS;
98
  offset = (address & OFFSETBITS) >> 2;
99
  pagetable = (ARMword **) state->MemDataPtr;
100
  pageptr = *(pagetable + page);
101
 
102
  if (pageptr == NULL)
103
    {
104
      pageptr = (ARMword *) malloc (PAGESIZE);
105
      if (pageptr == NULL)
106
        {
107
          perror ("ARMulator can't allocate VM page");
108
          exit (13);
109
        }
110
 
111
      *(pagetable + page) = pageptr;
112
    }
113
 
114
  *(pageptr + offset) = data;
115
}
116
 
117
/***************************************************************************\
118
*                      Initialise the memory interface                      *
119
\***************************************************************************/
120
 
121
unsigned
122
ARMul_MemoryInit (ARMul_State * state, unsigned long initmemsize)
123
{
124
  ARMword **pagetable;
125
  unsigned page;
126
 
127
  if (initmemsize)
128
    state->MemSize = initmemsize;
129
 
130
  pagetable = (ARMword **) malloc (sizeof (ARMword) * NUMPAGES);
131
 
132
  if (pagetable == NULL)
133
    return FALSE;
134
 
135
  for (page = 0; page < NUMPAGES; page++)
136
    *(pagetable + page) = NULL;
137
 
138
  state->MemDataPtr = (unsigned char *) pagetable;
139
 
140
  ARMul_ConsolePrint (state, ", 4 Gb memory");
141
 
142
  return TRUE;
143
}
144
 
145
/***************************************************************************\
146
*                         Remove the memory interface                       *
147
\***************************************************************************/
148
 
149
void
150
ARMul_MemoryExit (ARMul_State * state)
151
{
152
  ARMword page;
153
  ARMword **pagetable;
154
  ARMword *pageptr;
155
 
156
  pagetable = (ARMword **) state->MemDataPtr;
157
  for (page = 0; page < NUMPAGES; page++)
158
    {
159
      pageptr = *(pagetable + page);
160
      if (pageptr != NULL)
161
        free ((char *) pageptr);
162
    }
163
  free ((char *) pagetable);
164
  return;
165
}
166
 
167
/***************************************************************************\
168
*                   ReLoad Instruction                                     *
169
\***************************************************************************/
170
 
171
ARMword
172
ARMul_ReLoadInstr (ARMul_State * state, ARMword address, ARMword isize)
173
{
174
#ifdef ABORTS
175
  if (address >= LOWABORT && address < HIGHABORT)
176
    {
177
      ARMul_PREFETCHABORT (address);
178
      return ARMul_ABORTWORD;
179
    }
180
  else
181
    {
182
      ARMul_CLEARABORT;
183
    }
184
#endif
185
 
186
  if ((isize == 2) && (address & 0x2))
187
    {
188
      /* We return the next two halfwords: */
189
      ARMword lo = GetWord (state, address);
190
      ARMword hi = GetWord (state, address + 4);
191
 
192
      if (state->bigendSig == HIGH)
193
        return (lo << 16) | (hi >> 16);
194
      else
195
        return ((hi & 0xFFFF) << 16) | (lo >> 16);
196
    }
197
 
198
  return GetWord (state, address);
199
}
200
 
201
/***************************************************************************\
202
*                   Load Instruction, Sequential Cycle                      *
203
\***************************************************************************/
204
 
205
ARMword ARMul_LoadInstrS (ARMul_State * state, ARMword address, ARMword isize)
206
{
207
  state->NumScycles++;
208
 
209
#ifdef HOURGLASS
210
  if ((state->NumScycles & HOURGLASS_RATE) == 0)
211
    {
212
      HOURGLASS;
213
    }
214
#endif
215
 
216
  return ARMul_ReLoadInstr (state, address, isize);
217
}
218
 
219
/***************************************************************************\
220
*                 Load Instruction, Non Sequential Cycle                    *
221
\***************************************************************************/
222
 
223
ARMword ARMul_LoadInstrN (ARMul_State * state, ARMword address, ARMword isize)
224
{
225
  state->NumNcycles++;
226
 
227
  return ARMul_ReLoadInstr (state, address, isize);
228
}
229
 
230
/***************************************************************************\
231
*                      Read Word (but don't tell anyone!)                   *
232
\***************************************************************************/
233
 
234
ARMword ARMul_ReadWord (ARMul_State * state, ARMword address)
235
{
236
#ifdef ABORTS
237
  if (address >= LOWABORT && address < HIGHABORT)
238
    {
239
      ARMul_DATAABORT (address);
240
      return ARMul_ABORTWORD;
241
    }
242
  else
243
    {
244
      ARMul_CLEARABORT;
245
    }
246
#endif
247
 
248
  return GetWord (state, address);
249
}
250
 
251
/***************************************************************************\
252
*                        Load Word, Sequential Cycle                        *
253
\***************************************************************************/
254
 
255
ARMword ARMul_LoadWordS (ARMul_State * state, ARMword address)
256
{
257
  state->NumScycles++;
258
 
259
  return ARMul_ReadWord (state, address);
260
}
261
 
262
/***************************************************************************\
263
*                      Load Word, Non Sequential Cycle                      *
264
\***************************************************************************/
265
 
266
ARMword ARMul_LoadWordN (ARMul_State * state, ARMword address)
267
{
268
  state->NumNcycles++;
269
 
270
  return ARMul_ReadWord (state, address);
271
}
272
 
273
/***************************************************************************\
274
*                     Load Halfword, (Non Sequential Cycle)                 *
275
\***************************************************************************/
276
 
277
ARMword ARMul_LoadHalfWord (ARMul_State * state, ARMword address)
278
{
279
  ARMword temp, offset;
280
 
281
  state->NumNcycles++;
282
 
283
  temp = ARMul_ReadWord (state, address);
284
  offset = (((ARMword) state->bigendSig * 2) ^ (address & 2)) << 3;     /* bit offset into the word */
285
 
286
  return (temp >> offset) & 0xffff;
287
}
288
 
289
/***************************************************************************\
290
*                      Read Byte (but don't tell anyone!)                   *
291
\***************************************************************************/
292
 
293
ARMword ARMul_ReadByte (ARMul_State * state, ARMword address)
294
{
295
  ARMword temp, offset;
296
 
297
  temp = ARMul_ReadWord (state, address);
298
  offset = (((ARMword) state->bigendSig * 3) ^ (address & 3)) << 3;     /* bit offset into the word */
299
 
300
  return (temp >> offset & 0xffL);
301
}
302
 
303
/***************************************************************************\
304
*                     Load Byte, (Non Sequential Cycle)                     *
305
\***************************************************************************/
306
 
307
ARMword ARMul_LoadByte (ARMul_State * state, ARMword address)
308
{
309
  state->NumNcycles++;
310
 
311
  return ARMul_ReadByte (state, address);
312
}
313
 
314
/***************************************************************************\
315
*                     Write Word (but don't tell anyone!)                   *
316
\***************************************************************************/
317
 
318
void
319
ARMul_WriteWord (ARMul_State * state, ARMword address, ARMword data)
320
{
321
#ifdef ABORTS
322
  if (address >= LOWABORT && address < HIGHABORT)
323
    {
324
      ARMul_DATAABORT (address);
325
      return;
326
    }
327
  else
328
    {
329
      ARMul_CLEARABORT;
330
    }
331
#endif
332
 
333
  PutWord (state, address, data);
334
}
335
 
336
/***************************************************************************\
337
*                       Store Word, Sequential Cycle                        *
338
\***************************************************************************/
339
 
340
void
341
ARMul_StoreWordS (ARMul_State * state, ARMword address, ARMword data)
342
{
343
  state->NumScycles++;
344
 
345
  ARMul_WriteWord (state, address, data);
346
}
347
 
348
/***************************************************************************\
349
*                       Store Word, Non Sequential Cycle                        *
350
\***************************************************************************/
351
 
352
void
353
ARMul_StoreWordN (ARMul_State * state, ARMword address, ARMword data)
354
{
355
  state->NumNcycles++;
356
 
357
  ARMul_WriteWord (state, address, data);
358
}
359
 
360
/***************************************************************************\
361
*                    Store HalfWord, (Non Sequential Cycle)                 *
362
\***************************************************************************/
363
 
364
void
365
ARMul_StoreHalfWord (ARMul_State * state, ARMword address, ARMword data)
366
{
367
  ARMword temp, offset;
368
 
369
  state->NumNcycles++;
370
 
371
#ifdef VALIDATE
372
  if (address == TUBE)
373
    {
374
      if (data == 4)
375
        state->Emulate = FALSE;
376
      else
377
        (void) putc ((char) data, stderr);      /* Write Char */
378
      return;
379
    }
380
#endif
381
 
382
  temp = ARMul_ReadWord (state, address);
383
  offset = (((ARMword) state->bigendSig * 2) ^ (address & 2)) << 3;     /* bit offset into the word */
384
 
385
  PutWord (state, address,
386
           (temp & ~(0xffffL << offset)) | ((data & 0xffffL) << offset));
387
}
388
 
389
/***************************************************************************\
390
*                     Write Byte (but don't tell anyone!)                   *
391
\***************************************************************************/
392
 
393
void
394
ARMul_WriteByte (ARMul_State * state, ARMword address, ARMword data)
395
{
396
  ARMword temp, offset;
397
 
398
  temp = ARMul_ReadWord (state, address);
399
  offset = (((ARMword) state->bigendSig * 3) ^ (address & 3)) << 3;     /* bit offset into the word */
400
 
401
  PutWord (state, address,
402
           (temp & ~(0xffL << offset)) | ((data & 0xffL) << offset));
403
}
404
 
405
/***************************************************************************\
406
*                    Store Byte, (Non Sequential Cycle)                     *
407
\***************************************************************************/
408
 
409
void
410
ARMul_StoreByte (ARMul_State * state, ARMword address, ARMword data)
411
{
412
  state->NumNcycles++;
413
 
414
#ifdef VALIDATE
415
  if (address == TUBE)
416
    {
417
      if (data == 4)
418
        state->Emulate = FALSE;
419
      else
420
        (void) putc ((char) data, stderr);      /* Write Char */
421
      return;
422
    }
423
#endif
424
 
425
  ARMul_WriteByte (state, address, data);
426
}
427
 
428
/***************************************************************************\
429
*                   Swap Word, (Two Non Sequential Cycles)                  *
430
\***************************************************************************/
431
 
432
ARMword ARMul_SwapWord (ARMul_State * state, ARMword address, ARMword data)
433
{
434
  ARMword temp;
435
 
436
  state->NumNcycles++;
437
 
438
  temp = ARMul_ReadWord (state, address);
439
 
440
  state->NumNcycles++;
441
 
442
  PutWord (state, address, data);
443
 
444
  return temp;
445
}
446
 
447
/***************************************************************************\
448
*                   Swap Byte, (Two Non Sequential Cycles)                  *
449
\***************************************************************************/
450
 
451
ARMword ARMul_SwapByte (ARMul_State * state, ARMword address, ARMword data)
452
{
453
  ARMword temp;
454
 
455
  temp = ARMul_LoadByte (state, address);
456
  ARMul_StoreByte (state, address, data);
457
 
458
  return temp;
459
}
460
 
461
/***************************************************************************\
462
*                             Count I Cycles                                *
463
\***************************************************************************/
464
 
465
void
466
ARMul_Icycles (ARMul_State * state, unsigned number, ARMword address ATTRIBUTE_UNUSED)
467
{
468
  state->NumIcycles += number;
469
  ARMul_CLEARABORT;
470
}
471
 
472
/***************************************************************************\
473
*                             Count C Cycles                                *
474
\***************************************************************************/
475
 
476
void
477
ARMul_Ccycles (ARMul_State * state, unsigned number, ARMword address ATTRIBUTE_UNUSED)
478
{
479
  state->NumCcycles += number;
480
  ARMul_CLEARABORT;
481
}

powered by: WebSVN 2.1.0

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