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

📄 sys.c

📁 ARM入门的好帮手.包含了从简单到相对较复杂的程序.
💻 C
📖 第 1 页 / 共 2 页
字号:
/*> sys.c <*//*---------------------------------------------------------------------------*//* * Target _sys_ function definitions * * $Revision: 1.13.6.5 $ *   $Author: rivimey $ *     $Date: 1997/12/19 15:54:55 $ * * Copyright Advanced RISC Machines Limited, 1995. * All Rights Reserved *//****************************************************************************  These are functions needed by the C Library.  They are implemented by  sending messages to the host.  The message format is defined in sys.h, see  also channels.h.  They are not linked into an application but  called indirectly via a veneer and an undefined instruction trap. This  calls SysLibraryHandler which in turn calls the relevant routine.  The veneers package up their arguments and pass them to the handler.  Strings are passed along with their lengths. This aoids needed a strlen  function inside the Angel system. It does use its own __rt_memcpy routine  though.****************************************************************************//****************************************************************************     BE VERY CAREFUL IN THIS MODULE TO RESPECT THE ENDIANNESS OF VALUES     In particular:           - all values passed to _sys_ functions, excepting sys_writec and        sys_write0, are in little endian form.      - values passed to SysLibraryHandler are raw target registers, and        are thus in target endianness. Embedded ICE therefore can't access        these locations directly.                sys_writec and sys_write0 use target-endianness parameters.      - Values palaced in packets (e.g. via sys_build_transaction) MUST be        in little endian form.      - Embedded ICE can be assumed to be running in little endian mode. ****************************************************************************/#include <stdarg.h>#include "angel.h"#include "adp.h"#include "arm.h"#include "logging.h"#include "msgbuild.h"    /* General support functions for message handling */#include "support.h"#include "time.h"#include "sys.h"#include "endian.h"#include "debug.h" #include "stacks.h"#ifdef ICEMAN_LEVEL_3#  include "debugos.h"          /* angelOS_MemRead()/Write() */#endif#define FILEHANDLE int/* * External function prototypes not in .h files *//* These should be from bytesex.h but that uses host.h! */int32 bytesex_hostval(int32 v);#ifdef ICEMAN2static unsigned target_top_of_memory = (512 * 1024);#endif#ifdef TRUEstatic word bytes_transferred;/* we need to use MemRead and MemWrite to access target memory */# define MEMCPY_FROM_TARGET( d, s, l )                                  \         angelOS_MemRead( -1, -1, (word)(s), (word)(l), (byte *)(d),        \                         &bytes_transferred )# define MEMCPY_TO_TARGET( d, s, l )                                    \         angelOS_MemWrite( -1, -1, (word)(d), (word)(l), (byte *)(s),       \                         &bytes_transferred )#else/* we can just use __rt_memcpy to access target memory */# define MEMCPY_FROM_TARGET( d, s, l )  __rt_memcpy( (d), (s), (l) )# define MEMCPY_TO_TARGET( d, s, l )    __rt_memcpy( (d), (s), (l) )/* and __rt_strlen to implement strlen() */#endifstatic int sys_handler_running=0;static int _sys_do_transaction(p_Buffer request, unsigned req_len,                               p_Buffer *reply,                               word expectedReason, word *data){    p_Buffer rbuff = request;    word reasoncode, DebugID, OSInfo1, OSInfo2;    ChanError err;    err = angel_ChannelSendThenRead(CH_DEFAULT_DEV, CI_CLIB, &rbuff, &req_len);    if (err == CE_OKAY)    {        unpack_message(BUFFERDATA(rbuff), "%w%w%w%w%w",  &reasoncode,                       &DebugID, &OSInfo1, &OSInfo2, data);        if (reasoncode == expectedReason)        {            if (reply==NULL)                angel_ChannelReleaseBuffer(rbuff);            else                *(p_Buffer *)reply=rbuff;            return 0;        }        else        {            LogWarning(LOG_SYS, ("_sys_do_transaction: unexpected reason %d\n", reasoncode));            angel_ChannelReleaseBuffer(rbuff);            return -1;        }    }    LogWarning(LOG_SYS, ("SendThenRead failed %d\n", err));    return -1;}static int _sys_build_and_transact(p_Buffer *reply, word expectedReason,                                   word *data,                                   char *format, ...){    va_list    args;    p_Buffer   request;    unsigned   length;    request = angel_ChannelAllocBuffer( Angel_ChanBuffSize );    if (request != NULL)    {        va_start( args, format );        length = vmsgbuild( BUFFERDATA(request), format, args );        va_end( args );        return _sys_do_transaction( request, length, reply,                                    expectedReason, data );    }    else    {        LogWarning(LOG_SYS, ("_sys_build_and_transact: no build buffer\n"));        return -1;    }}/* Open file 'name' in mode 'openmode'. */static FILEHANDLE _sys_open(const char *name, int openmode, int namelen){    /* note openmode translation from char to int must have taken place     * earlier on */    int count;    p_Buffer pbuff;    FILEHANDLE handle;    pbuff = angel_ChannelAllocBuffer(Angel_ChanBuffSize);    if (pbuff!=NULL) {        count = msgbuild(BUFFERDATA(pbuff),"%w%w%w%w%w", CL_Open|TtoH,                         0, ADP_HandleUnknown, ADP_HandleUnknown, namelen);        MEMCPY_FROM_TARGET((char *)BUFFERDATA(pbuff)+count, name,namelen+1);        count += namelen+1;  /* allow for trailing NULL */        PUT32LE((BUFFERDATA(pbuff)+count), openmode);        count+=4;        if ( _sys_do_transaction(pbuff, count,                                 NULL,                                 CL_Open|HtoT, (word *)&handle) )            return -1;        else            return handle;    }    return -1;}/* Close file associated with 'fh'. */static int _sys_close(FILEHANDLE fh){    int status;    if (_sys_build_and_transact(NULL, CL_Close|HtoT, (word *)&status,                                "%w%w%w%w%w", CL_Close|TtoH,                                0, ADP_HandleUnknown, ADP_HandleUnknown, fh))        return -1;    else        return status;}/* * this routine makes the CL_WriteC Clib request; 'data' is a TARGET MEMORY * pointer to the character to send (i.e. data[0] is the character required) */static int _sys_writeC(unsigned char *data){    int      status;    unsigned char ch = 0;    if (data != NULL)    {        /* copy the character to local variable ch */        MEMCPY_FROM_TARGET((char *)&ch, (char *)data, 1);        /* send that byte as the argument to CL_WriteC */        if (_sys_build_and_transact(NULL, CL_WriteC|HtoT, (word *)&status,                                    "%w%w%w%w%b",                                    CL_WriteC|TtoH, 0,                                    ADP_HandleUnknown, ADP_HandleUnknown,                                    ch))            return -1;        else            return status;    }    else        return -1;}/* * this routine makes the CL_Write0 Clib request; 'data' is a TARGET MEMORY * pointer to the string to send (i.e. data[0] is the first character of the * string), and the string is null terminated. * * NOTE: Various pieces of documentation say SWI write0 takes a pointer * to a pointer to a string... this *was* correct but is no longer so. * * NOTE2: The documentation does not state what the behavoiour for long * (>240ish) byte strings is. prior to this change, they would have corrupted * someother buffer, with possibly bad consequences; now, multiple CL_Write0 * packets are sent. */static int _sys_write0(unsigned char *data){    int totlen;    /* Max number of chars which will fit in a buffer, excluding     * the zero terminator. 5 * 4 is the number of bytes in the     * header, '-1' is to allow for null termination.     */    const int maxlen = (Angel_ChanBuffSize - (5 * 4)) - 1;    int count, status;    int len;    int left;    if (data != NULL)    {        #ifdef ICEMAN2        int atend = FALSE;        char buf[16], *p;                /* implement strlen() for strings in TARGET memory. We need to know the         * length of the string before we copy any of it to a packet buffer,         * hence this code (otherwise we could have copied the whole string         * only once).         */        totlen = 0;        while(!atend)        {            MEMCPY_FROM_TARGET(buf, (char *)data + totlen, sizeof(buf));            for(p = buf; p < (buf + sizeof(buf)); p++)            {                if (*p == '\0')                {                    atend = TRUE;                    break;                }                totlen++;            }        }#else        /*         * For direct angel, we can just do it the traditional way...         */        totlen = __rt_strlen((char*)data);#endif                left = totlen;        status = 0;                while (left > 0)        {            char *string;            p_Buffer pbuff;            /* make len the number of chars we'll print with this write;             * subtracting it from 'left' gives the number still to go.             */            len = (left >= maxlen) ? maxlen : left;            left = left - len;            pbuff = angel_ChannelAllocBuffer(Angel_ChanBuffSize);            if (pbuff == NULL)                return -1;            /* construct the basic message. the return value count should             * always be 20 (5 words at 4 bytes/word)             */            count = msgbuild(BUFFERDATA(pbuff), "%w%w%w%w%w", CL_Write0|TtoH,                             0, ADP_HandleUnknown, ADP_HandleUnknown, len);            /* this is the start address of the string space in the packet.             * copy from target memory at 'data' to this packet, zero             * terminating the result.             */            string = (char*)(BUFFERDATA(pbuff)+count);            MEMCPY_FROM_TARGET(string, (char *)data, len);                        string[len] = '\0';            count += len+1;                        /* adjust 'data' to point to the next 'chunk' of string (if any) */            data += len;                                    /* if this call returns 0, we're ok... carry on. If non-zero,             * there's been a comms error, and we return without further ado.             */            if (_sys_do_transaction(pbuff, count, NULL,                                    CL_Write0|HtoT, (word *)&status))                return -1;                    }        return status;    }    return -1;}/* Write 'len' characters of 'buf' to file associated with 'fh' in 'mode'   Returns the number of characters NOT written, i.e. 0==NoError.           *//* Mode:  not passed on. It was not passed on in the Demon SWI World either.   So it looks like remnant of some earlier OS *//* assumes len is no of bytes rather than words, doesn't check that its   right */static int _sys_write(FILEHANDLE fh, const unsigned char *buf, unsigned len){    unsigned int msglen;    unsigned int nbytes;    p_Buffer pbuff, rbuff;    unsigned int bufp=0;    word status;    int expectedReason;    unsigned int lenToSend;#define SYS_PROTOCOL_OVERHEAD (4*4)#define MAX_DATA_IN_WRITE  (Angel_ChanBuffSize - SYS_PROTOCOL_OVERHEAD - 3*4)#define MAX_DATA_IN_WRITEX (Angel_ChanBuffSize - SYS_PROTOCOL_OVERHEAD - 4)    pbuff = angel_ChannelAllocBuffer(Angel_ChanBuffSize);    if (pbuff!=NULL) {        lenToSend = len > MAX_DATA_IN_WRITE ? MAX_DATA_IN_WRITE : len;        expectedReason =  CL_Write | HtoT;        msglen = msgbuild(BUFFERDATA(pbuff), "%w%w%w%w%w%w%w", CL_Write |TtoH,                          0, ADP_HandleUnknown, ADP_HandleUnknown, fh, len,                          lenToSend);        LogInfo(LOG_SYS, ("CL_Write: total %d this %d\n", len, lenToSend));        do {            MEMCPY_FROM_TARGET(BUFFERDATA(pbuff)+msglen, &buf[bufp], lenToSend);            bufp += lenToSend;            len  -= lenToSend;            if (_sys_do_transaction(pbuff, msglen+lenToSend,                                    &rbuff, expectedReason, &status) )                return -1;            nbytes = GET32LE(BUFFERDATA(rbuff)+20);            angel_ChannelReleaseBuffer(rbuff);            if (status)                return status;            if (len > 0) {                pbuff = angel_ChannelAllocBuffer(Angel_ChanBuffSize);                if (pbuff == NULL)                    return -1;                lenToSend = len > MAX_DATA_IN_WRITEX ? MAX_DATA_IN_WRITEX : len;                expectedReason =  CL_WriteX | HtoT;                msglen = msgbuild(BUFFERDATA(pbuff), "%w%w%w%w%w",                                  CL_WriteX |TtoH, 0, ADP_HandleUnknown,                                  ADP_HandleUnknown,  lenToSend);                LogInfo(LOG_SYS, ("CL_WriteX: %d of %d\n", lenToSend, len));            }        } while (len > 0);        return nbytes;    }    else return -1;}/* ReadC reads a byte from the debugger console */static int _sys_readc(void){    int status;    p_Buffer rbuff;    int ret_code;    if (_sys_build_and_transact(&rbuff, CL_ReadC|HtoT, (word *)&status,                                "%w%w%w%w", CL_ReadC|TtoH,                                0, ADP_HandleUnknown, ADP_HandleUnknown))        return -1;    else    {        if (status)            ret_code = status;        else            ret_code = GET8(BUFFERDATA(rbuff)+20);        angel_ChannelReleaseBuffer(rbuff);        return ret_code;    }}/* Read 'len' characters of 'buf' from file associated with 'fh' in 'mode'.   Returns the number of characters NOT read, i.e. 0==NoError.              *//* Note: Assumes that buf is large enough to hold the number of bytes read */static int _sys_read(FILEHANDLE fh, unsigned char *buf, unsigned len,                     int mode){    unsigned int nread , nbtotal,nbmore, nbytes, status, notread;    p_Buffer rbuff;    IGNORE(mode);    if (_sys_build_and_transact(&rbuff, CL_Read|HtoT, &status,                                "%w%w%w%w%w%w", CL_Read|TtoH,                                0, ADP_HandleUnknown, ADP_HandleUnknown,                                fh, len))    {        LogInfo(LOG_SYS, ("_sys_read: Error on CL_Read: status %d\n", status));        return -1;    }    else {        unpack_message(BUFFERDATA(rbuff)+20, "%w%w", &nbytes, &nbmore);

⌨️ 快捷键说明

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