xref: /NextBSD/sys/i386/bios/mca_machdep.c (revision eb1a5f8de9f7ea602c373a710f531abbf81141c4)
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 
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29 
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/kernel.h>
33 #include <vm/vm.h>
34 #include <vm/vm_param.h>
35 #include <vm/pmap.h>
36 #include <machine/pmap.h>
37 #include <machine/md_var.h>
38 #include <machine/vm86.h>
39 #include <machine/pc/bios.h>
40 #include <machine/cpufunc.h>
41 
42 #include <dev/mca/mca_busreg.h>
43 #include <i386/bios/mca_machdep.h>
44 
45 /* Global MCA bus flag */
46 int MCA_system = 0;
47 
48 /* System Configuration Block */
49 struct sys_config {
50 	u_int16_t	count;
51 	u_int8_t	model;
52 	u_int8_t	submodel;
53 	u_int8_t	bios_rev;
54 	u_int8_t	feature;
55 #define FEATURE_MCAISA	0x01	/* Machine contains both MCA and ISA bus*/
56 #define FEATURE_MCABUS	0x02	/* MicroChannel Architecture		*/
57 #define FEATURE_EBDA	0x04	/* Extended BIOS data area allocated	*/
58 #define FEATURE_WAITEV	0x08	/* Wait for external event is supported	*/
59 #define FEATURE_KBDINT	0x10	/* Keyboard intercept called by Int 09h	*/
60 #define FEATURE_RTC	0x20	/* Real-time clock present		*/
61 #define FEATURE_IC2	0x40	/* Second interrupt chip present	*/
62 #define FEATURE_DMA3	0x80	/* DMA channel 3 used by hard disk BIOS	*/
63 	u_int8_t	pad[3];
64 } __packed;
65 
66 /* Function Prototypes */
67 static void bios_mcabus_present	(void *);
68 SYSINIT(mca_present, SI_SUB_CPU, SI_ORDER_ANY, bios_mcabus_present, NULL);
69 
70 /* Functions */
71 static void
bios_mcabus_present(void * dummy)72 bios_mcabus_present(void * dummy)
73 {
74 	struct vm86frame	vmf;
75 	struct sys_config *	scp;
76 	vm_offset_t		paddr;
77 
78 	bzero(&vmf, sizeof(struct vm86frame));
79 
80 	vmf.vmf_ah = 0xc0;
81 	if (vm86_intcall(0x15, &vmf)) {
82 		if (bootverbose) {
83 			printf("BIOS SDT: INT call failed.\n");
84 		}
85 		return;
86 	}
87 
88 	if ((vmf.vmf_ah != 0) && (vmf.vmf_flags & 0x01)) {
89 		if (bootverbose) {
90 			printf("BIOS SDT: Not supported.  Not PS/2?\n");
91 			printf("BIOS SDT: AH 0x%02x, Flags 0x%04x\n",
92 				vmf.vmf_ah, vmf.vmf_flags);
93 		}
94 		return;
95 	}
96 
97 	paddr = vmf.vmf_es;
98 	paddr = (paddr << 4) + vmf.vmf_bx;
99 	scp = (struct sys_config *)BIOS_PADDRTOVADDR(paddr);
100 
101 	if (bootverbose) {
102 		printf("BIOS SDT: model 0x%02x, submodel 0x%02x, bios_rev 0x%02x\n",
103 			scp->model, scp->submodel, scp->bios_rev);
104 		printf("BIOS SDT: features 0x%b\n", scp->feature,
105 			"\20"
106 			"\01MCA+ISA"
107 			"\02MCA"
108 			"\03EBDA"
109 			"\04WAITEV"
110 			"\05KBDINT"
111 			"\06RTC"
112 			"\07IC2"
113 			"\08DMA3"
114 			"\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 
125 int
mca_bus_nmi(void)126 mca_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