]> Cypherpunks repositories - gostls13.git/commitdiff
update 386 to new runtime (CL 30381)
authorRuss Cox <rsc@golang.org>
Wed, 17 Jun 2009 22:15:55 +0000 (15:15 -0700)
committerRuss Cox <rsc@golang.org>
Wed, 17 Jun 2009 22:15:55 +0000 (15:15 -0700)
R=r
DELTA=298  (119 added, 81 deleted, 98 changed)
OCL=30427
CL=30443

src/cmd/8l/obj.c
src/cmd/8l/pass.c
src/pkg/runtime/386/asm.s
src/pkg/runtime/386/traceback.c
src/pkg/runtime/darwin/386/sys.s
src/pkg/runtime/darwin/thread.c
src/pkg/runtime/linux/386/sys.s
src/pkg/runtime/linux/os.h
src/pkg/runtime/linux/thread.c

index c3d4b9f659b1c6314472ff8a3dc40218bd9d4460..ef4e9a9b9021df43877973e5e01d2c80bf78e57d 100644 (file)
@@ -1038,7 +1038,7 @@ loop:
                s = p->from.sym;
                if(s != S && s->dupok) {
                        if(debug['v'])
-                               Bprint(&bso, "skipping %s in %s: dupok", s->name, pn);
+                               Bprint(&bso, "skipping %s in %s: dupok\n", s->name, pn);
                        goto loop;
                }
                if(s != S) {
index feaf287674d664034cb8bbd24b7c1ceacc459176..fa6d6a00fe179af4299b07c4fda45fe3a708fb5f 100644 (file)
@@ -30,7 +30,7 @@
 
 #include       "l.h"
 
-// see ../../runtime/proc.c:/StackGuard
+// see ../../pkg/runtime/proc.c:/StackGuard
 enum
 {
        StackSmall = 128,
@@ -619,29 +619,17 @@ dostkoff(void)
                                        q = p;
                                }
 
-                               p = appendp(p); // load m into DX
+                               p = appendp(p); // save frame size in DX
                                p->as = AMOVL;
-                               p->from.type = D_INDIR+D_FS;
-                               p->from.offset = 4;
                                p->to.type = D_DX;
-                               if(q1) {
-                                       q1->pcond = p;
-                                       q1 = P;
-                               }
-
-                               p = appendp(p); // save autoffset in 4(DX)
-                               p->as = AMOVL;
-                               p->to.type = D_INDIR+D_DX;
-                               p->to.offset = 4;
                                /* 160 comes from 3 calls (3*8) 4 safes (4*8) and 104 guard */
                                p->from.type = D_CONST;
                                if(autoffset+160 > 4096)
                                        p->from.offset = (autoffset+160) & ~7LL;
 
-                               p = appendp(p); // save textarg in 8(DX)
+                               p = appendp(p); // save arg size in AX
                                p->as = AMOVL;
-                               p->to.type = D_INDIR+D_DX;
-                               p->to.offset = 8;
+                               p->to.type = D_AX;
                                p->from.type = D_CONST;
                                p->from.offset = curtext->to.offset2;
 
index 5d3c4261ab2c8010cf3bff90f32f1814dad91c36..7b59bc7e31d61ce30f5e1a9873a3b25e4d1b4798 100644 (file)
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+#include "386/asm.h"
+
 TEXT _rt0_386(SB),7,$0
        // copy arguments forward on an even stack
        MOVL    0(SP), AX               // argc
@@ -11,17 +13,6 @@ TEXT _rt0_386(SB),7,$0
        MOVL    AX, 120(SP)             // save argc, argv away
        MOVL    BX, 124(SP)
 
-/*
-       // write "go386\n"
-       PUSHL   $6
-       PUSHL   $hello(SB)
-       PUSHL   $1
-       CALL    sys·write(SB)
-       POPL    AX
-       POPL    AX
-       POPL    AX
-*/
-
        CALL    ldt0setup(SB)
 
        // set up %fs to refer to that ldt entry
@@ -37,19 +28,18 @@ TEXT _rt0_386(SB),7,$0
 ok:
 
        // set up m and g "registers"
-       // g is 0(FS), m is 4(FS)
        LEAL    g0(SB), CX
-       MOVL    CX, 0(FS)
+       MOVL    CX, g
        LEAL    m0(SB), AX
-       MOVL    AX, 4(FS)
+       MOVL    AX, m
 
        // save m->g0 = g0
-       MOVL    CX, 0(AX)
+       MOVL    CX, m_g0(AX)
 
        // create istack out of the OS stack
        LEAL    (-8192+104)(SP), AX     // TODO: 104?
-       MOVL    AX, 0(CX)       // 8(g) is stack limit (w 104b guard)
-       MOVL    SP, 4(CX)       // 12(g) is base
+       MOVL    AX, g_stackguard(CX)
+       MOVL    SP, g_stackbase(CX)
        CALL    emptyfunc(SB)   // fault if stack check is wrong
 
        // convention is D is always cleared
@@ -68,7 +58,7 @@ ok:
 
        // create a new goroutine to start program
        PUSHL   $mainstart(SB)  // entry
-       PUSHL   $8      // arg size
+       PUSHL   $0      // arg size
        CALL    sys·newproc(SB)
        POPL    AX
        POPL    AX
@@ -93,51 +83,105 @@ TEXT       breakpoint(SB),7,$0
        BYTE $0xcc
        RET
 
-// go-routine
-TEXT   gogo(SB), 7, $0
-       MOVL    4(SP), AX       // gobuf
-       MOVL    0(AX), SP       // restore SP
-       MOVL    4(AX), AX
-       MOVL    AX, 0(SP)       // put PC on the stack
-       MOVL    $1, AX
-       RET
+/*
+ *  go-routine
+ */
 
+// uintptr gosave(Gobuf*)
+// save state in Gobuf; setjmp
 TEXT gosave(SB), 7, $0
-       MOVL    4(SP), AX       // gobuf
-       MOVL    SP, 0(AX)       // save SP
-       MOVL    0(SP), BX
-       MOVL    BX, 4(AX)       // save PC
-       MOVL    $0, AX  // return 0
+       MOVL    4(SP), AX               // gobuf
+       LEAL    4(SP), BX               // caller's SP
+       MOVL    BX, gobuf_sp(AX)
+       MOVL    0(SP), BX               // caller's PC
+       MOVL    BX, gobuf_pc(AX)
+       MOVL    g, BX
+       MOVL    BX, gobuf_g(AX)
+       MOVL    $0, AX                  // return 0
        RET
 
-// support for morestack
-
-// return point when leaving new stack.
-// save AX, jmp to lesstack to switch back
-TEXT   retfromnewstack(SB),7,$0
-       MOVL    4(FS), BX       // m
-       MOVL    AX, 12(BX)      // save AX in m->cret
-       JMP     lessstack(SB)
-
-// gogo, returning 2nd arg instead of 1
-TEXT gogoret(SB), 7, $0
-       MOVL    8(SP), AX       // return 2nd arg
-       MOVL    4(SP), BX       // gobuf
-       MOVL    0(BX), SP       // restore SP
-       MOVL    4(BX), BX
-       MOVL    BX, 0(SP)       // put PC on the stack
+// void gogo(Gobuf*, uintptr)
+// restore state from Gobuf; longjmp
+TEXT gogo(SB), 7, $0
+       MOVL    8(SP), AX               // return 2nd arg
+       MOVL    4(SP), BX               // gobuf
+       MOVL    gobuf_g(BX), DX
+       MOVL    0(DX), CX               // make sure g != nil
+       MOVL    DX, g
+       MOVL    gobuf_sp(BX), SP        // restore SP
+       MOVL    gobuf_pc(BX), BX
+       JMP     BX
+
+// void gogocall(Gobuf*, void (*fn)(void))
+// restore state from Gobuf but then call fn.
+// (call fn, returning to state in Gobuf)
+TEXT gogocall(SB), 7, $0
+       MOVL    8(SP), AX               // fn
+       MOVL    4(SP), BX               // gobuf
+       MOVL    gobuf_g(BX), DX
+       MOVL    DX, g
+       MOVL    0(DX), CX               // make sure g != nil
+       MOVL    gobuf_sp(BX), SP        // restore SP
+       MOVL    gobuf_pc(BX), BX
+       PUSHL   BX
+       JMP     AX
+       POPL    BX      // not reached
+
+/*
+ * support for morestack
+ */
+
+// Called during function prolog when more stack is needed.
+TEXT sys·morestack(SB),7,$0
+       // Cannot grow scheduler stack (m->g0).
+       MOVL    m, BX
+       MOVL    m_g0(BX), SI
+       CMPL    g, SI
+       JNE     2(PC)
+       INT     $3
+
+       // frame size in DX
+       // arg size in AX
+       // Save in m.
+       MOVL    DX, m_moreframe(BX)
+       MOVL    AX, m_moreargs(BX)
+
+       // Called from f.
+       // Set m->morebuf to f's caller.
+       MOVL    4(SP), DI       // f's caller's PC
+       MOVL    DI, (m_morebuf+gobuf_pc)(BX)
+       LEAL    8(SP), CX       // f's caller's SP
+       MOVL    CX, (m_morebuf+gobuf_sp)(BX)
+       MOVL    g, SI
+       MOVL    SI, (m_morebuf+gobuf_g)(BX)
+
+       // Set m->morepc to f's PC.
+       MOVL    0(SP), AX
+       MOVL    AX, m_morepc(BX)
+
+       // Call newstack on m's scheduling stack.
+       MOVL    m_g0(BX), BP
+       MOVL    BP, g
+       MOVL    (m_sched+gobuf_sp)(BX), SP
+       CALL    newstack(SB)
+       MOVL    $0, 0x1003      // crash if newstack returns
        RET
 
-TEXT setspgoto(SB), 7, $0
-       MOVL    4(SP), AX       // SP
-       MOVL    8(SP), BX       // fn to call
-       MOVL    12(SP), CX      // fn to return
-       MOVL    AX, SP
-       PUSHL   CX
-       JMP     BX
-       POPL    AX      // not reached
+// Return point when leaving stack.
+TEXT sys·lessstack(SB), 7, $0
+       // Save return value in m->cret
+       MOVL    m, BX
+       MOVL    AX, m_cret(BX)
+
+       // Call oldstack on m's scheduling stack.
+       MOVL    m_g0(BX), DX
+       MOVL    DX, g
+       MOVL    (m_sched+gobuf_sp)(BX), SP
+       CALL    oldstack(SB)
+       MOVL    $0, 0x1004      // crash if oldstack returns
        RET
 
+
 // bool cas(int32 *val, int32 old, int32 new)
 // Atomically:
 //     if(*val == old){
@@ -212,6 +256,3 @@ TEXT emptyfunc(SB),0,$0
 TEXT   abort(SB),7,$0
        INT $0x3
 
-DATA hello+0(SB)/8, $"go386\n\z\z"
-GLOBL hello+0(SB), $8
-
index 05724d9ac91f3eb5a9bd2e61770313bf5f409464..22a1bee5d7dfc3634d6b8ad687dfca2c7a0a942a 100644 (file)
@@ -27,19 +27,19 @@ traceback(byte *pc0, byte *sp, G *g)
 
        stk = (Stktop*)g->stackbase;
        for(n=0; n<100; n++) {
-               while(pc == (uintptr)retfromnewstack) {
+               if(pc == (uint64)sys·lessstack) {
+                       // printf("--\n");
                        // pop to earlier stack block
-                       sp = stk->oldsp;
-                       stk = (Stktop*)stk->oldbase;
-                       pc = *(uintptr*)(sp+sizeof(uintptr));
-                       sp += 2*sizeof(uintptr);        // two irrelevant calls on stack: morestack plus its call
+                       pc = (uintptr)stk->gobuf.pc;
+                       sp = stk->gobuf.sp;
+                       stk = (Stktop*)stk->stackbase;
                }
                f = findfunc(pc);
                if(f == nil) {
                        // dangerous, but poke around to see if it is a closure
                        p = (byte*)pc;
                        // ADDL $xxx, SP; RET
-                       if(p[0] == 0x81 && p[1] == 0xc4 && p[6] == 0xc3) {
+                       if(p != 0 && p[0] == 0x81 && p[1] == 0xc4 && p[6] == 0xc3) {
                                sp += *(uint32*)(p+2) + 8;
                                pc = *(uintptr*)(sp - 8);
                                if(pc <= 0x1000)
@@ -109,11 +109,10 @@ runtime·Caller(int32 n, uintptr retpc, String retfile, int32 retline, bool retb
        // now unwind n levels
        stk = (Stktop*)g->stackbase;
        while(n-- > 0) {
-               while(pc == (uintptr)retfromnewstack) {
-                       sp = stk->oldsp;
-                       stk = (Stktop*)stk->oldbase;
-                       pc = *((uintptr*)sp + 1);
-                       sp += 2*sizeof(uintptr);
+               while(pc == (uintptr)sys·lessstack) {
+                       pc = (uintptr)stk->gobuf.pc;
+                       sp = stk->gobuf.sp;
+                       stk = (Stktop*)stk->stackbase;
                }
 
                if(f->frame < sizeof(uintptr))  // assembly functions lie
index bbcb622d5f44261638dc9b761ab28b90b6b9d628..fc2d8ede9c4dcd30e396685ce210ed6c4b10dc2b 100644 (file)
@@ -6,6 +6,8 @@
 // See http://fxr.watson.org/fxr/source/bsd/kern/syscalls.c?v=xnu-1228
 // or /usr/include/sys/syscall.h (on a Mac) for system call numbers.
 
+#include "386/asm.h"
+
 TEXT notok(SB),7,$0
        MOVL    $0xf1, 0xf1
        RET
@@ -26,7 +28,7 @@ TEXT exit1(SB),7,$0
        CALL    notok(SB)
        RET
 
-TEXT sys·write(SB),7,$0
+TEXT write(SB),7,$0
        MOVL    $4, AX
        INT     $0x80
        JAE     2(PC)
@@ -56,9 +58,10 @@ TEXT sigaction(SB),7,$0
 //     16(FP)  siginfo
 //     20(FP)  context
 TEXT sigtramp(SB),7,$40
-       MOVL    4(FS), BP       // m
-       MOVL    28(BP), BP      // m->gsignal
-       MOVL    BP, 0(FS)       // g = m->gsignal
+       // g = m->gsignal
+       MOVL    m, BP
+       MOVL    m_gsignal(BP), BP
+       MOVL    BP, g
 
        MOVL    handler+4(FP), DI
        MOVL    signo+12(FP), AX
@@ -95,11 +98,11 @@ TEXT bsdthread_create(SB),7,$32
        // 0(SP) is where the caller PC would be; kernel skips it
        MOVL    func+12(FP), BX
        MOVL    BX, 4(SP)       // func
-       MOVL    m+4(FP), BX
+       MOVL    mm+4(FP), BX
        MOVL    BX, 8(SP)       // arg
        MOVL    stk+0(FP), BX
        MOVL    BX, 12(SP)      // stack
-       MOVL    g+8(FP), BX
+       MOVL    gg+8(FP), BX
        MOVL    BX, 16(SP)      // pthread
        MOVL    $0x1000000, 20(SP)      // flags = PTHREAD_START_CUSTOM
        INT     $0x80
@@ -121,7 +124,7 @@ TEXT bsdthread_start(SB),7,$0
        // set up ldt 7+id to point at m->tls.
        // m->tls is at m+40.  newosproc left
        // the m->id in tls[0].
-       LEAL    40(DX), BP
+       LEAL    m_tls(DX), BP
        MOVL    0(BP), DI
        ADDL    $7, DI  // m0 is LDT#7. count up.
        // setldt(tls#, &tls, sizeof tls)
@@ -139,9 +142,9 @@ TEXT bsdthread_start(SB),7,$0
        MOVW    DI, FS
 
        // Now segment is established.  Initialize m, g.
-       MOVL    AX, 0(FS)       // g
-       MOVL    DX, 4(FS)       // m
-       MOVL    BX, 20(DX)      // m->procid = thread port (for debuggers)
+       MOVL    AX, g
+       MOVL    DX, m
+       MOVL    BX, m_procid(DX)        // m->procid = thread port (for debuggers)
        CALL    CX      // fn()
        CALL    exit1(SB)
        RET
index 3a982471ae1a3fad5e9d69b7aaaed612037f1235..2a6116c103f268e59f238b21eb7b0049dc64eca6 100644 (file)
@@ -151,8 +151,12 @@ osinit(void)
 void
 newosproc(M *m, G *g, void *stk, void (*fn)(void))
 {
-       // printf("newosproc m=%p g=%p stk=%p fn=%p\n", m, g, stk, fn);
        m->tls[0] = m->id;      // so 386 asm can find it
+
+       if(0){
+               printf("newosproc stk=%p m=%p g=%p fn=%p id=%d/%d ostk=%p\n",
+                       stk, m, g, fn, m->id, m->tls[0], &m);
+       }
        bsdthread_create(stk, m, g, fn);
 }
 
index 419973a5ca9868a33bc9e0a0ad05ef26ec62af29..fa056c075dabc296db3e1d42bf85e289314359fa 100755 (executable)
@@ -6,6 +6,8 @@
 // System calls and other sys.stuff for 386, Linux
 //
 
+#include "386/asm.h"
+
 TEXT syscall(SB),7,$0
        MOVL 4(SP), AX  // syscall number
        MOVL 8(SP), BX  // arg1
@@ -42,26 +44,6 @@ TEXT write(SB),7,$0
        INT     $0x80
        RET
 
-TEXT getpid(SB),7,$0
-       MOVL    $20, AX
-       INT     $0x80
-       RET
-
-TEXT kill(SB),7,$0
-       MOVL    $37, AX
-       MOVL    4(SP), BX
-       MOVL    8(SP), CX
-       INT     $0x80
-       RET
-
-TEXT sys·write(SB),7,$0
-       MOVL    $4, AX          // syscall - write
-       MOVL    4(SP), BX
-       MOVL    8(SP), CX
-       MOVL    12(SP), DX
-       INT     $0x80
-       RET
-
 TEXT rt_sigaction(SB),7,$0
        MOVL    $174, AX                // syscall - rt_sigaction
        MOVL    4(SP), BX
@@ -72,18 +54,19 @@ TEXT rt_sigaction(SB),7,$0
        RET
 
 TEXT sigtramp(SB),7,$0
-       MOVL    4(FS), BP       // m
-       MOVL    20(BP), AX      // m->gsignal
-       MOVL    AX, 0(FS)       // g = m->gsignal
+       MOVL    m, BP
+       MOVL    m_gsignal(BP), AX
+       MOVL    AX, g
        JMP     sighandler(SB)
 
 TEXT sigignore(SB),7,$0
        RET
 
 TEXT sigreturn(SB),7,$0
-       MOVL    4(FS), BP       // m
-       MOVL    32(BP), BP      // m->curg
-       MOVL    BP, 0(FS)       // g = m->curg
+       // g = m->curg
+       MOVL    m, BP
+       MOVL    m_curg(BP), BP
+       MOVL    BP, g
        MOVL    $173, AX        // rt_sigreturn
        INT $0x80
        INT $3  // not reached
@@ -104,7 +87,7 @@ TEXT sys·mmap(SB),7,$0
        INT     $3
        RET
 
-// int64 futex(int32 *uaddr, int32 op, int32 val,
+// int32 futex(int32 *uaddr, int32 op, int32 val,
 //     struct timespec *timeout, int32 *uaddr2, int32 val2);
 TEXT futex(SB),7,$0
        MOVL    $240, AX        // futex
@@ -117,22 +100,24 @@ TEXT futex(SB),7,$0
        INT     $0x80
        RET
 
-// int64 clone(int32 flags, void *stack, M *m, G *g, void (*fn)(void));
+// int32 clone(int32 flags, void *stack, M *m, G *g, void (*fn)(void));
 TEXT clone(SB),7,$0
        MOVL    $120, AX        // clone
        MOVL    flags+4(SP), BX
        MOVL    stack+8(SP), CX
+       MOVL    $0, DX  // parent tid ptr
+       MOVL    $0, DI  // child tid ptr
 
        // Copy m, g, fn off parent stack for use by child.
-       SUBL    $12, CX
-       MOVL    m+12(SP), DX
-       MOVL    DX, 0(CX)
-       MOVL    g+16(SP), DX
-       MOVL    DX, 4(CX)
-       MOVL    fn+20(SP), DX
-       MOVL    DX, 8(CX)
-
-       MOVL    $120, AX
+       SUBL    $16, CX
+       MOVL    mm+12(SP), SI
+       MOVL    SI, 0(CX)
+       MOVL    gg+16(SP), SI
+       MOVL    SI, 4(CX)
+       MOVL    fn+20(SP), SI
+       MOVL    SI, 8(CX)
+       MOVL    $1234, 12(CX)
+
        INT     $0x80
 
        // In parent, return.
@@ -140,29 +125,58 @@ TEXT clone(SB),7,$0
        JEQ     2(PC)
        RET
 
-       // In child, set up new stack, etc.
-       MOVL    0(CX), BX       // m
-       MOVL    12(AX), AX      // fs (= m->cret)
-       MOVW    AX, FS
-       MOVL    8(CX), DX       // fn
-       ADDL    $12, CX
-       MOVL    CX, SP
-
-       // fn is now on top of stack.
+       // Paranoia: check that SP is as we expect.
+       MOVL    12(SP), BP
+       CMPL    BP, $1234
+       JEQ     2(PC)
+       INT     $3
 
-       // initialize m->procid to Linux tid
+       // Initialize AX to Linux tid
        MOVL    $224, AX
        INT     $0x80
-       MOVL    AX, 20(BX)
-
-       // call fn
-       CALL    DX
 
-       // It shouldn't return; if it does, exit.
-       MOVL    $111, DI
-       MOVL    $1, AX
-       INT     $0x80
-       JMP     -3(PC)  // keep exiting
+       // In child on new stack.  Reload registers (paranoia).
+       MOVL    0(SP), BX       // m
+       MOVL    4(SP), DX       // g
+       MOVL    8(SP), CX       // fn
+
+       MOVL    AX, m_procid(BX)        // save tid as m->procid
+
+       // set up ldt 7+id to point at m->tls.
+       // m->tls is at m+40.  newosproc left the id in tls[0].
+       LEAL    m_tls(BX), BP
+       MOVL    0(BP), DI
+       ADDL    $7, DI  // m0 is LDT#7. count up.
+       // setldt(tls#, &tls, sizeof tls)
+       PUSHAL  // save registers
+       PUSHL   $32     // sizeof tls
+       PUSHL   BP      // &tls
+       PUSHL   DI      // tls #
+       CALL    setldt(SB)
+       POPL    AX
+       POPL    AX
+       POPL    AX
+       POPAL
+       SHLL    $3, DI  // segment# is ldt*8 + 7 (different 7 than above)
+       ADDL    $7, DI
+       MOVW    DI, FS
+
+       // Now segment is established.  Initialize m, g.
+       MOVL    DX, g
+       MOVL    BX, m
+
+       MOVL    0(DX), DX       // paranoia; check they are not nil
+       MOVL    0(BX), BX
+
+       // more paranoia; check that stack splitting code works
+       PUSHAL
+       CALL    emptyfunc(SB)
+       POPAL
+
+       CALL    CX      // fn()
+       CALL    exit1(SB)
+       MOVL    $0x1234, 0x1005
+       RET
 
 TEXT sigaltstack(SB),7,$-8
        MOVL    $186, AX        // sigaltstack
@@ -174,10 +188,6 @@ TEXT sigaltstack(SB),7,$-8
        INT     $3
        RET
 
-//     // fake the per-goroutine and per-mach registers
-//     LEAL    m0(SB),
-
-// TODO(rsc): move to linux.s
 // <asm-i386/ldt.h>
 // struct user_desc {
 //     unsigned int  entry_number;
index c6161936760e9e90447999763ed5a21909a5399d..c36813a9bfb246a22e08f4cd13e2d58ca2ed67ad 100644 (file)
@@ -3,8 +3,8 @@
 // license that can be found in the LICENSE file.
 
 // Linux-specific system calls
-int64  futex(uint32*, int32, uint32, Timespec*, uint32*, uint32);
-int64  clone(int32, void*, M*, G*, void(*)(void));
+int32  futex(uint32*, int32, uint32, Timespec*, uint32*, uint32);
+int32  clone(int32, void*, M*, G*, void(*)(void));
 
 struct Sigaction;
 void   rt_sigaction(int64, struct Sigaction*, void*, uint64);
index cc9ba161bfdde9500e5cf15e4d0e8577b972d3b8..a1d927c7bb7c24bd9e355d25bbbc195f50172a60 100644 (file)
@@ -42,7 +42,7 @@ static Timespec longtime =
 static void
 futexsleep(uint32 *addr, uint32 val)
 {
-       int64 ret;
+       int32 ret;
 
        ret = futex(addr, FUTEX_WAIT, val, &longtime, nil, 0);
        if(ret >= 0 || ret == -EAGAIN || ret == -EINTR)
@@ -234,7 +234,7 @@ enum
 void
 newosproc(M *m, G *g, void *stk, void (*fn)(void))
 {
-       int64 ret;
+       int32 ret;
        int32 flags;
 
        /*
@@ -248,21 +248,14 @@ newosproc(M *m, G *g, void *stk, void (*fn)(void))
                | CLONE_THREAD  /* revisit - okay for now */
                ;
 
+       m->tls[0] = m->id;      // so 386 asm can find it
        if(0){
-               prints("newosproc stk=");
-               sys·printpointer(stk);
-               prints(" m=");
-               sys·printpointer(m);
-               prints(" g=");
-               sys·printpointer(g);
-               prints(" fn=");
-               sys·printpointer(fn);
-               prints(" clone=");
-               sys·printpointer(clone);
-               prints("\n");
+               printf("newosproc stk=%p m=%p g=%p fn=%p clone=%p id=%d/%d ostk=%p\n",
+                       stk, m, g, fn, clone, m->id, m->tls[0], &m);
        }
 
        ret = clone(flags, stk, m, g, fn);
+
        if(ret < 0)
                *(int32*)123 = 123;
 }