Home | History | Annotate | Line # | Download | only in rumpkern
emul.c revision 1.119
      1 /*	$NetBSD: emul.c,v 1.119 2010/01/15 19:01:04 pooka Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2007 Antti Kantee.  All Rights Reserved.
      5  *
      6  * Development of this software was supported by Google Summer of Code.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  * 1. Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  * 2. Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in the
     15  *    documentation and/or other materials provided with the distribution.
     16  *
     17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
     18  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     20  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     23  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     27  * SUCH DAMAGE.
     28  */
     29 
     30 #include <sys/cdefs.h>
     31 __KERNEL_RCSID(0, "$NetBSD: emul.c,v 1.119 2010/01/15 19:01:04 pooka Exp $");
     32 
     33 #include <sys/param.h>
     34 #include <sys/null.h>
     35 #include <sys/vnode.h>
     36 #include <sys/stat.h>
     37 #include <sys/select.h>
     38 #include <sys/syslog.h>
     39 #include <sys/namei.h>
     40 #include <sys/kauth.h>
     41 #include <sys/conf.h>
     42 #include <sys/device.h>
     43 #include <sys/queue.h>
     44 #include <sys/file.h>
     45 #include <sys/filedesc.h>
     46 #include <sys/cpu.h>
     47 #include <sys/kmem.h>
     48 #include <sys/poll.h>
     49 #include <sys/timetc.h>
     50 #include <sys/tprintf.h>
     51 #include <sys/module.h>
     52 #include <sys/tty.h>
     53 #include <sys/reboot.h>
     54 #include <sys/syscallvar.h>
     55 #include <sys/xcall.h>
     56 
     57 #include <dev/cons.h>
     58 
     59 #include <rump/rumpuser.h>
     60 
     61 #include <uvm/uvm_map.h>
     62 
     63 #include "rump_private.h"
     64 
     65 time_t time_second = 1;
     66 
     67 kmutex_t *proc_lock;
     68 struct lwp lwp0;
     69 struct vnode *rootvp;
     70 dev_t rootdev;
     71 int physmem = 256*256; /* 256 * 1024*1024 / 4k, PAGE_SIZE not always set */
     72 int doing_shutdown;
     73 const int schedppq = 1;
     74 int hardclock_ticks;
     75 bool mp_online = false;
     76 struct vm_map *mb_map;
     77 struct timeval boottime;
     78 struct emul emul_netbsd;
     79 int cold = 1;
     80 int boothowto = AB_SILENT;
     81 struct tty *constty;
     82 
     83 char hostname[MAXHOSTNAMELEN];
     84 size_t hostnamelen;
     85 
     86 const char *panicstr;
     87 const char *domainname;
     88 int domainnamelen;
     89 
     90 const struct filterops sig_filtops;
     91 
     92 #define DEVSW_SIZE 255
     93 const struct bdevsw *bdevsw0[DEVSW_SIZE]; /* XXX storage size */
     94 const struct bdevsw **bdevsw = bdevsw0;
     95 const int sys_cdevsws = DEVSW_SIZE;
     96 int max_cdevsws = DEVSW_SIZE;
     97 
     98 const struct cdevsw *cdevsw0[DEVSW_SIZE]; /* XXX storage size */
     99 const struct cdevsw **cdevsw = cdevsw0;
    100 const int sys_bdevsws = DEVSW_SIZE;
    101 int max_bdevsws = DEVSW_SIZE;
    102 
    103 struct devsw_conv devsw_conv0;
    104 struct devsw_conv *devsw_conv = &devsw_conv0;
    105 int max_devsw_convs = 0;
    106 int mem_no = 2;
    107 
    108 struct device *booted_device;
    109 struct device *booted_wedge;
    110 int booted_partition;
    111 
    112 kmutex_t tty_lock;
    113 
    114 /* sparc doesn't sport constant page size */
    115 #ifdef __sparc__
    116 int nbpg = 4096;
    117 #endif
    118 
    119 struct loadavg averunnable = {
    120 	{ 0 * FSCALE,
    121 	  1 * FSCALE,
    122 	  11 * FSCALE, },
    123 	FSCALE,
    124 };
    125 
    126 devclass_t
    127 device_class(device_t dev)
    128 {
    129 
    130 	return dev->dv_class;
    131 }
    132 
    133 void
    134 getnanouptime(struct timespec *ts)
    135 {
    136 
    137 	rump_getuptime(ts);
    138 }
    139 
    140 void
    141 getmicrouptime(struct timeval *tv)
    142 {
    143 	struct timespec ts;
    144 
    145 	getnanouptime(&ts);
    146 	TIMESPEC_TO_TIMEVAL(tv, &ts);
    147 }
    148 
    149 static void
    150 gettime(struct timespec *ts)
    151 {
    152 	uint64_t sec, nsec;
    153 	int error;
    154 
    155 	rumpuser_gettime(&sec, &nsec, &error);
    156 	ts->tv_sec = sec;
    157 	ts->tv_nsec = nsec;
    158 }
    159 
    160 void
    161 nanotime(struct timespec *ts)
    162 {
    163 
    164 	if (rump_threads) {
    165 		rump_gettime(ts);
    166 	} else {
    167 		gettime(ts);
    168 	}
    169 }
    170 
    171 /* hooray for mick, so what if I do */
    172 void
    173 getnanotime(struct timespec *ts)
    174 {
    175 
    176 	nanotime(ts);
    177 }
    178 
    179 void
    180 microtime(struct timeval *tv)
    181 {
    182 	struct timespec ts;
    183 
    184 	if (rump_threads) {
    185 		rump_gettime(&ts);
    186 		TIMESPEC_TO_TIMEVAL(tv, &ts);
    187 	} else {
    188 		gettime(&ts);
    189 		TIMESPEC_TO_TIMEVAL(tv, &ts);
    190 	}
    191 }
    192 
    193 void
    194 getmicrotime(struct timeval *tv)
    195 {
    196 
    197 	microtime(tv);
    198 }
    199 
    200 struct proc *
    201 p_find(pid_t pid, uint flags)
    202 {
    203 
    204 	panic("%s: not implemented", __func__);
    205 }
    206 
    207 struct pgrp *
    208 pg_find(pid_t pid, uint flags)
    209 {
    210 
    211 	panic("%s: not implemented", __func__);
    212 }
    213 
    214 void
    215 psignal(struct proc *p, int signo)
    216 {
    217 
    218 	switch (signo) {
    219 	case SIGSYS:
    220 		break;
    221 	default:
    222 		panic("unhandled signal %d\n", signo);
    223 	}
    224 }
    225 
    226 void
    227 pgsignal(struct pgrp *pgrp, int sig, int checktty)
    228 {
    229 
    230 	panic("%s: not implemented", __func__);
    231 }
    232 
    233 void
    234 kpsignal(struct proc *p, ksiginfo_t *ksi, void *data)
    235 {
    236 
    237 	panic("%s: not implemented", __func__);
    238 }
    239 
    240 void
    241 kpgsignal(struct pgrp *pgrp, ksiginfo_t *ksi, void *data, int checkctty)
    242 {
    243 
    244 	panic("%s: not implemented", __func__);
    245 }
    246 
    247 int
    248 pgid_in_session(struct proc *p, pid_t pg_id)
    249 {
    250 
    251 	panic("%s: not implemented", __func__);
    252 }
    253 
    254 int
    255 sigispending(struct lwp *l, int signo)
    256 {
    257 
    258 	return 0;
    259 }
    260 
    261 void
    262 sigpending1(struct lwp *l, sigset_t *ss)
    263 {
    264 
    265 	panic("%s: not implemented", __func__);
    266 }
    267 
    268 int
    269 kpause(const char *wmesg, bool intr, int timeo, kmutex_t *mtx)
    270 {
    271 	extern int hz;
    272 	int rv, error;
    273 	uint64_t sec, nsec;
    274 
    275 	if (mtx)
    276 		mutex_exit(mtx);
    277 
    278 	sec = timeo / hz;
    279 	nsec = (timeo % hz) * (1000000000 / hz);
    280 	rv = rumpuser_nanosleep(&sec, &nsec, &error);
    281 
    282 	if (mtx)
    283 		mutex_enter(mtx);
    284 
    285 	if (rv)
    286 		return error;
    287 
    288 	return 0;
    289 }
    290 
    291 void
    292 suspendsched(void)
    293 {
    294 
    295 	/* we don't control scheduling currently, can't do anything now */
    296 }
    297 
    298 void
    299 lwp_unsleep(lwp_t *l, bool cleanup)
    300 {
    301 
    302 	KASSERT(mutex_owned(l->l_mutex));
    303 
    304 	(*l->l_syncobj->sobj_unsleep)(l, cleanup);
    305 }
    306 
    307 vaddr_t
    308 calc_cache_size(struct vm_map *map, int pct, int va_pct)
    309 {
    310 	paddr_t t;
    311 
    312 	t = (paddr_t)physmem * pct / 100 * PAGE_SIZE;
    313 	if ((vaddr_t)t != t) {
    314 		panic("%s: needs tweak", __func__);
    315 	}
    316 	return t;
    317 }
    318 
    319 const char *
    320 device_xname(device_t dv)
    321 {
    322 	return "bogus0";
    323 }
    324 
    325 void
    326 assert_sleepable(void)
    327 {
    328 
    329 	/* always sleepable, although we should improve this */
    330 }
    331 
    332 void
    333 tc_setclock(const struct timespec *ts)
    334 {
    335 
    336 	panic("%s: not implemented", __func__);
    337 }
    338 
    339 int
    340 proc_uidmatch(kauth_cred_t cred, kauth_cred_t target)
    341 {
    342 
    343 	panic("%s: not implemented", __func__);
    344 }
    345 
    346 void
    347 proc_crmod_enter(void)
    348 {
    349 
    350 	panic("%s: not implemented", __func__);
    351 }
    352 
    353 void
    354 proc_crmod_leave(kauth_cred_t c1, kauth_cred_t c2, bool sugid)
    355 {
    356 
    357 	panic("%s: not implemented", __func__);
    358 }
    359 
    360 void
    361 module_init_md(void)
    362 {
    363 
    364 	/*
    365 	 * Nothing for now.  However, we should load the librump
    366 	 * symbol table.
    367 	 */
    368 }
    369 
    370 /* us and them, after all we're only ordinary seconds */
    371 static void
    372 rump_delay(unsigned int us)
    373 {
    374 	uint64_t sec, nsec;
    375 	int error;
    376 
    377 	sec = us / 1000000;
    378 	nsec = (us % 1000000) * 1000;
    379 
    380 	if (__predict_false(sec != 0))
    381 		printf("WARNING: over 1s delay\n");
    382 
    383 	rumpuser_nanosleep(&sec, &nsec, &error);
    384 }
    385 void (*delay_func)(unsigned int) = rump_delay;
    386 
    387 bool
    388 kpreempt(uintptr_t where)
    389 {
    390 
    391 	return false;
    392 }
    393 
    394 /*
    395  * There is no kernel thread preemption in rump currently.  But call
    396  * the implementing macros anyway in case they grow some side-effects
    397  * down the road.
    398  */
    399 void
    400 kpreempt_disable(void)
    401 {
    402 
    403 	KPREEMPT_DISABLE(curlwp);
    404 }
    405 
    406 void
    407 kpreempt_enable(void)
    408 {
    409 
    410 	KPREEMPT_ENABLE(curlwp);
    411 }
    412 
    413 void
    414 proc_sesshold(struct session *ss)
    415 {
    416 
    417 	panic("proc_sesshold() impossible, session %p", ss);
    418 }
    419 
    420 void
    421 proc_sessrele(struct session *ss)
    422 {
    423 
    424 	panic("proc_sessrele() impossible, session %p", ss);
    425 }
    426 
    427 int
    428 proc_vmspace_getref(struct proc *p, struct vmspace **vm)
    429 {
    430 
    431 	/* XXX */
    432 	*vm = p->p_vmspace;
    433 	return 0;
    434 }
    435 
    436 int
    437 ttycheckoutq(struct tty *tp, int wait)
    438 {
    439 
    440 	return 1;
    441 }
    442 
    443 void
    444 cnputc(int c)
    445 {
    446 	int error;
    447 
    448 	rumpuser_putchar(c, &error);
    449 }
    450 
    451 void
    452 cnflush(void)
    453 {
    454 
    455 	/* done */
    456 }
    457 
    458 int
    459 tputchar(int c, int flags, struct tty *tp)
    460 {
    461 
    462 	cnputc(c);
    463 	return 0;
    464 }
    465 
    466 void
    467 cpu_reboot(int howto, char *bootstr)
    468 {
    469 
    470 	rump_reboot(howto);
    471 
    472 	/* this function is __dead, we must exit */
    473 	rumpuser_exit(0);
    474 }
    475 
    476 int
    477 syscall_establish(const struct emul *em, const struct syscall_package *sp)
    478 {
    479 	extern struct sysent rump_sysent[];
    480 	int i;
    481 
    482 	KASSERT(em == NULL || em == &emul_netbsd);
    483 
    484 	for (i = 0; sp[i].sp_call; i++)
    485 		rump_sysent[sp[i].sp_code].sy_call = sp[i].sp_call;
    486 
    487 	return 0;
    488 }
    489 
    490 int
    491 syscall_disestablish(const struct emul *em, const struct syscall_package *sp)
    492 {
    493 
    494 	return 0;
    495 }
    496 
    497 void
    498 calcru(struct proc *p, struct timeval *up, struct timeval *sp,
    499 	struct timeval *ip, struct timeval *rp)
    500 {
    501 
    502 	panic("%s unimplemented", __func__);
    503 }
    504 
    505 int
    506 sigismasked(struct lwp *l, int sig)
    507 {
    508 
    509 	return 0;
    510 }
    511