1use core::arch::asm;
4
5#[inline]
10pub unsafe fn outb(port: u16, val: u8) {
11 asm!("outb %al, %dx", in("al") val, in("dx") port, options(att_syntax));
12}
13
14#[inline]
19pub unsafe fn inb(port: u16) -> u8 {
20 let ret: u8;
21 asm!("inb %dx, %al", in("dx") port, out("al") ret, options(att_syntax));
22 ret
23}
24
25#[inline]
30pub unsafe fn outw(port: u16, val: u16) {
31 asm!("outw %ax, %dx", in("ax") val, in("dx") port, options(att_syntax));
32}
33
34#[inline]
39pub unsafe fn inw(port: u16) -> u16 {
40 let ret: u16;
41 asm!("inw %dx, %ax", in("dx") port, out("ax") ret, options(att_syntax));
42 ret
43}
44
45#[inline]
50pub unsafe fn outl(port: u16, val: u32) {
51 asm!("outl %eax, %dx", in("eax") val, in("dx") port, options(att_syntax));
52}
53
54#[inline]
59pub unsafe fn inl(port: u16) -> u32 {
60 let ret: u32;
61 asm!("inl %dx, %eax", out("eax") ret, in("dx") port, options(att_syntax));
62 ret
63}
64
65#[cfg(all(test, feature = "vmtest"))]
66mod x86testing {
67 use super::*;
68 use x86test::*;
69
70 #[x86test(ioport(0x0, 0xaf))]
71 fn check_outb() {
72 unsafe {
73 outb(0x0, 0xaf);
74 }
76 }
77
78 #[x86test(ioport(0x0, 0xaf))]
79 #[should_panic]
80 fn check_outb_wrong_value() {
81 unsafe {
82 outb(0x0, 0xff);
83 }
84 }
85
86 #[x86test(ioport(0x1, 0xad))]
87 fn check_inb() {
88 unsafe {
89 kassert!(
90 inb(0x1) == 0xad,
91 "`inb` instruction didn't read the correct value"
92 );
93 }
94 }
95
96 #[x86test(ioport(0x2, 0xad))]
97 #[should_panic]
98 fn check_inb_wrong_port() {
99 unsafe {
100 kassert!(
101 inb(0x1) == 0xad,
102 "`inb` instruction didn't read the correct value"
103 );
104 }
105 }
106
107 #[x86test(ioport(0x2, 0x99))]
108 fn check_outw() {
109 unsafe {
110 super::outw(0x2, 0x99);
111 }
113 }
114
115 #[x86test(ioport(0x3, 0xfefe))]
116 fn check_inw() {
117 unsafe {
118 kassert!(
119 inw(0x3) == 0xfefe,
120 "`inw` instruction didn't read the correct value"
121 );
122 }
123 }
124
125 #[x86test(ioport(0x5, 0xbeefaaaa))]
126 fn check_outl() {
127 unsafe {
128 outl(0x5, 0xbeefaaaa);
129 }
131 }
132
133 #[x86test(ioport(0x4, 0xdeadbeef))]
134 fn check_inl() {
135 unsafe {
136 kassert!(
137 inl(0x4) == 0xdeadbeef,
138 "`inl` instruction didn't read the correct value"
139 );
140 }
141 }
142}