xref: /illumos-gate/usr/src/uts/sun4u/sunfire/io/jtag.c (revision c6a28d76)
129949e86Sstevel /*
229949e86Sstevel  * CDDL HEADER START
329949e86Sstevel  *
429949e86Sstevel  * The contents of this file are subject to the terms of the
529949e86Sstevel  * Common Development and Distribution License (the "License").
629949e86Sstevel  * You may not use this file except in compliance with the License.
729949e86Sstevel  *
829949e86Sstevel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
929949e86Sstevel  * or http://www.opensolaris.org/os/licensing.
1029949e86Sstevel  * See the License for the specific language governing permissions
1129949e86Sstevel  * and limitations under the License.
1229949e86Sstevel  *
1329949e86Sstevel  * When distributing Covered Code, include this CDDL HEADER in each
1429949e86Sstevel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1529949e86Sstevel  * If applicable, add the following below this CDDL HEADER, with the
1629949e86Sstevel  * fields enclosed by brackets "[]" replaced with your own identifying
1729949e86Sstevel  * information: Portions Copyright [yyyy] [name of copyright owner]
1829949e86Sstevel  *
1929949e86Sstevel  * CDDL HEADER END
2029949e86Sstevel  */
2129949e86Sstevel 
2229949e86Sstevel /*
2329949e86Sstevel  * Copyright 1999 Sun Microsystems, Inc.  All rights reserved.
2429949e86Sstevel  * Use is subject to license terms.
2529949e86Sstevel  */
2629949e86Sstevel 
2729949e86Sstevel #include <sys/types.h>
2829949e86Sstevel #include <sys/param.h>
2929949e86Sstevel #include <sys/ddi.h>
3029949e86Sstevel #include <sys/sunddi.h>
3129949e86Sstevel #include <sys/ddi_impldefs.h>
3229949e86Sstevel #include <sys/obpdefs.h>
3329949e86Sstevel #include <sys/cmn_err.h>
3429949e86Sstevel #include <sys/errno.h>
3529949e86Sstevel #include <sys/debug.h>
3629949e86Sstevel #include <sys/fhc.h>
3729949e86Sstevel #include <sys/jtag.h>
3829949e86Sstevel #include <sys/ac.h>
3929949e86Sstevel #include <sys/machsystm.h>
4029949e86Sstevel #include <sys/cpu.h>
4129949e86Sstevel #include <sys/cpuvar.h>
4229949e86Sstevel 
4329949e86Sstevel /*
4429949e86Sstevel  * Defines for data structures used only in this module. They will
4529949e86Sstevel  * not be exported to external modules.
4629949e86Sstevel  */
4729949e86Sstevel 
4829949e86Sstevel /*
4929949e86Sstevel  * Define the hardware structure of JTAG
5029949e86Sstevel  */
5129949e86Sstevel 
5229949e86Sstevel #define	JTAG_CSR_BASE ((jtag_csr *)0xF0300000)
5329949e86Sstevel 
5429949e86Sstevel 
5529949e86Sstevel #define	JTAG_CR 0x08000f0
5629949e86Sstevel #define	JTAG_CMD 0x0800100
5729949e86Sstevel 
5829949e86Sstevel /* JTAG status flags */
5929949e86Sstevel #define	JTAG_BUSY_BIT 0x100
6029949e86Sstevel 
6129949e86Sstevel /* JTAG commands */
6229949e86Sstevel #define	JTAG_SEL_RING	0x6000
6329949e86Sstevel #define	JTAG_SEL_DR	0x5050
6429949e86Sstevel #define	JTAG_SEL_IR	0x5068
6529949e86Sstevel #define	JTAG_SHIFT	0x00A0
6629949e86Sstevel #define	JTAG_RUNIDLE	0x50C0
6729949e86Sstevel #define	JTAG_IR_TO_DR	0x50E8
6829949e86Sstevel #define	JTAG_DR_TO_IR	0x50F4
6929949e86Sstevel #define	JTAG_TAP_RESET	0x50FF
7029949e86Sstevel 
7129949e86Sstevel 
7229949e86Sstevel /*
7329949e86Sstevel  * Definitions of data types.
7429949e86Sstevel  *
7529949e86Sstevel  */
7629949e86Sstevel 
7729949e86Sstevel /*
7829949e86Sstevel  * Most routines in this interface return a negative value when
7929949e86Sstevel  * an error occurs. In the normal case, the routines return a non-negative
8029949e86Sstevel  * value, which may be of interest to the caller. The following enumeration
8129949e86Sstevel  * provides the meaning of each error return code.
8229949e86Sstevel  */
8329949e86Sstevel 
8429949e86Sstevel /*
8529949e86Sstevel  * When calling verify_jtag_chip, you must pass PRINT_ERR if you
8629949e86Sstevel  * want the cmn_err call to occur. This is because sometimes
8729949e86Sstevel  * when we verify rings, (checking for NPB's) we do not want to
8829949e86Sstevel  * print error messages.
8929949e86Sstevel  */
9029949e86Sstevel #define	PRINT_JTAG_ERR	5
9129949e86Sstevel 
9229949e86Sstevel /*
9329949e86Sstevel  * You must pass in the proper chip masks when calling
9429949e86Sstevel  * config board()
9529949e86Sstevel  */
9629949e86Sstevel #define	AC_INIT		1
9729949e86Sstevel #define	DCU1500_INIT	2
9829949e86Sstevel #define	DCU1600_INIT	2
9929949e86Sstevel #define	DCU1700_INIT	2
10029949e86Sstevel #define	DCU1800_INIT	2
10129949e86Sstevel #define	DCU1900_INIT	2
10229949e86Sstevel #define	DCU2000_INIT	2
10329949e86Sstevel #define	DCU2100_INIT	2
10429949e86Sstevel #define	DCU2200_INIT	2
10529949e86Sstevel #define	FHC_INIT	4
10629949e86Sstevel 
10729949e86Sstevel #define	SYSIO_INIT	8
10829949e86Sstevel 
10929949e86Sstevel /* scan ring numbers */
11029949e86Sstevel #define	RING0		0
11129949e86Sstevel #define	RING1		1
11229949e86Sstevel #define	RING2		2
11329949e86Sstevel 
11429949e86Sstevel /*
11529949e86Sstevel  * Scan ring 0 lengths. Boards are typed by their scan ring length. This
11629949e86Sstevel  * is inherently flawed if a new board type has the same number of
11729949e86Sstevel  * components as one of the original boards.
11829949e86Sstevel  *
11929949e86Sstevel  * The inherently flawed scenario now exists with the introduction
12029949e86Sstevel  * of the soc+ versions of the 2-SBus and UPA/SBus boards. Argh...
12129949e86Sstevel  */
12229949e86Sstevel #define	CPU_TYPE_LEN	12		/* CPU board ring length */
12329949e86Sstevel #define	IO_TYPE1_LEN	15		/* 2 sysio 1 HM */
12429949e86Sstevel #define	IO_TYPE2_LEN	14		/* 1 sysio 1 ffb */
12529949e86Sstevel #define	PCI_TYPE_LEN	16		/* PCI board ring length */
12629949e86Sstevel #define	PCI_TYPEA_LEN	110		/* PCI ISP off ring */
12729949e86Sstevel #define	PCI_TYPEB_LEN	104		/* PCI ISP in ring */
12829949e86Sstevel #define	DSK_TYPE_LEN	2		/* Disk board ring length */
12929949e86Sstevel #define	IO_TYPE4_LEN	126		/* 2 sysio soc+ */
13029949e86Sstevel #define	IO_TYPE5_LEN	110		/* 1 sysio 1 ffb soc+ */
13129949e86Sstevel 
13229949e86Sstevel #define	CPU_0_5_LEN	8		/* 0.5 Meg Module ring length */
13329949e86Sstevel #define	CPU_1_0_LEN	12		/* 1 Meg and 2 Meg ring length */
13429949e86Sstevel #define	FFB_SNG_LEN	6		/* Single bufferef FFB */
13529949e86Sstevel #define	FFB_DBL_LEN	18		/* Double buffered FFB */
13629949e86Sstevel 
13729949e86Sstevel /*
13829949e86Sstevel  * Component IDs of various SRAM chips. The only way to distinguish between
13929949e86Sstevel  * 1M, 2M, and 4M Ecache is via the component IDs of the SRAMs.
14029949e86Sstevel  */
14129949e86Sstevel #define	SRAM_256K	0x00000000
14229949e86Sstevel #define	SRAM_128K	0x000090E3
14329949e86Sstevel #define	SRAM_64K_1	0x000000E3
14429949e86Sstevel #define	SRAM_64K_2	0x01901149
14529949e86Sstevel 
14629949e86Sstevel typedef enum {
14729949e86Sstevel 	JTAG_OK = 0,		/* no error */
14829949e86Sstevel 	JTAG_FAIL = -1,		/* generic JTAG failure */
14929949e86Sstevel 	TAP_TIMEOUT = -1,	/* JTAG TAP state machine not responding */
15029949e86Sstevel 	BAD_ARGS = -2,		/* incorrect arguments passed by caller */
15129949e86Sstevel 	BAD_CID = -3,		/* JTAG component ID does not match */
15229949e86Sstevel 	RING_BROKEN = -4,	/* JTAG ring continuity test failed */
15329949e86Sstevel 	INIT_MISMATCH = -5,	/* State after initialization not expected */
15429949e86Sstevel 	LENGTH_MISMATCH = -6	/* Ring length does not match expected */
15529949e86Sstevel } jtag_error;
15629949e86Sstevel 
15729949e86Sstevel typedef u_short jtag_instruction;
15829949e86Sstevel typedef u_char jtag_ring;	/* format is bbbb rrrr in binary */
15929949e86Sstevel 
16029949e86Sstevel /* Internal macros */
16129949e86Sstevel static int tap_issue_cmd(volatile u_int *, u_int);
16229949e86Sstevel 
16329949e86Sstevel /* TAP register access macros */
16429949e86Sstevel 
16529949e86Sstevel /* NOTE the only status is the busy bit (8) */
16629949e86Sstevel 
16729949e86Sstevel /* read the jtag data bits */
16829949e86Sstevel #define	jtag_data(reg, nbits) (*(reg) >> (32 - (nbits)))
16929949e86Sstevel 
17029949e86Sstevel #define	JTAG_TIMEOUT 0x10000
17129949e86Sstevel 
17229949e86Sstevel #define	TAP_DECLARE int timeout;
17329949e86Sstevel 
17429949e86Sstevel #define	TAP_WAIT(reg)  timeout = JTAG_TIMEOUT;		\
17529949e86Sstevel 	while ((*(reg) & JTAG_BUSY_BIT) != 0)		\
17629949e86Sstevel 		if ((--timeout) < 0)			\
17729949e86Sstevel 			return (TAP_TIMEOUT)
17829949e86Sstevel 
17929949e86Sstevel #define	TAP_SHIFT(reg, data, nbits)				\
18029949e86Sstevel 	*(reg) = ((data<<16) | ((nbits-1)<<12) | JTAG_SHIFT);	\
18129949e86Sstevel 	TAP_WAIT(reg)
18229949e86Sstevel 
18329949e86Sstevel /* Error-checking macros to simplify the coding */
18429949e86Sstevel 
18529949e86Sstevel #define	TAP_ISSUE_CMD(reg, cmd, status)		\
18629949e86Sstevel 	status = tap_issue_cmd(reg, cmd);	\
18729949e86Sstevel 	if (status < 0)				\
18829949e86Sstevel 		return (status)
18929949e86Sstevel 
19029949e86Sstevel #define	TAP_SHIFT_CONSTANT(reg, val, nbits, status)	\
19129949e86Sstevel 	status = tap_shift_constant(reg, val, nbits);	\
19229949e86Sstevel 	if (status < 0)					\
19329949e86Sstevel 		return (status)
19429949e86Sstevel 
19529949e86Sstevel #define	TAP_SHIFT_SINGLE(reg, val, nbits, status)	\
19629949e86Sstevel 	status = tap_shift_single(reg, val, nbits);	\
19729949e86Sstevel 	if (status < 0)					\
19829949e86Sstevel 		return (status)
19929949e86Sstevel 
20029949e86Sstevel #define	TAP_SHIFT_MULTIPLE(reg, in, nbits, out, status)		\
20129949e86Sstevel 	status = tap_shift_multiple(reg, in, nbits, out);	\
20229949e86Sstevel 	if (status < 0)						\
20329949e86Sstevel 		return (status)
20429949e86Sstevel 
20529949e86Sstevel /*
20629949e86Sstevel  * A jtag_log_comp describes a component as seen by JTAG.
20729949e86Sstevel  *
20829949e86Sstevel  * Since there are multiple versions & revision for a single
20929949e86Sstevel  * component, this can be a bit complicated...
21029949e86Sstevel  *
21129949e86Sstevel  * The implementation assumes that all components which can be used
21229949e86Sstevel  * interchangeably have the exact same programming model regarding
21329949e86Sstevel  * JTAG programming. Then, interchangeable components differ only by
21429949e86Sstevel  * their component IDs. The field id points to a NULL-terminated list
21529949e86Sstevel  * of component IDs. Allowable component IDs may differ only in the rev
21629949e86Sstevel  * number, which must be higher than or equal to the one in the list.
21729949e86Sstevel  *
21829949e86Sstevel  * The init_pdesc field points to a byte string which describes how to
21929949e86Sstevel  * initialize the component. The structure of this byte string is not
22029949e86Sstevel  * exported (see the implementation of jtag_init_chip).
22129949e86Sstevel  *
22229949e86Sstevel  * The fmt_desc field points to a byte string which describes how to
22329949e86Sstevel  * convert the scan-out format to the more usual DCSR format. The
22429949e86Sstevel  * structure of this string is not exported (see the implementation
22529949e86Sstevel  * of jtag_scanout_chip).
22629949e86Sstevel  */
22729949e86Sstevel 
22829949e86Sstevel typedef struct {
22929949e86Sstevel 	u_int *id;		/* Pointer to component IDs, 0 if no CID */
23029949e86Sstevel 	u_char ir_len;		/* number of bits in instruction register */
23129949e86Sstevel 	u_char dr_len;		/* number of bits in DR for init/dump */
23229949e86Sstevel 	jtag_instruction id_code;	/* instruction to read component ID */
23329949e86Sstevel 	jtag_instruction init_code;	/* instruction to write parameters */
23429949e86Sstevel 	jtag_instruction dump_code;	/* instruction to read parameters */
23529949e86Sstevel 	u_char *init_pdesc;		/* initialization patch descriptors */
23629949e86Sstevel 	u_char *fmt_desc;		/* reformat descriptor */
23729949e86Sstevel } jtag_log_comp;
23829949e86Sstevel 
23929949e86Sstevel 
24029949e86Sstevel /* A jtag_phys_comp describes a component position inside a ring */
24129949e86Sstevel 
24229949e86Sstevel typedef struct {
24329949e86Sstevel 	jtag_log_comp *chip;	/* pointer to chip descriptor */
24429949e86Sstevel 	short ir_after;		/* number of IR bits after chip in ring */
24529949e86Sstevel 	short ir_before;	/* number of IR bits before chip in ring */
24629949e86Sstevel 	short by_after;		/* number of bypass bits after chip in ring */
24729949e86Sstevel 	short by_before;	/* number of bypass bits before chip in ring */
24829949e86Sstevel } jtag_phys_comp;
24929949e86Sstevel 
25029949e86Sstevel 
25129949e86Sstevel /* Board ring description */
25229949e86Sstevel 
25329949e86Sstevel typedef struct {
25429949e86Sstevel 	int size;
25529949e86Sstevel 	jtag_phys_comp *components;
25629949e86Sstevel } jtag_ring_desc;
25729949e86Sstevel 
25829949e86Sstevel /*
25929949e86Sstevel  *	Initialization options
26029949e86Sstevel  *
26129949e86Sstevel  * These data types describe the options for each type of component
26229949e86Sstevel  * internally to the jtag_init_*_ring routines. They can all be
26329949e86Sstevel  * recast into arrays of unsigned integers.
26429949e86Sstevel  *
26529949e86Sstevel  * Note that these types DEPEND on the *_init_pdesc structures, which
26629949e86Sstevel  * use indices to the components of the *_options types. As a result,
26729949e86Sstevel  * the data structure & the type must be modified simultaneously,
26829949e86Sstevel  * although this dependency is not immediately visible. This is ugly,
26929949e86Sstevel  * but it makes the initialization routines much more readable.
27029949e86Sstevel  */
27129949e86Sstevel 
27229949e86Sstevel typedef struct {
27329949e86Sstevel 	u_int frozen;
27429949e86Sstevel 	u_int reset_a;
27529949e86Sstevel 	u_int reset_b;
27629949e86Sstevel 	u_int board_id;
27729949e86Sstevel 	u_int mask_hwerr;
27829949e86Sstevel 	u_int arb_fast;
27929949e86Sstevel 	u_int node_id;
28029949e86Sstevel 	u_int pcr_hi;
28129949e86Sstevel 	u_int pcr_lo;
28229949e86Sstevel 	u_int pcc_ctl1;
28329949e86Sstevel 	u_int pcc_ctl0;
28429949e86Sstevel 	u_int pcc_tctrl;
28529949e86Sstevel } ac_options;
28629949e86Sstevel 
28729949e86Sstevel struct ac_regs {
28829949e86Sstevel 	unsigned int bcsr;
28929949e86Sstevel 	unsigned int brscr;
29029949e86Sstevel 	unsigned int esr_hi;
29129949e86Sstevel 	unsigned int esr_lo;
29229949e86Sstevel 	unsigned int emr_hi;
29329949e86Sstevel 	unsigned int emr_lo;
29429949e86Sstevel 	unsigned int ccr;
29529949e86Sstevel 	unsigned int cntr_hi;
29629949e86Sstevel 	unsigned int cntr_lo;
29729949e86Sstevel };
29829949e86Sstevel 
29929949e86Sstevel typedef struct {
30029949e86Sstevel 	u_int frozen;
30129949e86Sstevel 	u_int mask_pe;
30229949e86Sstevel 	u_int mask_oe;
30329949e86Sstevel } dc_options;
30429949e86Sstevel 
30529949e86Sstevel typedef struct {
30629949e86Sstevel 	u_int csr_hi;		/* CSR 20:18 */
30729949e86Sstevel 	u_int csr_mid;		/* CSR 16:8 */
30829949e86Sstevel 	u_int csr_midlo;	/* CSR 6:4 */
30929949e86Sstevel } fhc_options;
31029949e86Sstevel 
31129949e86Sstevel 
31229949e86Sstevel struct fhc_regs {
31329949e86Sstevel 	u_int por;
31429949e86Sstevel 	u_int csr;
31529949e86Sstevel 	u_int rcsr;
31629949e86Sstevel 	u_int bsr;
31729949e86Sstevel };
31829949e86Sstevel 
31929949e86Sstevel /* Structure to capture the scan data from the bct8244's. */
32029949e86Sstevel struct bct_fields {
32129949e86Sstevel 	u_int disk1_pres;
32229949e86Sstevel 	u_int disk0_pres;
32329949e86Sstevel 	u_int disk1_id;
32429949e86Sstevel 	u_int disk0_id;
32529949e86Sstevel };
32629949e86Sstevel 
32729949e86Sstevel /* Collective type for *_options * */
32829949e86Sstevel typedef u_int *jtag_opt;
32929949e86Sstevel 
33029949e86Sstevel /*
33129949e86Sstevel  * The following definitions are the action flags used in the byte
33229949e86Sstevel  * string which is used to describe component initialization. The
33329949e86Sstevel  * only piece of code which understands those flags is jtag_init_chip.
33429949e86Sstevel  *
33529949e86Sstevel  * Initializing a component consists of scanning successive values
33629949e86Sstevel  * into the component. The data for each pass is obtained by applying
33729949e86Sstevel  * successive patches to a reference pattern. The patch descriptors
33829949e86Sstevel  * are a byte string which form a succession of operations. The first
33929949e86Sstevel  * byte of an operation is a set of flags defining the action:
34029949e86Sstevel  */
34129949e86Sstevel #define	JTIN_INDEX	0x0F
34229949e86Sstevel #define	JTIN_INSERT	0x10
34329949e86Sstevel #define	JTIN_UPDATE	0x20
34429949e86Sstevel #define	JTIN_COMPARE	0x40
34529949e86Sstevel #define	JTIN_END	0x80
34629949e86Sstevel 
34729949e86Sstevel /*
34829949e86Sstevel  * When JTIN_INSERT is specified, the flag byte is followed by
34929949e86Sstevel  * two bytes indicating the lsb and msb of the field to be updated, and
35029949e86Sstevel  * the JTIN_INDEX part of the flags indicate which value should be
35129949e86Sstevel  * inserted: if JTIN_INDEX is zero, the value to insert is the next
35229949e86Sstevel  * byte in the aray, extended to a 32-bit word; if JTIN_INDEX is
35329949e86Sstevel  * non-zero, the value to insert is at word offset index in the patch
35429949e86Sstevel  * array passed to jtag_init_chip.
35529949e86Sstevel  */
35629949e86Sstevel 
35729949e86Sstevel /*
35829949e86Sstevel  * The fmt_desc field points to a reformat table which converts the
35929949e86Sstevel  * scan-out format to the standard DSCR-style format. The format descriptor
36029949e86Sstevel  * is a byte string, with special bytes indicating functional operations
36129949e86Sstevel  * as indicated by bit fields in the following table:
36229949e86Sstevel  */
36329949e86Sstevel #define	JTSO_END	0x80	/* end of table */
36429949e86Sstevel #define	JTSO_XTRACT	0x40	/* extract & merge [lsb, msb] */
36529949e86Sstevel #define	JTSO_ST		0x20	/* store & increment */
36629949e86Sstevel #define	JTSO_SHIFT	0x1F	/* shift count for extract & merge */
36729949e86Sstevel 
36829949e86Sstevel /*
36929949e86Sstevel  * Function Declarations
37029949e86Sstevel  */
37129949e86Sstevel static void jtag_error_print(int, jtag_error);
37229949e86Sstevel static int jtag_get_comp_id(volatile u_int *, jtag_phys_comp *);
37329949e86Sstevel 
37429949e86Sstevel /*
37529949e86Sstevel  *	Bit-field manipulations
37629949e86Sstevel  */
37729949e86Sstevel static u_int jtag_bf_extract(u_char *s, int lsb, int msb);
37829949e86Sstevel static void jtag_bf_insert(u_char *s, int lsb, int msb, int value);
37929949e86Sstevel static void jtag_bf_zero(u_char *s, int nbits);
38029949e86Sstevel static int jtag_bf_cmp(u_char *s1, u_char *s2, int nbits);
38129949e86Sstevel 
38229949e86Sstevel /*
38329949e86Sstevel  *	Test-access port interface
38429949e86Sstevel  */
38529949e86Sstevel static int tap_wait(volatile u_int *);
38629949e86Sstevel static int tap_shift_single(volatile u_int *, int, int);
38729949e86Sstevel static int tap_shift_multiple(volatile u_int *, u_char *, int, u_char *);
38829949e86Sstevel 
38929949e86Sstevel /*
39029949e86Sstevel  *    Ring-level interface
39129949e86Sstevel  */
39229949e86Sstevel 
39329949e86Sstevel static int select_ring(volatile u_int *, jtag_ring, int);
39429949e86Sstevel static int jtag_rescan_IR_DR(volatile u_int *, jtag_phys_comp *,
39529949e86Sstevel 	jtag_instruction, u_char *, int, u_char *);
39629949e86Sstevel static int jtag_single_IR_DR(volatile u_int *, jtag_phys_comp *,
39729949e86Sstevel 	jtag_instruction, u_char *, int, u_char *);
39829949e86Sstevel static int jtag_ring_length(volatile u_int *, jtag_ring);
39929949e86Sstevel static int jtag_ring_ir_length(volatile u_int *, jtag_ring);
40029949e86Sstevel 
40129949e86Sstevel /*
40229949e86Sstevel  *    Component-level interface
40329949e86Sstevel  */
40429949e86Sstevel 
40529949e86Sstevel static int jtag_scanout_chip(volatile u_int *, jtag_ring, jtag_phys_comp *,
40629949e86Sstevel 	u_int *);
40729949e86Sstevel static int jtag_init_chip(volatile u_int *, jtag_ring, jtag_phys_comp *,
40829949e86Sstevel 	const u_int *, u_char *);
40929949e86Sstevel static jtag_phys_comp *find_chip(jtag_ring_desc *, jtag_log_comp *, int);
41029949e86Sstevel static void format_chip_data(u_char *, u_int *, u_char *);
41129949e86Sstevel static int jtag_init_ac(volatile u_int *, int, enum board_type);
41229949e86Sstevel 
41329949e86Sstevel /*
41429949e86Sstevel  * Data tables.
41529949e86Sstevel  *
41629949e86Sstevel  * The JTAG implementation is data table driven. These tables describe
41729949e86Sstevel  * the chip, ring, and board components.
41829949e86Sstevel  */
41929949e86Sstevel 
42029949e86Sstevel /*
42129949e86Sstevel  *    Data structures describing the scannable components
42229949e86Sstevel  */
42329949e86Sstevel 
42429949e86Sstevel static char jtag_err[] = "JTAG ERROR";
42529949e86Sstevel 
42629949e86Sstevel /* Constants defining the IR lengths for each of the chips */
42729949e86Sstevel 
42829949e86Sstevel #define	IR_LEN 8	/* all sunfire asics, spitfire, and sdb  are 8 bits */
42929949e86Sstevel #define	HM_LEN 4	/* happy meal is 4 bits */
43029949e86Sstevel #define	NDP_LEN 2	/* ndp83840 is 2 bits */
43129949e86Sstevel #define	SOC_LEN 4	/* SOC is 4 bits */
43229949e86Sstevel #define	SOCPLUS_LEN 8	/* SOC+ is 8 bits */
43329949e86Sstevel #define	SIO_LEN 16	/* sysio asic is 16 bits */
43429949e86Sstevel #define	PSYO_LEN 4	/* psycho asic is 4 bits */
43529949e86Sstevel #define	CHEO_LEN 4	/* cheerio asic is 4 bits */
43629949e86Sstevel #define	EC_LEN 3	/* ecache tag rams is 3 bits each */
43729949e86Sstevel 
43829949e86Sstevel #define	FFB_LEN 16	/* ffb module is 16 bits */
43929949e86Sstevel #define	THREED_LEN	4	/* IR length for three D rams */
44029949e86Sstevel #define	BT498_LEN 4	/* IR length for bt 498 chip (ramdac) */
44129949e86Sstevel 
44229949e86Sstevel 
44329949e86Sstevel 
44429949e86Sstevel /* Standard instructions */
44529949e86Sstevel #define	IDCODE		0xFFFE
44629949e86Sstevel #define	INITCODE	0xbe
44729949e86Sstevel #define	DUMPCODE	0xbe
44829949e86Sstevel 
44929949e86Sstevel #define	CID_TO_REV(cid)	((cid) >> 28)
45029949e86Sstevel 
45129949e86Sstevel /* ASIC Jag IDs */
45229949e86Sstevel static u_int cid_sf[] = {
45329949e86Sstevel 	0x0002502f,
45429949e86Sstevel 	0
45529949e86Sstevel };
45629949e86Sstevel 
45729949e86Sstevel static u_int cid_sdb[] = {
45829949e86Sstevel 	0x0002602f,
45929949e86Sstevel 	0
46029949e86Sstevel };
46129949e86Sstevel 
46229949e86Sstevel static u_int cid_fbc[] = {
46329949e86Sstevel 	0x1241906d,
46429949e86Sstevel 	0
46529949e86Sstevel };
46629949e86Sstevel 
46729949e86Sstevel static u_int cid_lvt[] = {
46829949e86Sstevel 	0x0001d02f,
46929949e86Sstevel 	0
47029949e86Sstevel };
47129949e86Sstevel 
47229949e86Sstevel static u_int cid_3dram[] = {
47329949e86Sstevel 	0X0E9A103B,
47429949e86Sstevel 	0
47529949e86Sstevel };
47629949e86Sstevel 
47729949e86Sstevel static u_int cid_bt498[] = {
47829949e86Sstevel 	0x0001d02f,
47929949e86Sstevel 	0
48029949e86Sstevel };
48129949e86Sstevel 
48229949e86Sstevel static u_int cid_sio[] = {
48329949e86Sstevel 	0x0ef0703b,
48429949e86Sstevel 	0
48529949e86Sstevel };
48629949e86Sstevel 
48729949e86Sstevel static u_int cid_hm[] = {
48829949e86Sstevel 	0x01792045,
48929949e86Sstevel 	0
49029949e86Sstevel };
49129949e86Sstevel 
49229949e86Sstevel static u_int cid_ac[] = {
49329949e86Sstevel 	0x10f9e07d,
49429949e86Sstevel 	0
49529949e86Sstevel };
49629949e86Sstevel 
49729949e86Sstevel static u_int cid_dc[] = {
49829949e86Sstevel 	0x10f9f07d,
49929949e86Sstevel 	0
50029949e86Sstevel };
50129949e86Sstevel 
50229949e86Sstevel static u_int cid_fhc[] = {
50329949e86Sstevel 	0x10fa007d,
50429949e86Sstevel 	0
50529949e86Sstevel };
50629949e86Sstevel 
50729949e86Sstevel static u_int cid_psyo[] = {
50829949e86Sstevel 	0x3195401d,
50929949e86Sstevel 	0
51029949e86Sstevel };
51129949e86Sstevel 
51229949e86Sstevel static u_int cid_cheo[] = {
51329949e86Sstevel 	0x11791022,
51429949e86Sstevel 	0
51529949e86Sstevel };
51629949e86Sstevel 
51729949e86Sstevel 
51829949e86Sstevel /*
51929949e86Sstevel  * NOTE the following chips are ignored for the most part by the POST JTAG
52029949e86Sstevel  * If if is later determined that scan data may be of interest then we need
52129949e86Sstevel  * to fill in the blanks below.
52229949e86Sstevel  */
52329949e86Sstevel 
52429949e86Sstevel static u_char ec_init_pdesc[] = {
52529949e86Sstevel 	JTIN_END|JTIN_INSERT|0, 0, 0, 0x0
52629949e86Sstevel };
52729949e86Sstevel 
52829949e86Sstevel static u_char ec_fmt[] = {
52929949e86Sstevel 	JTSO_ST|JTSO_XTRACT|JTSO_END| 0, 0, 4
53029949e86Sstevel };
53129949e86Sstevel 
53229949e86Sstevel static u_char sio_init_pdesc[] = {
53329949e86Sstevel 	JTIN_END|JTIN_INSERT|0, 0, 0, 0x0
53429949e86Sstevel };
53529949e86Sstevel 
53629949e86Sstevel static u_char sio_fmt[] = {
53729949e86Sstevel 	JTSO_ST|JTSO_XTRACT|JTSO_END| 0, 0, 4
53829949e86Sstevel };
53929949e86Sstevel 
54029949e86Sstevel static u_char psyo_init_pdesc[] = {
54129949e86Sstevel 	JTIN_END|JTIN_INSERT|0, 0, 0, 0x0
54229949e86Sstevel };
54329949e86Sstevel 
54429949e86Sstevel static u_char psyo_fmt[] = {
54529949e86Sstevel 	JTSO_ST|JTSO_XTRACT|JTSO_END| 0, 0, 4
54629949e86Sstevel };
54729949e86Sstevel 
54829949e86Sstevel static u_char hm_init_pdesc[] = {
54929949e86Sstevel 	JTIN_END|JTIN_INSERT|0, 0, 0, 0x0
55029949e86Sstevel };
55129949e86Sstevel 
55229949e86Sstevel static u_char hm_fmt[] = {
55329949e86Sstevel 	JTSO_ST|JTSO_XTRACT|JTSO_END| 0, 0, 4
55429949e86Sstevel };
55529949e86Sstevel 
55629949e86Sstevel static u_char ndp_init_pdesc[] = {
55729949e86Sstevel 	JTIN_END|JTIN_INSERT|0, 0, 0, 0x0
55829949e86Sstevel };
55929949e86Sstevel 
56029949e86Sstevel static u_char ndp_fmt[] = {
56129949e86Sstevel 	JTSO_ST|JTSO_XTRACT|JTSO_END| 0, 0, 4
56229949e86Sstevel };
56329949e86Sstevel 
56429949e86Sstevel static u_char cheo_init_pdesc[] = {
56529949e86Sstevel 	JTIN_END|JTIN_INSERT|0, 0, 0, 0x0
56629949e86Sstevel };
56729949e86Sstevel 
56829949e86Sstevel static u_char cheo_fmt[] = {
56929949e86Sstevel 	JTSO_ST|JTSO_XTRACT|JTSO_END| 0, 0, 4
57029949e86Sstevel };
57129949e86Sstevel 
57229949e86Sstevel 
57329949e86Sstevel /* The main ASCIS of interest are the AC, DC and FHC */
57429949e86Sstevel 
57529949e86Sstevel /*
57629949e86Sstevel  * The initialization of DC is as follows:
57729949e86Sstevel  *
57829949e86Sstevel  * Do NOT change the following data structure without checking
57929949e86Sstevel  * _options in jtag_private.h, which depends on it.
58029949e86Sstevel  */
58129949e86Sstevel static u_char dc_init_pdesc[] = {
58229949e86Sstevel 	JTIN_INSERT|1,   0,   0,	/* NFZN */
58329949e86Sstevel 	JTIN_INSERT|2,   4,   4,	/* Mask PE */
58429949e86Sstevel 	JTIN_INSERT|3,   3,   3,	/* Mask OE */
58529949e86Sstevel 	JTIN_INSERT|0,   1,   2,  3,	/* W1C Errors */
58629949e86Sstevel 	JTIN_END|JTIN_UPDATE,
58729949e86Sstevel };
58829949e86Sstevel 
58929949e86Sstevel static u_char dc_fmt[] = {
59029949e86Sstevel 	JTSO_ST|JTSO_XTRACT|JTSO_END| 0, 0, 4    /* DC[4:0] */
59129949e86Sstevel };
59229949e86Sstevel 
59329949e86Sstevel /*
59429949e86Sstevel  * The initialization of AC is as follows:
59529949e86Sstevel  *
59629949e86Sstevel  * Do NOT change the following data structure without checking
59729949e86Sstevel  * _options in jtag_private.h, which depends on it.
59829949e86Sstevel  */
59929949e86Sstevel static u_char ac_init_pdesc[] = {
60029949e86Sstevel 	JTIN_INSERT|0, 161, 161, 1,	/* BOARD ADDR 40 */
60129949e86Sstevel 	JTIN_INSERT|7, 159, 160,	/* BOARD ADDR 39:38, wfi node */
60229949e86Sstevel 	JTIN_INSERT|4, 155, 158, 	/* BOARD ADDR 37:34 */
60329949e86Sstevel 	JTIN_INSERT|4, 151, 154, 	/* BOARD ID */
60429949e86Sstevel 	JTIN_INSERT|6, 146, 146,	/* ARB_FAST */
60529949e86Sstevel 	JTIN_INSERT|1, 134, 134,	/* NFZN */
60629949e86Sstevel 	JTIN_INSERT|0, 133, 133, 0,	/* ENWAKPOR  */
60729949e86Sstevel 	JTIN_INSERT|2, 135, 135,	/* Reset B */
60829949e86Sstevel 	JTIN_INSERT|3, 136, 136,	/* Reset A */
60929949e86Sstevel 	JTIN_INSERT|0, 99, 106, 0xff,	/* W1C Errors */
61029949e86Sstevel 	JTIN_INSERT|0, 107, 114, 0xff,	/* W1C Errors */
61129949e86Sstevel 	JTIN_INSERT|0, 115, 122, 0xff,	/* W1C Errors */
61229949e86Sstevel 	JTIN_INSERT|0, 123, 130, 0xff,	/* W1C Errors */
61329949e86Sstevel 	JTIN_INSERT|0, 131, 132, 0xff,	/* W1C Errors */
61429949e86Sstevel 	JTIN_INSERT|5, 88, 98,		/* Error Masks */
61529949e86Sstevel 	JTIN_INSERT|12, 76, 87,		/* CNT1_CTL_<27:16> */
61629949e86Sstevel 	JTIN_INSERT|10, 70, 75,		/* CNT1_CTL <13:8> */
61729949e86Sstevel 	JTIN_INSERT|11, 64, 69,		/* CNT0_CTL <5:0> */
61829949e86Sstevel 	JTIN_INSERT|8, 32, 63,		/* CNT1 */
61929949e86Sstevel 	JTIN_INSERT|9, 0, 31,		/* CNT0 */
62029949e86Sstevel 	JTIN_END|JTIN_UPDATE,		/* Clears counters */
62129949e86Sstevel };
62229949e86Sstevel 
62329949e86Sstevel static u_char ac_fmt[] = {
62429949e86Sstevel 	JTSO_XTRACT|17,			148,	162,	/* BCSR[31:17] */
62529949e86Sstevel 	JTSO_XTRACT|15,			147,	147,	/* BSCR[15] */
62629949e86Sstevel 	JTSO_XTRACT|5,			138,	146,	/* BSCR[13:5] */
62729949e86Sstevel 	JTSO_ST|JTSO_XTRACT|0,		134,	137,	/* BSCR[3:0] */
62829949e86Sstevel 	JTSO_ST|JTSO_XTRACT|22,		133, 	133,	/* BRSCR[22] */
62929949e86Sstevel 	JTSO_XTRACT|16,			131,	132,	/* ESR[49:48] */
63029949e86Sstevel 	JTSO_XTRACT|8,			124,	130,	/* ESR[46:40] */
63129949e86Sstevel 	JTSO_XTRACT|4,			122,	123,	/* ESR[37:36] */
63229949e86Sstevel 	JTSO_ST|JTSO_XTRACT|0,		120,	121,	/* ESR[33:32] */
63329949e86Sstevel 	JTSO_XTRACT|28,			116,	119,	/* ESR[31:28] */
63429949e86Sstevel 	JTSO_XTRACT|24,			115,	115,	/* ESR[24] */
63529949e86Sstevel 	JTSO_XTRACT|20,			112,	114,    /* ESR[22:20] */
63629949e86Sstevel 	JTSO_XTRACT|12,			107,	111,    /* ESR[16:12] */
63729949e86Sstevel 	JTSO_XTRACT|4,			101,	106,	/* ESR[9:4] */
63829949e86Sstevel 	JTSO_ST|JTSO_XTRACT|0,		99,	100,	/* ESR[1:0] */
63929949e86Sstevel 	JTSO_XTRACT|16,			97,	98,	/* EMR[49:48] */
64029949e86Sstevel 	JTSO_XTRACT|8,			96,	96,	/* EMR[40] */
64129949e86Sstevel 	JTSO_ST|JTSO_XTRACT|4,		94,	95,	/* EMR[37:36] */
64229949e86Sstevel 	JTSO_XTRACT|28,			93,	93,	/* EMR[28] */
64329949e86Sstevel 	JTSO_XTRACT|24,			92,	92,	/* EMR[24] */
64429949e86Sstevel 	JTSO_XTRACT|20,			91,	91,	/* EMR[20] */
64529949e86Sstevel 	JTSO_XTRACT|12,			90,	90,	/* EMR[12] */
64629949e86Sstevel 	JTSO_XTRACT|8,			89,	89,	/* EMR[8] */
64729949e86Sstevel 	JTSO_ST|JTSO_XTRACT|4,		88,	88,	/* EMR[4] */
64829949e86Sstevel 	JTSO_XTRACT|16,			76,	87,	/* CCR[27:16] */
64929949e86Sstevel 	JTSO_XTRACT|8,			70,	75,	/* CCR[13:8] */
65029949e86Sstevel 	JTSO_ST|JTSO_XTRACT|0,		64,	69,	/* CCR[5:0] */
65129949e86Sstevel 	JTSO_ST|JTSO_XTRACT|0,		32,	63,	/* CNT[63:32] */
65229949e86Sstevel 	JTSO_ST|JTSO_XTRACT|JTSO_END|0,	0,	31	/* CNT[31:0] */
65329949e86Sstevel };
65429949e86Sstevel 
65529949e86Sstevel /*
65629949e86Sstevel  */
65729949e86Sstevel 
65829949e86Sstevel /*
65929949e86Sstevel  * The following structure has three variable elements, as noted
66029949e86Sstevel  * by the 1,2 and 3 digits or'ed in with the JTIN_INSERT flags.
66129949e86Sstevel  * The number nad position of these elements must correspond with
66229949e86Sstevel  * the fhc_ structure apssed into fhc_chip_init.
66329949e86Sstevel  */
66429949e86Sstevel static u_char fhc_init_pdesc[] = {
66529949e86Sstevel 	JTIN_INSERT|0,	41,	41,	0,		/* POR */
66629949e86Sstevel 	JTIN_INSERT|1,	38,	40,			/* CSR[20:18] */
66729949e86Sstevel 	JTIN_INSERT|2,	29,	37,			/* CSR[16:8] */
66829949e86Sstevel 	JTIN_INSERT|3,	26,	28,			/* CSR[6:4] */
66929949e86Sstevel 	JTIN_INSERT|0,	24,	25,	0x0,		/* CSR[1:0] */
67029949e86Sstevel 	JTIN_INSERT|0,	16,	23,	0x0,		/* RCSR[31:24] */
67129949e86Sstevel 	JTIN_INSERT|0,	2,	15,	0x0,		/* BSR[18:5] */
67229949e86Sstevel 	JTIN_INSERT|0,	0,	1,	0x0,		/* BSR[1:0] */
67329949e86Sstevel 	JTIN_END|JTIN_UPDATE,
67429949e86Sstevel };
67529949e86Sstevel 
67629949e86Sstevel static u_char fhc_fmt[] = {
67729949e86Sstevel 	JTSO_ST|JTSO_XTRACT|0,		41,	41,	/* POR State */
67829949e86Sstevel 	JTSO_XTRACT|18,			38,	40,	/* CSR[20:18] */
67929949e86Sstevel 	JTSO_XTRACT|8,			29,	37,	/* CSR[16:8] */
68029949e86Sstevel 	JTSO_XTRACT|4,			26,	28,	/* CSR[6:4] */
68129949e86Sstevel 	JTSO_ST|JTSO_XTRACT|0,		24,	25,	/* CSR[1:0] */
68229949e86Sstevel 	JTSO_ST|JTSO_XTRACT|24,		16,	23,	/* RCSR[31:24] */
68329949e86Sstevel 	JTSO_XTRACT|5,			2,	15,	/* BSR[18:5] */
68429949e86Sstevel 	JTSO_ST|JTSO_XTRACT|JTSO_END|0,	0,	1,	/* BSR[1:0] */
68529949e86Sstevel };
68629949e86Sstevel 
68729949e86Sstevel 
68829949e86Sstevel static u_char bct8244_fmt[] = {
68929949e86Sstevel 	JTSO_ST|JTSO_XTRACT|0,		17,	17,	/* Disk 1 present */
69029949e86Sstevel 	JTSO_ST|JTSO_XTRACT|0,		16,	16,	/* Disk 0 present */
69129949e86Sstevel 	JTSO_ST|JTSO_XTRACT|0,		12,	15,	/* Disk 1 Target */
69229949e86Sstevel 	JTSO_ST|JTSO_XTRACT|JTSO_END|0,	8,	11,	/* Disk 0 Target */
69329949e86Sstevel };
69429949e86Sstevel 
69529949e86Sstevel /* A jtag_log_comp describes a component as seen by JTAG. */
69629949e86Sstevel 
69729949e86Sstevel static jtag_log_comp chip_ac = {
69829949e86Sstevel 	cid_ac,
69929949e86Sstevel 	IR_LEN, 163,
70029949e86Sstevel 	IDCODE, INITCODE, DUMPCODE,
70129949e86Sstevel 	ac_init_pdesc, ac_fmt
70229949e86Sstevel };
70329949e86Sstevel 
70429949e86Sstevel static jtag_log_comp chip_bct8244 = {
70529949e86Sstevel 	0,
70629949e86Sstevel 	IR_LEN, 18,
70729949e86Sstevel 	0x2, 0x2, 0x2,
70829949e86Sstevel 	NULL, bct8244_fmt
70929949e86Sstevel };
71029949e86Sstevel 
71129949e86Sstevel static jtag_log_comp chip_dc = {
71229949e86Sstevel 	cid_dc,
71329949e86Sstevel 	IR_LEN, 5,
71429949e86Sstevel 	IDCODE, INITCODE, DUMPCODE,
71529949e86Sstevel 	dc_init_pdesc, dc_fmt
71629949e86Sstevel };
71729949e86Sstevel 
71829949e86Sstevel static jtag_log_comp chip_fhc = {
71929949e86Sstevel 	cid_fhc,
72029949e86Sstevel 	IR_LEN, 42,
72129949e86Sstevel 	IDCODE, INITCODE, DUMPCODE,
72229949e86Sstevel 	fhc_init_pdesc, fhc_fmt
72329949e86Sstevel };
72429949e86Sstevel 
72529949e86Sstevel static jtag_log_comp chip_ec = {
72629949e86Sstevel 	0,
72729949e86Sstevel 	EC_LEN, 42,
72829949e86Sstevel 	1, INITCODE, IDCODE,
72929949e86Sstevel 	ec_init_pdesc, ec_fmt
73029949e86Sstevel };
73129949e86Sstevel 
73229949e86Sstevel static jtag_log_comp chip_fbc = {
73329949e86Sstevel 	cid_fbc,
73429949e86Sstevel 	FFB_LEN, 42,
73529949e86Sstevel 	0xb000, 0xb000, 0xb000,
73629949e86Sstevel 	NULL, NULL
73729949e86Sstevel };
73829949e86Sstevel 
73929949e86Sstevel static jtag_log_comp chip_lvt = {
74029949e86Sstevel 	cid_lvt,
74129949e86Sstevel 	IR_LEN, 42,
74229949e86Sstevel 	IDCODE, INITCODE, DUMPCODE,
74329949e86Sstevel 	NULL, NULL
74429949e86Sstevel };
74529949e86Sstevel 
74629949e86Sstevel static jtag_log_comp chip_3dram = {
74729949e86Sstevel 	cid_3dram,
74829949e86Sstevel 	THREED_LEN, 42,
74929949e86Sstevel 	IDCODE, INITCODE, DUMPCODE,
75029949e86Sstevel 	NULL, NULL
75129949e86Sstevel };
75229949e86Sstevel 
75329949e86Sstevel static jtag_log_comp chip_bt498 = {
75429949e86Sstevel 	cid_bt498,
75529949e86Sstevel 	BT498_LEN, 42,
75629949e86Sstevel 	IDCODE, INITCODE, DUMPCODE,
75729949e86Sstevel 	NULL, NULL
75829949e86Sstevel };
75929949e86Sstevel 
76029949e86Sstevel static jtag_log_comp chip_sio = {
76129949e86Sstevel 	cid_sio,
76229949e86Sstevel 	SIO_LEN, 42,
76329949e86Sstevel 	0xb000, 0xb000, 0xb000,
76429949e86Sstevel 	sio_init_pdesc, sio_fmt
76529949e86Sstevel };
76629949e86Sstevel 
76729949e86Sstevel static jtag_log_comp chip_hm = {
76829949e86Sstevel 	cid_hm,
76929949e86Sstevel 	HM_LEN, 42,
77029949e86Sstevel 	0xe, 0xe, 0xe,
77129949e86Sstevel 	hm_init_pdesc, hm_fmt
77229949e86Sstevel };
77329949e86Sstevel 
77429949e86Sstevel static jtag_log_comp chip_ndp = {
77529949e86Sstevel 	0,
77629949e86Sstevel 	NDP_LEN, 42,
77729949e86Sstevel 	2, 2, 2,
77829949e86Sstevel 	ndp_init_pdesc, ndp_fmt
77929949e86Sstevel };
78029949e86Sstevel 
78129949e86Sstevel static jtag_log_comp chip_soc = {
78229949e86Sstevel 	0,
78329949e86Sstevel 	SOC_LEN, 42,
78429949e86Sstevel 	4, 4, 4,
78529949e86Sstevel 	NULL, NULL
78629949e86Sstevel };
78729949e86Sstevel 
78829949e86Sstevel static jtag_log_comp chip_socplus = {
78929949e86Sstevel 	0,
79029949e86Sstevel 	SOCPLUS_LEN, 42,
79129949e86Sstevel 	0xfe, 4, 4,
79229949e86Sstevel 	NULL, NULL
79329949e86Sstevel };
79429949e86Sstevel 
79529949e86Sstevel static jtag_log_comp chip_spitfire = {
79629949e86Sstevel 	cid_sf,
79729949e86Sstevel 	IR_LEN, 42,
79829949e86Sstevel 	0xfe, 0xfe, 0xfe,
79929949e86Sstevel 	NULL, NULL
80029949e86Sstevel };
80129949e86Sstevel 
80229949e86Sstevel 
80329949e86Sstevel static jtag_log_comp chip_sdb = {
80429949e86Sstevel 	cid_sdb,
80529949e86Sstevel 	IR_LEN,  42,
80629949e86Sstevel 	0xfe, 0xfe, 0xfe,
80729949e86Sstevel 	NULL, NULL
80829949e86Sstevel };
80929949e86Sstevel 
81029949e86Sstevel static jtag_log_comp chip_psyo = {
81129949e86Sstevel 	cid_psyo,
81229949e86Sstevel 	PSYO_LEN, 42,
81329949e86Sstevel 	0xb000, 0xb000, 0xb000,
81429949e86Sstevel 	psyo_init_pdesc, psyo_fmt
81529949e86Sstevel };
81629949e86Sstevel 
81729949e86Sstevel static jtag_log_comp chip_cheo = {
81829949e86Sstevel 	cid_cheo,
81929949e86Sstevel 	CHEO_LEN, 42,
82029949e86Sstevel 	0xb000, 0xb000, 0xb000,
82129949e86Sstevel 	cheo_init_pdesc, cheo_fmt
82229949e86Sstevel };
82329949e86Sstevel 
82429949e86Sstevel /*
82529949e86Sstevel  *    Ring descriptions for sunfire boards
82629949e86Sstevel  *
82729949e86Sstevel  * For each ring, there is a generic type descriptor which describes
82829949e86Sstevel  * the order of chips in the static data structure describing the
82929949e86Sstevel  * ring.
83029949e86Sstevel  *
83129949e86Sstevel  * Rings are described by an array of physical components, and are
83229949e86Sstevel  * recast into the specific ring type by routines which use them, see
83329949e86Sstevel  * for example the jtag_init_*_ring routines.
83429949e86Sstevel  *
83529949e86Sstevel  * Although the ring data structures are declared as jtag_phys_comp[],
83629949e86Sstevel  * the components must be ordered as required by the corresponding
83729949e86Sstevel  * *_*_ring type (in jtag_private.h).
83829949e86Sstevel  */
83929949e86Sstevel 
84029949e86Sstevel /*
84129949e86Sstevel  *    Data structures describing the system board rings
84229949e86Sstevel  */
84329949e86Sstevel 
84429949e86Sstevel static jtag_phys_comp cpu_sysbd_ring_components[] = {
84529949e86Sstevel 	{ &chip_ac, 11*IR_LEN,	0,		11,	0 },	/* AC */
84629949e86Sstevel 	{ &chip_dc, 10*IR_LEN,	1*IR_LEN,	10,	1 },	/* DC 1 */
84729949e86Sstevel 	{ &chip_dc, 9*IR_LEN,	2*IR_LEN,	9,	2 }, 	/* DC 2 */
84829949e86Sstevel 	{ &chip_dc, 8*IR_LEN,	3*IR_LEN,	8,	3 }, 	/* DC 3 */
84929949e86Sstevel 	{ &chip_dc, 7*IR_LEN,	4*IR_LEN,	7,	4 }, 	/* DC 4 */
85029949e86Sstevel 	{ &chip_dc, 6*IR_LEN,	5*IR_LEN,	6,	5 }, 	/* DC 5 */
85129949e86Sstevel 	{ &chip_dc, 5*IR_LEN,	6*IR_LEN,	5,	6 }, 	/* DC 6 */
85229949e86Sstevel 	{ &chip_dc, 4*IR_LEN,	7*IR_LEN,	4,	7 }, 	/* DC 7 */
85329949e86Sstevel 	{ &chip_dc, 3*IR_LEN,	8*IR_LEN,	3,	8 }, 	/* DC 8 */
85429949e86Sstevel 	{ &chip_fhc, 2*IR_LEN,	9*IR_LEN,	2,	9 }, 	/* FHC */
85529949e86Sstevel 	{ &chip_ec, 1*IR_LEN,	10*IR_LEN,	1,	10 }, 	/* RAM 0 */
85629949e86Sstevel 	{ &chip_ec, 0*IR_LEN,	11*IR_LEN,	0,	11 }, 	/* RAM 1 */
85729949e86Sstevel };
85829949e86Sstevel 
85929949e86Sstevel static jtag_ring_desc  cpu_sysbd_ring = {
86029949e86Sstevel 	12, cpu_sysbd_ring_components
86129949e86Sstevel };
86229949e86Sstevel 
86329949e86Sstevel 
86429949e86Sstevel static jtag_phys_comp cpu_mod_1m_ring_components[] = {
86529949e86Sstevel 	{ &chip_spitfire, 43,	0,	11,	0 },	/* Spitfire */
86629949e86Sstevel 	{ &chip_ec,	40,	8,	10,	1 },	/* Parity chip */
86729949e86Sstevel 	{ &chip_ec,	37,	11,	9,	2 },	/* Byte 0 */
86829949e86Sstevel 	{ &chip_ec,	34,	14,	8,	3 },	/* Byte 1 */
86929949e86Sstevel 	{ &chip_ec,	31,	17,	7,	4 },	/* Byte 2 */
87029949e86Sstevel 	{ &chip_ec,	28,	20,	6,	5 },	/* Byte 3 */
87129949e86Sstevel 	{ &chip_ec,	25,	23,	5,	6 },	/* Byte 4 */
87229949e86Sstevel 	{ &chip_ec,	22,	26,	4,	7 },	/* Byte 5 */
87329949e86Sstevel 	{ &chip_ec,	19,	29,	3,	8 },	/* Byte 6 */
87429949e86Sstevel 	{ &chip_ec,	16,	32,	2,	9 },	/* Byte 7 */
87529949e86Sstevel 	{ &chip_sdb,	8,	35,	1,	10 },	/* SDB */
87629949e86Sstevel 	{ &chip_sdb,	0,	43,	0,	11 },	/* SDB */
87729949e86Sstevel };
87829949e86Sstevel 
87929949e86Sstevel static jtag_ring_desc  cpu_mod_1m_ring = {
88029949e86Sstevel 	12, cpu_mod_1m_ring_components
88129949e86Sstevel };
88229949e86Sstevel 
88329949e86Sstevel static jtag_phys_comp cpu_mod_ring_components[] = {
88429949e86Sstevel 	{ &chip_spitfire, 31,	0,	7,	0 },	/* Spitfire */
88529949e86Sstevel 	{ &chip_ec,	28,	8,	6,	1 },	/* Parity chip */
88629949e86Sstevel 	{ &chip_ec,	25,	11,	5,	2 },	/* Byte 0 */
88729949e86Sstevel 	{ &chip_ec,	22,	14,	4,	3 },	/* Byte 1 */
88829949e86Sstevel 	{ &chip_ec,	19,	17,	3,	4 },	/* Byte 2 */
88929949e86Sstevel 	{ &chip_ec,	16,	20,	2,	5 },	/* Byte 3 */
89029949e86Sstevel 	{ &chip_sdb,	8,	23,	1,	6 },	/* SDB */
89129949e86Sstevel 	{ &chip_sdb,	0,	31,	0,	7 },	/* SDB */
89229949e86Sstevel };
89329949e86Sstevel 
89429949e86Sstevel static jtag_ring_desc  cpu_mod_ring = {
89529949e86Sstevel 	8, cpu_mod_ring_components
89629949e86Sstevel };
89729949e86Sstevel 
89829949e86Sstevel static jtag_phys_comp io1_sysbd_ring_components[] = {
89929949e86Sstevel 	{ &chip_ac,	114,	0,	14,	0 },	/* AC */
90029949e86Sstevel 	{ &chip_dc,	106,	8,	13,	1 },	/* DC 1 */
90129949e86Sstevel 	{ &chip_dc,	98,	16,	12,	2 },	/* DC 2 */
90229949e86Sstevel 	{ &chip_dc,	90,	24,	11,	3 },	/* DC 3 */
90329949e86Sstevel 	{ &chip_dc,	82,	32,	10,	4 },	/* DC 4 */
90429949e86Sstevel 	{ &chip_dc,	74,	40,	9,	5 },	/* DC 5 */
90529949e86Sstevel 	{ &chip_dc,	66,	48,	8,	6 },	/* DC 6 */
90629949e86Sstevel 	{ &chip_dc,	58,	56,	7,	7 },	/* DC 7 */
90729949e86Sstevel 	{ &chip_dc,	50,	64,	6,	8 },	/* DC 8 */
90829949e86Sstevel 	{ &chip_fhc,	42,	72,	5,	9 },	/* FHC */
90929949e86Sstevel 	{ &chip_sio,	26,	80,	4,	10 },	/* SIO 0 */
91029949e86Sstevel 	{ &chip_sio,	10,	96,	3,	11 },	/* SIO 1 */
91129949e86Sstevel 	{ &chip_hm,	6,	112,	2,	12 },	/* HM */
91229949e86Sstevel 	{ &chip_ndp,	4,	116,	1,	13 },	/* NDP */
91329949e86Sstevel 	{ &chip_soc,	0,	118,	0,	14 },	/* SOC */
91429949e86Sstevel };
91529949e86Sstevel 
91629949e86Sstevel static jtag_phys_comp io2_sysbd_ring_components[] = {
91729949e86Sstevel 	{ &chip_ac,	98,	0,	13,	0 },	/* AC */
91829949e86Sstevel 	{ &chip_dc,	90,	8,	12,	1 },	/* DC 1 */
91929949e86Sstevel 	{ &chip_dc,	82,	16,	11,	2 },	/* DC 2 */
92029949e86Sstevel 	{ &chip_dc,	74,	24,	10,	3 },	/* DC 3 */
92129949e86Sstevel 	{ &chip_dc,	66,	32,	9,	4 },	/* DC 4 */
92229949e86Sstevel 	{ &chip_dc,	58,	40,	8,	5 },	/* DC 5 */
92329949e86Sstevel 	{ &chip_dc,	50,	48,	7,	6 },	/* DC 6 */
92429949e86Sstevel 	{ &chip_dc,	42,	56,	6,	7 },	/* DC 7 */
92529949e86Sstevel 	{ &chip_dc,	34,	64,	5,	8 },	/* DC 8 */
92629949e86Sstevel 	{ &chip_fhc,	26,	72,	4,	9 },	/* FHC */
92729949e86Sstevel 	{ &chip_sio,	10,	80,	3,	10 },	/* SIO */
92829949e86Sstevel 	{ &chip_hm,	6,	96,	2,	11 },	/* HM */
92929949e86Sstevel 	{ &chip_ndp,	4,	100,	1,	12 },	/* NDP */
93029949e86Sstevel 	{ &chip_soc,	0,	102,	0,	13 },	/* SOC */
93129949e86Sstevel };
93229949e86Sstevel 
93329949e86Sstevel static jtag_phys_comp io1plus_sysbd_ring_components[] = {
93429949e86Sstevel 	{ &chip_ac,	118,	0,	14,	0 },	/* AC */
93529949e86Sstevel 	{ &chip_dc,	110,	8,	13,	1 },	/* DC 1 */
93629949e86Sstevel 	{ &chip_dc,	102,	16,	12,	2 },	/* DC 2 */
93729949e86Sstevel 	{ &chip_dc,	94,	24,	11,	3 },	/* DC 3 */
93829949e86Sstevel 	{ &chip_dc,	86,	32,	10,	4 },	/* DC 4 */
93929949e86Sstevel 	{ &chip_dc,	78,	40,	9,	5 },	/* DC 5 */
94029949e86Sstevel 	{ &chip_dc,	70,	48,	8,	6 },	/* DC 6 */
94129949e86Sstevel 	{ &chip_dc,	62,	56,	7,	7 },	/* DC 7 */
94229949e86Sstevel 	{ &chip_dc,	54,	64,	6,	8 },	/* DC 8 */
94329949e86Sstevel 	{ &chip_fhc,	46,	72,	5,	9 },	/* FHC */
94429949e86Sstevel 	{ &chip_sio,	30,	80,	4,	10 },	/* SIO 0 */
94529949e86Sstevel 	{ &chip_sio,	14,	96,	3,	11 },	/* SIO 1 */
94629949e86Sstevel 	{ &chip_hm,	10,	112,	2,	12 },	/* HM */
94729949e86Sstevel 	{ &chip_ndp,	8,	116,	1,	13 },	/* NDP */
94829949e86Sstevel 	{ &chip_socplus, 0,	118,	0,	14 },	/* SOC+ */
94929949e86Sstevel };
95029949e86Sstevel 
95129949e86Sstevel static jtag_phys_comp io2plus_sysbd_ring_components[] = {
95229949e86Sstevel 	{ &chip_ac,	102,	0,	13,	0 },	/* AC */
95329949e86Sstevel 	{ &chip_dc,	94,	8,	12,	1 },	/* DC 1 */
95429949e86Sstevel 	{ &chip_dc,	86,	16,	11,	2 },	/* DC 2 */
95529949e86Sstevel 	{ &chip_dc,	78,	24,	10,	3 },	/* DC 3 */
95629949e86Sstevel 	{ &chip_dc,	70,	32,	9,	4 },	/* DC 4 */
95729949e86Sstevel 	{ &chip_dc,	62,	40,	8,	5 },	/* DC 5 */
95829949e86Sstevel 	{ &chip_dc,	54,	48,	7,	6 },	/* DC 6 */
95929949e86Sstevel 	{ &chip_dc,	46,	56,	6,	7 },	/* DC 7 */
96029949e86Sstevel 	{ &chip_dc,	38,	64,	5,	8 },	/* DC 8 */
96129949e86Sstevel 	{ &chip_fhc,	30,	72,	4,	9 },	/* FHC */
96229949e86Sstevel 	{ &chip_sio,	14,	80,	3,	10 },	/* SIO */
96329949e86Sstevel 	{ &chip_hm,	10,	96,	2,	11 },	/* HM */
96429949e86Sstevel 	{ &chip_ndp,	8,	100,	1,	12 },	/* NDP */
96529949e86Sstevel 	{ &chip_socplus, 0,	102,	0,	13 },	/* SOC+ */
96629949e86Sstevel };
96729949e86Sstevel 
96829949e86Sstevel static jtag_phys_comp io3_sysbd_ring_components[] = {
96929949e86Sstevel 	{ &chip_ac,	102,	0,	15,	0 },	/* AC */
97029949e86Sstevel 	{ &chip_dc,	94,	8,	14,	1 },	/* DC 1 */
97129949e86Sstevel 	{ &chip_dc,	86,	16,	13,	2 },	/* DC 2 */
97229949e86Sstevel 	{ &chip_dc,	78,	24,	12,	3 },	/* DC 3 */
97329949e86Sstevel 	{ &chip_dc,	70,	32,	11,	4 },	/* DC 4 */
97429949e86Sstevel 	{ &chip_dc,	62,	40,	10,	5 },	/* DC 5 */
97529949e86Sstevel 	{ &chip_dc,	54,	48,	9,	6 },	/* DC 6 */
97629949e86Sstevel 	{ &chip_dc,	46,	56,	8,	7 },	/* DC 7 */
97729949e86Sstevel 	{ &chip_dc,	38,	64,	7,	8 },	/* DC 8 */
97829949e86Sstevel 	{ &chip_fhc,	30,	72,	6,	9 },	/* FHC */
97929949e86Sstevel 	{ &chip_psyo,	26,	80,	5,	10 },	/* PSYO 0 */
98029949e86Sstevel 	{ &chip_cheo,	22,	84,	4,	11 },	/* CHEO */
98129949e86Sstevel 	{ &chip_ndp,	20,	88,	3,	12 },	/* NDP */
98229949e86Sstevel 	{ &chip_psyo,	16,	90,	2,	13 },	/* PSYO 1 */
98329949e86Sstevel 	{ &chip_bct8244,	8,	94,	1,	14 },	/* BCT 8244 */
98429949e86Sstevel 	{ &chip_bct8244,	0,	102,	0,	15 },	/* BCT 8244 */
98529949e86Sstevel };
98629949e86Sstevel 
98729949e86Sstevel static jtag_phys_comp dsk_sysbd_ring_components[] = {
98829949e86Sstevel 	{ &chip_bct8244, 8,	0,	1,	0 },	/* BCT 8244 */
98929949e86Sstevel 	{ &chip_fhc,	0,	8,	0,	1 },	/* FHC */
99029949e86Sstevel };
99129949e86Sstevel 
99229949e86Sstevel static jtag_ring_desc  io1_sysbd_ring = {
99329949e86Sstevel 	15, io1_sysbd_ring_components
99429949e86Sstevel };
99529949e86Sstevel 
99629949e86Sstevel static jtag_ring_desc  io1plus_sysbd_ring = {
99729949e86Sstevel 	15, io1plus_sysbd_ring_components
99829949e86Sstevel };
99929949e86Sstevel 
100029949e86Sstevel static jtag_ring_desc  io2_sysbd_ring = {
100129949e86Sstevel 	14, io2_sysbd_ring_components
100229949e86Sstevel };
100329949e86Sstevel 
100429949e86Sstevel static jtag_ring_desc  io2plus_sysbd_ring = {
100529949e86Sstevel 	14, io2plus_sysbd_ring_components
100629949e86Sstevel };
100729949e86Sstevel 
100829949e86Sstevel static jtag_ring_desc  io3_sysbd_ring = {
100929949e86Sstevel 	16, io3_sysbd_ring_components
101029949e86Sstevel };
101129949e86Sstevel 
101229949e86Sstevel static jtag_ring_desc dsk_sysbd_ring = {
101329949e86Sstevel 	2, dsk_sysbd_ring_components
101429949e86Sstevel };
101529949e86Sstevel 
101629949e86Sstevel /*
101729949e86Sstevel  * Ring descriptors for single and double buffered FFB boards.
101829949e86Sstevel  * Note - Only the FBC has a component ID register. None of the
101929949e86Sstevel  * other chips on the FFB board has one, so do not check them.
102029949e86Sstevel  */
102129949e86Sstevel static jtag_phys_comp ffb_sngl_ring_components[] = {
102229949e86Sstevel 	{ &chip_fbc,	20,	0,	5,	0 },	/* FBC */
102329949e86Sstevel 	{ &chip_3dram,	16,	16,	4,	1 },	/* 3DRAM */
102429949e86Sstevel 	{ &chip_3dram,	12,	20,	3,	2 },	/* 3DRAM */
102529949e86Sstevel 	{ &chip_3dram,	8,	24,	2,	3 },	/* 3DRAM */
102629949e86Sstevel 	{ &chip_3dram,	4,	28,	1,	4 },	/* 3DRAM */
102729949e86Sstevel 	{ &chip_bt498,	0,	32,	0,	5 },	/* RAMDAC */
102829949e86Sstevel };
102929949e86Sstevel 
103029949e86Sstevel static jtag_phys_comp ffb_dbl_ring_components[] = {
103129949e86Sstevel 	{ &chip_fbc,	84,	0,	17,	0 },	/* FBC */
103229949e86Sstevel 	{ &chip_lvt,	76,	16,	16,	1 },	/* LVT */
103329949e86Sstevel 	{ &chip_lvt,	68,	24,	15,	2 },	/* LVT */
103429949e86Sstevel 	{ &chip_lvt,	60,	32,	14,	3 },	/* LVT */
103529949e86Sstevel 	{ &chip_lvt,	52,	40,	13,	4 },	/* LVT */
103629949e86Sstevel 	{ &chip_3dram,	48,	48,	12,	5 },	/* 3DRAM */
103729949e86Sstevel 	{ &chip_3dram,	44,	52,	11,	6 },	/* 3DRAM */
103829949e86Sstevel 	{ &chip_3dram,	40,	56,	10,	7 },	/* 3DRAM */
103929949e86Sstevel 	{ &chip_3dram,	36,	60,	9,	8 },	/* 3DRAM */
104029949e86Sstevel 	{ &chip_3dram,	32,	64,	8,	9 },	/* 3DRAM */
104129949e86Sstevel 	{ &chip_3dram,	28,	68,	7,	10 },	/* 3DRAM */
104229949e86Sstevel 	{ &chip_3dram,	24,	72,	6,	11 },	/* 3DRAM */
104329949e86Sstevel 	{ &chip_3dram,	20,	76,	5,	12 },	/* 3DRAM */
104429949e86Sstevel 	{ &chip_3dram,	16,	80,	4,	13 },	/* 3DRAM */
104529949e86Sstevel 	{ &chip_3dram,	12,	84,	3,	14 },	/* 3DRAM */
104629949e86Sstevel 	{ &chip_3dram,	8,	88,	2,	15 },	/* 3DRAM */
104729949e86Sstevel 	{ &chip_3dram,	4,	92,	1,	16 },	/* 3DRAM */
104829949e86Sstevel 	{ &chip_bt498,	0,	96,	0,	17 },	/* RAMDAC */
104929949e86Sstevel };
105029949e86Sstevel 
105129949e86Sstevel static jtag_ring_desc ffb_sngl_ring = {
105229949e86Sstevel 	6, ffb_sngl_ring_components
105329949e86Sstevel };
105429949e86Sstevel 
105529949e86Sstevel static jtag_ring_desc ffb_dbl_ring = {
105629949e86Sstevel 	18, ffb_dbl_ring_components
105729949e86Sstevel };
105829949e86Sstevel 
105929949e86Sstevel /*
106029949e86Sstevel  *    Board descriptions
106129949e86Sstevel  */
106229949e86Sstevel 
106329949e86Sstevel static jtag_ring_desc *cpu_system_board[] = {
106429949e86Sstevel 	&cpu_sysbd_ring,		/* Ring 0 */
106529949e86Sstevel 	&cpu_mod_ring,			/* Ring 1 */
106629949e86Sstevel 	&cpu_mod_ring,			/* Ring 2 */
106729949e86Sstevel };
106829949e86Sstevel 
106929949e86Sstevel static jtag_ring_desc *io1_system_board[] = {
107029949e86Sstevel 	&io1_sysbd_ring,			/* Ring 0 */
107129949e86Sstevel 	(jtag_ring_desc *) NULL,		/* Ring 1 */
107229949e86Sstevel 	(jtag_ring_desc *) NULL,		/* Ring 2 */
107329949e86Sstevel };
107429949e86Sstevel 
107529949e86Sstevel static jtag_ring_desc *io1plus_system_board[] = {
107629949e86Sstevel 	&io1plus_sysbd_ring,			/* Ring 0 */
107729949e86Sstevel 	(jtag_ring_desc *) NULL,		/* Ring 1 */
107829949e86Sstevel 	(jtag_ring_desc *) NULL,		/* Ring 2 */
107929949e86Sstevel };
108029949e86Sstevel 
108129949e86Sstevel static jtag_ring_desc *io2_system_board[] = {
108229949e86Sstevel 	&io2_sysbd_ring,			/* Ring 0 */
108329949e86Sstevel 	(jtag_ring_desc *) NULL,		/* Ring 1 (ffb) */
108429949e86Sstevel 	(jtag_ring_desc *) NULL,		/* Ring 2  */
108529949e86Sstevel };
108629949e86Sstevel 
108729949e86Sstevel static jtag_ring_desc *io2plus_system_board[] = {
108829949e86Sstevel 	&io2plus_sysbd_ring,			/* Ring 0 */
108929949e86Sstevel 	(jtag_ring_desc *) NULL,		/* Ring 1 (ffb) */
109029949e86Sstevel 	(jtag_ring_desc *) NULL,		/* Ring 2  */
109129949e86Sstevel };
109229949e86Sstevel 
109329949e86Sstevel static jtag_ring_desc *io3_system_board[] = {
109429949e86Sstevel 	&io3_sysbd_ring,			/* Ring 0 */
109529949e86Sstevel 	(jtag_ring_desc *) NULL,		/* Ring 1 */
109629949e86Sstevel 	(jtag_ring_desc *) NULL,		/* Ring 2 */
109729949e86Sstevel };
109829949e86Sstevel 
109929949e86Sstevel static jtag_ring_desc *disk_system_board[] = {
110029949e86Sstevel 	&dsk_sysbd_ring,			/* Ring 0 */
110129949e86Sstevel 	(jtag_ring_desc *) NULL,		/* Ring 1 */
110229949e86Sstevel 	(jtag_ring_desc *) NULL,		/* Ring 2 */
110329949e86Sstevel };
110429949e86Sstevel 
110529949e86Sstevel /*
110629949e86Sstevel  * Function Definitions:
110729949e86Sstevel  * ---------------------
110829949e86Sstevel  */
110929949e86Sstevel 
111029949e86Sstevel /* For sunfire there will be a ring descriptor for each type of board */
111129949e86Sstevel static jtag_ring_desc *
get_ring_descriptor_bytype(int ring,enum board_type type)111229949e86Sstevel get_ring_descriptor_bytype(int ring, enum board_type type)
111329949e86Sstevel {
111429949e86Sstevel 
111529949e86Sstevel 	switch (type) {
111629949e86Sstevel 	case CPU_BOARD:
111729949e86Sstevel 		return (cpu_system_board[ring & 0xf]);
111829949e86Sstevel 
111929949e86Sstevel 	case IO_2SBUS_BOARD:
112029949e86Sstevel 		return (io1_system_board[ring & 0xf]);
112129949e86Sstevel 
112229949e86Sstevel 	case IO_2SBUS_SOCPLUS_BOARD:
112329949e86Sstevel 		return (io1plus_system_board[ring & 0xf]);
112429949e86Sstevel 
112529949e86Sstevel 	case IO_SBUS_FFB_BOARD:
112629949e86Sstevel 		return (io2_system_board[ring & 0xf]);
112729949e86Sstevel 
112829949e86Sstevel 	case IO_SBUS_FFB_SOCPLUS_BOARD:
112929949e86Sstevel 		return (io2plus_system_board[ring & 0xf]);
113029949e86Sstevel 
113129949e86Sstevel 	case IO_PCI_BOARD:
113229949e86Sstevel 		return (io3_system_board[ring & 0xf]);
113329949e86Sstevel 
113429949e86Sstevel 	case DISK_BOARD:
113529949e86Sstevel 		return (disk_system_board[ring & 0xf]);
113629949e86Sstevel 
113729949e86Sstevel 	default:
113829949e86Sstevel 		return (NULL);
113929949e86Sstevel 	}
114029949e86Sstevel }
114129949e86Sstevel 
114229949e86Sstevel static void
jtag_check_plus_board(volatile u_int * jreg,jtag_ring ring,jtag_phys_comp * comp,sysc_cfga_stat_t * sc)114329949e86Sstevel jtag_check_plus_board(
114429949e86Sstevel 	volatile u_int *jreg,
114529949e86Sstevel 	jtag_ring ring,
114629949e86Sstevel 	jtag_phys_comp *comp,
114729949e86Sstevel 	sysc_cfga_stat_t *sc)
114829949e86Sstevel {
114929949e86Sstevel 	struct fhc_regs fhc_data;
115029949e86Sstevel 
115129949e86Sstevel 	/*
115229949e86Sstevel 	 * the FHC Board Status Register indicates whether
115329949e86Sstevel 	 * the board 100 Mhz capable or not.
115429949e86Sstevel 	 */
115529949e86Sstevel 	fhc_data.bsr = (u_int)0xffffffff;
115629949e86Sstevel 
115729949e86Sstevel 	if ((jtag_scanout_chip(jreg, ring, comp, (u_int *)&fhc_data) >= 0) &&
115829949e86Sstevel 	    (FHC_BSR_TO_BD(fhc_data.bsr) == sc->board) &&
115929949e86Sstevel 	    ISPLUSBRD(fhc_data.bsr))
116029949e86Sstevel 		sc->plus_board = 1;
116129949e86Sstevel }
116229949e86Sstevel 
116329949e86Sstevel /*
116429949e86Sstevel  * Returns (positive) board type if something detected, including
116529949e86Sstevel  * UNKNOWN_BOARD.
1166*c6a28d76SToomas Soome  * Returns EMPTY_BOARD if nothing there.
116729949e86Sstevel  */
116829949e86Sstevel enum board_type
jtag_get_board_type(volatile u_int * jreg,sysc_cfga_stat_t * sc)116929949e86Sstevel jtag_get_board_type(volatile u_int *jreg, sysc_cfga_stat_t *sc)
117029949e86Sstevel {
117129949e86Sstevel 	int len;
117229949e86Sstevel 	int ring;
117329949e86Sstevel 	int result;
117429949e86Sstevel 	int board;
117529949e86Sstevel 	int status;
117629949e86Sstevel 
117729949e86Sstevel 	/*
117829949e86Sstevel 	 * Select Board Ring 0 to scan. This contains the AC, FHC,
117929949e86Sstevel 	 * and DC ASICs
118029949e86Sstevel 	 */
118129949e86Sstevel 
118229949e86Sstevel 	/*
118329949e86Sstevel 	 * Ring number is JTAG Board (7:4) and ring number (3:0)
118429949e86Sstevel 	 */
118529949e86Sstevel 	board = sc->board;
118629949e86Sstevel 	ring = (board << 4) | 0;
118729949e86Sstevel 
118829949e86Sstevel 	if ((status = select_ring(jreg, ring, 1)) < 0) {
118929949e86Sstevel 		cmn_err(CE_WARN, "Select ring error %d\n", status);
119029949e86Sstevel 	}
119129949e86Sstevel 
119229949e86Sstevel 	len = jtag_ring_length(jreg, ring);
119329949e86Sstevel 	switch (len) {
119429949e86Sstevel 	case CPU_TYPE_LEN:
119529949e86Sstevel 		result = CPU_BOARD;
119629949e86Sstevel 
119729949e86Sstevel 		jtag_check_plus_board(jreg, ring,
119829949e86Sstevel 			&cpu_sysbd_ring_components[9], sc);
119929949e86Sstevel 
120029949e86Sstevel 		break;
120129949e86Sstevel 
120229949e86Sstevel 	case IO_TYPE1_LEN:
120329949e86Sstevel 		switch (jtag_ring_ir_length(jreg, ring)) {
120429949e86Sstevel 		case RING_BROKEN:
120529949e86Sstevel 			result = UNKNOWN_BOARD;
120629949e86Sstevel 			break;
120729949e86Sstevel 		case IO_TYPE4_LEN:
120829949e86Sstevel 			result = IO_2SBUS_SOCPLUS_BOARD;
120929949e86Sstevel 			jtag_check_plus_board(jreg, ring,
121029949e86Sstevel 			    &io1plus_sysbd_ring_components[9], sc);
121129949e86Sstevel 			break;
121229949e86Sstevel 		default:
121329949e86Sstevel 			result = IO_2SBUS_BOARD;
121429949e86Sstevel 			jtag_check_plus_board(jreg, ring,
121529949e86Sstevel 			    &io1_sysbd_ring_components[9], sc);
121629949e86Sstevel 			break;
121729949e86Sstevel 		}
121829949e86Sstevel 
121929949e86Sstevel 		break;
122029949e86Sstevel 
122129949e86Sstevel 	case IO_TYPE2_LEN:
122229949e86Sstevel 		switch (jtag_ring_ir_length(jreg, ring)) {
122329949e86Sstevel 		case RING_BROKEN:
122429949e86Sstevel 			result = UNKNOWN_BOARD;
122529949e86Sstevel 			break;
122629949e86Sstevel 		case IO_TYPE5_LEN:
122729949e86Sstevel 			result = IO_SBUS_FFB_SOCPLUS_BOARD;
122829949e86Sstevel 			jtag_check_plus_board(jreg, ring,
122929949e86Sstevel 			    &io2plus_sysbd_ring_components[9], sc);
123029949e86Sstevel 			break;
123129949e86Sstevel 		default:
123229949e86Sstevel 			result = IO_SBUS_FFB_BOARD;
123329949e86Sstevel 			jtag_check_plus_board(jreg, ring,
123429949e86Sstevel 			    &io2_sysbd_ring_components[9], sc);
123529949e86Sstevel 			break;
123629949e86Sstevel 		}
123729949e86Sstevel 
123829949e86Sstevel 		break;
123929949e86Sstevel 
124029949e86Sstevel 	case PCI_TYPE_LEN:
124129949e86Sstevel 		switch (jtag_ring_ir_length(jreg, ring)) {
124229949e86Sstevel 		case RING_BROKEN:
124329949e86Sstevel 			result = UNKNOWN_BOARD;
124429949e86Sstevel 			break;
124529949e86Sstevel 		case PCI_TYPEA_LEN:
124629949e86Sstevel 			result = IO_PCI_BOARD;
124729949e86Sstevel 			jtag_check_plus_board(jreg, ring,
124829949e86Sstevel 			    &io3_sysbd_ring_components[9], sc);
124929949e86Sstevel 			break;
125029949e86Sstevel 		case PCI_TYPEB_LEN:
125129949e86Sstevel 		default:
125229949e86Sstevel 			result = UNKNOWN_BOARD;
125329949e86Sstevel 			break;
125429949e86Sstevel 		}
125529949e86Sstevel 		break;
125629949e86Sstevel 
125729949e86Sstevel 	case DSK_TYPE_LEN:
125829949e86Sstevel 		result = DISK_BOARD;
125929949e86Sstevel 		break;
126029949e86Sstevel 
126129949e86Sstevel 	case RING_BROKEN:
1262*c6a28d76SToomas Soome 		result = EMPTY_BOARD;
126329949e86Sstevel 		break;
126429949e86Sstevel 
126529949e86Sstevel 	default:
126629949e86Sstevel 		result = UNKNOWN_BOARD;
126729949e86Sstevel 		break;
126829949e86Sstevel 	}
126929949e86Sstevel 
127029949e86Sstevel 	TAP_ISSUE_CMD(jreg, JTAG_TAP_RESET, status);
127129949e86Sstevel 
127229949e86Sstevel 	return (result);
127329949e86Sstevel }
127429949e86Sstevel 
127529949e86Sstevel #ifndef RFE_4174486
127629949e86Sstevel /*
127729949e86Sstevel  * Until the RFE is fully investigated the likelyhood is that the
127829949e86Sstevel  * CPU frequency may be incorrectly displayed. Coupled with the lack of
127929949e86Sstevel  * Ecache size information and no information at all unless the
128029949e86Sstevel  * CPU board is physically plugged in, the default is not to get any
128129949e86Sstevel  * CPU information.
128229949e86Sstevel  * This patchable flag is provided so that more testing can be done
128329949e86Sstevel  * without re-compilation.
128429949e86Sstevel  */
128529949e86Sstevel static int jtag_cpu_scan_enable = 0;
128629949e86Sstevel #endif /* RFE_4174486 */
128729949e86Sstevel 
128829949e86Sstevel int
jtag_get_board_info(volatile u_int * jreg,sysc_cfga_stat_t * sc)128929949e86Sstevel jtag_get_board_info(volatile u_int *jreg, sysc_cfga_stat_t *sc)
129029949e86Sstevel {
129129949e86Sstevel 	jtag_ring_desc *rd;
129229949e86Sstevel 	jtag_phys_comp *rc;
129329949e86Sstevel 	int status;
129429949e86Sstevel 	int ring;
129529949e86Sstevel 	int len;
129629949e86Sstevel 	int i;
129729949e86Sstevel 	struct cpu_info *cpu;
129829949e86Sstevel 	struct bct_fields bct_data;
129929949e86Sstevel 
130029949e86Sstevel 	/* fill in the board info structure */
130129949e86Sstevel 
130229949e86Sstevel 	ring = sc->board << 4;
130329949e86Sstevel 
130429949e86Sstevel 	if ((status = select_ring(jreg, ring, 1)) < 0) {
130529949e86Sstevel 		return (status);
130629949e86Sstevel 	}
130729949e86Sstevel 
130829949e86Sstevel 	rd = get_ring_descriptor_bytype(ring, sc->type);
130929949e86Sstevel 
131029949e86Sstevel 	if (rd == NULL) {
131129949e86Sstevel 		return (JTAG_FAIL);
131229949e86Sstevel 	}
131329949e86Sstevel 
131429949e86Sstevel 	/* scan in the generic data common to all board types. */
131529949e86Sstevel 
131629949e86Sstevel 	/* get the AC component ID */
131729949e86Sstevel 	rc = find_chip(rd, &chip_ac, 0);
131829949e86Sstevel 	if (rc != NULL) {
131929949e86Sstevel 		sc->ac_compid = jtag_get_comp_id(jreg, rc);
132029949e86Sstevel 	}
132129949e86Sstevel 
132229949e86Sstevel 	/* get the FHC component ID */
132329949e86Sstevel 	rc = find_chip(rd, &chip_fhc, 0);
132429949e86Sstevel 	if (rc != NULL) {
132529949e86Sstevel 		sc->fhc_compid = jtag_get_comp_id(jreg, rc);
132629949e86Sstevel 	}
132729949e86Sstevel 
132829949e86Sstevel 	/* Now scan the board type dependent components */
132929949e86Sstevel 	switch (sc->type) {
133029949e86Sstevel 	case CPU_BOARD:
133129949e86Sstevel 		/*
133229949e86Sstevel 		 * first determine the cache size of each module, then
133329949e86Sstevel 		 * use that ring descriptor.
133429949e86Sstevel 		 */
133529949e86Sstevel 
133629949e86Sstevel 		for (i = 0, cpu = &sc->bd.cpu[i]; i < 2; i++, cpu++) {
133729949e86Sstevel 			bzero(cpu, sizeof (*cpu));
133829949e86Sstevel #ifndef RFE_4174486
133929949e86Sstevel 			if (!jtag_cpu_scan_enable)
134029949e86Sstevel 				continue;
134129949e86Sstevel #endif /* RFE_4174486 */
134229949e86Sstevel 			if (select_ring(jreg, ring | (i + 1), 1) < 0) {
134329949e86Sstevel 				continue;
134429949e86Sstevel 			}
134529949e86Sstevel 
134629949e86Sstevel 			len = jtag_ring_length(jreg, ring | (i + 1));
134729949e86Sstevel 
134829949e86Sstevel 			switch (len) {
134929949e86Sstevel 			case CPU_0_5_LEN:
135029949e86Sstevel 				rd = &cpu_mod_ring;
135129949e86Sstevel 				cpu->cpu_detected = 1;
135229949e86Sstevel 				break;
135329949e86Sstevel 
135429949e86Sstevel 			case CPU_1_0_LEN:
135529949e86Sstevel 				rd = &cpu_mod_1m_ring;
135629949e86Sstevel 				cpu->cpu_detected = 1;
135729949e86Sstevel 				break;
135829949e86Sstevel 
135929949e86Sstevel 			case RING_BROKEN:
136029949e86Sstevel 			default:
136129949e86Sstevel 				rd = NULL;
136229949e86Sstevel 				break;
136329949e86Sstevel 			}
136429949e86Sstevel 
136529949e86Sstevel 			if (!cpu->cpu_detected)
136629949e86Sstevel 				continue;
136729949e86Sstevel 
136829949e86Sstevel 			if (rd != NULL) {
136929949e86Sstevel 				rc = find_chip(rd, &chip_spitfire, 0);
137029949e86Sstevel 				if (rc != NULL) {
137129949e86Sstevel 					cpu->cpu_compid =
137229949e86Sstevel 						jtag_get_comp_id(jreg, rc);
137329949e86Sstevel 				}
137429949e86Sstevel 
137529949e86Sstevel 				/*
137629949e86Sstevel 				 * Do not get the component ID from the
137729949e86Sstevel 				 * first E$ chip. This is the tag chip
137829949e86Sstevel 				 * and does not help determine cache size.
137929949e86Sstevel 				 */
138029949e86Sstevel 				rc = find_chip(rd, &chip_ec, 1);
138129949e86Sstevel 				if (rc != NULL) {
138229949e86Sstevel 					cpu->ec_compid =
138329949e86Sstevel 						jtag_get_comp_id(jreg, rc);
138429949e86Sstevel 				}
138529949e86Sstevel 
138629949e86Sstevel 				rc = find_chip(rd, &chip_sdb, 0);
138729949e86Sstevel 				if (rc != NULL) {
138829949e86Sstevel 					cpu->sdb0_compid =
138929949e86Sstevel 						jtag_get_comp_id(jreg, rc);
139029949e86Sstevel 				}
139129949e86Sstevel 
139229949e86Sstevel 				rc = find_chip(rd, &chip_sdb, 1);
139329949e86Sstevel 				if (rc != NULL) {
139429949e86Sstevel 					cpu->sdb1_compid =
139529949e86Sstevel 						jtag_get_comp_id(jreg, rc);
139629949e86Sstevel 				}
139729949e86Sstevel 			}
139829949e86Sstevel 
139929949e86Sstevel #ifdef RFE_4174486
140029949e86Sstevel 			/* Work out Ecache size. */
140129949e86Sstevel 			switch (len) {
140229949e86Sstevel 			case CPU_0_5_LEN:
140329949e86Sstevel 				cpu->cache_size = 0x80000;
140429949e86Sstevel 				break;
140529949e86Sstevel 
140629949e86Sstevel 			case CPU_1_0_LEN:
140729949e86Sstevel 				/* default cache size for 9 SRAM chips */
140829949e86Sstevel 				cpu->cache_size = 0x100000;
140929949e86Sstevel 				break;
141029949e86Sstevel 
141129949e86Sstevel 			default:
141229949e86Sstevel 				break;
141329949e86Sstevel 			}
141429949e86Sstevel #endif /* RFE_4174486 */
141529949e86Sstevel 		}
141629949e86Sstevel 
141729949e86Sstevel 		break;
141829949e86Sstevel 
141929949e86Sstevel 	case IO_2SBUS_BOARD:
142029949e86Sstevel 		rc = find_chip(rd, &chip_sio, 0);
142129949e86Sstevel 		if (rc != NULL) {
142229949e86Sstevel 			sc->bd.io1.sio0_compid =
142329949e86Sstevel 				jtag_get_comp_id(jreg, rc);
142429949e86Sstevel 		}
142529949e86Sstevel 
142629949e86Sstevel 		rc = find_chip(rd, &chip_sio, 1);
142729949e86Sstevel 		if (rc != NULL) {
142829949e86Sstevel 			sc->bd.io1.sio1_compid =
142929949e86Sstevel 				jtag_get_comp_id(jreg, rc);
143029949e86Sstevel 		}
143129949e86Sstevel 
143229949e86Sstevel 		rc = find_chip(rd, &chip_hm, 0);
143329949e86Sstevel 		if (rc != NULL) {
143429949e86Sstevel 			sc->bd.io1.hme_compid = jtag_get_comp_id(jreg, rc);
143529949e86Sstevel 		}
143629949e86Sstevel 
143729949e86Sstevel 		rc = find_chip(rd, &chip_soc, 0);
143829949e86Sstevel 		if (rc != NULL) {
143929949e86Sstevel 			sc->bd.io1.soc_compid = jtag_get_comp_id(jreg, rc);
144029949e86Sstevel 		}
144129949e86Sstevel 
144229949e86Sstevel 		break;
144329949e86Sstevel 
144429949e86Sstevel 	case IO_2SBUS_SOCPLUS_BOARD:
144529949e86Sstevel 		rc = find_chip(rd, &chip_sio, 0);
144629949e86Sstevel 		if (rc != NULL) {
144729949e86Sstevel 			sc->bd.io1.sio0_compid =
144829949e86Sstevel 				jtag_get_comp_id(jreg, rc);
144929949e86Sstevel 		}
145029949e86Sstevel 
145129949e86Sstevel 		rc = find_chip(rd, &chip_sio, 1);
145229949e86Sstevel 		if (rc != NULL) {
145329949e86Sstevel 			sc->bd.io1.sio1_compid =
145429949e86Sstevel 				jtag_get_comp_id(jreg, rc);
145529949e86Sstevel 		}
145629949e86Sstevel 
145729949e86Sstevel 		rc = find_chip(rd, &chip_hm, 0);
145829949e86Sstevel 		if (rc != NULL) {
145929949e86Sstevel 			sc->bd.io1.hme_compid = jtag_get_comp_id(jreg, rc);
146029949e86Sstevel 		}
146129949e86Sstevel 
146229949e86Sstevel 		rc = find_chip(rd, &chip_socplus, 0);
146329949e86Sstevel 		if (rc != NULL) {
146429949e86Sstevel 			sc->bd.io1plus.socplus_compid =
146529949e86Sstevel 					jtag_get_comp_id(jreg, rc);
146629949e86Sstevel 		}
146729949e86Sstevel 
146829949e86Sstevel 		break;
146929949e86Sstevel 
147029949e86Sstevel 	case IO_SBUS_FFB_BOARD:
147129949e86Sstevel 		rc = find_chip(rd, &chip_sio, 0);
147229949e86Sstevel 		if (rc != NULL) {
147329949e86Sstevel 			sc->bd.io2.sio1_compid = jtag_get_comp_id(jreg, rc);
147429949e86Sstevel 		}
147529949e86Sstevel 
147629949e86Sstevel 		rc = find_chip(rd, &chip_hm, 0);
147729949e86Sstevel 		if (rc != NULL) {
147829949e86Sstevel 			sc->bd.io2.hme_compid = jtag_get_comp_id(jreg, rc);
147929949e86Sstevel 		}
148029949e86Sstevel 
148129949e86Sstevel 		rc = find_chip(rd, &chip_soc, 0);
148229949e86Sstevel 		if (rc != NULL) {
148329949e86Sstevel 			sc->bd.io2.soc_compid = jtag_get_comp_id(jreg, rc);
148429949e86Sstevel 		}
148529949e86Sstevel 
148629949e86Sstevel 		/* Now scan for an FFB board */
148729949e86Sstevel 		if (select_ring(jreg, ring | 1, 1) < 0) {
148829949e86Sstevel 			len = RING_BROKEN;
148929949e86Sstevel 		} else {
149029949e86Sstevel 			len = jtag_ring_length(jreg, ring | 1);
149129949e86Sstevel 		}
149229949e86Sstevel 
149329949e86Sstevel 		switch (len) {
149429949e86Sstevel 		case FFB_SNG_LEN:
149529949e86Sstevel 			rd = &ffb_sngl_ring;
149629949e86Sstevel 			sc->bd.io2.ffb_size = FFB_SINGLE;
149729949e86Sstevel 			break;
149829949e86Sstevel 
149929949e86Sstevel 		case FFB_DBL_LEN:
150029949e86Sstevel 			rd = &ffb_dbl_ring;
150129949e86Sstevel 			sc->bd.io2.ffb_size = FFB_DOUBLE;
150229949e86Sstevel 			break;
150329949e86Sstevel 
150429949e86Sstevel 		case RING_BROKEN:
150529949e86Sstevel 			rd = NULL;
150629949e86Sstevel 			sc->bd.io2.ffb_size = FFB_NOT_FOUND;
150729949e86Sstevel 			break;
150829949e86Sstevel 
150929949e86Sstevel 		default:
151029949e86Sstevel 			rd = NULL;
151129949e86Sstevel 			sc->bd.io2.ffb_size = FFB_FAILED;
151229949e86Sstevel 			break;
151329949e86Sstevel 		}
151429949e86Sstevel 
151529949e86Sstevel 		/* Now scan out the FBC component ID */
151629949e86Sstevel 		if (rd != NULL) {
151729949e86Sstevel 			rc = find_chip(rd, &chip_fbc, 0);
151829949e86Sstevel 		}
151929949e86Sstevel 
152029949e86Sstevel 		if (rc != NULL) {
152129949e86Sstevel 			sc->bd.io2.fbc_compid = jtag_get_comp_id(jreg, rc);
152229949e86Sstevel 		}
152329949e86Sstevel 		break;
152429949e86Sstevel 
152529949e86Sstevel 	case IO_SBUS_FFB_SOCPLUS_BOARD:
152629949e86Sstevel 		rc = find_chip(rd, &chip_sio, 0);
152729949e86Sstevel 		if (rc != NULL) {
152829949e86Sstevel 			sc->bd.io2.sio1_compid = jtag_get_comp_id(jreg, rc);
152929949e86Sstevel 		}
153029949e86Sstevel 
153129949e86Sstevel 		rc = find_chip(rd, &chip_hm, 0);
153229949e86Sstevel 		if (rc != NULL) {
153329949e86Sstevel 			sc->bd.io2.hme_compid = jtag_get_comp_id(jreg, rc);
153429949e86Sstevel 		}
153529949e86Sstevel 
153629949e86Sstevel 		rc = find_chip(rd, &chip_socplus, 0);
153729949e86Sstevel 		if (rc != NULL) {
153829949e86Sstevel 			sc->bd.io2plus.socplus_compid =
153929949e86Sstevel 				jtag_get_comp_id(jreg, rc);
154029949e86Sstevel 		}
154129949e86Sstevel 
154229949e86Sstevel 		/* Now scan for an FFB board */
154329949e86Sstevel 		if (select_ring(jreg, ring | 1, 1) < 0) {
154429949e86Sstevel 			len = RING_BROKEN;
154529949e86Sstevel 		} else {
154629949e86Sstevel 			len = jtag_ring_length(jreg, ring | 1);
154729949e86Sstevel 		}
154829949e86Sstevel 
154929949e86Sstevel 		switch (len) {
155029949e86Sstevel 		case FFB_SNG_LEN:
155129949e86Sstevel 			rd = &ffb_sngl_ring;
155229949e86Sstevel 			sc->bd.io2.ffb_size = FFB_SINGLE;
155329949e86Sstevel 			break;
155429949e86Sstevel 
155529949e86Sstevel 		case FFB_DBL_LEN:
155629949e86Sstevel 			rd = &ffb_dbl_ring;
155729949e86Sstevel 			sc->bd.io2.ffb_size = FFB_DOUBLE;
155829949e86Sstevel 			break;
155929949e86Sstevel 
156029949e86Sstevel 		case RING_BROKEN:
156129949e86Sstevel 			rd = NULL;
156229949e86Sstevel 			sc->bd.io2.ffb_size = FFB_NOT_FOUND;
156329949e86Sstevel 			break;
156429949e86Sstevel 
156529949e86Sstevel 		default:
156629949e86Sstevel 			rd = NULL;
156729949e86Sstevel 			sc->bd.io2.ffb_size = FFB_FAILED;
156829949e86Sstevel 			break;
156929949e86Sstevel 		}
157029949e86Sstevel 
157129949e86Sstevel 		/* Now scan out the FBC component ID */
157229949e86Sstevel 		if (rd != NULL) {
157329949e86Sstevel 			rc = find_chip(rd, &chip_fbc, 0);
157429949e86Sstevel 		}
157529949e86Sstevel 
157629949e86Sstevel 		if (rc != NULL) {
157729949e86Sstevel 			sc->bd.io2.fbc_compid = jtag_get_comp_id(jreg, rc);
157829949e86Sstevel 		}
157929949e86Sstevel 		break;
158029949e86Sstevel 
158129949e86Sstevel 	case IO_PCI_BOARD:
158229949e86Sstevel 		rc = find_chip(rd, &chip_psyo, 0);
158329949e86Sstevel 		if (rc != NULL) {
158429949e86Sstevel 			sc->bd.io3.psyo0_compid =
158529949e86Sstevel 				jtag_get_comp_id(jreg, rc);
158629949e86Sstevel 		}
158729949e86Sstevel 
158829949e86Sstevel 		rc = find_chip(rd, &chip_psyo, 1);
158929949e86Sstevel 		if (rc != NULL) {
159029949e86Sstevel 			sc->bd.io3.psyo1_compid =
159129949e86Sstevel 				jtag_get_comp_id(jreg, rc);
159229949e86Sstevel 		}
159329949e86Sstevel 
159429949e86Sstevel 		rc = find_chip(rd, &chip_cheo, 0);
159529949e86Sstevel 		if (rc != NULL) {
159629949e86Sstevel 			sc->bd.io3.cheo_compid = jtag_get_comp_id(jreg, rc);
159729949e86Sstevel 		}
159829949e86Sstevel 
159929949e86Sstevel 		break;
160029949e86Sstevel 
160129949e86Sstevel 	case DISK_BOARD:
160229949e86Sstevel 		/*
160329949e86Sstevel 		 * Scan the BCT8244 to get the disk drive info out of
160429949e86Sstevel 		 * the chip.
160529949e86Sstevel 		 */
160629949e86Sstevel 		if (jtag_scanout_chip(jreg, ring,
160729949e86Sstevel 		    &dsk_sysbd_ring_components[0], (u_int *)&bct_data) < 0) {
160829949e86Sstevel 			TAP_ISSUE_CMD(jreg, JTAG_TAP_RESET, status);
160929949e86Sstevel 			return (-1);
161029949e86Sstevel 		}
161129949e86Sstevel 
161229949e86Sstevel 		if ((bct_data.disk0_pres && 0x1) == 0) {
161329949e86Sstevel 			sc->bd.dsk.disk_pres[0] = 1;
161429949e86Sstevel 			sc->bd.dsk.disk_id[0] = 0xf & ~bct_data.disk0_id;
161529949e86Sstevel 		} else {
161629949e86Sstevel 			sc->bd.dsk.disk_pres[0] = 0;
161729949e86Sstevel 		}
161829949e86Sstevel 
161929949e86Sstevel 		if ((bct_data.disk1_pres && 0x1) == 0) {
162029949e86Sstevel 			sc->bd.dsk.disk_pres[1] = 1;
162129949e86Sstevel 			sc->bd.dsk.disk_id[1] = 0xf & ~bct_data.disk1_id;
162229949e86Sstevel 		} else {
162329949e86Sstevel 			sc->bd.dsk.disk_pres[1] = 0;
162429949e86Sstevel 		}
162529949e86Sstevel 
162629949e86Sstevel 		break;
162729949e86Sstevel 
162829949e86Sstevel 	default:
162929949e86Sstevel 		break;
163029949e86Sstevel 	}
163129949e86Sstevel 
163229949e86Sstevel 	return (JTAG_OK);
163329949e86Sstevel }
163429949e86Sstevel 
163529949e86Sstevel static jtag_phys_comp *
find_chip(jtag_ring_desc * rd,jtag_log_comp * chip,int instance)163629949e86Sstevel find_chip(jtag_ring_desc *rd, jtag_log_comp *chip, int instance)
163729949e86Sstevel {
163829949e86Sstevel 	int i;
163929949e86Sstevel 	int found = 0;
164029949e86Sstevel 	jtag_phys_comp *rc;
164129949e86Sstevel 
164229949e86Sstevel 	for (i = rd->size, rc = rd->components; i != 0; rc++, i--) {
164329949e86Sstevel 		if (rc->chip == chip) {
164429949e86Sstevel 			if (found == instance) {
164529949e86Sstevel 				return (rc);
164629949e86Sstevel 			} else {
164729949e86Sstevel 				found++;
164829949e86Sstevel 			}
164929949e86Sstevel 		}
165029949e86Sstevel 	}
165129949e86Sstevel 	return (NULL);
165229949e86Sstevel }
165329949e86Sstevel 
165429949e86Sstevel /*
165529949e86Sstevel  * Function jtag_error() :
165629949e86Sstevel  *
165729949e86Sstevel  *	This function centrailizes the use of the JTAG error strings.
165829949e86Sstevel  * It should be called with the JTAG error code anytime the programmer
165929949e86Sstevel  * wants to print the type of JTAG error encountered. Just call with the
166029949e86Sstevel  * error code returned by the JTAG function. If no error occurred, nothing
166129949e86Sstevel  * is printed.
166229949e86Sstevel  */
166329949e86Sstevel static void
jtag_error_print(int ring,jtag_error code)166429949e86Sstevel jtag_error_print(int ring, jtag_error code)
166529949e86Sstevel {
166629949e86Sstevel 	char *ring_str = "System Board";
166729949e86Sstevel 
166829949e86Sstevel 	switch (code) {
166929949e86Sstevel 	case JTAG_OK :
167029949e86Sstevel 		break;
167129949e86Sstevel 
167229949e86Sstevel 	case TAP_TIMEOUT :
167329949e86Sstevel 		cmn_err(CE_WARN, "%s : TAP controller timeout\n", jtag_err);
167429949e86Sstevel 		break;
167529949e86Sstevel 
167629949e86Sstevel 	case BAD_ARGS :
167729949e86Sstevel 		cmn_err(CE_WARN,
167829949e86Sstevel 			"%s : routine reports bad args: Board %d, %s Ring\n",
167929949e86Sstevel 			jtag_err, ring >> 4, ring_str);
168029949e86Sstevel 		break;
168129949e86Sstevel 
168229949e86Sstevel 	case BAD_CID :
168329949e86Sstevel 		cmn_err(CE_WARN,
168429949e86Sstevel 			"%s : Bad component ID detected: Board %d, %s Ring\n",
168529949e86Sstevel 			jtag_err, ring >> 4, ring_str);
168629949e86Sstevel 		break;
168729949e86Sstevel 
168829949e86Sstevel 	case RING_BROKEN :
168929949e86Sstevel 		cmn_err(CE_WARN, "%s : ring broken: Board %d, %s Ring\n",
169029949e86Sstevel 			jtag_err, ring >> 4, ring_str);
169129949e86Sstevel 		break;
169229949e86Sstevel 
169329949e86Sstevel 	case INIT_MISMATCH:
169429949e86Sstevel 		cmn_err(CE_WARN,
169529949e86Sstevel 			"%s : State after init not expected: Board %d, "
169629949e86Sstevel 			"%s Ring\n", jtag_err, ring >> 4, ring_str);
169729949e86Sstevel 		break;
169829949e86Sstevel 
169929949e86Sstevel 	case LENGTH_MISMATCH :
170029949e86Sstevel 		cmn_err(CE_WARN,
170129949e86Sstevel 			"%s : Scan Chain Length mismatch: Board %d,"
170229949e86Sstevel 			" %s Ring\n",
170329949e86Sstevel 			jtag_err, ring >> 4, ring_str);
170429949e86Sstevel 		break;
170529949e86Sstevel 
170629949e86Sstevel 	}	/* end of switch on code */
170729949e86Sstevel }	/* end of jtag_error_print() */
170829949e86Sstevel 
170929949e86Sstevel 
171029949e86Sstevel static int
jtag_get_comp_id(volatile u_int * jreg,jtag_phys_comp * comp)171129949e86Sstevel jtag_get_comp_id(volatile u_int *jreg, jtag_phys_comp *comp)
171229949e86Sstevel {
171329949e86Sstevel 	u_char b[4];
171429949e86Sstevel 	u_int id;
171529949e86Sstevel 	int status;
171629949e86Sstevel 
171729949e86Sstevel 	status = jtag_single_IR_DR(jreg, comp, comp->chip->id_code,
171829949e86Sstevel 		b, 32, b);
171929949e86Sstevel 
172029949e86Sstevel 	/* Reorder the bytes of the ID read out */
172129949e86Sstevel 	id = b[0] | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
172229949e86Sstevel 
172329949e86Sstevel 	if (status < 0) {
172429949e86Sstevel 		return (0);
172529949e86Sstevel 	} else {
172629949e86Sstevel 		return (id);
172729949e86Sstevel 	}
172829949e86Sstevel }
172929949e86Sstevel 
173029949e86Sstevel /*
173129949e86Sstevel  *    Bit-manipulation routines
173229949e86Sstevel  */
173329949e86Sstevel 
173429949e86Sstevel /*
173529949e86Sstevel  * jtag_bf_extract()
173629949e86Sstevel  *
173729949e86Sstevel  * This routine extracts bit strings from JTAG data scanout strings. This
173829949e86Sstevel  * routine is used to decode data scanned out of chips via JTAG.
173929949e86Sstevel  */
174029949e86Sstevel static u_int
jtag_bf_extract(u_char * s,int lsb,int msb)174129949e86Sstevel jtag_bf_extract(u_char *s, int lsb, int msb)
174229949e86Sstevel {
174329949e86Sstevel 	u_int result = 0;
174429949e86Sstevel 
174529949e86Sstevel 	ASSERT(s);
174629949e86Sstevel 
174729949e86Sstevel 	/*
174829949e86Sstevel 	 * lsb and msb are assumed to be within string,
174929949e86Sstevel 	 * and to span 32 bits at most
175029949e86Sstevel 	 */
175129949e86Sstevel 	for (; msb >= lsb; msb--) {
175229949e86Sstevel 		result = (result << 1) | ((s[msb>>3] >> (msb & 7)) & 1);
175329949e86Sstevel 	}
175429949e86Sstevel 	return (result);
175529949e86Sstevel }
175629949e86Sstevel 
175729949e86Sstevel /*
175829949e86Sstevel  * jtag_bf_insert()
175929949e86Sstevel  *
176029949e86Sstevel  * This routine is used to build bit strings for scanning into the
176129949e86Sstevel  * shadow chains of ASICs.
176229949e86Sstevel  */
176329949e86Sstevel static void
jtag_bf_insert(u_char * s,int lsb,int msb,int value)176429949e86Sstevel jtag_bf_insert(u_char *s, int lsb, int msb, int value)
176529949e86Sstevel {
176629949e86Sstevel 	ASSERT(s);
176729949e86Sstevel 
176829949e86Sstevel 	/*
176929949e86Sstevel 	 * lsb and msb are assumed to be within string,
177029949e86Sstevel 	 * and to span 32 bits at most
177129949e86Sstevel 	 */
177229949e86Sstevel 
177329949e86Sstevel 	for (; msb >= lsb; lsb++) {
177429949e86Sstevel 		s[lsb>>3] = (s[lsb>>3] & ~ (1 << (lsb & 7))) |
177529949e86Sstevel 			((value & 1) << (lsb & 7));
177629949e86Sstevel 		value = value >> 1;
177729949e86Sstevel 	}
177829949e86Sstevel }
177929949e86Sstevel 
178029949e86Sstevel /*
178129949e86Sstevel  *
178229949e86Sstevel  */
178329949e86Sstevel static void
jtag_bf_zero(u_char * s,int nbits)178429949e86Sstevel jtag_bf_zero(u_char *s, int nbits)
178529949e86Sstevel {
178629949e86Sstevel 	int nbytes = (nbits+7)>>3;
178729949e86Sstevel 
178829949e86Sstevel 	while (nbytes-- != 0) {
178929949e86Sstevel 		*s++ = 0;
179029949e86Sstevel 	}
179129949e86Sstevel }
179229949e86Sstevel 
179329949e86Sstevel /*
179429949e86Sstevel  * Return 0 if equal, != 0 else
179529949e86Sstevel  */
179629949e86Sstevel static int
jtag_bf_cmp(u_char * s1,u_char * s2,int nbits)179729949e86Sstevel jtag_bf_cmp(u_char *s1, u_char *s2, int nbits)
179829949e86Sstevel {
179929949e86Sstevel 	int mask;
180029949e86Sstevel 	for (nbits -= 8; nbits > 0; nbits -= 8) {
180129949e86Sstevel 		if (*s1++ != *s2++) {
180229949e86Sstevel 			return (-1);
180329949e86Sstevel 		}
180429949e86Sstevel 		mask = 0xFF >> (-nbits);
180529949e86Sstevel 		if ((*s1++ & mask) != (*s2++ & mask)) {
180629949e86Sstevel 			return (-1);
180729949e86Sstevel 		}
180829949e86Sstevel 	}
180929949e86Sstevel 
181029949e86Sstevel 	return (0);
181129949e86Sstevel }
181229949e86Sstevel 
181329949e86Sstevel 
181429949e86Sstevel /*
181529949e86Sstevel  * Generic chip-level top routines
181629949e86Sstevel  */
181729949e86Sstevel static int
jtag_init_chip(volatile u_int * jreg,jtag_ring ring,jtag_phys_comp * component,const u_int * pval,u_char scan_out[32])181829949e86Sstevel jtag_init_chip(
181929949e86Sstevel 	volatile u_int *jreg,
182029949e86Sstevel 	jtag_ring ring,
182129949e86Sstevel 	jtag_phys_comp *component,
182229949e86Sstevel 	const u_int *pval,
182329949e86Sstevel 	u_char scan_out[32])
182429949e86Sstevel {
182529949e86Sstevel 	int status;
182629949e86Sstevel 	jtag_log_comp *chip;
182729949e86Sstevel 	u_char scan_in[32];
182829949e86Sstevel 	u_char *pdesc;
182929949e86Sstevel 
183029949e86Sstevel 	status = select_ring(jreg, ring, 1);
183129949e86Sstevel 	if (status < 0) {
183229949e86Sstevel 		return (status);
183329949e86Sstevel 	}
183429949e86Sstevel 
183529949e86Sstevel 	pval = pval - 1; /* adjust pval since indices start at 1 */
183629949e86Sstevel 	chip = component->chip;
183729949e86Sstevel 	pdesc = chip->init_pdesc;
183829949e86Sstevel 
183929949e86Sstevel 	/* Zero out the scan-in area */
184029949e86Sstevel 	jtag_bf_zero(scan_in, 8*32);
184129949e86Sstevel 	jtag_bf_zero(scan_out, 8*32);
184229949e86Sstevel 
184329949e86Sstevel 	for (;;) {
184429949e86Sstevel 		u_int flags, lsb, msb, patch;
184529949e86Sstevel 		flags = *pdesc++;
184629949e86Sstevel 		if ((flags & JTIN_INSERT) != 0) {
184729949e86Sstevel 			lsb = *pdesc++;
184829949e86Sstevel 			msb = *pdesc++;
184929949e86Sstevel 			if ((flags & JTIN_INDEX) != 0) {
185029949e86Sstevel 				patch = pval[flags & JTIN_INDEX];
185129949e86Sstevel 			} else {
185229949e86Sstevel 				patch = *pdesc++;
185329949e86Sstevel 			}
185429949e86Sstevel 			jtag_bf_insert(scan_in, lsb, msb, patch);
185529949e86Sstevel 		}
185629949e86Sstevel 
185729949e86Sstevel 		if ((flags & JTIN_UPDATE) != 0) {
185829949e86Sstevel 			status = jtag_single_IR_DR(jreg, component,
185929949e86Sstevel 				chip->init_code, scan_in, chip->dr_len,
186029949e86Sstevel 				scan_out);
186129949e86Sstevel 
186229949e86Sstevel 			if (status < 0) {
186329949e86Sstevel 				return (status);
186429949e86Sstevel 			}
186529949e86Sstevel 
186629949e86Sstevel 			if ((status = select_ring(jreg, ring, 1)) < 0) {
186729949e86Sstevel 				return (status);
186829949e86Sstevel 			}
186929949e86Sstevel 		}
187029949e86Sstevel 
187129949e86Sstevel 		if ((flags & JTIN_COMPARE) != 0) {
187229949e86Sstevel 			if (jtag_bf_cmp(scan_in, scan_out, chip->dr_len) != 0)
187329949e86Sstevel 				return (INIT_MISMATCH);
187429949e86Sstevel 		}
187529949e86Sstevel 
187629949e86Sstevel 		if ((flags & JTIN_END) != 0) {
187729949e86Sstevel 			break;
187829949e86Sstevel 		}
187929949e86Sstevel 	}
188029949e86Sstevel 
188129949e86Sstevel 	return (JTAG_OK);    /* all is OK... */
188229949e86Sstevel }
188329949e86Sstevel 
188429949e86Sstevel /*
188529949e86Sstevel  * Dump the info from a chip.
188629949e86Sstevel  * Return the number of bytes used, or <0 if failed
188729949e86Sstevel  */
188829949e86Sstevel static int
jtag_scanout_chip(volatile u_int * jreg,jtag_ring ring,jtag_phys_comp * component,u_int * result)188929949e86Sstevel jtag_scanout_chip(
189029949e86Sstevel 	volatile u_int *jreg,
189129949e86Sstevel 	jtag_ring ring,
189229949e86Sstevel 	jtag_phys_comp *component,
189329949e86Sstevel 	u_int *result)
189429949e86Sstevel {
189529949e86Sstevel 	int status;
189629949e86Sstevel 	jtag_log_comp *chip;
189729949e86Sstevel 	u_char scan_in[32];
189829949e86Sstevel 	u_char scan_out[32];
189929949e86Sstevel 	u_char *p;
190029949e86Sstevel 	u_int value;
190129949e86Sstevel 	int bytes_used = 0;
190229949e86Sstevel 
190329949e86Sstevel 	if ((status = select_ring(jreg, ring, 1)) < 0) {
190429949e86Sstevel 		return (status);
190529949e86Sstevel 	}
190629949e86Sstevel 
190729949e86Sstevel 	chip = component->chip;
190829949e86Sstevel 
190929949e86Sstevel 	p = chip->fmt_desc;
191029949e86Sstevel 	if (p == NULL) {
191129949e86Sstevel 		return (bytes_used);
191229949e86Sstevel 	}
191329949e86Sstevel 
191429949e86Sstevel 	status = jtag_rescan_IR_DR(jreg, component, chip->dump_code, scan_in,
191529949e86Sstevel 		chip->dr_len, scan_out);
191629949e86Sstevel 
191729949e86Sstevel 	if (status < 0) {
191829949e86Sstevel 		return (status);
191929949e86Sstevel 	}
192029949e86Sstevel 
192129949e86Sstevel 	if ((status = select_ring(jreg, ring, 1)) < 0) {
192229949e86Sstevel 		return (status);
192329949e86Sstevel 	}
192429949e86Sstevel 
192529949e86Sstevel 	for (value = 0; ; ) {
192629949e86Sstevel 		u_char cmd = *p++;
192729949e86Sstevel 
192829949e86Sstevel 		if ((cmd & JTSO_XTRACT) != 0) {
192929949e86Sstevel 			u_int lsb, msb;
193029949e86Sstevel 			lsb = *p++;
193129949e86Sstevel 			msb = *p++;
193229949e86Sstevel 			value |= jtag_bf_extract(scan_out, lsb, msb) <<
193329949e86Sstevel 				(cmd & JTSO_SHIFT);
193429949e86Sstevel 		}
193529949e86Sstevel 
193629949e86Sstevel 		if ((cmd & JTSO_ST) != 0) {
193729949e86Sstevel 			*result++ = value;
193829949e86Sstevel 			bytes_used += 4;
193929949e86Sstevel 			value = 0;
194029949e86Sstevel 		}
194129949e86Sstevel 
194229949e86Sstevel 		if ((cmd & JTSO_END) != 0) {
194329949e86Sstevel 			break;
194429949e86Sstevel 		}
194529949e86Sstevel 	}
194629949e86Sstevel 	return (bytes_used);
194729949e86Sstevel }
194829949e86Sstevel 
194929949e86Sstevel /*
195029949e86Sstevel  * Set the AC into hotplug mode upon insertion
195129949e86Sstevel  */
195229949e86Sstevel static int
jtag_init_ac(volatile u_int * jreg,int bid,enum board_type brdtype)195329949e86Sstevel jtag_init_ac(volatile u_int *jreg, int bid, enum board_type brdtype)
195429949e86Sstevel {
195529949e86Sstevel 	int rc = JTAG_OK;
195629949e86Sstevel 	int status;
195729949e86Sstevel 	int ring = (bid << 4);
195829949e86Sstevel 	ac_options ac_opt;
195929949e86Sstevel 	u_char scan_out[64];
196029949e86Sstevel 	uint_t cs_value;
196129949e86Sstevel 
196229949e86Sstevel 	if (brdtype == UNKNOWN_BOARD)
196329949e86Sstevel 		return (rc);
196429949e86Sstevel 
196529949e86Sstevel 	ac_opt.frozen = 0;	/* 0 = frozen */
196629949e86Sstevel 	ac_opt.reset_a = 1;
196729949e86Sstevel 	ac_opt.reset_b = 1;
196829949e86Sstevel 	ac_opt.board_id = bid;
196929949e86Sstevel 	ac_opt.mask_hwerr = (uint_t)-1;
197029949e86Sstevel 	ac_opt.node_id = 3;
197129949e86Sstevel 
197229949e86Sstevel 	/* Get a good AC BCSR value from the board we are running on. */
197329949e86Sstevel 	cs_value = ldphysio(AC_BCSR(FHC_CPU2BOARD(CPU->cpu_id)));
197429949e86Sstevel 
197529949e86Sstevel 	ac_opt.arb_fast = (cs_value & AC_ARB_FAST) ? 1 : 0;
197629949e86Sstevel 	ac_opt.pcr_hi = 0;
197729949e86Sstevel 	ac_opt.pcr_lo = 0x80000000LL - 0x9ac4  - (bid << 3);
197829949e86Sstevel 	ac_opt.pcc_ctl0 = 0x3f;
197929949e86Sstevel 	ac_opt.pcc_ctl1 = 0x3f;
198029949e86Sstevel 	ac_opt.pcc_tctrl = (1 << 11); /* TREN */
198129949e86Sstevel 
198229949e86Sstevel 	if ((brdtype == CPU_BOARD) || (brdtype == MEM_BOARD)) {
198329949e86Sstevel 		rc = jtag_init_chip(jreg, ring, &cpu_sysbd_ring_components[0],
198429949e86Sstevel 			(jtag_opt)&ac_opt, scan_out);
198529949e86Sstevel 	} else if (brdtype == IO_2SBUS_BOARD) {
198629949e86Sstevel 		rc = jtag_init_chip(jreg, ring, &io1_sysbd_ring_components[0],
198729949e86Sstevel 			(jtag_opt)&ac_opt, scan_out);
198829949e86Sstevel 	} else if (brdtype == IO_2SBUS_SOCPLUS_BOARD) {
198929949e86Sstevel 		rc = jtag_init_chip(jreg, ring,
199029949e86Sstevel 			&io1plus_sysbd_ring_components[0],
199129949e86Sstevel 			(jtag_opt)&ac_opt, scan_out);
199229949e86Sstevel 	} else if (brdtype == IO_SBUS_FFB_BOARD) {
199329949e86Sstevel 		rc = jtag_init_chip(jreg, ring, &io2_sysbd_ring_components[0],
199429949e86Sstevel 			(jtag_opt)&ac_opt, scan_out);
199529949e86Sstevel 	} else if (brdtype == IO_SBUS_FFB_SOCPLUS_BOARD) {
199629949e86Sstevel 		rc = jtag_init_chip(jreg, ring,
199729949e86Sstevel 			&io2plus_sysbd_ring_components[0],
199829949e86Sstevel 			(jtag_opt)&ac_opt, scan_out);
199929949e86Sstevel 	} else if (brdtype == IO_PCI_BOARD) {
200029949e86Sstevel 		rc = jtag_init_chip(jreg, ring, &io3_sysbd_ring_components[0],
200129949e86Sstevel 			(jtag_opt)&ac_opt, scan_out);
200229949e86Sstevel 	} else {
200329949e86Sstevel 		cmn_err(CE_NOTE, " jtag_init_ac() Board %d"
200429949e86Sstevel 		    " unsupported type %2X", bid, brdtype);
200529949e86Sstevel 	}
200629949e86Sstevel 
200729949e86Sstevel 	TAP_ISSUE_CMD(jreg, JTAG_TAP_RESET, status);
200829949e86Sstevel 
200929949e86Sstevel 	if (rc != JTAG_OK) {
201029949e86Sstevel 		jtag_error_print(ring, rc);
201129949e86Sstevel 	}
201229949e86Sstevel 
201329949e86Sstevel 	return (rc);
201429949e86Sstevel }
201529949e86Sstevel 
201629949e86Sstevel #define	EN_LOC_FATAL		0x02
201729949e86Sstevel #define	MOD_OFF			0x80
201829949e86Sstevel #define	ACDC_OFF		0x40
201929949e86Sstevel #define	EPDA_OFF		0x10
202029949e86Sstevel #define	EPDB_OFF		0x08
202129949e86Sstevel #define	NOT_BRD_PRESENT		0x02
202229949e86Sstevel #define	NOT_BRD_LED_LEFT	0x04
202329949e86Sstevel #define	BRD_LED_MID		0x02
202429949e86Sstevel #define	BRD_LED_RIGHT		0x01
202529949e86Sstevel 
202629949e86Sstevel /*
202729949e86Sstevel  * Each board has an FHC asic.
202829949e86Sstevel  */
202929949e86Sstevel int
jtag_powerdown_board(volatile u_int * jreg,int board,enum board_type type,u_int * fhc_csr,u_int * fhc_bsr,int intr)203029949e86Sstevel jtag_powerdown_board(volatile u_int *jreg, int board, enum board_type type,
203129949e86Sstevel 	u_int *fhc_csr, u_int *fhc_bsr, int intr)
203229949e86Sstevel {
203329949e86Sstevel 	int rc = JTAG_OK;
203429949e86Sstevel 	fhc_options fhc_opt;
203529949e86Sstevel 	struct fhc_regs fhc_data;
203629949e86Sstevel 	u_char scan_out[32];
203729949e86Sstevel 	int status;
203829949e86Sstevel 	int ring;
203929949e86Sstevel 
204029949e86Sstevel 	if (type == UNKNOWN_BOARD) {
204129949e86Sstevel 		sysc_cfga_stat_t asc;
204229949e86Sstevel 
204329949e86Sstevel 		bzero(&asc, sizeof (asc));
204429949e86Sstevel 		asc.board = board;
204529949e86Sstevel 		type = jtag_get_board_type(jreg, &asc);
204629949e86Sstevel 	}
204729949e86Sstevel 
204829949e86Sstevel 	if (!intr)
204929949e86Sstevel 		(void) jtag_init_ac(jreg, board, type);
205029949e86Sstevel 
205129949e86Sstevel 	ring = board << 4;
205229949e86Sstevel 
205329949e86Sstevel 	fhc_opt.csr_hi = 0;
205429949e86Sstevel 	fhc_opt.csr_mid = MOD_OFF | EPDA_OFF | EPDB_OFF | NOT_BRD_PRESENT;
205529949e86Sstevel 	if (intr) {
205629949e86Sstevel 		/*
205729949e86Sstevel 		 * by not setting NOT_BRD_PRESENT we can simulate a board
205829949e86Sstevel 		 * insertion
205929949e86Sstevel 		 */
206029949e86Sstevel 		fhc_opt.csr_mid &= ~NOT_BRD_PRESENT;
206129949e86Sstevel 	}
206229949e86Sstevel 
206329949e86Sstevel 	fhc_opt.csr_midlo = NOT_BRD_LED_LEFT | BRD_LED_MID;
206429949e86Sstevel 
206529949e86Sstevel 	if ((type == CPU_BOARD) || (type == MEM_BOARD)) {
206629949e86Sstevel 		rc = jtag_init_chip(jreg, ring, &cpu_sysbd_ring_components[9],
206729949e86Sstevel 			(jtag_opt)&fhc_opt, scan_out);
206829949e86Sstevel 	} else if (type == IO_2SBUS_BOARD) {
206929949e86Sstevel 		rc = jtag_init_chip(jreg, ring, &io1_sysbd_ring_components[9],
207029949e86Sstevel 			(jtag_opt)&fhc_opt, scan_out);
207129949e86Sstevel 	} else if (type == IO_2SBUS_SOCPLUS_BOARD) {
207229949e86Sstevel 		rc = jtag_init_chip(jreg, ring,
207329949e86Sstevel 			&io1plus_sysbd_ring_components[9],
207429949e86Sstevel 			(jtag_opt)&fhc_opt, scan_out);
207529949e86Sstevel 	} else if (type == IO_SBUS_FFB_BOARD) {
207629949e86Sstevel 		rc = jtag_init_chip(jreg, ring, &io2_sysbd_ring_components[9],
207729949e86Sstevel 			(jtag_opt)&fhc_opt, scan_out);
207829949e86Sstevel 	} else if (type == IO_SBUS_FFB_SOCPLUS_BOARD) {
207929949e86Sstevel 		rc = jtag_init_chip(jreg, ring,
208029949e86Sstevel 			&io2plus_sysbd_ring_components[9],
208129949e86Sstevel 			(jtag_opt)&fhc_opt, scan_out);
208229949e86Sstevel 	} else if (type == IO_PCI_BOARD) {
208329949e86Sstevel 		rc = jtag_init_chip(jreg, ring, &io3_sysbd_ring_components[9],
208429949e86Sstevel 			(jtag_opt)&fhc_opt, scan_out);
208529949e86Sstevel 	} else if (type == UNKNOWN_BOARD) {
208629949e86Sstevel 		rc = jtag_init_chip(jreg, ring, &cpu_sysbd_ring_components[9],
208729949e86Sstevel 			(jtag_opt)&fhc_opt, scan_out);
208829949e86Sstevel 	} else {
208929949e86Sstevel 		cmn_err(CE_WARN, "Unsupported Board type %2X\n",
209029949e86Sstevel 			fhc_bd_type(board));
209129949e86Sstevel 	}
209229949e86Sstevel 
209329949e86Sstevel 	TAP_ISSUE_CMD(jreg, JTAG_TAP_RESET, status);
209429949e86Sstevel 
209529949e86Sstevel 	if (rc != JTAG_OK) {
209629949e86Sstevel 		jtag_error_print(ring, rc);
209729949e86Sstevel 	}
209829949e86Sstevel 
209929949e86Sstevel 	/* Reformat the FHC shadow chain scan data */
210029949e86Sstevel 	format_chip_data(chip_fhc.fmt_desc, (u_int *)&fhc_data,
210129949e86Sstevel 		scan_out);
210229949e86Sstevel 
210329949e86Sstevel 	*fhc_csr = fhc_data.csr;
210429949e86Sstevel 	*fhc_bsr = fhc_data.bsr;
210529949e86Sstevel 
210629949e86Sstevel 
210729949e86Sstevel 	return (rc);
210829949e86Sstevel }
210929949e86Sstevel 
211029949e86Sstevel /*
211129949e86Sstevel  * This function performs the fhc initialization for a disk board. The
211229949e86Sstevel  * hotplug variable tells the function whether to put the LED into low
211329949e86Sstevel  * power mode or not.
211429949e86Sstevel  */
211529949e86Sstevel int
jtag_init_disk_board(volatile u_int * jreg,int board,u_int * fhc_csr,u_int * fhc_bsr)211629949e86Sstevel jtag_init_disk_board(volatile u_int *jreg, int board,
211729949e86Sstevel 	u_int *fhc_csr, u_int *fhc_bsr)
211829949e86Sstevel {
211929949e86Sstevel 	int rc = JTAG_OK;
212029949e86Sstevel 	fhc_options fhc_opt;
212129949e86Sstevel 	struct fhc_regs fhc_data;
212229949e86Sstevel 	u_char scan_out[32];
212329949e86Sstevel 	int status;
212429949e86Sstevel 	int ring;
212529949e86Sstevel 
212629949e86Sstevel 	ring = board << 4;
212729949e86Sstevel 
212829949e86Sstevel 	fhc_opt.csr_hi = 0;
212929949e86Sstevel 	fhc_opt.csr_mid = NOT_BRD_PRESENT;
213029949e86Sstevel 	fhc_opt.csr_midlo = NOT_BRD_LED_LEFT | BRD_LED_MID;
213129949e86Sstevel 
213229949e86Sstevel 	rc = jtag_init_chip(jreg, ring, &dsk_sysbd_ring_components[1],
213329949e86Sstevel 		(jtag_opt)&fhc_opt, scan_out);
213429949e86Sstevel 
213529949e86Sstevel 	TAP_ISSUE_CMD(jreg, JTAG_TAP_RESET, status);
213629949e86Sstevel 
213729949e86Sstevel 	if (rc != JTAG_OK) {
213829949e86Sstevel 		jtag_error_print(ring, rc);
213929949e86Sstevel 		return (-1);
214029949e86Sstevel 	}
214129949e86Sstevel 
214229949e86Sstevel 	/* Reformat the FHC shadow chain scan data */
214329949e86Sstevel 	format_chip_data(chip_fhc.fmt_desc, (u_int *)&fhc_data,
214429949e86Sstevel 		scan_out);
214529949e86Sstevel 
214629949e86Sstevel 	*fhc_csr = fhc_data.csr;
214729949e86Sstevel 	*fhc_bsr = fhc_data.bsr;
214829949e86Sstevel 
214929949e86Sstevel 	return (0);
215029949e86Sstevel }
215129949e86Sstevel 
215229949e86Sstevel /*
215329949e86Sstevel  * NOTES:
215429949e86Sstevel  *	1. Scan data streams are little-endian sequences of bytes: byte 0
215529949e86Sstevel  *	   will provide the 8 lsb of the scan chain, and so on. If the last
215629949e86Sstevel  *	   byte is not full (count not a multiple of 8), the least significant
215729949e86Sstevel  *	   bits are used.
215829949e86Sstevel  *	2. All procedures assume that the JTAG control register
215929949e86Sstevel  *	   is non-busy on entry, and return with the control register
216029949e86Sstevel  *	   non-busy. It is a good idea to call tap_wait as part of the JTAG
216129949e86Sstevel  *	   sanity check sequence to verify there is no obvious malfunction.
216229949e86Sstevel  */
216329949e86Sstevel 
216429949e86Sstevel 
216529949e86Sstevel /*
216629949e86Sstevel  *	Non-data TAP commands
216729949e86Sstevel  */
216829949e86Sstevel 
216929949e86Sstevel /*
217029949e86Sstevel  * Wait for the TAP to be idle.
217129949e86Sstevel  * Return <0 if error, >=0 if OK.
217229949e86Sstevel  */
217329949e86Sstevel 
217429949e86Sstevel int
tap_wait(volatile u_int * jreg)217529949e86Sstevel tap_wait(volatile u_int *jreg)
217629949e86Sstevel {
217729949e86Sstevel 	TAP_DECLARE;
217829949e86Sstevel 	TAP_WAIT(jreg);
217929949e86Sstevel 	return (JTAG_OK);
218029949e86Sstevel }
218129949e86Sstevel 
218229949e86Sstevel /*
218329949e86Sstevel  * Send a TAP command, wait for completion.
218429949e86Sstevel  * Return <0 if error, >=0 if OK.
218529949e86Sstevel  */
218629949e86Sstevel 
218729949e86Sstevel static int
tap_issue_cmd(volatile u_int * jreg,u_int command)218829949e86Sstevel tap_issue_cmd(volatile u_int *jreg, u_int command)
218929949e86Sstevel {
219029949e86Sstevel 	TAP_DECLARE;
219129949e86Sstevel 
219229949e86Sstevel 	*jreg = command;
219329949e86Sstevel 	TAP_WAIT(jreg);
219429949e86Sstevel 	return (JTAG_OK);
219529949e86Sstevel }
219629949e86Sstevel 
219729949e86Sstevel /*
219829949e86Sstevel  *	Data TAP commands
219929949e86Sstevel  */
220029949e86Sstevel 
220129949e86Sstevel /*
220229949e86Sstevel  * Shift 1 to 16 bits into the component.
220329949e86Sstevel  * Return <0 if error, the shifted out bits (always >=0) if OK.
220429949e86Sstevel  */
220529949e86Sstevel 
220629949e86Sstevel int
tap_shift_single(volatile u_int * jreg,int data,int nbits)220729949e86Sstevel tap_shift_single(volatile u_int *jreg, int data, int nbits)
220829949e86Sstevel {
220929949e86Sstevel 	/* Return <0 if error, >0 (16-bit data) if OK */
221029949e86Sstevel 	TAP_DECLARE;
221129949e86Sstevel 	TAP_SHIFT(jreg, data, nbits);
221229949e86Sstevel 	return (jtag_data(jreg, nbits));
221329949e86Sstevel }
221429949e86Sstevel 
221529949e86Sstevel /*
221629949e86Sstevel  * Shift the required number of bits from in into the component,
221729949e86Sstevel  * retrieve the bits shifted out.
221829949e86Sstevel  * Return <0 if error, >=0 if OK.
221929949e86Sstevel  */
222029949e86Sstevel 
222129949e86Sstevel int
tap_shift_multiple(volatile u_int * jreg,u_char * data_in,int nbits,u_char * data_out)222229949e86Sstevel tap_shift_multiple(
222329949e86Sstevel 	volatile u_int *jreg,
222429949e86Sstevel 	u_char *data_in,
222529949e86Sstevel 	int nbits,
222629949e86Sstevel 	u_char *data_out)    /* data_out may be NULL if not needed */
222729949e86Sstevel {
222829949e86Sstevel 	TAP_DECLARE;
222929949e86Sstevel 
223029949e86Sstevel 	/*
223129949e86Sstevel 	 * The loop is done a byte at a time to avoid stepping out
223229949e86Sstevel 	 * of the caller's buffer
223329949e86Sstevel 	 */
223429949e86Sstevel 	for (; nbits > 0; nbits = nbits - 8) {
223529949e86Sstevel 		int bits_this_pass = nbits > 8 ? 8 : nbits;
223629949e86Sstevel 		TAP_SHIFT(jreg, *data_in++, bits_this_pass);
223729949e86Sstevel 		if (data_out != NULL) {
223829949e86Sstevel 			*data_out = jtag_data(jreg, bits_this_pass);
223929949e86Sstevel 			data_out++;
224029949e86Sstevel 		}
224129949e86Sstevel 	}
224229949e86Sstevel 
224329949e86Sstevel 	return (JTAG_OK);
224429949e86Sstevel }
224529949e86Sstevel 
224629949e86Sstevel /*
224729949e86Sstevel  * Shift the required number of bits of the specified
224829949e86Sstevel  * value into the selected register. Note that this routine makes
224929949e86Sstevel  * sense only for value = 0 and value = -1.
225029949e86Sstevel  * Return <0 if error, >=0 if OK.
225129949e86Sstevel  */
225229949e86Sstevel 
225329949e86Sstevel static int
tap_shift_constant(volatile u_int * jreg,int value,int nbits)225429949e86Sstevel tap_shift_constant(volatile u_int *jreg, int value, int nbits)
225529949e86Sstevel {
225629949e86Sstevel 	TAP_DECLARE;
225729949e86Sstevel 
225829949e86Sstevel 	TAP_WAIT(jreg);
225929949e86Sstevel 
226029949e86Sstevel 	/*
226129949e86Sstevel 	 * The loop is done a half-word at a time
226229949e86Sstevel 	 */
226329949e86Sstevel 	for (; nbits > 0; nbits = nbits - 16) {
226429949e86Sstevel 		int bits_this_pass = nbits > 16 ? 16 : nbits;
226529949e86Sstevel 		TAP_SHIFT(jreg, value, bits_this_pass);
226629949e86Sstevel 	}
226729949e86Sstevel 
226829949e86Sstevel 	return (JTAG_OK);
226929949e86Sstevel }
227029949e86Sstevel 
227129949e86Sstevel 
227229949e86Sstevel /*
227329949e86Sstevel  *	Ring-level commands
227429949e86Sstevel  */
227529949e86Sstevel 
227629949e86Sstevel /*
227729949e86Sstevel  * Select the required ring. Reset it if required (reset != 0).
227829949e86Sstevel  * Return <0 if error, >=0 if OK.
227929949e86Sstevel  */
228029949e86Sstevel 
228129949e86Sstevel static int
select_ring(volatile u_int * jreg,jtag_ring ring,int reset)228229949e86Sstevel select_ring(volatile u_int *jreg, jtag_ring ring, int reset)
228329949e86Sstevel {
228429949e86Sstevel 	int status;
228529949e86Sstevel 	jtag_ring jring;
228629949e86Sstevel 
228729949e86Sstevel 	status = tap_wait(jreg);
228829949e86Sstevel 	if (status < 0) {
228929949e86Sstevel 		return (status);
229029949e86Sstevel 	}
229129949e86Sstevel 
229229949e86Sstevel 	/* Translate a Physical Board number to a JTAG board number */
229329949e86Sstevel 	jring = ((u_int)(ring & 0x10) << 3) | ((u_int)(ring & 0xE0) >> 1) |
229429949e86Sstevel 		(ring & 0xF);
229529949e86Sstevel 	status = tap_issue_cmd(jreg, (jring << 16) | JTAG_SEL_RING);
229629949e86Sstevel 	if (status < 0) {
229729949e86Sstevel 		return (status);
229829949e86Sstevel 	}
229929949e86Sstevel 
230029949e86Sstevel 	if (reset != 0) {
230129949e86Sstevel 		status = tap_issue_cmd(jreg, JTAG_TAP_RESET);
230229949e86Sstevel 	}
230329949e86Sstevel 
230429949e86Sstevel 	return (status);
230529949e86Sstevel }
230629949e86Sstevel 
230729949e86Sstevel /*
230829949e86Sstevel  * Shift the specified instruction into the component, then
230929949e86Sstevel  * shift the required data in & retrieve the data out.
231029949e86Sstevel  * Return <0 if error, >=0 if OK.
231129949e86Sstevel  */
231229949e86Sstevel 
231329949e86Sstevel static int
jtag_single_IR_DR(volatile u_int * jreg,jtag_phys_comp * component,jtag_instruction instr,u_char * in,int nbits,u_char * out)231429949e86Sstevel jtag_single_IR_DR(
231529949e86Sstevel 	volatile u_int *jreg,
231629949e86Sstevel 	jtag_phys_comp *component,
231729949e86Sstevel 	jtag_instruction instr,
231829949e86Sstevel 	u_char *in,
231929949e86Sstevel 	int nbits,
232029949e86Sstevel 	u_char *out)
232129949e86Sstevel {
232229949e86Sstevel 	int status;
232329949e86Sstevel 
232429949e86Sstevel 	TAP_ISSUE_CMD(jreg, JTAG_SEL_IR, status);
232529949e86Sstevel 	TAP_SHIFT_CONSTANT(jreg, -1, component->ir_after, status);
232629949e86Sstevel 	TAP_SHIFT_SINGLE(jreg, instr, component->chip->ir_len, status);
232729949e86Sstevel 	TAP_SHIFT_CONSTANT(jreg, -1, component->ir_before, status);
232829949e86Sstevel 	TAP_ISSUE_CMD(jreg, JTAG_IR_TO_DR, status);
232929949e86Sstevel 	TAP_SHIFT_CONSTANT(jreg, 0, component->by_after, status);
233029949e86Sstevel 	TAP_SHIFT_MULTIPLE(jreg, in, nbits, out, status);
233129949e86Sstevel 	TAP_SHIFT_CONSTANT(jreg, 0, component->by_before, status);
233229949e86Sstevel 	TAP_ISSUE_CMD(jreg, JTAG_RUNIDLE, status);
233329949e86Sstevel 
233429949e86Sstevel 	return (status);
233529949e86Sstevel }
233629949e86Sstevel 
233729949e86Sstevel /*
233829949e86Sstevel  * jtag_rescan_IR_DR()
233929949e86Sstevel  *
234029949e86Sstevel  * This function is used in order to rescan the DC ASICs when taking
234129949e86Sstevel  * them out of the frozen state. This is necessary because of a problem
234229949e86Sstevel  * when taking DCs out of the frozen state. Sometimes the operation must
234329949e86Sstevel  * be retryed.
234429949e86Sstevel  *
234529949e86Sstevel  * TODO - Eliminate the *in input parameter if able to.
234629949e86Sstevel  */
234729949e86Sstevel 
234829949e86Sstevel /* ARGSUSED */
234929949e86Sstevel static int
jtag_rescan_IR_DR(volatile u_int * jreg,jtag_phys_comp * component,jtag_instruction instr,u_char * in,int nbits,u_char * out)235029949e86Sstevel jtag_rescan_IR_DR(
235129949e86Sstevel 	volatile u_int *jreg,
235229949e86Sstevel 	jtag_phys_comp *component,
235329949e86Sstevel 	jtag_instruction instr,
235429949e86Sstevel 	u_char *in,
235529949e86Sstevel 	int nbits,
235629949e86Sstevel 	u_char *out)
235729949e86Sstevel {
235829949e86Sstevel 	int status, i;
235929949e86Sstevel 	u_char tmp[32];
236029949e86Sstevel 
236129949e86Sstevel 	for (i = 0; i < 32; i++)
236229949e86Sstevel 		tmp[i] = 0;
236329949e86Sstevel 
236429949e86Sstevel 	TAP_ISSUE_CMD(jreg, JTAG_SEL_IR, status);
236529949e86Sstevel 	TAP_SHIFT_CONSTANT(jreg, -1, component->ir_after, status);
236629949e86Sstevel 	TAP_SHIFT_SINGLE(jreg, instr, component->chip->ir_len, status);
236729949e86Sstevel 	TAP_SHIFT_CONSTANT(jreg, -1, component->ir_before, status);
236829949e86Sstevel 	TAP_ISSUE_CMD(jreg, JTAG_IR_TO_DR, status);
236929949e86Sstevel 
237029949e86Sstevel 	/* scan the chip out */
237129949e86Sstevel 	TAP_SHIFT_CONSTANT(jreg, 0, component->by_after, status);
237229949e86Sstevel 	TAP_SHIFT_MULTIPLE(jreg, tmp, nbits, out, status);
237329949e86Sstevel 	TAP_SHIFT_CONSTANT(jreg, 0, component->by_before, status);
237429949e86Sstevel 
237529949e86Sstevel 	/* re scan the chip */
237629949e86Sstevel 	TAP_SHIFT_CONSTANT(jreg, 0, component->by_after, status);
237729949e86Sstevel 	TAP_SHIFT_MULTIPLE(jreg, out, nbits, tmp, status);
237829949e86Sstevel 	TAP_SHIFT_CONSTANT(jreg, 0, component->by_before, status);
237929949e86Sstevel 
238029949e86Sstevel 	TAP_ISSUE_CMD(jreg, JTAG_RUNIDLE, status);
238129949e86Sstevel 
238229949e86Sstevel 	return (status);
238329949e86Sstevel }
238429949e86Sstevel 
238529949e86Sstevel /*
238629949e86Sstevel  * Return the number of components of the current ring, or <0 if failed
238729949e86Sstevel  */
238829949e86Sstevel static int
jtag_ring_length(volatile u_int * jreg,jtag_ring ring)238929949e86Sstevel jtag_ring_length(volatile u_int *jreg, jtag_ring ring)
239029949e86Sstevel {
239129949e86Sstevel 	int status, length;
239229949e86Sstevel 
239329949e86Sstevel 	/*
239429949e86Sstevel 	 * Reset the ring & check that there is a component
239529949e86Sstevel 	 * This is based on the fact that TAP reset forces the IDCODE,
239629949e86Sstevel 	 * or BYPASS (with 0 preloaded) if there is no ID
239729949e86Sstevel 	 */
239829949e86Sstevel 
239929949e86Sstevel 	status = select_ring(jreg, ring, 1);
240029949e86Sstevel 	if (status < 0) {
240129949e86Sstevel 		cmn_err(CE_WARN, "select ring error jtag status %x\n",
240229949e86Sstevel 			status);
240329949e86Sstevel 		return (status);
240429949e86Sstevel 	}
240529949e86Sstevel 
240629949e86Sstevel 	TAP_ISSUE_CMD(jreg, JTAG_SEL_DR, status);
240729949e86Sstevel 	TAP_SHIFT_SINGLE(jreg, -1, 8, status);
240829949e86Sstevel 	if (status == 0xFF) {
240929949e86Sstevel 		return (RING_BROKEN); /* no CID detected */
241029949e86Sstevel 	}
241129949e86Sstevel 
241229949e86Sstevel 	/*
241329949e86Sstevel 	 * Put all components in BYPASS. This assumes the chain has
241429949e86Sstevel 	 * at most 32 components, and that each IR is at most 16-bits.
241529949e86Sstevel 	 * Note that the algorithm depends on the bypass FF to be cleared
241629949e86Sstevel 	 * on a tap reset!
241729949e86Sstevel 	 */
241829949e86Sstevel 	TAP_ISSUE_CMD(jreg, JTAG_TAP_RESET, status);
241929949e86Sstevel 	TAP_ISSUE_CMD(jreg, JTAG_SEL_IR, status);
242029949e86Sstevel 	TAP_SHIFT_CONSTANT(jreg, -1, 32*16, status);
242129949e86Sstevel 	TAP_ISSUE_CMD(jreg, JTAG_IR_TO_DR, status);
242229949e86Sstevel 	TAP_SHIFT_CONSTANT(jreg, 0, 32, status);
242329949e86Sstevel 
242429949e86Sstevel 	for (length = 0; length <= 33; length++) { /* bit by bit */
242529949e86Sstevel 		TAP_SHIFT_SINGLE(jreg, -1, 1, status);
242629949e86Sstevel 
242729949e86Sstevel 		if (status != 0) {
242829949e86Sstevel 			break;
242929949e86Sstevel 		}
243029949e86Sstevel 	}
243129949e86Sstevel 	TAP_ISSUE_CMD(jreg, JTAG_RUNIDLE, status);
243229949e86Sstevel 	/* more than 32 components ??? */
243329949e86Sstevel 	return ((length <= 32) ? length : RING_BROKEN);
243429949e86Sstevel }
243529949e86Sstevel 
243629949e86Sstevel /*
243729949e86Sstevel  * Return the total number of instruction register bits in the
243829949e86Sstevel  * current ring,  or < 0 if failed.
243929949e86Sstevel  */
244029949e86Sstevel int
jtag_ring_ir_length(volatile u_int * jreg,jtag_ring ring)244129949e86Sstevel jtag_ring_ir_length(volatile u_int *jreg, jtag_ring ring)
244229949e86Sstevel {
244329949e86Sstevel 	int status, length;
244429949e86Sstevel 
244529949e86Sstevel 	/*
244629949e86Sstevel 	 * Reset the ring & check that there is a component
244729949e86Sstevel 	 * This is based on the fact that TAP reset forces the IDCODE,
244829949e86Sstevel 	 * or BYPASS (with 0 preloaded) if there is no ID
244929949e86Sstevel 	 */
245029949e86Sstevel 	status = select_ring(jreg, ring, 1);
245129949e86Sstevel 	if (status < 0) {
245229949e86Sstevel 		cmn_err(CE_WARN, "select error status %x", status);
245329949e86Sstevel 		return (status);
245429949e86Sstevel 	}
245529949e86Sstevel 
245629949e86Sstevel 	/*
245729949e86Sstevel 	 * Reset, Select IR, Shift in all 1's assuming the chain has
245829949e86Sstevel 	 * at most 32 components, and that each IR is at most 16-bits.
245929949e86Sstevel 	 * Then shift in 0's and count until a 0 comes out.
246029949e86Sstevel 	 * And cleanup by flushing with all 1's before reset or idle
246129949e86Sstevel 	 * --- FATAL's if you don't as you go through update-ir state
246229949e86Sstevel 	 */
246329949e86Sstevel 	TAP_ISSUE_CMD(jreg, JTAG_TAP_RESET, status);
246429949e86Sstevel 	TAP_ISSUE_CMD(jreg, JTAG_SEL_IR, status);
246529949e86Sstevel 
246629949e86Sstevel 	/* 1 fill, look for 0 */
246729949e86Sstevel 	TAP_SHIFT_CONSTANT(jreg, -1, 32 * 16, status);
246829949e86Sstevel 	for (length = 0; length <= 32 * 16; length++) {	/* bit by bit */
246929949e86Sstevel 		TAP_SHIFT_SINGLE(jreg, 0, 1, status);
247029949e86Sstevel 		if (status == 0)
247129949e86Sstevel 			break;
247229949e86Sstevel 	}
247329949e86Sstevel 
247429949e86Sstevel 	/* bypass should be safe */
247529949e86Sstevel 	TAP_SHIFT_CONSTANT(jreg, -1, 32 * 16, status);
247629949e86Sstevel 	TAP_ISSUE_CMD(jreg, JTAG_RUNIDLE, status);
247729949e86Sstevel 	/* more than 32*16 ir bits ??? */
247829949e86Sstevel 	return ((length <= 32 * 16) ? length : RING_BROKEN);
247929949e86Sstevel }
248029949e86Sstevel 
248129949e86Sstevel /*
248229949e86Sstevel  * Format the jtag shadow scan data from scan_out bit string and store
248329949e86Sstevel  * in the array on u_ints. The datap represents the registers from
248429949e86Sstevel  * the chip under scan.
248529949e86Sstevel  * XXX - How to represent 64 bit registers here?
248629949e86Sstevel  */
248729949e86Sstevel static void
format_chip_data(u_char * fmt,u_int * datap,u_char * scan_out)248829949e86Sstevel format_chip_data(u_char *fmt, u_int *datap, u_char *scan_out)
248929949e86Sstevel {
249029949e86Sstevel 	u_int value;
249129949e86Sstevel 
249229949e86Sstevel 	for (value = 0; ; ) {
249329949e86Sstevel 		u_char cmd = *fmt++;
249429949e86Sstevel 
249529949e86Sstevel 		if ((cmd & JTSO_XTRACT) != 0) {
249629949e86Sstevel 			u_int lsb, msb;
249729949e86Sstevel 			lsb = *fmt++;
249829949e86Sstevel 			msb = *fmt++;
249929949e86Sstevel 			value |= jtag_bf_extract(scan_out, lsb, msb) <<
250029949e86Sstevel 				(cmd & JTSO_SHIFT);
250129949e86Sstevel 		}
250229949e86Sstevel 
250329949e86Sstevel 		if ((cmd & JTSO_ST) != 0) {
250429949e86Sstevel 			*datap++ = value;
250529949e86Sstevel 			value = 0;
250629949e86Sstevel 		}
250729949e86Sstevel 
250829949e86Sstevel 		if ((cmd & JTSO_END) != 0) {
250929949e86Sstevel 			break;
251029949e86Sstevel 		}
251129949e86Sstevel 	}
251229949e86Sstevel }
2513