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

📄 semihost.c

📁 realview22.rar
💻 C
📖 第 1 页 / 共 5 页
字号:
/* for semihostingstate */
#define SEMIHOSTSTATE_ENABLED 1

/* Returns the time in bus-clocks. */
static ARMTime Semihost_GetTime(OSState *osstate)
{
    return ARMulif_Time(&osstate->coredesc);
}


static void LOG_FILE_OP(OSState *state, char *fmt, ...)
{
    if (state->os_file_log)
    {
        va_list ap;
        char buf[1000];
        va_start(ap, fmt);
        vsprintf(buf, fmt, ap);
        fputs(buf,state->os_file_log);
        va_end(ap);
    }
}

static bool_int isNewLine(char c)
{
    return c == '\n' || c == '\r' || c == '\0';
}

static void PutInLineBuffer(OSState *os, char *txt)
{
    while (txt && *txt)
    {
        if (isNewLine(*txt))
        {
            if (os->nchars_in_linebuf)
            {
                os->linebuf[os->nchars_in_linebuf] = '\0';
                /* Trace it, compare it, or whatever */
                if (os->os_Trace_OutPut && os->os_TracerPrintf.func)
                {
                    os->os_TracerPrintf.func(os->os_TracerPrintf.handle,
                                                "[SEMIHOST]");
                    os->os_TracerPrintf.func(os->os_TracerPrintf.handle,
                                                "%s\n", os->linebuf);
                }
            }
            os->nchars_in_linebuf = 0;
        }
        else if (os->nchars_in_linebuf < LINE_LENGTH - 1)
        {
            os->linebuf[os->nchars_in_linebuf++] = *txt;
        }
        ++txt;
    }
}
/* Return microseconds of wall-clock-time
 */
static ARMword wallclock_millisecs(OSState *osstate)
{
  (void)osstate;
#ifdef CLOCKS_PER_SEC
# if (CLOCKS_PER_SEC != 1000000) && (CLOCKS_PER_SEC != 1000)
#   error "CLOCKS_PER_SEC unexpected value"
# endif
#endif
  return (ARMword)(clock() / (CLOCKS_PER_SEC/1000));
}

/* for SYS_READ_CORECYCLES_AND_INSTRS */
static void read_core_cycles_and_instrs(OSState *osstate)
{
         RDI_CycleDesc *descs;
         ARMword       *counters;
         ARMword        ii;
         ARMword        ndesc=0;
         ARMword        cycs_lo=0, insts_lo=0;
         ARMword        cycs_hi=0, insts_hi=0;
         
         /* Fill in ndesc with the number of counters in the model */
         osstate->coredesc.rdi->info(osstate->coredesc.handle, RDIRequestCyclesDesc, &ndesc, NULL);

         /* Allocate some space (note that counters take up two words each) */
         descs=(RDI_CycleDesc *)calloc(ndesc,sizeof(RDI_CycleDesc));
         counters=(ARMword *)calloc((ndesc+1)*2, sizeof(ARMword));
         
         /* Fetch the info */
         osstate->coredesc.rdi->info(osstate->coredesc.handle, RDIRequestCyclesDesc, &ndesc, (ARMword *)descs);
         osstate->coredesc.rdi->info(osstate->coredesc.handle, RDICycles, counters, NULL);
         
         for (ii=0 ; ii<ndesc ; ii++) {
           /* Search for likely cycle counts first */
           if (!strcmp(descs[ii].name + 1, "Core_Cycles")) {
             cycs_lo=counters[ii*2+1];
             cycs_hi=counters[ii*2];
           }
           
           /* And then instruction counts.. */
           if (!strcmp(descs[ii].name + 1, "Instructions")) {
             insts_lo=counters[ii*2+1];
             insts_hi=counters[ii*2];
           }
         }
         
         free(descs);
         free(counters);

     {
         ARMword mode = ARMulif_GetCPSR(&osstate->coredesc) & 0x1f ;
         ARMword arg_addr = ARMulif_GetReg(&osstate->coredesc,mode,1);
         ARMulif_WriteWord(&osstate->coredesc, arg_addr, cycs_hi);
         ARMulif_WriteWord(&osstate->coredesc, arg_addr+4, cycs_lo);
         ARMulif_WriteWord(&osstate->coredesc, arg_addr+8, insts_hi);
         ARMulif_WriteWord(&osstate->coredesc, arg_addr+12, insts_lo);
     }
#ifdef VERBOSE
     Hostif_ConsolePrint(osstate->hostif, 
                         "read_core_cycles_and_instrs ndec:%u ->%u, %u\n",
                         (unsigned)ndesc,
                         (unsigned)cycs_lo, (unsigned)insts_lo);
#endif
}

static bool GetString(RDI_ModuleDesc *coredesc, ARMword from, char *to,
                      unsigned int BufferSize);


static bool PutString(RDI_ModuleDesc *coredesc, ARMword dest_addr,
                      char const *source,
                      unsigned int BufferSize)
{
    unsigned int i = 0;
    do {
        if (++i > BufferSize) 
        {
            return FALSE;
        }
        ARMulif_WriteByte(coredesc, dest_addr++, *source);
    } while (*source++ != '\0');
    return TRUE;
}


/* Args are r1: dest buffer address
 *          r2: size of buffer
 *          r3: address of tag.
 */
static void sys_lookup_config(OSState *my)
{
    ARMword mode = ARMulif_GetCPSR(&my->coredesc) & 0x1f ;
    ARMword dest_addr = ARMulif_GetReg(&my->coredesc,mode,1);
    ARMword dest_size = ARMulif_GetReg(&my->coredesc,mode,2);
    ARMword tag_addr = ARMulif_GetReg(&my->coredesc,mode,3);
    char tag[129];
    ARMword r0 = (ARMword)-1;
    if (GetString(&my->coredesc, tag_addr, tag, 128))
    {
        char const *option = ToolConf_Lookup(my->config, (tag_t)tag);
        if (option != NULL)
        {
            if (PutString(&my->coredesc, dest_addr, option, dest_size))
            {
                /* Claim success */
                r0 = 0;
            }
        }
    }
    ARMulif_SetReg(&my->coredesc, mode, 0, r0);
}




/* Return centiseconds of real or emulated time.
 * Real time is from the host's clock(),
 * Emulated time is 
 *  coreclocks * centiSecondsPerSecond [cs*Hz] / coreClockRate[Hz] 
 *
 */
static ARMTime OS_GetCentiseconds(OSState *osstate)
{
    /* First see if the core supports RDIRead_Clock */
    ARMword secs,ns;
    if (osstate->os_bUseRealTime)
    {
        return
#ifdef CLOCKS_PER_SEC
            ( (CLOCKS_PER_SEC >= 100)
              ? (ARMword) (clock() / (CLOCKS_PER_SEC / 100))
              : (ARMword) ((clock() * 100) / CLOCKS_PER_SEC)
                )
#else
        /* Assume unix... clock() returns microseconds */
        (ARMword) (clock() / 10000)
#endif
            ;
    }
    else if (osstate->coredesc.rdi->info(osstate->coredesc.handle,
                                 RDIRead_Clock,&ns,&secs) == RDIError_NoError)
    {
        ARMTime t = (ARMTime)secs * 100 + (ns / 10000) / 1000;
#ifdef VERBOSE_GetCS
        printf("GetCS secs:%lu ns:%lu -> %lu\n",
               (unsigned long)secs,(unsigned long)ns, (unsigned long)t);
#endif
        return t;
    }
    else
    {
        assert(osstate->os_BusSpeed != 0);
        return (ARMword)(ARMulif_Time(&osstate->coredesc) * 100 /
                         osstate->os_BusSpeed);

    }
}


/* Leaf node - no need to call next->func. */
static unsigned Time_Access(GenericAccessCallback *gacb,
                            ARMword address,
                            ARMword *data,
                            unsigned access_type)
{
    OSState *osstate = (OSState *)gacb->handle;
    (void)address;
#if 0
    printf("Time_Access type:0x%04x", access_type);
#endif
    switch (access_type & (ACCESS_WRITE | 0xF))
    {
    case (ACCESS_READ | ACCESS_WORD):
        *data = (uint32)Semihost_GetTime(osstate);
        return RDIError_NoError;
#ifdef TIME_CAN_BE_SET
    case (ACCESS_WRITE | ACCESS_WORD): {
        ARMTime ti = ARMulif_Time(&osstate->coredesc);
        ti = ( ti & ((ARMTime)0xFFFFFFFFU << 32) ) | (ARMTime)*data;
        return ARMulif_SetTime(&osstate->coredesc, ti);
        }
#endif
    }
    return RDIError_NoSuchHandle;
}

#ifdef CPUTIME_HI
/* Leaf node - no need to call next->func. */
static unsigned Time_Access_Hi(GenericAccessCallback *gacb,
                            ARMword address,
                            ARMword *data,
                            unsigned access_type)
{
    OSState *osstate = (OSState *)gacb->handle;
    (void)address;
    switch (access_type & (ACCESS_WRITE | 0xF))
    {
    case (ACCESS_READ | ACCESS_WORD):
        *data = (uint32)(Semihost_GetTime(osstate) >> 32);
        return RDIError_NoError;
    }
    return RDIError_NoSuchHandle;
}
#endif


static unsigned Clock_Access(GenericAccessCallback *gacb,
                            ARMword address,
                            ARMword *data,
                            unsigned access_type)
{
    OSState *osstate = (OSState *)gacb->handle;
    (void)address;
    switch (access_type & (ACCESS_WRITE | 0xF))
    {
    case (ACCESS_READ | ACCESS_WORD):
        *data = (uint32)OS_GetCentiseconds(osstate);
        return RDIError_NoError;
    }
    return RDIError_NoSuchHandle;
}


static ARMul_RDIPropertyDesc Time_PropDesc = 
{
    /* */
    {
        "cputime", /* name */
        "Time in units of core CPUSPEED", /* description */
        0,                  /* ID */
        FALSE,              /* AsString */
        0,                  /* maxStrLen */
        TRUE,               /* AsNumeric */
        FALSE,              /* IsSigned */
        32,                 /* Width */
        FALSE,               /* readOnly */
        FALSE,              /* monotonicIncreasing */
        FALSE,              /* traceable */
        RDIProperty_PDT_Standard
    },

    {
        NULL,
        Time_Access,
        NULL
    }

};


#ifdef CPUTIME_HI
static ARMul_RDIPropertyDesc TimeHi_PropDesc = 
{
    {
        "cputime_hi", /* name */
        "Time in units of core CPUSPEED", /* description */
        0,                  /* ID */
        FALSE,              /* AsString */
        0,                  /* maxStrLen */
        TRUE,               /* AsNumeric */
        FALSE,              /* IsSigned */
        32,                 /* Width */
        TRUE,               /* readOnly */
        FALSE,              /* monotonicIncreasing */
        FALSE,              /* traceable */
        RDIProperty_PDT_Standard
    },

    {
        NULL,
        Time_Access_Hi,
        NULL
    }

};
#endif

static ARMul_RDIPropertyDesc Clock_PropDesc = 
{
    /* */
    {
        "sys_clock", /* name */
        "Time in centiseconds as read by semihosting SYS_CLOCK", /* description */
        0,                  /* ID */
        FALSE,              /* AsString */
        0,                  /* maxStrLen */
        TRUE,               /* AsNumeric */
        FALSE,              /* IsSigned */
        32,                 /* Width */
        TRUE,               /* readOnly */
        FALSE,              /* monotonicIncreasing */
        FALSE,              /* traceable */
        RDIProperty_PDT_Standard
    },

    {
        NULL,
        Clock_Access,
        NULL
    }

};



/* fileflags */
#define NOOP 0
#define BINARY 1
#define READOP 2
#define WRITEOP 4

RDI150_OpenAgentProc OS_Init;
RDI150_CloseAgentProc OS_Exit;
static unsigned Angel_ConfigEvents(void *handle, void *data);
static SimRdiRegistrationListener OS_SimRdiListener;

BEGIN_INIT(OS)
{   ARMword i ;
    OSState *osstate = (OSState *)state;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -