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