diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2015-06-19 14:43:32 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2015-06-19 14:43:32 +0200 |
commit | 6b4a9c5d8d291ce15e9f31cb130537fe47a9688e (patch) | |
tree | 49c2c5b854636e3976a28ef9d207ee5ba86e625b | |
parent | 575015d2b023e5707293830186581f03c33aa90a (diff) | |
download | plan9front-6b4a9c5d8d291ce15e9f31cb130537fe47a9688e.tar.xz |
5e: implement DSB,DMB,ISB and CLREX instructions
-rw-r--r-- | sys/src/cmd/5e/5e.c | 1 | ||||
-rw-r--r-- | sys/src/cmd/5e/arm.c | 41 | ||||
-rw-r--r-- | sys/src/cmd/5e/dat.h | 3 | ||||
-rw-r--r-- | sys/src/cmd/5e/fns.h | 1 | ||||
-rw-r--r-- | sys/src/cmd/5e/proc.c | 1 |
5 files changed, 44 insertions, 3 deletions
diff --git a/sys/src/cmd/5e/5e.c b/sys/src/cmd/5e/5e.c index 7da70c873..238bcadaa 100644 --- a/sys/src/cmd/5e/5e.c +++ b/sys/src/cmd/5e/5e.c @@ -36,6 +36,7 @@ cleanup(void) if(P == nil) return; + clrex(); remproc(P); decref(&nproc); freesegs(); diff --git a/sys/src/cmd/5e/arm.c b/sys/src/cmd/5e/arm.c index bbede825c..f824d8a01 100644 --- a/sys/src/cmd/5e/arm.c +++ b/sys/src/cmd/5e/arm.c @@ -134,6 +134,7 @@ swap(u32int instr) addr = *Rn; if((instr & fB) == 0) addr = evenaddr(addr, 3); + clrex(); targ = (u32int *) vaddr(addr, 4, &seg); lock(&seg->lock); if(instr & fB) { @@ -400,8 +401,10 @@ singleex(u32int instr) invalid(instr); addr = evenaddr(*Rn, 3); if(instr & fS) { + clrex(); targ = vaddr(addr, 4, &seg); lock(&seg->lock); + P->excl = seg; *Rd = *targ; segunlock(seg); } else { @@ -410,17 +413,40 @@ singleex(u32int instr) invalid(instr); targ = vaddr(addr, 4, &seg); if(canlock(&seg->lock)) { + unlock(&seg->lock); + *Rd = 1; + } else if(P->excl != seg) { *Rd = 1; } else { *targ = *Rm; - unlock(&seg->lock); *Rd = 0; } segunlock(seg); + clrex(); } } void +clrex(void) +{ + Segment *seg; + + seg = P->excl; + P->excl = nil; + if(seg != nil) + unlock(&seg->lock); +} + +static void +barrier(void) +{ + static Lock l; + + lock(&l); + unlock(&l); +} + +void step(void) { u32int instr; @@ -463,7 +489,18 @@ step(void) case 0xC: if((P->CPSR & flZ) || !(P->CPSR & flN) != !(P->CPSR & flV)) return; break; case 0xD: if(!(P->CPSR & flZ) && !(P->CPSR & flN) == !(P->CPSR & flV)) return; break; case 0xE: break; - default: sysfatal("condition code %x not implemented", instr >> 28); + case 0xF: + switch(instr & 0xFFF000F0){ + case 0xF5700010: /* CLREX */ + clrex(); + return; + case 0xF5700040: /* DSB */ + case 0xF5700050: /* DMB */ + case 0xF5700060: /* ISB */ + barrier(); + return; + } + default: sysfatal("condition code %x not implemented (instr %ux, ps %ux)", instr >> 28, instr, P->R[15]); } if((instr & 0x0FB00FF0) == 0x01000090) swap(instr); diff --git a/sys/src/cmd/5e/dat.h b/sys/src/cmd/5e/dat.h index c883e4b6e..138656596 100644 --- a/sys/src/cmd/5e/dat.h +++ b/sys/src/cmd/5e/dat.h @@ -31,9 +31,10 @@ struct Process { Ref *path; /* Ref + string data */ Segment *S[SEGNUM]; /* memory */ + Segment *excl; /* recently acquired exclusive access */ u32int R[16]; /* general purpose registers / PC (R15) */ u32int CPSR; /* status register */ - + u32int FPSR; long double F[Nfpregs]; diff --git a/sys/src/cmd/5e/fns.h b/sys/src/cmd/5e/fns.h index 724775b6e..69012f0d7 100644 --- a/sys/src/cmd/5e/fns.h +++ b/sys/src/cmd/5e/fns.h @@ -17,6 +17,7 @@ void fddecref(Fd *); int iscexec(Fd *, int); void setcexec(Fd *, int, int); void cleanup(void); +void clrex(void); void segunlock(Segment *); void *copyifnec(u32int, int, int *); void *bufifnec(u32int, int, int *); diff --git a/sys/src/cmd/5e/proc.c b/sys/src/cmd/5e/proc.c index b0be07299..b1ef6dc9b 100644 --- a/sys/src/cmd/5e/proc.c +++ b/sys/src/cmd/5e/proc.c @@ -378,6 +378,7 @@ donote(char *msg, ulong type) if(P->notehandler == 0) exits(msg); + clrex(); uregp = P->R[13] - 18 * 4; ureg = vaddrnol(uregp, 18 * 4); memcpy(ureg, P->R, 15 * 4); |