diff options
-rw-r--r-- | src/flash/at91sam7.c | 15 | ||||
-rw-r--r-- | src/flash/cfi.c | 11 | ||||
-rw-r--r-- | src/flash/nand.c | 4 | ||||
-rw-r--r-- | src/flash/nand.h | 4 | ||||
-rw-r--r-- | src/helper/command.c | 2 | ||||
-rw-r--r-- | src/helper/fileio.c | 3 | ||||
-rw-r--r-- | src/helper/log.h | 3 | ||||
-rw-r--r-- | src/helper/time_support.c | 3 | ||||
-rw-r--r-- | src/jtag/ft2232.c | 20 | ||||
-rw-r--r-- | src/jtag/gw16012.c | 4 | ||||
-rw-r--r-- | src/jtag/jtag.c | 4 | ||||
-rw-r--r-- | src/jtag/jtag.h | 2 | ||||
-rw-r--r-- | src/openocd.c | 1 | ||||
-rw-r--r-- | src/pld/xilinx_bit.c | 3 | ||||
-rw-r--r-- | src/server/gdb_server.c | 16 | ||||
-rw-r--r-- | src/target/Makefile.am | 4 | ||||
-rw-r--r-- | src/target/arm720t.c | 2 | ||||
-rw-r--r-- | src/target/arm7_9_common.c | 55 | ||||
-rw-r--r-- | src/target/arm7_9_common.h | 3 | ||||
-rw-r--r-- | src/target/arm7tdmi.c | 2 | ||||
-rw-r--r-- | src/target/arm966e.c | 11 | ||||
-rw-r--r-- | src/target/arm9tdmi.c | 11 | ||||
-rw-r--r-- | src/target/arm_disassembler.c | 6 | ||||
-rw-r--r-- | src/target/etb.c | 319 | ||||
-rw-r--r-- | src/target/etb.h | 62 | ||||
-rw-r--r-- | src/target/target.c | 10 |
26 files changed, 499 insertions, 81 deletions
diff --git a/src/flash/at91sam7.c b/src/flash/at91sam7.c index dc9c2d72..6d96c87a 100644 --- a/src/flash/at91sam7.c +++ b/src/flash/at91sam7.c @@ -146,7 +146,7 @@ void at91sam7_read_clock_info(flash_bank_t *bank) at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv; target_t *target = at91sam7_info->target; u32 mckr, mcfr, pllr; - unsigned long tmp, mainfreq; + unsigned long tmp = 0, mainfreq; /* Read main clock freqency register */ target_read_u32(target, CKGR_MCFR, &mcfr); @@ -276,7 +276,7 @@ int at91sam7_flash_command(struct flash_bank_s *bank,u8 cmd,u16 pagen) fcr = (0x5A<<24) | (pagen<<8) | cmd; target_write_u32(target, MC_FCR, fcr); - DEBUG("Flash command: 0x%x, pagenumber:", fcr, pagen); + DEBUG("Flash command: 0x%x, pagenumber:%u", fcr, pagen); if ((at91sam7_info->cidr_arch == 0x60)&&((cmd==SLB)|(cmd==CLB))) { @@ -328,7 +328,7 @@ int at91sam7_read_part_info(struct flash_bank_s *bank) bank->size = NVPSIZ[at91sam7_info->cidr_nvpsiz]; at91sam7_info->target_name = "Unknown"; - DEBUG("nvptyp: 0x%3.3x, arch: 0x%4.4x, alt_id: 0x%4.4x, alt_addr: 0x%4.4x", at91sam7_info->cidr_nvptyp, at91sam7_info->cidr_arch ); + DEBUG("nvptyp: 0x%3.3x, arch: 0x%4.4x", at91sam7_info->cidr_nvptyp, at91sam7_info->cidr_arch ); /* Read main and master clock freqency register */ at91sam7_read_clock_info(bank); @@ -491,8 +491,6 @@ int at91sam7_read_part_info(struct flash_bank_s *bank) int at91sam7_erase_check(struct flash_bank_s *bank) { at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv; - target_t *target = at91sam7_info->target; - int i; if (!at91sam7_info->working_area_size) { @@ -509,7 +507,6 @@ int at91sam7_protect_check(struct flash_bank_s *bank) u32 status; at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv; - target_t *target = at91sam7_info->target; if (at91sam7_info->cidr == 0) { @@ -544,7 +541,7 @@ int at91sam7_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, ch at91sam7_info->target = get_target_by_num(strtoul(args[5], NULL, 0)); if (!at91sam7_info->target) { - ERROR("no target '%i' configured", args[5]); + ERROR("no target '%s' configured", args[5]); exit(-1); } @@ -598,7 +595,6 @@ int at91sam7_protect(struct flash_bank_s *bank, int set, int first, int last) int lockregion; at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv; - target_t *target = at91sam7_info->target; if (at91sam7_info->target->state != TARGET_HALTED) { @@ -651,7 +647,6 @@ int at91sam7_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) target_t *target = at91sam7_info->target; u32 dst_min_alignment, wcount, bytes_remaining = count; u32 first_page, last_page, pagen, buffer_pos; - u32 fcr; if (at91sam7_info->target->state != TARGET_HALTED) { @@ -712,7 +707,7 @@ int at91sam7_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) { return ERROR_FLASH_OPERATION_FAILED; } - DEBUG("Flash command: 0x%x, pagenumber:", fcr, pagen); + DEBUG("Write page number:%i", pagen); } return ERROR_OK; diff --git a/src/flash/cfi.c b/src/flash/cfi.c index 7f2313d8..b8b7eb54 100644 --- a/src/flash/cfi.c +++ b/src/flash/cfi.c @@ -329,7 +329,7 @@ int cfi_intel_info(struct flash_bank_s *bank, char *buf, int buf_size) int cfi_register_commands(struct command_context_s *cmd_ctx) { - command_t *cfi_cmd = register_command(cmd_ctx, NULL, "cfi", NULL, COMMAND_ANY, NULL); + /*command_t *cfi_cmd = */register_command(cmd_ctx, NULL, "cfi", NULL, COMMAND_ANY, NULL); /* register_command(cmd_ctx, cfi_cmd, "part_id", cfi_handle_part_id_command, COMMAND_EXEC, "print part id of cfi flash bank <num>"); @@ -362,7 +362,7 @@ int cfi_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char ** cfi_info->target = get_target_by_num(strtoul(args[5], NULL, 0)); if (!cfi_info->target) { - ERROR("no target '%i' configured", args[5]); + ERROR("no target '%s' configured", args[5]); exit(-1); } @@ -377,7 +377,6 @@ int cfi_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char ** int cfi_intel_erase(struct flash_bank_s *bank, int first, int last) { cfi_flash_bank_t *cfi_info = bank->driver_priv; - cfi_intel_pri_ext_t *pri_ext = cfi_info->pri_ext; target_t *target = cfi_info->target; u8 command[8]; int i; @@ -593,7 +592,6 @@ void cfi_add_byte(struct flash_bank_s *bank, u8 *word, u8 byte) int cfi_intel_write_block(struct flash_bank_s *bank, u8 *buffer, u32 address, u32 count) { cfi_flash_bank_t *cfi_info = bank->driver_priv; - cfi_intel_pri_ext_t *pri_ext = cfi_info->pri_ext; target_t *target = cfi_info->target; reg_param_t reg_params[7]; armv4_5_algorithm_t armv4_5_info; @@ -602,7 +600,6 @@ int cfi_intel_write_block(struct flash_bank_s *bank, u8 *buffer, u32 address, u3 u8 write_command[CFI_MAX_BUS_WIDTH]; u8 busy_pattern[CFI_MAX_BUS_WIDTH]; u8 error_pattern[CFI_MAX_BUS_WIDTH]; - int i; int retval; /* algorithm register usage: @@ -774,7 +771,6 @@ int cfi_intel_write_block(struct flash_bank_s *bank, u8 *buffer, u32 address, u3 int cfi_intel_write_word(struct flash_bank_s *bank, u8 *word, u32 address) { cfi_flash_bank_t *cfi_info = bank->driver_priv; - cfi_intel_pri_ext_t *pri_ext = cfi_info->pri_ext; target_t *target = cfi_info->target; u8 command[8]; @@ -799,7 +795,6 @@ int cfi_intel_write_word(struct flash_bank_s *bank, u8 *word, u32 address) int cfi_write_word(struct flash_bank_s *bank, u8 *word, u32 address) { cfi_flash_bank_t *cfi_info = bank->driver_priv; - target_t *target = cfi_info->target; switch(cfi_info->pri_id) { @@ -885,6 +880,7 @@ int cfi_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count) break; default: ERROR("cfi primary command set %i unsupported", cfi_info->pri_id); + retval = ERROR_FLASH_OPERATION_FAILED; break; } if (retval != ERROR_OK) @@ -1216,7 +1212,6 @@ int cfi_intel_protect_check(struct flash_bank_s *bank) int cfi_protect_check(struct flash_bank_s *bank) { cfi_flash_bank_t *cfi_info = bank->driver_priv; - target_t *target = cfi_info->target; if (cfi_info->qry[0] != 'Q') return ERROR_FLASH_BANK_NOT_PROBED; diff --git a/src/flash/nand.c b/src/flash/nand.c index 221d2a4b..e0dfa22f 100644 --- a/src/flash/nand.c +++ b/src/flash/nand.c @@ -368,7 +368,6 @@ int nand_read_status(struct nand_device_s *device, u8 *status) int nand_probe(struct nand_device_s *device) { u8 manufacturer_id, device_id; - nand_manufacturer_t *manufacturer; int retval; int i; @@ -419,8 +418,6 @@ int nand_probe(struct nand_device_s *device) device_id = data_buf & 0xff; } - device->manufacturer = manufacturer; - for (i = 0; nand_flash_ids[i].name; i++) { if (nand_flash_ids[i].id == device_id) @@ -1139,7 +1136,6 @@ int handle_nand_check_bad_blocks_command(struct command_context_s *cmd_ctx, char int handle_nand_copy_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { nand_device_t *p; - int retval; if (argc != 4) { diff --git a/src/flash/nand.h b/src/flash/nand.h index 65f1589f..7161c506 100644 --- a/src/flash/nand.h +++ b/src/flash/nand.h @@ -196,6 +196,10 @@ enum oob_formats extern nand_device_t *get_nand_device_by_num(int num); extern int nand_read_page_raw(struct nand_device_s *device, u32 page, u8 *data, u32 data_size, u8 *oob, u32 oob_size); extern int nand_write_page_raw(struct nand_device_s *device, u32 page, u8 *data, u32 data_size, u8 *oob, u32 oob_size); +extern int nand_read_status(struct nand_device_s *device, u8 *status); + +extern int nand_register_commands(struct command_context_s *cmd_ctx); +extern int nand_init(struct command_context_s *cmd_ctx); #define ERROR_NAND_DEVICE_INVALID (-1100) #define ERROR_NAND_OPERATION_FAILED (-1101) diff --git a/src/helper/command.c b/src/helper/command.c index dbf3f2aa..b4b2164e 100644 --- a/src/helper/command.c +++ b/src/helper/command.c @@ -377,7 +377,7 @@ int command_run_line(command_context_t *context, char *line) int command_run_file(command_context_t *context, FILE *file, enum command_mode mode) { - int retval; + int retval = ERROR_OK; int old_command_mode; char buffer[4096]; diff --git a/src/helper/fileio.c b/src/helper/fileio.c index 1e4353af..756e0f46 100644 --- a/src/helper/fileio.c +++ b/src/helper/fileio.c @@ -360,6 +360,7 @@ int fileio_close(fileio_t *fileio) break; default: ERROR("BUG: should never get here"); + retval = ERROR_FILEIO_OPERATION_FAILED; } if (retval != ERROR_OK) @@ -500,7 +501,7 @@ int fileio_dispatch_write(fileio_t *fileio, u32 size, u8 *buffer, u32 *size_writ int fileio_write(fileio_t *fileio, u32 size, u8 *buffer, u32 *size_written) { - int retval; + int retval = ERROR_FILEIO_OPERATION_NOT_SUPPORTED; if (fileio->sec_type == FILEIO_PLAIN) { retval = fileio_dispatch_write(fileio, size, buffer, size_written); diff --git a/src/helper/log.h b/src/helper/log.h index c495524c..6988bfcb 100644 --- a/src/helper/log.h +++ b/src/helper/log.h @@ -39,7 +39,8 @@ enum log_levels }; extern void log_printf(enum log_levels level, const char *file, int line, - const char *function, const char *format, ...); + const char *function, const char *format, ...) + __attribute__ ((format (printf, 5, 6))); extern int log_register_commands(struct command_context_s *cmd_ctx); extern int log_init(struct command_context_s *cmd_ctx); diff --git a/src/helper/time_support.c b/src/helper/time_support.c index fffc5379..9615817f 100644 --- a/src/helper/time_support.c +++ b/src/helper/time_support.c @@ -24,6 +24,7 @@ #include "time_support.h" #include "log.h" +#include <stdlib.h> #include <sys/time.h> #include <time.h> @@ -101,7 +102,7 @@ int duration_stop_measure(duration_t *duration, char **text) if (text) { *text = malloc(16); - snprintf(*text, 16, "%is %ius", duration->duration.tv_sec, duration->duration.tv_usec); + snprintf(*text, 16, "%lis %lius", duration->duration.tv_sec, duration->duration.tv_usec); } return ERROR_OK; diff --git a/src/jtag/ft2232.c b/src/jtag/ft2232.c index 4a705b5e..2a8c7387 100644 --- a/src/jtag/ft2232.c +++ b/src/jtag/ft2232.c @@ -161,7 +161,7 @@ int ft2232_write(u8 *buf, int size, u32* bytes_written) if ((status = FT_Write(ftdih, buf, size, &dw_bytes_written)) != FT_OK) { *bytes_written = dw_bytes_written; - ERROR("FT_Write returned: %i", status); + ERROR("FT_Write returned: %lu", status); return ERROR_JTAG_DEVICE_ERROR; } else @@ -198,7 +198,7 @@ int ft2232_read(u8* buf, int size, u32* bytes_read) if ((status = FT_Read(ftdih, buf, size, &dw_bytes_read)) != FT_OK) { *bytes_read = 0; - ERROR("FT_Read returned: %i", status); + ERROR("FT_Read returned: %lu", status); return ERROR_JTAG_DEVICE_ERROR; } *bytes_read += dw_bytes_read; @@ -1165,7 +1165,7 @@ int ft2232_execute_queue() } else if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE) { - DEBUG("ft2232 buffer size reached, sending queued commands (first_unsent: %x, cmd: %x)", first_unsent, cmd); + DEBUG("ft2232 buffer size reached, sending queued commands (first_unsent: %p, cmd: %p)", first_unsent, cmd); ft2232_send_and_recv(first_unsent, cmd); require_send = 0; first_unsent = cmd; @@ -1283,7 +1283,7 @@ int ft2232_init(void) { DWORD num_devices; - ERROR("unable to open ftdi device: %i", status); + ERROR("unable to open ftdi device: %lu", status); status = FT_ListDevices(&num_devices, NULL, FT_LIST_NUMBER_ONLY); if (status == FT_OK) { @@ -1298,7 +1298,7 @@ int ft2232_init(void) if (status == FT_OK) { - ERROR("ListDevices: %d\n", num_devices); + ERROR("ListDevices: %lu\n", num_devices); for (i = 0; i < num_devices; i++) ERROR("%i: %s", i, desc_array[i]); } @@ -1316,13 +1316,13 @@ int ft2232_init(void) if ((status = FT_SetLatencyTimer(ftdih, 2)) != FT_OK) { - ERROR("unable to set latency timer: %i", status); + ERROR("unable to set latency timer: %lu", status); return ERROR_JTAG_INIT_FAILED; } if ((status = FT_GetLatencyTimer(ftdih, &latency_timer)) != FT_OK) { - ERROR("unable to get latency timer: %i", status); + ERROR("unable to get latency timer: %lu", status); return ERROR_JTAG_INIT_FAILED; } else @@ -1332,13 +1332,13 @@ int ft2232_init(void) if ((status = FT_SetTimeouts(ftdih, 5000, 5000)) != FT_OK) { - ERROR("unable to set timeouts: %i", status); + ERROR("unable to set timeouts: %lu", status); return ERROR_JTAG_INIT_FAILED; } if ((status = FT_SetBitMode(ftdih, 0x0b, 2)) != FT_OK) { - ERROR("unable to enable bit i/o mode: %i", status); + ERROR("unable to enable bit i/o mode: %lu", status); return ERROR_JTAG_INIT_FAILED; } #elif BUILD_FT2232_LIBFTDI == 1 @@ -1401,7 +1401,7 @@ int ft2232_init(void) #if BUILD_FT2232_FTD2XX == 1 if ((status = FT_Purge(ftdih, FT_PURGE_RX | FT_PURGE_TX)) != FT_OK) { - ERROR("error purging ftd2xx device: %i", status); + ERROR("error purging ftd2xx device: %lu", status); return ERROR_JTAG_INIT_FAILED; } #elif BUILD_FT2232_LIBFTDI == 1 diff --git a/src/jtag/gw16012.c b/src/jtag/gw16012.c index 8211fee3..1f1f6086 100644 --- a/src/jtag/gw16012.c +++ b/src/jtag/gw16012.c @@ -421,7 +421,7 @@ int gw16012_execute_queue(void) break; case JTAG_SLEEP: #ifdef _DEBUG_JTAG_IO_ - DEBUG("sleep", cmd->cmd.sleep->us); + DEBUG("sleep %i", cmd->cmd.sleep->us); #endif jtag_sleep(cmd->cmd.sleep->us); break; @@ -527,7 +527,7 @@ int gw16012_init(void) WARNING("No gw16012 port specified, using default '0x378' (LPT1)"); } - DEBUG("requesting privileges for parallel port 0x%x...", gw16012_port); + DEBUG("requesting privileges for parallel port 0x%lx...", gw16012_port); #if PARPORT_USE_GIVEIO == 1 if (gw16012_get_giveio_access() != 0) #else /* PARPORT_USE_GIVEIO */ diff --git a/src/jtag/jtag.c b/src/jtag/jtag.c index b8d963b1..13041fc1 100644 --- a/src/jtag/jtag.c +++ b/src/jtag/jtag.c @@ -1123,7 +1123,7 @@ int jtag_reset_callback(enum jtag_event event, void *priv) { jtag_device_t *device = priv; - DEBUG(""); + DEBUG("-"); if (event == JTAG_TRST_ASSERTED) { @@ -1332,7 +1332,7 @@ int jtag_init(struct command_context_s *cmd_ctx) { int i; - DEBUG(""); + DEBUG("-"); if (jtag_speed == -1) jtag_speed = 0; diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h index 29e3da60..ad038ae5 100644 --- a/src/jtag/jtag.h +++ b/src/jtag/jtag.h @@ -25,7 +25,7 @@ #include "command.h" -#if 0 +#if 1 #define _DEBUG_JTAG_IO_ #endif diff --git a/src/openocd.c b/src/openocd.c index 123db3c8..4fbaf467 100644 --- a/src/openocd.c +++ b/src/openocd.c @@ -32,6 +32,7 @@ #include "xsvf.h" #include "target.h" #include "flash.h" +#include "nand.h" #include "pld.h" #include "command.h" diff --git a/src/pld/xilinx_bit.c b/src/pld/xilinx_bit.c index 7bf72b2e..3c99db0d 100644 --- a/src/pld/xilinx_bit.c +++ b/src/pld/xilinx_bit.c @@ -67,8 +67,7 @@ int read_section(FILE *input_file, int length_size, char section, u32 *buffer_le if (length_size == 4) length = be_to_h_u32(length_buffer); - - if (length_size == 2) + else /* (length_size == 2) */ length = be_to_h_u16(length_buffer); if (buffer_length) diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 10e36767..34b66050 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -224,7 +224,7 @@ int gdb_get_packet(connection_t *connection, char *buffer, int *len) int count = 0; int retval; int first_char = 0; - int packet_type; + int packet_type = '\0'; char checksum[3]; unsigned char my_checksum = 0; gdb_connection_t *gdb_con = connection->priv; @@ -550,7 +550,7 @@ int gdb_get_registers_packet(connection_t *connection, target_t *target, char* p char *reg_packet_p; int i; - DEBUG(""); + DEBUG("-"); if ((retval = target->type->get_gdb_reg_list(target, ®_list, ®_list_size)) != ERROR_OK) { @@ -603,7 +603,7 @@ int gdb_set_registers_packet(connection_t *connection, target_t *target, char *p int retval; char *packet_p; - DEBUG(""); + DEBUG("-"); /* skip command character */ packet++; @@ -677,7 +677,7 @@ int gdb_get_register_packet(connection_t *connection, target_t *target, char *pa int retval; char *hex_buf; - DEBUG(""); + DEBUG("-"); if ((retval = target->type->get_gdb_reg_list(target, ®_list, ®_list_size)) != ERROR_OK) { @@ -725,7 +725,7 @@ int gdb_set_register_packet(connection_t *connection, target_t *target, char *pa int retval; reg_arch_type_t *arch_type; - DEBUG(""); + DEBUG("-"); if ((retval = target->type->get_gdb_reg_list(target, ®_list, ®_list_size)) != ERROR_OK) { @@ -1039,7 +1039,7 @@ void gdb_step_continue_packet(connection_t *connection, target_t *target, char * int current = 0; u32 address = 0x0; - DEBUG(""); + DEBUG("-"); if (packet_size > 1) { @@ -1085,14 +1085,14 @@ int gdb_bp_wp_packet_error(connection_t *connection, int retval) int gdb_breakpoint_watchpoint_packet(connection_t *connection, target_t *target, char *packet, int packet_size) { int type; - enum breakpoint_type bp_type; + enum breakpoint_type bp_type = BKPT_SOFT /* dummy init to avoid warning */; enum watchpoint_rw wp_type; u32 address; u32 size; char *separator; int retval; - DEBUG(""); + DEBUG("-"); type = strtoul(packet + 1, &separator, 16); diff --git a/src/target/Makefile.am b/src/target/Makefile.am index 35414f37..3e2b39d3 100644 --- a/src/target/Makefile.am +++ b/src/target/Makefile.am @@ -3,7 +3,7 @@ METASOURCES = AUTO noinst_LIBRARIES = libtarget.a libtarget_a_SOURCES = target.c register.c breakpoints.c armv4_5.c embeddedice.c etm.c arm7tdmi.c arm9tdmi.c \ arm_jtag.c arm7_9_common.c algorithm.c arm920t.c arm720t.c armv4_5_mmu.c armv4_5_cache.c arm_disassembler.c \ - arm966e.c arm926ejs.c + arm966e.c arm926ejs.c etb.c noinst_HEADERS = target.h register.h armv4_5.h embeddedice.h etm.h arm7tdmi.h arm9tdmi.h \ arm_jtag.h arm7_9_common.h arm920t.h arm720t.h armv4_5_mmu.h armv4_5_cache.h breakpoints.h algorithm.h \ - arm_disassembler.h arm966e.h arm926ejs.h + arm_disassembler.h arm966e.h arm926ejs.h etb.h diff --git a/src/target/arm720t.c b/src/target/arm720t.c index 0a95e1c5..1b809e6d 100644 --- a/src/target/arm720t.c +++ b/src/target/arm720t.c @@ -138,7 +138,7 @@ int arm720t_scan_cp15(target_t *target, u32 out, u32 *in, int instruction, int c else DEBUG("out: %8.8x, instruction: %i, clock: %i", out, instruction, clock); #else - DEBUG("out: %8.8x, instruction: %i, clock: %i", in, out, instruction, clock); + DEBUG("out: %8.8x, instruction: %i, clock: %i", out, instruction, clock); #endif return ERROR_OK; diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c index a3ef8dea..7a409b0f 100644 --- a/src/target/arm7_9_common.c +++ b/src/target/arm7_9_common.c @@ -55,6 +55,7 @@ int handle_arm7_9_dbgrq_command(struct command_context_s *cmd_ctx, char *cmd, ch int handle_arm7_9_fast_memory_access_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); int handle_arm7_9_dcc_downloads_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); int handle_arm7_9_etm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); +int handle_arm7_9_etb_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); int arm7_9_reinit_embeddedice(target_t *target) { @@ -892,7 +893,7 @@ int arm7_9_debug_entry(target_t *target) reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]; #ifdef _DEBUG_ARM7_9_ - DEBUG(""); + DEBUG("-"); #endif if (arm7_9->pre_debug_entry) @@ -1042,7 +1043,7 @@ int arm7_9_full_context(target_t *target) armv4_5_common_t *armv4_5 = target->arch_info; arm7_9_common_t *arm7_9 = armv4_5->arch_info; - DEBUG(""); + DEBUG("-"); if (target->state != TARGET_HALTED) { @@ -1125,7 +1126,7 @@ int arm7_9_restore_context(target_t *target) int dirty; int mode_change; - DEBUG(""); + DEBUG("-"); if (target->state != TARGET_HALTED) { @@ -1326,7 +1327,7 @@ int arm7_9_resume(struct target_s *target, int current, u32 address, int handle_ breakpoint_t *breakpoint = target->breakpoints; reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]; - DEBUG(""); + DEBUG("-"); if (target->state != TARGET_HALTED) { @@ -2052,6 +2053,7 @@ int arm7_9_register_commands(struct command_context_s *cmd_ctx) arm7_9_cmd = register_command(cmd_ctx, NULL, "arm7_9", NULL, COMMAND_ANY, "arm7/9 specific commands"); register_command(cmd_ctx, arm7_9_cmd, "etm", handle_arm7_9_etm_command, COMMAND_CONFIG, NULL); + register_command(cmd_ctx, arm7_9_cmd, "etb", handle_arm7_9_etb_command, COMMAND_CONFIG, NULL); register_command(cmd_ctx, arm7_9_cmd, "write_xpsr", handle_arm7_9_write_xpsr_command, COMMAND_EXEC, "write program status register <value> <not cpsr|spsr>"); register_command(cmd_ctx, arm7_9_cmd, "write_xpsr_im8", handle_arm7_9_write_xpsr_im8_command, COMMAND_EXEC, "write program status register <8bit immediate> <rotate> <not cpsr|spsr>"); @@ -2410,6 +2412,50 @@ int handle_arm7_9_etm_command(struct command_context_s *cmd_ctx, char *cmd, char return ERROR_OK; } +int handle_arm7_9_etb_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +{ + target_t *target; + jtag_device_t *jtag_device; + armv4_5_common_t *armv4_5; + arm7_9_common_t *arm7_9; + + if (argc != 2) + { + ERROR("incomplete 'arm7_9 etb <target> <chain_pos>' command"); + exit(-1); + } + + target = get_target_by_num(strtoul(args[0], NULL, 0)); + + if (!target) + { + ERROR("target number '%s' not defined", args[0]); + exit(-1); + } + + if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK) + { + command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target"); + return ERROR_OK; + } + + jtag_device = jtag_get_device(strtoul(args[1], NULL, 0)); + + if (!jtag_device) + { + ERROR("jtag device number '%s' not defined", args[1]); + exit(-1); + } + + arm7_9->etb = malloc(sizeof(etb_t)); + + arm7_9->etb->chain_pos = strtoul(args[1], NULL, 0); + arm7_9->etb->cur_scan_chain = -1; + arm7_9->etb->reg_cache = NULL; + + return ERROR_OK; +} + int arm7_9_init_arch_info(target_t *target, arm7_9_common_t *arm7_9) { armv4_5_common_t *armv4_5 = &arm7_9->armv4_5_common; @@ -2424,6 +2470,7 @@ int arm7_9_init_arch_info(target_t *target, arm7_9_common_t *arm7_9) arm7_9->use_dbgrq = 0; arm7_9->has_etm = 0; + arm7_9->etb = NULL; arm7_9->has_single_step = 0; arm7_9->has_monitor_mode = 0; arm7_9->has_vector_catch = 0; diff --git a/src/target/arm7_9_common.h b/src/target/arm7_9_common.h index 25141a14..fd9a9e1b 100644 --- a/src/target/arm7_9_common.h +++ b/src/target/arm7_9_common.h @@ -25,6 +25,8 @@ #include "breakpoints.h" #include "target.h" +#include "etb.h" + #define ARM7_9_COMMON_MAGIC 0x0a790a79 typedef struct arm7_9_common_s @@ -47,6 +49,7 @@ typedef struct arm7_9_common_s int use_dbgrq; int has_etm; + etb_t *etb; int has_single_step; int has_monitor_mode; int has_vector_catch; diff --git a/src/target/arm7tdmi.c b/src/target/arm7tdmi.c index a87b8a4a..3fcfa296 100644 --- a/src/target/arm7tdmi.c +++ b/src/target/arm7tdmi.c @@ -669,7 +669,7 @@ void arm7tdmi_branch_resume(target_t *target) void arm7tdmi_branch_resume_thumb(target_t *target) { - DEBUG(""); + DEBUG("-"); /* get pointers to arch-specific information */ armv4_5_common_t *armv4_5 = target->arch_info; diff --git a/src/target/arm966e.c b/src/target/arm966e.c index 4573844a..d4b6cf47 100644 --- a/src/target/arm966e.c +++ b/src/target/arm966e.c @@ -85,11 +85,6 @@ target_type_t arm966e_target = int arm966e_assert_reset(target_t *target) { - armv4_5_common_t *armv4_5 = target->arch_info; - arm7_9_common_t *arm7_9 = armv4_5->arch_info; - arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info; - arm966e_common_t *arm966e = arm9tdmi->arch_info; - reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]; int retval; DEBUG("target->state: %s", target_state_strings[target->state]); @@ -154,12 +149,6 @@ int arm966e_assert_reset(target_t *target) int arm966e_deassert_reset(target_t *target) { - armv4_5_common_t *armv4_5 = target->arch_info; - arm7_9_common_t *arm7_9 = armv4_5->arch_info; - arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info; - arm966e_common_t *arm966e = arm9tdmi->arch_info; - reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]; - arm7_9_deassert_reset( target ); return ERROR_OK; diff --git a/src/target/arm9tdmi.c b/src/target/arm9tdmi.c index 434b5c99..e3302cf6 100644 --- a/src/target/arm9tdmi.c +++ b/src/target/arm9tdmi.c @@ -29,6 +29,7 @@ #include "armv4_5.h" #include "embeddedice.h" #include "etm.h" +#include "etb.h" #include "log.h" #include "jtag.h" #include "arm_jtag.h" @@ -723,7 +724,7 @@ void arm9tdmi_branch_resume(target_t *target) void arm9tdmi_branch_resume_thumb(target_t *target) { - DEBUG(""); + DEBUG("-"); /* get pointers to arch-specific information */ armv4_5_common_t *armv4_5 = target->arch_info; @@ -787,7 +788,6 @@ void arm9tdmi_enable_single_step(target_t *target) /* get pointers to arch-specific information */ armv4_5_common_t *armv4_5 = target->arch_info; arm7_9_common_t *arm7_9 = armv4_5->arch_info; - arm9tdmi_common_t *arm9 = arm7_9->arch_info; if (arm7_9->has_single_step) { @@ -805,7 +805,6 @@ void arm9tdmi_disable_single_step(target_t *target) /* get pointers to arch-specific information */ armv4_5_common_t *armv4_5 = target->arch_info; arm7_9_common_t *arm7_9 = armv4_5->arch_info; - arm9tdmi_common_t *arm9 = arm7_9->arch_info; if (arm7_9->has_single_step) { @@ -838,6 +837,12 @@ void arm9tdmi_build_reg_cache(target_t *target) (*cache_p)->next->next = etm_build_reg_cache(target, jtag_info, 0); arm7_9->etm_cache = (*cache_p)->next->next; } + + if (arm7_9->etb) + { + (*cache_p)->next->next->next = etb_build_reg_cache(arm7_9->etb); + arm7_9->etb->reg_cache = (*cache_p)->next->next->next; + } } int arm9tdmi_init_target(struct command_context_s *cmd_ctx, struct target_s *target) diff --git a/src/target/arm_disassembler.c b/src/target/arm_disassembler.c index 8a048cfc..f9e0227a 100644 --- a/src/target/arm_disassembler.c +++ b/src/target/arm_disassembler.c @@ -682,7 +682,7 @@ int evaluate_mul_and_extra_ld_st(u32 opcode, u32 address, arm_instruction_t *ins /* Multiply (accumulate) long */ if ((opcode & 0x0f800000) == 0x00800000) { - char* mnemonic; + char* mnemonic = NULL; u8 Rm, Rs, RdHi, RdLow, S; Rm = opcode & 0xf; Rs = (opcode & 0xf00) >> 8; @@ -841,7 +841,7 @@ int evaluate_misc_instr(u32 opcode, u32 address, arm_instruction_t *instruction) if ((opcode & 0x0000000f0) == 0x00000050) { u8 Rm, Rd, Rn; - char *mnemonic; + char *mnemonic = NULL; Rm = opcode & 0xf; Rd = (opcode & 0xf000) >> 12; Rn = (opcode & 0xf0000) >> 16; @@ -967,7 +967,7 @@ int evaluate_misc_instr(u32 opcode, u32 address, arm_instruction_t *instruction) int evaluate_data_proc(u32 opcode, u32 address, arm_instruction_t *instruction) { u8 I, op, S, Rn, Rd; - char *mnemonic; + char *mnemonic = NULL; char shifter_operand[32]; I = (opcode & 0x02000000) >> 25; diff --git a/src/target/etb.c b/src/target/etb.c new file mode 100644 index 00000000..3ac1adf4 --- /dev/null +++ b/src/target/etb.c @@ -0,0 +1,319 @@ +/*************************************************************************** + * Copyright (C) 2005 by Dominic Rath * + * Dominic.Rath@gmx.de * + * * + * 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. * + * * + * 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. * + ***************************************************************************/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "etb.h" + +#include "log.h" +#include "types.h" +#include "binarybuffer.h" +#include "target.h" +#include "register.h" +#include "jtag.h" + +#include <stdlib.h> + +char* etb_reg_list[] = +{ + "ETB_identification", + "ETB_ram_depth", + "ETB_ram_width", + "ETB_status", + "ETB_ram_data", + "ETB_ram_read_pointer", + "ETB_ram_write_pointer", + "ETB_trigger_counter", + "ETB_control", +}; + +int etb_reg_arch_type = -1; + +int etb_get_reg(reg_t *reg); +int etb_set_reg(reg_t *reg, u32 value); +int etb_set_reg_w_exec(reg_t *reg, u8 *buf); + +int etb_write_reg(reg_t *reg, u32 value); +int etb_read_reg(reg_t *reg); + +int etb_set_instr(etb_t *etb, u32 new_instr) +{ + jtag_device_t *device = jtag_get_device(etb->chain_pos); + + if (buf_get_u32(device->cur_instr, 0, device->ir_length) != new_instr) + { + scan_field_t field; + + field.device = etb->chain_pos; + field.num_bits = device->ir_length; + field.out_value = calloc(CEIL(field.num_bits, 8), 1); + buf_set_u32(field.out_value, 0, field.num_bits, new_instr); + field.out_mask = NULL; + field.in_value = NULL; + field.in_check_value = NULL; + field.in_check_mask = NULL; + field.in_handler = NULL; + field.in_handler_priv = NULL; + + jtag_add_ir_scan(1, &field, -1); + + free(field.out_value); + } + + return ERROR_OK; +} + +int etb_scann(etb_t *etb, u32 new_scan_chain) +{ + if(etb->cur_scan_chain != new_scan_chain) + { + scan_field_t field; + + field.device = etb->chain_pos; + field.num_bits = 5; + field.out_value = calloc(CEIL(field.num_bits, 8), 1); + buf_set_u32(field.out_value, 0, field.num_bits, new_scan_chain); + field.out_mask = NULL; + field.in_value = NULL; + field.in_check_value = NULL; + field.in_check_mask = NULL; + field.in_handler = NULL; + field.in_handler_priv = NULL; + + /* select INTEST instruction */ + etb_set_instr(etb, 0x2); + jtag_add_dr_scan(1, &field, -1); + + etb->cur_scan_chain = new_scan_chain; + + free(field.out_value); + } + + return ERROR_OK; +} + +reg_cache_t* etb_build_reg_cache(etb_t *etb) +{ + reg_cache_t *reg_cache = malloc(sizeof(reg_cache_t)); + reg_t *reg_list = NULL; + etb_reg_t *arch_info = NULL; + int num_regs = 9; + int i; + + /* register a register arch-type for etm registers only once */ + if (etb_reg_arch_type == -1) + etb_reg_arch_type = register_reg_arch_type(etb_get_reg, etb_set_reg_w_exec); + + /* the actual registers are kept in two arrays */ + reg_list = calloc(num_regs, sizeof(reg_t)); + arch_info = calloc(num_regs, sizeof(etb_reg_t)); + + /* fill in values for the reg cache */ + reg_cache->name = "etb registers"; + reg_cache->next = NULL; + reg_cache->reg_list = reg_list; + reg_cache->num_regs = num_regs; + + /* set up registers */ + for (i = 0; i < num_regs; i++) + { + reg_list[i].name = etb_reg_list[i]; + reg_list[i].size = 32; + reg_list[i].dirty = 0; + reg_list[i].valid = 0; + reg_list[i].bitfield_desc = NULL; + reg_list[i].num_bitfields = 0; + reg_list[i].value = calloc(1, 4); + reg_list[i].arch_info = &arch_info[i]; + reg_list[i].arch_type = etb_reg_arch_type; + reg_list[i].size = 32; + arch_info[i].addr = i; + arch_info[i].etb = etb; + } + + return reg_cache; +} + +int etb_get_reg(reg_t *reg) +{ + if (etb_read_reg(reg) != ERROR_OK) + { + ERROR("BUG: error scheduling etm register read"); + exit(-1); + } + + if (jtag_execute_queue() != ERROR_OK) + { + ERROR("register read failed"); + } + + return ERROR_OK; +} + +int etb_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask) +{ + etb_reg_t *etb_reg = reg->arch_info; + u8 reg_addr = etb_reg->addr & 0x7f; + scan_field_t fields[3]; + + DEBUG("%i", etb_reg->addr); + + jtag_add_end_state(TAP_RTI); + etb_scann(etb_reg->etb, 0x0); + etb_set_instr(etb_reg->etb, 0xc); + + fields[0].device = etb_reg->etb->chain_pos; + fields[0].num_bits = 32; + fields[0].out_value = reg->value; + fields[0].out_mask = NULL; + fields[0].in_value = NULL; + fields[0].in_check_value = NULL; + fields[0].in_check_mask = NULL; + fields[0].in_handler = NULL; + fields[0].in_handler_priv = NULL; + + fields[1].device = etb_reg->etb->chain_pos; + fields[1].num_bits = 7; + fields[1].out_value = malloc(1); + buf_set_u32(fields[1].out_value, 0, 7, reg_addr); + fields[1].out_mask = NULL; + fields[1].in_value = NULL; + fields[1].in_check_value = NULL; + fields[1].in_check_mask = NULL; + fields[1].in_handler = NULL; + fields[1].in_handler_priv = NULL; + + fields[2].device = etb_reg->etb->chain_pos; + fields[2].num_bits = 1; + fields[2].out_value = malloc(1); + buf_set_u32(fields[2].out_value, 0, 1, 0); + fields[2].out_mask = NULL; + fields[2].in_value = NULL; + fields[2].in_check_value = NULL; + fields[2].in_check_mask = NULL; + fields[2].in_handler = NULL; + fields[2].in_handler_priv = NULL; + + jtag_add_dr_scan(3, fields, -1); + + fields[0].in_value = reg->value; + fields[0].in_check_value = check_value; + fields[0].in_check_mask = check_mask; + + jtag_add_dr_scan(3, fields, -1); + + free(fields[1].out_value); + free(fields[2].out_value); + + return ERROR_OK; +} + +int etb_read_reg(reg_t *reg) +{ + return etb_read_reg_w_check(reg, NULL, NULL); +} + +int etb_set_reg(reg_t *reg, u32 value) +{ + if (etb_write_reg(reg, value) != ERROR_OK) + { + ERROR("BUG: error scheduling etm register write"); + exit(-1); + } + + buf_set_u32(reg->value, 0, reg->size, value); + reg->valid = 1; + reg->dirty = 0; + + return ERROR_OK; +} + +int etb_set_reg_w_exec(reg_t *reg, u8 *buf) +{ + etb_set_reg(reg, buf_get_u32(buf, 0, reg->size)); + + if (jtag_execute_queue() != ERROR_OK) + { + ERROR("register write failed"); + exit(-1); + } + return ERROR_OK; +} + +int etb_write_reg(reg_t *reg, u32 value) +{ + etb_reg_t *etb_reg = reg->arch_info; + u8 reg_addr = etb_reg->addr & 0x7f; + scan_field_t fields[3]; + + DEBUG("%i: 0x%8.8x", etb_reg->addr, value); + + jtag_add_end_state(TAP_RTI); + etb_scann(etb_reg->etb, 0x0); + etb_set_instr(etb_reg->etb, 0xc); + + fields[0].device = etb_reg->etb->chain_pos; + fields[0].num_bits = 32; + fields[0].out_value = malloc(4); + buf_set_u32(fields[0].out_value, 0, 32, value); + fields[0].out_mask = NULL; + fields[0].in_value = NULL; + fields[0].in_check_value = NULL; + fields[0].in_check_mask = NULL; + fields[0].in_handler = NULL; + fields[0].in_handler_priv = NULL; + + fields[1].device = etb_reg->etb->chain_pos; + fields[1].num_bits = 7; + fields[1].out_value = malloc(1); + buf_set_u32(fields[1].out_value, 0, 7, reg_addr); + fields[1].out_mask = NULL; + fields[1].in_value = NULL; + fields[1].in_check_value = NULL; + fields[1].in_check_mask = NULL; + fields[1].in_handler = NULL; + fields[1].in_handler_priv = NULL; + + fields[2].device = etb_reg->etb->chain_pos; + fields[2].num_bits = 1; + fields[2].out_value = malloc(1); + buf_set_u32(fields[2].out_value, 0, 1, 1); + fields[2].out_mask = NULL; + fields[2].in_value = NULL; + fields[2].in_check_value = NULL; + fields[2].in_check_mask = NULL; + fields[2].in_handler = NULL; + fields[2].in_handler_priv = NULL; + + jtag_add_dr_scan(3, fields, -1); + + free(fields[0].out_value); + free(fields[1].out_value); + free(fields[2].out_value); + + return ERROR_OK; +} + +int etb_store_reg(reg_t *reg) +{ + return etb_write_reg(reg, buf_get_u32(reg->value, 0, reg->size)); +} + diff --git a/src/target/etb.h b/src/target/etb.h new file mode 100644 index 00000000..55b7857b --- /dev/null +++ b/src/target/etb.h @@ -0,0 +1,62 @@ +/***************************************************************************
+ * Copyright (C) 2007 by Dominic Rath *
+ * Dominic.Rath@gmx.de *
+ * *
+ * 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. *
+ * *
+ * 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. *
+ ***************************************************************************/
+#ifndef ETB_H
+#define ETB_H
+
+#include "target.h"
+#include "register.h"
+#include "arm_jtag.h"
+
+/* ETB registers */
+enum
+{
+ ETB_ID = 0x00,
+ ETB_RAM_DEPTH = 0x01,
+ ETB_RAM_WIDTH = 0x02,
+ ETB_STATUS = 0x03,
+ ETB_RAM_DATA = 0x04,
+ ETB_RAM_READ_POINTER = 0x05,
+ ETB_RAM_WRITE_POINTER = 0x06,
+ ETB_TRIGGER_COUNTER = 0x07,
+ ETB_CTRL = 0x08,
+};
+
+typedef struct etb_s
+{
+ int chain_pos;
+ int cur_scan_chain;
+ reg_cache_t *reg_cache;
+} etb_t;
+
+typedef struct etb_reg_s
+{
+ int addr;
+ etb_t *etb;
+} etb_reg_t;
+
+extern reg_cache_t* etb_build_reg_cache(etb_t *etb);
+extern int etb_read_reg(reg_t *reg);
+extern int etb_write_reg(reg_t *reg, u32 value);
+extern int etb_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask);
+extern int etb_store_reg(reg_t *reg);
+extern int etb_set_reg(reg_t *reg, u32 value);
+extern int etb_set_reg_w_exec(reg_t *reg, u8 *buf);
+
+#endif /* ETB_H */
diff --git a/src/target/target.c b/src/target/target.c index 40205642..376fc52f 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -1087,7 +1087,7 @@ int handle_reg_command(struct command_context_s *cmd_ctx, char *cmd, char **args int count = 0; char *value; - DEBUG(""); + DEBUG("-"); target = get_current_target(cmd_ctx); @@ -1279,7 +1279,7 @@ int handle_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **arg int retval; target_t *target = get_current_target(cmd_ctx); - DEBUG(""); + DEBUG("-"); command_print(cmd_ctx, "requesting target halt..."); @@ -1353,7 +1353,7 @@ int handle_reset_command(struct command_context_s *cmd_ctx, char *cmd, char **ar target_t *target = get_current_target(cmd_ctx); enum target_reset_mode reset_mode = RESET_RUN; - DEBUG(""); + DEBUG("-"); if (argc >= 1) { @@ -1397,7 +1397,7 @@ int handle_resume_command(struct command_context_s *cmd_ctx, char *cmd, char **a int retval; target_t *target = get_current_target(cmd_ctx); - DEBUG(""); + DEBUG("-"); if (argc == 0) retval = target->type->resume(target, 1, 0, 1, 0); /* current pc, addr = 0, handle breakpoints, not debugging */ @@ -1429,7 +1429,7 @@ int handle_step_command(struct command_context_s *cmd_ctx, char *cmd, char **arg { target_t *target = get_current_target(cmd_ctx); - DEBUG(""); + DEBUG("-"); if (argc == 0) target->type->step(target, 1, 0, 1); /* current pc, addr = 0, handle breakpoints */ |