diff options
| author | Tianhao Wang <wth@riseup.net> | 2024-02-01 22:01:25 +0100 |
|---|---|---|
| committer | Tianhao Wang <shrik3@mailbox.org> | 2024-06-11 15:13:38 +0200 |
| commit | f857bd1d4f12316bd3434192d41c2489407c11a4 (patch) | |
| tree | 7ccedde31f7c403f6afbda7cd547e7af20145ef6 /src | |
| parent | 0ebc5ab0ee0fc80c801487f534687c8bd236abc1 (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.rs | 11 | ||||
| -rw-r--r-- | src/machine/cgascr.rs | 29 | ||||
| -rw-r--r-- | src/machine/device_io.rs | 20 |
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); + } +} |
