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

Subversion Repositories aor3000

[/] [aor3000/] [trunk/] [sim/] [tester/] [main_linux.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 BSD 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
#include <deque>
12
 
13
#include <sys/mman.h>
14
#include <sys/types.h>
15
#include <sys/stat.h>
16
#include <sys/wait.h>
17
#include <fcntl.h>
18
#include <signal.h>
19
#include <unistd.h>
20
#include <pty.h>
21
#include <poll.h>
22
 
23
#include "shared_mem.h"
24
 
25
//------------------------------------------------------------------------------
26
 
27
volatile shared_mem_t *shared_ptr = NULL;
28
 
29
//------------------------------------------------------------------------------
30
 
31
//128MB
32
#define MAX_MEMORY   0x8000000
33
#define RESET_VECTOR 0x1FC00000
34
 
35
int main(int argc, char **argv) {
36
 
37
    if(argc != 2) {
38
        printf("Error: missing argument: path to vmlinux.bin file !\n");
39
        return -1;
40
    }
41
 
42
    int int_ret;
43
 
44
    //open file with truncate
45
    FILE *fp = fopen("shared_mem.dat", "wb");
46
    if(fp == NULL) {
47
        perror("Can not truncate file shared_mem.dat");
48
        return -1;
49
    }
50
    uint8 *buf = new uint8[sizeof(shared_mem_t)];
51
    memset(buf, 0, sizeof(shared_mem_t));
52
 
53
    int_ret = fwrite(buf, sizeof(shared_mem_t), 1, fp);
54
    delete buf;
55
    if(int_ret != 1) {
56
        perror("Can not zero-fill file shared_mem.dat");
57
        fclose(fp);
58
        return -2;
59
    }
60
    fclose(fp);
61
 
62
    //--------------------------------------------------------------------------
63
 
64
    //map shared memory
65
    int fd = open("./shared_mem.dat", O_RDWR, S_IRUSR | S_IWUSR);
66
 
67
    if(fd == -1) {
68
        perror("open() failed for shared_mem.dat");
69
        return -3;
70
    }
71
 
72
    shared_ptr = (shared_mem_t *)mmap(NULL, sizeof(shared_mem_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
73
 
74
    if(shared_ptr == MAP_FAILED) {
75
        perror("mmap() failed");
76
        close(fd);
77
        return -4;
78
    }
79
 
80
    //--------------------------------------------------------------------------
81
 
82
    srand(0);
83
 
84
    //----------------------------------------------------------------------
85
    memset((void *)shared_ptr, 0, sizeof(shared_mem_t));
86
 
87
    //load linux kernel binary from address 0
88
    FILE *kernel_fp = fopen(argv[1], "rb");
89
    if(kernel_fp == NULL) {
90
        printf("Error: can not open file: %s\n", argv[1]);
91
        return -1;
92
    }
93
    uint8 *kernel_ptr = (uint8 *)shared_ptr->mem.bytes;
94
    while(true) {
95
        int_ret = fread(kernel_ptr, 1, 8192, kernel_fp);
96
        if(int_ret == 0) break;
97
        kernel_ptr += int_ret;
98
    }
99
    fclose(kernel_fp);
100
 
101
    printf("loaded linux kernel size: %d bytes.\n", (kernel_ptr - shared_ptr->mem.bytes));
102
 
103
    //----------------------------------------------------------------------
104
 
105
    uint32 *reset_ptr = (uint32 *)shared_ptr->reset_vector;
106
 
107
    reset_ptr[0] = (0b000000 << 26) | (0 << 21) | (1 << 16) | (1 << 11) | (0b00000 << 6) | (0b100100);   //AND R1,R0,R1 -- clear R1
108
    reset_ptr[1] = (0b001111 << 26) | (0 << 21) | (1 << 16) | 0x8000;                                    //LUI R1,0x8000
109
    reset_ptr[2] = (0b001101 << 26) | (1 << 21) | (1 << 16) | 0x0400;                                    //ORI R1,R1,0x400
110
    reset_ptr[3] = (0b000000 << 26) | (1 << 21) | (0 << 16) | (0 << 11) | (0 << 6) | (0b001000);         //JR R1
111
    reset_ptr[4] = 0;                                                                                    //NOP
112
 
113
    shared_ptr->check_at_event = 10000;
114
 
115
    //----------------------------------------------------------------------
116
 
117
    FILE *early_console_fp = fopen("early_console.txt", "wb");
118
    FILE *jtag_console_fp = fopen("jtag_console.txt", "wb");
119
 
120
    //----------------------------------------------------------------------
121
 
122
    int master_fd = 0, slave_fd = 0;
123
    char slave_name[256];
124
    memset(slave_name, 0, sizeof(slave_name));
125
 
126
    int_ret = openpty(&master_fd, &slave_fd, slave_name, NULL, NULL);
127
    if(int_ret != 0) {
128
        printf("Can not openpty().\n");
129
        return -1;
130
    }
131
    printf("slave pty: %s\n", slave_name);
132
 
133
    //----------------------------------------------------------------------
134
 
135
    pid_t proc_vmips = fork();
136
    if(proc_vmips == 0) {
137
        system("cd ./../vmips && ./main_linux > ./vmips_output.txt");
138
        return 0;
139
    }
140
 
141
    pid_t proc_ao = fork();
142
    if(proc_ao == 0) {
143
        system("cd ./../aoR3000 && ./obj_dir/VaoR3000 > ./ao_output.txt");
144
        return 0;
145
    }
146
 
147
    //----------------------------------------------------------------------
148
 
149
    printf("Waiting for init of vmips..."); fflush(stdout);
150
    shared_ptr->proc_vmips.initialize_do = true;
151
 
152
    while(shared_ptr->proc_vmips.initialize_do) usleep(1);
153
    printf("done\n");
154
 
155
    printf("Waiting for init of aoR3000...");  fflush(stdout);
156
    shared_ptr->proc_ao.initialize_do = true;
157
 
158
    while(shared_ptr->proc_ao.initialize_do) usleep(1);
159
    printf("done\n");
160
 
161
    //irq setup
162
    shared_ptr->irq2_at_event = 0;
163
    shared_ptr->irq3_at_event = 0xFFFFFFFF;
164
 
165
    //jtag data
166
    bool jtag_read_irq_enable  = false;
167
    bool jtag_write_irq_enable = false;
168
 
169
    uint64 loop = 0;
170
 
171
    struct pollfd master_poll;
172
    memset(&master_poll, 0, sizeof(master_poll));
173
    master_poll.fd = master_fd;
174
    master_poll.events = POLLIN;
175
 
176
    std::deque<char> jtag_deque;
177
 
178
    while(true) {
179
        loop++;
180
        if((loop % 100000000) == 0) printf("loop: %lld, vmips: %d ao: %d\n", loop, shared_ptr->proc_vmips.report.counter, shared_ptr->proc_ao.report.counter);
181
 
182
        //----------------------------------------------------------------------
183
 
184
        if((loop % 10000) == 0) {
185
            int_ret = poll(&master_poll, 1, 0);
186
            if(int_ret < 0) {
187
                printf("Error: poll() failed.\n");
188
                shared_ptr->test_finished = true;
189
                return -1;
190
            }
191
 
192
            if(int_ret == 1 && (master_poll.revents & POLLIN)) {
193
                char read_char = 0;
194
                int_ret = read(master_fd, &read_char, 1);
195
 
196
                jtag_deque.push_back(read_char);
197
                printf("read: %c\n", read_char);
198
            }
199
        }
200
 
201
        //----------------------------------------------------------------------
202
 
203
        uint32 retry = 0;
204
        while(shared_ptr->proc_vmips.check_do || shared_ptr->proc_ao.check_do) {
205
            if(shared_ptr->proc_vmips.check_do && shared_ptr->proc_ao.check_do) {
206
 
207
                //printf("check[%d, %d]\n", shared_ptr->proc_vmips.report.counter, shared_ptr->proc_ao.report.counter);
208
 
209
                if(shared_ptr->proc_vmips.report.counter != shared_ptr->proc_ao.report.counter) {
210
                    printf("check counter mismatch: vmips: %d != %d\n", shared_ptr->proc_vmips.report.counter, shared_ptr->proc_ao.report.counter);
211
                    getchar();
212
                }
213
 
214
                shared_ptr->check_at_event += 10000;
215
 
216
                if(jtag_write_irq_enable == false) {
217
                    if(jtag_deque.empty()) {
218
                        if(shared_ptr->irq3_at_event != 0xFFFFFFFF) {
219
                            printf("jtag: disabling irq\n");
220
                            shared_ptr->irq3_at_event = 0xFFFFFFFF;
221
                        }
222
                    }
223
                    else {
224
                        shared_ptr->irq3_at_event = shared_ptr->proc_vmips.report.counter + 10;
225
                        printf("jtag: enabling irq\n");
226
                    }
227
                }
228
 
229
                shared_ptr->proc_vmips.check_do = false;
230
                shared_ptr->proc_ao.check_do    = false;
231
            }
232
            else {
233
                usleep(10);
234
                retry++;
235
 
236
                if(retry == 500000) {
237
                    printf("vmips: %08x %01x %08x\n", shared_ptr->proc_vmips.write_address, shared_ptr->proc_vmips.write_byteenable, shared_ptr->proc_vmips.write_data);
238
                    printf("ao:    %08x %01x %08x\n", shared_ptr->proc_ao.write_address,    shared_ptr->proc_ao.write_byteenable,    shared_ptr->proc_ao.write_data);
239
 
240
                    printf("\nTEST FAILED. WAITING FOR CHECK [vmips: %d, ao: %d]\n", shared_ptr->proc_vmips.report.counter, shared_ptr->proc_ao.report.counter);
241
                    shared_ptr->test_finished = true;
242
                    return -1;
243
                }
244
            }
245
        }
246
 
247
        retry = 0;
248
        while(shared_ptr->proc_vmips.write_do || shared_ptr->proc_ao.write_do) {
249
            if(shared_ptr->proc_vmips.write_do && shared_ptr->proc_ao.write_do) {
250
                if( shared_ptr->proc_vmips.write_address    == shared_ptr->proc_ao.write_address &&
251
                    shared_ptr->proc_vmips.write_byteenable == shared_ptr->proc_ao.write_byteenable &&
252
                    shared_ptr->proc_vmips.write_data       == shared_ptr->proc_ao.write_data)
253
                {
254
                    //printf("write[%d]: %08x %01x %08x\n", shared_ptr->proc_vmips.report.counter, shared_ptr->proc_vmips.write_address, shared_ptr->proc_vmips.write_byteenable, shared_ptr->proc_vmips.write_data);
255
 
256
                    if(shared_ptr->proc_vmips.report.counter != shared_ptr->proc_ao.report.counter) {
257
                        printf("write instruction counter mismatch: vmips: %d != %d\n", shared_ptr->proc_vmips.report.counter, shared_ptr->proc_ao.report.counter);
258
                        getchar();
259
                    }
260
 
261
                    uint32 address = shared_ptr->proc_vmips.write_address;
262
                    uint32 byteena = shared_ptr->proc_vmips.write_byteenable;
263
                    uint32 value   = shared_ptr->proc_vmips.write_data;
264
 
265
                    if(address < MAX_MEMORY) {
266
                        for(uint32 i=0; i<4; i++) {
267
                            if(byteena & 1) shared_ptr->mem.bytes[shared_ptr->proc_vmips.write_address + i] = value & 0xFF;
268
                            value >>= 8;
269
                            byteena >>= 1;
270
                        }
271
                    }
272
                    else if(address >= RESET_VECTOR && address < RESET_VECTOR + sizeof(shared_ptr->reset_vector)) {
273
                        for(uint32 i=0; i<4; i++) {
274
                            uint8 *vector = (uint8 *)shared_ptr->reset_vector;
275
                            if(byteena & 1) vector[address - RESET_VECTOR + i] = value & 0xFF;
276
                            value >>= 8;
277
                            byteena >>= 1;
278
                        }
279
                    }
280
                    else if(address == 0x1FFFFFFC && byteena == 8) {
281
                        fprintf(early_console_fp, "%c", (value >> 24) & 0xFF);
282
                        fflush(early_console_fp);
283
                    }
284
                    else if(address == 0x1FFFFFF8 && byteena == 1) {
285
                        printf("timer irq ack\n");
286
                        shared_ptr->irq2_at_event = shared_ptr->proc_vmips.report.counter + 500000;
287
                    }
288
                    else if(address == 0x1FFFFFF0 && byteena == 0xF) {
289
                        printf("write jtaguart data: %08x\n", value);
290
 
291
                        char byte_to_write = (value & 0xFF);
292
 
293
                        fprintf(jtag_console_fp, "%c", byte_to_write);
294
                        fflush(jtag_console_fp);
295
 
296
                        write(master_fd, &byte_to_write, 1);
297
                    }
298
                    else if(address == 0x1FFFFFF4 && byteena == 0xF) {
299
                        printf("write jtaguart control: %08x\n", value);
300
 
301
                        jtag_read_irq_enable  = (value & 0x1)? true : false;
302
                        jtag_write_irq_enable = (value & 0x2)? true : false;
303
 
304
                        if(jtag_write_irq_enable || (jtag_read_irq_enable && jtag_deque.size() > 0))    shared_ptr->irq3_at_event = shared_ptr->proc_vmips.report.counter + 10;
305
                        else                                                                            shared_ptr->irq3_at_event = 0xFFFFFFFF;
306
                    }
307
                    else {
308
                        printf("vmips: %08x %01x %08x\n", shared_ptr->proc_vmips.write_address, shared_ptr->proc_vmips.write_byteenable, shared_ptr->proc_vmips.write_data);
309
                        printf("ao:    %08x %01x %08x\n", shared_ptr->proc_ao.write_address,    shared_ptr->proc_ao.write_byteenable,    shared_ptr->proc_ao.write_data);
310
 
311
                        printf("\nTEST FAILED. MEM WRITE TO UNKNOWN.\n");
312
                        shared_ptr->test_finished = true;
313
                        return -1;
314
                    }
315
 
316
                    shared_ptr->proc_vmips.write_do = false;
317
                    shared_ptr->proc_ao.write_do    = false;
318
                }
319
                else {
320
                    printf("vmips: %08x %01x %08x\n", shared_ptr->proc_vmips.write_address, shared_ptr->proc_vmips.write_byteenable, shared_ptr->proc_vmips.write_data);
321
                    printf("ao:    %08x %01x %08x\n", shared_ptr->proc_ao.write_address,    shared_ptr->proc_ao.write_byteenable,    shared_ptr->proc_ao.write_data);
322
 
323
                    printf("\nTEST FAILED. MEM WRITE DIFF [%d].\n", shared_ptr->proc_vmips.report.counter);
324
                    shared_ptr->test_finished = true;
325
                    return -1;
326
                }
327
            }
328
            else {
329
                usleep(10);
330
                retry++;
331
 
332
                if(retry == 500000) {
333
                    printf("vmips: %08x %01x %08x\n", shared_ptr->proc_vmips.write_address, shared_ptr->proc_vmips.write_byteenable, shared_ptr->proc_vmips.write_data);
334
                    printf("ao:    %08x %01x %08x\n", shared_ptr->proc_ao.write_address,    shared_ptr->proc_ao.write_byteenable,    shared_ptr->proc_ao.write_data);
335
 
336
                    printf("\nTEST FAILED. WAITING FOR WRITE [vmips: %d, ao: %d]\n", shared_ptr->proc_vmips.report.counter, shared_ptr->proc_ao.report.counter);
337
                    shared_ptr->test_finished = true;
338
                    return -1;
339
                }
340
            }
341
        }
342
 
343
        retry = 0;
344
        while(shared_ptr->proc_vmips.read_do || shared_ptr->proc_ao.read_do) {
345
            if(shared_ptr->proc_vmips.read_do && shared_ptr->proc_ao.read_do) {
346
                if( shared_ptr->proc_vmips.read_address    == shared_ptr->proc_ao.read_address &&
347
                    shared_ptr->proc_vmips.read_byteenable == shared_ptr->proc_ao.read_byteenable)
348
                {
349
                    printf("read: %08x %01x\n", shared_ptr->proc_vmips.read_address, shared_ptr->proc_vmips.read_byteenable);
350
 
351
                    if(shared_ptr->proc_vmips.report.counter != shared_ptr->proc_ao.report.counter) {
352
                        printf("read instruction counter mismatch: vmips: %d != %d\n", shared_ptr->proc_vmips.report.counter, shared_ptr->proc_ao.report.counter);
353
                        getchar();
354
                    }
355
 
356
                    uint32 address = shared_ptr->proc_vmips.read_address;
357
                    uint32 byteena = shared_ptr->proc_vmips.read_byteenable;
358
                    uint32 value   = 0xFFFFFFFF;
359
 
360
                    if(address == 0x1FFFFFF0 && byteena == 0xF) {
361
                        if(jtag_deque.empty()) value = 0;
362
                        else {
363
                            value =
364
                                (jtag_deque.front() & 0xFF) |
365
                                (1 << 15) |
366
                                (((jtag_deque.size() - 1) & 0xFFFF) << 16);
367
 
368
                            jtag_deque.pop_front();
369
                        }
370
 
371
                        if(jtag_write_irq_enable == false) {
372
                            if(jtag_deque.empty()) {
373
                                shared_ptr->irq3_at_event = 0xFFFFFFFF;
374
                                printf("jtag: disabling irq\n");
375
                            }
376
                            else {
377
                                shared_ptr->irq3_at_event = shared_ptr->proc_vmips.report.counter + 10;
378
                                printf("jtag: enabling irq\n");
379
                            }
380
                        }
381
 
382
                        printf("read jtaguart data: %08x\n", value);
383
                    }
384
                    else if(address == 0x1FFFFFF4 && byteena == 0xF) {
385
                        value =
386
                            ((jtag_read_irq_enable)?  1 : 0) |
387
                            ((jtag_write_irq_enable)? 2 : 0) |
388
                            (((jtag_deque.empty())? 0 : 1) << 8)  |     //read irq pending
389
                            (1 << 9)  |                                 //write irq pending
390
                            (1 << 10) |                                 //active
391
                            (0xFF << 16);                               //spaces left in write fifo
392
 
393
                        printf("read jtaguart control: %08x\n", value);
394
                    }
395
                    else
396
                    {
397
                        printf("vmips: %08x %01x\n", shared_ptr->proc_vmips.read_address, shared_ptr->proc_vmips.read_byteenable);
398
                        printf("ao:    %08x %01x\n", shared_ptr->proc_ao.read_address,    shared_ptr->proc_ao.read_byteenable);
399
 
400
                        printf("\nRUN FAILED. MEM READ FROM UNKNOWN.\n");
401
                        shared_ptr->test_finished = true;
402
                        return -1;
403
 
404
                    }
405
 
406
                    shared_ptr->proc_vmips.read_data = value;
407
                    shared_ptr->proc_ao.read_data = value;
408
 
409
                    shared_ptr->proc_vmips.read_do = false;
410
                    shared_ptr->proc_ao.read_do    = false;
411
                }
412
                else {
413
                    printf("vmips: %08x %01x\n", shared_ptr->proc_vmips.read_address, shared_ptr->proc_vmips.read_byteenable, shared_ptr->proc_vmips.read_data);
414
                    printf("ao:    %08x %01x\n", shared_ptr->proc_ao.read_address,    shared_ptr->proc_ao.read_byteenable,    shared_ptr->proc_ao.read_data);
415
 
416
                    printf("\nRUN FAILED. MEM READ DIFF.\n");
417
                    shared_ptr->test_finished = true;
418
                    return -1;
419
                }
420
            }
421
            else {
422
                usleep(10);
423
                retry++;
424
 
425
                if(retry == 500000) {
426
                    printf("vmips: %08x %01x\n", shared_ptr->proc_vmips.read_address, shared_ptr->proc_vmips.read_byteenable, shared_ptr->proc_vmips.read_data);
427
                    printf("ao:    %08x %01x\n", shared_ptr->proc_ao.read_address,    shared_ptr->proc_ao.read_byteenable,    shared_ptr->proc_ao.read_data);
428
 
429
                    printf("\nTEST FAILED. WAITING FOR READ.\n");
430
                    shared_ptr->test_finished = true;
431
                    return -1;
432
                }
433
            }
434
        }
435
    }
436
 
437
    //---------------------------------------------------------------------- wait for process end
438
    waitpid(proc_vmips, NULL, 0);
439
    waitpid(proc_ao, NULL, 0);
440
 
441
    return 0;
442
}
443
 
444
//------------------------------------------------------------------------------

powered by: WebSVN 2.1.0

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