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
This commit is contained in:
Satoshi Asami 1996-08-30 10:43:14 +00:00
parent d09e8179fa
commit 91eb961985
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=17947
26 changed files with 1026 additions and 1236 deletions

View file

@ -3,7 +3,7 @@
# Makefile.i386 -- with config changes. # Makefile.i386 -- with config changes.
# Copyright 1990 W. Jolitz # Copyright 1990 W. Jolitz
# from: @(#)Makefile.i386 7.1 5/10/91 # 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 # Makefile for FreeBSD
# #
@ -165,8 +165,8 @@ install:
fi fi
chflags noschg /kernel chflags noschg /kernel
mv /kernel /kernel.old mv /kernel /kernel.old
if [ `sysctl -n kern.bootfile` = /kernel ] ; then \ if [ `/usr/sbin/sysctl -n kern.bootfile` = /kernel ] ; then \
sysctl -w kern.bootfile=/kernel.old ; \ /usr/sbin/sysctl -w kern.bootfile=/kernel.old ; \
mv -f /var/db/kvm_kernel.db /var/db/kvm_kernel.old.db ; \ mv -f /var/db/kvm_kernel.db /var/db/kvm_kernel.old.db ; \
fi fi
install -c -m 555 -o root -g wheel -fschg kernel / install -c -m 555 -o root -g wheel -fschg kernel /

View file

@ -70,7 +70,7 @@
* Paul Mackerras (paulus@cs.anu.edu.au). * Paul Mackerras (paulus@cs.anu.edu.au).
*/ */
/* $Id: ppp_tty.c,v 1.8 1996/06/12 20:07:09 nate Exp $ */ /* $Id: ppp_tty.c,v 1.9 1996/06/14 11:01:49 asami Exp $ */
/* from Id: ppp_tty.c,v 1.3 1995/08/16 01:36:40 paulus Exp */ /* from Id: ppp_tty.c,v 1.3 1995/08/16 01:36:40 paulus Exp */
/* from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp */ /* from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp */
@ -99,7 +99,7 @@
#ifdef i386 /* fiddle with the spl locking */ #ifdef i386 /* fiddle with the spl locking */
# include <machine/spl.h> # include <machine/spl.h>
#ifdef PC98 #ifdef PC98
# include <i386/pc98/pc98_device.h> # include <pc98/pc98/pc98_device.h>
#else #else
# include <i386/isa/isa_device.h> # include <i386/isa/isa_device.h>
#endif #endif

View file

@ -34,7 +34,7 @@
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91 * 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 * 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; u_int idelayed;
#if defined(I586_CPU) || defined(I686_CPU) #if defined(I586_CPU) || defined(I686_CPU)
unsigned i586_ctr_freq; u_int i586_ctr_bias;
unsigned i586_ctr_rate; u_int i586_ctr_comultiplier;
long long i586_ctr_bias; u_int i586_ctr_freq;
u_int i586_ctr_multiplier;
long long i586_last_tick; long long i586_last_tick;
unsigned long i586_avg_tick; unsigned long i586_avg_tick;
#endif #endif
@ -175,6 +176,10 @@ static u_char timer2_state;
static void (*timer_func) __P((struct clockframe *frame)) = hardclock; static void (*timer_func) __P((struct clockframe *frame)) = hardclock;
int rtc_inb __P((void)); 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 static void
clkintr(struct clockframe frame) clkintr(struct clockframe frame)
{ {
@ -693,11 +698,7 @@ calibrate_clocks(void)
* similar to those for the i8254 clock. * similar to those for the i8254 clock.
*/ */
if (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686) { if (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686) {
unsigned long long i586_count; set_i586_ctr_freq((u_int)rdtsc(), tot_count);
i586_count = rdtsc();
i586_ctr_freq = i586_count;
i586_ctr_rate = (i586_count << I586_CTR_RATE_SHIFT) / 1000000;
printf("i586 clock: %u Hz, ", i586_ctr_freq); printf("i586 clock: %u Hz, ", i586_ctr_freq);
} }
#endif #endif
@ -794,7 +795,6 @@ startrtclock()
freq, timer_freq); freq, timer_freq);
#if defined(I586_CPU) || defined(I686_CPU) #if defined(I586_CPU) || defined(I686_CPU)
i586_ctr_freq = 0; i586_ctr_freq = 0;
i586_ctr_rate = 0;
#endif #endif
} }
#endif #endif
@ -803,27 +803,23 @@ startrtclock()
#if defined(I586_CPU) || defined(I686_CPU) #if defined(I586_CPU) || defined(I686_CPU)
#ifndef CLK_USE_I586_CALIBRATION #ifndef CLK_USE_I586_CALIBRATION
if (i586_ctr_rate != 0) { if (i586_ctr_freq != 0) {
if (bootverbose) if (bootverbose)
printf( printf(
"CLK_USE_I586_CALIBRATION not specified - using old calibration method\n"); "CLK_USE_I586_CALIBRATION not specified - using old calibration method\n");
i586_ctr_freq = 0; i586_ctr_freq = 0;
i586_ctr_rate = 0;
} }
#endif #endif
if (i586_ctr_rate == 0 && if (i586_ctr_freq == 0 &&
(cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686)) { (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686)) {
/* /*
* Calibration of the i586 clock relative to the mc146818A * Calibration of the i586 clock relative to the mc146818A
* clock failed. Do a less accurate calibration relative * clock failed. Do a less accurate calibration relative
* to the i8254 clock. * to the i8254 clock.
*/ */
unsigned long long i586_count;
wrmsr(0x10, 0LL); /* XXX */ wrmsr(0x10, 0LL); /* XXX */
DELAY(1000000); DELAY(1000000);
i586_count = rdtsc(); set_i586_ctr_freq((u_int)rdtsc(), timer_freq);
i586_ctr_rate = (i586_count << I586_CTR_RATE_SHIFT) / 1000000;
#ifdef CLK_USE_I586_CALIBRATION #ifdef CLK_USE_I586_CALIBRATION
printf("i586 clock: %u Hz\n", i586_ctr_freq); printf("i586 clock: %u Hz\n", i586_ctr_freq);
#endif #endif
@ -1121,7 +1117,7 @@ cpu_initclocks()
/* /*
* Finish setting up anti-jitter measures. * Finish setting up anti-jitter measures.
*/ */
if (i586_ctr_rate) { if (i586_ctr_freq != 0) {
i586_last_tick = rdtsc(); i586_last_tick = rdtsc();
i586_ctr_bias = i586_last_tick; i586_ctr_bias = i586_last_tick;
} }
@ -1144,10 +1140,13 @@ sysctl_machdep_i8254_freq SYSCTL_HANDLER_ARGS
*/ */
freq = timer_freq; freq = timer_freq;
error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req); 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) if (timer0_state != 0)
return (EBUSY); /* too much trouble to handle */ return (EBUSY); /* too much trouble to handle */
set_timer_freq(freq, hz); set_timer_freq(freq, hz);
#if defined(I586_CPU) || defined(I686_CPU)
set_i586_ctr_freq(i586_ctr_freq, timer_freq);
#endif
} }
return (error); 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", ""); 0, sizeof(u_int), sysctl_machdep_i8254_freq, "I", "");
#if defined(I586_CPU) || defined(I686_CPU) #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 static int
sysctl_machdep_i586_freq SYSCTL_HANDLER_ARGS sysctl_machdep_i586_freq SYSCTL_HANDLER_ARGS
{ {
int error; int error;
u_int freq; u_int freq;
if (i586_ctr_rate == 0) if (cpu_class != CPUCLASS_586 && cpu_class != CPUCLASS_686)
return (EOPNOTSUPP); return (EOPNOTSUPP);
freq = i586_ctr_freq; freq = i586_ctr_freq;
error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req); error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req);
if (error == 0 && freq != i586_ctr_freq) { if (error == 0 && req->newptr != NULL)
i586_ctr_freq = freq; set_i586_ctr_freq(freq, timer_freq);
i586_ctr_rate = ((unsigned long long)freq <<
I586_CTR_RATE_SHIFT) / 1000000;
}
return (error); return (error);
} }

View file

@ -34,7 +34,7 @@
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91 * 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 * 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; u_int idelayed;
#if defined(I586_CPU) || defined(I686_CPU) #if defined(I586_CPU) || defined(I686_CPU)
unsigned i586_ctr_freq; u_int i586_ctr_bias;
unsigned i586_ctr_rate; u_int i586_ctr_comultiplier;
long long i586_ctr_bias; u_int i586_ctr_freq;
u_int i586_ctr_multiplier;
long long i586_last_tick; long long i586_last_tick;
unsigned long i586_avg_tick; unsigned long i586_avg_tick;
#endif #endif
@ -175,6 +176,10 @@ static u_char timer2_state;
static void (*timer_func) __P((struct clockframe *frame)) = hardclock; static void (*timer_func) __P((struct clockframe *frame)) = hardclock;
int rtc_inb __P((void)); 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 static void
clkintr(struct clockframe frame) clkintr(struct clockframe frame)
{ {
@ -693,11 +698,7 @@ calibrate_clocks(void)
* similar to those for the i8254 clock. * similar to those for the i8254 clock.
*/ */
if (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686) { if (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686) {
unsigned long long i586_count; set_i586_ctr_freq((u_int)rdtsc(), tot_count);
i586_count = rdtsc();
i586_ctr_freq = i586_count;
i586_ctr_rate = (i586_count << I586_CTR_RATE_SHIFT) / 1000000;
printf("i586 clock: %u Hz, ", i586_ctr_freq); printf("i586 clock: %u Hz, ", i586_ctr_freq);
} }
#endif #endif
@ -794,7 +795,6 @@ startrtclock()
freq, timer_freq); freq, timer_freq);
#if defined(I586_CPU) || defined(I686_CPU) #if defined(I586_CPU) || defined(I686_CPU)
i586_ctr_freq = 0; i586_ctr_freq = 0;
i586_ctr_rate = 0;
#endif #endif
} }
#endif #endif
@ -803,27 +803,23 @@ startrtclock()
#if defined(I586_CPU) || defined(I686_CPU) #if defined(I586_CPU) || defined(I686_CPU)
#ifndef CLK_USE_I586_CALIBRATION #ifndef CLK_USE_I586_CALIBRATION
if (i586_ctr_rate != 0) { if (i586_ctr_freq != 0) {
if (bootverbose) if (bootverbose)
printf( printf(
"CLK_USE_I586_CALIBRATION not specified - using old calibration method\n"); "CLK_USE_I586_CALIBRATION not specified - using old calibration method\n");
i586_ctr_freq = 0; i586_ctr_freq = 0;
i586_ctr_rate = 0;
} }
#endif #endif
if (i586_ctr_rate == 0 && if (i586_ctr_freq == 0 &&
(cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686)) { (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686)) {
/* /*
* Calibration of the i586 clock relative to the mc146818A * Calibration of the i586 clock relative to the mc146818A
* clock failed. Do a less accurate calibration relative * clock failed. Do a less accurate calibration relative
* to the i8254 clock. * to the i8254 clock.
*/ */
unsigned long long i586_count;
wrmsr(0x10, 0LL); /* XXX */ wrmsr(0x10, 0LL); /* XXX */
DELAY(1000000); DELAY(1000000);
i586_count = rdtsc(); set_i586_ctr_freq((u_int)rdtsc(), timer_freq);
i586_ctr_rate = (i586_count << I586_CTR_RATE_SHIFT) / 1000000;
#ifdef CLK_USE_I586_CALIBRATION #ifdef CLK_USE_I586_CALIBRATION
printf("i586 clock: %u Hz\n", i586_ctr_freq); printf("i586 clock: %u Hz\n", i586_ctr_freq);
#endif #endif
@ -1121,7 +1117,7 @@ cpu_initclocks()
/* /*
* Finish setting up anti-jitter measures. * Finish setting up anti-jitter measures.
*/ */
if (i586_ctr_rate) { if (i586_ctr_freq != 0) {
i586_last_tick = rdtsc(); i586_last_tick = rdtsc();
i586_ctr_bias = i586_last_tick; i586_ctr_bias = i586_last_tick;
} }
@ -1144,10 +1140,13 @@ sysctl_machdep_i8254_freq SYSCTL_HANDLER_ARGS
*/ */
freq = timer_freq; freq = timer_freq;
error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req); 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) if (timer0_state != 0)
return (EBUSY); /* too much trouble to handle */ return (EBUSY); /* too much trouble to handle */
set_timer_freq(freq, hz); set_timer_freq(freq, hz);
#if defined(I586_CPU) || defined(I686_CPU)
set_i586_ctr_freq(i586_ctr_freq, timer_freq);
#endif
} }
return (error); 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", ""); 0, sizeof(u_int), sysctl_machdep_i8254_freq, "I", "");
#if defined(I586_CPU) || defined(I686_CPU) #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 static int
sysctl_machdep_i586_freq SYSCTL_HANDLER_ARGS sysctl_machdep_i586_freq SYSCTL_HANDLER_ARGS
{ {
int error; int error;
u_int freq; u_int freq;
if (i586_ctr_rate == 0) if (cpu_class != CPUCLASS_586 && cpu_class != CPUCLASS_686)
return (EOPNOTSUPP); return (EOPNOTSUPP);
freq = i586_ctr_freq; freq = i586_ctr_freq;
error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req); error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req);
if (error == 0 && freq != i586_ctr_freq) { if (error == 0 && req->newptr != NULL)
i586_ctr_freq = freq; set_i586_ctr_freq(freq, timer_freq);
i586_ctr_rate = ((unsigned long long)freq <<
I586_CTR_RATE_SHIFT) / 1000000;
}
return (error); return (error);
} }

View file

@ -3,7 +3,7 @@
# Makefile.i386 -- with config changes. # Makefile.i386 -- with config changes.
# Copyright 1990 W. Jolitz # Copyright 1990 W. Jolitz
# from: @(#)Makefile.i386 7.1 5/10/91 # 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 # Makefile for FreeBSD
# #
@ -165,8 +165,8 @@ install:
fi fi
chflags noschg /kernel chflags noschg /kernel
mv /kernel /kernel.old mv /kernel /kernel.old
if [ `sysctl -n kern.bootfile` = /kernel ] ; then \ if [ `/usr/sbin/sysctl -n kern.bootfile` = /kernel ] ; then \
sysctl -w kern.bootfile=/kernel.old ; \ /usr/sbin/sysctl -w kern.bootfile=/kernel.old ; \
mv -f /var/db/kvm_kernel.db /var/db/kvm_kernel.old.db ; \ mv -f /var/db/kvm_kernel.db /var/db/kvm_kernel.old.db ; \
fi fi
install -c -m 555 -o root -g wheel -fschg kernel / install -c -m 555 -o root -g wheel -fschg kernel /

