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  }