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

Subversion Repositories ion

[/] [ion/] [trunk/] [tools/] [slite/] [src/] [slite.c] - Blame information for rev 44

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

Line No. Rev Author Line
1 2 ja_rd
/*------------------------------------------------------------------------------
2
* slite.c -- MIPS-I simulator based on Steve Rhoad's "mlite"
3
*
4
* This is a slightly modified version of Steve Rhoad's "mlite" simulator, which
5
* is part of his PLASMA project (original date: 1/31/01).
6
*
7
*-------------------------------------------------------------------------------
8
* Usage:
9
*     slite <code file name> <data file name>
10
*
11
* The program will allocate a chunk of RAM (MEM_SIZE bytes) and map it to
12
* address 0x00000000 of the simulated CPU.
13
* Then it will read the 'code file' (as a big-endian plain binary) onto address
14
* 0x0 of the simulated CPU memory, and 'data file' on address 0x10000.
15
* Finally, will reset the CPU and enter the interactive debugger.
16
*
17
* (Note that the above is only necessary if the system does not have caches,
18
* because of the Harvard architecture. With caches in place, program loading
19
* would be antirely conventional).
20
*
21
* A simulation log file will be dumped to file "sw_sim_log.txt". This log can be
22
* used to compare with an equivalent log dumped by the hardware simulation, as
23
* a simple way to validate the hardware for a given program. See the project
24
* readme files for details.
25
*
26
*-------------------------------------------------------------------------------
27
* KNOWN BUGS:
28
*
29
*-------------------------------------------------------------------------------
30
* @date 2011-jan-16
31
*
32
*-------------------------------------------------------------------------------
33
* COPYRIGHT:    Software placed into the public domain by the author.
34
*               Software 'as is' without warranty.  Author liable for nothing.
35
*
36
* IMPORTANT: Assumes host is little endian.
37
*-----------------------------------------------------------------------------*/
38
 
39
#include <stdio.h>
40 11 ja_rd
#include <stdlib.h>
41
#include <stdint.h>
42 2 ja_rd
#include <string.h>
43
#include <ctype.h>
44
#include <assert.h>
45
 
46 31 ja_rd
/** Set to !=0 to disable file logging (much faster simulation) */
47 2 ja_rd
#define FILE_LOGGING_DISABLED (0)
48
/** Define to enable cache simulation (unimplemented) */
49
//#define ENABLE_CACHE
50 31 ja_rd
 
51
 
52
/*---- Definition of simulated system parameters -----------------------------*/
53
 
54
 
55
#define VECTOR_RESET (0x00000000)
56
#define VECTOR_TRAP  (0x0000003c)
57
 
58
typedef struct s_block {
59
    uint32_t start;
60
    uint32_t size;
61 44 ja_rd
    uint32_t mask;
62 31 ja_rd
    uint8_t  *mem;
63
    char     *name;
64
} t_block;
65
 
66
 
67 44 ja_rd
/* Here's where we define the memory areas (blocks) of the system.
68
   Memory decoding is done in the order the blocks are defined; the address
69
   is anded with field .mask and then compared to field .start. If they match
70
   the address modulo the field .size is used to index the memory block, giving
71
   a 'mirror' effect. All of this simulates the behavior of the actual hardware.
72
   Make sure the blocks don't overlap or the scheme will fail.
73
*/
74 31 ja_rd
 
75
#define NUM_MEM_BLOCKS (2)
76
 
77
t_block default_blocks[NUM_MEM_BLOCKS] = {
78
    /* meant as bootstrap block, though it's read/write */
79 44 ja_rd
    {VECTOR_RESET,  0x00010000, 0xf0000000, NULL, "Boot"},
80 31 ja_rd
    /* main ram block  */
81 44 ja_rd
    {0x80000000,    0x00001000, 0xf0000000, NULL, "Data"}
82 31 ja_rd
};
83
 
84 2 ja_rd
 
85
#define ntohs(A) ( ((A)>>8) | (((A)&0xff)<<8) )
86
#define htons(A) ntohs(A)
87
#define ntohl(A) ( ((A)>>24) | (((A)&0xff0000)>>8) | (((A)&0xff00)<<8) | ((A)<<24) )
88
#define htonl(A) ntohl(A)
89
 
90
/*---- OS-dependent support functions and definitions ------------------------*/
91
#ifndef WIN32
92
//Support for Linux
93
#define putch putchar
94
#include <termios.h>
95
#include <unistd.h>
96
 
97 31 ja_rd
void slite_sleep(unsigned int value){
98
    usleep(value * 1000);
99 2 ja_rd
}
100
 
101 31 ja_rd
int kbhit(void){
102
    struct termios oldt, newt;
103
    struct timeval tv;
104
    fd_set read_fd;
105 2 ja_rd
 
106 31 ja_rd
    tcgetattr(STDIN_FILENO, &oldt);
107
    newt = oldt;
108
    newt.c_lflag &= ~(ICANON | ECHO);
109
    tcsetattr(STDIN_FILENO, TCSANOW, &newt);
110
    tv.tv_sec=0;
111
    tv.tv_usec=0;
112
    FD_ZERO(&read_fd);
113
    FD_SET(0,&read_fd);
114
    if(select(1, &read_fd, NULL, NULL, &tv) == -1){
115
        return 0;
116
    }
117
    //tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
118
    if(FD_ISSET(0,&read_fd)){
119
        return 1;
120
    }
121
    return 0;
122 2 ja_rd
}
123
 
124 31 ja_rd
int getch(void){
125
    struct termios oldt, newt;
126
    int ch;
127 2 ja_rd
 
128 31 ja_rd
    tcgetattr(STDIN_FILENO, &oldt);
129
    newt = oldt;
130
    newt.c_lflag &= ~(ICANON | ECHO);
131
    tcsetattr(STDIN_FILENO, TCSANOW, &newt);
132
    ch = getchar();
133
    //tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
134
    return ch;
135 2 ja_rd
}
136
#else
137
//Support for Windows
138
#include <conio.h>
139 31 ja_rd
extern void __stdcall Sleep(unsigned long value);
140
 
141
void slite_sleep(unsigned int value){
142
    Sleep(value);
143
}
144
 
145 2 ja_rd
#endif
146
/*---- End of OS-dependent support functions and definitions -----------------*/
147
 
148
/*---- Hardware system parameters --------------------------------------------*/
149
 
150
/* Much of this is a remnant from Plasma's mlite and is  no longer used. */
151
/* FIXME Refactor HW system params */
152
 
153
#define UART_WRITE        0x20000000
154
#define UART_READ         0x20000000
155
#define IRQ_MASK          0x20000010
156
#define IRQ_STATUS        0x20000020
157
#define CONFIG_REG        0x20000070
158
#define MMU_PROCESS_ID    0x20000080
159
#define MMU_FAULT_ADDR    0x20000090
160
#define MMU_TLB           0x200000a0
161
 
