target: rtt: include rtt.h
[openocd.git] / src / pld / gatemate.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 /***************************************************************************
4 * Copyright (C) 2022 by Daniel Anselmi *
5 * danselmi@gmx.ch *
6 ***************************************************************************/
7
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
11
12 #include <jtag/jtag.h>
13 #include <jtag/adapter.h>
14 #include "pld.h"
15 #include "raw_bit.h"
16
17 #define JTAG_CONFIGURE 0x06
18
19 struct gatemate_pld_device {
20 struct jtag_tap *tap;
21 };
22
23 struct gatemate_bit_file {
24 struct raw_bit_file raw_file;
25 size_t capacity;
26 };
27
28 static int gatemate_add_byte_to_bitfile(struct gatemate_bit_file *bit_file, uint8_t byte)
29 {
30 const size_t chunk_size = 8192;
31 if (bit_file->raw_file.length + 1 > bit_file->capacity) {
32 uint8_t *buffer;
33 if (bit_file->raw_file.data)
34 buffer = realloc(bit_file->raw_file.data, bit_file->capacity + chunk_size);
35 else
36 buffer = malloc(chunk_size);
37 if (!buffer) {
38 LOG_ERROR("Out of memory");
39 return ERROR_FAIL;
40 }
41 bit_file->raw_file.data = buffer;
42 bit_file->capacity += chunk_size;
43 }
44
45 bit_file->raw_file.data[bit_file->raw_file.length++] = byte;
46
47 return ERROR_OK;
48 }
49
50 static int gatemate_read_cfg_line(struct gatemate_bit_file *bit_file, const char *line_buffer, size_t nread)
51 {
52 for (size_t idx = 0; idx < nread; ++idx) {
53 if (line_buffer[idx] == ' ') {
54 continue;
55 } else if (line_buffer[idx] == 0) {
56 break;
57 } else if (idx + 1 < nread) {
58 if (isxdigit(line_buffer[idx]) && isxdigit(line_buffer[idx + 1])) {
59 uint8_t byte;
60 unhexify(&byte, line_buffer + idx, 2);
61 int retval = gatemate_add_byte_to_bitfile(bit_file, byte);
62 if (retval != ERROR_OK)
63 return retval;
64 } else if (line_buffer[idx] == '/' && line_buffer[idx + 1] == '/') {
65 break;
66 }
67 ++idx;
68 } else {
69 LOG_ERROR("parsing failed");
70 return ERROR_FAIL;
71 }
72 }
73 return ERROR_OK;
74 }
75
76 static int gatemate_getline(char **buffer, size_t *buf_size, FILE *input_file)
77 {
78 const size_t chunk_size = 32;
79 if (!*buffer)
80 *buf_size = 0;
81
82 size_t read = 0;
83 do {
84 if (read + 1 > *buf_size) {
85 char *new_buffer;
86 if (*buffer)
87 new_buffer = realloc(*buffer, *buf_size + chunk_size);
88 else
89 new_buffer = malloc(chunk_size);
90 if (!new_buffer) {
91 LOG_ERROR("Out of memory");
92 return -1;
93 }
94 *buffer = new_buffer;
95 *buf_size += chunk_size;
96 }
97
98 int c = fgetc(input_file);
99 if ((c == EOF && read) || (char)c == '\n') {
100 (*buffer)[read++] = 0;
101 return read;
102 } else if (c == EOF) {
103 return -1;
104 }
105
106 (*buffer)[read++] = (char)c;
107 } while (1);
108
109 return -1;
110 }
111
112 static int gatemate_read_cfg_file(struct gatemate_bit_file *bit_file, const char *filename)
113 {
114 FILE *input_file = fopen(filename, "r");
115
116 if (!input_file) {
117 LOG_ERROR("Couldn't open %s: %s", filename, strerror(errno));
118 return ERROR_PLD_FILE_LOAD_FAILED;
119 }
120
121 int retval = ERROR_OK;
122 char *line_buffer = NULL;
123 size_t buffer_length = 0;
124 int nread;
125 while (((nread = gatemate_getline(&line_buffer, &buffer_length, input_file)) != -1) && (retval == ERROR_OK))
126 retval = gatemate_read_cfg_line(bit_file, line_buffer, (size_t)nread);
127
128 if (line_buffer)
129 free(line_buffer);
130
131 fclose(input_file);
132 if (retval != ERROR_OK)
133 free(bit_file->raw_file.data);
134 return retval;
135 }
136
137 static int gatemate_read_file(struct gatemate_bit_file *bit_file, const char *filename)
138 {
139 memset(bit_file, 0, sizeof(struct gatemate_bit_file));
140
141 if (!filename || !bit_file)
142 return ERROR_COMMAND_SYNTAX_ERROR;
143
144 /* check if binary .bit or ascii .cfg */
145 const char *file_suffix_pos = strrchr(filename, '.');
146 if (!file_suffix_pos) {
147 LOG_ERROR("Unable to detect filename suffix");
148 return ERROR_PLD_FILE_LOAD_FAILED;
149 }
150
151 if (strcasecmp(file_suffix_pos, ".bit") == 0)
152 return cpld_read_raw_bit_file(&bit_file->raw_file, filename);
153 else if (strcasecmp(file_suffix_pos, ".cfg") == 0)
154 return gatemate_read_cfg_file(bit_file, filename);
155
156 LOG_ERROR("Filetype not supported, expecting .bit or .cfg file");
157 return ERROR_PLD_FILE_LOAD_FAILED;
158 }
159
160 static int gatemate_set_instr(struct jtag_tap *tap, uint8_t new_instr)
161 {
162 struct scan_field field;
163 field.num_bits = tap->ir_length;
164 void *t = calloc(DIV_ROUND_UP(field.num_bits, 8), 1);
165 if (!t) {
166 LOG_ERROR("Out of memory");
167 return ERROR_FAIL;
168 }
169 field.out_value = t;
170 buf_set_u32(t, 0, field.num_bits, new_instr);
171 field.in_value = NULL;
172 jtag_add_ir_scan(tap, &field, TAP_IDLE);
173 jtag_add_runtest(3, TAP_IDLE);
174 free(t);
175 return ERROR_OK;
176 }
177
178 static int gatemate_load(struct pld_device *pld_device, const char *filename)
179 {
180 if (!pld_device)
181 return ERROR_FAIL;
182
183 struct gatemate_pld_device *gatemate_info = pld_device->driver_priv;
184
185 if (!gatemate_info || !gatemate_info->tap)
186 return ERROR_FAIL;
187 struct jtag_tap *tap = gatemate_info->tap;
188
189 struct gatemate_bit_file bit_file;
190 int retval = gatemate_read_file(&bit_file, filename);
191 if (retval != ERROR_OK)
192 return retval;
193
194 retval = gatemate_set_instr(tap, JTAG_CONFIGURE);
195 if (retval != ERROR_OK)
196 return retval;
197
198 struct scan_field field;
199 field.num_bits = bit_file.raw_file.length * 8;
200 field.out_value = bit_file.raw_file.data;
201 field.in_value = NULL;
202 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
203
204 retval = jtag_execute_queue();
205 free(bit_file.raw_file.data);
206
207 return retval;
208 }
209
210 PLD_DEVICE_COMMAND_HANDLER(gatemate_pld_device_command)
211 {
212 struct jtag_tap *tap;
213
214 struct gatemate_pld_device *gatemate_info;
215
216 if (CMD_ARGC != 2)
217 return ERROR_COMMAND_SYNTAX_ERROR;
218
219 tap = jtag_tap_by_string(CMD_ARGV[1]);
220 if (!tap) {
221 command_print(CMD, "Tap: %s does not exist", CMD_ARGV[1]);
222 return ERROR_FAIL;
223 }
224
225 gatemate_info = malloc(sizeof(struct gatemate_pld_device));
226 if (!gatemate_info) {
227 LOG_ERROR("Out of memory");
228 return ERROR_FAIL;
229 }
230 gatemate_info->tap = tap;
231
232 pld->driver_priv = gatemate_info;
233
234 return ERROR_OK;
235 }
236
237 struct pld_driver gatemate_pld = {
238 .name = "gatemate",
239 .pld_device_command = &gatemate_pld_device_command,
240 .load = &gatemate_load,
241 };

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)