]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/kw/coproc.c
devusb: fix format print warnings for ep->ntds and ep->uframes
[plan9front.git] / sys / src / 9 / kw / coproc.c
1 /*
2  * arm co-processors
3  * CP15 (system control) is the one that gets used the most in practice.
4  */
5 #include "u.h"
6 #include "../port/lib.h"
7 #include "mem.h"
8 #include "dat.h"
9 #include "fns.h"
10 #include "io.h"
11
12 #include "arm.h"
13
14 #define MAP2PCSPACE(va, pc) ((uintptr)(va) & ~KSEGM | (pc) & KSEGM)
15
16 enum {
17         /* alternates:  0xe12fff1e      BX (R14); last e is R14 */
18         /*              0xe28ef000      B 0(R14); second e is R14 (ken) */
19         Retinst = 0xe1a0f00e,           /* MOVW R14, R15 */
20
21         Fpproc  = 10,                   /* for vfp 3+; also 11 for doubles */
22 };
23
24 void
25 cpwr(int cp, int op1, int crn, int crm, int op2, ulong val)
26 {
27         int s;
28         volatile ulong instr[2];
29         void *pcaddr;
30         void (*fp)(ulong);
31
32         s = splhi();
33         op1 &= 7;
34         op2 &= 7;
35         crn &= 017;
36         crm &= 017;
37         cp &= 017;
38         /* MCR.  Rt will be R0. */
39         instr[0] = 0xee000010 |
40                 op1 << 21 | crn << 16 | cp << 8 | op2 << 5 | crm;
41         instr[1] = Retinst;
42         coherence();
43
44         pcaddr = (void *)MAP2PCSPACE(instr, getcallerpc(&cp));
45         cachedwbse(pcaddr, sizeof instr);
46         cacheiinv();
47
48         fp = (void (*)(ulong))pcaddr;
49         (*fp)(val);
50         coherence();
51         splx(s);
52 }
53
54 void
55 cpwrsc(int op1, int crn, int crm, int op2, ulong val)
56 {
57         cpwr(CpSC, op1, crn, crm, op2, val);
58 }
59
60 ulong
61 cprd(int cp, int op1, int crn, int crm, int op2)
62 {
63         int s;
64         ulong res;
65         volatile ulong instr[2];
66         void *pcaddr;
67         ulong (*fp)(void);
68
69         s = splhi();
70         op1 &= 7;
71         op2 &= 7;
72         crn &= 017;
73         crm &= 017;
74         /*
75          * MRC.  return value will be in R0, which is convenient.
76          * Rt will be R0.
77          */
78         instr[0] = 0xee100010 |
79                 op1 << 21 | crn << 16 | cp << 8 | op2 << 5 | crm;
80         instr[1] = Retinst;
81         coherence();
82
83         pcaddr = (void *)MAP2PCSPACE(instr, getcallerpc(&cp));
84         cachedwbse(pcaddr, sizeof instr);
85         cacheiinv();
86
87         fp = (ulong (*)(void))pcaddr;
88         res = (*fp)();
89         splx(s);
90         return res;
91 }
92
93 ulong
94 cprdsc(int op1, int crn, int crm, int op2)
95 {
96         return cprd(CpSC, op1, crn, crm, op2);
97 }
98
99 /* floating point */
100
101 ulong
102 fprd(int fpreg)
103 {
104         int s;
105         ulong res;
106         volatile ulong instr[2];
107         void *pcaddr;
108         ulong (*fp)(void);
109
110         s = splhi();
111         fpreg &= 017;
112         /*
113          * VMRS.  return value will be in R0, which is convenient.
114          * Rt will be R0.
115          */
116         instr[0] = 0xeef00010 | fpreg << 16 | 0 << 12 | Fpproc << 8;
117         instr[1] = Retinst;
118         coherence();
119
120         pcaddr = (void *)MAP2PCSPACE(instr, getcallerpc(&fpreg));
121         cachedwbse(pcaddr, sizeof instr);
122         cacheiinv();
123
124         fp = (ulong (*)(void))pcaddr;
125         res = (*fp)();
126         splx(s);
127         return res;
128 }
129
130 void
131 fpwr(int fpreg, ulong val)
132 {
133         int s;
134         volatile ulong instr[2];
135         void *pcaddr;
136         void (*fp)(ulong);
137
138         s = splhi();
139         fpreg &= 017;
140         /* VMSR.  Rt will be R0. */
141         instr[0] = 0xeee00010 | fpreg << 16 | 0 << 12 | Fpproc << 8;
142         instr[1] = Retinst;
143         coherence();
144
145         pcaddr = (void *)MAP2PCSPACE(instr, getcallerpc(&fpreg));
146         cachedwbse(pcaddr, sizeof instr);
147         cacheiinv();
148
149         fp = (void (*)(ulong))pcaddr;
150         (*fp)(val);
151         coherence();
152         splx(s);
153 }