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:
jdolecek 2000-05-11 16:38:10 +00:00
parent 6c1643be43
commit 8fedbd8497
9 changed files with 581 additions and 22 deletions

91
sys/arch/i386/conf/PS2 Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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(&regs, 0, sizeof(regs));
regs.AX_HI = 0xc0;
bioscall(0x15, &regs);
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 */
}