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

Subversion Repositories ion

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

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

powered by: WebSVN 2.1.0

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