xref: /csrg-svn/sys/i386/isa/isa.c (revision 49115)
1*49115Swilliam /*-
2*49115Swilliam  * Copyright (c) 1990 The Regents of the University of California.
3*49115Swilliam  * All rights reserved.
4*49115Swilliam  *
5*49115Swilliam  * This code is derived from software contributed to Berkeley by
6*49115Swilliam  * William Jolitz.
7*49115Swilliam  *
8*49115Swilliam  * %sccs.include.redist%
9*49115Swilliam  *
10*49115Swilliam  *	@(#)isa.c	1.4 (Berkeley) 05/04/91
11*49115Swilliam  */
12*49115Swilliam 
1345546Sbill /*
1445546Sbill  * code to manage AT bus
1545546Sbill  */
1645546Sbill 
1745546Sbill #include "param.h"
1845546Sbill #include "systm.h"
1945546Sbill #include "conf.h"
2045546Sbill #include "file.h"
2145546Sbill #include "user.h"
2245546Sbill #include "buf.h"
2345546Sbill #include "uio.h"
2445624Sbill #include "syslog.h"
2545624Sbill #include "machine/segments.h"
26*49115Swilliam #include "i386/isa/isa_device.h"
27*49115Swilliam #include "i386/isa/icu.h"
2845546Sbill 
2945624Sbill /*
3045624Sbill  * Configure all ISA devices
3145624Sbill  */
3245624Sbill isa_configure() {
3345624Sbill 	struct isa_device *dvp;
3445624Sbill 	struct isa_driver *dp;
3545624Sbill 
3645624Sbill 	splhigh();
3745624Sbill 	INTREN(IRQ_SLAVE);
3845624Sbill 	for (dvp = isa_devtab_bio; config_isadev(dvp,&biomask); dvp++);
3945624Sbill 	for (dvp = isa_devtab_tty; config_isadev(dvp,&ttymask); dvp++);
4045624Sbill 	for (dvp = isa_devtab_net; config_isadev(dvp,&netmask); dvp++);
4145624Sbill 	for (dvp = isa_devtab_null; config_isadev(dvp,0); dvp++);
4245624Sbill #include "sl.h"
4345624Sbill #if NSL > 0
4445624Sbill 	netmask |= ttymask;
4545624Sbill 	ttymask |= netmask;
4645624Sbill #endif
4745624Sbill 	/* biomask |= ttymask ;  can some tty devices use buffers? */
4845624Sbill 	printf("biomask %x ttymask %x netmask %x\n", biomask, ttymask, netmask);
4945624Sbill 	splnone();
5045624Sbill }
5145624Sbill 
5245624Sbill /*
5345624Sbill  * Configure an ISA device.
5445624Sbill  */
5545624Sbill config_isadev(isdp, mp)
5645624Sbill 	struct isa_device *isdp;
5745624Sbill 	int *mp;
5845624Sbill {
5945624Sbill 	struct isa_driver *dp;
6045624Sbill 
6145624Sbill 	if (dp = isdp->id_driver) {
6245624Sbill 		if (isdp->id_maddr) {
63*49115Swilliam 			extern int atdevbase;
6445624Sbill 
6545624Sbill 			isdp->id_maddr -= 0xa0000;
66*49115Swilliam 			isdp->id_maddr += atdevbase;
6745624Sbill 		}
6845624Sbill 		isdp->id_alive = (*dp->probe)(isdp);
6945624Sbill 		if (isdp->id_alive) {
7045624Sbill 			printf("%s%d", dp->name, isdp->id_unit);
7145624Sbill 			(*dp->attach)(isdp);
7245624Sbill 			printf(" at 0x%x ", isdp->id_iobase);
7345624Sbill 			if(isdp->id_irq) {
7445624Sbill 				int intrno;
7545624Sbill 
7645624Sbill 				intrno = ffs(isdp->id_irq)-1;
7745624Sbill 				printf("irq %d ", intrno);
7845624Sbill 				INTREN(isdp->id_irq);
7945624Sbill 				if(mp)INTRMASK(*mp,isdp->id_irq);
8045624Sbill 				setidt(ICU_OFFSET+intrno, isdp->id_intr,
8145624Sbill 					 SDT_SYS386IGT, SEL_KPL);
8245624Sbill 			}
8345624Sbill 			if (isdp->id_drq != -1) printf("drq %d ", isdp->id_drq);
8445624Sbill 			printf("on isa\n");
8545624Sbill 		}
8645624Sbill 		return (1);
8745624Sbill 	} else	return(0);
8845624Sbill }
8945624Sbill 
9045624Sbill #define	IDTVEC(name)	X/**/name
9145624Sbill /* default interrupt vector table */
9245624Sbill extern	IDTVEC(intr0), IDTVEC(intr1), IDTVEC(intr2), IDTVEC(intr3),
9345624Sbill 	IDTVEC(intr4), IDTVEC(intr5), IDTVEC(intr6), IDTVEC(intr7),
9445624Sbill 	IDTVEC(intr8), IDTVEC(intr9), IDTVEC(intr10), IDTVEC(intr11),
9545624Sbill 	IDTVEC(intr12), IDTVEC(intr13), IDTVEC(intr14), IDTVEC(intr15);
9645624Sbill 
9745624Sbill /*
9845624Sbill  * Fill in default interrupt table (in case of spuruious interrupt
9945624Sbill  * during configuration of kernel, setup interrupt control unit
10045624Sbill  */
10145624Sbill isa_defaultirq() {
10245624Sbill 
10345624Sbill /* first icu */
10445624Sbill 	setidt(32, &IDTVEC(intr0),  SDT_SYS386IGT, SEL_KPL);
10545624Sbill 	setidt(33, &IDTVEC(intr1),  SDT_SYS386IGT, SEL_KPL);
10645624Sbill 	setidt(34, &IDTVEC(intr2),  SDT_SYS386IGT, SEL_KPL);
10745624Sbill 	setidt(35, &IDTVEC(intr3),  SDT_SYS386IGT, SEL_KPL);
10845624Sbill 	setidt(36, &IDTVEC(intr4),  SDT_SYS386IGT, SEL_KPL);
10945624Sbill 	setidt(37, &IDTVEC(intr5),  SDT_SYS386IGT, SEL_KPL);
11045624Sbill 	setidt(38, &IDTVEC(intr6),  SDT_SYS386IGT, SEL_KPL);
11145624Sbill 	setidt(39, &IDTVEC(intr7),  SDT_SYS386IGT, SEL_KPL);
11245624Sbill 
11345624Sbill /* second icu */
11445624Sbill 	setidt(40, &IDTVEC(intr8),  SDT_SYS386IGT, SEL_KPL);
11545624Sbill 	setidt(41, &IDTVEC(intr9),  SDT_SYS386IGT, SEL_KPL);
11645624Sbill 	setidt(42, &IDTVEC(intr10),  SDT_SYS386IGT, SEL_KPL);
11745624Sbill 	setidt(43, &IDTVEC(intr11),  SDT_SYS386IGT, SEL_KPL);
11845624Sbill 	setidt(44, &IDTVEC(intr12),  SDT_SYS386IGT, SEL_KPL);
11945624Sbill 	setidt(45, &IDTVEC(intr13),  SDT_SYS386IGT, SEL_KPL);
12045624Sbill 	setidt(46, &IDTVEC(intr14),  SDT_SYS386IGT, SEL_KPL);
12145624Sbill 	setidt(47, &IDTVEC(intr15),  SDT_SYS386IGT, SEL_KPL);
12245624Sbill 
12345624Sbill 	/* initialize 8259's */
12445624Sbill 	outb(0xf1,0);
12545624Sbill 	outb(0x20,0x11);
12645624Sbill 	outb(0x21,32);
12745624Sbill 	outb(0x21,4);
12845624Sbill 	outb(0x21,1);
12945624Sbill 	outb(0x21,0xff);
13045624Sbill 
13145624Sbill 	outb(0xa0,0x11);
13245624Sbill 	outb(0xa1,40);
13345624Sbill 	outb(0xa1,2);
13445624Sbill 	outb(0xa1,1);
13545624Sbill 	outb(0xa1,0xff);
13645624Sbill }
13745624Sbill 
13845546Sbill /* stuff needed for virtual to physical calculations */
13945546Sbill extern char Sysbase;
14045546Sbill static unsigned long sbase = (unsigned long) &Sysbase;
14145546Sbill 
14245546Sbill struct buf *dma_bounce[8];
14345546Sbill #define MAXDMASZ 512
14445546Sbill 
14545546Sbill /* XXX temporary */
14645546Sbill kernel_space(x)
14745546Sbill unsigned long x;
14845546Sbill {
14945546Sbill 	if ((x >= sbase) & (x < sbase + 0x800000)) return 1;
15045546Sbill 	else return 0;
15145546Sbill }
15245546Sbill 
15345546Sbill 
15445546Sbill /****************************************************************************/
15545546Sbill /*                                 at_dma                                   */
15645546Sbill /* set up DMA read/write operation and virtual address addr for nbytes      */
15745546Sbill /****************************************************************************/
15845546Sbill at_dma(read,addr,nbytes, chan)
15945546Sbill int read;
16045546Sbill unsigned long addr;
16145546Sbill int nbytes;
16245546Sbill {
16345546Sbill 	unsigned long phys;
16445546Sbill 	int s,raw;
16545546Sbill 	caddr_t bounce;
16645546Sbill 
16745546Sbill 	if (kernel_space(addr)) raw = 0;
16845546Sbill 	else raw = 1;
16945546Sbill 
17045546Sbill 	if(raw) {
17145546Sbill 		if (dma_bounce[chan] == 0)
17245546Sbill 			dma_bounce[chan] = geteblk(MAXDMASZ);
17345546Sbill 		bounce = dma_bounce[chan]->b_un.b_addr;
17445546Sbill 	}
17545546Sbill 
17645546Sbill 	/* copy bounce buffer on write */
17745546Sbill 	if (raw && !read) bcopy(addr,bounce,nbytes);
17845546Sbill 
17945546Sbill 	/* Set read/write bytes */
18045546Sbill 	if (read) {
18145546Sbill 		outb(0xC,0x46); outb(0xB,0x46);
18245546Sbill 	} else {
18345546Sbill 		outb(0xC,0x4A); outb(0xB,0x4A);
18445546Sbill 	}
18545546Sbill 	/* Send start address */
18645546Sbill 	if (raw) phys = (unsigned long) bounce;
18745546Sbill 	else phys = addr;
18845546Sbill 	/* translate to physical */
18945546Sbill 	phys = phys - sbase;
19045546Sbill 	outb(0x4,phys & 0xFF);
19145546Sbill 	outb(0x4,(phys>>8) & 0xFF);
19245546Sbill 	outb(0x81,(phys>>16) & 0xFF);
19345546Sbill 	/* Send count */
19445546Sbill 	nbytes--;
19545546Sbill 	outb(0x5,nbytes & 0xFF);
19645546Sbill 	outb(0x5,(nbytes>>8) & 0xFF);
19745546Sbill 	/* set channel 2 */
19845546Sbill 	outb(0x0A,chan);
19945546Sbill }
20045624Sbill 
20145624Sbill /*
20245624Sbill  * Handle a NMI, possibly a machine check.
20345624Sbill  * return true to panic system, false to ignore.
20445624Sbill  */
20545624Sbill isa_nmi(cd) {
20645624Sbill 
20745624Sbill 	log(LOG_CRIT, "\nNMI port 61 %x, port 70 %x\n", inb(0x61), inb(0x70));
20845624Sbill 	return(0);
20945624Sbill }
21045624Sbill 
21145624Sbill /*
21245624Sbill  * Caught a stray interrupt, notify
21345624Sbill  */
21445624Sbill isa_strayintr(d) {
21545624Sbill 
21645624Sbill 	/* for some reason, we get bursts of intr #7, even if not enabled! */
21745624Sbill 	log(LOG_ERR,"ISA strayintr %d", ffs(d)-1);
21845624Sbill }
219