r3665 - in trunk/src/host/qemu-neo1973: . audio hw linux-user pc-bios target-sparc

andrew at sita.openmoko.org andrew at sita.openmoko.org
Mon Dec 17 18:53:19 CET 2007


Author: andrew
Date: 2007-12-17 18:52:55 +0100 (Mon, 17 Dec 2007)
New Revision: 3665

Added:
   trunk/src/host/qemu-neo1973/block-raw-posix.c
   trunk/src/host/qemu-neo1973/block-raw-win32.c
   trunk/src/host/qemu-neo1973/hw/pxa2xx_keypad.c
Removed:
   trunk/src/host/qemu-neo1973/block-raw.c
Modified:
   trunk/src/host/qemu-neo1973/Makefile
   trunk/src/host/qemu-neo1973/Makefile.target
   trunk/src/host/qemu-neo1973/audio/alsaaudio.c
   trunk/src/host/qemu-neo1973/block-vpc.c
   trunk/src/host/qemu-neo1973/block-vvfat.c
   trunk/src/host/qemu-neo1973/cpu-all.h
   trunk/src/host/qemu-neo1973/cpu-exec.c
   trunk/src/host/qemu-neo1973/exec-all.h
   trunk/src/host/qemu-neo1973/exec.c
   trunk/src/host/qemu-neo1973/gdbstub.c
   trunk/src/host/qemu-neo1973/hw/acpi.c
   trunk/src/host/qemu-neo1973/hw/apic.c
   trunk/src/host/qemu-neo1973/hw/boards.h
   trunk/src/host/qemu-neo1973/hw/cirrus_vga.c
   trunk/src/host/qemu-neo1973/hw/dma.c
   trunk/src/host/qemu-neo1973/hw/fdc.c
   trunk/src/host/qemu-neo1973/hw/i8254.c
   trunk/src/host/qemu-neo1973/hw/ide.c
   trunk/src/host/qemu-neo1973/hw/mainstone.c
   trunk/src/host/qemu-neo1973/hw/mc146818rtc.c
   trunk/src/host/qemu-neo1973/hw/ne2000.c
   trunk/src/host/qemu-neo1973/hw/pc.c
   trunk/src/host/qemu-neo1973/hw/pcnet.c
   trunk/src/host/qemu-neo1973/hw/ps2.c
   trunk/src/host/qemu-neo1973/hw/pxa.h
   trunk/src/host/qemu-neo1973/hw/pxa2xx.c
   trunk/src/host/qemu-neo1973/hw/rtl8139.c
   trunk/src/host/qemu-neo1973/hw/sb16.c
   trunk/src/host/qemu-neo1973/hw/sh.h
   trunk/src/host/qemu-neo1973/hw/sh7750.c
   trunk/src/host/qemu-neo1973/hw/sh_serial.c
   trunk/src/host/qemu-neo1973/hw/sh_timer.c
   trunk/src/host/qemu-neo1973/hw/slavio_serial.c
   trunk/src/host/qemu-neo1973/hw/sun4m.c
   trunk/src/host/qemu-neo1973/hw/usb-uhci.c
   trunk/src/host/qemu-neo1973/hw/vga.c
   trunk/src/host/qemu-neo1973/hw/vmware_vga.c
   trunk/src/host/qemu-neo1973/linux-user/main.c
   trunk/src/host/qemu-neo1973/linux-user/mmap.c
   trunk/src/host/qemu-neo1973/linux-user/syscall.c
   trunk/src/host/qemu-neo1973/monitor.c
   trunk/src/host/qemu-neo1973/osdep.h
   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/target-sparc/op.c
   trunk/src/host/qemu-neo1973/target-sparc/op_helper.c
   trunk/src/host/qemu-neo1973/translate-all.c
   trunk/src/host/qemu-neo1973/vl.c
   trunk/src/host/qemu-neo1973/vnc.c
   trunk/src/host/qemu-neo1973/vnchextile.h
Log:
Merge cvs.savannah.nongnu.org:/sources/qemu.


Modified: trunk/src/host/qemu-neo1973/Makefile
===================================================================
--- trunk/src/host/qemu-neo1973/Makefile	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/Makefile	2007-12-17 17:52:55 UTC (rev 3665)
@@ -121,9 +121,16 @@
 	rm -f $@ 
 	$(AR) rcs $@ $(OBJS)
 
+QEMU_IMG_BLOCK_OBJS = $(BLOCK_OBJS)
+ifdef CONFIG_WIN32
+QEMU_IMG_BLOCK_OBJS += qemu-img-block-raw-win32.o
+else
+QEMU_IMG_BLOCK_OBJS += qemu-img-block-raw-posix.o
+endif
+
 ######################################################################
 
-qemu-img$(EXESUF): qemu-img.o qemu-img-block.o qemu-img-block-raw.o $(BLOCK_OBJS)
+qemu-img$(EXESUF): qemu-img.o qemu-img-block.o $(QEMU_IMG_BLOCK_OBJS)
 	$(CC) $(LDFLAGS) $(BASE_LDFLAGS) -o $@ $^ -lz $(LIBS)
 
 qemu-img-%.o: %.c

Modified: trunk/src/host/qemu-neo1973/Makefile.target
===================================================================
--- trunk/src/host/qemu-neo1973/Makefile.target	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/Makefile.target	2007-12-17 17:52:55 UTC (rev 3665)
@@ -161,7 +161,7 @@
     OP_CFLAGS+=-fno-omit-frame-pointer
   else
     BASE_CFLAGS+=-ffixed-g1 -ffixed-g6
-    HELPER_CFLAGS=$(CFLAGS) -ffixed-i0 -mflat
+    HELPER_CFLAGS=$(CFLAGS) -ffixed-i0
     # -static is used to avoid g1/g3 usage by the dynamic linker
     BASE_LDFLAGS+=-Wl,-T,$(SRC_PATH)/$(ARCH).ld -static
   endif
@@ -398,7 +398,11 @@
 # must use static linking to avoid leaving stuff in virtual address space
 VL_OBJS=vl.o osdep.o monitor.o pci.o loader.o isa_mmio.o
 # XXX: suppress QEMU_TOOL tests
-VL_OBJS+=block-raw.o
+ifdef CONFIG_WIN32
+VL_OBJS+=block-raw-win32.o
+else
+VL_OBJS+=block-raw-posix.o
+endif
 
 ifdef CONFIG_ALSA
 LIBS += -lasound
@@ -502,7 +506,7 @@
 VL_OBJS+= pl061.o
 VL_OBJS+= arm-semi.o
 VL_OBJS+= pxa2xx.o pxa2xx_pic.o pxa2xx_gpio.o pxa2xx_timer.o pxa2xx_dma.o
-VL_OBJS+= pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o
+VL_OBJS+= pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o pxa2xx_keypad.o
 VL_OBJS+= pflash_cfi01.o gumstix.o
 VL_OBJS+= spitz.o ide.o serial.o nand.o ecc.o
 VL_OBJS+= s3c2410.o s3c24xx_gpio.o s3c24xx_lcd.o s3c24xx_mmci.o s3c24xx_rtc.o

Modified: trunk/src/host/qemu-neo1973/audio/alsaaudio.c
===================================================================
--- trunk/src/host/qemu-neo1973/audio/alsaaudio.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/audio/alsaaudio.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -86,9 +86,9 @@
 };
 
 struct alsa_params_req {
-    int freq;
+    unsigned int freq;
     audfmt_e fmt;
-    int nchannels;
+    unsigned int nchannels;
     unsigned int buffer_size;
     unsigned int period_size;
 };
