3a2d4b7c52ca833a105d5c59d51f904b860bd431
[openocd.git] / src / target / mem_ap.c
1 /*****************************************************************************
2 * Copyright (C) 2016 by Matthias Welwarsky <matthias.welwarsky@sysgo.com> *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 ****************************************************************************/
14
15 #ifdef HAVE_CONFIG_H
16 #include "config.h"
17 #endif
18
19 #include "target.h"
20 #include "target_type.h"
21 #include "arm.h"
22 #include "arm_adi_v5.h"
23
24 #include <jtag/jtag.h>
25
26 struct mem_ap {
27 struct arm arm;
28 struct adiv5_ap *ap;
29 int ap_num;
30 };
31
32 static int mem_ap_target_create(struct target *target, Jim_Interp *interp)
33 {
34 struct mem_ap *mem_ap = calloc(1, sizeof(struct mem_ap));
35 struct adiv5_private_config *pc;
36
37 pc = (struct adiv5_private_config *)target->private_config;
38 if (pc == NULL)
39 return ERROR_FAIL;
40
41 if (pc->ap_num == DP_APSEL_INVALID) {
42 LOG_ERROR("AP number not specified");
43 return ERROR_FAIL;
44 }
45
46 mem_ap->ap_num = pc->ap_num;
47 mem_ap->arm.common_magic = ARM_COMMON_MAGIC;
48 mem_ap->arm.dap = pc->dap;
49
50 target->arch_info = mem_ap;
51
52 return ERROR_OK;
53 }
54
55 static int mem_ap_init_target(struct command_context *cmd_ctx, struct target *target)
56 {
57 LOG_DEBUG("%s", __func__);
58 target->state = TARGET_UNKNOWN;
59 return ERROR_OK;
60 }
61
62 static int mem_ap_arch_state(struct target *target)
63 {
64 LOG_DEBUG("%s", __func__);
65 return ERROR_OK;
66 }
67
68 static int mem_ap_poll(struct target *target)
69 {
70 if (target->state == TARGET_UNKNOWN)
71 target->state = TARGET_RUNNING;
72
73 return ERROR_OK;
74 }
75
76 static int mem_ap_halt(struct target *target)
77 {
78 LOG_DEBUG("%s", __func__);
79 target->state = TARGET_HALTED;
80 return ERROR_OK;
81 }
82
83 static int mem_ap_resume(struct target *target, int current, target_addr_t address,
84 int handle_breakpoints, int debug_execution)
85 {
86 LOG_DEBUG("%s", __func__);
87 target->state = TARGET_RUNNING;
88 return ERROR_OK;
89 }
90
91 static int mem_ap_step(struct target *target, int current, target_addr_t address,
92 int handle_breakpoints)
93 {
94 LOG_DEBUG("%s", __func__);
95 target->state = TARGET_HALTED;
96 return ERROR_OK;
97 }
98
99 static int mem_ap_assert_reset(struct target *target)
100 {
101 target->state = TARGET_RESET;
102
103 LOG_DEBUG("%s", __func__);
104 return ERROR_OK;
105 }
106
107 static int mem_ap_examine(struct target *target)
108 {
109 struct mem_ap *mem_ap = target->arch_info;
110
111 if (!target_was_examined(target)) {
112 mem_ap->ap = dap_ap(mem_ap->arm.dap, mem_ap->ap_num);
113 target_set_examined(target);
114 target->state = TARGET_UNKNOWN;
115 return mem_ap_init(mem_ap->ap);
116 }
117
118 return ERROR_OK;
119 }
120
121 static int mem_ap_deassert_reset(struct target *target)
122 {
123 if (target->reset_halt)
124 target->state = TARGET_HALTED;
125 else
126 target->state = TARGET_RUNNING;
127
128 LOG_DEBUG("%s", __func__);
129 return ERROR_OK;
130 }
131
132 static int mem_ap_read_memory(struct target *target, target_addr_t address,
133 uint32_t size, uint32_t count, uint8_t *buffer)
134 {
135 struct mem_ap *mem_ap = target->arch_info;
136
137 LOG_DEBUG("Reading memory at physical address 0x" TARGET_ADDR_FMT
138 "; size %" PRId32 "; count %" PRId32, address, size, count);
139
140 if (count == 0 || buffer == NULL)
141 return ERROR_COMMAND_SYNTAX_ERROR;
142
143 return mem_ap_read_buf(mem_ap->ap, buffer, size, count, address);
144 }
145
146 static int mem_ap_write_memory(struct target *target, target_addr_t address,
147 uint32_t size, uint32_t count,
148 const uint8_t *buffer)
149 {
150 struct mem_ap *mem_ap = target->arch_info;
151
152 LOG_DEBUG("Writing memory at physical address 0x" TARGET_ADDR_FMT
153 "; size %" PRId32 "; count %" PRId32, address, size, count);
154
155 if (count == 0 || buffer == NULL)
156 return ERROR_COMMAND_SYNTAX_ERROR;
157
158 return mem_ap_write_buf(mem_ap->ap, buffer, size, count, address);
159 }
160
161 struct target_type mem_ap_target = {
162 .name = "mem_ap",
163
164 .target_create = mem_ap_target_create,
165 .init_target = mem_ap_init_target,
166 .examine = mem_ap_examine,
167 .target_jim_configure = adiv5_jim_configure,
168
169 .poll = mem_ap_poll,
170 .arch_state = mem_ap_arch_state,
171
172 .halt = mem_ap_halt,
173 .resume = mem_ap_resume,
174 .step = mem_ap_step,
175
176 .assert_reset = mem_ap_assert_reset,
177 .deassert_reset = mem_ap_deassert_reset,
178
179 .read_memory = mem_ap_read_memory,
180 .write_memory = mem_ap_write_memory,
181 };