1 /* $NetBSD: emul.c,v 1.150 2011/03/21 16:41:08 pooka Exp $ */ 2 3 /* 4 * Copyright (c) 2007-2011 Antti Kantee. All Rights Reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 16 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 #include <sys/cdefs.h> 29 __KERNEL_RCSID(0, "$NetBSD: emul.c,v 1.150 2011/03/21 16:41:08 pooka Exp $"); 30 31 #include <sys/param.h> 32 #include <sys/null.h> 33 #include <sys/vnode.h> 34 #include <sys/stat.h> 35 #include <sys/select.h> 36 #include <sys/syslog.h> 37 #include <sys/namei.h> 38 #include <sys/kauth.h> 39 #include <sys/conf.h> 40 #include <sys/device.h> 41 #include <sys/queue.h> 42 #include <sys/file.h> 43 #include <sys/cpu.h> 44 #include <sys/kmem.h> 45 #include <sys/poll.h> 46 #include <sys/timetc.h> 47 #include <sys/tprintf.h> 48 #include <sys/module.h> 49 #include <sys/tty.h> 50 #include <sys/reboot.h> 51 #include <sys/syscallvar.h> 52 #include <sys/xcall.h> 53 #include <sys/sleepq.h> 54 55 #include <dev/cons.h> 56 57 #include <rump/rumpuser.h> 58 59 #include <uvm/uvm_map.h> 60 61 #include "rump_private.h" 62 63 /* 64 * physmem is largely unused (except for nmbcluster calculations), 65 * so pick a default value which suits ZFS. if an application wants 66 * a very small memory footprint, it can still adjust this before 67 * calling rump_init() 68 */ 69 #define PHYSMEM 512*256 70 int physmem = PHYSMEM; 71 int nkmempages = PHYSMEM/2; /* from le chapeau */ 72 #undef PHYSMEM 73 74 struct lwp lwp0; 75 struct vnode *rootvp; 76 dev_t rootdev = NODEV; 77 78 const int schedppq = 1; 79 int hardclock_ticks; 80 bool mp_online = false; 81 struct timeval boottime; 82 int cold = 1; 83 int boothowto = AB_SILENT; 84 struct tty *constty; 85 86 const struct bdevsw *bdevsw0[255]; 87 const struct bdevsw **bdevsw = bdevsw0; 88 const int sys_cdevsws = 255; 89 int max_cdevsws = 255; 90 91 const struct cdevsw *cdevsw0[255]; 92 const struct cdevsw **cdevsw = cdevsw0; 93 const int sys_bdevsws = 255; 94 int max_bdevsws = 255; 95 96 int mem_no = 2; 97 98 struct device *booted_device; 99 struct device *booted_wedge; 100 int booted_partition; 101 102 /* XXX: unused */ 103 kmutex_t tty_lock; 104 krwlock_t exec_lock; 105 106 struct lwplist alllwp = LIST_HEAD_INITIALIZER(alllwp); 107 108 /* sparc doesn't sport constant page size, pretend we have 4k pages */ 109 #ifdef __sparc__ 110 int nbpg = 4096; 111 int pgofset = 4096-1; 112 int pgshift = 12; 113 #endif 114 115 /* on sun3 VM_MAX_ADDRESS is a const variable */ 116 /* XXX: should be moved into rump.c and initialize for sun3 and sun3x? */ 117 #ifdef sun3 118 const vaddr_t kernbase = KERNBASE3; 119 #endif 120 121 struct loadavg averunnable = { 122 { 0 * FSCALE, 123 1 * FSCALE, 124 11 * FSCALE, }, 125 FSCALE, 126 }; 127 128 struct emul emul_netbsd = { 129 .e_name = "netbsd-rump", 130 .e_sysent = rump_sysent, 131 .e_vm_default_addr = uvm_default_mapaddr, 132 #ifdef __HAVE_SYSCALL_INTERN 133 .e_syscall_intern = syscall_intern, 134 #endif 135 }; 136 137 u_int nprocs = 1; 138 139 int 140 kpause(const char *wmesg, bool intr, int timeo, kmutex_t *mtx) 141 { 142 extern int hz; 143 int rv, error; 144 uint64_t sec, nsec; 145 146 if (mtx) 147 mutex_exit(mtx); 148 149 sec = timeo / hz; 150 nsec = (timeo % hz) * (1000000000 / hz); 151 rv = rumpuser_nanosleep(&sec, &nsec, &error); 152 153 if (mtx) 154 mutex_enter(mtx); 155 156 if (rv) 157 return error; 158 159 return 0; 160 } 161 162 void 163 lwp_unsleep(lwp_t *l, bool cleanup) 164 { 165 166 KASSERT(mutex_owned(l->l_mutex)); 167 168 (*l->l_syncobj->sobj_unsleep)(l, cleanup); 169 } 170 171 void 172 lwp_update_creds(struct lwp *l) 173 { 174 struct proc *p; 175 kauth_cred_t oldcred; 176 177 p = l->l_proc; 178 oldcred = l->l_cred; 179 l->l_prflag &= ~LPR_CRMOD; 180 181 mutex_enter(p->p_lock); 182 kauth_cred_hold(p->p_cred); 183 l->l_cred = p->p_cred; 184 mutex_exit(p->p_lock); 185 186 if (oldcred != NULL) 187 kauth_cred_free(oldcred); 188 } 189 190 vaddr_t 191 calc_cache_size(struct vm_map *map, int pct, int va_pct) 192 { 193 paddr_t t; 194 195 t = (paddr_t)physmem * pct / 100 * PAGE_SIZE; 196 if ((vaddr_t)t != t) { 197 panic("%s: needs tweak", __func__); 198 } 199 return t; 200 } 201 202 void 203 assert_sleepable(void) 204 { 205 206 /* always sleepable, although we should improve this */ 207 } 208 209 void 210 module_init_md(void) 211 { 212 213 /* 214 * Nothing for now. However, we should load the librump 215 * symbol table. 216 */ 217 } 218 219 /* us and them, after all we're only ordinary seconds */ 220 static void 221 rump_delay(unsigned int us) 222 { 223 uint64_t sec, nsec; 224 int error; 225 226 sec = us / 1000000; 227 nsec = (us % 1000000) * 1000; 228 229 if (__predict_false(sec != 0)) 230 printf("WARNING: over 1s delay\n"); 231 232 rumpuser_nanosleep(&sec, &nsec, &error); 233 } 234 void (*delay_func)(unsigned int) = rump_delay; 235 236 /* 237 * Provide weak aliases for tty routines used by printf. 238 * They will be used unless the rumpkern_tty component is present. 239 */ 240 241 int rump_ttycheckoutq(struct tty *, int); 242 int 243 rump_ttycheckoutq(struct tty *tp, int wait) 244 { 245 246 return 1; 247 } 248 __weak_alias(ttycheckoutq,rump_ttycheckoutq); 249 250 int rump_tputchar(int, int, struct tty *); 251 int 252 rump_tputchar(int c, int flags, struct tty *tp) 253 { 254 255 cnputc(c); 256 return 0; 257 } 258 __weak_alias(tputchar,rump_tputchar); 259 260 void 261 cnputc(int c) 262 { 263 int error; 264 265 rumpuser_putchar(c, &error); 266 } 267 268 void 269 cnflush(void) 270 { 271 272 /* done */ 273 } 274 275 #ifdef __HAVE_SYSCALL_INTERN 276 void 277 syscall_intern(struct proc *p) 278 { 279 280 /* no you don't */ 281 } 282 #endif 283 284 void 285 xc_send_ipi(struct cpu_info *ci) 286 { 287 288 /* I'll think about the implementation if this is ever used */ 289 panic("not implemented"); 290 } 291 292 int 293 trace_enter(register_t code, const register_t *args, int narg) 294 { 295 296 return 0; 297 } 298 299 void 300 trace_exit(register_t code, register_t rval[], int error) 301 { 302 303 /* nada */ 304 } 305 306 #ifdef LOCKDEBUG 307 void 308 turnstile_print(volatile void *obj, void (*pr)(const char *, ...)) 309 { 310 311 /* nada */ 312 } 313 #endif 314