1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-02 08:42:48 +00:00

Change a directory layout for pc98.

- Move MD files into <arch>/<arch>.
  - Move bus dependent files into <arch>/<bus>.
Rename some files to more suitable names.

Repo-copied by:	peter
Discussed with:	imp
This commit is contained in:
Yoshihiro Takahashi 2005-05-10 12:02:18 +00:00
parent 671adc85da
commit d1725ef7ff
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=146049
52 changed files with 53 additions and 22354 deletions

View File

@ -32,7 +32,7 @@ __FBSDID("$FreeBSD$");
#include "boot.h"
#include <machine/cpufunc.h>
#include <sys/reboot.h>
#include <pc98/pc98/pc98.h>
#include <pc98/cbus/cbus.h>
static int getchar(int in_buf);

View File

@ -347,29 +347,29 @@ libkern/ucmpdi2.c standard
libkern/udivdi3.c standard
libkern/umoddi3.c standard
pc98/apm/apm_bioscall.S optional apm
pc98/i386/busio.s standard
pc98/i386/busiosubr.c standard
pc98/i386/machdep.c standard
pc98/cbus/cbus_dma.c optional isa
pc98/cbus/clock.c standard
pc98/cbus/fdc.c optional fdc
pc98/cbus/fdc_cbus.c optional fdc isa
pc98/cbus/gdc.c optional gdc
pc98/cbus/nmi.c standard
pc98/cbus/olpt.c optional olpt
pc98/cbus/pckbd.c optional pckbd
pc98/cbus/pmc.c optional pmc
pc98/cbus/ppc.c optional ppc
pc98/cbus/scgdcrndr.c optional sc gdc
pc98/cbus/scterm-sck.c optional sc
pc98/cbus/scvtb.c optional sc
pc98/cbus/sio.c optional sio
pc98/cbus/sio_cbus.c optional sio isa
pc98/cbus/syscons_cbus.c optional sc
pc98/pc98/busio.s standard
pc98/pc98/busiosubr.c standard
pc98/pc98/canbepm.c optional canbepm
pc98/pc98/canbus.c optional canbus
pc98/pc98/canbus_if.m optional canbus
pc98/pc98/clock.c standard
pc98/pc98/fd.c optional fdc
pc98/pc98/fdc_cbus.c optional fdc isa
pc98/pc98/isa_dma.c optional isa
pc98/pc98/nmi.c standard
pc98/pc98/olpt.c optional olpt
pc98/pc98/machdep.c standard
pc98/pc98/pc98_machdep.c standard
pc98/pc98/pc98gdc.c optional gdc
pc98/pc98/pc98kbd.c optional pckbd
pc98/pc98/pmc.c optional pmc
pc98/pc98/ppc.c optional ppc
pc98/pc98/scgdcrndr.c optional sc gdc
pc98/pc98/scterm-sck.c optional sc
pc98/pc98/scvtbpc98.c optional sc
pc98/pc98/sio.c optional sio
pc98/pc98/sio_cbus.c optional sio isa
pc98/pc98/syscons_pc98.c optional sc
pccard/pccard.c optional card
pccard/pccard_beep.c optional card
pccard/pccard_nbk.c optional card

View File

@ -78,7 +78,7 @@ __FBSDID("$FreeBSD$");
#include <sys/rman.h>
#include <machine/md_var.h>
#include <pc98/pc98/pc98.h>
#include <pc98/cbus/cbus.h>
#include <isa/isavar.h>
#include <compat/netbsd/dvcfg.h>

View File

@ -20,7 +20,7 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <isa/isavar.h>
#ifdef PC98
#include <pc98/pc98/pc98.h>
#include <pc98/cbus/cbus.h>
#else
#include <i386/isa/isa.h>
#endif

View File

@ -34,7 +34,7 @@
/* machine-dependent part of the header */
#ifdef PC98
#include <pc98/pc98/sc_machdep.h>
#include <pc98/cbus/sc_machdep.h>
#elif defined(__i386__)
/* nothing for the moment */
#elif defined(__alpha__)

View File

@ -64,7 +64,7 @@ __FBSDID("$FreeBSD$");
#ifdef DEV_ISA
#include <isa/isavar.h>
#ifdef PC98
#include <pc98/pc98/pc98.h>
#include <pc98/cbus/cbus.h>
#else
#include <i386/isa/isa.h>
#endif

View File

@ -91,7 +91,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_param.h>
#ifdef PC98
#include <pc98/pc98/pc98.h>
#include <pc98/cbus/cbus.h>
#else
#include <i386/isa/isa.h>
#endif

View File

@ -56,7 +56,7 @@ __FBSDID("$FreeBSD$");
#include <dev/ic/i8259.h>
#include <i386/isa/icu.h>
#ifdef PC98
#include <pc98/pc98/pc98.h>
#include <pc98/cbus/cbus.h>
#else
#include <i386/isa/isa.h>
#endif

View File

@ -70,7 +70,7 @@ __FBSDID("$FreeBSD$");
#include <machine/ucontext.h>
#ifdef PC98
#include <pc98/pc98/pc98.h>
#include <pc98/cbus/cbus.h>
#else
#include <i386/isa/isa.h>
#endif

View File

@ -46,7 +46,7 @@ __FBSDID("$FreeBSD$");
#include <machine/asmacros.h>
#ifdef PC98
#include <pc98/pc98/pc98.h>
#include <pc98/cbus/cbus.h>
#else
#include <i386/isa/isa.h>
#endif

View File

@ -20,7 +20,7 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <isa/isavar.h>
#ifdef PC98
#include <pc98/pc98/pc98.h>
#include <pc98/cbus/cbus.h>
#else
#include <i386/isa/isa.h>
#endif

View File

@ -4,8 +4,8 @@ KMOD= fdc
WARNS?= 2
.if ${MACHINE} == "pc98"
.PATH: ${.CURDIR}/../../pc98/pc98
SRCS= fd.c fdc_cbus.c
.PATH: ${.CURDIR}/../../pc98/cbus
SRCS= fdc.c fdc_cbus.c
.else
.PATH: ${.CURDIR}/../../dev/fdc
SRCS= fdc.c fdc_isa.c fdc_pccard.c

View File

@ -1,6 +1,6 @@
# $FreeBSD$
.PATH: ${.CURDIR}/../../pc98/pc98
.PATH: ${.CURDIR}/../../pc98/cbus
KMOD= pmc
SRCS= pmc.c

View File

@ -1,7 +1,7 @@
# $FreeBSD$
.if ${MACHINE} == "pc98"
.PATH: ${.CURDIR}/../../pc98/pc98
.PATH: ${.CURDIR}/../../pc98/cbus
.endif
.PATH: ${.CURDIR}/../../dev/sio

View File

@ -60,9 +60,9 @@ __FBSDID("$FreeBSD$");
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/pmap.h>
#include <pc98/pc98/pc98.h>
#include <dev/ic/i8237.h>
#include <isa/isavar.h>
#include <pc98/cbus/cbus.h>
/*
** Register definitions for DMA controller 1 (channels 0..3):

View File

@ -81,7 +81,7 @@
#include <machine/specialreg.h>
#include <i386/isa/icu.h>
#include <pc98/pc98/pc98.h>
#include <pc98/cbus/cbus.h>
#include <pc98/pc98/pc98_machdep.h>
#ifdef DEV_ISA
#include <isa/isavar.h>

View File

@ -78,11 +78,11 @@
#ifdef PC98
#include <isa/isavar.h>
#include <pc98/pc98/pc98.h>
#include <pc98/pc98/pc98_machdep.h>
#include <pc98/cbus/cbus.h>
#include <pc98/cbus/fdcreg.h>
#include <pc98/cbus/fdcvar.h>
#include <pc98/pc98/epsonio.h>
#include <pc98/pc98/fdreg.h>
#include <pc98/pc98/fdcvar.h>
#include <pc98/pc98/pc98_machdep.h>
#else
#include <isa/isavar.h>
#include <isa/isareg.h>

View File

@ -39,11 +39,11 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <pc98/pc98/fdcvar.h>
#include <pc98/pc98/fdreg.h>
#include <pc98/cbus/cbus.h>
#include <pc98/cbus/fdcreg.h>
#include <pc98/cbus/fdcvar.h>
#include <isa/isavar.h>
#include <pc98/pc98/pc98.h>
static bus_addr_t fdc_iat[] = {0, 2, 4};

View File

@ -55,7 +55,7 @@
#include <dev/fb/fbreg.h>
#ifdef LINE30
#include <pc98/pc98/pc98.h>
#include <pc98/cbus/cbus.h>
#endif
#include <pc98/pc98/pc98_machdep.h>
#include <isa/isavar.h>
@ -423,7 +423,7 @@ DRIVER_MODULE(gdc, isa, gdcdriver, gdc_devclass, 0, 0);
/* LOW-LEVEL */
#include <pc98/pc98/30line.h>
#include <pc98/cbus/30line.h>
#define TEXT_BUF_BASE 0x000a0000
#define TEXT_BUF_SIZE 0x00008000

View File

@ -43,8 +43,7 @@
#include <dev/kbd/kbdreg.h>
#include <pc98/pc98/pc98.h>
#include <pc98/cbus/cbus.h>
#include <isa/isavar.h>
#define DRIVER_NAME "pckbd"

View File

@ -81,7 +81,7 @@
#include <machine/specialreg.h>
#include <i386/isa/icu.h>
#include <pc98/pc98/pc98.h>
#include <pc98/cbus/cbus.h>
#include <pc98/pc98/pc98_machdep.h>
#ifdef DEV_ISA
#include <isa/isavar.h>

View File

@ -44,7 +44,7 @@
#include <sys/rman.h>
#ifdef PC98
#include <pc98/pc98/pc98.h>
#include <pc98/cbus/cbus.h>
#else
#include <isa/isareg.h>
#endif
@ -55,7 +55,7 @@
#include <dev/ppc/ppcvar.h>
#ifdef PC98
#include <pc98/pc98/ppcreg.h>
#include <pc98/cbus/ppcreg.h>
#else
#include <dev/ppc/ppcreg.h>
#endif

View File

@ -111,7 +111,7 @@
#include <dev/sio/siovar.h>
#ifdef PC98
#include <pc98/pc98/pc98.h>
#include <pc98/cbus/cbus.h>
#include <pc98/pc98/pc98_machdep.h>
#endif

View File

@ -39,7 +39,7 @@
#include <machine/clock.h>
#include <pc98/pc98/pc98.h>
#include <pc98/cbus/cbus.h>
#include <pc98/pc98/pc98_machdep.h>
#include <dev/syscons/syscons.h>

File diff suppressed because it is too large Load Diff

View File

@ -1,281 +0,0 @@
/* $FreeBSD$ */
/* $NecBSD: busiosubr.c,v 1.30.4.4 1999/08/28 02:25:35 honda Exp $ */
/* $NetBSD$ */
/*-
* [NetBSD for NEC PC-98 series]
* Copyright (c) 1996, 1997, 1998
* NetBSD/pc98 porting staff. All rights reserved.
*
* [Ported for FreeBSD]
* Copyright (c) 2001
* TAKAHASHI Yoshihiro. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 1997, 1998
* Naofumi HONDA. All rights reserved.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <machine/bus.h>
static MALLOC_DEFINE(M_BUSSPACEHANDLE, "busspacehandle", "Bus space handle");
_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_DA_io,u_int8_t,1)
_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_DA_io,u_int16_t,2)
_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_DA_io,u_int32_t,4)
_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_DA_mem,u_int8_t,1)
_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_DA_mem,u_int16_t,2)
_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_DA_mem,u_int32_t,4)
_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_RA_io,u_int8_t,1)
_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_RA_io,u_int16_t,2)
_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_RA_io,u_int32_t,4)
_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_RA_mem,u_int8_t,1)
_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_RA_mem,u_int16_t,2)
_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_RA_mem,u_int32_t,4)
struct bus_space_tag SBUS_io_space_tag = {
BUS_SPACE_IO,
/* direct bus access methods */
{
_BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_io,u_int8_t,1),
_BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_io,u_int16_t,2),
_BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_io,u_int32_t,4),
},
/* relocate bus access methods */
{
_BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_io,u_int8_t,1),
_BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_io,u_int16_t,2),
_BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_io,u_int32_t,4),
}
};
struct bus_space_tag SBUS_mem_space_tag = {
BUS_SPACE_MEM,
/* direct bus access methods */
{
_BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_mem,u_int8_t,1),
_BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_mem,u_int16_t,2),
_BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_mem,u_int32_t,4),
},
/* relocate bus access methods */
{
_BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_mem,u_int8_t,1),
_BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_mem,u_int16_t,2),
_BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_mem,u_int32_t,4),
}
};
#include "opt_mecia.h"
#ifdef DEV_MECIA
_BUS_SPACE_CALL_FUNCS_PROTO(NEPC_DA_io,u_int16_t,2)
_BUS_SPACE_CALL_FUNCS_PROTO(NEPC_DA_io,u_int32_t,4)
_BUS_SPACE_CALL_FUNCS_PROTO(NEPC_RA_io,u_int16_t,2)
_BUS_SPACE_CALL_FUNCS_PROTO(NEPC_RA_io,u_int32_t,4)
struct bus_space_tag NEPC_io_space_tag = {
BUS_SPACE_IO,
/* direct bus access methods */
{
_BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_io,u_int8_t,1),
_BUS_SPACE_CALL_FUNCS_TAB(NEPC_DA_io,u_int16_t,2),
_BUS_SPACE_CALL_FUNCS_TAB(NEPC_DA_io,u_int32_t,4),
},
/* relocate bus access methods */
{
_BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_io,u_int8_t,1),
_BUS_SPACE_CALL_FUNCS_TAB(NEPC_RA_io,u_int16_t,2),
_BUS_SPACE_CALL_FUNCS_TAB(NEPC_RA_io,u_int32_t,4),
}
};
struct bus_space_tag NEPC_mem_space_tag = {
BUS_SPACE_MEM,
/* direct bus access methods */
{
_BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_mem,u_int8_t,1),
_BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_mem,u_int16_t,2),
_BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_mem,u_int32_t,4),
},
/* relocate bus access methods */
{
_BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_mem,u_int8_t,1),
_BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_mem,u_int16_t,2),
_BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_mem,u_int32_t,4),
}
};
#endif /* DEV_MECIA */
/*************************************************************************
* map init
*************************************************************************/
static __inline void
bus_space_iat_init(bus_space_handle_t bsh)
{
int i;
for (i = 0; i < bsh->bsh_maxiatsz; i++)
bsh->bsh_iat[i] = bsh->bsh_base + i;
}
/*************************************************************************
* handle allocation
*************************************************************************/
int
i386_bus_space_handle_alloc(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size,
bus_space_handle_t *bshp)
{
bus_space_handle_t bsh;
bsh = (bus_space_handle_t) malloc(sizeof (*bsh), M_BUSSPACEHANDLE,
M_NOWAIT | M_ZERO);
if (bsh == NULL)
return ENOMEM;
bsh->bsh_maxiatsz = BUS_SPACE_IAT_MAXSIZE;
bsh->bsh_iatsz = 0;
bsh->bsh_base = bpa;
bsh->bsh_sz = size;
bsh->bsh_res = NULL;
bsh->bsh_ressz = 0;
bus_space_iat_init(bsh);
bsh->bsh_bam = t->bs_da; /* default: direct access */
*bshp = bsh;
return 0;
}
void
i386_bus_space_handle_free(bus_space_tag_t t, bus_space_handle_t bsh,
size_t size)
{
free(bsh, M_BUSSPACEHANDLE);
}
/*************************************************************************
* map
*************************************************************************/
int
i386_memio_map(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size, int flags,
bus_space_handle_t *bshp)
{
return i386_bus_space_handle_alloc(t, bpa, size, bshp);
}
void
i386_memio_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size)
{
i386_bus_space_handle_free(t, bsh, bsh->bsh_sz);
}
void
i386_memio_free(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size)
{
/* i386_memio_unmap() does all that we need to do. */
i386_memio_unmap(t, bsh, bsh->bsh_sz);
}
int
i386_memio_subregion(bus_space_tag_t t, bus_space_handle_t pbsh,
bus_size_t offset, bus_size_t size,
bus_space_handle_t *tbshp)
{
int i, error = 0;
bus_space_handle_t bsh;
bus_addr_t pbase;
pbase = pbsh->bsh_base + offset;
switch (t->bs_tag) {
case BUS_SPACE_IO:
if (pbsh->bsh_iatsz > 0) {
if (offset >= pbsh->bsh_iatsz ||
offset + size > pbsh->bsh_iatsz)
return EINVAL;
pbase = pbsh->bsh_base;
}
break;
case BUS_SPACE_MEM:
if (pbsh->bsh_iatsz > 0)
return EINVAL;
if (offset > pbsh->bsh_sz || offset + size > pbsh->bsh_sz)
return EINVAL;
break;
default:
panic("i386_memio_subregion: bad bus space tag");
break;
}
error = i386_bus_space_handle_alloc(t, pbase, size, &bsh);
if (error != 0)
return error;
switch (t->bs_tag) {
case BUS_SPACE_IO:
if (pbsh->bsh_iatsz > 0) {
for (i = 0; i < size; i ++)
bsh->bsh_iat[i] = pbsh->bsh_iat[i + offset];
bsh->bsh_iatsz = size;
} else if (pbsh->bsh_base > bsh->bsh_base ||
pbsh->bsh_base + pbsh->bsh_sz <
bsh->bsh_base + bsh->bsh_sz) {
i386_bus_space_handle_free(t, bsh, size);
return EINVAL;
}
break;
case BUS_SPACE_MEM:
break;
}
if (pbsh->bsh_iatsz > 0)
bsh->bsh_bam = t->bs_ra; /* relocate access */
*tbshp = bsh;
return error;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,130 +0,0 @@
/*-
* Copyright (c) 1994, 1995, 1996. FreeBSD(98) porting team.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer as
* the first lines of this file unmodified.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef __PC98_PC98_30LINE_H__
#define __PC98_PC98_30LINE_H__
#define LINE30_ROW 30
#define _HS 1 + 1
#define _VS 2
#define _HFP 3 + 1
#define _HBP 14 + 1
#define _VFP 11
#define _VBP 44
#define _CR 80
#define _LF LINE30_ROW*16
#define _GDC_RESET 0x00
#define _GDC_SYNC 0x0e
#define _GDC_MASTER 0x6f
#define _GDC_SLAVE 0x6e
#define _GDC_START 0x0d
#define _GDC_STOP 0x0c
#define _GDC_SCROLL 0x70
#define _GDC_PITCH 0x47
#define GDC_CR 0
#define GDC_VS 1
#define GDC_HS 2
#define GDC_HFP 3
#define GDC_HBP 4
#define GDC_VFP 5
#define GDC_VBP 6
#define GDC_LF 7
#define _24KHZ 0
#define _31KHZ 1
#define _2_5MHZ 0
#define _5MHZ 1
#define _25L 0
#define _30L 1
#define T25_G400 0
#define T30_G400 1
#define T30_G480 2
static void master_gdc_cmd(unsigned int);
static void master_gdc_prm(unsigned int);
static void master_gdc_word_prm(unsigned int);
#ifdef LINE30
static void master_gdc_fifo_empty(void);
#endif
static void master_gdc_wait_vsync(void);
static void gdc_cmd(unsigned int);
#ifdef LINE30
static void gdc_prm(unsigned int);
static void gdc_word_prm(unsigned int);
static void gdc_fifo_empty(void);
#endif
static void gdc_wait_vsync(void);
#ifdef LINE30
static int check_gdc_clock(void);
static int gdc_INFO = _25L;
#endif
static int gdc_FH = _24KHZ;
static void initialize_gdc(unsigned int, int);
#ifdef LINE30
static unsigned int master_param[2][2][8] = {
{{78, 8, 7, 9, 7, 7, 25, 400}, /* 400/24k */
{_CR-2, _VS, _HS-1, _HFP-1, _HBP-1, _VFP, _VBP, _LF}}, /* 480/24k */
{{78, 2, 7, 3, 7, 13, 34, 400}, /* 400/31k */
{78, 2, 11, 3, 3, 6, 37, 480}}}; /* 480/31k */
static unsigned int slave_param[2][6][8] = {
{{38, 8, 3, 4, 3, 7, 25, 400}, /* normal */
{78, 8, 7, 9, 7, 7, 25, 400},
{_CR/2-2, _VS, (_HS)/2-1, (_HFP)/2-1, (_HBP)/2-1,
_VFP+(_LF-400)/2+8, _VBP+(_LF-400)/2-8, 400}, /* 30 & 400 */
{_CR-2, _VS, _HS-1, _HFP-1, _HBP-1,
_VFP+(_LF-400)/2+8, _VBP+(_LF-400)/2-8, 400},
{_CR/2-2, _VS, (_HS)/2-1, (_HFP)/2-1, (_HBP)/2-1,
_VFP, _VBP, _LF}, /* 30 & 480 */
{_CR-2, _VS, _HS-1, _HFP-1, _HBP-1, _VFP, _VBP, _LF}},
{{38, 2, 3, 1, 3, 13, 34, 400}, /* normal */
{78, 2, 7, 3, 7, 13, 34, 400},
{38, 2, 5, 1, 1, 6+48, 37+32, 400}, /* 30 & 400 */
{78, 2, 11, 3, 3, 6+48, 37+32, 400},
{38, 2, 5, 1, 1, 6, 37, 480}, /* 30 & 480 */
{78, 2, 11, 3, 3, 6, 37, 480}}};
static int SlavePCH[2] = {40,80};
static int MasterPCH = 80;
static int SlaveScrlLF[3] = {400,400,_LF};
#endif
#endif /* __PC98_PC98_30LINE_H__ */

