X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Focd.c;h=826677540e307a5fdc6ba5111f9c1ec531ead0ba;hb=feb129926a8d12656f1ca4b7a8bb10268d3af4fb;hp=fdcd6476ca092ad0b7512861312d499e9d3e82d3;hpb=9cf7f520c671cdb644fb987facea36ff5e597605;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/ocd.c b/gdb/ocd.c index fdcd6476ca..826677540e 100644 --- a/gdb/ocd.c +++ b/gdb/ocd.c @@ -1,21 +1,22 @@ -/* Remote target communications for the Macraigor Systems BDM Wiggler +/* Target communications support for Macraigor Systems' On-Chip Debugging Copyright 1996, 1997 Free Software Foundation, Inc. -This file is part of GDB. + This file is part of GDB. -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the 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 of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ #include "defs.h" #include "gdbcore.h" @@ -38,13 +39,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Prototypes for local functions */ -static int ocd_write_bytes PARAMS ((CORE_ADDR memaddr, - char *myaddr, int len)); - static int ocd_read_bytes PARAMS ((CORE_ADDR memaddr, - char *myaddr, int len)); + char *myaddr, int len)); -static int ocd_start_remote PARAMS ((char *dummy)); +static int ocd_start_remote PARAMS ((PTR dummy)); static int readchar PARAMS ((int timeout)); @@ -62,11 +60,11 @@ static void ocd_interrupt_twice PARAMS ((int signo)); static void interrupt_query PARAMS ((void)); -static unsigned char * ocd_do_command PARAMS ((int cmd, int *statusp, int *lenp)); +static unsigned char *ocd_do_command PARAMS ((int cmd, int *statusp, int *lenp)); static void ocd_put_packet PARAMS ((unsigned char *packet, int pktlen)); -static unsigned char * ocd_get_packet PARAMS ((int cmd, int *pktlen, int timeout)); +static unsigned char *ocd_get_packet PARAMS ((int cmd, int *pktlen, int timeout)); static struct target_ops *current_ops = NULL; @@ -77,9 +75,11 @@ static int last_run_status; other form of hairy serial connection, I would think 2 seconds would be plenty. */ -/* Changed to allow option to set timeout value. - was static int remote_timeout = 2; */ -extern int remote_timeout; +#if 0 +/* FIXME: Change to allow option to set timeout value on a per target + basis. */ +static int remote_timeout = 2; +#endif /* Descriptor for I/O to remote machine. Initialize it to NULL so that ocd_open knows that we don't have a file open when the program @@ -98,20 +98,51 @@ ocd_error (s, error_code) switch (error_code) { - case 0x1: s = "Unknown fault"; break; - case 0x2: s = "Power failed"; break; - case 0x3: s = "Cable disconnected"; break; - case 0x4: s = "Couldn't enter BDM"; break; - case 0x5: s = "Target stuck in reset"; break; - case 0x6: s = "Port not configured"; break; - case 0x7: s = "Write verify failed"; break; - case 0x11: s = "Bus error"; break; - case 0x12: s = "Checksum error"; break; - case 0x13: s = "Illegal command"; break; - case 0x14: s = "Parameter error"; break; - case 0x15: s = "Internal error"; break; - case 0x16: s = "Register buffer error"; break; - case 0x80: s = "Flash erase error"; break; + case 0x1: + s = "Unknown fault"; + break; + case 0x2: + s = "Power failed"; + break; + case 0x3: + s = "Cable disconnected"; + break; + case 0x4: + s = "Couldn't enter OCD mode"; + break; + case 0x5: + s = "Target stuck in reset"; + break; + case 0x6: + s = "OCD hasn't been initialized"; + break; + case 0x7: + s = "Write verify failed"; + break; + case 0x8: + s = "Reg buff error (during MPC5xx fp reg read/write)"; + break; + case 0x9: + s = "Invalid CPU register access attempt failed"; + break; + case 0x11: + s = "Bus error"; + break; + case 0x12: + s = "Checksum error"; + break; + case 0x13: + s = "Illegal command"; + break; + case 0x14: + s = "Parameter error"; + break; + case 0x15: + s = "Internal error"; + break; + case 0x80: + s = "Flash erase error"; + break; default: sprintf (buf, "Unknown error code %d", error_code); s = buf; @@ -145,7 +176,7 @@ ocd_close (quitting) static int ocd_start_remote (dummy) - char *dummy; + PTR dummy; { unsigned char buf[10], *p; int pktlen; @@ -154,21 +185,13 @@ ocd_start_remote (dummy) int speed; enum ocd_target_type target_type; - target_type = (enum ocd_target_type)dummy; + target_type = *(enum ocd_target_type *) dummy; immediate_quit = 1; /* Allow user to interrupt it */ - SERIAL_SEND_BREAK (ocd_desc); /* Wake up the wiggler */ - - ocd_do_command (OCD_AYT, &status, &pktlen); - - p = ocd_do_command (OCD_GET_VERSION, &status, &pktlen); - - printf_unfiltered ("[Wiggler version %x.%x, capability 0x%x]\n", - p[0], p[1], (p[2] << 16) | p[3]); + SERIAL_SEND_BREAK (ocd_desc); /* Wake up the wiggler */ -#if 1 - speed = 0; /* 80; /* Divide clock by 4000 */ + speed = 80; /* Divide clock by 4000 */ buf[0] = OCD_INIT; buf[1] = speed >> 8; @@ -185,13 +208,19 @@ ocd_start_remote (dummy) if (error_code != 0) ocd_error ("OCD_INIT:", error_code); -#endif + + ocd_do_command (OCD_AYT, &status, &pktlen); + + p = ocd_do_command (OCD_GET_VERSION, &status, &pktlen); + + printf_unfiltered ("[Wiggler version %x.%x, capability 0x%x]\n", + p[0], p[1], (p[2] << 16) | p[3]); #if 0 /* Reset the target */ ocd_do_command (OCD_RESET_RUN, &status, &pktlen); -/* ocd_do_command (OCD_RESET, &status, &pktlen);*/ +/* ocd_do_command (OCD_RESET, &status, &pktlen); */ #endif /* If processor is still running, stop it. */ @@ -200,9 +229,12 @@ ocd_start_remote (dummy) ocd_stop (); #if 1 + /* When using a target box, we want to asynchronously return status when + target stops. The OCD_SET_CTL_FLAGS command is ignored by Wigglers.dll + when using a parallel Wiggler */ buf[0] = OCD_SET_CTL_FLAGS; buf[1] = 0; - buf[2] = 1; /* Asynchronously return status when target stops */ + buf[2] = 1; ocd_put_packet (buf, 3); p = ocd_get_packet (buf[0], &pktlen, remote_timeout); @@ -232,7 +264,12 @@ ocd_start_remote (dummy) print_stack_frame (selected_frame, -1, 1); buf[0] = OCD_LOG_FILE; - buf[1] = 3; /* close existing WIGGLERS.LOG */ + buf[1] = 3; /* close existing WIGGLERS.LOG */ + ocd_put_packet (buf, 2); + p = ocd_get_packet (buf[0], &pktlen, remote_timeout); + + buf[0] = OCD_LOG_FILE; + buf[1] = 2; /* append to existing WIGGLERS.LOG */ ocd_put_packet (buf, 2); p = ocd_get_packet (buf[0], &pktlen, remote_timeout); @@ -267,28 +304,29 @@ device the OCD device is attached to (e.g. /dev/ttya)."); ocd_dcache = dcache_init (ocd_read_bytes, ocd_write_bytes); - if (strncmp(name,"wiggler",7) == 0) - { - ocd_desc = SERIAL_OPEN ("ocd"); - if (!ocd_desc) - perror_with_name (name); - - buf[0] = OCD_LOG_FILE; - buf[1] = 1; /* open new or overwrite existing WIGGLERS.LOG */ - ocd_put_packet (buf, 2); - p = ocd_get_packet (buf[0], &pktlen, remote_timeout); - - buf[0] = OCD_SET_CONNECTION; - buf[1] = 0x01; /* atoi (name[11]); */ - ocd_put_packet (buf, 2); - p = ocd_get_packet (buf[0], &pktlen, remote_timeout); - } - else /* not using Wigglers.dll */ - { - ocd_desc = SERIAL_OPEN (name); - if (!ocd_desc) - perror_with_name (name); - } + if (strncmp (name, "wiggler", 7) == 0) + { + ocd_desc = SERIAL_OPEN ("ocd"); + if (!ocd_desc) + perror_with_name (name); + + buf[0] = OCD_LOG_FILE; + buf[1] = 1; /* open new or overwrite existing WIGGLERS.LOG */ + ocd_put_packet (buf, 2); + p = ocd_get_packet (buf[0], &pktlen, remote_timeout); + + buf[0] = OCD_SET_CONNECTION; + buf[1] = 0x01; /* atoi (name[11]); */ + ocd_put_packet (buf, 2); + p = ocd_get_packet (buf[0], &pktlen, remote_timeout); + } + else + /* not using Wigglers.dll */ + { + ocd_desc = SERIAL_OPEN (name); + if (!ocd_desc) + perror_with_name (name); + } if (baud_rate != -1) { @@ -324,10 +362,13 @@ device the OCD device is attached to (e.g. /dev/ttya)."); /* Start the remote connection; if error (0), discard this target. In particular, if the user quits, be sure to discard it (we'd be in an inconsistent state otherwise). */ - if (!catch_errors (ocd_start_remote, (char *)target_type, + if (!catch_errors (ocd_start_remote, &target_type, "Couldn't establish connection to remote target\n", RETURN_MASK_ALL)) - pop_target(); + { + pop_target (); + error ("Failed to connect to OCD."); + } } /* This takes a program previously attached to and detaches it. After @@ -388,7 +429,7 @@ ocd_interrupt (signo) { /* If this doesn't work, try more severe steps. */ signal (signo, ocd_interrupt_twice); - + if (remote_debug) printf_unfiltered ("ocd_interrupt called\n"); @@ -402,7 +443,7 @@ ocd_interrupt (signo) } } -static void (*ofunc)(); +static void (*ofunc) (); /* The user typed ^C twice. */ static void @@ -410,7 +451,7 @@ ocd_interrupt_twice (signo) int signo; { signal (signo, ofunc); - + interrupt_query (); signal (signo, ocd_interrupt); @@ -445,37 +486,38 @@ int ocd_wait () { unsigned char *p; - int error_code, status; + int error_code; int pktlen; + char buf[1]; ocd_interrupt_flag = 0; - /* Target may already be stopped by the time we get here. */ + /* Target might already be stopped by the time we get here. */ + /* If we aren't already stopped, we need to loop until we've dropped + back into BDM mode */ - if (!(last_run_status & OCD_FLAG_BDM)) + while (!(last_run_status & OCD_FLAG_BDM)) { - ofunc = (void (*)()) signal (SIGINT, ocd_interrupt); - + buf[0] = OCD_AYT; + ocd_put_packet (buf, 1); p = ocd_get_packet (OCD_AYT, &pktlen, -1); + ofunc = (void (*)()) signal (SIGINT, ocd_interrupt); signal (SIGINT, ofunc); if (pktlen < 2) error ("Truncated response packet from OCD device"); - status = p[1]; + last_run_status = p[1]; error_code = p[2]; if (error_code != 0) ocd_error ("target_wait:", error_code); - if (status & OCD_FLAG_PWF) + if (last_run_status & OCD_FLAG_PWF) error ("OCD device lost VCC at BDM interface."); - else if (status & OCD_FLAG_CABLE_DISC) - error ("BDM cable appears to have been disconnected."); - - if (!(status & OCD_FLAG_BDM)) - error ("OCD device woke up, but wasn't stopped: 0x%x", status); + else if (last_run_status & OCD_FLAG_CABLE_DISC) + error ("OCD device cable appears to have been disconnected."); } if (ocd_interrupt_flag) @@ -591,7 +633,7 @@ ocd_write_bdm_register (bdm_regno, reg) ocd_write_bdm_registers (bdm_regno, buf, 4); } -void +void ocd_prepare_to_store () { } @@ -606,7 +648,7 @@ ocd_prepare_to_store () static int write_mem_command = OCD_WRITE_MEM; -static int +int ocd_write_bytes (memaddr, myaddr, len) CORE_ADDR memaddr; char *myaddr; @@ -759,7 +801,7 @@ ocd_xfer_memory (memaddr, myaddr, len, should_write, target) char *myaddr; int len; int should_write; - struct target_ops *target; /* ignored */ + struct target_ops *target; /* ignored */ { return dcache_xfer_memory (ocd_dcache, memaddr, myaddr, len, should_write); } @@ -826,7 +868,7 @@ get_quoted_char (timeout) } } -static unsigned char pkt[256 * 2 + 10], *pktp; /* Worst case */ +static unsigned char pkt[256 * 2 + 10], *pktp; /* Worst case */ static void reset_packet () @@ -924,7 +966,7 @@ ocd_put_packet (buf, len) unsigned char c; unsigned char *packet, *packet_ptr; - packet = alloca (len + 1 + 1); /* packet + SYN + checksum */ + packet = alloca (len + 1 + 1); /* packet + SYN + checksum */ packet_ptr = packet; checksum = 0; @@ -950,7 +992,7 @@ ocd_put_packet (buf, len) first byte of the packet. Subsequent bytes are expected to arrive in time <= remote_timeout. Returns a pointer to a static buffer containing the payload of the packet. *LENP contains the length of the packet. -*/ + */ static unsigned char * stu_get_packet (cmd, lenp, timeout) @@ -962,7 +1004,7 @@ stu_get_packet (cmd, lenp, timeout) static unsigned char buf[256 + 10], *p; unsigned char checksum; - find_packet: +find_packet: ch = get_quoted_char (timeout); @@ -972,7 +1014,7 @@ stu_get_packet (cmd, lenp, timeout) if (ch != RAW_SYN) goto find_packet; - found_syn: /* Found the start of a packet */ +found_syn: /* Found the start of a packet */ p = buf; checksum = 0; @@ -1015,7 +1057,7 @@ stu_get_packet (cmd, lenp, timeout) first byte of the packet. Subsequent bytes are expected to arrive in time <= remote_timeout. Returns a pointer to a static buffer containing the payload of the packet. *LENP contains the length of the packet. -*/ + */ static unsigned char * ocd_get_packet (cmd, lenp, timeout) @@ -1029,15 +1071,13 @@ ocd_get_packet (cmd, lenp, timeout) unsigned char *packet_ptr; unsigned char checksum; - find_packet: - ch = readchar (timeout); if (ch < 0) error ("ocd_get_packet (readchar): %d", ch); if (ch != 0x55) - goto find_packet; + error ("ocd_get_packet (readchar): %d", ch); /* Found the start of a packet */ @@ -1078,7 +1118,7 @@ ocd_get_packet (cmd, lenp, timeout) len = 8; /* write address, value read back */ break; case 0x11: /* Bus error? */ - /* write address, read flag */ + /* write address, read flag */ case 0x15: /* Internal error */ len = 5; /* error code, vector */ break; @@ -1088,48 +1128,47 @@ ocd_get_packet (cmd, lenp, timeout) case 0x0: /* Normal result */ switch (packet[0]) { - case OCD_AYT: /* Are You There? */ - case OCD_SET_BAUD_RATE: /* Set Baud Rate */ - case OCD_INIT: /* Initialize OCD device */ + case OCD_AYT: /* Are You There? */ + case OCD_SET_BAUD_RATE: /* Set Baud Rate */ + case OCD_INIT: /* Initialize OCD device */ case OCD_SET_SPEED: /* Set Speed */ - case OCD_SET_FUNC_CODE: /* Set Function Code */ - case OCD_SET_CTL_FLAGS: /* Set Control Flags */ - case OCD_SET_BUF_ADDR: /* Set Register Buffer Address */ - case OCD_RUN: /* Run Target from PC */ + case OCD_SET_FUNC_CODE: /* Set Function Code */ + case OCD_SET_CTL_FLAGS: /* Set Control Flags */ + case OCD_SET_BUF_ADDR: /* Set Register Buffer Address */ + case OCD_RUN: /* Run Target from PC */ case OCD_RUN_ADDR: /* Run Target from Specified Address */ - case OCD_STOP: /* Stop Target */ + case OCD_STOP: /* Stop Target */ case OCD_RESET_RUN: /* Reset Target and Run */ case OCD_RESET: /* Reset Target and Halt */ - case OCD_STEP: /* Single Step */ - case OCD_WRITE_REGS: /* Write Register */ + case OCD_STEP: /* Single Step */ + case OCD_WRITE_REGS: /* Write Register */ case OCD_WRITE_MEM: /* Write Memory */ case OCD_FILL_MEM: /* Fill Memory */ case OCD_MOVE_MEM: /* Move Memory */ - case OCD_WRITE_INT_MEM: /* Write Internal Memory */ - case OCD_JUMP: /* Jump to Subroutine */ - case OCD_ERASE_FLASH: /* Erase flash memory */ - case OCD_PROGRAM_FLASH: /* Write flash memory */ + case OCD_WRITE_INT_MEM: /* Write Internal Memory */ + case OCD_JUMP: /* Jump to Subroutine */ + case OCD_ERASE_FLASH: /* Erase flash memory */ + case OCD_PROGRAM_FLASH: /* Write flash memory */ case OCD_EXIT_MON: /* Exit the flash programming monitor */ case OCD_ENTER_MON: /* Enter the flash programming monitor */ case OCD_LOG_FILE: /* Make Wigglers.dll save Wigglers.log */ - case OCD_SET_CONNECTION: /* Set type of connection in Wigglers.dll */ + case OCD_SET_CONNECTION: /* Set type of connection in Wigglers.dll */ len = 0; break; - case OCD_GET_VERSION: /* Get Version */ + case OCD_GET_VERSION: /* Get Version */ len = 10; break; - case OCD_GET_STATUS_MASK: /* Get Status Mask */ + case OCD_GET_STATUS_MASK: /* Get Status Mask */ len = 1; break; case OCD_GET_CTRS: /* Get Error Counters */ case OCD_READ_REGS: /* Read Register */ case OCD_READ_MEM: /* Read Memory */ - case OCD_READ_INT_MEM: /* Read Internal Memory */ + case OCD_READ_INT_MEM: /* Read Internal Memory */ len = 257; break; default: - fprintf_filtered (gdb_stderr, "Unknown packet type 0x%x\n", ch); - goto find_packet; + error ("ocd_get_packet: unknown packet type 0x%x\n", ch); } } @@ -1157,12 +1196,12 @@ ocd_get_packet (cmd, lenp, timeout) } if (checksum != 0) - goto find_packet; + error ("ocd_get_packet: bad packet checksum"); if (cmd != -1 && cmd != packet[0]) error ("Response phase error. Got 0x%x, expected 0x%x", packet[0], cmd); - *lenp = packet_ptr - packet - 1; /* Subtract checksum byte */ + *lenp = packet_ptr - packet - 1; /* Subtract checksum byte */ return packet; } #endif @@ -1180,8 +1219,11 @@ ocd_do_command (cmd, statusp, lenp) int status, error_code; char errbuf[100]; + unsigned char logbuf[100]; + int logpktlen; + buf[0] = cmd; - ocd_put_packet (buf, 1); /* Send command */ + ocd_put_packet (buf, 1); /* Send command */ p = ocd_get_packet (*buf, lenp, remote_timeout); if (*lenp < 3) @@ -1203,6 +1245,16 @@ ocd_do_command (cmd, statusp, lenp) *statusp = status; + logbuf[0] = OCD_LOG_FILE; + logbuf[1] = 3; /* close existing WIGGLERS.LOG */ + ocd_put_packet (logbuf, 2); + ocd_get_packet (logbuf[0], &logpktlen, remote_timeout); + + logbuf[0] = OCD_LOG_FILE; + logbuf[1] = 2; /* append to existing WIGGLERS.LOG */ + ocd_put_packet (logbuf, 2); + ocd_get_packet (logbuf[0], &logpktlen, remote_timeout); + return p + 3; } @@ -1264,20 +1316,42 @@ ocd_load (args, from_tty) clear_symtab_users (); } +/* This should be defined for each target */ +/* But we want to be able to compile this file for some configurations + not yet supported fully */ + +#define BDM_BREAKPOINT {0x0,0x0,0x0,0x0} /* For ppc 8xx */ +#if 0 +#define BDM_BREAKPOINT {0x4a,0xfa} /* BGND insn used for CPU32 */ +#endif + /* BDM (at least on CPU32) uses a different breakpoint */ -static int +int ocd_insert_breakpoint (addr, contents_cache) CORE_ADDR addr; char *contents_cache; { - static char break_insn[] = {BDM_BREAKPOINT}; + static char break_insn[] = BDM_BREAKPOINT; int val; - val = target_read_memory (addr, contents_cache, sizeof break_insn); + val = target_read_memory (addr, contents_cache, sizeof (break_insn)); if (val == 0) - val = target_write_memory (addr, break_insn, sizeof break_insn); + val = target_write_memory (addr, break_insn, sizeof (break_insn)); + + return val; +} + +int +ocd_remove_breakpoint (addr, contents_cache) + CORE_ADDR addr; + char *contents_cache; +{ + static char break_insn[] = BDM_BREAKPOINT; + int val; + + val = target_write_memory (addr, contents_cache, sizeof (break_insn)); return val; } @@ -1346,7 +1420,7 @@ bdm_update_flash_command (args, from_tty) if (!args) error ("Must specify file containing new OCD code."); -/* old_chain = make_cleanup (flash_cleanup, 0);*/ +/* old_chain = make_cleanup (flash_cleanup, 0); */ ocd_do_command (OCD_ENTER_MON, &status, &pktlen); @@ -1363,7 +1437,7 @@ bdm_update_flash_command (args, from_tty) ocd_do_command (OCD_EXIT_MON, &status, &pktlen); -/* discard_cleanups (old_chain);*/ +/* discard_cleanups (old_chain); */ } static void @@ -1388,8 +1462,8 @@ _initialize_remote_ocd () static struct cmd_list_element *ocd_cmd_list = NULL; add_show_from_set (add_set_cmd ("remotetimeout", no_class, - var_integer, (char *)&remote_timeout, - "Set timeout value for remote read.\n", &setlist), + var_integer, (char *) &remote_timeout, + "Set timeout value for remote read.\n", &setlist), &showlist); add_prefix_cmd ("ocd", class_obscure, bdm_command, "", &ocd_cmd_list, "ocd ", @@ -1398,5 +1472,5 @@ _initialize_remote_ocd () add_cmd ("reset", class_obscure, bdm_reset_command, "", &ocd_cmd_list); add_cmd ("restart", class_obscure, bdm_restart_command, "", &ocd_cmd_list); add_cmd ("update-flash", class_obscure, bdm_update_flash_command, "", &ocd_cmd_list); - /* add_cmd ("read-register", class_obscure, bdm_read_register_command, "", &ocd_cmd_list);*/ + /* add_cmd ("read-register", class_obscure, bdm_read_register_command, "", &ocd_cmd_list); */ }