fixed addr gdt, serial
parent
b0dffe7bc8
commit
988d3d601d
@ -0,0 +1,14 @@
|
|||||||
|
; flash seems to get mapped to ff000
|
||||||
|
; reset vector is f000:fff0 = ffff0
|
||||||
|
; so there's ff0 = 4080 bytes of something before the reset vector. what is it?
|
||||||
|
|
||||||
|
[bits 16]
|
||||||
|
[org 0xff000]
|
||||||
|
|
||||||
|
times (0xff0 - ($ - $$)) db 0x00
|
||||||
|
|
||||||
|
mov eax, 0xcafeface
|
||||||
|
hlt
|
||||||
|
|
||||||
|
times (0x1000 - ($ - $$)) db 0xf4
|
||||||
|
|
||||||
@ -0,0 +1,92 @@
|
|||||||
|
use core::{fmt, hint};
|
||||||
|
|
||||||
|
use crate::ioport;
|
||||||
|
|
||||||
|
pub struct Com {
|
||||||
|
port: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ComError;
|
||||||
|
|
||||||
|
impl Com {
|
||||||
|
pub unsafe fn init(port: u16) -> Result<Self, ComError> {
|
||||||
|
const ECHO_BYTE: u8 = 0x5a;
|
||||||
|
|
||||||
|
let echo = unsafe {
|
||||||
|
// Unset DLAB
|
||||||
|
ioport::outb(port + 3, 0x00);
|
||||||
|
// Disable interrupts
|
||||||
|
ioport::outb(port + 1, 0x00);
|
||||||
|
// Set DLAB
|
||||||
|
ioport::outb(port + 3, 0x80);
|
||||||
|
// Set baud rate divisor to 00 01 (115200)
|
||||||
|
ioport::outb(port + 0, 0x01);
|
||||||
|
ioport::outb(port + 1, 0x00);
|
||||||
|
// 8 bits, no parity, one stop bit
|
||||||
|
ioport::outb(port + 3, 0x03);
|
||||||
|
// Enable FIFO, clear them, with 14-byte threshold
|
||||||
|
ioport::outb(port + 2, 0xc7);
|
||||||
|
// IRQs enabled, RTS/DSR set
|
||||||
|
ioport::outb(port + 4, 0x0b);
|
||||||
|
// Set loopback mode
|
||||||
|
ioport::outb(port + 4, 0x1e);
|
||||||
|
ioport::outb(port + 0, ECHO_BYTE);
|
||||||
|
|
||||||
|
ioport::inb(port + 0)
|
||||||
|
};
|
||||||
|
|
||||||
|
if echo != ECHO_BYTE {
|
||||||
|
return Err(ComError);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
ioport::outb(port + 4, 0x0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
port,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn poll_has_data(&self) -> bool {
|
||||||
|
unsafe { ioport::inb(self.port + 5) & 0x01 != 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read_poll(&mut self) -> u8 {
|
||||||
|
while !self.poll_has_data() {
|
||||||
|
hint::spin_loop();
|
||||||
|
}
|
||||||
|
unsafe { ioport::inb(self.port) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn poll_has_space(&self) -> bool {
|
||||||
|
unsafe { ioport::inb(self.port + 5) & 0x20 != 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write_poll(&mut self, x: u8) {
|
||||||
|
while !self.poll_has_space() {
|
||||||
|
hint::spin_loop();
|
||||||
|
}
|
||||||
|
unsafe {
|
||||||
|
ioport::outb(self.port, x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Write for Com {
|
||||||
|
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||||
|
for b in s.bytes() {
|
||||||
|
self.write_poll(b);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_char(&mut self, c: char) -> fmt::Result {
|
||||||
|
let mut buf = [0u8; 4];
|
||||||
|
let s = c.encode_utf8(&mut buf);
|
||||||
|
for b in s.bytes() {
|
||||||
|
self.write_poll(b);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
use core::arch::asm;
|
||||||
|
|
||||||
|
pub unsafe fn inb(port: u16) -> u8 {
|
||||||
|
let x: u8;
|
||||||
|
unsafe {
|
||||||
|
asm!(
|
||||||
|
"in al, dx",
|
||||||
|
in("dx") port,
|
||||||
|
lateout("al") x
|
||||||
|
);
|
||||||
|
}
|
||||||
|
x
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn outb(port: u16, x: u8) {
|
||||||
|
unsafe {
|
||||||
|
asm!(
|
||||||
|
"out dx, al",
|
||||||
|
in("al") x,
|
||||||
|
in("dx") port,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue