machdep.c revision 17677
1/*- 2 * Copyright (c) 1992 Terrence R. Lambert. 3 * Copyright (c) 1982, 1987, 1990 The Regents of the University of California. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * William Jolitz. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed by the University of 20 * California, Berkeley and its contributors. 21 * 4. Neither the name of the University nor the names of its contributors 22 * may be used to endorse or promote products derived from this software 23 * without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 * 37 * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 38 * $Id: machdep.c,v 1.198 1996/08/12 20:03:16 wollman Exp $ 39 */ 40 41#include "npx.h" 42#include "opt_sysvipc.h" 43#include "opt_ddb.h" 44#include "opt_bounce.h" 45#include "opt_machdep.h" 46#include "opt_perfmon.h" 47 48#include <sys/param.h> 49#include <sys/systm.h> 50#include <sys/sysproto.h> 51#include <sys/signalvar.h> 52#include <sys/kernel.h> 53#include <sys/proc.h> 54#include <sys/buf.h> 55#include <sys/reboot.h> 56#include <sys/conf.h> 57#include <sys/file.h> 58#include <sys/callout.h> 59#include <sys/malloc.h> 60#include <sys/mbuf.h> 61#include <sys/mount.h> 62#include <sys/msgbuf.h> 63#include <sys/ioctl.h> 64#include <sys/sysent.h> 65#include <sys/tty.h> 66#include <sys/sysctl.h> 67#include <sys/devconf.h> 68#include <sys/vmmeter.h> 69 70#ifdef SYSVSHM 71#include <sys/shm.h> 72#endif 73 74#ifdef SYSVMSG 75#include <sys/msg.h> 76#endif 77 78#ifdef SYSVSEM 79#include <sys/sem.h> 80#endif 81 82#include <vm/vm.h> 83#include <vm/vm_param.h> 84#include <vm/vm_prot.h> 85#include <vm/lock.h> 86#include <vm/vm_kern.h> 87#include <vm/vm_object.h> 88#include <vm/vm_page.h> 89#include <vm/vm_map.h> 90#include <vm/vm_pager.h> 91#include <vm/vm_extern.h> 92 93#include <sys/user.h> 94#include <sys/exec.h> 95#include <sys/vnode.h> 96 97#include <ddb/ddb.h> 98 99#include <net/netisr.h> 100 101#include <machine/cpu.h> 102#include <machine/npx.h> 103#include <machine/reg.h> 104#include <machine/psl.h> 105#include <machine/clock.h> 106#include <machine/specialreg.h> 107#include <machine/sysarch.h> 108#include <machine/cons.h> 109#include <machine/devconf.h> 110#include <machine/bootinfo.h> 111#include <machine/md_var.h> 112#ifdef PERFMON 113#include <machine/perfmon.h> 114#endif 115 116#include <i386/isa/isa_device.h> 117#include <i386/isa/rtc.h> 118#include <machine/random.h> 119 120extern void init386 __P((int first)); 121extern int ptrace_set_pc __P((struct proc *p, unsigned int addr)); 122extern int ptrace_single_step __P((struct proc *p)); 123extern int ptrace_write_u __P((struct proc *p, vm_offset_t off, int data)); 124extern void dblfault_handler __P((void)); 125 126extern void identifycpu(void); /* XXX header file */ 127extern void earlysetcpuclass(void); /* same header file */ 128 129static void cpu_startup __P((void *)); 130SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL) 131 132 133#ifdef BOUNCE_BUFFERS 134extern char *bouncememory; 135extern int maxbkva; 136#ifdef BOUNCEPAGES 137int bouncepages = BOUNCEPAGES; 138#else 139int bouncepages = 0; 140#endif 141#endif /* BOUNCE_BUFFERS */ 142 143extern int freebufspace; 144int msgbufmapped = 0; /* set when safe to use msgbuf */ 145int _udatasel, _ucodesel; 146u_int atdevbase; 147 148 149int physmem = 0; 150int cold = 1; 151 152static int 153sysctl_hw_physmem SYSCTL_HANDLER_ARGS 154{ 155 int error = sysctl_handle_int(oidp, 0, ctob(physmem), req); 156 return (error); 157} 158 159SYSCTL_PROC(_hw, HW_PHYSMEM, physmem, CTLTYPE_INT|CTLFLAG_RD, 160 0, 0, sysctl_hw_physmem, "I", ""); 161 162static int 163sysctl_hw_usermem SYSCTL_HANDLER_ARGS 164{ 165 int error = sysctl_handle_int(oidp, 0, 166 ctob(physmem - cnt.v_wire_count), req); 167 return (error); 168} 169 170SYSCTL_PROC(_hw, HW_USERMEM, usermem, CTLTYPE_INT|CTLFLAG_RD, 171 0, 0, sysctl_hw_usermem, "I", ""); 172 173int boothowto = 0, bootverbose = 0, Maxmem = 0; 174static int badpages = 0; 175long dumplo; 176extern int bootdev; 177 178vm_offset_t phys_avail[10]; 179 180/* must be 2 less so 0 0 can signal end of chunks */ 181#define PHYS_AVAIL_ARRAY_END ((sizeof(phys_avail) / sizeof(vm_offset_t)) - 2) 182 183static void setup_netisrs __P((struct linker_set *)); /* XXX declare elsewhere */ 184 185static vm_offset_t buffer_sva, buffer_eva; 186vm_offset_t clean_sva, clean_eva; 187static vm_offset_t pager_sva, pager_eva; 188extern struct linker_set netisr_set; 189 190#define offsetof(type, member) ((size_t)(&((type *)0)->member)) 191 192static void 193cpu_startup(dummy) 194 void *dummy; 195{ 196 register unsigned i; 197 register caddr_t v; 198 vm_offset_t maxaddr; 199 vm_size_t size = 0; 200 int firstaddr; 201 vm_offset_t minaddr; 202 203 if (boothowto & RB_VERBOSE) 204 bootverbose++; 205 206 /* 207 * Initialize error message buffer (at end of core). 208 */ 209 210 /* avail_end was pre-decremented in init386() to compensate */ 211 for (i = 0; i < btoc(sizeof (struct msgbuf)); i++) 212 pmap_enter(pmap_kernel(), (vm_offset_t)msgbufp, 213 avail_end + i * PAGE_SIZE, 214 VM_PROT_ALL, TRUE); 215 msgbufmapped = 1; 216 217 /* 218 * Good {morning,afternoon,evening,night}. 219 */ 220 printf(version); 221 earlysetcpuclass(); 222 startrtclock(); 223 identifycpu(); 224#ifdef PERFMON 225 perfmon_init(); 226#endif 227 printf("real memory = %d (%dK bytes)\n", ptoa(Maxmem), ptoa(Maxmem) / 1024); 228 /* 229 * Display any holes after the first chunk of extended memory. 230 */ 231 if (badpages != 0) { 232 int indx = 1; 233 234 /* 235 * XXX skip reporting ISA hole & unmanaged kernel memory 236 */ 237 if (phys_avail[0] == PAGE_SIZE) 238 indx += 2; 239 240 printf("Physical memory hole(s):\n"); 241 for (; phys_avail[indx + 1] != 0; indx += 2) { 242 int size = phys_avail[indx + 1] - phys_avail[indx]; 243 244 printf("0x%08lx - 0x%08lx, %d bytes (%d pages)\n", phys_avail[indx], 245 phys_avail[indx + 1] - 1, size, size / PAGE_SIZE); 246 } 247 } 248 249 /* 250 * Quickly wire in netisrs. 251 */ 252 setup_netisrs(&netisr_set); 253 254/* 255#ifdef ISDN 256 DONET(isdnintr, NETISR_ISDN); 257#endif 258*/ 259 260 /* 261 * Allocate space for system data structures. 262 * The first available kernel virtual address is in "v". 263 * As pages of kernel virtual memory are allocated, "v" is incremented. 264 * As pages of memory are allocated and cleared, 265 * "firstaddr" is incremented. 266 * An index into the kernel page table corresponding to the 267 * virtual memory address maintained in "v" is kept in "mapaddr". 268 */ 269 270 /* 271 * Make two passes. The first pass calculates how much memory is 272 * needed and allocates it. The second pass assigns virtual 273 * addresses to the various data structures. 274 */ 275 firstaddr = 0; 276again: 277 v = (caddr_t)firstaddr; 278 279#define valloc(name, type, num) \ 280 (name) = (type *)v; v = (caddr_t)((name)+(num)) 281#define valloclim(name, type, num, lim) \ 282 (name) = (type *)v; v = (caddr_t)((lim) = ((name)+(num))) 283 valloc(callout, struct callout, ncallout); 284#ifdef SYSVSHM 285 valloc(shmsegs, struct shmid_ds, shminfo.shmmni); 286#endif 287#ifdef SYSVSEM 288 valloc(sema, struct semid_ds, seminfo.semmni); 289 valloc(sem, struct sem, seminfo.semmns); 290 /* This is pretty disgusting! */ 291 valloc(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int)); 292#endif 293#ifdef SYSVMSG 294 valloc(msgpool, char, msginfo.msgmax); 295 valloc(msgmaps, struct msgmap, msginfo.msgseg); 296 valloc(msghdrs, struct msg, msginfo.msgtql); 297 valloc(msqids, struct msqid_ds, msginfo.msgmni); 298#endif 299 300 if (nbuf == 0) { 301 nbuf = 30; 302 if( physmem > 1024) 303 nbuf += min((physmem - 1024) / 12, 1024); 304 } 305 nswbuf = min(nbuf, 128); 306 307 valloc(swbuf, struct buf, nswbuf); 308 valloc(buf, struct buf, nbuf); 309 310#ifdef BOUNCE_BUFFERS 311 /* 312 * If there is more than 16MB of memory, allocate some bounce buffers 313 */ 314 if (Maxmem > 4096) { 315 if (bouncepages == 0) { 316 bouncepages = 64; 317 bouncepages += ((Maxmem - 4096) / 2048) * 32; 318 } 319 v = (caddr_t)((vm_offset_t)round_page(v)); 320 valloc(bouncememory, char, bouncepages * PAGE_SIZE); 321 } 322#endif 323 324 /* 325 * End of first pass, size has been calculated so allocate memory 326 */ 327 if (firstaddr == 0) { 328 size = (vm_size_t)(v - firstaddr); 329 firstaddr = (int)kmem_alloc(kernel_map, round_page(size)); 330 if (firstaddr == 0) 331 panic("startup: no room for tables"); 332 goto again; 333 } 334 335 /* 336 * End of second pass, addresses have been assigned 337 */ 338 if ((vm_size_t)(v - firstaddr) != size) 339 panic("startup: table size inconsistency"); 340 341#ifdef BOUNCE_BUFFERS 342 clean_map = kmem_suballoc(kernel_map, &clean_sva, &clean_eva, 343 (nbuf*MAXBSIZE) + (nswbuf*MAXPHYS) + 344 maxbkva + pager_map_size, TRUE); 345 io_map = kmem_suballoc(clean_map, &minaddr, &maxaddr, maxbkva, FALSE); 346#else 347 clean_map = kmem_suballoc(kernel_map, &clean_sva, &clean_eva, 348 (nbuf*MAXBSIZE) + (nswbuf*MAXPHYS) + pager_map_size, TRUE); 349#endif 350 buffer_map = kmem_suballoc(clean_map, &buffer_sva, &buffer_eva, 351 (nbuf*MAXBSIZE), TRUE); 352 pager_map = kmem_suballoc(clean_map, &pager_sva, &pager_eva, 353 (nswbuf*MAXPHYS) + pager_map_size, TRUE); 354 exec_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr, 355 (16*ARG_MAX), TRUE); 356 exech_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr, 357 (32*ARG_MAX), TRUE); 358 u_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr, 359 (maxproc*UPAGES*PAGE_SIZE), FALSE); 360 361 /* 362 * Finally, allocate mbuf pool. Since mclrefcnt is an off-size 363 * we use the more space efficient malloc in place of kmem_alloc. 364 */ 365 mclrefcnt = (char *)malloc(nmbclusters+PAGE_SIZE/MCLBYTES, 366 M_MBUF, M_NOWAIT); 367 bzero(mclrefcnt, nmbclusters+PAGE_SIZE/MCLBYTES); 368 mcl_map = kmem_suballoc(kmem_map, (vm_offset_t *)&mbutl, &maxaddr, 369 nmbclusters * MCLBYTES, FALSE); 370 { 371 vm_size_t mb_map_size; 372 mb_map_size = nmbufs * MSIZE; 373 mb_map = kmem_suballoc(kmem_map, &minaddr, &maxaddr, 374 round_page(mb_map_size), FALSE); 375 } 376 377 /* 378 * Initialize callouts 379 */ 380 callfree = callout; 381 for (i = 1; i < ncallout; i++) 382 callout[i-1].c_next = &callout[i]; 383 384 if (boothowto & RB_CONFIG) { 385 userconfig(); 386 cninit(); /* the preferred console may have changed */ 387 } 388 389#ifdef BOUNCE_BUFFERS 390 /* 391 * init bounce buffers 392 */ 393 vm_bounce_init(); 394#endif 395 396 printf("avail memory = %d (%dK bytes)\n", ptoa(cnt.v_free_count), 397 ptoa(cnt.v_free_count) / 1024); 398 399 /* 400 * Set up buffers, so they can be used to read disk labels. 401 */ 402 bufinit(); 403 vm_pager_bufferinit(); 404 405 /* 406 * In verbose mode, print out the BIOS's idea of the disk geometries. 407 */ 408 if (bootverbose) { 409 printf("BIOS Geometries:\n"); 410 for (i = 0; i < N_BIOS_GEOM; i++) { 411 unsigned long bios_geom; 412 int max_cylinder, max_head, max_sector; 413 414 bios_geom = bootinfo.bi_bios_geom[i]; 415 416 /* 417 * XXX the bootstrap punts a 1200K floppy geometry 418 * when the get-disk-geometry interrupt fails. Skip 419 * drives that have this geometry. 420 */ 421 if (bios_geom == 0x4f010f) 422 continue; 423 424 printf(" %x:%08lx ", i, bios_geom); 425 max_cylinder = bios_geom >> 16; 426 max_head = (bios_geom >> 8) & 0xff; 427 max_sector = bios_geom & 0xff; 428 printf( 429 "0..%d=%d cylinders, 0..%d=%d heads, 1..%d=%d sectors\n", 430 max_cylinder, max_cylinder + 1, 431 max_head, max_head + 1, 432 max_sector, max_sector); 433 } 434 printf(" %d accounted for\n", bootinfo.bi_n_bios_used); 435 } 436} 437 438int 439register_netisr(num, handler) 440 int num; 441 netisr_t *handler; 442{ 443 444 if (num < 0 || num >= (sizeof(netisrs)/sizeof(*netisrs)) ) { 445 printf("register_netisr: bad isr number: %d\n", num); 446 return (EINVAL); 447 } 448 netisrs[num] = handler; 449 return (0); 450} 451 452static void 453setup_netisrs(ls) 454 struct linker_set *ls; 455{ 456 int i; 457 const struct netisrtab *nit; 458 459 for(i = 0; ls->ls_items[i]; i++) { 460 nit = (const struct netisrtab *)ls->ls_items[i]; 461 register_netisr(nit->nit_num, nit->nit_isr); 462 } 463} 464 465/* 466 * Send an interrupt to process. 467 * 468 * Stack is set up to allow sigcode stored 469 * at top to call routine, followed by kcall 470 * to sigreturn routine below. After sigreturn 471 * resets the signal mask, the stack, and the 472 * frame pointer, it returns to the user 473 * specified pc, psl. 474 */ 475void 476sendsig(catcher, sig, mask, code) 477 sig_t catcher; 478 int sig, mask; 479 u_long code; 480{ 481 register struct proc *p = curproc; 482 register int *regs; 483 register struct sigframe *fp; 484 struct sigframe sf; 485 struct sigacts *psp = p->p_sigacts; 486 int oonstack; 487 488 regs = p->p_md.md_regs; 489 oonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK; 490 /* 491 * Allocate and validate space for the signal handler context. 492 */ 493 if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack && 494 (psp->ps_sigonstack & sigmask(sig))) { 495 fp = (struct sigframe *)(psp->ps_sigstk.ss_sp + 496 psp->ps_sigstk.ss_size - sizeof(struct sigframe)); 497 psp->ps_sigstk.ss_flags |= SS_ONSTACK; 498 } else { 499 fp = (struct sigframe *)regs[tESP] - 1; 500 } 501 502 /* 503 * grow() will return FALSE if the fp will not fit inside the stack 504 * and the stack can not be grown. useracc will return FALSE 505 * if access is denied. 506 */ 507 if ((grow(p, (int)fp) == FALSE) || 508 (useracc((caddr_t)fp, sizeof (struct sigframe), B_WRITE) == FALSE)) { 509 /* 510 * Process has trashed its stack; give it an illegal 511 * instruction to halt it in its tracks. 512 */ 513 SIGACTION(p, SIGILL) = SIG_DFL; 514 sig = sigmask(SIGILL); 515 p->p_sigignore &= ~sig; 516 p->p_sigcatch &= ~sig; 517 p->p_sigmask &= ~sig; 518 psignal(p, SIGILL); 519 return; 520 } 521 522 /* 523 * Build the argument list for the signal handler. 524 */ 525 if (p->p_sysent->sv_sigtbl) { 526 if (sig < p->p_sysent->sv_sigsize) 527 sig = p->p_sysent->sv_sigtbl[sig]; 528 else 529 sig = p->p_sysent->sv_sigsize + 1; 530 } 531 sf.sf_signum = sig; 532 sf.sf_code = code; 533 sf.sf_scp = &fp->sf_sc; 534 sf.sf_addr = (char *) regs[tERR]; 535 sf.sf_handler = catcher; 536 537 /* save scratch registers */ 538 sf.sf_sc.sc_eax = regs[tEAX]; 539 sf.sf_sc.sc_ebx = regs[tEBX]; 540 sf.sf_sc.sc_ecx = regs[tECX]; 541 sf.sf_sc.sc_edx = regs[tEDX]; 542 sf.sf_sc.sc_esi = regs[tESI]; 543 sf.sf_sc.sc_edi = regs[tEDI]; 544 sf.sf_sc.sc_cs = regs[tCS]; 545 sf.sf_sc.sc_ds = regs[tDS]; 546 sf.sf_sc.sc_ss = regs[tSS]; 547 sf.sf_sc.sc_es = regs[tES]; 548 sf.sf_sc.sc_isp = regs[tISP]; 549 550 /* 551 * Build the signal context to be used by sigreturn. 552 */ 553 sf.sf_sc.sc_onstack = oonstack; 554 sf.sf_sc.sc_mask = mask; 555 sf.sf_sc.sc_sp = regs[tESP]; 556 sf.sf_sc.sc_fp = regs[tEBP]; 557 sf.sf_sc.sc_pc = regs[tEIP]; 558 sf.sf_sc.sc_ps = regs[tEFLAGS]; 559 560 /* 561 * Copy the sigframe out to the user's stack. 562 */ 563 if (copyout(&sf, fp, sizeof(struct sigframe)) != 0) { 564 /* 565 * Something is wrong with the stack pointer. 566 * ...Kill the process. 567 */ 568 sigexit(p, SIGILL); 569 }; 570 571 regs[tESP] = (int)fp; 572 regs[tEIP] = (int)(((char *)PS_STRINGS) - *(p->p_sysent->sv_szsigcode)); 573 regs[tEFLAGS] &= ~PSL_VM; 574 regs[tCS] = _ucodesel; 575 regs[tDS] = _udatasel; 576 regs[tES] = _udatasel; 577 regs[tSS] = _udatasel; 578} 579 580/* 581 * System call to cleanup state after a signal 582 * has been taken. Reset signal mask and 583 * stack state from context left by sendsig (above). 584 * Return to previous pc and psl as specified by 585 * context left by sendsig. Check carefully to 586 * make sure that the user has not modified the 587 * state to gain improper privileges. 588 */ 589int 590sigreturn(p, uap, retval) 591 struct proc *p; 592 struct sigreturn_args /* { 593 struct sigcontext *sigcntxp; 594 } */ *uap; 595 int *retval; 596{ 597 register struct sigcontext *scp; 598 register struct sigframe *fp; 599 register int *regs = p->p_md.md_regs; 600 int eflags; 601 602 /* 603 * (XXX old comment) regs[tESP] points to the return address. 604 * The user scp pointer is above that. 605 * The return address is faked in the signal trampoline code 606 * for consistency. 607 */ 608 scp = uap->sigcntxp; 609 fp = (struct sigframe *) 610 ((caddr_t)scp - offsetof(struct sigframe, sf_sc)); 611 612 if (useracc((caddr_t)fp, sizeof (*fp), 0) == 0) 613 return(EINVAL); 614 615 /* 616 * Don't allow users to change privileged or reserved flags. 617 */ 618#define EFLAGS_SECURE(ef, oef) ((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0) 619 eflags = scp->sc_ps; 620 /* 621 * XXX do allow users to change the privileged flag PSL_RF. The 622 * cpu sets PSL_RF in tf_eflags for faults. Debuggers should 623 * sometimes set it there too. tf_eflags is kept in the signal 624 * context during signal handling and there is no other place 625 * to remember it, so the PSL_RF bit may be corrupted by the 626 * signal handler without us knowing. Corruption of the PSL_RF 627 * bit at worst causes one more or one less debugger trap, so 628 * allowing it is fairly harmless. 629 */ 630 if (!EFLAGS_SECURE(eflags & ~PSL_RF, regs[tEFLAGS] & ~PSL_RF)) { 631#ifdef DEBUG 632 printf("sigreturn: eflags = 0x%x\n", eflags); 633#endif 634 return(EINVAL); 635 } 636 637 /* 638 * Don't allow users to load a valid privileged %cs. Let the 639 * hardware check for invalid selectors, excess privilege in 640 * other selectors, invalid %eip's and invalid %esp's. 641 */ 642#define CS_SECURE(cs) (ISPL(cs) == SEL_UPL) 643 if (!CS_SECURE(scp->sc_cs)) { 644#ifdef DEBUG 645 printf("sigreturn: cs = 0x%x\n", scp->sc_cs); 646#endif 647 trapsignal(p, SIGBUS, T_PROTFLT); 648 return(EINVAL); 649 } 650 651 /* restore scratch registers */ 652 regs[tEAX] = scp->sc_eax; 653 regs[tEBX] = scp->sc_ebx; 654 regs[tECX] = scp->sc_ecx; 655 regs[tEDX] = scp->sc_edx; 656 regs[tESI] = scp->sc_esi; 657 regs[tEDI] = scp->sc_edi; 658 regs[tCS] = scp->sc_cs; 659 regs[tDS] = scp->sc_ds; 660 regs[tES] = scp->sc_es; 661 regs[tSS] = scp->sc_ss; 662 regs[tISP] = scp->sc_isp; 663 664 if (useracc((caddr_t)scp, sizeof (*scp), 0) == 0) 665 return(EINVAL); 666 667 if (scp->sc_onstack & 01) 668 p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK; 669 else 670 p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK; 671 p->p_sigmask = scp->sc_mask &~ 672 (sigmask(SIGKILL)|sigmask(SIGCONT)|sigmask(SIGSTOP)); 673 regs[tEBP] = scp->sc_fp; 674 regs[tESP] = scp->sc_sp; 675 regs[tEIP] = scp->sc_pc; 676 regs[tEFLAGS] = eflags; 677 return(EJUSTRETURN); 678} 679 680/* 681 * Machine depdnetnt boot() routine 682 * 683 * I haven't seen anything too put here yet 684 * Possibly some stuff might be grafted back here from boot() 685 */ 686void 687cpu_boot(int howto) 688{ 689} 690 691/* 692 * Clear registers on exec 693 */ 694void 695setregs(p, entry, stack) 696 struct proc *p; 697 u_long entry; 698 u_long stack; 699{ 700 int *regs = p->p_md.md_regs; 701 702#ifdef USER_LDT 703 struct pcb *pcb = &p->p_addr->u_pcb; 704 705 /* was i386_user_cleanup() in NetBSD */ 706 if (pcb->pcb_ldt) { 707 if (pcb == curpcb) 708 lldt(GSEL(GUSERLDT_SEL, SEL_KPL)); 709 kmem_free(kernel_map, (vm_offset_t)pcb->pcb_ldt, 710 pcb->pcb_ldt_len * sizeof(union descriptor)); 711 pcb->pcb_ldt_len = (int)pcb->pcb_ldt = 0; 712 } 713#endif 714 715 bzero(regs, sizeof(struct trapframe)); 716 regs[tEIP] = entry; 717 regs[tESP] = stack; 718 regs[tEFLAGS] = PSL_USER | (regs[tEFLAGS] & PSL_T); 719 regs[tSS] = _udatasel; 720 regs[tDS] = _udatasel; 721 regs[tES] = _udatasel; 722 regs[tCS] = _ucodesel; 723 724 p->p_addr->u_pcb.pcb_flags = 0; /* no fp at all */ 725 load_cr0(rcr0() | CR0_TS); /* start emulating */ 726#if NNPX > 0 727 npxinit(__INITIAL_NPXCW__); 728#endif /* NNPX > 0 */ 729} 730 731static int 732sysctl_machdep_adjkerntz SYSCTL_HANDLER_ARGS 733{ 734 int error; 735 error = sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, 736 req); 737 if (!error && req->newptr) 738 resettodr(); 739 return (error); 740} 741 742SYSCTL_PROC(_machdep, CPU_ADJKERNTZ, adjkerntz, CTLTYPE_INT|CTLFLAG_RW, 743 &adjkerntz, 0, sysctl_machdep_adjkerntz, "I", ""); 744 745SYSCTL_INT(_machdep, CPU_DISRTCSET, disable_rtc_set, 746 CTLFLAG_RW, &disable_rtc_set, 0, ""); 747 748SYSCTL_STRUCT(_machdep, CPU_BOOTINFO, bootinfo, 749 CTLFLAG_RD, &bootinfo, bootinfo, ""); 750 751SYSCTL_INT(_machdep, CPU_WALLCLOCK, wall_cmos_clock, 752 CTLFLAG_RW, &wall_cmos_clock, 0, ""); 753 754/* 755 * Initialize 386 and configure to run kernel 756 */ 757 758/* 759 * Initialize segments & interrupt table 760 */ 761 762int currentldt; 763int _default_ldt; 764union descriptor gdt[NGDT]; /* global descriptor table */ 765struct gate_descriptor idt[NIDT]; /* interrupt descriptor table */ 766union descriptor ldt[NLDT]; /* local descriptor table */ 767 768static struct i386tss dblfault_tss; 769static char dblfault_stack[PAGE_SIZE]; 770 771extern struct user *proc0paddr; 772 773/* software prototypes -- in more palatable form */ 774struct soft_segment_descriptor gdt_segs[] = { 775/* GNULL_SEL 0 Null Descriptor */ 776{ 0x0, /* segment base address */ 777 0x0, /* length */ 778 0, /* segment type */ 779 0, /* segment descriptor priority level */ 780 0, /* segment descriptor present */ 781 0, 0, 782 0, /* default 32 vs 16 bit size */ 783 0 /* limit granularity (byte/page units)*/ }, 784/* GCODE_SEL 1 Code Descriptor for kernel */ 785{ 0x0, /* segment base address */ 786 0xfffff, /* length - all address space */ 787 SDT_MEMERA, /* segment type */ 788 0, /* segment descriptor priority level */ 789 1, /* segment descriptor present */ 790 0, 0, 791 1, /* default 32 vs 16 bit size */ 792 1 /* limit granularity (byte/page units)*/ }, 793/* GDATA_SEL 2 Data Descriptor for kernel */ 794{ 0x0, /* segment base address */ 795 0xfffff, /* length - all address space */ 796 SDT_MEMRWA, /* segment type */ 797 0, /* segment descriptor priority level */ 798 1, /* segment descriptor present */ 799 0, 0, 800 1, /* default 32 vs 16 bit size */ 801 1 /* limit granularity (byte/page units)*/ }, 802/* GLDT_SEL 3 LDT Descriptor */ 803{ (int) ldt, /* segment base address */ 804 sizeof(ldt)-1, /* length - all address space */ 805 SDT_SYSLDT, /* segment type */ 806 0, /* segment descriptor priority level */ 807 1, /* segment descriptor present */ 808 0, 0, 809 0, /* unused - default 32 vs 16 bit size */ 810 0 /* limit granularity (byte/page units)*/ }, 811/* GTGATE_SEL 4 Null Descriptor - Placeholder */ 812{ 0x0, /* segment base address */ 813 0x0, /* length - all address space */ 814 0, /* segment type */ 815 0, /* segment descriptor priority level */ 816 0, /* segment descriptor present */ 817 0, 0, 818 0, /* default 32 vs 16 bit size */ 819 0 /* limit granularity (byte/page units)*/ }, 820/* GPANIC_SEL 5 Panic Tss Descriptor */ 821{ (int) &dblfault_tss, /* segment base address */ 822 sizeof(struct i386tss)-1,/* length - all address space */ 823 SDT_SYS386TSS, /* segment type */ 824 0, /* segment descriptor priority level */ 825 1, /* segment descriptor present */ 826 0, 0, 827 0, /* unused - default 32 vs 16 bit size */ 828 0 /* limit granularity (byte/page units)*/ }, 829/* GPROC0_SEL 6 Proc 0 Tss Descriptor */ 830{ (int) kstack, /* segment base address */ 831 sizeof(struct i386tss)-1,/* length - all address space */ 832 SDT_SYS386TSS, /* segment type */ 833 0, /* segment descriptor priority level */ 834 1, /* segment descriptor present */ 835 0, 0, 836 0, /* unused - default 32 vs 16 bit size */ 837 0 /* limit granularity (byte/page units)*/ }, 838/* GUSERLDT_SEL 7 User LDT Descriptor per process */ 839{ (int) ldt, /* segment base address */ 840 (512 * sizeof(union descriptor)-1), /* length */ 841 SDT_SYSLDT, /* segment type */ 842 0, /* segment descriptor priority level */ 843 1, /* segment descriptor present */ 844 0, 0, 845 0, /* unused - default 32 vs 16 bit size */ 846 0 /* limit granularity (byte/page units)*/ }, 847/* GAPMCODE32_SEL 8 APM BIOS 32-bit interface (32bit Code) */ 848{ 0, /* segment base address (overwritten by APM) */ 849 0xfffff, /* length */ 850 SDT_MEMERA, /* segment type */ 851 0, /* segment descriptor priority level */ 852 1, /* segment descriptor present */ 853 0, 0, 854 1, /* default 32 vs 16 bit size */ 855 1 /* limit granularity (byte/page units)*/ }, 856/* GAPMCODE16_SEL 9 APM BIOS 32-bit interface (16bit Code) */ 857{ 0, /* segment base address (overwritten by APM) */ 858 0xfffff, /* length */ 859 SDT_MEMERA, /* segment type */ 860 0, /* segment descriptor priority level */ 861 1, /* segment descriptor present */ 862 0, 0, 863 0, /* default 32 vs 16 bit size */ 864 1 /* limit granularity (byte/page units)*/ }, 865/* GAPMDATA_SEL 10 APM BIOS 32-bit interface (Data) */ 866{ 0, /* segment base address (overwritten by APM) */ 867 0xfffff, /* length */ 868 SDT_MEMRWA, /* segment type */ 869 0, /* segment descriptor priority level */ 870 1, /* segment descriptor present */ 871 0, 0, 872 1, /* default 32 vs 16 bit size */ 873 1 /* limit granularity (byte/page units)*/ }, 874}; 875 876static struct soft_segment_descriptor ldt_segs[] = { 877 /* Null Descriptor - overwritten by call gate */ 878{ 0x0, /* segment base address */ 879 0x0, /* length - all address space */ 880 0, /* segment type */ 881 0, /* segment descriptor priority level */ 882 0, /* segment descriptor present */ 883 0, 0, 884 0, /* default 32 vs 16 bit size */ 885 0 /* limit granularity (byte/page units)*/ }, 886 /* Null Descriptor - overwritten by call gate */ 887{ 0x0, /* segment base address */ 888 0x0, /* length - all address space */ 889 0, /* segment type */ 890 0, /* segment descriptor priority level */ 891 0, /* segment descriptor present */ 892 0, 0, 893 0, /* default 32 vs 16 bit size */ 894 0 /* limit granularity (byte/page units)*/ }, 895 /* Null Descriptor - overwritten by call gate */ 896{ 0x0, /* segment base address */ 897 0x0, /* length - all address space */ 898 0, /* segment type */ 899 0, /* segment descriptor priority level */ 900 0, /* segment descriptor present */ 901 0, 0, 902 0, /* default 32 vs 16 bit size */ 903 0 /* limit granularity (byte/page units)*/ }, 904 /* Code Descriptor for user */ 905{ 0x0, /* segment base address */ 906 0xfffff, /* length - all address space */ 907 SDT_MEMERA, /* segment type */ 908 SEL_UPL, /* segment descriptor priority level */ 909 1, /* segment descriptor present */ 910 0, 0, 911 1, /* default 32 vs 16 bit size */ 912 1 /* limit granularity (byte/page units)*/ }, 913 /* Data Descriptor for user */ 914{ 0x0, /* segment base address */ 915 0xfffff, /* length - all address space */ 916 SDT_MEMRWA, /* segment type */ 917 SEL_UPL, /* segment descriptor priority level */ 918 1, /* segment descriptor present */ 919 0, 0, 920 1, /* default 32 vs 16 bit size */ 921 1 /* limit granularity (byte/page units)*/ }, 922}; 923 924void 925setidt(idx, func, typ, dpl, selec) 926 int idx; 927 inthand_t *func; 928 int typ; 929 int dpl; 930 int selec; 931{ 932 struct gate_descriptor *ip = idt + idx; 933 934 ip->gd_looffset = (int)func; 935 ip->gd_selector = selec; 936 ip->gd_stkcpy = 0; 937 ip->gd_xx = 0; 938 ip->gd_type = typ; 939 ip->gd_dpl = dpl; 940 ip->gd_p = 1; 941 ip->gd_hioffset = ((int)func)>>16 ; 942} 943 944#define IDTVEC(name) __CONCAT(X,name) 945 946extern inthand_t 947 IDTVEC(div), IDTVEC(dbg), IDTVEC(nmi), IDTVEC(bpt), IDTVEC(ofl), 948 IDTVEC(bnd), IDTVEC(ill), IDTVEC(dna), IDTVEC(fpusegm), 949 IDTVEC(tss), IDTVEC(missing), IDTVEC(stk), IDTVEC(prot), 950 IDTVEC(page), IDTVEC(mchk), IDTVEC(rsvd), IDTVEC(fpu), IDTVEC(align), 951 IDTVEC(syscall), IDTVEC(int0x80_syscall); 952 953void 954sdtossd(sd, ssd) 955 struct segment_descriptor *sd; 956 struct soft_segment_descriptor *ssd; 957{ 958 ssd->ssd_base = (sd->sd_hibase << 24) | sd->sd_lobase; 959 ssd->ssd_limit = (sd->sd_hilimit << 16) | sd->sd_lolimit; 960 ssd->ssd_type = sd->sd_type; 961 ssd->ssd_dpl = sd->sd_dpl; 962 ssd->ssd_p = sd->sd_p; 963 ssd->ssd_def32 = sd->sd_def32; 964 ssd->ssd_gran = sd->sd_gran; 965} 966 967void 968init386(first) 969 int first; 970{ 971 int x; 972 unsigned biosbasemem, biosextmem; 973 struct gate_descriptor *gdp; 974 int gsel_tss; 975 /* table descriptors - used to load tables by microp */ 976 struct region_descriptor r_gdt, r_idt; 977 int pagesinbase, pagesinext; 978 int target_page, pa_indx; 979 980 proc0.p_addr = proc0paddr; 981 982 atdevbase = ISA_HOLE_START + KERNBASE; 983 984 /* 985 * Initialize the console before we print anything out. 986 */ 987 cninit(); 988 989 /* 990 * make gdt memory segments, the code segment goes up to end of the 991 * page with etext in it, the data segment goes to the end of 992 * the address space 993 */ 994 /* 995 * XXX text protection is temporarily (?) disabled. The limit was 996 * i386_btop(round_page(etext)) - 1. 997 */ 998 gdt_segs[GCODE_SEL].ssd_limit = i386_btop(0) - 1; 999 gdt_segs[GDATA_SEL].ssd_limit = i386_btop(0) - 1; 1000 for (x = 0; x < NGDT; x++) 1001 ssdtosd(&gdt_segs[x], &gdt[x].sd); 1002 1003 /* make ldt memory segments */ 1004 /* 1005 * The data segment limit must not cover the user area because we 1006 * don't want the user area to be writable in copyout() etc. (page 1007 * level protection is lost in kernel mode on 386's). Also, we 1008 * don't want the user area to be writable directly (page level 1009 * protection of the user area is not available on 486's with 1010 * CR0_WP set, because there is no user-read/kernel-write mode). 1011 * 1012 * XXX - VM_MAXUSER_ADDRESS is an end address, not a max. And it 1013 * should be spelled ...MAX_USER... 1014 */ 1015#define VM_END_USER_RW_ADDRESS VM_MAXUSER_ADDRESS 1016 /* 1017 * The code segment limit has to cover the user area until we move 1018 * the signal trampoline out of the user area. This is safe because 1019 * the code segment cannot be written to directly. 1020 */ 1021#define VM_END_USER_R_ADDRESS (VM_END_USER_RW_ADDRESS + UPAGES * PAGE_SIZE) 1022 ldt_segs[LUCODE_SEL].ssd_limit = i386_btop(VM_END_USER_R_ADDRESS) - 1; 1023 ldt_segs[LUDATA_SEL].ssd_limit = i386_btop(VM_END_USER_RW_ADDRESS) - 1; 1024 /* Note. eventually want private ldts per process */ 1025 for (x = 0; x < NLDT; x++) 1026 ssdtosd(&ldt_segs[x], &ldt[x].sd); 1027 1028 /* exceptions */ 1029 for (x = 0; x < NIDT; x++) 1030 setidt(x, &IDTVEC(rsvd), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); 1031 setidt(0, &IDTVEC(div), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); 1032 setidt(1, &IDTVEC(dbg), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); 1033 setidt(2, &IDTVEC(nmi), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); 1034 setidt(3, &IDTVEC(bpt), SDT_SYS386TGT, SEL_UPL, GSEL(GCODE_SEL, SEL_KPL)); 1035 setidt(4, &IDTVEC(ofl), SDT_SYS386TGT, SEL_UPL, GSEL(GCODE_SEL, SEL_KPL)); 1036 setidt(5, &IDTVEC(bnd), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); 1037 setidt(6, &IDTVEC(ill), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); 1038 setidt(7, &IDTVEC(dna), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); 1039 setidt(8, 0, SDT_SYSTASKGT, SEL_KPL, GSEL(GPANIC_SEL, SEL_KPL)); 1040 setidt(9, &IDTVEC(fpusegm), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); 1041 setidt(10, &IDTVEC(tss), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); 1042 setidt(11, &IDTVEC(missing), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); 1043 setidt(12, &IDTVEC(stk), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); 1044 setidt(13, &IDTVEC(prot), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); 1045 setidt(14, &IDTVEC(page), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); 1046 setidt(15, &IDTVEC(rsvd), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); 1047 setidt(16, &IDTVEC(fpu), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); 1048 setidt(17, &IDTVEC(align), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); 1049 setidt(18, &IDTVEC(mchk), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); 1050 setidt(0x80, &IDTVEC(int0x80_syscall), 1051 SDT_SYS386TGT, SEL_UPL, GSEL(GCODE_SEL, SEL_KPL)); 1052 1053#include "isa.h" 1054#if NISA >0 1055 isa_defaultirq(); 1056#endif 1057 rand_initialize(); 1058 1059 r_gdt.rd_limit = sizeof(gdt) - 1; 1060 r_gdt.rd_base = (int) gdt; 1061 lgdt(&r_gdt); 1062 1063 r_idt.rd_limit = sizeof(idt) - 1; 1064 r_idt.rd_base = (int) idt; 1065 lidt(&r_idt); 1066 1067 _default_ldt = GSEL(GLDT_SEL, SEL_KPL); 1068 lldt(_default_ldt); 1069 currentldt = _default_ldt; 1070 1071#ifdef DDB 1072 kdb_init(); 1073 if (boothowto & RB_KDB) 1074 Debugger("Boot flags requested debugger"); 1075#endif 1076 1077 /* Use BIOS values stored in RTC CMOS RAM, since probing 1078 * breaks certain 386 AT relics. 1079 */ 1080 biosbasemem = rtcin(RTC_BASELO)+ (rtcin(RTC_BASEHI)<<8); 1081 biosextmem = rtcin(RTC_EXTLO)+ (rtcin(RTC_EXTHI)<<8); 1082 1083 /* 1084 * Print a warning if the official BIOS interface disagrees 1085 * with the hackish interface used above. Eventually only 1086 * the official interface should be used. 1087 */ 1088 if (bootinfo.bi_memsizes_valid) { 1089 if (bootinfo.bi_basemem != biosbasemem) 1090 printf("BIOS basemem (%ldK) != RTC basemem (%dK)\n", 1091 bootinfo.bi_basemem, biosbasemem); 1092 if (bootinfo.bi_extmem != biosextmem) 1093 printf("BIOS extmem (%ldK) != RTC extmem (%dK)\n", 1094 bootinfo.bi_extmem, biosextmem); 1095 } 1096 1097 /* 1098 * If BIOS tells us that it has more than 640k in the basemem, 1099 * don't believe it - set it to 640k. 1100 */ 1101 if (biosbasemem > 640) 1102 biosbasemem = 640; 1103 1104 /* 1105 * Some 386 machines might give us a bogus number for extended 1106 * mem. If this happens, stop now. 1107 */ 1108#ifndef LARGEMEM 1109 if (biosextmem > 65536) { 1110 panic("extended memory beyond limit of 64MB"); 1111 /* NOTREACHED */ 1112 } 1113#endif 1114 1115 pagesinbase = biosbasemem * 1024 / PAGE_SIZE; 1116 pagesinext = biosextmem * 1024 / PAGE_SIZE; 1117 1118 /* 1119 * Special hack for chipsets that still remap the 384k hole when 1120 * there's 16MB of memory - this really confuses people that 1121 * are trying to use bus mastering ISA controllers with the 1122 * "16MB limit"; they only have 16MB, but the remapping puts 1123 * them beyond the limit. 1124 */ 1125 /* 1126 * If extended memory is between 15-16MB (16-17MB phys address range), 1127 * chop it to 15MB. 1128 */ 1129 if ((pagesinext > 3840) && (pagesinext < 4096)) 1130 pagesinext = 3840; 1131 1132 /* 1133 * Maxmem isn't the "maximum memory", it's one larger than the 1134 * highest page of the physical address space. It should be 1135 * called something like "Maxphyspage". 1136 */ 1137 Maxmem = pagesinext + 0x100000/PAGE_SIZE; 1138 1139#ifdef MAXMEM 1140 Maxmem = MAXMEM/4; 1141#endif 1142 1143 /* call pmap initialization to make new kernel address space */ 1144 pmap_bootstrap (first, 0); 1145 1146 /* 1147 * Size up each available chunk of physical memory. 1148 */ 1149 1150 /* 1151 * We currently don't bother testing base memory. 1152 * XXX ...but we probably should. 1153 */ 1154 pa_indx = 0; 1155 badpages = 0; 1156 if (pagesinbase > 1) { 1157 phys_avail[pa_indx++] = PAGE_SIZE; /* skip first page of memory */ 1158 phys_avail[pa_indx] = ptoa(pagesinbase);/* memory up to the ISA hole */ 1159 physmem = pagesinbase - 1; 1160 } else { 1161 /* point at first chunk end */ 1162 pa_indx++; 1163 } 1164 1165 for (target_page = avail_start; target_page < ptoa(Maxmem); target_page += PAGE_SIZE) { 1166 int tmp, page_bad = FALSE; 1167 1168 /* 1169 * map page into kernel: valid, read/write, non-cacheable 1170 */ 1171 *(int *)CMAP1 = PG_V | PG_RW | PG_N | target_page; 1172 pmap_update(); 1173 1174 tmp = *(int *)CADDR1; 1175 /* 1176 * Test for alternating 1's and 0's 1177 */ 1178 *(volatile int *)CADDR1 = 0xaaaaaaaa; 1179 if (*(volatile int *)CADDR1 != 0xaaaaaaaa) { 1180 page_bad = TRUE; 1181 } 1182 /* 1183 * Test for alternating 0's and 1's 1184 */ 1185 *(volatile int *)CADDR1 = 0x55555555; 1186 if (*(volatile int *)CADDR1 != 0x55555555) { 1187 page_bad = TRUE; 1188 } 1189 /* 1190 * Test for all 1's 1191 */ 1192 *(volatile int *)CADDR1 = 0xffffffff; 1193 if (*(volatile int *)CADDR1 != 0xffffffff) { 1194 page_bad = TRUE; 1195 } 1196 /* 1197 * Test for all 0's 1198 */ 1199 *(volatile int *)CADDR1 = 0x0; 1200 if (*(volatile int *)CADDR1 != 0x0) { 1201 /* 1202 * test of page failed 1203 */ 1204 page_bad = TRUE; 1205 } 1206 /* 1207 * Restore original value. 1208 */ 1209 *(int *)CADDR1 = tmp; 1210 1211 /* 1212 * Adjust array of valid/good pages. 1213 */ 1214 if (page_bad == FALSE) { 1215 /* 1216 * If this good page is a continuation of the 1217 * previous set of good pages, then just increase 1218 * the end pointer. Otherwise start a new chunk. 1219 * Note that "end" points one higher than end, 1220 * making the range >= start and < end. 1221 */ 1222 if (phys_avail[pa_indx] == target_page) { 1223 phys_avail[pa_indx] += PAGE_SIZE; 1224 } else { 1225 pa_indx++; 1226 if (pa_indx == PHYS_AVAIL_ARRAY_END) { 1227 printf("Too many holes in the physical address space, giving up\n"); 1228 pa_indx--; 1229 break; 1230 } 1231 phys_avail[pa_indx++] = target_page; /* start */ 1232 phys_avail[pa_indx] = target_page + PAGE_SIZE; /* end */ 1233 } 1234 physmem++; 1235 } else { 1236 badpages++; 1237 page_bad = FALSE; 1238 } 1239 } 1240 1241 *(int *)CMAP1 = 0; 1242 pmap_update(); 1243 1244 /* 1245 * XXX 1246 * The last chunk must contain at least one page plus the message 1247 * buffer to avoid complicating other code (message buffer address 1248 * calculation, etc.). 1249 */ 1250 while (phys_avail[pa_indx - 1] + PAGE_SIZE + 1251 round_page(sizeof(struct msgbuf)) >= phys_avail[pa_indx]) { 1252 physmem -= atop(phys_avail[pa_indx] - phys_avail[pa_indx - 1]); 1253 phys_avail[pa_indx--] = 0; 1254 phys_avail[pa_indx--] = 0; 1255 } 1256 1257 Maxmem = atop(phys_avail[pa_indx]); 1258 1259 /* Trim off space for the message buffer. */ 1260 phys_avail[pa_indx] -= round_page(sizeof(struct msgbuf)); 1261 1262 avail_end = phys_avail[pa_indx]; 1263 1264 /* now running on new page tables, configured,and u/iom is accessible */ 1265 1266 /* make a initial tss so microp can get interrupt stack on syscall! */ 1267 proc0.p_addr->u_pcb.pcb_tss.tss_esp0 = (int) kstack + UPAGES*PAGE_SIZE; 1268 proc0.p_addr->u_pcb.pcb_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL) ; 1269 gsel_tss = GSEL(GPROC0_SEL, SEL_KPL); 1270 1271 dblfault_tss.tss_esp = dblfault_tss.tss_esp0 = dblfault_tss.tss_esp1 = 1272 dblfault_tss.tss_esp2 = (int) &dblfault_stack[sizeof(dblfault_stack)]; 1273 dblfault_tss.tss_ss = dblfault_tss.tss_ss0 = dblfault_tss.tss_ss1 = 1274 dblfault_tss.tss_ss2 = GSEL(GDATA_SEL, SEL_KPL); 1275 dblfault_tss.tss_cr3 = IdlePTD; 1276 dblfault_tss.tss_eip = (int) dblfault_handler; 1277 dblfault_tss.tss_eflags = PSL_KERNEL; 1278 dblfault_tss.tss_ds = dblfault_tss.tss_es = dblfault_tss.tss_fs = dblfault_tss.tss_gs = 1279 GSEL(GDATA_SEL, SEL_KPL); 1280 dblfault_tss.tss_cs = GSEL(GCODE_SEL, SEL_KPL); 1281 dblfault_tss.tss_ldt = GSEL(GLDT_SEL, SEL_KPL); 1282 1283 ((struct i386tss *)gdt_segs[GPROC0_SEL].ssd_base)->tss_ioopt = 1284 (sizeof(struct i386tss))<<16; 1285 1286 ltr(gsel_tss); 1287 1288 /* make a call gate to reenter kernel with */ 1289 gdp = &ldt[LSYS5CALLS_SEL].gd; 1290 1291 x = (int) &IDTVEC(syscall); 1292 gdp->gd_looffset = x++; 1293 gdp->gd_selector = GSEL(GCODE_SEL,SEL_KPL); 1294 gdp->gd_stkcpy = 1; 1295 gdp->gd_type = SDT_SYS386CGT; 1296 gdp->gd_dpl = SEL_UPL; 1297 gdp->gd_p = 1; 1298 gdp->gd_hioffset = ((int) &IDTVEC(syscall)) >>16; 1299 1300 /* transfer to user mode */ 1301 1302 _ucodesel = LSEL(LUCODE_SEL, SEL_UPL); 1303 _udatasel = LSEL(LUDATA_SEL, SEL_UPL); 1304 1305 /* setup proc 0's pcb */ 1306 proc0.p_addr->u_pcb.pcb_flags = 0; 1307 proc0.p_addr->u_pcb.pcb_cr3 = IdlePTD; 1308} 1309 1310/* 1311 * The registers are in the frame; the frame is in the user area of 1312 * the process in question; when the process is active, the registers 1313 * are in "the kernel stack"; when it's not, they're still there, but 1314 * things get flipped around. So, since p->p_md.md_regs is the whole address 1315 * of the register set, take its offset from the kernel stack, and 1316 * index into the user block. Don't you just *love* virtual memory? 1317 * (I'm starting to think seymour is right...) 1318 */ 1319#define TF_REGP(p) ((struct trapframe *) \ 1320 ((char *)(p)->p_addr \ 1321 + ((char *)(p)->p_md.md_regs - kstack))) 1322 1323int 1324ptrace_set_pc(p, addr) 1325 struct proc *p; 1326 unsigned int addr; 1327{ 1328 TF_REGP(p)->tf_eip = addr; 1329 return (0); 1330} 1331 1332int 1333ptrace_single_step(p) 1334 struct proc *p; 1335{ 1336 TF_REGP(p)->tf_eflags |= PSL_T; 1337 return (0); 1338} 1339 1340int ptrace_write_u(p, off, data) 1341 struct proc *p; 1342 vm_offset_t off; 1343 int data; 1344{ 1345 struct trapframe frame_copy; 1346 vm_offset_t min; 1347 struct trapframe *tp; 1348 1349 /* 1350 * Privileged kernel state is scattered all over the user area. 1351 * Only allow write access to parts of regs and to fpregs. 1352 */ 1353 min = (char *)p->p_md.md_regs - kstack; 1354 if (off >= min && off <= min + sizeof(struct trapframe) - sizeof(int)) { 1355 tp = TF_REGP(p); 1356 frame_copy = *tp; 1357 *(int *)((char *)&frame_copy + (off - min)) = data; 1358 if (!EFLAGS_SECURE(frame_copy.tf_eflags, tp->tf_eflags) || 1359 !CS_SECURE(frame_copy.tf_cs)) 1360 return (EINVAL); 1361 *(int*)((char *)p->p_addr + off) = data; 1362 return (0); 1363 } 1364 min = offsetof(struct user, u_pcb) + offsetof(struct pcb, pcb_savefpu); 1365 if (off >= min && off <= min + sizeof(struct save87) - sizeof(int)) { 1366 *(int*)((char *)p->p_addr + off) = data; 1367 return (0); 1368 } 1369 return (EFAULT); 1370} 1371 1372int 1373fill_regs(p, regs) 1374 struct proc *p; 1375 struct reg *regs; 1376{ 1377 struct trapframe *tp; 1378 1379 tp = TF_REGP(p); 1380 regs->r_es = tp->tf_es; 1381 regs->r_ds = tp->tf_ds; 1382 regs->r_edi = tp->tf_edi; 1383 regs->r_esi = tp->tf_esi; 1384 regs->r_ebp = tp->tf_ebp; 1385 regs->r_ebx = tp->tf_ebx; 1386 regs->r_edx = tp->tf_edx; 1387 regs->r_ecx = tp->tf_ecx; 1388 regs->r_eax = tp->tf_eax; 1389 regs->r_eip = tp->tf_eip; 1390 regs->r_cs = tp->tf_cs; 1391 regs->r_eflags = tp->tf_eflags; 1392 regs->r_esp = tp->tf_esp; 1393 regs->r_ss = tp->tf_ss; 1394 return (0); 1395} 1396 1397int 1398set_regs(p, regs) 1399 struct proc *p; 1400 struct reg *regs; 1401{ 1402 struct trapframe *tp; 1403 1404 tp = TF_REGP(p); 1405 if (!EFLAGS_SECURE(regs->r_eflags, tp->tf_eflags) || 1406 !CS_SECURE(regs->r_cs)) 1407 return (EINVAL); 1408 tp->tf_es = regs->r_es; 1409 tp->tf_ds = regs->r_ds; 1410 tp->tf_edi = regs->r_edi; 1411 tp->tf_esi = regs->r_esi; 1412 tp->tf_ebp = regs->r_ebp; 1413 tp->tf_ebx = regs->r_ebx; 1414 tp->tf_edx = regs->r_edx; 1415 tp->tf_ecx = regs->r_ecx; 1416 tp->tf_eax = regs->r_eax; 1417 tp->tf_eip = regs->r_eip; 1418 tp->tf_cs = regs->r_cs; 1419 tp->tf_eflags = regs->r_eflags; 1420 tp->tf_esp = regs->r_esp; 1421 tp->tf_ss = regs->r_ss; 1422 return (0); 1423} 1424 1425#ifndef DDB 1426void 1427Debugger(const char *msg) 1428{ 1429 printf("Debugger(\"%s\") called.\n", msg); 1430} 1431#endif /* no DDB */ 1432 1433#include <sys/disklabel.h> 1434#define b_cylin b_resid 1435/* 1436 * Determine the size of the transfer, and make sure it is 1437 * within the boundaries of the partition. Adjust transfer 1438 * if needed, and signal errors or early completion. 1439 */ 1440int 1441bounds_check_with_label(struct buf *bp, struct disklabel *lp, int wlabel) 1442{ 1443 struct partition *p = lp->d_partitions + dkpart(bp->b_dev); 1444 int labelsect = lp->d_partitions[0].p_offset; 1445 int maxsz = p->p_size, 1446 sz = (bp->b_bcount + DEV_BSIZE - 1) >> DEV_BSHIFT; 1447 1448 /* overwriting disk label ? */ 1449 /* XXX should also protect bootstrap in first 8K */ 1450 if (bp->b_blkno + p->p_offset <= LABELSECTOR + labelsect && 1451#if LABELSECTOR != 0 1452 bp->b_blkno + p->p_offset + sz > LABELSECTOR + labelsect && 1453#endif 1454 (bp->b_flags & B_READ) == 0 && wlabel == 0) { 1455 bp->b_error = EROFS; 1456 goto bad; 1457 } 1458 1459#if defined(DOSBBSECTOR) && defined(notyet) 1460 /* overwriting master boot record? */ 1461 if (bp->b_blkno + p->p_offset <= DOSBBSECTOR && 1462 (bp->b_flags & B_READ) == 0 && wlabel == 0) { 1463 bp->b_error = EROFS; 1464 goto bad; 1465 } 1466#endif 1467 1468 /* beyond partition? */ 1469 if (bp->b_blkno < 0 || bp->b_blkno + sz > maxsz) { 1470 /* if exactly at end of disk, return an EOF */ 1471 if (bp->b_blkno == maxsz) { 1472 bp->b_resid = bp->b_bcount; 1473 return(0); 1474 } 1475 /* or truncate if part of it fits */ 1476 sz = maxsz - bp->b_blkno; 1477 if (sz <= 0) { 1478 bp->b_error = EINVAL; 1479 goto bad; 1480 } 1481 bp->b_bcount = sz << DEV_BSHIFT; 1482 } 1483 1484 /* calculate cylinder for disksort to order transfers with */ 1485 bp->b_pblkno = bp->b_blkno + p->p_offset; 1486 bp->b_cylin = bp->b_pblkno / lp->d_secpercyl; 1487 return(1); 1488 1489bad: 1490 bp->b_flags |= B_ERROR; 1491 return(-1); 1492} 1493 1494int 1495disk_externalize(int drive, struct sysctl_req *req) 1496{ 1497 return SYSCTL_OUT(req, &drive, sizeof drive); 1498} 1499