@@ -285,7 +285,8 @@
 {
     snd_pcm_t *handle;
     snd_pcm_hw_params_t *hw_params;
-    int err, freq, nchannels;
+    int err;
+    unsigned int freq, nchannels;
     const char *pcm_name = in ? conf.pcm_name_in : conf.pcm_name_out;
     unsigned int period_size, buffer_size;
     snd_pcm_uframes_t obt_buffer_size;

Added: trunk/src/host/qemu-neo1973/block-raw-posix.c
===================================================================
--- trunk/src/host/qemu-neo1973/block-raw-posix.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/block-raw-posix.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -0,0 +1,901 @@
+/*
+ * Block driver for RAW files (posix)
+ *
+ * Copyright (c) 2006 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "qemu-common.h"
+#ifndef QEMU_IMG
+#include "qemu-timer.h"
+#include "exec-all.h"
+#endif
+#include "block_int.h"
+#include <assert.h>
+#include <aio.h>
+
+#ifdef CONFIG_COCOA
+#include <paths.h>
+#include <sys/param.h>
+#include <IOKit/IOKitLib.h>
+#include <IOKit/IOBSD.h>
+#include <IOKit/storage/IOMediaBSDClient.h>
+#include <IOKit/storage/IOMedia.h>
+#include <IOKit/storage/IOCDMedia.h>
+//#include <IOKit/storage/IOCDTypes.h>
+#include <CoreFoundation/CoreFoundation.h>
+#endif
+
+#ifdef __sun__
+#define _POSIX_PTHREAD_SEMANTICS 1
+#include <signal.h>
+#include <sys/dkio.h>
+#endif
+#ifdef __linux__
+#include <sys/ioctl.h>
+#include <linux/cdrom.h>
+#include <linux/fd.h>
+#endif
+#ifdef __FreeBSD__
+#include <sys/disk.h>
+#endif
+
+//#define DEBUG_FLOPPY
+
+//#define DEBUG_BLOCK
+#if defined(DEBUG_BLOCK) && !defined(QEMU_IMG)
+#define DEBUG_BLOCK_PRINT(formatCstr, args...) do { if (loglevel != 0)	\
+    { fprintf(logfile, formatCstr, ##args); fflush(logfile); } } while (0)
+#else
+#define DEBUG_BLOCK_PRINT(formatCstr, args...)
+#endif
+
+#define FTYPE_FILE   0
+#define FTYPE_CD     1
+#define FTYPE_FD     2
+
+/* if the FD is not accessed during that time (in ms), we try to
+   reopen it to see if the disk has been changed */
+#define FD_OPEN_TIMEOUT 1000
+
+typedef struct BDRVRawState {
+    int fd;
+    int type;
+    unsigned int lseek_err_cnt;
+#if defined(__linux__)
+    /* linux floppy specific */
+    int fd_open_flags;
+    int64_t fd_open_time;
+    int64_t fd_error_time;
+    int fd_got_error;
+    int fd_media_changed;
+#endif
+} BDRVRawState;
+
+static int fd_open(BlockDriverState *bs);
+
+static int raw_open(BlockDriverState *bs, const char *filename, int flags)
+{
+    BDRVRawState *s = bs->opaque;
+    int fd, open_flags, ret;
+
+    s->lseek_err_cnt = 0;
+
+    open_flags = O_BINARY;
+    if ((flags & BDRV_O_ACCESS) == O_RDWR) {
+        open_flags |= O_RDWR;
+    } else {
+        open_flags |= O_RDONLY;
+        bs->read_only = 1;
+    }
+    if (flags & BDRV_O_CREAT)
+        open_flags |= O_CREAT | O_TRUNC;
+
+    s->type = FTYPE_FILE;
+
+    fd = open(filename, open_flags, 0644);
+    if (fd < 0) {
+        ret = -errno;
+        if (ret == -EROFS)
+            ret = -EACCES;
+        return ret;
+    }
+    s->fd = fd;
+    return 0;
+}
+
+/* XXX: use host sector size if necessary with:
+#ifdef DIOCGSECTORSIZE
+        {
+            unsigned int sectorsize = 512;
+            if (!ioctl(fd, DIOCGSECTORSIZE, &sectorsize) &&
+                sectorsize > bufsize)
+                bufsize = sectorsize;
+        }
+#endif
+#ifdef CONFIG_COCOA
+        u_int32_t   blockSize = 512;
+        if ( !ioctl( fd, DKIOCGETBLOCKSIZE, &blockSize ) && blockSize > bufsize) {
+            bufsize = blockSize;
+        }
+#endif
+*/
+
+static int raw_pread(BlockDriverState *bs, int64_t offset,
+                     uint8_t *buf, int count)
+{
+    BDRVRawState *s = bs->opaque;
+    int ret;
+
+    ret = fd_open(bs);
+    if (ret < 0)
+        return ret;
+
+    if (lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
+        ++(s->lseek_err_cnt);
+        if(s->lseek_err_cnt <= 10) {
+            DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
+                              "] lseek failed : %d = %s\n",
+                              s->fd, bs->filename, offset, buf, count,
+                              bs->total_sectors, errno, strerror(errno));
+        }
+        return -1;
+    }
+    s->lseek_err_cnt=0;
+
+    ret = read(s->fd, buf, count);
+    if (ret == count)
+        goto label__raw_read__success;
+
+    DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
+                      "] read failed %d : %d = %s\n",
+                      s->fd, bs->filename, offset, buf, count,
+                      bs->total_sectors, ret, errno, strerror(errno));
+
+    /* Try harder for CDrom. */
+    if (bs->type == BDRV_TYPE_CDROM) {
+        lseek(s->fd, offset, SEEK_SET);
+        ret = read(s->fd, buf, count);
+        if (ret == count)
+            goto label__raw_read__success;
+        lseek(s->fd, offset, SEEK_SET);
+        ret = read(s->fd, buf, count);
+        if (ret == count)
+            goto label__raw_read__success;
+
+        DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
+                          "] retry read failed %d : %d = %s\n",
+                          s->fd, bs->filename, offset, buf, count,
+                          bs->total_sectors, ret, errno, strerror(errno));
+    }
+
+label__raw_read__success:
+
+    return ret;
+}
+
+static int raw_pwrite(BlockDriverState *bs, int64_t offset,
+                      const uint8_t *buf, int count)
+{
+    BDRVRawState *s = bs->opaque;
+    int ret;
+
+    ret = fd_open(bs);
+    if (ret < 0)
+        return ret;
+
+    if (lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
+        ++(s->lseek_err_cnt);
+        if(s->lseek_err_cnt) {
+            DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%"
+                              PRId64 "] lseek failed : %d = %s\n",
+                              s->fd, bs->filename, offset, buf, count,
+                              bs->total_sectors, errno, strerror(errno));
+        }
+        return -1;
+    }
+    s->lseek_err_cnt = 0;
+
+    ret = write(s->fd, buf, count);
+    if (ret == count)
+        goto label__raw_write__success;
+
+    DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
+                      "] write failed %d : %d = %s\n",
+                      s->fd, bs->filename, offset, buf, count,
+                      bs->total_sectors, ret, errno, strerror(errno));
+
+label__raw_write__success:
+
+    return ret;
+}
+
+/***********************************************************/
+/* Unix AIO using POSIX AIO */
+
+typedef struct RawAIOCB {
+    BlockDriverAIOCB common;
+    struct aiocb aiocb;
+    struct RawAIOCB *next;
+} RawAIOCB;
+
+static int aio_sig_num = SIGUSR2;
+static RawAIOCB *first_aio; /* AIO issued */
+static int aio_initialized = 0;
+
+static void aio_signal_handler(int signum)
+{
+#ifndef QEMU_IMG
+    CPUState *env = cpu_single_env;
+    if (env) {
+        /* stop the currently executing cpu because a timer occured */
+        cpu_interrupt(env, CPU_INTERRUPT_EXIT);
+#ifdef USE_KQEMU
+        if (env->kqemu_enabled) {
+            kqemu_cpu_interrupt(env);
+        }
+#endif
+    }
+#endif
+}
+
+void qemu_aio_init(void)
+{
+    struct sigaction act;
+
+    aio_initialized = 1;
+
+    sigfillset(&act.sa_mask);
+    act.sa_flags = 0; /* do not restart syscalls to interrupt select() */
+    act.sa_handler = aio_signal_handler;
+    sigaction(aio_sig_num, &act, NULL);
+
+#if defined(__GLIBC__) && defined(__linux__)
+    {
+        /* XXX: aio thread exit seems to hang on RedHat 9 and this init
+           seems to fix the problem. */
+        struct aioinit ai;
+        memset(&ai, 0, sizeof(ai));
+        ai.aio_threads = 1;
+        ai.aio_num = 1;
+        ai.aio_idle_time = 365 * 100000;
+        aio_init(&ai);
+    }
+#endif
+}
+
+void qemu_aio_poll(void)
+{
+    RawAIOCB *acb, **pacb;
+    int ret;
+
+    for(;;) {
+        pacb = &first_aio;
+        for(;;) {
+            acb = *pacb;
+            if (!acb)
+                goto the_end;
+            ret = aio_error(&acb->aiocb);
+            if (ret == ECANCELED) {
+                /* remove the request */
+                *pacb = acb->next;
+                qemu_aio_release(acb);
+            } else if (ret != EINPROGRESS) {
+                /* end of aio */
+                if (ret == 0) {
+                    ret = aio_return(&acb->aiocb);
+                    if (ret == acb->aiocb.aio_nbytes)
+                        ret = 0;
+                    else
+                        ret = -EINVAL;
+                } else {
+                    ret = -ret;
+                }
+                /* remove the request */
+                *pacb = acb->next;
+                /* call the callback */
+                acb->common.cb(acb->common.opaque, ret);
+                qemu_aio_release(acb);
+                break;
+            } else {
+                pacb = &acb->next;
+            }
+        }
+    }
+ the_end: ;
+}
+
+/* Wait for all IO requests to complete.  */
+void qemu_aio_flush(void)
+{
+    qemu_aio_wait_start();
+    qemu_aio_poll();
+    while (first_aio) {
+        qemu_aio_wait();
+    }
+    qemu_aio_wait_end();
+}
+
+/* wait until at least one AIO was handled */
+static sigset_t wait_oset;
+
+void qemu_aio_wait_start(void)
+{
+    sigset_t set;
+
+    if (!aio_initialized)
+        qemu_aio_init();
+    sigemptyset(&set);
+    sigaddset(&set, aio_sig_num);
+    sigprocmask(SIG_BLOCK, &set, &wait_oset);
+}
+
+void qemu_aio_wait(void)
+{
+    sigset_t set;
+    int nb_sigs;
+
+#ifndef QEMU_IMG
+    if (qemu_bh_poll())
+        return;
+#endif
+    sigemptyset(&set);
+    sigaddset(&set, aio_sig_num);
+    sigwait(&set, &nb_sigs);
+    qemu_aio_poll();
+}
+
+void qemu_aio_wait_end(void)
+{
+    sigprocmask(SIG_SETMASK, &wait_oset, NULL);
+}
+
+static RawAIOCB *raw_aio_setup(BlockDriverState *bs,
+        int64_t sector_num, uint8_t *buf, int nb_sectors,
+        BlockDriverCompletionFunc *cb, void *opaque)
+{
+    BDRVRawState *s = bs->opaque;
+    RawAIOCB *acb;
+
+    if (fd_open(bs) < 0)
+        return NULL;
+
+    acb = qemu_aio_get(bs, cb, opaque);
+    if (!acb)
+        return NULL;
+    acb->aiocb.aio_fildes = s->fd;
+    acb->aiocb.aio_sigevent.sigev_signo = aio_sig_num;
+    acb->aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
+    acb->aiocb.aio_buf = buf;
+    acb->aiocb.aio_nbytes = nb_sectors * 512;
+    acb->aiocb.aio_offset = sector_num * 512;
+    acb->next = first_aio;
+    first_aio = acb;
+    return acb;
+}
+
+static BlockDriverAIOCB *raw_aio_read(BlockDriverState *bs,
+        int64_t sector_num, uint8_t *buf, int nb_sectors,
+        BlockDriverCompletionFunc *cb, void *opaque)
+{
+    RawAIOCB *acb;
+
+    acb = raw_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque);
+    if (!acb)
+        return NULL;
+    if (aio_read(&acb->aiocb) < 0) {
+        qemu_aio_release(acb);
+        return NULL;
+    }
+    return &acb->common;
+}
+
+static BlockDriverAIOCB *raw_aio_write(BlockDriverState *bs,
+        int64_t sector_num, const uint8_t *buf, int nb_sectors,
+        BlockDriverCompletionFunc *cb, void *opaque)
+{
+    RawAIOCB *acb;
+
+    acb = raw_aio_setup(bs, sector_num, (uint8_t*)buf, nb_sectors, cb, opaque);
+    if (!acb)
+        return NULL;
+    if (aio_write(&acb->aiocb) < 0) {
+        qemu_aio_release(acb);
+        return NULL;
+    }
+    return &acb->common;
+}
+
+static void raw_aio_cancel(BlockDriverAIOCB *blockacb)
+{
+    int ret;
+    RawAIOCB *acb = (RawAIOCB *)blockacb;
+    RawAIOCB **pacb;
+
+    ret = aio_cancel(acb->aiocb.aio_fildes, &acb->aiocb);
+    if (ret == AIO_NOTCANCELED) {
+        /* fail safe: if the aio could not be canceled, we wait for
+           it */
+        while (aio_error(&acb->aiocb) == EINPROGRESS);
+    }
+
+    /* remove the callback from the queue */
+    pacb = &first_aio;
+    for(;;) {
+        if (*pacb == NULL) {
+            break;
+        } else if (*pacb == acb) {
+            *pacb = acb->next;
+            qemu_aio_release(acb);
+            break;
+        }
+        pacb = &acb->next;
+    }
+}
+
+static void raw_close(BlockDriverState *bs)
+{
+    BDRVRawState *s = bs->opaque;
+    if (s->fd >= 0) {
+        close(s->fd);
+        s->fd = -1;
+    }
+}
+
+static int raw_truncate(BlockDriverState *bs, int64_t offset)
+{
+    BDRVRawState *s = bs->opaque;
+    if (s->type != FTYPE_FILE)
+        return -ENOTSUP;
+    if (ftruncate(s->fd, offset) < 0)
+        return -errno;
+    return 0;
+}
+
+static int64_t  raw_getlength(BlockDriverState *bs)
+{
+    BDRVRawState *s = bs->opaque;
+    int fd = s->fd;
+    int64_t size;
+#ifdef _BSD
+    struct stat sb;
+#endif
+#ifdef __sun__
+    struct dk_minfo minfo;
+    int rv;
+#endif
+    int ret;
+
+    ret = fd_open(bs);
+    if (ret < 0)
+        return ret;
+
+#ifdef _BSD
+    if (!fstat(fd, &sb) && (S_IFCHR & sb.st_mode)) {
+#ifdef DIOCGMEDIASIZE
+	if (ioctl(fd, DIOCGMEDIASIZE, (off_t *)&size))
+#endif
+#ifdef CONFIG_COCOA
+        size = LONG_LONG_MAX;
+#else
+        size = lseek(fd, 0LL, SEEK_END);
+#endif
+    } else
+#endif
+#ifdef __sun__
+    /*
+     * use the DKIOCGMEDIAINFO ioctl to read the size.
+     */
+    rv = ioctl ( fd, DKIOCGMEDIAINFO, &minfo );
+    if ( rv != -1 ) {
+        size = minfo.dki_lbsize * minfo.dki_capacity;
+    } else /* there are reports that lseek on some devices
+              fails, but irc discussion said that contingency
+              on contingency was overkill */
+#endif
+    {
+        size = lseek(fd, 0, SEEK_END);
+    }
+    return size;
+}
+
+static int raw_create(const char *filename, int64_t total_size,
+                      const char *backing_file, int flags)
+{
+    int fd;
+
+    if (flags || backing_file)
+        return -ENOTSUP;
+
+    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
+              0644);
+    if (fd < 0)
+        return -EIO;
+    ftruncate(fd, total_size * 512);
+    close(fd);
+    return 0;
+}
+
+static void raw_flush(BlockDriverState *bs)
+{
+    BDRVRawState *s = bs->opaque;
+    fsync(s->fd);
+}
+
+BlockDriver bdrv_raw = {
+    "raw",
+    sizeof(BDRVRawState),
+    NULL, /* no probe for protocols */
+    raw_open,
+    NULL,
+    NULL,
+    raw_close,
+    raw_create,
+    raw_flush,
+
+    .bdrv_aio_read = raw_aio_read,
+    .bdrv_aio_write = raw_aio_write,
+    .bdrv_aio_cancel = raw_aio_cancel,
+    .aiocb_size = sizeof(RawAIOCB),
+    .protocol_name = "file",
+    .bdrv_pread = raw_pread,
+    .bdrv_pwrite = raw_pwrite,
+    .bdrv_truncate = raw_truncate,
+    .bdrv_getlength = raw_getlength,
+};
+
+/***********************************************/
+/* host device */
+
+#ifdef CONFIG_COCOA
+static kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator );
+static kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize );
+
+kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator )
+{
+    kern_return_t       kernResult;
+    mach_port_t     masterPort;
+    CFMutableDictionaryRef  classesToMatch;
+
+    kernResult = IOMasterPort( MACH_PORT_NULL, &masterPort );
+    if ( KERN_SUCCESS != kernResult ) {
+        printf( "IOMasterPort returned %d\n", kernResult );
+    }
+
+    classesToMatch = IOServiceMatching( kIOCDMediaClass );
+    if ( classesToMatch == NULL ) {
+        printf( "IOServiceMatching returned a NULL dictionary.\n" );
+    } else {
+    CFDictionarySetValue( classesToMatch, CFSTR( kIOMediaEjectableKey ), kCFBooleanTrue );
+    }
+    kernResult = IOServiceGetMatchingServices( masterPort, classesToMatch, mediaIterator );
+    if ( KERN_SUCCESS != kernResult )
+    {
+        printf( "IOServiceGetMatchingServices returned %d\n", kernResult );
+    }
+
+    return kernResult;
+}
+
+kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize )
+{
+    io_object_t     nextMedia;
+    kern_return_t   kernResult = KERN_FAILURE;
+    *bsdPath = '\0';
+    nextMedia = IOIteratorNext( mediaIterator );
+    if ( nextMedia )
+    {
+        CFTypeRef   bsdPathAsCFString;
+    bsdPathAsCFString = IORegistryEntryCreateCFProperty( nextMedia, CFSTR( kIOBSDNameKey ), kCFAllocatorDefault, 0 );
+        if ( bsdPathAsCFString ) {
+            size_t devPathLength;
+            strcpy( bsdPath, _PATH_DEV );
+            strcat( bsdPath, "r" );
+            devPathLength = strlen( bsdPath );
+            if ( CFStringGetCString( bsdPathAsCFString, bsdPath + devPathLength, maxPathSize - devPathLength, kCFStringEncodingASCII ) ) {
+                kernResult = KERN_SUCCESS;
+            }
+            CFRelease( bsdPathAsCFString );
+        }
+        IOObjectRelease( nextMedia );
+    }
+
+    return kernResult;
+}
+
+#endif
+
+static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
+{
+    BDRVRawState *s = bs->opaque;
+    int fd, open_flags, ret;
+
+#ifdef CONFIG_COCOA
+    if (strstart(filename, "/dev/cdrom", NULL)) {
+        kern_return_t kernResult;
+        io_iterator_t mediaIterator;
+        char bsdPath[ MAXPATHLEN ];
+        int fd;
+
+        kernResult = FindEjectableCDMedia( &mediaIterator );
+        kernResult = GetBSDPath( mediaIterator, bsdPath, sizeof( bsdPath ) );
+
+        if ( bsdPath[ 0 ] != '\0' ) {
+            strcat(bsdPath,"s0");
+            /* some CDs don't have a partition 0 */
+            fd = open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE);
+            if (fd < 0) {
+                bsdPath[strlen(bsdPath)-1] = '1';
+            } else {
+                close(fd);
+            }
+            filename = bsdPath;
+        }
+
+        if ( mediaIterator )
+            IOObjectRelease( mediaIterator );
+    }
+#endif
+    open_flags = O_BINARY;
+    if ((flags & BDRV_O_ACCESS) == O_RDWR) {
+        open_flags |= O_RDWR;
+    } else {
+        open_flags |= O_RDONLY;
+        bs->read_only = 1;
+    }
+
+    s->type = FTYPE_FILE;
+#if defined(__linux__)
+    if (strstart(filename, "/dev/cd", NULL)) {
+        /* open will not fail even if no CD is inserted */
+        open_flags |= O_NONBLOCK;
+        s->type = FTYPE_CD;
+    } else if (strstart(filename, "/dev/fd", NULL)) {
+        s->type = FTYPE_FD;
+        s->fd_open_flags = open_flags;
+        /* open will not fail even if no floppy is inserted */
+        open_flags |= O_NONBLOCK;
+    }
+#endif
+    fd = open(filename, open_flags, 0644);
+    if (fd < 0) {
+        ret = -errno;
+        if (ret == -EROFS)
+            ret = -EACCES;
+        return ret;
+    }
+    s->fd = fd;
+#if defined(__linux__)
+    /* close fd so that we can reopen it as needed */
+    if (s->type == FTYPE_FD) {
+        close(s->fd);
+        s->fd = -1;
+        s->fd_media_changed = 1;
+    }
+#endif
+    return 0;
+}
+
+#if defined(__linux__) && !defined(QEMU_IMG)
+
+/* Note: we do not have a reliable method to detect if the floppy is
+   present. The current method is to try to open the floppy at every
+   I/O and to keep it opened during a few hundreds of ms. */
+static int fd_open(BlockDriverState *bs)
+{
+    BDRVRawState *s = bs->opaque;
+    int last_media_present;
+
+    if (s->type != FTYPE_FD)
+        return 0;
+    last_media_present = (s->fd >= 0);
+    if (s->fd >= 0 &&
+        (qemu_get_clock(rt_clock) - s->fd_open_time) >= FD_OPEN_TIMEOUT) {
+        close(s->fd);
+        s->fd = -1;
+#ifdef DEBUG_FLOPPY
+        printf("Floppy closed\n");
+#endif
+    }
+    if (s->fd < 0) {
+        if (s->fd_got_error &&
+            (qemu_get_clock(rt_clock) - s->fd_error_time) < FD_OPEN_TIMEOUT) {
+#ifdef DEBUG_FLOPPY
+            printf("No floppy (open delayed)\n");
+#endif
+            return -EIO;
+        }
+        s->fd = open(bs->filename, s->fd_open_flags);
+        if (s->fd < 0) {
+            s->fd_error_time = qemu_get_clock(rt_clock);
+            s->fd_got_error = 1;
+            if (last_media_present)
+                s->fd_media_changed = 1;
+#ifdef DEBUG_FLOPPY
+            printf("No floppy\n");
+#endif
+            return -EIO;
+        }
+#ifdef DEBUG_FLOPPY
+        printf("Floppy opened\n");
+#endif
+    }
+    if (!last_media_present)
+        s->fd_media_changed = 1;
+    s->fd_open_time = qemu_get_clock(rt_clock);
+    s->fd_got_error = 0;
+    return 0;
+}
+#else
+static int fd_open(BlockDriverState *bs)
+{
+    return 0;
+}
+#endif
+
+#if defined(__linux__)
+
+static int raw_is_inserted(BlockDriverState *bs)
+{
+    BDRVRawState *s = bs->opaque;
+    int ret;
+
+    switch(s->type) {
+    case FTYPE_CD:
+        ret = ioctl(s->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
+        if (ret == CDS_DISC_OK)
+            return 1;
+        else
+            return 0;
+        break;
+    case FTYPE_FD:
+        ret = fd_open(bs);
+        return (ret >= 0);
+    default:
+        return 1;
+    }
+}
+
+/* currently only used by fdc.c, but a CD version would be good too */
+static int raw_media_changed(BlockDriverState *bs)
+{
+    BDRVRawState *s = bs->opaque;
+
+    switch(s->type) {
+    case FTYPE_FD:
+        {
+            int ret;
+            /* XXX: we do not have a true media changed indication. It
+               does not work if the floppy is changed without trying
+               to read it */
+            fd_open(bs);
+            ret = s->fd_media_changed;
+            s->fd_media_changed = 0;
+#ifdef DEBUG_FLOPPY
+            printf("Floppy changed=%d\n", ret);
+#endif
+            return ret;
+        }
+    default:
+        return -ENOTSUP;
+    }
+}
+
+static int raw_eject(BlockDriverState *bs, int eject_flag)
+{
+    BDRVRawState *s = bs->opaque;
+
+    switch(s->type) {
+    case FTYPE_CD:
+        if (eject_flag) {
+            if (ioctl (s->fd, CDROMEJECT, NULL) < 0)
+                perror("CDROMEJECT");
+        } else {
+            if (ioctl (s->fd, CDROMCLOSETRAY, NULL) < 0)
+                perror("CDROMEJECT");
+        }
+        break;
+    case FTYPE_FD:
+        {
+            int fd;
+            if (s->fd >= 0) {
+                close(s->fd);
+                s->fd = -1;
+            }
+            fd = open(bs->filename, s->fd_open_flags | O_NONBLOCK);
+            if (fd >= 0) {
+                if (ioctl(fd, FDEJECT, 0) < 0)
+                    perror("FDEJECT");
+                close(fd);
+            }
+        }
+        break;
+    default:
+        return -ENOTSUP;
+    }
+    return 0;
+}
+
+static int raw_set_locked(BlockDriverState *bs, int locked)
+{
+    BDRVRawState *s = bs->opaque;
+
+    switch(s->type) {
+    case FTYPE_CD:
+        if (ioctl (s->fd, CDROM_LOCKDOOR, locked) < 0) {
+            /* Note: an error can happen if the distribution automatically
+               mounts the CD-ROM */
+            //        perror("CDROM_LOCKDOOR");
+        }
+        break;
+    default:
+        return -ENOTSUP;
+    }
+    return 0;
+}
+
+#else
+
+static int raw_is_inserted(BlockDriverState *bs)
+{
+    return 1;
+}
+
+static int raw_media_changed(BlockDriverState *bs)
+{
+    return -ENOTSUP;
+}
+
+static int raw_eject(BlockDriverState *bs, int eject_flag)
+{
+    return -ENOTSUP;
+}
+
+static int raw_set_locked(BlockDriverState *bs, int locked)
+{
+    return -ENOTSUP;
+}
+
+#endif /* !linux */
+
+BlockDriver bdrv_host_device = {
+    "host_device",
+    sizeof(BDRVRawState),
+    NULL, /* no probe for protocols */
+    hdev_open,
+    NULL,
+    NULL,
+    raw_close,
+    NULL,
+    raw_flush,
+
+    .bdrv_aio_read = raw_aio_read,
+    .bdrv_aio_write = raw_aio_write,
+    .bdrv_aio_cancel = raw_aio_cancel,
+    .aiocb_size = sizeof(RawAIOCB),
+    .bdrv_pread = raw_pread,
+    .bdrv_pwrite = raw_pwrite,
+    .bdrv_getlength = raw_getlength,
+
+    /* removable device support */
+    .bdrv_is_inserted = raw_is_inserted,
+    .bdrv_media_changed = raw_media_changed,
+    .bdrv_eject = raw_eject,
+    .bdrv_set_locked = raw_set_locked,
+};

Added: trunk/src/host/qemu-neo1973/block-raw-win32.c
===================================================================
--- trunk/src/host/qemu-neo1973/block-raw-win32.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/block-raw-win32.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -0,0 +1,544 @@
+/*
+ * Block driver for RAW files (win32)
+ *
+ * Copyright (c) 2006 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "qemu-common.h"
+#ifndef QEMU_IMG
+#include "qemu-timer.h"
+#include "exec-all.h"
+#endif
+#include "block_int.h"
+#include <assert.h>
+#include <winioctl.h>
+
+#define FTYPE_FILE 0
+#define FTYPE_CD     1
+#define FTYPE_HARDDISK 2
+
+typedef struct BDRVRawState {
+    HANDLE hfile;
+    int type;
+    char drive_path[16]; /* format: "d:\" */
+} BDRVRawState;
+
+typedef struct RawAIOCB {
+    BlockDriverAIOCB common;
+    HANDLE hEvent;
+    OVERLAPPED ov;
+    int count;
+} RawAIOCB;
+
+int qemu_ftruncate64(int fd, int64_t length)
+{
+    LARGE_INTEGER li;
+    LONG high;
+    HANDLE h;
+    BOOL res;
+
+    if ((GetVersion() & 0x80000000UL) && (length >> 32) != 0)
+	return -1;
+
+    h = (HANDLE)_get_osfhandle(fd);
+
+    /* get current position, ftruncate do not change position */
+    li.HighPart = 0;
+    li.LowPart = SetFilePointer (h, 0, &li.HighPart, FILE_CURRENT);
+    if (li.LowPart == 0xffffffffUL && GetLastError() != NO_ERROR)
+	return -1;
+
+    high = length >> 32;
+    if (!SetFilePointer(h, (DWORD) length, &high, FILE_BEGIN))
+	return -1;
+    res = SetEndOfFile(h);
+
+    /* back to old position */
+    SetFilePointer(h, li.LowPart, &li.HighPart, FILE_BEGIN);
+    return res ? 0 : -1;
+}
+
+static int set_sparse(int fd)
+{
+    DWORD returned;
+    return (int) DeviceIoControl((HANDLE)_get_osfhandle(fd), FSCTL_SET_SPARSE,
+				 NULL, 0, NULL, 0, &returned, NULL);
+}
+
+static int raw_open(BlockDriverState *bs, const char *filename, int flags)
+{
+    BDRVRawState *s = bs->opaque;
+    int access_flags, create_flags;
+    DWORD overlapped;
+
+    s->type = FTYPE_FILE;
+
+    if ((flags & BDRV_O_ACCESS) == O_RDWR) {
+        access_flags = GENERIC_READ | GENERIC_WRITE;
+    } else {
+        access_flags = GENERIC_READ;
+    }
+    if (flags & BDRV_O_CREAT) {
+        create_flags = CREATE_ALWAYS;
+    } else {
+        create_flags = OPEN_EXISTING;
+    }
+#ifdef QEMU_IMG
+    overlapped = FILE_ATTRIBUTE_NORMAL;
+#else
+    overlapped = FILE_FLAG_OVERLAPPED;
+#endif
+    s->hfile = CreateFile(filename, access_flags,
+                          FILE_SHARE_READ, NULL,
+                          create_flags, overlapped, NULL);
+    if (s->hfile == INVALID_HANDLE_VALUE) {
+        int err = GetLastError();
+
+        if (err == ERROR_ACCESS_DENIED)
+            return -EACCES;
+        return -1;
+    }
+    return 0;
+}
+
+static int raw_pread(BlockDriverState *bs, int64_t offset,
+                     uint8_t *buf, int count)
+{
+    BDRVRawState *s = bs->opaque;
+    OVERLAPPED ov;
+    DWORD ret_count;
+    int ret;
+
+    memset(&ov, 0, sizeof(ov));
+    ov.Offset = offset;
+    ov.OffsetHigh = offset >> 32;
+    ret = ReadFile(s->hfile, buf, count, &ret_count, &ov);
+    if (!ret) {
+        ret = GetOverlappedResult(s->hfile, &ov, &ret_count, TRUE);
+        if (!ret)
+            return -EIO;
+        else
+            return ret_count;
+    }
+    return ret_count;
+}
+
+static int raw_pwrite(BlockDriverState *bs, int64_t offset,
+                      const uint8_t *buf, int count)
+{
+    BDRVRawState *s = bs->opaque;
+    OVERLAPPED ov;
+    DWORD ret_count;
+    int ret;
+
+    memset(&ov, 0, sizeof(ov));
+    ov.Offset = offset;
+    ov.OffsetHigh = offset >> 32;
+    ret = WriteFile(s->hfile, buf, count, &ret_count, &ov);
+    if (!ret) {
+        ret = GetOverlappedResult(s->hfile, &ov, &ret_count, TRUE);
+        if (!ret)
+            return -EIO;
+        else
+            return ret_count;
+    }
+    return ret_count;
+}
+
+#if 0
+#ifndef QEMU_IMG
+static void raw_aio_cb(void *opaque)
+{
+    RawAIOCB *acb = opaque;
+    BlockDriverState *bs = acb->common.bs;
+    BDRVRawState *s = bs->opaque;
+    DWORD ret_count;
+    int ret;
+
+    ret = GetOverlappedResult(s->hfile, &acb->ov, &ret_count, TRUE);
+    if (!ret || ret_count != acb->count) {
+        acb->common.cb(acb->common.opaque, -EIO);
+    } else {
+        acb->common.cb(acb->common.opaque, 0);
+    }
+}
+#endif
+
+static RawAIOCB *raw_aio_setup(BlockDriverState *bs,
+        int64_t sector_num, uint8_t *buf, int nb_sectors,
+        BlockDriverCompletionFunc *cb, void *opaque)
+{
+    RawAIOCB *acb;
+    int64_t offset;
+
+    acb = qemu_aio_get(bs, cb, opaque);
+    if (acb->hEvent) {
+        acb->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+        if (!acb->hEvent) {
+            qemu_aio_release(acb);
+            return NULL;
+        }
+    }
+    memset(&acb->ov, 0, sizeof(acb->ov));
+    offset = sector_num * 512;
+    acb->ov.Offset = offset;
+    acb->ov.OffsetHigh = offset >> 32;
+    acb->ov.hEvent = acb->hEvent;
+    acb->count = nb_sectors * 512;
+#ifndef QEMU_IMG
+    qemu_add_wait_object(acb->ov.hEvent, raw_aio_cb, acb);
+#endif
+    return acb;
+}
+
+static BlockDriverAIOCB *raw_aio_read(BlockDriverState *bs,
+        int64_t sector_num, uint8_t *buf, int nb_sectors,
+        BlockDriverCompletionFunc *cb, void *opaque)
+{
+    BDRVRawState *s = bs->opaque;
+    RawAIOCB *acb;
+    int ret;
+
+    acb = raw_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque);
+    if (!acb)
+        return NULL;
+    ret = ReadFile(s->hfile, buf, acb->count, NULL, &acb->ov);
+    if (!ret) {
+        qemu_aio_release(acb);
+        return NULL;
+    }
+#ifdef QEMU_IMG
+    qemu_aio_release(acb);
+#endif
+    return (BlockDriverAIOCB *)acb;
+}
+
+static BlockDriverAIOCB *raw_aio_write(BlockDriverState *bs,
+        int64_t sector_num, uint8_t *buf, int nb_sectors,
+        BlockDriverCompletionFunc *cb, void *opaque)
+{
+    BDRVRawState *s = bs->opaque;
+    RawAIOCB *acb;
+    int ret;
+
+    acb = raw_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque);
+    if (!acb)
+        return NULL;
+    ret = WriteFile(s->hfile, buf, acb->count, NULL, &acb->ov);
+    if (!ret) {
+        qemu_aio_release(acb);
+        return NULL;
+    }
+#ifdef QEMU_IMG
+    qemu_aio_release(acb);
+#endif
+    return (BlockDriverAIOCB *)acb;
+}
+
+static void raw_aio_cancel(BlockDriverAIOCB *blockacb)
+{
+#ifndef QEMU_IMG
+    RawAIOCB *acb = (RawAIOCB *)blockacb;
+    BlockDriverState *bs = acb->common.bs;
+    BDRVRawState *s = bs->opaque;
+
+    qemu_del_wait_object(acb->ov.hEvent, raw_aio_cb, acb);
+    /* XXX: if more than one async I/O it is not correct */
+    CancelIo(s->hfile);
+    qemu_aio_release(acb);
+#endif
+}
+#endif /* #if 0 */
+
+static void raw_flush(BlockDriverState *bs)
+{
+    BDRVRawState *s = bs->opaque;
+    FlushFileBuffers(s->hfile);
+}
+
+static void raw_close(BlockDriverState *bs)
+{
+    BDRVRawState *s = bs->opaque;
+    CloseHandle(s->hfile);
+}
+
+static int raw_truncate(BlockDriverState *bs, int64_t offset)
+{
+    BDRVRawState *s = bs->opaque;
+    DWORD low, high;
+
+    low = offset;
+    high = offset >> 32;
+    if (!SetFilePointer(s->hfile, low, &high, FILE_BEGIN))
+	return -EIO;
+    if (!SetEndOfFile(s->hfile))
+        return -EIO;
+    return 0;
+}
+
+static int64_t raw_getlength(BlockDriverState *bs)
+{
+    BDRVRawState *s = bs->opaque;
+    LARGE_INTEGER l;
+    ULARGE_INTEGER available, total, total_free;
+    DISK_GEOMETRY_EX dg;
+    DWORD count;
+    BOOL status;
+
+    switch(s->type) {
+    case FTYPE_FILE:
+        l.LowPart = GetFileSize(s->hfile, &l.HighPart);
+        if (l.LowPart == 0xffffffffUL && GetLastError() != NO_ERROR)
+            return -EIO;
+        break;
+    case FTYPE_CD:
+        if (!GetDiskFreeSpaceEx(s->drive_path, &available, &total, &total_free))
+            return -EIO;
+        l.QuadPart = total.QuadPart;
+        break;
+    case FTYPE_HARDDISK:
+        status = DeviceIoControl(s->hfile, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
+                                 NULL, 0, &dg, sizeof(dg), &count, NULL);
+        if (status != 0) {
+            l = dg.DiskSize;
+        }
+        break;
+    default:
+        return -EIO;
+    }
+    return l.QuadPart;
+}
+
+static int raw_create(const char *filename, int64_t total_size,
+                      const char *backing_file, int flags)
+{
+    int fd;
+
+    if (flags || backing_file)
+        return -ENOTSUP;
+
+    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
+              0644);
+    if (fd < 0)
+        return -EIO;
+    set_sparse(fd);
+    ftruncate(fd, total_size * 512);
+    close(fd);
+    return 0;
+}
+
+void qemu_aio_init(void)
+{
+}
+
+void qemu_aio_poll(void)
+{
+}
+
+void qemu_aio_flush(void)
+{
+}
+
+void qemu_aio_wait_start(void)
+{
+}
+
+void qemu_aio_wait(void)
+{
+#ifndef QEMU_IMG
+    qemu_bh_poll();
+#endif
+}
+
+void qemu_aio_wait_end(void)
+{
+}
+
+BlockDriver bdrv_raw = {
+    "raw",
+    sizeof(BDRVRawState),
+    NULL, /* no probe for protocols */
+    raw_open,
+    NULL,
+    NULL,
+    raw_close,
+    raw_create,
+    raw_flush,
+
+#if 0
+    .bdrv_aio_read = raw_aio_read,
+    .bdrv_aio_write = raw_aio_write,
+    .bdrv_aio_cancel = raw_aio_cancel,
+    .aiocb_size = sizeof(RawAIOCB);
+#endif
+    .protocol_name = "file",
+    .bdrv_pread = raw_pread,
+    .bdrv_pwrite = raw_pwrite,
+    .bdrv_truncate = raw_truncate,
+    .bdrv_getlength = raw_getlength,
+};
+
+/***********************************************/
+/* host device */
+
+static int find_cdrom(char *cdrom_name, int cdrom_name_size)
+{
+    char drives[256], *pdrv = drives;
+    UINT type;
+
+    memset(drives, 0, sizeof(drives));
+    GetLogicalDriveStrings(sizeof(drives), drives);
+    while(pdrv[0] != '\0') {
+        type = GetDriveType(pdrv);
+        switch(type) {
+        case DRIVE_CDROM:
+            snprintf(cdrom_name, cdrom_name_size, "\\\\.\\%c:", pdrv[0]);
+            return 0;
+            break;
+        }
+        pdrv += lstrlen(pdrv) + 1;
+    }
+    return -1;
+}
+
+static int find_device_type(BlockDriverState *bs, const char *filename)
+{
+    BDRVRawState *s = bs->opaque;
+    UINT type;
+    const char *p;
+
+    if (strstart(filename, "\\\\.\\", &p) ||
+        strstart(filename, "//./", &p)) {
+        if (stristart(p, "PhysicalDrive", NULL))
+            return FTYPE_HARDDISK;
+        snprintf(s->drive_path, sizeof(s->drive_path), "%c:\\", p[0]);
+        type = GetDriveType(s->drive_path);
+        if (type == DRIVE_CDROM)
+            return FTYPE_CD;
+        else
+            return FTYPE_FILE;
+    } else {
+        return FTYPE_FILE;
+    }
+}
+
+static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
+{
+    BDRVRawState *s = bs->opaque;
+    int access_flags, create_flags;
+    DWORD overlapped;
+    char device_name[64];
+
+    if (strstart(filename, "/dev/cdrom", NULL)) {
+        if (find_cdrom(device_name, sizeof(device_name)) < 0)
+            return -ENOENT;
+        filename = device_name;
+    } else {
+        /* transform drive letters into device name */
+        if (((filename[0] >= 'a' && filename[0] <= 'z') ||
+             (filename[0] >= 'A' && filename[0] <= 'Z')) &&
+            filename[1] == ':' && filename[2] == '\0') {
+            snprintf(device_name, sizeof(device_name), "\\\\.\\%c:", filename[0]);
+            filename = device_name;
+        }
+    }
+    s->type = find_device_type(bs, filename);
+
+    if ((flags & BDRV_O_ACCESS) == O_RDWR) {
+        access_flags = GENERIC_READ | GENERIC_WRITE;
+    } else {
+        access_flags = GENERIC_READ;
+    }
+    create_flags = OPEN_EXISTING;
+
+#ifdef QEMU_IMG
+    overlapped = FILE_ATTRIBUTE_NORMAL;
+#else
+    overlapped = FILE_FLAG_OVERLAPPED;
+#endif
+    s->hfile = CreateFile(filename, access_flags,
+                          FILE_SHARE_READ, NULL,
+                          create_flags, overlapped, NULL);
+    if (s->hfile == INVALID_HANDLE_VALUE) {
+        int err = GetLastError();
+
+        if (err == ERROR_ACCESS_DENIED)
+            return -EACCES;
+        return -1;
+    }
+    return 0;
+}
+
+#if 0
+/***********************************************/
+/* removable device additional commands */
+
+static int raw_is_inserted(BlockDriverState *bs)
+{
+    return 1;
+}
+
+static int raw_media_changed(BlockDriverState *bs)
+{
+    return -ENOTSUP;
+}
+
+static int raw_eject(BlockDriverState *bs, int eject_flag)
+{
+    DWORD ret_count;
+
+    if (s->type == FTYPE_FILE)
+        return -ENOTSUP;
+    if (eject_flag) {
+        DeviceIoControl(s->hfile, IOCTL_STORAGE_EJECT_MEDIA,
+                        NULL, 0, NULL, 0, &lpBytesReturned, NULL);
+    } else {
+        DeviceIoControl(s->hfile, IOCTL_STORAGE_LOAD_MEDIA,
+                        NULL, 0, NULL, 0, &lpBytesReturned, NULL);
+    }
+}
+
+static int raw_set_locked(BlockDriverState *bs, int locked)
+{
+    return -ENOTSUP;
+}
+#endif
+
+BlockDriver bdrv_host_device = {
+    "host_device",
+    sizeof(BDRVRawState),
+    NULL, /* no probe for protocols */
+    hdev_open,
+    NULL,
+    NULL,
+    raw_close,
+    NULL,
+    raw_flush,
+
+#if 0
+    .bdrv_aio_read = raw_aio_read,
+    .bdrv_aio_write = raw_aio_write,
+    .bdrv_aio_cancel = raw_aio_cancel,
+    .aiocb_size = sizeof(RawAIOCB);
+#endif
+    .bdrv_pread = raw_pread,
+    .bdrv_pwrite = raw_pwrite,
+    .bdrv_getlength = raw_getlength,
+};

Deleted: trunk/src/host/qemu-neo1973/block-raw.c
===================================================================
--- trunk/src/host/qemu-neo1973/block-raw.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/block-raw.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -1,1421 +0,0 @@
-/*
- * Block driver for RAW files
- *
- * Copyright (c) 2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu-common.h"
-#ifndef QEMU_IMG
-#include "qemu-timer.h"
-#include "exec-all.h"
-#endif
-#include "block_int.h"
-#include <assert.h>
-#ifndef _WIN32
-#include <aio.h>
-
-#ifdef CONFIG_COCOA
-#include <paths.h>
-#include <sys/param.h>
-#include <IOKit/IOKitLib.h>
-#include <IOKit/IOBSD.h>
-#include <IOKit/storage/IOMediaBSDClient.h>
-#include <IOKit/storage/IOMedia.h>
-#include <IOKit/storage/IOCDMedia.h>
-//#include <IOKit/storage/IOCDTypes.h>
-#include <CoreFoundation/CoreFoundation.h>
-#endif
-
-#ifdef __sun__
-#define _POSIX_PTHREAD_SEMANTICS 1
-#include <signal.h>
-#include <sys/dkio.h>
-#endif
-#ifdef __linux__
-#include <sys/ioctl.h>
-#include <linux/cdrom.h>
-#include <linux/fd.h>
-#endif
-#ifdef __FreeBSD__
-#include <sys/disk.h>
-#endif
-
-//#define DEBUG_FLOPPY
-
-//#define DEBUG_BLOCK
-#if defined(DEBUG_BLOCK) && !defined(QEMU_IMG)
-#define DEBUG_BLOCK_PRINT(formatCstr, args...) do { if (loglevel != 0)	\
-    { fprintf(logfile, formatCstr, ##args); fflush(logfile); } } while (0)
-#else
-#define DEBUG_BLOCK_PRINT(formatCstr, args...)
-#endif
-
-#define FTYPE_FILE   0
-#define FTYPE_CD     1
-#define FTYPE_FD     2
-
-/* if the FD is not accessed during that time (in ms), we try to
-   reopen it to see if the disk has been changed */
-#define FD_OPEN_TIMEOUT 1000
-
-typedef struct BDRVRawState {
-    int fd;
-    int type;
-    unsigned int lseek_err_cnt;
-#if defined(__linux__)
-    /* linux floppy specific */
-    int fd_open_flags;
-    int64_t fd_open_time;
-    int64_t fd_error_time;
-    int fd_got_error;
-    int fd_media_changed;
-#endif
-} BDRVRawState;
-
-static int fd_open(BlockDriverState *bs);
-
-static int raw_open(BlockDriverState *bs, const char *filename, int flags)
-{
-    BDRVRawState *s = bs->opaque;
-    int fd, open_flags, ret;
-
-    s->lseek_err_cnt = 0;
-
-    open_flags = O_BINARY;
-    if ((flags & BDRV_O_ACCESS) == O_RDWR) {
-        open_flags |= O_RDWR;
-    } else {
-        open_flags |= O_RDONLY;
-        bs->read_only = 1;
-    }
-    if (flags & BDRV_O_CREAT)
-        open_flags |= O_CREAT | O_TRUNC;
-
-    s->type = FTYPE_FILE;
-
-    fd = open(filename, open_flags, 0644);
-    if (fd < 0) {
-        ret = -errno;
-        if (ret == -EROFS)
-            ret = -EACCES;
-        return ret;
-    }
-    s->fd = fd;
-    return 0;
-}
-
-/* XXX: use host sector size if necessary with:
-#ifdef DIOCGSECTORSIZE
-        {
-            unsigned int sectorsize = 512;
-            if (!ioctl(fd, DIOCGSECTORSIZE, &sectorsize) &&
-                sectorsize > bufsize)
-                bufsize = sectorsize;
-        }
-#endif
-#ifdef CONFIG_COCOA
-        u_int32_t   blockSize = 512;
-        if ( !ioctl( fd, DKIOCGETBLOCKSIZE, &blockSize ) && blockSize > bufsize) {
-            bufsize = blockSize;
-        }
-#endif
-*/
-
-static int raw_pread(BlockDriverState *bs, int64_t offset,
-                     uint8_t *buf, int count)
-{
-    BDRVRawState *s = bs->opaque;
-    int ret;
-
-    ret = fd_open(bs);
-    if (ret < 0)
-        return ret;
-
-    if (lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
-        ++(s->lseek_err_cnt);
-        if(s->lseek_err_cnt <= 10) {
-            DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
-                              "] lseek failed : %d = %s\n",
-                              s->fd, bs->filename, offset, buf, count,
-                              bs->total_sectors, errno, strerror(errno));
-        }
-        return -1;
-    }
-    s->lseek_err_cnt=0;
-
-    ret = read(s->fd, buf, count);
-    if (ret == count)
-        goto label__raw_read__success;
-
-    DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
-                      "] read failed %d : %d = %s\n",
-                      s->fd, bs->filename, offset, buf, count,
-                      bs->total_sectors, ret, errno, strerror(errno));
-
-    /* Try harder for CDrom. */
-    if (bs->type == BDRV_TYPE_CDROM) {
-        lseek(s->fd, offset, SEEK_SET);
-        ret = read(s->fd, buf, count);
-        if (ret == count)
-            goto label__raw_read__success;
-        lseek(s->fd, offset, SEEK_SET);
-        ret = read(s->fd, buf, count);
-        if (ret == count)
-            goto label__raw_read__success;
-
-        DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
-                          "] retry read failed %d : %d = %s\n",
-                          s->fd, bs->filename, offset, buf, count,
-                          bs->total_sectors, ret, errno, strerror(errno));
-    }
-
-label__raw_read__success:
-
-    return ret;
-}
-
-static int raw_pwrite(BlockDriverState *bs, int64_t offset,
-                      const uint8_t *buf, int count)
-{
-    BDRVRawState *s = bs->opaque;
-    int ret;
-
-    ret = fd_open(bs);
-    if (ret < 0)
-        return ret;
-
-    if (lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
-        ++(s->lseek_err_cnt);
-        if(s->lseek_err_cnt) {
-            DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%"
-                              PRId64 "] lseek failed : %d = %s\n",
-                              s->fd, bs->filename, offset, buf, count,
-                              bs->total_sectors, errno, strerror(errno));
-        }
-        return -1;
-    }
-    s->lseek_err_cnt = 0;
-
-    ret = write(s->fd, buf, count);
-    if (ret == count)
-        goto label__raw_write__success;
-
-    DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
-                      "] write failed %d : %d = %s\n",
-                      s->fd, bs->filename, offset, buf, count,
-                      bs->total_sectors, ret, errno, strerror(errno));
-
-label__raw_write__success:
-
-    return ret;
-}
-
-/***********************************************************/
-/* Unix AIO using POSIX AIO */
-
-typedef struct RawAIOCB {
-    BlockDriverAIOCB common;
-    struct aiocb aiocb;
-    struct RawAIOCB *next;
-} RawAIOCB;
-
-static int aio_sig_num = SIGUSR2;
-static RawAIOCB *first_aio; /* AIO issued */
-static int aio_initialized = 0;
-
-static void aio_signal_handler(int signum)
-{
-#ifndef QEMU_IMG
-    CPUState *env = cpu_single_env;
-    if (env) {
-        /* stop the currently executing cpu because a timer occured */
-        cpu_interrupt(env, CPU_INTERRUPT_EXIT);
-#ifdef USE_KQEMU
-        if (env->kqemu_enabled) {
-            kqemu_cpu_interrupt(env);
-        }
-#endif
-    }
-#endif
-}
-
-void qemu_aio_init(void)
-{
-    struct sigaction act;
-
-    aio_initialized = 1;
-
-    sigfillset(&act.sa_mask);
-    act.sa_flags = 0; /* do not restart syscalls to interrupt select() */
-    act.sa_handler = aio_signal_handler;
-    sigaction(aio_sig_num, &act, NULL);
-
-#if defined(__GLIBC__) && defined(__linux__)
-    {
-        /* XXX: aio thread exit seems to hang on RedHat 9 and this init
-           seems to fix the problem. */
-        struct aioinit ai;
-        memset(&ai, 0, sizeof(ai));
-        ai.aio_threads = 1;
-        ai.aio_num = 1;
-        ai.aio_idle_time = 365 * 100000;
-        aio_init(&ai);
-    }
-#endif
-}
-
-void qemu_aio_poll(void)
-{
-    RawAIOCB *acb, **pacb;
-    int ret;
-
-    for(;;) {
-        pacb = &first_aio;
-        for(;;) {
-            acb = *pacb;
-            if (!acb)
-                goto the_end;
-            ret = aio_error(&acb->aiocb);
-            if (ret == ECANCELED) {
-                /* remove the request */
-                *pacb = acb->next;
-                qemu_aio_release(acb);
-            } else if (ret != EINPROGRESS) {
-                /* end of aio */
-                if (ret == 0) {
-                    ret = aio_return(&acb->aiocb);
-                    if (ret == acb->aiocb.aio_nbytes)
-                        ret = 0;
-                    else
-                        ret = -EINVAL;
-                } else {
-                    ret = -ret;
-                }
-                /* remove the request */
-                *pacb = acb->next;
-                /* call the callback */
-                acb->common.cb(acb->common.opaque, ret);
-                qemu_aio_release(acb);
-                break;
-            } else {
-                pacb = &acb->next;
-            }
-        }
-    }
- the_end: ;
-}
-
-/* Wait for all IO requests to complete.  */
-void qemu_aio_flush(void)
-{
-    qemu_aio_wait_start();
-    qemu_aio_poll();
-    while (first_aio) {
-        qemu_aio_wait();
-    }
-    qemu_aio_wait_end();
-}
-
-/* wait until at least one AIO was handled */
-static sigset_t wait_oset;
-
-void qemu_aio_wait_start(void)
-{
-    sigset_t set;
-
-    if (!aio_initialized)
-        qemu_aio_init();
-    sigemptyset(&set);
-    sigaddset(&set, aio_sig_num);
-    sigprocmask(SIG_BLOCK, &set, &wait_oset);
-}
-
-void qemu_aio_wait(void)
-{
-    sigset_t set;
-    int nb_sigs;
-
-#ifndef QEMU_IMG
-    if (qemu_bh_poll())
-        return;
-#endif
-    sigemptyset(&set);
-    sigaddset(&set, aio_sig_num);
-    sigwait(&set, &nb_sigs);
-    qemu_aio_poll();
-}
-
-void qemu_aio_wait_end(void)
-{
-    sigprocmask(SIG_SETMASK, &wait_oset, NULL);
-}
-
-static RawAIOCB *raw_aio_setup(BlockDriverState *bs,
-        int64_t sector_num, uint8_t *buf, int nb_sectors,
-        BlockDriverCompletionFunc *cb, void *opaque)
-{
-    BDRVRawState *s = bs->opaque;
-    RawAIOCB *acb;
-
-    if (fd_open(bs) < 0)
-        return NULL;
-
-    acb = qemu_aio_get(bs, cb, opaque);
-    if (!acb)
-        return NULL;
-    acb->aiocb.aio_fildes = s->fd;
-    acb->aiocb.aio_sigevent.sigev_signo = aio_sig_num;
-    acb->aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
-    acb->aiocb.aio_buf = buf;
-    acb->aiocb.aio_nbytes = nb_sectors * 512;
-    acb->aiocb.aio_offset = sector_num * 512;
-    acb->next = first_aio;
-    first_aio = acb;
-    return acb;
-}
-
-static BlockDriverAIOCB *raw_aio_read(BlockDriverState *bs,
-        int64_t sector_num, uint8_t *buf, int nb_sectors,
-        BlockDriverCompletionFunc *cb, void *opaque)
-{
-    RawAIOCB *acb;
-
-    acb = raw_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque);
-    if (!acb)
-        return NULL;
-    if (aio_read(&acb->aiocb) < 0) {
-        qemu_aio_release(acb);
-        return NULL;
-    }
-    return &acb->common;
-}
-
-static BlockDriverAIOCB *raw_aio_write(BlockDriverState *bs,
-        int64_t sector_num, const uint8_t *buf, int nb_sectors,
-        BlockDriverCompletionFunc *cb, void *opaque)
-{
-    RawAIOCB *acb;
-
-    acb = raw_aio_setup(bs, sector_num, (uint8_t*)buf, nb_sectors, cb, opaque);
-    if (!acb)
-        return NULL;
-    if (aio_write(&acb->aiocb) < 0) {
-        qemu_aio_release(acb);
-        return NULL;
-    }
-    return &acb->common;
-}
-
-static void raw_aio_cancel(BlockDriverAIOCB *blockacb)
-{
-    int ret;
-    RawAIOCB *acb = (RawAIOCB *)blockacb;
-    RawAIOCB **pacb;
-
-    ret = aio_cancel(acb->aiocb.aio_fildes, &acb->aiocb);
-    if (ret == AIO_NOTCANCELED) {
-        /* fail safe: if the aio could not be canceled, we wait for
-           it */
-        while (aio_error(&acb->aiocb) == EINPROGRESS);
-    }
-
-    /* remove the callback from the queue */
-    pacb = &first_aio;
-    for(;;) {
-        if (*pacb == NULL) {
-            break;
-        } else if (*pacb == acb) {
-            *pacb = acb->next;
-            qemu_aio_release(acb);
-            break;
-        }
-        pacb = &acb->next;
-    }
-}
-
-static void raw_close(BlockDriverState *bs)
-{
-    BDRVRawState *s = bs->opaque;
-    if (s->fd >= 0) {
-        close(s->fd);
-        s->fd = -1;
-    }
-}
-
-static int raw_truncate(BlockDriverState *bs, int64_t offset)
-{
-    BDRVRawState *s = bs->opaque;
-    if (s->type != FTYPE_FILE)
-        return -ENOTSUP;
-    if (ftruncate(s->fd, offset) < 0)
-        return -errno;
-    return 0;
-}
-
-static int64_t  raw_getlength(BlockDriverState *bs)
-{
-    BDRVRawState *s = bs->opaque;
-    int fd = s->fd;
-    int64_t size;
-#ifdef _BSD
-    struct stat sb;
-#endif
-#ifdef __sun__
-    struct dk_minfo minfo;
-    int rv;
-#endif
-    int ret;
-
-    ret = fd_open(bs);
-    if (ret < 0)
-        return ret;
-
-#ifdef _BSD
-    if (!fstat(fd, &sb) && (S_IFCHR & sb.st_mode)) {
-#ifdef DIOCGMEDIASIZE
-	if (ioctl(fd, DIOCGMEDIASIZE, (off_t *)&size))
-#endif
-#ifdef CONFIG_COCOA
-        size = LONG_LONG_MAX;
-#else
-        size = lseek(fd, 0LL, SEEK_END);
-#endif
-    } else
-#endif
-#ifdef __sun__
-    /*
-     * use the DKIOCGMEDIAINFO ioctl to read the size.
-     */
-    rv = ioctl ( fd, DKIOCGMEDIAINFO, &minfo );
-    if ( rv != -1 ) {
-        size = minfo.dki_lbsize * minfo.dki_capacity;
-    } else /* there are reports that lseek on some devices
-              fails, but irc discussion said that contingency
-              on contingency was overkill */
-#endif
-    {
-        size = lseek(fd, 0, SEEK_END);
-    }
-    return size;
-}
-
-static int raw_create(const char *filename, int64_t total_size,
-                      const char *backing_file, int flags)
-{
-    int fd;
-
-    if (flags || backing_file)
-        return -ENOTSUP;
-
-    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
-              0644);
-    if (fd < 0)
-        return -EIO;
-    ftruncate(fd, total_size * 512);
-    close(fd);
-    return 0;
-}
-
-static void raw_flush(BlockDriverState *bs)
-{
-    BDRVRawState *s = bs->opaque;
-    fsync(s->fd);
-}
-
-BlockDriver bdrv_raw = {
-    "raw",
-    sizeof(BDRVRawState),
-    NULL, /* no probe for protocols */
-    raw_open,
-    NULL,
-    NULL,
-    raw_close,
-    raw_create,
-    raw_flush,
-
-    .bdrv_aio_read = raw_aio_read,
-    .bdrv_aio_write = raw_aio_write,
-    .bdrv_aio_cancel = raw_aio_cancel,
-    .aiocb_size = sizeof(RawAIOCB),
-    .protocol_name = "file",
-    .bdrv_pread = raw_pread,
-    .bdrv_pwrite = raw_pwrite,
-    .bdrv_truncate = raw_truncate,
-    .bdrv_getlength = raw_getlength,
-};
-
-/***********************************************/
-/* host device */
-
-#ifdef CONFIG_COCOA
-static kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator );
-static kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize );
-
-kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator )
-{
-    kern_return_t       kernResult;
-    mach_port_t     masterPort;
-    CFMutableDictionaryRef  classesToMatch;
-
-    kernResult = IOMasterPort( MACH_PORT_NULL, &masterPort );
-    if ( KERN_SUCCESS != kernResult ) {
-        printf( "IOMasterPort returned %d\n", kernResult );
-    }
-
-    classesToMatch = IOServiceMatching( kIOCDMediaClass );
-    if ( classesToMatch == NULL ) {
-        printf( "IOServiceMatching returned a NULL dictionary.\n" );
-    } else {
-    CFDictionarySetValue( classesToMatch, CFSTR( kIOMediaEjectableKey ), kCFBooleanTrue );
-    }
-    kernResult = IOServiceGetMatchingServices( masterPort, classesToMatch, mediaIterator );
-    if ( KERN_SUCCESS != kernResult )
-    {
-        printf( "IOServiceGetMatchingServices returned %d\n", kernResult );
-    }
-
-    return kernResult;
-}
-
-kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize )
-{
-    io_object_t     nextMedia;
-    kern_return_t   kernResult = KERN_FAILURE;
-    *bsdPath = '\0';
-    nextMedia = IOIteratorNext( mediaIterator );
-    if ( nextMedia )
-    {
-        CFTypeRef   bsdPathAsCFString;
-    bsdPathAsCFString = IORegistryEntryCreateCFProperty( nextMedia, CFSTR( kIOBSDNameKey ), kCFAllocatorDefault, 0 );
-        if ( bsdPathAsCFString ) {
-            size_t devPathLength;
-            strcpy( bsdPath, _PATH_DEV );
-            strcat( bsdPath, "r" );
-            devPathLength = strlen( bsdPath );
-            if ( CFStringGetCString( bsdPathAsCFString, bsdPath + devPathLength, maxPathSize - devPathLength, kCFStringEncodingASCII ) ) {
-                kernResult = KERN_SUCCESS;
-            }
-            CFRelease( bsdPathAsCFString );
-        }
-        IOObjectRelease( nextMedia );
-    }
-
-    return kernResult;
-}
-
-#endif
-
-static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
-{
-    BDRVRawState *s = bs->opaque;
-    int fd, open_flags, ret;
-
-#ifdef CONFIG_COCOA
-    if (strstart(filename, "/dev/cdrom", NULL)) {
-        kern_return_t kernResult;
-        io_iterator_t mediaIterator;
-        char bsdPath[ MAXPATHLEN ];
-        int fd;
-
-        kernResult = FindEjectableCDMedia( &mediaIterator );
-        kernResult = GetBSDPath( mediaIterator, bsdPath, sizeof( bsdPath ) );
-
-        if ( bsdPath[ 0 ] != '\0' ) {
-            strcat(bsdPath,"s0");
-            /* some CDs don't have a partition 0 */
-            fd = open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE);
-            if (fd < 0) {
-                bsdPath[strlen(bsdPath)-1] = '1';
-            } else {
-                close(fd);
-            }
-            filename = bsdPath;
-        }
-
-        if ( mediaIterator )
-            IOObjectRelease( mediaIterator );
-    }
-#endif
-    open_flags = O_BINARY;
-    if ((flags & BDRV_O_ACCESS) == O_RDWR) {
-        open_flags |= O_RDWR;
-    } else {
-        open_flags |= O_RDONLY;
-        bs->read_only = 1;
-    }
-
-    s->type = FTYPE_FILE;
-#if defined(__linux__)
-    if (strstart(filename, "/dev/cd", NULL)) {
-        /* open will not fail even if no CD is inserted */
-        open_flags |= O_NONBLOCK;
-        s->type = FTYPE_CD;
-    } else if (strstart(filename, "/dev/fd", NULL)) {
-        s->type = FTYPE_FD;
-        s->fd_open_flags = open_flags;
-        /* open will not fail even if no floppy is inserted */
-        open_flags |= O_NONBLOCK;
-    }
-#endif
-    fd = open(filename, open_flags, 0644);
-    if (fd < 0) {
-        ret = -errno;
-        if (ret == -EROFS)
-            ret = -EACCES;
-        return ret;
-    }
-    s->fd = fd;
-#if defined(__linux__)
-    /* close fd so that we can reopen it as needed */
-    if (s->type == FTYPE_FD) {
-        close(s->fd);
-        s->fd = -1;
-        s->fd_media_changed = 1;
-    }
-#endif
-    return 0;
-}
-
-#if defined(__linux__) && !defined(QEMU_IMG)
-
-/* Note: we do not have a reliable method to detect if the floppy is
-   present. The current method is to try to open the floppy at every
-   I/O and to keep it opened during a few hundreds of ms. */
-static int fd_open(BlockDriverState *bs)
-{
-    BDRVRawState *s = bs->opaque;
-    int last_media_present;
-
-    if (s->type != FTYPE_FD)
-        return 0;
-    last_media_present = (s->fd >= 0);
-    if (s->fd >= 0 &&
-        (qemu_get_clock(rt_clock) - s->fd_open_time) >= FD_OPEN_TIMEOUT) {
-        close(s->fd);
-        s->fd = -1;
-#ifdef DEBUG_FLOPPY
-        printf("Floppy closed\n");
-#endif
-    }
-    if (s->fd < 0) {
-        if (s->fd_got_error &&
-            (qemu_get_clock(rt_clock) - s->fd_error_time) < FD_OPEN_TIMEOUT) {
-#ifdef DEBUG_FLOPPY
-            printf("No floppy (open delayed)\n");
-#endif
-            return -EIO;
-        }
-        s->fd = open(bs->filename, s->fd_open_flags);
-        if (s->fd < 0) {
-            s->fd_error_time = qemu_get_clock(rt_clock);
-            s->fd_got_error = 1;
-            if (last_media_present)
-                s->fd_media_changed = 1;
-#ifdef DEBUG_FLOPPY
-            printf("No floppy\n");
-#endif
-            return -EIO;
-        }
-#ifdef DEBUG_FLOPPY
-        printf("Floppy opened\n");
-#endif
-    }
-    if (!last_media_present)
-        s->fd_media_changed = 1;
-    s->fd_open_time = qemu_get_clock(rt_clock);
-    s->fd_got_error = 0;
-    return 0;
-}
-#else
-static int fd_open(BlockDriverState *bs)
-{
-    return 0;
-}
-#endif
-
-#if defined(__linux__)
-
-static int raw_is_inserted(BlockDriverState *bs)
-{
-    BDRVRawState *s = bs->opaque;
-    int ret;
-
-    switch(s->type) {
-    case FTYPE_CD:
-        ret = ioctl(s->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
-        if (ret == CDS_DISC_OK)
-            return 1;
-        else
-            return 0;
-        break;
-    case FTYPE_FD:
-        ret = fd_open(bs);
-        return (ret >= 0);
-    default:
-        return 1;
-    }
-}
-
-/* currently only used by fdc.c, but a CD version would be good too */
-static int raw_media_changed(BlockDriverState *bs)
-{
-    BDRVRawState *s = bs->opaque;
-
-    switch(s->type) {
-    case FTYPE_FD:
-        {
-            int ret;
-            /* XXX: we do not have a true media changed indication. It
-               does not work if the floppy is changed without trying
-               to read it */
-            fd_open(bs);
-            ret = s->fd_media_changed;
-            s->fd_media_changed = 0;
-#ifdef DEBUG_FLOPPY
-            printf("Floppy changed=%d\n", ret);
-#endif
-            return ret;
-        }
-    default:
-        return -ENOTSUP;
-    }
-}
-
-static int raw_eject(BlockDriverState *bs, int eject_flag)
-{
-    BDRVRawState *s = bs->opaque;
-
-    switch(s->type) {
-    case FTYPE_CD:
-        if (eject_flag) {
-            if (ioctl (s->fd, CDROMEJECT, NULL) < 0)
-                perror("CDROMEJECT");
-        } else {
-            if (ioctl (s->fd, CDROMCLOSETRAY, NULL) < 0)
-                perror("CDROMEJECT");
-        }
-        break;
-    case FTYPE_FD:
-        {
-            int fd;
-            if (s->fd >= 0) {
-                close(s->fd);
-                s->fd = -1;
-            }
-            fd = open(bs->filename, s->fd_open_flags | O_NONBLOCK);
-            if (fd >= 0) {
-                if (ioctl(fd, FDEJECT, 0) < 0)
-                    perror("FDEJECT");
-                close(fd);
-            }
-        }
-        break;
-    default:
-        return -ENOTSUP;
-    }
-    return 0;
-}
-
-static int raw_set_locked(BlockDriverState *bs, int locked)
-{
-    BDRVRawState *s = bs->opaque;
-
-    switch(s->type) {
-    case FTYPE_CD:
-        if (ioctl (s->fd, CDROM_LOCKDOOR, locked) < 0) {
-            /* Note: an error can happen if the distribution automatically
-               mounts the CD-ROM */
-            //        perror("CDROM_LOCKDOOR");
-        }
-        break;
-    default:
-        return -ENOTSUP;
-    }
-    return 0;
-}
-
-#else
-
-static int raw_is_inserted(BlockDriverState *bs)
-{
-    return 1;
-}
-
-static int raw_media_changed(BlockDriverState *bs)
-{
-    return -ENOTSUP;
-}
-
-static int raw_eject(BlockDriverState *bs, int eject_flag)
-{
-    return -ENOTSUP;
-}
-
-static int raw_set_locked(BlockDriverState *bs, int locked)
-{
-    return -ENOTSUP;
-}
-
-#endif /* !linux */
-
-BlockDriver bdrv_host_device = {
-    "host_device",
-    sizeof(BDRVRawState),
-    NULL, /* no probe for protocols */
-    hdev_open,
-    NULL,
-    NULL,
-    raw_close,
-    NULL,
-    raw_flush,
-
-    .bdrv_aio_read = raw_aio_read,
-    .bdrv_aio_write = raw_aio_write,
-    .bdrv_aio_cancel = raw_aio_cancel,
-    .aiocb_size = sizeof(RawAIOCB),
-    .bdrv_pread = raw_pread,
-    .bdrv_pwrite = raw_pwrite,
-    .bdrv_getlength = raw_getlength,
-
-    /* removable device support */
-    .bdrv_is_inserted = raw_is_inserted,
-    .bdrv_media_changed = raw_media_changed,
-    .bdrv_eject = raw_eject,
-    .bdrv_set_locked = raw_set_locked,
-};
-
-#else /* _WIN32 */
-
-/* XXX: use another file ? */
-#include <winioctl.h>
-
-#define FTYPE_FILE 0
-#define FTYPE_CD     1
-#define FTYPE_HARDDISK 2
-
-typedef struct BDRVRawState {
-    HANDLE hfile;
-    int type;
-    char drive_path[16]; /* format: "d:\" */
-} BDRVRawState;
-
-typedef struct RawAIOCB {
-    BlockDriverAIOCB common;
-    HANDLE hEvent;
-    OVERLAPPED ov;
-    int count;
-} RawAIOCB;
-
-int qemu_ftruncate64(int fd, int64_t length)
-{
-    LARGE_INTEGER li;
-    LONG high;
-    HANDLE h;
-    BOOL res;
-
-    if ((GetVersion() & 0x80000000UL) && (length >> 32) != 0)
-	return -1;
-
-    h = (HANDLE)_get_osfhandle(fd);
-
-    /* get current position, ftruncate do not change position */
-    li.HighPart = 0;
-    li.LowPart = SetFilePointer (h, 0, &li.HighPart, FILE_CURRENT);
-    if (li.LowPart == 0xffffffffUL && GetLastError() != NO_ERROR)
-	return -1;
-
-    high = length >> 32;
-    if (!SetFilePointer(h, (DWORD) length, &high, FILE_BEGIN))
-	return -1;
-    res = SetEndOfFile(h);
-
-    /* back to old position */
-    SetFilePointer(h, li.LowPart, &li.HighPart, FILE_BEGIN);
-    return res ? 0 : -1;
-}
-
-static int set_sparse(int fd)
-{
-    DWORD returned;
-    return (int) DeviceIoControl((HANDLE)_get_osfhandle(fd), FSCTL_SET_SPARSE,
-				 NULL, 0, NULL, 0, &returned, NULL);
-}
-
-static int raw_open(BlockDriverState *bs, const char *filename, int flags)
-{
-    BDRVRawState *s = bs->opaque;
-    int access_flags, create_flags;
-    DWORD overlapped;
-
-    s->type = FTYPE_FILE;
-
-    if ((flags & BDRV_O_ACCESS) == O_RDWR) {
-        access_flags = GENERIC_READ | GENERIC_WRITE;
-    } else {
-        access_flags = GENERIC_READ;
-    }
-    if (flags & BDRV_O_CREAT) {
-        create_flags = CREATE_ALWAYS;
-    } else {
-        create_flags = OPEN_EXISTING;
-    }
-#ifdef QEMU_IMG
-    overlapped = FILE_ATTRIBUTE_NORMAL;
-#else
-    overlapped = FILE_FLAG_OVERLAPPED;
-#endif
-    s->hfile = CreateFile(filename, access_flags,
-                          FILE_SHARE_READ, NULL,
-                          create_flags, overlapped, NULL);
-    if (s->hfile == INVALID_HANDLE_VALUE) {
-        int err = GetLastError();
-
-        if (err == ERROR_ACCESS_DENIED)
-            return -EACCES;
-        return -1;
-    }
-    return 0;
-}
-
-static int raw_pread(BlockDriverState *bs, int64_t offset,
-                     uint8_t *buf, int count)
-{
-    BDRVRawState *s = bs->opaque;
-    OVERLAPPED ov;
-    DWORD ret_count;
-    int ret;
-
-    memset(&ov, 0, sizeof(ov));
-    ov.Offset = offset;
-    ov.OffsetHigh = offset >> 32;
-    ret = ReadFile(s->hfile, buf, count, &ret_count, &ov);
-    if (!ret) {
-        ret = GetOverlappedResult(s->hfile, &ov, &ret_count, TRUE);
-        if (!ret)
-            return -EIO;
-        else
-            return ret_count;
-    }
-    return ret_count;
-}
-
-static int raw_pwrite(BlockDriverState *bs, int64_t offset,
-                      const uint8_t *buf, int count)
-{
-    BDRVRawState *s = bs->opaque;
-    OVERLAPPED ov;
-    DWORD ret_count;
-    int ret;
-
-    memset(&ov, 0, sizeof(ov));
-    ov.Offset = offset;
-    ov.OffsetHigh = offset >> 32;
-    ret = WriteFile(s->hfile, buf, count, &ret_count, &ov);
-    if (!ret) {
-        ret = GetOverlappedResult(s->hfile, &ov, &ret_count, TRUE);
-        if (!ret)
-            return -EIO;
-        else
-            return ret_count;
-    }
-    return ret_count;
-}
-
-#if 0
-#ifndef QEMU_IMG
-static void raw_aio_cb(void *opaque)
-{
-    RawAIOCB *acb = opaque;
-    BlockDriverState *bs = acb->common.bs;
-    BDRVRawState *s = bs->opaque;
-    DWORD ret_count;
-    int ret;
-
-    ret = GetOverlappedResult(s->hfile, &acb->ov, &ret_count, TRUE);
-    if (!ret || ret_count != acb->count) {
-        acb->common.cb(acb->common.opaque, -EIO);
-    } else {
-        acb->common.cb(acb->common.opaque, 0);
-    }
-}
-#endif
-
-static RawAIOCB *raw_aio_setup(BlockDriverState *bs,
-        int64_t sector_num, uint8_t *buf, int nb_sectors,
-        BlockDriverCompletionFunc *cb, void *opaque)
-{
-    RawAIOCB *acb;
-    int64_t offset;
-
-    acb = qemu_aio_get(bs, cb, opaque);
-    if (acb->hEvent) {
-        acb->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
-        if (!acb->hEvent) {
-            qemu_aio_release(acb);
-            return NULL;
-        }
-    }
-    memset(&acb->ov, 0, sizeof(acb->ov));
-    offset = sector_num * 512;
-    acb->ov.Offset = offset;
-    acb->ov.OffsetHigh = offset >> 32;
-    acb->ov.hEvent = acb->hEvent;
-    acb->count = nb_sectors * 512;
-#ifndef QEMU_IMG
-    qemu_add_wait_object(acb->ov.hEvent, raw_aio_cb, acb);
-#endif
-    return acb;
-}
-
-static BlockDriverAIOCB *raw_aio_read(BlockDriverState *bs,
-        int64_t sector_num, uint8_t *buf, int nb_sectors,
-        BlockDriverCompletionFunc *cb, void *opaque)
-{
-    BDRVRawState *s = bs->opaque;
-    RawAIOCB *acb;
-    int ret;
-
-    acb = raw_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque);
-    if (!acb)
-        return NULL;
-    ret = ReadFile(s->hfile, buf, acb->count, NULL, &acb->ov);
-    if (!ret) {
-        qemu_aio_release(acb);
-        return NULL;
-    }
-#ifdef QEMU_IMG
-    qemu_aio_release(acb);
-#endif
-    return (BlockDriverAIOCB *)acb;
-}
-
-static BlockDriverAIOCB *raw_aio_write(BlockDriverState *bs,
-        int64_t sector_num, uint8_t *buf, int nb_sectors,
-        BlockDriverCompletionFunc *cb, void *opaque)
-{
-    BDRVRawState *s = bs->opaque;
-    RawAIOCB *acb;
-    int ret;
-
-    acb = raw_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque);
-    if (!acb)
-        return NULL;
-    ret = WriteFile(s->hfile, buf, acb->count, NULL, &acb->ov);
-    if (!ret) {
-        qemu_aio_release(acb);
-        return NULL;
-    }
-#ifdef QEMU_IMG
-    qemu_aio_release(acb);
-#endif
-    return (BlockDriverAIOCB *)acb;
-}
-
-static void raw_aio_cancel(BlockDriverAIOCB *blockacb)
-{
-#ifndef QEMU_IMG
-    RawAIOCB *acb = (RawAIOCB *)blockacb;
-    BlockDriverState *bs = acb->common.bs;
-    BDRVRawState *s = bs->opaque;
-
-    qemu_del_wait_object(acb->ov.hEvent, raw_aio_cb, acb);
-    /* XXX: if more than one async I/O it is not correct */
-    CancelIo(s->hfile);
-    qemu_aio_release(acb);
-#endif
-}
-#endif /* #if 0 */
-
-static void raw_flush(BlockDriverState *bs)
-{
-    BDRVRawState *s = bs->opaque;
-    FlushFileBuffers(s->hfile);
-}
-
-static void raw_close(BlockDriverState *bs)
-{
-    BDRVRawState *s = bs->opaque;
-    CloseHandle(s->hfile);
-}
-
-static int raw_truncate(BlockDriverState *bs, int64_t offset)
-{
-    BDRVRawState *s = bs->opaque;
-    DWORD low, high;
-
-    low = offset;
-    high = offset >> 32;
-    if (!SetFilePointer(s->hfile, low, &high, FILE_BEGIN))
-	return -EIO;
-    if (!SetEndOfFile(s->hfile))
-        return -EIO;
-    return 0;
-}
-
-static int64_t raw_getlength(BlockDriverState *bs)
-{
-    BDRVRawState *s = bs->opaque;
-    LARGE_INTEGER l;
-    ULARGE_INTEGER available, total, total_free;
-    DISK_GEOMETRY_EX dg;
-    DWORD count;
-    BOOL status;
-
-    switch(s->type) {
-    case FTYPE_FILE:
-        l.LowPart = GetFileSize(s->hfile, &l.HighPart);
-        if (l.LowPart == 0xffffffffUL && GetLastError() != NO_ERROR)
-            return -EIO;
-        break;
-    case FTYPE_CD:
-        if (!GetDiskFreeSpaceEx(s->drive_path, &available, &total, &total_free))
-            return -EIO;
-        l.QuadPart = total.QuadPart;
-        break;
-    case FTYPE_HARDDISK:
-        status = DeviceIoControl(s->hfile, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
-                                 NULL, 0, &dg, sizeof(dg), &count, NULL);
-        if (status != 0) {
-            l = dg.DiskSize;
-        }
-        break;
-    default:
-        return -EIO;
-    }
-    return l.QuadPart;
-}
-
-static int raw_create(const char *filename, int64_t total_size,
-                      const char *backing_file, int flags)
-{
-    int fd;
-
-    if (flags || backing_file)
-        return -ENOTSUP;
-
-    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
-              0644);
-    if (fd < 0)
-        return -EIO;
-    set_sparse(fd);
-    ftruncate(fd, total_size * 512);
-    close(fd);
-    return 0;
-}
-
-void qemu_aio_init(void)
-{
-}
-
-void qemu_aio_poll(void)
-{
-}
-
-void qemu_aio_flush(void)
-{
-}
-
-void qemu_aio_wait_start(void)
-{
-}
-
-void qemu_aio_wait(void)
-{
-#ifndef QEMU_IMG
-    qemu_bh_poll();
-#endif
-}
-
-void qemu_aio_wait_end(void)
-{
-}
-
-BlockDriver bdrv_raw = {
-    "raw",
-    sizeof(BDRVRawState),
-    NULL, /* no probe for protocols */
-    raw_open,
-    NULL,
-    NULL,
-    raw_close,
-    raw_create,
-    raw_flush,
-
-#if 0
-    .bdrv_aio_read = raw_aio_read,
-    .bdrv_aio_write = raw_aio_write,
-    .bdrv_aio_cancel = raw_aio_cancel,
-    .aiocb_size = sizeof(RawAIOCB);
-#endif
-    .protocol_name = "file",
-    .bdrv_pread = raw_pread,
-    .bdrv_pwrite = raw_pwrite,
-    .bdrv_truncate = raw_truncate,
-    .bdrv_getlength = raw_getlength,
-};
-
-/***********************************************/
-/* host device */
-
-static int find_cdrom(char *cdrom_name, int cdrom_name_size)
-{
-    char drives[256], *pdrv = drives;
-    UINT type;
-
-    memset(drives, 0, sizeof(drives));
-    GetLogicalDriveStrings(sizeof(drives), drives);
-    while(pdrv[0] != '\0') {
-        type = GetDriveType(pdrv);
-        switch(type) {
-        case DRIVE_CDROM:
-            snprintf(cdrom_name, cdrom_name_size, "\\\\.\\%c:", pdrv[0]);
-            return 0;
-            break;
-        }
-        pdrv += lstrlen(pdrv) + 1;
-    }
-    return -1;
-}
-
-static int find_device_type(BlockDriverState *bs, const char *filename)
-{
-    BDRVRawState *s = bs->opaque;
-    UINT type;
-    const char *p;
-
-    if (strstart(filename, "\\\\.\\", &p) ||
-        strstart(filename, "//./", &p)) {
-        if (stristart(p, "PhysicalDrive", NULL))
-            return FTYPE_HARDDISK;
-        snprintf(s->drive_path, sizeof(s->drive_path), "%c:\\", p[0]);
-        type = GetDriveType(s->drive_path);
-        if (type == DRIVE_CDROM)
-            return FTYPE_CD;
-        else
-            return FTYPE_FILE;
-    } else {
-        return FTYPE_FILE;
-    }
-}
-
-static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
-{
-    BDRVRawState *s = bs->opaque;
-    int access_flags, create_flags;
-    DWORD overlapped;
-    char device_name[64];
-
-    if (strstart(filename, "/dev/cdrom", NULL)) {
-        if (find_cdrom(device_name, sizeof(device_name)) < 0)
-            return -ENOENT;
-        filename = device_name;
-    } else {
-        /* transform drive letters into device name */
-        if (((filename[0] >= 'a' && filename[0] <= 'z') ||
-             (filename[0] >= 'A' && filename[0] <= 'Z')) &&
-            filename[1] == ':' && filename[2] == '\0') {
-            snprintf(device_name, sizeof(device_name), "\\\\.\\%c:", filename[0]);
-            filename = device_name;
-        }
-    }
-    s->type = find_device_type(bs, filename);
-
-    if ((flags & BDRV_O_ACCESS) == O_RDWR) {
-        access_flags = GENERIC_READ | GENERIC_WRITE;
-    } else {
-        access_flags = GENERIC_READ;
-    }
-    create_flags = OPEN_EXISTING;
-
-#ifdef QEMU_IMG
-    overlapped = FILE_ATTRIBUTE_NORMAL;
-#else
-    overlapped = FILE_FLAG_OVERLAPPED;
-#endif
-    s->hfile = CreateFile(filename, access_flags,
-                          FILE_SHARE_READ, NULL,
-                          create_flags, overlapped, NULL);
-    if (s->hfile == INVALID_HANDLE_VALUE) {
-        int err = GetLastError();
-
-        if (err == ERROR_ACCESS_DENIED)
-            return -EACCES;
-        return -1;
-    }
-    return 0;
-}
-
-#if 0
-/***********************************************/
-/* removable device additional commands */
-
-static int raw_is_inserted(BlockDriverState *bs)
-{
-    return 1;
-}
-
-static int raw_media_changed(BlockDriverState *bs)
-{
-    return -ENOTSUP;
-}
-
-static int raw_eject(BlockDriverState *bs, int eject_flag)
-{
-    DWORD ret_count;
-
-    if (s->type == FTYPE_FILE)
-        return -ENOTSUP;
-    if (eject_flag) {
-        DeviceIoControl(s->hfile, IOCTL_STORAGE_EJECT_MEDIA,
-                        NULL, 0, NULL, 0, &lpBytesReturned, NULL);
-    } else {
-        DeviceIoControl(s->hfile, IOCTL_STORAGE_LOAD_MEDIA,
-                        NULL, 0, NULL, 0, &lpBytesReturned, NULL);
-    }
-}
-
-static int raw_set_locked(BlockDriverState *bs, int locked)
-{
-    return -ENOTSUP;
-}
-#endif
-
-BlockDriver bdrv_host_device = {
-    "host_device",
-    sizeof(BDRVRawState),
-    NULL, /* no probe for protocols */
-    hdev_open,
-    NULL,
-    NULL,
-    raw_close,
-    NULL,
-    raw_flush,
-
-#if 0
-    .bdrv_aio_read = raw_aio_read,
-    .bdrv_aio_write = raw_aio_write,
-    .bdrv_aio_cancel = raw_aio_cancel,
-    .aiocb_size = sizeof(RawAIOCB);
-#endif
-    .bdrv_pread = raw_pread,
-    .bdrv_pwrite = raw_pwrite,
-    .bdrv_getlength = raw_getlength,
-};
-#endif /* _WIN32 */

Modified: trunk/src/host/qemu-neo1973/block-vpc.c
===================================================================
--- trunk/src/host/qemu-neo1973/block-vpc.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/block-vpc.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -81,7 +81,7 @@
 
 static int vpc_probe(const uint8_t *buf, int buf_size, const char *filename)
 {
-    if (buf_size >= 8 && !strncmp(buf, "conectix", 8))
+    if (buf_size >= 8 && !strncmp((char *)buf, "conectix", 8))
 	return 100;
     return 0;
 }

Modified: trunk/src/host/qemu-neo1973/block-vvfat.c
===================================================================
--- trunk/src/host/qemu-neo1973/block-vvfat.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/block-vvfat.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -412,7 +412,7 @@
 /* direntry functions */
 
 /* dest is assumed to hold 258 bytes, and pads with 0xffff up to next multiple of 26 */
-static inline int short2long_name(unsigned char* dest,const char* src)
+static inline int short2long_name(char* dest,const char* src)
 {
     int i;
     for(i=0;i<129 && src[i];i++) {
@@ -565,7 +565,7 @@
 	uint16_t* entry=array_get(&(s->fat),cluster);
 	return le16_to_cpu(*entry);
     } else {
-	const uint8_t* x=s->fat.pointer+cluster*3/2;
+	const uint8_t* x=(uint8_t*)(s->fat.pointer)+cluster*3/2;
 	return ((x[0]|(x[1]<<8))>>(cluster&1?4:0))&0x0fff;
     }
 }
@@ -626,7 +626,7 @@
 
     entry=array_get_next(&(s->directory));
     memset(entry->name,0x20,11);
-    strncpy(entry->name,filename,i);
+    strncpy((char*)entry->name,filename,i);
 
     if(j > 0)
 	for (i = 0; i < 3 && filename[j+1+i]; i++)
@@ -868,7 +868,7 @@
     {
 	direntry_t* entry=array_get_next(&(s->directory));
 	entry->attributes=0x28; /* archive | volume label */
-	snprintf(entry->name,11,"QEMU VVFAT");
+	snprintf((char*)entry->name,11,"QEMU VVFAT");
     }
 
     /* Now build FAT, and write back information into directory */
@@ -1187,7 +1187,7 @@
 		s->current_mapping = mapping;
 read_cluster_directory:
 		offset = s->cluster_size*(cluster_num-s->current_mapping->begin);
-		s->cluster = s->directory.pointer+offset
+		s->cluster = (unsigned char*)s->directory.pointer+offset
 			+ 0x20*s->current_mapping->info.dir.first_dir_index;
 		assert(((s->cluster-(unsigned char*)s->directory.pointer)%s->cluster_size)==0);
 		assert((char*)s->cluster+s->cluster_size <= s->directory.pointer+s->directory.next*s->directory.item_size);
@@ -1457,7 +1457,7 @@
     }
 
     if (pointer[0] & 0x40)
-	lfn->len = offset + strlen(lfn->name + offset);
+	lfn->len = offset + strlen((char*)lfn->name + offset);
 
     return 0;
 }
@@ -1496,7 +1496,7 @@
     } else
 	lfn->name[i + j + 1] = '\0';
 
-    lfn->len = strlen(lfn->name);
+    lfn->len = strlen((char*)lfn->name);
 
     return 0;
 }
@@ -1792,8 +1792,8 @@
 		    fprintf(stderr, "Error in short name (%d)\n", subret);
 		    goto fail;
 		}
-		if (subret > 0 || !strcmp(lfn.name, ".")
-			|| !strcmp(lfn.name, ".."))
+		if (subret > 0 || !strcmp((char*)lfn.name, ".")
+			|| !strcmp((char*)lfn.name, ".."))
 		    continue;
 	    }
 	    lfn.checksum = 0x100; /* cannot use long name twice */
@@ -1802,7 +1802,7 @@
 		fprintf(stderr, "Name too long: %s/%s\n", path, lfn.name);
 		goto fail;
 	    }
-	    strcpy(path2 + path_len + 1, lfn.name);
+	    strcpy(path2 + path_len + 1, (char*)lfn.name);
 
 	    if (is_directory(direntries + i)) {
 		if (begin_of_direntry(direntries + i) == 0) {
@@ -2234,7 +2234,7 @@
 	assert(size >= 0);
 
 	ret = vvfat_read(s->bs, cluster2sector(s, c),
-	    cluster, (rest_size + 0x1ff) / 0x200);
+	    (uint8_t*)cluster, (rest_size + 0x1ff) / 0x200);
 
 	if (ret < 0)
 	    return ret;

Modified: trunk/src/host/qemu-neo1973/cpu-all.h
===================================================================
--- trunk/src/host/qemu-neo1973/cpu-all.h	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/cpu-all.h	2007-12-17 17:52:55 UTC (rev 3665)
@@ -716,6 +716,7 @@
 /* original state of the write flag (used when tracking self-modifying
    code */
 #define PAGE_WRITE_ORG 0x0010
+#define PAGE_RESERVED  0x0020
 
 void page_dump(FILE *f);
 int page_get_flags(target_ulong address);

Modified: trunk/src/host/qemu-neo1973/cpu-exec.c
===================================================================
--- trunk/src/host/qemu-neo1973/cpu-exec.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/cpu-exec.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -40,6 +40,52 @@
 //#define DEBUG_EXEC
 //#define DEBUG_SIGNAL
 
+#define SAVE_GLOBALS()
+#define RESTORE_GLOBALS()
+
+#if defined(__sparc__) && !defined(HOST_SOLARIS)
+#include <features.h>
+#if defined(__GLIBC__) && ((__GLIBC__ < 2) || \
+                           ((__GLIBC__ == 2) && (__GLIBC_MINOR__ <= 90)))
+// Work around ugly bugs in glibc that mangle global register contents
+
+static volatile void *saved_env;
+static volatile unsigned long saved_t0, saved_i7;
+#undef SAVE_GLOBALS
+#define SAVE_GLOBALS() do {                                     \
+        saved_env = env;                                        \
+        saved_t0 = T0;                                          \
+        asm volatile ("st %%i7, [%0]" : : "r" (&saved_i7));     \
+    } while(0)
+
+#undef RESTORE_GLOBALS
+#define RESTORE_GLOBALS() do {                                  \
+        env = (void *)saved_env;                                \
+        T0 = saved_t0;                                          \
+        asm volatile ("ld [%0], %%i7" : : "r" (&saved_i7));     \
+    } while(0)
+
+static int sparc_setjmp(jmp_buf buf)
+{
+    int ret;
+
+    SAVE_GLOBALS();
+    ret = setjmp(buf);
+    RESTORE_GLOBALS();
+    return ret;
+}
+#undef setjmp
+#define setjmp(jmp_buf) sparc_setjmp(jmp_buf)
+
+static void sparc_longjmp(jmp_buf buf, int val)
+{
+    SAVE_GLOBALS();
+    longjmp(buf, val);
+}
+#define longjmp(jmp_buf, val) sparc_longjmp(jmp_buf, val)
+#endif
+#endif
+
 void cpu_loop_exit(void)
 {
     /* NOTE: the register at this point must be saved by hand because
@@ -133,7 +179,9 @@
     tb->tc_ptr = tc_ptr;
     tb->cs_base = cs_base;
     tb->flags = flags;
-    cpu_gen_code(env, tb, CODE_GEN_MAX_SIZE, &code_gen_size);
+    SAVE_GLOBALS();
+    cpu_gen_code(env, tb, &code_gen_size);
+    RESTORE_GLOBALS();
     code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
 
     /* check next page if needed */
@@ -232,11 +280,7 @@
     return tb;
 }
 
-#if defined(__sparc__) && !defined(HOST_SOLARIS)
-#define BREAK_CHAIN tmp_T0 = 0
-#else
 #define BREAK_CHAIN T0 = 0
-#endif
 
 /* main execution loop */
 
@@ -249,10 +293,6 @@
     uint32_t *saved_regwptr;
 #endif
 #endif
-#if defined(__sparc__) && !defined(HOST_SOLARIS)
-    int saved_i7;
-    target_ulong tmp_T0;
-#endif
     int ret, interrupt_request;
     void (*gen_func)(void);
     TranslationBlock *tb;
@@ -267,10 +307,7 @@
 #define SAVE_HOST_REGS 1
 #include "hostregs_helper.h"
     env = env1;
-#if defined(__sparc__) && !defined(HOST_SOLARIS)
-    /* we also save i7 because longjmp may not restore it */
-    asm volatile ("mov %%i7, %0" : "=r" (saved_i7));
-#endif
+    SAVE_GLOBALS();
 
     env_to_regs();
 #if defined(TARGET_I386)
@@ -380,10 +417,7 @@
 
             T0 = 0; /* force lookup of first TB */
             for(;;) {
-#if defined(__sparc__) && !defined(HOST_SOLARIS)
-                /* g1 can be modified by some libc? functions */
-                tmp_T0 = T0;
-#endif
+                SAVE_GLOBALS();
                 interrupt_request = env->interrupt_request;
                 if (__builtin_expect(interrupt_request, 0)
 #if defined(TARGET_I386)
@@ -597,9 +631,7 @@
                             lookup_symbol(tb->pc));
                 }
 #endif
-#if defined(__sparc__) && !defined(HOST_SOLARIS)
-                T0 = tmp_T0;
-#endif
+                RESTORE_GLOBALS();
                 /* see if we can patch the calling TB. When the TB
                    spans two pages, we cannot safely do a direct
                    jump. */
@@ -695,9 +727,7 @@
 #endif
 
     /* restore global registers */
-#if defined(__sparc__) && !defined(HOST_SOLARIS)
-    asm volatile ("mov %0, %%i7" : : "r" (saved_i7));
-#endif
+    RESTORE_GLOBALS();
 #include "hostregs_helper.h"
 
     /* fail safe : never use cpu_single_env outside cpu_exec() */

Modified: trunk/src/host/qemu-neo1973/exec-all.h
===================================================================
--- trunk/src/host/qemu-neo1973/exec-all.h	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/exec-all.h	2007-12-17 17:52:55 UTC (rev 3665)
@@ -64,8 +64,9 @@
 int gen_intermediate_code(CPUState *env, struct TranslationBlock *tb);
 int gen_intermediate_code_pc(CPUState *env, struct TranslationBlock *tb);
 void dump_ops(const uint16_t *opc_buf, const uint32_t *opparam_buf);
+unsigned long code_gen_max_block_size(void);
 int cpu_gen_code(CPUState *env, struct TranslationBlock *tb,
-                 int max_code_size, int *gen_code_size_ptr);
+                 int *gen_code_size_ptr);
 int cpu_restore_state(struct TranslationBlock *tb,
                       CPUState *env, unsigned long searched_pc,
                       void *puc);
@@ -94,7 +95,6 @@
     return tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
 }
 
-#define CODE_GEN_MAX_SIZE        65536
 #define CODE_GEN_ALIGN           16 /* must be >= of the size of a icache line */
 
 #define CODE_GEN_PHYS_HASH_BITS     15

Modified: trunk/src/host/qemu-neo1973/exec.c
===================================================================
--- trunk/src/host/qemu-neo1973/exec.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/exec.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -56,7 +56,7 @@
 #endif
 
 /* threshold to flush the translated code buffer */
-#define CODE_GEN_BUFFER_MAX_SIZE (CODE_GEN_BUFFER_SIZE - CODE_GEN_MAX_SIZE)
+#define CODE_GEN_BUFFER_MAX_SIZE (CODE_GEN_BUFFER_SIZE - code_gen_max_block_size())
 
 #define SMC_BITMAP_USE_THRESHOLD 10
 
@@ -209,6 +209,27 @@
     qemu_host_page_mask = ~(qemu_host_page_size - 1);
     l1_phys_map = qemu_vmalloc(L1_SIZE * sizeof(void *));
     memset(l1_phys_map, 0, L1_SIZE * sizeof(void *));
+
+#if !defined(_WIN32) && defined(CONFIG_USER_ONLY)
+    {
+        long long startaddr, endaddr;
+        FILE *f;
+        int n;
+
+        f = fopen("/proc/self/maps", "r");
+        if (f) {
+            do {
+                n = fscanf (f, "%llx-%llx %*[^\n]\n", &startaddr, &endaddr);
+                if (n == 2) {
+                    page_set_flags(TARGET_PAGE_ALIGN(startaddr),
+                                   TARGET_PAGE_ALIGN(endaddr),
+                                   PAGE_RESERVED); 
+                }
+            } while (!feof(f));
+            fclose(f);
+        }
+    }
+#endif
 }
 
 static inline PageDesc *page_find_alloc(unsigned int index)
@@ -622,7 +643,7 @@
     tb->cs_base = cs_base;
     tb->flags = flags;
     tb->cflags = cflags;
-    cpu_gen_code(env, tb, CODE_GEN_MAX_SIZE, &code_gen_size);
+    cpu_gen_code(env, tb, &code_gen_size);
     code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
 
     /* check next page if needed */

Modified: trunk/src/host/qemu-neo1973/gdbstub.c
===================================================================
--- trunk/src/host/qemu-neo1973/gdbstub.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/gdbstub.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -63,7 +63,7 @@
     char line_buf[4096];
     int line_buf_index;
     int line_csum;
-    char last_packet[4100];
+    uint8_t last_packet[4100];
     int last_packet_len;
 #ifdef CONFIG_USER_ONLY
     int fd;
@@ -188,7 +188,7 @@
 static int put_packet(GDBState *s, char *buf)
 {
     int len, csum, i;
-    char *p;
+    uint8_t *p;
 
 #ifdef DEBUG_GDB
     printf("reply='%s'\n", buf);
@@ -209,7 +209,7 @@
         *(p++) = tohex((csum) & 0xf);
 
         s->last_packet_len = p - s->last_packet;
-        put_buffer(s, s->last_packet, s->last_packet_len);
+        put_buffer(s, (uint8_t *)s->last_packet, s->last_packet_len);
 
 #ifdef CONFIG_USER_ONLY
         i = get_char(s);
@@ -1179,7 +1179,7 @@
 {
     CPUState *env = s->env;
     int i, csum;
-    char reply[1];
+    uint8_t reply;
 
 #ifndef CONFIG_USER_ONLY
     if (s->last_packet_len) {
@@ -1189,7 +1189,7 @@
 #ifdef DEBUG_GDB
             printf("Got NACK, retransmitting\n");
 #endif
-            put_buffer(s, s->last_packet, s->last_packet_len);
+            put_buffer(s, (uint8_t *)s->last_packet, s->last_packet_len);
         }
 #ifdef DEBUG_GDB
         else if (ch == '+')
@@ -1237,12 +1237,12 @@
                 csum += s->line_buf[i];
             }
             if (s->line_csum != (csum & 0xff)) {
-                reply[0] = '-';
-                put_buffer(s, reply, 1);
+                reply = '-';
+                put_buffer(s, &reply, 1);
                 s->state = RS_IDLE;
             } else {
-                reply[0] = '+';
-                put_buffer(s, reply, 1);
+                reply = '+';
+                put_buffer(s, &reply, 1);
                 s->state = gdb_handle_packet(s, env, s->line_buf);
             }
             break;

Modified: trunk/src/host/qemu-neo1973/hw/acpi.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/acpi.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/hw/acpi.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -439,7 +439,7 @@
     qemu_put_8s(f, &s->apmc);
     qemu_put_8s(f, &s->apms);
     qemu_put_timer(f, s->tmr_timer);
-    qemu_put_be64s(f, &s->tmr_overflow_time);
+    qemu_put_be64(f, s->tmr_overflow_time);
 }
 
 static int pm_load(QEMUFile* f,void* opaque,int version_id)
@@ -460,7 +460,7 @@
     qemu_get_8s(f, &s->apmc);
     qemu_get_8s(f, &s->apms);
     qemu_get_timer(f, s->tmr_timer);
-    qemu_get_be64s(f, &s->tmr_overflow_time);
+    s->tmr_overflow_time=qemu_get_be64(f);
 
     pm_io_space_update(s);
 

Modified: trunk/src/host/qemu-neo1973/hw/apic.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/apic.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/hw/apic.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -761,10 +761,10 @@
     qemu_put_be32s(f, &s->icr[0]);
     qemu_put_be32s(f, &s->icr[1]);
     qemu_put_be32s(f, &s->divide_conf);
-    qemu_put_be32s(f, &s->count_shift);
+    qemu_put_be32(f, s->count_shift);
     qemu_put_be32s(f, &s->initial_count);
-    qemu_put_be64s(f, &s->initial_count_load_time);
-    qemu_put_be64s(f, &s->next_time);
+    qemu_put_be64(f, s->initial_count_load_time);
+    qemu_put_be64(f, s->next_time);
 
     qemu_put_timer(f, s->timer);
 }
@@ -797,10 +797,10 @@
     qemu_get_be32s(f, &s->icr[0]);
     qemu_get_be32s(f, &s->icr[1]);
     qemu_get_be32s(f, &s->divide_conf);
-    qemu_get_be32s(f, &s->count_shift);
+    s->count_shift=qemu_get_be32(f);
     qemu_get_be32s(f, &s->initial_count);
-    qemu_get_be64s(f, &s->initial_count_load_time);
-    qemu_get_be64s(f, &s->next_time);
+    s->initial_count_load_time=qemu_get_be64(f);
+    s->next_time=qemu_get_be64(f);
 
     if (version_id >= 2)
         qemu_get_timer(f, s->timer);

Modified: trunk/src/host/qemu-neo1973/hw/boards.h
===================================================================
--- trunk/src/host/qemu-neo1973/hw/boards.h	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/hw/boards.h	2007-12-17 17:52:55 UTC (rev 3665)
@@ -52,7 +52,7 @@
 extern QEMUMachine r2d_machine;
 
 /* sun4m.c */
-extern QEMUMachine ss5_machine, ss10_machine, ss600mp_machine;
+extern QEMUMachine ss5_machine, ss10_machine, ss600mp_machine, ss20_machine;
 
 /* sun4u.c */
 extern QEMUMachine sun4u_machine;

