forked from SanseroGames/LetsGo-OS
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserial.go
98 lines (82 loc) · 2.29 KB
/
serial.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package main
import (
"syscall"
)
const (
COM1_PORT uint16 = 0x3F8
COM1_IRQ uint8 = 0x4
)
var (
serialDevice UARTSerialDevice
)
type UARTSerialDevice struct {
BasePort uint16
initialized bool
}
func (d UARTSerialDevice) isInitialized() bool {
return d.initialized
}
func (d UARTSerialDevice) is_transmit_empty() bool {
return d.initialized && Inb(d.BasePort+5)&0x20 != 0
}
func (d UARTSerialDevice) WriteChar(arg byte) {
if d.isInitialized() == false {
return
}
for d.is_transmit_empty() == false {
}
Outb(d.BasePort, arg)
}
func (d UARTSerialDevice) Write(arr []byte) (int, error) {
if d.isInitialized() == false {
kernelPanic("DEBUG: Serial Device not initialized")
}
for _, v := range arr {
if v == '\n' {
// Make serial look correct
d.WriteChar('\r')
}
d.WriteChar(v)
}
return len(arr), nil
}
func (d UARTSerialDevice) HasReceivedData() bool {
return Inb(d.BasePort+5)&1 == 1
}
func (d UARTSerialDevice) Read() uint8 {
return Inb(d.BasePort)
}
func (d *UARTSerialDevice) Initialize() syscall.Errno {
if d.BasePort == 0 {
return syscall.ENOSYS
}
Outb(d.BasePort+1, 0x00) // Disable all interrupts
Outb(d.BasePort+3, 0x80) // Enable DLAB (set baud rate divisor)
Outb(d.BasePort+0, 0x03) // Set divisor to 3 (lo byte) 38400 baud
Outb(d.BasePort+1, 0x00) // (hi byte)
Outb(d.BasePort+3, 0x03) // 8 bits, no parity, one stop bit, disable DLAB
Outb(d.BasePort+2, 0x07) // Enable FIFO, clear them, with 1-byte threshold
Outb(d.BasePort+4, 0x1E) // Set in loopback mode, test the serial chip
Outb(d.BasePort+0, 0xAE) // Test serial chip (send byte 0xAE and check if serial returns same byte)
// Check if serial is faulty (i.e: not same byte as sent)
if Inb(d.BasePort+0) != 0xAE {
return syscall.ENOSYS
}
// If serial is not faulty set it in normal operation mode
// (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled)
Outb(d.BasePort+4, 0x00)
// Outb(d.BasePort+1, 0x01) // IRQs enabled, RTS/DSR set
d.initialized = true
return ESUCCESS
}
func InitSerialDevice() {
serialDevice = UARTSerialDevice{BasePort: COM1_PORT}
err := serialDevice.Initialize()
if err != ESUCCESS {
kernelPanic("Could not initialize serial device")
}
}
func InitSerialDeviceInterrupt() {
// RegisterPICHandler(COM1_IRQ, testInterrupt4)
// EnableIRQ(COM1_IRQ)
}