162
#define IRQ_UART_READ_AVAILABLE  0x001
163
#define IRQ_UART_WRITE_AVAILABLE 0x002
164
#define IRQ_COUNTER18_NOT        0x004
165
#define IRQ_COUNTER18            0x008
166
#define IRQ_MMU                  0x200
167
 
168 5 ja_rd
/*----------------------------------------------------------------------------*/
169 2 ja_rd
 
170 5 ja_rd
/* These are flags that will be used to notify the main cycle function of any
171
   failed assertions in its subfunctions. */
172
#define ASRT_UNALIGNED_READ         (1<<0)
173
#define ASRT_UNALIGNED_WRITE        (1<<1)
174
 
175
char *assertion_messages[2] = {
176
   "Unaligned read",
177
   "Unaligned write"
178
};
179
 
180
 
181 2 ja_rd
/** Length of debugging jump target queue */
182
#define TRACE_BUFFER_SIZE (32)
183
 
184 31 ja_rd
typedef struct s_trace {
185 2 ja_rd
   unsigned int buf[TRACE_BUFFER_SIZE];   /**< queue of last jump targets */
186
   unsigned int next;                     /**< internal queue head pointer */
187
   FILE *log;                             /**< text log file or NULL */
188
   int pr[32];                            /**< last value of register bank */
189
   int hi, lo, epc;                       /**< last value of internal regs */
190 31 ja_rd
} t_trace;
191 2 ja_rd
 
192 31 ja_rd
typedef struct s_state {
193 5 ja_rd
   unsigned failed_assertions;            /**< assertion bitmap */
194
   unsigned faulty_address;               /**< addr that failed assertion */
195 27 ja_rd
 
196
   int delay_slot;              /**< !=0 if prev. instruction was a branch */
197 5 ja_rd
 
198 2 ja_rd
   int r[32];
199
   int opcode;
200
   int pc, pc_next, epc;
201
   unsigned int hi;
202
   unsigned int lo;
203 27 ja_rd
   int status;
204
   unsigned cp0_cause;
205 2 ja_rd
   int userMode;
206
   int processId;
207 5 ja_rd
   int exceptionId;        /**< DEPRECATED, to be removed */
208 2 ja_rd
   int faultAddr;
209
   int irqStatus;
210
   int skip;
211 31 ja_rd
   t_trace t;
212
   //unsigned char *mem;
213
   t_block blocks[NUM_MEM_BLOCKS];
214 2 ja_rd
   int wakeup;
215
   int big_endian;
216 31 ja_rd
} t_state;
217 2 ja_rd
 
218
static char *opcode_string[]={
219
   "SPECIAL","REGIMM","J","JAL","BEQ","BNE","BLEZ","BGTZ",
220
   "ADDI","ADDIU","SLTI","SLTIU","ANDI","ORI","XORI","LUI",
221
   "COP0","COP1","COP2","COP3","BEQL","BNEL","BLEZL","BGTZL",
222
   "?","?","?","?","?","?","?","?",
223
   "LB","LH","LWL","LW","LBU","LHU","LWR","?",
224
   "SB","SH","SWL","SW","?","?","SWR","CACHE",
225
   "LL","LWC1","LWC2","LWC3","?","LDC1","LDC2","LDC3"
226
   "SC","SWC1","SWC2","SWC3","?","SDC1","SDC2","SDC3"
227
};
228
 
229
static char *special_string[]={
230
   "SLL","?","SRL","SRA","SLLV","?","SRLV","SRAV",
231
   "JR","JALR","MOVZ","MOVN","SYSCALL","BREAK","?","SYNC",
232
   "MFHI","MTHI","MFLO","MTLO","?","?","?","?",
233
   "MULT","MULTU","DIV","DIVU","?","?","?","?",
234
   "ADD","ADDU","SUB","SUBU","AND","OR","XOR","NOR",
235
   "?","?","SLT","SLTU","?","DADDU","?","?",
236
   "TGE","TGEU","TLT","TLTU","TEQ","?","TNE","?",
237
   "?","?","?","?","?","?","?","?"
238
};
239
 
240
static char *regimm_string[]={
241
   "BLTZ","BGEZ","BLTZL","BGEZL","?","?","?","?",
242
   "TGEI","TGEIU","TLTI","TLTIU","TEQI","?","TNEI","?",
243
   "BLTZAL","BEQZAL","BLTZALL","BGEZALL","?","?","?","?",
244
   "?","?","?","?","?","?","?","?"
245
};
246
 
247
static unsigned int HWMemory[8];
248
 
249
/*---- Local function prototypes ---------------------------------------------*/
250
 
251
/* Debug and logging */
252 31 ja_rd
void init_trace_buffer(t_state *s, const char *log_file_name);
253
void close_trace_buffer(t_state *s);
254
void dump_trace_buffer(t_state *s);
255
void log_cycle(t_state *s);
256
void log_read(t_state *s, int full_address, int word_value, int size, int log);
257
void log_failed_assertions(t_state *s);
258 2 ja_rd
 
259 31 ja_rd
/* CPU model */
260
void free_cpu(t_state *s);
261 44 ja_rd
int init_cpu(t_state *s);
262 31 ja_rd
void reset_cpu(t_state *s);
263
 
264 2 ja_rd
/* Hardware simulation */
265 31 ja_rd
int mem_read(t_state *s, int size, unsigned int address, int log);
266
void mem_write(t_state *s, int size, unsigned address, unsigned value, int log);
267
void start_load(t_state *s, int rt, int data);
268 2 ja_rd
 
269 16 ja_rd
 
270 2 ja_rd
/*---- Local functions -------------------------------------------------------*/
271
 
272
/** Log to file a memory read operation (not including target reg change) */
273 31 ja_rd
void log_read(t_state *s, int full_address, int word_value, int size, int log){
274 2 ja_rd
   if(s->t.log!=NULL && log!=0){
275
      if(size==4){ size=0x04; }
276
      else if(size==2){ size=0x02; }
277
      else { size=0x01; }
278
      fprintf(s->t.log, "(%08X) [%08X] <**>=%08X RD\n",
279
              s->pc, full_address, /*size,*/ word_value);
280
   }
281
}
282
 
283
/** Read memory, optionally logging */
284 31 ja_rd
int mem_read(t_state *s, int size, unsigned int address, int log){
285
    unsigned int value=0, word_value=0, i, ptr;
286
    unsigned int full_address = address;
287 2 ja_rd
 
288 31 ja_rd
    s->irqStatus |= IRQ_UART_WRITE_AVAILABLE;
289
    switch(address){
290
    case UART_READ:
291
        word_value = 0x00000001;
292
        log_read(s, full_address, word_value, size, log);
293
        return word_value;
294
        /* FIXME Take input from text file */
295
        /*
296
        if(kbhit()){
297 2 ja_rd
            HWMemory[0] = getch();
298 31 ja_rd
        }
299
        s->irqStatus &= ~IRQ_UART_READ_AVAILABLE; //clear bit
300
        return HWMemory[0];
301
        */
302
    case IRQ_MASK:
303
       return HWMemory[1];
304
    case IRQ_MASK + 4:
305
       slite_sleep(10);
306
       return 0;
307
    case IRQ_STATUS:
308
       /*if(kbhit())
309
          s->irqStatus |= IRQ_UART_READ_AVAILABLE;
310
       return s->irqStatus;
311
       */
312
       /* FIXME Optionally simulate UART TX delay */
313
       word_value = 0x00000003; /* Ready to TX and RX */
314
       log_read(s, full_address, word_value, size, log);
315
       return word_value;
316
    case MMU_PROCESS_ID:
317
       return s->processId;
318
    case MMU_FAULT_ADDR:
319
       return s->faultAddr;
320
    }
321
 
322
    /* point ptr to the byte in the block, or NULL is the address is unmapped */
323
    ptr = 0;
324
    for(i=0;i<NUM_MEM_BLOCKS;i++){
325 44 ja_rd
        if((address & s->blocks[i].mask) == s->blocks[i].start){
326
            ptr = (unsigned)(s->blocks[i].mem) +
327
                  ((address - s->blocks[i].start) % s->blocks[i].size);
328 31 ja_rd
            break;
329
        }
330
    }
331
    if(!ptr){
332
        /* address out of mapped blocks: log and return zero */
333
        if(s->t.log!=NULL && log!=0){
334
            fprintf(s->t.log, "(%08X) [%08X] <**>=%08X RD UNMAPPED\n",
335
                s->pc, full_address, 0);
336
        }
337
        return 0;
338
    }
339
 
340
    /* get the whole word */
341
    word_value = *(int*)(ptr&0xfffffffc);
342
    if(s->big_endian){
343
        word_value = ntohl(word_value);
344
    }
345 2 ja_rd
 
346 31 ja_rd
    switch(size){
347
    case 4:
348
        if(address & 3){
349 2 ja_rd
            printf("Unaligned access PC=0x%x address=0x%x\n",
350 31 ja_rd
                (int)s->pc, (int)address);
351
        }
352
        if((address & 3) != 0){
353
            /* unaligned word, log fault */
354 5 ja_rd
            s->failed_assertions |= ASRT_UNALIGNED_READ;
355
            s->faulty_address = address;
356
            address = address & 0xfffffffc;
357 31 ja_rd
        }
358
        value = *(int*)ptr;
359
        if(s->big_endian){
360
            value = ntohl(value);
361
        }
362
        break;
363
    case 2:
364
        if((address & 1) != 0){
365
            /* unaligned halfword, log fault */
366 5 ja_rd
            s->failed_assertions |= ASRT_UNALIGNED_READ;
367
            s->faulty_address = address;
368
            address = address & 0xfffffffe;
369 31 ja_rd
        }
370
        value = *(unsigned short*)ptr;
371
        if(s->big_endian){
372
            value = ntohs((unsigned short)value);
373
        }
374
        break;
375
    case 1:
376
        value = *(unsigned char*)ptr;
377
        break;
378
    default:
379
        /* FIXME this is a bug, should quit */
380
        printf("ERROR");
381
    }
382 2 ja_rd
 
383 31 ja_rd
    log_read(s, full_address, word_value, size, log);
384
    return(value);
385 2 ja_rd
}
386
 
387
/** Write memory */
388 31 ja_rd
void mem_write(t_state *s, int size, unsigned address, unsigned value, int log){
389
    unsigned int i, ptr, mask, dvalue, b0, b1, b2, b3;
390 2 ja_rd
 
391 31 ja_rd
    if(s->t.log!=NULL){
392
        b0 = value & 0x000000ff;
393
        b1 = value & 0x0000ff00;
394
        b2 = value & 0x00ff0000;
395
        b3 = value & 0xff000000;
396 2 ja_rd
 
397 31 ja_rd
        switch(size){
398
        case 4:  mask = 0x0f;
399
            dvalue = value;
400
            break;
401
        case 2:
402
            if((address&0x2)==0){
403
                mask = 0xc;
404
                dvalue = b1<<16 | b0<<16;
405
            }
406
            else{
407
               mask = 0x3;
408
               dvalue = b1 | b0;
409
            }
410
            break;
411
        case 1:
412
            switch(address%4){
413
            case 0 : mask = 0x8;
414
                dvalue = b0<<24;
415
                break;
416
            case 1 : mask = 0x4;
417
                dvalue = b0<<16;
418
                break;
419
            case 2 : mask = 0x2;
420
                dvalue = b0<<8;
421
                break;
422
            case 3 : mask = 0x1;
423
                dvalue = b0;
424
                break;
425
            }
426
            break;
427
        default:
428 2 ja_rd
            printf("BUG: mem write size invalid (%08x)\n", s->pc);
429
            exit(2);
430 31 ja_rd
        }
431 2 ja_rd
 
432 31 ja_rd
        fprintf(s->t.log, "(%08X) [%08X] |%02X|=%08X WR\n",
433
                s->pc, address, mask, dvalue);
434
    }
435 2 ja_rd
 
436 31 ja_rd
    switch(address){
437
    case UART_WRITE:
438
        putch(value);
439
        fflush(stdout);
440
        return;
441
    case IRQ_MASK:
442
        HWMemory[1] = value;
443
        return;
444
    case IRQ_STATUS:
445
        s->irqStatus = value;
446
        return;
447
    case CONFIG_REG:
448
        return;
449
    case MMU_PROCESS_ID:
450
        //printf("processId=%d\n", value);
451
        s->processId = value;
452
        return;
453
    }
454 2 ja_rd
 
455 31 ja_rd
    //ptr = (unsigned int)s->mem + (address % MEM_SIZE);
456
    if(address >= 0x80000000){
457
        ptr = 1;
458
    }
459
    ptr = 0;
460
    for(i=0;i<NUM_MEM_BLOCKS;i++){
461 44 ja_rd
        if((address & s->blocks[i].mask) == s->blocks[i].start){
462
            ptr = (unsigned)(s->blocks[i].mem) +
463
                            ((address - s->blocks[i].start) % s->blocks[i].size);
464 31 ja_rd
            break;
465
        }
466
    }
467
    if(!ptr){
468
        /* address out of mapped blocks: log and return zero */
469
        if(s->t.log!=NULL && log!=0){
470
            fprintf(s->t.log, "(%08X) [%08X] |%02X|=%08X WR UNMAPPED\n",
471
                s->pc, address, mask, dvalue);
472
        }
473
        return;
474
    }
475 2 ja_rd
 
476 31 ja_rd
    switch(size){
477
    case 4:
478
        if((address & 3) != 0){
479
            /* unaligned word, log fault */
480 5 ja_rd
            s->failed_assertions |= ASRT_UNALIGNED_WRITE;
481
            s->faulty_address = address;
482
            address = address & (~0x03);
483 31 ja_rd
        }
484
        if(s->big_endian){
485
            value = htonl(value);
486
        }
487
        *(int*)ptr = value;
488
        break;
489
    case 2:
490
        if((address & 1) != 0){
491
            /* unaligned halfword, log fault */
492 5 ja_rd
            s->failed_assertions |= ASRT_UNALIGNED_WRITE;
493
            s->faulty_address = address;
494
            address = address & (~0x01);
495 31 ja_rd
        }
496
        if(s->big_endian){
497
            value = htons((unsigned short)value);
498
        }
499
        *(short*)ptr = (unsigned short)value;
500
        break;
501
    case 1:
502
        *(char*)ptr = (unsigned char)value;
503
        break;
504
    default:
505
        /* FIXME this is a bug, should quit */
506
        printf("ERROR");
507
    }
508 2 ja_rd
}
509
 