Modified: trunk/src/host/qemu-neo1973/hw/cirrus_vga.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/cirrus_vga.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/hw/cirrus_vga.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -2985,7 +2985,7 @@
     qemu_put_buffer(f, s->gr + 2, 254);
     qemu_put_8s(f, &s->ar_index);
     qemu_put_buffer(f, s->ar, 21);
-    qemu_put_be32s(f, &s->ar_flip_flop);
+    qemu_put_be32(f, s->ar_flip_flop);
     qemu_put_8s(f, &s->cr_index);
     qemu_put_buffer(f, s->cr, 256);
     qemu_put_8s(f, &s->msr);
@@ -3000,7 +3000,7 @@
     qemu_put_buffer(f, s->dac_cache, 3);
     qemu_put_buffer(f, s->palette, 768);
 
-    qemu_put_be32s(f, &s->bank_offset);
+    qemu_put_be32(f, s->bank_offset);
 
     qemu_put_8s(f, &s->cirrus_hidden_dac_lockindex);
     qemu_put_8s(f, &s->cirrus_hidden_dac_data);
@@ -3036,7 +3036,7 @@
     qemu_get_buffer(f, s->gr + 2, 254);
     qemu_get_8s(f, &s->ar_index);
     qemu_get_buffer(f, s->ar, 21);
-    qemu_get_be32s(f, &s->ar_flip_flop);
+    s->ar_flip_flop=qemu_get_be32(f);
     qemu_get_8s(f, &s->cr_index);
     qemu_get_buffer(f, s->cr, 256);
     qemu_get_8s(f, &s->msr);
@@ -3051,7 +3051,7 @@
     qemu_get_buffer(f, s->dac_cache, 3);
     qemu_get_buffer(f, s->palette, 768);
 
-    qemu_get_be32s(f, &s->bank_offset);
+    s->bank_offset=qemu_get_be32(f);
 
     qemu_get_8s(f, &s->cirrus_hidden_dac_lockindex);
     qemu_get_8s(f, &s->cirrus_hidden_dac_data);

Modified: trunk/src/host/qemu-neo1973/hw/dma.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/dma.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/hw/dma.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -482,12 +482,12 @@
     qemu_put_8s (f, &d->command);
     qemu_put_8s (f, &d->mask);
     qemu_put_8s (f, &d->flip_flop);
-    qemu_put_be32s (f, &d->dshift);
+    qemu_put_be32 (f, d->dshift);
 
     for (i = 0; i < 4; ++i) {
         struct dma_regs *r = &d->regs[i];
-        qemu_put_be32s (f, &r->now[0]);
-        qemu_put_be32s (f, &r->now[1]);
+        qemu_put_be32 (f, r->now[0]);
+        qemu_put_be32 (f, r->now[1]);
         qemu_put_be16s (f, &r->base[0]);
         qemu_put_be16s (f, &r->base[1]);
         qemu_put_8s (f, &r->mode);
@@ -510,12 +510,12 @@
     qemu_get_8s (f, &d->command);
     qemu_get_8s (f, &d->mask);
     qemu_get_8s (f, &d->flip_flop);
-    qemu_get_be32s (f, &d->dshift);
+    d->dshift=qemu_get_be32 (f);
 
     for (i = 0; i < 4; ++i) {
         struct dma_regs *r = &d->regs[i];
-        qemu_get_be32s (f, &r->now[0]);
-        qemu_get_be32s (f, &r->now[1]);
+        r->now[0]=qemu_get_be32 (f);
+        r->now[1]=qemu_get_be32 (f);
         qemu_get_be16s (f, &r->base[0]);
         qemu_get_be16s (f, &r->base[1]);
         qemu_get_8s (f, &r->mode);

Modified: trunk/src/host/qemu-neo1973/hw/fdc.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/fdc.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/hw/fdc.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -180,7 +180,7 @@
     uint8_t last_sect;
     uint8_t max_track;
     uint8_t max_head;
-    const unsigned char *str;
+    const char *str;
 } fd_format_t;
 
 static const fd_format_t fd_formats[] = {

Modified: trunk/src/host/qemu-neo1973/hw/i8254.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/i8254.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/hw/i8254.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -397,7 +397,7 @@
 
     for(i = 0; i < 3; i++) {
         s = &pit->channels[i];
-        qemu_put_be32s(f, &s->count);
+        qemu_put_be32(f, s->count);
         qemu_put_be16s(f, &s->latched_count);
         qemu_put_8s(f, &s->count_latched);
         qemu_put_8s(f, &s->status_latched);
@@ -409,9 +409,9 @@
         qemu_put_8s(f, &s->mode);
         qemu_put_8s(f, &s->bcd);
         qemu_put_8s(f, &s->gate);
-        qemu_put_be64s(f, &s->count_load_time);
+        qemu_put_be64(f, s->count_load_time);
         if (s->irq_timer) {
-            qemu_put_be64s(f, &s->next_transition_time);
+            qemu_put_be64(f, s->next_transition_time);
             qemu_put_timer(f, s->irq_timer);
         }
     }
@@ -428,7 +428,7 @@
 
     for(i = 0; i < 3; i++) {
         s = &pit->channels[i];
-        qemu_get_be32s(f, &s->count);
+        s->count=qemu_get_be32(f);
         qemu_get_be16s(f, &s->latched_count);
         qemu_get_8s(f, &s->count_latched);
         qemu_get_8s(f, &s->status_latched);
@@ -440,9 +440,9 @@
         qemu_get_8s(f, &s->mode);
         qemu_get_8s(f, &s->bcd);
         qemu_get_8s(f, &s->gate);
-        qemu_get_be64s(f, &s->count_load_time);
+        s->count_load_time=qemu_get_be64(f);
         if (s->irq_timer) {
-            qemu_get_be64s(f, &s->next_transition_time);
+            s->next_transition_time=qemu_get_be64(f);
             qemu_get_timer(f, s->irq_timer);
         }
     }

Modified: trunk/src/host/qemu-neo1973/hw/ide.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/ide.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/hw/ide.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -471,12 +471,12 @@
     put_le16(p + 5, 512); /* XXX: retired, remove ? */
     put_le16(p + 6, s->sectors);
     snprintf(buf, sizeof(buf), "QM%05d", s->drive_serial);
-    padstr((uint8_t *)(p + 10), buf, 20); /* serial number */
+    padstr((char *)(p + 10), buf, 20); /* serial number */
     put_le16(p + 20, 3); /* XXX: retired, remove ? */
     put_le16(p + 21, 512); /* cache size in sectors */
     put_le16(p + 22, 4); /* ecc bytes */
-    padstr((uint8_t *)(p + 23), QEMU_VERSION, 8); /* firmware version */
-    padstr((uint8_t *)(p + 27), "QEMU HARDDISK", 40); /* model */
+    padstr((char *)(p + 23), QEMU_VERSION, 8); /* firmware version */
+    padstr((char *)(p + 27), "QEMU HARDDISK", 40); /* model */
 #if MAX_MULT_SECTORS > 1
     put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS);
 #endif
@@ -536,12 +536,12 @@
     /* Removable CDROM, 50us response, 12 byte packets */
     put_le16(p + 0, (2 << 14) | (5 << 8) | (1 << 7) | (2 << 5) | (0 << 0));
     snprintf(buf, sizeof(buf), "QM%05d", s->drive_serial);
-    padstr((uint8_t *)(p + 10), buf, 20); /* serial number */
+    padstr((char *)(p + 10), buf, 20); /* serial number */
     put_le16(p + 20, 3); /* buffer type */
     put_le16(p + 21, 512); /* cache size in sectors */
     put_le16(p + 22, 4); /* ecc bytes */
-    padstr((uint8_t *)(p + 23), QEMU_VERSION, 8); /* firmware version */
-    padstr((uint8_t *)(p + 27), "QEMU CD-ROM", 40); /* model */
+    padstr((char *)(p + 23), QEMU_VERSION, 8); /* firmware version */
+    padstr((char *)(p + 27), "QEMU CD-ROM", 40); /* model */
     put_le16(p + 48, 1); /* dword I/O (XXX: should not be set on CDROM) */
 #ifdef USE_DMA_CDROM
     put_le16(p + 49, 1 << 9 | 1 << 8); /* DMA and LBA supported */
@@ -591,10 +591,10 @@
     put_le16(p + 7, s->nb_sectors >> 16);	/* Sectors per card */
     put_le16(p + 8, s->nb_sectors);		/* Sectors per card */
     snprintf(buf, sizeof(buf), "QM%05d", s->drive_serial);
-    padstr((uint8_t *)(p + 10), buf, 20);	/* Serial number in ASCII */
+    padstr((char *)(p + 10), buf, 20);	/* Serial number in ASCII */
     put_le16(p + 22, 0x0004);			/* ECC bytes */
-    padstr((uint8_t *) (p + 23), QEMU_VERSION, 8);	/* Firmware Revision */
-    padstr((uint8_t *) (p + 27), "QEMU MICRODRIVE", 40);/* Model number */
+    padstr((char *) (p + 23), QEMU_VERSION, 8);	/* Firmware Revision */
+    padstr((char *) (p + 27), "QEMU MICRODRIVE", 40);/* Model number */
 #if MAX_MULT_SECTORS > 1
     put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS);
 #else
@@ -2042,6 +2042,7 @@
             ide_set_signature(s);
             s->status = 0x00; /* NOTE: READY is _not_ set */
             s->error = 0x01;
+            ide_set_irq(s);
             break;
         case WIN_SRST:
             if (!s->is_cdrom)
@@ -2508,8 +2509,8 @@
 /* save per IDE drive data */
 static void ide_save(QEMUFile* f, IDEState *s)
 {
-    qemu_put_be32s(f, &s->mult_sectors);
-    qemu_put_be32s(f, &s->identify_set);
+    qemu_put_be32(f, s->mult_sectors);
+    qemu_put_be32(f, s->identify_set);
     if (s->identify_set) {
         qemu_put_buffer(f, (const uint8_t *)s->identify_data, 512);
     }
@@ -2536,8 +2537,8 @@
 /* load per IDE drive data */
 static void ide_load(QEMUFile* f, IDEState *s)
 {
-    qemu_get_be32s(f, &s->mult_sectors);
-    qemu_get_be32s(f, &s->identify_set);
+    s->mult_sectors=qemu_get_be32(f);
+    s->identify_set=qemu_get_be32(f);
     if (s->identify_set) {
         qemu_get_buffer(f, (uint8_t *)s->identify_data, 512);
     }

Modified: trunk/src/host/qemu-neo1973/hw/mainstone.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/mainstone.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/hw/mainstone.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -18,6 +18,45 @@
 #include "sysemu.h"
 #include "flash.h"
 
+static struct keymap map[0xE0] = {
+    [0 ... 0xDF] = { -1, -1 },
+    [0x1e] = {0,0}, /* a */
+    [0x30] = {0,1}, /* b */
+    [0x2e] = {0,2}, /* c */
+    [0x20] = {0,3}, /* d */
+    [0x12] = {0,4}, /* e */
+    [0x21] = {0,5}, /* f */
+    [0x22] = {1,0}, /* g */
+    [0x23] = {1,1}, /* h */
+    [0x17] = {1,2}, /* i */
+    [0x24] = {1,3}, /* j */
+    [0x25] = {1,4}, /* k */
+    [0x26] = {1,5}, /* l */
+    [0x32] = {2,0}, /* m */
+    [0x31] = {2,1}, /* n */
+    [0x18] = {2,2}, /* o */
+    [0x19] = {2,3}, /* p */
+    [0x10] = {2,4}, /* q */
+    [0x13] = {2,5}, /* r */
+    [0x1f] = {3,0}, /* s */
+    [0x14] = {3,1}, /* t */
+    [0x16] = {3,2}, /* u */
+    [0x2f] = {3,3}, /* v */
+    [0x11] = {3,4}, /* w */
+    [0x2d] = {3,5}, /* x */
+    [0x15] = {4,2}, /* y */
+    [0x2c] = {4,3}, /* z */
+    [0xc7] = {5,0}, /* Home */
+    [0x2a] = {5,1}, /* shift */
+    [0x39] = {5,2}, /* space */
+    [0x39] = {5,3}, /* space */
+    [0x1c] = {5,5}, /*  enter */
+    [0xc8] = {6,0}, /* up */
+    [0xd0] = {6,1}, /* down */
+    [0xcb] = {6,2}, /* left */
+    [0xcd] = {6,3}, /* right */
+};
+
 enum mainstone_model_e { mainstone };
 
 static void mainstone_common_init(int ram_size, int vga_ram_size,
@@ -79,6 +118,10 @@
 
     mst_irq = mst_irq_init(cpu, MST_FPGA_PHYS, PXA2XX_PIC_GPIO_0);
 
+    /* setup keypad */
+    printf("map addr %p\n", &map);
+    pxa27x_register_keypad(cpu->kp, map, 0xe0);
+
     /* MMC/SD host */
     pxa2xx_mmci_handlers(cpu->mmc, NULL, mst_irq[MMC_IRQ]);
 

Modified: trunk/src/host/qemu-neo1973/hw/mc146818rtc.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/mc146818rtc.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/hw/mc146818rtc.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -421,18 +421,18 @@
     qemu_put_buffer(f, s->cmos_data, 128);
     qemu_put_8s(f, &s->cmos_index);
 
-    qemu_put_be32s(f, &s->current_tm.tm_sec);
-    qemu_put_be32s(f, &s->current_tm.tm_min);
-    qemu_put_be32s(f, &s->current_tm.tm_hour);
-    qemu_put_be32s(f, &s->current_tm.tm_wday);
-    qemu_put_be32s(f, &s->current_tm.tm_mday);
-    qemu_put_be32s(f, &s->current_tm.tm_mon);
-    qemu_put_be32s(f, &s->current_tm.tm_year);
+    qemu_put_be32(f, s->current_tm.tm_sec);
+    qemu_put_be32(f, s->current_tm.tm_min);
+    qemu_put_be32(f, s->current_tm.tm_hour);
+    qemu_put_be32(f, s->current_tm.tm_wday);
+    qemu_put_be32(f, s->current_tm.tm_mday);
+    qemu_put_be32(f, s->current_tm.tm_mon);
+    qemu_put_be32(f, s->current_tm.tm_year);
 
     qemu_put_timer(f, s->periodic_timer);
-    qemu_put_be64s(f, &s->next_periodic_time);
+    qemu_put_be64(f, s->next_periodic_time);
 
-    qemu_put_be64s(f, &s->next_second_time);
+    qemu_put_be64(f, s->next_second_time);
     qemu_put_timer(f, s->second_timer);
     qemu_put_timer(f, s->second_timer2);
 }
@@ -447,18 +447,18 @@
     qemu_get_buffer(f, s->cmos_data, 128);
     qemu_get_8s(f, &s->cmos_index);
 
-    qemu_get_be32s(f, &s->current_tm.tm_sec);
-    qemu_get_be32s(f, &s->current_tm.tm_min);
-    qemu_get_be32s(f, &s->current_tm.tm_hour);
-    qemu_get_be32s(f, &s->current_tm.tm_wday);
-    qemu_get_be32s(f, &s->current_tm.tm_mday);
-    qemu_get_be32s(f, &s->current_tm.tm_mon);
-    qemu_get_be32s(f, &s->current_tm.tm_year);
+    s->current_tm.tm_sec=qemu_get_be32(f);
+    s->current_tm.tm_min=qemu_get_be32(f);
+    s->current_tm.tm_hour=qemu_get_be32(f);
+    s->current_tm.tm_wday=qemu_get_be32(f);
+    s->current_tm.tm_mday=qemu_get_be32(f);
+    s->current_tm.tm_mon=qemu_get_be32(f);
+    s->current_tm.tm_year=qemu_get_be32(f);
 
     qemu_get_timer(f, s->periodic_timer);
-    qemu_get_be64s(f, &s->next_periodic_time);
+    s->next_periodic_time=qemu_get_be64(f);
 
-    qemu_get_be64s(f, &s->next_second_time);
+    s->next_second_time=qemu_get_be64(f);
     qemu_get_timer(f, s->second_timer);
     qemu_get_timer(f, s->second_timer2);
     return 0;

Modified: trunk/src/host/qemu-neo1973/hw/ne2000.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/ne2000.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/hw/ne2000.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -647,7 +647,7 @@
 static void ne2000_save(QEMUFile* f,void* opaque)
 {
 	NE2000State* s=(NE2000State*)opaque;
-        int tmp;
+        uint32_t tmp;
 
         if (s->pci_dev)
             pci_device_save(s->pci_dev, f);
@@ -679,7 +679,7 @@
 {
 	NE2000State* s=(NE2000State*)opaque;
         int ret;
-        int tmp;
+        uint32_t tmp;
 
         if (version_id > 3)
             return -EINVAL;

Modified: trunk/src/host/qemu-neo1973/hw/pc.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pc.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/hw/pc.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -552,7 +552,7 @@
 	initrd_max = ram_size-ACPI_DATA_SIZE-1;
 
     /* kernel command line */
-    pstrcpy(cmdline_addr, 4096, kernel_cmdline);
+    pstrcpy((char*)cmdline_addr, 4096, kernel_cmdline);
 
     if (protocol >= 0x202) {
 	stl_p(header+0x228, cmdline_addr-phys_ram_base);

Modified: trunk/src/host/qemu-neo1973/hw/pcnet.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pcnet.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/hw/pcnet.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -1843,9 +1843,9 @@
     if (s->pci_dev)
         pci_device_save(s->pci_dev, f);
 
-    qemu_put_be32s(f, &s->rap);
-    qemu_put_be32s(f, &s->isr);
-    qemu_put_be32s(f, &s->lnkst);
+    qemu_put_be32(f, s->rap);
+    qemu_put_be32(f, s->isr);
+    qemu_put_be32(f, s->lnkst);
     qemu_put_be32s(f, &s->rdra);
     qemu_put_be32s(f, &s->tdra);
     qemu_put_buffer(f, s->prom, 16);
@@ -1854,10 +1854,10 @@
     for (i = 0; i < 32; i++)
         qemu_put_be16s(f, &s->bcr[i]);
     qemu_put_be64s(f, &s->timer);
-    qemu_put_be32s(f, &s->xmit_pos);
-    qemu_put_be32s(f, &s->recv_pos);
+    qemu_put_be32(f, s->xmit_pos);
+    qemu_put_be32(f, s->recv_pos);
     qemu_put_buffer(f, s->buffer, 4096);
-    qemu_put_be32s(f, &s->tx_busy);
+    qemu_put_be32(f, s->tx_busy);
     qemu_put_timer(f, s->poll_timer);
 }
 
@@ -1875,9 +1875,9 @@
             return ret;
     }
 
-    qemu_get_be32s(f, &s->rap);
-    qemu_get_be32s(f, &s->isr);
-    qemu_get_be32s(f, &s->lnkst);
+    qemu_get_be32s(f, (uint32_t*)&s->rap);
+    qemu_get_be32s(f, (uint32_t*)&s->isr);
+    qemu_get_be32s(f, (uint32_t*)&s->lnkst);
     qemu_get_be32s(f, &s->rdra);
     qemu_get_be32s(f, &s->tdra);
     qemu_get_buffer(f, s->prom, 16);
@@ -1886,10 +1886,10 @@
     for (i = 0; i < 32; i++)
         qemu_get_be16s(f, &s->bcr[i]);
     qemu_get_be64s(f, &s->timer);
-    qemu_get_be32s(f, &s->xmit_pos);
-    qemu_get_be32s(f, &s->recv_pos);
+    qemu_get_be32s(f, (uint32_t*)&s->xmit_pos);
+    qemu_get_be32s(f, (uint32_t*)&s->recv_pos);
     qemu_get_buffer(f, s->buffer, 4096);
-    qemu_get_be32s(f, &s->tx_busy);
+    qemu_get_be32s(f, (uint32_t*)&s->tx_busy);
     qemu_get_timer(f, s->poll_timer);
 
     return 0;

Modified: trunk/src/host/qemu-neo1973/hw/ps2.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/ps2.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/hw/ps2.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -470,19 +470,19 @@
 
 static void ps2_common_save (QEMUFile *f, PS2State *s)
 {
-    qemu_put_be32s (f, &s->write_cmd);
-    qemu_put_be32s (f, &s->queue.rptr);
-    qemu_put_be32s (f, &s->queue.wptr);
-    qemu_put_be32s (f, &s->queue.count);
+    qemu_put_be32 (f, s->write_cmd);
+    qemu_put_be32 (f, s->queue.rptr);
+    qemu_put_be32 (f, s->queue.wptr);
+    qemu_put_be32 (f, s->queue.count);
     qemu_put_buffer (f, s->queue.data, sizeof (s->queue.data));
 }
 
 static void ps2_common_load (QEMUFile *f, PS2State *s)
 {
-    qemu_get_be32s (f, &s->write_cmd);
-    qemu_get_be32s (f, &s->queue.rptr);
-    qemu_get_be32s (f, &s->queue.wptr);
-    qemu_get_be32s (f, &s->queue.count);
+    s->write_cmd=qemu_get_be32 (f);
+    s->queue.rptr=qemu_get_be32 (f);
+    s->queue.wptr=qemu_get_be32 (f);
+    s->queue.count=qemu_get_be32 (f);
     qemu_get_buffer (f, s->queue.data, sizeof (s->queue.data));
 }
 
@@ -491,8 +491,8 @@
     PS2KbdState *s = (PS2KbdState*)opaque;
 
     ps2_common_save (f, &s->common);
-    qemu_put_be32s(f, &s->scan_enabled);
-    qemu_put_be32s(f, &s->translate);
+    qemu_put_be32(f, s->scan_enabled);
+    qemu_put_be32(f, s->translate);
 }
 
 static void ps2_mouse_save(QEMUFile* f, void* opaque)
@@ -506,9 +506,9 @@
     qemu_put_8s(f, &s->mouse_wrap);
     qemu_put_8s(f, &s->mouse_type);
     qemu_put_8s(f, &s->mouse_detect_state);
-    qemu_put_be32s(f, &s->mouse_dx);
-    qemu_put_be32s(f, &s->mouse_dy);
-    qemu_put_be32s(f, &s->mouse_dz);
+    qemu_put_be32(f, s->mouse_dx);
+    qemu_put_be32(f, s->mouse_dy);
+    qemu_put_be32(f, s->mouse_dz);
     qemu_put_8s(f, &s->mouse_buttons);
 }
 
@@ -520,8 +520,8 @@
         return -EINVAL;
 
     ps2_common_load (f, &s->common);
-    qemu_get_be32s(f, &s->scan_enabled);
-    qemu_get_be32s(f, &s->translate);
+    s->scan_enabled=qemu_get_be32(f);
+    s->translate=qemu_get_be32(f);
     return 0;
 }
 
@@ -539,9 +539,9 @@
     qemu_get_8s(f, &s->mouse_wrap);
     qemu_get_8s(f, &s->mouse_type);
     qemu_get_8s(f, &s->mouse_detect_state);
-    qemu_get_be32s(f, &s->mouse_dx);
-    qemu_get_be32s(f, &s->mouse_dy);
-    qemu_get_be32s(f, &s->mouse_dz);
+    s->mouse_dx=qemu_get_be32(f);
+    s->mouse_dy=qemu_get_be32(f);
+    s->mouse_dz=qemu_get_be32(f);
     qemu_get_8s(f, &s->mouse_buttons);
     return 0;
 }

Modified: trunk/src/host/qemu-neo1973/hw/pxa.h
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pxa.h	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/hw/pxa.h	2007-12-17 17:52:55 UTC (rev 3665)
@@ -13,6 +13,7 @@
 # define PXA2XX_PIC_SSP3	0
 # define PXA2XX_PIC_USBH2	2
 # define PXA2XX_PIC_USBH1	3
+# define PXA2XX_PIC_KEYPAD	4
 # define PXA2XX_PIC_PWRI2C	6
 # define PXA25X_PIC_HWUART	7
 # define PXA27X_PIC_OST_4_11	7
@@ -106,6 +107,17 @@
 int pxa2xx_pcmcia_dettach(void *opaque);
 void pxa2xx_pcmcia_set_irq_cb(void *opaque, qemu_irq irq, qemu_irq cd_irq);
 
