mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-14 14:55:41 +00:00
Update to current state of PC98 world.
Submitted by: The FreeBSD(98) development team
This commit is contained in:
parent
4d8db7c76f
commit
92b4f2e0df
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=17256
@ -30,7 +30,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: cpufunc.h,v 1.51 1996/07/01 18:12:23 bde Exp $
|
||||
* $Id: cpufunc.h,v 1.52 1996/07/01 20:16:09 bde Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -252,6 +252,8 @@ outw(u_int port, u_short data)
|
||||
}
|
||||
|
||||
#ifdef PC98
|
||||
#include <machine/spl.h>
|
||||
|
||||
static inline u_char
|
||||
epson_inb(u_int port)
|
||||
{
|
||||
|
@ -3,7 +3,7 @@
|
||||
# Makefile.i386 -- with config changes.
|
||||
# Copyright 1990 W. Jolitz
|
||||
# from: @(#)Makefile.i386 7.1 5/10/91
|
||||
# $Id: Makefile.i386,v 1.84 1996/06/08 23:27:16 jkh Exp $
|
||||
# $Id: Makefile.pc98,v 1.1.1.1 1996/06/14 10:04:40 asami Exp $
|
||||
#
|
||||
# Makefile for FreeBSD
|
||||
#
|
||||
@ -31,7 +31,7 @@ I386= ${S}/i386
|
||||
|
||||
CWARNFLAGS?= -W -Wreturn-type -Wcomment -Wredundant-decls -Wimplicit \
|
||||
-Wnested-externs -Wstrict-prototypes -Wmissing-prototypes \
|
||||
-Winline
|
||||
-Winline -Wunused
|
||||
#
|
||||
# The following flags are next up for working on:
|
||||
# -Wall
|
||||
|
@ -2,7 +2,7 @@
|
||||
# files marked standard are always included.
|
||||
#
|
||||
# modified for PC-9801 after:
|
||||
# $Id: files.i386,v 1.136 1996/06/07 22:26:59 nate Exp $
|
||||
# $Id: files.pc98,v 1.1.1.1 1996/06/14 10:04:40 asami Exp $
|
||||
#
|
||||
aic7xxx_asm optional ahc device-driver \
|
||||
dependency "$S/dev/aic7xxx/aic7xxx_asm.c" \
|
||||
@ -42,11 +42,13 @@ i386/i386/db_disasm.c optional ddb
|
||||
i386/i386/db_interface.c optional ddb
|
||||
i386/i386/db_trace.c optional ddb
|
||||
pc98/i386/exception.s standard
|
||||
i386/i386/identcpu.c standard
|
||||
i386/i386/in_cksum.c optional inet
|
||||
# locore.s needs to be handled in Makefile to put it first. Otherwise it's
|
||||
# now normal.
|
||||
# i386/i386/locore.s standard
|
||||
pc98/i386/machdep.c standard
|
||||
pc98/pc98/pc98_machdep.c standard
|
||||
i386/i386/math_emulate.c optional math_emulate
|
||||
i386/i386/mem.c standard
|
||||
pc98/i386/microtime.s standard
|
||||
@ -112,6 +114,7 @@ pc98/pc98/if_fe.c optional fe device-driver
|
||||
#pc98/isa/if_ix.c optional ix device-driver
|
||||
#pc98/isa/if_le.c optional le device-driver
|
||||
#pc98/isa/if_lnc.c optional lnc device-driver
|
||||
#i386/isa/if_sr.c optional sr device-driver
|
||||
#pc98/isa/if_ze.c optional ze device-driver
|
||||
pc98/pc98/if_zp.c optional zp device-driver
|
||||
pc98/pc98/pc98.c optional nec device-driver
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: options.i386,v 1.13 1996/05/11 04:39:44 bde Exp $
|
||||
# $Id: options.pc98,v 1.1.1.1 1996/06/14 10:04:40 asami Exp $
|
||||
BOUNCEPAGES opt_bounce.h
|
||||
USER_LDT
|
||||
MATH_EMULATE opt_math_emulate.h
|
||||
@ -23,3 +23,7 @@ FAT_CURSOR opt_pcvt.h
|
||||
PCVT_FREEBSD opt_pcvt.h
|
||||
PCVT_SCANSET opt_pcvt.h
|
||||
XSERVER opt_pcvt.h
|
||||
|
||||
CLK_CALIBRATION_LOOP opt_clock.h
|
||||
CLK_USE_I8254_CALIBRATION opt_clock.h
|
||||
CLK_USE_I586_CALIBRATION opt_clock.h
|
||||
|
@ -30,7 +30,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: cpufunc.h,v 1.51 1996/07/01 18:12:23 bde Exp $
|
||||
* $Id: cpufunc.h,v 1.52 1996/07/01 20:16:09 bde Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -252,6 +252,8 @@ outw(u_int port, u_short data)
|
||||
}
|
||||
|
||||
#ifdef PC98
|
||||
#include <machine/spl.h>
|
||||
|
||||
static inline u_char
|
||||
epson_inb(u_int port)
|
||||
{
|
||||
|
@ -14,7 +14,7 @@
|
||||
*
|
||||
* Sep, 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
|
||||
*
|
||||
* $Id: apm.c,v 1.43 1996/06/04 17:50:28 nate Exp $
|
||||
* $Id: apm.c,v 1.1.1.1 1996/06/14 10:04:36 asami Exp $
|
||||
*/
|
||||
|
||||
#include "apm.h"
|
||||
@ -36,10 +36,8 @@
|
||||
#include <sys/proc.h>
|
||||
#include <sys/vnode.h>
|
||||
#ifdef PC98
|
||||
#include "pc98/pc98/pc98.h"
|
||||
#include "pc98/pc98/pc98_device.h"
|
||||
#else
|
||||
#include "i386/isa/isa.h"
|
||||
#include "i386/isa/isa_device.h"
|
||||
#endif
|
||||
#include <machine/apm_bios.h>
|
||||
@ -710,6 +708,11 @@ apmattach(struct isa_device *dvp)
|
||||
#ifdef APM_DSVALUE_BUG
|
||||
caddr_t apm_bios_work;
|
||||
|
||||
/*
|
||||
* XXX - Malloc enough space for the APM DS, and then copy the
|
||||
* current DS into the new space since the DS setup by the
|
||||
* APM bios is going to get wiped out.
|
||||
*/
|
||||
apm_bios_work = (caddr_t)malloc(apm_ds_limit, M_DEVBUF, M_NOWAIT);
|
||||
bcopy((caddr_t)((apm_ds_base << 4) + APM_KERNBASE), apm_bios_work,
|
||||
apm_ds_limit);
|
||||
@ -721,14 +724,15 @@ apmattach(struct isa_device *dvp)
|
||||
sc->active = 0;
|
||||
|
||||
/* setup APM parameters */
|
||||
sc->cs16_base = (apm_cs32_base << 4) + APM_KERNBASE;
|
||||
sc->cs32_base = (apm_cs16_base << 4) + APM_KERNBASE;
|
||||
sc->cs16_base = (apm_cs16_base << 4) + APM_KERNBASE;
|
||||
sc->cs32_base = (apm_cs32_base << 4) + APM_KERNBASE;
|
||||
sc->ds_base = (apm_ds_base << 4) + APM_KERNBASE;
|
||||
sc->cs_limit = apm_cs_limit;
|
||||
sc->ds_limit = apm_ds_limit;
|
||||
sc->cs_entry = apm_cs_entry;
|
||||
|
||||
#ifdef APM_DSVALUE_BUG
|
||||
/* Set the DS base to point to the newly made copy of the APM DS */
|
||||
sc->ds_base = (u_int)apm_bios_work;
|
||||
#endif /* APM_DSVALUE_BUG */
|
||||
|
||||
@ -747,10 +751,11 @@ apmattach(struct isa_device *dvp)
|
||||
printf("apm: Code entry 0x%08x, Idling CPU %s, Management %s\n",
|
||||
sc->cs_entry, is_enabled(sc->slow_idle_cpu),
|
||||
is_enabled(!sc->disabled));
|
||||
printf("apm: CS_limit=%x, DS_limit=%x\n", sc->cs_limit, sc->ds_limit);
|
||||
printf("apm: CS_limit=0x%x, DS_limit=0x%x\n",
|
||||
sc->cs_limit, sc->ds_limit);
|
||||
#endif /* APM_DEBUG */
|
||||
|
||||
#ifdef APM_DEBUG
|
||||
#ifdef 0
|
||||
/* Workaround for some buggy APM BIOS implementations */
|
||||
sc->cs_limit = 0xffff;
|
||||
sc->ds_limit = 0xffff;
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: Makefile,v 1.40 1996/05/11 04:27:23 bde Exp $
|
||||
# $Id: Makefile,v 1.1.1.1 1996/06/14 10:04:37 asami Exp $
|
||||
#
|
||||
|
||||
PROG= boot
|
||||
@ -20,6 +20,11 @@ CFLAGS+= -DCOMCONSOLE=0x30 -DCOMCONSOLE_CLK=16 -DCOMCONSOLE_MODE=0x0c
|
||||
# PROBE_KEYBOARD is defined).
|
||||
#CFLAGS+= -DFORCE_COMCONSOLE
|
||||
|
||||
# Enable code to take the default boot string from a fixed location on the
|
||||
# disk. See nextboot(8) and README.386BSD for more info.
|
||||
#CFLAGS+= -DNAMEBLOCK
|
||||
#CFLAGS+= -DNAMEBLOCK_WRITEBACK
|
||||
|
||||
# Bias the conversion from the BIOS drive number to the FreeBSD unit number
|
||||
# for hard disks. This may be useful for people booting in a mixed IDE/SCSI
|
||||
# environment (set BOOT_HD_BIAS to the number of IDE drives).
|
||||
|
@ -1,3 +1,6 @@
|
||||
Note: all my original references to 386BSD also refer to freeBSD and NetBSD
|
||||
which in some ways are derived from 386BSD. --julian@freebsd.org
|
||||
|
||||
This Boot code is different from the original boot code that came with
|
||||
386BSD in that it uses the BIOS to load the kernel and to provide all i/o
|
||||
services. The advantage ofthis is that the same boot code exactly, can run
|
||||
@ -15,46 +18,60 @@ following operations occur:
|
||||
1/ the BIOS loads the first block of the disk (called the Master Boot Record
|
||||
or MBR) and if it has the correct magic numbers, jumps into it:
|
||||
|
||||
2/ The MBR code, looks at the Partition table that is embedded within it,
|
||||
2/ The MBR code, looks at the Partition table that is embedded within it,
|
||||
to determine which is the partition to boot from. If you install the
|
||||
boot manager when FreeBSD is first installed, it will also give you a nice
|
||||
menu for switching between operating systems.
|
||||
|
||||
3/ The MBR will load the first record of the selected partition and
|
||||
3/ The MBR will load the first record of the selected partition and
|
||||
if it has (the same) magic numbers, jumps into it. In 386bsd this is the
|
||||
first stage boot, (or boot1) it is represented in /usr/mdec by
|
||||
wdboot, asboot and sdboot. If the disk has been set up without DOS partitioning
|
||||
then this block will be at block zero, and will have been loaded directly by
|
||||
the BIOS.
|
||||
the BIOS. This is the usual case with floppies.
|
||||
|
||||
4/ Boot1 will look at block0 (which might be itself if there are no DOS
|
||||
partitions) and will find the 386bsd partition, and using the information
|
||||
regarding the start position of that partition, will load the next 13 sectors
|
||||
or so, to around 90000 (640k - 64k). and will jump into it at the appropriate
|
||||
entry point. Since boot1 and boot2 were compiled together as one file
|
||||
and then split later, boot1 knows the exact position within boot2 of the
|
||||
entry point.
|
||||
partitions) and will find the 386bsd partition,
|
||||
|
||||
Boot 1 also contains a compiled in DOS partition table
|
||||
(in case it is at block 0), which contains a 386bsd partition starting
|
||||
at 0. This ensures that the same code can work whether or not
|
||||
boot1 is at block 0.
|
||||
|
||||
4A/ IF the NAMEBLOCK option is compiled into the bootcode, then the
|
||||
boot1 code will load and examine block1 (usually unused) and
|
||||
look for a default boot string to use later (if the correct magic number
|
||||
is present). If the option NAMEBLOCK_WRITEBACK is also defined, then
|
||||
it will zero out that name after finding it, and write the block back,
|
||||
having "used up" that name. The block may contain multiple different
|
||||
boot strings which will be "used up" one after the other (one per boot)
|
||||
They are set using the "nextboot" utility.
|
||||
|
||||
4B/ Using the information found in step 4, regarding the start position
|
||||
of the BSD partition, boot1 will load the first 16 sectors of that partition,
|
||||
to around 0x10000 (64k) and will jump into it at the appropriate entry point.
|
||||
Since boot1 and boot2 were compiled together as one file and then split
|
||||
later, boot1 knows the exact position within boot2 of the entry point.
|
||||
|
||||
5/ Boot2 asks the user for a boot device, partition and filename, and then
|
||||
loads the MBR of the selected device. This may or may not be the device
|
||||
which was originally used to boot the first MBR. The partition table
|
||||
of the new MBR is searched for a 386bsd partition, and if one is found,
|
||||
that is then in turn searched for the disklabel. This could all be on the
|
||||
second disk at this point, if the user selected it.
|
||||
second disk at this point, if the user selected it. If the user makes no
|
||||
actions then a default string will be used.
|
||||
|
||||
6/On finding the disklabel, boot2 can find the correct unix partition
|
||||
within the 386bsd partition, and using cutdown filesystem code,
|
||||
look for the file to boot (e.g. 386bsd).
|
||||
If the NAMEBLOCK option is used, then the default string may have been
|
||||
loaded from block2. If none was found then a compiled in default will be used.
|
||||
|
||||
6/On finding the disklabel, on the disk the user spacified, boot2 can find
|
||||
the correct unix partition within the 386bsd partition, and using cutdown
|
||||
filesystem code, look for the file to boot (e.g., 386bsd).
|
||||
|
||||
7/ Boot2 loads this file starting at the location specified by the a.out header,
|
||||
(see later) and leaps into it at the location specified in he header.
|
||||
|
||||
if the file does not exist or cannot be loaded, boot2 goes back to step 5.
|
||||
if the file does not exist or cannot be loaded, boot2 goes back to step 5.
|
||||
|
||||
386bsd is now running and will hopefully start vm etc. and get to multi-user
|
||||
mode.
|
||||
@ -78,10 +95,12 @@ partition, and you can change it to a 386BSD partition later. If you use
|
||||
no DOS partitioning, then the compiled in table in Boot1 will do just fine.
|
||||
|
||||
If you want to do it by hand remember that BIOS counts sectors starting at 1.
|
||||
(cylinders and heads start at 0 (??))
|
||||
(cylinders and heads start at 0 (??))
|
||||
|
||||
2/ you cannot overwrite the bottom 4k of ram until you have finished ALL
|
||||
bios calls, as BIOS uses this area as scratch memory.
|
||||
This is no longer really a problem as we no-longer support loading the kernel
|
||||
at location 0.
|
||||
|
||||
3/ Since BIOS runs in REAL mode, and Boot2 runs in protected mode,
|
||||
Boot 2 switches back to real mode just before each BIOS call and then
|
||||
@ -90,8 +109,10 @@ back to protected mode on each return. Touch this at your peril.!
|
||||
#########################################################################
|
||||
In answering the prompt from Boot2:
|
||||
you can,
|
||||
1/ leave it alone.. it will boot the indicated file from the first
|
||||
1/ leave it alone. It will boot the indicated file from the first
|
||||
partition of the first drive seen by the BIOS (C:)
|
||||
If the NAMEBLOCK option is in use, the default name might be taken from block1
|
||||
(2nd block) on that drive (the drive on which boot 1 was loaded).
|
||||
|
||||
2/ enter only "-s" to boot the default to single user mode
|
||||
|
||||
@ -148,4 +169,4 @@ Before you do this ensure you have a booting floppy with correct
|
||||
disktab and bootblock files on it so that if it doesn't work, you can
|
||||
re-disklabel from the floppy.
|
||||
|
||||
$Id: README.386BSD,v 1.4 1996/04/07 14:27:57 bde Exp $
|
||||
$Id: README.386BSD,v 1.1.1.1 1996/06/14 10:04:37 asami Exp $
|
||||
|
@ -24,7 +24,7 @@
|
||||
* the rights to redistribute these changes.
|
||||
*
|
||||
* from: Mach, [92/04/03 16:51:14 rvb]
|
||||
* $Id: boot.c,v 1.50 1996/05/11 04:27:24 bde Exp $
|
||||
* $Id: boot.c,v 1.1.1.1 1996/06/14 10:04:37 asami Exp $
|
||||
*/
|
||||
|
||||
|
||||
@ -61,6 +61,9 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
#define NAMEBUF_LEN (8*1024)
|
||||
|
||||
#ifdef NAMEBLOCK
|
||||
char *dflt_name;
|
||||
#endif
|
||||
char namebuf[NAMEBUF_LEN];
|
||||
struct exec head;
|
||||
struct bootinfo bootinfo;
|
||||
@ -144,8 +147,19 @@ boot(int drive)
|
||||
#endif
|
||||
}
|
||||
#endif /* PC98 */
|
||||
|
||||
#ifdef NAMEBLOCK
|
||||
/*
|
||||
* XXX
|
||||
* DAMN! I don't understand why this is not being set
|
||||
* by the code in boot2.S
|
||||
*/
|
||||
dflt_name= (char *)0x0000ffb0;
|
||||
if( (*dflt_name++ == 'D') && (*dflt_name++ == 'N')) {
|
||||
name = dflt_name;
|
||||
} else
|
||||
#endif /*NAMEBLOCK*/
|
||||
loadstart:
|
||||
name = dflname; /* re-initialize in case of loop */
|
||||
/* print this all each time.. (saves space to do so) */
|
||||
/* If we have looped, use the previous entries as defaults */
|
||||
printf("\n>> FreeBSD BOOT @ 0x%x: %d/%d k of memory\n"
|
||||
@ -159,7 +173,6 @@ boot(int drive)
|
||||
dosdev & 0x7f, devs[maj], unit, name);
|
||||
#endif
|
||||
|
||||
name = dflname; /* re-initialize in case of loop */
|
||||
loadflags &= RB_SERIAL; /* clear all, but leave serial console */
|
||||
getbootdev(namebuf, &loadflags);
|
||||
ret = openrd();
|
||||
|
@ -50,6 +50,7 @@
|
||||
|
||||
/*
|
||||
* boot2() -- second stage boot
|
||||
* SP points to default string if found
|
||||
*/
|
||||
|
||||
ENTRY(boot2)
|
||||
@ -60,6 +61,11 @@ ENTRY(boot2)
|
||||
mov %ax, %es
|
||||
data32
|
||||
shll $4, %eax
|
||||
#ifdef NAMEBLOCK
|
||||
addr32
|
||||
data32
|
||||
movl %esp, EXT(dflt_name)
|
||||
#endif
|
||||
|
||||
/* fix up GDT entries for bootstrap */
|
||||
#define FIXUP(gdt_index) \
|
||||
|
@ -24,7 +24,7 @@
|
||||
* the rights to redistribute these changes.
|
||||
*
|
||||
* from: Mach, Revision 2.2 92/04/04 11:35:49 rpd
|
||||
* $Id: disk.c,v 1.16 1995/09/16 13:03:59 bde Exp $
|
||||
* $Id: disk.c,v 1.1.1.1 1996/06/14 10:04:37 asami Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -58,8 +58,8 @@
|
||||
#ifdef DO_BAD144
|
||||
struct dkbad dkb;
|
||||
int do_bad144;
|
||||
int bsize;
|
||||
#endif DO_BAD144
|
||||
int bsize;
|
||||
|
||||
int spt, spc;
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
* the rights to redistribute these changes.
|
||||
*
|
||||
* from: Mach, Revision 2.2 92/04/04 11:36:29 rpd
|
||||
* $Id: start.S,v 1.6 1995/09/16 13:51:20 bde Exp $
|
||||
* $Id: start.S,v 1.1.1.1 1996/06/14 10:04:37 asami Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -60,6 +60,18 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
SIGNATURE= 0xaa55
|
||||
LOADSZ= 8192 /* size of unix boot */
|
||||
|
||||
NAMEBLOCKMAGIC= 0xfadefeed /* value of magicnumebr for block2 */
|
||||
|
||||
/*
|
||||
* This DEBUGMSG(msg) macro may be useful for debugging. Its use is
|
||||
* restricted to this file since it only works in real mode.
|
||||
*/
|
||||
#define DEBUGMSG(msg) \
|
||||
data32 ; \
|
||||
mov $msg, %esi ; \
|
||||
data32 ; \
|
||||
call message
|
||||
|
||||
.text
|
||||
.globl start
|
||||
|
||||
@ -79,8 +91,13 @@ start:
|
||||
data32
|
||||
mov $BOOTSEG, %eax
|
||||
mov %ax, %ss
|
||||
/*
|
||||
* make a little room on the stack for
|
||||
* us to save the default bootstring we might find..
|
||||
* effectively, we push the bootstring.
|
||||
*/
|
||||
data32
|
||||
mov $BOOTSTACK, %esp
|
||||
mov $BOOTSTACK-64, %esp
|
||||
|
||||
/* set up %es, (where we will load boot2 to) */
|
||||
mov %ax, %es
|
||||
@ -221,6 +238,164 @@ hd:
|
||||
*/
|
||||
|
||||
load:
|
||||
#ifdef NAMEBLOCK
|
||||
/*
|
||||
* Load the second sector and see if it is a boot instruction block.
|
||||
* If it is then scan the contents for the first valid string and copy it to
|
||||
* the location of the default boot string.. then zero it out.
|
||||
* Finally write the block back to disk with the zero'd out entry..
|
||||
* I hate writing at this stage but we need this to be persistant.
|
||||
* If the boot fails, then the next boot will get the next string.
|
||||
* /etc/rc will regenerate a complete block2 iff teh boot succeeds.
|
||||
*
|
||||
* Format of block 2 is:
|
||||
* [NAMEBLOCKMAGIC] <--0xdeafc0de
|
||||
* [nulls]
|
||||
* [bootstring]NULL <---e.g. 0:wd(0,a)/kernel.experimental
|
||||
* [bootstring]NULL <---e.g. 0:wd(0,a)/kernel.old
|
||||
* ....
|
||||
* [bootstring]NULL <---e.g. 0:wd(0,f)/kernel
|
||||
* FF FF FF
|
||||
*/
|
||||
where:
|
||||
/*
|
||||
* save things we might smash
|
||||
* (that are not smashed immedatly after us anyway.)
|
||||
*/
|
||||
data32
|
||||
push %ecx /* preserve 'cyl,sector ' */
|
||||
data32
|
||||
push %edx
|
||||
/*
|
||||
* Load the second sector
|
||||
* BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
|
||||
* Call with %ah = 0x2
|
||||
* %al = number of sectors
|
||||
* %ch = cylinder
|
||||
* %cl = sector
|
||||
* %dh = head
|
||||
* %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
|
||||
* %es:%bx = segment:offset of buffer
|
||||
* Return:
|
||||
* %al = 0x0 on success; err code on failure
|
||||
*/
|
||||
data32
|
||||
movl $0x0201, %eax /function 2 (read) 1 sector */
|
||||
xor %ebx, %ebx /* %bx = 0 */ /* buffer address (ES:0) */
|
||||
data32
|
||||
movl $0x0002, %ecx /* sector 2, cylinder 0 */
|
||||
data32
|
||||
andl $0x00ff, %edx /* head 0, drive N */
|
||||
int $0x13
|
||||
data32
|
||||
jb read_error
|
||||
/*
|
||||
* confirm that it is one for us
|
||||
*/
|
||||
data32
|
||||
xorl %ebx, %ebx /* magic number at start of buffer */
|
||||
data32
|
||||
addr32
|
||||
movl %es:(%ebx), %eax
|
||||
data32
|
||||
cmpl $NAMEBLOCKMAGIC, %eax
|
||||
data32
|
||||
jne notours /* not ours so return to caller */
|
||||
/*
|
||||
* scan for a bootstring
|
||||
* Skip the magic number, and scan till we find a non-null,
|
||||
* or a -1
|
||||
*/
|
||||
incl %ebx /* quicker and smaller */
|
||||
incl %ebx
|
||||
incl %ebx
|
||||
scan:
|
||||
incl %ebx
|
||||
addr32
|
||||
movb %es:(%ebx), %al /* load the next byte */
|
||||
testb %al, %al /* and if it is null */
|
||||
data32 /* keep scanning (past deleted entries) */
|
||||
jz scan
|
||||
incb %al /* now look for -1 */
|
||||
data32
|
||||
jz notours /* if we reach the 0xFF then we have finished */
|
||||
|
||||
/*
|
||||
* save our settings.. we need them twice..
|
||||
*/
|
||||
data32
|
||||
push %ebx
|
||||
/*
|
||||
* copy it to the default string location
|
||||
* which is just above the stack for 64 bytes.
|
||||
*/
|
||||
data32
|
||||
movl $BOOTSTACK-64, %ecx /* 64 bytes at the top of the stack */
|
||||
nxtbyte:
|
||||
addr32
|
||||
movb %es:(%ebx), %al /* get the next byte in */
|
||||
addr32
|
||||
movb %al, %es:(%ecx) /* and transfer it to the name buffer */
|
||||
incl %ebx /* get on with the next byte */
|
||||
incl %ecx /* get on with the next byte */
|
||||
testb %al, %al /* if it was 0 then quit this */
|
||||
data32
|
||||
jnz nxtbyte /* and looop if more to do */
|
||||
|
||||
/*
|
||||
* restore the saved settings and
|
||||
* zero it out so next time we don't try it again
|
||||
*/
|
||||
data32
|
||||
pop %ebx /* get back our starting location */
|
||||
#ifdef NAMEBLOCK_WRITEBACK
|
||||
nxtbyte2:
|
||||
addr32
|
||||
movb %es:(%ebx), %al /* get the byte */
|
||||
addr32
|
||||
movb $0, %es:(%ebx) /* zero it out */
|
||||
data32
|
||||
incl %ebx /* point to the next byte */
|
||||
testb %al, %al /* check if we have finished.. */
|
||||
data32
|
||||
jne nxtbyte2
|
||||
/*
|
||||
* Write the second sector back
|
||||
* Load the second sector
|
||||
* BIOS call "INT 0x13 Function 0x3" to write sectors from memory to disk
|
||||
* Call with %ah = 0x3
|
||||
* %al = number of sectors
|
||||
* %ch = cylinder
|
||||
* %cl = sector
|
||||
* %dh = head
|
||||
* %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
|
||||
* %es:%bx = segment:offset of buffer
|
||||
* Return:
|
||||
* %al = 0x0 on success; err code on failure
|
||||
*/
|
||||
data32
|
||||
movl $0x0301, %eax /* write 1 sector */
|
||||
xor %ebx, %ebx /* buffer is at offset 0 */
|
||||
data32
|
||||
movl $0x0002, %ecx /* block 2 */
|
||||
data32
|
||||
andl $0xff, %edx /* head 0 */
|
||||
int $0x13
|
||||
data32
|
||||
jnb notours
|
||||
data32
|
||||
mov $eread, %esi
|
||||
jmp err_stop
|
||||
#endif /* NAMEBLOCK_WRITEBACK */
|
||||
/*
|
||||
* return to the main-line
|
||||
*/
|
||||
notours:
|
||||
data32
|
||||
pop %edx
|
||||
data32
|
||||
pop %ecx
|
||||
#endif
|
||||
data32
|
||||
mov $LOADSZ, %ebx
|
||||
addr32
|
||||
@ -334,15 +509,16 @@ vram:
|
||||
|
||||
/* error messages */
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
one: String "1\r\n\0"
|
||||
two: String "2\r\n\0"
|
||||
three: String "3\r\n\0"
|
||||
four: String "4\r\n\0"
|
||||
five: String "5\r\n\0"
|
||||
six: String "6\r\n\0"
|
||||
seven: String "7\r\n\0"
|
||||
one: String "1-\0"
|
||||
two: String "2-\0"
|
||||
three: String "3-\0"
|
||||
four: String "4-\0"
|
||||
#endif DEBUG
|
||||
#ifdef NAMEBLOCK_WRITEBACK
|
||||
ewrite: String "Write error\r\n\0"
|
||||
#endif /* NAMEBLOCK_WRITEBACK */
|
||||
eread: String "Read error\r\n\0"
|
||||
enoboot: String "No bootable partition\r\n\0"
|
||||
endofcode:
|
||||
|
@ -12,11 +12,12 @@ extern int hostnamelen;
|
||||
extern unsigned long netmask;
|
||||
extern eth_reset();
|
||||
extern short aui;
|
||||
extern int howto;
|
||||
|
||||
int cmd_ip(), cmd_server(), cmd_kernel(), cmd_help(), exit();
|
||||
int cmd_rootfs(), cmd_swapfs(), cmd_interface(), cmd_hostname();
|
||||
int cmd_netmask(), cmd_swapsize(), cmd_swapopts(), cmd_rootopts();
|
||||
int cmd_aui(), cmd_gateway();
|
||||
int cmd_aui(), cmd_gateway(), cmd_flags();
|
||||
|
||||
struct bootcmds_t {
|
||||
char *name;
|
||||
@ -39,6 +40,7 @@ struct bootcmds_t {
|
||||
{"diskboot", exit, " boot from disk"},
|
||||
{"autoboot", NULL, " continue"},
|
||||
{"trans", cmd_aui, "<on|off> turn transceiver on|off"},
|
||||
{"flags", cmd_flags, "[bcdhsv] set boot flags"},
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
@ -283,6 +285,32 @@ cmd_swapopts(p)
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
CMD_FLAGS - Set boot flags
|
||||
**************************************************************************/
|
||||
cmd_flags(buf)
|
||||
char *buf;
|
||||
{
|
||||
char p;
|
||||
int flags = 0;
|
||||
|
||||
while ((p = *buf++))
|
||||
switch (p) {
|
||||
case 'b': flags |= RB_HALT; break;
|
||||
case 'c': flags |= RB_CONFIG; break;
|
||||
case 'd': flags |= RB_KDB; break;
|
||||
case 'h': flags ^= RB_SERIAL; break;
|
||||
case 's': flags |= RB_SINGLE; break;
|
||||
case 'v': flags |= RB_VERBOSE; break;
|
||||
case ' ':
|
||||
case '\t': break;
|
||||
default: printf("Unknown boot flag: %c\n", p);
|
||||
}
|
||||
|
||||
howto = flags;
|
||||
return(0);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
EXECUTE - Decode command
|
||||
**************************************************************************/
|
||||
|
@ -24,7 +24,7 @@ struct bootinfo bootinfo;
|
||||
int root_nfs_port;
|
||||
unsigned long netmask;
|
||||
char kernel_handle[32];
|
||||
int offset;
|
||||
int offset, howto;
|
||||
|
||||
extern char eth_driver[];
|
||||
extern char packet[];
|
||||
@ -320,7 +320,7 @@ load()
|
||||
bootinfo.bi_nfs_diskless = &nfsdiskless;
|
||||
bootinfo.bi_size = sizeof bootinfo;
|
||||
kernelentry = (void *)(head.a_entry & 0x00FFFFFF);
|
||||
(*kernelentry)(RB_BOOTINFO,NODEV,0,0,0,&bootinfo,0,0,0);
|
||||
(*kernelentry)(howto|RB_BOOTINFO,NODEV,0,0,0,&bootinfo,0,0,0);
|
||||
printf("*** %s execute failure ***\n",kernel);
|
||||
}
|
||||
|
||||
|
@ -75,6 +75,10 @@ eth_probe()
|
||||
for (eth_asic_base = WD_LOW_BASE; eth_asic_base <= WD_HIGH_BASE;
|
||||
eth_asic_base += 0x20) {
|
||||
chksum = 0;
|
||||
/* Check for WD/SMC card by checking ethernet address */
|
||||
if (inb(eth_asic_base+8) != 0) continue;
|
||||
if (inb(eth_asic_base+9) != 0) continue;
|
||||
if (inb(eth_asic_base+10) != 0xC0) continue;
|
||||
for (i=8; i<16; i++)
|
||||
chksum += inb(i+eth_asic_base);
|
||||
if ((chksum & 0x00FF) == 0x00FF)
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
|
||||
* $Id: clock.c,v 1.58 1996/05/01 08:39:02 bde Exp $
|
||||
* $Id: clock.c,v 1.1.1.1 1996/06/14 10:04:42 asami Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -46,13 +46,14 @@
|
||||
|
||||
/*
|
||||
* modified for PC98
|
||||
* $Id: clock.c,v 1.7 1994/03/26 22:56:13 kakefuda Exp kakefuda $
|
||||
* $Id: clock.c,v 1.1.1.1 1996/06/14 10:04:42 asami Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Primitive clock interrupt routines.
|
||||
*/
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_clock.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -100,13 +101,13 @@
|
||||
#define TIMER0_LATCH_COUNT 20
|
||||
|
||||
/*
|
||||
* Minimum maximum count that we are willing to program into timer0.
|
||||
* Must be large enough to guarantee that the timer interrupt handler
|
||||
* returns before the next timer interrupt. Must be larger than
|
||||
* TIMER0_LATCH_COUNT so that we don't have to worry about underflow in
|
||||
* the calculation of timer0_overflow_threshold.
|
||||
* Maximum frequency that we are willing to allow for timer0. Must be
|
||||
* low enough to guarantee that the timer interrupt handler returns
|
||||
* before the next timer interrupt. Must result in a lower TIMER_DIV
|
||||
* value than TIMER0_LATCH_COUNT so that we don't have to worry about
|
||||
* underflow in the calculation of timer0_overflow_threshold.
|
||||
*/
|
||||
#define TIMER0_MIN_MAX_COUNT TIMER_DIV(20000)
|
||||
#define TIMER0_MAX_FREQ 20000
|
||||
|
||||
int adjkerntz; /* local offset from GMT in seconds */
|
||||
int disable_rtc_set; /* disable resettodr() if != 0 */
|
||||
@ -122,28 +123,6 @@ unsigned long i586_avg_tick;
|
||||
#endif
|
||||
int statclock_disable;
|
||||
u_int stat_imask = SWI_CLOCK_MASK;
|
||||
int timer0_max_count;
|
||||
u_int timer0_overflow_threshold;
|
||||
u_int timer0_prescaler_count;
|
||||
|
||||
static int beeping = 0;
|
||||
static u_int clk_imask = HWI_MASK | SWI_MASK;
|
||||
static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31};
|
||||
static u_int hardclock_max_count;
|
||||
/*
|
||||
* XXX new_function and timer_func should not handle clockframes, but
|
||||
* timer_func currently needs to hold hardclock to handle the
|
||||
* timer0_state == 0 case. We should use register_intr()/unregister_intr()
|
||||
* to switch between clkintr() and a slightly different timerintr().
|
||||
* This will require locking when acquiring and releasing timer0 - the
|
||||
* current (nonexistent) locking doesn't seem to be adequate even now.
|
||||
*/
|
||||
static void (*new_function) __P((struct clockframe *frame));
|
||||
static u_int new_rate;
|
||||
#ifndef PC98
|
||||
static u_char rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
|
||||
static u_char rtc_statusb = RTCSB_24HR | RTCSB_PINTR;
|
||||
#endif
|
||||
#ifdef TIMER_FREQ
|
||||
static u_int timer_freq = TIMER_FREQ;
|
||||
#else
|
||||
@ -161,31 +140,52 @@ static u_int timer_freq = 2457600;
|
||||
static u_int timer_freq = 1193182;
|
||||
#endif /* PC98 */
|
||||
#endif
|
||||
static char timer0_state = 0;
|
||||
#ifdef PC98
|
||||
static char timer1_state = 0;
|
||||
int timer0_max_count;
|
||||
u_int timer0_overflow_threshold;
|
||||
u_int timer0_prescaler_count;
|
||||
|
||||
static int beeping = 0;
|
||||
static u_int clk_imask = HWI_MASK | SWI_MASK;
|
||||
static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31};
|
||||
static u_int hardclock_max_count;
|
||||
/*
|
||||
* XXX new_function and timer_func should not handle clockframes, but
|
||||
* timer_func currently needs to hold hardclock to handle the
|
||||
* timer0_state == 0 case. We should use register_intr()/unregister_intr()
|
||||
* to switch between clkintr() and a slightly different timerintr().
|
||||
*/
|
||||
static void (*new_function) __P((struct clockframe *frame));
|
||||
static u_int new_rate;
|
||||
#ifndef PC98
|
||||
static u_char rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
|
||||
static u_char rtc_statusb = RTCSB_24HR | RTCSB_PINTR;
|
||||
#endif
|
||||
static char timer2_state = 0;
|
||||
|
||||
/* Values for timerX_state: */
|
||||
#define RELEASED 0
|
||||
#define RELEASE_PENDING 1
|
||||
#define ACQUIRED 2
|
||||
#define ACQUIRE_PENDING 3
|
||||
|
||||
static u_char timer0_state;
|
||||
#ifdef PC98
|
||||
static u_char timer1_state;
|
||||
#endif
|
||||
static u_char timer2_state;
|
||||
static void (*timer_func) __P((struct clockframe *frame)) = hardclock;
|
||||
int rtc_inb __P((void));
|
||||
|
||||
#if 0
|
||||
void
|
||||
clkintr(struct clockframe frame)
|
||||
{
|
||||
hardclock(&frame);
|
||||
setdelayed();
|
||||
}
|
||||
#else
|
||||
static void
|
||||
clkintr(struct clockframe frame)
|
||||
{
|
||||
timer_func(&frame);
|
||||
switch (timer0_state) {
|
||||
case 0:
|
||||
|
||||
case RELEASED:
|
||||
setdelayed();
|
||||
break;
|
||||
case 1:
|
||||
|
||||
case ACQUIRED:
|
||||
if ((timer0_prescaler_count += timer0_max_count)
|
||||
>= hardclock_max_count) {
|
||||
hardclock(&frame);
|
||||
@ -193,7 +193,8 @@ clkintr(struct clockframe frame)
|
||||
timer0_prescaler_count -= hardclock_max_count;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
|
||||
case ACQUIRE_PENDING:
|
||||
setdelayed();
|
||||
timer0_max_count = TIMER_DIV(new_rate);
|
||||
timer0_overflow_threshold =
|
||||
@ -205,9 +206,10 @@ clkintr(struct clockframe frame)
|
||||
enable_intr();
|
||||
timer0_prescaler_count = 0;
|
||||
timer_func = new_function;
|
||||
timer0_state = 1;
|
||||
timer0_state = ACQUIRED;
|
||||
break;
|
||||
case 3:
|
||||
|
||||
case RELEASE_PENDING:
|
||||
if ((timer0_prescaler_count += timer0_max_count)
|
||||
>= hardclock_max_count) {
|
||||
hardclock(&frame);
|
||||
@ -248,84 +250,140 @@ clkintr(struct clockframe frame)
|
||||
}
|
||||
#endif /* AUTO_CLOCK */
|
||||
#else /* IBM-PC */
|
||||
time.tv_usec += (27645 *
|
||||
time.tv_usec += (27465 *
|
||||
(timer0_prescaler_count - hardclock_max_count))
|
||||
>> 15;
|
||||
#endif /* PC98 */
|
||||
if (time.tv_usec >= 1000000)
|
||||
time.tv_usec -= 1000000;
|
||||
timer0_prescaler_count = 0;
|
||||
timer_func = hardclock;;
|
||||
timer0_state = 0;
|
||||
timer_func = hardclock;
|
||||
timer0_state = RELEASED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The acquire and release functions must be called at ipl >= splclock().
|
||||
*/
|
||||
int
|
||||
acquire_timer0(int rate, void (*function) __P((struct clockframe *frame)))
|
||||
{
|
||||
if (timer0_state || TIMER_DIV(rate) < TIMER0_MIN_MAX_COUNT ||
|
||||
!function)
|
||||
return -1;
|
||||
static int old_rate;
|
||||
|
||||
if (rate <= 0 || rate > TIMER0_MAX_FREQ)
|
||||
return (-1);
|
||||
switch (timer0_state) {
|
||||
|
||||
case RELEASED:
|
||||
timer0_state = ACQUIRE_PENDING;
|
||||
break;
|
||||
|
||||
case RELEASE_PENDING:
|
||||
if (rate != old_rate)
|
||||
return (-1);
|
||||
/*
|
||||
* The timer has been released recently, but is being
|
||||
* re-acquired before the release completed. In this
|
||||
* case, we simply reclaim it as if it had not been
|
||||
* released at all.
|
||||
*/
|
||||
timer0_state = ACQUIRED;
|
||||
break;
|
||||
|
||||
default:
|
||||
return (-1); /* busy */
|
||||
}
|
||||
new_function = function;
|
||||
new_rate = rate;
|
||||
timer0_state = 2;
|
||||
return 0;
|
||||
old_rate = new_rate = rate;
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef PC98
|
||||
int
|
||||
acquire_timer1(int mode)
|
||||
{
|
||||
if (timer1_state)
|
||||
return -1;
|
||||
timer1_state = 1;
|
||||
outb(TIMER_MODE, TIMER_SEL1 | (mode &0x3f));
|
||||
return 0;
|
||||
|
||||
if (timer1_state != RELEASED)
|
||||
return (-1);
|
||||
timer1_state = ACQUIRED;
|
||||
|
||||
/*
|
||||
* This access to the timer registers is as atomic as possible
|
||||
* because it is a single instruction. We could do better if we
|
||||
* knew the rate. Use of splclock() limits glitches to 10-100us,
|
||||
* and this is probably good enough for timer2, so we aren't as
|
||||
* careful with it as with timer0.
|
||||
*/
|
||||
outb(TIMER_MODE, TIMER_SEL1 | (mode & 0x3f));
|
||||
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
acquire_timer2(int mode)
|
||||
{
|
||||
if (timer2_state)
|
||||
return -1;
|
||||
timer2_state = 1;
|
||||
outb(TIMER_MODE, TIMER_SEL2 | (mode &0x3f));
|
||||
return 0;
|
||||
|
||||
if (timer2_state != RELEASED)
|
||||
return (-1);
|
||||
timer2_state = ACQUIRED;
|
||||
|
||||
/*
|
||||
* This access to the timer registers is as atomic as possible
|
||||
* because it is a single instruction. We could do better if we
|
||||
* knew the rate. Use of splclock() limits glitches to 10-100us,
|
||||
* and this is probably good enough for timer2, so we aren't as
|
||||
* careful with it as with timer0.
|
||||
*/
|
||||
outb(TIMER_MODE, TIMER_SEL2 | (mode & 0x3f));
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
release_timer0()
|
||||
{
|
||||
if (!timer0_state)
|
||||
return -1;
|
||||
timer0_state = 3;
|
||||
return 0;
|
||||
switch (timer0_state) {
|
||||
|
||||
case ACQUIRED:
|
||||
timer0_state = RELEASE_PENDING;
|
||||
break;
|
||||
|
||||
case ACQUIRE_PENDING:
|
||||
/* Nothing happened yet, release quickly. */
|
||||
timer0_state = RELEASED;
|
||||
break;
|
||||
|
||||
default:
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef PC98
|
||||
int
|
||||
release_timer1()
|
||||
{
|
||||
if (!timer1_state)
|
||||
return -1;
|
||||
timer1_state = 0;
|
||||
outb(TIMER_MODE, TIMER_SEL1|TIMER_SQWAVE|TIMER_16BIT);
|
||||
return 0;
|
||||
|
||||
if (timer1_state != ACQUIRED)
|
||||
return (-1);
|
||||
timer1_state = RELEASED;
|
||||
outb(TIMER_MODE, TIMER_SEL1 | TIMER_SQWAVE | TIMER_16BIT);
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
release_timer2()
|
||||
{
|
||||
if (!timer2_state)
|
||||
return -1;
|
||||
timer2_state = 0;
|
||||
outb(TIMER_MODE, TIMER_SEL2|TIMER_SQWAVE|TIMER_16BIT);
|
||||
return 0;
|
||||
|
||||
if (timer2_state != ACQUIRED)
|
||||
return (-1);
|
||||
timer2_state = RELEASED;
|
||||
outb(TIMER_MODE, TIMER_SEL2 | TIMER_SQWAVE | TIMER_16BIT);
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifndef PC98
|
||||
@ -367,14 +425,19 @@ DDB_printrtc(void)
|
||||
static int
|
||||
getit(void)
|
||||
{
|
||||
u_long ef;
|
||||
int high, low;
|
||||
|
||||
ef = read_eflags();
|
||||
disable_intr();
|
||||
/* select timer0 and latch counter value */
|
||||
|
||||
/* Select timer0 and latch counter value. */
|
||||
outb(TIMER_MODE, TIMER_SEL0);
|
||||
|
||||
low = inb(TIMER_CNTR0);
|
||||
high = inb(TIMER_CNTR0);
|
||||
enable_intr();
|
||||
|
||||
write_eflags(ef);
|
||||
return ((high << 8) | low);
|
||||
}
|
||||
|
||||
@ -459,33 +522,45 @@ sysbeepstop(void *chan)
|
||||
int
|
||||
sysbeep(int pitch, int period)
|
||||
{
|
||||
int x = splclock();
|
||||
|
||||
#ifdef PC98
|
||||
if (acquire_timer1(TIMER_SQWAVE|TIMER_16BIT))
|
||||
return -1;
|
||||
if (!beeping) {
|
||||
/* Something else owns it. */
|
||||
splx(x);
|
||||
return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */
|
||||
}
|
||||
disable_intr();
|
||||
outb(0x3fdb, pitch);
|
||||
outb(0x3fdb, (pitch>>8));
|
||||
enable_intr();
|
||||
if (!beeping) {
|
||||
outb(IO_PPI, (inb(IO_PPI) & 0xf7)); /* enable counter1 output to speaker */
|
||||
/* enable counter1 output to speaker */
|
||||
outb(IO_PPI, (inb(IO_PPI) & 0xf7));
|
||||
beeping = period;
|
||||
timeout(sysbeepstop, (void *)NULL, period);
|
||||
}
|
||||
#else
|
||||
|
||||
if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT))
|
||||
return -1;
|
||||
if (!beeping) {
|
||||
/* Something else owns it. */
|
||||
splx(x);
|
||||
return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */
|
||||
}
|
||||
disable_intr();
|
||||
outb(TIMER_CNTR2, pitch);
|
||||
outb(TIMER_CNTR2, (pitch>>8));
|
||||
enable_intr();
|
||||
if (!beeping) {
|
||||
outb(IO_PPI, inb(IO_PPI) | 3); /* enable counter2 output to speaker */
|
||||
/* enable counter2 output to speaker */
|
||||
outb(IO_PPI, inb(IO_PPI) | 3);
|
||||
beeping = period;
|
||||
timeout(sysbeepstop, (void *)NULL, period);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
splx(x);
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifndef PC98
|
||||
@ -546,7 +621,7 @@ calibrate_clocks(void)
|
||||
u_int count, prev_count, tot_count;
|
||||
int sec, start_sec, timeout;
|
||||
|
||||
printf("Calibrating clock(s) relative to mc146818A clock ... ");
|
||||
printf("Calibrating clock(s) relative to mc146818A clock...\n");
|
||||
if (!(rtcin(RTC_STATUSD) & RTCSD_PWR))
|
||||
goto fail;
|
||||
timeout = 100000000;
|
||||
@ -639,9 +714,10 @@ calibrate_clocks(void)
|
||||
static void
|
||||
set_timer_freq(u_int freq, int intr_freq)
|
||||
{
|
||||
u_long ef;
|
||||
u_long ef;
|
||||
|
||||
ef = read_eflags();
|
||||
disable_intr();
|
||||
timer_freq = freq;
|
||||
timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq);
|
||||
timer0_overflow_threshold = timer0_max_count - TIMER0_LATCH_COUNT;
|
||||
@ -688,11 +764,7 @@ startrtclock()
|
||||
#endif
|
||||
|
||||
#ifndef PC98
|
||||
/*
|
||||
* Temporarily calibrate with a high intr_freq to get a low
|
||||
* timer0_max_count to help detect bogus i8254 counts.
|
||||
*/
|
||||
set_timer_freq(timer_freq, 20000);
|
||||
set_timer_freq(timer_freq, hz);
|
||||
freq = calibrate_clocks();
|
||||
#ifdef CLK_CALIBRATION_LOOP
|
||||
if (bootverbose) {
|
||||
@ -711,7 +783,8 @@ startrtclock()
|
||||
delta = freq > timer_freq ? freq - timer_freq : timer_freq - freq;
|
||||
if (delta < timer_freq / 100) {
|
||||
#ifndef CLK_USE_I8254_CALIBRATION
|
||||
printf(
|
||||
if (bootverbose)
|
||||
printf(
|
||||
"CLK_USE_I8254_CALIBRATION not specified - using default frequency\n");
|
||||
freq = timer_freq;
|
||||
#endif
|
||||
@ -731,7 +804,8 @@ startrtclock()
|
||||
#if defined(I586_CPU) || defined(I686_CPU)
|
||||
#ifndef CLK_USE_I586_CALIBRATION
|
||||
if (i586_ctr_rate != 0) {
|
||||
printf(
|
||||
if (bootverbose)
|
||||
printf(
|
||||
"CLK_USE_I586_CALIBRATION not specified - using old calibration method\n");
|
||||
i586_ctr_freq = 0;
|
||||
i586_ctr_rate = 0;
|
||||
@ -750,7 +824,9 @@ startrtclock()
|
||||
DELAY(1000000);
|
||||
i586_count = rdtsc();
|
||||
i586_ctr_rate = (i586_count << I586_CTR_RATE_SHIFT) / 1000000;
|
||||
#ifdef CLK_USE_I586_CALIBRATION
|
||||
printf("i586 clock: %u Hz\n", i586_ctr_freq);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -43,7 +43,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
|
||||
* $Id: fd.c,v 1.89 1996/05/03 20:15:11 phk Exp $
|
||||
* $Id: fd.c,v 1.1.1.1 1996/06/14 10:04:43 asami Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -430,7 +430,7 @@ static int fdformat(dev_t, struct fd_formb *, struct proc *);
|
||||
#define IOTIMEDOUT 11
|
||||
|
||||
#ifdef DEBUG
|
||||
char *fdstates[] =
|
||||
static char const * const fdstates[] =
|
||||
{
|
||||
"DEVIDLE",
|
||||
"FINDWORK",
|
||||
@ -447,7 +447,7 @@ char *fdstates[] =
|
||||
};
|
||||
|
||||
/* CAUTION: fd_debug causes huge amounts of logging output */
|
||||
int fd_debug = 0;
|
||||
static int volatile fd_debug = 0;
|
||||
#define TRACE0(arg) if(fd_debug) printf(arg)
|
||||
#define TRACE1(arg1, arg2) if(fd_debug) printf(arg1, arg2)
|
||||
#else /* DEBUG */
|
||||
@ -786,7 +786,10 @@ fdattach(struct isa_device *dev)
|
||||
fdcu_t fdcu = dev->id_unit;
|
||||
fdc_p fdc = fdc_data + fdcu;
|
||||
fd_p fd;
|
||||
int fdsu, st0, st3, i, unithasfd;
|
||||
int fdsu, st0, st3, i;
|
||||
#if NFT > 0
|
||||
int unithasfd;
|
||||
#endif
|
||||
#ifdef PC98
|
||||
struct pc98_device *fdup;
|
||||
#else
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
|
||||
* $Id: clock.c,v 1.58 1996/05/01 08:39:02 bde Exp $
|
||||
* $Id: clock.c,v 1.1.1.1 1996/06/14 10:04:42 asami Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -46,13 +46,14 @@
|
||||
|
||||
/*
|
||||
* modified for PC98
|
||||
* $Id: clock.c,v 1.7 1994/03/26 22:56:13 kakefuda Exp kakefuda $
|
||||
* $Id: clock.c,v 1.1.1.1 1996/06/14 10:04:42 asami Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Primitive clock interrupt routines.
|
||||
*/
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_clock.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -100,13 +101,13 @@
|
||||
#define TIMER0_LATCH_COUNT 20
|
||||
|
||||
/*
|
||||
* Minimum maximum count that we are willing to program into timer0.
|
||||
* Must be large enough to guarantee that the timer interrupt handler
|
||||
* returns before the next timer interrupt. Must be larger than
|
||||
* TIMER0_LATCH_COUNT so that we don't have to worry about underflow in
|
||||
* the calculation of timer0_overflow_threshold.
|
||||
* Maximum frequency that we are willing to allow for timer0. Must be
|
||||
* low enough to guarantee that the timer interrupt handler returns
|
||||
* before the next timer interrupt. Must result in a lower TIMER_DIV
|
||||
* value than TIMER0_LATCH_COUNT so that we don't have to worry about
|
||||
* underflow in the calculation of timer0_overflow_threshold.
|
||||
*/
|
||||
#define TIMER0_MIN_MAX_COUNT TIMER_DIV(20000)
|
||||
#define TIMER0_MAX_FREQ 20000
|
||||
|
||||
int adjkerntz; /* local offset from GMT in seconds */
|
||||
int disable_rtc_set; /* disable resettodr() if != 0 */
|
||||
@ -122,28 +123,6 @@ unsigned long i586_avg_tick;
|
||||
#endif
|
||||
int statclock_disable;
|
||||
u_int stat_imask = SWI_CLOCK_MASK;
|
||||
int timer0_max_count;
|
||||
u_int timer0_overflow_threshold;
|
||||
u_int timer0_prescaler_count;
|
||||
|
||||
static int beeping = 0;
|
||||
static u_int clk_imask = HWI_MASK | SWI_MASK;
|
||||
static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31};
|
||||
static u_int hardclock_max_count;
|
||||
/*
|
||||
* XXX new_function and timer_func should not handle clockframes, but
|
||||
* timer_func currently needs to hold hardclock to handle the
|
||||
* timer0_state == 0 case. We should use register_intr()/unregister_intr()
|
||||
* to switch between clkintr() and a slightly different timerintr().
|
||||
* This will require locking when acquiring and releasing timer0 - the
|
||||
* current (nonexistent) locking doesn't seem to be adequate even now.
|
||||
*/
|
||||
static void (*new_function) __P((struct clockframe *frame));
|
||||
static u_int new_rate;
|
||||
#ifndef PC98
|
||||
static u_char rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
|
||||
static u_char rtc_statusb = RTCSB_24HR | RTCSB_PINTR;
|
||||
#endif
|
||||
#ifdef TIMER_FREQ
|
||||
static u_int timer_freq = TIMER_FREQ;
|
||||
#else
|
||||
@ -161,31 +140,52 @@ static u_int timer_freq = 2457600;
|
||||
static u_int timer_freq = 1193182;
|
||||
#endif /* PC98 */
|
||||
#endif
|
||||
static char timer0_state = 0;
|
||||
#ifdef PC98
|
||||
static char timer1_state = 0;
|
||||
int timer0_max_count;
|
||||
u_int timer0_overflow_threshold;
|
||||
u_int timer0_prescaler_count;
|
||||
|
||||
static int beeping = 0;
|
||||
static u_int clk_imask = HWI_MASK | SWI_MASK;
|
||||
static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31};
|
||||
static u_int hardclock_max_count;
|
||||
/*
|
||||
* XXX new_function and timer_func should not handle clockframes, but
|
||||
* timer_func currently needs to hold hardclock to handle the
|
||||
* timer0_state == 0 case. We should use register_intr()/unregister_intr()
|
||||
* to switch between clkintr() and a slightly different timerintr().
|
||||
*/
|
||||
static void (*new_function) __P((struct clockframe *frame));
|
||||
static u_int new_rate;
|
||||
#ifndef PC98
|
||||
static u_char rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
|
||||
static u_char rtc_statusb = RTCSB_24HR | RTCSB_PINTR;
|
||||
#endif
|
||||
static char timer2_state = 0;
|
||||
|
||||
/* Values for timerX_state: */
|
||||
#define RELEASED 0
|
||||
#define RELEASE_PENDING 1
|
||||
#define ACQUIRED 2
|
||||
#define ACQUIRE_PENDING 3
|
||||
|
||||
static u_char timer0_state;
|
||||
#ifdef PC98
|
||||
static u_char timer1_state;
|
||||
#endif
|
||||
static u_char timer2_state;
|
||||
static void (*timer_func) __P((struct clockframe *frame)) = hardclock;
|
||||
int rtc_inb __P((void));
|
||||
|
||||
#if 0
|
||||
void
|
||||
clkintr(struct clockframe frame)
|
||||
{
|
||||
hardclock(&frame);
|
||||
setdelayed();
|
||||
}
|
||||
#else
|
||||
static void
|
||||
clkintr(struct clockframe frame)
|
||||
{
|
||||
timer_func(&frame);
|
||||
switch (timer0_state) {
|
||||
case 0:
|
||||
|
||||
case RELEASED:
|
||||
setdelayed();
|
||||
break;
|
||||
case 1:
|
||||
|
||||
case ACQUIRED:
|
||||
if ((timer0_prescaler_count += timer0_max_count)
|
||||
>= hardclock_max_count) {
|
||||
hardclock(&frame);
|
||||
@ -193,7 +193,8 @@ clkintr(struct clockframe frame)
|
||||
timer0_prescaler_count -= hardclock_max_count;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
|
||||
case ACQUIRE_PENDING:
|
||||
setdelayed();
|
||||
timer0_max_count = TIMER_DIV(new_rate);
|
||||
timer0_overflow_threshold =
|
||||
@ -205,9 +206,10 @@ clkintr(struct clockframe frame)
|
||||
enable_intr();
|
||||
timer0_prescaler_count = 0;
|
||||
timer_func = new_function;
|
||||
timer0_state = 1;
|
||||
timer0_state = ACQUIRED;
|
||||
break;
|
||||
case 3:
|
||||
|
||||
case RELEASE_PENDING:
|
||||
if ((timer0_prescaler_count += timer0_max_count)
|
||||
>= hardclock_max_count) {
|
||||
hardclock(&frame);
|
||||
@ -248,84 +250,140 @@ clkintr(struct clockframe frame)
|
||||
}
|
||||
#endif /* AUTO_CLOCK */
|
||||
#else /* IBM-PC */
|
||||
time.tv_usec += (27645 *
|
||||
time.tv_usec += (27465 *
|
||||
(timer0_prescaler_count - hardclock_max_count))
|
||||
>> 15;
|
||||
#endif /* PC98 */
|
||||
if (time.tv_usec >= 1000000)
|
||||
time.tv_usec -= 1000000;
|
||||
timer0_prescaler_count = 0;
|
||||
timer_func = hardclock;;
|
||||
timer0_state = 0;
|
||||
timer_func = hardclock;
|
||||
timer0_state = RELEASED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The acquire and release functions must be called at ipl >= splclock().
|
||||
*/
|
||||
int
|
||||
acquire_timer0(int rate, void (*function) __P((struct clockframe *frame)))
|
||||
{
|
||||
if (timer0_state || TIMER_DIV(rate) < TIMER0_MIN_MAX_COUNT ||
|
||||
!function)
|
||||
return -1;
|
||||
static int old_rate;
|
||||
|
||||
if (rate <= 0 || rate > TIMER0_MAX_FREQ)
|
||||
return (-1);
|
||||
switch (timer0_state) {
|
||||
|
||||
case RELEASED:
|
||||
timer0_state = ACQUIRE_PENDING;
|
||||
break;
|
||||
|
||||
case RELEASE_PENDING:
|
||||
if (rate != old_rate)
|
||||
return (-1);
|
||||
/*
|
||||
* The timer has been released recently, but is being
|
||||
* re-acquired before the release completed. In this
|
||||
* case, we simply reclaim it as if it had not been
|
||||
* released at all.
|
||||
*/
|
||||
timer0_state = ACQUIRED;
|
||||
break;
|
||||
|
||||
default:
|
||||
return (-1); /* busy */
|
||||
}
|
||||
new_function = function;
|
||||
new_rate = rate;
|
||||
timer0_state = 2;
|
||||
return 0;
|
||||
old_rate = new_rate = rate;
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef PC98
|
||||
int
|
||||
acquire_timer1(int mode)
|
||||
{
|
||||
if (timer1_state)
|
||||
return -1;
|
||||
timer1_state = 1;
|
||||
outb(TIMER_MODE, TIMER_SEL1 | (mode &0x3f));
|
||||
return 0;
|
||||
|
||||
if (timer1_state != RELEASED)
|
||||
return (-1);
|
||||
timer1_state = ACQUIRED;
|
||||
|
||||
/*
|
||||
* This access to the timer registers is as atomic as possible
|
||||
* because it is a single instruction. We could do better if we
|
||||
* knew the rate. Use of splclock() limits glitches to 10-100us,
|
||||
* and this is probably good enough for timer2, so we aren't as
|
||||
* careful with it as with timer0.
|
||||
*/
|
||||
outb(TIMER_MODE, TIMER_SEL1 | (mode & 0x3f));
|
||||
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
acquire_timer2(int mode)
|
||||
{
|
||||
if (timer2_state)
|
||||
return -1;
|
||||
timer2_state = 1;
|
||||
outb(TIMER_MODE, TIMER_SEL2 | (mode &0x3f));
|
||||
return 0;
|
||||
|
||||
if (timer2_state != RELEASED)
|
||||
return (-1);
|
||||
timer2_state = ACQUIRED;
|
||||
|
||||
/*
|
||||
* This access to the timer registers is as atomic as possible
|
||||
* because it is a single instruction. We could do better if we
|
||||
* knew the rate. Use of splclock() limits glitches to 10-100us,
|
||||
* and this is probably good enough for timer2, so we aren't as
|
||||
* careful with it as with timer0.
|
||||
*/
|
||||
outb(TIMER_MODE, TIMER_SEL2 | (mode & 0x3f));
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
release_timer0()
|
||||
{
|
||||
if (!timer0_state)
|
||||
return -1;
|
||||
timer0_state = 3;
|
||||
return 0;
|
||||
switch (timer0_state) {
|
||||
|
||||
case ACQUIRED:
|
||||
timer0_state = RELEASE_PENDING;
|
||||
break;
|
||||
|
||||
case ACQUIRE_PENDING:
|
||||
/* Nothing happened yet, release quickly. */
|
||||
timer0_state = RELEASED;
|
||||
break;
|
||||
|
||||
default:
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef PC98
|
||||
int
|
||||
release_timer1()
|
||||
{
|
||||
if (!timer1_state)
|
||||
return -1;
|
||||
timer1_state = 0;
|
||||
outb(TIMER_MODE, TIMER_SEL1|TIMER_SQWAVE|TIMER_16BIT);
|
||||
return 0;
|
||||
|
||||
if (timer1_state != ACQUIRED)
|
||||
return (-1);
|
||||
timer1_state = RELEASED;
|
||||
outb(TIMER_MODE, TIMER_SEL1 | TIMER_SQWAVE | TIMER_16BIT);
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
release_timer2()
|
||||
{
|
||||
if (!timer2_state)
|
||||
return -1;
|
||||
timer2_state = 0;
|
||||
outb(TIMER_MODE, TIMER_SEL2|TIMER_SQWAVE|TIMER_16BIT);
|
||||
return 0;
|
||||
|
||||
if (timer2_state != ACQUIRED)
|
||||
return (-1);
|
||||
timer2_state = RELEASED;
|
||||
outb(TIMER_MODE, TIMER_SEL2 | TIMER_SQWAVE | TIMER_16BIT);
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifndef PC98
|
||||
@ -367,14 +425,19 @@ DDB_printrtc(void)
|
||||
static int
|
||||
getit(void)
|
||||
{
|
||||
u_long ef;
|
||||
int high, low;
|
||||
|
||||
ef = read_eflags();
|
||||
disable_intr();
|
||||
/* select timer0 and latch counter value */
|
||||
|
||||
/* Select timer0 and latch counter value. */
|
||||
outb(TIMER_MODE, TIMER_SEL0);
|
||||
|
||||
low = inb(TIMER_CNTR0);
|
||||
high = inb(TIMER_CNTR0);
|
||||
enable_intr();
|
||||
|
||||
write_eflags(ef);
|
||||
return ((high << 8) | low);
|
||||
}
|
||||
|
||||
@ -459,33 +522,45 @@ sysbeepstop(void *chan)
|
||||
int
|
||||
sysbeep(int pitch, int period)
|
||||
{
|
||||
int x = splclock();
|
||||
|
||||
#ifdef PC98
|
||||
if (acquire_timer1(TIMER_SQWAVE|TIMER_16BIT))
|
||||
return -1;
|
||||
if (!beeping) {
|
||||
/* Something else owns it. */
|
||||
splx(x);
|
||||
return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */
|
||||
}
|
||||
disable_intr();
|
||||
outb(0x3fdb, pitch);
|
||||
outb(0x3fdb, (pitch>>8));
|
||||
enable_intr();
|
||||
if (!beeping) {
|
||||
outb(IO_PPI, (inb(IO_PPI) & 0xf7)); /* enable counter1 output to speaker */
|
||||
/* enable counter1 output to speaker */
|
||||
outb(IO_PPI, (inb(IO_PPI) & 0xf7));
|
||||
beeping = period;
|
||||
timeout(sysbeepstop, (void *)NULL, period);
|
||||
}
|
||||
#else
|
||||
|
||||
if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT))
|
||||
return -1;
|
||||
if (!beeping) {
|
||||
/* Something else owns it. */
|
||||
splx(x);
|
||||
return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */
|
||||
}
|
||||
disable_intr();
|
||||
outb(TIMER_CNTR2, pitch);
|
||||
outb(TIMER_CNTR2, (pitch>>8));
|
||||
enable_intr();
|
||||
if (!beeping) {
|
||||
outb(IO_PPI, inb(IO_PPI) | 3); /* enable counter2 output to speaker */
|
||||
/* enable counter2 output to speaker */
|
||||
outb(IO_PPI, inb(IO_PPI) | 3);
|
||||
beeping = period;
|
||||
timeout(sysbeepstop, (void *)NULL, period);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
splx(x);
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifndef PC98
|
||||
@ -546,7 +621,7 @@ calibrate_clocks(void)
|
||||
u_int count, prev_count, tot_count;
|
||||
int sec, start_sec, timeout;
|
||||
|
||||
printf("Calibrating clock(s) relative to mc146818A clock ... ");
|
||||
printf("Calibrating clock(s) relative to mc146818A clock...\n");
|
||||
if (!(rtcin(RTC_STATUSD) & RTCSD_PWR))
|
||||
goto fail;
|
||||
timeout = 100000000;
|
||||
@ -639,9 +714,10 @@ calibrate_clocks(void)
|
||||
static void
|
||||
set_timer_freq(u_int freq, int intr_freq)
|
||||
{
|
||||
u_long ef;
|
||||
u_long ef;
|
||||
|
||||
ef = read_eflags();
|
||||
disable_intr();
|
||||
timer_freq = freq;
|
||||
timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq);
|
||||
timer0_overflow_threshold = timer0_max_count - TIMER0_LATCH_COUNT;
|
||||
@ -688,11 +764,7 @@ startrtclock()
|
||||
#endif
|
||||
|
||||
#ifndef PC98
|
||||
/*
|
||||
* Temporarily calibrate with a high intr_freq to get a low
|
||||
* timer0_max_count to help detect bogus i8254 counts.
|
||||
*/
|
||||
set_timer_freq(timer_freq, 20000);
|
||||
set_timer_freq(timer_freq, hz);
|
||||
freq = calibrate_clocks();
|
||||
#ifdef CLK_CALIBRATION_LOOP
|
||||
if (bootverbose) {
|
||||
@ -711,7 +783,8 @@ startrtclock()
|
||||
delta = freq > timer_freq ? freq - timer_freq : timer_freq - freq;
|
||||
if (delta < timer_freq / 100) {
|
||||
#ifndef CLK_USE_I8254_CALIBRATION
|
||||
printf(
|
||||
if (bootverbose)
|
||||
printf(
|
||||
"CLK_USE_I8254_CALIBRATION not specified - using default frequency\n");
|
||||
freq = timer_freq;
|
||||
#endif
|
||||
@ -731,7 +804,8 @@ startrtclock()
|
||||
#if defined(I586_CPU) || defined(I686_CPU)
|
||||
#ifndef CLK_USE_I586_CALIBRATION
|
||||
if (i586_ctr_rate != 0) {
|
||||
printf(
|
||||
if (bootverbose)
|
||||
printf(
|
||||
"CLK_USE_I586_CALIBRATION not specified - using old calibration method\n");
|
||||
i586_ctr_freq = 0;
|
||||
i586_ctr_rate = 0;
|
||||
@ -750,7 +824,9 @@ startrtclock()
|
||||
DELAY(1000000);
|
||||
i586_count = rdtsc();
|
||||
i586_ctr_rate = (i586_count << I586_CTR_RATE_SHIFT) / 1000000;
|
||||
#ifdef CLK_USE_I586_CALIBRATION
|
||||
printf("i586 clock: %u Hz\n", i586_ctr_freq);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)com.c 7.5 (Berkeley) 5/16/91
|
||||
* $Id: sio.c,v 1.142 1996/05/02 09:34:40 phk Exp $
|
||||
* $Id: sio.c,v 1.1.1.1 1996/06/14 10:04:45 asami Exp $
|
||||
*/
|
||||
|
||||
#include "opt_comconsole.h"
|
||||
@ -138,14 +138,13 @@
|
||||
#include <machine/clock.h>
|
||||
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/icu.h> /* XXX just to get at `imen' */
|
||||
#include <pc98/pc98/pc98.h>
|
||||
#include <pc98/pc98/icu.h>
|
||||
#include <pc98/pc98/pc98_device.h>
|
||||
#include <pc98/pc98/sioreg.h>
|
||||
#include <pc98/pc98/ic/i8251.h>
|
||||
#include <pc98/pc98/ic/ns16550.h>
|
||||
#else
|
||||
#include <i386/isa/icu.h> /* XXX just to get at `imen' */
|
||||
#include <i386/isa/isa.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/sioreg.h>
|
||||
@ -330,7 +329,9 @@ struct com_s {
|
||||
struct termios lt_out;
|
||||
|
||||
bool_t do_timestamp;
|
||||
bool_t do_dcd_timestamp;
|
||||
struct timeval timestamp;
|
||||
struct timeval dcd_timestamp;
|
||||
|
||||
u_long bytes_in; /* statistics */
|
||||
u_long bytes_out;
|
||||
@ -366,8 +367,7 @@ struct com_s {
|
||||
* by `config', not here.
|
||||
*/
|
||||
|
||||
/* Interrupt handling entry points. */
|
||||
inthand2_t siointrts;
|
||||
/* Interrupt handling entry point. */
|
||||
void siopoll __P((void));
|
||||
|
||||
/* Device switch entry points. */
|
||||
@ -417,8 +417,6 @@ static char driver_name[] = "sio";
|
||||
static struct com_s *p_com_addr[NSIO];
|
||||
#define com_addr(unit) (p_com_addr[unit])
|
||||
|
||||
static struct timeval intr_timestamp;
|
||||
|
||||
#ifdef PC98
|
||||
struct pc98_driver siodriver = {
|
||||
#else
|
||||
@ -957,18 +955,6 @@ sioprobe(dev)
|
||||
disable_intr();
|
||||
/* EXTRA DELAY? */
|
||||
|
||||
/*
|
||||
* XXX DELAY() reenables CPU interrupts. This is a problem for
|
||||
* shared interrupts after the first device using one has been
|
||||
* successfully probed - config_isadev() has enabled the interrupt
|
||||
* in the ICU.
|
||||
*/
|
||||
#ifdef PC98
|
||||
outb(IO_ICU1 + 2, 0xff);
|
||||
#else
|
||||
outb(IO_ICU1 + 1, 0xff);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Initialize the speed and the word size and wait long enough to
|
||||
* drain the maximum of 16 bytes of junk in device output queues.
|
||||
@ -1042,7 +1028,7 @@ sioprobe(dev)
|
||||
failures[0] = inb(iobase + com_cfcr) - CFCR_8BITS;
|
||||
failures[1] = inb(iobase + com_ier) - IER_ETXRDY;
|
||||
failures[2] = inb(iobase + com_mcr) - mcr_image;
|
||||
DELAY(1000); /* XXX */
|
||||
DELAY(10000); /* Some internal modems need this time */
|
||||
if (idev->id_irq != 0)
|
||||
#ifdef PC98
|
||||
failures[3] = pc98_irq_pending(idev) ? 0 : 1;
|
||||
@ -1082,11 +1068,6 @@ sioprobe(dev)
|
||||
#endif
|
||||
failures[9] = (inb(iobase + com_iir) & IIR_IMASK) - IIR_NOPEND;
|
||||
|
||||
#ifdef PC98
|
||||
outb(IO_ICU1 + 2, imen); /* XXX */
|
||||
#else
|
||||
outb(IO_ICU1 + 1, imen); /* XXX */
|
||||
#endif
|
||||
enable_intr();
|
||||
|
||||
result = IO_COMSIZE;
|
||||
@ -1868,32 +1849,6 @@ siodtrwakeup(chan)
|
||||
wakeup(&com->dtr_wait);
|
||||
}
|
||||
|
||||
/* Interrupt routine for timekeeping purposes */
|
||||
void
|
||||
siointrts(unit)
|
||||
int unit;
|
||||
{
|
||||
/*
|
||||
* XXX microtime() reenables CPU interrupts. We can't afford to
|
||||
* be interrupted and don't want to slow down microtime(), so lock
|
||||
* out interrupts in another way.
|
||||
*/
|
||||
#ifdef PC98
|
||||
outb(IO_ICU1 + 2, 0xff);
|
||||
#else /* IBM-PC */
|
||||
outb(IO_ICU1 + 1, 0xff);
|
||||
#endif /* PC98 */
|
||||
microtime(&intr_timestamp);
|
||||
disable_intr();
|
||||
#ifdef PC98
|
||||
outb(IO_ICU1 + 2, imen);
|
||||
#else /* IBM_PC */
|
||||
outb(IO_ICU1 + 1, imen);
|
||||
#endif /* PC98 */
|
||||
|
||||
siointr(unit);
|
||||
}
|
||||
|
||||
void
|
||||
siointr(unit)
|
||||
int unit;
|
||||
@ -1947,9 +1902,6 @@ siointr1(com)
|
||||
recv_data=0;
|
||||
#endif /* PC98 */
|
||||
|
||||
if (com->do_timestamp)
|
||||
/* XXX a little bloat here... */
|
||||
com->timestamp = intr_timestamp;
|
||||
while (TRUE) {
|
||||
#ifdef PC98
|
||||
status_read:;
|
||||
@ -2024,6 +1976,8 @@ status_read:;
|
||||
if (ioptr >= com->ibufend)
|
||||
CE_RECORD(com, CE_INTERRUPT_BUF_OVERFLOW);
|
||||
else {
|
||||
if (com->do_timestamp)
|
||||
microtime(&com->timestamp);
|
||||
++com_events;
|
||||
schedsofttty();
|
||||
#if 0 /* for testing input latency vs efficiency */
|
||||
@ -2064,6 +2018,11 @@ if (com->iptr - com->ibuf == 8)
|
||||
#endif
|
||||
modem_status = inb(com->modem_status_port);
|
||||
if (modem_status != com->last_modem_status) {
|
||||
if (com->do_dcd_timestamp
|
||||
&& !(com->last_modem_status & MSR_DCD)
|
||||
&& modem_status & MSR_DCD)
|
||||
microtime(&com->dcd_timestamp);
|
||||
|
||||
/*
|
||||
* Schedule high level to handle DCD changes. Note
|
||||
* that we don't use the delta bits anywhere. Some
|
||||
@ -2115,11 +2074,7 @@ if (com->iptr - com->ibuf == 8)
|
||||
com->obufq.l_head = ioptr;
|
||||
if (ioptr >= com->obufq.l_tail) {
|
||||
struct lbq *qp;
|
||||
#ifdef PC98
|
||||
if(IS_8251(com->pc98_if_type))
|
||||
if ( pc98_check_i8251_interrupt(com) & IEN_TxFLAG )
|
||||
com_int_Tx_disable(com);
|
||||
#endif
|
||||
|
||||
qp = com->obufq.l_next;
|
||||
qp->l_queued = FALSE;
|
||||
qp = qp->l_next;
|
||||
@ -2130,6 +2085,11 @@ if (com->iptr - com->ibuf == 8)
|
||||
} else {
|
||||
/* output just completed */
|
||||
com->state &= ~CS_BUSY;
|
||||
#if defined(PC98)
|
||||
if(IS_8251(com->pc98_if_type))
|
||||
if ( pc98_check_i8251_interrupt(com) & IEN_TxFLAG )
|
||||
com_int_Tx_disable(com);
|
||||
#endif
|
||||
}
|
||||
if (!(com->state & CS_ODONE)) {
|
||||
com_events += LOTS_OF_EVENTS;
|
||||
@ -2331,6 +2291,10 @@ sioioctl(dev, cmd, data, flag, p)
|
||||
com->do_timestamp = TRUE;
|
||||
*(struct timeval *)data = com->timestamp;
|
||||
break;
|
||||
case TIOCDCDTIMESTAMP:
|
||||
com->do_dcd_timestamp = TRUE;
|
||||
*(struct timeval *)data = com->dcd_timestamp;
|
||||
break;
|
||||
default:
|
||||
splx(s);
|
||||
return (ENOTTY);
|
||||
@ -3199,9 +3163,6 @@ static void
|
||||
siocntxwait()
|
||||
{
|
||||
int timo;
|
||||
#ifdef PC98
|
||||
int tmp;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Wait for any pending transmission to finish. Required to avoid
|
||||
@ -3551,8 +3512,6 @@ pc98_get_modem_status(struct com_s *com)
|
||||
int stat, stat2;
|
||||
register int msr;
|
||||
|
||||
int ret;
|
||||
|
||||
stat = inb(com->sts_port);
|
||||
stat2 = inb(com->in_modem_port);
|
||||
msr = com->pc98_prev_modem_status
|
||||
@ -3763,7 +3722,7 @@ static void
|
||||
com_cflag_and_speed_set( struct com_s *com, int cflag, int speed)
|
||||
{
|
||||
int cfcr=0, count;
|
||||
int s, previnterrupt;
|
||||
int previnterrupt;
|
||||
|
||||
count = pc98_ttspeedtab( com, speed );
|
||||
if ( count < 0 ) return;
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# GENERIC -- Generic machine with WD/AHx/NCR/BTx family disks
|
||||
#
|
||||
# $Id: GENERIC,v 1.70 1996/05/13 04:29:13 nate Exp $
|
||||
# $Id: GENERIC98,v 1.1.1.1 1996/06/14 10:04:40 asami Exp $
|
||||
#
|
||||
|
||||
# GENERIC98 -- Generic PC98 machine with WD/SBIC55 disks
|
||||
@ -62,14 +62,8 @@ options COM_MULTIPORT
|
||||
# It is highly recomended to compile with following options, and to
|
||||
# record the panic messages and the result of trace command brefore
|
||||
# reporting a problem.
|
||||
#
|
||||
# If you need more information for the kernel, KTRACE option may help
|
||||
# you.
|
||||
#
|
||||
options DDB
|
||||
options DIAGNOSTIC
|
||||
#options KTRACE
|
||||
|
||||
|
||||
config kernel root on wd0
|
||||
|
||||
@ -138,7 +132,7 @@ device sio2 at nec? port 0x8d2 tty flags 0x101 vector siointr
|
||||
device ed0 at nec? port 0x00d0 net irq 6 vector edintr
|
||||
device ed1 at nec? port 0x56d0 net irq 5 vector edintr
|
||||
device ed2 at nec? port 0x00d0 net irq 6 iomem 0xd0000 iosiz 16384 vector edintr
|
||||
device fe0 at nec? prot 0x00d0 net irq 3 vector feintr
|
||||
device fe0 at nec? port 0x00d0 net irq 3 vector feintr
|
||||
device zp0 at nec? port 0x0300 net irq 10 iomem 0xe0000 vector zpintr
|
||||
device ep0 at nec? port 0x00d0 net irq 6 vector epintr
|
||||
|
||||
@ -160,5 +154,10 @@ pseudo-device sl 2
|
||||
#pseudo-device ppp 1
|
||||
pseudo-device tun 1
|
||||
pseudo-device pty 16
|
||||
# keep this if you want to be able to continue to use /stand/sysinstall
|
||||
pseudo-device gzip # Exec gzipped a.out's
|
||||
|
||||
# KTRACE enables the system-call tracing facility ktrace(2).
|
||||
# This adds 4 KB bloat to your kernel, and slightly increases
|
||||
# the costs of each syscall.
|
||||
options KTRACE #kernel tracing
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# GENERIC -- Generic machine with WD/AHx/NCR/BTx family disks
|
||||
#
|
||||
# $Id: GENERIC,v 1.70 1996/05/13 04:29:13 nate Exp $
|
||||
# $Id: GENERIC98,v 1.1.1.1 1996/06/14 10:04:40 asami Exp $
|
||||
#
|
||||
|
||||
# GENERIC98 -- Generic PC98 machine with WD/SBIC55 disks
|
||||
@ -62,14 +62,8 @@ options COM_MULTIPORT
|
||||
# It is highly recomended to compile with following options, and to
|
||||
# record the panic messages and the result of trace command brefore
|
||||
# reporting a problem.
|
||||
#
|
||||
# If you need more information for the kernel, KTRACE option may help
|
||||
# you.
|
||||
#
|
||||
options DDB
|
||||
options DIAGNOSTIC
|
||||
#options KTRACE
|
||||
|
||||
|
||||
config kernel root on wd0
|
||||
|
||||
@ -138,7 +132,7 @@ device sio2 at nec? port 0x8d2 tty flags 0x101 vector siointr
|
||||
device ed0 at nec? port 0x00d0 net irq 6 vector edintr
|
||||
device ed1 at nec? port 0x56d0 net irq 5 vector edintr
|
||||
device ed2 at nec? port 0x00d0 net irq 6 iomem 0xd0000 iosiz 16384 vector edintr
|
||||
device fe0 at nec? prot 0x00d0 net irq 3 vector feintr
|
||||
device fe0 at nec? port 0x00d0 net irq 3 vector feintr
|
||||
device zp0 at nec? port 0x0300 net irq 10 iomem 0xe0000 vector zpintr
|
||||
device ep0 at nec? port 0x00d0 net irq 6 vector epintr
|
||||
|
||||
@ -160,5 +154,10 @@ pseudo-device sl 2
|
||||
#pseudo-device ppp 1
|
||||
pseudo-device tun 1
|
||||
pseudo-device pty 16
|
||||
# keep this if you want to be able to continue to use /stand/sysinstall
|
||||
pseudo-device gzip # Exec gzipped a.out's
|
||||
|
||||
# KTRACE enables the system-call tracing facility ktrace(2).
|
||||
# This adds 4 KB bloat to your kernel, and slightly increases
|
||||
# the costs of each syscall.
|
||||
options KTRACE #kernel tracing
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
# Makefile.i386 -- with config changes.
|
||||
# Copyright 1990 W. Jolitz
|
||||
# from: @(#)Makefile.i386 7.1 5/10/91
|
||||
# $Id: Makefile.i386,v 1.84 1996/06/08 23:27:16 jkh Exp $
|
||||
# $Id: Makefile.pc98,v 1.1.1.1 1996/06/14 10:04:40 asami Exp $
|
||||
#
|
||||
# Makefile for FreeBSD
|
||||
#
|
||||
@ -31,7 +31,7 @@ I386= ${S}/i386
|
||||
|
||||
CWARNFLAGS?= -W -Wreturn-type -Wcomment -Wredundant-decls -Wimplicit \
|
||||
-Wnested-externs -Wstrict-prototypes -Wmissing-prototypes \
|
||||
-Winline
|
||||
-Winline -Wunused
|
||||
#
|
||||
# The following flags are next up for working on:
|
||||
# -Wall
|
||||
|
@ -2,7 +2,7 @@
|
||||
# files marked standard are always included.
|
||||
#
|
||||
# modified for PC-9801 after:
|
||||
# $Id: files.i386,v 1.136 1996/06/07 22:26:59 nate Exp $
|
||||
# $Id: files.pc98,v 1.1.1.1 1996/06/14 10:04:40 asami Exp $
|
||||
#
|
||||
aic7xxx_asm optional ahc device-driver \
|
||||
dependency "$S/dev/aic7xxx/aic7xxx_asm.c" \
|
||||
@ -42,11 +42,13 @@ i386/i386/db_disasm.c optional ddb
|
||||
i386/i386/db_interface.c optional ddb
|
||||
i386/i386/db_trace.c optional ddb
|
||||
pc98/i386/exception.s standard
|
||||
i386/i386/identcpu.c standard
|
||||
i386/i386/in_cksum.c optional inet
|
||||
# locore.s needs to be handled in Makefile to put it first. Otherwise it's
|
||||
# now normal.
|
||||
# i386/i386/locore.s standard
|
||||
pc98/i386/machdep.c standard
|
||||
pc98/pc98/pc98_machdep.c standard
|
||||
i386/i386/math_emulate.c optional math_emulate
|
||||
i386/i386/mem.c standard
|
||||
pc98/i386/microtime.s standard
|
||||
@ -112,6 +114,7 @@ pc98/pc98/if_fe.c optional fe device-driver
|
||||
#pc98/isa/if_ix.c optional ix device-driver
|
||||
#pc98/isa/if_le.c optional le device-driver
|
||||
#pc98/isa/if_lnc.c optional lnc device-driver
|
||||
#i386/isa/if_sr.c optional sr device-driver
|
||||
#pc98/isa/if_ze.c optional ze device-driver
|
||||
pc98/pc98/if_zp.c optional zp device-driver
|
||||
pc98/pc98/pc98.c optional nec device-driver
|
||||
|
@ -1,4 +1,4 @@
|
||||
$Id: majors.i386,v 1.5 1996/05/04 08:40:13 peter Exp $
|
||||
$Id: majors.pc98,v 1.1.1.1 1996/06/14 10:04:40 asami Exp $
|
||||
|
||||
Hopefully, this list will one day be obsoleted by DEVFS, but for now
|
||||
this is the current allocation of device major numbers.
|
||||
@ -113,3 +113,4 @@ chrdev name comments
|
||||
73 qcam quickcam
|
||||
74 ccd concatenated disk
|
||||
75 stli Stallion (intelligent cdk based) (gerg@stallion.oz.au)
|
||||
76 scc IBM Smart Capture Card (ohashi@mickey.ai.kyutech.ac.jp)
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: options.i386,v 1.13 1996/05/11 04:39:44 bde Exp $
|
||||
# $Id: options.pc98,v 1.1.1.1 1996/06/14 10:04:40 asami Exp $
|
||||
BOUNCEPAGES opt_bounce.h
|
||||
USER_LDT
|
||||
MATH_EMULATE opt_math_emulate.h
|
||||
@ -23,3 +23,7 @@ FAT_CURSOR opt_pcvt.h
|
||||
PCVT_FREEBSD opt_pcvt.h
|
||||
PCVT_SCANSET opt_pcvt.h
|
||||
XSERVER opt_pcvt.h
|
||||
|
||||
CLK_CALIBRATION_LOOP opt_clock.h
|
||||
CLK_USE_I8254_CALIBRATION opt_clock.h
|
||||
CLK_USE_I586_CALIBRATION opt_clock.h
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)locore.s 7.3 (Berkeley) 5/13/91
|
||||
* $Id: locore.s,v 1.72 1996/05/27 06:51:46 phk Exp $
|
||||
* $Id: locore.s,v 1.1.1.1 1996/06/14 10:04:41 asami Exp $
|
||||
*
|
||||
* originally from: locore.s, by William F. Jolitz
|
||||
*
|
||||
@ -116,7 +116,7 @@ _bootinfo: .space BOOTINFO_SIZE /* bootinfo that we can handle */
|
||||
|
||||
_KERNend: .long 0 /* phys addr end of kernel (just after bss) */
|
||||
physfree: .long 0 /* phys addr of next free page */
|
||||
upa: .long 0 /* phys addr of proc0's UPAGES */
|
||||
p0upa: .long 0 /* phys addr of proc0's UPAGES */
|
||||
p0upt: .long 0 /* phys addr of proc0's UPAGES page table */
|
||||
|
||||
.globl _IdlePTD
|
||||
@ -276,10 +276,10 @@ _pc98_system_parameter:
|
||||
|
||||
/* clear bss */
|
||||
/*
|
||||
* XXX this should be done a little earlier. (bde)
|
||||
* XXX this should be done a little earlier.
|
||||
*
|
||||
* XXX we don't check that there is memory for our bss or page tables
|
||||
* before using it. (bde)
|
||||
* XXX we don't check that there is memory for our bss and page tables
|
||||
* before using it.
|
||||
*
|
||||
* XXX the boot program somewhat bogusly clears the bss. We still have
|
||||
* to do it in case we were unzipped by kzipboot. Then the boot program
|
||||
@ -288,7 +288,7 @@ _pc98_system_parameter:
|
||||
* XXX the gdt and idt are still somewhere in the boot program. We
|
||||
* depend on the convention that the boot program is below 1MB and we
|
||||
* are above 1MB to keep the gdt and idt away from the bss and page
|
||||
* tables. The idT is only used if BDE_DEBUGGER is enabled.
|
||||
* tables. The idt is only used if BDE_DEBUGGER is enabled.
|
||||
*/
|
||||
movl $R(_end),%ecx
|
||||
movl $R(_edata),%edi
|
||||
@ -326,7 +326,7 @@ _pc98_system_parameter:
|
||||
#ifdef BDE_DEBUGGER
|
||||
/*
|
||||
* Complete the adjustments for paging so that we can keep tracing through
|
||||
* initi386() after the low (physical) addresses for the gdt and idT become
|
||||
* initi386() after the low (physical) addresses for the gdt and idt become
|
||||
* invalid.
|
||||
*/
|
||||
call bdb_commit_paging
|
||||
@ -916,7 +916,7 @@ over_symalloc:
|
||||
|
||||
/* Allocate UPAGES */
|
||||
ALLOCPAGES(UPAGES)
|
||||
movl %esi,R(upa)
|
||||
movl %esi,R(p0upa)
|
||||
addl $KERNBASE, %esi
|
||||
movl %esi, R(_proc0paddr)
|
||||
|
||||
@ -951,13 +951,13 @@ map_read_write:
|
||||
movl $1, %ecx
|
||||
fillkptphys(PG_RW)
|
||||
|
||||
/* Map proc0's page table for the UPAGES the physical way. */
|
||||
/* Map proc0's page table for the UPAGES. */
|
||||
movl R(p0upt), %eax
|
||||
movl $1, %ecx
|
||||
fillkptphys(PG_RW)
|
||||
|
||||
/* Map proc0s UPAGES the physical way */
|
||||
movl R(upa), %eax
|
||||
/* Map proc0's UPAGES in the physical way ... */
|
||||
movl R(p0upa), %eax
|
||||
movl $UPAGES, %ecx
|
||||
fillkptphys(PG_RW)
|
||||
|
||||
@ -966,13 +966,13 @@ map_read_write:
|
||||
movl $ISA_HOLE_LENGTH>>PAGE_SHIFT, %ecx
|
||||
fillkptphys(PG_RW|PG_N)
|
||||
|
||||
/* Map proc0s UPAGES in the special page table for this purpose. */
|
||||
movl R(upa), %eax
|
||||
/* Map proc0s UPAGES in the special page table for this purpose ... */
|
||||
movl R(p0upa), %eax
|
||||
movl $KSTKPTEOFF, %ebx
|
||||
movl $UPAGES, %ecx
|
||||
fillkpt(R(p0upt), PG_RW)
|
||||
|
||||
/* and put the page table in the pde. */
|
||||
/* ... and put the page table in the pde. */
|
||||
movl R(p0upt), %eax
|
||||
movl $KSTKPTDI, %ebx
|
||||
movl $1, %ecx
|
||||
|
@ -35,13 +35,10 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
|
||||
* $Id: machdep.c,v 1.192 1996/06/08 11:03:01 bde Exp $
|
||||
* $Id: machdep.c,v 1.1.1.1 1996/06/14 10:04:41 asami Exp $
|
||||
*/
|
||||
|
||||
#include "npx.h"
|
||||
#ifndef PC98
|
||||
#include "isa.h"
|
||||
#endif
|
||||
#include "opt_sysvipc.h"
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_bounce.h"
|
||||
@ -117,10 +114,9 @@
|
||||
#endif
|
||||
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/pc98.h>
|
||||
#include <pc98/pc98/pc98_device.h>
|
||||
#include <pc98/pc98/pc98_machdep.h>
|
||||
#else
|
||||
#include <i386/isa/isa.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/rtc.h>
|
||||
#endif
|
||||
@ -132,31 +128,12 @@ extern int ptrace_single_step __P((struct proc *p));
|
||||
extern int ptrace_write_u __P((struct proc *p, vm_offset_t off, int data));
|
||||
extern void dblfault_handler __P((void));
|
||||
|
||||
extern void i486_bzero __P((void *, size_t));
|
||||
extern void i586_bzero __P((void *, size_t));
|
||||
extern void i686_bzero __P((void *, size_t));
|
||||
extern void identifycpu(void); /* XXX header file */
|
||||
extern void earlysetcpuclass(void); /* same header file */
|
||||
|
||||
static void cpu_startup __P((void *));
|
||||
SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL)
|
||||
|
||||
static void identifycpu(void);
|
||||
|
||||
char machine[] = "i386";
|
||||
SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, "");
|
||||
|
||||
static char cpu_model[128];
|
||||
SYSCTL_STRING(_hw, HW_MODEL, model, CTLFLAG_RD, cpu_model, 0, "");
|
||||
|
||||
struct kern_devconf kdc_cpu0 = {
|
||||
0, 0, 0, /* filled in by dev_attach */
|
||||
"cpu", 0, { MDDT_CPU },
|
||||
0, 0, 0, CPU_EXTERNALLEN,
|
||||
0, /* CPU has no parent */
|
||||
0, /* no parentdata */
|
||||
DC_BUSY, /* the CPU is always busy */
|
||||
cpu_model, /* no sense in duplication */
|
||||
DC_CLS_CPU /* class */
|
||||
};
|
||||
|
||||
#ifndef PANIC_REBOOT_WAIT_TIME
|
||||
#define PANIC_REBOOT_WAIT_TIME 15 /* default to 15 seconds */
|
||||
@ -206,8 +183,6 @@ int boothowto = 0, bootverbose = 0, Maxmem = 0;
|
||||
static int badpages = 0;
|
||||
#ifdef PC98
|
||||
int Maxmem_under16M = 0;
|
||||
extern pt_entry_t *panic_kwin_pte;
|
||||
extern caddr_t panic_kwin;
|
||||
#endif
|
||||
long dumplo;
|
||||
extern int bootdev;
|
||||
@ -217,8 +192,6 @@ vm_offset_t phys_avail[10];
|
||||
/* must be 2 less so 0 0 can signal end of chunks */
|
||||
#define PHYS_AVAIL_ARRAY_END ((sizeof(phys_avail) / sizeof(vm_offset_t)) - 2)
|
||||
|
||||
int cpu_class = CPUCLASS_386; /* smallest common denominator */
|
||||
|
||||
static void dumpsys __P((void));
|
||||
static void setup_netisrs __P((struct linker_set *)); /* XXX declare elsewhere */
|
||||
|
||||
@ -258,9 +231,12 @@ cpu_startup(dummy)
|
||||
* Good {morning,afternoon,evening,night}.
|
||||
*/
|
||||
printf(version);
|
||||
cpu_class = i386_cpus[cpu].cpu_class;
|
||||
earlysetcpuclass();
|
||||
startrtclock();
|
||||
identifycpu();
|
||||
#ifdef PERFMON
|
||||
perfmon_init();
|
||||
#endif
|
||||
printf("real memory = %d (%dK bytes)\n", ptoa(Maxmem), ptoa(Maxmem) / 1024);
|
||||
/*
|
||||
* Display any holes after the first chunk of extended memory.
|
||||
@ -499,176 +475,6 @@ setup_netisrs(ls)
|
||||
}
|
||||
}
|
||||
|
||||
static struct cpu_nameclass i386_cpus[] = {
|
||||
{ "Intel 80286", CPUCLASS_286 }, /* CPU_286 */
|
||||
{ "i386SX", CPUCLASS_386 }, /* CPU_386SX */
|
||||
{ "i386DX", CPUCLASS_386 }, /* CPU_386 */
|
||||
{ "i486SX", CPUCLASS_486 }, /* CPU_486SX */
|
||||
{ "i486DX", CPUCLASS_486 }, /* CPU_486 */
|
||||
{ "Pentium", CPUCLASS_586 }, /* CPU_586 */
|
||||
{ "Cy486DLC", CPUCLASS_486 }, /* CPU_486DLC */
|
||||
{ "Pentium Pro", CPUCLASS_686 }, /* CPU_686 */
|
||||
};
|
||||
|
||||
static void
|
||||
identifycpu()
|
||||
{
|
||||
printf("CPU: ");
|
||||
strncpy(cpu_model, i386_cpus[cpu].cpu_name, sizeof cpu_model);
|
||||
|
||||
#if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU)
|
||||
if (!strcmp(cpu_vendor,"GenuineIntel")) {
|
||||
if ((cpu_id & 0xf00) > 3) {
|
||||
cpu_model[0] = '\0';
|
||||
|
||||
switch (cpu_id & 0x3000) {
|
||||
case 0x1000:
|
||||
strcpy(cpu_model, "Overdrive ");
|
||||
break;
|
||||
case 0x2000:
|
||||
strcpy(cpu_model, "Dual ");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (cpu_id & 0xf00) {
|
||||
case 0x400:
|
||||
strcat(cpu_model, "i486 ");
|
||||
break;
|
||||
case 0x500:
|
||||
strcat(cpu_model, "Pentium"); /* nb no space */
|
||||
break;
|
||||
case 0x600:
|
||||
strcat(cpu_model, "Pentium Pro");
|
||||
break;
|
||||
default:
|
||||
strcat(cpu_model, "unknown");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (cpu_id & 0xff0) {
|
||||
case 0x400:
|
||||
strcat(cpu_model, "DX"); break;
|
||||
case 0x410:
|
||||
strcat(cpu_model, "DX"); break;
|
||||
case 0x420:
|
||||
strcat(cpu_model, "SX"); break;
|
||||
case 0x430:
|
||||
strcat(cpu_model, "DX2"); break;
|
||||
case 0x440:
|
||||
strcat(cpu_model, "SL"); break;
|
||||
case 0x450:
|
||||
strcat(cpu_model, "SX2"); break;
|
||||
case 0x470:
|
||||
strcat(cpu_model, "DX2 Write-Back Enhanced");
|
||||
break;
|
||||
case 0x480:
|
||||
strcat(cpu_model, "DX4"); break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
printf("%s (", cpu_model);
|
||||
switch(cpu_class) {
|
||||
case CPUCLASS_286:
|
||||
printf("286");
|
||||
break;
|
||||
#if defined(I386_CPU)
|
||||
case CPUCLASS_386:
|
||||
printf("386");
|
||||
break;
|
||||
#endif
|
||||
#if defined(I486_CPU)
|
||||
case CPUCLASS_486:
|
||||
printf("486");
|
||||
bzero = i486_bzero;
|
||||
break;
|
||||
#endif
|
||||
#if defined(I586_CPU)
|
||||
case CPUCLASS_586:
|
||||
printf("%d.%02d-MHz ",
|
||||
((100 * i586_ctr_rate) >> I586_CTR_RATE_SHIFT) / 100,
|
||||
((100 * i586_ctr_rate) >> I586_CTR_RATE_SHIFT) % 100);
|
||||
printf("586");
|
||||
break;
|
||||
#endif
|
||||
#if defined(I686_CPU)
|
||||
case CPUCLASS_686:
|
||||
printf("%d.%02d-MHz ",
|
||||
((100 * i586_ctr_rate) >> I586_CTR_RATE_SHIFT) / 100,
|
||||
((100 * i586_ctr_rate) >> I586_CTR_RATE_SHIFT) % 100);
|
||||
printf("686");
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
printf("unknown"); /* will panic below... */
|
||||
}
|
||||
printf("-class CPU)\n");
|
||||
#if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU)
|
||||
if(*cpu_vendor)
|
||||
printf(" Origin = \"%s\"",cpu_vendor);
|
||||
if(cpu_id)
|
||||
printf(" Id = 0x%lx",cpu_id);
|
||||
|
||||
if (!strcmp(cpu_vendor, "GenuineIntel")) {
|
||||
printf(" Stepping=%ld", cpu_id & 0xf);
|
||||
if (cpu_high > 0) {
|
||||
printf("\n Features=0x%b", cpu_feature,
|
||||
"\020"
|
||||
"\001FPU"
|
||||
"\002VME"
|
||||
"\003DE"
|
||||
"\004PSE"
|
||||
"\005TSC"
|
||||
"\006MSR"
|
||||
"\007PAE"
|
||||
"\010MCE"
|
||||
"\011CX8"
|
||||
"\012APIC"
|
||||
"\013<b10>"
|
||||
"\014<b11>"
|
||||
"\015MTRR"
|
||||
"\016PGE"
|
||||
"\017MCA"
|
||||
"\020CMOV"
|
||||
);
|
||||
}
|
||||
}
|
||||
/* Avoid ugly blank lines: only print newline when we have to. */
|
||||
if (*cpu_vendor || cpu_id)
|
||||
printf("\n");
|
||||
#endif
|
||||
/*
|
||||
* Now that we have told the user what they have,
|
||||
* let them know if that machine type isn't configured.
|
||||
*/
|
||||
switch (cpu_class) {
|
||||
case CPUCLASS_286: /* a 286 should not make it this far, anyway */
|
||||
#if !defined(I386_CPU) && !defined(I486_CPU) && !defined(I586_CPU) && !defined(I686_CPU)
|
||||
#error This kernel is not configured for one of the supported CPUs
|
||||
#endif
|
||||
#if !defined(I386_CPU)
|
||||
case CPUCLASS_386:
|
||||
#endif
|
||||
#if !defined(I486_CPU)
|
||||
case CPUCLASS_486:
|
||||
#endif
|
||||
#if !defined(I586_CPU)
|
||||
case CPUCLASS_586:
|
||||
#endif
|
||||
#if !defined(I686_CPU)
|
||||
case CPUCLASS_686:
|
||||
#endif
|
||||
panic("CPU class not configured");
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#ifdef PERFMON
|
||||
perfmon_init();
|
||||
#endif
|
||||
dev_attach(&kdc_cpu0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Send an interrupt to process.
|
||||
*
|
||||
@ -884,66 +690,6 @@ sigreturn(p, uap, retval)
|
||||
return(EJUSTRETURN);
|
||||
}
|
||||
|
||||
#ifdef PC98
|
||||
/*
|
||||
* disable screen saver
|
||||
*/
|
||||
extern int scrn_blanked;
|
||||
extern void (*current_saver)(int blank);
|
||||
|
||||
static void pc98_disable_screen_saver(void)
|
||||
{
|
||||
if (scrn_blanked)
|
||||
(*current_saver)(FALSE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* change ralay on video card
|
||||
*/
|
||||
static void pc98_change_relay(void)
|
||||
{
|
||||
/* mode register 2 */
|
||||
outb(0x6a, 0x07); /* enable to change FF */
|
||||
outb(0x6a, 0x8e);
|
||||
outb(0x6a, 0x06); /* disable to change FF */
|
||||
outb(0x7c, 0);
|
||||
outb(0x68, 0x0f); /* display */
|
||||
|
||||
/* PWLB */
|
||||
*(int *)panic_kwin_pte = (0xf0c00000 & PG_FRAME) | PG_V | PG_RW ;
|
||||
pmap_update();
|
||||
*(long *)panic_kwin = 0;
|
||||
/* PowerWindow(C-Bus) */
|
||||
outb(0x0dc | 0x600, 0); /* XXX */
|
||||
/* PCHKB & PCSKB4 */
|
||||
outb(0x6e68, 0);
|
||||
/* PCSKB */
|
||||
outb(0x6ee8, 0);
|
||||
/* NEC-S3, Cirrus (local bus) */
|
||||
outb(0xfaa, 3);
|
||||
outb(0xfab, 1);
|
||||
outb(0xfaa, 6);
|
||||
outb(0xfab, 0xff);
|
||||
outb(0xfaa, 7);
|
||||
outb(0xfab, 0);
|
||||
/* NEC-S3 (C-bus) */
|
||||
outb(0xfa2, 3);
|
||||
outb(0xfa3, 0);
|
||||
/* GA-NB */
|
||||
outb(0x40e1, 0xc2);
|
||||
/* WAB-S & WAP */
|
||||
outb(0x40e1, 0xfa);
|
||||
|
||||
/* stop G-GDC */
|
||||
outb(0xa2, 0x0c);
|
||||
/* XXX start T-GDC (which is true?)*/
|
||||
outb(0x62, 0x69);
|
||||
outb(0x62, 0x0d);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static int waittime = -1;
|
||||
struct pcb dumppcb;
|
||||
|
||||
@ -955,10 +701,6 @@ boot(howto)
|
||||
register struct buf *bp;
|
||||
int iter, nbusy;
|
||||
|
||||
#ifdef PC98
|
||||
pc98_change_relay();
|
||||
pc98_disable_screen_saver();
|
||||
#endif
|
||||
waittime = 0;
|
||||
printf("\nsyncing disks... ");
|
||||
|
||||
@ -1051,7 +793,7 @@ boot(howto)
|
||||
* exported (symorder) and used at least by savecore(8)
|
||||
*
|
||||
*/
|
||||
u_long dumpmag = 0x8fca0101UL;
|
||||
static u_long const dumpmag = 0x8fca0101UL;
|
||||
|
||||
static int dumpsize = 0; /* also for savecore */
|
||||
|
||||
@ -1406,6 +1148,13 @@ init386(first)
|
||||
*/
|
||||
cninit();
|
||||
|
||||
#ifdef PC98
|
||||
/*
|
||||
* Initialize DMAC
|
||||
*/
|
||||
init_pc98_dmac();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* make gdt memory segments, the code segment goes up to end of the
|
||||
* page with etext in it, the data segment goes to the end of
|
||||
@ -1507,56 +1256,7 @@ init386(first)
|
||||
|
||||
#ifdef PC98
|
||||
#ifdef EPSON_MEMWIN
|
||||
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 */
|
||||
}
|
||||
init_epson_memwin();
|
||||
#endif
|
||||
biosbasemem = 640; /* 640KB */
|
||||
biosextmem = (Maxmem * PAGE_SIZE - 0x100000)/1024; /* extent memory */
|
||||
@ -1623,7 +1323,8 @@ init386(first)
|
||||
|
||||
/*
|
||||
* Maxmem isn't the "maximum memory", it's one larger than the
|
||||
* highest page of of the physical address space. It
|
||||
* highest page of the physical address space. It should be
|
||||
* called something like "Maxphyspage".
|
||||
*/
|
||||
Maxmem = pagesinext + 0x100000/PAGE_SIZE;
|
||||
|
||||
@ -1654,76 +1355,9 @@ init386(first)
|
||||
}
|
||||
|
||||
#ifdef PC98
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef notyet
|
||||
init_cpu_accel_mem();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
for (target_page = avail_start; target_page < ptoa(Maxmem); target_page += PAGE_SIZE) {
|
||||
|
@ -32,7 +32,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: Steve McCanne's microtime code
|
||||
* $Id: microtime.s,v 1.13 1996/05/31 01:08:02 peter Exp $
|
||||
* $Id: microtime.s,v 1.1.1.1 1996/06/14 10:04:41 asami Exp $
|
||||
*/
|
||||
|
||||
#include <machine/asmacros.h>
|
||||
@ -60,6 +60,7 @@ ENTRY(microtime)
|
||||
|
||||
movb $TIMER_SEL0|TIMER_LATCH, %al /* prepare to latch */
|
||||
|
||||
pushfl
|
||||
cli /* disable interrupts */
|
||||
|
||||
outb %al, $TIMER_MODE /* latch timer 0's counter */
|
||||
@ -218,7 +219,7 @@ overflow:
|
||||
#endif /* !AUTO_CLOCK */
|
||||
#else /* IBM-PC */
|
||||
#if 0
|
||||
imul $27645, %edx /* 25 cycles on a 486 */
|
||||
imul $27465, %edx /* 25 cycles on a 486 */
|
||||
#else
|
||||
leal (%edx,%edx,2), %eax /* a = 3 2 cycles on a 486 */
|
||||
leal (%edx,%eax,4), %eax /* a = 13 2 */
|
||||
@ -235,7 +236,7 @@ common_microtime:
|
||||
addl _time+4, %eax /* usec += time.tv_sec */
|
||||
movl _time, %edx /* sec = time.tv_sec */
|
||||
|
||||
sti /* enable interrupts */
|
||||
popfl /* restore interrupt mask */
|
||||
|
||||
cmpl $1000000, %eax /* usec valid? */
|
||||
jb 1f
|
||||
@ -251,6 +252,7 @@ common_microtime:
|
||||
#if defined(I586_CPU) || defined(I686_CPU)
|
||||
ALIGN_TEXT
|
||||
pentium_microtime:
|
||||
pushfl
|
||||
cli
|
||||
.byte 0x0f, 0x31 /* RDTSC */
|
||||
subl _i586_ctr_bias, %eax
|
||||
|
1135
sys/pc98/i386/pmap.c
1135
sys/pc98/i386/pmap.c
File diff suppressed because it is too large
Load Diff
@ -30,13 +30,14 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: support.s,v 1.36 1996/05/31 01:08:03 peter Exp $
|
||||
* $Id: support.s,v 1.1.1.1 1996/06/14 10:04:41 asami Exp $
|
||||
*/
|
||||
|
||||
#include "assym.s" /* system definitions */
|
||||
#include "errno.h" /* error return codes */
|
||||
#include "machine/asmacros.h" /* miscellaneous asm macros */
|
||||
#include "machine/cputypes.h" /* types of CPUs */
|
||||
#include "machine/specialreg.h"
|
||||
|
||||
#define KDSEL 0x10 /* kernel data selector */
|
||||
#define IDXSHIFT 10
|
||||
@ -453,6 +454,21 @@ ENTRY(copyout) /* copyout(from_kernel, to_user, len) */
|
||||
/* bcopy(%esi, %edi, %ebx) */
|
||||
3:
|
||||
movl %ebx,%ecx
|
||||
#if defined(I586_CPU) && defined(I586_FAST_BCOPY)
|
||||
cmpl $1024,%ecx
|
||||
jbe slow_copyout
|
||||
|
||||
#if defined(I386_CPU) || defined(I486_CPU) || defined(I686_CPU)
|
||||
cmpl $CPUCLASS_586,_cpu_class
|
||||
jne slow_copyout
|
||||
#endif /* I386_CPU || I486_CPU || I686_CPU */
|
||||
|
||||
call fastmove
|
||||
jmp done_copyout
|
||||
|
||||
ALIGN_TEXT
|
||||
slow_copyout:
|
||||
#endif /* I586_CPU && I586_FAST_BCOPY */
|
||||
shrl $2,%ecx
|
||||
cld
|
||||
rep
|
||||
@ -500,6 +516,21 @@ ENTRY(copyin)
|
||||
cmpl $VM_MAXUSER_ADDRESS,%edx
|
||||
ja copyin_fault
|
||||
|
||||
#if defined(I586_CPU) && defined(I586_FAST_BCOPY)
|
||||
cmpl $1024,%ecx
|
||||
jbe slow_copyin
|
||||
|
||||
#if defined(I386_CPU) || defined(I486_CPU) || defined(I686_CPU)
|
||||
cmpl $CPUCLASS_586,_cpu_class
|
||||
jne slow_copyin
|
||||
#endif /* I386_CPU || I486_CPU || I686_CPU */
|
||||
|
||||
call fastmove
|
||||
jmp done_copyin
|
||||
|
||||
ALIGN_TEXT
|
||||
slow_copyin:
|
||||
#endif /* I586_CPU && I586_FAST_BCOPY */
|
||||
movb %cl,%al
|
||||
shrl $2,%ecx /* copy longword-wise */
|
||||
cld
|
||||
@ -510,6 +541,10 @@ ENTRY(copyin)
|
||||
rep
|
||||
movsb
|
||||
|
||||
#if defined(I586_CPU) && defined(I586_FAST_BCOPY)
|
||||
ALIGN_TEXT
|
||||
done_copyin:
|
||||
#endif /* I586_CPU && I586_FAST_BCOPY */
|
||||
popl %edi
|
||||
popl %esi
|
||||
xorl %eax,%eax
|
||||
@ -526,6 +561,161 @@ copyin_fault:
|
||||
movl $EFAULT,%eax
|
||||
ret
|
||||
|
||||
#if defined(I586_CPU) && defined(I586_FAST_BCOPY)
|
||||
/* fastmove(src, dst, len)
|
||||
src in %esi
|
||||
dst in %edi
|
||||
len in %ecx
|
||||
uses %eax and %edx for tmp. storage
|
||||
*/
|
||||
ALIGN_TEXT
|
||||
fastmove:
|
||||
cmpl $63,%ecx
|
||||
jbe 8f
|
||||
|
||||
testl $7,%esi /* check if src addr is multiple of 8 */
|
||||
jnz 8f
|
||||
|
||||
testl $7,%edi /* check if dst addr is multiple of 8 */
|
||||
jnz 8f
|
||||
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
subl $PCB_SAVEFPU_SIZE,%esp
|
||||
|
||||
/* if (npxproc != NULL) { */
|
||||
cmpl $0,_npxproc
|
||||
je 6f
|
||||
/* fnsave(&curpcb->pcb_savefpu); */
|
||||
movl _curpcb,%eax
|
||||
fnsave PCB_SAVEFPU(%eax)
|
||||
/* npxproc = NULL; */
|
||||
movl $0,_npxproc
|
||||
/* } */
|
||||
6:
|
||||
/* now we own the FPU. */
|
||||
|
||||
/*
|
||||
* The process' FP state is saved in the pcb, but if we get
|
||||
* switched, the cpu_switch() will store our FP state in the
|
||||
* pcb. It should be possible to avoid all the copying for
|
||||
* this, e.g., by setting a flag to tell cpu_switch() to
|
||||
* save the state somewhere else.
|
||||
*/
|
||||
/* tmp = curpcb->pcb_savefpu; */
|
||||
pushl %edi
|
||||
pushl %esi
|
||||
pushl %ecx
|
||||
leal -PCB_SAVEFPU_SIZE(%ebp),%edi
|
||||
movl _curpcb,%esi
|
||||
addl $PCB_SAVEFPU,%esi
|
||||
cld
|
||||
movl $PCB_SAVEFPU_SIZE>>2,%ecx
|
||||
rep
|
||||
movsl
|
||||
popl %ecx
|
||||
popl %esi
|
||||
popl %edi
|
||||
/* stop_emulating(); */
|
||||
clts
|
||||
/* npxproc = curproc; */
|
||||
movl _curproc,%eax
|
||||
movl %eax,_npxproc
|
||||
4:
|
||||
pushl %ecx
|
||||
cmpl $1792,%ecx
|
||||
jbe 2f
|
||||
movl $1792,%ecx
|
||||
2:
|
||||
subl %ecx,0(%esp)
|
||||
cmpl $256,%ecx
|
||||
jb 5f
|
||||
pushl %esi
|
||||
pushl %ecx
|
||||
ALIGN_TEXT
|
||||
3:
|
||||
movl 0(%esi),%eax
|
||||
movl 32(%esi),%eax
|
||||
movl 64(%esi),%eax
|
||||
movl 96(%esi),%eax
|
||||
movl 128(%esi),%eax
|
||||
movl 160(%esi),%eax
|
||||
movl 192(%esi),%eax
|
||||
movl 224(%esi),%eax
|
||||
addl $256,%esi
|
||||
subl $256,%ecx
|
||||
cmpl $256,%ecx
|
||||
jae 3b
|
||||
popl %ecx
|
||||
popl %esi
|
||||
5:
|
||||
ALIGN_TEXT
|
||||
7:
|
||||
fildq 0(%esi)
|
||||
fildq 8(%esi)
|
||||
fildq 16(%esi)
|
||||
fildq 24(%esi)
|
||||
fildq 32(%esi)
|
||||
fildq 40(%esi)
|
||||
fildq 48(%esi)
|
||||
fildq 56(%esi)
|
||||
fistpq 56(%edi)
|
||||
fistpq 48(%edi)
|
||||
fistpq 40(%edi)
|
||||
fistpq 32(%edi)
|
||||
fistpq 24(%edi)
|
||||
fistpq 16(%edi)
|
||||
fistpq 8(%edi)
|
||||
fistpq 0(%edi)
|
||||
addl $-64,%ecx
|
||||
addl $64,%esi
|
||||
addl $64,%edi
|
||||
cmpl $63,%ecx
|
||||
ja 7b
|
||||
popl %eax
|
||||
addl %eax,%ecx
|
||||
cmpl $64,%ecx
|
||||
jae 4b
|
||||
|
||||
/* curpcb->pcb_savefpu = tmp; */
|
||||
pushl %edi
|
||||
pushl %esi
|
||||
pushl %ecx
|
||||
movl _curpcb,%edi
|
||||
addl $PCB_SAVEFPU,%edi
|
||||
leal -PCB_SAVEFPU_SIZE(%ebp),%esi
|
||||
cld
|
||||
movl $PCB_SAVEFPU_SIZE>>2,%ecx
|
||||
rep
|
||||
movsl
|
||||
popl %ecx
|
||||
popl %esi
|
||||
popl %edi
|
||||
|
||||
/* start_emulating(); */
|
||||
smsw %ax
|
||||
orb $CR0_TS,%al
|
||||
lmsw %ax
|
||||
/* npxproc = NULL; */
|
||||
movl $0,_npxproc
|
||||
movl %ebp,%esp
|
||||
popl %ebp
|
||||
|
||||
ALIGN_TEXT
|
||||
8:
|
||||
movb %cl,%al
|
||||
shrl $2,%ecx /* copy longword-wise */
|
||||
cld
|
||||
rep
|
||||
movsl
|
||||
movb %al,%cl
|
||||
andb $3,%cl /* copy remaining bytes */
|
||||
rep
|
||||
movsb
|
||||
|
||||
ret
|
||||
#endif /* I586_CPU && I586_FAST_BCOPY */
|
||||
|
||||
/*
|
||||
* fu{byte,sword,word} : fetch a byte (sword, word) from user memory
|
||||
*/
|
||||
|
@ -35,7 +35,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)trap.c 7.4 (Berkeley) 5/13/91
|
||||
* $Id: trap.c,v 1.76 1996/05/18 03:36:19 dyson Exp $
|
||||
* $Id: trap.c,v 1.1.1.1 1996/06/14 10:04:41 asami Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -175,19 +175,10 @@ userret(p, frame, oticks)
|
||||
/*
|
||||
* Charge system time if profiling.
|
||||
*/
|
||||
if (p->p_flag & P_PROFIL) {
|
||||
u_quad_t ticks = p->p_sticks - oticks;
|
||||
if (p->p_flag & P_PROFIL)
|
||||
addupc_task(p, frame->tf_eip,
|
||||
(u_int)(p->p_sticks - oticks) * psratio);
|
||||
|
||||
if (ticks) {
|
||||
#ifdef PROFTIMER
|
||||
extern int profscale;
|
||||
addupc(frame->tf_eip, &p->p_stats->p_prof,
|
||||
ticks * profscale);
|
||||
#else
|
||||
addupc(frame->tf_eip, &p->p_stats->p_prof, ticks);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
curpriority = p->p_priority;
|
||||
}
|
||||
|
||||
@ -255,8 +246,9 @@ trap(frame)
|
||||
astoff();
|
||||
cnt.v_soft++;
|
||||
if (p->p_flag & P_OWEUPC) {
|
||||
addupc(frame.tf_eip, &p->p_stats->p_prof, 1);
|
||||
p->p_flag &= ~P_OWEUPC;
|
||||
addupc_task(p, p->p_stats->p_prof.pr_addr,
|
||||
p->p_stats->p_prof.pr_ticks);
|
||||
}
|
||||
goto out;
|
||||
|
||||
@ -325,8 +317,7 @@ trap(frame)
|
||||
/* if a transparent fault (due to context switch "late") */
|
||||
if (npxdna())
|
||||
return;
|
||||
#endif /* NNPX > 0 */
|
||||
|
||||
#endif
|
||||
if (!pmath_emulate) {
|
||||
i = SIGFPE;
|
||||
ucode = FPE_FPU_NP_TRAP;
|
||||
@ -359,6 +350,18 @@ trap(frame)
|
||||
#endif
|
||||
return;
|
||||
|
||||
case T_DNA:
|
||||
#if NNPX > 0
|
||||
/*
|
||||
* The kernel is apparently using npx for copying.
|
||||
* XXX this should be fatal unless the kernel has
|
||||
* registered such use.
|
||||
*/
|
||||
if (npxdna())
|
||||
return;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case T_PROTFLT: /* general protection fault */
|
||||
case T_SEGNPFLT: /* segment not present fault */
|
||||
/*
|
||||
@ -672,9 +675,6 @@ trap_pfault(frame, usermode)
|
||||
ftype = VM_PROT_READ;
|
||||
|
||||
if (map != kernel_map) {
|
||||
vm_offset_t v;
|
||||
vm_page_t mpte;
|
||||
|
||||
/*
|
||||
* Keep swapout from messing with us during this
|
||||
* critical time.
|
||||
|
@ -38,7 +38,7 @@
|
||||
*
|
||||
* from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91
|
||||
* Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$
|
||||
* $Id: vm_machdep.c,v 1.63 1996/05/18 03:36:22 dyson Exp $
|
||||
* $Id: vm_machdep.c,v 1.1.1.1 1996/06/14 10:04:42 asami Exp $
|
||||
*/
|
||||
|
||||
#include "npx.h"
|
||||
@ -235,13 +235,13 @@ vm_bounce_kva(size, waitok)
|
||||
|
||||
if( size == 0) {
|
||||
splx(s);
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((kva = kmem_alloc_pageable(io_map, size)) == 0) {
|
||||
if( !waitok) {
|
||||
splx(s);
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
bmwait = 1;
|
||||
tsleep((caddr_t) io_map, PRIBIO, "bmwait", 0);
|
||||
@ -694,56 +694,31 @@ void
|
||||
vmapbuf(bp)
|
||||
register struct buf *bp;
|
||||
{
|
||||
register int npf;
|
||||
register caddr_t addr;
|
||||
int off;
|
||||
vm_offset_t kva;
|
||||
register caddr_t addr, v, kva;
|
||||
vm_offset_t pa;
|
||||
|
||||
if ((bp->b_flags & B_PHYS) == 0)
|
||||
panic("vmapbuf");
|
||||
|
||||
/*
|
||||
* this is the kva that is to be used for
|
||||
* the temporary kernel mapping
|
||||
*/
|
||||
kva = (vm_offset_t) bp->b_saveaddr;
|
||||
|
||||
for (addr = (caddr_t)trunc_page(bp->b_data);
|
||||
addr < bp->b_data + bp->b_bufsize;
|
||||
addr += PAGE_SIZE) {
|
||||
|
||||
/*
|
||||
* do the vm_fault if needed, do the copy-on-write thing when
|
||||
* reading stuff off device into memory.
|
||||
*/
|
||||
for (v = bp->b_saveaddr, addr = (caddr_t)trunc_page(bp->b_data);
|
||||
addr < bp->b_data + bp->b_bufsize;
|
||||
addr += PAGE_SIZE, v += PAGE_SIZE) {
|
||||
/*
|
||||
* Do the vm_fault if needed; do the copy-on-write thing
|
||||
* when reading stuff off device into memory.
|
||||
*/
|
||||
vm_fault_quick(addr,
|
||||
(bp->b_flags&B_READ)?(VM_PROT_READ|VM_PROT_WRITE):VM_PROT_READ);
|
||||
pa = pmap_kextract((vm_offset_t) addr);
|
||||
pa = trunc_page(pmap_kextract((vm_offset_t) addr));
|
||||
if (pa == 0)
|
||||
panic("vmapbuf: page not present");
|
||||
/*
|
||||
* hold the data page
|
||||
*/
|
||||
#ifdef DIAGNOSTIC
|
||||
if( VM_PAGE_TO_PHYS(PHYS_TO_VM_PAGE(pa)) != pa)
|
||||
panic("vmapbuf: confused PHYS_TO_VM_PAGE mapping");
|
||||
#endif
|
||||
vm_page_hold(PHYS_TO_VM_PAGE(pa));
|
||||
pmap_kenter((vm_offset_t) v, pa);
|
||||
}
|
||||
|
||||
addr = bp->b_saveaddr = bp->b_data;
|
||||
off = (int)addr & PAGE_MASK;
|
||||
npf = btoc(round_page(bp->b_bufsize + off));
|
||||
bp->b_data = (caddr_t) (kva + off);
|
||||
while (npf--) {
|
||||
pa = pmap_kextract((vm_offset_t)addr);
|
||||
if (pa == 0)
|
||||
panic("vmapbuf: null page frame");
|
||||
pmap_kenter(kva, trunc_page(pa));
|
||||
addr += PAGE_SIZE;
|
||||
kva += PAGE_SIZE;
|
||||
}
|
||||
kva = bp->b_saveaddr;
|
||||
bp->b_saveaddr = bp->b_data;
|
||||
bp->b_data = kva + (((vm_offset_t) bp->b_data) & PAGE_MASK);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -760,26 +735,15 @@ vunmapbuf(bp)
|
||||
if ((bp->b_flags & B_PHYS) == 0)
|
||||
panic("vunmapbuf");
|
||||
|
||||
for (addr = (caddr_t)trunc_page((vm_offset_t) bp->b_data);
|
||||
addr < bp->b_data + bp->b_bufsize;
|
||||
addr += PAGE_SIZE)
|
||||
for (addr = (caddr_t)trunc_page(bp->b_data);
|
||||
addr < bp->b_data + bp->b_bufsize;
|
||||
addr += PAGE_SIZE) {
|
||||
pa = trunc_page(pmap_kextract((vm_offset_t) addr));
|
||||
pmap_kremove((vm_offset_t) addr);
|
||||
|
||||
bp->b_data = bp->b_saveaddr;
|
||||
bp->b_saveaddr = NULL;
|
||||
|
||||
/*
|
||||
* unhold the pde, and data pages
|
||||
*/
|
||||
for (addr = (caddr_t)trunc_page((vm_offset_t) bp->b_data);
|
||||
addr < bp->b_data + bp->b_bufsize;
|
||||
addr += PAGE_SIZE) {
|
||||
/*
|
||||
* release the data page
|
||||
*/
|
||||
pa = pmap_kextract((vm_offset_t) addr);
|
||||
vm_page_unhold(PHYS_TO_VM_PAGE(pa));
|
||||
}
|
||||
|
||||
bp->b_data = bp->b_saveaddr;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
|
||||
* $Id: clock.c,v 1.58 1996/05/01 08:39:02 bde Exp $
|
||||
* $Id: clock.c,v 1.1.1.1 1996/06/14 10:04:42 asami Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -46,13 +46,14 @@
|
||||
|
||||
/*
|
||||
* modified for PC98
|
||||
* $Id: clock.c,v 1.7 1994/03/26 22:56:13 kakefuda Exp kakefuda $
|
||||
* $Id: clock.c,v 1.1.1.1 1996/06/14 10:04:42 asami Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Primitive clock interrupt routines.
|
||||
*/
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_clock.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -100,13 +101,13 @@
|
||||
#define TIMER0_LATCH_COUNT 20
|
||||
|
||||
/*
|
||||
* Minimum maximum count that we are willing to program into timer0.
|
||||
* Must be large enough to guarantee that the timer interrupt handler
|
||||
* returns before the next timer interrupt. Must be larger than
|
||||
* TIMER0_LATCH_COUNT so that we don't have to worry about underflow in
|
||||
* the calculation of timer0_overflow_threshold.
|
||||
* Maximum frequency that we are willing to allow for timer0. Must be
|
||||
* low enough to guarantee that the timer interrupt handler returns
|
||||
* before the next timer interrupt. Must result in a lower TIMER_DIV
|
||||
* value than TIMER0_LATCH_COUNT so that we don't have to worry about
|
||||
* underflow in the calculation of timer0_overflow_threshold.
|
||||
*/
|
||||
#define TIMER0_MIN_MAX_COUNT TIMER_DIV(20000)
|
||||
#define TIMER0_MAX_FREQ 20000
|
||||
|
||||
int adjkerntz; /* local offset from GMT in seconds */
|
||||
int disable_rtc_set; /* disable resettodr() if != 0 */
|
||||
@ -122,28 +123,6 @@ unsigned long i586_avg_tick;
|
||||
#endif
|
||||
int statclock_disable;
|
||||
u_int stat_imask = SWI_CLOCK_MASK;
|
||||
int timer0_max_count;
|
||||
u_int timer0_overflow_threshold;
|
||||
u_int timer0_prescaler_count;
|
||||
|
||||
static int beeping = 0;
|
||||
static u_int clk_imask = HWI_MASK | SWI_MASK;
|
||||
static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31};
|
||||
static u_int hardclock_max_count;
|
||||
/*
|
||||
* XXX new_function and timer_func should not handle clockframes, but
|
||||
* timer_func currently needs to hold hardclock to handle the
|
||||
* timer0_state == 0 case. We should use register_intr()/unregister_intr()
|
||||
* to switch between clkintr() and a slightly different timerintr().
|
||||
* This will require locking when acquiring and releasing timer0 - the
|
||||
* current (nonexistent) locking doesn't seem to be adequate even now.
|
||||
*/
|
||||
static void (*new_function) __P((struct clockframe *frame));
|
||||
static u_int new_rate;
|
||||
#ifndef PC98
|
||||
static u_char rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
|
||||
static u_char rtc_statusb = RTCSB_24HR | RTCSB_PINTR;
|
||||
#endif
|
||||
#ifdef TIMER_FREQ
|
||||
static u_int timer_freq = TIMER_FREQ;
|
||||
#else
|
||||
@ -161,31 +140,52 @@ static u_int timer_freq = 2457600;
|
||||
static u_int timer_freq = 1193182;
|
||||
#endif /* PC98 */
|
||||
#endif
|
||||
static char timer0_state = 0;
|
||||
#ifdef PC98
|
||||
static char timer1_state = 0;
|
||||
int timer0_max_count;
|
||||
u_int timer0_overflow_threshold;
|
||||
u_int timer0_prescaler_count;
|
||||
|
||||
static int beeping = 0;
|
||||
static u_int clk_imask = HWI_MASK | SWI_MASK;
|
||||
static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31};
|
||||
static u_int hardclock_max_count;
|
||||
/*
|
||||
* XXX new_function and timer_func should not handle clockframes, but
|
||||
* timer_func currently needs to hold hardclock to handle the
|
||||
* timer0_state == 0 case. We should use register_intr()/unregister_intr()
|
||||
* to switch between clkintr() and a slightly different timerintr().
|
||||
*/
|
||||
static void (*new_function) __P((struct clockframe *frame));
|
||||
static u_int new_rate;
|
||||
#ifndef PC98
|
||||
static u_char rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
|
||||
static u_char rtc_statusb = RTCSB_24HR | RTCSB_PINTR;
|
||||
#endif
|
||||
static char timer2_state = 0;
|
||||
|
||||
/* Values for timerX_state: */
|
||||
#define RELEASED 0
|
||||
#define RELEASE_PENDING 1
|
||||
#define ACQUIRED 2
|
||||
#define ACQUIRE_PENDING 3
|
||||
|
||||
static u_char timer0_state;
|
||||
#ifdef PC98
|
||||
static u_char timer1_state;
|
||||
#endif
|
||||
static u_char timer2_state;
|
||||
static void (*timer_func) __P((struct clockframe *frame)) = hardclock;
|
||||
int rtc_inb __P((void));
|
||||
|
||||
#if 0
|
||||
void
|
||||
clkintr(struct clockframe frame)
|
||||
{
|
||||
hardclock(&frame);
|
||||
setdelayed();
|
||||
}
|
||||
#else
|
||||
static void
|
||||
clkintr(struct clockframe frame)
|
||||
{
|
||||
timer_func(&frame);
|
||||
switch (timer0_state) {
|
||||
case 0:
|
||||
|
||||
case RELEASED:
|
||||
setdelayed();
|
||||
break;
|
||||
case 1:
|
||||
|
||||
case ACQUIRED:
|
||||
if ((timer0_prescaler_count += timer0_max_count)
|
||||
>= hardclock_max_count) {
|
||||
hardclock(&frame);
|
||||
@ -193,7 +193,8 @@ clkintr(struct clockframe frame)
|
||||
timer0_prescaler_count -= hardclock_max_count;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
|
||||
case ACQUIRE_PENDING:
|
||||
setdelayed();
|
||||
timer0_max_count = TIMER_DIV(new_rate);
|
||||
timer0_overflow_threshold =
|
||||
@ -205,9 +206,10 @@ clkintr(struct clockframe frame)
|
||||
enable_intr();
|
||||
timer0_prescaler_count = 0;
|
||||
timer_func = new_function;
|
||||
timer0_state = 1;
|
||||
timer0_state = ACQUIRED;
|
||||
break;
|
||||
case 3:
|
||||
|
||||
case RELEASE_PENDING:
|
||||
if ((timer0_prescaler_count += timer0_max_count)
|
||||
>= hardclock_max_count) {
|
||||
hardclock(&frame);
|
||||
@ -248,84 +250,140 @@ clkintr(struct clockframe frame)
|
||||
}
|
||||
#endif /* AUTO_CLOCK */
|
||||
#else /* IBM-PC */
|
||||
time.tv_usec += (27645 *
|
||||
time.tv_usec += (27465 *
|
||||
(timer0_prescaler_count - hardclock_max_count))
|
||||
>> 15;
|
||||
#endif /* PC98 */
|
||||
if (time.tv_usec >= 1000000)
|
||||
time.tv_usec -= 1000000;
|
||||
timer0_prescaler_count = 0;
|
||||
timer_func = hardclock;;
|
||||
timer0_state = 0;
|
||||
timer_func = hardclock;
|
||||
timer0_state = RELEASED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The acquire and release functions must be called at ipl >= splclock().
|
||||
*/
|
||||
int
|
||||
acquire_timer0(int rate, void (*function) __P((struct clockframe *frame)))
|
||||
{
|
||||
if (timer0_state || TIMER_DIV(rate) < TIMER0_MIN_MAX_COUNT ||
|
||||
!function)
|
||||
return -1;
|
||||
static int old_rate;
|
||||
|
||||
if (rate <= 0 || rate > TIMER0_MAX_FREQ)
|
||||
return (-1);
|
||||
switch (timer0_state) {
|
||||
|
||||
case RELEASED:
|
||||
timer0_state = ACQUIRE_PENDING;
|
||||
break;
|
||||
|
||||
case RELEASE_PENDING:
|
||||
if (rate != old_rate)
|
||||
return (-1);
|
||||
/*
|
||||
* The timer has been released recently, but is being
|
||||
* re-acquired before the release completed. In this
|
||||
* case, we simply reclaim it as if it had not been
|
||||
* released at all.
|
||||
*/
|
||||
timer0_state = ACQUIRED;
|
||||
break;
|
||||
|
||||
default:
|
||||
return (-1); /* busy */
|
||||
}
|
||||
new_function = function;
|
||||
new_rate = rate;
|
||||
timer0_state = 2;
|
||||
return 0;
|
||||
old_rate = new_rate = rate;
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef PC98
|
||||
int
|
||||
acquire_timer1(int mode)
|
||||
{
|
||||
if (timer1_state)
|
||||
return -1;
|
||||
timer1_state = 1;
|
||||
outb(TIMER_MODE, TIMER_SEL1 | (mode &0x3f));
|
||||
return 0;
|
||||
|
||||
if (timer1_state != RELEASED)
|
||||
return (-1);
|
||||
timer1_state = ACQUIRED;
|
||||
|
||||
/*
|
||||
* This access to the timer registers is as atomic as possible
|
||||
* because it is a single instruction. We could do better if we
|
||||
* knew the rate. Use of splclock() limits glitches to 10-100us,
|
||||
* and this is probably good enough for timer2, so we aren't as
|
||||
* careful with it as with timer0.
|
||||
*/
|
||||
outb(TIMER_MODE, TIMER_SEL1 | (mode & 0x3f));
|
||||
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
acquire_timer2(int mode)
|
||||
{
|
||||
if (timer2_state)
|
||||
return -1;
|
||||
timer2_state = 1;
|
||||
outb(TIMER_MODE, TIMER_SEL2 | (mode &0x3f));
|
||||
return 0;
|
||||
|
||||
if (timer2_state != RELEASED)
|
||||
return (-1);
|
||||
timer2_state = ACQUIRED;
|
||||
|
||||
/*
|
||||
* This access to the timer registers is as atomic as possible
|
||||
* because it is a single instruction. We could do better if we
|
||||
* knew the rate. Use of splclock() limits glitches to 10-100us,
|
||||
* and this is probably good enough for timer2, so we aren't as
|
||||
* careful with it as with timer0.
|
||||
*/
|
||||
outb(TIMER_MODE, TIMER_SEL2 | (mode & 0x3f));
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
release_timer0()
|
||||
{
|
||||
if (!timer0_state)
|
||||
return -1;
|
||||
timer0_state = 3;
|
||||
return 0;
|
||||
switch (timer0_state) {
|
||||
|
||||
case ACQUIRED:
|
||||
timer0_state = RELEASE_PENDING;
|
||||
break;
|
||||
|
||||
case ACQUIRE_PENDING:
|
||||
/* Nothing happened yet, release quickly. */
|
||||
timer0_state = RELEASED;
|
||||
break;
|
||||
|
||||
default:
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef PC98
|
||||
int
|
||||
release_timer1()
|
||||
{
|
||||
if (!timer1_state)
|
||||
return -1;
|
||||
timer1_state = 0;
|
||||
outb(TIMER_MODE, TIMER_SEL1|TIMER_SQWAVE|TIMER_16BIT);
|
||||
return 0;
|
||||
|
||||
if (timer1_state != ACQUIRED)
|
||||
return (-1);
|
||||
timer1_state = RELEASED;
|
||||
outb(TIMER_MODE, TIMER_SEL1 | TIMER_SQWAVE | TIMER_16BIT);
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
release_timer2()
|
||||
{
|
||||
if (!timer2_state)
|
||||
return -1;
|
||||
timer2_state = 0;
|
||||
outb(TIMER_MODE, TIMER_SEL2|TIMER_SQWAVE|TIMER_16BIT);
|
||||
return 0;
|
||||
|
||||
if (timer2_state != ACQUIRED)
|
||||
return (-1);
|
||||
timer2_state = RELEASED;
|
||||
outb(TIMER_MODE, TIMER_SEL2 | TIMER_SQWAVE | TIMER_16BIT);
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifndef PC98
|
||||
@ -367,14 +425,19 @@ DDB_printrtc(void)
|
||||
static int
|
||||
getit(void)
|
||||
{
|
||||
u_long ef;
|
||||
int high, low;
|
||||
|
||||
ef = read_eflags();
|
||||
disable_intr();
|
||||
/* select timer0 and latch counter value */
|
||||
|
||||
/* Select timer0 and latch counter value. */
|
||||
outb(TIMER_MODE, TIMER_SEL0);
|
||||
|
||||
low = inb(TIMER_CNTR0);
|
||||
high = inb(TIMER_CNTR0);
|
||||
enable_intr();
|
||||
|
||||
write_eflags(ef);
|
||||
return ((high << 8) | low);
|
||||
}
|
||||
|
||||
@ -459,33 +522,45 @@ sysbeepstop(void *chan)
|
||||
int
|
||||
sysbeep(int pitch, int period)
|
||||
{
|
||||
int x = splclock();
|
||||
|
||||
#ifdef PC98
|
||||
if (acquire_timer1(TIMER_SQWAVE|TIMER_16BIT))
|
||||
return -1;
|
||||
if (!beeping) {
|
||||
/* Something else owns it. */
|
||||
splx(x);
|
||||
return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */
|
||||
}
|
||||
disable_intr();
|
||||
outb(0x3fdb, pitch);
|
||||
outb(0x3fdb, (pitch>>8));
|
||||
enable_intr();
|
||||
if (!beeping) {
|
||||
outb(IO_PPI, (inb(IO_PPI) & 0xf7)); /* enable counter1 output to speaker */
|
||||
/* enable counter1 output to speaker */
|
||||
outb(IO_PPI, (inb(IO_PPI) & 0xf7));
|
||||
beeping = period;
|
||||
timeout(sysbeepstop, (void *)NULL, period);
|
||||
}
|
||||
#else
|
||||
|
||||
if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT))
|
||||
return -1;
|
||||
if (!beeping) {
|
||||
/* Something else owns it. */
|
||||
splx(x);
|
||||
return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */
|
||||
}
|
||||
disable_intr();
|
||||
outb(TIMER_CNTR2, pitch);
|
||||
outb(TIMER_CNTR2, (pitch>>8));
|
||||
enable_intr();
|
||||
if (!beeping) {
|
||||
outb(IO_PPI, inb(IO_PPI) | 3); /* enable counter2 output to speaker */
|
||||
/* enable counter2 output to speaker */
|
||||
outb(IO_PPI, inb(IO_PPI) | 3);
|
||||
beeping = period;
|
||||
timeout(sysbeepstop, (void *)NULL, period);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
splx(x);
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifndef PC98
|
||||
@ -546,7 +621,7 @@ calibrate_clocks(void)
|
||||
u_int count, prev_count, tot_count;
|
||||
int sec, start_sec, timeout;
|
||||
|
||||
printf("Calibrating clock(s) relative to mc146818A clock ... ");
|
||||
printf("Calibrating clock(s) relative to mc146818A clock...\n");
|
||||
if (!(rtcin(RTC_STATUSD) & RTCSD_PWR))
|
||||
goto fail;
|
||||
timeout = 100000000;
|
||||
@ -639,9 +714,10 @@ calibrate_clocks(void)
|
||||
static void
|
||||
set_timer_freq(u_int freq, int intr_freq)
|
||||
{
|
||||
u_long ef;
|
||||
u_long ef;
|
||||
|
||||
ef = read_eflags();
|
||||
disable_intr();
|
||||
timer_freq = freq;
|
||||
timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq);
|
||||
timer0_overflow_threshold = timer0_max_count - TIMER0_LATCH_COUNT;
|
||||
@ -688,11 +764,7 @@ startrtclock()
|
||||
#endif
|
||||
|
||||
#ifndef PC98
|
||||
/*
|
||||
* Temporarily calibrate with a high intr_freq to get a low
|
||||
* timer0_max_count to help detect bogus i8254 counts.
|
||||
*/
|
||||
set_timer_freq(timer_freq, 20000);
|
||||
set_timer_freq(timer_freq, hz);
|
||||
freq = calibrate_clocks();
|
||||
#ifdef CLK_CALIBRATION_LOOP
|
||||
if (bootverbose) {
|
||||
@ -711,7 +783,8 @@ startrtclock()
|
||||
delta = freq > timer_freq ? freq - timer_freq : timer_freq - freq;
|
||||
if (delta < timer_freq / 100) {
|
||||
#ifndef CLK_USE_I8254_CALIBRATION
|
||||
printf(
|
||||
if (bootverbose)
|
||||
printf(
|
||||
"CLK_USE_I8254_CALIBRATION not specified - using default frequency\n");
|
||||
freq = timer_freq;
|
||||
#endif
|
||||
@ -731,7 +804,8 @@ startrtclock()
|
||||
#if defined(I586_CPU) || defined(I686_CPU)
|
||||
#ifndef CLK_USE_I586_CALIBRATION
|
||||
if (i586_ctr_rate != 0) {
|
||||
printf(
|
||||
if (bootverbose)
|
||||
printf(
|
||||
"CLK_USE_I586_CALIBRATION not specified - using old calibration method\n");
|
||||
i586_ctr_freq = 0;
|
||||
i586_ctr_rate = 0;
|
||||
@ -750,7 +824,9 @@ startrtclock()
|
||||
DELAY(1000000);
|
||||
i586_count = rdtsc();
|
||||
i586_ctr_rate = (i586_count << I586_CTR_RATE_SHIFT) / 1000000;
|
||||
#ifdef CLK_USE_I586_CALIBRATION
|
||||
printf("i586 clock: %u Hz\n", i586_ctr_freq);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -35,7 +35,7 @@
|
||||
*
|
||||
* from: @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91
|
||||
* from: ufs_disksubr.c,v 1.8 1994/06/07 01:21:39 phk Exp $
|
||||
* $Id: diskslice_machdep.c,v 1.20 1996/04/07 17:32:09 bde Exp $
|
||||
* $Id: diskslice_machdep.c,v 1.1.1.1 1996/06/14 10:04:43 asami Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -238,14 +238,15 @@ dsinit(dname, dev, strat, lp, sspp)
|
||||
sp[WHOLE_DISK_SLICE].ds_size = lp->d_secperunit;
|
||||
|
||||
mbr_offset = DOSBBSECTOR;
|
||||
reread_mbr:
|
||||
/* Read master boot record. */
|
||||
#ifdef PC98
|
||||
/* Read master boot record. */
|
||||
if ((int)lp->d_secsize < 1024)
|
||||
bp = geteblk((int)1024);
|
||||
else
|
||||
bp = geteblk((int)lp->d_secsize);
|
||||
#else
|
||||
reread_mbr:
|
||||
/* Read master boot record. */
|
||||
bp = geteblk((int)lp->d_secsize);
|
||||
#endif
|
||||
bp->b_dev = dkmodpart(dkmodslice(dev, WHOLE_DISK_SLICE), RAW_PART);
|
||||
|
@ -43,7 +43,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
|
||||
* $Id: fd.c,v 1.89 1996/05/03 20:15:11 phk Exp $
|
||||
* $Id: fd.c,v 1.1.1.1 1996/06/14 10:04:43 asami Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -430,7 +430,7 @@ static int fdformat(dev_t, struct fd_formb *, struct proc *);
|
||||
#define IOTIMEDOUT 11
|
||||
|
||||
#ifdef DEBUG
|
||||
char *fdstates[] =
|
||||
static char const * const fdstates[] =
|
||||
{
|
||||
"DEVIDLE",
|
||||
"FINDWORK",
|
||||
@ -447,7 +447,7 @@ char *fdstates[] =
|
||||
};
|
||||
|
||||
/* CAUTION: fd_debug causes huge amounts of logging output */
|
||||
int fd_debug = 0;
|
||||
static int volatile fd_debug = 0;
|
||||
#define TRACE0(arg) if(fd_debug) printf(arg)
|
||||
#define TRACE1(arg1, arg2) if(fd_debug) printf(arg1, arg2)
|
||||
#else /* DEBUG */
|
||||
@ -786,7 +786,10 @@ fdattach(struct isa_device *dev)
|
||||
fdcu_t fdcu = dev->id_unit;
|
||||
fdc_p fdc = fdc_data + fdcu;
|
||||
fd_p fd;
|
||||
int fdsu, st0, st3, i, unithasfd;
|
||||
int fdsu, st0, st3, i;
|
||||
#if NFT > 0
|
||||
int unithasfd;
|
||||
#endif
|
||||
#ifdef PC98
|
||||
struct pc98_device *fdup;
|
||||
#else
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -17,7 +17,7 @@
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* ft.c - QIC-40/80 floppy tape driver
|
||||
* $Id: ft.c,v 1.25 1995/12/15 00:53:58 bde Exp $
|
||||
* $Id: ft.c,v 1.1.1.1 1996/06/14 10:04:43 asami Exp $
|
||||
*
|
||||
* 01/19/95 ++sg
|
||||
* Cleaned up recalibrate/seek code at attach time for FreeBSD 2.x.
|
||||
@ -86,13 +86,11 @@
|
||||
#include <pc98/pc98/pc98_device.h>
|
||||
#include <pc98/pc98/fdreg.h>
|
||||
#include <pc98/pc98/fdc.h>
|
||||
#include <pc98/pc98/icu.h>
|
||||
#include <pc98/pc98/ftreg.h>
|
||||
#else
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/fdreg.h>
|
||||
#include <i386/isa/fdc.h>
|
||||
#include <i386/isa/icu.h>
|
||||
#include <i386/isa/rtc.h>
|
||||
#include <i386/isa/ftreg.h>
|
||||
#endif
|
||||
|
@ -44,57 +44,6 @@
|
||||
* documents..
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modified for Allied-Telesis RE1000 series.
|
||||
*/
|
||||
|
||||
#ifdef PC98
|
||||
/* Data Link Control Registrs, on invaliant port addresses. */
|
||||
#define FE_DLCR0 0
|
||||
#define FE_DLCR1 1
|
||||
#define FE_DLCR2 0x200
|
||||
#define FE_DLCR3 0x201
|
||||
#define FE_DLCR4 0x400
|
||||
#define FE_DLCR5 0x401
|
||||
#define FE_DLCR6 0x600
|
||||
#define FE_DLCR7 0x601
|
||||
|
||||
/* More DLCRs, on register bank #0. */
|
||||
#define FE_DLCR8 0x800
|
||||
#define FE_DLCR9 0x801
|
||||
#define FE_DLCR10 0xA00
|
||||
#define FE_DLCR11 0xA01
|
||||
#define FE_DLCR12 0xC00
|
||||
#define FE_DLCR13 0xC01
|
||||
#define FE_DLCR14 0xE00
|
||||
#define FE_DLCR15 0xE01
|
||||
|
||||
/* Malticast Address Registers. On register bank #1. */
|
||||
#define FE_MAR8 0x800
|
||||
#define FE_MAR9 0x801
|
||||
#define FE_MAR10 0xA00
|
||||
#define FE_MAR11 0xA01
|
||||
#define FE_MAR12 0xC00
|
||||
#define FE_MAR13 0xC01
|
||||
#define FE_MAR14 0xE00
|
||||
#define FE_MAR15 0xE01
|
||||
|
||||
/* Buffer Memory Port Registers. On register back #2. */
|
||||
#define FE_BMPR8 0x800
|
||||
#define FE_BMPR9 0x801
|
||||
#define FE_BMPR10 0xA00
|
||||
#define FE_BMPR11 0xA01
|
||||
#define FE_BMPR12 0xC00
|
||||
#define FE_BMPR13 0xC01
|
||||
#define FE_BMPR14 0xE00
|
||||
#define FE_BMPR15 0xE01
|
||||
|
||||
/* More BMPRs, only on MB86965A, accessible only when JLI mode. */
|
||||
#define FE_BMPR16 0x1000
|
||||
#define FE_BMPR17 0x1001
|
||||
#define FE_BMPR18 0x1200
|
||||
#define FE_BMPR19 0x1201
|
||||
#else /* not PC98 */
|
||||
/* Data Link Control Registrs, on invaliant port addresses. */
|
||||
#define FE_DLCR0 0
|
||||
#define FE_DLCR1 1
|
||||
@ -140,7 +89,6 @@
|
||||
#define FE_BMPR17 17
|
||||
#define FE_BMPR18 18
|
||||
#define FE_BMPR19 19
|
||||
#endif /* PC98 */
|
||||
|
||||
/*
|
||||
* Definitions of registers.
|
||||
|
@ -24,7 +24,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: if_ed.c,v 1.99 1996/05/27 22:32:23 gpalmer Exp $
|
||||
* $Id: if_ed.c,v 1.1.1.1 1996/06/14 10:04:43 asami Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -38,8 +38,16 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* FreeBSD(98) supports the LGY-98 series, EGY-98 series, LGH-98 series,
|
||||
* IF_2766ET, AD-ET2-T, SIC-98 series, LD-BDN and LPC-T.
|
||||
* FreeBSD(98) supports:
|
||||
* Allied Telesis CenterCom LA-98-T, SIC-98
|
||||
* D-Link DE-298P, DE-298
|
||||
* ELECOM LANEED LD-BDN
|
||||
* ICM DT-ET-25, DT-ET-T5, IF-2766ET, IF_2711ET
|
||||
* IO-DATA PCLA/T, LA/T-98
|
||||
* MACNICA NE2098
|
||||
* NEC PC-9801-108
|
||||
* MELCO LPC-TJ, LPC-TS, LGY-98, LGH-98, IND-SP, IND-SS, EGY-98
|
||||
* PLANET SMART COM CREDITCARD/2000 PCMCIA, EN-2298
|
||||
*
|
||||
* Modified for FreeBSD(98) 2.2 by KATO T. of Nagoya University.
|
||||
*
|
||||
@ -90,17 +98,19 @@
|
||||
#endif
|
||||
|
||||
#include <machine/clock.h>
|
||||
#include <machine/md_var.h>
|
||||
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/pc98.h>
|
||||
#include <pc98/pc98/pc98_device.h>
|
||||
#include <pc98/pc98/icu.h>
|
||||
#include <pc98/pc98/if_edreg.h>
|
||||
#else
|
||||
#include <i386/isa/isa.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/icu.h>
|
||||
#endif
|
||||
#include <i386/isa/if_edreg.h>
|
||||
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/if_ed98.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -331,120 +341,6 @@ card_intr(struct pccard_dev *dp)
|
||||
#endif /* NCRD > 0 */
|
||||
|
||||
#ifdef PC98
|
||||
/* 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
|
||||
};
|
||||
|
||||
|
||||
static void pc98_set_register(int unit, int type)
|
||||
{
|
||||
switch (type) {
|
||||
case ED_TYPE98_GENERIC:
|
||||
edp[unit] = edp_generic;
|
||||
pc98_io_skip[unit] = 1;
|
||||
ED_NOVELL_NIC_OFFSET = 0x0000;
|
||||
ED_NOVELL_ASIC_OFFSET = 0x0010;
|
||||
ED_NOVELL_DATA = 0x0000;
|
||||
ED_NOVELL_RESET = 0x000f;
|
||||
break;
|
||||
|
||||
case ED_TYPE98_LGY:
|
||||
edp[unit] = edp_generic;
|
||||
pc98_io_skip[unit] = 1;
|
||||
ED_NOVELL_NIC_OFFSET = 0x0000;
|
||||
ED_NOVELL_ASIC_OFFSET = 0x0200;
|
||||
ED_NOVELL_DATA = 0x0000;
|
||||
ED_NOVELL_RESET = 0x0100;
|
||||
break;
|
||||
|
||||
case ED_TYPE98_EGY:
|
||||
edp[unit] = edp_egy98;
|
||||
pc98_io_skip[unit] = 2;
|
||||
ED_NOVELL_NIC_OFFSET = 0;
|
||||
ED_NOVELL_ASIC_OFFSET = 0x0200;
|
||||
ED_NOVELL_DATA = 0x0000;
|
||||
ED_NOVELL_RESET = 0x0100;
|
||||
break;
|
||||
|
||||
case ED_TYPE98_ICM:
|
||||
edp[unit] = edp_generic;
|
||||
pc98_io_skip[unit] = 1;
|
||||
ED_NOVELL_NIC_OFFSET = 0;
|
||||
ED_NOVELL_ASIC_OFFSET = 0x0100;
|
||||
ED_NOVELL_DATA = 0x0000;
|
||||
ED_NOVELL_RESET = 0x000f;
|
||||
break;
|
||||
|
||||
case ED_TYPE98_BDN:
|
||||
edp[unit] = edp_bdn98;
|
||||
pc98_io_skip[unit] = 0x1000;
|
||||
ED_NOVELL_NIC_OFFSET = 0x0000;
|
||||
ED_NOVELL_ASIC_OFFSET = 0x0100;
|
||||
ED_NOVELL_DATA = 0;
|
||||
ED_NOVELL_RESET = 0xc100;
|
||||
break;
|
||||
|
||||
case ED_TYPE98_SIC:
|
||||
edp[unit] = edp_sic98;
|
||||
pc98_io_skip[unit] = 0x200;
|
||||
ED_NOVELL_NIC_OFFSET = 0x0000;
|
||||
ED_NOVELL_ASIC_OFFSET = 0x2000;
|
||||
ED_NOVELL_DATA = 0x00; /* dummy */
|
||||
ED_NOVELL_RESET = 0x00;
|
||||
break;
|
||||
|
||||
case ED_TYPE98_LPC:
|
||||
edp[unit] = edp_generic;
|
||||
pc98_io_skip[unit] = 0x1;
|
||||
ED_NOVELL_NIC_OFFSET = 0x0000;
|
||||
ED_NOVELL_ASIC_OFFSET = 0x0100;
|
||||
ED_NOVELL_DATA = 0x0000;
|
||||
ED_NOVELL_RESET = 0x0200;
|
||||
}
|
||||
}
|
||||
|
||||
struct pc98_driver eddriver = {
|
||||
#else
|
||||
struct isa_driver eddriver = {
|
||||
@ -553,18 +449,33 @@ ed_probe(isa_dev)
|
||||
#endif /* not DEV_LKM */
|
||||
|
||||
#ifdef PC98
|
||||
ed_softc[isa_dev->id_unit].unit = isa_dev->id_unit;
|
||||
|
||||
ed_softc[isa_dev->id_unit].type = ED_TYPE98_LPC;
|
||||
pc98_set_register(isa_dev->id_unit, ED_TYPE98_LPC);
|
||||
nports = ed_probe_Novell(isa_dev);
|
||||
if (nports)
|
||||
return (nports);
|
||||
/*
|
||||
* XXX
|
||||
* MELCO LPC-TJ, LPC-TS
|
||||
* PLANET SMART COM CREDITCARD/2000 PCMCIA
|
||||
* IO-DATA PCLA/T
|
||||
*/
|
||||
if ((ED_TYPE98(isa_dev) == ED_TYPE98_GENERIC) ||
|
||||
(ED_TYPE98(isa_dev) == ED_TYPE98_LPC)) {
|
||||
ed_softc[isa_dev->id_unit].unit = isa_dev->id_unit;
|
||||
ed_softc[isa_dev->id_unit].type = ED_TYPE98_LPC;
|
||||
pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_LPC);
|
||||
nports = ed_probe_Novell(isa_dev);
|
||||
if (nports)
|
||||
return (nports);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generic probe routine
|
||||
* Allied Telesis CenterCom LA-98-T
|
||||
*/
|
||||
ed_softc[isa_dev->id_unit].type = ED_TYPE98_GENERIC;
|
||||
pc98_set_register(isa_dev->id_unit, ED_TYPE98_GENERIC);
|
||||
pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_GENERIC);
|
||||
#endif
|
||||
|
||||
#ifdef PC98
|
||||
if (ED_TYPE98(isa_dev) == ED_TYPE98_GENERIC) {
|
||||
#endif
|
||||
nports = ed_probe_WD80x3(isa_dev);
|
||||
if (nports)
|
||||
return (nports);
|
||||
@ -576,36 +487,102 @@ ed_probe(isa_dev)
|
||||
nports = ed_probe_Novell(isa_dev);
|
||||
if (nports)
|
||||
return (nports);
|
||||
#ifdef PC98
|
||||
}
|
||||
#endif
|
||||
|
||||
ed_softc[isa_dev->id_unit].type = ED_TYPE98_SIC;
|
||||
pc98_set_register(isa_dev->id_unit, ED_TYPE98_SIC);
|
||||
nports = ed_probe_SIC98(isa_dev);
|
||||
if (nports)
|
||||
return (nports);
|
||||
/*
|
||||
* Allied Telesis SIC-98
|
||||
*/
|
||||
if ((ED_TYPE98(isa_dev) == ED_TYPE98_GENERIC) ||
|
||||
(ED_TYPE98(isa_dev) == ED_TYPE98_SIC)) {
|
||||
ed_softc[isa_dev->id_unit].type = ED_TYPE98_SIC;
|
||||
pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_SIC);
|
||||
nports = ed_probe_SIC98(isa_dev);
|
||||
if (nports)
|
||||
return (nports);
|
||||
}
|
||||
|
||||
ed_softc[isa_dev->id_unit].type = ED_TYPE98_BDN;
|
||||
pc98_set_register(isa_dev->id_unit, ED_TYPE98_BDN);
|
||||
nports = ed_probe_Novell(isa_dev);
|
||||
if (nports)
|
||||
return (nports);
|
||||
/*
|
||||
* ELECOM LANEED LD-BDN
|
||||
* PLANET SMART COM 98 EN-2298
|
||||
*/
|
||||
if ((ED_TYPE98(isa_dev) == ED_TYPE98_GENERIC) ||
|
||||
(ED_TYPE98(isa_dev) == ED_TYPE98_BDN)) {
|
||||
/* LD-BDN */
|
||||
ed_softc[isa_dev->id_unit].type = ED_TYPE98_BDN;
|
||||
pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_BDN);
|
||||
nports = ed_probe_Novell(isa_dev);
|
||||
if (nports)
|
||||
return (nports);
|
||||
}
|
||||
|
||||
ed_softc[isa_dev->id_unit].type = ED_TYPE98_LGY;
|
||||
pc98_set_register(isa_dev->id_unit, ED_TYPE98_LGY);
|
||||
nports = ed_probe_Novell(isa_dev);
|
||||
if (nports)
|
||||
return (nports);
|
||||
/*
|
||||
* MELCO LGY-98, IND-SP, IND-SS
|
||||
* MACNICA NE2098
|
||||
*/
|
||||
if ((ED_TYPE98(isa_dev) == ED_TYPE98_GENERIC) ||
|
||||
(ED_TYPE98(isa_dev) == ED_TYPE98_LGY)) {
|
||||
/* LGY-98 */
|
||||
ed_softc[isa_dev->id_unit].type = ED_TYPE98_LGY;
|
||||
pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_LGY);
|
||||
nports = ed_probe_Novell(isa_dev);
|
||||
if (nports)
|
||||
return (nports);
|
||||
}
|
||||
|
||||
ed_softc[isa_dev->id_unit].type = ED_TYPE98_ICM;
|
||||
pc98_set_register(isa_dev->id_unit, ED_TYPE98_ICM);
|
||||
nports = ed_probe_Novell(isa_dev);
|
||||
if (nports)
|
||||
return (nports);
|
||||
/*
|
||||
* ICM DT-ET-25, DT-ET-T5, IF-2766ET, IF-2771ET
|
||||
* D-Link DE-298P, DE-298
|
||||
*/
|
||||
if ((ED_TYPE98(isa_dev) == ED_TYPE98_GENERIC) ||
|
||||
(ED_TYPE98(isa_dev) == ED_TYPE98_ICM)) {
|
||||
/* ICM */
|
||||
ed_softc[isa_dev->id_unit].type = ED_TYPE98_ICM;
|
||||
pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_ICM);
|
||||
nports = ed_probe_Novell(isa_dev);
|
||||
if (nports)
|
||||
return (nports);
|
||||
}
|
||||
|
||||
ed_softc[isa_dev->id_unit].type = ED_TYPE98_EGY;
|
||||
pc98_set_register(isa_dev->id_unit, ED_TYPE98_EGY);
|
||||
nports = ed_probe_Novell(isa_dev);
|
||||
if (nports)
|
||||
return (nports);
|
||||
/*
|
||||
* MELCO EGY-98
|
||||
*/
|
||||
if ((ED_TYPE98(isa_dev) == ED_TYPE98_GENERIC) ||
|
||||
(ED_TYPE98(isa_dev) == ED_TYPE98_EGY)) {
|
||||
/* EGY-98 */
|
||||
ed_softc[isa_dev->id_unit].type = ED_TYPE98_EGY;
|
||||
pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_EGY);
|
||||
nports = ed_probe_Novell(isa_dev);
|
||||
if (nports)
|
||||
return (nports);
|
||||
}
|
||||
|
||||
/*
|
||||
* IO-DATA LA/T-98
|
||||
*/
|
||||
if ((ED_TYPE98(isa_dev) == ED_TYPE98_GENERIC) ||
|
||||
(ED_TYPE98(isa_dev) == ED_TYPE98_LA98)) {
|
||||
/* LA-98 */
|
||||
ed_softc[isa_dev->id_unit].type = ED_TYPE98_LA98;
|
||||
pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_LA98);
|
||||
nports = ed_probe_Novell(isa_dev);
|
||||
if (nports)
|
||||
return (nports);
|
||||
}
|
||||
|
||||
/*
|
||||
* NEC PC-9801-108
|
||||
*/
|
||||
if ((ED_TYPE98(isa_dev) == ED_TYPE98_GENERIC) ||
|
||||
(ED_TYPE98(isa_dev) == ED_TYPE98_108)) {
|
||||
/* PC-9801-108 */
|
||||
ed_softc[isa_dev->id_unit].type = ED_TYPE98_108;
|
||||
pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_108);
|
||||
nports = ed_probe_Novell(isa_dev);
|
||||
if (nports)
|
||||
return (nports);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -1481,22 +1458,38 @@ ed_probe_Novell_generic(sc, port, unit, flags)
|
||||
sc->type_str = "NE2000";
|
||||
sc->kdc.kdc_description = "Ethernet adapter: NE2000";
|
||||
break;
|
||||
case ED_TYPE98_LGY:
|
||||
sc->type_str = "LGY-98";
|
||||
sc->kdc.kdc_description = "Ethernet adapter: LGY-98";
|
||||
break;
|
||||
case ED_TYPE98_EGY:
|
||||
sc->type_str = "EGY-98";
|
||||
sc->kdc.kdc_description = "Ethernet adapter: EGY-98";
|
||||
break;
|
||||
case ED_TYPE98_ICM:
|
||||
sc->type_str = "ICM";
|
||||
sc->kdc.kdc_description = "Ethernet adapter: ICM";
|
||||
case ED_TYPE98_LPC:
|
||||
sc->type_str = "LPC-T";
|
||||
sc->kdc.kdc_description = "Ethernet adapter: LPC-T";
|
||||
break;
|
||||
case ED_TYPE98_BDN:
|
||||
sc->type_str = "LD-BDN";
|
||||
sc->kdc.kdc_description = "Ethernet adapter: LD-BDN";
|
||||
break;
|
||||
case ED_TYPE98_EGY:
|
||||
sc->type_str = "EGY-98";
|
||||
sc->kdc.kdc_description = "Ethernet adapter: EGY-98";
|
||||
break;
|
||||
case ED_TYPE98_LGY:
|
||||
sc->type_str = "LGY-98";
|
||||
sc->kdc.kdc_description = "Ethernet adapter: LGY-98";
|
||||
break;
|
||||
case ED_TYPE98_ICM:
|
||||
sc->type_str = "ICM";
|
||||
sc->kdc.kdc_description = "Ethernet adapter: ICM";
|
||||
break;
|
||||
case ED_TYPE98_SIC:
|
||||
sc->type_str = "SIC-98";
|
||||
sc->kdc.kdc_description = "Ethernet adapter: SIC-98";
|
||||
break;
|
||||
case ED_TYPE98_108:
|
||||
sc->type_str = "PC-9801-108";
|
||||
sc->kdc.kdc_description = "Ethernet adapter: PC-9801-108";
|
||||
break;
|
||||
case ED_TYPE98_LA98:
|
||||
sc->type_str = "LA-98";
|
||||
sc->kdc.kdc_description = "Ethernet adapter: LA-98";
|
||||
break;
|
||||
default:
|
||||
sc->type_str = "Unknown";
|
||||
sc->kdc.kdc_description = "Ethernet adapter: Unkonwn";
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -38,7 +38,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: if_ep.c,v 1.44 1996/05/24 15:22:36 gibbs Exp $
|
||||
* $Id: if_ep.c,v 1.1.1.1 1996/06/14 10:04:44 asami Exp $
|
||||
*
|
||||
* Promiscuous mode added and interrupt logic slightly changed
|
||||
* to reduce the number of adapter failures. Transceiver select
|
||||
@ -50,6 +50,12 @@
|
||||
* babkin@hq.icb.chel.su
|
||||
*/
|
||||
|
||||
/*
|
||||
* Pccard support for 3C589 by:
|
||||
* HAMADA Naoki
|
||||
* nao@tom-yam.or.jp
|
||||
*/
|
||||
|
||||
#include "ep.h"
|
||||
#if NEP > 0
|
||||
|
||||
@ -103,14 +109,10 @@
|
||||
#endif
|
||||
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/pc98.h>
|
||||
#include <pc98/pc98/pc98_device.h>
|
||||
#include <pc98/pc98/icu.h>
|
||||
#include <pc98/pc98/if_epreg.h>
|
||||
#else
|
||||
#include <i386/isa/isa.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/icu.h>
|
||||
#include <i386/isa/if_epreg.h>
|
||||
#endif
|
||||
#include <i386/isa/elink.h>
|
||||
@ -146,7 +148,9 @@ static void epstart __P((struct ifnet *));
|
||||
static void epstop __P((struct ep_softc *));
|
||||
static void epwatchdog __P((struct ifnet *));
|
||||
|
||||
#if 0
|
||||
static int send_ID_sequence __P((int));
|
||||
#endif
|
||||
static int get_eeprom_data __P((int, int));
|
||||
|
||||
static struct ep_softc* ep_softc[NEP];
|
||||
@ -185,6 +189,179 @@ static struct kern_devconf kdc_isa_ep = {
|
||||
DC_CLS_NETIF /* class */
|
||||
};
|
||||
|
||||
#include "crd.h"
|
||||
|
||||
#if NCRD > 0
|
||||
#include "apm.h"
|
||||
#include <sys/select.h>
|
||||
#include <pccard/card.h>
|
||||
#include <pccard/driver.h>
|
||||
#include <pccard/slot.h>
|
||||
|
||||
/*
|
||||
* PC-Card (PCMCIA) specific code.
|
||||
*/
|
||||
static int card_intr __P((struct pccard_dev *));
|
||||
static void ep_unload __P((struct pccard_dev *));
|
||||
static void ep_suspend __P((struct pccard_dev *));
|
||||
static int ep_pccard_init __P((struct pccard_dev *, int));
|
||||
static int ep_pccard_attach __P((struct pccard_dev *));
|
||||
|
||||
static struct pccard_drv ep_info = {
|
||||
"ep",
|
||||
card_intr,
|
||||
ep_unload,
|
||||
ep_suspend,
|
||||
ep_pccard_init,
|
||||
0, /* Attributes - presently unused */
|
||||
&net_imask
|
||||
};
|
||||
|
||||
/* Resume is done by executing ep_pccard_init(dp, 0). */
|
||||
static void
|
||||
ep_suspend(dp)
|
||||
struct pccard_dev *dp;
|
||||
{
|
||||
struct ep_softc *sc = ep_softc[dp->isahd.id_unit];
|
||||
|
||||
printf("ep%d: suspending\n", dp->isahd.id_unit);
|
||||
sc->gone = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
static int
|
||||
ep_pccard_init(dp, first)
|
||||
struct pccard_dev *dp;
|
||||
int first;
|
||||
{
|
||||
#ifdef PC98
|
||||
struct pc98_device *is = &dp->isahd;
|
||||
#else
|
||||
struct isa_device *is = &dp->isahd;
|
||||
#endif
|
||||
struct ep_softc *sc = ep_softc[is->id_unit];
|
||||
struct ep_board *epb;
|
||||
int i;
|
||||
|
||||
epb = &ep_board[is->id_unit];
|
||||
|
||||
if (sc == 0) {
|
||||
if ((sc = ep_alloc(is->id_unit, epb)) == 0) {
|
||||
return (ENXIO);
|
||||
}
|
||||
ep_unit++;
|
||||
ep_isa_registerdev(sc, is);
|
||||
}
|
||||
|
||||
/* get_e() requires these. */
|
||||
sc->ep_io_addr = is->id_iobase;
|
||||
sc->unit = is->id_unit;
|
||||
|
||||
epb->epb_addr = is->id_iobase;
|
||||
epb->epb_used = 1;
|
||||
epb->prod_id = get_e(sc, EEPROM_PROD_ID);
|
||||
|
||||
if (epb->prod_id != 0x9058) { /* 3C589's product id */
|
||||
if (first) {
|
||||
printf("ep%d: failed to come ready.\n", is->id_unit);
|
||||
} else {
|
||||
printf("ep%d: failed to resume.\n", is->id_unit);
|
||||
}
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
epb->res_cfg = get_e(sc, EEPROM_RESOURCE_CFG);
|
||||
for (i = 0; i < 3; i++) {
|
||||
sc->epb->eth_addr[i] = get_e(sc, EEPROM_NODE_ADDR_0 + i);
|
||||
}
|
||||
|
||||
if (first) {
|
||||
if (ep_pccard_attach(dp) == 0) {
|
||||
return (ENXIO);
|
||||
}
|
||||
sc->arpcom.ac_if.if_snd.ifq_maxlen = ifqmaxlen;
|
||||
}
|
||||
|
||||
if (!first) {
|
||||
sc->kdc->kdc_state = DC_IDLE;
|
||||
sc->gone = 0;
|
||||
printf("ep%d: resumed.\n", is->id_unit);
|
||||
epinit(sc);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ep_pccard_attach(dp)
|
||||
struct pccard_dev *dp;
|
||||
{
|
||||
#ifdef PC98
|
||||
struct pc98_device *is = &dp->isahd;
|
||||
#else
|
||||
struct isa_device *is = &dp->isahd;
|
||||
#endif
|
||||
struct ep_softc *sc = ep_softc[is->id_unit];
|
||||
u_short config;
|
||||
|
||||
sc->ep_connectors = 0;
|
||||
config = inw(IS_BASE + EP_W0_CONFIG_CTRL);
|
||||
if (config & IS_BNC) {
|
||||
sc->ep_connectors |= BNC;
|
||||
}
|
||||
if (config & IS_UTP) {
|
||||
sc->ep_connectors |= UTP;
|
||||
}
|
||||
if (!(sc->ep_connectors & 7))
|
||||
printf("no connectors!");
|
||||
sc->ep_connector = inw(BASE + EP_W0_ADDRESS_CFG) >> ACF_CONNECTOR_BITS;
|
||||
|
||||
/* ROM size = 0, ROM base = 0 */
|
||||
/* For now, ignore AUTO SELECT feature of 3C589B and later. */
|
||||
outw(BASE + EP_W0_ADDRESS_CFG, get_e(sc, EEPROM_ADDR_CFG) & 0xc000);
|
||||
|
||||
/* Fake IRQ must be 3 */
|
||||
outw(BASE + EP_W0_RESOURCE_CFG, (sc->epb->res_cfg & 0x0fff) | 0x3000);
|
||||
|
||||
outw(BASE + EP_W0_PRODUCT_ID, sc->epb->prod_id);
|
||||
|
||||
ep_attach(sc);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
ep_unload(dp)
|
||||
struct pccard_dev *dp;
|
||||
{
|
||||
struct ep_softc *sc = ep_softc[dp->isahd.id_unit];
|
||||
|
||||
if (sc->kdc->kdc_state == DC_UNCONFIGURED) {
|
||||
printf("ep%d: already unloaded\n", dp->isahd.id_unit);
|
||||
return;
|
||||
}
|
||||
sc->kdc->kdc_state = DC_UNCONFIGURED;
|
||||
sc->arpcom.ac_if.if_flags &= ~IFF_RUNNING;
|
||||
sc->gone = 1;
|
||||
printf("ep%d: unload\n", dp->isahd.id_unit);
|
||||
}
|
||||
|
||||
/*
|
||||
* card_intr - Shared interrupt called from
|
||||
* front end of PC-Card handler.
|
||||
*/
|
||||
static int
|
||||
card_intr(dp)
|
||||
struct pccard_dev *dp;
|
||||
{
|
||||
epintr(dp->isahd.id_unit);
|
||||
return(1);
|
||||
}
|
||||
|
||||
#endif /* NCRD > 0 */
|
||||
|
||||
static void
|
||||
ep_isa_registerdev(sc, id)
|
||||
struct ep_softc *sc;
|
||||
@ -229,7 +406,7 @@ ep_look_for_board_at(is)
|
||||
struct isa_device *is;
|
||||
#endif
|
||||
{
|
||||
int data, i, j, io_base, id_port = ELINK_ID_PORT;
|
||||
int data, i, j, id_port = ELINK_ID_PORT;
|
||||
int count = 0;
|
||||
|
||||
if (ep_current_tag == (EP_LAST_TAG + 1)) {
|
||||
@ -401,7 +578,10 @@ ep_isa_probe(is)
|
||||
struct ep_softc *sc;
|
||||
struct ep_board *epb;
|
||||
u_short k;
|
||||
int i;
|
||||
|
||||
#if NCRD > 0
|
||||
pccard_add_driver(&ep_info);
|
||||
#endif /* NCRD > 0 */
|
||||
|
||||
if(( epb=ep_look_for_board_at(is) )==0)
|
||||
return (0);
|
||||
@ -493,7 +673,7 @@ ep_isa_attach(is)
|
||||
GO_WINDOW(0);
|
||||
if(irq == 9)
|
||||
irq = 2;
|
||||
outw(BASE + EP_W0_RESOURCE_CFG, SET_IRQ(irq));
|
||||
SET_IRQ(BASE, irq);
|
||||
|
||||
ep_attach(sc);
|
||||
return 1;
|
||||
@ -508,6 +688,10 @@ ep_attach(sc)
|
||||
struct sockaddr_dl *sdl;
|
||||
u_short *p;
|
||||
int i;
|
||||
int attached;
|
||||
|
||||
sc->gone = 0;
|
||||
attached = (ifp->if_softc != 0);
|
||||
|
||||
printf("ep%d: ", sc->unit);
|
||||
/*
|
||||
@ -550,8 +734,10 @@ ep_attach(sc)
|
||||
ifp->if_ioctl = epioctl;
|
||||
ifp->if_watchdog = epwatchdog;
|
||||
|
||||
if (!attached) {
|
||||
if_attach(ifp);
|
||||
ether_ifattach(ifp);
|
||||
}
|
||||
|
||||
/* device attach does transition from UNCONFIGURED to IDLE state */
|
||||
sc->kdc->kdc_state=DC_IDLE;
|
||||
@ -599,7 +785,9 @@ ep_attach(sc)
|
||||
sc->top = sc->mcur = 0;
|
||||
|
||||
#if NBPFILTER > 0
|
||||
if (!attached) {
|
||||
bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@ -616,6 +804,9 @@ epinit(sc)
|
||||
register struct ifnet *ifp = &sc->arpcom.ac_if;
|
||||
int s, i, j;
|
||||
|
||||
if (sc->gone)
|
||||
return;
|
||||
|
||||
/*
|
||||
if (ifp->if_addrlist == (struct ifaddr *) 0)
|
||||
return;
|
||||
@ -682,39 +873,40 @@ epinit(sc)
|
||||
*
|
||||
*/
|
||||
|
||||
/* Set the xcvr. */
|
||||
if(ifp->if_flags & IFF_LINK0 && sc->ep_connectors & AUI) {
|
||||
/* nothing */
|
||||
i = ACF_CONNECTOR_AUI;
|
||||
} else if(ifp->if_flags & IFF_LINK1 && sc->ep_connectors & BNC) {
|
||||
outw(BASE + EP_COMMAND, START_TRANSCEIVER);
|
||||
DELAY(1000);
|
||||
i = ACF_CONNECTOR_BNC;
|
||||
} else if(ifp->if_flags & IFF_LINK2 && sc->ep_connectors & UTP) {
|
||||
GO_WINDOW(4);
|
||||
outw(BASE + EP_W4_MEDIA_TYPE, ENABLE_UTP);
|
||||
GO_WINDOW(1);
|
||||
i = ACF_CONNECTOR_UTP;
|
||||
} else {
|
||||
GO_WINDOW(1);
|
||||
switch(sc->ep_connector) {
|
||||
case ACF_CONNECTOR_UTP:
|
||||
if(sc->ep_connectors & UTP) {
|
||||
GO_WINDOW(4);
|
||||
outw(BASE + EP_W4_MEDIA_TYPE, ENABLE_UTP);
|
||||
GO_WINDOW(1);
|
||||
}
|
||||
break;
|
||||
case ACF_CONNECTOR_BNC:
|
||||
if(sc->ep_connectors & BNC) {
|
||||
outw(BASE + EP_COMMAND, START_TRANSCEIVER);
|
||||
DELAY(1000);
|
||||
}
|
||||
break;
|
||||
case ACF_CONNECTOR_AUI:
|
||||
/* nothing to do */
|
||||
break;
|
||||
default:
|
||||
printf("ep%d: strange connector type in EEPROM: assuming AUI\n",
|
||||
sc->unit);
|
||||
break;
|
||||
i = sc->ep_connector;
|
||||
}
|
||||
GO_WINDOW(0);
|
||||
j = inw(BASE + EP_W0_ADDRESS_CFG) & 0x3fff;
|
||||
outw(BASE + EP_W0_ADDRESS_CFG, j | (i << ACF_CONNECTOR_BITS));
|
||||
|
||||
switch(i) {
|
||||
case ACF_CONNECTOR_UTP:
|
||||
if(sc->ep_connectors & UTP) {
|
||||
GO_WINDOW(4);
|
||||
outw(BASE + EP_W4_MEDIA_TYPE, ENABLE_UTP);
|
||||
}
|
||||
break;
|
||||
case ACF_CONNECTOR_BNC:
|
||||
if(sc->ep_connectors & BNC) {
|
||||
outw(BASE + EP_COMMAND, START_TRANSCEIVER);
|
||||
DELAY(1000);
|
||||
}
|
||||
break;
|
||||
case ACF_CONNECTOR_AUI:
|
||||
/* nothing to do */
|
||||
break;
|
||||
default:
|
||||
printf("ep%d: strange connector type in EEPROM: assuming AUI\n",
|
||||
sc->unit);
|
||||
break;
|
||||
}
|
||||
|
||||
outw(BASE + EP_COMMAND, RX_ENABLE);
|
||||
@ -759,6 +951,7 @@ epinit(sc)
|
||||
sc->next_mb = 0;
|
||||
epmbuffill((caddr_t) sc, 0);
|
||||
|
||||
GO_WINDOW(1);
|
||||
epstart(ifp);
|
||||
|
||||
splx(s);
|
||||
@ -776,6 +969,10 @@ epstart(ifp)
|
||||
struct mbuf *top;
|
||||
int s, pad;
|
||||
|
||||
if (sc->gone) {
|
||||
return;
|
||||
}
|
||||
|
||||
s = splimp();
|
||||
if (ifp->if_flags & IFF_OACTIVE) {
|
||||
splx(s);
|
||||
@ -814,7 +1011,7 @@ epstart(ifp)
|
||||
}
|
||||
IF_DEQUEUE(&ifp->if_snd, m);
|
||||
|
||||
outw(BASE + EP_W1_TX_PIO_WR_1, len);
|
||||
outw(BASE + EP_W1_TX_PIO_WR_1, len | 0x8000); /* XXX */
|
||||
outw(BASE + EP_W1_TX_PIO_WR_1, 0x0); /* Second dword meaningless */
|
||||
|
||||
/* compute the Tx start threshold for this packet */
|
||||
@ -890,6 +1087,11 @@ epintr(unit)
|
||||
int unit;
|
||||
{
|
||||
register struct ep_softc *sc = ep_softc[unit];
|
||||
|
||||
if (sc->gone) {
|
||||
return;
|
||||
}
|
||||
|
||||
ep_intr(sc);
|
||||
}
|
||||
|
||||
@ -1389,6 +1591,8 @@ static void
|
||||
epwatchdog(ifp)
|
||||
struct ifnet *ifp;
|
||||
{
|
||||
struct ep_softc *sc = ifp->if_softc;
|
||||
|
||||
/*
|
||||
printf("ep: watchdog\n");
|
||||
|
||||
@ -1396,6 +1600,10 @@ epwatchdog(ifp)
|
||||
ifp->if_oerrors++;
|
||||
*/
|
||||
|
||||
if (sc->gone) {
|
||||
return;
|
||||
}
|
||||
|
||||
ifp->if_flags &= ~IFF_OACTIVE;
|
||||
epstart(ifp);
|
||||
ep_intr(ifp->if_softc);
|
||||
@ -1405,6 +1613,10 @@ static void
|
||||
epstop(sc)
|
||||
struct ep_softc *sc;
|
||||
{
|
||||
if (sc->gone) {
|
||||
return;
|
||||
}
|
||||
|
||||
outw(BASE + EP_COMMAND, RX_DISABLE);
|
||||
outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK);
|
||||
while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
|
||||
@ -1419,6 +1631,7 @@ epstop(sc)
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
static int
|
||||
send_ID_sequence(port)
|
||||
int port;
|
||||
@ -1433,6 +1646,7 @@ send_ID_sequence(port)
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
@ -31,7 +31,7 @@
|
||||
|
||||
*/
|
||||
/*
|
||||
* $Id: if_epreg.h,v 1.13 1996/02/28 17:19:04 gibbs Exp $
|
||||
* $Id: if_epreg.h,v 1.1.1.1 1996/06/14 10:04:44 asami Exp $
|
||||
*
|
||||
* Promiscuous mode added and interrupt logic slightly changed
|
||||
* to reduce the number of adapter failures. Transceiver select
|
||||
@ -43,6 +43,12 @@
|
||||
* babkin@hq.icb.chel.su
|
||||
*/
|
||||
|
||||
/*
|
||||
* Pccard support for 3C589 by:
|
||||
* HAMADA Naoki
|
||||
* nao@tom-yam.or.jp
|
||||
*/
|
||||
|
||||
/*
|
||||
* Ethernet software status per interface.
|
||||
*/
|
||||
@ -64,6 +70,7 @@ struct ep_softc {
|
||||
u_short ep_connectors; /* Connectors on this card. */
|
||||
u_char ep_connector; /* Configured connector. */
|
||||
int stat; /* some flags */
|
||||
int gone; /* adapter is not present (for PCCARD) */
|
||||
#define F_RX_FIRST 0x1
|
||||
#define F_WAIT_TRAIL 0x2
|
||||
#define F_RX_TRAILER 0x4
|
||||
@ -363,7 +370,9 @@ struct ep_board {
|
||||
*
|
||||
*/
|
||||
|
||||
#define SET_IRQ(i) (((i)<<12) | 0xF00) /* set IRQ i */
|
||||
#define SET_IRQ(base,irq) outw((base) + EP_W0_RESOURCE_CFG, \
|
||||
((inw((base) + EP_W0_RESOURCE_CFG) & 0x0fff) | \
|
||||
((u_short)(irq)<<12)) ) /* set IRQ i */
|
||||
|
||||
/*
|
||||
* FIFO Registers.
|
||||
|
@ -21,7 +21,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: if_fe.c,v 1.14 1996/04/23 18:36:55 nate Exp $
|
||||
* $Id: if_fe.c,v 1.1.1.1 1996/06/14 10:04:44 asami Exp $
|
||||
*
|
||||
* Device driver for Fujitsu MB86960A/MB86965A based Ethernet cards.
|
||||
* To be used with FreeBSD 2.x
|
||||
@ -128,11 +128,9 @@
|
||||
#include <machine/clock.h>
|
||||
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/pc98.h>
|
||||
#include <pc98/pc98/pc98_device.h>
|
||||
#include <pc98/pc98/icu.h>
|
||||
#else
|
||||
#include <i386/isa/isa.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/icu.h>
|
||||
#endif
|
||||
@ -264,13 +262,8 @@ static struct fe_softc {
|
||||
#define sc_description kdc.kdc_description
|
||||
|
||||
/* Standard driver entry points. These can be static. */
|
||||
#ifdef PC98
|
||||
static int fe_probe ( struct pc98_device * );
|
||||
static int fe_attach ( struct pc98_device * );
|
||||
#else
|
||||
static int fe_probe ( struct isa_device * );
|
||||
static int fe_attach ( struct isa_device * );
|
||||
#endif
|
||||
static int fe_probe ( DEVICE * );
|
||||
static int fe_attach ( DEVICE * );
|
||||
static void fe_init ( int );
|
||||
static int fe_ioctl ( struct ifnet *, int, caddr_t );
|
||||
static void fe_start ( struct ifnet * );
|
||||
@ -281,6 +274,7 @@ static void fe_watchdog ( struct ifnet * );
|
||||
static void fe_registerdev ( struct fe_softc *, DEVICE * );
|
||||
#ifdef PC98
|
||||
static int fe_probe_re1000 ( DEVICE *, struct fe_softc * );
|
||||
static int fe_probe_re1000p( DEVICE *, struct fe_softc * );
|
||||
#else
|
||||
static int fe_probe_fmv ( DEVICE *, struct fe_softc * );
|
||||
static int fe_probe_ati ( DEVICE *, struct fe_softc * );
|
||||
@ -369,40 +363,16 @@ static struct kern_devconf const fe_kdc_template =
|
||||
static void
|
||||
inblk ( struct fe_softc * sc, int offs, u_char * mem, int len )
|
||||
{
|
||||
#ifdef PC98
|
||||
u_short addr = sc->ioaddr[offs];
|
||||
#endif
|
||||
|
||||
while ( --len >= 0 ) {
|
||||
#ifdef PC98
|
||||
*mem++ = inb( addr );
|
||||
if (addr & 1)
|
||||
addr+=0x1FF;
|
||||
else
|
||||
addr++;
|
||||
#else
|
||||
*mem++ = inb( sc->ioaddr[ offs++ ] );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
outblk ( struct fe_softc * sc, int offs, u_char const * mem, int len )
|
||||
{
|
||||
#ifdef PC98
|
||||
u_short addr = sc->ioaddr[offs];
|
||||
#endif
|
||||
|
||||
while ( --len >= 0 ) {
|
||||
#ifdef PC98
|
||||
outb( addr, *mem++ );
|
||||
if (addr & 1)
|
||||
addr+=0x1FF;
|
||||
else
|
||||
addr++;
|
||||
#else
|
||||
outb( sc->ioaddr[ offs++ ], *mem++ );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -521,7 +491,10 @@ struct fe_probe_list
|
||||
/* Lists of possible addresses. */
|
||||
#ifdef PC98
|
||||
static u_short const fe_re1000_addr [] =
|
||||
{ 0xD0, 0xD2, 0xD4, 0xD8, 0x1D4, 0x1D6, 0x1D8, 0x1DA, 0 };
|
||||
{ 0x0D0, 0x0D2, 0x0D4, 0x0D6, 0x0D8, 0x0DA, 0x0DC, 0x0DE,
|
||||
0x1D0, 0x1D2, 0x1D4, 0x1D6, 0x1D8, 0x1DA, 0x1DC, 0x1DE, 0 };
|
||||
static u_short const fe_re1000p_addr [] =
|
||||
{ 0x0D0, 0x0D2, 0x0D4, 0x0D8, 0x1D4, 0x1D6, 0x1D8, 0x1DA, 0 };
|
||||
#else
|
||||
static u_short const fe_fmv_addr [] =
|
||||
{ 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x300, 0x340, 0 };
|
||||
@ -533,6 +506,7 @@ static struct fe_probe_list const fe_probe_list [] =
|
||||
{
|
||||
#ifdef PC98
|
||||
{ fe_probe_re1000, fe_re1000_addr },
|
||||
{ fe_probe_re1000p, fe_re1000p_addr },
|
||||
#else
|
||||
{ fe_probe_fmv, fe_fmv_addr },
|
||||
{ fe_probe_ati, fe_ati_addr },
|
||||
@ -661,11 +635,7 @@ fe_probe ( DEVICE * dev )
|
||||
*/
|
||||
struct fe_simple_probe_struct
|
||||
{
|
||||
#ifdef PC98
|
||||
u_short port; /* Offset from the base I/O address. */
|
||||
#else
|
||||
u_char port; /* Offset from the base I/O address. */
|
||||
#endif
|
||||
u_char mask; /* Bits to be checked. */
|
||||
u_char bits; /* Values to be compared against. */
|
||||
};
|
||||
@ -794,9 +764,101 @@ fe_read_eeprom ( struct fe_softc * sc, u_char * data )
|
||||
/*
|
||||
* Probe and initialization for Allied-Telesis RE1000 series.
|
||||
*/
|
||||
#if 1
|
||||
static int
|
||||
fe_probe_re1000 ( struct pc98_device * isa_dev, struct fe_softc * sc )
|
||||
fe_probe_re1000 ( DEVICE * isa_dev, struct fe_softc * sc )
|
||||
{
|
||||
int i, n;
|
||||
int dlcr6, dlcr7;
|
||||
u_char c = 0;
|
||||
|
||||
static u_short const irqmap [ 4 ] =
|
||||
{ IRQ3, IRQ5, IRQ6, IRQ12 };
|
||||
|
||||
#if FE_DEBUG >= 3
|
||||
log( LOG_INFO, "fe%d: probe (0x%x) for RE1000\n", sc->sc_unit, sc->iobase );
|
||||
fe_dump( LOG_INFO, sc, NULL );
|
||||
#endif
|
||||
|
||||
/* Setup an I/O address mapping table. */
|
||||
for ( i = 0; i < MAXREGISTERS; i++ ) {
|
||||
sc->ioaddr[ i ] = sc->iobase + (i/2)*0x200 + (i%2);
|
||||
}
|
||||
|
||||
/*
|
||||
* RE1000 does not use 86965 EEPROM interface.
|
||||
*/
|
||||
c ^= sc->sc_enaddr[0] = inb(sc->ioaddr[FE_RE1000_MAC0]);
|
||||
c ^= sc->sc_enaddr[1] = inb(sc->ioaddr[FE_RE1000_MAC1]);
|
||||
c ^= sc->sc_enaddr[2] = inb(sc->ioaddr[FE_RE1000_MAC2]);
|
||||
c ^= sc->sc_enaddr[3] = inb(sc->ioaddr[FE_RE1000_MAC3]);
|
||||
c ^= sc->sc_enaddr[4] = inb(sc->ioaddr[FE_RE1000_MAC4]);
|
||||
c ^= sc->sc_enaddr[5] = inb(sc->ioaddr[FE_RE1000_MAC5]);
|
||||
c ^= inb(sc->ioaddr[FE_RE1000_MACCHK]);
|
||||
if (c != 0) return 0;
|
||||
|
||||
if ( sc->sc_enaddr[ 0 ] != 0x00
|
||||
|| sc->sc_enaddr[ 1 ] != 0x00
|
||||
|| sc->sc_enaddr[ 2 ] != 0xF4 ) return 0;
|
||||
|
||||
/*
|
||||
* check interrupt configure
|
||||
*/
|
||||
for (n=0; n<4; n++) {
|
||||
if (isa_dev->id_irq == irqmap[n]) break;
|
||||
}
|
||||
if (n == 4) return 0;
|
||||
|
||||
/*
|
||||
* set irq
|
||||
*/
|
||||
c = inb(sc->ioaddr[FE_RE1000_IRQCONF]);
|
||||
c &= (~ FE_RE1000_IRQCONF_IRQ);
|
||||
c |= (1 << (n + FE_RE1000_IRQCONF_IRQSHIFT));
|
||||
outb(sc->ioaddr[FE_RE1000_IRQCONF], c);
|
||||
|
||||
sc->typestr = "RE1000";
|
||||
sc->sc_description = "Ethernet adapter: RE1000";
|
||||
|
||||
/*
|
||||
* Program the 86965 as follows:
|
||||
* SRAM: 32KB, 100ns, byte-wide access.
|
||||
* Transmission buffer: 4KB x 2.
|
||||
* System bus interface: 16 bits.
|
||||
*/
|
||||
sc->proto_dlcr4 = FE_D4_LBC_DISABLE | FE_D4_CNTRL; /* FIXME */
|
||||
sc->proto_dlcr5 = 0;
|
||||
sc->proto_dlcr6 = FE_D6_BUFSIZ_32KB | FE_D6_TXBSIZ_2x4KB
|
||||
| FE_D6_BBW_BYTE | FE_D6_SBW_WORD | FE_D6_SRAM_100ns;
|
||||
sc->proto_dlcr7 = FE_D7_BYTSWP_LH | FE_D7_IDENT_EC;
|
||||
sc->proto_bmpr13 = FE_B13_TPTYPE_UTP | FE_B13_PORT_AUTO;
|
||||
|
||||
#if FE_DEBUG >= 3
|
||||
fe_dump( LOG_INFO, sc, "RE1000 found" );
|
||||
#endif
|
||||
|
||||
/* Initialize 86965. */
|
||||
outb( sc->ioaddr[FE_DLCR6], sc->proto_dlcr6 | FE_D6_DLC_DISABLE );
|
||||
DELAY(200);
|
||||
|
||||
/* Disable all interrupts. */
|
||||
outb( sc->ioaddr[FE_DLCR2], 0 );
|
||||
outb( sc->ioaddr[FE_DLCR3], 0 );
|
||||
|
||||
#if FE_DEBUG >= 3
|
||||
fe_dump( LOG_INFO, sc, "end of fe_probe_re1000()" );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* That's all. RE1000 occupies 2*16 I/O addresses, by the way.
|
||||
*/
|
||||
return 2; /* ??? */
|
||||
}
|
||||
|
||||
/*
|
||||
* Probe and initialization for Allied-Telesis RE1000Plus/ME1500 series.
|
||||
*/
|
||||
static int
|
||||
fe_probe_re1000p ( DEVICE * isa_dev, struct fe_softc * sc )
|
||||
{
|
||||
int i, n, signature;
|
||||
int dlcr6, dlcr7;
|
||||
@ -829,23 +891,24 @@ fe_probe_re1000 ( struct pc98_device * isa_dev, struct fe_softc * sc )
|
||||
{ FE_DLCR10, 0xFF, 0xF4 },
|
||||
{ 0 }
|
||||
};
|
||||
static struct fe_simple_probe_struct const re1000_check [] = {
|
||||
{ FE_RE1000_MAC0, 0xff, 0x00 },
|
||||
{ FE_RE1000_MAC1, 0xff, 0x00 },
|
||||
{ FE_RE1000_MAC2, 0xff, 0xf4 }, /* ATI vendor code */
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
#if FE_DEBUG >= 3
|
||||
log( LOG_INFO, "fe%d: probe (0x%x) for RE1000/RE1000Plus/ME1500\n", sc->sc_unit, sc->iobase );
|
||||
log( LOG_INFO, "fe%d: probe (0x%x) for RE1000Plus/ME1500\n", sc->sc_unit, sc->iobase );
|
||||
fe_dump( LOG_INFO, sc, NULL );
|
||||
#endif
|
||||
|
||||
/* Setup an I/O address mapping table. */
|
||||
for ( i = 0; i < 16; i++ ) {
|
||||
sc->ioaddr[ i ] = sc->iobase + (i/2)*0x200 + (i%2);
|
||||
}
|
||||
for ( i = 16; i < MAXREGISTERS; i++ ) {
|
||||
sc->ioaddr[ i ] = sc->iobase + i*0x200 - 0x1000;
|
||||
}
|
||||
|
||||
/* First, check the "signature" */
|
||||
signature = 0;
|
||||
if (fe_simple_probe(sc, probe_signature1)) {
|
||||
|
||||
outb(sc->iobase+FE_DLCR6, (inb(sc->iobase+FE_DLCR6) & 0xCF) | 0x16);
|
||||
outb(sc->ioaddr[FE_DLCR6], (inb(sc->ioaddr[FE_DLCR6]) & 0xCF) | 0x16);
|
||||
if (fe_simple_probe(sc, probe_signature2))
|
||||
signature = 1;
|
||||
}
|
||||
@ -861,290 +924,85 @@ fe_probe_re1000 ( struct pc98_device * isa_dev, struct fe_softc * sc )
|
||||
if (!fe_simple_probe(sc, probe_table)) return 0;
|
||||
|
||||
/* Disable DLC */
|
||||
dlcr6 = inb(sc->iobase + FE_DLCR6);
|
||||
outb(sc->iobase + FE_DLCR6, dlcr6 | FE_D6_DLC_DISABLE);
|
||||
dlcr6 = inb(sc->ioaddr[FE_DLCR6]);
|
||||
outb(sc->ioaddr[FE_DLCR6], dlcr6 | FE_D6_DLC_DISABLE);
|
||||
/* Select register bank for DLCR */
|
||||
dlcr7 = inb(sc->iobase + FE_DLCR7);
|
||||
outb(sc->iobase + FE_DLCR7, dlcr7 & 0xF3 | FE_D7_RBS_DLCR);
|
||||
dlcr7 = inb(sc->ioaddr[FE_DLCR7]);
|
||||
outb(sc->ioaddr[FE_DLCR7], dlcr7 & 0xF3 | FE_D7_RBS_DLCR);
|
||||
|
||||
/* Check the Ethernet address */
|
||||
if (!fe_simple_probe(sc, vendor_code)) return 0;
|
||||
|
||||
/* Restore configuration registers */
|
||||
DELAY(200);
|
||||
outb(sc->iobase + FE_DLCR6, dlcr6);
|
||||
outb(sc->iobase + FE_DLCR7, dlcr7);
|
||||
outb(sc->ioaddr[FE_DLCR6], dlcr6);
|
||||
outb(sc->ioaddr[FE_DLCR7], dlcr7);
|
||||
}
|
||||
|
||||
#if 1
|
||||
/*
|
||||
* This test doesn't work well for RE1000 look-alike by
|
||||
* other vendors.
|
||||
* We are now almost sure we have an 86965 at the given
|
||||
* address. So, read EEPROM through 86965. We have to write
|
||||
* into LSI registers to read from EEPROM. I want to avoid it
|
||||
* at this stage, but I cannot test the presense of the chip
|
||||
* any further without reading EEPROM. FIXME.
|
||||
*/
|
||||
if ( fe_simple_probe( sc, re1000_check )){
|
||||
/*
|
||||
* RE1000 does not use 86965 EEPROM interface.
|
||||
*/
|
||||
u_char c = 0;
|
||||
c ^= sc->sc_enaddr[0] = inb(sc->iobase + FE_RE1000_MAC0);
|
||||
c ^= sc->sc_enaddr[1] = inb(sc->iobase + FE_RE1000_MAC1);
|
||||
c ^= sc->sc_enaddr[2] = inb(sc->iobase + FE_RE1000_MAC2);
|
||||
c ^= sc->sc_enaddr[3] = inb(sc->iobase + FE_RE1000_MAC3);
|
||||
c ^= sc->sc_enaddr[4] = inb(sc->iobase + FE_RE1000_MAC4);
|
||||
c ^= sc->sc_enaddr[5] = inb(sc->iobase + FE_RE1000_MAC5);
|
||||
c ^= inb(sc->iobase + FE_RE1000_MACCHK);
|
||||
if (c != 0) return 0;
|
||||
fe_read_eeprom( sc, eeprom );
|
||||
|
||||
if ( sc->sc_enaddr[ 0 ] != 0x00
|
||||
|| sc->sc_enaddr[ 1 ] != 0x00
|
||||
|| sc->sc_enaddr[ 2 ] != 0xF4 ) return 0;
|
||||
|
||||
/*
|
||||
* check interrupt configure
|
||||
*/
|
||||
for (n=0; n<4; n++) {
|
||||
if (isa_dev->id_irq == irqmap[n]) break;
|
||||
}
|
||||
if (n == 4) return 0;
|
||||
|
||||
/*
|
||||
* set irq
|
||||
*/
|
||||
c = inb(sc->iobase + FE_RE1000_IRQCONF);
|
||||
c &= (~ FE_RE1000_IRQCONF_IRQ);
|
||||
c |= (1 << (n + FE_RE1000_IRQCONF_IRQSHIFT));
|
||||
outb(sc->iobase + FE_RE1000_IRQCONF, c);
|
||||
#if 0
|
||||
PC98WAIT; PC98WAIT;
|
||||
if (c == (inb(sc->iobase + FE_RE1000_IRQCONF)
|
||||
& FE_RE1000_IRQCONF_IRQ)) return 0;
|
||||
#endif
|
||||
|
||||
sc->typestr = "RE1000";
|
||||
sc->sc_description = "Ethernet adapter: RE1000";
|
||||
|
||||
} else {
|
||||
/*
|
||||
* We are now almost sure we have an 86965 at the given
|
||||
* address. So, read EEPROM through 86965. We have to write
|
||||
* into LSI registers to read from EEPROM. I want to avoid it
|
||||
* at this stage, but I cannot test the presense of the chip
|
||||
* any further without reading EEPROM. FIXME.
|
||||
*/
|
||||
fe_read_eeprom( sc, eeprom );
|
||||
|
||||
/* Make sure that config info in EEPROM and 86965 agree. */
|
||||
if ( eeprom[ FE_EEPROM_CONF ] != inb( sc->iobase + FE_BMPR19 ) ) {
|
||||
/* Make sure that config info in EEPROM and 86965 agree. */
|
||||
if ( eeprom[ FE_EEPROM_CONF ] != inb( sc->ioaddr[FE_BMPR19] ) ) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize constants in the per-line structure.
|
||||
*/
|
||||
/*
|
||||
* Initialize constants in the per-line structure.
|
||||
*/
|
||||
|
||||
/* Get our station address from EEPROM. */
|
||||
bcopy( eeprom + FE_ATI_EEP_ADDR, sc->sc_enaddr, ETHER_ADDR_LEN );
|
||||
|
||||
sc->typestr = "RE1000Plus/ME1500";
|
||||
sc->sc_description = "Ethernet adapter: RE1000Plus/ME1500";
|
||||
/*
|
||||
* Read IRQ configuration.
|
||||
*/
|
||||
n = (inb(sc->iobase + FE_BMPR19) & FE_B19_IRQ ) >> FE_B19_IRQ_SHIFT;
|
||||
isa_dev->id_irq = irqmap[n];
|
||||
}
|
||||
/* Get our station address from EEPROM. */
|
||||
bcopy( eeprom + FE_ATI_EEP_ADDR, sc->sc_enaddr, ETHER_ADDR_LEN );
|
||||
|
||||
#else
|
||||
/* Make sure we got a valid station address. */
|
||||
if ( ( sc->sc_enaddr[ 0 ] & 0x03 ) != 0x00
|
||||
|| ( sc->sc_enaddr[ 0 ] == 0x00
|
||||
&& sc->sc_enaddr[ 1 ] == 0x00
|
||||
&& sc->sc_enaddr[ 2 ] == 0x00 ) ) return 0;
|
||||
#endif
|
||||
|
||||
/* Should find all register prototypes here. FIXME. */
|
||||
sc->proto_dlcr4 = FE_D4_LBC_DISABLE | FE_D4_CNTRL; /* FIXME */
|
||||
sc->proto_dlcr5 = 0;
|
||||
sc->proto_dlcr7 = FE_D7_BYTSWP_LH | FE_D7_IDENT_EC;
|
||||
|
||||
/*
|
||||
* Program the 86965 as follows:
|
||||
* SRAM: 32KB, 100ns, byte-wide access.
|
||||
* Transmission buffer: 4KB x 2.
|
||||
* System bus interface: 16 bits.
|
||||
* We cannot change these values but TXBSIZE, because they
|
||||
* are hard-wired on the board. Modifying TXBSIZE will affect
|
||||
* the driver performance.
|
||||
*/
|
||||
sc->proto_dlcr6 = FE_D6_BUFSIZ_32KB | FE_D6_TXBSIZ_2x4KB
|
||||
| FE_D6_BBW_BYTE | FE_D6_SBW_WORD | FE_D6_SRAM_100ns;
|
||||
|
||||
#if FE_DEBUG >= 3
|
||||
fe_dump( LOG_INFO, sc, "RE1000 found" );
|
||||
#endif
|
||||
|
||||
/* Initialize 86965. */
|
||||
outb( sc->iobase + FE_DLCR6, sc->proto_dlcr6 | FE_D6_DLC_DISABLE );
|
||||
DELAY(200);
|
||||
|
||||
/* Disable all interrupts. */
|
||||
outb( sc->iobase + FE_DLCR2, 0 );
|
||||
outb( sc->iobase + FE_DLCR3, 0 );
|
||||
|
||||
#if FE_DEBUG >= 3
|
||||
fe_dump( LOG_INFO, sc, "end of fe_probe_re1000()" );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* That's all. RE1000 occupies 2*16 I/O addresses, by the way.
|
||||
*/
|
||||
return 2; /* ??? */
|
||||
}
|
||||
#else
|
||||
static int
|
||||
fe_probe_re1000 ( struct pc98_device * isa_dev, struct fe_softc * sc )
|
||||
{
|
||||
int i, n, signature;
|
||||
int dlcr6, dlcr7;
|
||||
u_char eeprom [ FE_EEPROM_SIZE ];
|
||||
|
||||
static u_short const irqmap [ 4 ] =
|
||||
{ IRQ3, IRQ5, IRQ6, IRQ12 };
|
||||
static struct fe_simple_probe_struct const probe_signature1 [] = {
|
||||
{ FE_DLCR0, 0xBF, 0x00 },
|
||||
{ FE_DLCR2, 0xFF, 0x00 },
|
||||
{ FE_DLCR4, 0x0F, 0x06 },
|
||||
{ FE_DLCR6, 0x0F, 0x06 },
|
||||
{ 0 }
|
||||
};
|
||||
static struct fe_simple_probe_struct const probe_signature2 [] = {
|
||||
{ FE_DLCR1, 0xFF, 0x00 },
|
||||
{ FE_DLCR3, 0xFF, 0x00 },
|
||||
{ FE_DLCR5, 0xFF, 0x41 },
|
||||
{ 0 }
|
||||
};
|
||||
static struct fe_simple_probe_struct const probe_table [] = {
|
||||
{ FE_DLCR2, 0x71, 0x00 },
|
||||
{ FE_DLCR4, 0x08, 0x00 },
|
||||
{ FE_DLCR5, 0x80, 0x00 },
|
||||
{ 0 }
|
||||
};
|
||||
static struct fe_simple_probe_struct const vendor_code [] = {
|
||||
{ FE_DLCR8, 0xFF, 0x00 },
|
||||
{ FE_DLCR9, 0xFF, 0x00 },
|
||||
{ FE_DLCR10, 0xFF, 0xF4 },
|
||||
{ 0 }
|
||||
};
|
||||
static struct fe_simple_probe_struct const re1000_check [] = {
|
||||
{ FE_RE1000_MAC0, 0xff, 0x00 },
|
||||
{ FE_RE1000_MAC1, 0xff, 0x00 },
|
||||
{ FE_RE1000_MAC2, 0xff, 0xf4 }, /* ATI vendor code */
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
#if FE_DEBUG >= 3
|
||||
log( LOG_INFO, "fe%d: probe (0x%x) for RE1000\n", sc->sc_unit, sc->iobase );
|
||||
fe_dump( LOG_INFO, sc, NULL );
|
||||
#endif
|
||||
|
||||
/* First, check the "signature" */
|
||||
signature = 0;
|
||||
if (fe_simple_probe(sc, probe_signature1)) {
|
||||
|
||||
outb(sc->iobase+FE_DLCR6, (inb(sc->iobase+FE_DLCR6) & 0xCF) | 0x16);
|
||||
if (fe_simple_probe(sc, probe_signature2))
|
||||
signature = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the "signature" not detected, RE1000 *might* be previously
|
||||
* initialized. So, check the Ethernet address here.
|
||||
*
|
||||
* Allied-Telesis uses 00 00 F4 ?? ?? ??.
|
||||
*/
|
||||
if (signature == 0) {
|
||||
/* Simple check */
|
||||
if (!fe_simple_probe(sc, probe_table)) return 0;
|
||||
|
||||
/* Disable DLC */
|
||||
dlcr6 = inb(sc->iobase + FE_DLCR6);
|
||||
outb(sc->iobase + FE_DLCR6, dlcr6 | FE_D6_DLC_DISABLE);
|
||||
/* Select register bank for DLCR */
|
||||
dlcr7 = inb(sc->iobase + FE_DLCR7);
|
||||
outb(sc->iobase + FE_DLCR7, dlcr7 & 0xF3 | FE_D7_RBS_DLCR);
|
||||
|
||||
/* Check the Ethernet address */
|
||||
if (!fe_simple_probe(sc, vendor_code)) return 0;
|
||||
|
||||
/* Restore configuration registers */
|
||||
DELAY(200);
|
||||
outb(sc->iobase + FE_DLCR6, dlcr6);
|
||||
outb(sc->iobase + FE_DLCR7, dlcr7);
|
||||
}
|
||||
sc->typestr = "RE1000Plus/ME1500";
|
||||
sc->sc_description = "Ethernet adapter: RE1000Plus/ME1500";
|
||||
|
||||
/*
|
||||
* Read IRQ configuration.
|
||||
*/
|
||||
n = (inb(sc->iobase + 0x1600) & FE_B19_IRQ ) >> FE_B19_IRQ_SHIFT;
|
||||
n = (inb(sc->ioaddr[FE_BMPR19]) & FE_B19_IRQ ) >> FE_B19_IRQ_SHIFT;
|
||||
isa_dev->id_irq = irqmap[n];
|
||||
|
||||
#if 1
|
||||
/*
|
||||
* This test doesn't work well for RE1000 look-alike by
|
||||
* other vendors.
|
||||
*/
|
||||
/* Make sure the vendor part is for Allied-Telesis. */
|
||||
if ( sc->sc_enaddr[ 0 ] != 0x00
|
||||
|| sc->sc_enaddr[ 1 ] != 0x00
|
||||
|| sc->sc_enaddr[ 2 ] != 0xF4 ) return 0;
|
||||
|
||||
#else
|
||||
/* Make sure we got a valid station address. */
|
||||
if ( ( sc->sc_enaddr[ 0 ] & 0x03 ) != 0x00
|
||||
|| ( sc->sc_enaddr[ 0 ] == 0x00
|
||||
&& sc->sc_enaddr[ 1 ] == 0x00
|
||||
&& sc->sc_enaddr[ 2 ] == 0x00 ) ) return 0;
|
||||
#endif
|
||||
|
||||
/* Should find all register prototypes here. FIXME. */
|
||||
sc->proto_dlcr4 = FE_D4_LBC_DISABLE | FE_D4_CNTRL; /* FIXME */
|
||||
sc->proto_dlcr5 = 0;
|
||||
sc->proto_dlcr7 = FE_D7_BYTSWP_LH | FE_D7_IDENT_EC;
|
||||
|
||||
/*
|
||||
* Program the 86965 as follows:
|
||||
* SRAM: 32KB, 100ns, byte-wide access.
|
||||
* Transmission buffer: 4KB x 2.
|
||||
* System bus interface: 16 bits.
|
||||
* We cannot change these values but TXBSIZE, because they
|
||||
* are hard-wired on the board. Modifying TXBSIZE will affect
|
||||
* the driver performance.
|
||||
*/
|
||||
sc->proto_dlcr4 = FE_D4_LBC_DISABLE | FE_D4_CNTRL; /* FIXME */
|
||||
sc->proto_dlcr5 = 0;
|
||||
sc->proto_dlcr6 = FE_D6_BUFSIZ_32KB | FE_D6_TXBSIZ_2x4KB
|
||||
| FE_D6_BBW_BYTE | FE_D6_SBW_WORD | FE_D6_SRAM_100ns;
|
||||
sc->proto_dlcr7 = FE_D7_BYTSWP_LH | FE_D7_IDENT_EC;
|
||||
sc->proto_bmpr13 = FE_B13_TPTYPE_UTP | FE_B13_PORT_AUTO;
|
||||
|
||||
#if FE_DEBUG >= 3
|
||||
fe_dump( LOG_INFO, sc, "RE1000 found" );
|
||||
fe_dump( LOG_INFO, sc, "RE1000Plus/ME1500 found" );
|
||||
#endif
|
||||
|
||||
/* Initialize 86965. */
|
||||
outb( sc->iobase + FE_DLCR6, sc->proto_dlcr6 | FE_D6_DLC_DISABLE );
|
||||
outb( sc->ioaddr[FE_DLCR6], sc->proto_dlcr6 | FE_D6_DLC_DISABLE );
|
||||
DELAY(200);
|
||||
|
||||
/* Disable all interrupts. */
|
||||
outb( sc->iobase + FE_DLCR2, 0 );
|
||||
outb( sc->iobase + FE_DLCR3, 0 );
|
||||
outb( sc->ioaddr[FE_DLCR2], 0 );
|
||||
outb( sc->ioaddr[FE_DLCR3], 0 );
|
||||
|
||||
#if FE_DEBUG >= 3
|
||||
fe_dump( LOG_INFO, sc, "end of fe_probe_re1000()" );
|
||||
fe_dump( LOG_INFO, sc, "end of fe_probe_re1000p()" );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* That's all. AT1700 occupies 2*16 I/O addresses, by the way.
|
||||
* That's all. RE1000Plus/ME1500 occupies 2*16 I/O addresses, by the way.
|
||||
*/
|
||||
return 2; /* ??? */
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
/*
|
||||
* Probe and initialization for Fujitsu FMV-180 series boards
|
||||
@ -1519,7 +1377,7 @@ fe_probe_ati ( DEVICE * dev, struct fe_softc * sc )
|
||||
*/
|
||||
|
||||
/* Get our station address from EEPROM. */
|
||||
bcopy( eeprom + FE_EEP_ATI_ADDR, sc->sc_enaddr, ETHER_ADDR_LEN );
|
||||
bcopy( eeprom + FE_ATI_EEP_ADDR, sc->sc_enaddr, ETHER_ADDR_LEN );
|
||||
|
||||
#if 1
|
||||
/*
|
||||
@ -3065,7 +2923,6 @@ fe_write_mbufs ( struct fe_softc *sc, struct mbuf *m )
|
||||
{
|
||||
u_short addr_bmpr8 = sc->ioaddr[ FE_BMPR8 ];
|
||||
u_short length, len;
|
||||
short pad;
|
||||
struct mbuf *mp;
|
||||
u_char *data;
|
||||
u_short savebyte; /* WARNING: Architecture dependent! */
|
||||
|
@ -24,7 +24,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* $Id: if_fereg.h,v 1.3 1996/03/17 08:36:38 jkh Exp $ */
|
||||
/* $Id: if_fereg.h,v 1.1.1.1 1996/06/14 10:04:44 asami Exp $ */
|
||||
|
||||
/*
|
||||
* Registers on FMV-180 series' ISA bus interface ASIC.
|
||||
@ -115,35 +115,18 @@
|
||||
*/
|
||||
|
||||
/* IRQ configuration. */
|
||||
#ifdef PC98
|
||||
#define FE_RE1000_IRQCONF 0x1000
|
||||
#else
|
||||
#define FE_RE1000_IRQCONF 0x10
|
||||
#endif
|
||||
#define FE_RE1000_IRQCONF_IRQ 0xf0
|
||||
#define FE_RE1000_IRQCONF_IRQSHIFT 4
|
||||
|
||||
/* MAC (station) address. */
|
||||
#ifdef PC98
|
||||
#define FE_RE1000_MAC0 0x1001
|
||||
#define FE_RE1000_MAC1 0x1201
|
||||
#define FE_RE1000_MAC2 0x1401
|
||||
#define FE_RE1000_MAC3 0x1601
|
||||
#define FE_RE1000_MAC4 0x1801
|
||||
#define FE_RE1000_MAC5 0x1a01
|
||||
#else
|
||||
#define FE_RE1000_MAC0 0x11
|
||||
#define FE_RE1000_MAC1 0x13
|
||||
#define FE_RE1000_MAC2 0x15
|
||||
#define FE_RE1000_MAC3 0x17
|
||||
#define FE_RE1000_MAC4 0x19
|
||||
#define FE_RE1000_MAC5 0x1B
|
||||
#endif
|
||||
|
||||
/* "Check sum" -- an xor of MAC0 through MAC5 */
|
||||
#ifdef PC98
|
||||
#define FE_RE1000_MACCHK 0x1c01 /* xor data MAC0 through MAC5 */
|
||||
#else
|
||||
#define FE_RE1000_MACCHK 0x1D
|
||||
#endif
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* From: if_ep.c,v 1.9 1994/01/25 10:46:29 deraadt Exp $
|
||||
* $Id: if_zp.c,v 1.19 1996/06/04 21:41:01 nate Exp $
|
||||
* $Id: if_zp.c,v 1.1.1.1 1996/06/14 10:04:44 asami Exp $
|
||||
*/
|
||||
/*-
|
||||
* TODO:
|
||||
@ -144,17 +144,14 @@
|
||||
#endif
|
||||
|
||||
#include <machine/clock.h>
|
||||
#include <machine/md_var.h>
|
||||
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/pc98.h>
|
||||
#include <pc98/pc98/pc98_device.h>
|
||||
#include <pc98/pc98/icu.h>
|
||||
#include <pc98/pc98/if_zpreg.h>
|
||||
#include <pc98/pc98/pcic.h>
|
||||
#else
|
||||
#include <i386/isa/isa.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/icu.h>
|
||||
#include <i386/isa/if_zpreg.h>
|
||||
#include <i386/isa/pcic.h>
|
||||
#endif
|
||||
@ -361,7 +358,7 @@ zpprobe(struct isa_device * isa_dev)
|
||||
int re_init_flag;
|
||||
|
||||
if ((slot = zp_find_adapter(isa_dev->id_maddr, isa_dev->id_reconfig)) < 0)
|
||||
return NULL;
|
||||
return 0;
|
||||
|
||||
/* okay, we found a card, so set it up */
|
||||
/* Inhibit 16 bit memory delay. POINTETH.SYS apparently does this, for
|
||||
@ -510,8 +507,6 @@ zpattach(isa_dev)
|
||||
struct zp_softc *sc = &zp_softc[isa_dev->id_unit];
|
||||
struct ifnet *ifp = &sc->arpcom.ac_if;
|
||||
u_short i;
|
||||
struct ifaddr *ifa;
|
||||
struct sockaddr_dl *sdl;
|
||||
int pl;
|
||||
|
||||
/* PCMCIA card can be offlined. Reconfiguration is required */
|
||||
|
@ -46,7 +46,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: unknown origin, 386BSD 0.1
|
||||
* $Id: lpt.c,v 1.53 1996/04/04 12:28:36 joerg Exp $
|
||||
* $Id: lpt.c,v 1.1.1.1 1996/06/14 10:04:44 asami Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -203,7 +203,7 @@
|
||||
#define lprintf (void)
|
||||
#else
|
||||
#define lprintf if (lptflag) printf
|
||||
int lptflag = 1;
|
||||
static int volatile lptflag = 1;
|
||||
#endif
|
||||
|
||||
#define LPTUNIT(s) ((s)&0x03)
|
||||
|
@ -35,13 +35,10 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
|
||||
* $Id: machdep.c,v 1.192 1996/06/08 11:03:01 bde Exp $
|
||||
* $Id: machdep.c,v 1.1.1.1 1996/06/14 10:04:41 asami Exp $
|
||||
*/
|
||||
|
||||
#include "npx.h"
|
||||
#ifndef PC98
|
||||
#include "isa.h"
|
||||
#endif
|
||||
#include "opt_sysvipc.h"
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_bounce.h"
|
||||
@ -117,10 +114,9 @@
|
||||
#endif
|
||||
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/pc98.h>
|
||||
#include <pc98/pc98/pc98_device.h>
|
||||
#include <pc98/pc98/pc98_machdep.h>
|
||||
#else
|
||||
#include <i386/isa/isa.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/rtc.h>
|
||||
#endif
|
||||
@ -132,31 +128,12 @@ extern int ptrace_single_step __P((struct proc *p));
|
||||
extern int ptrace_write_u __P((struct proc *p, vm_offset_t off, int data));
|
||||
extern void dblfault_handler __P((void));
|
||||
|
||||
extern void i486_bzero __P((void *, size_t));
|
||||
extern void i586_bzero __P((void *, size_t));
|
||||
extern void i686_bzero __P((void *, size_t));
|
||||
extern void identifycpu(void); /* XXX header file */
|
||||
extern void earlysetcpuclass(void); /* same header file */
|
||||
|
||||
static void cpu_startup __P((void *));
|
||||
SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL)
|
||||
|
||||
static void identifycpu(void);
|
||||
|
||||
char machine[] = "i386";
|
||||
SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, "");
|
||||
|
||||
static char cpu_model[128];
|
||||
SYSCTL_STRING(_hw, HW_MODEL, model, CTLFLAG_RD, cpu_model, 0, "");
|
||||
|
||||
struct kern_devconf kdc_cpu0 = {
|
||||
0, 0, 0, /* filled in by dev_attach */
|
||||
"cpu", 0, { MDDT_CPU },
|
||||
0, 0, 0, CPU_EXTERNALLEN,
|
||||
0, /* CPU has no parent */
|
||||
0, /* no parentdata */
|
||||
DC_BUSY, /* the CPU is always busy */
|
||||
cpu_model, /* no sense in duplication */
|
||||
DC_CLS_CPU /* class */
|
||||
};
|
||||
|
||||
#ifndef PANIC_REBOOT_WAIT_TIME
|
||||
#define PANIC_REBOOT_WAIT_TIME 15 /* default to 15 seconds */
|
||||
@ -206,8 +183,6 @@ int boothowto = 0, bootverbose = 0, Maxmem = 0;
|
||||
static int badpages = 0;
|
||||
#ifdef PC98
|
||||
int Maxmem_under16M = 0;
|
||||
extern pt_entry_t *panic_kwin_pte;
|
||||
extern caddr_t panic_kwin;
|
||||
#endif
|
||||
long dumplo;
|
||||
extern int bootdev;
|
||||
@ -217,8 +192,6 @@ vm_offset_t phys_avail[10];
|
||||
/* must be 2 less so 0 0 can signal end of chunks */
|
||||
#define PHYS_AVAIL_ARRAY_END ((sizeof(phys_avail) / sizeof(vm_offset_t)) - 2)
|
||||
|
||||
int cpu_class = CPUCLASS_386; /* smallest common denominator */
|
||||
|
||||
static void dumpsys __P((void));
|
||||
static void setup_netisrs __P((struct linker_set *)); /* XXX declare elsewhere */
|
||||
|
||||
@ -258,9 +231,12 @@ cpu_startup(dummy)
|
||||
* Good {morning,afternoon,evening,night}.
|
||||
*/
|
||||
printf(version);
|
||||
cpu_class = i386_cpus[cpu].cpu_class;
|
||||
earlysetcpuclass();
|
||||
startrtclock();
|
||||
identifycpu();
|
||||
#ifdef PERFMON
|
||||
perfmon_init();
|
||||
#endif
|
||||
printf("real memory = %d (%dK bytes)\n", ptoa(Maxmem), ptoa(Maxmem) / 1024);
|
||||
/*
|
||||
* Display any holes after the first chunk of extended memory.
|
||||
@ -499,176 +475,6 @@ setup_netisrs(ls)
|
||||
}
|
||||
}
|
||||
|
||||
static struct cpu_nameclass i386_cpus[] = {
|
||||
{ "Intel 80286", CPUCLASS_286 }, /* CPU_286 */
|
||||
{ "i386SX", CPUCLASS_386 }, /* CPU_386SX */
|
||||
{ "i386DX", CPUCLASS_386 }, /* CPU_386 */
|
||||
{ "i486SX", CPUCLASS_486 }, /* CPU_486SX */
|
||||
{ "i486DX", CPUCLASS_486 }, /* CPU_486 */
|
||||
{ "Pentium", CPUCLASS_586 }, /* CPU_586 */
|
||||
{ "Cy486DLC", CPUCLASS_486 }, /* CPU_486DLC */
|
||||
{ "Pentium Pro", CPUCLASS_686 }, /* CPU_686 */
|
||||
};
|
||||
|
||||
static void
|
||||
identifycpu()
|
||||
{
|
||||
printf("CPU: ");
|
||||
strncpy(cpu_model, i386_cpus[cpu].cpu_name, sizeof cpu_model);
|
||||
|
||||
#if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU)
|
||||
if (!strcmp(cpu_vendor,"GenuineIntel")) {
|
||||
if ((cpu_id & 0xf00) > 3) {
|
||||
cpu_model[0] = '\0';
|
||||
|
||||
switch (cpu_id & 0x3000) {
|
||||
case 0x1000:
|
||||
strcpy(cpu_model, "Overdrive ");
|
||||
break;
|
||||
case 0x2000:
|
||||
strcpy(cpu_model, "Dual ");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (cpu_id & 0xf00) {
|
||||
case 0x400:
|
||||
strcat(cpu_model, "i486 ");
|
||||
break;
|
||||
case 0x500:
|
||||
strcat(cpu_model, "Pentium"); /* nb no space */
|
||||
break;
|
||||
case 0x600:
|
||||
strcat(cpu_model, "Pentium Pro");
|
||||
break;
|
||||
default:
|
||||
strcat(cpu_model, "unknown");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (cpu_id & 0xff0) {
|
||||
case 0x400:
|
||||
strcat(cpu_model, "DX"); break;
|
||||
case 0x410:
|
||||
strcat(cpu_model, "DX"); break;
|
||||
case 0x420:
|
||||
strcat(cpu_model, "SX"); break;
|
||||
case 0x430:
|
||||
strcat(cpu_model, "DX2"); break;
|
||||
case 0x440:
|
||||
strcat(cpu_model, "SL"); break;
|
||||
case 0x450:
|
||||
strcat(cpu_model, "SX2"); break;
|
||||
case 0x470:
|
||||
strcat(cpu_model, "DX2 Write-Back Enhanced");
|
||||
break;
|
||||
case 0x480:
|
||||
strcat(cpu_model, "DX4"); break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
printf("%s (", cpu_model);
|
||||
switch(cpu_class) {
|
||||
case CPUCLASS_286:
|
||||
printf("286");
|
||||
break;
|
||||
#if defined(I386_CPU)
|
||||
case CPUCLASS_386:
|
||||
printf("386");
|
||||
break;
|
||||
#endif
|
||||
#if defined(I486_CPU)
|
||||
case CPUCLASS_486:
|
||||
printf("486");
|
||||
bzero = i486_bzero;
|
||||
break;
|
||||
#endif
|
||||
#if defined(I586_CPU)
|
||||
case CPUCLASS_586:
|
||||
printf("%d.%02d-MHz ",
|
||||
((100 * i586_ctr_rate) >> I586_CTR_RATE_SHIFT) / 100,
|
||||
((100 * i586_ctr_rate) >> I586_CTR_RATE_SHIFT) % 100);
|
||||
printf("586");
|
||||
break;
|
||||
#endif
|
||||
#if defined(I686_CPU)
|
||||
case CPUCLASS_686:
|
||||
printf("%d.%02d-MHz ",
|
||||
((100 * i586_ctr_rate) >> I586_CTR_RATE_SHIFT) / 100,
|
||||
((100 * i586_ctr_rate) >> I586_CTR_RATE_SHIFT) % 100);
|
||||
printf("686");
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
printf("unknown"); /* will panic below... */
|
||||
}
|
||||
printf("-class CPU)\n");
|
||||
#if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU)
|
||||
if(*cpu_vendor)
|
||||
printf(" Origin = \"%s\"",cpu_vendor);
|
||||
if(cpu_id)
|
||||
printf(" Id = 0x%lx",cpu_id);
|
||||
|
||||
if (!strcmp(cpu_vendor, "GenuineIntel")) {
|
||||
printf(" Stepping=%ld", cpu_id & 0xf);
|
||||
if (cpu_high > 0) {
|
||||
printf("\n Features=0x%b", cpu_feature,
|
||||
"\020"
|
||||
"\001FPU"
|
||||
"\002VME"
|
||||
"\003DE"
|
||||
"\004PSE"
|
||||
"\005TSC"
|
||||
"\006MSR"
|
||||
"\007PAE"
|
||||
"\010MCE"
|
||||
"\011CX8"
|
||||
"\012APIC"
|
||||
"\013<b10>"
|
||||
"\014<b11>"
|
||||
"\015MTRR"
|
||||
"\016PGE"
|
||||
"\017MCA"
|
||||
"\020CMOV"
|
||||
);
|
||||
}
|
||||
}
|
||||
/* Avoid ugly blank lines: only print newline when we have to. */
|
||||
if (*cpu_vendor || cpu_id)
|
||||
printf("\n");
|
||||
#endif
|
||||
/*
|
||||
* Now that we have told the user what they have,
|
||||
* let them know if that machine type isn't configured.
|
||||
*/
|
||||
switch (cpu_class) {
|
||||
case CPUCLASS_286: /* a 286 should not make it this far, anyway */
|
||||
#if !defined(I386_CPU) && !defined(I486_CPU) && !defined(I586_CPU) && !defined(I686_CPU)
|
||||
#error This kernel is not configured for one of the supported CPUs
|
||||
#endif
|
||||
#if !defined(I386_CPU)
|
||||
case CPUCLASS_386:
|
||||
#endif
|
||||
#if !defined(I486_CPU)
|
||||
case CPUCLASS_486:
|
||||
#endif
|
||||
#if !defined(I586_CPU)
|
||||
case CPUCLASS_586:
|
||||
#endif
|
||||
#if !defined(I686_CPU)
|
||||
case CPUCLASS_686:
|
||||
#endif
|
||||
panic("CPU class not configured");
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#ifdef PERFMON
|
||||
perfmon_init();
|
||||
#endif
|
||||
dev_attach(&kdc_cpu0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Send an interrupt to process.
|
||||
*
|
||||
@ -884,66 +690,6 @@ sigreturn(p, uap, retval)
|
||||
return(EJUSTRETURN);
|
||||
}
|
||||
|
||||
#ifdef PC98
|
||||
/*
|
||||
* disable screen saver
|
||||
*/
|
||||
extern int scrn_blanked;
|
||||
extern void (*current_saver)(int blank);
|
||||
|
||||
static void pc98_disable_screen_saver(void)
|
||||
{
|
||||
if (scrn_blanked)
|
||||
(*current_saver)(FALSE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* change ralay on video card
|
||||
*/
|
||||
static void pc98_change_relay(void)
|
||||
{
|
||||
/* mode register 2 */
|
||||
outb(0x6a, 0x07); /* enable to change FF */
|
||||
outb(0x6a, 0x8e);
|
||||
outb(0x6a, 0x06); /* disable to change FF */
|
||||
outb(0x7c, 0);
|
||||
outb(0x68, 0x0f); /* display */
|
||||
|
||||
/* PWLB */
|
||||
*(int *)panic_kwin_pte = (0xf0c00000 & PG_FRAME) | PG_V | PG_RW ;
|
||||
pmap_update();
|
||||
*(long *)panic_kwin = 0;
|
||||
/* PowerWindow(C-Bus) */
|
||||
outb(0x0dc | 0x600, 0); /* XXX */
|
||||
/* PCHKB & PCSKB4 */
|
||||
outb(0x6e68, 0);
|
||||
/* PCSKB */
|
||||
outb(0x6ee8, 0);
|
||||
/* NEC-S3, Cirrus (local bus) */
|
||||
outb(0xfaa, 3);
|
||||
outb(0xfab, 1);
|
||||
outb(0xfaa, 6);
|
||||
outb(0xfab, 0xff);
|
||||
outb(0xfaa, 7);
|
||||
outb(0xfab, 0);
|
||||
/* NEC-S3 (C-bus) */
|
||||
outb(0xfa2, 3);
|
||||
outb(0xfa3, 0);
|
||||
/* GA-NB */
|
||||
outb(0x40e1, 0xc2);
|
||||
/* WAB-S & WAP */
|
||||
outb(0x40e1, 0xfa);
|
||||
|
||||
/* stop G-GDC */
|
||||
outb(0xa2, 0x0c);
|
||||
/* XXX start T-GDC (which is true?)*/
|
||||
outb(0x62, 0x69);
|
||||
outb(0x62, 0x0d);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static int waittime = -1;
|
||||
struct pcb dumppcb;
|
||||
|
||||
@ -955,10 +701,6 @@ boot(howto)
|
||||
register struct buf *bp;
|
||||
int iter, nbusy;
|
||||
|
||||
#ifdef PC98
|
||||
pc98_change_relay();
|
||||
pc98_disable_screen_saver();
|
||||
#endif
|
||||
waittime = 0;
|
||||
printf("\nsyncing disks... ");
|
||||
|
||||
@ -1051,7 +793,7 @@ boot(howto)
|
||||
* exported (symorder) and used at least by savecore(8)
|
||||
*
|
||||
*/
|
||||
u_long dumpmag = 0x8fca0101UL;
|
||||
static u_long const dumpmag = 0x8fca0101UL;
|
||||
|
||||
static int dumpsize = 0; /* also for savecore */
|
||||
|
||||
@ -1406,6 +1148,13 @@ init386(first)
|
||||
*/
|
||||
cninit();
|
||||
|
||||
#ifdef PC98
|
||||
/*
|
||||
* Initialize DMAC
|
||||
*/
|
||||
init_pc98_dmac();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* make gdt memory segments, the code segment goes up to end of the
|
||||
* page with etext in it, the data segment goes to the end of
|
||||
@ -1507,56 +1256,7 @@ init386(first)
|
||||
|
||||
#ifdef PC98
|
||||
#ifdef EPSON_MEMWIN
|
||||
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 */
|
||||
}
|
||||
init_epson_memwin();
|
||||
#endif
|
||||
biosbasemem = 640; /* 640KB */
|
||||
biosextmem = (Maxmem * PAGE_SIZE - 0x100000)/1024; /* extent memory */
|
||||
@ -1623,7 +1323,8 @@ init386(first)
|
||||
|
||||
/*
|
||||
* Maxmem isn't the "maximum memory", it's one larger than the
|
||||
* highest page of of the physical address space. It
|
||||
* highest page of the physical address space. It should be
|
||||
* called something like "Maxphyspage".
|
||||
*/
|
||||
Maxmem = pagesinext + 0x100000/PAGE_SIZE;
|
||||
|
||||
@ -1654,76 +1355,9 @@ init386(first)
|
||||
}
|
||||
|
||||
#ifdef PC98
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef notyet
|
||||
init_cpu_accel_mem();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
for (target_page = avail_start; target_page < ptoa(Maxmem); target_page += PAGE_SIZE) {
|
||||
|
@ -32,7 +32,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)npx.c 7.2 (Berkeley) 5/12/91
|
||||
* $Id: npx.c,v 1.29 1996/01/06 23:10:52 peter Exp $
|
||||
* $Id: npx.c,v 1.1.1.1 1996/06/14 10:04:45 asami Exp $
|
||||
*/
|
||||
|
||||
#include "npx.h"
|
||||
@ -54,6 +54,7 @@
|
||||
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/pcb.h>
|
||||
#include <machine/md_var.h>
|
||||
#include <machine/trap.h>
|
||||
#include <machine/clock.h>
|
||||
#include <machine/specialreg.h>
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)isa.c 7.2 (Berkeley) 5/13/91
|
||||
* $Id: isa.c,v 1.70 1996/05/02 10:43:09 phk Exp $
|
||||
* $Id: pc98.c,v 1.1.1.1 1996/06/14 10:04:45 asami Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -50,7 +50,7 @@
|
||||
/*
|
||||
* modified for PC9801 by A.Kojima F.Ukai M.Ishii
|
||||
* Kyoto University Microcomputer Club (KMC)
|
||||
* $Id: pc98.c,v 1.3 1994/03/17 23:24:40 kakefuda Exp $
|
||||
* $Id: pc98.c,v 1.1.1.1 1996/06/14 10:04:45 asami Exp $
|
||||
*/
|
||||
|
||||
#include "opt_auto_eoi.h"
|
||||
@ -62,6 +62,7 @@
|
||||
#include <sys/buf.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <machine/md_var.h>
|
||||
#include <machine/segments.h>
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_param.h>
|
||||
@ -106,6 +107,11 @@ u_int intr_mask[ICU_LEN];
|
||||
u_int* intr_mptr[ICU_LEN];
|
||||
int intr_unit[ICU_LEN];
|
||||
|
||||
#ifdef DDB
|
||||
unsigned int ddb_inb __P((unsigned int addr));
|
||||
void ddb_outb __P((unsigned int addr, unsigned char dt));
|
||||
#endif
|
||||
|
||||
extern struct kern_devconf kdc_cpu0;
|
||||
|
||||
#ifdef PC98
|
||||
@ -778,8 +784,6 @@ void pc98_dmacascade(chan)
|
||||
* pc98_dmastart(): program 8237 DMA controller channel, avoid page alignment
|
||||
* problems by using a bounce buffer.
|
||||
*/
|
||||
int dma_init_flag = 0;
|
||||
|
||||
void pc98_dmastart(int flags, caddr_t addr, u_int nbytes, int chan)
|
||||
{
|
||||
vm_offset_t phys;
|
||||
@ -825,16 +829,6 @@ void pc98_dmastart(int flags, caddr_t addr, u_int nbytes, int chan)
|
||||
asm("wbinvd"); /* wbinvd (WB cache flush) */
|
||||
#endif
|
||||
|
||||
if (!dma_init_flag) {
|
||||
dma_init_flag = 1;
|
||||
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 */
|
||||
}
|
||||
|
||||
/* mask channel */
|
||||
mskport = IO_DMA + 0x14; /* 0x15 */
|
||||
outb(mskport, chan & 3 | 0x04);
|
||||
|
@ -25,7 +25,7 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: pcaudio.c,v 1.27 1996/03/28 14:28:47 scrappy Exp $
|
||||
* $Id: pcaudio.c,v 1.1.1.1 1996/06/14 10:04:45 asami Exp $
|
||||
*/
|
||||
|
||||
#include "pca.h"
|
||||
@ -183,6 +183,9 @@ pca_init()
|
||||
static int
|
||||
pca_start(void)
|
||||
{
|
||||
int x = splhigh();
|
||||
int rv = 0;
|
||||
|
||||
/* use the first buffer */
|
||||
pca_status.current = 0;
|
||||
pca_status.index = 0;
|
||||
@ -195,28 +198,31 @@ pca_start(void)
|
||||
#endif
|
||||
/* acquire the timers */
|
||||
#ifdef PC98
|
||||
if (acquire_timer1(TIMER_LSB|TIMER_ONESHOT)) {
|
||||
if (acquire_timer1(TIMER_LSB|TIMER_ONESHOT))
|
||||
#else
|
||||
if (acquire_timer2(TIMER_LSB|TIMER_ONESHOT)) {
|
||||
if (acquire_timer2(TIMER_LSB|TIMER_ONESHOT))
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
if (acquire_timer0(INTERRUPT_RATE, pcaintr)) {
|
||||
rv = -1;
|
||||
else if (acquire_timer0(INTERRUPT_RATE, pcaintr)) {
|
||||
#ifdef PC98
|
||||
release_timer1();
|
||||
#else
|
||||
release_timer2();
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
pca_status.timer_on = 1;
|
||||
return 0;
|
||||
rv = -1;
|
||||
} else
|
||||
pca_status.timer_on = 1;
|
||||
|
||||
splx(x);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
pca_stop(void)
|
||||
{
|
||||
int x = splhigh();
|
||||
|
||||
/* release the timers */
|
||||
release_timer0();
|
||||
#ifdef PC98
|
||||
@ -231,12 +237,15 @@ pca_stop(void)
|
||||
pca_status.current = 0;
|
||||
pca_status.buffer = pca_status.buf[pca_status.current];
|
||||
pca_status.timer_on = 0;
|
||||
splx(x);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
pca_pause()
|
||||
{
|
||||
int x = splhigh();
|
||||
|
||||
release_timer0();
|
||||
#ifdef PC98
|
||||
release_timer1();
|
||||
@ -244,12 +253,15 @@ pca_pause()
|
||||
release_timer2();
|
||||
#endif
|
||||
pca_status.timer_on = 0;
|
||||
splx(x);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
pca_continue()
|
||||
{
|
||||
int x = splhigh();
|
||||
|
||||
#ifdef PC98
|
||||
pca_status.oldval = inb(IO_PPI) & ~0x08;
|
||||
acquire_timer1(TIMER_LSB|TIMER_ONESHOT);
|
||||
@ -259,18 +271,24 @@ pca_continue()
|
||||
#endif
|
||||
acquire_timer0(INTERRUPT_RATE, pcaintr);
|
||||
pca_status.timer_on = 1;
|
||||
splx(x);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
pca_wait(void)
|
||||
{
|
||||
int error;
|
||||
int error, x;
|
||||
|
||||
if (!pca_status.timer_on)
|
||||
return 0;
|
||||
|
||||
while (pca_status.in_use[0] || pca_status.in_use[1]) {
|
||||
x = spltty();
|
||||
pca_sleep = 1;
|
||||
error = tsleep(&pca_sleep, PZERO|PCATCH, "pca_drain", 0);
|
||||
pca_sleep = 0;
|
||||
splx(x);
|
||||
if (error != 0 && error != ERESTART) {
|
||||
pca_stop();
|
||||
return error;
|
||||
@ -396,7 +414,7 @@ pcaclose(dev_t dev, int flags, int fmt, struct proc *p)
|
||||
static int
|
||||
pcawrite(dev_t dev, struct uio *uio, int flag)
|
||||
{
|
||||
int count, error, which;
|
||||
int count, error, which, x;
|
||||
|
||||
/* only audio device can be written */
|
||||
if (minor(dev) > 0)
|
||||
@ -404,9 +422,11 @@ pcawrite(dev_t dev, struct uio *uio, int flag)
|
||||
|
||||
while ((count = min(BUF_SIZE, uio->uio_resid)) > 0) {
|
||||
if (pca_status.in_use[0] && pca_status.in_use[1]) {
|
||||
x = spltty();
|
||||
pca_sleep = 1;
|
||||
error = tsleep(&pca_sleep, PZERO|PCATCH, "pca_wait", 0);
|
||||
pca_sleep = 0;
|
||||
splx(x);
|
||||
if (error != 0 && error != ERESTART) {
|
||||
pca_stop();
|
||||
return error;
|
||||
@ -488,9 +508,11 @@ pcaioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
|
||||
return 0;
|
||||
|
||||
case AUDIO_DRAIN:
|
||||
case AUDIO_COMPAT_DRAIN:
|
||||
return pca_wait();
|
||||
|
||||
case AUDIO_FLUSH:
|
||||
case AUDIO_COMPAT_FLUSH:
|
||||
pca_stop();
|
||||
return 0;
|
||||
|
||||
@ -531,10 +553,8 @@ pcaintr(struct clockframe *frame)
|
||||
pca_status.in_use[pca_status.current] = 0;
|
||||
pca_status.current ^= 1;
|
||||
pca_status.buffer = pca_status.buf[pca_status.current];
|
||||
if (pca_sleep) {
|
||||
if (pca_sleep)
|
||||
wakeup(&pca_sleep);
|
||||
pca_sleep = 0;
|
||||
}
|
||||
if (pca_status.wsel.si_pid) {
|
||||
selwakeup((struct selinfo *)&pca_status.wsel.si_pid);
|
||||
pca_status.wsel.si_pid = 0;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** $Id: pcibus.c,v 1.24 1996/04/30 21:37:21 se Exp $
|
||||
** $Id: pcibus.c,v 1.1.1.1 1996/06/14 10:04:45 asami Exp $
|
||||
**
|
||||
** pci bus subroutines for i386 architecture.
|
||||
**
|
||||
@ -43,11 +43,9 @@
|
||||
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/icu.h>
|
||||
#include <pc98/pc98/pc98.h>
|
||||
#include <pc98/pc98/pc98_device.h>
|
||||
#else
|
||||
#include <i386/isa/icu.h>
|
||||
#include <i386/isa/isa.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#endif
|
||||
|
||||
@ -152,7 +150,7 @@ DATA_SET (pcibus_set, i386pci);
|
||||
|
||||
#define CONF1_ENABLE 0x80000000ul
|
||||
#define CONF1_ENABLE_CHK 0x80000000ul
|
||||
#define CONF1_ENABLE_MSK 0x00ff0700ul
|
||||
#define CONF1_ENABLE_MSK 0x7ff00000ul
|
||||
#define CONF1_ENABLE_CHK1 0xff000001ul
|
||||
#define CONF1_ENABLE_MSK1 0x80000001ul
|
||||
#define CONF1_ENABLE_RES1 0x80000000ul
|
||||
|
@ -43,14 +43,10 @@
|
||||
#include <machine/clock.h>
|
||||
#endif
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/pc98.h>
|
||||
#include <pc98/pc98/pc98_device.h>
|
||||
#include <pc98/pc98/icu.h>
|
||||
#include <pc98/pc98/pcic.h>
|
||||
#else
|
||||
#include <i386/isa/isa.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/icu.h>
|
||||
#include <i386/isa/pcic.h>
|
||||
#endif
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* random_machdep.c -- A strong random number generator
|
||||
*
|
||||
* $Id: random_machdep.c,v 1.7 1996/06/08 08:18:00 bde Exp $
|
||||
* $Id: random_machdep.c,v 1.1.1.1 1996/06/14 10:04:45 asami Exp $
|
||||
*
|
||||
* Version 0.95, last modified 18-Oct-95
|
||||
*
|
||||
@ -53,10 +53,12 @@
|
||||
#include <machine/random.h>
|
||||
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/icu.h>
|
||||
#include <pc98/pc98/pc98.h>
|
||||
#include <pc98/pc98/pc98_device.h>
|
||||
#include <pc98/pc98/timerreg.h>
|
||||
#else
|
||||
#include <i386/isa/icu.h>
|
||||
#include <i386/isa/isa.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/timerreg.h>
|
||||
@ -108,7 +110,9 @@ static u_int32_t random_pool[POOLWORDS];
|
||||
static struct timer_rand_state keyboard_timer_state;
|
||||
static struct timer_rand_state extract_timer_state;
|
||||
static struct timer_rand_state irq_timer_state[ICU_LEN];
|
||||
#ifdef notyet
|
||||
static struct timer_rand_state blkdev_timer_state[MAX_BLKDEV];
|
||||
#endif
|
||||
static struct wait_queue *random_wait;
|
||||
|
||||
inthand2_t *sec_intr_handler[ICU_LEN];
|
||||
|
@ -96,7 +96,6 @@
|
||||
#define MAXSIMUL 8
|
||||
#define SBIC_RESET_TIMEOUT 2000 /* time to wait for reset */
|
||||
|
||||
extern int dma_init_flag;
|
||||
extern short dmapageport[];
|
||||
|
||||
|
||||
@ -904,15 +903,6 @@ sbic_dmastart(int flags, int phys, unsigned nbytes, unsigned chan)
|
||||
#ifdef CYRIX_5X86
|
||||
asm("wbinvd"); /* wbinvd (WB cache flush) */
|
||||
#endif
|
||||
if (!dma_init_flag) {
|
||||
dma_init_flag = 1;
|
||||
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 */
|
||||
}
|
||||
|
||||
/* mask channel */
|
||||
mskport = IO_DMA + 0x14; /* 0x15 */
|
||||
|
@ -80,7 +80,6 @@
|
||||
#include <pc98/pc98/sbicreg.h>
|
||||
#include <pc98/pc98/sbicvar.h>
|
||||
|
||||
extern int dma_init_flag;
|
||||
extern short dmapageport[];
|
||||
|
||||
/*
|
||||
@ -1721,16 +1720,6 @@ sbic_dmastart(sbic)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!dma_init_flag) {
|
||||
dma_init_flag = 1;
|
||||
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 */
|
||||
}
|
||||
|
||||
/* mask channel */
|
||||
outb(DMA_SMSK, sbic->sc_dma | DMA37SM_SET);
|
||||
|
||||
|
@ -41,7 +41,7 @@
|
||||
*/
|
||||
|
||||
|
||||
/* $Id: scd.c,v 1.21 1996/06/08 09:18:23 bde Exp $ */
|
||||
/* $Id: scd.c,v 1.1.1.1 1996/06/14 10:04:45 asami Exp $ */
|
||||
|
||||
/* Please send any comments to micke@dynas.se */
|
||||
|
||||
@ -73,10 +73,8 @@
|
||||
#include <machine/stdarg.h>
|
||||
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/pc98.h>
|
||||
#include <pc98/pc98/pc98_device.h>
|
||||
#else
|
||||
#include <i386/isa/isa.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#endif
|
||||
#include <i386/isa/scdreg.h>
|
||||
@ -1193,7 +1191,7 @@ spin_up(unsigned unit)
|
||||
int loop_count = 0;
|
||||
|
||||
again:
|
||||
rc = send_cmd(unit, CMD_SPIN_UP, NULL, 0, res_reg, &res_size);
|
||||
rc = send_cmd(unit, CMD_SPIN_UP, 0, 0, res_reg, &res_size);
|
||||
if (rc != 0) {
|
||||
XDEBUG(2, ("scd%d: CMD_SPIN_UP error 0x%x\n", unit, rc));
|
||||
return rc;
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)com.c 7.5 (Berkeley) 5/16/91
|
||||
* $Id: sio.c,v 1.142 1996/05/02 09:34:40 phk Exp $
|
||||
* $Id: sio.c,v 1.1.1.1 1996/06/14 10:04:45 asami Exp $
|
||||
*/
|
||||
|
||||
#include "opt_comconsole.h"
|
||||
@ -138,14 +138,13 @@
|
||||
#include <machine/clock.h>
|
||||
|
||||
#ifdef PC98
|
||||
#include <pc98/pc98/icu.h> /* XXX just to get at `imen' */
|
||||
#include <pc98/pc98/pc98.h>
|
||||
#include <pc98/pc98/icu.h>
|
||||
#include <pc98/pc98/pc98_device.h>
|
||||
#include <pc98/pc98/sioreg.h>
|
||||
#include <pc98/pc98/ic/i8251.h>
|
||||
#include <pc98/pc98/ic/ns16550.h>
|
||||
#else
|
||||
#include <i386/isa/icu.h> /* XXX just to get at `imen' */
|
||||
#include <i386/isa/isa.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/sioreg.h>
|
||||
@ -330,7 +329,9 @@ struct com_s {
|
||||
struct termios lt_out;
|
||||
|
||||
bool_t do_timestamp;
|
||||
bool_t do_dcd_timestamp;
|
||||
struct timeval timestamp;
|
||||
struct timeval dcd_timestamp;
|
||||
|
||||
u_long bytes_in; /* statistics */
|
||||
u_long bytes_out;
|
||||
@ -366,8 +367,7 @@ struct com_s {
|
||||
* by `config', not here.
|
||||
*/
|
||||
|
||||
/* Interrupt handling entry points. */
|
||||
inthand2_t siointrts;
|
||||
/* Interrupt handling entry point. */
|
||||
void siopoll __P((void));
|
||||
|
||||
/* Device switch entry points. */
|
||||
@ -417,8 +417,6 @@ static char driver_name[] = "sio";
|
||||
static struct com_s *p_com_addr[NSIO];
|
||||
#define com_addr(unit) (p_com_addr[unit])
|
||||
|
||||
static struct timeval intr_timestamp;
|
||||
|
||||
#ifdef PC98
|
||||
struct pc98_driver siodriver = {
|
||||
#else
|
||||
@ -957,18 +955,6 @@ sioprobe(dev)
|
||||
disable_intr();
|
||||
/* EXTRA DELAY? */
|
||||
|
||||
/*
|
||||
* XXX DELAY() reenables CPU interrupts. This is a problem for
|
||||
* shared interrupts after the first device using one has been
|
||||
* successfully probed - config_isadev() has enabled the interrupt
|
||||
* in the ICU.
|
||||
*/
|
||||
#ifdef PC98
|
||||
outb(IO_ICU1 + 2, 0xff);
|
||||
#else
|
||||
outb(IO_ICU1 + 1, 0xff);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Initialize the speed and the word size and wait long enough to
|
||||
* drain the maximum of 16 bytes of junk in device output queues.
|
||||
@ -1042,7 +1028,7 @@ sioprobe(dev)
|
||||
failures[0] = inb(iobase + com_cfcr) - CFCR_8BITS;
|
||||
failures[1] = inb(iobase + com_ier) - IER_ETXRDY;
|
||||
failures[2] = inb(iobase + com_mcr) - mcr_image;
|
||||
DELAY(1000); /* XXX */
|
||||
DELAY(10000); /* Some internal modems need this time */
|
||||
if (idev->id_irq != 0)
|
||||
#ifdef PC98
|
||||
failures[3] = pc98_irq_pending(idev) ? 0 : 1;
|
||||
@ -1082,11 +1068,6 @@ sioprobe(dev)
|
||||
#endif
|
||||
failures[9] = (inb(iobase + com_iir) & IIR_IMASK) - IIR_NOPEND;
|
||||
|
||||
#ifdef PC98
|
||||
outb(IO_ICU1 + 2, imen); /* XXX */
|
||||
#else
|
||||
outb(IO_ICU1 + 1, imen); /* XXX */
|
||||
#endif
|
||||
enable_intr();
|
||||
|
||||
result = IO_COMSIZE;
|
||||
@ -1868,32 +1849,6 @@ siodtrwakeup(chan)
|
||||
wakeup(&com->dtr_wait);
|
||||
}
|
||||
|
||||
/* Interrupt routine for timekeeping purposes */
|
||||
void
|
||||
siointrts(unit)
|
||||
int unit;
|
||||
{
|
||||
/*
|
||||
* XXX microtime() reenables CPU interrupts. We can't afford to
|
||||
* be interrupted and don't want to slow down microtime(), so lock
|
||||
* out interrupts in another way.
|
||||
*/
|
||||
#ifdef PC98
|
||||
outb(IO_ICU1 + 2, 0xff);
|
||||
#else /* IBM-PC */
|
||||
outb(IO_ICU1 + 1, 0xff);
|
||||
#endif /* PC98 */
|
||||
microtime(&intr_timestamp);
|
||||
disable_intr();
|
||||
#ifdef PC98
|
||||
outb(IO_ICU1 + 2, imen);
|
||||
#else /* IBM_PC */
|
||||
outb(IO_ICU1 + 1, imen);
|
||||
#endif /* PC98 */
|
||||
|
||||
siointr(unit);
|
||||
}
|
||||
|
||||
void
|
||||
siointr(unit)
|
||||
int unit;
|
||||
@ -1947,9 +1902,6 @@ siointr1(com)
|
||||
recv_data=0;
|
||||
#endif /* PC98 */
|
||||
|
||||
if (com->do_timestamp)
|
||||
/* XXX a little bloat here... */
|
||||
com->timestamp = intr_timestamp;
|
||||
while (TRUE) {
|
||||
#ifdef PC98
|
||||
status_read:;
|
||||
@ -2024,6 +1976,8 @@ status_read:;
|
||||
if (ioptr >= com->ibufend)
|
||||
CE_RECORD(com, CE_INTERRUPT_BUF_OVERFLOW);
|
||||
else {
|
||||
if (com->do_timestamp)
|
||||
microtime(&com->timestamp);
|
||||
++com_events;
|
||||
schedsofttty();
|
||||
#if 0 /* for testing input latency vs efficiency */
|
||||
@ -2064,6 +2018,11 @@ if (com->iptr - com->ibuf == 8)
|
||||
#endif
|
||||
modem_status = inb(com->modem_status_port);
|
||||
if (modem_status != com->last_modem_status) {
|
||||
if (com->do_dcd_timestamp
|
||||
&& !(com->last_modem_status & MSR_DCD)
|
||||
&& modem_status & MSR_DCD)
|
||||
microtime(&com->dcd_timestamp);
|
||||
|
||||
/*
|
||||
* Schedule high level to handle DCD changes. Note
|
||||
* that we don't use the delta bits anywhere. Some
|
||||
@ -2115,11 +2074,7 @@ if (com->iptr - com->ibuf == 8)
|
||||
com->obufq.l_head = ioptr;
|
||||
if (ioptr >= com->obufq.l_tail) {
|
||||
struct lbq *qp;
|
||||
#ifdef PC98
|
||||
if(IS_8251(com->pc98_if_type))
|
||||
if ( pc98_check_i8251_interrupt(com) & IEN_TxFLAG )
|
||||
com_int_Tx_disable(com);
|
||||
#endif
|
||||
|
||||
qp = com->obufq.l_next;
|
||||
qp->l_queued = FALSE;
|
||||
qp = qp->l_next;
|
||||
@ -2130,6 +2085,11 @@ if (com->iptr - com->ibuf == 8)
|
||||
} else {
|
||||
/* output just completed */
|
||||
com->state &= ~CS_BUSY;
|
||||
#if defined(PC98)
|
||||
if(IS_8251(com->pc98_if_type))
|
||||
if ( pc98_check_i8251_interrupt(com) & IEN_TxFLAG )
|
||||
com_int_Tx_disable(com);
|
||||
#endif
|
||||
}
|
||||
if (!(com->state & CS_ODONE)) {
|
||||
com_events += LOTS_OF_EVENTS;
|
||||
@ -2331,6 +2291,10 @@ sioioctl(dev, cmd, data, flag, p)
|
||||
com->do_timestamp = TRUE;
|
||||
*(struct timeval *)data = com->timestamp;
|
||||
break;
|
||||
case TIOCDCDTIMESTAMP:
|
||||
com->do_dcd_timestamp = TRUE;
|
||||
*(struct timeval *)data = com->dcd_timestamp;
|
||||
break;
|
||||
default:
|
||||
splx(s);
|
||||
return (ENOTTY);
|
||||
@ -3199,9 +3163,6 @@ static void
|
||||
siocntxwait()
|
||||
{
|
||||
int timo;
|
||||
#ifdef PC98
|
||||
int tmp;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Wait for any pending transmission to finish. Required to avoid
|
||||
@ -3551,8 +3512,6 @@ pc98_get_modem_status(struct com_s *com)
|
||||
int stat, stat2;
|
||||
register int msr;
|
||||
|
||||
int ret;
|
||||
|
||||
stat = inb(com->sts_port);
|
||||
stat2 = inb(com->in_modem_port);
|
||||
msr = com->pc98_prev_modem_status
|
||||
@ -3763,7 +3722,7 @@ static void
|
||||
com_cflag_and_speed_set( struct com_s *com, int cflag, int speed)
|
||||
{
|
||||
int cfcr=0, count;
|
||||
int s, previnterrupt;
|
||||
int previnterrupt;
|
||||
|
||||
count = pc98_ttspeedtab( com, speed );
|
||||
if ( count < 0 ) return;
|
||||
|
@ -678,8 +678,9 @@ DMAbuf_start_dma (int dev, unsigned long physaddr, int count, int dma_mode)
|
||||
{
|
||||
int chan = audio_devs[dev]->dmachan;
|
||||
struct dma_buffparms *dmap = audio_devs[dev]->dmap;
|
||||
#ifdef linux
|
||||
unsigned long flags;
|
||||
|
||||
#endif
|
||||
/*
|
||||
* This function is not as portable as it should be.
|
||||
*/
|
||||
|
@ -4,12 +4,12 @@
|
||||
* v1.4 by Eric S. Raymond (esr@snark.thyrsus.com) Aug 1993
|
||||
* modified for FreeBSD by Andrew A. Chernov <ache@astral.msk.su>
|
||||
*
|
||||
* $Id: spkr.c,v 1.24 1996/03/27 19:07:33 bde Exp $
|
||||
* $Id: spkr.c,v 1.1.1.1 1996/06/14 10:04:46 asami Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* modified for PC98
|
||||
* $Id: spkr.c,v 1.2 1994/03/14 09:53:38 kakefuda Exp $
|
||||
* $Id: spkr.c,v 1.1.1.1 1996/06/14 10:04:46 asami Exp $
|
||||
*/
|
||||
|
||||
#include "speaker.h"
|
||||
@ -115,9 +115,10 @@ static void playtone __P((int pitch, int value, int sustain));
|
||||
static int abs __P((int n));
|
||||
static void playstring __P((char *cp, size_t slen));
|
||||
|
||||
static void tone(thz, ticks)
|
||||
/* emit tone of frequency thz for given number of ticks */
|
||||
unsigned int thz, ticks;
|
||||
static void
|
||||
tone(thz, ticks)
|
||||
unsigned int thz, ticks;
|
||||
{
|
||||
unsigned int divisor;
|
||||
int sps;
|
||||
@ -139,7 +140,7 @@ unsigned int thz, ticks;
|
||||
#endif /* DEBUG */
|
||||
|
||||
/* set timer to generate clicks at given frequency in Hertz */
|
||||
sps = spltty();
|
||||
sps = splclock();
|
||||
|
||||
#ifdef PC98
|
||||
if (acquire_timer1(PIT_MODE)) {
|
||||
@ -147,8 +148,11 @@ unsigned int thz, ticks;
|
||||
if (acquire_timer2(PIT_MODE)) {
|
||||
#endif
|
||||
/* enter list of waiting procs ??? */
|
||||
splx(sps);
|
||||
return;
|
||||
}
|
||||
splx(sps);
|
||||
disable_intr();
|
||||
#ifdef PC98
|
||||
outb(PIT_COUNT, (divisor & 0xff)); /* send lo byte */
|
||||
outb(PIT_COUNT, (divisor >> 8)); /* send hi byte */
|
||||
@ -156,7 +160,7 @@ unsigned int thz, ticks;
|
||||
outb(TIMER_CNTR2, (divisor & 0xff)); /* send lo byte */
|
||||
outb(TIMER_CNTR2, (divisor >> 8)); /* send hi byte */
|
||||
#endif
|
||||
splx(sps);
|
||||
enable_intr();
|
||||
|
||||
/* turn the speaker on */
|
||||
#ifdef PC98
|
||||
@ -174,16 +178,21 @@ unsigned int thz, ticks;
|
||||
tsleep((caddr_t)&endtone, SPKRPRI | PCATCH, "spkrtn", ticks);
|
||||
#ifdef PC98
|
||||
outb(IO_PPI, inb(IO_PPI) | PPI_SPKR);
|
||||
sps = splclock();
|
||||
release_timer1();
|
||||
splx(sps);
|
||||
#else
|
||||
outb(IO_PPI, inb(IO_PPI) & ~PPI_SPKR);
|
||||
sps = splclock();
|
||||
release_timer2();
|
||||
splx(sps);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void rest(ticks)
|
||||
/* rest for given number of ticks */
|
||||
int ticks;
|
||||
static void
|
||||
rest(ticks)
|
||||
int ticks;
|
||||
{
|
||||
/*
|
||||
* Set timeout to endrest function, then give up the timeslice.
|
||||
@ -260,7 +269,8 @@ static int pitchtab[] =
|
||||
/* 6 */ 4186, 4435, 4698, 4978, 5274, 5588, 5920, 6272, 6644, 7040, 7459, 7902,
|
||||
};
|
||||
|
||||
static void playinit()
|
||||
static void
|
||||
playinit()
|
||||
{
|
||||
octave = DFLT_OCTAVE;
|
||||
whole = (hz * SECS_PER_MIN * WHOLE_NOTE) / DFLT_TEMPO;
|
||||
@ -270,9 +280,10 @@ static void playinit()
|
||||
octprefix = TRUE; /* act as though there was an initial O(n) */
|
||||
}
|
||||
|
||||
static void playtone(pitch, value, sustain)
|
||||
/* play tone of proper duration for current rhythm signature */
|
||||
int pitch, value, sustain;
|
||||
static void
|
||||
playtone(pitch, value, sustain)
|
||||
int pitch, value, sustain;
|
||||
{
|
||||
register int sound, silence, snum = 1, sdenom = 1;
|
||||
|
||||
@ -306,8 +317,9 @@ int pitch, value, sustain;
|
||||
}
|
||||
}
|
||||
|
||||
static int abs(n)
|
||||
int n;
|
||||
static int
|
||||
abs(n)
|
||||
int n;
|
||||
{
|
||||
if (n < 0)
|
||||
return(-n);
|
||||
@ -315,10 +327,11 @@ int n;
|
||||
return(n);
|
||||
}
|
||||
|
||||
static void playstring(cp, slen)
|
||||
/* interpret and play an item from a notation string */
|
||||
char *cp;
|
||||
size_t slen;
|
||||
static void
|
||||
playstring(cp, slen)
|
||||
char *cp;
|
||||
size_t slen;
|
||||
{
|
||||
int pitch, oldfill, lastpitch = OCTAVE_NOTES * DFLT_OCTAVE;
|
||||
|
||||
@ -515,11 +528,12 @@ size_t slen;
|
||||
static int spkr_active = FALSE; /* exclusion flag */
|
||||
static struct buf *spkr_inbuf; /* incoming buf */
|
||||
|
||||
int spkropen(dev, flags, fmt, p)
|
||||
dev_t dev;
|
||||
int flags;
|
||||
int fmt;
|
||||
struct proc *p;
|
||||
int
|
||||
spkropen(dev, flags, fmt, p)
|
||||
dev_t dev;
|
||||
int flags;
|
||||
int fmt;
|
||||
struct proc *p;
|
||||
{
|
||||
#ifdef DEBUG
|
||||
(void) printf("spkropen: entering with dev = %x\n", dev);
|
||||
@ -541,10 +555,11 @@ struct proc *p;
|
||||
}
|
||||
}
|
||||
|
||||
int spkrwrite(dev, uio, ioflag)
|
||||
dev_t dev;
|
||||
struct uio *uio;
|
||||
int ioflag;
|
||||
int
|
||||
spkrwrite(dev, uio, ioflag)
|
||||
dev_t dev;
|
||||
struct uio *uio;
|
||||
int ioflag;
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("spkrwrite: entering with dev = %x, count = %d\n",
|
||||
@ -569,11 +584,12 @@ int ioflag;
|
||||
}
|
||||
}
|
||||
|
||||
int spkrclose(dev, flags, fmt, p)
|
||||
dev_t dev;
|
||||
int flags;
|
||||
int fmt;
|
||||
struct proc *p;
|
||||
int
|
||||
spkrclose(dev, flags, fmt, p)
|
||||
dev_t dev;
|
||||
int flags;
|
||||
int fmt;
|
||||
struct proc *p;
|
||||
{
|
||||
#ifdef DEBUG
|
||||
(void) printf("spkrclose: entering with dev = %x\n", dev);
|
||||
@ -591,12 +607,13 @@ struct proc *p;
|
||||
}
|
||||
}
|
||||
|
||||
int spkrioctl(dev, cmd, cmdarg, flags, p)
|
||||
dev_t dev;
|
||||
int cmd;
|
||||
caddr_t cmdarg;
|
||||
int flags;
|
||||
struct proc *p;
|
||||
int
|
||||
spkrioctl(dev, cmd, cmdarg, flags, p)
|
||||
dev_t dev;
|
||||
int cmd;
|
||||
caddr_t cmdarg;
|
||||
int flags;
|
||||
struct proc *p;
|
||||
{
|
||||
#ifdef DEBUG
|
||||
(void) printf("spkrioctl: entering with dev = %x, cmd = %x\n");
|
||||
@ -639,7 +656,8 @@ struct proc *p;
|
||||
|
||||
static spkr_devsw_installed = 0;
|
||||
|
||||
static void spkr_drvinit(void *unused)
|
||||
static void
|
||||
spkr_drvinit(void *unused)
|
||||
{
|
||||
dev_t dev;
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: syscons.c,v 1.150 1996/05/27 06:02:52 peter Exp $
|
||||
* $Id: syscons.c,v 1.1.1.1 1996/06/14 10:04:47 asami Exp $
|
||||
*/
|
||||
|
||||
#include "sc.h"
|
||||
@ -54,6 +54,7 @@
|
||||
#include <machine/clock.h>
|
||||
#include <machine/cons.h>
|
||||
#include <machine/console.h>
|
||||
#include <machine/md_var.h>
|
||||
#include <machine/psl.h>
|
||||
#include <machine/frame.h>
|
||||
#include <machine/pc/display.h>
|
||||
@ -110,7 +111,9 @@ static default_attr kernel_default = {
|
||||
|
||||
static scr_stat main_console;
|
||||
static scr_stat *console[MAXCONS];
|
||||
#ifdef DEVFS
|
||||
static void *sc_devfs_token[MAXCONS];
|
||||
#endif
|
||||
scr_stat *cur_console;
|
||||
static scr_stat *new_scp, *old_scp;
|
||||
static term_stat kernel_console;
|
||||
@ -142,10 +145,7 @@ static long scrn_time_stamp;
|
||||
#ifndef PC98
|
||||
static char *video_mode_ptr = NULL;
|
||||
#endif
|
||||
#if ASYNCH
|
||||
static u_char kbd_reply = 0;
|
||||
#endif
|
||||
|
||||
static char *cut_buffer;
|
||||
static u_short mouse_and_mask[16] = {
|
||||
0xc000, 0xe000, 0xf000, 0xf800, 0xfc00, 0xfe00, 0xff00, 0xff80,
|
||||
0xfe00, 0x1e00, 0x1f00, 0x0f00, 0x0f00, 0x0000, 0x0000, 0x0000
|
||||
@ -159,19 +159,6 @@ static void none_saver(int blank) { }
|
||||
|
||||
void (*current_saver) __P((int blank)) = none_saver;
|
||||
|
||||
#ifdef PC98
|
||||
static int scattach(struct pc98_device *dev);
|
||||
#else
|
||||
static int scattach(struct isa_device *dev);
|
||||
#endif
|
||||
static int scparam(struct tty *tp, struct termios *t);
|
||||
#ifdef PC98
|
||||
static int scprobe(struct pc98_device *dev);
|
||||
#else
|
||||
static int scprobe(struct isa_device *dev);
|
||||
#endif
|
||||
static void scstart(struct tty *tp);
|
||||
|
||||
/* OS specific stuff */
|
||||
#ifdef not_yet_done
|
||||
#define VIRTUAL_TTY(x) (sccons[x] = ttymalloc(sccons[x]))
|
||||
@ -202,6 +189,56 @@ u_short *Crtat;
|
||||
+ (offset)) % (scp->history_size)))
|
||||
#endif
|
||||
|
||||
/* prototypes */
|
||||
#ifdef PC98
|
||||
static int scattach(struct pc98_device *dev);
|
||||
#else
|
||||
static int scattach(struct isa_device *dev);
|
||||
#endif
|
||||
static int scparam(struct tty *tp, struct termios *t);
|
||||
#ifdef PC98
|
||||
static int scprobe(struct pc98_device *dev);
|
||||
#else
|
||||
static int scprobe(struct isa_device *dev);
|
||||
#endif
|
||||
static void scstart(struct tty *tp);
|
||||
static void scinit(void);
|
||||
static u_int scgetc(int noblock);
|
||||
static scr_stat *get_scr_stat(dev_t dev);
|
||||
static scr_stat *alloc_scp(void);
|
||||
static void init_scp(scr_stat *scp);
|
||||
static int get_scr_num(void);
|
||||
static void scrn_timer(void);
|
||||
static void clear_screen(scr_stat *scp);
|
||||
static int switch_scr(scr_stat *scp, u_int next_scr);
|
||||
static void exchange_scr(void);
|
||||
static inline void move_crsr(scr_stat *scp, int x, int y);
|
||||
static void scan_esc(scr_stat *scp, u_char c);
|
||||
static inline void draw_cursor(scr_stat *scp, int show);
|
||||
static void ansi_put(scr_stat *scp, u_char *buf, int len);
|
||||
static u_char *get_fstr(u_int c, u_int *len);
|
||||
static void update_leds(int which);
|
||||
static void history_to_screen(scr_stat *scp);
|
||||
static int history_up_line(scr_stat *scp);
|
||||
static int history_down_line(scr_stat *scp);
|
||||
static void kbd_wait(void);
|
||||
static void kbd_cmd(u_char command);
|
||||
static void set_mode(scr_stat *scp);
|
||||
static void set_vgaregs(char *modetable);
|
||||
static void set_font_mode(void);
|
||||
static void set_normal_mode(void);
|
||||
static void copy_font(int operation, int font_type, char* font_image);
|
||||
static void set_destructive_cursor(scr_stat *scp, int force);
|
||||
static void set_mouse_pos(scr_stat *scp);
|
||||
static void reverse_mouse_cut(scr_stat *scp, int cut);
|
||||
static void mouse_cut_start(scr_stat *scp);
|
||||
static void mouse_cut_end(scr_stat *scp);
|
||||
static void mouse_paste(scr_stat *scp);
|
||||
static void draw_mouse_image(scr_stat *scp);
|
||||
static void save_palette(void);
|
||||
static void do_bell(scr_stat *scp, int pitch, int duration);
|
||||
static void blink_screen(scr_stat *scp);
|
||||
|
||||
#ifdef PC98
|
||||
struct pc98_driver scdriver = {
|
||||
#else
|
||||
@ -346,8 +383,14 @@ draw_cursor(scr_stat *scp, int show)
|
||||
static inline void
|
||||
move_crsr(scr_stat *scp, int x, int y)
|
||||
{
|
||||
if (x < 0 || y < 0 || x >= scp->xsize || y >= scp->ysize)
|
||||
return;
|
||||
if (x < 0)
|
||||
x = 0;
|
||||
if (y < 0)
|
||||
y = 0;
|
||||
if (x >= scp->xsize)
|
||||
x = scp->xsize-1;
|
||||
if (y >= scp->ysize)
|
||||
y = scp->ysize-1;
|
||||
scp->xpos = x;
|
||||
scp->ypos = y;
|
||||
mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
|
||||
@ -371,12 +414,12 @@ scprobe(struct pc98_device *dev)
|
||||
scprobe(struct isa_device *dev)
|
||||
#endif
|
||||
{
|
||||
int i, j, retries = 5;
|
||||
unsigned char val;
|
||||
|
||||
#ifdef PC98
|
||||
return(16);
|
||||
#else
|
||||
int i, j, retries = 5;
|
||||
unsigned char val;
|
||||
|
||||
/* Enable interrupts and keyboard controller */
|
||||
kbd_wait();
|
||||
outb(KB_STAT, KB_WRITE);
|
||||
@ -385,7 +428,7 @@ scprobe(struct isa_device *dev)
|
||||
|
||||
/* flush any noise in the buffer */
|
||||
while (inb(KB_STAT) & KB_BUF_FULL) {
|
||||
DELAY(10);
|
||||
DELAY(100);
|
||||
(void) inb(KB_DATA);
|
||||
}
|
||||
|
||||
@ -393,8 +436,8 @@ scprobe(struct isa_device *dev)
|
||||
while (retries--) {
|
||||
kbd_wait();
|
||||
outb(KB_DATA, KB_RESET);
|
||||
for (i=0; i<100000; i++) {
|
||||
DELAY(10);
|
||||
for (i=0; i<10000; i++) {
|
||||
DELAY(100);
|
||||
val = inb(KB_DATA);
|
||||
if (val == KB_ACK || val == KB_ECHO)
|
||||
goto gotres;
|
||||
@ -408,10 +451,10 @@ scprobe(struct isa_device *dev)
|
||||
else {
|
||||
i = 10; /* At most 10 retries. */
|
||||
gotack:
|
||||
DELAY(10);
|
||||
j = 1000; /* Wait at most 10 ms (supposedly). */
|
||||
while ((inb(KB_STAT) & KB_BUF_FULL) == 0 && --j > 0) DELAY(10);
|
||||
DELAY(10);
|
||||
DELAY(100);
|
||||
j = 1000; /* Wait at most 1 s. */
|
||||
while ((inb(KB_STAT) & KB_BUF_FULL) == 0 && --j > 0) DELAY(1000);
|
||||
DELAY(1000);
|
||||
val = inb(KB_DATA);
|
||||
if (val == KB_ACK && --i > 0)
|
||||
goto gotack;
|
||||
@ -496,12 +539,13 @@ scattach(struct isa_device *dev)
|
||||
|
||||
#ifndef PC98
|
||||
if (crtc_vga) {
|
||||
cut_buffer = (char *)malloc(scp->xsize*scp->ysize, M_DEVBUF, M_NOWAIT);
|
||||
font_8 = (char *)malloc(8*256, M_DEVBUF, M_NOWAIT);
|
||||
font_14 = (char *)malloc(14*256, M_DEVBUF, M_NOWAIT);
|
||||
font_16 = (char *)malloc(16*256, M_DEVBUF, M_NOWAIT);
|
||||
copy_font(SAVE, FONT_16, font_16);
|
||||
fonts_loaded = FONT_16;
|
||||
scp->font = FONT_16;
|
||||
scp->font_size = FONT_16;
|
||||
save_palette();
|
||||
}
|
||||
#endif
|
||||
@ -873,22 +917,26 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
|
||||
case CONS_MOUSECTL: /* control mouse arrow */
|
||||
{
|
||||
mouse_info_t *mouse = (mouse_info_t*)data;
|
||||
int fontsize;
|
||||
|
||||
switch (scp->font) {
|
||||
default:
|
||||
case FONT_8:
|
||||
fontsize = 8; break;
|
||||
case FONT_14:
|
||||
fontsize = 14; break;
|
||||
case FONT_16:
|
||||
fontsize = 16; break;
|
||||
}
|
||||
|
||||
switch (mouse->operation) {
|
||||
case MOUSE_MODE:
|
||||
if (mouse->u.mode.signal > 0 && mouse->u.mode.signal < NSIG) {
|
||||
scp->mouse_signal = mouse->u.mode.signal;
|
||||
scp->mouse_proc = p;
|
||||
scp->mouse_pid = p->p_pid;
|
||||
}
|
||||
else {
|
||||
scp->mouse_signal = 0;
|
||||
scp->mouse_proc = NULL;
|
||||
scp->mouse_pid = 0;
|
||||
}
|
||||
return 0;
|
||||
|
||||
case MOUSE_SHOW:
|
||||
if (!(scp->status & MOUSE_ENABLED)) {
|
||||
scp->status |= MOUSE_ENABLED;
|
||||
scp->mouse_oldpos = Crtat + (scp->mouse_pos - scp->scr_buf);
|
||||
scp->status |= (UPDATE_MOUSE | MOUSE_ENABLED);
|
||||
mark_all(scp);
|
||||
}
|
||||
else
|
||||
return EINVAL;
|
||||
@ -897,40 +945,64 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
|
||||
case MOUSE_HIDE:
|
||||
if (scp->status & MOUSE_ENABLED) {
|
||||
scp->status &= ~MOUSE_ENABLED;
|
||||
scp->status |= UPDATE_MOUSE;
|
||||
mark_all(scp);
|
||||
}
|
||||
else
|
||||
return EINVAL;
|
||||
break;
|
||||
|
||||
case MOUSE_MOVEABS:
|
||||
scp->mouse_xpos = mouse->x;
|
||||
scp->mouse_ypos = mouse->y;
|
||||
goto set_mouse_pos;
|
||||
|
||||
case MOUSE_MOVEREL:
|
||||
scp->mouse_xpos += mouse->x;
|
||||
scp->mouse_ypos += mouse->y;
|
||||
set_mouse_pos:
|
||||
if (scp->mouse_xpos < 0)
|
||||
scp->mouse_xpos = 0;
|
||||
if (scp->mouse_ypos < 0)
|
||||
scp->mouse_ypos = 0;
|
||||
if (scp->mouse_xpos >= scp->xsize*8)
|
||||
scp->mouse_xpos = (scp->xsize*8)-1;
|
||||
if (scp->mouse_ypos >= scp->ysize*fontsize)
|
||||
scp->mouse_ypos = (scp->ysize*fontsize)-1;
|
||||
scp->mouse_pos = scp->scr_buf +
|
||||
(scp->mouse_ypos/fontsize)*scp->xsize + scp->mouse_xpos/8;
|
||||
if (scp->status & MOUSE_ENABLED)
|
||||
scp->status |= UPDATE_MOUSE;
|
||||
scp->mouse_xpos = mouse->u.data.x;
|
||||
scp->mouse_ypos = mouse->u.data.y;
|
||||
set_mouse_pos(scp);
|
||||
break;
|
||||
|
||||
case MOUSE_GETPOS:
|
||||
mouse->x = scp->mouse_xpos;
|
||||
mouse->y = scp->mouse_ypos;
|
||||
case MOUSE_MOVEREL:
|
||||
scp->mouse_xpos += mouse->u.data.x;
|
||||
scp->mouse_ypos += mouse->u.data.y;
|
||||
set_mouse_pos(scp);
|
||||
break;
|
||||
|
||||
case MOUSE_GETINFO:
|
||||
mouse->u.data.x = scp->mouse_xpos;
|
||||
mouse->u.data.y = scp->mouse_ypos;
|
||||
mouse->u.data.buttons = scp->mouse_buttons;
|
||||
return 0;
|
||||
|
||||
case MOUSE_ACTION:
|
||||
/* this should maybe only be settable from /dev/console SOS */
|
||||
cur_console->mouse_xpos += mouse->u.data.x;
|
||||
cur_console->mouse_ypos += mouse->u.data.y;
|
||||
if (cur_console->mouse_signal) {
|
||||
cur_console->mouse_buttons = mouse->u.data.buttons;
|
||||
/* has controlling process died? */
|
||||
if (cur_console->mouse_proc &&
|
||||
(cur_console->mouse_proc != pfind(cur_console->mouse_pid))){
|
||||
cur_console->mouse_signal = 0;
|
||||
cur_console->mouse_proc = NULL;
|
||||
cur_console->mouse_pid = 0;
|
||||
}
|
||||
else
|
||||
psignal(cur_console->mouse_proc, cur_console->mouse_signal);
|
||||
}
|
||||
else {
|
||||
/* process button presses*/
|
||||
if (cur_console->mouse_buttons != mouse->u.data.buttons) {
|
||||
cur_console->mouse_buttons = mouse->u.data.buttons;
|
||||
if (!(scp->status & UNKNOWN_MODE)) {
|
||||
if (cur_console->mouse_buttons & LEFT_BUTTON)
|
||||
mouse_cut_start(cur_console);
|
||||
else
|
||||
mouse_cut_end(cur_console);
|
||||
if (cur_console->mouse_buttons & RIGHT_BUTTON)
|
||||
mouse_paste(cur_console);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mouse->u.data.x != 0 || mouse->u.data.y != 0)
|
||||
set_mouse_pos(cur_console);
|
||||
break;
|
||||
|
||||
default:
|
||||
return EINVAL;
|
||||
}
|
||||
@ -1053,10 +1125,13 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
|
||||
break;
|
||||
}
|
||||
scp->mode = cmd & 0xff;
|
||||
scp->status &= ~UNKNOWN_MODE; /* text mode */
|
||||
scp->status &= ~UNKNOWN_MODE;
|
||||
free(scp->scr_buf, M_DEVBUF);
|
||||
scp->scr_buf = (u_short *)malloc(scp->xsize*scp->ysize*sizeof(u_short),
|
||||
M_DEVBUF, M_WAITOK);
|
||||
free(cut_buffer, M_DEVBUF);
|
||||
cut_buffer = (char *)malloc(scp->xsize*scp->ysize, M_DEVBUF, M_NOWAIT);
|
||||
cut_buffer[0] = 0x00;
|
||||
if (scp == cur_console)
|
||||
set_mode(scp);
|
||||
clear_screen(scp);
|
||||
@ -1538,7 +1613,7 @@ sccnputc(dev_t dev, int c)
|
||||
kernel_console = scp->term;
|
||||
current_default = &user_default;
|
||||
scp->term = save;
|
||||
s = splclock(); /* XXX stop scrn_timer */
|
||||
s = splclock();
|
||||
if (scp == cur_console) {
|
||||
if (scp->scr_buf != Crtat && (scp->start <= scp->end)) {
|
||||
bcopyw(scp->scr_buf + scp->start, Crtat + scp->start,
|
||||
@ -1575,6 +1650,7 @@ static void
|
||||
scrn_timer()
|
||||
{
|
||||
static int cursor_blinkrate;
|
||||
static int last_mouse_x = -1, last_mouse_y = -1;
|
||||
scr_stat *scp = cur_console;
|
||||
|
||||
/* should we just return ? */
|
||||
@ -1595,10 +1671,15 @@ scrn_timer()
|
||||
scp->status &= ~CURSOR_SHOWN;
|
||||
scp->start = scp->xsize * scp->ysize;
|
||||
scp->end = 0;
|
||||
last_mouse_x = last_mouse_y = -1;
|
||||
}
|
||||
/* update "pseudo" mouse arrow */
|
||||
if ((scp->status & MOUSE_ENABLED) && (scp->status & UPDATE_MOUSE))
|
||||
if ((scp->status & MOUSE_ENABLED) &&
|
||||
(scp->mouse_xpos!=last_mouse_x || scp->mouse_xpos!=last_mouse_x)) {
|
||||
last_mouse_x = scp->mouse_xpos;
|
||||
last_mouse_y = scp->mouse_ypos;
|
||||
draw_mouse_image(scp);
|
||||
}
|
||||
|
||||
/* update cursor image */
|
||||
if (scp->status & CURSOR_ENABLED)
|
||||
@ -1716,13 +1797,7 @@ exchange_scr(void)
|
||||
shfts = ctls = alts = agrs = metas = 0;
|
||||
update_leds(new_scp->status);
|
||||
delayed_next_scr = FALSE;
|
||||
bcopyw(new_scp->scr_buf, Crtat,
|
||||
(new_scp->xsize*new_scp->ysize)*sizeof(u_short));
|
||||
#ifdef PC98
|
||||
bcopyw(new_scp->atr_buf, Atrat,
|
||||
(new_scp->xsize*new_scp->ysize)*sizeof(u_short));
|
||||
#endif
|
||||
new_scp->status &= ~CURSOR_SHOWN;
|
||||
mark_all(new_scp);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2175,15 +2250,12 @@ scan_esc(scr_stat *scp, u_char c)
|
||||
n = scp->xsize - scp->xpos;
|
||||
#ifdef PC98
|
||||
fillw(scr_map[0x20],
|
||||
scp->scr_buf + scp->xpos +
|
||||
((scp->xsize*scp->ypos) * sizeof(u_short)), n);
|
||||
scp->cursor_pos, n);
|
||||
fillw(at2pc98(scp->term.cur_color),
|
||||
scp->atr_buf + scp->xpos +
|
||||
((scp->xsize*scp->ypos) * sizeof(u_short)), n);
|
||||
scp->cursor_atr, n);
|
||||
#else
|
||||
fillw(scp->term.cur_color | scr_map[0x20],
|
||||
scp->scr_buf + scp->xpos +
|
||||
((scp->xsize*scp->ypos) * sizeof(u_short)), n);
|
||||
scp->cursor_pos, n);
|
||||
#endif
|
||||
mark_for_update(scp, scp->cursor_pos - scp->scr_buf);
|
||||
#ifdef PC98
|
||||
@ -2790,6 +2862,9 @@ ansi_put(scr_stat *scp, u_char *buf, int len)
|
||||
}
|
||||
/* do we have to scroll ?? */
|
||||
if (scp->cursor_pos >= scp->scr_buf + scp->ysize * scp->xsize) {
|
||||
reverse_mouse_cut(scp, 0);
|
||||
scp->mouse_cut_start = scp->mouse_cut_end = NULL;
|
||||
scp->status &= ~MOUSE_CUTTING;
|
||||
if (scp->history) {
|
||||
bcopyw(scp->scr_buf, scp->history_head,
|
||||
scp->xsize * sizeof(u_short));
|
||||
@ -2982,7 +3057,7 @@ static scr_stat
|
||||
|
||||
scp = (scr_stat *)malloc(sizeof(scr_stat), M_DEVBUF, M_WAITOK);
|
||||
init_scp(scp);
|
||||
scp->scr_buf = scp->cursor_pos = scp->scr_buf = scp->mouse_pos =
|
||||
scp->scr_buf = scp->cursor_pos = scp->mouse_pos =
|
||||
(u_short *)malloc(scp->xsize*scp->ysize*sizeof(u_short),
|
||||
M_DEVBUF, M_WAITOK);
|
||||
#ifdef PC98
|
||||
@ -3014,7 +3089,7 @@ init_scp(scr_stat *scp)
|
||||
#else
|
||||
scp->mode = M_PC98_80x25;
|
||||
#endif
|
||||
scp->font = FONT_16;
|
||||
scp->font_size = FONT_16;
|
||||
scp->xsize = COL;
|
||||
scp->ysize = ROW;
|
||||
scp->start = COL * ROW;
|
||||
@ -3034,6 +3109,10 @@ init_scp(scr_stat *scp)
|
||||
scp->cursor_end = *(char *)pa_to_va(0x460);
|
||||
#endif
|
||||
scp->mouse_xpos = scp->mouse_ypos = 0;
|
||||
scp->mouse_cut_start = scp->mouse_cut_end = NULL;
|
||||
scp->mouse_signal = 0;
|
||||
scp->mouse_pid = 0;
|
||||
scp->mouse_proc = NULL;
|
||||
scp->bell_pitch = BELL_PITCH;
|
||||
scp->bell_duration = BELL_DURATION;
|
||||
#ifdef PC98
|
||||
@ -3180,14 +3259,7 @@ scgetc(int noblock)
|
||||
|
||||
if (cur_console->status & KBD_RAW_MODE)
|
||||
return scancode;
|
||||
#if ASYNCH
|
||||
if (scancode == KB_ACK || scancode == KB_RESEND) {
|
||||
kbd_reply = scancode;
|
||||
if (noblock)
|
||||
return(NOKEY);
|
||||
goto next_code;
|
||||
}
|
||||
#endif
|
||||
|
||||
keycode = scancode & 0x7F;
|
||||
switch (esc_flag) {
|
||||
case 0x00: /* normal scancode */
|
||||
@ -3682,40 +3754,29 @@ kbd_wait(void)
|
||||
#ifdef PC98
|
||||
DELAY(30);
|
||||
#else
|
||||
int i = 1000;
|
||||
int i = 500;
|
||||
|
||||
while (i--) {
|
||||
if ((inb(KB_STAT) & KB_READY) == 0)
|
||||
break;
|
||||
DELAY (10);
|
||||
DELAY (25);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef PC98
|
||||
static void
|
||||
kbd_cmd(u_char command)
|
||||
{
|
||||
#ifndef PC98
|
||||
int retry = 5;
|
||||
int i, retry = 5;
|
||||
do {
|
||||
int i = 100000;
|
||||
|
||||
kbd_wait();
|
||||
#if ASYNCH
|
||||
kbd_reply = 0;
|
||||
outb(KB_DATA, command);
|
||||
while (i--) {
|
||||
if (kbd_reply == KB_ACK)
|
||||
return;
|
||||
if (kbd_reply == KB_RESEND)
|
||||
break;
|
||||
}
|
||||
#else
|
||||
outb(KB_DATA, command);
|
||||
i = 50000;
|
||||
while (i--) {
|
||||
if (inb(KB_STAT) & KB_BUF_FULL) {
|
||||
int val;
|
||||
DELAY(10);
|
||||
DELAY(25);
|
||||
val = inb(KB_DATA);
|
||||
if (val == KB_ACK)
|
||||
return;
|
||||
@ -3723,10 +3784,9 @@ kbd_cmd(u_char command)
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} while (retry--);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
set_mode(scr_stat *scp)
|
||||
@ -3831,16 +3891,16 @@ set_mode(scr_stat *scp)
|
||||
switch (font_size) {
|
||||
case 0x10:
|
||||
outb(TSIDX, 0x03); outb(TSREG, 0x00); /* font 0 */
|
||||
scp->font = FONT_16;
|
||||
scp->font_size = FONT_16;
|
||||
break;
|
||||
case 0x0E:
|
||||
outb(TSIDX, 0x03); outb(TSREG, 0x05); /* font 1 */
|
||||
scp->font = FONT_14;
|
||||
scp->font_size = FONT_14;
|
||||
break;
|
||||
default:
|
||||
case 0x08:
|
||||
outb(TSIDX, 0x03); outb(TSREG, 0x0A); /* font 2 */
|
||||
scp->font = FONT_8;
|
||||
scp->font_size = FONT_8;
|
||||
break;
|
||||
}
|
||||
if (configuration & CHAR_CURSOR)
|
||||
@ -3853,6 +3913,7 @@ set_mode(scr_stat *scp)
|
||||
case M_BG640x480: case M_CG640x480: case M_VGA_CG320:
|
||||
|
||||
set_vgaregs(video_mode_ptr + (scp->mode * 64));
|
||||
scp->font_size = FONT_NONE;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -3879,10 +3940,10 @@ set_border(int color)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef PC98
|
||||
static void
|
||||
set_vgaregs(char *modetable)
|
||||
{
|
||||
#ifndef PC98
|
||||
int i, s = splhigh();
|
||||
|
||||
outb(TSIDX, 0x00); outb(TSREG, 0x01); /* stop sequencer */
|
||||
@ -3914,13 +3975,11 @@ set_vgaregs(char *modetable)
|
||||
inb(crtc_addr+6); /* reset flip-flop */
|
||||
outb(ATC ,0x20); /* enable palette */
|
||||
splx(s);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
set_font_mode()
|
||||
{
|
||||
#ifndef PC98
|
||||
/* setup vga for loading fonts (graphics plane mode) */
|
||||
inb(crtc_addr+6);
|
||||
outb(ATC, 0x30); outb(ATC, 0x01);
|
||||
@ -3937,13 +3996,11 @@ set_font_mode()
|
||||
outw(GDCIDX, 0x0005);
|
||||
outw(GDCIDX, 0x0506); /* addr = a0000, 64kb */
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
set_normal_mode()
|
||||
{
|
||||
#ifndef PC98
|
||||
int s = splhigh();
|
||||
|
||||
/* setup vga for normal operation mode again */
|
||||
@ -3971,8 +4028,8 @@ set_normal_mode()
|
||||
outw(GDCIDX, 0x0E06); /* addr = b8000, 32kb */
|
||||
#endif
|
||||
splx(s);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
copy_font(int operation, int font_type, char* font_image)
|
||||
@ -4018,36 +4075,50 @@ set_destructive_cursor(scr_stat *scp, int force)
|
||||
#ifndef PC98
|
||||
u_char cursor[32];
|
||||
caddr_t address;
|
||||
int i, font_size;
|
||||
int i;
|
||||
char *font_buffer;
|
||||
static u_char old_saveunder = DEAD_CHAR;
|
||||
u_short new_saveunder;
|
||||
|
||||
if (!force && (scp->cursor_saveunder & 0xFF) == old_saveunder)
|
||||
if (!force && !(scp->status & MOUSE_ENABLED) &&
|
||||
(scp->cursor_saveunder & 0xFF) == old_saveunder)
|
||||
return;
|
||||
old_saveunder = force ? DEAD_CHAR : scp->cursor_saveunder & 0xFF;
|
||||
switch (scp->font) {
|
||||
new_saveunder = scp->cursor_saveunder;
|
||||
switch (scp->font_size) {
|
||||
default:
|
||||
case FONT_8:
|
||||
font_size = 8;
|
||||
font_buffer = font_8;
|
||||
address = (caddr_t)VIDEOMEM + 0x8000;
|
||||
break;
|
||||
case FONT_14:
|
||||
font_size = 14;
|
||||
font_buffer = font_14;
|
||||
address = (caddr_t)VIDEOMEM + 0x4000;
|
||||
break;
|
||||
case FONT_16:
|
||||
font_size = 16;
|
||||
font_buffer = font_16;
|
||||
address = (caddr_t)VIDEOMEM;
|
||||
break;
|
||||
}
|
||||
bcopyw(font_buffer + ((scp->cursor_saveunder & 0xff) * font_size),
|
||||
cursor, font_size);
|
||||
if (scp->status & MOUSE_ENABLED) {
|
||||
if ((scp->cursor_saveunder & 0xff) == 0xd0)
|
||||
bcopyw(&scp->mouse_cursor[0], cursor, scp->font_size);
|
||||
else if ((scp->cursor_saveunder & 0xff) == 0xd1)
|
||||
bcopyw(&scp->mouse_cursor[32], cursor, scp->font_size);
|
||||
else if ((scp->cursor_saveunder & 0xff) == 0xd2)
|
||||
bcopyw(&scp->mouse_cursor[64], cursor, scp->font_size);
|
||||
else if ((scp->cursor_saveunder & 0xff) == 0xd3)
|
||||
bcopyw(&scp->mouse_cursor[96], cursor, scp->font_size);
|
||||
else
|
||||
bcopyw(font_buffer + ((scp->cursor_saveunder&0xff)*scp->font_size),
|
||||
cursor, scp->font_size);
|
||||
}
|
||||
else
|
||||
bcopyw(font_buffer + ((scp->cursor_saveunder&0xff) * scp->font_size),
|
||||
cursor, scp->font_size);
|
||||
for (i=0; i<32; i++)
|
||||
if ((i >= scp->cursor_start && i <= scp->cursor_end) ||
|
||||
(scp->cursor_start >= font_size && i == font_size - 1))
|
||||
(scp->cursor_start >= scp->font_size && i == scp->font_size - 1))
|
||||
cursor[i] |= 0xff;
|
||||
while (!(inb(crtc_addr+6) & 0x08)) /* wait for vertical retrace */ ;
|
||||
set_font_mode();
|
||||
@ -4056,40 +4127,152 @@ set_destructive_cursor(scr_stat *scp, int force)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
set_mouse_pos(scr_stat *scp)
|
||||
{
|
||||
/*
|
||||
* the margins imposed here are not ideal, we loose
|
||||
* a couble of pixels on the borders..
|
||||
*/
|
||||
if (scp->mouse_xpos < 0)
|
||||
scp->mouse_xpos = 0;
|
||||
if (scp->mouse_ypos < 0)
|
||||
scp->mouse_ypos = 0;
|
||||
if (scp->mouse_xpos > (scp->xsize*8)-2)
|
||||
scp->mouse_xpos = (scp->xsize*8)-2;
|
||||
if (scp->mouse_ypos > (scp->ysize*scp->font_size)-2)
|
||||
scp->mouse_ypos = (scp->ysize*scp->font_size)-2;
|
||||
|
||||
if (scp->status & UNKNOWN_MODE)
|
||||
return;
|
||||
|
||||
scp->mouse_pos = scp->scr_buf +
|
||||
((scp->mouse_ypos/scp->font_size)*scp->xsize + scp->mouse_xpos/8);
|
||||
|
||||
if ((scp->status & MOUSE_ENABLED) && (scp->status & MOUSE_CUTTING)) {
|
||||
int s = splclock();
|
||||
reverse_mouse_cut(scp, 0);
|
||||
scp->mouse_cut_end = scp->mouse_pos;
|
||||
reverse_mouse_cut(scp, 1);
|
||||
mark_all(scp);
|
||||
splx(s);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
reverse_mouse_cut(scr_stat *scp, int cut)
|
||||
{
|
||||
ushort *ptr;
|
||||
int i = 0;
|
||||
|
||||
if (scp->mouse_cut_start != NULL && scp->mouse_cut_end != NULL) {
|
||||
for (ptr = (scp->mouse_cut_start > scp->mouse_cut_end
|
||||
? scp->mouse_cut_end : scp->mouse_cut_start);
|
||||
ptr <= (scp->mouse_cut_start > scp->mouse_cut_end
|
||||
? scp->mouse_cut_start : scp->mouse_cut_end);
|
||||
ptr++) {
|
||||
*ptr = (*ptr & 0x88ff) | (*ptr & 0x7000)>>4 | (*ptr & 0x0700)<<4;
|
||||
if (cut) {
|
||||
cut_buffer[i++] = *ptr & 0xff;
|
||||
if (((ptr - scp->scr_buf) % scp->xsize) == (scp->xsize - 1)) {
|
||||
cut_buffer[i++] = '\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cut)
|
||||
cut_buffer[i] = 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mouse_cut_start(scr_stat *scp)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (scp->status & MOUSE_ENABLED) {
|
||||
reverse_mouse_cut(scp, 0);
|
||||
if (scp->mouse_pos == scp->mouse_cut_start &&
|
||||
scp->mouse_cut_start == scp->mouse_cut_end) {
|
||||
scp->mouse_cut_end = NULL;
|
||||
cut_buffer[0] = 0x00;
|
||||
scp->status &= ~MOUSE_CUTTING;
|
||||
mark_all(scp);
|
||||
}
|
||||
else {
|
||||
scp->mouse_cut_start = scp->mouse_cut_end = scp->mouse_pos;
|
||||
*scp->mouse_cut_start = (*scp->mouse_cut_start & 0x88ff) |
|
||||
(*scp->mouse_cut_start & 0x7000) >> 4 |
|
||||
(*scp->mouse_cut_start & 0x0700) << 4;
|
||||
cut_buffer[0] = *scp->mouse_cut_start & 0xff;
|
||||
cut_buffer[1] = 0x00;
|
||||
scp->status |= MOUSE_CUTTING;
|
||||
mark_for_update(scp, scp->mouse_cut_start - scp->scr_buf);
|
||||
set_mouse_pos(scp);
|
||||
}
|
||||
/* delete all other screens cut markings */
|
||||
for (i=0; i<MAXCONS; i++) {
|
||||
if (console[i] == NULL || console[i] == scp)
|
||||
continue;
|
||||
reverse_mouse_cut(console[i], 0);
|
||||
console[i]->status &= ~MOUSE_CUTTING;
|
||||
console[i]->mouse_cut_start = console[i]->mouse_cut_end = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mouse_cut_end(scr_stat *scp)
|
||||
{
|
||||
if (scp->status & MOUSE_ENABLED) {
|
||||
scp->status &= ~MOUSE_CUTTING;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mouse_paste(scr_stat *scp)
|
||||
{
|
||||
if (scp->status & MOUSE_ENABLED) {
|
||||
struct tty *tp;
|
||||
u_char *ptr = cut_buffer;
|
||||
|
||||
tp = VIRTUAL_TTY(get_scr_num());
|
||||
while (*ptr)
|
||||
(*linesw[tp->t_line].l_rint)(*ptr++, tp);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
draw_mouse_image(scr_stat *scp)
|
||||
{
|
||||
#ifndef PC98
|
||||
caddr_t address;
|
||||
int i, font_size;
|
||||
int i;
|
||||
char *font_buffer;
|
||||
u_short buffer[32];
|
||||
u_short xoffset, yoffset;
|
||||
u_short *crt_pos = Crtat + (scp->mouse_pos - scp->scr_buf);
|
||||
u_short *ptr = scp->scr_buf + (scp->mouse_oldpos - Crtat);
|
||||
int font_size = scp->font_size;
|
||||
|
||||
xoffset = scp->mouse_xpos % 8;
|
||||
switch (scp->font) {
|
||||
switch (font_size) {
|
||||
default:
|
||||
case FONT_8:
|
||||
font_size = 8;
|
||||
font_buffer = font_8;
|
||||
yoffset = scp->mouse_ypos % 8;
|
||||
address = (caddr_t)VIDEOMEM + 0x8000;
|
||||
break;
|
||||
case FONT_14:
|
||||
font_size = 14;
|
||||
font_buffer = font_14;
|
||||
yoffset = scp->mouse_ypos % 14;
|
||||
address = (caddr_t)VIDEOMEM + 0x4000;
|
||||
break;
|
||||
case FONT_16:
|
||||
font_size = 16;
|
||||
font_buffer = font_16;
|
||||
yoffset = scp->mouse_ypos % 16;
|
||||
address = (caddr_t)VIDEOMEM;
|
||||
break;
|
||||
}
|
||||
|
||||
bcopyw(font_buffer + ((*(scp->mouse_pos) & 0xff) * font_size),
|
||||
&scp->mouse_cursor[0], font_size);
|
||||
bcopyw(font_buffer + ((*(scp->mouse_pos+1) & 0xff) * font_size),
|
||||
@ -4098,7 +4281,6 @@ draw_mouse_image(scr_stat *scp)
|
||||
&scp->mouse_cursor[64], font_size);
|
||||
bcopyw(font_buffer + ((*(scp->mouse_pos+scp->xsize+1) & 0xff) * font_size),
|
||||
&scp->mouse_cursor[96], font_size);
|
||||
|
||||
for (i=0; i<font_size; i++) {
|
||||
buffer[i] = scp->mouse_cursor[i]<<8 | scp->mouse_cursor[i+32];
|
||||
buffer[i+font_size]=scp->mouse_cursor[i+64]<<8|scp->mouse_cursor[i+96];
|
||||
@ -4114,53 +4296,51 @@ draw_mouse_image(scr_stat *scp)
|
||||
scp->mouse_cursor[i+64] = (buffer[i+font_size] & 0xff00) >> 8;
|
||||
scp->mouse_cursor[i+96] = buffer[i+font_size] & 0xff;
|
||||
}
|
||||
if (scp->status & UPDATE_MOUSE) {
|
||||
u_short *ptr = scp->scr_buf + (scp->mouse_oldpos - Crtat);
|
||||
|
||||
if (crt_pos != scp->mouse_oldpos) {
|
||||
*(scp->mouse_oldpos) = scp->mouse_saveunder[0];
|
||||
*(scp->mouse_oldpos+1) = scp->mouse_saveunder[1];
|
||||
*(scp->mouse_oldpos+scp->xsize) = scp->mouse_saveunder[2];
|
||||
*(scp->mouse_oldpos+scp->xsize+1) = scp->mouse_saveunder[3];
|
||||
}
|
||||
scp->mouse_saveunder[0] = *(scp->mouse_pos);
|
||||
scp->mouse_saveunder[1] = *(scp->mouse_pos+1);
|
||||
scp->mouse_saveunder[2] = *(scp->mouse_pos+scp->xsize);
|
||||
scp->mouse_saveunder[3] = *(scp->mouse_pos+scp->xsize+1);
|
||||
if ((scp->cursor_pos == (ptr)) ||
|
||||
(scp->cursor_pos == (ptr+1)) ||
|
||||
(scp->cursor_pos == (ptr+scp->xsize)) ||
|
||||
(scp->cursor_pos == (ptr+scp->xsize+1)) ||
|
||||
(scp->cursor_pos == (scp->mouse_pos)) ||
|
||||
(scp->cursor_pos == (scp->mouse_pos+1)) ||
|
||||
(scp->cursor_pos == (scp->mouse_pos+scp->xsize)) ||
|
||||
(scp->cursor_pos == (scp->mouse_pos+scp->xsize+1)))
|
||||
scp->status &= ~CURSOR_SHOWN;
|
||||
if (crt_pos != scp->mouse_oldpos) {
|
||||
*(scp->mouse_oldpos) = scp->mouse_saveunder[0];
|
||||
*(scp->mouse_oldpos+1) = scp->mouse_saveunder[1];
|
||||
*(scp->mouse_oldpos+scp->xsize) = scp->mouse_saveunder[2];
|
||||
*(scp->mouse_oldpos+scp->xsize+1) = scp->mouse_saveunder[3];
|
||||
}
|
||||
scp->mouse_saveunder[0] = *(scp->mouse_pos);
|
||||
scp->mouse_saveunder[1] = *(scp->mouse_pos+1);
|
||||
scp->mouse_saveunder[2] = *(scp->mouse_pos+scp->xsize);
|
||||
scp->mouse_saveunder[3] = *(scp->mouse_pos+scp->xsize+1);
|
||||
if ((scp->cursor_pos == (ptr)) ||
|
||||
(scp->cursor_pos == (ptr+1)) ||
|
||||
(scp->cursor_pos == (ptr+scp->xsize)) ||
|
||||
(scp->cursor_pos == (ptr+scp->xsize+1)) ||
|
||||
(scp->cursor_pos == (scp->mouse_pos)) ||
|
||||
(scp->cursor_pos == (scp->mouse_pos+1)) ||
|
||||
(scp->cursor_pos == (scp->mouse_pos+scp->xsize)) ||
|
||||
(scp->cursor_pos == (scp->mouse_pos+scp->xsize+1)))
|
||||
scp->status &= ~CURSOR_SHOWN;
|
||||
scp->mouse_oldpos = crt_pos;
|
||||
while (!(inb(crtc_addr+6) & 0x08)) /* wait for vertical retrace */ ;
|
||||
*(crt_pos) = (*(scp->mouse_pos)&0xff00)|0xd0;
|
||||
*(crt_pos+1) = (*(scp->mouse_pos+1)&0xff00)|0xd1;
|
||||
*(crt_pos+scp->xsize) = (*(scp->mouse_pos+scp->xsize)&0xff00)|0xd2;
|
||||
*(crt_pos+scp->xsize+1) = (*(scp->mouse_pos+scp->xsize+1)&0xff00)|0xd3;
|
||||
set_font_mode();
|
||||
bcopy(scp->mouse_cursor, (char *)pa_to_va(address) + 0xd0 * 32, 128);
|
||||
set_normal_mode();
|
||||
*(crt_pos) = (*(scp->mouse_pos)&0xff00)|0xd0;
|
||||
*(crt_pos+scp->xsize) = (*(scp->mouse_pos+scp->xsize)&0xff00)|0xd2;
|
||||
if (scp->mouse_xpos < (scp->xsize-1)*8) {
|
||||
*(crt_pos+1) = (*(scp->mouse_pos+1)&0xff00)|0xd1;
|
||||
*(crt_pos+scp->xsize+1) = (*(scp->mouse_pos+scp->xsize+1)&0xff00)|0xd3;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef PC98
|
||||
static void
|
||||
save_palette(void)
|
||||
{
|
||||
#ifndef PC98
|
||||
int i;
|
||||
|
||||
outb(PALRADR, 0x00);
|
||||
for (i=0x00; i<0x300; i++)
|
||||
palette[i] = inb(PALDATA);
|
||||
inb(crtc_addr+6); /* reset flip/flop */
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
load_palette(void)
|
||||
|
@ -25,7 +25,7 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: syscons.h,v 1.15 1996/01/30 22:56:11 mpp Exp $
|
||||
* $Id: syscons.h,v 1.1.1.1 1996/06/14 10:04:47 asami Exp $
|
||||
*/
|
||||
|
||||
#ifndef _PC98_PC98_SYSCONS_H_
|
||||
@ -62,7 +62,7 @@
|
||||
#define CURSOR_ENABLED 0x00200
|
||||
#define CURSOR_SHOWN 0x00400
|
||||
#define MOUSE_ENABLED 0x00800
|
||||
#define UPDATE_MOUSE 0x01000
|
||||
#define MOUSE_CUTTING 0x01000
|
||||
|
||||
/* configuration flags */
|
||||
#define VISUAL_BELL 0x00001
|
||||
@ -112,9 +112,10 @@ static unsigned int TIMER_FREQ = 2457600;
|
||||
|
||||
#define CONSOLE_BUFSIZE 1024
|
||||
#define PCBURST 128
|
||||
#define FONT_8 0x001
|
||||
#define FONT_14 0x002
|
||||
#define FONT_16 0x004
|
||||
#define FONT_NONE 1
|
||||
#define FONT_8 8
|
||||
#define FONT_14 14
|
||||
#define FONT_16 16
|
||||
#define HISTORY_SIZE 100*80
|
||||
|
||||
/* defines related to hardware addresses */
|
||||
@ -152,8 +153,8 @@ typedef struct term_stat {
|
||||
int num_param; /* # of parameters to ESC */
|
||||
int last_param; /* last parameter # */
|
||||
int param[MAX_ESC_PAR]; /* contains ESC parameters */
|
||||
int cur_attr; /* current hardware attributes word */
|
||||
int attr_mask; /* current logical attributes mask */
|
||||
int cur_attr; /* current hardware attr word */
|
||||
int attr_mask; /* current logical attr mask */
|
||||
int cur_color; /* current hardware color */
|
||||
int std_color; /* normal hardware color */
|
||||
int rev_color; /* reverse hardware color */
|
||||
@ -169,6 +170,7 @@ typedef struct scr_stat {
|
||||
int ypos; /* current Y position */
|
||||
int xsize; /* X size */
|
||||
int ysize; /* Y size */
|
||||
int font_size; /* fontsize in Y direction */
|
||||
int start; /* modified area start */
|
||||
int end; /* modified area end */
|
||||
term_stat term; /* terminal emulation stuff */
|
||||
@ -182,12 +184,17 @@ typedef struct scr_stat {
|
||||
u_short mouse_saveunder[4]; /* saved chars under mouse */
|
||||
short mouse_xpos; /* mouse x coordinate */
|
||||
short mouse_ypos; /* mouse y coordinate */
|
||||
short mouse_buttons; /* mouse buttons */
|
||||
u_char mouse_cursor[128]; /* mouse cursor bitmap store */
|
||||
u_short *mouse_cut_start; /* mouse cut start pos */
|
||||
u_short *mouse_cut_end; /* mouse cut end pos */
|
||||
struct proc *mouse_proc; /* proc* of controlling proc */
|
||||
pid_t mouse_pid; /* pid of controlling proc */
|
||||
int mouse_signal; /* signal # to report with */
|
||||
u_short bell_duration;
|
||||
u_short bell_pitch;
|
||||
u_char border; /* border color */
|
||||
u_char mode; /* mode */
|
||||
u_char font; /* font on this screen */
|
||||
pid_t pid; /* pid of controlling proc */
|
||||
struct proc *proc; /* proc* of controlling proc */
|
||||
struct vt_mode smode; /* switch mode */
|
||||
@ -216,48 +223,9 @@ typedef struct default_attr {
|
||||
int rev_color; /* reverse hardware color */
|
||||
} default_attr;
|
||||
|
||||
/* function prototypes */
|
||||
static void scinit(void);
|
||||
static u_int scgetc(int noblock);
|
||||
static scr_stat *get_scr_stat(dev_t dev);
|
||||
static scr_stat *alloc_scp(void);
|
||||
static void init_scp(scr_stat *scp);
|
||||
static int get_scr_num(void);
|
||||
static void scrn_timer(void);
|
||||
static void clear_screen(scr_stat *scp);
|
||||
static int switch_scr(scr_stat *scp, u_int next_scr);
|
||||
static void exchange_scr(void);
|
||||
#ifdef PC98
|
||||
static void move_crsr(scr_stat *scp, int x, int y);
|
||||
#else
|
||||
static inline void move_crsr(scr_stat *scp, int x, int y);
|
||||
#endif
|
||||
static void scan_esc(scr_stat *scp, u_char c);
|
||||
#ifdef PC98
|
||||
static void draw_cursor(scr_stat *scp, int show);
|
||||
#else
|
||||
static inline void draw_cursor(scr_stat *scp, int show);
|
||||
#endif
|
||||
static void ansi_put(scr_stat *scp, u_char *buf, int len);
|
||||
static u_char *get_fstr(u_int c, u_int *len);
|
||||
static void update_leds(int which);
|
||||
static void history_to_screen(scr_stat *scp);
|
||||
static int history_up_line(scr_stat *scp);
|
||||
static int history_down_line(scr_stat *scp);
|
||||
static void kbd_wait(void);
|
||||
static void kbd_cmd(u_char command);
|
||||
static void set_mode(scr_stat *scp);
|
||||
void set_border(int color);
|
||||
static void set_vgaregs(char *modetable);
|
||||
static void set_font_mode(void);
|
||||
static void set_normal_mode(void);
|
||||
static void copy_font(int operation, int font_type, char* font_image);
|
||||
static void set_destructive_cursor(scr_stat *scp, int force);
|
||||
static void draw_mouse_image(scr_stat *scp);
|
||||
static void save_palette(void);
|
||||
void load_palette(void);
|
||||
static void do_bell(scr_stat *scp, int pitch, int duration);
|
||||
static void blink_screen(scr_stat *scp);
|
||||
void load_palette(void);
|
||||
void set_border(int color);
|
||||
|
||||
#ifdef PC98
|
||||
unsigned int at2pc98(unsigned int attr);
|
||||
#endif
|
||||
|
@ -254,7 +254,7 @@ static void wcd_describe (struct wcd *t);
|
||||
static int wcd_open(dev_t dev, int rawflag);
|
||||
static int wcd_setchan (struct wcd *t,
|
||||
u_char c0, u_char c1, u_char c2, u_char c3);
|
||||
static int wcd_eject (struct wcd *t);
|
||||
static int wcd_eject (struct wcd *t, int closeit);
|
||||
|
||||
static struct kern_devconf cftemplate = {
|
||||
0, 0, 0, "wcd", 0, { MDDT_DISK, 0 },
|
||||
@ -744,7 +744,12 @@ int wcdioctl (dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p)
|
||||
* by somebody (not us) in block mode. */
|
||||
if ((t->flags & F_BOPEN) && t->refcnt)
|
||||
return (EBUSY);
|
||||
return wcd_eject (t);
|
||||
return wcd_eject (t, 0);
|
||||
|
||||
case CDIOCCLOSE:
|
||||
if ((t->flags & F_BOPEN) && t->refcnt)
|
||||
return (0);
|
||||
return wcd_eject (t, 1);
|
||||
|
||||
case CDIOREADTOCHEADER:
|
||||
if (! t->toc.hdr.ending_track)
|
||||
@ -1072,7 +1077,7 @@ static int wcd_setchan (struct wcd *t,
|
||||
0, (char*) &t->au, - sizeof (t->au));
|
||||
}
|
||||
|
||||
static int wcd_eject (struct wcd *t)
|
||||
static int wcd_eject (struct wcd *t, int closeit)
|
||||
{
|
||||
struct atapires result;
|
||||
|
||||
@ -1085,12 +1090,16 @@ static int wcd_eject (struct wcd *t)
|
||||
if (result.code == RES_ERR &&
|
||||
((result.error & AER_SKEY) == AER_SK_NOT_READY ||
|
||||
(result.error & AER_SKEY) == AER_SK_UNIT_ATTENTION)) {
|
||||
int err;
|
||||
|
||||
if (!closeit)
|
||||
return (0);
|
||||
/*
|
||||
* The disc was unloaded.
|
||||
* Load it (close tray).
|
||||
* Read the table of contents.
|
||||
*/
|
||||
int err = wcd_request_wait (t, ATAPI_START_STOP,
|
||||
err = wcd_request_wait (t, ATAPI_START_STOP,
|
||||
0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0);
|
||||
if (err)
|
||||
return (err);
|
||||
@ -1110,6 +1119,9 @@ static int wcd_eject (struct wcd *t)
|
||||
return (EIO);
|
||||
}
|
||||
|
||||
if (closeit)
|
||||
return (0);
|
||||
|
||||
/* Give it some time to stop spinning. */
|
||||
tsleep ((caddr_t)&lbolt, PRIBIO, "wcdej1", 0);
|
||||
tsleep ((caddr_t)&lbolt, PRIBIO, "wcdej2", 0);
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)wd.c 7.2 (Berkeley) 5/9/91
|
||||
* $Id: wd.c,v 1.109 1996/06/08 10:03:35 bde Exp $
|
||||
* $Id: wd.c,v 1.1.1.1 1996/06/14 10:04:48 asami Exp $
|
||||
*/
|
||||
|
||||
/* TODO:
|
||||
@ -120,6 +120,7 @@ extern void wdstart(int ctrlr);
|
||||
/* can't handle that in all cases */
|
||||
#define WDOPT_32BIT 0x8000
|
||||
#define WDOPT_SLEEPHACK 0x4000
|
||||
#define WDOPT_FORCEHD(x) (((x)&0x0f00)>>8)
|
||||
#define WDOPT_MULTIMASK 0x00ff
|
||||
|
||||
|
||||
@ -334,7 +335,9 @@ static int wdcontrol(struct buf *bp);
|
||||
static int wdcommand(struct disk *du, u_int cylinder, u_int head,
|
||||
u_int sector, u_int count, u_int command);
|
||||
static int wdsetctlr(struct disk *du);
|
||||
#if 0
|
||||
static int wdwsetctlr(struct disk *du);
|
||||
#endif
|
||||
static int wdgetctlr(struct disk *du);
|
||||
static void wderror(struct buf *bp, struct disk *du, char *mesg);
|
||||
static void wdflushirq(struct disk *du, int old_ipl);
|
||||
@ -849,7 +852,6 @@ wdstart(int ctrlr)
|
||||
if (wdtab[ctrlr].b_active)
|
||||
return;
|
||||
#endif
|
||||
loop:
|
||||
/* is there a drive for the controller to do a transfer with? */
|
||||
bp = wdtab[ctrlr].controller_queue.tqh_first;
|
||||
if (bp == NULL) {
|
||||
@ -1660,6 +1662,7 @@ wdsetctlr(struct disk *du)
|
||||
return (0);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Wait until driver is inactive, then set up controller.
|
||||
*/
|
||||
@ -1676,6 +1679,7 @@ wdwsetctlr(struct disk *du)
|
||||
splx(x);
|
||||
return (stat);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* issue READP to drive to ask it what it is.
|
||||
@ -1859,9 +1863,8 @@ wdgetctlr(struct disk *du)
|
||||
#ifdef PC98
|
||||
/* for larger than 40MB */
|
||||
{
|
||||
long cyl = wp->wdp_fixedcyl * wp->wdp_heads * wp->wdp_sectors;
|
||||
wp->wdp_removcyl = 0; /* XXX ukai */
|
||||
#ifdef PC98
|
||||
long cyl = wp->wdp_cylinders * wp->wdp_heads * wp->wdp_sectors;
|
||||
|
||||
if ( du->dk_unit > 1 ) {
|
||||
wp->wdp_sectors = 17;
|
||||
wp->wdp_heads = 8;
|
||||
@ -1869,8 +1872,8 @@ wdgetctlr(struct disk *du)
|
||||
wp->wdp_sectors = bootinfo.bi_bios_geom[du->dk_unit] & 0xff;
|
||||
wp->wdp_heads = (bootinfo.bi_bios_geom[du->dk_unit] >> 8) & 0xff;
|
||||
}
|
||||
#endif
|
||||
wp->wdp_fixedcyl = cyl / (wp->wdp_heads * wp->wdp_sectors);
|
||||
|
||||
wp->wdp_cylinders = cyl / (wp->wdp_heads * wp->wdp_sectors);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1881,6 +1884,13 @@ wdgetctlr(struct disk *du)
|
||||
du->dk_dd.d_nsectors = wp->wdp_sectors;
|
||||
du->dk_dd.d_secpercyl = du->dk_dd.d_ntracks * du->dk_dd.d_nsectors;
|
||||
du->dk_dd.d_secperunit = du->dk_dd.d_secpercyl * du->dk_dd.d_ncylinders;
|
||||
if (WDOPT_FORCEHD(du->cfg_flags)) {
|
||||
du->dk_dd.d_ntracks = WDOPT_FORCEHD(du->cfg_flags);
|
||||
du->dk_dd.d_secpercyl =
|
||||
du->dk_dd.d_ntracks * du->dk_dd.d_nsectors;
|
||||
du->dk_dd.d_ncylinders =
|
||||
du->dk_dd.d_secperunit / du->dk_dd.d_secpercyl;
|
||||
}
|
||||
#if 0
|
||||
du->dk_dd.d_partitions[RAW_PART].p_size = du->dk_dd.d_secperunit;
|
||||
/* dubious ... */
|
||||
|
@ -23,7 +23,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: diskslice.h,v 1.12 1996/01/30 23:00:31 mpp Exp $
|
||||
* $Id: diskslice.h,v 1.13 1996/06/14 11:02:28 asami Exp $
|
||||
*/
|
||||
|
||||
#ifndef _SYS_DISKSLICE_H_
|
||||
@ -85,6 +85,10 @@ struct diskslice {
|
||||
u_long ds_offset; /* starting sector */
|
||||
u_long ds_size; /* number of sectors */
|
||||
int ds_type; /* (foreign) slice type */
|
||||
#ifdef PC98
|
||||
int ds_subtype; /* sub slice type */
|
||||
u_char ds_name[16]; /* slice name */
|
||||
#endif
|
||||
struct dkbad_intern *ds_bad; /* bad sector table, if any */
|
||||
void *ds_date; /* Slice type specific data */
|
||||
struct slice_switch *switch; /* switch table for type handler */
|
||||
|
Loading…
Reference in New Issue
Block a user