URL
https://opencores.org/ocsvn/eco32/eco32/trunk
Subversion Repositories eco32
Compare Revisions
- This comparison shows the changes necessary to convert path
/eco32
- from Rev 274 to Rev 275
- ↔ Reverse comparison
Rev 274 → Rev 275
/trunk/sim/trace.c
0,0 → 1,187
/* |
* trace.c -- trace buffer |
*/ |
|
|
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <setjmp.h> |
|
#include "common.h" |
#include "console.h" |
#include "error.h" |
#include "except.h" |
#include "disasm.h" |
#include "trace.h" |
|
|
#define TRACE_EMPTY 0 |
#define TRACE_FETCH 1 |
#define TRACE_EXEC 2 |
#define TRACE_LOAD_WORD 3 |
#define TRACE_LOAD_HALF 4 |
#define TRACE_LOAD_BYTE 5 |
#define TRACE_STORE_WORD 6 |
#define TRACE_STORE_HALF 7 |
#define TRACE_STORE_BYTE 8 |
#define TRACE_EXCEPTION 9 |
|
|
typedef struct { |
unsigned char type; |
Word data1; |
Word data2; |
} TraceEntry; |
|
|
static TraceEntry traceBuffer[TRACE_BUF_SIZE]; |
static int nextWrite; |
|
|
/**************************************************************/ |
|
|
void traceFetch(Word pc) { |
traceBuffer[nextWrite].type = TRACE_FETCH; |
traceBuffer[nextWrite].data1 = pc; |
nextWrite = (nextWrite + 1) & TRACE_BUF_MASK; |
} |
|
|
void traceExec(Word instr, Word locus) { |
traceBuffer[nextWrite].type = TRACE_EXEC; |
traceBuffer[nextWrite].data1 = instr; |
traceBuffer[nextWrite].data2 = locus; |
nextWrite = (nextWrite + 1) & TRACE_BUF_MASK; |
} |
|
|
void traceLoadWord(Word addr) { |
traceBuffer[nextWrite].type = TRACE_LOAD_WORD; |
traceBuffer[nextWrite].data1 = addr; |
nextWrite = (nextWrite + 1) & TRACE_BUF_MASK; |
} |
|
|
void traceLoadHalf(Word addr) { |
traceBuffer[nextWrite].type = TRACE_LOAD_HALF; |
traceBuffer[nextWrite].data1 = addr; |
nextWrite = (nextWrite + 1) & TRACE_BUF_MASK; |
} |
|
|
void traceLoadByte(Word addr) { |
traceBuffer[nextWrite].type = TRACE_LOAD_BYTE; |
traceBuffer[nextWrite].data1 = addr; |
nextWrite = (nextWrite + 1) & TRACE_BUF_MASK; |
} |
|
|
void traceStoreWord(Word addr) { |
traceBuffer[nextWrite].type = TRACE_STORE_WORD; |
traceBuffer[nextWrite].data1 = addr; |
nextWrite = (nextWrite + 1) & TRACE_BUF_MASK; |
} |
|
|
void traceStoreHalf(Word addr) { |
traceBuffer[nextWrite].type = TRACE_STORE_HALF; |
traceBuffer[nextWrite].data1 = addr; |
nextWrite = (nextWrite + 1) & TRACE_BUF_MASK; |
} |
|
|
void traceStoreByte(Word addr) { |
traceBuffer[nextWrite].type = TRACE_STORE_BYTE; |
traceBuffer[nextWrite].data1 = addr; |
nextWrite = (nextWrite + 1) & TRACE_BUF_MASK; |
} |
|
|
void traceException(Word priority) { |
traceBuffer[nextWrite].type = TRACE_EXCEPTION; |
traceBuffer[nextWrite].data1 = priority; |
nextWrite = (nextWrite + 1) & TRACE_BUF_MASK; |
} |
|
|
char *traceShow(int back) { |
static char answer[100]; |
int index; |
|
if (back < 1 || back > TRACE_BUF_SIZE) { |
return NULL; |
} |
index = (nextWrite - back) & TRACE_BUF_MASK; |
switch (traceBuffer[index].type) { |
case TRACE_EMPTY: |
sprintf(answer, "-- empty --"); |
break; |
case TRACE_FETCH: |
sprintf(answer, "instr fetch, addr = %08X", |
traceBuffer[index].data1); |
break; |
case TRACE_EXEC: |
sprintf(answer, "instr exec, instr = %08X %s", |
traceBuffer[index].data1, |
disasm(traceBuffer[index].data1, |
traceBuffer[index].data2)); |
break; |
case TRACE_LOAD_WORD: |
sprintf(answer, "load word, addr = %08X", |
traceBuffer[index].data1); |
break; |
case TRACE_LOAD_HALF: |
sprintf(answer, "load half, addr = %08X", |
traceBuffer[index].data1); |
break; |
case TRACE_LOAD_BYTE: |
sprintf(answer, "load byte, addr = %08X", |
traceBuffer[index].data1); |
break; |
case TRACE_STORE_WORD: |
sprintf(answer, "store word, addr = %08X", |
traceBuffer[index].data1); |
break; |
case TRACE_STORE_HALF: |
sprintf(answer, "store half, addr = %08X", |
traceBuffer[index].data1); |
break; |
case TRACE_STORE_BYTE: |
sprintf(answer, "store byte, addr = %08X", |
traceBuffer[index].data1); |
break; |
case TRACE_EXCEPTION: |
sprintf(answer, "**** exception %2d (%s) ****", |
traceBuffer[index].data1, |
exceptionToString(traceBuffer[index].data1)); |
break; |
default: |
error("unknown trace buffer entry"); |
} |
return answer; |
} |
|
|
/**************************************************************/ |
|
|
void traceReset(void) { |
int i; |
|
cPrintf("Resetting Trace Buffer...\n"); |
for (i = 0; i < TRACE_BUF_SIZE; i++) { |
traceBuffer[i].type = TRACE_EMPTY; |
} |
nextWrite = 0; |
} |
|
|
void traceInit(void) { |
traceReset(); |
} |
|
|
void traceExit(void) { |
} |
/trunk/sim/trace.h
0,0 → 1,31
/* |
* trace.h -- trace buffer |
*/ |
|
|
#ifndef _TRACE_H_ |
#define _TRACE_H_ |
|
|
#define TRACE_BUF_ADDR 12 |
#define TRACE_BUF_SIZE (1 << TRACE_BUF_ADDR) |
#define TRACE_BUF_MASK (TRACE_BUF_SIZE - 1) |
|
|
void traceFetch(Word pc); |
void traceExec(Word instr, Word locus); |
void traceLoadWord(Word addr); |
void traceLoadHalf(Word addr); |
void traceLoadByte(Word addr); |
void traceStoreWord(Word addr); |
void traceStoreHalf(Word addr); |
void traceStoreByte(Word addr); |
void traceException(Word priority); |
char *traceShow(int back); |
|
void traceReset(void); |
void traceInit(void); |
void traceExit(void); |
|
|
#endif /* _TRACE_H_ */ |
/trunk/sim/cpu.c
14,6 → 14,7
#include "except.h" |
#include "instr.h" |
#include "cpu.h" |
#include "trace.h" |
#include "mmu.h" |
#include "timer.h" |
|
88,6 → 89,7
} |
/* acknowledge exception, or interrupt if enabled */ |
if (priority >= 16 || IE != 0) { |
traceException(priority); |
if (priority >= 16) { |
/* clear corresponding bit in irqPending vector */ |
/* only done for exceptions, since interrupts are level-sensitive */ |
150,11 → 152,14
int scnt; |
Word smsk; |
Word aux; |
Word addr; |
|
/* count the instruction */ |
total++; |
/* fetch the instruction */ |
traceFetch(pc); |
instr = mmuReadWord(pc, UM); |
traceExec(instr, pc); |
/* decode the instruction */ |
op = (instr >> 26) & 0x3F; |
reg1 = (instr >> 21) & 0x1F; |
385,30 → 390,44
next = RR(30); |
break; |
case OP_LDW: |
WR(reg2, mmuReadWord(RR(reg1) + SEXT16(immed), UM)); |
addr = RR(reg1) + SEXT16(immed); |
traceLoadWord(addr); |
WR(reg2, mmuReadWord(addr, UM)); |
break; |
case OP_LDH: |
WR(reg2, (signed int) (signed short) |
mmuReadHalf(RR(reg1) + SEXT16(immed), UM)); |
addr = RR(reg1) + SEXT16(immed); |
traceLoadHalf(addr); |
WR(reg2, (signed int) (signed short) mmuReadHalf(addr, UM)); |
break; |
case OP_LDHU: |
WR(reg2, mmuReadHalf(RR(reg1) + SEXT16(immed), UM)); |
addr = RR(reg1) + SEXT16(immed); |
traceLoadHalf(addr); |
WR(reg2, mmuReadHalf(addr, UM)); |
break; |
case OP_LDB: |
WR(reg2, (signed int) (signed char) |
mmuReadByte(RR(reg1) + SEXT16(immed), UM)); |
addr = RR(reg1) + SEXT16(immed); |
traceLoadByte(addr); |
WR(reg2, (signed int) (signed char) mmuReadByte(addr, UM)); |
break; |
case OP_LDBU: |
WR(reg2, mmuReadByte(RR(reg1) + SEXT16(immed), UM)); |
addr = RR(reg1) + SEXT16(immed); |
traceLoadByte(addr); |
WR(reg2, mmuReadByte(addr, UM)); |
break; |
case OP_STW: |
mmuWriteWord(RR(reg1) + SEXT16(immed), RR(reg2), UM); |
addr = RR(reg1) + SEXT16(immed); |
traceStoreWord(addr); |
mmuWriteWord(addr, RR(reg2), UM); |
break; |
case OP_STH: |
mmuWriteHalf(RR(reg1) + SEXT16(immed), RR(reg2), UM); |
addr = RR(reg1) + SEXT16(immed); |
traceStoreHalf(addr); |
mmuWriteHalf(addr, RR(reg2), UM); |
break; |
case OP_STB: |
mmuWriteByte(RR(reg1) + SEXT16(immed), RR(reg2), UM); |
addr = RR(reg1) + SEXT16(immed); |
traceStoreByte(addr); |
mmuWriteByte(addr, RR(reg2), UM); |
break; |
case OP_MVFS: |
switch (immed) { |
/trunk/sim/except.c
42,3 → 42,48
} |
currentEnvironment--; |
} |
|
|
static char *cause[32] = { |
/* 0 */ "serial line 0 xmt interrupt", |
/* 1 */ "serial line 0 rcv interrupt", |
/* 2 */ "serial line 1 xmt interrupt", |
/* 3 */ "serial line 1 rcv interrupt", |
/* 4 */ "keyboard interrupt", |
/* 5 */ "unknown interrupt", |
/* 6 */ "unknown interrupt", |
/* 7 */ "unknown interrupt", |
/* 8 */ "disk interrupt", |
/* 9 */ "unknown interrupt", |
/* 10 */ "unknown interrupt", |
/* 11 */ "unknown interrupt", |
/* 12 */ "unknown interrupt", |
/* 13 */ "unknown interrupt", |
/* 14 */ "timer 0 interrupt", |
/* 15 */ "timer 1 interrupt", |
/* 16 */ "bus timeout exception", |
/* 17 */ "illegal instruction exception", |
/* 18 */ "privileged instruction exception", |
/* 19 */ "divide instruction exception", |
/* 20 */ "trap instruction exception", |
/* 21 */ "TLB miss exception", |
/* 22 */ "TLB write exception", |
/* 23 */ "TLB invalid exception", |
/* 24 */ "illegal address exception", |
/* 25 */ "privileged address exception", |
/* 26 */ "unknown exception", |
/* 27 */ "unknown exception", |
/* 28 */ "unknown exception", |
/* 29 */ "unknown exception", |
/* 30 */ "unknown exception", |
/* 31 */ "unknown exception" |
}; |
|
|
char *exceptionToString(int exception) { |
if (exception < 0 || |
exception >= sizeof(cause)/sizeof(cause[0])) { |
error("exception number out of bounds"); |
} |
return cause[exception]; |
} |
/trunk/sim/error.c
12,6 → 12,7
#include "console.h" |
#include "error.h" |
#include "cpu.h" |
#include "trace.h" |
#include "mmu.h" |
#include "memory.h" |
#include "timer.h" |
27,6 → 28,7
va_list ap; |
|
cpuExit(); |
traceExit(); |
mmuExit(); |
memoryExit(); |
timerExit(); |
/trunk/sim/Makefile
10,9 → 10,9
LDLIBS = -lgetline -lX11 -lpthread -lm |
|
SRCS = main.c console.c error.c except.c command.c \ |
instr.c asm.c disasm.c cpu.c mmu.c memory.c \ |
timer.c dspkbd.c serial.c disk.c output.c \ |
shutdown.c graph.c |
instr.c asm.c disasm.c cpu.c trace.c mmu.c \ |
memory.c timer.c dspkbd.c serial.c disk.c \ |
output.c shutdown.c graph.c |
OBJS = $(patsubst %.c,%.o,$(SRCS)) |
BIN = sim |
|
/trunk/sim/except.h
22,6 → 22,7
void throwException(int exception); |
void pushEnvironment(jmp_buf *environment); |
void popEnvironment(void); |
char *exceptionToString(int exception); |
|
|
#endif /* _EXCEPT_H_ */ |
/trunk/sim/shutdown.c
11,6 → 11,7
#include "console.h" |
#include "error.h" |
#include "cpu.h" |
#include "trace.h" |
#include "mmu.h" |
#include "memory.h" |
#include "timer.h" |
31,6 → 32,7
void shutdownWrite(Word addr, Word data) { |
/* the device supports a single function: exiting the simulator */ |
cpuExit(); |
traceExit(); |
mmuExit(); |
memoryExit(); |
timerExit(); |
/trunk/sim/command.c
16,6 → 16,7
#include "asm.h" |
#include "disasm.h" |
#include "cpu.h" |
#include "trace.h" |
#include "mmu.h" |
#include "memory.h" |
#include "timer.h" |
60,6 → 61,7
cPrintf(" mh show/set memory halfword\n"); |
cPrintf(" mb show/set memory byte\n"); |
cPrintf(" t show/set TLB contents\n"); |
cPrintf(" l list trace buffer\n"); |
cPrintf(" i initialize hardware\n"); |
cPrintf(" q quit simulator\n"); |
cPrintf("type 'help <cmd>' to get help for <cmd>\n"); |
164,57 → 166,19
|
|
static void help15(void) { |
cPrintf(" i initialize hardware\n"); |
cPrintf(" l list 16 trace entries starting at -16\n"); |
cPrintf(" l <i> list 16 trace entries starting at <i>\n"); |
cPrintf(" l <i> <cnt> list <cnt> trace entries starting at <i>\n"); |
} |
|
|
static void help16(void) { |
cPrintf(" q quit simulator\n"); |
cPrintf(" i initialize hardware\n"); |
} |
|
|
static char *cause[32] = { |
/* 0 */ "serial line 0 xmt interrupt", |
/* 1 */ "serial line 0 rcv interrupt", |
/* 2 */ "serial line 1 xmt interrupt", |
/* 3 */ "serial line 1 rcv interrupt", |
/* 4 */ "keyboard interrupt", |
/* 5 */ "unknown interrupt", |
/* 6 */ "unknown interrupt", |
/* 7 */ "unknown interrupt", |
/* 8 */ "disk interrupt", |
/* 9 */ "unknown interrupt", |
/* 10 */ "unknown interrupt", |
/* 11 */ "unknown interrupt", |
/* 12 */ "unknown interrupt", |
/* 13 */ "unknown interrupt", |
/* 14 */ "timer 0 interrupt", |
/* 15 */ "timer 1 interrupt", |
/* 16 */ "bus timeout exception", |
/* 17 */ "illegal instruction exception", |
/* 18 */ "privileged instruction exception", |
/* 19 */ "divide instruction exception", |
/* 20 */ "trap instruction exception", |
/* 21 */ "TLB miss exception", |
/* 22 */ "TLB write exception", |
/* 23 */ "TLB invalid exception", |
/* 24 */ "illegal address exception", |
/* 25 */ "privileged address exception", |
/* 26 */ "unknown exception", |
/* 27 */ "unknown exception", |
/* 28 */ "unknown exception", |
/* 29 */ "unknown exception", |
/* 30 */ "unknown exception", |
/* 31 */ "unknown exception" |
}; |
|
|
static char *exceptionToString(int exception) { |
if (exception < 0 || |
exception >= sizeof(cause)/sizeof(cause[0])) { |
error("exception number out of bounds"); |
} |
return cause[exception]; |
static void help17(void) { |
cPrintf(" q quit simulator\n"); |
} |
|
|
850,6 → 814,47
} |
|
|
static void doList(char *tokens[], int n) { |
int start, count, stop; |
int back; |
|
if (n == 1) { |
start = 16; |
count = 16; |
} else if (n == 2) { |
if (!getDecNumber(tokens[1], &start) || start >= 0) { |
cPrintf("illegal trace buffer index (must be < 0)\n"); |
return; |
} |
start = -start; |
count = 16; |
} else if (n == 3) { |
if (!getDecNumber(tokens[1], &start) || start >= 0) { |
cPrintf("illegal trace buffer index (must be < 0)\n"); |
return; |
} |
start = -start; |
if (!getDecNumber(tokens[2], &count) || count <= 0) { |
cPrintf("illegal trace buffer count (must be > 0)\n"); |
return; |
} |
} else { |
help15(); |
return; |
} |
if (start > TRACE_BUF_SIZE) { |
start = TRACE_BUF_SIZE; |
} |
stop = start - count; |
if (stop < 0) { |
stop = 0; |
} |
for (back = start; back > stop; back--) { |
cPrintf("trace[%5d]: %s\n", -back, traceShow(back)); |
} |
} |
|
|
static void doInit(char *tokens[], int n) { |
if (n == 1) { |
timerReset(); |
864,7 → 869,7
mmuReset(); |
cpuReset(); |
} else { |
help15(); |
help16(); |
} |
} |
|
873,7 → 878,7
if (n == 1) { |
quit = true; |
} else { |
help16(); |
help17(); |
} |
} |
|
894,8 → 899,9
{ "mh", help12, doMemoryHalf }, |
{ "mb", help13, doMemoryByte }, |
{ "t", help14, doTLB }, |
{ "i", help15, doInit }, |
{ "q", help16, doQuit }, |
{ "l", help15, doList }, |
{ "i", help16, doInit }, |
{ "q", help17, doQuit }, |
}; |
|
int numCommands = sizeof(commands) / sizeof(commands[0]); |
/trunk/sim/main.c
13,6 → 13,7
#include "command.h" |
#include "instr.h" |
#include "cpu.h" |
#include "trace.h" |
#include "mmu.h" |
#include "memory.h" |
#include "timer.h" |
197,6 → 198,7
} |
memoryInit(memSize * M, progName, loadAddr, romName); |
mmuInit(); |
traceInit(); |
if (progName != NULL) { |
initialPC = 0xC0000000 | loadAddr; |
} else { |
220,6 → 222,7
} |
} |
cpuExit(); |
traceExit(); |
mmuExit(); |
memoryExit(); |
timerExit(); |