510
/*---- Optional MMU and cache implementation ---------------------------------*/
511
 
512
/*
513
   The actual core does not have a cache so all of the original Plasma mlite.c
514
   code for cache simulation has been removed.
515
*/
516
 
517
/*---- End optional cache implementation -------------------------------------*/
518
 
519
 
520
/** Simulates MIPS-I multiplier unsigned behavior*/
521
void mult_big(unsigned int a,
522
              unsigned int b,
523
              unsigned int *hi,
524 31 ja_rd
              unsigned int *lo){
525
    unsigned int ahi, alo, bhi, blo;
526
    unsigned int c0, c1, c2;
527
    unsigned int c1_a, c1_b;
528 2 ja_rd
 
529 31 ja_rd
    ahi = a >> 16;
530
    alo = a & 0xffff;
531
    bhi = b >> 16;
532
    blo = b & 0xffff;
533 2 ja_rd
 
534 31 ja_rd
    c0 = alo * blo;
535
    c1_a = ahi * blo;
536
    c1_b = alo * bhi;
537
    c2 = ahi * bhi;
538 2 ja_rd
 
539 31 ja_rd
    c2 += (c1_a >> 16) + (c1_b >> 16);
540
    c1 = (c1_a & 0xffff) + (c1_b & 0xffff) + (c0 >> 16);
541
    c2 += (c1 >> 16);
542
    c0 = (c1 << 16) + (c0 & 0xffff);
543
    *hi = c2;
544
    *lo = c0;
545 2 ja_rd
}
546
 
547
/** Simulates MIPS-I multiplier signed behavior*/
548
void mult_big_signed(int a,
549
                     int b,
550
                     unsigned int *hi,
551 31 ja_rd
                     unsigned int *lo){
552
    int64_t xa, xb, xr, temp;
553
    int32_t rh, rl;
554 11 ja_rd
 
555 31 ja_rd
    xa = a;
556
    xb = b;
557
    xr = xa * xb;
558 11 ja_rd
 
559 31 ja_rd
    temp = (xr >> 32) & 0xffffffff;
560
    rh = temp;
561
    temp = (xr >> 0) & 0xffffffff;
562
    rl = temp;
563 11 ja_rd
 
564 31 ja_rd
    *hi = rh;
565
    *lo = rl;
566 2 ja_rd
}
567
 
568
/** Load data from memory (used to simulate load delay slots) */
569 31 ja_rd
void start_load(t_state *s, int rt, int data){
570
    /* load delay slot not simulated */
571
    s->r[rt] = data;
572 2 ja_rd
}
573
 
