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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_42/] [or1ksim/] [cpu/] [common/] [abstract.c] - Blame information for rev 235

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

Line No. Rev Author Line
1 2 cvs
/* abstract.c -- Abstract entities
2
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
3
 
4
This file is part of OpenRISC 1000 Architectural Simulator.
5
 
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or
9
(at your option) any later version.
10
 
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
GNU General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
 
20 66 lampret
/* Abstract memory and routines that go with this. I need to
21 2 cvs
add all sorts of other abstract entities. Currently we have
22
only memory. */
23
 
24 221 markom
#include <stdlib.h>
25 2 cvs
#include <stdio.h>
26
#include <ctype.h>
27
#include <string.h>
28
 
29 6 lampret
#include "config.h"
30 7 jrydberg
#include "sim-config.h"
31 6 lampret
 
32 2 cvs
#include "parse.h"
33
#include "abstract.h"
34
#include "arch.h"
35
#include "trace.h"
36
#include "execute.h"
37 32 lampret
#include "sprs.h"
38 35 lampret
#include "stats.h"
39 32 lampret
#include "except.h"
40 123 markom
#include "debug_unit.h"
41 134 markom
#include "opcode/or32.h"
42 2 cvs
 
43
extern unsigned long reg[];
44 138 markom
extern char *disassembled;
45 2 cvs
 
46 28 lampret
/* This is an abstract+physical memory array rather than only physical
47
   memory array */
48 221 markom
static struct mem_entry *simmem;
49 2 cvs
 
50 30 lampret
/* Pointer to memory area descriptions that are assigned to individual
51
   peripheral devices. */
52
struct dev_memarea *dev_list;
53
 
54 221 markom
/* Temporary variable to increase speed.  */
55
struct dev_memarea *cur_area;
56
 
57 167 markom
void dumpmemory(unsigned int from, unsigned int to, int disasm)
58 2 cvs
{
59 235 erez
        unsigned int i, j;
60
        struct label_entry *tmp;
61
        int breakpoint = 0;
62
        int ilen = disasm ? 4 : 16;
63 221 markom
 
64 235 erez
        for(i = from; i < to; i += ilen) {
65
                for (j = 0; j < ilen;) {
66
                        int data = -1;
67
                        if (!disasm) {
68
                                tmp = NULL;
69
                                if (verify_memoryarea(i+j)) {
70
                                        struct mem_entry *entry;
71
                                        if (cur_area->getentry && (entry = cur_area->getentry(i+j)))
72
                                                for(tmp = entry->label; tmp; tmp = tmp->next)
73
                                                        printf(" %s%s", tmp->name, LABELEND_CHAR);
74
                                        printf("%02x ", data = evalsim_mem8(i+j));
75
                                } else printf("XX ");
76
                                j++;
77
                        } else {
78
                                int breakpoint;
79
                                unsigned int _insn = eval_mem32(i, &breakpoint);
80
                                int index = insn_decode (_insn);
81
                                int len = insn_len (index);
82
 
83
                                tmp = NULL;
84
                                if (verify_memoryarea(i+j)) {
85
                                        struct mem_entry *entry;
86
                                        if (cur_area->getentry && (entry = cur_area->getentry(i+j)))
87
                                                tmp = entry->label;
88
 
89
                                        for(; tmp; tmp = tmp->next)
90
                                                printf(" %s%s", tmp->name, LABELEND_CHAR);
91
                                        printf("%.8x:    ", i);
92 221 markom
 
93 235 erez
                                        printf("%08x            ", (unsigned char)_insn);
94
                                        if (index >= 0) {
95
                                                disassemble_insn (_insn);
96
                                                printf(" %s", disassembled);
97
                                        } else
98
                                                printf("<invalid>");
99
                                } else printf("XXXXXXXX");
100
                                j += len;
101
                        }
102
                }
103
        }
104 2 cvs
}
105
 
