]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/bcm64/sysreg.c
vmx: clean up mksegment, memset only if segment existed (devsegment clears new ones)
[plan9front.git] / sys / src / 9 / bcm64 / sysreg.c
1 /*
2  * ARMv8 system registers
3  * mainly to cope with arm hard-wiring register numbers into instructions.
4  *
5  * these routines must be callable from KZERO.
6  *
7  * on a multiprocessor, process switching to another cpu is assumed
8  * to be inhibited by the caller as these registers are local to the cpu.
9  */
10 #include "u.h"
11 #include "../port/lib.h"
12 #include "mem.h"
13 #include "dat.h"
14 #include "fns.h"
15
16 static void*
17 mkinstr(ulong wd)
18 {
19         static ulong ib[256], *ep[MAXMACH+1];
20         static Lock lk;
21         ulong *ip, *ie;
22
23         ie = ep[m->machno];
24         for(ip = ib; ip < ie; ip += 2)
25                 if(*ip == wd)
26                         return ip;
27
28         ilock(&lk);
29         ie = ep[MAXMACH];
30         for(; ip < ie; ip += 2)
31                 if(*ip == wd)
32                         goto Found;
33         if(ip >= &ib[nelem(ib)])
34                 panic("mkinstr: out of instrucuction buffer");
35         ip[0] = wd;
36         ip[1] = 0xd65f03c0;     // RETURN
37         ep[MAXMACH] = ie = ip + 2;
38         cachedwbinvse(ip, 2*sizeof(*ip));
39 Found:
40         iunlock(&lk);
41         cacheiinv();
42         ep[m->machno] = ie;
43         return ip;
44 }
45
46 uvlong
47 sysrd(ulong spr)
48 {
49         uvlong (*fp)(void) = mkinstr(0xd5380000UL | spr);
50         return fp();
51 }
52
53 void
54 syswr(ulong spr, uvlong val)
55 {
56         void (*fp)(uvlong) = mkinstr(0xd5180000UL | spr);
57         fp(val);
58 }