View file

@ -34,7 +34,7 @@
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* from: @(#)autoconf.c 7.1 (Berkeley) 5/9/91 * 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
#endif /* !PC98 */ #endif /* !PC98 */
if (setdumpdev(dumpdev) != 0)
dumpdev = NODEV;
configure_finish(); configure_finish();
cninit_finish(); cninit_finish();
@ -287,15 +290,11 @@ configure(dummy)
setroot(); setroot();
} }
#endif #endif
if (!mountroot) { if (!mountroot) {
panic("Nobody wants to mount my root for me"); 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(); setconf();
cold = 0; cold = 0;
if (bootverbose) if (bootverbose)
@ -311,7 +310,6 @@ setdumpdev(dev)
if (dev == NODEV) { if (dev == NODEV) {
dumpdev = dev; dumpdev = dev;
dumplo = 0;
return (0); return (0);
} }
maj = major(dev); maj = major(dev);
@ -398,9 +396,8 @@ sysctl_kern_dumpdev SYSCTL_HANDLER_ARGS
ndumpdev = dumpdev; ndumpdev = dumpdev;
error = sysctl_handle_opaque(oidp, &ndumpdev, sizeof ndumpdev, req); error = sysctl_handle_opaque(oidp, &ndumpdev, sizeof ndumpdev, req);
if (!error && ndumpdev != dumpdev) { if (error == 0 && req->newptr != NULL)
error = setdumpdev(ndumpdev); error = setdumpdev(ndumpdev);
}
return (error); return (error);
} }

View file

@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * 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 */ #include "npx.h" /* NNPX */
@ -113,6 +113,8 @@ IDTVEC(prot)
TRAP(T_PROTFLT) TRAP(T_PROTFLT)
IDTVEC(page) IDTVEC(page)
TRAP(T_PAGEFLT) TRAP(T_PAGEFLT)
IDTVEC(mchk)
pushl $0; TRAP(T_MCHK)
IDTVEC(rsvd) IDTVEC(rsvd)
pushl $0; TRAP(T_RESERVED) pushl $0; TRAP(T_RESERVED)
IDTVEC(fpu) IDTVEC(fpu)

View file

