ref: 2346ea488600e7e735c2275e5bcd310bbbf9810c
parent: 5851d6fe391a1169d595721dd33afe77165bd84b
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"
--
⑨