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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [sim/] [arm/] [armvirt.c] - Blame information for rev 1782

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

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

powered by: WebSVN 2.1.0

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