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

Subversion Repositories or1k

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 138 to Rev 139
    Reverse comparison

Rev 138 → Rev 139

/trunk/or1ksim/cpu/or1k/sprs.c
26,6 → 26,7
 
extern int cont_run; /* defined in toplevel.c */
extern int tt_stopped; /* defined in tick.c */
extern int GlobalMode; /* CZ 21/06/01 */
 
static sprword sprs[MAX_SPRS];
 
66,9 → 67,41
printf("MTSPR(0x1234, %x);\n", value);
break;
}
 
/* What the hell is happening here? This looks like a bug
waiting to happen. Assume regno = 2*MAX_SPRS_PER_GRP+3,
which presumably means I want to set register 3 in
group 2. Instead, I calculate ofs as 3, and regno as
2, and get a final value of 5??? Is this correct?
Oh well...I didn't write this. Who knows what it is
actually supposed to do. It doesn't matter if regno
is less than MAX_SPRS_PER_GRP, which is the only
way I use it. CZ - 21/06/01
*/
 
regno /= MAX_SPRS_PER_GRP;
regno += ofs;
/* CZ 21/06/01 ... the debugger wants to do this! */
if(GlobalMode)
{
extern unsigned long pc;
 
if(regno == SPR_PC)
{
sprs[SPR_PC] = value;
#if 0
/* There is currently a problem with symbol tables by
gdb. It doesn't properly set up the CPU. We'll ignore
this for now. */
pc = value;
pc_phy = simulate_ic_mmu_fetch(pc);
pcnext = pc+4;
#endif
return;
}
}
 
/* printf("mtspr(%x, %x)\n", regno, value);
*/ if (regno < MAX_SPRS)
sprs[regno] = value;
86,6 → 119,15
regno /= MAX_SPRS_PER_GRP;
regno += ofs;
/* CZ 21/06/01 ... the debugger wants to do this! */
if(GlobalMode)
{
extern unsigned long pc;
 
if(regno == SPR_PC)
return pc;
}
 
/* MM: l.rfe, for example, temporarly disables
exceptions. We will make it appear as SR bit
is set. */
/trunk/or1ksim/cpu/or1k/except.c
25,6 → 25,8
#include "except.h"
#include "sprs.h"
 
static void except_handle_backend(int,unsigned long,unsigned long);
 
extern int cont_run;
extern struct iqueue_entry iqueue[20];
extern unsigned long pc;
35,15 → 37,99
extern int delay_insn;
int cycle_delay = 0; /* Added by CZ 27/05/01 */
 
static struct {
int valid;
int type;
unsigned long address;
unsigned long saved;
} pending;
 
void ClearPendingException()
{
if(pending.valid && pending.type != EXCEPT_RESET)
{
pending.valid = 0;
pending.type = 0;
pending.address = 0;
pending.saved = 0;
}
}
 
/* The delayed_pc and delayed_pcnext are fields which hold
the original value of the PC across breakpoint exceptions
in the case of a development interface. Due to an implementation
issues, DIR injected instructions can modify these values
when in fact they should not. So we save and restore them
later on. */
static unsigned long delayed_pc = 0;
static unsigned long delayed_pcnext = 0;
static int delayed_pc_valid = 0;
 
void PrepareExceptionPC(unsigned long t_pc,unsigned long t_pcnext)
{
/* If a real exception occurred which has stalled
the CPU, we are expecting to halt before the end
of the instruction. Otherwise, if it is a single
step that has caused the halt, we are expected to
complete the entire instruction and stop after
it is finished. */
 
if(pending.valid)
{
delayed_pc = t_pc;
delayed_pcnext = t_pcnext;
delayed_pc_valid = 1;
}
else
_execute_update_pc(t_pc,t_pcnext);
}
 
