📄 debugos.c
字号:
/* -*-C-*- * * $Revision: 1.19.4.4 $ * $Author: rivimey $ * $Date: 1998/03/03 13:47:47 $ * * Copyright (c) 1995-96 Advanced RISC Machines Limited * All Rights Reserved. * * debugos.c: Operating system debug support functions. */#include "angel.h"#include "adp.h"#include "debug.h"#include "debugos.h"#include "endian.h"#include "debughwi.h"#include "logging.h"#include "serlock.h"#include "devclnt.h"#include "devconf.h"#include "support.h"#if 0typedef enum{ bs_32bit, bs_16bit}BreakPointSize;struct BreakPoint{ struct BreakPoint *next; word address; word inst; unsigned count; int bpno; /* Index to array where this structure is saved. */ BreakPointSize size;};#endifstruct 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;#ifdef SUPPORT_SYSTEM_COPROCESSOR/* Define the coprocessor data structures */#define SYS_COPROC_MAX_REGS 32static int sys_coproc_reg_entries;static Dbg_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; rb = Angel_AccessApplicationRegBlock(); LogInfo(LOG_DEBUGOS, ( "State: OSinfo1: 0x%x. OSinfo2: 0x%x.\n", OSinfo1, OSinfo2)); LogInfo(LOG_DEBUGOS, ( "Registers r0 - r14:-\n")); for (c = 0; c < 8; c++) { LogInfo(LOG_DEBUGOS, ( " r%d 0x%08x ", c, rb->r[c])); } for (; c < 15; c++) { LogInfo(LOG_DEBUGOS, ( "%sr%d 0x%08x ", (c < 10)? " ":"", c, rb->r[c])); } LogInfo(LOG_DEBUGOS, ( " pc 0x%08x\n", rb->r[reg_pc])); LogInfo(LOG_DEBUGOS, ( "cpsr 0x%08x ", rb->cpsr)); LogInfo(LOG_DEBUGOS, ( "spsr 0x%08x\n", rb->spsr)); /* cannot do banked modes any more! */ 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;#ifdef SUPPORT_SYSTEM_COPROCESSOR /* 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: * * Params: * Input: * * Returns: */intangelOS_MemRead(word OSinfo1, word OSinfo2, word Address, word Nbytes, byte * DataArea, word * BytesRead){ /* word c; */ 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; /*for (c = 0; c < Nbytes; c++) * *{ * * DataArea[c] = *(((char *)Address) + c); * * if (memory_access_aborted) * * break; * *} */ /* Use the word copy if the transfer is word aligned */ if (((int)DataArea | Address | Nbytes) & 0x3) { char *sbAddress = (char *)Address; char *dbAddress = (char *)DataArea; int b; while (Nbytes > 0) { b = (Nbytes > 8) ? 8 : Nbytes; Nbytes -= b; /* check to see access is ok */ *dbAddress = 0; if (memory_access_aborted) break; if (( (int)sbAddress & ~0x3 ) != 0xFFFFF100 ) { for ( ; b > 0; b--) { *dbAddress++ = *sbAddress++; } } else { for ( ; b > 0; b--) { *dbAddress++ = 0xa5; sbAddress++ ; } } } *BytesRead = (int)dbAddress - (int)DataArea; } else { int *swAddress = (int*)Address; int *dwAddress = (int*)DataArea; word Nwords = Nbytes >> 2; int b; for (b = Nwords; b > 0; b--) { if ( swAddress != (int *)0xFFFFF100 ) { *dwAddress++ = *swAddress++; } else { *dwAddress++ = 0xdeaddead ; swAddress++ ; } if (memory_access_aborted) break; } *BytesRead = (int)dwAddress - (int)DataArea; } memory_is_being_accessed = 0; /* *BytesRead = c; */ return memory_access_aborted ? RDIError_DataAbort : RDIError_NoError;}/* * Function: angelOS_MemWrite * Purpose: * * Params: * Input: * * Returns: */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 word copy if addresses are word aligned and copying integral number * of words * *(((char *)Address) + c) = DataArea[c]; */ if (((int)DataArea | Address | Nbytes) & 0x3) { char *sbAddress = (char *)DataArea; char *dbAddress = (char *)Address; int b; while (Nbytes > 0) { b = (Nbytes > 8) ? 8 : Nbytes; Nbytes -= b; /* check to see access is ok */ *dbAddress = 0; if (memory_access_aborted) break; for ( ; b > 0; b--) { *dbAddress++ = *sbAddress++; } } *BytesWritten = (int)dbAddress - Address; } else { int *swAddress = (int*)DataArea; int *dwAddress = (int*)Address; word Nwords = Nbytes >> 2; int b; for (b = Nwords; b > 0; b--) { *dwAddress++ = *swAddress++; if (memory_access_aborted) break; } *BytesWritten = (int)dwAddress - 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; 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; if (Mode == ADP_CPUmode_Current) Mode = (rb->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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -