📄 udip2mm.c
字号:
UDISize size; /* in -- size of each object */UDICount *count_done; /* out - count actually transferred */UDIBool direction; /* in -- high-to-low or reverse */{ UDIError errno_mm = 0; msg_sbuf.class = CODE_COPY; msg_sbuf.length = 5*4 msg_sbuf.param[0] = MapSpace_udi2mm[from.Space]; /* source space */ msg_sbuf.param[1] = source.Offset; /* address */ msg_sbuf.param[2] = MapSpace_udi2mm[to.Space]; /* dest space */ msg_sbuf.param[3] = to.Offset; /* address */ msg_sbuf.param[4] = size*count /* byte_count */ (*msg_send)(&msg_sbuf); /* send MiniMON message */ while( (*msg_recv)(&msg_rbuf) ); /* wait for reply */ if(msg_rbuf.class == COPY_ACK)) *count_done = msg_rbuf.param[4]/size; else { errno_mm = EMCOPY; *count_done = 0; if(msg_rbuf.class == ERROR) errno_mm = msg_rbuf.param[0]; } return errno_mm;}/***************************************************************** UDI_EXECUTE UDIExecute() continues execution of the default process from the current PC.*/UDIError UDIExecute(){ UDIError errno_mm = 0; msg_sbuf.class = CODE_GO; msg_sbuf.length = 0; (*msg_send)(&msg_sbuf); /* send MiniMON message */ return errno_mm;}/******************************************************************** UDI_STEP UDIStep() specifies a number of "instruction" steps to make. The step can be further qualified to state whether CALLs should or should not be stepped over; whether TRAPs should or should not be stepped over; and whether stepping should halt when the PC gets outside a certain range. The semantics of UDIStep imply that progress is made; ie; at least one instruction is executed before traps or interrupts are handled.*/UDIError UDIStep(steps, steptype, range)UINT32 steps; /* in -- number of steps */UDIStepType steptype; /* in -- type of stepping to be done */UDIRange range; /* in -- range if StepInRange is TRUE */{ UDIError errno_mm = 0; msg_sbuf.class = CODE_STEP; msg_sbuf.length = 1*4; msg_sbuf.param[0] = steps; /* number of steps */ (*msg_send)(&msg_sbuf); /* send MiniMON message */ while( (*msg_recv)(&msg_rbuf) ); /* wait for reply */ return errno_mm;}/******************************************************************** UDI_STOP UDIStop() stops the default process*/UDIError UDIStop(stop_pc)UDIResource *stop_pc; /* out -- value of PC where we stopped */{ UDIError errno_mm = 0; msg_sbuf.class = CODE_BREAK; msg_sbuf.length = 0; (*msg_send)(&msg_sbuf); /* send MiniMON message */ while( (*msg_recv)(&msg_rbuf) ); /* wait for reply */ if(msg_rbuf.class == HALT) stop_pc->Offset = msg_rbuf.param[2]; /* PC1 address */ stop_pc->Space = MapSpace_mm2udi[msg_rbuf.param[0]]; /* address space */ else { errno_mm = EMBADMSG; if(msg_rbuf.class == ERROR) errno_mm = msg_rbuf.param[0]; } return errno_mm;}/******************************************************************* SIG_TIMER*/void sig_timer(){}/******************************************************************** UDI_WAIT UDIWait() returns the state of the target proces- sor. The TIP is expected to return when the target state is no longer RUNNING or when maxtime mil- liseconds have elapsed; whichever comes first. The special maxtime value UDI_WAIT_FOREVER essentially means that the DFE blocks until the target is no longer RUNNING. On completion; pid is used to re- port which process stopped (necessary for multi- process targets). On completion; stop_pc is usual- ly set to the PC where execution stopped. The return status STDIN_NEEDED allows the TIP to tell the DFE that the target program is requesting input and the TIP's own internal buffer of charcters is empty. The DFE can inform the user of this situation if it desires. Possible states are: NOT_EXECUTING RUNNING STOPPED (due to UDIStop) BREAK (breakpoint hit) STEPPED (completed number of steps requested by UDIStep) WAITING (wait mode bit set) HALTED (at a halt instruction) WARNED (not executing because WARN line asserted) TRAPPED (invalid trap taken; indicates trap number) STDOUT_READY (stopped waiting for stdout to be output) STDERR_READY (stopped waiting for stderr to be output) STDIN_NEEDED (stopped waiting for stdin to be supplied)*/UDIError UDIWait(maxtime, pid, stop_reason)INT32 maxtime; /* in -- maximum time to wait for completion */UDIPID *pid; /* out -- pid of process which stopped if any */UINT32 *stop_reason; /* out -- PC where process stopped */{ UDIError errno_mm = 0; if(signal(SIGALRM, sig_timer)) == -1) errno_mm = return errno_mm;}/********************************************************** UDI_SET_BREAKPOINT UDISetBreakpoint() sets a breakpoint at an ad- dress and uses the passcount to state how many times that instruction should be hit before the break occurs. The passcount continues to count down; even if a different breakpoint is hit and is reinitialized only when this breakpoint is hit. A passcount value of 0 indicates a Temporary break- point that will be removed whenever execution stops. A negative passcount indicates a non-sticky breakpoint.*/UDIError UDISetBreakpoint (addr, passcount, type, break_id)UDIResource addr; /* in -- where breakpoint gets set */INT32 passcount; /* in -- passcount for breakpoint */UDIBreakType type; /* in -- breakpoint type */INT32 *break_id; /* out-- break number assigned */{ UDIError errno_mm = 0; bkpt_entry_t *bkpt_p = &bkpt_table[break_id]; int cnt = 0; if(type != UDIBreakFlagExecute) { errno_mm = EMBKPTSET; return errno_mm; } while( cnt < MAX_BKPT) /* find BKPT slot in table */ if( !(bkpt_p->type) ) break; else cnt++; if(cnt >= MAX_BKPT) { errno_mm = EMBKPTNONE; return errno_mm; } bkpt_p->address.Offset = addr.Offset; bkpt_p->address.Space = addr.Space; bkpt_p->passcount = passcount; bkpt_p->type = type; *break_id = cnt; msg_sbuf.class = CODE_SET_BKPT; msg_sbuf.length = 4*4; msg_sbuf.param[0] = MapSpace_udi2mm[addr.Space]; msg_sbuf.param[1] = addr.Offset; msg_sbuf.param[2] = passcount; msg_sbuf.param[3] = -1; /* non 050 breakpoint */ (*msg_send)(&msg_sbuf); /* send MiniMON message */ while( (*msg_recv)(&msg_rbuf) ); /* wait for reply */ if(msg_rbuf.class == ERROR) errno_mm = msg_rbuf.param[0]; else if(msg_rbuf.class != CODE_SET_BKPT_ACK) errno_mm = EMBKPTSET; return error_mm;}/******************************************************** UDI_QUERY_BREAKPOINT*/UDIError UDIQueryBreakpoint (break_id, addr, passcount, type, current_count)INT32 break_id; /* in -- select brekpoint */UDIResource *addr; /* out - where breakpoint gets set */INT32 *passcount; /* out - passcount for breakpoint */UDIBreakType *type; /* out - breakpoint type */INT32 *current_count; /* out - current passcount for breakpoint */{ UDIError errno_mm = 0; msg_sbuf.class = CODE_BKPT_STAT; msg_sbuf.length = 2*4; msg_sbuf.param[0] = MapSpace_udi2mm[addr.Space]; msg_sbuf.param[1] = addr.Offset; (*msg_send)(&msg_sbuf); /* send MiniMON message */ while( (*msg_recv)(&msg_rbuf) ); /* wait for reply */ if(msg_rbuf.class == CODE_BKPT_STAT_ACK) { addr->Offset = bkpt_table[break_id].addr.Offset; addr->Space = bkpt_table[break_id].addr.Space; *passcount = bkpt_table[break_id].passcount; *type = bkpt_table[break_id].type; *current_count = msg_rbuf.param[2]; } else if(msg_rbuf.class == ERROR) errno_mm = msg_rbuf.param[0]; else errno_mm = EMBKPTSTAT; return errno_mm;}/******************************************************** UDI_CLEAR_BREAKPOINT UDIClearBreakpoint() is used to clear a break- point.*/UDIError UDIClearBreakpoint (break_id)INT32 break_id; /* in -- select brekpoint */{ UDIError errno_mm = 0; bkpt_entry_t *bkpt_p = &bkpt_table[break_id]; msg_sbuf.class = CODE_RM_BKPT; msg_sbuf.length = 2*4; msg_sbuf.param[0] = MapSpace_udi2mm[bkpt_p->Space]; msg_sbuf.param[1] = bkpt->Offset; (*msg_send)(&msg_sbuf); /* send MiniMON message */ while( (*msg_recv)(&msg_rbuf) ); /* wait for reply */ if(msg_rbuf.class == CODE_RM_BKPT_ACK) { bkpt->Space = 0; /* invalidate BKPT entry */ } else if(msg_rbuf.class == ERROR) errno_mm = msg_rbuf.param[0]; else errno_mm = EMBKPTRM; return errno_mm;}/************************************************************** UDI_GET_STDOUT UDIGetStdout() is called when a call to UDIWait() returns with the status STDOUT_READY. The parameter "buf" specifies the DFE's buffer ad- dress which is expected to be filled by the TIP. The parameter "bufsize" specifies the size of this buffer. On return; count_done is set to the number of bytes actually written to buf. The DFE should keep calling UDIGetStdout() until count_done is less than bufsize.*/UDIError UDIGetStdout(buf, bufsize, count_done)UDIHostMemPtr buf; /* out -- buffer to be filled */CPUSizeT bufsize; /* in -- buffer size in bytes */CPUSizeT *count_done; /* out -- number of bytes written to buf */{ UDIError errno_mm = EMBADMSG; return errno_mm;}/************************************************************** UDI_GET_STDERR UDIGetStderr() is called when a call to UDIWait() returns with the status STDERR_READY. In other respects it is similar to UDIGetStdout().*/UDIError UDIGetStderr(buf, bufsize, count)UDIHostMemPtr buf; /* out -- buffer to be filled */UINT32 bufsize; /* in -- buffer size in bytes */INT32 *count; /* out -- number of bytes written to buf */{ UDIError errno_mm = EMBADMSG; return errno_mm;}/*************************************************************** UDI_PUT_STDIN UDIPutStdin() is called whenever the DFE wants to deliver an input character to the TIP. This may be in response to a status STDIN_NEEDED but need not be. (Some target operating systems will never block for input). Any buffering and line editing of the stdin characters is done under control of the TIP.*/INT32 UDIPutStdin (buf, bufsize, count)UDIHostMemPtr buf; /* out - buffer to be filled */UINT32 bufsize; /* in -- buffer size in bytes */INT32 *count; /* out - number of bytes written to buf */{ UDIError errno_mm = EMBADMSG; return errno_mm;}/*************************************************************** UDI_PUT_TRANS UDIPutTrans() is used to feed input to the pass- thru mode. The parameter "buf" is points to the input data in DFE memory. The parameter "count" specifies the number of bytes.*/INT32 UDIPutTrans (buf, count)UDIHostMemPtr buf; /* in -- buffer address containing input data */CPUSizeT count; /* in -- number of bytes in buf */{ UDIError errno_mm = EMBADMSG; return errno_mm;}/*************************************************************** UDI_GET_TRANS UDIGetTrans() is used to get output lines from the pass-thru mode The parameter "buf" specifies to the buffer to be filled in DFE space. "bufsize" speci- fies the size of the buffer and; on return, "count" is set to the number of bytes put in the buffer. The DFE should continue to call UDIGetTrans() un- til count is less than bufsize. Other possible re- turn values are: EOF -- leave transparent mode UDI_GET_INPUT -- host should get some in- put; then call UDIPutTrans().*/INT32 UDIGetTrans (buf, bufsize, count)UDIHostMemPtr buf; /* out -- buffer to be filled */CPUSizeT bufsize; /* in -- size of buf */CPUSizeT *count; /* out -- number of bytes in buf */{ UDIError errno_mm = EMBADMSG; return errno_mm;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -