diff options
author | asami <asami@FreeBSD.org> | 1996-08-30 10:43:14 +0000 |
---|---|---|
committer | asami <asami@FreeBSD.org> | 1996-08-30 10:43:14 +0000 |
commit | 5819170b8cd956ae523c31a05fbdf86e91450838 (patch) | |
tree | 829d7ec3d9f9abe2259f3b799667243ab94f1c6b /sys/pc98 | |
parent | d564e1831385a2423f7a027b94d614558a09d924 (diff) | |
download | FreeBSD-src-5819170b8cd956ae523c31a05fbdf86e91450838.zip FreeBSD-src-5819170b8cd956ae523c31a05fbdf86e91450838.tar.gz |
Re-sync with the state of PC98 world. This will be the last commit before
we start merging things in earnest...
Submitted by: The FreeBSD(98) Development Team
Diffstat (limited to 'sys/pc98')
-rw-r--r-- | sys/pc98/cbus/clock.c | 69 | ||||
-rw-r--r-- | sys/pc98/cbus/pcrtc.c | 69 | ||||
-rw-r--r-- | sys/pc98/conf/Makefile.pc98 | 6 | ||||
-rw-r--r-- | sys/pc98/i386/autoconf.c | 17 | ||||
-rw-r--r-- | sys/pc98/i386/exception.s | 4 | ||||
-rw-r--r-- | sys/pc98/i386/machdep.c | 169 | ||||
-rw-r--r-- | sys/pc98/i386/microtime.s | 10 | ||||
-rw-r--r-- | sys/pc98/i386/trap.c | 5 | ||||
-rw-r--r-- | sys/pc98/i386/userconfig.c | 7 | ||||
-rw-r--r-- | sys/pc98/pc98/clock.c | 69 | ||||
-rw-r--r-- | sys/pc98/pc98/if_ed.c | 835 | ||||
-rw-r--r-- | sys/pc98/pc98/if_ed98.h | 410 | ||||
-rw-r--r-- | sys/pc98/pc98/if_epreg.h | 8 | ||||
-rw-r--r-- | sys/pc98/pc98/if_fe.c | 31 | ||||
-rw-r--r-- | sys/pc98/pc98/if_zp.c | 7 | ||||
-rw-r--r-- | sys/pc98/pc98/if_zpreg.h | 4 | ||||
-rw-r--r-- | sys/pc98/pc98/machdep.c | 169 | ||||
-rw-r--r-- | sys/pc98/pc98/pc98_machdep.c | 194 | ||||
-rw-r--r-- | sys/pc98/pc98/pc98_machdep.h | 37 | ||||
-rw-r--r-- | sys/pc98/pc98/random_machdep.c | 4 | ||||
-rw-r--r-- | sys/pc98/pc98/spkr.c | 11 | ||||
-rw-r--r-- | sys/pc98/pc98/syscons.c | 5 | ||||
-rw-r--r-- | sys/pc98/pc98/wd.c | 63 |
23 files changed, 974 insertions, 1229 deletions
diff --git a/sys/pc98/cbus/clock.c b/sys/pc98/cbus/clock.c index 071650c..166ba2a 100644 --- a/sys/pc98/cbus/clock.c +++ b/sys/pc98/cbus/clock.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 - * $Id: clock.c,v 1.1.1.1 1996/06/14 10:04:42 asami Exp $ + * $Id: clock.c,v 1.2 1996/07/23 07:46:07 asami Exp $ */ /* @@ -46,7 +46,7 @@ /* * modified for PC98 - * $Id: clock.c,v 1.1.1.1 1996/06/14 10:04:42 asami Exp $ + * $Id: clock.c,v 1.2 1996/07/23 07:46:07 asami Exp $ */ /* @@ -115,9 +115,10 @@ int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */ u_int idelayed; #if defined(I586_CPU) || defined(I686_CPU) -unsigned i586_ctr_freq; -unsigned i586_ctr_rate; -long long i586_ctr_bias; +u_int i586_ctr_bias; +u_int i586_ctr_comultiplier; +u_int i586_ctr_freq; +u_int i586_ctr_multiplier; long long i586_last_tick; unsigned long i586_avg_tick; #endif @@ -175,6 +176,10 @@ static u_char timer2_state; static void (*timer_func) __P((struct clockframe *frame)) = hardclock; int rtc_inb __P((void)); +#if defined(I586_CPU) || defined(I686_CPU) +static void set_i586_ctr_freq(u_int i586_freq, u_int i8254_freq); +#endif + static void clkintr(struct clockframe frame) { @@ -693,11 +698,7 @@ calibrate_clocks(void) * similar to those for the i8254 clock. */ if (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686) { - unsigned long long i586_count; - - i586_count = rdtsc(); - i586_ctr_freq = i586_count; - i586_ctr_rate = (i586_count << I586_CTR_RATE_SHIFT) / 1000000; + set_i586_ctr_freq((u_int)rdtsc(), tot_count); printf("i586 clock: %u Hz, ", i586_ctr_freq); } #endif @@ -794,7 +795,6 @@ startrtclock() freq, timer_freq); #if defined(I586_CPU) || defined(I686_CPU) i586_ctr_freq = 0; - i586_ctr_rate = 0; #endif } #endif @@ -803,27 +803,23 @@ startrtclock() #if defined(I586_CPU) || defined(I686_CPU) #ifndef CLK_USE_I586_CALIBRATION - if (i586_ctr_rate != 0) { + if (i586_ctr_freq != 0) { if (bootverbose) printf( "CLK_USE_I586_CALIBRATION not specified - using old calibration method\n"); i586_ctr_freq = 0; - i586_ctr_rate = 0; } #endif - if (i586_ctr_rate == 0 && + if (i586_ctr_freq == 0 && (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686)) { /* * Calibration of the i586 clock relative to the mc146818A * clock failed. Do a less accurate calibration relative * to the i8254 clock. */ - unsigned long long i586_count; - wrmsr(0x10, 0LL); /* XXX */ DELAY(1000000); - i586_count = rdtsc(); - i586_ctr_rate = (i586_count << I586_CTR_RATE_SHIFT) / 1000000; + set_i586_ctr_freq((u_int)rdtsc(), timer_freq); #ifdef CLK_USE_I586_CALIBRATION printf("i586 clock: %u Hz\n", i586_ctr_freq); #endif @@ -1121,7 +1117,7 @@ cpu_initclocks() /* * Finish setting up anti-jitter measures. */ - if (i586_ctr_rate) { + if (i586_ctr_freq != 0) { i586_last_tick = rdtsc(); i586_ctr_bias = i586_last_tick; } @@ -1144,10 +1140,13 @@ sysctl_machdep_i8254_freq SYSCTL_HANDLER_ARGS */ freq = timer_freq; error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req); - if (error == 0 && freq != timer_freq) { + if (error == 0 && req->newptr != NULL) { if (timer0_state != 0) return (EBUSY); /* too much trouble to handle */ set_timer_freq(freq, hz); +#if defined(I586_CPU) || defined(I686_CPU) + set_i586_ctr_freq(i586_ctr_freq, timer_freq); +#endif } return (error); } @@ -1156,21 +1155,39 @@ SYSCTL_PROC(_machdep, OID_AUTO, i8254_freq, CTLTYPE_INT | CTLFLAG_RW, 0, sizeof(u_int), sysctl_machdep_i8254_freq, "I", ""); #if defined(I586_CPU) || defined(I686_CPU) +static void +set_i586_ctr_freq(u_int i586_freq, u_int i8254_freq) +{ + u_int comultiplier, multiplier; + u_long ef; + + if (i586_freq == 0) { + i586_ctr_freq = i586_freq; + return; + } + comultiplier = ((unsigned long long)i586_freq + << I586_CTR_COMULTIPLIER_SHIFT) / i8254_freq; + multiplier = (1000000LL << I586_CTR_MULTIPLIER_SHIFT) / i586_freq; + ef = read_eflags(); + disable_intr(); + i586_ctr_freq = i586_freq; + i586_ctr_comultiplier = comultiplier; + i586_ctr_multiplier = multiplier; + write_eflags(ef); +} + static int sysctl_machdep_i586_freq SYSCTL_HANDLER_ARGS { int error; u_int freq; - if (i586_ctr_rate == 0) + if (cpu_class != CPUCLASS_586 && cpu_class != CPUCLASS_686) return (EOPNOTSUPP); freq = i586_ctr_freq; error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req); - if (error == 0 && freq != i586_ctr_freq) { - i586_ctr_freq = freq; - i586_ctr_rate = ((unsigned long long)freq << - I586_CTR_RATE_SHIFT) / 1000000; - } + if (error == 0 && req->newptr != NULL) + set_i586_ctr_freq(freq, timer_freq); return (error); } diff --git a/sys/pc98/cbus/pcrtc.c b/sys/pc98/cbus/pcrtc.c index 071650c..166ba2a 100644 --- a/sys/pc98/cbus/pcrtc.c +++ b/sys/pc98/cbus/pcrtc.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 - * $Id: clock.c,v 1.1.1.1 1996/06/14 10:04:42 asami Exp $ + * $Id: clock.c,v 1.2 1996/07/23 07:46:07 asami Exp $ */ /* @@ -46,7 +46,7 @@ /* * modified for PC98 - * $Id: clock.c,v 1.1.1.1 1996/06/14 10:04:42 asami Exp $ + * $Id: clock.c,v 1.2 1996/07/23 07:46:07 asami Exp $ */ /* @@ -115,9 +115,10 @@ int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */ u_int idelayed; #if defined(I586_CPU) || defined(I686_CPU) -unsigned i586_ctr_freq; -unsigned i586_ctr_rate; -long long i586_ctr_bias; +u_int i586_ctr_bias; +u_int i586_ctr_comultiplier; +u_int i586_ctr_freq; +u_int i586_ctr_multiplier; long long i586_last_tick; unsigned long i586_avg_tick; #endif @@ -175,6 +176,10 @@ static u_char timer2_state; static void (*timer_func) __P((struct clockframe *frame)) = hardclock; int rtc_inb __P((void)); +#if defined(I586_CPU) || defined(I686_CPU) +static void set_i586_ctr_freq(u_int i586_freq, u_int i8254_freq); +#endif + static void clkintr(struct clockframe frame) { @@ -693,11 +698,7 @@ calibrate_clocks(void) * similar to those for the i8254 clock. */ if (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686) { - unsigned long long i586_count; - - i586_count = rdtsc(); - i586_ctr_freq = i586_count; - i586_ctr_rate = (i586_count << I586_CTR_RATE_SHIFT) / 1000000; + set_i586_ctr_freq((u_int)rdtsc(), tot_count); printf("i586 clock: %u Hz, ", i586_ctr_freq); } #endif @@ -794,7 +795,6 @@ startrtclock() freq, timer_freq); #if defined(I586_CPU) || defined(I686_CPU) i586_ctr_freq = 0; - i586_ctr_rate = 0; #endif } #endif @@ -803,27 +803,23 @@ startrtclock() #if defined(I586_CPU) || defined(I686_CPU) #ifndef CLK_USE_I586_CALIBRATION - if (i586_ctr_rate != 0) { + if (i586_ctr_freq != 0) { if (bootverbose) printf( "CLK_USE_I586_CALIBRATION not specified - using old calibration method\n"); i586_ctr_freq = 0; - i586_ctr_rate = 0; } #endif - if (i586_ctr_rate == 0 && + if (i586_ctr_freq == 0 && (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686)) { /* * Calibration of the i586 clock relative to the mc146818A * clock failed. Do a less accurate calibration relative * to the i8254 clock. */ - unsigned long long i586_count; - wrmsr(0x10, 0LL); /* XXX */ DELAY(1000000); - i586_count = rdtsc(); - i586_ctr_rate = (i586_count << I586_CTR_RATE_SHIFT) / 1000000; + set_i586_ctr_freq((u_int)rdtsc(), timer_freq); #ifdef CLK_USE_I586_CALIBRATION printf("i586 clock: %u Hz\n", i586_ctr_freq); #endif @@ -1121,7 +1117,7 @@ cpu_initclocks() /* * Finish setting up anti-jitter measures. */ - if (i586_ctr_rate) { + if (i586_ctr_freq != 0) { i586_last_tick = rdtsc(); i586_ctr_bias = i586_last_tick; } @@ -1144,10 +1140,13 @@ sysctl_machdep_i8254_freq SYSCTL_HANDLER_ARGS */ freq = timer_freq; error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req); - if (error == 0 && freq != timer_freq) { + if (error == 0 && req->newptr != NULL) { if (timer0_state != 0) return (EBUSY); /* too much trouble to handle */ set_timer_freq(freq, hz); +#if defined(I586_CPU) || defined(I686_CPU) + set_i586_ctr_freq(i586_ctr_freq, timer_freq); +#endif } return (error); } @@ -1156,21 +1155,39 @@ SYSCTL_PROC(_machdep, OID_AUTO, i8254_freq, CTLTYPE_INT | CTLFLAG_RW, 0, sizeof(u_int), sysctl_machdep_i8254_freq, "I", ""); #if defined(I586_CPU) || defined(I686_CPU) +static void +set_i586_ctr_freq(u_int i586_freq, u_int i8254_freq) +{ + u_int comultiplier, multiplier; + u_long ef; + + if (i586_freq == 0) { + i586_ctr_freq = i586_freq; + return; + } + comultiplier = ((unsigned long long)i586_freq + << I586_CTR_COMULTIPLIER_SHIFT) / i8254_freq; + multiplier = (1000000LL << I586_CTR_MULTIPLIER_SHIFT) / i586_freq; + ef = read_eflags(); + disable_intr(); + i586_ctr_freq = i586_freq; + i586_ctr_comultiplier = comultiplier; + i586_ctr_multiplier = multiplier; + write_eflags(ef); +} + static int sysctl_machdep_i586_freq SYSCTL_HANDLER_ARGS { int error; u_int freq; - if (i586_ctr_rate == 0) + if (cpu_class != CPUCLASS_586 && cpu_class != CPUCLASS_686) return (EOPNOTSUPP); freq = i586_ctr_freq; error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req); - if (error == 0 && freq != i586_ctr_freq) { - i586_ctr_freq = freq; - i586_ctr_rate = ((unsigned long long)freq << - I586_CTR_RATE_SHIFT) / 1000000; - } + if (error == 0 && req->newptr != NULL) + set_i586_ctr_freq(freq, timer_freq); return (error); } diff --git a/sys/pc98/conf/Makefile.pc98 b/sys/pc98/conf/Makefile.pc98 index e092349..9c95812 100644 --- a/sys/pc98/conf/Makefile.pc98 +++ b/sys/pc98/conf/Makefile.pc98 @@ -3,7 +3,7 @@ # Makefile.i386 -- with config changes. # Copyright 1990 W. Jolitz # from: @(#)Makefile.i386 7.1 5/10/91 -# $Id: Makefile.pc98,v 1.1.1.1 1996/06/14 10:04:40 asami Exp $ +# $Id: Makefile.pc98,v 1.2 1996/07/23 07:45:48 asami Exp $ # # Makefile for FreeBSD # @@ -165,8 +165,8 @@ install: fi chflags noschg /kernel mv /kernel /kernel.old - if [ `sysctl -n kern.bootfile` = /kernel ] ; then \ - sysctl -w kern.bootfile=/kernel.old ; \ + if [ `/usr/sbin/sysctl -n kern.bootfile` = /kernel ] ; then \ + /usr/sbin/sysctl -w kern.bootfile=/kernel.old ; \ mv -f /var/db/kvm_kernel.db /var/db/kvm_kernel.old.db ; \ fi install -c -m 555 -o root -g wheel -fschg kernel / diff --git a/sys/pc98/i386/autoconf.c b/sys/pc98/i386/autoconf.c index d5f5d0e..6474650 100644 --- a/sys/pc98/i386/autoconf.c +++ b/sys/pc98/i386/autoconf.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)autoconf.c 7.1 (Berkeley) 5/9/91 - * $Id: autoconf.c,v 1.55 1996/06/08 09:37:35 bde Exp $ + * $Id: autoconf.c,v 1.1.1.1 1996/06/14 10:04:40 asami Exp $ */ /* @@ -210,6 +210,9 @@ configure(dummy) #endif #endif /* !PC98 */ + if (setdumpdev(dumpdev) != 0) + dumpdev = NODEV; + configure_finish(); cninit_finish(); @@ -287,15 +290,11 @@ configure(dummy) setroot(); } #endif + if (!mountroot) { panic("Nobody wants to mount my root for me"); } - /* - * Configure swap area and related system - * parameter based on device(s) used. - */ - if (bootverbose) - printf("Configuring root and swap devs.\n"); + setconf(); cold = 0; if (bootverbose) @@ -311,7 +310,6 @@ setdumpdev(dev) if (dev == NODEV) { dumpdev = dev; - dumplo = 0; return (0); } maj = major(dev); @@ -398,9 +396,8 @@ sysctl_kern_dumpdev SYSCTL_HANDLER_ARGS ndumpdev = dumpdev; error = sysctl_handle_opaque(oidp, &ndumpdev, sizeof ndumpdev, req); - if (!error && ndumpdev != dumpdev) { + if (error == 0 && req->newptr != NULL) error = setdumpdev(ndumpdev); - } return (error); } diff --git a/sys/pc98/i386/exception.s b/sys/pc98/i386/exception.s index b040c88..b2bfa93 100644 --- a/sys/pc98/i386/exception.s +++ b/sys/pc98/i386/exception.s @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: exception.s,v 1.18 1996/05/31 01:08:02 peter Exp $ + * $Id: exception.s,v 1.1.1.1 1996/06/14 10:04:41 asami Exp $ */ #include "npx.h" /* NNPX */ @@ -113,6 +113,8 @@ IDTVEC(prot) TRAP(T_PROTFLT) IDTVEC(page) TRAP(T_PAGEFLT) +IDTVEC(mchk) + pushl $0; TRAP(T_MCHK) IDTVEC(rsvd) pushl $0; TRAP(T_RESERVED) IDTVEC(fpu) diff --git a/sys/pc98/i386/machdep.c b/sys/pc98/i386/machdep.c index 78b2de4..9b439cf 100644 --- a/sys/pc98/i386/machdep.c +++ b/sys/pc98/i386/machdep.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 - * $Id: machdep.c,v 1.1.1.1 1996/06/14 10:04:41 asami Exp $ + * $Id: machdep.c,v 1.2 1996/07/23 07:45:54 asami Exp $ */ #include "npx.h" @@ -135,10 +135,6 @@ static void cpu_startup __P((void *)); SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL) -#ifndef PANIC_REBOOT_WAIT_TIME -#define PANIC_REBOOT_WAIT_TIME 15 /* default to 15 seconds */ -#endif - #ifdef BOUNCE_BUFFERS extern char *bouncememory; extern int maxbkva; @@ -192,7 +188,6 @@ vm_offset_t phys_avail[10]; /* must be 2 less so 0 0 can signal end of chunks */ #define PHYS_AVAIL_ARRAY_END ((sizeof(phys_avail) / sizeof(vm_offset_t)) - 2) -static void dumpsys __P((void)); static void setup_netisrs __P((struct linker_set *)); /* XXX declare elsewhere */ static vm_offset_t buffer_sva, buffer_eva; @@ -690,164 +685,15 @@ sigreturn(p, uap, retval) return(EJUSTRETURN); } -static int waittime = -1; -struct pcb dumppcb; - -__dead void -boot(howto) - int howto; -{ - if (!cold && (howto & RB_NOSYNC) == 0 && waittime < 0) { - register struct buf *bp; - int iter, nbusy; - - waittime = 0; - printf("\nsyncing disks... "); - - sync(&proc0, NULL, NULL); - - for (iter = 0; iter < 20; iter++) { - nbusy = 0; - for (bp = &buf[nbuf]; --bp >= buf; ) { - if ((bp->b_flags & (B_BUSY | B_INVAL)) == B_BUSY) { - nbusy++; - } - } - if (nbusy == 0) - break; - printf("%d ", nbusy); - DELAY(40000 * iter); - } - if (nbusy) { - /* - * Failed to sync all blocks. Indicate this and don't - * unmount filesystems (thus forcing an fsck on reboot). - */ - printf("giving up\n"); -#ifdef SHOW_BUSYBUFS - nbusy = 0; - for (bp = &buf[nbuf]; --bp >= buf; ) { - if ((bp->b_flags & (B_BUSY | B_INVAL)) == B_BUSY) { - nbusy++; - printf("%d: dev:%08x, flags:%08x, blkno:%d, lblkno:%d\n", nbusy, bp->b_dev, bp->b_flags, bp->b_blkno, bp->b_lblkno); - } - } - DELAY(5000000); /* 5 seconds */ -#endif - } else { - printf("done\n"); - /* - * Unmount filesystems - */ - if (panicstr == 0) - vfs_unmountall(); - } - DELAY(100000); /* wait for console output to finish */ - dev_shutdownall(FALSE); - } - splhigh(); - if (howto & RB_HALT) { - printf("\n"); - printf("The operating system has halted.\n"); - printf("Please press any key to reboot.\n\n"); - cngetc(); - } else { - if (howto & RB_DUMP) { - if (!cold) { - savectx(&dumppcb); - dumppcb.pcb_cr3 = rcr3(); - dumpsys(); - } - - if (PANIC_REBOOT_WAIT_TIME != 0) { - if (PANIC_REBOOT_WAIT_TIME != -1) { - int loop; - printf("Automatic reboot in %d seconds - press a key on the console to abort\n", - PANIC_REBOOT_WAIT_TIME); - for (loop = PANIC_REBOOT_WAIT_TIME * 10; loop > 0; --loop) { - DELAY(1000 * 100); /* 1/10th second */ - if (cncheckc()) /* Did user type a key? */ - break; - } - if (!loop) - goto die; - } - } else { /* zero time specified - reboot NOW */ - goto die; - } - printf("--> Press a key on the console to reboot <--\n"); - cngetc(); - } - } -die: - printf("Rebooting...\n"); - DELAY(1000000); /* wait 1 sec for printf's to complete and be read */ - cpu_reset(); - for(;;) ; - /* NOTREACHED */ -} - /* - * Magic number for savecore - * - * exported (symorder) and used at least by savecore(8) + * Machine depdnetnt boot() routine * + * I haven't seen anything too put here yet + * Possibly some stuff might be grafted back here from boot() */ -static u_long const dumpmag = 0x8fca0101UL; - -static int dumpsize = 0; /* also for savecore */ - -static int dodump = 1; -SYSCTL_INT(_machdep, OID_AUTO, do_dump, CTLFLAG_RW, &dodump, 0, ""); - -/* - * Doadump comes here after turning off memory management and - * getting on the dump stack, either when called above, or by - * the auto-restart code. - */ -static void -dumpsys() +void +cpu_boot(int howto) { - - if (!dodump) - return; - if (dumpdev == NODEV) - return; - if ((minor(dumpdev)&07) != 1) - return; - if (!(bdevsw[major(dumpdev)])) - return; - if (!(bdevsw[major(dumpdev)]->d_dump)) - return; - dumpsize = Maxmem; - printf("\ndumping to dev %lx, offset %ld\n", dumpdev, dumplo); - printf("dump "); - switch ((*bdevsw[major(dumpdev)]->d_dump)(dumpdev)) { - - case ENXIO: - printf("device bad\n"); - break; - - case EFAULT: - printf("device not ready\n"); - break; - - case EINVAL: - printf("area improper\n"); - break; - - case EIO: - printf("i/o error\n"); - break; - - case EINTR: - printf("aborted from console\n"); - break; - - default: - printf("succeeded\n"); - break; - } } /* @@ -1109,7 +955,7 @@ extern inthand_t IDTVEC(div), IDTVEC(dbg), IDTVEC(nmi), IDTVEC(bpt), IDTVEC(ofl), IDTVEC(bnd), IDTVEC(ill), IDTVEC(dna), IDTVEC(fpusegm), IDTVEC(tss), IDTVEC(missing), IDTVEC(stk), IDTVEC(prot), - IDTVEC(page), IDTVEC(rsvd), IDTVEC(fpu), IDTVEC(align), + IDTVEC(page), IDTVEC(mchk), IDTVEC(rsvd), IDTVEC(fpu), IDTVEC(align), IDTVEC(syscall), IDTVEC(int0x80_syscall); void @@ -1219,6 +1065,7 @@ init386(first) setidt(15, &IDTVEC(rsvd), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); setidt(16, &IDTVEC(fpu), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); setidt(17, &IDTVEC(align), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(18, &IDTVEC(mchk), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); setidt(0x80, &IDTVEC(int0x80_syscall), SDT_SYS386TGT, SEL_UPL, GSEL(GCODE_SEL, SEL_KPL)); diff --git a/sys/pc98/i386/microtime.s b/sys/pc98/i386/microtime.s index 4731ecf..71d9d2c 100644 --- a/sys/pc98/i386/microtime.s +++ b/sys/pc98/i386/microtime.s @@ -32,7 +32,7 @@ * SUCH DAMAGE. * * from: Steve McCanne's microtime code - * $Id: microtime.s,v 1.1.1.1 1996/06/14 10:04:41 asami Exp $ + * $Id: microtime.s,v 1.2 1996/07/23 07:45:55 asami Exp $ */ #include <machine/asmacros.h> @@ -51,7 +51,7 @@ ENTRY(microtime) #if defined(I586_CPU) || defined(I686_CPU) - movl _i586_ctr_rate, %ecx + movl _i586_ctr_freq, %ecx testl %ecx, %ecx jne pentium_microtime #else @@ -256,9 +256,7 @@ pentium_microtime: cli .byte 0x0f, 0x31 /* RDTSC */ subl _i586_ctr_bias, %eax - sbbl _i586_ctr_bias+4, %edx - shldl $I586_CTR_RATE_SHIFT, %eax, %edx /* magic suggested by */ - shll $I586_CTR_RATE_SHIFT, %eax /* math_emulate.c */ - divl %ecx /* get value in usec */ + mull _i586_ctr_multiplier + movl %edx, %eax jmp common_microtime #endif diff --git a/sys/pc98/i386/trap.c b/sys/pc98/i386/trap.c index 29ecb2b..727a36e 100644 --- a/sys/pc98/i386/trap.c +++ b/sys/pc98/i386/trap.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 - * $Id: trap.c,v 1.1.1.1 1996/06/14 10:04:41 asami Exp $ + * $Id: trap.c,v 1.2 1996/07/23 07:45:59 asami Exp $ */ /* @@ -109,7 +109,7 @@ void dblfault_handler __P((void)); extern inthand_t IDTVEC(syscall); -#define MAX_TRAP_MSG 27 +#define MAX_TRAP_MSG 28 static char *trap_msg[] = { "", /* 0 unused */ "privileged instruction fault", /* 1 T_PRIVINFLT */ @@ -139,6 +139,7 @@ static char *trap_msg[] = { "invalid TSS fault", /* 25 T_TSSFLT */ "segment not present fault", /* 26 T_SEGNPFLT */ "stack fault", /* 27 T_STKFLT */ + "machine check trap", /* 28 T_MCHK */ }; static void userret __P((struct proc *p, struct trapframe *frame, diff --git a/sys/pc98/i386/userconfig.c b/sys/pc98/i386/userconfig.c index 2e9f719..8533de4 100644 --- a/sys/pc98/i386/userconfig.c +++ b/sys/pc98/i386/userconfig.c @@ -46,7 +46,7 @@ ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** - ** $Id: userconfig.c,v 1.42 1996/04/13 18:33:04 bde Exp $ + ** $Id: userconfig.c,v 1.1.1.1 1996/06/14 10:04:41 asami Exp $ **/ /** @@ -1523,7 +1523,7 @@ editval(int x, int y, int width, int hex, int min, int max, int *val, int ro) break; /* nope, drop through */ case 1: /* there was an escape prefix */ - if (c == '[') /* second character in sequence */ + if (c == '[' || c == 'O') /* second character in sequence */ { extended = 2; continue; @@ -1930,6 +1930,7 @@ dolist(int row, int num, int detail, int *ofs, DEV_LIST **list, char *dhelp) break; case '[': /* cheat : always preceeds cursor move */ + case 'O': /* ANSI application key mode */ if (extended==1) extended=2; else @@ -2225,7 +2226,7 @@ visuserconfig(void) * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: userconfig.c,v 1.42 1996/04/13 18:33:04 bde Exp $ + * $Id: userconfig.c,v 1.1.1.1 1996/06/14 10:04:41 asami Exp $ */ #include "scbus.h" diff --git a/sys/pc98/pc98/clock.c b/sys/pc98/pc98/clock.c index 071650c..166ba2a 100644 --- a/sys/pc98/pc98/clock.c +++ b/sys/pc98/pc98/clock.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 - * $Id: clock.c,v 1.1.1.1 1996/06/14 10:04:42 asami Exp $ + * $Id: clock.c,v 1.2 1996/07/23 07:46:07 asami Exp $ */ /* @@ -46,7 +46,7 @@ /* * modified for PC98 - * $Id: clock.c,v 1.1.1.1 1996/06/14 10:04:42 asami Exp $ + * $Id: clock.c,v 1.2 1996/07/23 07:46:07 asami Exp $ */ /* @@ -115,9 +115,10 @@ int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */ u_int idelayed; #if defined(I586_CPU) || defined(I686_CPU) -unsigned i586_ctr_freq; -unsigned i586_ctr_rate; -long long i586_ctr_bias; +u_int i586_ctr_bias; +u_int i586_ctr_comultiplier; +u_int i586_ctr_freq; +u_int i586_ctr_multiplier; long long i586_last_tick; unsigned long i586_avg_tick; #endif @@ -175,6 +176,10 @@ static u_char timer2_state; static void (*timer_func) __P((struct clockframe *frame)) = hardclock; int rtc_inb __P((void)); +#if defined(I586_CPU) || defined(I686_CPU) +static void set_i586_ctr_freq(u_int i586_freq, u_int i8254_freq); +#endif + static void clkintr(struct clockframe frame) { @@ -693,11 +698,7 @@ calibrate_clocks(void) * similar to those for the i8254 clock. */ if (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686) { - unsigned long long i586_count; - - i586_count = rdtsc(); - i586_ctr_freq = i586_count; - i586_ctr_rate = (i586_count << I586_CTR_RATE_SHIFT) / 1000000; + set_i586_ctr_freq((u_int)rdtsc(), tot_count); printf("i586 clock: %u Hz, ", i586_ctr_freq); } #endif @@ -794,7 +795,6 @@ startrtclock() freq, timer_freq); #if defined(I586_CPU) || defined(I686_CPU) i586_ctr_freq = 0; - i586_ctr_rate = 0; #endif } #endif @@ -803,27 +803,23 @@ startrtclock() #if defined(I586_CPU) || defined(I686_CPU) #ifndef CLK_USE_I586_CALIBRATION - if (i586_ctr_rate != 0) { + if (i586_ctr_freq != 0) { if (bootverbose) printf( "CLK_USE_I586_CALIBRATION not specified - using old calibration method\n"); i586_ctr_freq = 0; - i586_ctr_rate = 0; } #endif - if (i586_ctr_rate == 0 && + if (i586_ctr_freq == 0 && (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686)) { /* * Calibration of the i586 clock relative to the mc146818A * clock failed. Do a less accurate calibration relative * to the i8254 clock. */ - unsigned long long i586_count; - wrmsr(0x10, 0LL); /* XXX */ DELAY(1000000); - i586_count = rdtsc(); - i586_ctr_rate = (i586_count << I586_CTR_RATE_SHIFT) / 1000000; + set_i586_ctr_freq((u_int)rdtsc(), timer_freq); #ifdef CLK_USE_I586_CALIBRATION printf("i586 clock: %u Hz\n", i586_ctr_freq); #endif @@ -1121,7 +1117,7 @@ cpu_initclocks() /* * Finish setting up anti-jitter measures. */ - if (i586_ctr_rate) { + if (i586_ctr_freq != 0) { i586_last_tick = rdtsc(); i586_ctr_bias = i586_last_tick; } @@ -1144,10 +1140,13 @@ sysctl_machdep_i8254_freq SYSCTL_HANDLER_ARGS */ freq = timer_freq; error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req); - if (error == 0 && freq != timer_freq) { + if (error == 0 && req->newptr != NULL) { if (timer0_state != 0) return (EBUSY); /* too much trouble to handle */ set_timer_freq(freq, hz); +#if defined(I586_CPU) || defined(I686_CPU) + set_i586_ctr_freq(i586_ctr_freq, timer_freq); +#endif } return (error); } @@ -1156,21 +1155,39 @@ SYSCTL_PROC(_machdep, OID_AUTO, i8254_freq, CTLTYPE_INT | CTLFLAG_RW, 0, sizeof(u_int), sysctl_machdep_i8254_freq, "I", ""); #if defined(I586_CPU) || defined(I686_CPU) +static void +set_i586_ctr_freq(u_int i586_freq, u_int i8254_freq) +{ + u_int comultiplier, multiplier; + u_long ef; + + if (i586_freq == 0) { + i586_ctr_freq = i586_freq; + return; + } + comultiplier = ((unsigned long long)i586_freq + << I586_CTR_COMULTIPLIER_SHIFT) / i8254_freq; + multiplier = (1000000LL << I586_CTR_MULTIPLIER_SHIFT) / i586_freq; + ef = read_eflags(); + disable_intr(); + i586_ctr_freq = i586_freq; + i586_ctr_comultiplier = comultiplier; + i586_ctr_multiplier = multiplier; + write_eflags(ef); +} + static int sysctl_machdep_i586_freq SYSCTL_HANDLER_ARGS { int error; u_int freq; - if (i586_ctr_rate == 0) + if (cpu_class != CPUCLASS_586 && cpu_class != CPUCLASS_686) return (EOPNOTSUPP); freq = i586_ctr_freq; error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req); - if (error == 0 && freq != i586_ctr_freq) { - i586_ctr_freq = freq; - i586_ctr_rate = ((unsigned long long)freq << - I586_CTR_RATE_SHIFT) / 1000000; - } + if (error == 0 && req->newptr != NULL) + set_i586_ctr_freq(freq, timer_freq); return (error); } diff --git a/sys/pc98/pc98/if_ed.c b/sys/pc98/pc98/if_ed.c index adf3c4d..0c7ce40 100644 --- a/sys/pc98/pc98/if_ed.c +++ b/sys/pc98/pc98/if_ed.c @@ -24,7 +24,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: if_ed.c,v 1.1.1.1 1996/06/14 10:04:43 asami Exp $ + * $Id: if_ed.c,v 1.2 1996/07/23 07:46:15 asami Exp $ */ /* @@ -137,6 +137,14 @@ struct ed_softc { int is790; /* set by the probe code if the card is 790 * based */ +/* + * HP PC LAN PLUS card support. + */ + + u_short hpp_options; /* flags controlling behaviour of the HP card */ + u_short hpp_id; /* software revision and other fields */ + caddr_t hpp_mem_start; /* Memory-mapped IO register address */ + caddr_t mem_start; /* NIC memory start address */ caddr_t mem_end; /* NIC memory end address */ u_long mem_size; /* total NIC memory size */ @@ -169,7 +177,7 @@ static int ed_attach_isa __P((struct pc98_device *)); static int ed_attach_isa __P((struct isa_device *)); #endif -static void ed_init __P((struct ifnet *)); +static void ed_init __P((struct ed_softc *)); static int ed_ioctl __P((struct ifnet *, int, caddr_t)); #ifdef PC98 static int ed_probe __P((struct pc98_device *)); @@ -193,6 +201,11 @@ static int ed_probe_3Com __P((struct isa_device *)); static int ed_probe_Novell __P((struct isa_device *)); #endif static int ed_probe_Novell_generic __P((struct ed_softc *, int, int, int)); +#ifdef PC98 +static int ed_probe_HP_pclanp __P((struct pc98_device *)); +#else +static int ed_probe_HP_pclanp __P((struct isa_device *)); +#endif #include "pci.h" #if NPCI > 0 @@ -216,6 +229,11 @@ static void ed_rint __P((struct ed_softc *)); static void ed_xmit __P((struct ed_softc *)); static char * ed_ring_copy __P((struct ed_softc *, char *, char *, /* u_short */ int)); +static void ed_hpp_set_physical_link __P((struct ed_softc *)); +static void ed_hpp_readmem __P((struct ed_softc *, int, unsigned char *, + /* u_short */ int)); +static u_short ed_hpp_write_mbufs __P((struct ed_softc *, struct mbuf *, + int)); static void ed_pio_readmem __P((struct ed_softc *, int, unsigned char *, /* u_short */ int)); @@ -223,8 +241,10 @@ static void ed_pio_writemem __P((struct ed_softc *, char *, /* u_short */ int, /* u_short */ int)); static u_short ed_pio_write_mbufs __P((struct ed_softc *, struct mbuf *, int)); +void edintr_sc __P((struct ed_softc *)); static void ed_setrcr(struct ed_softc *); + static u_long ds_crc(u_char *ep); #if NCRD > 0 @@ -241,8 +261,6 @@ static void edunload(struct pccard_dev *); /* Disable driver */ static void edsuspend(struct pccard_dev *); /* Suspend driver */ static int edinit(struct pccard_dev *, int); /* init device */ -void edintr_sc __P((struct ed_softc *)); - static struct pccard_drv ed_info = { "ed", card_intr, @@ -380,10 +398,28 @@ static unsigned short ed_790_intr_mask[] = { IRQ15 }; -#define ETHER_MIN_LEN 60 -#define ETHER_MAX_LEN 1514 -#define ETHER_ADDR_LEN 6 -#define ETHER_HDR_SIZE 14 +/* + * Interrupt conversion table for the HP PC LAN+ + */ + +static unsigned short ed_hpp_intr_mask[] = { + 0, /* 0 */ + 0, /* 1 */ + 0, /* 2 */ + IRQ3, /* 3 */ + IRQ4, /* 4 */ + IRQ5, /* 5 */ + IRQ6, /* 6 */ + IRQ7, /* 7 */ + 0, /* 8 */ + IRQ9, /* 9 */ + IRQ10, /* 10 */ + IRQ11, /* 11 */ + IRQ12, /* 12 */ + 0, /* 13 */ + 0, /* 14 */ + IRQ15 /* 15 */ +}; static struct kern_devconf kdc_ed_template = { 0, 0, 0, /* filled in by dev_attach */ @@ -583,6 +619,11 @@ ed_probe(isa_dev) if (nports) return (nports); } +#ifdef NCDR > 0 + nports = ed_probe_HP_pclanp(isa_dev); + if (nports) + return (nports); +#endif return (0); } @@ -1627,6 +1668,329 @@ ed_probe_Novell(isa_dev) #if NCRD > 0 +#define ED_HPP_TEST_SIZE 16 + +/* + * Probe and vendor specific initialization for the HP PC Lan+ Cards. + * (HP Part nos: 27247B and 27252A). + * + * The card has an asic wrapper around a DS8390 core. The asic handles + * host accesses and offers both standard register IO and memory mapped + * IO. Memory mapped I/O allows better performance at the expense of greater + * chance of an incompatibility with existing ISA cards. + * + * The card has a few caveats: it isn't tolerant of byte wide accesses, only + * short (16 bit) or word (32 bit) accesses are allowed. Some card revisions + * don't allow 32 bit accesses; these are indicated by a bit in the software + * ID register (see if_edreg.h). + * + * Other caveats are: we should read the MAC address only when the card + * is inactive. + * + * For more information; please consult the CRYNWR packet driver. + * + * The AUI port is turned on using the "link2" option on the ifconfig + * command line. + */ +static int +ed_probe_HP_pclanp(isa_dev) +#ifdef PC98 + struct isa_device *isa_dev; +#else + struct isa_device *isa_dev; +#endif +{ + struct ed_softc *sc = &ed_softc[isa_dev->id_unit]; + int n; /* temp var */ + int memsize; /* mem on board */ + u_char checksum; /* checksum of board address */ + u_char irq; /* board configured IRQ */ + char test_pattern[ED_HPP_TEST_SIZE]; /* read/write areas for */ + char test_buffer[ED_HPP_TEST_SIZE]; /* probing card */ + + + /* Fill in basic information */ + sc->asic_addr = isa_dev->id_iobase + ED_HPP_ASIC_OFFSET; + sc->nic_addr = isa_dev->id_iobase + ED_HPP_NIC_OFFSET; + sc->is790 = 0; + sc->isa16bit = 0; /* the 8390 core needs to be in byte mode */ + + /* + * Look for the HP PCLAN+ signature: "0x50,0x48,0x00,0x53" + */ + + if ((inb(sc->asic_addr + ED_HPP_ID) != 0x50) || + (inb(sc->asic_addr + ED_HPP_ID + 1) != 0x48) || + ((inb(sc->asic_addr + ED_HPP_ID + 2) & 0xF0) != 0) || + (inb(sc->asic_addr + ED_HPP_ID + 3) != 0x53)) + return 0; + + /* + * Read the MAC address and verify checksum on the address. + */ + + outw(sc->asic_addr + ED_HPP_PAGING, ED_HPP_PAGE_MAC); + for (n = 0, checksum = 0; n < ETHER_ADDR_LEN; n++) + checksum += (sc->arpcom.ac_enaddr[n] = + inb(sc->asic_addr + ED_HPP_MAC_ADDR + n)); + + checksum += inb(sc->asic_addr + ED_HPP_MAC_ADDR + ETHER_ADDR_LEN); + + if (checksum != 0xFF) + return 0; + + /* + * Verify that the software model number is 0. + */ + + outw(sc->asic_addr + ED_HPP_PAGING, ED_HPP_PAGE_ID); + if (((sc->hpp_id = inw(sc->asic_addr + ED_HPP_PAGE_4)) & + ED_HPP_ID_SOFT_MODEL_MASK) != 0x0000) + return 0; + + /* + * Read in and save the current options configured on card. + */ + + sc->hpp_options = inw(sc->asic_addr + ED_HPP_OPTION); + + sc->hpp_options |= (ED_HPP_OPTION_NIC_RESET | + ED_HPP_OPTION_CHIP_RESET | + ED_HPP_OPTION_ENABLE_IRQ); + + /* + * Reset the chip. This requires writing to the option register + * so take care to preserve the other bits. + */ + + outw(sc->asic_addr + ED_HPP_OPTION, + (sc->hpp_options & ~(ED_HPP_OPTION_NIC_RESET | + ED_HPP_OPTION_CHIP_RESET))); + + DELAY(5000); /* wait for chip reset to complete */ + + outw(sc->asic_addr + ED_HPP_OPTION, + (sc->hpp_options | (ED_HPP_OPTION_NIC_RESET | + ED_HPP_OPTION_CHIP_RESET | + ED_HPP_OPTION_ENABLE_IRQ))); + + DELAY(5000); + + if (!(inb(sc->nic_addr + ED_P0_ISR) & ED_ISR_RST)) + return 0; /* reset did not complete */ + + /* + * Read out configuration information. + */ + + outw(sc->asic_addr + ED_HPP_PAGING, ED_HPP_PAGE_HW); + + irq = inb(sc->asic_addr + ED_HPP_HW_IRQ); + + /* + * Check for impossible IRQ. + */ + + if (irq >= (sizeof(ed_hpp_intr_mask) / sizeof(ed_hpp_intr_mask[0]))) + return 0; + + /* + * If the kernel IRQ was specified with a '?' use the cards idea + * of the IRQ. If the kernel IRQ was explicitly specified, it + * should match that of the hardware. + */ + + if (isa_dev->id_irq <= 0) + isa_dev->id_irq = ed_hpp_intr_mask[irq]; + else if (isa_dev->id_irq != ed_hpp_intr_mask[irq]) + return 0; + + /* + * Fill in softconfig info. + */ + + sc->vendor = ED_VENDOR_HP; + sc->type = ED_TYPE_HP_PCLANPLUS; + sc->type_str = "HP-PCLAN+"; + sc->kdc.kdc_description = "Ethernet adapter: HP PCLAN+ (27247B/27252A)"; + + sc->mem_shared = 0; /* we DON'T have dual ported RAM */ + sc->mem_start = 0; /* we use offsets inside the card RAM */ + + sc->hpp_mem_start = NULL;/* no memory mapped I/O by default */ + + /* + * Check if memory mapping of the I/O registers possible. + */ + + if (sc->hpp_options & ED_HPP_OPTION_MEM_ENABLE) + { + u_long mem_addr; + + /* + * determine the memory address from the board. + */ + + outw(sc->asic_addr + ED_HPP_PAGING, ED_HPP_PAGE_HW); + mem_addr = (inw(sc->asic_addr + ED_HPP_HW_MEM_MAP) << 8); + + /* + * Check that the kernel specified start of memory and + * hardware's idea of it match. + */ + + if (mem_addr != kvtop(isa_dev->id_maddr)) + return 0; + + sc->hpp_mem_start = isa_dev->id_maddr; + } + + /* + * The board has 32KB of memory. Is there a way to determine + * this programmatically? + */ + + memsize = 32768; + + /* + * Fill in the rest of the soft config structure. + */ + + /* + * The transmit page index. + */ + + sc->tx_page_start = ED_HPP_TX_PAGE_OFFSET; + + if (isa_dev->id_flags & ED_FLAGS_NO_MULTI_BUFFERING) + sc->txb_cnt = 1; + else + sc->txb_cnt = 2; + + /* + * Memory description + */ + + sc->mem_size = memsize; + sc->mem_ring = sc->mem_start + + (sc->txb_cnt * ED_PAGE_SIZE * ED_TXBUF_SIZE); + sc->mem_end = sc->mem_start + sc->mem_size; + + /* + * Receive area starts after the transmit area and + * continues till the end of memory. + */ + + sc->rec_page_start = sc->tx_page_start + + (sc->txb_cnt * ED_TXBUF_SIZE); + sc->rec_page_stop = (sc->mem_size / ED_PAGE_SIZE); + + + sc->cr_proto = 0; /* value works */ + + /* + * Set the wrap registers for string I/O reads. + */ + + outw(sc->asic_addr + ED_HPP_PAGING, ED_HPP_PAGE_HW); + outw(sc->asic_addr + ED_HPP_HW_WRAP, + ((sc->rec_page_start / ED_PAGE_SIZE) | + (((sc->rec_page_stop / ED_PAGE_SIZE) - 1) << 8))); + + /* + * Reset the register page to normal operation. + */ + + outw(sc->asic_addr + ED_HPP_PAGING, ED_HPP_PAGE_PERF); + + /* + * Verify that we can read/write from adapter memory. + * Create test pattern. + */ + + for (n = 0; n < ED_HPP_TEST_SIZE; n++) + { + test_pattern[n] = (n*n) ^ ~n; + } + +#undef ED_HPP_TEST_SIZE + + /* + * Check that the memory is accessible thru the I/O ports. + * Write out the contents of "test_pattern", read back + * into "test_buffer" and compare the two for any + * mismatch. + */ + + for (n = 0; n < (32768 / ED_PAGE_SIZE); n ++) { + + ed_pio_writemem(sc, test_pattern, (n * ED_PAGE_SIZE), + sizeof(test_pattern)); + ed_pio_readmem(sc, (n * ED_PAGE_SIZE), + test_buffer, sizeof(test_pattern)); + + if (bcmp(test_pattern, test_buffer, + sizeof(test_pattern))) + return 0; + } + + return (ED_HPP_IO_PORTS); + +} + +/* + * HP PC Lan+ : Set the physical link to use AUI or TP/TL. + */ + +void +ed_hpp_set_physical_link(struct ed_softc *sc) +{ + struct ifnet *ifp = &sc->arpcom.ac_if; + int lan_page; + + outw(sc->asic_addr + ED_HPP_PAGING, ED_HPP_PAGE_LAN); + lan_page = inw(sc->asic_addr + ED_HPP_PAGE_0); + + if (ifp->if_flags & IFF_ALTPHYS) { + + /* + * Use the AUI port. + */ + + lan_page |= ED_HPP_LAN_AUI; + + outw(sc->asic_addr + ED_HPP_PAGING, ED_HPP_PAGE_LAN); + outw(sc->asic_addr + ED_HPP_PAGE_0, lan_page); + + + } else { + + /* + * Use the ThinLan interface + */ + + lan_page &= ~ED_HPP_LAN_AUI; + + outw(sc->asic_addr + ED_HPP_PAGING, ED_HPP_PAGE_LAN); + outw(sc->asic_addr + ED_HPP_PAGE_0, lan_page); + + } + + /* + * Wait for the lan card to re-initialize itself + */ + + DELAY(150000); /* wait 150 ms */ + + /* + * Restore normal pages. + */ + + outw(sc->asic_addr + ED_HPP_PAGING, ED_HPP_PAGE_PERF); + +} + + /* * Probe and vendor-specific initialization routine for PCCARDs */ @@ -1857,6 +2221,7 @@ ed_attach(sc, unit, flags) ifp->if_start = ed_start; ifp->if_ioctl = ed_ioctl; ifp->if_watchdog = ed_watchdog; + ifp->if_init = (if_init_f_t *)ed_init; ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; /* @@ -1891,10 +2256,16 @@ ed_attach(sc, unit, flags) else printf("type unknown (0x%x) ", sc->type); - printf("%s ", sc->isa16bit ? "(16 bit)" : "(8 bit)"); + if (sc->vendor == ED_VENDOR_HP) + printf("(%s %s IO)", (sc->hpp_id & ED_HPP_ID_16_BIT_ACCESS) ? + "16-bit" : "32-bit", + sc->hpp_mem_start ? "memory mapped" : "regular"); + else + printf("%s ", sc->isa16bit ? "(16 bit)" : "(8 bit)"); - printf("%s\n", ((sc->vendor == ED_VENDOR_3COM) && - (ifp->if_flags & IFF_ALTPHYS)) ? " tranceiver disabled" : ""); + printf("%s\n", (((sc->vendor == ED_VENDOR_3COM) || + (sc->vendor == ED_VENDOR_HP)) && + (ifp->if_flags & IFF_ALTPHYS)) ? " tranceiver disabled" : ""); /* * If BPF is in the kernel, call the attach for it @@ -1959,7 +2330,7 @@ ed_reset(ifp) * Stop interface and re-initialize. */ ed_stop(sc); - ed_init(ifp); + ed_init(sc); (void) splx(s); } @@ -2013,10 +2384,10 @@ ed_watchdog(ifp) * Initialize device. */ static void -ed_init(ifp) - struct ifnet *ifp; +ed_init(sc) + struct ed_softc *sc; { - struct ed_softc *sc = ifp->if_softc; + struct ifnet *ifp = &sc->arpcom.ac_if; int i, s; #ifdef PC98 int unit = sc->unit; @@ -2355,7 +2726,7 @@ outloop: goto outloop; } - sc->txb_len[sc->txb_new] = max(len, ETHER_MIN_LEN); + sc->txb_len[sc->txb_new] = max(len, (ETHER_MIN_LEN-ETHER_CRC_LEN)); sc->txb_inuse++; @@ -2434,8 +2805,8 @@ ed_rint(sc) ed_pio_readmem(sc, (int)packet_ptr, (char *) &packet_hdr, sizeof(packet_hdr)); len = packet_hdr.count; - if (len > (ETHER_MAX_LEN + sizeof(struct ed_ring)) || - len < (ETHER_HDR_SIZE + sizeof(struct ed_ring))) { + if (len > (ETHER_MAX_LEN - ETHER_CRC_LEN + sizeof(struct ed_ring)) || + len < (ETHER_MIN_LEN - ETHER_CRC_LEN + sizeof(struct ed_ring))) { /* * Length is a wild value. There's a good chance that * this was caused by the NIC being old and buggy. @@ -2744,7 +3115,6 @@ ed_ioctl(ifp, command, data) int command; caddr_t data; { - register struct ifaddr *ifa = (struct ifaddr *) data; struct ed_softc *sc = ifp->if_softc; struct ifreq *ifr = (struct ifreq *) data; int s, error = 0; @@ -2758,79 +3128,8 @@ ed_ioctl(ifp, command, data) switch (command) { case SIOCSIFADDR: - ifp->if_flags |= IFF_UP; - /* netifs are BUSY when UP */ - sc->kdc.kdc_state = DC_BUSY; - - switch (ifa->ifa_addr->sa_family) { -#ifdef INET - case AF_INET: - ed_init(ifp); /* before arpwhohas */ - arp_ifinit((struct arpcom *)ifp, ifa); - break; -#endif -#ifdef IPX - /* - * XXX - This code is probably wrong - */ - case AF_IPX: - { - register struct ipx_addr *ina = &(IA_SIPX(ifa)->sipx_addr); - - if (ipx_nullhost(*ina)) - ina->x_host = - *(union ipx_host *) (sc->arpcom.ac_enaddr); - else { - bcopy((caddr_t) ina->x_host.c_host, - (caddr_t) sc->arpcom.ac_enaddr, - sizeof(sc->arpcom.ac_enaddr)); - } - - /* - * Set new address - */ - ed_init(ifp); - break; - } -#endif -#ifdef NS - /* - * XXX - This code is probably wrong - */ - case AF_NS: - { - register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr); - - if (ns_nullhost(*ina)) - ina->x_host = - *(union ns_host *) (sc->arpcom.ac_enaddr); - else { - bcopy((caddr_t) ina->x_host.c_host, - (caddr_t) sc->arpcom.ac_enaddr, - sizeof(sc->arpcom.ac_enaddr)); - } - - /* - * Set new address - */ - ed_init(ifp); - break; - } -#endif - default: - ed_init(ifp); - break; - } - break; - case SIOCGIFADDR: - { - struct sockaddr *sa; - - sa = (struct sockaddr *) & ifr->ifr_data; - bcopy((caddr_t) sc->arpcom.ac_enaddr, - (caddr_t) sa->sa_data, ETHER_ADDR_LEN); - } + ether_ioctl(ifp, command, data); break; case SIOCSIFFLAGS: @@ -2841,7 +3140,7 @@ ed_ioctl(ifp, command, data) */ if (ifp->if_flags & IFF_UP) { if ((ifp->if_flags & IFF_RUNNING) == 0) - ed_init(ifp); + ed_init(ifp->if_softc); } else { if (ifp->if_flags & IFF_RUNNING) { ed_stop(sc); @@ -2873,6 +3172,10 @@ ed_ioctl(ifp, command, data) outb(sc->asic_addr + ED_3COM_CR, ED_3COM_CR_XSEL); } } +#if NCRD > 0 + else if (sc->vendor == ED_VENDOR_HP) + ed_hpp_set_physical_link(sc); +#endif break; case SIOCADDMULTI: @@ -3054,6 +3357,12 @@ ed_pio_readmem(sc, src, dst, amount) int unit = sc->unit; #endif + /* HP cards need special handling */ + if (sc->vendor == ED_VENDOR_HP && sc->type == ED_TYPE_HP_PCLANPLUS) { + ed_hpp_readmem(sc, src, dst, amount); + return; + } + /* select page 0 registers */ outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2 | ED_CR_STA); @@ -3102,43 +3411,94 @@ ed_pio_writemem(sc, src, dst, len) int unit = sc->unit; #endif - /* select page 0 registers */ - outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2 | ED_CR_STA); + if (sc->vendor == ED_VENDOR_NOVELL) { - /* reset remote DMA complete flag */ - outb(sc->nic_addr + ED_P0_ISR, ED_ISR_RDC); + /* select page 0 registers */ + outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2 | ED_CR_STA); - /* set up DMA byte count */ - outb(sc->nic_addr + ED_P0_RBCR0, len); - outb(sc->nic_addr + ED_P0_RBCR1, len >> 8); + /* reset remote DMA complete flag */ + outb(sc->nic_addr + ED_P0_ISR, ED_ISR_RDC); - /* set up destination address in NIC mem */ - outb(sc->nic_addr + ED_P0_RSAR0, dst); - outb(sc->nic_addr + ED_P0_RSAR1, dst >> 8); + /* set up DMA byte count */ + outb(sc->nic_addr + ED_P0_RBCR0, len); + outb(sc->nic_addr + ED_P0_RBCR1, len >> 8); + + /* set up destination address in NIC mem */ + outb(sc->nic_addr + ED_P0_RSAR0, dst); + outb(sc->nic_addr + ED_P0_RSAR1, dst >> 8); + + /* set remote DMA write */ + outb(sc->nic_addr + ED_P0_CR, ED_CR_RD1 | ED_CR_STA); - /* set remote DMA write */ - outb(sc->nic_addr + ED_P0_CR, ED_CR_RD1 | ED_CR_STA); #ifdef PC98 if (sc->type == ED_TYPE98_LPC) LPCT_1d0_ON(); #endif - if (sc->isa16bit) - outsw(sc->asic_addr + ED_NOVELL_DATA, src, len / 2); - else - outsb(sc->asic_addr + ED_NOVELL_DATA, src, len); + + if (sc->isa16bit) + outsw(sc->asic_addr + ED_NOVELL_DATA, src, len / 2); + else + outsb(sc->asic_addr + ED_NOVELL_DATA, src, len); + #ifdef PC98 if (sc->type == ED_TYPE98_LPC) LPCT_1d0_OFF(); #endif - /* - * Wait for remote DMA complete. This is necessary because on the - * transmit side, data is handled internally by the NIC in bursts and - * we can't start another remote DMA until this one completes. Not - * waiting causes really bad things to happen - like the NIC - * irrecoverably jamming the ISA bus. - */ - while (((inb(sc->nic_addr + ED_P0_ISR) & ED_ISR_RDC) != ED_ISR_RDC) && --maxwait); + /* + * Wait for remote DMA complete. This is necessary because on the + * transmit side, data is handled internally by the NIC in bursts and + * we can't start another remote DMA until this one completes. Not + * waiting causes really bad things to happen - like the NIC + * irrecoverably jamming the ISA bus. + */ + while (((inb(sc->nic_addr + ED_P0_ISR) & ED_ISR_RDC) != ED_ISR_RDC) && --maxwait); + + } else if ((sc->vendor == ED_VENDOR_HP) && + (sc->type == ED_TYPE_HP_PCLANPLUS)) { + + /* HP PCLAN+ */ + + /* reset remote DMA complete flag */ + outb(sc->nic_addr + ED_P0_ISR, ED_ISR_RDC); + + /* program the write address in RAM */ + outw(sc->asic_addr + ED_HPP_PAGE_0, dst); + + if (sc->hpp_mem_start) { + u_short *s = (u_short *) src; + volatile u_short *d = (u_short *) sc->hpp_mem_start; + u_short *const fence = s + (len >> 1); + + /* + * Enable memory mapped access. + */ + + outw(sc->asic_addr + ED_HPP_OPTION, + sc->hpp_options & + ~(ED_HPP_OPTION_MEM_DISABLE | + ED_HPP_OPTION_BOOT_ROM_ENB)); + + /* + * Copy to NIC memory. + */ + + while (s < fence) + *d = *s++; + + /* + * Restore Boot ROM access. + */ + + outw(sc->asic_addr + ED_HPP_OPTION, + sc->hpp_options); + + } else { + /* write data using I/O writes */ + outsw(sc->asic_addr + ED_HPP_PAGE_4, src, len / 2); + } + + } } /* @@ -3159,6 +3519,12 @@ ed_pio_write_mbufs(sc, m, dst) int unit = sc->unit; #endif + /* HP PC Lan+ cards need special handling */ + if ((sc->vendor == ED_VENDOR_HP) && + (sc->type == ED_TYPE_HP_PCLANPLUS)) { + return ed_hpp_write_mbufs(sc, m, dst); + } + /* First, count up the total number of bytes to copy */ for (total_len = 0, mp = m; mp; mp = mp->m_next) total_len += mp->m_len; @@ -3290,6 +3656,243 @@ ed_pio_write_mbufs(sc, m, dst) return (total_len); } +/* + * Support routines to handle the HP PC Lan+ card. + */ + +/* + * HP PC Lan+: Read from NIC memory, using either PIO or memory mapped + * IO. + */ + +static void +ed_hpp_readmem(sc, src, dst, amount) + struct ed_softc *sc; + unsigned short src; + unsigned char *dst; + unsigned short amount; +{ + + int use_32bit_access = !(sc->hpp_id & ED_HPP_ID_16_BIT_ACCESS); + + + /* Program the source address in RAM */ + outw(sc->asic_addr + ED_HPP_PAGE_2, src); + + /* + * The HP PC Lan+ card supports word reads as well as + * a memory mapped i/o port that is aliased to every + * even address on the board. + */ + + if (sc->hpp_mem_start) { + + /* Enable memory mapped access. */ + outw(sc->asic_addr + ED_HPP_OPTION, + sc->hpp_options & + ~(ED_HPP_OPTION_MEM_DISABLE | + ED_HPP_OPTION_BOOT_ROM_ENB)); + + if (use_32bit_access && (amount > 3)) { + u_long *dl = (u_long *) dst; + volatile u_long *const sl = + (u_long *) sc->hpp_mem_start; + u_long *const fence = dl + (amount >> 2); + + /* Copy out NIC data. We could probably write this + as a `movsl'. The currently generated code is lousy. + */ + + while (dl < fence) + *dl++ = *sl; + + dst += (amount & ~3); + amount &= 3; + + } + + /* Finish off any words left, as a series of short reads */ + if (amount > 1) { + u_short *d = (u_short *) dst; + volatile u_short *const s = + (u_short *) sc->hpp_mem_start; + u_short *const fence = d + (amount >> 1); + + /* Copy out NIC data. */ + + while (d < fence) + *d++ = *s; + + dst += (amount & ~1); + amount &= 1; + } + + /* + * read in a byte; however we need to always read 16 bits + * at a time or the hardware gets into a funny state + */ + + if (amount == 1) { + /* need to read in a short and copy LSB */ + volatile u_short *const s = + (volatile u_short *) sc->hpp_mem_start; + + *dst = (*s) & 0xFF; + } + + /* Restore Boot ROM access. */ + + outw(sc->asic_addr + ED_HPP_OPTION, + sc->hpp_options); + + + } else { + /* Read in data using the I/O port */ + if (use_32bit_access && (amount > 3)) { + insl(sc->asic_addr + ED_HPP_PAGE_4, dst, amount >> 2); + dst += (amount & ~3); + amount &= 3; + } + if (amount > 1) { + insw(sc->asic_addr + ED_HPP_PAGE_4, dst, amount >> 1); + dst += (amount & ~1); + amount &= 1; + } + if (amount == 1) { /* read in a short and keep the LSB */ + *dst = inw(sc->asic_addr + ED_HPP_PAGE_4) & 0xFF; + } + } +} + +/* + * Write to HP PC Lan+ NIC memory. Access to the NIC can be by using + * outsw() or via the memory mapped interface to the same register. + * Writes have to be in word units; byte accesses won't work and may cause + * the NIC to behave wierdly. Long word accesses are permitted if the ASIC + * allows it. + */ + +static u_short +ed_hpp_write_mbufs(struct ed_softc *sc, struct mbuf *m, int dst) +{ + int len, wantbyte; + unsigned short total_len; + unsigned char savebyte[2]; + volatile u_short * const d = + (volatile u_short *) sc->hpp_mem_start; + int use_32bit_accesses = !(sc->hpp_id & ED_HPP_ID_16_BIT_ACCESS); +#ifdef PC98 + int unit = sc->unit; +#endif + + /* select page 0 registers */ + outb(sc->nic_addr + ED_P0_CR, sc->cr_proto | ED_CR_STA); + + /* reset remote DMA complete flag */ + outb(sc->nic_addr + ED_P0_ISR, ED_ISR_RDC); + + /* program the write address in RAM */ + outw(sc->asic_addr + ED_HPP_PAGE_0, dst); + + if (sc->hpp_mem_start) /* enable memory mapped I/O */ + outw(sc->asic_addr + ED_HPP_OPTION, sc->hpp_options & + ~(ED_HPP_OPTION_MEM_DISABLE | + ED_HPP_OPTION_BOOT_ROM_ENB)); + + wantbyte = 0; + total_len = 0; + + if (sc->hpp_mem_start) { /* Memory mapped I/O port */ + while (m) { + total_len += (len = m->m_len); + if (len) { + caddr_t data = mtod(m, caddr_t); + /* finish the last word of the previous mbuf */ + if (wantbyte) { + savebyte[1] = *data; + *d = *((ushort *) savebyte); + data++; len--; wantbyte = 0; + } + /* output contiguous words */ + if ((len > 3) && (use_32bit_accesses)) { + volatile u_long *const dl = + (volatile u_long *) d; + u_long *sl = (u_long *) data; + u_long *fence = sl + (len >> 2); + + while (sl < fence) + *dl = *sl++; + + data += (len & ~3); + len &= 3; + } + /* finish off remain 16 bit writes */ + if (len > 1) { + u_short *s = (u_short *) data; + u_short *fence = s + (len >> 1); + + while (s < fence) + *d = *s++; + + data += (len & ~1); + len &= 1; + } + /* save last byte if needed */ + if (wantbyte = (len == 1)) + savebyte[0] = *data; + } + m = m->m_next; /* to next mbuf */ + } + if (wantbyte) /* write last byte */ + *d = *((u_short *) savebyte); + } else { + /* use programmed I/O */ + while (m) { + total_len += (len = m->m_len); + if (len) { + caddr_t data = mtod(m, caddr_t); + /* finish the last word of the previous mbuf */ + if (wantbyte) { + savebyte[1] = *data; + outw(sc->asic_addr + ED_HPP_PAGE_4, + *((u_short *)savebyte)); + data++; + len--; + wantbyte = 0; + } + /* output contiguous words */ + if ((len > 3) && use_32bit_accesses) { + outsl(sc->asic_addr + ED_HPP_PAGE_4, + data, len >> 2); + data += (len & ~3); + len &= 3; + } + /* finish off remaining 16 bit accesses */ + if (len > 1) { + outsw(sc->asic_addr + ED_HPP_PAGE_4, + data, len >> 1); + data += (len & ~1); + len &= 1; + } + if (wantbyte = (len == 1)) + savebyte[0] = *data; + + } /* if len != 0 */ + m = m->m_next; + } + if (wantbyte) /* spit last byte */ + outw(sc->asic_addr + ED_HPP_PAGE_4, + *(u_short *)savebyte); + + } + + if (sc->hpp_mem_start) /* turn off memory mapped i/o */ + outw(sc->asic_addr + ED_HPP_OPTION, + sc->hpp_options); + + return (total_len); +} + static void ed_setrcr(sc) struct ed_softc *sc; diff --git a/sys/pc98/pc98/if_ed98.h b/sys/pc98/pc98/if_ed98.h index 2bb4b8b..9826c4c 100644 --- a/sys/pc98/pc98/if_ed98.h +++ b/sys/pc98/pc98/if_ed98.h @@ -248,7 +248,10 @@ static void pc98_set_register __P((struct pc98_device *dev, #undef ED_PC_MISC #endif #define ED_PC_MISC ed_pc_misc[unit] - +#ifdef ED_PC_RESET +#undef ED_PC_RESET +#endif +#define ED_PC_RESET ed_pc_reset[unit] /* LPC-T support */ #define LPCT_1d0_ON() \ @@ -274,6 +277,7 @@ static int ed_novell_asic_offset[NED]; static int ed_novell_data[NED]; static int ed_novell_reset[NED]; static int ed_pc_misc[NED]; +static int ed_pc_reset[NED]; /* NE2000, LGY-98, ICM, LPC-T */ @@ -324,6 +328,7 @@ static void pc98_set_register(struct pc98_device *dev, int unit, int type) ED_NOVELL_DATA = 0x0000; ED_NOVELL_RESET = 0x000f; ED_PC_MISC = 0x18; + ED_PC_RESET = 0x1f; break; case ED_TYPE98_LGY: @@ -334,6 +339,7 @@ static void pc98_set_register(struct pc98_device *dev, int unit, int type) ED_NOVELL_DATA = 0x0000; ED_NOVELL_RESET = 0x0100; ED_PC_MISC = 0x18; + ED_PC_RESET = 0x1f; break; case ED_TYPE98_EGY: @@ -344,6 +350,7 @@ static void pc98_set_register(struct pc98_device *dev, int unit, int type) ED_NOVELL_DATA = 0x0000; ED_NOVELL_RESET = 0x0100; ED_PC_MISC = 0x18; + ED_PC_RESET = 0x1f; break; case ED_TYPE98_ICM: @@ -354,6 +361,7 @@ static void pc98_set_register(struct pc98_device *dev, int unit, int type) ED_NOVELL_DATA = 0x0000; ED_NOVELL_RESET = 0x000f; ED_PC_MISC = 0x18; + ED_PC_RESET = 0x1f; break; case ED_TYPE98_BDN: @@ -364,6 +372,7 @@ static void pc98_set_register(struct pc98_device *dev, int unit, int type) ED_NOVELL_DATA = 0; ED_NOVELL_RESET = 0xc100; ED_PC_MISC = 0x18; + ED_PC_RESET = 0x1f; break; case ED_TYPE98_SIC: @@ -374,6 +383,7 @@ static void pc98_set_register(struct pc98_device *dev, int unit, int type) ED_NOVELL_DATA = 0x00; /* dummy */ ED_NOVELL_RESET = 0x00; ED_PC_MISC = 0x18; + ED_PC_RESET = 0x1f; break; case ED_TYPE98_LPC: @@ -382,8 +392,9 @@ static void pc98_set_register(struct pc98_device *dev, int unit, int type) ED_NOVELL_NIC_OFFSET = 0x0000; ED_NOVELL_ASIC_OFFSET = 0x0100; ED_NOVELL_DATA = 0x0000; - ED_NOVELL_RESET = 0x010f; + ED_NOVELL_RESET = 0x0200; ED_PC_MISC = 0x108; + ED_PC_RESET = 0x10f; break; case ED_TYPE98_108: @@ -395,6 +406,7 @@ static void pc98_set_register(struct pc98_device *dev, int unit, int type) ED_NOVELL_DATA = 0; ED_NOVELL_RESET = 4; ED_PC_MISC = 0x18; + ED_PC_RESET = 0x1f; break; case ED_TYPE98_LA98: @@ -405,399 +417,7 @@ static void pc98_set_register(struct pc98_device *dev, int unit, int type) ED_NOVELL_DATA = 0x0000; ED_NOVELL_RESET = 0xf000; ED_PC_MISC = 0x18; - break; - } -} - -#endif /* __PC98_PC98_IF_ED98_H__ */ -/* - * Copyright (c) KATO Takenori, 1996. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer as - * the first lines of this file unmodified. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * PC-9801 specific definitions for National Semiconductor DP8390 NIC - */ -#ifndef __PC98_PC98_IF_ED98_H__ -#define __PC98_PC98_IF_ED98_H__ - -/* PC98 only */ -#ifndef PC98 -#error Why you include if_ed98.h? -#endif - -static void pc98_set_register __P((struct pc98_device *dev, - int unit, int type)); - -/* - * Vendor types - */ -#define ED_VENDOR_MISC 0xf0 /* others */ - -/* - * Register offsets/total - */ -#ifdef ED_NOVELL_NIC_OFFSET -#undef ED_NOVELL_NIC_OFFSET -#endif -#define ED_NOVELL_NIC_OFFSET ed_novell_nic_offset[unit] -#ifdef ED_NOVELL_ASIC_OFFSET -#undef ED_NOVELL_ASIC_OFFSET -#endif -#define ED_NOVELL_ASIC_OFFSET ed_novell_asic_offset[unit] - -/* - * Remote DMA data register; for reading or writing to the NIC mem - * via programmed I/O (offset from ASIC base) - */ -#ifdef ED_NOVELL_DATA -#undef ED_NOVELL_DATA -#endif -#define ED_NOVELL_DATA ed_novell_data[unit] - -/* - * Reset register; reading from this register causes a board reset - */ -#ifdef ED_NOVELL_RESET -#undef ED_NOVELL_RESET -#endif -#define ED_NOVELL_RESET ed_novell_reset[unit] - -/* - * Card type - * - * Type Card - * 0 Allied Telesis CenterCom LA-98-T - * 1 MELCO LPC-TJ, LPC-TS / IO-DATA PCLA/T - * 2 PLANET SMART COM 98 EN-2298 / ELECOM LANEED LD-BDN[123]A - * 3 MELCO EGY-98 - * 4 MELCO LGY-98, IND-SP, IND-SS / MACNICA NE2098(XXX) - * 5 ICM DT-ET-25, DT-ET-T5, IF-2766ET, IF-2771ET / - * D-Link DE-298P{T,CAT}, DE-298{T,TP,CAT} - * 6 Allied Telesis SIC-98 - * 8 NEC PC-9801-108 - * 9 IO-DATA LA-98 - */ -#define ED_TYPE98_BASE 0x10 - -#define ED_TYPE98_GENERIC 0x10 -#define ED_TYPE98_LPC 0x11 -#define ED_TYPE98_BDN 0x12 -#define ED_TYPE98_EGY 0x13 -#define ED_TYPE98_LGY 0x14 -#define ED_TYPE98_ICM 0x15 -#define ED_TYPE98_SIC 0x16 -#define ED_TYPE98_108 0x18 -#define ED_TYPE98_LA98 0x19 - -#define ED_TYPE98(x) (((x->id_flags & 0xffff0000) >> 16) | ED_TYPE98_BASE) - -/* - * Page 0 register offsets - */ -#undef ED_P0_CR -#define ED_P0_CR edp[unit][0x00] - -#undef ED_P0_CLDA0 -#define ED_P0_CLDA0 edp[unit][0x01] -#undef ED_P0_PSTART -#define ED_P0_PSTART edp[unit][0x01] - -#undef ED_P0_CLDA1 -#define ED_P0_CLDA1 edp[unit][0x02] -#undef ED_P0_PSTOP -#define ED_P0_PSTOP edp[unit][0x02] - -#undef ED_P0_BNRY -#define ED_P0_BNRY edp[unit][0x03] - -#undef ED_P0_TSR -#define ED_P0_TSR edp[unit][0x04] -#undef ED_P0_TPSR -#define ED_P0_TPSR edp[unit][0x04] - -#undef ED_P0_NCR -#define ED_P0_NCR edp[unit][0x05] -#undef ED_P0_TBCR0 -#define ED_P0_TBCR0 edp[unit][0x05] - -#undef ED_P0_FIFO -#define ED_P0_FIFO edp[unit][0x06] -#undef ED_P0_TBCR1 -#define ED_P0_TBCR1 edp[unit][0x06] - -#undef ED_P0_ISR -#define ED_P0_ISR edp[unit][0x07] - -#undef ED_P0_CRDA0 -#define ED_P0_CRDA0 edp[unit][0x08] -#undef ED_P0_RSAR0 -#define ED_P0_RSAR0 edp[unit][0x08] - -#undef ED_P0_CRDA1 -#define ED_P0_CRDA1 edp[unit][0x09] -#undef ED_P0_RSAR1 -#define ED_P0_RSAR1 edp[unit][0x09] - -#undef ED_P0_RBCR0 -#define ED_P0_RBCR0 edp[unit][0x0a] - -#undef ED_P0_RBCR1 -#define ED_P0_RBCR1 edp[unit][0x0b] - -#undef ED_P0_RSR -#define ED_P0_RSR edp[unit][0x0c] -#undef ED_P0_RCR -#define ED_P0_RCR edp[unit][0x0c] - -#undef ED_P0_CNTR0 -#define ED_P0_CNTR0 edp[unit][0x0d] -#undef ED_P0_TCR -#define ED_P0_TCR edp[unit][0x0d] - -#undef ED_P0_CNTR1 -#define ED_P0_CNTR1 edp[unit][0x0e] -#undef ED_P0_DCR -#define ED_P0_DCR edp[unit][0x0e] - -#undef ED_P0_CNTR2 -#define ED_P0_CNTR2 edp[unit][0x0f] -#undef ED_P0_IMR -#define ED_P0_IMR edp[unit][0x0f] - -/* - * Page 1 register offsets - */ -#undef ED_P1_CR -#define ED_P1_CR edp[unit][0x00] -#undef ED_P1_PAR0 -#define ED_P1_PAR0 edp[unit][0x01] -#undef ED_P1_PAR1 -#define ED_P1_PAR1 edp[unit][0x02] -#undef ED_P1_PAR2 -#define ED_P1_PAR2 edp[unit][0x03] -#undef ED_P1_PAR3 -#define ED_P1_PAR3 edp[unit][0x04] -#undef ED_P1_PAR4 -#define ED_P1_PAR4 edp[unit][0x05] -#undef ED_P1_PAR5 -#define ED_P1_PAR5 edp[unit][0x06] -#undef ED_P1_CURR -#define ED_P1_CURR edp[unit][0x07] -#undef ED_P1_MAR0 -#define ED_P1_MAR0 edp[unit][0x08] -#undef ED_P1_MAR1 -#define ED_P1_MAR1 edp[unit][0x09] -#undef ED_P1_MAR2 -#define ED_P1_MAR2 edp[unit][0x0a] -#undef ED_P1_MAR3 -#define ED_P1_MAR3 edp[unit][0x0b] -#undef ED_P1_MAR4 -#define ED_P1_MAR4 edp[unit][0x0c] -#undef ED_P1_MAR5 -#define ED_P1_MAR5 edp[unit][0x0d] -#undef ED_P1_MAR6 -#define ED_P1_MAR6 edp[unit][0x0e] -#undef ED_P1_MAR7 -#define ED_P1_MAR7 edp[unit][0x0f] - -/* - * Page 2 register offsets - */ -#undef ED_P2_CR -#define ED_P2_CR edp[unit][0x00] -#undef ED_P2_PSTART -#define ED_P2_PSTART edp[unit][0x01] -#undef ED_P2_CLDA0 -#define ED_P2_CLDA0 edp[unit][0x01] -#undef ED_P2_PSTOP -#define ED_P2_PSTOP edp[unit][0x02] -#undef ED_P2_CLDA1 -#define ED_P2_CLDA1 edp[unit][0x02] -#undef ED_P2_RNPP -#define ED_P2_RNPP edp[unit][0x03] -#undef ED_P2_TPSR -#define ED_P2_TPSR edp[unit][0x04] -#undef ED_P2_LNPP -#define ED_P2_LNPP edp[unit][0x05] -#undef ED_P2_ACU -#define ED_P2_ACU edp[unit][0x06] -#undef ED_P2_ACL -#define ED_P2_ACL edp[unit][0x07] -#undef ED_P2_RCR -#define ED_P2_RCR edp[unit][0x0c] -#undef ED_P2_TCR -#define ED_P2_TCR edp[unit][0x0d] -#undef ED_P2_DCR -#define ED_P2_DCR edp[unit][0x0e] -#undef ED_P2_IMR -#define ED_P2_IMR edp[unit][0x0f] - -/* LPC-T support */ -#define LPCT_1d0_ON() \ -{ \ - outb(0x2a8e, 0x84); \ - outw(0x4a8e, 0x1d0); \ - outw(0x5a8e, 0x0310); \ -} - -#define LPCT_1d0_OFF() \ -{ \ - outb(0x2a8e, 0xa4); \ - outw(0x4a8e, 0xd0); \ - outw(0x5a8e, 0x0300); \ -} - -/* register offsets */ -static unsigned int *edp[NED]; -static unsigned int pc98_io_skip[NED]; -static int ed_novell_nic_offset[NED]; -static int ed_novell_asic_offset[NED]; -static int ed_novell_data[NED]; -static int ed_novell_reset[NED]; - -/* NE2000, LGY-98, ICM, LPC-T */ -static unsigned int edp_generic[16] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 -}; - -/* EGY-98 */ -static unsigned int edp_egy98[16] = { - 0, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, - 0x100, 0x102, 0x104, 0x106, 0x108, 0x10a, 0x10c, 0x10e -}; - -/* LD-BDN */ -static unsigned int edp_bdn98[16] = { - 0x00000, 0x01000, 0x02000, 0x03000, 0x04000, 0x05000, 0x06000, 0x07000, - 0x08000, 0x0a000, 0x0b000, 0x0c000, 0x0d000, 0x0d000, 0x0e000, 0x0f000 -}; - -/* SIC-98 */ -static unsigned int edp_sic98[16] = { - 0x0000, 0x0200, 0x0400, 0x0600, 0x0800, 0x0a00, 0x0c00, 0x0e00, - 0x1000, 0x1200, 0x1400, 0x1600, 0x1800, 0x1a00, 0x1c00, 0x1e00 -}; - -/* IO-DATA LA-98 */ -static unsigned int edp_la98[16] = { - 0x0000, 0x1000, 0x2000, 0x3000, 0x4000, 0x5000, 0x6000, 0x7000, - 0x8000, 0x9000, 0xa000, 0xb000, 0xc000, 0xd000, 0xe000, 0xf000 -}; - -/* NEC PC-9801-108 */ -static unsigned int edp_nec108[16] = { - 0x0000, 0x0002, 0x0004, 0x0006, 0x0008, 0x000a, 0x000c, 0x000e, - 0x1000, 0x1002, 0x1004, 0x1006, 0x1008, 0x100a, 0x100c, 0x100e -}; - -static void pc98_set_register(struct pc98_device *dev, int unit, int type) -{ - int adj; - - switch (type) { - case ED_TYPE98_GENERIC: - edp[unit] = edp_generic; - pc98_io_skip[unit] = 1; - ED_NOVELL_NIC_OFFSET = 0x0000; - ED_NOVELL_ASIC_OFFSET = 0x0010; - ED_NOVELL_DATA = 0x0000; - ED_NOVELL_RESET = 0x000f; - break; - - case ED_TYPE98_LGY: - edp[unit] = edp_generic; - pc98_io_skip[unit] = 1; - ED_NOVELL_NIC_OFFSET = 0x0000; - ED_NOVELL_ASIC_OFFSET = 0x0200; - ED_NOVELL_DATA = 0x0000; - ED_NOVELL_RESET = 0x0100; - break; - - case ED_TYPE98_EGY: - edp[unit] = edp_egy98; - pc98_io_skip[unit] = 2; - ED_NOVELL_NIC_OFFSET = 0; - ED_NOVELL_ASIC_OFFSET = 0x0200; - ED_NOVELL_DATA = 0x0000; - ED_NOVELL_RESET = 0x0100; - break; - - case ED_TYPE98_ICM: - edp[unit] = edp_generic; - pc98_io_skip[unit] = 1; - ED_NOVELL_NIC_OFFSET = 0; - ED_NOVELL_ASIC_OFFSET = 0x0100; - ED_NOVELL_DATA = 0x0000; - ED_NOVELL_RESET = 0x000f; - break; - - case ED_TYPE98_BDN: - edp[unit] = edp_bdn98; - pc98_io_skip[unit] = 0x1000; - ED_NOVELL_NIC_OFFSET = 0x0000; - ED_NOVELL_ASIC_OFFSET = 0x0100; - ED_NOVELL_DATA = 0; - ED_NOVELL_RESET = 0xc100; - break; - - case ED_TYPE98_SIC: - edp[unit] = edp_sic98; - pc98_io_skip[unit] = 0x200; - ED_NOVELL_NIC_OFFSET = 0x0000; - ED_NOVELL_ASIC_OFFSET = 0x2000; - ED_NOVELL_DATA = 0x00; /* dummy */ - ED_NOVELL_RESET = 0x00; - break; - - case ED_TYPE98_LPC: - edp[unit] = edp_generic; - pc98_io_skip[unit] = 0x1; - ED_NOVELL_NIC_OFFSET = 0x0000; - ED_NOVELL_ASIC_OFFSET = 0x0100; - ED_NOVELL_DATA = 0x0000; - ED_NOVELL_RESET = 0x0200; - break; - - case ED_TYPE98_108: - edp[unit] = edp_nec108; - pc98_io_skip[unit] = 2; - adj = (dev->id_iobase & 0xf000) / 2; - ED_NOVELL_NIC_OFFSET = 0; - ED_NOVELL_ASIC_OFFSET = (0x888 | adj) - dev->id_iobase; - ED_NOVELL_DATA = 0; - ED_NOVELL_RESET = 4; - break; - - case ED_TYPE98_LA98: - edp[unit] = edp_la98; - pc98_io_skip[unit] = 0x1000; - ED_NOVELL_NIC_OFFSET = 0; - ED_NOVELL_ASIC_OFFSET = 0x100; - ED_NOVELL_DATA = 0x0000; - ED_NOVELL_RESET = 0xf000; + ED_PC_RESET = 0x1f; break; } } diff --git a/sys/pc98/pc98/if_epreg.h b/sys/pc98/pc98/if_epreg.h index 0744644..d27f1b6 100644 --- a/sys/pc98/pc98/if_epreg.h +++ b/sys/pc98/pc98/if_epreg.h @@ -31,7 +31,7 @@ */ /* - * $Id: if_epreg.h,v 1.1.1.1 1996/06/14 10:04:44 asami Exp $ + * $Id: if_epreg.h,v 1.2 1996/07/23 07:46:18 asami Exp $ * * Promiscuous mode added and interrupt logic slightly changed * to reduce the number of adapter failures. Transceiver select @@ -107,10 +107,6 @@ struct ep_board { /* * Some global constants */ -#define ETHER_MIN_LEN 64 -#define ETHER_MAX_LEN 1518 -#define ETHER_ADDR_LEN 6 - #define TX_INIT_RATE 16 #define TX_INIT_MAX_RATE 64 #define RX_INIT_LATENCY 64 @@ -455,8 +451,6 @@ struct ep_board { #define BNC 0x2 #define UTP 0x4 -#define ETHER_ADDR_LEN 6 -#define ETHER_MAX 1536 #define RX_BYTES_MASK (u_short) (0x07ff) extern struct ep_board ep_board[]; diff --git a/sys/pc98/pc98/if_fe.c b/sys/pc98/pc98/if_fe.c index b27b02c..482136f 100644 --- a/sys/pc98/pc98/if_fe.c +++ b/sys/pc98/pc98/if_fe.c @@ -21,7 +21,7 @@ */ /* - * $Id: if_fe.c,v 1.1.1.1 1996/06/14 10:04:44 asami Exp $ + * $Id: if_fe.c,v 1.2 1996/07/23 07:46:19 asami Exp $ * * Device driver for Fujitsu MB86960A/MB86965A based Ethernet cards. * To be used with FreeBSD 2.x @@ -296,14 +296,6 @@ static void fe_loadmar ( struct fe_softc * ); static void fe_dump ( int, struct fe_softc *, char * ); #endif -/* Ethernet constants. To be defined in if_ehter.h? FIXME. */ -#define ETHER_MIN_LEN 60 /* with header, without CRC. */ -#define ETHER_MAX_LEN 1514 /* with header, without CRC. */ -#define ETHER_ADDR_LEN 6 /* number of bytes in an address. */ -#define ETHER_TYPE_LEN 2 /* number of bytes in a data type field. */ -#define ETHER_HDR_SIZE 14 /* src addr, dst addr, and data type. */ -#define ETHER_CRC_LEN 4 /* number of bytes in CRC field. */ - /* Driver struct used in the config code. This must be public (external.) */ #ifdef PC98 struct pc98_driver fedriver = @@ -2118,7 +2110,7 @@ fe_start ( struct ifnet *ifp ) * (i.e., minimum packet sized) packets rapidly. An 8KB * buffer can hold 130 blocks of 62 bytes long... */ - if ( sc->txb_free < ETHER_MAX_LEN + FE_DATA_LEN_LEN ) { + if ( sc->txb_free < ETHER_MAX_LEN - ETHER_CRC_LEN + FE_DATA_LEN_LEN ) { /* No room. */ goto indicate_active; } @@ -2417,12 +2409,12 @@ fe_rint ( struct fe_softc * sc, u_char rstat ) * * Is this statement true? FIXME. */ - if ( len > ETHER_MAX_LEN || len < ETHER_HDR_SIZE ) { + if ( len > ETHER_MAX_LEN - ETHER_CRC_LEN || len < ETHER_MIN_LEN- ETHER_CRC_LEN ) { #if FE_DEBUG >= 2 log( LOG_WARNING, "fe%d: received a %s packet? (%u bytes)\n", sc->sc_unit, - len < ETHER_HDR_SIZE ? "partial" : "big", + len < ETHER_MIN_SIZE- ETHER_CRC_SIZE ? "partial" : "big", len ); #endif sc->sc_if.if_ierrors++; @@ -2437,7 +2429,7 @@ fe_rint ( struct fe_softc * sc, u_char rstat ) * if it carries data for upper layer. */ #if FE_DEBUG >= 2 - if ( len < ETHER_MIN_LEN ) { + if ( len < ETHER_MIN_LEN - ETHER_CRC_LEN) { log( LOG_WARNING, "fe%d: received a short packet? (%u bytes)\n", sc->sc_unit, len ); @@ -2797,7 +2789,7 @@ fe_get_packet ( struct fe_softc * sc, u_short len ) * however. If the following #error message were printed upon * compile, you need to rewrite this function. */ -#if ( MCLBYTES < ETHER_MAX_LEN + NFS_MAGIC_OFFSET ) +#if ( MCLBYTES < ETHER_MAX_LEN - ETHER_CRC_LEN + NFS_MAGIC_OFFSET ) #error "Too small MCLBYTES to use fe driver." #endif @@ -2950,11 +2942,10 @@ fe_write_mbufs ( struct fe_softc *sc, struct mbuf *m ) * it should be a bug of upper layer. We just ignore it. * ... Partial (too short) packets, neither. */ - if ( length > ETHER_MAX_LEN || length < ETHER_HDR_SIZE ) { + if ( ETHER_IS_VALID_LEN(length + ETHER_CRC_LEN)) { log( LOG_ERR, - "fe%d: got a %s packet (%u bytes) to send\n", - sc->sc_unit, - length < ETHER_HDR_SIZE ? "partial" : "big", length ); + "fe%d: got a out-of-spes packet (%u bytes) to send\n", + sc->sc_unit, length ); sc->sc_if.if_oerrors++; return; } @@ -2968,14 +2959,14 @@ fe_write_mbufs ( struct fe_softc *sc, struct mbuf *m ) * packet in the transmission buffer, we can skip the * padding process. It may gain performance slightly. FIXME. */ - outw( addr_bmpr8, max( length, ETHER_MIN_LEN ) ); + outw( addr_bmpr8, max( length, ETHER_MIN_LEN - ETHER_CRC_LEN ) ); /* * Update buffer status now. * Truncate the length up to an even number, since we use outw(). */ length = ( length + 1 ) & ~1; - sc->txb_free -= FE_DATA_LEN_LEN + max( length, ETHER_MIN_LEN ); + sc->txb_free -= FE_DATA_LEN_LEN + max( length, ETHER_MIN_LEN - ETHER_CRC_LEN); sc->txb_count++; /* diff --git a/sys/pc98/pc98/if_zp.c b/sys/pc98/pc98/if_zp.c index ce7c705..4c79f2e 100644 --- a/sys/pc98/pc98/if_zp.c +++ b/sys/pc98/pc98/if_zp.c @@ -34,7 +34,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * From: if_ep.c,v 1.9 1994/01/25 10:46:29 deraadt Exp $ - * $Id: if_zp.c,v 1.1.1.1 1996/06/14 10:04:44 asami Exp $ + * $Id: if_zp.c,v 1.2 1996/07/23 07:46:22 asami Exp $ */ /*- * TODO: @@ -161,11 +161,6 @@ #include <machine/apm_bios.h> #endif /* NAPM > 0 */ -#define ETHER_MIN_LEN 64 -#define ETHER_MAX_LEN 1518 -#define ETHER_ADDR_LEN 6 - - /***************************************************************************** * Driver for Ethernet Adapter * diff --git a/sys/pc98/pc98/if_zpreg.h b/sys/pc98/pc98/if_zpreg.h index 2e214d8..ef0215d 100644 --- a/sys/pc98/pc98/if_zpreg.h +++ b/sys/pc98/pc98/if_zpreg.h @@ -21,7 +21,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: if_zpreg.h,v 1.3 1996/01/30 22:55:55 mpp Exp $ + * $Id: if_zpreg.h,v 1.1.1.1 1996/06/14 10:04:44 asami Exp $ */ /************************************************************************** * * @@ -288,8 +288,6 @@ #define EEPROM_BUSY (1<<15) #define EEPROM_TST_MODE (1<<14) #define READ_EEPROM (1<<7) -#define ETHER_ADDR_LEN 6 -#define ETHER_MAX 1536 #define ENABLE_UTP 0xc0 #define DISABLE_UTP 0x0 #define RX_BYTES_MASK (u_short) (0x07ff) diff --git a/sys/pc98/pc98/machdep.c b/sys/pc98/pc98/machdep.c index 78b2de4..9b439cf 100644 --- a/sys/pc98/pc98/machdep.c +++ b/sys/pc98/pc98/machdep.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 - * $Id: machdep.c,v 1.1.1.1 1996/06/14 10:04:41 asami Exp $ + * $Id: machdep.c,v 1.2 1996/07/23 07:45:54 asami Exp $ */ #include "npx.h" @@ -135,10 +135,6 @@ static void cpu_startup __P((void *)); SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL) -#ifndef PANIC_REBOOT_WAIT_TIME -#define PANIC_REBOOT_WAIT_TIME 15 /* default to 15 seconds */ -#endif - #ifdef BOUNCE_BUFFERS extern char *bouncememory; extern int maxbkva; @@ -192,7 +188,6 @@ vm_offset_t phys_avail[10]; /* must be 2 less so 0 0 can signal end of chunks */ #define PHYS_AVAIL_ARRAY_END ((sizeof(phys_avail) / sizeof(vm_offset_t)) - 2) -static void dumpsys __P((void)); static void setup_netisrs __P((struct linker_set *)); /* XXX declare elsewhere */ static vm_offset_t buffer_sva, buffer_eva; @@ -690,164 +685,15 @@ sigreturn(p, uap, retval) return(EJUSTRETURN); } -static int waittime = -1; -struct pcb dumppcb; - -__dead void -boot(howto) - int howto; -{ - if (!cold && (howto & RB_NOSYNC) == 0 && waittime < 0) { - register struct buf *bp; - int iter, nbusy; - - waittime = 0; - printf("\nsyncing disks... "); - - sync(&proc0, NULL, NULL); - - for (iter = 0; iter < 20; iter++) { - nbusy = 0; - for (bp = &buf[nbuf]; --bp >= buf; ) { - if ((bp->b_flags & (B_BUSY | B_INVAL)) == B_BUSY) { - nbusy++; - } - } - if (nbusy == 0) - break; - printf("%d ", nbusy); - DELAY(40000 * iter); - } - if (nbusy) { - /* - * Failed to sync all blocks. Indicate this and don't - * unmount filesystems (thus forcing an fsck on reboot). - */ - printf("giving up\n"); -#ifdef SHOW_BUSYBUFS - nbusy = 0; - for (bp = &buf[nbuf]; --bp >= buf; ) { - if ((bp->b_flags & (B_BUSY | B_INVAL)) == B_BUSY) { - nbusy++; - printf("%d: dev:%08x, flags:%08x, blkno:%d, lblkno:%d\n", nbusy, bp->b_dev, bp->b_flags, bp->b_blkno, bp->b_lblkno); - } - } - DELAY(5000000); /* 5 seconds */ -#endif - } else { - printf("done\n"); - /* - * Unmount filesystems - */ - if (panicstr == 0) - vfs_unmountall(); - } - DELAY(100000); /* wait for console output to finish */ - dev_shutdownall(FALSE); - } - splhigh(); - if (howto & RB_HALT) { - printf("\n"); - printf("The operating system has halted.\n"); - printf("Please press any key to reboot.\n\n"); - cngetc(); - } else { - if (howto & RB_DUMP) { - if (!cold) { - savectx(&dumppcb); - dumppcb.pcb_cr3 = rcr3(); - dumpsys(); - } - - if (PANIC_REBOOT_WAIT_TIME != 0) { - if (PANIC_REBOOT_WAIT_TIME != -1) { - int loop; - printf("Automatic reboot in %d seconds - press a key on the console to abort\n", - PANIC_REBOOT_WAIT_TIME); - for (loop = PANIC_REBOOT_WAIT_TIME * 10; loop > 0; --loop) { - DELAY(1000 * 100); /* 1/10th second */ - if (cncheckc()) /* Did user type a key? */ - break; - } - if (!loop) - goto die; - } - } else { /* zero time specified - reboot NOW */ - goto die; - } - printf("--> Press a key on the console to reboot <--\n"); - cngetc(); - } - } -die: - printf("Rebooting...\n"); - DELAY(1000000); /* wait 1 sec for printf's to complete and be read */ - cpu_reset(); - for(;;) ; - /* NOTREACHED */ -} - /* - * Magic number for savecore - * - * exported (symorder) and used at least by savecore(8) + * Machine depdnetnt boot() routine * + * I haven't seen anything too put here yet + * Possibly some stuff might be grafted back here from boot() */ -static u_long const dumpmag = 0x8fca0101UL; - -static int dumpsize = 0; /* also for savecore */ - -static int dodump = 1; -SYSCTL_INT(_machdep, OID_AUTO, do_dump, CTLFLAG_RW, &dodump, 0, ""); - -/* - * Doadump comes here after turning off memory management and - * getting on the dump stack, either when called above, or by - * the auto-restart code. - */ -static void -dumpsys() +void +cpu_boot(int howto) { - - if (!dodump) - return; - if (dumpdev == NODEV) - return; - if ((minor(dumpdev)&07) != 1) - return; - if (!(bdevsw[major(dumpdev)])) - return; - if (!(bdevsw[major(dumpdev)]->d_dump)) - return; - dumpsize = Maxmem; - printf("\ndumping to dev %lx, offset %ld\n", dumpdev, dumplo); - printf("dump "); - switch ((*bdevsw[major(dumpdev)]->d_dump)(dumpdev)) { - - case ENXIO: - printf("device bad\n"); - break; - - case EFAULT: - printf("device not ready\n"); - break; - - case EINVAL: - printf("area improper\n"); - break; - - case EIO: - printf("i/o error\n"); - break; - - case EINTR: - printf("aborted from console\n"); - break; - - default: - printf("succeeded\n"); - break; - } } /* @@ -1109,7 +955,7 @@ extern inthand_t IDTVEC(div), IDTVEC(dbg), IDTVEC(nmi), IDTVEC(bpt), IDTVEC(ofl), IDTVEC(bnd), IDTVEC(ill), IDTVEC(dna), IDTVEC(fpusegm), IDTVEC(tss), IDTVEC(missing), IDTVEC(stk), IDTVEC(prot), - IDTVEC(page), IDTVEC(rsvd), IDTVEC(fpu), IDTVEC(align), + IDTVEC(page), IDTVEC(mchk), IDTVEC(rsvd), IDTVEC(fpu), IDTVEC(align), IDTVEC(syscall), IDTVEC(int0x80_syscall); void @@ -1219,6 +1065,7 @@ init386(first) setidt(15, &IDTVEC(rsvd), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); setidt(16, &IDTVEC(fpu), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); setidt(17, &IDTVEC(align), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(18, &IDTVEC(mchk), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); setidt(0x80, &IDTVEC(int0x80_syscall), SDT_SYS386TGT, SEL_UPL, GSEL(GCODE_SEL, SEL_KPL)); diff --git a/sys/pc98/pc98/pc98_machdep.c b/sys/pc98/pc98/pc98_machdep.c index da383ad..8e481a3 100644 --- a/sys/pc98/pc98/pc98_machdep.c +++ b/sys/pc98/pc98/pc98_machdep.c @@ -192,197 +192,3 @@ void init_pc98_dmac(void) outb(0x29, (0x0c | 3)); /* Bank Mode Reg. 16M mode */ outb(0x11, 0x50); /* PC98 must be 0x40 */ } -/* - * Copyright (c) KATO Takenori, 1996. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer as - * the first lines of this file unmodified. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/vmmeter.h> - -#include <vm/vm.h> -#include <vm/vm_param.h> -#include <vm/vm_prot.h> -#include <vm/lock.h> -#include <vm/vm_kern.h> -#include <vm/vm_object.h> -#include <vm/vm_page.h> -#include <vm/vm_map.h> -#include <vm/vm_pager.h> -#include <vm/vm_extern.h> - -#include <pc98/pc98/pc98_device.h> - -extern int Maxmem; -extern int Maxmem_under16M; - -void init_cpu_accel_mem __P((void)); -void init_pc98_dmac __P((void)); - -#ifdef EPSON_MEMWIN -void init_epson_memwin __P((void)); - -void init_epson_memwin(void) -{ - if (pc98_machine_type & M_EPSON_PC98) { - if (Maxmem > 3840) { - if (Maxmem == Maxmem_under16M) { - Maxmem = 3840; - Maxmem_under16M = 3840; - } else if (Maxmem_under16M > 3840) { - Maxmem_under16M = 3840; - } - } - - /* Disable 15MB-16MB caching */ - switch (epson_machine_id) { - case 0x34: /* PC486HX */ - case 0x35: /* PC486HG */ - case 0x3B: /* PC486HA */ - /* Cache control start */ - outb(0x43f, 0x42); - outw(0xc40, 0x0033); - - /* Disable 0xF00000-0xFFFFFF */ - outb(0xc48, 0x49); outb(0xc4c, 0x00); - outb(0xc48, 0x48); outb(0xc4c, 0xf0); - outb(0xc48, 0x4d); outb(0xc4c, 0x00); - outb(0xc48, 0x4c); outb(0xc4c, 0xff); - outb(0xc48, 0x4f); outb(0xc4c, 0x00); - - /* Cache control end */ - outb(0x43f, 0x40); - break; - - case 0x2B: /* PC486GR/GF */ - case 0x30: /* PC486P */ - case 0x31: /* PC486GRSuper */ - case 0x32: /* PC486GR+ */ - case 0x37: /* PC486SE */ - case 0x38: /* PC486SR */ - /* Disable 0xF00000-0xFFFFFF */ - outb(0x43f, 0x42); - outb(0x467, 0xe0); - outb(0x567, 0xd8); - - outb(0x43f, 0x40); - outb(0x467, 0xe0); - outb(0x567, 0xe0); - break; - } - - /* Disable 15MB-16MB RAM and enable memory window */ - outb(0x43b, inb(0x43b) & 0xfd); /* clear bit1 */ - } -} -#endif - -void init_cpu_accel_mem(void) -{ - int target_page; - /* - * Certain 'CPU accelerator' supports over 16MB memory on - * the machines whose BIOS doesn't store true size. - * To support this, we don't trust BIOS values if Maxmem < 4096. - */ - if (Maxmem < 4096) { - for (target_page = ptoa(4096); /* 16MB */ - target_page < ptoa(32768); /* 128MB */ - target_page += 256 * PAGE_SIZE /* 1MB step */) { - int tmp, page_bad = FALSE, OrigMaxmem = Maxmem; - - *(int *)CMAP1 = PG_V | PG_RW | PG_N | target_page; - pmap_update(); - - tmp = *(int *)CADDR1; - /* - * Test for alternating 1's and 0's - */ - *(volatile int *)CADDR1 = 0xaaaaaaaa; - if (*(volatile int *)CADDR1 != 0xaaaaaaaa) { - page_bad = TRUE; - } - /* - * Test for alternating 0's and 1's - */ - *(volatile int *)CADDR1 = 0x55555555; - if (*(volatile int *)CADDR1 != 0x55555555) { - page_bad = TRUE; - } - /* - * Test for all 1's - */ - *(volatile int *)CADDR1 = 0xffffffff; - if (*(volatile int *)CADDR1 != 0xffffffff) { - page_bad = TRUE; - } - /* - * Test for all 0's - */ - *(volatile int *)CADDR1 = 0x0; - if (*(volatile int *)CADDR1 != 0x0) { - /* - * test of page failed - */ - page_bad = TRUE; - } - /* - * Restore original value. - */ - *(int *)CADDR1 = tmp; - if (page_bad == TRUE) { - if (target_page > ptoa(4096)) - Maxmem = atop(target_page); - else - Maxmem = OrigMaxmem; - - break; - } - } - *(int *)CMAP1 = 0; - pmap_update(); - - /* XXX */ - if (Maxmem > 3840) { - Maxmem_under16M = 3840; - if (Maxmem < 4096) { - Maxmem = 3840; - } - } - } -} - -int dma_init_flag = 1; /* dummy */ - -void init_pc98_dmac(void) -{ - outb(0x439, (inb(0x439) & 0xfb)); /* DMA Accsess Control over 1MB */ - outb(0x29, (0x0c | 0)); /* Bank Mode Reg. 16M mode */ - outb(0x29, (0x0c | 1)); /* Bank Mode Reg. 16M mode */ - outb(0x29, (0x0c | 2)); /* Bank Mode Reg. 16M mode */ - outb(0x29, (0x0c | 3)); /* Bank Mode Reg. 16M mode */ - outb(0x11, 0x50); /* PC98 must be 0x40 */ -} diff --git a/sys/pc98/pc98/pc98_machdep.h b/sys/pc98/pc98/pc98_machdep.h index 311113b..6528029 100644 --- a/sys/pc98/pc98/pc98_machdep.h +++ b/sys/pc98/pc98/pc98_machdep.h @@ -35,40 +35,3 @@ void init_cpu_accel_mem __P((void)); void init_pc98_dmac __P((void)); #endif /* __PC98_PC98_PC98_MACHDEP_H__ */ -/* - * Copyright (c) KATO Takenori, 1996. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer as - * the first lines of this file unmodified. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __PC98_PC98_PC98_MACHDEP_H__ -#define __PC98_PC98_PC98_MACHDEP_H__ - -#ifdef EPSON_MEMWIN -void init_epson_memwin __P((void)); -#endif -void init_cpu_accel_mem __P((void)); -void init_pc98_dmac __P((void)); - -#endif /* __PC98_PC98_PC98_MACHDEP_H__ */ diff --git a/sys/pc98/pc98/random_machdep.c b/sys/pc98/pc98/random_machdep.c index c9fce34..c48b1c9 100644 --- a/sys/pc98/pc98/random_machdep.c +++ b/sys/pc98/pc98/random_machdep.c @@ -1,7 +1,7 @@ /* * random_machdep.c -- A strong random number generator * - * $Id: random_machdep.c,v 1.1.1.1 1996/06/14 10:04:45 asami Exp $ + * $Id: random_machdep.c,v 1.2 1996/07/23 07:46:32 asami Exp $ * * Version 0.95, last modified 18-Oct-95 * @@ -194,7 +194,7 @@ add_timer_randomness(struct random_bucket *r, struct timer_rand_state *state, u_int32_t time; #if defined(I586_CPU) || defined(I686_CPU) - if (i586_ctr_rate != 0) { + if (i586_ctr_freq != 0) { num ^= (u_int32_t) rdtsc() << 16; r->entropy_count += 2; } else { diff --git a/sys/pc98/pc98/spkr.c b/sys/pc98/pc98/spkr.c index f931d86..3d78075 100644 --- a/sys/pc98/pc98/spkr.c +++ b/sys/pc98/pc98/spkr.c @@ -4,12 +4,12 @@ * v1.4 by Eric S. Raymond (esr@snark.thyrsus.com) Aug 1993 * modified for FreeBSD by Andrew A. Chernov <ache@astral.msk.su> * - * $Id: spkr.c,v 1.1.1.1 1996/06/14 10:04:46 asami Exp $ + * $Id: spkr.c,v 1.2 1996/07/23 07:46:39 asami Exp $ */ /* * modified for PC98 - * $Id: spkr.c,v 1.1.1.1 1996/06/14 10:04:46 asami Exp $ + * $Id: spkr.c,v 1.2 1996/07/23 07:46:39 asami Exp $ */ #include "speaker.h" @@ -568,7 +568,7 @@ spkrwrite(dev, uio, ioflag) if (minor(dev) != 0) return(ENXIO); - else if (uio->uio_resid > DEV_BSIZE) /* prevent system crashes */ + else if (uio->uio_resid > (DEV_BSIZE - 1)) /* prevent system crashes */ return(E2BIG); else { @@ -578,8 +578,11 @@ spkrwrite(dev, uio, ioflag) n = uio->uio_resid; cp = spkr_inbuf->b_un.b_addr; - if (!(error = uiomove(cp, n, uio))) + error = uiomove(cp, n, uio); + if (!error) { + cp[n] = '\0'; playstring(cp, n); + } return(error); } } diff --git a/sys/pc98/pc98/syscons.c b/sys/pc98/pc98/syscons.c index a22252a..e12f1d0 100644 --- a/sys/pc98/pc98/syscons.c +++ b/sys/pc98/pc98/syscons.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: syscons.c,v 1.1.1.1 1996/06/14 10:04:47 asami Exp $ + * $Id: syscons.c,v 1.2 1996/07/23 07:46:41 asami Exp $ */ #include "sc.h" @@ -168,6 +168,7 @@ struct tty *sccons[MAXCONS+1]; #define VIRTUAL_TTY(x) &sccons[x] #define CONSOLE_TTY &sccons[MAXCONS] static struct tty sccons[MAXCONS+1]; +static int nsccons = MAXCONS; /* for pstat only */ #endif #ifdef PC98 @@ -826,7 +827,7 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) switch (cmd) { /* process console hardware related ioctl's */ case GIO_ATTR: /* get current attributes */ - *(int*)data = scp->term.cur_attr; + *(int*)data = (scp->term.cur_attr >> 8) & 0xFF; return 0; case GIO_COLOR: /* is this a color console ? */ diff --git a/sys/pc98/pc98/wd.c b/sys/pc98/pc98/wd.c index faa81d2..a81b7b8 100644 --- a/sys/pc98/pc98/wd.c +++ b/sys/pc98/pc98/wd.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)wd.c 7.2 (Berkeley) 5/9/91 - * $Id: wd.c,v 1.2 1996/07/23 07:46:44 asami Exp $ + * $Id: wd.c,v 1.3 1996/07/30 18:56:10 asami Exp $ */ /* TODO: @@ -503,8 +503,12 @@ reset_ok: else du->dk_error = inb(du->dk_port + wd_error); /* printf("Error (drv 1) : %x\n", du->dk_error); */ - - if(du->dk_error != 0x01) + /* + * Sometimes (apparently mostly with ATAPI + * drives involved) 0x81 really means 0x81 + * (drive 0 OK, drive 1 failed). + */ + if(du->dk_error != 0x01 && du->dk_error != 0x81) goto nodevice; } else /* drive 0 fail */ goto nodevice; @@ -1603,6 +1607,30 @@ wdcommand(struct disk *du, u_int cylinder, u_int head, u_int sector, return (0); } +static void +wdsetmulti(struct disk *du) +{ + /* + * The config option flags low 8 bits define the maximum multi-block + * transfer size. If the user wants the maximum that the drive + * is capable of, just set the low bits of the config option to + * 0x00ff. + */ + if ((du->cfg_flags & WDOPT_MULTIMASK) != 0 && (du->dk_multi > 1)) { + int configval = du->cfg_flags & WDOPT_MULTIMASK; + du->dk_multi = min(du->dk_multi, configval); + if (wdcommand(du, 0, 0, 0, du->dk_multi, WDCC_SET_MULTI)) { + du->dk_multi = 1; + } else { + if (wdwait(du, WDCS_READY, TIMEOUT) < 0) { + du->dk_multi = 1; + } + } + } else { + du->dk_multi = 1; + } +} + /* * issue IDC to drive to tell it just what geometry it is to be. */ @@ -1653,26 +1681,15 @@ wdsetctlr(struct disk *du) return (1); } - /* - * The config option flags low 8 bits define the maximum multi-block - * transfer size. If the user wants the maximum that the drive - * is capable of, just set the low bits of the config option to - * 0x00ff. - */ - if ((du->cfg_flags & WDOPT_MULTIMASK) != 0 && (du->dk_multi > 1)) { - if (du->dk_multi > (du->cfg_flags & WDOPT_MULTIMASK)) - du->dk_multi = du->cfg_flags & WDOPT_MULTIMASK; - if (wdcommand(du, 0, 0, 0, du->dk_multi, WDCC_SET_MULTI)) { - du->dk_multi = 1; - } - } else { - du->dk_multi = 1; - } + wdsetmulti(du); #ifdef NOTYET /* set read caching and write caching */ wdcommand(du, 0, 0, 0, WDFEA_RCACHE, WDCC_FEATURES); + wdwait(du, WDCS_READY, TIMEOUT); + wdcommand(du, 0, 0, 0, WDFEA_WCACHE, WDCC_FEATURES); + wdwait(du, WDCS_READY, TIMEOUT); #endif return (0); @@ -1748,6 +1765,10 @@ again: else { outb(du->dk_port + wd_sdh, WDSD_IBM | (du->dk_unit << 4)); DELAY(5000); /* usually unnecessary; drive select is fast */ + /* + * Do this twice: may get a false WDCS_READY the first time. + */ + inb(du->dk_port + wd_status); if ((inb(du->dk_port + wd_status) & (WDCS_BUSY | WDCS_READY)) != WDCS_READY || wdcommand(du, 0, 0, 0, 0, WDCC_RESTORE | WD_STEP) != 0 @@ -1869,6 +1890,12 @@ failed: wp->wdp_model[i] = '\0'; } + /* + * find out the drives maximum multi-block transfer capability + */ + du->dk_multi = wp->wdp_nsecperint & 0xff; + wdsetmulti(du); + #ifdef WDDEBUG printf( "\nwd(%d,%d): wdgetctlr: gc %x cyl %d trk %d sec %d type %d sz %d model %s\n", |