--- /home/peter/releng_4/src/sys/i386/boot/biosboot/start.S Fri Aug 27 17:43:14 1999 +++ ./boot/biosboot/start.S Fri Apr 6 16:58:37 2001 @@ -25,6 +25,7 @@ * * from: Mach, Revision 2.2 92/04/04 11:36:29 rpd * $FreeBSD: src/sys/i386/boot/biosboot/start.S,v 1.13 1999/08/28 00:43:14 peter Exp $ + * $Yahoo: //depot/yahoo/ybsd_4/src/sys/i386/boot/biosboot/start.S#2 $ */ /* @@ -119,6 +120,14 @@ cmpb $0x80, %dl data32 jae hd + + /* the above assumption is not always true, so let's force it. */ + /* needed for the al440lx board. don't see much harm in it. */ + /* this used to fall through to floppy, but we know this is */ + /* a hd boot, right? */ + movb $0x80, %dl + data32 + jmp hd fd: /* diff -ru /home/peter/releng_4/src/sys/i386/i386/machdep.c ./i386/machdep.c --- /home/peter/releng_4/src/sys/i386/i386/machdep.c Mon Dec 1 23:02:18 2003 +++ ./i386/machdep.c Thu Dec 4 18:02:28 2003 @@ -1,3 +1,4 @@ +/* $Yahoo: //depot/yahoo/ybsd_4/src/sys/i386/i386/machdep.c#28 $ */ /*- * Copyright (c) 1992 Terrence R. Lambert. * Copyright (c) 1982, 1987, 1990 The Regents of the University of California. @@ -237,6 +238,8 @@ int bootverbose = 0, Maxmem = 0; long dumplo; +SYSCTL_INT(_hw, OID_AUTO, maxmem, CTLFLAG_RD, &Maxmem, 0, ""); + vm_paddr_t phys_avail[10]; /* must be 2 less so 0 0 can signal end of chunks */ @@ -359,7 +362,16 @@ (BKVASIZE * 2)) { nbuf = (kernel_map->max_offset - kernel_map->min_offset) / (BKVASIZE * 2); - printf("Warning: nbufs capped at %d\n", nbuf); + printf("Warning: nbufs capped at %d (1/2 of KVM)\n", nbuf); + } + + /* + * Do not allow the buffers to be more than 1/3 of the system ram. + * Even that is probably too generous. + */ + if (nbuf > (physmem / (3 * BKVASIZE / PAGE_SIZE))) { + nbuf = physmem / (4 * BKVASIZE / PAGE_SIZE); + printf("Warning: nbufs reset to %d (1/4 of system ram)\n", nbuf); } nswbuf = max(min(nbuf/4, 256), 16); @@ -978,6 +990,11 @@ * * On -stable, cpu_idle() is called with interrupts disabled and must * return with them enabled. + * + * XXX Pentium 4 Xeons suck. cpu_idle_hlt=1 on a SMP system depends on + * the interrupts being round-robined. But, that wasn't necessary for + * game performance so intel removed it. So, nothing regularly wakes the + * idle cpus. */ static int cpu_idle_hlt = 1; SYSCTL_INT(_machdep, OID_AUTO, cpu_idle_hlt, CTLFLAG_RW, @@ -1428,7 +1445,7 @@ static void getmemsize(int first) { - int i, physmap_idx, pa_indx; + int i, j, physmap_idx, pa_indx; int hasbrokenint12; u_int basemem, extmem; struct vm86frame vmf; @@ -1839,6 +1856,45 @@ phys_avail[pa_indx] -= round_page(MSGBUF_SIZE); avail_end = phys_avail[pa_indx]; + + if ((cp = getenv("hw.noclearmem")) != NULL) + return; + /* + * Clear all memory outside the message buffer. + * Certain versions of the Tyan 2510 bios do not + * clear extended memory to initialize the ECC system. + */ + printf("Clearing system memory... "); + pte = vtopte(KERNBASE + PAGE_SIZE); + j = 0; + for (i = 0; i <= pa_indx; i += 2) { + vm_paddr_t end; + int *ptr = (int *)(KERNBASE + PAGE_SIZE); + + end = phys_avail[i + 1]; + for (pa = phys_avail[i]; pa < end; pa += PAGE_SIZE) { + /* Do not bzero the kernel... */ + if (pa >= 0x100000 && pa < first) + continue; + + /* Map page into kernel: valid, read/write */ + *pte = pa | PG_V | PG_RW; + invltlb(); + + /* Clear the page */ + bzero(ptr, PAGE_SIZE); + + /* Progress? */ + j++; + if ((j & 0xffff) == 0) { /* 256MB */ + printf("%4dMB\b\b\b\b\b\b", + j * (PAGE_SIZE / 1024) / 1024); + } + } + } + *pte = 0; + invltlb(); + printf(" done. \n"); } void diff -ru /home/peter/releng_4/src/sys/i386/i386/mp_machdep.c ./i386/mp_machdep.c --- /home/peter/releng_4/src/sys/i386/i386/mp_machdep.c Thu Mar 25 13:35:14 2004 +++ ./i386/mp_machdep.c Thu Mar 11 11:33:14 2004 @@ -55,10 +55,8 @@ #include #include #include -#ifdef GPROF #include #endif -#endif #include #include @@ -2599,10 +2597,8 @@ struct vmspace *vm; int cpustate; struct proc *p; -#ifdef GPROF register struct gmonparam *g; int i; -#endif p = checkstate_curproc[id]; cpustate = checkstate_cpustate[id]; @@ -2620,7 +2616,6 @@ cp_time[CP_USER]++; break; case CHECKSTATE_SYS: -#ifdef GPROF /* * Kernel statistics are just like addupc_intr, only easier. */ @@ -2632,7 +2627,6 @@ g->kcount[i]++; } } -#endif if (pscnt > 1) return; @@ -2645,7 +2639,6 @@ break; case CHECKSTATE_INTR: default: -#ifdef GPROF /* * Kernel statistics are just like addupc_intr, only easier. */ @@ -2657,7 +2650,6 @@ g->kcount[i]++; } } -#endif if (pscnt > 1) return; if (p) diff -ru /home/peter/releng_4/src/sys/i386/i386/pmap.c ./i386/pmap.c --- /home/peter/releng_4/src/sys/i386/i386/pmap.c Mon Dec 1 23:02:18 2003 +++ ./i386/pmap.c Mon Dec 1 22:57:54 2003 @@ -1,3 +1,4 @@ +/* $Yahoo: //depot/yahoo/ybsd_4/src/sys/i386/i386/pmap.c#13 $ */ /* * Copyright (c) 1991 Regents of the University of California. * All rights reserved. @@ -144,6 +145,8 @@ #endif /* SMP || APIC_IO */ #define PMAP_KEEP_PDIRS + +/* can be overridden by the boot variable vm.pmap.shpgperproc */ #ifndef PMAP_SHPGPERPROC #define PMAP_SHPGPERPROC 200 #endif @@ -566,6 +569,7 @@ int shpgperproc = PMAP_SHPGPERPROC; TUNABLE_INT_FETCH("vm.pmap.shpgperproc", &shpgperproc); + TUNABLE_INT_FETCH("kern.vm.pmap.shpgperproc", &shpgperproc); pv_entry_max = shpgperproc * maxproc + vm_page_array_size; TUNABLE_INT_FETCH("vm.pmap.pv_entries", &pv_entry_max); pv_entry_high_water = 9 * (pv_entry_max / 10); @@ -1368,7 +1372,7 @@ { unsigned long ksize = VM_MAX_KERNEL_ADDRESS - KERNBASE; - return sysctl_handle_long(oidp, &ksize, 0, req); + return sysctl_handle_long(oidp, &ksize, 0, req); } SYSCTL_PROC(_vm, OID_AUTO, kvm_size, CTLTYPE_LONG|CTLFLAG_RD, 0, 0, kvm_size, "IU", "Size of KVM"); @@ -1378,11 +1382,21 @@ { unsigned long kfree = VM_MAX_KERNEL_ADDRESS - kernel_vm_end; - return sysctl_handle_long(oidp, &kfree, 0, req); + return sysctl_handle_long(oidp, &kfree, 0, req); } SYSCTL_PROC(_vm, OID_AUTO, kvm_free, CTLTYPE_LONG|CTLFLAG_RD, 0, 0, kvm_free, "IU", "Amount of KVM free"); +static int +kvm_used(SYSCTL_HANDLER_ARGS) +{ + unsigned long kused = kernel_vm_end - KERNBASE; + + return sysctl_handle_long(oidp, &kused, 0, req); +} +SYSCTL_PROC(_vm, OID_AUTO, kvm_used, CTLTYPE_LONG|CTLFLAG_RD, + 0, 0, kvm_used, "IU", "Amount of KVM used"); + /* * grow the number of kernel page table entries, if needed */ @@ -1489,7 +1503,7 @@ return; if (warningdone < 5) { - printf("pmap_collect: collecting pv entries -- suggest increasing PMAP_SHPGPERPROC\n"); + printf("pmap_collect: collecting pv entries -- suggest increasing vm.pmap.shpgperproc\n"); warningdone++; } diff -ru /home/peter/releng_4/src/sys/i386/i386/trap.c ./i386/trap.c --- /home/peter/releng_4/src/sys/i386/i386/trap.c Fri Mar 7 17:30:33 2003 +++ ./i386/trap.c Fri Aug 29 15:27:44 2003 @@ -1,3 +1,4 @@ +/* $Yahoo: //depot/yahoo/ybsd_4/src/sys/i386/i386/trap.c#15 $ */ /*- * Copyright (C) 1994, David Greenman * Copyright (c) 1990, 1993 @@ -46,7 +47,6 @@ #include "opt_ddb.h" #include "opt_ktrace.h" #include "opt_clock.h" -#include "opt_trap.h" #include #include @@ -84,11 +84,6 @@ #include -#ifdef POWERFAIL_NMI -#include -#include -#endif - #include #include @@ -148,14 +143,13 @@ extern int has_f00f_bug; #endif -#ifdef DDB -static int ddb_on_nmi = 1; -SYSCTL_INT(_machdep, OID_AUTO, ddb_on_nmi, CTLFLAG_RW, - &ddb_on_nmi, 0, "Go to DDB on NMI"); -#endif -static int panic_on_nmi = 1; -SYSCTL_INT(_machdep, OID_AUTO, panic_on_nmi, CTLFLAG_RW, - &panic_on_nmi, 0, "Panic on NMI"); +static int nnmi = 0; +SYSCTL_INT(_machdep, OID_AUTO, nnmi, CTLFLAG_RD, + &nnmi, 0, "Number of NMI's"); +static int nmi_killproc = 0; +SYSCTL_INT(_machdep, OID_AUTO, nmi_killproc, CTLFLAG_RD, + &nmi_killproc, 0, "give process SIGBUS on userland ECC error"); +TUNABLE_INT("machdep.nmi_killproc", &nmi_killproc); static __inline int userret(p, frame, oticks, have_mplock) @@ -188,11 +182,19 @@ get_mplock(); have_mplock = 1; } +#ifdef KTRACE + if (KTRPOINT(p, KTR_CSW)) + ktrcsw(p->p_tracep, 1, 1); +#endif s = splhigh(); setrunqueue(p); p->p_stats->p_ru.ru_nivcsw++; mi_switch(); splx(s); +#ifdef KTRACE + if (KTRPOINT(p, KTR_CSW)) + ktrcsw(p->p_tracep, 0, 1); +#endif while ((sig = CURSIG(p)) != 0) postsig(sig); } @@ -392,29 +394,22 @@ i = SIGFPE; break; -#if NISA > 0 case T_NMI: -#ifdef POWERFAIL_NMI - goto handle_powerfail; -#else /* !POWERFAIL_NMI */ + ++nnmi; +#if NISA > 0 /* machine/parity/power fail/"kitchen sink" faults */ - if (isa_nmi(code) == 0) { -#ifdef DDB - /* - * NMI can be hooked up to a pushbutton - * for debugging. - */ - if (ddb_on_nmi) { - printf ("NMI ... going to debugger\n"); - kdb_trap (type, 0, &frame); - } -#endif /* DDB */ - return; - } else if (panic_on_nmi) - panic("NMI indicates hardware failure"); - break; -#endif /* POWERFAIL_NMI */ + if (isa_nmi(code, 1) == 0) + goto out; /* harmless */ #endif /* NISA > 0 */ + if (nmi_killproc) { + printf("ECC: PID %d got an NMI!\n", p->p_pid); + ucode = type; /* T_NMI */ + i = SIGBUS; + break; + } else { + printf("ECC: PID %d should have been killed!\n", p->p_pid); + goto out; /* ignore */ + } case T_OFLOW: /* integer overflow fault */ ucode = FPE_INTOVF; @@ -594,42 +589,12 @@ #endif break; -#if NISA > 0 case T_NMI: -#ifdef POWERFAIL_NMI -#ifndef TIMER_FREQ -# define TIMER_FREQ 1193182 -#endif - handle_powerfail: - { - static unsigned lastalert = 0; - - if(time_second - lastalert > 10) - { - log(LOG_WARNING, "NMI: power fail\n"); - sysbeep(TIMER_FREQ/880, hz); - lastalert = time_second; - } - return; - } -#else /* !POWERFAIL_NMI */ + ++nnmi; +#if NISA > 0 /* machine/parity/power fail/"kitchen sink" faults */ - if (isa_nmi(code) == 0) { -#ifdef DDB - /* - * NMI can be hooked up to a pushbutton - * for debugging. - */ - if (ddb_on_nmi) { - printf ("NMI ... going to debugger\n"); - kdb_trap (type, 0, &frame); - } -#endif /* DDB */ - return; - } else if (panic_on_nmi == 0) - return; - /* FALL THROUGH */ -#endif /* POWERFAIL_NMI */ + isa_nmi(code, 0); + return; #endif /* NISA > 0 */ } diff -ru /home/peter/releng_4/src/sys/i386/include/elf.h ./include/elf.h --- /home/peter/releng_4/src/sys/i386/include/elf.h Tue Nov 27 19:47:04 2001 +++ ./include/elf.h Mon Sep 29 13:44:47 2003 @@ -118,16 +118,4 @@ #define ELF_TARG_MACH EM_386 #define ELF_TARG_VER 1 -#ifdef _KERNEL - -/* - * On the i386 we load the dynamic linker where a userland call - * to mmap(0, ...) would put it. The rationale behind this - * calculation is that it leaves room for the heap to grow to - * its maximum allowed size. - */ -#define ELF_RTLD_ADDR(vmspace) \ - (round_page((vm_offset_t)(vmspace)->vm_daddr + maxdsiz)) - -#endif /* _KERNEL */ #endif /* !_MACHINE_ELF_H_ */ Only in /home/peter/releng_4/src/sys/i386/include/pc: CVS diff -ru /home/peter/releng_4/src/sys/i386/include/pmap.h ./include/pmap.h --- /home/peter/releng_4/src/sys/i386/include/pmap.h Thu Mar 25 13:35:14 2004 +++ ./include/pmap.h Thu Dec 4 18:01:32 2003 @@ -1,3 +1,4 @@ +/* $Yahoo: //depot/yahoo/ybsd_4/src/sys/i386/include/pmap.h#4 $ */ /* * Copyright (c) 1991 Regents of the University of California. * All rights reserved. @@ -88,7 +89,7 @@ * This **MUST** be a multiple of 4 (eg: 252, 256, 260, etc). */ #ifndef KVA_PAGES -#define KVA_PAGES (1 << (30 - PDRSHIFT)) +#define KVA_PAGES 384 #endif /* diff -ru /home/peter/releng_4/src/sys/i386/include/smptests.h ./include/smptests.h --- /home/peter/releng_4/src/sys/i386/include/smptests.h Mon May 15 23:58:10 2000 +++ ./include/smptests.h Fri Jan 24 15:23:39 2003 @@ -1,3 +1,4 @@ +/* $Yahoo: //depot/yahoo/ybsd_4/src/sys/i386/include/smptests.h#4 $ */ /* * Copyright (c) 1996, by Steve Passe * All rights reserved. diff -ru /home/peter/releng_4/src/sys/i386/isa/intr_machdep.c ./isa/intr_machdep.c --- /home/peter/releng_4/src/sys/i386/isa/intr_machdep.c Thu Mar 25 13:35:15 2004 +++ ./isa/intr_machdep.c Thu Dec 4 18:01:32 2003 @@ -1,3 +1,4 @@ +/* $Yahoo: //depot/yahoo/ybsd_4/src/sys/i386/isa/intr_machdep.c#10 $ */ /*- * Copyright (c) 1991 The Regents of the University of California. * All rights reserved. @@ -44,6 +45,7 @@ */ #include "opt_auto_eoi.h" +#include "opt_ddb.h" #include "isa.h" @@ -52,6 +54,7 @@ #include #endif #include +#include #include #include #include @@ -60,6 +63,8 @@ #include #include #include +#include +#include #if defined(APIC_IO) #include @@ -144,27 +149,43 @@ static inthand2_t isa_strayintr; static void init_i8259(void); -#ifdef PC98 -#define NMI_PARITY 0x04 -#define NMI_EPARITY 0x02 -#else -#define NMI_PARITY (1 << 7) -#define NMI_IOCHAN (1 << 6) -#define ENMI_WATCHDOG (1 << 7) -#define ENMI_BUSTIMER (1 << 6) -#define ENMI_IOSTATUS (1 << 5) +#ifdef DDB +static int ddb_on_nmi = 0; +SYSCTL_INT(_machdep, OID_AUTO, ddb_on_nmi, CTLFLAG_RW, + &ddb_on_nmi, 0, "Go to DDB on NMI"); +TUNABLE_INT("machdep.ddb_on_nmi", &ddb_on_nmi); #endif +static int panic_on_nmi = 1; +SYSCTL_INT(_machdep, OID_AUTO, panic_on_nmi, CTLFLAG_RW, + &panic_on_nmi, 0, "Panic on NMI"); +TUNABLE_INT("machdep.panic_on_nmi", &panic_on_nmi); + +static int nmi_rearm = 1; +SYSCTL_INT(_machdep, OID_AUTO, nmi_rearm, CTLFLAG_RW, + &nmi_rearm, 0, "Rearm after NMI"); +TUNABLE_INT("machdep.nmi_rearm", &nmi_rearm); + +/* + * The NMI handlers set this to 1 if they accept responsibility + * and have cleared the source. + */ +int nmi_handled; /* * Handle a NMI, possibly a machine check. * return true to panic system, false to ignore. */ +#ifdef PC98 + +#define NMI_PARITY 0x04 +#define NMI_EPARITY 0x02 + int -isa_nmi(cd) +isa_nmi(cd, user) int cd; + int user; { int retval = 0; -#ifdef PC98 int port = inb(0x33); log(LOG_CRIT, "NMI PC98 port = %x\n", port); @@ -179,51 +200,125 @@ } else { log(LOG_CRIT, "\nNMI Resume ??\n"); } + return(retval); +} #else /* IBM-PC */ + +#define NMI_PARITY (1 << 7) +#define NMI_IOCHAN (1 << 6) +#define NMI_IODIS (1 << 3) +#define NMI_PARDIS (1 << 2) +#define ENMI_WATCHDOG (1 << 7) +#define ENMI_BUSTIMER (1 << 6) +#define ENMI_IOSTATUS (1 << 5) + +int +isa_nmi(cd, user) + int cd; + int user; +{ + int retval = 0; int isa_port = inb(0x61); int eisa_port = inb(0x461); + u_int32_t i; + + nmi_handled = 0; + /* + * On a real EISA machine, this will never happen. However it can + * happen on ISA machines which implement XT style floating point + * error handling (very rare). Save them from a meaningless panic. + */ + if (eisa_port == 0xff) + eisa_port = 0; + + log(LOG_CRIT, "NMI ISA %x, EISA %x, SOURCE %s\n", isa_port, eisa_port, + user ? "userland" : "kernel"); - log(LOG_CRIT, "NMI ISA %x, EISA %x\n", isa_port, eisa_port); #if NMCA > 0 if (MCA_system && mca_bus_nmi()) return(0); #endif if (isa_port & NMI_PARITY) { - log(LOG_CRIT, "RAM parity error, likely hardware failure."); + log(LOG_CRIT, "RAM parity error, likely hardware failure.\n"); + EVENTHANDLER_INVOKE(nmievents, 0); retval = 1; + if (nmi_rearm && nmi_handled) { + /* 'ack' the parity error */ + isa_port &= ~NMI_PARITY; + isa_port |= NMI_PARDIS; /* set disable_clear */ + outb(0x61, isa_port); + isa_port &= ~NMI_PARDIS;/* reenable parity NMI */ + outb(0x61, isa_port); + } } if (isa_port & NMI_IOCHAN) { - log(LOG_CRIT, "I/O channel check, likely hardware failure."); - retval = 1; + log(LOG_CRIT, "I/O channel check, likely hardware failure.\n"); +#ifdef DDB + /* + * NMI can be hooked up to a pushbutton + * for debugging. This is often IOCHK# on the isa bus! + */ + if (ddb_on_nmi) { + printf ("NMI ... going to debugger\n"); + Debugger("NMI"); + } else +#endif /* DDB */ + retval = 1; + nmi_handled = 1; /* IOCHK is edge triggered */ + if (nmi_rearm) { + /* 'ack' the IOCHK error */ + isa_port &= ~NMI_IOCHAN; + isa_port |= NMI_IODIS; /* set disable_clear */ + outb(0x61, isa_port); + isa_port &= ~NMI_IODIS; /* reenable parity NMI */ + outb(0x61, isa_port); + } } - /* - * On a real EISA machine, this will never happen. However it can - * happen on ISA machines which implement XT style floating point - * error handling (very rare). Save them from a meaningless panic. - */ - if (eisa_port == 0xff) - return(retval); - if (eisa_port & ENMI_WATCHDOG) { - log(LOG_CRIT, "EISA watchdog timer expired, likely hardware failure."); + log(LOG_CRIT, "EISA watchdog timer expired, likely hardware failure.\n"); retval = 1; } if (eisa_port & ENMI_BUSTIMER) { - log(LOG_CRIT, "EISA bus timeout, likely hardware failure."); + log(LOG_CRIT, "EISA bus timeout, likely hardware failure.\n"); retval = 1; } if (eisa_port & ENMI_IOSTATUS) { - log(LOG_CRIT, "EISA I/O port status error."); + log(LOG_CRIT, "EISA I/O port status error.\n"); retval = 1; } -#endif + + + if (user || retval == 0) { +#ifdef DDB + /* + * NMI can be hooked up to a pushbutton + * for debugging. This is often IOCHK# on the isa bus! + */ + if (ddb_on_nmi) { + printf ("NMI ... going to debugger\n"); + Debugger("NMI"); + } +#endif /* DDB */ + } else if (panic_on_nmi) + panic("NMI indicates hardware failure"); + + if (nmi_rearm && nmi_handled) { + /* Now reset/rearm the global NMI */ + i = inb(0x70); + i |= 0x80; + outb(0x70, i); /* disable globally */ + i &= 0x7f; + outb(0x70, i); /* rearm ! */ + } + return(retval); } +#endif /* * ICU reinitialize when ICU configuration has lost. diff -ru /home/peter/releng_4/src/sys/i386/isa/intr_machdep.h ./isa/intr_machdep.h --- /home/peter/releng_4/src/sys/i386/isa/intr_machdep.h Thu Mar 25 13:35:15 2004 +++ ./isa/intr_machdep.h Thu Dec 4 18:01:32 2003 @@ -1,3 +1,4 @@ +/* $Yahoo: //depot/yahoo/ybsd_4/src/sys/i386/isa/intr_machdep.h#6 $ */ /*- * Copyright (c) 1991 The Regents of the University of California. * All rights reserved. @@ -188,7 +189,7 @@ #endif /* SMP || APIC_IO */ void isa_defaultirq __P((void)); -int isa_nmi __P((int cd)); +int isa_nmi __P((int cd, int user)); int icu_setup __P((int intr, inthand2_t *func, void *arg, u_int *maskptr, int flags)); int icu_unset __P((int intr, inthand2_t *handler)); @@ -208,6 +209,13 @@ void *arg, intrmask_t *maskptr, int flags); int inthand_remove(struct intrec *idesc); + +/* + * NMI handler stuff. Set this to 1 if an event handler accepts + * responsibility for the source of the interrupt and it has been + * cleared/rearmed at the source. If so, we can reactivate NMI. + */ +extern int nmi_handled; #endif /* LOCORE */