]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/i386/bios/mca_machdep.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / sys / i386 / bios / mca_machdep.c
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
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
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 }