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