#ifndef _FPGA_H #define _FPGA_H /* * Per-target FPGA descriptor and registry. * * Holds the facts that cannot be derived from the BSDL alone: * - IDCODE pattern to match on the chain * - private IR opcodes (USER1, CFG_IN, JPROGRAM, …) needed for * configuration and for the BSCAN proxy bridge (Phase 2.5) * - path to the BSCAN proxy bitstream * - per-target caveats (known hardware gotchas) * * The registry is loaded at runtime from a YAML file (no longer a * compile-time array). Adding an FPGA = one entry in the YAML + * its .bsd in bsdl_files/ + (optionally) its proxy .bit in * bscan_proxies/. See fpga_registry.yaml for the format. */ #include "jtag_core/jtag_core.h" typedef enum { FPGA_FAMILY_UNKNOWN = 0, FPGA_FAMILY_XILINX_7, FPGA_FAMILY_XILINX_US, FPGA_FAMILY_XILINX_USP, FPGA_FAMILY_MICROSEMI_IGLOO2, FPGA_FAMILY_MICROSEMI_SMARTFUSION2, FPGA_FAMILY_LATTICE_MACHXO2, FPGA_FAMILY_LATTICE_MACHXO3, } fpga_family; /* Caveat flags: known hardware gotchas for a part. */ #define FPGA_CAVEAT_CCLK_VIA_STARTUP (1u << 0) /* CCLK not directly drivable in EXTEST */ typedef struct { const char *name; /* human-readable part name */ unsigned long idcode; /* IDCODE pattern */ unsigned long idcode_mask; /* bits to ignore (typically 0x0FFFFFFF for Xilinx — version masked) */ fpga_family family; const char *bsdl_filename; /* basename within bsdl_files/ */ int ir_length; /* IR width in bits */ /* Private IR opcodes (0 = N/A for this family). * For Xilinx, these are read from the BSDL INSTRUCTION_OPCODE block. */ unsigned int ir_cfg_in; unsigned int ir_user1; unsigned int ir_jprogram; unsigned int ir_jstart; unsigned int ir_jshutdown; unsigned int ir_isc_disable; const char *proxy_bitstream; /* path under bscan_proxies/, NULL if not yet available */ unsigned int caveats; /* FPGA_CAVEAT_* flags */ int max_tck_khz; /* max safe JTAG TCK for this part/board, 0 = unspecified */ } fpga_target; /* Registry access. The YAML file is loaded lazily on first call to any * of these, and cached for the process lifetime. */ int fpga_get_target_count(void); const fpga_target * fpga_get_target_by_index(int index); const fpga_target * fpga_lookup_by_idcode(unsigned long idcode); const char * fpga_family_name(fpga_family f); /* Path the registry was loaded from, or NULL if nothing loaded * (file missing / parse error). For diagnostics. */ const char * fpga_registry_source(void); #endif