ref: b143811a53bf25824e74b7e6e6c2ee7af8c7a954
parent: a6964cfab636bbd7f30abc6ce1776d283ba75cf7
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Mon Apr 7 18:10:40 EDT 2025
kernel: deduplicate the mess that is the 32-bit arm ports avoid these #include "../omap/*.h" constructs, and handle it in the mkfile instead. move most of the 32-bit arm stuff to omap, except bcm hosts some crazy vfp3 + fpi mixed mode code which is shared with tegra. get rid of omap/mouse.c, just define a mousectl() in screen.c, we'r done.
--- a/sys/src/9/bcm/fpi.c
+++ /dev/null
@@ -1,1 +1,0 @@
-#include "../omap/fpi.c"
--- a/sys/src/9/bcm/fpi.h
+++ /dev/null
@@ -1,1 +1,0 @@
-#include "../omap/fpi.h"
--- a/sys/src/9/bcm/fpiarm.c
+++ b/sys/src/9/bcm/fpiarm.c
@@ -13,7 +13,7 @@
#include "ureg.h"
#include "arm.h"
-#include "fpi.h"
+#include "../omap/fpi.h"
/* undef this if correct kernel r13 isn't in Ureg;
* check calculation in fpiarm below
--- a/sys/src/9/bcm/fpimem.c
+++ /dev/null
@@ -1,1 +1,0 @@
-#include "../omap/fpimem.c"
--- a/sys/src/9/bcm/mkfile
+++ b/sys/src/9/bcm/mkfile
@@ -102,15 +102,23 @@
<../port/portmkfile
<|../port/mkbootrules $CONF
+fpi.$O fpiarm.$O fpimem.$O: ../omap/fpi.h
+fpi.$O: ../omap/fpi.c
+ $CC $CFLAGS -. ../omap/fpi.c
+fpimem.$O: ../omap/fpimem.c
+ $CC $CFLAGS -. ../omap/fpimem.c
+
+syscall.$O: ../omap/syscall.c
+ $CC $CFLAGS -. ../omap/syscall.c
+
arch.$O clock.$O fpiarm.$O main.$O mmu.$O screen.$O syscall.$O trap.$O: \
/$objtype/include/ureg.h
arch.$O trap.$O main.$O: /sys/include/tos.h
-fpi.$O fpiarm.$O fpimem.$O: fpi.h
l.$O lexception.$O lproc.$O mmu.$O: mem.h
l.$O lexception.$O lproc.$O armv6.$O armv7.$O: arm.s
armv7.$O: cache.v7.s
main.$O: errstr.h rebootcode.i
-devmouse.$O mouse.$O screen.$O: screen.h
+devmouse.$O screen.$O: screen.h
usbdwc.$O: dwcotg.h ../port/usb.h
i2cbcm.$O i2cgpio.$O: ../port/i2c.h
emmc.$O ether4330.$O: ../port/sd.h
--- a/sys/src/9/bcm/mouse.c
+++ /dev/null
@@ -1,1 +1,0 @@
-#include "../omap/mouse.c"
--- a/sys/src/9/bcm/pi
+++ b/sys/src/9/bcm/pi
@@ -16,7 +16,7 @@
bridge log
ip arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium inferno
draw screen swcursor
- mouse mouse
+ mouse
uart gpio
gpio gpio
i2c
--- a/sys/src/9/bcm/pi2
+++ b/sys/src/9/bcm/pi2
@@ -16,7 +16,7 @@
bridge log
ip arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium inferno
draw screen swcursor
- mouse mouse
+ mouse
uart gpio
gpio gpio
i2c
--- a/sys/src/9/bcm/screen.c
+++ b/sys/src/9/bcm/screen.c
@@ -56,6 +56,33 @@
static void screenwin(void);
/* called from devmouse */
+enum
+{+ CMaccelerated,
+ CMlinear,
+};
+
+static Cmdtab mousectlmsg[] =
+{+ CMaccelerated, "accelerated", 0,
+ CMlinear, "linear", 1,
+};
+
+void
+mousectl(Cmdbuf *cb)
+{+ Cmdtab *ct;
+
+ ct = lookupcmd(cb, mousectlmsg, nelem(mousectlmsg));
+ switch(ct->index){+ case CMaccelerated:
+ mouseaccelerate(cb->nf == 1? 1: atoi(cb->f[1]));
+ break;
+ case CMlinear:
+ mouseaccelerate(0);
+ break;
+ }
+}
void
cursoron(void)
--- a/sys/src/9/bcm/syscall.c
+++ /dev/null
@@ -1,1 +1,0 @@
-#include "../kw/syscall.c"
--- a/sys/src/9/bcm64/mkfile
+++ b/sys/src/9/bcm64/mkfile
@@ -114,7 +114,7 @@
main.$O: rebootcode.i
pcibcm.$O: ../port/pci.h
-devmouse.$O mouse.$O screen.$O: screen.h
+devmouse.$O screen.$O: screen.h
usbdwc.$O: dwcotg.h ../port/usb.h
i2cbcm.$O i2cgpio.$O: ../port/i2c.h
emmc.$O sdhc.$O sdhost.$O ether4330.$O: ../port/sd.h
--- a/sys/src/9/bcm64/pi3
+++ b/sys/src/9/bcm64/pi3
@@ -17,7 +17,7 @@
bridge log
ip arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium inferno
draw screen swcursor
- mouse mouse
+ mouse
uart gpio
gpio gpio
i2c
--- a/sys/src/9/bcm64/pi4
+++ b/sys/src/9/bcm64/pi4
@@ -17,7 +17,7 @@
bridge log
ip arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium inferno
draw screen swcursor
- mouse mouse
+ mouse
uart gpio
gpio gpio
i2c
--- a/sys/src/9/kw/fpi.c
+++ /dev/null
@@ -1,300 +1,0 @@
-/*
- * Floating Point Interpreter.
- * shamelessly stolen from an original by ark.
- */
-#include "fpi.h"
-
-void
-fpiround(Internal *i)
-{- unsigned long guard;
-
- guard = i->l & GuardMask;
- i->l &= ~GuardMask;
- if(guard > (LsBit>>1) || (guard == (LsBit>>1) && (i->l & LsBit))){- i->l += LsBit;
- if(i->l & CarryBit){- i->l &= ~CarryBit;
- i->h++;
- if(i->h & CarryBit){- if (i->h & 0x01)
- i->l |= CarryBit;
- i->l >>= 1;
- i->h >>= 1;
- i->e++;
- }
- }
- }
-}
-
-static void
-matchexponents(Internal *x, Internal *y)
-{- int count;
-
- count = y->e - x->e;
- x->e = y->e;
- if(count >= 2*FractBits){- x->l = x->l || x->h;
- x->h = 0;
- return;
- }
- if(count >= FractBits){- count -= FractBits;
- x->l = x->h|(x->l != 0);
- x->h = 0;
- }
- while(count > 0){- count--;
- if(x->h & 0x01)
- x->l |= CarryBit;
- if(x->l & 0x01)
- x->l |= 2;
- x->l >>= 1;
- x->h >>= 1;
- }
-}
-
-static void
-shift(Internal *i)
-{- i->e--;
- i->h <<= 1;
- i->l <<= 1;
- if(i->l & CarryBit){- i->l &= ~CarryBit;
- i->h |= 0x01;
- }
-}
-
-static void
-normalise(Internal *i)
-{- while((i->h & HiddenBit) == 0)
- shift(i);
-}
-
-static void
-renormalise(Internal *i)
-{- if(i->e < -2 * FractBits)
- i->e = -2 * FractBits;
- while(i->e < 1){- i->e++;
- if(i->h & 0x01)
- i->l |= CarryBit;
- i->h >>= 1;
- i->l = (i->l>>1)|(i->l & 0x01);
- }
- if(i->e >= ExpInfinity)
- SetInfinity(i);
-}
-
-void
-fpinormalise(Internal *x)
-{- if(!IsWeird(x) && !IsZero(x))
- normalise(x);
-}
-
-void
-fpiadd(Internal *x, Internal *y, Internal *i)
-{- Internal *t;
-
- i->s = x->s;
- if(IsWeird(x) || IsWeird(y)){- if(IsNaN(x) || IsNaN(y))
- SetQNaN(i);
- else
- SetInfinity(i);
- return;
- }
- if(x->e > y->e){- t = x;
- x = y;
- y = t;
- }
- matchexponents(x, y);
- i->e = x->e;
- i->h = x->h + y->h;
- i->l = x->l + y->l;
- if(i->l & CarryBit){- i->h++;
- i->l &= ~CarryBit;
- }
- if(i->h & (HiddenBit<<1)){- if(i->h & 0x01)
- i->l |= CarryBit;
- i->l = (i->l>>1)|(i->l & 0x01);
- i->h >>= 1;
- i->e++;
- }
- if(IsWeird(i))
- SetInfinity(i);
-}
-
-void
-fpisub(Internal *x, Internal *y, Internal *i)
-{- Internal *t;
-
- if(y->e < x->e
- || (y->e == x->e && (y->h < x->h || (y->h == x->h && y->l < x->l)))){- t = x;
- x = y;
- y = t;
- }
- i->s = y->s;
- if(IsNaN(y)){- SetQNaN(i);
- return;
- }
- if(IsInfinity(y)){- if(IsInfinity(x))
- SetQNaN(i);
- else
- SetInfinity(i);
- return;
- }
- matchexponents(x, y);
- i->e = y->e;
- i->h = y->h - x->h;
- i->l = y->l - x->l;
- if(i->l < 0){- i->l += CarryBit;
- i->h--;
- }
- if(i->h == 0 && i->l == 0)
- SetZero(i);
- else while(i->e > 1 && (i->h & HiddenBit) == 0)
- shift(i);
-}
-
-#define CHUNK (FractBits/2)
-#define CMASK ((1<<CHUNK)-1)
-#define HI(x) ((short)((x)>>CHUNK) & CMASK)
-#define LO(x) ((short)(x) & CMASK)
-#define SPILL(x) ((x)>>CHUNK)
-#define M(x, y) ((long)a[x]*(long)b[y])
-#define C(h, l) (((long)((h) & CMASK)<<CHUNK)|((l) & CMASK))
-
-void
-fpimul(Internal *x, Internal *y, Internal *i)
-{- long a[4], b[4], c[7], f[4];
-
- i->s = x->s^y->s;
- if(IsWeird(x) || IsWeird(y)){- if(IsNaN(x) || IsNaN(y) || IsZero(x) || IsZero(y))
- SetQNaN(i);
- else
- SetInfinity(i);
- return;
- }
- else if(IsZero(x) || IsZero(y)){- SetZero(i);
- return;
- }
- normalise(x);
- normalise(y);
- i->e = x->e + y->e - (ExpBias - 1);
-
- a[0] = HI(x->h); b[0] = HI(y->h);
- a[1] = LO(x->h); b[1] = LO(y->h);
- a[2] = HI(x->l); b[2] = HI(y->l);
- a[3] = LO(x->l); b[3] = LO(y->l);
-
- c[6] = M(3, 3);
- c[5] = M(2, 3) + M(3, 2) + SPILL(c[6]);
- c[4] = M(1, 3) + M(2, 2) + M(3, 1) + SPILL(c[5]);
- c[3] = M(0, 3) + M(1, 2) + M(2, 1) + M(3, 0) + SPILL(c[4]);
- c[2] = M(0, 2) + M(1, 1) + M(2, 0) + SPILL(c[3]);
- c[1] = M(0, 1) + M(1, 0) + SPILL(c[2]);
- c[0] = M(0, 0) + SPILL(c[1]);
-
- f[0] = c[0];
- f[1] = C(c[1], c[2]);
- f[2] = C(c[3], c[4]);
- f[3] = C(c[5], c[6]);
-
- if((f[0] & HiddenBit) == 0){- f[0] <<= 1;
- f[1] <<= 1;
- f[2] <<= 1;
- f[3] <<= 1;
- if(f[1] & CarryBit){- f[0] |= 1;
- f[1] &= ~CarryBit;
- }
- if(f[2] & CarryBit){- f[1] |= 1;
- f[2] &= ~CarryBit;
- }
- if(f[3] & CarryBit){- f[2] |= 1;
- f[3] &= ~CarryBit;
- }
- i->e--;
- }
- i->h = f[0];
- i->l = f[1];
- if(f[2] || f[3])
- i->l |= 1;
- renormalise(i);
-}
-
-void
-fpidiv(Internal *x, Internal *y, Internal *i)
-{- i->s = x->s^y->s;
- if(IsNaN(x) || IsNaN(y)
- || (IsInfinity(x) && IsInfinity(y)) || (IsZero(x) && IsZero(y))){- SetQNaN(i);
- return;
- }
- else if(IsZero(x) || IsInfinity(y)){- SetInfinity(i);
- return;
- }
- else if(IsInfinity(x) || IsZero(y)){- SetZero(i);
- return;
- }
- normalise(x);
- normalise(y);
- i->h = 0;
- i->l = 0;
- i->e = y->e - x->e + (ExpBias + 2*FractBits - 1);
- do{- if(y->h > x->h || (y->h == x->h && y->l >= x->l)){- i->l |= 0x01;
- y->h -= x->h;
- y->l -= x->l;
- if(y->l < 0){- y->l += CarryBit;
- y->h--;
- }
- }
- shift(y);
- shift(i);
- }while ((i->h & HiddenBit) == 0);
- if(y->h || y->l)
- i->l |= 0x01;
- renormalise(i);
-}
-
-int
-fpicmp(Internal *x, Internal *y)
-{- if(IsNaN(x) && IsNaN(y))
- return 0;
- if(IsInfinity(x) && IsInfinity(y))
- return y->s - x->s;
- if(x->e == y->e && x->h == y->h && x->l == y->l)
- return y->s - x->s;
- if(x->e < y->e
- || (x->e == y->e && (x->h < y->h || (x->h == y->h && x->l < y->l))))
- return y->s ? 1: -1;
- return x->s ? -1: 1;
-}
--- a/sys/src/9/kw/fpi.h
+++ /dev/null
@@ -1,61 +1,0 @@
-typedef long Word;
-typedef unsigned long Single;
-typedef struct {- unsigned long l;
- unsigned long h;
-} Double;
-
-enum {- FractBits = 28,
- CarryBit = 0x10000000,
- HiddenBit = 0x08000000,
- MsBit = HiddenBit,
- NGuardBits = 3,
- GuardMask = 0x07,
- LsBit = (1<<NGuardBits),
-
- SingleExpBias = 127,
- SingleExpMax = 255,
- DoubleExpBias = 1023,
- DoubleExpMax = 2047,
-
- ExpBias = DoubleExpBias,
- ExpInfinity = DoubleExpMax,
-};
-
-typedef struct {- unsigned char s;
- short e;
- long l; /* 0000FFFFFFFFFFFFFFFFFFFFFFFFFGGG */
- long h; /* 0000HFFFFFFFFFFFFFFFFFFFFFFFFFFF */
-} Internal;
-
-#define IsWeird(n) ((n)->e >= ExpInfinity)
-#define IsInfinity(n) (IsWeird(n) && (n)->h == HiddenBit && (n)->l == 0)
-#define SetInfinity(n) ((n)->e = ExpInfinity, (n)->h = HiddenBit, (n)->l = 0)
-#define IsNaN(n) (IsWeird(n) && (((n)->h & ~HiddenBit) || (n)->l))
-#define SetQNaN(n) ((n)->s = 0, (n)->e = ExpInfinity, \
- (n)->h = HiddenBit|(LsBit<<1), (n)->l = 0)
-#define IsZero(n) ((n)->e == 1 && (n)->h == 0 && (n)->l == 0)
-#define SetZero(n) ((n)->e = 1, (n)->h = 0, (n)->l = 0)
-
-/*
- * fpi.c
- */
-extern void fpiround(Internal *);
-extern void fpiadd(Internal *, Internal *, Internal *);
-extern void fpisub(Internal *, Internal *, Internal *);
-extern void fpimul(Internal *, Internal *, Internal *);
-extern void fpidiv(Internal *, Internal *, Internal *);
-extern int fpicmp(Internal *, Internal *);
-extern void fpinormalise(Internal*);
-
-/*
- * fpimem.c
- */
-extern void fpis2i(Internal *, void *);
-extern void fpid2i(Internal *, void *);
-extern void fpiw2i(Internal *, void *);
-extern void fpii2s(void *, Internal *);
-extern void fpii2d(void *, Internal *);
-extern void fpii2w(Word *, Internal *);
--- a/sys/src/9/kw/fpiarm.c
+++ /dev/null
@@ -1,772 +1,0 @@
-/*
- * this doesn't attempt to implement ARM floating-point properties
- * that aren't visible in the Inferno environment.
- * all arithmetic is done in double precision.
- * the FP trap status isn't updated.
- */
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-
-#include "ureg.h"
-
-#include "arm.h"
-#include "fpi.h"
-
-/* undef this if correct kernel r13 isn't in Ureg;
- * check calculation in fpiarm below
- */
-#define REG(ur, x) (*(long*)(((char*)(ur))+roff[(x)]))
-#define FR(ufp, x) (*(Internal*)(ufp)->regs[(x)&(Nfpctlregs - 1)])
-
-typedef struct FP2 FP2;
-typedef struct FP1 FP1;
-
-struct FP2 {- char* name;
- void (*f)(Internal, Internal, Internal*);
-};
-
-struct FP1 {- char* name;
- void (*f)(Internal*, Internal*);
-};
-
-enum {- N = 1<<31,
- Z = 1<<30,
- C = 1<<29,
- V = 1<<28,
- REGPC = 15,
-};
-
-enum {- fpemudebug = 0,
-};
-
-#undef OFR
-#define OFR(X) ((ulong)&((Ureg*)0)->X)
-
-static int roff[] = {- OFR(r0), OFR(r1), OFR(r2), OFR(r3),
- OFR(r4), OFR(r5), OFR(r6), OFR(r7),
- OFR(r8), OFR(r9), OFR(r10), OFR(r11),
- OFR(r12), OFR(r13), OFR(r14), OFR(pc),
-};
-
-static Internal fpconst[8] = { /* indexed by op&7 (ARM 7500 FPA) */- /* s, e, l, h */
- {0, 0x1, 0x00000000, 0x00000000}, /* 0.0 */- {0, 0x3FF, 0x00000000, 0x08000000}, /* 1.0 */- {0, 0x400, 0x00000000, 0x08000000}, /* 2.0 */- {0, 0x400, 0x00000000, 0x0C000000}, /* 3.0 */- {0, 0x401, 0x00000000, 0x08000000}, /* 4.0 */- {0, 0x401, 0x00000000, 0x0A000000}, /* 5.0 */- {0, 0x3FE, 0x00000000, 0x08000000}, /* 0.5 */- {0, 0x402, 0x00000000, 0x0A000000}, /* 10.0 */-};
-
-/*
- * arm binary operations
- */
-
-static void
-fadd(Internal m, Internal n, Internal *d)
-{- (m.s == n.s? fpiadd: fpisub)(&m, &n, d);
-}
-
-static void
-fsub(Internal m, Internal n, Internal *d)
-{- m.s ^= 1;
- (m.s == n.s? fpiadd: fpisub)(&m, &n, d);
-}
-
-static void
-fsubr(Internal m, Internal n, Internal *d)
-{- n.s ^= 1;
- (n.s == m.s? fpiadd: fpisub)(&n, &m, d);
-}
-
-static void
-fmul(Internal m, Internal n, Internal *d)
-{- fpimul(&m, &n, d);
-}
-
-static void
-fdiv(Internal m, Internal n, Internal *d)
-{- fpidiv(&m, &n, d);
-}
-
-static void
-fdivr(Internal m, Internal n, Internal *d)
-{- fpidiv(&n, &m, d);
-}
-
-/*
- * arm unary operations
- */
-
-static void
-fmov(Internal *m, Internal *d)
-{- *d = *m;
-}
-
-static void
-fmovn(Internal *m, Internal *d)
-{- *d = *m;
- d->s ^= 1;
-}
-
-static void
-fabsf(Internal *m, Internal *d)
-{- *d = *m;
- d->s = 0;
-}
-
-static void
-frnd(Internal *m, Internal *d)
-{- short e;
-
- (m->s? fsub: fadd)(fpconst[6], *m, d);
- if(IsWeird(d))
- return;
- fpiround(d);
- e = (d->e - ExpBias) + 1;
- if(e <= 0)
- SetZero(d);
- else if(e > FractBits){- if(e < 2*FractBits)
- d->l &= ~((1<<(2*FractBits - e))-1);
- }else{- d->l = 0;
- if(e < FractBits)
- d->h &= ~((1<<(FractBits-e))-1);
- }
-}
-
-/*
- * ARM 7500 FPA opcodes
- */
-
-static FP1 optab1[16] = { /* Fd := OP Fm */-[0] {"MOVF", fmov},-[1] {"NEGF", fmovn},-[2] {"ABSF", fabsf},-[3] {"RNDF", frnd},-[4] {"SQTF", /*fsqt*/0},-/* LOG, LGN, EXP, SIN, COS, TAN, ASN, ACS, ATN all `deprecated' */
-/* URD and NRM aren't implemented */
-};
-
-static FP2 optab2[16] = { /* Fd := Fn OP Fm */-[0] {"ADDF", fadd},-[1] {"MULF", fmul},-[2] {"SUBF", fsub},-[3] {"RSUBF", fsubr},-[4] {"DIVF", fdiv},-[5] {"RDIVF", fdivr},-/* POW, RPW deprecated */
-[8] {"REMF", /*frem*/0},-[9] {"FMF", fmul}, /* fast multiply */-[10] {"FDV", fdiv}, /* fast divide */-[11] {"FRD", fdivr}, /* fast reverse divide */-/* POL deprecated */
-};
-
-/*
- * ARM VFP opcodes
- */
-
-static FP1 voptab1[32] = { /* Vd := OP Vm */-[0] {"MOVF", fmov},-[1] {"ABSF", fabsf},-[2] {"NEGF", fmovn},-[15] {"CVTF", fmov},-};
-
-static FP2 voptab2[16] = { /* Vd := Vn FOP Fm */-[4] {"MULF", fmul},-[6] {"ADDF", fadd},-[7] {"SUBF", fsub},-[8] {"DIVF", fdiv},-};
-
-static ulong
-fcmp(Internal *n, Internal *m)
-{- int i;
- Internal rm, rn;
-
- if(IsWeird(m) || IsWeird(n)){- /* BUG: should trap if not masked */
- return V|C;
- }
- rn = *n;
- rm = *m;
- fpiround(&rn);
- fpiround(&rm);
- i = fpicmp(&rn, &rm);
- if(i > 0)
- return C;
- else if(i == 0)
- return C|Z;
- else
- return N;
-}
-
-static void
-fld(void (*f)(Internal*, void*), int d, ulong ea, int n, FPsave *ufp)
-{- void *mem;
-
- mem = (void*)ea;
- (*f)(&FR(ufp, d), mem);
- if(fpemudebug)
- print("MOV%c #%lux, F%d\n", n==8? 'D': 'F', ea, d);-}
-
-static void
-fst(void (*f)(void*, Internal*), ulong ea, int s, int n, FPsave *ufp)
-{- Internal tmp;
- void *mem;
-
- mem = (void*)ea;
- tmp = FR(ufp, s);
- if(fpemudebug)
- print("MOV%c F%d,#%lux\n", n==8? 'D': 'F', s, ea);- (*f)(mem, &tmp);
-}
-
-static int
-condok(int cc, int c)
-{- switch(c){- case 0: /* Z set */
- return cc&Z;
- case 1: /* Z clear */
- return (cc&Z) == 0;
- case 2: /* C set */
- return cc&C;
- case 3: /* C clear */
- return (cc&C) == 0;
- case 4: /* N set */
- return cc&N;
- case 5: /* N clear */
- return (cc&N) == 0;
- case 6: /* V set */
- return cc&V;
- case 7: /* V clear */
- return (cc&V) == 0;
- case 8: /* C set and Z clear */
- return cc&C && (cc&Z) == 0;
- case 9: /* C clear or Z set */
- return (cc&C) == 0 || cc&Z;
- case 10: /* N set and V set, or N clear and V clear */
- return (~cc&(N|V))==0 || (cc&(N|V)) == 0;
- case 11: /* N set and V clear, or N clear and V set */
- return (cc&(N|V))==N || (cc&(N|V))==V;
- case 12: /* Z clear, and either N set and V set or N clear and V clear */
- return (cc&Z) == 0 && ((~cc&(N|V))==0 || (cc&(N|V))==0);
- case 13: /* Z set, or N set and V clear or N clear and V set */
- return (cc&Z) || (cc&(N|V))==N || (cc&(N|V))==V;
- case 14: /* always */
- return 1;
- case 15: /* never (reserved) */
- return 0;
- }
- return 0; /* not reached */
-}
-
-static void
-unimp(ulong pc, ulong op)
-{- char buf[60];
-
- snprint(buf, sizeof(buf), "sys: fp: pc=%lux unimp fp 0x%.8lux", pc, op);
- if(fpemudebug)
- print("FPE: %s\n", buf);- error(buf);
- /* no return */
-}
-
-static void
-fpaemu(ulong pc, ulong op, Ureg *ur, FPsave *ufp)
-{- int rn, rd, tag, o;
- long off;
- ulong ea;
- Internal tmp, *fm, *fn;
-
- /* note: would update fault status here if we noted numeric exceptions */
-
- /*
- * LDF, STF; 10.1.1
- */
- if(((op>>25)&7) == 6){- if(op & (1<<22))
- unimp(pc, op); /* packed or extended */
- rn = (op>>16)&0xF;
- off = (op&0xFF)<<2;
- if((op & (1<<23)) == 0)
- off = -off;
- ea = REG(ur, rn);
- if(rn == REGPC)
- ea += 8;
- if(op & (1<<24))
- ea += off;
- rd = (op>>12)&7;
- if(op & (1<<20)){- if(op & (1<<15))
- fld(fpid2i, rd, ea, 8, ufp);
- else
- fld(fpis2i, rd, ea, 4, ufp);
- }else{- if(op & (1<<15))
- fst(fpii2d, ea, rd, 8, ufp);
- else
- fst(fpii2s, ea, rd, 4, ufp);
- }
- if((op & (1<<24)) == 0)
- ea += off;
- if(op & (1<<21))
- REG(ur, rn) = ea;
- return;
- }
-
- /*
- * CPRT/transfer, 10.3
- */
- if(op & (1<<4)){- rd = (op>>12) & 0xF;
-
- /*
- * compare, 10.3.1
- */
- if(rd == 15 && op & (1<<20)){- rn = (op>>16)&7;
- fn = &FR(ufp, rn);
- if(op & (1<<3)){- fm = &fpconst[op&7];
- if(fpemudebug)
- tag = 'C';
- }else{- fm = &FR(ufp, op&7);
- if(fpemudebug)
- tag = 'F';
- }
- switch((op>>21)&7){- default:
- unimp(pc, op);
- case 4: /* CMF: Fn :: Fm */
- case 6: /* CMFE: Fn :: Fm (with exception) */
- ur->psr &= ~(N|C|Z|V);
- ur->psr |= fcmp(fn, fm);
- break;
- case 5: /* CNF: Fn :: -Fm */
- case 7: /* CNFE: Fn :: -Fm (with exception) */
- tmp = *fm;
- tmp.s ^= 1;
- ur->psr &= ~(N|C|Z|V);
- ur->psr |= fcmp(fn, &tmp);
- break;
- }
- if(fpemudebug)
- print("CMPF %c%d,F%ld =%#lux\n",- tag, rn, op&7, ur->psr>>28);
- return;
- }
-
- /*
- * other transfer, 10.3
- */
- switch((op>>20)&0xF){- default:
- unimp(pc, op);
- case 0: /* FLT */
- rn = (op>>16) & 7;
- fpiw2i(&FR(ufp, rn), ®(ur, rd));
- if(fpemudebug)
- print("MOVW[FD] R%d, F%d\n", rd, rn);- break;
- case 1: /* FIX */
- if(op & (1<<3))
- unimp(pc, op);
- rn = op & 7;
- tmp = FR(ufp, rn);
- fpii2w(®(ur, rd), &tmp);
- if(fpemudebug)
- print("MOV[FD]W F%d, R%d =%ld\n", rn, rd, REG(ur, rd));- break;
- case 2: /* FPSR := Rd */
- ufp->status = REG(ur, rd);
- if(fpemudebug)
- print("MOVW R%d, FPSR\n", rd);- break;
- case 3: /* Rd := FPSR */
- REG(ur, rd) = ufp->status;
- if(fpemudebug)
- print("MOVW FPSR, R%d\n", rd);- break;
- case 4: /* FPCR := Rd */
- ufp->control = REG(ur, rd);
- if(fpemudebug)
- print("MOVW R%d, FPCR\n", rd);- break;
- case 5: /* Rd := FPCR */
- REG(ur, rd) = ufp->control;
- if(fpemudebug)
- print("MOVW FPCR, R%d\n", rd);- break;
- }
- return;
- }
-
- /*
- * arithmetic
- */
-
- if(op & (1<<3)){ /* constant */- fm = &fpconst[op&7];
- if(fpemudebug)
- tag = 'C';
- }else{- fm = &FR(ufp, op&7);
- if(fpemudebug)
- tag = 'F';
- }
- rd = (op>>12)&7;
- o = (op>>20)&0xF;
- if(op & (1<<15)){ /* monadic */- FP1 *fp;
- fp = &optab1[o];
- if(fp->f == nil)
- unimp(pc, op);
- if(fpemudebug)
- print("%s %c%ld,F%d\n", fp->name, tag, op&7, rd);- (*fp->f)(fm, &FR(ufp, rd));
- } else {- FP2 *fp;
- fp = &optab2[o];
- if(fp->f == nil)
- unimp(pc, op);
- rn = (op>>16)&7;
- if(fpemudebug)
- print("%s %c%ld,F%d,F%d\n", fp->name, tag, op&7, rn, rd);- (*fp->f)(*fm, FR(ufp, rn), &FR(ufp, rd));
- }
-}
-
-static void
-vfpoptoi(Internal *fm, uchar o2, uchar o4)
-{- fm->s = o2>>3;
- fm->e = ((o2>>3) | ~(o2 & 4)) - 3 + ExpBias;
- fm->l = 0;
- fm->h = o4 << (20+NGuardBits);
- if(fm->e)
- fm->h |= HiddenBit;
- else
- fm->e++;
-}
-
-static void
-vfpemu(ulong pc, ulong op, Ureg *ur, FPsave *ufp)
-{- int sz, vd, o1, o2, o3, o4, o, tag;
- long off;
- ulong ea;
- Word w;
-
- Internal *fm, fc;
-
- /* note: would update fault status here if we noted numeric exceptions */
-
- sz = op & (1<<8);
- o1 = (op>>20) & 0xF;
- o2 = (op>>16) & 0xF;
- vd = (op>>12) & 0xF;
-
- switch((op>>24) & 0xF){- default:
- unimp(pc, op);
- case 0xD:
- /*
- * Extension Register load/store A7.6
- */
- off = (op&0xFF)<<2;
- if((op & (1<<23)) == 0)
- off = -off;
- ea = REG(ur, o2) + off;
- switch(o1&0x7){ /* D(Bit 22) = 0 (5l) */- default:
- unimp(pc, op);
- case 0:
- if(sz)
- fst(fpii2d, ea, vd, sz, ufp);
- else
- fst(fpii2s, ea, vd, sz, ufp);
- break;
- case 1:
- if(sz)
- fld(fpid2i, vd, ea, sz, ufp);
- else
- fld(fpis2i, vd, ea, sz, ufp);
- break;
- }
- break;
- case 0xE:
- if(op & (1<<4)){- /*
- * Register transfer between Core & Extension A7.8
- */
- if(sz) /* C(Bit 8) != 0 */
- unimp(pc, op);
- switch(o1){- default:
- unimp(pc, op);
- case 0: /* Fn := Rt */
- *((Word*)&FR(ufp, o2)) = REG(ur, vd);
- if(fpemudebug)
- print("MOVWF R%d, F%d\n", vd, o2);- break;
- case 1: /* Rt := Fn */
- REG(ur, vd) = *((Word*)&FR(ufp, o2));
- if(fpemudebug)
- print("MOVFW F%d, R%d =%ld\n", o2, vd, REG(ur, vd));- break;
- case 0xE: /* FPSCR := Rt */
- ufp->status = REG(ur, vd);
- if(fpemudebug)
- print("MOVW R%d, FPSCR\n", vd);- break;
- case 0xF: /* Rt := FPSCR */
- if(vd == 0xF){- ur->psr = ufp->status;
- if(fpemudebug)
- print("MOVW FPSCR, PSR\n");- }else{- REG(ur, vd) = ufp->status;
- if(fpemudebug)
- print("MOVW FPSCR, R%d\n", vd);- }
- break;
- }
- }
- else{- /*
- * VFP data processing instructions A7.5
- * Note: As per 5l we ignore (D, N, M) bits
- */
- if(fpemudebug)
- tag = 'F';
- o3 = (op>>6) & 0x3;
- o4 = op & 0xF;
- fm = &FR(ufp, o4);
-
- if(o1 == 0xB){ /* A7-17 */- if(o3 & 0x1){- switch(o2){- default:
- o = (o2<<1) | (o3>>1);
- break;
- case 0x8: /* CVT int -> float/double */
- w = *((Word*)fm);
- fpiw2i(&FR(ufp, vd), &w);
- if(fpemudebug)
- print("CVTW%c F%d, F%d\n", sz?'D':'F', o4, vd);- return;
- case 0xD: /* CVT float/double -> int */
- fpii2w(&w, fm);
- *((Word*)&FR(ufp, vd)) = w;
- if(fpemudebug)
- print("CVT%cW F%d, F%d\n", sz?'D':'F', o4, vd);- return;
- case 0x5: /* CMPF(E) */
- fm = &fpconst[0];
- if(fpemudebug)
- tag = 'C';
- case 0x4: /* CMPF(E) */
- ufp->status &= ~(N|C|Z|V);
- ufp->status |= fcmp(&FR(ufp, vd), fm);
- if(fpemudebug)
- print("CMPF %c%d,F%d =%#lux\n",- tag, (o2&0x1)? 0: o4, vd, ufp->status>>28);
- return;
- }
- }else{ /* VMOV imm (VFPv3 & v4) (5l doesn't generate) */- vfpoptoi(&fc, o2, o4);
- fm = &fc;
- o = 0;
- if(fpemudebug)
- tag = 'C';
- }
- FP1 *vfp;
- vfp = &voptab1[o];
- if(vfp->f == nil)
- unimp(pc, op);
- if(fpemudebug)
- print("%s %c%d,F%d\n", vfp->name, tag, o4, vd);- (*vfp->f)(fm, &FR(ufp, vd));
- }
- else { /* A7-16 */- FP2 *vfp;
- o = ((o1&0x3)<<1) | (o1&0x8) | (o3&0x1);
- vfp = &voptab2[o];
- if(vfp->f == nil)
- unimp(pc, op);
- if(fpemudebug)
- print("%s F%d,F%d,F%d\n", vfp->name, o4, o2, vd);- (*vfp->f)(*fm, FR(ufp, o2), &FR(ufp, vd));
- }
- }
- break;
- }
-}
-
-void
-casemu(ulong pc, ulong op, Ureg *ur)
-{- ulong *rp, ro, rn, *rd;
-
- USED(pc);
-
- rp = (ulong*)ur;
- ro = rp[op>>16 & 0x7];
- rn = rp[op>>0 & 0x7];
- rd = rp + (op>>12 & 0x7);
- rp = (ulong*)*rd;
- validaddr((uintptr)rp, 4, 1);
- splhi();
- if(*rd = (*rp == ro))
- *rp = rn;
- spllo();
-}
-
-int ldrexvalid;
-
-void
-ldrex(ulong pc, ulong op, Ureg *ur)
-{- ulong *rp, *rd, *addr;
-
- USED(pc);
-
- rp = (ulong*)ur;
- rd = rp + (op>>16 & 0x7);
- addr = (ulong*)*rd;
- validaddr((uintptr)addr, 4, 0);
- ldrexvalid = 1;
- rp[op>>12 & 0x7] = *addr;
- if(fpemudebug)
- print("ldrex, r%ld = [r%ld]@0x%8.8p = 0x%8.8lux",- op>>12 & 0x7, op>>16 & 0x7, addr, rp[op>>12 & 0x7]);
-}
-
-void
-strex(ulong pc, ulong op, Ureg *ur)
-{- ulong *rp, rn, *rd, *addr;
-
- USED(pc);
-
- rp = (ulong*)ur;
- rd = rp + (op>>16 & 0x7);
- rn = rp[op>>0 & 0x7];
- addr = (ulong*)*rd;
- validaddr((uintptr)addr, 4, 1);
- splhi();
- if(ldrexvalid){- if(fpemudebug)
- print("strex valid, [r%ld]@0x%8.8p = r%ld = 0x%8.8lux",- op>>16 & 0x7, addr, op>>0 & 0x7, rn);
- *addr = rn;
- ldrexvalid = 0;
- rp[op>>12 & 0x7] = 0;
- }else{- if(fpemudebug)
- print("strex invalid, r%ld = 1", op>>16 & 0x7);- rp[op>>12 & 0x7] = 1;
- }
- spllo();
-}
-
-struct {- ulong opc;
- ulong mask;
- void (*f)(ulong, ulong, Ureg*);
-} specialopc[] = {- { 0x01900f9f, 0x0ff00fff, ldrex },- { 0x01800f90, 0x0ff00ff0, strex },- { 0x0ed00100, 0x0ef08100, casemu },- { 0x00000000, 0x00000000, nil }-};
-
-/*
- * returns the number of FP instructions emulated
- */
-int
-fpiarm(Ureg *ur)
-{- ulong op, o, cp;
- FPsave *ufp;
- int i, n;
-
- if(up == nil)
- panic("fpiarm not in a process");- ufp = up->fpsave;
- /*
- * because all the emulated fp state is in the proc structure,
- * it need not be saved/restored
- */
- if(up->fpstate != FPactive){-// assert(sizeof(Internal) == sizeof(ufp->regs[0]));
- up->fpstate = FPactive;
- ufp->control = 0;
- ufp->status = (0x01<<28)|(1<<12); /* software emulation, alternative C flag */
- for(n = 0; n < Nfpctlregs; n++)
- FR(ufp, n) = fpconst[0];
- }
- for(n=0; ;n++){- validaddr(ur->pc, 4, 0);
- op = *(ulong*)(ur->pc);
- if(fpemudebug)
- print("%#lux: %#8.8lux ", ur->pc, op);- o = (op>>24) & 0xF;
- cp = (op>>8) & 0xF;
- for(i = 0; specialopc[i].f; i++)
- if((op & specialopc[i].mask) == specialopc[i].opc)
- break;
- if(specialopc[i].f){- if(condok(ur->psr, op>>28))
- specialopc[i].f(ur->pc, op, ur);
- }
- else if(ISVFPOP(cp, o)){- if(condok(ur->psr, op>>28))
- vfpemu(ur->pc, op, ur, ufp);
- }
- else if(ISFPAOP(cp, o)){- if(condok(ur->psr, op>>28))
- fpaemu(ur->pc, op, ur, ufp);
- }
- else
- break;
-
- ur->pc += 4; /* pretend cpu executed the instr */
- }
- if(fpemudebug)
- print("\n");- return n;
-}
--- a/sys/src/9/kw/fpimem.c
+++ /dev/null
@@ -1,136 +1,0 @@
-#include "fpi.h"
-
-/*
- * the following routines depend on memory format, not the machine
- */
-
-void
-fpis2i(Internal *i, void *v)
-{- Single *s = v;
-
- i->s = (*s & 0x80000000) ? 1: 0;
- if((*s & ~0x80000000) == 0){- SetZero(i);
- return;
- }
- i->e = ((*s>>23) & 0x00FF) - SingleExpBias + ExpBias;
- i->h = (*s & 0x007FFFFF)<<(1+NGuardBits);
- i->l = 0;
- if(i->e)
- i->h |= HiddenBit;
- else
- i->e++;
-}
-
-void
-fpid2i(Internal *i, void *v)
-{- Double *d = v;
-
- i->s = (d->h & 0x80000000) ? 1: 0;
- i->e = (d->h>>20) & 0x07FF;
- i->h = ((d->h & 0x000FFFFF)<<(4+NGuardBits))|((d->l>>25) & 0x7F);
- i->l = (d->l & 0x01FFFFFF)<<NGuardBits;
- if(i->e)
- i->h |= HiddenBit;
- else
- i->e++;
-}
-
-void
-fpiw2i(Internal *i, void *v)
-{- Word w, word = *(Word*)v;
- short e;
-
- if(word < 0){- i->s = 1;
- word = -word;
- }
- else
- i->s = 0;
- if(word == 0){- SetZero(i);
- return;
- }
- if(word > 0){- for (e = 0, w = word; w; w >>= 1, e++)
- ;
- } else
- e = 32;
- if(e > FractBits){- i->h = word>>(e - FractBits);
- i->l = (word & ((1<<(e - FractBits)) - 1))<<(2*FractBits - e);
- }
- else {- i->h = word<<(FractBits - e);
- i->l = 0;
- }
- i->e = (e - 1) + ExpBias;
-}
-
-void
-fpii2s(void *v, Internal *i)
-{- short e;
- Single *s = (Single*)v;
-
- fpiround(i);
- if(i->h & HiddenBit)
- i->h &= ~HiddenBit;
- else
- i->e--;
- *s = i->s ? 0x80000000: 0;
- e = i->e;
- if(e < ExpBias){- if(e <= (ExpBias - SingleExpBias))
- return;
- e = SingleExpBias - (ExpBias - e);
- }
- else if(e >= (ExpBias + (SingleExpMax-SingleExpBias))){- *s |= SingleExpMax<<23;
- return;
- }
- else
- e = SingleExpBias + (e - ExpBias);
- *s |= (e<<23)|(i->h>>(1+NGuardBits));
-}
-
-void
-fpii2d(void *v, Internal *i)
-{- Double *d = (Double*)v;
-
- fpiround(i);
- if(i->h & HiddenBit)
- i->h &= ~HiddenBit;
- else
- i->e--;
- i->l = ((i->h & GuardMask)<<25)|(i->l>>NGuardBits);
- i->h >>= NGuardBits;
- d->h = i->s ? 0x80000000: 0;
- d->h |= (i->e<<20)|((i->h & 0x00FFFFFF)>>4);
- d->l = (i->h<<28)|i->l;
-}
-
-void
-fpii2w(Word *word, Internal *i)
-{- Word w;
- short e;
-
- fpiround(i);
- e = (i->e - ExpBias) + 1;
- if(e <= 0)
- w = 0;
- else if(e > 31)
- w = 0x7FFFFFFF;
- else if(e > FractBits)
- w = (i->h<<(e - FractBits))|(i->l>>(2*FractBits - e));
- else
- w = i->h>>(FractBits-e);
- if(i->s)
- w = -w;
- *word = w;
-}
--- a/sys/src/9/kw/mkfile
+++ b/sys/src/9/kw/mkfile
@@ -124,7 +124,20 @@
archkw.$O devether.$O ether1116.$O ethermii.$O: \
../port/ethermii.h ../port/etherif.h ../port/netif.h
archkw.$O devflash.$O flashkw.$O: ../port/flashif.h
-fpi.$O fpiarm.$O fpimem.$O: fpi.h
+
+fpi.$O fpiarm.$O fpimem.$O: ../omap/fpi.h
+fpi.$O: ../omap/fpi.c
+ $CC $CFLAGS -. ../omap/fpi.c
+fpiarm.$O: ../omap/fpiarm.c
+ $CC $CFLAGS -. ../omap/fpiarm.c
+fpimem.$O: ../omap/fpimem.c
+ $CC $CFLAGS -. ../omap/fpimem.c
+
+softfpu.$O: ../omap/softfpu.c
+ $CC $CFLAGS -. ../omap/softfpu.c
+syscall.$O: ../omap/syscall.c
+ $CC $CFLAGS -. ../omap/syscall.c
+
l.$O lexception.$O lproc.$O mmu.$O rebootcode.$O: arm.s arm.h mem.h
main.$O: errstr.h rebootcode.i
mouse.$O: screen.h
--- a/sys/src/9/kw/softfpu.c
+++ /dev/null
@@ -1,104 +1,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-
-int
-fpudevprocio(Proc* proc, void* a, long n, uintptr offset, int write)
-{- /*
- * Called from procdevtab.read and procdevtab.write
- * allow user process access to the FPU registers.
- * This is the only FPU routine which is called directly
- * from the port code; it would be nice to have dynamic
- * creation of entries in the device file trees...
- */
- USED(proc, a, n, offset, write);
-
- return 0;
-}
-
-void
-fpunotify(void)
-{- /*
- * Called when a note is about to be delivered to a
- * user process, usually at the end of a system call.
- * Note handlers are not allowed to use the FPU so
- * the state is marked (after saving if necessary) and
- * checked in the Device Not Available handler.
- */
-}
-
-void
-fpunoted(void)
-{- /*
- * Called from sysnoted() via the machine-dependent
- * noted() routine.
- * Clear the flag set above in fpunotify().
- */
-}
-
-FPsave*
-notefpsave(Proc*)
-{- return nil;
-}
-
-void
-fpuprocsave(Proc*)
-{- /*
- * Called from sched() and sleep() via the machine-dependent
- * procsave() routine.
- * About to go in to the scheduler.
- * If the process wasn't using the FPU
- * there's nothing to do.
- */
-}
-
-void
-fpuprocrestore(Proc*)
-{- /*
- * The process has been rescheduled and is about to run.
- * Nothing to do here right now. If the process tries to use
- * the FPU again it will cause a Device Not Available
- * exception and the state will then be restored.
- */
-}
-
-void
-fpusysprocsetup(Proc*)
-{- /*
- * Disable the FPU.
- * Called from sysexec() via sysprocsetup() to
- * set the FPU for the new process.
- */
-}
-
-void
-fpuinit(void)
-{-}
-
-int
-fpuemu(Ureg* ureg)
-{- int nfp;
-
- if(waserror()){- splhi();
- postnote(up, 1, up->errstr, NDebug);
- return 1;
- }
- spllo();
- nfp = fpiarm(ureg);
- splhi();
- poperror();
-
- return nfp;
-}
--- a/sys/src/9/kw/syscall.c
+++ /dev/null
@@ -1,293 +1,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "../port/error.h"
-#include "../port/systab.h"
-
-#include <tos.h>
-#include "ureg.h"
-
-#include "arm.h"
-
-typedef struct {- uintptr ip;
- Ureg* arg0;
- char* arg1;
- char msg[ERRMAX];
- Ureg* old;
- Ureg ureg;
-} NFrame;
-
-/*
- * Return user to state before notify()
- */
-static void
-noted(Ureg* cur, uintptr arg0)
-{- NFrame *nf;
- Ureg *nur;
-
- qlock(&up->debug);
- if(arg0 != NRSTR && !up->notified){- qunlock(&up->debug);
- pprint("call to noted() when not notified\n");- pexit("Suicide", 0);- }
- up->notified = 0;
-
- splhi();
- fpunoted();
- spllo();
-
- nf = up->ureg;
-
- /* sanity clause */
- if(!okaddr((uintptr)nf, sizeof(NFrame), 0)){- qunlock(&up->debug);
- pprint("bad ureg in noted %#p\n", nf);- pexit("Suicide", 0);- }
-
- /* don't let user change system flags */
- nur = &nf->ureg;
- nur->psr &= PsrMask|PsrDfiq|PsrDirq;
- nur->psr |= (cur->psr & ~(PsrMask|PsrDfiq|PsrDirq));
-
- memmove(cur, nur, sizeof(Ureg));
-
- switch((int)arg0){- case NCONT:
- case NRSTR:
- if(!okaddr(nur->pc, BY2WD, 0) || !okaddr(nur->sp, BY2WD, 0)){- qunlock(&up->debug);
- pprint("suicide: trap in noted\n");- pexit("Suicide", 0);- }
- up->ureg = nf->old;
- qunlock(&up->debug);
- break;
- case NSAVE:
- if(!okaddr(nur->pc, BY2WD, 0) || !okaddr(nur->sp, BY2WD, 0)){- qunlock(&up->debug);
- pprint("suicide: trap in noted\n");- pexit("Suicide", 0);- }
- qunlock(&up->debug);
-
- splhi();
- nf->arg1 = nf->msg;
- nf->arg0 = &nf->ureg;
- nf->ip = 0;
- cur->sp = (uintptr)nf;
- cur->r0 = (uintptr)nf->arg0;
- break;
- default:
- up->lastnote->flag = NDebug;
- /*FALLTHROUGH*/
- case NDFLT:
- qunlock(&up->debug);
- if(up->lastnote->flag == NDebug)
- pprint("suicide: %s\n", up->lastnote->msg);- pexit(up->lastnote->msg, up->lastnote->flag != NDebug);
- }
-}
-
-/*
- * Call user, if necessary, with note.
- * Pass user the Ureg struct and the note on his stack.
- */
-int
-notify(Ureg* ureg)
-{- uintptr sp;
- NFrame *nf;
- char *msg;
-
- if(up->procctl)
- procctl();
- if(up->nnote == 0)
- return 0;
-
- spllo();
- qlock(&up->debug);
- msg = popnote(ureg);
- if(msg == nil){- qunlock(&up->debug);
- splhi();
- return 0;
- }
-
- if(!okaddr((uintptr)up->notify, 1, 0)){- qunlock(&up->debug);
- pprint("suicide: notify function address %#p\n", up->notify);- pexit("Suicide", 0);- }
-
- sp = ureg->sp - sizeof(NFrame);
- if(!okaddr(sp, sizeof(NFrame), 1)){- qunlock(&up->debug);
- pprint("suicide: notify stack address %#p\n", sp);- pexit("Suicide", 0);- }
-
- nf = (void*)sp;
- memmove(&nf->ureg, ureg, sizeof(Ureg));
- nf->old = up->ureg;
- up->ureg = nf;
- memmove(nf->msg, msg, ERRMAX);
- nf->arg1 = nf->msg;
- nf->arg0 = &nf->ureg;
- nf->ip = 0;
-
- ureg->sp = sp;
- ureg->pc = (uintptr)up->notify;
- ureg->r0 = (uintptr)nf->arg0;
-
- splhi();
- fpunotify();
- qunlock(&up->debug);
-
- return 1;
-}
-
-void
-syscall(Ureg* ureg)
-{- char *e;
- u32int s;
- ulong sp;
- long ret;
- int i, scallnr;
- vlong startns, stopns;
-
- if(!kenter(ureg))
- panic("syscall: from kernel: pc %#lux r14 %#lux psr %#lux",- ureg->pc, ureg->r14, ureg->psr);
-
- m->syscall++;
- up->insyscall = 1;
- up->pc = ureg->pc;
-
- scallnr = ureg->r0;
- up->scallnr = scallnr;
- spllo();
- sp = ureg->sp;
-
- up->nerrlab = 0;
- ret = -1;
- if(!waserror()){- if(sp < (USTKTOP-BY2PG) || sp > (USTKTOP-sizeof(Sargs)-BY2WD))
- validaddr(sp, sizeof(Sargs)+BY2WD, 0);
- up->s = *((Sargs*)(sp+BY2WD));
- if(up->procctl == Proc_tracesyscall){- syscallfmt(scallnr, ureg->pc, (va_list)up->s.args);
- s = splhi();
- up->procctl = Proc_stopme;
- procctl();
- splx(s);
- todget(nil, &startns);
- }
- if(scallnr >= nsyscall || systab[scallnr] == nil){- postnote(up, 1, "sys: bad sys call", NDebug);
- error(Ebadarg);
- }
- up->psstate = sysctab[scallnr];
- ret = systab[scallnr]((va_list)up->s.args);
- poperror();
- }else{- /* failure: save the error buffer for errstr */
- e = up->syserrstr;
- up->syserrstr = up->errstr;
- up->errstr = e;
- }
- if(up->nerrlab){- print("bad errstack [%d]: %d extra\n", scallnr, up->nerrlab);- for(i = 0; i < NERR; i++)
- print("sp=%#p pc=%#p\n",- up->errlab[i].sp, up->errlab[i].pc);
- panic("error stack");- }
-
- /*
- * Put return value in frame. On the x86 the syscall is
- * just another trap and the return value from syscall is
- * ignored. On other machines the return value is put into
- * the results register by caller of syscall.
- */
- ureg->r0 = ret;
-
- if(up->procctl == Proc_tracesyscall){- todget(nil, &stopns);
- sysretfmt(scallnr, (va_list)up->s.args, ret, startns, stopns);
- s = splhi();
- up->procctl = Proc_stopme;
- procctl();
- splx(s);
- }
-
- up->insyscall = 0;
- up->psstate = 0;
-
- if(scallnr == NOTED)
- noted(ureg, *((ulong*)up->s.args));
-
- splhi();
- if(scallnr != RFORK && (up->procctl || up->nnote))
- notify(ureg);
-
- /* if we delayed sched because we held a lock, sched now */
- if(up->delaysched)
- sched();
- kexit(ureg);
-}
-
-uintptr
-execregs(uintptr entry, ulong ssize, ulong nargs)
-{- ulong *sp;
- Ureg *ureg;
-
- sp = (ulong*)(USTKTOP - ssize);
- *--sp = nargs;
-
- ureg = up->dbgreg;
-// memset(ureg, 0, 15*sizeof(ulong));
- ureg->r13 = (ulong)sp;
- ureg->pc = entry;
-//print("%lud: EXECREGS pc %#ux sp %#ux nargs %ld\n", up->pid, ureg->pc, ureg->r13, nargs);-
- /*
- * return the address of kernel/user shared data
- * (e.g. clock stuff)
- */
- return USTKTOP-sizeof(Tos);
-}
-
-void
-sysprocsetup(Proc* p)
-{- fpusysprocsetup(p);
-}
-
-/*
- * Craft a return frame which will cause the child to pop out of
- * the scheduler in user mode with the return register zero. Set
- * pc to point to a l.s return function.
- */
-void
-forkchild(Proc *p, Ureg *ureg)
-{- Ureg *cureg;
-
-//print("%lud setting up for forking child %lud\n", up->pid, p->pid);- p->sched.sp = (ulong)p-sizeof(Ureg);
- p->sched.pc = (ulong)forkret;
-
- cureg = (Ureg*)(p->sched.sp);
- memmove(cureg, ureg, sizeof(Ureg));
-
- /* syscall returns 0 for child */
- cureg->r0 = 0;
-}
--- a/sys/src/9/omap/beagle
+++ b/sys/src/9/omap/beagle
@@ -59,7 +59,6 @@
rdb
coproc
dma
- mouse
# sdaoe sdscsi
softfpu
uarti8250
--- a/sys/src/9/omap/fpi.c
+++ b/sys/src/9/omap/fpi.c
@@ -2,7 +2,7 @@
* Floating Point Interpreter.
* shamelessly stolen from an original by ark.
*/
-#include "fpi.h"
+#include "../omap/fpi.h"
void
fpiround(Internal *i)
--- a/sys/src/9/omap/fpiarm.c
+++ b/sys/src/9/omap/fpiarm.c
@@ -13,7 +13,8 @@
#include "ureg.h"
#include "arm.h"
-#include "fpi.h"
+
+#include "../omap/fpi.h"
/* undef this if correct kernel r13 isn't in Ureg;
* check calculation in fpiarm below
--- a/sys/src/9/omap/fpimem.c
+++ b/sys/src/9/omap/fpimem.c
@@ -1,4 +1,4 @@
-#include "fpi.h"
+#include "../omap/fpi.h"
/*
* the following routines depend on memory format, not the machine
--- a/sys/src/9/omap/mkfile
+++ b/sys/src/9/omap/mkfile
@@ -33,6 +33,7 @@
qio.$O\
qlock.$O\
segment.$O\
+ syscallfmt.$O\
sysfile.$O\
sysproc.$O\
taslock.$O\
@@ -107,7 +108,7 @@
l.$O lexception.$O lproc.$O mmu.$O rebootcode.$O: arm.s arm.h mem.h
l.$O rebootcode.$O: cache.v7.s
main.$O: errstr.h rebootcode.i
-devdss.$O devmouse.$O mouse.$O screen.$O: screen.h
+devdss.$O devmouse.$O screen.$O: screen.h
devusb.$O: ../port/usb.h
usbehci.$O usbohci.$O usbuhci.$O: ../port/usb.h usbehci.h
--- a/sys/src/9/omap/mouse.c
+++ /dev/null
@@ -1,66 +1,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "../port/error.h"
-#include "io.h"
-
-#define Image IMAGE
-#include <draw.h>
-#include <memdraw.h>
-#include <cursor.h>
-#include "screen.h"
-
-static QLock mousectlqlock;
-static int accelerated;
-
-enum
-{- CMaccelerated,
- CMlinear,
-};
-
-static Cmdtab mousectlmsg[] =
-{- CMaccelerated, "accelerated", 0,
- CMlinear, "linear", 1,
-};
-
-
-static void
-setaccelerated(int x)
-{- accelerated = x;
- mouseaccelerate(x);
-}
-
-static void
-setlinear(void)
-{- accelerated = 0;
- mouseaccelerate(0);
-}
-
-void
-mousectl(Cmdbuf *cb)
-{- Cmdtab *ct;
-
- qlock(&mousectlqlock);
- if(waserror()){- qunlock(&mousectlqlock);
- nexterror();
- }
- ct = lookupcmd(cb, mousectlmsg, nelem(mousectlmsg));
- switch(ct->index){- case CMaccelerated:
- setaccelerated(cb->nf == 1? 1: atoi(cb->f[1]));
- break;
- case CMlinear:
- setlinear();
- break;
- }
- qunlock(&mousectlqlock);
- poperror();
-}
--- a/sys/src/9/omap/screen.c
+++ b/sys/src/9/omap/screen.c
@@ -313,6 +313,33 @@
}
/* called from devmouse */
+enum
+{+ CMaccelerated,
+ CMlinear,
+};
+
+static Cmdtab mousectlmsg[] =
+{+ CMaccelerated, "accelerated", 0,
+ CMlinear, "linear", 1,
+};
+
+void
+mousectl(Cmdbuf *cb)
+{+ Cmdtab *ct;
+
+ ct = lookupcmd(cb, mousectlmsg, nelem(mousectlmsg));
+ switch(ct->index){+ case CMaccelerated:
+ mouseaccelerate(cb->nf == 1? 1: atoi(cb->f[1]));
+ break;
+ case CMlinear:
+ mouseaccelerate(0);
+ break;
+ }
+}
void
cursoron(void)
--- a/sys/src/9/teg2/fns.h
+++ b/sys/src/9/teg2/fns.h
@@ -142,6 +142,7 @@
extern int fpiarm(Ureg*);
extern int fpudevprocio(Proc*, void*, long, uintptr, int);
+extern FPalloc *fpalloc(void);
extern void fpuinit(void);
extern void fpunoted(void);
extern void fpunotify(void);
--- a/sys/src/9/teg2/fpi.c
+++ /dev/null
@@ -1,300 +1,0 @@
-/*
- * Floating Point Interpreter.
- * shamelessly stolen from an original by ark.
- */
-#include "fpi.h"
-
-void
-fpiround(Internal *i)
-{- unsigned long guard;
-
- guard = i->l & GuardMask;
- i->l &= ~GuardMask;
- if(guard > (LsBit>>1) || (guard == (LsBit>>1) && (i->l & LsBit))){- i->l += LsBit;
- if(i->l & CarryBit){- i->l &= ~CarryBit;
- i->h++;
- if(i->h & CarryBit){- if (i->h & 0x01)
- i->l |= CarryBit;
- i->l >>= 1;
- i->h >>= 1;
- i->e++;
- }
- }
- }
-}
-
-static void
-matchexponents(Internal *x, Internal *y)
-{- int count;
-
- count = y->e - x->e;
- x->e = y->e;
- if(count >= 2*FractBits){- x->l = x->l || x->h;
- x->h = 0;
- return;
- }
- if(count >= FractBits){- count -= FractBits;
- x->l = x->h|(x->l != 0);
- x->h = 0;
- }
- while(count > 0){- count--;
- if(x->h & 0x01)
- x->l |= CarryBit;
- if(x->l & 0x01)
- x->l |= 2;
- x->l >>= 1;
- x->h >>= 1;
- }
-}
-
-static void
-shift(Internal *i)
-{- i->e--;
- i->h <<= 1;
- i->l <<= 1;
- if(i->l & CarryBit){- i->l &= ~CarryBit;
- i->h |= 0x01;
- }
-}
-
-static void
-normalise(Internal *i)
-{- while((i->h & HiddenBit) == 0)
- shift(i);
-}
-
-static void
-renormalise(Internal *i)
-{- if(i->e < -2 * FractBits)
- i->e = -2 * FractBits;
- while(i->e < 1){- i->e++;
- if(i->h & 0x01)
- i->l |= CarryBit;
- i->h >>= 1;
- i->l = (i->l>>1)|(i->l & 0x01);
- }
- if(i->e >= ExpInfinity)
- SetInfinity(i);
-}
-
-void
-fpinormalise(Internal *x)
-{- if(!IsWeird(x) && !IsZero(x))
- normalise(x);
-}
-
-void
-fpiadd(Internal *x, Internal *y, Internal *i)
-{- Internal *t;
-
- i->s = x->s;
- if(IsWeird(x) || IsWeird(y)){- if(IsNaN(x) || IsNaN(y))
- SetQNaN(i);
- else
- SetInfinity(i);
- return;
- }
- if(x->e > y->e){- t = x;
- x = y;
- y = t;
- }
- matchexponents(x, y);
- i->e = x->e;
- i->h = x->h + y->h;
- i->l = x->l + y->l;
- if(i->l & CarryBit){- i->h++;
- i->l &= ~CarryBit;
- }
- if(i->h & (HiddenBit<<1)){- if(i->h & 0x01)
- i->l |= CarryBit;
- i->l = (i->l>>1)|(i->l & 0x01);
- i->h >>= 1;
- i->e++;
- }
- if(IsWeird(i))
- SetInfinity(i);
-}
-
-void
-fpisub(Internal *x, Internal *y, Internal *i)
-{- Internal *t;
-
- if(y->e < x->e
- || (y->e == x->e && (y->h < x->h || (y->h == x->h && y->l < x->l)))){- t = x;
- x = y;
- y = t;
- }
- i->s = y->s;
- if(IsNaN(y)){- SetQNaN(i);
- return;
- }
- if(IsInfinity(y)){- if(IsInfinity(x))
- SetQNaN(i);
- else
- SetInfinity(i);
- return;
- }
- matchexponents(x, y);
- i->e = y->e;
- i->h = y->h - x->h;
- i->l = y->l - x->l;
- if(i->l < 0){- i->l += CarryBit;
- i->h--;
- }
- if(i->h == 0 && i->l == 0)
- SetZero(i);
- else while(i->e > 1 && (i->h & HiddenBit) == 0)
- shift(i);
-}
-
-#define CHUNK (FractBits/2)
-#define CMASK ((1<<CHUNK)-1)
-#define HI(x) ((short)((x)>>CHUNK) & CMASK)
-#define LO(x) ((short)(x) & CMASK)
-#define SPILL(x) ((x)>>CHUNK)
-#define M(x, y) ((long)a[x]*(long)b[y])
-#define C(h, l) (((long)((h) & CMASK)<<CHUNK)|((l) & CMASK))
-
-void
-fpimul(Internal *x, Internal *y, Internal *i)
-{- long a[4], b[4], c[7], f[4];
-
- i->s = x->s^y->s;
- if(IsWeird(x) || IsWeird(y)){- if(IsNaN(x) || IsNaN(y) || IsZero(x) || IsZero(y))
- SetQNaN(i);
- else
- SetInfinity(i);
- return;
- }
- else if(IsZero(x) || IsZero(y)){- SetZero(i);
- return;
- }
- normalise(x);
- normalise(y);
- i->e = x->e + y->e - (ExpBias - 1);
-
- a[0] = HI(x->h); b[0] = HI(y->h);
- a[1] = LO(x->h); b[1] = LO(y->h);
- a[2] = HI(x->l); b[2] = HI(y->l);
- a[3] = LO(x->l); b[3] = LO(y->l);
-
- c[6] = M(3, 3);
- c[5] = M(2, 3) + M(3, 2) + SPILL(c[6]);
- c[4] = M(1, 3) + M(2, 2) + M(3, 1) + SPILL(c[5]);
- c[3] = M(0, 3) + M(1, 2) + M(2, 1) + M(3, 0) + SPILL(c[4]);
- c[2] = M(0, 2) + M(1, 1) + M(2, 0) + SPILL(c[3]);
- c[1] = M(0, 1) + M(1, 0) + SPILL(c[2]);
- c[0] = M(0, 0) + SPILL(c[1]);
-
- f[0] = c[0];
- f[1] = C(c[1], c[2]);
- f[2] = C(c[3], c[4]);
- f[3] = C(c[5], c[6]);
-
- if((f[0] & HiddenBit) == 0){- f[0] <<= 1;
- f[1] <<= 1;
- f[2] <<= 1;
- f[3] <<= 1;
- if(f[1] & CarryBit){- f[0] |= 1;
- f[1] &= ~CarryBit;
- }
- if(f[2] & CarryBit){- f[1] |= 1;
- f[2] &= ~CarryBit;
- }
- if(f[3] & CarryBit){- f[2] |= 1;
- f[3] &= ~CarryBit;
- }
- i->e--;
- }
- i->h = f[0];
- i->l = f[1];
- if(f[2] || f[3])
- i->l |= 1;
- renormalise(i);
-}
-
-void
-fpidiv(Internal *x, Internal *y, Internal *i)
-{- i->s = x->s^y->s;
- if(IsNaN(x) || IsNaN(y)
- || (IsInfinity(x) && IsInfinity(y)) || (IsZero(x) && IsZero(y))){- SetQNaN(i);
- return;
- }
- else if(IsZero(x) || IsInfinity(y)){- SetInfinity(i);
- return;
- }
- else if(IsInfinity(x) || IsZero(y)){- SetZero(i);
- return;
- }
- normalise(x);
- normalise(y);
- i->h = 0;
- i->l = 0;
- i->e = y->e - x->e + (ExpBias + 2*FractBits - 1);
- do{- if(y->h > x->h || (y->h == x->h && y->l >= x->l)){- i->l |= 0x01;
- y->h -= x->h;
- y->l -= x->l;
- if(y->l < 0){- y->l += CarryBit;
- y->h--;
- }
- }
- shift(y);
- shift(i);
- }while ((i->h & HiddenBit) == 0);
- if(y->h || y->l)
- i->l |= 0x01;
- renormalise(i);
-}
-
-int
-fpicmp(Internal *x, Internal *y)
-{- if(IsNaN(x) && IsNaN(y))
- return 0;
- if(IsInfinity(x) && IsInfinity(y))
- return y->s - x->s;
- if(x->e == y->e && x->h == y->h && x->l == y->l)
- return y->s - x->s;
- if(x->e < y->e
- || (x->e == y->e && (x->h < y->h || (x->h == y->h && x->l < y->l))))
- return y->s ? 1: -1;
- return x->s ? -1: 1;
-}
--- a/sys/src/9/teg2/fpi.h
+++ /dev/null
@@ -1,61 +1,0 @@
-typedef long Word;
-typedef unsigned long Single;
-typedef struct {- unsigned long l;
- unsigned long h;
-} Double;
-
-enum {- FractBits = 28,
- CarryBit = 0x10000000,
- HiddenBit = 0x08000000,
- MsBit = HiddenBit,
- NGuardBits = 3,
- GuardMask = 0x07,
- LsBit = (1<<NGuardBits),
-
- SingleExpBias = 127,
- SingleExpMax = 255,
- DoubleExpBias = 1023,
- DoubleExpMax = 2047,
-
- ExpBias = DoubleExpBias,
- ExpInfinity = DoubleExpMax,
-};
-
-typedef struct {- unsigned char s;
- short e;
- long l; /* 0000FFFFFFFFFFFFFFFFFFFFFFFFFGGG */
- long h; /* 0000HFFFFFFFFFFFFFFFFFFFFFFFFFFF */
-} Internal;
-
-#define IsWeird(n) ((n)->e >= ExpInfinity)
-#define IsInfinity(n) (IsWeird(n) && (n)->h == HiddenBit && (n)->l == 0)
-#define SetInfinity(n) ((n)->e = ExpInfinity, (n)->h = HiddenBit, (n)->l = 0)
-#define IsNaN(n) (IsWeird(n) && (((n)->h & ~HiddenBit) || (n)->l))
-#define SetQNaN(n) ((n)->s = 0, (n)->e = ExpInfinity, \
- (n)->h = HiddenBit|(LsBit<<1), (n)->l = 0)
-#define IsZero(n) ((n)->e == 1 && (n)->h == 0 && (n)->l == 0)
-#define SetZero(n) ((n)->e = 1, (n)->h = 0, (n)->l = 0)
-
-/*
- * fpi.c
- */
-extern void fpiround(Internal *);
-extern void fpiadd(Internal *, Internal *, Internal *);
-extern void fpisub(Internal *, Internal *, Internal *);
-extern void fpimul(Internal *, Internal *, Internal *);
-extern void fpidiv(Internal *, Internal *, Internal *);
-extern int fpicmp(Internal *, Internal *);
-extern void fpinormalise(Internal*);
-
-/*
- * fpimem.c
- */
-extern void fpis2i(Internal *, void *);
-extern void fpid2i(Internal *, void *);
-extern void fpiw2i(Internal *, void *);
-extern void fpii2s(void *, Internal *);
-extern void fpii2d(void *, Internal *);
-extern void fpii2w(Word *, Internal *);
--- a/sys/src/9/teg2/fpiarm.c
+++ /dev/null
@@ -1,691 +1,0 @@
-/*
- * this doesn't attempt to implement ARM floating-point properties
- * that aren't visible in the Inferno environment.
- * all arithmetic is done in double precision.
- * the FP trap status isn't updated.
- */
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-
-#include "ureg.h"
-
-#include "arm.h"
-#include "fpi.h"
-
-/* undef this if correct kernel r13 isn't in Ureg;
- * check calculation in fpiarm below
- */
-#define REG(ur, x) (*(long*)(((char*)(ur))+roff[(x)]))
-#define FR(ufp, x) (*(Internal*)(ufp)->regs[(x)&(Nfpctlregs - 1)])
-
-typedef struct FP2 FP2;
-typedef struct FP1 FP1;
-
-struct FP2 {- char* name;
- void (*f)(Internal, Internal, Internal*);
-};
-
-struct FP1 {- char* name;
- void (*f)(Internal*, Internal*);
-};
-
-enum {- N = 1<<31,
- Z = 1<<30,
- C = 1<<29,
- V = 1<<28,
- REGPC = 15,
-};
-
-enum {- fpemudebug = 0,
-};
-
-#undef OFR
-#define OFR(X) ((ulong)&((Ureg*)0)->X)
-
-static int roff[] = {- OFR(r0), OFR(r1), OFR(r2), OFR(r3),
- OFR(r4), OFR(r5), OFR(r6), OFR(r7),
- OFR(r8), OFR(r9), OFR(r10), OFR(r11),
- OFR(r12), OFR(r13), OFR(r14), OFR(pc),
-};
-
-static Internal fpconst[8] = { /* indexed by op&7 (ARM 7500 FPA) */- /* s, e, l, h */
- {0, 0x1, 0x00000000, 0x00000000}, /* 0.0 */- {0, 0x3FF, 0x00000000, 0x08000000}, /* 1.0 */- {0, 0x400, 0x00000000, 0x08000000}, /* 2.0 */- {0, 0x400, 0x00000000, 0x0C000000}, /* 3.0 */- {0, 0x401, 0x00000000, 0x08000000}, /* 4.0 */- {0, 0x401, 0x00000000, 0x0A000000}, /* 5.0 */- {0, 0x3FE, 0x00000000, 0x08000000}, /* 0.5 */- {0, 0x402, 0x00000000, 0x0A000000}, /* 10.0 */-};
-
-/*
- * arm binary operations
- */
-
-static void
-fadd(Internal m, Internal n, Internal *d)
-{- (m.s == n.s? fpiadd: fpisub)(&m, &n, d);
-}
-
-static void
-fsub(Internal m, Internal n, Internal *d)
-{- m.s ^= 1;
- (m.s == n.s? fpiadd: fpisub)(&m, &n, d);
-}
-
-static void
-fsubr(Internal m, Internal n, Internal *d)
-{- n.s ^= 1;
- (n.s == m.s? fpiadd: fpisub)(&n, &m, d);
-}
-
-static void
-fmul(Internal m, Internal n, Internal *d)
-{- fpimul(&m, &n, d);
-}
-
-static void
-fdiv(Internal m, Internal n, Internal *d)
-{- fpidiv(&m, &n, d);
-}
-
-static void
-fdivr(Internal m, Internal n, Internal *d)
-{- fpidiv(&n, &m, d);
-}
-
-/*
- * arm unary operations
- */
-
-static void
-fmov(Internal *m, Internal *d)
-{- *d = *m;
-}
-
-static void
-fmovn(Internal *m, Internal *d)
-{- *d = *m;
- d->s ^= 1;
-}
-
-static void
-fabsf(Internal *m, Internal *d)
-{- *d = *m;
- d->s = 0;
-}
-
-static void
-frnd(Internal *m, Internal *d)
-{- short e;
-
- (m->s? fsub: fadd)(fpconst[6], *m, d);
- if(IsWeird(d))
- return;
- fpiround(d);
- e = (d->e - ExpBias) + 1;
- if(e <= 0)
- SetZero(d);
- else if(e > FractBits){- if(e < 2*FractBits)
- d->l &= ~((1<<(2*FractBits - e))-1);
- }else{- d->l = 0;
- if(e < FractBits)
- d->h &= ~((1<<(FractBits-e))-1);
- }
-}
-
-/*
- * ARM 7500 FPA opcodes
- */
-
-static FP1 optab1[16] = { /* Fd := OP Fm */-[0] {"MOVF", fmov},-[1] {"NEGF", fmovn},-[2] {"ABSF", fabsf},-[3] {"RNDF", frnd},-[4] {"SQTF", /*fsqt*/0},-/* LOG, LGN, EXP, SIN, COS, TAN, ASN, ACS, ATN all `deprecated' */
-/* URD and NRM aren't implemented */
-};
-
-static FP2 optab2[16] = { /* Fd := Fn OP Fm */-[0] {"ADDF", fadd},-[1] {"MULF", fmul},-[2] {"SUBF", fsub},-[3] {"RSUBF", fsubr},-[4] {"DIVF", fdiv},-[5] {"RDIVF", fdivr},-/* POW, RPW deprecated */
-[8] {"REMF", /*frem*/0},-[9] {"FMF", fmul}, /* fast multiply */-[10] {"FDV", fdiv}, /* fast divide */-[11] {"FRD", fdivr}, /* fast reverse divide */-/* POL deprecated */
-};
-
-/*
- * ARM VFP opcodes
- */
-
-static FP1 voptab1[32] = { /* Vd := OP Vm */-[0] {"MOVF", fmov},-[1] {"ABSF", fabsf},-[2] {"NEGF", fmovn},-[15] {"CVTF", fmov},-};
-
-static FP2 voptab2[16] = { /* Vd := Vn FOP Fm */-[4] {"MULF", fmul},-[6] {"ADDF", fadd},-[7] {"SUBF", fsub},-[8] {"DIVF", fdiv},-};
-
-static ulong
-fcmp(Internal *n, Internal *m)
-{- int i;
- Internal rm, rn;
-
- if(IsWeird(m) || IsWeird(n)){- /* BUG: should trap if not masked */
- return V|C;
- }
- rn = *n;
- rm = *m;
- fpiround(&rn);
- fpiround(&rm);
- i = fpicmp(&rn, &rm);
- if(i > 0)
- return C;
- else if(i == 0)
- return C|Z;
- else
- return N;
-}
-
-static void
-fld(void (*f)(Internal*, void*), int d, ulong ea, int n, FPsave *ufp)
-{- void *mem;
-
- mem = (void*)ea;
- (*f)(&FR(ufp, d), mem);
- if(fpemudebug)
- print("MOV%c #%lux, F%d\n", n==8? 'D': 'F', ea, d);-}
-
-static void
-fst(void (*f)(void*, Internal*), ulong ea, int s, int n, FPsave *ufp)
-{- Internal tmp;
- void *mem;
-
- mem = (void*)ea;
- tmp = FR(ufp, s);
- if(fpemudebug)
- print("MOV%c F%d,#%lux\n", n==8? 'D': 'F', s, ea);- (*f)(mem, &tmp);
-}
-
-static int
-condok(int cc, int c)
-{- switch(c){- case 0: /* Z set */
- return cc&Z;
- case 1: /* Z clear */
- return (cc&Z) == 0;
- case 2: /* C set */
- return cc&C;
- case 3: /* C clear */
- return (cc&C) == 0;
- case 4: /* N set */
- return cc&N;
- case 5: /* N clear */
- return (cc&N) == 0;
- case 6: /* V set */
- return cc&V;
- case 7: /* V clear */
- return (cc&V) == 0;
- case 8: /* C set and Z clear */
- return cc&C && (cc&Z) == 0;
- case 9: /* C clear or Z set */
- return (cc&C) == 0 || cc&Z;
- case 10: /* N set and V set, or N clear and V clear */
- return (~cc&(N|V))==0 || (cc&(N|V)) == 0;
- case 11: /* N set and V clear, or N clear and V set */
- return (cc&(N|V))==N || (cc&(N|V))==V;
- case 12: /* Z clear, and either N set and V set or N clear and V clear */
- return (cc&Z) == 0 && ((~cc&(N|V))==0 || (cc&(N|V))==0);
- case 13: /* Z set, or N set and V clear or N clear and V set */
- return (cc&Z) || (cc&(N|V))==N || (cc&(N|V))==V;
- case 14: /* always */
- return 1;
- case 15: /* never (reserved) */
- return 0;
- }
- return 0; /* not reached */
-}
-
-static void
-unimp(ulong pc, ulong op)
-{- char buf[60];
-
- snprint(buf, sizeof(buf), "sys: fp: pc=%lux unimp fp 0x%.8lux", pc, op);
- if(fpemudebug)
- print("FPE: %s\n", buf);- error(buf);
- /* no return */
-}
-
-static void
-fpaemu(ulong pc, ulong op, Ureg *ur, FPsave *ufp)
-{- int rn, rd, tag, o;
- long off;
- ulong ea;
- Internal tmp, *fm, *fn;
-
- /* note: would update fault status here if we noted numeric exceptions */
-
- /*
- * LDF, STF; 10.1.1
- */
- if(((op>>25)&7) == 6){- if(op & (1<<22))
- unimp(pc, op); /* packed or extended */
- rn = (op>>16)&0xF;
- off = (op&0xFF)<<2;
- if((op & (1<<23)) == 0)
- off = -off;
- ea = REG(ur, rn);
- if(rn == REGPC)
- ea += 8;
- if(op & (1<<24))
- ea += off;
- rd = (op>>12)&7;
- if(op & (1<<20)){- if(op & (1<<15))
- fld(fpid2i, rd, ea, 8, ufp);
- else
- fld(fpis2i, rd, ea, 4, ufp);
- }else{- if(op & (1<<15))
- fst(fpii2d, ea, rd, 8, ufp);
- else
- fst(fpii2s, ea, rd, 4, ufp);
- }
- if((op & (1<<24)) == 0)
- ea += off;
- if(op & (1<<21))
- REG(ur, rn) = ea;
- return;
- }
-
- /*
- * CPRT/transfer, 10.3
- */
- if(op & (1<<4)){- rd = (op>>12) & 0xF;
-
- /*
- * compare, 10.3.1
- */
- if(rd == 15 && op & (1<<20)){- rn = (op>>16)&7;
- fn = &FR(ufp, rn);
- if(op & (1<<3)){- fm = &fpconst[op&7];
- if(fpemudebug)
- tag = 'C';
- }else{- fm = &FR(ufp, op&7);
- if(fpemudebug)
- tag = 'F';
- }
- switch((op>>21)&7){- default:
- unimp(pc, op);
- case 4: /* CMF: Fn :: Fm */
- case 6: /* CMFE: Fn :: Fm (with exception) */
- ur->psr &= ~(N|C|Z|V);
- ur->psr |= fcmp(fn, fm);
- break;
- case 5: /* CNF: Fn :: -Fm */
- case 7: /* CNFE: Fn :: -Fm (with exception) */
- tmp = *fm;
- tmp.s ^= 1;
- ur->psr &= ~(N|C|Z|V);
- ur->psr |= fcmp(fn, &tmp);
- break;
- }
- if(fpemudebug)
- print("CMPF %c%d,F%ld =%#lux\n",- tag, rn, op&7, ur->psr>>28);
- return;
- }
-
- /*
- * other transfer, 10.3
- */
- switch((op>>20)&0xF){- default:
- unimp(pc, op);
- case 0: /* FLT */
- rn = (op>>16) & 7;
- fpiw2i(&FR(ufp, rn), ®(ur, rd));
- if(fpemudebug)
- print("MOVW[FD] R%d, F%d\n", rd, rn);- break;
- case 1: /* FIX */
- if(op & (1<<3))
- unimp(pc, op);
- rn = op & 7;
- tmp = FR(ufp, rn);
- fpii2w(®(ur, rd), &tmp);
- if(fpemudebug)
- print("MOV[FD]W F%d, R%d =%ld\n", rn, rd, REG(ur, rd));- break;
- case 2: /* FPSR := Rd */
- ufp->status = REG(ur, rd);
- if(fpemudebug)
- print("MOVW R%d, FPSR\n", rd);- break;
- case 3: /* Rd := FPSR */
- REG(ur, rd) = ufp->status;
- if(fpemudebug)
- print("MOVW FPSR, R%d\n", rd);- break;
- case 4: /* FPCR := Rd */
- ufp->control = REG(ur, rd);
- if(fpemudebug)
- print("MOVW R%d, FPCR\n", rd);- break;
- case 5: /* Rd := FPCR */
- REG(ur, rd) = ufp->control;
- if(fpemudebug)
- print("MOVW FPCR, R%d\n", rd);- break;
- }
- return;
- }
-
- /*
- * arithmetic
- */
-
- if(op & (1<<3)){ /* constant */- fm = &fpconst[op&7];
- if(fpemudebug)
- tag = 'C';
- }else{- fm = &FR(ufp, op&7);
- if(fpemudebug)
- tag = 'F';
- }
- rd = (op>>12)&7;
- o = (op>>20)&0xF;
- if(op & (1<<15)){ /* monadic */- FP1 *fp;
- fp = &optab1[o];
- if(fp->f == nil)
- unimp(pc, op);
- if(fpemudebug)
- print("%s %c%ld,F%d\n", fp->name, tag, op&7, rd);- (*fp->f)(fm, &FR(ufp, rd));
- } else {- FP2 *fp;
- fp = &optab2[o];
- if(fp->f == nil)
- unimp(pc, op);
- rn = (op>>16)&7;
- if(fpemudebug)
- print("%s %c%ld,F%d,F%d\n", fp->name, tag, op&7, rn, rd);- (*fp->f)(*fm, FR(ufp, rn), &FR(ufp, rd));
- }
-}
-
-static void
-vfpoptoi(Internal *fm, uchar o2, uchar o4)
-{- fm->s = o2>>3;
- fm->e = ((o2>>3) | ~(o2 & 4)) - 3 + ExpBias;
- fm->l = 0;
- fm->h = o4 << (20+NGuardBits);
- if(fm->e)
- fm->h |= HiddenBit;
- else
- fm->e++;
-}
-
-static void
-vfpemu(ulong pc, ulong op, Ureg *ur, FPsave *ufp)
-{- int sz, vd, o1, o2, o3, o4, o, tag;
- long off;
- ulong ea;
- Word w;
-
- Internal *fm, fc;
-
- /* note: would update fault status here if we noted numeric exceptions */
-
- sz = op & (1<<8);
- o1 = (op>>20) & 0xF;
- o2 = (op>>16) & 0xF;
- vd = (op>>12) & 0xF;
-
- switch((op>>24) & 0xF){- default:
- unimp(pc, op);
- case 0xD:
- /*
- * Extension Register load/store A7.6
- */
- off = (op&0xFF)<<2;
- if((op & (1<<23)) == 0)
- off = -off;
- ea = REG(ur, o2) + off;
- switch(o1&0x7){ /* D(Bit 22) = 0 (5l) */- default:
- unimp(pc, op);
- case 0:
- if(sz)
- fst(fpii2d, ea, vd, sz, ufp);
- else
- fst(fpii2s, ea, vd, sz, ufp);
- break;
- case 1:
- if(sz)
- fld(fpid2i, vd, ea, sz, ufp);
- else
- fld(fpis2i, vd, ea, sz, ufp);
- break;
- }
- break;
- case 0xE:
- if(op & (1<<4)){- /*
- * Register transfer between Core & Extension A7.8
- */
- if(sz) /* C(Bit 8) != 0 */
- unimp(pc, op);
- switch(o1){- default:
- unimp(pc, op);
- case 0: /* Fn := Rt */
- *((Word*)&FR(ufp, o2)) = REG(ur, vd);
- if(fpemudebug)
- print("MOVWF R%d, F%d\n", vd, o2);- break;
- case 1: /* Rt := Fn */
- REG(ur, vd) = *((Word*)&FR(ufp, o2));
- if(fpemudebug)
- print("MOVFW F%d, R%d =%ld\n", o2, vd, REG(ur, vd));- break;
- case 0xE: /* FPSCR := Rt */
- ufp->status = REG(ur, vd);
- if(fpemudebug)
- print("MOVW R%d, FPSCR\n", vd);- break;
- case 0xF: /* Rt := FPSCR */
- if(vd == 0xF){- ur->psr = ufp->status;
- if(fpemudebug)
- print("MOVW FPSCR, PSR\n");- }else{- REG(ur, vd) = ufp->status;
- if(fpemudebug)
- print("MOVW FPSCR, R%d\n", vd);- }
- break;
- }
- }
- else{- /*
- * VFP data processing instructions A7.5
- * Note: As per 5l we ignore (D, N, M) bits
- */
- if(fpemudebug)
- tag = 'F';
- o3 = (op>>6) & 0x3;
- o4 = op & 0xF;
- fm = &FR(ufp, o4);
-
- if(o1 == 0xB){ /* A7-17 */- if(o3 & 0x1){- switch(o2){- default:
- o = (o2<<1) | (o3>>1);
- break;
- case 0x8: /* CVT int -> float/double */
- w = *((Word*)fm);
- fpiw2i(&FR(ufp, vd), &w);
- if(fpemudebug)
- print("CVTW%c F%d, F%d\n", sz?'D':'F', o4, vd);- return;
- case 0xD: /* CVT float/double -> int */
- fpii2w(&w, fm);
- *((Word*)&FR(ufp, vd)) = w;
- if(fpemudebug)
- print("CVT%cW F%d, F%d\n", sz?'D':'F', o4, vd);- return;
- case 0x5: /* CMPF(E) */
- fm = &fpconst[0];
- if(fpemudebug)
- tag = 'C';
- case 0x4: /* CMPF(E) */
- ufp->status &= ~(N|C|Z|V);
- ufp->status |= fcmp(&FR(ufp, vd), fm);
- if(fpemudebug)
- print("CMPF %c%d,F%d =%#lux\n",- tag, (o2&0x1)? 0: o4, vd, ufp->status>>28);
- return;
- }
- }else{ /* VMOV imm (VFPv3 & v4) (5l doesn't generate) */- vfpoptoi(&fc, o2, o4);
- fm = &fc;
- o = 0;
- if(fpemudebug)
- tag = 'C';
- }
- FP1 *vfp;
- vfp = &voptab1[o];
- if(vfp->f == nil)
- unimp(pc, op);
- if(fpemudebug)
- print("%s %c%d,F%d\n", vfp->name, tag, o4, vd);- (*vfp->f)(fm, &FR(ufp, vd));
- }
- else { /* A7-16 */- FP2 *vfp;
- o = ((o1&0x3)<<1) | (o1&0x8) | (o3&0x1);
- vfp = &voptab2[o];
- if(vfp->f == nil)
- unimp(pc, op);
- if(fpemudebug)
- print("%s F%d,F%d,F%d\n", vfp->name, o4, o2, vd);- (*vfp->f)(*fm, FR(ufp, o2), &FR(ufp, vd));
- }
- }
- break;
- }
-}
-
-
-/*
- * returns the number of FP instructions emulated
- */
-int
-fpiarm(Ureg *ur)
-{- ulong op, o, cp;
- FPsave *ufp;
- int n;
- void (*fpemu)(ulong , ulong , Ureg *, FPsave *);
-
- if(up == nil)
- panic("fpiarm not in a process");- ufp = up->fpsave;
- /*
- * because all the emulated fp state is in the proc structure,
- * it need not be saved/restored
- */
- switch(up->fpstate){- case FPactive:
- case FPinactive:
- error("illegal instruction: emulated fpu opcode in VFP mode");- case FPinit:
- assert(sizeof(Internal) <= sizeof(ufp->regs[0]));
- up->fpstate = FPemu;
- ufp->control = 0;
- ufp->status = (0x01<<28)|(1<<12); /* sw emulation, alt. C flag */
- for(n = 0; n < Nfpctlregs; n++)
- FR(ufp, n) = fpconst[0];
- }
- for(n=0; ;n++){- validaddr(ur->pc, 4, 0);
- op = *(ulong*)(ur->pc);
- if(fpemudebug)
- print("%#lux: %#8.8lux ", ur->pc, op);- o = (op>>24) & 0xF;
- cp = (op>>8) & 0xF;
- if(ISFPAOP(cp, o))
- fpemu = fpaemu;
- else if(ISVFPOP(cp, o))
- fpemu = vfpemu;
- else
- break;
- if(condok(ur->psr, op>>28))
- fpemu(ur->pc, op, ur, ufp);
-
- ur->pc += 4; /* pretend cpu executed the instr */
- }
- if(fpemudebug)
- print("\n");- return n;
-}
--- a/sys/src/9/teg2/fpimem.c
+++ /dev/null
@@ -1,136 +1,0 @@
-#include "fpi.h"
-
-/*
- * the following routines depend on memory format, not the machine
- */
-
-void
-fpis2i(Internal *i, void *v)
-{- Single *s = v;
-
- i->s = (*s & 0x80000000) ? 1: 0;
- if((*s & ~0x80000000) == 0){- SetZero(i);
- return;
- }
- i->e = ((*s>>23) & 0x00FF) - SingleExpBias + ExpBias;
- i->h = (*s & 0x007FFFFF)<<(1+NGuardBits);
- i->l = 0;
- if(i->e)
- i->h |= HiddenBit;
- else
- i->e++;
-}
-
-void
-fpid2i(Internal *i, void *v)
-{- Double *d = v;
-
- i->s = (d->h & 0x80000000) ? 1: 0;
- i->e = (d->h>>20) & 0x07FF;
- i->h = ((d->h & 0x000FFFFF)<<(4+NGuardBits))|((d->l>>25) & 0x7F);
- i->l = (d->l & 0x01FFFFFF)<<NGuardBits;
- if(i->e)
- i->h |= HiddenBit;
- else
- i->e++;
-}
-
-void
-fpiw2i(Internal *i, void *v)
-{- Word w, word = *(Word*)v;
- short e;
-
- if(word < 0){- i->s = 1;
- word = -word;
- }
- else
- i->s = 0;
- if(word == 0){- SetZero(i);
- return;
- }
- if(word > 0){- for (e = 0, w = word; w; w >>= 1, e++)
- ;
- } else
- e = 32;
- if(e > FractBits){- i->h = word>>(e - FractBits);
- i->l = (word & ((1<<(e - FractBits)) - 1))<<(2*FractBits - e);
- }
- else {- i->h = word<<(FractBits - e);
- i->l = 0;
- }
- i->e = (e - 1) + ExpBias;
-}
-
-void
-fpii2s(void *v, Internal *i)
-{- short e;
- Single *s = (Single*)v;
-
- fpiround(i);
- if(i->h & HiddenBit)
- i->h &= ~HiddenBit;
- else
- i->e--;
- *s = i->s ? 0x80000000: 0;
- e = i->e;
- if(e < ExpBias){- if(e <= (ExpBias - SingleExpBias))
- return;
- e = SingleExpBias - (ExpBias - e);
- }
- else if(e >= (ExpBias + (SingleExpMax-SingleExpBias))){- *s |= SingleExpMax<<23;
- return;
- }
- else
- e = SingleExpBias + (e - ExpBias);
- *s |= (e<<23)|(i->h>>(1+NGuardBits));
-}
-
-void
-fpii2d(void *v, Internal *i)
-{- Double *d = (Double*)v;
-
- fpiround(i);
- if(i->h & HiddenBit)
- i->h &= ~HiddenBit;
- else
- i->e--;
- i->l = ((i->h & GuardMask)<<25)|(i->l>>NGuardBits);
- i->h >>= NGuardBits;
- d->h = i->s ? 0x80000000: 0;
- d->h |= (i->e<<20)|((i->h & 0x00FFFFFF)>>4);
- d->l = (i->h<<28)|i->l;
-}
-
-void
-fpii2w(Word *word, Internal *i)
-{- Word w;
- short e;
-
- fpiround(i);
- e = (i->e - ExpBias) + 1;
- if(e <= 0)
- w = 0;
- else if(e > 31)
- w = 0x7FFFFFFF;
- else if(e > FractBits)
- w = (i->h<<(e - FractBits))|(i->l>>(2*FractBits - e));
- else
- w = i->h>>(FractBits-e);
- if(i->s)
- w = -w;
- *word = w;
-}
--- a/sys/src/9/teg2/mkfile
+++ b/sys/src/9/teg2/mkfile
@@ -113,6 +113,22 @@
CFLAGS= -I. -I../port $CFLAGS # hack to compile private sysproc.c (e.g.)
+fpi.$O fpiarm.$O fpimem.$O: ../omap/fpi.h
+fpi.$O: ../omap/fpi.c
+ $CC $CFLAGS -. ../omap/fpi.c
+fpimem.$O: ../omap/fpimem.c
+ $CC $CFLAGS -. ../omap/fpimem.c
+
+fpiarm.$O: ../bcm/fpiarm.c
+ $CC $CFLAGS -. ../bcm/fpiarm.c
+vfp3.$O: ../bcm/vfp3.c
+ $CC $CFLAGS -. ../bcm/vfp3.c
+
+softfpu.$O: ../omap/softfpu.c
+ $CC $CFLAGS -. ../omap/softfpu.c
+syscall.$O: ../omap/syscall.c
+ $CC $CFLAGS -. ../omap/syscall.c
+
arch.$O clock.$O fpiarm.$O main.$O mmu.$O screen.$O sdscsi.$O syscall.$O \
trap.$O: /$objtype/include/ureg.h
@@ -119,7 +135,6 @@
archtegra.$O devether.$0 ether9221.$O: ../port/etherif.h ../port/netif.h
archtegra.$O devflash.$O flashtegra.$O flashigep.$O: ../port/flashif.h
ecc.$O flashtegra.$O flashigep.$O: ../port/nandecc.h io.h
-fpi.$O fpiarm.$O fpimem.$O: fpi.h
l.$O lexception.$O lproc.$O mmu.$O rebootcode.$O: arm.s mem.h
l.$O rebootcode.$O: cache.v7.s
main.$O: errstr.h rebootcode.i /sys/include/tos.h
--- a/sys/src/9/teg2/softfpu.c
+++ /dev/null
@@ -1,117 +1,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-
-int
-fpudevprocio(Proc* proc, void* a, long n, uintptr offset, int write)
-{- /*
- * Called from procdevtab.read and procdevtab.write
- * allow user process access to the FPU registers.
- * This is the only FPU routine which is called directly
- * from the port code; it would be nice to have dynamic
- * creation of entries in the device file trees...
- */
- USED(proc, a, n, offset, write);
-
- return 0;
-}
-
-void
-fpunotify(void)
-{- /*
- * Called when a note is about to be delivered to a
- * user process, usually at the end of a system call.
- * Note handlers are not allowed to use the FPU so
- * the state is marked (after saving if necessary) and
- * checked in the Device Not Available handler.
- */
-}
-
-void
-fpunoted(void)
-{- /*
- * Called from sysnoted() via the machine-dependent
- * noted() routine.
- * Clear the flag set above in fpunotify().
- */
-}
-
-void
-fpuprocrestore(Proc*)
-{- /*
- * The process has been rescheduled and is about to run.
- * Nothing to do here right now. If the process tries to use
- * the FPU again it will cause a Device Not Available
- * exception and the state will then be restored.
- */
-}
-
-void
-fpuprocfork(Proc*)
-{- /*
- * The current process has been forked, save and copy neccesary
- * state to child. Nothing to do here, child proc starts with FPinit.
- */
-}
-
-void
-fpuprocsave(Proc*)
-{- /*
- * Called from sched() and sleep() via the machine-dependent
- * procsave() routine.
- * About to go in to the scheduler.
- * If the process wasn't using the FPU
- * there's nothing to do.
- */
-}
-
-void
-fpusysprocsetup(Proc*)
-{- /*
- * Disable the FPU.
- * Called from sysexec() via sysprocsetup() to
- * set the FPU for the new process.
- */
-}
-
-void
-fpuinit(void)
-{-}
-
-int
-fpuemu(Ureg* ureg)
-{- int nfp;
-
- if(waserror()){- splhi();
- postnote(up, 1, up->errstr, NDebug);
- return 1;
- }
- spllo();
- nfp = fpiarm(ureg);
- splhi();
- poperror();
-
- return nfp;
-}
-
-void
-fpon(void)
-{-}
-
-void
-fpoff(void)
-{-}
--- a/sys/src/9/teg2/syscall.c
+++ /dev/null
@@ -1,316 +1,0 @@
-/* we use l1 and l2 cache ops to help stability. */
-
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "../port/error.h"
-#include "../port/systab.h"
-
-#include <tos.h>
-#include "ureg.h"
-
-#include "arm.h"
-
-enum {- Psrsysbits = PsrMask | PsrDfiq | PsrDirq | PsrDasabt | PsrMbz,
-};
-
-typedef struct {- uintptr ip;
- Ureg* arg0;
- char* arg1;
- char msg[ERRMAX];
- Ureg* old;
- Ureg ureg;
-} NFrame;
-
-/*
- * Return user to state before notify()
- */
-static void
-noted(Ureg* cur, uintptr arg0)
-{- NFrame *nf;
- Ureg *nur;
-
- qlock(&up->debug);
- if(arg0 != NRSTR && !up->notified){- qunlock(&up->debug);
- pprint("call to noted() when not notified\n");- pexit("Suicide", 0);- }
- up->notified = 0;
- fpunoted();
-
- nf = up->ureg;
- /* sanity clause */
- if(!okaddr((uintptr)nf, sizeof(NFrame), 0)){- qunlock(&up->debug);
- pprint("bad ureg in noted %#p\n", nf);- pexit("Suicide", 0);- }
-
- /* don't let user change system flags */
- nur = &nf->ureg;
- nur->psr &= Psrsysbits;
- nur->psr |= cur->psr & ~Psrsysbits;
-
- memmove(cur, nur, sizeof(Ureg));
-
- switch((int)arg0){- case NCONT:
- case NRSTR:
- if(!okaddr(nur->pc, BY2WD, 0) || !okaddr(nur->sp, BY2WD, 0)){- qunlock(&up->debug);
- pprint("suicide: trap in noted\n");- pexit("Suicide", 0);- }
- up->ureg = nf->old;
- qunlock(&up->debug);
- break;
- case NSAVE:
- if(!okaddr(nur->pc, BY2WD, 0) || !okaddr(nur->sp, BY2WD, 0)){- qunlock(&up->debug);
- pprint("suicide: trap in noted\n");- pexit("Suicide", 0);- }
- qunlock(&up->debug);
-
- splhi();
- nf->arg1 = nf->msg;
- nf->arg0 = &nf->ureg;
- nf->ip = 0;
- cur->sp = (uintptr)nf;
- cur->r0 = (uintptr)nf->arg0;
- break;
- default:
- up->lastnote->flag = NDebug;
- /*FALLTHROUGH*/
- case NDFLT:
- qunlock(&up->debug);
- if(up->lastnote->flag == NDebug)
- pprint("suicide: %s\n", up->lastnote->msg);- pexit(up->lastnote->msg, up->lastnote->flag != NDebug);
- }
-}
-
-/*
- * Call user, if necessary, with note.
- * Pass user the Ureg struct and the note on his stack.
- */
-int
-notify(Ureg* ureg)
-{- uintptr sp;
- NFrame *nf;
- char *msg;
-
- if(up->procctl)
- procctl();
- if(up->nnote == 0)
- return 0;
-
- spllo();
- qlock(&up->debug);
- msg = popnote(ureg);
- if(msg == nil){- qunlock(&up->debug);
- splhi();
- return 0;
- }
-
- if(!okaddr((uintptr)up->notify, 1, 0)){- qunlock(&up->debug);
- pprint("suicide: notify function address %#p\n", up->notify);- pexit("Suicide", 0);- }
-
- sp = ureg->sp - sizeof(NFrame);
- if(!okaddr(sp, sizeof(NFrame), 1)){- qunlock(&up->debug);
- pprint("suicide: notify stack address %#p\n", sp);- pexit("Suicide", 0);- }
-
- nf = (void*)sp;
- memmove(&nf->ureg, ureg, sizeof(Ureg));
- nf->old = up->ureg;
- up->ureg = nf;
- memmove(nf->msg, msg, ERRMAX);
- nf->arg1 = nf->msg;
- nf->arg0 = &nf->ureg;
- nf->ip = 0;
-
- ureg->sp = sp;
- ureg->pc = (uintptr)up->notify;
- ureg->r0 = (uintptr)nf->arg0;
-
- splhi();
- fpunotify();
- qunlock(&up->debug);
-
- l1cache->wb(); /* is this needed? */
- return 1;
-}
-
-void
-syscall(Ureg* ureg)
-{- char *e;
- u32int s;
- ulong sp;
- long ret;
- int i, scallnr;
- vlong startns, stopns;
-
- if(!kenter(ureg))
- panic("syscall: from kernel: pc %#lux r14 %#lux psr %#lux",- ureg->pc, ureg->r14, ureg->psr);
-
- m->syscall++;
- up->insyscall = 1;
- up->pc = ureg->pc;
-
- scallnr = ureg->r0;
- up->scallnr = scallnr;
- spllo();
- sp = ureg->sp;
-
- if(up->procctl == Proc_tracesyscall){- /*
- * Redundant validaddr. Do we care?
- * Tracing syscalls is not exactly a fast path...
- * Beware, validaddr currently does a pexit rather
- * than an error if there's a problem; that might
- * change in the future.
- */
- if(sp < (USTKTOP-BY2PG) || sp > (USTKTOP-sizeof(Sargs)-BY2WD))
- validaddr(sp, sizeof(Sargs)+BY2WD, 0);
-
- syscallfmt(scallnr, ureg->pc, (va_list)(sp+BY2WD));
- up->procctl = Proc_stopme;
- procctl();
- if (up->syscalltrace)
- free(up->syscalltrace);
- up->syscalltrace = nil;
- }
-
- up->nerrlab = 0;
- ret = -1;
- todget(nil, &startns);
-
- l1cache->wb(); /* system is more stable with this */
- if(!waserror()){- if(sp < (USTKTOP-BY2PG) || sp > (USTKTOP-sizeof(Sargs)-BY2WD))
- validaddr(sp, sizeof(Sargs)+BY2WD, 0);
-
- up->s = *((Sargs*)(sp+BY2WD));
- if(scallnr >= nsyscall || systab[scallnr] == nil){- postnote(up, 1, "sys: bad sys call", NDebug);
- error(Ebadarg);
- }
- up->psstate = sysctab[scallnr];
- ret = systab[scallnr]((va_list)up->s.args);
- poperror();
- }else{- /* failure: save the error buffer for errstr */
- e = up->syserrstr;
- up->syserrstr = up->errstr;
- up->errstr = e;
- }
- if(up->nerrlab){- print("bad errstack [%d]: %d extra\n", scallnr, up->nerrlab);- for(i = 0; i < NERR; i++)
- print("sp=%#p pc=%#p\n",- up->errlab[i].sp, up->errlab[i].pc);
- panic("error stack");- }
-
- /*
- * Put return value in frame. On the x86 the syscall is
- * just another trap and the return value from syscall is
- * ignored. On other machines the return value is put into
- * the results register by caller of syscall.
- */
- ureg->r0 = ret;
-
- if(up->procctl == Proc_tracesyscall){- todget(nil, &stopns);
- sysretfmt(scallnr, (va_list)(sp+BY2WD), ret, startns, stopns);
- s = splhi();
- up->procctl = Proc_stopme;
- procctl();
- splx(s);
- if(up->syscalltrace)
- free(up->syscalltrace);
- up->syscalltrace = nil;
- }
-
- up->insyscall = 0;
- up->psstate = 0;
-
- if(scallnr == NOTED)
- noted(ureg, *(ulong*)(sp+BY2WD));
-
- splhi();
- if(scallnr != RFORK && (up->procctl || up->nnote))
- notify(ureg);
-
- l1cache->wb(); /* system is more stable with this */
-
- /* if we delayed sched because we held a lock, sched now */
- if(up->delaysched)
- sched();
- kexit(ureg);
-}
-
-uintptr
-execregs(uintptr entry, ulong ssize, ulong nargs)
-{- ulong *sp;
- Ureg *ureg;
-
- sp = (ulong*)(USTKTOP - ssize);
- *--sp = nargs;
-
- ureg = up->dbgreg;
-// memset(ureg, 0, 15*sizeof(ulong));
- ureg->r13 = (ulong)sp;
- ureg->pc = entry;
-//print("%lud: EXECREGS pc %#ux sp %#ux nargs %ld\n", up->pid, ureg->pc, ureg->r13, nargs);- allcache->wbse(ureg, sizeof *ureg); /* is this needed? */
-
- /*
- * return the address of kernel/user shared data
- * (e.g. clock stuff)
- */
- return USTKTOP-sizeof(Tos);
-}
-
-void
-sysprocsetup(Proc* p)
-{- fpusysprocsetup(p);
-}
-
-/*
- * Craft a return frame which will cause the child to pop out of
- * the scheduler in user mode with the return register zero. Set
- * pc to point to a l.s return function.
- */
-void
-forkchild(Proc *p, Ureg *ureg)
-{- Ureg *cureg;
-
- p->sched.sp = (ulong)p - sizeof(Ureg);
- p->sched.pc = (ulong)forkret;
-
- cureg = (Ureg*)(p->sched.sp);
- memmove(cureg, ureg, sizeof(Ureg));
-
- /* syscall returns 0 for child */
- cureg->r0 = 0;
-}
--- a/sys/src/9/teg2/vfp3.c
+++ /dev/null
@@ -1,1 +1,0 @@
-#include "../bcm/vfp3.c"
--
⑨