📄 mini_simrdi_manager.h
字号:
/*
* Copyright (C) ARM Ltd. 2002. All rights reserved.
*/
/*
* mini_simrdi_manager.h
*
* this is the interface that simabs-aware modules should talk to.
*
* RCS $Revision: 1.1.4.6.136.1 $
* Checkin $Date: 2003/05/02 16:46:36 $
* Revising $Author: dsinclai $
*/
#ifndef MINI_SIMRDI_MANAGER_H
#define MINI_SIMRDI_MANAGER_H
/* tell the RDI headers what version we talk */
#ifdef RDI_VERSION
#if RDI_VERSION != 151
#error "There is no support for RDI versions != 151"
#endif
#else
#define RDI_VERSION 151
#endif
#include "rdi.h"
#include "rdi_hif.h"
#include "rdi_err.h"
#include "rdi_armul.h"
#include "host.h"
#include "uniregs_registration_event.h"
#ifdef _SIMABS_H
/* if we have simabs.h, this can't be the rebuild kit */
#ifndef NON_REBUILD_KIT
#define NON_REBUILD_KIT
#endif /* NON_REBUILD_KIT */
#endif /* _SIMABS_H */
#ifdef NON_REBUILD_KIT
#include "simabs.h"
/* if we are SimRdi_Manager then we need some extra types */
#endif /* NON_REBUILD_KIT */
#ifndef NON_REBUILD_KIT
/* If part of the rebuild kit, then we wrap SIMABS so you don't have
to see it. But we still need some definitions from it. */
typedef enum
{ /* case of register name */
EECHGCASE_NOT, /* no case processing required */
EECHGCASE_UP, /* lower defined, make an upper one */
EECHGCASE_DOWN /* upper defined, make a lower one */
} EECHGCASE;
#define EECHGCASE uint8
/* used for register definitions */
typedef enum
{
TYPE_STRUCT_UNION,
TYPE_SIGNED_CHAR = 2,
TYPE_UNSIGNED_CHAR,
TYPE_SIGNED_SHORT_INT,
TYPE_UNSIGNED_SHORT_INT,
TYPE_SIGNED_LONG,
TYPE_UNSIGNED_LONG,
TYPE_SIGNED_LONG_LONG,
TYPE_UNSIGNED_LONG_LONG,
TYPE_FLOAT = 10,
TYPE_DOUBLE,
TYPE_LONG_DOUBLE,
TYPE_POINTER_TO_HOST = 14,
TYPE_INSTRUCTION_ADDRESS
/* NOTE: maximum number of types is 31 */
} REGISTER_TYPE;
#define REGISTER_TYPE uint8
/* simulator-models should only ever add registers using the char,
int, long types */
typedef struct REG_WIN RegWin;
typedef void* SIM_HANDLE;
typedef uint32 SIM_ERR;
/* return these as values for SIM_ERR */
#define SIM_OK 0
#define SIM_REGISTER_ACCESS 8
/* REG_WIN is used to describe a register window tab groups. It is
used to define register window lines to add. The tab name is:
<short name on tab>,<longer tooltip name>
Each line will contain a comma sep list of register names to show.
Their button name will be used (defined in the register
adverts). If the line starts with '=', the line will use the
Button=text, else just the value will appear. If a line starts with
'_', it will show as a label line (not active).
A line of '$-' means mark as an expansion group (default open, if
"$+" the default closed), the following "_<label>" line names it.
Button names should be padded with space if you want a tabular
format that lines up, we suggest 14 characters is a reasonable
packing width. */
struct REG_WIN
{
char *tab_name;
uint16 line_cnt; /* number of lines */
uint16 enum_cnt; /* reserved -- set to 0 */
char **lines; /* array of lines */
char **enum_list; /* reserved -- set to NULL */
};
/* sometimes people use these */
typedef uint8 UINT8;
typedef uint16 UINT16;
typedef uint32 UINT32;
/* copied from allant/xrywin/common/hostport.h */
/*
Due to the cornucopia of definitions of Boolean, and we don't want
to include the hostport.h file. We have made Boolean unusable.
*/
typedef struct { char do_not_use; } Boolean;
#include "tmgrem.h"
/* if part of the rebuild kit we are only interested in the stop
reasons in this file */
typedef int SimabsMemoryCallback( SIM_HANDLE *handle, MEMACC_TYPE type,
uint32 page, uint32 address, uint32 len,
uint32 curr_count, uint8 *buffer);
#endif /* _SIMABS_H */
/*
The model we have for interaction is:
Debugger <-> (transport layer) <->
[ single process
REMSIM <-> (SIMABS interface) <->
SimRdi_Manager <-- (SimRdiProcVec interface) <--
--> (Custom interface) -->
--> (RDI) -->
Module (dynamically loaded)
]
REMSIM talks SIMABS to the SimRdi_Manager which mediates the
interactions between the RDI target and REMSIM. SIMABS aware
modules get an extra interface to SimRdi_Manager called
SimRdiProcVec that is broadcast to all modules by
ARMulif_BroadcastSimRdiRegistration().
Simabs-aware modules will use the methods in SimRdiProcVec to
register with the SimRdi_Manager and should store a pointer to
SimRdiProcVec in their own state. All subsequent communication
involving Simabs features will be through this channel rather than
RDI calls.
SimRdi_Manager builds up a database of modules that can perform
a certain feature of the SIMABS interface. For example, when REMSIM
calls SimRdi_Manager to register a certain callback:
1) search the database for those module that have advertised their
interest in this callback
2) call each of these modules with the callback into REMSIM (using
the interface that the module gave at registration time)
3) the module alters its state such that next time it sees an event
that REMSIM was interested in then it calls the callback to REMSIM.
The module can alter the state of SimRdi_Manager through the
SimRdiProcVec.
4) when REMSIM has had enough it will call SimRdi_Manager to
deregister the REMSIM callback.
5) SimRdi_Manager uses its database to inform the modules of the
change and the modules should no longer do the callback.
Modules register their abilities by asking the SimRdiProcVec for a
new advert structure that SimRdi_Manager allocates and fills in
various fields. The module then fills out the advert and advertises
it to the SimRdi_Manager. This is also scalable in the sense that
new fields can be appended to the advert structure and modules that
are not aware of them will not fill them in and SimRdi_Manager can
detect this.
It is up to SimRdi_Manager whether it accepts a module's advert for
a callback. SimRdi_Manager even if it accepts a module's advert, it
may not call it when REMSIM asks for a particular method. However,
in the case of callbacks then, if it turns on a simabs-callback then
it will always deregister it when REMSIM is no longer interested.
By using adverts as a way of advertising capabilities, we could let
the list of adverts be available to modules to query to see if they
can implement a particular functionality that depends on another
capability being available.
When you ask for an advert then the returned advert has an Advert_ID
field. This is used to uniquely identify the advert. Once you have
advertised the advert then you may not access it again without
explicitly being given the address of it. This will allow
SimRdi_Manager to implement the advert container in anyway it feels
like, however it will give you an Advert_ID to let you refer to the
advert again, typically when destroying the advert.
For future expansion I have put in some extra fields (but not code!)
called SimRdi_Noticeboard_Change. The idea is that the registration
process occurs in multiple passes. The first is as above -- a
module registers all capabilities it can. If a particular
capability is dependent on another module advertising a service then
it should not check that module exists at the moment but post
anyway. Once all modules have had the UserEvent_Registration, then
all adverts with a non-NULL 'notice' member are called. This lets
the modules examine what other modules are available. If it notices
that another module implements its functionality in a better way, or
that a module that it depends on does not exist then it should
deregister itself and return false. The process is repeated until
all adverts return true (or a maximum number of times). Modules
should only ever deregister themselves, adding new capabilities
might lead to a non-terminating behaviour.
The code for this has not been written yet, as we have no modules
that depend in such a manner, and the protocol and a general
iterator format will be defined then, the above is just a suggestion
and the 'notice' member is just provisional.
*/
/*** error codes returns by SimRdiProcVec and registration methods ***/
typedef enum tag_simrdi_err {
SimRdi_Err_ok,
SimRdi_Err_not_available,
SimRdi_Err_already_registered,
SimRdi_Err_cant_attach_callback
} SimRdi_Err;
struct tag_simrdiprocvec;
/* typedef struct tag_simrdiprocvec SimRdiProcVec; // in registration_event.h */
/*** Memory callback capability ***/
/*
during the advertising stage, the module passes this structure to SimRdi_Manager
to advertise its interest in the event.
*/
typedef int RemSim_Callback(SIM_HANDLE*);
typedef struct tag_simrdi_advert_base SimRdi_Advert_Base;
typedef struct tag_simrdi_Callback_Advert SimRdi_Callback_Advert;
typedef SimRdi_Err SimRdi_Register_Callback( SimRdi_Callback_Advert* advert,
RemSim_Callback* remsim_callback );
/* remsim_callback is in the remsim module. The actual arguments are
dependent on the callback but can't be type-checked as SIMABS has a
single entry for all. */
enum NoticeBoardEvent {
simrdi_notice_destroy, /* the advert is about to be destroyed by SimRdi_Manager */
simrdi_notice_noticeboard_changed,
simrdi_notice_you_are_the_counter /* tell the advert that it is the master
counter */
};
typedef bool_int SimRdi_Notice( SimRdiProcVec* srpv, SimRdi_Callback_Advert* advert,
enum NoticeBoardEvent event, uint32 arg1, void* arg2 );
/*
* Adverts (Base advert)
*
* A SIMABS-aware module will ask the SimRdi_Manager through the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -