Update to current state of PC98 world.

Submitted by:	The FreeBSD(98) development team
This commit is contained in:
Satoshi Asami 1996-07-23 07:46:59 +00:00
parent 4d8db7c76f
commit 92b4f2e0df
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=17256
64 changed files with 2941 additions and 6632 deletions

View File

@ -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)
{

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)
{

View File

@ -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;

View File

@ -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).

View File

@ -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 $

View File

@ -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();

View File

@ -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) \

View File

@ -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;

View File

@ -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:

View File

@ -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
**************************************************************************/

View File

@ -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);
}

View File

@ -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)

View File

@ -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
}

View File

@ -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

View File

@ -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
}

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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) {

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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
*/

View File

@ -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.

View File

@ -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;
}
/*

View File

@ -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
}

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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
/*

View File

@ -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.

View File

@ -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! */

View File

@ -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

View File

@ -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 */

View File

@ -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)

View File

@ -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) {

View File

@ -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>

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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];

View File

@ -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 */

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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.
*/

View File

@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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);

View File

@ -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 ... */

View File

@ -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 */