From patchwork Thu Dec 3 05:04:17 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H. Peter Anvin" X-Patchwork-Id: 40129 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 9473FB7C07 for ; Thu, 3 Dec 2009 16:05:11 +1100 (EST) Received: from localhost ([127.0.0.1]:35297 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NG3sJ-00029U-Pt for incoming@patchwork.ozlabs.org; Thu, 03 Dec 2009 00:05:07 -0500 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1NG3rf-00026D-2f for qemu-devel@nongnu.org; Thu, 03 Dec 2009 00:04:27 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1NG3ra-0001y8-Hy for qemu-devel@nongnu.org; Thu, 03 Dec 2009 00:04:26 -0500 Received: from [199.232.76.173] (port=39422 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NG3ra-0001xv-21 for qemu-devel@nongnu.org; Thu, 03 Dec 2009 00:04:22 -0500 Received: from terminus.zytor.com ([198.137.202.10]:38720) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1NG3rZ-0004g4-GM for qemu-devel@nongnu.org; Thu, 03 Dec 2009 00:04:21 -0500 Received: from mail.hos.anvin.org (c-98-210-181-100.hsd1.ca.comcast.net [98.210.181.100]) (authenticated bits=0) by terminus.zytor.com (8.14.3/8.14.3) with ESMTP id nB354IST008161 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Wed, 2 Dec 2009 21:04:18 -0800 Received: from tazenda.hos.anvin.org (tazenda.hos.anvin.org [172.27.0.16]) by mail.hos.anvin.org (8.14.3/8.14.3) with ESMTP id nB354Inx018983; Wed, 2 Dec 2009 21:04:18 -0800 Received: from tazenda.hos.anvin.org (localhost.localdomain [127.0.0.1]) by tazenda.hos.anvin.org (8.14.3/8.13.6) with ESMTP id nB354ID2020963; Wed, 2 Dec 2009 21:04:18 -0800 Received: (from hpa@localhost) by tazenda.hos.anvin.org (8.14.3/8.14.3/Submit) id nB354HoW020961; Wed, 2 Dec 2009 21:04:17 -0800 From: "H. Peter Anvin" To: qemu-devel@nongnu.org Date: Wed, 2 Dec 2009 21:04:17 -0800 Message-Id: <1259816657-20930-1-git-send-email-hpa@zytor.com> X-Mailer: git-send-email 1.6.2.5 X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 3) Cc: "H. Peter Anvin" , hpa@zytor.com Subject: [Qemu-devel] [PATCH] debugcon: support for debugging consoles (e.g. Bochs port 0xe9) X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Add generic support for debugging consoles (simple I/O ports which when written to cause debugging output to be written to a target.) The current implementation matches Bochs' port 0xe9, allowing the same debugging code to be used for both Bochs and Qemu. There is no vm state associated with the debugging port, simply because it has none -- the entire interface is a single, stateless, write-only port. Most of the code was cribbed from the serial port driver. v2: removed non-ISA variants (they can be introduced when/if someone wants them, using code from the serial port); added configurable readback (Bochs returns 0xe9 on a read from this register, mimic that by default) This retains the apparently somewhat controversial user friendly option, however. v3: reimplemented the user friendly option as a synthetic option ("-debugcon foo" basically ends up being a parser-level shorthand for "-chardev stdio,id=debugcon -device isa-debugcon,chardev=debugcon") -- this dramatically reduced the complexity while keeping the same level of user friendliness. v4: spaces, not tabs. Signed-off-by: H. Peter Anvin --- Makefile.target | 2 +- hw/debugcon.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ qemu-options.hx | 11 ++++++ vl.c | 12 ++++++ 4 files changed, 131 insertions(+), 1 deletions(-) create mode 100644 hw/debugcon.c diff --git a/Makefile.target b/Makefile.target index 2985658..df4a7b2 100644 --- a/Makefile.target +++ b/Makefile.target @@ -197,7 +197,7 @@ obj-i386-y += fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o obj-i386-y += cirrus_vga.o apic.o ioapic.o parallel.o acpi.o piix_pci.o obj-i386-y += usb-uhci.o vmmouse.o vmport.o vmware_vga.o hpet.o obj-i386-y += device-hotplug.o pci-hotplug.o smbios.o wdt_ib700.o -obj-i386-y += ne2000-isa.o +obj-i386-y += ne2000-isa.o debugcon.o # shared objects obj-ppc-y = ppc.o ide/core.o ide/qdev.o ide/isa.o ide/pci.o ide/macio.o diff --git a/hw/debugcon.c b/hw/debugcon.c new file mode 100644 index 0000000..d549091 --- /dev/null +++ b/hw/debugcon.c @@ -0,0 +1,107 @@ +/* + * QEMU Bochs-style debug console ("port E9") emulation + * + * Copyright (c) 2003-2004 Fabrice Bellard + * Copyright (c) 2008 Citrix Systems, Inc. + * Copyright (c) Intel Corporation; author: H. Peter Anvin + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "hw.h" +#include "qemu-char.h" +#include "isa.h" +#include "pc.h" + +//#define DEBUG_DEBUGCON + +typedef struct DebugconState { + CharDriverState *chr; + uint32_t readback; +} DebugconState; + +typedef struct ISADebugconState { + ISADevice dev; + uint32_t iobase; + DebugconState state; +} ISADebugconState; + +static void debugcon_ioport_write(void *opaque, uint32_t addr, uint32_t val) +{ + DebugconState *s = opaque; + unsigned char ch = val; + +#ifdef DEBUG_DEBUGCON + printf("debugcon: write addr=0x%04x val=0x%02x\n", addr, val); +#endif + + qemu_chr_write(s->chr, &ch, 1); +} + + +static uint32_t debugcon_ioport_read(void *opaque, uint32_t addr) +{ + DebugconState *s = opaque; + +#ifdef DEBUG_DEBUGCON + printf("debugcon: read addr=0x%04x\n", addr, val); +#endif + + return s->readback; +} + +static void debugcon_init_core(DebugconState *s) +{ + if (!s->chr) { + fprintf(stderr, "Can't create debugcon device, empty char device\n"); + exit(1); + } + + qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, s); +} + +static int debugcon_isa_initfn(ISADevice *dev) +{ + ISADebugconState *isa = DO_UPCAST(ISADebugconState, dev, dev); + DebugconState *s = &isa->state; + + debugcon_init_core(s); + register_ioport_write(isa->iobase, 1, 1, debugcon_ioport_write, s); + register_ioport_read(isa->iobase, 1, 1, debugcon_ioport_read, s); + return 0; +} + +static ISADeviceInfo debugcon_isa_info = { + .qdev.name = "isa-debugcon", + .qdev.size = sizeof(ISADebugconState), + .init = debugcon_isa_initfn, + .qdev.props = (Property[]) { + DEFINE_PROP_HEX32("iobase", ISADebugconState, iobase, 0xe9), + DEFINE_PROP_CHR("chardev", ISADebugconState, state.chr), + DEFINE_PROP_HEX32("readback", ISADebugconState, state.readback, 0xe9), + DEFINE_PROP_END_OF_LIST(), + }, +}; + +static void debugcon_register_devices(void) +{ + isa_qdev_register(&debugcon_isa_info); +} + +device_init(debugcon_register_devices) diff --git a/qemu-options.hx b/qemu-options.hx index b65fd74..efa74df 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1586,6 +1586,17 @@ The default device is @code{vc} in graphical mode and @code{stdio} in non graphical mode. ETEXI +DEF("debugcon", HAS_ARG, QEMU_OPTION_debugcon, \ + "-debugcon dev redirect the debug console to char device 'dev'\n") +STEXI +@item -debugcon @var{dev} +Redirect the debug console to host device @var{dev} (same devices as the +serial port). The debug console is an I/O port which is typically port +0xe9; writing to that I/O port sends output to this device. +The default device is @code{vc} in graphical mode and @code{stdio} in +non graphical mode. +ETEXI + DEF("pidfile", HAS_ARG, QEMU_OPTION_pidfile, \ "-pidfile file write PID to 'file'\n") STEXI diff --git a/vl.c b/vl.c index 44763af..86e0d73 100644 --- a/vl.c +++ b/vl.c @@ -5149,6 +5149,18 @@ int main(int argc, char **argv, char **envp) parallel_devices[parallel_device_index] = optarg; parallel_device_index++; break; + case QEMU_OPTION_debugcon: + if (!qemu_chr_open("debugcon", optarg, NULL)) { + exit(1); + } + opts = qemu_opts_create(&qemu_device_opts, "debugcon", 1); + if (!opts) { + fprintf(stderr, "qemu: already have a debugcon device\n"); + exit(1); + } + qemu_opt_set(opts, "driver", "isa-debugcon"); + qemu_opt_set(opts, "chardev", "debugcon"); + break; case QEMU_OPTION_loadvm: loadvm = optarg; break;