View File

@ -1,885 +0,0 @@
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* William Jolitz and Don Ahn.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
* $FreeBSD$
*/
/*
* Routines to handle clock hardware.
*/
/*
* inittodr, settodr and support routines written
* by Christoph Robitschko <chmr@edvz.tu-graz.ac.at>
*
* reintroduced and updated by Chris Stenton <chris@gnome.co.uk> 8/10/94
*/
/*
* modified for PC98 by Kakefuda
*/
#include "opt_apic.h"
#include "opt_clock.h"
#include "opt_isa.h"
#include "opt_mca.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/lock.h>
#include <sys/kdb.h>
#include <sys/mutex.h>
#include <sys/proc.h>
#include <sys/time.h>
#include <sys/timetc.h>
#include <sys/kernel.h>
#include <sys/limits.h>
#include <sys/module.h>
#include <sys/sysctl.h>
#include <sys/cons.h>
#include <sys/power.h>
#include <machine/clock.h>
#include <machine/cputypes.h>
#include <machine/frame.h>
#include <machine/intr_machdep.h>
#include <machine/md_var.h>
#include <machine/psl.h>
#ifdef DEV_APIC
#include <machine/apicvar.h>
#endif
#include <machine/specialreg.h>
#include <i386/isa/icu.h>
#include <pc98/pc98/pc98.h>
#include <pc98/pc98/pc98_machdep.h>
#ifdef DEV_ISA
#include <isa/isavar.h>
#endif
#include <i386/isa/timerreg.h>
/*
* 32-bit time_t's can't reach leap years before 1904 or after 2036, so we
* can use a simple formula for leap years.
*/
#define LEAPYEAR(y) (((u_int)(y) % 4 == 0) ? 1 : 0)
#define DAYSPERYEAR (31+28+31+30+31+30+31+31+30+31+30+31)
#define TIMER_DIV(x) ((timer_freq + (x) / 2) / (x))
int adjkerntz; /* local offset from GMT in seconds */
int clkintr_pending;
int disable_rtc_set; /* disable resettodr() if != 0 */
int pscnt = 1;
int psdiv = 1;
int statclock_disable;
#ifndef TIMER_FREQ
#define TIMER_FREQ 2457600
#endif
u_int timer_freq = TIMER_FREQ;
int timer0_max_count;
int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */
struct mtx clock_lock;
static int beeping = 0;
static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31};
static u_int hardclock_max_count;
static struct intsrc *i8254_intsrc;
static u_int32_t i8254_lastcount;
static u_int32_t i8254_offset;
static int (*i8254_pending)(struct intsrc *);
static int i8254_ticked;
static int using_lapic_timer;
/* Values for timerX_state: */
#define RELEASED 0
#define RELEASE_PENDING 1
#define ACQUIRED 2
#define ACQUIRE_PENDING 3
static u_char timer1_state;
static u_char timer2_state;
static void rtc_serialcombit(int);
static void rtc_serialcom(int);
static int rtc_inb(void);
static void rtc_outb(int);
static unsigned i8254_get_timecount(struct timecounter *tc);
static void set_timer_freq(u_int freq, int intr_freq);
static struct timecounter i8254_timecounter = {
i8254_get_timecount, /* get_timecount */
0, /* no poll_pps */
~0u, /* counter_mask */
0, /* frequency */
"i8254", /* name */
0 /* quality */
};
static void
clkintr(struct clockframe *frame)
{
if (timecounter->tc_get_timecount == i8254_get_timecount) {
mtx_lock_spin(&clock_lock);
if (i8254_ticked)
i8254_ticked = 0;
else {
i8254_offset += timer0_max_count;
i8254_lastcount = 0;
}
clkintr_pending = 0;
mtx_unlock_spin(&clock_lock);
}
if (!using_lapic_timer)
hardclock(frame);
}
int
acquire_timer1(int mode)
{
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);
}
int
acquire_timer2(int mode)
{
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_timer1()
{
if (timer1_state != ACQUIRED)
return (-1);
timer1_state = RELEASED;
outb(TIMER_MODE, TIMER_SEL1 | TIMER_SQWAVE | TIMER_16BIT);
return (0);
}
int
release_timer2()
{
if (timer2_state != ACQUIRED)
return (-1);
timer2_state = RELEASED;
outb(TIMER_MODE, TIMER_SEL2 | TIMER_SQWAVE | TIMER_16BIT);
return (0);
}
static int
getit(void)
{
int high, low;
mtx_lock_spin(&clock_lock);
/* Select timer0 and latch counter value. */
outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
low = inb(TIMER_CNTR0);
high = inb(TIMER_CNTR0);
mtx_unlock_spin(&clock_lock);
return ((high << 8) | low);
}
/*
* Wait "n" microseconds.
* Relies on timer 1 counting down from (timer_freq / hz)
* Note: timer had better have been programmed before this is first used!
*/
void
DELAY(int n)
{
int delta, prev_tick, tick, ticks_left;
#ifdef DELAYDEBUG
int getit_calls = 1;
int n1;
static int state = 0;
if (state == 0) {
state = 1;
for (n1 = 1; n1 <= 10000000; n1 *= 10)
DELAY(n1);
state = 2;
}
if (state == 1)
printf("DELAY(%d)...", n);
#endif
/*
* Guard against the timer being uninitialized if we are called
* early for console i/o.
*/
if (timer0_max_count == 0)
set_timer_freq(timer_freq, hz);
/*
* Read the counter first, so that the rest of the setup overhead is
* counted. Guess the initial overhead is 20 usec (on most systems it
* takes about 1.5 usec for each of the i/o's in getit(). The loop
* takes about 6 usec on a 486/33 and 13 usec on a 386/20. The
* multiplications and divisions to scale the count take a while).
*
* However, if ddb is active then use a fake counter since reading
* the i8254 counter involves acquiring a lock. ddb must not do
* locking for many reasons, but it calls here for at least atkbd
* input.
*/
#ifdef KDB
if (kdb_active)
prev_tick = 1;
else
#endif
prev_tick = getit();
n -= 0; /* XXX actually guess no initial overhead */
/*
* Calculate (n * (timer_freq / 1e6)) without using floating point
* and without any avoidable overflows.
*/
if (n <= 0)
ticks_left = 0;
else if (n < 256)
/*
* Use fixed point to avoid a slow division by 1000000.
* 39099 = 1193182 * 2^15 / 10^6 rounded to nearest.
* 2^15 is the first power of 2 that gives exact results
* for n between 0 and 256.
*/
ticks_left = ((u_int)n * 39099 + (1 << 15) - 1) >> 15;
else
/*
* Don't bother using fixed point, although gcc-2.7.2
* generates particularly poor code for the long long
* division, since even the slow way will complete long
* before the delay is up (unless we're interrupted).
*/
ticks_left = ((u_int)n * (long long)timer_freq + 999999)
/ 1000000;
while (ticks_left > 0) {
#ifdef KDB
if (kdb_active) {
outb(0x5f, 0);
tick = prev_tick - 1;
if (tick <= 0)
tick = timer0_max_count;
} else
#endif
tick = getit();
#ifdef DELAYDEBUG
++getit_calls;
#endif
delta = prev_tick - tick;
prev_tick = tick;
if (delta < 0) {
delta += timer0_max_count;
/*
* Guard against timer0_max_count being wrong.
* This shouldn't happen in normal operation,
* but it may happen if set_timer_freq() is
* traced.
*/
if (delta < 0)
delta = 0;
}
ticks_left -= delta;
}
#ifdef DELAYDEBUG
if (state == 1)
printf(" %d calls to getit() at %d usec each\n",
getit_calls, (n + 5) / getit_calls);
#endif
}
static void
sysbeepstop(void *chan)
{
outb(IO_PPI, inb(IO_PPI)|0x08); /* disable counter1 output to speaker */
release_timer1();
beeping = 0;
}
int
sysbeep(int pitch, int period)
{
int x = splclock();
if (acquire_timer1(TIMER_SQWAVE|TIMER_16BIT))
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) {
/* enable counter1 output to speaker */
outb(IO_PPI, (inb(IO_PPI) & 0xf7));
beeping = period;
timeout(sysbeepstop, (void *)NULL, period);
}
splx(x);
return (0);
}
unsigned int delaycount;
#define FIRST_GUESS 0x2000
static void findcpuspeed(void)
{
int i;
int remainder;
/* Put counter in count down mode */
outb(TIMER_MODE, TIMER_SEL0 | TIMER_16BIT | TIMER_RATEGEN);
outb(TIMER_CNTR0, 0xff);
outb(TIMER_CNTR0, 0xff);
for (i = FIRST_GUESS; i; i--)
;
remainder = getit();
delaycount = (FIRST_GUESS * TIMER_DIV(1000)) / (0xffff - remainder);
}
static u_int
calibrate_clocks(void)
{
int timeout;
u_int count, prev_count, tot_count;
u_short sec, start_sec;
if (bootverbose)
printf("Calibrating clock(s) ... ");
/* Check ARTIC. */
if (!(PC98_SYSTEM_PARAMETER(0x458) & 0x80) &&
!(PC98_SYSTEM_PARAMETER(0x45b) & 0x04))
goto fail;
timeout = 100000000;
/* Read the ARTIC. */
sec = inw(0x5e);
/* Wait for the ARTIC to changes. */
start_sec = sec;
for (;;) {
sec = inw(0x5e);
if (sec != start_sec)
break;
if (--timeout == 0)
goto fail;
}
prev_count = getit();
if (prev_count == 0 || prev_count > timer0_max_count)
goto fail;
tot_count = 0;
start_sec = sec;
for (;;) {
sec = inw(0x5e);
count = getit();
if (count == 0 || count > timer0_max_count)
goto fail;
if (count > prev_count)
tot_count += prev_count - (count - timer0_max_count);
else
tot_count += prev_count - count;
prev_count = count;
if ((sec == start_sec + 1200) || /* 1200 = 307.2KHz >> 8 */
(sec < start_sec &&
(u_int)sec + 0x10000 == (u_int)start_sec + 1200))
break;
if (--timeout == 0)
goto fail;
}
if (bootverbose) {
printf("i8254 clock: %u Hz\n", tot_count);
}
return (tot_count);
fail:
if (bootverbose)
printf("failed, using default i8254 clock of %u Hz\n",
timer_freq);
return (timer_freq);
}
static void
set_timer_freq(u_int freq, int intr_freq)
{
int new_timer0_max_count;
mtx_lock_spin(&clock_lock);
timer_freq = freq;
new_timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq);
if (new_timer0_max_count != timer0_max_count) {
timer0_max_count = new_timer0_max_count;
outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
outb(TIMER_CNTR0, timer0_max_count & 0xff);
outb(TIMER_CNTR0, timer0_max_count >> 8);
}
mtx_unlock_spin(&clock_lock);
}
static void
i8254_restore(void)
{
mtx_lock_spin(&clock_lock);
outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
outb(TIMER_CNTR0, timer0_max_count & 0xff);
outb(TIMER_CNTR0, timer0_max_count >> 8);
mtx_unlock_spin(&clock_lock);
}
/*
* Restore all the timers non-atomically (XXX: should be atomically).
*
* This function is called from pmtimer_resume() to restore all the timers.
* This should not be necessary, but there are broken laptops that do not
* restore all the timers on resume.
*/
void
timer_restore(void)
{
i8254_restore(); /* restore timer_freq and hz */
}
/*
* Initialize 8254 timer 0 early so that it can be used in DELAY().
* XXX initialization of other timers is unintentionally left blank.
*/
void
startrtclock()
{
u_int delta, freq;
findcpuspeed();
if (pc98_machine_type & M_8M)
timer_freq = 1996800L; /* 1.9968 MHz */
else
timer_freq = 2457600L; /* 2.4576 MHz */
set_timer_freq(timer_freq, hz);
freq = calibrate_clocks();
#ifdef CLK_CALIBRATION_LOOP
if (bootverbose) {
printf(
"Press a key on the console to abort clock calibration\n");
while (cncheckc() == -1)
calibrate_clocks();
}
#endif
/*
* Use the calibrated i8254 frequency if it seems reasonable.
* Otherwise use the default, and don't use the calibrated i586
* frequency.
*/
delta = freq > timer_freq ? freq - timer_freq : timer_freq - freq;
if (delta < timer_freq / 100) {
#ifndef CLK_USE_I8254_CALIBRATION
if (bootverbose)
printf(
"CLK_USE_I8254_CALIBRATION not specified - using default frequency\n");
freq = timer_freq;
#endif
timer_freq = freq;
} else {
if (bootverbose)
printf(
"%d Hz differs from default of %d Hz by more than 1%%\n",
freq, timer_freq);
}
set_timer_freq(timer_freq, hz);
i8254_timecounter.tc_frequency = timer_freq;
tc_init(&i8254_timecounter);
init_TSC();
}
static void
rtc_serialcombit(int i)
{
outb(IO_RTC, ((i&0x01)<<5)|0x07);
DELAY(1);
outb(IO_RTC, ((i&0x01)<<5)|0x17);
DELAY(1);
outb(IO_RTC, ((i&0x01)<<5)|0x07);
DELAY(1);
}
static void
rtc_serialcom(int i)
{
rtc_serialcombit(i&0x01);
rtc_serialcombit((i&0x02)>>1);
rtc_serialcombit((i&0x04)>>2);
rtc_serialcombit((i&0x08)>>3);
outb(IO_RTC, 0x07);
DELAY(1);
outb(IO_RTC, 0x0f);
DELAY(1);
outb(IO_RTC, 0x07);
DELAY(1);
}
static void
rtc_outb(int val)
{
int s;
int sa = 0;
for (s=0;s<8;s++) {
sa = ((val >> s) & 0x01) ? 0x27 : 0x07;
outb(IO_RTC, sa); /* set DI & CLK 0 */
DELAY(1);
outb(IO_RTC, sa | 0x10); /* CLK 1 */
DELAY(1);
}
outb(IO_RTC, sa & 0xef); /* CLK 0 */
}
static int
rtc_inb(void)
{
int s;
int sa = 0;
for (s=0;s<8;s++) {
sa |= ((inb(0x33) & 0x01) << s);
outb(IO_RTC, 0x17); /* CLK 1 */
DELAY(1);
outb(IO_RTC, 0x07); /* CLK 0 */
DELAY(2);
}
return sa;
}
/*
* Initialize the time of day register, based on the time base which is, e.g.
* from a filesystem.
*/
void
inittodr(time_t base)
{
unsigned long sec, days;
int year, month;
int y, m, s;
struct timespec ts;
int second, min, hour;
if (base) {
s = splclock();
ts.tv_sec = base;
ts.tv_nsec = 0;
tc_setclock(&ts);
splx(s);
}
rtc_serialcom(0x03); /* Time Read */
rtc_serialcom(0x01); /* Register shift command. */
DELAY(20);
second = bcd2bin(rtc_inb() & 0xff); /* sec */
min = bcd2bin(rtc_inb() & 0xff); /* min */
hour = bcd2bin(rtc_inb() & 0xff); /* hour */
days = bcd2bin(rtc_inb() & 0xff) - 1; /* date */
month = (rtc_inb() >> 4) & 0x0f; /* month */
for (m = 1; m < month; m++)
days += daysinmonth[m-1];
year = bcd2bin(rtc_inb() & 0xff) + 1900; /* year */
/* 2000 year problem */
if (year < 1995)
year += 100;
if (year < 1970)
goto wrong_time;
for (y = 1970; y < year; y++)
days += DAYSPERYEAR + LEAPYEAR(y);
if ((month > 2) && LEAPYEAR(year))
days ++;
sec = ((( days * 24 +
hour) * 60 +
min) * 60 +
second);
/* sec now contains the number of seconds, since Jan 1 1970,
in the local time zone */
s = splhigh();
sec += tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0);
y = time_second - sec;
if (y <= -2 || y >= 2) {
/* badly off, adjust it */
ts.tv_sec = sec;
ts.tv_nsec = 0;
tc_setclock(&ts);
}
splx(s);
return;
wrong_time:
printf("Invalid time in real time clock.\n");
printf("Check and reset the date immediately!\n");
}
/*
* Write system time back to RTC
*/
void
resettodr()
{
unsigned long tm;
int y, m, s;
int wd;
if (disable_rtc_set)
return;
s = splclock();
tm = time_second;
splx(s);
rtc_serialcom(0x01); /* Register shift command. */
/* Calculate local time to put in RTC */
tm -= tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0);
rtc_outb(bin2bcd(tm%60)); tm /= 60; /* Write back Seconds */
rtc_outb(bin2bcd(tm%60)); tm /= 60; /* Write back Minutes */
rtc_outb(bin2bcd(tm%24)); tm /= 24; /* Write back Hours */
/* We have now the days since 01-01-1970 in tm */
wd = (tm + 4) % 7 + 1; /* Write back Weekday */
for (y = 1970, m = DAYSPERYEAR + LEAPYEAR(y);
tm >= m;
y++, m = DAYSPERYEAR + LEAPYEAR(y))
tm -= m;
/* Now we have the years in y and the day-of-the-year in tm */
for (m = 0; ; m++) {
int ml;
ml = daysinmonth[m];
if (m == 1 && LEAPYEAR(y))
ml++;
if (tm < ml)
break;
tm -= ml;
}
m++;
rtc_outb(bin2bcd(tm+1)); /* Write back Day */
rtc_outb((m << 4) | wd); /* Write back Month & Weekday */
rtc_outb(bin2bcd(y%100)); /* Write back Year */
rtc_serialcom(0x02); /* Time set & Counter hold command. */
rtc_serialcom(0x00); /* Register hold command. */
}
/*
* Start both clocks running.
*/
void
cpu_initclocks()
{
#ifdef DEV_APIC
using_lapic_timer = lapic_setup_clock();
#endif
/*
* If we aren't using the local APIC timer to drive the kernel
* clocks, setup the interrupt handler for the 8254 timer 0 so
* that it can drive hardclock().
*/
if (!using_lapic_timer) {
intr_add_handler("clk", 0, (driver_intr_t *)clkintr, NULL,
INTR_TYPE_CLK | INTR_FAST, NULL);
i8254_intsrc = intr_lookup_source(0);
if (i8254_intsrc != NULL)
i8254_pending =
i8254_intsrc->is_pic->pic_source_pending;
}
init_TSC_tc();
}
void
cpu_startprofclock(void)
{
}
void
cpu_stopprofclock(void)
{
}
static int
sysctl_machdep_i8254_freq(SYSCTL_HANDLER_ARGS)
{
int error;
u_int freq;
/*
* Use `i8254' instead of `timer' in external names because `timer'
* is is too generic. Should use it everywhere.
*/
freq = timer_freq;
error = sysctl_handle_int(oidp, &freq, sizeof(freq), req);
if (error == 0 && req->newptr != NULL) {
set_timer_freq(freq, hz);
i8254_timecounter.tc_frequency = freq;
}
return (error);
}
SYSCTL_PROC(_machdep, OID_AUTO, i8254_freq, CTLTYPE_INT | CTLFLAG_RW,
0, sizeof(u_int), sysctl_machdep_i8254_freq, "IU", "");
static unsigned
i8254_get_timecount(struct timecounter *tc)
{
u_int count;
u_int high, low;
u_int eflags;
eflags = read_eflags();
mtx_lock_spin(&clock_lock);
/* Select timer0 and latch counter value. */
outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
low = inb(TIMER_CNTR0);
high = inb(TIMER_CNTR0);
count = timer0_max_count - ((high << 8) | low);
if (count < i8254_lastcount ||
(!i8254_ticked && (clkintr_pending ||
((count < 20 || (!(eflags & PSL_I) && count < timer0_max_count / 2u)) &&
i8254_pending != NULL && i8254_pending(i8254_intsrc))))) {
i8254_ticked = 1;
i8254_offset += timer0_max_count;
}
i8254_lastcount = count;
count += i8254_offset;
mtx_unlock_spin(&clock_lock);
return (count);
}
#ifdef DEV_ISA
/*
* Attach to the ISA PnP descriptors for the timer and realtime clock.
*/
static struct isa_pnp_id attimer_ids[] = {
{ 0x0001d041 /* PNP0100 */, "AT timer" },
{ 0x000bd041 /* PNP0B00 */, "AT realtime clock" },
{ 0 }
};
static int
attimer_probe(device_t dev)
{
int result;
if ((result = ISA_PNP_PROBE(device_get_parent(dev), dev, attimer_ids)) <= 0)
device_quiet(dev);
return(result);
}
static int
attimer_attach(device_t dev)
{
return(0);
}
static device_method_t attimer_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, attimer_probe),
DEVMETHOD(device_attach, attimer_attach),
DEVMETHOD(device_detach, bus_generic_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD(device_suspend, bus_generic_suspend), /* XXX stop statclock? */
DEVMETHOD(device_resume, bus_generic_resume), /* XXX restart statclock? */
{ 0, 0 }
};
static driver_t attimer_driver = {
"attimer",
attimer_methods,
1, /* no softc */
};
static devclass_t attimer_devclass;
DRIVER_MODULE(attimer, isa, attimer_driver, attimer_devclass, 0, 0);
#endif /* DEV_ISA */

