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
const COM1: u16 = 0x3F8;
pub unsafe fn init_bootstrap_log() {
let _data_port = COM1 + 0;
let interrupt_port = COM1 + 1;
let baud_diviser_lo = COM1 + 0;
let baud_diviser_hi = COM1 + 1;
let fifo_port = COM1 + 2;
let lcr_port = COM1 + 3;
let _mcr_port = COM1 + 4;
let _status_port = COM1 + 5;
bootstrap_outb(interrupt_port , 0x00);
bootstrap_outb(lcr_port , 0x80);
bootstrap_outb(baud_diviser_lo, 0x03);
bootstrap_outb(baud_diviser_hi, 0x00);
bootstrap_outb(lcr_port , 0x03);
bootstrap_outb(fifo_port , 0xC7);
}
pub fn bootstrap_log(string: &str) {
let status_port = COM1 + 5;
for byte in string.bytes() {
unsafe {
while bootstrap_inb(status_port) & 0x20 == 0 { }
bootstrap_outb(COM1, byte);
}
}
}
unsafe fn bootstrap_inb(port: u16) -> u8 {
let value: u8;
llvm_asm!("in $0, $1" : "={al}"(value) : "{dx}"(port) : "memory" : "intel", "volatile");
value
}
unsafe fn bootstrap_outb(port: u16, value: u8) {
llvm_asm!("out $1, $0" : : "{al}"(value), "{dx}"(port) : "memory" : "intel", "volatile");
}
pub struct Serial;
impl ::core::fmt::Write for Serial {
fn write_str(&mut self, s: &str) -> Result<(), ::core::fmt::Error> {
bootstrap_log(s);
Ok(())
}
}