aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTianhao Wang <wth@riseup.net>2024-02-01 22:01:25 +0100
committerTianhao Wang <shrik3@mailbox.org>2024-06-11 15:13:38 +0200
commitf857bd1d4f12316bd3434192d41c2489407c11a4 (patch)
tree7ccedde31f7c403f6afbda7cd547e7af20145ef6 /src
parent0ebc5ab0ee0fc80c801487f534687c8bd236abc1 (diff)
add IOPort struct
So that device IO can be be synchronized.
Diffstat (limited to 'src')
-rw-r--r--src/arch/x86_64/io_port.rs11
-rw-r--r--src/machine/cgascr.rs29
-rw-r--r--src/machine/device_io.rs20
3 files changed, 46 insertions, 14 deletions
diff --git a/src/arch/x86_64/io_port.rs b/src/arch/x86_64/io_port.rs
index 7b37989..cb6c80f 100644
--- a/src/arch/x86_64/io_port.rs
+++ b/src/arch/x86_64/io_port.rs
@@ -1,5 +1,9 @@
use core::arch::asm;
+// put a few cycles of delay after IO ops
+use super::misc::delay;
+
+#[inline(always)]
pub fn inw(p: u16) -> u16 {
let result: u16;
unsafe {
@@ -8,9 +12,11 @@ pub fn inw(p: u16) -> u16 {
out("ax") result
)
}
+ delay();
result
}
+#[inline(always)]
pub fn inb(p: u16) -> u8 {
let result: u8;
unsafe {
@@ -19,9 +25,11 @@ pub fn inb(p: u16) -> u8 {
out("al") result
)
}
+ delay();
result
}
+#[inline(always)]
pub fn outb(p: u16, val: u8) {
unsafe {
asm!("out dx, al",
@@ -29,8 +37,10 @@ pub fn outb(p: u16, val: u8) {
in("al") val,
)
}
+ delay();
}
+#[inline(always)]
pub fn outw(p: u16, val: u16) {
unsafe {
asm!("out dx, ax",
@@ -38,4 +48,5 @@ pub fn outw(p: u16, val: u16) {
in("ax") val,
)
}
+ delay();
}
diff --git a/src/machine/cgascr.rs b/src/machine/cgascr.rs
index 634373c..3004fb1 100644
--- a/src/machine/cgascr.rs
+++ b/src/machine/cgascr.rs
@@ -1,5 +1,5 @@
-use crate::machine::device_io::*;
use crate::arch::x86_64::misc::*;
+use crate::machine::device_io::*;
use core::{fmt, ptr, slice, str};
// TODO this is a "hard copy" of the c code, making little use
@@ -35,6 +35,8 @@ pub struct CGAScreen {
cursor_r: usize,
cursor_c: usize,
attr: u8,
+ iport: IOPort,
+ dport: IOPort,
}
#[allow(dead_code)]
@@ -47,6 +49,8 @@ impl CGAScreen {
cursor_r: 0,
cursor_c: 0,
attr: 0x0f,
+ iport: IOPort::new(IR_PORT),
+ dport: IOPort::new(DR_PORT),
}
}
@@ -161,34 +165,31 @@ impl CGAScreen {
// io ports for instruction register and data register
let offset = self.cal_offset(row, col);
// set lower byte
- outb(IR_PORT, 15 as u8);
- delay();
- outb(DR_PORT, offset as u8);
+ self.iport.outb(15 as u8);
delay();
+ self.dport.outb(offset as u8);
// set higher byte
- outb(IR_PORT, 14 as u8);
- delay();
- outb(DR_PORT, (offset >> 8) as u8);
- delay();
+ self.iport.outb(14 as u8);
+ self.dport.outb((offset >> 8) as u8);
self.cursor_r = row;
self.cursor_c = col;
}
pub fn getpos_xy(&self, row: &mut u32, col: &mut u32) {
- let offset = Self::getpos_offset();
+ let offset = self.getpos_offset();
*row = offset % MAX_COLS as u32;
*col = offset / MAX_COLS as u32;
}
#[allow(arithmetic_overflow)]
- pub fn getpos_offset() -> u32 {
+ pub fn getpos_offset(&self) -> u32 {
// read higher byte
- outb(IR_PORT, 14 as u8);
- let mut offset = inb(DR_PORT);
+ self.iport.outb(14 as u8);
+ let mut offset = self.dport.inb();
offset = offset << 8;
// read lower byte
- outb(IR_PORT, 15 as u8);
- offset += inb(DR_PORT);
+ self.iport.outb(15 as u8);
+ offset += self.dport.inb();
offset as u32
}
diff --git a/src/machine/device_io.rs b/src/machine/device_io.rs
index 4573653..2a0c907 100644
--- a/src/machine/device_io.rs
+++ b/src/machine/device_io.rs
@@ -1,2 +1,22 @@
#[cfg(target_arch = "x86_64")]
pub use crate::arch::x86_64::io_port::*;
+
+// either use the io functions directly, or via a IOPort instance.
+pub struct IOPort(u16);
+impl IOPort {
+ pub fn new(port: u16) -> Self {
+ Self(port)
+ }
+ pub fn inw(&self) -> u16 {
+ inw(self.0)
+ }
+ pub fn inb(&self) -> u8 {
+ inb(self.0)
+ }
+ pub fn outw(&self, val: u16) {
+ outw(self.0, val);
+ }
+ pub fn outb(&self, val: u8) {
+ outb(self.0, val);
+ }
+}