M gnot/main.c => gnot/main.c +1 -1
@@ 158,7 158,7 @@ userinit(void)
* Kernel Stack
*/
p->sched.pc = (ulong)init0;
- p->sched.sp = USERADDR+BY2PG-20; /* BUG */
+ p->sched.sp = USERADDR+BY2PG-MAXSYSARG*BY2WD;
p->sched.sr = SUPER|SPL(0);
p->upage = newpage(1, 0, USERADDR|(p->pid&0xFFFF));
M pc/clock.c => pc/clock.c +4 -2
@@ 43,12 43,14 @@ void
clock(Ureg *ur)
{
Proc *p;
- static int last;
m->ticks++;
+
+ checkalarms();
+
p = m->proc;
if(p){
- p->pc = ur->eip;
+ p->pc = ur->pc;
if (p->state==Running)
p->time[p->insyscall]++;
}
M pc/dat.h => pc/dat.h +28 -14
@@ 31,9 31,21 @@ struct Label
ulong pc;
};
-struct FPsave
+
+/*
+ * FPsave.fpstatus
+ */
+enum
+{
+ FPinit,
+ FPactive,
+ FPinactive,
+};
+
+struct FPsave /* ??? needs to be fixed ??? */
{
- int type;
+ long fpreg[32];
+ long fpstatus;
};
struct Conf
@@ 41,14 53,13 @@ struct Conf
ulong nmach; /* processors */
ulong nproc; /* processes */
ulong npgrp; /* process groups */
- ulong npage0; /* total physical pages of memory, bank 0 */
- ulong npage1; /* total physical pages of memory, bank 1 */
- ulong base0; /* base of bank 0 */
- ulong base1; /* base of bank 1 */
+ ulong npage0; /* total physical pages in bank0 */
+ ulong npage1; /* total physical pages in bank1 */
ulong npage; /* total physical pages of memory */
- ulong norig; /* origins */
- ulong npte; /* contiguous page table entries */
- ulong nmod; /* single (modifying) page table entries */
+ ulong nseg; /* number of segments */
+ ulong nimage; /* number of page cache image headers */
+ ulong npagetab; /* number of pte tables */
+ ulong nswap; /* number of swap pages */
ulong nalarm; /* alarms */
ulong nchan; /* channels */
ulong nenv; /* distinct environment values */
@@ 66,16 77,19 @@ struct Conf
ulong nbitmap; /* bitmap structs (devbit.c) */
ulong nbitbyte; /* bytes of bitmap data (devbit.c) */
ulong nfont; /* font structs (devbit.c) */
+ ulong nnoifc; /* number of nonet interfaces */
+ ulong nnoconv; /* number of nonet conversations/ifc */
ulong nurp; /* max urp conversations */
ulong nasync; /* number of async protocol modules */
ulong npipe; /* number of pipes */
- ulong nservice; /* number of services */
- ulong nfsyschan; /* number of filsys open channels */
ulong maxialloc; /* maximum bytes used by ialloc */
+ ulong base0; /* base of bank 0 */
+ ulong base1; /* base of bank 1 */
ulong copymode; /* 0 is copy on write, 1 is copy on reference */
- ulong portispaged; /* ??? */
- ulong nnoifc;
- ulong nnoconv;
+ ulong ipif; /* Ip protocol interfaces */
+ ulong ip; /* Ip conversations per interface */
+ ulong arp; /* Arp table size */
+ ulong frag; /* Ip fragment assemble queue size */
ulong cntrlp; /* panic on ^P */
};
M pc/fault386.c => pc/fault386.c +1 -0
@@ 4,6 4,7 @@
#include "dat.h"
#include "fns.h"
#include "ureg.h"
+#include "io.h"
void
faultinit(void)
M pc/fns.h => pc/fns.h +8 -2
@@ 1,13 1,15 @@
#include "../port/portfns.h"
+#define clearmmucache() /* 386 doesn't have one */
void clock(Ureg*);
void clockinit(void);
void delay(int);
+#define evenaddr(x) /* 386 doesn't care */
void fault386(Ureg*);
void floppyinit(void);
void floppyintr(Ureg*);
-void floppystart(int);
-void floppystop(int);
+long floppyseek(int, ulong);
+#define flushvirt();
void idle(void);
int inb(int);
void intr0(void);
@@ 43,11 45,15 @@ void lidt(Segdesc*, int);
void mmuinit(void);
void outb(int, int);
void prhex(ulong);
+#define procrestore(x,y)
+#define procsave(x,y)
+#define procsetup(p) ((p)->fpstate = FPinit)
void screeninit(void);
void screenputc(int);
void screenputs(char*, int);
void setvec(int, void (*)(Ureg*), int);
void systrap(void);
+void touser(void);
void trapinit(void);
int tas(Lock*);
#define waserror() (u->nerrlab++, setlabel(&u->errlab[u->nerrlab-1]))
M pc/kbd.c => pc/kbd.c +0 -8
@@ 241,14 241,6 @@ kbdinit(void)
setvec(Kbdvec, kbdintr, SEGIG);
}
-int
-kbdputc(IOQ* q, int c)
-{
- if(c==0x10)
- panic("^p");
- putc(q, c);
-}
-
/*
* keyboard interrupt
*/
M pc/l.s => pc/l.s +22 -9
@@ 103,33 103,43 @@ TEXT mode32bit(SB),$0
/*
* make a bottom level page table page that maps the first
- * 4 meg of physical memory
+ * 16 meg of physical memory
*/
LEAL tpt-KZERO(SB),AX /* get phys addr of temporary page table */
ADDL $(BY2PG-1),AX /* must be page alligned */
ANDL $(~(BY2PG-1)),AX /* ... */
- MOVL $1024,CX /* pte's per page */
- MOVL $(((1024-1)<<12)|PTEVALID|PTEKERNEL|PTEWRITE),BX
+ MOVL $(4*1024),CX /* pte's per page */
+ MOVL $((((4*1024)-1)<<PGSHIFT)|PTEVALID|PTEKERNEL|PTEWRITE),BX
setpte:
MOVL BX,-4(AX)(CX*4)
- SUBL $(1<<12),BX
+ SUBL $(1<<PGSHIFT),BX
LOOP setpte
/*
* make a top level page table page that maps the first
- * 4 meg of memory to 0 thru 4meg and to KZERO thru KZERO+4meg
+ * 16 meg of memory to 0 thru 16meg and to KZERO thru KZERO+16meg
*/
MOVL AX,BX
- ADDL $BY2PG,AX
+ ADDL $(4*BY2PG),AX
+ ADDL $(PTEVALID|PTEKERNEL|PTEWRITE),BX
MOVL BX,0(AX)
- MOVL BX,((KZERO>>22)&(BY2PG-1))(AX)
+ MOVL BX,((((KZERO>>1)&0x7FFFFFFF)>>(2*PGSHIFT-1-4))+0)(AX)
+ ADDL $BY2PG,BX
+ MOVL BX,4(AX)
+ MOVL BX,((((KZERO>>1)&0x7FFFFFFF)>>(2*PGSHIFT-1-4))+4)(AX)
+ ADDL $BY2PG,BX
+ MOVL BX,8(AX)
+ MOVL BX,((((KZERO>>1)&0x7FFFFFFF)>>(2*PGSHIFT-1-4))+8)(AX)
+ ADDL $BY2PG,BX
+ MOVL BX,12(AX)
+ MOVL BX,((((KZERO>>1)&0x7FFFFFFF)>>(2*PGSHIFT-1-4))+12)(AX)
/*
* point processor to top level page & turn on paging
*/
MOVL AX,CR3
MOVL CR0,AX
- ORL $1,AX
+ ORL $0X80000000,AX
MOVL AX,CR0
/*
@@ 149,7 159,7 @@ loop:
GLOBL mach0+0(SB), $MACHSIZE
GLOBL u(SB), $4
GLOBL m(SB), $4
-GLOBL tpt(SB), $(BY2PG*3)
+GLOBL tpt(SB), $(BY2PG*6)
/*
* gdt to get us to 32-bit/segmented/unpaged mode
@@ 407,3 417,6 @@ TEXT setlabel(SB),$0
MOVL 0(SP),BX /* store return pc */
MOVL BX,4(AX)
RET
+
+TEXT touser(SB),$0
+ RET
M pc/main.c => pc/main.c +161 -9
@@ 5,29 5,54 @@
#include "fns.h"
#include "io.h"
+
+char sysname[NAMELEN];
+Conf conf;
+char user[NAMELEN] = "bootes";
+
+extern ulong edata;
+
main(void)
{
+ int i;
+
+ machinit();
+ confinit();
screeninit();
+ print("%d pages in bank0, %d pages in bank1\n", conf.npage0, conf.npage1);
+ print("edata == %lux, end == %lux\n", &edata, &end);
trapinit();
+ mmuinit();
+ clockinit();
+ alarminit();
kbdinit();
clockinit();
- mmuinit();
floppyinit();
spllo();
- floppystart(0);
- for(;;){
+
+ for(i=0; i<100; i++){
int c;
c = getc(&kbdq);
if(c!=-1)
screenputc(c);
idle();
- if((TK2SEC(m->ticks)%5)==0)
- if((TK2SEC(m->ticks)%10)==0)
- floppystop(0);
- else
- floppystart(0);
+ floppyseek(0, 0);
+ floppyseek(0, 18*512*20);
}
+ for(;;);
+}
+
+void
+machinit(void)
+{
+ int n;
+
+ n = m->machno;
+ memset(m, 0, sizeof(Mach));
+ m->machno = n;
+ m->mmask = 1<<m->machno;
+ active.machs = 1;
}
void
@@ 36,11 61,95 @@ delay(int l)
int i;
while(--l){
- for(i=0; i < 100; i++)
+ for(i=0; i < 404; i++)
;
}
}
+void
+confinit(void)
+{
+ long x, i, j, *l;
+ int mul;
+
+ /*
+ * size memory
+ */
+ x = 0x12345678;
+ for(i=1; i<16; i++){
+ /*
+ * write the word
+ */
+ l = (long*)(KZERO|(i*1024L*1024L));
+ *l = x;
+ /*
+ * take care of wraps
+ */
+ for(j = 0; j < i; j++){
+ l = (long*)(KZERO|(j*1024L*1024L));
+ *l = 0;
+ }
+ /*
+ * check
+ */
+ l = (long*)(KZERO|(i*1024L*1024L));
+ if(*l != x)
+ break;
+ x += 0x3141526;
+ }
+
+ /*
+ * the first 640k is the standard useful memory
+ */
+ conf.npage0 = 640/4;
+ conf.base0 = 0;
+
+ /*
+ * the last 128k belongs to the roms
+ */
+ conf.npage1 = (i)*1024/4;
+ conf.base1 = 1024/4;
+
+ conf.npage = conf.npage0 + conf.npage1;
+ conf.maxialloc = (640*1024-256*1024-BY2PG);
+
+ mul = 1;
+ conf.nproc = 20 + 50*mul;
+ conf.npgrp = conf.nproc/2;
+ conf.nseg = conf.nproc*3;
+ conf.npagetab = (conf.nseg*14)/10;
+ conf.nswap = conf.nproc*80;
+ conf.nimage = 50;
+ conf.nalarm = 1000;
+ conf.nchan = 4*conf.nproc;
+ conf.nenv = 4*conf.nproc;
+ conf.nenvchar = 8000*mul;
+ conf.npgenv = 200*mul;
+ conf.nmtab = 50*mul;
+ conf.nmount = 80*mul;
+ conf.nmntdev = 15*mul;
+ conf.nmntbuf = conf.nmntdev+3;
+ conf.nmnthdr = 2*conf.nmntdev;
+ conf.nsrv = 16*mul; /* was 32 */
+ conf.nbitmap = 512*mul;
+ conf.nbitbyte = conf.nbitmap*1024*screenbits();
+ conf.nfont = 10*mul;
+ conf.nnoifc = 1;
+ conf.nnoconv = 32;
+ conf.nurp = 32;
+ conf.nasync = 1;
+ conf.nstream = (conf.nproc*3)/2;
+ conf.nqueue = 5 * conf.nstream;
+ conf.nblock = 24 * conf.nstream;
+ conf.npipe = conf.nstream/2;
+ conf.copymode = 0; /* copy on write */
+ conf.ipif = 8;
+ conf.ip = 64;
+ conf.arp = 32;
+ conf.frag = 32;
+ conf.cntrlp = 0;
+}
+
int
sprint(char *s, char *fmt, ...)
{
@@ 73,7 182,50 @@ panic(char *fmt, ...)
idle();
}
+int
+kbdputc(IOQ* q, int c)
+{
+ if(c==0x10)
+ panic("^p");
+ putc(q, c);
+}
+
+struct Palloc palloc;
+
+void*
+ialloc(ulong n, int align)
+{
+ ulong p;
+
+ if(palloc.active && n!=0)
+ print("ialloc bad\n");
+ if(palloc.addr == 0)
+ palloc.addr = ((ulong)&end)&~KZERO;
+ if(align)
+ palloc.addr = PGROUND(palloc.addr);
+
+ memset((void*)(palloc.addr|KZERO), 0, n);
+ p = palloc.addr;
+ palloc.addr += n;
+ if(align)
+ palloc.addr = PGROUND(palloc.addr);
+
+ if(palloc.addr >= conf.maxialloc)
+ panic("keep bill joy away");
+
+ return (void*)(p|KZERO);
+}
+
void
sched(void)
+{ }
+
+void
+ready(Proc*p)
+{ }
+
+int
+postnote(Proc*p, int x, char* y, int z)
{
+ panic("postnote");
}
M pc/mem.h => pc/mem.h +3 -3
@@ 10,7 10,7 @@
#define BY2WD 4 /* bytes per word */
#define BY2PG 4096 /* bytes per page */
#define WD2PG (BY2PG/BY2WD) /* words per page */
-#define PGSHIFT 13 /* log(BY2PG) */
+#define PGSHIFT 12 /* log(BY2PG) */
#define PGROUND(s) (((s)+(BY2PG-1))&~(BY2PG-1))
#define MAXMACH 1 /* max # cpus system can run */
@@ 47,7 47,7 @@
#define MACHSIZE 4096
-#define isphys(x) ((x)&KZERO)
+#define isphys(x) (((ulong)x)&KZERO)
/*
* known 80386 segments (in GDT) and their selectors
@@ 101,11 101,11 @@
#define PTEMAPMEM (1024*1024) /* ??? */
#define SEGMAPSIZE 16 /* ??? */
#define PTEPERTAB (PTEMAPMEM/BY2PG) /* ??? */
+#define PPN(x) ((x)&~(BY2PG-1))
/*
* physical MMU
*/
-#define PPN(x) ((x)&~(BY2PG-1))
#define PTEVALID (1<<0)
#define PTEUNCACHED 0 /* everything is uncached */
#define PTEWRITE (1<<1)
M pc/mmu.c => pc/mmu.c +28 -0
@@ 67,15 67,43 @@ Segdesc gdt[] =
[RESEG] E16SEG(0), /* reboot code */
};
+extern ulong tpt[];
+
void
mmuinit(void)
{
+
gdt[SYSGATE].d0 = ((ulong)systrap)&0xFFFF|(KESEL<<16);
gdt[SYSGATE].d1 = ((ulong)systrap)&0xFFFF0000|SEGP|SEGPL(3)|SEGCG;
lgdt(gdt, sizeof gdt);
}
void
+mapstack(Proc *p)
+{
+}
+
+void
+flushmmu(void)
+{
+}
+
+void
+mmurelease(Proc *p)
+{
+}
+
+void
+putmmu(ulong x, ulong y, Page*z)
+{
+}
+
+void
+invalidateu(void)
+{
+}
+
+void
systrap(void)
{
panic("system trap from user");
A pc/segment.h => pc/segment.h +20 -0
@@ 0,0 1,20 @@
+/*
+ * Attach segment types
+ */
+
+typedef struct Physseg Physseg;
+struct Physseg
+{
+ ulong attr; /* Segment attributes */
+ char *name; /* Attach name */
+ ulong pa; /* Physical address */
+ ulong size; /* Maximum segment size in pages */
+ Page *(*pgalloc)(ulong); /* Allocation if we need it */
+ void (*pgfree)(Page*);
+}physseg[] = {
+ { SG_SHARED, "lock", 0, SEGMAXSIZE, &snewpage, &putpage },
+ { SG_SHARED, "shared", 0, SEGMAXSIZE, &snewpage, &putpage },
+ { SG_PHYSICAL, "kmem", KZERO, SEGMAXSIZE, 0, 0 },
+ { SG_BSS, "memory", 0, SEGMAXSIZE, &snewpage, &putpage },
+ { 0, 0, 0, 0, 0, 0 },
+};
M pc/trap.c => pc/trap.c +4 -16
@@ 124,7 124,7 @@ void
trap(Ureg *ur)
{
if(ur->trap>=256 || ivec[ur->trap] == 0)
- panic("bad trap type %d\n", ur->trap);
+ panic("bad trap type %d %lux\n", ur->trap, ur->pc);
/*
* call the trap routine
@@ 147,25 147,13 @@ syscall(Ureg *ur)
panic("syscall");
}
-#include "errstr.h"
-
-void
-error(int code)
-{
- strncpy(u->error, errstrtab[code], ERRLEN);
- nexterror();
-}
-
void
-errors(char *err)
+dumpstack(void)
{
- strncpy(u->error, err, ERRLEN);
- nexterror();
}
-
void
-nexterror(void)
+execpc(ulong entry)
{
- gotolabel(&u->errlab[--u->nerrlab]);
+ ((Ureg*)UREGADDR)->pc = entry;
}
M port/malloc.c => port/malloc.c +1 -1
@@ 423,7 423,7 @@ cached(Store *p)
void *calloc(ulong n, ulong size){
void *p;
- size *= n;
+ size = size*n;
p = malloc(size);
memset(p, 0, size);
return p;
M port/qlock.c => port/qlock.c +2 -0
@@ 17,6 17,8 @@ qlock(QLock *q)
unlock(&q->queue);
return;
}
+ if(u == 0)
+ panic("qlock");
p = q->tail;
if(p == 0)
q->head = u->p;
M power/dat.h => power/dat.h +1 -1
@@ 136,7 136,7 @@ struct Mach
Proc *pidproc[NTLBPID]; /* process that owns this tlbpid on this mach */
Page *ufreeme; /* address of upage of exited process */
- int tlbfault;
+ int tlbfault; /* this offset known in l.s/utlbmiss() */
int tlbpurge;
int pfault;
int cs;
M power/l.s => power/l.s +12 -7
@@ 243,26 243,30 @@ TEXT vector0(SB), $-4
MOVW $utlbmiss(SB), R26
MOVW M(TLBVIRT), R27
- SRL $(6-3), R27 /* delay slot fodder, right adjust */
JMP (R26)
TEXT utlbmiss(SB), $-4
- SRL $6, R27, R26 /* right adjusted vpn */
- SLL $(STLBLOG-6), R27 /* left adjusted pid */
+ MOVW R27, R26
+ SLL $1, R26
+ SRL $12, R27
XOR R26, R27
- AND $((STLBSIZE-1)<<3), R27
+ AND $(STLBSIZE-1), R27
+ SLL $8, R27
+ /* R27 = (((tlbvirt<<1)^(tlbvirt>>12)) & (STLBSIZE-1)) << 8 (8 to clear zero in TLBPHYS) */
MOVW R27, M(TLBPHYS) /* scratch register, store */
- MOVW $((MACHADDR+4) & 0xffff0000), R26
- MOVW $MPID, R27
+ MOVW $((MACHADDR+4) & 0xffff0000), R26 /* get &mach[0].stb BUG */
+ OR $((MACHADDR+4) & 0xffff), R26
+ MOVW $MPID, R27 /* add BY2PG*machno */
MOVB 3(R27), R27
AND $7, R27
SLL $PGSHIFT, R27
ADDU R27, R26
MOVW M(TLBPHYS), R27 /* scratch register, load */
- MOVW ((MACHADDR+4) & 0xffff)(R26), R26
+ MOVW (R26), R26
+ SRL $5, R27 /* R27 is now index * 8 */
ADDU R26, R27
MOVW 4(R27), R26
MOVW R26, M(TLBPHYS)
@@ 279,6 283,7 @@ stlbm:
MOVW $exception(SB), R26
JMP (R26)
+
TEXT exception(SB), $-4
MOVW M(STATUS), R26
M power/main.c => power/main.c +1 -1
@@ 261,7 261,7 @@ userinit(void)
* Kernel Stack
*/
p->sched.pc = (ulong)init0;
- p->sched.sp = USERADDR+BY2PG-24; /* BUG */
+ p->sched.sp = USERADDR+BY2PG-(1+MAXSYSARG)*BY2WD;
p->upage = newpage(0, 0, USERADDR|(p->pid&0xFFFF));
/*
M power/mem.h => power/mem.h +1 -1
@@ 103,7 103,7 @@
#define TLBPID(n) (((n)>>6)&0x3F)
#define PTEMAPMEM (1024*1024)
#define PTEPERTAB (PTEMAPMEM/BY2PG)
-#define STLBLOG 11
+#define STLBLOG 13
#define STLBSIZE (1<<STLBLOG)
#define SEGMAPSIZE 64
M power/trap.c => power/trap.c +2 -2
@@ 546,8 546,8 @@ syscall(Ureg *aur)
pprint("old system call linkage; recompile\n");
sp += BY2WD;
}
- if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-6*BY2WD))
- validaddr(sp, 6*BY2WD, 0);
+ if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-(1+MAXSYSARG)*BY2WD))
+ validaddr(sp, (1+MAXSYSARG)*BY2WD, 0);
ret = (*systab[r1])((ulong*)(sp+BY2WD));
}
ur->pc += 4;
M ss/clock.c => ss/clock.c +5 -2
@@ 59,7 59,10 @@ clock(Ureg *ur)
if((ur->psr&SPL(0xF))==0 && p && p->state==Running){
if(anyready())
sched();
- if(u->nnote && (ur->psr&PSRPSUPER)==0)
- notify(ur);
+ if((ur->psr&PSRPSUPER) == 0){
+ *(ulong*)(USTKTOP-BY2WD) += TK2MS(1);
+ if(u->nnote)
+ notify(ur);
+ }
}
}
M ss/faultsparc.c => ss/faultsparc.c +1 -0
@@ 25,6 25,7 @@ faultsparc(Ureg *ur)
read = 0;
}
spllo();
+print("fault %lux %lux %d\n", ur->pc, addr, read);
if(u == 0){
dumpregs(ur);
panic("fault u==0 pc=%lux addr=%lux", ur->pc, addr);
M ss/main.c => ss/main.c +2 -2
@@ 111,7 111,7 @@ init0(void)
u->dot = clone(u->slash, 0);
kickpager();
- touser(USTKTOP-5*BY2WD);
+ touser(USTKTOP-(1+MAXSYSARG)*BY2WD);
}
FPsave initfp;
@@ 137,7 137,7 @@ userinit(void)
* Kernel Stack
*/
p->sched.pc = (((ulong)init0) - 8); /* 8 because of RETURN in gotolabel */
- p->sched.sp = USERADDR+BY2PG-20; /* BUG */
+ p->sched.sp = USERADDR+BY2PG-(1+MAXSYSARG)*BY2WD;
p->upage = newpage(0, 0, USERADDR|(p->pid&0xFFFF));
/*
M ss/trap.c => ss/trap.c +21 -6
@@ 174,14 174,22 @@ void
dumpstack(void)
{
ulong l, v;
+ int i;
extern ulong etext;
+print("no dumpstack\n");
+return;
- if(u)
+ if(u){
+ i = 0;
for(l=(ulong)&l; l<USERADDR+BY2PG; l+=4){
v = *(ulong*)l;
if(KTZERO < v && v < (ulong)&etext)
- print("%lux=%lux\n", l, v);
+ print("%lux=%lux ", l, v);
+ ++i;
+ if((i&7) == 0)
+ print("\n");
}
+ }
}
void
@@ 316,11 324,13 @@ syscall(Ureg *aur)
Ureg *ur;
char *msg;
- u->p->insyscall = 1;
ur = aur;
- u->p->pc = ur->pc;
- if(ur->psr & PSRPSUPER)
+ if(ur->psr & PSRPSUPER){
+ dumpregs(ur);
panic("recursive system call");
+ }
+ u->p->insyscall = 1;
+ u->p->pc = ur->pc;
/*
* since the system call interface does not
@@ 330,8 340,9 @@ syscall(Ureg *aur)
u->p->fpstate = FPinit;
ur->psr &= ~PSREF;
}
-
+print("syscall %d\n", ur->r7);
spllo();
+print("got low in syscall\n");
r7 = ur->r7;
sp = ur->usp;
@@ 350,6 361,10 @@ syscall(Ureg *aur)
msg = "sys: odd stack";
goto Bad;
}
+ if(((ulong*)ur->pc)[-2] != 0x82206004){ /* new calling convention: look for ADD $-4, SP */
+ pprint("new system call linkage\n");
+ sp -= BY2WD;
+ }
if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-(2+MAXSYSARG)*BY2WD))
validaddr(sp, ((2+MAXSYSARG)*BY2WD), 0);
ret = (*systab[r7])((ulong*)(sp+2*BY2WD));