pld: add support for altera/intel devices 55/7355/18
authorDaniel Anselmi <danselmi@gmx.ch>
Mon, 12 Dec 2022 08:49:51 +0000 (09:49 +0100)
committerAntonio Borneo <borneo.antonio@gmail.com>
Sun, 30 Apr 2023 14:54:38 +0000 (14:54 +0000)
Change-Id: I7977d39c9037ae71139f78c8d381f5f925dc3489
Signed-off-by: Daniel Anselmi <danselmi@gmx.ch>
Reviewed-on: https://review.openocd.org/c/openocd/+/7355
Tested-by: jenkins
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
17 files changed:
doc/openocd.texi
src/pld/Makefile.am
src/pld/intel.c [new file with mode: 0644]
src/pld/pld.c
tcl/board/bemicro_cycloneiii.cfg [new file with mode: 0644]
tcl/cpld/altera-5m570z-cpld.cfg
tcl/cpld/altera-epm240.cfg
tcl/cpld/altera-max10.cfg [new file with mode: 0644]
tcl/cpld/altera-maxii.cfg [new file with mode: 0644]
tcl/cpld/altera-maxv.cfg [new file with mode: 0644]
tcl/fpga/altera-10m50.cfg
tcl/fpga/altera-arriaii.cfg [new file with mode: 0644]
tcl/fpga/altera-cyclone10.cfg [new file with mode: 0644]
tcl/fpga/altera-cycloneiii.cfg [new file with mode: 0644]
tcl/fpga/altera-cycloneiv.cfg [new file with mode: 0644]
tcl/fpga/altera-cyclonev.cfg [new file with mode: 0644]
tcl/fpga/altera-ep3c10.cfg

index 6037b8bb23cda409031a73a9385c68f50e6c60a6..8099455ac2211da7868e7fa264b4d0d854cc9780 100644 (file)
@@ -8530,6 +8530,34 @@ This driver can be used to load the bitstream into the FPGA.
 @end deffn
 
 
+@deffn {FPGA Driver} {intel} [@option{family}]
+This driver can be used to load the bitstream into Intel (former Altera) FPGAs.
+The families Cyclone III, Cyclone IV, Cyclone V, Cyclone 10, Arria II are supported.
+@c Arria V and Arria 10, MAX II, MAX V, MAX10)
+
+The option @option{family} is one of @var{cycloneiii cycloneiv cyclonev cyclone10 arriaii}.
+This is needed when the JTAG ID of the device is ambiguous (same ID is used for chips in different families).
+
+As input file format the driver supports a '.rbf' (raw bitstream file) file. The '.rbf' file can be generated
+from a '.sof' file with @verb{|quartus_cpf -c blinker.sof blinker.rbf|}
+
+Defines a new PLD device, an FPGA of the Cyclone III family, using the TAP named @verb{|cycloneiii.tap|}:
+@example
+pld device intel cycloneiii.tap cycloneiii
+@end example
+
+@deffn {Command} {intel set_bscan} num len
+Set boundary scan register length of FPGA @var{num} to @var{len}. This is needed because the
+length can vary between chips with the same JTAG ID.
+@end deffn
+
+@deffn {Command} {intel set_check_pos} num pos
+Selects the position @var{pos} in the boundary-scan register. The bit at this
+position is checked after loading the bitstream and must be '1', which is the case when no error occurred.
+With a value of -1 for @var{pos} the check will be omitted.
+@end deffn
+@end deffn
+
 
 @node General Commands
 @chapter General Commands
index be33bcd0982d3656c1ebfc59d6104122a1cae186..a13f738ea6b8e3bb1e4d52561d59201d75b33c62 100644 (file)
@@ -6,6 +6,7 @@ noinst_LTLIBRARIES += %D%/libpld.la
        %D%/ecp2_3.c \
        %D%/ecp5.c \
        %D%/efinix.c \
+       %D%/intel.c \
        %D%/lattice.c \
        %D%/lattice_bit.c \
        %D%/pld.c \
