v86
v86 copied to clipboard
Windows 2000: serial port not working
How to reproduce:
- open Windows 2000 VM
- run cmd.exe (Start > Run > cmd)
- run this command:
type com1
I get this error: The system cannot find the file specified.
This shouldn't be happening if COM1 is available.
I studied COM port detection in Windows 2000 SP4 on v86 and did not find any anomalies. Both seabios and ntdetect.com correctly find COM1 port.
I changed uart.js to log every IO operation on serial ports and set LOG_LEVEL = LOG_SERIAL in config.js. Modified uart.js and raw log are in the attachment.
Below is annotated log. This is the full log, there is no other COM port activity beyond SeaBIOS:serial_setup and ntdetect.com:GetComportInformation.
SeaBIOS: serial_setup > detect_serial
0x3F8+1: write 0x2 outb(0x02, port+SEROFF_IER);
0x3F8+1: read 0x2 u8 ier = inb(port+SEROFF_IER); // GOOD
0x3F8+2: read 0xC2 u8 iir = inb(port+SEROFF_IIR); // GOOD (0xC2 & 0x3F) == 0x02
0x3F8+1: write 0x0 outb(0x00, port+SEROFF_IER);
ntdetect.com: GetComportInformation
// GetComportInformation > DoesPortExist
0x3F8+3: read 0x0 LineControl_Save = READ_PORT_UCHAR(Address+LINE_CONTROL_REGISTER);
0x3F8+3: write 0x80 WRITE_PORT_UCHAR(Address+LINE_CONTROL_REGISTER, (UCHAR)(LineControl | SERIAL_LCR_DLAB) );
0x3F8+1: read 0x0 BaudRateMsb = READ_PORT_UCHAR(Address+DIVISOR_LATCH_MSB);
0x3F8: read 0x0 BaudRateLsb = READ_PORT_UCHAR(Address+DIVISOR_LATCH_LSB);
0x3F8+1: write 0x0 WRITE_PORT_UCHAR(Address+DIVISOR_LATCH_MSB, BAUD_RATE_9600_MSB);
0x3F8: write 0xC WRITE_PORT_UCHAR(Address+DIVISOR_LATCH_LSB, BAUD_RATE_9600_LSB);
0x3F8+3: write 0x0 WRITE_PORT_UCHAR(Address+LINE_CONTROL_REGISTER, (UCHAR)(LineControl & ~SERIAL_LCR_DLAB) );
0x3F8+1: read 0x0 IerContents = READ_PORT_UCHAR(Address + INTERRUPT_ENABLE_REGISTER);
0x3F8+1: write 0xF WRITE_PORT_UCHAR(Address + INTERRUPT_ENABLE_REGISTER, IER_TEST_VALUE);
0x3F8+3: write 0x80 WRITE_PORT_UCHAR(Address+LINE_CONTROL_REGISTER, (UCHAR)(LineControl | SERIAL_LCR_DLAB) ); // Read baud rate divisor. The values we read should be equal to the values we set earlier.
0x3F8+1: read 0x0 Temp = READ_PORT_UCHAR(Address+DIVISOR_LATCH_MSB); // GOOD
0x3F8: read 0xC Temp = READ_PORT_UCHAR(Address+DIVISOR_LATCH_LSB); // GOOD
0x3F8+3: write 0x0 WRITE_PORT_UCHAR(Address+LINE_CONTROL_REGISTER, (UCHAR)(LineControl & ~SERIAL_LCR_DLAB) ); // Read IER and it should be equal to the value we set earlier.
0x3F8+1: read 0xF Temp = READ_PORT_UCHAR(Address + INTERRUPT_ENABLE_REGISTER); // GOOD
// cleanup
0x3F8+3: write 0x0
0x3F8+1: write 0x0
0x3F8+3: write 0x80
0x3F8+1: write 0x0
0x3F8: write 0x0
0x3F8+3: write 0x0
// end of DoesPortExist
GetComportInformation > HwInterruptDetection > SerialInterruptDismiss // (*InterruptDismissRoutine)(BasePort); // line 380
0x3F8+2: read 0xC1
0x3F8+1: write 0x0
GetComportInformation > HwInterruptDetection > SerialInterruptRequest // (*InterruptRequestRoutine)(BasePort); // line 404
0x3F8+4: write 0x8
0x3F8+1: write 0x0
0x3F8+1: write 0xF
// (*InterruptDismissRoutine)(BasePort); // line 474
0x3F8+2: read 0xC1
0x3F8+1: write 0x0
// (*InterruptRequestRoutine)(BasePort); // line 498
0x3F8+4: write 0x8
0x3F8+1: write 0x0
0x3F8+1: write 0xF
// (*InterruptDismissRoutine)(BasePort); // line 561
0x3F8+2: read 0xC1
0x3F8+1: write 0x0
// cleanup
0x3F8+1: write 0x0 // line 813
0x3F8+4: write 0x0 // line 814
// end of GetComportInformation
Probably related to #610. A PR would welcome.