File diff suppressed because it is too large Load Diff

View File

@ -1,174 +0,0 @@
/*-
* Copyright (c) 2004 Yoshihiro TAKAHASHI
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer,
* without modification, immediately at the beginning of the file.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/bio.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/rman.h>
#include <sys/systm.h>
#include <machine/bus.h>
#include <pc98/pc98/fdcvar.h>
#include <pc98/pc98/fdreg.h>
#include <isa/isavar.h>
#include <pc98/pc98/pc98.h>
static bus_addr_t fdc_iat[] = {0, 2, 4};
static int
fdc_cbus_alloc_resources(device_t dev, struct fdc_data *fdc)
{
int rid;
fdc->fdc_dev = dev;
fdc->rid_ioport = 0;
fdc->rid_irq = 0;
fdc->rid_drq = 0;
fdc->res_irq = 0;
fdc->res_drq = 0;
fdc->res_ioport = isa_alloc_resourcev(dev, SYS_RES_IOPORT,
&fdc->rid_ioport, fdc_iat,
3, RF_ACTIVE);
if (fdc->res_ioport == 0) {
device_printf(dev, "cannot reserve I/O port range\n");
return ENXIO;
}
isa_load_resourcev(fdc->res_ioport, fdc_iat, 3);
fdc->portt = rman_get_bustag(fdc->res_ioport);
fdc->porth = rman_get_bushandle(fdc->res_ioport);
rid = 3;
bus_set_resource(dev, SYS_RES_IOPORT, rid, IO_FDPORT, 1);
fdc->res_fdsio = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,
RF_ACTIVE);
if (fdc->res_fdsio == 0)
return ENXIO;
fdc->sc_fdsiot = rman_get_bustag(fdc->res_fdsio);
fdc->sc_fdsioh = rman_get_bushandle(fdc->res_fdsio);
rid = 4;
bus_set_resource(dev, SYS_RES_IOPORT, rid, 0x4be, 1);
fdc->res_fdemsio = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,
RF_ACTIVE);
if (fdc->res_fdemsio == 0)
return ENXIO;
fdc->sc_fdemsiot = rman_get_bustag(fdc->res_fdemsio);
fdc->sc_fdemsioh = rman_get_bushandle(fdc->res_fdemsio);
fdc->res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &fdc->rid_irq,
RF_ACTIVE);
if (fdc->res_irq == 0) {
device_printf(dev, "cannot reserve interrupt line\n");
return ENXIO;
}
if ((fdc->flags & FDC_NODMA) == 0) {
fdc->res_drq = bus_alloc_resource_any(dev, SYS_RES_DRQ,
&fdc->rid_drq, RF_ACTIVE);
if (fdc->res_drq == 0) {
device_printf(dev, "cannot reserve DMA request line\n");
return ENXIO;
}
fdc->dmachan = rman_get_start(fdc->res_drq);
}
return 0;
}
static int
fdc_cbus_probe(device_t dev)
{
int error;
struct fdc_data *fdc;
fdc = device_get_softc(dev);
/* Check pnp ids */
if (isa_get_vendorid(dev))
return (ENXIO);
/* Attempt to allocate our resources for the duration of the probe */
error = fdc_cbus_alloc_resources(dev, fdc);
if (!error)
error = fdc_initial_reset(fdc);
fdc_release_resources(fdc);
return (error);
}
static int
fdc_cbus_attach(device_t dev)
{
struct fdc_data *fdc;
int error;
fdc = device_get_softc(dev);
if ((error = fdc_cbus_alloc_resources(dev, fdc)) != 0 ||
(error = fdc_attach(dev)) != 0 ||
(error = fdc_hints_probe(dev)) != 0) {
fdc_release_resources(fdc);
return (error);
}
return (0);
}
static device_method_t fdc_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, fdc_cbus_probe),
DEVMETHOD(device_attach, fdc_cbus_attach),
DEVMETHOD(device_detach, fdc_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, bus_generic_resume),
/* Bus interface */
DEVMETHOD(bus_print_child, fdc_print_child),
DEVMETHOD(bus_read_ivar, fdc_read_ivar),
DEVMETHOD(bus_write_ivar, fdc_write_ivar),
/* Our children never use any other bus interface methods. */
{ 0, 0 }
};
static driver_t fdc_driver = {
"fdc",
fdc_methods,
sizeof(struct fdc_data)
};
DRIVER_MODULE(fdc, isa, fdc_driver, fdc_devclass, 0, 0);

View File

@ -1,167 +0,0 @@
/*-
* Copyright (c) 2004 M. Warner Losh.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer,
* without modification, immediately at the beginning of the file.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
/* XXX should audit this file to see if additional copyrights needed */
enum fdc_type
{
FDC_NE765, FDC_ENHANCED, FDC_UNKNOWN = -1
};
enum fdc_states {
DEVIDLE,
FINDWORK,
DOSEEK,
SEEKCOMPLETE ,
IOCOMPLETE,
RECALCOMPLETE,
STARTRECAL,
RESETCTLR,
SEEKWAIT,
RECALWAIT,
MOTORWAIT,
IOTIMEDOUT,
RESETCOMPLETE,
PIOREAD
};
#ifdef FDC_DEBUG
static char const * const fdstates[] = {
"DEVIDLE",
"FINDWORK",
"DOSEEK",
"SEEKCOMPLETE",
"IOCOMPLETE",
"RECALCOMPLETE",
"STARTRECAL",
"RESETCTLR",
"SEEKWAIT",
"RECALWAIT",
"MOTORWAIT",
"IOTIMEDOUT",
"RESETCOMPLETE",
"PIOREAD"
};
#endif
/*
* Per controller structure (softc).
*/
struct fdc_data
{
int fdcu; /* our unit number */
int dmacnt;
int dmachan;
int flags;
#define FDC_STAT_VALID 0x08
#define FDC_HAS_FIFO 0x10
#define FDC_NEEDS_RESET 0x20
#define FDC_NODMA 0x40
#define FDC_ISPNP 0x80
#define FDC_ISPCMCIA 0x100
struct fd_data *fd;
int fdu; /* the active drive */
enum fdc_states state;
int retry;
#ifndef PC98
int fdout; /* mirror of the w/o digital output reg */
#endif
u_int status[7]; /* copy of the registers */
enum fdc_type fdct; /* chip version of FDC */
int fdc_errs; /* number of logged errors */
int dma_overruns; /* number of DMA overruns */
struct bio_queue_head head;
struct bio *bp; /* active buffer */
#ifdef PC98
struct resource *res_ioport, *res_fdsio, *res_fdemsio;
struct resource *res_irq, *res_drq;
int rid_ioport, rid_irq, rid_drq;
#else
struct resource *res_ioport, *res_ctl, *res_irq, *res_drq;
int rid_ioport, rid_ctl, rid_irq, rid_drq;
#endif
int port_off;
bus_space_tag_t portt;
bus_space_handle_t porth;
#ifdef PC98
bus_space_tag_t sc_fdsiot;
bus_space_handle_t sc_fdsioh;
bus_space_tag_t sc_fdemsiot;
bus_space_handle_t sc_fdemsioh;
#else
bus_space_tag_t ctlt;
bus_space_handle_t ctlh;
#endif
void *fdc_intr;
struct device *fdc_dev;
#ifndef PC98
void (*fdctl_wr)(struct fdc_data *fdc, u_int8_t v);
#endif
};
typedef int fdu_t;
typedef int fdcu_t;
typedef int fdsu_t;
typedef struct fd_data *fd_p;
typedef struct fdc_data *fdc_p;
typedef enum fdc_type fdc_t;
/* error returns for fd_cmd() */
#define FD_FAILED -1
#define FD_NOT_VALID -2
#define FDC_ERRMAX 100 /* do not log more */
extern devclass_t fdc_devclass;
enum fdc_device_ivars {
FDC_IVAR_FDUNIT,
FDC_IVAR_FDTYPE,
};
__BUS_ACCESSOR(fdc, fdunit, FDC, FDUNIT, int);
__BUS_ACCESSOR(fdc, fdtype, FDC, FDTYPE, int);
int fdc_alloc_resources(struct fdc_data *);
#ifndef PC98
void fdout_wr(fdc_p, u_int8_t);
#endif
int fd_cmd(struct fdc_data *, int, ...);
void fdc_release_resources(struct fdc_data *);
int fdc_attach(device_t);
int fdc_hints_probe(device_t);
int fdc_detach(device_t dev);
device_t fdc_add_child(device_t, const char *, int);
int fdc_initial_reset(struct fdc_data *);
int fdc_print_child(device_t, device_t);
int fdc_read_ivar(device_t, device_t, int, uintptr_t *);
int fdc_write_ivar(device_t, device_t, int, uintptr_t);
#ifndef PC98
int fdc_isa_alloc_resources(device_t, struct fdc_data *);
#endif

View File

@ -1,88 +0,0 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)fdreg.h 7.1 (Berkeley) 5/9/91
* $FreeBSD$
*/
/*
* AT floppy controller registers and bitfields
*/
/* uses NEC765 controller */
#include <dev/ic/nec765.h>
#ifdef PC98
/* registers */
#define FDSTS 0 /* NEC 765 Main Status Register (R) */
#define FDDATA 1 /* NEC 765 Data Register (R/W) */
#define FDCTL 2 /* FD Control Register */
#define FDC_RST 0x80 /* FDC RESET */
#define FDC_RDY 0x40 /* force READY */
#define FDC_DD 0x20 /* FDD Mode Exchange 0:1M 1:640K */
#define FDC_DMAE 0x10 /* enable floppy DMA */
#define FDC_MTON 0x08 /* MOTOR ON (when EMTON=1)*/
#define FDC_TMSK 0x04 /* TIMER MASK */
#define FDC_TTRG 0x01 /* TIMER TRIGER */
#define FDP_EMTON 0x04 /* enable MTON */
#define FDP_FDDEXC 0x02 /* FDD Mode Exchange 1:1M 0:640K */
#define FDP_PORTEXC 0x01 /* PORT Exchane 1:1M 0:640K */
#else
/* registers */
#define FDOUT 2 /* Digital Output Register (W) */
#define FDO_FDSEL 0x03 /* floppy device select */
#define FDO_FRST 0x04 /* floppy controller reset */
#define FDO_FDMAEN 0x08 /* enable floppy DMA and Interrupt */
#define FDO_MOEN0 0x10 /* motor enable drive 0 */
#define FDO_MOEN1 0x20 /* motor enable drive 1 */
#define FDO_MOEN2 0x40 /* motor enable drive 2 */
#define FDO_MOEN3 0x80 /* motor enable drive 3 */
#define FDSTS 4 /* NEC 765 Main Status Register (R) */
#define FDDATA 5 /* NEC 765 Data Register (R/W) */
#define FDCTL 7 /* Control Register (W) */
#endif /* PC98 */
/*
* The definitions for FDC_500KBPS etc. have been moved out to <sys/fdcio.h>
* since they need to be visible in userland. They cover the lower two bits
* of FDCTL when used for output.
*/
/*
* this is the secret PIO data port (offset from base)
*/
#define FDC_YE_DATAPORT 6
#ifndef PC98
#define FDIN 7 /* Digital Input Register (R) */
#define FDI_DCHG 0x80 /* diskette has been changed */
/* requires drive and motor being selected */
/* is cleared by any step pulse to drive */
#endif

View File

@ -1,497 +0,0 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* William Jolitz.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)isa.c 7.2 (Berkeley) 5/13/91
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*
* code to manage AT bus
*
* 92/08/18 Frank P. MacLachlan (fpm@crash.cts.com):
* Fixed uninitialized variable problem and added code to deal
* with DMA page boundaries in isa_dmarangecheck(). Fixed word
* mode DMA count compution and reorganized DMA setup code in
* isa_dmastart()
*/
#include "opt_pc98.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/lock.h>
#include <sys/proc.h>
#include <sys/mutex.h>
#include <sys/module.h>
#include <machine/md_var.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/pmap.h>
#include <pc98/pc98/pc98.h>
#include <dev/ic/i8237.h>
#include <isa/isavar.h>
/*
** Register definitions for DMA controller 1 (channels 0..3):
*/
#define DMA1_CHN(c) (IO_DMA + (4*(c))) /* addr reg for channel c */
#define DMA1_STATUS (IO_DMA + 0x10) /* status register */
#define DMA1_SMSK (IO_DMA + 0x14) /* single mask register */
#define DMA1_MODE (IO_DMA + 0x16) /* mode register */
#define DMA1_FFC (IO_DMA + 0x18) /* clear first/last FF */
static int isa_dmarangecheck(caddr_t va, u_int length, int chan);
static caddr_t dma_bouncebuf[4];
static u_int dma_bouncebufsize[4];
static u_int8_t dma_bounced = 0;
static u_int8_t dma_busy = 0; /* Used in isa_dmastart() */
static u_int8_t dma_inuse = 0; /* User for acquire/release */
static u_int8_t dma_auto_mode = 0;
#define VALID_DMA_MASK (3)
/* high byte of address is stored in this port for i-th dma channel */
static int dmapageport[4] = { 0x27, 0x21, 0x23, 0x25 };
/*
* Setup a DMA channel's bounce buffer.
*/
int
isa_dma_init(int chan, u_int bouncebufsize, int flag)
{
void *buf;
#ifdef DIAGNOSTIC
if (chan & ~VALID_DMA_MASK)
panic("isa_dma_init: channel out of range");
if (dma_bouncebuf[chan] != NULL)
panic("isa_dma_init: impossible request");
#endif
dma_bouncebufsize[chan] = bouncebufsize;
/* Try malloc() first. It works better if it works. */
buf = malloc(bouncebufsize, M_DEVBUF, flag);
if (buf != NULL) {
if (isa_dmarangecheck(buf, bouncebufsize, chan) == 0) {
dma_bouncebuf[chan] = buf;
return (0);
}
free(buf, M_DEVBUF);
}
buf = contigmalloc(bouncebufsize, M_DEVBUF, flag, 0ul, 0xfffffful,
1ul, chan & 4 ? 0x20000ul : 0x10000ul);
if (buf == NULL)
return (ENOMEM);
dma_bouncebuf[chan] = buf;
return (0);
}
/*
* Register a DMA channel's usage. Usually called from a device driver
* in open() or during its initialization.
*/
int
isa_dma_acquire(chan)
int chan;
{
#ifdef DIAGNOSTIC
if (chan & ~VALID_DMA_MASK)
panic("isa_dma_acquire: channel out of range");
#endif
if (dma_inuse & (1 << chan)) {
printf("isa_dma_acquire: channel %d already in use\n", chan);
return (EBUSY);
}
dma_inuse |= (1 << chan);
dma_auto_mode &= ~(1 << chan);
return (0);
}
/*
* Unregister a DMA channel's usage. Usually called from a device driver
* during close() or during its shutdown.
*/
void
isa_dma_release(chan)
int chan;
{
#ifdef DIAGNOSTIC
if (chan & ~VALID_DMA_MASK)
panic("isa_dma_release: channel out of range");
if ((dma_inuse & (1 << chan)) == 0)
printf("isa_dma_release: channel %d not in use\n", chan);
#endif
if (dma_busy & (1 << chan)) {
dma_busy &= ~(1 << chan);
/*
* XXX We should also do "dma_bounced &= (1 << chan);"
* because we are acting on behalf of isa_dmadone() which
* was not called to end the last DMA operation. This does
* not matter now, but it may in the future.
*/
}
dma_inuse &= ~(1 << chan);
dma_auto_mode &= ~(1 << chan);
}
/*
* isa_dmastart(): program 8237 DMA controller channel, avoid page alignment
* problems by using a bounce buffer.
*/
void
isa_dmastart(int flags, caddr_t addr, u_int nbytes, int chan)
{
vm_paddr_t phys;
int waport;
caddr_t newaddr;
GIANT_REQUIRED;
#ifdef DIAGNOSTIC
if (chan & ~VALID_DMA_MASK)
panic("isa_dmastart: channel out of range");
if ((chan < 4 && nbytes > (1<<16))
|| (chan >= 4 && (nbytes > (1<<17) || (u_int)addr & 1)))
panic("isa_dmastart: impossible request");
if ((dma_inuse & (1 << chan)) == 0)
printf("isa_dmastart: channel %d not acquired\n", chan);
#endif
#if 0
/*
* XXX This should be checked, but drivers like ad1848 only call
* isa_dmastart() once because they use Auto DMA mode. If we
* leave this in, drivers that do this will print this continuously.
*/
if (dma_busy & (1 << chan))
printf("isa_dmastart: channel %d busy\n", chan);
#endif
dma_busy |= (1 << chan);
if (isa_dmarangecheck(addr, nbytes, chan)) {
if (dma_bouncebuf[chan] == NULL
|| dma_bouncebufsize[chan] < nbytes)
panic("isa_dmastart: bad bounce buffer");
dma_bounced |= (1 << chan);
newaddr = dma_bouncebuf[chan];
/* copy bounce buffer on write */
if (!(flags & ISADMA_READ))
bcopy(addr, newaddr, nbytes);
addr = newaddr;
}
/* translate to physical */
phys = pmap_extract(kernel_pmap, (vm_offset_t)addr);
if (flags & ISADMA_RAW) {
dma_auto_mode |= (1 << chan);
} else {
dma_auto_mode &= ~(1 << chan);
}
if (need_pre_dma_flush)
wbinvd(); /* wbinvd (WB cache flush) */
/* set dma channel mode, and reset address ff */
/* If ISADMA_RAW flag is set, then use autoinitialise mode */
if (flags & ISADMA_RAW) {
if (flags & ISADMA_READ)
outb(DMA1_MODE, DMA37MD_AUTO|DMA37MD_WRITE|chan);
else
outb(DMA1_MODE, DMA37MD_AUTO|DMA37MD_READ|chan);
} else {
if (flags & ISADMA_READ)
outb(DMA1_MODE, DMA37MD_SINGLE|DMA37MD_WRITE|chan);
else
outb(DMA1_MODE, DMA37MD_SINGLE|DMA37MD_READ|chan);
}
outb(DMA1_FFC, 0);
/* send start address */
waport = DMA1_CHN(chan);
outb(waport, phys);
outb(waport, phys>>8);
outb(dmapageport[chan], phys>>16);
/* send count */
outb(waport + 2, --nbytes);
outb(waport + 2, nbytes>>8);
/* unmask channel */
outb(DMA1_SMSK, chan);
}
void
isa_dmadone(int flags, caddr_t addr, int nbytes, int chan)
{
if (flags & ISADMA_READ) {
/* cache flush only after reading 92/12/9 by A.Kojima */
if (need_post_dma_flush)
invd();
}
#ifdef DIAGNOSTIC
if (chan & ~VALID_DMA_MASK)
panic("isa_dmadone: channel out of range");
if ((dma_inuse & (1 << chan)) == 0)
printf("isa_dmadone: channel %d not acquired\n", chan);
#endif
if (((dma_busy & (1 << chan)) == 0) &&
(dma_auto_mode & (1 << chan)) == 0 )
printf("isa_dmadone: channel %d not busy\n", chan);
if ((dma_auto_mode & (1 << chan)) == 0)
outb(DMA1_SMSK, (chan & 3) | 4);
if (dma_bounced & (1 << chan)) {
/* copy bounce buffer on read */
if (flags & ISADMA_READ)
bcopy(dma_bouncebuf[chan], addr, nbytes);
dma_bounced &= ~(1 << chan);
}
dma_busy &= ~(1 << chan);
}
/*
* Check for problems with the address range of a DMA transfer
* (non-contiguous physical pages, outside of bus address space,
* crossing DMA page boundaries).
* Return true if special handling needed.
*/
static int
isa_dmarangecheck(caddr_t va, u_int length, int chan)
{
vm_paddr_t phys, priorpage = 0;
vm_offset_t endva;
u_int dma_pgmsk = (chan & 4) ? ~(128*1024-1) : ~(64*1024-1);
GIANT_REQUIRED;
endva = (vm_offset_t)round_page((vm_offset_t)va + length);
for (; va < (caddr_t) endva ; va += PAGE_SIZE) {
phys = trunc_page(pmap_extract(kernel_pmap, (vm_offset_t)va));
#ifdef EPSON_BOUNCEDMA
#define ISARAM_END 0xf00000
#else
#define ISARAM_END RAM_END
#endif
if (phys == 0)
panic("isa_dmacheck: no physical page present");
if (phys >= ISARAM_END)
return (1);
if (priorpage) {
if (priorpage + PAGE_SIZE != phys)
return (1);
/* check if crossing a DMA page boundary */
if (((u_int)priorpage ^ (u_int)phys) & dma_pgmsk)
return (1);
}
priorpage = phys;
}
return (0);
}
/*
* Query the progress of a transfer on a DMA channel.
*
* To avoid having to interrupt a transfer in progress, we sample
* each of the high and low databytes twice, and apply the following
* logic to determine the correct count.
*
* Reads are performed with interrupts disabled, thus it is to be
* expected that the time between reads is very small. At most
* one rollover in the low count byte can be expected within the
* four reads that are performed.
*
* There are three gaps in which a rollover can occur :
*
* - read low1
* gap1
* - read high1
* gap2
* - read low2
* gap3
* - read high2
*
* If a rollover occurs in gap1 or gap2, the low2 value will be
* greater than the low1 value. In this case, low2 and high2 are a
* corresponding pair.
*
* In any other case, low1 and high1 can be considered to be correct.
*
* The function returns the number of bytes remaining in the transfer,
* or -1 if the channel requested is not active.
*
*/
int
isa_dmastatus(int chan)
{
u_long cnt = 0;
int ffport, waport;
u_long low1, high1, low2, high2;
/* channel active? */
if ((dma_inuse & (1 << chan)) == 0) {
printf("isa_dmastatus: channel %d not active\n", chan);
return(-1);
}
/* channel busy? */
if (((dma_busy & (1 << chan)) == 0) &&
(dma_auto_mode & (1 << chan)) == 0 ) {
printf("chan %d not busy\n", chan);
return -2 ;
}
ffport = DMA1_FFC;
waport = DMA1_CHN(chan) + 2;
disable_intr(); /* no interrupts Mr Jones! */
outb(ffport, 0); /* clear register LSB flipflop */
low1 = inb(waport);
high1 = inb(waport);
outb(ffport, 0); /* clear again */
low2 = inb(waport);
high2 = inb(waport);
enable_intr(); /* enable interrupts again */
/*
* Now decide if a wrap has tried to skew our results.
* Note that after TC, the count will read 0xffff, while we want
* to return zero, so we add and then mask to compensate.
*/
if (low1 >= low2) {
cnt = (low1 + (high1 << 8) + 1) & 0xffff;
} else {
cnt = (low2 + (high2 << 8) + 1) & 0xffff;
}
if (chan >= 4) /* high channels move words */
cnt *= 2;
return(cnt);
}
/*
* Reached terminal count yet ?
*/
int
isa_dmatc(int chan)
{
return(inb(DMA1_STATUS) & (1 << chan));
}
/*
* Stop a DMA transfer currently in progress.
*/
int
isa_dmastop(int chan)
{
if ((dma_inuse & (1 << chan)) == 0)
printf("isa_dmastop: channel %d not acquired\n", chan);
if (((dma_busy & (1 << chan)) == 0) &&
((dma_auto_mode & (1 << chan)) == 0)) {
printf("chan %d not busy\n", chan);
return -2 ;
}
if ((chan & 4) == 0)
outb(DMA1_SMSK, (chan & 3) | 4 /* disable mask */);
return(isa_dmastatus(chan));
}
/*
* Attach to the ISA PnP descriptor for the AT DMA controller
*/
static struct isa_pnp_id atdma_ids[] = {
{ 0x0002d041 /* PNP0200 */, "AT DMA controller" },
{ 0 }
};
static int
atdma_probe(device_t dev)
{
int result;
if ((result = ISA_PNP_PROBE(device_get_parent(dev), dev, atdma_ids)) <= 0)
device_quiet(dev);
return(result);
}
static int
atdma_attach(device_t dev)
{
return(0);
}
static device_method_t atdma_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, atdma_probe),
DEVMETHOD(device_attach, atdma_attach),
DEVMETHOD(device_detach, bus_generic_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, bus_generic_resume),
{ 0, 0 }
};
static driver_t atdma_driver = {
"atdma",
atdma_methods,
1, /* no softc */
};
static devclass_t atdma_devclass;
DRIVER_MODULE(atdma, isa, atdma_driver, atdma_devclass, 0, 0);

