mca_machdep.c revision 50824
1/*-
2 * Copyright (c) 1999 Matthew N. Dodd <winter@jurai.net>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD: head/sys/i386/bios/mca_machdep.c 50824 1999-09-03 03:14:36Z mdodd $
27 */
28
29#include "mca.h"
30#if NMCA > 0
31
32#include <sys/param.h>
33#include <sys/systm.h>
34#include <sys/kernel.h>
35#include <vm/vm.h>
36#include <vm/pmap.h>
37#include <machine/pmap.h>
38#include <machine/md_var.h>
39#include <machine/vm86.h>
40#include <machine/pc/bios.h>
41#include <machine/cpufunc.h>
42
43#include <dev/mca/mca_busreg.h>
44#include <i386/isa/mca_machdep.h>
45
46/* Global MCA bus flag */
47int MCA_system = 0;
48
49/* System Configuration Block */
50struct sys_config {
51	u_int16_t	count;
52	u_int8_t	model;
53	u_int8_t	submodel;
54	u_int8_t	bios_rev;
55	u_int8_t	feature;
56#define FEATURE_RESV	0x01	/* Reserved				*/
57#define FEATURE_MCABUS	0x02	/* MicroChannel Architecture		*/
58#define FEATURE_EBDA	0x04	/* Extended BIOS data area allocated	*/
59#define FEATURE_WAITEV	0x08	/* Wait for external event is supported	*/
60#define FEATURE_KBDINT	0x10	/* Keyboard intercept called by Int 09h	*/
61#define FEATURE_RTC	0x20	/* Real-time clock present		*/
62#define FEATURE_IC2	0x40	/* Second interrupt chip present	*/
63#define FEATURE_DMA3	0x80	/* DMA channel 3 used by hard disk BIOS	*/
64	u_int8_t	pad[3];
65} __attribute__ ((packed));
66
67/* Function Prototypes */
68static void bios_mcabus_present	(void *);
69SYSINIT(mca_present, SI_SUB_CPU, SI_ORDER_ANY, bios_mcabus_present, NULL);
70
71/* Functions */
72static void
73bios_mcabus_present(void * dummy)
74{
75	struct vm86frame	vmf;
76	struct sys_config *	scp;
77	vm_offset_t		paddr;
78
79	bzero(&vmf, sizeof(struct vm86frame));
80
81	vmf.vmf_ah = 0xc0;
82	if (vm86_intcall(0x15, &vmf)) {
83		if (bootverbose) {
84			printf("BIOS SDT: INT call failed.\n");
85		}
86		return;
87	}
88
89	if ((vmf.vmf_ah != 0) && (vmf.vmf_flags != 0)) {
90		if (bootverbose) {
91			printf("BIOS SDT: Not supported.  Not PS/2?\n");
92			printf("BIOS SDT: AH 0x%02x, Flags 0x%04x\n",
93				vmf.vmf_ah, vmf.vmf_flags);
94		}
95		return;
96	}
97
98	paddr = vmf.vmf_es;
99	paddr = (paddr << 4) + vmf.vmf_bx;
100	scp = (struct sys_config *)BIOS_PADDRTOVADDR(paddr);
101
102	if (bootverbose) {
103		printf("BIOS SDT: model 0x%02x, submodel 0x%02x, bios_rev 0x%02x\n",
104			scp->model, scp->submodel, scp->bios_rev);
105		printf("BIOS SDT: features 0x%b\n", scp->feature,
106			"\20"
107			"\01RESV"
108			"\02MCABUS"
109			"\03EBDA"
110			"\04WAITEV"
111			"\05KBDINT"
112			"\06RTC"
113			"\07IC2"
114			"\08DMA3\n");
115	}
116
117	MCA_system = ((scp->feature & FEATURE_MCABUS) ? 1 : 0);
118
119	if (MCA_system)
120		printf("MicroChannel Architecture System detected.\n");
121
122	return;
123}
124
125int
126mca_bus_nmi (void)
127{
128	int	slot;
129	int	retval = 0;
130	int	pos5 = 0;
131
132	/* Disable motherboard setup */
133	outb(MCA_MB_SETUP_REG, MCA_MB_SETUP_DIS);
134
135	/* For each slot */
136	for (slot = 0; slot < MCA_MAX_SLOTS; slot++) {
137
138		/* Select the slot */
139		outb(MCA_ADAP_SETUP_REG, slot | MCA_ADAP_SET);
140		pos5 = inb(MCA_POS_REG(MCA_POS5));
141
142		/* If Adapter Check is low */
143		if ((pos5 & MCA_POS5_CHCK) == 0) {
144			retval++;
145
146			/* If Adapter Check Status is available */
147			if ((pos5 & MCA_POS5_CHCK_STAT) == 0) {
148				printf("MCA NMI: slot %d, POS6=0x%02x, POS7=0x%02x\n",
149					slot+1,
150					inb( MCA_POS_REG(MCA_POS6) ),
151					inb( MCA_POS_REG(MCA_POS7) ));
152			} else {
153				printf("MCA NMI: slot %d\n", slot+1);
154			}
155		}
156		/* Disable adapter setup */
157		outb(MCA_ADAP_SETUP_REG, MCA_ADAP_SETUP_DIS);
158	}
159
160	return (retval);
161}
162#endif
163