+static int target_get_gdb_fileio_info_default(struct target *target,
+ struct gdb_fileio_info *fileio_info)
+{
+ /* If target does not support semi-hosting function, target
+ has no need to provide .get_gdb_fileio_info callback.
+ It just return ERROR_FAIL and gdb_server will return "Txx"
+ as target halted every time. */
+ return ERROR_FAIL;
+}
+
+static int target_gdb_fileio_end_default(struct target *target,
+ int retcode, int fileio_errno, bool ctrl_c)
+{
+ return ERROR_OK;
+}
+
+static int target_profiling_default(struct target *target, uint32_t *samples,
+ uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds)
+{
+ struct timeval timeout, now;
+
+ gettimeofday(&timeout, NULL);
+ timeval_add_time(&timeout, seconds, 0);
+
+ LOG_INFO("Starting profiling. Halting and resuming the"
+ " target as often as we can...");
+
+ uint32_t sample_count = 0;
+ /* hopefully it is safe to cache! We want to stop/restart as quickly as possible. */
+ struct reg *reg = register_get_by_name(target->reg_cache, "pc", 1);
+
+ int retval = ERROR_OK;
+ for (;;) {
+ target_poll(target);
+ if (target->state == TARGET_HALTED) {
+ uint32_t t = *((uint32_t *)reg->value);
+ samples[sample_count++] = t;
+ /* current pc, addr = 0, do not handle breakpoints, not debugging */
+ retval = target_resume(target, 1, 0, 0, 0);
+ target_poll(target);
+ alive_sleep(10); /* sleep 10ms, i.e. <100 samples/second. */
+ } else if (target->state == TARGET_RUNNING) {
+ /* We want to quickly sample the PC. */
+ retval = target_halt(target);
+ } else {
+ LOG_INFO("Target not halted or running");
+ retval = ERROR_OK;
+ break;
+ }
+
+ if (retval != ERROR_OK)
+ break;
+
+ gettimeofday(&now, NULL);
+ if ((sample_count >= max_num_samples) ||
+ ((now.tv_sec >= timeout.tv_sec) && (now.tv_usec >= timeout.tv_usec))) {
+ LOG_INFO("Profiling completed. %d samples.", sample_count);
+ break;
+ }
+ }
+
+ *num_samples = sample_count;
+ return retval;
+}
+