View File

@ -103,7 +103,7 @@ __FBSDID("$FreeBSD$");
#endif
#include <pc98/pc98/pc98_machdep.h>
#include <pc98/pc98/pc98.h>
#include <pc98/cbus/cbus.h>
#include <net/netisr.h>

View File

@ -1,74 +0,0 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* William Jolitz.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)isa.c 7.2 (Berkeley) 5/13/91
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/syslog.h>
#include <sys/systm.h>
#include <machine/md_var.h>
#include <pc98/pc98/epsonio.h>
#include <pc98/pc98/pc98_machdep.h>
#define NMI_PARITY 0x04
#define NMI_EPARITY 0x02
/*
* Handle a NMI, possibly a machine check.
* return true to panic system, false to ignore.
*/
int
isa_nmi(int cd)
{
int retval = 0;
int port = inb(0x33);
log(LOG_CRIT, "NMI PC98 port = %x\n", port);
if (epson_machine_id == 0x20)
epson_outb(0xc16, epson_inb(0xc16) | 0x1);
if (port & NMI_PARITY) {
log(LOG_CRIT, "BASE RAM parity error, likely hardware failure.");
retval = 1;
} else if (port & NMI_EPARITY) {
log(LOG_CRIT, "EXTENDED RAM parity error, likely hardware failure.");
retval = 1;
} else {
log(LOG_CRIT, "\nNMI Resume ??\n");
}
return(retval);
}

View File

@ -1,653 +0,0 @@
/*-
* Copyright (c) 1990 William F. Jolitz, TeleMuse
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This software is a component of "386BSD" developed by
* William F. Jolitz, TeleMuse.
* 4. Neither the name of the developer nor the name "386BSD"
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS A COMPONENT OF 386BSD DEVELOPED BY WILLIAM F. JOLITZ
* AND IS INTENDED FOR RESEARCH AND EDUCATIONAL PURPOSES ONLY. THIS
* SOFTWARE SHOULD NOT BE CONSIDERED TO BE A COMMERCIAL PRODUCT.
* THE DEVELOPER URGES THAT USERS WHO REQUIRE A COMMERCIAL PRODUCT
* NOT MAKE USE OF THIS WORK.
*
* FOR USERS WHO WISH TO UNDERSTAND THE 386BSD SYSTEM DEVELOPED
* BY WILLIAM F. JOLITZ, WE RECOMMEND THE USER STUDY WRITTEN
* REFERENCES SUCH AS THE "PORTING UNIX TO THE 386" SERIES
* (BEGINNING JANUARY 1991 "DR. DOBBS JOURNAL", USA AND BEGINNING
* JUNE 1991 "UNIX MAGAZIN", GERMANY) BY WILLIAM F. JOLITZ AND
* LYNNE GREER JOLITZ, AS WELL AS OTHER BOOKS ON UNIX AND THE
* ON-LINE 386BSD USER MANUAL BEFORE USE. A BOOK DISCUSSING THE INTERNALS
* OF 386BSD ENTITLED "386BSD FROM THE INSIDE OUT" WILL BE AVAILABLE LATE 1992.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE DEVELOPER BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: unknown origin, 386BSD 0.1
* $FreeBSD$
*/
/*
* Device Driver for AT parallel printer port
* Written by William Jolitz 12/18/90
*/
/*
* Parallel port TCP/IP interfaces added. I looked at the driver from
* MACH but this is a complete rewrite, and btw. incompatible, and it
* should perform better too. I have never run the MACH driver though.
*
* This driver sends two bytes (0x08, 0x00) in front of each packet,
* to allow us to distinguish another format later.
*
* Now added a Linux/Crynwr compatibility mode which is enabled using
* IF_LINK0 - Tim Wilkinson.
*
* TODO:
* Make HDLC/PPP mode, use IF_LLC1 to enable.
*
* Connect the two computers using a Laplink parallel cable to use this
* feature:
*
* +----------------------------------------+
* |A-name A-End B-End Descr. Port/Bit |
* +----------------------------------------+
* |DATA0 2 15 Data 0/0x01 |
* |-ERROR 15 2 1/0x08 |
* +----------------------------------------+
* |DATA1 3 13 Data 0/0x02 |
* |+SLCT 13 3 1/0x10 |
* +----------------------------------------+
* |DATA2 4 12 Data 0/0x04 |
* |+PE 12 4 1/0x20 |
* +----------------------------------------+
* |DATA3 5 10 Strobe 0/0x08 |
* |-ACK 10 5 1/0x40 |
* +----------------------------------------+
* |DATA4 6 11 Data 0/0x10 |
* |BUSY 11 6 1/~0x80 |
* +----------------------------------------+
* |GND 18-25 18-25 GND - |
* +----------------------------------------+
*
* Expect transfer-rates up to 75 kbyte/sec.
*
* If GCC could correctly grok
* register int port asm("edx")
* the code would be cleaner
*
* Poul-Henning Kamp <phk@freebsd.org>
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/conf.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/uio.h>
#include <sys/syslog.h>
#include <sys/malloc.h>
#include <machine/clock.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/rman.h>
#include <isa/isavar.h>
#include <i386/isa/lptreg.h>
#include <dev/ppbus/lptio.h>
#define LPINITRDY 4 /* wait up to 4 seconds for a ready */
#define LPTOUTINITIAL 10 /* initial timeout to wait for ready 1/10 s */
#define LPTOUTMAX 1 /* maximal timeout 1 s */
#define LPPRI (PZERO+8)
#define BUFSIZE 1024
#ifndef DEBUG
#define lprintf(args)
#else
#define lprintf(args) do { \
if (lptflag) \
printf args; \
} while (0)
static int volatile lptflag = 1;
#endif
#define LPTUNIT(s) ((s)&0x03)
#define LPTFLAGS(s) ((s)&0xfc)
struct lpt_softc {
struct resource *res_port;
struct resource *res_irq;
void *sc_ih;
int sc_port;
short sc_state;
/* default case: negative prime, negative ack, handshake strobe,
prime once */
u_char sc_control;
char sc_flags;
#define LP_POS_INIT 0x04 /* if we are a postive init signal */
#define LP_POS_ACK 0x08 /* if we are a positive going ack */
#define LP_NO_PRIME 0x10 /* don't prime the printer at all */
#define LP_PRIMEOPEN 0x20 /* prime on every open */
#define LP_AUTOLF 0x40 /* tell printer to do an automatic lf */
#define LP_BYPASS 0x80 /* bypass printer ready checks */
void *sc_inbuf;
short sc_xfercnt ;
char sc_primed;
char *sc_cp ;
u_char sc_irq ; /* IRQ status of port */
#define LP_HAS_IRQ 0x01 /* we have an irq available */
#define LP_USE_IRQ 0x02 /* we are using our irq */
#define LP_ENABLE_IRQ 0x04 /* enable IRQ on open */
u_char sc_backoff ; /* time to call lptout() again */
};
/* bits for state */
#define OPEN (1<<0) /* device is open */
#define ASLP (1<<1) /* awaiting draining of printer */
#define ERROR (1<<2) /* error was received from printer */
#define OBUSY (1<<3) /* printer is busy doing output */
#define LPTOUT (1<<4) /* timeout while not selected */
#define TOUT (1<<5) /* timeout while not selected */
#define INIT (1<<6) /* waiting to initialize for open */
#define INTERRUPTED (1<<7) /* write call was interrupted */
/* status masks to interrogate printer status */
#define RDY_MASK (LPS_SEL|LPS_OUT|LPS_NBSY|LPS_NERR) /* ready ? */
#define LP_READY (LPS_SEL|LPS_NBSY|LPS_NERR)
/* Printer Ready condition - from lpa.c */
/* Only used in polling code */
#define NOT_READY(x) ((inb(x) & LPS_NBSY) != LPS_NBSY)
#define MAX_SLEEP (hz*5) /* Timeout while waiting for device ready */
#define MAX_SPIN 20 /* Max delay for device ready in usecs */
static timeout_t lptout;
static int lpt_probe(device_t);
static int lpt_attach(device_t);
static void lpt_intr(void *);
static devclass_t olpt_devclass;
static device_method_t olpt_methods[] = {
DEVMETHOD(device_probe, lpt_probe),
DEVMETHOD(device_attach, lpt_attach),
{ 0, 0 }
};
static driver_t olpt_driver = {
"olpt",
olpt_methods,
sizeof (struct lpt_softc),
};
DRIVER_MODULE(olpt, isa, olpt_driver, olpt_devclass, 0, 0);
static d_open_t lptopen;
static d_close_t lptclose;
static d_write_t lptwrite;
static d_ioctl_t lptioctl;
static struct cdevsw lpt_cdevsw = {
.d_version = D_VERSION,
.d_flags = D_NEEDGIANT,
.d_open = lptopen,
.d_close = lptclose,
.d_write = lptwrite,
.d_ioctl = lptioctl,
.d_name = "lpt",
};
static bus_addr_t lpt_iat[] = {0, 2, 4, 6};
/*
* New lpt port probe Geoff Rehmet - Rhodes University - 14/2/94
* Based partially on Rod Grimes' printer probe
*
* Logic:
* 1) If no port address was given, use the bios detected ports
* and autodetect what ports the printers are on.
* 2) Otherwise, probe the data port at the address given,
* using the method in Rod Grimes' port probe.
* (Much code ripped off directly from Rod's probe.)
*
* Comments from Rod's probe:
* Logic:
* 1) You should be able to write to and read back the same value
* to the data port. Do an alternating zeros, alternating ones,
* walking zero, and walking one test to check for stuck bits.
*
* 2) You should be able to write to and read back the same value
* to the control port lower 5 bits, the upper 3 bits are reserved
* per the IBM PC technical reference manauls and different boards
* do different things with them. Do an alternating zeros, alternating
* ones, walking zero, and walking one test to check for stuck bits.
*
* Some printers drag the strobe line down when the are powered off
* so this bit has been masked out of the control port test.
*
* XXX Some printers may not like a fast pulse on init or strobe, I
* don't know at this point, if that becomes a problem these bits
* should be turned off in the mask byte for the control port test.
*
* We are finally left with a mask of 0x14, due to some printers
* being adamant about holding other bits high ........
*
* Before probing the control port, we write a 0 to the data port -
* If not, some printers chuck out garbage when the strobe line
* gets toggled.
*
* 3) Set the data and control ports to a value of 0
*
* This probe routine has been tested on Epson Lx-800, HP LJ3P,
* Epson FX-1170 and C.Itoh 8510RM
* printers.
* Quick exit on fail added.
*/
int
lpt_probe(device_t dev)
{
#define PC98_OLD_LPT 0x40
#define PC98_IEEE_1284_FUNCTION 0x149
int rid;
struct resource *res;
/* Check isapnp ids */
if (isa_get_vendorid(dev))
return ENXIO;
rid = 0;
res = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid, lpt_iat, 4,
RF_ACTIVE);
if (res == NULL)
return ENXIO;
isa_load_resourcev(res, lpt_iat, 4);
if (isa_get_port(dev) == PC98_OLD_LPT) {
unsigned int pc98_ieee_mode, tmp;
tmp = inb(PC98_IEEE_1284_FUNCTION);
pc98_ieee_mode = tmp;
if ((tmp & 0x10) == 0x10) {
outb(PC98_IEEE_1284_FUNCTION, tmp & ~0x10);
tmp = inb(PC98_IEEE_1284_FUNCTION);
if ((tmp & 0x10) != 0x10) {
outb(PC98_IEEE_1284_FUNCTION, pc98_ieee_mode);
bus_release_resource(dev, SYS_RES_IOPORT, rid,
res);
return ENXIO;
}
}
}
bus_release_resource(dev, SYS_RES_IOPORT, rid, res);
return 0;
}
/* XXX Todo - try and detect if interrupt is working */
int
lpt_attach(device_t dev)
{
int rid, unit;
struct lpt_softc *sc;
unit = device_get_unit(dev);
sc = device_get_softc(dev);
rid = 0;
sc->res_port = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid,
lpt_iat, 4, RF_ACTIVE);
if (sc->res_port == NULL)
return ENXIO;
isa_load_resourcev(sc->res_port, lpt_iat, 4);
sc->sc_port = rman_get_start(sc->res_port);
sc->sc_primed = 0; /* not primed yet */
outb(sc->sc_port+lpt_pstb_ctrl, LPC_DIS_PSTB); /* PSTB disable */
outb(sc->sc_port+lpt_control, LPC_MODE8255); /* 8255 mode set */
outb(sc->sc_port+lpt_control, LPC_NIRQ8); /* IRQ8 inactive */
outb(sc->sc_port+lpt_control, LPC_NPSTB); /* PSTB inactive */
outb(sc->sc_port+lpt_pstb_ctrl, LPC_EN_PSTB); /* PSTB enable */
sc->sc_irq = 0;
if (isa_get_irq(dev) != -1) {
rid = 0;
sc->res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_ACTIVE);
if (sc->res_irq == NULL) {
bus_release_resource(dev, SYS_RES_IOPORT, 0,
sc->res_port);
return ENXIO;
}
if (bus_setup_intr(dev, sc->res_irq, INTR_TYPE_TTY, lpt_intr,
sc, &sc->sc_ih)) {
bus_release_resource(dev, SYS_RES_IOPORT, 0,
sc->res_port);
bus_release_resource(dev, SYS_RES_IRQ, 0,
sc->res_irq);
return ENXIO;
}
sc->sc_irq = LP_HAS_IRQ | LP_USE_IRQ | LP_ENABLE_IRQ;
device_printf(dev, "Interrupt-driven port");
}
/* XXX what to do about the flags in the minor number? */
make_dev(&lpt_cdevsw, unit, UID_ROOT, GID_WHEEL, 0600, "lpt%d", unit);
make_dev(&lpt_cdevsw, unit | LP_BYPASS,
UID_ROOT, GID_WHEEL, 0600, "lpctl%d", unit);
return 0;
}
/*
* lptopen -- reset the printer, then wait until it's selected and not busy.
* If LP_BYPASS flag is selected, then we do not try to select the
* printer -- this is just used for passing ioctls.
*/
static int
lptopen (struct cdev *dev, int flags, int fmt, struct thread *td)
{
struct lpt_softc *sc;
int s;
int port;
sc = devclass_get_softc(olpt_devclass, LPTUNIT(minor(dev)));
if (sc->sc_port == 0)
return (ENXIO);
if (sc->sc_state) {
lprintf(("lp: still open %x\n", sc->sc_state));
return(EBUSY);
} else
sc->sc_state |= INIT;
sc->sc_flags = LPTFLAGS(minor(dev));
/* Check for open with BYPASS flag set. */
if (sc->sc_flags & LP_BYPASS) {
sc->sc_state = OPEN;
return(0);
}
s = spltty();
lprintf(("lp flags 0x%x\n", sc->sc_flags));
port = sc->sc_port;
/* set IRQ status according to ENABLE_IRQ flag */
if (sc->sc_irq & LP_ENABLE_IRQ)
sc->sc_irq |= LP_USE_IRQ;
else
sc->sc_irq &= ~LP_USE_IRQ;
/* init printer */
sc->sc_state = OPEN;
sc->sc_inbuf = malloc(BUFSIZE, M_DEVBUF, M_WAITOK);
sc->sc_xfercnt = 0;
splx(s);
/* only use timeout if using interrupt */
lprintf(("irq %x\n", sc->sc_irq));
if (sc->sc_irq & LP_USE_IRQ) {
sc->sc_state |= TOUT;
timeout (lptout, (caddr_t)sc,
(sc->sc_backoff = hz/LPTOUTINITIAL));
}
lprintf(("opened.\n"));
return(0);
}
static void
lptout (void *arg)
{
struct lpt_softc *sc = arg;
int pl;
lprintf(("T %x ", inb(sc->sc_port+lpt_status)));
if (sc->sc_state & OPEN) {
sc->sc_backoff++;
if (sc->sc_backoff > hz/LPTOUTMAX)
sc->sc_backoff = sc->sc_backoff > hz/LPTOUTMAX;
timeout (lptout, (caddr_t)sc, sc->sc_backoff);
} else
sc->sc_state &= ~TOUT;
if (sc->sc_state & ERROR)
sc->sc_state &= ~ERROR;
/*
* Avoid possible hangs do to missed interrupts
*/
if (sc->sc_xfercnt) {
pl = spltty();
lpt_intr(sc);
splx(pl);
} else {
sc->sc_state &= ~OBUSY;
wakeup(sc);
}
}
/*
* lptclose -- close the device, free the local line buffer.
*
* Check for interrupted write call added.
*/
static int
lptclose(struct cdev *dev, int flags, int fmt, struct thread *td)
{
struct lpt_softc *sc;
sc = devclass_get_softc(olpt_devclass, LPTUNIT(minor(dev)));
if(sc->sc_flags & LP_BYPASS)
goto end_close;
sc->sc_state &= ~OPEN;
free(sc->sc_inbuf, M_DEVBUF);
end_close:
sc->sc_state = 0;
sc->sc_xfercnt = 0;
lprintf(("closed.\n"));
return(0);
}
/*
* pushbytes()
* Workhorse for actually spinning and writing bytes to printer
* Derived from lpa.c
* Originally by ?
*
* This code is only used when we are polling the port
*/
static int
pushbytes(struct lpt_softc * sc)
{
int spin, err, tic;
char ch;
int port = sc->sc_port;
lprintf(("p"));
/* loop for every character .. */
while (sc->sc_xfercnt > 0) {
/* printer data */
ch = *(sc->sc_cp);
sc->sc_cp++;
sc->sc_xfercnt--;
/*
* Wait for printer ready.
* Loop 20 usecs testing BUSY bit, then sleep
* for exponentially increasing timeout. (vak)
*/
for (spin=0; NOT_READY(port+lpt_status) && spin<MAX_SPIN; ++spin)
DELAY(1); /* XXX delay is NOT this accurate! */
if (spin >= MAX_SPIN) {
tic = 0;
while (NOT_READY(port+lpt_status)) {
/*
* Now sleep, every cycle a
* little longer ..
*/
tic = tic + tic + 1;
/*
* But no more than 10 seconds. (vak)
*/
if (tic > MAX_SLEEP)
tic = MAX_SLEEP;
err = tsleep(sc, LPPRI,
"lptpoll", tic);
if (err != EWOULDBLOCK) {
return (err);
}
}
}
/* output data */
outb(port+lpt_data, ch);
DELAY(1);
outb(port+lpt_control, LPC_PSTB);
DELAY(1);
outb(port+lpt_control, LPC_NPSTB);
}
return(0);
}
/*
* lptwrite --copy a line from user space to a local buffer, then call
* putc to get the chars moved to the output queue.
*
* Flagging of interrupted write added.
*/
static int
lptwrite(struct cdev *dev, struct uio * uio, int ioflag)
{
register unsigned n;
int pl, err;
struct lpt_softc *sc;
sc = devclass_get_softc(olpt_devclass, LPTUNIT(minor(dev)));
if(sc->sc_flags & LP_BYPASS) {
/* we can't do writes in bypass mode */
return(EPERM);
}
sc->sc_state &= ~INTERRUPTED;
while ((n = min(BUFSIZE, uio->uio_resid)) != 0) {
sc->sc_cp = sc->sc_inbuf;
uiomove(sc->sc_cp, n, uio);
sc->sc_xfercnt = n ;
while ((sc->sc_xfercnt > 0)&&(sc->sc_irq & LP_USE_IRQ)) {
lprintf(("i"));
/* if the printer is ready for a char, */
/* give it one */
if ((sc->sc_state & OBUSY) == 0){
lprintf(("\nC %d. ", sc->sc_xfercnt));
pl = spltty();
lpt_intr(sc);
(void) splx(pl);
}
lprintf(("W "));
if (sc->sc_state & OBUSY)
if ((err = tsleep (sc,
LPPRI|PCATCH, "lpwrite", 0))) {
sc->sc_state |= INTERRUPTED;
return(err);
}
}
/* check to see if we must do a polled write */
if(!(sc->sc_irq & LP_USE_IRQ) && (sc->sc_xfercnt)) {
lprintf(("p"));
if((err = pushbytes(sc)))
return(err);
}
}
return(0);
}
/*
* lptintr -- handle printer interrupts which occur when the printer is
* ready to accept another char.
*
* do checking for interrupted write call.
*/
static void
lpt_intr(void *arg)
{
}
static int
lptioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags, struct thread *td)
{
int error = 0;
struct lpt_softc *sc;
u_int unit = LPTUNIT(minor(dev));
u_char old_sc_irq; /* old printer IRQ status */
sc = devclass_get_softc(olpt_devclass, unit);
switch (cmd) {
case LPT_IRQ :
if(sc->sc_irq & LP_HAS_IRQ) {
/*
* NOTE:
* If the IRQ status is changed,
* this will only be visible on the
* next open.
*
* If interrupt status changes,
* this gets syslog'd.
*/
old_sc_irq = sc->sc_irq;
if(*(int*)data == 0)
sc->sc_irq &= (~LP_ENABLE_IRQ);
else
sc->sc_irq |= LP_ENABLE_IRQ;
if (old_sc_irq != sc->sc_irq )
log(LOG_NOTICE, "lpt%c switched to %s mode\n",
(char)unit+'0',
(sc->sc_irq & LP_ENABLE_IRQ)?
"interrupt-driven":"polled");
} else /* polled port */
error = EOPNOTSUPP;
break;
default:
error = ENODEV;
}
return(error);
}

