isa.c (775) | isa.c (798) |
---|---|
1/*- 2 * Copyright (c) 1991 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * William Jolitz. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 20 unchanged lines hidden (view full) --- 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * from: @(#)isa.c 7.2 (Berkeley) 5/13/91 | 1/*- 2 * Copyright (c) 1991 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * William Jolitz. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 20 unchanged lines hidden (view full) --- 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * from: @(#)isa.c 7.2 (Berkeley) 5/13/91 |
37 * $Id: isa.c,v 1.8 1993/11/14 23:53:32 ache Exp $ | 37 * $Id: isa.c,v 1.9 1993/11/17 00:21:03 ache Exp $ |
38 */ 39 40/* 41 * code to manage AT bus 42 * 43 * 92/08/18 Frank P. MacLachlan (fpm@crash.cts.com): 44 * Fixed uninitialized variable problem and added code to deal 45 * with DMA page boundaries in isa_dmarangecheck(). Fixed word 46 * mode DMA count compution and reorganized DMA setup code in 47 * isa_dmastart() 48 */ 49 50#include "param.h" | 38 */ 39 40/* 41 * code to manage AT bus 42 * 43 * 92/08/18 Frank P. MacLachlan (fpm@crash.cts.com): 44 * Fixed uninitialized variable problem and added code to deal 45 * with DMA page boundaries in isa_dmarangecheck(). Fixed word 46 * mode DMA count compution and reorganized DMA setup code in 47 * isa_dmastart() 48 */ 49 50#include "param.h" |
51#include "systm.h" | 51#include "systm.h" /* isn't it a joy */ 52#include "kernel.h" /* to have three of these */ |
52#include "conf.h" 53#include "file.h" 54#include "buf.h" 55#include "uio.h" 56#include "syslog.h" 57#include "malloc.h" 58#include "rlist.h" 59#include "machine/segments.h" --- 15 unchanged lines hidden (view full) --- 75/* 76** Register definitions for DMA controller 2 (channels 4..7): 77*/ 78#define DMA2_CHN(c) (IO_DMA2 + 2*(2*(c))) /* addr reg for channel c */ 79#define DMA2_SMSK (IO_DMA2 + 2*10) /* single mask register */ 80#define DMA2_MODE (IO_DMA2 + 2*11) /* mode register */ 81#define DMA2_FFC (IO_DMA2 + 2*12) /* clear first/last FF */ 82 | 53#include "conf.h" 54#include "file.h" 55#include "buf.h" 56#include "uio.h" 57#include "syslog.h" 58#include "malloc.h" 59#include "rlist.h" 60#include "machine/segments.h" --- 15 unchanged lines hidden (view full) --- 76/* 77** Register definitions for DMA controller 2 (channels 4..7): 78*/ 79#define DMA2_CHN(c) (IO_DMA2 + 2*(2*(c))) /* addr reg for channel c */ 80#define DMA2_SMSK (IO_DMA2 + 2*10) /* single mask register */ 81#define DMA2_MODE (IO_DMA2 + 2*11) /* mode register */ 82#define DMA2_FFC (IO_DMA2 + 2*12) /* clear first/last FF */ 83 |
83int config_isadev __P((struct isa_device *, u_int *)); | 84void config_isadev __P((struct isa_device *, u_int *)); |
84 85/* 86 * print a conflict message 87 */ 88void 89conflict(dvp, tmpdvp, item, reason, format) 90 struct isa_device *dvp, *tmpdvp; 91 int item; --- 153 unchanged lines hidden (view full) --- 245 /* biomask |= ttymask ; can some tty devices use buffers? */ 246 printf("biomask %x ttymask %x netmask %x\n", biomask, ttymask, netmask); 247 splnone(); 248} 249 250/* 251 * Configure an ISA device. 252 */ | 85 86/* 87 * print a conflict message 88 */ 89void 90conflict(dvp, tmpdvp, item, reason, format) 91 struct isa_device *dvp, *tmpdvp; 92 int item; --- 153 unchanged lines hidden (view full) --- 246 /* biomask |= ttymask ; can some tty devices use buffers? */ 247 printf("biomask %x ttymask %x netmask %x\n", biomask, ttymask, netmask); 248 splnone(); 249} 250 251/* 252 * Configure an ISA device. 253 */ |
254void |
|
253config_isadev(isdp, mp) 254 struct isa_device *isdp; 255 u_int *mp; 256{ 257 struct isa_driver *dp = isdp->id_driver; 258 259 if (isdp->id_maddr) { 260 extern u_int atdevbase; --- 72 unchanged lines hidden (view full) --- 333 334/* out of range default interrupt vector gate entry */ 335extern IDTVEC(intrdefault); 336 337/* 338 * Fill in default interrupt table (in case of spuruious interrupt 339 * during configuration of kernel, setup interrupt control unit 340 */ | 255config_isadev(isdp, mp) 256 struct isa_device *isdp; 257 u_int *mp; 258{ 259 struct isa_driver *dp = isdp->id_driver; 260 261 if (isdp->id_maddr) { 262 extern u_int atdevbase; --- 72 unchanged lines hidden (view full) --- 335 336/* out of range default interrupt vector gate entry */ 337extern IDTVEC(intrdefault); 338 339/* 340 * Fill in default interrupt table (in case of spuruious interrupt 341 * during configuration of kernel, setup interrupt control unit 342 */ |
341isa_defaultirq() { | 343void 344isa_defaultirq() 345{ |
342 int i; 343 344 /* icu vectors */ 345 for (i = NRSVIDT ; i < NRSVIDT+ICU_LEN ; i++) 346 setidt(i, defvec[i], SDT_SYS386IGT, SEL_KPL); 347 348 /* out of range vectors */ 349 for (i = NRSVIDT; i < NIDT; i++) --- 150 unchanged lines hidden (view full) --- 500 501/* 502 * Check for problems with the address range of a DMA transfer 503 * (non-contiguous physical pages, outside of bus address space, 504 * crossing DMA page boundaries). 505 * Return true if special handling needed. 506 */ 507 | 346 int i; 347 348 /* icu vectors */ 349 for (i = NRSVIDT ; i < NRSVIDT+ICU_LEN ; i++) 350 setidt(i, defvec[i], SDT_SYS386IGT, SEL_KPL); 351 352 /* out of range vectors */ 353 for (i = NRSVIDT; i < NIDT; i++) --- 150 unchanged lines hidden (view full) --- 504 505/* 506 * Check for problems with the address range of a DMA transfer 507 * (non-contiguous physical pages, outside of bus address space, 508 * crossing DMA page boundaries). 509 * Return true if special handling needed. 510 */ 511 |
512int |
|
508isa_dmarangecheck(caddr_t va, unsigned length, unsigned chan) { 509 vm_offset_t phys, priorpage = 0, endva; 510 u_int dma_pgmsk = (chan & 4) ? ~(128*1024-1) : ~(64*1024-1); 511 512 endva = (vm_offset_t)round_page(va + length); 513 for (; va < (caddr_t) endva ; va += NBPG) { 514 phys = trunc_page(pmap_extract(pmap_kernel(), (vm_offset_t)va)); 515#define ISARAM_END RAM_END --- 27 unchanged lines hidden (view full) --- 543 * (assumed to be called at splbio()) 544 */ 545caddr_t 546isa_allocphysmem(caddr_t va, unsigned length, void (*func)()) { 547 548 isaphysmemunblock = func; 549 while (isaphysmemflag & B_BUSY) { 550 isaphysmemflag |= B_WANTED; | 513isa_dmarangecheck(caddr_t va, unsigned length, unsigned chan) { 514 vm_offset_t phys, priorpage = 0, endva; 515 u_int dma_pgmsk = (chan & 4) ? ~(128*1024-1) : ~(64*1024-1); 516 517 endva = (vm_offset_t)round_page(va + length); 518 for (; va < (caddr_t) endva ; va += NBPG) { 519 phys = trunc_page(pmap_extract(pmap_kernel(), (vm_offset_t)va)); 520#define ISARAM_END RAM_END --- 27 unchanged lines hidden (view full) --- 548 * (assumed to be called at splbio()) 549 */ 550caddr_t 551isa_allocphysmem(caddr_t va, unsigned length, void (*func)()) { 552 553 isaphysmemunblock = func; 554 while (isaphysmemflag & B_BUSY) { 555 isaphysmemflag |= B_WANTED; |
551 tsleep(&isaphysmemflag, PRIBIO, "isaphys", 0); | 556 tsleep((caddr_t)&isaphysmemflag, PRIBIO, "isaphys", 0); |
552 } 553 isaphysmemflag |= B_BUSY; 554 555 return((caddr_t)isaphysmem); 556} 557 558/* 559 * Free contiguous physical memory used for transfer. 560 * (assumed to be called at splbio()) 561 */ 562void 563isa_freephysmem(caddr_t va, unsigned length) { 564 565 isaphysmemflag &= ~B_BUSY; 566 if (isaphysmemflag & B_WANTED) { 567 isaphysmemflag &= B_WANTED; | 557 } 558 isaphysmemflag |= B_BUSY; 559 560 return((caddr_t)isaphysmem); 561} 562 563/* 564 * Free contiguous physical memory used for transfer. 565 * (assumed to be called at splbio()) 566 */ 567void 568isa_freephysmem(caddr_t va, unsigned length) { 569 570 isaphysmemflag &= ~B_BUSY; 571 if (isaphysmemflag & B_WANTED) { 572 isaphysmemflag &= B_WANTED; |
568 wakeup(&isaphysmemflag); | 573 wakeup((caddr_t)&isaphysmemflag); |
569 if (isaphysmemunblock) 570 (*isaphysmemunblock)(); 571 } 572} 573 574/* 575 * Handle a NMI, possibly a machine check. 576 * return true to panic system, false to ignore. 577 */ | 574 if (isaphysmemunblock) 575 (*isaphysmemunblock)(); 576 } 577} 578 579/* 580 * Handle a NMI, possibly a machine check. 581 * return true to panic system, false to ignore. 582 */ |
578isa_nmi(cd) { | 583int 584isa_nmi(cd) 585 int cd; 586{ |
579 580 log(LOG_CRIT, "\nNMI port 61 %x, port 70 %x\n", inb(0x61), inb(0x70)); 581 return(0); 582} 583 584/* 585 * Caught a stray interrupt, notify 586 */ | 587 588 log(LOG_CRIT, "\nNMI port 61 %x, port 70 %x\n", inb(0x61), inb(0x70)); 589 return(0); 590} 591 592/* 593 * Caught a stray interrupt, notify 594 */ |
587isa_strayintr(d) { | 595void 596isa_strayintr(d) 597 int d; 598{ |
588 589 /* DON'T BOTHER FOR NOW! */ 590 /* for some reason, we get bursts of intr #7, even if not enabled! */ 591 /* 592 * Well the reason you got bursts of intr #7 is because someone 593 * raised an interrupt line and dropped it before the 8259 could 594 * prioritize it. This is documented in the intel data book. This 595 * means you have BAD hardware! I have changed this so that only --- 15 unchanged lines hidden (view full) --- 611 * (1 * TIMER_FREQ) Hz. 612 * Note: timer had better have been programmed before this is first used! 613 * (The standard programming causes the timer to generate a square wave and 614 * the counter is decremented twice every cycle.) 615 */ 616#define CF (1 * TIMER_FREQ) 617#define TIMER_FREQ 1193182 /* XXX - should be elsewhere */ 618 | 599 600 /* DON'T BOTHER FOR NOW! */ 601 /* for some reason, we get bursts of intr #7, even if not enabled! */ 602 /* 603 * Well the reason you got bursts of intr #7 is because someone 604 * raised an interrupt line and dropped it before the 8259 could 605 * prioritize it. This is documented in the intel data book. This 606 * means you have BAD hardware! I have changed this so that only --- 15 unchanged lines hidden (view full) --- 622 * (1 * TIMER_FREQ) Hz. 623 * Note: timer had better have been programmed before this is first used! 624 * (The standard programming causes the timer to generate a square wave and 625 * the counter is decremented twice every cycle.) 626 */ 627#define CF (1 * TIMER_FREQ) 628#define TIMER_FREQ 1193182 /* XXX - should be elsewhere */ 629 |
619extern int hz; /* XXX - should be elsewhere */ 620 621int DELAY(n) | 630void 631DELAY(n) |
622 int n; 623{ 624 int counter_limit; 625 int prev_tick; 626 int tick; 627 int ticks_left; 628 int sec; 629 int usec; --- 48 unchanged lines hidden (view full) --- 678 } 679#ifdef DELAYDEBUG 680 if (state == 1) 681 printf(" %d calls to getit() at %d usec each\n", 682 getit_calls, (n + 5) / getit_calls); 683#endif 684} 685 | 632 int n; 633{ 634 int counter_limit; 635 int prev_tick; 636 int tick; 637 int ticks_left; 638 int sec; 639 int usec; --- 48 unchanged lines hidden (view full) --- 688 } 689#ifdef DELAYDEBUG 690 if (state == 1) 691 printf(" %d calls to getit() at %d usec each\n", 692 getit_calls, (n + 5) / getit_calls); 693#endif 694} 695 |
686getit(unit, timer) { | 696int 697getit(unit, timer) 698 int unit; 699 int timer; 700{ |
687 int high; 688 int low; 689 690 /* 691 * XXX - isa.h defines bogus timers. There's no such timer as 692 * IO_TIMER_2 = 0x48. There's a timer in the CMOS RAM chip but 693 * its interface is quite different. Neither timer is an 8252. 694 * We actually only call this with unit = 0 and timer = 0. It --- 10 unchanged lines hidden (view full) --- 705 outb(IO_TIMER1 + 3, timer << 6); 706 707 low = inb(IO_TIMER1 + timer); 708 high = inb(IO_TIMER1 + timer); 709 enable_intr(); 710 return ((high << 8) | low); 711} 712 | 701 int high; 702 int low; 703 704 /* 705 * XXX - isa.h defines bogus timers. There's no such timer as 706 * IO_TIMER_2 = 0x48. There's a timer in the CMOS RAM chip but 707 * its interface is quite different. Neither timer is an 8252. 708 * We actually only call this with unit = 0 and timer = 0. It --- 10 unchanged lines hidden (view full) --- 719 outb(IO_TIMER1 + 3, timer << 6); 720 721 low = inb(IO_TIMER1 + timer); 722 high = inb(IO_TIMER1 + timer); 723 enable_intr(); 724 return ((high << 8) | low); 725} 726 |
713static beeping; 714static 715sysbeepstop(f) | 727static int beeping; 728 729static void 730sysbeepstop(f, dummy) 731 caddr_t f; 732 int dummy; |
716{ 717 /* disable counter 2 */ 718 outb(0x61, inb(0x61) & 0xFC); 719 if (f) | 733{ 734 /* disable counter 2 */ 735 outb(0x61, inb(0x61) & 0xFC); 736 if (f) |
720 timeout(sysbeepstop, 0, f); | 737 timeout(sysbeepstop, (caddr_t)0, (int)f); |
721 else 722 beeping = 0; 723} 724 | 738 else 739 beeping = 0; 740} 741 |
725void sysbeep(int pitch, int period) | 742void 743sysbeep(int pitch, int period) |
726{ 727 728 outb(0x61, inb(0x61) | 3); /* enable counter 2 */ 729 /* 730 * XXX - move timer stuff to clock.c. 731 * Program counter 2: 732 * ccaammmb, c counter, a = access, m = mode, b = BCD 733 * 1011x110, 11 for aa = LSB then MSB, x11 for mmm = square wave. 734 */ 735 outb(0x43, 0xb6); /* set command for counter 2, 2 byte write */ 736 737 outb(0x42, pitch); 738 outb(0x42, (pitch>>8)); 739 740 if (!beeping) { 741 beeping = period; | 744{ 745 746 outb(0x61, inb(0x61) | 3); /* enable counter 2 */ 747 /* 748 * XXX - move timer stuff to clock.c. 749 * Program counter 2: 750 * ccaammmb, c counter, a = access, m = mode, b = BCD 751 * 1011x110, 11 for aa = LSB then MSB, x11 for mmm = square wave. 752 */ 753 outb(0x43, 0xb6); /* set command for counter 2, 2 byte write */ 754 755 outb(0x42, pitch); 756 outb(0x42, (pitch>>8)); 757 758 if (!beeping) { 759 beeping = period; |
742 timeout(sysbeepstop, period/2, period); | 760 timeout(sysbeepstop, (caddr_t)(period/2), period); |
743 } 744} 745 746/* 747 * Pass command to keyboard controller (8042) 748 */ | 761 } 762} 763 764/* 765 * Pass command to keyboard controller (8042) 766 */ |
749unsigned kbc_8042cmd(val) { | 767unsigned 768kbc_8042cmd(val) 769 int val; 770{ |
750 751 while (inb(KBSTATP)&KBS_IBF); 752 if (val) outb(KBCMDP, val); 753 while (inb(KBSTATP)&KBS_IBF); 754 return (inb(KBDATAP)); 755} 756 757/* --- 41 unchanged lines hidden --- | 771 772 while (inb(KBSTATP)&KBS_IBF); 773 if (val) outb(KBCMDP, val); 774 while (inb(KBSTATP)&KBS_IBF); 775 return (inb(KBDATAP)); 776} 777 778/* --- 41 unchanged lines hidden --- |