Skip to contentSkip to conversation

parallel port support for qemu.

PATCH In review Mark Jonckheere 2 participants 2 messages Jan 7, 2005 – Jan 8, 2005 Kbuild

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 parallel port support for qemu.

This patch adds parallel printer ports to the emulated pc hardware. The code in hw/parallel.c has been derived from hw/serial.c.

It has been tested on a linux host with a MSDOS-5 and a Knoppix 3.3 guest.

What is missing:
- EPP/ECP/IEEE-1284 mode.
- redirecting printer output to an arbitrary filename.
- redirecting printer output to a print spool.
- redirecting printer output to a physical device.
- an easy way to flush a spool before qemu is terminated:
a fixed timeout, a formfeed character, a "flush" command, a <ctrl-alt-X> key sequence, or something else, ... ?
- documentation.

If you like it, give it a try.

Groeten,
Mark.

Signature · 1 line
:wq
Makefile.target +1 -1
diff -urN qemu/Makefile.target qemu_parallel/Makefile.target
@@ -316,7 +316,7 @@
 # Hardware support
 VL_OBJS+= ide.o ne2000.o pckbd.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
 VL_OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pc.o
-VL_OBJS+= cirrus_vga.o mixeng.o apic.o
+VL_OBJS+= cirrus_vga.o mixeng.o apic.o parallel.o
 endif
 ifeq ($(TARGET_ARCH), ppc)
 VL_OBJS+= ppc.o ide.o ne2000.o pckbd.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
hw/parallel.c +188 -0

188 lines not on this page · raw message

hw/pc.c +9 -0
diff -urN qemu/hw/pc.c qemu_parallel/hw/pc.c
@@ -376,6 +376,9 @@
 static int serial_io[MAX_SERIAL_PORTS] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
 static int serial_irq[MAX_SERIAL_PORTS] = { 4, 3, 4, 3 };
 
+static int parallel_io[MAX_PARALLEL_PORTS] = { 0x378, 0x278, 0x3bc };
+static int parallel_irq[MAX_PARALLEL_PORTS] = { 7, 7, 7 };
+
 /* PC hardware initialisation */
 void pc_init(int ram_size, int vga_ram_size, int boot_device,
              DisplayState *ds, const char **fd_filename, int snapshot,
@@ -538,6 +541,12 @@
         }
     }
 