void PrepareException()
{
if(delayed_pc_valid)
{
pc = delayed_pc;
pcnext = delayed_pcnext;
pc_phy = simulate_ic_mmu_fetch(pc);
if ((pc_phy < MEMORY_START) || (pc_phy > MEMORY_START + MEMORY_LEN))
except_handle(EXCEPT_BUSERR, pc);
delayed_pc_valid = delayed_pc = delayed_pcnext = 0;
}
 
if(pending.valid)
except_handle_backend(pending.type,pending.address,pending.saved);
}
 
/* Handle OR1K exceptions. */
void except_handle(int except, unsigned long ea)
{
unsigned long pc_saved;
printf("Exception 0x%x (%s): ", except, EXCEPT_NAME(except));
printf("Iqueue[0].insn_addr: 0x%x Eff ADDR: 0x%x\n", iqueue[0].insn_addr, ea);
printf(" pc: 0x%x pcnext: 0x%x\n", pc, pcnext);
 
printf("Exception 0x%x (%s): ", except, EXCEPT_NAME(except));
printf("Iqueue[0].insn_addr: 0x%x Eff ADDR: 0x%x\n", iqueue[0].insn_addr, ea);
printf(" pc: 0x%x pcnext: 0x%x\n", pc, pcnext);
pending.valid = 1;
pending.type = except;
pending.address = ea;
pending.saved = pc;
 
if(DebugCheckException(except))
{
pending.valid = 0;
pending.type = 0;
pending.address = 0;
pending.saved = 0;
}
 
cycle_delay = 0; /* An exception stalls the CPU 0 clock cycles */
}
 
static void except_handle_backend(int except, unsigned long ea, unsigned long pc_saved)
{
pending.valid = 0;
pending.type = 0;
pending.address = 0;
pending.saved = 0;
 
#if ONLY_VIRTUAL_MACHINE
printf("WARNING: No exception processing while ONLY_VIRTUAL_MACHINE is defined.\n");
cont_run = 0;
81,15 → 167,27
mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_EXR); /* Disable except. */
pc = (unsigned long)except;
 
/* This has been removed. All exceptions (not just SYSCALL) suffer
from the same problem. The solution is to continue just like
the pipeline would, and issue the exception on the next
clock cycle. We assume now that this function is being called
->BEFORE<- the instruction fetch and after the previous update
which always yields the correct behavior. This has the added
advantage that a debugger can prevent an exception from
taking place by resetting the pc. */
#if 0
/* MM: We do pc update after the execute (in the simulator), so we
decrease it by 4 so that next instruction points to first exception
instruction. */
if (except == EXCEPT_SYSCALL)
pc -= 4;
#endif
 
pcnext = pc+4;
 
/* Added by CZ 27/05/01 */
pc_phy = pc;
cycle_delay = 7; /* An exception stalls the CPU 7 clock cycles */
pc_phy = pc; /* An exception always turns off the MMU, so
pc is always pc_phy */
 
#endif
}
/trunk/or1ksim/cpu/or1k/spr_defs.h
42,9 → 42,10
/* System control and status group */
#define SPR_VR (SPRGROUP_SYS + 0)
#define SPR_UPR (SPRGROUP_SYS + 1)
#define SPR_SR (SPRGROUP_SYS + 2)
#define SPR_EPCR_BASE (SPRGROUP_SYS + 16)
#define SPR_EPCR_LAST (SPRGROUP_SYS + 31)
#define SPR_PC (SPRGROUP_SYS + 16) /* CZ 21/06/01 */
#define SPR_SR (SPRGROUP_SYS + 17) /* CZ 21/06/01 */
#define SPR_EPCR_BASE (SPRGROUP_SYS + 32) /* CZ 21/06/01 */
#define SPR_EPCR_LAST (SPRGROUP_SYS + 47) /* CZ 21/06/01 */
#define SPR_EEAR_BASE (SPRGROUP_SYS + 48)
#define SPR_EEAR_LAST (SPRGROUP_SYS + 63)
#define SPR_ESR_BASE (SPRGROUP_SYS + 64)
/trunk/or1ksim/toplevel.c
79,7 → 79,7
int GlobalMode = 0; /* Start off in the orginal mode */
 
/* CVS revision number. */
const char rcsrev[] = "$Revision: 1.18 $";
const char rcsrev[] = "$Revision: 1.19 $";
 
/* Continuos run versus single step tracing switch. */
int cont_run;
1061,10 → 1061,15
JTAGProxyWriteResponse resp_write;
JTAGProxyReadResponse resp_read;
JTAGProxyChainResponse resp_chain;
JTAGProxyBlockWriteMessage *msg_bwrite;
JTAGProxyBlockReadMessage msg_bread;
JTAGProxyBlockWriteResponse resp_bwrite;
JTAGProxyBlockReadResponse *resp_bread;
char *buf;
unsigned long long data;
int err;
int err = 0;
uint32_t command,length;
int len,i;
 
/* First, we must read the incomming command */
if(gdb_read(&command,sizeof(uint32_t)) < 0)
1158,6 → 1163,103
return;
}
break;
case JTAG_COMMAND_BLOCK_WRITE:
if(length < sizeof(JTAGProxyBlockWriteMessage)-8)
{
ProtocolClean(length,JTAG_PROXY_PROTOCOL_ERROR);
return;
}
if(!(buf = (char*)malloc(8+length)))
{
ProtocolClean(length,JTAG_PROXY_OUT_OF_MEMORY);
return;
}
msg_bwrite = (JTAGProxyBlockWriteMessage*)buf;
if(gdb_read(&buf[8],length) < 0)
{
if(gdb_fd)
{
perror("gdb socket - 5");
close(gdb_fd);
gdb_fd = 0;
}
free(buf);
return;
}
msg_bwrite->address = ntohl(msg_bwrite->address);
msg_bwrite->nRegisters = ntohl(msg_bwrite->nRegisters);
for(i=0;i<msg_bwrite->nRegisters;i++)
{
int t_err;
 
msg_bwrite->data[i] = ntohl(msg_bwrite->data[i]);
t_err = DebugSetRegister(msg_bwrite->address+i,msg_bwrite->data[i]);
err = err ? err : t_err;
}
resp_bwrite.status = htonl(err);
free(buf);
buf = msg_bwrite = NULL;
if(gdb_write(&resp_bwrite,sizeof(resp_bwrite)) < 0)
{
if(gdb_fd)
{
perror("gdb socket - 4");
close(gdb_fd);
gdb_fd = 0;
}
return;
}
break;
case JTAG_COMMAND_BLOCK_READ:
if(length != sizeof(msg_bread) - 8)
{
ProtocolClean(length,JTAG_PROXY_PROTOCOL_ERROR);
return;
}
buf = (char*)&msg_bread;
if(gdb_read(&buf[8],length) < 0)
{
if(gdb_fd)
{
perror("gdb socket - 5");
close(gdb_fd);
gdb_fd = 0;
}
return;
}
msg_bread.address = ntohl(msg_bread.address);
msg_bread.nRegisters = ntohl(msg_bread.nRegisters);
len = sizeof(JTAGProxyBlockReadResponse) + 4*(msg_bread.nRegisters-1);
if(!(buf = (char*)malloc(len)))
{
ProtocolClean(0,JTAG_PROXY_OUT_OF_MEMORY);
return;
}
resp_bread = (JTAGProxyBlockReadResponse*)buf;
for(i=0;i<msg_bread.nRegisters;i++)
{
int t_err;
 
t_err = DebugGetRegister(msg_bread.address+i,&resp_bread->data[i]);
resp_bread->data[i] = htonl(resp_bread->data[i]);
err = err ? err : t_err;
}
resp_bread->status = htonl(err);
resp_bread->nRegisters = htonl(msg_bread.nRegisters);
if(gdb_write(resp_bread,len) < 0)
{
if(gdb_fd)
{
perror("gdb socket - 6");
close(gdb_fd);
gdb_fd = 0;
}
free(buf);
return;
}
free(buf);
buf = resp_bread = NULL;
break;
case JTAG_COMMAND_CHAIN:
if(length != sizeof(msg_chain) - 8)
{

powered by: WebSVN 2.1.0

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