⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 semihost.c

📁 realview22.rar
💻 C
📖 第 1 页 / 共 5 页
字号:
         * 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 + -