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

📄 uniregs_registration_event.h

📁 realview22.rar
💻 H
📖 第 1 页 / 共 2 页
字号:
  /* the maximum number of blocks that SimRdi_Manager can cope with is this
     number, any higher and you need to recompile SimRdi_Manager. */
  uniregs_armulator_top = NUMBER_OF_UNIREGS_BLOCKS-1
};

/*
 * UniregsRegistration
 *
 * This is the object that gets broadcast in the RegistrationEvent.
 */

/* typedef struct tag_uniregistration UniregsRegistration; // in
 // simrdi_registration_event.h */
struct tag_uniregsregistration {
  uint32 signature; /* should check == UNIREGS_REGISTRATION_SIGNATURE */
  struct {
    uint32 major;
    uint32 minor;
  } version; /* these are the version numbers of SimRdi_Manager */

  void* handle;     /* handle for the private data of the methods */

  int number;       /* number of members below this one */

  void (*advertise)( UniregsRegistration* handle,
                     Uniregs_Advert* advert );

}; /* UniregsRegistration */

/*
 * Useful constructions for coprocessors
 */

#define DEBUG_MRC_OPCODE(opcode1,crn,rd,cp_num,opcode2,crm)     \
     0xEE100010                                                 \
     | ( (opcode1) << 21 )                                      \
     | ( (crn    ) << 16 )                                      \
     | ( (rd     ) << 12 )                                      \
     | ( (cp_num ) << 8 )                                       \
     | ( (opcode2) << 5 )                                       \
     | ( crm )

#define DEBUG_MCR_OPCODE(opcode1,crn,rd,cp_num,opcode2,crm)     \
     0xEE000010                                                 \
     | ( (opcode1) << 21 )                                      \
     | ( (crn    ) << 16 )                                      \
     | ( (rd     ) << 12 )                                      \
     | ( (cp_num ) << 8 )                                       \
     | ( (opcode2) << 5 )                                       \
     | ( crm )

/*
 * All blocks sort their adverts by (advert->x.config_flags &
 * UNIREGS_SORT_MASK)
 *
 * When an advert returns true to
 * UNIREGS_IS_DEFINITIVE(advert->x.config_flags) then no further
 * adverts will be considered.  This allows chaining of registers
 * within blocks.
 *
 * Blocks will usually describe with an appropriate enumeration the
 * values that the config_flags should take.
 *
 * The sorting is done in simrdi_manager.c::DemultiplexRegisters()
 *
 * At the moment, for simulator-defined registers, it is their own
 * responsibility that their names do not clash with other adverts.
 * This could take place at advert negotiation time. */

#define UNIREGS_IN_BLOCK(unireg) ((unireg)&0x7FF)
#define UNIREGS_BLOCK_NUMBER_MASK (0xF800)
#define UNIREGS_BLOCK_NUMBER(config_flags) \
    ( (((uint32)(config_flags)) & UNIREGS_BLOCK_NUMBER_MASK) >> 11 )
#define UNIREGS_IS_DEFINITIVE_MASK (0x10)
#define UNIREGS_IS_DEFINITIVE(config_flags) (!!((config_flags) & UNIREGS_IS_DEFINITIVE_MASK))
#define UNIREGS_SORT_MASK (0xF)

/* see simulator-added register blocks */
#define UNIREGS_DO_NOT_AUTO_GENERATE_REG_WIN (0x20)

/*
 * Block 0
 *
 * Block zero contains, eight sub-blocks, the sub-block number should
 * be x.config_flags & 0x700.  The bottom 4 bits (mask) 0xF are used
 * for sorting.  The UNIREGS_SUBBLOCK_MASK corresponds to the bits of
 * the uniregs number for the subblock number.  At the moment the
 * SimRdi_Manager does not use the subblock number to optimise the
 * access, however, it may in the future so it is an error not to
 * now. */
#define UNIREGS_SUBBLOCK_MASK    (0x700)

/* Blocks 1 and 2 is the MCRR/MRRC blocks or uniregs.
 * 
 * With the ARM1136, we have new CP15 registers that use MCRR to write
 * to them to invalidate or prefetch various ranges.  The blocks 15-31
 * are essentially encodings of the MCR/MRC opcode space.  Thus in
 * order to distinguish the MCRR/MRRC instruction space then we need
 * new blocks.
 *
 * The MCRR/MRCC instructions have 8 bits of freedom, thus for all
 * coprocessors we need to provide two blocks:
 *
 *   Block 1: MCRR/MRCC extension space, coprocessors 0-7 
 *     FEDCB A98 7654 3210
 *     block cp  op   crm
 *     00001 cp  op   crm
 *   
 *   Block 2: MCRR/MRCC extension space, coprocessors 8-15
 *     FEDCB A98   7654 3210
 *     block cp-8  op   crm
 *     00010 cp-8  op   crm
 *
 * We now have the possibility of several coprocessors chaining off
 * each other in then it is necessary to be careful about returning
 * 'can't' when the coprocessor number doesn't match.
 *
 * Note that this operation is encoding the transfer of two 32 bit
 * words, however, RVD will give us a _host_ endian 64 bit quantity
 * and so we define that the most significant word is Rn and the least
 * significant word is Rd to form the instruction:
 *     MCRR <copro>, <opcode>, <Rd>, <Rn>, <CRm>
 *
 * The config_flags used should be the same as
 * Uniregs_Config_Block16_Block31 (see later).  Each handler should
 * explicitly test for the coprocessor register using
 *   if (UNIREGS_X_CPNUM(unireg) == my_copro_number)
 *   {
 *       #if defined(HOST_ENDIAN_BIG)
 *       // swap to little-endian
 *       ARMword temp = data[1];
 *       data[1] = data[0];
 *       data[0] = temp;
 *       #elif defined(HOST_ENDIAN_LITTLE)
 *       // do nothing
 *       #else
 *       #error "Cannot determine endianness"
 *       #endif
 *       ...; // do it
 *   }
 *   else
 *   {
 *       return 1; // bounce
 *   }
 */


