📄 semihost.c
字号:
* isn't handled by the FPE code because it's not executed.
*/
ARMulif_SetR15(&osstate->coredesc,
(ARMulif_GetReg(&osstate->coredesc,CURRENTMODE,14)+ 4
+ DEMON_PC_OFFSET ));
ARMulif_SetCPSR(&osstate->coredesc,
ARMulif_GetSPSR(&osstate->coredesc,
ARMulif_GetCPSR(&osstate->coredesc) & 0x1f));
#ifdef VERBOSE_DEMON_EXIT
printf("Demon Exit SWI STOPPING number:0x%04x vector_catch:%08lx "
"pc:%08lx\n",
(unsigned)number, (unsigned long)OSptr->vector_catch,
(unsigned long)ARMulif_GetR15(&osstate->coredesc));
#endif
if (number == 0x90) {
#if 0
printf("b t z\n");
#endif
ARMulif_StopExecution(&osstate->coredesc, RDIError_BranchThrough0);
} else {
ARMulif_StopExecution(&osstate->coredesc,number - 0x8f);
}
} else {
ARMword sp = ARMulif_GetReg(&osstate->coredesc,CURRENTMODE,13);
ARMulif_WriteWord(&osstate->coredesc, sp - 4,
ARMulif_GetReg(&osstate->coredesc,CURRENTMODE,14));
ARMulif_WriteWord(&osstate->coredesc, sp - 8,
ARMulif_GetReg(&osstate->coredesc,CURRENTMODE,12));
ARMulif_WriteWord(&osstate->coredesc, sp - 12,
ARMulif_GetReg(&osstate->coredesc,CURRENTMODE,11));
ARMulif_WriteWord(&osstate->coredesc, sp - 16,
ARMulif_GetReg(&osstate->coredesc,CURRENTMODE,10));
ARMulif_SetReg(&osstate->coredesc,CURRENTMODE,13, sp - 16);
ARMulif_SetReg(&osstate->coredesc,CURRENTMODE,11,
OSptr->map.handlers + 8 * (number-0x90));
#ifdef VERBOSE_DEMON_EXIT
printf("DemonExitSWI TidyCommon (stacking, not stopping) number:0x%04x "
"vector_catch:%08lx stacked R14:%08lx\n",
(unsigned)number, (unsigned long)OSptr->vector_catch,
(unsigned long)ARMulif_GetReg(&osstate->coredesc,CURRENTMODE,14));
#endif
}
return TRUE;
/* SWI's 0x8x pass an abort of type x to the debugger if a handler returns */
case 0x80: case 0x81: case 0x82: case 0x83:
case 0x84: case 0x85: case 0x86: case 0x87: case 0x88: {
ARMword sp = ARMulif_GetReg(&osstate->coredesc,CURRENTMODE,13);
ARMulif_SetReg(&osstate->coredesc,CURRENTMODE,10,
ARMulif_ReadWord(&osstate->coredesc, sp));
ARMulif_SetReg(&osstate->coredesc,CURRENTMODE,11,
ARMulif_ReadWord(&osstate->coredesc, sp + 4));
ARMulif_SetReg(&osstate->coredesc,CURRENTMODE,12,
ARMulif_ReadWord(&osstate->coredesc, sp + 8));
ARMulif_SetReg(&osstate->coredesc,CURRENTMODE,14,
ARMulif_ReadWord(&osstate->coredesc, sp + 12));
ARMulif_SetReg(&osstate->coredesc,CURRENTMODE,13, sp + 16);
/* the pipelining the the RDI will undo */
if ( number == 0x84)
{
/* Data abort - return address is an extra 4! */
ARMulif_SetR15(&osstate->coredesc,
(ARMulif_GetReg(&osstate->coredesc,CURRENTMODE,14)+
4 + DEMON_PC_OFFSET)); /* ? Check this! */
}
else
{
ARMulif_SetR15(&osstate->coredesc,
(ARMulif_GetReg(&osstate->coredesc,CURRENTMODE,14)+
DEMON_PC_OFFSET));
}
#ifdef VERBOSE_DEMON_EXIT
printf("DemonExitSWI Stopping number:0x%04x "
"unstacked R14:%08lx -> R15:%08lx\n",
(unsigned)number,
(unsigned long)ARMulif_GetReg(&osstate->coredesc,CURRENTMODE,14),
(unsigned long)ARMulif_GetReg(&osstate->coredesc,CURRENTMODE,15));
#endif
ARMulif_SetCPSR(&osstate->coredesc,
ARMulif_GetSPSR(&osstate->coredesc,
ARMulif_GetCPSR(&osstate->coredesc) & 0x1f));
if (number == 0x80)
{
ARMulif_StopExecution(&osstate->coredesc, RDIError_BranchThrough0);
}
else
ARMulif_StopExecution(&osstate->coredesc,number - 0x7f);
return TRUE;
default:
return FALSE; /* We didn't understand */
} /* end switch(number) */
}
} /*( ?? )*/
static unsigned OS_HandleEvent(void *handle,
void *data)
{
ARMul_Event *evt = data;
OS_State *osstate = (OS_State *)handle;
switch (evt->event)
{
case ConfigEvent_RouteLinks:
ARMulif_QueryMethod(&osstate->coredesc, "TracerPrintf",
(GenericMethod*)&osstate->os_TracerPrintf);
break;
default:
break;
}
return FALSE;
}
#ifdef VERBOSE_SYS_FILE
#include <ctype.h> /* for isprint */
static void ShowChars(OS_State *osstate, const char* s, size_t n) {
for (; 0 < n; --n, ++s) {
int ch = *(const unsigned char *)s;
Hostif_ConsolePrint(osstate->hostif, isprint(ch) ? "%c" : "\\%03o", ch);
}
}
#endif
/***************************************************************************\
* The emulator calls this routine when a SWI instruction is encuntered. The *
* parameter passed is the SWI number (lower 24 bits of the instruction). *
\***************************************************************************/
static INLINE unsigned RaiseOutOfSemihostEventAndReturnTRUE(OS_State *state)
{
ARMulif_RaiseEvent(&state->coredesc,DebugEvent_OutOfSemihost,0,0);
return TRUE;
}
#define TRY_NEXT return FALSE
#define DONE return RaiseOutOfSemihostEventAndReturnTRUE(osstate)
/* We get called for ConfigEvent_Reset (50002) and CoreEvent_SWI (3) */
static unsigned OS_HandleException(void *handle,
void *data)
{
ARMul_Event *evt = data;
OS_State *osstate = (OS_State *)handle;
ARMword vector = evt->data1;
ARMword instr = evt->data2;
#ifdef VERBOSE_EXCEPTION
int dummy = printf("\n* OS_handleException, osstate = %p, "
"coredesc.rdi=%p evt=(%08lx,%08lx,%08lx)\n", osstate,
osstate->coredesc.rdi,
(unsigned long)evt->event,
(unsigned long)evt->data1,
(unsigned long)evt->data2
);
#endif
#ifdef VERBOSE_RESET /* for making sure the reset event gets sent. */
if (evt->event == CoreEvent_Reset)
printf("** Semihost gets Reset **\n");
#endif
unsigned isangel;
ARMword mode = ARMulif_GetCPSR(&osstate->coredesc) & 0x1f ;
ARMword addr, temp;
char buffer[BUFFERSIZE], *cptr;
FILE *fptr;
osstate->bStop_Received = FALSE;
#ifdef VERBOSE_EXCEPTION
(void)dummy;
#endif
if (evt->event != CoreEvent_SWI || vector != ARM_VECTOR_SWI)
{ /* we only do SWIs */
tryNext:
TRY_NEXT;
}
instr = instr & 0x00ffffff ;
if (instr == osstate->AngelSWIARM || instr == osstate->AngelSWIThumb) {
if (osstate->AngelEnabled &&
(osstate->semihostingstate & SEMIHOSTSTATE_ENABLED)
)
{
instr = ARMulif_GetReg(&osstate->coredesc,mode,0) ;
isangel = TRUE ;
}
else
goto tryNext;
}
else if ( (osstate->DemonEnabled &&
(osstate->semihostingstate & SEMIHOSTSTATE_ENABLED))
||
(osstate->ExitSwisEnabled && instr >= 0x80 && instr <= 0x9f)) {
if (instr & 0x100)
goto tryNext;
instr |= 0x100 ; /* to make the SWI number distinct from the SYS number */
isangel = FALSE ;
}
else /* not for us */
goto tryNext;
#ifdef VERBOSE_EXCEPTION
printf("Semihosted SWI# %02x\n", (unsigned)instr);
#endif
/*
* Tell anyone who cares that semihosting has begun. This is required
* because semihosting is half-like a debug state, and some models may
* be confused by the spurious memory accesses
*/
ARMulif_RaiseEvent(&osstate->coredesc,DebugEvent_InToSemihost,0,0);
switch (instr) {
case SWI_WriteC :
case SYS_WRITEC: /* 0x3 */
{
unsigned data = GetNthByteArg(osstate,0,isangel);
char tempc[2];
Hostif_ConsoleWriteC(osstate->hostif, data);
tempc[0]=(char)data;
tempc[1]='\0';
PutInLineBuffer(osstate, tempc);
}
osstate->ErrorNo = errno;
DONE;
case SWI_Write0 :
case SYS_WRITE0: /* 0x4 */
addr = ARMulif_GetReg(&osstate->coredesc,mode, isangel ? 1 : 0);
while ((temp = ARMulif_ReadByte(&osstate->coredesc,addr++)) != 0)
{
char tempc[2];
Hostif_ConsoleWriteC(osstate->hostif, (char)temp );
tempc[0]=(char)temp;
tempc[1]='\0';
PutInLineBuffer(osstate, tempc);
}
osstate->ErrorNo = errno;
break;
case SWI_WriteHex:
{
char temptxt[10];
addr = ARMulif_GetReg(&osstate->coredesc,mode,0) ;
sprintf(temptxt, "%08lx", (unsigned long)addr);
Hostif_ConsolePrint(osstate->hostif, "%s", temptxt);
PutInLineBuffer(osstate, temptxt);
break;
}
case SWI_ReadC :
case SYS_READC:
{
int temp = Hostif_ConsoleReadC(osstate->hostif);
if(osstate->bStop_Received == TRUE)
{
OS_MoveBackOneInstruction(&osstate->coredesc,
ARMulif_GetReg(&osstate->coredesc,mode,15),
mode);
ARMulif_StopExecution(&osstate->coredesc, RDIError_UserInterrupt);
DONE;
}
ARMulif_SetReg(&osstate->coredesc,mode,0,(ARMword)temp);
osstate->ErrorNo = errno;
break;
}
case SWI_CLI : /* Demon only */
addr = ARMulif_GetReg(&osstate->coredesc, mode,0);
if (GetString(&osstate->coredesc,addr,buffer,BUFFERSIZE))
{
ARMulif_SetReg(&osstate->coredesc, mode, 0,
(ARMword)system(buffer));
osstate->ErrorNo = errno;
}
#ifdef VERBOSE_CLI
printf("Angel_SWI_CLI[%s] ->%u\n",buffer,(unsigned)osstate->ErrorNo);
#endif
break;
case SYS_SYSTEM: {
unsigned int c, len;
addr = ARMulif_GetReg(&osstate->coredesc, mode,1);
len = ARMulif_ReadWord(&osstate->coredesc, addr + 4);
/* memset(buffer,'Z',BUFFERSIZE); -- check that we DO null-terminate
* by being very bad when we don't. */
if (ARMulif_ReadWord(&osstate->coredesc, addr) == (unsigned int)NULL
|| len > BUFFERSIZE-1) /* Reserve one byte for the null. */
{
/* handle the "check for command processor" case */
ARMulif_SetReg(&osstate->coredesc, mode, 0, 1);
DONE;
}
addr = ARMulif_ReadWord(&osstate->coredesc, addr); /* Where text is */
for (c = 0; c < len; c++)
buffer[c] = (char)ARMulif_ReadByte(&osstate->coredesc, addr + c);
buffer[c]=0; /* Null-terminate */
ARMulif_SetReg(&osstate->coredesc, mode, 0, (ARMword)system(buffer));
osstate->ErrorNo = errno;
break;
}
case SWI_GetEnv :
ARMulif_SetReg(&osstate->coredesc,mode,0,osstate->cmdlineaddr);
ARMulif_SetReg(&osstate->coredesc,mode,1,osstate->usersp) ;
addr = osstate->cmdlineaddr;
cptr = osstate->CommandLine;
if (cptr == NULL)
cptr = "\0";
do {
temp = (ARMword)*cptr++;
ARMulif_WriteByte(&osstate->coredesc,addr++,temp);
} while (temp != 0);
break;
case SYS_GET_CMDLINE: {
ARMword word2; /* Buffer size */
char * ccptr = osstate->CommandLine;
unsigned cl_length;
ARMword arg_addr = ARMulif_GetReg(&osstate->coredesc,mode,1);
if (ccptr != NULL && arg_addr != 0)
{
addr = ARMulif_ReadWord(&osstate->coredesc, arg_addr);
word2 = ARMulif_ReadWord(&osstate->coredesc, 4 + arg_addr);
#ifdef VERBOSE_CMDLINE
printf("SYS_GET_CMDLINE [%s] "
"R1:0x%08lx->{addr:0x%08lx size:0x%08lx}\n",
ccptr,
(unsigned long)arg_addr,
(unsigned long)addr, (unsigned long)word2);
#endif
if (ccptr == NULL)
ccptr = "\0";
cl_length = strlen(ccptr) + 1; /* Include the \0 */
/* We need to fill in the length of the string too */
ARMulif_WriteWord(&osstate->coredesc, 4+arg_addr, cl_length
#ifdef CMDLINE_LENGTH_EXCLUDES_NULL
- 1
#endif
);
if ( word2 == 0 || word2 < cl_length ) {
/* The buffer size given is too small - do no more. */
ARMulif_SetReg(&osstate->coredesc,mode,0, -1);
DONE;
}
if (addr != 0)
{
do {
temp = (ARMword)*ccptr++;
ARMulif_WriteByte(&osstate->coredesc,addr++,temp);
} while (temp != 0);
}
ARMulif_SetReg(&osstate->coredesc,mode,0, 0);
}
else
{
/* Return the only error-code. */
ARMulif_SetReg(&osstate->coredesc,mode,0, -1);
}
break;
}
case SYS_ISERROR: {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -