From 5e8861a0361d8d39ab69fe557294471c28c49c8b Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 29 May 2012 10:23:15 +0200 Subject: build: move obj-TARGET-y variables to nested Makefile.objs Also drop duplicate occurrence of device-hotplug.o. Signed-off-by: Paolo Bonzini --- Makefile.target | 186 +-------------- arm-semi.c | 509 ---------------------------------------- configure | 48 ++-- hw/alpha/Makefile.objs | 4 + hw/arm/Makefile.objs | 39 +++ hw/cris/Makefile.objs | 13 + hw/i386/Makefile.objs | 13 + hw/lm32/Makefile.objs | 23 ++ hw/m68k/Makefile.objs | 4 + hw/microblaze/Makefile.objs | 13 + hw/mips/Makefile.objs | 6 + hw/ppc/Makefile.objs | 31 +++ hw/s390x/Makefile.objs | 3 + hw/sh4/Makefile.objs | 5 + hw/sparc/Makefile.objs | 8 + hw/sparc64/Makefile.objs | 4 + hw/xtensa/Makefile.objs | 5 + ioport-user.c | 60 ----- m68k-semi.c | 408 -------------------------------- target-alpha/Makefile.objs | 1 + target-arm/Makefile.objs | 1 + target-arm/arm-semi.c | 509 ++++++++++++++++++++++++++++++++++++++++ target-cris/Makefile.objs | 1 + target-i386/Makefile.objs | 3 + target-i386/ioport-user.c | 60 +++++ target-lm32/Makefile.objs | 1 + target-m68k/Makefile.objs | 1 + target-m68k/m68k-semi.c | 408 ++++++++++++++++++++++++++++++++ target-microblaze/Makefile.objs | 1 + target-mips/Makefile.objs | 1 + target-ppc/Makefile.objs | 1 + target-s390x/Makefile.objs | 1 + target-sh4/Makefile.objs | 1 + target-sparc/Makefile.objs | 1 + target-unicore32/Makefile.objs | 1 + target-xtensa/Makefile.objs | 4 + target-xtensa/xtensa-semi.c | 224 ++++++++++++++++++ xtensa-semi.c | 224 ------------------ 38 files changed, 1430 insertions(+), 1396 deletions(-) delete mode 100644 arm-semi.c create mode 100644 hw/alpha/Makefile.objs create mode 100644 hw/arm/Makefile.objs create mode 100644 hw/cris/Makefile.objs create mode 100644 hw/i386/Makefile.objs create mode 100644 hw/lm32/Makefile.objs create mode 100644 hw/m68k/Makefile.objs create mode 100644 hw/microblaze/Makefile.objs create mode 100644 hw/mips/Makefile.objs create mode 100644 hw/ppc/Makefile.objs create mode 100644 hw/s390x/Makefile.objs create mode 100644 hw/sh4/Makefile.objs create mode 100644 hw/sparc/Makefile.objs create mode 100644 hw/sparc64/Makefile.objs create mode 100644 hw/xtensa/Makefile.objs delete mode 100644 ioport-user.c delete mode 100644 m68k-semi.c create mode 100644 target-alpha/Makefile.objs create mode 100644 target-arm/Makefile.objs create mode 100644 target-arm/arm-semi.c create mode 100644 target-cris/Makefile.objs create mode 100644 target-i386/Makefile.objs create mode 100644 target-i386/ioport-user.c create mode 100644 target-lm32/Makefile.objs create mode 100644 target-m68k/Makefile.objs create mode 100644 target-m68k/m68k-semi.c create mode 100644 target-microblaze/Makefile.objs create mode 100644 target-mips/Makefile.objs create mode 100644 target-ppc/Makefile.objs create mode 100644 target-s390x/Makefile.objs create mode 100644 target-sh4/Makefile.objs create mode 100644 target-sparc/Makefile.objs create mode 100644 target-unicore32/Makefile.objs create mode 100644 target-xtensa/Makefile.objs create mode 100644 target-xtensa/xtensa-semi.c delete mode 100644 xtensa-semi.c diff --git a/Makefile.target b/Makefile.target index 5cc577b890..c416ba56fc 100644 --- a/Makefile.target +++ b/Makefile.target @@ -102,6 +102,8 @@ libobj-$(TARGET_ALPHA) += int_helper.o fpu_helper.o sys_helper.o mem_helper.o libobj-y += disas.o libobj-$(CONFIG_TCI_DIS) += tci-dis.o +obj-y += target-$(TARGET_BASE_ARCH)/ + tci-dis.o: QEMU_CFLAGS += -I$(SRC_PATH)/tcg -I$(SRC_PATH)/tcg/tci # HELPER_CFLAGS is used for all the legacy code compiled with static register @@ -124,9 +126,6 @@ QEMU_CFLAGS+=-I$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR) -I$(SRC_PATH)/linux-user obj-y += linux-user/ obj-y += gdbstub.o thunk.o user-exec.o $(oslib-obj-y) -obj-i386-y += ioport-user.o -obj-$(TARGET_ARM) += arm-semi.o -obj-$(TARGET_M68K) += m68k-semi.o obj-y += $(addprefix ../, $(universal-obj-y)) obj-y += $(addprefix ../libuser/, $(user-obj-y)) @@ -144,7 +143,6 @@ QEMU_CFLAGS+=-I$(SRC_PATH)/bsd-user -I$(SRC_PATH)/bsd-user/$(TARGET_ARCH) obj-y += bsd-user/ obj-y += gdbstub.o user-exec.o -obj-i386-y += ioport-user.o obj-y += $(addprefix ../, $(universal-obj-y)) obj-y += $(addprefix ../libuser/, $(user-obj-y)) @@ -157,7 +155,7 @@ endif #CONFIG_BSD_USER # System emulator target ifdef CONFIG_SOFTMMU -obj-y = arch_init.o cpus.o monitor.o machine.o gdbstub.o balloon.o ioport.o +obj-y += arch_init.o cpus.o monitor.o machine.o gdbstub.o balloon.o ioport.o # virtio has to be here due to weird dependency between PCI and virtio-net. # need to fix this properly obj-$(CONFIG_NO_PCI) += pci-stub.o @@ -175,8 +173,6 @@ obj-$(CONFIG_HAVE_GET_MEMORY_MAPPING) += arch_memory_mapping.o obj-$(CONFIG_HAVE_CORE_DUMP) += arch_dump.o LIBS+=-lz -obj-i386-$(CONFIG_KVM) += hyperv.o - QEMU_CFLAGS += $(VNC_TLS_CFLAGS) QEMU_CFLAGS += $(VNC_SASL_CFLAGS) QEMU_CFLAGS += $(VNC_JPEG_CFLAGS) @@ -186,8 +182,6 @@ QEMU_CFLAGS += $(VNC_PNG_CFLAGS) obj-$(CONFIG_XEN) += xen-all.o xen_machine_pv.o xen_domainbuild.o xen-mapcache.o obj-$(CONFIG_NO_XEN) += xen-stub.o -obj-i386-$(CONFIG_XEN) += xen_platform.o xen_apic.o - # Inter-VM PCI shared memory CONFIG_IVSHMEM = ifeq ($(CONFIG_KVM), y) @@ -201,172 +195,18 @@ obj-$(CONFIG_IVSHMEM) += ivshmem.o obj-y += device-hotplug.o # Hardware support -obj-i386-y += mc146818rtc.o pc.o -obj-i386-y += apic_common.o apic.o kvmvapic.o -obj-i386-y += sga.o ioapic_common.o ioapic.o piix_pci.o -obj-i386-y += vmport.o -obj-i386-y += pci-hotplug.o smbios.o wdt_ib700.o -obj-i386-y += debugcon.o multiboot.o -obj-i386-y += pc_piix.o -obj-i386-y += pc_sysfw.o -obj-i386-$(CONFIG_KVM) += kvm/clock.o kvm/apic.o kvm/i8259.o kvm/ioapic.o kvm/i8254.o -obj-i386-$(CONFIG_SPICE) += qxl.o qxl-logger.o qxl-render.o - -# shared objects -obj-ppc-y = ppc.o ppc_booke.o -# PREP target -obj-ppc-y += mc146818rtc.o -obj-ppc-y += ppc_prep.o -# OldWorld PowerMac -obj-ppc-y += ppc_oldworld.o -# NewWorld PowerMac -obj-ppc-y += ppc_newworld.o -# IBM pSeries (sPAPR) -obj-ppc-$(CONFIG_PSERIES) += spapr.o spapr_hcall.o spapr_rtas.o spapr_vio.o -obj-ppc-$(CONFIG_PSERIES) += xics.o spapr_vty.o spapr_llan.o spapr_vscsi.o -obj-ppc-$(CONFIG_PSERIES) += spapr_pci.o device-hotplug.o pci-hotplug.o -# PowerPC 4xx boards -obj-ppc-y += ppc4xx_devs.o ppc4xx_pci.o ppc405_uc.o ppc405_boards.o -obj-ppc-y += ppc440_bamboo.o -# PowerPC E500 boards -obj-ppc-y += ppce500_mpc8544ds.o mpc8544_guts.o ppce500_spin.o -# PowerPC 440 Xilinx ML507 reference board. -obj-ppc-y += virtex_ml507.o -obj-ppc-$(CONFIG_KVM) += kvm_ppc.o -obj-ppc-$(CONFIG_FDT) += device_tree.o -# PowerPC OpenPIC -obj-ppc-y += openpic.o - -# Xilinx PPC peripherals -obj-ppc-y += xilinx_intc.o -obj-ppc-y += xilinx_timer.o -obj-ppc-y += xilinx_uartlite.o -obj-ppc-y += xilinx_ethlite.o - -# LM32 boards -obj-lm32-y += lm32_boards.o -obj-lm32-y += milkymist.o - -# LM32 peripherals -obj-lm32-y += lm32_pic.o -obj-lm32-y += lm32_juart.o -obj-lm32-y += lm32_timer.o -obj-lm32-y += lm32_uart.o -obj-lm32-y += lm32_sys.o -obj-lm32-y += milkymist-ac97.o -obj-lm32-y += milkymist-hpdmc.o -obj-lm32-y += milkymist-memcard.o -obj-lm32-y += milkymist-minimac2.o -obj-lm32-y += milkymist-pfpu.o -obj-lm32-y += milkymist-softusb.o -obj-lm32-y += milkymist-sysctl.o -obj-lm32-$(CONFIG_OPENGL) += milkymist-tmu2.o -obj-lm32-y += milkymist-uart.o -obj-lm32-y += milkymist-vgafb.o -obj-lm32-y += framebuffer.o - -obj-mips-y = mips_r4k.o mips_jazz.o mips_malta.o mips_mipssim.o -obj-mips-y += mips_addr.o mips_timer.o mips_int.o -obj-mips-y += gt64xxx.o mc146818rtc.o -obj-mips-$(CONFIG_FULONG) += bonito.o vt82c686.o mips_fulong2e.o - -obj-microblaze-y = petalogix_s3adsp1800_mmu.o -obj-microblaze-y += petalogix_ml605_mmu.o -obj-microblaze-y += microblaze_boot.o - -obj-microblaze-y += microblaze_pic_cpu.o -obj-microblaze-y += xilinx_intc.o -obj-microblaze-y += xilinx_timer.o -obj-microblaze-y += xilinx_uartlite.o -obj-microblaze-y += xilinx_ethlite.o -obj-microblaze-y += xilinx_axidma.o -obj-microblaze-y += xilinx_axienet.o - -obj-microblaze-$(CONFIG_FDT) += device_tree.o - -# Boards -obj-cris-y = cris_pic_cpu.o -obj-cris-y += cris-boot.o -obj-cris-y += axis_dev88.o - -# IO blocks -obj-cris-y += etraxfs_dma.o -obj-cris-y += etraxfs_pic.o -obj-cris-y += etraxfs_eth.o -obj-cris-y += etraxfs_timer.o -obj-cris-y += etraxfs_ser.o - ifeq ($(TARGET_ARCH), sparc64) -obj-sparc-y = sun4u.o apb_pci.o -obj-sparc-y += mc146818rtc.o +obj-y += hw/sparc64/ else -obj-sparc-y = sun4m.o lance.o tcx.o sun4m_iommu.o slavio_intctl.o -obj-sparc-y += slavio_timer.o slavio_misc.o sparc32_dma.o -obj-sparc-y += cs4231.o eccmemctl.o sbi.o sun4c_intctl.o leon3.o - -# GRLIB -obj-sparc-y += grlib_gptimer.o grlib_irqmp.o grlib_apbuart.o +obj-y += hw/$(TARGET_BASE_ARCH)/ endif -obj-arm-y = integratorcp.o versatilepb.o arm_pic.o arm_timer.o -obj-arm-y += arm_boot.o pl011.o pl031.o pl050.o pl080.o pl110.o pl181.o pl190.o -obj-arm-y += versatile_pci.o -obj-arm-y += versatile_i2c.o -obj-arm-y += cadence_uart.o -obj-arm-y += cadence_ttc.o -obj-arm-y += cadence_gem.o -obj-arm-y += xilinx_zynq.o zynq_slcr.o -obj-arm-y += arm_gic.o -obj-arm-y += realview_gic.o realview.o arm_sysctl.o arm11mpcore.o a9mpcore.o -obj-arm-y += exynos4210_gic.o exynos4210_combiner.o exynos4210.o -obj-arm-y += exynos4_boards.o exynos4210_uart.o exynos4210_pwm.o -obj-arm-y += exynos4210_pmu.o exynos4210_mct.o exynos4210_fimd.o -obj-arm-y += arm_l2x0.o -obj-arm-y += arm_mptimer.o a15mpcore.o -obj-arm-y += armv7m.o armv7m_nvic.o stellaris.o pl022.o stellaris_enet.o -obj-arm-y += highbank.o -obj-arm-y += pl061.o -obj-arm-y += xgmac.o -obj-arm-y += arm-semi.o -obj-arm-y += pxa2xx.o pxa2xx_pic.o pxa2xx_gpio.o pxa2xx_timer.o pxa2xx_dma.o -obj-arm-y += pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o pxa2xx_keypad.o -obj-arm-y += gumstix.o -obj-arm-y += zaurus.o ide/microdrive.o spitz.o tosa.o tc6393xb.o -obj-arm-y += omap1.o omap_lcdc.o omap_dma.o omap_clk.o omap_mmc.o omap_i2c.o \ - omap_gpio.o omap_intc.o omap_uart.o -obj-arm-y += omap2.o omap_dss.o soc_dma.o omap_gptimer.o omap_synctimer.o \ - omap_gpmc.o omap_sdrc.o omap_spi.o omap_tap.o omap_l4.o -obj-arm-y += omap_sx1.o palm.o tsc210x.o -obj-arm-y += nseries.o blizzard.o onenand.o cbus.o tusb6010.o usb/hcd-musb.o -obj-arm-y += mst_fpga.o mainstone.o -obj-arm-y += z2.o -obj-arm-y += musicpal.o bitbang_i2c.o marvell_88w8618_audio.o -obj-arm-y += framebuffer.o -obj-arm-y += vexpress.o -obj-arm-y += strongarm.o -obj-arm-y += collie.o -obj-arm-y += pl041.o lm4549.o -obj-arm-$(CONFIG_FDT) += device_tree.o - -obj-sh4-y = shix.o r2d.o sh7750.o sh7750_regnames.o tc58128.o -obj-sh4-y += sh_timer.o sh_serial.o sh_intc.o sh_pci.o sm501.o -obj-sh4-y += ide/mmio.o - -obj-m68k-y = an5206.o mcf5206.o mcf_uart.o mcf_intc.o mcf5208.o mcf_fec.o -obj-m68k-y += m68k-semi.o dummy_m68k.o - -obj-s390x-y = s390-virtio-bus.o s390-virtio.o - -obj-alpha-y = mc146818rtc.o -obj-alpha-y += alpha_pci.o alpha_dp264.o alpha_typhoon.o - -obj-xtensa-y += xtensa_pic.o -obj-xtensa-y += xtensa_sim.o -obj-xtensa-y += xtensa_lx60.o -obj-xtensa-y += xtensa-semi.o -obj-xtensa-y += core-dc232b.o -obj-xtensa-y += core-dc233c.o -obj-xtensa-y += core-fsf.o +# Device tree +ifeq ($(CONFIG_FDT), y) +obj-$(TARGET_ARM) += device_tree.o +obj-$(TARGET_MICROBLAZE) += device_tree.o +obj-$(TARGET_PPC) += device_tree.o +endif main.o: QEMU_CFLAGS+=$(GPROF_CFLAGS) @@ -398,12 +238,12 @@ dummy := $(call unnest-vars) ifdef QEMU_PROGW # The linker builds a windows executable. Make also a console executable. -$(QEMU_PROGW): $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y) +$(QEMU_PROGW): $(obj-y) $(call LINK,$^) $(QEMU_PROG): $(QEMU_PROGW) $(call quiet-command,$(OBJCOPY) --subsystem console $(QEMU_PROGW) $(QEMU_PROG)," GEN $(TARGET_DIR)$(QEMU_PROG)") else -$(QEMU_PROG): $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y) +$(QEMU_PROG): $(obj-y) $(call LINK,$^) endif diff --git a/arm-semi.c b/arm-semi.c deleted file mode 100644 index 88ca9bb1b7..0000000000 --- a/arm-semi.c +++ /dev/null @@ -1,509 +0,0 @@ -/* - * Arm "Angel" semihosting syscalls - * - * Copyright (c) 2005, 2007 CodeSourcery. - * Written by Paul Brook. - * - * 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; either version 2 of the License, or - * (at your option) any later version. - * - * 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 -#include -#include -#include -#include -#include -#include - -#include "cpu.h" -#ifdef CONFIG_USER_ONLY -#include "qemu.h" - -#define ARM_ANGEL_HEAP_SIZE (128 * 1024 * 1024) -#else -#include "qemu-common.h" -#include "gdbstub.h" -#include "hw/arm-misc.h" -#endif - -#define TARGET_SYS_OPEN 0x01 -#define TARGET_SYS_CLOSE 0x02 -#define TARGET_SYS_WRITEC 0x03 -#define TARGET_SYS_WRITE0 0x04 -#define TARGET_SYS_WRITE 0x05 -#define TARGET_SYS_READ 0x06 -#define TARGET_SYS_READC 0x07 -#define TARGET_SYS_ISTTY 0x09 -#define TARGET_SYS_SEEK 0x0a -#define TARGET_SYS_FLEN 0x0c -#define TARGET_SYS_TMPNAM 0x0d -#define TARGET_SYS_REMOVE 0x0e -#define TARGET_SYS_RENAME 0x0f -#define TARGET_SYS_CLOCK 0x10 -#define TARGET_SYS_TIME 0x11 -#define TARGET_SYS_SYSTEM 0x12 -#define TARGET_SYS_ERRNO 0x13 -#define TARGET_SYS_GET_CMDLINE 0x15 -#define TARGET_SYS_HEAPINFO 0x16 -#define TARGET_SYS_EXIT 0x18 - -#ifndef O_BINARY -#define O_BINARY 0 -#endif - -#define GDB_O_RDONLY 0x000 -#define GDB_O_WRONLY 0x001 -#define GDB_O_RDWR 0x002 -#define GDB_O_APPEND 0x008 -#define GDB_O_CREAT 0x200 -#define GDB_O_TRUNC 0x400 -#define GDB_O_BINARY 0 - -static int gdb_open_modeflags[12] = { - GDB_O_RDONLY, - GDB_O_RDONLY | GDB_O_BINARY, - GDB_O_RDWR, - GDB_O_RDWR | GDB_O_BINARY, - GDB_O_WRONLY | GDB_O_CREAT | GDB_O_TRUNC, - GDB_O_WRONLY | GDB_O_CREAT | GDB_O_TRUNC | GDB_O_BINARY, - GDB_O_RDWR | GDB_O_CREAT | GDB_O_TRUNC, - GDB_O_RDWR | GDB_O_CREAT | GDB_O_TRUNC | GDB_O_BINARY, - GDB_O_WRONLY | GDB_O_CREAT | GDB_O_APPEND, - GDB_O_WRONLY | GDB_O_CREAT | GDB_O_APPEND | GDB_O_BINARY, - GDB_O_RDWR | GDB_O_CREAT | GDB_O_APPEND, - GDB_O_RDWR | GDB_O_CREAT | GDB_O_APPEND | GDB_O_BINARY -}; - -static int open_modeflags[12] = { - O_RDONLY, - O_RDONLY | O_BINARY, - O_RDWR, - O_RDWR | O_BINARY, - O_WRONLY | O_CREAT | O_TRUNC, - O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, - O_RDWR | O_CREAT | O_TRUNC, - O_RDWR | O_CREAT | O_TRUNC | O_BINARY, - O_WRONLY | O_CREAT | O_APPEND, - O_WRONLY | O_CREAT | O_APPEND | O_BINARY, - O_RDWR | O_CREAT | O_APPEND, - O_RDWR | O_CREAT | O_APPEND | O_BINARY -}; - -#ifdef CONFIG_USER_ONLY -static inline uint32_t set_swi_errno(TaskState *ts, uint32_t code) -{ - if (code == (uint32_t)-1) - ts->swi_errno = errno; - return code; -} -#else -static inline uint32_t set_swi_errno(CPUARMState *env, uint32_t code) -{ - return code; -} - -#include "softmmu-semi.h" -#endif - -static target_ulong arm_semi_syscall_len; - -#if !defined(CONFIG_USER_ONLY) -static target_ulong syscall_err; -#endif - -static void arm_semi_cb(CPUARMState *env, target_ulong ret, target_ulong err) -{ -#ifdef CONFIG_USER_ONLY - TaskState *ts = env->opaque; -#endif - - if (ret == (target_ulong)-1) { -#ifdef CONFIG_USER_ONLY - ts->swi_errno = err; -#else - syscall_err = err; -#endif - env->regs[0] = ret; - } else { - /* Fixup syscalls that use nonstardard return conventions. */ - switch (env->regs[0]) { - case TARGET_SYS_WRITE: - case TARGET_SYS_READ: - env->regs[0] = arm_semi_syscall_len - ret; - break; - case TARGET_SYS_SEEK: - env->regs[0] = 0; - break; - default: - env->regs[0] = ret; - break; - } - } -} - -static void arm_semi_flen_cb(CPUARMState *env, target_ulong ret, target_ulong err) -{ - /* The size is always stored in big-endian order, extract - the value. We assume the size always fit in 32 bits. */ - uint32_t size; - cpu_memory_rw_debug(env, env->regs[13]-64+32, (uint8_t *)&size, 4, 0); - env->regs[0] = be32_to_cpu(size); -#ifdef CONFIG_USER_ONLY - ((TaskState *)env->opaque)->swi_errno = err; -#else - syscall_err = err; -#endif -} - -#define ARG(n) \ -({ \ - target_ulong __arg; \ - /* FIXME - handle get_user() failure */ \ - get_user_ual(__arg, args + (n) * 4); \ - __arg; \ -}) -#define SET_ARG(n, val) put_user_ual(val, args + (n) * 4) -uint32_t do_arm_semihosting(CPUARMState *env) -{ - target_ulong args; - char * s; - int nr; - uint32_t ret; - uint32_t len; -#ifdef CONFIG_USER_ONLY - TaskState *ts = env->opaque; -#else - CPUARMState *ts = env; -#endif - - nr = env->regs[0]; - args = env->regs[1]; - switch (nr) { - case TARGET_SYS_OPEN: - if (!(s = lock_user_string(ARG(0)))) - /* FIXME - should this error code be -TARGET_EFAULT ? */ - return (uint32_t)-1; - if (ARG(1) >= 12) - return (uint32_t)-1; - if (strcmp(s, ":tt") == 0) { - if (ARG(1) < 4) - return STDIN_FILENO; - else - return STDOUT_FILENO; - } - if (use_gdb_syscalls()) { - gdb_do_syscall(arm_semi_cb, "open,%s,%x,1a4", ARG(0), - (int)ARG(2)+1, gdb_open_modeflags[ARG(1)]); - return env->regs[0]; - } else { - ret = set_swi_errno(ts, open(s, open_modeflags[ARG(1)], 0644)); - } - unlock_user(s, ARG(0), 0); - return ret; - case TARGET_SYS_CLOSE: - if (use_gdb_syscalls()) { - gdb_do_syscall(arm_semi_cb, "close,%x", ARG(0)); - return env->regs[0]; - } else { - return set_swi_errno(ts, close(ARG(0))); - } - case TARGET_SYS_WRITEC: - { - char c; - - if (get_user_u8(c, args)) - /* FIXME - should this error code be -TARGET_EFAULT ? */ - return (uint32_t)-1; - /* Write to debug console. stderr is near enough. */ - if (use_gdb_syscalls()) { - gdb_do_syscall(arm_semi_cb, "write,2,%x,1", args); - return env->regs[0]; - } else { - return write(STDERR_FILENO, &c, 1); - } - } - case TARGET_SYS_WRITE0: - if (!(s = lock_user_string(args))) - /* FIXME - should this error code be -TARGET_EFAULT ? */ - return (uint32_t)-1; - len = strlen(s); - if (use_gdb_syscalls()) { - gdb_do_syscall(arm_semi_cb, "write,2,%x,%x\n", args, len); - ret = env->regs[0]; - } else { - ret = write(STDERR_FILENO, s, len); - } - unlock_user(s, args, 0); - return ret; - case TARGET_SYS_WRITE: - len = ARG(2); - if (use_gdb_syscalls()) { - arm_semi_syscall_len = len; - gdb_do_syscall(arm_semi_cb, "write,%x,%x,%x", ARG(0), ARG(1), len); - return env->regs[0]; - } else { - if (!(s = lock_user(VERIFY_READ, ARG(1), len, 1))) - /* FIXME - should this error code be -TARGET_EFAULT ? */ - return (uint32_t)-1; - ret = set_swi_errno(ts, write(ARG(0), s, len)); - unlock_user(s, ARG(1), 0); - if (ret == (uint32_t)-1) - return -1; - return len - ret; - } - case TARGET_SYS_READ: - len = ARG(2); - if (use_gdb_syscalls()) { - arm_semi_syscall_len = len; - gdb_do_syscall(arm_semi_cb, "read,%x,%x,%x", ARG(0), ARG(1), len); - return env->regs[0]; - } else { - if (!(s = lock_user(VERIFY_WRITE, ARG(1), len, 0))) - /* FIXME - should this error code be -TARGET_EFAULT ? */ - return (uint32_t)-1; - do - ret = set_swi_errno(ts, read(ARG(0), s, len)); - while (ret == -1 && errno == EINTR); - unlock_user(s, ARG(1), len); - if (ret == (uint32_t)-1) - return -1; - return len - ret; - } - case TARGET_SYS_READC: - /* XXX: Read from debug cosole. Not implemented. */ - return 0; - case TARGET_SYS_ISTTY: - if (use_gdb_syscalls()) { - gdb_do_syscall(arm_semi_cb, "isatty,%x", ARG(0)); - return env->regs[0]; - } else { - return isatty(ARG(0)); - } - case TARGET_SYS_SEEK: - if (use_gdb_syscalls()) { - gdb_do_syscall(arm_semi_cb, "lseek,%x,%x,0", ARG(0), ARG(1)); - return env->regs[0]; - } else { - ret = set_swi_errno(ts, lseek(ARG(0), ARG(1), SEEK_SET)); - if (ret == (uint32_t)-1) - return -1; - return 0; - } - case TARGET_SYS_FLEN: - if (use_gdb_syscalls()) { - gdb_do_syscall(arm_semi_flen_cb, "fstat,%x,%x", - ARG(0), env->regs[13]-64); - return env->regs[0]; - } else { - struct stat buf; - ret = set_swi_errno(ts, fstat(ARG(0), &buf)); - if (ret == (uint32_t)-1) - return -1; - return buf.st_size; - } - case TARGET_SYS_TMPNAM: - /* XXX: Not implemented. */ - return -1; - case TARGET_SYS_REMOVE: - if (use_gdb_syscalls()) { - gdb_do_syscall(arm_semi_cb, "unlink,%s", ARG(0), (int)ARG(1)+1); - ret = env->regs[0]; - } else { - if (!(s = lock_user_string(ARG(0)))) - /* FIXME - should this error code be -TARGET_EFAULT ? */ - return (uint32_t)-1; - ret = set_swi_errno(ts, remove(s)); - unlock_user(s, ARG(0), 0); - } - return ret; - case TARGET_SYS_RENAME: - if (use_gdb_syscalls()) { - gdb_do_syscall(arm_semi_cb, "rename,%s,%s", - ARG(0), (int)ARG(1)+1, ARG(2), (int)ARG(3)+1); - return env->regs[0]; - } else { - char *s2; - s = lock_user_string(ARG(0)); - s2 = lock_user_string(ARG(2)); - if (!s || !s2) - /* FIXME - should this error code be -TARGET_EFAULT ? */ - ret = (uint32_t)-1; - else - ret = set_swi_errno(ts, rename(s, s2)); - if (s2) - unlock_user(s2, ARG(2), 0); - if (s) - unlock_user(s, ARG(0), 0); - return ret; - } - case TARGET_SYS_CLOCK: - return clock() / (CLOCKS_PER_SEC / 100); - case TARGET_SYS_TIME: - return set_swi_errno(ts, time(NULL)); - case TARGET_SYS_SYSTEM: - if (use_gdb_syscalls()) { - gdb_do_syscall(arm_semi_cb, "system,%s", ARG(0), (int)ARG(1)+1); - return env->regs[0]; - } else { - if (!(s = lock_user_string(ARG(0)))) - /* FIXME - should this error code be -TARGET_EFAULT ? */ - return (uint32_t)-1; - ret = set_swi_errno(ts, system(s)); - unlock_user(s, ARG(0), 0); - return ret; - } - case TARGET_SYS_ERRNO: -#ifdef CONFIG_USER_ONLY - return ts->swi_errno; -#else - return syscall_err; -#endif - case TARGET_SYS_GET_CMDLINE: - { - /* Build a command-line from the original argv. - * - * The inputs are: - * * ARG(0), pointer to a buffer of at least the size - * specified in ARG(1). - * * ARG(1), size of the buffer pointed to by ARG(0) in - * bytes. - * - * The outputs are: - * * ARG(0), pointer to null-terminated string of the - * command line. - * * ARG(1), length of the string pointed to by ARG(0). - */ - - char *output_buffer; - size_t input_size = ARG(1); - size_t output_size; - int status = 0; - - /* Compute the size of the output string. */ -#if !defined(CONFIG_USER_ONLY) - output_size = strlen(ts->boot_info->kernel_filename) - + 1 /* Separating space. */ - + strlen(ts->boot_info->kernel_cmdline) - + 1; /* Terminating null byte. */ -#else - unsigned int i; - - output_size = ts->info->arg_end - ts->info->arg_start; - if (!output_size) { - /* We special-case the "empty command line" case (argc==0). - Just provide the terminating 0. */ - output_size = 1; - } -#endif - - if (output_size > input_size) { - /* Not enough space to store command-line arguments. */ - return -1; - } - - /* Adjust the command-line length. */ - SET_ARG(1, output_size - 1); - - /* Lock the buffer on the ARM side. */ - output_buffer = lock_user(VERIFY_WRITE, ARG(0), output_size, 0); - if (!output_buffer) { - return -1; - } - - /* Copy the command-line arguments. */ -#if !defined(CONFIG_USER_ONLY) - pstrcpy(output_buffer, output_size, ts->boot_info->kernel_filename); - pstrcat(output_buffer, output_size, " "); - pstrcat(output_buffer, output_size, ts->boot_info->kernel_cmdline); -#else - if (output_size == 1) { - /* Empty command-line. */ - output_buffer[0] = '\0'; - goto out; - } - - if (copy_from_user(output_buffer, ts->info->arg_start, - output_size)) { - status = -1; - goto out; - } - - /* Separate arguments by white spaces. */ - for (i = 0; i < output_size - 1; i++) { - if (output_buffer[i] == 0) { - output_buffer[i] = ' '; - } - } - out: -#endif - /* Unlock the buffer on the ARM side. */ - unlock_user(output_buffer, ARG(0), output_size); - - return status; - } - case TARGET_SYS_HEAPINFO: - { - uint32_t *ptr; - uint32_t limit; - -#ifdef CONFIG_USER_ONLY - /* Some C libraries assume the heap immediately follows .bss, so - allocate it using sbrk. */ - if (!ts->heap_limit) { - abi_ulong ret; - - ts->heap_base = do_brk(0); - limit = ts->heap_base + ARM_ANGEL_HEAP_SIZE; - /* Try a big heap, and reduce the size if that fails. */ - for (;;) { - ret = do_brk(limit); - if (ret >= limit) { - break; - } - limit = (ts->heap_base >> 1) + (limit >> 1); - } - ts->heap_limit = limit; - } - - if (!(ptr = lock_user(VERIFY_WRITE, ARG(0), 16, 0))) - /* FIXME - should this error code be -TARGET_EFAULT ? */ - return (uint32_t)-1; - ptr[0] = tswap32(ts->heap_base); - ptr[1] = tswap32(ts->heap_limit); - ptr[2] = tswap32(ts->stack_base); - ptr[3] = tswap32(0); /* Stack limit. */ - unlock_user(ptr, ARG(0), 16); -#else - limit = ram_size; - if (!(ptr = lock_user(VERIFY_WRITE, ARG(0), 16, 0))) - /* FIXME - should this error code be -TARGET_EFAULT ? */ - return (uint32_t)-1; - /* TODO: Make this use the limit of the loaded application. */ - ptr[0] = tswap32(limit / 2); - ptr[1] = tswap32(limit); - ptr[2] = tswap32(limit); /* Stack base */ - ptr[3] = tswap32(0); /* Stack limit. */ - unlock_user(ptr, ARG(0), 16); -#endif - return 0; - } - case TARGET_SYS_EXIT: - gdb_exit(env, 0); - exit(0); - default: - fprintf(stderr, "qemu: Unsupported SemiHosting SWI 0x%02x\n", nr); - cpu_dump_state(env, stderr, fprintf, 0); - abort(); - } -} diff --git a/configure b/configure index 2c44488131..a2fca50260 100755 --- a/configure +++ b/configure @@ -3514,24 +3514,6 @@ case "$target" in esac mkdir -p $target_dir -mkdir -p $target_dir/fpu -mkdir -p $target_dir/tcg -mkdir -p $target_dir/ide -mkdir -p $target_dir/usb -mkdir -p $target_dir/9pfs -mkdir -p $target_dir/kvm -if test "$target_linux_user" = yes; then - mkdir -p $target_dir/linux-user -fi -if test "$target_bsd_user" = yes; then - mkdir -p $target_dir/bsd-user -fi -if test "$target" = "arm-linux-user" -o "$target" = "armeb-linux-user" -o "$target" = "arm-bsd-user" -o "$target" = "armeb-bsd-user" ; then - mkdir -p $target_dir/linux-user/arm/nwfpe -fi -symlink "$source_path/Makefile.target" "$target_dir/Makefile" - - echo "# Automatically generated by configure - do not modify" > $config_target_mak bflt="no" @@ -3682,6 +3664,32 @@ case "$target_arch2" in exit 1 ;; esac +# TARGET_BASE_ARCH needs to be defined after TARGET_ARCH +if [ "$TARGET_BASE_ARCH" = "" ]; then + TARGET_BASE_ARCH=$TARGET_ARCH +fi + +mkdir -p $target_dir/fpu +mkdir -p $target_dir/tcg +mkdir -p $target_dir/9pfs +mkdir -p $target_dir/hw +mkdir -p $target_dir/hw/ide +mkdir -p $target_dir/hw/usb +mkdir -p $target_dir/hw/kvm +mkdir -p $target_dir/hw/$TARGET_ARCH +mkdir -p $target_dir/hw/$TARGET_BASE_ARCH +mkdir -p $target_dir/target-$TARGET_BASE_ARCH +if test "$target_linux_user" = yes; then + mkdir -p $target_dir/linux-user +fi +if test "$target_bsd_user" = yes; then + mkdir -p $target_dir/bsd-user +fi +if test "$target" = "arm-linux-user" -o "$target" = "armeb-linux-user" -o "$target" = "arm-bsd-user" -o "$target" = "armeb-bsd-user" ; then + mkdir -p $target_dir/linux-user/arm/nwfpe +fi +symlink "$source_path/Makefile.target" "$target_dir/Makefile" + case "$target_arch2" in alpha | sparc*) @@ -3697,10 +3705,6 @@ echo "TARGET_ARCH=$TARGET_ARCH" >> $config_target_mak target_arch_name="`echo $TARGET_ARCH | LC_ALL=C tr '[a-z]' '[A-Z]'`" echo "TARGET_$target_arch_name=y" >> $config_target_mak echo "TARGET_ARCH2=$target_arch2" >> $config_target_mak -# TARGET_BASE_ARCH needs to be defined after TARGET_ARCH -if [ "$TARGET_BASE_ARCH" = "" ]; then - TARGET_BASE_ARCH=$TARGET_ARCH -fi echo "TARGET_BASE_ARCH=$TARGET_BASE_ARCH" >> $config_target_mak if [ "$TARGET_ABI_DIR" = "" ]; then TARGET_ABI_DIR=$TARGET_ARCH diff --git a/hw/alpha/Makefile.objs b/hw/alpha/Makefile.objs new file mode 100644 index 0000000000..af1c07fa7c --- /dev/null +++ b/hw/alpha/Makefile.objs @@ -0,0 +1,4 @@ +obj-y = mc146818rtc.o +obj-y += alpha_pci.o alpha_dp264.o alpha_typhoon.o + +obj-y := $(addprefix ../,$(obj-y)) diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs new file mode 100644 index 0000000000..92b4f1eb7f --- /dev/null +++ b/hw/arm/Makefile.objs @@ -0,0 +1,39 @@ +obj-y = integratorcp.o versatilepb.o arm_pic.o arm_timer.o +obj-y += arm_boot.o pl011.o pl031.o pl050.o pl080.o pl110.o pl181.o pl190.o +obj-y += versatile_pci.o +obj-y += versatile_i2c.o +obj-y += cadence_uart.o +obj-y += cadence_ttc.o +obj-y += cadence_gem.o +obj-y += xilinx_zynq.o zynq_slcr.o +obj-y += arm_gic.o +obj-y += realview_gic.o realview.o arm_sysctl.o arm11mpcore.o a9mpcore.o +obj-y += exynos4210_gic.o exynos4210_combiner.o exynos4210.o +obj-y += exynos4_boards.o exynos4210_uart.o exynos4210_pwm.o +obj-y += exynos4210_pmu.o exynos4210_mct.o exynos4210_fimd.o +obj-y += arm_l2x0.o +obj-y += arm_mptimer.o a15mpcore.o +obj-y += armv7m.o armv7m_nvic.o stellaris.o pl022.o stellaris_enet.o +obj-y += highbank.o +obj-y += pl061.o +obj-y += xgmac.o +obj-y += pxa2xx.o pxa2xx_pic.o pxa2xx_gpio.o pxa2xx_timer.o pxa2xx_dma.o +obj-y += pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o pxa2xx_keypad.o +obj-y += gumstix.o +obj-y += zaurus.o ide/microdrive.o spitz.o tosa.o tc6393xb.o +obj-y += omap1.o omap_lcdc.o omap_dma.o omap_clk.o omap_mmc.o omap_i2c.o \ + omap_gpio.o omap_intc.o omap_uart.o +obj-y += omap2.o omap_dss.o soc_dma.o omap_gptimer.o omap_synctimer.o \ + omap_gpmc.o omap_sdrc.o omap_spi.o omap_tap.o omap_l4.o +obj-y += omap_sx1.o palm.o tsc210x.o +obj-y += nseries.o blizzard.o onenand.o cbus.o tusb6010.o usb/hcd-musb.o +obj-y += mst_fpga.o mainstone.o +obj-y += z2.o +obj-y += musicpal.o bitbang_i2c.o marvell_88w8618_audio.o +obj-y += framebuffer.o +obj-y += vexpress.o +obj-y += strongarm.o +obj-y += collie.o +obj-y += pl041.o lm4549.o + +obj-y := $(addprefix ../,$(obj-y)) diff --git a/hw/cris/Makefile.objs b/hw/cris/Makefile.objs new file mode 100644 index 0000000000..aa9298a0ed --- /dev/null +++ b/hw/cris/Makefile.objs @@ -0,0 +1,13 @@ +# Boards +obj-y = cris_pic_cpu.o +obj-y += cris-boot.o +obj-y += axis_dev88.o + +# IO blocks +obj-y += etraxfs_dma.o +obj-y += etraxfs_pic.o +obj-y += etraxfs_eth.o +obj-y += etraxfs_timer.o +obj-y += etraxfs_ser.o + +obj-y := $(addprefix ../,$(obj-y)) diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs new file mode 100644 index 0000000000..d43f1df5f0 --- /dev/null +++ b/hw/i386/Makefile.objs @@ -0,0 +1,13 @@ +obj-y += mc146818rtc.o pc.o +obj-y += apic_common.o apic.o kvmvapic.o +obj-y += sga.o ioapic_common.o ioapic.o piix_pci.o +obj-y += vmport.o +obj-y += pci-hotplug.o smbios.o wdt_ib700.o +obj-y += debugcon.o multiboot.o +obj-y += pc_piix.o +obj-y += pc_sysfw.o +obj-$(CONFIG_XEN) += xen_platform.o xen_apic.o +obj-$(CONFIG_KVM) += kvm/clock.o kvm/apic.o kvm/i8259.o kvm/ioapic.o kvm/i8254.o +obj-$(CONFIG_SPICE) += qxl.o qxl-logger.o qxl-render.o + +obj-y := $(addprefix ../,$(obj-y)) diff --git a/hw/lm32/Makefile.objs b/hw/lm32/Makefile.objs new file mode 100644 index 0000000000..4e1843c11d --- /dev/null +++ b/hw/lm32/Makefile.objs @@ -0,0 +1,23 @@ +# LM32 boards +obj-y += lm32_boards.o +obj-y += milkymist.o + +# LM32 peripherals +obj-y += lm32_pic.o +obj-y += lm32_juart.o +obj-y += lm32_timer.o +obj-y += lm32_uart.o +obj-y += lm32_sys.o +obj-y += milkymist-ac97.o +obj-y += milkymist-hpdmc.o +obj-y += milkymist-memcard.o +obj-y += milkymist-minimac2.o +obj-y += milkymist-pfpu.o +obj-y += milkymist-softusb.o +obj-y += milkymist-sysctl.o +obj-$(CONFIG_OPENGL) += milkymist-tmu2.o +obj-y += milkymist-uart.o +obj-y += milkymist-vgafb.o +obj-y += framebuffer.o + +obj-y := $(addprefix ../,$(obj-y)) diff --git a/hw/m68k/Makefile.objs b/hw/m68k/Makefile.objs new file mode 100644 index 0000000000..93b6d25baf --- /dev/null +++ b/hw/m68k/Makefile.objs @@ -0,0 +1,4 @@ +obj-y = an5206.o mcf5206.o mcf_uart.o mcf_intc.o mcf5208.o mcf_fec.o +obj-y += dummy_m68k.o + +obj-y := $(addprefix ../,$(obj-y)) diff --git a/hw/microblaze/Makefile.objs b/hw/microblaze/Makefile.objs new file mode 100644 index 0000000000..41724425cb --- /dev/null +++ b/hw/microblaze/Makefile.objs @@ -0,0 +1,13 @@ +obj-y = petalogix_s3adsp1800_mmu.o +obj-y += petalogix_ml605_mmu.o +obj-y += microblaze_boot.o + +obj-y += microblaze_pic_cpu.o +obj-y += xilinx_intc.o +obj-y += xilinx_timer.o +obj-y += xilinx_uartlite.o +obj-y += xilinx_ethlite.o +obj-y += xilinx_axidma.o +obj-y += xilinx_axienet.o + +obj-y := $(addprefix ../,$(obj-y)) diff --git a/hw/mips/Makefile.objs b/hw/mips/Makefile.objs new file mode 100644 index 0000000000..29a5d0db04 --- /dev/null +++ b/hw/mips/Makefile.objs @@ -0,0 +1,6 @@ +obj-y = mips_r4k.o mips_jazz.o mips_malta.o mips_mipssim.o +obj-y += mips_addr.o mips_timer.o mips_int.o +obj-y += gt64xxx.o mc146818rtc.o +obj-$(CONFIG_FULONG) += bonito.o vt82c686.o mips_fulong2e.o + +obj-y := $(addprefix ../,$(obj-y)) diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs new file mode 100644 index 0000000000..5b09849bed --- /dev/null +++ b/hw/ppc/Makefile.objs @@ -0,0 +1,31 @@ +# shared objects +obj-y = ppc.o ppc_booke.o +# PREP target +obj-y += mc146818rtc.o +obj-y += ppc_prep.o +# OldWorld PowerMac +obj-y += ppc_oldworld.o +# NewWorld PowerMac +obj-y += ppc_newworld.o +# IBM pSeries (sPAPR) +obj-$(CONFIG_PSERIES) += spapr.o spapr_hcall.o spapr_rtas.o spapr_vio.o +obj-$(CONFIG_PSERIES) += xics.o spapr_vty.o spapr_llan.o spapr_vscsi.o +obj-$(CONFIG_PSERIES) += spapr_pci.o pci-hotplug.o +# PowerPC 4xx boards +obj-y += ppc4xx_devs.o ppc4xx_pci.o ppc405_uc.o ppc405_boards.o +obj-y += ppc440_bamboo.o +# PowerPC E500 boards +obj-y += ppce500_mpc8544ds.o mpc8544_guts.o ppce500_spin.o +# PowerPC 440 Xilinx ML507 reference board. +obj-y += virtex_ml507.o +obj-$(CONFIG_KVM) += kvm_ppc.o +# PowerPC OpenPIC +obj-y += openpic.o + +# Xilinx PPC peripherals +obj-y += xilinx_intc.o +obj-y += xilinx_timer.o +obj-y += xilinx_uartlite.o +obj-y += xilinx_ethlite.o + +obj-y := $(addprefix ../,$(obj-y)) diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs new file mode 100644 index 0000000000..dcdcac8a81 --- /dev/null +++ b/hw/s390x/Makefile.objs @@ -0,0 +1,3 @@ +obj-y = s390-virtio-bus.o s390-virtio.o + +obj-y := $(addprefix ../,$(obj-y)) diff --git a/hw/sh4/Makefile.objs b/hw/sh4/Makefile.objs new file mode 100644 index 0000000000..68c5921790 --- /dev/null +++ b/hw/sh4/Makefile.objs @@ -0,0 +1,5 @@ +obj-y = shix.o r2d.o sh7750.o sh7750_regnames.o tc58128.o +obj-y += sh_timer.o sh_serial.o sh_intc.o sh_pci.o sm501.o +obj-y += ide/mmio.o + +obj-y := $(addprefix ../,$(obj-y)) diff --git a/hw/sparc/Makefile.objs b/hw/sparc/Makefile.objs new file mode 100644 index 0000000000..a39a511c52 --- /dev/null +++ b/hw/sparc/Makefile.objs @@ -0,0 +1,8 @@ +obj-y = sun4m.o lance.o tcx.o sun4m_iommu.o slavio_intctl.o +obj-y += slavio_timer.o slavio_misc.o sparc32_dma.o +obj-y += cs4231.o eccmemctl.o sbi.o sun4c_intctl.o leon3.o + +# GRLIB +obj-y += grlib_gptimer.o grlib_irqmp.o grlib_apbuart.o + +obj-y := $(addprefix ../,$(obj-y)) diff --git a/hw/sparc64/Makefile.objs b/hw/sparc64/Makefile.objs new file mode 100644 index 0000000000..8c65fc4215 --- /dev/null +++ b/hw/sparc64/Makefile.objs @@ -0,0 +1,4 @@ +obj-y = sun4u.o apb_pci.o +obj-y += mc146818rtc.o + +obj-y := $(addprefix ../,$(obj-y)) diff --git a/hw/xtensa/Makefile.objs b/hw/xtensa/Makefile.objs new file mode 100644 index 0000000000..79698e903d --- /dev/null +++ b/hw/xtensa/Makefile.objs @@ -0,0 +1,5 @@ +obj-y += xtensa_pic.o +obj-y += xtensa_sim.o +obj-y += xtensa_lx60.o + +obj-y := $(addprefix ../,$(obj-y)) diff --git a/ioport-user.c b/ioport-user.c deleted file mode 100644 index 03fac22d22..0000000000 --- a/ioport-user.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * qemu user ioport functions - * - * Copyright (c) 2003-2008 Fabrice Bellard - * - * 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; either version 2 of the License, or - * (at your option) any later version. - * - * 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 - -#include "qemu.h" -#include "qemu-common.h" -#include "ioport.h" - -void cpu_outb(pio_addr_t addr, uint8_t val) -{ - fprintf(stderr, "outb: port=0x%04"FMT_pioaddr", data=%02"PRIx8"\n", - addr, val); -} - -void cpu_outw(pio_addr_t addr, uint16_t val) -{ - fprintf(stderr, "outw: port=0x%04"FMT_pioaddr", data=%04"PRIx16"\n", - addr, val); -} - -void cpu_outl(pio_addr_t addr, uint32_t val) -{ - fprintf(stderr, "outl: port=0x%04"FMT_pioaddr", data=%08"PRIx32"\n", - addr, val); -} - -uint8_t cpu_inb(pio_addr_t addr) -{ - fprintf(stderr, "inb: port=0x%04"FMT_pioaddr"\n", addr); - return 0; -} - -uint16_t cpu_inw(pio_addr_t addr) -{ - fprintf(stderr, "inw: port=0x%04"FMT_pioaddr"\n", addr); - return 0; -} - -uint32_t cpu_inl(pio_addr_t addr) -{ - fprintf(stderr, "inl: port=0x%04"FMT_pioaddr"\n", addr); - return 0; -} diff --git a/m68k-semi.c b/m68k-semi.c deleted file mode 100644 index 3bb30cd1f7..0000000000 --- a/m68k-semi.c +++ /dev/null @@ -1,408 +0,0 @@ -/* - * m68k/ColdFire Semihosting syscall interface - * - * Copyright (c) 2005-2007 CodeSourcery. - * - * 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; either version 2 of the License, or - * (at your option) any later version. - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include - -#include "cpu.h" -#if defined(CONFIG_USER_ONLY) -#include "qemu.h" -#define SEMIHOSTING_HEAP_SIZE (128 * 1024 * 1024) -#else -#include "qemu-common.h" -#include "gdbstub.h" -#include "softmmu-semi.h" -#endif -#include "sysemu.h" - -#define HOSTED_EXIT 0 -#define HOSTED_INIT_SIM 1 -#define HOSTED_OPEN 2 -#define HOSTED_CLOSE 3 -#define HOSTED_READ 4 -#define HOSTED_WRITE 5 -#define HOSTED_LSEEK 6 -#define HOSTED_RENAME 7 -#define HOSTED_UNLINK 8 -#define HOSTED_STAT 9 -#define HOSTED_FSTAT 10 -#define HOSTED_GETTIMEOFDAY 11 -#define HOSTED_ISATTY 12 -#define HOSTED_SYSTEM 13 - -typedef uint32_t gdb_mode_t; -typedef uint32_t gdb_time_t; - -struct m68k_gdb_stat { - uint32_t gdb_st_dev; /* device */ - uint32_t gdb_st_ino; /* inode */ - gdb_mode_t gdb_st_mode; /* protection */ - uint32_t gdb_st_nlink; /* number of hard links */ - uint32_t gdb_st_uid; /* user ID of owner */ - uint32_t gdb_st_gid; /* group ID of owner */ - uint32_t gdb_st_rdev; /* device type (if inode device) */ - uint64_t gdb_st_size; /* total size, in bytes */ - uint64_t gdb_st_blksize; /* blocksize for filesystem I/O */ - uint64_t gdb_st_blocks; /* number of blocks allocated */ - gdb_time_t gdb_st_atime; /* time of last access */ - gdb_time_t gdb_st_mtime; /* time of last modification */ - gdb_time_t gdb_st_ctime; /* time of last change */ -} QEMU_PACKED; - -struct gdb_timeval { - gdb_time_t tv_sec; /* second */ - uint64_t tv_usec; /* microsecond */ -} QEMU_PACKED; - -#define GDB_O_RDONLY 0x0 -#define GDB_O_WRONLY 0x1 -#define GDB_O_RDWR 0x2 -#define GDB_O_APPEND 0x8 -#define GDB_O_CREAT 0x200 -#define GDB_O_TRUNC 0x400 -#define GDB_O_EXCL 0x800 - -static int translate_openflags(int flags) -{ - int hf; - - if (flags & GDB_O_WRONLY) - hf = O_WRONLY; - else if (flags & GDB_O_RDWR) - hf = O_RDWR; - else - hf = O_RDONLY; - - if (flags & GDB_O_APPEND) hf |= O_APPEND; - if (flags & GDB_O_CREAT) hf |= O_CREAT; - if (flags & GDB_O_TRUNC) hf |= O_TRUNC; - if (flags & GDB_O_EXCL) hf |= O_EXCL; - - return hf; -} - -static void translate_stat(CPUM68KState *env, target_ulong addr, struct stat *s) -{ - struct m68k_gdb_stat *p; - - if (!(p = lock_user(VERIFY_WRITE, addr, sizeof(struct m68k_gdb_stat), 0))) - /* FIXME - should this return an error code? */ - return; - p->gdb_st_dev = cpu_to_be32(s->st_dev); - p->gdb_st_ino = cpu_to_be32(s->st_ino); - p->gdb_st_mode = cpu_to_be32(s->st_mode); - p->gdb_st_nlink = cpu_to_be32(s->st_nlink); - p->gdb_st_uid = cpu_to_be32(s->st_uid); - p->gdb_st_gid = cpu_to_be32(s->st_gid); - p->gdb_st_rdev = cpu_to_be32(s->st_rdev); - p->gdb_st_size = cpu_to_be64(s->st_size); -#ifdef _WIN32 - /* Windows stat is missing some fields. */ - p->gdb_st_blksize = 0; - p->gdb_st_blocks = 0; -#else - p->gdb_st_blksize = cpu_to_be64(s->st_blksize); - p->gdb_st_blocks = cpu_to_be64(s->st_blocks); -#endif - p->gdb_st_atime = cpu_to_be32(s->st_atime); - p->gdb_st_mtime = cpu_to_be32(s->st_mtime); - p->gdb_st_ctime = cpu_to_be32(s->st_ctime); - unlock_user(p, addr, sizeof(struct m68k_gdb_stat)); -} - -static int m68k_semi_is_fseek; - -static void m68k_semi_cb(CPUM68KState *env, target_ulong ret, target_ulong err) -{ - target_ulong args; - - args = env->dregs[1]; - if (m68k_semi_is_fseek) { - /* FIXME: We've already lost the high bits of the fseek - return value. */ - /* FIXME - handle put_user() failure */ - put_user_u32(0, args); - args += 4; - m68k_semi_is_fseek = 0; - } - /* FIXME - handle put_user() failure */ - put_user_u32(ret, args); - put_user_u32(errno, args + 4); -} - -#define ARG(n) \ -({ \ - target_ulong __arg; \ - /* FIXME - handle get_user() failure */ \ - get_user_ual(__arg, args + (n) * 4); \ - __arg; \ -}) -#define PARG(x) ((unsigned long)ARG(x)) -void do_m68k_semihosting(CPUM68KState *env, int nr) -{ - uint32_t args; - void *p; - void *q; - uint32_t len; - uint32_t result; - - args = env->dregs[1]; - switch (nr) { - case HOSTED_EXIT: - gdb_exit(env, env->dregs[0]); - exit(env->dregs[0]); - case HOSTED_OPEN: - if (use_gdb_syscalls()) { - gdb_do_syscall(m68k_semi_cb, "open,%s,%x,%x", ARG(0), (int)ARG(1), - ARG(2), ARG(3)); - return; - } else { - if (!(p = lock_user_string(ARG(0)))) { - /* FIXME - check error code? */ - result = -1; - } else { - result = open(p, translate_openflags(ARG(2)), ARG(3)); - unlock_user(p, ARG(0), 0); - } - } - break; - case HOSTED_CLOSE: - { - /* Ignore attempts to close stdin/out/err. */ - int fd = ARG(0); - if (fd > 2) { - if (use_gdb_syscalls()) { - gdb_do_syscall(m68k_semi_cb, "close,%x", ARG(0)); - return; - } else { - result = close(fd); - } - } else { - result = 0; - } - break; - } - case HOSTED_READ: - len = ARG(2); - if (use_gdb_syscalls()) { - gdb_do_syscall(m68k_semi_cb, "read,%x,%x,%x", - ARG(0), ARG(1), len); - return; - } else { - if (!(p = lock_user(VERIFY_WRITE, ARG(1), len, 0))) { - /* FIXME - check error code? */ - result = -1; - } else { - result = read(ARG(0), p, len); - unlock_user(p, ARG(1), len); - } - } - break; - case HOSTED_WRITE: - len = ARG(2); - if (use_gdb_syscalls()) { - gdb_do_syscall(m68k_semi_cb, "write,%x,%x,%x", - ARG(0), ARG(1), len); - return; - } else { - if (!(p = lock_user(VERIFY_READ, ARG(1), len, 1))) { - /* FIXME - check error code? */ - result = -1; - } else { - result = write(ARG(0), p, len); - unlock_user(p, ARG(0), 0); - } - } - break; - case HOSTED_LSEEK: - { - uint64_t off; - off = (uint32_t)ARG(2) | ((uint64_t)ARG(1) << 32); - if (use_gdb_syscalls()) { - m68k_semi_is_fseek = 1; - gdb_do_syscall(m68k_semi_cb, "fseek,%x,%lx,%x", - ARG(0), off, ARG(3)); - } else { - off = lseek(ARG(0), off, ARG(3)); - /* FIXME - handle put_user() failure */ - put_user_u32(off >> 32, args); - put_user_u32(off, args + 4); - put_user_u32(errno, args + 8); - } - return; - } - case HOSTED_RENAME: - if (use_gdb_syscalls()) { - gdb_do_syscall(m68k_semi_cb, "rename,%s,%s", - ARG(0), (int)ARG(1), ARG(2), (int)ARG(3)); - return; - } else { - p = lock_user_string(ARG(0)); - q = lock_user_string(ARG(2)); - if (!p || !q) { - /* FIXME - check error code? */ - result = -1; - } else { - result = rename(p, q); - } - unlock_user(p, ARG(0), 0); - unlock_user(q, ARG(2), 0); - } - break; - case HOSTED_UNLINK: - if (use_gdb_syscalls()) { - gdb_do_syscall(m68k_semi_cb, "unlink,%s", - ARG(0), (int)ARG(1)); - return; - } else { - if (!(p = lock_user_string(ARG(0)))) { - /* FIXME - check error code? */ - result = -1; - } else { - result = unlink(p); - unlock_user(p, ARG(0), 0); - } - } - break; - case HOSTED_STAT: - if (use_gdb_syscalls()) { - gdb_do_syscall(m68k_semi_cb, "stat,%s,%x", - ARG(0), (int)ARG(1), ARG(2)); - return; - } else { - struct stat s; - if (!(p = lock_user_string(ARG(0)))) { - /* FIXME - check error code? */ - result = -1; - } else { - result = stat(p, &s); - unlock_user(p, ARG(0), 0); - } - if (result == 0) { - translate_stat(env, ARG(2), &s); - } - } - break; - case HOSTED_FSTAT: - if (use_gdb_syscalls()) { - gdb_do_syscall(m68k_semi_cb, "fstat,%x,%x", - ARG(0), ARG(1)); - return; - } else { - struct stat s; - result = fstat(ARG(0), &s); - if (result == 0) { - translate_stat(env, ARG(1), &s); - } - } - break; - case HOSTED_GETTIMEOFDAY: - if (use_gdb_syscalls()) { - gdb_do_syscall(m68k_semi_cb, "gettimeofday,%x,%x", - ARG(0), ARG(1)); - return; - } else { - qemu_timeval tv; - struct gdb_timeval *p; - result = qemu_gettimeofday(&tv); - if (result != 0) { - if (!(p = lock_user(VERIFY_WRITE, - ARG(0), sizeof(struct gdb_timeval), 0))) { - /* FIXME - check error code? */ - result = -1; - } else { - p->tv_sec = cpu_to_be32(tv.tv_sec); - p->tv_usec = cpu_to_be64(tv.tv_usec); - unlock_user(p, ARG(0), sizeof(struct gdb_timeval)); - } - } - } - break; - case HOSTED_ISATTY: - if (use_gdb_syscalls()) { - gdb_do_syscall(m68k_semi_cb, "isatty,%x", ARG(0)); - return; - } else { - result = isatty(ARG(0)); - } - break; - case HOSTED_SYSTEM: - if (use_gdb_syscalls()) { - gdb_do_syscall(m68k_semi_cb, "system,%s", - ARG(0), (int)ARG(1)); - return; - } else { - if (!(p = lock_user_string(ARG(0)))) { - /* FIXME - check error code? */ - result = -1; - } else { - result = system(p); - unlock_user(p, ARG(0), 0); - } - } - break; - case HOSTED_INIT_SIM: -#if defined(CONFIG_USER_ONLY) - { - TaskState *ts = env->opaque; - /* Allocate the heap using sbrk. */ - if (!ts->heap_limit) { - abi_ulong ret; - uint32_t size; - uint32_t base; - - base = do_brk(0); - size = SEMIHOSTING_HEAP_SIZE; - /* Try a big heap, and reduce the size if that fails. */ - for (;;) { - ret = do_brk(base + size); - if (ret >= (base + size)) { - break; - } - size >>= 1; - } - ts->heap_limit = base + size; - } - /* This call may happen before we have writable memory, so return - values directly in registers. */ - env->dregs[1] = ts->heap_limit; - env->aregs[7] = ts->stack_base; - } -#else - /* FIXME: This is wrong for boards where RAM does not start at - address zero. */ - env->dregs[1] = ram_size; - env->aregs[7] = ram_size; -#endif - return; - default: - cpu_abort(env, "Unsupported semihosting syscall %d\n", nr); - result = 0; - } - /* FIXME - handle put_user() failure */ - put_user_u32(result, args); - put_user_u32(errno, args + 4); -} diff --git a/target-alpha/Makefile.objs b/target-alpha/Makefile.objs new file mode 100644 index 0000000000..c574c9ea7d --- /dev/null +++ b/target-alpha/Makefile.objs @@ -0,0 +1 @@ +# still empty diff --git a/target-arm/Makefile.objs b/target-arm/Makefile.objs new file mode 100644 index 0000000000..f5bb920266 --- /dev/null +++ b/target-arm/Makefile.objs @@ -0,0 +1 @@ +obj-y += arm-semi.o diff --git a/target-arm/arm-semi.c b/target-arm/arm-semi.c new file mode 100644 index 0000000000..88ca9bb1b7 --- /dev/null +++ b/target-arm/arm-semi.c @@ -0,0 +1,509 @@ +/* + * Arm "Angel" semihosting syscalls + * + * Copyright (c) 2005, 2007 CodeSourcery. + * Written by Paul Brook. + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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 +#include +#include +#include +#include +#include +#include + +#include "cpu.h" +#ifdef CONFIG_USER_ONLY +#include "qemu.h" + +#define ARM_ANGEL_HEAP_SIZE (128 * 1024 * 1024) +#else +#include "qemu-common.h" +#include "gdbstub.h" +#include "hw/arm-misc.h" +#endif + +#define TARGET_SYS_OPEN 0x01 +#define TARGET_SYS_CLOSE 0x02 +#define TARGET_SYS_WRITEC 0x03 +#define TARGET_SYS_WRITE0 0x04 +#define TARGET_SYS_WRITE 0x05 +#define TARGET_SYS_READ 0x06 +#define TARGET_SYS_READC 0x07 +#define TARGET_SYS_ISTTY 0x09 +#define TARGET_SYS_SEEK 0x0a +#define TARGET_SYS_FLEN 0x0c +#define TARGET_SYS_TMPNAM 0x0d +#define TARGET_SYS_REMOVE 0x0e +#define TARGET_SYS_RENAME 0x0f +#define TARGET_SYS_CLOCK 0x10 +#define TARGET_SYS_TIME 0x11 +#define TARGET_SYS_SYSTEM 0x12 +#define TARGET_SYS_ERRNO 0x13 +#define TARGET_SYS_GET_CMDLINE 0x15 +#define TARGET_SYS_HEAPINFO 0x16 +#define TARGET_SYS_EXIT 0x18 + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +#define GDB_O_RDONLY 0x000 +#define GDB_O_WRONLY 0x001 +#define GDB_O_RDWR 0x002 +#define GDB_O_APPEND 0x008 +#define GDB_O_CREAT 0x200 +#define GDB_O_TRUNC 0x400 +#define GDB_O_BINARY 0 + +static int gdb_open_modeflags[12] = { + GDB_O_RDONLY, + GDB_O_RDONLY | GDB_O_BINARY, + GDB_O_RDWR, + GDB_O_RDWR | GDB_O_BINARY, + GDB_O_WRONLY | GDB_O_CREAT | GDB_O_TRUNC, + GDB_O_WRONLY | GDB_O_CREAT | GDB_O_TRUNC | GDB_O_BINARY, + GDB_O_RDWR | GDB_O_CREAT | GDB_O_TRUNC, + GDB_O_RDWR | GDB_O_CREAT | GDB_O_TRUNC | GDB_O_BINARY, + GDB_O_WRONLY | GDB_O_CREAT | GDB_O_APPEND, + GDB_O_WRONLY | GDB_O_CREAT | GDB_O_APPEND | GDB_O_BINARY, + GDB_O_RDWR | GDB_O_CREAT | GDB_O_APPEND, + GDB_O_RDWR | GDB_O_CREAT | GDB_O_APPEND | GDB_O_BINARY +}; + +static int open_modeflags[12] = { + O_RDONLY, + O_RDONLY | O_BINARY, + O_RDWR, + O_RDWR | O_BINARY, + O_WRONLY | O_CREAT | O_TRUNC, + O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, + O_RDWR | O_CREAT | O_TRUNC, + O_RDWR | O_CREAT | O_TRUNC | O_BINARY, + O_WRONLY | O_CREAT | O_APPEND, + O_WRONLY | O_CREAT | O_APPEND | O_BINARY, + O_RDWR | O_CREAT | O_APPEND, + O_RDWR | O_CREAT | O_APPEND | O_BINARY +}; + +#ifdef CONFIG_USER_ONLY +static inline uint32_t set_swi_errno(TaskState *ts, uint32_t code) +{ + if (code == (uint32_t)-1) + ts->swi_errno = errno; + return code; +} +#else +static inline uint32_t set_swi_errno(CPUARMState *env, uint32_t code) +{ + return code; +} + +#include "softmmu-semi.h" +#endif + +static target_ulong arm_semi_syscall_len; + +#if !defined(CONFIG_USER_ONLY) +static target_ulong syscall_err; +#endif + +static void arm_semi_cb(CPUARMState *env, target_ulong ret, target_ulong err) +{ +#ifdef CONFIG_USER_ONLY + TaskState *ts = env->opaque; +#endif + + if (ret == (target_ulong)-1) { +#ifdef CONFIG_USER_ONLY + ts->swi_errno = err; +#else + syscall_err = err; +#endif + env->regs[0] = ret; + } else { + /* Fixup syscalls that use nonstardard return conventions. */ + switch (env->regs[0]) { + case TARGET_SYS_WRITE: + case TARGET_SYS_READ: + env->regs[0] = arm_semi_syscall_len - ret; + break; + case TARGET_SYS_SEEK: + env->regs[0] = 0; + break; + default: + env->regs[0] = ret; + break; + } + } +} + +static void arm_semi_flen_cb(CPUARMState *env, target_ulong ret, target_ulong err) +{ + /* The size is always stored in big-endian order, extract + the value. We assume the size always fit in 32 bits. */ + uint32_t size; + cpu_memory_rw_debug(env, env->regs[13]-64+32, (uint8_t *)&size, 4, 0); + env->regs[0] = be32_to_cpu(size); +#ifdef CONFIG_USER_ONLY + ((TaskState *)env->opaque)->swi_errno = err; +#else + syscall_err = err; +#endif +} + +#define ARG(n) \ +({ \ + target_ulong __arg; \ + /* FIXME - handle get_user() failure */ \ + get_user_ual(__arg, args + (n) * 4); \ + __arg; \ +}) +#define SET_ARG(n, val) put_user_ual(val, args + (n) * 4) +uint32_t do_arm_semihosting(CPUARMState *env) +{ + target_ulong args; + char * s; + int nr; + uint32_t ret; + uint32_t len; +#ifdef CONFIG_USER_ONLY + TaskState *ts = env->opaque; +#else + CPUARMState *ts = env; +#endif + + nr = env->regs[0]; + args = env->regs[1]; + switch (nr) { + case TARGET_SYS_OPEN: + if (!(s = lock_user_string(ARG(0)))) + /* FIXME - should this error code be -TARGET_EFAULT ? */ + return (uint32_t)-1; + if (ARG(1) >= 12) + return (uint32_t)-1; + if (strcmp(s, ":tt") == 0) { + if (ARG(1) < 4) + return STDIN_FILENO; + else + return STDOUT_FILENO; + } + if (use_gdb_syscalls()) { + gdb_do_syscall(arm_semi_cb, "open,%s,%x,1a4", ARG(0), + (int)ARG(2)+1, gdb_open_modeflags[ARG(1)]); + return env->regs[0]; + } else { + ret = set_swi_errno(ts, open(s, open_modeflags[ARG(1)], 0644)); + } + unlock_user(s, ARG(0), 0); + return ret; + case TARGET_SYS_CLOSE: + if (use_gdb_syscalls()) { + gdb_do_syscall(arm_semi_cb, "close,%x", ARG(0)); + return env->regs[0]; + } else { + return set_swi_errno(ts, close(ARG(0))); + } + case TARGET_SYS_WRITEC: + { + char c; + + if (get_user_u8(c, args)) + /* FIXME - should this error code be -TARGET_EFAULT ? */ + return (uint32_t)-1; + /* Write to debug console. stderr is near enough. */ + if (use_gdb_syscalls()) { + gdb_do_syscall(arm_semi_cb, "write,2,%x,1", args); + return env->regs[0]; + } else { + return write(STDERR_FILENO, &c, 1); + } + } + case TARGET_SYS_WRITE0: + if (!(s = lock_user_string(args))) + /* FIXME - should this error code be -TARGET_EFAULT ? */ + return (uint32_t)-1; + len = strlen(s); + if (use_gdb_syscalls()) { + gdb_do_syscall(arm_semi_cb, "write,2,%x,%x\n", args, len); + ret = env->regs[0]; + } else { + ret = write(STDERR_FILENO, s, len); + } + unlock_user(s, args, 0); + return ret; + case TARGET_SYS_WRITE: + len = ARG(2); + if (use_gdb_syscalls()) { + arm_semi_syscall_len = len; + gdb_do_syscall(arm_semi_cb, "write,%x,%x,%x", ARG(0), ARG(1), len); + return env->regs[0]; + } else { + if (!(s = lock_user(VERIFY_READ, ARG(1), len, 1))) + /* FIXME - should this error code be -TARGET_EFAULT ? */ + return (uint32_t)-1; + ret = set_swi_errno(ts, write(ARG(0), s, len)); + unlock_user(s, ARG(1), 0); + if (ret == (uint32_t)-1) + return -1; + return len - ret; + } + case TARGET_SYS_READ: + len = ARG(2); + if (use_gdb_syscalls()) { + arm_semi_syscall_len = len; + gdb_do_syscall(arm_semi_cb, "read,%x,%x,%x", ARG(0), ARG(1), len); + return env->regs[0]; + } else { + if (!(s = lock_user(VERIFY_WRITE, ARG(1), len, 0))) + /* FIXME - should this error code be -TARGET_EFAULT ? */ + return (uint32_t)-1; + do + ret = set_swi_errno(ts, read(ARG(0), s, len)); + while (ret == -1 && errno == EINTR); + unlock_user(s, ARG(1), len); + if (ret == (uint32_t)-1) + return -1; + return len - ret; + } + case TARGET_SYS_READC: + /* XXX: Read from debug cosole. Not implemented. */ + return 0; + case TARGET_SYS_ISTTY: + if (use_gdb_syscalls()) { + gdb_do_syscall(arm_semi_cb, "isatty,%x", ARG(0)); + return env->regs[0]; + } else { + return isatty(ARG(0)); + } + case TARGET_SYS_SEEK: + if (use_gdb_syscalls()) { + gdb_do_syscall(arm_semi_cb, "lseek,%x,%x,0", ARG(0), ARG(1)); + return env->regs[0]; + } else { + ret = set_swi_errno(ts, lseek(ARG(0), ARG(1), SEEK_SET)); + if (ret == (uint32_t)-1) + return -1; + return 0; + } + case TARGET_SYS_FLEN: + if (use_gdb_syscalls()) { + gdb_do_syscall(arm_semi_flen_cb, "fstat,%x,%x", + ARG(0), env->regs[13]-64); + return env->regs[0]; + } else { + struct stat buf; + ret = set_swi_errno(ts, fstat(ARG(0), &buf)); + if (ret == (uint32_t)-1) + return -1; + return buf.st_size; + } + case TARGET_SYS_TMPNAM: + /* XXX: Not implemented. */ + return -1; + case TARGET_SYS_REMOVE: + if (use_gdb_syscalls()) { + gdb_do_syscall(arm_semi_cb, "unlink,%s", ARG(0), (int)ARG(1)+1); + ret = env->regs[0]; + } else { + if (!(s = lock_user_string(ARG(0)))) + /* FIXME - should this error code be -TARGET_EFAULT ? */ + return (uint32_t)-1; + ret = set_swi_errno(ts, remove(s)); + unlock_user(s, ARG(0), 0); + } + return ret; + case TARGET_SYS_RENAME: + if (use_gdb_syscalls()) { + gdb_do_syscall(arm_semi_cb, "rename,%s,%s", + ARG(0), (int)ARG(1)+1, ARG(2), (int)ARG(3)+1); + return env->regs[0]; + } else { + char *s2; + s = lock_user_string(ARG(0)); + s2 = lock_user_string(ARG(2)); + if (!s || !s2) + /* FIXME - should this error code be -TARGET_EFAULT ? */ + ret = (uint32_t)-1; + else + ret = set_swi_errno(ts, rename(s, s2)); + if (s2) + unlock_user(s2, ARG(2), 0); + if (s) + unlock_user(s, ARG(0), 0); + return ret; + } + case TARGET_SYS_CLOCK: + return clock() / (CLOCKS_PER_SEC / 100); + case TARGET_SYS_TIME: + return set_swi_errno(ts, time(NULL)); + case TARGET_SYS_SYSTEM: + if (use_gdb_syscalls()) { + gdb_do_syscall(arm_semi_cb, "system,%s", ARG(0), (int)ARG(1)+1); + return env->regs[0]; + } else { + if (!(s = lock_user_string(ARG(0)))) + /* FIXME - should this error code be -TARGET_EFAULT ? */ + return (uint32_t)-1; + ret = set_swi_errno(ts, system(s)); + unlock_user(s, ARG(0), 0); + return ret; + } + case TARGET_SYS_ERRNO: +#ifdef CONFIG_USER_ONLY + return ts->swi_errno; +#else + return syscall_err; +#endif + case TARGET_SYS_GET_CMDLINE: + { + /* Build a command-line from the original argv. + * + * The inputs are: + * * ARG(0), pointer to a buffer of at least the size + * specified in ARG(1). + * * ARG(1), size of the buffer pointed to by ARG(0) in + * bytes. + * + * The outputs are: + * * ARG(0), pointer to null-terminated string of the + * command line. + * * ARG(1), length of the string pointed to by ARG(0). + */ + + char *output_buffer; + size_t input_size = ARG(1); + size_t output_size; + int status = 0; + + /* Compute the size of the output string. */ +#if !defined(CONFIG_USER_ONLY) + output_size = strlen(ts->boot_info->kernel_filename) + + 1 /* Separating space. */ + + strlen(ts->boot_info->kernel_cmdline) + + 1; /* Terminating null byte. */ +#else + unsigned int i; + + output_size = ts->info->arg_end - ts->info->arg_start; + if (!output_size) { + /* We special-case the "empty command line" case (argc==0). + Just provide the terminating 0. */ + output_size = 1; + } +#endif + + if (output_size > input_size) { + /* Not enough space to store command-line arguments. */ + return -1; + } + + /* Adjust the command-line length. */ + SET_ARG(1, output_size - 1); + + /* Lock the buffer on the ARM side. */ + output_buffer = lock_user(VERIFY_WRITE, ARG(0), output_size, 0); + if (!output_buffer) { + return -1; + } + + /* Copy the command-line arguments. */ +#if !defined(CONFIG_USER_ONLY) + pstrcpy(output_buffer, output_size, ts->boot_info->kernel_filename); + pstrcat(output_buffer, output_size, " "); + pstrcat(output_buffer, output_size, ts->boot_info->kernel_cmdline); +#else + if (output_size == 1) { + /* Empty command-line. */ + output_buffer[0] = '\0'; + goto out; + } + + if (copy_from_user(output_buffer, ts->info->arg_start, + output_size)) { + status = -1; + goto out; + } + + /* Separate arguments by white spaces. */ + for (i = 0; i < output_size - 1; i++) { + if (output_buffer[i] == 0) { + output_buffer[i] = ' '; + } + } + out: +#endif + /* Unlock the buffer on the ARM side. */ + unlock_user(output_buffer, ARG(0), output_size); + + return status; + } + case TARGET_SYS_HEAPINFO: + { + uint32_t *ptr; + uint32_t limit; + +#ifdef CONFIG_USER_ONLY + /* Some C libraries assume the heap immediately follows .bss, so + allocate it using sbrk. */ + if (!ts->heap_limit) { + abi_ulong ret; + + ts->heap_base = do_brk(0); + limit = ts->heap_base + ARM_ANGEL_HEAP_SIZE; + /* Try a big heap, and reduce the size if that fails. */ + for (;;) { + ret = do_brk(limit); + if (ret >= limit) { + break; + } + limit = (ts->heap_base >> 1) + (limit >> 1); + } + ts->heap_limit = limit; + } + + if (!(ptr = lock_user(VERIFY_WRITE, ARG(0), 16, 0))) + /* FIXME - should this error code be -TARGET_EFAULT ? */ + return (uint32_t)-1; + ptr[0] = tswap32(ts->heap_base); + ptr[1] = tswap32(ts->heap_limit); + ptr[2] = tswap32(ts->stack_base); + ptr[3] = tswap32(0); /* Stack limit. */ + unlock_user(ptr, ARG(0), 16); +#else + limit = ram_size; + if (!(ptr = lock_user(VERIFY_WRITE, ARG(0), 16, 0))) + /* FIXME - should this error code be -TARGET_EFAULT ? */ + return (uint32_t)-1; + /* TODO: Make this use the limit of the loaded application. */ + ptr[0] = tswap32(limit / 2); + ptr[1] = tswap32(limit); + ptr[2] = tswap32(limit); /* Stack base */ + ptr[3] = tswap32(0); /* Stack limit. */ + unlock_user(ptr, ARG(0), 16); +#endif + return 0; + } + case TARGET_SYS_EXIT: + gdb_exit(env, 0); + exit(0); + default: + fprintf(stderr, "qemu: Unsupported SemiHosting SWI 0x%02x\n", nr); + cpu_dump_state(env, stderr, fprintf, 0); + abort(); + } +} diff --git a/target-cris/Makefile.objs b/target-cris/Makefile.objs new file mode 100644 index 0000000000..c574c9ea7d --- /dev/null +++ b/target-cris/Makefile.objs @@ -0,0 +1 @@ +# still empty diff --git a/target-i386/Makefile.objs b/target-i386/Makefile.objs new file mode 100644 index 0000000000..93c6f3fce5 --- /dev/null +++ b/target-i386/Makefile.objs @@ -0,0 +1,3 @@ +obj-$(CONFIG_KVM) += hyperv.o +obj-$(CONFIG_LINUX_USER) += ioport-user.o +obj-$(CONFIG_BSD_USER) += ioport-user.o diff --git a/target-i386/ioport-user.c b/target-i386/ioport-user.c new file mode 100644 index 0000000000..03fac22d22 --- /dev/null +++ b/target-i386/ioport-user.c @@ -0,0 +1,60 @@ +/* + * qemu user ioport functions + * + * Copyright (c) 2003-2008 Fabrice Bellard + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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 + +#include "qemu.h" +#include "qemu-common.h" +#include "ioport.h" + +void cpu_outb(pio_addr_t addr, uint8_t val) +{ + fprintf(stderr, "outb: port=0x%04"FMT_pioaddr", data=%02"PRIx8"\n", + addr, val); +} + +void cpu_outw(pio_addr_t addr, uint16_t val) +{ + fprintf(stderr, "outw: port=0x%04"FMT_pioaddr", data=%04"PRIx16"\n", + addr, val); +} + +void cpu_outl(pio_addr_t addr, uint32_t val) +{ + fprintf(stderr, "outl: port=0x%04"FMT_pioaddr", data=%08"PRIx32"\n", + addr, val); +} + +uint8_t cpu_inb(pio_addr_t addr) +{ + fprintf(stderr, "inb: port=0x%04"FMT_pioaddr"\n", addr); + return 0; +} + +uint16_t cpu_inw(pio_addr_t addr) +{ + fprintf(stderr, "inw: port=0x%04"FMT_pioaddr"\n", addr); + return 0; +} + +uint32_t cpu_inl(pio_addr_t addr) +{ + fprintf(stderr, "inl: port=0x%04"FMT_pioaddr"\n", addr); + return 0; +} diff --git a/target-lm32/Makefile.objs b/target-lm32/Makefile.objs new file mode 100644 index 0000000000..c574c9ea7d --- /dev/null +++ b/target-lm32/Makefile.objs @@ -0,0 +1 @@ +# still empty diff --git a/target-m68k/Makefile.objs b/target-m68k/Makefile.objs new file mode 100644 index 0000000000..e73a5ba289 --- /dev/null +++ b/target-m68k/Makefile.objs @@ -0,0 +1 @@ +obj-y += m68k-semi.o diff --git a/target-m68k/m68k-semi.c b/target-m68k/m68k-semi.c new file mode 100644 index 0000000000..3bb30cd1f7 --- /dev/null +++ b/target-m68k/m68k-semi.c @@ -0,0 +1,408 @@ +/* + * m68k/ColdFire Semihosting syscall interface + * + * Copyright (c) 2005-2007 CodeSourcery. + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cpu.h" +#if defined(CONFIG_USER_ONLY) +#include "qemu.h" +#define SEMIHOSTING_HEAP_SIZE (128 * 1024 * 1024) +#else +#include "qemu-common.h" +#include "gdbstub.h" +#include "softmmu-semi.h" +#endif +#include "sysemu.h" + +#define HOSTED_EXIT 0 +#define HOSTED_INIT_SIM 1 +#define HOSTED_OPEN 2 +#define HOSTED_CLOSE 3 +#define HOSTED_READ 4 +#define HOSTED_WRITE 5 +#define HOSTED_LSEEK 6 +#define HOSTED_RENAME 7 +#define HOSTED_UNLINK 8 +#define HOSTED_STAT 9 +#define HOSTED_FSTAT 10 +#define HOSTED_GETTIMEOFDAY 11 +#define HOSTED_ISATTY 12 +#define HOSTED_SYSTEM 13 + +typedef uint32_t gdb_mode_t; +typedef uint32_t gdb_time_t; + +struct m68k_gdb_stat { + uint32_t gdb_st_dev; /* device */ + uint32_t gdb_st_ino; /* inode */ + gdb_mode_t gdb_st_mode; /* protection */ + uint32_t gdb_st_nlink; /* number of hard links */ + uint32_t gdb_st_uid; /* user ID of owner */ + uint32_t gdb_st_gid; /* group ID of owner */ + uint32_t gdb_st_rdev; /* device type (if inode device) */ + uint64_t gdb_st_size; /* total size, in bytes */ + uint64_t gdb_st_blksize; /* blocksize for filesystem I/O */ + uint64_t gdb_st_blocks; /* number of blocks allocated */ + gdb_time_t gdb_st_atime; /* time of last access */ + gdb_time_t gdb_st_mtime; /* time of last modification */ + gdb_time_t gdb_st_ctime; /* time of last change */ +} QEMU_PACKED; + +struct gdb_timeval { + gdb_time_t tv_sec; /* second */ + uint64_t tv_usec; /* microsecond */ +} QEMU_PACKED; + +#define GDB_O_RDONLY 0x0 +#define GDB_O_WRONLY 0x1 +#define GDB_O_RDWR 0x2 +#define GDB_O_APPEND 0x8 +#define GDB_O_CREAT 0x200 +#define GDB_O_TRUNC 0x400 +#define GDB_O_EXCL 0x800 + +static int translate_openflags(int flags) +{ + int hf; + + if (flags & GDB_O_WRONLY) + hf = O_WRONLY; + else if (flags & GDB_O_RDWR) + hf = O_RDWR; + else + hf = O_RDONLY; + + if (flags & GDB_O_APPEND) hf |= O_APPEND; + if (flags & GDB_O_CREAT) hf |= O_CREAT; + if (flags & GDB_O_TRUNC) hf |= O_TRUNC; + if (flags & GDB_O_EXCL) hf |= O_EXCL; + + return hf; +} + +static void translate_stat(CPUM68KState *env, target_ulong addr, struct stat *s) +{ + struct m68k_gdb_stat *p; + + if (!(p = lock_user(VERIFY_WRITE, addr, sizeof(struct m68k_gdb_stat), 0))) + /* FIXME - should this return an error code? */ + return; + p->gdb_st_dev = cpu_to_be32(s->st_dev); + p->gdb_st_ino = cpu_to_be32(s->st_ino); + p->gdb_st_mode = cpu_to_be32(s->st_mode); + p->gdb_st_nlink = cpu_to_be32(s->st_nlink); + p->gdb_st_uid = cpu_to_be32(s->st_uid); + p->gdb_st_gid = cpu_to_be32(s->st_gid); + p->gdb_st_rdev = cpu_to_be32(s->st_rdev); + p->gdb_st_size = cpu_to_be64(s->st_size); +#ifdef _WIN32 + /* Windows stat is missing some fields. */ + p->gdb_st_blksize = 0; + p->gdb_st_blocks = 0; +#else + p->gdb_st_blksize = cpu_to_be64(s->st_blksize); + p->gdb_st_blocks = cpu_to_be64(s->st_blocks); +#endif + p->gdb_st_atime = cpu_to_be32(s->st_atime); + p->gdb_st_mtime = cpu_to_be32(s->st_mtime); + p->gdb_st_ctime = cpu_to_be32(s->st_ctime); + unlock_user(p, addr, sizeof(struct m68k_gdb_stat)); +} + +static int m68k_semi_is_fseek; + +static void m68k_semi_cb(CPUM68KState *env, target_ulong ret, target_ulong err) +{ + target_ulong args; + + args = env->dregs[1]; + if (m68k_semi_is_fseek) { + /* FIXME: We've already lost the high bits of the fseek + return value. */ + /* FIXME - handle put_user() failure */ + put_user_u32(0, args); + args += 4; + m68k_semi_is_fseek = 0; + } + /* FIXME - handle put_user() failure */ + put_user_u32(ret, args); + put_user_u32(errno, args + 4); +} + +#define ARG(n) \ +({ \ + target_ulong __arg; \ + /* FIXME - handle get_user() failure */ \ + get_user_ual(__arg, args + (n) * 4); \ + __arg; \ +}) +#define PARG(x) ((unsigned long)ARG(x)) +void do_m68k_semihosting(CPUM68KState *env, int nr) +{ + uint32_t args; + void *p; + void *q; + uint32_t len; + uint32_t result; + + args = env->dregs[1]; + switch (nr) { + case HOSTED_EXIT: + gdb_exit(env, env->dregs[0]); + exit(env->dregs[0]); + case HOSTED_OPEN: + if (use_gdb_syscalls()) { + gdb_do_syscall(m68k_semi_cb, "open,%s,%x,%x", ARG(0), (int)ARG(1), + ARG(2), ARG(3)); + return; + } else { + if (!(p = lock_user_string(ARG(0)))) { + /* FIXME - check error code? */ + result = -1; + } else { + result = open(p, translate_openflags(ARG(2)), ARG(3)); + unlock_user(p, ARG(0), 0); + } + } + break; + case HOSTED_CLOSE: + { + /* Ignore attempts to close stdin/out/err. */ + int fd = ARG(0); + if (fd > 2) { + if (use_gdb_syscalls()) { + gdb_do_syscall(m68k_semi_cb, "close,%x", ARG(0)); + return; + } else { + result = close(fd); + } + } else { + result = 0; + } + break; + } + case HOSTED_READ: + len = ARG(2); + if (use_gdb_syscalls()) { + gdb_do_syscall(m68k_semi_cb, "read,%x,%x,%x", + ARG(0), ARG(1), len); + return; + } else { + if (!(p = lock_user(VERIFY_WRITE, ARG(1), len, 0))) { + /* FIXME - check error code? */ + result = -1; + } else { + result = read(ARG(0), p, len); + unlock_user(p, ARG(1), len); + } + } + break; + case HOSTED_WRITE: + len = ARG(2); + if (use_gdb_syscalls()) { + gdb_do_syscall(m68k_semi_cb, "write,%x,%x,%x", + ARG(0), ARG(1), len); + return; + } else { + if (!(p = lock_user(VERIFY_READ, ARG(1), len, 1))) { + /* FIXME - check error code? */ + result = -1; + } else { + result = write(ARG(0), p, len); + unlock_user(p, ARG(0), 0); + } + } + break; + case HOSTED_LSEEK: + { + uint64_t off; + off = (uint32_t)ARG(2) | ((uint64_t)ARG(1) << 32); + if (use_gdb_syscalls()) { + m68k_semi_is_fseek = 1; + gdb_do_syscall(m68k_semi_cb, "fseek,%x,%lx,%x", + ARG(0), off, ARG(3)); + } else { + off = lseek(ARG(0), off, ARG(3)); + /* FIXME - handle put_user() failure */ + put_user_u32(off >> 32, args); + put_user_u32(off, args + 4); + put_user_u32(errno, args + 8); + } + return; + } + case HOSTED_RENAME: + if (use_gdb_syscalls()) { + gdb_do_syscall(m68k_semi_cb, "rename,%s,%s", + ARG(0), (int)ARG(1), ARG(2), (int)ARG(3)); + return; + } else { + p = lock_user_string(ARG(0)); + q = lock_user_string(ARG(2)); + if (!p || !q) { + /* FIXME - check error code? */ + result = -1; + } else { + result = rename(p, q); + } + unlock_user(p, ARG(0), 0); + unlock_user(q, ARG(2), 0); + } + break; + case HOSTED_UNLINK: + if (use_gdb_syscalls()) { + gdb_do_syscall(m68k_semi_cb, "unlink,%s", + ARG(0), (int)ARG(1)); + return; + } else { + if (!(p = lock_user_string(ARG(0)))) { + /* FIXME - check error code? */ + result = -1; + } else { + result = unlink(p); + unlock_user(p, ARG(0), 0); + } + } + break; + case HOSTED_STAT: + if (use_gdb_syscalls()) { + gdb_do_syscall(m68k_semi_cb, "stat,%s,%x", + ARG(0), (int)ARG(1), ARG(2)); + return; + } else { + struct stat s; + if (!(p = lock_user_string(ARG(0)))) { + /* FIXME - check error code? */ + result = -1; + } else { + result = stat(p, &s); + unlock_user(p, ARG(0), 0); + } + if (result == 0) { + translate_stat(env, ARG(2), &s); + } + } + break; + case HOSTED_FSTAT: + if (use_gdb_syscalls()) { + gdb_do_syscall(m68k_semi_cb, "fstat,%x,%x", + ARG(0), ARG(1)); + return; + } else { + struct stat s; + result = fstat(ARG(0), &s); + if (result == 0) { + translate_stat(env, ARG(1), &s); + } + } + break; + case HOSTED_GETTIMEOFDAY: + if (use_gdb_syscalls()) { + gdb_do_syscall(m68k_semi_cb, "gettimeofday,%x,%x", + ARG(0), ARG(1)); + return; + } else { + qemu_timeval tv; + struct gdb_timeval *p; + result = qemu_gettimeofday(&tv); + if (result != 0) { + if (!(p = lock_user(VERIFY_WRITE, + ARG(0), sizeof(struct gdb_timeval), 0))) { + /* FIXME - check error code? */ + result = -1; + } else { + p->tv_sec = cpu_to_be32(tv.tv_sec); + p->tv_usec = cpu_to_be64(tv.tv_usec); + unlock_user(p, ARG(0), sizeof(struct gdb_timeval)); + } + } + } + break; + case HOSTED_ISATTY: + if (use_gdb_syscalls()) { + gdb_do_syscall(m68k_semi_cb, "isatty,%x", ARG(0)); + return; + } else { + result = isatty(ARG(0)); + } + break; + case HOSTED_SYSTEM: + if (use_gdb_syscalls()) { + gdb_do_syscall(m68k_semi_cb, "system,%s", + ARG(0), (int)ARG(1)); + return; + } else { + if (!(p = lock_user_string(ARG(0)))) { + /* FIXME - check error code? */ + result = -1; + } else { + result = system(p); + unlock_user(p, ARG(0), 0); + } + } + break; + case HOSTED_INIT_SIM: +#if defined(CONFIG_USER_ONLY) + { + TaskState *ts = env->opaque; + /* Allocate the heap using sbrk. */ + if (!ts->heap_limit) { + abi_ulong ret; + uint32_t size; + uint32_t base; + + base = do_brk(0); + size = SEMIHOSTING_HEAP_SIZE; + /* Try a big heap, and reduce the size if that fails. */ + for (;;) { + ret = do_brk(base + size); + if (ret >= (base + size)) { + break; + } + size >>= 1; + } + ts->heap_limit = base + size; + } + /* This call may happen before we have writable memory, so return + values directly in registers. */ + env->dregs[1] = ts->heap_limit; + env->aregs[7] = ts->stack_base; + } +#else + /* FIXME: This is wrong for boards where RAM does not start at + address zero. */ + env->dregs[1] = ram_size; + env->aregs[7] = ram_size; +#endif + return; + default: + cpu_abort(env, "Unsupported semihosting syscall %d\n", nr); + result = 0; + } + /* FIXME - handle put_user() failure */ + put_user_u32(result, args); + put_user_u32(errno, args + 4); +} diff --git a/target-microblaze/Makefile.objs b/target-microblaze/Makefile.objs new file mode 100644 index 0000000000..c574c9ea7d --- /dev/null +++ b/target-microblaze/Makefile.objs @@ -0,0 +1 @@ +# still empty diff --git a/target-mips/Makefile.objs b/target-mips/Makefile.objs new file mode 100644 index 0000000000..c574c9ea7d --- /dev/null +++ b/target-mips/Makefile.objs @@ -0,0 +1 @@ +# still empty diff --git a/target-ppc/Makefile.objs b/target-ppc/Makefile.objs new file mode 100644 index 0000000000..c574c9ea7d --- /dev/null +++ b/target-ppc/Makefile.objs @@ -0,0 +1 @@ +# still empty diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs new file mode 100644 index 0000000000..c574c9ea7d --- /dev/null +++ b/target-s390x/Makefile.objs @@ -0,0 +1 @@ +# still empty diff --git a/target-sh4/Makefile.objs b/target-sh4/Makefile.objs new file mode 100644 index 0000000000..c574c9ea7d --- /dev/null +++ b/target-sh4/Makefile.objs @@ -0,0 +1 @@ +# still empty diff --git a/target-sparc/Makefile.objs b/target-sparc/Makefile.objs new file mode 100644 index 0000000000..c574c9ea7d --- /dev/null +++ b/target-sparc/Makefile.objs @@ -0,0 +1 @@ +# still empty diff --git a/target-unicore32/Makefile.objs b/target-unicore32/Makefile.objs new file mode 100644 index 0000000000..c574c9ea7d --- /dev/null +++ b/target-unicore32/Makefile.objs @@ -0,0 +1 @@ +# still empty diff --git a/target-xtensa/Makefile.objs b/target-xtensa/Makefile.objs new file mode 100644 index 0000000000..a49ca8d09f --- /dev/null +++ b/target-xtensa/Makefile.objs @@ -0,0 +1,4 @@ +obj-y += xtensa-semi.o +obj-y += core-dc232b.o +obj-y += core-dc233c.o +obj-y += core-fsf.o diff --git a/target-xtensa/xtensa-semi.c b/target-xtensa/xtensa-semi.c new file mode 100644 index 0000000000..b7c8c34564 --- /dev/null +++ b/target-xtensa/xtensa-semi.c @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2011, Max Filippov, Open Source and Linux Lab. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Open Source and Linux Lab nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include "cpu.h" +#include "dyngen-exec.h" +#include "helper.h" +#include "qemu-log.h" + +enum { + TARGET_SYS_exit = 1, + TARGET_SYS_read = 3, + TARGET_SYS_write = 4, + TARGET_SYS_open = 5, + TARGET_SYS_close = 6, + TARGET_SYS_lseek = 19, + TARGET_SYS_select_one = 29, + + TARGET_SYS_argc = 1000, + TARGET_SYS_argv_sz = 1001, + TARGET_SYS_argv = 1002, + TARGET_SYS_memset = 1004, +}; + +enum { + SELECT_ONE_READ = 1, + SELECT_ONE_WRITE = 2, + SELECT_ONE_EXCEPT = 3, +}; + +void HELPER(simcall)(CPUXtensaState *env) +{ + uint32_t *regs = env->regs; + + switch (regs[2]) { + case TARGET_SYS_exit: + qemu_log("exit(%d) simcall\n", regs[3]); + exit(regs[3]); + break; + + case TARGET_SYS_read: + case TARGET_SYS_write: + { + bool is_write = regs[2] == TARGET_SYS_write; + uint32_t fd = regs[3]; + uint32_t vaddr = regs[4]; + uint32_t len = regs[5]; + + while (len > 0) { + target_phys_addr_t paddr = + cpu_get_phys_page_debug(env, vaddr); + uint32_t page_left = + TARGET_PAGE_SIZE - (vaddr & (TARGET_PAGE_SIZE - 1)); + uint32_t io_sz = page_left < len ? page_left : len; + target_phys_addr_t sz = io_sz; + void *buf = cpu_physical_memory_map(paddr, &sz, is_write); + + if (buf) { + vaddr += io_sz; + len -= io_sz; + regs[2] = is_write ? + write(fd, buf, io_sz) : + read(fd, buf, io_sz); + regs[3] = errno; + cpu_physical_memory_unmap(buf, sz, is_write, sz); + if (regs[2] == -1) { + break; + } + } else { + regs[2] = -1; + regs[3] = EINVAL; + break; + } + } + } + break; + + case TARGET_SYS_open: + { + char name[1024]; + int rc; + int i; + + for (i = 0; i < ARRAY_SIZE(name); ++i) { + rc = cpu_memory_rw_debug( + env, regs[3] + i, (uint8_t *)name + i, 1, 0); + if (rc != 0 || name[i] == 0) { + break; + } + } + + if (rc == 0 && i < ARRAY_SIZE(name)) { + regs[2] = open(name, regs[4], regs[5]); + regs[3] = errno; + } else { + regs[2] = -1; + regs[3] = EINVAL; + } + } + break; + + case TARGET_SYS_close: + if (regs[3] < 3) { + regs[2] = regs[3] = 0; + } else { + regs[2] = close(regs[3]); + regs[3] = errno; + } + break; + + case TARGET_SYS_lseek: + regs[2] = lseek(regs[3], (off_t)(int32_t)regs[4], regs[5]); + regs[3] = errno; + break; + + case TARGET_SYS_select_one: + { + uint32_t fd = regs[3]; + uint32_t rq = regs[4]; + uint32_t target_tv = regs[5]; + uint32_t target_tvv[2]; + + struct timeval tv = {0}; + fd_set fdset; + + FD_ZERO(&fdset); + FD_SET(fd, &fdset); + + if (target_tv) { + cpu_memory_rw_debug(env, target_tv, + (uint8_t *)target_tvv, sizeof(target_tvv), 0); + tv.tv_sec = (int32_t)tswap32(target_tvv[0]); + tv.tv_usec = (int32_t)tswap32(target_tvv[1]); + } + regs[2] = select(fd + 1, + rq == SELECT_ONE_READ ? &fdset : NULL, + rq == SELECT_ONE_WRITE ? &fdset : NULL, + rq == SELECT_ONE_EXCEPT ? &fdset : NULL, + target_tv ? &tv : NULL); + regs[3] = errno; + } + break; + + case TARGET_SYS_argc: + regs[2] = 1; + regs[3] = 0; + break; + + case TARGET_SYS_argv_sz: + regs[2] = 128; + regs[3] = 0; + break; + + case TARGET_SYS_argv: + { + struct Argv { + uint32_t argptr[2]; + char text[120]; + } argv = { + {0, 0}, + "test" + }; + + argv.argptr[0] = tswap32(regs[3] + offsetof(struct Argv, text)); + cpu_memory_rw_debug( + env, regs[3], (uint8_t *)&argv, sizeof(argv), 1); + } + break; + + case TARGET_SYS_memset: + { + uint32_t base = regs[3]; + uint32_t sz = regs[5]; + + while (sz) { + target_phys_addr_t len = sz; + void *buf = cpu_physical_memory_map(base, &len, 1); + + if (buf && len) { + memset(buf, regs[4], len); + cpu_physical_memory_unmap(buf, len, 1, len); + } else { + len = 1; + } + base += len; + sz -= len; + } + regs[2] = regs[3]; + regs[3] = 0; + } + break; + + default: + qemu_log("%s(%d): not implemented\n", __func__, regs[2]); + break; + } +} diff --git a/xtensa-semi.c b/xtensa-semi.c deleted file mode 100644 index b7c8c34564..0000000000 --- a/xtensa-semi.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright (c) 2011, Max Filippov, Open Source and Linux Lab. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the Open Source and Linux Lab nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include "cpu.h" -#include "dyngen-exec.h" -#include "helper.h" -#include "qemu-log.h" - -enum { - TARGET_SYS_exit = 1, - TARGET_SYS_read = 3, - TARGET_SYS_write = 4, - TARGET_SYS_open = 5, - TARGET_SYS_close = 6, - TARGET_SYS_lseek = 19, - TARGET_SYS_select_one = 29, - - TARGET_SYS_argc = 1000, - TARGET_SYS_argv_sz = 1001, - TARGET_SYS_argv = 1002, - TARGET_SYS_memset = 1004, -}; - -enum { - SELECT_ONE_READ = 1, - SELECT_ONE_WRITE = 2, - SELECT_ONE_EXCEPT = 3, -}; - -void HELPER(simcall)(CPUXtensaState *env) -{ - uint32_t *regs = env->regs; - - switch (regs[2]) { - case TARGET_SYS_exit: - qemu_log("exit(%d) simcall\n", regs[3]); - exit(regs[3]); - break; - - case TARGET_SYS_read: - case TARGET_SYS_write: - { - bool is_write = regs[2] == TARGET_SYS_write; - uint32_t fd = regs[3]; - uint32_t vaddr = regs[4]; - uint32_t len = regs[5]; - - while (len > 0) { - target_phys_addr_t paddr = - cpu_get_phys_page_debug(env, vaddr); - uint32_t page_left = - TARGET_PAGE_SIZE - (vaddr & (TARGET_PAGE_SIZE - 1)); - uint32_t io_sz = page_left < len ? page_left : len; - target_phys_addr_t sz = io_sz; - void *buf = cpu_physical_memory_map(paddr, &sz, is_write); - - if (buf) { - vaddr += io_sz; - len -= io_sz; - regs[2] = is_write ? - write(fd, buf, io_sz) : - read(fd, buf, io_sz); - regs[3] = errno; - cpu_physical_memory_unmap(buf, sz, is_write, sz); - if (regs[2] == -1) { - break; - } - } else { - regs[2] = -1; - regs[3] = EINVAL; - break; - } - } - } - break; - - case TARGET_SYS_open: - { - char name[1024]; - int rc; - int i; - - for (i = 0; i < ARRAY_SIZE(name); ++i) { - rc = cpu_memory_rw_debug( - env, regs[3] + i, (uint8_t *)name + i, 1, 0); - if (rc != 0 || name[i] == 0) { - break; - } - } - - if (rc == 0 && i < ARRAY_SIZE(name)) { - regs[2] = open(name, regs[4], regs[5]); - regs[3] = errno; - } else { - regs[2] = -1; - regs[3] = EINVAL; - } - } - break; - - case TARGET_SYS_close: - if (regs[3] < 3) { - regs[2] = regs[3] = 0; - } else { - regs[2] = close(regs[3]); - regs[3] = errno; - } - break; - - case TARGET_SYS_lseek: - regs[2] = lseek(regs[3], (off_t)(int32_t)regs[4], regs[5]); - regs[3] = errno; - break; - - case TARGET_SYS_select_one: - { - uint32_t fd = regs[3]; - uint32_t rq = regs[4]; - uint32_t target_tv = regs[5]; - uint32_t target_tvv[2]; - - struct timeval tv = {0}; - fd_set fdset; - - FD_ZERO(&fdset); - FD_SET(fd, &fdset); - - if (target_tv) { - cpu_memory_rw_debug(env, target_tv, - (uint8_t *)target_tvv, sizeof(target_tvv), 0); - tv.tv_sec = (int32_t)tswap32(target_tvv[0]); - tv.tv_usec = (int32_t)tswap32(target_tvv[1]); - } - regs[2] = select(fd + 1, - rq == SELECT_ONE_READ ? &fdset : NULL, - rq == SELECT_ONE_WRITE ? &fdset : NULL, - rq == SELECT_ONE_EXCEPT ? &fdset : NULL, - target_tv ? &tv : NULL); - regs[3] = errno; - } - break; - - case TARGET_SYS_argc: - regs[2] = 1; - regs[3] = 0; - break; - - case TARGET_SYS_argv_sz: - regs[2] = 128; - regs[3] = 0; - break; - - case TARGET_SYS_argv: - { - struct Argv { - uint32_t argptr[2]; - char text[120]; - } argv = { - {0, 0}, - "test" - }; - - argv.argptr[0] = tswap32(regs[3] + offsetof(struct Argv, text)); - cpu_memory_rw_debug( - env, regs[3], (uint8_t *)&argv, sizeof(argv), 1); - } - break; - - case TARGET_SYS_memset: - { - uint32_t base = regs[3]; - uint32_t sz = regs[5]; - - while (sz) { - target_phys_addr_t len = sz; - void *buf = cpu_physical_memory_map(base, &len, 1); - - if (buf && len) { - memset(buf, regs[4], len); - cpu_physical_memory_unmap(buf, len, 1, len); - } else { - len = 1; - } - base += len; - sz -= len; - } - regs[2] = regs[3]; - regs[3] = 0; - } - break; - - default: - qemu_log("%s(%d): not implemented\n", __func__, regs[2]); - break; - } -} -- cgit v1.2.3-55-g7522