+/* pxa2xx_keypad.c */
+struct  keymap {
+    int column;
+    int row;
+};
+struct pxa2xx_keypad_s;
+struct pxa2xx_keypad_s *pxa27x_keypad_init(target_phys_addr_t base,
+                qemu_irq irq);
+void pxa27x_register_keypad(struct pxa2xx_keypad_s *kp, struct keymap *map,
+                int size);
+
 /* pxa2xx.c */
 struct pxa2xx_ssp_s;
 void pxa2xx_ssp_attach(struct pxa2xx_ssp_s *port,
@@ -133,6 +145,7 @@
     struct pxa2xx_pcmcia_s *pcmcia[2];
     struct pxa2xx_i2s_s *i2s;
     struct pxa2xx_fir_s *fir;
+    struct pxa2xx_keypad_s *kp;
 
     /* Power management */
     target_phys_addr_t pm_base;

Modified: trunk/src/host/qemu-neo1973/hw/pxa2xx.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pxa2xx.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/hw/pxa2xx.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -2154,6 +2154,8 @@
 
     s->i2s = pxa2xx_i2s_init(0x40400000, s->pic[PXA2XX_PIC_I2S], s->dma);
 
+    s->kp = pxa27x_keypad_init(0x41500000, s->pic[PXA2XX_PIC_KEYPAD]);
+
     /* GPIO1 resets the processor */
     /* The handler can be overridden by board-specific code */
     pxa2xx_gpio_out_set(s->gpio, 1, s->reset);

Added: trunk/src/host/qemu-neo1973/hw/pxa2xx_keypad.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pxa2xx_keypad.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/hw/pxa2xx_keypad.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -0,0 +1,342 @@
+/*
+ * Intel PXA27X Keypad Controller emulation.
+ *
+ * Copyright (c) 2007 MontaVista Software, Inc
+ * Written by Armin Kuster <akuster at kama-aina.net>
+ *              or  <Akuster at mvista.com>
+ *
+ * This code is licensed under the GPLv2.
+ */
+
+#include "hw.h"
+#include "pxa.h"
+#include "console.h"
+
+/*
+ * Keypad
+ */
+#define KPC         0x00    /* Keypad Interface Control register */
+#define KPDK        0x08    /* Keypad Interface Direct Key register */
+#define KPREC       0x10    /* Keypad Interface Rotary Encoder register */
+#define KPMK        0x18    /* Keypad Interface Matrix Key register */
+#define KPAS        0x20    /* Keypad Interface Automatic Scan register */
+#define KPASMKP0    0x28    /* Keypad Interface Automatic Scan Multiple
+                                Key Presser register 0 */
+#define KPASMKP1    0x30    /* Keypad Interface Automatic Scan Multiple
+                                Key Presser register 1 */
+#define KPASMKP2    0x38    /* Keypad Interface Automatic Scan Multiple
+                                Key Presser register 2 */
+#define KPASMKP3    0x40    /* Keypad Interface Automatic Scan Multiple
+                                Key Presser register 3 */
+#define KPKDI       0x48    /* Keypad Interface Key Debounce Interval
+                                register */
+
+/* Keypad defines */
+#define KPC_AS          (0x1 << 30)  /* Automatic Scan bit */
+#define KPC_ASACT       (0x1 << 29)  /* Automatic Scan on Activity */
+#define KPC_MI          (0x1 << 22)  /* Matrix interrupt bit */
+#define KPC_IMKP        (0x1 << 21)  /* Ignore Multiple Key Press */
+#define KPC_MS7         (0x1 << 20)  /* Matrix scan line 7 */
+#define KPC_MS6         (0x1 << 19)  /* Matrix scan line 6 */
+#define KPC_MS5         (0x1 << 18)  /* Matrix scan line 5 */
+#define KPC_MS4         (0x1 << 17)  /* Matrix scan line 4 */
+#define KPC_MS3         (0x1 << 16)  /* Matrix scan line 3 */
+#define KPC_MS2         (0x1 << 15)  /* Matrix scan line 2 */
+#define KPC_MS1         (0x1 << 14)  /* Matrix scan line 1 */
+#define KPC_MS0         (0x1 << 13)  /* Matrix scan line 0 */
+#define KPC_ME          (0x1 << 12)  /* Matrix Keypad Enable */
+#define KPC_MIE         (0x1 << 11)  /* Matrix Interrupt Enable */
+#define KPC_DK_DEB_SEL  (0x1 <<  9)  /* Direct Keypad Debounce Select */
+#define KPC_DI          (0x1 <<  5)  /* Direct key interrupt bit */
+#define KPC_RE_ZERO_DEB (0x1 <<  4)  /* Rotary Encoder Zero Debounce */
+#define KPC_REE1        (0x1 <<  3)  /* Rotary Encoder1 Enable */
+#define KPC_REE0        (0x1 <<  2)  /* Rotary Encoder0 Enable */
+#define KPC_DE          (0x1 <<  1)  /* Direct Keypad Enable */
+#define KPC_DIE         (0x1 <<  0)  /* Direct Keypad interrupt Enable */
+
+#define KPDK_DKP        (0x1 << 31)
+#define KPDK_DK7        (0x1 <<  7)
+#define KPDK_DK6        (0x1 <<  6)
+#define KPDK_DK5        (0x1 <<  5)
+#define KPDK_DK4        (0x1 <<  4)
+#define KPDK_DK3        (0x1 <<  3)
+#define KPDK_DK2        (0x1 <<  2)
+#define KPDK_DK1        (0x1 <<  1)
+#define KPDK_DK0        (0x1 <<  0)
+
+#define KPREC_OF1       (0x1 << 31)
+#define KPREC_UF1       (0x1 << 30)
+#define KPREC_OF0       (0x1 << 15)
+#define KPREC_UF0       (0x1 << 14)
+
+#define KPMK_MKP        (0x1 << 31)
+#define KPAS_SO         (0x1 << 31)
+#define KPASMKPx_SO     (0x1 << 31)
+
+
+#define KPASMKPx_MKC(row, col)  (1 << (row + 16 * (col % 2)))
+
+#define PXAKBD_MAXROW   8
+#define PXAKBD_MAXCOL   8
+
+struct pxa2xx_keypad_s{
+    target_phys_addr_t base;
+    qemu_irq    irq;
+    struct  keymap *map;
+
+    uint32_t    kpc;
+    uint32_t    kpdk;
+    uint32_t    kprec;
+    uint32_t    kpmk;
+    uint32_t    kpas;
+    uint32_t    kpasmkp0;
+    uint32_t    kpasmkp1;
+    uint32_t    kpasmkp2;
+    uint32_t    kpasmkp3;
+    uint32_t    kpkdi;
+};
+
+static void pxa27x_keyboard_event (struct  pxa2xx_keypad_s *kp, int keycode)
+{
+    int row, col,rel;
+
+    if(!(kp->kpc & KPC_ME)) /* skip if not enabled */
+        return;
+
+    if(kp->kpc & KPC_AS || kp->kpc & KPC_ASACT) {
+        if(kp->kpc & KPC_AS)
+            kp->kpc &= ~(KPC_AS);
+
+        rel = (keycode & 0x80) ? 1 : 0; /* key release from qemu */
+        keycode &= ~(0x80); /* strip qemu key release bit */
+        row = kp->map[keycode].row;
+        col = kp->map[keycode].column;
+        if(row == -1 || col == -1)
+            return;
+        switch (col) {
+        case 0:
+        case 1:
+            if(rel)
+                kp->kpasmkp0 = ~(0xffffffff);
+            else
+                kp->kpasmkp0 |= KPASMKPx_MKC(row,col);
+            break;
+        case 2:
+        case 3:
+            if(rel)
+                kp->kpasmkp1 = ~(0xffffffff);
+            else
+                kp->kpasmkp1 |= KPASMKPx_MKC(row,col);
+            break;
+        case 4:
+        case 5:
+            if(rel)
+                kp->kpasmkp2 = ~(0xffffffff);
+            else
+                kp->kpasmkp2 |= KPASMKPx_MKC(row,col);
+            break;
+        case 6:
+        case 7:
+            if(rel)
+                kp->kpasmkp3 = ~(0xffffffff);
+            else
+                kp->kpasmkp3 |= KPASMKPx_MKC(row,col);
+            break;
+        } /* switch */
+        goto out;
+    }
+    return;
+
+out:
+    if(kp->kpc & KPC_MIE) {
+        kp->kpc |= KPC_MI;
+        qemu_irq_raise(kp->irq);
+    }
+    return;
+}
+
+static uint32_t pxa2xx_keypad_read(void *opaque, target_phys_addr_t offset)
+{
+    struct pxa2xx_keypad_s *s = (struct pxa2xx_keypad_s *) opaque;
+    uint32_t tmp;
+    offset -= s->base;
+
+    switch (offset) {
+    case KPC:
+        tmp = s->kpc;
+        if(tmp & KPC_MI)
+            s->kpc &= ~(KPC_MI);
+        if(tmp & KPC_DI)
+            s->kpc &= ~(KPC_DI);
+        qemu_irq_lower(s->irq);
+        return tmp;
+        break;
+    case KPDK:
+        return s->kpdk;
+        break;
+    case KPREC:
+        tmp = s->kprec;
+        if(tmp & KPREC_OF1)
+            s->kprec &= ~(KPREC_OF1);
+        if(tmp & KPREC_UF1)
+            s->kprec &= ~(KPREC_UF1);
+        if(tmp & KPREC_OF0)
+            s->kprec &= ~(KPREC_OF0);
+        if(tmp & KPREC_UF0)
+            s->kprec &= ~(KPREC_UF0);
+        return tmp;
+        break;
+    case KPMK:
+        tmp = s->kpmk;
+        if(tmp & KPMK_MKP)
+            s->kpmk &= ~(KPMK_MKP);
+        return tmp;
+        break;
+    case KPAS:
+        return s->kpas;
+        break;
+    case KPASMKP0:
+        return s->kpasmkp0;
+        break;
+    case KPASMKP1:
+        return s->kpasmkp1;
+        break;
+    case KPASMKP2:
+        return s->kpasmkp2;
+        break;
+    case KPASMKP3:
+        return s->kpasmkp3;
+        break;
+    case KPKDI:
+        return s->kpkdi;
+        break;
+    default:
+        cpu_abort(cpu_single_env, "%s: Bad offset " REG_FMT "\n",
+                        __FUNCTION__, offset);
+    }
+
+    return 0;
+}
+
+static void pxa2xx_keypad_write(void *opaque,
+                target_phys_addr_t offset, uint32_t value)
+{
+    struct pxa2xx_keypad_s *s = (struct pxa2xx_keypad_s *) opaque;
+    offset -= s->base;
+
+    switch (offset) {
+    case KPC:
+        s->kpc = value;
+        break;
+    case KPDK:
+        s->kpdk = value;
+        break;
+    case KPREC:
+        s->kprec = value;
+        break;
+    case KPMK:
+        s->kpmk = value;
+        break;
+    case KPAS:
+        s->kpas = value;
+        break;
+    case KPASMKP0:
+        s->kpasmkp0 = value;
+        break;
+    case KPASMKP1:
+        s->kpasmkp1 = value;
+        break;
+    case KPASMKP2:
+        s->kpasmkp2 = value;
+        break;
+    case KPASMKP3:
+        s->kpasmkp3 = value;
+        break;
+    case KPKDI:
+        s->kpkdi = value;
+        break;
+
+    default:
+        cpu_abort(cpu_single_env, "%s: Bad offset " REG_FMT "\n",
+                        __FUNCTION__, offset);
+    }
+}
+
+static CPUReadMemoryFunc *pxa2xx_keypad_readfn[] = {
+    pxa2xx_keypad_read,
+    pxa2xx_keypad_read,
+    pxa2xx_keypad_read
+};
+
+static CPUWriteMemoryFunc *pxa2xx_keypad_writefn[] = {
+    pxa2xx_keypad_write,
+    pxa2xx_keypad_write,
+    pxa2xx_keypad_write
+};
+
+static void pxa2xx_keypad_save(QEMUFile *f, void *opaque)
+{
+    struct pxa2xx_keypad_s *s = (struct pxa2xx_keypad_s *) opaque;
+
+    qemu_put_be32s(f, &s->kpc);
+    qemu_put_be32s(f, &s->kpdk);
+    qemu_put_be32s(f, &s->kprec);
+    qemu_put_be32s(f, &s->kpmk);
+    qemu_put_be32s(f, &s->kpas);
+    qemu_put_be32s(f, &s->kpasmkp0);
+    qemu_put_be32s(f, &s->kpasmkp1);
+    qemu_put_be32s(f, &s->kpasmkp2);
+    qemu_put_be32s(f, &s->kpasmkp3);
+    qemu_put_be32s(f, &s->kpkdi);
+
+}
+
+static int pxa2xx_keypad_load(QEMUFile *f, void *opaque, int version_id)
+{
+    struct pxa2xx_keypad_s *s = (struct pxa2xx_keypad_s *) opaque;
+
+    qemu_get_be32s(f, &s->kpc);
+    qemu_get_be32s(f, &s->kpdk);
+    qemu_get_be32s(f, &s->kprec);
+    qemu_get_be32s(f, &s->kpmk);
+    qemu_get_be32s(f, &s->kpas);
+    qemu_get_be32s(f, &s->kpasmkp0);
+    qemu_get_be32s(f, &s->kpasmkp1);
+    qemu_get_be32s(f, &s->kpasmkp2);
+    qemu_get_be32s(f, &s->kpasmkp3);
+    qemu_get_be32s(f, &s->kpkdi);
+
+    return 0;
+}
+
+struct pxa2xx_keypad_s *pxa27x_keypad_init(target_phys_addr_t base,
+        qemu_irq irq)
+{
+    int iomemtype;
+    struct pxa2xx_keypad_s *s;
+
+    s = (struct pxa2xx_keypad_s *) qemu_mallocz(sizeof(struct pxa2xx_keypad_s));
+    s->base = base;
+    s->irq = irq;
+
+    iomemtype = cpu_register_io_memory(0, pxa2xx_keypad_readfn,
+                    pxa2xx_keypad_writefn, s);
+    cpu_register_physical_memory(base, 0x00100000, iomemtype);
+
+    register_savevm("pxa2xx_keypad", 0, 0,
+                    pxa2xx_keypad_save, pxa2xx_keypad_load, s);
+
+    return s;
+}
+
+void pxa27x_register_keypad(struct pxa2xx_keypad_s *kp, struct keymap *map,
+        int size)
+{
+    if(!map || size < 0x80) {
+        fprintf(stderr, "%s - No PXA keypad map defined\n", __FUNCTION__);
+        exit(-1);
+    }
+
+    kp->map = map;
+    qemu_add_kbd_event_handler((QEMUPutKBDEvent *) pxa27x_keyboard_event, kp);
+}

Modified: trunk/src/host/qemu-neo1973/hw/rtl8139.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/rtl8139.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/hw/rtl8139.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -3119,7 +3119,7 @@
 static void rtl8139_save(QEMUFile* f,void* opaque)
 {
     RTL8139State* s=(RTL8139State*)opaque;
-    int i;
+    unsigned int i;
 
     pci_device_save(s->pci_dev, f);
 
@@ -3172,7 +3172,7 @@
     i = 0;
     qemu_put_be32s(f, &i); /* unused.  */
     qemu_put_buffer(f, s->macaddr, 6);
-    qemu_put_be32s(f, &s->rtl8139_mmio_io_addr);
+    qemu_put_be32(f, s->rtl8139_mmio_io_addr);
 
     qemu_put_be32s(f, &s->currTxDesc);
     qemu_put_be32s(f, &s->currCPlusRxDesc);
@@ -3184,7 +3184,7 @@
     {
         qemu_put_be16s(f, &s->eeprom.contents[i]);
     }
-    qemu_put_be32s(f, &s->eeprom.mode);
+    qemu_put_be32(f, s->eeprom.mode);
     qemu_put_be32s(f, &s->eeprom.tick);
     qemu_put_8s(f, &s->eeprom.address);
     qemu_put_be16s(f, &s->eeprom.input);
@@ -3197,7 +3197,7 @@
 
     qemu_put_be32s(f, &s->TCTR);
     qemu_put_be32s(f, &s->TimerInt);
-    qemu_put_be64s(f, &s->TCTR_base);
+    qemu_put_be64(f, s->TCTR_base);
 
     RTL8139TallyCounters_save(f, &s->tally_counters);
 }
@@ -3205,7 +3205,8 @@
 static int rtl8139_load(QEMUFile* f,void* opaque,int version_id)
 {
     RTL8139State* s=(RTL8139State*)opaque;
-    int i, ret;
+    unsigned int i;
+    int ret;
 
     /* just 2 versions for now */
     if (version_id > 3)
@@ -3266,7 +3267,7 @@
 
     qemu_get_be32s(f, &i); /* unused.  */
     qemu_get_buffer(f, s->macaddr, 6);
-    qemu_get_be32s(f, &s->rtl8139_mmio_io_addr);
+    s->rtl8139_mmio_io_addr=qemu_get_be32(f);
 
     qemu_get_be32s(f, &s->currTxDesc);
     qemu_get_be32s(f, &s->currCPlusRxDesc);
@@ -3278,7 +3279,7 @@
     {
         qemu_get_be16s(f, &s->eeprom.contents[i]);
     }
-    qemu_get_be32s(f, &s->eeprom.mode);
+    s->eeprom.mode=qemu_get_be32(f);
     qemu_get_be32s(f, &s->eeprom.tick);
     qemu_get_8s(f, &s->eeprom.address);
     qemu_get_be16s(f, &s->eeprom.input);
@@ -3294,7 +3295,7 @@
     {
         qemu_get_be32s(f, &s->TCTR);
         qemu_get_be32s(f, &s->TimerInt);
-        qemu_get_be64s(f, &s->TCTR_base);
+        s->TCTR_base=qemu_get_be64(f);
 
         RTL8139TallyCounters_load(f, &s->tally_counters);
     }

Modified: trunk/src/host/qemu-neo1973/hw/sb16.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/sb16.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/hw/sb16.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -1257,29 +1257,29 @@
 {
     SB16State *s = opaque;
 
-    qemu_put_be32s (f, &s->irq);
-    qemu_put_be32s (f, &s->dma);
-    qemu_put_be32s (f, &s->hdma);
-    qemu_put_be32s (f, &s->port);
-    qemu_put_be32s (f, &s->ver);
-    qemu_put_be32s (f, &s->in_index);
-    qemu_put_be32s (f, &s->out_data_len);
-    qemu_put_be32s (f, &s->fmt_stereo);
-    qemu_put_be32s (f, &s->fmt_signed);
-    qemu_put_be32s (f, &s->fmt_bits);
+    qemu_put_be32 (f, s->irq);
+    qemu_put_be32 (f, s->dma);
+    qemu_put_be32 (f, s->hdma);
+    qemu_put_be32 (f, s->port);
+    qemu_put_be32 (f, s->ver);
+    qemu_put_be32 (f, s->in_index);
+    qemu_put_be32 (f, s->out_data_len);
+    qemu_put_be32 (f, s->fmt_stereo);
+    qemu_put_be32 (f, s->fmt_signed);
+    qemu_put_be32 (f, s->fmt_bits);
     qemu_put_be32s (f, &s->fmt);
-    qemu_put_be32s (f, &s->dma_auto);
-    qemu_put_be32s (f, &s->block_size);
-    qemu_put_be32s (f, &s->fifo);
-    qemu_put_be32s (f, &s->freq);
-    qemu_put_be32s (f, &s->time_const);
-    qemu_put_be32s (f, &s->speaker);
-    qemu_put_be32s (f, &s->needed_bytes);
-    qemu_put_be32s (f, &s->cmd);
-    qemu_put_be32s (f, &s->use_hdma);
-    qemu_put_be32s (f, &s->highspeed);
-    qemu_put_be32s (f, &s->can_write);
-    qemu_put_be32s (f, &s->v2x6);
+    qemu_put_be32 (f, s->dma_auto);
+    qemu_put_be32 (f, s->block_size);
+    qemu_put_be32 (f, s->fifo);
+    qemu_put_be32 (f, s->freq);
+    qemu_put_be32 (f, s->time_const);
+    qemu_put_be32 (f, s->speaker);
+    qemu_put_be32 (f, s->needed_bytes);
+    qemu_put_be32 (f, s->cmd);
+    qemu_put_be32 (f, s->use_hdma);
+    qemu_put_be32 (f, s->highspeed);
+    qemu_put_be32 (f, s->can_write);
+    qemu_put_be32 (f, s->v2x6);
 
     qemu_put_8s (f, &s->csp_param);
     qemu_put_8s (f, &s->csp_value);
@@ -1288,21 +1288,21 @@
     qemu_put_buffer (f, s->csp_regs, 256);
     qemu_put_8s (f, &s->csp_index);
     qemu_put_buffer (f, s->csp_reg83, 4);
-    qemu_put_be32s (f, &s->csp_reg83r);
-    qemu_put_be32s (f, &s->csp_reg83w);
+    qemu_put_be32 (f, s->csp_reg83r);
+    qemu_put_be32 (f, s->csp_reg83w);
 
     qemu_put_buffer (f, s->in2_data, sizeof (s->in2_data));
     qemu_put_buffer (f, s->out_data, sizeof (s->out_data));
     qemu_put_8s (f, &s->test_reg);
     qemu_put_8s (f, &s->last_read_byte);
 
-    qemu_put_be32s (f, &s->nzero);
-    qemu_put_be32s (f, &s->left_till_irq);
-    qemu_put_be32s (f, &s->dma_running);
-    qemu_put_be32s (f, &s->bytes_per_second);
-    qemu_put_be32s (f, &s->align);
+    qemu_put_be32 (f, s->nzero);
+    qemu_put_be32 (f, s->left_till_irq);
+    qemu_put_be32 (f, s->dma_running);
+    qemu_put_be32 (f, s->bytes_per_second);
+    qemu_put_be32 (f, s->align);
 
-    qemu_put_be32s (f, &s->mixer_nreg);
+    qemu_put_be32 (f, s->mixer_nreg);
     qemu_put_buffer (f, s->mixer_regs, 256);
 }
 
@@ -1314,29 +1314,29 @@
         return -EINVAL;
     }
 
-    qemu_get_be32s (f, &s->irq);
-    qemu_get_be32s (f, &s->dma);
-    qemu_get_be32s (f, &s->hdma);
-    qemu_get_be32s (f, &s->port);
-    qemu_get_be32s (f, &s->ver);
-    qemu_get_be32s (f, &s->in_index);
-    qemu_get_be32s (f, &s->out_data_len);
-    qemu_get_be32s (f, &s->fmt_stereo);
-    qemu_get_be32s (f, &s->fmt_signed);
-    qemu_get_be32s (f, &s->fmt_bits);
+    s->irq=qemu_get_be32 (f);
+    s->dma=qemu_get_be32 (f);
+    s->hdma=qemu_get_be32 (f);
+    s->port=qemu_get_be32 (f);
+    s->ver=qemu_get_be32 (f);
+    s->in_index=qemu_get_be32 (f);
+    s->out_data_len=qemu_get_be32 (f);
+    s->fmt_stereo=qemu_get_be32 (f);
+    s->fmt_signed=qemu_get_be32 (f);
+    s->fmt_bits=qemu_get_be32 (f);
     qemu_get_be32s (f, &s->fmt);
-    qemu_get_be32s (f, &s->dma_auto);
-    qemu_get_be32s (f, &s->block_size);
-    qemu_get_be32s (f, &s->fifo);
-    qemu_get_be32s (f, &s->freq);
-    qemu_get_be32s (f, &s->time_const);
-    qemu_get_be32s (f, &s->speaker);
-    qemu_get_be32s (f, &s->needed_bytes);
-    qemu_get_be32s (f, &s->cmd);
-    qemu_get_be32s (f, &s->use_hdma);
-    qemu_get_be32s (f, &s->highspeed);
-    qemu_get_be32s (f, &s->can_write);
-    qemu_get_be32s (f, &s->v2x6);
+    s->dma_auto=qemu_get_be32 (f);
+    s->block_size=qemu_get_be32 (f);
+    s->fifo=qemu_get_be32 (f);
+    s->freq=qemu_get_be32 (f);
+    s->time_const=qemu_get_be32 (f);
+    s->speaker=qemu_get_be32 (f);
+    s->needed_bytes=qemu_get_be32 (f);
+    s->cmd=qemu_get_be32 (f);
+    s->use_hdma=qemu_get_be32 (f);
+    s->highspeed=qemu_get_be32 (f);
+    s->can_write=qemu_get_be32 (f);
+    s->v2x6=qemu_get_be32 (f);
 
     qemu_get_8s (f, &s->csp_param);
     qemu_get_8s (f, &s->csp_value);
@@ -1345,21 +1345,21 @@
     qemu_get_buffer (f, s->csp_regs, 256);
     qemu_get_8s (f, &s->csp_index);
     qemu_get_buffer (f, s->csp_reg83, 4);
-    qemu_get_be32s (f, &s->csp_reg83r);
-    qemu_get_be32s (f, &s->csp_reg83w);
+    s->csp_reg83r=qemu_get_be32 (f);
+    s->csp_reg83w=qemu_get_be32 (f);
 
     qemu_get_buffer (f, s->in2_data, sizeof (s->in2_data));
     qemu_get_buffer (f, s->out_data, sizeof (s->out_data));
     qemu_get_8s (f, &s->test_reg);
     qemu_get_8s (f, &s->last_read_byte);
 
-    qemu_get_be32s (f, &s->nzero);
-    qemu_get_be32s (f, &s->left_till_irq);
-    qemu_get_be32s (f, &s->dma_running);
-    qemu_get_be32s (f, &s->bytes_per_second);
-    qemu_get_be32s (f, &s->align);
+    s->nzero=qemu_get_be32 (f);
+    s->left_till_irq=qemu_get_be32 (f);
+    s->dma_running=qemu_get_be32 (f);
+    s->bytes_per_second=qemu_get_be32 (f);
+    s->align=qemu_get_be32 (f);
 
-    qemu_get_be32s (f, &s->mixer_nreg);
+    s->mixer_nreg=qemu_get_be32 (f);
     qemu_get_buffer (f, s->mixer_regs, 256);
 
     if (s->voice) {

Modified: trunk/src/host/qemu-neo1973/hw/sh.h
===================================================================
--- trunk/src/host/qemu-neo1973/hw/sh.h	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/hw/sh.h	2007-12-17 17:52:55 UTC (rev 3665)
@@ -2,6 +2,8 @@
 #define QEMU_SH_H
 /* Definitions for SH board emulation.  */
 
+#include "sh_intc.h"
+
 /* sh7750.c */
 struct SH7750State;
 
@@ -25,8 +27,11 @@
 #define TMU012_FEAT_TOCR   (1 << 0)
 #define TMU012_FEAT_3CHAN  (1 << 1)
 #define TMU012_FEAT_EXTCLK (1 << 2)
-void tmu012_init(uint32_t base, int feat, uint32_t freq);
+void tmu012_init(target_phys_addr_t base, int feat, uint32_t freq,
+		 struct intc_source *ch0_irq, struct intc_source *ch1_irq,
+		 struct intc_source *ch2_irq0, struct intc_source *ch2_irq1);
 
+
 /* sh_serial.c */
 #define SH_SERIAL_FEAT_SCIF (1 << 0)
 void sh_serial_init (target_phys_addr_t base, int feat,

Modified: trunk/src/host/qemu-neo1973/hw/sh7750.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/sh7750.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/hw/sh7750.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -559,9 +559,12 @@
 
     tmu012_init(0x1fd80000,
 		TMU012_FEAT_TOCR | TMU012_FEAT_3CHAN | TMU012_FEAT_EXTCLK,
-		s->periph_freq);
+		s->periph_freq,
+		sh_intc_source(&s->intc, TMU0),
+		sh_intc_source(&s->intc, TMU1),
+		sh_intc_source(&s->intc, TMU2_TUNI),
+		sh_intc_source(&s->intc, TMU2_TICPI));
 
-
     if (cpu_model & (SH_CPU_SH7750 | SH_CPU_SH7750S | SH_CPU_SH7751)) {
         sh_intc_register_sources(&s->intc, 
 				 _INTC_ARRAY(vectors_dma4),
@@ -578,7 +581,10 @@
         sh_intc_register_sources(&s->intc, 
 				 _INTC_ARRAY(vectors_tmu34),
 				 NULL, 0);
-        tmu012_init(0x1e100000, 0, s->periph_freq);
+        tmu012_init(0x1e100000, 0, s->periph_freq,
+		    sh_intc_source(&s->intc, TMU3),
+		    sh_intc_source(&s->intc, TMU4),
+		    NULL, NULL);
     }
 
     if (cpu_model & (SH_CPU_SH7751_ALL)) {

Modified: trunk/src/host/qemu-neo1973/hw/sh_serial.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/sh_serial.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/hw/sh_serial.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -293,7 +293,7 @@
 
     s->smr = 0;
     s->brr = 0xff;
-    s->scr = 0;
+    s->scr = 1 << 5; /* pretend that TX is enabled so early printk works */
     s->sptr = 0;
 
     if (feat & SH_SERIAL_FEAT_SCIF) {

Modified: trunk/src/host/qemu-neo1973/hw/sh_timer.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/sh_timer.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/hw/sh_timer.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -33,23 +33,23 @@
     uint32_t tcpr;
     int freq;
     int int_level;
+    int old_level;
     int feat;
     int enabled;
-    qemu_irq irq;
+    struct intc_source *irq;
 } sh_timer_state;
 
 /* Check all active timers, and schedule the next timer interrupt. */
 
 static void sh_timer_update(sh_timer_state *s)
 {
-#if 0 /* not yet */
-    /* Update interrupts.  */
-    if (s->int_level && (s->tcr & TIMER_TCR_UNIE)) {
-        qemu_irq_raise(s->irq);
-    } else {
-        qemu_irq_lower(s->irq);
-    }
-#endif
+    int new_level = s->int_level && (s->tcr & TIMER_TCR_UNIE);
+
+    if (new_level != s->old_level)
+      sh_intc_toggle_source(s->irq, 0, new_level ? 1 : -1);
+
+    s->old_level = s->int_level;
+    s->int_level = new_level;
 }
 
 static uint32_t sh_timer_read(void *opaque, target_phys_addr_t offset)
@@ -185,7 +185,7 @@
     sh_timer_update(s);
 }
 
-static void *sh_timer_init(uint32_t freq, int feat)
+static void *sh_timer_init(uint32_t freq, int feat, struct intc_source *irq)
 {
     sh_timer_state *s;
     QEMUBH *bh;
@@ -198,6 +198,7 @@
     s->tcpr = 0xdeadbeef;
     s->tcor = 0;
     s->enabled = 0;
+    s->irq = irq;
 
     bh = qemu_bh_new(sh_timer_tick, s);
     s->timer = ptimer_init(bh);
@@ -305,7 +306,9 @@
     tmu012_write
 };
 
-void tmu012_init(uint32_t base, int feat, uint32_t freq)
+void tmu012_init(target_phys_addr_t base, int feat, uint32_t freq,
+		 struct intc_source *ch0_irq, struct intc_source *ch1_irq,
+		 struct intc_source *ch2_irq0, struct intc_source *ch2_irq1)
 {
     int iomemtype;
     tmu012_state *s;
@@ -314,10 +317,11 @@
     s = (tmu012_state *)qemu_mallocz(sizeof(tmu012_state));
     s->base = base;
     s->feat = feat;
-    s->timer[0] = sh_timer_init(freq, timer_feat);
-    s->timer[1] = sh_timer_init(freq, timer_feat);
+    s->timer[0] = sh_timer_init(freq, timer_feat, ch0_irq);
+    s->timer[1] = sh_timer_init(freq, timer_feat, ch1_irq);
     if (feat & TMU012_FEAT_3CHAN)
-        s->timer[2] = sh_timer_init(freq, timer_feat | TIMER_FEAT_CAPT);
+        s->timer[2] = sh_timer_init(freq, timer_feat | TIMER_FEAT_CAPT,
+				    ch2_irq0); /* ch2_irq1 not supported */
     iomemtype = cpu_register_io_memory(0, tmu012_readfn,
                                        tmu012_writefn, s);
     cpu_register_physical_memory(base, 0x00001000, iomemtype);

Modified: trunk/src/host/qemu-neo1973/hw/slavio_serial.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/slavio_serial.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/hw/slavio_serial.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -89,6 +89,7 @@
     int rptr, wptr, count;
 } SERIOQueue;
 
+#define SERIAL_REGS 16
 typedef struct ChannelState {
     qemu_irq irq;
     int reg;
@@ -96,7 +97,7 @@
     chn_id_t chn; // this channel, A (base+4) or B (base+0)
     chn_type_t type;
     struct ChannelState *otherchn;
-    uint8_t rx, tx, wregs[16], rregs[16];
+    uint8_t rx, tx, wregs[SERIAL_REGS], rregs[SERIAL_REGS];
     SERIOQueue queue;
     CharDriverState *chr;
     int e0_mode, led_mode, caps_lock_mode, num_lock_mode;
@@ -109,7 +110,108 @@
 
 #define SERIAL_MAXADDR 7
 #define SERIAL_SIZE (SERIAL_MAXADDR + 1)
+#define SERIAL_CTRL 0
+#define SERIAL_DATA 1
 
+#define W_CMD     0
+#define CMD_PTR_MASK   0x07
+#define CMD_CMD_MASK   0x38
+#define CMD_HI         0x08
+#define CMD_CLR_TXINT  0x28
+#define CMD_CLR_IUS    0x38
+#define W_INTR    1
+#define INTR_INTALL    0x01
+#define INTR_TXINT     0x02
+#define INTR_RXMODEMSK 0x18
+#define INTR_RXINT1ST  0x08
+#define INTR_RXINTALL  0x10
+#define W_IVEC    2
+#define W_RXCTRL  3
+#define RXCTRL_RXEN    0x01
+#define W_TXCTRL1 4
+#define TXCTRL1_PAREN  0x01
+#define TXCTRL1_PAREV  0x02
+#define TXCTRL1_1STOP  0x04
+#define TXCTRL1_1HSTOP 0x08
+#define TXCTRL1_2STOP  0x0c
+#define TXCTRL1_STPMSK 0x0c
+#define TXCTRL1_CLK1X  0x00
+#define TXCTRL1_CLK16X 0x40
+#define TXCTRL1_CLK32X 0x80
+#define TXCTRL1_CLK64X 0xc0
+#define TXCTRL1_CLKMSK 0xc0
+#define W_TXCTRL2 5
+#define TXCTRL2_TXEN   0x08
+#define TXCTRL2_BITMSK 0x60
+#define TXCTRL2_5BITS  0x00
+#define TXCTRL2_7BITS  0x20
+#define TXCTRL2_6BITS  0x40
+#define TXCTRL2_8BITS  0x60
+#define W_SYNC1   6
+#define W_SYNC2   7
+#define W_TXBUF   8
+#define W_MINTR   9
+#define MINTR_STATUSHI 0x10
+#define MINTR_RST_MASK 0xc0
+#define MINTR_RST_B    0x40
+#define MINTR_RST_A    0x80
+#define MINTR_RST_ALL  0xc0
+#define W_MISC1  10
+#define W_CLOCK  11
+#define CLOCK_TRXC     0x08
+#define W_BRGLO  12
+#define W_BRGHI  13
+#define W_MISC2  14
+#define MISC2_PLLDIS   0x30
+#define W_EXTINT 15
+#define EXTINT_DCD     0x08
+#define EXTINT_SYNCINT 0x10
+#define EXTINT_CTSINT  0x20
+#define EXTINT_TXUNDRN 0x40
+#define EXTINT_BRKINT  0x80
+
+#define R_STATUS  0
+#define STATUS_RXAV    0x01
+#define STATUS_ZERO    0x02
+#define STATUS_TXEMPTY 0x04
+#define STATUS_DCD     0x08
+#define STATUS_SYNC    0x10
+#define STATUS_CTS     0x20
+#define STATUS_TXUNDRN 0x40
+#define STATUS_BRK     0x80
+#define R_SPEC    1
+#define SPEC_ALLSENT   0x01
+#define SPEC_BITS8     0x06
+#define R_IVEC    2
+#define IVEC_TXINTB    0x00
+#define IVEC_LONOINT   0x06
+#define IVEC_LORXINTA  0x0c
+#define IVEC_LORXINTB  0x04
+#define IVEC_LOTXINTA  0x08
+#define IVEC_HINOINT   0x60
+#define IVEC_HIRXINTA  0x30
+#define IVEC_HIRXINTB  0x20
+#define IVEC_HITXINTA  0x10
+#define R_INTR    3
+#define INTR_EXTINTB   0x01
+#define INTR_TXINTB    0x02
+#define INTR_RXINTB    0x04
+#define INTR_EXTINTA   0x08
+#define INTR_TXINTA    0x10
+#define INTR_RXINTA    0x20
+#define R_IPEN    4
+#define R_TXCTRL1 5
+#define R_TXCTRL2 6
+#define R_BC      7
+#define R_RXBUF   8
+#define R_RXCTRL  9
+#define R_MISC   10
+#define R_MISC1  11
+#define R_BRGLO  12
+#define R_BRGHI  13
+#define R_MISC1I 14
+#define R_EXTINT 15
+
 static void handle_kbd_command(ChannelState *s, int val);
 static int serial_can_receive(void *opaque);
 static void serial_receive_byte(ChannelState *s, int ch);
@@ -159,11 +261,14 @@
 
 static int slavio_serial_update_irq_chn(ChannelState *s)
 {
-    if ((s->wregs[1] & 1) && // interrupts enabled
-        (((s->wregs[1] & 2) && s->txint == 1) || // tx ints enabled, pending
-         ((((s->wregs[1] & 0x18) == 8) || ((s->wregs[1] & 0x18) == 0x10)) &&
+    if ((s->wregs[W_INTR] & INTR_INTALL) && // interrupts enabled
+        (((s->wregs[W_INTR] & INTR_TXINT) && s->txint == 1) ||
+         // tx ints enabled, pending
+         ((((s->wregs[W_INTR] & INTR_RXMODEMSK) == INTR_RXINT1ST) ||
+           ((s->wregs[W_INTR] & INTR_RXMODEMSK) == INTR_RXINTALL)) &&
           s->rxint == 1) || // rx ints enabled, pending
-         ((s->wregs[15] & 0x80) && (s->rregs[0] & 0x80)))) { // break int e&p
+         ((s->wregs[W_EXTINT] & EXTINT_BRKINT) &&
+          (s->rregs[R_STATUS] & STATUS_BRK)))) { // break int e&p
         return 1;
     }
     return 0;
@@ -189,16 +294,18 @@
         s->rregs[i] = 0;
         s->wregs[i] = 0;
     }
-    s->wregs[4] = 4;
-    s->wregs[9] = 0xc0;
-    s->wregs[11] = 8;
-    s->wregs[14] = 0x30;
-    s->wregs[15] = 0xf8;
+    s->wregs[W_TXCTRL1] = TXCTRL1_1STOP; // 1X divisor, 1 stop bit, no parity
+    s->wregs[W_MINTR] = MINTR_RST_ALL;
+    s->wregs[W_CLOCK] = CLOCK_TRXC; // Synch mode tx clock = TRxC
+    s->wregs[W_MISC2] = MISC2_PLLDIS; // PLL disabled
+    s->wregs[W_EXTINT] = EXTINT_DCD | EXTINT_SYNCINT | EXTINT_CTSINT |
+        EXTINT_TXUNDRN | EXTINT_BRKINT; // Enable most interrupts
     if (s->disabled)
-        s->rregs[0] = 0x7c;
+        s->rregs[R_STATUS] = STATUS_TXEMPTY | STATUS_DCD | STATUS_SYNC |
+            STATUS_CTS | STATUS_TXUNDRN;
     else
-        s->rregs[0] = 0x44;
-    s->rregs[1] = 6;
+        s->rregs[R_STATUS] = STATUS_TXEMPTY | STATUS_TXUNDRN;
+    s->rregs[R_SPEC] = SPEC_BITS8;
 
     s->rx = s->tx = 0;
     s->rxint = s->txint = 0;
@@ -219,17 +326,17 @@
     s->rxint = 0;
     s->rxint_under_svc = 0;
     if (s->chn == chn_a) {
-        if (s->wregs[9] & 0x10)
-            s->otherchn->rregs[2] = 0x60;
+        if (s->wregs[W_MINTR] & MINTR_STATUSHI)
+            s->otherchn->rregs[R_IVEC] = IVEC_HINOINT;
         else
-            s->otherchn->rregs[2] = 0x06;
-        s->rregs[3] &= ~0x20;
+            s->otherchn->rregs[R_IVEC] = IVEC_LONOINT;
+        s->rregs[R_INTR] &= ~INTR_RXINTA;
     } else {
-        if (s->wregs[9] & 0x10)
-            s->rregs[2] = 0x60;
+        if (s->wregs[W_MINTR] & MINTR_STATUSHI)
+            s->rregs[R_IVEC] = IVEC_HINOINT;
         else
-            s->rregs[2] = 0x06;
-        s->otherchn->rregs[3] &= ~4;
+            s->rregs[R_IVEC] = IVEC_LONOINT;
+        s->otherchn->rregs[R_INTR] &= ~INTR_RXINTB;
     }
     if (s->txint)
         set_txint(s);
@@ -242,21 +349,21 @@
     if (!s->txint_under_svc) {
         s->rxint_under_svc = 1;
         if (s->chn == chn_a) {
-            if (s->wregs[9] & 0x10)
-                s->otherchn->rregs[2] = 0x30;
+            if (s->wregs[W_MINTR] & MINTR_STATUSHI)
+                s->otherchn->rregs[R_IVEC] = IVEC_HIRXINTA;
             else
-                s->otherchn->rregs[2] = 0x0c;
+                s->otherchn->rregs[R_IVEC] = IVEC_LORXINTA;
         } else {
-            if (s->wregs[9] & 0x10)
-                s->rregs[2] = 0x20;
+            if (s->wregs[W_MINTR] & MINTR_STATUSHI)
+                s->rregs[R_IVEC] = IVEC_HIRXINTB;
             else
-                s->rregs[2] = 0x04;
+                s->rregs[R_IVEC] = IVEC_LORXINTB;
         }
     }
     if (s->chn == chn_a)
-        s->rregs[3] |= 0x20;
+        s->rregs[R_INTR] |= INTR_RXINTA;
     else
-        s->otherchn->rregs[3] |= 4;
+        s->otherchn->rregs[R_INTR] |= INTR_RXINTB;
     slavio_serial_update_irq(s);
 }
 
@@ -265,17 +372,17 @@
     s->txint = 0;
     s->txint_under_svc = 0;
     if (s->chn == chn_a) {
-        if (s->wregs[9] & 0x10)
-            s->otherchn->rregs[2] = 0x60;
+        if (s->wregs[W_MINTR] & MINTR_STATUSHI)
+            s->otherchn->rregs[R_IVEC] = IVEC_HINOINT;
         else
-            s->otherchn->rregs[2] = 0x06;
-        s->rregs[3] &= ~0x10;
+            s->otherchn->rregs[R_IVEC] = IVEC_LONOINT;
+        s->rregs[R_INTR] &= ~INTR_TXINTA;
     } else {
-        if (s->wregs[9] & 0x10)
-            s->rregs[2] = 0x60;
+        if (s->wregs[W_MINTR] & MINTR_STATUSHI)
+            s->rregs[R_IVEC] = IVEC_HINOINT;
         else
-            s->rregs[2] = 0x06;
-        s->otherchn->rregs[3] &= ~2;
+            s->rregs[R_IVEC] = IVEC_LONOINT;
+        s->otherchn->rregs[R_INTR] &= ~INTR_TXINTB;
     }
     if (s->rxint)
         set_rxint(s);
@@ -288,18 +395,18 @@
     if (!s->rxint_under_svc) {
         s->txint_under_svc = 1;
         if (s->chn == chn_a) {
-            if (s->wregs[9] & 0x10)
-                s->otherchn->rregs[2] = 0x10;
+            if (s->wregs[W_MINTR] & MINTR_STATUSHI)
+                s->otherchn->rregs[R_IVEC] = IVEC_HITXINTA;
             else
-                s->otherchn->rregs[2] = 0x08;
+                s->otherchn->rregs[R_IVEC] = IVEC_LOTXINTA;
         } else {
-            s->rregs[2] = 0;
+            s->rregs[R_IVEC] = IVEC_TXINTB;
         }
     }
     if (s->chn == chn_a)
-        s->rregs[3] |= 0x10;
+        s->rregs[R_INTR] |= INTR_TXINTA;
     else
-        s->otherchn->rregs[3] |= 2;
+        s->otherchn->rregs[R_INTR] |= INTR_TXINTB;
     slavio_serial_update_irq(s);
 }
 
@@ -311,45 +418,45 @@
     if (!s->chr || s->type != ser)
         return;
 
-    if (s->wregs[4] & 1) {
-        if (s->wregs[4] & 2)
+    if (s->wregs[W_TXCTRL1] & TXCTRL1_PAREN) {
+        if (s->wregs[W_TXCTRL1] & TXCTRL1_PAREV)
             parity = 'E';
         else
             parity = 'O';
     } else {
         parity = 'N';
     }
-    if ((s->wregs[4] & 0x0c) == 0x0c)
+    if ((s->wregs[W_TXCTRL1] & TXCTRL1_STPMSK) == TXCTRL1_2STOP)
         stop_bits = 2;
     else
         stop_bits = 1;
-    switch (s->wregs[5] & 0x60) {
-    case 0x00:
+    switch (s->wregs[W_TXCTRL2] & TXCTRL2_BITMSK) {
+    case TXCTRL2_5BITS:
         data_bits = 5;
         break;
-    case 0x20:
+    case TXCTRL2_7BITS:
         data_bits = 7;
         break;
-    case 0x40:
+    case TXCTRL2_6BITS:
         data_bits = 6;
         break;
     default:
-    case 0x60:
+    case TXCTRL2_8BITS:
         data_bits = 8;
         break;
     }
-    speed = 2457600 / ((s->wregs[12] | (s->wregs[13] << 8)) + 2);
-    switch (s->wregs[4] & 0xc0) {
-    case 0x00:
+    speed = 2457600 / ((s->wregs[W_BRGLO] | (s->wregs[W_BRGHI] << 8)) + 2);
+    switch (s->wregs[W_TXCTRL1] & TXCTRL1_CLKMSK) {
+    case TXCTRL1_CLK1X:
         break;
-    case 0x40:
+    case TXCTRL1_CLK16X:
         speed /= 16;
         break;
-    case 0x80:
+    case TXCTRL1_CLK32X:
         speed /= 32;
         break;
     default:
-    case 0xc0:
+    case TXCTRL1_CLK64X:
         speed /= 64;
         break;
     }
@@ -362,7 +469,8 @@
     qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
 }
 
-static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
+static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr,
+                                     uint32_t val)
 {
     SerialState *serial = opaque;
     ChannelState *s;
@@ -374,21 +482,22 @@
     channel = (addr & SERIAL_MAXADDR) >> 2;
     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);
+    case SERIAL_CTRL:
+        SER_DPRINTF("Write channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg,
+                    val & 0xff);
         newreg = 0;
         switch (s->reg) {
-        case 0:
-            newreg = val & 7;
-            val &= 0x38;
+        case W_CMD:
+            newreg = val & CMD_PTR_MASK;
+            val &= CMD_CMD_MASK;
             switch (val) {
-            case 8:
-                newreg |= 0x8;
+            case CMD_HI:
+                newreg |= CMD_HI;
                 break;
-            case 0x28:
+            case CMD_CLR_TXINT:
                 clr_txint(s);
                 break;
-            case 0x38:
+            case CMD_CLR_IUS:
                 if (s->rxint_under_svc)
                     clr_rxint(s);
                 else if (s->txint_under_svc)
@@ -398,31 +507,31 @@
                 break;
             }
             break;
-        case 1 ... 3:
-        case 6 ... 8:
-        case 10 ... 11:
-        case 14 ... 15:
+        case W_INTR ... W_RXCTRL:
+        case W_SYNC1 ... W_TXBUF:
+        case W_MISC1 ... W_CLOCK:
+        case W_MISC2 ... W_EXTINT:
             s->wregs[s->reg] = val;
             break;
-        case 4:
-        case 5:
-        case 12:
-        case 13:
+        case W_TXCTRL1:
+        case W_TXCTRL2:
+        case W_BRGLO:
+        case W_BRGHI:
             s->wregs[s->reg] = val;
             slavio_serial_update_parameters(s);
             break;
-        case 9:
-            switch (val & 0xc0) {
+        case W_MINTR:
+            switch (val & MINTR_RST_MASK) {
             case 0:
             default:
                 break;
-            case 0x40:
+            case MINTR_RST_B:
                 slavio_serial_reset_chn(&serial->chn[1]);
                 return;
-            case 0x80:
+            case MINTR_RST_A:
                 slavio_serial_reset_chn(&serial->chn[0]);
                 return;
-            case 0xc0:
+            case MINTR_RST_ALL:
                 slavio_serial_reset(serial);
                 return;
             }
@@ -435,18 +544,18 @@
         else
             s->reg = 0;
         break;
-    case 1:
+    case SERIAL_DATA:
         SER_DPRINTF("Write channel %c, ch %d\n", CHN_C(s), val);
         s->tx = val;
-        if (s->wregs[5] & 8) { // tx enabled
+        if (s->wregs[W_TXCTRL2] & TXCTRL2_TXEN) { // tx enabled
             if (s->chr)
                 qemu_chr_write(s->chr, &s->tx, 1);
             else if (s->type == kbd && !s->disabled) {
                 handle_kbd_command(s, val);
             }
         }
-        s->rregs[0] |= 4; // Tx buffer empty
-        s->rregs[1] |= 1; // All sent
+        s->rregs[R_STATUS] |= STATUS_TXEMPTY; // Tx buffer empty
+        s->rregs[R_SPEC] |= SPEC_ALLSENT; // All sent
         set_txint(s);
         break;
     default:
@@ -466,13 +575,14 @@
     channel = (addr & SERIAL_MAXADDR) >> 2;
     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]);
+    case SERIAL_CTRL:
+        SER_DPRINTF("Read channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg,
+                    s->rregs[s->reg]);
         ret = s->rregs[s->reg];
         s->reg = 0;
         return ret;
-    case 1:
-        s->rregs[0] &= ~1;
+    case SERIAL_DATA:
+        s->rregs[R_STATUS] &= ~STATUS_RXAV;
         clr_rxint(s);
         if (s->type == kbd || s->type == mouse)
             ret = get_queue(s);
@@ -493,26 +603,26 @@
     ChannelState *s = opaque;
     int ret;
 
-    if (((s->wregs[3] & 1) == 0) // Rx not enabled
-        || ((s->rregs[0] & 1) == 1)) // char already available
+    if (((s->wregs[W_RXCTRL] & RXCTRL_RXEN) == 0) // Rx not enabled
+        || ((s->rregs[R_STATUS] & STATUS_RXAV) == STATUS_RXAV))
+        // char already available
         ret = 0;
     else
         ret = 1;
-    //SER_DPRINTF("channel %c can receive %d\n", CHN_C(s), ret);
     return ret;
 }
 
 static void serial_receive_byte(ChannelState *s, int ch)
 {
     SER_DPRINTF("channel %c put ch %d\n", CHN_C(s), ch);
-    s->rregs[0] |= 1;
+    s->rregs[R_STATUS] |= STATUS_RXAV;
     s->rx = ch;
     set_rxint(s);
 }
 
 static void serial_receive_break(ChannelState *s)
 {
-    s->rregs[0] |= 0x80;
+    s->rregs[R_STATUS] |= STATUS_BRK;
     slavio_serial_update_irq(s);
 }
 
@@ -553,8 +663,8 @@
     qemu_put_be32s(f, &s->txint_under_svc);
     qemu_put_8s(f, &s->rx);
     qemu_put_8s(f, &s->tx);
-    qemu_put_buffer(f, s->wregs, 16);
-    qemu_put_buffer(f, s->rregs, 16);
+    qemu_put_buffer(f, s->wregs, SERIAL_REGS);
+    qemu_put_buffer(f, s->rregs, SERIAL_REGS);
 }
 
 static void slavio_serial_save(QEMUFile *f, void *opaque)
@@ -582,8 +692,8 @@
     }
     qemu_get_8s(f, &s->rx);
     qemu_get_8s(f, &s->tx);
-    qemu_get_buffer(f, s->wregs, 16);
-    qemu_get_buffer(f, s->rregs, 16);
+    qemu_get_buffer(f, s->wregs, SERIAL_REGS);
+    qemu_get_buffer(f, s->rregs, SERIAL_REGS);
     return 0;
 }
 
@@ -610,7 +720,9 @@
     if (!s)
         return NULL;
 
-    slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
+    slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read,
+                                                     slavio_serial_mem_write,
+                                                     s);
     cpu_register_physical_memory(base, SERIAL_SIZE, slavio_serial_io_memory);
 
     s->chn[0].chr = chr1;
@@ -629,7 +741,8 @@
     }
     s->chn[0].otherchn = &s->chn[1];
     s->chn[1].otherchn = &s->chn[0];
