mca_machdep.c revision 50824
1144518Sdavidxu/*-
2144518Sdavidxu * Copyright (c) 1999 Matthew N. Dodd <winter@jurai.net>
3144518Sdavidxu * All rights reserved.
4144518Sdavidxu *
5144518Sdavidxu * Redistribution and use in source and binary forms, with or without
6144518Sdavidxu * modification, are permitted provided that the following conditions
7144518Sdavidxu * are met:
8144518Sdavidxu * 1. Redistributions of source code must retain the above copyright
9144518Sdavidxu *    notice, this list of conditions and the following disclaimer.
10144518Sdavidxu * 2. Redistributions in binary form must reproduce the above copyright
11144518Sdavidxu *    notice, this list of conditions and the following disclaimer in the
12144518Sdavidxu *    documentation and/or other materials provided with the distribution.
13144518Sdavidxu *
14144518Sdavidxu * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15144518Sdavidxu * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16144518Sdavidxu * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17144518Sdavidxu * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18144518Sdavidxu * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19144518Sdavidxu * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20144518Sdavidxu * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21144518Sdavidxu * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22144518Sdavidxu * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23144518Sdavidxu * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24144518Sdavidxu * SUCH DAMAGE.
25144518Sdavidxu *
26144518Sdavidxu * $FreeBSD: head/sys/i386/bios/mca_machdep.c 50824 1999-09-03 03:14:36Z mdodd $
27144518Sdavidxu */
28144518Sdavidxu
29144518Sdavidxu#include "mca.h"
30144518Sdavidxu#if NMCA > 0
31144518Sdavidxu
32144518Sdavidxu#include <sys/param.h>
33144518Sdavidxu#include <sys/systm.h>
34144518Sdavidxu#include <sys/kernel.h>
35144518Sdavidxu#include <vm/vm.h>
36144518Sdavidxu#include <vm/pmap.h>
37144518Sdavidxu#include <machine/pmap.h>
38144518Sdavidxu#include <machine/md_var.h>
39144518Sdavidxu#include <machine/vm86.h>
40144518Sdavidxu#include <machine/pc/bios.h>
41144518Sdavidxu#include <machine/cpufunc.h>
42144518Sdavidxu
43144518Sdavidxu#include <dev/mca/mca_busreg.h>
44144518Sdavidxu#include <i386/isa/mca_machdep.h>
45144518Sdavidxu
46144518Sdavidxu/* Global MCA bus flag */
47144518Sdavidxuint MCA_system = 0;
48144518Sdavidxu
49144518Sdavidxu/* System Configuration Block */
50144518Sdavidxustruct sys_config {
51144518Sdavidxu	u_int16_t	count;
52144518Sdavidxu	u_int8_t	model;
53144518Sdavidxu	u_int8_t	submodel;
54144518Sdavidxu	u_int8_t	bios_rev;
55144518Sdavidxu	u_int8_t	feature;
56144518Sdavidxu#define FEATURE_RESV	0x01	/* Reserved				*/
57144518Sdavidxu#define FEATURE_MCABUS	0x02	/* MicroChannel Architecture		*/
58144518Sdavidxu#define FEATURE_EBDA	0x04	/* Extended BIOS data area allocated	*/
59144518Sdavidxu#define FEATURE_WAITEV	0x08	/* Wait for external event is supported	*/
60144518Sdavidxu#define FEATURE_KBDINT	0x10	/* Keyboard intercept called by Int 09h	*/
61144518Sdavidxu#define FEATURE_RTC	0x20	/* Real-time clock present		*/
62144518Sdavidxu#define FEATURE_IC2	0x40	/* Second interrupt chip present	*/
63157457Sdavidxu#define FEATURE_DMA3	0x80	/* DMA channel 3 used by hard disk BIOS	*/
64144518Sdavidxu	u_int8_t	pad[3];
65144518Sdavidxu} __attribute__ ((packed));
66144518Sdavidxu
67144518Sdavidxu/* Function Prototypes */
68144518Sdavidxustatic void bios_mcabus_present	(void *);
69144518SdavidxuSYSINIT(mca_present, SI_SUB_CPU, SI_ORDER_ANY, bios_mcabus_present, NULL);
70157457Sdavidxu
71144518Sdavidxu/* Functions */
72144518Sdavidxustatic void
73144518Sdavidxubios_mcabus_present(void * dummy)
74144518Sdavidxu{
75144518Sdavidxu	struct vm86frame	vmf;
76144518Sdavidxu	struct sys_config *	scp;
77144518Sdavidxu	vm_offset_t		paddr;
78144518Sdavidxu
79144518Sdavidxu	bzero(&vmf, sizeof(struct vm86frame));
80144518Sdavidxu
81144518Sdavidxu	vmf.vmf_ah = 0xc0;
82144518Sdavidxu	if (vm86_intcall(0x15, &vmf)) {
83144518Sdavidxu		if (bootverbose) {
84144518Sdavidxu			printf("BIOS SDT: INT call failed.\n");
85144518Sdavidxu		}
86144518Sdavidxu		return;
87144518Sdavidxu	}
88144518Sdavidxu
89144518Sdavidxu	if ((vmf.vmf_ah != 0) && (vmf.vmf_flags != 0)) {
90144518Sdavidxu		if (bootverbose) {
91144518Sdavidxu			printf("BIOS SDT: Not supported.  Not PS/2?\n");
92144518Sdavidxu			printf("BIOS SDT: AH 0x%02x, Flags 0x%04x\n",
93144518Sdavidxu				vmf.vmf_ah, vmf.vmf_flags);
94144518Sdavidxu		}
95144518Sdavidxu		return;
96144518Sdavidxu	}
97144518Sdavidxu
98144518Sdavidxu	paddr = vmf.vmf_es;
99144518Sdavidxu	paddr = (paddr << 4) + vmf.vmf_bx;
100144518Sdavidxu	scp = (struct sys_config *)BIOS_PADDRTOVADDR(paddr);
101157457Sdavidxu
102157457Sdavidxu	if (bootverbose) {
103144518Sdavidxu		printf("BIOS SDT: model 0x%02x, submodel 0x%02x, bios_rev 0x%02x\n",
104144518Sdavidxu			scp->model, scp->submodel, scp->bios_rev);
105144518Sdavidxu		printf("BIOS SDT: features 0x%b\n", scp->feature,
106144518Sdavidxu			"\20"
107144518Sdavidxu			"\01RESV"
108144518Sdavidxu			"\02MCABUS"
109144518Sdavidxu			"\03EBDA"
110144518Sdavidxu			"\04WAITEV"
111144518Sdavidxu			"\05KBDINT"
112144518Sdavidxu			"\06RTC"
113144518Sdavidxu			"\07IC2"
114144518Sdavidxu			"\08DMA3\n");
115144518Sdavidxu	}
116144518Sdavidxu
117144518Sdavidxu	MCA_system = ((scp->feature & FEATURE_MCABUS) ? 1 : 0);
118144518Sdavidxu
119144518Sdavidxu	if (MCA_system)
120144518Sdavidxu		printf("MicroChannel Architecture System detected.\n");
121144518Sdavidxu
122144518Sdavidxu	return;
123144518Sdavidxu}
124144518Sdavidxu
125144518Sdavidxuint
126144518Sdavidxumca_bus_nmi (void)
127144518Sdavidxu{
128144518Sdavidxu	int	slot;
129144518Sdavidxu	int	retval = 0;
130154248Sjasone	int	pos5 = 0;
131144518Sdavidxu
132154248Sjasone	/* Disable motherboard setup */
133144518Sdavidxu	outb(MCA_MB_SETUP_REG, MCA_MB_SETUP_DIS);
134144518Sdavidxu
135144518Sdavidxu	/* For each slot */
136144518Sdavidxu	for (slot = 0; slot < MCA_MAX_SLOTS; slot++) {
137153987Sdavidxu
138153987Sdavidxu		/* Select the slot */
139153987Sdavidxu		outb(MCA_ADAP_SETUP_REG, slot | MCA_ADAP_SET);
140153987Sdavidxu		pos5 = inb(MCA_POS_REG(MCA_POS5));
141153987Sdavidxu
142144518Sdavidxu		/* If Adapter Check is low */
143144518Sdavidxu		if ((pos5 & MCA_POS5_CHCK) == 0) {
144144518Sdavidxu			retval++;
145144518Sdavidxu
146144518Sdavidxu			/* If Adapter Check Status is available */
147144518Sdavidxu			if ((pos5 & MCA_POS5_CHCK_STAT) == 0) {
148144518Sdavidxu				printf("MCA NMI: slot %d, POS6=0x%02x, POS7=0x%02x\n",
149144518Sdavidxu					slot+1,
150144518Sdavidxu					inb( MCA_POS_REG(MCA_POS6) ),
151144518Sdavidxu					inb( MCA_POS_REG(MCA_POS7) ));
152144518Sdavidxu			} else {
153144518Sdavidxu				printf("MCA NMI: slot %d\n", slot+1);
154144518Sdavidxu			}
155144518Sdavidxu		}
156144518Sdavidxu		/* Disable adapter setup */
157144518Sdavidxu		outb(MCA_ADAP_SETUP_REG, MCA_ADAP_SETUP_DIS);
158144518Sdavidxu	}
159144518Sdavidxu
160144518Sdavidxu	return (retval);
161154248Sjasone}
162144518Sdavidxu#endif
163144518Sdavidxu