From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=46176 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PCw54-00039g-1J for qemu-devel@nongnu.org; Mon, 01 Nov 2010 11:13:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PCw4f-0002lc-1U for qemu-devel@nongnu.org; Mon, 01 Nov 2010 11:13:32 -0400 Received: from fe02x03-cgp.akado.ru ([77.232.31.165]:56302 helo=akado.ru) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PCw4e-0002lM-DE for qemu-devel@nongnu.org; Mon, 01 Nov 2010 11:13:29 -0400 Date: Mon, 1 Nov 2010 18:13:25 +0300 (MSK) From: malc Subject: Re: [Qemu-devel] [PATCH 33/40] xenner: core In-Reply-To: <1288623713-28062-34-git-send-email-agraf@suse.de> Message-ID: References: <1288623713-28062-1-git-send-email-agraf@suse.de> <1288623713-28062-34-git-send-email-agraf@suse.de> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Alexander Graf Cc: qemu-devel Developers , Gerd Hoffmann On Mon, 1 Nov 2010, Alexander Graf wrote: > This patch adds generic xenner functionality to qemu. > > Signed-off-by: Alexander Graf > --- > hw/xenner.h | 52 +++++++++++++ > hw/xenner_core.c | 224 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 276 insertions(+), 0 deletions(-) > create mode 100644 hw/xenner.h > create mode 100644 hw/xenner_core.c > > diff --git a/hw/xenner.h b/hw/xenner.h > new file mode 100644 > index 0000000..241dc4c > --- /dev/null > +++ b/hw/xenner.h > @@ -0,0 +1,52 @@ > +/* > + * Copyright (C) Red Hat 2007 > + * Copyright (C) Novell Inc. 2010 > + * > + * Author(s): Gerd Hoffmann > + * Alexander Graf > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; under version 2 of the License. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License along > + * with this program; if not, see . > + */ > + > +#include "qemu-common.h" > + > +/* xenner_core.c */ > +struct xenner_emu_file { > + const char *filename; > + int pages; > + void *blob; > +}; > + > +void *xenner_mfn_to_ptr(xen_pfn_t pfn); > +void *xenner_get_grant_table(int index); > +void *xenner_get_vminfo(void); > +uint64_t xenner_get_config(uint32_t reg); > +uint32_t xenner_get_evtchn_pin(uint32_t reg); > +void xenner_set_config(uint32_t reg, uint64_t value); > +int xenner_load_emu_file(struct xenner_emu_file *f); > +int xenner_guest_evtchn_alloc(void); > +int xenner_guest_evtchn_release(int port); > +int xenner_core_init(int evt); > + > +/* xenner_guest_store.c */ > +void xenner_guest_store_setup(uint64_t guest_mfn, evtchn_port_t guest_evtchn); > +void xenner_guest_store_reset(void); > + > +/* xenner_pv.c */ > +int xenner_init_pv(const char *kernel_filename, > + const char *kernel_cmdline, > + const char *initrd_filename); > + > +int xenner_domain_build_pv(const char *kernel, > + const char *initrd, > + const char *cmdline); > diff --git a/hw/xenner_core.c b/hw/xenner_core.c > new file mode 100644 > index 0000000..53a9a75 > --- /dev/null > +++ b/hw/xenner_core.c > @@ -0,0 +1,224 @@ > +/* > + * Copyright (C) Red Hat 2007 > + * Copyright (C) Novell Inc. 2010 > + * > + * Author(s): Gerd Hoffmann > + * Alexander Graf > + * > + * Xenner Core > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; under version 2 of the License. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License along > + * with this program; if not, see . > + */ > + > +#include "hw.h" > +#include "isa.h" > +#include "sysemu.h" > +#include "xen.h" > +#include "xen_interfaces.h" > +#include "xenner.h" > +#include "xenner_emudev.h" > +#include "loader.h" > + > +/* #define DEBUG */ > + > +static int guest_evtchndev; > +static struct emudev_state xen_emudev; > + > +/* ------------------------------------------------------------- */ > + > +static void do_emudev_command(uint16_t cmd, uint16_t arg) > +{ > + switch (cmd) { > + case EMUDEV_CMD_NOP: > + /* nop vmexit */ > + break; > + case EMUDEV_CMD_WRITE_CHAR: > +#ifdef DEBUG > + fprintf(stderr, "%c", arg); > +#endif > + break; > + case EMUDEV_CMD_CONFIGURATION_DONE: > + /* emu finisted initial EMUDEV_CONF_* setup */ > + break; > + case EMUDEV_CMD_EVTCHN_ALLOC: > + if (arg < EMUDEV_CONF_COMMAND_RESULT_COUNT) { > + xen_emudev.result[arg] = xenner_guest_evtchn_alloc(); > + } > + break; > + case EMUDEV_CMD_EVTCHN_SEND: > + xc_evtchn.notify(guest_evtchndev, arg); > + break; > + case EMUDEV_CMD_GUEST_SHUTDOWN: > + switch (arg) { > + case SHUTDOWN_poweroff: > + fprintf(stderr, "xenner emudev: guest poweroff -> powerdown\n"); > + qemu_system_powerdown_request(); > + break; > + case SHUTDOWN_reboot: > + fprintf(stderr, "xenner emudev: guest reboot -> reset\n"); > + qemu_system_reset_request(); > + vm_stop(0); > + break; > + case SHUTDOWN_suspend: > + fprintf(stderr, "xenner emudev: guest suspend -> stop vm\n"); > + vm_stop(0); > + break; > + case SHUTDOWN_crash: > + fprintf(stderr, "xenner emudev: guest crash -> reset\n"); > + vm_stop(0); > + qemu_system_reset_request(); > + break; > + } > + break; > + default: > + fprintf(stderr, "xenner emudev: cmd 0x%04x arg 0x%04x\n", cmd, arg); > + } > +} > + > +static void xenner_port_write(void *opaque, uint32_t addr, uint32_t val) > +{ > + uint16_t cmd, arg; > + > + switch (addr) { > + case EMUDEV_REG_CONF_ENTRY: > + emudev_write_entry(&xen_emudev, val); > + break; > + case EMUDEV_REG_CONF_VALUE: > + emudev_write_value(&xen_emudev, val); > + break; > + case EMUDEV_REG_COMMAND: > + cmd = val >> 16; > + arg = val & 0xffff; > + do_emudev_command(cmd, arg); > + break; > + default: > + fprintf(stderr, "io: %s, addr 0x%" PRIx16 " value 0x%" PRIx32 "\n", > + __FUNCTION__, addr, val); > + break; > + } > +} > + > +static uint32_t xenner_port_read(void *opaque, uint32_t addr) > +{ > + uint32_t val; > + > + switch (addr) { > + case EMUDEV_REG_CONF_VALUE: > + val = emudev_read_value(&xen_emudev); > + break; > + default: > + fprintf(stderr, "io: %s, addr 0x%" PRIx16 "\n", __FUNCTION__, addr); > + val = 0xffffffff; > + break; > + } > + return val; > +} > + > +/* ------------------------------------------------------------- */ > + > +void *xenner_mfn_to_ptr(xen_pfn_t pfn) > +{ > + ram_addr_t offset; > + > + offset = cpu_get_physical_page_desc(pfn << PAGE_SHIFT); > + return qemu_get_ram_ptr(offset); > +} > + > +void *xenner_get_grant_table(int index) > +{ > + uint32_t pfn; > + > + if (index > EMUDEV_CONF_GRANT_TABLE_COUNT) { > + return NULL; > + } > + pfn = xen_emudev.gnttab[index]; > + if (!pfn) { > + return NULL; > + } > + return xenner_mfn_to_ptr(pfn); > +} > + > +void *xenner_get_vminfo(void) > +{ > + uint32_t pfn; > + > + pfn = xen_emudev.config[EMUDEV_CONF_VMINFO_PFN]; > + if (!pfn) { > + return NULL; > + } > + return xenner_mfn_to_ptr(pfn); > +} > + > +uint64_t xenner_get_config(uint32_t reg) > +{ > + return xen_emudev.config[reg]; > +} > + > +uint32_t xenner_get_evtchn_pin(uint32_t reg) > +{ > + return xen_emudev.evtchn[reg]; > +} > + > +void xenner_set_config(uint32_t reg, uint64_t value) > +{ > + xen_emudev.config[reg] = value; > +} > + > +/* ------------------------------------------------------------- */ > + > +int xenner_load_emu_file(struct xenner_emu_file *f) > +{ > + int r; > + > + /* Fetch size */ > + r = get_image_size(f->filename); > + if (r <= 0) { > + fprintf(stderr, "can't find %s\n", f->filename); > + return -1; > + } > + > + /* Allocate memory */ > + f->pages = (r + PAGE_SIZE - 1) / PAGE_SIZE; > + f->blob = qemu_mallocz(f->pages * PAGE_SIZE); > + if (!f->blob) { > + return -1; > + } qemu_mallocz doesn't return NULL > + > + /* Load image */ > + r = load_image(f->filename, f->blob); > + > + return r; > +} > + > +/* ------------------------------------------------------------- */ > + > +int xenner_guest_evtchn_alloc(void) > +{ > + return xc_evtchn.bind_unbound_port(guest_evtchndev, 0); > +} > + > +int xenner_guest_evtchn_release(int port) > +{ > + return xc_evtchn.unbind(guest_evtchndev, port); > +} > + > +int xenner_core_init(int evt) > +{ > + guest_evtchndev = evt; > + xc_evtchn.domid(guest_evtchndev, xen_domid); > + > + register_ioport_write(EMUDEV_REG_BASE, 16, 4, xenner_port_write, NULL); > + register_ioport_read(EMUDEV_REG_BASE, 16, 4, xenner_port_read, NULL); > + > + return 0; > +} > -- mailto:av1474@comtv.ru