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

Subversion Repositories aor3000

[/] [aor3000/] [trunk/] [sim/] [vmips/] [main_tester.cpp] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 alfik
/*
2
 * This file is subject to the terms and conditions of the GPL License. See
3
 * the file "LICENSE" in the main directory of this archive for more details.
4
 *
5
 * Copyright (C) 2014 Aleksander Osman
6
 */
7
 
8
#include <cstdio>
9
#include <cstdlib>
10
#include <cstring>
11
 
12
#include <sys/mman.h>
13
#include <sys/types.h>
14
#include <sys/stat.h>
15
#include <fcntl.h>
16
#include <unistd.h>
17
 
18
#include "shared_mem.h"
19
#include "vmips_emulator.h"
20
 
21
//------------------------------------------------------------------------------
22
 
23
volatile shared_mem_t *shared_ptr = NULL;
24
 
25
//------------------------------------------------------------------------------
26
 
27
 
28
#define GET(field, mask) \
29
    (shared_ptr->initial.field & mask)
30
 
31
void CPZero::initialize() {
32
    for(int i=0; i<64; i++) {
33
        tlb[i].entryHi = 0;
34
        tlb[i].entryHi |= GET(tlb[i].vpn, 0xFFFFF) << 12;
35
        tlb[i].entryHi |= GET(tlb[i].asid, 0x3F)   << 6;
36
 
37
        tlb[i].entryLo = 0;
38
        tlb[i].entryLo |= GET(tlb[i].pfn, 0xFFFFF) << 12;
39
        tlb[i].entryLo |= GET(tlb[i].n,   0x1)     << 11;
40
        tlb[i].entryLo |= GET(tlb[i].d,   0x1)     << 10;
41
        tlb[i].entryLo |= GET(tlb[i].v,   0x1)     << 9;
42
        tlb[i].entryLo |= GET(tlb[i].g,   0x1)     << 8;
43
    }
44
    for(int i=0; i<32; i++) reg[i] = 0; //cp0 regs
45
 
46
    reg[0] |= GET(index_p, 0x1)      << 31;
47
    reg[0] |= GET(index_index, 0x3F) << 8;
48
 
49
    reg[1] |= GET(random, 0x3F) << 8;
50
 
51
    reg[2] |= GET(entrylo_pfn, 0xFFFFF) << 12;
52
    reg[2] |= GET(entrylo_n,   0x1)     << 11;
53
    reg[2] |= GET(entrylo_d,   0x1)     << 10;
54
    reg[2] |= GET(entrylo_v,   0x1)     << 9;
55
    reg[2] |= GET(entrylo_g,   0x1)     << 8;
56
 
57
    reg[4] |= GET(context_ptebase, 0x7FF)   << 21;
58
    reg[4] |= GET(context_badvpn,  0x7FFFF) << 2;
59
 
60
    reg[8] |= GET(bad_vaddr, 0xFFFFFFFF);
61
 
62
    reg[10] |= GET(entryhi_vpn, 0xFFFFF) << 12;
63
    reg[10] |= GET(entryhi_asid, 0x3F)   << 6;
64
 
65
    reg[12] |= GET(sr_cp_usable,     0xF) << 28;
66
    reg[12] |= GET(sr_rev_endian,    0x1) << 25;
67
    reg[12] |= GET(sr_bootstrap_vec, 0x1) << 22;
68
    reg[12] |= GET(sr_tlb_shutdown,  0x1) << 21;
69
    reg[12] |= GET(sr_parity_err,    0x1) << 20;
70
    reg[12] |= GET(sr_cache_miss,    0x1) << 19;
71
    reg[12] |= GET(sr_parity_zero,   0x1) << 18;
72
    reg[12] |= GET(sr_switch_cache,  0x1) << 17;
73
    reg[12] |= GET(sr_isolate_cache, 0x1) << 16;
74
    reg[12] |= GET(sr_irq_mask,      0xFF) << 8;
75
    reg[12] |= GET(sr_ku_ie,         0x3F) << 0;
76
 
77
    reg[13] |= GET(cause_branch_delay, 0x1)  << 31;
78
    reg[13] |= GET(cause_cp_error,     0x3)  << 28;
79
    reg[13] |= GET(cause_irq_pending,  0x3)  << 8; //only 2 lowest bits
80
    reg[13] |= GET(cause_exc_code,     0x1F) << 2;
81
 
82
    reg[14] |= GET(epc, 0xFFFFFFFF);
83
 
84
    reg[15] |= 0x00000230; /* MIPS R3000A */
85
}
86
 
