0e2f14e76d1afa7ed14f17d9b20c5e56b19d963b
[fw/openocd] / src / target / ls1_sap.c
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2
3 /*
4  * Copyright (C) 2015 by Esben Haabendal <eha@deif.com>
5  */
6
7 #ifdef HAVE_CONFIG_H
8 #include "config.h"
9 #endif
10
11 #include "target.h"
12 #include "target_type.h"
13
14 #include <jtag/jtag.h>
15
16 struct ls1_sap {
17         struct jtag_tap *tap;
18 };
19
20 static int ls1_sap_target_create(struct target *target, Jim_Interp *interp)
21 {
22         struct ls1_sap *ls1_sap = calloc(1, sizeof(struct ls1_sap));
23
24         ls1_sap->tap = target->tap;
25         target->arch_info = ls1_sap;
26
27         return ERROR_OK;
28 }
29
30 static int ls1_sap_init_target(struct command_context *cmd_ctx, struct target *target)
31 {
32         LOG_DEBUG("%s", __func__);
33         return ERROR_OK;
34 }
35
36 static int ls1_sap_arch_state(struct target *target)
37 {
38         LOG_DEBUG("%s", __func__);
39         return ERROR_OK;
40 }
41
42 static int ls1_sap_poll(struct target *target)
43 {
44         if ((target->state == TARGET_UNKNOWN) ||
45             (target->state == TARGET_RUNNING) ||
46             (target->state == TARGET_DEBUG_RUNNING))
47                 target->state = TARGET_HALTED;
48
49         return ERROR_OK;
50 }
51
52 static int ls1_sap_halt(struct target *target)
53 {
54         LOG_DEBUG("%s", __func__);
55         return ERROR_OK;
56 }
57
58 static int ls1_sap_resume(struct target *target, int current, target_addr_t address,
59                 int handle_breakpoints, int debug_execution)
60 {
61         LOG_DEBUG("%s", __func__);
62         return ERROR_OK;
63 }
64
65 static int ls1_sap_step(struct target *target, int current, target_addr_t address,
66                                 int handle_breakpoints)
67 {
68         LOG_DEBUG("%s", __func__);
69         return ERROR_OK;
70 }
71
72 static int ls1_sap_assert_reset(struct target *target)
73 {
74         target->state = TARGET_RESET;
75
76         LOG_DEBUG("%s", __func__);
77         return ERROR_OK;
78 }
79
80 static int ls1_sap_deassert_reset(struct target *target)
81 {
82         target->state = TARGET_RUNNING;
83
84         LOG_DEBUG("%s", __func__);
85         return ERROR_OK;
86 }
87
88 static void ls1_sap_set_instr(struct jtag_tap *tap, uint32_t new_instr)
89 {
90         struct scan_field field;
91
92         if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) == new_instr)
93                 return;
94
95         field.num_bits = tap->ir_length;
96         uint8_t *t = calloc(DIV_ROUND_UP(field.num_bits, 8), 1);
97         field.out_value = t;
98         buf_set_u32(t, 0, field.num_bits, new_instr);
99         field.in_value = NULL;
100         jtag_add_ir_scan(tap, &field, TAP_IDLE);
101         free(t);
102 }
103
104 static void ls1_sap_set_addr_high(struct jtag_tap *tap, uint16_t addr_high)
105 {
106         struct scan_field field;
107         uint8_t buf[2] = { 0 };
108
109         ls1_sap_set_instr(tap, 0x21);
110
111         field.num_bits = 16;
112         field.out_value = buf;
113         buf_set_u32(buf, 0, 16, addr_high);
114         field.in_value = NULL;
115         field.check_value = NULL;
116         field.check_mask = NULL;
117         jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
118 }
119
120 static void ls1_sap_memory_cmd(struct jtag_tap *tap, uint32_t address,
121                                int32_t size, bool rnw)
122 {
123         struct scan_field field;
124         uint8_t cmd[8] = { 0 };
125
126         ls1_sap_set_instr(tap, 0x24);
127
128         field.num_bits = 64;
129         field.out_value = cmd;
130         buf_set_u64(cmd, 0, 9, 0);
131         buf_set_u64(cmd, 9, 3, size);
132         buf_set_u64(cmd, 12, 1, rnw);
133         buf_set_u64(cmd, 13, 3, 0);
134         buf_set_u64(cmd, 16, 32, address);
135         buf_set_u64(cmd, 48, 16, 0);
136         field.in_value = NULL;
137         field.check_value = NULL;
138         field.check_mask = NULL;
139         jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
140 }
141
142 static void ls1_sap_memory_read(struct jtag_tap *tap, uint32_t size,
143                                 uint8_t *value)
144 {
145         struct scan_field field;
146
147         ls1_sap_set_instr(tap, 0x25);
148
149         field.num_bits = 8 * size;
150         field.out_value = NULL;
151         field.in_value = value;
152         field.check_value = NULL;
153         field.check_mask = NULL;
154         jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
155 }
156
157 static void ls1_sap_memory_write(struct jtag_tap *tap, uint32_t size,
158                                  const uint8_t *value)
159 {
160         struct scan_field field;
161
162         ls1_sap_set_instr(tap, 0x25);
163
164         field.num_bits = 8 * size;
165         field.out_value = value;
166         field.in_value = NULL;
167         field.check_value = NULL;
168         field.check_mask = NULL;
169         jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
170 }
171
172 static int ls1_sap_read_memory(struct target *target, target_addr_t address,
173                                uint32_t size, uint32_t count, uint8_t *buffer)
174 {
175         LOG_DEBUG("Reading memory at physical address 0x%" TARGET_PRIxADDR
176                   "; size %" PRIu32 "; count %" PRIu32, address, size, count);
177
178         if (count == 0 || !buffer)
179                 return ERROR_COMMAND_SYNTAX_ERROR;
180
181         ls1_sap_set_addr_high(target->tap, 0);
182
183         while (count--) {
184                 ls1_sap_memory_cmd(target->tap, address, size, true);
185                 ls1_sap_memory_read(target->tap, size, buffer);
186                 address += size;
187                 buffer += size;
188         }
189
190         return jtag_execute_queue();
191 }
192
193 static int ls1_sap_write_memory(struct target *target, target_addr_t address,
194                                 uint32_t size, uint32_t count,
195                                 const uint8_t *buffer)
196 {
197         LOG_DEBUG("Writing memory at physical address 0x%" TARGET_PRIxADDR
198                   "; size %" PRIu32 "; count %" PRIu32, address, size, count);
199
200
201         if (count == 0 || !buffer)
202                 return ERROR_COMMAND_SYNTAX_ERROR;
203
204         ls1_sap_set_addr_high(target->tap, 0);
205
206         while (count--) {
207                 ls1_sap_memory_cmd(target->tap, address, size, false);
208                 ls1_sap_memory_write(target->tap, size, buffer);
209                 address += size;
210                 buffer += size;
211         }
212
213         return jtag_execute_queue();
214 }
215
216 struct target_type ls1_sap_target = {
217         .name = "ls1_sap",
218
219         .target_create = ls1_sap_target_create,
220         .init_target = ls1_sap_init_target,
221
222         .poll = ls1_sap_poll,
223         .arch_state = ls1_sap_arch_state,
224
225         .halt = ls1_sap_halt,
226         .resume = ls1_sap_resume,
227         .step = ls1_sap_step,
228
229         .assert_reset = ls1_sap_assert_reset,
230         .deassert_reset = ls1_sap_deassert_reset,
231
232         .read_memory = ls1_sap_read_memory,
233         .write_memory = ls1_sap_write_memory,
234 };