574
/** Execute one cycle of the CPU (including any interlock stall cycles) */
575 31 ja_rd
void cycle(t_state *s, int show_mode){
576
    unsigned int opcode;
577
    int delay_slot = 0; /* 1 of this instruction is a branch */
578
    unsigned int op, rs, rt, rd, re, func, imm, target;
579
    int trap_cause = 0;
580
    int imm_shift, branch=0, lbranch=2, skip2=0;
581
    int *r=s->r;
582
    unsigned int *u=(unsigned int*)s->r;
583
    unsigned int ptr, epc, rSave;
584 2 ja_rd
 
585 31 ja_rd
    if(!show_mode){
586
        /* if we're NOT showing output to console, log state of CPU to file */
587
        log_cycle(s);
588
    }
589 2 ja_rd
 
590 31 ja_rd
    opcode = mem_read(s, 4, s->pc, 0);
591
    op = (opcode >> 26) & 0x3f;
592
    rs = (opcode >> 21) & 0x1f;
593
    rt = (opcode >> 16) & 0x1f;
594
    rd = (opcode >> 11) & 0x1f;
595
    re = (opcode >> 6) & 0x1f;
596
    func = opcode & 0x3f;
597
    imm = opcode & 0xffff;
598
    imm_shift = (((int)(short)imm) << 2) - 4;
599
    target = (opcode << 6) >> 4;
600
    ptr = (short)imm + r[rs];
601
    r[0] = 0;
602
 
603
    /* if we are priting state to console, do it now */
604
    if(show_mode){
605
        printf("%8.8x %8.8x ", s->pc, opcode);
606
        if(op == 0){
607
            printf("%8s ", special_string[func]);
608
        }
609
        else if(op == 1){
610
            printf("%8s ", regimm_string[rt]);
611
        }
612
        else{
613
            printf("%8s ", opcode_string[op]);
614
        }
615 2 ja_rd
 
616 31 ja_rd
        printf("$%2.2d $%2.2d $%2.2d $%2.2d ", rs, rt, rd, re);
617
        printf("%4.4x", imm);
618
        if(show_mode == 1){
619
            printf(" r[%2.2d]=%8.8x r[%2.2d]=%8.8x", rs, r[rs], rt, r[rt]);
620
        }
621
        printf("\n");
622
    }
623
 
624
    /* if we're just showing state to console, quit and don't run instruction */
625
    if(show_mode > 5){
626
        return;
627
    }
628
 
629
    /* epc will point to the victim instruction, i.e. THIS instruction */
630
    epc = s->pc;
631 32 ja_rd
 
632
    /* If we catch a jump instruction jumping to itself, assume we hit the
633
       and of the program and quit. */
634
    if(s->pc == s->pc_next+4){
635
        printf("\n\nEndless loop at 0x%08x\n\n", s->pc-4);
636
        s->wakeup = 1;
637
    }
638 31 ja_rd
    s->pc = s->pc_next;
639
    s->pc_next = s->pc_next + 4;
640
    if(s->skip){
641
        s->skip = 0;
642
        return;
643
    }
644
    rSave = r[rt];
645
 
646
    switch(op){
647
    case 0x00:/*SPECIAL*/
648
        switch(func){
649
        case 0x00:/*SLL*/  r[rd]=r[rt]<<re;          break;
650
        case 0x02:/*SRL*/  r[rd]=u[rt]>>re;          break;
651
        case 0x03:/*SRA*/  r[rd]=r[rt]>>re;          break;
652
        case 0x04:/*SLLV*/ r[rd]=r[rt]<<r[rs];       break;
653
        case 0x06:/*SRLV*/ r[rd]=u[rt]>>r[rs];       break;
654
        case 0x07:/*SRAV*/ r[rd]=r[rt]>>r[rs];       break;
655
        case 0x08:/*JR*/   delay_slot=1;
656
                           s->pc_next=r[rs];         break;
657
        case 0x09:/*JALR*/ delay_slot=1;
658
                           r[rd]=s->pc_next;
659
                           s->pc_next=r[rs]; break;
660
        case 0x0a:/*MOVZ*/ if(!r[rt]) r[rd]=r[rs];   break;  /*IV*/
661
        case 0x0b:/*MOVN*/ if(r[rt]) r[rd]=r[rs];    break;  /*IV*/
662
        case 0x0c:/*SYSCALL*/ trap_cause = 8;
663
                              s->exceptionId=1; break;
664
        case 0x0d:/*BREAK*/   trap_cause = 9;
665
                              s->exceptionId=1; break;
666
        case 0x0f:/*SYNC*/ s->wakeup=1;              break;
667
        case 0x10:/*MFHI*/ r[rd]=s->hi;              break;
668
        case 0x11:/*FTHI*/ s->hi=r[rs];              break;
669
        case 0x12:/*MFLO*/ r[rd]=s->lo;              break;
670
        case 0x13:/*MTLO*/ s->lo=r[rs];              break;
671
        case 0x18:/*MULT*/ mult_big_signed(r[rs],r[rt],&s->hi,&s->lo); break;
672
        case 0x19:/*MULTU*/ mult_big(r[rs],r[rt],&s->hi,&s->lo); break;
673
        case 0x1a:/*DIV*/  s->lo=r[rs]/r[rt]; s->hi=r[rs]%r[rt]; break;
674
        case 0x1b:/*DIVU*/ s->lo=u[rs]/u[rt]; s->hi=u[rs]%u[rt]; break;
675
        case 0x20:/*ADD*/  r[rd]=r[rs]+r[rt];        break;
676
        case 0x21:/*ADDU*/ r[rd]=r[rs]+r[rt];        break;
677
        case 0x22:/*SUB*/  r[rd]=r[rs]-r[rt];        break;
678
        case 0x23:/*SUBU*/ r[rd]=r[rs]-r[rt];        break;
679
        case 0x24:/*AND*/  r[rd]=r[rs]&r[rt];        break;
680
        case 0x25:/*OR*/   r[rd]=r[rs]|r[rt];        break;
681
        case 0x26:/*XOR*/  r[rd]=r[rs]^r[rt];        break;
682
        case 0x27:/*NOR*/  r[rd]=~(r[rs]|r[rt]);     break;
683
        case 0x2a:/*SLT*/  r[rd]=r[rs]<r[rt];        break;
684
        case 0x2b:/*SLTU*/ r[rd]=u[rs]<u[rt];        break;
685
        case 0x2d:/*DADDU*/r[rd]=r[rs]+u[rt];        break;
686
        case 0x31:/*TGEU*/ break;
687
        case 0x32:/*TLT*/  break;
688
        case 0x33:/*TLTU*/ break;
689
        case 0x34:/*TEQ*/  break;
690
        case 0x36:/*TNE*/  break;
691
        default: printf("ERROR0(*0x%x~0x%x)\n", s->pc, opcode);
692
           s->wakeup=1;
693
        }
694
        break;
695
    case 0x01:/*REGIMM*/
696
        switch(rt){
697 2 ja_rd
            case 0x10:/*BLTZAL*/ r[31]=s->pc_next;
698
            case 0x00:/*BLTZ*/   branch=r[rs]<0;    break;
699
            case 0x11:/*BGEZAL*/ r[31]=s->pc_next;
700
            case 0x01:/*BGEZ*/   branch=r[rs]>=0;   break;
701
            case 0x12:/*BLTZALL*/r[31]=s->pc_next;
702
            case 0x02:/*BLTZL*/  lbranch=r[rs]<0;   break;
703
            case 0x13:/*BGEZALL*/r[31]=s->pc_next;
704
            case 0x03:/*BGEZL*/  lbranch=r[rs]>=0;  break;
705
            default: printf("ERROR1\n"); s->wakeup=1;
706 31 ja_rd
        }
707
        break;
708
    case 0x03:/*JAL*/    r[31]=s->pc_next;
709
    case 0x02:/*J*/      delay_slot=1;
710
                       s->pc_next=(s->pc&0xf0000000)|target; break;
711
    case 0x04:/*BEQ*/    branch=r[rs]==r[rt];     break;
712
    case 0x05:/*BNE*/    branch=r[rs]!=r[rt];     break;
713
    case 0x06:/*BLEZ*/   branch=r[rs]<=0;         break;
714
    case 0x07:/*BGTZ*/   branch=r[rs]>0;          break;
715
    case 0x08:/*ADDI*/   r[rt]=r[rs]+(short)imm;  break;
716
    case 0x09:/*ADDIU*/  u[rt]=u[rs]+(short)imm;  break;
717
    case 0x0a:/*SLTI*/   r[rt]=r[rs]<(short)imm;  break;
718
    case 0x0b:/*SLTIU*/  u[rt]=u[rs]<(unsigned int)(short)imm; break;
719
    case 0x0c:/*ANDI*/   r[rt]=r[rs]&imm;         break;
720
    case 0x0d:/*ORI*/    r[rt]=r[rs]|imm;         break;
721
    case 0x0e:/*XORI*/   r[rt]=r[rs]^imm;         break;
722
    case 0x0f:/*LUI*/    r[rt]=(imm<<16);         break;
723
    case 0x10:/*COP0*/
724
        if((opcode & (1<<23)) == 0){  //move from CP0
725 27 ja_rd
            if(rd == 12){
726 31 ja_rd
                r[rt]=s->status;
727 27 ja_rd
            }
728
            else if(rd == 13){
729 31 ja_rd
                r[rt]=s->cp0_cause;
730 27 ja_rd
            }
731
            else{
732 31 ja_rd
                r[rt]=s->epc;
733 27 ja_rd
            }
734 31 ja_rd
        }
735
        else{                         //move to CP0
736 2 ja_rd
            s->status=r[rt]&1;
737 31 ja_rd
            if(s->processId && (r[rt]&2)){
738
                s->userMode|=r[rt]&2;
739
                //printf("CpuStatus=%d %d %d\n", r[rt], s->status, s->userMode);
740
                //s->wakeup = 1;
741
                //printf("pc=0x%x\n", epc);
742 2 ja_rd
            }
743 31 ja_rd
        }
744
        break;
745 2 ja_rd
//      case 0x11:/*COP1*/ break;
746
//      case 0x12:/*COP2*/ break;
747
//      case 0x13:/*COP3*/ break;
748 31 ja_rd
    case 0x14:/*BEQL*/  lbranch=r[rs]==r[rt];    break;
749
    case 0x15:/*BNEL*/  lbranch=r[rs]!=r[rt];    break;
750
    case 0x16:/*BLEZL*/ lbranch=r[rs]<=0;        break;
751
    case 0x17:/*BGTZL*/ lbranch=r[rs]>0;         break;
752 2 ja_rd
//      case 0x1c:/*MAD*/  break;   /*IV*/
753 31 ja_rd
    case 0x20:/*LB*/    //r[rt]=(signed char)mem_read(s,1,ptr,1);  break;
754
                        start_load(s, rt,(signed char)mem_read(s,1,ptr,1));
755
                        break;
756 2 ja_rd
 
757 31 ja_rd
    case 0x21:/*LH*/    //r[rt]=(signed short)mem_read(s,2,ptr,1); break;
758
                        start_load(s, rt, (signed short)mem_read(s,2,ptr,1));
759
                        break;
760
    case 0x22:/*LWL*/   //target=8*(ptr&3);
761
                        //r[rt]=(r[rt]&~(0xffffffff<<target))|
762
                        //      (mem_read(s,4,ptr&~3)<<target); break;
763
                        break;
764
    case 0x23:/*LW*/    //r[rt]=mem_read(s,4,ptr,1);   break;
765
                        start_load(s, rt, mem_read(s,4,ptr,1));
766
                        break;
767
    case 0x24:/*LBU*/   //r[rt]=(unsigned char)mem_read(s,1,ptr,1); break;
768
                        start_load(s, rt, (unsigned char)mem_read(s,1,ptr,1));
769
                        break;
770
    case 0x25:/*LHU*/   //r[rt]= (unsigned short)mem_read(s,2,ptr,1);
771
                        start_load(s, rt, (unsigned short)mem_read(s,2,ptr,1));
772
                        break;
773
    case 0x26:/*LWR*/   //target=32-8*(ptr&3);
774
                        //r[rt]=(r[rt]&~((unsigned int)0xffffffff>>target))|
775
                        //((unsigned int)mem_read(s,4,ptr&~3)>>target);
776
                        break;
777
    case 0x28:/*SB*/    mem_write(s,1,ptr,r[rt],1);  break;
778
    case 0x29:/*SH*/    mem_write(s,2,ptr,r[rt],1);  break;
779
    case 0x2a:/*SWL*/   //mem_write(s,1,ptr,r[rt]>>24);
780
                        //mem_write(s,1,ptr+1,r[rt]>>16);
781
                        //mem_write(s,1,ptr+2,r[rt]>>8);
782
                        //mem_write(s,1,ptr+3,r[rt]); break;
783
    case 0x2b:/*SW*/    mem_write(s,4,ptr,r[rt],1);  break;
784
    case 0x2e:/*SWR*/   break; //FIXME
785
    case 0x2f:/*CACHE*/ break;
786
    case 0x30:/*LL*/    //r[rt]=mem_read(s,4,ptr);   break;
787
                        start_load(s, rt, mem_read(s,4,ptr,1));
788
                        break;
789 2 ja_rd
//      case 0x31:/*LWC1*/ break;
790
//      case 0x32:/*LWC2*/ break;
791
//      case 0x33:/*LWC3*/ break;
792
//      case 0x35:/*LDC1*/ break;
793
//      case 0x36:/*LDC2*/ break;
794
//      case 0x37:/*LDC3*/ break;
795
//      case 0x38:/*SC*/     *(int*)ptr=r[rt]; r[rt]=1; break;
796 31 ja_rd
    case 0x38:/*SC*/    mem_write(s,4,ptr,r[rt],1); r[rt]=1; break;
797 2 ja_rd
//      case 0x39:/*SWC1*/ break;
798
//      case 0x3a:/*SWC2*/ break;
799
//      case 0x3b:/*SWC3*/ break;
800
//      case 0x3d:/*SDC1*/ break;
801
//      case 0x3e:/*SDC2*/ break;
802
//      case 0x3f:/*SDC3*/ break;
803 31 ja_rd
    default:
804
        /* FIXME should trap unimplemented opcodes */
805
        printf("ERROR2 address=0x%x opcode=0x%x\n", s->pc, opcode);
806
        s->wakeup=1;
807
    }
808
    s->pc_next += (branch || lbranch == 1) ? imm_shift : 0;
809
    s->pc_next &= ~3;
810
    s->skip = (lbranch == 0) | skip2;
811 2 ja_rd
 
812 31 ja_rd
    /* If there was trouble (failed assertions), log it */
813
    if(s->failed_assertions!=0){
814
        log_failed_assertions(s);
815
        s->failed_assertions=0;
816
    }
817 5 ja_rd
 
818 31 ja_rd
    /* if there's a delayed load pending, do it now: load reg with memory data*/
819
    /* load delay slots not simulated */
820 2 ja_rd
 
821 31 ja_rd
    /* Handle exceptions */
822
   if(s->exceptionId){
823
        r[rt] = rSave;
824
        s->cp0_cause = (s->delay_slot & 0x1) << 31 | (trap_cause & 0x1f);
825
        /* adjust epc if we (i.e. the victim instruction) are in a delay slot */
826
        if(s->delay_slot){
827 27 ja_rd
        epc = epc - 4;
828 31 ja_rd
        }
829
        s->epc = epc;
830
        s->pc_next = 0x3c;
831
        s->skip = 1;
832
        s->exceptionId = 0;
833
        s->userMode = 0;
834
        //s->wakeup = 1;
835
    }
836 27 ja_rd
 
837 31 ja_rd
    /* if this instruction was any kind of branch that actually jumped, then
838
       the next instruction will be in a delay slot. Remember it. */
839
    delay_slot = ((lbranch==1) || branch || delay_slot);
840
    s->delay_slot = delay_slot;
841 2 ja_rd
}
842
 
