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

Subversion Repositories altor32

[/] [altor32/] [trunk/] [or1k-sim/] [main.cpp] - Blame information for rev 28

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 28 ultra_embe
//-----------------------------------------------------------------
2
//                           AltOR32 
3
//                Alternative Lightweight OpenRisc 
4
//                            V2.0
5
//                     Ultra-Embedded.com
6
//                   Copyright 2011 - 2013
7
//
8
//               Email: admin@ultra-embedded.com
9
//
10
//                       License: LGPL
11
//-----------------------------------------------------------------
12
//
13
// Copyright (C) 2011 - 2013 Ultra-Embedded.com
14
//
15
// This source file may be used and distributed without         
16
// restriction provided that this copyright statement is not    
17
// removed from the file and that any derivative work contains  
18
// the original copyright notice and the associated disclaimer. 
19
//
20
// This source file is free software; you can redistribute it   
21
// and/or modify it under the terms of the GNU Lesser General   
22
// Public License as published by the Free Software Foundation; 
23
// either version 2.1 of the License, or (at your option) any   
24
// later version.
25
//
26
// This source is distributed in the hope that it will be       
27
// useful, but WITHOUT ANY WARRANTY; without even the implied   
28
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      
29
// PURPOSE.  See the GNU Lesser General Public License for more 
30
// details.
31
//
32
// You should have received a copy of the GNU Lesser General    
33
// Public License along with this source; if not, write to the 
34
// Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
35
// Boston, MA  02111-1307  USA
36
//-----------------------------------------------------------------
37
#include <stdio.h>
38
#include <string.h>
39
#include <stdlib.h>
40
#include <assert.h>
41
 
42
#include "or32.h"
43
 
44
#include "periph_timer.h"
45
 
46
#ifdef WIN32
47
#include "getopt_win32.h"
48
#else
49
#include <unistd.h>
50
#endif
51
 
52
#ifdef INCLUDE_ELF_SUPPORT
53
#include <libelf.h>
54
#include <fcntl.h>
55
#include <gelf.h>
56
#endif
57
 
58
//-----------------------------------------------------------------
59
// Defines
60
//-----------------------------------------------------------------
61
#define DEFAULT_MEM_BASE            0x10000000
62
#define DEFAULT_MEM_SIZE            (10 << 20)
63
#define DEFAULT_LOAD_ADDR           0x10000000
64
#define DEFAULT_FILENAME            NULL
65
 
66
//-----------------------------------------------------------------
67
// Locals
68
//-----------------------------------------------------------------
69
 
