From ce38758e3df929d5b27947ab7b987cc319a628aa Mon Sep 17 00:00:00 2001 From: Paul Fertser Date: Tue, 26 Nov 2024 23:16:15 +0200 Subject: [PATCH 01/29] rtos: chibios: replace malloc+sprintf with alloc_printf This makes it safer and simpler at the same time. Signed-off-by: Paul Fertser Change-Id: Ie294f1f6033ffc9f46b39210e2f7fc2f648e80ac Reviewed-on: https://review.openocd.org/c/openocd/+/8598 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/rtos/chibios.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/rtos/chibios.c b/src/rtos/chibios.c index f4ee33a49..af590c2cb 100644 --- a/src/rtos/chibios.c +++ b/src/rtos/chibios.c @@ -421,9 +421,11 @@ static int chibios_update_threads(struct rtos *rtos) else state_desc = "Unknown"; - curr_thrd_details->extra_info_str = malloc(strlen( - state_desc)+8); - sprintf(curr_thrd_details->extra_info_str, "State: %s", state_desc); + curr_thrd_details->extra_info_str = alloc_printf("State: %s", state_desc); + if (!curr_thrd_details->extra_info_str) { + LOG_ERROR("Could not allocate space for thread state description"); + return -1; + } curr_thrd_details->exists = true; From eb6f2745b7d9924d0dddeab91c1743867c4e812c Mon Sep 17 00:00:00 2001 From: Sergey Matsievskiy Date: Wed, 18 Sep 2024 20:12:48 +0300 Subject: [PATCH 02/29] flash/nor: add DesignWare SPI controller driver Driver for DesignWare SPI controller, found on many SoCs (see compatible list in Linux device tree bindings Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml). This implementation only supports MIPS as it was the only one available for the tests, however, adding support for other architectures should require only few adjustments. Driver relies on flash/nor/spi.h to find Flash chip info. Driver internal functions support 24bit addressing mode, but due to limitations of flash/nor/spi.h, it is not used. The reported writing speed is about 60kb/s. Lint, sanitizer and valgrind reported warnings were not related to the driver. Change-Id: Id3df5626ab88055f034f74f274823051dedefeb1 Signed-off-by: Sergey Matsievskiy Reviewed-on: https://review.openocd.org/c/openocd/+/8400 Tested-by: jenkins Reviewed-by: Tomas Vanek --- contrib/loaders/flash/dw-spi/Makefile | 35 + contrib/loaders/flash/dw-spi/dw-spi.c | 246 +++ contrib/loaders/flash/dw-spi/dw-spi.h | 313 ++++ .../dw-spi/mipsel-linux-gnu-check_fill.inc | 39 + .../flash/dw-spi/mipsel-linux-gnu-erase.inc | 39 + .../flash/dw-spi/mipsel-linux-gnu-program.inc | 51 + .../flash/dw-spi/mipsel-linux-gnu-read.inc | 33 + .../dw-spi/mipsel-linux-gnu-transaction.inc | 21 + doc/openocd.texi | 69 + src/flash/nor/Makefile.am | 2 + src/flash/nor/driver.h | 1 + src/flash/nor/drivers.c | 1 + src/flash/nor/dw-spi-helper.h | 102 ++ src/flash/nor/dw-spi.c | 1608 +++++++++++++++++ 14 files changed, 2560 insertions(+) create mode 100644 contrib/loaders/flash/dw-spi/Makefile create mode 100644 contrib/loaders/flash/dw-spi/dw-spi.c create mode 100644 contrib/loaders/flash/dw-spi/dw-spi.h create mode 100644 contrib/loaders/flash/dw-spi/mipsel-linux-gnu-check_fill.inc create mode 100644 contrib/loaders/flash/dw-spi/mipsel-linux-gnu-erase.inc create mode 100644 contrib/loaders/flash/dw-spi/mipsel-linux-gnu-program.inc create mode 100644 contrib/loaders/flash/dw-spi/mipsel-linux-gnu-read.inc create mode 100644 contrib/loaders/flash/dw-spi/mipsel-linux-gnu-transaction.inc create mode 100644 src/flash/nor/dw-spi-helper.h create mode 100644 src/flash/nor/dw-spi.c diff --git a/contrib/loaders/flash/dw-spi/Makefile b/contrib/loaders/flash/dw-spi/Makefile new file mode 100644 index 000000000..e86827882 --- /dev/null +++ b/contrib/loaders/flash/dw-spi/Makefile @@ -0,0 +1,35 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +TOOLCHAIN:=mipsel-linux-gnu- +CC:=$(TOOLCHAIN)gcc +OBJCOPY:=$(TOOLCHAIN)objcopy +CFLAGS:=-O2 -Wall -Wextra -fpic -Wno-int-to-pointer-cast +SRC=dw-spi.c +OBJ=$(patsubst %.c, %.o,$(SRC)) + +# sparx-iv +ifeq ($(TOOLCHAIN),mipsel-linux-gnu-) + CFLAGS+= -march=24kec +endif + +all: \ + $(TOOLCHAIN)transaction.inc \ + $(TOOLCHAIN)erase.inc \ + $(TOOLCHAIN)check_fill.inc \ + $(TOOLCHAIN)program.inc \ + $(TOOLCHAIN)read.inc + +$(TOOLCHAIN)%.bin: $(OBJ) + $(OBJCOPY) --dump-section .$*=$@ $< + +%.inc: %.bin + xxd -i > $@ < $< + +.PHONY: clean +clean: + rm -rf .ccls-cache + find . \( \ + -iname "*.o" \ + -o -iname "*.bin" \ + -o -iname "*.inc" \ + \) -delete diff --git a/contrib/loaders/flash/dw-spi/dw-spi.c b/contrib/loaders/flash/dw-spi/dw-spi.c new file mode 100644 index 000000000..66b743913 --- /dev/null +++ b/contrib/loaders/flash/dw-spi/dw-spi.c @@ -0,0 +1,246 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/** + * @file + * Helper functions for DesignWare SPI Core driver. + * These helpers are loaded into CPU and execute Flash manipulation algorithms + * at full CPU speed. Due to inability to control nCS pin, this is the only way + * to communicate with Flash chips connected via DW SPI serial interface. + * + * In order to avoid using stack, all functions used in helpers are inlined. + * Software breakpoints are used to terminate helpers. + * + * Pushing byte to TX FIFO does not make byte immediately available in RX FIFO + * and nCS is only asserted when TX FIFO is not empty. General approach is to + * fill TX FIFO with as many bytes as possible, at the same time reading + * available bytes from RX FIFO. + * + * This file contains helper functions. + */ + +#include "dw-spi.h" + +#include "../../../../src/flash/nor/dw-spi-helper.h" + +/** + * @brief Generic flash transaction. + * + * @param[in] arg: Function arguments. + */ +__attribute__((section(".transaction"))) void +transaction(struct dw_spi_transaction *arg) +{ + register uint8_t *buffer_tx = (uint8_t *)arg->buffer; + register uint8_t *buffer_rx = buffer_tx; + register uint32_t size = arg->size; + register volatile uint8_t *status = (uint8_t *)arg->status_reg; + register volatile uint8_t *data = (uint8_t *)arg->data_reg; + + wait_tx_finish(status); + flush_rx(status, data); + + for (; size > 0; size--) { + send_u8(status, data, *buffer_tx++); + if (arg->read_flag && rx_available(status)) + *buffer_rx++ = rcv_byte(data); + } + + // Pushed all data to TX FIFO. Read bytes left in RX FIFO. + if (arg->read_flag) { + while (buffer_rx < buffer_tx) { + wait_rx_available(status); + *buffer_rx++ = rcv_byte(data); + } + } + + RETURN; +} + +/** + * @brief Check flash sectors are filled with pattern. Primary use for + * checking sector erase state. + * + * @param[in] arg: Function arguments. + */ +__attribute__((section(".check_fill"))) void +check_fill(struct dw_spi_check_fill *arg) +{ + register uint32_t tx_size; + register uint32_t rx_size; + register uint32_t dummy_count; + register uint8_t filled; + register uint8_t *fill_status_array = (uint8_t *)arg->fill_status_array; + register volatile uint8_t *status = (uint8_t *)arg->status_reg; + register volatile uint8_t *data = (uint8_t *)arg->data_reg; + + for (; arg->sector_count > 0; arg->sector_count--, + arg->address += arg->sector_size, + fill_status_array++) { + wait_tx_finish(status); + flush_rx(status, data); + + /* + * Command byte and address bytes make up for dummy_count number of + * bytes, that must be skipped in RX FIFO before actual data arrives. + */ + send_u8(status, data, arg->read_cmd); + if (arg->four_byte_mode) { + dummy_count = 1 + 4; // Command byte + 4 address bytes + send_u32(status, data, arg->address); + } else { + dummy_count = 1 + 3; // Command byte + 3 address bytes + send_u24(status, data, arg->address); + } + + for (tx_size = arg->sector_size, rx_size = arg->sector_size, filled = 1; + tx_size > 0; tx_size--) { + send_u8(status, data, 0); // Dummy write to push out read data. + if (rx_available(status)) { + if (dummy_count > 0) { + // Read data not arrived yet. + rcv_byte(data); + dummy_count--; + } else { + if (rcv_byte(data) != arg->pattern) { + filled = 0; + break; + } + rx_size--; + } + } + } + if (filled) { + for (; rx_size > 0; rx_size--) { + wait_rx_available(status); + if (rcv_byte(data) != arg->pattern) { + filled = 0; + break; + } + } + } + *fill_status_array = filled; + } + + RETURN; +} + +/** + * @brief Erase flash sectors. + * + * @param[in] arg: Function arguments. + */ +__attribute__((section(".erase"))) void +erase(struct dw_spi_erase *arg) +{ + register uint32_t address = arg->address; + register uint32_t count = arg->sector_count; + register volatile uint8_t *status = (uint8_t *)arg->status_reg; + register volatile uint8_t *data = (uint8_t *)arg->data_reg; + + for (; count > 0; count--, address += arg->sector_size) { + write_enable(status, data, arg->write_enable_cmd); + wait_write_enable(status, data, arg->read_status_cmd, + arg->write_enable_mask); + + erase_sector(status, data, arg->erase_sector_cmd, address, + arg->four_byte_mode); + wait_busy(status, data, arg->read_status_cmd, arg->busy_mask); + } + + RETURN; +} + +/** + * @brief Flash program. + * + * @param[in] arg: Function arguments. + */ +__attribute__((section(".program"))) void +program(struct dw_spi_program *arg) +{ + register uint8_t *buffer = (uint8_t *)arg->buffer; + register uint32_t buffer_size = arg->buffer_size; + register volatile uint8_t *status = (uint8_t *)arg->status_reg; + register volatile uint8_t *data = (uint8_t *)arg->data_reg; + register uint32_t page_size; + + while (buffer_size > 0) { + write_enable(status, data, arg->write_enable_cmd); + wait_write_enable(status, data, arg->read_status_cmd, + arg->write_enable_mask); + + wait_tx_finish(status); + + send_u8(status, data, arg->program_cmd); + if (arg->four_byte_mode) + send_u32(status, data, arg->address); + else + send_u24(status, data, arg->address); + + for (page_size = MIN(arg->page_size, buffer_size); page_size > 0; + page_size--, buffer_size--) { + send_u8(status, data, *buffer++); + } + arg->address += arg->page_size; + wait_busy(status, data, arg->read_status_cmd, arg->busy_mask); + } + + RETURN; +} + +/** + * @brief Read data from flash. + * + * @param[in] arg: Function arguments. + */ +__attribute__((section(".read"))) void +read(struct dw_spi_read *arg) +{ + register uint32_t tx_size = arg->buffer_size; + register uint32_t rx_size = arg->buffer_size; + register uint32_t dummy_count; + register uint8_t *buffer = (uint8_t *)arg->buffer; + register volatile uint8_t *status = (uint8_t *)arg->status_reg; + register volatile uint8_t *data = (uint8_t *)arg->data_reg; + + wait_tx_finish(status); + flush_rx(status, data); + + /* + * Command byte and address bytes make up for dummy_count number of + * bytes, that must be skipped in RX FIFO before actual data arrives. + */ + send_u8(status, data, arg->read_cmd); + if (arg->four_byte_mode) { + dummy_count = 1 + 4; // Command byte + 4 address bytes + send_u32(status, data, arg->address); + } else { + dummy_count = 1 + 3; // Command byte + 3 address bytes + send_u24(status, data, arg->address); + } + + for (; tx_size > 0; tx_size--) { + send_u8(status, data, 0); // Dummy write to push out read data. + if (rx_available(status)) { + if (dummy_count > 0) { + rcv_byte(data); + dummy_count--; + } else { + *buffer++ = rcv_byte(data); + rx_size--; + } + } + } + while (rx_size > 0) { + wait_rx_available(status); + if (dummy_count > 0) { + // Read data not arrived yet. + rcv_byte(data); + dummy_count--; + } else { + *buffer++ = rcv_byte(data); + rx_size--; + } + } + + RETURN; +} diff --git a/contrib/loaders/flash/dw-spi/dw-spi.h b/contrib/loaders/flash/dw-spi/dw-spi.h new file mode 100644 index 000000000..9efa768e6 --- /dev/null +++ b/contrib/loaders/flash/dw-spi/dw-spi.h @@ -0,0 +1,313 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/** + * @file + * Helper functions for DesignWare SPI Core driver. + * These helpers are loaded into CPU and execute Flash manipulation algorithms + * at full CPU speed. Due to inability to control nCS pin, this is the only way + * to communicate with Flash chips connected via DW SPI serial interface. + * + * In order to avoid using stack, all functions used in helpers are inlined. + * Software breakpoints are used to terminate helpers. + * + * This file contains functions, common to helpers. + */ + +#ifndef _DW_SPI_H_ +#define _DW_SPI_H_ + +#include +#include + +#include "../../../../src/helper/types.h" + +/** + * @brief SI busy status bit. + * + * Set when serial transfer is in progress, cleared when master is idle or + * disabled. + */ +#define DW_SPI_STATUS_BUSY 0x01 + +/** + * @brief SI TX FIFO not full status bit. + * + * Set when TX FIFO has room for one or more data-word. + */ +#define DW_SPI_STATUS_TFNF 0x02 + +/** + * @brief SI TX FIFO empty status bit. + */ +#define DW_SPI_STATUS_TFE 0x04 + +/** + * @brief SI RX FIFO not empty status bit. + */ +#define DW_SPI_STATUS_RFNE 0x08 + +/** + * @brief Return from helper function. + */ +#define RETURN \ + do { \ + asm("sdbbp\n\t"); \ + return; \ + } while (0) + +/** + * @brief Append byte to TX FIFO. + * + * For each transferred byte, DW SPI controller receives a byte into RX FIFO. + * Slave data are read by pushing dummy bytes to TX FIFO. + * + * @param[in] dr: Pointer to DR register. + * @param[in] byte: Data to push. + */ +__attribute__((always_inline)) static inline void +_send_byte(volatile uint8_t *dr, uint8_t byte) +{ + *dr = byte; +} + +/** + * @brief Get byte from RX FIFO. + * + * Reading RX byte removes it from RX FIFO. + * + * @param[in] dr: Pointer to DR register. + * @return RX FIFO byte. + */ +__attribute__((always_inline)) static inline uint8_t +rcv_byte(volatile uint8_t *dr) +{ + return *dr; +} + +/** + * @brief Check transmission is currently in progress. + * + * @param[in] sr: Pointer to SR register. + * @retval 1: Transmission is in progress. + * @retval 0: Controller is idle or off. + */ +__attribute__((always_inline)) static inline int +tx_in_progress(volatile uint8_t *sr) +{ + return (*sr ^ DW_SPI_STATUS_TFE) & (DW_SPI_STATUS_BUSY | DW_SPI_STATUS_TFE); +} + +/** + * @brief Wait for controller to finish previous transaction. + * + * @param[in] sr: Pointer to SR register. + */ +__attribute__((always_inline)) static inline void +wait_tx_finish(volatile uint8_t *sr) +{ + while (tx_in_progress(sr)) + ; +} + +/** + * @brief Wait for room in TX FIFO. + * + * @param[in] sr: Pointer to SR register. + */ +__attribute__((always_inline)) static inline void +wait_tx_available(volatile uint8_t *sr) +{ + while (!(*sr & DW_SPI_STATUS_TFNF)) + ; +} + +/** + * @brief Check for data available in RX FIFO. + * + * @param[in] sr: Pointer to SR register. + * @retval 1: Data available. + * @retval 0: No data available. + */ +__attribute__((always_inline)) static inline int +rx_available(volatile uint8_t *sr) +{ + return *sr & DW_SPI_STATUS_RFNE; +} + +/** + * @brief Wait for data in RX FIFO. + * + * @param[in] sr: Pointer to SR register. + */ +__attribute__((always_inline)) static inline void +wait_rx_available(volatile uint8_t *sr) +{ + while (!rx_available(sr)) + ; +} + +/** + * @brief Flush RX FIFO. + * + * @param[in] sr: Pointer to SR register. + * @param[in] dr: Pointer to DR register. + */ +__attribute__((always_inline)) static inline void +flush_rx(volatile uint8_t *sr, volatile uint8_t *dr) +{ + while (*sr & DW_SPI_STATUS_RFNE) + *dr; +} + +/** + * @brief Append variable number of bytes to TX FIFO. + * + * @param[in] sr: Pointer to SR register. + * @param[in] dr: Pointer to DR register. + * @param[in] word: Data to append. + * @param[in] bytes: Number of bytes to append. + */ +__attribute__((always_inline)) static inline void +_send_bytes(volatile uint8_t *sr, volatile uint8_t *dr, uint32_t word, + int bytes) +{ + for (register int i = bytes - 1; i >= 0; i--) { + wait_tx_available(sr); + _send_byte(dr, (word >> (i * 8)) & 0xff); + } +} + +/** + * @brief Append 8 bit value to TX FIFO. + * + * @param[in] sr: Pointer to SR register. + * @param[in] dr: Pointer to DR register. + * @param[in] word: Data to push. + */ +__attribute__((always_inline)) static inline void +send_u8(volatile uint8_t *sr, volatile uint8_t *dr, uint8_t byte) +{ + wait_tx_available(sr); + _send_byte(dr, byte); +} + +/** + * @brief Append 24 bit value to TX FIFO. + * + * Used to send Flash addresses in 24 bit mode. + * + * @param[in] sr: Pointer to SR register. + * @param[in] dr: Pointer to DR register. + * @param[in] word: Data to push. + */ +__attribute__((always_inline)) static inline void +send_u24(volatile uint8_t *sr, volatile uint8_t *dr, uint32_t word) +{ + _send_bytes(sr, dr, word, 3); +} + +/** + * @brief Append 32 bit value to TX FIFO. + * + * @param[in] sr: Pointer to SR register. + * @param[in] dr: Pointer to DR register. + * @param[in] word: Data to push. + */ +__attribute__((always_inline)) static inline void +send_u32(volatile uint8_t *sr, volatile uint8_t *dr, uint32_t word) +{ + _send_bytes(sr, dr, word, 4); +} + +/** + * @brief Read chip status register. + * + * @param[in] sr: Pointer to SR register. + * @param[in] dr: Pointer to DR register. + * @param[in] stat_cmd: Read status command. + * @return Chip status. + */ +__attribute__((always_inline)) static inline uint8_t +read_status(volatile uint8_t *sr, volatile uint8_t *dr, uint8_t stat_cmd) +{ + wait_tx_finish(sr); + flush_rx(sr, dr); + /* + * Don't bother with wait_tx_available() as TX FIFO is empty + * and we only send two bytes. + */ + _send_byte(dr, stat_cmd); + _send_byte(dr, 0); // Dummy write to push out read data. + wait_rx_available(sr); + rcv_byte(dr); // Dummy read to skip command byte. + wait_rx_available(sr); + return rcv_byte(dr); +} + +/** + * @brief Enable Flash chip write. + * + * @param[in] sr: Pointer to SR register. + * @param[in] dr: Pointer to DR register. + * @param[in] we_cmd: Write enable command. + */ +__attribute__((always_inline)) static inline void +write_enable(volatile uint8_t *sr, volatile uint8_t *dr, uint8_t we_cmd) +{ + wait_tx_finish(sr); + _send_byte(dr, we_cmd); +} + +/** + * @brief Erase Flash sector. + * + * @param[in] sr: Pointer to SR register. + * @param[in] dr: Pointer to DR register. + * @param[in] erase_cmd: Erase sector cmd. + * @param[in] address: Sector address. + * @param[in] four_byte_mode: Device is in 32 bit mode flag. + */ +__attribute__((always_inline)) static inline void +erase_sector(volatile uint8_t *sr, volatile uint8_t *dr, uint8_t erase_cmd, + uint32_t address, uint8_t four_byte_mode) +{ + wait_tx_finish(sr); + _send_byte(dr, erase_cmd); + if (four_byte_mode) + send_u32(sr, dr, address); + else + send_u24(sr, dr, address); +} + +/** + * @brief Wait for write enable flag. + * + * @param[in] sr: Pointer to SR register. + * @param[in] dr: Pointer to DR register. + * @param[in] stat_cmd: Read status command. + * @param[in] we_mask: Write enable status mask. + */ +__attribute__((always_inline)) static inline void +wait_write_enable(volatile uint8_t *sr, volatile uint8_t *dr, uint8_t stat_cmd, + uint8_t we_mask) +{ + while (!(read_status(sr, dr, stat_cmd) & we_mask)) + ; +} + +/** + * @brief Wait while flash is busy. + * + * @param[in] sr: Pointer to SR register. + * @param[in] dr: Pointer to DR register. + * @param[in] stat_cmd: Read status command. + * @param[in] busy_mask: Flash busy mask. + */ +__attribute__((always_inline)) static inline void +wait_busy(volatile uint8_t *sr, volatile uint8_t *dr, uint8_t stat_cmd, + uint8_t busy_mask) +{ + while (read_status(sr, dr, stat_cmd) & busy_mask) + ; +} + +#endif // _DW_SPI_H_ diff --git a/contrib/loaders/flash/dw-spi/mipsel-linux-gnu-check_fill.inc b/contrib/loaders/flash/dw-spi/mipsel-linux-gnu-check_fill.inc new file mode 100644 index 000000000..94c732fe5 --- /dev/null +++ b/contrib/loaders/flash/dw-spi/mipsel-linux-gnu-check_fill.inc @@ -0,0 +1,39 @@ + 0x0b, 0x00, 0x82, 0x88, 0x1f, 0x00, 0x8a, 0x88, 0x0f, 0x00, 0x83, 0x88, + 0x17, 0x00, 0x86, 0x88, 0x08, 0x00, 0x82, 0x98, 0x1c, 0x00, 0x8a, 0x98, + 0x0c, 0x00, 0x83, 0x98, 0x14, 0x00, 0x86, 0x98, 0x25, 0x38, 0x80, 0x00, + 0x54, 0x00, 0x40, 0x10, 0xf8, 0xff, 0x09, 0x24, 0x00, 0x00, 0x64, 0x90, + 0x05, 0x00, 0x84, 0x30, 0x04, 0x00, 0x84, 0x38, 0xfc, 0xff, 0x80, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x90, 0x08, 0x00, 0x42, 0x30, + 0x07, 0x00, 0x40, 0x50, 0x25, 0x00, 0xe5, 0x90, 0x00, 0x00, 0xc2, 0x90, + 0x00, 0x00, 0x62, 0x90, 0x08, 0x00, 0x42, 0x30, 0xfc, 0xff, 0x40, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x25, 0x00, 0xe5, 0x90, 0x00, 0x00, 0x62, 0x90, + 0x02, 0x00, 0x42, 0x30, 0xfd, 0xff, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc5, 0xa0, 0x26, 0x00, 0xe2, 0x90, 0x45, 0x00, 0x40, 0x10, + 0x03, 0x00, 0xe8, 0x88, 0x00, 0x00, 0xe8, 0x98, 0x18, 0x00, 0x05, 0x24, + 0x00, 0x00, 0x62, 0x90, 0x02, 0x00, 0x42, 0x30, 0xfd, 0xff, 0x40, 0x10, + 0x06, 0x10, 0xa8, 0x00, 0xff, 0x00, 0x42, 0x30, 0xf8, 0xff, 0xa5, 0x24, + 0x00, 0x00, 0xc2, 0xa0, 0xf8, 0xff, 0xa9, 0x14, 0x05, 0x00, 0x0b, 0x24, + 0x07, 0x00, 0xe8, 0x88, 0x04, 0x00, 0xe8, 0x98, 0x1e, 0x00, 0x00, 0x11, + 0x25, 0x28, 0x00, 0x01, 0x00, 0x00, 0x62, 0x90, 0x02, 0x00, 0x42, 0x30, + 0xfd, 0xff, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa0, + 0x00, 0x00, 0x62, 0x90, 0x08, 0x00, 0x42, 0x30, 0x06, 0x00, 0x40, 0x50, + 0xff, 0xff, 0xa5, 0x24, 0x00, 0x00, 0xc2, 0x90, 0x25, 0x00, 0x60, 0x51, + 0x24, 0x00, 0xec, 0x90, 0xff, 0xff, 0x6b, 0x25, 0xff, 0xff, 0xa5, 0x24, + 0xf1, 0xff, 0xa0, 0x14, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x51, + 0x01, 0x00, 0x04, 0x24, 0x24, 0x00, 0xe5, 0x90, 0x00, 0x00, 0x62, 0x90, + 0x08, 0x00, 0x42, 0x30, 0xfd, 0xff, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc2, 0x90, 0xff, 0x00, 0x42, 0x30, 0x04, 0x00, 0xa2, 0x14, + 0xff, 0xff, 0x08, 0x25, 0xf7, 0xff, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x04, 0x24, 0x00, 0x00, 0x44, 0xa1, 0x0b, 0x00, 0xe2, 0x88, + 0x01, 0x00, 0x4a, 0x25, 0x08, 0x00, 0xe2, 0x98, 0xff, 0xff, 0x42, 0x24, + 0x0b, 0x00, 0xe2, 0xa8, 0x08, 0x00, 0xe2, 0xb8, 0x03, 0x00, 0xe4, 0x88, + 0x07, 0x00, 0xe5, 0x88, 0x00, 0x00, 0xe4, 0x98, 0x04, 0x00, 0xe5, 0x98, + 0x21, 0x20, 0x85, 0x00, 0x03, 0x00, 0xe4, 0xa8, 0xae, 0xff, 0x40, 0x14, + 0x00, 0x00, 0xe4, 0xb8, 0x3f, 0x00, 0x00, 0x70, 0x08, 0x00, 0xe0, 0x03, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x42, 0x30, 0xed, 0xff, 0x82, 0x55, + 0x00, 0x00, 0x44, 0xa1, 0xd9, 0xff, 0x00, 0x10, 0xff, 0xff, 0x08, 0x25, + 0x00, 0x00, 0xe8, 0x98, 0x10, 0x00, 0x05, 0x24, 0x00, 0x00, 0x62, 0x90, + 0x02, 0x00, 0x42, 0x30, 0xfd, 0xff, 0x40, 0x10, 0x06, 0x10, 0xa8, 0x00, + 0xff, 0x00, 0x42, 0x30, 0xf8, 0xff, 0xa5, 0x24, 0x00, 0x00, 0xc2, 0xa0, + 0xf8, 0xff, 0xa9, 0x14, 0x04, 0x00, 0x0b, 0x24, 0xbc, 0xff, 0x00, 0x10, + 0x07, 0x00, 0xe8, 0x88 diff --git a/contrib/loaders/flash/dw-spi/mipsel-linux-gnu-erase.inc b/contrib/loaders/flash/dw-spi/mipsel-linux-gnu-erase.inc new file mode 100644 index 000000000..b72c7ea44 --- /dev/null +++ b/contrib/loaders/flash/dw-spi/mipsel-linux-gnu-erase.inc @@ -0,0 +1,39 @@ + 0x0b, 0x00, 0x88, 0x88, 0x25, 0x28, 0x80, 0x00, 0x03, 0x00, 0x86, 0x88, + 0x0f, 0x00, 0x82, 0x88, 0x17, 0x00, 0x84, 0x88, 0x08, 0x00, 0xa8, 0x98, + 0x00, 0x00, 0xa6, 0x98, 0x0c, 0x00, 0xa2, 0x98, 0x5f, 0x00, 0x00, 0x11, + 0x14, 0x00, 0xa4, 0x98, 0xf8, 0xff, 0x07, 0x24, 0x1d, 0x00, 0xa9, 0x90, + 0x00, 0x00, 0x43, 0x90, 0x05, 0x00, 0x63, 0x30, 0x04, 0x00, 0x63, 0x38, + 0xfc, 0xff, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0xa0, + 0x1c, 0x00, 0xaa, 0x90, 0x1f, 0x00, 0xa9, 0x90, 0x00, 0x00, 0x43, 0x90, + 0x05, 0x00, 0x63, 0x30, 0x04, 0x00, 0x63, 0x38, 0xfc, 0xff, 0x60, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x90, 0x08, 0x00, 0x63, 0x30, + 0x06, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x90, + 0x00, 0x00, 0x43, 0x90, 0x08, 0x00, 0x63, 0x30, 0xfc, 0xff, 0x60, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a, 0xa0, 0x00, 0x00, 0x80, 0xa0, + 0x00, 0x00, 0x43, 0x90, 0x08, 0x00, 0x63, 0x30, 0xfd, 0xff, 0x60, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x90, 0x00, 0x00, 0x43, 0x90, + 0x08, 0x00, 0x63, 0x30, 0xfd, 0xff, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x83, 0x90, 0x24, 0x18, 0x23, 0x01, 0xe4, 0xff, 0x60, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0xaa, 0x90, 0x21, 0x00, 0xa9, 0x90, + 0x00, 0x00, 0x43, 0x90, 0x05, 0x00, 0x63, 0x30, 0x04, 0x00, 0x63, 0x38, + 0xfc, 0xff, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a, 0xa0, + 0x31, 0x00, 0x20, 0x11, 0x10, 0x00, 0x09, 0x24, 0x18, 0x00, 0x09, 0x24, + 0x00, 0x00, 0x43, 0x90, 0x02, 0x00, 0x63, 0x30, 0xfd, 0xff, 0x60, 0x10, + 0x06, 0x18, 0x26, 0x01, 0xff, 0x00, 0x63, 0x30, 0xf8, 0xff, 0x29, 0x25, + 0xf9, 0xff, 0x27, 0x15, 0x00, 0x00, 0x83, 0xa0, 0x1c, 0x00, 0xaa, 0x90, + 0x20, 0x00, 0xa9, 0x90, 0x00, 0x00, 0x43, 0x90, 0x05, 0x00, 0x63, 0x30, + 0x04, 0x00, 0x63, 0x38, 0xfc, 0xff, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x43, 0x90, 0x08, 0x00, 0x63, 0x30, 0x06, 0x00, 0x60, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x90, 0x00, 0x00, 0x43, 0x90, + 0x08, 0x00, 0x63, 0x30, 0xfc, 0xff, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x8a, 0xa0, 0x00, 0x00, 0x80, 0xa0, 0x00, 0x00, 0x43, 0x90, + 0x08, 0x00, 0x63, 0x30, 0xfd, 0xff, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x83, 0x90, 0x00, 0x00, 0x43, 0x90, 0x08, 0x00, 0x63, 0x30, + 0xfd, 0xff, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x90, + 0x24, 0x18, 0x23, 0x01, 0xe4, 0xff, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00, + 0x07, 0x00, 0xa3, 0x88, 0xff, 0xff, 0x08, 0x25, 0x04, 0x00, 0xa3, 0x98, + 0xa4, 0xff, 0x00, 0x15, 0x21, 0x30, 0xc3, 0x00, 0x3f, 0x00, 0x00, 0x70, + 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x90, + 0x02, 0x00, 0x63, 0x30, 0xfd, 0xff, 0x60, 0x10, 0x06, 0x18, 0x26, 0x01, + 0xff, 0x00, 0x63, 0x30, 0xf8, 0xff, 0x29, 0x25, 0xf9, 0xff, 0x27, 0x15, + 0x00, 0x00, 0x83, 0xa0, 0xd1, 0xff, 0x00, 0x10, 0x1c, 0x00, 0xaa, 0x90 diff --git a/contrib/loaders/flash/dw-spi/mipsel-linux-gnu-program.inc b/contrib/loaders/flash/dw-spi/mipsel-linux-gnu-program.inc new file mode 100644 index 000000000..31500e01d --- /dev/null +++ b/contrib/loaders/flash/dw-spi/mipsel-linux-gnu-program.inc @@ -0,0 +1,51 @@ + 0x13, 0x00, 0x88, 0x88, 0x25, 0x30, 0x80, 0x00, 0x0b, 0x00, 0x85, 0x88, + 0x17, 0x00, 0x82, 0x88, 0x1f, 0x00, 0x84, 0x88, 0x10, 0x00, 0xc8, 0x98, + 0x08, 0x00, 0xc5, 0x98, 0x14, 0x00, 0xc2, 0x98, 0x1c, 0x00, 0xc4, 0x98, + 0x78, 0x00, 0x00, 0x11, 0xf8, 0xff, 0x07, 0x24, 0x25, 0x00, 0xc9, 0x90, + 0x00, 0x00, 0x43, 0x90, 0x05, 0x00, 0x63, 0x30, 0x04, 0x00, 0x63, 0x38, + 0xfc, 0xff, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0xa0, + 0x24, 0x00, 0xca, 0x90, 0x27, 0x00, 0xc9, 0x90, 0x00, 0x00, 0x43, 0x90, + 0x05, 0x00, 0x63, 0x30, 0x04, 0x00, 0x63, 0x38, 0xfc, 0xff, 0x60, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x90, 0x08, 0x00, 0x63, 0x30, + 0x06, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x90, + 0x00, 0x00, 0x43, 0x90, 0x08, 0x00, 0x63, 0x30, 0xfc, 0xff, 0x60, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a, 0xa0, 0x00, 0x00, 0x80, 0xa0, + 0x00, 0x00, 0x43, 0x90, 0x08, 0x00, 0x63, 0x30, 0xfd, 0xff, 0x60, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x90, 0x00, 0x00, 0x43, 0x90, + 0x08, 0x00, 0x63, 0x30, 0xfd, 0xff, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x83, 0x90, 0x24, 0x18, 0x23, 0x01, 0xe4, 0xff, 0x60, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x90, 0x05, 0x00, 0x63, 0x30, + 0x04, 0x00, 0x63, 0x38, 0xfc, 0xff, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00, + 0x26, 0x00, 0xc9, 0x90, 0x00, 0x00, 0x43, 0x90, 0x02, 0x00, 0x63, 0x30, + 0xfd, 0xff, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0xa0, + 0x29, 0x00, 0xc3, 0x90, 0x47, 0x00, 0x60, 0x10, 0x03, 0x00, 0xca, 0x88, + 0x00, 0x00, 0xca, 0x98, 0x18, 0x00, 0x09, 0x24, 0x00, 0x00, 0x43, 0x90, + 0x02, 0x00, 0x63, 0x30, 0xfd, 0xff, 0x60, 0x10, 0x06, 0x18, 0x2a, 0x01, + 0xff, 0x00, 0x63, 0x30, 0xf8, 0xff, 0x29, 0x25, 0x00, 0x00, 0x83, 0xa0, + 0xf8, 0xff, 0x27, 0x15, 0x25, 0x58, 0x00, 0x01, 0x07, 0x00, 0xc3, 0x88, + 0x04, 0x00, 0xc3, 0x98, 0x2b, 0x48, 0x03, 0x01, 0x0a, 0x58, 0x69, 0x00, + 0x0d, 0x00, 0x60, 0x11, 0x21, 0x50, 0xab, 0x00, 0x00, 0x00, 0xa9, 0x90, + 0x01, 0x00, 0xa5, 0x24, 0x00, 0x00, 0x43, 0x90, 0x02, 0x00, 0x63, 0x30, + 0xfd, 0xff, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0xa0, + 0xf9, 0xff, 0xaa, 0x54, 0x00, 0x00, 0xa9, 0x90, 0x07, 0x00, 0xc3, 0x88, + 0x23, 0x40, 0x0b, 0x01, 0x04, 0x00, 0xc3, 0x98, 0x03, 0x00, 0xc9, 0x88, + 0x00, 0x00, 0xc9, 0x98, 0x21, 0x18, 0x23, 0x01, 0x03, 0x00, 0xc3, 0xa8, + 0x00, 0x00, 0xc3, 0xb8, 0x24, 0x00, 0xca, 0x90, 0x28, 0x00, 0xc9, 0x90, + 0x00, 0x00, 0x43, 0x90, 0x05, 0x00, 0x63, 0x30, 0x04, 0x00, 0x63, 0x38, + 0xfc, 0xff, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x90, + 0x08, 0x00, 0x63, 0x30, 0x06, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x83, 0x90, 0x00, 0x00, 0x43, 0x90, 0x08, 0x00, 0x63, 0x30, + 0xfc, 0xff, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a, 0xa0, + 0x00, 0x00, 0x80, 0xa0, 0x00, 0x00, 0x43, 0x90, 0x08, 0x00, 0x63, 0x30, + 0xfd, 0xff, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x90, + 0x00, 0x00, 0x43, 0x90, 0x08, 0x00, 0x63, 0x30, 0xfd, 0xff, 0x60, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x90, 0x24, 0x18, 0x23, 0x01, + 0xe4, 0xff, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00, 0x8b, 0xff, 0x00, 0x55, + 0x25, 0x00, 0xc9, 0x90, 0x3f, 0x00, 0x00, 0x70, 0x08, 0x00, 0xe0, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0x98, 0x10, 0x00, 0x09, 0x24, + 0x00, 0x00, 0x43, 0x90, 0x02, 0x00, 0x63, 0x30, 0xfd, 0xff, 0x60, 0x10, + 0x06, 0x18, 0x2a, 0x01, 0xff, 0x00, 0x63, 0x30, 0xf8, 0xff, 0x29, 0x25, + 0x00, 0x00, 0x83, 0xa0, 0xf8, 0xff, 0x27, 0x15, 0x25, 0x58, 0x00, 0x01, + 0x07, 0x00, 0xc3, 0x88, 0x04, 0x00, 0xc3, 0x98, 0x2b, 0x48, 0x03, 0x01, + 0x0a, 0x58, 0x69, 0x00, 0xbb, 0xff, 0x60, 0x15, 0x21, 0x50, 0xab, 0x00, + 0xc6, 0xff, 0x00, 0x10, 0x03, 0x00, 0xc9, 0x88 diff --git a/contrib/loaders/flash/dw-spi/mipsel-linux-gnu-read.inc b/contrib/loaders/flash/dw-spi/mipsel-linux-gnu-read.inc new file mode 100644 index 000000000..3f18b7c2e --- /dev/null +++ b/contrib/loaders/flash/dw-spi/mipsel-linux-gnu-read.inc @@ -0,0 +1,33 @@ + 0x0f, 0x00, 0x87, 0x88, 0x07, 0x00, 0x88, 0x88, 0x13, 0x00, 0x83, 0x88, + 0x1b, 0x00, 0x85, 0x88, 0x0c, 0x00, 0x87, 0x98, 0x04, 0x00, 0x88, 0x98, + 0x10, 0x00, 0x83, 0x98, 0x18, 0x00, 0x85, 0x98, 0x00, 0x00, 0x62, 0x90, + 0x05, 0x00, 0x42, 0x30, 0x04, 0x00, 0x42, 0x38, 0xfc, 0xff, 0x40, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x90, 0x08, 0x00, 0x42, 0x30, + 0x07, 0x00, 0x40, 0x50, 0x20, 0x00, 0x86, 0x90, 0x00, 0x00, 0xa2, 0x90, + 0x00, 0x00, 0x62, 0x90, 0x08, 0x00, 0x42, 0x30, 0xfc, 0xff, 0x40, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x86, 0x90, 0x00, 0x00, 0x62, 0x90, + 0x02, 0x00, 0x42, 0x30, 0xfd, 0xff, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xa6, 0xa0, 0x21, 0x00, 0x82, 0x90, 0x35, 0x00, 0x40, 0x10, + 0x03, 0x00, 0x82, 0x88, 0x18, 0x00, 0x06, 0x24, 0xf8, 0xff, 0x09, 0x24, + 0x00, 0x00, 0x82, 0x98, 0x25, 0x20, 0x40, 0x00, 0x00, 0x00, 0x62, 0x90, + 0x02, 0x00, 0x42, 0x30, 0xfd, 0xff, 0x40, 0x10, 0x06, 0x10, 0xc4, 0x00, + 0xff, 0x00, 0x42, 0x30, 0xf8, 0xff, 0xc6, 0x24, 0xf9, 0xff, 0xc9, 0x14, + 0x00, 0x00, 0xa2, 0xa0, 0x05, 0x00, 0x06, 0x24, 0x23, 0x00, 0xe0, 0x10, + 0x25, 0x20, 0xe0, 0x00, 0x00, 0x00, 0x62, 0x90, 0x02, 0x00, 0x42, 0x30, + 0xfd, 0xff, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xa0, + 0x00, 0x00, 0x62, 0x90, 0x08, 0x00, 0x42, 0x30, 0x06, 0x00, 0x40, 0x50, + 0xff, 0xff, 0x84, 0x24, 0x00, 0x00, 0xa2, 0x90, 0x14, 0x00, 0xc0, 0x50, + 0x00, 0x00, 0x02, 0xa1, 0xff, 0xff, 0xc6, 0x24, 0xff, 0xff, 0x84, 0x24, + 0xf1, 0xff, 0x80, 0x14, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0xe0, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x90, 0x08, 0x00, 0x42, 0x30, + 0xfd, 0xff, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x90, + 0x03, 0x00, 0xc0, 0x50, 0xff, 0xff, 0xe7, 0x24, 0xf8, 0xff, 0x00, 0x10, + 0xff, 0xff, 0xc6, 0x24, 0x06, 0x00, 0xe0, 0x10, 0x00, 0x00, 0x02, 0xa1, + 0xf4, 0xff, 0x00, 0x10, 0x01, 0x00, 0x08, 0x25, 0xff, 0xff, 0xe7, 0x24, + 0xec, 0xff, 0x00, 0x10, 0x01, 0x00, 0x08, 0x25, 0x3f, 0x00, 0x00, 0x70, + 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x06, 0x24, + 0xf8, 0xff, 0x09, 0x24, 0x00, 0x00, 0x82, 0x98, 0x25, 0x20, 0x40, 0x00, + 0x00, 0x00, 0x62, 0x90, 0x02, 0x00, 0x42, 0x30, 0xfd, 0xff, 0x40, 0x10, + 0x06, 0x10, 0xc4, 0x00, 0xff, 0x00, 0x42, 0x30, 0xf8, 0xff, 0xc6, 0x24, + 0xf9, 0xff, 0xc9, 0x14, 0x00, 0x00, 0xa2, 0xa0, 0xcc, 0xff, 0x00, 0x10, + 0x04, 0x00, 0x06, 0x24 diff --git a/contrib/loaders/flash/dw-spi/mipsel-linux-gnu-transaction.inc b/contrib/loaders/flash/dw-spi/mipsel-linux-gnu-transaction.inc new file mode 100644 index 000000000..384dbadb1 --- /dev/null +++ b/contrib/loaders/flash/dw-spi/mipsel-linux-gnu-transaction.inc @@ -0,0 +1,21 @@ + 0x03, 0x00, 0x85, 0x88, 0x0b, 0x00, 0x88, 0x88, 0x0f, 0x00, 0x83, 0x88, + 0x17, 0x00, 0x86, 0x88, 0x00, 0x00, 0x85, 0x98, 0x08, 0x00, 0x88, 0x98, + 0x0c, 0x00, 0x83, 0x98, 0x14, 0x00, 0x86, 0x98, 0x00, 0x00, 0x62, 0x90, + 0x05, 0x00, 0x42, 0x30, 0x04, 0x00, 0x42, 0x38, 0xfc, 0xff, 0x40, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x90, 0x08, 0x00, 0x42, 0x30, + 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0x90, + 0x00, 0x00, 0x62, 0x90, 0x08, 0x00, 0x42, 0x30, 0xfc, 0xff, 0x40, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, + 0x25, 0x38, 0xa0, 0x00, 0x21, 0x40, 0x05, 0x01, 0x00, 0x00, 0xa9, 0x90, + 0x01, 0x00, 0xa5, 0x24, 0x00, 0x00, 0x62, 0x90, 0x02, 0x00, 0x42, 0x30, + 0xfd, 0xff, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc9, 0xa0, + 0x1c, 0x00, 0x82, 0x90, 0x08, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x62, 0x90, 0x08, 0x00, 0x42, 0x30, 0x04, 0x00, 0x40, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0x90, 0x01, 0x00, 0xe7, 0x24, + 0xff, 0xff, 0xe2, 0xa0, 0xef, 0xff, 0xa8, 0x54, 0x00, 0x00, 0xa9, 0x90, + 0x1c, 0x00, 0x82, 0x90, 0x0c, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x2b, 0x10, 0xe8, 0x00, 0x09, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x62, 0x90, 0x08, 0x00, 0x42, 0x30, 0xfd, 0xff, 0x40, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0x90, 0x01, 0x00, 0xe7, 0x24, + 0xf9, 0xff, 0x07, 0x15, 0xff, 0xff, 0xe2, 0xa0, 0x3f, 0x00, 0x00, 0x70, + 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00 diff --git a/doc/openocd.texi b/doc/openocd.texi index 47a6f69eb..2ec49a4c0 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -6421,6 +6421,75 @@ flash bank $_FLASHNAME fespi 0x20000000 0 0 0 $_TARGETNAME @end example @end deffn +@deffn {Flash Driver} {dw-spi} +@cindex DesignWare SPI controller driver +@cindex DW-SPI +Driver for SPI NOR flash chips connected via DesignWare SPI Core, used +in number of MCUs. +Currently, only MIPS M4K CPU architecture is supported. + +The flash size is autodetected based on the table of known JEDEC IDs hardcoded +in the OpenOCD sources. When flash size is set to @var{0}, probed Flash +size is used. + +This driver requires configuring DRAM controller first, setting up a +working area big enough to hold read/write buffers and switching Flash +chip to 32bit mode via Tcl commands. + +@quotation Note +If chip contains Boot controller, its 24/32bit setting must match +Flash chip. If Flash chip's reset line is not connected to JTAG adapter, +CPU reset may cause these configurations to be out of sync. +@end quotation + + +Mandatory driver's arguments are + +@itemize +@item @var{-freq} ... core frequency in Hz, used in communication speed +calculation. +@item @var{-simc} ... @var{SIMC} register block absolute address. +This value is the same as for Linux's driver device tree register field. +@item @var{-spi_mst} ... @var{SPI_MST} register address. When available, +it is used for switching between SPI Boot and Master controllers. This +value is the same as for Linux's driver device tree register field +second argument. Set to @var{0} if SPI Boot controller not available. +@item @var{-if_owner_offset} ... offset of @var{if_owner} field inside +@var{SPI_MST} register. Set to @var{0} if SPI Boot controller not available. +@end itemize + +Optional driver's arguments are + +@itemize +@item @var{-speed} ... SPI device communication speed in Hz. Minimal +speed depends on the @var{-freq} variable and has the value of +@var{freq/0xfffe}. The default value is @var{1000000}. +@item @var{-chip_select} ... Chip select pin. The default value +is @var{0}. +@item @var{-timeout} ... flash communication timeout in +seconds. The default value is @var{600}. +@end itemize + +For some SoCs there are shortcuts for mandatory arguments + +@itemize +@item @var{-jaguar2} ... configuration for MSCC Jaguar2 SoC family. +@item @var{-ocelot} ... configuration for MSCC Ocelot SoC family. +@end itemize + +Driver provides shortcut arguments for MSCC @var{-jaguar2} and +@var{-ocelot} network switch SOCs, which set the correct values for @var{-freq}, +@var{-simc}, @var{-spi_mst} and @var{-if_owner_offset} arguments. + +Example of equivalent configurations for Jaguar2 SoC + +@example +flash bank $_FLASHNAME dw-spi 0x40000000 0x02000000 4 4 $_TARGETNAME -freq 250000000 -simc 0x70101000 -spi_mst 0x70000024 -if_owner_offset 6 -speed 3000000 +flash bank $_FLASHNAME dw-spi 0x40000000 0x02000000 4 4 $_TARGETNAME -jaguar2 -speed 3000000 +@end example + +@end deffn + @subsection Internal Flash (Microcontrollers) @deffn {Flash Driver} {aduc702x} diff --git a/src/flash/nor/Makefile.am b/src/flash/nor/Makefile.am index afa11e7d4..829687761 100644 --- a/src/flash/nor/Makefile.am +++ b/src/flash/nor/Makefile.am @@ -26,6 +26,7 @@ NOR_DRIVERS = \ %D%/cc26xx.c \ %D%/cfi.c \ %D%/dsp5680xx_flash.c \ + %D%/dw-spi.c \ %D%/efm32.c \ %D%/em357.c \ %D%/eneispif.c \ @@ -89,6 +90,7 @@ NORHEADERS = \ %D%/cc26xx.h \ %D%/cfi.h \ %D%/driver.h \ + %D%/dw-spi-helper.h \ %D%/imp.h \ %D%/non_cfi.h \ %D%/ocl.h \ diff --git a/src/flash/nor/driver.h b/src/flash/nor/driver.h index 211661e21..852a55a11 100644 --- a/src/flash/nor/driver.h +++ b/src/flash/nor/driver.h @@ -254,6 +254,7 @@ extern const struct flash_driver cc26xx_flash; extern const struct flash_driver cc3220sf_flash; extern const struct flash_driver cfi_flash; extern const struct flash_driver dsp5680xx_flash; +extern const struct flash_driver dw_spi_flash; extern const struct flash_driver efm32_flash; extern const struct flash_driver em357_flash; extern const struct flash_driver eneispif_flash; diff --git a/src/flash/nor/drivers.c b/src/flash/nor/drivers.c index dd9995ecb..ce97b8150 100644 --- a/src/flash/nor/drivers.c +++ b/src/flash/nor/drivers.c @@ -31,6 +31,7 @@ static const struct flash_driver * const flash_drivers[] = { &cc26xx_flash, &cfi_flash, &dsp5680xx_flash, + &dw_spi_flash, &efm32_flash, &em357_flash, &eneispif_flash, diff --git a/src/flash/nor/dw-spi-helper.h b/src/flash/nor/dw-spi-helper.h new file mode 100644 index 000000000..d3537557b --- /dev/null +++ b/src/flash/nor/dw-spi-helper.h @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/** + * @file + * Driver for SPI NOR flash chips connected via DesignWare SPI Core. + * + * In order to avoid using stack, all helper function arguments are packed + * into a single struct, passed by pointer. + * + * Pointers are represented by 64 bit integers to make structs compatible + * with 64 bit targets. + * + * This file contains helper function argument structures. + */ + +#ifndef OPENOCD_FLASH_NOR_DW_SPI_HELPER_H +#define OPENOCD_FLASH_NOR_DW_SPI_HELPER_H + +#include + +/** + * @brief Arguments for transaction helper function. + */ +struct dw_spi_transaction { + uint64_t buffer; + ///< Pointer to data buffer to send over SPI. + ///< Return values are stored in place of output data when + ///< dw_spi_transaction::read_flag is 1. + uint32_t size; ///< Size of dw_spi_transaction::buffer. + uint64_t status_reg; ///< Pointer to SR register. + uint64_t data_reg; ///< Pointer to DR register. + uint8_t read_flag; + ///< When 1, store RX FIFO data to dw_spi_transaction::buffer. +} __attribute__((packed)); + +/** + * @brief Arguments for check_fill helper function. + */ +struct dw_spi_check_fill { + uint32_t address; ///< Starting address. Sector aligned. + uint32_t sector_size; ///< Sector size. + uint32_t sector_count; ///< Number of sectors to check. + uint64_t status_reg; ///< Pointer to SR register. + uint64_t data_reg; ///< Pointer to DR register. + uint64_t fill_status_array; + ///< Pointer to array describing sectors fill status. + ///< 1 if filled, 0 if not filled. + uint8_t pattern; ///< Fill pattern. + uint8_t read_cmd; ///< Read data command. + uint8_t four_byte_mode; ///< Four byte addressing mode flag. +} __attribute__((packed)); + +/** + * @brief Arguments for erase helper function. + */ +struct dw_spi_erase { + uint32_t address; ///< First sector address. Sector aligned. + uint32_t sector_size; ///< Sector size. + uint32_t sector_count; ///< Number of sectors to erase. + uint64_t status_reg; ///< Pointer to SR register. + uint64_t data_reg; ///< Pointer to DR register. + uint8_t read_status_cmd; ///< Read status command. + uint8_t write_enable_cmd; ///< Write enable command. + uint8_t erase_sector_cmd; ///< Erase sector command. + uint8_t write_enable_mask; ///< Write enable mask. + uint8_t busy_mask; ///< Busy mask. + uint8_t four_byte_mode; ///< Four byte addressing mode flag. +} __attribute__((packed)); + +/** + * @brief Arguments for program helper function. + */ +struct dw_spi_program { + uint32_t address; + ///< First page address. Page aligned when write is crossing + ///< the page boundary. + uint32_t page_size; ///< Page size. + uint64_t buffer; ///< Data buffer pointer. + uint32_t buffer_size; ///< Size of dw_spi_program::buffer. + uint64_t status_reg; ///< Pointer to SR register. + uint64_t data_reg; ///< Pointer to DR register. + uint8_t read_status_cmd; ///< Read status command. + uint8_t write_enable_cmd; ///< Write enable command. + uint8_t program_cmd; ///< Program command. + uint8_t write_enable_mask; ///< Write enable mask. + uint8_t busy_mask; ///< Busy mask. + uint8_t four_byte_mode; ///< Four byte addressing mode flag. +} __attribute__((packed)); + +/** + * @brief Arguments for read helper function. + */ +struct dw_spi_read { + uint32_t address; ///< First sector address. + uint64_t buffer; ///< Data buffer pointer. + uint32_t buffer_size; ///< Size of dw_spi_read::buffer. + uint64_t status_reg; ///< Pointer to SR register. + uint64_t data_reg; ///< Pointer to DR register. + uint8_t read_cmd; ///< Read data command. + uint8_t four_byte_mode; ///< Four byte addressing mode flag. +} __attribute__((packed)); + +#endif /* OPENOCD_FLASH_NOR_DW_SPI_HELPER_H */ diff --git a/src/flash/nor/dw-spi.c b/src/flash/nor/dw-spi.c new file mode 100644 index 000000000..e1965477e --- /dev/null +++ b/src/flash/nor/dw-spi.c @@ -0,0 +1,1608 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/** + * @file + * Driver for SPI NOR flash chips connected via DesignWare SPI Core. + * Controller's Linux driver is located at drivers/spi/spi-dw-mmio.c. + * DW-SPI is used in a number of processors, including Microsemi Jaguar2 and + * Ocelot switch chips. + * + * Serial interface (SI) nCS0 pin, which is usually connected to the external + * flash, cannot be controlled via GPIO controller: it is asserted only when + * TX FIFO is not empty. Since JTAG is not fast enough to fill TX FIFO and + * collect data from RX FIFO at the same time even on the slowest SPI clock + * speeds, driver can only operate using functions, loaded in target's memory. + * Therefore, it requires the user to set up DRAM controller and provide + * work-area. + * + * In Microsemi devices, serial interface pins may be governed either + * by Boot or Master controller. For these devices, additional configuration of + * spi_mst address is required to switch between the two. + * + * Currently supported devices typically have much more RAM then NOR Flash + * (Jaguar2 reference design has 256MB RAM and 32MB NOR Flash), so supporting + * work-area sizes smaller then transfer buffer seems like the unnecessary + * complication. + * + * This code was tested on Jaguar2 VSC7448 connected to Macronix MX25L25635F. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "dw-spi-helper.h" +#include "imp.h" +#include "spi.h" + +#include +#include +#include +#include +#include +#include + +/** + * @brief IP block placement map. + * + * Used for dynamic definition of the register map. + * + * IP block is used on different chips and placed in different locations. + * This structure defines some implementation specific variables. + */ +struct dw_spi_regmap { + uint32_t freq; ///< Clock frequency. + target_addr_t simc; ///< Absolute offset of SIMC register block. + target_addr_t spi_mst; + ///< Absolute offset of ICPU_CFG:SPI_MST register. 0 if not available. + uint8_t si_if_owner_offset; + ///< Offset of \ref si_mode bits in ICPU_CFG:SPI_MST. +}; + +/** + * @brief Register map for Jaguar2 switch devices. + */ +static const struct dw_spi_regmap jaguar2_regmap = { + .freq = 250000000UL, + .simc = 0x70101000UL, + .spi_mst = 0x70000024UL, + .si_if_owner_offset = 6, +}; + +/** + * @brief Register map for Ocelot switch devices. + */ +static const struct dw_spi_regmap ocelot_regmap = { + .freq = 250000000UL, + .simc = 0x70101000UL, + .spi_mst = 0x70000024UL, + .si_if_owner_offset = 4, +}; + +#define DW_SPI_IF_OWNER_WIDTH 2 ///< IF owner register field width. + +/** + * @brief Owner of the SI interface. + */ +enum dw_spi_si_mode { + DW_SPI_SI_MODE_BOOT = 1, + ///< Boot controller maps contents of SPI Flash to memory in read-only mode. + DW_SPI_SI_MODE_MASTER = 2, + ///< SPI controller mode for reading/writing SPI Flash. +}; + +#define DW_SPI_REG_CTRLR0 0x00 ///< General configuration register. +#define DW_SPI_REG_SIMCEN 0x08 ///< Master controller enable register. +#define DW_SPI_REG_SER 0x10 ///< Slave select register. +#define DW_SPI_REG_BAUDR 0x14 ///< Baud rate configuration register. +#define DW_SPI_REG_SR 0x28 ///< Status register. +#define DW_SPI_REG_IMR 0x2c ///< Interrupt configuration register. +#define DW_SPI_REG_DR 0x60 ///< Data register. + +#define DW_SPI_REG_CTRLR0_DFS(x) ((x) & GENMASK(3, 0)) ///< Data frame size. +#define DW_SPI_REG_CTRLR0_FRF(x) (((x) << 4) & GENMASK(5, 4)) ///< SI protocol. +#define DW_SPI_REG_CTRLR0_SCPH(x) ((!!(x)) << 6) ///< Probe position. +#define DW_SPI_REG_CTRLR0_SCPOL(x) ((!!(x)) << 7) ///< Probe polarity. +#define DW_SPI_REG_CTRLR0_TMOD(x) (((x) << 8) & GENMASK(9, 8)) ///< SI mode. +#define DW_SPI_REG_SIMCEN_SIMCEN(x) (!!(x)) ///< Controller enable. +#define DW_SPI_REG_SER_SER(x) ((x) & GENMASK(15, 0)) ///< Slave select bitmask. +#define DW_SPI_REG_BAUDR_SCKDV(x) ((x) & GENMASK(15, 0)) ///< Clock divisor. + +/** + * @brief Driver private state. + */ +struct dw_spi_driver { + bool probed; ///< Bank is probed. + uint32_t id; ///< Chip ID. + unsigned int speed; ///< Flash speed. + unsigned int timeout; ///< Flash timeout in milliseconds. + uint8_t chip_select_bitmask; ///< Chip select bitmask. + bool four_byte_mode; ///< Flash chip is in 32bit address mode. + enum dw_spi_si_mode saved_ctrl_mode; + ///< Previously selected controller mode. + struct dw_spi_regmap regmap; ///< SI controller regmap. + const struct flash_device *spi_flash; ///< SPI flash device info. +}; + +/** + * @brief Register used to pass argument struct to helper functions. + */ +#define DW_SPI_ARG_REG "r4" + +/** + * @brief Default timeout value in ms for flash transaction jobs. + */ +#define DW_SPI_TIMEOUT_DEFAULT (600 * 1000) + +/** + * @brief Timeout value in ms for short flash transactions, + * e.g. reading flash ID and status register. + */ +#define DW_SPI_TIMEOUT_TRANSACTION 1000 + +/** + * @brief Select SI interface owner. + * + * Mode selection is skipped if Boot controller not available on target + * (i.e. spi_mst command argument is not configured). + * + * @param[in] bank: Flash bank. + * @param[in] mode: New controller mode. + * @return Command execution status. + */ +static int +dw_spi_ctrl_mode(const struct flash_bank *const bank, enum dw_spi_si_mode mode) +{ + struct target *const target = bank->target; + const struct dw_spi_driver *const driver = bank->driver_priv; + const struct dw_spi_regmap *const regmap = &driver->regmap; + + if (!regmap->spi_mst) + return ERROR_OK; + + uint32_t ctrl; + int ret = target_read_u32(target, regmap->spi_mst, &ctrl); + if (ret) { + LOG_ERROR("DW SPI SPI:MST register read error"); + return ret; + } + ctrl &= ~GENMASK(DW_SPI_IF_OWNER_WIDTH + driver->regmap.si_if_owner_offset, + driver->regmap.si_if_owner_offset); + ctrl |= mode << driver->regmap.si_if_owner_offset; + + ret = target_write_u32(target, regmap->spi_mst, ctrl); + if (ret) + LOG_ERROR("DW SPI controller mode configuration error"); + + return ret; +} + +/** + * @brief Select master controller as SI interface owner. + * + * Previous interface owner is restored via dw_spi_ctrl_mode_restore() function. + * Mode selection is skipped if Boot controller not available on target + * (i.e. spi_mst command argument is not configured). + * + * @param[in] bank: Flash bank. + * @param[in] mode: New controller mode. + * @return Command execution status. + */ +static int +dw_spi_ctrl_mode_configure(const struct flash_bank *const bank, + enum dw_spi_si_mode mode) +{ + struct target *const target = bank->target; + struct dw_spi_driver *const driver = bank->driver_priv; + const struct dw_spi_regmap *const regmap = &driver->regmap; + + if (!regmap->spi_mst) + return ERROR_OK; + + uint32_t ctrl; + int ret = target_read_u32(target, regmap->spi_mst, &ctrl); + if (ret) { + LOG_ERROR("DW SPI controller mode query error"); + return ret; + } + driver->saved_ctrl_mode = + (enum dw_spi_si_mode)((ctrl >> driver->regmap.si_if_owner_offset) & + GENMASK(DW_SPI_IF_OWNER_WIDTH, 0)); + + return dw_spi_ctrl_mode(bank, mode); +} + +/** + * @brief Restore SI controller mode. + * + * Restore initially configured SI controller mode. Undo configuration done by + * dw_spi_ctrl_mode_configure() function. + * Mode selection is skipped if Boot controller not available on target + * (i.e. spi_mst command argument is not configured). + * + * @param[in] bank: Flash bank. + * @return Command execution status. + */ +static int +dw_spi_ctrl_mode_restore(const struct flash_bank *const bank) +{ + const struct dw_spi_driver *const driver = bank->driver_priv; + + return dw_spi_ctrl_mode(bank, driver->saved_ctrl_mode); +} + +/** + * @brief Enable master controller. + * + * Configuration of the master controller must be done when it is disabled. + * + * @param[in] bank: Flash bank. + * @param[in] value: New enable state. + * @return Command execution status. + */ +static int +dw_spi_master_ctrl_enable(const struct flash_bank *const bank, bool value) +{ + struct target *const target = bank->target; + const struct dw_spi_driver *const driver = bank->driver_priv; + const struct dw_spi_regmap *const regmap = &driver->regmap; + + int ret = target_write_u32(target, regmap->simc + DW_SPI_REG_SIMCEN, + DW_SPI_REG_SIMCEN_SIMCEN(value)); + if (ret) + LOG_ERROR("DW SPI master controller enable flag configuration error"); + + return ret; +} + +/** + * @brief Configure SI transfer mode. + * + * @param[in] bank: Flash bank. + * @return Command execution status. + */ +static int +dw_spi_ctrl_configure_si(const struct flash_bank *const bank) +{ + struct target *const target = bank->target; + const struct dw_spi_driver *const driver = bank->driver_priv; + const struct dw_spi_regmap *const regmap = &driver->regmap; + + // 8 bit frame; Motorola protocol; middle lo probe; TX RX mode + const uint32_t mode = DW_SPI_REG_CTRLR0_DFS(0x7) | + DW_SPI_REG_CTRLR0_FRF(0) | + DW_SPI_REG_CTRLR0_SCPH(0) | + DW_SPI_REG_CTRLR0_SCPOL(0) | + DW_SPI_REG_CTRLR0_TMOD(0); + + int ret = target_write_u32(target, regmap->simc + DW_SPI_REG_CTRLR0, mode); + if (ret) { + LOG_ERROR("DW SPI master controller configuration query error"); + return ret; + } + + ret = target_write_u32(target, regmap->simc + DW_SPI_REG_SER, + DW_SPI_REG_SER_SER(driver->chip_select_bitmask)); + if (ret) + LOG_ERROR("DW SPI slave select configuration error"); + + return ret; +} + +/** + * @brief Configure SI transfer speed. + * + * @param[in] bank: Flash bank. + * @return Command execution status. + */ +static int +dw_spi_ctrl_configure_speed(const struct flash_bank *const bank) +{ + struct target *const target = bank->target; + const struct dw_spi_driver *const driver = bank->driver_priv; + const struct dw_spi_regmap *const regmap = &driver->regmap; + + // divisor LSB must be zero + const uint16_t div = MIN((regmap->freq / driver->speed), 0xfffe) & 0xfffe; + + int ret = target_write_u32(target, regmap->simc + DW_SPI_REG_BAUDR, + DW_SPI_REG_BAUDR_SCKDV(div)); + if (ret) { + LOG_ERROR("DW SPI speed configuration error"); + return ret; + } + + unsigned int speed = regmap->freq / div; + LOG_DEBUG("DW SPI setting NOR controller speed to %u kHz", speed / 1000); + + return ret; +} + +/** + * @brief Disable SI master controller interrupts. + * + * @param[in] bank: Flash bank. + * @return Command execution status. + */ +static int +dw_spi_ctrl_disable_interrupts(const struct flash_bank *const bank) +{ + struct target *const target = bank->target; + const struct dw_spi_driver *const driver = bank->driver_priv; + const struct dw_spi_regmap *const regmap = &driver->regmap; + + int ret = target_write_u32(target, regmap->simc + DW_SPI_REG_IMR, 0); + if (ret) + LOG_ERROR("DW SPI disable interrupts error"); + + return ret; +} + +/** + * @brief Do data transaction. + * + * Buffer data are sent and replaced with received data. Total buffer size + * is a sum of TX and RX messages. RX portion of the buffer is initially + * filled with dummy values, which get replaced by the message. + * + * @param[in] bank: Flash bank. + * @param[in,out] buffer: Data buffer. If \p read flag is set, buffer is + * filled with received data. + * @param[in] size: \p buffer size. + * @param[in] read: The read flag. If set to true, read values will override + * \p buffer. + * @return Command execution status. + */ +static int +dw_spi_ctrl_transaction(const struct flash_bank *const bank, + uint8_t *const buffer, size_t size, bool read) +{ + struct target *const target = bank->target; + const struct dw_spi_driver *const driver = bank->driver_priv; + const struct dw_spi_regmap *const regmap = &driver->regmap; + + static const uint8_t target_code[] = { +#include "../../../contrib/loaders/flash/dw-spi/mipsel-linux-gnu-transaction.inc" + }; + const size_t target_code_size = sizeof(target_code); + const size_t total_working_area_size = + target_code_size + sizeof(struct dw_spi_transaction) + size; + + // allocate working area, memory args and data buffer + struct working_area *helper; + int ret = target_alloc_working_area(target, target_code_size, &helper); + if (ret) { + LOG_ERROR("DW SPI could not allocate working area. Need %zx", + total_working_area_size); + goto err_helper; + } + + struct working_area *helper_args; + ret = target_alloc_working_area(target, sizeof(struct dw_spi_transaction), + &helper_args); + if (ret) { + LOG_ERROR("DW SPI could not allocate working area. Need %zx", + total_working_area_size); + goto err_helper_args; + } + + struct working_area *target_buffer; + ret = target_alloc_working_area(target, size, &target_buffer); + if (ret) { + LOG_ERROR("DW SPI could not allocate working area. Need %zx", + total_working_area_size); + goto err_target_buffer; + } + + // write algorithm code and buffer to working areas + ret = target_write_buffer(target, helper->address, target_code_size, + target_code); + if (ret) { + LOG_ERROR("DW SPI writing to working area error"); + goto err_write_buffer; + } + + ret = target_write_buffer(target, target_buffer->address, size, buffer); + if (ret) { + LOG_ERROR("DW SPI writing to working area error"); + goto err_write_buffer; + } + + // prepare helper execution + struct mips32_algorithm mips32_algo = { .common_magic = MIPS32_COMMON_MAGIC, + .isa_mode = MIPS32_ISA_MIPS32 }; + + struct reg_param reg_param; + init_reg_param(®_param, DW_SPI_ARG_REG, 32, PARAM_OUT); + struct mem_param mem_param; + init_mem_param(&mem_param, helper_args->address, helper_args->size, + PARAM_OUT); + + // Set the arguments for the helper + buf_set_u32(reg_param.value, 0, 32, helper_args->address); + + struct dw_spi_transaction *helper_args_val = + (struct dw_spi_transaction *)mem_param.value; + target_buffer_set_u32(target, (uint8_t *)&helper_args_val->buffer, + target_buffer->address); + target_buffer_set_u32(target, (uint8_t *)&helper_args_val->size, size); + target_buffer_set_u32(target, (uint8_t *)&helper_args_val->status_reg, + regmap->simc + DW_SPI_REG_SR); + target_buffer_set_u32(target, (uint8_t *)&helper_args_val->data_reg, + regmap->simc + DW_SPI_REG_DR); + helper_args_val->read_flag = read; + + ret = target_run_algorithm(target, 1, &mem_param, 1, ®_param, + helper->address, 0, DW_SPI_TIMEOUT_TRANSACTION, + &mips32_algo); + + if (ret) { + LOG_ERROR("DW SPI flash algorithm error"); + goto cleanup; + } + + if (read) { + ret = target_read_buffer(target, target_buffer->address, size, buffer); + if (ret) + LOG_ERROR("DW SPI target buffer read error"); + } + +cleanup: + destroy_reg_param(®_param); + destroy_mem_param(&mem_param); + +err_write_buffer: + target_free_working_area(target, target_buffer); +err_target_buffer: + target_free_working_area(target, helper_args); +err_helper_args: + target_free_working_area(target, helper); +err_helper: + + return ret; +} + +/** + * @brief Check that selected region is filled with pattern. + * + * This function is used for Flash erase checking. + * + * @param[in] bank: Flash bank. + * @param[in] address: Starting address. Sector aligned. + * @param[in] sector_size: Size of sector. + * @param[in] sector_count: Number of sectors. + * @param[in] pattern: Fill pattern. + * @param[in] read_cmd: Flash read command. + * @param[out] buffer: Filled flag array. Must hold \p sector_count number + * of entries. + * @return Command execution status. + */ +static int +dw_spi_ctrl_check_sectors_fill(const struct flash_bank *const bank, + uint32_t address, size_t sector_size, + size_t sector_count, uint8_t pattern, + uint8_t read_cmd, uint8_t *buffer) +{ + struct target *const target = bank->target; + const struct dw_spi_driver *const driver = bank->driver_priv; + const struct dw_spi_regmap *const regmap = &driver->regmap; + + static const uint8_t target_code[] = { +#include "../../../contrib/loaders/flash/dw-spi/mipsel-linux-gnu-check_fill.inc" + }; + const size_t target_code_size = sizeof(target_code); + const size_t total_working_area_size = + target_code_size + sizeof(struct dw_spi_check_fill) + sector_count; + + // allocate working area, memory args and data buffer + struct working_area *helper; + int ret = target_alloc_working_area(target, target_code_size, &helper); + if (ret) { + LOG_ERROR("DW SPI could not allocate working area. Need %zx", + total_working_area_size); + goto err_helper; + } + + struct working_area *helper_args; + ret = target_alloc_working_area(target, sizeof(struct dw_spi_check_fill), + &helper_args); + if (ret) { + LOG_ERROR("DW SPI could not allocate working area. Need %zx", + total_working_area_size); + goto err_helper_args; + } + + struct working_area *target_buffer; + ret = target_alloc_working_area(target, sector_count, &target_buffer); + if (ret) { + LOG_ERROR("DW SPI could not allocate working area. Need %zx", + total_working_area_size); + goto err_target_buffer; + } + + // write algorithm code and buffer to working areas + ret = target_write_buffer(target, helper->address, target_code_size, + target_code); + if (ret) { + LOG_ERROR("DW SPI writing to working area error"); + goto err_write_buffer; + } + + // prepare helper execution + struct mips32_algorithm mips32_algo = { .common_magic = MIPS32_COMMON_MAGIC, + .isa_mode = MIPS32_ISA_MIPS32 }; + + struct reg_param reg_param; + init_reg_param(®_param, DW_SPI_ARG_REG, 32, PARAM_OUT); + struct mem_param mem_param; + init_mem_param(&mem_param, helper_args->address, helper_args->size, + PARAM_OUT); + + // Set the arguments for the helper + buf_set_u32(reg_param.value, 0, 32, helper_args->address); + + struct dw_spi_check_fill *helper_args_val = + (struct dw_spi_check_fill *)mem_param.value; + target_buffer_set_u32(target, (uint8_t *)&helper_args_val->address, + address); + target_buffer_set_u32(target, (uint8_t *)&helper_args_val->sector_size, + sector_size); + target_buffer_set_u32(target, (uint8_t *)&helper_args_val->sector_count, + sector_count); + target_buffer_set_u32(target, (uint8_t *)&helper_args_val->status_reg, + regmap->simc + DW_SPI_REG_SR); + target_buffer_set_u32(target, (uint8_t *)&helper_args_val->data_reg, + regmap->simc + DW_SPI_REG_DR); + target_buffer_set_u32(target, + (uint8_t *)&helper_args_val->fill_status_array, + target_buffer->address); + helper_args_val->pattern = pattern; + helper_args_val->read_cmd = read_cmd; + helper_args_val->four_byte_mode = driver->four_byte_mode; + + ret = target_run_algorithm(target, 1, &mem_param, 1, ®_param, + helper->address, 0, driver->timeout, + &mips32_algo); + + if (ret) { + LOG_ERROR("DW SPI flash algorithm error"); + goto cleanup; + } + + ret = target_read_buffer(target, target_buffer->address, sector_count, + buffer); + if (ret) + LOG_ERROR("DW SPI target buffer read error"); + +cleanup: + destroy_reg_param(®_param); + destroy_mem_param(&mem_param); + +err_write_buffer: + target_free_working_area(target, target_buffer); +err_target_buffer: + target_free_working_area(target, helper_args); +err_helper_args: + target_free_working_area(target, helper); +err_helper: + + return ret; +} + +/** + * @brief Write flash region. + * + * @param[in] bank: Flash bank. + * @param[in] address: First page address. Page aligned when write is crossing + * the page boundary. + * @param[in] buffer: Data buffer. + * @param[in] buffer_size: \p buffer size. + * @param[in] page_size: Size of flash page. + * @param[in] stat_cmd: Flash command to read chip status. + * @param[in] we_cmd: Flash command to enable write. + * @param[in] program_cmd: Flash command to program chip. + * @param[in] we_mask: Status byte write enable mask. + * @param[in] busy_mask: Status byte write busy mask. + * @return Command execution status. + */ +static int +dw_spi_ctrl_program(const struct flash_bank *const bank, uint32_t address, + const uint8_t *const buffer, size_t buffer_size, + uint32_t page_size, uint8_t stat_cmd, uint8_t we_cmd, + uint8_t program_cmd, uint8_t we_mask, uint8_t busy_mask) +{ + struct target *const target = bank->target; + const struct dw_spi_driver *const driver = bank->driver_priv; + const struct dw_spi_regmap *const regmap = &driver->regmap; + + static const uint8_t target_code[] = { +#include "../../../contrib/loaders/flash/dw-spi/mipsel-linux-gnu-program.inc" + }; + const size_t target_code_size = sizeof(target_code); + const size_t total_working_area_size = + target_code_size + sizeof(struct dw_spi_program) + buffer_size; + + // allocate working area, memory args and data buffer + struct working_area *helper; + int ret = target_alloc_working_area(target, target_code_size, &helper); + if (ret) { + LOG_ERROR("DW SPI could not allocate working area. Need %zx", + total_working_area_size); + goto err_helper; + } + + struct working_area *helper_args; + ret = target_alloc_working_area(target, sizeof(struct dw_spi_program), + &helper_args); + if (ret) { + LOG_ERROR("DW SPI could not allocate working area. Need %zx", + total_working_area_size); + goto err_helper_args; + } + + struct working_area *target_buffer; + ret = target_alloc_working_area(target, buffer_size, &target_buffer); + if (ret) { + LOG_ERROR("DW SPI could not allocate working area. Need %zx", + total_working_area_size); + goto err_target_buffer; + } + + // write algorithm code and buffer to working areas + ret = target_write_buffer(target, helper->address, target_code_size, + target_code); + if (ret) { + LOG_ERROR("DW SPI writing to working area error"); + goto err_write_buffer; + } + + ret = target_write_buffer(target, target_buffer->address, buffer_size, + buffer); + if (ret) { + LOG_ERROR("DW SPI writing to working area error"); + goto err_write_buffer; + } + + // prepare helper execution + struct mips32_algorithm mips32_algo = { .common_magic = MIPS32_COMMON_MAGIC, + .isa_mode = MIPS32_ISA_MIPS32 }; + + struct reg_param reg_param; + init_reg_param(®_param, DW_SPI_ARG_REG, 32, PARAM_OUT); + struct mem_param mem_param; + init_mem_param(&mem_param, helper_args->address, helper_args->size, + PARAM_OUT); + + // Set the arguments for the helper + buf_set_u32(reg_param.value, 0, 32, helper_args->address); + struct dw_spi_program *helper_args_val = + (struct dw_spi_program *)mem_param.value; + target_buffer_set_u32(target, (uint8_t *)&helper_args_val->address, + address); + target_buffer_set_u32(target, (uint8_t *)&helper_args_val->page_size, + page_size); + target_buffer_set_u32(target, (uint8_t *)&helper_args_val->buffer, + target_buffer->address); + target_buffer_set_u32(target, (uint8_t *)&helper_args_val->buffer_size, + buffer_size); + target_buffer_set_u32(target, (uint8_t *)&helper_args_val->status_reg, + regmap->simc + DW_SPI_REG_SR); + target_buffer_set_u32(target, (uint8_t *)&helper_args_val->data_reg, + regmap->simc + DW_SPI_REG_DR); + helper_args_val->read_status_cmd = stat_cmd; + helper_args_val->write_enable_cmd = we_cmd; + helper_args_val->program_cmd = program_cmd; + helper_args_val->write_enable_mask = we_mask; + helper_args_val->busy_mask = busy_mask; + helper_args_val->four_byte_mode = driver->four_byte_mode; + + ret = target_run_algorithm(target, 1, &mem_param, 1, ®_param, + helper->address, 0, driver->timeout, + &mips32_algo); + if (ret) + LOG_ERROR("DW SPI flash algorithm error"); + + destroy_reg_param(®_param); + destroy_mem_param(&mem_param); + +err_write_buffer: + target_free_working_area(target, target_buffer); +err_target_buffer: + target_free_working_area(target, helper_args); +err_helper_args: + target_free_working_area(target, helper); +err_helper: + + return ret; +} + +/** + * @brief Erase sectors. + * + * @param[in] bank: Flash bank. + * @param[in] address: Flash address. Must be sector aligned. + * @param[in] sector_size: Size of flash sector. + * @param[in] sector_count: Number of sectors to erase. + * @param[in] stat_cmd: Flash command to read chip status. + * @param[in] we_cmd: Flash command to set enable write. + * @param[in] erase_sector_cmd: Flash command to set erase sector. + * @param[in] we_mask: Status byte write enable mask. + * @param[in] busy_mask: Status byte write busy mask. + * @return Command execution status. + */ +static int +dw_spi_ctrl_erase_sectors(const struct flash_bank *const bank, uint32_t address, + uint32_t sector_size, size_t sector_count, + uint8_t stat_cmd, uint8_t we_cmd, + uint8_t erase_sector_cmd, uint8_t we_mask, + uint8_t busy_mask) +{ + struct target *const target = bank->target; + const struct dw_spi_driver *const driver = bank->driver_priv; + const struct dw_spi_regmap *const regmap = &driver->regmap; + + static const uint8_t target_code[] = { +#include "../../../contrib/loaders/flash/dw-spi/mipsel-linux-gnu-erase.inc" + }; + const size_t target_code_size = sizeof(target_code); + const size_t total_working_area_size = + target_code_size + sizeof(struct dw_spi_erase); + + // allocate working area and memory args + struct working_area *helper; + int ret = target_alloc_working_area(target, target_code_size, &helper); + if (ret) { + LOG_ERROR("DW SPI could not allocate working area. Need %zx", + total_working_area_size); + goto err_helper; + } + + struct working_area *helper_args; + ret = target_alloc_working_area(target, sizeof(struct dw_spi_erase), + &helper_args); + if (ret) { + LOG_ERROR("DW SPI could not allocate working area. Need %zx", + total_working_area_size); + goto err_helper_args; + } + + // write algorithm code to working area + ret = target_write_buffer(target, helper->address, target_code_size, + target_code); + if (ret) { + LOG_ERROR("DW SPI writing to working area error"); + goto err_write_buffer; + } + + // prepare helper execution + struct mips32_algorithm mips32_algo = { .common_magic = MIPS32_COMMON_MAGIC, + .isa_mode = MIPS32_ISA_MIPS32 }; + + struct reg_param reg_param; + init_reg_param(®_param, DW_SPI_ARG_REG, 32, PARAM_OUT); + struct mem_param mem_param; + init_mem_param(&mem_param, helper_args->address, helper_args->size, + PARAM_OUT); + + // Set the arguments for the helper + buf_set_u32(reg_param.value, 0, 32, helper_args->address); + struct dw_spi_erase *helper_args_val = + (struct dw_spi_erase *)mem_param.value; + target_buffer_set_u32(target, (uint8_t *)&helper_args_val->address, + address); + target_buffer_set_u32(target, (uint8_t *)&helper_args_val->sector_size, + sector_size); + target_buffer_set_u32(target, (uint8_t *)&helper_args_val->sector_count, + sector_count); + target_buffer_set_u32(target, (uint8_t *)&helper_args_val->status_reg, + regmap->simc + DW_SPI_REG_SR); + target_buffer_set_u32(target, (uint8_t *)&helper_args_val->data_reg, + regmap->simc + DW_SPI_REG_DR); + helper_args_val->read_status_cmd = stat_cmd; + helper_args_val->write_enable_cmd = we_cmd; + helper_args_val->erase_sector_cmd = erase_sector_cmd; + helper_args_val->write_enable_mask = we_mask; + helper_args_val->busy_mask = busy_mask; + helper_args_val->four_byte_mode = driver->four_byte_mode; + + ret = target_run_algorithm(target, 1, &mem_param, 1, ®_param, + helper->address, 0, driver->timeout, + &mips32_algo); + if (ret) + LOG_ERROR("DW SPI flash algorithm error"); + + destroy_reg_param(®_param); + destroy_mem_param(&mem_param); + +err_write_buffer: + target_free_working_area(target, helper_args); +err_helper_args: + target_free_working_area(target, helper); +err_helper: + + return ret; +} + +/** + * @brief Read flash data. + * + * @param[in] bank: Flash bank. + * @param[in] address: Flash address. + * @param[out] buffer: Data buffer. + * @param[in] buffer_size: \p buffer size. + * @param[in] read_cmd: Flash command to read data from flash. + * @return Command execution status. + */ +static int +dw_spi_ctrl_read(const struct flash_bank *const bank, uint32_t address, + uint8_t *buffer, size_t buffer_size, uint8_t read_cmd) +{ + struct target *const target = bank->target; + const struct dw_spi_driver *const driver = bank->driver_priv; + const struct dw_spi_regmap *const regmap = &driver->regmap; + + static const uint8_t target_code[] = { +#include "../../../contrib/loaders/flash/dw-spi/mipsel-linux-gnu-read.inc" + }; + const size_t target_code_size = sizeof(target_code); + const size_t total_working_area_size = + target_code_size + sizeof(struct dw_spi_read) + buffer_size; + + // allocate working area and memory args + struct working_area *helper; + int ret = target_alloc_working_area(target, target_code_size, &helper); + if (ret) { + LOG_ERROR("DW SPI could not allocate working area. Need %zx", + total_working_area_size); + goto err_helper; + } + + struct working_area *helper_args; + ret = target_alloc_working_area(target, sizeof(struct dw_spi_read), + &helper_args); + if (ret) { + LOG_ERROR("DW SPI could not allocate working area. Need %zx", + total_working_area_size); + goto err_helper_args; + } + + struct working_area *target_buffer; + ret = target_alloc_working_area(target, buffer_size, &target_buffer); + if (ret) { + LOG_ERROR("DW SPI could not allocate working area. Need %zx", + total_working_area_size); + goto err_target_buffer; + } + + // write algorithm code to working area + ret = target_write_buffer(target, helper->address, target_code_size, + target_code); + if (ret) { + LOG_ERROR("DW SPI writing to working area error"); + goto err_write_buffer; + } + + // prepare helper execution + struct mips32_algorithm mips32_algo = { .common_magic = MIPS32_COMMON_MAGIC, + .isa_mode = MIPS32_ISA_MIPS32 }; + + struct reg_param reg_param; + init_reg_param(®_param, DW_SPI_ARG_REG, 32, PARAM_OUT); + struct mem_param mem_param; + init_mem_param(&mem_param, helper_args->address, helper_args->size, + PARAM_OUT); + + // Set the arguments for the helper + buf_set_u32(reg_param.value, 0, 32, helper_args->address); + struct dw_spi_read *helper_args_val = (struct dw_spi_read *)mem_param.value; + target_buffer_set_u32(target, (uint8_t *)&helper_args_val->address, + address); + target_buffer_set_u32(target, (uint8_t *)&helper_args_val->buffer, + target_buffer->address); + target_buffer_set_u32(target, (uint8_t *)&helper_args_val->buffer_size, + buffer_size); + target_buffer_set_u32(target, (uint8_t *)&helper_args_val->status_reg, + regmap->simc + DW_SPI_REG_SR); + target_buffer_set_u32(target, (uint8_t *)&helper_args_val->data_reg, + regmap->simc + DW_SPI_REG_DR); + helper_args_val->read_cmd = read_cmd; + helper_args_val->four_byte_mode = driver->four_byte_mode; + + ret = target_run_algorithm(target, 1, &mem_param, 1, ®_param, + helper->address, 0, driver->timeout, + &mips32_algo); + if (ret) { + LOG_ERROR("DW SPI flash algorithm error"); + goto cleanup; + } + + ret = + target_read_buffer(target, target_buffer->address, buffer_size, buffer); + if (ret) + LOG_ERROR("DW SPI target buffer read error"); + +cleanup: + destroy_reg_param(®_param); + destroy_mem_param(&mem_param); + +err_write_buffer: + target_free_working_area(target, target_buffer); +err_target_buffer: + target_free_working_area(target, helper_args); +err_helper_args: + target_free_working_area(target, helper); +err_helper: + + return ret; +} + +/** + * @brief Read Flash device ID. + * + * @param[in] bank: Flash bank handle. + * @return Command execution status. + */ +static int +dw_spi_read_id(const struct flash_bank *const bank) +{ + struct dw_spi_driver *const driver = bank->driver_priv; + + const size_t buffer_size = 1 + 3 + 1; + uint8_t buffer[buffer_size]; + + memset(buffer, 0, buffer_size); + buffer[0] = SPIFLASH_READ_ID; + + int ret = dw_spi_ctrl_transaction(bank, buffer, buffer_size, true); + if (ret) { + LOG_ERROR("DW SPI flash ID read error"); + return ret; + } + + buffer[buffer_size - 1] = 0; + // use le_to_h_u32 to decode flash ID as per JEDEC SFDP + driver->id = le_to_h_u32(buffer + 1); + LOG_DEBUG("DW SPI read flash ID %" PRIx32, driver->id); + + return ERROR_OK; +} + +/** + * @brief Read Flash device status. + * + * @param[in] bank: Flash bank handle. + * @param[out] status: The status byte. + * @return Command execution status. + */ +static int +dw_spi_read_status(const struct flash_bank *const bank, uint8_t *const status) +{ + const int buffer_size = 2; + uint8_t buffer[buffer_size]; + + memset(buffer, 0, buffer_size); + buffer[0] = SPIFLASH_READ_STATUS; + + int ret = dw_spi_ctrl_transaction(bank, buffer, buffer_size, true); + if (ret) { + LOG_ERROR("DW SPI flash status read error"); + return ret; + } + + *status = buffer[1]; + + return ERROR_OK; +} + +/** + * @brief Wait for Flash command to finish. + * + * @param[in] bank: Flash bank handle. + * @param[in] timeout: The timeout in ms. + * @return Command execution status. + */ +static int +dw_spi_wait_finish(const struct flash_bank *const bank, unsigned int timeout) +{ + const int64_t end_time = timeval_ms() + timeout; + while (timeval_ms() <= end_time) { + uint8_t status; + int ret = dw_spi_read_status(bank, &status); + if (ret) { + LOG_ERROR("DW SPI status query error"); + return ret; + } + if (!(status & SPIFLASH_BSY_BIT)) + return ERROR_OK; + + alive_sleep(1); + } + + LOG_ERROR("DW SPI process timeout"); + return ERROR_TIMEOUT_REACHED; +} + +/** + * @brief Flash device write enable. + * + * @param[in] bank: Flash bank handle. + * @return Command execution status. + */ +static int +dw_spi_write_enable(const struct flash_bank *const bank) +{ + const int buffer_size = 1; + uint8_t buffer[buffer_size]; + + memset(buffer, 0, buffer_size); + buffer[0] = SPIFLASH_WRITE_ENABLE; + + int ret = dw_spi_ctrl_transaction(bank, buffer, buffer_size, false); + if (ret) { + LOG_ERROR("DW SPI flash write enable error"); + return ret; + } + + uint8_t status; + ret = dw_spi_read_status(bank, &status); + if (ret) + return ret; + + return status & SPIFLASH_WE_BIT ? ERROR_OK : ERROR_FAIL; +} + +/** + * @brief Erase Flash chip. + * + * @param[in] bank: Flash bank handle. + * @return Command execution status. + */ +static int +dw_spi_erase_chip(const struct flash_bank *const bank) +{ + const struct dw_spi_driver *const driver = bank->driver_priv; + + const int buffer_size = 1; + uint8_t buffer[buffer_size]; + + int ret = dw_spi_write_enable(bank); + if (ret) + return ret; + + memset(buffer, 0, buffer_size); + buffer[0] = driver->spi_flash->chip_erase_cmd; + + ret = dw_spi_ctrl_transaction(bank, buffer, buffer_size, false); + if (ret) { + LOG_ERROR("DW SPI erase flash error"); + return ret; + } + + ret = dw_spi_wait_finish(bank, driver->timeout); + if (ret) { + LOG_ERROR("DW SPI erase flash timeout"); + return ret; + } + + return ERROR_OK; +} + +/** + * @brief Flash device erase sectors. + * + * @param[in] bank: Flash bank handle. + * @param[in] first: The first sector to erase. + * @param[in] last: The last sector to erase. + * @return Command execution status. + */ +static int +dw_spi_erase_sectors(const struct flash_bank *const bank, unsigned int first, + unsigned int last) +{ + const struct dw_spi_driver *const driver = bank->driver_priv; + + if (first == 0 && last >= (bank->num_sectors - 1)) { + // full erase + int ret = dw_spi_erase_chip(bank); + if (ret) + return ret; + } else { + // partial erase + int ret = dw_spi_ctrl_erase_sectors(bank, bank->sectors[first].offset, + driver->spi_flash->sectorsize, + last - first + 1, + SPIFLASH_READ_STATUS, + SPIFLASH_WRITE_ENABLE, + driver->spi_flash->erase_cmd, + SPIFLASH_WE_BIT, SPIFLASH_BSY_BIT); + if (ret) { + LOG_ERROR("DW SPI flash erase sectors error"); + return ret; + } + } + + return ERROR_OK; +} + +/** + * @brief Flash bank blank check. + */ +static int +dw_spi_blank_check(struct flash_bank *bank, size_t sector_count, + uint8_t pattern) +{ + const struct dw_spi_driver *const driver = bank->driver_priv; + + uint8_t *erased = malloc(sector_count); + if (!erased) { + LOG_ERROR("could not allocate memory"); + return ERROR_FAIL; + } + + // set initial erased value to unknown + memset(erased, 2, sector_count); + for (unsigned int sector_idx = 0; sector_idx < sector_count; sector_idx++) + bank->sectors[sector_idx].is_erased = 2; + + int ret = dw_spi_ctrl_check_sectors_fill(bank, 0, bank->sectors[0].size, + sector_count, pattern, + driver->spi_flash->read_cmd, + erased); + if (!ret) { + for (unsigned int sector_idx = 0; sector_idx < sector_count; + sector_idx++) + bank->sectors[sector_idx].is_erased = erased[sector_idx]; + } else { + LOG_ERROR("DW SPI flash erase check error"); + } + + free(erased); + + return ret; +} + +/** + * @brief Write buffer to Flash. + * + * @param[in] bank: Flash bank handle. + * @param[in] buffer: Data buffer. + * @param[in] offset: Flash address offset. + * @param[in] count: \p buffer size. + * @return Command execution status. + */ +static int +dw_spi_write_buffer(const struct flash_bank *const bank, const uint8_t *buffer, + uint32_t offset, uint32_t count) +{ + const struct dw_spi_driver *const driver = bank->driver_priv; + const size_t page_size = driver->spi_flash->pagesize; + + // Write unaligned first sector separately as helper function does + // not handle this case well. + struct { + uint32_t address; + const uint8_t *buffer; + size_t count; + } chunks[2] = { + { .address = offset, .buffer = buffer, .count = 0 }, + { .address = offset, .buffer = buffer, .count = count }, + }; + + if (offset % page_size) { + // start is not aligned + chunks[0].count = MIN(page_size - (offset % page_size), count); + chunks[1].count -= chunks[0].count; + chunks[1].address += chunks[0].count; + chunks[1].buffer += chunks[0].count; + } + + for (unsigned int chunk_idx = 0; chunk_idx < ARRAY_SIZE(chunks); + chunk_idx++) { + if (chunks[chunk_idx].count > 0) { + int ret = dw_spi_ctrl_program(bank, chunks[chunk_idx].address, + chunks[chunk_idx].buffer, + chunks[chunk_idx].count, page_size, + SPIFLASH_READ_STATUS, + SPIFLASH_WRITE_ENABLE, + driver->spi_flash->pprog_cmd, + SPIFLASH_WE_BIT, SPIFLASH_BSY_BIT); + if (ret) { + LOG_ERROR("DW SPI flash write error"); + return ret; + } + } + } + + return ERROR_OK; +} + +/** + * @brief Search for Flash chip info. + * + * @param[in] bank: Flash bank handle. + * @return Command execution status. + */ +static int +dw_spi_spiflash_search(const struct flash_bank *const bank) +{ + struct dw_spi_driver *const driver = bank->driver_priv; + + int ret = dw_spi_read_id(bank); + if (ret) + return ret; + + unsigned int idx = 0; + while (flash_devices[idx].name) { + if (flash_devices[idx].device_id == driver->id) { + driver->spi_flash = &flash_devices[idx]; + return ERROR_OK; + } + idx++; + } + + LOG_ERROR("DW SPI could not find Flash with ID %" PRIx32 + " in SPI Flash table: either Flash device is not supported " + "or communication speed is too high", + driver->id); + return ERROR_FAIL; +} + +/** + * @brief Handle flash bank command. + * + * @param[in] CMD_ARGC: Number of arguments. + * @param[in] CMD_ARGV: Command arguments. + * @return Command execution status. + */ +FLASH_BANK_COMMAND_HANDLER(dw_spi_flash_bank_command) +{ + unsigned int speed = 1000000; + unsigned int timeout = DW_SPI_TIMEOUT_DEFAULT; + uint8_t chip_select_bitmask = BIT(0); + struct dw_spi_regmap regmap = { 0 }; + + if (CMD_ARGC < 6) + return ERROR_COMMAND_SYNTAX_ERROR; + + for (unsigned int idx = 6; idx < CMD_ARGC; idx++) { + if (strcmp(CMD_ARGV[idx], "-jaguar2") == 0) { + // Fast config for Jaguar2 chips. + memcpy(®map, &jaguar2_regmap, sizeof(jaguar2_regmap)); + } else if (strcmp(CMD_ARGV[idx], "-ocelot") == 0) { + // Fast config for Ocelot chips. + memcpy(®map, &ocelot_regmap, sizeof(ocelot_regmap)); + } else if (strcmp(CMD_ARGV[idx], "-freq") == 0) { + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[++idx], regmap.freq); + } else if (strcmp(CMD_ARGV[idx], "-simc") == 0) { + COMMAND_PARSE_NUMBER(target_addr, CMD_ARGV[++idx], regmap.simc); + } else if (strcmp(CMD_ARGV[idx], "-spi_mst") == 0) { + COMMAND_PARSE_NUMBER(target_addr, CMD_ARGV[++idx], regmap.spi_mst); + } else if (strcmp(CMD_ARGV[idx], "-if_owner_offset") == 0) { + COMMAND_PARSE_NUMBER(u8, CMD_ARGV[++idx], + regmap.si_if_owner_offset); + } else if (strcmp(CMD_ARGV[idx], "-speed") == 0) { + COMMAND_PARSE_NUMBER(uint, CMD_ARGV[++idx], speed); + } else if (strcmp(CMD_ARGV[idx], "-timeout") == 0) { + COMMAND_PARSE_NUMBER(uint, CMD_ARGV[++idx], timeout); + timeout *= 1000; // convert to ms + } else if (strcmp(CMD_ARGV[idx], "-chip_select") == 0) { + unsigned int cs_bit; + COMMAND_PARSE_NUMBER(uint, CMD_ARGV[++idx], cs_bit); + chip_select_bitmask = BIT(cs_bit); + } else { + LOG_WARNING("DW SPI unknown argument %s", CMD_ARGV[idx]); + } + } + + if (!regmap.simc) { + LOG_ERROR("DW SPI cannot use boot controller with unconfigured simc"); + return ERROR_COMMAND_SYNTAX_ERROR; + } + + bank->driver_priv = malloc(sizeof(struct dw_spi_driver)); + if (!bank->driver_priv) { + LOG_ERROR("could not allocate memory"); + return ERROR_FAIL; + } + + struct dw_spi_driver *driver = bank->driver_priv; + memset(driver, 0, sizeof(struct dw_spi_driver)); + driver->speed = speed; + driver->timeout = timeout; + driver->chip_select_bitmask = chip_select_bitmask; + driver->four_byte_mode = true; // 24bit commands not provided by spi.h + memcpy(&driver->regmap, ®map, sizeof(regmap)); + + return ERROR_OK; +} + +/** + * @brief Assert target is halted. + * + * @param[in] bank: Flash bank handle. + * @return Command execution status. + */ +static int +dw_spi_assert_halted(const struct flash_bank *const bank) +{ + if (bank->target->state != TARGET_HALTED) { + LOG_ERROR("target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + return ERROR_OK; +} + +/** + * @brief Prepare master controller for transaction. + * + * @param[in] bank: Flash bank handle. + * @return Command execution status. + */ +static int +dw_spi_master_ctrl_configure(struct flash_bank *bank) +{ + int ret = dw_spi_assert_halted(bank); + if (ret) + return ret; + ret = dw_spi_ctrl_mode_configure(bank, DW_SPI_SI_MODE_MASTER); + if (ret) { + LOG_ERROR("DW SPI switch to master controller mode error"); + return ret; + } + ret = dw_spi_master_ctrl_enable(bank, false); + if (ret) { + LOG_ERROR("DW SPI disable master controller error"); + return ret; + } + ret = dw_spi_ctrl_configure_speed(bank); + if (ret) { + LOG_ERROR("DW SPI speed configuration error"); + return ret; + } + ret = dw_spi_ctrl_disable_interrupts(bank); + if (ret) { + LOG_ERROR("DW SPI disable SPI interrupts error"); + return ret; + } + ret = dw_spi_ctrl_configure_si(bank); + if (ret) { + LOG_ERROR("DW SPI controller configuration error"); + return ret; + } + ret = dw_spi_master_ctrl_enable(bank, true); + if (ret) { + LOG_ERROR("DW SPI enable master controller error"); + return ret; + } + + return ERROR_OK; +} + +/** + * @brief Restore SI controller selection. + * + * @param[in] bank: Flash bank handle. + * @return Command execution status. + */ +static int +dw_spi_master_ctrl_restore(struct flash_bank *bank) +{ + int ret = dw_spi_master_ctrl_enable(bank, false); + if (ret) { + LOG_ERROR("DW SPI disable master controller error"); + return ret; + } + ret = dw_spi_ctrl_mode_restore(bank); + if (ret) { + LOG_ERROR("DW SPI controller restore error"); + return ret; + } + + return ret; +} + +/** + * @brief Flash bank probe. + * + * @param[in] bank: Flash bank handle. + * @return Command execution status. + */ +static int +dw_spi_probe(struct flash_bank *bank) +{ + struct dw_spi_driver *const driver = bank->driver_priv; + + if (!driver) + return ERROR_FAIL; + + if (strcmp(bank->target->type->name, mips_m4k_target.name) != 0 || + bank->target->endianness != TARGET_LITTLE_ENDIAN) { + LOG_ERROR("DW SPI currently only supports " + "little endian mips_m4k target"); + return ERROR_TARGET_INVALID; + } + + int ret = dw_spi_master_ctrl_configure(bank); + if (ret) + return ret; + + ret = dw_spi_spiflash_search(bank); + if (ret) + goto err; + + bank->write_start_alignment = 0; + bank->write_end_alignment = 0; + + uint32_t flash_size = driver->spi_flash->size_in_bytes; + if (!bank->size) { + bank->size = flash_size; + LOG_INFO("DW SPI probed flash size 0x%" PRIx32, flash_size); + } else { + if (flash_size > bank->size) + LOG_WARNING("DW SPI probed flash size 0x%" PRIx32 + " is greater then declared 0x%" PRIx32, + flash_size, bank->size); + if (flash_size < bank->size) { + LOG_ERROR("DW SPI probed flash size 0x%" PRIx32 + " is smaller then declared 0x%" PRIx32, + flash_size, bank->size); + ret = ERROR_FLASH_BANK_INVALID; + goto err; + } + } + bank->num_sectors = bank->size / driver->spi_flash->sectorsize; + + // free previously allocated in case of reprobing + free(bank->sectors); + + bank->sectors = + alloc_block_array(0, driver->spi_flash->sectorsize, bank->num_sectors); + + if (!bank->sectors) { + LOG_ERROR("could not allocate memory"); + ret = ERROR_FAIL; + goto err; + } + + driver->probed = true; + +err: + dw_spi_master_ctrl_restore(bank); + return ret; +} + +/** + * @brief Flash bank erase sectors. + * + * @param[in] bank: Flash bank handle. + * @param[in] first: The first sector to erase. + * @param[in] last: The last sector to erase. + * @return Command execution status. + */ +static int +dw_spi_erase(struct flash_bank *bank, unsigned int first, unsigned int last) +{ + int ret = dw_spi_master_ctrl_configure(bank); + if (ret) + return ret; + + ret = dw_spi_erase_sectors(bank, first, last); + dw_spi_master_ctrl_restore(bank); + return ret; +} + +/** + * @brief Flash bank write data. + * + * @param[in] bank: Flash bank handle. + * @param[in] buffer: Data buffer. + * @param[in] offset: Flash address offset. + * @param[in] count: \p buffer size. + * @return Command execution status. + */ +static int +dw_spi_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, + uint32_t count) +{ + int ret = dw_spi_master_ctrl_configure(bank); + if (ret) + return ret; + + ret = dw_spi_write_buffer(bank, buffer, offset, count); + dw_spi_master_ctrl_restore(bank); + return ret; +} + +/** + * @brief Flash bank read data using master controller. + * + * @param[in] bank: Flash bank handle. + * @param[out] buffer: Data buffer. + * @param[in] offset: Flash address offset. + * @param[in] count: \p buffer size. + * @return Command execution status. + */ +static int +dw_spi_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, + uint32_t count) +{ + struct dw_spi_driver *const driver = bank->driver_priv; + + int ret = dw_spi_master_ctrl_configure(bank); + if (ret) + return ret; + + ret = dw_spi_ctrl_read(bank, offset, buffer, count, + driver->spi_flash->read_cmd); + dw_spi_master_ctrl_restore(bank); + return ret; +} + +/** + * @brief Flash bank erase check. + * + * @param[in] bank: Flash bank handle. + * @return Command execution status. + */ +static int +dw_spi_erase_check(struct flash_bank *bank) +{ + int ret = dw_spi_master_ctrl_configure(bank); + if (ret) + return ret; + + ret = dw_spi_blank_check(bank, bank->num_sectors, bank->erased_value); + + dw_spi_master_ctrl_restore(bank); + return ret; +} + +/** + * @brief Flash bank info. + * + * @param[in] bank: Flash bank handle. + * @param[in,out] cmd Command invocation. + * @return Command execution status. + */ +static int +dw_spi_info(struct flash_bank *bank, struct command_invocation *cmd) +{ + const struct dw_spi_driver *const driver = bank->driver_priv; + command_print(cmd, "model %s", driver->spi_flash->name); + command_print(cmd, "ID 0x%" PRIx32, driver->id); + command_print_sameline(cmd, "size 0x%" PRIx32, bank->size); + return ERROR_OK; +} + +/** + * @brief Autoprobe driver. + * + * @param[in] bank: Flash bank handle. + * @return Command execution status. + */ +static int +dw_spi_auto_probe(struct flash_bank *bank) +{ + struct dw_spi_driver *driver = bank->driver_priv; + if (!driver) + return ERROR_FAIL; + if (!driver->probed) + return dw_spi_probe(bank); + return ERROR_OK; +} + +/** + * @brief DW-SPI NOR flash functions. + */ +const struct flash_driver dw_spi_flash = { + .name = "dw-spi", + .flash_bank_command = dw_spi_flash_bank_command, + .erase = dw_spi_erase, + .write = dw_spi_write, + .read = dw_spi_read, + .probe = dw_spi_probe, + .auto_probe = dw_spi_auto_probe, + .erase_check = dw_spi_erase_check, + .info = dw_spi_info, + .verify = default_flash_verify, + .free_driver_priv = default_flash_free_driver_priv, +}; From 7f2db80ebc168d74a56dc8b76be5355ee4878be6 Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Sat, 7 Dec 2024 10:53:56 +0100 Subject: [PATCH 03/29] rtos/hwthread: Use LOG_TARGET_xxx() Use LOG_TARGET_xxx() to indicate which target the message belongs to. While at it, fix some coding style issues. Change-Id: Iac0296498557a689468a4a19d0bc64f03178a0d0 Signed-off-by: Marc Schink Reviewed-on: https://review.openocd.org/c/openocd/+/8727 Reviewed-by: Antonio Borneo Reviewed-by: Tomas Vanek Tested-by: jenkins --- src/rtos/hwthread.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/rtos/hwthread.c b/src/rtos/hwthread.c index c9f1a1792..6332bd8ad 100644 --- a/src/rtos/hwthread.c +++ b/src/rtos/hwthread.c @@ -119,7 +119,7 @@ static int hwthread_update_threads(struct rtos *rtos) if (current_threadid <= thread_list_size) rtos->current_threadid = current_threadid; else - LOG_WARNING("SMP node change, disconnect GDB from core/thread %" PRId64, + LOG_TARGET_WARNING(target, "SMP node change, disconnect GDB from core/thread %" PRId64, current_threadid); /* create space for new thread details */ @@ -204,7 +204,8 @@ static int hwthread_update_threads(struct rtos *rtos) else rtos->current_thread = threadid_from_target(target); - LOG_DEBUG("%s current_thread=%i", __func__, (int)rtos->current_thread); + LOG_TARGET_DEBUG(target, "%s current_thread=%i", __func__, + (int)rtos->current_thread); return 0; } @@ -270,7 +271,8 @@ static int hwthread_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, if (!reg_list[i]->valid) { retval = reg_list[i]->type->get(reg_list[i]); if (retval != ERROR_OK) { - LOG_ERROR("Couldn't get register %s.", reg_list[i]->name); + LOG_TARGET_ERROR(curr, "Couldn't get register %s", + reg_list[i]->name); free(reg_list); free(*rtos_reg_list); return retval; @@ -297,7 +299,8 @@ static int hwthread_get_thread_reg(struct rtos *rtos, int64_t thread_id, struct target *curr = hwthread_find_thread(target, thread_id); if (!curr) { - LOG_ERROR("Couldn't find RTOS thread for id %" PRId64 ".", thread_id); + LOG_TARGET_ERROR(target, "Couldn't find RTOS thread for id %" PRId64, + thread_id); return ERROR_FAIL; } @@ -308,8 +311,8 @@ static int hwthread_get_thread_reg(struct rtos *rtos, int64_t thread_id, struct reg *reg = register_get_by_number(curr->reg_cache, reg_num, true); if (!reg) { - LOG_ERROR("Couldn't find register %" PRIu32 " in thread %" PRId64 ".", reg_num, - thread_id); + LOG_TARGET_ERROR(curr, "Couldn't find register %" PRIu32 " in thread %" PRId64, + reg_num, thread_id); return ERROR_FAIL; } @@ -372,17 +375,17 @@ static bool hwthread_detect_rtos(struct target *target) static int hwthread_thread_packet(struct connection *connection, const char *packet, int packet_size) { - struct target *target = get_target_from_connection(connection); - - struct target *curr = NULL; - int64_t current_threadid; - if (packet[0] == 'H' && packet[1] == 'g') { + int64_t current_threadid; sscanf(packet, "Hg%16" SCNx64, ¤t_threadid); + struct target *target = get_target_from_connection(connection); + if (current_threadid > 0) { + struct target *curr = NULL; if (hwthread_target_for_threadid(connection, current_threadid, &curr) != ERROR_OK) { - LOG_ERROR("hwthread: cannot find thread id %"PRId64, current_threadid); + LOG_TARGET_ERROR(target, "hwthread: cannot find thread id %" PRId64, + current_threadid); gdb_put_packet(connection, "E01", 3); return ERROR_FAIL; } @@ -402,7 +405,7 @@ static int hwthread_thread_packet(struct connection *connection, const char *pac static int hwthread_create(struct target *target) { - LOG_INFO("Hardware thread awareness created"); + LOG_TARGET_INFO(target, "Hardware thread awareness created"); target->rtos->rtos_specific_params = NULL; target->rtos->current_thread = 0; From 7dd875900ec252b5f332298cef3030f67a37150f Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Mon, 3 Feb 2025 20:23:08 +0100 Subject: [PATCH 04/29] drivers/linuxspidev: fix minor memory leak free() strduped spi_path on quit. Found by valgrind. Change-Id: Iaa59c7258c920b5e60d615df790dfe815831b925 Signed-off-by: Tomas Vanek Fixes: 83e0293f7ba3 ("Add Linux SPI device SWD adapter support") Reviewed-on: https://review.openocd.org/c/openocd/+/8732 Tested-by: jenkins Reviewed-by: Antonio Borneo Reviewed-by: Richard Pasek --- src/jtag/drivers/linuxspidev.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/jtag/drivers/linuxspidev.c b/src/jtag/drivers/linuxspidev.c index 737d2bef8..94a0c510a 100644 --- a/src/jtag/drivers/linuxspidev.c +++ b/src/jtag/drivers/linuxspidev.c @@ -337,6 +337,10 @@ static int spidev_quit(void) close(spi_fd); spi_fd = -1; + + free(spi_path); + spi_path = NULL; + return ERROR_OK; } From 82277462b91506a9e7ee4bdcee86d6b414d59149 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Mon, 3 Feb 2025 20:28:49 +0100 Subject: [PATCH 05/29] drivers/linuxspidev: fix use of uninitialized speed variable Valgrind reported == Syscall param ioctl(generic) points to uninitialised byte(s) == at 0x4ABF990: ioctl (ioctl.S:26) == by 0x19D00B: spidev_speed (linuxspidev.c:181) == by 0x19D00B: spidev_init (linuxspidev.c:307) Indeed, spidev_init() uses adapter_get_speed(), it calls adapter_khz_to_speed() and it returns early without setting the output parameter if adapter is not initialized. Of course the adapter initialized flag is not set until spidev_init() returns. Simply drop this code as the adapter infrastructure initializes adapter speed just after spidev_init() return. Change-Id: I26f011ae59fc942a34d9bb517f467c22f735091d Signed-off-by: Tomas Vanek Fixes: 83e0293f7ba3 ("Add Linux SPI device SWD adapter support") Reviewed-on: https://review.openocd.org/c/openocd/+/8733 Tested-by: jenkins Reviewed-by: Richard Pasek --- src/jtag/drivers/linuxspidev.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/jtag/drivers/linuxspidev.c b/src/jtag/drivers/linuxspidev.c index 94a0c510a..73d5e8bed 100644 --- a/src/jtag/drivers/linuxspidev.c +++ b/src/jtag/drivers/linuxspidev.c @@ -307,18 +307,6 @@ static int spidev_init(void) LOG_INFO("Opened SPI device at %s in mode 0x%" PRIx32 " with %" PRIu8 " bits ", spi_path, spi_mode, spi_bits); - // Set SPI read and write max speed. - int speed; - ret = adapter_get_speed(&speed); - if (ret != ERROR_OK) { - LOG_ERROR("Failed to get adapter speed"); - return ERROR_JTAG_INIT_FAILED; - } - - ret = spidev_speed(speed); - if (ret != ERROR_OK) - return ERROR_JTAG_INIT_FAILED; - if (max_queue_entries == 0) { ret = spidev_alloc_queue(MAX_QUEUE_ENTRIES); if (ret != ERROR_OK) From d09f53a930676817a49ae7c575c705487ea51861 Mon Sep 17 00:00:00 2001 From: Richard Pasek Date: Thu, 30 Jan 2025 05:38:08 -0500 Subject: [PATCH 06/29] driver/linuxspidev: Clear queue on allocation SWD idle clocks are added to the queue by advancing the queue index assuming the queue is zeroed. If the queue isn't zeroed, these idle clocks end up being filled with junk data. Lets clear the queue and associated buffers on queue allocation. TEST: Connects successfully and ran the following TCL command: dump_image /dev/null 0x20000000 0x42000 Host: Unnamed Qualcomm SoC with QUPv3 based SPI port Target: RT500 Signed-off-by: Richard Pasek Change-Id: Ie660c10c27c4d0937ab0629138935ddbf5aeb0ae Fixes: 83e0293f7ba3 ("Add Linux SPI device SWD adapter support") Reviewed-on: https://review.openocd.org/c/openocd/+/8730 Reviewed-by: Tomas Vanek Reviewed-by: Jonathon Reinhart Tested-by: jenkins --- src/jtag/drivers/linuxspidev.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/jtag/drivers/linuxspidev.c b/src/jtag/drivers/linuxspidev.c index 73d5e8bed..6a149a977 100644 --- a/src/jtag/drivers/linuxspidev.c +++ b/src/jtag/drivers/linuxspidev.c @@ -230,10 +230,21 @@ static void spidev_free_queue(void) tx_flip_buf = NULL; } +static void spidev_clear_queue(void) +{ + queue_fill = 0; + queue_buf_fill = 0; + + memset(queue_infos, 0, sizeof(struct queue_info) * max_queue_entries); + memset(queue_tx_buf, 0, queue_buf_size); + memset(queue_rx_buf, 0, queue_buf_size); + memset(tx_flip_buf, 0, queue_buf_size); +} + static int spidev_alloc_queue(unsigned int new_queue_entries) { if (queue_fill || queue_buf_fill) { - LOG_ERROR("Can't realloc allocate queue when queue is in use"); + LOG_ERROR("Can't realloc queue when queue is in use"); return ERROR_FAIL; } @@ -259,6 +270,8 @@ static int spidev_alloc_queue(unsigned int new_queue_entries) max_queue_entries = new_queue_entries; queue_buf_size = new_queue_buf_size; + spidev_clear_queue(); + LOG_DEBUG("Set queue entries to %u (buffers %u bytes)", max_queue_entries, queue_buf_size); return ERROR_OK; @@ -400,12 +413,7 @@ static int spidev_swd_execute_queue(unsigned int end_idle_bytes) } skip: - // Clear everything in the queue - queue_fill = 0; - queue_buf_fill = 0; - memset(queue_infos, 0, sizeof(queue_infos[0]) * max_queue_entries); - memset(queue_tx_buf, 0, queue_buf_size); - memset(queue_rx_buf, 0, queue_buf_size); + spidev_clear_queue(); int retval = queue_retval; queue_retval = ERROR_OK; From 73e9b7898f5518e0cfe7bc2f66d135736558a9fd Mon Sep 17 00:00:00 2001 From: Samuel Obuch Date: Tue, 11 Feb 2025 09:56:38 +0100 Subject: [PATCH 07/29] github/workflow: build jimtcl from sources JimTCL submodule was deprecated, this patch modifies the GitHub snapshot action to build from sources instead. Change-Id: Ie9ab20dbfd70506992d11a91489e82a9fa6e13ce Signed-off-by: Samuel Obuch Reviewed-on: https://review.openocd.org/c/openocd/+/8751 Reviewed-by: Marc Schink Tested-by: jenkins Reviewed-by: Antonio Borneo Reviewed-by: Erhan Kurubas --- .github/workflows/snapshot.yml | 15 ++++++++++++--- contrib/cross-build.sh | 15 +++++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml index f5cf56459..36b2f3bb3 100644 --- a/.github/workflows/snapshot.yml +++ b/.github/workflows/snapshot.yml @@ -18,7 +18,7 @@ jobs: sudo apt-get update sudo apt-get install autotools-dev autoconf automake libtool pkg-config cmake texinfo texlive g++-mingw-w64-i686 - name: Checkout Code - uses: actions/checkout@v1 + uses: actions/checkout@v4 - run: ./bootstrap - name: Prepare libusb1 env: @@ -66,6 +66,14 @@ jobs: cd libjaylink-${LIBJAYLINK_VER} ./autogen.sh echo "LIBJAYLINK_SRC=$PWD" >> $GITHUB_ENV + - name: Prepare jimtcl + env: + JIMTCL_VER: 0.83 + run: | + mkdir -p $DL_DIR && cd $DL_DIR + wget https://github.com/msteveb/jimtcl/archive/refs/tags/${JIMTCL_VER}.tar.gz + tar -xzf ${JIMTCL_VER}.tar.gz + echo "JIMTCL_SRC=$PWD/jimtcl-${JIMTCL_VER}" >> $GITHUB_ENV - name: Package OpenOCD for windows env: MAKE_JOBS: 2 @@ -75,6 +83,7 @@ jobs: LIBFTDI_CONFIG: -DSTATICLIBS=OFF -DEXAMPLES=OFF -DFTDI_EEPROM=OFF CAPSTONE_CONFIG: "CAPSTONE_BUILD_CORE_ONLY=yes CAPSTONE_STATIC=yes CAPSTONE_SHARED=no" LIBJAYLINK_CONFIG: --enable-shared --disable-static + JIMTCL_CONFIG: --with-ext=json --minimal --disable-ssl run: | # check if there is tag pointing at HEAD, otherwise take the HEAD SHA-1 as OPENOCD_TAG OPENOCD_TAG="`git tag --points-at HEAD`" @@ -102,11 +111,11 @@ jobs: echo "IS_PRE_RELEASE=$IS_PRE_RELEASE" >> $GITHUB_ENV echo "ARTIFACT_PATH=$PWD/$ARTIFACT" >> $GITHUB_ENV - name: Publish OpenOCD packaged for windows - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: path: ${{ env.ARTIFACT_PATH }} - name: Delete 'latest' Release - uses: dev-drprasad/delete-tag-and-release@v0.2.1 + uses: dev-drprasad/delete-tag-and-release@v1.1 with: delete_release: true tag_name: ${{ env.RELEASE_NAME }} diff --git a/contrib/cross-build.sh b/contrib/cross-build.sh index bb8c8c47d..1784d79ad 100755 --- a/contrib/cross-build.sh +++ b/contrib/cross-build.sh @@ -42,6 +42,7 @@ WORK_DIR=$PWD : ${LIBFTDI_SRC:=/path/to/libftdi} : ${CAPSTONE_SRC:=/path/to/capstone} : ${LIBJAYLINK_SRC:=/path/to/libjaylink} +: ${JIMTCL_SRC:=/path/to/jimtcl} OPENOCD_SRC=`readlink -m $OPENOCD_SRC` LIBUSB1_SRC=`readlink -m $LIBUSB1_SRC` @@ -49,6 +50,7 @@ HIDAPI_SRC=`readlink -m $HIDAPI_SRC` LIBFTDI_SRC=`readlink -m $LIBFTDI_SRC` CAPSTONE_SRC=`readlink -m $CAPSTONE_SRC` LIBJAYLINK_SRC=`readlink -m $LIBJAYLINK_SRC` +JIMTCL_SRC=`readlink -m $JIMTCL_SRC` HOST_TRIPLET=$1 BUILD_DIR=$WORK_DIR/$HOST_TRIPLET-build @@ -57,6 +59,7 @@ HIDAPI_BUILD_DIR=$BUILD_DIR/hidapi LIBFTDI_BUILD_DIR=$BUILD_DIR/libftdi CAPSTONE_BUILD_DIR=$BUILD_DIR/capstone LIBJAYLINK_BUILD_DIR=$BUILD_DIR/libjaylink +JIMTCL_BUILD_DIR=$BUILD_DIR/jimtcl OPENOCD_BUILD_DIR=$BUILD_DIR/openocd ## Root of host file tree @@ -172,6 +175,18 @@ if [ -d $LIBJAYLINK_SRC ] ; then make install DESTDIR=$SYSROOT fi +# jimtcl build & install into sysroot +if [ -d $JIMTCL_SRC ] ; then + mkdir -p $JIMTCL_BUILD_DIR + cd $JIMTCL_BUILD_DIR + $JIMTCL_SRC/configure --host=$HOST_TRIPLET --prefix=$PREFIX \ + $JIMTCL_CONFIG + make -j $MAKE_JOBS + # Running "make" does not create this file for static builds on Windows but "make install" still expects it + touch $JIMTCL_BUILD_DIR/build-jim-ext + make install DESTDIR=$SYSROOT +fi + # OpenOCD build & install into sysroot mkdir -p $OPENOCD_BUILD_DIR cd $OPENOCD_BUILD_DIR From 6e39af3b0e17ce0376db10bdca25ce60334448cd Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 10 Jan 2025 12:13:30 +0100 Subject: [PATCH 08/29] rtt: drop useless typedefs There is no need to use extra typedef for the rtt functions. Declare the type of the functions in the struct. Change-Id: Idf2fee6e63ec3b3add38d042bbebe8d74613627c Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/8698 Tested-by: jenkins Reviewed-by: zapb --- src/rtt/rtt.h | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/src/rtt/rtt.h b/src/rtt/rtt.h index 49409074c..d84fdb40b 100644 --- a/src/rtt/rtt.h +++ b/src/rtt/rtt.h @@ -95,35 +95,27 @@ enum rtt_channel_type { RTT_CHANNEL_TYPE_DOWN }; -typedef int (*rtt_source_find_ctrl_block)(struct target *target, +/** RTT source. */ +struct rtt_source { + int (*find_cb)(struct target *target, target_addr_t *address, size_t size, const char *id, bool *found, void *user_data); -typedef int (*rtt_source_read_ctrl_block)(struct target *target, + int (*read_cb)(struct target *target, target_addr_t address, struct rtt_control *ctrl_block, void *user_data); -typedef int (*rtt_source_read_channel_info)(struct target *target, + int (*read_channel_info)(struct target *target, const struct rtt_control *ctrl, unsigned int channel, enum rtt_channel_type type, struct rtt_channel_info *info, void *user_data); -typedef int (*rtt_source_start)(struct target *target, + int (*start)(struct target *target, const struct rtt_control *ctrl, void *user_data); -typedef int (*rtt_source_stop)(struct target *target, void *user_data); -typedef int (*rtt_source_read)(struct target *target, + int (*stop)(struct target *target, void *user_data); + int (*read)(struct target *target, const struct rtt_control *ctrl, struct rtt_sink_list **sinks, size_t num_channels, void *user_data); -typedef int (*rtt_source_write)(struct target *target, + int (*write)(struct target *target, struct rtt_control *ctrl, unsigned int channel, const uint8_t *buffer, size_t *length, void *user_data); - -/** RTT source. */ -struct rtt_source { - rtt_source_find_ctrl_block find_cb; - rtt_source_read_ctrl_block read_cb; - rtt_source_read_channel_info read_channel_info; - rtt_source_start start; - rtt_source_stop stop; - rtt_source_read read; - rtt_source_write write; }; /** From 3e4512d62d1513a81905ff65f3d42477f0258f64 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 10 Jan 2025 13:40:59 +0100 Subject: [PATCH 09/29] openocd: drop useless typedef There is no need to use typedef for the array of functions. Drop it. While there, move the declaration outside the function and use the array size to drop the error-prone sentinel to NULL. Change-Id: I424964a6ef82ed1a7b27e78fbd19aa9f985b52c7 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/8699 Reviewed-by: zapb Tested-by: jenkins --- src/openocd.c | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/src/openocd.c b/src/openocd.c index 9fd709e32..3fbece395 100644 --- a/src/openocd.c +++ b/src/openocd.c @@ -232,6 +232,23 @@ static int openocd_register_commands(struct command_context *cmd_ctx) struct command_context *global_cmd_ctx; +static int (* const command_registrants[])(struct command_context *cmd_ctx_value) = { + openocd_register_commands, + server_register_commands, + gdb_register_commands, + log_register_commands, + rtt_server_register_commands, + transport_register_commands, + adapter_register_commands, + target_register_commands, + flash_register_commands, + nand_register_commands, + pld_register_commands, + cti_register_commands, + dap_register_commands, + arm_tpiu_swo_register_commands, +}; + static struct command_context *setup_command_handler(Jim_Interp *interp) { log_init(); @@ -240,25 +257,7 @@ static struct command_context *setup_command_handler(Jim_Interp *interp) struct command_context *cmd_ctx = command_init(openocd_startup_tcl, interp); /* register subsystem commands */ - typedef int (*command_registrant_t)(struct command_context *cmd_ctx_value); - static const command_registrant_t command_registrants[] = { - &openocd_register_commands, - &server_register_commands, - &gdb_register_commands, - &log_register_commands, - &rtt_server_register_commands, - &transport_register_commands, - &adapter_register_commands, - &target_register_commands, - &flash_register_commands, - &nand_register_commands, - &pld_register_commands, - &cti_register_commands, - &dap_register_commands, - &arm_tpiu_swo_register_commands, - NULL - }; - for (unsigned int i = 0; command_registrants[i]; i++) { + for (unsigned int i = 0; i < ARRAY_SIZE(command_registrants); i++) { int retval = (*command_registrants[i])(cmd_ctx); if (retval != ERROR_OK) { command_done(cmd_ctx); From 4140fa2a81b259fa99c76084fea78affb2511a08 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 10 Jan 2025 13:55:18 +0100 Subject: [PATCH 10/29] drivers: rshim: drop useless typedef Use 'struct name' instead of typedef. Change-Id: Ifff56811f53a260c314c8f5473d368599e0912e6 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/8700 Tested-by: jenkins Reviewed-by: zapb --- src/jtag/drivers/rshim.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/jtag/drivers/rshim.c b/src/jtag/drivers/rshim.c index 21fc7fd37..b37fe8c45 100644 --- a/src/jtag/drivers/rshim.c +++ b/src/jtag/drivers/rshim.c @@ -60,14 +60,14 @@ #ifdef HAVE_SYS_IOCTL_H /* Message used to program rshim via ioctl(). */ -typedef struct { +struct rshim_ioctl_msg { uint32_t addr; uint64_t data; -} __attribute__((packed)) rshim_ioctl_msg; +} __attribute__((packed)); enum { - RSH_IOC_READ = _IOWR('R', 0, rshim_ioctl_msg), - RSH_IOC_WRITE = _IOWR('R', 1, rshim_ioctl_msg), + RSH_IOC_READ = _IOWR('R', 0, struct rshim_ioctl_msg), + RSH_IOC_WRITE = _IOWR('R', 1, struct rshim_ioctl_msg), }; #endif @@ -104,7 +104,7 @@ static int rshim_dev_read(int chan, int addr, uint64_t *value) #ifdef HAVE_SYS_IOCTL_H if (rc < 0 && errno == ENOSYS) { - rshim_ioctl_msg msg; + struct rshim_ioctl_msg msg; msg.addr = addr; msg.data = 0; @@ -126,7 +126,7 @@ static int rshim_dev_write(int chan, int addr, uint64_t value) #ifdef HAVE_SYS_IOCTL_H if (rc < 0 && errno == ENOSYS) { - rshim_ioctl_msg msg; + struct rshim_ioctl_msg msg; msg.addr = addr; msg.data = value; From e325b482b11d203423b44d44dd35b89e31ffb19d Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 10 Jan 2025 15:01:20 +0100 Subject: [PATCH 11/29] target: esp_algorithm: drop useless typedefs There is no need to use extra typedef for the functions in struct esp_algorithm_run_data. Declare the type of the functions in the struct. Split the comment lines to stay in the line limits. Change-Id: I0afa6242e57133f8bf1b13ba541abd6b067350b0 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/8701 Reviewed-by: Erhan Kurubas Tested-by: jenkins --- src/target/espressif/esp_algorithm.h | 125 +++++++++++++-------------- 1 file changed, 60 insertions(+), 65 deletions(-) diff --git a/src/target/espressif/esp_algorithm.h b/src/target/espressif/esp_algorithm.h index 11d275777..185234f97 100644 --- a/src/target/espressif/esp_algorithm.h +++ b/src/target/espressif/esp_algorithm.h @@ -36,11 +36,13 @@ * Procedure of executing stub on target includes: * 1) User prepares struct esp_algorithm_run_data and calls one of algorithm_run_xxx() functions. * 2) Routine allocates all necessary stub code and data sections. - * 3) If a user specifies an initializer func esp_algorithm_usr_func_init_t it is called just before the stub starts. - * 4) If user specifies stub communication func esp_algorithm_usr_func_t (@see esp_flash_write/read in ESP flash driver) + * 3) If a user specifies an initializer func esp_algorithm_run_data::usr_func_init + * it is called just before the stub starts. + * 4) If user specifies stub communication func esp_algorithm_run_data::usr_func + * (@see esp_flash_write/read in ESP flash driver) * it is called just after the stub starts. When communication with stub is finished this function must return. * 5) OpenOCD waits for the stub to finish (hit exit breakpoint). - * 6) If the user specified arguments cleanup func esp_algorithm_usr_func_done_t, + * 6) If the user specified arguments cleanup func esp_algorithm_run_data::usr_func_done, * it is called just after the stub finishes. * * There are two options to run code on target under OpenOCD control: @@ -190,60 +192,6 @@ struct esp_algorithm_reg_args { struct esp_algorithm_run_data; -/** - * @brief Algorithm run function. - * - * @param target Pointer to target. - * @param run Pointer to algo run data. - * @param arg Function specific argument. - * - * @return ERROR_OK on success, otherwise ERROR_XXX. - */ -typedef int (*esp_algorithm_func_t)(struct target *target, struct esp_algorithm_run_data *run, void *arg); - -/** - * @brief Host part of algorithm. - * This function will be called while stub is running on target. - * It can be used for communication with stub. - * - * @param target Pointer to target. - * @param usr_arg Function specific argument. - * - * @return ERROR_OK on success, otherwise ERROR_XXX. - */ -typedef int (*esp_algorithm_usr_func_t)(struct target *target, void *usr_arg); - -/** - * @brief Algorithm's arguments setup function. - * This function will be called just before stub start. - * It must return when all operations with running stub are completed. - * It can be used to prepare stub memory parameters. - * - * @param target Pointer to target. - * @param run Pointer to algo run data. - * @param usr_arg Function specific argument. The same as for esp_algorithm_usr_func_t. - * - * @return ERROR_OK on success, otherwise ERROR_XXX. - */ -typedef int (*esp_algorithm_usr_func_init_t)(struct target *target, - struct esp_algorithm_run_data *run, - void *usr_arg); - -/** - * @brief Algorithm's arguments cleanup function. - * This function will be called just after stub exit. - * It can be used to cleanup stub memory parameters. - * - * @param target Pointer to target. - * @param run Pointer to algo run data. - * @param usr_arg Function specific argument. The same as for esp_algorithm_usr_func_t. - * - * @return ERROR_OK on success, otherwise ERROR_XXX. - */ -typedef void (*esp_algorithm_usr_func_done_t)(struct target *target, - struct esp_algorithm_run_data *run, - void *usr_arg); - struct esp_algorithm_hw { int (*algo_init)(struct target *target, struct esp_algorithm_run_data *run, uint32_t num_args, va_list ap); int (*algo_cleanup)(struct target *target, struct esp_algorithm_run_data *run); @@ -283,14 +231,61 @@ struct esp_algorithm_run_data { }; /** Host side algorithm function argument. */ void *usr_func_arg; - /** Host side algorithm function. */ - esp_algorithm_usr_func_t usr_func; - /** Host side algorithm function setup routine. */ - esp_algorithm_usr_func_init_t usr_func_init; - /** Host side algorithm function cleanup routine. */ - esp_algorithm_usr_func_done_t usr_func_done; - /** Algorithm run function: see algorithm_run_xxx for example. */ - esp_algorithm_func_t algo_func; + + /** + * @brief Host part of algorithm. + * This function will be called while stub is running on target. + * It can be used for communication with stub. + * + * @param target Pointer to target. + * @param usr_arg Function specific argument. + * + * @return ERROR_OK on success, otherwise ERROR_XXX. + */ + int (*usr_func)(struct target *target, void *usr_arg); + + /** + * @brief Algorithm's arguments setup function. + * This function will be called just before stub start. + * It must return when all operations with running stub are completed. + * It can be used to prepare stub memory parameters. + * + * @param target Pointer to target. + * @param run Pointer to algo run data. + * @param usr_arg Function specific argument. The same as for usr_func. + * + * @return ERROR_OK on success, otherwise ERROR_XXX. + */ + int (*usr_func_init)(struct target *target, + struct esp_algorithm_run_data *run, + void *usr_arg); + + /** + * @brief Algorithm's arguments cleanup function. + * This function will be called just after stub exit. + * It can be used to cleanup stub memory parameters. + * + * @param target Pointer to target. + * @param run Pointer to algo run data. + * @param usr_arg Function specific argument. The same as for usr_func. + * + * @return ERROR_OK on success, otherwise ERROR_XXX. + */ + void (*usr_func_done)(struct target *target, + struct esp_algorithm_run_data *run, + void *usr_arg); + + /** + * @brief Algorithm run function. + * + * @param target Pointer to target. + * @param run Pointer to algo run data. + * @param arg Function specific argument. + * + * @return ERROR_OK on success, otherwise ERROR_XXX. + */ + int (*algo_func)(struct target *target, struct esp_algorithm_run_data *run, void *arg); + /** HW specific API */ const struct esp_algorithm_hw *hw; }; From b023c4c6c51a90fb0f831c5725c44ee9061e80ab Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 10 Jan 2025 15:09:49 +0100 Subject: [PATCH 12/29] nor: lpc2000: drop useless typedef lpc2000_variant No need to use a typedef for an enum. Drop it. Change-Id: Iec690ebf6704f346d010cad1e6c65496f7bcc218 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/8702 Tested-by: jenkins Reviewed-by: zapb --- src/flash/nor/lpc2000.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/flash/nor/lpc2000.c b/src/flash/nor/lpc2000.c index f12eef7e4..09d35f604 100644 --- a/src/flash/nor/lpc2000.c +++ b/src/flash/nor/lpc2000.c @@ -272,7 +272,7 @@ #define LPC11XX_REG_SECTORS 24 -typedef enum { +enum lpc2000_variant { LPC2000_V1, LPC2000_V2, LPC1700, @@ -282,10 +282,10 @@ typedef enum { LPC1500, LPC54100, LPC_AUTO, -} lpc2000_variant; +}; struct lpc2000_flash_bank { - lpc2000_variant variant; + enum lpc2000_variant variant; uint32_t cclk; int cmd51_dst_boundary; int calc_checksum; From ff5fb8f6100fdd630e698133f860fb02515f5cf5 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 10 Jan 2025 15:12:38 +0100 Subject: [PATCH 13/29] target: etm: drop useless typedefs No need to use a typedef for an enum. Drop etmv1_pipestat_t and etmv1_branch_reason_t. Change-Id: I03ae4de3efe699d9635fc4f162649f6bedcef4c0 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/8703 Reviewed-by: zapb Tested-by: jenkins --- src/target/etm.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/target/etm.h b/src/target/etm.h index be5f2c7d0..6c5b5e595 100644 --- a/src/target/etm.h +++ b/src/target/etm.h @@ -175,7 +175,7 @@ struct etm_context { }; /* PIPESTAT values */ -typedef enum { +enum etmv1_pipestat { STAT_IE = 0x0, STAT_ID = 0x1, STAT_IN = 0x2, @@ -184,10 +184,10 @@ typedef enum { STAT_BD = 0x5, STAT_TR = 0x6, STAT_TD = 0x7 -} etmv1_pipestat_t; +}; /* branch reason values */ -typedef enum { +enum etmv1_branch_reason { BR_NORMAL = 0x0, /* Normal PC change : periodic synchro (ETMv1.1) */ BR_ENABLE = 0x1, /* Trace has been enabled */ BR_RESTART = 0x2, /* Trace restarted after a FIFO overflow */ @@ -196,7 +196,7 @@ typedef enum { BR_RSVD5 = 0x5, /* reserved */ BR_RSVD6 = 0x6, /* reserved */ BR_RSVD7 = 0x7, /* reserved */ -} etmv1_branch_reason_t; +}; struct reg_cache *etm_build_reg_cache(struct target *target, struct arm_jtag *jtag_info, struct etm_context *etm_ctx); From c50b54147170b70a794f39aa4850a61d3b52cb49 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 10 Jan 2025 15:17:08 +0100 Subject: [PATCH 14/29] target: trace: drop useless typedef trace_status_t No need to use a typedef for an enum. Drop it. Change-Id: I31e0e3869c7277bcb14e05cfcac82c9655963ae6 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/8704 Tested-by: jenkins Reviewed-by: zapb --- src/target/etb.c | 4 ++-- src/target/etm.c | 2 +- src/target/etm.h | 4 ++-- src/target/etm_dummy.c | 2 +- src/target/trace.h | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/target/etb.c b/src/target/etb.c index 3b9004bb8..fb3112d70 100644 --- a/src/target/etb.c +++ b/src/target/etb.c @@ -454,12 +454,12 @@ static int etb_init(struct etm_context *etm_ctx) return ERROR_OK; } -static trace_status_t etb_status(struct etm_context *etm_ctx) +static enum trace_status etb_status(struct etm_context *etm_ctx) { struct etb *etb = etm_ctx->capture_driver_priv; struct reg *control = &etb->reg_cache->reg_list[ETB_CTRL]; struct reg *status = &etb->reg_cache->reg_list[ETB_STATUS]; - trace_status_t retval = 0; + enum trace_status retval = 0; int etb_timeout = 100; etb->etm_ctx = etm_ctx; diff --git a/src/target/etm.c b/src/target/etm.c index 53d5cb68c..d9a3cdc5e 100644 --- a/src/target/etm.c +++ b/src/target/etm.c @@ -1567,7 +1567,7 @@ COMMAND_HANDLER(handle_etm_status_command) struct target *target; struct arm *arm; struct etm_context *etm; - trace_status_t trace_status; + enum trace_status trace_status; target = get_current_target(CMD_CTX); arm = target_to_arm(target); diff --git a/src/target/etm.h b/src/target/etm.h index 6c5b5e595..e18549dfe 100644 --- a/src/target/etm.h +++ b/src/target/etm.h @@ -126,7 +126,7 @@ struct etm_capture_driver { const char *name; const struct command_registration *commands; int (*init)(struct etm_context *etm_ctx); - trace_status_t (*status)(struct etm_context *etm_ctx); + enum trace_status (*status)(struct etm_context *etm_ctx); int (*read_trace)(struct etm_context *etm_ctx); int (*start_capture)(struct etm_context *etm_ctx); int (*stop_capture)(struct etm_context *etm_ctx); @@ -153,7 +153,7 @@ struct etm_context { struct reg_cache *reg_cache; /* ETM register cache */ struct etm_capture_driver *capture_driver; /* driver used to access ETM data */ void *capture_driver_priv; /* capture driver private data */ - trace_status_t capture_status; /* current state of capture run */ + enum trace_status capture_status; /* current state of capture run */ struct etmv1_trace_data *trace_data; /* trace data */ uint32_t trace_depth; /* number of cycles to be analyzed, 0 if no data available */ uint32_t control; /* shadow of ETM_CTRL */ diff --git a/src/target/etm_dummy.c b/src/target/etm_dummy.c index 8deccf5f9..2709b6e9d 100644 --- a/src/target/etm_dummy.c +++ b/src/target/etm_dummy.c @@ -65,7 +65,7 @@ static int etm_dummy_init(struct etm_context *etm_ctx) return ERROR_OK; } -static trace_status_t etm_dummy_status(struct etm_context *etm_ctx) +static enum trace_status etm_dummy_status(struct etm_context *etm_ctx) { return TRACE_IDLE; } diff --git a/src/target/trace.h b/src/target/trace.h index e3d787edd..dc3ab5712 100644 --- a/src/target/trace.h +++ b/src/target/trace.h @@ -33,13 +33,13 @@ struct trace { * to *hardware* tracing ... split such "real" tracing out from * the contrib/libdcc support. */ -typedef enum trace_status { +enum trace_status { TRACE_IDLE = 0x0, TRACE_RUNNING = 0x1, TRACE_TRIGGERED = 0x2, TRACE_COMPLETED = 0x4, TRACE_OVERFLOWED = 0x8, -} trace_status_t; +}; int trace_point(struct target *target, uint32_t number); int trace_register_commands(struct command_context *cmd_ctx); From 894a39eda30c1b0e8eff39b687333deb4b3b0891 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 10 Jan 2025 15:20:35 +0100 Subject: [PATCH 15/29] target_request: drop useless typedef target_req_cmd_t No need to use a typedef for an enum. Drop it. Change-Id: Ib5a872b52a6f3d7379d2662e4ff84f32c2bd2ef8 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/8705 Reviewed-by: zapb Tested-by: jenkins --- src/target/target_request.c | 2 +- src/target/target_request.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/target/target_request.c b/src/target/target_request.c index bccae07b4..8d51dc3d6 100644 --- a/src/target/target_request.c +++ b/src/target/target_request.c @@ -107,7 +107,7 @@ static int target_hexmsg(struct target *target, int size, uint32_t length) */ int target_request(struct target *target, uint32_t request) { - target_req_cmd_t target_req_cmd = request & 0xff; + enum target_req_cmd target_req_cmd = request & 0xff; assert(target->type->target_request_data); diff --git a/src/target/target_request.h b/src/target/target_request.h index 62d5c74b1..97edd9ede 100644 --- a/src/target/target_request.h +++ b/src/target/target_request.h @@ -17,12 +17,12 @@ struct target; struct command_context; -typedef enum target_req_cmd { +enum target_req_cmd { TARGET_REQ_TRACEMSG, TARGET_REQ_DEBUGMSG, TARGET_REQ_DEBUGCHAR, /* TARGET_REQ_SEMIHOSTING, */ -} target_req_cmd_t; +}; struct debug_msg_receiver { struct command_context *cmd_ctx; From 8a5c3318315324574196ae3320c7abf326d4df88 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 10 Jan 2025 15:22:17 +0100 Subject: [PATCH 16/29] jtag: remote_bitbang: drop useless typedef flush_bool_t No need to use a typedef for an enum. Drop it. Change-Id: I122784ddd7b81ccd86da258b08526685c3d70033 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/8706 Tested-by: jenkins Reviewed-by: zapb --- src/jtag/drivers/remote_bitbang.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/jtag/drivers/remote_bitbang.c b/src/jtag/drivers/remote_bitbang.c index 037c1f27f..66f995d57 100644 --- a/src/jtag/drivers/remote_bitbang.c +++ b/src/jtag/drivers/remote_bitbang.c @@ -145,12 +145,12 @@ static int remote_bitbang_fill_buf(enum block_bool block) return ERROR_OK; } -typedef enum { +enum flush_bool { NO_FLUSH, FLUSH_SEND_BUF -} flush_bool_t; +}; -static int remote_bitbang_queue(int c, flush_bool_t flush) +static int remote_bitbang_queue(int c, enum flush_bool flush) { remote_bitbang_send_buf[remote_bitbang_send_buf_used++] = c; if (flush == FLUSH_SEND_BUF || From 54d07de86ea6abf1123cc2b032316f0c1bb88b3e Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 10 Jan 2025 15:25:15 +0100 Subject: [PATCH 17/29] jtag: bitbang: drop useless typedef bb_value_t No need to use a typedef for an enum. Drop it. Change-Id: I8800c95f97d2bafe27c699d7d451fb9b54286d99 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/8707 Tested-by: jenkins --- src/jtag/drivers/am335xgpio.c | 2 +- src/jtag/drivers/at91rm9200.c | 4 ++-- src/jtag/drivers/bcm2835gpio.c | 2 +- src/jtag/drivers/bitbang.h | 8 ++++---- src/jtag/drivers/dummy.c | 2 +- src/jtag/drivers/ep93xx.c | 4 ++-- src/jtag/drivers/imx_gpio.c | 4 ++-- src/jtag/drivers/linuxgpiod.c | 2 +- src/jtag/drivers/parport.c | 2 +- src/jtag/drivers/remote_bitbang.c | 4 ++-- src/jtag/drivers/sysfsgpio.c | 2 +- 11 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/jtag/drivers/am335xgpio.c b/src/jtag/drivers/am335xgpio.c index 05a73aa53..cacf4e7c7 100644 --- a/src/jtag/drivers/am335xgpio.c +++ b/src/jtag/drivers/am335xgpio.c @@ -206,7 +206,7 @@ static void restore_gpio(enum adapter_gpio_config_index idx) } } -static bb_value_t am335xgpio_read(void) +static enum bb_value am335xgpio_read(void) { return get_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_TDO]) ? BB_HIGH : BB_LOW; } diff --git a/src/jtag/drivers/at91rm9200.c b/src/jtag/drivers/at91rm9200.c index 57dd54c11..a77e29aa6 100644 --- a/src/jtag/drivers/at91rm9200.c +++ b/src/jtag/drivers/at91rm9200.c @@ -98,7 +98,7 @@ static uint32_t *pio_base; /* low level command set */ -static bb_value_t at91rm9200_read(void); +static enum bb_value at91rm9200_read(void); static int at91rm9200_write(int tck, int tms, int tdi); static int at91rm9200_init(void); @@ -110,7 +110,7 @@ static const struct bitbang_interface at91rm9200_bitbang = { .blink = NULL, }; -static bb_value_t at91rm9200_read(void) +static enum bb_value at91rm9200_read(void) { return (pio_base[device->TDO_PIO + PIO_PDSR] & device->TDO_MASK) ? BB_HIGH : BB_LOW; } diff --git a/src/jtag/drivers/bcm2835gpio.c b/src/jtag/drivers/bcm2835gpio.c index 2c2061dae..095601fa6 100644 --- a/src/jtag/drivers/bcm2835gpio.c +++ b/src/jtag/drivers/bcm2835gpio.c @@ -182,7 +182,7 @@ static void initialize_gpio(enum adapter_gpio_config_index idx) bcm2835_gpio_synchronize(); } -static bb_value_t bcm2835gpio_read(void) +static enum bb_value bcm2835gpio_read(void) { unsigned int shift = adapter_gpio_config[ADAPTER_GPIO_IDX_TDO].gpio_num; uint32_t value = (GPIO_LEV >> shift) & 1; diff --git a/src/jtag/drivers/bitbang.h b/src/jtag/drivers/bitbang.h index d6fd95e27..6afa409e9 100644 --- a/src/jtag/drivers/bitbang.h +++ b/src/jtag/drivers/bitbang.h @@ -14,11 +14,11 @@ #include #include -typedef enum { +enum bb_value { BB_LOW, BB_HIGH, BB_ERROR -} bb_value_t; +}; /** Low level callbacks (for bitbang). * @@ -29,7 +29,7 @@ typedef enum { * increase throughput. */ struct bitbang_interface { /** Sample TDO and return the value. */ - bb_value_t (*read)(void); + enum bb_value (*read)(void); /** The number of TDO samples that can be buffered up before the caller has * to call read_sample. */ @@ -39,7 +39,7 @@ struct bitbang_interface { int (*sample)(void); /** Return the next unread value from the buffer. */ - bb_value_t (*read_sample)(void); + enum bb_value (*read_sample)(void); /** Set TCK, TMS, and TDI to the given values. */ int (*write)(int tck, int tms, int tdi); diff --git a/src/jtag/drivers/dummy.c b/src/jtag/drivers/dummy.c index 315e03697..bfd6e8c54 100644 --- a/src/jtag/drivers/dummy.c +++ b/src/jtag/drivers/dummy.c @@ -22,7 +22,7 @@ static int clock_count; /* count clocks in any stable state, only stable states static uint32_t dummy_data; -static bb_value_t dummy_read(void) +static enum bb_value dummy_read(void) { int data = 1 & dummy_data; dummy_data = (dummy_data >> 1) | (1 << 31); diff --git a/src/jtag/drivers/ep93xx.c b/src/jtag/drivers/ep93xx.c index ae35f4ac0..ea9faf19b 100644 --- a/src/jtag/drivers/ep93xx.c +++ b/src/jtag/drivers/ep93xx.c @@ -30,7 +30,7 @@ static volatile uint8_t *gpio_data_direction_register; /* low level command set */ -static bb_value_t ep93xx_read(void); +static enum bb_value ep93xx_read(void); static int ep93xx_write(int tck, int tms, int tdi); static int ep93xx_reset(int trst, int srst); @@ -61,7 +61,7 @@ static const struct bitbang_interface ep93xx_bitbang = { .blink = NULL, }; -static bb_value_t ep93xx_read(void) +static enum bb_value ep93xx_read(void) { return (*gpio_data_register & TDO_BIT) ? BB_HIGH : BB_LOW; } diff --git a/src/jtag/drivers/imx_gpio.c b/src/jtag/drivers/imx_gpio.c index 7aefbeb8a..18dc2ddf6 100644 --- a/src/jtag/drivers/imx_gpio.c +++ b/src/jtag/drivers/imx_gpio.c @@ -72,7 +72,7 @@ static inline bool gpio_level(int g) return pio_base[g / 32].dr >> (g & 0x1F) & 1; } -static bb_value_t imx_gpio_read(void); +static enum bb_value imx_gpio_read(void); static int imx_gpio_write(int tck, int tms, int tdi); static int imx_gpio_swdio_read(void); @@ -118,7 +118,7 @@ static int speed_coeff = 50000; static int speed_offset = 100; static unsigned int jtag_delay; -static bb_value_t imx_gpio_read(void) +static enum bb_value imx_gpio_read(void) { return gpio_level(tdo_gpio) ? BB_HIGH : BB_LOW; } diff --git a/src/jtag/drivers/linuxgpiod.c b/src/jtag/drivers/linuxgpiod.c index 5ffbf4d2f..eda7b1a80 100644 --- a/src/jtag/drivers/linuxgpiod.c +++ b/src/jtag/drivers/linuxgpiod.c @@ -42,7 +42,7 @@ static bool is_gpio_config_valid(enum adapter_gpio_config_index idx) } /* Bitbang interface read of TDO */ -static bb_value_t linuxgpiod_read(void) +static enum bb_value linuxgpiod_read(void) { int retval; diff --git a/src/jtag/drivers/parport.c b/src/jtag/drivers/parport.c index f3478db51..3b20fe247 100644 --- a/src/jtag/drivers/parport.c +++ b/src/jtag/drivers/parport.c @@ -115,7 +115,7 @@ static unsigned long dataport; static unsigned long statusport; #endif -static bb_value_t parport_read(void) +static enum bb_value parport_read(void) { int data = 0; diff --git a/src/jtag/drivers/remote_bitbang.c b/src/jtag/drivers/remote_bitbang.c index 66f995d57..bb608ba0a 100644 --- a/src/jtag/drivers/remote_bitbang.c +++ b/src/jtag/drivers/remote_bitbang.c @@ -176,7 +176,7 @@ static int remote_bitbang_quit(void) return ERROR_OK; } -static bb_value_t char_to_int(int c) +static enum bb_value char_to_int(int c) { switch (c) { case '0': @@ -198,7 +198,7 @@ static int remote_bitbang_sample(void) return remote_bitbang_queue('R', NO_FLUSH); } -static bb_value_t remote_bitbang_read_sample(void) +static enum bb_value remote_bitbang_read_sample(void) { if (remote_bitbang_recv_buf_empty()) { if (remote_bitbang_fill_buf(BLOCK) != ERROR_OK) diff --git a/src/jtag/drivers/sysfsgpio.c b/src/jtag/drivers/sysfsgpio.c index c47754bd1..ccd3974a4 100644 --- a/src/jtag/drivers/sysfsgpio.c +++ b/src/jtag/drivers/sysfsgpio.c @@ -255,7 +255,7 @@ static int sysfsgpio_swd_write(int swclk, int swdio) * The sysfs value will read back either '0' or '1'. The trick here is to call * lseek to bypass buffering in the sysfs kernel driver. */ -static bb_value_t sysfsgpio_read(void) +static enum bb_value sysfsgpio_read(void) { char buf[1]; From 0d1932520b535270d1b454d1aad28819d359e6a5 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 10 Jan 2025 15:26:50 +0100 Subject: [PATCH 18/29] jtag: openjtag: drop useless typedef openjtag_tap_state_t No need to use a typedef for an enum. Drop it. Change-Id: I31531b80eaf7f3d0ee6cd22844e60a05c6b748dc Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/8708 Reviewed-by: zapb Tested-by: jenkins --- src/jtag/drivers/openjtag.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/jtag/drivers/openjtag.c b/src/jtag/drivers/openjtag.c index 0ae885e87..a3fbd204e 100644 --- a/src/jtag/drivers/openjtag.c +++ b/src/jtag/drivers/openjtag.c @@ -50,7 +50,7 @@ static const char * const openjtag_variant_names[] = { /* * OpenJTAG-OpenOCD state conversion */ -typedef enum openjtag_tap_state { +enum openjtag_tap_state { OPENJTAG_TAP_INVALID = -1, OPENJTAG_TAP_RESET = 0, OPENJTAG_TAP_IDLE = 1, @@ -68,7 +68,7 @@ typedef enum openjtag_tap_state { OPENJTAG_TAP_PAUSE_IR = 13, OPENJTAG_TAP_EXIT2_IR = 14, OPENJTAG_TAP_UPDATE_IR = 15, -} openjtag_tap_state_t; +}; /* OPENJTAG access library includes */ #include "libftdi_helper.h" From 4895a556fa6bafce14237b7e4c821d18fc55df02 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 10 Jan 2025 17:05:29 +0100 Subject: [PATCH 19/29] jtag: drop useless typedef tap_state_t No need to use a typedef for an enum. Drop it. Change-Id: I9eb2dc4f926671c5bb44e61453d92880e3036848 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/8709 Tested-by: jenkins Reviewed-by: zapb --- src/flash/nor/str9xpec.c | 2 +- src/jtag/commands.h | 10 +++--- src/jtag/core.c | 38 +++++++++++----------- src/jtag/drivers/amt_jtagaccel.c | 10 +++--- src/jtag/drivers/angie.c | 6 ++-- src/jtag/drivers/arm-jtag-ew.c | 12 +++---- src/jtag/drivers/bitbang.c | 6 ++-- src/jtag/drivers/bitq.c | 4 +-- src/jtag/drivers/buspirate.c | 12 +++---- src/jtag/drivers/cmsis_dap.c | 6 ++-- src/jtag/drivers/driver.c | 18 +++++----- src/jtag/drivers/dummy.c | 4 +-- src/jtag/drivers/ft232r.c | 6 ++-- src/jtag/drivers/ftdi.c | 8 ++--- src/jtag/drivers/gw16012.c | 6 ++-- src/jtag/drivers/jlink.c | 10 +++--- src/jtag/drivers/jtag_vpi.c | 4 +-- src/jtag/drivers/opendous.c | 12 +++---- src/jtag/drivers/openjtag.c | 2 +- src/jtag/drivers/osbdm.c | 8 ++--- src/jtag/drivers/rlink.c | 6 ++-- src/jtag/drivers/ulink.c | 6 ++-- src/jtag/drivers/usb_blaster/usb_blaster.c | 4 +-- src/jtag/drivers/usbprog.c | 6 ++-- src/jtag/drivers/vdebug.c | 10 +++--- src/jtag/drivers/vsllink.c | 12 +++---- src/jtag/drivers/xds110.c | 2 +- src/jtag/drivers/xlnx-pcie-xvc.c | 6 ++-- src/jtag/interface.c | 34 +++++++++---------- src/jtag/interface.h | 32 +++++++++--------- src/jtag/jtag.h | 28 ++++++++-------- src/jtag/minidriver.h | 12 +++---- src/jtag/tcl.c | 8 ++--- src/pld/lattice.c | 2 +- src/pld/lattice.h | 2 +- src/svf/svf.c | 24 +++++++------- src/svf/svf.h | 4 +-- src/target/arc_jtag.c | 6 ++-- src/target/arm11_dbgtap.c | 16 ++++----- src/target/arm11_dbgtap.h | 6 ++-- src/target/arm_jtag.c | 4 +-- src/target/arm_jtag.h | 8 ++--- src/target/dsp5680xx.c | 2 +- src/target/xscale.c | 8 ++--- src/target/xtensa/xtensa_debug_module.c | 2 +- src/xsvf/xsvf.c | 30 ++++++++--------- 46 files changed, 232 insertions(+), 232 deletions(-) diff --git a/src/flash/nor/str9xpec.c b/src/flash/nor/str9xpec.c index c39eb3aa8..eff7df5a1 100644 --- a/src/flash/nor/str9xpec.c +++ b/src/flash/nor/str9xpec.c @@ -68,7 +68,7 @@ static int str9xpec_erase_area(struct flash_bank *bank, unsigned int first, static int str9xpec_set_address(struct flash_bank *bank, uint8_t sector); static int str9xpec_write_options(struct flash_bank *bank); -static int str9xpec_set_instr(struct jtag_tap *tap, uint32_t new_instr, tap_state_t end_state) +static int str9xpec_set_instr(struct jtag_tap *tap, uint32_t new_instr, enum tap_state end_state) { if (!tap) return ERROR_TARGET_INVALID; diff --git a/src/jtag/commands.h b/src/jtag/commands.h index 29fa8426e..2923df1e6 100644 --- a/src/jtag/commands.h +++ b/src/jtag/commands.h @@ -40,26 +40,26 @@ struct scan_command { /** pointer to an array of data scan fields */ struct scan_field *fields; /** state in which JTAG commands should finish */ - tap_state_t end_state; + enum tap_state end_state; }; struct statemove_command { /** state in which JTAG commands should finish */ - tap_state_t end_state; + enum tap_state end_state; }; struct pathmove_command { /** number of states in *path */ unsigned int num_states; /** states that have to be passed */ - tap_state_t *path; + enum tap_state *path; }; struct runtest_command { /** number of cycles to spend in Run-Test/Idle state */ unsigned int num_cycles; /** state in which JTAG commands should finish */ - tap_state_t end_state; + enum tap_state end_state; }; @@ -78,7 +78,7 @@ struct reset_command { struct end_state_command { /** state in which JTAG commands should finish */ - tap_state_t end_state; + enum tap_state end_state; }; struct sleep_command { diff --git a/src/jtag/core.c b/src/jtag/core.c index 769e07571..89d53aecb 100644 --- a/src/jtag/core.c +++ b/src/jtag/core.c @@ -48,8 +48,8 @@ static void jtag_add_scan_check(struct jtag_tap *active, void (*jtag_add_scan)(struct jtag_tap *active, int in_num_fields, const struct scan_field *in_fields, - tap_state_t state), - int in_num_fields, struct scan_field *in_fields, tap_state_t state); + enum tap_state state), + int in_num_fields, struct scan_field *in_fields, enum tap_state state); static int jtag_error_clear(void); @@ -87,7 +87,7 @@ static int jtag_srst = -1; static struct jtag_tap *__jtag_all_taps; static enum reset_types jtag_reset_config = RESET_NONE; -tap_state_t cmd_queue_cur_state = TAP_RESET; +enum tap_state cmd_queue_cur_state = TAP_RESET; static bool jtag_verify_capture_ir = true; static bool jtag_verify = true; @@ -350,7 +350,7 @@ static void jtag_checks(void) assert(jtag_trst == 0); } -static void jtag_prelude(tap_state_t state) +static void jtag_prelude(enum tap_state state) { jtag_checks(); @@ -360,7 +360,7 @@ static void jtag_prelude(tap_state_t state) } void jtag_add_ir_scan_noverify(struct jtag_tap *active, const struct scan_field *in_fields, - tap_state_t state) + enum tap_state state) { jtag_prelude(state); @@ -371,13 +371,13 @@ void jtag_add_ir_scan_noverify(struct jtag_tap *active, const struct scan_field static void jtag_add_ir_scan_noverify_callback(struct jtag_tap *active, int dummy, const struct scan_field *in_fields, - tap_state_t state) + enum tap_state state) { jtag_add_ir_scan_noverify(active, in_fields, state); } /* If fields->in_value is filled out, then the captured IR value will be checked */ -void jtag_add_ir_scan(struct jtag_tap *active, struct scan_field *in_fields, tap_state_t state) +void jtag_add_ir_scan(struct jtag_tap *active, struct scan_field *in_fields, enum tap_state state) { assert(state != TAP_RESET); @@ -396,7 +396,7 @@ void jtag_add_ir_scan(struct jtag_tap *active, struct scan_field *in_fields, tap } void jtag_add_plain_ir_scan(int num_bits, const uint8_t *out_bits, uint8_t *in_bits, - tap_state_t state) + enum tap_state state) { assert(out_bits); assert(state != TAP_RESET); @@ -426,8 +426,8 @@ static void jtag_add_scan_check(struct jtag_tap *active, void (*jtag_add_scan)( struct jtag_tap *active, int in_num_fields, const struct scan_field *in_fields, - tap_state_t state), - int in_num_fields, struct scan_field *in_fields, tap_state_t state) + enum tap_state state), + int in_num_fields, struct scan_field *in_fields, enum tap_state state) { jtag_add_scan(active, in_num_fields, in_fields, state); @@ -445,7 +445,7 @@ static void jtag_add_scan_check(struct jtag_tap *active, void (*jtag_add_scan)( void jtag_add_dr_scan_check(struct jtag_tap *active, int in_num_fields, struct scan_field *in_fields, - tap_state_t state) + enum tap_state state) { if (jtag_verify) jtag_add_scan_check(active, jtag_add_dr_scan, in_num_fields, in_fields, state); @@ -457,7 +457,7 @@ void jtag_add_dr_scan_check(struct jtag_tap *active, void jtag_add_dr_scan(struct jtag_tap *active, int in_num_fields, const struct scan_field *in_fields, - tap_state_t state) + enum tap_state state) { assert(state != TAP_RESET); @@ -469,7 +469,7 @@ void jtag_add_dr_scan(struct jtag_tap *active, } void jtag_add_plain_dr_scan(int num_bits, const uint8_t *out_bits, uint8_t *in_bits, - tap_state_t state) + enum tap_state state) { assert(out_bits); assert(state != TAP_RESET); @@ -520,9 +520,9 @@ int jtag_add_tms_seq(unsigned int nbits, const uint8_t *seq, enum tap_state stat return retval; } -void jtag_add_pathmove(unsigned int num_states, const tap_state_t *path) +void jtag_add_pathmove(unsigned int num_states, const enum tap_state *path) { - tap_state_t cur_state = cmd_queue_cur_state; + enum tap_state cur_state = cmd_queue_cur_state; /* the last state has to be a stable state */ if (!tap_is_state_stable(path[num_states - 1])) { @@ -554,9 +554,9 @@ void jtag_add_pathmove(unsigned int num_states, const tap_state_t *path) cmd_queue_cur_state = path[num_states - 1]; } -int jtag_add_statemove(tap_state_t goal_state) +int jtag_add_statemove(enum tap_state goal_state) { - tap_state_t cur_state = cmd_queue_cur_state; + enum tap_state cur_state = cmd_queue_cur_state; if (goal_state != cur_state) { LOG_DEBUG("cur_state=%s goal_state=%s", @@ -575,7 +575,7 @@ int jtag_add_statemove(tap_state_t goal_state) else if (tap_is_state_stable(cur_state) && tap_is_state_stable(goal_state)) { unsigned int tms_bits = tap_get_tms_path(cur_state, goal_state); unsigned int tms_count = tap_get_tms_path_len(cur_state, goal_state); - tap_state_t moves[8]; + enum tap_state moves[8]; assert(tms_count < ARRAY_SIZE(moves)); for (unsigned int i = 0; i < tms_count; i++, tms_bits >>= 1) { @@ -595,7 +595,7 @@ int jtag_add_statemove(tap_state_t goal_state) return ERROR_OK; } -void jtag_add_runtest(unsigned int num_cycles, tap_state_t state) +void jtag_add_runtest(unsigned int num_cycles, enum tap_state state) { jtag_prelude(state); jtag_set_error(interface_jtag_add_runtest(num_cycles, state)); diff --git a/src/jtag/drivers/amt_jtagaccel.c b/src/jtag/drivers/amt_jtagaccel.c index 489cb2471..80254ff07 100644 --- a/src/jtag/drivers/amt_jtagaccel.c +++ b/src/jtag/drivers/amt_jtagaccel.c @@ -146,7 +146,7 @@ static int amt_jtagaccel_speed(int speed) return ERROR_OK; } -static void amt_jtagaccel_end_state(tap_state_t state) +static void amt_jtagaccel_end_state(enum tap_state state) { if (tap_is_state_stable(state)) tap_set_end_state(state); @@ -179,8 +179,8 @@ static void amt_jtagaccel_state_move(void) uint8_t aw_scan_tms_5; uint8_t tms_scan[2]; - tap_state_t cur_state = tap_get_state(); - tap_state_t end_state = tap_get_end_state(); + enum tap_state cur_state = tap_get_state(); + enum tap_state end_state = tap_get_end_state(); tms_scan[0] = amt_jtagaccel_tap_move[tap_move_ndx(cur_state)][tap_move_ndx(end_state)][0]; tms_scan[1] = amt_jtagaccel_tap_move[tap_move_ndx(cur_state)][tap_move_ndx(end_state)][1]; @@ -209,7 +209,7 @@ static void amt_jtagaccel_runtest(unsigned int num_cycles) uint8_t aw_scan_tms_5; uint8_t aw_scan_tms_1to4; - tap_state_t saved_end_state = tap_get_end_state(); + enum tap_state saved_end_state = tap_get_end_state(); /* only do a state_move when we're not already in IDLE */ if (tap_get_state() != TAP_IDLE) { @@ -237,7 +237,7 @@ static void amt_jtagaccel_scan(bool ir_scan, enum scan_type type, uint8_t *buffe { int bits_left = scan_size; int bit_count = 0; - tap_state_t saved_end_state = tap_get_end_state(); + enum tap_state saved_end_state = tap_get_end_state(); uint8_t aw_tdi_option; uint8_t dw_tdi_scan; uint8_t dr_tdo; diff --git a/src/jtag/drivers/angie.c b/src/jtag/drivers/angie.c index 47628fef7..46a4c82e5 100644 --- a/src/jtag/drivers/angie.c +++ b/src/jtag/drivers/angie.c @@ -219,7 +219,7 @@ static int angie_append_test_cmd(struct angie *device); static int angie_calculate_delay(enum angie_delay_type type, long f, int *delay); /* Interface between ANGIE and OpenOCD */ -static void angie_set_end_state(tap_state_t endstate); +static void angie_set_end_state(enum tap_state endstate); static int angie_queue_statemove(struct angie *device); static int angie_queue_scan(struct angie *device, struct jtag_command *cmd); @@ -1519,7 +1519,7 @@ static long angie_calculate_frequency(enum angie_delay_type type, int delay) * * @param endstate the state the end state follower should be set to. */ -static void angie_set_end_state(tap_state_t endstate) +static void angie_set_end_state(enum tap_state endstate) { if (tap_is_state_stable(endstate)) tap_set_end_state(endstate); @@ -1837,7 +1837,7 @@ static int angie_reset(int trst, int srst) static int angie_queue_pathmove(struct angie *device, struct jtag_command *cmd) { int ret, state_count; - tap_state_t *path; + enum tap_state *path; uint8_t tms_sequence; unsigned int num_states = cmd->cmd.pathmove->num_states; diff --git a/src/jtag/drivers/arm-jtag-ew.c b/src/jtag/drivers/arm-jtag-ew.c index aaed16db6..45e03840e 100644 --- a/src/jtag/drivers/arm-jtag-ew.c +++ b/src/jtag/drivers/arm-jtag-ew.c @@ -42,9 +42,9 @@ static uint8_t usb_in_buffer[ARMJTAGEW_IN_BUFFER_SIZE]; static uint8_t usb_out_buffer[ARMJTAGEW_OUT_BUFFER_SIZE]; /* Queue command functions */ -static void armjtagew_end_state(tap_state_t state); +static void armjtagew_end_state(enum tap_state state); static void armjtagew_state_move(void); -static void armjtagew_path_move(unsigned int num_states, tap_state_t *path); +static void armjtagew_path_move(unsigned int num_states, enum tap_state *path); static void armjtagew_runtest(unsigned int num_cycles); static void armjtagew_scan(bool ir_scan, enum scan_type type, @@ -253,7 +253,7 @@ static int armjtagew_quit(void) /************************************************************************** * Queue command implementations */ -static void armjtagew_end_state(tap_state_t state) +static void armjtagew_end_state(enum tap_state state) { if (tap_is_state_stable(state)) tap_set_end_state(state); @@ -279,7 +279,7 @@ static void armjtagew_state_move(void) tap_set_state(tap_get_end_state()); } -static void armjtagew_path_move(unsigned int num_states, tap_state_t *path) +static void armjtagew_path_move(unsigned int num_states, enum tap_state *path) { for (unsigned int i = 0; i < num_states; i++) { /* @@ -305,7 +305,7 @@ static void armjtagew_path_move(unsigned int num_states, tap_state_t *path) static void armjtagew_runtest(unsigned int num_cycles) { - tap_state_t saved_end_state = tap_get_end_state(); + enum tap_state saved_end_state = tap_get_end_state(); /* only do a state_move when we're not already in IDLE */ if (tap_get_state() != TAP_IDLE) { @@ -329,7 +329,7 @@ static void armjtagew_scan(bool ir_scan, int scan_size, struct scan_command *command) { - tap_state_t saved_end_state; + enum tap_state saved_end_state; armjtagew_tap_ensure_space(1, scan_size + 8); diff --git a/src/jtag/drivers/bitbang.c b/src/jtag/drivers/bitbang.c index 0a49feb00..c2e763ddb 100644 --- a/src/jtag/drivers/bitbang.c +++ b/src/jtag/drivers/bitbang.c @@ -60,7 +60,7 @@ const struct bitbang_interface *bitbang_interface; #define CLOCK_IDLE() 0 /* The bitbang driver leaves the TCK 0 when in idle */ -static void bitbang_end_state(tap_state_t state) +static void bitbang_end_state(enum tap_state state) { assert(tap_is_state_stable(state)); tap_set_end_state(state); @@ -149,7 +149,7 @@ static int bitbang_path_move(struct pathmove_command *cmd) static int bitbang_runtest(unsigned int num_cycles) { - tap_state_t saved_end_state = tap_get_end_state(); + enum tap_state saved_end_state = tap_get_end_state(); /* only do a state_move when we're not already in IDLE */ if (tap_get_state() != TAP_IDLE) { @@ -195,7 +195,7 @@ static int bitbang_stableclocks(unsigned int num_cycles) static int bitbang_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, unsigned int scan_size) { - tap_state_t saved_end_state = tap_get_end_state(); + enum tap_state saved_end_state = tap_get_end_state(); unsigned int bit_cnt; if (!((!ir_scan && diff --git a/src/jtag/drivers/bitq.c b/src/jtag/drivers/bitq.c index ef870e648..84acff835 100644 --- a/src/jtag/drivers/bitq.c +++ b/src/jtag/drivers/bitq.c @@ -76,7 +76,7 @@ static void bitq_io(int tms, int tdi, int tdo_req) bitq_in_proc(); } -static void bitq_end_state(tap_state_t state) +static void bitq_end_state(enum tap_state state) { if (!tap_is_state_stable(state)) { LOG_ERROR("BUG: %i is not a valid end state", state); @@ -85,7 +85,7 @@ static void bitq_end_state(tap_state_t state) tap_set_end_state(state); } -static void bitq_state_move(tap_state_t new_state) +static void bitq_state_move(enum tap_state new_state) { int i = 0; uint8_t tms_scan; diff --git a/src/jtag/drivers/buspirate.c b/src/jtag/drivers/buspirate.c index 6f8df5ada..93f0ba383 100644 --- a/src/jtag/drivers/buspirate.c +++ b/src/jtag/drivers/buspirate.c @@ -25,9 +25,9 @@ static int buspirate_init(void); static int buspirate_quit(void); static int buspirate_reset(int trst, int srst); -static void buspirate_end_state(tap_state_t state); +static void buspirate_end_state(enum tap_state state); static void buspirate_state_move(void); -static void buspirate_path_move(unsigned int num_states, tap_state_t *path); +static void buspirate_path_move(unsigned int num_states, enum tap_state *path); static void buspirate_runtest(unsigned int num_cycles); static void buspirate_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, int scan_size, struct scan_command *command); @@ -554,7 +554,7 @@ struct adapter_driver buspirate_adapter_driver = { }; /*************** jtag execute commands **********************/ -static void buspirate_end_state(tap_state_t state) +static void buspirate_end_state(enum tap_state state) { if (tap_is_state_stable(state)) tap_set_end_state(state); @@ -580,7 +580,7 @@ static void buspirate_state_move(void) tap_set_state(tap_get_end_state()); } -static void buspirate_path_move(unsigned int num_states, tap_state_t *path) +static void buspirate_path_move(unsigned int num_states, enum tap_state *path) { for (unsigned int i = 0; i < num_states; i++) { if (tap_state_transition(tap_get_state(), false) == path[i]) { @@ -604,7 +604,7 @@ static void buspirate_path_move(unsigned int num_states, tap_state_t *path) static void buspirate_runtest(unsigned int num_cycles) { - tap_state_t saved_end_state = tap_get_end_state(); + enum tap_state saved_end_state = tap_get_end_state(); /* only do a state_move when we're not already in IDLE */ if (tap_get_state() != TAP_IDLE) { @@ -628,7 +628,7 @@ static void buspirate_runtest(unsigned int num_cycles) static void buspirate_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, int scan_size, struct scan_command *command) { - tap_state_t saved_end_state; + enum tap_state saved_end_state; buspirate_tap_make_space(1, scan_size+8); /* is 8 correct ? (2 moves = 16) */ diff --git a/src/jtag/drivers/cmsis_dap.c b/src/jtag/drivers/cmsis_dap.c index e9fd93ad1..c8a7cf8fc 100644 --- a/src/jtag/drivers/cmsis_dap.c +++ b/src/jtag/drivers/cmsis_dap.c @@ -1502,7 +1502,7 @@ static int cmsis_dap_execute_tlr_reset(struct jtag_command *cmd) } /* Set new end state */ -static void cmsis_dap_end_state(tap_state_t state) +static void cmsis_dap_end_state(enum tap_state state) { if (tap_is_state_stable(state)) tap_set_end_state(state); @@ -1831,7 +1831,7 @@ static void cmsis_dap_execute_scan(struct jtag_command *cmd) tap_state_name(tap_get_end_state())); } -static void cmsis_dap_pathmove(int num_states, tap_state_t *path) +static void cmsis_dap_pathmove(int num_states, enum tap_state *path) { uint8_t tms0 = 0x00; uint8_t tms1 = 0xff; @@ -1873,7 +1873,7 @@ static void cmsis_dap_stableclocks(unsigned int num_cycles) static void cmsis_dap_runtest(unsigned int num_cycles) { - tap_state_t saved_end_state = tap_get_end_state(); + enum tap_state saved_end_state = tap_get_end_state(); /* Only do a state_move when we're not already in IDLE. */ if (tap_get_state() != TAP_IDLE) { diff --git a/src/jtag/drivers/driver.c b/src/jtag/drivers/driver.c index 58e59a559..43101b865 100644 --- a/src/jtag/drivers/driver.c +++ b/src/jtag/drivers/driver.c @@ -49,7 +49,7 @@ static void jtag_callback_queue_reset(void) * */ int interface_jtag_add_ir_scan(struct jtag_tap *active, - const struct scan_field *in_fields, tap_state_t state) + const struct scan_field *in_fields, enum tap_state state) { size_t num_taps = jtag_tap_count_enabled(); @@ -111,7 +111,7 @@ int interface_jtag_add_ir_scan(struct jtag_tap *active, * */ int interface_jtag_add_dr_scan(struct jtag_tap *active, int in_num_fields, - const struct scan_field *in_fields, tap_state_t state) + const struct scan_field *in_fields, enum tap_state state) { /* count devices in bypass */ @@ -184,7 +184,7 @@ int interface_jtag_add_dr_scan(struct jtag_tap *active, int in_num_fields, } static int jtag_add_plain_scan(int num_bits, const uint8_t *out_bits, - uint8_t *in_bits, tap_state_t state, bool ir_scan) + uint8_t *in_bits, enum tap_state state, bool ir_scan) { struct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command)); struct scan_command *scan = cmd_queue_alloc(sizeof(struct scan_command)); @@ -207,19 +207,19 @@ static int jtag_add_plain_scan(int num_bits, const uint8_t *out_bits, return ERROR_OK; } -int interface_jtag_add_plain_dr_scan(int num_bits, const uint8_t *out_bits, uint8_t *in_bits, tap_state_t state) +int interface_jtag_add_plain_dr_scan(int num_bits, const uint8_t *out_bits, uint8_t *in_bits, enum tap_state state) { return jtag_add_plain_scan(num_bits, out_bits, in_bits, state, false); } -int interface_jtag_add_plain_ir_scan(int num_bits, const uint8_t *out_bits, uint8_t *in_bits, tap_state_t state) +int interface_jtag_add_plain_ir_scan(int num_bits, const uint8_t *out_bits, uint8_t *in_bits, enum tap_state state) { return jtag_add_plain_scan(num_bits, out_bits, in_bits, state, true); } int interface_jtag_add_tlr(void) { - tap_state_t state = TAP_RESET; + enum tap_state state = TAP_RESET; /* allocate memory for a new list member */ struct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command)); @@ -259,7 +259,7 @@ int interface_add_tms_seq(unsigned int num_bits, const uint8_t *seq, enum tap_st return ERROR_OK; } -int interface_jtag_add_pathmove(unsigned int num_states, const tap_state_t *path) +int interface_jtag_add_pathmove(unsigned int num_states, const enum tap_state *path) { /* allocate memory for a new list member */ struct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command)); @@ -270,7 +270,7 @@ int interface_jtag_add_pathmove(unsigned int num_states, const tap_state_t *path cmd->cmd.pathmove = cmd_queue_alloc(sizeof(struct pathmove_command)); cmd->cmd.pathmove->num_states = num_states; - cmd->cmd.pathmove->path = cmd_queue_alloc(sizeof(tap_state_t) * num_states); + cmd->cmd.pathmove->path = cmd_queue_alloc(sizeof(enum tap_state) * num_states); for (unsigned int i = 0; i < num_states; i++) cmd->cmd.pathmove->path[i] = path[i]; @@ -278,7 +278,7 @@ int interface_jtag_add_pathmove(unsigned int num_states, const tap_state_t *path return ERROR_OK; } -int interface_jtag_add_runtest(unsigned int num_cycles, tap_state_t state) +int interface_jtag_add_runtest(unsigned int num_cycles, enum tap_state state) { /* allocate memory for a new list member */ struct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command)); diff --git a/src/jtag/drivers/dummy.c b/src/jtag/drivers/dummy.c index bfd6e8c54..79b29fbae 100644 --- a/src/jtag/drivers/dummy.c +++ b/src/jtag/drivers/dummy.c @@ -14,7 +14,7 @@ #include "hello.h" /* my private tap controller state, which tracks state for calling code */ -static tap_state_t dummy_state = TAP_RESET; +static enum tap_state dummy_state = TAP_RESET; static int dummy_clock; /* edge detector */ @@ -34,7 +34,7 @@ static int dummy_write(int tck, int tms, int tdi) /* TAP standard: "state transitions occur on rising edge of clock" */ if (tck != dummy_clock) { if (tck) { - tap_state_t old_state = dummy_state; + enum tap_state old_state = dummy_state; dummy_state = tap_state_transition(old_state, tms); if (old_state != dummy_state) { diff --git a/src/jtag/drivers/ft232r.c b/src/jtag/drivers/ft232r.c index 6dc130493..f4e5af4dd 100644 --- a/src/jtag/drivers/ft232r.c +++ b/src/jtag/drivers/ft232r.c @@ -622,7 +622,7 @@ static const struct command_registration ft232r_command_handlers[] = { * Synchronous bitbang protocol implementation. */ -static void syncbb_end_state(tap_state_t state) +static void syncbb_end_state(enum tap_state state) { if (tap_is_state_stable(state)) tap_set_end_state(state); @@ -705,7 +705,7 @@ static void syncbb_path_move(struct pathmove_command *cmd) static void syncbb_runtest(unsigned int num_cycles) { - tap_state_t saved_end_state = tap_get_end_state(); + enum tap_state saved_end_state = tap_get_end_state(); /* only do a state_move when we're not already in IDLE */ if (tap_get_state() != TAP_IDLE) { @@ -747,7 +747,7 @@ static void syncbb_stableclocks(unsigned int num_cycles) static void syncbb_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, int scan_size) { - tap_state_t saved_end_state = tap_get_end_state(); + enum tap_state saved_end_state = tap_get_end_state(); int bit_cnt, bit0_index; if (!((!ir_scan && (tap_get_state() == TAP_DRSHIFT)) || (ir_scan && (tap_get_state() == TAP_IRSHIFT)))) { diff --git a/src/jtag/drivers/ftdi.c b/src/jtag/drivers/ftdi.c index 42ecda117..ec0ae4c00 100644 --- a/src/jtag/drivers/ftdi.c +++ b/src/jtag/drivers/ftdi.c @@ -238,9 +238,9 @@ static int ftdi_get_signal(const struct signal *s, uint16_t *value_out) * * @param goal_state is the destination state for the move. */ -static void move_to_state(tap_state_t goal_state) +static void move_to_state(enum tap_state goal_state) { - tap_state_t start_state = tap_get_state(); + enum tap_state start_state = tap_get_state(); /* goal_state is 1/2 of a tuple/pair of states which allow convenient lookup of the required TMS pattern to move to this state from the @@ -299,7 +299,7 @@ static int ftdi_khz(int khz, int *jtag_speed) return ERROR_OK; } -static void ftdi_end_state(tap_state_t state) +static void ftdi_end_state(enum tap_state state) { if (tap_is_state_stable(state)) tap_set_end_state(state); @@ -370,7 +370,7 @@ static void ftdi_execute_tms(struct jtag_command *cmd) static void ftdi_execute_pathmove(struct jtag_command *cmd) { - tap_state_t *path = cmd->cmd.pathmove->path; + enum tap_state *path = cmd->cmd.pathmove->path; unsigned int num_states = cmd->cmd.pathmove->num_states; LOG_DEBUG_IO("pathmove: %u states, current: %s end: %s", num_states, diff --git a/src/jtag/drivers/gw16012.c b/src/jtag/drivers/gw16012.c index d0fe43fdb..7200e757c 100644 --- a/src/jtag/drivers/gw16012.c +++ b/src/jtag/drivers/gw16012.c @@ -133,7 +133,7 @@ static void gw16012_reset(int trst, int srst) gw16012_control(0x0b); } -static void gw16012_end_state(tap_state_t state) +static void gw16012_end_state(enum tap_state state) { if (tap_is_state_stable(state)) tap_set_end_state(state); @@ -187,7 +187,7 @@ static void gw16012_path_move(struct pathmove_command *cmd) static void gw16012_runtest(unsigned int num_cycles) { - tap_state_t saved_end_state = tap_get_end_state(); + enum tap_state saved_end_state = tap_get_end_state(); /* only do a state_move when we're not already in IDLE */ if (tap_get_state() != TAP_IDLE) { @@ -209,7 +209,7 @@ static void gw16012_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, int { int bits_left = scan_size; int bit_count = 0; - tap_state_t saved_end_state = tap_get_end_state(); + enum tap_state saved_end_state = tap_get_end_state(); uint8_t scan_out, scan_in; /* only if we're not already in the correct Shift state */ diff --git a/src/jtag/drivers/jlink.c b/src/jtag/drivers/jlink.c index 74660744a..4d15cf5e6 100644 --- a/src/jtag/drivers/jlink.c +++ b/src/jtag/drivers/jlink.c @@ -78,9 +78,9 @@ static struct device_config config; static struct device_config tmp_config; /* Queue command functions */ -static void jlink_end_state(tap_state_t state); +static void jlink_end_state(enum tap_state state); static void jlink_state_move(void); -static void jlink_path_move(unsigned int num_states, tap_state_t *path); +static void jlink_path_move(unsigned int num_states, enum tap_state *path); static void jlink_stableclocks(unsigned int num_cycles); static void jlink_runtest(unsigned int num_cycles); static void jlink_reset(int trst, int srst); @@ -875,7 +875,7 @@ static int jlink_quit(void) /***************************************************************************/ /* Queue command implementations */ -static void jlink_end_state(tap_state_t state) +static void jlink_end_state(enum tap_state state) { if (tap_is_state_stable(state)) tap_set_end_state(state); @@ -899,7 +899,7 @@ static void jlink_state_move(void) tap_set_state(tap_get_end_state()); } -static void jlink_path_move(unsigned int num_states, tap_state_t *path) +static void jlink_path_move(unsigned int num_states, enum tap_state *path) { uint8_t tms = 0xff; @@ -930,7 +930,7 @@ static void jlink_stableclocks(unsigned int num_cycles) static void jlink_runtest(unsigned int num_cycles) { - tap_state_t saved_end_state = tap_get_end_state(); + enum tap_state saved_end_state = tap_get_end_state(); /* Only do a state_move when we're not already in IDLE. */ if (tap_get_state() != TAP_IDLE) { diff --git a/src/jtag/drivers/jtag_vpi.c b/src/jtag/drivers/jtag_vpi.c index 079bb1d0a..f6cb3de5d 100644 --- a/src/jtag/drivers/jtag_vpi.c +++ b/src/jtag/drivers/jtag_vpi.c @@ -272,7 +272,7 @@ static int jtag_vpi_tms(struct tms_command *cmd) return jtag_vpi_tms_seq(cmd->bits, cmd->num_bits); } -static int jtag_vpi_state_move(tap_state_t state) +static int jtag_vpi_state_move(enum tap_state state) { if (tap_get_state() == state) return ERROR_OK; @@ -440,7 +440,7 @@ static int jtag_vpi_scan(struct scan_command *cmd) return ERROR_OK; } -static int jtag_vpi_runtest(unsigned int num_cycles, tap_state_t state) +static int jtag_vpi_runtest(unsigned int num_cycles, enum tap_state state) { int retval; diff --git a/src/jtag/drivers/opendous.c b/src/jtag/drivers/opendous.c index e828d46d0..999afb3fc 100644 --- a/src/jtag/drivers/opendous.c +++ b/src/jtag/drivers/opendous.c @@ -104,9 +104,9 @@ static int opendous_init(void); static int opendous_quit(void); /* Queue command functions */ -static void opendous_end_state(tap_state_t state); +static void opendous_end_state(enum tap_state state); static void opendous_state_move(void); -static void opendous_path_move(unsigned int num_states, tap_state_t *path); +static void opendous_path_move(unsigned int num_states, enum tap_state *path); static void opendous_runtest(unsigned int num_cycles); static void opendous_scan(int ir_scan, enum scan_type type, uint8_t *buffer, int scan_size, struct scan_command *command); @@ -393,7 +393,7 @@ static int opendous_quit(void) /***************************************************************************/ /* Queue command implementations */ -void opendous_end_state(tap_state_t state) +void opendous_end_state(enum tap_state state) { if (tap_is_state_stable(state)) tap_set_end_state(state); @@ -419,7 +419,7 @@ void opendous_state_move(void) tap_set_state(tap_get_end_state()); } -void opendous_path_move(unsigned int num_states, tap_state_t *path) +void opendous_path_move(unsigned int num_states, enum tap_state *path) { for (unsigned int i = 0; i < num_states; i++) { if (path[i] == tap_state_transition(tap_get_state(), false)) @@ -440,7 +440,7 @@ void opendous_path_move(unsigned int num_states, tap_state_t *path) void opendous_runtest(unsigned int num_cycles) { - tap_state_t saved_end_state = tap_get_end_state(); + enum tap_state saved_end_state = tap_get_end_state(); /* only do a state_move when we're not already in IDLE */ if (tap_get_state() != TAP_IDLE) { @@ -460,7 +460,7 @@ void opendous_runtest(unsigned int num_cycles) void opendous_scan(int ir_scan, enum scan_type type, uint8_t *buffer, int scan_size, struct scan_command *command) { - tap_state_t saved_end_state; + enum tap_state saved_end_state; opendous_tap_ensure_space(1, scan_size + 8); diff --git a/src/jtag/drivers/openjtag.c b/src/jtag/drivers/openjtag.c index a3fbd204e..14bcc171e 100644 --- a/src/jtag/drivers/openjtag.c +++ b/src/jtag/drivers/openjtag.c @@ -748,7 +748,7 @@ static void openjtag_execute_scan(struct jtag_command *cmd) static void openjtag_execute_runtest(struct jtag_command *cmd) { - tap_state_t end_state = cmd->cmd.runtest->end_state; + enum tap_state end_state = cmd->cmd.runtest->end_state; tap_set_end_state(end_state); /* only do a state_move when we're not already in IDLE */ diff --git a/src/jtag/drivers/osbdm.c b/src/jtag/drivers/osbdm.c index c41a0e13c..80f66d197 100644 --- a/src/jtag/drivers/osbdm.c +++ b/src/jtag/drivers/osbdm.c @@ -380,7 +380,7 @@ static int osbdm_quit(void) static int osbdm_add_pathmove( struct queue *queue, - tap_state_t *path, + enum tap_state *path, unsigned int num_states) { assert(num_states <= 32); @@ -415,7 +415,7 @@ static int osbdm_add_pathmove( static int osbdm_add_statemove( struct queue *queue, - tap_state_t new_state, + enum tap_state new_state, int skip_first) { int len = 0; @@ -490,7 +490,7 @@ static int osbdm_add_scan( struct queue *queue, struct scan_field *fields, unsigned int num_fields, - tap_state_t end_state, + enum tap_state end_state, bool ir_scan) { /* Move to desired shift state */ @@ -537,7 +537,7 @@ static int osbdm_add_scan( static int osbdm_add_runtest( struct queue *queue, unsigned int num_cycles, - tap_state_t end_state) + enum tap_state end_state) { if (osbdm_add_statemove(queue, TAP_IDLE, 0) != ERROR_OK) return ERROR_FAIL; diff --git a/src/jtag/drivers/rlink.c b/src/jtag/drivers/rlink.c index f4a4fcba9..6ea3729a5 100644 --- a/src/jtag/drivers/rlink.c +++ b/src/jtag/drivers/rlink.c @@ -842,7 +842,7 @@ static int tap_state_queue_append(uint8_t tms) return 0; } -static void rlink_end_state(tap_state_t state) +static void rlink_end_state(enum tap_state state) { if (tap_is_state_stable(state)) tap_set_end_state(state); @@ -898,7 +898,7 @@ static void rlink_path_move(struct pathmove_command *cmd) static void rlink_runtest(unsigned int num_cycles) { - tap_state_t saved_end_state = tap_get_end_state(); + enum tap_state saved_end_state = tap_get_end_state(); /* only do a state_move when we're not already in RTI */ if (tap_get_state() != TAP_IDLE) { @@ -1019,7 +1019,7 @@ static int rlink_scan(struct jtag_command *cmd, enum scan_type type, uint8_t *buffer, int scan_size) { bool ir_scan; - tap_state_t saved_end_state; + enum tap_state saved_end_state; int byte_bits; int extra_bits; int chunk_bits; diff --git a/src/jtag/drivers/ulink.c b/src/jtag/drivers/ulink.c index 3a248e388..0a13bf6d4 100644 --- a/src/jtag/drivers/ulink.c +++ b/src/jtag/drivers/ulink.c @@ -212,7 +212,7 @@ static int ulink_append_test_cmd(struct ulink *device); static int ulink_calculate_delay(enum ulink_delay_type type, long f, int *delay); /* Interface between OpenULINK and OpenOCD */ -static void ulink_set_end_state(tap_state_t endstate); +static void ulink_set_end_state(enum tap_state endstate); static int ulink_queue_statemove(struct ulink *device); static int ulink_queue_scan(struct ulink *device, struct jtag_command *cmd); @@ -1393,7 +1393,7 @@ static long ulink_calculate_frequency(enum ulink_delay_type type, int delay) * * @param endstate the state the end state follower should be set to. */ -static void ulink_set_end_state(tap_state_t endstate) +static void ulink_set_end_state(enum tap_state endstate) { if (tap_is_state_stable(endstate)) tap_set_end_state(endstate); @@ -1702,7 +1702,7 @@ static int ulink_queue_reset(struct ulink *device, struct jtag_command *cmd) static int ulink_queue_pathmove(struct ulink *device, struct jtag_command *cmd) { int ret, state_count; - tap_state_t *path; + enum tap_state *path; uint8_t tms_sequence; unsigned int num_states = cmd->cmd.pathmove->num_states; diff --git a/src/jtag/drivers/usb_blaster/usb_blaster.c b/src/jtag/drivers/usb_blaster/usb_blaster.c index 496466ca3..1782cc424 100644 --- a/src/jtag/drivers/usb_blaster/usb_blaster.c +++ b/src/jtag/drivers/usb_blaster/usb_blaster.c @@ -494,7 +494,7 @@ static void ublast_path_move(struct pathmove_command *cmd) * Input the correct TMS sequence to the JTAG TAP so that we end up in the * target state. This assumes the current state (tap_get_state()) is correct. */ -static void ublast_state_move(tap_state_t state, int skip) +static void ublast_state_move(enum tap_state state, int skip) { uint8_t tms_scan; int tms_len; @@ -673,7 +673,7 @@ static void ublast_queue_tdi(uint8_t *bits, int nb_bits, enum scan_type scan) ublast_idle_clock(); } -static void ublast_runtest(unsigned int num_cycles, tap_state_t state) +static void ublast_runtest(unsigned int num_cycles, enum tap_state state) { LOG_DEBUG_IO("%s(cycles=%u, end_state=%d)", __func__, num_cycles, state); diff --git a/src/jtag/drivers/usbprog.c b/src/jtag/drivers/usbprog.c index 6e3b3ba24..24407f003 100644 --- a/src/jtag/drivers/usbprog.c +++ b/src/jtag/drivers/usbprog.c @@ -34,7 +34,7 @@ #define TCK_BIT 2 #define TMS_BIT 1 -static void usbprog_end_state(tap_state_t state); +static void usbprog_end_state(enum tap_state state); static void usbprog_state_move(void); static void usbprog_path_move(struct pathmove_command *cmd); static void usbprog_runtest(unsigned int num_cycles); @@ -168,7 +168,7 @@ static int usbprog_quit(void) } /*************** jtag execute commands **********************/ -static void usbprog_end_state(tap_state_t state) +static void usbprog_end_state(enum tap_state state) { if (tap_is_state_stable(state)) tap_set_end_state(state); @@ -257,7 +257,7 @@ static void usbprog_runtest(unsigned int num_cycles) static void usbprog_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, int scan_size) { - tap_state_t saved_end_state = tap_get_end_state(); + enum tap_state saved_end_state = tap_get_end_state(); if (ir_scan) usbprog_end_state(TAP_IRSHIFT); diff --git a/src/jtag/drivers/vdebug.c b/src/jtag/drivers/vdebug.c index 20819f70b..fd1e6a7e7 100644 --- a/src/jtag/drivers/vdebug.c +++ b/src/jtag/drivers/vdebug.c @@ -944,11 +944,11 @@ static int vdebug_jtag_path_move(struct pathmove_command *cmd, uint8_t f_flush) return vdebug_jtag_tms_seq(tms, cmd->num_states, f_flush); } -static int vdebug_jtag_tlr(tap_state_t state, uint8_t f_flush) +static int vdebug_jtag_tlr(enum tap_state state, uint8_t f_flush) { int rc = ERROR_OK; - tap_state_t cur = tap_get_state(); + enum tap_state cur = tap_get_state(); uint8_t tms_pre = tap_get_tms_path(cur, state); uint8_t num_pre = tap_get_tms_path_len(cur, state); LOG_DEBUG_IO("tlr from %x to %x", cur, state); @@ -964,7 +964,7 @@ static int vdebug_jtag_scan(struct scan_command *cmd, uint8_t f_flush) { int rc = ERROR_OK; - tap_state_t cur = tap_get_state(); + enum tap_state cur = tap_get_state(); uint8_t state = cmd->ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT; uint8_t tms_pre = tap_get_tms_path(cur, state); uint8_t num_pre = tap_get_tms_path_len(cur, state); @@ -992,9 +992,9 @@ static int vdebug_jtag_scan(struct scan_command *cmd, uint8_t f_flush) return rc; } -static int vdebug_jtag_runtest(unsigned int num_cycles, tap_state_t state, uint8_t f_flush) +static int vdebug_jtag_runtest(unsigned int num_cycles, enum tap_state state, uint8_t f_flush) { - tap_state_t cur = tap_get_state(); + enum tap_state cur = tap_get_state(); uint8_t tms_pre = tap_get_tms_path(cur, state); uint8_t num_pre = tap_get_tms_path_len(cur, state); LOG_DEBUG_IO("idle len:%u state cur:%x end:%x", num_cycles, cur, state); diff --git a/src/jtag/drivers/vsllink.c b/src/jtag/drivers/vsllink.c index ca142177e..c10ed1380 100644 --- a/src/jtag/drivers/vsllink.c +++ b/src/jtag/drivers/vsllink.c @@ -41,9 +41,9 @@ static struct pending_scan_result pending_scan_results_buffer[MAX_PENDING_SCAN_RESULTS]; /* Queue command functions */ -static void vsllink_end_state(tap_state_t state); +static void vsllink_end_state(enum tap_state state); static void vsllink_state_move(void); -static void vsllink_path_move(unsigned int num_states, tap_state_t *path); +static void vsllink_path_move(unsigned int num_states, enum tap_state *path); static void vsllink_tms(int num_bits, const uint8_t *bits); static void vsllink_runtest(unsigned int num_cycles); static void vsllink_stableclocks(unsigned int num_cycles, int tms); @@ -346,7 +346,7 @@ static int vsllink_init(void) /************************************************************************** * Queue command implementations */ -static void vsllink_end_state(tap_state_t state) +static void vsllink_end_state(enum tap_state state) { if (tap_is_state_stable(state)) tap_set_end_state(state); @@ -371,7 +371,7 @@ static void vsllink_state_move(void) tap_set_state(tap_get_end_state()); } -static void vsllink_path_move(unsigned int num_states, tap_state_t *path) +static void vsllink_path_move(unsigned int num_states, enum tap_state *path) { for (unsigned int i = 0; i < num_states; i++) { if (path[i] == tap_state_transition(tap_get_state(), false)) @@ -407,7 +407,7 @@ static void vsllink_stableclocks(unsigned int num_cycles, int tms) static void vsllink_runtest(unsigned int num_cycles) { - tap_state_t saved_end_state = tap_get_end_state(); + enum tap_state saved_end_state = tap_get_end_state(); if (tap_get_state() != TAP_IDLE) { /* enter IDLE state */ @@ -427,7 +427,7 @@ static void vsllink_runtest(unsigned int num_cycles) static void vsllink_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, int scan_size, struct scan_command *command) { - tap_state_t saved_end_state; + enum tap_state saved_end_state; saved_end_state = tap_get_end_state(); diff --git a/src/jtag/drivers/xds110.c b/src/jtag/drivers/xds110.c index 6e12b9a79..c84371001 100644 --- a/src/jtag/drivers/xds110.c +++ b/src/jtag/drivers/xds110.c @@ -172,7 +172,7 @@ #define CMD_RUNTEST 3 #define CMD_STABLECLOCKS 4 -/* Array to convert from OpenOCD tap_state_t to XDS JTAG state */ +/* Array to convert from OpenOCD enum tap_state to XDS JTAG state */ static const uint32_t xds_jtag_state[] = { XDS_JTAG_STATE_EXIT2_DR, /* TAP_DREXIT2 = 0x0 */ XDS_JTAG_STATE_EXIT1_DR, /* TAP_DREXIT1 = 0x1 */ diff --git a/src/jtag/drivers/xlnx-pcie-xvc.c b/src/jtag/drivers/xlnx-pcie-xvc.c index d90a022cd..37c6777e4 100644 --- a/src/jtag/drivers/xlnx-pcie-xvc.c +++ b/src/jtag/drivers/xlnx-pcie-xvc.c @@ -171,7 +171,7 @@ static int xlnx_pcie_xvc_execute_runtest(struct jtag_command *cmd) cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state); - tap_state_t tmp_state = tap_get_end_state(); + enum tap_state tmp_state = tap_get_end_state(); if (tap_get_state() != TAP_IDLE) { tap_set_end_state(TAP_IDLE); @@ -201,7 +201,7 @@ static int xlnx_pcie_xvc_execute_runtest(struct jtag_command *cmd) static int xlnx_pcie_xvc_execute_pathmove(struct jtag_command *cmd) { unsigned int num_states = cmd->cmd.pathmove->num_states; - tap_state_t *path = cmd->cmd.pathmove->path; + enum tap_state *path = cmd->cmd.pathmove->path; int err = ERROR_OK; LOG_DEBUG("pathmove: %u states, end in %i", @@ -232,7 +232,7 @@ static int xlnx_pcie_xvc_execute_pathmove(struct jtag_command *cmd) static int xlnx_pcie_xvc_execute_scan(struct jtag_command *cmd) { enum scan_type type = jtag_scan_type(cmd->cmd.scan); - tap_state_t saved_end_state = cmd->cmd.scan->end_state; + enum tap_state saved_end_state = cmd->cmd.scan->end_state; bool ir_scan = cmd->cmd.scan->ir_scan; uint32_t tdi, tms, tdo; uint8_t *buf, *rd_ptr; diff --git a/src/jtag/interface.c b/src/jtag/interface.c index 87d704db9..92c88ca93 100644 --- a/src/jtag/interface.c +++ b/src/jtag/interface.c @@ -26,15 +26,15 @@ * @see tap_set_state() and tap_get_state() accessors. * Actual name is not important since accessors hide it. */ -static tap_state_t state_follower = TAP_RESET; +static enum tap_state state_follower = TAP_RESET; -void tap_set_state_impl(tap_state_t new_state) +void tap_set_state_impl(enum tap_state new_state) { /* this is the state we think the TAPs are in now, was cur_state */ state_follower = new_state; } -tap_state_t tap_get_state(void) +enum tap_state tap_get_state(void) { return state_follower; } @@ -43,9 +43,9 @@ tap_state_t tap_get_state(void) * @see tap_set_end_state() and tap_get_end_state() accessors. * Actual name is not important because accessors hide it. */ -static tap_state_t end_state_follower = TAP_RESET; +static enum tap_state end_state_follower = TAP_RESET; -void tap_set_end_state(tap_state_t new_end_state) +void tap_set_end_state(enum tap_state new_end_state) { /* this is the state we think the TAPs will be in at completion of the * current TAP operation, was end_state @@ -53,12 +53,12 @@ void tap_set_end_state(tap_state_t new_end_state) end_state_follower = new_end_state; } -tap_state_t tap_get_end_state(void) +enum tap_state tap_get_end_state(void) { return end_state_follower; } -int tap_move_ndx(tap_state_t astate) +int tap_move_ndx(enum tap_state astate) { /* given a stable state, return the index into the tms_seqs[] * array within tap_get_tms_path() @@ -187,17 +187,17 @@ typedef const struct tms_sequences tms_table[6][6]; static tms_table *tms_seqs = &short_tms_seqs; -int tap_get_tms_path(tap_state_t from, tap_state_t to) +int tap_get_tms_path(enum tap_state from, enum tap_state to) { return (*tms_seqs)[tap_move_ndx(from)][tap_move_ndx(to)].bits; } -int tap_get_tms_path_len(tap_state_t from, tap_state_t to) +int tap_get_tms_path_len(enum tap_state from, enum tap_state to) { return (*tms_seqs)[tap_move_ndx(from)][tap_move_ndx(to)].bit_count; } -bool tap_is_state_stable(tap_state_t astate) +bool tap_is_state_stable(enum tap_state astate) { bool is_stable; @@ -220,9 +220,9 @@ bool tap_is_state_stable(tap_state_t astate) return is_stable; } -tap_state_t tap_state_transition(tap_state_t cur_state, bool tms) +enum tap_state tap_state_transition(enum tap_state cur_state, bool tms) { - tap_state_t new_state; + enum tap_state new_state; /* A switch is used because it is symbol dependent and not value dependent * like an array. Also it can check for out of range conditions. @@ -341,7 +341,7 @@ static const struct name_mapping { { TAP_IDLE, "IDLE", }, }; -const char *tap_state_name(tap_state_t state) +const char *tap_state_name(enum tap_state state) { unsigned int i; @@ -352,7 +352,7 @@ const char *tap_state_name(tap_state_t state) return "???"; } -tap_state_t tap_state_by_name(const char *name) +enum tap_state tap_state_by_name(const char *name) { unsigned int i; @@ -371,8 +371,8 @@ tap_state_t tap_state_by_name(const char *name) LOG_DEBUG_IO("TAP/SM: %9s -> %5s\tTMS: %s\tTDI: %s", \ tap_state_name(a), tap_state_name(b), astr, bstr) -tap_state_t jtag_debug_state_machine_(const void *tms_buf, const void *tdi_buf, - unsigned int tap_bits, tap_state_t next_state) +enum tap_state jtag_debug_state_machine_(const void *tms_buf, const void *tdi_buf, + unsigned int tap_bits, enum tap_state next_state) { const uint8_t *tms_buffer; const uint8_t *tdi_buffer; @@ -384,7 +384,7 @@ tap_state_t jtag_debug_state_machine_(const void *tms_buf, const void *tdi_buf, char tms_str[33]; char tdi_str[33]; - tap_state_t last_state; + enum tap_state last_state; /* set startstate (and possibly last, if tap_bits == 0) */ last_state = next_state; diff --git a/src/jtag/interface.h b/src/jtag/interface.h index f69326492..b2d7123fd 100644 --- a/src/jtag/interface.h +++ b/src/jtag/interface.h @@ -28,7 +28,7 @@ /** implementation of wrapper function tap_set_state() */ -void tap_set_state_impl(tap_state_t new_state); +void tap_set_state_impl(enum tap_state new_state); /** * This function sets the state of a "state follower" which tracks the @@ -55,9 +55,9 @@ void tap_set_state_impl(tap_state_t new_state); /** * This function gets the state of the "state follower" which tracks the * state of the TAPs connected to the cable. @see tap_set_state @return - * tap_state_t The state the TAPs are in now. + * enum tap_state The state the TAPs are in now. */ -tap_state_t tap_get_state(void); +enum tap_state tap_get_state(void); /** * This function sets the state of an "end state follower" which tracks @@ -70,13 +70,13 @@ tap_state_t tap_get_state(void); * @param new_end_state The state the TAPs should enter at completion of * a pending TAP operation. */ -void tap_set_end_state(tap_state_t new_end_state); +void tap_set_end_state(enum tap_state new_end_state); /** * For more information, @see tap_set_end_state - * @return tap_state_t - The state the TAPs should be in at completion of the current TAP operation. + * @return enum tap_state - The state the TAPs should be in at completion of the current TAP operation. */ -tap_state_t tap_get_end_state(void); +enum tap_state tap_get_end_state(void); /** * This function provides a "bit sequence" indicating what has to be @@ -91,7 +91,7 @@ tap_state_t tap_get_end_state(void); * @return int The required TMS bit sequence, with the first bit in the * sequence at bit 0. */ -int tap_get_tms_path(tap_state_t from, tap_state_t to); +int tap_get_tms_path(enum tap_state from, enum tap_state to); /** * Function int tap_get_tms_path_len @@ -109,7 +109,7 @@ int tap_get_tms_path(tap_state_t from, tap_state_t to); * @param to is the resultant or final state * @return int - the total number of bits in a transition. */ -int tap_get_tms_path_len(tap_state_t from, tap_state_t to); +int tap_get_tms_path_len(enum tap_state from, enum tap_state to); /** @@ -125,30 +125,30 @@ int tap_get_tms_path_len(tap_state_t from, tap_state_t to); * and terminate. * @return int - the array (or sequence) index as described above */ -int tap_move_ndx(tap_state_t astate); +int tap_move_ndx(enum tap_state astate); /** * Function tap_is_state_stable * returns true if the \a astate is stable. */ -bool tap_is_state_stable(tap_state_t astate); +bool tap_is_state_stable(enum tap_state astate); /** * Function tap_state_transition * takes a current TAP state and returns the next state according to the tms value. * @param current_state is the state of a TAP currently. * @param tms is either zero or non-zero, just like a real TMS line in a jtag interface. - * @return tap_state_t - the next state a TAP would enter. + * @return enum tap_state - the next state a TAP would enter. */ -tap_state_t tap_state_transition(tap_state_t current_state, bool tms); +enum tap_state tap_state_transition(enum tap_state current_state, bool tms); /** Allow switching between old and new TMS tables. @see tap_get_tms_path */ void tap_use_new_tms_table(bool use_new); /** @returns True if new TMS table is active; false otherwise. */ bool tap_uses_new_tms_table(void); -tap_state_t jtag_debug_state_machine_(const void *tms_buf, const void *tdi_buf, - unsigned int tap_len, tap_state_t start_tap_state); +enum tap_state jtag_debug_state_machine_(const void *tms_buf, const void *tdi_buf, + unsigned int tap_len, enum tap_state start_tap_state); /** * @brief Prints verbose TAP state transitions for the given TMS/TDI buffers. @@ -158,8 +158,8 @@ tap_state_t jtag_debug_state_machine_(const void *tms_buf, const void *tdi_buf, * @param start_tap_state must specify the current TAP state. * @returns the final TAP state; pass as @a start_tap_state in following call. */ -static inline tap_state_t jtag_debug_state_machine(const void *tms_buf, - const void *tdi_buf, unsigned int tap_len, tap_state_t start_tap_state) +static inline enum tap_state jtag_debug_state_machine(const void *tms_buf, + const void *tdi_buf, unsigned int tap_len, enum tap_state start_tap_state) { if (LOG_LEVEL_IS(LOG_LVL_DEBUG_IO)) return jtag_debug_state_machine_(tms_buf, tdi_buf, tap_len, start_tap_state); diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h index 86526a09a..47efdff37 100644 --- a/src/jtag/jtag.h +++ b/src/jtag/jtag.h @@ -34,7 +34,7 @@ * Fix those drivers to map as appropriate ... then pick some * sane set of numbers here (where 0/uninitialized == INVALID). */ -typedef enum tap_state { +enum tap_state { TAP_INVALID = -1, /* Proper ARM recommended numbers */ @@ -54,7 +54,7 @@ typedef enum tap_state { TAP_IRUPDATE = 0xd, TAP_IRCAPTURE = 0xe, TAP_RESET = 0x0f, -} tap_state_t; +}; /** * Defines arguments for reset functions @@ -68,13 +68,13 @@ typedef enum tap_state { * Function tap_state_name * Returns a string suitable for display representing the JTAG tap_state */ -const char *tap_state_name(tap_state_t state); +const char *tap_state_name(enum tap_state state); /** Provides user-friendly name lookup of TAP states. */ -tap_state_t tap_state_by_name(const char *name); +enum tap_state tap_state_by_name(const char *name); /** The current TAP state of the pending JTAG command queue. */ -extern tap_state_t cmd_queue_cur_state; +extern enum tap_state cmd_queue_cur_state; /** * This structure defines a single scan field in the scan. It provides @@ -295,20 +295,20 @@ int jtag_init_inner(struct command_context *cmd_ctx); * */ void jtag_add_ir_scan(struct jtag_tap *tap, - struct scan_field *fields, tap_state_t endstate); + struct scan_field *fields, enum tap_state endstate); /** * The same as jtag_add_ir_scan except no verification is performed out * the output values. */ void jtag_add_ir_scan_noverify(struct jtag_tap *tap, - const struct scan_field *fields, tap_state_t state); + const struct scan_field *fields, enum tap_state state); /** * Scan out the bits in ir scan mode. * * If in_bits == NULL, discard incoming bits. */ void jtag_add_plain_ir_scan(int num_bits, const uint8_t *out_bits, uint8_t *in_bits, - tap_state_t endstate); + enum tap_state endstate); /** * Generate a DR SCAN using the fields passed to the function. @@ -317,17 +317,17 @@ void jtag_add_plain_ir_scan(int num_bits, const uint8_t *out_bits, uint8_t *in_b * 1-bit field. The bypass status of TAPs is set by jtag_add_ir_scan(). */ void jtag_add_dr_scan(struct jtag_tap *tap, int num_fields, - const struct scan_field *fields, tap_state_t endstate); + const struct scan_field *fields, enum tap_state endstate); /** A version of jtag_add_dr_scan() that uses the check_value/mask fields */ void jtag_add_dr_scan_check(struct jtag_tap *tap, int num_fields, - struct scan_field *fields, tap_state_t endstate); + struct scan_field *fields, enum tap_state endstate); /** * Scan out the bits in ir scan mode. * * If in_bits == NULL, discard incoming bits. */ void jtag_add_plain_dr_scan(int num_bits, - const uint8_t *out_bits, uint8_t *in_bits, tap_state_t endstate); + const uint8_t *out_bits, uint8_t *in_bits, enum tap_state endstate); /** * Defines the type of data passed to the jtag_callback_t interface. @@ -435,7 +435,7 @@ void jtag_add_tlr(void); * - ERROR_JTAG_TRANSITION_INVALID -- The path includes invalid * state transitions. */ -void jtag_add_pathmove(unsigned int num_states, const tap_state_t *path); +void jtag_add_pathmove(unsigned int num_states, const enum tap_state *path); /** * jtag_add_statemove() moves from the current state to @a goal_state. @@ -446,7 +446,7 @@ void jtag_add_pathmove(unsigned int num_states, const tap_state_t *path); * Moves from the current state to the goal \a state. * Both states must be stable. */ -int jtag_add_statemove(tap_state_t goal_state); +int jtag_add_statemove(enum tap_state goal_state); /** * Goes to TAP_IDLE (if we're not already there), cycle @@ -458,7 +458,7 @@ int jtag_add_statemove(tap_state_t goal_state); * via TAP_IDLE. * @param endstate The final state. */ -void jtag_add_runtest(unsigned int num_cycles, tap_state_t endstate); +void jtag_add_runtest(unsigned int num_cycles, enum tap_state endstate); /** * A reset of the TAP state machine can be requested. diff --git a/src/jtag/minidriver.h b/src/jtag/minidriver.h index 1b1094dd5..4b61bf125 100644 --- a/src/jtag/minidriver.h +++ b/src/jtag/minidriver.h @@ -38,21 +38,21 @@ int interface_jtag_add_ir_scan(struct jtag_tap *active, const struct scan_field *fields, - tap_state_t endstate); + enum tap_state endstate); int interface_jtag_add_plain_ir_scan( int num_bits, const uint8_t *out_bits, uint8_t *in_bits, - tap_state_t endstate); + enum tap_state endstate); int interface_jtag_add_dr_scan(struct jtag_tap *active, int num_fields, const struct scan_field *fields, - tap_state_t endstate); + enum tap_state endstate); int interface_jtag_add_plain_dr_scan( int num_bits, const uint8_t *out_bits, uint8_t *in_bits, - tap_state_t endstate); + enum tap_state endstate); int interface_jtag_add_tlr(void); -int interface_jtag_add_pathmove(unsigned int num_states, const tap_state_t *path); -int interface_jtag_add_runtest(unsigned int num_cycles, tap_state_t endstate); +int interface_jtag_add_pathmove(unsigned int num_states, const enum tap_state *path); +int interface_jtag_add_runtest(unsigned int num_cycles, enum tap_state endstate); int interface_add_tms_seq(unsigned int num_bits, const uint8_t *bits, enum tap_state state); diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c index 790aedfc4..8b0bc7aff 100644 --- a/src/jtag/tcl.c +++ b/src/jtag/tcl.c @@ -61,7 +61,7 @@ struct jtag_tap *jtag_tap_by_jim_obj(Jim_Interp *interp, Jim_Obj *o) return t; } -static bool scan_is_safe(tap_state_t state) +static bool scan_is_safe(enum tap_state state) { switch (state) { case TAP_RESET: @@ -126,7 +126,7 @@ COMMAND_HANDLER(handle_jtag_command_drscan) return ERROR_FAIL; } - tap_state_t endstate = TAP_IDLE; + enum tap_state endstate = TAP_IDLE; if (CMD_ARGC > 3 && !strcmp("-endstate", CMD_ARGV[CMD_ARGC - 2])) { const char *state_name = CMD_ARGV[CMD_ARGC - 1]; endstate = tap_state_by_name(state_name); @@ -176,7 +176,7 @@ fail: COMMAND_HANDLER(handle_jtag_command_pathmove) { - tap_state_t states[8]; + enum tap_state states[8]; if (CMD_ARGC < 1 || CMD_ARGC > ARRAY_SIZE(states)) return ERROR_COMMAND_SYNTAX_ERROR; @@ -919,7 +919,7 @@ COMMAND_HANDLER(handle_irscan_command) int i; struct scan_field *fields; struct jtag_tap *tap = NULL; - tap_state_t endstate; + enum tap_state endstate; if ((CMD_ARGC < 2) || (CMD_ARGC % 2)) return ERROR_COMMAND_SYNTAX_ERROR; diff --git a/src/pld/lattice.c b/src/pld/lattice.c index 2997cdc39..93ef3565c 100644 --- a/src/pld/lattice.c +++ b/src/pld/lattice.c @@ -59,7 +59,7 @@ static const struct lattice_devices_elem lattice_devices[] = { {0x010f4043, 362, LATTICE_CERTUS /* LFCPNX-100 */}, }; -int lattice_set_instr(struct jtag_tap *tap, uint8_t new_instr, tap_state_t endstate) +int lattice_set_instr(struct jtag_tap *tap, uint8_t new_instr, enum tap_state endstate) { struct scan_field field; field.num_bits = tap->ir_length; diff --git a/src/pld/lattice.h b/src/pld/lattice.h index 9a76a4ec3..c21598966 100644 --- a/src/pld/lattice.h +++ b/src/pld/lattice.h @@ -20,7 +20,7 @@ struct lattice_pld_device { enum lattice_family_e family; }; -int lattice_set_instr(struct jtag_tap *tap, uint8_t new_instr, tap_state_t endstate); +int lattice_set_instr(struct jtag_tap *tap, uint8_t new_instr, enum tap_state endstate); int lattice_read_u32_register(struct jtag_tap *tap, uint8_t cmd, uint32_t *in_val, uint32_t out_val, bool do_idle); int lattice_read_u64_register(struct jtag_tap *tap, uint8_t cmd, uint64_t *in_val, diff --git a/src/svf/svf.c b/src/svf/svf.c index 9dd2463c0..ce994686f 100644 --- a/src/svf/svf.c +++ b/src/svf/svf.c @@ -75,10 +75,10 @@ static const char *svf_trst_mode_name[4] = { }; struct svf_statemove { - tap_state_t from; - tap_state_t to; + enum tap_state from; + enum tap_state to; uint32_t num_of_moves; - tap_state_t paths[8]; + enum tap_state paths[8]; }; /* @@ -155,10 +155,10 @@ struct svf_xxr_para { struct svf_para { float frequency; - tap_state_t ir_end_state; - tap_state_t dr_end_state; - tap_state_t runtest_run_state; - tap_state_t runtest_end_state; + enum tap_state ir_end_state; + enum tap_state dr_end_state; + enum tap_state runtest_run_state; + enum tap_state runtest_end_state; enum trst_mode trst_mode; struct svf_xxr_para hir_para; @@ -313,9 +313,9 @@ static void svf_free_xxd_para(struct svf_xxr_para *para) } } -int svf_add_statemove(tap_state_t state_to) +int svf_add_statemove(enum tap_state state_to) { - tap_state_t state_from = cmd_queue_cur_state; + enum tap_state state_from = cmd_queue_cur_state; unsigned int index_var; /* when resetting, be paranoid and ignore current state */ @@ -816,7 +816,7 @@ parse_char: return ERROR_OK; } -bool svf_tap_state_is_stable(tap_state_t state) +bool svf_tap_state_is_stable(enum tap_state state) { return (state == TAP_RESET) || (state == TAP_IDLE) || (state == TAP_DRPAUSE) || (state == TAP_IRPAUSE); @@ -995,7 +995,7 @@ static int svf_run_command(struct command_context *cmd_ctx, char *cmd_str) uint8_t **pbuffer_tmp; struct scan_field field; /* for STATE */ - tap_state_t *path = NULL, state; + enum tap_state *path = NULL, state; /* flag padding commands skipped due to -tap command */ int padding_command_skipped = 0; @@ -1498,7 +1498,7 @@ xxr_common: } if (num_of_argu > 2) { /* STATE pathstate1 ... stable_state */ - path = malloc((num_of_argu - 1) * sizeof(tap_state_t)); + path = malloc((num_of_argu - 1) * sizeof(enum tap_state)); if (!path) { LOG_ERROR("not enough memory"); return ERROR_FAIL; diff --git a/src/svf/svf.h b/src/svf/svf.h index 74f7d9ca9..77a0e0dcf 100644 --- a/src/svf/svf.h +++ b/src/svf/svf.h @@ -23,7 +23,7 @@ int svf_register_commands(struct command_context *cmd_ctx); * SVF specification for single-argument STATE commands (and also used * for various other state transitions). */ -int svf_add_statemove(tap_state_t goal_state); +int svf_add_statemove(enum tap_state goal_state); /** * svf_tap_state_is_stable() returns true for stable non-SHIFT states @@ -31,6 +31,6 @@ int svf_add_statemove(tap_state_t goal_state); * @param state The TAP state in question * @return true iff the state is stable and not a SHIFT state. */ -bool svf_tap_state_is_stable(tap_state_t state); +bool svf_tap_state_is_stable(enum tap_state state); #endif /* OPENOCD_SVF_SVF_H */ diff --git a/src/target/arc_jtag.c b/src/target/arc_jtag.c index a186709c6..c2bc5aa8f 100644 --- a/src/target/arc_jtag.c +++ b/src/target/arc_jtag.c @@ -66,7 +66,7 @@ static void arc_jtag_enque_write_ir(struct arc_jtag *jtag_info, uint32_t * @param end_state End state after reading. */ static void arc_jtag_enque_read_dr(struct arc_jtag *jtag_info, uint8_t *data, - tap_state_t end_state) + enum tap_state end_state) { assert(jtag_info); @@ -88,7 +88,7 @@ static void arc_jtag_enque_read_dr(struct arc_jtag *jtag_info, uint8_t *data, * @param end_state End state after writing. */ static void arc_jtag_enque_write_dr(struct arc_jtag *jtag_info, uint32_t data, - tap_state_t end_state) + enum tap_state end_state) { uint8_t out_value[sizeof(uint32_t)] = {0}; @@ -116,7 +116,7 @@ static void arc_jtag_enque_write_dr(struct arc_jtag *jtag_info, uint32_t data, * @param end_state End state after writing. */ static void arc_jtag_enque_set_transaction(struct arc_jtag *jtag_info, - uint32_t new_trans, tap_state_t end_state) + uint32_t new_trans, enum tap_state end_state) { uint8_t out_value[sizeof(uint32_t)] = {0}; diff --git a/src/target/arm11_dbgtap.c b/src/target/arm11_dbgtap.c index 36325911a..4c7211365 100644 --- a/src/target/arm11_dbgtap.c +++ b/src/target/arm11_dbgtap.c @@ -31,13 +31,13 @@ behavior of the FTDI driver IIRC was to go via RTI. Conversely there may be other places in this code where the ARM11 code relies on the driver to hit through RTI when coming from Update-?R. */ -static const tap_state_t arm11_move_pi_to_si_via_ci[] = { +static const enum tap_state arm11_move_pi_to_si_via_ci[] = { TAP_IREXIT2, TAP_IRUPDATE, TAP_DRSELECT, TAP_IRSELECT, TAP_IRCAPTURE, TAP_IRSHIFT }; /* REVISIT no error handling here! */ static void arm11_add_ir_scan_vc(struct jtag_tap *tap, struct scan_field *fields, - tap_state_t state) + enum tap_state state) { if (cmd_queue_cur_state == TAP_IRPAUSE) jtag_add_pathmove(ARRAY_SIZE(arm11_move_pi_to_si_via_ci), @@ -46,13 +46,13 @@ static void arm11_add_ir_scan_vc(struct jtag_tap *tap, struct scan_field *fields jtag_add_ir_scan(tap, fields, state); } -static const tap_state_t arm11_move_pd_to_sd_via_cd[] = { +static const enum tap_state arm11_move_pd_to_sd_via_cd[] = { TAP_DREXIT2, TAP_DRUPDATE, TAP_DRSELECT, TAP_DRCAPTURE, TAP_DRSHIFT }; /* REVISIT no error handling here! */ void arm11_add_dr_scan_vc(struct jtag_tap *tap, int num_fields, struct scan_field *fields, - tap_state_t state) + enum tap_state state) { if (cmd_queue_cur_state == TAP_DRPAUSE) jtag_add_pathmove(ARRAY_SIZE(arm11_move_pd_to_sd_via_cd), @@ -121,7 +121,7 @@ static const char *arm11_ir_to_string(uint8_t ir) * * \remarks This adds to the JTAG command queue but does \em not execute it. */ -void arm11_add_ir(struct arm11_common *arm11, uint8_t instr, tap_state_t state) +void arm11_add_ir(struct arm11_common *arm11, uint8_t instr, enum tap_state state) { struct jtag_tap *tap = arm11->arm.target->tap; @@ -181,7 +181,7 @@ static void arm11_in_handler_scan_n(uint8_t *in_value) */ int arm11_add_debug_scan_n(struct arm11_common *arm11, - uint8_t chain, tap_state_t state) + uint8_t chain, enum tap_state state) { /* Don't needlessly switch the scan chain. * NOTE: the ITRSEL instruction fakes SCREG changing; @@ -240,7 +240,7 @@ int arm11_add_debug_scan_n(struct arm11_common *arm11, * to ensure that the rDTR is ready before that Run-Test/Idle state. */ static void arm11_add_debug_inst(struct arm11_common *arm11, - uint32_t inst, uint8_t *flag, tap_state_t state) + uint32_t inst, uint8_t *flag, enum tap_state state) { JTAG_DEBUG("INST <= 0x%08" PRIx32, inst); @@ -542,7 +542,7 @@ int arm11_run_instr_data_to_core(struct arm11_common *arm11, * https://lists.berlios.de/pipermail/openocd-development/2009-July/009698.html * https://lists.berlios.de/pipermail/openocd-development/2009-August/009865.html */ -static const tap_state_t arm11_move_drpause_idle_drpause_with_delay[] = { +static const enum tap_state arm11_move_drpause_idle_drpause_with_delay[] = { TAP_DREXIT2, TAP_DRUPDATE, TAP_IDLE, TAP_IDLE, TAP_IDLE, TAP_DRSELECT, TAP_DRCAPTURE, TAP_DRSHIFT }; diff --git a/src/target/arm11_dbgtap.h b/src/target/arm11_dbgtap.h index eeb174a8b..74dda6e89 100644 --- a/src/target/arm11_dbgtap.h +++ b/src/target/arm11_dbgtap.h @@ -17,9 +17,9 @@ void arm11_setup_field(struct arm11_common *arm11, int num_bits, void *in_data, void *out_data, struct scan_field *field); void arm11_add_ir(struct arm11_common *arm11, - uint8_t instr, tap_state_t state); + uint8_t instr, enum tap_state state); int arm11_add_debug_scan_n(struct arm11_common *arm11, - uint8_t chain, tap_state_t state); + uint8_t chain, enum tap_state state); int arm11_read_dscr(struct arm11_common *arm11); int arm11_write_dscr(struct arm11_common *arm11, uint32_t dscr); @@ -40,7 +40,7 @@ int arm11_run_instr_data_to_core_via_r0(struct arm11_common *arm11, uint32_t opcode, uint32_t data); void arm11_add_dr_scan_vc(struct jtag_tap *tap, int num_fields, struct scan_field *fields, - tap_state_t state); + enum tap_state state); /** * Used with arm11_sc7_run to make a list of read/write commands for diff --git a/src/target/arm_jtag.c b/src/target/arm_jtag.c index c1ec4735a..e553ec8b8 100644 --- a/src/target/arm_jtag.c +++ b/src/target/arm_jtag.c @@ -19,7 +19,7 @@ #endif int arm_jtag_set_instr_inner(struct jtag_tap *tap, - uint32_t new_instr, void *no_verify_capture, tap_state_t end_state) + uint32_t new_instr, void *no_verify_capture, enum tap_state end_state) { struct scan_field field; uint8_t t[4] = { 0 }; @@ -41,7 +41,7 @@ int arm_jtag_set_instr_inner(struct jtag_tap *tap, return ERROR_OK; } -int arm_jtag_scann_inner(struct arm_jtag *jtag_info, uint32_t new_scan_chain, tap_state_t end_state) +int arm_jtag_scann_inner(struct arm_jtag *jtag_info, uint32_t new_scan_chain, enum tap_state end_state) { int retval = ERROR_OK; diff --git a/src/target/arm_jtag.h b/src/target/arm_jtag.h index 11b7c3efd..5356bcf27 100644 --- a/src/target/arm_jtag.h +++ b/src/target/arm_jtag.h @@ -26,10 +26,10 @@ struct arm_jtag { int arm_jtag_set_instr_inner(struct jtag_tap *tap, uint32_t new_instr, void *no_verify_capture, - tap_state_t end_state); + enum tap_state end_state); static inline int arm_jtag_set_instr(struct jtag_tap *tap, - uint32_t new_instr, void *no_verify_capture, tap_state_t end_state) + uint32_t new_instr, void *no_verify_capture, enum tap_state end_state) { /* inline most common code path */ if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != (new_instr & (BIT(tap->ir_length) - 1))) @@ -39,8 +39,8 @@ static inline int arm_jtag_set_instr(struct jtag_tap *tap, } -int arm_jtag_scann_inner(struct arm_jtag *jtag_info, uint32_t new_scan_chain, tap_state_t end_state); -static inline int arm_jtag_scann(struct arm_jtag *jtag_info, uint32_t new_scan_chain, tap_state_t end_state) +int arm_jtag_scann_inner(struct arm_jtag *jtag_info, uint32_t new_scan_chain, enum tap_state end_state); +static inline int arm_jtag_scann(struct arm_jtag *jtag_info, uint32_t new_scan_chain, enum tap_state end_state) { /* inline most common code path */ int retval = ERROR_OK; diff --git a/src/target/dsp5680xx.c b/src/target/dsp5680xx.c index 8b3b1c49b..b370aafa4 100644 --- a/src/target/dsp5680xx.c +++ b/src/target/dsp5680xx.c @@ -44,7 +44,7 @@ static int reset_jtag(void) { int retval; - tap_state_t states[2]; + enum tap_state states[2]; const char *cp = "RESET"; diff --git a/src/target/xscale.c b/src/target/xscale.c index 155abaef1..83afd5de2 100644 --- a/src/target/xscale.c +++ b/src/target/xscale.c @@ -137,7 +137,7 @@ static int xscale_verify_pointer(struct command_invocation *cmd, return ERROR_OK; } -static int xscale_jtag_set_instr(struct jtag_tap *tap, uint32_t new_instr, tap_state_t end_state) +static int xscale_jtag_set_instr(struct jtag_tap *tap, uint32_t new_instr, enum tap_state end_state) { assert(tap); @@ -232,7 +232,7 @@ static int xscale_receive(struct target *target, uint32_t *buffer, int num_words struct xscale_common *xscale = target_to_xscale(target); int retval = ERROR_OK; - tap_state_t path[3]; + enum tap_state path[3]; struct scan_field fields[3]; uint8_t *field0 = malloc(num_words * 1); uint8_t field0_check_value = 0x2; @@ -330,8 +330,8 @@ static int xscale_receive(struct target *target, uint32_t *buffer, int num_words static int xscale_read_tx(struct target *target, int consume) { struct xscale_common *xscale = target_to_xscale(target); - tap_state_t path[3]; - tap_state_t noconsume_path[6]; + enum tap_state path[3]; + enum tap_state noconsume_path[6]; int retval; struct timeval timeout, now; struct scan_field fields[3]; diff --git a/src/target/xtensa/xtensa_debug_module.c b/src/target/xtensa/xtensa_debug_module.c index 8045779b8..943f199c1 100644 --- a/src/target/xtensa/xtensa_debug_module.c +++ b/src/target/xtensa/xtensa_debug_module.c @@ -60,7 +60,7 @@ static void xtensa_dm_add_dr_scan(struct xtensa_debug_module *dm, int len, const uint8_t *src, uint8_t *dest, - tap_state_t endstate) + enum tap_state endstate) { struct scan_field field; diff --git a/src/xsvf/xsvf.c b/src/xsvf/xsvf.c index 88275043e..617c2f423 100644 --- a/src/xsvf/xsvf.c +++ b/src/xsvf/xsvf.c @@ -111,10 +111,10 @@ TDO (1); static int xsvf_fd; -/* map xsvf tap state to an openocd "tap_state_t" */ -static tap_state_t xsvf_to_tap(int xsvf_state) +/* map xsvf tap state to an openocd "enum tap_state" */ +static enum tap_state xsvf_to_tap(int xsvf_state) { - tap_state_t ret; + enum tap_state ret; switch (xsvf_state) { case XSV_RESET: @@ -196,16 +196,16 @@ COMMAND_HANDLER(handle_xsvf_command) int xruntest = 0; /* number of TCK cycles OR *microseconds */ int xrepeat = 0; /* number of retries */ - tap_state_t xendir = TAP_IDLE; /* see page 8 of the SVF spec, initial + enum tap_state xendir = TAP_IDLE; /* see page 8 of the SVF spec, initial *xendir to be TAP_IDLE */ - tap_state_t xenddr = TAP_IDLE; + enum tap_state xenddr = TAP_IDLE; uint8_t opcode; uint8_t uc = 0; long file_offset = 0; int loop_count = 0; - tap_state_t loop_state = TAP_IDLE; + enum tap_state loop_state = TAP_IDLE; int loop_clocks = 0; int loop_usecs = 0; @@ -216,7 +216,7 @@ COMMAND_HANDLER(handle_xsvf_command) int verbose = 1; bool collecting_path = false; - tap_state_t path[XSTATE_MAX_PATH]; + enum tap_state path[XSTATE_MAX_PATH]; unsigned int pathlen = 0; /* a flag telling whether to clock TCK during waits, @@ -272,7 +272,7 @@ COMMAND_HANDLER(handle_xsvf_command) * or terminate a path. */ if (collecting_path) { - tap_state_t mystate; + enum tap_state mystate; switch (opcode) { case XCOMMENT: @@ -455,7 +455,7 @@ COMMAND_HANDLER(handle_xsvf_command) * will be skipped entirely if xrepeat is set to zero. */ - static tap_state_t exception_path[] = { + static enum tap_state exception_path[] = { TAP_DREXIT2, TAP_DRSHIFT, TAP_DREXIT1, @@ -563,7 +563,7 @@ COMMAND_HANDLER(handle_xsvf_command) case XSTATE: { - tap_state_t mystate; + enum tap_state mystate; if (read(xsvf_fd, &uc, 1) < 0) { do_abort = 1; @@ -654,7 +654,7 @@ COMMAND_HANDLER(handle_xsvf_command) uint8_t short_buf[2]; uint8_t *ir_buf; int bitcount; - tap_state_t my_end_state = xruntest ? TAP_IDLE : xendir; + enum tap_state my_end_state = xruntest ? TAP_IDLE : xendir; if (opcode == XSIR) { /* one byte bitcount */ @@ -744,8 +744,8 @@ COMMAND_HANDLER(handle_xsvf_command) uint8_t end; uint8_t delay_buf[4]; - tap_state_t wait_state; - tap_state_t end_state; + enum tap_state wait_state; + enum tap_state end_state; int delay; if (read(xsvf_fd, &wait_local, 1) < 0 @@ -788,8 +788,8 @@ COMMAND_HANDLER(handle_xsvf_command) uint8_t usecs_buf[4]; uint8_t wait_local; uint8_t end; - tap_state_t wait_state; - tap_state_t end_state; + enum tap_state wait_state; + enum tap_state end_state; int clock_count; int usecs; From 9ccd6265dd56c75cc8d58359d33bf6d65a7524ab Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 10 Jan 2025 17:11:24 +0100 Subject: [PATCH 20/29] checkpatch: enable check for new typedefs We should strictly check for every new typedef. Let checkpatch detect them and let developer use Checkpatch-ignore: NEW_TYPEDEFS if it's really needed to add a new typedef. With this change chackpatch will not complain for typedef on function's type but only on enum, struct, variable's type. Change-Id: I644a753e97de877d892af3a0219716f022fb1c59 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/8710 Reviewed-by: zapb Tested-by: jenkins --- .checkpatch.conf | 1 - 1 file changed, 1 deletion(-) diff --git a/.checkpatch.conf b/.checkpatch.conf index 8cb9a3729..f432503e1 100644 --- a/.checkpatch.conf +++ b/.checkpatch.conf @@ -17,7 +17,6 @@ --ignore LINE_SPACING --ignore LOGICAL_CONTINUATIONS --ignore MACRO_WITH_FLOW_CONTROL ---ignore NEW_TYPEDEFS --ignore PARENTHESIS_ALIGNMENT --ignore PREFER_DEFINED_ATTRIBUTE_MACRO --ignore PREFER_FALLTHROUGH From 9bb0a4558bc84b8be63aa937d4b7b9283614f132 Mon Sep 17 00:00:00 2001 From: Chris Friedt Date: Mon, 9 Dec 2024 16:11:03 -0500 Subject: [PATCH 21/29] target/arc: add RTT commands Since RTT is architecture agnostic, add support for using it on the ARC architecture as well. Change-Id: Icd0dec105177a1a224bfb1a63f0be5f03561b166 Signed-off-by: Chris Friedt Reviewed-on: https://review.openocd.org/c/openocd/+/8720 Reviewed-by: zapb Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/target/arc.h | 1 + src/target/arc_cmd.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/target/arc.h b/src/target/arc.h index a351802ac..4255840d1 100644 --- a/src/target/arc.h +++ b/src/target/arc.h @@ -22,6 +22,7 @@ #include "target_request.h" #include "target_type.h" #include "helper/bits.h" +#include "rtt/rtt.h" #include "arc_jtag.h" #include "arc_cmd.h" diff --git a/src/target/arc_cmd.c b/src/target/arc_cmd.c index e7760b037..bf8a8aa28 100644 --- a/src/target/arc_cmd.c +++ b/src/target/arc_cmd.c @@ -906,5 +906,8 @@ const struct command_registration arc_monitor_command_handlers[] = { .usage = "", .chain = arc_core_command_handlers, }, + { + .chain = rtt_target_command_handlers, + }, COMMAND_REGISTRATION_DONE }; From 44e782d55bf1ce0d924c082281082496cdc2495e Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Thu, 16 Jan 2025 22:33:48 -0500 Subject: [PATCH 22/29] target/arc: allow reading memory while target runs There is no reason that ARC can't support reading from memory over JTAG while the target is executing, and this is in fact required for RTT support. Remove this check from arc_mem_read and arc_mem_write Change-Id: I2accfb4b99bf77c5473d133623e0eb0632cb45f6 Signed-off-by: Daniel DeGrasse Reviewed-on: https://review.openocd.org/c/openocd/+/8721 Tested-by: jenkins Reviewed-by: Evgeniy Didin Reviewed-by: Antonio Borneo --- src/target/arc_mem.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/target/arc_mem.c b/src/target/arc_mem.c index 3daed1cbb..5132aca3d 100644 --- a/src/target/arc_mem.c +++ b/src/target/arc_mem.c @@ -161,11 +161,6 @@ int arc_mem_write(struct target *target, target_addr_t address, uint32_t size, LOG_TARGET_DEBUG(target, "address: 0x%08" TARGET_PRIxADDR ", size: %" PRIu32 ", count: %" PRIu32, address, size, count); - if (target->state != TARGET_HALTED) { - LOG_TARGET_ERROR(target, "not halted"); - return ERROR_TARGET_NOT_HALTED; - } - /* sanitize arguments */ if (((size != 4) && (size != 2) && (size != 1)) || !(count) || !(buffer)) return ERROR_COMMAND_SYNTAX_ERROR; @@ -246,11 +241,6 @@ int arc_mem_read(struct target *target, target_addr_t address, uint32_t size, LOG_TARGET_DEBUG(target, "Read memory: addr=0x%08" TARGET_PRIxADDR ", size=%" PRIu32 ", count=%" PRIu32, address, size, count); - if (target->state != TARGET_HALTED) { - LOG_TARGET_WARNING(target, "target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - /* Sanitize arguments */ if (((size != 4) && (size != 2) && (size != 1)) || !(count) || !(buffer)) return ERROR_COMMAND_SYNTAX_ERROR; From a71f2b70894a8118730d912edf27fe488580bd4c Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sat, 25 Jan 2025 17:26:16 +0100 Subject: [PATCH 23/29] README: report dependency from libjim The support for jimtcl submodule is deprecated. Report libjim as a dependency for building OpenOCD. Change-Id: Iaaeb03dc810451c0d72add281016c81b8cbf7059 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/8722 Reviewed-by: zapb Tested-by: jenkins --- README | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README b/README index 950c71f70..fba758cfe 100644 --- a/README +++ b/README @@ -209,9 +209,7 @@ You'll also need: - make - libtool - pkg-config >= 0.23 or pkgconf - -OpenOCD uses jimtcl library; build from git can retrieve jimtcl as git -submodule. +- libjim >= 0.79 Additionally, for building from git: From 4deb76fc9d48aff71b1f2875eecc4b6964c0a0c7 Mon Sep 17 00:00:00 2001 From: "R. Diez" Date: Sat, 25 Jan 2025 22:06:22 +0100 Subject: [PATCH 24/29] options.c: option --help should yield exit code 0 --help is supported and there is no reason to signal failure Change-Id: I59fda5336df47ec0b8172541a5fbfe60014bba7e Signed-off-by: R. Diez Reviewed-on: https://review.openocd.org/c/openocd/+/8723 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/helper/options.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/helper/options.c b/src/helper/options.c index 50977a610..735b8af5f 100644 --- a/src/helper/options.c +++ b/src/helper/options.c @@ -334,7 +334,7 @@ int parse_cmdline_args(struct command_context *cmd_ctx, int argc, char *argv[]) LOG_OUTPUT(" | -d\tset debug level to \n"); LOG_OUTPUT("--log_output | -l\tredirect log output to file \n"); LOG_OUTPUT("--command | -c\trun \n"); - exit(-1); + exit(0); } if (version_flag) { From 5e4ad24ba610e81ee6e9358154ef176e15c36fe7 Mon Sep 17 00:00:00 2001 From: "R. Diez" Date: Sat, 25 Jan 2025 21:04:05 +0100 Subject: [PATCH 25/29] configure.ac: show vdebug in the config summary Also enable this adapter by default (auto). Change-Id: Id011168b93c4cdc602ab78eabfb9a64ca8d8a7df Signed-off-by: R. Diez Reviewed-on: https://review.openocd.org/c/openocd/+/8601 Reviewed-by: Antonio Borneo Tested-by: jenkins --- configure.ac | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/configure.ac b/configure.ac index 4b10aabd5..fda0b2a36 100644 --- a/configure.ac +++ b/configure.ac @@ -172,6 +172,8 @@ m4_define([SERIAL_PORT_ADAPTERS], m4_define([LINUXSPIDEV_ADAPTER], [[[linuxspidev], [Linux spidev driver], [LINUXSPIDEV]]]) +m4_define([VDEBUG_ADAPTER], + [[[vdebug], [Cadence Virtual Debug Interface], [VDEBUG]]]) # The word 'Adapter' in "Dummy Adapter" below must begin with a capital letter # because there is an M4 macro called 'adapter'. @@ -302,6 +304,7 @@ AC_ARG_ADAPTERS([ LINUXSPIDEV_ADAPTER, SERIAL_PORT_ADAPTERS, DUMMY_ADAPTER, + VDEBUG_ADAPTER, PCIE_ADAPTERS, LIBJAYLINK_ADAPTERS ],[auto]) @@ -324,10 +327,6 @@ AC_ARG_ENABLE([jtag_vpi], AS_HELP_STRING([--enable-jtag_vpi], [Enable building support for JTAG VPI]), [build_jtag_vpi=$enableval], [build_jtag_vpi=no]) -AC_ARG_ENABLE([vdebug], - AS_HELP_STRING([--enable-vdebug], [Enable building support for Cadence Virtual Debug Interface]), - [build_vdebug=$enableval], [build_vdebug=no]) - AC_ARG_ENABLE([jtag_dpi], AS_HELP_STRING([--enable-jtag_dpi], [Enable building support for JTAG DPI]), [build_jtag_dpi=$enableval], [build_jtag_dpi=no]) @@ -581,12 +580,6 @@ AS_IF([test "x$build_jtag_vpi" = "xyes"], [ AC_DEFINE([BUILD_JTAG_VPI], [0], [0 if you don't want JTAG VPI.]) ]) -AS_IF([test "x$build_vdebug" = "xyes"], [ - AC_DEFINE([BUILD_VDEBUG], [1], [1 if you want Cadence vdebug interface.]) -], [ - AC_DEFINE([BUILD_VDEBUG], [0], [0 if you don't want Cadence vdebug interface.]) -]) - AS_IF([test "x$build_jtag_dpi" = "xyes"], [ AC_DEFINE([BUILD_JTAG_DPI], [1], [1 if you want JTAG DPI.]) ], [ @@ -738,6 +731,7 @@ PROCESS_ADAPTERS([PCIE_ADAPTERS], ["x$is_linux" = "xyes"], [Linux build]) PROCESS_ADAPTERS([SERIAL_PORT_ADAPTERS], ["x$can_build_buspirate" = "xyes"], [internal error: validation should happen beforehand]) PROCESS_ADAPTERS([LINUXSPIDEV_ADAPTER], ["x$is_linux" = "xyes"], [Linux spidev]) +PROCESS_ADAPTERS([VDEBUG_ADAPTER], [true], [unused]) PROCESS_ADAPTERS([DUMMY_ADAPTER], [true], [unused]) AS_IF([test "x$enable_linuxgpiod" != "xno"], [ @@ -786,7 +780,6 @@ AM_CONDITIONAL([IMX_GPIO], [test "x$build_imx_gpio" = "xyes"]) AM_CONDITIONAL([AM335XGPIO], [test "x$build_am335xgpio" = "xyes"]) AM_CONDITIONAL([BITBANG], [test "x$build_bitbang" = "xyes"]) AM_CONDITIONAL([JTAG_VPI], [test "x$build_jtag_vpi" = "xyes"]) -AM_CONDITIONAL([VDEBUG], [test "x$build_vdebug" = "xyes"]) AM_CONDITIONAL([JTAG_DPI], [test "x$build_jtag_dpi" = "xyes"]) AM_CONDITIONAL([USB_BLASTER_DRIVER], [test "x$enable_usb_blaster" != "xno" -o "x$enable_usb_blaster_2" != "xno"]) AM_CONDITIONAL([AMTJTAGACCEL], [test "x$build_amtjtagaccel" = "xyes"]) @@ -892,6 +885,7 @@ m4_foreach([adapter], [USB1_ADAPTERS, LIBGPIOD_ADAPTERS, LIBJAYLINK_ADAPTERS, PCIE_ADAPTERS, SERIAL_PORT_ADAPTERS, LINUXSPIDEV_ADAPTER, + VDEBUG_ADAPTER, DUMMY_ADAPTER, OPTIONAL_LIBRARIES, COVERAGE], From dcf02f46ff8355eb3f889aaa9d660f73dacede4f Mon Sep 17 00:00:00 2001 From: "R. Diez" Date: Sat, 25 Jan 2025 23:04:50 +0100 Subject: [PATCH 26/29] Makefile.am: DISTCHECK_CONFIGURE_FLAGS -> AM_DISTCHECK_CONFIGURE_FLAGS The Automake manual states: "The user can still extend or override the flags provided there by defining the DISTCHECK_CONFIGURE_FLAGS variable". Overriding variable DISTCHECK_CONFIGURE_FLAGS in Makefile.am makes it impossible for the user to do that. I discovered this when trying to pass --enable-internal-jimtcl to distcheck. Change-Id: Ibe5b1f23ccf3fbaa21c48b574a1b3f3e9f6fb916 Signed-off-by: R. Diez Reviewed-on: https://review.openocd.org/c/openocd/+/8724 Reviewed-by: Antonio Borneo Tested-by: jenkins --- Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 155a2b3bb..271a2c165 100644 --- a/Makefile.am +++ b/Makefile.am @@ -7,7 +7,7 @@ AUTOMAKE_OPTIONS = gnu 1.6 .DELETE_ON_ERROR: # make sure we pass the correct jimtcl flags to distcheck -DISTCHECK_CONFIGURE_FLAGS = --disable-install-jim +AM_DISTCHECK_CONFIGURE_FLAGS = --disable-install-jim # do not run Jim Tcl tests (esp. during distcheck) check-recursive: SUBDIRS := From 71f92c94468f370be80ce60dd76d5d924ddba69a Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Tue, 28 Jan 2025 20:43:33 +0100 Subject: [PATCH 27/29] target/cortex_m: call adapter_deassert_reset() only if srst is configured Deasserting is useless if reset was not asserted except the very corner case: changed reset_config during reset processing. Change-Id: I1d1ea142980d67293daa348a2869b68ffd78d0eb Signed-off-by: Tomas Vanek Reviewed-on: https://review.openocd.org/c/openocd/+/8734 Reviewed-by: Antonio Borneo Tested-by: jenkins --- src/target/cortex_m.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index 2cea203a2..9314d6675 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -1849,11 +1849,13 @@ static int cortex_m_deassert_reset(struct target *target) target_state_name(target), target_was_examined(target) ? "" : " not"); - /* deassert reset lines */ - adapter_deassert_reset(); - enum reset_types jtag_reset_config = jtag_get_reset_config(); + /* deassert reset lines */ + if (jtag_reset_config & RESET_HAS_SRST) + adapter_deassert_reset(); + + if ((jtag_reset_config & RESET_HAS_SRST) && !(jtag_reset_config & RESET_SRST_NO_GATING) && armv7m->debug_ap) { From ed4e58410446343a485625ee2722144cc23d55a6 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Mon, 3 Feb 2025 21:45:07 +0100 Subject: [PATCH 28/29] jtag/core: fix segfault when adapter driver has no reset method xlnx-pcie-xvc and linuxspidev adapter drivers does not implement the reset method. Although it is likely both adapters will implement the method in the near future, avoid segfault and return an error instead. Change-Id: If8ddf165dbc563cf6d64b2094968151075778ba7 Signed-off-by: Tomas Vanek Fixes: commit 8850eb8f2c51 ("swd: get rid of jtag queue to assert/deassert srst") Reviewed-on: https://review.openocd.org/c/openocd/+/8735 Reviewed-by: Antonio Borneo Tested-by: jenkins --- src/jtag/core.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/jtag/core.c b/src/jtag/core.c index 89d53aecb..030c173be 100644 --- a/src/jtag/core.c +++ b/src/jtag/core.c @@ -631,6 +631,13 @@ static int adapter_system_reset(int req_srst) /* Maybe change SRST signal state */ if (jtag_srst != req_srst) { + if (!adapter_driver->reset) { + if (req_srst) + LOG_ERROR("Adapter driver does not implement SRST handling"); + + return ERROR_NOT_IMPLEMENTED; + } + retval = adapter_driver->reset(0, req_srst); if (retval != ERROR_OK) { LOG_ERROR("SRST error"); From 1f3f635693a1ddc85f362dc324cb49c3e7b75f27 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 6 Feb 2025 11:48:30 +0100 Subject: [PATCH 29/29] build: drop space after 'angie' folder name The makefile consider the two white spaces between the end of the folder name and the '#' character for the beginning of the comment as part of the folder name. This cause 'make install' to create a folder named 'angie ' that is not welcome on all the OS. Drop the comment and the space after the folder name. Reported-by: Liviu Ionescu Change-Id: Iadd6803431edb83d0d84f4e4dc6d36b454f912ac Signed-off-by: Antonio Borneo Fixes: 0ed03df6e95b ("amend angie build definitions to fix make dist") Reviewed-on: https://review.openocd.org/c/openocd/+/8740 Reviewed-by: Liviu Ionescu Tested-by: jenkins Reviewed-by: Adrien Charruel --- src/jtag/drivers/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jtag/drivers/Makefile.am b/src/jtag/drivers/Makefile.am index ec233b247..b0dd8e3ad 100644 --- a/src/jtag/drivers/Makefile.am +++ b/src/jtag/drivers/Makefile.am @@ -125,7 +125,7 @@ dist_ulink_DATA = $(ULINK_FIRMWARE)/ulink_firmware.hex endif if ANGIE - angiedir = $(pkgdatadir)/angie # This is only for dist_angie_DATA. + angiedir = $(pkgdatadir)/angie DRIVERFILES += %D%/angie.c DRIVERFILES += %D%/angie/include/msgtypes.h EXTRA_DIST += %D%/angie/README