1 /* $NetBSD: emul.c,v 1.122 2010/02/08 19:02:33 joerg 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.122 2010/02/08 19:02:33 joerg 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 timeval boottime; 77 struct emul emul_netbsd; 78 int cold = 1; 79 int boothowto = AB_SILENT; 80 struct tty *constty; 81 82 char hostname[MAXHOSTNAMELEN]; 83 size_t hostnamelen; 84 85 const char *panicstr; 86 const char *domainname; 87 int domainnamelen; 88 89 const struct filterops sig_filtops; 90 91 #define DEVSW_SIZE 255 92 const struct bdevsw *bdevsw0[DEVSW_SIZE]; /* XXX storage size */ 93 const struct bdevsw **bdevsw = bdevsw0; 94 const int sys_cdevsws = DEVSW_SIZE; 95 int max_cdevsws = DEVSW_SIZE; 96 97 const struct cdevsw *cdevsw0[DEVSW_SIZE]; /* XXX storage size */ 98 const struct cdevsw **cdevsw = cdevsw0; 99 const int sys_bdevsws = DEVSW_SIZE; 100 int max_bdevsws = DEVSW_SIZE; 101 102 struct devsw_conv devsw_conv0; 103 struct devsw_conv *devsw_conv = &devsw_conv0; 104 int max_devsw_convs = 0; 105 int mem_no = 2; 106 107 struct device *booted_device; 108 struct device *booted_wedge; 109 int booted_partition; 110 111 /* XXX: unused */ 112 kmutex_t tty_lock; 113 krwlock_t exec_lock; 114 115 /* sparc doesn't sport constant page size */ 116 #ifdef __sparc__ 117 int nbpg = 4096; 118 #endif 119 120 struct loadavg averunnable = { 121 { 0 * FSCALE, 122 1 * FSCALE, 123 11 * FSCALE, }, 124 FSCALE, 125 }; 126 127 void 128 getnanouptime(struct timespec *ts) 129 { 130 131 rump_getuptime(ts); 132 } 133 134 void 135 getmicrouptime(struct timeval *tv) 136 { 137 struct timespec ts; 138 139 getnanouptime(&ts); 140 TIMESPEC_TO_TIMEVAL(tv, &ts); 141 } 142 143 static void 144 gettime(struct timespec *ts) 145 { 146 uint64_t sec, nsec; 147 int error; 148 149 rumpuser_gettime(&sec, &nsec, &error); 150 ts->tv_sec = sec; 151 ts->tv_nsec = nsec; 152 } 153 154 void 155 nanotime(struct timespec *ts) 156 { 157 158 if (rump_threads) { 159 rump_gettime(ts); 160 } else { 161 gettime(ts); 162 } 163 } 164 165 /* hooray for mick, so what if I do */ 166 void 167 getnanotime(struct timespec *ts) 168 { 169 170 nanotime(ts); 171 } 172 173 void 174 microtime(struct timeval *tv) 175 { 176 struct timespec ts; 177 178 if (rump_threads) { 179 rump_gettime(&ts); 180 TIMESPEC_TO_TIMEVAL(tv, &ts); 181 } else { 182 gettime(&ts); 183 TIMESPEC_TO_TIMEVAL(tv, &ts); 184 } 185 } 186 187 void 188 getmicrotime(struct timeval *tv) 189 { 190 191 microtime(tv); 192 } 193 194 struct proc * 195 p_find(pid_t pid, uint flags) 196 { 197 198 panic("%s: not implemented", __func__); 199 } 200 201 struct pgrp * 202 pg_find(pid_t pid, uint flags) 203 { 204 205 panic("%s: not implemented", __func__); 206 } 207 208 void 209 psignal(struct proc *p, int signo) 210 { 211 212 switch (signo) { 213 case SIGSYS: 214 break; 215 default: 216 panic("unhandled signal %d\n", signo); 217 } 218 } 219 220 void 221 pgsignal(struct pgrp *pgrp, int sig, int checktty) 222 { 223 224 panic("%s: not implemented", __func__); 225 } 226 227 void 228 kpsignal(struct proc *p, ksiginfo_t *ksi, void *data) 229 { 230 231 panic("%s: not implemented", __func__); 232 } 233 234 void 235 kpgsignal(struct pgrp *pgrp, ksiginfo_t *ksi, void *data, int checkctty) 236 { 237 238 panic("%s: not implemented", __func__); 239 } 240 241 int 242 pgid_in_session(struct proc *p, pid_t pg_id) 243 { 244 245 panic("%s: not implemented", __func__); 246 } 247 248 int 249 sigispending(struct lwp *l, int signo) 250 { 251 252 return 0; 253 } 254 255 void 256 sigpending1(struct lwp *l, sigset_t *ss) 257 { 258 259 panic("%s: not implemented", __func__); 260 } 261 262 int 263 kpause(const char *wmesg, bool intr, int timeo, kmutex_t *mtx) 264 { 265 extern int hz; 266 int rv, error; 267 uint64_t sec, nsec; 268 269 if (mtx) 270 mutex_exit(mtx); 271 272 sec = timeo / hz; 273 nsec = (timeo % hz) * (1000000000 / hz); 274 rv = rumpuser_nanosleep(&sec, &nsec, &error); 275 276 if (mtx) 277 mutex_enter(mtx); 278 279 if (rv) 280 return error; 281 282 return 0; 283 } 284 285 void 286 suspendsched(void) 287 { 288 289 /* we don't control scheduling currently, can't do anything now */ 290 } 291 292 void 293 lwp_unsleep(lwp_t *l, bool cleanup) 294 { 295 296 KASSERT(mutex_owned(l->l_mutex)); 297 298 (*l->l_syncobj->sobj_unsleep)(l, cleanup); 299 } 300 301 vaddr_t 302 calc_cache_size(struct vm_map *map, int pct, int va_pct) 303 { 304 paddr_t t; 305 306 t = (paddr_t)physmem * pct / 100 * PAGE_SIZE; 307 if ((vaddr_t)t != t) { 308 panic("%s: needs tweak", __func__); 309 } 310 return t; 311 } 312 313 void 314 assert_sleepable(void) 315 { 316 317 /* always sleepable, although we should improve this */ 318 } 319 320 void 321 tc_setclock(const struct timespec *ts) 322 { 323 324 panic("%s: not implemented", __func__); 325 } 326 327 int 328 proc_uidmatch(kauth_cred_t cred, kauth_cred_t target) 329 { 330 331 panic("%s: not implemented", __func__); 332 } 333 334 void 335 proc_crmod_enter(void) 336 { 337 338 panic("%s: not implemented", __func__); 339 } 340 341 void 342 proc_crmod_leave(kauth_cred_t c1, kauth_cred_t c2, bool sugid) 343 { 344 345 panic("%s: not implemented", __func__); 346 } 347 348 void 349 module_init_md(void) 350 { 351 352 /* 353 * Nothing for now. However, we should load the librump 354 * symbol table. 355 */ 356 } 357 358 /* us and them, after all we're only ordinary seconds */ 359 static void 360 rump_delay(unsigned int us) 361 { 362 uint64_t sec, nsec; 363 int error; 364 365 sec = us / 1000000; 366 nsec = (us % 1000000) * 1000; 367 368 if (__predict_false(sec != 0)) 369 printf("WARNING: over 1s delay\n"); 370 371 rumpuser_nanosleep(&sec, &nsec, &error); 372 } 373 void (*delay_func)(unsigned int) = rump_delay; 374 375 bool 376 kpreempt(uintptr_t where) 377 { 378 379 return false; 380 } 381 382 /* 383 * There is no kernel thread preemption in rump currently. But call 384 * the implementing macros anyway in case they grow some side-effects 385 * down the road. 386 */ 387 void 388 kpreempt_disable(void) 389 { 390 391 KPREEMPT_DISABLE(curlwp); 392 } 393 394 void 395 kpreempt_enable(void) 396 { 397 398 KPREEMPT_ENABLE(curlwp); 399 } 400 401 void 402 proc_sesshold(struct session *ss) 403 { 404 405 panic("proc_sesshold() impossible, session %p", ss); 406 } 407 408 void 409 proc_sessrele(struct session *ss) 410 { 411 412 panic("proc_sessrele() impossible, session %p", ss); 413 } 414 415 int 416 proc_vmspace_getref(struct proc *p, struct vmspace **vm) 417 { 418 419 /* XXX */ 420 *vm = p->p_vmspace; 421 return 0; 422 } 423 424 int 425 ttycheckoutq(struct tty *tp, int wait) 426 { 427 428 return 1; 429 } 430 431 void 432 cnputc(int c) 433 { 434 int error; 435 436 rumpuser_putchar(c, &error); 437 } 438 439 void 440 cnflush(void) 441 { 442 443 /* done */ 444 } 445 446 int 447 tputchar(int c, int flags, struct tty *tp) 448 { 449 450 cnputc(c); 451 return 0; 452 } 453 454 void 455 cpu_reboot(int howto, char *bootstr) 456 { 457 458 rump_reboot(howto); 459 460 /* this function is __dead, we must exit */ 461 rumpuser_exit(0); 462 } 463 464 int 465 syscall_establish(const struct emul *em, const struct syscall_package *sp) 466 { 467 extern struct sysent rump_sysent[]; 468 int i; 469 470 KASSERT(em == NULL || em == &emul_netbsd); 471 472 for (i = 0; sp[i].sp_call; i++) 473 rump_sysent[sp[i].sp_code].sy_call = sp[i].sp_call; 474 475 return 0; 476 } 477 478 int 479 syscall_disestablish(const struct emul *em, const struct syscall_package *sp) 480 { 481 482 return 0; 483 } 484 485 void 486 calcru(struct proc *p, struct timeval *up, struct timeval *sp, 487 struct timeval *ip, struct timeval *rp) 488 { 489 490 panic("%s unimplemented", __func__); 491 } 492 493 int 494 sigismasked(struct lwp *l, int sig) 495 { 496 497 return 0; 498 } 499