Line 275... |
Line 275... |
/* FIXME Refactor HW system params */
|
/* FIXME Refactor HW system params */
|
|
|
#define DBG_REGS (0x20010000)
|
#define DBG_REGS (0x20010000)
|
#define UART_WRITE (0x20000000)
|
#define UART_WRITE (0x20000000)
|
#define UART_READ (0x20000000)
|
#define UART_READ (0x20000000)
|
|
#define UART_STATUS (0x20000004)
|
#define TIMER_READ (0x20000100)
|
#define TIMER_READ (0x20000100)
|
|
|
#define DEFAULT_TIMER_PRESCALER (50)
|
#define DEFAULT_TIMER_PRESCALER (50)
|
|
|
/* FIXME The following addresses are remnants of Plasma to be removed */
|
/* FIXME The following addresses are remnants of Plasma to be removed */
|
Line 287... |
Line 288... |
#define CONFIG_REG 0x20000070
|
#define CONFIG_REG 0x20000070
|
#define MMU_PROCESS_ID 0x20000080
|
#define MMU_PROCESS_ID 0x20000080
|
#define MMU_FAULT_ADDR 0x20000090
|
#define MMU_FAULT_ADDR 0x20000090
|
#define MMU_TLB 0x200000a0
|
#define MMU_TLB 0x200000a0
|
|
|
#define IRQ_UART_READ_AVAILABLE 0x001
|
#define IRQ_UART_READ_AVAILABLE 0x002
|
#define IRQ_UART_WRITE_AVAILABLE 0x002
|
#define IRQ_UART_WRITE_AVAILABLE 0x001
|
#define IRQ_COUNTER18_NOT 0x004
|
#define IRQ_COUNTER18_NOT 0x004
|
#define IRQ_COUNTER18 0x008
|
#define IRQ_COUNTER18 0x008
|
#define IRQ_MMU 0x200
|
#define IRQ_MMU 0x200
|
|
|
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
Line 332... |
Line 333... |
uint32_t breakpoint; /**< BP address of 0xffffffff */
|
uint32_t breakpoint; /**< BP address of 0xffffffff */
|
|
|
int delay_slot; /**< !=0 if prev. instruction was a branch */
|
int delay_slot; /**< !=0 if prev. instruction was a branch */
|
uint32_t instruction_ctr; /**< # of instructions executed since reset */
|
uint32_t instruction_ctr; /**< # of instructions executed since reset */
|
uint32_t inst_ctr_prescaler; /**< Prescaler counter for instruction ctr. */
|
uint32_t inst_ctr_prescaler; /**< Prescaler counter for instruction ctr. */
|
|
uint32_t debug_regs[16]; /**< Rd/wr debug registers */
|
|
|
int r[32];
|
int r[32];
|
int opcode;
|
int opcode;
|
int pc, pc_next, epc;
|
int pc, pc_next, epc;
|
uint32_t op_addr; /**< address of opcode being simulated */
|
uint32_t op_addr; /**< address of opcode being simulated */
|
Line 451... |
Line 453... |
|
|
/* Hardware simulation */
|
/* Hardware simulation */
|
int mem_read(t_state *s, int size, unsigned int address, int log);
|
int mem_read(t_state *s, int size, unsigned int address, int log);
|
void mem_write(t_state *s, int size, unsigned address, unsigned value, int log);
|
void mem_write(t_state *s, int size, unsigned address, unsigned value, int log);
|
void debug_reg_write(t_state *s, uint32_t address, uint32_t data);
|
void debug_reg_write(t_state *s, uint32_t address, uint32_t data);
|
|
int debug_reg_read(t_state *s, int size, unsigned int address);
|
void start_load(t_state *s, uint32_t addr, int rt, int data);
|
void start_load(t_state *s, uint32_t addr, int rt, int data);
|
uint32_t simulate_hw_irqs(t_state *s);
|
uint32_t simulate_hw_irqs(t_state *s);
|
|
|
|
|
/*---- Local functions -------------------------------------------------------*/
|
/*---- Local functions -------------------------------------------------------*/
|
Line 532... |
Line 535... |
/** Read memory, optionally logging */
|
/** Read memory, optionally logging */
|
int mem_read(t_state *s, int size, unsigned int address, int log){
|
int mem_read(t_state *s, int size, unsigned int address, int log){
|
unsigned int value=0, word_value=0, i, ptr;
|
unsigned int value=0, word_value=0, i, ptr;
|
unsigned int full_address = address;
|
unsigned int full_address = address;
|
|
|
|
/* Handle access to debug register block */
|
|
if((address&0xffff0000)==(DBG_REGS&0xffff0000)){
|
|
return debug_reg_read(s, size, address);
|
|
}
|
|
|
s->irqStatus |= IRQ_UART_WRITE_AVAILABLE;
|
s->irqStatus |= IRQ_UART_WRITE_AVAILABLE;
|
switch(address){
|
switch(address){
|
case UART_READ:
|
case UART_READ:
|
/* FIXME Take input from text file */
|
/* FIXME Take input from text file */
|
|
/* Wait for incoming character */
|
while(!kbhit());
|
while(!kbhit());
|
HWMemory[0] = getch();
|
HWMemory[0] = getch();
|
//s->irqStatus &= ~IRQ_UART_READ_AVAILABLE; //clear bit
|
//s->irqStatus &= ~IRQ_UART_READ_AVAILABLE; //clear bit
|
printf("%c", HWMemory[0]);
|
printf("%c", HWMemory[0]);
|
return (HWMemory[0] << 24) | 0x03;
|
return HWMemory[0];
|
|
case UART_STATUS:
|
|
/* Hardcoded status bits: tx and rx available */
|
|
return IRQ_UART_WRITE_AVAILABLE | IRQ_UART_READ_AVAILABLE;
|
case TIMER_READ:
|
case TIMER_READ:
|
printf("TIMER = %10d\n", s->instruction_ctr);
|
printf("TIMER = %10d\n", s->instruction_ctr);
|
return s->instruction_ctr;
|
return s->instruction_ctr;
|
break;
|
break;
|
case IRQ_MASK:
|
case IRQ_MASK:
|
Line 634... |
Line 646... |
|
|
//log_read(s, full_address, value, size, log);
|
//log_read(s, full_address, value, size, log);
|
return(value);
|
return(value);
|
}
|
}
|
|
|
|
int debug_reg_read(t_state *s, int size, unsigned int address){
|
|
/* FIXME should mirror debug registers 0..3 */
|
|
return s->debug_regs[(address >> 2)&0x0f];
|
|
}
|
|
|
|
|
/** Write to debug register */
|
/** Write to debug register */
|
void debug_reg_write(t_state *s, uint32_t address, uint32_t data){
|
void debug_reg_write(t_state *s, uint32_t address, uint32_t data){
|
|
|
if((address>= 0x0000f000) && (address < 0x0000f008)){
|
if((address>= 0x0000f000) && (address < 0x0000f008)){
|
/* HW interrupt trigger register */
|
/* HW interrupt trigger register */
|
Line 645... |
Line 663... |
printf("DEBUG REG[%04x]=%08x\n", address & 0xffff, data);
|
printf("DEBUG REG[%04x]=%08x\n", address & 0xffff, data);
|
}
|
}
|
else{
|
else{
|
/* all other registers are used for display (like LEDs) */
|
/* all other registers are used for display (like LEDs) */
|
printf("DEBUG REG[%04x]=%08x\n", address & 0xffff, data);
|
printf("DEBUG REG[%04x]=%08x\n", address & 0xffff, data);
|
|
s->debug_regs[(address >> 2)&0x0f] = data;
|
}
|
}
|
}
|
}
|
|
|
/** Write to memory, including simulated i/o */
|
/** Write to memory, including simulated i/o */
|
void mem_write(t_state *s, int size, unsigned address, unsigned value, int log){
|
void mem_write(t_state *s, int size, unsigned address, unsigned value, int log){
|