xref: /plan9-contrib/sys/src/cmd/jtagfs/icert.h (revision dedb130315e7b691e306ee069395ee1f0b18e4d4)
1 typedef struct ArmCtxt ArmCtxt;
2 typedef struct EiceChain1 EiceChain1;
3 typedef struct EiceChain2 EiceChain2;
4 typedef struct EiceRegs EiceRegs;
5 typedef struct EiceWp EiceWp;
6 typedef struct MMURegs MMURegs;
7 typedef struct PackedSz PackedSz;
8 
9 enum{
10 	/*
11 	  *	This is an arm 926, except no MOE, only 1 Wpoint
12 	  *	I think this means "mcr access"
13 	  * 	for the MMU. It would be good knowing for real
14 	  *	what the good doc for it is or if it is just
15 	  *	random mix and match!!.
16 	  */
17 	FeroceonId	= 0x20a023d3,
18 
19 	/* Looks like a pxa/feroceon frankenstein */
20 	ArmadaId	= 0x304113d3,
21 
22 	ArmInstSz = 4,
23 	ThumbInstSz = 2,
24 };
25 
26 
27 /* instructions for the IR, 4 bits */
28 enum {
29 	InExtest	= 0x0,
30 	InScanN	= 0x2,		/* shift the scan chain id, 5 bits */
31 	InSampPre	= 0x3,
32 	InRestart	= 0x4,
33 	InHighZ	= 0x7,
34 	InClampZ	= 0x9,
35 	InTest		= 0xc,
36 	InIdCode	= 0xe,
37 	InBypass	= 0xf,
38 
39 	InGuruTapctl = 0x98,
40 	InGuruLen = 9,
41 	DrGuruTapctl = 0x00a,
42 	DrGuruLen = 16,
43 
44 	InLen		= 4,		/* bits */
45 	EiceCh1Len	= 67,		/* bits */
46 	EiceCh2Len	= 38,		/* bits */
47 };
48 
49 /* sizes are in bits */
50 #define WpN(nreg, field) ((nreg<<(nreg))|(field))
51 
52 enum {
53 
54 	/* chain 1 */
55 	InstrSz			= 32,
56 	SysSpeedSz		= 1,
57 	WpTanDBKptSz		= 1,
58 	Ch1ResvdSz,
59 	RWDataSz			= 32,
60 
61 
62 	/* chain 2, here registers are directed through addr */
63 	DataSz			= 32,
64 	AddrSz			= 5,
65 	RWSz			= 1,
66 
67 	DebugCtlReg		= 0x00,
68 	DebStsReg		= 0x01,
69 	VecCatReg		= 0x02,
70 	DebComCtlReg		= 0x04,
71 	DebComDataReg	= 0x05,
72 
73 	Wp0				= 1<<4,	/* Wp0|AddrValReg and so on */
74 	Wp1				= 1<<5,	/* Wp1|AddrValReg and so on */
75 
76 	AddrValReg		= 0x00,
77 	AddrMskReg		= 0x01,
78 	DataValReg		= 0x02,
79 	DataMskReg		= 0x03,
80 	CtlValReg			= 0x04,
81 	CtlMskReg		= 0x05,
82 
83 	/* sizes in bits */
84 	DebugCtlRegSz		= 6,
85 	DebStsRegSz		= 10,		/* in feroceon 5, no Moe */
86 	VecCatRegSz		= 8,
87 	DebComCtlRegSz	= 6,
88 	DebComDataRegSz	= 32,
89 
90 	AddrValRegSz		= 32,
91 	AddrMskRegSz		= 32,
92 	DataValRegSz		= 32,
93 	DataMskRegSz		= 32,
94 	CtlValRegSz		= 9,
95 	CtlMskRegSz		= 8,
96 
97 	/*	DebugCtlReg (write) */
98 	DBGACK			= 1,		/* I am dealing with debug mode */
99 	DBGRQ			= 1<<1,	/* Enter debug mode */
100 	INTDIS			= 1<<2,	/* Disable interrupts */
101 	SBZ0				= 1<<3,	/* Should be Zero */
102 	MONENAB		= 1<<4,	/* Monitor mode/halt mode */
103 	EICEDISAB		= 1<<5,	/* Power down */
104 
105 	/*	DebugSTSReg (read)
106 	 * 	two first bits same as ctl
107 	 */
108 	IFEN			= 1<<2,		/* Are interrupts enabled */
109 	SYSCOMP		= 1<<3,		/* Memory access complete */
110 	ITBIT		= 1<<4,		/* Thumb/Arm mode */
111 	SBZ1			= 1<<5,
112 	MOEMSK		= 0xf<<6,		/* Method of entry */
113 
114 	/*	VecCatReg (write), one bit per exception to catch */
115 	ResetCat		= 1,
116 	UndefCat		= 1<<1,
117 	SWICat		= 1<<2,
118 	PAbortCat		= 1<<3,
119 	DAbortCat	= 1<<4,
120 	RsvdCat		= 1<<5,
121 	IrqCat		= 1<<6,
122 	FiqCat		= 1<<7,
123 
124 	/*
125 	 *	Watchpoint control registers:
126 	 *	CtlValReg CtlMskReg
127 	 *	Bit 1 in Msk makes condition ignored.
128 	 */
129 
130 	/* Data version of CtlValReg bits 6, 7, 8 are shared */
131 	DnRWWPCtl		= 1,		/*  0 access is read 1 write */
132 	DmasWPCtlMsk	= 3<<1,	/*  this two bits represent size of access */
133 	DataWPCtl		= 1<<3,	/* compare against data/0 is inst */
134 	DnTransWPCtl		= 1<<4,	/* 0 user 1 privileged */
135 	DbgExtWPCtl		= 1<<5,	/* External condition for watchpoint */
136 	ChainWPCtl		= 1<<6,	/* Chain together watchpoints */
137 	RangeWPCtl		= 1<<7,	/* Range connecting watchpoints together */
138 	EnableWPCtl		= 1<<8,	/* Cannot be masked */
139 	/* Inst version of CtlValReg */
140 	IgnWPCtl			= 1,	/*  ignored */
141 	ITbitWPCtlMsk		= 3<<1,	/*  1 Thumb  */
142 	IJbitWPCtl			= 1<<2,	/*  1 Jazelle  */
143 	InTransWPCtl		= 1<<4,	/* 0 user 1 privileged */
144 
145 
146 	/*	Id code */
147 	ManIdSz		= 11,
148 	PartNoSz		= 16,
149 	VerSz		= 4,
150 
151 };
152 
153 enum{
154 	ChNoCommit	= 0,
155 	ChCommit	= 1,
156 };
157 
158 struct PackedSz {
159 	uchar unpkSz;
160 	uchar pkSz;
161 };
162 
163 /*
164  * The bit ordering on this one is peculiar, see packech1()
165  * in particular the instruction is upside down,
166  */
167 
168 struct EiceChain1 {
169 	u32int	instr;			/* 32 bits */
170 	uchar	sysspeed;		/* 1 bit */
171 	uchar	wptandbkpt;	/* 1 bit */
172 	/* 1 bit rsvd */
173 	u32int	rwdata;		/* 32 bits */
174 };
175 
176 struct EiceChain2 {
177 	u32int data;		/* 32 bits */
178 	uchar addr;		/* 5 bits */
179 	uchar	rw;		/* 1 bit */
180 };
181 
182 struct EiceWp {
183 	u32int	addrval;	/* 32 bits */
184 	u32int	addrmsk;	/* 32 bits */
185 	u32int	dataval;	/* 32 bits */
186 	u32int	datamsk;	/* 32 bits */
187 	u16int	ctlval;	/* 9 bits */
188 	uchar	ctlmsk;	/* 8 bits */
189 };
190 
191 struct EiceRegs {
192 	uchar	debug;		/* 4 bits */
193 	uchar	debsts;		/* 5 bits */
194 	uchar	veccat;		/* 8 bits */
195 	uchar	debcomctl;	/* 6 bits */
196 	u32int	debcomdata;	/* 32 bits */
197 	EiceWp wp[2];
198 };
199 
200 enum{
201 	ARMSTMIA = 0xe8800000,
202 	ARMLDMIA = 0xe8900000,
203 	BYTEWDTH = 0x00400000,
204 	ARMLDRindr1xr0 = 0xe5901000,	/* LDR r1, [r0]	|| [r0]->r1*/
205 	ARMSTRindxr0r1 = 0xe5801000,	/* STR [r0], r1 || r1->[r0] */
206 	ARMNOP = 0xe1a08008,
207 	ARMMRSr0CPSR = 0xE10F0000,
208 	ARMMSRr0CPSR = 0xE12FF000,
209 	SPSR = 1<<22,
210 	ARMMRSr0SPSR = ARMMRSr0CPSR|SPSR,
211 	ARMMSRr0SPSR = ARMMSRr0CPSR|SPSR,
212 	ARMBRIMM = 0xea000000,
213 };
214 
215 
216 #define MOE(dbgreg)	(((dbgreg)&MOEMSK)>>6);
217 
218 #define MANID(id)	(((id)>>1)&MSK(ManIdSz))
219 #define PARTNO(id)	(((id)>>ManIdSz+1)&MSK(PartNoSz))
220 #define VERS(id)	(((id)>>ManIdSz+1+PartNoSz)&MSK(VerSz))
221 
222 struct MMURegs {
223 	u32int	cpid;		/* main ID */
224 	u32int	control;	/* control */
225 	u32int	ttb;		/* translation table base */
226 	u32int	dac;		/* domain access control */
227 	u32int	fsr;		/* fault status */
228 	u32int	far;		/* fault address */
229 	u32int	ct;		/* cache type */
230 	u32int	pid;		/* address translation pid */
231 };
232 
233 enum{
234 	NoReas,
235 	BreakReqReas,
236 	BreakReas,
237 	VeccatReqReas,
238 	VeccatReas,
239 	DebugReas,
240 };
241 
242 struct ArmCtxt {
243 	int pcadjust;
244 	int debug;
245 	int debugreas;
246 	int exitreas;
247 	int cpuid;
248 	u32int r[16];
249 	u32int cpsr;
250 	u32int spsr;
251 	MMURegs;
252 };
253 
254 extern int	armbpasstest(JMedium *jmed);
255 extern int	armfastexec(JMedium *jmed, u32int inst);
256 extern int	armgetexec(JMedium *jmed, int nregs, u32int *regs, u32int inst);
257 extern int	armgofetch(JMedium *jmed, u32int instr, int sysspeed);
258 extern u32int	armidentify(JMedium *jmed);
259 extern int	armrdmemwd(JMedium *jmed, u32int addr, u32int *data, int sz);
260 extern int	armsavectxt(JMedium *jmed, ArmCtxt *ctxt);
261 extern int	armsetexec(JMedium *jmed, int nregs, u32int *regs, u32int inst);
262 extern int	armsetregs(JMedium *jmed, int mask, u32int *regs);
263 extern int	armwrmemwd(JMedium *jmed, u32int addr, u32int data, int sz);
264 extern int	icedebugstate(JMedium *jmed);
265 extern int	iceenterdebug(JMedium *jmed, ArmCtxt *ctxt);
266 extern int	iceexitdebug(JMedium *jmed, ArmCtxt *ctxt);
267 extern u32int	icegetreg(JMedium *jmed, int regaddr);
268 extern int	icesetreg(JMedium *jmed, int regaddr, u32int val);
269 extern int	icewaitdebug(JMedium *jmed);
270 extern int	icewaitentry(JMedium *jmed, ArmCtxt *ctxt);
271 extern int	setchain(JMedium *jmed, int commit, uchar chain);
272 extern int	setinst(JMedium *jmed, uchar inst, int nocommit);
273 extern char *	armsprctxt(ArmCtxt *ctxt, char *s, int ssz);
274