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, §orsize) &&
+ 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, §orsize) &&
- 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