github.com/icexin/eggos@v0.4.2-0.20220216025428-78b167e4f349/drivers/uart/uart.go (about) 1 package uart 2 3 import ( 4 "github.com/icexin/eggos/drivers/pic" 5 "github.com/icexin/eggos/kernel/sys" 6 "github.com/icexin/eggos/kernel/trap" 7 ) 8 9 const ( 10 com1 = uint16(0x3f8) 11 _IRQ_COM1 = pic.IRQ_BASE + pic.LINE_COM1 12 ) 13 14 var ( 15 inputCallback func(byte) 16 ) 17 18 //go:nosplit 19 func ReadByte() int { 20 if sys.Inb(com1+5)&0x01 == 0 { 21 return -1 22 } 23 return int(sys.Inb(com1 + 0)) 24 } 25 26 //go:nosplit 27 func WriteByte(ch byte) { 28 const lstatus = uint16(5) 29 for { 30 ret := sys.Inb(com1 + lstatus) 31 if ret&0x20 != 0 { 32 break 33 } 34 } 35 sys.Outb(com1, uint8(ch)) 36 } 37 38 //go:nosplit 39 func Write(s []byte) (int, error) { 40 for _, c := range s { 41 WriteByte(c) 42 } 43 return len(s), nil 44 } 45 46 //go:nosplit 47 func WriteString(s string) (int, error) { 48 for i := 0; i < len(s); i++ { 49 WriteByte(s[i]) 50 } 51 return len(s), nil 52 } 53 54 //go:nosplit 55 func intr() { 56 if inputCallback == nil { 57 return 58 } 59 for { 60 ch := ReadByte() 61 if ch == -1 { 62 break 63 } 64 inputCallback(byte(ch)) 65 } 66 pic.EOI(_IRQ_COM1) 67 } 68 69 //go:nosplit 70 func PreInit() { 71 sys.Outb(com1+3, 0x80) // unlock divisor 72 sys.Outb(com1+0, 115200/9600) 73 sys.Outb(com1+1, 0) 74 75 sys.Outb(com1+3, 0x03) // lock divisor 76 // disable fifo 77 sys.Outb(com1+2, 0) 78 79 // enable receive interrupt 80 sys.Outb(com1+4, 0x00) 81 sys.Outb(com1+1, 0x01) 82 } 83 84 func OnInput(callback func(byte)) { 85 inputCallback = callback 86 } 87 88 func Init() { 89 trap.Register(_IRQ_COM1, intr) 90 pic.EnableIRQ(pic.LINE_COM1) 91 }