📄 semihost.c
字号:
if (osstate == NULL) {
Hostif_RaiseError(hostif,"OS_Init can't allocate state\n");
return RDIError_OutOfStore;
}
#ifdef VERBOSE_INIT
printf("\n* OS_Init, osstate = %p, coredesc.rdi=%p type:%u\n", osstate,
osstate->coredesc.rdi, type);
#endif
osstate->ErrorNo = 0;
osstate->CommandLine = NULL ;
osstate->simrdiprocvec = NULL;
osstate->os_verbose = ToolConf_DLookupBool(
config, (tag_t)"VERBOSE", TRUE);
osstate->os_Trace_OutPut = ToolConf_DLookupBool(
config, (tag_t)"TRACE_SEMIHOST_CONOUT", TRUE);
{ char const *option = ToolConf_Lookup(config,
(tag_t)"SEMIHOST_FILEOP_LOG");
if (option&& option[0])
state->os_file_log = fopen(option,"w");
}
#ifdef VERBOSE_SYS_FILE
osstate->verbose_sys_file = ToolConf_DLookupBool(
config, (tag_t)"VERBOSE_SYS_FILE", FALSE);
#endif
osstate->semihostingstate = SEMIHOSTSTATE_ENABLED;
osstate->sh_Bigend32 =
((type & RDIOpen_ByteSexMask) == RDIOpen_BigEndian);
osstate->Set_Endian =
((type & RDIOpen_ByteSexMask) != RDIOpen_DontCareEndian);
if (!osstate->Set_Endian)
{
char const *str_bytesex = ToolConf_Lookup(config, Dbg_Cnf_ByteSex);
osstate->sh_Bigend32 = (str_bytesex && str_bytesex[0] == 'B') ?
RDISex_Big : RDISex_Little;
osstate->Set_Endian = (str_bytesex && (str_bytesex[0] == 'B' ||
str_bytesex[0] == 'L'));
}
/* Only set the endianness if we don't have HWENDIAN=True */
osstate->Set_Endian &= !ToolConf_DLookupBool(
config,Dbg_Cnf_TargetHWEndian,FALSE);
/* And if we're boing asked for BE-8 mode... */
if (ToolConf_DLookupBool(osstate->config, ARMulCnf_HAS_BE8, FALSE) &&
ToolConf_DLookupBool(osstate->config, ARMulCnf_BIGEND_IS_BE8, FALSE))
{
/* In Pagetab, we also set MMU_EE and CPSR.E
* Here, we do nothing for now. */
osstate->Set_Endian = FALSE;
}
osstate->usersp = 0x80000000 ;
osstate->map.soft_vectors = ToolConf_DLookupUInt(
osstate->config, (tag_t)"AddrSoftVectors", 0xA40L) ;
osstate->map.soft_vec_code = ToolConf_DLookupUInt(
osstate->config, (tag_t)"SoftVectorCode", 0xB80L) ;
osstate->map.handlers = ToolConf_DLookupUInt(
osstate->config, (tag_t)"AddrsOfHandlers", 0xad0L) ;
osstate->map.cmd_line = ToolConf_DLookupUInt(
osstate->config, (tag_t)"AddrCmdLine", 0xf00L) ;
osstate->AngelEnabled = ToolConf_DLookupBool(osstate->config,
(tag_t)ARMulCnf_Angel, FALSE);
osstate->DemonEnabled = ToolConf_DLookupBool(osstate->config,
(tag_t)ARMulCnf_Demon, FALSE);
osstate->ExitSwisEnabled = osstate->DemonEnabled ||
ToolConf_DLookupBool(osstate->config,
(tag_t)"EXIT_SWIS", FALSE);
osstate->os_HaltOnUnknownAngelSwi = ToolConf_DLookupBool(config,
(tag_t)"HALTONUNKNOWNSYSNUMBER", FALSE);
osstate->os_CPUSpeed = ARMul_GetFCLK(osstate->config);
osstate->os_BusSpeed = ARMul_GetMCLK(osstate->config);
if (osstate->AngelEnabled || osstate->DemonEnabled ||
osstate->ExitSwisEnabled)
{
ARMulif_InstallUnkRDIInfoHandler(&osstate->coredesc,
OS_HandleUnkRDI,osstate);
ARMulif_InstallExceptionHandler(
&osstate->coredesc, OS_HandleException, osstate);
ARMulif_InstallEventHandler(
&osstate->coredesc, ConfigEventSel, OS_HandleEvent, osstate);
}
if (osstate->AngelEnabled) {
osstate->AngelSWIARM = ToolConf_DLookupUInt(osstate->config, (tag_t)ARMulCnf_AngelSWIARM, ANGEL_SWI_ARM) ;
osstate->AngelSWIThumb = ToolConf_DLookupUInt(osstate->config, (tag_t)ARMulCnf_AngelSWIThumb, ANGEL_SWI_THUMB) ;
osstate->heap_base = ToolConf_DLookupUInt(osstate->config, (tag_t)ARMulCnf_HeapBase, ANGEL_HEAPBASE) ;
osstate->heap_limit = ToolConf_DLookupUInt(osstate->config, (tag_t)ARMulCnf_HeapLimit, ANGEL_HEAPLIMIT) ;
osstate->stack_base = ToolConf_DLookupUInt(osstate->config, (tag_t)ARMulCnf_StackBase, ANGEL_STACKBASE) ;
osstate->stack_limit = ToolConf_DLookupUInt(osstate->config, (tag_t)ARMulCnf_StackLimit, ANGEL_STACKLIMIT) ;
Hostif_PrettyPrint(osstate->hostif, osstate->config, ", Semihosting");
if (osstate->os_verbose)
{
if (osstate->DemonEnabled)
Hostif_PrettyPrint(osstate->hostif, osstate->config,
"+DEMON");
if (osstate->AngelEnabled)
Hostif_PrettyPrint(osstate->hostif, osstate->config,
"+ANGEL");
}
}
if (osstate->DemonEnabled) {
ARMword value ;
value = ToolConf_DLookupUInt(osstate->config, (tag_t)ARMulCnf_AddrSuperStack, DEMON_ADDRSUPERSTACK) ; /* supervisor stack space */
ARMulif_SetReg(&osstate->coredesc, ARMulif_GetCPSR(&osstate->coredesc) & 0x1f,
13, value) ;
ARMulif_SetReg(&osstate->coredesc, ARM_MODE_V5_SVC32, 13, value) ;
value = ToolConf_DLookupUInt(osstate->config, (tag_t)ARMulCnf_AddrAbortStack, DEMON_ADDRABORTSTACK) ; /* abort stack space */
ARMulif_SetReg(&osstate->coredesc, ARM_MODE_V5_ABORT32, 13, value) ;
value = ToolConf_DLookupUInt(osstate->config, (tag_t)ARMulCnf_AddrUndefStack, DEMON_ADDRUNDEFSTACK); /* undef stack space */
ARMulif_SetReg(&osstate->coredesc, ARM_MODE_V5_UNDEF32, 13, value) ;
value = ToolConf_DLookupUInt(osstate->config, (tag_t)ARMulCnf_AddrIRQStack, DEMON_ADDRIRQSTACK) ; /* IRQ stack space */
ARMulif_SetReg(&osstate->coredesc, ARM_MODE_V5_IRQ32, 13, value) ;
value = ToolConf_DLookupUInt(osstate->config, (tag_t)ARMulCnf_AddrFIQStack, DEMON_ADDRFIQSTACK) ; /* FIQ stack space */
ARMulif_SetReg(&osstate->coredesc, ARM_MODE_V5_FIQ32, 13, value) ;
osstate->usersp = ToolConf_DLookupUInt(osstate->config, (tag_t)ARMulCnf_AddrUserStack, DEMON_ADDRUSERSTACK) ; /* default user stack start */
osstate->cmdlineaddr = ToolConf_DLookupUInt(osstate->config, (tag_t)ARMulCnf_AddrCmdLine, DEMON_ADDRCMDLINE) ; /* command line is here after a SWI GetEnv */
Hostif_PrettyPrint(osstate->hostif, osstate->config, ", Demon");
}
ARMulif_InstallEventHandler(&state->coredesc,
ConfigEventSel,
Angel_ConfigEvents, osstate);
ARMulif_InstallSimRdiRegistration( &state->coredesc,
OS_SimRdiListener,
osstate );
Time_PropDesc.gacb.handle = state;
ARMulif_AddProperty(&state->coredesc, RDIPropertyGroup_SuperGroup,
&Time_PropDesc);
#ifdef CPUTIME_HI
TimeHi_PropDesc.gacb.handle = state;
ARMulif_AddProperty(&state->coredesc, RDIPropertyGroup_SuperGroup,
&TimeHi_PropDesc);
#endif
Clock_PropDesc.gacb.handle = state;
ARMulif_AddProperty(&state->coredesc, RDIPropertyGroup_SuperGroup,
&Clock_PropDesc);
{
state->os_bUseRealTime = !ARMul_ClockIsEmulated(config);
if (osstate->os_verbose && state->os_bUseRealTime)
{
Hostif_PrettyPrint(osstate->hostif, osstate->config, " Clock=Real Time");
}
}
osstate->os_FakeTimeFrom = ToolConf_DLookupUInt(osstate->config, (tag_t)"FAKETIMEFROM", 0);
for (i = 0; i < FOPEN_MAX; i++) {
osstate->FileTable[i] = NULL;
osstate->FileCount[i] = 0;
}
for (i = 0; i < UNIQUETEMPS; i++)
osstate->tempnames[i] = NULL;
}
END_INIT(OS)
#define ADD_TO_NEW_TAB
#ifdef ADD_TO_NEW_TAB
#define FOE(a) OS_FreeOnExit(state,a)
/* Returns an allocated string, pre-FOE'd, (or NULL on out-of-memory). */
static char *make_enum_name(OSState *state)
{
(void)state;
return "OS_OffOn=Off,On";
}
static RegWin *new_RegWin(OSState *state)
{
RegWin *rw = (RegWin*)calloc(1,sizeof(RegWin));
if (rw != NULL)
{
unsigned i;
unsigned numr = sizeof(semihost_reg_defs)/sizeof(semihost_reg_defs[0]);
/* {{{ Fill in the RegWin fields. */
/* !Todo: Use the instance-name in case we have a multi-core system! */
rw->tab_name = "Semihost,Semihosting Information";
#define NUM_HEADER_LINES 0
rw->line_cnt = numr + NUM_HEADER_LINES;
rw->lines = (char**)FOE(calloc(rw->line_cnt,sizeof(char *)));
#define NUM_ENUMS 0
rw->enum_cnt = NUM_ENUMS;
rw->enum_list = NUM_ENUMS > 0 ? FOE(calloc(NUM_ENUMS,sizeof(char*))) : NULL;
if (NUM_ENUMS > 0)
{
rw->enum_list[0] = FOE(StrDup(make_enum_name(state)));
}
/* {{ Fill in Lines */
#if NUM_HEADER_LINES
rw->lines[0] = "_Name Value ";
#endif
for (i = 0; i < numr; i++)
{
char *str1;
if (rw->enum_cnt > 0 && strcmp(semihost_reg_defs[i].name, "@semihost_state") == 0)
{
str1 = StrMultiCat( "=", semihost_reg_defs[i].name, "=OS_OffOn", NULL);
}
else
{
str1 = StrMultiCat( "=", semihost_reg_defs[i].name, NULL);
}
rw->lines[i+ NUM_HEADER_LINES] = FOE(str1);
}
/* }} Fill in Lines */
/* }}} RegWin fields. */
}
return FOE(rw);
}
#endif
static void
OS_SimRdiListener( SimRdiRegistrationProcVec* srpv,
void* handle )
{
OSState *osstate = (OSState *)handle;
SimRdiProcVec* spv = srpv->simrdiprocvec;
SimRdi_Callback_Advert* advert;
if( srpv->number < 1
|| spv == NULL
|| spv->signature != SIMRDIPROCVEC_SIGNATURE
|| (spv->version.major) != 0x01
|| spv->null == NULL
|| spv->null->advertise == NULL
|| spv->null->c_new == NULL
)
{
return;
}
advert = spv->null->c_new(spv->null);
if( advert != NULL )
{
osstate->advert = advert->x.id;
osstate->simrdiprocvec = spv;
advert->x.name =
__FILE__ ": semi-hosting returns exit information through "
"stop_info";
advert->x.handle = osstate;
advert->x.coredesc = &osstate->coredesc;
advert->x.config_flags = semihosting_null_config_flag;
advert->simregistercallback = NULL;
#ifdef ADD_TO_NEW_TAB
advert->x.config_flags |= UNIREGS_DO_NOT_AUTO_GENERATE_REG_WIN;
#endif
spv->null->advertise( spv->null, advert );
}
/* add all funky semihosting stuff to the output pane */
{
SimRdi_Uniregs_Advert* ad =
spv->uniregs->c_new( spv->uniregs );
if( ad != NULL )
{
osstate->advert_regs = advert->x.id;
ad->x.name = "Semihosting information";
ad->x.handle = osstate;
ad->x.coredesc = &osstate->coredesc;
ad->description = "Semihosting Parameters";
ad->len = sizeof(semihost_reg_defs)/sizeof(semihost_reg_defs[0]);
#if 0 /* If you've got it... */
ad->block_num = uniregs_model_debugging_registers;
#else
/* ... Flaunt it! */
ad->block_num = uniregs_cycle_counter /*uniregs_extensions */;
#endif
ad->desc = semihost_reg_defs;
ad->handle_for_function = (void*)osstate;
ad->_SimReg = OS_SimReg;
ad->start_reg_number = 0;
#ifdef ADD_TO_NEW_TAB
/* Otherwise we add to predefined ad->block_num */
ad->x.config_flags |= UNIREGS_DO_NOT_AUTO_GENERATE_REG_WIN;
#endif
spv->uniregs->advertise( spv->uniregs, ad );
}
}
#ifdef ADD_TO_NEW_TAB
{
RegWin *rw = new_RegWin(osstate);
if (rw != NULL)
{
SimRdi_Regwin_Advert* ad =
spv->regwin->c_new( spv->regwin );
ad->regwin = rw;
osstate->os_ad_to_destroy = ad->x.id;
spv->regwin->advertise( spv->regwin, ad );
}
}
#endif
}
#define OS_State OSState
/*void OS_Exit(void *voidosstate)*/
int OS_Exit(RDI_AgentHandle agent)
{
OS_State *osstate = (OS_State *)agent;
unsigned i ;
if (osstate != NULL) {
if (osstate->CommandLine != NULL)
free((char *)(osstate->CommandLine));
for (i = 0; i < UNIQUETEMPS; i++)
if (osstate->tempnames[i] != NULL)
free(osstate->tempnames[i]);
if (osstate->os_file_log)
{
fclose(osstate->os_file_log);
}
if (osstate->simrdiprocvec)
{
if (osstate->simrdiprocvec->null->destroy)
{
osstate->simrdiprocvec
->null->destroy(osstate->simrdiprocvec->null,
osstate->advert);
}
#ifdef ADD_TO_NEW_TAB
if (osstate->simrdiprocvec->regwin->destroy)
{
osstate->simrdiprocvec->regwin->destroy(
osstate->simrdiprocvec->regwin,
osstate->os_ad_to_destroy);
}
#endif
}
free((char *)osstate);
}
return RDIError_NoError;
}
/* This is an RDI_InfoProc, so must validate its inputs */
static int OS_HandleUnkRDI(void *handle,
unsigned subcode,
ARMword *arg1, ARMword *arg2)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -