machdep.c revision 2426
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.58 1994/08/31 06:17:31 davidg Exp $ 39 */ 40 41#include "npx.h" 42#include "isa.h" 43 44#include <sys/param.h> 45#include <sys/systm.h> 46#include <sys/signalvar.h> 47#include <sys/kernel.h> 48#include <sys/map.h> 49#include <sys/proc.h> 50#include <sys/user.h> 51#include <sys/buf.h> 52#include <sys/reboot.h> 53#include <sys/conf.h> 54#include <sys/file.h> 55#include <sys/callout.h> 56#include <sys/malloc.h> 57#include <sys/mbuf.h> 58#include <sys/msgbuf.h> 59#include <sys/ioctl.h> 60#include <sys/sysent.h> 61#include <sys/tty.h> 62#include <sys/sysctl.h> 63 64#ifdef SYSVSHM 65#include <sys/shm.h> 66#endif 67 68#ifdef SYSVMSG 69#include <sys/msg.h> 70#endif 71 72#ifdef SYSVSEM 73#include <sys/sem.h> 74#endif 75 76#include <vm/vm.h> 77#include <vm/vm_kern.h> 78#include <vm/vm_page.h> 79 80#include <sys/exec.h> 81#include <sys/vnode.h> 82 83extern vm_offset_t avail_start, avail_end; 84 85#include <machine/cpu.h> 86#include <machine/reg.h> 87#include <machine/psl.h> 88#include <machine/specialreg.h> 89#include <machine/sysarch.h> 90#include <machine/cons.h> 91 92#include <i386/isa/isa.h> 93#include <i386/isa/rtc.h> 94 95static void identifycpu(void); 96static void initcpu(void); 97static int test_page(int *, int); 98 99char machine[] = "i386"; 100char cpu_model[sizeof("Pentium") + 1]; 101 102#ifndef PANIC_REBOOT_WAIT_TIME 103#define PANIC_REBOOT_WAIT_TIME 15 /* default to 15 seconds */ 104#endif 105 106/* 107 * Declare these as initialized data so we can patch them. 108 */ 109int nswbuf = 0; 110#ifdef NBUF 111int nbuf = NBUF; 112#else 113int nbuf = 0; 114#endif 115#ifdef BUFPAGES 116int bufpages = BUFPAGES; 117#else 118int bufpages = 0; 119#endif 120 121#ifdef BOUNCE_BUFFERS 122extern char *bouncememory; 123extern int maxbkva; 124#ifdef BOUNCEPAGES 125int bouncepages = BOUNCEPAGES; 126#else 127int bouncepages = 0; 128#endif 129#endif /* BOUNCE_BUFFERS */ 130 131extern int freebufspace; 132int msgbufmapped = 0; /* set when safe to use msgbuf */ 133int _udatasel, _ucodesel; 134 135/* 136 * Machine-dependent startup code 137 */ 138int boothowto = 0, Maxmem = 0, badpages = 0, physmem = 0; 139long dumplo; 140extern int bootdev; 141int biosmem; 142 143vm_offset_t phys_avail[6]; 144 145extern cyloffset; 146 147int cpu_class; 148 149void dumpsys __P((void)); 150vm_offset_t buffer_sva, buffer_eva; 151vm_offset_t clean_sva, clean_eva; 152vm_offset_t pager_sva, pager_eva; 153extern int pager_map_size; 154 155#define offsetof(type, member) ((size_t)(&((type *)0)->member)) 156 157void 158cpu_startup() 159{ 160 register int unixsize; 161 register unsigned i; 162 register struct pte *pte; 163 int mapaddr, j; 164 register caddr_t v; 165 int maxbufs, base, residual; 166 extern long Usrptsize; 167 vm_offset_t minaddr, maxaddr; 168 vm_size_t size = 0; 169 int firstaddr; 170 171 /* 172 * Initialize error message buffer (at end of core). 173 */ 174 175 /* avail_end was pre-decremented in init_386() to compensate */ 176 for (i = 0; i < btoc(sizeof (struct msgbuf)); i++) 177 pmap_enter(pmap_kernel(), (vm_offset_t)msgbufp, 178 avail_end + i * NBPG, 179 VM_PROT_ALL, TRUE); 180 msgbufmapped = 1; 181 182 /* 183 * Good {morning,afternoon,evening,night}. 184 */ 185 printf(version); 186 startrtclock(); 187 identifycpu(); 188 printf("real memory = %d (%d pages)\n", ptoa(physmem), physmem); 189 if (badpages) 190 printf("bad memory = %d (%d pages)\n", ptoa(badpages), badpages); 191 192 /* 193 * Allocate space for system data structures. 194 * The first available kernel virtual address is in "v". 195 * As pages of kernel virtual memory are allocated, "v" is incremented. 196 * As pages of memory are allocated and cleared, 197 * "firstaddr" is incremented. 198 * An index into the kernel page table corresponding to the 199 * virtual memory address maintained in "v" is kept in "mapaddr". 200 */ 201 202 /* 203 * Make two passes. The first pass calculates how much memory is 204 * needed and allocates it. The second pass assigns virtual 205 * addresses to the various data structures. 206 */ 207 firstaddr = 0; 208again: 209 v = (caddr_t)firstaddr; 210 211#define valloc(name, type, num) \ 212 (name) = (type *)v; v = (caddr_t)((name)+(num)) 213#define valloclim(name, type, num, lim) \ 214 (name) = (type *)v; v = (caddr_t)((lim) = ((name)+(num))) 215 valloc(callout, struct callout, ncallout); 216#ifdef SYSVSHM 217 valloc(shmsegs, struct shmid_ds, shminfo.shmmni); 218#endif 219#ifdef SYSVSEM 220 valloc(sema, struct semid_ds, seminfo.semmni); 221 valloc(sem, struct sem, seminfo.semmns); 222 /* This is pretty disgusting! */ 223 valloc(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int)); 224#endif 225#ifdef SYSVMSG 226 valloc(msgpool, char, msginfo.msgmax); 227 valloc(msgmaps, struct msgmap, msginfo.msgseg); 228 valloc(msghdrs, struct msg, msginfo.msgtql); 229 valloc(msqids, struct msqid_ds, msginfo.msgmni); 230#endif 231 /* 232 * Determine how many buffers to allocate. 233 * Use 20% of memory of memory beyond the first 2MB 234 * Insure a minimum of 16 fs buffers. 235 * We allocate 1/2 as many swap buffer headers as file i/o buffers. 236 */ 237 if (bufpages == 0) 238 bufpages = ((physmem << PGSHIFT) - 2048*1024) / NBPG / 5; 239 if (bufpages < 64) 240 bufpages = 64; 241 242 /* 243 * We must still limit the maximum number of buffers to be no 244 * more than 2/5's of the size of the kernal malloc region, this 245 * will only take effect for machines with lots of memory 246 */ 247 bufpages = min(bufpages, (VM_KMEM_SIZE / NBPG) * 2 / 5); 248 if (nbuf == 0) { 249 nbuf = bufpages / 2; 250 if (nbuf < 32) 251 nbuf = 32; 252 } 253 freebufspace = bufpages * NBPG; 254 if (nswbuf == 0) { 255 nswbuf = (nbuf / 2) &~ 1; /* force even */ 256 if (nswbuf > 64) 257 nswbuf = 64; /* sanity */ 258 } 259 valloc(swbuf, struct buf, nswbuf); 260 valloc(buf, struct buf, nbuf); 261 262#ifdef BOUNCE_BUFFERS 263 /* 264 * If there is more than 16MB of memory, allocate some bounce buffers 265 */ 266 if (Maxmem > 4096) { 267 if (bouncepages == 0) 268 bouncepages = 96; /* largest physio size + extra */ 269 v = (caddr_t)((vm_offset_t)((vm_offset_t)v + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)); 270 valloc(bouncememory, char, bouncepages * PAGE_SIZE); 271 } 272#endif 273 274 /* 275 * End of first pass, size has been calculated so allocate memory 276 */ 277 if (firstaddr == 0) { 278 size = (vm_size_t)(v - firstaddr); 279 firstaddr = (int)kmem_alloc(kernel_map, round_page(size)); 280 if (firstaddr == 0) 281 panic("startup: no room for tables"); 282 goto again; 283 } 284 285 /* 286 * End of second pass, addresses have been assigned 287 */ 288 if ((vm_size_t)(v - firstaddr) != size) 289 panic("startup: table size inconsistency"); 290 291#ifdef BOUNCE_BUFFERS 292 clean_map = kmem_suballoc(kernel_map, &clean_sva, &clean_eva, 293 (nbuf*MAXBSIZE) + (nswbuf*MAXPHYS) + 294 maxbkva + pager_map_size, TRUE); 295 io_map = kmem_suballoc(clean_map, &minaddr, &maxaddr, maxbkva, FALSE); 296#else 297 clean_map = kmem_suballoc(kernel_map, &clean_sva, &clean_eva, 298 (nbuf*MAXBSIZE) + (nswbuf*MAXPHYS) + pager_map_size, TRUE); 299#endif 300 buffer_map = kmem_suballoc(clean_map, &buffer_sva, &buffer_eva, 301 (nbuf*MAXBSIZE), TRUE); 302 pager_map = kmem_suballoc(clean_map, &pager_sva, &pager_eva, 303 (nswbuf*MAXPHYS) + pager_map_size, TRUE); 304 305 /* 306 * Finally, allocate mbuf pool. Since mclrefcnt is an off-size 307 * we use the more space efficient malloc in place of kmem_alloc. 308 */ 309 mclrefcnt = (char *)malloc(NMBCLUSTERS+CLBYTES/MCLBYTES, 310 M_MBUF, M_NOWAIT); 311 bzero(mclrefcnt, NMBCLUSTERS+CLBYTES/MCLBYTES); 312 mb_map = kmem_suballoc(kmem_map, (vm_offset_t *)&mbutl, &maxaddr, 313 VM_MBUF_SIZE, FALSE); 314 /* 315 * Initialize callouts 316 */ 317 callfree = callout; 318 for (i = 1; i < ncallout; i++) 319 callout[i-1].c_next = &callout[i]; 320 321 printf("avail memory = %d (%d pages)\n", ptoa(cnt.v_free_count), cnt.v_free_count); 322 printf("using %d buffers containing %d bytes of memory\n", 323 nbuf, bufpages * CLBYTES); 324 325#ifdef BOUNCE_BUFFERS 326 /* 327 * init bounce buffers 328 */ 329 vm_bounce_init(); 330#endif 331 332 /* 333 * Set up CPU-specific registers, cache, etc. 334 */ 335 initcpu(); 336 337 /* 338 * Set up buffers, so they can be used to read disk labels. 339 */ 340 bufinit(); 341 vm_pager_bufferinit(); 342 343 /* 344 * Configure the system. 345 */ 346 configure(); 347} 348 349 350struct cpu_nameclass i386_cpus[] = { 351 { "Intel 80286", CPUCLASS_286 }, /* CPU_286 */ 352 { "i386SX", CPUCLASS_386 }, /* CPU_386SX */ 353 { "i386DX", CPUCLASS_386 }, /* CPU_386 */ 354 { "i486SX", CPUCLASS_486 }, /* CPU_486SX */ 355 { "i486DX", CPUCLASS_486 }, /* CPU_486 */ 356 { "Pentium", CPUCLASS_586 }, /* CPU_586 */ 357}; 358 359static void 360identifycpu() 361{ 362 extern u_long cpu_id; 363 extern char cpu_vendor[]; 364 printf("CPU: "); 365 if (cpu >= 0 366 && cpu < (sizeof i386_cpus/sizeof(struct cpu_nameclass))) { 367 printf("%s", i386_cpus[cpu].cpu_name); 368 cpu_class = i386_cpus[cpu].cpu_class; 369 strncpy(cpu_model, i386_cpus[cpu].cpu_name, sizeof cpu_model); 370 } else { 371 printf("unknown cpu type %d\n", cpu); 372 panic("startup: bad cpu id"); 373 } 374 printf(" ("); 375 switch(cpu_class) { 376 case CPUCLASS_286: 377 printf("286"); 378 break; 379 case CPUCLASS_386: 380 printf("386"); 381 break; 382 case CPUCLASS_486: 383 printf("486"); 384 break; 385 case CPUCLASS_586: 386 printf("Pentium"); 387 break; 388 default: 389 printf("unknown"); /* will panic below... */ 390 } 391 printf("-class CPU)"); 392#ifdef I586_CPU 393 if(cpu_class == CPUCLASS_586) { 394 extern void calibrate_cyclecounter(); 395 extern int pentium_mhz; 396 calibrate_cyclecounter(); 397 printf(" %d MHz", pentium_mhz); 398 } 399#endif 400 if(cpu_id) 401 printf(" Id = 0x%x",cpu_id); 402 if(*cpu_vendor) 403 printf(" Origin = \"%s\"",cpu_vendor); 404 printf("\n"); /* cpu speed would be nice, but how? */ 405 406 /* 407 * Now that we have told the user what they have, 408 * let them know if that machine type isn't configured. 409 */ 410 switch (cpu_class) { 411 case CPUCLASS_286: /* a 286 should not make it this far, anyway */ 412#if !defined(I386_CPU) && !defined(I486_CPU) && !defined(I586_CPU) 413#error This kernel is not configured for one of the supported CPUs 414#endif 415#if !defined(I386_CPU) 416 case CPUCLASS_386: 417#endif 418#if !defined(I486_CPU) 419 case CPUCLASS_486: 420#endif 421#if !defined(I586_CPU) 422 case CPUCLASS_586: 423#endif 424 panic("CPU class not configured"); 425 default: 426 break; 427 } 428} 429 430#ifdef PGINPROF 431/* 432 * Return the difference (in microseconds) 433 * between the current time and a previous 434 * time as represented by the arguments. 435 * If there is a pending clock interrupt 436 * which has not been serviced due to high 437 * ipl, return error code. 438 */ 439/*ARGSUSED*/ 440vmtime(otime, olbolt, oicr) 441 register int otime, olbolt, oicr; 442{ 443 444 return (((time.tv_sec-otime)*60 + lbolt-olbolt)*16667); 445} 446#endif 447 448extern int kstack[]; 449 450/* 451 * Send an interrupt to process. 452 * 453 * Stack is set up to allow sigcode stored 454 * in u. to call routine, followed by kcall 455 * to sigreturn routine below. After sigreturn 456 * resets the signal mask, the stack, and the 457 * frame pointer, it returns to the user 458 * specified pc, psl. 459 */ 460void 461sendsig(catcher, sig, mask, code) 462 sig_t catcher; 463 int sig, mask; 464 unsigned code; 465{ 466 register struct proc *p = curproc; 467 register int *regs; 468 register struct sigframe *fp; 469 struct sigacts *psp = p->p_sigacts; 470 int oonstack, frmtrap; 471 472 regs = p->p_md.md_regs; 473 oonstack = psp->ps_sigstk.ss_flags & SA_ONSTACK; 474 /* 475 * Allocate and validate space for the signal handler 476 * context. Note that if the stack is in P0 space, the 477 * call to grow() is a nop, and the useracc() check 478 * will fail if the process has not already allocated 479 * the space with a `brk'. 480 */ 481 if ((psp->ps_flags & SAS_ALTSTACK) && 482 (psp->ps_sigstk.ss_flags & SA_ONSTACK) == 0 && 483 (psp->ps_sigonstack & sigmask(sig))) { 484 fp = (struct sigframe *)(psp->ps_sigstk.ss_base + 485 psp->ps_sigstk.ss_size - sizeof(struct sigframe)); 486 psp->ps_sigstk.ss_flags |= SA_ONSTACK; 487 } else { 488 fp = (struct sigframe *)(regs[tESP] 489 - sizeof(struct sigframe)); 490 } 491 492 /* 493 * grow() will return FALSE if the fp will not fit inside the stack 494 * and the stack can not be grown. useracc will return FALSE 495 * if access is denied. 496 */ 497 if ((grow(p, (int)fp) == FALSE) || 498 (useracc((caddr_t)fp, sizeof (struct sigframe), B_WRITE) == FALSE)) { 499 /* 500 * Process has trashed its stack; give it an illegal 501 * instruction to halt it in its tracks. 502 */ 503 SIGACTION(p, SIGILL) = SIG_DFL; 504 sig = sigmask(SIGILL); 505 p->p_sigignore &= ~sig; 506 p->p_sigcatch &= ~sig; 507 p->p_sigmask &= ~sig; 508 psignal(p, SIGILL); 509 return; 510 } 511 512 /* 513 * Build the argument list for the signal handler. 514 */ 515 if (p->p_sysent->sv_sigtbl) { 516 if (sig < p->p_sysent->sv_sigsize) 517 sig = p->p_sysent->sv_sigtbl[sig]; 518 else 519 sig = p->p_sysent->sv_sigsize + 1; 520 } 521 fp->sf_signum = sig; 522 fp->sf_code = code; 523 fp->sf_scp = &fp->sf_sc; 524 fp->sf_addr = (char *) regs[tERR]; 525 fp->sf_handler = catcher; 526 527 /* save scratch registers */ 528 fp->sf_sc.sc_eax = regs[tEAX]; 529 fp->sf_sc.sc_ebx = regs[tEBX]; 530 fp->sf_sc.sc_ecx = regs[tECX]; 531 fp->sf_sc.sc_edx = regs[tEDX]; 532 fp->sf_sc.sc_esi = regs[tESI]; 533 fp->sf_sc.sc_edi = regs[tEDI]; 534 fp->sf_sc.sc_cs = regs[tCS]; 535 fp->sf_sc.sc_ds = regs[tDS]; 536 fp->sf_sc.sc_ss = regs[tSS]; 537 fp->sf_sc.sc_es = regs[tES]; 538 fp->sf_sc.sc_isp = regs[tISP]; 539 540 /* 541 * Build the signal context to be used by sigreturn. 542 */ 543 fp->sf_sc.sc_onstack = oonstack; 544 fp->sf_sc.sc_mask = mask; 545 fp->sf_sc.sc_sp = regs[tESP]; 546 fp->sf_sc.sc_fp = regs[tEBP]; 547 fp->sf_sc.sc_pc = regs[tEIP]; 548 fp->sf_sc.sc_ps = regs[tEFLAGS]; 549 regs[tESP] = (int)fp; 550 regs[tEIP] = (int)((struct pcb *)kstack)->pcb_sigc; 551 regs[tEFLAGS] &= ~PSL_VM; 552 regs[tCS] = _ucodesel; 553 regs[tDS] = _udatasel; 554 regs[tES] = _udatasel; 555 regs[tSS] = _udatasel; 556} 557 558/* 559 * System call to cleanup state after a signal 560 * has been taken. Reset signal mask and 561 * stack state from context left by sendsig (above). 562 * Return to previous pc and psl as specified by 563 * context left by sendsig. Check carefully to 564 * make sure that the user has not modified the 565 * psl to gain improper privileges or to cause 566 * a machine fault. 567 */ 568struct sigreturn_args { 569 struct sigcontext *sigcntxp; 570}; 571 572int 573sigreturn(p, uap, retval) 574 struct proc *p; 575 struct sigreturn_args *uap; 576 int *retval; 577{ 578 register struct sigcontext *scp; 579 register struct sigframe *fp; 580 register int *regs = p->p_md.md_regs; 581 int eflags; 582 583 /* 584 * (XXX old comment) regs[tESP] points to the return address. 585 * The user scp pointer is above that. 586 * The return address is faked in the signal trampoline code 587 * for consistency. 588 */ 589 scp = uap->sigcntxp; 590 fp = (struct sigframe *) 591 ((caddr_t)scp - offsetof(struct sigframe, sf_sc)); 592 593 if (useracc((caddr_t)fp, sizeof (*fp), 0) == 0) 594 return(EINVAL); 595 596 eflags = scp->sc_ps; 597 if ((eflags & PSL_USERCLR) != 0 || 598 (eflags & PSL_USERSET) != PSL_USERSET || 599 (eflags & PSL_IOPL) < (regs[tEFLAGS] & PSL_IOPL)) { 600#ifdef DEBUG 601 printf("sigreturn: eflags=0x%x\n", eflags); 602#endif 603 return(EINVAL); 604 } 605 606 /* 607 * Sanity check the user's selectors and error if they 608 * are suspect. 609 */ 610#define max_ldt_sel(pcb) \ 611 ((pcb)->pcb_ldt ? (pcb)->pcb_ldt_len : (sizeof(ldt) / sizeof(ldt[0]))) 612 613#define valid_ldt_sel(sel) \ 614 (ISLDT(sel) && ISPL(sel) == SEL_UPL && \ 615 IDXSEL(sel) < max_ldt_sel(&p->p_addr->u_pcb)) 616 617#define null_sel(sel) \ 618 (!ISLDT(sel) && IDXSEL(sel) == 0) 619 620 if ((scp->sc_cs&0xffff != _ucodesel && !valid_ldt_sel(scp->sc_cs)) || 621 (scp->sc_ss&0xffff != _udatasel && !valid_ldt_sel(scp->sc_ss)) || 622 (scp->sc_ds&0xffff != _udatasel && !valid_ldt_sel(scp->sc_ds) && 623 !null_sel(scp->sc_ds)) || 624 (scp->sc_es&0xffff != _udatasel && !valid_ldt_sel(scp->sc_es) && 625 !null_sel(scp->sc_es))) { 626#ifdef DEBUG 627 printf("sigreturn: cs=0x%x ss=0x%x ds=0x%x es=0x%x\n", 628 scp->sc_cs, scp->sc_ss, scp->sc_ds, scp->sc_es); 629#endif 630 trapsignal(p, SIGBUS, T_PROTFLT); 631 return(EINVAL); 632 } 633 634#undef max_ldt_sel 635#undef valid_ldt_sel 636#undef null_sel 637 638 /* restore scratch registers */ 639 regs[tEAX] = scp->sc_eax; 640 regs[tEBX] = scp->sc_ebx; 641 regs[tECX] = scp->sc_ecx; 642 regs[tEDX] = scp->sc_edx; 643 regs[tESI] = scp->sc_esi; 644 regs[tEDI] = scp->sc_edi; 645 regs[tCS] = scp->sc_cs; 646 regs[tDS] = scp->sc_ds; 647 regs[tES] = scp->sc_es; 648 regs[tSS] = scp->sc_ss; 649 regs[tISP] = scp->sc_isp; 650 651 if (useracc((caddr_t)scp, sizeof (*scp), 0) == 0) 652 return(EINVAL); 653 654 if (scp->sc_onstack & 01) 655 p->p_sigacts->ps_sigstk.ss_flags |= SA_ONSTACK; 656 else 657 p->p_sigacts->ps_sigstk.ss_flags &= ~SA_ONSTACK; 658 p->p_sigmask = scp->sc_mask &~ 659 (sigmask(SIGKILL)|sigmask(SIGCONT)|sigmask(SIGSTOP)); 660 regs[tEBP] = scp->sc_fp; 661 regs[tESP] = scp->sc_sp; 662 regs[tEIP] = scp->sc_pc; 663 regs[tEFLAGS] = eflags; 664 return(EJUSTRETURN); 665} 666 667/* 668 * a simple function to make the system panic (and dump a vmcore) 669 * in a predictable fashion 670 */ 671void diediedie() 672{ 673 panic("because you said to!"); 674} 675 676int waittime = -1; 677struct pcb dumppcb; 678 679__dead void 680boot(arghowto) 681 int arghowto; 682{ 683 register long dummy; /* r12 is reserved */ 684 register int howto; /* r11 == how to boot */ 685 register int devtype; /* r10 == major of root dev */ 686 extern int cold; 687 688 if (cold) { 689 printf("hit reset please"); 690 for(;;); 691 } 692 howto = arghowto; 693 if ((howto&RB_NOSYNC) == 0 && waittime < 0) { 694 register struct buf *bp; 695 int iter, nbusy; 696 697 waittime = 0; 698 (void) splnet(); 699 printf("\nsyncing disks... "); 700 /* 701 * Release inodes held by texts before update. 702 */ 703 if (panicstr == 0) 704 vnode_pager_umount(NULL); 705 sync(curproc, NULL, NULL); 706 707 for (iter = 0; iter < 20; iter++) { 708 nbusy = 0; 709 for (bp = &buf[nbuf]; --bp >= buf; ) 710 if ((bp->b_flags & (B_BUSY|B_INVAL)) == B_BUSY) 711 nbusy++; 712 if (nbusy == 0) 713 break; 714 printf("%d ", nbusy); 715 DELAY(40000 * iter); 716 } 717 if (nbusy) { 718 /* 719 * Failed to sync all blocks. Indicate this and don't 720 * unmount filesystems (thus forcing an fsck on reboot). 721 */ 722 printf("giving up\n"); 723 } else { 724 printf("done\n"); 725 /* 726 * Unmount filesystems 727 */ 728 if (panicstr == 0) 729 vfs_unmountall(); 730 } 731 DELAY(100000); /* wait for console output to finish */ 732 } 733 splhigh(); 734 devtype = major(rootdev); 735 if (howto&RB_HALT) { 736 printf("\n"); 737 printf("The operating system has halted.\n"); 738 printf("Please press any key to reboot.\n\n"); 739 cngetc(); 740 } else { 741 if (howto & RB_DUMP) { 742 savectx(&dumppcb, 0); 743 dumppcb.pcb_ptd = rcr3(); 744 dumpsys(); 745 746 if (PANIC_REBOOT_WAIT_TIME != 0) { 747 if (PANIC_REBOOT_WAIT_TIME != -1) { 748 int loop; 749 printf("Automatic reboot in %d seconds - press a key on the console to abort\n", 750 PANIC_REBOOT_WAIT_TIME); 751 for (loop = PANIC_REBOOT_WAIT_TIME; loop > 0; --loop) { 752 DELAY(1000 * 1000); /* one second */ 753 if (sgetc(1)) /* Did user type a key? */ 754 break; 755 } 756 if (!loop) 757 goto die; 758 } 759 } else { /* zero time specified - reboot NOW */ 760 goto die; 761 } 762 printf("--> Press a key on the console to reboot <--\n"); 763 cngetc(); 764 } 765 } 766#ifdef lint 767 dummy = 0; dummy = dummy; 768 printf("howto %d, devtype %d\n", arghowto, devtype); 769#endif 770die: 771 printf("Rebooting...\n"); 772 DELAY(1000000); /* wait 1 sec for printf's to complete and be read */ 773 cpu_reset(); 774 for(;;) ; 775 /* NOTREACHED */ 776} 777 778unsigned long dumpmag = 0x8fca0101UL; /* magic number for savecore */ 779int dumpsize = 0; /* also for savecore */ 780/* 781 * Doadump comes here after turning off memory management and 782 * getting on the dump stack, either when called above, or by 783 * the auto-restart code. 784 */ 785void 786dumpsys() 787{ 788 789 if (dumpdev == NODEV) 790 return; 791 if ((minor(dumpdev)&07) != 1) 792 return; 793 dumpsize = Maxmem; 794 printf("\ndumping to dev %x, offset %d\n", dumpdev, dumplo); 795 printf("dump "); 796 switch ((*bdevsw[major(dumpdev)].d_dump)(dumpdev)) { 797 798 case ENXIO: 799 printf("device bad\n"); 800 break; 801 802 case EFAULT: 803 printf("device not ready\n"); 804 break; 805 806 case EINVAL: 807 printf("area improper\n"); 808 break; 809 810 case EIO: 811 printf("i/o error\n"); 812 break; 813 814 case EINTR: 815 printf("aborted from console\n"); 816 break; 817 818 default: 819 printf("succeeded\n"); 820 break; 821 } 822} 823 824#ifdef HZ 825/* 826 * If HZ is defined we use this code, otherwise the code in 827 * /sys/i386/i386/microtime.s is used. The othercode only works 828 * for HZ=100. 829 */ 830microtime(tvp) 831 register struct timeval *tvp; 832{ 833 int s = splhigh(); 834 835 *tvp = time; 836 tvp->tv_usec += tick; 837 while (tvp->tv_usec > 1000000) { 838 tvp->tv_sec++; 839 tvp->tv_usec -= 1000000; 840 } 841 splx(s); 842} 843#endif /* HZ */ 844 845static void 846initcpu() 847{ 848} 849 850/* 851 * Clear registers on exec 852 */ 853void 854setregs(p, entry, stack) 855 struct proc *p; 856 u_long entry; 857 u_long stack; 858{ 859 p->p_md.md_regs[tEBP] = 0; /* bottom of the fp chain */ 860 p->p_md.md_regs[tEIP] = entry; 861 p->p_md.md_regs[tESP] = stack; 862 p->p_md.md_regs[tSS] = _udatasel; 863 p->p_md.md_regs[tDS] = _udatasel; 864 p->p_md.md_regs[tES] = _udatasel; 865 p->p_md.md_regs[tCS] = _ucodesel; 866 867 p->p_addr->u_pcb.pcb_flags = 0; /* no fp at all */ 868 load_cr0(rcr0() | CR0_TS); /* start emulating */ 869#if NNPX > 0 870 npxinit(__INITIAL_NPXCW__); 871#endif /* NNPX > 0 */ 872} 873 874/* 875 * machine dependent system variables. 876 */ 877int 878cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) 879 int *name; 880 u_int namelen; 881 void *oldp; 882 size_t *oldlenp; 883 void *newp; 884 size_t newlen; 885 struct proc *p; 886{ 887 888 /* all sysctl names at this level are terminal */ 889 if (namelen != 1) 890 return (ENOTDIR); /* overloaded */ 891 892 switch (name[0]) { 893 case CPU_CONSDEV: 894 return (sysctl_rdstruct(oldp, oldlenp, newp, &cn_tty->t_dev, 895 sizeof cn_tty->t_dev)); 896 default: 897 return (EOPNOTSUPP); 898 } 899 /* NOTREACHED */ 900} 901 902/* 903 * Initialize 386 and configure to run kernel 904 */ 905 906/* 907 * Initialize segments & interrupt table 908 */ 909 910union descriptor gdt[NGDT]; 911union descriptor ldt[NLDT]; /* local descriptor table */ 912struct gate_descriptor idt[NIDT]; /* interrupt descriptor table */ 913 914int _default_ldt, currentldt; 915 916struct i386tss tss, panic_tss; 917 918extern struct user *proc0paddr; 919 920/* software prototypes -- in more palatable form */ 921struct soft_segment_descriptor gdt_segs[] = { 922 /* Null Descriptor */ 923{ 0x0, /* segment base address */ 924 0x0, /* length */ 925 0, /* segment type */ 926 0, /* segment descriptor priority level */ 927 0, /* segment descriptor present */ 928 0, 0, 929 0, /* default 32 vs 16 bit size */ 930 0 /* limit granularity (byte/page units)*/ }, 931 /* Code Descriptor for kernel */ 932{ 0x0, /* segment base address */ 933 0xfffff, /* length - all address space */ 934 SDT_MEMERA, /* segment type */ 935 0, /* segment descriptor priority level */ 936 1, /* segment descriptor present */ 937 0, 0, 938 1, /* default 32 vs 16 bit size */ 939 1 /* limit granularity (byte/page units)*/ }, 940 /* Data Descriptor for kernel */ 941{ 0x0, /* segment base address */ 942 0xfffff, /* length - all address space */ 943 SDT_MEMRWA, /* segment type */ 944 0, /* segment descriptor priority level */ 945 1, /* segment descriptor present */ 946 0, 0, 947 1, /* default 32 vs 16 bit size */ 948 1 /* limit granularity (byte/page units)*/ }, 949 /* LDT Descriptor */ 950{ (int) ldt, /* segment base address */ 951 sizeof(ldt)-1, /* length - all address space */ 952 SDT_SYSLDT, /* segment type */ 953 0, /* segment descriptor priority level */ 954 1, /* segment descriptor present */ 955 0, 0, 956 0, /* unused - default 32 vs 16 bit size */ 957 0 /* limit granularity (byte/page units)*/ }, 958 /* Null Descriptor - Placeholder */ 959{ 0x0, /* segment base address */ 960 0x0, /* length - all address space */ 961 0, /* segment type */ 962 0, /* segment descriptor priority level */ 963 0, /* segment descriptor present */ 964 0, 0, 965 0, /* default 32 vs 16 bit size */ 966 0 /* limit granularity (byte/page units)*/ }, 967 /* Panic Tss Descriptor */ 968{ (int) &panic_tss, /* segment base address */ 969 sizeof(tss)-1, /* length - all address space */ 970 SDT_SYS386TSS, /* segment type */ 971 0, /* segment descriptor priority level */ 972 1, /* segment descriptor present */ 973 0, 0, 974 0, /* unused - default 32 vs 16 bit size */ 975 0 /* limit granularity (byte/page units)*/ }, 976 /* Proc 0 Tss Descriptor */ 977{ (int) kstack, /* segment base address */ 978 sizeof(tss)-1, /* length - all address space */ 979 SDT_SYS386TSS, /* segment type */ 980 0, /* segment descriptor priority level */ 981 1, /* segment descriptor present */ 982 0, 0, 983 0, /* unused - default 32 vs 16 bit size */ 984 0 /* limit granularity (byte/page units)*/ }, 985 /* User LDT Descriptor per process */ 986{ (int) ldt, /* segment base address */ 987 (512 * sizeof(union descriptor)-1), /* length */ 988 SDT_SYSLDT, /* segment type */ 989 0, /* segment descriptor priority level */ 990 1, /* segment descriptor present */ 991 0, 0, 992 0, /* unused - default 32 vs 16 bit size */ 993 0 /* limit granularity (byte/page units)*/ }, 994}; 995 996struct soft_segment_descriptor ldt_segs[] = { 997 /* Null Descriptor - overwritten by call gate */ 998{ 0x0, /* segment base address */ 999 0x0, /* length - all address space */ 1000 0, /* segment type */ 1001 0, /* segment descriptor priority level */ 1002 0, /* segment descriptor present */ 1003 0, 0, 1004 0, /* default 32 vs 16 bit size */ 1005 0 /* limit granularity (byte/page units)*/ }, 1006 /* Null Descriptor - overwritten by call gate */ 1007{ 0x0, /* segment base address */ 1008 0x0, /* length - all address space */ 1009 0, /* segment type */ 1010 0, /* segment descriptor priority level */ 1011 0, /* segment descriptor present */ 1012 0, 0, 1013 0, /* default 32 vs 16 bit size */ 1014 0 /* limit granularity (byte/page units)*/ }, 1015 /* Null Descriptor - overwritten by call gate */ 1016{ 0x0, /* segment base address */ 1017 0x0, /* length - all address space */ 1018 0, /* segment type */ 1019 0, /* segment descriptor priority level */ 1020 0, /* segment descriptor present */ 1021 0, 0, 1022 0, /* default 32 vs 16 bit size */ 1023 0 /* limit granularity (byte/page units)*/ }, 1024 /* Code Descriptor for user */ 1025{ 0x0, /* segment base address */ 1026 0xfffff, /* length - all address space */ 1027 SDT_MEMERA, /* segment type */ 1028 SEL_UPL, /* segment descriptor priority level */ 1029 1, /* segment descriptor present */ 1030 0, 0, 1031 1, /* default 32 vs 16 bit size */ 1032 1 /* limit granularity (byte/page units)*/ }, 1033 /* Data Descriptor for user */ 1034{ 0x0, /* segment base address */ 1035 0xfffff, /* length - all address space */ 1036 SDT_MEMRWA, /* segment type */ 1037 SEL_UPL, /* segment descriptor priority level */ 1038 1, /* segment descriptor present */ 1039 0, 0, 1040 1, /* default 32 vs 16 bit size */ 1041 1 /* limit granularity (byte/page units)*/ } }; 1042 1043void 1044setidt(idx, func, typ, dpl) 1045 int idx; 1046 void (*func)(); 1047 int typ; 1048 int dpl; 1049{ 1050 struct gate_descriptor *ip = idt + idx; 1051 1052 ip->gd_looffset = (int)func; 1053 ip->gd_selector = 8; 1054 ip->gd_stkcpy = 0; 1055 ip->gd_xx = 0; 1056 ip->gd_type = typ; 1057 ip->gd_dpl = dpl; 1058 ip->gd_p = 1; 1059 ip->gd_hioffset = ((int)func)>>16 ; 1060} 1061 1062#define IDTVEC(name) __CONCAT(X,name) 1063typedef void idtvec_t(); 1064 1065extern idtvec_t 1066 IDTVEC(div), IDTVEC(dbg), IDTVEC(nmi), IDTVEC(bpt), IDTVEC(ofl), 1067 IDTVEC(bnd), IDTVEC(ill), IDTVEC(dna), IDTVEC(dble), IDTVEC(fpusegm), 1068 IDTVEC(tss), IDTVEC(missing), IDTVEC(stk), IDTVEC(prot), 1069 IDTVEC(page), IDTVEC(rsvd), IDTVEC(fpu), IDTVEC(rsvd0), 1070 IDTVEC(rsvd1), IDTVEC(rsvd2), IDTVEC(rsvd3), IDTVEC(rsvd4), 1071 IDTVEC(rsvd5), IDTVEC(rsvd6), IDTVEC(rsvd7), IDTVEC(rsvd8), 1072 IDTVEC(rsvd9), IDTVEC(rsvd10), IDTVEC(rsvd11), IDTVEC(rsvd12), 1073 IDTVEC(rsvd13), IDTVEC(rsvd14), IDTVEC(syscall); 1074 1075int _gsel_tss; 1076 1077void 1078init386(first) 1079 int first; 1080{ 1081 extern lgdt(), lidt(), lldt(), etext; 1082 int x, *pi; 1083 unsigned biosbasemem, biosextmem; 1084 struct gate_descriptor *gdp; 1085 extern int sigcode,szsigcode; 1086 /* table descriptors - used to load tables by microp */ 1087 struct region_descriptor r_gdt, r_idt; 1088 int pagesinbase, pagesinext; 1089 int target_page; 1090 extern struct pte *CMAP1; 1091 extern caddr_t CADDR1; 1092 1093 proc0.p_addr = proc0paddr; 1094 1095 /* 1096 * Initialize the console before we print anything out. 1097 */ 1098 1099 cninit (); 1100 1101 /* 1102 * make gdt memory segments, the code segment goes up to end of the 1103 * page with etext in it, the data segment goes to the end of 1104 * the address space 1105 */ 1106 gdt_segs[GCODE_SEL].ssd_limit = i386_btop(0) - 1 /* i386_btop(i386_round_page(&etext)) - 1 */; 1107 gdt_segs[GDATA_SEL].ssd_limit = i386_btop(0) - 1; 1108 for (x=0; x < NGDT; x++) ssdtosd(gdt_segs+x, gdt+x); 1109 1110 /* make ldt memory segments */ 1111 /* 1112 * The data segment limit must not cover the user area because we 1113 * don't want the user area to be writable in copyout() etc. (page 1114 * level protection is lost in kernel mode on 386's). Also, we 1115 * don't want the user area to be writable directly (page level 1116 * protection of the user area is not available on 486's with 1117 * CR0_WP set, because there is no user-read/kernel-write mode). 1118 * 1119 * XXX - VM_MAXUSER_ADDRESS is an end address, not a max. And it 1120 * should be spelled ...MAX_USER... 1121 */ 1122#define VM_END_USER_RW_ADDRESS VM_MAXUSER_ADDRESS 1123 /* 1124 * The code segment limit has to cover the user area until we move 1125 * the signal trampoline out of the user area. This is safe because 1126 * the code segment cannot be written to directly. 1127 */ 1128#define VM_END_USER_R_ADDRESS (VM_END_USER_RW_ADDRESS + UPAGES * NBPG) 1129 ldt_segs[LUCODE_SEL].ssd_limit = i386_btop(VM_END_USER_R_ADDRESS) - 1; 1130 ldt_segs[LUDATA_SEL].ssd_limit = i386_btop(VM_END_USER_RW_ADDRESS) - 1; 1131 /* Note. eventually want private ldts per process */ 1132 for (x=0; x < 5; x++) ssdtosd(ldt_segs+x, ldt+x); 1133 1134 /* exceptions */ 1135 setidt(0, &IDTVEC(div), SDT_SYS386TGT, SEL_KPL); 1136 setidt(1, &IDTVEC(dbg), SDT_SYS386TGT, SEL_KPL); 1137 setidt(2, &IDTVEC(nmi), SDT_SYS386TGT, SEL_KPL); 1138 setidt(3, &IDTVEC(bpt), SDT_SYS386TGT, SEL_UPL); 1139 setidt(4, &IDTVEC(ofl), SDT_SYS386TGT, SEL_UPL); 1140 setidt(5, &IDTVEC(bnd), SDT_SYS386TGT, SEL_KPL); 1141 setidt(6, &IDTVEC(ill), SDT_SYS386TGT, SEL_KPL); 1142 setidt(7, &IDTVEC(dna), SDT_SYS386TGT, SEL_KPL); 1143 setidt(8, &IDTVEC(dble), SDT_SYS386TGT, SEL_KPL); 1144 setidt(9, &IDTVEC(fpusegm), SDT_SYS386TGT, SEL_KPL); 1145 setidt(10, &IDTVEC(tss), SDT_SYS386TGT, SEL_KPL); 1146 setidt(11, &IDTVEC(missing), SDT_SYS386TGT, SEL_KPL); 1147 setidt(12, &IDTVEC(stk), SDT_SYS386TGT, SEL_KPL); 1148 setidt(13, &IDTVEC(prot), SDT_SYS386TGT, SEL_KPL); 1149 setidt(14, &IDTVEC(page), SDT_SYS386TGT, SEL_KPL); 1150 setidt(15, &IDTVEC(rsvd), SDT_SYS386TGT, SEL_KPL); 1151 setidt(16, &IDTVEC(fpu), SDT_SYS386TGT, SEL_KPL); 1152 setidt(17, &IDTVEC(rsvd0), SDT_SYS386TGT, SEL_KPL); 1153 setidt(18, &IDTVEC(rsvd1), SDT_SYS386TGT, SEL_KPL); 1154 setidt(19, &IDTVEC(rsvd2), SDT_SYS386TGT, SEL_KPL); 1155 setidt(20, &IDTVEC(rsvd3), SDT_SYS386TGT, SEL_KPL); 1156 setidt(21, &IDTVEC(rsvd4), SDT_SYS386TGT, SEL_KPL); 1157 setidt(22, &IDTVEC(rsvd5), SDT_SYS386TGT, SEL_KPL); 1158 setidt(23, &IDTVEC(rsvd6), SDT_SYS386TGT, SEL_KPL); 1159 setidt(24, &IDTVEC(rsvd7), SDT_SYS386TGT, SEL_KPL); 1160 setidt(25, &IDTVEC(rsvd8), SDT_SYS386TGT, SEL_KPL); 1161 setidt(26, &IDTVEC(rsvd9), SDT_SYS386TGT, SEL_KPL); 1162 setidt(27, &IDTVEC(rsvd10), SDT_SYS386TGT, SEL_KPL); 1163 setidt(28, &IDTVEC(rsvd11), SDT_SYS386TGT, SEL_KPL); 1164 setidt(29, &IDTVEC(rsvd12), SDT_SYS386TGT, SEL_KPL); 1165 setidt(30, &IDTVEC(rsvd13), SDT_SYS386TGT, SEL_KPL); 1166 setidt(31, &IDTVEC(rsvd14), SDT_SYS386TGT, SEL_KPL); 1167 1168#include "isa.h" 1169#if NISA >0 1170 isa_defaultirq(); 1171#endif 1172 1173 r_gdt.rd_limit = sizeof(gdt) - 1; 1174 r_gdt.rd_base = (int) gdt; 1175 lgdt(&r_gdt); 1176 1177 r_idt.rd_limit = sizeof(idt) - 1; 1178 r_idt.rd_base = (int) idt; 1179 lidt(&r_idt); 1180 1181 _default_ldt = GSEL(GLDT_SEL, SEL_KPL); 1182 lldt(_default_ldt); 1183 currentldt = _default_ldt; 1184 1185#ifdef DDB 1186 kdb_init(); 1187 if (boothowto & RB_KDB) 1188 Debugger("Boot flags requested debugger"); 1189#endif 1190 1191 /* Use BIOS values stored in RTC CMOS RAM, since probing 1192 * breaks certain 386 AT relics. 1193 */ 1194 biosbasemem = rtcin(RTC_BASELO)+ (rtcin(RTC_BASEHI)<<8); 1195 biosextmem = rtcin(RTC_EXTLO)+ (rtcin(RTC_EXTHI)<<8); 1196 1197 /* 1198 * If BIOS tells us that it has more than 640k in the basemem, 1199 * don't believe it - set it to 640k. 1200 */ 1201 if (biosbasemem > 640) 1202 biosbasemem = 640; 1203 1204 /* 1205 * Some 386 machines might give us a bogus number for extended 1206 * mem. If this happens, stop now. 1207 */ 1208#ifndef LARGEMEM 1209 if (biosextmem > 65536) { 1210 panic("extended memory beyond limit of 64MB"); 1211 /* NOTREACHED */ 1212 } 1213#endif 1214 1215 pagesinbase = biosbasemem * 1024 / NBPG; 1216 pagesinext = biosextmem * 1024 / NBPG; 1217 1218 /* 1219 * Special hack for chipsets that still remap the 384k hole when 1220 * there's 16MB of memory - this really confuses people that 1221 * are trying to use bus mastering ISA controllers with the 1222 * "16MB limit"; they only have 16MB, but the remapping puts 1223 * them beyond the limit. 1224 * XXX - this should be removed when bounce buffers are 1225 * implemented. 1226 */ 1227 /* 1228 * If extended memory is between 15-16MB (16-17MB phys address range), 1229 * chop it to 15MB. 1230 */ 1231 if ((pagesinext > 3840) && (pagesinext < 4096)) 1232 pagesinext = 3840; 1233 1234 /* 1235 * Maxmem isn't the "maximum memory", it's the highest page of 1236 * of the physical address space. It should be "Maxphyspage". 1237 */ 1238 Maxmem = pagesinext + 0x100000/PAGE_SIZE; 1239 1240#ifdef MAXMEM 1241 if (MAXMEM/4 < Maxmem) 1242 Maxmem = MAXMEM/4; 1243#endif 1244 /* 1245 * Calculate number of physical pages, but account for Maxmem 1246 * limitation above. 1247 */ 1248 physmem = pagesinbase + 1249 (min(pagesinext + 0x100000/PAGE_SIZE, Maxmem) - 0x100000/PAGE_SIZE); 1250 1251 /* call pmap initialization to make new kernel address space */ 1252 pmap_bootstrap (first, 0); 1253 1254 /* 1255 * Do simple memory test over range of extended memory that BIOS 1256 * indicates exists. Adjust Maxmem to the highest page of 1257 * good memory. 1258 */ 1259 printf("Testing memory (%dMB)...", ptoa(Maxmem)/1024/1024); 1260 1261 for (target_page = Maxmem - 1; target_page >= atop(first); target_page--) { 1262 1263 /* 1264 * map page into kernel: valid, read/write, non-cacheable 1265 */ 1266 *(int *)CMAP1 = PG_V | PG_KW | PG_N | ptoa(target_page); 1267 tlbflush(); 1268 1269 /* 1270 * Test for alternating 1's and 0's 1271 */ 1272 filli(0xaaaaaaaa, CADDR1, PAGE_SIZE/sizeof(int)); 1273 if (test_page((int *)CADDR1, 0xaaaaaaaa)) { 1274 Maxmem = target_page; 1275 badpages++; 1276 continue; 1277 } 1278 /* 1279 * Test for alternating 0's and 1's 1280 */ 1281 filli(0x55555555, CADDR1, PAGE_SIZE/sizeof(int)); 1282 if (test_page((int *)CADDR1, 0x55555555)) { 1283 Maxmem = target_page; 1284 badpages++; 1285 continue; 1286 } 1287 /* 1288 * Test for all 1's 1289 */ 1290 filli(0xffffffff, CADDR1, PAGE_SIZE/sizeof(int)); 1291 if (test_page((int *)CADDR1, 0xffffffff)) { 1292 Maxmem = target_page; 1293 badpages++; 1294 continue; 1295 } 1296 /* 1297 * Test zeroing of page 1298 */ 1299 bzero(CADDR1, PAGE_SIZE); 1300 if (test_page((int *)CADDR1, 0)) { 1301 /* 1302 * test of page failed 1303 */ 1304 Maxmem = target_page; 1305 badpages++; 1306 continue; 1307 } 1308 } 1309 printf("done.\n"); 1310 1311 *(int *)CMAP1 = 0; 1312 tlbflush(); 1313 1314 avail_end = (Maxmem << PAGE_SHIFT) 1315 - i386_round_page(sizeof(struct msgbuf)); 1316 1317 /* 1318 * Initialize pointers to the two chunks of memory; for use 1319 * later in vm_page_startup. 1320 */ 1321 /* avail_start is initialized in pmap_bootstrap */ 1322 x = 0; 1323 if (pagesinbase > 1) { 1324 phys_avail[x++] = NBPG; /* skip first page of memory */ 1325 phys_avail[x++] = pagesinbase * NBPG; /* memory up to the ISA hole */ 1326 } 1327 phys_avail[x++] = avail_start; /* memory up to the end */ 1328 phys_avail[x++] = avail_end; 1329 phys_avail[x++] = 0; /* no more chunks */ 1330 phys_avail[x++] = 0; 1331 1332 /* now running on new page tables, configured,and u/iom is accessible */ 1333 1334 /* make a initial tss so microp can get interrupt stack on syscall! */ 1335 proc0.p_addr->u_pcb.pcb_tss.tss_esp0 = (int) kstack + UPAGES*NBPG; 1336 proc0.p_addr->u_pcb.pcb_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL) ; 1337 _gsel_tss = GSEL(GPROC0_SEL, SEL_KPL); 1338 1339 ((struct i386tss *)gdt_segs[GPROC0_SEL].ssd_base)->tss_ioopt = 1340 (sizeof(tss))<<16; 1341 1342 ltr(_gsel_tss); 1343 1344 /* make a call gate to reenter kernel with */ 1345 gdp = &ldt[LSYS5CALLS_SEL].gd; 1346 1347 x = (int) &IDTVEC(syscall); 1348 gdp->gd_looffset = x++; 1349 gdp->gd_selector = GSEL(GCODE_SEL,SEL_KPL); 1350 gdp->gd_stkcpy = 1; 1351 gdp->gd_type = SDT_SYS386CGT; 1352 gdp->gd_dpl = SEL_UPL; 1353 gdp->gd_p = 1; 1354 gdp->gd_hioffset = ((int) &IDTVEC(syscall)) >>16; 1355 1356 /* transfer to user mode */ 1357 1358 _ucodesel = LSEL(LUCODE_SEL, SEL_UPL); 1359 _udatasel = LSEL(LUDATA_SEL, SEL_UPL); 1360 1361 /* setup proc 0's pcb */ 1362 bcopy(&sigcode, proc0.p_addr->u_pcb.pcb_sigc, szsigcode); 1363 proc0.p_addr->u_pcb.pcb_flags = 0; 1364 proc0.p_addr->u_pcb.pcb_ptd = IdlePTD; 1365} 1366 1367int 1368test_page(address, pattern) 1369 int *address; 1370 int pattern; 1371{ 1372 int *x; 1373 1374 for (x = address; x < (int *)((char *)address + PAGE_SIZE); x++) { 1375 if (*x != pattern) 1376 return (1); 1377 } 1378 return(0); 1379} 1380 1381/* 1382 * The registers are in the frame; the frame is in the user area of 1383 * the process in question; when the process is active, the registers 1384 * are in "the kernel stack"; when it's not, they're still there, but 1385 * things get flipped around. So, since p->p_md.md_regs is the whole address 1386 * of the register set, take its offset from the kernel stack, and 1387 * index into the user block. Don't you just *love* virtual memory? 1388 * (I'm starting to think seymour is right...) 1389 */ 1390 1391int 1392ptrace_set_pc (struct proc *p, unsigned int addr) { 1393 void *regs = (char*)p->p_addr + 1394 ((char*) p->p_md.md_regs - (char*) kstack); 1395 1396 ((struct trapframe *)regs)->tf_eip = addr; 1397 return 0; 1398} 1399 1400int 1401ptrace_single_step (struct proc *p) { 1402 void *regs = (char*)p->p_addr + 1403 ((char*) p->p_md.md_regs - (char*) kstack); 1404 1405 ((struct trapframe *)regs)->tf_eflags |= PSL_T; 1406 return 0; 1407} 1408 1409/* 1410 * Copy the registers to user-space. 1411 */ 1412 1413int 1414ptrace_getregs (struct proc *p, unsigned int *addr) { 1415 int error; 1416 struct reg regs = {0}; 1417 1418 if (error = fill_regs (p, ®s)) 1419 return error; 1420 1421 return copyout (®s, addr, sizeof (regs)); 1422} 1423 1424int 1425ptrace_setregs (struct proc *p, unsigned int *addr) { 1426 int error; 1427 struct reg regs = {0}; 1428 1429 if (error = copyin (addr, ®s, sizeof(regs))) 1430 return error; 1431 1432 return set_regs (p, ®s); 1433} 1434 1435int 1436fill_regs(struct proc *p, struct reg *regs) { 1437 int error; 1438 struct trapframe *tp; 1439 void *ptr = (char*)p->p_addr + 1440 ((char*) p->p_md.md_regs - (char*) kstack); 1441 1442 tp = ptr; 1443 regs->r_es = tp->tf_es; 1444 regs->r_ds = tp->tf_ds; 1445 regs->r_edi = tp->tf_edi; 1446 regs->r_esi = tp->tf_esi; 1447 regs->r_ebp = tp->tf_ebp; 1448 regs->r_ebx = tp->tf_ebx; 1449 regs->r_edx = tp->tf_edx; 1450 regs->r_ecx = tp->tf_ecx; 1451 regs->r_eax = tp->tf_eax; 1452 regs->r_eip = tp->tf_eip; 1453 regs->r_cs = tp->tf_cs; 1454 regs->r_eflags = tp->tf_eflags; 1455 regs->r_esp = tp->tf_esp; 1456 regs->r_ss = tp->tf_ss; 1457 return 0; 1458} 1459 1460int 1461set_regs (struct proc *p, struct reg *regs) { 1462 int error; 1463 struct trapframe *tp; 1464 void *ptr = (char*)p->p_addr + 1465 ((char*) p->p_md.md_regs - (char*) kstack); 1466 1467 tp = ptr; 1468 tp->tf_es = regs->r_es; 1469 tp->tf_ds = regs->r_ds; 1470 tp->tf_edi = regs->r_edi; 1471 tp->tf_esi = regs->r_esi; 1472 tp->tf_ebp = regs->r_ebp; 1473 tp->tf_ebx = regs->r_ebx; 1474 tp->tf_edx = regs->r_edx; 1475 tp->tf_ecx = regs->r_ecx; 1476 tp->tf_eax = regs->r_eax; 1477 tp->tf_eip = regs->r_eip; 1478 tp->tf_cs = regs->r_cs; 1479 tp->tf_eflags = regs->r_eflags; 1480 tp->tf_esp = regs->r_esp; 1481 tp->tf_ss = regs->r_ss; 1482 return 0; 1483} 1484 1485#ifndef DDB 1486void 1487Debugger(const char *msg) 1488{ 1489 printf("Debugger(\"%s\") called.\n", msg); 1490} 1491#endif /* no DDB */ 1492 1493#include <sys/disklabel.h> 1494#define b_cylin b_resid 1495#define dkpart(dev) (minor(dev) & 7) 1496/* 1497 * Determine the size of the transfer, and make sure it is 1498 * within the boundaries of the partition. Adjust transfer 1499 * if needed, and signal errors or early completion. 1500 */ 1501int 1502bounds_check_with_label(struct buf *bp, struct disklabel *lp, int wlabel) 1503{ 1504 struct partition *p = lp->d_partitions + dkpart(bp->b_dev); 1505 int labelsect = lp->d_partitions[0].p_offset; 1506 int maxsz = p->p_size, 1507 sz = (bp->b_bcount + DEV_BSIZE - 1) >> DEV_BSHIFT; 1508 1509 /* overwriting disk label ? */ 1510 /* XXX should also protect bootstrap in first 8K */ 1511 if (bp->b_blkno + p->p_offset <= LABELSECTOR + labelsect && 1512#if LABELSECTOR != 0 1513 bp->b_blkno + p->p_offset + sz > LABELSECTOR + labelsect && 1514#endif 1515 (bp->b_flags & B_READ) == 0 && wlabel == 0) { 1516 bp->b_error = EROFS; 1517 goto bad; 1518 } 1519 1520#if defined(DOSBBSECTOR) && defined(notyet) 1521 /* overwriting master boot record? */ 1522 if (bp->b_blkno + p->p_offset <= DOSBBSECTOR && 1523 (bp->b_flags & B_READ) == 0 && wlabel == 0) { 1524 bp->b_error = EROFS; 1525 goto bad; 1526 } 1527#endif 1528 1529 /* beyond partition? */ 1530 if (bp->b_blkno < 0 || bp->b_blkno + sz > maxsz) { 1531 /* if exactly at end of disk, return an EOF */ 1532 if (bp->b_blkno == maxsz) { 1533 bp->b_resid = bp->b_bcount; 1534 return(0); 1535 } 1536 /* or truncate if part of it fits */ 1537 sz = maxsz - bp->b_blkno; 1538 if (sz <= 0) { 1539 bp->b_error = EINVAL; 1540 goto bad; 1541 } 1542 bp->b_bcount = sz << DEV_BSHIFT; 1543 } 1544 1545 /* calculate cylinder for disksort to order transfers with */ 1546 bp->b_pblkno = bp->b_blkno + p->p_offset; 1547 bp->b_cylin = bp->b_pblkno / lp->d_secpercyl; 1548 return(1); 1549 1550bad: 1551 bp->b_flags |= B_ERROR; 1552 return(-1); 1553} 1554 1555