aboutsummaryrefslogtreecommitdiffstats
path: root/com32/sysdump/serial.c
diff options
context:
space:
mode:
Diffstat (limited to 'com32/sysdump/serial.c')
-rw-r--r--com32/sysdump/serial.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/com32/sysdump/serial.c b/com32/sysdump/serial.c
index 71b3067a..03f6403a 100644
--- a/com32/sysdump/serial.c
+++ b/com32/sysdump/serial.c
@@ -2,6 +2,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <sys/io.h>
+#include <sys/cpu.h>
#include "serial.h"
@@ -28,8 +29,13 @@ int serial_init(struct serial_if *sif, const char *argv[])
uint8_t dll, dlm, lcr;
port = strtoul(argv[0], NULL, 0);
- if (port <= 3)
- port = *(uint16_t *)(0x400 + port*2);
+ if (port <= 3) {
+ uint16_t addr = ((uint16_t *)0x400)[port];
+ printf("Serial port %u is at 0x%04x\n", port, addr);
+ port = addr;
+ }
+
+ sif->port = port;
if (argv[1])
speed = strtoul(argv[1], NULL, 0);
@@ -38,12 +44,14 @@ int serial_init(struct serial_if *sif, const char *argv[])
divisor = 115200/speed;
+ cli(); /* Just in case... */
+
/* Save old register settings */
sif->old.lcr = inb(port + LCR);
sif->old.mcr = inb(port + MCR);
sif->old.iir = inb(port + IIR);
- /* Set 115200n81 */
+ /* Set speed */
outb(0x83, port + LCR); /* Enable divisor access */
sif->old.dll = inb(port + DLL);
sif->old.dlm = inb(port + DLM);
@@ -54,17 +62,21 @@ int serial_init(struct serial_if *sif, const char *argv[])
dll = inb(port + DLL);
dlm = inb(port + DLM);
lcr = inb(port + LCR);
- outb(0x03, port + LCR);
+ outb(0x03, port + LCR); /* Enable data access, n81 */
(void)inb(port + IER); /* Synchronize */
sif->old.ier = inb(port + IER);
+ /* Disable interrupts */
+ outb(0, port + IER);
+
+ sti();
+
if (dll != (uint8_t)divisor ||
dlm != (uint8_t)(divisor >> 8) ||
- lcr != 0x83)
+ lcr != 0x83) {
+ printf("No serial port detected!\n");
return -1; /* This doesn't look like a serial port */
-
- /* Disable interrupts */
- outb(0, port + IER);
+ }
/* Enable 16550A FIFOs if available */
outb(0x41, port + FCR); /* Enable FIFO */
@@ -119,6 +131,6 @@ void serial_cleanup(struct serial_if *sif)
(void)inb(port + IER);
outb(sif->old.mcr, port + MCR);
outb(sif->old.ier, port + IER);
- if ((sif->old.iir & 0xc0) != 0xc0)
+ if (sif->old.iir < 0xc0)
outb(0x00, port + FCR); /* Disable FIFOs */
}