diff --git a/src/pld/intel.c b/src/pld/intel.c
new file mode 100644 (file)
index 0000000..119a569
--- /dev/null
@@ -0,0 +1,474 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/***************************************************************************
+ *   Copyright (C) 2022 by Daniel Anselmi                                  *
+ *   danselmi@gmx.ch                                                       *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <jtag/jtag.h>
+#include <jtag/adapter.h>
+#include <helper/system.h>
+#include <helper/log.h>
+
+#include "pld.h"
+#include "raw_bit.h"
+
+#define BYPASS 0x3FF
+
+enum intel_family_e {
+       INTEL_CYCLONEIII,
+       INTEL_CYCLONEIV,
+       INTEL_CYCLONEV,
+       INTEL_CYCLONE10,
+       INTEL_ARRIAII,
+       INTEL_UNKNOWN
+};
+
+struct intel_pld_device {
+       struct jtag_tap *tap;
+       unsigned int boundary_scan_length;
+       int checkpos;
+       enum intel_family_e family;
+};
+
+struct intel_device_parameters_elem {
+       uint32_t id;
+       unsigned int boundary_scan_length;
+       int checkpos;
+       enum intel_family_e family;
+};
+
+static const struct intel_device_parameters_elem intel_device_parameters[] = {
+       {0x020f10dd,  603,  226, INTEL_CYCLONEIII}, /* EP3C5 EP3C10 */
+       {0x020f20dd, 1080,  409, INTEL_CYCLONEIII}, /* EP3C16 */
+       {0x020f30dd,  732,  286, INTEL_CYCLONEIII}, /* EP3C25 */
+       {0x020f40dd, 1632,  604, INTEL_CYCLONEIII}, /* EP3C40 */
+       {0x020f50dd, 1164,  442, INTEL_CYCLONEIII}, /* EP3C55 */
+       {0x020f60dd, 1314,  502, INTEL_CYCLONEIII}, /* EP3C80 */
+       {0x020f70dd, 1620,  613, INTEL_CYCLONEIII}, /* EP3C120*/
+       {0x027010dd, 1314,  226, INTEL_CYCLONEIII}, /* EP3CLS70 */
+       {0x027000dd, 1314,  226, INTEL_CYCLONEIII}, /* EP3CLS100 */
+       {0x027030dd, 1314,  409, INTEL_CYCLONEIII}, /* EP3CLS150 */
+       {0x027020dd, 1314,  409, INTEL_CYCLONEIII}, /* EP3CLS200 */
+
+       {0x020f10dd,  603,  226, INTEL_CYCLONEIV}, /* EP4CE6 EP4CE10 */
+       {0x020f20dd, 1080,  409, INTEL_CYCLONEIV}, /* EP4CE15 */
+       {0x020f30dd,  732,  286, INTEL_CYCLONEIV}, /* EP4CE22 */
+       {0x020f40dd, 1632,  604, INTEL_CYCLONEIV}, /* EP4CE30 EP4CE40 */
+       {0x020f50dd, 1164,  442, INTEL_CYCLONEIV}, /* EP4CE55 */
+       {0x020f60dd, 1314,  502, INTEL_CYCLONEIV}, /* EP4CE75 */
+       {0x020f70dd, 1620,  613, INTEL_CYCLONEIV}, /* EP4CE115 */
+       {0x028010dd,  260,  229, INTEL_CYCLONEIV}, /* EP4CGX15 */
+       {0x028120dd,  494,  463, INTEL_CYCLONEIV}, /* EP4CGX22 */
+       {0x028020dd,  494,  463, INTEL_CYCLONEIV}, /* EP4CGX30 */
+       {0x028230dd, 1006,  943, INTEL_CYCLONEIV}, /* EP4CGX30 */
+       {0x028130dd, 1006,  943, INTEL_CYCLONEIV}, /* EP4CGX50 */
+       {0x028030dd, 1006,  943, INTEL_CYCLONEIV}, /* EP4CGX75 */
+       {0x028140dd, 1495, 1438, INTEL_CYCLONEIV}, /* EP4CGX110 */
+       {0x028040dd, 1495, 1438, INTEL_CYCLONEIV}, /* EP4CGX150 */
+
+       {0x02b150dd,  864, 163, INTEL_CYCLONEV}, /* 5CEBA2F23 5CEBA2F17 5CEFA2M13 5CEFA2F23 5CEBA2U15 5CEFA2U19 5CEBA2U19 */
+       {0x02d020dd, 1485,  19, INTEL_CYCLONEV}, /* 5CSXFC6D6F31 5CSTFD6D5F31 5CSEBA6U23 5CSEMA6U23 5CSEBA6U19 5CSEBA6U23
+                                                                                       5CSEBA6U19 5CSEMA6F31 5CSXFC6C6U23 */
+       {0x02b040dd, 1728,  -1, INTEL_CYCLONEV}, /* 5CGXFC9EF35 5CGXBC9AU19 5CGXBC9CF23 5CGTFD9CF23 5CGXFC9AU19 5CGXFC9CF23
+                                                                                       5CGXFC9EF31 5CGXFC9DF27 5CGXBC9DF27 5CGXBC9EF31 5CGTFD9EF31 5CGTFD9EF35
+                                                                                       5CGTFD9AU19 5CGXBC9EF35 5CGTFD9DF27 */
+       {0x02b050dd,  864, 163, INTEL_CYCLONEV}, /* 5CEFA4U19 5CEFA4F23 5CEFA4M13 5CEBA4F17 5CEBA4U15 5CEBA4U19 5CEBA4F23 */
+       {0x02b030dd, 1488,  19, INTEL_CYCLONEV}, /* 5CGXBC7CU19 5CGTFD7CU19 5CGTFD7DF27 5CGXFC7BM15 5CGXFC7DF27 5CGXFC7DF31
+                                                                                       5CGTFD7CF23 5CGXBC7CF23 5CGXBC7DF31 5CGTFD7BM15 5CGXFC7CU19 5CGTFD7DF31
+                                                                                       5CGXBC7BM15 5CGXFC7CF23 5CGXBC7DF27 */
+       {0x02d120dd, 1485,  -1, INTEL_CYCLONEV}, /* 5CSEBA5U23 5CSEBA5U23 5CSTFD5D5F31 5CSEBA5U19 5CSXFC5D6F31 5CSEMA5U23
+                                                                                       5CSEMA5F31 5CSXFC5C6U23 5CSEBA5U19 */
+       {0x02b220dd, 1104,  19, INTEL_CYCLONEV}, /* 5CEBA5U19 5CEFA5U19 5CEFA5M13 5CEBA5F23 5CEFA5F23 */
+       {0x02b020dd, 1104,  19, INTEL_CYCLONEV}, /* 5CGXBC5CU19 5CGXFC5F6M11 5CGXFC5CM13 5CGTFD5CF23 5CGXBC5CF23 5CGTFD5CF27
+                                                                                       5CGTFD5F5M11 5CGXFC5CF27 5CGXFC5CU19 5CGTFD5CM13 5CGXFC5CF23 5CGXBC5CF27
+                                                                                       5CGTFD5CU19 */
+       {0x02d010dd, 1197,  -1, INTEL_CYCLONEV}, /* 5CSEBA4U23 5CSXFC4C6U23 5CSEMA4U23 5CSEBA4U23 5CSEBA4U19 5CSEBA4U19
+                                                                                       5CSXFC2C6U23 */
+       {0x02b120dd, 1104,  19, INTEL_CYCLONEV}, /* 5CGXFC4CM13 5CGXFC4CU19 5CGXFC4F6M11 5CGXBC4CU19 5CGXFC4CF27 5CGXBC4CF23
+                                                                                       5CGXBC4CF27 5CGXFC4CF23 */
+       {0x02b140dd, 1728,  -1, INTEL_CYCLONEV}, /* 5CEFA9F31 5CEBA9F31 5CEFA9F27 5CEBA9U19 5CEBA9F27 5CEFA9U19 5CEBA9F23
+                                                                                       5CEFA9F23 */
+       {0x02b010dd,  720,  19, INTEL_CYCLONEV}, /* 5CGXFC3U15 5CGXBC3U15 5CGXFC3F23 5CGXFC3U19 5CGXBC3U19 5CGXBC3F23 */
+       {0x02b130dd, 1488,  19, INTEL_CYCLONEV}, /* 5CEFA7F31 5CEBA7F27 5CEBA7M15 5CEFA7U19 5CEBA7F23 5CEFA7F23 5CEFA7F27
+                                                                                       5CEFA7M15 5CEBA7U19 5CEBA7F31 */
+       {0x02d110dd, 1197,  -1, INTEL_CYCLONEV}, /* 5CSEBA2U23 5CSEMA2U23 5CSEBA2U23 5CSEBA2U19 5CSEBA2U19 */
+
+       {0x020f10dd,  603, 226, INTEL_CYCLONE10}, /* 10CL006E144 10CL006U256 10CL010M164 10CL010U256 10CL010E144 */
+       {0x020f20dd, 1080, 409, INTEL_CYCLONE10}, /* 10CL016U256 10CL016E144 10CL016U484 10CL016F484 10CL016M164 */
+       {0x020f30dd,  732, 286, INTEL_CYCLONE10}, /* 10CL025U256 10CL025E144 */
+       {0x020f40dd, 1632, 604, INTEL_CYCLONE10}, /* 10CL040F484 10CL040U484 */
+       {0x020f50dd, 1164, 442, INTEL_CYCLONE10}, /* 10CL055F484 10CL055U484 */
+       {0x020f60dd, 1314, 502, INTEL_CYCLONE10}, /* 10CL080F484 10CL080F780 10CL080U484 */
+       {0x020f70dd, 1620, 613, INTEL_CYCLONE10}, /* 10CL120F484 10CL120F780 */
+
+       {0x02e120dd, 1339, -1, INTEL_CYCLONE10}, /* 10CX085U484 10CX085F672 */
+       {0x02e320dd, 1339, -1, INTEL_CYCLONE10}, /* 10CX105F780 10CX105U484 10CX105F672 */
+       {0x02e720dd, 1339, -1, INTEL_CYCLONE10}, /* 10CX150F672 10CX150F780 10CX150U484 */
+       {0x02ef20dd, 1339, -1, INTEL_CYCLONE10}, /* 10CX220F672 10CX220F780 10CX220U484 */
+
+       {0x025120dd, 1227, 1174, INTEL_ARRIAII}, /* EP2AGX45 */
+       {0x025020dd, 1227,   -1, INTEL_ARRIAII}, /* EP2AGX65 */
+       {0x025130dd, 1467,   -1, INTEL_ARRIAII}, /* EP2AGX95 */
+       {0x025030dd, 1467,   -1, INTEL_ARRIAII}, /* EP2AGX125 */
+       {0x025140dd, 1971,   -1, INTEL_ARRIAII}, /* EP2AGX190 */
+       {0x025040dd, 1971,   -1, INTEL_ARRIAII}, /* EP2AGX260 */
+       {0x024810dd, 2274,   -1, INTEL_ARRIAII}, /* EP2AGZ225 */
+       {0x0240a0dd, 2682,   -1, INTEL_ARRIAII}, /* EP2AGZ300 */
+       {0x024820dd, 2682,   -1, INTEL_ARRIAII}, /* EP2AGZ350 */
+};
+
+static int intel_fill_device_parameters(struct intel_pld_device *intel_info)
+{
+       for (size_t i = 0; i < ARRAY_SIZE(intel_device_parameters); ++i) {
+               if (intel_device_parameters[i].id == intel_info->tap->idcode &&
+                       intel_info->family == intel_device_parameters[i].family) {
+                       if (intel_info->boundary_scan_length == 0)
+                               intel_info->boundary_scan_length = intel_device_parameters[i].boundary_scan_length;
+
+                       if (intel_info->checkpos == -1)
+                               intel_info->checkpos = intel_device_parameters[i].checkpos;
+
+                       return ERROR_OK;
+               }
+       }
+
+       return ERROR_FAIL;
+}
+
+static int intel_check_for_unique_id(struct intel_pld_device *intel_info)
+{
+       int found = 0;
+       for (size_t i = 0; i < ARRAY_SIZE(intel_device_parameters); ++i) {
+               if (intel_device_parameters[i].id == intel_info->tap->idcode) {
+                       ++found;
+                       intel_info->family = intel_device_parameters[i].family;
+               }
+       }
+
+       return (found == 1) ? ERROR_OK : ERROR_FAIL;
+}
+
+static int intel_check_config(struct intel_pld_device *intel_info)
+{
+       if (!intel_info->tap->hasidcode) {
+               LOG_ERROR("no IDCODE");
+               return ERROR_FAIL;
+       }
+
+       if (intel_info->family == INTEL_UNKNOWN) {
+               if (intel_check_for_unique_id(intel_info) != ERROR_OK) {
+                       LOG_ERROR("id is ambiguous, please specify family");
+                       return ERROR_FAIL;
+               }
+       }
+
+       if (intel_info->boundary_scan_length == 0 || intel_info->checkpos == -1) {
+               int ret = intel_fill_device_parameters(intel_info);
+               if (ret != ERROR_OK)
+                       return ret;
+       }
+
+       if (intel_info->checkpos >= 0 && (unsigned int)intel_info->checkpos >= intel_info->boundary_scan_length) {
+               LOG_ERROR("checkpos has to be smaller than scan length %d < %u",
+                                       intel_info->checkpos, intel_info->boundary_scan_length);
+               return ERROR_FAIL;
+       }
+
+       return ERROR_OK;
+}
+
+static int intel_read_file(struct raw_bit_file *bit_file, const char *filename)
+{
+       if (!filename || !bit_file)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       /* check if binary .bin or ascii .bit/.hex */
+       const char *file_ending_pos = strrchr(filename, '.');
+       if (!file_ending_pos) {
+               LOG_ERROR("Unable to detect filename suffix");
+               return ERROR_PLD_FILE_LOAD_FAILED;
+       }
+
+       if (strcasecmp(file_ending_pos, ".rbf") == 0)
+               return cpld_read_raw_bit_file(bit_file, filename);
+
+       LOG_ERROR("Unable to detect filetype");
+       return ERROR_PLD_FILE_LOAD_FAILED;
+}
+
+static int intel_set_instr(struct jtag_tap *tap, uint16_t new_instr)
+{
+       struct scan_field field;
+       field.num_bits = tap->ir_length;
+       void *t = calloc(DIV_ROUND_UP(field.num_bits, 8), 1);
+       if (!t) {
+               LOG_ERROR("Out of memory");
+               return ERROR_FAIL;
+       }
+       field.out_value = t;
+       buf_set_u32(t, 0, field.num_bits, new_instr);
+       field.in_value = NULL;
+       jtag_add_ir_scan(tap, &field, TAP_IDLE);
+       free(t);
+       return ERROR_OK;
+}
+
+
+static int intel_load(struct pld_device *pld_device, const char *filename)
+{
+       unsigned int speed = adapter_get_speed_khz();
+       if (speed < 1)
+               speed = 1;
+
+       unsigned int cycles = DIV_ROUND_UP(speed, 200);
+       if (cycles < 1)
+               cycles = 1;
+
+       if (!pld_device || !pld_device->driver_priv)
+               return ERROR_FAIL;
+
+       struct intel_pld_device *intel_info = pld_device->driver_priv;
+       if (!intel_info || !intel_info->tap)
+               return ERROR_FAIL;
+       struct jtag_tap *tap = intel_info->tap;
+
+       int retval = intel_check_config(intel_info);
+       if (retval != ERROR_OK)
+               return retval;
+
+       struct raw_bit_file bit_file;
+       retval = intel_read_file(&bit_file, filename);
+       if (retval != ERROR_OK)
+               return retval;
+
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = intel_set_instr(tap, 0x002);
+       if (retval != ERROR_OK) {
+               free(bit_file.data);
+               return retval;
+       }
+       jtag_add_runtest(speed, TAP_IDLE);
+       retval = jtag_execute_queue();
+       if (retval != ERROR_OK) {
+               free(bit_file.data);
+               return retval;
+       }
+
+       /* shift in the bitstream */
+       struct scan_field field;
+       field.num_bits = bit_file.length * 8;
+       field.out_value = bit_file.data;
+       field.in_value = NULL;
+
+       jtag_add_dr_scan(tap, 1, &field, TAP_DRPAUSE);
+       retval = jtag_execute_queue();
+       free(bit_file.data);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = intel_set_instr(tap, 0x004);
+       if (retval != ERROR_OK)
+               return retval;
+       jtag_add_runtest(cycles, TAP_IDLE);
+       retval = jtag_execute_queue();
+       if (retval != ERROR_OK)
+               return retval;
+
+       if (intel_info->boundary_scan_length != 0) {
+               uint8_t *buf = calloc(DIV_ROUND_UP(intel_info->boundary_scan_length, 8), 1);
+               if (!buf) {
+                       LOG_ERROR("Out of memory");
+                       return ERROR_FAIL;
+               }
+
+               field.num_bits = intel_info->boundary_scan_length;
+               field.out_value = buf;
+               field.in_value = buf;
+               jtag_add_dr_scan(tap, 1, &field, TAP_DRPAUSE);
+               retval = jtag_execute_queue();
+               if (retval != ERROR_OK) {
+                       free(buf);
+                       return retval;
+               }
+
+               if (intel_info->checkpos != -1)
+                       retval = ((buf[intel_info->checkpos / 8] & (1 << (intel_info->checkpos % 8)))) ?
+                                       ERROR_OK : ERROR_FAIL;
+               free(buf);
+               if (retval != ERROR_OK) {
+                       LOG_ERROR("Check failed");
+                       return ERROR_FAIL;
+               }
+       }
+
+       retval = intel_set_instr(tap, 0x003);
+       if (retval != ERROR_OK)
+               return retval;
+       switch (intel_info->family) {
+       case INTEL_CYCLONEIII:
+       case INTEL_CYCLONEIV:
+               jtag_add_runtest(5 * speed + 512, TAP_IDLE);
+               break;
+       case INTEL_CYCLONEV:
+               jtag_add_runtest(5 * speed + 512, TAP_IDLE);
+               break;
+       case INTEL_CYCLONE10:
+               jtag_add_runtest(DIV_ROUND_UP(512ul * speed, 125ul) + 512, TAP_IDLE);
+               break;
+       case INTEL_ARRIAII:
+               jtag_add_runtest(DIV_ROUND_UP(64ul * speed, 125ul) + 512, TAP_IDLE);
+               break;
+       case INTEL_UNKNOWN:
+               LOG_ERROR("unknown family");
+               return ERROR_FAIL;
+       }
+
+       retval = intel_set_instr(tap, BYPASS);
+       if (retval != ERROR_OK)
+               return retval;
+       jtag_add_runtest(speed, TAP_IDLE);
+       return jtag_execute_queue();
+}
+
+COMMAND_HANDLER(intel_set_bscan_command_handler)
+{
+       int dev_id;
+       unsigned int boundary_scan_length;
+
+       if (CMD_ARGC != 2)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], dev_id);
+       struct pld_device *pld_device = get_pld_device_by_num(dev_id);
+       if (!pld_device) {
+               command_print(CMD, "pld device '#%s' is out of bounds", CMD_ARGV[0]);
+               return ERROR_FAIL;
+       }
+
+       COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], boundary_scan_length);
+
+       struct intel_pld_device *intel_info = pld_device->driver_priv;
+
+       if (!intel_info)
+               return ERROR_FAIL;
+
+       intel_info->boundary_scan_length = boundary_scan_length;
+
+       return  ERROR_OK;
+}
+
+COMMAND_HANDLER(intel_set_check_pos_command_handler)
+{
+       int dev_id;
+       int checkpos;
+
+       if (CMD_ARGC != 2)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], dev_id);
+       struct pld_device *pld_device = get_pld_device_by_num(dev_id);
+       if (!pld_device) {
+               command_print(CMD, "pld device '#%s' is out of bounds", CMD_ARGV[0]);
+               return ERROR_FAIL;
+       }
+
+       COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], checkpos);
+
+       struct intel_pld_device *intel_info = pld_device->driver_priv;
+
+       if (!intel_info)
+               return ERROR_FAIL;
+
+       intel_info->checkpos = checkpos;
+
+       return ERROR_OK;
+}
+
+
+PLD_DEVICE_COMMAND_HANDLER(intel_pld_device_command)
+{
+       if (CMD_ARGC < 2 || CMD_ARGC > 3)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       struct jtag_tap *tap = jtag_tap_by_string(CMD_ARGV[1]);
+       if (!tap) {
+               command_print(CMD, "Tap: %s does not exist", CMD_ARGV[1]);
+               return ERROR_FAIL;
+       }
+
+       struct intel_pld_device *intel_info = malloc(sizeof(struct intel_pld_device));
+       if (!intel_info) {
+               LOG_ERROR("Out of memory");
+               return ERROR_FAIL;
+       }
+
+       enum intel_family_e family = INTEL_UNKNOWN;
+
+       if (CMD_ARGC == 3) {
+               if (strcmp(CMD_ARGV[2], "cycloneiii") == 0) {
+                       family = INTEL_CYCLONEIII;
+               } else if (strcmp(CMD_ARGV[2], "cycloneiv") == 0) {
+                       family = INTEL_CYCLONEIV;
+               } else if (strcmp(CMD_ARGV[2], "cyclonev") == 0) {
+                       family = INTEL_CYCLONEV;
+               } else if (strcmp(CMD_ARGV[2], "cyclone10") == 0) {
+                       family = INTEL_CYCLONE10;
+               } else if (strcmp(CMD_ARGV[2], "arriaii") == 0) {
+                       family = INTEL_ARRIAII;
+               } else {
+                       command_print(CMD, "unknown family");
+                       free(intel_info);
+                       return ERROR_FAIL;
+               }
+       }
+       intel_info->tap = tap;
+       intel_info->boundary_scan_length = 0;
+       intel_info->checkpos = -1;
+       intel_info->family = family;
+
+       pld->driver_priv = intel_info;
+
+       return ERROR_OK;
+}
+
+static const struct command_registration intel_exec_command_handlers[] = {
+       {
+               .name = "set_bscan",
+               .mode = COMMAND_EXEC,
+               .handler = intel_set_bscan_command_handler,
+               .help = "set boundary scan register length of FPGA",
+               .usage = "num_pld len",
+       }, {
+               .name = "set_check_pos",
+               .mode = COMMAND_EXEC,
+               .handler = intel_set_check_pos_command_handler,
+               .help = "set check_pos of FPGA",
+               .usage = "num_pld pos",
+       },
+       COMMAND_REGISTRATION_DONE
+};
+
+static const struct command_registration intel_command_handler[] = {
+       {
+               .name = "intel",
+               .mode = COMMAND_ANY,
+               .help = "intel specific commands",
+               .usage = "",
+               .chain = intel_exec_command_handlers,
+       },
+       COMMAND_REGISTRATION_DONE
+};
+
+struct pld_driver intel_pld = {
+       .name = "intel",
+       .commands = intel_command_handler,
+       .pld_device_command = &intel_pld_device_command,
+       .load = &intel_load,
+};
index a92486ab1cb8aabe62707fa2def3df8e36bcb589..f4f79bacb0792ac816a9a2b0dceb9e4cf145822e 100644 (file)
 /* pld drivers
  */
 extern struct pld_driver efinix_pld;