View File

@ -1,128 +0,0 @@
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* William Jolitz.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)isa.h 5.7 (Berkeley) 5/9/91
* $FreeBSD$
*/
#ifndef _PC98_PC98_PC98_H_
#define _PC98_PC98_PC98_H_
/* BEWARE: Included in both assembler and C code */
/*
* PC98 Bus conventions
* modified for PC9801 by A.Kojima F.Ukai M.Ishii
* Kyoto University Microcomputer Club (KMC)
*/
/*
* Input / Output Port Assignments
*/
#ifndef IO_ISABEGIN
#define IO_ISABEGIN 0x000 /* 0x000 - Beginning of I/O Registers */
/* PC98 IO address ... very dirty (^_^; */
#define IO_ICU1 0x000 /* 8259A Interrupt Controller #1 */
#define IO_DMA 0x001 /* 8237A DMA Controller */
#define IO_ICU2 0x008 /* 8259A Interrupt Controller #2 */
#define IO_RTC 0x020 /* 4990A RTC */
#define IO_SYSPORT 0x031 /* 8255A System Port */
#define IO_PPI 0x035 /* Programmable Peripheral Interface */
#define IO_KBD 0x041 /* 8251A Keyboard */
#define IO_TIMER1 0x071 /* 8253C Timer */
#define IO_COM2 0x0B1 /* 8251A RS232C serial I/O (ext) */
#define IO_COM3 0x0B9 /* 8251A RS232C serial I/O (ext) */
#define IO_FDPORT 0x0BE /* FD I/F port (1M<->640K,EMTON) */
#define IO_NPX 0x0F8 /* Numeric Coprocessor */
#define IO_WD1_EPSON 0x80 /* 386note Hard disk controller */
#define IO_ISAEND 0xFFFF /* - 0x3FF End of I/O Registers */
#endif /* !IO_ISABEGIN */
/*
* Input / Output Port Sizes - these are from several sources, and tend
* to be the larger of what was found, ie COM ports can be 4, but some
* boards do not fully decode the address, thus 8 ports are used.
*/
#ifndef IO_ISASIZES
#define IO_ISASIZES
#define IO_KBDSIZE 16 /* 8042 Keyboard controllers */
#define IO_LPTSIZE 8 /* LPT controllers, some use only 4 */
#define IO_LPTSIZE_EXTENDED 8 /* "Extended" LPT controllers */
#define IO_LPTSIZE_NORMAL 4 /* "Normal" LPT controllers */
#define IO_NPXSIZE 8 /* 80387/80487 NPX registers */
#endif /* !IO_ISASIZES */
/*
* Input / Output Memory Physical Addresses
*/
#ifndef IOM_BEGIN
#define IOM_BEGIN 0x0A0000 /* Start of I/O Memory "hole" */
#define IOM_END 0x100000 /* End of I/O Memory "hole" */
#define IOM_SIZE (IOM_END - IOM_BEGIN)
#endif /* !IOM_BEGIN */
/*
* RAM Physical Address Space (ignoring the above mentioned "hole")
*/
#ifndef RAM_BEGIN
#define RAM_BEGIN 0x0000000 /* Start of RAM Memory */
#ifdef EPSON_BOUNCEDMA
#define RAM_END 0x0f00000 /* End of EPSON GR?? RAM Memory */
#else
#define RAM_END 0x1000000 /* End of RAM Memory */
#endif
#define RAM_SIZE (RAM_END - RAM_BEGIN)
#endif /* !RAM_BEGIN */
/*
* IRQs
*/
#define IRQ_NPX 8
/*
* Npx MD defines
*/
/* full reset of npx: not needed on pc98 */
#define npx_full_reset()
#define M_NEC_PC98 0x0001
#define M_EPSON_PC98 0x0002
#define M_NOT_H98 0x0010
#define M_H98 0x0020
#define M_NOTE 0x0040
#define M_NORMAL 0x1000
#define M_8M 0x8000
#endif /* !_PC98_PC98_PC98_H_ */

View File

@ -39,7 +39,7 @@
#include <cam/cam.h>
#include <cam/cam_ccb.h>
#ifdef EPSON_MEMWIN
#include <pc98/pc98/pc98.h>
#include <pc98/cbus/cbus.h>
#endif
#include <pc98/pc98/pc98_machdep.h>

File diff suppressed because it is too large Load Diff

View File

