gdb/gdbserver/linux-crisv32-low.c - gdb
Global variables defined
Functions defined
Macros defined
Source code
- #include "server.h"
- #include "linux-low.h"
- #include <sys/ptrace.h>
- void init_registers_crisv32 (void);
- extern const struct target_desc *tdesc_crisv32;
- #define cris_num_regs 49
- #ifndef PTRACE_GET_THREAD_AREA
- #define PTRACE_GET_THREAD_AREA 25
- #endif
- static int cris_regmap[] = {
- 1*4, 2*4, 3*4, 4*4,
- 5*4, 6*4, 7*4, 8*4,
- 9*4, 10*4, 11*4, 12*4,
- 13*4, 14*4, 24*4, 15*4,
- -1, -1, -1, 16*4,
- -1, 22*4, 23*4, 17*4,
- -1, -1, 21*4, 20*4,
- -1, 19*4, -1, 18*4,
- 25*4,
- 26*4, -1, -1, 29*4,
- 30*4, 31*4, 32*4, 33*4,
- 34*4, 35*4, 36*4, 37*4,
- 38*4, 39*4, 40*4, -1
- };
- extern int debug_threads;
- static CORE_ADDR
- cris_get_pc (struct regcache *regcache)
- {
- unsigned long pc;
- collect_register_by_name (regcache, "pc", &pc);
- if (debug_threads)
- debug_printf ("stop pc is %08lx\n", pc);
- return pc;
- }
- static void
- cris_set_pc (struct regcache *regcache, CORE_ADDR pc)
- {
- unsigned long newpc = pc;
- supply_register_by_name (regcache, "pc", &newpc);
- }
- static const unsigned short cris_breakpoint = 0xe938;
- #define cris_breakpoint_len 2
- static int
- cris_breakpoint_at (CORE_ADDR where)
- {
- unsigned short insn;
- (*the_target->read_memory) (where, (unsigned char *) &insn,
- cris_breakpoint_len);
- if (insn == cris_breakpoint)
- return 1;
-
- return 0;
- }
- FIXME
- static CORE_ADDR
- cris_reinsert_addr (void)
- {
- struct regcache *regcache = get_thread_regcache (current_thread, 1);
- unsigned long pc;
- collect_register_by_name (regcache, "srp", &pc);
- return pc;
- }
- static void
- cris_write_data_breakpoint (struct regcache *regcache,
- int bp, unsigned long start, unsigned long end)
- {
- switch (bp)
- {
- case 0:
- supply_register_by_name (regcache, "s3", &start);
- supply_register_by_name (regcache, "s4", &end);
- break;
- case 1:
- supply_register_by_name (regcache, "s5", &start);
- supply_register_by_name (regcache, "s6", &end);
- break;
- case 2:
- supply_register_by_name (regcache, "s7", &start);
- supply_register_by_name (regcache, "s8", &end);
- break;
- case 3:
- supply_register_by_name (regcache, "s9", &start);
- supply_register_by_name (regcache, "s10", &end);
- break;
- case 4:
- supply_register_by_name (regcache, "s11", &start);
- supply_register_by_name (regcache, "s12", &end);
- break;
- case 5:
- supply_register_by_name (regcache, "s13", &start);
- supply_register_by_name (regcache, "s14", &end);
- break;
- }
- }
- static int
- cris_supports_z_point_type (char z_type)
- {
- switch (z_type)
- {
- case Z_PACKET_WRITE_WP:
- case Z_PACKET_READ_WP:
- case Z_PACKET_ACCESS_WP:
- return 1;
- default:
- return 0;
- }
- }
- static int
- cris_insert_point (enum raw_bkpt_type type, CORE_ADDR addr,
- int len, struct raw_breakpoint *bp)
- {
- int bp;
- unsigned long bp_ctrl;
- unsigned long start, end;
- unsigned long ccs;
- struct regcache *regcache;
- regcache = get_thread_regcache (current_thread, 1);
-
- if (type == raw_bkpt_type_read_wp)
- type = raw_bkpt_type_access_wp;
-
- collect_register_by_name (regcache, "s0", &bp_ctrl);
-
-
- for (bp = 0; bp < 6; bp++)
- {
-
- if (!(bp_ctrl & (0x3 << (2 + (bp * 4)))))
- break;
- }
- if (bp > 5)
- {
-
- return -1;
- }
-
- if (type == raw_bkpt_type_read_wp || type == raw_bkpt_type_access_wp)
- {
-
- bp_ctrl |= (1 << (2 + bp * 4));
- }
- if (type == raw_bkpt_type_write_wp || type == raw_bkpt_type_access_wp)
- {
-
- bp_ctrl |= (2 << (2 + bp * 4));
- }
-
- supply_register_by_name (regcache, "s0", &bp_ctrl);
-
- start = addr;
- end = addr + len - 1;
-
- cris_write_data_breakpoint (regcache, bp, start, end);
- collect_register_by_name (regcache, "ccs", &ccs);
-
- ccs |= (1 << 19);
- supply_register_by_name (regcache, "ccs", &ccs);
- return 0;
- }
- static int
- cris_remove_point (enum raw_bkpt_type type, CORE_ADDR addr, int len,
- struct raw_breakpoint *bp)
- {
- int bp;
- unsigned long bp_ctrl;
- unsigned long start, end;
- struct regcache *regcache;
- unsigned long bp_d_regs[12];
- regcache = get_thread_regcache (current_thread, 1);
-
- if (type == raw_bkpt_type_read_wp)
- type = raw_bkpt_type_access_wp;
-
- collect_register_by_name (regcache, "s0", &bp_ctrl);
-
-
-
- collect_register_by_name (regcache, "s3", &bp_d_regs[0]);
- collect_register_by_name (regcache, "s4", &bp_d_regs[1]);
- collect_register_by_name (regcache, "s5", &bp_d_regs[2]);
- collect_register_by_name (regcache, "s6", &bp_d_regs[3]);
- collect_register_by_name (regcache, "s7", &bp_d_regs[4]);
- collect_register_by_name (regcache, "s8", &bp_d_regs[5]);
- collect_register_by_name (regcache, "s9", &bp_d_regs[6]);
- collect_register_by_name (regcache, "s10", &bp_d_regs[7]);
- collect_register_by_name (regcache, "s11", &bp_d_regs[8]);
- collect_register_by_name (regcache, "s12", &bp_d_regs[9]);
- collect_register_by_name (regcache, "s13", &bp_d_regs[10]);
- collect_register_by_name (regcache, "s14", &bp_d_regs[11]);
- for (bp = 0; bp < 6; bp++)
- {
- if (bp_d_regs[bp * 2] == addr
- && bp_d_regs[bp * 2 + 1] == (addr + len - 1)) {
-
- int bitpos = 2 + bp * 4;
- int rw_bits;
-
- rw_bits = (bp_ctrl & (0x3 << bitpos)) >> bitpos;
- if ((type == raw_bkpt_type_read_wp && rw_bits == 0x1)
- || (type == raw_bkpt_type_write_wp && rw_bits == 0x2)
- || (type == raw_bkpt_type_access_wp && rw_bits == 0x3))
- {
-
- break;
- }
- }
- }
- if (bp > 5)
- {
-
- return -1;
- }
-
- bp_ctrl &= ~(3 << (2 + (bp * 4)));
-
- supply_register_by_name (regcache, "s0", &bp_ctrl);
- start = end = 0;
-
- cris_write_data_breakpoint (regcache, bp, start, end);
-
- return 0;
- }
- static int
- cris_stopped_by_watchpoint (void)
- {
- unsigned long exs;
- struct regcache *regcache = get_thread_regcache (current_thread, 1);
- collect_register_by_name (regcache, "exs", &exs);
- return (((exs & 0xff00) >> 8) == 0xc);
- }
- static CORE_ADDR
- cris_stopped_data_address (void)
- {
- unsigned long eda;
- struct regcache *regcache = get_thread_regcache (current_thread, 1);
- collect_register_by_name (regcache, "eda", &eda);
- FIXME
- return eda;
- }
- ps_err_e
- ps_get_thread_area (const struct ps_prochandle *ph,
- lwpid_t lwpid, int idx, void **base)
- {
- if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) != 0)
- return PS_ERR;
-
- *base = (void *) ((char *) *base - idx);
- return PS_OK;
- }
- static void
- cris_fill_gregset (struct regcache *regcache, void *buf)
- {
- int i;
- for (i = 0; i < cris_num_regs; i++)
- {
- if (cris_regmap[i] != -1)
- collect_register (regcache, i, ((char *) buf) + cris_regmap[i]);
- }
- }
- static void
- cris_store_gregset (struct regcache *regcache, const void *buf)
- {
- int i;
- for (i = 0; i < cris_num_regs; i++)
- {
- if (cris_regmap[i] != -1)
- supply_register (regcache, i, ((char *) buf) + cris_regmap[i]);
- }
- }
- static void
- cris_arch_setup (void)
- {
- current_process ()->tdesc = tdesc_crisv32;
- }
- static struct regset_info cris_regsets[] = {
- { PTRACE_GETREGS, PTRACE_SETREGS, 0, cris_num_regs * 4,
- GENERAL_REGS, cris_fill_gregset, cris_store_gregset },
- { 0, 0, 0, -1, -1, NULL, NULL }
- };
- static struct regsets_info cris_regsets_info =
- {
- cris_regsets,
- 0,
- NULL,
- };
- static struct usrregs_info cris_usrregs_info =
- {
- cris_num_regs,
- cris_regmap,
- };
- static struct regs_info regs_info =
- {
- NULL,
- &cris_usrregs_info,
- &cris_regsets_info
- };
- static const struct regs_info *
- cris_regs_info (void)
- {
- return ®s_info;
- }
- struct linux_target_ops the_low_target = {
- cris_arch_setup,
- cris_regs_info,
- NULL,
- NULL,
- NULL,
- cris_get_pc,
- cris_set_pc,
- (const unsigned char *) &cris_breakpoint,
- cris_breakpoint_len,
- cris_reinsert_addr,
- 0,
- cris_breakpoint_at,
- cris_supports_z_point_type,
- cris_insert_point,
- cris_remove_point,
- cris_stopped_by_watchpoint,
- cris_stopped_data_address,
- };
- void
- initialize_low_arch (void)
- {
- init_registers_crisv32 ();
- initialize_regsets_info (&cris_regsets_info);
- }