]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/omap/coproc.c
kernel: make addbroken() static, remove misleading Proc* argument
[plan9front.git] / sys / src / 9 / omap / 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,           /* MOV R14, R15 */
20 };
21
22 void
23 cpwr(int cp, int op1, int crn, int crm, int op2, ulong val)
24 {
25         volatile ulong instr[2];
26         void *pcaddr;
27         void (*fp)(ulong);
28
29         op1 &= 7;
30         op2 &= 7;
31         crn &= 017;
32         crm &= 017;
33         cp &= 017;
34         /* MCR.  Rt will be R0. */
35         instr[0] = 0xee000010 |
36                 op1 << 21 | crn << 16 | cp << 8 | op2 << 5 | crm;
37         instr[1] = Retinst;
38
39         pcaddr = (void *)MAP2PCSPACE(instr, getcallerpc(&cp));
40         cachedwbse(pcaddr, sizeof instr);
41         cacheiinv();
42
43         fp = (void (*)(ulong))pcaddr;
44         (*fp)(val);
45         coherence();
46 }
47
48 void
49 cpwrsc(int op1, int crn, int crm, int op2, ulong val)
50 {
51         cpwr(CpSC, op1, crn, crm, op2, val);
52 }
53
54 ulong
55 cprd(int cp, int op1, int crn, int crm, int op2)
56 {
57         volatile ulong instr[2];
58         void *pcaddr;
59         ulong (*fp)(void);
60
61         op1 &= 7;
62         op2 &= 7;
63         crn &= 017;
64         crm &= 017;
65         /*
66          * MRC.  return value will be in R0, which is convenient.
67          * Rt will be R0.
68          */
69         instr[0] = 0xee100010 |
70                 op1 << 21 | crn << 16 | cp << 8 | op2 << 5 | crm;
71         instr[1] = Retinst;
72
73         pcaddr = (void *)MAP2PCSPACE(instr, getcallerpc(&cp));
74         cachedwbse(pcaddr, sizeof instr);
75         cacheiinv();
76
77         fp = (ulong (*)(void))pcaddr;
78         return (*fp)();
79 }
80
81 ulong
82 cprdsc(int op1, int crn, int crm, int op2)
83 {
84         return cprd(CpSC, op1, crn, crm, op2);
85 }
86
87 /* floating point */
88
89 ulong
90 fprd(int fpreg)
91 {
92         volatile ulong instr[2];
93         void *pcaddr;
94         ulong (*fp)(void);
95
96         fpreg &= 017;
97         /*
98          * VMRS.  return value will be in R0, which is convenient.
99          * Rt will be R0.
100          */
101         instr[0] = 0xeef00a10 | fpreg << 16 | 0 << 12;
102         instr[1] = Retinst;
103         coherence();
104
105         pcaddr = (void *)MAP2PCSPACE(instr, getcallerpc(&fpreg));
106         cachedwbse(pcaddr, sizeof instr);
107         cacheiinv();
108
109         fp = (ulong (*)(void))pcaddr;
110         return (*fp)();
111 }
112
113 void
114 fpwr(int fpreg, ulong val)
115 {
116         volatile ulong instr[2];
117         void *pcaddr;
118         void (*fp)(ulong);
119
120         fpreg &= 017;
121         /* VMSR.  Rt will be R0. */
122         instr[0] = 0xeee00a10 | fpreg << 16 | 0 << 12;
123         instr[1] = Retinst;
124         coherence();
125
126         pcaddr = (void *)MAP2PCSPACE(instr, getcallerpc(&fpreg));
127         cachedwbse(pcaddr, sizeof instr);
128         cacheiinv();
129
130         fp = (void (*)(ulong))pcaddr;
131         (*fp)(val);
132         coherence();
133 }