@ -1,964 +0,0 @@
/*-
* Copyright (c) 1999 FreeBSD(98) port team.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer as
* the first lines of this file unmodified.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#include "opt_kbd.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <machine/bus.h>
#include <sys/rman.h>
#include <sys/kbio.h>
#include <machine/resource.h>
#include <dev/kbd/kbdreg.h>
#include <pc98/pc98/pc98.h>
#include <isa/isavar.h>
#define DRIVER_NAME "pckbd"
/* device configuration flags */
#define KB_CONF_FAIL_IF_NO_KBD (1 << 0) /* don't install if no kbd is found */
static devclass_t pckbd_devclass;
static int pckbdprobe(device_t dev);
static int pckbdattach(device_t dev);
static int pckbdresume(device_t dev);
static void pckbd_isa_intr(void *arg);
static device_method_t pckbd_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, pckbdprobe),
DEVMETHOD(device_attach, pckbdattach),
DEVMETHOD(device_resume, pckbdresume),
{ 0, 0 }
};
static driver_t pckbd_driver = {
DRIVER_NAME,
pckbd_methods,
1,
};
DRIVER_MODULE(pckbd, isa, pckbd_driver, pckbd_devclass, 0, 0);
static bus_addr_t pckbd_iat[] = {0, 2};
static int pckbd_probe_unit(int unit, int port, int irq,
int flags);
static int pckbd_attach_unit(int unit, keyboard_t **kbd,
int port, int irq, int flags);
static timeout_t pckbd_timeout;
static int
pckbdprobe(device_t dev)
{
struct resource *res;
int error, rid;
/* Check isapnp ids */
if (isa_get_vendorid(dev))
return (ENXIO);
device_set_desc(dev, "PC-98 Keyboard");
rid = 0;
res = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid, pckbd_iat, 2,
RF_ACTIVE);
if (res == NULL)
return ENXIO;
isa_load_resourcev(res, pckbd_iat, 2);
error = pckbd_probe_unit(device_get_unit(dev),
isa_get_port(dev),
(1 << isa_get_irq(dev)),
device_get_flags(dev));
bus_release_resource(dev, SYS_RES_IOPORT, rid, res);
return (error);
}
static int
pckbdattach(device_t dev)
{
keyboard_t *kbd;
void *ih;
struct resource *res;
int error, rid;
rid = 0;
res = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid, pckbd_iat, 2,
RF_ACTIVE);
if (res == NULL)
return ENXIO;
isa_load_resourcev(res, pckbd_iat, 2);
error = pckbd_attach_unit(device_get_unit(dev), &kbd,
isa_get_port(dev),
(1 << isa_get_irq(dev)),
device_get_flags(dev));
rid = 0;
res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
if (res == NULL)
return ENXIO;
BUS_SETUP_INTR(device_get_parent(dev), dev, res, INTR_TYPE_TTY,
pckbd_isa_intr, kbd, &ih);
return 0;
}
static int
pckbdresume(device_t dev)
{
keyboard_t *kbd;
kbd = kbd_get_keyboard(kbd_find_keyboard(DRIVER_NAME,
device_get_unit(dev)));
if (kbd)
(*kbdsw[kbd->kb_index]->clear_state)(kbd);
return (0);
}
static void
pckbd_isa_intr(void *arg)
{
keyboard_t *kbd = arg;
(*kbdsw[kbd->kb_index]->intr)(kbd, NULL);
}
static int
pckbd_probe_unit(int unit, int port, int irq, int flags)
{
keyboard_switch_t *sw;
int args[2];
int error;
sw = kbd_get_switch(DRIVER_NAME);
if (sw == NULL)
return ENXIO;
args[0] = port;
args[1] = irq;
error = (*sw->probe)(unit, args, flags);
if (error)
return error;
return 0;
}
static int
pckbd_attach_unit(int unit, keyboard_t **kbd, int port, int irq, int flags)
{
keyboard_switch_t *sw;
int args[2];
int error;
sw = kbd_get_switch(DRIVER_NAME);
if (sw == NULL)
return ENXIO;
/* reset, initialize and enable the device */
args[0] = port;
args[1] = irq;
*kbd = NULL;
error = (*sw->probe)(unit, args, flags);
if (error)
return error;
error = (*sw->init)(unit, kbd, args, flags);
if (error)
return error;
(*sw->enable)(*kbd);
#ifdef KBD_INSTALL_CDEV
/* attach a virtual keyboard cdev */
error = kbd_attach(*kbd);
if (error)
return error;
#endif /* KBD_INSTALL_CDEV */
/*
* This is a kludge to compensate for lost keyboard interrupts.
* A similar code used to be in syscons. See below. XXX
*/
pckbd_timeout(*kbd);
if (bootverbose)
(*sw->diag)(*kbd, bootverbose);
return 0;
}
static void
pckbd_timeout(void *arg)
{
keyboard_t *kbd;
int s;
/* The following comments are extracted from syscons.c (1.287) */
/*
* With release 2.1 of the Xaccel server, the keyboard is left
* hanging pretty often. Apparently an interrupt from the
* keyboard is lost, and I don't know why (yet).
* This ugly hack calls scintr if input is ready for the keyboard
* and conveniently hides the problem. XXX
*/
/*
* Try removing anything stuck in the keyboard controller; whether
* it's a keyboard scan code or mouse data. `scintr()' doesn't
* read the mouse data directly, but `kbdio' routines will, as a
* side effect.
*/
s = spltty();
kbd = (keyboard_t *)arg;
if ((*kbdsw[kbd->kb_index]->lock)(kbd, TRUE)) {
/*
* We have seen the lock flag is not set. Let's reset
* the flag early, otherwise the LED update routine fails
* which may want the lock during the interrupt routine.
*/
(*kbdsw[kbd->kb_index]->lock)(kbd, FALSE);
if ((*kbdsw[kbd->kb_index]->check_char)(kbd))
(*kbdsw[kbd->kb_index]->intr)(kbd, NULL);
}
splx(s);
timeout(pckbd_timeout, arg, hz/10);
}
/* LOW-LEVEL */
#include <sys/limits.h>
#define PC98KBD_DEFAULT 0
typedef caddr_t KBDC;
typedef struct pckbd_state {
KBDC kbdc; /* keyboard controller */
int ks_mode; /* input mode (K_XLATE,K_RAW,K_CODE) */
int ks_flags; /* flags */
#define COMPOSE (1 << 0)
int ks_state; /* shift/lock key state */
int ks_accents; /* accent key index (> 0) */
u_int ks_composed_char; /* composed char code (> 0) */
} pckbd_state_t;
/* keyboard driver declaration */
static int pckbd_configure(int flags);
static kbd_probe_t pckbd_probe;
static kbd_init_t pckbd_init;
static kbd_term_t pckbd_term;
static kbd_intr_t pckbd_intr;
static kbd_test_if_t pckbd_test_if;
static kbd_enable_t pckbd_enable;
static kbd_disable_t pckbd_disable;
static kbd_read_t pckbd_read;
static kbd_check_t pckbd_check;
static kbd_read_char_t pckbd_read_char;
static kbd_check_char_t pckbd_check_char;
static kbd_ioctl_t pckbd_ioctl;
static kbd_lock_t pckbd_lock;
static kbd_clear_state_t pckbd_clear_state;
static kbd_get_state_t pckbd_get_state;
static kbd_set_state_t pckbd_set_state;
static kbd_poll_mode_t pckbd_poll;
keyboard_switch_t pckbdsw = {
pckbd_probe,
pckbd_init,
pckbd_term,
pckbd_intr,
pckbd_test_if,
pckbd_enable,
pckbd_disable,
pckbd_read,
pckbd_check,
pckbd_read_char,
pckbd_check_char,
pckbd_ioctl,
pckbd_lock,
pckbd_clear_state,
pckbd_get_state,
pckbd_set_state,
genkbd_get_fkeystr,
pckbd_poll,
genkbd_diag,
};
KEYBOARD_DRIVER(pckbd, pckbdsw, pckbd_configure);
struct kbdc_softc {
int port; /* base port address */
int lock; /* FIXME: XXX not quite a semaphore... */
};
/* local functions */
static int probe_keyboard(KBDC kbdc, int flags);
static int init_keyboard(KBDC kbdc, int *type, int flags);
static KBDC kbdc_open(int port);
static int kbdc_lock(KBDC kbdc, int lock);
static int kbdc_data_ready(KBDC kbdc);
static int read_kbd_data(KBDC kbdc);
static int read_kbd_data_no_wait(KBDC kbdc);
static int wait_for_kbd_data(struct kbdc_softc *kbdc);
/* local variables */
/* the initial key map, accent map and fkey strings */
#include <dev/kbd/kbdtables.h>
/* structures for the default keyboard */
static keyboard_t default_kbd;
static pckbd_state_t default_kbd_state;
static keymap_t default_keymap;
static accentmap_t default_accentmap;
static fkeytab_t default_fkeytab[NUM_FKEYS];
/*
* The back door to the keyboard driver!
* This function is called by the console driver, via the kbdio module,
* to tickle keyboard drivers when the low-level console is being initialized.
* Almost nothing in the kernel has been initialied yet. Try to probe
* keyboards if possible.
* NOTE: because of the way the low-level conole is initialized, this routine
* may be called more than once!!
*/
static int
pckbd_configure(int flags)
{
keyboard_t *kbd;
int arg[2];
int i;
/* XXX: a kludge to obtain the device configuration flags */
if (resource_int_value(DRIVER_NAME, 0, "flags", &i) == 0) {
flags |= i;
/* if the driver is disabled, unregister the keyboard if any */
if (resource_disabled(DRIVER_NAME, 0)) {
i = kbd_find_keyboard(DRIVER_NAME, PC98KBD_DEFAULT);
if (i >= 0) {
kbd = kbd_get_keyboard(i);
kbd_unregister(kbd);
kbd->kb_flags &= ~KB_REGISTERED;
return 0;
}
}
}
/* probe the default keyboard */
arg[0] = -1;
arg[1] = -1;
kbd = NULL;
if (pckbd_probe(PC98KBD_DEFAULT, arg, flags))
return 0;
if (pckbd_init(PC98KBD_DEFAULT, &kbd, arg, flags))
return 0;
/* return the number of found keyboards */
return 1;
}
/* low-level functions */
/* detect a keyboard */
static int
pckbd_probe(int unit, void *arg, int flags)
{
KBDC kbdc;
int *data = (int *)arg;
if (unit != PC98KBD_DEFAULT)
return ENXIO;
if (KBD_IS_PROBED(&default_kbd))
return 0;
kbdc = kbdc_open(data[0]);
if (kbdc == NULL)
return ENXIO;
if (probe_keyboard(kbdc, flags)) {
if (flags & KB_CONF_FAIL_IF_NO_KBD)
return ENXIO;
}
return 0;
}
/* reset and initialize the device */
static int
pckbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
{
keyboard_t *kbd;
pckbd_state_t *state;
keymap_t *keymap;
accentmap_t *accmap;
fkeytab_t *fkeymap;
int fkeymap_size;
int *data = (int *)arg;
if (unit != PC98KBD_DEFAULT) /* shouldn't happen */
return ENXIO;
*kbdp = kbd = &default_kbd;
state = &default_kbd_state;
if (!KBD_IS_PROBED(kbd)) {
keymap = &default_keymap;
accmap = &default_accentmap;
fkeymap = default_fkeytab;
fkeymap_size =
sizeof(default_fkeytab)/sizeof(default_fkeytab[0]);
state->kbdc = kbdc_open(data[0]);
if (state->kbdc == NULL)
return ENXIO;
kbd_init_struct(kbd, DRIVER_NAME, KB_OTHER, unit, flags,
data[0], IO_KBDSIZE);
bcopy(&key_map, keymap, sizeof(key_map));
bcopy(&accent_map, accmap, sizeof(accent_map));
bcopy(fkey_tab, fkeymap,
imin(fkeymap_size*sizeof(fkeymap[0]), sizeof(fkey_tab)));
kbd_set_maps(kbd, keymap, accmap, fkeymap, fkeymap_size);
kbd->kb_data = (void *)state;
if (probe_keyboard(state->kbdc, flags)) {/* shouldn't happen */
if (flags & KB_CONF_FAIL_IF_NO_KBD)
return ENXIO;
} else {
KBD_FOUND_DEVICE(kbd);
}
pckbd_clear_state(kbd);
state->ks_mode = K_XLATE;
KBD_PROBE_DONE(kbd);
}
if (!KBD_IS_INITIALIZED(kbd) && !(flags & KB_CONF_PROBE_ONLY)) {
if (KBD_HAS_DEVICE(kbd)
&& init_keyboard(state->kbdc, &kbd->kb_type, kbd->kb_config)
&& (kbd->kb_config & KB_CONF_FAIL_IF_NO_KBD))
return ENXIO;
pckbd_ioctl(kbd, KDSETLED, (caddr_t)&state->ks_state);
KBD_INIT_DONE(kbd);
}
if (!KBD_IS_CONFIGURED(kbd)) {
if (kbd_register(kbd) < 0)
return ENXIO;
KBD_CONFIG_DONE(kbd);
}
return 0;
}
/* finish using this keyboard */
static int
pckbd_term(keyboard_t *kbd)
{
kbd_unregister(kbd);
return 0;
}
/* keyboard interrupt routine */
static int
pckbd_intr(keyboard_t *kbd, void *arg)
{
int c;
if (KBD_IS_ACTIVE(kbd) && KBD_IS_BUSY(kbd)) {
/* let the callback function to process the input */
(*kbd->kb_callback.kc_func)(kbd, KBDIO_KEYINPUT,
kbd->kb_callback.kc_arg);
} else {
/* read and discard the input; no one is waiting for input */
do {
c = pckbd_read_char(kbd, FALSE);
} while (c != NOKEY);
}
return 0;
}
/* test the interface to the device */
static int
pckbd_test_if(keyboard_t *kbd)
{
return 0;
}
/*
* Enable the access to the device; until this function is called,
* the client cannot read from the keyboard.
*/
static int
pckbd_enable(keyboard_t *kbd)
{
int s;
s = spltty();
KBD_ACTIVATE(kbd);
splx(s);
return 0;
}
/* disallow the access to the device */
static int
pckbd_disable(keyboard_t *kbd)
{
int s;
s = spltty();
KBD_DEACTIVATE(kbd);
splx(s);
return 0;
}
/* read one byte from the keyboard if it's allowed */
static int
pckbd_read(keyboard_t *kbd, int wait)
{
int c;
if (wait)
c = read_kbd_data(((pckbd_state_t *)kbd->kb_data)->kbdc);
else
c = read_kbd_data_no_wait(((pckbd_state_t *)kbd->kb_data)->kbdc);
if (c != -1)
++kbd->kb_count;
return (KBD_IS_ACTIVE(kbd) ? c : -1);
}
/* check if data is waiting */
static int
pckbd_check(keyboard_t *kbd)
{
if (!KBD_IS_ACTIVE(kbd))
return FALSE;
return kbdc_data_ready(((pckbd_state_t *)kbd->kb_data)->kbdc);
}
/* read char from the keyboard */
static u_int
pckbd_read_char(keyboard_t *kbd, int wait)
{
pckbd_state_t *state;
u_int action;
int scancode;
int keycode;
state = (pckbd_state_t *)kbd->kb_data;
next_code:
/* do we have a composed char to return? */
if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char > 0)) {
action = state->ks_composed_char;
state->ks_composed_char = 0;
if (action > UCHAR_MAX)
return ERRKEY;
return action;
}
/* see if there is something in the keyboard port */
if (wait) {
do {
scancode = read_kbd_data(state->kbdc);
} while (scancode == -1);
} else {
scancode = read_kbd_data_no_wait(state->kbdc);
if (scancode == -1)
return NOKEY;
}
++kbd->kb_count;
#if 0
printf("pckbd_read_char(): scancode:0x%x\n", scancode);
#endif
/* return the byte as is for the K_RAW mode */
if (state->ks_mode == K_RAW)
return scancode;
/* translate the scan code into a keycode */
keycode = scancode & 0x7F;
switch(scancode) {
case 0xF3: /* GRPH (compose key) released */
if (state->ks_flags & COMPOSE) {
state->ks_flags &= ~COMPOSE;
if (state->ks_composed_char > UCHAR_MAX)
state->ks_composed_char = 0;
}
break;
case 0x73: /* GRPH (compose key) pressed */
if (!(state->ks_flags & COMPOSE)) {
state->ks_flags |= COMPOSE;
state->ks_composed_char = 0;
}
break;
}
/* return the key code in the K_CODE mode */
if (state->ks_mode == K_CODE)
return (keycode | (scancode & 0x80));
/* compose a character code */
if (state->ks_flags & COMPOSE) {
switch (scancode) {
/* key pressed, process it */
case 0x42: case 0x43: case 0x44: /* keypad 7,8,9 */
state->ks_composed_char *= 10;
state->ks_composed_char += scancode - 0x3B;
if (state->ks_composed_char > UCHAR_MAX)
return ERRKEY;
goto next_code;
case 0x46: case 0x47: case 0x48: /* keypad 4,5,6 */
state->ks_composed_char *= 10;
state->ks_composed_char += scancode - 0x42;
if (state->ks_composed_char > UCHAR_MAX)
return ERRKEY;
goto next_code;
case 0x4A: case 0x4B: case 0x4C: /* keypad 1,2,3 */
state->ks_composed_char *= 10;
state->ks_composed_char += scancode - 0x49;
if (state->ks_composed_char > UCHAR_MAX)
return ERRKEY;
goto next_code;
case 0x4E: /* keypad 0 */
state->ks_composed_char *= 10;
if (state->ks_composed_char > UCHAR_MAX)
return ERRKEY;
goto next_code;
/* key released, no interest here */
case 0xC2: case 0xC3: case 0xC4: /* keypad 7,8,9 */
case 0xC6: case 0xC7: case 0xC8: /* keypad 4,5,6 */
case 0xCA: case 0xCB: case 0xCC: /* keypad 1,2,3 */
case 0xCE: /* keypad 0 */
goto next_code;
case 0x73: /* GRPH key */
break;
default:
if (state->ks_composed_char > 0) {
state->ks_flags &= ~COMPOSE;
state->ks_composed_char = 0;
return ERRKEY;
}
break;
}
}
/* keycode to key action */
action = genkbd_keyaction(kbd, keycode, scancode & 0x80,
&state->ks_state, &state->ks_accents);
if (action == NOKEY)
goto next_code;
else
return action;
}
/* check if char is waiting */
static int
pckbd_check_char(keyboard_t *kbd)
{
pckbd_state_t *state;
if (!KBD_IS_ACTIVE(kbd))
return FALSE;
state = (pckbd_state_t *)kbd->kb_data;
if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char > 0))
return TRUE;
return kbdc_data_ready(state->kbdc);
}
/* some useful control functions */
static int
pckbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
{
pckbd_state_t *state = kbd->kb_data;
int s;
int i;
s = spltty();
switch (cmd) {
case KDGKBMODE: /* get keyboard mode */
*(int *)arg = state->ks_mode;
break;
case KDSKBMODE: /* set keyboard mode */
switch (*(int *)arg) {
case K_XLATE:
if (state->ks_mode != K_XLATE) {
/* make lock key state and LED state match */
state->ks_state &= ~LOCK_MASK;
state->ks_state |= KBD_LED_VAL(kbd);
}
/* FALLTHROUGH */
case K_RAW:
case K_CODE:
if (state->ks_mode != *(int *)arg) {
pckbd_clear_state(kbd);
state->ks_mode = *(int *)arg;
}
break;
default:
splx(s);
return EINVAL;
}
break;
case KDGETLED: /* get keyboard LED */
*(int *)arg = KBD_LED_VAL(kbd);
break;
case KDSETLED: /* set keyboard LED */
/* NOTE: lock key state in ks_state won't be changed */
if (*(int *)arg & ~LOCK_MASK) {
splx(s);
return EINVAL;
}
i = *(int *)arg;
/* replace CAPS LED with ALTGR LED for ALTGR keyboards */
if (kbd->kb_keymap->n_keys > ALTGR_OFFSET) {
if (i & ALKED)
i |= CLKED;
else
i &= ~CLKED;
}
KBD_LED_VAL(kbd) = *(int *)arg;
break;
case KDGKBSTATE: /* get lock key state */
*(int *)arg = state->ks_state & LOCK_MASK;
break;
case KDSKBSTATE: /* set lock key state */
if (*(int *)arg & ~LOCK_MASK) {
splx(s);
return EINVAL;
}
state->ks_state &= ~LOCK_MASK;
state->ks_state |= *(int *)arg;
splx(s);
/* set LEDs and quit */
return pckbd_ioctl(kbd, KDSETLED, arg);
case KDSETRAD: /* set keyboard repeat rate (old interface)*/
break;
case KDSETREPEAT: /* set keyboard repeat rate (new interface) */
break;
case PIO_KEYMAP: /* set keyboard translation table */
case PIO_KEYMAPENT: /* set keyboard translation table entry */
case PIO_DEADKEYMAP: /* set accent key translation table */
state->ks_accents = 0;
/* FALLTHROUGH */
default:
splx(s);
return genkbd_commonioctl(kbd, cmd, arg);
}
splx(s);
return 0;
}
/* lock the access to the keyboard */
static int
pckbd_lock(keyboard_t *kbd, int lock)
{
return kbdc_lock(((pckbd_state_t *)kbd->kb_data)->kbdc, lock);
}
/* clear the internal state of the keyboard */
static void
pckbd_clear_state(keyboard_t *kbd)
{
pckbd_state_t *state;
state = (pckbd_state_t *)kbd->kb_data;
state->ks_flags = 0;
state->ks_state &= LOCK_MASK; /* preserve locking key state */
state->ks_accents = 0;
state->ks_composed_char = 0;
}
/* save the internal state */
static int
pckbd_get_state(keyboard_t *kbd, void *buf, size_t len)
{
if (len == 0)
return sizeof(pckbd_state_t);
if (len < sizeof(pckbd_state_t))
return -1;
bcopy(kbd->kb_data, buf, sizeof(pckbd_state_t));
return 0;
}
/* set the internal state */
static int
pckbd_set_state(keyboard_t *kbd, void *buf, size_t len)
{
if (len < sizeof(pckbd_state_t))
return ENOMEM;
if (((pckbd_state_t *)kbd->kb_data)->kbdc
!= ((pckbd_state_t *)buf)->kbdc)
return ENOMEM;
bcopy(buf, kbd->kb_data, sizeof(pckbd_state_t));
return 0;
}
/* set polling mode */
static int
pckbd_poll(keyboard_t *kbd, int on)
{
return 0;
}
/* local functions */
static int
probe_keyboard(KBDC kbdc, int flags)
{
return 0;
}
static int
init_keyboard(KBDC kbdc, int *type, int flags)
{
*type = KB_OTHER;
return 0;
}
/* keyboard I/O routines */
/* retry count */
#ifndef KBD_MAXRETRY
#define KBD_MAXRETRY 3
#endif
/* timing parameters */
#ifndef KBD_RESETDELAY
#define KBD_RESETDELAY 200 /* wait 200msec after kbd/mouse reset */
#endif
#ifndef KBD_MAXWAIT
#define KBD_MAXWAIT 5 /* wait 5 times at most after reset */
#endif
/* I/O recovery time */
#define KBDC_DELAYTIME 37
#define KBDD_DELAYTIME 37
/* I/O ports */
#define KBD_STATUS_PORT 2 /* status port, read */
#define KBD_DATA_PORT 0 /* data port, read */
/* status bits (KBD_STATUS_PORT) */
#define KBDS_BUFFER_FULL 0x0002
/* macros */
#define kbdcp(p) ((struct kbdc_softc *)(p))
/* local variables */
static struct kbdc_softc kbdc_softc[1] = { { 0 }, };
/* associate a port number with a KBDC */
static KBDC
kbdc_open(int port)
{
if (port <= 0)
port = IO_KBD;
/* PC-98 has only one keyboard I/F */
kbdc_softc[0].port = port;
kbdc_softc[0].lock = FALSE;
return (KBDC)&kbdc_softc[0];
}
/* set/reset polling lock */
static int
kbdc_lock(KBDC p, int lock)
{
int prevlock;
prevlock = kbdcp(p)->lock;
kbdcp(p)->lock = lock;
return (prevlock != lock);
}
/* check if any data is waiting to be processed */
static int
kbdc_data_ready(KBDC p)
{
return (inb(kbdcp(p)->port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL);
}
/* wait for data from the keyboard */
static int
wait_for_kbd_data(struct kbdc_softc *kbdc)
{
/* CPU will stay inside the loop for 200msec at most */
int retry = 10000;
int port = kbdc->port;
while (!(inb(port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL)) {
DELAY(KBDD_DELAYTIME);
DELAY(KBDC_DELAYTIME);
if (--retry < 0)
return 0;
}
DELAY(KBDD_DELAYTIME);
return 1;
}
/* read one byte from the keyboard */
static int
read_kbd_data(KBDC p)
{
if (!wait_for_kbd_data(kbdcp(p)))
return -1; /* timeout */
DELAY(KBDC_DELAYTIME);
return inb(kbdcp(p)->port + KBD_DATA_PORT);
}
/* read one byte from the keyboard, but return immediately if
* no data is waiting
*/
static int
read_kbd_data_no_wait(KBDC p)
{
if (inb(kbdcp(p)->port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL) {
DELAY(KBDD_DELAYTIME);
return inb(kbdcp(p)->port + KBD_DATA_PORT);
}
return -1; /* no data */
}

View File

@ -1,245 +0,0 @@
/*-
* PMC (Power Management Controller of NEC PC-98Note) Driver
*
* Copyright (c) 2001 Chiharu Shibata.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/eventhandler.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/types.h>
#include <sys/conf.h>
#include <sys/reboot.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/rman.h>
#include <isa/isavar.h>
struct pmc_isa_softc {
struct resource *port_res;
eventhandler_tag evt;
int flags;
};
static int pmc_isa_alloc_resources(device_t);
static void pmc_isa_release_resources(device_t);
static int pmc_isa_probe(device_t);
static int pmc_isa_attach(device_t);
static int pmc_isa_detach(device_t);
#define PMC_ISA_PORT 0x8f0
#define PMC_ISA_PORTSIZE 4
#define sc_inw(sc, port) \
bus_space_read_2(rman_get_bustag((sc)->port_res), \
rman_get_bushandle((sc)->port_res), (port))
#define sc_outw(sc, port, value) \
bus_space_write_2(rman_get_bustag((sc)->port_res), \
rman_get_bushandle((sc)->port_res), (port), (value))
static void
pmc_poweroff(void *arg, int howto)
{
struct pmc_isa_softc *sc = (struct pmc_isa_softc *)arg;
if (!sc->flags) {
outb(0x5e8e, inb(0x5e8e) & ~0x11); /* FDD LED off */
}
if (!(howto & RB_POWEROFF)) {
return;
}
sc_outw(sc, 0, 0x0044);
sc_outw(sc, 2, 1 << 10);
#if 1
/* for 9801NS/T */
sc_outw(sc, 0, 0xf00a);
sc_outw(sc, 2, 1 << 9);
#endif
}
static int
pmc_isa_alloc_resources(device_t dev)
{
struct pmc_isa_softc *sc = device_get_softc(dev);
int rid;
bzero(sc, sizeof(*sc));
rid = 0;
sc->port_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
0ul, ~0ul, PMC_ISA_PORTSIZE,
RF_ACTIVE);
if (sc->port_res == NULL) {
return (ENOMEM);
}
return 0;
}
static void
pmc_isa_release_resources(device_t dev)
{
struct pmc_isa_softc *sc = device_get_softc(dev);
if (sc->port_res != NULL) {
bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->port_res);
}
sc->port_res = NULL;
}
static int
pmc_isa_probe(device_t dev)
{
struct pmc_isa_softc *sc = device_get_softc(dev);
u_int port;
u_int16_t save, tmp;
#if 0
if (isa_get_vendorid(dev)) {
return ENXIO;
}
if (device_get_unit(dev) > 0) {
printf("pmc: Only one PMC driver supported.\n");
return ENXIO;
}
#endif
port = isa_get_port(dev);
if (port == -1) {
port = PMC_ISA_PORT;
}
if (bootverbose) {
device_printf(dev, "port = 0x%x\n", port);
}
if (bus_set_resource(dev, SYS_RES_IOPORT, 0, port, PMC_ISA_PORTSIZE)) {
if (bootverbose) {
device_printf(dev, "bus_set_resource failed\n");
}
return ENXIO;
}
if (pmc_isa_alloc_resources(dev)) {
if (bootverbose) {
device_printf(dev, "pmc_isa_alloc_resources failed\n");
}
return ENXIO;
}
/* Check the existence of PMC */
sc_outw(sc, 0, 0x0052);
save = sc_inw(sc, 2);
tmp = save & ~0x3f;
sc_outw(sc, 2, tmp);
if (sc_inw(sc, 2) != tmp) {
if (bootverbose) {
device_printf(dev, "failed to clear index(0x0052)\n");
}
pmc_isa_release_resources(dev);
return ENXIO;
}
tmp |= 0x3e;
sc_outw(sc, 2, tmp);
if (sc_inw(sc, 2) != tmp) {
if (bootverbose) {
device_printf(dev, "failed to set index(0x0052)\n");
}
pmc_isa_release_resources(dev);
return ENXIO;
}
sc_outw(sc, 2, save);
pmc_isa_release_resources(dev);
device_set_desc(dev, "Power Management Controller");
return 0;
}
static int
pmc_isa_attach(device_t dev)
{
struct pmc_isa_softc *sc = device_get_softc(dev);
int error;
error = pmc_isa_alloc_resources(dev);
if (error) {
device_printf(dev, "resource allocation failed\n");
return error;
}
/* Power the system off using PMC */
sc->evt = EVENTHANDLER_REGISTER(shutdown_final, pmc_poweroff, sc,
SHUTDOWN_PRI_LAST);
sc->flags = device_get_flags(dev);
return 0;
}
static int
pmc_isa_detach(device_t dev)
{
struct pmc_isa_softc *sc = device_get_softc(dev);
if (bootverbose) {
device_printf(dev, "pmc_isa_detach called\n");
}
if (sc->evt != NULL) {
EVENTHANDLER_DEREGISTER(shutdown_final, sc->evt);
}
sc->evt = NULL;
pmc_isa_release_resources(dev);
return 0;
}
static device_method_t pmc_isa_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, pmc_isa_probe),
DEVMETHOD(device_attach, pmc_isa_attach),
DEVMETHOD(device_detach, pmc_isa_detach),
{0, 0}
};
static driver_t pmc_isa_driver = {
"pmc",
pmc_isa_methods, sizeof(struct pmc_isa_softc),
};
devclass_t pmc_devclass;
DRIVER_MODULE(pmc, isa, pmc_isa_driver, pmc_devclass, 0, 0);

