vx32

Local 9vx git repository for patches.
git clone git://r-36.net/vx32
Log | Files | 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