stub.c - vx32 - Local 9vx git repository for patches.
 (HTM) git clone git://r-36.net/vx32
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       stub.c (7582B)
       ---
            1 
            2 #define        WANT_M
            3 
            4 #ifdef __APPLE__
            5 #define __DARWIN_UNIX03 0
            6 #endif
            7 
            8 #include        "u.h"
            9 #include        <sched.h>
           10 #include        <signal.h>
           11 #include        "lib.h"
           12 #include        "mem.h"
           13 #include        "dat.h"
           14 #include        "fns.h"
           15 #include        "error.h"
           16 
           17 int tracefp;
           18 
           19 /*
           20  * Simple xalloc memory allocator.
           21  */
           22 static int xalloced;
           23 
           24 void*
           25 xallocz(ulong size, int zero)
           26 {
           27         void *v;
           28         
           29         v = malloc(size);
           30         if(v && zero)
           31                 memset(v, 0, size);
           32         if(v)
           33                 xalloced += size;
           34         return v;
           35 }
           36 
           37 void*
           38 xalloc(ulong size)
           39 {
           40         return xallocz(size, 1);
           41 }
           42 
           43 void
           44 xfree(void *p)
           45 {
           46         free(p);
           47 }
           48 
           49 void
           50 xsummary(void)
           51 {
           52         print("%d allocated\n", xalloced);
           53 }
           54 
           55 /* 
           56  * Very simple non-caching cache implementation.
           57  */
           58 void
           59 cinit(void)
           60 {
           61 }
           62 
           63 void
           64 copen(Chan *c)
           65 {
           66         USED(c);
           67 }
           68 
           69 int
           70 cread(Chan *c, uchar *buf, int len, vlong off)
           71 {
           72         USED(c);
           73         USED(buf);
           74         USED(len);
           75         USED(off);
           76 
           77         return 0;
           78 }
           79 
           80 void
           81 cupdate(Chan *c, uchar *buf, int len, vlong off)
           82 {
           83         USED(c);
           84         USED(buf);
           85         USED(len);
           86         USED(off);
           87 }
           88 
           89 void
           90 cwrite(Chan* c, uchar *buf, int len, vlong off)
           91 {
           92         USED(c);
           93         USED(buf);
           94         USED(len);
           95         USED(off);
           96 }
           97 
           98 /*
           99  * Interrupt priority level
          100  */
          101 int
          102 _splx(int s)
          103 {
          104         int ospl;
          105         
          106         ospl = m->spl;
          107         m->spl = s;
          108         return ospl;
          109 }
          110 
          111 int
          112 splhi(void)
          113 {
          114         return _splx(1);
          115 }
          116 
          117 int
          118 spllo(void)
          119 {
          120         return _splx(0);
          121 }
          122 
          123 int
          124 islo(void)
          125 {
          126         return m->spl == 0;
          127 }
          128 
          129 void
          130 splx(int s)
          131 {
          132         _splx(s);
          133 }
          134 
          135 
          136 /*
          137  * Floating point.
          138  */
          139 void
          140 fpoff(void)
          141 {
          142 }
          143 
          144 void
          145 fpinit(void)
          146 {
          147         if(tracefp)
          148                 iprint("fpinit\n");
          149 
          150 #ifdef i386
          151         asm volatile(
          152                 "finit\n"
          153                 "fwait\n"
          154                 "pushw $0x232\n"
          155                 "fldcw 0(%%esp)\n"
          156                 "popw %%ax\n"
          157                 "fwait\n" : : : "memory");
          158 #else
          159         asm volatile(
          160                 "finit\n"
          161                 "fwait\n"
          162                 "pushq $0x232\n"
          163                 "fldcw 0(%%rsp)\n"
          164                 "popq %%rax\n"
          165                 "fwait\n" : : : "memory");
          166 #endif
          167 
          168 }
          169 
          170 void
          171 fpsave(FPsave *s)
          172 {
          173 #ifdef i386
          174         asm volatile("fnsave 0(%%eax)\n" : : "a" (s) : "memory");
          175 #else
          176         asm volatile("fnsave 0(%%rax)\n" : : "a" (s) : "memory");
          177 #endif
          178         if(tracefp)
          179                 iprint("fpsave: %#x %#x %#x %#ux\n", s->control, s->status, s->tag, s->pc);
          180 }
          181 
          182 void
          183 fprestore(FPsave *s)
          184 {
          185         if(tracefp)
          186                 iprint("fprestore: %#x %#x %#x %#ux\n", s->control, s->status, s->tag, s->pc);
          187 #ifdef i386
          188         asm volatile("frstor 0(%%eax); fwait\n" : : "a" (s) : "memory");
          189 #else
          190         asm volatile("frstor 0(%%rax); fwait\n" : : "a" (s) : "memory");
          191 #endif
          192 }
          193 
          194 void
          195 fpenv(FPsave *s)
          196 {
          197         if(tracefp)
          198                 iprint("fpenv: %#x %#x %#x %#ux\n", s->control, s->status, s->tag, s->pc);
          199 #ifdef i386
          200         asm volatile("fstenv 0(%%eax)\n" : : "a" (s) : "memory");
          201 #else
          202         asm volatile("fstenv 0(%%rax)\n" : : "a" (s) : "memory");
          203 #endif
          204 }
          205 
          206 void
          207 fpclear(void)
          208 {
          209         if(tracefp)
          210                 iprint("fpclear\n");
          211         asm volatile("fclex\n");
          212 }
          213 
          214 ulong
          215 fpstatus(void)
          216 {
          217         ushort x;
          218         asm volatile("fstsw %%ax\n" : "=a" (x));
          219         return x;
          220 }
          221 
          222 
          223 /*
          224  * Malloc (#defined to _kmalloc) zeros its memory.
          225  */
          226 void*
          227 malloc(ulong size)
          228 {
          229         return calloc(1, size);
          230 }
          231 
          232 void
          233 mallocsummary(void)
          234 {
          235 }
          236 
          237 void
          238 setmalloctag(void *v, ulong tag)
          239 {
          240 }
          241 
          242 void*
          243 smalloc(ulong size)
          244 {
          245         void *v;
          246 
          247         for(;;){
          248                 v = malloc(size);
          249                 if(v != nil){
          250                         memset(v, 0, size);  // XXX
          251                         return v;
          252                 }
          253                 tsleep(&up->sleep, return0, 0, 100);
          254         }
          255 }
          256 
          257 
          258 #undef malloc
          259 void*
          260 mallocz(ulong size, int clr)
          261 {
          262         if(clr)
          263                 return calloc(1, size);
          264         else
          265                 return malloc(size);
          266 }
          267 #define malloc _kmalloc
          268 
          269 
          270 /*
          271  * Spin locks
          272  */
          273 int
          274 tas(void *x)
          275 {
          276         int     v;
          277 
          278 #ifdef i386
          279         __asm__(        "movl   $1, %%eax\n\t"
          280                         "xchgl  %%eax,(%%ecx)"
          281                         : "=a" (v)
          282                         : "c" (x)
          283         );
          284 #else
          285         __asm__(        "movl   $1, %%eax\n\t"
          286                         "xchgl  %%eax,(%%rcx)"
          287                         : "=a" (v)
          288                         : "c" (x)
          289         );
          290 #endif
          291 
          292         switch(v) {
          293         case 0:
          294         case 1:
          295                 return v;
          296         default:
          297                 print("tas: corrupted lock 0x%lux\n", v);
          298                 return 1;
          299         }
          300 }
          301 
          302 int
          303 _tas(void *x)
          304 {
          305         return tas(x);
          306 }
          307 
          308 int
          309 lock(Lock *lk)
          310 {
          311         int i, j, printed;
          312         
          313         for(i=0; i<1000; i++){
          314                 if(canlock(lk))
          315                         return 1;
          316                 sched_yield();
          317         }
          318         for(j=10; j<=1000; j*=10)
          319                 for(i=0; i<10; i++){
          320                         if(canlock(lk))
          321                                 return 1;
          322                         microdelay(j);
          323                 }
          324         printed = 0;
          325         for(;;){
          326                 if(canlock(lk))
          327                         return 1;
          328                 if(!printed++)
          329                         iprint("cpu%d deadlock? %p caller=%p\n",
          330                                 m->machno, lk, getcallerpc(&lk));
          331                 microdelay(10000);
          332         }
          333         return 0;
          334 }
          335 
          336 void
          337 unlock(Lock *l)
          338 {
          339         if(l->key == 0)
          340                 iprint("unlock: not locked: pc %luX\n",
          341                         getcallerpc(&l));
          342         if(l->isilock)
          343                 iprint("unlock of ilock: pc %lux, held by %lux\n",
          344                         getcallerpc(&l), l->pc);
          345         if(l->p != up)
          346                 iprint("unlock: up changed: pc %lux, acquired at pc %lux, lock p 0x%p, unlock up 0x%p\n",
          347                         getcallerpc(&l), l->pc, l->p, up);
          348         l->m_ = nil;
          349         if(up)
          350                 up->nlocks.ref--;
          351         l->key = 0;
          352 }
          353 
          354 int
          355 canlock(Lock *l)
          356 {
          357         if(up)
          358                 up->nlocks.ref++;
          359         if(tas(&l->key)){
          360                 if(up)
          361                         up->nlocks.ref--;
          362                 return 0;
          363         }
          364 
          365         if(up)
          366                 up->lastlock = l;
          367         l->pc = getcallerpc(&l);
          368         l->p = up;
          369         l->m_ = MACHP(m->machno);
          370         l->isilock = 0;
          371         return 1;
          372 }
          373 
          374 void
          375 ilock(Lock *lk)
          376 {
          377         int s;
          378         
          379         s = splhi();
          380         lock(lk);
          381         lk->sr = s;
          382 }
          383 
          384 void
          385 iunlock(Lock *lk)
          386 {
          387         int s;
          388         
          389         s = lk->sr;
          390         unlock(lk);
          391         splx(s);
          392 }
          393 
          394 
          395 /*
          396  * One of a kind
          397  */
          398 #include "kerndate.h"
          399 
          400 ulong
          401 getcallerpc(void *v)
          402 {
          403         return ((ulong*)v)[-1];
          404 }
          405 
          406 static int randfd = -1;
          407 void
          408 randominit(void)
          409 {
          410         if((randfd = open("/dev/urandom", OREAD)) < 0)
          411         if((randfd = open("/dev/random", OREAD)) < 0)
          412                 panic("open /dev/random: %r");
          413 }
          414 
          415 ulong
          416 randomread(void *v, ulong n)
          417 {
          418         int r;
          419 
          420         if(randfd < 0)
          421                 randominit();
          422         if((r = read(randfd, v, n)) != n)
          423                 panic("short read from /dev/random: %d but %d", n, r);
          424         return r;
          425 }
          426 
          427 int cpuserver = 0;
          428 
          429 void
          430 rebootcmd(int argc, char **argv)
          431 {
          432         int i;
          433         restoretty();
          434         for(i = 0; i < argc; i++)
          435                 iprint("%s%s", argv[i], argc - i > 1 ? " " : "");
          436         if(argc > 0)
          437                 iprint("\n");
          438         exit(0);
          439         error(Egreg);
          440 }
          441 
          442 void
          443 labelinit(Label *l, ulong pc, ulong sp)
          444 {
          445         assert(l);
          446         setlabel(l);
          447         l->pc = pc;
          448 
          449         /*
          450          * Stack pointer at call instruction (before return address
          451          * gets pushed) must be 16-byte aligned.
          452          */
          453         if((uintptr)sp%4)
          454                 panic("labelinit %#lux %#lux", pc, sp);
          455         while((uintptr)sp%64)
          456                 sp -= 4;
          457         sp -= 8;        // trial and error on OS X
          458         l->sp = sp;
          459 //iprint("labelinit %p %p\n", pc, sp);
          460 }
          461 
          462 void
          463 dumpstack(void)
          464 {
          465 }
          466 
          467 void
          468 rdb(void)
          469 {
          470 }
          471 
          472 void
          473 halt(void)
          474 {
          475 }
          476 
          477 void
          478 checkmmu(ulong a, ulong b)
          479 {
          480 }
          481 
          482 void
          483 delay(int x)
          484 {
          485         // no
          486 }
          487 
          488 void
          489 reboot(void *entry, void *code, ulong size)
          490 {
          491         restoretty(); exit(0);
          492         error(Egreg);
          493 }
          494 
          495 void
          496 countpagerefs(ulong *ref, int print)
          497 {
          498         panic("countpagerefs");
          499 }
          500 
          501 
          502 /*
          503  * Debugging prints go to standard error, always.
          504  */
          505 int
          506 iprint(char *fmt, ...)
          507 {
          508         int n;
          509         va_list arg;
          510         char buf[PRINTSIZE];
          511 
          512         va_start(arg, fmt);
          513         n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf;
          514         va_end(arg);
          515         write(2, buf, n);
          516         return n;
          517 }
          518 
          519 void 
          520 talktome(void)
          521 {
          522         int i;
          523         static char cmd[512];
          524         while (fgets(cmd, sizeof(cmd), stdin)) {
          525                 if (! strcmp(cmd, "mach")) {
          526                         for(i = 0; i < MAXMACH; i++) {
          527                                 fprintf(stderr, "%ld ", MACHP(i)->splpc);
          528                         }
          529                 }
          530         }
          531         fprintf(stderr, "We're done talking\n");
          532 }
          533 /*
          534  * Panics go to standard error.
          535  */
          536 int panicking;
          537 void
          538 panic(char *fmt, ...)
          539 {
          540         int n;
          541         va_list arg;
          542         char buf[PRINTSIZE];
          543 
          544         if(panicking)
          545                 for(;;);
          546         panicking = 1;
          547 
          548         strcpy(buf, "9vx panic: ");
          549         va_start(arg, fmt);
          550         n = vseprint(buf+strlen(buf), buf+sizeof(buf), fmt, arg) - buf;
          551         va_end(arg);
          552         buf[n] = '\n';
          553         write(2, buf, n+1);
          554         restoretty();
          555         if(doabort){
          556 #ifdef __APPLE__
          557                 fprint(2, "sleeping, so you can attach gdb to pid %d\n", (int)getpid());
          558                 for(;;)
          559                         microdelay(1000000);
          560 #else
          561                 fprint(2, "aborting, to dump core.\n");
          562                 talktome();
          563                 abort();
          564 #endif
          565         }
          566         exit(0);
          567 }
          568 
          569 /*
          570  * Sleazy: replace vsnprintf with vsnprint, so that
          571  * vxprint will use the Fmt library, which behaves
          572  * better on small stacks.
          573  *
          574  * TODO: Apple linker doesn't like this.
          575  */
          576 #ifndef __APPLE__
          577 int
          578 vsnprintf(char *buf, size_t nbuf, const char *fmt, va_list arg)
          579 {
          580         return vsnprint(buf, nbuf, (char*)fmt, arg);
          581 }
          582 #endif