843
/** Dump CPU state to console */
844 31 ja_rd
void show_state(t_state *s){
845
    int i,j;
846
    printf("pid=%d userMode=%d, epc=0x%x\n", s->processId, s->userMode, s->epc);
847
    printf("hi=0x%08x lo=0x%08x\n", s->hi, s->lo);
848
    for(i = 0; i < 4; ++i){
849
        printf("%2.2d ", i * 8);
850
        for(j = 0; j < 8; ++j){
851
            printf("%8.8x ", s->r[i*8+j]);
852
        }
853
        printf("\n");
854
    }
855
    //printf("%8.8lx %8.8lx %8.8lx %8.8lx\n", s->pc, s->pc_next, s->hi, s->lo);
856
    j = s->pc;
857
    for(i = -4; i <= 8; ++i){
858
        printf("%c", i==0 ? '*' : ' ');
859
        s->pc = j + i * 4;
860
        cycle(s, 10);
861
    }
862
    s->pc = j;
863 2 ja_rd
}
864
 
865
/** Show debug monitor prompt and execute user command */
866 31 ja_rd
void do_debug(t_state *s){
867
    int ch;
868
    int i, j=0, watch=0, addr;
869
    s->pc_next = s->pc + 4;
870
    s->skip = 0;
871
    s->wakeup = 0;
872
    show_state(s);
873
    ch = ' ';
874
    for(;;){
875
        if(ch != 'n'){
876
            if(watch){
877
                printf("0x%8.8x=0x%8.8x\n", watch, mem_read(s, 4, watch,0));
878 2 ja_rd
            }
879 31 ja_rd
            printf("1=Debug 2=t_trace 3=Step 4=BreakPt 5=Go 6=Memory ");
880
            printf("7=Watch 8=Jump 9=Quit A=dump > ");
881
        }
882
        ch = getch();
883
        if(ch != 'n'){
884
            printf("\n");
885
        }
886
        switch(ch){
887
        case 'a': case 'A':
888
            dump_trace_buffer(s); break;
889
        case '1': case 'd': case ' ':
890
            cycle(s, 0); show_state(s); break;
891
        case 'n':
892
            cycle(s, 1); break;
893
        case '2': case 't':
894
            cycle(s, 0); printf("*"); cycle(s, 10); break;
895
        case '3': case 's':
896
            printf("Count> ");
897
            scanf("%d", &j);
898
            for(i = 0; i < j; ++i){
899
                cycle(s, 1);
900
            }
901
            show_state(s);
902
            break;
903
        case '4': case 'b':
904
            printf("Line> ");
905
            scanf("%x", &j);
906
            printf("break point=0x%x\n", j);
907
            break;
908
        case '5': case 'g':
909
            s->wakeup = 0;
910 2 ja_rd
            cycle(s, 0);
911 31 ja_rd
            while(s->wakeup == 0){
912
                if(s->pc == j){
913
                    printf("\n\nStop: pc = 0x%08x\n\n", j);
914
                    break;
915
                }
916
                cycle(s, 0);
917
            }
918
            show_state(s);
919
            break;
920
        case 'G':
921
            s->wakeup = 0;
922 2 ja_rd
            cycle(s, 1);
923 31 ja_rd
            while(s->wakeup == 0){
924
                if(s->pc == j){
925
                    break;
926
                }
927
                cycle(s, 1);
928
            }
929
            show_state(s);
930
            break;
931
        case '6': case 'm':
932
            printf("Memory> ");
933
            scanf("%x", &j);
934
            for(i = 0; i < 8; ++i){
935
                printf("%8.8x ", mem_read(s, 4, j+i*4, 0));
936
            }
937
            printf("\n");
938
            break;
939
        case '7': case 'w':
940
            printf("Watch> ");
941
            scanf("%x", &watch);
942
            break;
943
        case '8': case 'j':
944
            printf("Jump> ");
945
            scanf("%x", &addr);
946
            s->pc = addr;
947
            s->pc_next = addr + 4;
948
            show_state(s);
949
            break;
950
        case '9': case 'q':
951
            return;
952
        }
953
    }
954 2 ja_rd
}
955
 
