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