7ed41c63c37bcb1cc8270c0050e009a1e3f3b3e4
[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 void mem_ap_deinit_target(struct target *target)
69 {
70         LOG_DEBUG("%s", __func__);
71
72         free(target->private_config);
73         free(target->arch_info);
74         return;
75 }
76
77 static int mem_ap_arch_state(struct target *target)
78 {
79         LOG_DEBUG("%s", __func__);
80         return ERROR_OK;
81 }
82
83 static int mem_ap_poll(struct target *target)
84 {
85         if (target->state == TARGET_UNKNOWN)
86                 target->state = TARGET_RUNNING;
87
88         return ERROR_OK;
89 }
90
91 static int mem_ap_halt(struct target *target)
92 {
93         LOG_DEBUG("%s", __func__);
94         target->state = TARGET_HALTED;
95         return ERROR_OK;
96 }
97
98 static int mem_ap_resume(struct target *target, int current, target_addr_t address,
99                 int handle_breakpoints, int debug_execution)
100 {
101         LOG_DEBUG("%s", __func__);
102         target->state = TARGET_RUNNING;
103         return ERROR_OK;
104 }
105
106 static int mem_ap_step(struct target *target, int current, target_addr_t address,
107                                 int handle_breakpoints)
108 {
109         LOG_DEBUG("%s", __func__);
110         target->state = TARGET_HALTED;
111         return ERROR_OK;
112 }
113
114 static int mem_ap_assert_reset(struct target *target)
115 {
116         target->state = TARGET_RESET;
117
118         LOG_DEBUG("%s", __func__);
119         return ERROR_OK;
120 }
121
122 static int mem_ap_examine(struct target *target)
123 {
124         struct mem_ap *mem_ap = target->arch_info;
125
126         if (!target_was_examined(target)) {
127                 mem_ap->ap = dap_ap(mem_ap->arm.dap, mem_ap->ap_num);
128                 target_set_examined(target);
129                 target->state = TARGET_UNKNOWN;
130                 return mem_ap_init(mem_ap->ap);
131         }
132
133         return ERROR_OK;
134 }
135
136 static int mem_ap_deassert_reset(struct target *target)
137 {
138         if (target->reset_halt)
139                 target->state = TARGET_HALTED;
140         else
141                 target->state = TARGET_RUNNING;
142
143         LOG_DEBUG("%s", __func__);
144         return ERROR_OK;
145 }
146
147 static int mem_ap_read_memory(struct target *target, target_addr_t address,
148                                uint32_t size, uint32_t count, uint8_t *buffer)
149 {
150         struct mem_ap *mem_ap = target->arch_info;
151
152         LOG_DEBUG("Reading memory at physical address " TARGET_ADDR_FMT
153                   "; size %" PRIu32 "; count %" PRIu32, address, size, count);
154
155         if (count == 0 || buffer == NULL)
156                 return ERROR_COMMAND_SYNTAX_ERROR;
157
158         return mem_ap_read_buf(mem_ap->ap, buffer, size, count, address);
159 }
160
161 static int mem_ap_write_memory(struct target *target, target_addr_t address,
162                                 uint32_t size, uint32_t count,
163                                 const uint8_t *buffer)
164 {
165         struct mem_ap *mem_ap = target->arch_info;
166
167         LOG_DEBUG("Writing memory at physical address " TARGET_ADDR_FMT
168                   "; size %" PRIu32 "; count %" PRIu32, address, size, count);
169
170         if (count == 0 || buffer == NULL)
171                 return ERROR_COMMAND_SYNTAX_ERROR;
172
173         return mem_ap_write_buf(mem_ap->ap, buffer, size, count, address);
174 }
175
176 struct target_type mem_ap_target = {
177         .name = "mem_ap",
178
179         .target_create = mem_ap_target_create,
180         .init_target = mem_ap_init_target,
181         .deinit_target = mem_ap_deinit_target,
182         .examine = mem_ap_examine,
183         .target_jim_configure = adiv5_jim_configure,
184
185         .poll = mem_ap_poll,
186         .arch_state = mem_ap_arch_state,
187
188         .halt = mem_ap_halt,
189         .resume = mem_ap_resume,
190         .step = mem_ap_step,
191
192         .assert_reset = mem_ap_assert_reset,
193         .deassert_reset = mem_ap_deassert_reset,
194
195         .read_memory = mem_ap_read_memory,
196         .write_memory = mem_ap_write_memory,
197 };