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

📄 debugos.c

📁 AT91所有开发板的资料 AT91所有开发板的资料
💻 C
📖 第 1 页 / 共 4 页
字号:
 *         These rules are fairly simple to understand and include the *         above requirements as a subset. *          *         Finally, the code must protect Angel from overwriting itself, *         and may thus refuse the request with a privilegde error if *         the requested address is in a protected region. *          *         This routine uses the volatile variables  *            memory_is_being_accessed   - flag to data abort handler *            memory_access_aborted      - count of data aborts caught *          *         The data abort handler is expected, when memory_is_being_accessed *         is non-zero, to increment the count of aborts found in *         memory_access_aborted whenever an abort occurs, returning to the *         *next* instruction. That is, this code requires that if data aborts *         are retried then when the handler returns the attempt *will* *         succeed; in this case, the aborted count should *not* be *         incremented. *          *    Params:  *       Input: *              OsInfo[12]  - unused; would be used for thread context etc *              Address     - the address in the target to write the data *              Nbytes      - the number of bytes to write *              DataArea    - where to get the data from *               *      Output:  *              BytesWritten- return of how many bytes were transferred * *   Returns: Error code: OK if memort transferred, DataAbort or Priviledge *                        error otherwise. */intangelOS_MemWrite(word OSinfo1, word OSinfo2, word Address, word Nbytes,                 byte * DataArea, word * BytesWritten){    int all_permitted;    IGNORE(OSinfo1);    IGNORE(OSinfo2);    /*     * If we detect that either the start or end of the area is not     * a permitted write area then give up immediately.     * Otherwise transfer the whole lot a byte (or word) at a time.     * This is preferable to transferring words due to a number of     * problesm: endianess and non alignment of data in target memory     * and/or the datablock.     */    all_permitted = (WRITE_PERMITTED(Address) &&                     WRITE_PERMITTED(Address + Nbytes - 1));    if (!all_permitted)    {        *BytesWritten = 0;        return RDIError_InsufficientPrivilege;    }    memory_is_being_accessed = 1;    memory_access_aborted = 0;    /*     * use halfword copy if addresses are halfword aligned but not     * word aligned and number of bytes is not odd     *     * use word copy if addresses are word aligned and copying integral number     * of words     *      *(((char *)Address) + c) = DataArea[c];     *     * otherwise, copy byte-by-byte.     *     */    if ((((int)DataArea | (int)Address | Nbytes) & 0x3) == 0)    {        int *swAddress = (int*)DataArea;        int *dwAddress = (int*)Address;        word Nwords = Nbytes >> 2;                while (Nwords >= 4)        {            *dwAddress++ = *swAddress++;            *dwAddress++ = *swAddress++;            *dwAddress++ = *swAddress++;            *dwAddress++ = *swAddress++;            Nwords -= 4;            /* check to see access was ok */            if (memory_access_aborted)                break;        }                switch(Nwords)        {            case 3:                *dwAddress++ = *swAddress++;                /*fallthrough*/            case 2:                *dwAddress++ = *swAddress++;                /*fallthrough*/            case 1:                *dwAddress++ = *swAddress++;                break;                            default:                /* could have 0 or > 3 words here... either way, do nothing */                break;        }        dwAddress -= memory_access_aborted;        *BytesWritten = (int)dwAddress - (int)Address;    }    else if ((((int)DataArea | (int)Address | Nbytes) & 0x1) == 0)    {        short *ssAddress = (short *)DataArea;        short *dsAddress = (short *)Address;        word Nshorts = Nbytes >> 1;        while (Nshorts >= 4)        {            *dsAddress++ = *ssAddress++;            *dsAddress++ = *ssAddress++;            *dsAddress++ = *ssAddress++;            *dsAddress++ = *ssAddress++;            Nshorts -= 4;            /* check to see access was ok */            if (memory_access_aborted)                break;        }        switch(Nshorts)        {            case 3:                *dsAddress++ = *ssAddress++;                /*fallthrough*/            case 2:                *dsAddress++ = *ssAddress++;                /*fallthrough*/            case 1:                *dsAddress++ = *ssAddress++;                break;                            default:                /* could have 0 or > 3 halfwords here... either way, do nothing */                break;        }        dsAddress -= memory_access_aborted;        *BytesWritten = (int)dsAddress - (int)Address;    }    else    {        char *sbAddress = (char *)DataArea;        char *dbAddress = (char *)Address;        while (Nbytes >= 4)        {            *dbAddress++ = *sbAddress++;            *dbAddress++ = *sbAddress++;            *dbAddress++ = *sbAddress++;            *dbAddress++ = *sbAddress++;            Nbytes -= 4;            /* check to see access was ok */            if (memory_access_aborted)                break;        }        switch(Nbytes)        {            case 3:                *dbAddress++ = *sbAddress++;                /*fallthrough*/            case 2:                *dbAddress++ = *sbAddress++;                /*fallthrough*/            case 1:                *dbAddress++ = *sbAddress++;                break;                            default:                /* could have 0 or > 3 bytes here... either way, do nothing */                break;        }        dbAddress -= memory_access_aborted;        *BytesWritten = (int)dbAddress - (int)Address;    }    memory_is_being_accessed = 0;#if CACHE_SUPPORTED    Cache_IBR((char *)Address, (char *)(Address + Nbytes - 1));#endif    return memory_access_aborted ? RDIError_DataAbort : RDIError_NoError;}/* *  Function: cpuread *   Purpose: Convenient function to read the next word from a byte buffer and *            then increment a counter appropriately * *    Params:  *       Input:  * *   Returns:  */static wordcpuread(byte * wd, int *c){    word w;    w = GET32LE(wd + *c);    *c += 4;    return (w);}/* *  Function: angelOS_MemWrite *   Purpose:  * *    Params:  *       Input:  * *   Returns:  */intangelOS_CPUWrite(word OSinfo1, word OSinfo2, word Mode, word Mask,                 byte * WriteData){    int i, c = 0;    angel_RegBlock *rb;    unsigned *r, cpsr;    IGNORE(OSinfo1);    IGNORE(OSinfo2);    LogInfo(LOG_DEBUGOS, ( "angelOS_CPUWrite: Mode = 0x%x, Mask = 0x%x.\n", Mode, Mask));    rb = Angel_AccessApplicationRegBlock();    if (rb == NULL)        return RDIError_Error;    cpsr = rb->cpsr;        if (Mode == ADP_CPUmode_Current)        Mode = (cpsr & ModeMask);    if (Mode == SYS32mode)        Mode = USR32mode;    if ((Mode & ModeMask) != Mode)    {        LogWarning(LOG_DEBUGOS, ( "ERROR: Unrecognised mode in angelOS_CPUWrite.\n"));        return RDIError_BadCPUStateSetting;    }    /*     * requested mode must match application mode  - if not then refuse     * to do it.     */    if (Mode != (cpsr & ModeMask))        return RDIError_BadCPUStateSetting;    if ((Mask & 0x7FFFF) != Mask)    {        LogWarning(LOG_DEBUGOS, ( "ERROR: Mask invalid in angelOS_CPUWrite.\n"));        return RDIError_Error;    }    /* deal first with r0 */    if (Mask & 1L)        rb->r0 = cpuread(WriteData, &c);    /* now r1 -- r7 */    r = &rb->r1;    for (i = 1; i < 8; i++, r++)        if ((1L << i) & Mask)            *r = cpuread(WriteData, &c);    /* now r8 - r12, banked FIQ / NotFIQ */    if ((cpsr & ModeMask) == FIQmode)        r = &rb->r8fiq;    else        r = &rb->r8usr;        for (; i < 13; i++, r++)        if ((1L << i) & Mask)            *r = cpuread(WriteData, &c);    /* finally, r13, r14 */    if (Mask & (1L << 13))        *Angel_AdrBankedReg(rb, Mode, 13) = cpuread(WriteData, &c);        if (Mask & (1L << 14))        *Angel_AdrBankedReg(rb, Mode, 14) = cpuread(WriteData, &c);    /* now r15 -- pc */    if (ADP_CPUread_PCmode & Mask)        rb->pc = cpuread(WriteData, &c);    if (ADP_CPUread_PCnomode & Mask)        rb->pc = cpuread(WriteData, &c);    if (ADP_CPUread_CPSR & Mask)        rb->cpsr = cpuread(WriteData, &c);    /* banked register 15 is the SPSR for the mode */    if (Mode != USR32mode) /* and Mode != SYS32mode -- see above */        if (ADP_CPUread_SPSR & Mask)            *Angel_AdrBankedReg(rb, Mode, 15) = cpuread(WriteData, &c);    return RDIError_NoError;}/* *  Function: cpuwrite *   Purpose:  *            Convenient function to write the next word to a byte buffer and *            then increment a counter appropriately * *    Params:  *       Input:  * *   Returns:  */static voidcpuwrite(word w, byte * wd, int *c){    PUT32LE(wd + *c, w);    *c += 4;}/* *  Function: angelOS_CPURead *   Purpose:  * *    Params:  *       Input:  * *   Returns:  */intangelOS_CPURead(word OSinfo1, word OSinfo2, word Mode, word Mask,                byte * ReadData){    int i, c = 0;    angel_RegBlock *rb;    unsigned *r, cpsr;    IGNORE(OSinfo1);    IGNORE(OSinfo2);    LogInfo(LOG_DEBUGOS, ( "angelOS_CPURead: Mode = 0x%x, Mask = 0x%x.\n", Mode, Mask));    rb = Angel_AccessApplicationRegBlock();    if (rb == NULL)        return RDIError_Error;    cpsr = rb->cpsr;        if (Mode == ADP_CPUmode_Current)        Mode = (rb->cpsr & ModeMask);    if (Mode == SYS32mode)        Mode = USR32mode;    /* If we have made a request for a 26 bit mode, change it to the     * 32 bit equivalent mode - this allows such requests to work     * properly on the StrongARM.     */    Mode |= 0x10;    if ((Mode & ModeMask) != Mode)    {        LogWarning(LOG_DEBUGOS, ( "ERROR: Unrecognised mode in angelOS_CPURead.\n"));        return RDIError_BadCPUStateSetting;    }    if ((Mask & 0x7FFFF) != Mask)    {        LogWarning(LOG_DEBUGOS, ( "ERROR: Mask invalid in angelOS_CPURead.\n"));        return RDIError_Error;    }    /* deal first with r0 */    if (Mask & 1L)        cpuwrite(rb->r0, ReadData, &c);    /* now r1 -- r7 */    r = &rb->r1;    for (i = 1; i < 8; i++, r++)        if ((1L << i) & Mask)            cpuwrite(*r, ReadData, &c);    /* now r8 - r12, banked FIQ / NotFIQ */    if ((cpsr & ModeMask) == FIQmode)        r = &rb->r8fiq;    else        r = &rb->r8usr;        for (; i < 13; i++, r++)        if ((1L << i) & Mask)            cpuwrite(*r, ReadData, &c);    /* finally, r13, r14 */    if (Mask & (1L << 13))        cpuwrite(Angel_GetBankedReg(rb, Mode, 13), ReadData, &c);        if (Mask & (1L << 14))        cpuwrite(Angel_GetBankedReg(rb, Mode, 14), ReadData, &c);    /* now r15 -- pc */    if (ADP_CPUread_PCmode & Mask)        cpuwrite(rb->pc, ReadData, &c);    if (ADP_CPUread_PCnomode & Mask)    {        if (!(cpsr) & (1 << 4))        {            /* if in 26 bit mode */            cpuwrite(rb->pc & 0x0FFFFFFb, ReadData, &c);        }        else        {            /* 32 bit, return full PC */            cpuwrite(rb->pc, ReadData, &c);        }    }        if (ADP_CPUread_CPSR & Mask)        cpuwrite(rb->cpsr, ReadData, &c);    /* banked register 15 is the SPSR for the mode */

⌨️ 快捷键说明

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