/* BDM/m68k specific low level interface, for the remote server for GDB. Copyright (C) 1989, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 2007 Chris Johns (chrisj@rtems.org). Copyright (C) 1995 W. Eric Norum Copyright (C) 2000 Bryan Feir (bryan@sgl.crestech.ca) This file is part of M68K BDM. 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 3 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. You should have received a copy of the GNU General Public License along with this program. If not, see . The code in the this file is based on the GDB server code in GDB and the code in M68K BDM GDB patch file called 'remote-m68k-bdm.c'. Based on: 1. `A Background Debug Mode Driver Package for Motorola's 16-bit and 32-Bit Microcontrollers', Scott Howard, Motorola Canada, 1993. 2. `Linux device driver for public domain BDM Interface', M. Schraut, Technische Universitaet Muenchen, Lehrstuhl fuer Prozessrechner, 1995. */ #include #include #include "server.h" #include "regdef.h" #include "m68k-bdm-low.h" /* * Compare a string with a constant string. */ #define M68K_BDM_STR_IS(_s, _c) \ (strncmp (_s, _c, sizeof (_c) - 1) == 0) /* * Map the internal GDB wait kinds to the response letters for the * remote protocol. */ #define TARGET_WAITKIND_STOPPED 'S' #define TARGET_WAITKIND_TRAP 'T' #define TARGET_WAITKIND_EXITED 'X' /* * The version of BDM hardware. */ #define M68K_BDM_VER_A (0) #define M68K_BDM_VER_B (1) #define M68K_BDM_VER_B_PLUS (9) #define M68K_BDM_VER_C (2) #define M68K_BDM_VER_D (3) #define M68K_BDM_VER_D_PLUS (12) /* * The type of CPU. */ #define M68K_BDM_MARCH_68000 (0) #define M68K_BDM_MARCH_CPU32 (1) #define M68K_BDM_MARCH_CPU32PLUS (2) #define M68K_BDM_MARCH_CF5200 (3) #define M68K_BDM_MARCH_CF5235 (4) #define M68K_BDM_MARCH_CF5272 (5) #define M68K_BDM_MARCH_CF5282 (6) #define M68K_BDM_MARCH_CF52223 (7) #define M68K_BDM_MARCH_CF5307 (8) #define M68K_BDM_MARCH_CFV4E (9) /* * The CPU labels. */ #define M68K_BDM_MARCH_68000_LABEL "68000" #define M68K_BDM_MARCH_CPU32_LABEL "CPU32" #define M68K_BDM_MARCH_CPU32PLUS_LABEL "CPU32+" #define M68K_BDM_MARCH_CF5200_LABEL "CF5200" #define M68K_BDM_MARCH_CF5235_LABEL "CF5235" #define M68K_BDM_MARCH_CF5272_LABEL "CF5272" #define M68K_BDM_MARCH_CF5282_LABEL "CF5282" #define M68K_BDM_MARCH_CF52223_LABEL "CF52223" #define M68K_BDM_MARCH_CF5307_LABEL "CF5307" #define M68K_BDM_MARCH_CFV4E_LABEL "CFV4E" /* * The size of the register in bits. */ static const int m68k_bdm_reg_sizes[4] = { 32, 32, 32, 64 }; /* * The array of registers for each support processor. */ struct m68k_bdm_registers { const char const* xml_name; const struct m68k_bdm_reg_mapping* map; const int* num_regs; int watchpoints; int breakpoints; }; /* * The number of registers. */ #define M68K_BDM_NUM_REGS_BDM (*m68k_bdm_regs->num_regs) /* * Get a BDM register. */ #define M68K_BDM_REG_XML() (m68k_bdm_regs->xml_name) #define M68K_BDM_REG_NAME_INDEXED(_r) (m68k_bdm_regs->map[_r].name) #define M68K_BDM_REG_TYPE_INDEXED(_r) (m68k_bdm_regs->map[_r].type) #define M68K_BDM_REG_NUM_INDEXED(_r) (m68k_bdm_regs->map[_r].num) #define M68K_BDM_REG_CODE_INDEXED(_r) (m68k_bdm_regs->map[_r].code) #define M68K_BDM_REG_FLAGS_INDEXED(_r) (m68k_bdm_regs->map[_r].flags) #define M68K_BDM_REG_SIZE_INDEXED(_r) (m68k_bdm_reg_sizes[M68K_BDM_REG_TYPE_INDEXED (_r)]) #define M68K_BDM_REG_NAME(_r) M68K_BDM_REG_NAME_INDEXED(m68k_bdm_register_index (_r)) #define M68K_BDM_REG_TYPE(_r) M68K_BDM_REG_TYPE_INDEXED(m68k_bdm_register_index (_r)) #define M68K_BDM_REG_NUM(_r) M68K_BDM_REG_NUM_INDEXED(m68k_bdm_register_index (_r)) #define M68K_BDM_REG_CODE(_r) M68K_BDM_REG_CODE_INDEXED(m68k_bdm_register_index (_r)) #define M68K_BDM_REG_FLAGS(_r) M68K_BDM_REG_FLAGS_INDEXED(m68k_bdm_register_index (_r)) #define M68K_BDM_REG_SIZE(_r) M68K_BDM_REG_SIZE_INDEXED(m68k_bdm_register_index (_r)) /* * The supported registers maps. */ extern const struct m68k_bdm_reg_mapping m68k_bdm_68000_reg_map[]; extern const int m68k_bdm_68000_reg_map_size; extern const struct m68k_bdm_reg_mapping m68k_bdm_cpu32_reg_map[]; extern const int m68k_bdm_cpu32_reg_map_size; extern const struct m68k_bdm_reg_mapping m68k_bdm_cpu32plus_reg_map[]; extern const int m68k_bdm_cpu32plus_reg_map_size; extern const struct m68k_bdm_reg_mapping m68k_bdm_cf5200_reg_map[]; extern const int m68k_bdm_cf5200_reg_map_size; extern const struct m68k_bdm_reg_mapping m68k_bdm_cf52223_reg_map[]; extern const int m68k_bdm_cf52223_reg_map_size; extern const struct m68k_bdm_reg_mapping m68k_bdm_cf5235_reg_map[]; extern const int m68k_bdm_cf5235_reg_map_size; extern const struct m68k_bdm_reg_mapping m68k_bdm_cf5272_reg_map[]; extern const int m68k_bdm_cf5272_reg_map_size; extern const struct m68k_bdm_reg_mapping m68k_bdm_cf5282_reg_map[]; extern const int m68k_bdm_cf5282_reg_map_size; extern const struct m68k_bdm_reg_mapping m68k_bdm_cf5307_reg_map[]; extern const int m68k_bdm_cf5307_reg_map_size; extern const struct m68k_bdm_reg_mapping m68k_bdm_cfv4e_reg_map[]; extern const int m68k_bdm_cfv4e_reg_map_size; /* * Must match the type of CPU index at the start of this file. */ const struct m68k_bdm_registers m68k_bdm_reg_map[] = { /* 0 */ { "m68k-core.xml", m68k_bdm_68000_reg_map, &m68k_bdm_68000_reg_map_size, 0, 0 }, /* 1 */ { "m68k-cpu32.xml", m68k_bdm_cpu32_reg_map, &m68k_bdm_cpu32_reg_map_size, 0, 0 }, /* 2 */ { "m68k-cpu32plus.xml", m68k_bdm_cpu32plus_reg_map, &m68k_bdm_cpu32plus_reg_map_size, 0, 0 }, /* 3 */ { "m68k-cf5200.xml", m68k_bdm_cf5200_reg_map, &m68k_bdm_cf5200_reg_map_size, 1, 1 }, /* 4 */ { "m68k-cf5235.xml", m68k_bdm_cf5235_reg_map, &m68k_bdm_cf5235_reg_map_size, 1, 1 }, /* 5 */ { "m68k-cf5272.xml", m68k_bdm_cf5272_reg_map, &m68k_bdm_cf5272_reg_map_size, 1, 1 }, /* 6 */ { "m68k-cf5282.xml", m68k_bdm_cf5282_reg_map, &m68k_bdm_cf5282_reg_map_size, 1, 1 }, /* 7 */ { "m68k-cf52223.xml", m68k_bdm_cf52223_reg_map, &m68k_bdm_cf52223_reg_map_size, 1, 4 }, /* 8 */ { "m68k-cf5307.xml", m68k_bdm_cf5307_reg_map, &m68k_bdm_cf5307_reg_map_size, 1, 1 }, /* 9 */ { "m68k-cfv4e.xml", m68k_bdm_cfv4e_reg_map, &m68k_bdm_cfv4e_reg_map_size, 2, 4 } }; const char *m68k_bdm_expedite_regs[] = { "sp", "fp", "pc", 0 }; /* * The name of the BDM driver special file */ static char* m68k_bdm_dev_name; static int m68k_bdm_cpu_family; static int m68k_bdm_cpu_type = M68K_BDM_MARCH_68000; static const char* m68k_bdm_cpu_label = M68K_BDM_MARCH_68000_LABEL; static const struct m68k_bdm_registers *m68k_bdm_regs = &m68k_bdm_reg_map[M68K_BDM_MARCH_68000]; static int m68k_bdm_kill_on_exit; /* * Hold BDM ATEMP register (CPU32 only). */ static unsigned long m68k_bdm_atemp; static int m68k_bdm_have_atemp; /* * CF BDM Debug hardware version number. */ static unsigned long m68k_bdm_cf_debug_ver; /* * Have we set a debug level. */ static int m68k_bdm_debug_level; /* * give target time to come up after reset * time in usec */ #define M68K_BDM_TIME_TO_COME_UP 60000 /* * We are quitting, so do not call error and therefore * jump back into the main event handler. */ static int m68k_bdm_gdb_is_quitting; /* * Release the processor on a close. */ static int m68k_bdm_release_on_exit; /* * Our pid. */ #define null_ptid (0) unsigned long m68k_bdm_ptid; /* * The breakpoint codes for the different processors */ #define M68K_BDM_BREAKPOINT_SIZE_MAX (2) static unsigned char m68k_bdm_cpu32_breakpoint[] = {0x4a, 0xfa}; static unsigned char m68k_bdm_cf_breakpoint[] = {0x4a, 0xc8}; static unsigned char* m68k_bdm_breakpoint_code = (unsigned char*) "\x4e\x41"; static unsigned int m68k_bdm_breakpoint_size = 2; /* * Trial of not stopping on an error. */ static int m68k_bdm_use_error; /* * Treat all breakpoints as hardware breakpoints. */ static int m68k_bdm_breakpoints_hard; /* * Display error message and jump back to main input loop */ static void m68k_bdm_report_error (void) { if (!m68k_bdm_gdb_is_quitting) { if (m68k_bdm_use_error) error ("m68k-bdm: error: %s", bdmErrorString ()); else printf_filtered ("m68k-bdm: error: %s", bdmErrorString ()); } } static void m68k_bdm_help (void) { printf_filtered ("%s\n" \ "%s -vVhBDd -t