[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] Re: [Qemu-devel] [PATCH 03/15] xen: Add a new target to qemu: target-xen


  • To: stefano.stabellini@xxxxxxxxxxxxx
  • From: Blue Swirl <blauwirbel@xxxxxxxxx>
  • Date: Thu, 12 Aug 2010 18:56:35 +0000
  • Cc: Anthony.Perard@xxxxxxxxxx, xen-devel@xxxxxxxxxxxxxxxxxxx, qemu-devel@xxxxxxxxxx
  • Delivery-date: Thu, 12 Aug 2010 11:58:01 -0700
  • Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-type:content-transfer-encoding; b=TBb+EV7CvvqR+OpUAaEdvA7uW77lNVlSnLoBEoA2+ZYhUNwNdkc+xcywjwcTiUFNP4 yoPJGLYblvPqxb2ftgZkBGHFqyTeDCjXnutQQVthmC7PJnamO3B3kSLwhcHwFjlG6ZeR Zar0Xs3I98Y6OUq3yXpmbGg1iDqL+NG+xlCJY=
  • List-id: Xen developer discussion <xen-devel.lists.xensource.com>

On Thu, Aug 12, 2010 at 2:09 PM,  <stefano.stabellini@xxxxxxxxxxxxx> wrote:
> From: Anthony PERARD <anthony.perard@xxxxxxxxxx>
>
> This patch adds a new Xen device model target to Qemu, called
> target-xen.

I don't understand why it would be a target, QEMU calls CPU
architectures targets. Isn't it possible to have Xen for Sparc, PPC or
ARM? It should really be just a machine, not copy&paste from x86
target.

> The new target makes use of the previously introduced xen_machine_fv.
> In order to have a fully working Xen device model we still need
> functionalities introduced by the following patches.
>
> Signed-off-by: Anthony PERARD <anthony.perard@xxxxxxxxxx>
> Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
> ---
> ÂMakefile.target          Â|  31 ++-
> Âarch_init.c            Â|  Â2 +
> Âarch_init.h            Â|  Â1 +
> Âconfigure             Â|  11 +-
> Âdefault-configs/xen-dm-softmmu.mak | Â 24 ++
> Âtarget-xen/cpu.h          | Â120 ++++++
> Âtarget-xen/exec-dm.c        | Â791 
> ++++++++++++++++++++++++++++++++++++
> Âtarget-xen/helper.c        Â|  69 ++++
> Âtarget-xen/qemu-xen.h       Â|  30 ++
> Âtarget-xen/stub-functions.c    Â|  42 ++
> Âtarget-xen/xen_mapcache.c     Â|  14 +
> Â11 files changed, 1130 insertions(+), 5 deletions(-)
> Âcreate mode 100644 default-configs/xen-dm-softmmu.mak
> Âcreate mode 100644 target-xen/cpu.h
> Âcreate mode 100644 target-xen/exec-dm.c
> Âcreate mode 100644 target-xen/helper.c
> Âcreate mode 100644 target-xen/machine.c
> Âcreate mode 100644 target-xen/qemu-xen.h
> Âcreate mode 100644 target-xen/stub-functions.c
> Âcreate mode 100644 target-xen/xen_mapcache.c
>
> diff --git a/Makefile.target b/Makefile.target
> index 8fdc884..359a984 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -183,9 +183,6 @@ QEMU_CFLAGS += $(VNC_PNG_CFLAGS)
> Â# xen backend driver support
> Âobj-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o
>
> -# xen full virtualized machine
> -obj-$(CONFIG_XEN) += xen_machine_fv.o
> -
> Â# USB layer
> Âobj-$(CONFIG_USB_OHCI) += usb-ohci.o
>
> @@ -310,6 +307,34 @@ obj-y += $(addprefix $(HWDIR)/, $(hw-obj-y))
>
> Âendif # CONFIG_SOFTMMU
>
> +# Xen Device Model
> +# xen full virtualized machine
> +
> +# Remove some lib, because we don't want it for a xen target.
> +ifeq ($(TARGET_BASE_ARCH), xen)
> +bad-libobj-y = exec.o translate-all.o cpu-exec.o translate.o
> +bad-libobj-y += tcg%.o fpu/%.o
> +bad-libobj-y += disas.o op_helper.o
> +libobj-y := $(filter-out $(bad-libobj-y), $(libobj-y))
> +endif
> +
> +obj-xen-y += xen_machine_fv.o
> +obj-xen-y += i8259.o
> +obj-xen-y += pc.o
> +obj-xen-y += piix_pci.o
> +obj-xen-y += mc146818rtc.o
> +
> +obj-xen-y += xen_mapcache.o
> +obj-xen-y += stub-functions.o
> +
> +obj-xen-y += vga.o
> +obj-xen-y += hpet.o
> +obj-xen-y += cirrus_vga.o
> +obj-xen-y += smbios.o
> +obj-xen-y += multiboot.o
> +obj-xen-y += exec-dm.o
> +obj-xen-y += lsi53c895a.o usb-ohci.o
> +
> Âobj-$(CONFIG_GDBSTUB_XML) += gdbstub-xml.o
>
> Â$(QEMU_PROG): $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y)
> diff --git a/arch_init.c b/arch_init.c
> index 47bb4b2..ebc5cb6 100644
> --- a/arch_init.c
> +++ b/arch_init.c
> @@ -75,6 +75,8 @@ const char arch_config_name[] = CONFIG_QEMU_CONFDIR 
> "/target-" TARGET_ARCH ".con
> Â#define QEMU_ARCH QEMU_ARCH_SH4
> Â#elif defined(TARGET_SPARC)
> Â#define QEMU_ARCH QEMU_ARCH_SPARC
> +#elif defined(TARGET_XEN)
> +#define QEMU_ARCH QEMU_ARCH_XEN
> Â#endif
>
> Âconst uint32_t arch_type = QEMU_ARCH;
> diff --git a/arch_init.h b/arch_init.h
> index 682890c..b5f8eb1 100644
> --- a/arch_init.h
> +++ b/arch_init.h
> @@ -16,6 +16,7 @@ enum {
> Â Â QEMU_ARCH_S390X = 256,
> Â Â QEMU_ARCH_SH4 = 512,
> Â Â QEMU_ARCH_SPARC = 1024,
> + Â ÂQEMU_ARCH_XEN = 2048,
> Â};
>
> Âextern const uint32_t arch_type;
> diff --git a/configure b/configure
> index 89d9b44..c3f52ce 100755
> --- a/configure
> +++ b/configure
> @@ -2517,6 +2517,9 @@ case "$target" in
> Â ${target_arch2}-softmmu)
> Â Â target_softmmu="yes"
> Â Â ;;
> + Â${target_arch2}-dm-softmmu)
> + Â Âtarget_softmmu="yes"
> + Â Â;;
> Â ${target_arch2}-linux-user)
> Â Â if test "$linux" != "yes" ; then
> Â Â Â echo "ERROR: Target '$target' is only available on a Linux host"
> @@ -2582,6 +2585,10 @@ case "$target_arch2" in
> Â Â TARGET_BASE_ARCH=i386
> Â Â target_phys_bits=64
> Â ;;
> + Âxen)
> + Â Â# This is use for xen mapcache
> + Â Âtarget_phys_bits=64
> + Â;;
> Â alpha)
> Â Â target_phys_bits=64
> Â Â target_nptl="yes"
> @@ -2693,7 +2700,7 @@ if [ "$TARGET_ABI_DIR" = "" ]; then
> Âfi
> Âecho "TARGET_ABI_DIR=$TARGET_ABI_DIR" >> $config_target_mak
> Âcase "$target_arch2" in
> - Âi386|x86_64)
> + Âi386|x86_64|xen)
> Â Â if test "$xen" = "yes" -a "$target_softmmu" = "yes" ; then
> Â Â Â echo "CONFIG_XEN=y" >> $config_target_mak
> Â Â fi
> @@ -2859,7 +2866,7 @@ if test "$target_softmmu" = "yes" ; then
> Â arm)
> Â Â cflags="-DHAS_AUDIO $cflags"
> Â ;;
> - Âi386|mips|ppc)
> + Âi386|mips|ppc|xen)
> Â Â cflags="-DHAS_AUDIO -DHAS_AUDIO_CHOICE $cflags"
> Â ;;
> Â esac
> diff --git a/default-configs/xen-dm-softmmu.mak 
> b/default-configs/xen-dm-softmmu.mak
> new file mode 100644
> index 0000000..72fe141
> --- /dev/null
> +++ b/default-configs/xen-dm-softmmu.mak
> @@ -0,0 +1,24 @@
> +# Default configuration for xen-dm-softmmu
> +
> +CONFIG_VGA_PCI=y
> +CONFIG_VGA_ISA=y
> +CONFIG_VMWARE_VGA=y
> +CONFIG_SERIAL=y
> +CONFIG_PARALLEL=y
> +CONFIG_I8254=y
> +CONFIG_PCSPK=y
> +CONFIG_PCKBD=y
> +CONFIG_USB_UHCI=y
> +CONFIG_FDC=y
> +CONFIG_ACPI=y
> +CONFIG_APM=y
> +CONFIG_DMA=y
> +CONFIG_IDE_CORE=y
> +CONFIG_IDE_QDEV=y
> +CONFIG_IDE_PCI=y
> +CONFIG_IDE_ISA=y
> +CONFIG_IDE_PIIX=y
> +CONFIG_NE2000_ISA=y
> +CONFIG_PIIX_PCI=y
> +CONFIG_SOUND=y
> +CONFIG_XEN=y
> diff --git a/target-xen/cpu.h b/target-xen/cpu.h
> new file mode 100644
> index 0000000..5a45d1c
> --- /dev/null
> +++ b/target-xen/cpu.h
> @@ -0,0 +1,120 @@
> +/*
> + * xen virtual CPU header
> + *
> + * ÂCopyright (c) 2003 Fabrice Bellard
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2 of the License, or (at your option) any later version.
> + *
> + * This library 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
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, see 
> <http://www.gnu.org/licenses/>.
> + */
> +#ifndef CPU_XEN_H
> +#define CPU_XEN_H
> +
> +#include "config.h"
> +
> +#ifdef TARGET_X86_64
> +#define TARGET_LONG_BITS 64
> +#else
> +#define TARGET_LONG_BITS 32
> +#endif
> +
> +#ifdef TARGET_X86_64
> +#define ELF_MACHINE Â Â EM_X86_64
> +#else
> +#define ELF_MACHINE Â Â EM_386
> +#endif
> +
> +#define CPUState struct CPUXenState
> +#define CPUX86State CPUXenState
> +
> +#include "cpu-defs.h"
> +
> +#include "softfloat.h"
> +
> +/* hidden flags - used internally by qemu to represent additional cpu
> + Â states. Only the CPL, INHIBIT_IRQ, SMM and SVMI are not
> + Â redundant. We avoid using the IOPL_MASK, TF_MASK and VM_MASK bit
> + Â position to ease oring with eflags. */
> +/* current cpl */
> +#define HF_CPL_SHIFT Â Â Â Â 0
> +#define HF_SMM_SHIFT Â Â Â Â19 /* CPU in SMM mode */
> +
> +#define HF_CPL_MASK Â Â Â Â Â(3 << HF_CPL_SHIFT)
> +#define HF_SMM_MASK Â Â Â Â Â(1 << HF_SMM_SHIFT)
> +
> +/* cpuid_features bits */
> +#define CPUID_APIC (1 << 9)
> +
> +#define NB_MMU_MODES 2
> +
> +typedef struct CPUXenState {
> + Â Âuint32_t hflags; /* TB flags, see HF_xxx constants. These flags
> + Â Â Â Â Â Â Â Â Â Â Â Âare known at translation time. */
> + Â ÂCPU_COMMON
> +
> + Â Â/* processor features (e.g. for CPUID insn) */
> + Â Âuint32_t cpuid_features;
> + Â Âuint32_t cpuid_apic_id;
> +
> + Â Â/* in order to simplify APIC support, we leave this pointer to the
> + Â Â Â user */
> + Â Âstruct DeviceState *apic_state;
> +} CPUXenState;
> +
> +CPUXenState *cpu_xen_init(const char *cpu_model);
> +int cpu_xen_exec(CPUXenState *s);
> +
> +int cpu_get_pic_interrupt(CPUXenState *s);
> +void cpu_set_ferr(CPUX86State *s);
> +
> +/* helper.c */
> +void cpu_x86_set_a20(CPUXenState *env, int a20_state);
> +
> +/* hw/pc.c */
> +void cpu_smm_update(CPUXenState *env);
> +uint64_t cpu_get_tsc(CPUX86State *env);
> +
> +#define TARGET_PAGE_BITS 12
> +
> +#ifdef TARGET_X86_64
> +#define TARGET_PHYS_ADDR_SPACE_BITS 52
> +/* ??? This is really 48 bits, sign-extended, but the only thing
> + Â accessible to userland with bit 48 set is the VSYSCALL, and that
> + Â is handled via other mechanisms. Â*/
> +#define TARGET_VIRT_ADDR_SPACE_BITS 47
> +#else
> +#define TARGET_PHYS_ADDR_SPACE_BITS 36
> +#define TARGET_VIRT_ADDR_SPACE_BITS 32
> +#endif
> +
> +#define cpu_init cpu_xen_init
> +#define cpu_exec cpu_xen_exec
> +
> +/* MMU modes definitions */
> +static inline int cpu_mmu_index (CPUState *env)
> +{
> + Â Âreturn (env->hflags & HF_CPL_MASK) == 3 ? 1 : 0;
> +}
> +
> +#include "cpu-all.h"
> +#include "exec-all.h"
> +
> +static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
> +{
> +}
> +
> +static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âtarget_ulong *cs_base, int *flags)
> +{
> +}
> +
> +#endif /* CPU_XEN_H */
> diff --git a/target-xen/exec-dm.c b/target-xen/exec-dm.c
> new file mode 100644
> index 0000000..3d64695
> --- /dev/null
> +++ b/target-xen/exec-dm.c
> @@ -0,0 +1,791 @@
> +/*
> + * Âvirtual page mapping and translated block handling
> + *
> + * ÂCopyright (c) 2003 Fabrice Bellard
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2 of the License, or (at your option) any later version.
> + *
> + * This library 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
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA Â02111-1307 ÂUSA

Please use the URL version. The address is ancient.

> + */
> +#include "config.h"
> +
> +#include "cpu.h"
> +#include "hw/hw.h"
> +#include "hw/pc.h"
> +#include "disas.h"
> +#include "hw/xen_common.h"
> +#include "qemu-xen.h"
> +#include "hw/xen.h"
> +#include "hw/xen_backend.h"
> +
> +int use_icount = 0;
> +int64_t qemu_icount;
> +
> +RAMList ram_list = { .blocks = QLIST_HEAD_INITIALIZER(ram_list) };
> +
> +CPUState *first_cpu;
> +/* current CPU in the current thread. It is only valid inside
> + Â cpu_exec() */
> +CPUState *cpu_single_env;
> +
> +/* io memory support */
> +CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
> +CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
> +void *io_mem_opaque[IO_MEM_NB_ENTRIES];
> +static int io_mem_nb = 1;
> +
> +/* log support */
> +FILE *logfile;
> +int loglevel;
> +
> +void cpu_exec_init_all(unsigned long tb_size)
> +{
> +}
> +
> +void cpu_exec_init(CPUState *env)
> +{
> + Â ÂCPUState **penv;
> + Â Âint cpu_index;
> +
> + Â Âenv->next_cpu = NULL;
> + Â Âpenv = &first_cpu;
> + Â Âcpu_index = 0;
> + Â Âwhile (*penv != NULL) {
> + Â Â Â Âpenv = (CPUState **)&(*penv)->next_cpu;
> + Â Â Â Âcpu_index++;
> + Â Â}
> + Â Âenv->cpu_index = cpu_index;
> + Â Â*penv = env;
> +}
> +
> +/* enable or disable low levels log */
> +void cpu_set_log(int log_flags)
> +{
> + Â Âloglevel = log_flags;
> + Â Âif (!logfile) {
> + Â Â Â Âlogfile = stderr;
> + Â Â}
> +}
> +
> +void cpu_set_log_filename(const char *filename)
> +{
> + Â Âlogfile = fopen(filename, "w");
> + Â Âif (!logfile) {
> + Â Â Â Âperror(filename);
> + Â Â Â Â_exit(1);
> + Â Â}
> +#if !defined(CONFIG_SOFTMMU)
> + Â Â/* must avoid mmap() usage of glibc by setting a buffer "by hand" */
> + Â Â{
> + Â Â Â Âstatic uint8_t logfile_buf[4096];
> + Â Â Â Âsetvbuf(logfile, logfile_buf, _IOLBF, sizeof(logfile_buf));
> + Â Â}
> +#else
> + Â Âsetvbuf(logfile, NULL, _IOLBF, 0);
> +#endif
> + Â Âdup2(fileno(logfile), 1);
> + Â Âdup2(fileno(logfile), 2);
> +}
> +
> +/* mask must never be zero, except for A20 change call */
> +void cpu_interrupt(CPUState *env, int mask)
> +{
> + Â Âenv->interrupt_request |= mask;
> +}
> +
> +void cpu_reset_interrupt(CPUState *env, int mask)
> +{
> + Â Âenv->interrupt_request &= ~mask;
> +}
> +
> +const CPULogItem cpu_log_items[] = {
> +#ifdef DEBUG_IOPORT
> + Â Â{ CPU_LOG_IOPORT, "ioport",
> + Â Â Â"show all i/o ports accesses" },
> +#endif
> + Â Â{ 0, NULL, NULL },
> +};
> +
> +static int cmp1(const char *s1, int n, const char *s2)
> +{
> + Â Âif (strlen(s2) != n)
> + Â Â Â Âreturn 0;
> + Â Âreturn memcmp(s1, s2, n) == 0;
> +}
> +
> +/* takes a comma separated list of log masks. Return 0 if error. */
> +int cpu_str_to_log_mask(const char *str)
> +{
> + Â Âconst CPULogItem *item;
> + Â Âint mask;
> + Â Âconst char *p, *p1;
> +
> + Â Âp = str;
> + Â Âmask = 0;
> + Â Âfor(;;) {
> + Â Â Â Âp1 = strchr(p, ',');
> + Â Â Â Âif (!p1) {
> + Â Â Â Â Â Âp1 = p + strlen(p);
> + Â Â Â Â}
> + Â Â Â Âif(cmp1(p,p1-p,"all")) {
> + Â Â Â Â Â Âfor(item = cpu_log_items; item->mask != 0; item++) {
> + Â Â Â Â Â Â Â Âmask |= item->mask;
> + Â Â Â Â Â Â}
> + Â Â Â Â} else {
> + Â Â Â Â Â Âfor(item = cpu_log_items; item->mask != 0; item++) {
> + Â Â Â Â Â Â Â Âif (cmp1(p, p1 - p, item->name))
> + Â Â Â Â Â Â Â Â Â Âgoto found;
> + Â Â Â Â Â Â}
> + Â Â Â Â Â Âreturn 0;
> + Â Â Â Â}
> +found:
> + Â Â Â Âmask |= item->mask;
> + Â Â Â Âif (*p1 != ',')
> + Â Â Â Â Â Âbreak;
> + Â Â Â Âp = p1 + 1;
> + Â Â}
> + Â Âreturn mask;
> +}
> +
> +/* XXX: Simple implementation. Fix later */
> +#define MAX_MMIO 1024
> +static struct mmio_space {
> + Â Âtarget_phys_addr_t start;
> + Â Âunsigned long size;
> + Â Âunsigned long io_index;
> +} mmio[MAX_MMIO];
> +static unsigned long mmio_cnt;
> +
> +/* register physical memory. 'size' must be a multiple of the target
> + Â page size. If (phys_offset & ~TARGET_PAGE_MASK) != 0, then it is an
> + Â io memory page */
> +void cpu_register_physical_memory_offset(target_phys_addr_t start_addr,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ram_addr_t size,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ram_addr_t phys_offset,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ram_addr_t region_offset)
> +{
> + Â Âregion_offset &= TARGET_PAGE_MASK;
> + Â Âstart_addr += region_offset;
> +
> + Â Âint i;
> +
> + Â Âfor (i = 0; i < mmio_cnt; i++) {
> + Â Â Â Âif(mmio[i].start == start_addr) {
> + Â Â Â Â Â Âmmio[i].io_index = phys_offset;
> + Â Â Â Â Â Âmmio[i].size = size;
> + Â Â Â Â Â Âreturn;
> + Â Â Â Â}
> + Â Â}
> +
> + Â Âif (mmio_cnt == MAX_MMIO) {
> + Â Â Â Âfprintf(stderr, "too many mmio regions\n");
> + Â Â Â Âexit(-1);
> + Â Â}
> +
> + Â Âmmio[mmio_cnt].io_index = phys_offset;
> + Â Âmmio[mmio_cnt].start = start_addr;
> + Â Âmmio[mmio_cnt++].size = size;
> +}
> +
> +/* mem_read and mem_write are arrays of functions containing the
> + Â function to access byte (index 0), word (index 1) and dword (index
> + Â 2). All functions must be supplied. If io_index is non zero, the
> + Â corresponding io zone is modified. If it is zero, a new io zone is
> + Â allocated. The return value can be used with
> + Â cpu_register_physical_memory(). (-1) is returned if error. */
> +int cpu_register_io_memory_fixed(int io_index,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â CPUReadMemoryFunc * const *mem_read,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â CPUWriteMemoryFunc * const *mem_write,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â void *opaque)
> +{
> + Â Âint i;
> +
> + Â Âif (io_index <= 0) {
> + Â Â Â Âif (io_index >= IO_MEM_NB_ENTRIES)
> + Â Â Â Â Â Âreturn -1;
> + Â Â Â Âio_index = io_mem_nb++;
> + Â Â} else {
> + Â Â Â Âif (io_index >= IO_MEM_NB_ENTRIES)
> + Â Â Â Â Â Âreturn -1;
> + Â Â}
> +
> + Â Âfor(i = 0;i < 3; i++) {
> + Â Â Â Âio_mem_read[io_index][i] = mem_read[i];
> + Â Â Â Âio_mem_write[io_index][i] = mem_write[i];
> + Â Â}
> + Â Âio_mem_opaque[io_index] = opaque;
> + Â Âreturn io_index << IO_MEM_SHIFT;
> +}
> +
> +int cpu_register_io_memory(CPUReadMemoryFunc * const *mem_read,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â CPUWriteMemoryFunc * const *mem_write,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â void *opaque)
> +{
> + Â Âreturn cpu_register_io_memory_fixed(0, mem_read, mem_write, opaque);
> +}
> +
> +void cpu_unregister_io_memory(int io_table_address)
> +{
> + Â Âint i;
> + Â Âint io_index = io_table_address >> IO_MEM_SHIFT;
> +
> + Â Âfor (i = 0; i < mmio_cnt; i++) {
> + Â Â Â Âif (mmio[i].size && mmio[i].io_index == io_index) {
> + Â Â Â Â Â Âmmio[i].start = mmio[i].size = 0;
> + Â Â Â Â Â Âbreak;
> + Â Â Â Â}
> + Â Â}
> +
> + Â Âfor (i=0;i < 3; i++) {
> + Â Â Â Âio_mem_read[io_index][i] = NULL;
> + Â Â Â Âio_mem_write[io_index][i] = NULL;
> + Â Â}
> + Â Âio_mem_opaque[io_index] = NULL;
> +}
> +
> +int cpu_physical_memory_set_dirty_tracking(int enable)
> +{
> + Â Âreturn 0;
> +}
> +
> +#ifdef __ia64__
> +
> +#define __ia64_fc(addr) asm volatile ("fc %0" :: "r"(addr) : "memory")
> +#define ia64_sync_i() Â asm volatile (";; sync.i" ::: "memory")
> +#define ia64_srlz_i() Â asm volatile (";; srlz.i ;;" ::: "memory")
> +
> +/* IA64 has seperate I/D cache, with coherence maintained by DMA controller.
> + * So to emulate right behavior that guest OS is assumed, we need to flush
> + * I/D cache here.
> + */
> +static void sync_icache(uint8_t *address, int len)
> +{
> + Â Âunsigned long addr = (unsigned long)address;
> + Â Âunsigned long end = addr + len;
> +
> + Â Âfor (addr &= ~(32UL-1); addr < end; addr += 32UL) {
> + Â Â Â Â__ia64_fc(addr);
> + Â Â}
> +
> + Â Âia64_sync_i();
> + Â Âia64_srlz_i();
> +}
> +#endif
> +
> +static int iomem_index(target_phys_addr_t addr)
> +{
> + Â Âint i;
> +
> + Â Âfor (i = 0; i < mmio_cnt; i++) {
> + Â Â Â Âunsigned long start, end;
> +
> + Â Â Â Âstart = mmio[i].start;
> + Â Â Â Âend = mmio[i].start + mmio[i].size;
> +
> + Â Â Â Âif ((addr >= start) && (addr < end)) {
> + Â Â Â Â Â Âreturn (mmio[i].io_index >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 
> 1);
> + Â Â Â Â}
> + Â Â}
> + Â Âreturn 0;
> +}
> +
> +unsigned int xen_logdirty_enable = 0;
> +
> +/*
> + * Replace the standard byte memcpy with a word memcpy for appropriately 
> sized
> + * memory copy operations. ÂSome users (USB-UHCI) can not tolerate the 
> possible
> + * word tearing that can result from a guest concurrently writing a memory
> + * structure while the qemu device model is modifying the same location.
> + * Forcing a word-sized read/write prevents the guest from seeing a partially
> + * written word-sized atom.
> + */
> +#if defined(__x86_64__) || defined(__i386__)
> +static void memcpy_words(void *dst, void *src, size_t n)
> +{
> + Â Âasm volatile (
> + Â Â Â Â" Â movl %%edx,%%ecx \n"
> +#ifdef __x86_64__
> +    Â"  shrl $3,%%ecx  Â\n"
> +    Â"  rep Âmovsq    \n"
> +    Â"  test $4,%%edx  Â\n"
> +    Â"  jz  1f     Â\n"
> +    Â"  movsl      Â\n"
> +#else /* __i386__ */
> +    Â"  shrl $2,%%ecx  Â\n"
> +    Â"  rep Âmovsl    \n"
> +#endif
> +    Â"1: test $2,%%edx  Â\n"
> +    Â"  jz  1f     Â\n"
> +    Â"  movsw      Â\n"
> +    Â"1: test $1,%%edx  Â\n"
> +    Â"  jz  1f     Â\n"
> +    Â"  movsb      Â\n"
> + Â Â Â Â"1: Â Â Â Â Â Â Â Â Â\n"
> + Â Â Â Â: "+S" (src), "+D" (dst) : "d" (n) : "ecx", "memory" );
> +}
> +#else
> +static void memcpy_words(void *dst, void *src, size_t n)
> +{
> + Â Â/* Some architectures do not like unaligned accesses. */
> + Â Âif (((unsigned long)dst | (unsigned long)src) & 3) {
> + Â Â Â Âmemcpy(dst, src, n);
> + Â Â Â Âreturn;
> + Â Â}
> +
> + Â Âwhile (n >= sizeof(uint32_t)) {
> + Â Â Â Â*((uint32_t *)dst) = *((uint32_t *)src);
> + Â Â Â Âdst = ((uint32_t *)dst) + 1;
> + Â Â Â Âsrc = ((uint32_t *)src) + 1;
> + Â Â Â Ân -= sizeof(uint32_t);
> + Â Â}
> +
> + Â Âif (n & 2) {
> + Â Â Â Â*((uint16_t *)dst) = *((uint16_t *)src);
> + Â Â Â Âdst = ((uint16_t *)dst) + 1;
> + Â Â Â Âsrc = ((uint16_t *)src) + 1;
> + Â Â}
> +
> + Â Âif (n & 1) {
> + Â Â Â Â*((uint8_t *)dst) = *((uint8_t *)src);
> + Â Â Â Âdst = ((uint8_t *)dst) + 1;
> + Â Â Â Âsrc = ((uint8_t *)src) + 1;
> + Â Â}
> +}
> +#endif
> +
> +void cpu_physical_memory_rw(target_phys_addr_t _addr, uint8_t *buf,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Âint _len, int is_write)
> +{
> + Â Âtarget_phys_addr_t addr = _addr;
> + Â Âint len = _len;
> + Â Âint l, io_index;
> + Â Âuint8_t *ptr;
> + Â Âuint32_t val;
> +
> + Â Âmapcache_lock();
> +
> + Â Âwhile (len > 0) {
> + Â Â Â Â/* How much can we copy before the next page boundary? */
> + Â Â Â Âl = TARGET_PAGE_SIZE - (addr & ~TARGET_PAGE_MASK);
> + Â Â Â Âif (l > len) {
> + Â Â Â Â Â Âl = len;
> + Â Â Â Â}
> +
> + Â Â Â Âio_index = iomem_index(addr);
> + Â Â Â Âif (is_write) {
> + Â Â Â Â Â Âif (io_index) {
> + Â Â Â Â Â Â Â Âif (l >= 4 && ((addr & 3) == 0)) {
> + Â Â Â Â Â Â Â Â Â Â/* 32 bit read access */
> + Â Â Â Â Â Â Â Â Â Âval = ldl_raw(buf);
> + Â Â Â Â Â Â Â Â Â Âio_mem_write[io_index][2](io_mem_opaque[io_index], addr, 
> val);
> + Â Â Â Â Â Â Â Â Â Âl = 4;
> + Â Â Â Â Â Â Â Â} else if (l >= 2 && ((addr & 1) == 0)) {
> + Â Â Â Â Â Â Â Â Â Â/* 16 bit read access */
> + Â Â Â Â Â Â Â Â Â Âval = lduw_raw(buf);
> + Â Â Â Â Â Â Â Â Â Âio_mem_write[io_index][1](io_mem_opaque[io_index], addr, 
> val);
> + Â Â Â Â Â Â Â Â Â Âl = 2;
> + Â Â Â Â Â Â Â Â} else {
> + Â Â Â Â Â Â Â Â Â Â/* 8 bit access */
> + Â Â Â Â Â Â Â Â Â Âval = ldub_raw(buf);
> + Â Â Â Â Â Â Â Â Â Âio_mem_write[io_index][0](io_mem_opaque[io_index], addr, 
> val);
> + Â Â Â Â Â Â Â Â Â Âl = 1;
> + Â Â Â Â Â Â Â Â}
> + Â Â Â Â Â Â} else if ((ptr = phys_ram_addr(addr)) != NULL) {
> + Â Â Â Â Â Â Â Â/* Writing to RAM */
> + Â Â Â Â Â Â Â Âmemcpy_words(ptr, buf, l);
> +
> + Â Â Â Â Â Â Â Âif (xen_logdirty_enable) {
> + Â Â Â Â Â Â Â Â Â Âxc_hvm_modified_memory(xen_xc,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Âxen_domid,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Âaddr >> TARGET_PAGE_BITS,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â((addr + l + TARGET_PAGE_SIZE - 1) >> 
> TARGET_PAGE_BITS)
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â- (addr >> TARGET_PAGE_BITS));
> + Â Â Â Â Â Â Â Â}
> +#ifdef __ia64__
> + Â Â Â Â Â Â Â Âsync_icache(ptr, l);
> +#endif
> + Â Â Â Â Â Â}
> + Â Â Â Â} else {
> + Â Â Â Â Â Âif (io_index) {
> + Â Â Â Â Â Â Â Âif (l >= 4 && ((addr & 3) == 0)) {
> + Â Â Â Â Â Â Â Â Â Â/* 32 bit read access */
> + Â Â Â Â Â Â Â Â Â Âval = io_mem_read[io_index][2](io_mem_opaque[io_index], 
> addr);
> + Â Â Â Â Â Â Â Â Â Âstl_raw(buf, val);
> + Â Â Â Â Â Â Â Â Â Âl = 4;
> + Â Â Â Â Â Â Â Â} else if (l >= 2 && ((addr & 1) == 0)) {
> + Â Â Â Â Â Â Â Â Â Â/* 16 bit read access */
> + Â Â Â Â Â Â Â Â Â Âval = io_mem_read[io_index][1](io_mem_opaque[io_index], 
> addr);
> + Â Â Â Â Â Â Â Â Â Âstw_raw(buf, val);
> + Â Â Â Â Â Â Â Â Â Âl = 2;
> + Â Â Â Â Â Â Â Â} else {
> + Â Â Â Â Â Â Â Â Â Â/* 8 bit access */
> + Â Â Â Â Â Â Â Â Â Âval = io_mem_read[io_index][0](io_mem_opaque[io_index], 
> addr);
> + Â Â Â Â Â Â Â Â Â Âstb_raw(buf, val);
> + Â Â Â Â Â Â Â Â Â Âl = 1;
> + Â Â Â Â Â Â Â Â}
> + Â Â Â Â Â Â} else if ((ptr = phys_ram_addr(addr)) != NULL) {
> + Â Â Â Â Â Â Â Â/* Reading from RAM */
> + Â Â Â Â Â Â Â Âmemcpy_words(buf, ptr, l);
> + Â Â Â Â Â Â} else {
> + Â Â Â Â Â Â Â Â/* Neither RAM nor known MMIO space */
> + Â Â Â Â Â Â Â Âmemset(buf, 0xff, len);
> + Â Â Â Â Â Â}
> + Â Â Â Â}
> + Â Â Â Âlen -= l;
> + Â Â Â Âbuf += l;
> + Â Â Â Âaddr += l;
> + Â Â}
> +
> + Â Âmapcache_unlock();
> +}
> +
> +/* virtual memory access for debug */
> +int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
> + Â Â Â Â Â Â Â Â Â Â Â Âuint8_t *buf, int len, int is_write)
> +{
> + Â Âint l;
> + Â Âtarget_ulong page, phys_addr;
> +
> + Â Âwhile (len > 0) {
> + Â Â Â Âpage = addr & TARGET_PAGE_MASK;
> + Â Â Â Âphys_addr = cpu_get_phys_page_debug(env, page);
> + Â Â Â Â/* if no physical page mapped, return an error */
> + Â Â Â Âif (phys_addr == -1)
> + Â Â Â Â Â Âreturn -1;
> + Â Â Â Âl = (page + TARGET_PAGE_SIZE) - addr;
> + Â Â Â Âif (l > len)
> + Â Â Â Â Â Âl = len;
> + Â Â Â Âcpu_physical_memory_rw(phys_addr + (addr & ~TARGET_PAGE_MASK),
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â buf, l, is_write);
> + Â Â Â Âlen -= l;
> + Â Â Â Âbuf += l;
> + Â Â Â Âaddr += l;
> + Â Â}
> + Â Âreturn 0;
> +}
> +
> +void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â int dirty_flags)
> +{
> + Â Âunsigned long length;
> + Â Âint i, mask, len;
> + Â Âuint8_t *p;
> +
> + Â Âstart &= TARGET_PAGE_MASK;
> + Â Âend = TARGET_PAGE_ALIGN(end);
> +
> + Â Âlength = end - start;
> + Â Âif (length == 0)
> + Â Â Â Âreturn;
> + Â Âmask = ~dirty_flags;
> + Â Âp = ram_list.phys_dirty + (start >> TARGET_PAGE_BITS);
> + Â Âlen = length >> TARGET_PAGE_BITS;
> + Â Âfor(i = 0; i < len; i++) {
> + Â Â Â Âp[i] &= mask;
> + Â Â}
> +
> + Â Âreturn;
> +}
> +
> +
> +/* Unoptimised in Xen DM, nicked from git
> + * Âaab33094073678d459ccaac5c60ea7533e8d1d8e */
> +uint32_t ldub_phys(target_phys_addr_t addr)
> +{
> + Â Âuint8_t val;
> + Â Âcpu_physical_memory_read(addr, &val, 1);
> + Â Âreturn val;
> +}
> +uint32_t lduw_phys(target_phys_addr_t addr)
> +{
> + Â Âuint16_t val;
> + Â Âcpu_physical_memory_read(addr, (uint8_t *)&val, 2);
> + Â Âreturn tswap16(val);
> +}
> +uint64_t ldq_phys(target_phys_addr_t addr)
> +{
> + Â Âuint64_t val;
> + Â Âcpu_physical_memory_read(addr, (uint8_t *)&val, 8);
> + Â Âreturn tswap64(val);
> +}
> +void stb_phys(target_phys_addr_t addr, uint32_t val)
> +{
> + Â Âuint8_t v = val;
> + Â Âcpu_physical_memory_write(addr, &v, 1);
> +}
> +void stw_phys(target_phys_addr_t addr, uint32_t val)
> +{
> + Â Âuint16_t v = tswap16(val);
> + Â Âcpu_physical_memory_write(addr, (const uint8_t *)&v, 2);
> +}
> +void stq_phys(target_phys_addr_t addr, uint64_t val)
> +{
> + Â Âval = tswap64(val);
> + Â Âcpu_physical_memory_write(addr, (const uint8_t *)&val, 8);
> +}
> +
> +/* stubs which we hope (think!) are OK for Xen DM */
> +void stl_phys(target_phys_addr_t addr, uint32_t val)
> +{
> + Â Âval = tswap32(val);
> + Â Âcpu_physical_memory_write(addr, (const uint8_t *)&val, 4);
> +}
> +void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val)
> +{
> + Â Âstl_phys(addr, val);
> +}
> +uint32_t ldl_phys(target_phys_addr_t addr)
> +{
> + Â Âuint32_t val;
> + Â Âcpu_physical_memory_read(addr, (uint8_t *)&val, 4);
> + Â Âreturn tswap32(val);
> +}
> +
> +void cpu_physical_memory_write_rom(target_phys_addr_t addr,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â const uint8_t *buf, int len)
> +{
> + Â Âreturn cpu_physical_memory_write(addr,buf,len);
> +}
> +
> +void qemu_register_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size)
> +{
> +}
> +void qemu_unregister_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size)
> +{
> +}
> +
> +/* stub out various functions for Xen DM */
> +void dump_exec_info(FILE *f,
> + Â Â Â Â Â Â Â Â Â Âint (*cpu_fprintf)(FILE *f, const char *fmt, ...))
> +{
> +}
> +
> +void monitor_disas(Monitor *mon, CPUState *env,
> + Â Â Â Â Â Â Â Â Â target_ulong pc, int nb_insn, int is_physical, int flags)
> +{
> +}
> +
> +/*
> + * This next section was clone-and-hacked from the version in exec.c
> + * :-(. ÂBut the exec.c version is full of tcg-specific stuff and
> + * assumptions about phys_ram_base.

Then fix those assumptions and introduce xen specific hooks, like KVM.

> + */
> +
> +typedef struct MapClient {
> + Â Âvoid *opaque;
> + Â Âvoid (*callback)(void *opaque);
> + Â ÂQLIST_ENTRY(MapClient) link;
> +} MapClient;
> +
> +static QLIST_HEAD(map_client_list, MapClient) map_client_list
> + Â Â= QLIST_HEAD_INITIALIZER(map_client_list);
> +
> +void *cpu_register_map_client(void *opaque, void (*callback)(void *opaque))
> +{
> + Â ÂMapClient *client = qemu_malloc(sizeof(*client));
> +
> + Â Âclient->opaque = opaque;
> + Â Âclient->callback = callback;
> + Â ÂQLIST_INSERT_HEAD(&map_client_list, client, link);
> + Â Âreturn client;
> +}
> +
> +void cpu_unregister_map_client(void *_client)
> +{
> + Â ÂMapClient *client = (MapClient *)_client;
> +
> + Â ÂQLIST_REMOVE(client, link);
> + Â Âqemu_free(client);
> +}
> +
> +static void cpu_notify_map_clients(void)
> +{
> + Â ÂMapClient *client;
> +
> + Â Âwhile (!QLIST_EMPTY(&map_client_list)) {
> + Â Â Â Âclient = QLIST_FIRST(&map_client_list);
> + Â Â Â Âclient->callback(client->opaque);
> + Â Â Â Âcpu_unregister_map_client(client);
> + Â Â}
> +}
> +
> +/* Map a physical memory region into a host virtual address.
> + * May map a subset of the requested range, given by and returned in *plen.
> + * May return NULL if resources needed to perform the mapping are exhausted.
> + * Use only for reads OR writes - not for read-modify-write operations.
> + * Use cpu_register_map_client() to know when retrying the map operation is
> + * likely to succeed.
> + */
> +void *cpu_physical_memory_map(target_phys_addr_t addr,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âtarget_phys_addr_t *plen,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âint is_write)
> +{
> + Â Âunsigned long l = 0;
> +#ifdef MAPCACHE
> + Â Âl = MCACHE_BUCKET_SIZE - (addr & (MCACHE_BUCKET_SIZE-1));
> + Â Âif ((*plen) > l) {
> + Â Â Â Â*plen = l;
> + Â Â}
> +#endif
> + Â Âif (xen_logdirty_enable) {
> + Â Â Â Âxc_hvm_modified_memory(xen_xc, xen_domid, addr >> TARGET_PAGE_BITS,
> + Â Â Â Â Â Â Â Â((addr + l + TARGET_PAGE_SIZE - 1) >> TARGET_PAGE_BITS)
> + Â Â Â Â Â Â Â Â Â Â- (addr >> TARGET_PAGE_BITS));
> + Â Â}
> +
> + Â Âreturn qemu_map_cache(addr, 1);
> +}
> +
> +/* Unmaps a memory region previously mapped by cpu_physical_memory_map().
> + * Will also mark the memory as dirty if is_write == 1. Âaccess_len gives
> + * the amount of memory that was actually read or written by the caller.
> + */
> +void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â int is_write, target_phys_addr_t access_len)
> +{
> + Â Âqemu_invalidate_entry(buffer);
> + Â Âcpu_notify_map_clients();
> +}
> +
> +
> +void cpu_exit(CPUState *env)
> +{
> + Â Âenv->exit_request = 1;
> +}
> +
> +void qemu_flush_coalesced_mmio_buffer(void)
> +{
> +}
> +
> +void *qemu_get_ram_ptr(ram_addr_t addr)
> +{
> + Â ÂRAMBlock *block;
> +
> + Â ÂQLIST_FOREACH(block, &ram_list.blocks, next) {
> + Â Â Â Âif (addr - block->offset < block->length) {
> + Â Â Â Â Â ÂQLIST_REMOVE(block, next);
> + Â Â Â Â Â ÂQLIST_INSERT_HEAD(&ram_list.blocks, block, next);
> + Â Â Â Â Â Âreturn block->host + (addr - block->offset);
> + Â Â Â Â}
> + Â Â}
> + Â Âreturn block->host + (addr - block->offset);
> +
> + Â Âfprintf(stderr, "Bad ram offset %" PRIx64 "\n", (uint64_t)addr);
> + Â Âabort();
> +
> + Â Âreturn NULL;
> +}
> +
> +int cpu_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â target_phys_addr_t end_addr)
> +{
> + Â Âreturn 0;
> +}
> +ram_addr_t cpu_get_physical_page_desc(target_phys_addr_t addr)
> +{
> + Â Âreturn 0;
> +}
> +
> +static ram_addr_t find_ram_offset(ram_addr_t size)
> +{
> + Â ÂRAMBlock *block;
> + Â Âram_addr_t last = 0;
> +
> + Â ÂQLIST_FOREACH(block, &ram_list.blocks, next) {
> + Â Â Â Âlast = MAX(last, block->offset + block->length);
> + Â Â}
> +
> + Â Âreturn last;
> +}
> +
> +ram_addr_t qemu_ram_alloc(DeviceState *dev, const char *name, ram_addr_t 
> size)
> +{
> + Â ÂRAMBlock *new_block;
> +
> + Â Âsize = TARGET_PAGE_ALIGN(size);
> + Â Ânew_block = qemu_malloc(sizeof(*new_block));
> +
> + Â Âif (mem_path) {
> +#if defined (__linux__) && !defined(TARGET_S390X)
> + Â Â Â Ânew_block->host = 0; // file_ram_alloc(size, mem_path);
> + Â Â Â Âif (!new_block->host) {
> + Â Â Â Â Â Ânew_block->host = qemu_vmalloc(size);
> +#ifdef MADV_MERGEABLE
> + Â Â Â Â Â Âmadvise(new_block->host, size, MADV_MERGEABLE);
> +#endif
> + Â Â Â Â}
> +#else
> + Â Â Â Âfprintf(stderr, "-mem-path option unsupported\n");
> + Â Â Â Âexit(1);
> +#endif
> + Â Â} else {
> + Â Â Â Ânew_block->host = qemu_vmalloc(size);
> +#ifdef MADV_MERGEABLE
> + Â Â Â Âmadvise(new_block->host, size, MADV_MERGEABLE);
> +#endif
> + Â Â}
> + Â Ânew_block->offset = find_ram_offset(size);
> + Â Ânew_block->length = size;
> +
> + Â ÂQLIST_INSERT_HEAD(&ram_list.blocks, new_block, next);
> +
> + Â Âram_list.phys_dirty = qemu_realloc(ram_list.phys_dirty,
> + Â Â Â Â(new_block->offset + size) >> TARGET_PAGE_BITS);
> + Â Âmemset(ram_list.phys_dirty + (new_block->offset >> TARGET_PAGE_BITS),
> + Â Â Â Â Â 0xff, size >> TARGET_PAGE_BITS);
> +
> + Â Âreturn new_block->offset;
> +}
> +
> +void qemu_ram_free(ram_addr_t addr)
> +{
> +}
> +
> +void tb_flush(CPUState *env1)
> +{
> +}
> +
> +int cpu_watchpoint_insert(CPUState *env, target_ulong addr, target_ulong len,
> + Â Â Â Â Â Â Â Â Â Â Â Â Âint flags, CPUWatchpoint **watchpoint)
> +{
> + Â Âreturn -ENOSYS;
> +}
> +
> +int cpu_watchpoint_remove(CPUState *env, target_ulong addr, target_ulong len,
> + Â Â Â Â Â Â Â Â Â Â Â Â Âint flags)
> +{
> + Â Âreturn -ENOENT;
> +}
> +
> +void cpu_watchpoint_remove_all(CPUState *env, int mask)
> +{
> +}
> +
> +int cpu_breakpoint_insert(CPUState *env, target_ulong pc, int flags,
> + Â Â Â Â Â Â Â Â Â Â Â Â ÂCPUBreakpoint **breakpoint)
> +{
> + Â Âreturn -ENOSYS;
> +}
> +
> +int cpu_breakpoint_remove(CPUState *env, target_ulong pc, int flags)
> +{
> + Â Âreturn -ENOSYS;
> +}
> +
> +void cpu_breakpoint_remove_all(CPUState *env, int mask)
> +{
> +}
> +
> +void cpu_single_step(CPUState *env, int enabled)
> +{
> +}
> diff --git a/target-xen/helper.c b/target-xen/helper.c
> new file mode 100644
> index 0000000..d588e64
> --- /dev/null
> +++ b/target-xen/helper.c
> @@ -0,0 +1,69 @@
> +/*
> + * Âi386 helpers (without register variable usage)
> + *
> + * ÂCopyright (c) 2003 Fabrice Bellard
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2 of the License, or (at your option) any later version.
> + *
> + * This library 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
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA Â02111-1307 ÂUSA
> + */
> +
> +#include "cpu.h"
> +
> +CPUXenState *cpu_xen_init(const char *cpu_model)
> +{
> + Â ÂCPUXenState *env = NULL;
> + Â Âstatic int inited;
> +
> + Â Âenv = qemu_mallocz(sizeof(CPUXenState));
> + Â Âif (!env)

qemu_mallocz won't return NULL.

> + Â Â Â Âreturn NULL;
> + Â Âcpu_exec_init(env);
> +
> + Â Â/* init various static tables */
> + Â Âif (!inited) {
> + Â Â Â Âinited = 1;
> +
> + Â Â Â Âcpu_single_env = env;
> + Â Â}
> +
> + Â Âreturn env;
> +}
> +
> +int cpu_xen_exec(CPUState *env1)
> +{
> + Â Âreturn 0;
> +}
> +
> +void cpu_reset(CPUXenState *env)
> +{
> +}
> +
> +void cpu_dump_state(CPUState *env, FILE *f,
> + Â Â Â Â Â Â Â Â Â Âint (*cpu_fprintf)(FILE *f, const char *fmt, ...),
> + Â Â Â Â Â Â Â Â Â Âint flags)
> +{
> +}
> +
> +/***********************************************************/
> +/* x86 mmu */
> +/* XXX: add PGE support */
> +
> +void cpu_x86_set_a20(CPUXenState *env, int a20_state)
> +{
> +}
> +
> +target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
> +{
> + Â Âreturn addr;
> +}
> diff --git a/target-xen/machine.c b/target-xen/machine.c
> new file mode 100644
> index 0000000..e69de29
> diff --git a/target-xen/qemu-xen.h b/target-xen/qemu-xen.h
> new file mode 100644
> index 0000000..d1910d6
> --- /dev/null
> +++ b/target-xen/qemu-xen.h
> @@ -0,0 +1,30 @@
> +#ifndef QEMU_XEN_H
> +#define QEMU_XEN_H
> +
> +#include "hw/xen_common.h"
> +
> +/* vl.c */
> +
> +#if defined(__i386__) || defined(__x86_64__)
> +#define phys_ram_addr(x) (qemu_map_cache(x, 0))
> +#elif defined(__ia64__)
> +#define phys_ram_addr(x) (((x) < ram_size) ? (phys_ram_base + (x)) : NULL)
> +#endif
> +
> +/* xen_mapcache.c */
> +
> +uint8_t *qemu_map_cache(target_phys_addr_t phys_addr, uint8_t lock);
> +void   qemu_invalidate_entry(uint8_t *buffer);
> +void   qemu_invalidate_map_cache(void);
> +
> +#define mapcache_lock() Â ((void)0)
> +#define mapcache_unlock() ((void)0)
> +
> +/* target-xen/exec-dm.c */
> +
> +int cpu_register_io_memory_fixed(int io_index,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â CPUReadMemoryFunc * const *mem_read,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â CPUWriteMemoryFunc * const *mem_write,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â void *opaque);
> +
> +#endif /*QEMU_XEN_H*/
> diff --git a/target-xen/stub-functions.c b/target-xen/stub-functions.c
> new file mode 100644
> index 0000000..0db6898
> --- /dev/null
> +++ b/target-xen/stub-functions.c
> @@ -0,0 +1,42 @@
> +#include "config.h"
> +#include "disas.h"
> +#include "hw/apic.h"
> +#include "hw/pc.h"
> +#include "cpu.h"
> +
> +/* disas */
> +struct syminfo *syminfos = NULL;
> +
> +/* apic */
> +void apic_deliver_pic_intr(DeviceState *d, int level)
> +{
> +}
> +
> +int apic_get_interrupt(DeviceState *d)
> +{
> + Â Âreturn -1;
> +}
> +
> +int apic_accept_pic_intr(DeviceState *d)
> +{
> + Â Âreturn 0;
> +}
> +
> +/* vmmouse */
> +void *vmmouse_init(void *m)
> +{
> + Â Âreturn NULL;
> +}
> +
> +/* cpu-exec */
> +volatile sig_atomic_t exit_request;
> +
> +CPUDebugExcpHandler *cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler)
> +{
> + Â Âreturn NULL;
> +}
> +
> +int qemu_cpu_has_work(CPUState *env)
> +{
> + Â Âreturn 0;
> +}
> diff --git a/target-xen/xen_mapcache.c b/target-xen/xen_mapcache.c
> new file mode 100644
> index 0000000..39daae2
> --- /dev/null
> +++ b/target-xen/xen_mapcache.c
> @@ -0,0 +1,14 @@
> +#include "qemu-xen.h"
> +
> +uint8_t *qemu_map_cache(target_phys_addr_t phys_addr, uint8_t lock)
> +{
> + Â Âreturn phys_ram_addr(phys_addr);
> +}
> +
> +void qemu_invalidate_map_cache(void)
> +{
> +}
> +
> +void qemu_invalidate_entry(uint8_t *buffer)
> +{
> +}
> --
> 1.7.0.4
>
>
>

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.