File diff suppressed because it is too large Load Diff

View File

@ -1,280 +0,0 @@
/*-
* Copyright (c) 2001 Alcove - Nicolas Souchu
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*
*/
#ifndef __PPCREG_H
#define __PPCREG_H
/*
* Parallel Port Chipset type.
*/
#define SMC_LIKE 0
#define SMC_37C665GT 1
#define SMC_37C666GT 2
#define NS_PC87332 3
#define NS_PC87306 4
#define INTEL_820191AA 5 /* XXX not implemented */
#define GENERIC 6
#define WINB_W83877F 7
#define WINB_W83877AF 8
#define WINB_UNKNOWN 9
#define NS_PC87334 10
#define SMC_37C935 11
#define NS_PC87303 12
/*
* Parallel Port Chipset Type. SMC versus GENERIC (others)
*/
#define PPC_TYPE_SMCLIKE 0
#define PPC_TYPE_GENERIC 1
/*
* Generic structure to hold parallel port chipset info.
*/
struct ppc_data {
int ppc_unit;
int ppc_model; /* chipset model if detected */
int ppc_type; /* generic or smclike chipset type */
int ppc_mode; /* chipset current mode */
int ppc_avm; /* chipset available modes */
int ppc_dtm; /* chipset detected modes */
#define PPC_IRQ_NONE 0x0
#define PPC_IRQ_nACK 0x1
#define PPC_IRQ_DMA 0x2
#define PPC_IRQ_FIFO 0x4
#define PPC_IRQ_nFAULT 0x8
int ppc_irqstat; /* remind irq settings */
#define PPC_DMA_INIT 0x01
#define PPC_DMA_STARTED 0x02
#define PPC_DMA_COMPLETE 0x03
#define PPC_DMA_INTERRUPTED 0x04
#define PPC_DMA_ERROR 0x05
int ppc_dmastat; /* dma state */
int ppc_dmachan; /* dma channel */
int ppc_dmaflags; /* dma transfer flags */
caddr_t ppc_dmaddr; /* buffer address */
u_int ppc_dmacnt; /* count of bytes sent with dma */
#define PPC_PWORD_MASK 0x30
#define PPC_PWORD_16 0x00
#define PPC_PWORD_8 0x10
#define PPC_PWORD_32 0x20
char ppc_pword; /* PWord size */
short ppc_fifo; /* FIFO threshold */
short ppc_wthr; /* writeIntrThresold */
short ppc_rthr; /* readIntrThresold */
char *ppc_ptr; /* microseq current pointer */
int ppc_accum; /* microseq accumulator */
int ppc_base; /* parallel port base address */
int ppc_epp; /* EPP mode (1.7 or 1.9) */
int ppc_irq;
unsigned char ppc_flags;
device_t ppbus; /* parallel port chipset corresponding ppbus */
int rid_irq, rid_drq, rid_ioport;
struct resource *res_irq, *res_drq, *res_ioport;
bus_space_handle_t bsh;
bus_space_tag_t bst;
void *intr_cookie;
int ppc_registered; /* 1 if ppcintr() is the registered interrupt */
};
/*
* Parallel Port Chipset registers.
*/
#define PPC_SPP_DTR 0 /* SPP data register */
#define PPC_ECP_A_FIFO 0 /* ECP Address fifo register */
#define PPC_SPP_STR 1 /* SPP status register */
#define PPC_SPP_CTR 2 /* SPP control register */
#define PPC_EPP_ADDR 3 /* EPP address register (8 bit) */
#define PPC_EPP_DATA 4 /* EPP data register (8, 16 or 32 bit) */
#ifdef PC98
#define PPC_1284_ENABLE 0x09 /* IEEE STD 1284 Enable register */
#define PPC_ECP_D_FIFO 0x0c /* ECP Data fifo register */
#define PPC_ECP_CNFGA 0x0c /* Configuration register A */
#define PPC_ECP_CNFGB 0x0d /* Configuration register B */
#define PPC_ECP_ECR 0x0e /* ECP extended control register */
#else
#define PPC_ECP_D_FIFO 0x400 /* ECP Data fifo register */
#define PPC_ECP_CNFGA 0x400 /* Configuration register A */
#define PPC_ECP_CNFGB 0x401 /* Configuration register B */
#define PPC_ECP_ECR 0x402 /* ECP extended control register */
#endif
#define PPC_FIFO_EMPTY 0x1 /* ecr register - bit 0 */
#define PPC_FIFO_FULL 0x2 /* ecr register - bit 1 */
#define PPC_SERVICE_INTR 0x4 /* ecr register - bit 2 */
#define PPC_ENABLE_DMA 0x8 /* ecr register - bit 3 */
#define PPC_nFAULT_INTR 0x10 /* ecr register - bit 4 */
#define PPC_ECR_STD 0x0
#define PPC_ECR_PS2 0x20
#define PPC_ECR_FIFO 0x40
#define PPC_ECR_ECP 0x60
#define PPC_ECR_EPP 0x80
#define PPC_DISABLE_INTR (PPC_SERVICE_INTR | PPC_nFAULT_INTR)
#define PPC_ECR_RESET (PPC_ECR_PS2 | PPC_DISABLE_INTR)
#define r_dtr(ppc) (bus_space_read_1((ppc)->bst, (ppc)->bsh, PPC_SPP_DTR))
#define r_str(ppc) (bus_space_read_1((ppc)->bst, (ppc)->bsh, PPC_SPP_STR))
#define r_ctr(ppc) (bus_space_read_1((ppc)->bst, (ppc)->bsh, PPC_SPP_CTR))
#define r_epp_A(ppc) (bus_space_read_1((ppc)->bst, (ppc)->bsh, PPC_EPP_ADDR))
#define r_epp_D(ppc) (bus_space_read_1((ppc)->bst, (ppc)->bsh, PPC_EPP_DATA))
#define r_cnfgA(ppc) (bus_space_read_1((ppc)->bst, (ppc)->bsh, PPC_ECP_CNFGA))
#define r_cnfgB(ppc) (bus_space_read_1((ppc)->bst, (ppc)->bsh, PPC_ECP_CNFGB))
#define r_ecr(ppc) (bus_space_read_1((ppc)->bst, (ppc)->bsh, PPC_ECP_ECR))
#define r_fifo(ppc) (bus_space_read_1((ppc)->bst, (ppc)->bsh, PPC_ECP_D_FIFO))
#define w_dtr(ppc, byte) (bus_space_write_1((ppc)->bst, (ppc)->bsh, PPC_SPP_DTR, byte))
#define w_str(ppc, byte) (bus_space_write_1((ppc)->bst, (ppc)->bsh, PPC_SPP_STR, byte))
#define w_ctr(ppc, byte) (bus_space_write_1((ppc)->bst, (ppc)->bsh, PPC_SPP_CTR, byte))
#define w_epp_A(ppc, byte) (bus_space_write_1((ppc)->bst, (ppc)->bsh, PPC_EPP_ADDR, byte))
#define w_epp_D(ppc, byte) (bus_space_write_1((ppc)->bst, (ppc)->bsh, PPC_EPP_DATA, byte))
#define w_ecr(ppc, byte) (bus_space_write_1((ppc)->bst, (ppc)->bsh, PPC_ECP_ECR, byte))
#define w_fifo(ppc, byte) (bus_space_write_1((ppc)->bst, (ppc)->bsh, PPC_ECP_D_FIFO, byte))
/*
* Register defines for the PC873xx parts
*/
#define PC873_FER 0x00
#define PC873_PPENABLE (1<<0)
#define PC873_FAR 0x01
#define PC873_PTR 0x02
#define PC873_CFGLOCK (1<<6)
#define PC873_EPPRDIR (1<<7)
#define PC873_EXTENDED (1<<7)
#define PC873_LPTBIRQ7 (1<<3)
#define PC873_FCR 0x03
#define PC873_ZWS (1<<5)
#define PC873_ZWSPWDN (1<<6)
#define PC873_PCR 0x04
#define PC873_EPPEN (1<<0)
#define PC873_EPP19 (1<<1)
#define PC873_ECPEN (1<<2)
#define PC873_ECPCLK (1<<3)
#define PC873_PMC 0x06
#define PC873_TUP 0x07
#define PC873_SID 0x08
#define PC873_PNP0 0x1b
#define PC873_PNP1 0x1c
#define PC873_LPTBA 0x19
/*
* Register defines for the SMC FDC37C66xGT parts
*/
/* Init codes */
#define SMC665_iCODE 0x55
#define SMC666_iCODE 0x44
/* Base configuration ports */
#define SMC66x_CSR 0x3F0
#define SMC666_CSR 0x370 /* hard-configured value for 666 */
/* Bits */
#define SMC_CR1_ADDR 0x3 /* bit 0 and 1 */
#define SMC_CR1_MODE (1<<3) /* bit 3 */
#define SMC_CR4_EMODE 0x3 /* bits 0 and 1 */
#define SMC_CR4_EPPTYPE (1<<6) /* bit 6 */
/* Extended modes */
#define SMC_SPP 0x0 /* SPP */
#define SMC_EPPSPP 0x1 /* EPP and SPP */
#define SMC_ECP 0x2 /* ECP */
#define SMC_ECPEPP 0x3 /* ECP and EPP */
/*
* Register defines for the SMC FDC37C935 parts
*/
/* Configuration ports */
#define SMC935_CFG 0x370
#define SMC935_IND 0x370
#define SMC935_DAT 0x371
/* Registers */
#define SMC935_LOGDEV 0x7
#define SMC935_ID 0x20
#define SMC935_PORTHI 0x60
#define SMC935_PORTLO 0x61
#define SMC935_PPMODE 0xf0
/* Parallel port modes */
#define SMC935_SPP 0x38 + 0
#define SMC935_EPP19SPP 0x38 + 1
#define SMC935_ECP 0x38 + 2
#define SMC935_ECPEPP19 0x38 + 3
#define SMC935_CENT 0x38 + 4
#define SMC935_EPP17SPP 0x38 + 5
#define SMC935_UNUSED 0x38 + 6
#define SMC935_ECPEPP17 0x38 + 7
/*
* Register defines for the Winbond W83877F parts
*/
#define WINB_W83877F_ID 0xa
#define WINB_W83877AF_ID 0xb
/* Configuration bits */
#define WINB_HEFERE (1<<5) /* CROC bit 5 */
#define WINB_HEFRAS (1<<0) /* CR16 bit 0 */
#define WINB_PNPCVS (1<<2) /* CR16 bit 2 */
#define WINB_CHIPID 0xf /* CR9 bits 0-3 */
#define WINB_PRTMODS0 (1<<2) /* CR0 bit 2 */
#define WINB_PRTMODS1 (1<<3) /* CR0 bit 3 */
#define WINB_PRTMODS2 (1<<7) /* CR9 bit 7 */
/* W83877F modes: CR9/bit7 | CR0/bit3 | CR0/bit2 */
#define WINB_W83757 0x0
#define WINB_EXTFDC 0x4
#define WINB_EXTADP 0x8
#define WINB_EXT2FDD 0xc
#define WINB_JOYSTICK 0x80
#define WINB_PARALLEL 0x80
#define WINB_EPP_SPP 0x4
#define WINB_ECP 0x8
#define WINB_ECP_EPP 0xc
#endif

View File

@ -1,56 +0,0 @@
/*-
* Copyright (c) 1999 FreeBSD(98) Porting Team.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer as
* the first lines of this file unmodified.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _PC98_PC98_SC_MACHDEP_H_
#define _PC98_PC98_SC_MACHDEP_H_
#undef SC_DFLT_FONT
#undef SC_MOUSE_CHAR
#undef SC_PIXEL_MODE
#undef SC_NO_FONT_LOADING
#define SC_NO_FONT_LOADING 1
#undef SC_NO_PALETTE_LOADING
#define SC_NO_PALETTE_LOADING 1
#ifndef SC_KERNEL_CONS_ATTR
#define SC_KERNEL_CONS_ATTR (FG_LIGHTGREY | BG_BLACK)
#endif
#define KANJI 1
#define BELL_DURATION 5
#define BELL_PITCH_8M 1339
#define BELL_PITCH_5M 1678
#define UJIS 0
#define SJIS 1
#define PRINTABLE(c) ((c) > 0x1b || ((c) > 0x0f && (c) < 0x1b) \
|| (c) < 0x07)
#endif /* !_PC98_PC98_SC_MACHDEP_H_ */

View File

@ -1,208 +0,0 @@
/*-
* Copyright (c) 1999 FreeBSD(98) Porting Team.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer as
* the first lines of this file unmodified.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#include "opt_syscons.h"
#include "opt_gdc.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/fbio.h>
#include <sys/consio.h>
#include <dev/fb/fbreg.h>
#include <dev/syscons/syscons.h>
#ifndef SC_RENDER_DEBUG
#define SC_RENDER_DEBUG 0
#endif
static vr_clear_t gdc_txtclear;
static vr_draw_border_t gdc_txtborder;
static vr_draw_t gdc_txtdraw;
static vr_set_cursor_t gdc_txtcursor_shape;
static vr_draw_cursor_t gdc_txtcursor;
#ifndef SC_NO_CUTPASTE
static vr_draw_mouse_t gdc_txtmouse;
#else
#define gdc_txtmouse (vr_draw_mouse_t *)gdc_nop
#endif
#ifndef SC_NO_MODE_CHANGE
static vr_draw_border_t gdc_grborder;
#endif
static void gdc_nop(scr_stat *scp, ...);
static sc_rndr_sw_t txtrndrsw = {
gdc_txtclear,
gdc_txtborder,
gdc_txtdraw,
gdc_txtcursor_shape,
gdc_txtcursor,
(vr_blink_cursor_t *)gdc_nop,
(vr_set_mouse_t *)gdc_nop,
gdc_txtmouse,
};
RENDERER(gdc, 0, txtrndrsw, gdc_set);
#ifndef SC_NO_MODE_CHANGE
static sc_rndr_sw_t grrndrsw = {
(vr_clear_t *)gdc_nop,
gdc_grborder,
(vr_draw_t *)gdc_nop,
(vr_set_cursor_t *)gdc_nop,
(vr_draw_cursor_t *)gdc_nop,
(vr_blink_cursor_t *)gdc_nop,
(vr_set_mouse_t *)gdc_nop,
(vr_draw_mouse_t *)gdc_nop,
};
RENDERER(gdc, GRAPHICS_MODE, grrndrsw, gdc_set);
#endif /* SC_NO_MODE_CHANGE */
RENDERER_MODULE(gdc, gdc_set);
static void
gdc_nop(scr_stat *scp, ...)
{
}
/* text mode renderer */
static void
gdc_txtclear(scr_stat *scp, int c, int attr)
{
sc_vtb_clear(&scp->scr, c, attr);
}
static void
gdc_txtborder(scr_stat *scp, int color)
{
(*vidsw[scp->sc->adapter]->set_border)(scp->sc->adp, color);
}
static void
gdc_txtdraw(scr_stat *scp, int from, int count, int flip)
{
vm_offset_t p;
int c;
int a;
if (from + count > scp->xsize*scp->ysize)
count = scp->xsize*scp->ysize - from;
if (flip) {
for (p = sc_vtb_pointer(&scp->scr, from); count-- > 0; ++from) {
c = sc_vtb_getc(&scp->vtb, from);
a = sc_vtb_geta(&scp->vtb, from);
#if 0
a ^= 0x0800;
#else
a = (a & 0x8800) | ((a & 0x7000) >> 4)
| ((a & 0x0700) << 4);
#endif
p = sc_vtb_putchar(&scp->scr, p, c, a);
}
} else {
sc_vtb_copy(&scp->vtb, from, &scp->scr, from, count);
}
}
static void
gdc_txtcursor_shape(scr_stat *scp, int base, int height, int blink)
{
if (base < 0 || base >= scp->font_size)
return;
/* the caller may set height <= 0 in order to disable the cursor */
(*vidsw[scp->sc->adapter]->set_hw_cursor_shape)(scp->sc->adp,
base, height,
scp->font_size, blink);
}
static void
gdc_txtcursor(scr_stat *scp, int at, int blink, int on, int flip)
{
if (on) {
scp->status |= VR_CURSOR_ON;
(*vidsw[scp->sc->adapter]->set_hw_cursor)(scp->sc->adp,
at%scp->xsize, at/scp->xsize);
} else {
if (scp->status & VR_CURSOR_ON)
(*vidsw[scp->sc->adapter]->set_hw_cursor)(scp->sc->adp,
-1, -1);
scp->status &= ~VR_CURSOR_ON;
}
}
#ifndef SC_NO_CUTPASTE
static void
draw_txtmouse(scr_stat *scp, int x, int y)
{
int at;
int a;
at = (y/scp->font_size - scp->yoff)*scp->xsize + x/8 - scp->xoff;
a = sc_vtb_geta(&scp->vtb, at);
#if 0
a ^= 0x0800;
#else
a = (a & 0x8800) | ((a & 0x7000) >> 4)
| ((a & 0x0700) << 4);
#endif
sc_vtb_putc(&scp->scr, at, sc_vtb_getc(&scp->scr, at), a);
}
static void
remove_txtmouse(scr_stat *scp, int x, int y)
{
}
static void
gdc_txtmouse(scr_stat *scp, int x, int y, int on)
{
if (on)
draw_txtmouse(scp, x, y);
else
remove_txtmouse(scp, x, y);
}
#endif /* SC_NO_CUTPASTE */
#ifndef SC_NO_MODE_CHANGE
/* graphics mode renderer */
static void
gdc_grborder(scr_stat *scp, int color)
{
(*vidsw[scp->sc->adapter]->set_border)(scp->sc->adp, color);
}
#endif /* SC_NO_MODE_CHANGE */

File diff suppressed because it is too large Load Diff

View File