/* compose a unireg number in the extension space from cpnum, opcode
   and crm */
#define ARMREGNUM_XUNIREG(cpnum, opcode, crm) \
        ( ((0x8+(cpnum))<<8) | (((opcode)<<4) & 0xF0) | ((crm) & 0xF))
/* given that it is in the extension space figure out what coprocessor
   it is for */
#define UNIREGS_X_CPNUM(unireg) ( (((unireg) >> 8) - 0x8) & 0xF )
/* make a MCRR/MRCC instruction from the unireg number */
#define DEBUG_MCRR_FROM_UNIREG(unireg) ( (((unireg)-(0x8<<8)) & 0xFFF) \
                                         | 0xec401000 )
#define DEBUG_MRRC_FROM_UNIREG(unireg) ( (((unireg)-(0x8<<8)) & 0xFFF) \
                                         | 0xec501000 )

/*
 * Blocks 16 to 31 (Coprocessors)
 *
 * A coprocessor can provide uniregs or the core can provide the
 * uniregs.  If more than one coprocessor registers against the same
 * block then the list will be sorted by the numerical value of
 * (config_flags & UNIREGS_SORT_MASK).  Thus chainable coprocessors
 * will be first, the non-chainable one(s), followed by the core and
 * then codesequences.
 *
 * If there is a copro or a core or a codeseq then if any of them fail
 * then the others will not be attempted if they exist.
 *
 * Cores and codeseqs might register as backup options, but if they
 * exist then they provide definitive answers as too whether a unireg
 * exists and/or is accessible.  A copro is also considered definitive
 * and if a core or codeseq exists then it will not be used.  A
 * chainable coprocessor is considered non-definitive and a will chain
 * through all the (chainable_)copros until it finds a definitive
 * handler.  This allows uniregs and non-uniregs coprocessors exist
 * simultaneously.  The core or codeseq will pick them up.
 *
 * Chainable and non-chainable coprocessor can exist on the same
 * chain.  This might be useful if a single register is served by more
 * than one coprocessor. The chainable coprocessor adverts will be
 * serviced first and they will bit manipulate the destination but
 * will return non-zero to bounce the request down to the next
 * (chainable) coprocessor.  When it eventually hits the coprocessor
 * entry, then it will fill in the remaining parts and then return
 * that it serviced it (0).
 *
 * Some of the simulator blocks will automatically be converted into
 * register windows.  If you don't want them appearing in the window
 * then you should set the UNIREGS_DO_NOT_AUTO_GENERATE_REG_WIN flag
 * in advert->x.config_flags.  Typically this is because they export
 * their own window.  If an advert advertises more than one register
 * then they will be grouped under */

enum Uniregs_Config_Block16_Block31 {
  uniregs_codeseq = 1 | UNIREGS_IS_DEFINITIVE_MASK,
  /* the thing registering performs a codeseq, note that this need not
     be a general codeseq but one specificly geared to copro access */

  uniregs_core    = 3 | UNIREGS_IS_DEFINITIVE_MASK,
  /* the thing registering is the core */

  uniregs_copro           = 5, /* non-chainable coprocessor */
  uniregs_chainable_copro = 7  /* the copro can chain */
};

/*
 * Block uniregs_cycle_counter
 *
 * This block is for cycle counters to advertise their willingness to
 * provide cycle-counts.
 *
 * Because of the importance of cycle counters in RVD for profiling
 * this should be cycle counters that would have meaning.  Thus an
 * I-cycle counter should not go here.  What will happen is that
 * services that need a cycle counter will, during advert negotiation,
 * search this list for a cycle counter, by virtue of it being sorted
 * then it will pick the first one that applies to it.  At the moment
 * this will simply pick the topmost as we don't support multi-cores
 * but in the future should check that their cores correspond.
 *
 * As the absolute register number used in RVD is not exposed then we
 * have to walk the co_container to find the number.  The comparison
 * is done on handle_for_function, _SimReg and start_reg_number.
 * While it is not impossible to define more than one cycle counter
 * with the single advert, only the first will be taken and the rest
 * will be available to the user but will not be used to count
 * cycles.
 *
 * Cycle counters are assumed to have the properties SIMFLG_CYCLES |
 * SIMFLG_CYC_REAL | SIMFLG_CYC_ALWAYS | SIMFLG_CYC_OFFSET (in
 * simabs.h).  In the future we may allow support for other than this,
 * but at the moment this is hardwired in SimRdi_Manager.
 *
 * For information to help people choose the sort number in x.config_flags
 * record what values you use here:
 *    armulext/SimabsMemCallback -- uniregs_cycle_counter -- 0xF
 *                               -- currently assumes that it is the
 *                               -- master cycle counter.  It will have to
 *                               -- be modified if it is not.  */

#endif /* UNIREGS_REGISTRATION_EVENT_H */

⌨️ 快捷键说明

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