+extern struct pld_driver intel_pld;
 extern struct pld_driver lattice_pld;
 extern struct pld_driver virtex2_pld;
 
 static struct pld_driver *pld_drivers[] = {
        &efinix_pld,
+       &intel_pld,
        &lattice_pld,
        &virtex2_pld,
        NULL,
diff --git a/tcl/board/bemicro_cycloneiii.cfg b/tcl/board/bemicro_cycloneiii.cfg
new file mode 100644 (file)
index 0000000..7781bd5
--- /dev/null
@@ -0,0 +1,20 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+# BeMicro Cyclone III
+
+
+adapter driver ftdi
+ftdi channel 0
+ftdi layout_init 0x0008 0x008b
+ftdi vid_pid 0x0403 0xa4a0
+reset_config none
+transport select jtag
+
+adapter speed 10000
+
+source [find cpld/altera-cycloneiii.cfg]
+
+#quartus_cpf --option=bitstream_compression=off -c output_files\cycloneiii_blinker.sof cycloneiii_blinker.rbf
+
+#openocd -f board/bemicro_cycloneiii.cfg -c "init" -c "pld load 0 cycloneiii_blinker.rbf"
+# "ipdbg -start -tap cycloneiii.tap -hub 0x00e -tool 0 -port 5555"
index 5dbd0deee846869a7ecc3a1695fa97d7096fb239..4504a8064810336011a35e69104e9d84303dbe96 100644 (file)
@@ -1,8 +1,9 @@
 # SPDX-License-Identifier: GPL-2.0-or-later
 
-# Altera MAXV 5M24OZ/5M570Z CPLD
-# see MAX V Device Handbook
-# Table 6-3: 32-Bit MAX V Device IDCODE
-# Version     Part Number             Manuf. ID        LSB
-# 0000        0010 0000 1010 0111     000 0110 1110    1
-jtag newtap 5m570z tap -expected-id 0x020a60dd -irlen 10
+# file altera-5m570z-cpld.cfg replaced by altera-maxv.cfg
+echo "DEPRECATED: use altera-maxv.cfg instead of deprecated altera-5m570z-cpld.cfg"
+
+#just to be backward compatible:
+#tap will be 5m570z.tap instead of maxv.tap:
+set CHIPNAME 5m570z
+source [find cpld/altera-maxv.cfg]
index 39c409bc3a573be479ffebef79330d35b907437e..185925a16fa13b31ad9490433d2b4ea150aac1f2 100644 (file)
@@ -1,24 +1,12 @@
 # SPDX-License-Identifier: GPL-2.0-or-later
 
-# Altera MAXII EPM240T100C CPLD
+# file altera-epm240.cfg replaced by altera-maxii.cfg
+echo "DEPRECATED: use altera-maxii.cfg instead of deprecated altera-epm240.cfg"
 
-if { [info exists CHIPNAME] } {
-       set _CHIPNAME $CHIPNAME
-} else {
-       set _CHIPNAME epm240
-}
-
-# see MAX II Device Handbook
-# Table 3-3: 32-Bit MAX II Device IDCODE
-# Version     Part Number             Manuf. ID        LSB
-# 0000        0010 0000 1010 0001     000 0110 1110    1
-jtag newtap $_CHIPNAME tap -irlen 10 \
-       -expected-id 0x020a10dd \
-       -expected-id 0x020a20dd \
-       -expected-id 0x020a30dd \
-       -expected-id 0x020a40dd \
-       -expected-id 0x020a50dd \
-       -expected-id 0x020a60dd
+#just to be backward compatible:
+#tap will be epm240.tap instead of maxii.tap:
+set CHIPNAME epm240
+source [find cpld/altera-maxii.cfg]
 
 # 200ns seems like a good speed
 # c.f. Table 5-34: MAX II JTAG Timing Parameters
diff --git a/tcl/cpld/altera-max10.cfg b/tcl/cpld/altera-max10.cfg
new file mode 100644 (file)
index 0000000..a2ed00a
--- /dev/null
@@ -0,0 +1,30 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+# see MAX 10 FPGA Device Architecture
+# Table 3-1: IDCODE Information for MAX 10 Devices
+# Intel MAX 10M02 0x31810dd
+# Intel MAX 10M04 0x318a0dd
+# Intel MAX 10M08 0x31820dd
+# Intel MAX 10M16 0x31830dd
+# Intel MAX 10M25 0x31840dd
+# Intel MAX 10M40 0x318d0dd
+# Intel MAX 10M50 0x31850dd
+# Intel MAX 10M02 0x31010dd
+# Intel MAX 10M04 0x310a0dd
+# Intel MAX 10M08 0x31020dd
+# Intel MAX 10M16 0x31030dd
+# Intel MAX 10M25 0x31040dd
+# Intel MAX 10M40 0x310d0dd
+# Intel MAX 10M50 0x31050dd
+
+if { [info exists CHIPNAME] } {
+       set _CHIPNAME $CHIPNAME
+} else {
+       set _CHIPNAME max10
+}
+
+jtag newtap $_CHIPNAME tap -irlen 10 -expected-id 0x31810dd -expected-id 0x318a0dd \
+       -expected-id 0x31820dd -expected-id 0x31830dd -expected-id 0x31840dd \
+       -expected-id 0x318d0dd -expected-id 0x31850dd -expected-id 0x31010dd \
+       -expected-id 0x310a0dd -expected-id 0x31020dd -expected-id 0x31030dd \
+       -expected-id 0x31040dd -expected-id 0x310d0dd -expected-id 0x31050dd
diff --git a/tcl/cpld/altera-maxii.cfg b/tcl/cpld/altera-maxii.cfg
new file mode 100644 (file)
index 0000000..2dee37f
--- /dev/null
@@ -0,0 +1,21 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+# Altera MAXII CPLD
+
+if { [info exists CHIPNAME] } {
+       set _CHIPNAME $CHIPNAME
+} else {
+       set _CHIPNAME maxii
+}
+
+# see MAX II Device Handbook
+# Table 3-3: 32-Bit MAX II Device IDCODE
+# Version     Part Number             Manuf. ID        LSB
+# 0000        0010 0000 1010 0001     000 0110 1110    1
+jtag newtap $_CHIPNAME tap -irlen 10 \
+       -expected-id 0x020a10dd \
+       -expected-id 0x020a20dd \
+       -expected-id 0x020a30dd \
+       -expected-id 0x020a40dd \
+       -expected-id 0x020a50dd \
+       -expected-id 0x020a60dd
diff --git a/tcl/cpld/altera-maxv.cfg b/tcl/cpld/altera-maxv.cfg
new file mode 100644 (file)
index 0000000..03fad07
--- /dev/null
@@ -0,0 +1,19 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+# Altera MAXV 5M24OZ/5M570Z CPLD
+# see MAX V Device Handbook
+# Table 6-3: 32-Bit MAX V Device IDCODE
+# 5M40Z 5M80Z 5M160Z 5M240Z: 0x020A50DD
+# 5M570Z:                    0x020A60DD
+# 5M1270Z:                   0x020A30DD
+# 5M1270Z 5M2210Z:           0x020A40DD
+
+if { [info exists CHIPNAME] } {
+       set _CHIPNAME $CHIPNAME
+} else {
+       set _CHIPNAME maxv
+}
+
+jtag newtap $_CHIPNAME tap -irlen 10 \
+  -expected-id 0x020A50DD -expected-id 0x020A60DD \
+  -expected-id 0x020A30DD -expected-id 0x020A40DD
index 1937cb4b638f2a896a252957c1b1113c00832875..94228d26fd6116a07190976898fbdde26851c5bc 100644 (file)
@@ -1,24 +1,9 @@
 # SPDX-License-Identifier: GPL-2.0-or-later
 
-# see MAX 10 FPGA Device Architecture
-# Table 3-1: IDCODE Information for MAX 10 Devices
-# Intel MAX 10M02 0x31810dd
-# Intel MAX 10M04 0x318a0dd
-# Intel MAX 10M08 0x31820dd
-# Intel MAX 10M16 0x31830dd
-# Intel MAX 10M25 0x31840dd
-# Intel MAX 10M40 0x318d0dd
-# Intel MAX 10M50 0x31850dd
-# Intel MAX 10M02 0x31010dd
-# Intel MAX 10M04 0x310a0dd
-# Intel MAX 10M08 0x31020dd
-# Intel MAX 10M16 0x31030dd
-# Intel MAX 10M25 0x31040dd
-# Intel MAX 10M40 0x310d0dd
-# Intel MAX 10M50 0x31050dd
+# file altera-10m50.cfg replaced by altera-max10.cfg
+echo "DEPRECATED: use altera-max10.cfg instead of deprecated altera-10m50.cfg"
 
-jtag newtap 10m50 tap -irlen 10 -expected-id 0x31810dd -expected-id 0x318a0dd \
-       -expected-id 0x31820dd -expected-id 0x31830dd -expected-id 0x31840dd \
-       -expected-id 0x318d0dd -expected-id 0x31850dd -expected-id 0x31010dd \
-       -expected-id 0x310a0dd -expected-id 0x31020dd -expected-id 0x31030dd \
-       -expected-id 0x31040dd -expected-id 0x310d0dd -expected-id 0x31050dd
+#just to be backward compatible:
+#tap will be 10m50.tap instead of max10.tap:
+set CHIPNAME 10m50
+source [find cpld/altera-max10.cfg]
diff --git a/tcl/fpga/altera-arriaii.cfg b/tcl/fpga/altera-arriaii.cfg
new file mode 100644 (file)
index 0000000..ae752df
--- /dev/null
@@ -0,0 +1,31 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+# Intel Arria II FPGA
+# Arria II Device Handbook
+# Table 11–2. 32-Bit IDCODE for Arria II Devices
+
+#GX:
+#EP2AGX45:  0x025120dd
+#EP2AGX65:  0x025020dd
+#EP2AGX95:  0x025130dd
+#EP2AGX125: 0x025030dd
+#EP2AGX190: 0x025140dd
+#EP2AGX260: 0x025040dd
+#EP2AGZ225: 0x024810dd
+#EP2AGZ300: 0x0240a0dd
+#EP2AGZ350: 0x024820dd
+
+if { [info exists CHIPNAME] } {
+       set _CHIPNAME $CHIPNAME
+} else {
+       set _CHIPNAME arriaii
+}
+
+jtag newtap $_CHIPNAME tap -irlen 10 \
+  -expected-id 0x025120dd -expected-id 0x025040dd \
+  -expected-id 0x025020dd -expected-id 0x024810dd \
+  -expected-id 0x025130dd -expected-id 0x0240a0dd \
+  -expected-id 0x025030dd -expected-id 0x024820dd \
+  -expected-id 0x025140dd
+
+pld device intel $_CHIPNAME.tap arriaii
diff --git a/tcl/fpga/altera-cyclone10.cfg b/tcl/fpga/altera-cyclone10.cfg
new file mode 100644 (file)
index 0000000..3a1bc1f
--- /dev/null
@@ -0,0 +1,34 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+# Intel Cyclone 10 FPGA
+# see: https://www.intel.com/content/www/us/en/docs/programmable/683777/current/bst-operation-control.html
+# and: https://www.intel.cn/content/dam/support/us/en/programmable/kdb/pdfs/literature/hb/cyclone-10/c10gx-51003.pdf
+
+# GX085: 0x02e120dd
+# GX105: 0x02e320dd
+# GX150: 0x02e720dd
+# GX220: 0x02ef20dd
+# 10cl006: 0x020f10dd
+# 10cl010: 0x020f10dd
+# 10cl016: 0x020f20dd
+# 10cl025: 0x020f30dd
+# 10cl040: 0x020f40dd
+# 10cl055: 0x020f50dd
+# 10cl080: 0x020f60dd
+# 10cl120: 0x020f70dd
+
+if { [info exists CHIPNAME] } {
+       set _CHIPNAME $CHIPNAME
+} else {
+       set _CHIPNAME cyclone10
+}
+
+jtag newtap $_CHIPNAME tap -irlen 10 \
+  -expected-id 0x02e720dd -expected-id 0x02e120dd \
+  -expected-id 0x02ef20dd -expected-id 0x02e320dd \
+  -expected-id 0x020f10dd -expected-id 0x020f20dd \
+  -expected-id 0x020f30dd -expected-id 0x020f40dd \
+  -expected-id 0x020f50dd -expected-id 0x020f60dd \
+  -expected-id 0x020f70dd
+
+pld device intel $_CHIPNAME.tap cyclone10
diff --git a/tcl/fpga/altera-cycloneiii.cfg b/tcl/fpga/altera-cycloneiii.cfg
new file mode 100644 (file)
index 0000000..e143572
--- /dev/null
@@ -0,0 +1,35 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+# Intel Cyclone III FPGA
+# see Cyclone III Device Handbook
+# Table 12-2: Device IDCODE for Cyclone III Device Family
+
+#EP3C5     0x020f10dd
+#EP3C10    0x020f10dd
+#EP3C16    0x020f20dd
+#EP3C25    0x020f30dd
+#EP3C40    0x020f40dd
+#EP3C55    0x020f50dd
+#EP3C80    0x020f60dd
+#EP3C120   0x020f70dd
+#Cyclone III LS
+#EP3CLS70  0x027010dd
+#EP3CLS100 0x027000dd
+#EP3CLS150 0x027030dd
+#EP3CLS200 0x027020dd
+
+if { [info exists CHIPNAME] } {
+       set _CHIPNAME $CHIPNAME
+} else {
+       set _CHIPNAME cycloneiii
+}
+
+jtag newtap $_CHIPNAME tap -irlen 10 \
+  -expected-id 0x020f10dd -expected-id 0x020f20dd \
+  -expected-id 0x020f30dd -expected-id 0x020f40dd \
+  -expected-id 0x020f50dd -expected-id 0x020f60dd \
+  -expected-id 0x020f70dd -expected-id 0x027010dd \
+  -expected-id 0x027000dd -expected-id 0x027030dd \
+  -expected-id 0x027020dd
+
+pld device intel $_CHIPNAME.tap cycloneiii
diff --git a/tcl/fpga/altera-cycloneiv.cfg b/tcl/fpga/altera-cycloneiv.cfg
new file mode 100644 (file)
index 0000000..59243cf
--- /dev/null
@@ -0,0 +1,41 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+# Intel Cyclone IV FPGA
+# see Cyclone IV Device Handbook
+# Table 10-2: IDCODE Information for 32-Bit Cyclone IV Devices
+
+#EP4CE6       0x020f10dd
+#EP4CE10      0x020f10dd
+#EP4CE15      0x020f20dd
+#EP4CE22      0x020f30dd
+#EP4CE30      0x020f40dd
+#EP4CE40      0x020f40dd
+#EP4CE55      0x020f50dd
+#EP4CE75      0x020f60dd
+#EP4CE115     0x020f70dd
+#EP4CGX15     0x028010dd
+#EP4CGX22     0x028120dd
+#EP4CGX30 (3) 0x028020dd
+#EP4CGX30 (4) 0x028230dd
+#EP4CGX50     0x028130dd
+#EP4CGX75     0x028030dd
+#EP4CGX110    0x028140dd
+#EP4CGX150    0x028040dd
+
+if { [info exists CHIPNAME] } {
+       set _CHIPNAME $CHIPNAME
+} else {
+       set _CHIPNAME cycloneiv
+}
+
+jtag newtap $_CHIPNAME tap -irlen 10 \
+  -expected-id 0x020f10dd -expected-id 0x020f20dd \
+  -expected-id 0x020f30dd -expected-id 0x020f40dd \
+  -expected-id 0x020f50dd -expected-id 0x020f60dd \
+  -expected-id 0x020f70dd -expected-id 0x028010dd \
+  -expected-id 0x028120dd -expected-id 0x028020dd \
+  -expected-id 0x028230dd -expected-id 0x028130dd \
+  -expected-id 0x028030dd -expected-id 0x028140dd \
+  -expected-id 0x028040dd
+
+pld device intel $_CHIPNAME.tap cycloneiv
diff --git a/tcl/fpga/altera-cyclonev.cfg b/tcl/fpga/altera-cyclonev.cfg
new file mode 100644 (file)
index 0000000..1e9c9c4
--- /dev/null
@@ -0,0 +1,47 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+# Intel Cyclone 5 FPGA
+# see Cyclone V Device Handbook
+# Table 9-1: IDCODE Information for Cyclone V Devices
+
+#5CEA2 0x02b150dd
+#5CEA4 0x02b050dd
+#5CEA5 0x02b220dd
+#5CEA7 0x02b130dd
+#5CEA9 0x02b140dd
+#5CGXC3 0x02b010dd
+#5CGXC4 0x02b120dd
+#5CGXC5 0x02b020dd
+#5CGXC7 0x02b030dd
+#5CGXC9 0x02b040dd
+#5CGTD5 0x02b020dd
+#5CGTD7 0x02b030dd
+#5CGTD9 0x02b040dd
+#5CSEA2 0x02d110dd
+#5CSEA4 0x02d010dd
+#5CSEA5 0x02d120dd
+#5CSEA6 0x02d020dd
+#5CSXC2 0x02d110dd
+#5CSXC4 0x02d010dd
+#5CSXC5 0x02d120dd
+#5CSXC6 0x02d020dd
+#5CSTD5 0x02d120dd
+#5CSTD6 0x02d020dd
+
+
+if { [info exists CHIPNAME] } {
+       set _CHIPNAME $CHIPNAME
+} else {
+       set _CHIPNAME cyclonev
+}
+
+jtag newtap $_CHIPNAME tap -irlen 10 \
+  -expected-id 0x02b150dd -expected-id 0x02b050dd \
+  -expected-id 0x02b220dd -expected-id 0x02b130dd \
+  -expected-id 0x02b140dd -expected-id 0x02b010dd \
+  -expected-id 0x02b120dd -expected-id 0x02b020dd \
+  -expected-id 0x02b030dd -expected-id 0x02b040dd \
+  -expected-id 0x02d110dd -expected-id 0x02d010dd \
+  -expected-id 0x02d120dd -expected-id 0x02d020dd
+
+pld device intel $_CHIPNAME.tap cyclonev
index 7c231f9424a3207485d8fd87e2d09da67bd0f803..d7a92d7484e30e8b98c591cdad3133eb2bf1bc2d 100644 (file)
@@ -1,6 +1,9 @@
 # SPDX-License-Identifier: GPL-2.0-or-later
 
-# Altera Cyclone III EP3C10
-# see Cyclone III Device Handbook, Volume 1;
-# Table 14–5. 32-Bit Cyclone III Device IDCODE
-jtag newtap ep3c10 tap -expected-id 0x020f10dd -irlen 10
+# file altera-ep3c10.cfg replaced by altera-cycloneiii.cfg
+echo "DEPRECATED: use altera-cycloneiii.cfg instead of deprecated altera-ep3c10.cfg"
+
+#just to be backward compatible:
+#tap will be ep3c10.tap instead of cycloneiii.tap:
+set CHIPNAME ep3c10
+source [find fpga/altera-cycloneiii.cfg]

Linking to existing account procedure

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

SSH host keys fingerprints

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