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

📄 debugos.c

📁 AT91所有开发板的资料 AT91所有开发板的资料
💻 C
📖 第 1 页 / 共 4 页
字号:
/* -*-C-*- * * $Revision: 1.1 $ *   $Author: rivimey $ *     $Date: 1999/03/11 11:53:35 $ * * Copyright (c) 1995-96 Advanced RISC Machines Limited * All Rights Reserved. * * debugos.c: Operating system debug support functions. */#include "angel.h"#include "devconf.h"#include "adp.h"#include "debug.h"#include "debugos.h"#include "endian.h"#include "debughwi.h"#include "logging.h"#include "serlock.h"#include "stacks.h"#include "devclnt.h"#include "support.h"#include "sys.h"/* use the memset in suppasm.s */#define memset __rt_memsetstruct AngelOSInfo OSinfo_struct;/* Breakpoint stuff */static struct BreakPoint *head_bp;struct BreakPoint bp[32];word free_bps;int memory_is_being_accessed = 0;volatile int memory_access_aborted = 0;#if defined(SYSTEM_COPROCESSOR_SUPPORTED) && SYSTEM_COPROCESSOR_SUPPORTED > 0/* Define the coprocessor data structures */#define SYS_COPROC_MAX_REGS 32static int sys_coproc_reg_entries;static CP_CoProRegDesc sys_coproc_regdesc[SYS_COPROC_MAX_REGS];#endifunsigned int angel_debugger_endianess;int angelOS_SemiHostingEnabled;/* *  Function:  *   Purpose:  * *    Params:  *       Input:  * *   Returns:  */#if DEBUG == 1int angelOS_PrintState(word OSinfo1, word OSinfo2){    int c;    angel_RegBlock *rb;    unsigned *r;    rb = Angel_AccessApplicationRegBlock();    LogInfo(LOG_DEBUGOS, ( "State:  OSinfo1: 0x%x.  OSinfo2: 0x%x.\n", OSinfo1, OSinfo2));    LogInfo(LOG_DEBUGOS, ( "Registers r0 - r14:-\n"));    /* r0 is separate, r1-7 are in a single block */    LogInfo(LOG_DEBUGOS, ( " r0 0x%08x ", rb->r0));    r = &rb->r1;    for (c = 1; c < 8; c++, r++)    {        LogInfo(LOG_DEBUGOS, ( " r%d 0x%08x ", c, *r));        if (c == 3 || c == 7)            LogInfo(LOG_DEBUGOS, ("\n"));    }        if ((rb->cpsr & 0x1f) == FIQmode)        r = &rb->r8fiq;    else        r = &rb->r8usr;        for (; c < 13; c++, r++)    {        LogInfo(LOG_DEBUGOS, ( "%sr%d 0x%08x ", (c < 10)? " ":"", c, *r));        if (c == 11)            LogInfo(LOG_DEBUGOS, ("\n"));    }    /* now do r13, r14... banked across most modes */    LogInfo(LOG_DEBUGOS, ( "r13 0x%08x ", Angel_GetBankedReg(rb, rb->cpsr, 13)));    LogInfo(LOG_DEBUGOS, ( "r14 0x%08x\n", Angel_GetBankedReg(rb, rb->cpsr, 14)));        LogInfo(LOG_DEBUGOS, ( " pc 0x%08x cpsr 0x%08x\n", rb->pc, rb->cpsr));    return RDIError_NoError;}#else#define angelOS_PrintState(OSinfo1, OSinfo2)#endif/* *  Function:  *   Purpose:  * *    Params:  *       Input:  * *   Returns:  */int angelOS_Initialise(void){    LogInfo(LOG_DEBUGOS, ( "Entered angelOS_Initialise.\n"));    /* Initialise OS info structure. */    OSinfo_struct.infoBitset = ADP_Info_Target_HW        | ADP_Info_Target_CanInquireBufferSize        | ADP_Info_Target_CanReloadAgent#if defined(THUMB_SUPPORT) && THUMB_SUPPORT!=0        | ADP_Info_Target_Thumb#endif#if PROFILE_SUPPORTED        | ADP_Info_Target_Profiling#endif        ;    OSinfo_struct.infoPoints = 0;    OSinfo_struct.infoStep = 0;    /* Initialise breakpoints. */    head_bp = NULL;    free_bps = 0xFFFFFFFF;    /* semihosting on by default */    angelOS_SemiHostingEnabled = 1;#if defined(SYSTEM_COPROCESSOR_SUPPORTED) && SYSTEM_COPROCESSOR_SUPPORTED > 0    /* Initialise system coprocessor description array; the first part     * of this is correct for any processor with a system co-processor     */    /* Reg 0 is read only */    sys_coproc_regdesc[0].rmin = 0;    sys_coproc_regdesc[0].rmax = 0;    sys_coproc_regdesc[0].nbytes = 4;    sys_coproc_regdesc[0].access = 0x1;  /* Read only, use register access */    sys_coproc_regdesc[0].accessinst.cprt.read_b0 = 0;    sys_coproc_regdesc[0].accessinst.cprt.read_b1 = 0;    sys_coproc_regdesc[0].accessinst.cprt.write_b0 = 0;    sys_coproc_regdesc[0].accessinst.cprt.write_b1 = 0;    /* Registers 1 to 3 are simple control registers */    sys_coproc_regdesc[1].rmin = 1;    sys_coproc_regdesc[1].rmax = 3;    sys_coproc_regdesc[1].nbytes = 4;    sys_coproc_regdesc[1].access = 0x3;  /* Read/Write, use register access */    sys_coproc_regdesc[1].accessinst.cprt.read_b0 = 0;    sys_coproc_regdesc[1].accessinst.cprt.read_b1 = 0;    sys_coproc_regdesc[1].accessinst.cprt.write_b0 = 0;    sys_coproc_regdesc[1].accessinst.cprt.write_b1 = 0;    /* Register 4 is undefined */    /* Registers 5 and 6 are fault registers, similar to 1 to 3 */    sys_coproc_regdesc[2].rmin = 5;    sys_coproc_regdesc[2].rmax = 6;    sys_coproc_regdesc[2].nbytes = 4;    sys_coproc_regdesc[2].access = 0x3;  /* Read/Write, use register access */    sys_coproc_regdesc[2].accessinst.cprt.read_b0 = 0;    sys_coproc_regdesc[2].accessinst.cprt.read_b1 = 0;    sys_coproc_regdesc[2].accessinst.cprt.write_b0 = 0;    sys_coproc_regdesc[2].accessinst.cprt.write_b1 = 0;    /* Registers 7 and 8 provide cache and writebuffer operations; since     * these need a variety of different opcode_2 and CRm values it does     * not make sense to provide a default for these     */    /* StrongARM only - Register 15 provides some additional clock     * control functions. Again there are no sensible defaults for     * opcode_2 and CRm     */    sys_coproc_reg_entries = 3;#endif    memory_is_being_accessed = 0;    memory_access_aborted = 0;    return RDIError_NoError;}/* *  Function: angelOS_MemRead * *   Purpose: To transfer memory from the application memory space *         (that is, not Angel's memory) to an internal buffer in *         Angel, typically in response to a debugger request for  *         that memory. Because of this, it is important that halfword *         reads and word reads are used when transferring 2 or 4  *         bytes of data. Of course 1 bytes reads must use single byte *         transfers. For 3 or >4 bytes the limitations are less *         severe, but as implemented: *          *         - use word copy if addresses are word aligned and copying integral *           number of words *          *         - use halfword copy if addresses are halfword aligned but not *           word aligned and number of bytes is even *          *         - otherwise, copy byte-by-byte. *          *         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 read *              Nbytes      - the number of bytes to read *              DataArea    - where to put the data once read *               *      Output:  *              BytesRead   - return of how many bytes were transferred * *   Returns: Error code: OK if memort transferred, DataAbort or Priviledge *                        error otherwise. */intangelOS_MemRead(word OSinfo1, word OSinfo2, word Address, word Nbytes,                byte * DataArea, word * BytesRead){    int all_permitted;    IGNORE(OSinfo1);    IGNORE(OSinfo2);    /*     * If we detect that either the start or end of the area is not     * a permitted read area then give up immediately.     * Otherwise transfer the whole lot a byte at a time.     * This is preferable to transferring words due to a number of     * problems: endianess and non alignment of data in target memory     * and/or the datablock.     */    all_permitted = (READ_PERMITTED(Address) &&                     READ_PERMITTED(Address + Nbytes - 1));    if (!all_permitted)    {        *BytesRead = 0;        return RDIError_InsufficientPrivilege;    }    memory_is_being_accessed = 1;    memory_access_aborted = 0;    /*     *     */    if ( (((int)DataArea | Address | Nbytes) & 0x3) == 0)    {        word *swAddress = (word *)Address;        word *dwAddress = (word *)DataArea;        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;        }        /* modify ssAddress by the number of aborts; this should         * get us back to the real abort address         */        swAddress -= memory_access_aborted;                *BytesRead = (int)swAddress - (int)Address;    }    else if ((((int)DataArea | (int)Address | Nbytes) & 0x1) == 0)    {        short *ssAddress = (short *)Address;        short *dsAddress = (short *)DataArea;        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 words here... either way, do nothing */                break;        }        /* modify ssAddress by the number of aborts; this should         * get us back to the real abort address         */        ssAddress -= memory_access_aborted;        *BytesRead = (int)ssAddress - (int)Address;    }    else    {        char *sbAddress = (char *)Address;        char *dbAddress = (char *)DataArea;        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 words here... either way, do nothing */                break;        }        /* modify ssAddress by the number of aborts; this should         * get us back to the real abort address         */        sbAddress -= memory_access_aborted;        *BytesRead = (int)sbAddress - (int)Address;    }    memory_is_being_accessed = 0;    return memory_access_aborted ? RDIError_DataAbort : RDIError_NoError;}/* *  Function: angelOS_MemWrite *   Purpose: To transfer memory from an internal buffer in Angel, to *         the application memory space (that is, not Angel's memory) *         typically in response to a debugger request to write that *         memory. Because of this, it is important that halfword *         reads and word reads are used when transferring 2 or 4  *         bytes of data. Of course 1 bytes reads must use single byte *         transfers. For 3 or >4 bytes the limitations are less *         severe, but as implemented: *          *         - use word copy if addresses are word aligned and copying integral *           number of words *          *         - use halfword copy if addresses are halfword aligned but not *           word aligned and number of bytes is even *          *         - otherwise, copy byte-by-byte. *         

⌨️ 快捷键说明

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