machdep.c revision 4038
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.83 1994/10/28 12:41:50 jkh 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 <machine/cpu.h> 87#include <machine/reg.h> 88#include <machine/psl.h> 89#include <machine/specialreg.h> 90#include <machine/sysarch.h> 91#include <machine/cons.h> 92#include <machine/devconf.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, disable_rtc_set; /* from clock.c */ 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 unsigned i; 164 register caddr_t v; 165 extern void (*netisrs[32])(void); 166 vm_offset_t maxaddr; 167 vm_size_t size = 0; 168 int firstaddr; 169#ifdef BOUNCE_BUFFERS 170 vm_offset_t minaddr; 171#endif /* BOUNCE_BUFFERS */ 172 173 /* 174 * Initialize error message buffer (at end of core). 175 */ 176 177 /* avail_end was pre-decremented in init_386() to compensate */ 178 for (i = 0; i < btoc(sizeof (struct msgbuf)); i++) 179 pmap_enter(pmap_kernel(), (vm_offset_t)msgbufp, 180 avail_end + i * NBPG, 181 VM_PROT_ALL, TRUE); 182 msgbufmapped = 1; 183 184 /* 185 * Good {morning,afternoon,evening,night}. 186 */ 187 printf(version); 188 startrtclock(); 189 identifycpu(); 190 printf("real memory = %d (%d pages)\n", ptoa(physmem), physmem); 191 if (badpages) 192 printf("bad memory = %d (%d pages)\n", ptoa(badpages), badpages); 193 194 /* 195 * Quickly wire in netisrs. 196 */ 197#define DONET(isr, n) do { extern void isr(void); netisrs[n] = isr; } while(0) 198#ifdef INET 199#if NETHER > 0 200 DONET(arpintr, NETISR_ARP); 201#endif 202 DONET(ipintr, NETISR_IP); 203#endif 204#ifdef NS 205 DONET(nsintr, NETISR_NS); 206#endif 207#ifdef ISO 208 DONET(clnlintr, NETISR_ISO); 209#endif 210#ifdef CCITT 211 DONET(ccittintr, NETISR_CCITT); 212#endif 213#undef DONET 214 215 /* 216 * Allocate space for system data structures. 217 * The first available kernel virtual address is in "v". 218 * As pages of kernel virtual memory are allocated, "v" is incremented. 219 * As pages of memory are allocated and cleared, 220 * "firstaddr" is incremented. 221 * An index into the kernel page table corresponding to the 222 * virtual memory address maintained in "v" is kept in "mapaddr". 223 */ 224 225 /* 226 * Make two passes. The first pass calculates how much memory is 227 * needed and allocates it. The second pass assigns virtual 228 * addresses to the various data structures. 229 */ 230 firstaddr = 0; 231again: 232 v = (caddr_t)firstaddr; 233 234#define valloc(name, type, num) \ 235 (name) = (type *)v; v = (caddr_t)((name)+(num)) 236#define valloclim(name, type, num, lim) \ 237 (name) = (type *)v; v = (caddr_t)((lim) = ((name)+(num))) 238 valloc(callout, struct callout, ncallout); 239#ifdef SYSVSHM 240 valloc(shmsegs, struct shmid_ds, shminfo.shmmni); 241#endif 242#ifdef SYSVSEM 243 valloc(sema, struct semid_ds, seminfo.semmni); 244 valloc(sem, struct sem, seminfo.semmns); 245 /* This is pretty disgusting! */ 246 valloc(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int)); 247#endif 248#ifdef SYSVMSG 249 valloc(msgpool, char, msginfo.msgmax); 250 valloc(msgmaps, struct msgmap, msginfo.msgseg); 251 valloc(msghdrs, struct msg, msginfo.msgtql); 252 valloc(msqids, struct msqid_ds, msginfo.msgmni); 253#endif 254 /* 255 * Determine how many buffers to allocate. 256 * Use 20% of memory of memory beyond the first 2MB 257 * Insure a minimum of 16 fs buffers. 258 * We allocate 1/2 as many swap buffer headers as file i/o buffers. 259 */ 260 if (bufpages == 0) 261 bufpages = ((physmem << PGSHIFT) - 2048*1024) / NBPG / 6; 262 if (bufpages < 64) 263 bufpages = 64; 264 265 /* 266 * We must still limit the maximum number of buffers to be no 267 * more than 750 because we'll run out of kernel VM otherwise. 268 */ 269 bufpages = min(bufpages, 1500); 270 if (nbuf == 0) { 271 nbuf = bufpages / 2; 272 if (nbuf < 32) 273 nbuf = 32; 274 } 275 freebufspace = bufpages * NBPG; 276 if (nswbuf == 0) { 277 nswbuf = (nbuf / 2) &~ 1; /* force even */ 278 if (nswbuf > 64) 279 nswbuf = 64; /* sanity */ 280 } 281 valloc(swbuf, struct buf, nswbuf); 282 valloc(buf, struct buf, nbuf); 283 284#ifdef BOUNCE_BUFFERS 285 /* 286 * If there is more than 16MB of memory, allocate some bounce buffers 287 */ 288 if (Maxmem > 4096) { 289 if (bouncepages == 0) 290 bouncepages = 96; /* largest physio size + extra */ 291 v = (caddr_t)((vm_offset_t)((vm_offset_t)v + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)); 292 valloc(bouncememory, char, bouncepages * PAGE_SIZE); 293 } 294#endif 295 296 /* 297 * End of first pass, size has been calculated so allocate memory 298 */ 299 if (firstaddr == 0) { 300 size = (vm_size_t)(v - firstaddr); 301 firstaddr = (int)kmem_alloc(kernel_map, round_page(size)); 302 if (firstaddr == 0) 303 panic("startup: no room for tables"); 304 goto again; 305 } 306 307 /* 308 * End of second pass, addresses have been assigned 309 */ 310 if ((vm_size_t)(v - firstaddr) != size) 311 panic("startup: table size inconsistency"); 312 313#ifdef BOUNCE_BUFFERS 314 clean_map = kmem_suballoc(kernel_map, &clean_sva, &clean_eva, 315 (nbuf*MAXBSIZE) + (nswbuf*MAXPHYS) + 316 maxbkva + pager_map_size, TRUE); 317 io_map = kmem_suballoc(clean_map, &minaddr, &maxaddr, maxbkva, FALSE); 318#else 319 clean_map = kmem_suballoc(kernel_map, &clean_sva, &clean_eva, 320 (nbuf*MAXBSIZE) + (nswbuf*MAXPHYS) + pager_map_size, TRUE); 321#endif 322 buffer_map = kmem_suballoc(clean_map, &buffer_sva, &buffer_eva, 323 (nbuf*MAXBSIZE), TRUE); 324 pager_map = kmem_suballoc(clean_map, &pager_sva, &pager_eva, 325 (nswbuf*MAXPHYS) + pager_map_size, TRUE); 326 327 /* 328 * Finally, allocate mbuf pool. Since mclrefcnt is an off-size 329 * we use the more space efficient malloc in place of kmem_alloc. 330 */ 331 mclrefcnt = (char *)malloc(NMBCLUSTERS+CLBYTES/MCLBYTES, 332 M_MBUF, M_NOWAIT); 333 bzero(mclrefcnt, NMBCLUSTERS+CLBYTES/MCLBYTES); 334 mb_map = kmem_suballoc(kmem_map, (vm_offset_t *)&mbutl, &maxaddr, 335 VM_MBUF_SIZE, FALSE); 336 /* 337 * Initialize callouts 338 */ 339 callfree = callout; 340 for (i = 1; i < ncallout; i++) 341 callout[i-1].c_next = &callout[i]; 342#ifdef USERCONFIG 343 if (boothowto & RB_CONFIG) 344 userconfig(); 345#endif 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%lx",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; 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 (cncheckc()) /* 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 %lx, offset %ld\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 int error; 913 914 /* all sysctl names at this level are terminal */ 915 if (namelen != 1) 916 return (ENOTDIR); /* overloaded */ 917 918 switch (name[0]) { 919 case CPU_CONSDEV: 920 return (sysctl_rdstruct(oldp, oldlenp, newp, &cn_tty->t_dev, 921 sizeof cn_tty->t_dev)); 922 case CPU_ADJKERNTZ: 923 error = sysctl_int(oldp, oldlenp, newp, newlen, &adjkerntz); 924 if (!error && newp) 925 resettodr(); 926 return error; 927 case CPU_DISRTCSET: 928 return (sysctl_int(oldp, oldlenp, newp, newlen, &disable_rtc_set)); 929 default: 930 return (EOPNOTSUPP); 931 } 932 /* NOTREACHED */ 933} 934 935/* 936 * Initialize 386 and configure to run kernel 937 */ 938 939/* 940 * Initialize segments & interrupt table 941 */ 942 943union descriptor gdt[NGDT]; 944union descriptor ldt[NLDT]; /* local descriptor table */ 945struct gate_descriptor idt[NIDT]; /* interrupt descriptor table */ 946 947int _default_ldt, currentldt; 948 949struct i386tss tss, panic_tss; 950 951extern struct user *proc0paddr; 952 953/* software prototypes -- in more palatable form */ 954struct soft_segment_descriptor gdt_segs[] = { 955/* GNULL_SEL 0 Null Descriptor */ 956{ 0x0, /* segment base address */ 957 0x0, /* length */ 958 0, /* segment type */ 959 0, /* segment descriptor priority level */ 960 0, /* segment descriptor present */ 961 0, 0, 962 0, /* default 32 vs 16 bit size */ 963 0 /* limit granularity (byte/page units)*/ }, 964/* GCODE_SEL 1 Code Descriptor for kernel */ 965{ 0x0, /* segment base address */ 966 0xfffff, /* length - all address space */ 967 SDT_MEMERA, /* segment type */ 968 0, /* segment descriptor priority level */ 969 1, /* segment descriptor present */ 970 0, 0, 971 1, /* default 32 vs 16 bit size */ 972 1 /* limit granularity (byte/page units)*/ }, 973/* GDATA_SEL 2 Data Descriptor for kernel */ 974{ 0x0, /* segment base address */ 975 0xfffff, /* length - all address space */ 976 SDT_MEMRWA, /* segment type */ 977 0, /* segment descriptor priority level */ 978 1, /* segment descriptor present */ 979 0, 0, 980 1, /* default 32 vs 16 bit size */ 981 1 /* limit granularity (byte/page units)*/ }, 982/* GLDT_SEL 3 LDT Descriptor */ 983{ (int) ldt, /* segment base address */ 984 sizeof(ldt)-1, /* length - all address space */ 985 SDT_SYSLDT, /* segment type */ 986 0, /* segment descriptor priority level */ 987 1, /* segment descriptor present */ 988 0, 0, 989 0, /* unused - default 32 vs 16 bit size */ 990 0 /* limit granularity (byte/page units)*/ }, 991/* GTGATE_SEL 4 Null Descriptor - Placeholder */ 992{ 0x0, /* segment base address */ 993 0x0, /* length - all address space */ 994 0, /* segment type */ 995 0, /* segment descriptor priority level */ 996 0, /* segment descriptor present */ 997 0, 0, 998 0, /* default 32 vs 16 bit size */ 999 0 /* limit granularity (byte/page units)*/ }, 1000/* GPANIC_SEL 5 Panic Tss Descriptor */ 1001{ (int) &panic_tss, /* segment base address */ 1002 sizeof(tss)-1, /* length - all address space */ 1003 SDT_SYS386TSS, /* segment type */ 1004 0, /* segment descriptor priority level */ 1005 1, /* segment descriptor present */ 1006 0, 0, 1007 0, /* unused - default 32 vs 16 bit size */ 1008 0 /* limit granularity (byte/page units)*/ }, 1009/* GPROC0_SEL 6 Proc 0 Tss Descriptor */ 1010{ (int) kstack, /* segment base address */ 1011 sizeof(tss)-1, /* length - all address space */ 1012 SDT_SYS386TSS, /* segment type */ 1013 0, /* segment descriptor priority level */ 1014 1, /* segment descriptor present */ 1015 0, 0, 1016 0, /* unused - default 32 vs 16 bit size */ 1017 0 /* limit granularity (byte/page units)*/ }, 1018/* GUSERLDT_SEL 7 User LDT Descriptor per process */ 1019{ (int) ldt, /* segment base address */ 1020 (512 * sizeof(union descriptor)-1), /* length */ 1021 SDT_SYSLDT, /* segment type */ 1022 0, /* segment descriptor priority level */ 1023 1, /* segment descriptor present */ 1024 0, 0, 1025 0, /* unused - default 32 vs 16 bit size */ 1026 0 /* limit granularity (byte/page units)*/ }, 1027/* GAPMCODE32_SEL 8 APM BIOS 32-bit interface (32bit Code) */ 1028{ 0, /* segment base address (overwritten by APM) */ 1029 0xfffff, /* length */ 1030 SDT_MEMERA, /* segment type */ 1031 0, /* segment descriptor priority level */ 1032 1, /* segment descriptor present */ 1033 0, 0, 1034 1, /* default 32 vs 16 bit size */ 1035 1 /* limit granularity (byte/page units)*/ }, 1036/* GAPMCODE16_SEL 9 APM BIOS 32-bit interface (16bit Code) */ 1037{ 0, /* segment base address (overwritten by APM) */ 1038 0xfffff, /* length */ 1039 SDT_MEMERA, /* segment type */ 1040 0, /* segment descriptor priority level */ 1041 1, /* segment descriptor present */ 1042 0, 0, 1043 0, /* default 32 vs 16 bit size */ 1044 1 /* limit granularity (byte/page units)*/ }, 1045/* GAPMDATA_SEL 10 APM BIOS 32-bit interface (Data) */ 1046{ 0, /* segment base address (overwritten by APM) */ 1047 0xfffff, /* length */ 1048 SDT_MEMRWA, /* segment type */ 1049 0, /* segment descriptor priority level */ 1050 1, /* segment descriptor present */ 1051 0, 0, 1052 1, /* default 32 vs 16 bit size */ 1053 1 /* limit granularity (byte/page units)*/ }, 1054}; 1055 1056struct soft_segment_descriptor ldt_segs[] = { 1057 /* Null Descriptor - overwritten by call gate */ 1058{ 0x0, /* segment base address */ 1059 0x0, /* length - all address space */ 1060 0, /* segment type */ 1061 0, /* segment descriptor priority level */ 1062 0, /* segment descriptor present */ 1063 0, 0, 1064 0, /* default 32 vs 16 bit size */ 1065 0 /* limit granularity (byte/page units)*/ }, 1066 /* Null Descriptor - overwritten by call gate */ 1067{ 0x0, /* segment base address */ 1068 0x0, /* length - all address space */ 1069 0, /* segment type */ 1070 0, /* segment descriptor priority level */ 1071 0, /* segment descriptor present */ 1072 0, 0, 1073 0, /* default 32 vs 16 bit size */ 1074 0 /* limit granularity (byte/page units)*/ }, 1075 /* Null Descriptor - overwritten by call gate */ 1076{ 0x0, /* segment base address */ 1077 0x0, /* length - all address space */ 1078 0, /* segment type */ 1079 0, /* segment descriptor priority level */ 1080 0, /* segment descriptor present */ 1081 0, 0, 1082 0, /* default 32 vs 16 bit size */ 1083 0 /* limit granularity (byte/page units)*/ }, 1084 /* Code Descriptor for user */ 1085{ 0x0, /* segment base address */ 1086 0xfffff, /* length - all address space */ 1087 SDT_MEMERA, /* segment type */ 1088 SEL_UPL, /* segment descriptor priority level */ 1089 1, /* segment descriptor present */ 1090 0, 0, 1091 1, /* default 32 vs 16 bit size */ 1092 1 /* limit granularity (byte/page units)*/ }, 1093 /* Data Descriptor for user */ 1094{ 0x0, /* segment base address */ 1095 0xfffff, /* length - all address space */ 1096 SDT_MEMRWA, /* segment type */ 1097 SEL_UPL, /* segment descriptor priority level */ 1098 1, /* segment descriptor present */ 1099 0, 0, 1100 1, /* default 32 vs 16 bit size */ 1101 1 /* limit granularity (byte/page units)*/ } }; 1102 1103void 1104setidt(idx, func, typ, dpl) 1105 int idx; 1106 void (*func)(); 1107 int typ; 1108 int dpl; 1109{ 1110 struct gate_descriptor *ip = idt + idx; 1111 1112 ip->gd_looffset = (int)func; 1113 ip->gd_selector = 8; 1114 ip->gd_stkcpy = 0; 1115 ip->gd_xx = 0; 1116 ip->gd_type = typ; 1117 ip->gd_dpl = dpl; 1118 ip->gd_p = 1; 1119 ip->gd_hioffset = ((int)func)>>16 ; 1120} 1121 1122#define IDTVEC(name) __CONCAT(X,name) 1123typedef void idtvec_t(); 1124 1125extern idtvec_t 1126 IDTVEC(div), IDTVEC(dbg), IDTVEC(nmi), IDTVEC(bpt), IDTVEC(ofl), 1127 IDTVEC(bnd), IDTVEC(ill), IDTVEC(dna), IDTVEC(dble), IDTVEC(fpusegm), 1128 IDTVEC(tss), IDTVEC(missing), IDTVEC(stk), IDTVEC(prot), 1129 IDTVEC(page), IDTVEC(rsvd), IDTVEC(fpu), IDTVEC(rsvd0), 1130 IDTVEC(rsvd1), IDTVEC(rsvd2), IDTVEC(rsvd3), IDTVEC(rsvd4), 1131 IDTVEC(rsvd5), IDTVEC(rsvd6), IDTVEC(rsvd7), IDTVEC(rsvd8), 1132 IDTVEC(rsvd9), IDTVEC(rsvd10), IDTVEC(rsvd11), IDTVEC(rsvd12), 1133 IDTVEC(rsvd13), IDTVEC(rsvd14), IDTVEC(syscall); 1134 1135int _gsel_tss; 1136 1137/* added sdtossd() by HOSOKAWA Tatsumi <hosokawa@mt.cs.keio.ac.jp> */ 1138int 1139sdtossd(sd, ssd) 1140 struct segment_descriptor *sd; 1141 struct soft_segment_descriptor *ssd; 1142{ 1143 ssd->ssd_base = (sd->sd_hibase << 24) | sd->sd_lobase; 1144 ssd->ssd_limit = (sd->sd_hilimit << 16) | sd->sd_lolimit; 1145 ssd->ssd_type = sd->sd_type; 1146 ssd->ssd_dpl = sd->sd_dpl; 1147 ssd->ssd_p = sd->sd_p; 1148 ssd->ssd_def32 = sd->sd_def32; 1149 ssd->ssd_gran = sd->sd_gran; 1150 return 0; 1151} 1152 1153void 1154init386(first) 1155 int first; 1156{ 1157 extern lgdt(), lidt(), lldt(); 1158 int x; 1159 unsigned biosbasemem, biosextmem; 1160 struct gate_descriptor *gdp; 1161 extern int sigcode,szsigcode; 1162 /* table descriptors - used to load tables by microp */ 1163 struct region_descriptor r_gdt, r_idt; 1164 int pagesinbase, pagesinext; 1165 int target_page; 1166 extern struct pte *CMAP1; 1167 extern caddr_t CADDR1; 1168 1169 proc0.p_addr = proc0paddr; 1170 1171 /* 1172 * Initialize the console before we print anything out. 1173 */ 1174 1175 cninit (); 1176 1177 /* 1178 * make gdt memory segments, the code segment goes up to end of the 1179 * page with etext in it, the data segment goes to the end of 1180 * the address space 1181 */ 1182 gdt_segs[GCODE_SEL].ssd_limit = i386_btop(0) - 1 /* i386_btop(i386_round_page(&etext)) - 1 */; 1183 gdt_segs[GDATA_SEL].ssd_limit = i386_btop(0) - 1; 1184 for (x=0; x < NGDT; x++) ssdtosd(gdt_segs+x, gdt+x); 1185 1186 /* make ldt memory segments */ 1187 /* 1188 * The data segment limit must not cover the user area because we 1189 * don't want the user area to be writable in copyout() etc. (page 1190 * level protection is lost in kernel mode on 386's). Also, we 1191 * don't want the user area to be writable directly (page level 1192 * protection of the user area is not available on 486's with 1193 * CR0_WP set, because there is no user-read/kernel-write mode). 1194 * 1195 * XXX - VM_MAXUSER_ADDRESS is an end address, not a max. And it 1196 * should be spelled ...MAX_USER... 1197 */ 1198#define VM_END_USER_RW_ADDRESS VM_MAXUSER_ADDRESS 1199 /* 1200 * The code segment limit has to cover the user area until we move 1201 * the signal trampoline out of the user area. This is safe because 1202 * the code segment cannot be written to directly. 1203 */ 1204#define VM_END_USER_R_ADDRESS (VM_END_USER_RW_ADDRESS + UPAGES * NBPG) 1205 ldt_segs[LUCODE_SEL].ssd_limit = i386_btop(VM_END_USER_R_ADDRESS) - 1; 1206 ldt_segs[LUDATA_SEL].ssd_limit = i386_btop(VM_END_USER_RW_ADDRESS) - 1; 1207 /* Note. eventually want private ldts per process */ 1208 for (x=0; x < 5; x++) ssdtosd(ldt_segs+x, ldt+x); 1209 1210 /* exceptions */ 1211 setidt(0, &IDTVEC(div), SDT_SYS386TGT, SEL_KPL); 1212 setidt(1, &IDTVEC(dbg), SDT_SYS386TGT, SEL_KPL); 1213 setidt(2, &IDTVEC(nmi), SDT_SYS386TGT, SEL_KPL); 1214 setidt(3, &IDTVEC(bpt), SDT_SYS386TGT, SEL_UPL); 1215 setidt(4, &IDTVEC(ofl), SDT_SYS386TGT, SEL_UPL); 1216 setidt(5, &IDTVEC(bnd), SDT_SYS386TGT, SEL_KPL); 1217 setidt(6, &IDTVEC(ill), SDT_SYS386TGT, SEL_KPL); 1218 setidt(7, &IDTVEC(dna), SDT_SYS386TGT, SEL_KPL); 1219 setidt(8, &IDTVEC(dble), SDT_SYS386TGT, SEL_KPL); 1220 setidt(9, &IDTVEC(fpusegm), SDT_SYS386TGT, SEL_KPL); 1221 setidt(10, &IDTVEC(tss), SDT_SYS386TGT, SEL_KPL); 1222 setidt(11, &IDTVEC(missing), SDT_SYS386TGT, SEL_KPL); 1223 setidt(12, &IDTVEC(stk), SDT_SYS386TGT, SEL_KPL); 1224 setidt(13, &IDTVEC(prot), SDT_SYS386TGT, SEL_KPL); 1225 setidt(14, &IDTVEC(page), SDT_SYS386TGT, SEL_KPL); 1226 setidt(15, &IDTVEC(rsvd), SDT_SYS386TGT, SEL_KPL); 1227 setidt(16, &IDTVEC(fpu), SDT_SYS386TGT, SEL_KPL); 1228 setidt(17, &IDTVEC(rsvd0), SDT_SYS386TGT, SEL_KPL); 1229 setidt(18, &IDTVEC(rsvd1), SDT_SYS386TGT, SEL_KPL); 1230 setidt(19, &IDTVEC(rsvd2), SDT_SYS386TGT, SEL_KPL); 1231 setidt(20, &IDTVEC(rsvd3), SDT_SYS386TGT, SEL_KPL); 1232 setidt(21, &IDTVEC(rsvd4), SDT_SYS386TGT, SEL_KPL); 1233 setidt(22, &IDTVEC(rsvd5), SDT_SYS386TGT, SEL_KPL); 1234 setidt(23, &IDTVEC(rsvd6), SDT_SYS386TGT, SEL_KPL); 1235 setidt(24, &IDTVEC(rsvd7), SDT_SYS386TGT, SEL_KPL); 1236 setidt(25, &IDTVEC(rsvd8), SDT_SYS386TGT, SEL_KPL); 1237 setidt(26, &IDTVEC(rsvd9), SDT_SYS386TGT, SEL_KPL); 1238 setidt(27, &IDTVEC(rsvd10), SDT_SYS386TGT, SEL_KPL); 1239 setidt(28, &IDTVEC(rsvd11), SDT_SYS386TGT, SEL_KPL); 1240 setidt(29, &IDTVEC(rsvd12), SDT_SYS386TGT, SEL_KPL); 1241 setidt(30, &IDTVEC(rsvd13), SDT_SYS386TGT, SEL_KPL); 1242 setidt(31, &IDTVEC(rsvd14), SDT_SYS386TGT, SEL_KPL); 1243 1244#include "isa.h" 1245#if NISA >0 1246 isa_defaultirq(); 1247#endif 1248 1249 r_gdt.rd_limit = sizeof(gdt) - 1; 1250 r_gdt.rd_base = (int) gdt; 1251 lgdt(&r_gdt); 1252 1253 r_idt.rd_limit = sizeof(idt) - 1; 1254 r_idt.rd_base = (int) idt; 1255 lidt(&r_idt); 1256 1257 _default_ldt = GSEL(GLDT_SEL, SEL_KPL); 1258 lldt(_default_ldt); 1259 currentldt = _default_ldt; 1260 1261#ifdef DDB 1262 kdb_init(); 1263 if (boothowto & RB_KDB) 1264 Debugger("Boot flags requested debugger"); 1265#endif 1266 1267 /* Use BIOS values stored in RTC CMOS RAM, since probing 1268 * breaks certain 386 AT relics. 1269 */ 1270 biosbasemem = rtcin(RTC_BASELO)+ (rtcin(RTC_BASEHI)<<8); 1271 biosextmem = rtcin(RTC_EXTLO)+ (rtcin(RTC_EXTHI)<<8); 1272 1273 /* 1274 * If BIOS tells us that it has more than 640k in the basemem, 1275 * don't believe it - set it to 640k. 1276 */ 1277 if (biosbasemem > 640) 1278 biosbasemem = 640; 1279 1280 /* 1281 * Some 386 machines might give us a bogus number for extended 1282 * mem. If this happens, stop now. 1283 */ 1284#ifndef LARGEMEM 1285 if (biosextmem > 65536) { 1286 panic("extended memory beyond limit of 64MB"); 1287 /* NOTREACHED */ 1288 } 1289#endif 1290 1291 pagesinbase = biosbasemem * 1024 / NBPG; 1292 pagesinext = biosextmem * 1024 / NBPG; 1293 1294 /* 1295 * Special hack for chipsets that still remap the 384k hole when 1296 * there's 16MB of memory - this really confuses people that 1297 * are trying to use bus mastering ISA controllers with the 1298 * "16MB limit"; they only have 16MB, but the remapping puts 1299 * them beyond the limit. 1300 * XXX - this should be removed when bounce buffers are 1301 * implemented. 1302 */ 1303 /* 1304 * If extended memory is between 15-16MB (16-17MB phys address range), 1305 * chop it to 15MB. 1306 */ 1307 if ((pagesinext > 3840) && (pagesinext < 4096)) 1308 pagesinext = 3840; 1309 1310 /* 1311 * Maxmem isn't the "maximum memory", it's the highest page of 1312 * of the physical address space. It should be "Maxphyspage". 1313 */ 1314 Maxmem = pagesinext + 0x100000/PAGE_SIZE; 1315 1316#ifdef MAXMEM 1317 if (MAXMEM/4 < Maxmem) 1318 Maxmem = MAXMEM/4; 1319#endif 1320 /* 1321 * Calculate number of physical pages, but account for Maxmem 1322 * adjustment above. 1323 */ 1324 physmem = pagesinbase + Maxmem - 0x100000/PAGE_SIZE; 1325 1326 /* call pmap initialization to make new kernel address space */ 1327 pmap_bootstrap (first, 0); 1328 1329 /* 1330 * Do simple memory test over range of extended memory that BIOS 1331 * indicates exists. Adjust Maxmem to the highest page of 1332 * good memory. 1333 */ 1334 printf("Testing memory (%dMB)...", ptoa(Maxmem)/1024/1024); 1335 1336 for (target_page = Maxmem - 1; target_page >= atop(first); target_page--) { 1337 1338 /* 1339 * map page into kernel: valid, read/write, non-cacheable 1340 */ 1341 *(int *)CMAP1 = PG_V | PG_KW | PG_N | ptoa(target_page); 1342 pmap_update(); 1343 1344 /* 1345 * Test for alternating 1's and 0's 1346 */ 1347 filli(0xaaaaaaaa, CADDR1, PAGE_SIZE/sizeof(int)); 1348 if (test_page((int *)CADDR1, 0xaaaaaaaa)) { 1349 Maxmem = target_page; 1350 badpages++; 1351 continue; 1352 } 1353 /* 1354 * Test for alternating 0's and 1's 1355 */ 1356 filli(0x55555555, CADDR1, PAGE_SIZE/sizeof(int)); 1357 if (test_page((int *)CADDR1, 0x55555555)) { 1358 Maxmem = target_page; 1359 badpages++; 1360 continue; 1361 } 1362 /* 1363 * Test for all 1's 1364 */ 1365 filli(0xffffffff, CADDR1, PAGE_SIZE/sizeof(int)); 1366 if (test_page((int *)CADDR1, 0xffffffff)) { 1367 Maxmem = target_page; 1368 badpages++; 1369 continue; 1370 } 1371 /* 1372 * Test zeroing of page 1373 */ 1374 bzero(CADDR1, PAGE_SIZE); 1375 if (test_page((int *)CADDR1, 0)) { 1376 /* 1377 * test of page failed 1378 */ 1379 Maxmem = target_page; 1380 badpages++; 1381 continue; 1382 } 1383 } 1384 printf("done.\n"); 1385 1386 *(int *)CMAP1 = 0; 1387 pmap_update(); 1388 1389 avail_end = (Maxmem << PAGE_SHIFT) 1390 - i386_round_page(sizeof(struct msgbuf)); 1391 1392 /* 1393 * Initialize pointers to the two chunks of memory; for use 1394 * later in vm_page_startup. 1395 */ 1396 /* avail_start is initialized in pmap_bootstrap */ 1397 x = 0; 1398 if (pagesinbase > 1) { 1399 phys_avail[x++] = NBPG; /* skip first page of memory */ 1400 phys_avail[x++] = pagesinbase * NBPG; /* memory up to the ISA hole */ 1401 } 1402 phys_avail[x++] = avail_start; /* memory up to the end */ 1403 phys_avail[x++] = avail_end; 1404 phys_avail[x++] = 0; /* no more chunks */ 1405 phys_avail[x++] = 0; 1406 1407 /* now running on new page tables, configured,and u/iom is accessible */ 1408 1409 /* make a initial tss so microp can get interrupt stack on syscall! */ 1410 proc0.p_addr->u_pcb.pcb_tss.tss_esp0 = (int) kstack + UPAGES*NBPG; 1411 proc0.p_addr->u_pcb.pcb_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL) ; 1412 _gsel_tss = GSEL(GPROC0_SEL, SEL_KPL); 1413 1414 ((struct i386tss *)gdt_segs[GPROC0_SEL].ssd_base)->tss_ioopt = 1415 (sizeof(tss))<<16; 1416 1417 ltr(_gsel_tss); 1418 1419 /* make a call gate to reenter kernel with */ 1420 gdp = &ldt[LSYS5CALLS_SEL].gd; 1421 1422 x = (int) &IDTVEC(syscall); 1423 gdp->gd_looffset = x++; 1424 gdp->gd_selector = GSEL(GCODE_SEL,SEL_KPL); 1425 gdp->gd_stkcpy = 1; 1426 gdp->gd_type = SDT_SYS386CGT; 1427 gdp->gd_dpl = SEL_UPL; 1428 gdp->gd_p = 1; 1429 gdp->gd_hioffset = ((int) &IDTVEC(syscall)) >>16; 1430 1431 /* transfer to user mode */ 1432 1433 _ucodesel = LSEL(LUCODE_SEL, SEL_UPL); 1434 _udatasel = LSEL(LUDATA_SEL, SEL_UPL); 1435 1436 /* setup proc 0's pcb */ 1437 bcopy(&sigcode, proc0.p_addr->u_pcb.pcb_sigc, szsigcode); 1438 proc0.p_addr->u_pcb.pcb_flags = 0; 1439 proc0.p_addr->u_pcb.pcb_ptd = IdlePTD; 1440} 1441 1442int 1443test_page(address, pattern) 1444 int *address; 1445 int pattern; 1446{ 1447 int *x; 1448 1449 for (x = address; x < (int *)((char *)address + PAGE_SIZE); x++) { 1450 if (*x != pattern) 1451 return (1); 1452 } 1453 return(0); 1454} 1455 1456/* 1457 * The registers are in the frame; the frame is in the user area of 1458 * the process in question; when the process is active, the registers 1459 * are in "the kernel stack"; when it's not, they're still there, but 1460 * things get flipped around. So, since p->p_md.md_regs is the whole address 1461 * of the register set, take its offset from the kernel stack, and 1462 * index into the user block. Don't you just *love* virtual memory? 1463 * (I'm starting to think seymour is right...) 1464 */ 1465 1466int 1467ptrace_set_pc (struct proc *p, unsigned int addr) { 1468 void *regs = (char*)p->p_addr + 1469 ((char*) p->p_md.md_regs - (char*) kstack); 1470 1471 ((struct trapframe *)regs)->tf_eip = addr; 1472 return 0; 1473} 1474 1475int 1476ptrace_single_step (struct proc *p) { 1477 void *regs = (char*)p->p_addr + 1478 ((char*) p->p_md.md_regs - (char*) kstack); 1479 1480 ((struct trapframe *)regs)->tf_eflags |= PSL_T; 1481 return 0; 1482} 1483 1484/* 1485 * Copy the registers to user-space. 1486 */ 1487 1488int 1489ptrace_getregs (struct proc *p, unsigned int *addr) { 1490 int error; 1491 struct reg regs = {0}; 1492 1493 error = fill_regs (p, ®s); 1494 if (error) 1495 return error; 1496 1497 return copyout (®s, addr, sizeof (regs)); 1498} 1499 1500int 1501ptrace_setregs (struct proc *p, unsigned int *addr) { 1502 int error; 1503 struct reg regs = {0}; 1504 1505 error = copyin (addr, ®s, sizeof(regs)); 1506 if (error) 1507 return error; 1508 1509 return set_regs (p, ®s); 1510} 1511 1512int 1513fill_regs(struct proc *p, struct reg *regs) { 1514 struct trapframe *tp; 1515 void *ptr = (char*)p->p_addr + 1516 ((char*) p->p_md.md_regs - (char*) kstack); 1517 1518 tp = ptr; 1519 regs->r_es = tp->tf_es; 1520 regs->r_ds = tp->tf_ds; 1521 regs->r_edi = tp->tf_edi; 1522 regs->r_esi = tp->tf_esi; 1523 regs->r_ebp = tp->tf_ebp; 1524 regs->r_ebx = tp->tf_ebx; 1525 regs->r_edx = tp->tf_edx; 1526 regs->r_ecx = tp->tf_ecx; 1527 regs->r_eax = tp->tf_eax; 1528 regs->r_eip = tp->tf_eip; 1529 regs->r_cs = tp->tf_cs; 1530 regs->r_eflags = tp->tf_eflags; 1531 regs->r_esp = tp->tf_esp; 1532 regs->r_ss = tp->tf_ss; 1533 return 0; 1534} 1535 1536int 1537set_regs (struct proc *p, struct reg *regs) { 1538 struct trapframe *tp; 1539 void *ptr = (char*)p->p_addr + 1540 ((char*) p->p_md.md_regs - (char*) kstack); 1541 1542 tp = ptr; 1543 tp->tf_es = regs->r_es; 1544 tp->tf_ds = regs->r_ds; 1545 tp->tf_edi = regs->r_edi; 1546 tp->tf_esi = regs->r_esi; 1547 tp->tf_ebp = regs->r_ebp; 1548 tp->tf_ebx = regs->r_ebx; 1549 tp->tf_edx = regs->r_edx; 1550 tp->tf_ecx = regs->r_ecx; 1551 tp->tf_eax = regs->r_eax; 1552 tp->tf_eip = regs->r_eip; 1553 tp->tf_cs = regs->r_cs; 1554 tp->tf_eflags = regs->r_eflags; 1555 tp->tf_esp = regs->r_esp; 1556 tp->tf_ss = regs->r_ss; 1557 return 0; 1558} 1559 1560#ifndef DDB 1561void 1562Debugger(const char *msg) 1563{ 1564 printf("Debugger(\"%s\") called.\n", msg); 1565} 1566#endif /* no DDB */ 1567 1568#include <sys/dkbad.h> 1569#include <sys/disklabel.h> 1570#define b_cylin b_resid 1571/* 1572 * Determine the size of the transfer, and make sure it is 1573 * within the boundaries of the partition. Adjust transfer 1574 * if needed, and signal errors or early completion. 1575 */ 1576int 1577bounds_check_with_label(struct buf *bp, struct disklabel *lp, int wlabel) 1578{ 1579 struct partition *p = lp->d_partitions + dkpart(bp->b_dev); 1580 int labelsect = lp->d_partitions[0].p_offset; 1581 int maxsz = p->p_size, 1582 sz = (bp->b_bcount + DEV_BSIZE - 1) >> DEV_BSHIFT; 1583 1584 /* overwriting disk label ? */ 1585 /* XXX should also protect bootstrap in first 8K */ 1586 if (bp->b_blkno + p->p_offset <= LABELSECTOR + labelsect && 1587#if LABELSECTOR != 0 1588 bp->b_blkno + p->p_offset + sz > LABELSECTOR + labelsect && 1589#endif 1590 (bp->b_flags & B_READ) == 0 && wlabel == 0) { 1591 bp->b_error = EROFS; 1592 goto bad; 1593 } 1594 1595#if defined(DOSBBSECTOR) && defined(notyet) 1596 /* overwriting master boot record? */ 1597 if (bp->b_blkno + p->p_offset <= DOSBBSECTOR && 1598 (bp->b_flags & B_READ) == 0 && wlabel == 0) { 1599 bp->b_error = EROFS; 1600 goto bad; 1601 } 1602#endif 1603 1604 /* beyond partition? */ 1605 if (bp->b_blkno < 0 || bp->b_blkno + sz > maxsz) { 1606 /* if exactly at end of disk, return an EOF */ 1607 if (bp->b_blkno == maxsz) { 1608 bp->b_resid = bp->b_bcount; 1609 return(0); 1610 } 1611 /* or truncate if part of it fits */ 1612 sz = maxsz - bp->b_blkno; 1613 if (sz <= 0) { 1614 bp->b_error = EINVAL; 1615 goto bad; 1616 } 1617 bp->b_bcount = sz << DEV_BSHIFT; 1618 } 1619 1620 /* calculate cylinder for disksort to order transfers with */ 1621 bp->b_pblkno = bp->b_blkno + p->p_offset; 1622 bp->b_cylin = bp->b_pblkno / lp->d_secpercyl; 1623 return(1); 1624 1625bad: 1626 bp->b_flags |= B_ERROR; 1627 return(-1); 1628} 1629 1630int 1631disk_externalize(int drive, void *userp, size_t *maxlen) 1632{ 1633 if(*maxlen < sizeof drive) { 1634 return ENOMEM; 1635 } 1636 1637 *maxlen -= sizeof drive; 1638 return copyout(&drive, userp, sizeof drive); 1639} 1640 1641