github.com/icexin/eggos@v0.4.2-0.20220216025428-78b167e4f349/drivers/pic/pic.go (about) 1 package pic 2 3 import "github.com/icexin/eggos/kernel/sys" 4 5 const ( 6 PIC1_CMD = 0x20 7 PIC1_DATA = PIC1_CMD + 1 8 PIC2_CMD = 0xA0 9 PIC2_DATA = PIC2_CMD + 1 10 11 ICW4_8086 = 0x01 /* 8086/88 (MCS-80/85) mode */ 12 ICW4_AUTO = 0x02 /* Auto (normal) EOI */ 13 14 IRQ_BASE = 0x20 15 16 LINE_TIMER = 0 17 LINE_KBD = 1 18 LINE_COM1 = 4 19 LINE_COM2 = 3 20 LINE_MOUSE = 12 21 ) 22 23 //go:nosplit 24 func Init() { 25 // send init command 26 sys.Outb(PIC1_CMD, 0x11) 27 sys.Outb(PIC2_CMD, 0x11) 28 29 // set offset 30 sys.Outb(PIC1_DATA, IRQ_BASE) 31 sys.Outb(PIC2_DATA, IRQ_BASE+8) 32 33 // set master and slave chip 34 sys.Outb(PIC1_DATA, 0x4) 35 sys.Outb(PIC2_DATA, 0x2) 36 37 sys.Outb(PIC1_DATA, ICW4_8086) 38 sys.Outb(PIC2_DATA, ICW4_8086) 39 // sys.Outb(PIC1_DATA, ICW4_8086|ICW4_AUTO) 40 // sys.Outb(PIC2_DATA, ICW4_8086|ICW4_AUTO) 41 42 // disable all ints 43 sys.Outb(PIC1_DATA, 0xff) 44 sys.Outb(PIC2_DATA, 0xff) 45 46 // Enable slave intr pin on master 47 EnableIRQ(0x02) 48 } 49 50 //go:nosplit 51 func EnableIRQ(line uint16) { 52 var port uint16 = PIC1_DATA 53 if line >= 8 { 54 port = PIC2_DATA 55 line -= 8 56 } 57 sys.Outb(port, byte(sys.Inb(port)&^(1<<line))) 58 } 59 60 //go:nosplit 61 func DisableIRQ(line uint16) { 62 var port uint16 = PIC1_DATA 63 if line >= 8 { 64 port = PIC2_DATA 65 line -= 8 66 } 67 sys.Outb(port, byte(sys.Inb(port)|(1<<line))) 68 } 69 70 //go:nosplit 71 func EOI(irq uintptr) { 72 if irq >= 0x28 { 73 sys.Outb(PIC2_CMD, 0x20) 74 } 75 sys.Outb(PIC1_CMD, 0x20) 76 }