Initial import from FreeBSD RELENG_4:
[dragonfly.git] / sys / platform / pc32 / 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  * $FreeBSD: src/sys/i386/bios/mca_machdep.c,v 1.4 2000/01/29 16:17:34 peter Exp $
27  */
28
29 #include <sys/param.h>
30 #include <sys/systm.h>
31 #include <sys/kernel.h>
32 #include <vm/vm.h>
33 #include <vm/pmap.h>
34 #include <machine/pmap.h>
35 #include <machine/md_var.h>
36 #include <machine/vm86.h>
37 #include <machine/pc/bios.h>
38 #include <machine/cpufunc.h>
39
40 #include <dev/mca/mca_busreg.h>
41 #include <i386/isa/mca_machdep.h>
42
43 /* Global MCA bus flag */
44 int MCA_system = 0;
45
46 /* System Configuration Block */
47 struct sys_config {
48         u_int16_t       count;
49         u_int8_t        model;
50         u_int8_t        submodel;
51         u_int8_t        bios_rev;
52         u_int8_t        feature;
53 #define FEATURE_RESV    0x01    /* Reserved                             */
54 #define FEATURE_MCABUS  0x02    /* MicroChannel Architecture            */
55 #define FEATURE_EBDA    0x04    /* Extended BIOS data area allocated    */
56 #define FEATURE_WAITEV  0x08    /* Wait for external event is supported */
57 #define FEATURE_KBDINT  0x10    /* Keyboard intercept called by Int 09h */
58 #define FEATURE_RTC     0x20    /* Real-time clock present              */
59 #define FEATURE_IC2     0x40    /* Second interrupt chip present        */
60 #define FEATURE_DMA3    0x80    /* DMA channel 3 used by hard disk BIOS */
61         u_int8_t        pad[3];
62 } __attribute__ ((packed));
63
64 /* Function Prototypes */
65 static void bios_mcabus_present (void *);
66 SYSINIT(mca_present, SI_SUB_CPU, SI_ORDER_ANY, bios_mcabus_present, NULL);
67
68 /* Functions */
69 static void
70 bios_mcabus_present(void * dummy)
71 {
72         struct vm86frame        vmf;
73         struct sys_config *     scp;
74         vm_offset_t             paddr;
75
76         bzero(&vmf, sizeof(struct vm86frame));
77
78         vmf.vmf_ah = 0xc0;
79         if (vm86_intcall(0x15, &vmf)) {
80                 if (bootverbose) {
81                         printf("BIOS SDT: INT call failed.\n");
82                 }
83                 return;
84         }
85
86         if ((vmf.vmf_ah != 0) && (vmf.vmf_flags & 0x01)) {
87                 if (bootverbose) {
88                         printf("BIOS SDT: Not supported.  Not PS/2?\n");
89                         printf("BIOS SDT: AH 0x%02x, Flags 0x%04x\n",
90                                 vmf.vmf_ah, vmf.vmf_flags);
91                 }
92                 return;
93         }
94
95         paddr = vmf.vmf_es;
96         paddr = (paddr << 4) + vmf.vmf_bx;
97         scp = (struct sys_config *)BIOS_PADDRTOVADDR(paddr);
98
99         if (bootverbose) {
100                 printf("BIOS SDT: model 0x%02x, submodel 0x%02x, bios_rev 0x%02x\n",
101                         scp->model, scp->submodel, scp->bios_rev);
102                 printf("BIOS SDT: features 0x%b\n", scp->feature,
103                         "\20"
104                         "\01RESV"
105                         "\02MCABUS"
106                         "\03EBDA"
107                         "\04WAITEV"
108                         "\05KBDINT"
109                         "\06RTC"
110                         "\07IC2"
111                         "\08DMA3\n");
112         }
113
114         MCA_system = ((scp->feature & FEATURE_MCABUS) ? 1 : 0);
115
116         if (MCA_system)
117                 printf("MicroChannel Architecture System detected.\n");
118
119         return;
120 }
121
122 int
123 mca_bus_nmi (void)
124 {
125         int     slot;
126         int     retval = 0;
127         int     pos5 = 0;
128
129         /* Disable motherboard setup */
130         outb(MCA_MB_SETUP_REG, MCA_MB_SETUP_DIS);
131
132         /* For each slot */
133         for (slot = 0; slot < MCA_MAX_SLOTS; slot++) {
134
135                 /* Select the slot */
136                 outb(MCA_ADAP_SETUP_REG, slot | MCA_ADAP_SET); 
137                 pos5 = inb(MCA_POS_REG(MCA_POS5));
138
139                 /* If Adapter Check is low */
140                 if ((pos5 & MCA_POS5_CHCK) == 0) {
141                         retval++;
142
143                         /* If Adapter Check Status is available */
144                         if ((pos5 & MCA_POS5_CHCK_STAT) == 0) {
145                                 printf("MCA NMI: slot %d, POS6=0x%02x, POS7=0x%02x\n",
146                                         slot+1,
147                                         inb( MCA_POS_REG(MCA_POS6) ),
148                                         inb( MCA_POS_REG(MCA_POS7) ));
149                         } else { 
150                                 printf("MCA NMI: slot %d\n", slot+1);
151                         }
152                 }
153                 /* Disable adapter setup */
154                 outb(MCA_ADAP_SETUP_REG, MCA_ADAP_SETUP_DIS);
155         }
156
157         return (retval);
158 }