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