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