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, ®s->cpid, 0, CpIDid, C(CpID), C(0));
98 if(res < 0)
99 return -1;
100 res = jtagmrc(jmed, ®s->control, 0, 0, C(CpCONTROL), C(0));
101 if(res < 0)
102 return -1;
103 res = jtagmrc(jmed, ®s->ttb, 0, 0, C(CpTTB), C(0));
104 if(res < 0)
105 return -1;
106 res = jtagmrc(jmed, ®s->dac, 0, 0, C(CpDAC), C(0));
107 if(res < 0)
108 return -1;
109 res = jtagmrc(jmed, ®s->fsr, 0, 0, C(CpFSR), C(0));
110 if(res < 0)
111 return -1;
112 res = jtagmrc(jmed, ®s->far, 0, 0, C(CpFAR), C(0));
113 if(res < 0)
114 return -1;
115 res = jtagmrc(jmed, ®s->ct, 0, CpIDct, C(CpID), C(0));
116 if(res < 0)
117 return -1;
118 res = jtagmrc(jmed, ®s->pid, 0, 0, C(CpPID), C(0));
119 if(res < 0)
120 return -1;
121
122 return 0;
123 }
124
125
126