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]); | ||
|  | 	} | ||
|  | } |