@ -35,7 +35,7 @@
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 * 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" #include "npx.h"
@ -135,10 +135,6 @@ static void cpu_startup __P((void *));
SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL) 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 #ifdef BOUNCE_BUFFERS
extern char *bouncememory; extern char *bouncememory;
extern int maxbkva; 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 */ /* 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) #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 void setup_netisrs __P((struct linker_set *)); /* XXX declare elsewhere */
static vm_offset_t buffer_sva, buffer_eva; static vm_offset_t buffer_sva, buffer_eva;
@ -690,164 +685,15 @@ sigreturn(p, uap, retval)
return(EJUSTRETURN); 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 * Machine depdnetnt boot() routine
*
* exported (symorder) and used at least by savecore(8)
* *
* 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; void
cpu_boot(int howto)
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()
{ {
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(div), IDTVEC(dbg), IDTVEC(nmi), IDTVEC(bpt), IDTVEC(ofl),
IDTVEC(bnd), IDTVEC(ill), IDTVEC(dna), IDTVEC(fpusegm), IDTVEC(bnd), IDTVEC(ill), IDTVEC(dna), IDTVEC(fpusegm),
IDTVEC(tss), IDTVEC(missing), IDTVEC(stk), IDTVEC(prot), 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); IDTVEC(syscall), IDTVEC(int0x80_syscall);
void void
@ -1219,6 +1065,7 @@ init386(first)
setidt(15, &IDTVEC(rsvd), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); 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(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(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), setidt(0x80, &IDTVEC(int0x80_syscall),
SDT_SYS386TGT, SEL_UPL, GSEL(GCODE_SEL, SEL_KPL)); SDT_SYS386TGT, SEL_UPL, GSEL(GCODE_SEL, SEL_KPL));

View file

@ -32,7 +32,7 @@
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* from: Steve McCanne's microtime code * 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> #include <machine/asmacros.h>
@ -51,7 +51,7 @@
ENTRY(microtime) ENTRY(microtime)
#if defined(I586_CPU) || defined(I686_CPU) #if defined(I586_CPU) || defined(I686_CPU)
movl _i586_ctr_rate, %ecx movl _i586_ctr_freq, %ecx
testl %ecx, %ecx testl %ecx, %ecx
jne pentium_microtime jne pentium_microtime
#else #else
@ -256,9 +256,7 @@ pentium_microtime:
cli cli
.byte 0x0f, 0x31 /* RDTSC */ .byte 0x0f, 0x31 /* RDTSC */
subl _i586_ctr_bias, %eax subl _i586_ctr_bias, %eax
sbbl _i586_ctr_bias+4, %edx mull _i586_ctr_multiplier
shldl $I586_CTR_RATE_SHIFT, %eax, %edx /* magic suggested by */ movl %edx, %eax
shll $I586_CTR_RATE_SHIFT, %eax /* math_emulate.c */
divl %ecx /* get value in usec */
jmp common_microtime jmp common_microtime
#endif #endif

View file

@ -35,7 +35,7 @@
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* from: @(#)trap.c 7.4 (Berkeley) 5/13/91 * 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); extern inthand_t IDTVEC(syscall);
#define MAX_TRAP_MSG 27 #define MAX_TRAP_MSG 28
static char *trap_msg[] = { static char *trap_msg[] = {
"", /* 0 unused */ "", /* 0 unused */
"privileged instruction fault", /* 1 T_PRIVINFLT */ "privileged instruction fault", /* 1 T_PRIVINFLT */
@ -139,6 +139,7 @@ static char *trap_msg[] = {
"invalid TSS fault", /* 25 T_TSSFLT */ "invalid TSS fault", /* 25 T_TSSFLT */
"segment not present fault", /* 26 T_SEGNPFLT */ "segment not present fault", /* 26 T_SEGNPFLT */
"stack fault", /* 27 T_STKFLT */ "stack fault", /* 27 T_STKFLT */
"machine check trap", /* 28 T_MCHK */
}; };
static void userret __P((struct proc *p, struct trapframe *frame, static void userret __P((struct proc *p, struct trapframe *frame,

View file

@ -46,7 +46,7 @@
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** 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 */ break; /* nope, drop through */
case 1: /* there was an escape prefix */ case 1: /* there was an escape prefix */
if (c == '[') /* second character in sequence */ if (c == '[' || c == 'O') /* second character in sequence */
{ {
extended = 2; extended = 2;
continue; continue;
@ -1930,6 +1930,7 @@ dolist(int row, int num, int detail, int *ofs, DEV_LIST **list, char *dhelp)
break; break;
case '[': /* cheat : always preceeds cursor move */ case '[': /* cheat : always preceeds cursor move */
case 'O': /* ANSI application key mode */
if (extended==1) if (extended==1)
extended=2; extended=2;
else else
@ -2225,7 +2226,7 @@ visuserconfig(void)
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * 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" #include "scbus.h"

View file

@ -34,7 +34,7 @@
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91 * 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 * 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; u_int idelayed;
#if defined(I586_CPU) || defined(I686_CPU) #if defined(I586_CPU) || defined(I686_CPU)
unsigned i586_ctr_freq; u_int i586_ctr_bias;
unsigned i586_ctr_rate; u_int i586_ctr_comultiplier;
long long i586_ctr_bias; u_int i586_ctr_freq;
u_int i586_ctr_multiplier;
long long i586_last_tick; long long i586_last_tick;
unsigned long i586_avg_tick; unsigned long i586_avg_tick;
#endif #endif
@ -175,6 +176,10 @@ static u_char timer2_state;
static void (*timer_func) __P((struct clockframe *frame)) = hardclock; static void (*timer_func) __P((struct clockframe *frame)) = hardclock;
int rtc_inb __P((void)); 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 static void
clkintr(struct clockframe frame) clkintr(struct clockframe frame)
{ {
@ -693,11 +698,7 @@ calibrate_clocks(void)
* similar to those for the i8254 clock. * similar to those for the i8254 clock.
*/ */
if (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686) { if (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686) {
unsigned long long i586_count; set_i586_ctr_freq((u_int)rdtsc(), tot_count);
i586_count = rdtsc();
i586_ctr_freq = i586_count;
i586_ctr_rate = (i586_count << I586_CTR_RATE_SHIFT) / 1000000;
printf("i586 clock: %u Hz, ", i586_ctr_freq); printf("i586 clock: %u Hz, ", i586_ctr_freq);
} }
#endif #endif
@ -794,7 +795,6 @@ startrtclock()
freq, timer_freq); freq, timer_freq);
#if defined(I586_CPU) || defined(I686_CPU) #if defined(I586_CPU) || defined(I686_CPU)
i586_ctr_freq = 0; i586_ctr_freq = 0;
i586_ctr_rate = 0;
#endif #endif
} }
#endif #endif
@ -803,27 +803,23 @@ startrtclock()
#if defined(I586_CPU) || defined(I686_CPU) #if defined(I586_CPU) || defined(I686_CPU)
#ifndef CLK_USE_I586_CALIBRATION #ifndef CLK_USE_I586_CALIBRATION
if (i586_ctr_rate != 0) { if (i586_ctr_freq != 0) {
if (bootverbose) if (bootverbose)
printf( printf(
"CLK_USE_I586_CALIBRATION not specified - using old calibration method\n"); "CLK_USE_I586_CALIBRATION not specified - using old calibration method\n");
i586_ctr_freq = 0; i586_ctr_freq = 0;
i586_ctr_rate = 0;
} }
#endif #endif
if (i586_ctr_rate == 0 && if (i586_ctr_freq == 0 &&
(cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686)) { (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686)) {
/* /*
* Calibration of the i586 clock relative to the mc146818A * Calibration of the i586 clock relative to the mc146818A
* clock failed. Do a less accurate calibration relative * clock failed. Do a less accurate calibration relative
* to the i8254 clock. * to the i8254 clock.
*/ */
unsigned long long i586_count;
wrmsr(0x10, 0LL); /* XXX */ wrmsr(0x10, 0LL); /* XXX */
DELAY(1000000); DELAY(1000000);
i586_count = rdtsc(); set_i586_ctr_freq((u_int)rdtsc(), timer_freq);
i586_ctr_rate = (i586_count << I586_CTR_RATE_SHIFT) / 1000000;
#ifdef CLK_USE_I586_CALIBRATION #ifdef CLK_USE_I586_CALIBRATION
printf("i586 clock: %u Hz\n", i586_ctr_freq); printf("i586 clock: %u Hz\n", i586_ctr_freq);
#endif #endif
@ -1121,7 +1117,7 @@ cpu_initclocks()
/* /*
* Finish setting up anti-jitter measures. * Finish setting up anti-jitter measures.
*/ */
if (i586_ctr_rate) { if (i586_ctr_freq != 0) {
i586_last_tick = rdtsc(); i586_last_tick = rdtsc();
i586_ctr_bias = i586_last_tick; i586_ctr_bias = i586_last_tick;
} }
@ -1144,10 +1140,13 @@ sysctl_machdep_i8254_freq SYSCTL_HANDLER_ARGS
*/ */
freq = timer_freq; freq = timer_freq;
error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req); 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) if (timer0_state != 0)
return (EBUSY); /* too much trouble to handle */ return (EBUSY); /* too much trouble to handle */
set_timer_freq(freq, hz); set_timer_freq(freq, hz);
#if defined(I586_CPU) || defined(I686_CPU)
set_i586_ctr_freq(i586_ctr_freq, timer_freq);
#endif
} }
return (error); 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", ""); 0, sizeof(u_int), sysctl_machdep_i8254_freq, "I", "");
#if defined(I586_CPU) || defined(I686_CPU) #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 static int
sysctl_machdep_i586_freq SYSCTL_HANDLER_ARGS sysctl_machdep_i586_freq SYSCTL_HANDLER_ARGS
{ {
int error; int error;
u_int freq; u_int freq;
if (i586_ctr_rate == 0) if (cpu_class != CPUCLASS_586 && cpu_class != CPUCLASS_686)
return (EOPNOTSUPP); return (EOPNOTSUPP);
freq = i586_ctr_freq; freq = i586_ctr_freq;
error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req); error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req);
if (error == 0 && freq != i586_ctr_freq) { if (error == 0 && req->newptr != NULL)
i586_ctr_freq = freq; set_i586_ctr_freq(freq, timer_freq);
i586_ctr_rate = ((unsigned long long)freq <<
I586_CTR_RATE_SHIFT) / 1000000;
}
return (error); return (error);
} }

View file

@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * 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 int is790; /* set by the probe code if the card is 790
* based */ * 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_start; /* NIC memory start address */
caddr_t mem_end; /* NIC memory end address */ caddr_t mem_end; /* NIC memory end address */
u_long mem_size; /* total NIC memory size */ 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 *)); static int ed_attach_isa __P((struct isa_device *));
#endif #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)); static int ed_ioctl __P((struct ifnet *, int, caddr_t));
#ifdef PC98 #ifdef PC98
static int ed_probe __P((struct pc98_device *)); 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 *)); static int ed_probe_Novell __P((struct isa_device *));
#endif #endif
static int ed_probe_Novell_generic __P((struct ed_softc *, int, int, int)); 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" #include "pci.h"
#if NPCI > 0 #if NPCI > 0
@ -216,6 +229,11 @@ static void ed_rint __P((struct ed_softc *));
static void ed_xmit __P((struct ed_softc *)); static void ed_xmit __P((struct ed_softc *));
static char * ed_ring_copy __P((struct ed_softc *, char *, char *, static char * ed_ring_copy __P((struct ed_softc *, char *, char *,
/* u_short */ int)); /* 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 *, static void ed_pio_readmem __P((struct ed_softc *, int, unsigned char *,
/* u_short */ int)); /* u_short */ int));
@ -223,8 +241,10 @@ static void ed_pio_writemem __P((struct ed_softc *, char *,
/* u_short */ int, /* u_short */ int)); /* u_short */ int, /* u_short */ int));
static u_short ed_pio_write_mbufs __P((struct ed_softc *, struct mbuf *, static u_short ed_pio_write_mbufs __P((struct ed_softc *, struct mbuf *,
int)); int));
void edintr_sc __P((struct ed_softc *));
static void ed_setrcr(struct ed_softc *); static void ed_setrcr(struct ed_softc *);
static u_long ds_crc(u_char *ep); static u_long ds_crc(u_char *ep);
#if NCRD > 0 #if NCRD > 0
@ -241,8 +261,6 @@ static void edunload(struct pccard_dev *); /* Disable driver */
static void edsuspend(struct pccard_dev *); /* Suspend driver */ static void edsuspend(struct pccard_dev *); /* Suspend driver */
static int edinit(struct pccard_dev *, int); /* init device */ static int edinit(struct pccard_dev *, int); /* init device */
void edintr_sc __P((struct ed_softc *));
static struct pccard_drv ed_info = { static struct pccard_drv ed_info = {
"ed", "ed",
card_intr, card_intr,
@ -380,10 +398,28 @@ static unsigned short ed_790_intr_mask[] = {
IRQ15 IRQ15
}; };
#define ETHER_MIN_LEN 60 /*
#define ETHER_MAX_LEN 1514 * Interrupt conversion table for the HP PC LAN+
#define ETHER_ADDR_LEN 6 */
#define ETHER_HDR_SIZE 14
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 = { static struct kern_devconf kdc_ed_template = {
0, 0, 0, /* filled in by dev_attach */ 0, 0, 0, /* filled in by dev_attach */
@ -583,6 +619,11 @@ ed_probe(isa_dev)
if (nports) if (nports)
return (nports); return (nports);
} }
#ifdef NCDR > 0
nports = ed_probe_HP_pclanp(isa_dev);
if (nports)
return (nports);
#endif
return (0); return (0);
} }
@ -1627,6 +1668,329 @@ ed_probe_Novell(isa_dev)
#if NCRD > 0 #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 * Probe and vendor-specific initialization routine for PCCARDs
*/ */
@ -1857,6 +2221,7 @@ ed_attach(sc, unit, flags)
ifp->if_start = ed_start; ifp->if_start = ed_start;
ifp->if_ioctl = ed_ioctl; ifp->if_ioctl = ed_ioctl;
ifp->if_watchdog = ed_watchdog; ifp->if_watchdog = ed_watchdog;
ifp->if_init = (if_init_f_t *)ed_init;
ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
/* /*
@ -1891,10 +2256,16 @@ ed_attach(sc, unit, flags)
else else
printf("type unknown (0x%x) ", sc->type); 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) && printf("%s\n", (((sc->vendor == ED_VENDOR_3COM) ||
(ifp->if_flags & IFF_ALTPHYS)) ? " tranceiver disabled" : ""); (sc->vendor == ED_VENDOR_HP)) &&
(ifp->if_flags & IFF_ALTPHYS)) ? " tranceiver disabled" : "");
/* /*
* If BPF is in the kernel, call the attach for it * If BPF is in the kernel, call the attach for it
@ -1959,7 +2330,7 @@ ed_reset(ifp)
* Stop interface and re-initialize. * Stop interface and re-initialize.
*/ */
ed_stop(sc); ed_stop(sc);
ed_init(ifp); ed_init(sc);
(void) splx(s); (void) splx(s);
} }
@ -2013,10 +2384,10 @@ ed_watchdog(ifp)
* Initialize device. * Initialize device.
*/ */
static void static void
ed_init(ifp) ed_init(sc)
struct ifnet *ifp; struct ed_softc *sc;
{ {
struct ed_softc *sc = ifp->if_softc; struct ifnet *ifp = &sc->arpcom.ac_if;
int i, s; int i, s;
#ifdef PC98 #ifdef PC98
int unit = sc->unit; int unit = sc->unit;
@ -2355,7 +2726,7 @@ ed_start(ifp)
goto 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++; sc->txb_inuse++;
@ -2434,8 +2805,8 @@ ed_rint(sc)
ed_pio_readmem(sc, (int)packet_ptr, (char *) &packet_hdr, ed_pio_readmem(sc, (int)packet_ptr, (char *) &packet_hdr,
sizeof(packet_hdr)); sizeof(packet_hdr));
len = packet_hdr.count; len = packet_hdr.count;
if (len > (ETHER_MAX_LEN + sizeof(struct ed_ring)) || if (len > (ETHER_MAX_LEN - ETHER_CRC_LEN + sizeof(struct ed_ring)) ||
len < (ETHER_HDR_SIZE + 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 * Length is a wild value. There's a good chance that
* this was caused by the NIC being old and buggy. * this was caused by the NIC being old and buggy.
@ -2744,7 +3115,6 @@ ed_ioctl(ifp, command, data)
int command; int command;
caddr_t data; caddr_t data;
{ {
register struct ifaddr *ifa = (struct ifaddr *) data;
struct ed_softc *sc = ifp->if_softc; struct ed_softc *sc = ifp->if_softc;
struct ifreq *ifr = (struct ifreq *) data; struct ifreq *ifr = (struct ifreq *) data;
int s, error = 0; int s, error = 0;
@ -2758,79 +3128,8 @@ ed_ioctl(ifp, command, data)
switch (command) { switch (command) {
case SIOCSIFADDR: 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: case SIOCGIFADDR:
{ ether_ioctl(ifp, command, data);
struct sockaddr *sa;
sa = (struct sockaddr *) & ifr->ifr_data;
bcopy((caddr_t) sc->arpcom.ac_enaddr,
(caddr_t) sa->sa_data, ETHER_ADDR_LEN);
}
break; break;
case SIOCSIFFLAGS: case SIOCSIFFLAGS:
@ -2841,7 +3140,7 @@ ed_ioctl(ifp, command, data)
*/ */
if (ifp->if_flags & IFF_UP) { if (ifp->if_flags & IFF_UP) {
if ((ifp->if_flags & IFF_RUNNING) == 0) if ((ifp->if_flags & IFF_RUNNING) == 0)
ed_init(ifp); ed_init(ifp->if_softc);
} else { } else {
if (ifp->if_flags & IFF_RUNNING) { if (ifp->if_flags & IFF_RUNNING) {
ed_stop(sc); ed_stop(sc);
@ -2873,6 +3172,10 @@ ed_ioctl(ifp, command, data)
outb(sc->asic_addr + ED_3COM_CR, ED_3COM_CR_XSEL); 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; break;
case SIOCADDMULTI: case SIOCADDMULTI:
@ -3054,6 +3357,12 @@ ed_pio_readmem(sc, src, dst, amount)
int unit = sc->unit; int unit = sc->unit;
#endif #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 */ /* select page 0 registers */
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2 | ED_CR_STA); 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; int unit = sc->unit;
#endif #endif
/* select page 0 registers */ if (sc->vendor == ED_VENDOR_NOVELL) {
outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2 | ED_CR_STA);
/* reset remote DMA complete flag */ /* select page 0 registers */
outb(sc->nic_addr + ED_P0_ISR, ED_ISR_RDC); outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2 | ED_CR_STA);
/* set up DMA byte count */ /* reset remote DMA complete flag */
outb(sc->nic_addr + ED_P0_RBCR0, len); outb(sc->nic_addr + ED_P0_ISR, ED_ISR_RDC);
outb(sc->nic_addr + ED_P0_RBCR1, len >> 8);
/* set up destination address in NIC mem */ /* set up DMA byte count */
outb(sc->nic_addr + ED_P0_RSAR0, dst); outb(sc->nic_addr + ED_P0_RBCR0, len);
outb(sc->nic_addr + ED_P0_RSAR1, dst >> 8); 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 #ifdef PC98
if (sc->type == ED_TYPE98_LPC) if (sc->type == ED_TYPE98_LPC)
LPCT_1d0_ON(); LPCT_1d0_ON();
#endif #endif
if (sc->isa16bit)
outsw(sc->asic_addr + ED_NOVELL_DATA, src, len / 2); if (sc->isa16bit)
else outsw(sc->asic_addr + ED_NOVELL_DATA, src, len / 2);
outsb(sc->asic_addr + ED_NOVELL_DATA, src, len); else
outsb(sc->asic_addr + ED_NOVELL_DATA, src, len);
#ifdef PC98 #ifdef PC98
if (sc->type == ED_TYPE98_LPC) if (sc->type == ED_TYPE98_LPC)
LPCT_1d0_OFF(); LPCT_1d0_OFF();
#endif #endif
/* /*
* Wait for remote DMA complete. This is necessary because on the * Wait for remote DMA complete. This is necessary because on the
* transmit side, data is handled internally by the NIC in bursts and * transmit side, data is handled internally by the NIC in bursts and
* we can't start another remote DMA until this one completes. Not * we can't start another remote DMA until this one completes. Not
* waiting causes really bad things to happen - like the NIC * waiting causes really bad things to happen - like the NIC
* irrecoverably jamming the ISA bus. * irrecoverably jamming the ISA bus.
*/ */
while (((inb(sc->nic_addr + ED_P0_ISR) & ED_ISR_RDC) != ED_ISR_RDC) && --maxwait); 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; int unit = sc->unit;
#endif #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 */ /* First, count up the total number of bytes to copy */
for (total_len = 0, mp = m; mp; mp = mp->m_next) for (total_len = 0, mp = m; mp; mp = mp->m_next)
total_len += mp->m_len; total_len += mp->m_len;
@ -3290,6 +3656,243 @@ ed_pio_write_mbufs(sc, m, dst)
return (total_len); 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 static void
ed_setrcr(sc) ed_setrcr(sc)
struct ed_softc *sc; struct ed_softc *sc;

View file

@ -248,7 +248,10 @@ static void pc98_set_register __P((struct pc98_device *dev,
#undef ED_PC_MISC #undef ED_PC_MISC
#endif #endif
#define ED_PC_MISC ed_pc_misc[unit] #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 */ /* LPC-T support */
#define LPCT_1d0_ON() \ #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_data[NED];
static int ed_novell_reset[NED]; static int ed_novell_reset[NED];
static int ed_pc_misc[NED]; static int ed_pc_misc[NED];
static int ed_pc_reset[NED];
/* NE2000, LGY-98, ICM, LPC-T */ /* 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_DATA = 0x0000;
ED_NOVELL_RESET = 0x000f; ED_NOVELL_RESET = 0x000f;
ED_PC_MISC = 0x18; ED_PC_MISC = 0x18;
ED_PC_RESET = 0x1f;
break; break;
case ED_TYPE98_LGY: 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_DATA = 0x0000;
ED_NOVELL_RESET = 0x0100; ED_NOVELL_RESET = 0x0100;
ED_PC_MISC = 0x18; ED_PC_MISC = 0x18;
ED_PC_RESET = 0x1f;
break; break;
case ED_TYPE98_EGY: 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_DATA = 0x0000;
ED_NOVELL_RESET = 0x0100; ED_NOVELL_RESET = 0x0100;
ED_PC_MISC = 0x18; ED_PC_MISC = 0x18;
ED_PC_RESET = 0x1f;
break; break;
case ED_TYPE98_ICM: 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_DATA = 0x0000;
ED_NOVELL_RESET = 0x000f; ED_NOVELL_RESET = 0x000f;
ED_PC_MISC = 0x18; ED_PC_MISC = 0x18;
ED_PC_RESET = 0x1f;
break; break;
case ED_TYPE98_BDN: 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_DATA = 0;
ED_NOVELL_RESET = 0xc100; ED_NOVELL_RESET = 0xc100;
ED_PC_MISC = 0x18; ED_PC_MISC = 0x18;
ED_PC_RESET = 0x1f;
break; break;
case ED_TYPE98_SIC: case ED_TYPE98_SIC:
@ -374,402 +383,7 @@ static void pc98_set_register(struct pc98_device *dev, int unit, int type)
ED_NOVELL_DATA = 0x00; /* dummy */ ED_NOVELL_DATA = 0x00; /* dummy */
ED_NOVELL_RESET = 0x00; ED_NOVELL_RESET = 0x00;
ED_PC_MISC = 0x18; ED_PC_MISC = 0x18;
break; ED_PC_RESET = 0x1f;
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 = 0x010f;
ED_PC_MISC = 0x108;
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;
ED_PC_MISC = 0x18;
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_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; break;
case ED_TYPE98_LPC: case ED_TYPE98_LPC:
@ -779,6 +393,8 @@ static void pc98_set_register(struct pc98_device *dev, int unit, int type)
ED_NOVELL_ASIC_OFFSET = 0x0100; ED_NOVELL_ASIC_OFFSET = 0x0100;
ED_NOVELL_DATA = 0x0000; ED_NOVELL_DATA = 0x0000;
ED_NOVELL_RESET = 0x0200; ED_NOVELL_RESET = 0x0200;
ED_PC_MISC = 0x108;
ED_PC_RESET = 0x10f;
break; break;
case ED_TYPE98_108: case ED_TYPE98_108:
@ -789,6 +405,8 @@ static void pc98_set_register(struct pc98_device *dev, int unit, int type)
ED_NOVELL_ASIC_OFFSET = (0x888 | adj) - dev->id_iobase; ED_NOVELL_ASIC_OFFSET = (0x888 | adj) - dev->id_iobase;
ED_NOVELL_DATA = 0; ED_NOVELL_DATA = 0;
ED_NOVELL_RESET = 4; ED_NOVELL_RESET = 4;
ED_PC_MISC = 0x18;
ED_PC_RESET = 0x1f;
break; break;
case ED_TYPE98_LA98: case ED_TYPE98_LA98:
@ -798,6 +416,8 @@ static void pc98_set_register(struct pc98_device *dev, int unit, int type)
ED_NOVELL_ASIC_OFFSET = 0x100; ED_NOVELL_ASIC_OFFSET = 0x100;
ED_NOVELL_DATA = 0x0000; ED_NOVELL_DATA = 0x0000;
ED_NOVELL_RESET = 0xf000; ED_NOVELL_RESET = 0xf000;
ED_PC_MISC = 0x18;
ED_PC_RESET = 0x1f;
break; break;
} }
} }

View file

@ -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 * Promiscuous mode added and interrupt logic slightly changed
* to reduce the number of adapter failures. Transceiver select * to reduce the number of adapter failures. Transceiver select
@ -107,10 +107,6 @@ struct ep_board {
/* /*
* Some global constants * 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_RATE 16
#define TX_INIT_MAX_RATE 64 #define TX_INIT_MAX_RATE 64
#define RX_INIT_LATENCY 64 #define RX_INIT_LATENCY 64
@ -455,8 +451,6 @@ struct ep_board {
#define BNC 0x2 #define BNC 0x2
#define UTP 0x4 #define UTP 0x4
#define ETHER_ADDR_LEN 6
#define ETHER_MAX 1536
#define RX_BYTES_MASK (u_short) (0x07ff) #define RX_BYTES_MASK (u_short) (0x07ff)
extern struct ep_board ep_board[]; extern struct ep_board ep_board[];

View file

@ -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. * Device driver for Fujitsu MB86960A/MB86965A based Ethernet cards.
* To be used with FreeBSD 2.x * 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 * ); static void fe_dump ( int, struct fe_softc *, char * );
#endif #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.) */ /* Driver struct used in the config code. This must be public (external.) */
#ifdef PC98 #ifdef PC98
struct pc98_driver fedriver = struct pc98_driver fedriver =
@ -2118,7 +2110,7 @@ fe_start ( struct ifnet *ifp )
* (i.e., minimum packet sized) packets rapidly. An 8KB * (i.e., minimum packet sized) packets rapidly. An 8KB
* buffer can hold 130 blocks of 62 bytes long... * 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. */ /* No room. */
goto indicate_active; goto indicate_active;
} }
@ -2417,12 +2409,12 @@ fe_rint ( struct fe_softc * sc, u_char rstat )
* *
* Is this statement true? FIXME. * 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 #if FE_DEBUG >= 2
log( LOG_WARNING, log( LOG_WARNING,
"fe%d: received a %s packet? (%u bytes)\n", "fe%d: received a %s packet? (%u bytes)\n",
sc->sc_unit, sc->sc_unit,
len < ETHER_HDR_SIZE ? "partial" : "big", len < ETHER_MIN_SIZE- ETHER_CRC_SIZE ? "partial" : "big",
len ); len );
#endif #endif
sc->sc_if.if_ierrors++; 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 it carries data for upper layer.
*/ */
#if FE_DEBUG >= 2 #if FE_DEBUG >= 2
if ( len < ETHER_MIN_LEN ) { if ( len < ETHER_MIN_LEN - ETHER_CRC_LEN) {
log( LOG_WARNING, log( LOG_WARNING,
"fe%d: received a short packet? (%u bytes)\n", "fe%d: received a short packet? (%u bytes)\n",
sc->sc_unit, len ); 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 * however. If the following #error message were printed upon
* compile, you need to rewrite this function. * 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." #error "Too small MCLBYTES to use fe driver."
#endif #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. * it should be a bug of upper layer. We just ignore it.
* ... Partial (too short) packets, neither. * ... 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, log( LOG_ERR,
"fe%d: got a %s packet (%u bytes) to send\n", "fe%d: got a out-of-spes packet (%u bytes) to send\n",
sc->sc_unit, sc->sc_unit, length );
length < ETHER_HDR_SIZE ? "partial" : "big", length );
sc->sc_if.if_oerrors++; sc->sc_if.if_oerrors++;
return; return;
} }
@ -2968,14 +2959,14 @@ fe_write_mbufs ( struct fe_softc *sc, struct mbuf *m )
* packet in the transmission buffer, we can skip the * packet in the transmission buffer, we can skip the
* padding process. It may gain performance slightly. FIXME. * 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. * Update buffer status now.
* Truncate the length up to an even number, since we use outw(). * Truncate the length up to an even number, since we use outw().
*/ */
length = ( length + 1 ) & ~1; 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++; sc->txb_count++;
/* /*

View file

@ -34,7 +34,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 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 $ * 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: * TODO:
@ -161,11 +161,6 @@
#include <machine/apm_bios.h> #include <machine/apm_bios.h>
#endif /* NAPM > 0 */ #endif /* NAPM > 0 */
#define ETHER_MIN_LEN 64
#define ETHER_MAX_LEN 1518
#define ETHER_ADDR_LEN 6
/***************************************************************************** /*****************************************************************************
* Driver for Ethernet Adapter * * Driver for Ethernet Adapter *

View file

@ -21,7 +21,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 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_BUSY (1<<15)
#define EEPROM_TST_MODE (1<<14) #define EEPROM_TST_MODE (1<<14)
#define READ_EEPROM (1<<7) #define READ_EEPROM (1<<7)
#define ETHER_ADDR_LEN 6
#define ETHER_MAX 1536
#define ENABLE_UTP 0xc0 #define ENABLE_UTP 0xc0
#define DISABLE_UTP 0x0 #define DISABLE_UTP 0x0
#define RX_BYTES_MASK (u_short) (0x07ff) #define RX_BYTES_MASK (u_short) (0x07ff)

View file

@ -35,7 +35,7 @@
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 * 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" #include "npx.h"
@ -135,10 +135,6 @@ static void cpu_startup __P((void *));
SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL) 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 #ifdef BOUNCE_BUFFERS
extern char *bouncememory; extern char *bouncememory;
extern int maxbkva; 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 */ /* 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) #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 void setup_netisrs __P((struct linker_set *)); /* XXX declare elsewhere */
static vm_offset_t buffer_sva, buffer_eva; static vm_offset_t buffer_sva, buffer_eva;
@ -690,164 +685,15 @@ sigreturn(p, uap, retval)
return(EJUSTRETURN); 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 * Machine depdnetnt boot() routine
*
* exported (symorder) and used at least by savecore(8)
* *
* 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; void
cpu_boot(int howto)
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()
{ {
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(div), IDTVEC(dbg), IDTVEC(nmi), IDTVEC(bpt), IDTVEC(ofl),
IDTVEC(bnd), IDTVEC(ill), IDTVEC(dna), IDTVEC(fpusegm), IDTVEC(bnd), IDTVEC(ill), IDTVEC(dna), IDTVEC(fpusegm),
IDTVEC(tss), IDTVEC(missing), IDTVEC(stk), IDTVEC(prot), 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); IDTVEC(syscall), IDTVEC(int0x80_syscall);
void void
@ -1219,6 +1065,7 @@ init386(first)
setidt(15, &IDTVEC(rsvd), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); 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(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(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), setidt(0x80, &IDTVEC(int0x80_syscall),
SDT_SYS386TGT, SEL_UPL, GSEL(GCODE_SEL, SEL_KPL)); SDT_SYS386TGT, SEL_UPL, GSEL(GCODE_SEL, SEL_KPL));

View file

@ -192,197 +192,3 @@ void init_pc98_dmac(void)
outb(0x29, (0x0c | 3)); /* Bank Mode Reg. 16M mode */ outb(0x29, (0x0c | 3)); /* Bank Mode Reg. 16M mode */
outb(0x11, 0x50); /* PC98 must be 0x40 */ 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 */
}

View file

@ -35,40 +35,3 @@ void init_cpu_accel_mem __P((void));
void init_pc98_dmac __P((void)); void init_pc98_dmac __P((void));
#endif /* __PC98_PC98_PC98_MACHDEP_H__ */ #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__ */

View file

@ -1,7 +1,7 @@
/* /*
* random_machdep.c -- A strong random number generator * 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 * 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; u_int32_t time;
#if defined(I586_CPU) || defined(I686_CPU) #if defined(I586_CPU) || defined(I686_CPU)
if (i586_ctr_rate != 0) { if (i586_ctr_freq != 0) {
num ^= (u_int32_t) rdtsc() << 16; num ^= (u_int32_t) rdtsc() << 16;
r->entropy_count += 2; r->entropy_count += 2;
} else { } else {

View file

@ -4,12 +4,12 @@
* v1.4 by Eric S. Raymond (esr@snark.thyrsus.com) Aug 1993 * v1.4 by Eric S. Raymond (esr@snark.thyrsus.com) Aug 1993
* modified for FreeBSD by Andrew A. Chernov <ache@astral.msk.su> * 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 * 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" #include "speaker.h"
@ -568,7 +568,7 @@ spkrwrite(dev, uio, ioflag)
if (minor(dev) != 0) if (minor(dev) != 0)
return(ENXIO); 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); return(E2BIG);
else else
{ {
@ -578,8 +578,11 @@ spkrwrite(dev, uio, ioflag)
n = uio->uio_resid; n = uio->uio_resid;
cp = spkr_inbuf->b_un.b_addr; 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); playstring(cp, n);
}
return(error); return(error);
} }
} }

View file

@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 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" #include "sc.h"
@ -168,6 +168,7 @@ struct tty *sccons[MAXCONS+1];
#define VIRTUAL_TTY(x) &sccons[x] #define VIRTUAL_TTY(x) &sccons[x]
#define CONSOLE_TTY &sccons[MAXCONS] #define CONSOLE_TTY &sccons[MAXCONS]
static struct tty sccons[MAXCONS+1]; static struct tty sccons[MAXCONS+1];
static int nsccons = MAXCONS; /* for pstat only */
#endif #endif
#ifdef PC98 #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 */ switch (cmd) { /* process console hardware related ioctl's */
case GIO_ATTR: /* get current attributes */ case GIO_ATTR: /* get current attributes */
*(int*)data = scp->term.cur_attr; *(int*)data = (scp->term.cur_attr >> 8) & 0xFF;
return 0; return 0;
case GIO_COLOR: /* is this a color console ? */ case GIO_COLOR: /* is this a color console ? */

View file

@ -34,7 +34,7 @@
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* from: @(#)wd.c 7.2 (Berkeley) 5/9/91 * 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: /* TODO:
@ -503,8 +503,12 @@ wdprobe(struct pc98_device *dvp)
else else
du->dk_error = inb(du->dk_port + wd_error); du->dk_error = inb(du->dk_port + wd_error);
/* printf("Error (drv 1) : %x\n", du->dk_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; goto nodevice;
} else /* drive 0 fail */ } else /* drive 0 fail */
goto nodevice; goto nodevice;
@ -1603,6 +1607,30 @@ wdcommand(struct disk *du, u_int cylinder, u_int head, u_int sector,
return (0); 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. * issue IDC to drive to tell it just what geometry it is to be.
*/ */
@ -1653,26 +1681,15 @@ wdsetctlr(struct disk *du)
return (1); return (1);
} }
/* wdsetmulti(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)) {
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;
}
#ifdef NOTYET #ifdef NOTYET
/* set read caching and write caching */ /* set read caching and write caching */
wdcommand(du, 0, 0, 0, WDFEA_RCACHE, WDCC_FEATURES); wdcommand(du, 0, 0, 0, WDFEA_RCACHE, WDCC_FEATURES);
wdwait(du, WDCS_READY, TIMEOUT);
wdcommand(du, 0, 0, 0, WDFEA_WCACHE, WDCC_FEATURES); wdcommand(du, 0, 0, 0, WDFEA_WCACHE, WDCC_FEATURES);
wdwait(du, WDCS_READY, TIMEOUT);
#endif #endif
return (0); return (0);
@ -1748,6 +1765,10 @@ wdgetctlr(struct disk *du)
else { else {
outb(du->dk_port + wd_sdh, WDSD_IBM | (du->dk_unit << 4)); outb(du->dk_port + wd_sdh, WDSD_IBM | (du->dk_unit << 4));
DELAY(5000); /* usually unnecessary; drive select is fast */ 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)) if ((inb(du->dk_port + wd_status) & (WDCS_BUSY | WDCS_READY))
!= WDCS_READY != WDCS_READY
|| wdcommand(du, 0, 0, 0, 0, WDCC_RESTORE | WD_STEP) != 0 || wdcommand(du, 0, 0, 0, 0, WDCC_RESTORE | WD_STEP) != 0
@ -1869,6 +1890,12 @@ wdgetctlr(struct disk *du)
wp->wdp_model[i] = '\0'; 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 #ifdef WDDEBUG
printf( printf(
"\nwd(%d,%d): wdgetctlr: gc %x cyl %d trk %d sec %d type %d sz %d model %s\n", "\nwd(%d,%d): wdgetctlr: gc %x cyl %d trk %d sec %d type %d sz %d model %s\n",

45
sys/pccard/pcic98reg.h Normal file
View file

@ -0,0 +1,45 @@
/*
pcic98reg.h
PC9801NS/A PCMCIA contorer routine conpatible to PCIC
Noriyuki Hosobuchi 96.1.20
*/
/*--- I/O port definition */
#define PCIC98_REG0 0x0a8e /* byte */
#define PCIC98_REG1 0x1a8e /* byte */
#define PCIC98_REG2 0x2a8e /* byte */
#define PCIC98_REG3 0x3a8e /* byte : Interrupt */
#define PCIC98_REG4 0x4a8e /* word : PC98 side IO base */
#define PCIC98_REG5 0x5a8e /* word : Card side IO base */
#define PCIC98_REG6 0x7a8e /* byte */
#define PCIC98_REG_WINSEL 0x1e8e /* byte : win bank select register */
#define PCIC98_REG_PAGOFS 0x0e8e /* word */
/* PC98_REG_WINSEL */
#define PCIC98_MAPWIN 0x84 /* map Card on 0xda0000 - 0xdbffff */
#define PCIC98_UNMAPWIN 0x00
/* PCIC98_REG1 */
#define PCIC98_CARDEXIST 0x08 /* 1:exist 0:not exist */
/* PCIC98_REG2 */
#define PCIC98_IOMEMORY 0x80 /* 1:IO 0:Memory */
#define PCIC98_MAPIO 0x40 /* 0:IO map 1:??? */
#define PCIC98_8BIT 0x20 /* bit width 1:8bit 0:16bit */
#define PCIC98_MAP128 0x10 /* IO map size 1:128byte 0:16byte */
#define PCIC98_VCC3P3V 0x02 /* Vcc 1:3.3V 0:5.0V */
/* PCIC98_REG3 */
#define PCIC98_INT0 (0xf8 + 0x0) /* INT0(IRQ3) */
#define PCIC98_INT1 (0xf8 + 0x1) /* INT1(IRQ5) */
#define PCIC98_INT2 (0xf8 + 0x2) /* INT2(IRQ6) */
#define PCIC98_INT4 (0xf8 + 0x4) /* INT4(IRQ10) */
#define PCIC98_INT5 (0xf8 + 0x5) /* INT5(IRQ12) */
#define PCIC98_INTDISABLE (0xf8 + 0x7) /* disable interrupt */
/* PCIC98_REG6 */
#define PCIC98_ATTRMEM 0x20 /* 1:attr mem 0:common mem */
#define PCIC98_VPP12V 0x10 /* Vpp 0:5V 1:12V */