@ -1,399 +0,0 @@
/*-
* Copyright (c) 1999 FreeBSD(98) Porting Team.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer as
* the first lines of this file unmodified.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#include "opt_syscons.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/consio.h>
#include <sys/fbio.h>
#include <machine/md_var.h>
#include <dev/fb/fbreg.h>
#include <dev/syscons/syscons.h>
#define ATTR_OFFSET_FB 0x2000
#define attr_offset(vtb) ((vtb)->vtb_size*sizeof(u_int16_t))
#define vtb_pointer(vtb, at) \
((vtb)->vtb_buffer + sizeof(u_int16_t)*(at))
#define vtb_wrap(vtb, at, offset) \
(((at) + (offset) + (vtb)->vtb_size)%(vtb)->vtb_size)
static u_int8_t ibmpc_to_pc98[256] = {
0x01, 0x21, 0x81, 0xa1, 0x41, 0x61, 0xc1, 0xe1,
0x09, 0x29, 0x89, 0xa9, 0x49, 0x69, 0xc9, 0xe9,
0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45,
0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45,
0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65,
0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65,
0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5,
0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5,
0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5,
0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5,
0x03, 0x23, 0x83, 0xa3, 0x43, 0x63, 0xc3, 0xe3,
0x0b, 0x2b, 0x8b, 0xab, 0x4b, 0x6b, 0xcb, 0xeb,
0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f,
0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f,
0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f,
0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f,
0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf,
0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf,
0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef,
0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef,
};
#define at2pc98(attr) ((attr) | ibmpc_to_pc98[(unsigned)(attr) >> 8])
void
sc_vtb_init(sc_vtb_t *vtb, int type, int cols, int rows, void *buf, int wait)
{
vtb->vtb_flags = 0;
vtb->vtb_type = type;
vtb->vtb_cols = cols;
vtb->vtb_rows = rows;
vtb->vtb_size = cols*rows;
vtb->vtb_buffer = 0;
vtb->vtb_tail = 0;
switch (type) {
case VTB_MEMORY:
case VTB_RINGBUFFER:
if ((buf == NULL) && (cols*rows != 0)) {
vtb->vtb_buffer =
(vm_offset_t)malloc(cols*rows*sizeof(u_int16_t)*2,
M_DEVBUF,
((wait) ? M_WAITOK : M_NOWAIT) | M_ZERO);
if (vtb->vtb_buffer != 0) {
vtb->vtb_flags |= VTB_ALLOCED;
}
} else {
vtb->vtb_buffer = (vm_offset_t)buf;
}
vtb->vtb_flags |= VTB_VALID;
break;
case VTB_FRAMEBUFFER:
vtb->vtb_buffer = (vm_offset_t)buf;
vtb->vtb_flags |= VTB_VALID;
break;
default:
break;
}
}
void
sc_vtb_destroy(sc_vtb_t *vtb)
{
vm_offset_t p;
vtb->vtb_cols = 0;
vtb->vtb_rows = 0;
vtb->vtb_size = 0;
vtb->vtb_tail = 0;
p = vtb->vtb_buffer;
vtb->vtb_buffer = 0;
switch (vtb->vtb_type) {
case VTB_MEMORY:
case VTB_RINGBUFFER:
if ((vtb->vtb_flags & VTB_ALLOCED) && (p != 0))
free((void *)p, M_DEVBUF);
break;
default:
break;
}
vtb->vtb_flags = 0;
vtb->vtb_type = VTB_INVALID;
}
size_t
sc_vtb_size(int cols, int rows)
{
return (size_t)(cols*rows*sizeof(u_int16_t)*2);
}
int
sc_vtb_getc(sc_vtb_t *vtb, int at)
{
vm_offset_t p = vtb_pointer(vtb, at);
if (vtb->vtb_type == VTB_FRAMEBUFFER)
return (readw(p) & 0x00ff);
else
return (*(u_int16_t *)p & 0x00ff);
}
int
sc_vtb_geta(sc_vtb_t *vtb, int at)
{
vm_offset_t p = vtb_pointer(vtb, at);
if (vtb->vtb_type == VTB_FRAMEBUFFER)
return (readw(p + ATTR_OFFSET_FB) & 0xff00);
else
return (*(u_int16_t *)(p + attr_offset(vtb)) & 0xff00);
}
__inline static void
vtb_putc(sc_vtb_t *vtb, vm_offset_t p, int c, int a)
{
if (vtb->vtb_type == VTB_FRAMEBUFFER) {
writew(p, c);
writew(p + ATTR_OFFSET_FB, at2pc98(a));
} else {
*(u_int16_t *)p = c;
*(u_int16_t *)(p + attr_offset(vtb)) = at2pc98(a);
}
}
void
sc_vtb_putc(sc_vtb_t *vtb, int at, int c, int a)
{
vtb_putc(vtb, vtb_pointer(vtb, at), c, a);
}
vm_offset_t
sc_vtb_putchar(sc_vtb_t *vtb, vm_offset_t p, int c, int a)
{
vtb_putc(vtb, p, c, a);
return (p + sizeof(u_int16_t));
}
vm_offset_t
sc_vtb_pointer(sc_vtb_t *vtb, int at)
{
return (vtb_pointer(vtb, at));
}
int
sc_vtb_pos(sc_vtb_t *vtb, int pos, int offset)
{
return ((pos + offset + vtb->vtb_size)%vtb->vtb_size);
}
void
sc_vtb_clear(sc_vtb_t *vtb, int c, int attr)
{
vm_offset_t p = vtb_pointer(vtb, 0);
if (vtb->vtb_type == VTB_FRAMEBUFFER) {
fillw_io(c, p, vtb->vtb_size);
fillw_io(at2pc98(attr), p + ATTR_OFFSET_FB, vtb->vtb_size);
} else {
fillw(c, (void *)p, vtb->vtb_size);
fillw(at2pc98(attr), (void *)(p + attr_offset(vtb)),
vtb->vtb_size);
}
}
void
sc_vtb_copy(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int to, int count)
{
vm_offset_t p1, p2;
p1 = vtb_pointer(vtb1, from);
p2 = vtb_pointer(vtb2, to);
if (vtb2->vtb_type == VTB_FRAMEBUFFER) {
bcopy_toio(p1, p2, count*sizeof(u_int16_t));
bcopy_toio(p1 + attr_offset(vtb1),
p2 + ATTR_OFFSET_FB,
count*sizeof(u_int16_t));
} else if (vtb1->vtb_type == VTB_FRAMEBUFFER) {
bcopy_fromio(p1, p2, count*sizeof(u_int16_t));
bcopy_fromio(p1 + ATTR_OFFSET_FB,
p2 + attr_offset(vtb2),
count*sizeof(u_int16_t));
} else {
bcopy((void *)p1, (void *)p2, count*sizeof(u_int16_t));
bcopy((void *)(p1 + attr_offset(vtb1)),
(void *)(p2 + attr_offset(vtb2)),
count*sizeof(u_int16_t));
}
}
void
sc_vtb_append(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int count)
{
int len;
vm_offset_t p1, p2;
if (vtb2->vtb_type != VTB_RINGBUFFER)
return;
while (count > 0) {
p1 = vtb_pointer(vtb1, from);
p2 = vtb_pointer(vtb2, vtb2->vtb_tail);
len = imin(count, vtb2->vtb_size - vtb2->vtb_tail);
if (vtb1->vtb_type == VTB_FRAMEBUFFER) {
bcopy_fromio(p1, p2, len*sizeof(u_int16_t));
bcopy_fromio(p1 + ATTR_OFFSET_FB,
p2 + attr_offset(vtb2),
len*sizeof(u_int16_t));
} else {
bcopy((void *)p1, (void *)p2, len*sizeof(u_int16_t));
bcopy((void *)(p1 + attr_offset(vtb1)),
(void *)(p2 + attr_offset(vtb2)),
len*sizeof(u_int16_t));
}
from += len;
count -= len;
vtb2->vtb_tail = vtb_wrap(vtb2, vtb2->vtb_tail, len);
}
}
void
sc_vtb_seek(sc_vtb_t *vtb, int pos)
{
vtb->vtb_tail = pos%vtb->vtb_size;
}
void
sc_vtb_erase(sc_vtb_t *vtb, int at, int count, int c, int attr)
{
vm_offset_t p;
if (at + count > vtb->vtb_size)
count = vtb->vtb_size - at;
p = vtb_pointer(vtb, at);
if (vtb->vtb_type == VTB_FRAMEBUFFER) {
fillw_io(c, p, count);
fillw_io(at2pc98(attr), p + ATTR_OFFSET_FB, count);
} else {
fillw(c, (void *)p, count);
fillw(at2pc98(attr), (void *)(p + attr_offset(vtb)), count);
}
}
void
sc_vtb_move(sc_vtb_t *vtb, int from, int to, int count)
{
vm_offset_t p1, p2;
if (from + count > vtb->vtb_size)
count = vtb->vtb_size - from;
if (to + count > vtb->vtb_size)
count = vtb->vtb_size - to;
if (count <= 0)
return;
p1 = vtb_pointer(vtb, from);
p2 = vtb_pointer(vtb, to);
if (vtb->vtb_type == VTB_FRAMEBUFFER) {
bcopy_io(p1, p2, count*sizeof(u_int16_t));
bcopy_io(p1 + ATTR_OFFSET_FB,
p2 + ATTR_OFFSET_FB, count*sizeof(u_int16_t));
} else {
bcopy((void *)p1, (void *)p2, count*sizeof(u_int16_t));
bcopy((void *)(p1 + attr_offset(vtb)),
(void *)(p2 + attr_offset(vtb)), count*sizeof(u_int16_t));
}
}
void
sc_vtb_delete(sc_vtb_t *vtb, int at, int count, int c, int attr)
{
int len;
vm_offset_t p1, p2;
if (at + count > vtb->vtb_size)
count = vtb->vtb_size - at;
len = vtb->vtb_size - at - count;
if (len > 0) {
p1 = vtb_pointer(vtb, at + count);
p2 = vtb_pointer(vtb, at);
if (vtb->vtb_type == VTB_FRAMEBUFFER) {
bcopy_io(p1, p2, len*sizeof(u_int16_t));
bcopy_io(p1 + ATTR_OFFSET_FB,
p2 + ATTR_OFFSET_FB,
len*sizeof(u_int16_t));
} else {
bcopy((void *)p1, (void *)p2, len*sizeof(u_int16_t));
bcopy((void *)(p1 + attr_offset(vtb)),
(void *)(p2 + attr_offset(vtb)),
len*sizeof(u_int16_t));
}
}
p1 = vtb_pointer(vtb, at + len);
if (vtb->vtb_type == VTB_FRAMEBUFFER) {
fillw_io(c, p1, vtb->vtb_size - at - len);
fillw_io(at2pc98(attr), p1 + ATTR_OFFSET_FB,
vtb->vtb_size - at - len);
} else {
fillw(c, (void *)p1, vtb->vtb_size - at - len);
fillw(at2pc98(attr), (void *)(p1 + attr_offset(vtb)),
vtb->vtb_size - at - len);
}
}
void
sc_vtb_ins(sc_vtb_t *vtb, int at, int count, int c, int attr)
{
vm_offset_t p1, p2;
p1 = vtb_pointer(vtb, at);
if (at + count > vtb->vtb_size) {
count = vtb->vtb_size - at;
} else {
p2 = vtb_pointer(vtb, at + count);
if (vtb->vtb_type == VTB_FRAMEBUFFER) {
bcopy_io(p1, p2,
(vtb->vtb_size - at - count)*sizeof(u_int16_t));
bcopy_io(p1 + ATTR_OFFSET_FB,
p2 + ATTR_OFFSET_FB,
(vtb->vtb_size - at - count)*sizeof(u_int16_t));
} else {
bcopy((void *)p1, (void *)p2,
(vtb->vtb_size - at - count)*sizeof(u_int16_t));
bcopy((void *)(p1 + attr_offset(vtb)),
(void *)(p2 + attr_offset(vtb)),
(vtb->vtb_size - at - count)*sizeof(u_int16_t));
}
}
if (vtb->vtb_type == VTB_FRAMEBUFFER) {
fillw_io(c, p1, count);
fillw_io(at2pc98(attr), p1 + ATTR_OFFSET_FB, count);
} else {
fillw(c, (void *)p1, count);
fillw(at2pc98(attr), (void *)(p1 + attr_offset(vtb)), count);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,118 +0,0 @@
/*-
* Copyright (c) 2001 Yoshihiro TAKAHASHI. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/module.h>
#include <sys/tty.h>
#include <machine/bus.h>
#include <sys/timepps.h>
#include <dev/sio/siovar.h>
#include <isa/isavar.h>
static int sio_isa_attach(device_t dev);
static int sio_isa_probe(device_t dev);
static device_method_t sio_isa_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, sio_isa_probe),
DEVMETHOD(device_attach, sio_isa_attach),
DEVMETHOD(device_detach, siodetach),
{ 0, 0 }
};
static driver_t sio_isa_driver = {
sio_driver_name,
sio_isa_methods,
0,
};
static struct isa_pnp_id sio_ids[] = {
{0x0100e4a5, "RSA-98III"},
{0x4180a3b8, NULL}, /* NEC8041 - PC-9821CB-B04 */
{0x0181a3b8, NULL}, /* NEC8101 - PC-9821CB2-B04 */
{0x5181a3b8, NULL}, /* NEC8151 - Internal FAX/Modem for Cx3, Cb3 */
{0x9181a3b8, NULL}, /* NEC8191 - NEC PC-9801-120 */
{0xe181a3b8, NULL}, /* NEC81E1 - Internal FAX/Modem */
{0x1182a3b8, NULL}, /* NEC8211 - PC-9801-123 */
{0x3182a3b8, NULL}, /* NEC8231 - Internal FAX/Modem(Voice) */
{0x4182a3b8, NULL}, /* NEC8241 - NEC PC-9821NR-B05 */
{0x5182a3b8, NULL}, /* NEC8251 - Internel FAX/Modem */
{0x7182a3b8, NULL}, /* NEC8271 - NEC PC-9801-125 */
{0x11802fbf, NULL}, /* OYO8011 - Internal FAX/Modem for ValueStar(Ring) */
{0}
};
static int
sio_isa_probe(dev)
device_t dev;
{
int logical_id;
/* Check isapnp ids */
if (ISA_PNP_PROBE(device_get_parent(dev), dev, sio_ids) == ENXIO)
return (ENXIO);
logical_id = isa_get_logicalid(dev);
switch (logical_id) {
case 0x0100e4a5: /* RSA-98III */
SET_FLAG(dev, SET_IFTYPE(COM_IF_RSA98III));
break;
case 0x4180a3b8: /* PC-9821CB-B04 */
case 0x0181a3b8: /* PC-9821CB2-B04 */
case 0x5181a3b8: /* for Cx3, Cb3 internal */
case 0x9181a3b8: /* PC-9801-120 */
case 0xe181a3b8: /* Internal FAX/Modem */
case 0x1182a3b8: /* PC-9801-123 */
case 0x3182a3b8: /* FAX/Voice/Modem internal */
case 0x4182a3b8: /* PC-9821NR-B05 */
case 0x5182a3b8: /* FAX/Modem internal */
case 0x7182a3b8: /* PC-9801-125 */
case 0x11802fbf: /* for ValueStar internal */
SET_FLAG(dev, SET_IFTYPE(COM_IF_NS16550));
break;
}
return (sioprobe(dev, 0, 0UL, 0));
}
static int
sio_isa_attach(dev)
device_t dev;
{
return (sioattach(dev, 0, 0UL));
}
DRIVER_MODULE(sio, isa, sio_isa_driver, sio_devclass, 0, 0);

View File

@ -1,265 +0,0 @@
/*-
* Copyright (c) 1999 FreeBSD(98) Porting Team.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer as
* the first lines of this file unmodified.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#include "opt_syscons.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/cons.h>
#include <sys/consio.h>
#include <sys/sysctl.h>
#include <machine/clock.h>
#include <pc98/pc98/pc98.h>
#include <pc98/pc98/pc98_machdep.h>
#include <dev/syscons/syscons.h>
#include <i386/isa/timerreg.h>
#include <isa/isavar.h>
static devclass_t sc_devclass;
static sc_softc_t main_softc;
#ifdef SC_NO_SUSPEND_VTYSWITCH
static int sc_no_suspend_vtswitch = 1;
#else
static int sc_no_suspend_vtswitch = 0;
#endif
static int sc_cur_scr;
TUNABLE_INT("hw.syscons.sc_no_suspend_vtswitch", (int *)&sc_no_suspend_vtswitch);
SYSCTL_DECL(_hw_syscons);
SYSCTL_INT(_hw_syscons, OID_AUTO, sc_no_suspend_vtswitch, CTLFLAG_RW,
&sc_no_suspend_vtswitch, 0, "Disable VT switch before suspend.");
static void
scidentify (driver_t *driver, device_t parent)
{
BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "sc", 0);
}
static int
scprobe(device_t dev)
{
/* No pnp support */
if (isa_get_vendorid(dev))
return (ENXIO);
device_set_desc(dev, "System console");
return sc_probe_unit(device_get_unit(dev), device_get_flags(dev));
}
static int
scattach(device_t dev)
{
return sc_attach_unit(device_get_unit(dev), device_get_flags(dev));
}
static int
scsuspend(device_t dev)
{
int retry = 10;
static int dummy;
sc_softc_t *sc;
sc = &main_softc;
if (sc->cur_scp == NULL)
return (0);
sc_cur_scr = sc->cur_scp->index;
if (sc_no_suspend_vtswitch)
return (0);
do {
sc_switch_scr(sc, 0);
if (!sc->switch_in_progress) {
break;
}
tsleep(&dummy, 0, "scsuspend", 100);
} while (retry--);
return (0);
}
static int
scresume(device_t dev)
{
sc_softc_t *sc;
if (sc_no_suspend_vtswitch)
return (0);
sc = &main_softc;
sc_switch_scr(sc, sc_cur_scr);
return (0);
}
int
sc_max_unit(void)
{
return devclass_get_maxunit(sc_devclass);
}
sc_softc_t
*sc_get_softc(int unit, int flags)
{
sc_softc_t *sc;
if (unit < 0)
return NULL;
if (flags & SC_KERNEL_CONSOLE) {
/* FIXME: clear if it is wired to another unit! */
sc = &main_softc;
} else {
sc = (sc_softc_t *)device_get_softc(devclass_get_device(sc_devclass, unit));
if (sc == NULL)
return NULL;
}
sc->unit = unit;
if (!(sc->flags & SC_INIT_DONE)) {
sc->keyboard = -1;
sc->adapter = -1;
sc->mouse_char = SC_MOUSE_CHAR;
}
return sc;
}
sc_softc_t
*sc_find_softc(struct video_adapter *adp, struct keyboard *kbd)
{
sc_softc_t *sc;
int units;
int i;
sc = &main_softc;
if (((adp == NULL) || (adp == sc->adp))
&& ((kbd == NULL) || (kbd == sc->kbd)))
return sc;
units = devclass_get_maxunit(sc_devclass);
for (i = 0; i < units; ++i) {
sc = (sc_softc_t *)device_get_softc(devclass_get_device(sc_devclass, i));
if (sc == NULL)
continue;
if (((adp == NULL) || (adp == sc->adp))
&& ((kbd == NULL) || (kbd == sc->kbd)))
return sc;
}
return NULL;
}
int
sc_get_cons_priority(int *unit, int *flags)
{
const char *at;
int u, f;
*unit = -1;
for (u = 0; u < 16; u++) {
if (resource_disabled(SC_DRIVER_NAME, u))
continue;
if (resource_string_value(SC_DRIVER_NAME, u, "at", &at) != 0)
continue;
if (resource_int_value(SC_DRIVER_NAME, u, "flags", &f) != 0)
f = 0;
if (f & SC_KERNEL_CONSOLE) {
/* the user designates this unit to be the console */
*unit = u;
*flags = f;
break;
}
if (*unit < 0) {
/* ...otherwise remember the first found unit */
*unit = u;
*flags = f;
}
}
if (*unit < 0)
return CN_DEAD;
return CN_INTERNAL;
}
void
sc_get_bios_values(bios_values_t *values)
{
values->cursor_start = 15;
values->cursor_end = 16;
values->shift_state = 0;
if (pc98_machine_type & M_8M)
values->bell_pitch = BELL_PITCH_8M;
else
values->bell_pitch = BELL_PITCH_5M;
}
int
sc_tone(int herz)
{
int pitch;
if (herz) {
/* enable counter 1 */
outb(0x35, inb(0x35) & 0xf7);
/* set command for counter 1, 2 byte write */
if (acquire_timer1(TIMER_16BIT | TIMER_SQWAVE))
return EBUSY;
/* set pitch */
pitch = timer_freq/herz;
outb(TIMER_CNTR1, pitch);
outb(TIMER_CNTR1, pitch >> 8);
} else {
/* disable counter 1 */
outb(0x35, inb(0x35) | 0x08);
release_timer1();
}
return 0;
}
static device_method_t sc_methods[] = {
DEVMETHOD(device_identify, scidentify),
DEVMETHOD(device_probe, scprobe),
DEVMETHOD(device_attach, scattach),
DEVMETHOD(device_suspend, scsuspend),
DEVMETHOD(device_resume, scresume),
{ 0, 0 }
};
static driver_t sc_driver = {
SC_DRIVER_NAME,
sc_methods,
sizeof(sc_softc_t),
};
DRIVER_MODULE(sc, isa, sc_driver, sc_devclass, 0, 0);

View File

@ -64,7 +64,7 @@
/* XXX Shouldn't reach into the MD code here */
#ifdef PC98
#include <pc98/pc98/pc98.h>
#include <pc98/cbus/cbus.h>
#else
#include <i386/isa/isa.h>
#endif