956
/** Read binary code and data files */
957 31 ja_rd
int read_program(t_state *s, uint32_t num_files, char **file_names){
958
    FILE *in;
959 44 ja_rd
    uint32_t bytes, i, files_read=0;
960 2 ja_rd
 
961 31 ja_rd
    for(i=0;i<NUM_MEM_BLOCKS;i++){
962
        if(i<num_files){
963
            in = fopen(file_names[i], "rb");
964
            if(in == NULL){
965 44 ja_rd
                free_cpu(s);
966 31 ja_rd
                printf("Can't open file %s, quitting!\n",file_names[i]);
967
                getch();
968
                return(2);
969
            }
970 2 ja_rd
 
971 31 ja_rd
            bytes = fread(s->blocks[i].mem, 1, s->blocks[i].size, in);
972
            fclose(in);
973
            printf("%-16s [size= %6d, start= 0x%08x]\n",
974
                    s->blocks[i].name,
975
                    bytes,
976
                    s->blocks[i].start);
977
            files_read++;
978
        }
979
        else{
980
            break;
981
        }
982
    }
983
 
984
    if(!files_read){
985 44 ja_rd
        free_cpu(s);
986 31 ja_rd
        printf("No binary object files read, quitting\n");
987 44 ja_rd
        return 0;
988 31 ja_rd
    }
989
 
990 44 ja_rd
    return files_read;
991 2 ja_rd
}
992
 
993
/*----------------------------------------------------------------------------*/
994
 
995 31 ja_rd
int main(int argc,char *argv[]){
996
    t_state state, *s=&state;
997 2 ja_rd
 
998 31 ja_rd
    printf("MIPS-I emulator\n");
999 44 ja_rd
    if(!init_cpu(s)){
1000
        printf("Trouble allocating memory, quitting!\n");
1001
        getch();
1002
        return 1;
1003
    };
1004 2 ja_rd
 
1005 31 ja_rd
    /* do a minimal check on args */
1006
    if(argc==3 || argc==2){
1007
        /* */
1008
    }
1009
    else{
1010
        printf("Usage:");
1011
        printf("    slite file.exe <bin code file> [<bin data file>]\n");
1012
        return 0;
1013
    }
1014 2 ja_rd
 
1015 44 ja_rd
    if(!read_program(s, argc-1, &(argv[1]))){
1016 31 ja_rd
        return 2;
1017
    }
1018 2 ja_rd
 
1019 31 ja_rd
    init_trace_buffer(s, "sw_sim_log.txt");
1020 2 ja_rd
 
1021 31 ja_rd
    /* NOTE: Original mlite supported loading little-endian code, which this
1022 2 ja_rd
      program doesn't. The endianess-conversion code has been removed.
1023 31 ja_rd
    */
1024 2 ja_rd
 
1025 31 ja_rd
    /* Simulate a CPU reset */
1026
    reset_cpu(s);
1027 2 ja_rd
 
1028 31 ja_rd
    /* Enter debug command interface; will only exit clean with user command */
1029
    do_debug(s);
1030 2 ja_rd
 
1031 31 ja_rd
    /* Close and deallocate everything and quit */
1032
    close_trace_buffer(s);
1033
    free_cpu(s);
1034
    return(0);
1035 2 ja_rd
}
1036
 
