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 102

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
#include <stdio.h>
25
#include <ctype.h>
26
#include <string.h>
27
 
28 6 lampret
#include "config.h"
29 7 jrydberg
#include "sim-config.h"
30 6 lampret
 
31 2 cvs
#include "parse.h"
32
#include "abstract.h"
33
#include "arch.h"
34
#include "trace.h"
35
#include "execute.h"
36 32 lampret
#include "sprs.h"
37 35 lampret
#include "stats.h"
38 32 lampret
#include "except.h"
39 2 cvs
 
40
extern unsigned long reg[];
41
 
42 28 lampret
/* This is an abstract+physical memory array rather than only physical
43
   memory array */
44 2 cvs
struct mem_entry mem[MEMORY_LEN];
45
 
46 30 lampret
/* Pointer to memory area descriptions that are assigned to individual
47
   peripheral devices. */
48
struct dev_memarea *dev_list;
49
 
50 2 cvs
void dumpmemory(unsigned int from, unsigned int to)
51
{
52 30 lampret
        unsigned int i, done = 0;
53 28 lampret
        struct label_entry *tmp;
54 2 cvs
 
55 30 lampret
        for(i = from; i < to && i < (MEMORY_START + MEMORY_LEN); i++) {
56 28 lampret
                if (mem[i].insn) {
57 47 lampret
                        printf("\n%4x:", i);
58
 
59 28 lampret
                        tmp = mem[i].label;
60
                        for(; tmp; tmp = tmp->next)
61 47 lampret
                                printf("\t%s%s\n", tmp->name, LABELEND_CHAR);
62
 
63
                        if (tmp)
64
                                printf("\n%4x:", i);
65
 
66
                        printf("\t%.2x%.2x", mem[i].data, mem[i+1].data);
67
                        printf("%.2x%.2x:  ", mem[i+2].data, mem[i+3].data);
68 28 lampret
                        if (mem[i].insn)
69 47 lampret
                                printf("\t%s\t%s", mem[i].insn->insn, mem[i].insn->op1);
70 28 lampret
                        if (strlen(mem[i].insn->op2))
71
                                printf("%s%s", OPERAND_DELIM, mem[i].insn->op2);
72
                        if (strlen(mem[i].insn->op3))
73
                                printf("%s%s", OPERAND_DELIM, mem[i].insn->op3);
74
                        if (strlen(mem[i].insn->op4))
75
                                printf("%s%s", OPERAND_DELIM, mem[i].insn->op4);
76
                        i += (insn_len(mem[i].insn->insn) - 1);
77 2 cvs
                } else
78
                {
79
                        if (i % 8 == 0)
80 30 lampret
                                printf("\n%.8x:  ", i);
81 2 cvs
 
82
                        /* don't print ascii chars below 0x20. */
83
                        if (mem[i].data < 0x20)
84
                                printf("0x%.2x     ", (unsigned char)mem[i].data);
85
                        else
86
                                printf("0x%.2x'%c'  ", (unsigned char)mem[i].data, mem[i].data);
87
 
88
                }
89 30 lampret
                done = 1;
90
        }
91
 
92
        if (done)
93
                return;
94
 
95
        for(i = from; i < to; i++) {
96
                if (i % 8 == 0)
97
                        printf("\n%.8x:  ", i);
98
 
99
                /* don't print ascii chars below 0x20. */
100
                if (eval_mem32(i) < 0x20)
101
                        printf("0x%.2x     ", (unsigned char)eval_mem32(i));
102
                else
103
                        printf("0x%.2x'%c'  ", (unsigned char)eval_mem32(i), (unsigned char)eval_mem32(i));
104
 
105
        }
106 2 cvs
}
107
 
108
/* Searches mem array for a particular label and returns label's address.
109
   If label does not exist, returns 0. */
110
 