-    register_savevm("slavio_serial", base, 2, slavio_serial_save, slavio_serial_load, s);
+    register_savevm("slavio_serial", base, 2, slavio_serial_save,
+                    slavio_serial_load, s);
     qemu_register_reset(slavio_serial_reset, s);
     slavio_serial_reset(s);
     return s;
@@ -662,7 +775,8 @@
     ChannelState *s = opaque;
     int release = ch & 0x80;
 
-    KBD_DPRINTF("Untranslated keycode %2.2x (%s)\n", ch, release? "release" : "press");
+    KBD_DPRINTF("Untranslated keycode %2.2x (%s)\n", ch, release? "release" :
+                "press");
     switch (ch) {
     case 58: // Caps lock press
         s->caps_lock_mode ^= 1;
@@ -792,12 +906,16 @@
     s->chn[0].disabled = disabled;
     s->chn[1].disabled = disabled;
 
-    slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
+    slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read,
+                                                     slavio_serial_mem_write,
+                                                     s);
     cpu_register_physical_memory(base, SERIAL_SIZE, slavio_serial_io_memory);
 
-    qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0, "QEMU Sun Mouse");
+    qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0,
+                                 "QEMU Sun Mouse");
     qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
-    register_savevm("slavio_serial_mouse", base, 2, slavio_serial_save, slavio_serial_load, s);
+    register_savevm("slavio_serial_mouse", base, 2, slavio_serial_save,
+                    slavio_serial_load, s);
     qemu_register_reset(slavio_serial_reset, s);
     slavio_serial_reset(s);
 }

Modified: trunk/src/host/qemu-neo1973/hw/sun4m.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/sun4m.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/hw/sun4m.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -600,6 +600,44 @@
         .max_mem = 0xffffffff, // XXX actually first 62GB ok
         .default_cpu_model = "TI SuperSparc II",
     },
+    /* SS-20 */
+    {
+        .iommu_base   = 0xfe0000000ULL,
+        .tcx_base     = 0xe20000000ULL,
+        .cs_base      = -1,
+        .slavio_base  = 0xff0000000ULL,
+        .ms_kb_base   = 0xff1000000ULL,
+        .serial_base  = 0xff1100000ULL,
+        .nvram_base   = 0xff1200000ULL,
+        .fd_base      = 0xff1700000ULL,
+        .counter_base = 0xff1300000ULL,
+        .intctl_base  = 0xff1400000ULL,
+        .dma_base     = 0xef0400000ULL,
+        .esp_base     = 0xef0800000ULL,
+        .le_base      = 0xef0c00000ULL,
+        .power_base   = 0xefa000000ULL,
+        .ecc_base     = 0xf00000000ULL,
+        .ecc_version  = 0x20000000, // version 0, implementation 2
+        .vram_size    = 0x00100000,
+        .nvram_size   = 0x2000,
+        .esp_irq = 18,
+        .le_irq = 16,
+        .clock_irq = 7,
+        .clock1_irq = 19,
+        .ms_kb_irq = 14,
+        .ser_irq = 15,
+        .fd_irq = 22,
+        .me_irq = 30,
+        .cs_irq = -1,
+        .machine_id = 0x72,
+        .iommu_version = 0x13000000,
+        .intbit_to_level = {
+            2, 3, 5, 7, 9, 11, 0, 14,   3, 5, 7, 9, 11, 13, 12, 12,
+            6, 0, 4, 10, 8, 0, 11, 0,   0, 0, 0, 0, 15, 0, 15, 0,
+        },
+        .max_mem = 0xffffffff, // XXX actually first 62GB ok
+        .default_cpu_model = "TI SuperSparc II",
+    },
 };
 
 /* SPARCstation 5 hardware initialisation */
@@ -632,6 +670,16 @@
                   kernel_cmdline, initrd_filename, cpu_model);
 }
 
+/* SPARCstation 20 hardware initialisation */
+static void ss20_init(int RAM_size, int vga_ram_size,
+                      const char *boot_device, DisplayState *ds,
+                      const char *kernel_filename, const char *kernel_cmdline,
+                      const char *initrd_filename, const char *cpu_model)
+{
+    sun4m_hw_init(&hwdefs[3], RAM_size, boot_device, ds, kernel_filename,
+                  kernel_cmdline, initrd_filename, cpu_model);
+}
+
 QEMUMachine ss5_machine = {
     "SS-5",
     "Sun4m platform, SPARCstation 5",
@@ -649,3 +697,10 @@
     "Sun4m platform, SPARCserver 600MP",
     ss600mp_init,
 };
+
+QEMUMachine ss20_machine = {
+    "SS-20",
+    "Sun4m platform, SPARCstation 20",
+    ss20_init,
+};
+

Modified: trunk/src/host/qemu-neo1973/hw/usb-uhci.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/usb-uhci.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/hw/usb-uhci.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -508,7 +508,7 @@
           0 if TD successful
           1 if TD unsuccessful or inactive
 */