106
/* Searches mem array for a particular label and returns label's address.
107
   If label does not exist, returns 0. */
108 221 markom
 
109 2 cvs
unsigned long eval_label(char *label)
110
{
111
        int i;
112 235 erez
        char *plus;
113 18 lampret
        char *minus;
114
        int positive_offset = 0;
115
        int negative_offset = 0;
116 221 markom
 
117 18 lampret
        if (plus = strchr(label, '+')) {
118
                *plus = '\0';
119
                positive_offset = atoi(++plus);
120
        }
121
 
122
        if (minus = strchr(label, '-')) {
123
                *minus = '\0';
124
                negative_offset = atoi(++minus);
125
        }
126 235 erez
        for (cur_area = dev_list; cur_area; cur_area = cur_area->next) {
127
                for(i = 0; i < cur_area->size; i++) if (cur_area->getentry) {
128
                        int mi = i + cur_area->start;
129
                        struct mem_entry *entry = cur_area->getentry(mi);
130
                        if (entry) {
131
                                struct label_entry *tmp = entry->label;
132
                                for(; tmp; tmp = tmp->next)
133
                                        if (strcmp(label, tmp->name) == 0) {
134
                                                debug("eval_label(%s) => 0x%x\n", label, i + positive_offset - negative_offset + cur_area->start);
135
                                                return i + positive_offset - negative_offset + cur_area->start;
136
                                        }
137
                        }
138
                }
139
        }
140 221 markom
 
141 235 erez
        printf("\nINTERNAL ERROR: undefined label %s\n", label);
142
        cont_run = 0;
143
        return 0;
144 2 cvs
}
145
 
146 77 lampret
/* Calls IMMU translation routines before simulating insn
147
cache for virtually indexed insn cache or after simulating insn cache
148
for physically indexed insn cache. It returns physical address. */
149
 
150
unsigned long simulate_ic_mmu_fetch(unsigned long virtaddr)
151
{
152
        if (config.ic.tagtype == NONE)
153
                return virtaddr;
154
        else
155 235 erez
                if (config.ic.tagtype == VIRTUAL) {
156
                        ic_simulate_fetch(virtaddr);
157
                        return immu_translate(virtaddr);
158
                }
159
                else if (config.dc.tagtype == PHYSICAL) {
160
                        unsigned long phyaddr = immu_translate(virtaddr);
161
                        ic_simulate_fetch(phyaddr);
162
                        return phyaddr;
163
                }
164
                else {
165
                        printf("INTERNAL ERROR: Unknown insn cache type.\n");
166
                        cont_run = 0;
167
                }
168 221 markom
 
169 77 lampret
        return -1;
170
}
171
 
172
/* Calls DMMU translation routines (load cycles) before simulating data
173 235 erez
         cache for virtually indexed data cache or after simulating data cache
174
         for physically indexed data cache. It returns physical address. */
175 6 lampret
 
176
unsigned long simulate_dc_mmu_load(unsigned long virtaddr)
177
{
178 47 lampret
        if (config.dc.tagtype == NONE)
179
                return virtaddr;
180
        else
181 235 erez
        if (config.ic.tagtype == VIRTUAL) {
182
                ic_simulate_fetch(virtaddr);
183
                return immu_translate(virtaddr);
184 6 lampret
        }
185 30 lampret
        else if (config.dc.tagtype == PHYSICAL) {
186 235 erez
                unsigned long phyaddr = immu_translate(virtaddr);
187
                ic_simulate_fetch(phyaddr);
188 6 lampret
                return phyaddr;
189
        }
190
        else {
191 235 erez
                printf("INTERNAL ERROR: Unknown insn cache type.\n");
192 6 lampret
                cont_run = 0;
193
        }
194 221 markom
 
195 6 lampret
        return -1;
196
}
197
 
198 77 lampret
/* Calls DMMU translation routines (store cycles) before simulating data
199 6 lampret
cache for virtually indexed data cache or after simulating data cache
200
for physically indexed data cache. It returns physical address. */
201
 
