arm_adi_v5: enhance command error reporting
[fw/openocd] / 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;
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 = calloc(1, sizeof(struct mem_ap));
47         if (mem_ap == NULL) {
48                 LOG_ERROR("Out of memory");
49                 return ERROR_FAIL;
50         }
51
52         mem_ap->ap_num = pc->ap_num;
53         mem_ap->arm.common_magic = ARM_COMMON_MAGIC;
54         mem_ap->arm.dap = pc->dap;
55
56         target->arch_info = mem_ap;
57
58         return ERROR_OK;
59 }
60
61 static int mem_ap_init_target(struct command_context *cmd_ctx, struct target *target)
62 {
63         LOG_DEBUG("%s", __func__);
64         target->state = TARGET_UNKNOWN;
65         return ERROR_OK;
66 }
67
68 static int mem_ap_arch_state(struct target *target)
69 {
70         LOG_DEBUG("%s", __func__);
71         return ERROR_OK;
72 }
73
74 static int mem_ap_poll(struct target *target)
75 {
76         if (target->state == TARGET_UNKNOWN)
77                 target->state = TARGET_RUNNING;
78
79         return ERROR_OK;
80 }
81
82 static int mem_ap_halt(struct target *target)
83 {
84         LOG_DEBUG("%s", __func__);
85         target->state = TARGET_HALTED;
86         return ERROR_OK;
87 }
88
89 static int mem_ap_resume(struct target *target, int current, target_addr_t address,
90                 int handle_breakpoints, int debug_execution)
91 {
92         LOG_DEBUG("%s", __func__);
93         target->state = TARGET_RUNNING;
94         return ERROR_OK;
95 }
96
97 static int mem_ap_step(struct target *target, int current, target_addr_t address,
98                                 int handle_breakpoints)
99 {
100         LOG_DEBUG("%s", __func__);
101         target->state = TARGET_HALTED;
102         return ERROR_OK;
103 }
104
105 static int mem_ap_assert_reset(struct target *target)
106 {
107         target->state = TARGET_RESET;
108
109         LOG_DEBUG("%s", __func__);
110         return ERROR_OK;
111 }
112
113 static int mem_ap_examine(struct target *target)
114 {
115         struct mem_ap *mem_ap = target->arch_info;
116
117         if (!target_was_examined(target)) {
118                 mem_ap->ap = dap_ap(mem_ap->arm.dap, mem_ap->ap_num);
119                 target_set_examined(target);
120                 target->state = TARGET_UNKNOWN;
121                 return mem_ap_init(mem_ap->ap);
122         }
123
124         return ERROR_OK;
125 }
126
127 static int mem_ap_deassert_reset(struct target *target)
128 {
129         if (target->reset_halt)
130                 target->state = TARGET_HALTED;
131         else
132                 target->state = TARGET_RUNNING;
133
134         LOG_DEBUG("%s", __func__);
135         return ERROR_OK;
136 }
137
138 static int mem_ap_read_memory(struct target *target, target_addr_t address,
139                                uint32_t size, uint32_t count, uint8_t *buffer)
140 {
141         struct mem_ap *mem_ap = target->arch_info;
142
143         LOG_DEBUG("Reading memory at physical address " TARGET_ADDR_FMT
144                   "; size %" PRId32 "; count %" PRId32, address, size, count);
145
146         if (count == 0 || buffer == NULL)
147                 return ERROR_COMMAND_SYNTAX_ERROR;
148
149         return mem_ap_read_buf(mem_ap->ap, buffer, size, count, address);
150 }
151
152 static int mem_ap_write_memory(struct target *target, target_addr_t address,
153                                 uint32_t size, uint32_t count,
154                                 const uint8_t *buffer)
155 {
156         struct mem_ap *mem_ap = target->arch_info;
157
158         LOG_DEBUG("Writing memory at physical address " TARGET_ADDR_FMT
159                   "; size %" PRId32 "; count %" PRId32, address, size, count);
160
161         if (count == 0 || buffer == NULL)
162                 return ERROR_COMMAND_SYNTAX_ERROR;
163
164         return mem_ap_write_buf(mem_ap->ap, buffer, size, count, address);
165 }
166
167 struct target_type mem_ap_target = {
168         .name = "mem_ap",
169
170         .target_create = mem_ap_target_create,
171         .init_target = mem_ap_init_target,
172         .examine = mem_ap_examine,
173         .target_jim_configure = adiv5_jim_configure,
174
175         .poll = mem_ap_poll,
176         .arch_state = mem_ap_arch_state,
177
178         .halt = mem_ap_halt,
179         .resume = mem_ap_resume,
180         .step = mem_ap_step,
181
182         .assert_reset = mem_ap_assert_reset,
183         .deassert_reset = mem_ap_deassert_reset,
184
185         .read_memory = mem_ap_read_memory,
186         .write_memory = mem_ap_write_memory,
187 };