📄 sys.c
字号:
LogInfo(LOG_SYS, ("_sys_read: CL_Read: status %d, nbytes %d. nbmore %d\n", status, nbytes, nbmore)); nbtotal = nbytes+nbmore; notread = len - nbytes; nread = nbytes; if (status == 0) MEMCPY_TO_TARGET(buf, BUFFERDATA(rbuff)+28, nbytes); angel_ChannelReleaseBuffer(rbuff); if (status) return (notread|0x80000000); while(nread<nbtotal) { LogInfo(LOG_SYS, ("_sys_read: CL_ReadX\n")); if (_sys_build_and_transact(&rbuff, CL_ReadX|HtoT, &status, "%w%w%w%w", CL_ReadX|TtoH, 0, ADP_HandleUnknown, ADP_HandleUnknown)) return -1; else { unpack_message(BUFFERDATA(rbuff)+20, "%w%w", &nbytes, &nbmore); notread = nbmore; if (status == 0) MEMCPY_TO_TARGET(buf+nread, BUFFERDATA(rbuff)+28, nbytes); nread += nbytes; angel_ChannelReleaseBuffer(rbuff); if (status) return (notread|0x80000000); } } LogInfo(LOG_SYS, ("_sys_read: returning notread: %d\n", notread)); /* Return number of bytes unread */ return notread; }}/* Return TRUE if status value indicates an error. */static int _sys_iserror(int status){ if (status == -1) return TRUE; else return FALSE;}/* Returns non-zero if the file is connected to an interactive device. */static int _sys_istty(FILEHANDLE fh){ int status; if (_sys_build_and_transact(NULL, CL_IsTTY|HtoT, (word *)&status, "%w%w%w%w%w", CL_IsTTY|TtoH, 0, ADP_HandleUnknown, ADP_HandleUnknown, fh)) return -1; else return status;}/* Seeks to position 'pos' in the file associated with 'fh'. Returns a negative value if there is an error, otherwise >=0. */static int _sys_seek(FILEHANDLE fh, long pos){ int status; if (_sys_build_and_transact(NULL, CL_Seek|HtoT, (word *)&status, "%w%w%w%w%w%w", CL_Seek |TtoH, 0, ADP_HandleUnknown, ADP_HandleUnknown, fh, pos)) return -1; else return status;}/* Flushes any buffers associated with fh and ensures that the file is up to date on the backing store medium. The result is >=0 if OK, negative for an error. */static int _sys_ensure(FILEHANDLE fh){ IGNORE(fh); return -1;}/* Returns length of the file fh ( or a negative error indicator). */static long _sys_flen(FILEHANDLE fh){ long length; if (_sys_build_and_transact(NULL, CL_Flen|HtoT, (word *)&length, "%w%w%w%w%w", CL_Flen |TtoH, 0, ADP_HandleUnknown, ADP_HandleUnknown, fh)) return -1; else return length;}/* Returns the name for a temporary file number fileno in the buffer name *//* NOTE: header unclear leave atm */static int _sys_tmpnam(char *name, int sig, unsigned maxlen){ p_Buffer rbuff; int status, namlen; if (_sys_build_and_transact(&rbuff, CL_TmpNam|HtoT, (word *)&status, "%w%w%w%w%w%w", CL_TmpNam |TtoH, 0, ADP_HandleUnknown, ADP_HandleUnknown, maxlen, sig)) return -1; if (status == 0) { namlen = PREAD(LE,(word *)(BUFFERDATA(rbuff)+20)); MEMCPY_TO_TARGET(name, BUFFERDATA(rbuff)+24, namlen); } angel_ChannelReleaseBuffer(rbuff); return status;}static int _sys_clock(void){ p_Buffer rbuff; int status, clks; if (_sys_build_and_transact(&rbuff, CL_Clock|HtoT, (word *)&status, "%w%w%w%w", CL_Clock |TtoH, 0, ADP_HandleUnknown, ADP_HandleUnknown)) return -1; if (status) clks = -1; else clks = PREAD(LE,(word *)(BUFFERDATA(rbuff)+20)); angel_ChannelReleaseBuffer(rbuff); return clks;}static time_t _sys_time(void){ p_Buffer rbuff; int status; time_t time; if (_sys_build_and_transact(&rbuff, CL_Time|HtoT, (word *)&status, "%w%w%w%w", CL_Time |TtoH, 0, ADP_HandleUnknown, ADP_HandleUnknown)) return -1; if (status) time = -1; else time = PREAD(LE,(word *)(BUFFERDATA(rbuff)+20)); angel_ChannelReleaseBuffer(rbuff); return time;}static int _sys_system(unsigned char *name, int namelen){ p_Buffer pbuff, rbuff; int status, data, count; if (name == NULL) return 0; /* NULL line do nothing */ pbuff = angel_ChannelAllocBuffer(Angel_ChanBuffSize); if (pbuff!=NULL) { count = msgbuild(BUFFERDATA(pbuff),"%w%w%w%w%w", CL_System|TtoH, 0, ADP_HandleUnknown, ADP_HandleUnknown, namelen); MEMCPY_FROM_TARGET((char *)BUFFERDATA(pbuff)+count, name, namelen+1); count += (namelen+1); /* allow for trailing NULL */ if (_sys_do_transaction(pbuff, count, &rbuff, CL_System|HtoT, (word *)&status)) return -1; data = GET32LE(BUFFERDATA(rbuff)+20); angel_ChannelReleaseBuffer(rbuff); if (status) return status; else return data; } return -1;}static int _sys_remove(unsigned char *name, int namelen){ p_Buffer pbuff; int status,count; pbuff = angel_ChannelAllocBuffer(Angel_ChanBuffSize); if (pbuff!=NULL) { count = msgbuild(BUFFERDATA(pbuff),"%w%w%w%w%w", CL_Remove|TtoH, 0, ADP_HandleUnknown, ADP_HandleUnknown, namelen); MEMCPY_FROM_TARGET((char *)BUFFERDATA(pbuff)+count, name, namelen+1); count += (namelen+1); /* allow for trailing NULL */ if ( _sys_do_transaction(pbuff, count, NULL, CL_Remove|HtoT, (word *)&status)) return -1; else return status; } return -1;}static int _sys_rename(unsigned char *oldname, int oldnamelen, unsigned char *newname, int newnamelen){ p_Buffer pbuff; int status, count, count2; pbuff = angel_ChannelAllocBuffer(Angel_ChanBuffSize); if (pbuff!=NULL) { count = msgbuild(BUFFERDATA(pbuff),"%w%w%w%w%w", CL_Rename|TtoH, 0, ADP_HandleUnknown, ADP_HandleUnknown, oldnamelen); MEMCPY_FROM_TARGET((char *)BUFFERDATA(pbuff)+count, oldname,++oldnamelen); count += oldnamelen; /* allow for trailing NULL */ count2 = count; PUT32LE((char *)(BUFFERDATA(pbuff)+count), newnamelen); count+=4; MEMCPY_FROM_TARGET((char *)BUFFERDATA(pbuff)+count, newname,++newnamelen); count +=newnamelen; if (_sys_do_transaction(pbuff, count, NULL, CL_Rename|HtoT, (word *)&status)) return -1; else return status; } return -1;}static int _sys_getcmdline(unsigned char *cmdline){ p_Buffer rbuff; int status, cmdlen; if (_sys_build_and_transact(&rbuff, CL_GetCmdLine|HtoT, (word *)&status, "%w%w%w%w", CL_GetCmdLine|TtoH, 0, ADP_HandleUnknown, ADP_HandleUnknown)) return -1; if (status == 0) { cmdlen = PREAD(LE,(word *)(BUFFERDATA(rbuff)+20)); /* overwrite buffer, but that's okay */ ((char *)BUFFERDATA(rbuff))[24+cmdlen] = '\0'; MEMCPY_TO_TARGET(cmdline,(char *)BUFFERDATA(rbuff)+24, cmdlen+1); } angel_ChannelReleaseBuffer(rbuff); return status;}/* Put the following data into the datablock passed to us: * datablock[0] = heap base * datablock[1] = heap limit * datablock[2] = stack base * datablock[3] = stack limit */static int _sys_heapinfo(unsigned *datablock){#ifdef ICEMAN2# define TARGET_STACK_SIZE (16*1024) unsigned tmp_data[4]; tmp_data[0] = 0; /* This means use the end of the image as heap base*/ tmp_data[1] = bytesex_hostval(target_top_of_memory - TARGET_STACK_SIZE); tmp_data[2] = bytesex_hostval(target_top_of_memory); tmp_data[3] = bytesex_hostval(target_top_of_memory - TARGET_STACK_SIZE); MEMCPY_TO_TARGET((char *) datablock,(char *)tmp_data, 16);#else *(AngelHeapStackDesc *)datablock = angel_heapstackdesc;#endif return (int) datablock;}/* * The main decoder for the C library support routines... * * sysCode is the Semihosting Call number for the SH SWI * r1 points at the args of the function. for details see sys.h * * Remember that r1 is a target address at this point; if running in * a memory space other than the target's (e.g. E-ICE), appropriate action * will have to be taken to get the data required from the target. * */#define MAX_ARGS 4static word RealSysLibraryHandler(unsigned int sysCode, word r1){#ifdef ICEMAN2 word argarray[MAX_ARGS];#endif int *args; LogInfo(LOG_SYS, ("RealSysLibraryHandler: code = 0x%x, r1 = 0x%x.\n", sysCode, r1)); if (boot_completed == 0) { LogWarning(LOG_SYS, ("RealSysLibraryHandler: Not booted -- unable to do semihosting!\n" )); return -1; } /* these operations do their own parameter management */ switch (sysCode) { case SYS_WRITEC: return _sys_writeC((unsigned char *)r1); case SYS_WRITE0: return _sys_write0((unsigned char *)r1); default: break; } /* grab the parameter list from the target for the functions below. */ if ( r1 != NULL ) {#ifdef ICEMAN2 int i; word count; /* r1 is in target memory, and we need a local memory pointer... copy * the args to local memory before passing them on. */ args = (int*)argarray; /* * Really, we ought to only fetch the appropriate number of args, * according to sysCode. But that's a chore and as the maximum is * only 4 words we can afford to get them all. There's a very small * chance that this will cause an illegal read in the target, but in * actual fact this seems pretty unlikely. */ angelOS_MemRead( -1, -1, r1, MAX_ARGS * 4, (byte *)args, &count ); /* If the TARGET is big endian we must byte-reverse these * words for little endian transmission to the host. */ for (i=0; i<MAX_ARGS ; i++) { args[i] = bytesex_hostval(args[i]); }#else /* for direct Angel, r1 is already a suitable pointer to the args. */ args = (int*)r1;#endif } switch (sysCode) { case SYS_OPEN: return _sys_open((char *)args[0], args[1], args[2]); case SYS_CLOSE: return _sys_close((FILEHANDLE)args[0]); case SYS_WRITE: return _sys_write((FILEHANDLE)args[0], (unsigned char *)args[1], (unsigned)args[2]); case SYS_READC: return _sys_readc(); case SYS_READ: return _sys_read((FILEHANDLE)args[0], (unsigned char *)args[1], (unsigned)args[2],args[3]); case SYS_ISTTY: return _sys_istty((FILEHANDLE )args[0]); case SYS_ENSURE: return _sys_ensure((FILEHANDLE )args[0]); case SYS_ISERROR: return _sys_iserror(args[0]); case SYS_SEEK: return _sys_seek((FILEHANDLE)args[0],(long)args[1]); case SYS_FLEN: return (word)_sys_flen((FILEHANDLE)args[0]); case SYS_TMPNAM: return _sys_tmpnam((char *)args[0],args[1], (unsigned) args[2]); case SYS_GET_CMDLINE: return _sys_getcmdline((unsigned char *)args[0]); case SYS_HEAPINFO: return _sys_heapinfo((unsigned *) args[0]); case SYS_RENAME: return _sys_rename((unsigned char *)args[0],args[1], (unsigned char *)args[2],args[3]); case SYS_REMOVE: return _sys_remove((unsigned char *)args[0],args[1]); case SYS_SYSTEM: return _sys_system((unsigned char *)args[0],args[1]); case SYS_TIME: return _sys_time(); case SYS_CLOCK: return _sys_clock(); default: LogWarning(LOG_SYS, ("RealSysLibraryHandler: Unknown Angel SWI called\n")); break; } return -1;}word SysLibraryHandler(unsigned int sysCode, word r1){ word retval; sys_handler_running = 1; retval = RealSysLibraryHandler(sysCode, r1); sys_handler_running = 0; return retval;}/* * This routine is called by Angel Startup to initialise the C library support * code. */void angel_SysLibraryInit(void){ sys_handler_running = 0; return;}#ifdef ICEMAN2void angel_SetTopMem(unsigned addr){ target_top_of_memory=addr;}#endifint Angel_IsSysHandlerRunning(void){ return sys_handler_running;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -