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

📄 codeseq.c

📁 realview22.rar
💻 C
📖 第 1 页 / 共 2 页
字号:
/* codeseq.c - module to allow RDI code sequences to be run on ARMulator 
 * Copyright (c) 2001  ARM Limited. All Rights Reserved.
 *
 * RCS $Revision: 1.2.2.22.2.1 $
 * Checkin $Date: 2002/06/13 20:48:13 $
 * Revising $Author: gevans $
 */


#define MODEL_NAME Codeseq

#include <stdio.h>
#include <time.h>
#include <ctype.h>
#include <string.h>       /* for strcpy */
#include "armul_cnf.h"

#include "minperip.h"

#include "armul_callbackid.h"
#include "armul_agent.h"
#include "disass.h"

#ifdef SOCKETS
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#endif

#include "armul_mem.h"
#include "rdi_sdm.h"

#ifndef NDEBUG
# if 1
# else
#  define VERBOSE_SAVEDREGS
#  define VERBOSE_BUS
#  define VERBOSE_RDI_LOG
#  define VERBOSE_SDM
# endif
#endif


#define CURRENTMODE RDIMode_Curr

/* MOV Rd,Rm; Rd in bits 12..15, Rm in bits 0..3 */
#define ARM_NOP_INSTR 0xE1A00000
/* ADDS Rd, Rn, #0; Rd in bits 0..2, Rn in bits 3..5. */
#define THUMB_NOP_INSTR 0x1C00

/* static ARMword nop_instr[5] = {
   0,0,THUMB_NOP_INSTR,0,ARM_NOP_INSTR }; */

BEGIN_STATE_DECL(Codeseq)
    struct RDICodeSequence_Data CodeSequenceToRun;
ARMword RegsSavedForRunCodeSequence[16];
ARMul_MemInterface bus_mem, child;
ARMul_MemInterfaceRef mem_ref;
ARMword last_address;
    unsigned instr_size; /* 4 for ARM, 2 for Thumb */
    ARMword base_address;
    ARMword stop_pc; /* When to stop! */
    bool_int verbose;
    bool_int InPreamble;
END_STATE_DECL(Codeseq)

static unsigned CodeseqMemInfo(void *handle, unsigned type, ARMword *pID,
                               uint64 *data)
{
    CodeseqState *mem = (CodeseqState *)handle;
    if (mem->child.mem_info)
    {
        return mem->child.mem_info(mem->child.handle,type,pID,data);
    }
    else
    {
        return RDIError_UnimplementedMessage;
    }
}
static int Codeseq_MemAccess(void *handle, ARMWord address, ARMWord *data,
                             unsigned acc);
static int Codeseq_MemAccessSA(void *handle,ARMWord address, ARMWord *data,
                               unsigned acc);
static void Codeseq_MemAccessHarvard(void *handle,
                       ARMword daddr,ARMword *ddata, ARMul_acc dacc, int *drv,
                       ARMword iaddr,ARMword *idata, ARMul_acc iacc, int *irv);



/* Aims to return a value in microseconds */
static ARMTime CodeseqReadClock(void *handle)
{
    CodeseqState *mem = (CodeseqState *)handle;
    if (mem->child.read_clock)
    {
        return mem->child.read_clock(mem->child.handle);
    }
    else
    {
        return 0L;
    }    
}


static const ARMul_Cycles *CodeseqReadCycles(void *handle)
{
    CodeseqState *mem = (CodeseqState *)handle;
    if (mem->child.read_cycles)
    {
        return mem->child.read_cycles(mem->child.handle);
    }
    else
    {
        return NULL;
    }
}


static uint32 CodeseqGetCycleLength(void *handle)
{
    CodeseqState *mem = (CodeseqState *)handle;
    if (mem->child.get_cycle_length)
        return mem->child.get_cycle_length(mem->child.handle);
    return 0;
}


static void CodeseqCoreException(void *handle,ARMword address,
                        ARMword penc)
{
    CodeseqState *cs = (CodeseqState *)handle;
    cs->child.x.arm8.core_exception(cs->child.handle,address,penc);
}

static unsigned int CodeseqDataCacheBusy(void *handle)
{
    CodeseqState *cs = (CodeseqState *)handle;
    return cs->child.x.strongarm.data_cache_busy(cs->child.handle);
}

static int Codeseq_MemAccess2(void *handle,
                             ARMword address,
                             ARMword *data,
                             ARMul_acc access_type)
{
    CodeseqState *state = (CodeseqState *)handle;
    if(!(acc_nOPC(access_type))) 
    {
        return Codeseq_MemAccess(handle, address, data, access_type);
    }
    else
    {
        int err = 
            state->child.x.arm8.access2(state->child.handle,
                                        address,data,access_type);
        return err;
    }
}

/* This is only for ARM7 (and ARM6) cores. */
static int Codeseq_MemAccess(void *handle,
                             ARMword address,
                             ARMword *data,
                             ARMul_acc access_type)
{
 
    CodeseqState *state = (CodeseqState *)handle;
    armul_MemAccess *mem_access=state->child.x.basic.access;
    RDICodeSequence_Data *cs = &state->CodeSequenceToRun;
    UNUSEDARG(address);
    UNUSEDARG(data);
    UNUSEDARG(access_type);
    if (access_type & ACCESS_IDLE)
        return PERIP_OK;

    if(!(acc_nOPC(access_type))) 
    {
        switch(acc_WIDTH(access_type))
        {
        case BITS_16:
        {
            uint16* ip2 = (uint16*)cs->instructions;
            unsigned offset = (address - state->base_address)>>1;
            if (offset < cs->numInstructions)
            {
                *data = ip2[offset];
            }
            else
            {
                *data = THUMB_NOP_INSTR;
            }
            return PERIP_OK;
        }
        default:
# ifndef NDEBUG
                Hostif_ConsolePrint(state->hostif,"Codeseq : Unexpected access-size. %u\n", acc_WIDTH(access_type));
                /* fallthru */
# endif
        case BITS_32:
        {
            unsigned offset = (address - state->base_address)>>2;
            if (!state->InPreamble && offset < cs->numInstructions)
            {
                *data = cs->instructions[offset];
            }
            else
            {
                unsigned Reg = ((offset - cs->numInstructions) & 15);
                *data = ARM_NOP_INSTR + Reg + (Reg << 12);
            }
#ifdef VERBOSE_SDM
            Hostif_ConsolePrint(state->hostif,"SDM A:%08x, I:%08x\n",
                                (unsigned)address,
                                (unsigned)*data);
#endif
            return PERIP_OK;
        }
        case BITS_64: /* E.g. ARM8 */
        {
            int err1 = Codeseq_MemAccess(handle,address,data,
                                         access_type - 1);
            int err2 = Codeseq_MemAccess(handle,address+4,data+1,
                                         access_type - 1);
            (void)err1; (void)err2;
            return PERIP_OK2;
        }
        }
#  ifdef VERBOSE_CODESEQ_END
        Hostif_ConsolePrint(state->hostif,"Addr:%08x, LAST:%08x\n",
                            (unsigned)address,
                            (unsigned)state->last_address);
#  endif
    }
    /*
     * Need to pass data access on to mem system.
     * NB data-aborts are bad news here.
     */
    return mem_access(state->child.handle,address,data,access_type);
}

static int Codeseq_MemAccessSA(void *handle,
                               ARMword address,
                               ARMword *data,
                               ARMul_acc access_type)
{
 
    CodeseqState *state = (CodeseqState *)handle;
    RDICodeSequence_Data *cs = &state->CodeSequenceToRun;

    UNUSEDARG(address);
    UNUSEDARG(data);
    UNUSEDARG(access_type);
  
    if(!(acc_nOPC(access_type)))
    {
        if (cs->numInstructions > 0)
        {
            --cs->numInstructions;
            if (acc_WIDTH(access_type) == BITS_16)
            {
                uint16* ip2 = (uint16*)cs->instructions;
                ARMWord rv = *(ip2++);
                cs->instructions = (uint32*)ip2;
                *data = rv; 
                state->last_address = address;
                return PERIP_OK;
            }
            else
            {
                uint32 rv = *(cs->instructions++);
                *data = rv; 
                state->last_address = address;
                return PERIP_OK;
            }
        }
        return (unsigned)PERIP_DABORT; /* Ouch! */
    }
    return
        state->child.x.strongarm.access(state->child.handle,address,data,access_type);
}

static void Codeseq_MemAccessHarvard(void *handle,
                       ARMword daddr,ARMword *ddata, ARMul_acc dacc, int *drv,
                       ARMword iaddr,ARMword *idata, ARMul_acc iacc, int *irv)
{
    CodeseqState *state = (CodeseqState *)handle;

    ARMWord dummy_idata = 0;
    ARMul_acc dummy_iacc = ACCESS_IDLE + ACCESS_INSTR;
    int dummy_irv = 0;

    /* It is a requirement on the core-models that they clear *irv when
     * they want a new opcode. (This test isn't needed while we don't
     * generate D-side waits, but it's in here while we remember.)
     */
    if (!*irv) /* Only return opcode when requested */
    {
        if(!(acc_nMREQ(iacc)))
        {
            *irv = Codeseq_MemAccess(state,iaddr,idata,iacc);
        }
        else
            *irv =  PERIP_OK;
    }
    state->child.x.pipe_arm9.harvard_access(
        state->child.handle,
        daddr, ddata, dacc, drv,
        iaddr, &dummy_idata, dummy_iacc, &dummy_irv);
#ifndef NDEBUG
    if (state->verbose)
    {
        if (*irv!=PERIP_OK) Hostif_ConsolePrint(state->hostif,"Warning, FPE i returns %d\n",*irv);
        if (*drv!=PERIP_OK) Hostif_ConsolePrint(state->hostif,"Warning, FPE d returns %d\n",*drv);
    }
#endif
    return;
}

⌨️ 快捷键说明

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