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