-static int uhci_handle_td(UHCIState *s, UHCI_TD *td, int *int_mask,
+static int uhci_handle_td(UHCIState *s, UHCI_TD *td, uint32_t *int_mask,
                           int completion)
 {
     uint8_t pid;
@@ -733,8 +733,8 @@
 {
     UHCIState *s = opaque;
     int64_t expire_time;
-    uint32_t frame_addr, link, old_td_ctrl, val;
-    int int_mask, cnt, ret;
+    uint32_t frame_addr, link, old_td_ctrl, val, int_mask;
+    int cnt, ret;
     UHCI_TD td;
     UHCI_QH qh;
     uint32_t old_async_qh;

Modified: trunk/src/host/qemu-neo1973/hw/vga.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/vga.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/hw/vga.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -1687,12 +1687,12 @@
     qemu_put_buffer(f, s->gr, 16);
     qemu_put_8s(f, &s->ar_index);
     qemu_put_buffer(f, s->ar, 21);
-    qemu_put_be32s(f, &s->ar_flip_flop);
+    qemu_put_be32(f, s->ar_flip_flop);
     qemu_put_8s(f, &s->cr_index);
     qemu_put_buffer(f, s->cr, 256);
     qemu_put_8s(f, &s->msr);
     qemu_put_8s(f, &s->fcr);
-    qemu_put_8s(f, &s->st00);
+    qemu_put_byte(f, s->st00);
     qemu_put_8s(f, &s->st01);
 
     qemu_put_8s(f, &s->dac_state);
@@ -1702,7 +1702,7 @@
     qemu_put_buffer(f, s->dac_cache, 3);
     qemu_put_buffer(f, s->palette, 768);
 
-    qemu_put_be32s(f, &s->bank_offset);
+    qemu_put_be32(f, s->bank_offset);
 #ifdef CONFIG_BOCHS_VBE
     qemu_put_byte(f, 1);
     qemu_put_be16s(f, &s->vbe_index);
@@ -1737,7 +1737,7 @@
     qemu_get_buffer(f, s->gr, 16);
     qemu_get_8s(f, &s->ar_index);
     qemu_get_buffer(f, s->ar, 21);
-    qemu_get_be32s(f, &s->ar_flip_flop);
+    s->ar_flip_flop=qemu_get_be32(f);
     qemu_get_8s(f, &s->cr_index);
     qemu_get_buffer(f, s->cr, 256);
     qemu_get_8s(f, &s->msr);
@@ -1752,7 +1752,7 @@
     qemu_get_buffer(f, s->dac_cache, 3);
     qemu_get_buffer(f, s->palette, 768);
 
-    qemu_get_be32s(f, &s->bank_offset);
+    s->bank_offset=qemu_get_be32(f);
     is_vbe = qemu_get_byte(f);
 #ifdef CONFIG_BOCHS_VBE
     if (!is_vbe)

Modified: trunk/src/host/qemu-neo1973/hw/vmware_vga.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/vmware_vga.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/hw/vmware_vga.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -1028,41 +1028,41 @@
 
 static void vmsvga_save(struct vmsvga_state_s *s, QEMUFile *f)
 {
-    qemu_put_be32s(f, &s->depth);
-    qemu_put_be32s(f, &s->enable);
-    qemu_put_be32s(f, &s->config);
-    qemu_put_be32s(f, &s->cursor.id);
-    qemu_put_be32s(f, &s->cursor.x);
-    qemu_put_be32s(f, &s->cursor.y);
-    qemu_put_be32s(f, &s->cursor.on);
-    qemu_put_be32s(f, &s->index);
+    qemu_put_be32(f, s->depth);
+    qemu_put_be32(f, s->enable);
+    qemu_put_be32(f, s->config);
+    qemu_put_be32(f, s->cursor.id);
+    qemu_put_be32(f, s->cursor.x);
+    qemu_put_be32(f, s->cursor.y);
+    qemu_put_be32(f, s->cursor.on);
+    qemu_put_be32(f, s->index);
     qemu_put_buffer(f, (uint8_t *) s->scratch, s->scratch_size * 4);
-    qemu_put_be32s(f, &s->new_width);
-    qemu_put_be32s(f, &s->new_height);
+    qemu_put_be32(f, s->new_width);
+    qemu_put_be32(f, s->new_height);
     qemu_put_be32s(f, &s->guest);
     qemu_put_be32s(f, &s->svgaid);
-    qemu_put_be32s(f, &s->syncing);
-    qemu_put_be32s(f, &s->fb_size);
+    qemu_put_be32(f, s->syncing);
+    qemu_put_be32(f, s->fb_size);
 }
 
 static int vmsvga_load(struct vmsvga_state_s *s, QEMUFile *f)
 {
     int depth;
-    qemu_get_be32s(f, &depth);
-    qemu_get_be32s(f, &s->enable);
-    qemu_get_be32s(f, &s->config);
-    qemu_get_be32s(f, &s->cursor.id);
-    qemu_get_be32s(f, &s->cursor.x);
-    qemu_get_be32s(f, &s->cursor.y);
-    qemu_get_be32s(f, &s->cursor.on);
-    qemu_get_be32s(f, &s->index);
+    depth=qemu_get_be32(f);
+    s->enable=qemu_get_be32(f);
+    s->config=qemu_get_be32(f);
+    s->cursor.id=qemu_get_be32(f);
+    s->cursor.x=qemu_get_be32(f);
+    s->cursor.y=qemu_get_be32(f);
+    s->cursor.on=qemu_get_be32(f);
+    s->index=qemu_get_be32(f);
     qemu_get_buffer(f, (uint8_t *) s->scratch, s->scratch_size * 4);
-    qemu_get_be32s(f, &s->new_width);
-    qemu_get_be32s(f, &s->new_height);
+    s->new_width=qemu_get_be32(f);
+    s->new_height=qemu_get_be32(f);
     qemu_get_be32s(f, &s->guest);
     qemu_get_be32s(f, &s->svgaid);
-    qemu_get_be32s(f, &s->syncing);
-    qemu_get_be32s(f, &s->fb_size);
+    s->syncing=qemu_get_be32(f);
+    s->fb_size=qemu_get_be32(f);
 
     if (s->enable && depth != s->depth) {
         printf("%s: need colour depth of %i bits to resume operation.\n",

Modified: trunk/src/host/qemu-neo1973/linux-user/main.c
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/main.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/linux-user/main.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -1906,7 +1906,12 @@
            "debug options:\n"
            "-d options   activate log (logfile=%s)\n"
            "-p pagesize  set the host page size to 'pagesize'\n"
-           "-strace      log system calls\n",
+           "-strace      log system calls\n"
+           "\n"
+           "environment variables:\n"
+           "QEMU_STRACE       Print system calls and arguments similar to the\n"
+           "                  'strace' program.  Enable by setting to any value.\n"
+           ,
            TARGET_ARCH,
            interp_prefix,
            x86_stack_size,

Modified: trunk/src/host/qemu-neo1973/linux-user/mmap.c
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/mmap.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/linux-user/mmap.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -162,7 +162,7 @@
    'start'. If 'start' == 0, then a default start address is used.
    Return -1 if error.
 */
-/* XXX: should mark pages used by the host as reserved to be sure not
+/* page_init() marks pages used by the host as reserved to be sure not
    to use them. */
 static abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size)
 {

Modified: trunk/src/host/qemu-neo1973/linux-user/syscall.c
===================================================================
--- trunk/src/host/qemu-neo1973/linux-user/syscall.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/linux-user/syscall.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -3177,6 +3177,7 @@
             goto efault;
         ret = get_errno(sys_unlinkat(arg1, p, arg3));
         unlock_user(p, arg2, 0);
+        break;
 #endif
     case TARGET_NR_execve:
         {

Modified: trunk/src/host/qemu-neo1973/monitor.c
===================================================================
--- trunk/src/host/qemu-neo1973/monitor.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/monitor.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -77,7 +77,7 @@
 static term_cmd_t info_cmds[];
 static term_cmd_t modem_cmds[];
 
-static char term_outbuf[1024];
+static uint8_t term_outbuf[1024];
 static int term_outbuf_index;
 
 static void monitor_start_input(void);
@@ -98,7 +98,7 @@
 /* flush at every end of line or if the buffer is full */
 void term_puts(const char *str)
 {
-    int c;
+    char c;
     for(;;) {
         c = *str++;
         if (c == '\0')

Modified: trunk/src/host/qemu-neo1973/osdep.h
===================================================================
--- trunk/src/host/qemu-neo1973/osdep.h	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/osdep.h	2007-12-17 17:52:55 UTC (rev 3665)
@@ -56,6 +56,8 @@
 int qemu_create_pidfile(const char *filename);
 
 #ifdef _WIN32
+int ffs(int i);
+
 typedef struct {
     long tv_sec;
     long tv_usec;

Modified: trunk/src/host/qemu-neo1973/pc-bios/README
===================================================================
--- trunk/src/host/qemu-neo1973/pc-bios/README	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/pc-bios/README	2007-12-17 17:52:55 UTC (rev 3665)
@@ -15,7 +15,7 @@
   firmware implementation. The goal is to implement a 100% IEEE
   1275-1994 (referred to as Open Firmware) compliant firmware.
   The included Sparc32 and Sparc64 images are built from SVN
-  revision 176.
+  revision 181.
 
 - 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-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/qemu-doc.texi	2007-12-17 17:52:55 UTC (rev 3665)
@@ -227,6 +227,76 @@
 @option{-cdrom} at the same time). You can use the host CD-ROM by
 using @file{/dev/cdrom} as filename (@pxref{host_drives}).
 
+ at item -drive @var{option}[, at var{option}[, at var{option}[,...]]]
+
+Define a new drive. Valid options are:
+
+ at table @code
+ at item file=@var{file}
+This option defines which disk image (@pxref{disk_images}) to use with
+this drive.
+ at item if=@var{interface}
+This option defines on which type on interface the drive is connected.
+Available types are: ide, scsi, sd, mtd, floppy, pflash.
+ at item bus=@var{bus},unit=@var{unit}
+These options define where is connected the drive by defining the bus number and
+the unit id.
+ at item index=@var{index}
+This option defines where is connected the drive by using an index in the list
+of available connectors of a given interface type.
+ at item media=@var{media}
+This option defines the type of the media: disk or cdrom.
+ at item cyls=@var{c},heads=@var{h},secs=@var{s}[,trans=@var{t}]
+These options have the same definition as they have in @option{-hdachs}.
+ at item snapshot=@var{snapshot}
+ at var{snapshot} is "on" or "off" and allows to enable snapshot for given drive (see @option{-snapshot}).
+ at end table
+
+Instead of @option{-cdrom} you can use:
+ at example
+qemu -drive file=file,index=2,media=cdrom
+ at end example
+
+Instead of @option{-hda}, @option{-hdb}, @option{-hdc}, @option{-hdd}, you can
+use:
+ at example
+qemu -drive file=file,index=0,media=disk
+qemu -drive file=file,index=1,media=disk
+qemu -drive file=file,index=2,media=disk
+qemu -drive file=file,index=3,media=disk
+ at end example
+
+You can connect a CDROM to the slave of ide0:
+ at example
+qemu -drive file=file,if=ide,index=1,media=cdrom
+ at end example
+
+If you don't specify the "file=" argument, you define an empty drive:
+ at example
+qemu -drive if=ide,index=1,media=cdrom
+ at end example
+
+You can connect a SCSI disk with unit ID 6 on the bus #0:
+ at example
+qemu -drive file=file,if=scsi,bus=0,unit=6
+ at end example
+
+Instead of @option{-fda}, @option{-fdb}, you can use:
+ at example
+qemu -drive file=file,index=0,if=floppy
+qemu -drive file=file,index=1,if=floppy
+ at end example
+
+By default, @var{interface} is "ide" and @var{index} is automatically
+incremented:
+ at example
+qemu -drive file=a -drive file=b"
+ at end example
+is interpreted like:
+ at example
+qemu -hda a -hdb b
+ at end example
+
 @item -boot [a|c|d|n]
 Boot on floppy (a), hard disk (c), CD-ROM (d), or Etherboot (n). Hard disk boot
 is the default.
@@ -2437,6 +2507,17 @@
 Act as if the host page size was 'pagesize' bytes
 @end table
 
+Environment variables:
+
+ at table @env
+ at item QEMU_STRACE
+Print system calls and arguments similar to the 'strace' program
+(NOTE: the actual 'strace' program will not work because the user
+space emulator hasn't implemented ptrace).  At the moment this is
+incomplete.  All system calls that don't have a specific argument
+format are printed with information for six arguments.  Many
+flag-style arguments don't have decoders and will show up as numbers.
+
 @node Other binaries
 @subsection Other binaries
 

Modified: trunk/src/host/qemu-neo1973/target-sparc/op.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-sparc/op.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/target-sparc/op.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -1244,12 +1244,14 @@
 {
     env->exception_index = PARAM1;
     cpu_loop_exit();
+    FORCE_RET();
 }
 
 void OPPROTO op_trap_T0(void)
 {
     env->exception_index = TT_TRAP + (T0 & 0x7f);
     cpu_loop_exit();
+    FORCE_RET();
 }
 
 void OPPROTO op_trapcc_T0(void)

Modified: trunk/src/host/qemu-neo1973/target-sparc/op_helper.c
===================================================================
--- trunk/src/host/qemu-neo1973/target-sparc/op_helper.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/target-sparc/op_helper.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -411,6 +411,9 @@
             break;
         }
         break;
+    case 0x39: /* data cache diagnostic register */
+        ret = 0;
+        break;
     case 0x21 ... 0x2d: /* MMU passthrough, unassigned */
     default:
         do_unassigned_access(T0, 0, 0, 1);
@@ -703,9 +706,13 @@
             }
         }
         return;
-    case 0x31: /* Ross RT620 I-cache flush */
+    case 0x30: /* store buffer tags */
+    case 0x31: /* store buffer data or Ross RT620 I-cache flush */
+    case 0x32: /* store buffer control */
     case 0x36: /* I-cache flash clear */
     case 0x37: /* D-cache flash clear */
+    case 0x38: /* breakpoint diagnostics */
+    case 0x4c: /* breakpoint action */
         break;
     case 9: /* Supervisor code access, XXX */
     case 0x21 ... 0x2d: /* MMU passthrough, unassigned */

Modified: trunk/src/host/qemu-neo1973/translate-all.c
===================================================================
--- trunk/src/host/qemu-neo1973/translate-all.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/translate-all.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -132,14 +132,27 @@
     }
 }
 
+unsigned long code_gen_max_block_size(void)
+{
+    static unsigned long max;
+
+    if (max == 0) {
+#define DEF(s, n, copy_size) max = copy_size > max? copy_size : max;
+#include "opc.h"
+#undef DEF
+        max *= OPC_MAX_SIZE;
+    }
+
+    return max;
+}
+
 /* return non zero if the very first instruction is invalid so that
    the virtual CPU can trigger an exception.
 
    '*gen_code_size_ptr' contains the size of the generated code (host
    code).
 */
-int cpu_gen_code(CPUState *env, TranslationBlock *tb,
-                 int max_code_size, int *gen_code_size_ptr)
+int cpu_gen_code(CPUState *env, TranslationBlock *tb, int *gen_code_size_ptr)
 {
     uint8_t *gen_code_buf;
     int gen_code_size;

Modified: trunk/src/host/qemu-neo1973/vl.c
===================================================================
--- trunk/src/host/qemu-neo1973/vl.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/vl.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -237,7 +237,7 @@
 
 static CPUState *cur_cpu;
 static CPUState *next_cpu;
-static int event_pending;
+static int event_pending = 1;
 
 #define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
 
@@ -828,6 +828,7 @@
 };
 
 #define ALARM_FLAG_DYNTICKS  0x1
+#define ALARM_FLAG_MODIFIED  0x2
 
 static inline int alarm_has_dynticks(struct qemu_alarm_timer *t)
 {
@@ -839,6 +840,11 @@
     if (!alarm_has_dynticks(t))
         return;
 
+    if (!(t->flags & ALARM_FLAG_MODIFIED))
+        return;
+
+    t->flags &= ~(ALARM_FLAG_MODIFIED);
+
     t->rearm(t);
 }
 
@@ -1012,6 +1018,8 @@
 {
     QEMUTimer **pt, *t;
 
+    alarm_timer->flags |= ALARM_FLAG_MODIFIED;
+
     /* NOTE: this code must be signal safe because
        qemu_timer_expired() can be called from a signal. */
     pt = &active_timers[ts->clock->type];
@@ -1092,7 +1100,6 @@
         /* run the callback (the timer list can be modified) */
         ts->cb(ts->opaque);
     }
-    qemu_rearm_alarm_timer(alarm_timer);
 }
 
 int64_t qemu_get_clock(QEMUClock *clock)
@@ -1144,9 +1151,9 @@
     if (cpu_ticks_enabled) {
         hw_error("cannot save state if virtual timers are running");
     }
-    qemu_put_be64s(f, &cpu_ticks_offset);
-    qemu_put_be64s(f, &ticks_per_sec);
-    qemu_put_be64s(f, &cpu_clock_offset);
+    qemu_put_be64(f, cpu_ticks_offset);
+    qemu_put_be64(f, ticks_per_sec);
+    qemu_put_be64(f, cpu_clock_offset);
 }
 
 static int timer_load(QEMUFile *f, void *opaque, int version_id)
@@ -1156,10 +1163,10 @@
     if (cpu_ticks_enabled) {
         return -EINVAL;
     }
-    qemu_get_be64s(f, &cpu_ticks_offset);
-    qemu_get_be64s(f, &ticks_per_sec);
+    cpu_ticks_offset=qemu_get_be64(f);
+    ticks_per_sec=qemu_get_be64(f);
     if (version_id == 2) {
-        qemu_get_be64s(f, &cpu_clock_offset);
+        cpu_clock_offset=qemu_get_be64(f);
     }
     return 0;
 }
@@ -1215,13 +1222,16 @@
         if (!alarm_has_dynticks(alarm_timer) && !cpu_single_env)
             return;
 
-        /* stop the currently executing cpu because a timer occured */
-        cpu_interrupt(env, CPU_INTERRUPT_EXIT);
+        if (env) {
+            alarm_timer->flags |= ALARM_FLAG_MODIFIED;
+            /* stop the currently executing cpu because a timer occured */
+            cpu_interrupt(env, CPU_INTERRUPT_EXIT);
 #ifdef USE_KQEMU
-        if (env->kqemu_enabled) {
-            kqemu_cpu_interrupt(env);
+            if (env->kqemu_enabled) {
+                kqemu_cpu_interrupt(env);
+            }
+#endif
         }
-#endif
         event_pending = 1;
     }
 }
@@ -1639,7 +1649,7 @@
     va_list ap;
     va_start(ap, fmt);
     vsnprintf(buf, sizeof(buf), fmt, ap);
-    qemu_chr_write(s, buf, strlen(buf));
+    qemu_chr_write(s, (uint8_t *)buf, strlen(buf));
     va_end(ap);
 }
 
@@ -1728,7 +1738,7 @@
                          (secs / 60) % 60,
                          secs % 60,
                          (int)((ti / 1000000) % 1000));
-                d->drv->chr_write(d->drv, buf1, strlen(buf1));
+                d->drv->chr_write(d->drv, (uint8_t *)buf1, strlen(buf1));
             }
         }
     }
@@ -1757,15 +1767,16 @@
         sprintf(cbuf,"\n\r");
         sprintf(ebuf,"C-%c", term_escape_char - 1 + 'a');
     } else {
-        sprintf(cbuf,"\n\rEscape-Char set to Ascii: 0x%02x\n\r\n\r", term_escape_char);
+        sprintf(cbuf,"\n\rEscape-Char set to Ascii: 0x%02x\n\r\n\r",
+            term_escape_char);
     }
-    chr->chr_write(chr, cbuf, strlen(cbuf));
+    chr->chr_write(chr, (uint8_t *)cbuf, strlen(cbuf));
     for (i = 0; mux_help[i] != NULL; i++) {
         for (j=0; mux_help[i][j] != '\0'; j++) {
             if (mux_help[i][j] == '%')
-                chr->chr_write(chr, ebuf, strlen(ebuf));
+                chr->chr_write(chr, (uint8_t *)ebuf, strlen(ebuf));
             else
-                chr->chr_write(chr, &mux_help[i][j], 1);
+                chr->chr_write(chr, (uint8_t *)&mux_help[i][j], 1);
         }
     }
 }
@@ -1784,7 +1795,7 @@
         case 'x':
             {
                  char *term =  "QEMU: Terminated\n\r";
-                 chr->chr_write(chr,term,strlen(term));
+                 chr->chr_write(chr,(uint8_t *)term,strlen(term));
                  exit(0);
                  break;
             }
@@ -2905,7 +2916,7 @@
 typedef struct {
     int fd;
     struct sockaddr_in daddr;
-    char buf[1024];
+    uint8_t buf[1024];
     int bufcnt;
     int bufptr;
     int max_size;
@@ -3063,7 +3074,7 @@
 #define IAC_BREAK 243
 static void tcp_chr_process_IAC_bytes(CharDriverState *chr,
                                       TCPCharDriver *s,
-                                      char *buf, int *size)
+                                      uint8_t *buf, int *size)
 {
     /* Handle any telnet client's basic IAC options to satisfy char by
      * char mode with no echo.  All IAC options will be removed from
@@ -3481,18 +3492,33 @@
 static int parse_macaddr(uint8_t *macaddr, const char *p)
 {
     int i;
-    for(i = 0; i < 6; i++) {
-        macaddr[i] = strtol(p, (char **)&p, 16);
-        if (i == 5) {
-            if (*p != '\0')
-                return -1;
-        } else {
-            if (*p != ':')
-                return -1;
-            p++;
+    char *last_char;
+    long int offset;
+
+    errno = 0;
+    offset = strtol(p, &last_char, 0);    
+    if (0 == errno && '\0' == *last_char &&
+            offset >= 0 && offset <= 0xFFFFFF) {
+        macaddr[3] = (offset & 0xFF0000) >> 16;
+        macaddr[4] = (offset & 0xFF00) >> 8;
+        macaddr[5] = offset & 0xFF;
+        return 0;
+    } else {
+        for(i = 0; i < 6; i++) {
+            macaddr[i] = strtol(p, (char **)&p, 16);
+            if (i == 5) {
+                if (*p != '\0')
+                    return -1;
+            } else {
+                if (*p != ':' && *p != '-')
+                    return -1;
+                p++;
+            }
         }
+        return 0;    
     }
-    return 0;
+
+    return -1;
 }
 
 static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
@@ -6033,7 +6059,7 @@
         /* ID string */
         len = strlen(se->idstr);
         qemu_put_byte(f, len);
-        qemu_put_buffer(f, se->idstr, len);
+        qemu_put_buffer(f, (uint8_t *)se->idstr, len);
 
         qemu_put_be32(f, se->instance_id);
         qemu_put_be32(f, se->version_id);
@@ -6094,7 +6120,7 @@
         if (qemu_ftell(f) >= end_pos)
             break;
         len = qemu_get_byte(f);
-        qemu_get_buffer(f, idstr, len);
+        qemu_get_buffer(f, (uint8_t *)idstr, len);
         idstr[len] = '\0';
         instance_id = qemu_get_be32(f);
         version_id = qemu_get_be32(f);
@@ -7601,6 +7627,8 @@
     qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME],
                     qemu_get_clock(rt_clock));
 
+    qemu_rearm_alarm_timer(alarm_timer);
+
     /* Check bottom-halves last in case any of the earlier events triggered
        them.  */
     qemu_bh_poll();
@@ -8096,6 +8124,7 @@
     qemu_register_machine(&ss5_machine);
     qemu_register_machine(&ss10_machine);
     qemu_register_machine(&ss600mp_machine);
+    qemu_register_machine(&ss20_machine);
 #endif
 #elif defined(TARGET_ARM)
     qemu_register_machine(&integratorcp_machine);
@@ -8526,7 +8555,7 @@
                 /* We just do some generic consistency checks */
                 {
                     /* Could easily be extended to 64 devices if needed */
-                    const unsigned char *p;
+                    const char *p;
                     
                     boot_devices_bitmap = 0;
                     for (p = boot_devices; *p != '\0'; p++) {
@@ -8995,7 +9024,7 @@
     }
 
 #ifdef TARGET_I386
-    /* XXX: this should be moved in the PC machine instanciation code */
+    /* XXX: this should be moved in the PC machine instantiation code */
     if (net_boot != 0) {
         int netroms = 0;
 	for (i = 0; i < nb_nics && i < 4; i++) {

Modified: trunk/src/host/qemu-neo1973/vnc.c
===================================================================
--- trunk/src/host/qemu-neo1973/vnc.c	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/vnc.c	2007-12-17 17:52:55 UTC (rev 3665)
@@ -60,12 +60,12 @@
 {
     size_t capacity;
     size_t offset;
-    char *buffer;
+    uint8_t *buffer;
 } Buffer;
 
 typedef struct VncState VncState;
 
-typedef int VncReadEvent(VncState *vs, char *data, size_t len);
+typedef int VncReadEvent(VncState *vs, uint8_t *data, size_t len);
 
 typedef void VncWritePixels(VncState *vs, void *data, int size);
 
@@ -258,6 +258,13 @@
 
     h += y;
 
+    /* round x down to ensure the loop only spans one 16-pixel block per,
+       iteration.  otherwise, if (x % 16) != 0, the last iteration may span
+       two 16-pixel blocks but we only mark the first as dirty
+    */
+    w += (x % 16);
+    x -= (x % 16);
+
     for (; y < h; y++)
 	for (i = 0; i < w; i += 16)
 	    vnc_set_bit(vs->dirty_row[y], (x + i) / 16);
@@ -369,7 +376,7 @@
 static void send_framebuffer_update_raw(VncState *vs, int x, int y, int w, int h)
 {
     int i;
-    char *row;
+    uint8_t *row;
 
     vnc_framebuffer_update(vs, x, y, w, h, 0);
 
@@ -433,8 +440,8 @@
 static void vnc_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
 {
     int src, dst;
-    char *src_row;
-    char *dst_row;
+    uint8_t *src_row;
+    uint8_t *dst_row;
     char *old_row;
     int y = 0;
     int pitch = ds->linesize;
@@ -492,7 +499,7 @@
 
     if (vs->need_update && vs->csock != -1) {
 	int y;
-	char *row;
+	uint8_t *row;
 	char *old_row;
 	uint32_t width_mask[VNC_DIRTY_WORDS];
 	int n_rectangles;
@@ -509,10 +516,11 @@
 	for (y = 0; y < vs->height; y++) {
 	    if (vnc_and_bits(vs->dirty_row[y], width_mask, VNC_DIRTY_WORDS)) {
 		int x;
-		char *ptr, *old_ptr;
+		uint8_t *ptr;
+		char *old_ptr;
 
 		ptr = row;
-		old_ptr = old_row;
+		old_ptr = (char*)old_row;
 
 		for (x = 0; x < vs->ds->width; x += 16) {
 		    if (memcmp(old_ptr, ptr, 16 * vs->depth) == 0) {
@@ -615,7 +623,7 @@
     return buffer->offset == 0;
 }
 
-static char *buffer_end(Buffer *buffer)
+static uint8_t *buffer_end(Buffer *buffer)
 {
     return buffer->buffer + buffer->offset;
 }
@@ -846,7 +854,7 @@
 }
 #endif /* CONFIG_VNC_TLS */
 
-static void client_cut_text(VncState *vs, size_t len, char *text)
+static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
 {
 }
 
@@ -1174,7 +1182,7 @@
     vga_hw_update();
 }
 
-static int protocol_client_msg(VncState *vs, char *data, size_t len)
+static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
 {
     int i;
     uint16_t limit;
@@ -1247,7 +1255,7 @@
     return 0;
 }
 
-static int protocol_client_init(VncState *vs, char *data, size_t len)
+static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
 {
     char pad[3] = { 0, 0, 0 };
     char buf[1024];
@@ -1320,11 +1328,11 @@
         vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
 }
 
-static int protocol_client_auth_vnc(VncState *vs, char *data, size_t len)
+static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
 {
-    char response[VNC_AUTH_CHALLENGE_SIZE];
+    unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
     int i, j, pwlen;
-    char key[8];
+    unsigned char key[8];
 
     if (!vs->password || !vs->password[0]) {
 	VNC_DEBUG("No password configured on server");
@@ -1731,7 +1739,7 @@
     return vnc_continue_handshake(vs);
 }
 
-static int protocol_client_vencrypt_auth(VncState *vs, char *data, size_t len)
+static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len)
 {
     int auth = read_u32(data, 0);
 
@@ -1761,7 +1769,7 @@
     return 0;
 }
 
-static int protocol_client_vencrypt_init(VncState *vs, char *data, size_t len)
+static int protocol_client_vencrypt_init(VncState *vs, uint8_t *data, size_t len)
 {
     if (data[0] != 0 ||
 	data[1] != 2) {
@@ -1791,7 +1799,7 @@
 }
 #endif /* CONFIG_VNC_TLS */
 
-static int protocol_client_auth(VncState *vs, char *data, size_t len)
+static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
 {
     /* We only advertise 1 auth scheme at a time, so client
      * must pick the one we sent. Verify this */
@@ -1840,7 +1848,7 @@
     return 0;
 }
 
-static int protocol_version(VncState *vs, char *version, size_t len)
+static int protocol_version(VncState *vs, uint8_t *version, size_t len)
 {
     char local[13];
 

Modified: trunk/src/host/qemu-neo1973/vnchextile.h
===================================================================
--- trunk/src/host/qemu-neo1973/vnchextile.h	2007-12-17 17:44:30 UTC (rev 3664)
+++ trunk/src/host/qemu-neo1973/vnchextile.h	2007-12-17 17:52:55 UTC (rev 3665)
@@ -13,7 +13,7 @@
                                              uint32_t *last_fg32,
                                              int *has_bg, int *has_fg)
 {
-    char *row = (vs->ds->data + y * vs->ds->linesize + x * vs->depth);
+    uint8_t *row = (vs->ds->data + y * vs->ds->linesize + x * vs->depth);
     pixel_t *irow = (pixel_t *)row;
     int j, i;
     pixel_t *last_bg = (pixel_t *)last_bg32;





More information about the commitlog mailing list