xref: /plan9-contrib/sys/src/cmd/jtagfs/mmu.c (revision dedb130315e7b691e306ee069395ee1f0b18e4d4)
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include "chain.h"
5 #include "debug.h"
6 #include "tap.h"
7 #include "lebo.h"
8 #include "bebo.h"
9 #include "jtag.h"
10 #include "icert.h"
11 #include "mmu.h"
12 #include "mpsse.h"
13 #include "/sys/src/9/kw/arm.h"
14 
15 /*
16  *	Feroceon's scan chain 15 does not work, I suspect it has the multi-ice
17  *	40 bits limit (even if it is only one core). Just pushing MCR/MRC and
18  *	reading back seems to be more portable
19  *	The only bad thing is that using chain 15 one can
20  *	change things secondary effects (I cannot think of any, but there may be)
21  */
22 
23 char *
printmmuregs(MMURegs * mmuregs,char * s,int ssz)24 printmmuregs(MMURegs *mmuregs, char *s, int ssz)
25 {
26 	char *e, *te;
27 
28 	te = s + ssz - 1;
29 
30 	e = seprint(s, te, "cpid: %#8.8ux\n", mmuregs->cpid);
31 	e = seprint(e, te, "ct: %#8.8ux\n", mmuregs->ct);
32 	e = seprint(e, te, "control: %#8.8ux\n", mmuregs->control);
33 	e = seprint(e, te, "ttb: %#8.8ux\n", mmuregs->ttb);
34 	e = seprint(e, te, "dac: %#8.8ux\n", mmuregs->dac);
35 	e = seprint(e, te, "fsr: %#8.8ux\n", mmuregs->fsr);
36 	e = seprint(e, te, "far: %#8.8ux\n", mmuregs->far);
37 	e = seprint(e, te, "pid: %#8.8ux\n", mmuregs->pid);
38 	return e;
39 }
40 
41 /* Chain 15 does not work properly and is not portable, use MCR/MRC */
42 
43 static int
jtagmrc(JMedium * jmed,u32int * data,uchar op1,uchar op2,uchar crn,uchar crm)44 jtagmrc(JMedium *jmed, u32int *data, uchar op1, uchar op2, uchar crn, uchar crm)
45 {
46 	int res;
47 	u32int d;
48 
49 	res = armfastexec(jmed, ARMMRC(CpSC, op1, 0, crn, crm, op2));
50 	if(res < 0)
51 		return -1;
52 
53 	setinst(jmed, InRestart, 0);
54 	res = icewaitdebug(jmed);
55 	if(res < 0)
56 		return -1;
57 	res = setchain(jmed, ChCommit, 1);
58 	if(res < 0)
59 		sysfatal("setchain %r");
60 	armgetexec(jmed, 1, &d, ARMSTMIA|0x0001);
61 
62 	*data = d;
63 	dprint(Dmmu, "MCR data %#8.8ux \n", d);
64 	return 0;
65 }
66 
67 static int
jtagmcr(JMedium * jmed,u32int data,uchar op1,uchar op2,uchar crn,uchar crm)68 jtagmcr(JMedium *jmed, u32int data, uchar op1, uchar op2, uchar crn, uchar crm)
69 {
70 	int res;
71 	dprint(Dmem, "MCR data %#8.8ux\n",
72 				data);
73 	/* load data in r0 */
74 	res = armsetexec(jmed, 1, &data, ARMLDMIA|0x0001);
75 	if(res < 0)
76 		return -1;
77 
78 	res = armfastexec(jmed, ARMMCR(CpSC, op1, 0, crn, crm, op2));
79 	if(res < 0)
80 		return -1;
81 
82 	setinst(jmed, InRestart, 0);
83 	res = icewaitdebug(jmed);
84 	if(res < 0)
85 		return -1;
86 	return 0;
87 }
88 
89 
90 int
mmurdregs(JMedium * jmed,MMURegs * regs)91 mmurdregs(JMedium *jmed, MMURegs *regs)
92 {
93 	int res;
94 	res = setchain(jmed, ChCommit, 1);
95 	if(res < 0)
96 		sysfatal("setchain %r");
97 	res = jtagmrc(jmed, &regs->cpid, 0, CpIDid, C(CpID), C(0));
98 	if(res < 0)
99 		return -1;
100 	res = jtagmrc(jmed, &regs->control, 0, 0,  C(CpCONTROL), C(0));
101 	if(res < 0)
102 		return -1;
103 	res = jtagmrc(jmed, &regs->ttb, 0, 0,  C(CpTTB), C(0));
104 	if(res < 0)
105 		return -1;
106 	res = jtagmrc(jmed, &regs->dac, 0, 0,  C(CpDAC), C(0));
107 	if(res < 0)
108 		return -1;
109 	res = jtagmrc(jmed, &regs->fsr, 0, 0,  C(CpFSR), C(0));
110 	if(res < 0)
111 		return -1;
112 	res = jtagmrc(jmed, &regs->far, 0, 0,  C(CpFAR), C(0));
113 	if(res < 0)
114 		return -1;
115 	res = jtagmrc(jmed, &regs->ct, 0, CpIDct, C(CpID), C(0));
116 	if(res < 0)
117 		return -1;
118 	res = jtagmrc(jmed, &regs->pid, 0, 0,  C(CpPID), C(0));
119 	if(res < 0)
120 		return -1;
121 
122 	return 0;
123 }
124 
125 
126