1037
/*----------------------------------------------------------------------------*/
1038
 
1039
 
1040 31 ja_rd
void init_trace_buffer(t_state *s, const char *log_file_name){
1041
    int i;
1042 2 ja_rd
 
1043
#if FILE_LOGGING_DISABLED
1044 31 ja_rd
    s->t.log = NULL;
1045
    return;
1046 2 ja_rd
#else
1047 31 ja_rd
    for(i=0;i<TRACE_BUFFER_SIZE;i++){
1048
        s->t.buf[i]=0xffffffff;
1049
    }
1050
    s->t.next = 0;
1051 2 ja_rd
 
1052 31 ja_rd
    /* if file logging is enabled, open log file */
1053
    if(log_file_name!=NULL){
1054
        s->t.log = fopen(log_file_name, "w");
1055
        if(s->t.log==NULL){
1056
            printf("Error opening log file '%s', file logging disabled\n",
1057
                    log_file_name);
1058
        }
1059
    }
1060
    else{
1061
        s->t.log = NULL;
1062
    }
1063 2 ja_rd
#endif
1064
}
1065
 
1066
/** Dumps last jump targets as a chunk of hex numbers (older is left top) */
1067 31 ja_rd
void dump_trace_buffer(t_state *s){
1068
    int i, col;
1069 2 ja_rd
 
1070 31 ja_rd
    for(i=0, col=0;i<TRACE_BUFFER_SIZE;i++, col++){
1071
        printf("%08x ", s->t.buf[s->t.next + i]);
1072
        if((col % 8)==7){
1073
            printf("\n");
1074
        }
1075
    }
1076 2 ja_rd
}
1077
 
1078
/** Logs last cycle's activity (changes in state and/or loads/stores) */
1079 31 ja_rd
void log_cycle(t_state *s){
1080
    static unsigned int last_pc = 0;
1081
    int i;
1082 2 ja_rd
 
1083 31 ja_rd
    /* store PC in trace buffer only if there was a jump */
1084
    if(s->pc != (last_pc+4)){
1085
        s->t.buf[s->t.next] = s->pc;
1086
        s->t.next = (s->t.next + 1) % TRACE_BUFFER_SIZE;
1087
    }
1088
    last_pc = s->pc;
1089 2 ja_rd
 
1090 31 ja_rd
    /* if file logging is enabled, dump a trace log to file */
1091
    if(s->t.log!=NULL){
1092
        for(i=0;i<32;i++){
1093
            if(s->t.pr[i] != s->r[i]){
1094
                fprintf(s->t.log, "(%08X) [%02X]=%08X\n", s->pc, i, s->r[i]);
1095
            }
1096
            s->t.pr[i] = s->r[i];
1097
        }
1098
        if(s->lo != s->t.lo){
1099
            fprintf(s->t.log, "(%08X) [LO]=%08X\n", s->pc, s->lo);
1100
        }
1101
        s->t.lo = s->lo;
1102 2 ja_rd
 
1103 31 ja_rd
        if(s->hi != s->t.hi){
1104
            fprintf(s->t.log, "(%08X) [HI]=%08X\n", s->pc, s->hi);
1105
        }
1106
        s->t.hi = s->hi;
1107 2 ja_rd
 
1108 31 ja_rd
        if(s->epc != s->t.epc){
1109
            fprintf(s->t.log, "(%08X) [EP]=%08X\n", s->pc, s->epc);
1110
        }
1111
        s->t.epc = s->epc;
1112
    }
1113 2 ja_rd
}
1114
 
1115
/** Frees debug buffers and closes log file */
1116 31 ja_rd
void close_trace_buffer(t_state *s){
1117
    if(s->t.log){
1118
        fclose(s->t.log);
1119
    }
1120 2 ja_rd
}
1121 5 ja_rd
 
1122
/** Logs a message for each failed assertion, each in a line */
1123 31 ja_rd
void log_failed_assertions(t_state *s){
1124
    unsigned bitmap = s->failed_assertions;
1125
    int i = 0;
1126 5 ja_rd
 
1127 31 ja_rd
    /* This loop will crash the program if the message table is too short...*/
1128
    if(s->t.log != NULL){
1129
        for(i=0;i<32;i++){
1130
            if(bitmap & 0x1){
1131
                fprintf(s->t.log, "ASSERTION FAILED: [%08x] %s\n",
1132
                        s->faulty_address,
1133
                        assertion_messages[i]);
1134
            }
1135
            bitmap = bitmap >> 1;
1136
        }
1137
    }
1138 5 ja_rd
}
1139 31 ja_rd
 
1140
void free_cpu(t_state *s){
1141
    int i;
1142
 
1143
    for(i=0;i<NUM_MEM_BLOCKS;i++){
1144
        free(s->blocks[i].mem);
1145
        s->blocks[i].mem = NULL;
1146
 
1147
    }
1148
}
1149
 
1150
void reset_cpu(t_state *s){
1151
    s->pc = VECTOR_RESET;     /* reset start vector */
1152
    s->delay_slot = 0;
1153
    s->failed_assertions = 0; /* no failed assertions pending */
1154
}
1155
 
1156 44 ja_rd
int init_cpu(t_state *s){
1157
    int i, j;
1158
 
1159 31 ja_rd
    memset(s, 0, sizeof(t_state));
1160
    s->big_endian = 1;
1161
    for(i=0;i<NUM_MEM_BLOCKS;i++){
1162
        s->blocks[i].start =  default_blocks[i].start;
1163
        s->blocks[i].size =  default_blocks[i].size;
1164
        s->blocks[i].name =  default_blocks[i].name;
1165 44 ja_rd
        s->blocks[i].mask =  default_blocks[i].mask;
1166
 
1167
        s->blocks[i].mem = (unsigned char*)malloc(s->blocks[i].size);
1168
 
1169
        if(s->blocks[i].mem == NULL){
1170
            for(j=0;j<i;j++){
1171
                free(s->blocks[j].mem);
1172
            }
1173
            return 0;
1174
        }
1175
        memset(s->blocks[i].mem, 0, s->blocks[i].size);
1176 31 ja_rd
    }
1177 44 ja_rd
    return NUM_MEM_BLOCKS;
1178 31 ja_rd
}

powered by: WebSVN 2.1.0

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