111
unsigned long eval_label(char *label)
112
{
113
        int i;
114 18 lampret
        char *plus;
115
        char *minus;
116
        int positive_offset = 0;
117
        int negative_offset = 0;
118 28 lampret
        struct label_entry *tmp;
119 18 lampret
 
120
        if (plus = strchr(label, '+')) {
121
                *plus = '\0';
122
                positive_offset = atoi(++plus);
123
        }
124
 
125
        if (minus = strchr(label, '-')) {
126
                *minus = '\0';
127
                negative_offset = atoi(++minus);
128
        }
129
 
130 30 lampret
        for(i = 0; i < (MEMORY_START + MEMORY_LEN); i++) {
131 28 lampret
                tmp = mem[i].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);
135
                                return i+positive_offset-negative_offset;
136
                        }
137
        }
138
 
139 2 cvs
        printf("\nINTERNAL ERROR: undefined label %s\n", label);
140
        cont_run = 0;
141
        return 0;
142
 
143
}
144
 
145 77 lampret
/* Calls IMMU translation routines before simulating insn
146
cache for virtually indexed insn cache or after simulating insn cache
147
for physically indexed insn cache. It returns physical address. */
148
 
149
unsigned long simulate_ic_mmu_fetch(unsigned long virtaddr)
150
{
151
        if (config.ic.tagtype == NONE)
152
                return virtaddr;
153
        else
154
        if (config.ic.tagtype == VIRTUAL) {
155
                ic_simulate_fetch(virtaddr);
156
                return immu_translate(virtaddr);
157
        }
158
        else if (config.dc.tagtype == PHYSICAL) {
159
                unsigned long phyaddr = immu_translate(virtaddr);
160
                ic_simulate_fetch(phyaddr);
161
                return phyaddr;
162
        }
163
        else {
164
                printf("INTERNAL ERROR: Unknown insn cache type.\n");
165
                cont_run = 0;
166
        }
167
 
168
        return -1;
169
}
170
 
171
/* Calls DMMU translation routines (load cycles) before simulating data
172 6 lampret
cache for virtually indexed data cache or after simulating data cache
173
for physically indexed data cache. It returns physical address. */
174
 
175
unsigned long simulate_dc_mmu_load(unsigned long virtaddr)
176
{
177 47 lampret
        if (config.dc.tagtype == NONE)
178
                return virtaddr;
179
        else
180 30 lampret
        if (config.dc.tagtype == VIRTUAL) {
181 6 lampret
                dc_simulate_read(virtaddr);
182
                return dmmu_translate(virtaddr);
183
        }
184 30 lampret
        else if (config.dc.tagtype == PHYSICAL) {
185 6 lampret
                unsigned long phyaddr = dmmu_translate(virtaddr);
186
                dc_simulate_read(phyaddr);
187
                return phyaddr;
188
        }
189
        else {
190
                printf("INTERNAL ERROR: Unknown data cache type.\n");
191
                cont_run = 0;
192
        }
193
 
194
        return -1;
195
}
196
 
197 77 lampret
/* Calls DMMU translation routines (store cycles) before simulating data
198 6 lampret
cache for virtually indexed data cache or after simulating data cache
199
for physically indexed data cache. It returns physical address. */
200
 
201
unsigned long simulate_dc_mmu_store(unsigned long virtaddr)
202
{
203 47 lampret
        if (config.dc.tagtype == NONE)
204
                return virtaddr;
205
        else
206 30 lampret
        if (config.dc.tagtype == VIRTUAL) {
207 6 lampret
                dc_simulate_write(virtaddr);
208
                return dmmu_translate(virtaddr);
209
        }
210 30 lampret
        else if (config.dc.tagtype == PHYSICAL) {
211 6 lampret
                unsigned long phyaddr = dmmu_translate(virtaddr);
212
                dc_simulate_write(phyaddr);
213
                return phyaddr;
214
        }
215
        else {
216
                printf("INTERNAL ERROR: Unknown data cache type.\n");
217
                cont_run = 0;
218
        }
219
 
220
        return -1;
221
}
222
 
223 30 lampret
/* Register read and write function for a memory area (used by peripheral
224
   devices like 16450 UART etc.) */
225
void register_memoryarea(unsigned long baseaddr, unsigned long size, unsigned char (readfunc)(unsigned long), void (writefunc)(unsigned long, unsigned char))
226
{
227
        struct dev_memarea **pptmp;
228
 
229
        /* Go to the end of the list. */
230
        for(pptmp = &dev_list; *pptmp; pptmp = &(*pptmp)->next);
231
 
232
        *pptmp = (struct dev_memarea *)malloc(sizeof(struct dev_memarea));
233
        (*pptmp)->baseaddr = baseaddr;
234
        (*pptmp)->size = size;
235
        (*pptmp)->readfunc = readfunc;
236
        (*pptmp)->writefunc = writefunc;
237
        (*pptmp)->next = NULL;
238
 
239
        return;
240
}
241
 
242
/* Check if access is to registered area of memory. */
243
struct dev_memarea *verify_memoryarea(unsigned long addr)
244
{
245
        struct dev_memarea *ptmp;
246
 
247
        /* Check list of registered devices. */
248
        for(ptmp = dev_list; ptmp; ptmp = ptmp->next)
249
                if (addr >= ptmp->baseaddr &&
250
                    addr < (ptmp->baseaddr + ptmp->size))
251
                        return ptmp;
252
        return NULL;
253
}
254
 
255 2 cvs
/* Returns 32-bit values from mem array. Big endian version. */
256
unsigned long eval_mem32(unsigned long memaddr)
257
{
258
        unsigned long temp;
259 30 lampret
        struct dev_memarea *dev;
260 2 cvs
 
261 35 lampret
        slp_checkaccess(memaddr, SLP_MEMREAD);
262 6 lampret
        memaddr = simulate_dc_mmu_load(memaddr);
263
 
264 66 lampret
        return evalsim_mem32(memaddr);
265
}
266
 
267
unsigned long evalsim_mem32(unsigned long memaddr)
268
{
269
        unsigned long temp;
270
        struct dev_memarea *dev;
271
 
272 30 lampret
        if (memaddr < (MEMORY_START + MEMORY_LEN)) {
273 2 cvs
                temp = mem[memaddr].data << 24;
274
                temp += mem[memaddr + 1].data << 16;
275
                temp += mem[memaddr + 2].data << 8;
276
                temp += mem[memaddr + 3].data;
277 30 lampret
        } else if (dev = verify_memoryarea(memaddr)) {
278
                temp = dev->readfunc(memaddr);
279 2 cvs
        } else {
280
                printf("EXCEPTION: read out of memory (32-bit access to %.8lx)\n", memaddr);
281
                cont_run = 0;
282 30 lampret
                temp = 0;
283 2 cvs
        }
284
        return temp;
285
}
286
 
287
/* Returns 16-bit values from mem array. Big endian version. */
288
 
289
unsigned short eval_mem16(unsigned long memaddr)
290
{
291 66 lampret
        memaddr = simulate_dc_mmu_load(memaddr);
292
 
293
        return evalsim_mem16(memaddr);
294
}
295
 
296
unsigned short evalsim_mem16(unsigned long memaddr)
297
{
298 2 cvs
        unsigned short temp;
299
 
300 30 lampret
        if (memaddr < (MEMORY_START + MEMORY_LEN)) {
301 2 cvs
                temp = ((unsigned short)(mem[memaddr].data << 8) & 0xff00);
302
                temp += ((unsigned short)mem[memaddr + 1].data & 0x00ff);
303
        } else {
304
                printf("EXCEPTION: read out of memory (16-bit access to %.8lx)\n", memaddr);
305
                cont_run = 0;
306 30 lampret
                temp = 0;
307 2 cvs
        }
308
        return temp;
309
}
310
 
311
 
312 6 lampret
/* Returns 8-bit values from mem array. */
313 2 cvs
 
314
unsigned char eval_mem8(unsigned long memaddr)
315
{
316 6 lampret
        memaddr = simulate_dc_mmu_load(memaddr);
317
 
318 66 lampret
        return evalsim_mem8(memaddr);
319
}
320
 
321
unsigned char evalsim_mem8(unsigned long memaddr)
322
{
323 30 lampret
        if (memaddr < (MEMORY_START + MEMORY_LEN)) {
324 2 cvs
                return (unsigned char)mem[memaddr].data;
325
        } else {
326 6 lampret
                printf("EXCEPTION: read out of memory (8-bit access to %.8lx)\n", memaddr);
327 2 cvs
                cont_run = 0;
328 30 lampret
                return 0;
329 2 cvs
        }
330
}
331
 
332
/* Set mem, 32-bit. Big endian version. */
333
 
334
void set_mem32(unsigned long memaddr, unsigned long value)
335
{
336 35 lampret
        slp_checkaccess(memaddr, SLP_MEMWRITE);
337 6 lampret
        memaddr = simulate_dc_mmu_store(memaddr);
338
 
339 66 lampret
        setsim_mem32(memaddr, value);
340
        return;
341
}
342
 
343
void setsim_mem32(unsigned long memaddr, unsigned long value)
344
{
345
        struct dev_memarea *dev;
346
 
347 30 lampret
        if (memaddr < (MEMORY_START + MEMORY_LEN)) {
348 2 cvs
                mem[memaddr].data = (value >> 24);
349
                mem[memaddr + 1].data = (char)(value >> 16);
350
                mem[memaddr + 2].data = (char)(value >> 8);
351
                mem[memaddr + 3].data = (char)(value);
352 30 lampret
        } else if (dev = verify_memoryarea(memaddr)) {
353
                dev->writefunc(memaddr, value);
354 2 cvs
        } else {
355
                printf("EXCEPTION: write out of memory (32-bit access to %.8lx)\n", memaddr);
356
                cont_run = 0;
357
        }
358
 
359
        return;
360
}
361
 
362
/* Set mem, 16-bit. Big endian version. */
363
 
364
void set_mem16(unsigned long memaddr, unsigned short value)
365
{
366 6 lampret
        memaddr = simulate_dc_mmu_store(memaddr);
367
 
368 66 lampret
        setsim_mem16(memaddr, value);
369
        return;
370
}
371
 
372
void setsim_mem16(unsigned long memaddr, unsigned short value)
373
{
374 30 lampret
        if (memaddr < (MEMORY_START + MEMORY_LEN)) {
375 2 cvs
                mem[memaddr].data = (value >> 8);
376
                mem[memaddr + 1].data = (char)(value);
377
        } else {
378
                printf("EXCEPTION: write out of memory (16-bit access to %.8lx)\n", memaddr);
379
                cont_run = 0;
380
        }
381
 
382
        return;
383
}
384
 
385 6 lampret
/* Set mem, 8-bit. */
386 2 cvs
 
387
void set_mem8(unsigned long memaddr, unsigned char value)
388
{
389 6 lampret
        memaddr = simulate_dc_mmu_store(memaddr);
390
 
391 66 lampret
        setsim_mem8(memaddr, value);
392
        return;
393
}
394
 
395
void setsim_mem8(unsigned long memaddr, unsigned char value)
396
{
397 30 lampret
        if (memaddr < (MEMORY_START + MEMORY_LEN)) {
398 2 cvs
                mem[memaddr].data = value;
399
        } else {
400
                printf("EXCEPTION: write out of memory (8-bit access to %.8lx)\n", memaddr);
401
                cont_run = 0;
402
        }
403
 
404
        return;
405
}
406 30 lampret
 

powered by: WebSVN 2.1.0

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