202
unsigned long simulate_dc_mmu_store(unsigned long virtaddr)
203
{
204 47 lampret
        if (config.dc.tagtype == NONE)
205
                return virtaddr;
206
        else
207 30 lampret
        if (config.dc.tagtype == VIRTUAL) {
208 6 lampret
                dc_simulate_write(virtaddr);
209
                return dmmu_translate(virtaddr);
210
        }
211 30 lampret
        else if (config.dc.tagtype == PHYSICAL) {
212 6 lampret
                unsigned long phyaddr = dmmu_translate(virtaddr);
213
                dc_simulate_write(phyaddr);
214
                return phyaddr;
215
        }
216
        else {
217
                printf("INTERNAL ERROR: Unknown data cache type.\n");
218
                cont_run = 0;
219
        }
220 221 markom
 
221 6 lampret
        return -1;
222
}
223
 
224 30 lampret
/* Register read and write function for a memory area (used by peripheral
225
   devices like 16450 UART etc.) */
226 235 erez
void register_memoryarea(unsigned long start, unsigned long size,
227
                                                                                                 unsigned granularity,
228
                                                                                                 unsigned long (readfunc)(unsigned long),
229
                                                                                                 void (writefunc)(unsigned long, unsigned long),
230
                                                                                                 struct mem_entry *(getentry)(unsigned long))
231 30 lampret
{
232
        struct dev_memarea **pptmp;
233 221 markom
 
234 30 lampret
        /* Go to the end of the list. */
235
        for(pptmp = &dev_list; *pptmp; pptmp = &(*pptmp)->next);
236 221 markom
 
237
        cur_area = *pptmp = (struct dev_memarea *)malloc(sizeof(struct dev_memarea));
238
        (*pptmp)->start = start;
239 30 lampret
        (*pptmp)->size = size;
240 221 markom
        (*pptmp)->end = start + size;
241 235 erez
        (*pptmp)->granularity = granularity;
242 30 lampret
        (*pptmp)->readfunc = readfunc;
243
        (*pptmp)->writefunc = writefunc;
244 221 markom
        (*pptmp)->getentry = getentry;
245 30 lampret
        (*pptmp)->next = NULL;
246 221 markom
 
247 30 lampret
        return;
248
}
249
 
250
/* Check if access is to registered area of memory. */
251
struct dev_memarea *verify_memoryarea(unsigned long addr)
252
{
253
        struct dev_memarea *ptmp;
254 221 markom
 
255 30 lampret
        /* Check list of registered devices. */
256
        for(ptmp = dev_list; ptmp; ptmp = ptmp->next)
257 221 markom
                if (addr >= ptmp->start &&
258 235 erez
                                addr < (ptmp->end))
259 221 markom
                        return cur_area = ptmp;
260
        return cur_area = NULL;
261 30 lampret
}
262
 
263 2 cvs
/* Returns 32-bit values from mem array. Big endian version. */
264 123 markom
unsigned long eval_mem32(unsigned long memaddr,int* breakpoint)
265 2 cvs
{
266 6 lampret
 
267 235 erez
        unsigned long temp;
268
        struct dev_memarea *dev;
269 123 markom
 
270 235 erez
        slp_checkaccess(memaddr, SLP_MEMREAD);
271
        memaddr = simulate_dc_mmu_load(memaddr);
272
        *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
273
        temp = evalsim_mem32(memaddr);
274
        *breakpoint += CheckDebugUnit(DebugLoadData,temp);      /* MM170901 */
275 221 markom
        return temp;
276 66 lampret
}
277
 
