📄 debugos.c
字号:
/* -*-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 + -