OpenOCD
npcx.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /*
4  * Copyright (C) 2020 by Nuvoton Technology Corporation
5  * Mulin Chao <mlchao@nuvoton.com>
6  * Wealian Liao <WHLIAO@nuvoton.com>
7  */
8 
9 #ifdef HAVE_CONFIG_H
10 #include "config.h"
11 #endif
12 
13 #include "imp.h"
14 #include <helper/binarybuffer.h>
15 #include <helper/time_support.h>
16 #include <target/armv7m.h>
17 #include "../../../contrib/loaders/flash/npcx/npcx_flash.h"
18 
19 /* NPCX flash loader */
20 static const uint8_t npcx_algo[] = {
21 #include "../../../contrib/loaders/flash/npcx/npcx_algo.inc"
22 };
23 
24 #define NPCX_FLASH_TIMEOUT_MS 8000
25 #define NPCX_FLASH_BASE_ADDR 0x64000000
26 
27 /* flash list */
33 };
34 
36  const char *family_name;
37  uint32_t sector_length;
38  bool probed;
42  const uint8_t *algo_code;
43  uint32_t algo_size;
45  uint32_t buffer_addr;
46  uint32_t params_addr;
47 };
48 
50  char *name;
51  uint32_t id;
52  uint32_t size;
53 };
54 
55 static const struct npcx_flash_info flash_info[] = {
56  [NPCX_FLASH_256KB] = {
57  .name = "256KB Flash",
58  .id = 0xEF4012,
59  .size = 256 * 1024,
60  },
61  [NPCX_FLASH_512KB] = {
62  .name = "512KB Flash",
63  .id = 0xEF4013,
64  .size = 512 * 1024,
65  },
66  [NPCX_FLASH_1MB] = {
67  .name = "1MB Flash",
68  .id = 0xEF4014,
69  .size = 1024 * 1024,
70  },
71  [NPCX_FLASH_UNKNOWN] = {
72  .name = "Unknown Flash",
73  .size = 0xFFFFFFFF,
74  },
75 };
76 
77 static int npcx_init(struct flash_bank *bank)
78 {
79  struct target *target = bank->target;
80  struct npcx_flash_bank *npcx_bank = bank->driver_priv;
81 
82  /* Check for working area to use for flash helper algorithm */
84  npcx_bank->working_area = NULL;
85 
86  int retval = target_alloc_working_area(target, npcx_bank->algo_working_size,
87  &npcx_bank->working_area);
88  if (retval != ERROR_OK)
89  return retval;
90 
91  /* Confirm the defined working address is the area we need to use */
92  if (npcx_bank->working_area->address != NPCX_FLASH_LOADER_WORKING_ADDR) {
93  LOG_ERROR("%s: Invalid working address", npcx_bank->family_name);
94  LOG_INFO("Hint: Use '-work-area-phys 0x%" PRIx32 "' in your target configuration",
95  NPCX_FLASH_LOADER_WORKING_ADDR);
97  npcx_bank->working_area = NULL;
99  }
100 
101  /* Write flash helper algorithm into target memory */
102  retval = target_write_buffer(target, NPCX_FLASH_LOADER_PROGRAM_ADDR,
103  npcx_bank->algo_size, npcx_bank->algo_code);
104  if (retval != ERROR_OK) {
105  LOG_ERROR("%s: Failed to load flash helper algorithm",
106  npcx_bank->family_name);
108  npcx_bank->working_area = NULL;
109  return retval;
110  }
111 
112  /* Initialize the ARMv7 specific info to run the algorithm */
115 
116  /* Begin executing the flash helper algorithm */
117  retval = target_start_algorithm(target, 0, NULL, 0, NULL,
118  NPCX_FLASH_LOADER_PROGRAM_ADDR, 0,
119  &npcx_bank->armv7m_info);
120  if (retval != ERROR_OK) {
121  LOG_ERROR("%s: Failed to start flash helper algorithm",
122  npcx_bank->family_name);
124  npcx_bank->working_area = NULL;
125  return retval;
126  }
127 
128  /*
129  * At this point, the algorithm is running on the target and
130  * ready to receive commands and data to flash the target
131  */
132 
133  return retval;
134 }
135 
136 static int npcx_quit(struct flash_bank *bank)
137 {
138  struct target *target = bank->target;
139  struct npcx_flash_bank *npcx_bank = bank->driver_priv;
140 
141  /* Regardless of the algo's status, attempt to halt the target */
142  (void)target_halt(target);
143 
144  /* Now confirm target halted and clean up from flash helper algorithm */
145  int retval = target_wait_algorithm(target, 0, NULL, 0, NULL, 0,
146  NPCX_FLASH_TIMEOUT_MS, &npcx_bank->armv7m_info);
147 
149  npcx_bank->working_area = NULL;
150 
151  return retval;
152 }
153 
154 static int npcx_wait_algo_done(struct flash_bank *bank, uint32_t params_addr)
155 {
156  struct target *target = bank->target;
157  struct npcx_flash_bank *npcx_bank = bank->driver_priv;
158  uint32_t status_addr = params_addr + offsetof(struct npcx_flash_params, sync);
159  uint32_t status;
160  int64_t start_ms = timeval_ms();
161 
162  do {
163  int retval = target_read_u32(target, status_addr, &status);
164  if (retval != ERROR_OK)
165  return retval;
166 
167  keep_alive();
168 
169  int64_t elapsed_ms = timeval_ms() - start_ms;
170  if (elapsed_ms > NPCX_FLASH_TIMEOUT_MS)
171  break;
172  } while (status == NPCX_FLASH_LOADER_EXECUTE);
173 
174  if (status != NPCX_FLASH_LOADER_WAIT) {
175  LOG_ERROR("%s: Flash operation failed, status=0x%" PRIx32,
176  npcx_bank->family_name,
177  status);
178  return ERROR_FAIL;
179  }
180 
181  return ERROR_OK;
182 }
183 
184 static enum npcx_flash_device_index npcx_get_flash_id(struct flash_bank *bank, uint32_t *flash_id)
185 {
186  struct target *target = bank->target;
187  struct npcx_flash_bank *npcx_bank = bank->driver_priv;
188  struct npcx_flash_params algo_params;
189 
190  if (target->state != TARGET_HALTED) {
191  LOG_ERROR("Target not halted");
193  }
194 
195  int retval = npcx_init(bank);
196  if (retval != ERROR_OK)
197  return retval;
198 
199  /* Set up algorithm parameters for get flash ID command */
200  target_buffer_set_u32(target, (uint8_t *)&algo_params.cmd, NPCX_FLASH_CMD_GET_FLASH_ID);
201  target_buffer_set_u32(target, (uint8_t *)&algo_params.sync, NPCX_FLASH_LOADER_WAIT);
202 
203  /* Issue flash helper algorithm parameters for get flash ID */
204  retval = target_write_buffer(target, npcx_bank->params_addr,
205  sizeof(algo_params), (uint8_t *)&algo_params);
206  if (retval != ERROR_OK) {
207  (void)npcx_quit(bank);
208  return retval;
209  }
210 
211  target_buffer_set_u32(target, (uint8_t *)&algo_params.sync, NPCX_FLASH_LOADER_EXECUTE);
212  retval = target_write_buffer(target, npcx_bank->params_addr,
213  sizeof(algo_params), (uint8_t *)&algo_params);
214 
215  /* If no error, wait for finishing */
216  if (retval == ERROR_OK) {
217  retval = npcx_wait_algo_done(bank, npcx_bank->params_addr);
218  if (retval == ERROR_OK)
219  target_read_u32(target, NPCX_FLASH_LOADER_BUFFER_ADDR, flash_id);
220  }
221 
222  /* Regardless of errors, try to close down algo */
223  (void)npcx_quit(bank);
224 
225  return retval;
226 }
227 
228 static int npcx_get_flash(uint32_t flash_id)
229 {
230  for (uint32_t i = 0; i < ARRAY_SIZE(flash_info) - 1; i++) {
231  if (flash_info[i].id == flash_id)
232  return i;
233  }
234 
235  return NPCX_FLASH_UNKNOWN;
236 }
237 
238 static int npcx_probe(struct flash_bank *bank)
239 {
240  struct npcx_flash_bank *npcx_bank = bank->driver_priv;
241  uint32_t sector_length = NPCX_FLASH_ERASE_SIZE;
242  uint32_t flash_id;
243 
244  /* Set up appropriate flash helper algorithm */
245  npcx_bank->algo_code = npcx_algo;
246  npcx_bank->algo_size = sizeof(npcx_algo);
247  npcx_bank->algo_working_size = NPCX_FLASH_LOADER_PARAMS_SIZE +
248  NPCX_FLASH_LOADER_BUFFER_SIZE +
249  NPCX_FLASH_LOADER_PROGRAM_SIZE;
250  npcx_bank->buffer_addr = NPCX_FLASH_LOADER_BUFFER_ADDR;
251  npcx_bank->params_addr = NPCX_FLASH_LOADER_PARAMS_ADDR;
252 
253  int retval = npcx_get_flash_id(bank, &flash_id);
254  if (retval != ERROR_OK)
255  return retval;
256 
257  npcx_bank->flash = npcx_get_flash(flash_id);
258 
259  unsigned int num_sectors = flash_info[npcx_bank->flash].size / sector_length;
260 
261  bank->sectors = calloc(num_sectors, sizeof(struct flash_sector));
262  if (!bank->sectors) {
263  LOG_ERROR("Out of memory");
264  return ERROR_FAIL;
265  }
266 
267  bank->base = NPCX_FLASH_BASE_ADDR;
268  bank->num_sectors = num_sectors;
269  bank->size = num_sectors * sector_length;
270  bank->write_start_alignment = 0;
271  bank->write_end_alignment = 0;
272  npcx_bank->sector_length = sector_length;
273 
274  for (unsigned int i = 0; i < num_sectors; i++) {
275  bank->sectors[i].offset = i * sector_length;
276  bank->sectors[i].size = sector_length;
277  bank->sectors[i].is_erased = -1;
278  bank->sectors[i].is_protected = 0;
279  }
280 
281  /* We've successfully determined the stats on the flash bank */
282  npcx_bank->probed = true;
283 
284  /* If we fall through to here, then all went well */
285  return ERROR_OK;
286 }
287 
288 static int npcx_auto_probe(struct flash_bank *bank)
289 {
290  struct npcx_flash_bank *npcx_bank = bank->driver_priv;
291  int retval = ERROR_OK;
292 
293  if (!npcx_bank->probed)
294  retval = npcx_probe(bank);
295 
296  return retval;
297 }
298 
299 FLASH_BANK_COMMAND_HANDLER(npcx_flash_bank_command)
300 {
301  struct npcx_flash_bank *npcx_bank;
302 
303  if (CMD_ARGC < 6)
305 
306  npcx_bank = calloc(1, sizeof(struct npcx_flash_bank));
307  if (!npcx_bank) {
308  LOG_ERROR("Out of memory");
309  return ERROR_FAIL;
310  }
311 
312  /* Initialize private flash information */
313  npcx_bank->family_name = "npcx";
314  npcx_bank->sector_length = NPCX_FLASH_ERASE_SIZE;
315 
316  /* Finish initialization of bank */
317  bank->driver_priv = npcx_bank;
318  bank->next = NULL;
319 
320  return ERROR_OK;
321 }
322 
323 static int npcx_chip_erase(struct flash_bank *bank)
324 {
325  struct target *target = bank->target;
326  struct npcx_flash_bank *npcx_bank = bank->driver_priv;
327  struct npcx_flash_params algo_params;
328 
329  if (target->state != TARGET_HALTED) {
330  LOG_ERROR("Target not halted");
332  }
333 
334  /* Make sure we've probed the flash to get the device and size */
335  int retval = npcx_auto_probe(bank);
336  if (retval != ERROR_OK)
337  return retval;
338 
339  retval = npcx_init(bank);
340  if (retval != ERROR_OK)
341  return retval;
342 
343  /* Set up algorithm parameters for chip erase command */
344  target_buffer_set_u32(target, (uint8_t *)&algo_params.cmd, NPCX_FLASH_CMD_ERASE_ALL);
345  target_buffer_set_u32(target, (uint8_t *)&algo_params.sync, NPCX_FLASH_LOADER_WAIT);
346 
347  /* Set algorithm parameters */
348  retval = target_write_buffer(target, npcx_bank->params_addr,
349  sizeof(algo_params), (uint8_t *)&algo_params);
350  if (retval != ERROR_OK) {
351  (void)npcx_quit(bank);
352  return retval;
353  }
354 
355  /* Issue flash helper algorithm parameters for chip erase */
356  target_buffer_set_u32(target, (uint8_t *)&algo_params.sync, NPCX_FLASH_LOADER_EXECUTE);
357  retval = target_write_buffer(target, npcx_bank->params_addr,
358  sizeof(algo_params), (uint8_t *)&algo_params);
359 
360  /* If no error, wait for chip erase finish */
361  if (retval == ERROR_OK)
362  retval = npcx_wait_algo_done(bank, npcx_bank->params_addr);
363 
364  /* Regardless of errors, try to close down algo */
365  (void)npcx_quit(bank);
366 
367  return retval;
368 }
369 
370 static int npcx_erase(struct flash_bank *bank, unsigned int first,
371  unsigned int last)
372 {
373  struct target *target = bank->target;
374  struct npcx_flash_bank *npcx_bank = bank->driver_priv;
375  struct npcx_flash_params algo_params;
376 
377  if (target->state != TARGET_HALTED) {
378  LOG_ERROR("Target not halted");
380  }
381 
382  if ((first == 0) && (last == (bank->num_sectors - 1))) {
383  /* Request chip erase */
384  return npcx_chip_erase(bank);
385  }
386 
387  uint32_t address = first * npcx_bank->sector_length;
388  uint32_t length = (last - first + 1) * npcx_bank->sector_length;
389 
390  /* Make sure we've probed the flash to get the device and size */
391  int retval = npcx_auto_probe(bank);
392  if (retval != ERROR_OK)
393  return retval;
394 
395  retval = npcx_init(bank);
396  if (retval != ERROR_OK)
397  return retval;
398 
399  /* Set up algorithm parameters for erase command */
400  target_buffer_set_u32(target, (uint8_t *)&algo_params.addr, address);
401  target_buffer_set_u32(target, (uint8_t *)&algo_params.len, length);
402  target_buffer_set_u32(target, (uint8_t *)&algo_params.cmd, NPCX_FLASH_CMD_ERASE_SECTORS);
403  target_buffer_set_u32(target, (uint8_t *)&algo_params.sync, NPCX_FLASH_LOADER_WAIT);
404 
405  /* Set algorithm parameters */
406  retval = target_write_buffer(target, npcx_bank->params_addr,
407  sizeof(algo_params), (uint8_t *)&algo_params);
408  if (retval != ERROR_OK) {
409  (void)npcx_quit(bank);
410  return retval;
411  }
412 
413  /* Issue flash helper algorithm parameters for erase */
414  target_buffer_set_u32(target, (uint8_t *)&algo_params.sync, NPCX_FLASH_LOADER_EXECUTE);
415  retval = target_write_buffer(target, npcx_bank->params_addr,
416  sizeof(algo_params), (uint8_t *)&algo_params);
417 
418  /* If no error, wait for erase to finish */
419  if (retval == ERROR_OK)
420  retval = npcx_wait_algo_done(bank, npcx_bank->params_addr);
421 
422  /* Regardless of errors, try to close down algo */
423  (void)npcx_quit(bank);
424 
425  return retval;
426 }
427 
428 static int npcx_write(struct flash_bank *bank, const uint8_t *buffer,
429  uint32_t offset, uint32_t count)
430 {
431  struct target *target = bank->target;
432  struct npcx_flash_bank *npcx_bank = bank->driver_priv;
433  struct npcx_flash_params algo_params;
434 
435  if (target->state != TARGET_HALTED) {
436  LOG_ERROR("Target not halted");
438  }
439 
440  /* Make sure we've probed the flash to get the device and size */
441  int retval = npcx_auto_probe(bank);
442  if (retval != ERROR_OK)
443  return retval;
444 
445  retval = npcx_init(bank);
446  if (retval != ERROR_OK)
447  return retval;
448 
449  /* Initialize algorithm parameters to default values */
450  target_buffer_set_u32(target, (uint8_t *)&algo_params.cmd, NPCX_FLASH_CMD_PROGRAM);
451 
452  uint32_t address = offset;
453 
454  while (count > 0) {
455  uint32_t size = (count > NPCX_FLASH_LOADER_BUFFER_SIZE) ?
456  NPCX_FLASH_LOADER_BUFFER_SIZE : count;
457 
458  /* Put the data into buffer */
459  retval = target_write_buffer(target, npcx_bank->buffer_addr,
460  size, buffer);
461  if (retval != ERROR_OK) {
462  LOG_ERROR("Unable to write data to target memory");
463  break;
464  }
465 
466  /* Update algo parameters for flash write */
467  target_buffer_set_u32(target, (uint8_t *)&algo_params.addr, address);
468  target_buffer_set_u32(target, (uint8_t *)&algo_params.len, size);
469  target_buffer_set_u32(target, (uint8_t *)&algo_params.sync, NPCX_FLASH_LOADER_WAIT);
470 
471  /* Set algorithm parameters */
472  retval = target_write_buffer(target, npcx_bank->params_addr,
473  sizeof(algo_params), (uint8_t *)&algo_params);
474  if (retval != ERROR_OK)
475  break;
476 
477  /* Issue flash helper algorithm parameters for flash write */
478  target_buffer_set_u32(target, (uint8_t *)&algo_params.sync, NPCX_FLASH_LOADER_EXECUTE);
479  retval = target_write_buffer(target, npcx_bank->params_addr,
480  sizeof(algo_params), (uint8_t *)&algo_params);
481  if (retval != ERROR_OK)
482  break;
483 
484  /* Wait for flash write finish */
485  retval = npcx_wait_algo_done(bank, npcx_bank->params_addr);
486  if (retval != ERROR_OK)
487  break;
488 
489  count -= size;
490  buffer += size;
491  address += size;
492  }
493 
494  /* Regardless of errors, try to close down algo */
495  (void)npcx_quit(bank);
496 
497  return retval;
498 }
499 
500 static int npcx_info(struct flash_bank *bank, struct command_invocation *cmd)
501 {
502  struct npcx_flash_bank *npcx_bank = bank->driver_priv;
503 
504  command_print_sameline(cmd, "%s flash: %s\n",
505  npcx_bank->family_name,
506  flash_info[npcx_bank->flash].name);
507 
508  return ERROR_OK;
509 }
510 
511 const struct flash_driver npcx_flash = {
512  .name = "npcx",
513  .flash_bank_command = npcx_flash_bank_command,
514  .erase = npcx_erase,
515  .write = npcx_write,
516  .read = default_flash_read,
517  .probe = npcx_probe,
518  .auto_probe = npcx_auto_probe,
519  .erase_check = default_flash_blank_check,
520  .info = npcx_info,
521  .free_driver_priv = default_flash_free_driver_priv,
522 };
@ ARM_MODE_THREAD
Definition: arm.h:86
#define ARMV7M_COMMON_MAGIC
Definition: armv7m.h:218
Support functions to access arbitrary bits in a byte array.
void command_print_sameline(struct command_invocation *cmd, const char *format,...)
Definition: command.c:450
#define ERROR_COMMAND_SYNTAX_ERROR
Definition: command.h:385
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
Definition: command.h:150
uint8_t bank
Definition: esirisc.c:135
uint8_t length
Definition: esp_usb_jtag.c:1
int default_flash_blank_check(struct flash_bank *bank)
Provides default erased-bank check handling.
int default_flash_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
Provides default read implementation for flash memory.
void default_flash_free_driver_priv(struct flash_bank *bank)
Deallocates bank->driver_priv.
void keep_alive(void)
Definition: log.c:419
#define ERROR_FAIL
Definition: log.h:161
#define LOG_ERROR(expr ...)
Definition: log.h:123
#define LOG_INFO(expr ...)
Definition: log.h:117
#define ERROR_OK
Definition: log.h:155
#define NPCX_FLASH_TIMEOUT_MS
Definition: npcx.c:24
static int npcx_auto_probe(struct flash_bank *bank)
Definition: npcx.c:288
static const uint8_t npcx_algo[]
Definition: npcx.c:20
static enum npcx_flash_device_index npcx_get_flash_id(struct flash_bank *bank, uint32_t *flash_id)
Definition: npcx.c:184
static int npcx_info(struct flash_bank *bank, struct command_invocation *cmd)
Definition: npcx.c:500
#define NPCX_FLASH_BASE_ADDR
Definition: npcx.c:25
static int npcx_wait_algo_done(struct flash_bank *bank, uint32_t params_addr)
Definition: npcx.c:154
npcx_flash_device_index
Definition: npcx.c:28
@ NPCX_FLASH_256KB
Definition: npcx.c:29
@ NPCX_FLASH_UNKNOWN
Definition: npcx.c:32
@ NPCX_FLASH_512KB
Definition: npcx.c:30
@ NPCX_FLASH_1MB
Definition: npcx.c:31
static const struct npcx_flash_info flash_info[]
Definition: npcx.c:55
static int npcx_init(struct flash_bank *bank)
Definition: npcx.c:77
static int npcx_chip_erase(struct flash_bank *bank)
Definition: npcx.c:323
const struct flash_driver npcx_flash
Definition: npcx.c:511
FLASH_BANK_COMMAND_HANDLER(npcx_flash_bank_command)
Definition: npcx.c:299
static int npcx_quit(struct flash_bank *bank)
Definition: npcx.c:136
static int npcx_get_flash(uint32_t flash_id)
Definition: npcx.c:228
static int npcx_probe(struct flash_bank *bank)
Definition: npcx.c:238
static int npcx_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
Definition: npcx.c:428
static int npcx_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
Definition: npcx.c:370
size_t size
Size of the control block search area.
Definition: rtt/rtt.c:30
unsigned int common_magic
Definition: armv7m.h:293
enum arm_mode core_mode
Definition: armv7m.h:295
When run_command is called, a new instance will be created on the stack, filled with the proper value...
Definition: command.h:76
Provides details of a flash bank, available either on-chip or through a major interface.
Definition: nor/core.h:75
Provides the implementation-independent structure that defines all of the callbacks required by OpenO...
Definition: nor/driver.h:39
const char * name
Gives a human-readable name of this flash driver, This field is used to select and initialize the dri...
Definition: nor/driver.h:44
Describes the geometry and status of a single flash sector within a flash bank.
Definition: nor/core.h:28
uint32_t sector_length
Definition: npcx.c:37
uint32_t algo_size
Definition: npcx.c:43
uint32_t algo_working_size
Definition: npcx.c:44
struct armv7m_algorithm armv7m_info
Definition: npcx.c:41
uint32_t buffer_addr
Definition: npcx.c:45
const char * family_name
Definition: npcx.c:36
const uint8_t * algo_code
Definition: npcx.c:42
enum npcx_flash_device_index flash
Definition: npcx.c:39
bool probed
Definition: npcx.c:38
uint32_t params_addr
Definition: npcx.c:46
struct working_area * working_area
Definition: npcx.c:40
uint32_t id
Definition: npcx.c:51
char * name
Definition: npcx.c:50
uint32_t size
Definition: npcx.c:52
Definition: target.h:120
enum target_state state
Definition: target.h:162
target_addr_t address
Definition: target.h:90
int target_halt(struct target *target)
Definition: target.c:585
void target_buffer_set_u32(struct target *target, uint8_t *buffer, uint32_t value)
Definition: target.c:411
int target_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
Definition: target.c:2408
int target_wait_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, target_addr_t exit_point, int timeout_ms, void *arch_info)
Waits for an algorithm started with target_start_algorithm() to complete.
Definition: target.c:931
int target_alloc_working_area(struct target *target, uint32_t size, struct working_area **area)
Definition: target.c:2129
int target_free_working_area(struct target *target, struct working_area *area)
Free a working area.
Definition: target.c:2187
int target_read_u32(struct target *target, target_addr_t address, uint32_t *value)
Definition: target.c:2616
int target_start_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, target_addr_t entry_point, target_addr_t exit_point, void *arch_info)
Executes a target-specific native code algorithm and leaves it running.
Definition: target.c:887
#define ERROR_TARGET_NOT_HALTED
Definition: target.h:792
@ TARGET_HALTED
Definition: target.h:55
#define ERROR_TARGET_RESOURCE_NOT_AVAILABLE
Definition: target.h:796
int64_t timeval_ms(void)
#define ARRAY_SIZE(x)
Compute the number of elements of a variable length array.
Definition: types.h:57
#define NULL
Definition: usb.h:16
uint8_t status[4]
Definition: vdebug.c:17
uint8_t cmd
Definition: vdebug.c:1
uint8_t offset[4]
Definition: vdebug.c:9
uint8_t count[4]
Definition: vdebug.c:22