278 221 markom
unsigned long evalsim_mem32(unsigned long memaddr)
279 66 lampret
{
280
        unsigned long temp;
281 221 markom
 
282
        if (verify_memoryarea(memaddr)) {
283 235 erez
                switch(cur_area->granularity) {
284
                case 1:
285
                        temp = cur_area->readfunc(memaddr) << 24;
286
                        temp |= cur_area->readfunc(memaddr + 1) << 16;
287
                        temp |= cur_area->readfunc(memaddr + 2) << 8;
288
                        temp |= cur_area->readfunc(memaddr + 3);
289
                        break;
290
                case 2:
291
                        temp = cur_area->readfunc(memaddr) << 16;
292
                        temp |= cur_area->readfunc(memaddr + 2);
293
                        break;
294
                case 4:
295
                        temp = cur_area->readfunc(memaddr);
296
                        break;
297
                }
298 2 cvs
        } else {
299 221 markom
                printf("EXCEPTION: read out of memory (32-bit access to %.8lx)\n", memaddr);
300 2 cvs
                cont_run = 0;
301 30 lampret
                temp = 0;
302 2 cvs
        }
303
        return temp;
304
}
305
 
306
/* Returns 16-bit values from mem array. Big endian version. */
307
 
308 123 markom
unsigned short eval_mem16(unsigned long memaddr,int* breakpoint)
309 2 cvs
{
310 235 erez
        unsigned short temp;
311 66 lampret
        memaddr = simulate_dc_mmu_load(memaddr);
312 235 erez
        *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
313 66 lampret
 
314 221 markom
        temp = evalsim_mem16(memaddr);
315 235 erez
        *breakpoint += CheckDebugUnit(DebugLoadData,temp);      /* MM170901 */
316 221 markom
        return temp;
317 66 lampret
}
318
 
319 221 markom
unsigned short evalsim_mem16(unsigned long memaddr)
320 66 lampret
{
321 2 cvs
        unsigned short temp;
322 221 markom
 
323
        if (verify_memoryarea(memaddr)) {
324 235 erez
                switch(cur_area->granularity) {
325
                case 1:
326
                        temp = cur_area->readfunc(memaddr) << 8;
327
                        temp |= cur_area->readfunc(memaddr + 1);
328
                        break;
329
                case 2:
330
                        temp = cur_area->readfunc(memaddr);
331
                        break;
332
                case 4:
333
                        printf("EXCEPTION: read 16-bit value from 32-bit region (address 0x%08lX)\n", cur_area->granularity * 8, memaddr);
334
                        cont_run = 0;
335
                        break;
336
                }
337 2 cvs
        } else {
338 221 markom
                printf("EXCEPTION: read out of memory (16-bit access to %.8lx)\n", memaddr);
339 2 cvs
                cont_run = 0;
340 30 lampret
                temp = 0;
341 2 cvs
        }
342
        return temp;
343
}
344
 
345
 
346 6 lampret
/* Returns 8-bit values from mem array. */
347 2 cvs
 
348 123 markom
unsigned char eval_mem8(unsigned long memaddr,int* breakpoint)
349 221 markom
{
350 235 erez
        unsigned char temp;
351 6 lampret
        memaddr = simulate_dc_mmu_load(memaddr);
352 235 erez
        *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr);        /* 28/05/01 CZ */
353 6 lampret
 
354 221 markom
        temp = evalsim_mem8(memaddr);
355 235 erez
        *breakpoint += CheckDebugUnit(DebugLoadData,temp);      /* MM170901 */
356 221 markom
        return temp;
357 66 lampret
}
358
 
