76 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			76 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
| Copyright (C) 2015-2019 The University of Notre Dame
 | |
| This software is distributed under the GNU General Public License.
 | |
| See the file LICENSE for details.
 | |
| */
 | |
| 
 | |
| #include "ioports.h"
 | |
| #include "kernel/types.h"
 | |
| #include "console.h"
 | |
| 
 | |
| #define PIC_ICW1 0x11
 | |
| #define PIC_ICW4_MASTER 0x01
 | |
| #define PIC_ICW4_SLAVE  0x05
 | |
| #define PIC_ACK_SPECIFIC 0x60
 | |
| 
 | |
| static uint8_t pic_control[2] = { 0x20, 0xa0 };
 | |
| static uint8_t pic_data[2] = { 0x21, 0xa1 };
 | |
| 
 | |
| void pic_init(int pic0base, int pic1base)
 | |
| {
 | |
| 	outb(PIC_ICW1, pic_control[0]);
 | |
| 	outb(pic0base, pic_data[0]);
 | |
| 	outb(1 << 2, pic_data[0]);
 | |
| 	outb(PIC_ICW4_MASTER, pic_data[0]);
 | |
| 	outb(~(1 << 2), pic_data[0]);
 | |
| 
 | |
| 	outb(PIC_ICW1, pic_control[1]);
 | |
| 	outb(pic1base, pic_data[1]);
 | |
| 	outb(2, pic_data[1]);
 | |
| 	outb(PIC_ICW4_SLAVE, pic_data[1]);
 | |
| 	outb(~0, pic_data[1]);
 | |
| 
 | |
| 	printf("pic: ready\n");
 | |
| }
 | |
| 
 | |
| void pic_enable(uint8_t irq)
 | |
| {
 | |
| 	uint8_t mask;
 | |
| 	if(irq < 8) {
 | |
| 		mask = inb(pic_data[0]);
 | |
| 		mask = mask & ~(1 << irq);
 | |
| 		outb(mask, pic_data[0]);
 | |
| 	} else {
 | |
| 		irq -= 8;
 | |
| 		mask = inb(pic_data[1]);
 | |
| 		mask = mask & ~(1 << irq);
 | |
| 		outb(mask, pic_data[1]);
 | |
| 		pic_enable(2);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| void pic_disable(uint8_t irq)
 | |
| {
 | |
| 	uint8_t mask;
 | |
| 	if(irq < 8) {
 | |
| 		mask = inb(pic_data[0]);
 | |
| 		mask = mask | (1 << irq);
 | |
| 		outb(mask, pic_data[0]);
 | |
| 	} else {
 | |
| 		irq -= 8;
 | |
| 		mask = inb(pic_data[1]);
 | |
| 		mask = mask | (1 << irq);
 | |
| 		outb(mask, pic_data[1]);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| void pic_acknowledge(uint8_t irq)
 | |
| {
 | |
| 	if(irq >= 8) {
 | |
| 		outb(PIC_ACK_SPECIFIC + (irq - 8), pic_control[1]);
 | |
| 		outb(PIC_ACK_SPECIFIC + (2), pic_control[0]);
 | |
| 	} else {
 | |
| 		outb(PIC_ACK_SPECIFIC + irq, pic_control[0]);
 | |
| 	}
 | |
| }
 |