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

📄 rdi150-low.c

📁 在Linux下和multi-ice连接
💻 C
📖 第 1 页 / 共 3 页
字号:
/* RDI 1.5 translation code for Arm Multi-ice server for GDB.   Copyright (C) 1999 Free Software Foundation, Inc.This file is part of GDB.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */typedef unsigned int unsigned32;typedef unsigned short unsigned16;typedef unsigned char unsigned8;typedef int bool;#include "defs.h"#include "target.h" /* For "enum target_signal" */#include "server.h"#include "low.h"#include "remote-utils.h"#include "tm.h"/* These are all the WinRDI defines that we need. */#include "windows.h"#include "host.h"#include "rdi.h"#include "rdi150.h"#include "rdi_hif.h"#include "rdi_conf.h"#include "rdi_info.h"#include "winrdi.h"/* This is set in low_resume, it indicates when we are running.  This is so   that a call to low_close_target can know to stop the target before it tries   to shut down.*/int currently_running = 0;/* * We will keep a linked list of the RDI "points" that have been set. * We need these tokens to delete the points again. */struct rdi_points {  RDI_PointHandle handle;  CORE_ADDR addr;  struct rdi_points *next;};struct rdi_points *breakpoint_list; /* This one keeps the breakpoints. */struct rdi_points *watchpoint_list; /* This one the watchpoints. *//* * Really have to do better than this...  I don't want to put routines * that need platform types in server.h, so I need to abstract the "window" * type, and coerce on the other end.  For another day. */extern HWND get_main_window (void);/* Pointers to the functions we have dug out of the Multi-ICE DLL. */WinRDI_funcGetVersion winRDI_GetVersion;WinRDI_funcValid_RDI_DLL winRDI_Valid_RDI_DLL;WinRDI_funcGet_DLL_Description winRDI_Get_DLL_Description;WinRDI_funcGetRDIProcVec winRDI_GetRDIProcVec;WinRDI_funcInitialise winRDI_Initialise;WinRDI_funcConsoleInitialise winRDI_ConsoleInitialise;WinRDI_funcConfig winRDI_Config;WinRDI_funcRegister_Yield_Callback winRDI_Register_Yield_Callback;/* * This is the RDI proc vector */struct RDI_ProcVec * rdi_proc_vec;/* This is the that we need to pass to WinRDI_Initialise.  There are a lot of * other calls that this also gets passed to, but according to the docs, it is * ignored in all of them. */RDI_ConfigPointer gdb_config;/* * This is the agent handle for the arm processor.  It is filled out * in the initialisation section. */RDI_AgentHandle gdb_agent;RDI_DbgState *gdb_debug_state;/* * This is the interface for debug messages used by the Multi-ICE. */struct RDI_HostosInterface gdb_IO_struct;/* * proc_desc_array is the Array of processor modules for the ARM's * et al on the * board.  num_procs is the number of processers on board. */unsigned num_procs;RDI_ModuleDesc *proc_desc_array = NULL;/* * TARGET_ARM_CORE is the index in the proc_desc_array for the arm * core we are debugging.  We are not currently prepared to debug more * than one Arm core, and have no interface to set which core * to debug, so for now this is just set to the first arm we find. * Set it to -1 on startup, and then low_open_target will set it to * the correct value. * * TARGET_ARM_MODULE is just a convenience for * * proc_desc_array[target_arm_core].handle * * which we use all the time. */int target_arm_core = -1;RDI_ModuleHandle target_arm_module = NULL;/* Gives the target byte order returned from the RDI initialization   for the "target_arm_core" processor. I don't understand the response   that I get back from the RDI info call for ByteSex, so for now,    initialize this to the same value you put in the cfnArray's BYTESEX   parameter below. */int target_byte_order = BIG_ENDIAN;/* Does the target_arm_core support single-stepping? */int target_step = 0;/* TARGET_LOAD_SIZE is the largest Memory write that the target supports   Not all targets support reporting this, -1 indicates unknown. */int target_load_size = -1;/* If TARGET_STOP_OTHERS = 1, then a resume stops all the other   processors. */int target_stop_others = 0;/* * This is the default Toolconf database that we will use. * Because the RDIinfo ByteSex call comes back with some * response I don't understand, be sure to initialize  * target_byte_order to the value in the BYTESEX field below. * Also, the array needs to end with a NULL element. *//* This was the original version of the array that I cooked up based   on Multi-ICE 1.0.  It doesn't work with versions >=  1.3, however.*/char *cfnArray[] = {"MEMORYSIZE=0","SERIALPORT=1","SERIALLINESPEED=0","PARALLELPORT=1","PARALLELLINESPEED=1","LLSYMSNEEDPREFIX=TRUE","RDITYPE=0","HEARTBEAT=TRUE","MICETAPPOS1=0","RESET=FALSE","MICEDBGCONN=","MICEDRIVER1=","MICESERVER=localhost","MICETAPPOS0=0","FPE=TRUE",/* These fields were added from on the advice of David Adshead from ARM.   They work with versions > 1.3 of the Multi-ICE DLL.  Some of these   fields need to get filled in for the DLL to start properly.  If they   are not filled the get_agent call will report success, but will return   a null agent token, which is not good.  I haven't played around with   which ones are needed, however.*/"Multi-ICE_Tap1_Position=0","Multi-ICE_Connection_Name=","Multi-ICE_Driver1_Name=","Multi-ICE_Server_Location=localhost","Multi-ICE_Tap0_Position=0","Multi-ICE_DLL_Settings=0",NULL};char *target_driver_name = "ARM7TDMI";  /* Default driver *//* Define the registers array here. */char *aregisters;char hold_registers[REGISTER_BYTES];   /* Used while running thread code on target */int registers_up_to_date = 0;int registers_are_dirty = 0;int need_to_abort = 0;/* * Defines for functions used only in this file. */RDI_Hif_DbgPrint my_IO_dbgprint;RDI_Hif_DbgPause my_IO_dbgpause;void my_IO_dbgarg(RDI_Hif_DbgArg *arg);RDI_Hif_WriteC my_IO_writec;RDI_Hif_ReadC my_IO_readc;RDI_Hif_Write my_IO_write;RDI_Hif_GetS my_IO_gets;RDI_Hif_ResetProc my_IO_reset;void my_IO_resetarg(RDI_Hif_ResetArg *arg);  char *rdi_error_message (int err);static int rdi_to_gdb_signal (int rdi_error);void record_register (int regno, ARMword val);ARMword restore_register (int regno);/* These functions come from arm-singlestep.c */extern CORE_ADDR server_arm_get_next_pc (CORE_ADDR pc,					 unsigned short *is_thumb);extern int arm_pc_is_thumb (bfd_vma memaddr);/* Yield callback */static int yield_arg;static int yield_count;#define YIELD_PERIOD 10voidyield_func(WinRDI_YieldArg *arg){    ARMword empty;    if (++yield_count == YIELD_PERIOD) {        yield_count = 0;        check_for_SIGIO();    }    if (need_to_abort) {        need_to_abort = 0;        rdi_proc_vec->info (target_arm_module, RDISignal_Stop, &empty, &empty);    }}/* * low_open_target * * This opens the connection to the target board.  TARGET_PORT * gives the port address for the board.  If QUERY is 1, the * user is queried for the setup of the connection parameters. */intlow_open_target (char *target_port, char *byte_sex, int query){  int vers;  int valid, result = 0;  unsigned i;  unsigned write_mask = 0;  ARMword null_value[2] = {0, 0};  unsigned open_type;  ARMword flags, dummy;  HINSTANCE handle;  HWND main_win;  char driver[64];  /*   * First, we will open the Multi-ICE DLL and dig all the procs   * that we need out of it.   */    handle = LoadLibrary ("Multi-ICE.dll");  if (handle == NULL)    {      output_error ("Could not load the Multi-ICE DLL\n");      return 0;    }    winRDI_GetVersion = WinRDI_GetProcAddress (handle, GetVersion);  if (winRDI_GetVersion == NULL)    {      output_error ("Could not get GetVersion from the Multi-ICE DLL\n");      return 0;    }    winRDI_Valid_RDI_DLL = WinRDI_GetProcAddress (handle, Valid_RDI_DLL);  if (winRDI_Valid_RDI_DLL == NULL)    {      output_error ("Could not get Valid_RDI_DLL from the Multi-ICE DLL\n");      return 0;    }  winRDI_Get_DLL_Description = WinRDI_GetProcAddress (handle,						      Get_DLL_Description);  if (winRDI_Get_DLL_Description == NULL)    {      output_error ("Could not get Get_DLL_Description from the Multi-ICE DLL\n");      return 0;    }    winRDI_Config = WinRDI_GetProcAddress (handle, Config);  if (winRDI_Config == NULL)    {      output_error ("Could not get Config from the Multi-ICE DLL\n");      return 0;    }    winRDI_Initialise = WinRDI_GetProcAddress (handle, Initialise);  if (winRDI_Initialise == NULL)    {      output_error ("Could not get Initialise from the Multi-ICE DLL\n");      return 0;    }  winRDI_GetRDIProcVec = WinRDI_GetProcAddress (handle, GetRDIProcVec);  if (winRDI_GetRDIProcVec == NULL)    {      output_error ("Could not get GetRDIProcVec from the Multi-ICE DLL\n");      return 0;    }  winRDI_Register_Yield_Callback = WinRDI_GetProcAddress (handle, Register_Yield_Callback);  if (winRDI_Register_Yield_Callback == NULL)    {      output_error ("Could not get Register_Yield_Callback from the Multi-ICE DLL\n");      return 0;    }  /* Register a "yield" callback so we can regain control while 'executing' */  winRDI_Register_Yield_Callback(yield_func, (WinRDI_YieldArg *)&yield_arg);    /*   * Okay, now we are ready to start the actual initialization process.   * First we check that the DLL is copasetic, then start to open the   * connection to the target.   */    valid = winRDI_Valid_RDI_DLL ();    if (!valid)    {      output_error ("RDI DLL says it is not valid\n");      return 0;    }    vers = winRDI_GetVersion ();  if (vers < 150 || vers >= 200)    {      output_error ("RDI version mismatch, expected 150 <> 200, got %d\n",		    vers);      return 0;    }    rdi_proc_vec = winRDI_GetRDIProcVec ();  if (rdi_proc_vec == NULL)    {      output_error ("Got null proc vector from GetRDIProcVec\n");      return 0;    }    /*   * Now fill the ToolConf database.  Some of these have to be   * filled BEFORE you call winRDI_Initialise, or the DLL will   * crash in random places...  This is supposed to be fixed in   * the 1.4 version of the DLL.   */    gdb_config = ToolConf_New (30);  for (i = 0; cfnArray[i] != NULL; i++)    {      ToolConf_Add (gdb_config, cfnArray[i]);    }    if (target_port != NULL)    {      char buffer[256];      /* This is the Multi-ICE DLL < 1.3 version. */      sprintf (buffer, "MICESERVER=%s", target_port);      ToolConf_Update (gdb_config, buffer);      /* This is the Multi-ICE DLL >= 1.3 version. */      sprintf (buffer, "Multi-ICE_Server_Location=%s", target_port);      ToolConf_Update (gdb_config, buffer);  }  if (byte_sex != NULL)    {      if (*byte_sex == 'b' || *byte_sex == 'B')	{	  ToolConf_Update (gdb_config, "BYTESEX=BIG");          target_byte_order = BIG_ENDIAN;	}      else if (*byte_sex == 'l' || *byte_sex == 'L')	{	  ToolConf_Update (gdb_config, "BYTESEX=LITTLE");          target_byte_order = LITTLE_ENDIAN;	}    }  sprintf(driver, "Multi-ICE_Driver0_Name=%s", target_driver_name);  ToolConf_Update (gdb_config, driver);  /* There seems to be some confusion about the real name here */  sprintf(driver, "MICEDRIVER0=%s", target_driver_name);  ToolConf_Update (gdb_config, driver);  main_win = get_main_window ();    if (main_win == NULL)    {      output_error ("The main window handle was null.\n");      return 0;    }  if (query)    {      result = winRDI_Config (gdb_config, main_win);      if (!result)	{	  output_error ("Configure failed...\n");	  return 0;	}    }    result = winRDI_Initialise (main_win, gdb_config);  if (!result)    {      output_error ("Initialise failed...\n");      return 0;    }    /*   * Set the open type to cold boot, reset comm, byte sex dont care   */    open_type = (0 << RDIOpen_BootLevel);  open_type |= (1 << RDIOpen_CommsReset);  open_type |= (RDISex_DontCare << RDIOpen_ByteSexShift);    /*   * Fill the IO structure with the appropriate functions.   */    gdb_IO_struct.dbgprint = my_IO_dbgprint;  gdb_IO_struct.dbgpause = my_IO_dbgpause;  gdb_IO_struct.writec = my_IO_writec;  gdb_IO_struct.readc = my_IO_readc;  gdb_IO_struct.write = my_IO_write;  gdb_IO_struct.gets = my_IO_gets;    result = rdi_proc_vec->openagent (&gdb_agent, open_type, gdb_config, 				   &gdb_IO_struct, gdb_debug_state);    if (result != RDIError_NoError) {    output_error ("RDI_OpenAgent failed with error %d.\n", result);    if (gdb_agent != NULL)      {	rdi_proc_vec->closeagent (gdb_agent);      }    return 0;  }  /*   * Next, query the agent to find out how many processors are on   * board, get the info for these, and open them all.  Note that   * you have to open all of them even though you only intend to   * talk to one of them.   */    num_procs = 0;  result = rdi_proc_vec->info (gdb_agent, RDIInfo_Modules, 			      (ARMword *) &num_procs,			      (ARMword *) NULL);  if (num_procs == 0)     {      output_error ("Found no processors for agent %d\n", gdb_agent);      return 0;    }  proc_desc_array = (RDI_ModuleDesc *)     malloc(sizeof(RDI_ModuleDesc) * num_procs);  result = rdi_proc_vec->info(gdb_agent, RDIInfo_Modules, 			      (ARMword *) &num_procs,			      (ARMword *) proc_desc_array);  for (i = 0; i < num_procs; i++)    {      /*       * Some modules may have their own RDI vectors, use it if       * it is present.       */            if (proc_desc_array[i].rdi == NULL)	{	  result = rdi_proc_vec->open (proc_desc_array[i].handle, 				       open_type, gdb_config,				       &gdb_IO_struct,				       gdb_debug_state);	}      else	{	  result = proc_desc_array[i].rdi->open (proc_desc_array[i].handle, 						 open_type, gdb_config,						 &gdb_IO_struct,						 gdb_debug_state);	}            if (result != RDIError_NoError && result != RDIError_LittleEndian && result != RDIError_BigEndian)	{	  int j;	  	  output_error ("Error #%d opening module module %d\n%s\n", result,                         i, rdi_error_message(result));	  for (j = 0; j < i; j++)	    {	      if (proc_desc_array[j].rdi == NULL)		{		  result = rdi_proc_vec->close (proc_desc_array[j].handle);		}	      else		{		  result =		    proc_desc_array[j].rdi->close (proc_desc_array[j].handle);		}	    }	    rdi_proc_vec->closeagent (gdb_agent);	    return 0;	}      /*       * For now there is no interface to tell us which ARM core       * you want to debug.  We default to the first one found.       * At this point we also get its byte order.       */            if (target_arm_core < 0)	{	  if (strcmp (proc_desc_array[i].type, "ARM") == 0)	    {	      unsigned32 sex;	      target_arm_core = i;	      target_arm_module = proc_desc_array[i].handle;	      #if 0	      rdi_proc_vec->info(target_arm_module,				 RDIInfo_ByteSex,				 &sex,				 NULL);              /* The "sex" value is coming back with some                 bogus value, so if I don't recognize it,                  just leave it alone, since the code above                 sets it to whatever I have requested... */	      if (sex == RDISex_Big) 		{		  target_byte_order = BIG_ENDIAN;		}	      else if (sex == RDISex_Little)		{		  target_byte_order = LITTLE_ENDIAN;		}	    #else		  if (result == RDIError_BigEndian)		      target_byte_order = BIG_ENDIAN;		  else if (result == RDIError_LittleEndian)		      target_byte_order = LITTLE_ENDIAN;		  else		      output_error ("Target didn't return ARM endianness");#endif	    }	}        }  if (target_arm_core < 0)    {      low_close_target();      output_error ("Didn't find a core of type \"ARM\" on target.\n");      return 0;    }  /*   * Set the frame pointer to zero.  Sometimes if you power-cycle   * the board this can be pointing off into never-never land, and   * that can confuse GDB no end.   */  write_mask = ( 1 << 11 );  write_mask |= (1 << 15);  rdi_proc_vec->CPUwrite (target_arm_module, RDIMode_Curr,			  write_mask, null_value);  /*   * Finally, write out some information on the processor we   * are connected to:   */  output ("\nConnected to the Multi-Ice target.\n\n");  output ("Targeted ARM core: %s\n", proc_desc_array[target_arm_core].name);

⌨️ 快捷键说明

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