X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Ftarget.c;h=942dbc1c38c1020fcbeee10fa4e1a5c75466fd0d;hp=b038519732d92c9b63761351c9dfda719728bbc9;hb=1c975fe30b8fb380907133462cc38a0b2e9de565;hpb=2803fa3822d4aaa4803b103a035fe98782a8adc9 diff --git a/src/target/target.c b/src/target/target.c index b038519732..942dbc1c38 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -87,7 +87,7 @@ extern struct target_type fa526_target; extern struct target_type feroceon_target; extern struct target_type dragonite_target; extern struct target_type xscale_target; -extern struct target_type cortexm3_target; +extern struct target_type cortexm_target; extern struct target_type cortexa8_target; extern struct target_type cortexr4_target; extern struct target_type arm11_target; @@ -101,6 +101,7 @@ extern struct target_type hla_target; extern struct target_type nds32_v2_target; extern struct target_type nds32_v3_target; extern struct target_type nds32_v3m_target; +extern struct target_type or1k_target; static struct target_type *target_types[] = { &arm7tdmi_target, @@ -114,7 +115,7 @@ static struct target_type *target_types[] = { &feroceon_target, &dragonite_target, &xscale_target, - &cortexm3_target, + &cortexm_target, &cortexa8_target, &cortexr4_target, &arm11_target, @@ -128,6 +129,7 @@ static struct target_type *target_types[] = { &nds32_v2_target, &nds32_v3_target, &nds32_v3m_target, + &or1k_target, NULL, }; @@ -2031,12 +2033,13 @@ int target_read_u16(struct target *target, uint32_t address, uint16_t *value) int target_read_u8(struct target *target, uint32_t address, uint8_t *value) { - int retval = target_read_memory(target, address, 1, 1, value); if (!target_was_examined(target)) { LOG_ERROR("Target not examined yet"); return ERROR_FAIL; } + int retval = target_read_memory(target, address, 1, 1, value); + if (retval == ERROR_OK) { LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%2.2x", address, @@ -2744,12 +2747,6 @@ COMMAND_HANDLER(handle_md_command) typedef int (*target_write_fn)(struct target *target, uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer); -static int target_write_memory_fast(struct target *target, - uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer) -{ - return target_write_buffer(target, address, size * count, buffer); -} - static int target_fill_mem(struct target *target, uint32_t address, target_write_fn fn, @@ -2814,7 +2811,7 @@ COMMAND_HANDLER(handle_mw_command) CMD_ARGV++; fn = target_write_phys_memory; } else - fn = target_write_memory_fast; + fn = target_write_memory; if ((CMD_ARGC < 2) || (CMD_ARGC > 3)) return ERROR_COMMAND_SYNTAX_ERROR; @@ -3426,8 +3423,11 @@ static void writeString(FILE *f, char *s) writeData(f, s, strlen(s)); } +typedef unsigned char UNIT[2]; /* unit of profiling */ + /* Dump a gmon.out histogram file. */ -static void write_gmon(uint32_t *samples, uint32_t sampleNum, const char *filename) +static void write_gmon(uint32_t *samples, uint32_t sampleNum, const char *filename, + bool with_range, uint32_t start_address, uint32_t end_address) { uint32_t i; FILE *f = fopen(filename, "w"); @@ -3443,18 +3443,25 @@ static void write_gmon(uint32_t *samples, uint32_t sampleNum, const char *filena writeData(f, &zero, 1); /* figure out bucket size */ - uint32_t min = samples[0]; - uint32_t max = samples[0]; - for (i = 0; i < sampleNum; i++) { - if (min > samples[i]) - min = samples[i]; - if (max < samples[i]) - max = samples[i]; - } + uint32_t min; + uint32_t max; + if (with_range) { + min = start_address; + max = end_address; + } else { + min = samples[0]; + max = samples[0]; + for (i = 0; i < sampleNum; i++) { + if (min > samples[i]) + min = samples[i]; + if (max < samples[i]) + max = samples[i]; + } - /* max should be (largest sample + 1) - * Refer to binutils/gprof/hist.c (find_histogram_for_pc) */ - max++; + /* max should be (largest sample + 1) + * Refer to binutils/gprof/hist.c (find_histogram_for_pc) */ + max++; + } int addressSpace = max - min; assert(addressSpace >= 2); @@ -3462,7 +3469,7 @@ static void write_gmon(uint32_t *samples, uint32_t sampleNum, const char *filena /* FIXME: What is the reasonable number of buckets? * The profiling result will be more accurate if there are enough buckets. */ static const uint32_t maxBuckets = 128 * 1024; /* maximum buckets. */ - uint32_t numBuckets = addressSpace; + uint32_t numBuckets = addressSpace / sizeof(UNIT); if (numBuckets > maxBuckets) numBuckets = maxBuckets; int *buckets = malloc(sizeof(int) * numBuckets); @@ -3473,6 +3480,10 @@ static void write_gmon(uint32_t *samples, uint32_t sampleNum, const char *filena memset(buckets, 0, sizeof(int) * numBuckets); for (i = 0; i < sampleNum; i++) { uint32_t address = samples[i]; + + if ((address < min) || (max <= address)) + continue; + long long a = address - min; long long b = numBuckets; long long c = addressSpace; @@ -3517,7 +3528,7 @@ COMMAND_HANDLER(handle_profile_command) { struct target *target = get_current_target(CMD_CTX); - if (CMD_ARGC != 2) + if ((CMD_ARGC != 2) && (CMD_ARGC != 4)) return ERROR_COMMAND_SYNTAX_ERROR; const uint32_t MAX_PROFILE_SAMPLE_NUM = 10000; @@ -3565,7 +3576,17 @@ COMMAND_HANDLER(handle_profile_command) return retval; } - write_gmon(samples, num_of_sampels, CMD_ARGV[1]); + uint32_t start_address = 0; + uint32_t end_address = 0; + bool with_range = false; + if (CMD_ARGC == 4) { + with_range = true; + COMMAND_PARSE_NUMBER(uint, CMD_ARGV[2], start_address); + COMMAND_PARSE_NUMBER(uint, CMD_ARGV[3], end_address); + } + + write_gmon(samples, num_of_sampels, CMD_ARGV[1], + with_range, start_address, end_address); command_print(CMD_CTX, "Wrote %s", CMD_ARGV[1]); free(samples); @@ -4351,7 +4372,7 @@ static int jim_target_mw(Jim_Interp *interp, int argc, Jim_Obj *const *argv) } target_write_fn fn; - fn = target_write_memory_fast; + fn = target_write_memory; int e; if (strcmp(Jim_GetString(argv[1], NULL), "phys") == 0) { @@ -5563,7 +5584,7 @@ static const struct command_registration target_exec_command_handlers[] = { .name = "profile", .handler = handle_profile_command, .mode = COMMAND_EXEC, - .usage = "seconds filename", + .usage = "seconds filename [start end]", .help = "profiling samples the CPU PC", }, /** @todo don't register virt2phys() unless target supports it */