359 221 markom
unsigned char evalsim_mem8(unsigned long memaddr)
360
{
361 235 erez
        unsigned char temp;
362 123 markom
 
363 221 markom
        if (verify_memoryarea(memaddr)) {
364 235 erez
                switch(cur_area->granularity) {
365
                case 1:
366
                        temp = cur_area->readfunc(memaddr);
367
                        temp |= cur_area->readfunc(memaddr + 1) << 16;
368
                        temp |= cur_area->readfunc(memaddr + 2) << 8;
369
                        temp |= cur_area->readfunc(memaddr + 3);
370
                        break;
371
                case 2:
372
                case 4:
373
                        printf("EXCEPTION: read 8-bit value from %u-bit region (address 0x%08lX)\n", cur_area->granularity * 8, memaddr);
374
                        cont_run = 0;
375
                        break;
376
                }
377 2 cvs
        } else {
378 221 markom
                printf("EXCEPTION: read out of memory (8-bit access to %.8lx)\n", memaddr);
379 2 cvs
                cont_run = 0;
380 123 markom
                temp = 0;
381 2 cvs
        }
382 123 markom
        return temp;
383 2 cvs
}
384
 
385
/* Set mem, 32-bit. Big endian version. */
386
 
387 123 markom
void set_mem32(unsigned long memaddr, unsigned long value,int* breakpoint)
388 2 cvs
{
389 235 erez
        slp_checkaccess(memaddr, SLP_MEMWRITE);
390
        memaddr = simulate_dc_mmu_store(memaddr);
391 221 markom
 
392 235 erez
        *breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr);        /* 28/05/01 CZ */
393
        *breakpoint += CheckDebugUnit(DebugStoreData,value);
394 123 markom
 
395 235 erez
        setsim_mem32(memaddr, value);
396 123 markom
 
397 235 erez
        return;
398 66 lampret
}
399
 
400
void setsim_mem32(unsigned long memaddr, unsigned long value)
401
{
402
        struct dev_memarea *dev;
403
 
404 235 erez
        if (verify_memoryarea(memaddr)) {
405
                switch(cur_area->granularity) {
406
                case 1:
407
                        cur_area->writefunc(memaddr, (value >> 24) & 0xFF);
408
                        cur_area->writefunc(memaddr + 1, (value >> 16) & 0xFF);
409
                        cur_area->writefunc(memaddr + 2, (value >> 8) & 0xFF);
410
                        cur_area->writefunc(memaddr + 3, value & 0xFF);
411
                        break;
412
                case 2:
413
                        cur_area->writefunc(memaddr, (value >> 16) & 0xFFFF);
414
                        cur_area->writefunc(memaddr + 2, value & 0xFFFF);
415
                        break;
416
                case 4:
417
                        cur_area->writefunc(memaddr, value);
418
                        break;
419
                }
420 2 cvs
        } else {
421 221 markom
                printf("EXCEPTION: write out of memory (32-bit access to %.8lx)\n", memaddr);
422 2 cvs
                cont_run = 0;
423
        }
424
 
425
        return;
426
}
427
 
428
/* Set mem, 16-bit. Big endian version. */
429
 
430 123 markom
void set_mem16(unsigned long memaddr, unsigned short value,int* breakpoint)
431 2 cvs
{
432 235 erez
        memaddr = simulate_dc_mmu_store(memaddr);
433 221 markom
 
434 235 erez
        *breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr);        /* 28/05/01 CZ */
435
        *breakpoint += CheckDebugUnit(DebugStoreData,value);
436 123 markom
 
437 235 erez
        setsim_mem16(memaddr, value);
438 221 markom
 
439 235 erez
        return;
440 66 lampret
}
441
 
442
void setsim_mem16(unsigned long memaddr, unsigned short value)
443
{
444 235 erez
        if (verify_memoryarea(memaddr)) {
445
                switch(cur_area->granularity) {
446
                case 1:
447
                        cur_area->writefunc(memaddr, (value >> 8) & 0xFF);
448
                        cur_area->writefunc(memaddr + 1, value & 0xFF);
449
                        break;
450
                case 2:
451
                        cur_area->writefunc(memaddr, (value >> 16) & 0xFFFF);
452
                        break;
453
                case 4:
454
                        printf("EXCEPTION: write 16-bit value to 32-bit region (address 0x%08lX)\n", memaddr);
455
                        cont_run = 0;
456
                        break;
457
                }
458
        } else {
459
                printf("EXCEPTION: write out of memory (16-bit access to %.8lx)\n", memaddr);
460
                cont_run = 0;
461
        }
462 2 cvs
 
463 235 erez
        return;
464 2 cvs
}
465
 
466 6 lampret
/* Set mem, 8-bit. */
467 2 cvs
 
468 123 markom
void set_mem8(unsigned long memaddr, unsigned char value,int* breakpoint)
469 2 cvs
{
470 235 erez
        memaddr = simulate_dc_mmu_store(memaddr);
471 221 markom
 
472 235 erez
        *breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr);        /* 28/05/01 CZ */
473
        *breakpoint += CheckDebugUnit(DebugStoreData,value);
474 123 markom
 
475 235 erez
        setsim_mem8(memaddr, value);
476 123 markom
 
477 235 erez
        return;
478 66 lampret
}
479
 
480
void setsim_mem8(unsigned long memaddr, unsigned char value)
481
{
482 221 markom
        if (verify_memoryarea(memaddr)) {
483 235 erez
                if (cur_area->granularity == 1)
484
                        cur_area->writefunc(memaddr, value);
485
                else {
486
                        printf("EXCEPTION: write 8-bit value to %u-bit region (address 0x%08lX)\n", cur_area->granularity * 8, memaddr);
487
                        cont_run = 0;
488
                }
489 2 cvs
        } else {
490 221 markom
                printf("EXCEPTION: write out of memory (8-bit access to %.8lx)\n", memaddr);
491 2 cvs
                cont_run = 0;
492
        }
493
 
494
        return;
495
}
496 30 lampret
 
497 235 erez
unsigned long simmem_read_byte(unsigned long addr) {
498
        return simmem[cur_area->misc + addr - cur_area->start].data;
499 221 markom
}
500
 
501 235 erez
void simmem_write_byte(unsigned long addr, unsigned long value) {
502
        simmem[cur_area->misc + addr - cur_area->start].data = (unsigned char)value;
503 221 markom
}
504
 
505
struct mem_entry * simmem_getentry(unsigned long addr) {
506 235 erez
        return &simmem[cur_area->misc + addr - cur_area->start];
507 221 markom
}
508
 
509
void sim_read_memory_table (char *filename)
510
{
511 235 erez
        FILE *f;
512
        unsigned long memory_needed = 0;
513
        char *home = getenv("HOME");
514
        char ctmp[256];
515
        int local = 1;
516
        sprintf(ctmp, "%s/.or1k/%s", home, filename);
517
        if ((f = fopen (filename, "rt")) != NULL
518
                        || home != NULL && !(local = 0) && (f = fopen (ctmp, "rt")) != NULL) {
519
                unsigned long start, length;
520
                char type[100];
521
                printf ("Reading memory table from '%s':\n", local ? filename : ctmp);
522
                while (fscanf (f, "%08x %08x %s\n", &start, &length, &type) == 3) {
523
                        printf ("%08X %08X (%i KB): %s\n", start, length, length >> 10, type);
524
                        register_memoryarea(start, length, 1, &simmem_read_byte, &simmem_write_byte, &simmem_getentry);
525
                        cur_area->misc = memory_needed;
526
                        memory_needed += DEFAULT_MEMORY_LEN;
527
                }
528
                fclose (f);
529
                printf ("\n");
530
        } else {
531
                fprintf (stderr, "Cannot read memory table from '%s',\nneither '%s', assuming standard configuration.\n", filename, ctmp);
532
                register_memoryarea(DEFAULT_MEMORY_START, DEFAULT_MEMORY_LEN, 1, &simmem_read_byte, &simmem_write_byte, &simmem_getentry);
533
                memory_needed += DEFAULT_MEMORY_LEN;
534
        }
535
 
536
        simmem = (struct mem_entry *) malloc (sizeof (struct mem_entry) * memory_needed);
537 221 markom
}

powered by: WebSVN 2.1.0

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