/* $NetBSD: emul.c,v 1.202 2024/07/28 13:01:55 bad Exp $ */
/*
* Copyright (c) 2007-2011 Antti Kantee. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* physmem is largely unused (except for nmbcluster calculations),
* so pick a default value which suits ZFS. if an application wants
* a very small memory footprint, it can still adjust this before
* calling rump_init()
*/
#define PHYSMEM 512*256
psize_t physmem = PHYSMEM;
size_t nkmempages = PHYSMEM/2; /* from le chapeau */
#undef PHYSMEM
struct vnode *rootvp;
dev_t rootdev = NODEV;
const int schedppq = 1;
int cold = 1;
int shutting_down;
int boothowto = AB_SILENT;
struct tty *constty;
const struct bdevsw *bdevsw0[255];
const struct bdevsw **bdevsw = bdevsw0;
const int sys_bdevsws = 255;
int max_bdevsws = 255;
const struct cdevsw *cdevsw0[255];
const struct cdevsw **cdevsw = cdevsw0;
const int sys_cdevsws = 255;
int max_cdevsws = 255;
/* sparc doesn't sport constant page size, pretend we have 4k pages */
#ifdef __sparc__
int nbpg = 4096;
int pgofset = 4096-1;
int pgshift = 12;
#endif
/* on sun3 VM_MAX_ADDRESS is a const variable */
/* XXX: should be moved into rump.c and initialize for sun3 and sun3x? */
#ifdef sun3
const vaddr_t kernbase = KERNBASE3;
#endif
/*
* Nothing for now. However, we should load the librump
* symbol table.
*/
}
/*
* Try to emulate all the MD definitions of DELAY() / delay().
* Would be nice to fix the #defines in MD headers, but this quicker.
*
* XXX: we'd need a rumpuser_clock_sleep_nowrap() here. Since we
* don't have it in the current hypercall revision, busyloop.
* Note that rather than calibrate a loop delay and work with that,
* get call gettime (which does not block) in a loop to make sure
* we didn't get virtual ghosttime. That might be slightly inaccurate
* for very small delays ...
*
* The other option would be to run a thread in the hypervisor which
* sleeps for us and we can wait for it using rumpuser_cv_wait_nowrap()
* Probably too fussy. Better just wait for hypercall rev 18 ;)
*/
static void
rump_delay(unsigned int us)
{
struct timespec target, tmp;
uint64_t sec, sec_ini, sec_now;
long nsec, nsec_ini, nsec_now;
int loops;
if (!RUMP_LOCALPROC_P(curproc))
finiarg = RUMP_SPVM2CTL(curproc->p_vmspace);
else
finiarg = NULL;
/* dump means we really take the dive here */
if ((howto & RB_DUMP) || panicstr) {
ruhow = RUMPUSER_PANIC;
goto out;
}
/* try to sync */
if (!((howto & RB_NOSYNC) || panicstr)) {
rump_vfs_fini();
}
doshutdownhooks();
/* your wish is my command */
if (howto & RB_HALT) {
printf("rump kernel halted (with RB_HALT, not exiting)\n");
rump_sysproxy_fini(finiarg);
for (;;) {
rumpuser_clock_sleep(RUMPUSER_CLOCK_RELWALL, 10, 0);
}
}
/* this function is __dead, we must exit */
out:
rump_sysproxy_fini(finiarg);
rumpuser_exit(ruhow);
}