70
//-----------------------------------------------------------------
71
// elf_load
72
//-----------------------------------------------------------------
73
#ifdef INCLUDE_ELF_SUPPORT
74
static int elf_load(OR32 *sim, const char *filename, unsigned int *startAddr)
75
{
76
    int fd;
77
    Elf * e;
78
    Elf_Kind ek;
79
    Elf_Scn *scn;
80
    Elf_Data *data;
81
    Elf32_Shdr *shdr;
82
    size_t shstrndx;
83
 
84
    if (elf_version ( EV_CURRENT ) == EV_NONE)
85
        return 0;
86
 
87
    if ((fd = open ( filename , O_RDONLY , 0)) < 0)
88
        return 0;
89
 
90
    if ((e = elf_begin ( fd , ELF_C_READ, NULL )) == NULL)
91
        return 0;
92
 
93
    ek = elf_kind ( e );
94
    if (ek != ELF_K_ELF)
95
        return 0;
96
 
97
    // Get section name header index
98
    if (elf_getshdrstrndx(e, &shstrndx)!=0)
99
        return 0;
100
 
101
    int section_idx = 0;
102
    while ((scn = elf_getscn(e, section_idx)) != NULL)
103
    {
104
        shdr = elf32_getshdr(scn);
105
 
106
        // Section which need loading (.text, .bss, .data, etc)
107
        if ((shdr->sh_type == SHT_PROGBITS || shdr->sh_type == SHT_NOBITS) &&
108
            (shdr->sh_flags & SHF_EXECINSTR || shdr->sh_flags & SHF_ALLOC)
109
           )
110
        {
111
            data = elf_getdata(scn, NULL);
112
 
113
            // .text section?
114
            if (elf_strptr(e, shstrndx, shdr->sh_name) && startAddr &&
115
                strcmp(elf_strptr(e, shstrndx, shdr->sh_name), ".text") == 0)
116
            {
117
                *startAddr = shdr->sh_addr;
118
            }
119
 
120
            // Create some memory for this section
121
            if (!sim->CreateMemory(shdr->sh_addr, shdr->sh_size))
122
                return 0;
123
 
124
            printf("Memory: 0x%x - 0x%x (Size=%dKB) [%s]\n", shdr->sh_addr, shdr->sh_addr + shdr->sh_size - 1, shdr->sh_size / 1024, elf_strptr(e, shstrndx, shdr->sh_name));
125
 
126
            if (shdr->sh_type == SHT_PROGBITS)
127
            {
128
                if (!sim->Load(shdr->sh_addr, (unsigned char*)data->d_buf, data->d_size))
129
                    return 0;
130
            }
131
        }
132
 
133
        section_idx++;
134
    }
135
 
136
    elf_end ( e );
137
    close ( fd );
138
 
139
    return 1;
140
}
141
#endif
142
//-----------------------------------------------------------------
143
// main
144
//-----------------------------------------------------------------
145
int main(int argc, char *argv[])
146
{
147
    int c;
148
    unsigned int loadAddr = DEFAULT_LOAD_ADDR;
149
    unsigned int memBase = DEFAULT_MEM_BASE;
150
    unsigned int memSize = DEFAULT_MEM_SIZE;
151
    unsigned int startAddr = DEFAULT_MEM_BASE + VECTOR_RESET;
152
    int max_cycles = -1;
153
    char *filename = DEFAULT_FILENAME;
154
    char *elf_file = NULL;
155
    int help = 0;
156
    int trace = 0;
157
    unsigned int trace_mask = 1;
158
    int exitcode = -1;
159
    int mem_trace = 0;
160
    unsigned int trace_enable_pc = 0xFFFFFFFF;
161
    unsigned int stop_pc = 0xFFFFFFFF;
162
    OR32 *sim = NULL;
163
 
164
    while ((c = getopt (argc, argv, "tv:l:b:s:f:c:x:nme:d:z:k:r:")) != -1)
165
    {
166
        switch(c)
167
        {
168
            case 't':
169
                 trace = 1;
170
                 break;
171
            case 'v':
172
                 trace_mask = strtoul(optarg, NULL, 0);
173
                 break;
174
            case 'l':
175
                 loadAddr = strtoul(optarg, NULL, 0);
176
                 break;
177
            case 'b':
178
                 memBase = strtoul(optarg, NULL, 0);
179
                 break;
180
            case 's':
181
                 memSize = strtoul(optarg, NULL, 0);
182
                 break;
183
            case 'x':
184
                 startAddr = strtoul(optarg, NULL, 0);
185
                 break;
186
            case 'k':
187
                 trace_enable_pc = strtoul(optarg, NULL, 0);
188
                 break;
189
            case 'r':
190
                 stop_pc = strtoul(optarg, NULL, 0);
191
                 break;
192
            case 'f':
193
                 filename = optarg;
194
                 break;
195
#ifdef INCLUDE_ELF_SUPPORT                  
196
            case 'e':
197
                 elf_file = optarg;
198
                 break;
199
#endif                 
200
            case 'c':
201
                 max_cycles = (int)strtoul(optarg, NULL, 0);
202
                 break;
203
            case 'm':
204
                 mem_trace = 1;
205
                 break;
206
            case '?':
207
            default:
208
                help = 1;
209
                break;
210
        }
211
    }
212
 
213
    if (help || (filename == NULL && elf_file == NULL))
214
    {
215
        fprintf (stderr,"Usage:\n");
216
        fprintf (stderr,"-f filename.bin = Executable to load (binary)\n");
217
#ifdef INCLUDE_ELF_SUPPORT        
218
        fprintf (stderr,"-e filename.elf = Executable to load (ELF)\n");
219
#endif
220
        fprintf (stderr,"-t              = Enable program trace\n");
221
        fprintf (stderr,"-v 0xX          = Trace Mask\n");
222
        fprintf (stderr,"-b 0xnnnn       = Memory base address\n");
223
        fprintf (stderr,"-s 0xnnnn       = Memory size\n");
224
        fprintf (stderr,"-l 0xnnnn       = Executable load address\n");
225
        fprintf (stderr,"-x 0xnnnn       = Executable boot address\n");
226
        fprintf (stderr,"-c nnnn         = Max instructions to execute\n");
227
        fprintf (stderr,"-k 0xnnnn       = Trace enable PC\n");
228
 
229
        exit(-1);
230
    }
231
 
232
 
233
    if (elf_file)
234
    {
235
#ifdef INCLUDE_ELF_SUPPORT                
236
        sim = new OR32(false);
237
        sim->AttachPeripheral(new TimerPeripheral());
238
 
239
        if (elf_load(sim, elf_file, &memBase))
240
        {
241
            int cycles = 0;
242
 
243
            sim->Reset(memBase + VECTOR_RESET);
244
 
245
            if (trace & trace_enable_pc == 0xFFFFFFFF)
246
                sim->EnableTrace(trace_mask);
247
 
248
            if (mem_trace)
249
            {
250
                printf("Memory trace enabled\n");
251
                sim->EnableMemoryTrace();
252
            }
253
 
254
            printf("Execute from 0x%x\n", memBase + VECTOR_RESET);
255
            while (!sim->GetBreak() && !sim->GetFault() && sim->GetPC() != stop_pc)
256
            {
257
                sim->Step();
258
                cycles++;
259
 
260
                if (max_cycles != -1 && max_cycles == cycles)
261
                    break;
262
 
263
                if (trace)
264
                {
265
                    if (sim->GetPC() == trace_enable_pc)
266
                        sim->EnableTrace(trace_mask);
267
                }
268
            }
269
 
270
            // Show execution stats
271
            sim->DumpStats();
272
 
273
            // Fault occurred?
274
            if (sim->GetFault())
275
                exitcode = 1;
276
            else
277
                exitcode = 0;
278
        }
279
        else
280
            fprintf (stderr,"Error: Could not open ELF file %s\n", elf_file);
281
 
282
        delete sim;
283
 
284
        return exitcode;
285
#else
286
        fprintf (stderr,"Error: ELF files not supported\n");
287
        return -1;
288
#endif
289
    }
290
    else
291
    {
292
        sim = new OR32(memBase, memSize, false);
293
        sim->AttachPeripheral(new TimerPeripheral());
294
 
295
        sim->Reset(startAddr);
296
 
297
        if (trace)
298
            sim->EnableTrace(trace_mask);
299
 
300
        if (mem_trace)
301
        {
302
            printf("Memory trace enabled\n");
303
            sim->EnableMemoryTrace();
304
        }
305
 
306
        FILE *f = fopen(filename, "rb");
307
        if (f)
308
        {
309
            long size;
310
            char *buf;
311
 
312
            // Get size
313
            fseek(f, 0, SEEK_END);
314
            size = ftell(f);
315
            rewind(f);
316
 
317
            buf = (char*)malloc(size+1);
318
            if (buf)
319
            {
320
                int wait_for_input = 0;
321
 
322
                // Read file data in
323
                int len = fread(buf, 1, size, f);
324
                buf[len] = 0;
325
 
326
                if (sim->Load(loadAddr, (unsigned char *)buf, len))
327
                {
328
                    int cycles = 0;
329
 
330
                    while (!sim->GetBreak() && !sim->GetFault() && sim->GetPC() != stop_pc)
331
                    {
332
                        sim->Step();
333
                        cycles++;
334
 
335
                        if (max_cycles != -1 && max_cycles == cycles)
336
                            break;
337
 
338
                        if (trace)
339
                        {
340
                            if (sim->GetPC() == trace_enable_pc)
341
                                sim->EnableTrace(trace_mask);
342
                        }
343
                    }
344
                }
345
                else
346
                    fprintf (stderr,"Error: Could not load image to memory\n");
347
 
348
                free(buf);
349
                fclose(f);
350
            }
351
            // Show execution stats
352
            sim->DumpStats();
353
 
354
            // Fault occurred?
355
            if (sim->GetFault())
356
                exitcode = 1;
357
            else
358
                exitcode = 0;
359
        }
360
        else
361
            fprintf (stderr,"Error: Could not open %s\n", filename);
362
 
363
        delete sim;
364
    }
365
 
366
    return exitcode;
367
}
368
 

powered by: WebSVN 2.1.0

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