r2356 - in trunk/src/host/qemu-neo1973: . hw linux-user linux-user/i386 pc-bios target-arm target-i386 target-mips target-ppc target-sh4 target-sparc
andrew at sita.openmoko.org
andrew at sita.openmoko.org
Mon Jul 2 22:44:21 CEST 2007
Author: andrew
Date: 2007-07-02 22:43:42 +0200 (Mon, 02 Jul 2007)
New Revision: 2356
Modified:
trunk/src/host/qemu-neo1973/Changelog
trunk/src/host/qemu-neo1973/Makefile
trunk/src/host/qemu-neo1973/Makefile.target
trunk/src/host/qemu-neo1973/block-vmdk.c
trunk/src/host/qemu-neo1973/configure
trunk/src/host/qemu-neo1973/cpu-defs.h
trunk/src/host/qemu-neo1973/dyngen.h
trunk/src/host/qemu-neo1973/exec-all.h
trunk/src/host/qemu-neo1973/exec.c
trunk/src/host/qemu-neo1973/hw/ads7846.c
trunk/src/host/qemu-neo1973/hw/eepro100.c
trunk/src/host/qemu-neo1973/hw/integratorcp.c
trunk/src/host/qemu-neo1973/hw/mips_malta.c
trunk/src/host/qemu-neo1973/hw/mips_pica61.c
trunk/src/host/qemu-neo1973/hw/ne2000.c
trunk/src/host/qemu-neo1973/hw/parallel.c
trunk/src/host/qemu-neo1973/hw/pcnet.c
trunk/src/host/qemu-neo1973/hw/pl110.c
trunk/src/host/qemu-neo1973/hw/realview.c
trunk/src/host/qemu-neo1973/hw/slavio_serial.c
trunk/src/host/qemu-neo1973/hw/spitz.c
trunk/src/host/qemu-neo1973/hw/sun4m.c
trunk/src/host/qemu-neo1973/hw/tcx.c
trunk/src/host/qemu-neo1973/hw/versatilepb.c
trunk/src/host/qemu-neo1973/linux-user/elfload.c
trunk/src/host/qemu-neo1973/linux-user/i386/syscall_nr.h
trunk/src/host/qemu-neo1973/linux-user/main.c
trunk/src/host/qemu-neo1973/linux-user/syscall.c
trunk/src/host/qemu-neo1973/linux-user/syscall_defs.h
trunk/src/host/qemu-neo1973/monitor.c
trunk/src/host/qemu-neo1973/pc-bios/README
trunk/src/host/qemu-neo1973/pc-bios/openbios-sparc32
trunk/src/host/qemu-neo1973/pc-bios/openbios-sparc64
trunk/src/host/qemu-neo1973/qemu-doc.texi
trunk/src/host/qemu-neo1973/qemu-img.c
trunk/src/host/qemu-neo1973/readline.c
trunk/src/host/qemu-neo1973/sdl.c
trunk/src/host/qemu-neo1973/target-arm/cpu.h
trunk/src/host/qemu-neo1973/target-arm/helper.c
trunk/src/host/qemu-neo1973/target-i386/exec.h
trunk/src/host/qemu-neo1973/target-i386/helper.c
trunk/src/host/qemu-neo1973/target-i386/op.c
trunk/src/host/qemu-neo1973/target-i386/translate.c
trunk/src/host/qemu-neo1973/target-mips/cpu.h
trunk/src/host/qemu-neo1973/target-mips/helper.c
trunk/src/host/qemu-neo1973/target-mips/op.c
trunk/src/host/qemu-neo1973/target-mips/op_helper.c
trunk/src/host/qemu-neo1973/target-mips/translate.c
trunk/src/host/qemu-neo1973/target-mips/translate_init.c
trunk/src/host/qemu-neo1973/target-ppc/cpu.h
trunk/src/host/qemu-neo1973/target-ppc/op.c
trunk/src/host/qemu-neo1973/target-sh4/cpu.h
trunk/src/host/qemu-neo1973/target-sh4/exec.h
trunk/src/host/qemu-neo1973/target-sh4/op.c
trunk/src/host/qemu-neo1973/target-sh4/translate.c
trunk/src/host/qemu-neo1973/target-sparc/translate.c
trunk/src/host/qemu-neo1973/vl.c
trunk/src/host/qemu-neo1973/vl.h
Log:
Merge changes from cvs.savannah.nongnu.org:/sources/qemu.
Modified: trunk/src/host/qemu-neo1973/Changelog
===================================================================
--- trunk/src/host/qemu-neo1973/Changelog 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/Changelog 2007-07-02 20:43:42 UTC (rev 2356)
@@ -7,6 +7,9 @@
- MIPS 64-bit FPU support (Thiemo Seufer)
- Xscale PDA emulation (Andrzei Zaborowski)
- ColdFire system emulation (Paul Brook)
+ - Improved SH4 support (Magnus Damm)
+ - MIPS64 support (Aurelien Jarno, Thiemo Seufer)
+ - Preliminary Alpha guest support (J. Mayer)
version 0.9.0:
Modified: trunk/src/host/qemu-neo1973/Makefile
===================================================================
--- trunk/src/host/qemu-neo1973/Makefile 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/Makefile 2007-07-02 20:43:42 UTC (rev 2356)
@@ -49,7 +49,7 @@
clean:
# avoid old build problems by removing potentially incorrect old files
rm -f config.mak config.h op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h gen-op-arm.h
- rm -f *.o *.a $(TOOLS) dyngen$(EXESUF) TAGS *.pod *~ */*~
+ rm -f *.o *.a $(TOOLS) dyngen$(EXESUF) TAGS cscope.* *.pod *~ */*~
$(MAKE) -C tests clean
for d in $(TARGET_DIRS); do \
$(MAKE) -C $$d $@ || exit 1 ; \
Modified: trunk/src/host/qemu-neo1973/Makefile.target
===================================================================
--- trunk/src/host/qemu-neo1973/Makefile.target 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/Makefile.target 2007-07-02 20:43:42 UTC (rev 2356)
@@ -446,6 +446,7 @@
ifeq ($(TARGET_BASE_ARCH), mips)
VL_OBJS+= mips_r4k.o mips_malta.o mips_pica61.o
VL_OBJS+= mips_timer.o mips_int.o dma.o vga.o serial.o i8254.o i8259.o
+VL_OBJS+= jazz_led.o
VL_OBJS+= ide.o gt64xxx.o pckbd.o ps2.o fdc.o mc146818rtc.o usb-uhci.o acpi.o ds1225y.o
VL_OBJS+= piix_pci.o smbus_eeprom.o parallel.o mixeng.o cirrus_vga.o $(SOUND_HW) $(AUDIODRV)
CPPFLAGS += -DHAS_AUDIO
@@ -463,7 +464,7 @@
endif
ifeq ($(TARGET_BASE_ARCH), arm)
VL_OBJS+= integratorcp.o versatilepb.o ps2.o smc91c111.o arm_pic.o arm_timer.o
-VL_OBJS+= arm_boot.o pl011.o pl050.o pl080.o pl110.o pl181.o pl190.o
+VL_OBJS+= arm_boot.o pl011.o pl031.o pl050.o pl080.o pl110.o pl181.o pl190.o
VL_OBJS+= versatile_pci.o sd.o ptimer.o
VL_OBJS+= arm_gic.o realview.o arm_sysctl.o
VL_OBJS+= arm-semi.o
Modified: trunk/src/host/qemu-neo1973/block-vmdk.c
===================================================================
--- trunk/src/host/qemu-neo1973/block-vmdk.c 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/block-vmdk.c 2007-07-02 20:43:42 UTC (rev 2356)
@@ -75,8 +75,25 @@
unsigned int cluster_sectors;
uint32_t parent_cid;
+ int is_parent;
} BDRVVmdkState;
+typedef struct VmdkMetaData {
+ uint32_t offset;
+ unsigned int l1_index;
+ unsigned int l2_index;
+ unsigned int l2_offset;
+ int valid;
+} VmdkMetaData;
+
+typedef struct ActiveBDRVState{
+ BlockDriverState *hd; // active image handler
+ uint64_t cluster_offset; // current write offset
+}ActiveBDRVState;
+
+static ActiveBDRVState activeBDRV;
+
+
static int vmdk_probe(const uint8_t *buf, int buf_size, const char *filename)
{
uint32_t magic;
@@ -305,7 +322,7 @@
bdrv_close(bs->backing_hd);
}
-
+int parent_open = 0;
static int vmdk_parent_open(BlockDriverState *bs, const char * filename)
{
BDRVVmdkState *s = bs->opaque;
@@ -339,8 +356,10 @@
bdrv_close(s->hd);
return -1;
}
- if (bdrv_open(s->hd->backing_hd, parent_img_name, 0) < 0)
+ parent_open = 1;
+ if (bdrv_open(s->hd->backing_hd, parent_img_name, BDRV_O_RDONLY) < 0)
goto failure;
+ parent_open = 0;
}
return 0;
@@ -352,6 +371,11 @@
uint32_t magic;
int l1_size, i, ret;
+ if (parent_open)
+ // Parent must be opened as RO.
+ flags = BDRV_O_RDONLY;
+ fprintf(stderr, "(VMDK) image open: flags=0x%x filename=%s\n", flags, bs->filename);
+
ret = bdrv_file_open(&s->hd, filename, flags);
if (ret < 0)
return ret;
@@ -387,6 +411,11 @@
s->l1_table_offset = le64_to_cpu(header.rgd_offset) << 9;
s->l1_backup_table_offset = le64_to_cpu(header.gd_offset) << 9;
+ if (parent_open)
+ s->is_parent = 1;
+ else
+ s->is_parent = 0;
+
// try to open parent images, if exist
if (vmdk_parent_open(bs, filename) != 0)
goto fail;
@@ -430,7 +459,8 @@
return -1;
}
-static uint64_t get_cluster_offset(BlockDriverState *bs, uint64_t offset, int allocate);
+static uint64_t get_cluster_offset(BlockDriverState *bs, VmdkMetaData *m_data,
+ uint64_t offset, int allocate);
static int get_whole_cluster(BlockDriverState *bs, uint64_t cluster_offset,
uint64_t offset, int allocate)
@@ -446,27 +476,55 @@
if (!vmdk_is_cid_valid(bs))
return -1;
- parent_cluster_offset = get_cluster_offset(s->hd->backing_hd, offset, allocate);
- if (bdrv_pread(ps->hd, parent_cluster_offset, whole_grain, ps->cluster_sectors*512) !=
- ps->cluster_sectors*512)
- return -1;
- if (bdrv_pwrite(s->hd, cluster_offset << 9, whole_grain, sizeof(whole_grain)) !=
- sizeof(whole_grain))
+ parent_cluster_offset = get_cluster_offset(s->hd->backing_hd, NULL, offset, allocate);
+
+ if (parent_cluster_offset) {
+ BDRVVmdkState *act_s = activeBDRV.hd->opaque;
+
+ if (bdrv_pread(ps->hd, parent_cluster_offset, whole_grain, ps->cluster_sectors*512) != ps->cluster_sectors*512)
+ return -1;
+
+ //Write grain only into the active image
+ if (bdrv_pwrite(act_s->hd, activeBDRV.cluster_offset << 9, whole_grain, sizeof(whole_grain)) != sizeof(whole_grain))
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int vmdk_L2update(BlockDriverState *bs, VmdkMetaData *m_data)
+{
+ BDRVVmdkState *s = bs->opaque;
+
+ /* update L2 table */
+ if (bdrv_pwrite(s->hd, ((int64_t)m_data->l2_offset * 512) + (m_data->l2_index * sizeof(m_data->offset)),
+ &(m_data->offset), sizeof(m_data->offset)) != sizeof(m_data->offset))
+ return -1;
+ /* update backup L2 table */
+ if (s->l1_backup_table_offset != 0) {
+ m_data->l2_offset = s->l1_backup_table[m_data->l1_index];
+ if (bdrv_pwrite(s->hd, ((int64_t)m_data->l2_offset * 512) + (m_data->l2_index * sizeof(m_data->offset)),
+ &(m_data->offset), sizeof(m_data->offset)) != sizeof(m_data->offset))
return -1;
}
+
return 0;
}
-static uint64_t get_cluster_offset(BlockDriverState *bs,
+static uint64_t get_cluster_offset(BlockDriverState *bs, VmdkMetaData *m_data,
uint64_t offset, int allocate)
{
BDRVVmdkState *s = bs->opaque;
unsigned int l1_index, l2_offset, l2_index;
int min_index, i, j;
- uint32_t min_count, *l2_table, tmp;
+ uint32_t min_count, *l2_table, tmp = 0;
uint64_t cluster_offset;
-
+ int status;
+
+ if (m_data)
+ m_data->valid = 0;
+
l1_index = (offset >> 9) / s->l1_entry_sectors;
if (l1_index >= s->l1_size)
return 0;
@@ -504,32 +562,45 @@
found:
l2_index = ((offset >> 9) / s->cluster_sectors) % s->l2_size;
cluster_offset = le32_to_cpu(l2_table[l2_index]);
+
if (!cluster_offset) {
struct stat file_buf;
if (!allocate)
return 0;
- stat(s->hd->filename, &file_buf);
- cluster_offset = file_buf.st_size;
- bdrv_truncate(s->hd, cluster_offset + (s->cluster_sectors << 9));
+ // Avoid the L2 tables update for the images that have snapshots.
+ if (!s->is_parent) {
+ status = stat(s->hd->filename, &file_buf);
+ if (status == -1) {
+ fprintf(stderr, "(VMDK) Fail file stat: filename =%s size=0x%lx errno=%s\n",
+ s->hd->filename, (uint64_t)file_buf.st_size, strerror(errno));
+ return 0;
+ }
+ cluster_offset = file_buf.st_size;
+ bdrv_truncate(s->hd, cluster_offset + (s->cluster_sectors << 9));
- cluster_offset >>= 9;
- /* update L2 table */
- tmp = cpu_to_le32(cluster_offset);
- l2_table[l2_index] = tmp;
- if (bdrv_pwrite(s->hd, ((int64_t)l2_offset * 512) + (l2_index * sizeof(tmp)),
- &tmp, sizeof(tmp)) != sizeof(tmp))
- return 0;
- /* update backup L2 table */
- if (s->l1_backup_table_offset != 0) {
- l2_offset = s->l1_backup_table[l1_index];
- if (bdrv_pwrite(s->hd, ((int64_t)l2_offset * 512) + (l2_index * sizeof(tmp)),
- &tmp, sizeof(tmp)) != sizeof(tmp))
- return 0;
+ cluster_offset >>= 9;
+ tmp = cpu_to_le32(cluster_offset);
+ l2_table[l2_index] = tmp;
+ // Save the active image state
+ activeBDRV.cluster_offset = cluster_offset;
+ activeBDRV.hd = bs;
}
-
+ /* First of all we write grain itself, to avoid race condition
+ * that may to corrupt the image.
+ * This problem may occur because of insufficient space on host disk
+ * or inappropriate VM shutdown.
+ */
if (get_whole_cluster(bs, cluster_offset, offset, allocate) == -1)
return 0;
+
+ if (m_data) {
+ m_data->offset = tmp;
+ m_data->l1_index = l1_index;
+ m_data->l2_index = l2_index;
+ m_data->l2_offset = l2_offset;
+ m_data->valid = 1;
+ }
}
cluster_offset <<= 9;
return cluster_offset;
@@ -542,7 +613,7 @@
int index_in_cluster, n;
uint64_t cluster_offset;
- cluster_offset = get_cluster_offset(bs, sector_num << 9, 0);
+ cluster_offset = get_cluster_offset(bs, NULL, sector_num << 9, 0);
index_in_cluster = sector_num % s->cluster_sectors;
n = s->cluster_sectors - index_in_cluster;
if (n > nb_sectors)
@@ -559,7 +630,7 @@
uint64_t cluster_offset;
while (nb_sectors > 0) {
- cluster_offset = get_cluster_offset(bs, sector_num << 9, 0);
+ cluster_offset = get_cluster_offset(bs, NULL, sector_num << 9, 0);
index_in_cluster = sector_num % s->cluster_sectors;
n = s->cluster_sectors - index_in_cluster;
if (n > nb_sectors)
@@ -590,20 +661,34 @@
const uint8_t *buf, int nb_sectors)
{
BDRVVmdkState *s = bs->opaque;
+ VmdkMetaData m_data;
int index_in_cluster, n;
uint64_t cluster_offset;
static int cid_update = 0;
+ if (sector_num > bs->total_sectors) {
+ fprintf(stderr,
+ "(VMDK) Wrong offset: sector_num=0x%lx total_sectors=0x%lx\n",
+ sector_num, bs->total_sectors);
+ return -1;
+ }
+
while (nb_sectors > 0) {
index_in_cluster = sector_num & (s->cluster_sectors - 1);
n = s->cluster_sectors - index_in_cluster;
if (n > nb_sectors)
n = nb_sectors;
- cluster_offset = get_cluster_offset(bs, sector_num << 9, 1);
+ cluster_offset = get_cluster_offset(bs, &m_data, sector_num << 9, 1);
if (!cluster_offset)
return -1;
+
if (bdrv_pwrite(s->hd, cluster_offset + index_in_cluster * 512, buf, n * 512) != n * 512)
return -1;
+ if (m_data.valid) {
+ /* update L2 tables */
+ if (vmdk_L2update(bs, &m_data) == -1)
+ return -1;
+ }
nb_sectors -= n;
sector_num += n;
buf += n * 512;
Modified: trunk/src/host/qemu-neo1973/configure
===================================================================
--- trunk/src/host/qemu-neo1973/configure 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/configure 2007-07-02 20:43:42 UTC (rev 2356)
@@ -113,6 +113,12 @@
MINGW32*)
mingw32="yes"
;;
+GNU/kFreeBSD)
+oss="yes"
+if [ "$cpu" = "i386" -o "$cpu" = "x86_64" ] ; then
+ kqemu="yes"
+fi
+;;
FreeBSD)
bsd="yes"
oss="yes"
Modified: trunk/src/host/qemu-neo1973/cpu-defs.h
===================================================================
--- trunk/src/host/qemu-neo1973/cpu-defs.h 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/cpu-defs.h 2007-07-02 20:43:42 UTC (rev 2356)
@@ -141,7 +141,7 @@
\
struct { \
target_ulong vaddr; \
- int is_ram; \
+ target_phys_addr_t addend; \
} watchpoint[MAX_WATCHPOINTS]; \
int nb_watchpoints; \
int watchpoint_hit; \
Modified: trunk/src/host/qemu-neo1973/dyngen.h
===================================================================
--- trunk/src/host/qemu-neo1973/dyngen.h 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/dyngen.h 2007-07-02 20:43:42 UTC (rev 2356)
@@ -392,7 +392,8 @@
0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, /* nop 0; brl IP */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0
};
- uint8_t *gen_code_ptr = *gen_code_pp, *plt_start, *got_start, *vp;
+ uint8_t *gen_code_ptr = *gen_code_pp, *plt_start, *got_start;
+ uint64_t *vp;
struct ia64_fixup *fixup;
unsigned int offset = 0;
struct fdesc {
@@ -429,12 +430,12 @@
/* First, create the GOT: */
for (fixup = ltoff_fixes; fixup; fixup = fixup->next) {
/* first check if we already have this value in the GOT: */
- for (vp = got_start; vp < gen_code_ptr; ++vp)
- if (*(uint64_t *) vp == fixup->value)
+ for (vp = (uint64_t *) got_start; vp < (uint64_t *) gen_code_ptr; ++vp)
+ if (*vp == fixup->value)
break;
- if (vp == gen_code_ptr) {
+ if (vp == (uint64_t *) gen_code_ptr) {
/* Nope, we need to put the value in the GOT: */
- *(uint64_t *) vp = fixup->value;
+ *vp = fixup->value;
gen_code_ptr += 8;
}
ia64_imm22(fixup->addr, (long) vp - gp);
Modified: trunk/src/host/qemu-neo1973/exec-all.h
===================================================================
--- trunk/src/host/qemu-neo1973/exec-all.h 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/exec-all.h 2007-07-02 20:43:42 UTC (rev 2356)
@@ -346,8 +346,8 @@
cache flushing, but slower because of indirect jump) */
#define GOTO_TB(opname, tbparam, n)\
do {\
- static void __attribute__((unused)) *dummy ## n = &&dummy_label ## n;\
- static void __attribute__((unused)) *__op_label ## n \
+ static void __attribute__((used)) *dummy ## n = &&dummy_label ## n;\
+ static void __attribute__((used)) *__op_label ## n \
__asm__(ASM_OP_LABEL_NAME(n, opname)) = &&label ## n;\
goto *(void *)(((TranslationBlock *)tbparam)->tb_next[n]);\
label ## n: ;\
Modified: trunk/src/host/qemu-neo1973/exec.c
===================================================================
--- trunk/src/host/qemu-neo1973/exec.c 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/exec.c 2007-07-02 20:43:42 UTC (rev 2356)
@@ -152,6 +152,7 @@
char *logfilename = "/tmp/qemu.log";
FILE *logfile;
int loglevel;
+static int log_append = 0;
/* statistics */
static int tlb_flush_count;
@@ -1160,7 +1161,7 @@
{
loglevel = log_flags;
if (loglevel && !logfile) {
- logfile = fopen(logfilename, "w");
+ logfile = fopen(logfilename, log_append ? "a" : "w");
if (!logfile) {
perror(logfilename);
_exit(1);
@@ -1174,12 +1175,22 @@
#else
setvbuf(logfile, NULL, _IOLBF, 0);
#endif
+ log_append = 1;
}
+ if (!loglevel && logfile) {
+ fclose(logfile);
+ logfile = NULL;
+ }
}
void cpu_set_log_filename(const char *filename)
{
logfilename = strdup(filename);
+ if (logfile) {
+ fclose(logfile);
+ logfile = NULL;
+ }
+ cpu_set_log(loglevel);
}
/* mask must never be zero, except for A20 change call */
@@ -1626,17 +1637,18 @@
for (i = 0; i < env->nb_watchpoints; i++) {
if (vaddr == (env->watchpoint[i].vaddr & TARGET_PAGE_MASK)) {
if (address & ~TARGET_PAGE_MASK) {
- env->watchpoint[i].is_ram = 0;
+ env->watchpoint[i].addend = 0;
address = vaddr | io_mem_watch;
} else {
- env->watchpoint[i].is_ram = 1;
+ env->watchpoint[i].addend = pd - paddr +
+ (unsigned long) phys_ram_base;
/* TODO: Figure out how to make read watchpoints coexist
with code. */
pd = (pd & TARGET_PAGE_MASK) | io_mem_watch | IO_MEM_ROMD;
}
}
}
-
+
index = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
addend -= vaddr;
te = &env->tlb_table[is_user][index];
@@ -2178,7 +2190,7 @@
/* Generate a debug exception if a watchpoint has been hit.
Returns the real physical address of the access. addr will be a host
- address in the is_ram case. */
+ address in case of a RAM location. */
static target_ulong check_watchpoint(target_phys_addr_t addr)
{
CPUState *env = cpu_single_env;
@@ -2190,8 +2202,7 @@
for (i = 0; i < env->nb_watchpoints; i++) {
watch = env->watchpoint[i].vaddr;
if (((env->mem_write_vaddr ^ watch) & TARGET_PAGE_MASK) == 0) {
- if (env->watchpoint[i].is_ram)
- retaddr = addr - (unsigned long)phys_ram_base;
+ retaddr = addr - env->watchpoint[i].addend;
if (((addr ^ watch) & ~TARGET_PAGE_MASK) == 0) {
cpu_single_env->watchpoint_hit = i + 1;
cpu_interrupt(cpu_single_env, CPU_INTERRUPT_DEBUG);
Modified: trunk/src/host/qemu-neo1973/hw/ads7846.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/ads7846.c 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/hw/ads7846.c 2007-07-02 20:43:42 UTC (rev 2356)
@@ -30,10 +30,10 @@
#define CB_A2 (1 << 6)
#define CB_START (1 << 7)
-#define X_AXIS_DMAX 3680
-#define X_AXIS_MIN 150
-#define Y_AXIS_DMAX 3640
-#define Y_AXIS_MIN 190
+#define X_AXIS_DMAX 3470
+#define X_AXIS_MIN 290
+#define Y_AXIS_DMAX 3450
+#define Y_AXIS_MIN 200
#define ADS_VBAT 2000
#define ADS_VAUX 2000
@@ -95,10 +95,11 @@
struct ads7846_state_s *s = opaque;
if (buttons_state) {
- s->input[1] = ADS_YPOS(x, y);
+ x = 0x7fff - x;
+ s->input[1] = ADS_XPOS(x, y);
s->input[3] = ADS_Z1POS(x, y);
s->input[4] = ADS_Z2POS(x, y);
- s->input[5] = ADS_XPOS(x, y);
+ s->input[5] = ADS_YPOS(x, y);
}
if (s->pressure == !buttons_state) {
Modified: trunk/src/host/qemu-neo1973/hw/eepro100.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/eepro100.c 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/hw/eepro100.c 2007-07-02 20:43:42 UTC (rev 2356)
@@ -1571,10 +1571,9 @@
static int nic_load(QEMUFile * f, void *opaque, int version_id)
{
EEPRO100State *s = (EEPRO100State *) opaque;
+ int i;
int ret;
- missing("NIC load");
-
if (version_id > 3)
return -EINVAL;
@@ -1608,15 +1607,62 @@
qemu_get_buffer(f, s->mult, 8);
qemu_get_buffer(f, s->mem, sizeof(s->mem));
+ /* Restore all members of struct between scv_stat and mem */
+ qemu_get_8s(f, &s->scb_stat);
+ qemu_get_8s(f, &s->int_stat);
+ for (i = 0; i < 3; i++)
+ qemu_get_be32s(f, &s->region[i]);
+ qemu_get_buffer(f, s->macaddr, 6);
+ for (i = 0; i < 19; i++)
+ qemu_get_be32s(f, &s->statcounter[i]);
+ for (i = 0; i < 32; i++)
+ qemu_get_be16s(f, &s->mdimem[i]);
+ /* The eeprom should be saved and restored by its own routines */
+ qemu_get_be32s(f, &s->device);
+ qemu_get_be32s(f, &s->pointer);
+ qemu_get_be32s(f, &s->cu_base);
+ qemu_get_be32s(f, &s->cu_offset);
+ qemu_get_be32s(f, &s->ru_base);
+ qemu_get_be32s(f, &s->ru_offset);
+ qemu_get_be32s(f, &s->statsaddr);
+ /* Restore epro100_stats_t statistics */
+ qemu_get_be32s(f, &s->statistics.tx_good_frames);
+ qemu_get_be32s(f, &s->statistics.tx_max_collisions);
+ qemu_get_be32s(f, &s->statistics.tx_late_collisions);
+ qemu_get_be32s(f, &s->statistics.tx_underruns);
+ qemu_get_be32s(f, &s->statistics.tx_lost_crs);
+ qemu_get_be32s(f, &s->statistics.tx_deferred);
+ qemu_get_be32s(f, &s->statistics.tx_single_collisions);
+ qemu_get_be32s(f, &s->statistics.tx_multiple_collisions);
+ qemu_get_be32s(f, &s->statistics.tx_total_collisions);
+ qemu_get_be32s(f, &s->statistics.rx_good_frames);
+ qemu_get_be32s(f, &s->statistics.rx_crc_errors);
+ qemu_get_be32s(f, &s->statistics.rx_alignment_errors);
+ qemu_get_be32s(f, &s->statistics.rx_resource_errors);
+ qemu_get_be32s(f, &s->statistics.rx_overrun_errors);
+ qemu_get_be32s(f, &s->statistics.rx_cdt_errors);
+ qemu_get_be32s(f, &s->statistics.rx_short_frame_errors);
+ qemu_get_be32s(f, &s->statistics.fc_xmt_pause);
+ qemu_get_be32s(f, &s->statistics.fc_rcv_pause);
+ qemu_get_be32s(f, &s->statistics.fc_rcv_unsupported);
+ qemu_get_be16s(f, &s->statistics.xmt_tco_frames);
+ qemu_get_be16s(f, &s->statistics.rcv_tco_frames);
+ qemu_get_be32s(f, &s->statistics.complete);
+#if 0
+ qemu_get_be16s(f, &s->status);
+#endif
+
+ /* Configuration bytes. */
+ qemu_get_buffer(f, s->configuration, sizeof(s->configuration));
+
return 0;
}
static void nic_save(QEMUFile * f, void *opaque)
{
EEPRO100State *s = (EEPRO100State *) opaque;
+ int i;
- missing("NIC save");
-
if (s->pci_dev)
pci_device_save(s->pci_dev, f);
@@ -1639,6 +1685,54 @@
qemu_put_8s(f, &s->curpag);
qemu_put_buffer(f, s->mult, 8);
qemu_put_buffer(f, s->mem, sizeof(s->mem));
+
+ /* Save all members of struct between scv_stat and mem */
+ qemu_put_8s(f, &s->scb_stat);
+ qemu_put_8s(f, &s->int_stat);
+ for (i = 0; i < 3; i++)
+ qemu_put_be32s(f, &s->region[i]);
+ qemu_put_buffer(f, s->macaddr, 6);
+ for (i = 0; i < 19; i++)
+ qemu_put_be32s(f, &s->statcounter[i]);
+ for (i = 0; i < 32; i++)
+ qemu_put_be16s(f, &s->mdimem[i]);
+ /* The eeprom should be saved and restored by its own routines */
+ qemu_put_be32s(f, &s->device);
+ qemu_put_be32s(f, &s->pointer);
+ qemu_put_be32s(f, &s->cu_base);
+ qemu_put_be32s(f, &s->cu_offset);
+ qemu_put_be32s(f, &s->ru_base);
+ qemu_put_be32s(f, &s->ru_offset);
+ qemu_put_be32s(f, &s->statsaddr);
+ /* Save epro100_stats_t statistics */
+ qemu_put_be32s(f, &s->statistics.tx_good_frames);
+ qemu_put_be32s(f, &s->statistics.tx_max_collisions);
+ qemu_put_be32s(f, &s->statistics.tx_late_collisions);
+ qemu_put_be32s(f, &s->statistics.tx_underruns);
+ qemu_put_be32s(f, &s->statistics.tx_lost_crs);
+ qemu_put_be32s(f, &s->statistics.tx_deferred);
+ qemu_put_be32s(f, &s->statistics.tx_single_collisions);
+ qemu_put_be32s(f, &s->statistics.tx_multiple_collisions);
+ qemu_put_be32s(f, &s->statistics.tx_total_collisions);
+ qemu_put_be32s(f, &s->statistics.rx_good_frames);
+ qemu_put_be32s(f, &s->statistics.rx_crc_errors);
+ qemu_put_be32s(f, &s->statistics.rx_alignment_errors);
+ qemu_put_be32s(f, &s->statistics.rx_resource_errors);
+ qemu_put_be32s(f, &s->statistics.rx_overrun_errors);
+ qemu_put_be32s(f, &s->statistics.rx_cdt_errors);
+ qemu_put_be32s(f, &s->statistics.rx_short_frame_errors);
+ qemu_put_be32s(f, &s->statistics.fc_xmt_pause);
+ qemu_put_be32s(f, &s->statistics.fc_rcv_pause);
+ qemu_put_be32s(f, &s->statistics.fc_rcv_unsupported);
+ qemu_put_be16s(f, &s->statistics.xmt_tco_frames);
+ qemu_put_be16s(f, &s->statistics.rcv_tco_frames);
+ qemu_put_be32s(f, &s->statistics.complete);
+#if 0
+ qemu_put_be16s(f, &s->status);
+#endif
+
+ /* Configuration bytes. */
+ qemu_put_buffer(f, s->configuration, sizeof(s->configuration));
}
static void nic_init(PCIBus * bus, NICInfo * nd,
Modified: trunk/src/host/qemu-neo1973/hw/integratorcp.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/integratorcp.c 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/hw/integratorcp.c 2007-07-02 20:43:42 UTC (rev 2356)
@@ -490,6 +490,7 @@
cpu_pic[ARM_PIC_CPU_FIQ]);
icp_pic_init(0xca000000, pic[26], NULL);
icp_pit_init(0x13000000, pic, 5);
+ pl031_init(0x15000000, pic[8]);
pl011_init(0x16000000, pic[1], serial_hds[0]);
pl011_init(0x17000000, pic[2], serial_hds[1]);
icp_control_init(0xcb000000);
Modified: trunk/src/host/qemu-neo1973/hw/mips_malta.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/mips_malta.c 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/hw/mips_malta.c 2007-07-02 20:43:42 UTC (rev 2356)
@@ -42,7 +42,6 @@
#define ENVP_NB_ENTRIES 16
#define ENVP_ENTRY_SIZE 256
-extern int nographic;
extern FILE *logfile;
typedef struct {
@@ -67,18 +66,16 @@
int i;
MaltaFPGAState *s = opaque;
- if (!nographic) {
- for (i = 7 ; i >= 0 ; i--) {
- if (s->leds & (1 << i))
- leds_text[i] = '#';
- else
- leds_text[i] = ' ';
- }
- leds_text[8] = '\0';
-
- qemu_chr_printf(s->display, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", leds_text);
- qemu_chr_printf(s->display, "\n\n\n\n|\e[31m%-8.8s\e[00m|", s->display_text);
+ for (i = 7 ; i >= 0 ; i--) {
+ if (s->leds & (1 << i))
+ leds_text[i] = '#';
+ else
+ leds_text[i] = ' ';
}
+ leds_text[8] = '\0';
+
+ qemu_chr_printf(s->display, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", leds_text);
+ qemu_chr_printf(s->display, "\n\n\n\n|\e[31m%-8.8s\e[00m|", s->display_text);
}
/*
@@ -415,22 +412,20 @@
cpu_register_physical_memory(base, 0x900, malta);
cpu_register_physical_memory(base + 0xa00, 0x100000 - 0xa00, malta);
- if (!nographic) {
- s->display = qemu_chr_open("vc");
- qemu_chr_printf(s->display, "\e[HMalta LEDBAR\r\n");
- qemu_chr_printf(s->display, "+--------+\r\n");
- qemu_chr_printf(s->display, "+ +\r\n");
- qemu_chr_printf(s->display, "+--------+\r\n");
- qemu_chr_printf(s->display, "\n");
- qemu_chr_printf(s->display, "Malta ASCII\r\n");
- qemu_chr_printf(s->display, "+--------+\r\n");
- qemu_chr_printf(s->display, "+ +\r\n");
- qemu_chr_printf(s->display, "+--------+\r\n");
+ s->display = qemu_chr_open("vc");
+ qemu_chr_printf(s->display, "\e[HMalta LEDBAR\r\n");
+ qemu_chr_printf(s->display, "+--------+\r\n");
+ qemu_chr_printf(s->display, "+ +\r\n");
+ qemu_chr_printf(s->display, "+--------+\r\n");
+ qemu_chr_printf(s->display, "\n");
+ qemu_chr_printf(s->display, "Malta ASCII\r\n");
+ qemu_chr_printf(s->display, "+--------+\r\n");
+ qemu_chr_printf(s->display, "+ +\r\n");
+ qemu_chr_printf(s->display, "+--------+\r\n");
- uart_chr = qemu_chr_open("vc");
- qemu_chr_printf(uart_chr, "CBUS UART\r\n");
- s->uart = serial_mm_init(base + 0x900, 3, env->irq[2], uart_chr, 1);
- }
+ uart_chr = qemu_chr_open("vc");
+ qemu_chr_printf(uart_chr, "CBUS UART\r\n");
+ s->uart = serial_mm_init(base + 0x900, 3, env->irq[2], uart_chr, 1);
malta_fpga_reset(s);
qemu_register_reset(malta_fpga_reset, s);
Modified: trunk/src/host/qemu-neo1973/hw/mips_pica61.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/mips_pica61.c 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/hw/mips_pica61.c 2007-07-02 20:43:42 UTC (rev 2356)
@@ -151,11 +151,8 @@
serial_mm_init(serial_base[i], 0, i8259[serial_irq[i]], serial_hds[i], 1);
}
}
- for (i = 0; i < MAX_PARALLEL_PORTS; i++) {
- if (parallel_hds[i]) {
- /* FIXME: memory mapped! parallel_init(0x80008000, i8259[17], parallel_hds[i]); */
- }
- }
+ /* Parallel port */
+ if (parallel_hds[0]) parallel_mm_init(0x80008000, 0, i8259[1], parallel_hds[0]);
/* Sound card */
/* FIXME: missing Jazz sound, IRQ 18 */
@@ -171,6 +168,9 @@
* but let's do with what Qemu currenly emulates... */
isa_vga_mm_init(ds, phys_ram_base + ram_size, ram_size, vga_ram_size,
0x40000000, 0x60000000, 0);
+
+ /* LED indicator */
+ jazz_led_init(ds, 0x8000f000);
}
QEMUMachine mips_pica61_machine = {
Modified: trunk/src/host/qemu-neo1973/hw/ne2000.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/ne2000.c 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/hw/ne2000.c 2007-07-02 20:43:42 UTC (rev 2356)
@@ -224,7 +224,7 @@
{
NE2000State *s = opaque;
uint8_t *p;
- int total_len, next, avail, len, index, mcast_idx;
+ unsigned int total_len, next, avail, len, index, mcast_idx;
uint8_t buf1[60];
static const uint8_t broadcast_macaddr[6] =
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
@@ -293,7 +293,10 @@
/* write packet data */
while (size > 0) {
- avail = s->stop - index;
+ if (index <= s->stop)
+ avail = s->stop - index;
+ else
+ avail = 0;
len = size;
if (len > avail)
len = avail;
Modified: trunk/src/host/qemu-neo1973/hw/parallel.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/parallel.c 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/hw/parallel.c 2007-07-02 20:43:42 UTC (rev 2356)
@@ -71,6 +71,9 @@
int hw_driver;
int epp_timeout;
uint32_t last_read_offset; /* For debugging */
+ /* Memory-mapped interface */
+ target_phys_addr_t base;
+ int it_shift;
};
static void parallel_update_irq(ParallelState *s)
@@ -400,15 +403,8 @@
return ret;
}
-/* If fd is zero, it means that the parallel device uses the console */
-ParallelState *parallel_init(int base, qemu_irq irq, CharDriverState *chr)
+static void parallel_reset(ParallelState *s, qemu_irq irq, CharDriverState *chr)
{
- ParallelState *s;
- uint8_t dummy;
-
- s = qemu_mallocz(sizeof(ParallelState));
- if (!s)
- return NULL;
s->datar = ~0;
s->dataw = ~0;
s->status = PARA_STS_BUSY;
@@ -423,7 +419,19 @@
s->hw_driver = 0;
s->epp_timeout = 0;
s->last_read_offset = ~0U;
+}
+/* If fd is zero, it means that the parallel device uses the console */
+ParallelState *parallel_init(int base, qemu_irq irq, CharDriverState *chr)
+{
+ ParallelState *s;
+ uint8_t dummy;
+
+ s = qemu_mallocz(sizeof(ParallelState));
+ if (!s)
+ return NULL;
+ parallel_reset(s, irq, chr);
+
if (qemu_chr_ioctl(chr, CHR_IOCTL_PP_READ_STATUS, &dummy) == 0) {
s->hw_driver = 1;
s->status = dummy;
@@ -445,3 +453,79 @@
}
return s;
}
+
+/* Memory mapped interface */
+uint32_t parallel_mm_readb (void *opaque, target_phys_addr_t addr)
+{
+ ParallelState *s = opaque;
+
+ return parallel_ioport_read_sw(s, (addr - s->base) >> s->it_shift) & 0xFF;
+}
+
+void parallel_mm_writeb (void *opaque,
+ target_phys_addr_t addr, uint32_t value)
+{
+ ParallelState *s = opaque;
+
+ parallel_ioport_write_sw(s, (addr - s->base) >> s->it_shift, value & 0xFF);
+}
+
+uint32_t parallel_mm_readw (void *opaque, target_phys_addr_t addr)
+{
+ ParallelState *s = opaque;
+
+ return parallel_ioport_read_sw(s, (addr - s->base) >> s->it_shift) & 0xFFFF;
+}
+
+void parallel_mm_writew (void *opaque,
+ target_phys_addr_t addr, uint32_t value)
+{
+ ParallelState *s = opaque;
+
+ parallel_ioport_write_sw(s, (addr - s->base) >> s->it_shift, value & 0xFFFF);
+}
+
+uint32_t parallel_mm_readl (void *opaque, target_phys_addr_t addr)
+{
+ ParallelState *s = opaque;
+
+ return parallel_ioport_read_sw(s, (addr - s->base) >> s->it_shift);
+}
+
+void parallel_mm_writel (void *opaque,
+ target_phys_addr_t addr, uint32_t value)
+{
+ ParallelState *s = opaque;
+
+ parallel_ioport_write_sw(s, (addr - s->base) >> s->it_shift, value);
+}
+
+static CPUReadMemoryFunc *parallel_mm_read_sw[] = {
+ ¶llel_mm_readb,
+ ¶llel_mm_readw,
+ ¶llel_mm_readl,
+};
+
+static CPUWriteMemoryFunc *parallel_mm_write_sw[] = {
+ ¶llel_mm_writeb,
+ ¶llel_mm_writew,
+ ¶llel_mm_writel,
+};
+
+/* If fd is zero, it means that the parallel device uses the console */
+ParallelState *parallel_mm_init(target_phys_addr_t base, int it_shift, qemu_irq irq, CharDriverState *chr)
+{
+ ParallelState *s;
+ int io_sw;
+
+ s = qemu_mallocz(sizeof(ParallelState));
+ if (!s)
+ return NULL;
+ parallel_reset(s, irq, chr);
+ s->base = base;
+ s->it_shift = it_shift;
+
+ io_sw = cpu_register_io_memory(0, parallel_mm_read_sw, parallel_mm_write_sw, s);
+ cpu_register_physical_memory(base, 8 << it_shift, io_sw);
+ return s;
+}
Modified: trunk/src/host/qemu-neo1973/hw/pcnet.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pcnet.c 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/hw/pcnet.c 2007-07-02 20:43:42 UTC (rev 2356)
@@ -2011,16 +2011,39 @@
#if defined (TARGET_SPARC) && !defined(TARGET_SPARC64) // Avoid compile failure
+static void lance_mem_writew(void *opaque, target_phys_addr_t addr,
+ uint32_t val)
+{
+#ifdef PCNET_DEBUG_IO
+ printf("lance_mem_writew addr=" TARGET_FMT_plx " val=0x%04x\n", addr,
+ val & 0xffff);
+#endif
+ pcnet_ioport_writew(opaque, addr & 7, val & 0xffff);
+}
+
+static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr)
+{
+ uint32_t val;
+
+ val = pcnet_ioport_readw(opaque, addr & 7);
+#ifdef PCNET_DEBUG_IO
+ printf("pcnet_mmio_readw addr=" TARGET_FMT_plx " val = 0x%04x\n", addr,
+ val & 0xffff);
+#endif
+
+ return val & 0xffff;
+}
+
static CPUReadMemoryFunc *lance_mem_read[3] = {
- (CPUReadMemoryFunc *)&pcnet_ioport_readw,
- (CPUReadMemoryFunc *)&pcnet_ioport_readw,
- (CPUReadMemoryFunc *)&pcnet_ioport_readw,
+ lance_mem_readw,
+ lance_mem_readw,
+ lance_mem_readw,
};
static CPUWriteMemoryFunc *lance_mem_write[3] = {
- (CPUWriteMemoryFunc *)&pcnet_ioport_writew,
- (CPUWriteMemoryFunc *)&pcnet_ioport_writew,
- (CPUWriteMemoryFunc *)&pcnet_ioport_writew,
+ lance_mem_writew,
+ lance_mem_writew,
+ lance_mem_writew,
};
void lance_init(NICInfo *nd, target_phys_addr_t leaddr, void *dma_opaque,
Modified: trunk/src/host/qemu-neo1973/hw/pl110.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pl110.c 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/hw/pl110.c 2007-07-02 20:43:42 UTC (rev 2356)
@@ -302,8 +302,12 @@
case 5: /* LCDLPBASE */
return s->lpbase;
case 6: /* LCDIMSC */
+ if (s->versatile)
+ return s->cr;
return s->int_mask;
case 7: /* LCDControl */
+ if (s->versatile)
+ return s->int_mask;
return s->cr;
case 8: /* LCDRIS */
return s->int_status;
Modified: trunk/src/host/qemu-neo1973/hw/realview.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/realview.c 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/hw/realview.c 2007-07-02 20:43:42 UTC (rev 2356)
@@ -57,6 +57,8 @@
pl181_init(0x10005000, sd_bdrv, pic[17], pic[18]);
+ pl031_init(0x10017000, pic[10]);
+
pci_bus = pci_vpb_init(pic, 48, 1);
if (usb_enabled) {
usb_ohci_init_pci(pci_bus, 3, -1);
@@ -102,7 +104,7 @@
/* 0x10014000 GPIO 1. */
/* 0x10015000 GPIO 2. */
/* 0x10016000 Reserved. */
- /* 0x10017000 RTC. */
+ /* 0x10017000 RTC. */
/* 0x10018000 DMC. */
/* 0x10019000 PCI controller config. */
/* 0x10020000 CLCD. */
Modified: trunk/src/host/qemu-neo1973/hw/slavio_serial.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/slavio_serial.c 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/hw/slavio_serial.c 2007-07-02 20:43:42 UTC (rev 2356)
@@ -354,7 +354,7 @@
static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
{
- SerialState *ser = opaque;
+ SerialState *serial = opaque;
ChannelState *s;
uint32_t saddr;
int newreg, channel;
@@ -362,7 +362,7 @@
val &= 0xff;
saddr = (addr & 3) >> 1;
channel = (addr & SERIAL_MAXADDR) >> 2;
- s = &ser->chn[channel];
+ s = &serial->chn[channel];
switch (saddr) {
case 0:
SER_DPRINTF("Write channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg, val & 0xff);
@@ -407,13 +407,13 @@
default:
break;
case 0x40:
- slavio_serial_reset_chn(&ser->chn[1]);
+ slavio_serial_reset_chn(&serial->chn[1]);
return;
case 0x80:
- slavio_serial_reset_chn(&ser->chn[0]);
+ slavio_serial_reset_chn(&serial->chn[0]);
return;
case 0xc0:
- slavio_serial_reset(ser);
+ slavio_serial_reset(serial);
return;
}
break;
@@ -446,7 +446,7 @@
static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr)
{
- SerialState *ser = opaque;
+ SerialState *serial = opaque;
ChannelState *s;
uint32_t saddr;
uint32_t ret;
@@ -454,7 +454,7 @@
saddr = (addr & 3) >> 1;
channel = (addr & SERIAL_MAXADDR) >> 2;
- s = &ser->chn[channel];
+ s = &serial->chn[channel];
switch (saddr) {
case 0:
SER_DPRINTF("Read channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg, s->rregs[s->reg]);
Modified: trunk/src/host/qemu-neo1973/hw/spitz.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/spitz.c 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/hw/spitz.c 2007-07-02 20:43:42 UTC (rev 2356)
@@ -919,8 +919,8 @@
/* Wm8750 and Max7310 on I2C */
#define AKITA_MAX_ADDR 0x18
-#define SPITZ_WM_ADDRL 0x1a
-#define SPITZ_WM_ADDRH 0x1b
+#define SPITZ_WM_ADDRL 0x1b
+#define SPITZ_WM_ADDRH 0x1a
#define SPITZ_GPIO_WM 5
Modified: trunk/src/host/qemu-neo1973/hw/sun4m.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/sun4m.c 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/hw/sun4m.c 2007-07-02 20:43:42 UTC (rev 2356)
@@ -154,8 +154,6 @@
m48t59_write(nvram, start + 1, sum & 0xff);
}
-static m48t59_t *nvram;
-
extern int nographic;
static void nvram_init(m48t59_t *nvram, uint8_t *macaddr, const char *cmdline,
@@ -292,13 +290,13 @@
env->halted = 1;
}
-static void sun4m_hw_init(const struct hwdef *hwdef, int ram_size,
- DisplayState *ds, const char *cpu_model)
+static void *sun4m_hw_init(const struct hwdef *hwdef, int RAM_size,
+ DisplayState *ds, const char *cpu_model)
{
CPUState *env, *envs[MAX_CPUS];
unsigned int i;
- void *iommu, *espdma, *ledma, *main_esp;
+ void *iommu, *espdma, *ledma, *main_esp, *nvram;
const sparc_def_t *def;
qemu_irq *cpu_irqs[MAX_CPUS], *slavio_irq, *slavio_cpu_irq,
*espdma_irq, *ledma_irq;
@@ -328,7 +326,7 @@
cpu_irqs[i] = qemu_allocate_irqs(dummy_cpu_set_irq, NULL, MAX_PILS);
/* allocate RAM */
- cpu_register_physical_memory(0, ram_size, 0);
+ cpu_register_physical_memory(0, RAM_size, 0);
iommu = iommu_init(hwdef->iommu_base);
slavio_intctl = slavio_intctl_init(hwdef->intctl_base,
@@ -347,7 +345,7 @@
fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
exit (1);
}
- tcx_init(ds, hwdef->tcx_base, phys_ram_base + ram_size, ram_size,
+ tcx_init(ds, hwdef->tcx_base, phys_ram_base + RAM_size, RAM_size,
hwdef->vram_size, graphic_width, graphic_height, graphic_depth);
if (nd_table[0].model == NULL
@@ -388,13 +386,16 @@
slavio_irq[hwdef->me_irq]);
if (hwdef->cs_base != (target_phys_addr_t)-1)
cs_init(hwdef->cs_base, hwdef->cs_irq, slavio_intctl);
+
+ return nvram;
}
-static void sun4m_load_kernel(long vram_size, int ram_size, int boot_device,
+static void sun4m_load_kernel(long vram_size, int RAM_size, int boot_device,
const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename,
- int machine_id)
+ int machine_id,
+ void *nvram)
{
int ret, linux_boot;
char buf[1024];
@@ -403,7 +404,7 @@
linux_boot = (kernel_filename != NULL);
- prom_offset = ram_size + vram_size;
+ prom_offset = RAM_size + vram_size;
cpu_register_physical_memory(PROM_ADDR,
(PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK,
prom_offset | IO_MEM_ROM);
@@ -451,7 +452,7 @@
}
}
nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline,
- boot_device, ram_size, kernel_size, graphic_width,
+ boot_device, RAM_size, kernel_size, graphic_width,
graphic_height, graphic_depth, machine_id);
}
@@ -524,46 +525,48 @@
},
};
-static void sun4m_common_init(int ram_size, int boot_device, DisplayState *ds,
+static void sun4m_common_init(int RAM_size, int boot_device, DisplayState *ds,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model,
unsigned int machine, int max_ram)
{
- if ((unsigned int)ram_size > (unsigned int)max_ram) {
+ void *nvram;
+
+ if ((unsigned int)RAM_size > (unsigned int)max_ram) {
fprintf(stderr, "qemu: Too much memory for this machine: %d, maximum %d\n",
- (unsigned int)ram_size / (1024 * 1024),
+ (unsigned int)RAM_size / (1024 * 1024),
(unsigned int)max_ram / (1024 * 1024));
exit(1);
}
- sun4m_hw_init(&hwdefs[machine], ram_size, ds, cpu_model);
+ nvram = sun4m_hw_init(&hwdefs[machine], RAM_size, ds, cpu_model);
- sun4m_load_kernel(hwdefs[machine].vram_size, ram_size, boot_device,
+ sun4m_load_kernel(hwdefs[machine].vram_size, RAM_size, boot_device,
kernel_filename, kernel_cmdline, initrd_filename,
- hwdefs[machine].machine_id);
+ hwdefs[machine].machine_id, nvram);
}
/* SPARCstation 5 hardware initialisation */
-static void ss5_init(int ram_size, int vga_ram_size, int boot_device,
+static void ss5_init(int RAM_size, int vga_ram_size, int boot_device,
DisplayState *ds, const char **fd_filename, int snapshot,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
{
if (cpu_model == NULL)
cpu_model = "Fujitsu MB86904";
- sun4m_common_init(ram_size, boot_device, ds, kernel_filename,
+ sun4m_common_init(RAM_size, boot_device, ds, kernel_filename,
kernel_cmdline, initrd_filename, cpu_model,
0, 0x10000000);
}
/* SPARCstation 10 hardware initialisation */
-static void ss10_init(int ram_size, int vga_ram_size, int boot_device,
+static void ss10_init(int RAM_size, int vga_ram_size, int boot_device,
DisplayState *ds, const char **fd_filename, int snapshot,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
{
if (cpu_model == NULL)
cpu_model = "TI SuperSparc II";
- sun4m_common_init(ram_size, boot_device, ds, kernel_filename,
+ sun4m_common_init(RAM_size, boot_device, ds, kernel_filename,
kernel_cmdline, initrd_filename, cpu_model,
1, PROM_ADDR); // XXX prom overlap, actually first 4GB ok
}
Modified: trunk/src/host/qemu-neo1973/hw/tcx.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/tcx.c 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/hw/tcx.c 2007-07-02 20:43:42 UTC (rev 2356)
@@ -180,7 +180,7 @@
ram_addr_t page, page_min, page_max;
int y, y_start, dd, ds;
uint8_t *d, *s;
- void (*f)(TCXState *s1, uint8_t *d, const uint8_t *s, int width);
+ void (*f)(TCXState *s1, uint8_t *dst, const uint8_t *src, int width);
if (ts->ds->depth == 0)
return;
Modified: trunk/src/host/qemu-neo1973/hw/versatilepb.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/versatilepb.c 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/hw/versatilepb.c 2007-07-02 20:43:42 UTC (rev 2356)
@@ -223,6 +223,9 @@
pl181_init(0x1000b000, NULL, sic, 23, 2);
#endif
+ /* Add PL031 Real Time Clock. */
+ pl031_init(0x101e8000,pic[10]);
+
/* Memory map for Versatile/PB: */
/* 0x10000000 System registers. */
/* 0x10001000 PCI controller config registers. */
Modified: trunk/src/host/qemu-neo1973/linux-user/elfload.c
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/elfload.c 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/linux-user/elfload.c 2007-07-02 20:43:42 UTC (rev 2356)
@@ -325,7 +325,7 @@
{
/* Check other registers XXXXX */
regs->pc = infop->entry;
- regs->regs[15] = infop->start_stack - 16 * 4;
+ regs->regs[15] = infop->start_stack;
}
#define USE_ELF_CORE_DUMP
Modified: trunk/src/host/qemu-neo1973/linux-user/i386/syscall_nr.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/i386/syscall_nr.h 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/linux-user/i386/syscall_nr.h 2007-07-02 20:43:42 UTC (rev 2356)
@@ -271,4 +271,7 @@
#define TARGET_NR_clock_getres (TARGET_NR_timer_create+7)
#define TARGET_NR_clock_nanosleep (TARGET_NR_timer_create+8)
+#define TARGET_NR_tgkill 270
#define TARGET_NR_utimes 271
+
+#define TARGET_NR_set_robust_list 311
Modified: trunk/src/host/qemu-neo1973/linux-user/main.c
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/main.c 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/linux-user/main.c 2007-07-02 20:43:42 UTC (rev 2356)
@@ -1666,11 +1666,12 @@
"usage: qemu-" TARGET_ARCH " [-h] [-g] [-d opts] [-L path] [-s size] [-cpu model] program [arguments...]\n"
"Linux CPU emulator (compiled for %s emulation)\n"
"\n"
- "-h print this help\n"
- "-g port wait gdb connection to port\n"
- "-L path set the elf interpreter prefix (default=%s)\n"
- "-s size set the stack size in bytes (default=%ld)\n"
- "-cpu model select CPU (-cpu ? for list)\n"
+ "-h print this help\n"
+ "-g port wait gdb connection to port\n"
+ "-L path set the elf interpreter prefix (default=%s)\n"
+ "-s size set the stack size in bytes (default=%ld)\n"
+ "-cpu model select CPU (-cpu ? for list)\n"
+ "-drop-ld-preload drop LD_PRELOAD for target process\n"
"\n"
"debug options:\n"
#ifdef USE_CODE_COPY
@@ -1702,7 +1703,9 @@
int optind;
const char *r;
int gdbstub_port = 0;
-
+ int drop_ld_preload = 0, environ_count = 0;
+ char **target_environ, **wrk, **dst;
+
if (argc <= 1)
usage();
@@ -1774,6 +1777,8 @@
#endif
_exit(1);
}
+ } else if (!strcmp(r, "drop-ld-preload")) {
+ drop_ld_preload = 1;
} else
#ifdef USE_CODE_COPY
if (!strcmp(r, "no-code-copy")) {
@@ -1802,11 +1807,31 @@
env = cpu_init();
global_env = env;
- if (loader_exec(filename, argv+optind, environ, regs, info) != 0) {
- printf("Error loading %s\n", filename);
- _exit(1);
+ wrk = environ;
+ while (*(wrk++))
+ environ_count++;
+
+ target_environ = malloc((environ_count + 1) * sizeof(char *));
+ if (!target_environ)
+ abort();
+ for (wrk = environ, dst = target_environ; *wrk; wrk++) {
+ if (drop_ld_preload && !strncmp(*wrk, "LD_PRELOAD=", 11))
+ continue;
+ *(dst++) = strdup(*wrk);
}
+ *dst = NULL; /* NULL terminate target_environ */
+
+ if (loader_exec(filename, argv+optind, target_environ, regs, info) != 0) {
+ printf("Error loading %s\n", filename);
+ _exit(1);
+ }
+
+ for (wrk = target_environ; *wrk; wrk++) {
+ free(*wrk);
+ }
+ free(target_environ);
+
if (loglevel) {
page_dump(logfile);
@@ -1908,6 +1933,8 @@
cpu_x86_load_seg(env, R_FS, __USER_DS);
cpu_x86_load_seg(env, R_GS, __USER_DS);
+ /* This hack makes Wine work... */
+ env->segs[R_FS].selector = 0;
#elif defined(TARGET_ARM)
{
int i;
Modified: trunk/src/host/qemu-neo1973/linux-user/syscall.c
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/syscall.c 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/linux-user/syscall.c 2007-07-02 20:43:42 UTC (rev 2356)
@@ -144,6 +144,7 @@
#define __NR_sys_getdents64 __NR_getdents64
#define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
#define __NR_sys_syslog __NR_syslog
+#define __NR_sys_tgkill __NR_tgkill
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
#define __NR__llseek __NR_lseek
@@ -164,6 +165,7 @@
loff_t *, res, uint, wh);
_syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
_syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
+_syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
#ifdef __NR_exit_group
_syscall1(int,exit_group,int,error_code)
#endif
@@ -4604,10 +4606,21 @@
break;
#endif
+#ifdef TARGET_NR_tgkill
+ case TARGET_NR_tgkill:
+ ret = get_errno(sys_tgkill((int)arg1, (int)arg2, (int)arg3));
+ break;
+#endif
+
+#ifdef TARGET_NR_set_robust_list
+ case TARGET_NR_set_robust_list:
+ goto unimplemented_nowarn;
+#endif
+
default:
unimplemented:
gemu_log("qemu: Unsupported syscall: %d\n", num);
-#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname)
+#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
unimplemented_nowarn:
#endif
ret = -ENOSYS;
Modified: trunk/src/host/qemu-neo1973/linux-user/syscall_defs.h
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/syscall_defs.h 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/linux-user/syscall_defs.h 2007-07-02 20:43:42 UTC (rev 2356)
@@ -869,7 +869,7 @@
#define TARGET_MAP_NORESERVE 0x4000 /* don't check for reservations */
#endif
-#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SH4)
+#if defined(TARGET_I386) || defined(TARGET_ARM)
struct target_stat {
unsigned short st_dev;
unsigned short __pad1;
@@ -1242,6 +1242,65 @@
target_long __unused[3];
};
+#elif defined(TARGET_SH4)
+
+struct target_stat {
+ target_ulong st_dev;
+ target_ulong st_ino;
+ unsigned short st_mode;
+ unsigned short st_nlink;
+ unsigned short st_uid;
+ unsigned short st_gid;
+ target_ulong st_rdev;
+ target_ulong st_size;
+ target_ulong st_blksize;
+ target_ulong st_blocks;
+ target_ulong target_st_atime;
+ target_ulong target_st_atime_nsec;
+ target_ulong target_st_mtime;
+ target_ulong target_st_mtime_nsec;
+ target_ulong target_st_ctime;
+ target_ulong target_st_ctime_nsec;
+ target_ulong __unused4;
+ target_ulong __unused5;
+};
+
+/* This matches struct stat64 in glibc2.1, hence the absolutely
+ * insane amounts of padding around dev_t's.
+ */
+struct target_stat64 {
+ unsigned long long st_dev;
+ unsigned char __pad0[4];
+
+#define TARGET_STAT64_HAS_BROKEN_ST_INO 1
+ target_ulong __st_ino;
+
+ unsigned int st_mode;
+ unsigned int st_nlink;
+
+ target_ulong st_uid;
+ target_ulong st_gid;
+
+ unsigned long long st_rdev;
+ unsigned char __pad3[4];
+
+ long long st_size;
+ target_ulong st_blksize;
+
+ unsigned long long st_blocks; /* Number 512-byte blocks allocated. */
+
+ target_ulong target_st_atime;
+ target_ulong target_st_atime_nsec;
+
+ target_ulong target_st_mtime;
+ target_ulong target_st_mtime_nsec;
+
+ target_ulong target_st_ctime;
+ target_ulong target_st_ctime_nsec;
+
+ unsigned long long st_ino;
+};
+
#else
#error unsupported CPU
#endif
Modified: trunk/src/host/qemu-neo1973/monitor.c
===================================================================
--- trunk/src/host/qemu-neo1973/monitor.c 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/monitor.c 2007-07-02 20:43:42 UTC (rev 2356)
@@ -409,6 +409,11 @@
vga_hw_screen_dump(filename);
}
+static void do_logfile(const char *filename)
+{
+ cpu_set_log_filename(filename);
+}
+
static void do_log(const char *items)
{
int mask;
@@ -787,7 +792,7 @@
{ 0xb5, "kp_divide" },
{ 0x37, "kp_multiply" },
- { 0x4a, "kp_substract" },
+ { 0x4a, "kp_subtract" },
{ 0x4e, "kp_add" },
{ 0x9c, "kp_enter" },
{ 0x53, "kp_decimal" },
@@ -1239,6 +1244,8 @@
"device filename", "change a removable medium" },
{ "screendump", "F", do_screen_dump,
"filename", "save screen into PPM image 'filename'" },
+ { "logfile", "s", do_logfile,
+ "filename", "output logs to 'filename'" },
{ "log", "s", do_log,
"item1[,...]", "activate logging of the specified items to '/tmp/qemu.log'" },
{ "savevm", "s?", do_savevm,
Modified: trunk/src/host/qemu-neo1973/pc-bios/README
===================================================================
--- trunk/src/host/qemu-neo1973/pc-bios/README 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/pc-bios/README 2007-07-02 20:43:42 UTC (rev 2356)
@@ -14,8 +14,7 @@
- OpenBIOS (http://www.openbios.org/) is a free (GPL v2) portable
firmware implementation. The goal is to implement a 100% IEEE
1275-1994 (referred to as Open Firmware) compliant firmware.
- The included Sparc32 image is built from SVN version 149 and Sparc64
- image from version 125.
+ The included Sparc32 and Sparc64 images are built from SVN version 157.
- The PXE roms come from Rom-o-Matic etherboot 5.4.2.
pcnet32:pcnet32 -- [0x1022,0x2000]
Modified: trunk/src/host/qemu-neo1973/pc-bios/openbios-sparc32
===================================================================
(Binary files differ)
Modified: trunk/src/host/qemu-neo1973/pc-bios/openbios-sparc64
===================================================================
(Binary files differ)
Modified: trunk/src/host/qemu-neo1973/qemu-doc.texi
===================================================================
--- trunk/src/host/qemu-neo1973/qemu-doc.texi 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/qemu-doc.texi 2007-07-02 20:43:42 UTC (rev 2356)
@@ -1363,8 +1363,7 @@
above but it can be used with the tslib library because in addition to touch
coordinates it reports touch pressure.
@item @code{keyboard}
-Standard USB keyboard. Will override the PS/2 keyboard emulation (if
-present).
+Standard USB keyboard. Will override the PS/2 keyboard (if present).
@end table
@node host_usb_devices
Modified: trunk/src/host/qemu-neo1973/qemu-img.c
===================================================================
--- trunk/src/host/qemu-neo1973/qemu-img.c 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/qemu-img.c 2007-07-02 20:43:42 UTC (rev 2356)
@@ -297,7 +297,7 @@
drv = bdrv_find_format(fmt);
if (!drv)
error("Unknown file format '%s'", fmt);
- printf("Formating '%s', fmt=%s",
+ printf("Formatting '%s', fmt=%s",
filename, fmt);
if (encrypted)
printf(", encrypted");
Modified: trunk/src/host/qemu-neo1973/readline.c
===================================================================
--- trunk/src/host/qemu-neo1973/readline.c 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/readline.c 2007-07-02 20:43:42 UTC (rev 2356)
@@ -156,6 +156,45 @@
}
}
+static void term_backword(void)
+{
+ int start;
+
+ if (term_cmd_buf_index == 0 || term_cmd_buf_index > term_cmd_buf_size) {
+ return;
+ }
+
+ start = term_cmd_buf_index - 1;
+
+ /* find first word (backwards) */
+ while (start > 0) {
+ if (!isspace(term_cmd_buf[start])) {
+ break;
+ }
+
+ --start;
+ }
+
+ /* find first space (backwards) */
+ while (start > 0) {
+ if (isspace(term_cmd_buf[start])) {
+ ++start;
+ break;
+ }
+
+ --start;
+ }
+
+ /* remove word */
+ if (start < term_cmd_buf_index) {
+ memmove(term_cmd_buf + start,
+ term_cmd_buf + term_cmd_buf_index,
+ term_cmd_buf_size - term_cmd_buf_index);
+ term_cmd_buf_size -= term_cmd_buf_index - start;
+ term_cmd_buf_index = start;
+ }
+}
+
static void term_bol(void)
{
term_cmd_buf_index = 0;
@@ -338,6 +377,10 @@
/* NOTE: readline_start can be called here */
term_readline_func(term_readline_opaque, term_cmd_buf);
break;
+ case 23:
+ /* ^W */
+ term_backword();
+ break;
case 27:
term_esc_state = IS_ESC;
break;
Modified: trunk/src/host/qemu-neo1973/sdl.c
===================================================================
--- trunk/src/host/qemu-neo1973/sdl.c 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/sdl.c 2007-07-02 20:43:42 UTC (rev 2356)
@@ -223,8 +223,12 @@
if (!vm_running)
status = " [Stopped]";
- else if (gui_grab)
- status = " - Press Ctrl-Alt to exit grab";
+ else if (gui_grab) {
+ if (!alt_grab)
+ status = " - Press Ctrl-Alt to exit grab";
+ else
+ status = " - Press Ctrl-Alt-Shift to exit grab";
+ }
if (qemu_name)
snprintf(buf, sizeof(buf), "QEMU (%s)%s", qemu_name, status);
@@ -357,8 +361,13 @@
case SDL_KEYDOWN:
case SDL_KEYUP:
if (ev->type == SDL_KEYDOWN) {
- mod_state = (SDL_GetModState() & gui_grab_code) ==
- gui_grab_code;
+ if (!alt_grab) {
+ mod_state = (SDL_GetModState() & gui_grab_code) ==
+ gui_grab_code;
+ } else {
+ mod_state = (SDL_GetModState() & (gui_grab_code | KMOD_LSHIFT)) ==
+ (gui_grab_code | KMOD_LSHIFT);
+ }
gui_key_modifier_pressed = mod_state;
if (gui_key_modifier_pressed) {
int keycode;
@@ -419,7 +428,12 @@
}
}
} else if (ev->type == SDL_KEYUP) {
- mod_state = (ev->key.keysym.mod & gui_grab_code);
+ if (!alt_grab) {
+ mod_state = (ev->key.keysym.mod & gui_grab_code);
+ } else {
+ mod_state = (ev->key.keysym.mod &
+ (gui_grab_code | KMOD_LSHIFT));
+ }
if (!mod_state) {
if (gui_key_modifier_pressed) {
gui_key_modifier_pressed = 0;
@@ -452,6 +466,7 @@
case SDL_QUIT:
if (!no_quit) {
qemu_system_shutdown_request();
+ vm_start(); /* In case we're paused */
}
break;
case SDL_MOUSEMOTION:
Modified: trunk/src/host/qemu-neo1973/target-arm/cpu.h
===================================================================
--- trunk/src/host/qemu-neo1973/target-arm/cpu.h 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/target-arm/cpu.h 2007-07-02 20:43:42 UTC (rev 2356)
@@ -83,6 +83,7 @@
uint32_t c0_cachetype;
uint32_t c1_sys; /* System control register. */
uint32_t c1_coproc; /* Coprocessor access register. */
+ uint32_t c1_xscaleauxcr; /* XScale auxiliary control register. */
uint32_t c2_base; /* MMU translation table base. */
uint32_t c2_data; /* MPU data cachable bits. */
uint32_t c2_insn; /* MPU instruction cachable bits. */
Modified: trunk/src/host/qemu-neo1973/target-arm/helper.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-arm/helper.c 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/target-arm/helper.c 2007-07-02 20:43:42 UTC (rev 2356)
@@ -22,16 +22,19 @@
set_feature(env, ARM_FEATURE_VFP);
env->vfp.xregs[ARM_VFP_FPSID] = 0x41011090;
env->cp15.c0_cachetype = 0x1dd20d2;
+ env->cp15.c1_sys = 0x00090078;
break;
case ARM_CPUID_ARM946:
set_feature(env, ARM_FEATURE_MPU);
env->cp15.c0_cachetype = 0x0f004006;
+ env->cp15.c1_sys = 0x00000078;
break;
case ARM_CPUID_ARM1026:
set_feature(env, ARM_FEATURE_VFP);
set_feature(env, ARM_FEATURE_AUXCR);
env->vfp.xregs[ARM_VFP_FPSID] = 0x410110a0;
env->cp15.c0_cachetype = 0x1dd20d2;
+ env->cp15.c1_sys = 0x00090078;
break;
case ARM_CPUID_PXA250:
case ARM_CPUID_PXA255:
@@ -41,6 +44,7 @@
set_feature(env, ARM_FEATURE_XSCALE);
/* JTAG_ID is ((id << 28) | 0x09265013) */
env->cp15.c0_cachetype = 0xd172172;
+ env->cp15.c1_sys = 0x00000078;
break;
case ARM_CPUID_PXA270_A0:
case ARM_CPUID_PXA270_A1:
@@ -53,6 +57,7 @@
set_feature(env, ARM_FEATURE_IWMMXT);
env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q';
env->cp15.c0_cachetype = 0xd172172;
+ env->cp15.c1_sys = 0x00000078;
break;
default:
cpu_abort(env, "Bad CPU ID: %x\n", id);
@@ -642,6 +647,8 @@
crm = insn & 0xf;
switch ((insn >> 16) & 0xf) {
case 0: /* ID codes. */
+ if (arm_feature(env, ARM_FEATURE_XSCALE))
+ break;
goto bad_reg;
case 1: /* System configuration. */
switch (op2) {
@@ -653,12 +660,14 @@
tlb_flush(env, 1);
break;
case 1:
- /* XScale doesn't implement AUX CR (P-Bit) but allows
- * writing with zero and reading. */
- if (arm_feature(env, ARM_FEATURE_XSCALE))
+ if (arm_feature(env, ARM_FEATURE_XSCALE)) {
+ env->cp15.c1_xscaleauxcr = val;
break;
+ }
goto bad_reg;
case 2:
+ if (arm_feature(env, ARM_FEATURE_XSCALE))
+ goto bad_reg;
env->cp15.c1_coproc = val;
/* ??? Is this safe when called from within a TB? */
tb_flush(env);
@@ -844,6 +853,9 @@
case 2: /* TCM status. */
if (arm_feature(env, ARM_FEATURE_S3C))
return env->cp15.c0_cpuid;
+ if (arm_feature(env, ARM_FEATURE_XSCALE))
+ goto bad_reg;
+ return 0;
}
case 1: /* System configuration. */
switch (op2) {
@@ -853,9 +865,11 @@
if (arm_feature(env, ARM_FEATURE_AUXCR))
return 1;
if (arm_feature(env, ARM_FEATURE_XSCALE))
- return 0;
+ return env->cp15.c1_xscaleauxcr;
goto bad_reg;
case 2: /* Coprocessor access register. */
+ if (arm_feature(env, ARM_FEATURE_XSCALE))
+ goto bad_reg;
return env->cp15.c1_coproc;
default:
goto bad_reg;
Modified: trunk/src/host/qemu-neo1973/target-i386/exec.h
===================================================================
--- trunk/src/host/qemu-neo1973/target-i386/exec.h 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/target-i386/exec.h 2007-07-02 20:43:42 UTC (rev 2356)
@@ -190,6 +190,7 @@
void helper_idivq_EAX_T0(void);
void helper_bswapq_T0(void);
void helper_cmpxchg8b(void);
+void helper_single_step(void);
void helper_cpuid(void);
void helper_enter_level(int level, int data32);
void helper_enter64_level(int level, int data64);
Modified: trunk/src/host/qemu-neo1973/target-i386/helper.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-i386/helper.c 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/target-i386/helper.c 2007-07-02 20:43:42 UTC (rev 2356)
@@ -1622,6 +1622,12 @@
CC_SRC = eflags;
}
+void helper_single_step()
+{
+ env->dr[6] |= 0x4000;
+ raise_exception(EXCP01_SSTP);
+}
+
void helper_cpuid(void)
{
uint32_t index;
Modified: trunk/src/host/qemu-neo1973/target-i386/op.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-i386/op.c 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/target-i386/op.c 2007-07-02 20:43:42 UTC (rev 2356)
@@ -730,6 +730,11 @@
helper_cmpxchg8b();
}
+void OPPROTO op_single_step(void)
+{
+ helper_single_step();
+}
+
void OPPROTO op_movl_T0_0(void)
{
T0 = 0;
Modified: trunk/src/host/qemu-neo1973/target-i386/translate.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-i386/translate.c 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/target-i386/translate.c 2007-07-02 20:43:42 UTC (rev 2356)
@@ -2277,7 +2277,7 @@
if (s->singlestep_enabled) {
gen_op_debug();
} else if (s->tf) {
- gen_op_raise_exception(EXCP01_SSTP);
+ gen_op_single_step();
} else {
gen_op_movl_T0_0();
gen_op_exit_tb();
@@ -5327,8 +5327,12 @@
if (CODE64(s))
goto illegal_op;
val = ldub_code(s->pc++);
- gen_op_aam(val);
- s->cc_op = CC_OP_LOGICB;
+ if (val == 0) {
+ gen_exception(s, EXCP00_DIVZ, pc_start - s->cs_base);
+ } else {
+ gen_op_aam(val);
+ s->cc_op = CC_OP_LOGICB;
+ }
break;
case 0xd5: /* aad */
if (CODE64(s))
Modified: trunk/src/host/qemu-neo1973/target-mips/cpu.h
===================================================================
--- trunk/src/host/qemu-neo1973/target-mips/cpu.h 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/target-mips/cpu.h 2007-07-02 20:43:42 UTC (rev 2356)
@@ -102,6 +102,8 @@
uint32_t nb_tlb;
uint32_t tlb_in_use;
+ uint32_t SEGBITS;
+ target_ulong SEGMask;
int (*map_address) (CPUMIPSState *env, target_ulong *physical, int *prot, target_ulong address, int rw, int access_type);
void (*do_tlbwi) (void);
void (*do_tlbwr) (void);
Modified: trunk/src/host/qemu-neo1973/target-mips/helper.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-mips/helper.c 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/target-mips/helper.c 2007-07-02 20:43:42 UTC (rev 2356)
@@ -77,7 +77,7 @@
target_ulong tag = address & ~mask;
target_ulong VPN = tlb->VPN & ~mask;
#ifdef TARGET_MIPS64
- tag &= 0xC00000FFFFFFFFFFULL;
+ tag &= env->SEGMask;
#endif
/* Check ASID, virtual page number & size */
@@ -130,28 +130,27 @@
if (address <= (int32_t)0x7FFFFFFFUL) {
/* useg */
- if (!(env->CP0_Status & (1 << CP0St_ERL) && user_mode)) {
- ret = env->map_address(env, physical, prot, address, rw, access_type);
- } else {
+ if (env->CP0_Status & (1 << CP0St_ERL)) {
*physical = address & 0xFFFFFFFF;
*prot = PAGE_READ | PAGE_WRITE;
+ } else {
+ ret = env->map_address(env, physical, prot, address, rw, access_type);
}
#ifdef TARGET_MIPS64
/*
XXX: Assuming :
- PABITS = 36 (correct for MIPS64R1)
- - SEGBITS = 40
*/
} else if (address < 0x3FFFFFFFFFFFFFFFULL) {
/* xuseg */
- if (UX && address < 0x000000FFFFFFFFFFULL) {
+ if (UX && address < (0x3FFFFFFFFFFFFFFFULL & env->SEGMask)) {
ret = env->map_address(env, physical, prot, address, rw, access_type);
} else {
ret = TLBRET_BADADDR;
}
} else if (address < 0x7FFFFFFFFFFFFFFFULL) {
/* xsseg */
- if (SX && address < 0x400000FFFFFFFFFFULL) {
+ if (SX && address < (0x7FFFFFFFFFFFFFFFULL & env->SEGMask)) {
ret = env->map_address(env, physical, prot, address, rw, access_type);
} else {
ret = TLBRET_BADADDR;
@@ -159,9 +158,9 @@
} else if (address < 0xBFFFFFFFFFFFFFFFULL) {
/* xkphys */
/* XXX: check supervisor mode */
- if (KX && (address & 0x03FFFFFFFFFFFFFFULL) < 0X0000000FFFFFFFFFULL)
+ if (KX && (address & 0x07FFFFFFFFFFFFFFULL) < 0X0000000FFFFFFFFFULL)
{
- *physical = address & 0X000000FFFFFFFFFFULL;
+ *physical = address & 0X0000000FFFFFFFFFULL;
*prot = PAGE_READ | PAGE_WRITE;
} else {
ret = TLBRET_BADADDR;
@@ -169,7 +168,7 @@
} else if (address < 0xFFFFFFFF7FFFFFFFULL) {
/* xkseg */
/* XXX: check supervisor mode */
- if (KX && address < 0xC00000FF7FFFFFFFULL) {
+ if (KX && address < (0xFFFFFFFF7FFFFFFFULL & env->SEGMask)) {
ret = env->map_address(env, physical, prot, address, rw, access_type);
} else {
ret = TLBRET_BADADDR;
@@ -303,10 +302,10 @@
env->CP0_EntryHi =
(env->CP0_EntryHi & 0xFF) | (address & (TARGET_PAGE_MASK << 1));
#ifdef TARGET_MIPS64
- env->CP0_EntryHi &= 0xc00000ffffffffffULL;
- env->CP0_XContext = (env->CP0_XContext & 0xfffffffe00000000ULL) |
- ((address >> 31) & 0x0000000180000000ULL) |
- ((address >> 9) & 0x000000007ffffff0ULL);
+ env->CP0_EntryHi &= env->SEGMask;
+ env->CP0_XContext = (env->CP0_XContext & ((~0ULL) << (env->SEGBITS - 7))) |
+ ((address & 0xC00000000000ULL) >> (env->SEGBITS - 9)) |
+ ((address & ((1ULL << env->SEGBITS) - 1) & 0xFFFFFFFFFFFFE000ULL) >> 9);
#endif
env->exception_index = exception;
env->error_code = error_code;
@@ -555,7 +554,7 @@
if (tlb->V0) {
addr = tlb->VPN & ~mask;
#ifdef TARGET_MIPS64
- if (addr >= 0xC00000FF80000000ULL) {
+ if (addr >= (0xFFFFFFFF80000000ULL & env->SEGMask)) {
addr |= 0x3FFFFF0000000000ULL;
}
#endif
@@ -568,7 +567,7 @@
if (tlb->V1) {
addr = (tlb->VPN & ~mask) | ((mask >> 1) + 1);
#ifdef TARGET_MIPS64
- if (addr >= 0xC00000FF80000000ULL) {
+ if (addr >= (0xFFFFFFFF80000000ULL & env->SEGMask)) {
addr |= 0x3FFFFF0000000000ULL;
}
#endif
Modified: trunk/src/host/qemu-neo1973/target-mips/op.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-mips/op.c 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/target-mips/op.c 2007-07-02 20:43:42 UTC (rev 2356)
@@ -297,7 +297,7 @@
with Status_UX = 0 should be casted to 32-bit and sign extended.
See the MIPS64 PRA manual, section 4.10. */
#ifdef TARGET_MIPS64
- if ((env->CP0_Status & (1 << CP0St_UM)) &&
+ if ((env->hflags & MIPS_HFLAG_UM) &&
!(env->CP0_Status & (1 << CP0St_UX)))
T0 = (int64_t)(int32_t)(T0 + T1);
else
@@ -1328,7 +1328,7 @@
/* 1k pages not implemented */
val = T0 & ((TARGET_PAGE_MASK << 1) | 0xFF);
#ifdef TARGET_MIPS64
- val = T0 & 0xC00000FFFFFFFFFFULL;
+ val &= env->SEGMask;
#endif
old = env->CP0_EntryHi;
env->CP0_EntryHi = val;
@@ -1433,7 +1433,7 @@
void op_mtc0_config0 (void)
{
- env->CP0_Config0 = (env->CP0_Config0 & 0x81FFFFF8) | (T0 & 0x00000001);
+ env->CP0_Config0 = (env->CP0_Config0 & 0x81FFFFF8) | (T0 & 0x00000007);
RETURN();
}
@@ -1526,7 +1526,8 @@
#ifdef TARGET_MIPS64
void op_mtc0_xcontext (void)
{
- env->CP0_XContext = (env->CP0_XContext & 0x1ffffffffULL) | (T0 & ~0x1ffffffffULL);
+ target_ulong mask = (1ULL << (env->SEGBITS - 7)) - 1;
+ env->CP0_XContext = (env->CP0_XContext & mask) | (T0 & ~mask);
RETURN();
}
@@ -1607,7 +1608,7 @@
void op_cp0_enabled(void)
{
if (!(env->CP0_Status & (1 << CP0St_CU0)) &&
- (env->hflags & MIPS_HFLAG_UM)) {
+ (env->hflags & MIPS_HFLAG_UM)) {
CALL_FROM_TB2(do_raise_exception_err, EXCP_CpU, 0);
}
RETURN();
Modified: trunk/src/host/qemu-neo1973/target-mips/op_helper.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-mips/op_helper.c 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/target-mips/op_helper.c 2007-07-02 20:43:42 UTC (rev 2356)
@@ -374,7 +374,7 @@
tlb = &env->mmu.r4k.tlb[idx];
tlb->VPN = env->CP0_EntryHi & (TARGET_PAGE_MASK << 1);
#ifdef TARGET_MIPS64
- tlb->VPN &= 0xC00000FFFFFFFFFFULL;
+ tlb->VPN &= env->SEGMask;
#endif
tlb->ASID = env->CP0_EntryHi & 0xFF;
tlb->PageMask = env->CP0_PageMask;
@@ -597,6 +597,13 @@
/* Complex FPU operations which may need stack space. */
+#define FLOAT_SIGN32 (1 << 31)
+#define FLOAT_SIGN64 (1ULL << 63)
+#define FLOAT_ONE32 (0x3f8 << 20)
+#define FLOAT_ONE64 (0x3ffULL << 52)
+#define FLOAT_TWO32 (1 << 30)
+#define FLOAT_TWO64 (1ULL << 62)
+
/* convert MIPS rounding mode in FCR31 to IEEE library */
unsigned int ieee_rm[] = {
float_round_nearest_even,
@@ -775,7 +782,7 @@
FLOAT_OP(roundl, d)
{
set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
- DT2 = float64_round_to_int(FDT0, &env->fp_status);
+ DT2 = float64_to_int64(FDT0, &env->fp_status);
RESTORE_ROUNDING_MODE;
update_fcr31();
if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
@@ -784,7 +791,7 @@
FLOAT_OP(roundl, s)
{
set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
- DT2 = float32_round_to_int(FST0, &env->fp_status);
+ DT2 = float32_to_int64(FST0, &env->fp_status);
RESTORE_ROUNDING_MODE;
update_fcr31();
if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
@@ -793,7 +800,7 @@
FLOAT_OP(roundw, d)
{
set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
- WT2 = float64_round_to_int(FDT0, &env->fp_status);
+ WT2 = float64_to_int32(FDT0, &env->fp_status);
RESTORE_ROUNDING_MODE;
update_fcr31();
if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
@@ -802,7 +809,7 @@
FLOAT_OP(roundw, s)
{
set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
- WT2 = float32_round_to_int(FST0, &env->fp_status);
+ WT2 = float32_to_int32(FST0, &env->fp_status);
RESTORE_ROUNDING_MODE;
update_fcr31();
if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
@@ -841,7 +848,7 @@
FLOAT_OP(ceill, d)
{
set_float_rounding_mode(float_round_up, &env->fp_status);
- DT2 = float64_round_to_int(FDT0, &env->fp_status);
+ DT2 = float64_to_int64(FDT0, &env->fp_status);
RESTORE_ROUNDING_MODE;
update_fcr31();
if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
@@ -850,7 +857,7 @@
FLOAT_OP(ceill, s)
{
set_float_rounding_mode(float_round_up, &env->fp_status);
- DT2 = float32_round_to_int(FST0, &env->fp_status);
+ DT2 = float32_to_int64(FST0, &env->fp_status);
RESTORE_ROUNDING_MODE;
update_fcr31();
if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
@@ -859,7 +866,7 @@
FLOAT_OP(ceilw, d)
{
set_float_rounding_mode(float_round_up, &env->fp_status);
- WT2 = float64_round_to_int(FDT0, &env->fp_status);
+ WT2 = float64_to_int32(FDT0, &env->fp_status);
RESTORE_ROUNDING_MODE;
update_fcr31();
if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
@@ -868,7 +875,7 @@
FLOAT_OP(ceilw, s)
{
set_float_rounding_mode(float_round_up, &env->fp_status);
- WT2 = float32_round_to_int(FST0, &env->fp_status);
+ WT2 = float32_to_int32(FST0, &env->fp_status);
RESTORE_ROUNDING_MODE;
update_fcr31();
if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
@@ -878,7 +885,7 @@
FLOAT_OP(floorl, d)
{
set_float_rounding_mode(float_round_down, &env->fp_status);
- DT2 = float64_round_to_int(FDT0, &env->fp_status);
+ DT2 = float64_to_int64(FDT0, &env->fp_status);
RESTORE_ROUNDING_MODE;
update_fcr31();
if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
@@ -887,7 +894,7 @@
FLOAT_OP(floorl, s)
{
set_float_rounding_mode(float_round_down, &env->fp_status);
- DT2 = float32_round_to_int(FST0, &env->fp_status);
+ DT2 = float32_to_int64(FST0, &env->fp_status);
RESTORE_ROUNDING_MODE;
update_fcr31();
if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
@@ -896,7 +903,7 @@
FLOAT_OP(floorw, d)
{
set_float_rounding_mode(float_round_down, &env->fp_status);
- WT2 = float64_round_to_int(FDT0, &env->fp_status);
+ WT2 = float64_to_int32(FDT0, &env->fp_status);
RESTORE_ROUNDING_MODE;
update_fcr31();
if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
@@ -905,66 +912,86 @@
FLOAT_OP(floorw, s)
{
set_float_rounding_mode(float_round_down, &env->fp_status);
- WT2 = float32_round_to_int(FST0, &env->fp_status);
+ WT2 = float32_to_int32(FST0, &env->fp_status);
RESTORE_ROUNDING_MODE;
update_fcr31();
if (GET_FP_CAUSE(env->fcr31) & (FP_OVERFLOW | FP_INVALID))
WT2 = 0x7fffffff;
}
-/* unary operations, MIPS specific, s and d */
-#define FLOAT_UNOP(name) \
-FLOAT_OP(name, d) \
-{ \
- set_float_exception_flags(0, &env->fp_status); \
-/* XXX: not implemented */ \
-/* FDT2 = float64_ ## name (FDT0, &env->fp_status);*/ \
-do_raise_exception(EXCP_RI); \
- update_fcr31(); \
-} \
-FLOAT_OP(name, s) \
-{ \
- set_float_exception_flags(0, &env->fp_status); \
-/* XXX: not implemented */ \
-/* FST2 = float32_ ## name (FST0, &env->fp_status);*/ \
-do_raise_exception(EXCP_RI); \
- update_fcr31(); \
+/* MIPS specific unary operations */
+FLOAT_OP(recip, d)
+{
+ set_float_exception_flags(0, &env->fp_status);
+ FDT2 = float64_div(FLOAT_ONE64, FDT0, &env->fp_status);
+ update_fcr31();
}
-FLOAT_UNOP(rsqrt)
-FLOAT_UNOP(recip)
-#undef FLOAT_UNOP
+FLOAT_OP(recip, s)
+{
+ set_float_exception_flags(0, &env->fp_status);
+ FST2 = float32_div(FLOAT_ONE32, FST0, &env->fp_status);
+ update_fcr31();
+}
-/* unary operations, MIPS specific, s, d and ps */
-#define FLOAT_UNOP(name) \
-FLOAT_OP(name, d) \
-{ \
- set_float_exception_flags(0, &env->fp_status); \
-/* XXX: not implemented */ \
-/* FDT2 = float64_ ## name (FDT0, &env->fp_status);*/ \
-do_raise_exception(EXCP_RI); \
- update_fcr31(); \
-} \
-FLOAT_OP(name, s) \
-{ \
- set_float_exception_flags(0, &env->fp_status); \
-/* XXX: not implemented */ \
-/* FST2 = float32_ ## name (FST0, &env->fp_status);*/ \
-do_raise_exception(EXCP_RI); \
- update_fcr31(); \
-} \
-FLOAT_OP(name, ps) \
-{ \
- set_float_exception_flags(0, &env->fp_status); \
-/* XXX: not implemented */ \
-/* FST2 = float32_ ## name (FST0, &env->fp_status);*/ \
-/* FSTH2 = float32_ ## name (FSTH0, &env->fp_status);*/ \
-do_raise_exception(EXCP_RI); \
- update_fcr31(); \
+FLOAT_OP(rsqrt, d)
+{
+ set_float_exception_flags(0, &env->fp_status);
+ FDT2 = float64_sqrt(FDT0, &env->fp_status);
+ FDT2 = float64_div(FLOAT_ONE64, FDT2, &env->fp_status);
+ update_fcr31();
}
-FLOAT_UNOP(rsqrt1)
-FLOAT_UNOP(recip1)
-#undef FLOAT_UNOP
+FLOAT_OP(rsqrt, s)
+{
+ set_float_exception_flags(0, &env->fp_status);
+ FST2 = float32_sqrt(FST0, &env->fp_status);
+ FST2 = float32_div(FLOAT_ONE32, FST2, &env->fp_status);
+ update_fcr31();
+}
+FLOAT_OP(recip1, d)
+{
+ set_float_exception_flags(0, &env->fp_status);
+ FDT2 = float64_div(FLOAT_ONE64, FDT0, &env->fp_status);
+ update_fcr31();
+}
+FLOAT_OP(recip1, s)
+{
+ set_float_exception_flags(0, &env->fp_status);
+ FST2 = float32_div(FLOAT_ONE32, FST0, &env->fp_status);
+ update_fcr31();
+}
+FLOAT_OP(recip1, ps)
+{
+ set_float_exception_flags(0, &env->fp_status);
+ FST2 = float32_div(FLOAT_ONE32, FST0, &env->fp_status);
+ FSTH2 = float32_div(FLOAT_ONE32, FSTH0, &env->fp_status);
+ update_fcr31();
+}
+
+FLOAT_OP(rsqrt1, d)
+{
+ set_float_exception_flags(0, &env->fp_status);
+ FDT2 = float64_sqrt(FDT0, &env->fp_status);
+ FDT2 = float64_div(FLOAT_ONE64, FDT2, &env->fp_status);
+ update_fcr31();
+}
+FLOAT_OP(rsqrt1, s)
+{
+ set_float_exception_flags(0, &env->fp_status);
+ FST2 = float32_sqrt(FST0, &env->fp_status);
+ FST2 = float32_div(FLOAT_ONE32, FST2, &env->fp_status);
+ update_fcr31();
+}
+FLOAT_OP(rsqrt1, ps)
+{
+ set_float_exception_flags(0, &env->fp_status);
+ FST2 = float32_sqrt(FST0, &env->fp_status);
+ FSTH2 = float32_sqrt(FSTH0, &env->fp_status);
+ FST2 = float32_div(FLOAT_ONE32, FST2, &env->fp_status);
+ FSTH2 = float32_div(FLOAT_ONE32, FSTH2, &env->fp_status);
+ update_fcr31();
+}
+
/* binary operations */
#define FLOAT_BINOP(name) \
FLOAT_OP(name, d) \
@@ -976,7 +1003,7 @@
FDT2 = 0x7ff7ffffffffffffULL; \
else if (GET_FP_CAUSE(env->fcr31) & FP_UNDERFLOW) { \
if ((env->fcr31 & 0x3) == 0) \
- FDT2 &= 0x8000000000000000ULL; \
+ FDT2 &= FLOAT_SIGN64; \
} \
} \
FLOAT_OP(name, s) \
@@ -988,7 +1015,7 @@
FST2 = 0x7fbfffff; \
else if (GET_FP_CAUSE(env->fcr31) & FP_UNDERFLOW) { \
if ((env->fcr31 & 0x3) == 0) \
- FST2 &= 0x80000000ULL; \
+ FST2 &= FLOAT_SIGN32; \
} \
} \
FLOAT_OP(name, ps) \
@@ -1002,8 +1029,8 @@
FSTH2 = 0x7fbfffff; \
} else if (GET_FP_CAUSE(env->fcr31) & FP_UNDERFLOW) { \
if ((env->fcr31 & 0x3) == 0) { \
- FST2 &= 0x80000000ULL; \
- FSTH2 &= 0x80000000ULL; \
+ FST2 &= FLOAT_SIGN32; \
+ FSTH2 &= FLOAT_SIGN32; \
} \
} \
}
@@ -1013,37 +1040,59 @@
FLOAT_BINOP(div)
#undef FLOAT_BINOP
-/* binary operations, MIPS specific */
-#define FLOAT_BINOP(name) \
-FLOAT_OP(name, d) \
-{ \
- set_float_exception_flags(0, &env->fp_status); \
-/* XXX: not implemented */ \
-/* FDT2 = float64_ ## name (FDT0, FDT1, &env->fp_status);*/ \
-do_raise_exception(EXCP_RI); \
- update_fcr31(); \
-} \
-FLOAT_OP(name, s) \
-{ \
- set_float_exception_flags(0, &env->fp_status); \
-/* XXX: not implemented */ \
-/* FST2 = float32_ ## name (FST0, FST1, &env->fp_status);*/ \
-do_raise_exception(EXCP_RI); \
- update_fcr31(); \
-} \
-FLOAT_OP(name, ps) \
-{ \
- set_float_exception_flags(0, &env->fp_status); \
-/* XXX: not implemented */ \
-/* FST2 = float32_ ## name (FST0, FST1, &env->fp_status);*/ \
-/* FSTH2 = float32_ ## name (FSTH0, FSTH1, &env->fp_status);*/ \
-do_raise_exception(EXCP_RI); \
- update_fcr31(); \
+/* MIPS specific binary operations */
+FLOAT_OP(recip2, d)
+{
+ set_float_exception_flags(0, &env->fp_status);
+ FDT2 = float64_mul(FDT0, FDT2, &env->fp_status);
+ FDT2 = float64_sub(FDT2, FLOAT_ONE64, &env->fp_status) ^ FLOAT_SIGN64;
+ update_fcr31();
}
-FLOAT_BINOP(rsqrt2)
-FLOAT_BINOP(recip2)
-#undef FLOAT_BINOP
+FLOAT_OP(recip2, s)
+{
+ set_float_exception_flags(0, &env->fp_status);
+ FST2 = float32_mul(FST0, FST2, &env->fp_status);
+ FST2 = float32_sub(FST2, FLOAT_ONE32, &env->fp_status) ^ FLOAT_SIGN32;
+ update_fcr31();
+}
+FLOAT_OP(recip2, ps)
+{
+ set_float_exception_flags(0, &env->fp_status);
+ FST2 = float32_mul(FST0, FST2, &env->fp_status);
+ FSTH2 = float32_mul(FSTH0, FSTH2, &env->fp_status);
+ FST2 = float32_sub(FST2, FLOAT_ONE32, &env->fp_status) ^ FLOAT_SIGN32;
+ FSTH2 = float32_sub(FSTH2, FLOAT_ONE32, &env->fp_status) ^ FLOAT_SIGN32;
+ update_fcr31();
+}
+FLOAT_OP(rsqrt2, d)
+{
+ set_float_exception_flags(0, &env->fp_status);
+ FDT2 = float64_mul(FDT0, FDT2, &env->fp_status);
+ FDT2 = float64_sub(FDT2, FLOAT_ONE64, &env->fp_status);
+ FDT2 = float64_div(FDT2, FLOAT_TWO64, &env->fp_status) ^ FLOAT_SIGN64;
+ update_fcr31();
+}
+FLOAT_OP(rsqrt2, s)
+{
+ set_float_exception_flags(0, &env->fp_status);
+ FST2 = float32_mul(FST0, FST2, &env->fp_status);
+ FST2 = float32_sub(FST2, FLOAT_ONE32, &env->fp_status);
+ FST2 = float32_div(FST2, FLOAT_TWO32, &env->fp_status) ^ FLOAT_SIGN32;
+ update_fcr31();
+}
+FLOAT_OP(rsqrt2, ps)
+{
+ set_float_exception_flags(0, &env->fp_status);
+ FST2 = float32_mul(FST0, FST2, &env->fp_status);
+ FSTH2 = float32_mul(FSTH0, FSTH2, &env->fp_status);
+ FST2 = float32_sub(FST2, FLOAT_ONE32, &env->fp_status);
+ FSTH2 = float32_sub(FSTH2, FLOAT_ONE32, &env->fp_status);
+ FST2 = float32_div(FST2, FLOAT_TWO32, &env->fp_status) ^ FLOAT_SIGN32;
+ FSTH2 = float32_div(FSTH2, FLOAT_TWO32, &env->fp_status) ^ FLOAT_SIGN32;
+ update_fcr31();
+}
+
FLOAT_OP(addr, ps)
{
set_float_exception_flags(0, &env->fp_status);
@@ -1060,6 +1109,7 @@
update_fcr31();
}
+/* compare operations */
#define FOP_COND_D(op, cond) \
void do_cmp_d_ ## op (long cc) \
{ \
@@ -1073,8 +1123,8 @@
void do_cmpabs_d_ ## op (long cc) \
{ \
int c; \
- FDT0 &= ~(1ULL << 63); \
- FDT1 &= ~(1ULL << 63); \
+ FDT0 &= ~FLOAT_SIGN64; \
+ FDT1 &= ~FLOAT_SIGN64; \
c = cond; \
update_fcr31(); \
if (c) \
@@ -1131,8 +1181,8 @@
void do_cmpabs_s_ ## op (long cc) \
{ \
int c; \
- FST0 &= ~(1 << 31); \
- FST1 &= ~(1 << 31); \
+ FST0 &= ~FLOAT_SIGN32; \
+ FST1 &= ~FLOAT_SIGN32; \
c = cond; \
update_fcr31(); \
if (c) \
@@ -1194,10 +1244,10 @@
void do_cmpabs_ps_ ## op (long cc) \
{ \
int cl, ch; \
- FST0 &= ~(1 << 31); \
- FSTH0 &= ~(1 << 31); \
- FST1 &= ~(1 << 31); \
- FSTH1 &= ~(1 << 31); \
+ FST0 &= ~FLOAT_SIGN32; \
+ FSTH0 &= ~FLOAT_SIGN32; \
+ FST1 &= ~FLOAT_SIGN32; \
+ FSTH1 &= ~FLOAT_SIGN32; \
cl = condl; \
ch = condh; \
update_fcr31(); \
Modified: trunk/src/host/qemu-neo1973/target-mips/translate.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-mips/translate.c 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/target-mips/translate.c 2007-07-02 20:43:42 UTC (rev 2356)
@@ -4551,7 +4551,7 @@
case FOP(31, 16):
check_cp1_64bitmode(ctx);
GEN_LOAD_FREG_FTN(WT0, fs);
- GEN_LOAD_FREG_FTN(WT2, fd);
+ GEN_LOAD_FREG_FTN(WT2, ft);
gen_op_float_rsqrt2_s();
GEN_STORE_FTN_FREG(fd, WT2);
opn = "rsqrt2.s";
@@ -5036,8 +5036,8 @@
check_cp1_64bitmode(ctx);
GEN_LOAD_FREG_FTN(WT0, fs);
GEN_LOAD_FREG_FTN(WTH0, fs);
- GEN_LOAD_FREG_FTN(WT2, fd);
- GEN_LOAD_FREG_FTN(WTH2, fd);
+ GEN_LOAD_FREG_FTN(WT2, ft);
+ GEN_LOAD_FREG_FTN(WTH2, ft);
gen_op_float_rsqrt2_ps();
GEN_STORE_FTN_FREG(fd, WT2);
GEN_STORE_FTN_FREG(fd, WTH2);
Modified: trunk/src/host/qemu-neo1973/target-mips/translate_init.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-mips/translate_init.c 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/target-mips/translate_init.c 2007-07-02 20:43:42 UTC (rev 2356)
@@ -71,13 +71,13 @@
int32_t CCRes;
int32_t Status_rw_bitmask;
int32_t CP1_fcr0;
+ int32_t SEGBITS;
};
/*****************************************************************************/
/* MIPS CPU definitions */
static mips_def_t mips_defs[] =
{
-#ifndef TARGET_MIPS64
{
.name = "4Kc",
.CP0_PRid = 0x00018000,
@@ -88,6 +88,7 @@
.SYNCI_Step = 32,
.CCRes = 2,
.Status_rw_bitmask = 0x3278FF17,
+ .SEGBITS = 32,
},
{
.name = "4KEcR1",
@@ -99,6 +100,7 @@
.SYNCI_Step = 32,
.CCRes = 2,
.Status_rw_bitmask = 0x3278FF17,
+ .SEGBITS = 32,
},
{
.name = "4KEc",
@@ -110,6 +112,7 @@
.SYNCI_Step = 32,
.CCRes = 2,
.Status_rw_bitmask = 0x3278FF17,
+ .SEGBITS = 32,
},
{
.name = "24Kc",
@@ -121,6 +124,7 @@
.SYNCI_Step = 32,
.CCRes = 2,
.Status_rw_bitmask = 0x3278FF17,
+ .SEGBITS = 32,
},
{
.name = "24Kf",
@@ -134,8 +138,9 @@
.Status_rw_bitmask = 0x3678FF17,
.CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) |
(1 << FCR0_D) | (1 << FCR0_S) | (0x93 << FCR0_PRID),
+ .SEGBITS = 32,
},
-#else
+#ifdef TARGET_MIPS64
{
.name = "R4000",
.CP0_PRid = 0x00000400,
@@ -148,6 +153,7 @@
.Status_rw_bitmask = 0x3678FFFF,
/* The R4000 has a full 64bit FPU doesn't use the fcr0 bits. */
.CP1_fcr0 = (0x5 << FCR0_PRID) | (0x0 << FCR0_REV),
+ .SEGBITS = 40,
},
{
.name = "5Kc",
@@ -162,6 +168,7 @@
.SYNCI_Step = 32,
.CCRes = 2,
.Status_rw_bitmask = 0x32F8FFFF,
+ .SEGBITS = 42,
},
{
.name = "5Kf",
@@ -179,6 +186,7 @@
/* The 5Kf has F64 / L / W but doesn't use the fcr0 bits. */
.CP1_fcr0 = (1 << FCR0_D) | (1 << FCR0_S) |
(0x81 << FCR0_PRID) | (0x0 << FCR0_REV),
+ .SEGBITS = 42,
},
{
.name = "20Kc",
@@ -199,6 +207,7 @@
.CP1_fcr0 = (1 << FCR0_3D) | (1 << FCR0_PS) |
(1 << FCR0_D) | (1 << FCR0_S) |
(0x82 << FCR0_PRID) | (0x0 << FCR0_REV),
+ .SEGBITS = 40,
},
#endif
};
@@ -275,6 +284,10 @@
env->CCRes = def->CCRes;
env->Status_rw_bitmask = def->Status_rw_bitmask;
env->fcr0 = def->CP1_fcr0;
+#ifdef TARGET_MIPS64
+ env->SEGBITS = def->SEGBITS;
+ env->SEGMask = (3ULL << 62) | ((1ULL << def->SEGBITS) - 1);
+#endif
#ifdef CONFIG_USER_ONLY
if (env->CP0_Config1 & (1 << CP0C1_FP))
env->hflags |= MIPS_HFLAG_FPU;
Modified: trunk/src/host/qemu-neo1973/target-ppc/cpu.h
===================================================================
--- trunk/src/host/qemu-neo1973/target-ppc/cpu.h 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/target-ppc/cpu.h 2007-07-02 20:43:42 UTC (rev 2356)
@@ -1326,7 +1326,7 @@
EXCP_FP_ZX = 0x03, /* FP divide by zero */
EXCP_FP_XX = 0x04, /* FP inexact */
EXCP_FP_VXNAN = 0x05, /* FP invalid SNaN op */
- EXCP_FP_VXISI = 0x06, /* FP invalid infinite substraction */
+ EXCP_FP_VXISI = 0x06, /* FP invalid infinite subtraction */
EXCP_FP_VXIDI = 0x07, /* FP invalid infinite divide */
EXCP_FP_VXZDZ = 0x08, /* FP invalid zero divide */
EXCP_FP_VXIMZ = 0x09, /* FP invalid infinite * zero */
Modified: trunk/src/host/qemu-neo1973/target-ppc/op.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-ppc/op.c 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/target-ppc/op.c 2007-07-02 20:43:42 UTC (rev 2356)
@@ -1025,7 +1025,7 @@
}
#endif
-/* substract from */
+/* subtract from */
PPC_OP(subf)
{
T0 = T1 - T0;
@@ -1058,7 +1058,7 @@
}
#endif
-/* substract from carrying */
+/* subtract from carrying */
void OPPROTO op_check_subfc (void)
{
if (likely((uint32_t)T0 > (uint32_t)T1)) {
@@ -1081,7 +1081,7 @@
}
#endif
-/* substract from extended */
+/* subtract from extended */
void OPPROTO op_subfe (void)
{
do_subfe();
@@ -1096,7 +1096,7 @@
}
#endif
-/* substract from immediate carrying */
+/* subtract from immediate carrying */
void OPPROTO op_subfic (void)
{
T0 = (int32_t)PARAM1 + ~T0 + 1;
@@ -1121,7 +1121,7 @@
}
#endif
-/* substract from minus one extended */
+/* subtract from minus one extended */
void OPPROTO op_subfme (void)
{
T0 = ~T0 + xer_ca - 1;
@@ -1154,7 +1154,7 @@
}
#endif
-/* substract from zero extended */
+/* subtract from zero extended */
void OPPROTO op_subfze (void)
{
T1 = ~T0;
Modified: trunk/src/host/qemu-neo1973/target-sh4/cpu.h
===================================================================
--- trunk/src/host/qemu-neo1973/target-sh4/cpu.h 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/target-sh4/cpu.h 2007-07-02 20:43:42 UTC (rev 2356)
@@ -80,7 +80,7 @@
typedef struct CPUSH4State {
uint32_t flags; /* general execution flags */
uint32_t gregs[24]; /* general registers */
- uint32_t fregs[32]; /* floating point registers */
+ float32 fregs[32]; /* floating point registers */
uint32_t sr; /* status register */
uint32_t ssr; /* saved status register */
uint32_t spc; /* saved program counter */
@@ -99,6 +99,7 @@
/* temporary float registers */
float32 ft0, ft1;
float64 dt0, dt1;
+ float_status fp_status;
/* Those belong to the specific unit (SH7750) but are handled here */
uint32_t mmucr; /* MMU control register */
@@ -114,6 +115,7 @@
jmp_buf jmp_env;
int user_mode_only;
int interrupt_request;
+ int halted;
int exception_index;
CPU_COMMON tlb_t utlb[UTLB_SIZE]; /* unified translation table */
tlb_t itlb[ITLB_SIZE]; /* instruction translation table */
Modified: trunk/src/host/qemu-neo1973/target-sh4/exec.h
===================================================================
--- trunk/src/host/qemu-neo1973/target-sh4/exec.h 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/target-sh4/exec.h 2007-07-02 20:43:42 UTC (rev 2356)
@@ -36,6 +36,16 @@
#include "cpu.h"
#include "exec-all.h"
+static inline int cpu_halted(CPUState *env) {
+ if (!env->halted)
+ return 0;
+ if (env->interrupt_request & CPU_INTERRUPT_HARD) {
+ env->halted = 0;
+ return 0;
+ }
+ return EXCP_HALTED;
+}
+
#ifndef CONFIG_USER_ONLY
#include "softmmu_exec.h"
#endif
Modified: trunk/src/host/qemu-neo1973/target-sh4/op.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-sh4/op.c 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/target-sh4/op.c 2007-07-02 20:43:42 UTC (rev 2356)
@@ -509,6 +509,9 @@
void OPPROTO op_lds_T0_fpscr(void)
{
env->fpscr = T0 & 0x003fffff;
+ env->fp_status.float_rounding_mode = T0 & 0x01 ?
+ float_round_to_zero : float_round_nearest_even;
+
RETURN();
}
@@ -695,28 +698,130 @@
void OPPROTO op_fmov_frN_FT0(void)
{
- FT0 = *(float32 *)&env->fregs[PARAM1];
+ FT0 = env->fregs[PARAM1];
RETURN();
}
void OPPROTO op_fmov_drN_DT0(void)
{
- DT0 = *(float64 *)&env->fregs[PARAM1];
+ CPU_DoubleU d;
+
+ d.l.upper = *(uint32_t *)&env->fregs[PARAM1];
+ d.l.lower = *(uint32_t *)&env->fregs[PARAM1 + 1];
+ DT0 = d.d;
RETURN();
}
+void OPPROTO op_fmov_frN_FT1(void)
+{
+ FT1 = env->fregs[PARAM1];
+ RETURN();
+}
+
+void OPPROTO op_fmov_drN_DT1(void)
+{
+ CPU_DoubleU d;
+
+ d.l.upper = *(uint32_t *)&env->fregs[PARAM1];
+ d.l.lower = *(uint32_t *)&env->fregs[PARAM1 + 1];
+ DT1 = d.d;
+ RETURN();
+}
+
void OPPROTO op_fmov_FT0_frN(void)
{
- *(float32 *)&env->fregs[PARAM1] = FT0;
+ env->fregs[PARAM1] = FT0;
RETURN();
}
void OPPROTO op_fmov_DT0_drN(void)
{
- *(float64 *)&env->fregs[PARAM1] = DT0;
+ CPU_DoubleU d;
+
+ d.d = DT0;
+ *(uint32_t *)&env->fregs[PARAM1] = d.l.upper;
+ *(uint32_t *)&env->fregs[PARAM1 + 1] = d.l.lower;
RETURN();
}
+void OPPROTO op_fadd_FT(void)
+{
+ FT0 = float32_add(FT0, FT1, &env->fp_status);
+ RETURN();
+}
+
+void OPPROTO op_fadd_DT(void)
+{
+ DT0 = float64_add(DT0, DT1, &env->fp_status);
+ RETURN();
+}
+
+void OPPROTO op_fsub_FT(void)
+{
+ FT0 = float32_sub(FT0, FT1, &env->fp_status);
+ RETURN();
+}
+
+void OPPROTO op_fsub_DT(void)
+{
+ DT0 = float64_sub(DT0, DT1, &env->fp_status);
+ RETURN();
+}
+
+void OPPROTO op_fmul_FT(void)
+{
+ FT0 = float32_mul(FT0, FT1, &env->fp_status);
+ RETURN();
+}
+
+void OPPROTO op_fmul_DT(void)
+{
+ DT0 = float64_mul(DT0, DT1, &env->fp_status);
+ RETURN();
+}
+
+void OPPROTO op_fdiv_FT(void)
+{
+ FT0 = float32_div(FT0, FT1, &env->fp_status);
+ RETURN();
+}
+
+void OPPROTO op_fdiv_DT(void)
+{
+ DT0 = float64_div(DT0, DT1, &env->fp_status);
+ RETURN();
+}
+
+void OPPROTO op_float_FT(void)
+{
+ FT0 = int32_to_float32(env->fpul, &env->fp_status);
+ RETURN();
+}
+
+void OPPROTO op_float_DT(void)
+{
+ DT0 = int32_to_float64(env->fpul, &env->fp_status);
+ RETURN();
+}
+
+void OPPROTO op_ftrc_FT(void)
+{
+ env->fpul = float32_to_int32_round_to_zero(FT0, &env->fp_status);
+ RETURN();
+}
+
+void OPPROTO op_ftrc_DT(void)
+{
+ env->fpul = float64_to_int32_round_to_zero(DT0, &env->fp_status);
+ RETURN();
+}
+
+void OPPROTO op_fmov_T0_frN(void)
+{
+ *(unsigned int *)&env->fregs[PARAM1] = T0;
+ RETURN();
+}
+
void OPPROTO op_dec1_rN(void)
{
env->gregs[PARAM1] -= 1;
Modified: trunk/src/host/qemu-neo1973/target-sh4/translate.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-sh4/translate.c 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/target-sh4/translate.c 2007-07-02 20:43:42 UTC (rev 2356)
@@ -125,13 +125,19 @@
void cpu_sh4_reset(CPUSH4State * env)
{
#if defined(CONFIG_USER_ONLY)
- env->sr = 0x00000000;
+ env->sr = SR_FD; /* FD - kernel does lazy fpu context switch */
#else
env->sr = 0x700000F0; /* MD, RB, BL, I3-I0 */
#endif
env->vbr = 0;
env->pc = 0xA0000000;
- env->fpscr = 0x00040001;
+#if defined(CONFIG_USER_ONLY)
+ env->fpscr = FPSCR_PR; /* value for userspace according to the kernel */
+ env->fp_status.float_rounding_mode = float_round_nearest_even; /* ?! */
+#else
+ env->fpscr = 0x00040001; /* CPU reset value according to SH4 manual */
+ env->fp_status.float_rounding_mode = float_round_to_zero;
+#endif
env->mmucr = 0;
}
@@ -238,6 +244,7 @@
#define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x))
#define XHACK(x) ((((x) & 1 ) << 4) | ((x) & 0xe))
#define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x))
+#define DREG(x) FREG(x) /* Assumes lsb of (x) is always 0 */
#define CHECK_NOT_DELAY_SLOT \
if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
@@ -640,29 +647,22 @@
gen_op_movl_rN_T0(REG(B7_4));
gen_op_xor_T0_rN(REG(B11_8));
return;
- case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn */
- if (ctx->fpscr & FPSCR_PR) {
- gen_op_fmov_drN_DT0(XREG(B7_4));
- gen_op_fmov_DT0_drN(XREG(B11_8));
- } else if (ctx->fpscr & FPSCR_SZ) {
+ case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn - FPSCR: Nothing */
+ if (ctx->fpscr & FPSCR_SZ) {
if (ctx->opcode & 0x0110)
break; /* illegal instruction */
- gen_op_fmov_drN_DT0(XREG(B7_4));
- gen_op_fmov_DT0_drN(XREG(B11_8));
+ gen_op_fmov_drN_DT0(DREG(B7_4));
+ gen_op_fmov_DT0_drN(DREG(B11_8));
} else {
gen_op_fmov_frN_FT0(FREG(B7_4));
gen_op_fmov_FT0_frN(FREG(B11_8));
}
return;
- case 0xf00a: /* fmov {F,D,X}Rm, at Rn */
- if (ctx->fpscr & FPSCR_PR) {
- gen_op_fmov_drN_DT0(XREG(B7_4));
- gen_op_movl_rN_T1(REG(B11_8));
- gen_op_stfq_DT0_T1(ctx);
- } else if (ctx->fpscr & FPSCR_SZ) {
+ case 0xf00a: /* fmov {F,D,X}Rm, at Rn - FPSCR: Nothing */
+ if (ctx->fpscr & FPSCR_SZ) {
if (ctx->opcode & 0x0010)
break; /* illegal instruction */
- gen_op_fmov_drN_DT0(XREG(B7_4));
+ gen_op_fmov_drN_DT0(DREG(B7_4));
gen_op_movl_rN_T1(REG(B11_8));
gen_op_stfq_DT0_T1(ctx);
} else {
@@ -671,35 +671,26 @@
gen_op_stfl_FT0_T1(ctx);
}
return;
- case 0xf008: /* fmov @Rm,{F,D,X}Rn */
- if (ctx->fpscr & FPSCR_PR) {
- gen_op_movl_rN_T0(REG(B7_4));
- gen_op_ldfq_T0_DT0(ctx);
- gen_op_fmov_DT0_drN(XREG(B11_8));
- } else if (ctx->fpscr & FPSCR_SZ) {
+ case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */
+ if (ctx->fpscr & FPSCR_SZ) {
if (ctx->opcode & 0x0100)
break; /* illegal instruction */
gen_op_movl_rN_T0(REG(B7_4));
gen_op_ldfq_T0_DT0(ctx);
- gen_op_fmov_DT0_drN(XREG(B11_8));
+ gen_op_fmov_DT0_drN(DREG(B11_8));
} else {
gen_op_movl_rN_T0(REG(B7_4));
gen_op_ldfl_T0_FT0(ctx);
gen_op_fmov_FT0_frN(FREG(B11_8));
}
return;
- case 0xf009: /* fmov @Rm+,{F,D,X}Rn */
- if (ctx->fpscr & FPSCR_PR) {
- gen_op_movl_rN_T0(REG(B7_4));
- gen_op_ldfq_T0_DT0(ctx);
- gen_op_fmov_DT0_drN(XREG(B11_8));
- gen_op_inc8_rN(REG(B7_4));
- } else if (ctx->fpscr & FPSCR_SZ) {
+ case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */
+ if (ctx->fpscr & FPSCR_SZ) {
if (ctx->opcode & 0x0100)
break; /* illegal instruction */
gen_op_movl_rN_T0(REG(B7_4));
gen_op_ldfq_T0_DT0(ctx);
- gen_op_fmov_DT0_drN(XREG(B11_8));
+ gen_op_fmov_DT0_drN(DREG(B11_8));
gen_op_inc8_rN(REG(B7_4));
} else {
gen_op_movl_rN_T0(REG(B7_4));
@@ -708,17 +699,12 @@
gen_op_inc4_rN(REG(B7_4));
}
return;
- case 0xf00b: /* fmov {F,D,X}Rm, at -Rn */
- if (ctx->fpscr & FPSCR_PR) {
- gen_op_dec8_rN(REG(B11_8));
- gen_op_fmov_drN_DT0(XREG(B7_4));
- gen_op_movl_rN_T1(REG(B11_8));
- gen_op_stfq_DT0_T1(ctx);
- } else if (ctx->fpscr & FPSCR_SZ) {
+ case 0xf00b: /* fmov {F,D,X}Rm, at -Rn - FPSCR: Nothing */
+ if (ctx->fpscr & FPSCR_SZ) {
if (ctx->opcode & 0x0100)
break; /* illegal instruction */
gen_op_dec8_rN(REG(B11_8));
- gen_op_fmov_drN_DT0(XREG(B7_4));
+ gen_op_fmov_drN_DT0(DREG(B7_4));
gen_op_movl_rN_T1(REG(B11_8));
gen_op_stfq_DT0_T1(ctx);
} else {
@@ -728,19 +714,14 @@
gen_op_stfl_FT0_T1(ctx);
}
return;
- case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm */
- if (ctx->fpscr & FPSCR_PR) {
- gen_op_movl_rN_T0(REG(B7_4));
- gen_op_add_rN_T0(REG(0));
- gen_op_ldfq_T0_DT0(ctx);
- gen_op_fmov_DT0_drN(XREG(B11_8));
- } else if (ctx->fpscr & FPSCR_SZ) {
+ case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */
+ if (ctx->fpscr & FPSCR_SZ) {
if (ctx->opcode & 0x0100)
break; /* illegal instruction */
gen_op_movl_rN_T0(REG(B7_4));
gen_op_add_rN_T0(REG(0));
gen_op_ldfq_T0_DT0(ctx);
- gen_op_fmov_DT0_drN(XREG(B11_8));
+ gen_op_fmov_DT0_drN(DREG(B11_8));
} else {
gen_op_movl_rN_T0(REG(B7_4));
gen_op_add_rN_T0(REG(0));
@@ -748,16 +729,11 @@
gen_op_fmov_FT0_frN(FREG(B11_8));
}
return;
- case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) */
- if (ctx->fpscr & FPSCR_PR) {
- gen_op_fmov_drN_DT0(XREG(B7_4));
- gen_op_movl_rN_T1(REG(B11_8));
- gen_op_add_rN_T1(REG(0));
- gen_op_stfq_DT0_T1(ctx);
- } else if (ctx->fpscr & FPSCR_SZ) {
+ case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) - FPSCR: Nothing */
+ if (ctx->fpscr & FPSCR_SZ) {
if (ctx->opcode & 0x0010)
break; /* illegal instruction */
- gen_op_fmov_drN_DT0(XREG(B7_4));
+ gen_op_fmov_drN_DT0(DREG(B7_4));
gen_op_movl_rN_T1(REG(B11_8));
gen_op_add_rN_T1(REG(0));
gen_op_stfq_DT0_T1(ctx);
@@ -768,6 +744,49 @@
gen_op_stfl_FT0_T1(ctx);
}
return;
+ case 0xf000: /* fadd Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
+ case 0xf001: /* fsub Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
+ case 0xf002: /* fmul Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
+ case 0xf003: /* fdiv Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
+ case 0xf004: /* fcmp/eq Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
+ case 0xf005: /* fcmp/gt Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
+ if (ctx->fpscr & FPSCR_PR) {
+ if (ctx->opcode & 0x0110)
+ break; /* illegal instruction */
+ gen_op_fmov_drN_DT1(DREG(B7_4));
+ gen_op_fmov_drN_DT0(DREG(B11_8));
+ }
+ else {
+ gen_op_fmov_frN_FT1(FREG(B7_4));
+ gen_op_fmov_frN_FT0(FREG(B11_8));
+ }
+
+ switch (ctx->opcode & 0xf00f) {
+ case 0xf000: /* fadd Rm,Rn */
+ ctx->fpscr & FPSCR_PR ? gen_op_fadd_DT() : gen_op_fadd_FT();
+ break;
+ case 0xf001: /* fsub Rm,Rn */
+ ctx->fpscr & FPSCR_PR ? gen_op_fsub_DT() : gen_op_fsub_FT();
+ break;
+ case 0xf002: /* fmul Rm,Rn */
+ ctx->fpscr & FPSCR_PR ? gen_op_fmul_DT() : gen_op_fmul_FT();
+ break;
+ case 0xf003: /* fdiv Rm,Rn */
+ ctx->fpscr & FPSCR_PR ? gen_op_fdiv_DT() : gen_op_fdiv_FT();
+ break;
+ case 0xf004: /* fcmp/eq Rm,Rn */
+ return;
+ case 0xf005: /* fcmp/gt Rm,Rn */
+ return;
+ }
+
+ if (ctx->fpscr & FPSCR_PR) {
+ gen_op_fmov_DT0_drN(DREG(B11_8));
+ }
+ else {
+ gen_op_fmov_FT0_frN(FREG(B11_8));
+ }
+ return;
}
switch (ctx->opcode & 0xff00) {
@@ -1071,14 +1090,52 @@
case 0x401b: /* tas.b @Rn */
gen_op_tasb_rN(REG(B11_8));
return;
- case 0xf00d: /* fsts FPUL,FRn */
+ case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */
gen_op_movl_fpul_FT0();
gen_op_fmov_FT0_frN(FREG(B11_8));
return;
- case 0xf01d: /* flds FRm.FPUL */
+ case 0xf01d: /* flds FRm,FPUL - FPSCR: Nothing */
gen_op_fmov_frN_FT0(FREG(B11_8));
gen_op_movl_FT0_fpul();
return;
+ case 0xf02d: /* float FPUL,FRn/DRn - FPSCR: R[PR,Enable.I]/W[Cause,Flag] */
+ if (ctx->fpscr & FPSCR_PR) {
+ if (ctx->opcode & 0x0100)
+ break; /* illegal instruction */
+ gen_op_float_DT();
+ gen_op_fmov_DT0_drN(DREG(B11_8));
+ }
+ else {
+ gen_op_float_FT();
+ gen_op_fmov_FT0_frN(FREG(B11_8));
+ }
+ return;
+ case 0xf03d: /* ftrc FRm/DRm,FPUL - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
+ if (ctx->fpscr & FPSCR_PR) {
+ if (ctx->opcode & 0x0100)
+ break; /* illegal instruction */
+ gen_op_fmov_drN_DT0(DREG(B11_8));
+ gen_op_ftrc_DT();
+ }
+ else {
+ gen_op_fmov_frN_FT0(FREG(B11_8));
+ gen_op_ftrc_FT();
+ }
+ return;
+ case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */
+ if (!(ctx->fpscr & FPSCR_PR)) {
+ gen_op_movl_imm_T0(0);
+ gen_op_fmov_T0_frN(FREG(B11_8));
+ return;
+ }
+ break;
+ case 0xf09d: /* fldi1 FRn - FPSCR: R[PR] */
+ if (!(ctx->fpscr & FPSCR_PR)) {
+ gen_op_movl_imm_T0(0x3f800000);
+ gen_op_fmov_T0_frN(FREG(B11_8));
+ return;
+ }
+ break;
}
fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
Modified: trunk/src/host/qemu-neo1973/target-sparc/translate.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-sparc/translate.c 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/target-sparc/translate.c 2007-07-02 20:43:42 UTC (rev 2356)
@@ -598,7 +598,8 @@
}
}
-static inline void gen_branch2(DisasContext *dc, long tb, target_ulong pc1, target_ulong pc2)
+static inline void gen_branch2(DisasContext *dc, target_ulong pc1,
+ target_ulong pc2)
{
int l1;
@@ -612,7 +613,8 @@
gen_goto_tb(dc, 1, pc2, pc2 + 4);
}
-static inline void gen_branch_a(DisasContext *dc, long tb, target_ulong pc1, target_ulong pc2)
+static inline void gen_branch_a(DisasContext *dc, target_ulong pc1,
+ target_ulong pc2)
{
int l1;
@@ -626,12 +628,13 @@
gen_goto_tb(dc, 1, pc2 + 4, pc2 + 8);
}
-static inline void gen_branch(DisasContext *dc, long tb, target_ulong pc, target_ulong npc)
+static inline void gen_branch(DisasContext *dc, target_ulong pc,
+ target_ulong npc)
{
gen_goto_tb(dc, 0, pc, npc);
}
-static inline void gen_generic_branch(DisasContext *dc, target_ulong npc1, target_ulong npc2)
+static inline void gen_generic_branch(target_ulong npc1, target_ulong npc2)
{
int l1, l2;
@@ -651,7 +654,7 @@
static inline void flush_T2(DisasContext * dc)
{
if (dc->npc == JUMP_PC) {
- gen_generic_branch(dc, dc->jump_pc[0], dc->jump_pc[1]);
+ gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1]);
dc->npc = DYNAMIC_PC;
}
}
@@ -659,7 +662,7 @@
static inline void save_npc(DisasContext * dc)
{
if (dc->npc == JUMP_PC) {
- gen_generic_branch(dc, dc->jump_pc[0], dc->jump_pc[1]);
+ gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1]);
dc->npc = DYNAMIC_PC;
} else if (dc->npc != DYNAMIC_PC) {
gen_movl_npc_im(dc->npc);
@@ -675,7 +678,7 @@
static inline void gen_mov_pc_npc(DisasContext * dc)
{
if (dc->npc == JUMP_PC) {
- gen_generic_branch(dc, dc->jump_pc[0], dc->jump_pc[1]);
+ gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1]);
gen_op_mov_pc_npc();
dc->pc = DYNAMIC_PC;
} else if (dc->npc == DYNAMIC_PC) {
@@ -861,7 +864,7 @@
flush_T2(dc);
gen_cond[cc][cond]();
if (a) {
- gen_branch_a(dc, (long)dc->tb, target, dc->npc);
+ gen_branch_a(dc, target, dc->npc);
dc->is_br = 1;
} else {
dc->pc = dc->npc;
@@ -900,7 +903,7 @@
flush_T2(dc);
gen_fcond[cc][cond]();
if (a) {
- gen_branch_a(dc, (long)dc->tb, target, dc->npc);
+ gen_branch_a(dc, target, dc->npc);
dc->is_br = 1;
} else {
dc->pc = dc->npc;
@@ -921,7 +924,7 @@
flush_T2(dc);
gen_cond_reg(cond);
if (a) {
- gen_branch_a(dc, (long)dc->tb, target, dc->npc);
+ gen_branch_a(dc, target, dc->npc);
dc->is_br = 1;
} else {
dc->pc = dc->npc;
@@ -3123,7 +3126,7 @@
gen_op_next_insn();
} else if (dc->npc == JUMP_PC) {
/* we can do a static jump */
- gen_branch2(dc, (long)dc->tb, dc->jump_pc[0], dc->jump_pc[1]);
+ gen_branch2(dc, dc->jump_pc[0], dc->jump_pc[1]);
dc->is_br = 1;
} else {
dc->pc = dc->npc;
@@ -3249,7 +3252,7 @@
if (dc->pc != DYNAMIC_PC &&
(dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
/* static PC and NPC: we can use direct chaining */
- gen_branch(dc, (long)tb, dc->pc, dc->npc);
+ gen_branch(dc, dc->pc, dc->npc);
} else {
if (dc->pc != DYNAMIC_PC)
gen_jmp_im(dc->pc);
Modified: trunk/src/host/qemu-neo1973/vl.c
===================================================================
--- trunk/src/host/qemu-neo1973/vl.c 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/vl.c 2007-07-02 20:43:42 UTC (rev 2356)
@@ -47,6 +47,8 @@
#ifndef __APPLE__
#include <libutil.h>
#endif
+#elif defined (__GLIBC__) && defined (__FreeBSD_kernel__)
+#include <freebsd/stdlib.h>
#else
#ifndef __sun__
#include <linux/if.h>
@@ -196,6 +198,7 @@
int semihosting_enabled = 0;
int autostart = 1;
const char *qemu_name;
+int alt_grab = 0;
#ifdef TARGET_SPARC
unsigned int nb_prom_envs = 0;
const char *prom_envs[MAX_PROM_ENVS];
@@ -203,6 +206,8 @@
struct bt_piconet_s *local_piconet;
struct modem_ops_s modem_ops;
+#define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
+
/***********************************************************/
/* x86 ISA bus support */
@@ -1028,7 +1033,7 @@
static int start_rtc_timer(void)
{
- rtc_fd = open("/dev/rtc", O_RDONLY);
+ TFR(rtc_fd = open("/dev/rtc", O_RDONLY));
if (rtc_fd < 0)
return -1;
if (ioctl(rtc_fd, RTC_IRQP_SET, RTC_FREQ) < 0) {
@@ -1639,7 +1644,7 @@
{
int fd_out;
- fd_out = open(file_out, O_WRONLY | O_TRUNC | O_CREAT | O_BINARY, 0666);
+ TFR(fd_out = open(file_out, O_WRONLY | O_TRUNC | O_CREAT | O_BINARY, 0666));
if (fd_out < 0)
return NULL;
return qemu_chr_open_fd(-1, fd_out);
@@ -1652,14 +1657,14 @@
snprintf(filename_in, 256, "%s.in", filename);
snprintf(filename_out, 256, "%s.out", filename);
- fd_in = open(filename_in, O_RDWR | O_BINARY);
- fd_out = open(filename_out, O_RDWR | O_BINARY);
+ TFR(fd_in = open(filename_in, O_RDWR | O_BINARY));
+ TFR(fd_out = open(filename_out, O_RDWR | O_BINARY));
if (fd_in < 0 || fd_out < 0) {
if (fd_in >= 0)
close(fd_in);
if (fd_out >= 0)
close(fd_out);
- fd_in = fd_out = open(filename, O_RDWR | O_BINARY);
+ TFR(fd_in = fd_out = open(filename, O_RDWR | O_BINARY));
if (fd_in < 0)
return NULL;
}
@@ -1763,17 +1768,19 @@
return chr;
}
-#if defined(__linux__)
+#if defined(__linux__) || defined(__sun__)
static CharDriverState *qemu_chr_open_pty(void)
{
struct termios tty;
char slave_name[1024];
int master_fd, slave_fd;
+#if defined(__linux__)
/* Not satisfying */
if (openpty(&master_fd, &slave_fd, slave_name, NULL, NULL) < 0) {
return NULL;
}
+#endif
/* Disabling local echo and line-buffered output */
tcgetattr (master_fd, &tty);
@@ -1908,19 +1915,26 @@
CharDriverState *chr;
int fd;
- fd = open(filename, O_RDWR | O_NONBLOCK);
- if (fd < 0)
- return NULL;
+ TFR(fd = open(filename, O_RDWR | O_NONBLOCK));
fcntl(fd, F_SETFL, O_NONBLOCK);
tty_serial_init(fd, 115200, 'N', 8, 1);
chr = qemu_chr_open_fd(fd, fd);
- if (!chr)
+ if (!chr) {
+ close(fd);
return NULL;
+ }
chr->chr_ioctl = tty_serial_ioctl;
qemu_chr_reset(chr);
return chr;
}
+#else /* ! __linux__ && ! __sun__ */
+static CharDriverState *qemu_chr_open_pty(void)
+{
+ return NULL;
+}
+#endif /* __linux__ || __sun__ */
+#if defined(__linux__)
typedef struct {
int fd;
int mode;
@@ -2031,7 +2045,7 @@
ParallelCharDriver *drv;
int fd;
- fd = open(filename, O_RDWR);
+ TFR(fd = open(filename, O_RDWR));
if (fd < 0)
return NULL;
@@ -2063,17 +2077,10 @@
return chr;
}
+#endif /* __linux__ */
-#else
-static CharDriverState *qemu_chr_open_pty(void)
-{
- return NULL;
-}
-#endif
+#else /* _WIN32 */
-#endif /* !defined(_WIN32) */
-
-#ifdef _WIN32
typedef struct {
int max_size;
HANDLE hcom, hrecv, hsend;
@@ -2439,7 +2446,7 @@
return qemu_chr_open_win_file(fd_out);
}
-#endif
+#endif /* !_WIN32 */
/***********************************************************/
/* UDP Net console */
@@ -2953,16 +2960,17 @@
} else if (!strcmp(filename, "stdio")) {
return qemu_chr_open_stdio();
} else
-#endif
#if defined(__linux__)
if (strstart(filename, "/dev/parport", NULL)) {
return qemu_chr_open_pp(filename);
} else
+#endif
+#if defined(__linux__) || defined(__sun__)
if (strstart(filename, "/dev/", NULL)) {
return qemu_chr_open_tty(filename);
- } else
+ } else
#endif
-#ifdef _WIN32
+#else /* !_WIN32 */
if (strstart(filename, "COM", NULL)) {
return qemu_chr_open_win(filename);
} else
@@ -3191,11 +3199,11 @@
for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
if (vc != vc1) {
- if (vc->fd_can_read && !vc->fd_can_read(vc->opaque))
- return 0;
+ if (vc->fd_can_read && vc->fd_can_read(vc->opaque))
+ return 1;
}
}
- return 1;
+ return 0;
}
void qemu_send_packet(VLANClientState *vc1, const uint8_t *buf, int size)
@@ -3452,14 +3460,14 @@
return s;
}
-#ifdef _BSD
+#if defined (_BSD) || defined (__FreeBSD_kernel__)
static int tap_open(char *ifname, int ifname_size)
{
int fd;
char *dev;
struct stat s;
- fd = open("/dev/tap", O_RDWR);
+ TFR(fd = open("/dev/tap", O_RDWR));
if (fd < 0) {
fprintf(stderr, "warning: could not open /dev/tap: no virtual network emulation\n");
return -1;
@@ -3503,12 +3511,14 @@
if( ip_fd )
close(ip_fd);
- if( (ip_fd = open("/dev/udp", O_RDWR, 0)) < 0){
+ TFR(ip_fd = open("/dev/udp", O_RDWR, 0));
+ if (ip_fd < 0) {
syslog(LOG_ERR, "Can't open /dev/ip (actually /dev/udp)");
return -1;
}
- if( (tap_fd = open("/dev/tap", O_RDWR, 0)) < 0){
+ TFR(tap_fd = open("/dev/tap", O_RDWR, 0));
+ if (tap_fd < 0) {
syslog(LOG_ERR, "Can't open /dev/tap");
return -1;
}
@@ -3521,7 +3531,8 @@
if ((ppa = ioctl (tap_fd, I_STR, &strioc_ppa)) < 0)
syslog (LOG_ERR, "Can't assign new interface");
- if( (if_fd = open("/dev/tap", O_RDWR, 0)) < 0){
+ TFR(if_fd = open("/dev/tap", O_RDWR, 0));
+ if (if_fd < 0) {
syslog(LOG_ERR, "Can't open /dev/tap (2)");
return -1;
}
@@ -3553,7 +3564,8 @@
if (ioctl (ip_fd, I_PUSH, "arp") < 0)
syslog (LOG_ERR, "Can't push ARP module (3)\n");
/* Open arp_fd */
- if ((arp_fd = open ("/dev/tap", O_RDWR, 0)) < 0)
+ TFR(arp_fd = open ("/dev/tap", O_RDWR, 0));
+ if (arp_fd < 0)
syslog (LOG_ERR, "Can't open %s\n", "/dev/tap");
/* Set ifname to arp */
@@ -3609,7 +3621,7 @@
struct ifreq ifr;
int fd, ret;
- fd = open("/dev/net/tun", O_RDWR);
+ TFR(fd = open("/dev/net/tun", O_RDWR));
if (fd < 0) {
fprintf(stderr, "warning: could not open /dev/net/tun: no virtual network emulation\n");
return -1;
@@ -3645,7 +3657,7 @@
pstrcpy(ifname, sizeof(ifname), ifname1);
else
ifname[0] = '\0';
- fd = tap_open(ifname, sizeof(ifname));
+ TFR(fd = tap_open(ifname, sizeof(ifname)));
if (fd < 0)
return -1;
@@ -4712,6 +4724,34 @@
}
/***********************************************************/
+/* dumb display */
+
+static void dumb_update(DisplayState *ds, int x, int y, int w, int h)
+{
+}
+
+static void dumb_resize(DisplayState *ds, int w, int h)
+{
+}
+
+static void dumb_refresh(DisplayState *ds)
+{
+#if defined(CONFIG_SDL)
+ vga_hw_update();
+#endif
+}
+
+static void dumb_display_init(DisplayState *ds)
+{
+ ds->data = NULL;
+ ds->linesize = 0;
+ ds->depth = 0;
+ ds->dpy_update = dumb_update;
+ ds->dpy_resize = dumb_resize;
+ ds->dpy_refresh = dumb_refresh;
+}
+
+/***********************************************************/
/* I/O handling */
#define MAX_IO_HANDLERS 64
@@ -5900,6 +5940,7 @@
qemu_put_be32(f, env->cp15.c0_cachetype);
qemu_put_be32(f, env->cp15.c1_sys);
qemu_put_be32(f, env->cp15.c1_coproc);
+ qemu_put_be32(f, env->cp15.c1_xscaleauxcr);
qemu_put_be32(f, env->cp15.c2_base);
qemu_put_be32(f, env->cp15.c2_data);
qemu_put_be32(f, env->cp15.c2_insn);
@@ -5971,6 +6012,7 @@
env->cp15.c0_cachetype = qemu_get_be32(f);
env->cp15.c1_sys = qemu_get_be32(f);
env->cp15.c1_coproc = qemu_get_be32(f);
+ env->cp15.c1_xscaleauxcr = qemu_get_be32(f);
env->cp15.c2_base = qemu_get_be32(f);
env->cp15.c2_data = qemu_get_be32(f);
env->cp15.c2_insn = qemu_get_be32(f);
@@ -6524,8 +6566,6 @@
shutdown_requested = 1;
if (cpu_single_env)
cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
- /* In case the emulation is stopped */
- vm_start();
}
void qemu_system_powerdown_request(void)
@@ -6750,7 +6790,7 @@
return ret;
}
-void help(void)
+static void help(int exitcode)
{
printf("QEMU PC emulator version " QEMU_VERSION ", Copyright (c) 2003-2007 Fabrice Bellard\n"
"usage: %s [options] [disk_image]\n"
@@ -6771,6 +6811,7 @@
"-snapshot write to temporary files instead of disk image files\n"
#ifdef CONFIG_SDL
"-no-frame open SDL window without a frame and window decorations\n"
+ "-alt-grab use Ctrl-Alt-Shift to grab mouse (instead of Ctrl-Alt)\n"
"-no-quit disable SDL window close capability\n"
#endif
#ifdef TARGET_I386
@@ -6892,7 +6933,7 @@
#endif
DEFAULT_GDBSTUB_PORT,
"/tmp/qemu.log");
- exit(1);
+ exit(exitcode);
}
#define HAS_ARG 0x0001
@@ -6955,6 +6996,7 @@
QEMU_OPTION_loadvm,
QEMU_OPTION_full_screen,
QEMU_OPTION_no_frame,
+ QEMU_OPTION_alt_grab,
QEMU_OPTION_no_quit,
QEMU_OPTION_pidfile,
QEMU_OPTION_no_kqemu,
@@ -7041,14 +7083,15 @@
#endif
{ "localtime", 0, QEMU_OPTION_localtime },
{ "std-vga", 0, QEMU_OPTION_std_vga },
- { "echr", 1, QEMU_OPTION_echr },
- { "monitor", 1, QEMU_OPTION_monitor },
- { "serial", 1, QEMU_OPTION_serial },
- { "parallel", 1, QEMU_OPTION_parallel },
+ { "echr", HAS_ARG, QEMU_OPTION_echr },
+ { "monitor", HAS_ARG, QEMU_OPTION_monitor },
+ { "serial", HAS_ARG, QEMU_OPTION_serial },
+ { "parallel", HAS_ARG, QEMU_OPTION_parallel },
{ "loadvm", HAS_ARG, QEMU_OPTION_loadvm },
{ "full-screen", 0, QEMU_OPTION_full_screen },
#ifdef CONFIG_SDL
{ "no-frame", 0, QEMU_OPTION_no_frame },
+ { "alt-grab", 0, QEMU_OPTION_alt_grab },
{ "no-quit", 0, QEMU_OPTION_no_quit },
#endif
{ "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
@@ -7465,12 +7508,12 @@
m->name, m->desc,
m == first_machine ? " (default)" : "");
}
- exit(1);
+ exit(*optarg != '?');
}
break;
case QEMU_OPTION_cpu:
/* hw initialization will check this */
- if (optarg[0] == '?') {
+ if (*optarg == '?') {
#if defined(TARGET_PPC)
ppc_cpu_list(stdout, &fprintf);
#elif defined(TARGET_ARM)
@@ -7480,7 +7523,7 @@
#elif defined(TARGET_SPARC)
sparc_cpu_list(stdout, &fprintf);
#endif
- exit(1);
+ exit(0);
} else {
cpu_model = optarg;
}
@@ -7634,12 +7677,12 @@
break;
#endif
case QEMU_OPTION_h:
- help();
+ help(0);
break;
case QEMU_OPTION_m:
ram_size = atoi(optarg) * 1024 * 1024;
if (ram_size <= 0)
- help();
+ help(1);
if (ram_size > PHYS_RAM_MAX_SIZE) {
fprintf(stderr, "qemu: at most %d MB RAM can be simulated\n",
PHYS_RAM_MAX_SIZE / (1024 * 1024));
@@ -7767,6 +7810,9 @@
case QEMU_OPTION_no_frame:
no_frame = 1;
break;
+ case QEMU_OPTION_alt_grab:
+ alt_grab = 1;
+ break;
case QEMU_OPTION_no_quit:
no_quit = 1;
break;
@@ -7925,7 +7971,7 @@
hd_filename[0] == '\0' &&
(cdrom_index >= 0 && hd_filename[cdrom_index] == '\0') &&
fd_filename[0] == '\0')
- help();
+ help(1);
/* boot to floppy or the default cd if no hard disk defined yet */
if (hd_filename[0] == '\0' && boot_device == 'c') {
@@ -8103,7 +8149,8 @@
/* terminal init */
memset(&display_state, 0, sizeof(display_state));
if (nographic) {
- /* nothing to do */
+ /* nearly nothing to do */
+ dumb_display_init(ds);
} else if (vnc_display != NULL) {
vnc_display_init(ds, vnc_display);
} else {
@@ -8200,8 +8247,9 @@
gdbstub_port);
exit(1);
}
- } else
+ }
#endif
+
if (loadvm)
do_loadvm(loadvm);
@@ -8226,7 +8274,7 @@
if (len != 1)
exit(1);
- fd = open("/dev/null", O_RDWR);
+ TFR(fd = open("/dev/null", O_RDWR));
if (fd == -1)
exit(1);
Modified: trunk/src/host/qemu-neo1973/vl.h
===================================================================
--- trunk/src/host/qemu-neo1973/vl.h 2007-07-01 11:01:12 UTC (rev 2355)
+++ trunk/src/host/qemu-neo1973/vl.h 2007-07-02 20:43:42 UTC (rev 2356)
@@ -156,6 +156,7 @@
extern const char *keyboard_layout;
extern int kqemu_allowed;
extern int win2k_install_hack;
+extern int alt_grab;
extern int usb_enabled;
extern int smp_cpus;
extern int cursor_hide;
@@ -1091,6 +1092,7 @@
typedef struct ParallelState ParallelState;
ParallelState *parallel_init(int base, qemu_irq irq, CharDriverState *chr);
+ParallelState *parallel_mm_init(target_phys_addr_t base, int it_shift, qemu_irq irq, CharDriverState *chr);
/* i8259.c */
@@ -1128,6 +1130,9 @@
int pit_get_mode(PITState *pit, int channel);
int pit_get_out(PITState *pit, int channel, int64_t current_time);
+/* jazz_led.c */
+extern void jazz_led_init(DisplayState *ds, target_phys_addr_t base);
+
/* pcspk.c */
void pcspk_init(PITState *);
int pcspk_audio_init(AudioState *, qemu_irq *pic);
@@ -1440,6 +1445,9 @@
/* smc91c111.c */
void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
+/* pl031.c */
+void pl031_init(uint32_t base, qemu_irq irq);
+
/* pl110.c */
void *pl110_init(DisplayState *ds, uint32_t base, qemu_irq irq, int);
More information about the commitlog
mailing list