static int cris_insert_point (char type, CORE_ADDR addr, int len) { int bp; unsigned long bp_ctrl; unsigned long start, end; unsigned long ccs; struct regcache *regcache; /* Breakpoint/watchpoint types (GDB terminology): 0 = memory breakpoint for instructions (not supported; done via memory write instead) 1 = hardware breakpoint for instructions (not supported) 2 = write watchpoint (supported) 3 = read watchpoint (supported) 4 = access watchpoint (supported). */ if (type < '2' || type > '4') { /* Unsupported. */ return 1; } regcache = get_thread_regcache (current_inferior, 1); /* Read watchpoints are set as access watchpoints, because of GDB's inability to deal with pure read watchpoints. */ if (type == '3') type = '4'; /* Get the configuration register. */ collect_register_by_name (regcache, "s0", &bp_ctrl); /* The watchpoint allocation scheme is the simplest possible. For example, if a region is watched for read and a write watch is requested, a new watchpoint will be used. Also, if a watch for a region that is already covered by one or more existing watchpoints, a new watchpoint will be used. */ /* First, find a free data watchpoint. */ for (bp = 0; bp < 6; bp++) { /* Each data watchpoint's control registers occupy 2 bits (hence the 3), starting at bit 2 for D0 (hence the 2) with 4 bits between for each watchpoint (yes, the 4). */ if (!(bp_ctrl & (0x3 << (2 + (bp * 4))))) break; } if (bp > 5) { /* We're out of watchpoints. */ return -1; } /* Configure the control register first. */ if (type == '3' || type == '4') { /* Trigger on read. */ bp_ctrl |= (1 << (2 + bp * 4)); } if (type == '2' || type == '4') { /* Trigger on write. */ bp_ctrl |= (2 << (2 + bp * 4)); } /* Setup the configuration register. */ supply_register_by_name (regcache, "s0", &bp_ctrl); /* Setup the range. */ start = addr; end = addr + len - 1; /* Configure the watchpoint register. */ cris_write_data_breakpoint (regcache, bp, start, end); collect_register_by_name (regcache, "ccs", &ccs); /* Set the S1 flag to enable watchpoints. */ ccs |= (1 << 19); supply_register_by_name (regcache, "ccs", &ccs); 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); /* Read watchpoints are set as access watchpoints, because of GDB's inability to deal with pure read watchpoints. */ if (type == raw_bkpt_type_read_wp) type = raw_bkpt_type_access_wp; /* Get the configuration register. */ collect_register_by_name (regcache, "s0", &bp_ctrl); /* The watchpoint allocation scheme is the simplest possible. For example, if a region is watched for read and a write watch is requested, a new watchpoint will be used. Also, if a watch for a region that is already covered by one or more existing watchpoints, a new watchpoint will be used. */ /* First, find a free data watchpoint. */ for (bp = 0; bp < 6; bp++) { /* Each data watchpoint's control registers occupy 2 bits (hence the 3), starting at bit 2 for D0 (hence the 2) with 4 bits between for each watchpoint (yes, the 4). */ if (!(bp_ctrl & (0x3 << (2 + (bp * 4))))) break; } if (bp > 5) { /* We're out of watchpoints. */ return -1; } /* Configure the control register first. */ if (type == raw_bkpt_type_read_wp || type == raw_bkpt_type_access_wp) { /* Trigger on read. */ bp_ctrl |= (1 << (2 + bp * 4)); } if (type == raw_bkpt_type_write_wp || type == raw_bkpt_type_access_wp) { /* Trigger on write. */ bp_ctrl |= (2 << (2 + bp * 4)); } /* Setup the configuration register. */ supply_register_by_name (regcache, "s0", &bp_ctrl); /* Setup the range. */ start = addr; end = addr + len - 1; /* Configure the watchpoint register. */ cris_write_data_breakpoint (regcache, bp, start, end); collect_register_by_name (regcache, "ccs", &ccs); /* Set the S1 flag to enable watchpoints. */ ccs |= (1 << 19); supply_register_by_name (regcache, "ccs", &ccs); return 0; }