#include "defs.h"
#include "frame.h"
#include "inferior.h"
#include "gdb_wait.h"
#include "value.h"
#include <ctype.h>
#include <fcntl.h>
#include <signal.h>
#include <errno.h>
#include "gdb_string.h"
#include "terminal.h"
#include "target.h"
#include "29k-share/udi/udiproc.h"
#include "gdbcmd.h"
#include "bfd.h"
#include "gdbcore.h"
extern int stop_soon_quietly;
extern struct value *call_function_by_hand ();
static void udi_resume (int pid, int step, enum target_signal sig);
static void udi_fetch_registers (int regno);
static void udi_load (char *args, int from_tty);
static void fetch_register (int regno);
static void udi_store_registers (int regno);
static int store_register (int regno);
static int regnum_to_srnum (int regno);
static void udi_close (int quitting);
static CPUSpace udi_memory_space (CORE_ADDR addr);
static int udi_write_inferior_memory (CORE_ADDR memaddr, char *myaddr,
int len);
static int udi_read_inferior_memory (CORE_ADDR memaddr, char *myaddr,
int len);
static void download (char *load_arg_string, int from_tty);
char CoffFileName[100] = "";
#define FREEZE_MODE (read_register(CPS_REGNUM) & 0x400)
#define USE_SHADOW_PC ((processor_type == a29k_freeze_mode) && FREEZE_MODE)
static int timeout = 5;
extern struct target_ops udi_ops;
#define MAXDATA 2*1024
UDISessionId udi_session_id = -1;
static char *udi_config_id;
CPUOffset IMemStart = 0;
CPUSizeT IMemSize = 0;
CPUOffset DMemStart = 0;
CPUSizeT DMemSize = 0;
CPUOffset RMemStart = 0;
CPUSizeT RMemSize = 0;
UDIUInt32 CPUPRL;
UDIUInt32 CoProcPRL;
UDIMemoryRange address_ranges[2];
UDIResource entry =
{0, 0};
CPUSizeT stack_sizes[2];
#define SBUF_MAX 1024
char sbuf[SBUF_MAX];
typedef struct bkpt_entry_str
{
UDIResource Addr;
UDIUInt32 PassCount;
UDIBreakType Type;
unsigned int BreakId;
}
bkpt_entry_t;
#define BKPT_TABLE_SIZE 40
static bkpt_entry_t bkpt_table[BKPT_TABLE_SIZE];
extern char dfe_errmsg[];
static char *prog_name = NULL;
static void
udi_create_inferior (char *execfile, char *args, char **env)
{
char *args1;
if (execfile)
{
if (prog_name != NULL)
free (prog_name);
prog_name = savestring (execfile, strlen (execfile));
}
else if (entry.Offset)
execfile = "";
else
error ("No image loaded into target.");
if (udi_session_id < 0)
{
if (UDIConnect (udi_config_id, &udi_session_id))
error ("UDIConnect() failed: %s\n", dfe_errmsg);
entry.Offset = 0;
}
inferior_pid = 40000;
if (!entry.Offset)
download (execfile, 0);
args1 = alloca (strlen (execfile) + strlen (args) + 2);
if (execfile[0] == '\0')
strcpy (args1, "''");
else
strcpy (args1, execfile);
strcat (args1, " ");
strcat (args1, args);
UDIInitializeProcess (address_ranges,
(UDIInt) 2,
entry,
stack_sizes,
(UDIInt) 2,
args1);
init_wait_for_inferior ();
clear_proceed_status ();
proceed (-1, TARGET_SIGNAL_DEFAULT, 0);
}
static void
udi_mourn (void)
{
#if 0
pop_target ();
#endif
remove_breakpoints ();
generic_mourn_inferior ();
}
static void
udi_open (char *name, int from_tty)
{
unsigned int prl;
char *p;
int cnt;
UDIMemoryRange KnownMemory[10];
UDIUInt32 ChipVersions[10];
UDIInt NumberOfRanges = 10;
UDIInt NumberOfChips = 10;
UDIPId PId;
UDIUInt32 TIPId, TargetId, DFEId, DFE, TIP, DFEIPCId, TIPIPCId;
target_preopen (from_tty);
entry.Offset = 0;
for (cnt = 0; cnt < BKPT_TABLE_SIZE; cnt++)
bkpt_table[cnt].Type = 0;
if (udi_config_id)
free (udi_config_id);
if (!name)
error ("Usage: target udi config_id, where config_id appears in udi_soc file");
udi_config_id = strsave (strtok (name, " \t"));
if (UDIConnect (udi_config_id, &udi_session_id))
error ("UDIConnect() failed: %s\n", dfe_errmsg);
push_target (&udi_ops);
if (UDIGetTargetConfig (KnownMemory, &NumberOfRanges,
ChipVersions, &NumberOfChips))
error ("UDIGetTargetConfig() failed");
if (NumberOfChips > 2)
fprintf_unfiltered (gdb_stderr, "Target has more than one processor\n");
for (cnt = 0; cnt < NumberOfRanges; cnt++)
{
switch (KnownMemory[cnt].Space)
{
default:
fprintf_unfiltered (gdb_stderr, "UDIGetTargetConfig() unknown memory space\n");
break;
case UDI29KCP_S:
break;
case UDI29KIROMSpace:
RMemStart = KnownMemory[cnt].Offset;
RMemSize = KnownMemory[cnt].Size;
break;
case UDI29KIRAMSpace:
IMemStart = KnownMemory[cnt].Offset;
IMemSize = KnownMemory[cnt].Size;
break;
case UDI29KDRAMSpace:
DMemStart = KnownMemory[cnt].Offset;
DMemSize = KnownMemory[cnt].Size;
break;
}
}
a29k_get_processor_type ();
if (UDICreateProcess (&PId))
fprintf_unfiltered (gdb_stderr, "UDICreateProcess() failed\n");
if (UDICapabilities (&TIPId, &TargetId, DFEId, DFE, &TIP, &DFEIPCId,
&TIPIPCId, sbuf))
error ("UDICapabilities() failed");
if (from_tty)
{
printf_filtered ("Connected via UDI socket,\n\
DFE-IPC version %x.%x.%x TIP-IPC version %x.%x.%x TIP version %x.%x.%x\n %s\n",
(DFEIPCId >> 8) & 0xf, (DFEIPCId >> 4) & 0xf, DFEIPCId & 0xf,
(TIPIPCId >> 8) & 0xf, (TIPIPCId >> 4) & 0xf, TIPIPCId & 0xf,
(TargetId >> 8) & 0xf, (TargetId >> 4) & 0xf, TargetId & 0xf,
sbuf);
}
}
static void
udi_close (
int quitting)
{
if (udi_session_id < 0)
return;
if (UDIDisconnect (udi_session_id, UDITerminateSession))
{
if (quitting)
warning ("UDIDisconnect() failed in udi_close");
else
error ("UDIDisconnect() failed in udi_close");
}
udi_session_id = -1;
inferior_pid = 0;
printf_filtered (" Ending remote debugging\n");
}
static void
udi_attach (char *args, int from_tty)
{
UDIResource From;
UDIInt32 PC_adds;
UDICount Count = 1;
UDISizeT Size = 4;
UDICount CountDone;
UDIBool HostEndian = 0;
UDIError err;
if (args == NULL)
error_no_arg ("program to attach");
if (udi_session_id < 0)
error ("UDI connection not opened yet, use the 'target udi' command.\n");
if (from_tty)
printf_unfiltered ("Attaching to remote program %s...\n", prog_name);
UDIStop ();
From.Space = UDI29KSpecialRegs;
From.Offset = 11;
if (err = UDIRead (From, &PC_adds, Count, Size, &CountDone, HostEndian))
error ("UDIRead failed in udi_attach");
printf_unfiltered ("Remote process is now halted, pc1 = 0x%x.\n", PC_adds);
}
static void
udi_detach (char *args, int from_tty)
{
remove_breakpoints ();
if (UDIDisconnect (udi_session_id, UDIContinueSession))
error ("UDIDisconnect() failed in udi_detach");
udi_session_id = -1;
inferior_pid = 0;
pop_target ();
if (from_tty)
printf_unfiltered ("Detaching from TIP\n");
}
static void
udi_resume (int pid, int step, enum target_signal sig)
{
UDIError tip_error;
UDIUInt32 Steps = 1;
UDIStepType StepType = UDIStepNatural;
UDIRange Range;
if (step)
{
tip_error = UDIStep (Steps, StepType, Range);
if (!tip_error)
return;
fprintf_unfiltered (gdb_stderr, "UDIStep() error = %d\n", tip_error);
error ("failed in udi_resume");
}
if (UDIExecute ())
error ("UDIExecute() failed in udi_resume");
}
static int
udi_wait (int pid, struct target_waitstatus *status)
{
UDIInt32 MaxTime;
UDIPId PId;
UDIInt32 StopReason;
UDISizeT CountDone;
int old_timeout = timeout;
int old_immediate_quit = immediate_quit;
int i;
status->kind = TARGET_WAITKIND_EXITED;
status->value.integer = 0;
timeout = 0;
immediate_quit = 1;
while (1)
{
i = 0;
MaxTime = UDIWaitForever;
UDIWait (MaxTime, &PId, &StopReason);
QUIT;
switch (StopReason & UDIGrossState)
{
case UDIStdoutReady:
if (UDIGetStdout (sbuf, (UDISizeT) SBUF_MAX, &CountDone))
warning ("UDIGetStdout() failed in udi_wait");
fwrite (sbuf, 1, CountDone, stdout);
gdb_flush (gdb_stdout);
continue;
case UDIStderrReady:
UDIGetStderr (sbuf, (UDISizeT) SBUF_MAX, &CountDone);
fwrite (sbuf, 1, CountDone, stderr);
gdb_flush (gdb_stderr);
continue;
case UDIStdinNeeded:
{
int ch;
i = 0;
do
{
ch = getchar ();
if (ch == EOF)
break;
sbuf[i++] = ch;
}
while (i < SBUF_MAX && ch != '\n');
UDIPutStdin (sbuf, (UDISizeT) i, &CountDone);
continue;
}
case UDIRunning:
case UDIStdinModeX:
continue;
default:
break;
}
break;
}
switch (StopReason & UDIGrossState)
{
case UDITrapped:
printf_unfiltered ("Am290*0 received vector number %d\n", StopReason >> 24);
switch ((StopReason >> 8) & 0xff)
{
case 0:
printf_unfiltered (" (break point)\n");
status->kind = TARGET_WAITKIND_STOPPED;
status->value.sig = TARGET_SIGNAL_TRAP;
break;
case 1:
status->kind = TARGET_WAITKIND_STOPPED;
status->value.sig = TARGET_SIGNAL_BUS;
break;
case 3:
case 4:
status->kind = TARGET_WAITKIND_STOPPED;
status->value.sig = TARGET_SIGNAL_FPE;
break;
case 5:
status->kind = TARGET_WAITKIND_STOPPED;
status->value.sig = TARGET_SIGNAL_ILL;
break;
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
status->kind = TARGET_WAITKIND_STOPPED;
status->value.sig = TARGET_SIGNAL_SEGV;
break;
case 12:
case 13:
status->kind = TARGET_WAITKIND_STOPPED;
status->value.sig = TARGET_SIGNAL_ILL;
break;
case 14:
status->kind = TARGET_WAITKIND_STOPPED;
status->value.sig = TARGET_SIGNAL_ALRM;
break;
case 15:
status->kind = TARGET_WAITKIND_STOPPED;
status->value.sig = TARGET_SIGNAL_TRAP;
break;
case 16:
case 17:
case 18:
case 19:
case 20:
case 21:
status->kind = TARGET_WAITKIND_STOPPED;
status->value.sig = TARGET_SIGNAL_INT;
break;
case 22:
status->kind = TARGET_WAITKIND_STOPPED;
status->value.sig = TARGET_SIGNAL_ILL;
break;
case 77:
status->kind = TARGET_WAITKIND_STOPPED;
status->value.sig = TARGET_SIGNAL_TRAP;
break;
default:
status->kind = TARGET_WAITKIND_EXITED;
status->value.integer = 0;
}
break;
case UDINotExecuting:
status->kind = TARGET_WAITKIND_STOPPED;
status->value.sig = TARGET_SIGNAL_TERM;
break;
case UDIStopped:
status->kind = TARGET_WAITKIND_STOPPED;
status->value.sig = TARGET_SIGNAL_TSTP;
break;
case UDIWarned:
status->kind = TARGET_WAITKIND_STOPPED;
status->value.sig = TARGET_SIGNAL_URG;
break;
case UDIStepped:
case UDIBreak:
status->kind = TARGET_WAITKIND_STOPPED;
status->value.sig = TARGET_SIGNAL_TRAP;
break;
case UDIWaiting:
status->kind = TARGET_WAITKIND_STOPPED;
status->value.sig = TARGET_SIGNAL_STOP;
break;
case UDIHalted:
status->kind = TARGET_WAITKIND_STOPPED;
status->value.sig = TARGET_SIGNAL_KILL;
break;
case UDIExited:
default:
status->kind = TARGET_WAITKIND_EXITED;
status->value.integer = 0;
}
timeout = old_timeout;
immediate_quit = old_immediate_quit;
return inferior_pid;
}
#if 0
udi_pc (void)
{
UDIResource From;
UDIUInt32 *To;
UDICount Count;
UDISizeT Size = 4;
UDICount CountDone;
UDIBool HostEndian = 0;
UDIError err;
int pc[2];
unsigned long myregs[256];
int i;
From.Space = UDI29KPC;
From.Offset = 0;
To = (UDIUInt32 *) pc;
Count = 2;
err = UDIRead (From, To, Count, Size, &CountDone, HostEndian);
printf_unfiltered ("err = %d, CountDone = %d, pc[0] = 0x%x, pc[1] = 0x%x\n",
err, CountDone, pc[0], pc[1]);
udi_fetch_registers (-1);
printf_unfiltered ("other pc1 = 0x%x, pc0 = 0x%x\n", *(int *) ®isters[4 * PC_REGNUM],
*(int *) ®isters[4 * NPC_REGNUM]);
From.Space = UDI29KGlobalRegs;
From.Offset = 0;
err = UDIRead (From, myregs, 256, 4, &CountDone, HostEndian);
printf ("err = %d, CountDone = %d\n", err, CountDone);
printf ("\n");
for (i = 0; i < 256; i += 2)
printf ("%d:\t%#10x\t%11d\t%#10x\t%11d\n", i, myregs[i], myregs[i],
myregs[i + 1], myregs[i + 1]);
printf ("\n");
return pc[0];
}
#endif
static void
udi_fetch_registers (int regno)
{
UDIResource From;
UDIUInt32 *To;
UDICount Count;
UDISizeT Size = 4;
UDICount CountDone;
UDIBool HostEndian = 0;
UDIError err;
int i;
if (regno >= 0)
{
fetch_register (regno);
return;
}
From.Space = UDI29KGlobalRegs;
From.Offset = 1;
To = (UDIUInt32 *) & registers[4 * GR1_REGNUM];
Count = 1;
if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
error ("UDIRead() failed in udi_fetch_registers");
register_valid[GR1_REGNUM] = 1;
#if defined(GR64_REGNUM)
From.Space = UDI29KGlobalRegs;
From.Offset = 64;
To = (UDIUInt32 *) & registers[4 * GR64_REGNUM];
Count = 32;
if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
error ("UDIRead() failed in udi_fetch_registers");
for (i = GR64_REGNUM; i < GR64_REGNUM + 32; i++)
register_valid[i] = 1;
#endif
From.Space = UDI29KGlobalRegs;
From.Offset = 96;
To = (UDIUInt32 *) & registers[4 * GR96_REGNUM];
Count = 32;
if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
error ("UDIRead() failed in udi_fetch_registers");
for (i = GR96_REGNUM; i < GR96_REGNUM + 32; i++)
register_valid[i] = 1;
From.Space = UDI29KLocalRegs;
From.Offset = 0;
To = (UDIUInt32 *) & registers[4 * LR0_REGNUM];
Count = 128;
if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
error ("UDIRead() failed in udi_fetch_registers");
for (i = LR0_REGNUM; i < LR0_REGNUM + 128; i++)
register_valid[i] = 1;
From.Space = UDI29KSpecialRegs;
From.Offset = 0;
To = (UDIUInt32 *) & registers[4 * SR_REGNUM (0)];
Count = 15;
if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
error ("UDIRead() failed in udi_fetch_registers");
for (i = SR_REGNUM (0); i < SR_REGNUM (0) + 15; i++)
register_valid[i] = 1;
if (USE_SHADOW_PC)
{
fetch_register (NPC_REGNUM);
fetch_register (PC_REGNUM);
fetch_register (PC2_REGNUM);
From.Space = UDI29KSpecialRegs;
From.Offset = 128;
To = (UDIUInt32 *) & registers[4 * SR_REGNUM (128)];
Count = 135 - 128 + 1;
if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
error ("UDIRead() failed in udi_fetch_registers");
for (i = SR_REGNUM (128); i < SR_REGNUM (128) + 135 - 128 + 1; i++)
register_valid[i] = 1;
}
if (remote_debug)
{
fprintf_unfiltered (gdb_stdlog, "Fetching all registers\n");
fprintf_unfiltered (gdb_stdlog,
"Fetching PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n",
read_register (NPC_REGNUM),
read_register (PC_REGNUM),
read_register (PC2_REGNUM));
}
{
int val = -1;
supply_register (FPE_REGNUM, (char *) &val);
supply_register (INTE_REGNUM, (char *) &val);
supply_register (FPS_REGNUM, (char *) &val);
supply_register (EXO_REGNUM, (char *) &val);
}
}
static void
udi_store_registers (int regno)
{
UDIUInt32 *From;
UDIResource To;
UDICount Count;
UDISizeT Size = 4;
UDICount CountDone;
UDIBool HostEndian = 0;
if (regno >= 0)
{
store_register (regno);
return;
}
if (remote_debug)
{
fprintf_unfiltered (gdb_stdlog, "Storing all registers\n");
fprintf_unfiltered (gdb_stdlog,
"PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n",
read_register (NPC_REGNUM),
read_register (PC_REGNUM),
read_register (PC2_REGNUM));
}
From = (UDIUInt32 *) & registers[4 * GR1_REGNUM];
To.Space = UDI29KGlobalRegs;
To.Offset = 1;
Count = 1;
if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
error ("UDIWrite() failed in udi_store_regisetrs");
#if defined(GR64_REGNUM)
From = (UDIUInt32 *) & registers[4 * GR64_REGNUM];
To.Space = UDI29KGlobalRegs;
To.Offset = 64;
Count = 32;
if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
error ("UDIWrite() failed in udi_store_regisetrs");
#endif
From = (UDIUInt32 *) & registers[4 * GR96_REGNUM];
To.Space = UDI29KGlobalRegs;
To.Offset = 96;
Count = 32;
if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
error ("UDIWrite() failed in udi_store_regisetrs");
From = (UDIUInt32 *) & registers[4 * LR0_REGNUM];
To.Space = UDI29KLocalRegs;
To.Offset = 0;
Count = 128;
if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
error ("UDIWrite() failed in udi_store_regisetrs");
From = (UDIUInt32 *) & registers[4 * SR_REGNUM (0)];
To.Space = UDI29KSpecialRegs;
To.Offset = 0;
Count = 10;
if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
error ("UDIWrite() failed in udi_store_regisetrs");
From = (UDIUInt32 *) & registers[4 * SR_REGNUM (10)];
To.Space = UDI29KSpecialRegs;
Count = 3;
if (USE_SHADOW_PC)
To.Offset = 20;
else
To.Offset = 10;
if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
error ("UDIWrite() failed in udi_store_regisetrs");
From = (UDIUInt32 *) & registers[4 * PC_REGNUM];
To.Space = UDI29KPC;
To.Offset = 0;
Count = 1;
if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
error ("UDIWrite() failed in udi_store_regisetrs");
From = (UDIUInt32 *) & registers[4 * SR_REGNUM (13)];
To.Space = UDI29KSpecialRegs;
To.Offset = 13;
Count = 2;
if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
error ("UDIWrite() failed in udi_store_regisetrs");
From = (UDIUInt32 *) & registers[4 * SR_REGNUM (128)];
To.Space = UDI29KSpecialRegs;
To.Offset = 128;
Count = 135 - 128 + 1;
if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
error ("UDIWrite() failed in udi_store_regisetrs");
registers_changed ();
}
static void
udi_prepare_to_store (void)
{
}
static CORE_ADDR
translate_addr (CORE_ADDR addr)
{
#if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
if (addr >= UVADDR)
{
CORE_ADDR i = (CORE_ADDR) read_register (PADDR_U_REGNUM);
return (i + addr - (CORE_ADDR) UVADDR);
}
else
{
return (addr);
}
#else
return (addr);
#endif
}
static int
udi_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
struct target_ops * target)
{
memaddr = translate_addr (memaddr);
if (write)
return udi_write_inferior_memory (memaddr, myaddr, len);
else
return udi_read_inferior_memory (memaddr, myaddr, len);
}
static void
udi_files_info (struct target_ops *target)
{
printf_unfiltered ("\tAttached to UDI socket to %s", udi_config_id);
if (prog_name != NULL)
printf_unfiltered ("and running program %s", prog_name);
printf_unfiltered (".\n");
}
static int
udi_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
{
int cnt;
UDIError err;
for (cnt = 0; cnt < BKPT_TABLE_SIZE; cnt++)
if (bkpt_table[cnt].Type == 0)
break;
if (cnt >= BKPT_TABLE_SIZE)
error ("Too many breakpoints set");
bkpt_table[cnt].Addr.Offset = addr;
bkpt_table[cnt].Addr.Space = UDI29KIRAMSpace;
bkpt_table[cnt].PassCount = 1;
bkpt_table[cnt].Type = UDIBreakFlagExecute;
err = UDISetBreakpoint (bkpt_table[cnt].Addr,
bkpt_table[cnt].PassCount,
bkpt_table[cnt].Type,
&bkpt_table[cnt].BreakId);
if (err == 0)
return 0;
bkpt_table[cnt].Type = 0;
error ("UDISetBreakpoint returned error code %d\n", err);
}
static int
udi_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
{
int cnt;
UDIError err;
for (cnt = 0; cnt < BKPT_TABLE_SIZE; cnt++)
if (bkpt_table[cnt].Addr.Offset == addr)
break;
if (cnt >= BKPT_TABLE_SIZE)
error ("Can't find breakpoint in table");
bkpt_table[cnt].Type = 0;
err = UDIClearBreakpoint (bkpt_table[cnt].BreakId);
if (err == 0)
return 0;
error ("UDIClearBreakpoint returned error code %d\n", err);
}
static void
udi_kill (void)
{
#if 0
UDIStop ();
udi_session_id = -1;
inferior_pid = 0;
if (from_tty)
printf_unfiltered ("Target has been stopped.");
#endif
#if 0
udi_close (0);
pop_target ();
#endif
if (UDIDisconnect (udi_session_id, UDITerminateSession))
{
warning ("UDIDisconnect() failed");
}
udi_session_id = -1;
inferior_pid = 0;
}
static void
download (char *load_arg_string, int from_tty)
{
#define DEFAULT_MEM_STACK_SIZE 0x6000
#define DEFAULT_REG_STACK_SIZE 0x2000
char *token;
char *filename;
asection *section;
bfd *pbfd;
UDIError err;
int load_text = 1, load_data = 1, load_bss = 1, load_lit = 1;
address_ranges[0].Space = UDI29KIRAMSpace;
address_ranges[0].Offset = 0xffffffff;
address_ranges[0].Size = 0;
address_ranges[1].Space = UDI29KDRAMSpace;
address_ranges[1].Offset = 0xffffffff;
address_ranges[1].Size = 0;
stack_sizes[0] = DEFAULT_REG_STACK_SIZE;
stack_sizes[1] = DEFAULT_MEM_STACK_SIZE;
dont_repeat ();
filename = strtok (load_arg_string, " \t");
if (!filename)
error ("Must specify at least a file name with the load command");
filename = tilde_expand (filename);
make_cleanup (free, filename);
while (token = strtok (NULL, " \t"))
{
if (token[0] == '-')
{
token++;
if (STREQ (token, "ms"))
stack_sizes[1] = atol (strtok (NULL, " \t"));
else if (STREQ (token, "rs"))
stack_sizes[0] = atol (strtok (NULL, " \t"));
else
{
load_text = load_data = load_bss = load_lit = 0;
while (*token)
{
switch (*token++)
{
case 't':
case 'T':
load_text = 1;
break;
case 'd':
case 'D':
load_data = 1;
break;
case 'b':
case 'B':
load_bss = 1;
break;
case 'l':
case 'L':
load_lit = 1;
break;
default:
error ("Unknown UDI load option -%s", token - 1);
}
}
}
}
}
pbfd = bfd_openr (filename, gnutarget);
if (!pbfd)
perror_with_name (filename);
make_cleanup_bfd_close (pbfd);
QUIT;
immediate_quit++;
if (!bfd_check_format (pbfd, bfd_object))
error ("It doesn't seem to be an object file");
for (section = pbfd->sections; section; section = section->next)
{
if (bfd_get_section_flags (pbfd, section) & SEC_ALLOC)
{
UDIResource To;
UDICount Count;
unsigned long section_size, section_end;
const char *section_name;
section_name = bfd_get_section_name (pbfd, section);
if (STREQ (section_name, ".text") && !load_text)
continue;
else if (STREQ (section_name, ".data") && !load_data)
continue;
else if (STREQ (section_name, ".bss") && !load_bss)
continue;
else if (STREQ (section_name, ".lit") && !load_lit)
continue;
To.Offset = bfd_get_section_vma (pbfd, section);
section_size = bfd_section_size (pbfd, section);
section_end = To.Offset + section_size;
if (section_size == 0)
continue;
printf_unfiltered ("[Loading section %s at %x (%d bytes)]\n",
section_name,
To.Offset,
section_size);
if (bfd_get_section_flags (pbfd, section) & SEC_CODE)
{
To.Space = UDI29KIRAMSpace;
address_ranges[0].Offset = min (address_ranges[0].Offset,
To.Offset);
address_ranges[0].Size = max (address_ranges[0].Size,
section_end
- address_ranges[0].Offset);
}
else
{
To.Space = UDI29KDRAMSpace;
address_ranges[1].Offset = min (address_ranges[1].Offset,
To.Offset);
address_ranges[1].Size = max (address_ranges[1].Size,
section_end
- address_ranges[1].Offset);
}
if (bfd_get_section_flags (pbfd, section) & SEC_LOAD)
{
file_ptr fptr;
fptr = 0;
while (section_size > 0)
{
char buffer[1024];
Count = min (section_size, 1024);
bfd_get_section_contents (pbfd, section, buffer, fptr,
Count);
err = UDIWrite ((UDIHostMemPtr) buffer,
To,
Count,
(UDISizeT) 1,
&Count,
(UDIBool) 0);
if (err)
error ("UDIWrite failed, error = %d", err);
To.Offset += Count;
fptr += Count;
section_size -= Count;
}
}
else
{
UDIResource From;
unsigned long zero = 0;
err = UDIWrite ((UDIHostMemPtr) & zero,
To,
(UDICount) 1,
(UDISizeT) 4,
&Count,
(UDIBool) 0);
if (err)
error ("UDIWrite failed, error = %d", err);
From = To;
To.Offset += 4;
err = UDICopy (From,
To,
(UDICount) (section_size / 4 - 1),
(UDISizeT) 4,
&Count,
(UDIBool) 1);
if (err)
{
char message[100];
int xerr;
xerr = UDIGetErrorMsg (err, 100, message, &Count);
if (!xerr)
fprintf_unfiltered (gdb_stderr, "Error is %s\n", message);
else
fprintf_unfiltered (gdb_stderr, "xerr is %d\n", xerr);
error ("UDICopy failed, error = %d", err);
}
}
}
}
entry.Space = UDI29KIRAMSpace;
entry.Offset = bfd_get_start_address (pbfd);
immediate_quit--;
}
static void
udi_load (char *args, int from_tty)
{
download (args, from_tty);
symbol_file_add (strtok (args, " \t"), from_tty, NULL, 1, 0);
reinit_frame_cache ();
}
static int
udi_write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
{
int nwritten = 0;
UDIUInt32 *From;
UDIResource To;
UDICount Count;
UDISizeT Size = 1;
UDICount CountDone = 0;
UDIBool HostEndian = 0;
To.Space = udi_memory_space (memaddr);
From = (UDIUInt32 *) myaddr;
while (nwritten < len)
{
Count = len - nwritten;
if (Count > MAXDATA)
Count = MAXDATA;
To.Offset = memaddr + nwritten;
if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
{
error ("UDIWrite() failed in udi_write_inferior_memory");
break;
}
else
{
nwritten += CountDone;
From += CountDone;
}
}
return (nwritten);
}
static int
udi_read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
{
int nread = 0;
UDIResource From;
UDIUInt32 *To;
UDICount Count;
UDISizeT Size = 1;
UDICount CountDone = 0;
UDIBool HostEndian = 0;
UDIError err;
From.Space = udi_memory_space (memaddr);
To = (UDIUInt32 *) myaddr;
while (nread < len)
{
Count = len - nread;
if (Count > MAXDATA)
Count = MAXDATA;
From.Offset = memaddr + nread;
if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
{
error ("UDIRead() failed in udi_read_inferior_memory");
break;
}
else
{
nread += CountDone;
To += CountDone;
}
}
return (nread);
}
udi_warning (int num)
{
error ("ERROR while loading program into remote TIP: $d\n", num);
}
static void
fetch_register (int regno)
{
UDIResource From;
UDIUInt32 To;
UDICount Count = 1;
UDISizeT Size = 4;
UDICount CountDone;
UDIBool HostEndian = 0;
UDIError err;
int result;
if (regno == GR1_REGNUM)
{
From.Space = UDI29KGlobalRegs;
From.Offset = 1;
}
else if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32)
{
From.Space = UDI29KGlobalRegs;
From.Offset = (regno - GR96_REGNUM) + 96;;
}
#if defined(GR64_REGNUM)
else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32)
{
From.Space = UDI29KGlobalRegs;
From.Offset = (regno - GR64_REGNUM) + 64;
}
#endif
else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128)
{
From.Space = UDI29KLocalRegs;
From.Offset = (regno - LR0_REGNUM);
}
else if (regno >= FPE_REGNUM && regno <= EXO_REGNUM)
{
int val = -1;
supply_register (regno, (char *) &val);
return;
}
else
{
From.Space = UDI29KSpecialRegs;
From.Offset = regnum_to_srnum (regno);
}
if (err = UDIRead (From, &To, Count, Size, &CountDone, HostEndian))
error ("UDIRead() failed in udi_fetch_registers");
supply_register (regno, (char *) &To);
if (remote_debug)
fprintf_unfiltered (gdb_stdlog, "Fetching register %s = 0x%x\n",
REGISTER_NAME (regno), To);
}
static int
store_register (int regno)
{
int result;
UDIUInt32 From;
UDIResource To;
UDICount Count = 1;
UDISizeT Size = 4;
UDICount CountDone;
UDIBool HostEndian = 0;
From = read_register (regno);
if (remote_debug)
fprintf_unfiltered (gdb_stdlog, "Storing register %s = 0x%x\n",
REGISTER_NAME (regno), From);
if (regno == GR1_REGNUM)
{
To.Space = UDI29KGlobalRegs;
To.Offset = 1;
result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian);
registers_changed ();
}
#if defined(GR64_REGNUM)
else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32)
{
To.Space = UDI29KGlobalRegs;
To.Offset = (regno - GR64_REGNUM) + 64;
result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian);
}
#endif
else if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32)
{
To.Space = UDI29KGlobalRegs;
To.Offset = (regno - GR96_REGNUM) + 96;
result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian);
}
else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128)
{
To.Space = UDI29KLocalRegs;
To.Offset = (regno - LR0_REGNUM);
result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian);
}
else if (regno >= FPE_REGNUM && regno <= EXO_REGNUM)
return 0;
else if (regno == PC_REGNUM)
{
To.Space = UDI29KPC;
To.Offset = 0;
result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian);
register_valid[PC_REGNUM] = 0;
register_valid[NPC_REGNUM] = 0;
}
else
{
To.Space = UDI29KSpecialRegs;
To.Offset = regnum_to_srnum (regno);
result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian);
}
if (result != 0)
error ("UDIWrite() failed in store_registers");
return 0;
}
static int
regnum_to_srnum (int regno)
{
switch (regno)
{
case VAB_REGNUM:
return (0);
case OPS_REGNUM:
return (1);
case CPS_REGNUM:
return (2);
case CFG_REGNUM:
return (3);
case CHA_REGNUM:
return (4);
case CHD_REGNUM:
return (5);
case CHC_REGNUM:
return (6);
case RBP_REGNUM:
return (7);
case TMC_REGNUM:
return (8);
case TMR_REGNUM:
return (9);
case NPC_REGNUM:
return (USE_SHADOW_PC ? (20) : (10));
case PC_REGNUM:
return (USE_SHADOW_PC ? (21) : (11));
case PC2_REGNUM:
return (USE_SHADOW_PC ? (22) : (12));
case MMU_REGNUM:
return (13);
case LRU_REGNUM:
return (14);
case IPC_REGNUM:
return (128);
case IPA_REGNUM:
return (129);
case IPB_REGNUM:
return (130);
case Q_REGNUM:
return (131);
case ALU_REGNUM:
return (132);
case BP_REGNUM:
return (133);
case FC_REGNUM:
return (134);
case CR_REGNUM:
return (135);
case FPE_REGNUM:
return (160);
case INTE_REGNUM:
return (161);
case FPS_REGNUM:
return (162);
case EXO_REGNUM:
return (164);
default:
return (255);
}
}
static CPUSpace
udi_memory_space (CORE_ADDR addr)
{
UDIUInt32 tstart = IMemStart;
UDIUInt32 tend = tstart + IMemSize;
UDIUInt32 dstart = DMemStart;
UDIUInt32 dend = tstart + DMemSize;
UDIUInt32 rstart = RMemStart;
UDIUInt32 rend = tstart + RMemSize;
if (((UDIUInt32) addr >= tstart) && ((UDIUInt32) addr < tend))
{
return UDI29KIRAMSpace;
}
else if (((UDIUInt32) addr >= dstart) && ((UDIUInt32) addr < dend))
{
return UDI29KDRAMSpace;
}
else if (((UDIUInt32) addr >= rstart) && ((UDIUInt32) addr < rend))
{
return UDI29KIROMSpace;
}
else
return UDI29KDRAMSpace;
}
void
convert16 (void)
{;
}
void
convert32 (void)
{;
}
struct ui_file *EchoFile = 0;
int QuietMode = 0;
#ifdef NO_HIF_SUPPORT
service_HIF (union msg_t *msg)
{
return (0);
}
#endif
struct target_ops udi_ops;
static void
init_udi_ops (void)
{
udi_ops.to_shortname = "udi";
udi_ops.to_longname = "Remote UDI connected TIP";
udi_ops.to_doc = "Remote debug an AMD 29k using UDI socket connection to TIP process.\n\
Arguments are\n\
`configuration-id AF_INET hostname port-number'\n\
To connect via the network, where hostname and port-number specify the\n\
host and port where you can connect via UDI.\n\
configuration-id is unused.\n\
\n\
`configuration-id AF_UNIX socket-name tip-program'\n\
To connect using a local connection to the \"tip.exe\" program which is\n\
supplied by AMD. If socket-name specifies an AF_UNIX socket then the\n\
tip program must already be started; connect to it using that socket.\n\
If not, start up tip-program, which should be the name of the tip\n\
program. If appropriate, the PATH environment variable is searched.\n\
configuration-id is unused.\n\
\n\
`configuration-id'\n\
Look up the configuration in ./udi_soc or /etc/udi_soc, which\n\
are files containing lines in the above formats. configuration-id is\n\
used to pick which line of the file to use.";
udi_ops.to_open = udi_open;
udi_ops.to_close = udi_close;
udi_ops.to_attach = udi_attach;
udi_ops.to_detach = udi_detach;
udi_ops.to_resume = udi_resume;
udi_ops.to_wait = udi_wait;
udi_ops.to_fetch_registers = udi_fetch_registers;
udi_ops.to_store_registers = udi_store_registers;
udi_ops.to_prepare_to_store = udi_prepare_to_store;
udi_ops.to_xfer_memory = udi_xfer_inferior_memory;
udi_ops.to_files_info = udi_files_info;
udi_ops.to_insert_breakpoint = udi_insert_breakpoint;
udi_ops.to_remove_breakpoint = udi_remove_breakpoint;
udi_ops.to_terminal_init = 0;
udi_ops.to_terminal_inferior = 0;
udi_ops.to_terminal_ours_for_output = 0;
udi_ops.to_terminal_ours = 0;
udi_ops.to_terminal_info = 0;
udi_ops.to_kill = udi_kill;
udi_ops.to_load = udi_load;
udi_ops.to_lookup_symbol = 0;
udi_ops.to_create_inferior = udi_create_inferior;
udi_ops.to_mourn_inferior = udi_mourn;
udi_ops.to_can_run = 0;
udi_ops.to_notice_signals = 0;
udi_ops.to_thread_alive = 0;
udi_ops.to_stop = 0;
udi_ops.to_stratum = process_stratum;
udi_ops.DONT_USE = 0;
udi_ops.to_has_all_memory = 1;
udi_ops.to_has_memory = 1;
udi_ops.to_has_stack = 1;
udi_ops.to_has_registers = 1;
udi_ops.to_has_execution = 1;
udi_ops.to_sections = 0;
udi_ops.to_sections_end = 0;
udi_ops.to_magic = OPS_MAGIC;
};
void
_initialize_remote_udi (void)
{
init_udi_ops ();
add_target (&udi_ops);
}