87
void CPU::initialize() {
88
 
89
    put_reg(0, 0);
90
    for(int i=1; i<32; i++) { put_reg(i, GET(reg[i-1], 0xFFFFFFFF)); }
91
 
92
    pc = GET(pc, 0xFFFFFFFF);
93
    //not comapred: hi = GET(hi, 0xFFFFFFFF);
94
    //not compared: lo = GET(lo, 0xFFFFFFFF);
95
 
96
    cpzero->initialize();
97
}
98
 
99
//------------------------------------------------------------------------------
100
 
101
#define PUT(field, val, mask) \
102
    shared_ptr->proc_vmips.report.state.field = (val) & mask
103
 
104
void CPZero::report() {
105
    for(int i=0; i<64; i++) {
106
        PUT(tlb[i].vpn,  tlb[i].entryHi >> 12, 0xFFFFF);
107
        PUT(tlb[i].asid, tlb[i].entryHi >> 6,  0x3F);
108
 
109
        PUT(tlb[i].pfn,  tlb[i].entryLo >> 12, 0xFFFFF);
110
        PUT(tlb[i].n,    tlb[i].entryLo >> 11, 0x1);
111
        PUT(tlb[i].d,    tlb[i].entryLo >> 10, 0x1);
112
        PUT(tlb[i].v,    tlb[i].entryLo >> 9, 0x1);
113
        PUT(tlb[i].g,    tlb[i].entryLo >> 8, 0x1);
114
    }
115
 
116
    PUT(index_p,     reg[0] >> 31, 0x1);
117
    PUT(index_index, reg[0] >> 8,  0x3F);
118
 
119
    PUT(random, reg[1] >> 8, 0x3F);
120
 
121
    PUT(entrylo_pfn, reg[2] >> 12, 0xFFFFF);
122
    PUT(entrylo_n,   reg[2] >> 11, 0x1);
123
    PUT(entrylo_d,   reg[2] >> 10, 0x1);
124
    PUT(entrylo_v,   reg[2] >> 9,  0x1);
125
    PUT(entrylo_g,   reg[2] >> 8,  0x1);
126
 
127
    PUT(context_ptebase, reg[4] >> 21, 0x7FF);
128
    PUT(context_badvpn,  reg[4] >> 2,  0x7FFFF);
129
 
130
    PUT(bad_vaddr, reg[8], 0xFFFFFFFF);
131
 
132
    PUT(entryhi_vpn,  reg[10] >> 12, 0xFFFFF);
133
    PUT(entryhi_asid, reg[10] >> 6,  0x3F);
134
 
135
    PUT(sr_cp_usable,     reg[12] >> 28, 0xF);
136
    PUT(sr_rev_endian,    reg[12] >> 25, 0x1);
137
    PUT(sr_bootstrap_vec, reg[12] >> 22, 0x1);
138
    PUT(sr_tlb_shutdown,  reg[12] >> 21, 0x1);
139
    PUT(sr_parity_err,    reg[12] >> 20, 0x1);
140
    PUT(sr_cache_miss,    reg[12] >> 19, 0x1);
141
    PUT(sr_parity_zero,   reg[12] >> 18, 0x1);
142
    PUT(sr_switch_cache,  reg[12] >> 17, 0x1);
143
    PUT(sr_isolate_cache, reg[12] >> 16, 0x1);
144
    PUT(sr_irq_mask,      reg[12] >> 8,  0xFF);
145
    PUT(sr_ku_ie,         reg[12] >> 0,  0x3F);
146
 
147
    PUT(cause_branch_delay, reg[13] >> 31, 0x1);
148
    PUT(cause_cp_error,     reg[13] >> 28, 0x3);
149
    PUT(cause_irq_pending,  reg[13] >> 8,  0x3); //only 2 lowest bits
150
    PUT(cause_exc_code,     reg[13] >> 2,  0x1F);
151
 
152
    PUT(epc, reg[14], 0xFFFFFFFF);
153
}
154
 
