Add i386-specific part of MicroChannel Architecture bus support, as
found in some older IBM PS/2 machines. This code is based upon work by Scott D. Telford, with some minor bits in arch/i386/mca/mca_machdep.c taken from FreeBSD. XXX this is still very experimental and development version; use at your XXX own risk
This commit is contained in:
parent
6c1643be43
commit
8fedbd8497
|
@ -0,0 +1,91 @@
|
|||
# $NetBSD: PS2,v 1.1 2000/05/11 16:38:10 jdolecek Exp $
|
||||
#
|
||||
# Sample kernel config for PS/2 with MCA bus
|
||||
#
|
||||
# BEWARE: do NOT use MCA-enabled kernel on non-MCA machine
|
||||
|
||||
include "arch/i386/conf/std.i386"
|
||||
|
||||
maxusers 32 # estimated number of users
|
||||
|
||||
options I386_CPU
|
||||
options I486_CPU
|
||||
|
||||
options MATH_EMULATE # floating point emulation
|
||||
#options XSERVER # X server support in console drivers
|
||||
|
||||
#options UCONSOLE # users can use TIOCCONS (for xconsole)
|
||||
options INSECURE # disable kernel security levels
|
||||
|
||||
options RTC_OFFSET=-600 # hardware clock is this many mins. west of GMT
|
||||
options KTRACE # system call tracing via ktrace(1)
|
||||
|
||||
options SYSVMSG # System V-like message queues
|
||||
options SYSVSEM # System V-like semaphores
|
||||
options SYSVSHM # System V-like memory sharing
|
||||
#options SHMMAXPGS=1024 # 1024 pages is the default
|
||||
|
||||
options DIAGNOSTIC # cheap kernel consistency checks
|
||||
options DEBUG # expensive debugging checks/support
|
||||
options KMEMSTATS # kernel memory statistics (vmstat -m)
|
||||
options DDB # in-kernel debugger
|
||||
|
||||
file-system FFS # UFS
|
||||
#file-system NFS # Network File System client
|
||||
file-system MSDOSFS # MS-DOS file system
|
||||
#file-system FDESC # /dev/fd
|
||||
#file-system KERNFS # /kern
|
||||
|
||||
#options QUOTA # UFS quotas
|
||||
#options NFSSERVER # Network File System server
|
||||
options FIFO # FIFOs; RECOMMENDED
|
||||
|
||||
options INET # IP + ICMP + TCP + UDP
|
||||
|
||||
options COMPAT_AOUT
|
||||
options COMPAT_13
|
||||
options COMPAT_14
|
||||
|
||||
options MCAVERBOSE # verbose MCA device autoconfig messages
|
||||
|
||||
#options NFS_BOOT_BOOTP
|
||||
|
||||
options WSEMUL_VT100 # VT100 / VT220 emulation
|
||||
options WS_KERNEL_FG=WSCOL_GREEN
|
||||
|
||||
config netbsd root on ? type ?
|
||||
#config netbsd root on ? type nfs
|
||||
|
||||
#
|
||||
# Device Configuration
|
||||
#
|
||||
|
||||
mainbus0 at root
|
||||
mca0 at mainbus0
|
||||
isa0 at mainbus0
|
||||
|
||||
npx0 at isa? port 0xf0 irq 13 # x86 math coprocessor
|
||||
|
||||
#pc0 at isa? port 0x60 irq 1
|
||||
|
||||
# wscons
|
||||
pckbc0 at isa? # pc keyboard controller
|
||||
#pcconskbd* at pckbc?
|
||||
pms* at pckbc? # PS/2 mouse for wsmouse
|
||||
wsmouse* at pms?
|
||||
pckbd* at pckbc? # PC keyboard
|
||||
wskbd* at pckbd? console ?
|
||||
vga0 at isa?
|
||||
wsdisplay* at vga? console ?
|
||||
options WSDISPLAY_DEFAULTSCREENS=4
|
||||
|
||||
com0 at isa? port 0x3f8 irq 4 # "SERIAL_!"
|
||||
lpt0 at isa? port 0x3bc irq 7 # "PARALLEL_1"
|
||||
fdc0 at isa? port 0x3f0 irq 6 drq 2 # standard PC floppy controllers
|
||||
fd* at fdc? drive ? # the drives themselves
|
||||
tr* at mca? slot ? # IBM Token Ring adapter
|
||||
#ef* at mca? slot ? # 3Com 3C523 (not yet)
|
||||
|
||||
pseudo-device bpfilter 4 # Berkeley packet filter
|
||||
pseudo-device loop # network loopback
|
||||
pseudo-device pty 16 # pseudo-terminals
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: files.i386,v 1.158 2000/04/28 17:23:51 uch Exp $
|
||||
# $NetBSD: files.i386,v 1.159 2000/05/11 16:38:10 jdolecek Exp $
|
||||
#
|
||||
# new style config file for i386 architecture
|
||||
#
|
||||
|
@ -108,8 +108,7 @@ file arch/i386/i386/bios32.c bios32 needs-flag
|
|||
|
||||
define mainbus { }
|
||||
# XXX BIOS32 only if something that uses it is configured!
|
||||
# device mainbus: isabus, eisabus, mcabus, pcibus, mainbus, bios32
|
||||
device mainbus: isabus, eisabus, pcibus, mainbus, bios32
|
||||
device mainbus: isabus, eisabus, mcabus, pcibus, mainbus, bios32
|
||||
attach mainbus at root
|
||||
file arch/i386/i386/mainbus.c mainbus
|
||||
|
||||
|
@ -260,9 +259,9 @@ file arch/i386/eisa/eisa_machdep.c eisa
|
|||
# MCA-only drivers
|
||||
#
|
||||
|
||||
# device mca {[slot = -1]} : bioscall
|
||||
# include "dev/mca/files.mca"
|
||||
# file arch/i386/mca/mca_machdep.c mca
|
||||
device mca {[slot = -1]} : bioscall
|
||||
include "dev/mca/files.mca"
|
||||
file arch/i386/mca/mca_machdep.c mca
|
||||
|
||||
# ISA Plug 'n Play devices
|
||||
file arch/i386/isa/isapnp_machdep.c isapnp
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: machdep.c,v 1.383 2000/05/03 20:17:37 mycroft Exp $ */
|
||||
/* $NetBSD: machdep.c,v 1.384 2000/05/11 16:38:11 jdolecek Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
|
||||
|
@ -162,6 +162,11 @@
|
|||
extern struct proc *npxproc;
|
||||
#endif
|
||||
|
||||
#include "mca.h"
|
||||
#if NMCA > 0
|
||||
#include <machine/mca_machdep.h> /* for mca_busprobe() */
|
||||
#endif
|
||||
|
||||
/* the following is used externally (sysctl_hw) */
|
||||
char machine[] = "i386"; /* cpu "architecture" */
|
||||
char machine_arch[] = "i386"; /* machine == machine_arch */
|
||||
|
@ -1687,6 +1692,13 @@ init386(first_avail)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if NMCA > 0
|
||||
/* check for MCA bus, needed to be done before ISA stuff - if
|
||||
* MCA is detected, ISA needs to use level triggered interrupts
|
||||
* by default */
|
||||
mca_busprobe();
|
||||
#endif
|
||||
|
||||
#if NISA > 0
|
||||
isa_defaultirq();
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: mainbus.c,v 1.30 2000/03/22 20:58:27 ws Exp $ */
|
||||
/* $NetBSD: mainbus.c,v 1.31 2000/05/11 16:38:11 jdolecek Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
|
||||
|
@ -45,6 +45,7 @@
|
|||
#include "pci.h"
|
||||
#include "eisa.h"
|
||||
#include "isa.h"
|
||||
#include "mca.h"
|
||||
#include "apm.h"
|
||||
#include "pnpbios.h"
|
||||
|
||||
|
@ -57,6 +58,10 @@
|
|||
#include <arch/i386/pnpbios/pnpbiosvar.h>
|
||||
#endif
|
||||
|
||||
#if NMCA > 0
|
||||
#include <dev/mca/mcavar.h>
|
||||
#endif
|
||||
|
||||
int mainbus_match __P((struct device *, struct cfdata *, void *));
|
||||
void mainbus_attach __P((struct device *, struct device *, void *));
|
||||
|
||||
|
@ -71,6 +76,9 @@ union mainbus_attach_args {
|
|||
struct pcibus_attach_args mba_pba;
|
||||
struct eisabus_attach_args mba_eba;
|
||||
struct isabus_attach_args mba_iba;
|
||||
#if NMCA > 0
|
||||
struct mcabus_attach_args mba_mba;
|
||||
#endif
|
||||
#if NAPM > 0
|
||||
struct apm_attach_args mba_aaa;
|
||||
#endif
|
||||
|
@ -151,6 +159,19 @@ mainbus_attach(parent, self, aux)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if NMCA > 0
|
||||
/* note MCA bus probe is done in i386/machdep.c */
|
||||
if (MCA_system) {
|
||||
mba.mba_mba.mba_busname = "mca";
|
||||
mba.mba_mba.mba_iot = I386_BUS_SPACE_IO;
|
||||
mba.mba_mba.mba_memt = I386_BUS_SPACE_MEM;
|
||||
mba.mba_mba.mba_dmat = &mca_bus_dma_tag;
|
||||
mba.mba_mba.mba_mc = NULL;
|
||||
mba.mba_mba.mba_bus = 0;
|
||||
config_found(self, &mba.mba_mba, mainbus_print);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (memcmp(ISA_HOLE_VADDR(EISA_ID_PADDR), EISA_ID, EISA_ID_LEN) == 0 &&
|
||||
eisa_has_been_seen == 0) {
|
||||
mba.mba_eba.eba_busname = "eisa";
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: trap.c,v 1.134 1999/12/04 21:20:32 ragge Exp $ */
|
||||
/* $NetBSD: trap.c,v 1.135 2000/05/11 16:38:12 jdolecek Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
|
@ -114,6 +114,13 @@
|
|||
#include <machine/db_machdep.h>
|
||||
#endif
|
||||
|
||||
#include "mca.h"
|
||||
#if NMCA > 0
|
||||
#include <machine/mca_machdep.h>
|
||||
#endif
|
||||
|
||||
#include "isa.h"
|
||||
|
||||
#ifdef KGDB
|
||||
#include <sys/kgdb.h>
|
||||
#endif
|
||||
|
@ -530,8 +537,7 @@ trap(frame)
|
|||
trapsignal(p, SIGTRAP, type &~ T_USER);
|
||||
break;
|
||||
|
||||
#include "isa.h"
|
||||
#if NISA > 0
|
||||
#if NISA > 0 || NMCA > 0
|
||||
case T_NMI:
|
||||
#if defined(KGDB) || defined(DDB)
|
||||
/* NMI can be hooked up to a pushbutton for debugging */
|
||||
|
@ -547,11 +553,20 @@ trap(frame)
|
|||
#endif
|
||||
#endif /* KGDB || DDB */
|
||||
/* machine/parity/power fail/"kitchen sink" faults */
|
||||
if (isa_nmi() == 0)
|
||||
return;
|
||||
else
|
||||
|
||||
#if NMCA > 0
|
||||
/* mca_nmi() takes care to call isa_nmi() if appropriate */
|
||||
if (mca_nmi() != 0)
|
||||
goto we_re_toast;
|
||||
#endif
|
||||
else
|
||||
return;
|
||||
#else /* NISA > 0 */
|
||||
if (isa_nmi() != 0)
|
||||
goto we_re_toast;
|
||||
else
|
||||
return;
|
||||
#endif /* NMCA > 0 */
|
||||
#endif /* NISA > 0 || NMCA > 0 */
|
||||
}
|
||||
|
||||
if ((type & T_USER) == 0)
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
/* $NetBSD: mca_machdep.h,v 1.1 2000/05/11 16:38:13 jdolecek Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 1999 Scott D. Telford. 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.
|
||||
*/
|
||||
|
||||
#ifndef _I386_MCA_MACHDEP_H_
|
||||
#define _I386_MCA_MACHDEP_H_
|
||||
|
||||
/*
|
||||
* i386-specific definitions for MCA autoconfiguration.
|
||||
*/
|
||||
|
||||
extern struct i386_bus_dma_tag mca_bus_dma_tag;
|
||||
|
||||
/* set to 1 if MCA bus is detected */
|
||||
extern int MCA_system;
|
||||
|
||||
int mca_nmi __P((void));
|
||||
|
||||
/*
|
||||
* Types provided to machine-independent MCA code.
|
||||
*/
|
||||
struct i386_mca_chipset {
|
||||
void * /*struct mca_dma_state*/ ic_dmastate;
|
||||
};
|
||||
|
||||
typedef struct i386_mca_chipse *mca_chipset_tag_t;
|
||||
typedef int mca_intr_handle_t;
|
||||
|
||||
/*
|
||||
* Functions provided to machine-independent MCA code.
|
||||
*/
|
||||
struct mcabus_attach_args;
|
||||
|
||||
void mca_attach_hook __P((struct device *, struct device *,
|
||||
struct mcabus_attach_args *));
|
||||
void *mca_intr_establish __P((mca_chipset_tag_t, mca_intr_handle_t,
|
||||
int, int (*)(void *), void *));
|
||||
void mca_intr_disestablish __P((mca_chipset_tag_t, void *));
|
||||
int mca_conf_read __P((mca_chipset_tag_t, int, int));
|
||||
void mca_conf_write __P((mca_chipset_tag_t, int, int, int));
|
||||
void mca_busprobe __P((void));
|
||||
|
||||
/* MCA register addresses for IBM PS/2 */
|
||||
|
||||
#define PS2_SYS_CTL_A 0x92 /* PS/2 System Control Port A */
|
||||
#define MCA_MB_SETUP_REG 0x94 /* Motherboard setup register */
|
||||
#define MCA_ADAP_SETUP_REG 0x96 /* Adapter setup register */
|
||||
#define MCA_POS_REG_BASE 0x100 /* POS registers base address */
|
||||
#define MCA_POS_REG_SIZE 8 /* POS registers window size */
|
||||
|
||||
#define MCA_POS_REG(n) (0x100+(n)) /* POS registers 0-7 */
|
||||
|
||||
/* Adapter setup register bits */
|
||||
|
||||
#define MCA_ADAP_SET 0x08 /* Adapter setup mode */
|
||||
#define MCA_ADAP_CHR 0x80 /* Adapter channel reset */
|
||||
|
||||
#endif /* _I386_MCA_MACHDEP_H_ */
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: clock.c,v 1.64 2000/05/03 21:32:59 mycroft Exp $ */
|
||||
/* $NetBSD: clock.c,v 1.65 2000/05/11 16:38:13 jdolecek Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1993, 1994 Charles M. Hannum.
|
||||
|
@ -113,6 +113,11 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#if (NPCPPI > 0)
|
||||
#include <dev/isa/pcppivar.h>
|
||||
|
||||
#include "mca.h"
|
||||
#if NMCA > 0
|
||||
#include <machine/mca_machdep.h> /* for MCA_system */
|
||||
#endif
|
||||
|
||||
#ifdef CLOCKDEBUG
|
||||
int clock_debug = 0;
|
||||
#define DPRINTF(arg) if (clock_debug) printf arg
|
||||
|
@ -402,6 +407,13 @@ clockintr(arg)
|
|||
struct clockframe *frame = arg; /* not strictly necessary */
|
||||
|
||||
hardclock(frame);
|
||||
|
||||
#if NMCA > 0
|
||||
if (MCA_system) {
|
||||
/* Reset PS/2 clock interrupt by asserting bit 7 of port 0x61 */
|
||||
outb(0x61, inb(0x61) | 0x80);
|
||||
}
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: isa_machdep.c,v 1.45 1999/11/12 18:39:38 drochner Exp $ */
|
||||
/* $NetBSD: isa_machdep.c,v 1.46 2000/05/11 16:38:13 jdolecek Exp $ */
|
||||
|
||||
#define ISA_DMA_STATS
|
||||
|
||||
|
@ -98,6 +98,11 @@
|
|||
|
||||
#include <vm/vm.h>
|
||||
|
||||
#include "mca.h"
|
||||
#if NMCA > 0
|
||||
#include <machine/mca_machdep.h> /* for MCA_system */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ISA can only DMA to 0-16M.
|
||||
*/
|
||||
|
@ -110,7 +115,11 @@ typedef void (vector) __P((void));
|
|||
extern vector *IDTVEC(intr)[];
|
||||
void isa_strayintr __P((int));
|
||||
void intr_calculatemasks __P((void));
|
||||
int fakeintr __P((void *));
|
||||
static int fakeintr __P((void *));
|
||||
#if NMCA > 0
|
||||
static int mca_clockfakeintr __P((void *));
|
||||
#endif
|
||||
|
||||
|
||||
int _isa_bus_dmamap_create __P((bus_dma_tag_t, bus_size_t, int,
|
||||
bus_size_t, bus_size_t, int, bus_dmamap_t *));
|
||||
|
@ -171,7 +180,14 @@ isa_defaultirq()
|
|||
SDT_SYS386IGT, SEL_KPL);
|
||||
|
||||
/* initialize 8259's */
|
||||
outb(IO_ICU1, 0x11); /* reset; program device, four bytes */
|
||||
#if NMCA > 0
|
||||
/* level-triggered interrupts on MCA PS/2s */
|
||||
if (MCA_system)
|
||||
outb(IO_ICU1, 0x19); /* reset; program device, four bytes */
|
||||
else
|
||||
#endif
|
||||
outb(IO_ICU1, 0x11); /* reset; program device, four bytes */
|
||||
|
||||
outb(IO_ICU1+1, ICU_OFFSET); /* starting at this vector index */
|
||||
outb(IO_ICU1+1, 1 << IRQ_SLAVE); /* slave on line 2 */
|
||||
#ifdef AUTO_EOI_1
|
||||
|
@ -186,7 +202,14 @@ isa_defaultirq()
|
|||
outb(IO_ICU1, 0xc0 | (3 - 1)); /* pri order 3-7, 0-2 (com2 first) */
|
||||
#endif
|
||||
|
||||
outb(IO_ICU2, 0x11); /* reset; program device, four bytes */
|
||||
#if NMCA > 0
|
||||
/* level-triggered interrupts on MCA PS/2s */
|
||||
if (MCA_system)
|
||||
outb(IO_ICU2, 0x19); /* reset; program device, four bytes */
|
||||
else
|
||||
#endif
|
||||
outb(IO_ICU2, 0x11); /* reset; program device, four bytes */
|
||||
|
||||
outb(IO_ICU2+1, ICU_OFFSET+8); /* staring at this vector index */
|
||||
outb(IO_ICU2+1, IRQ_SLAVE);
|
||||
#ifdef AUTO_EOI_2
|
||||
|
@ -206,7 +229,6 @@ isa_defaultirq()
|
|||
int
|
||||
isa_nmi()
|
||||
{
|
||||
|
||||
log(LOG_CRIT, "NMI port 61 %x, port 70 %x\n", inb(0x61), inb(0x70));
|
||||
return(0);
|
||||
}
|
||||
|
@ -335,7 +357,7 @@ intr_calculatemasks()
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
fakeintr(arg)
|
||||
void *arg;
|
||||
{
|
||||
|
@ -434,6 +456,15 @@ isa_intr_establish(ic, irq, type, level, ih_fun, ih_arg)
|
|||
struct intrhand **p, *q, *ih;
|
||||
static struct intrhand fakehand = {fakeintr};
|
||||
|
||||
#if NMCA > 0
|
||||
/*
|
||||
* Need special fake handler for PS/2 MCA clock interrupt
|
||||
*/
|
||||
|
||||
if (MCA_system && irq == 0)
|
||||
fakehand.ih_fun = &mca_clockfakeintr;
|
||||
#endif
|
||||
|
||||
/* no point in sleeping unless someone can free memory. */
|
||||
ih = malloc(sizeof *ih, M_DEVBUF, cold ? M_NOWAIT : M_WAITOK);
|
||||
if (ih == NULL)
|
||||
|
@ -442,6 +473,12 @@ isa_intr_establish(ic, irq, type, level, ih_fun, ih_arg)
|
|||
if (!LEGAL_IRQ(irq) || type == IST_NONE)
|
||||
panic("intr_establish: bogus irq or type");
|
||||
|
||||
#if NMCA > 0
|
||||
/* change IST_EDGE to IST_LEVEL if MCA system */
|
||||
if (MCA_system && type == IST_EDGE)
|
||||
type = IST_LEVEL;
|
||||
#endif
|
||||
|
||||
switch (intrtype[irq]) {
|
||||
case IST_NONE:
|
||||
intrtype[irq] = type;
|
||||
|
@ -1130,3 +1167,17 @@ _isa_dma_free_bouncebuf(t, map)
|
|||
cookie->id_nbouncesegs = 0;
|
||||
cookie->id_flags &= ~ID_HAS_BOUNCE;
|
||||
}
|
||||
|
||||
#if NMCA > 0
|
||||
/*
|
||||
* Special fake handler for PS/2 MCA clock interrupts
|
||||
*/
|
||||
static int
|
||||
mca_clockfakeintr(arg)
|
||||
void *arg;
|
||||
{
|
||||
/* Reset clock interrupt by asserting bit 7 of port 0x61 */
|
||||
outb(0x61, inb(0x61) | 0x80);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,275 @@
|
|||
/* $NetBSD: mca_machdep.c,v 1.1 2000/05/11 16:38:14 jdolecek Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 1996-1999 Scott D. Telford. 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Machine-specific functions for MCA autoconfiguration.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/syslog.h>
|
||||
|
||||
#include <machine/bioscall.h>
|
||||
#include <machine/psl.h>
|
||||
|
||||
#define _I386_BUS_DMA_PRIVATE
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include <i386/isa/icu.h>
|
||||
#include <dev/isa/isavar.h>
|
||||
#include <dev/isa/isareg.h>
|
||||
#include <dev/mca/mcavar.h>
|
||||
#include <dev/mca/mcareg.h>
|
||||
|
||||
#include "isa.h"
|
||||
#include "opt_mcaverbose.h"
|
||||
|
||||
struct i386_bus_dma_tag mca_bus_dma_tag = {
|
||||
NULL, /* _cookie */
|
||||
_bus_dmamap_create,
|
||||
_bus_dmamap_destroy,
|
||||
_bus_dmamap_load,
|
||||
_bus_dmamap_load_mbuf,
|
||||
_bus_dmamap_load_uio,
|
||||
_bus_dmamap_load_raw,
|
||||
_bus_dmamap_unload,
|
||||
NULL, /* _dmamap_sync */
|
||||
_bus_dmamem_alloc,
|
||||
_bus_dmamem_free,
|
||||
_bus_dmamem_map,
|
||||
_bus_dmamem_unmap,
|
||||
_bus_dmamem_mmap,
|
||||
};
|
||||
|
||||
/* setup by mca_busprobe() */
|
||||
int MCA_system = 1; /* XXX force MCA for now */
|
||||
int bios_features = 1;
|
||||
|
||||
/* System Configuration Block */
|
||||
struct sys_config {
|
||||
u_int16_t count;
|
||||
u_int8_t model;
|
||||
u_int8_t submodel;
|
||||
u_int8_t bios_rev;
|
||||
u_int8_t feature;
|
||||
#define FEATURE_RESV 0x01 /* Reserved */
|
||||
#define FEATURE_MCABUS 0x02 /* MicroChannel Architecture */
|
||||
#define FEATURE_EBDA 0x04 /* Extended BIOS data area allocated */
|
||||
#define FEATURE_WAITEV 0x08 /* Wait for external event is supported */
|
||||
#define FEATURE_KBDINT 0x10 /* Keyboard intercept called by Int 09h */
|
||||
#define FEATURE_RTC 0x20 /* Real-time clock present */
|
||||
#define FEATURE_IC2 0x40 /* Second interrupt chip present */
|
||||
#define FEATURE_DMA3 0x80 /* DMA channel 3 used by hard disk BIOS */
|
||||
u_int8_t pad[3];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
void
|
||||
mca_attach_hook(parent, self, mba)
|
||||
struct device *parent, *self;
|
||||
struct mcabus_attach_args *mba;
|
||||
{
|
||||
/* Nothing */
|
||||
}
|
||||
|
||||
/*
|
||||
* Read value of MCA POS register "reg" in slot "slot".
|
||||
*/
|
||||
|
||||
int
|
||||
mca_conf_read(mc, slot, reg)
|
||||
mca_chipset_tag_t mc;
|
||||
int slot, reg;
|
||||
{
|
||||
int data;
|
||||
|
||||
slot &= 7; /* slot must be in range 0-7 */
|
||||
outb(MCA_MB_SETUP_REG, 0xff); /* ensure m/board setup is disabled */
|
||||
outb(MCA_ADAP_SETUP_REG, slot | MCA_ADAP_SET);
|
||||
data = inb(MCA_POS_REG(reg));
|
||||
outb(MCA_ADAP_SETUP_REG, 0);
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write "data" to MCA POS register "reg" in slot "slot".
|
||||
*/
|
||||
|
||||
void
|
||||
mca_conf_write(mc, slot, reg, data)
|
||||
mca_chipset_tag_t mc;
|
||||
int slot, reg, data;
|
||||
{
|
||||
slot&=7; /* slot must be in range 0-7 */
|
||||
outb(MCA_MB_SETUP_REG, 0xff); /* ensure m/board setup is disabled */
|
||||
outb(MCA_ADAP_SETUP_REG, slot | MCA_ADAP_SET);
|
||||
outb(MCA_POS_REG(reg), data);
|
||||
outb(MCA_ADAP_SETUP_REG, 0);
|
||||
}
|
||||
|
||||
#if NISA <= 0
|
||||
#error mca_intr_(dis)establish: needs ISA to be configured into kernel
|
||||
#endif
|
||||
|
||||
void *
|
||||
mca_intr_establish(mc, ih, level, func, arg)
|
||||
mca_chipset_tag_t mc;
|
||||
mca_intr_handle_t ih;
|
||||
int level, (*func) __P((void *));
|
||||
void *arg;
|
||||
{
|
||||
if (ih == 0 || ih >= ICU_LEN || ih == 2)
|
||||
panic("mca_intr_establish: bogus handle 0x%x\n", ih);
|
||||
|
||||
/* MCA interrupts are always level-triggered */
|
||||
return isa_intr_establish(NULL, ih, IST_LEVEL, level, func, arg);
|
||||
}
|
||||
|
||||
void
|
||||
mca_intr_disestablish(mc, cookie)
|
||||
mca_chipset_tag_t mc;
|
||||
void *cookie;
|
||||
{
|
||||
return isa_intr_disestablish(NULL, cookie);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Handle a NMI.
|
||||
* return true to panic system, false to ignore.
|
||||
*/
|
||||
int
|
||||
mca_nmi()
|
||||
{
|
||||
/*
|
||||
* PS/2 MCA devices can generate NMIs - we can find out which
|
||||
* slot generated it from the POS registers.
|
||||
*/
|
||||
|
||||
int slot, mcanmi=0;
|
||||
|
||||
/* if there is no MCA bus, call isa_nmi() */
|
||||
if (!MCA_system)
|
||||
goto out;
|
||||
|
||||
/* ensure motherboard setup is disabled */
|
||||
outb(MCA_MB_SETUP_REG, 0xff);
|
||||
|
||||
/* find if an MCA slot has the CHCK bit asserted (low) in POS 5 */
|
||||
for(slot=0; slot<MCA_MAX_SLOTS; slot++)
|
||||
{
|
||||
outb(MCA_ADAP_SETUP_REG, slot | MCA_ADAP_SET);
|
||||
if ((inb(MCA_POS_REG(5)) & MCA_POS5_CHCK) == 0)
|
||||
{
|
||||
mcanmi = 1;
|
||||
/* find if CHCK status is available in POS 6/7 */
|
||||
if((inb(MCA_POS_REG(5)) & MCA_POS5_CHCK_STAT) == 0)
|
||||
log(LOG_CRIT, "MCA NMI: slot %d, POS6=0x%02x, POS7=0x%02x\n",
|
||||
slot+1, inb(MCA_POS_REG(6)),
|
||||
inb(MCA_POS_REG(7)));
|
||||
else
|
||||
log(LOG_CRIT, "MCA NMI: slot %d\n", slot+1);
|
||||
}
|
||||
}
|
||||
outb(MCA_ADAP_SETUP_REG, 0);
|
||||
|
||||
out:
|
||||
#if NISA > 0
|
||||
if (!mcanmi) {
|
||||
/* no CHCK bits asserted, assume ISA NMI */
|
||||
return (isa_nmi());
|
||||
} else
|
||||
#endif
|
||||
return(0);
|
||||
}
|
||||
|
||||
void
|
||||
mca_busprobe()
|
||||
{
|
||||
/* According to Linux's linux/arch/i386/boot/setup.S,
|
||||
* we can get the extra BIOS information via int 0x15,
|
||||
* ah == 0xc0. The extra information is stored on
|
||||
* es:bx; it contains two bytes of length, then byte
|
||||
* of machine id, byte of machine submodel, byte of BIOS
|
||||
* revision number and byte of feature info.
|
||||
*/
|
||||
/*
|
||||
* Scott Telford's code used
|
||||
* ((inb(MCA_ADAP_SETUP_REG) & (MCA_ADAP_SET | MCA_ADAP_CHR)) == 0)
|
||||
* - somewhat dubious, but good enough.
|
||||
*/
|
||||
|
||||
#if notyet
|
||||
/*
|
||||
* Following has been taken from FreeBSD, for now just for
|
||||
* documentation purposes
|
||||
*/
|
||||
struct bioscallregs regs;
|
||||
struct sys_config *scp;
|
||||
paddr_t paddr;
|
||||
|
||||
memset(®s, 0, sizeof(regs));
|
||||
regs.AX_HI = 0xc0;
|
||||
bioscall(0x15, ®s);
|
||||
|
||||
if ((regs.EFLAGS & PSL_C)
|
||||
|| (regs.AX_HI != 0 && (regs.FLAGS & PSL_AC)))
|
||||
{
|
||||
#ifdef MCAVERBOSE
|
||||
printf("BIOS SDT: Not supported. Not PS/2?\n");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
paddr = (regs.ES << 4) + regs.BX;
|
||||
scp = (struct sys_config *)ISA_HOLE_VADDR(paddr);
|
||||
|
||||
printf("BIOS SDT: model 0x%x, submodel 0x%x, BIOS rev. 0x%x\n",
|
||||
scp->model, scp->submodel, scp->bios_rev);
|
||||
|
||||
#ifdef MCAVERBOSE
|
||||
printf("BIOS SDT: features 0x%b\n", scp->feature,
|
||||
"\20"
|
||||
"\01RESV"
|
||||
"\02MCABUS"
|
||||
"\03EBDA"
|
||||
"\04WAITEV"
|
||||
"\05KBDINT"
|
||||
"\06RTC"
|
||||
"\07IC2"
|
||||
"\08DMA3\n");
|
||||
#endif
|
||||
|
||||
bios_features = scp->feature;
|
||||
MCA_system = (bios_features & FEATURE_MCABUS) ? 1 : 0;
|
||||
#endif /* 0 */
|
||||
}
|
Loading…
Reference in New Issue