📄 remote-hms.c
字号:
int ch_handled; int old_timeout = timeout; int old_immediate_quit = immediate_quit; int swallowed_cr = 0; WSETEXIT ((*status), 0); if (need_artificial_trap != 0) { WSETSTOP ((*status), SIGTRAP); need_artificial_trap--; return 0; } timeout = 99999; /* Don't time out -- user program is running. */ immediate_quit = 1; /* Helps ability to QUIT */ while (1) { QUIT; /* Let user quit and leave process running */ ch_handled = 0; ch = readchar (); if (ch == *bp) { bp++; if (*bp == '\0') break; ch_handled = 1; *swallowed_p++ = ch; } else { bp = bpt; } if (ch == *ep || *ep == '?') { ep++; if (*ep == '\0') break; if (!ch_handled) *swallowed_p++ = ch; ch_handled = 1; } else { ep = exitmsg; } if (!ch_handled) { char *p; /* Print out any characters which have been swallowed. */ for (p = swallowed; p < swallowed_p; ++p) putc (*p, stdout); swallowed_p = swallowed; if ((ch != '\r' && ch != '\n') || swallowed_cr>10) { putc (ch, stdout); swallowed_cr = 10; } swallowed_cr ++; } } if (*bp== '\0') { WSETSTOP ((*status), SIGTRAP); expect_prompt(); } else { WSETEXIT ((*status), 0); } timeout = old_timeout; immediate_quit = old_immediate_quit; return 0;}/* Return the name of register number REGNO in the form input and output by hms. Returns a pointer to a static buffer containing the answer. */static char *get_reg_name (regno) int regno;{ static char *rn[NUM_REGS]= REGISTER_NAMES; return rn[regno];}/* Read the remote registers. */static int gethex(length, start, ok)unsigned int length;char *start;int *ok;{ int result = 0; while (length--) { result <<= 4 ; if (*start >='a' && *start <= 'f') { result += *start - 'a' + 10; } else if (*start >='A' && *start <= 'F') { result += *start - 'A' + 10; } else if (*start >='0' && *start <= '9') { result += *start - '0' ; } else *ok = 0; start++; } return result;}static int timed_read(buf, n, timeout)char *buf;{ int i; char c; i = 0; while (i < n) { c = readchar(); if (c == 0) return i; buf[i] = c; i++; } return i; }hms_write(a,l)char *a;{ int i; serial_write(a, l); if (!quiet) for (i = 0; i < l ; i++) { printf("%c", a[i]); }}hms_write_cr(s)char *s;{ hms_write( s, strlen(s)); hms_write("\r",1); }static voidhms_fetch_register (dummy)int dummy;{#define REGREPLY_SIZE 79 char linebuf[REGREPLY_SIZE+1]; int i; int s ; int gottok; REGISTER_TYPE reg[NUM_REGS]; int foo[8]; check_open(); do { hms_write_cr("r"); s = timed_read(linebuf, REGREPLY_SIZE, 1); linebuf[REGREPLY_SIZE] = 0; gottok = 0; if (linebuf[0] == 'r' && linebuf[3] == 'P' && linebuf[4] == 'C' && linebuf[5] == '=' && linebuf[75] == 'H' && linebuf[76] == 'M' && linebuf[77] == 'S') { /* PC=XXXX CCR=XX:XXXXXXXX R0-R7= XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX 5436789012345678901234567890123456789012345678901234567890123456789012 0 1 2 3 4 5 6 */ gottok = 1; reg[PC_REGNUM] = gethex(4,linebuf+6, &gottok); reg[CCR_REGNUM] = gethex(2,linebuf+15, &gottok); for (i = 0; i < 8; i++) { reg[i] = gethex(4, linebuf+34+5*i, &gottok); } } } while (!gottok); for (i = 0; i < NUM_REGS; i++) { char swapped[2]; swapped[1] = reg[i]; swapped[0] = (reg[i])>> 8; supply_register (i, swapped); } }/* Store register REGNO, or all if REGNO == -1. Return errno value. */static voidhms_store_register (regno) int regno;{ /* printf("hms_store_register() called.\n"); fflush(stdout); /* */ if (regno == -1) { for (regno = 0; regno < NUM_REGS; regno ++) { hms_store_register(regno); } } else { char *name = get_reg_name (regno); char buffer[100]; sprintf(buffer,"r %s=%x", name, read_register(regno)); hms_write_cr(buffer); expect_prompt(); }}/* Get ready to modify the registers array. On machines which store individual registers, this doesn't need to do anything. On machines which store all the registers in one fell swoop, this makes sure that registers contains all the registers from the program being debugged. */voidhms_prepare_to_store (){ /* Do nothing, since we can store individual regs */}static CORE_ADDR translate_addr(addr)CORE_ADDR addr;{ return(addr);}/* Read a word from remote address ADDR and return it. * This goes through the data cache. */inthms_fetch_word (addr) CORE_ADDR addr;{ return dcache_fetch (addr);}/* Write a word WORD into remote address ADDR. This goes through the data cache. */voidhms_store_word (addr, word) CORE_ADDR addr; int word;{ dcache_poke (addr, word);}inthms_xfer_inferior_memory(memaddr, myaddr, len, write, target) CORE_ADDR memaddr; char *myaddr; int len; int write; struct target_ops *target; /* ignored */{ register int i; /* Round starting address down to longword boundary. */ register CORE_ADDR addr; /* Round ending address up; get number of longwords that makes. */ register int count; /* Allocate buffer of that many longwords. */ register int *buffer ; memaddr &= 0xffff; addr = memaddr & - sizeof (int); count = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int); buffer = (int *)alloca (count * sizeof (int)); if (write) { /* Fill start and end extra bytes of buffer with existing memory data. */ if (addr != memaddr || len < (int)sizeof (int)) { /* Need part of initial word -- fetch it. */ buffer[0] = hms_fetch_word (addr); } if (count > 1) /* FIXME, avoid if even boundary */ { buffer[count - 1] = hms_fetch_word (addr + (count - 1) * sizeof (int)); } /* Copy data to be written over corresponding part of buffer */ bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len); /* Write the entire buffer. */ for (i = 0; i < count; i++, addr += sizeof (int)) { errno = 0; hms_store_word (addr, buffer[i]); if (errno) { return 0; } } } else { /* Read all the longwords */ for (i = 0; i < count; i++, addr += sizeof (int)) { errno = 0; buffer[i] = hms_fetch_word (addr); if (errno) { return 0; } QUIT; } /* Copy appropriate bytes out of the buffer. */ bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len); } return len;}inthms_write_inferior_memory (memaddr, myaddr, len) CORE_ADDR memaddr; unsigned char *myaddr; int len;{ bfd_vma addr; int done; int todo ; done = 0; while(done < len) { char buffer[20]; int thisgo; int idx; thisgo = len - done; if (thisgo > 20) thisgo = 20; sprintf(buffer,"M.B %4x =", memaddr+done); hms_write(buffer,10); for (idx = 0; idx < thisgo; idx++) { char buf[20]; sprintf(buf, "%2x ", myaddr[idx+done]); hms_write(buf, 3); } hms_write_cr(""); expect_prompt(); done += thisgo; }}voidhms_files_info (){char *file = "nothing";if (exec_bfd) file = bfd_get_filename(exec_bfd);if (exec_bfd)#ifdef __GO32__ printf_filtered("\tAttached to DOS asynctsr and running program %s\n",file);#else printf_filtered("\tAttached to %s at %d baud and running program %s\n",file);#endif printf_filtered("\ton an H8/300 processor.\n");}/* Copy LEN bytes of data from debugger memory at MYADDR to inferior's memory at MEMADDR. Returns errno value. * sb/sh instructions don't work on unaligned addresses, when TU=1. *//* Read LEN bytes from inferior memory at MEMADDR. Put the result at debugger address MYADDR. Returns errno value. */inthms_read_inferior_memory(memaddr, myaddr, len) CORE_ADDR memaddr; char *myaddr; int len;{ /* Align to nearest low 16 bits */ int i; #if 0 CORE_ADDR start = memaddr & ~0xf; CORE_ADDR end = ((memaddr + len +16) & ~0xf) -1;#endif CORE_ADDR start = memaddr; CORE_ADDR end = memaddr + len -1; int ok =1; /* AAAA: XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX '................' 012345678901234567890123456789012345678901234567890123456789012345 0 1 2 3 4 5 6 */ char buffer[66]; if (memaddr & 0xf) abort(); if (len != 16) abort(); sprintf(buffer, "m %4x %4x", start & 0xffff, end & 0xffff); hms_write_cr(buffer); /* drop the echo and newline*/ for (i = 0; i < 13; i++) readchar(); /* Grab the lines as they come out and fill the area */ /* Skip over cr */ while(1) { int p; int i; int addr; size_t idx; char byte[16]; buffer[0] = readchar(); if (buffer[0] == 'M') break; for (i = 1; i < 66; i++) buffer[i] = readchar(); /* Now parse the line */ addr = gethex(4, buffer, &ok); idx = 6; for (p = 0; p < 16; p+=2) { byte[p] = gethex(2, buffer + idx, &ok); byte[p+1] = gethex(2, buffer+ idx + 2, &ok); idx+=5; } for (p = 0; p<16;p++) { if (addr + p >= memaddr && addr + p < memaddr + len) { myaddr[ (addr + p)-memaddr] = byte[p]; } } } hms_write_cr(" "); expect_prompt(); return len;}/* This routine is run as a hook, just before the main command loop is entered. If gdb is configured for the H8, but has not had its target specified yet, this will loop prompting the user to do so.*/hms_before_main_loop (){ char ttyname[100]; char *p, *p2; extern FILE *instream; extern jmp_buf to_top_level; push_target (&hms_ops);}#define MAX_BREAKS 16static int num_brkpts=0;static inthms_insert_breakpoint(addr, save)CORE_ADDR addr;char *save; /* Throw away, let hms save instructions */{ check_open(); if (num_brkpts < MAX_BREAKS) { char buffer[100]; num_brkpts++; sprintf(buffer,"b %x", addr & 0xffff); hms_write_cr(buffer); expect_prompt (); return(0); } else { fprintf_filtered(stderr, "Too many break points, break point not installed\n"); return(1); }}static inthms_remove_breakpoint(addr, save)CORE_ADDR addr;char *save; /* Throw away, let hms save instructions */{ if (num_brkpts > 0) { char buffer[100]; num_brkpts--; sprintf(buffer,"b - %x", addr & 0xffff); hms_write_cr(buffer); expect_prompt(); } return(0);}/* Clear the hmss notion of what the break points are */static inthms_clear_breakpoints() { if (is_open) { hms_write_cr("b -"); expect_prompt (); } num_brkpts = 0;}static voidhms_mourn() { hms_clear_breakpoints(); generic_mourn_inferior ();}/* Put a command string, in args, out to the hms. The hms is assumed to be in raw mode, all writing/reading done through desc. Ouput from the hms is placed on the users terminal until the prompt from the hms is seen. FIXME: Can't handle commands that take input. */voidhms_com (args, fromtty) char *args; int fromtty;{ check_open(); if (!args) return; /* Clear all input so only command relative output is displayed */ hms_write_cr(args); hms_write("\030",1); expect_prompt();}/* Define the target subroutine names */struct target_ops hms_ops = { "hms", "Remote HMS monitor","Use the H8 evaluation board running the HMS monitor connected\n\by a serial line.", hms_open, hms_close, 0, hms_detach, hms_resume, hms_wait, /* attach */ hms_fetch_register, hms_store_register, hms_prepare_to_store, hms_xfer_inferior_memory, hms_files_info, hms_insert_breakpoint, hms_remove_breakpoint, /* Breakpoints */ 0, 0, 0, 0, 0, /* Terminal handling */ hms_kill, /* FIXME, kill */ hms_load, 0, /* lookup_symbol */ hms_create_inferior, /* create_inferior */ hms_mourn, /* mourn_inferior FIXME */ 0, /* can_run */ 0, /* notice_signals */ process_stratum, 0, /* next */ 1, 1, 1, 1, 1, /* all mem, mem, stack, regs, exec */ 0,0, /* Section pointers */ OPS_MAGIC, /* Always the last thing */};hms_quiet(){ quiet = ! quiet; if (quiet) printf_filtered("Snoop disabled\n"); else printf_filtered("Snoop enabled\n");}hms_device(s)char *s;{ if (s) { dev_name = get_word(&s); } }static hms_speed(s)char *s;{ check_open(); if (s) { char buffer[100]; int newrate = atoi(s); int which = 0; if (!serial_setbaudrate(newrate)) error("Can't use %d baud\n", newrate); printf_filtered("Checking target is in sync\n"); get_baudrate_right(); baudrate = newrate; printf_filtered("Sending commands to set target to %d\n", baudrate); sprintf(buffer, "tm %d. N 8 1", baudrate); hms_write_cr(buffer); } }/***********************************************************************/void_initialize_remote_hms (){ add_target (&hms_ops); add_com ("hms <command>", class_obscure, hms_com, "Send a command to the HMS monitor."); add_com ("snoop", class_obscure, hms_quiet, "Show what commands are going to the monitor"); add_com ("device", class_obscure, hms_device, "Set the terminal line for HMS communications"); add_com ("speed", class_obscure, hms_speed, "Set the terminal line speed for HMS communications"); #if 0 dev_name = serial_default_name();#endif dev_name = NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -