1130812Smarcel/* Remote debugging for the ARM RDP interface. 2130812Smarcel 3130812Smarcel Copyright 1994, 1995, 1998, 1999, 2000, 2001, 2002, 2003 Free 4130812Smarcel Software Foundation, Inc. 5130812Smarcel 6130812Smarcel This file is part of GDB. 7130812Smarcel 8130812Smarcel This program is free software; you can redistribute it and/or modify 9130812Smarcel it under the terms of the GNU General Public License as published by 10130812Smarcel the Free Software Foundation; either version 2 of the License, or 11130812Smarcel (at your option) any later version. 12130812Smarcel 13130812Smarcel This program is distributed in the hope that it will be useful, 14130812Smarcel but WITHOUT ANY WARRANTY; without even the implied warranty of 15130812Smarcel MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16130812Smarcel GNU General Public License for more details. 17130812Smarcel 18130812Smarcel You should have received a copy of the GNU General Public License 19130812Smarcel along with this program; if not, write to the Free Software 20130812Smarcel Foundation, Inc., 59 Temple Place - Suite 330, 21130812Smarcel Boston, MA 02111-1307, USA. 22130812Smarcel 23130812Smarcel 24130812Smarcel */ 25130812Smarcel 26130812Smarcel 27130812Smarcel/* 28130812Smarcel Much of this file (in particular the SWI stuff) is based on code by 29130812Smarcel David Taylor (djt1000@uk.ac.cam.hermes). 30130812Smarcel 31130812Smarcel I hacked on and simplified it by removing a lot of sexy features he 32130812Smarcel had added, and some of the (unix specific) workarounds he'd done 33130812Smarcel for other GDB problems - which if they still exist should be fixed 34130812Smarcel in GDB, not in a remote-foo thing . I also made it conform more to 35130812Smarcel the doc I have; which may be wrong. 36130812Smarcel 37130812Smarcel Steve Chamberlain (sac@cygnus.com). 38130812Smarcel */ 39130812Smarcel 40130812Smarcel 41130812Smarcel#include "defs.h" 42130812Smarcel#include "inferior.h" 43130812Smarcel#include "value.h" 44130812Smarcel#include "gdb/callback.h" 45130812Smarcel#include "command.h" 46130812Smarcel#include <ctype.h> 47130812Smarcel#include <fcntl.h> 48130812Smarcel#include "symfile.h" 49130812Smarcel#include "remote-utils.h" 50130812Smarcel#include "gdb_string.h" 51130812Smarcel#include "gdbcore.h" 52130812Smarcel#include "regcache.h" 53130812Smarcel#include "serial.h" 54130812Smarcel 55130812Smarcel#include "arm-tdep.h" 56130812Smarcel 57130812Smarcel#ifdef HAVE_TIME_H 58130812Smarcel#include <time.h> 59130812Smarcel#endif 60130812Smarcel 61130812Smarcelextern struct target_ops remote_rdp_ops; 62130812Smarcelstatic struct serial *io; 63130812Smarcelstatic host_callback *callback = &default_callback; 64130812Smarcel 65130812Smarcelstruct 66130812Smarcel { 67130812Smarcel int step_info; 68130812Smarcel int break_info; 69130812Smarcel int model_info; 70130812Smarcel int target_info; 71130812Smarcel int can_step; 72130812Smarcel char command_line[10]; 73130812Smarcel int rdi_level; 74130812Smarcel int rdi_stopped_status; 75130812Smarcel } 76130812Smarcelds; 77130812Smarcel 78130812Smarcel 79130812Smarcel 80130812Smarcel/* Definitions for the RDP protocol. */ 81130812Smarcel 82130812Smarcel#define RDP_MOUTHFULL (1<<6) 83130812Smarcel#define FPU_COPRO_NUMBER 1 84130812Smarcel 85130812Smarcel#define RDP_OPEN 0 86130812Smarcel#define RDP_OPEN_TYPE_COLD 0 87130812Smarcel#define RDP_OPEN_TYPE_WARM 1 88130812Smarcel#define RDP_OPEN_TYPE_BAUDRATE 2 89130812Smarcel 90130812Smarcel#define RDP_OPEN_BAUDRATE_9600 1 91130812Smarcel#define RDP_OPEN_BAUDRATE_19200 2 92130812Smarcel#define RDP_OPEN_BAUDRATE_38400 3 93130812Smarcel 94130812Smarcel#define RDP_OPEN_TYPE_RETURN_SEX (1<<3) 95130812Smarcel 96130812Smarcel#define RDP_CLOSE 1 97130812Smarcel 98130812Smarcel#define RDP_MEM_READ 2 99130812Smarcel 100130812Smarcel#define RDP_MEM_WRITE 3 101130812Smarcel 102130812Smarcel#define RDP_CPU_READ 4 103130812Smarcel#define RDP_CPU_WRITE 5 104130812Smarcel#define RDP_CPU_READWRITE_MODE_CURRENT 255 105130812Smarcel#define RDP_CPU_READWRITE_MASK_PC (1<<16) 106130812Smarcel#define RDP_CPU_READWRITE_MASK_CPSR (1<<17) 107130812Smarcel#define RDP_CPU_READWRITE_MASK_SPSR (1<<18) 108130812Smarcel 109130812Smarcel#define RDP_COPRO_READ 6 110130812Smarcel#define RDP_COPRO_WRITE 7 111130812Smarcel#define RDP_FPU_READWRITE_MASK_FPS (1<<8) 112130812Smarcel 113130812Smarcel#define RDP_SET_BREAK 0xa 114130812Smarcel#define RDP_SET_BREAK_TYPE_PC_EQUAL 0 115130812Smarcel#define RDP_SET_BREAK_TYPE_GET_HANDLE (0x10) 116130812Smarcel 117130812Smarcel#define RDP_CLEAR_BREAK 0xb 118130812Smarcel 119130812Smarcel#define RDP_EXEC 0x10 120130812Smarcel#define RDP_EXEC_TYPE_SYNC 0 121130812Smarcel 122130812Smarcel#define RDP_STEP 0x11 123130812Smarcel 124130812Smarcel#define RDP_INFO 0x12 125130812Smarcel#define RDP_INFO_ABOUT_STEP 2 126130812Smarcel#define RDP_INFO_ABOUT_STEP_GT_1 1 127130812Smarcel#define RDP_INFO_ABOUT_STEP_TO_JMP 2 128130812Smarcel#define RDP_INFO_ABOUT_STEP_1 4 129130812Smarcel#define RDP_INFO_ABOUT_TARGET 0 130130812Smarcel#define RDP_INFO_ABOUT_BREAK 1 131130812Smarcel#define RDP_INFO_ABOUT_BREAK_COMP 1 132130812Smarcel#define RDP_INFO_ABOUT_BREAK_RANGE 2 133130812Smarcel#define RDP_INFO_ABOUT_BREAK_BYTE_READ 4 134130812Smarcel#define RDP_INFO_ABOUT_BREAK_HALFWORD_READ 8 135130812Smarcel#define RDP_INFO_ABOUT_BREAK_WORD_READ (1<<4) 136130812Smarcel#define RDP_INFO_ABOUT_BREAK_BYTE_WRITE (1<<5) 137130812Smarcel#define RDP_INFO_ABOUT_BREAK_HALFWORD_WRITE (1<<6) 138130812Smarcel#define RDP_INFO_ABOUT_BREAK_WORD_WRITE (1<<7) 139130812Smarcel#define RDP_INFO_ABOUT_BREAK_MASK (1<<8) 140130812Smarcel#define RDP_INFO_ABOUT_BREAK_THREAD_BREAK (1<<9) 141130812Smarcel#define RDP_INFO_ABOUT_BREAK_THREAD_WATCH (1<<10) 142130812Smarcel#define RDP_INFO_ABOUT_BREAK_COND (1<<11) 143130812Smarcel#define RDP_INFO_VECTOR_CATCH (0x180) 144130812Smarcel#define RDP_INFO_ICEBREAKER (7) 145130812Smarcel#define RDP_INFO_SET_CMDLINE (0x300) 146130812Smarcel 147130812Smarcel#define RDP_SELECT_CONFIG (0x16) 148130812Smarcel#define RDI_ConfigCPU 0 149130812Smarcel#define RDI_ConfigSystem 1 150130812Smarcel#define RDI_MatchAny 0 151130812Smarcel#define RDI_MatchExactly 1 152130812Smarcel#define RDI_MatchNoEarlier 2 153130812Smarcel 154130812Smarcel#define RDP_RESET 0x7f 155130812Smarcel 156130812Smarcel/* Returns from RDP */ 157130812Smarcel#define RDP_RES_STOPPED 0x20 158130812Smarcel#define RDP_RES_SWI 0x21 159130812Smarcel#define RDP_RES_FATAL 0x5e 160130812Smarcel#define RDP_RES_VALUE 0x5f 161130812Smarcel#define RDP_RES_VALUE_LITTLE_ENDIAN 240 162130812Smarcel#define RDP_RES_VALUE_BIG_ENDIAN 241 163130812Smarcel#define RDP_RES_RESET 0x7f 164130812Smarcel#define RDP_RES_AT_BREAKPOINT 143 165130812Smarcel#define RDP_RES_IDUNNO 0xe6 166130812Smarcel#define RDP_OSOpReply 0x13 167130812Smarcel#define RDP_OSOpWord 2 168130812Smarcel#define RDP_OSOpNothing 0 169130812Smarcel 170130812Smarcelstatic int timeout = 2; 171130812Smarcel 172130812Smarcelstatic char *commandline = NULL; 173130812Smarcel 174130812Smarcelstatic int 175130812Smarcelremote_rdp_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, 176130812Smarcel int write, 177130812Smarcel struct mem_attrib *attrib, 178130812Smarcel struct target_ops *target); 179130812Smarcel 180130812Smarcel 181130812Smarcel/* Stuff for talking to the serial layer. */ 182130812Smarcel 183130812Smarcelstatic unsigned char 184130812Smarcelget_byte (void) 185130812Smarcel{ 186130812Smarcel int c = serial_readchar (io, timeout); 187130812Smarcel 188130812Smarcel if (remote_debug) 189130812Smarcel fprintf_unfiltered (gdb_stdlog, "[%02x]\n", c); 190130812Smarcel 191130812Smarcel if (c == SERIAL_TIMEOUT) 192130812Smarcel { 193130812Smarcel if (timeout == 0) 194130812Smarcel return (unsigned char) c; 195130812Smarcel 196130812Smarcel error ("Timeout reading from remote_system"); 197130812Smarcel } 198130812Smarcel 199130812Smarcel return c; 200130812Smarcel} 201130812Smarcel 202130812Smarcel/* Note that the target always speaks little-endian to us, 203130812Smarcel even if it's a big endian machine. */ 204130812Smarcelstatic unsigned int 205130812Smarcelget_word (void) 206130812Smarcel{ 207130812Smarcel unsigned int val = 0; 208130812Smarcel unsigned int c; 209130812Smarcel int n; 210130812Smarcel for (n = 0; n < 4; n++) 211130812Smarcel { 212130812Smarcel c = get_byte (); 213130812Smarcel val |= c << (n * 8); 214130812Smarcel } 215130812Smarcel return val; 216130812Smarcel} 217130812Smarcel 218130812Smarcelstatic void 219130812Smarcelput_byte (char val) 220130812Smarcel{ 221130812Smarcel if (remote_debug) 222130812Smarcel fprintf_unfiltered (gdb_stdlog, "(%02x)\n", val); 223130812Smarcel serial_write (io, &val, 1); 224130812Smarcel} 225130812Smarcel 226130812Smarcelstatic void 227130812Smarcelput_word (int val) 228130812Smarcel{ 229130812Smarcel /* We always send in little endian */ 230130812Smarcel unsigned char b[4]; 231130812Smarcel b[0] = val; 232130812Smarcel b[1] = val >> 8; 233130812Smarcel b[2] = val >> 16; 234130812Smarcel b[3] = val >> 24; 235130812Smarcel 236130812Smarcel if (remote_debug) 237130812Smarcel fprintf_unfiltered (gdb_stdlog, "(%04x)", val); 238130812Smarcel 239130812Smarcel serial_write (io, b, 4); 240130812Smarcel} 241130812Smarcel 242130812Smarcel 243130812Smarcel 244130812Smarcel/* Stuff for talking to the RDP layer. */ 245130812Smarcel 246130812Smarcel/* This is a bit more fancy that need be so that it syncs even in nasty cases. 247130812Smarcel 248130812Smarcel I'be been unable to make it reliably sync up with the change 249130812Smarcel baudrate open command. It likes to sit and say it's been reset, 250130812Smarcel with no more action. So I took all that code out. I'd rather sync 251130812Smarcel reliably at 9600 than wait forever for a possible 19200 connection. 252130812Smarcel 253130812Smarcel */ 254130812Smarcelstatic void 255130812Smarcelrdp_init (int cold, int tty) 256130812Smarcel{ 257130812Smarcel int sync = 0; 258130812Smarcel int type = cold ? RDP_OPEN_TYPE_COLD : RDP_OPEN_TYPE_WARM; 259130812Smarcel int baudtry = 9600; 260130812Smarcel 261130812Smarcel time_t now = time (0); 262130812Smarcel time_t stop_time = now + 10; /* Try and sync for 10 seconds, then give up */ 263130812Smarcel 264130812Smarcel 265130812Smarcel while (time (0) < stop_time && !sync) 266130812Smarcel { 267130812Smarcel int restype; 268130812Smarcel QUIT; 269130812Smarcel 270130812Smarcel serial_flush_input (io); 271130812Smarcel serial_flush_output (io); 272130812Smarcel 273130812Smarcel if (tty) 274130812Smarcel printf_unfiltered ("Trying to connect at %d baud.\n", baudtry); 275130812Smarcel 276130812Smarcel /* 277130812Smarcel ** It seems necessary to reset an EmbeddedICE to get it going. 278130812Smarcel ** This has the side benefit of displaying the startup banner. 279130812Smarcel */ 280130812Smarcel if (cold) 281130812Smarcel { 282130812Smarcel put_byte (RDP_RESET); 283130812Smarcel while ((restype = serial_readchar (io, 1)) > 0) 284130812Smarcel { 285130812Smarcel switch (restype) 286130812Smarcel { 287130812Smarcel case SERIAL_TIMEOUT: 288130812Smarcel break; 289130812Smarcel case RDP_RESET: 290130812Smarcel /* Sent at start of reset process: ignore */ 291130812Smarcel break; 292130812Smarcel default: 293130812Smarcel printf_unfiltered ("%c", isgraph (restype) ? restype : ' '); 294130812Smarcel break; 295130812Smarcel } 296130812Smarcel } 297130812Smarcel 298130812Smarcel if (restype == 0) 299130812Smarcel { 300130812Smarcel /* Got end-of-banner mark */ 301130812Smarcel printf_filtered ("\n"); 302130812Smarcel } 303130812Smarcel } 304130812Smarcel 305130812Smarcel put_byte (RDP_OPEN); 306130812Smarcel 307130812Smarcel put_byte (type | RDP_OPEN_TYPE_RETURN_SEX); 308130812Smarcel put_word (0); 309130812Smarcel 310130812Smarcel while (!sync && (restype = serial_readchar (io, 1)) > 0) 311130812Smarcel { 312130812Smarcel if (remote_debug) 313130812Smarcel fprintf_unfiltered (gdb_stdlog, "[%02x]\n", restype); 314130812Smarcel 315130812Smarcel switch (restype) 316130812Smarcel { 317130812Smarcel case SERIAL_TIMEOUT: 318130812Smarcel break; 319130812Smarcel 320130812Smarcel case RDP_RESET: 321130812Smarcel while ((restype = serial_readchar (io, 1)) == RDP_RESET) 322130812Smarcel ; 323130812Smarcel do 324130812Smarcel { 325130812Smarcel printf_unfiltered ("%c", isgraph (restype) ? restype : ' '); 326130812Smarcel } 327130812Smarcel while ((restype = serial_readchar (io, 1)) > 0); 328130812Smarcel 329130812Smarcel if (tty) 330130812Smarcel { 331130812Smarcel printf_unfiltered ("\nThe board has sent notification that it was reset.\n"); 332130812Smarcel printf_unfiltered ("Waiting for it to settle down...\n"); 333130812Smarcel } 334130812Smarcel sleep (3); 335130812Smarcel if (tty) 336130812Smarcel printf_unfiltered ("\nTrying again.\n"); 337130812Smarcel cold = 0; 338130812Smarcel break; 339130812Smarcel 340130812Smarcel default: 341130812Smarcel break; 342130812Smarcel 343130812Smarcel case RDP_RES_VALUE: 344130812Smarcel { 345130812Smarcel int resval = serial_readchar (io, 1); 346130812Smarcel 347130812Smarcel if (remote_debug) 348130812Smarcel fprintf_unfiltered (gdb_stdlog, "[%02x]\n", resval); 349130812Smarcel 350130812Smarcel switch (resval) 351130812Smarcel { 352130812Smarcel case SERIAL_TIMEOUT: 353130812Smarcel break; 354130812Smarcel case RDP_RES_VALUE_LITTLE_ENDIAN: 355130812Smarcel#if 0 356130812Smarcel /* FIXME: cagney/2003-11-22: Ever since the ARM 357130812Smarcel was multi-arched (in 2002-02-08), this 358130812Smarcel assignment has had no effect. There needs to 359130812Smarcel be some sort of check/decision based on the 360130812Smarcel current architecture's byte-order vs the remote 361130812Smarcel target's byte order. For the moment disable 362130812Smarcel the assignment to keep things building. */ 363130812Smarcel target_byte_order = BFD_ENDIAN_LITTLE; 364130812Smarcel#endif 365130812Smarcel sync = 1; 366130812Smarcel break; 367130812Smarcel case RDP_RES_VALUE_BIG_ENDIAN: 368130812Smarcel#if 0 369130812Smarcel /* FIXME: cagney/2003-11-22: Ever since the ARM 370130812Smarcel was multi-arched (in 2002-02-08), this 371130812Smarcel assignment has had no effect. There needs to 372130812Smarcel be some sort of check/decision based on the 373130812Smarcel current architecture's byte-order vs the remote 374130812Smarcel target's byte order. For the moment disable 375130812Smarcel the assignment to keep things building. */ 376130812Smarcel target_byte_order = BFD_ENDIAN_BIG; 377130812Smarcel#endif 378130812Smarcel sync = 1; 379130812Smarcel break; 380130812Smarcel default: 381130812Smarcel break; 382130812Smarcel } 383130812Smarcel } 384130812Smarcel } 385130812Smarcel } 386130812Smarcel } 387130812Smarcel 388130812Smarcel if (!sync) 389130812Smarcel { 390130812Smarcel error ("Couldn't reset the board, try pressing the reset button"); 391130812Smarcel } 392130812Smarcel} 393130812Smarcel 394130812Smarcel 395130812Smarcelstatic void 396130812Smarcelsend_rdp (char *template,...) 397130812Smarcel{ 398130812Smarcel char buf[200]; 399130812Smarcel char *dst = buf; 400130812Smarcel va_list alist; 401130812Smarcel va_start (alist, template); 402130812Smarcel 403130812Smarcel while (*template) 404130812Smarcel { 405130812Smarcel unsigned int val; 406130812Smarcel int *pi; 407130812Smarcel int *pstat; 408130812Smarcel char *pc; 409130812Smarcel int i; 410130812Smarcel switch (*template++) 411130812Smarcel { 412130812Smarcel case 'b': 413130812Smarcel val = va_arg (alist, int); 414130812Smarcel *dst++ = val; 415130812Smarcel break; 416130812Smarcel case 'w': 417130812Smarcel val = va_arg (alist, int); 418130812Smarcel *dst++ = val; 419130812Smarcel *dst++ = val >> 8; 420130812Smarcel *dst++ = val >> 16; 421130812Smarcel *dst++ = val >> 24; 422130812Smarcel break; 423130812Smarcel case 'S': 424130812Smarcel val = get_byte (); 425130812Smarcel if (val != RDP_RES_VALUE) 426130812Smarcel { 427130812Smarcel printf_unfiltered ("got bad res value of %d, %x\n", val, val); 428130812Smarcel } 429130812Smarcel break; 430130812Smarcel case 'V': 431130812Smarcel pstat = va_arg (alist, int *); 432130812Smarcel pi = va_arg (alist, int *); 433130812Smarcel 434130812Smarcel *pstat = get_byte (); 435130812Smarcel /* Check the result was zero, if not read the syndrome */ 436130812Smarcel if (*pstat) 437130812Smarcel { 438130812Smarcel *pi = get_word (); 439130812Smarcel } 440130812Smarcel break; 441130812Smarcel case 'Z': 442130812Smarcel /* Check the result code */ 443130812Smarcel switch (get_byte ()) 444130812Smarcel { 445130812Smarcel case 0: 446130812Smarcel /* Success */ 447130812Smarcel break; 448130812Smarcel case 253: 449130812Smarcel /* Target can't do it; never mind */ 450130812Smarcel printf_unfiltered ("RDP: Insufficient privilege\n"); 451130812Smarcel return; 452130812Smarcel case 254: 453130812Smarcel /* Target can't do it; never mind */ 454130812Smarcel printf_unfiltered ("RDP: Unimplemented message\n"); 455130812Smarcel return; 456130812Smarcel case 255: 457130812Smarcel error ("Command garbled"); 458130812Smarcel break; 459130812Smarcel default: 460130812Smarcel error ("Corrupt reply from target"); 461130812Smarcel break; 462130812Smarcel } 463130812Smarcel break; 464130812Smarcel case 'W': 465130812Smarcel /* Read a word from the target */ 466130812Smarcel pi = va_arg (alist, int *); 467130812Smarcel *pi = get_word (); 468130812Smarcel break; 469130812Smarcel case 'P': 470130812Smarcel /* Read in some bytes from the target. */ 471130812Smarcel pc = va_arg (alist, char *); 472130812Smarcel val = va_arg (alist, int); 473130812Smarcel for (i = 0; i < val; i++) 474130812Smarcel { 475130812Smarcel pc[i] = get_byte (); 476130812Smarcel } 477130812Smarcel break; 478130812Smarcel case 'p': 479130812Smarcel /* send what's being pointed at */ 480130812Smarcel pc = va_arg (alist, char *); 481130812Smarcel val = va_arg (alist, int); 482130812Smarcel dst = buf; 483130812Smarcel serial_write (io, pc, val); 484130812Smarcel break; 485130812Smarcel case '-': 486130812Smarcel /* Send whats in the queue */ 487130812Smarcel if (dst != buf) 488130812Smarcel { 489130812Smarcel serial_write (io, buf, dst - buf); 490130812Smarcel dst = buf; 491130812Smarcel } 492130812Smarcel break; 493130812Smarcel case 'B': 494130812Smarcel pi = va_arg (alist, int *); 495130812Smarcel *pi = get_byte (); 496130812Smarcel break; 497130812Smarcel default: 498130812Smarcel internal_error (__FILE__, __LINE__, "failed internal consistency check"); 499130812Smarcel } 500130812Smarcel } 501130812Smarcel va_end (alist); 502130812Smarcel 503130812Smarcel if (dst != buf) 504130812Smarcel internal_error (__FILE__, __LINE__, "failed internal consistency check"); 505130812Smarcel} 506130812Smarcel 507130812Smarcel 508130812Smarcelstatic int 509130812Smarcelrdp_write (CORE_ADDR memaddr, char *buf, int len) 510130812Smarcel{ 511130812Smarcel int res; 512130812Smarcel int val; 513130812Smarcel 514130812Smarcel send_rdp ("bww-p-SV", RDP_MEM_WRITE, memaddr, len, buf, len, &res, &val); 515130812Smarcel 516130812Smarcel if (res) 517130812Smarcel { 518130812Smarcel return val; 519130812Smarcel } 520130812Smarcel return len; 521130812Smarcel} 522130812Smarcel 523130812Smarcel 524130812Smarcelstatic int 525130812Smarcelrdp_read (CORE_ADDR memaddr, char *buf, int len) 526130812Smarcel{ 527130812Smarcel int res; 528130812Smarcel int val; 529130812Smarcel send_rdp ("bww-S-P-V", 530130812Smarcel RDP_MEM_READ, memaddr, len, 531130812Smarcel buf, len, 532130812Smarcel &res, &val); 533130812Smarcel if (res) 534130812Smarcel { 535130812Smarcel return val; 536130812Smarcel } 537130812Smarcel return len; 538130812Smarcel} 539130812Smarcel 540130812Smarcelstatic void 541130812Smarcelrdp_fetch_one_register (int mask, char *buf) 542130812Smarcel{ 543130812Smarcel int val; 544130812Smarcel send_rdp ("bbw-SWZ", RDP_CPU_READ, RDP_CPU_READWRITE_MODE_CURRENT, mask, &val); 545130812Smarcel store_signed_integer (buf, 4, val); 546130812Smarcel} 547130812Smarcel 548130812Smarcelstatic void 549130812Smarcelrdp_fetch_one_fpu_register (int mask, char *buf) 550130812Smarcel{ 551130812Smarcel#if 0 552130812Smarcel /* !!! Since the PIE board doesn't work as documented, 553130812Smarcel and it doesn't have FPU hardware anyway and since it 554130812Smarcel slows everything down, I've disabled this. */ 555130812Smarcel int val; 556130812Smarcel if (mask == RDP_FPU_READWRITE_MASK_FPS) 557130812Smarcel { 558130812Smarcel /* this guy is only a word */ 559130812Smarcel send_rdp ("bbw-SWZ", RDP_COPRO_READ, FPU_COPRO_NUMBER, mask, &val); 560130812Smarcel store_signed_integer (buf, 4, val); 561130812Smarcel } 562130812Smarcel else 563130812Smarcel { 564130812Smarcel /* There are 12 bytes long 565130812Smarcel !! fixme about endianness 566130812Smarcel */ 567130812Smarcel int dummy; /* I've seen these come back as four words !! */ 568130812Smarcel send_rdp ("bbw-SWWWWZ", RDP_COPRO_READ, FPU_COPRO_NUMBER, mask, buf + 0, buf + 4, buf + 8, &dummy); 569130812Smarcel } 570130812Smarcel#endif 571130812Smarcel memset (buf, 0, MAX_REGISTER_SIZE); 572130812Smarcel} 573130812Smarcel 574130812Smarcel 575130812Smarcelstatic void 576130812Smarcelrdp_store_one_register (int mask, char *buf) 577130812Smarcel{ 578130812Smarcel int val = extract_unsigned_integer (buf, 4); 579130812Smarcel 580130812Smarcel send_rdp ("bbww-SZ", 581130812Smarcel RDP_CPU_WRITE, RDP_CPU_READWRITE_MODE_CURRENT, mask, val); 582130812Smarcel} 583130812Smarcel 584130812Smarcel 585130812Smarcelstatic void 586130812Smarcelrdp_store_one_fpu_register (int mask, char *buf) 587130812Smarcel{ 588130812Smarcel#if 0 589130812Smarcel /* See comment in fetch_one_fpu_register */ 590130812Smarcel if (mask == RDP_FPU_READWRITE_MASK_FPS) 591130812Smarcel { 592130812Smarcel int val = extract_unsigned_integer (buf, 4); 593130812Smarcel /* this guy is only a word */ 594130812Smarcel send_rdp ("bbww-SZ", RDP_COPRO_WRITE, 595130812Smarcel FPU_COPRO_NUMBER, 596130812Smarcel mask, val); 597130812Smarcel } 598130812Smarcel else 599130812Smarcel { 600130812Smarcel /* There are 12 bytes long 601130812Smarcel !! fixme about endianness 602130812Smarcel */ 603130812Smarcel int dummy = 0; 604130812Smarcel /* I've seen these come as four words, not the three advertized !! */ 605130812Smarcel printf ("Sending mask %x\n", mask); 606130812Smarcel send_rdp ("bbwwwww-SZ", 607130812Smarcel RDP_COPRO_WRITE, 608130812Smarcel FPU_COPRO_NUMBER, 609130812Smarcel mask, 610130812Smarcel *(int *) (buf + 0), 611130812Smarcel *(int *) (buf + 4), 612130812Smarcel *(int *) (buf + 8), 613130812Smarcel 0); 614130812Smarcel 615130812Smarcel printf ("done mask %x\n", mask); 616130812Smarcel } 617130812Smarcel#endif 618130812Smarcel} 619130812Smarcel 620130812Smarcel 621130812Smarcel/* Convert between GDB requests and the RDP layer. */ 622130812Smarcel 623130812Smarcelstatic void 624130812Smarcelremote_rdp_fetch_register (int regno) 625130812Smarcel{ 626130812Smarcel if (regno == -1) 627130812Smarcel { 628130812Smarcel for (regno = 0; regno < NUM_REGS; regno++) 629130812Smarcel remote_rdp_fetch_register (regno); 630130812Smarcel } 631130812Smarcel else 632130812Smarcel { 633130812Smarcel char buf[MAX_REGISTER_SIZE]; 634130812Smarcel if (regno < 15) 635130812Smarcel rdp_fetch_one_register (1 << regno, buf); 636130812Smarcel else if (regno == ARM_PC_REGNUM) 637130812Smarcel rdp_fetch_one_register (RDP_CPU_READWRITE_MASK_PC, buf); 638130812Smarcel else if (regno == ARM_PS_REGNUM) 639130812Smarcel rdp_fetch_one_register (RDP_CPU_READWRITE_MASK_CPSR, buf); 640130812Smarcel else if (regno == ARM_FPS_REGNUM) 641130812Smarcel rdp_fetch_one_fpu_register (RDP_FPU_READWRITE_MASK_FPS, buf); 642130812Smarcel else if (regno >= ARM_F0_REGNUM && regno <= ARM_F7_REGNUM) 643130812Smarcel rdp_fetch_one_fpu_register (1 << (regno - ARM_F0_REGNUM), buf); 644130812Smarcel else 645130812Smarcel { 646130812Smarcel printf ("Help me with fetch reg %d\n", regno); 647130812Smarcel } 648130812Smarcel supply_register (regno, buf); 649130812Smarcel } 650130812Smarcel} 651130812Smarcel 652130812Smarcel 653130812Smarcelstatic void 654130812Smarcelremote_rdp_store_register (int regno) 655130812Smarcel{ 656130812Smarcel if (regno == -1) 657130812Smarcel { 658130812Smarcel for (regno = 0; regno < NUM_REGS; regno++) 659130812Smarcel remote_rdp_store_register (regno); 660130812Smarcel } 661130812Smarcel else 662130812Smarcel { 663130812Smarcel char tmp[MAX_REGISTER_SIZE]; 664130812Smarcel deprecated_read_register_gen (regno, tmp); 665130812Smarcel if (regno < 15) 666130812Smarcel rdp_store_one_register (1 << regno, tmp); 667130812Smarcel else if (regno == ARM_PC_REGNUM) 668130812Smarcel rdp_store_one_register (RDP_CPU_READWRITE_MASK_PC, tmp); 669130812Smarcel else if (regno == ARM_PS_REGNUM) 670130812Smarcel rdp_store_one_register (RDP_CPU_READWRITE_MASK_CPSR, tmp); 671130812Smarcel else if (regno >= ARM_F0_REGNUM && regno <= ARM_F7_REGNUM) 672130812Smarcel rdp_store_one_fpu_register (1 << (regno - ARM_F0_REGNUM), tmp); 673130812Smarcel else 674130812Smarcel { 675130812Smarcel printf ("Help me with reg %d\n", regno); 676130812Smarcel } 677130812Smarcel } 678130812Smarcel} 679130812Smarcel 680130812Smarcelstatic void 681130812Smarcelremote_rdp_kill (void) 682130812Smarcel{ 683130812Smarcel callback->shutdown (callback); 684130812Smarcel} 685130812Smarcel 686130812Smarcel 687130812Smarcelstatic void 688130812Smarcelrdp_info (void) 689130812Smarcel{ 690130812Smarcel send_rdp ("bw-S-W-Z", RDP_INFO, RDP_INFO_ABOUT_STEP, 691130812Smarcel &ds.step_info); 692130812Smarcel send_rdp ("bw-S-W-Z", RDP_INFO, RDP_INFO_ABOUT_BREAK, 693130812Smarcel &ds.break_info); 694130812Smarcel send_rdp ("bw-S-WW-Z", RDP_INFO, RDP_INFO_ABOUT_TARGET, 695130812Smarcel &ds.target_info, 696130812Smarcel &ds.model_info); 697130812Smarcel 698130812Smarcel ds.can_step = ds.step_info & RDP_INFO_ABOUT_STEP_1; 699130812Smarcel 700130812Smarcel ds.rdi_level = (ds.target_info >> 5) & 3; 701130812Smarcel} 702130812Smarcel 703130812Smarcel 704130812Smarcelstatic void 705130812Smarcelrdp_execute_start (void) 706130812Smarcel{ 707130812Smarcel /* Start it off, but don't wait for it */ 708130812Smarcel send_rdp ("bb-", RDP_EXEC, RDP_EXEC_TYPE_SYNC); 709130812Smarcel} 710130812Smarcel 711130812Smarcel 712130812Smarcelstatic void 713130812Smarcelrdp_set_command_line (char *command, char *args) 714130812Smarcel{ 715130812Smarcel /* 716130812Smarcel ** We could use RDP_INFO_SET_CMDLINE to send this, but EmbeddedICE systems 717130812Smarcel ** don't implement that, and get all confused at the unexpected text. 718130812Smarcel ** Instead, just keep a copy, and send it when the target does a SWI_GetEnv 719130812Smarcel */ 720130812Smarcel 721130812Smarcel if (commandline != NULL) 722130812Smarcel xfree (commandline); 723130812Smarcel 724130812Smarcel xasprintf (&commandline, "%s %s", command, args); 725130812Smarcel} 726130812Smarcel 727130812Smarcelstatic void 728130812Smarcelrdp_catch_vectors (void) 729130812Smarcel{ 730130812Smarcel /* 731130812Smarcel ** We want the target monitor to intercept the abort vectors 732130812Smarcel ** i.e. stop the program if any of these are used. 733130812Smarcel */ 734130812Smarcel send_rdp ("bww-SZ", RDP_INFO, RDP_INFO_VECTOR_CATCH, 735130812Smarcel /* 736130812Smarcel ** Specify a bitmask including 737130812Smarcel ** the reset vector 738130812Smarcel ** the undefined instruction vector 739130812Smarcel ** the prefetch abort vector 740130812Smarcel ** the data abort vector 741130812Smarcel ** the address exception vector 742130812Smarcel */ 743130812Smarcel (1 << 0) | (1 << 1) | (1 << 3) | (1 << 4) | (1 << 5) 744130812Smarcel ); 745130812Smarcel} 746130812Smarcel 747130812Smarcel 748130812Smarcel 749130812Smarcel#define a_byte 1 750130812Smarcel#define a_word 2 751130812Smarcel#define a_string 3 752130812Smarcel 753130812Smarcel 754130812Smarceltypedef struct 755130812Smarcel{ 756130812Smarcel CORE_ADDR n; 757130812Smarcel const char *s; 758130812Smarcel} 759130812Smarcelargsin; 760130812Smarcel 761130812Smarcel#define ABYTE 1 762130812Smarcel#define AWORD 2 763130812Smarcel#define ASTRING 3 764130812Smarcel#define ADDRLEN 4 765130812Smarcel 766130812Smarcel#define SWI_WriteC 0x0 767130812Smarcel#define SWI_Write0 0x2 768130812Smarcel#define SWI_ReadC 0x4 769130812Smarcel#define SWI_CLI 0x5 770130812Smarcel#define SWI_GetEnv 0x10 771130812Smarcel#define SWI_Exit 0x11 772130812Smarcel#define SWI_EnterOS 0x16 773130812Smarcel 774130812Smarcel#define SWI_GetErrno 0x60 775130812Smarcel#define SWI_Clock 0x61 776130812Smarcel 777130812Smarcel#define SWI_Time 0x63 778130812Smarcel#define SWI_Remove 0x64 779130812Smarcel#define SWI_Rename 0x65 780130812Smarcel#define SWI_Open 0x66 781130812Smarcel 782130812Smarcel#define SWI_Close 0x68 783130812Smarcel#define SWI_Write 0x69 784130812Smarcel#define SWI_Read 0x6a 785130812Smarcel#define SWI_Seek 0x6b 786130812Smarcel#define SWI_Flen 0x6c 787130812Smarcel 788130812Smarcel#define SWI_IsTTY 0x6e 789130812Smarcel#define SWI_TmpNam 0x6f 790130812Smarcel#define SWI_InstallHandler 0x70 791130812Smarcel#define SWI_GenerateError 0x71 792130812Smarcel 793130812Smarcel 794130812Smarcel#ifndef O_BINARY 795130812Smarcel#define O_BINARY 0 796130812Smarcel#endif 797130812Smarcel 798130812Smarcelstatic int translate_open_mode[] = 799130812Smarcel{ 800130812Smarcel O_RDONLY, /* "r" */ 801130812Smarcel O_RDONLY + O_BINARY, /* "rb" */ 802130812Smarcel O_RDWR, /* "r+" */ 803130812Smarcel O_RDWR + O_BINARY, /* "r+b" */ 804130812Smarcel O_WRONLY + O_CREAT + O_TRUNC, /* "w" */ 805130812Smarcel O_WRONLY + O_BINARY + O_CREAT + O_TRUNC, /* "wb" */ 806130812Smarcel O_RDWR + O_CREAT + O_TRUNC, /* "w+" */ 807130812Smarcel O_RDWR + O_BINARY + O_CREAT + O_TRUNC, /* "w+b" */ 808130812Smarcel O_WRONLY + O_APPEND + O_CREAT, /* "a" */ 809130812Smarcel O_WRONLY + O_BINARY + O_APPEND + O_CREAT, /* "ab" */ 810130812Smarcel O_RDWR + O_APPEND + O_CREAT, /* "a+" */ 811130812Smarcel O_RDWR + O_BINARY + O_APPEND + O_CREAT /* "a+b" */ 812130812Smarcel}; 813130812Smarcel 814130812Smarcelstatic int 815130812Smarcelexec_swi (int swi, argsin *args) 816130812Smarcel{ 817130812Smarcel int i; 818130812Smarcel char c; 819130812Smarcel switch (swi) 820130812Smarcel { 821130812Smarcel case SWI_WriteC: 822130812Smarcel callback->write_stdout (callback, &c, 1); 823130812Smarcel return 0; 824130812Smarcel case SWI_Write0: 825130812Smarcel for (i = 0; i < args->n; i++) 826130812Smarcel callback->write_stdout (callback, args->s, strlen (args->s)); 827130812Smarcel return 0; 828130812Smarcel case SWI_ReadC: 829130812Smarcel callback->read_stdin (callback, &c, 1); 830130812Smarcel args->n = c; 831130812Smarcel return 1; 832130812Smarcel case SWI_CLI: 833130812Smarcel args->n = callback->system (callback, args->s); 834130812Smarcel return 1; 835130812Smarcel case SWI_GetErrno: 836130812Smarcel args->n = callback->get_errno (callback); 837130812Smarcel return 1; 838130812Smarcel case SWI_Time: 839130812Smarcel args->n = callback->time (callback, NULL); 840130812Smarcel return 1; 841130812Smarcel 842130812Smarcel case SWI_Clock: 843130812Smarcel /* return number of centi-seconds... */ 844130812Smarcel args->n = 845130812Smarcel#ifdef CLOCKS_PER_SEC 846130812Smarcel (CLOCKS_PER_SEC >= 100) 847130812Smarcel ? (clock () / (CLOCKS_PER_SEC / 100)) 848130812Smarcel : ((clock () * 100) / CLOCKS_PER_SEC); 849130812Smarcel#else 850130812Smarcel /* presume unix... clock() returns microseconds */ 851130812Smarcel clock () / 10000; 852130812Smarcel#endif 853130812Smarcel return 1; 854130812Smarcel 855130812Smarcel case SWI_Remove: 856130812Smarcel args->n = callback->unlink (callback, args->s); 857130812Smarcel return 1; 858130812Smarcel case SWI_Rename: 859130812Smarcel args->n = callback->rename (callback, args[0].s, args[1].s); 860130812Smarcel return 1; 861130812Smarcel 862130812Smarcel case SWI_Open: 863130812Smarcel /* Now we need to decode the Demon open mode */ 864130812Smarcel i = translate_open_mode[args[1].n]; 865130812Smarcel 866130812Smarcel /* Filename ":tt" is special: it denotes stdin/out */ 867130812Smarcel if (strcmp (args->s, ":tt") == 0) 868130812Smarcel { 869130812Smarcel if (i == O_RDONLY) /* opening tty "r" */ 870130812Smarcel args->n = 0 /* stdin */ ; 871130812Smarcel else 872130812Smarcel args->n = 1 /* stdout */ ; 873130812Smarcel } 874130812Smarcel else 875130812Smarcel args->n = callback->open (callback, args->s, i); 876130812Smarcel return 1; 877130812Smarcel 878130812Smarcel case SWI_Close: 879130812Smarcel args->n = callback->close (callback, args->n); 880130812Smarcel return 1; 881130812Smarcel 882130812Smarcel case SWI_Write: 883130812Smarcel /* Return the number of bytes *not* written */ 884130812Smarcel args->n = args[1].n - 885130812Smarcel callback->write (callback, args[0].n, args[1].s, args[1].n); 886130812Smarcel return 1; 887130812Smarcel 888130812Smarcel case SWI_Read: 889130812Smarcel { 890130812Smarcel char *copy = alloca (args[2].n); 891130812Smarcel int done = callback->read (callback, args[0].n, copy, args[2].n); 892130812Smarcel if (done > 0) 893130812Smarcel remote_rdp_xfer_inferior_memory (args[1].n, copy, done, 1, 0, 0); 894130812Smarcel args->n = args[2].n - done; 895130812Smarcel return 1; 896130812Smarcel } 897130812Smarcel 898130812Smarcel case SWI_Seek: 899130812Smarcel /* Return non-zero on failure */ 900130812Smarcel args->n = callback->lseek (callback, args[0].n, args[1].n, 0) < 0; 901130812Smarcel return 1; 902130812Smarcel 903130812Smarcel case SWI_Flen: 904130812Smarcel { 905130812Smarcel long old = callback->lseek (callback, args->n, 0, SEEK_CUR); 906130812Smarcel args->n = callback->lseek (callback, args->n, 0, SEEK_END); 907130812Smarcel callback->lseek (callback, args->n, old, 0); 908130812Smarcel return 1; 909130812Smarcel } 910130812Smarcel 911130812Smarcel case SWI_IsTTY: 912130812Smarcel args->n = callback->isatty (callback, args->n); 913130812Smarcel return 1; 914130812Smarcel 915130812Smarcel case SWI_GetEnv: 916130812Smarcel if (commandline != NULL) 917130812Smarcel { 918130812Smarcel int len = strlen (commandline); 919130812Smarcel if (len > 255) 920130812Smarcel { 921130812Smarcel len = 255; 922130812Smarcel commandline[255] = '\0'; 923130812Smarcel } 924130812Smarcel remote_rdp_xfer_inferior_memory (args[0].n, 925130812Smarcel commandline, len + 1, 1, 0, 0); 926130812Smarcel } 927130812Smarcel else 928130812Smarcel remote_rdp_xfer_inferior_memory (args[0].n, "", 1, 1, 0, 0); 929130812Smarcel return 1; 930130812Smarcel 931130812Smarcel default: 932130812Smarcel return 0; 933130812Smarcel } 934130812Smarcel} 935130812Smarcel 936130812Smarcel 937130812Smarcelstatic void 938130812Smarcelhandle_swi (void) 939130812Smarcel{ 940130812Smarcel argsin args[3]; 941130812Smarcel char *buf; 942130812Smarcel int len; 943130812Smarcel int count = 0; 944130812Smarcel 945130812Smarcel int swino = get_word (); 946130812Smarcel int type = get_byte (); 947130812Smarcel while (type != 0) 948130812Smarcel { 949130812Smarcel switch (type & 0x3) 950130812Smarcel { 951130812Smarcel case ABYTE: 952130812Smarcel args[count].n = get_byte (); 953130812Smarcel break; 954130812Smarcel 955130812Smarcel case AWORD: 956130812Smarcel args[count].n = get_word (); 957130812Smarcel break; 958130812Smarcel 959130812Smarcel case ASTRING: 960130812Smarcel /* If the word is under 32 bytes it will be sent otherwise 961130812Smarcel an address to it is passed. Also: Special case of 255 */ 962130812Smarcel 963130812Smarcel len = get_byte (); 964130812Smarcel if (len > 32) 965130812Smarcel { 966130812Smarcel if (len == 255) 967130812Smarcel { 968130812Smarcel len = get_word (); 969130812Smarcel } 970130812Smarcel buf = alloca (len); 971130812Smarcel remote_rdp_xfer_inferior_memory (get_word (), 972130812Smarcel buf, 973130812Smarcel len, 974130812Smarcel 0, 975130812Smarcel 0, 976130812Smarcel 0); 977130812Smarcel } 978130812Smarcel else 979130812Smarcel { 980130812Smarcel int i; 981130812Smarcel buf = alloca (len + 1); 982130812Smarcel for (i = 0; i < len; i++) 983130812Smarcel buf[i] = get_byte (); 984130812Smarcel buf[i] = 0; 985130812Smarcel } 986130812Smarcel args[count].n = len; 987130812Smarcel args[count].s = buf; 988130812Smarcel break; 989130812Smarcel 990130812Smarcel default: 991130812Smarcel error ("Unimplemented SWI argument"); 992130812Smarcel } 993130812Smarcel 994130812Smarcel type = type >> 2; 995130812Smarcel count++; 996130812Smarcel } 997130812Smarcel 998130812Smarcel if (exec_swi (swino, args)) 999130812Smarcel { 1000130812Smarcel /* We have two options here reply with either a byte or a word 1001130812Smarcel which is stored in args[0].n. There is no harm in replying with 1002130812Smarcel a word all the time, so thats what I do! */ 1003130812Smarcel send_rdp ("bbw-", RDP_OSOpReply, RDP_OSOpWord, args[0].n); 1004130812Smarcel } 1005130812Smarcel else 1006130812Smarcel { 1007130812Smarcel send_rdp ("bb-", RDP_OSOpReply, RDP_OSOpNothing); 1008130812Smarcel } 1009130812Smarcel} 1010130812Smarcel 1011130812Smarcelstatic void 1012130812Smarcelrdp_execute_finish (void) 1013130812Smarcel{ 1014130812Smarcel int running = 1; 1015130812Smarcel 1016130812Smarcel while (running) 1017130812Smarcel { 1018130812Smarcel int res; 1019130812Smarcel res = serial_readchar (io, 1); 1020130812Smarcel while (res == SERIAL_TIMEOUT) 1021130812Smarcel { 1022130812Smarcel QUIT; 1023130812Smarcel printf_filtered ("Waiting for target..\n"); 1024130812Smarcel res = serial_readchar (io, 1); 1025130812Smarcel } 1026130812Smarcel 1027130812Smarcel switch (res) 1028130812Smarcel { 1029130812Smarcel case RDP_RES_SWI: 1030130812Smarcel handle_swi (); 1031130812Smarcel break; 1032130812Smarcel case RDP_RES_VALUE: 1033130812Smarcel send_rdp ("B", &ds.rdi_stopped_status); 1034130812Smarcel running = 0; 1035130812Smarcel break; 1036130812Smarcel case RDP_RESET: 1037130812Smarcel printf_filtered ("Target reset\n"); 1038130812Smarcel running = 0; 1039130812Smarcel break; 1040130812Smarcel default: 1041130812Smarcel printf_filtered ("Ignoring %x\n", res); 1042130812Smarcel break; 1043130812Smarcel } 1044130812Smarcel } 1045130812Smarcel} 1046130812Smarcel 1047130812Smarcel 1048130812Smarcelstatic void 1049130812Smarcelrdp_execute (void) 1050130812Smarcel{ 1051130812Smarcel rdp_execute_start (); 1052130812Smarcel rdp_execute_finish (); 1053130812Smarcel} 1054130812Smarcel 1055130812Smarcelstatic int 1056130812Smarcelremote_rdp_insert_breakpoint (CORE_ADDR addr, char *save) 1057130812Smarcel{ 1058130812Smarcel int res; 1059130812Smarcel if (ds.rdi_level > 0) 1060130812Smarcel { 1061130812Smarcel send_rdp ("bwb-SWB", 1062130812Smarcel RDP_SET_BREAK, 1063130812Smarcel addr, 1064130812Smarcel RDP_SET_BREAK_TYPE_PC_EQUAL | RDP_SET_BREAK_TYPE_GET_HANDLE, 1065130812Smarcel save, 1066130812Smarcel &res); 1067130812Smarcel } 1068130812Smarcel else 1069130812Smarcel { 1070130812Smarcel send_rdp ("bwb-SB", 1071130812Smarcel RDP_SET_BREAK, 1072130812Smarcel addr, 1073130812Smarcel RDP_SET_BREAK_TYPE_PC_EQUAL, 1074130812Smarcel &res); 1075130812Smarcel } 1076130812Smarcel return res; 1077130812Smarcel} 1078130812Smarcel 1079130812Smarcelstatic int 1080130812Smarcelremote_rdp_remove_breakpoint (CORE_ADDR addr, char *save) 1081130812Smarcel{ 1082130812Smarcel int res; 1083130812Smarcel if (ds.rdi_level > 0) 1084130812Smarcel { 1085130812Smarcel send_rdp ("b-p-S-B", 1086130812Smarcel RDP_CLEAR_BREAK, 1087130812Smarcel save, 4, 1088130812Smarcel &res); 1089130812Smarcel } 1090130812Smarcel else 1091130812Smarcel { 1092130812Smarcel send_rdp ("bw-S-B", 1093130812Smarcel RDP_CLEAR_BREAK, 1094130812Smarcel addr, 1095130812Smarcel &res); 1096130812Smarcel } 1097130812Smarcel return res; 1098130812Smarcel} 1099130812Smarcel 1100130812Smarcelstatic void 1101130812Smarcelrdp_step (void) 1102130812Smarcel{ 1103130812Smarcel if (ds.can_step && 0) 1104130812Smarcel { 1105130812Smarcel /* The pie board can't do steps so I can't test this, and 1106130812Smarcel the other code will always work. */ 1107130812Smarcel int status; 1108130812Smarcel send_rdp ("bbw-S-B", 1109130812Smarcel RDP_STEP, 0, 1, 1110130812Smarcel &status); 1111130812Smarcel } 1112130812Smarcel else 1113130812Smarcel { 1114130812Smarcel char handle[4]; 1115130812Smarcel CORE_ADDR pc = read_register (ARM_PC_REGNUM); 1116130812Smarcel pc = arm_get_next_pc (pc); 1117130812Smarcel remote_rdp_insert_breakpoint (pc, handle); 1118130812Smarcel rdp_execute (); 1119130812Smarcel remote_rdp_remove_breakpoint (pc, handle); 1120130812Smarcel } 1121130812Smarcel} 1122130812Smarcel 1123130812Smarcelstatic void 1124130812Smarcelremote_rdp_open (char *args, int from_tty) 1125130812Smarcel{ 1126130812Smarcel int not_icebreaker; 1127130812Smarcel 1128130812Smarcel if (!args) 1129130812Smarcel error_no_arg ("serial port device name"); 1130130812Smarcel 1131130812Smarcel baud_rate = 9600; 1132130812Smarcel 1133130812Smarcel target_preopen (from_tty); 1134130812Smarcel 1135130812Smarcel io = serial_open (args); 1136130812Smarcel 1137130812Smarcel if (!io) 1138130812Smarcel perror_with_name (args); 1139130812Smarcel 1140130812Smarcel serial_raw (io); 1141130812Smarcel 1142130812Smarcel rdp_init (1, from_tty); 1143130812Smarcel 1144130812Smarcel 1145130812Smarcel if (from_tty) 1146130812Smarcel { 1147130812Smarcel printf_unfiltered ("Remote RDP debugging using %s at %d baud\n", args, baud_rate); 1148130812Smarcel } 1149130812Smarcel 1150130812Smarcel rdp_info (); 1151130812Smarcel 1152130812Smarcel /* Need to set up the vector interception state */ 1153130812Smarcel rdp_catch_vectors (); 1154130812Smarcel 1155130812Smarcel /* 1156130812Smarcel ** If it's an EmbeddedICE, we need to set the processor config. 1157130812Smarcel ** Assume we can always have ARM7TDI... 1158130812Smarcel */ 1159130812Smarcel send_rdp ("bw-SB", RDP_INFO, RDP_INFO_ICEBREAKER, ¬_icebreaker); 1160130812Smarcel if (!not_icebreaker) 1161130812Smarcel { 1162130812Smarcel const char *CPU = "ARM7TDI"; 1163130812Smarcel int ICEversion; 1164130812Smarcel int len = strlen (CPU); 1165130812Smarcel 1166130812Smarcel send_rdp ("bbbbw-p-SWZ", 1167130812Smarcel RDP_SELECT_CONFIG, 1168130812Smarcel RDI_ConfigCPU, /* Aspect: set the CPU */ 1169130812Smarcel len, /* The number of bytes in the name */ 1170130812Smarcel RDI_MatchAny, /* We'll take whatever we get */ 1171130812Smarcel 0, /* We'll take whatever version's there */ 1172130812Smarcel CPU, len, 1173130812Smarcel &ICEversion); 1174130812Smarcel } 1175130812Smarcel 1176130812Smarcel /* command line initialised on 'run' */ 1177130812Smarcel 1178130812Smarcel push_target (&remote_rdp_ops); 1179130812Smarcel 1180130812Smarcel callback->init (callback); 1181130812Smarcel flush_cached_frames (); 1182130812Smarcel registers_changed (); 1183130812Smarcel stop_pc = read_pc (); 1184130812Smarcel print_stack_frame (get_selected_frame (), -1, 1); 1185130812Smarcel} 1186130812Smarcel 1187130812Smarcel 1188130812Smarcel 1189130812Smarcel/* Close out all files and local state before this target loses control. */ 1190130812Smarcel 1191130812Smarcelstatic void 1192130812Smarcelremote_rdp_close (int quitting) 1193130812Smarcel{ 1194130812Smarcel callback->shutdown (callback); 1195130812Smarcel if (io) 1196130812Smarcel serial_close (io); 1197130812Smarcel io = 0; 1198130812Smarcel} 1199130812Smarcel 1200130812Smarcel 1201130812Smarcel/* Resume execution of the target process. STEP says whether to single-step 1202130812Smarcel or to run free; SIGGNAL is the signal value (e.g. SIGINT) to be given 1203130812Smarcel to the target, or zero for no signal. */ 1204130812Smarcel 1205130812Smarcelstatic void 1206130812Smarcelremote_rdp_resume (ptid_t ptid, int step, enum target_signal siggnal) 1207130812Smarcel{ 1208130812Smarcel if (step) 1209130812Smarcel rdp_step (); 1210130812Smarcel else 1211130812Smarcel rdp_execute (); 1212130812Smarcel} 1213130812Smarcel 1214130812Smarcel/* Wait for inferior process to do something. Return pid of child, 1215130812Smarcel or -1 in case of error; store status through argument pointer STATUS, 1216130812Smarcel just as `wait' would. */ 1217130812Smarcel 1218130812Smarcelstatic ptid_t 1219130812Smarcelremote_rdp_wait (ptid_t ptid, struct target_waitstatus *status) 1220130812Smarcel{ 1221130812Smarcel switch (ds.rdi_stopped_status) 1222130812Smarcel { 1223130812Smarcel default: 1224130812Smarcel case RDP_RES_RESET: 1225130812Smarcel case RDP_RES_SWI: 1226130812Smarcel status->kind = TARGET_WAITKIND_EXITED; 1227130812Smarcel status->value.integer = read_register (0); 1228130812Smarcel break; 1229130812Smarcel case RDP_RES_AT_BREAKPOINT: 1230130812Smarcel status->kind = TARGET_WAITKIND_STOPPED; 1231130812Smarcel /* The signal in sigrc is a host signal. That probably 1232130812Smarcel should be fixed. */ 1233130812Smarcel status->value.sig = TARGET_SIGNAL_TRAP; 1234130812Smarcel break; 1235130812Smarcel#if 0 1236130812Smarcel case rdp_signalled: 1237130812Smarcel status->kind = TARGET_WAITKIND_SIGNALLED; 1238130812Smarcel /* The signal in sigrc is a host signal. That probably 1239130812Smarcel should be fixed. */ 1240130812Smarcel status->value.sig = target_signal_from_host (sigrc); 1241130812Smarcel break; 1242130812Smarcel#endif 1243130812Smarcel } 1244130812Smarcel 1245130812Smarcel return inferior_ptid; 1246130812Smarcel} 1247130812Smarcel 1248130812Smarcel/* Get ready to modify the registers array. On machines which store 1249130812Smarcel individual registers, this doesn't need to do anything. On machines 1250130812Smarcel which store all the registers in one fell swoop, this makes sure 1251130812Smarcel that registers contains all the registers from the program being 1252130812Smarcel debugged. */ 1253130812Smarcel 1254130812Smarcelstatic void 1255130812Smarcelremote_rdp_prepare_to_store (void) 1256130812Smarcel{ 1257130812Smarcel /* Do nothing, since we can store individual regs */ 1258130812Smarcel} 1259130812Smarcel 1260130812Smarcel/* Transfer LEN bytes between GDB address MYADDR and target address 1261130812Smarcel MEMADDR. If WRITE is non-zero, transfer them to the target, 1262130812Smarcel otherwise transfer them from the target. TARGET is unused. 1263130812Smarcel 1264130812Smarcel Returns the number of bytes transferred. */ 1265130812Smarcel 1266130812Smarcelstatic int 1267130812Smarcelremote_rdp_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, 1268130812Smarcel int write, struct mem_attrib *attrib, 1269130812Smarcel struct target_ops *target) 1270130812Smarcel{ 1271130812Smarcel /* I infer from D Taylor's code that there's a limit on the amount 1272130812Smarcel we can transfer in one chunk.. */ 1273130812Smarcel int done = 0; 1274130812Smarcel while (done < len) 1275130812Smarcel { 1276130812Smarcel int justdone; 1277130812Smarcel int thisbite = len - done; 1278130812Smarcel if (thisbite > RDP_MOUTHFULL) 1279130812Smarcel thisbite = RDP_MOUTHFULL; 1280130812Smarcel 1281130812Smarcel QUIT; 1282130812Smarcel 1283130812Smarcel if (write) 1284130812Smarcel { 1285130812Smarcel justdone = rdp_write (memaddr + done, myaddr + done, thisbite); 1286130812Smarcel } 1287130812Smarcel else 1288130812Smarcel { 1289130812Smarcel justdone = rdp_read (memaddr + done, myaddr + done, thisbite); 1290130812Smarcel } 1291130812Smarcel 1292130812Smarcel done += justdone; 1293130812Smarcel 1294130812Smarcel if (justdone != thisbite) 1295130812Smarcel break; 1296130812Smarcel } 1297130812Smarcel return done; 1298130812Smarcel} 1299130812Smarcel 1300130812Smarcel 1301130812Smarcel 1302130812Smarcelstruct yn 1303130812Smarcel{ 1304130812Smarcel const char *name; 1305130812Smarcel int bit; 1306130812Smarcel}; 1307130812Smarcelstatic struct yn stepinfo[] = 1308130812Smarcel{ 1309130812Smarcel {"Step more than one instruction", RDP_INFO_ABOUT_STEP_GT_1}, 1310130812Smarcel {"Step to jump", RDP_INFO_ABOUT_STEP_TO_JMP}, 1311130812Smarcel {"Step one instruction", RDP_INFO_ABOUT_STEP_1}, 1312130812Smarcel {0} 1313130812Smarcel}; 1314130812Smarcel 1315130812Smarcelstatic struct yn breakinfo[] = 1316130812Smarcel{ 1317130812Smarcel {"comparison breakpoints supported", RDP_INFO_ABOUT_BREAK_COMP}, 1318130812Smarcel {"range breakpoints supported", RDP_INFO_ABOUT_BREAK_RANGE}, 1319130812Smarcel {"watchpoints for byte reads supported", RDP_INFO_ABOUT_BREAK_BYTE_READ}, 1320130812Smarcel {"watchpoints for half-word reads supported", RDP_INFO_ABOUT_BREAK_HALFWORD_READ}, 1321130812Smarcel {"watchpoints for word reads supported", RDP_INFO_ABOUT_BREAK_WORD_READ}, 1322130812Smarcel {"watchpoints for byte writes supported", RDP_INFO_ABOUT_BREAK_BYTE_WRITE}, 1323130812Smarcel {"watchpoints for half-word writes supported", RDP_INFO_ABOUT_BREAK_HALFWORD_WRITE}, 1324130812Smarcel {"watchpoints for word writes supported", RDP_INFO_ABOUT_BREAK_WORD_WRITE}, 1325130812Smarcel {"mask break/watch-points supported", RDP_INFO_ABOUT_BREAK_MASK}, 1326130812Smarcel{"thread-specific breakpoints supported", RDP_INFO_ABOUT_BREAK_THREAD_BREAK}, 1327130812Smarcel{"thread-specific watchpoints supported", RDP_INFO_ABOUT_BREAK_THREAD_WATCH}, 1328130812Smarcel {"conditional breakpoints supported", RDP_INFO_ABOUT_BREAK_COND}, 1329130812Smarcel {0} 1330130812Smarcel}; 1331130812Smarcel 1332130812Smarcel 1333130812Smarcelstatic void 1334130812Smarceldump_bits (struct yn *t, int info) 1335130812Smarcel{ 1336130812Smarcel while (t->name) 1337130812Smarcel { 1338130812Smarcel printf_unfiltered (" %-45s : %s\n", t->name, (info & t->bit) ? "Yes" : "No"); 1339130812Smarcel t++; 1340130812Smarcel } 1341130812Smarcel} 1342130812Smarcel 1343130812Smarcelstatic void 1344130812Smarcelremote_rdp_files_info (struct target_ops *target) 1345130812Smarcel{ 1346130812Smarcel printf_filtered ("Target capabilities:\n"); 1347130812Smarcel dump_bits (stepinfo, ds.step_info); 1348130812Smarcel dump_bits (breakinfo, ds.break_info); 1349130812Smarcel printf_unfiltered ("target level RDI %x\n", (ds.target_info >> 5) & 3); 1350130812Smarcel} 1351130812Smarcel 1352130812Smarcel 1353130812Smarcelstatic void 1354130812Smarcelremote_rdp_create_inferior (char *exec_file, char *allargs, char **env) 1355130812Smarcel{ 1356130812Smarcel CORE_ADDR entry_point; 1357130812Smarcel 1358130812Smarcel if (exec_file == 0 || exec_bfd == 0) 1359130812Smarcel error ("No executable file specified."); 1360130812Smarcel 1361130812Smarcel entry_point = (CORE_ADDR) bfd_get_start_address (exec_bfd); 1362130812Smarcel 1363130812Smarcel remote_rdp_kill (); 1364130812Smarcel remove_breakpoints (); 1365130812Smarcel init_wait_for_inferior (); 1366130812Smarcel 1367130812Smarcel /* This gives us a chance to set up the command line */ 1368130812Smarcel rdp_set_command_line (exec_file, allargs); 1369130812Smarcel 1370130812Smarcel inferior_ptid = pid_to_ptid (42); 1371130812Smarcel insert_breakpoints (); /* Needed to get correct instruction in cache */ 1372130812Smarcel 1373130812Smarcel /* 1374130812Smarcel ** RDP targets don't provide any facility to set the top of memory, 1375130812Smarcel ** so we don't bother to look for MEMSIZE in the environment. 1376130812Smarcel */ 1377130812Smarcel 1378130812Smarcel /* Let's go! */ 1379130812Smarcel proceed (entry_point, TARGET_SIGNAL_DEFAULT, 0); 1380130812Smarcel} 1381130812Smarcel 1382130812Smarcel/* Attach doesn't need to do anything */ 1383130812Smarcelstatic void 1384130812Smarcelremote_rdp_attach (char *args, int from_tty) 1385130812Smarcel{ 1386130812Smarcel return; 1387130812Smarcel} 1388130812Smarcel 1389130812Smarcel/* Define the target subroutine names */ 1390130812Smarcel 1391130812Smarcelstruct target_ops remote_rdp_ops; 1392130812Smarcel 1393130812Smarcelstatic void 1394130812Smarcelinit_remote_rdp_ops (void) 1395130812Smarcel{ 1396130812Smarcel remote_rdp_ops.to_shortname = "rdp"; 1397130812Smarcel remote_rdp_ops.to_longname = "Remote Target using the RDProtocol"; 1398130812Smarcel remote_rdp_ops.to_doc = "Use a remote ARM system which uses the ARM Remote Debugging Protocol"; 1399130812Smarcel remote_rdp_ops.to_open = remote_rdp_open; 1400130812Smarcel remote_rdp_ops.to_close = remote_rdp_close; 1401130812Smarcel remote_rdp_ops.to_attach = remote_rdp_attach; 1402130812Smarcel remote_rdp_ops.to_resume = remote_rdp_resume; 1403130812Smarcel remote_rdp_ops.to_wait = remote_rdp_wait; 1404130812Smarcel remote_rdp_ops.to_fetch_registers = remote_rdp_fetch_register; 1405130812Smarcel remote_rdp_ops.to_store_registers = remote_rdp_store_register; 1406130812Smarcel remote_rdp_ops.to_prepare_to_store = remote_rdp_prepare_to_store; 1407130812Smarcel remote_rdp_ops.to_xfer_memory = remote_rdp_xfer_inferior_memory; 1408130812Smarcel remote_rdp_ops.to_files_info = remote_rdp_files_info; 1409130812Smarcel remote_rdp_ops.to_insert_breakpoint = remote_rdp_insert_breakpoint; 1410130812Smarcel remote_rdp_ops.to_remove_breakpoint = remote_rdp_remove_breakpoint; 1411130812Smarcel remote_rdp_ops.to_kill = remote_rdp_kill; 1412130812Smarcel remote_rdp_ops.to_load = generic_load; 1413130812Smarcel remote_rdp_ops.to_create_inferior = remote_rdp_create_inferior; 1414130812Smarcel remote_rdp_ops.to_mourn_inferior = generic_mourn_inferior; 1415130812Smarcel remote_rdp_ops.to_stratum = process_stratum; 1416130812Smarcel remote_rdp_ops.to_has_all_memory = 1; 1417130812Smarcel remote_rdp_ops.to_has_memory = 1; 1418130812Smarcel remote_rdp_ops.to_has_stack = 1; 1419130812Smarcel remote_rdp_ops.to_has_registers = 1; 1420130812Smarcel remote_rdp_ops.to_has_execution = 1; 1421130812Smarcel remote_rdp_ops.to_magic = OPS_MAGIC; 1422130812Smarcel} 1423130812Smarcel 1424130812Smarcelextern initialize_file_ftype _initialize_remote_rdp; /* -Wmissing-prototypes */ 1425130812Smarcel 1426130812Smarcelvoid 1427130812Smarcel_initialize_remote_rdp (void) 1428130812Smarcel{ 1429130812Smarcel init_remote_rdp_ops (); 1430130812Smarcel add_target (&remote_rdp_ops); 1431130812Smarcel} 1432