155
void CPU::report() {
156
    for(int i=1; i<32; i++) PUT(reg[i-1], get_reg(i), 0xFFFFFFFF);
157
 
158
    PUT(pc, pc, 0xFFFFFFFF);
159
    //not compared: PUT(hi, hi, 0xFFFFFFFF);
160
    //not compared: PUT(lo, lo, 0xFFFFFFFF);
161
 
162
    cpzero->report();
163
}
164
 
165
//------------------------------------------------------------------------------
166
 
167
CPU *cpu = NULL;
168
uint32 event_counter = 0;
169
 
170
void usleep_or_finish() {
171
    if(shared_ptr->test_finished) {
172
        printf("Finishing.\n");
173
        exit(0);
174
    }
175
    usleep(1);
176
}
177
 
178
uint32 ao_interrupts() {
179
    return (shared_ptr->irq2_at_event == event_counter)? 1 << 10 : 0;
180
}
181
 
182
uint8 ao_fetch_byte(uint32 addr, bool cacheable, bool isolated) {
183
    //DBE IBE
184
    //cpu->exception((mode == INSTFETCH / DATALOAD ? IBE : DBE), mode);
185
 
186
    if(addr < 0x8000000) {
187
        return shared_ptr->mem.bytes[addr];
188
    }
189
 
190
    shared_ptr->proc_vmips.read_address    = addr & 0xFFFFFFFC;
191
    shared_ptr->proc_vmips.read_byteenable = ((addr % 4) == 0)? 0x1 : ((addr % 4) == 1)? 0x2 : ((addr % 4) == 2)? 0x3 : 0x4;
192
    shared_ptr->proc_vmips.read_do         = true;
193
 
194
    while(shared_ptr->proc_vmips.read_do) usleep_or_finish();
195
 
196
    return (shared_ptr->proc_vmips.read_data >> ( ((addr % 4) == 0)? 0 : ((addr % 4) == 1)? 8 : ((addr % 4) == 2)? 16 : 24 )) & 0xFF;
197
}
198
 
199
uint16 ao_fetch_halfword(uint32 addr, bool cacheable, bool isolated) {
200
    //AdE
201
    if (addr % 2 != 0) {
202
        cpu->exception(AdEL,DATALOAD);
203
        return 0xffff;
204
    }
205
 
206
    //DBE IBE
207
    //cpu->exception((mode == INSTFETCH / DATALOAD ? IBE : DBE), mode);
208
 
209
    if(addr < 0x8000000) {
210
        return shared_ptr->mem.shorts[addr/2];
211
    }
212
 
213
    shared_ptr->proc_vmips.read_address    = addr & 0xFFFFFFFC;
214
    shared_ptr->proc_vmips.read_byteenable = ((addr % 4) == 0)? 0x3 : 0xC;
215
    shared_ptr->proc_vmips.read_do         = true;
216
 
217
    while(shared_ptr->proc_vmips.read_do) usleep_or_finish();
218
 
219
    return (shared_ptr->proc_vmips.read_data >> ( ((addr % 4) == 0)? 0 : 16 )) & 0xFFFF;
220
}
221
 
222
uint32 ao_fetch_word(uint32 addr, int32 mode, bool cacheable, bool isolated) {
223
    //AdE
224
    if (addr % 4 != 0) {
225
        cpu->exception(AdEL,mode);
226
        return 0xffffffff;
227
    }
228
 
229
    //DBE IBE
230
    //cpu->exception((mode == INSTFETCH / DATALOAD ? IBE : DBE), mode);
231
 
232
    if(addr < 0x8000000) {
233
        return shared_ptr->mem.ints[addr/4];
234
    }
235
 
236
    shared_ptr->proc_vmips.read_address    = addr & 0xFFFFFFFC;
237
    shared_ptr->proc_vmips.read_byteenable = 0xF;
238
    shared_ptr->proc_vmips.read_do         = true;
239
 
240
    while(shared_ptr->proc_vmips.read_do) usleep_or_finish();
241
 
242
    return (shared_ptr->proc_vmips.read_data) & 0xFFFFFFFF;
243
}
244
 
245
void ao_store_byte(uint32 addr, uint8 data, bool cacheable, bool isolated) {
246
    //DBE
247
    //cpu->exception((mode == INSTFETCH / DATALOAD ? IBE : DBE), mode);
248
 
249
    shared_ptr->proc_vmips.write_address    = addr & 0xFFFFFFFC;
250
    shared_ptr->proc_vmips.write_byteenable = ((addr % 4) == 0)? 0x1 : ((addr % 4) == 1)? 0x2 : ((addr % 4) == 2)? 0x4 : 0x8;
251
    shared_ptr->proc_vmips.write_data       = ((addr % 4) == 0)? data : ((addr % 4) == 1)? data << 8 : ((addr % 4) == 2)? data << 16 : data << 24;
252
    shared_ptr->proc_vmips.write_do         = true;
253
 
254
    while(shared_ptr->proc_vmips.write_do) usleep_or_finish();
255
}
256
 
257
void ao_store_halfword(uint32 addr, uint16 data, bool cacheable, bool isolated) {
258
    //AdE
259
    if (addr % 2 != 0) {
260
        cpu->exception(AdES,DATASTORE);
261
        return;
262
    }
263
 
264
    //DBE
265
    //cpu->exception((mode == INSTFETCH / DATALOAD ? IBE : DBE), mode);
266
 
267
    shared_ptr->proc_vmips.write_address    = addr & 0xFFFFFFFC;
268
    shared_ptr->proc_vmips.write_byteenable = ((addr % 4) == 0)? 0x3 : 0xC;
269
    shared_ptr->proc_vmips.write_data       = ((addr % 4) == 0)? data : data << 16;
270
    shared_ptr->proc_vmips.write_do         = true;
271
 
272
    while(shared_ptr->proc_vmips.write_do) usleep_or_finish();
273
}
274
 
275
void ao_store_word(uint32 addr, uint32 data, bool cacheable, bool isolated, uint32 byteenable) {
276
    //AdE
277
    if (addr % 4 != 0) {
278
        cpu->exception(AdES,DATASTORE);
279
        return;
280
    }
281
 
282
    //DBE
283
    //cpu->exception((mode == INSTFETCH / DATALOAD ? IBE : DBE), mode);
284
 
285
    shared_ptr->proc_vmips.write_address    = addr & 0xFFFFFFFC;
286
    shared_ptr->proc_vmips.write_byteenable = byteenable;
287
    shared_ptr->proc_vmips.write_data       = data;
288
    shared_ptr->proc_vmips.write_do         = true;
289
 
290
    while(shared_ptr->proc_vmips.write_do) usleep_or_finish();
291
}
292
 
293
void fatal_error(const char *error, ...) {
294
    printf("[fatal_error]: %s\n", error);
295
    exit(-1);
296
}
297
 
298
//------------------------------------------------------------------------------
299
 
300
 
301
int main() {
302
    //map shared memory
303
    int fd = open("./../tester/shared_mem.dat", O_RDWR, S_IRUSR | S_IWUSR);
304
 
305
    if(fd == -1) {
306
        perror("open() failed for shared_mem.dat");
307
        return -1;
308
    }
309
 
310
    shared_ptr = (shared_mem_t *)mmap(NULL, sizeof(shared_mem_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
311
 
312
    if(shared_ptr == MAP_FAILED) {
313
        perror("mmap() failed");
314
        close(fd);
315
        return -2;
316
    }
317
 
318
    cpu = new CPU();
319
    cpu->reset();
320
 
321
    printf("Waiting for initialize..."); fflush(stdout);
322
    while(shared_ptr->proc_vmips.initialize_do == false) usleep_or_finish();
323
 
324
    cpu->initialize();
325
    shared_ptr->proc_vmips.initialize_do = false;
326
    printf("done\n");
327
 
328
    while(true) {
329
        int exception_pending = cpu->step();
330
 
331
        cpu->report();
332
        shared_ptr->proc_vmips.report.counter     = event_counter;
333
        shared_ptr->proc_vmips.report.exception   = (exception_pending > 0)? 1 : 0;
334
 
335
        if(cpu->was_delayed_transfer && exception_pending == 0) shared_ptr->proc_vmips.report.state.pc = cpu->was_delayed_pc;
336
 
337
        shared_ptr->proc_vmips.report_do = true;
338
 
339
        while(shared_ptr->proc_vmips.report_do) usleep_or_finish();
340
 
341
        event_counter++;
342
    }
343
    return 0;
344
}
345
 
346
//------------------------------------------------------------------------------

powered by: WebSVN 2.1.0

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