+    for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
+        if (parallel_hds[i]) {
+            parallel_init(parallel_io[i], parallel_irq[i], parallel_hds[i]);
+        }
+    }
+
     if (pci_enabled) {
         for(i = 0; i < nb_nics; i++) {
             pci_ne2000_init(pci_bus, &nd_table[i]);
vl.c +34 -0
diff -urN qemu/vl.c qemu_parallel/vl.c
@@ -136,6 +136,7 @@
 int full_screen = 0;
 TextConsole *vga_console;
 CharDriverState *serial_hds[MAX_SERIAL_PORTS];
+CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
 
 /***********************************************************/
 /* x86 ISA bus support */
@@ -2671,6 +2672,7 @@
            "Debug/Expert options:\n"
            "-monitor dev    redirect the monitor to char device 'dev'\n"
            "-serial dev     redirect the serial port to char device 'dev'\n"
+           "-parallel dev   redirect the parallel port to char device 'dev'\n"
            "-pidfile file   Write PID to 'file'\n"
            "-S              freeze CPU at startup (use 'c' to start execution)\n"
            "-s              wait gdb connection to port %d\n"
@@ -2763,6 +2765,7 @@
     QEMU_OPTION_std_vga,
     QEMU_OPTION_monitor,
     QEMU_OPTION_serial,
+    QEMU_OPTION_parallel,
     QEMU_OPTION_loadvm,
     QEMU_OPTION_full_screen,
     QEMU_OPTION_pidfile,
@@ -2825,6 +2828,7 @@
     { "std-vga", 0, QEMU_OPTION_std_vga },
     { "monitor", 1, QEMU_OPTION_monitor },
     { "serial", 1, QEMU_OPTION_serial },
+    { "parallel", 1, QEMU_OPTION_parallel },
     { "loadvm", HAS_ARG, QEMU_OPTION_loadvm },
     { "full-screen", 0, QEMU_OPTION_full_screen },
     { "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
@@ -2907,6 +2911,8 @@
     char monitor_device[128];
     char serial_devices[MAX_SERIAL_PORTS][128];
     int serial_device_index;
+    char parallel_devices[MAX_PARALLEL_PORTS][128];
+    int parallel_device_index;
     const char *loadvm = NULL;
     
 #if !defined(CONFIG_SOFTMMU)
@@ -2940,6 +2946,11 @@
         serial_devices[i][0] = '\0';
     serial_device_index = 0;
     
+    pstrcpy(parallel_devices[0], sizeof(parallel_devices[0]), "vc");
+    for(i = 1; i < MAX_PARALLEL_PORTS; i++)
+        parallel_devices[i][0] = '\0';
+    parallel_device_index = 0;
+    
     nb_tun_fds = 0;
     net_if_type = -1;
     nb_nics = 1;
@@ -3036,6 +3047,7 @@
             case QEMU_OPTION_nographic:
                 pstrcpy(monitor_device, sizeof(monitor_device), "stdio");
                 pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "stdio");
+                pstrcpy(parallel_devices[0], sizeof(parallel_devices[0]), "stdio");
                 nographic = 1;
                 break;
             case QEMU_OPTION_kernel:
@@ -3250,6 +3262,15 @@
                         sizeof(serial_devices[0]), optarg);
                 serial_device_index++;
                 break;
+            case QEMU_OPTION_parallel:
+                if (parallel_device_index >= MAX_PARALLEL_PORTS) {
+                    fprintf(stderr, "qemu: too many parallel ports\n");
+                    exit(1);
+                }
+                pstrcpy(parallel_devices[parallel_device_index], 
+                        sizeof(parallel_devices[0]), optarg);
+                parallel_device_index++;
+                break;
 	    case QEMU_OPTION_loadvm:
 		loadvm = optarg;
 		break;
@@ -3473,6 +3494,19 @@
         }
     }
 
+    for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
+        if (parallel_devices[i][0] != '\0') {
+            parallel_hds[i] = qemu_chr_open(parallel_devices[i]);
+            if (!parallel_hds[i]) {
+                fprintf(stderr, "qemu: could not open parallel device '%s'\n", 
+                        parallel_devices[i]);
+                exit(1);
+            }
+            if (!strcmp(parallel_devices[i], "vc"))
+                qemu_chr_printf(parallel_hds[i], "parallel%d console\n", i);
+        }
+    }
+
     /* setup cpu signal handlers for MMU / self modifying code handling */
 #if !defined(CONFIG_SOFTMMU)
     
vl.h +11 -0
diff -urN qemu/vl.h qemu_parallel/vl.h
@@ -224,6 +224,12 @@
 
 extern CharDriverState *serial_hds[MAX_SERIAL_PORTS];
 
+/* parallel ports */
+
+#define MAX_PARALLEL_PORTS 3
+
+extern CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
+
 /* network redirectors support */
 
 #define MAX_NICS 8
@@ -632,6 +638,11 @@
 typedef struct SerialState SerialState;
 SerialState *serial_init(int base, int irq, CharDriverState *chr);
 
+/* parallel.c */
+
+typedef struct ParallelState ParallelState;
+ParallelState *parallel_init(int base, int irq, CharDriverState *chr);
+
 /* i8259.c */
 
 void pic_set_irq(int irq, int level);
#1 lore raw
Quoted 1 line · Mark Jonckheere

- redirecting printer output to a physical device.

This would be useful for running the Xilinx FPGA tools under qemu, which use a parallel port JTAG dongle. I'm trying to read out the FPGA bitstream as described in their datasheets using CFG_IN/CFG_OUT but it just doesn't seem to work as they describe -- this would be useful for figuring out how it all really works.

I'll have a go at this in a few days when I come back home.

cheers,
Lennert