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