11use crate :: device:: {
2- DeviceRegion , EmulatedDevice , Port , PortReadRequest , PortWriteRequest ,
2+ DeviceRegion , EmulatedDevice , InterruptArray , Port , PortReadRequest ,
3+ PortWriteRequest ,
34} ;
45use crate :: error:: Result ;
56use crate :: logger;
@@ -44,8 +45,7 @@ impl ComDevice {
4445 base_port,
4546 buff : vec ! [ ] ,
4647
47- // For now, transmitter holding register is always empty
48- interrupt_identification_register : 0x02 ,
48+ interrupt_identification_register : 0x01 ,
4949
5050 ..Default :: default ( )
5151 } )
@@ -66,7 +66,7 @@ impl EmulatedDevice for ComDevice {
6666 port : Port ,
6767 mut val : PortReadRequest ,
6868 _space : GuestAddressSpaceViewMut ,
69- ) -> Result < ( ) > {
69+ ) -> Result < InterruptArray > {
7070 if port - self . base_port == SerialOffset :: DATA
7171 && self . divisor_latch_bit_set ( )
7272 {
@@ -79,23 +79,26 @@ impl EmulatedDevice for ComDevice {
7979
8080 if port - self . base_port == SerialOffset :: IIR {
8181 val. copy_from_u32 ( self . interrupt_identification_register as u32 ) ;
82+
83+ // Reading the IIR clears it (the LSB = 1 indicates there is _not_ a
84+ // pending interrupt)
85+ self . interrupt_identification_register = 1 ;
8286 } else if port - self . base_port == SerialOffset :: IER {
8387 val. copy_from_u32 ( self . interrupt_enable_register as u32 ) ;
8488 }
8589
8690 if port - self . base_port == SerialOffset :: LSR {
87- val. copy_from_u32 ( 0x20 ) ;
91+ val. copy_from_u32 ( 0x60 ) ;
8892 }
89-
90- Ok ( ( ) )
93+ Ok ( InterruptArray :: default ( ) )
9194 }
9295
9396 fn on_port_write (
9497 & mut self ,
9598 port : Port ,
9699 val : PortWriteRequest ,
97100 _space : GuestAddressSpaceViewMut ,
98- ) -> Result < ( ) > {
101+ ) -> Result < InterruptArray > {
99102 let val: u8 = val. try_into ( ) ?;
100103 if port - self . base_port == SerialOffset :: DATA {
101104 if self . divisor_latch_bit_set ( ) {
@@ -107,6 +110,12 @@ impl EmulatedDevice for ComDevice {
107110 logger:: write_console ( & format ! ( "GUEST{}: {}" , self . id, s) ) ;
108111 self . buff . clear ( ) ;
109112 }
113+ let mut arr = InterruptArray :: default ( ) ;
114+ if self . interrupt_enable_register & 0b00000010 == 0b10 {
115+ arr. push ( 52 ) ;
116+ }
117+ self . interrupt_identification_register = 0b10 ;
118+ return Ok ( arr) ;
110119 }
111120 } else if port - self . base_port == SerialOffset :: DLL
112121 && self . divisor_latch_bit_set ( )
@@ -120,6 +129,6 @@ impl EmulatedDevice for ComDevice {
120129 self . interrupt_enable_register = val;
121130 }
122131
123- Ok ( ( ) )
132+ Ok ( InterruptArray :: default ( ) )
124133 }
125134}
0 commit comments