diff --git a/bug-252519_goo-qemu-sec-0.9.0.diff b/bug-252519_goo-qemu-sec-0.9.0.diff deleted file mode 100644 index dbb3a560..00000000 --- a/bug-252519_goo-qemu-sec-0.9.0.diff +++ /dev/null @@ -1,380 +0,0 @@ -diff -rpu qemu-0.9.0.orig/block.c qemu-0.9.0/block.c ---- qemu-0.9.0.orig/block.c 2007-02-05 23:01:54.000000000 +0000 -+++ qemu-0.9.0/block.c 2007-02-20 22:41:03.000000000 +0000 -@@ -539,13 +539,22 @@ int bdrv_write(BlockDriverState *bs, int - return -ENOMEDIUM; - if (bs->read_only) - return -EACCES; -+ if (sector_num < 0) -+ return -EINVAL; - if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) { - memcpy(bs->boot_sector_data, buf, 512); - } - if (drv->bdrv_pwrite) { - int ret, len; -+ unsigned ns; -+ -+ ns = sector_num * 512; - len = nb_sectors * 512; -- ret = drv->bdrv_pwrite(bs, sector_num * 512, buf, len); -+ -+ if (ns < 0) -+ return -EINVAL; -+ -+ ret = drv->bdrv_pwrite(bs, ns, buf, len); - if (ret < 0) - return ret; - else if (ret != len) -diff -rpu qemu-0.9.0.orig/hw/cirrus_vga.c qemu-0.9.0/hw/cirrus_vga.c ---- qemu-0.9.0.orig/hw/cirrus_vga.c 2007-02-05 23:01:54.000000000 +0000 -+++ qemu-0.9.0/hw/cirrus_vga.c 2007-02-21 17:00:09.585042632 +0000 -@@ -217,6 +217,20 @@ - #define CIRRUS_HOOK_NOT_HANDLED 0 - #define CIRRUS_HOOK_HANDLED 1 - -+#define BLTUNSAFE(s) \ -+ ( \ -+ ( /* check dst is within bounds */ \ -+ (s)->cirrus_blt_height * (s)->cirrus_blt_dstpitch \ -+ + ((s)->cirrus_blt_dstaddr & (s)->cirrus_addr_mask) > \ -+ (s)->vram_size \ -+ ) || \ -+ ( /* check src is within bounds */ \ -+ (s)->cirrus_blt_height * (s)->cirrus_blt_srcpitch \ -+ + ((s)->cirrus_blt_srcaddr & (s)->cirrus_addr_mask) > \ -+ (s)->vram_size \ -+ ) \ -+ ) -+ - struct CirrusVGAState; - typedef void (*cirrus_bitblt_rop_t) (struct CirrusVGAState *s, - uint8_t * dst, const uint8_t * src, -@@ -589,7 +603,7 @@ static void cirrus_invalidate_region(Cir - - for (y = 0; y < lines; y++) { - off_cur = off_begin; -- off_cur_end = off_cur + bytesperline; -+ off_cur_end = (off_cur + bytesperline) & s->cirrus_addr_mask; - off_cur &= TARGET_PAGE_MASK; - while (off_cur < off_cur_end) { - cpu_physical_memory_set_dirty(s->vram_offset + off_cur); -@@ -604,7 +618,11 @@ static int cirrus_bitblt_common_patternc - { - uint8_t *dst; - -- dst = s->vram_ptr + s->cirrus_blt_dstaddr; -+ dst = s->vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask); -+ -+ if (BLTUNSAFE(s)) -+ return 0; -+ - (*s->cirrus_rop) (s, dst, src, - s->cirrus_blt_dstpitch, 0, - s->cirrus_blt_width, s->cirrus_blt_height); -@@ -620,8 +638,11 @@ static int cirrus_bitblt_solidfill(Cirru - { - cirrus_fill_t rop_func; - -+ if (BLTUNSAFE(s)) -+ return 0; -+ - rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; -- rop_func(s, s->vram_ptr + s->cirrus_blt_dstaddr, -+ rop_func(s, s->vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask), - s->cirrus_blt_dstpitch, - s->cirrus_blt_width, s->cirrus_blt_height); - cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, -@@ -640,8 +661,8 @@ static int cirrus_bitblt_solidfill(Cirru - static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s) - { - return cirrus_bitblt_common_patterncopy(s, -- s->vram_ptr + -- (s->cirrus_blt_srcaddr & ~7)); -+ s->vram_ptr + ((s->cirrus_blt_srcaddr & ~7) & -+ s->cirrus_addr_mask)); - } - - static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h) -@@ -691,8 +712,10 @@ static void cirrus_do_copy(CirrusVGAStat - if (notify) - vga_hw_update(); - -- (*s->cirrus_rop) (s, s->vram_ptr + s->cirrus_blt_dstaddr, -- s->vram_ptr + s->cirrus_blt_srcaddr, -+ (*s->cirrus_rop) (s, s->vram_ptr + -+ (s->cirrus_blt_dstaddr & s->cirrus_addr_mask), -+ s->vram_ptr + -+ (s->cirrus_blt_srcaddr & s->cirrus_addr_mask), - s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch, - s->cirrus_blt_width, s->cirrus_blt_height); - -@@ -718,8 +741,14 @@ static int cirrus_bitblt_videotovideo_co - s->cirrus_blt_srcaddr - s->start_addr, - s->cirrus_blt_width, s->cirrus_blt_height); - } else { -- (*s->cirrus_rop) (s, s->vram_ptr + s->cirrus_blt_dstaddr, -- s->vram_ptr + s->cirrus_blt_srcaddr, -+ -+ if (BLTUNSAFE(s)) -+ return 0; -+ -+ (*s->cirrus_rop) (s, s->vram_ptr + -+ (s->cirrus_blt_dstaddr & s->cirrus_addr_mask), -+ s->vram_ptr + -+ (s->cirrus_blt_srcaddr & s->cirrus_addr_mask), - s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch, - s->cirrus_blt_width, s->cirrus_blt_height); - -@@ -751,8 +780,9 @@ static void cirrus_bitblt_cputovideo_nex - } else { - /* at least one scan line */ - do { -- (*s->cirrus_rop)(s, s->vram_ptr + s->cirrus_blt_dstaddr, -- s->cirrus_bltbuf, 0, 0, s->cirrus_blt_width, 1); -+ (*s->cirrus_rop)(s, s->vram_ptr + -+ (s->cirrus_blt_dstaddr & s->cirrus_addr_mask), -+ s->cirrus_bltbuf, 0, 0, s->cirrus_blt_width, 1); - cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 0, - s->cirrus_blt_width, 1); - s->cirrus_blt_dstaddr += s->cirrus_blt_dstpitch; -@@ -1857,7 +1887,7 @@ static void cirrus_mem_writeb_mode4and5_ - unsigned val = mem_value; - uint8_t *dst; - -- dst = s->vram_ptr + offset; -+ dst = s->vram_ptr + (offset &= s->cirrus_addr_mask); - for (x = 0; x < 8; x++) { - if (val & 0x80) { - *dst = s->cirrus_shadow_gr1; -@@ -1880,7 +1910,7 @@ static void cirrus_mem_writeb_mode4and5_ - unsigned val = mem_value; - uint8_t *dst; - -- dst = s->vram_ptr + offset; -+ dst = s->vram_ptr + (offset &= s->cirrus_addr_mask); - for (x = 0; x < 8; x++) { - if (val & 0x80) { - *dst = s->cirrus_shadow_gr1; -diff -rpu qemu-0.9.0.orig/hw/cirrus_vga_rop.h qemu-0.9.0/hw/cirrus_vga_rop.h ---- qemu-0.9.0.orig/hw/cirrus_vga_rop.h 2007-02-05 23:01:54.000000000 +0000 -+++ qemu-0.9.0/hw/cirrus_vga_rop.h 2007-02-21 01:45:32.000000000 +0000 -@@ -31,6 +31,12 @@ glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(C - int x,y; - dstpitch -= bltwidth; - srcpitch -= bltwidth; -+ -+ if (dstpitch < 0 || srcpitch < 0) { -+ /* is 0 valid? srcpitch == 0 could be useful */ -+ return; -+ } -+ - for (y = 0; y < bltheight; y++) { - for (x = 0; x < bltwidth; x++) { - ROP_OP(*dst, *src); -diff -rpu qemu-0.9.0.orig/hw/dma.c qemu-0.9.0/hw/dma.c ---- qemu-0.9.0.orig/hw/dma.c 2007-02-05 23:01:54.000000000 +0000 -+++ qemu-0.9.0/hw/dma.c 2007-02-20 21:53:41.000000000 +0000 -@@ -340,9 +340,11 @@ static void channel_run (int ncont, int - #endif - - r = dma_controllers[ncont].regs + ichan; -- n = r->transfer_handler (r->opaque, ichan + (ncont << 2), -- r->now[COUNT], (r->base[COUNT] + 1) << ncont); -- r->now[COUNT] = n; -+ if (r->transfer_handler) { -+ n = r->transfer_handler (r->opaque, ichan + (ncont << 2), -+ r->now[COUNT], (r->base[COUNT] + 1) << ncont); -+ r->now[COUNT] = n; -+ } - ldebug ("dma_pos %d size %d\n", n, (r->base[COUNT] + 1) << ncont); - } - -diff -rpu qemu-0.9.0.orig/hw/fdc.c qemu-0.9.0/hw/fdc.c ---- qemu-0.9.0.orig/hw/fdc.c 2007-02-05 23:01:54.000000000 +0000 -+++ qemu-0.9.0/hw/fdc.c 2007-02-20 23:41:01.000000000 +0000 -@@ -1100,8 +1100,13 @@ static uint32_t fdctrl_read_data (fdctrl - len = fdctrl->data_len - fdctrl->data_pos; - if (len > FD_SECTOR_LEN) - len = FD_SECTOR_LEN; -- bdrv_read(cur_drv->bs, fd_sector(cur_drv), -- fdctrl->fifo, len); -+ if (cur_drv->bs) { -+ bdrv_read(cur_drv->bs, fd_sector(cur_drv), -+ fdctrl->fifo, len); -+ } else { -+ FLOPPY_ERROR("can't read data from drive\n"); -+ return 0; -+ } - } - } - retval = fdctrl->fifo[pos]; -diff -rpu qemu-0.9.0.orig/hw/i8259.c qemu-0.9.0/hw/i8259.c ---- qemu-0.9.0.orig/hw/i8259.c 2007-02-05 23:01:54.000000000 +0000 -+++ qemu-0.9.0/hw/i8259.c 2007-02-20 21:53:41.000000000 +0000 -@@ -299,9 +299,11 @@ static void pic_ioport_write(void *opaqu - s->init_state = 1; - s->init4 = val & 1; - if (val & 0x02) -- hw_error("single mode not supported"); -+ /* hw_error("single mode not supported"); */ -+ return; - if (val & 0x08) -- hw_error("level sensitive irq not supported"); -+ /* hw_error("level sensitive irq not supported"); */ -+ return; - } else if (val & 0x08) { - if (val & 0x04) - s->poll = 1; -diff -rpu qemu-0.9.0.orig/hw/ne2000.c qemu-0.9.0/hw/ne2000.c ---- qemu-0.9.0.orig/hw/ne2000.c 2007-02-05 23:01:54.000000000 +0000 -+++ qemu-0.9.0/hw/ne2000.c 2007-02-20 21:53:41.000000000 +0000 -@@ -230,7 +230,7 @@ static void ne2000_receive(void *opaque, - { - NE2000State *s = opaque; - uint8_t *p; -- int total_len, next, avail, len, index, mcast_idx; -+ unsigned int total_len, next, avail, len, index, mcast_idx; - uint8_t buf1[60]; - static const uint8_t broadcast_macaddr[6] = - { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; -@@ -299,7 +299,11 @@ static void ne2000_receive(void *opaque, - - /* write packet data */ - while (size > 0) { -- avail = s->stop - index; -+ /* taviso: this can wrap, so check its okay. */ -+ if (index <= s->stop) -+ avail = s->stop - index; -+ else -+ avail = 0; - len = size; - if (len > avail) - len = avail; -diff -rpu qemu-0.9.0.orig/hw/pc.c qemu-0.9.0/hw/pc.c ---- qemu-0.9.0.orig/hw/pc.c 2007-02-05 23:01:54.000000000 +0000 -+++ qemu-0.9.0/hw/pc.c 2007-02-20 21:53:41.000000000 +0000 -@@ -299,7 +299,8 @@ void bochs_bios_write(void *opaque, uint - case 0x400: - case 0x401: - fprintf(stderr, "BIOS panic at rombios.c, line %d\n", val); -- exit(1); -+ /* according to documentation, these can be safely ignored */ -+ break; - case 0x402: - case 0x403: - #ifdef DEBUG_BIOS -@@ -322,8 +323,9 @@ void bochs_bios_write(void *opaque, uint - /* LGPL'ed VGA BIOS messages */ - case 0x501: - case 0x502: -+ /* according to documentation, these can be safely ignored */ - fprintf(stderr, "VGA BIOS panic, line %d\n", val); -- exit(1); -+ break; - case 0x500: - case 0x503: - #ifdef DEBUG_BIOS -diff -rpu qemu-0.9.0.orig/hw/sb16.c qemu-0.9.0/hw/sb16.c ---- qemu-0.9.0.orig/hw/sb16.c 2007-02-05 23:01:54.000000000 +0000 -+++ qemu-0.9.0/hw/sb16.c 2007-02-20 21:53:41.000000000 +0000 -@@ -1235,8 +1235,10 @@ static int SB_read_DMA (void *opaque, in - s->block_size); - #endif - -- while (s->left_till_irq <= 0) { -- s->left_till_irq = s->block_size + s->left_till_irq; -+ if (s->block_size) { -+ while (s->left_till_irq <= 0) { -+ s->left_till_irq = s->block_size + s->left_till_irq; -+ } - } - - return dma_pos; -diff -rpu qemu-0.9.0.orig/slirp/slirp.c qemu-0.9.0/slirp/slirp.c ---- qemu-0.9.0.orig/slirp/slirp.c 2007-02-05 23:01:54.000000000 +0000 -+++ qemu-0.9.0/slirp/slirp.c 2007-02-20 21:53:41.000000000 +0000 -@@ -611,6 +611,10 @@ void slirp_input(const uint8_t *pkt, int - if (!m) - return; - /* Note: we add to align the IP header */ -+ /* taviso: large values in ne2k TCNT register may exceed msize on transmit */ -+ if (M_FREEROOM(m) < pkt_len + 2) { -+ m_inc(m, pkt_len + 2); -+ } - m->m_len = pkt_len + 2; - memcpy(m->m_data + 2, pkt, pkt_len); - -diff -rpu qemu-0.9.0.orig/target-i386/translate.c qemu-0.9.0/target-i386/translate.c ---- qemu-0.9.0.orig/target-i386/translate.c 2007-02-05 23:01:54.000000000 +0000 -+++ qemu-0.9.0/target-i386/translate.c 2007-02-20 21:53:41.000000000 +0000 -@@ -5326,7 +5326,12 @@ static target_ulong disas_insn(DisasCont - if (CODE64(s)) - goto illegal_op; - val = ldub_code(s->pc++); -- gen_op_aam(val); -+ /* taviso: operand can be zero */ -+ if (val) { -+ gen_op_aam(val); -+ } else { -+ gen_exception(s, EXCP00_DIVZ, s->pc - s->cs_base); -+ } - s->cc_op = CC_OP_LOGICB; - break; - case 0xd5: /* aad */ -@@ -5374,6 +5379,7 @@ static target_ulong disas_insn(DisasCont - gen_jmp_im(pc_start - s->cs_base); - gen_op_into(s->pc - pc_start); - break; -+#ifdef WANT_ICEBP - case 0xf1: /* icebp (undocumented, exits to external debugger) */ - #if 1 - gen_debug(s, pc_start - s->cs_base); -@@ -5383,6 +5389,7 @@ static target_ulong disas_insn(DisasCont - cpu_set_log(CPU_LOG_INT | CPU_LOG_TB_IN_ASM); - #endif - break; -+#endif /* icebp */ - case 0xfa: /* cli */ - if (!s->vm86) { - if (s->cpl <= s->iopl) { -diff -rpu qemu-0.9.0.orig/vl.c qemu-0.9.0/vl.c ---- qemu-0.9.0.orig/vl.c 2007-02-05 23:01:54.000000000 +0000 -+++ qemu-0.9.0/vl.c 2007-02-20 21:53:41.000000000 +0000 -@@ -3329,8 +3329,8 @@ typedef struct NetSocketState { - VLANClientState *vc; - int fd; - int state; /* 0 = getting length, 1 = getting data */ -- int index; -- int packet_len; -+ unsigned int index; -+ unsigned int packet_len; - uint8_t buf[4096]; - struct sockaddr_in dgram_dst; /* contains inet host and port destination iff connectionless (SOCK_DGRAM) */ - } NetSocketState; -@@ -3361,7 +3361,8 @@ static void net_socket_receive_dgram(voi - static void net_socket_send(void *opaque) - { - NetSocketState *s = opaque; -- int l, size, err; -+ int size, err; -+ unsigned l; - uint8_t buf1[4096]; - const uint8_t *buf; - -@@ -3400,7 +3401,15 @@ static void net_socket_send(void *opaque - l = s->packet_len - s->index; - if (l > size) - l = size; -- memcpy(s->buf + s->index, buf, l); -+ if (s->index + l <= sizeof(s->buf)) { -+ memcpy(s->buf + s->index, buf, l); -+ } else { -+ fprintf(stderr, "serious error: oversized packet received," -+ "connection terminated.\n"); -+ s->state = 0; -+ goto eoc; -+ } -+ - s->index += l; - buf += l; - size -= l; diff --git a/linkerscripts.patch b/linkerscripts.patch index 2a7f4bf2..5dcb4788 100644 --- a/linkerscripts.patch +++ b/linkerscripts.patch @@ -274,309 +274,3 @@ - /* These must appear regardless of . */ + /DISCARD/ : { *(.note.GNU-stack) } } ---- ppc.ld -+++ ppc.ld -@@ -1,116 +1,200 @@ --/* ld script to make i386 Linux kernel -- * Written by Martin Mares ; -- */ --OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc") --OUTPUT_ARCH(powerpc) --SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/alpha-unknown-linux-gnu/lib); -+/* Default linker script, for normal executables */ -+OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", -+ "elf32-powerpc") -+OUTPUT_ARCH(powerpc:common) - ENTRY(_start) -+SEARCH_DIR("/usr/powerpc-suse-linux/lib"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib"); - SECTIONS - { - /* Read-only sections, merged into text segment: */ -- . = 0x60000000 + SIZEOF_HEADERS; -- .interp : { *(.interp) } -- .hash : { *(.hash) } -- .dynsym : { *(.dynsym) } -- .dynstr : { *(.dynstr) } -- .gnu.version : { *(.gnu.version) } -- .gnu.version_d : { *(.gnu.version_d) } -- .gnu.version_r : { *(.gnu.version_r) } -- .rel.text : -- { *(.rel.text) *(.rel.gnu.linkonce.t*) } -- .rela.text : -- { *(.rela.text) *(.rela.gnu.linkonce.t*) } -- .rel.data : -- { *(.rel.data) *(.rel.gnu.linkonce.d*) } -- .rela.data : -- { *(.rela.data) *(.rela.gnu.linkonce.d*) } -- .rel.rodata : -- { *(.rel.rodata) *(.rel.gnu.linkonce.r*) } -- .rela.rodata : -- { *(.rela.rodata) *(.rela.gnu.linkonce.r*) } -- .rel.got : { *(.rel.got) } -- .rela.got : { *(.rela.got) } -- .rel.ctors : { *(.rel.ctors) } -- .rela.ctors : { *(.rela.ctors) } -- .rel.dtors : { *(.rel.dtors) } -- .rela.dtors : { *(.rela.dtors) } -- .rel.init : { *(.rel.init) } -- .rela.init : { *(.rela.init) } -- .rel.fini : { *(.rel.fini) } -- .rela.fini : { *(.rela.fini) } -- .rel.bss : { *(.rel.bss) } -- .rela.bss : { *(.rela.bss) } -- .rel.plt : { *(.rel.plt) } -- .rela.plt : { *(.rela.plt) } -- .init : { *(.init) } =0x47ff041f -- .text : -+ PROVIDE (__executable_start = 0x60000000); . = 0x60000000 + SIZEOF_HEADERS; -+ .interp : { *(.interp) } -+ .hash : { *(.hash) } -+ .dynsym : { *(.dynsym) } -+ .dynstr : { *(.dynstr) } -+ .gnu.version : { *(.gnu.version) } -+ .gnu.version_d : { *(.gnu.version_d) } -+ .gnu.version_r : { *(.gnu.version_r) } -+ .rel.init : { *(.rel.init) } -+ .rela.init : { *(.rela.init) } -+ .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } -+ .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } -+ .rel.fini : { *(.rel.fini) } -+ .rela.fini : { *(.rela.fini) } -+ .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } -+ .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } -+ .rel.data.rel.ro : { *(.rel.data.rel.ro*) } -+ .rela.data.rel.ro : { *(.rel.data.rel.ro*) } -+ .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } -+ .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } -+ .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) } -+ .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) } -+ .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) } -+ .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) } -+ .rel.ctors : { *(.rel.ctors) } -+ .rela.ctors : { *(.rela.ctors) } -+ .rel.dtors : { *(.rel.dtors) } -+ .rela.dtors : { *(.rela.dtors) } -+ .rel.got : { *(.rel.got) } -+ .rela.got : { *(.rela.got) } -+ .rela.got1 : { *(.rela.got1) } -+ .rela.got2 : { *(.rela.got2) } -+ .rel.sdata : { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) } -+ .rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) } -+ .rel.sbss : { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) } -+ .rela.sbss : { *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) } -+ .rel.sdata2 : { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) } -+ .rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) } -+ .rel.sbss2 : { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) } -+ .rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) } -+ .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } -+ .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } -+ .rel.plt : { *(.rel.plt) } -+ .rela.plt : { *(.rela.plt) } -+ .init : - { -- *(.text) -+ KEEP (*(.init)) -+ } =0 -+ .text : -+ { -+ *(.text .stub .text.* .gnu.linkonce.t.*) -+ KEEP (*(.text.*personality*)) - /* .gnu.warning sections are handled specially by elf32.em. */ - *(.gnu.warning) -- *(.gnu.linkonce.t*) -- } =0x47ff041f -- _etext = .; -+ *(.glink) -+ } =0 -+ .fini : -+ { -+ KEEP (*(.fini)) -+ } =0 -+ PROVIDE (__etext = .); -+ PROVIDE (_etext = .); - PROVIDE (etext = .); -- .fini : { *(.fini) } =0x47ff041f -- . = ALIGN(32 / 8); -- PROVIDE (__preinit_array_start = .); -- .preinit_array : { *(.preinit_array) } -- PROVIDE (__preinit_array_end = .); -- PROVIDE (__init_array_start = .); -- .init_array : { *(.init_array) } -- PROVIDE (__init_array_end = .); -- PROVIDE (__fini_array_start = .); -- .fini_array : { *(.fini_array) } -- PROVIDE (__fini_array_end = .); -- .rodata : { *(.rodata) *(.gnu.linkonce.r*) } -- .rodata1 : { *(.rodata1) } -- .reginfo : { *(.reginfo) } -+ .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } -+ .rodata1 : { *(.rodata1) } -+ .sdata2 : -+ { -+ PROVIDE (_SDA2_BASE_ = 32768); -+ *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) -+ } -+ .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } -+ .eh_frame_hdr : { *(.eh_frame_hdr) } -+ .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } -+ .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) } - /* Adjust the address for the data segment. We want to adjust up to - the same address within the page on the next page up. */ -- . = ALIGN(0x100000) + (. & (0x100000 - 1)); -- .data : -+ . = ALIGN (0x10000) - ((0x10000 - .) & (0x10000 - 1)); . = DATA_SEGMENT_ALIGN (0x10000, 0x1000); -+ /* Exception handling */ -+ .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } -+ .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } -+ /* Thread Local Storage sections */ -+ .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } -+ .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } -+ .preinit_array : -+ { -+ PROVIDE_HIDDEN (__preinit_array_start = .); -+ KEEP (*(.preinit_array)) -+ PROVIDE_HIDDEN (__preinit_array_end = .); -+ } -+ .init_array : -+ { -+ PROVIDE_HIDDEN (__init_array_start = .); -+ KEEP (*(.init_array)) -+ PROVIDE_HIDDEN (__init_array_end = .); -+ } -+ .fini_array : - { -- *(.data) -- *(.gnu.linkonce.d*) -- CONSTRUCTORS -+ PROVIDE_HIDDEN (__fini_array_start = .); -+ KEEP (*(.fini_array)) -+ PROVIDE_HIDDEN (__fini_array_end = .); - } -- .data1 : { *(.data1) } -- .ctors : -+ .ctors : - { -- *(.ctors) -+ /* gcc uses crtbegin.o to find the start of -+ the constructors, so we make sure it is -+ first. Because this is a wildcard, it -+ doesn't matter if the user does not -+ actually link against crtbegin.o; the -+ linker won't look for a file to match a -+ wildcard. The wildcard also means that it -+ doesn't matter which directory crtbegin.o -+ is in. */ -+ KEEP (*crtbegin*.o(.ctors)) -+ /* We don't want to include the .ctor section from -+ from the crtend.o file until after the sorted ctors. -+ The .ctor section from the crtend file contains the -+ end of ctors marker and it must be last */ -+ KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors)) -+ KEEP (*(SORT(.ctors.*))) -+ KEEP (*(.ctors)) - } -- .dtors : -+ .dtors : - { -- *(.dtors) -+ KEEP (*crtbegin*.o(.dtors)) -+ KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors)) -+ KEEP (*(SORT(.dtors.*))) -+ KEEP (*(.dtors)) - } -- .plt : { *(.plt) } -- .got : { *(.got.plt) *(.got) } -- .dynamic : { *(.dynamic) } -+ .jcr : { KEEP (*(.jcr)) } -+ .data.rel.ro : { *(.data.rel.ro.local) *(.data.rel.ro*) } -+ .got1 : { *(.got1) } -+ .got2 : { *(.got2) } -+ .dynamic : { *(.dynamic) } -+ .got : SPECIAL { *(.got) } -+ . = DATA_SEGMENT_RELRO_END (0, .); -+ .plt : SPECIAL { *(.plt) } -+ .data : -+ { -+ *(.data .data.* .gnu.linkonce.d.*) -+ KEEP (*(.gnu.linkonce.d.*personality*)) -+ SORT(CONSTRUCTORS) -+ } -+ .data1 : { *(.data1) } -+ .got : SPECIAL { *(.got) } - /* We want the small data sections together, so single-instruction offsets - can access them all, and initialized data all before uninitialized, so - we can shorten the on-disk segment size. */ -- .sdata : { *(.sdata) } -- _edata = .; -- PROVIDE (edata = .); -+ .sdata : -+ { -+ PROVIDE (_SDA_BASE_ = 32768); -+ *(.sdata .sdata.* .gnu.linkonce.s.*) -+ } -+ _edata = .; PROVIDE (edata = .); - __bss_start = .; -- .sbss : { *(.sbss) *(.scommon) } -- .bss : -+ .sbss : -+ { -+ PROVIDE (__sbss_start = .); PROVIDE (___sbss_start = .); -+ *(.dynsbss) -+ *(.sbss .sbss.* .gnu.linkonce.sb.*) -+ *(.scommon) -+ PROVIDE (__sbss_end = .); PROVIDE (___sbss_end = .); -+ } -+ .plt : SPECIAL { *(.plt) } -+ .bss : - { - *(.dynbss) -- *(.bss) -+ *(.bss .bss.* .gnu.linkonce.b.*) - *(COMMON) -+ /* Align here to ensure that the .bss section occupies space up to -+ _end. Align after .bss to ensure correct alignment even if the -+ .bss section disappears because there are no input sections. -+ FIXME: Why do we need it? When there is no .bss section, we don't -+ pad the .data section. */ -+ . = ALIGN(. != 0 ? 32 / 8 : 1); - } -- _end = . ; -+ . = ALIGN(32 / 8); -+ . = ALIGN(32 / 8); -+ _end = .; - PROVIDE (end = .); -+ . = DATA_SEGMENT_END (.); - /* Stabs debugging sections. */ -- .stab 0 : { *(.stab) } -- .stabstr 0 : { *(.stabstr) } -- .stab.excl 0 : { *(.stab.excl) } -- .stab.exclstr 0 : { *(.stab.exclstr) } -- .stab.index 0 : { *(.stab.index) } -+ .stab 0 : { *(.stab) } -+ .stabstr 0 : { *(.stabstr) } -+ .stab.excl 0 : { *(.stab.excl) } -+ .stab.exclstr 0 : { *(.stab.exclstr) } -+ .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } -- .comment 0 : { *(.comment) } -+ .comment 0 : { *(.comment) } - /* DWARF debug sections. - Symbols in the DWARF debugging sections are relative to the beginning - of the section so we begin them at 0. */ -@@ -124,7 +208,7 @@ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ -- .debug_info 0 : { *(.debug_info) } -+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } -@@ -136,5 +220,6 @@ - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } -- /* These must appear regardless of . */ -+ /DISCARD/ : { *(.fixup) } -+ /DISCARD/ : { *(.note.GNU-stack) } - } diff --git a/qemu-0.7.0-binfmt.patch b/qemu-0.7.0-binfmt.patch index 0b9812a2..f2383fca 100644 --- a/qemu-0.7.0-binfmt.patch +++ b/qemu-0.7.0-binfmt.patch @@ -1,17 +1,8 @@ ---- qemu-binfmt-conf.sh -+++ qemu-binfmt-conf.sh -@@ -2,38 +2,46 @@ - # enable automatic i386/ARM/SPARC/PPC program execution by the kernel - - # load the binfmt_misc module --/sbin/modprobe binfmt_misc -+ -+if test ! -e /proc/sys/fs/binfmt_misc/register -+then -+ /sbin/modprobe binfmt_misc -+ mount -t binfmt_misc none /proc/sys/fs/binfmt_misc -+fi - +Index: qemu-0.9.0/qemu-binfmt-conf.sh +=================================================================== +--- qemu-0.9.0.orig/qemu-binfmt-conf.sh ++++ qemu-0.9.0/qemu-binfmt-conf.sh +@@ -12,7 +12,7 @@ fi # probe cpu type cpu=`uname -m` case "$cpu" in @@ -19,6 +10,8 @@ + i386|i486|i586|i686|i86pc|BePC|x86_64) cpu="i386" ;; + m68k) +@@ -24,32 +24,34 @@ case "$cpu" in "Power Macintosh"|ppc|ppc64) cpu="ppc" ;; @@ -28,7 +21,6 @@ ;; + sparc*) + cpu="sparc" -+ ;; esac # register the interpreter for each cpu except for the native one @@ -51,8 +43,14 @@ if [ $cpu != "ppc" ] ; then - echo ':ppc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-ppc:' > /proc/sys/fs/binfmt_misc/register + echo ':ppc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-ppc:' > /proc/sys/fs/binfmt_misc/register + fi + if [ $cpu != "m68k" ] ; then + echo 'Please check cpu value and header information for m68k!' +- echo ':m68k:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-m68k:' > /proc/sys/fs/binfmt_misc/register ++ echo ':m68k:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-m68k:' > /proc/sys/fs/binfmt_misc/register fi if [ $cpu != "mips" ] ; then + # FIXME: We could use the other endianness on a MIPS host. - echo ':mips:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mips:' > /proc/sys/fs/binfmt_misc/register - echo ':mipsel:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mipsel:' > /proc/sys/fs/binfmt_misc/register + echo ':mips:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mips:' > /proc/sys/fs/binfmt_misc/register diff --git a/qemu-0.7.2-kqemu.patch b/qemu-0.7.2-kqemu.patch deleted file mode 100644 index 34eb9f3c..00000000 --- a/qemu-0.7.2-kqemu.patch +++ /dev/null @@ -1,117 +0,0 @@ ---- kqemu/kqemu.h -+++ kqemu/kqemu.h -@@ -0,0 +1,114 @@ -+/* -+ * KQEMU header -+ * -+ * Copyright (c) 2004-2005 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. -+ */ -+#ifndef KQEMU_H -+#define KQEMU_H -+ -+#define KQEMU_VERSION 0x010200 -+ -+struct kqemu_segment_cache { -+ uint32_t selector; -+ unsigned long base; -+ uint32_t limit; -+ uint32_t flags; -+}; -+ -+struct kqemu_cpu_state { -+#ifdef __x86_64__ -+ unsigned long regs[16]; -+#else -+ unsigned long regs[8]; -+#endif -+ unsigned long eip; -+ unsigned long eflags; -+ -+ uint32_t dummy0, dummy1, dumm2, dummy3, dummy4; -+ -+ struct kqemu_segment_cache segs[6]; /* selector values */ -+ struct kqemu_segment_cache ldt; -+ struct kqemu_segment_cache tr; -+ struct kqemu_segment_cache gdt; /* only base and limit are used */ -+ struct kqemu_segment_cache idt; /* only base and limit are used */ -+ -+ unsigned long cr0; -+ unsigned long dummy5; -+ unsigned long cr2; -+ unsigned long cr3; -+ unsigned long cr4; -+ uint32_t a20_mask; -+ -+ uint64_t efer __attribute__((aligned(8))); -+ -+ unsigned long dr0; -+ unsigned long dr1; -+ unsigned long dr2; -+ unsigned long dr3; -+ unsigned long dr6; -+ unsigned long dr7; -+ -+ uint8_t cpl; -+ uint8_t user_only; -+ -+ uint32_t error_code; /* error_code when exiting with an exception */ -+ unsigned long next_eip; /* next eip value when exiting with an interrupt */ -+ unsigned int nb_pages_to_flush; /* number of pages to flush, -+ KQEMU_FLUSH_ALL means full flush */ -+#define KQEMU_MAX_PAGES_TO_FLUSH 512 -+#define KQEMU_FLUSH_ALL (KQEMU_MAX_PAGES_TO_FLUSH + 1) -+ -+ long retval; -+ -+ /* number of ram_dirty entries to update */ -+ unsigned int nb_ram_pages_to_update; -+#define KQEMU_MAX_RAM_PAGES_TO_UPDATE 512 -+#define KQEMU_RAM_PAGES_UPDATE_ALL (KQEMU_MAX_RAM_PAGES_TO_UPDATE + 1) -+}; -+ -+struct kqemu_init { -+ uint8_t *ram_base; /* must be page aligned */ -+ unsigned long ram_size; /* must be multiple of 4 KB */ -+ uint8_t *ram_dirty; /* must be page aligned */ -+ uint32_t **phys_to_ram_map; /* must be page aligned */ -+ unsigned long *pages_to_flush; /* must be page aligned */ -+ unsigned long *ram_pages_to_update; /* must be page aligned */ -+}; -+ -+#define KQEMU_RET_ABORT (-1) -+#define KQEMU_RET_EXCEPTION 0x0000 /* 8 low order bit are the exception */ -+#define KQEMU_RET_INT 0x0100 /* 8 low order bit are the interrupt */ -+#define KQEMU_RET_SOFTMMU 0x0200 /* emulation needed (I/O or -+ unsupported INSN) */ -+#define KQEMU_RET_INTR 0x0201 /* interrupted by a signal */ -+#define KQEMU_RET_SYSCALL 0x0300 /* syscall insn */ -+ -+#ifdef _WIN32 -+#define KQEMU_EXEC CTL_CODE(FILE_DEVICE_UNKNOWN, 1, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) -+#define KQEMU_INIT CTL_CODE(FILE_DEVICE_UNKNOWN, 2, METHOD_BUFFERED, FILE_WRITE_ACCESS) -+#define KQEMU_GET_VERSION CTL_CODE(FILE_DEVICE_UNKNOWN, 3, METHOD_BUFFERED, FILE_READ_ACCESS) -+#else -+#define KQEMU_EXEC _IOWR('q', 1, struct kqemu_cpu_state) -+#define KQEMU_INIT _IOW('q', 2, struct kqemu_init) -+#define KQEMU_GET_VERSION _IOR('q', 3, int) -+#endif -+ -+#endif /* KQEMU_H */ diff --git a/qemu-0.8.3-gcc4.patch b/qemu-0.8.3-gcc4.patch new file mode 100644 index 00000000..8287f4d9 --- /dev/null +++ b/qemu-0.8.3-gcc4.patch @@ -0,0 +1,901 @@ +2007-02-17 Gwenole Beauchesne + + * target-i386/op.c (op_imull_EAX_T0, op_imulw_T0_T1, + op_imull_T0_T1): Add FORCE_RET() since CC_SRC involves a + compare-branch that may be optimized into a beqlr on ppc. + +2005-06-02 Gwenole Beauchesne + + * dyngen.c (trace_i386_insn): Fix push/imul case with 8-bit + immediate. + +2005-05-11 Paul Brook + + * gcc4 host support. + +--- qemu-0.8.3/dyngen-exec.h.gcc4 2006-12-23 01:49:32.000000000 +0100 ++++ qemu-0.8.3/dyngen-exec.h 2007-01-30 18:14:25.000000000 +0100 +@@ -188,7 +188,12 @@ extern int printf(const char *, ...); + #endif + + /* force GCC to generate only one epilog at the end of the function */ ++#if defined(__i386__) || defined(__x86_64__) ++/* Also add 4 bytes of padding so that we can replace the ret with a jmp. */ ++#define FORCE_RET() __asm__ __volatile__("nop;nop;nop;nop" : : : "memory"); ++#else + #define FORCE_RET() __asm__ __volatile__("" : : : "memory"); ++#endif + + #ifndef OPPROTO + #define OPPROTO +@@ -238,9 +243,16 @@ extern int __op_jmp0, __op_jmp1, __op_jm + #endif + + #if defined(__i386__) +-#define EXIT_TB() asm volatile ("ret") +-#define GOTO_LABEL_PARAM(n) asm volatile ("jmp " ASM_NAME(__op_gen_label) #n) ++/* Dyngen will replace hlt instructions with a ret instruction. Inserting a ++ ret directly would confuse dyngen. */ ++#define EXIT_TB() asm volatile ("hlt") ++/* Dyngen will replace cli with 0x9e (jmp). ++ We generate the offset manually. */ ++#define GOTO_LABEL_PARAM(n) \ ++ asm volatile ("cli;.long " ASM_NAME(__op_gen_label) #n " - 1f;1:") + #elif defined(__x86_64__) +-#define EXIT_TB() asm volatile ("ret") +-#define GOTO_LABEL_PARAM(n) asm volatile ("jmp " ASM_NAME(__op_gen_label) #n) ++/* The same as i386. */ ++#define EXIT_TB() asm volatile ("hlt") ++#define GOTO_LABEL_PARAM(n) \ ++ asm volatile ("cli;.long " ASM_NAME(__op_gen_label) #n " - 1f;1:") + #elif defined(__powerpc__) +--- qemu-0.8.3/dyngen.c.gcc4 2006-12-21 17:49:27.000000000 +0100 ++++ qemu-0.8.3/dyngen.c 2007-01-30 18:11:21.000000000 +0100 +@@ -32,6 +32,8 @@ + + #include "config-host.h" + ++//#define DEBUG_OP ++ + /* NOTE: we test CONFIG_WIN32 instead of _WIN32 to enabled cross + compilation */ + #if defined(CONFIG_WIN32) +@@ -1414,6 +1416,644 @@ int arm_emit_ldr_info(const char *name, + #endif + + ++#if defined(HOST_I386) || defined(HOST_X86_64) ++ ++/* This byte is the first byte of an instruction. */ ++#define FLAG_INSN (1 << 0) ++/* This byte has been processed as part of an instruction. */ ++#define FLAG_SCANNED (1 << 1) ++/* This instruction is a return instruction. Gcc cometimes generates prefix ++ bytes, so may be more than one byte long. */ ++#define FLAG_RET (1 << 2) ++/* This is either the target of a jump, or the preceeding instruction uses ++ a pc-relative offset. */ ++#define FLAG_TARGET (1 << 3) ++/* This is a magic instruction that needs fixing up. */ ++#define FLAG_EXIT (1 << 4) ++#define MAX_EXITS 5 ++ ++static void ++bad_opcode(const char *name, uint32_t op) ++{ ++ error("Unsupported opcode %0*x in %s", (op > 0xff) ? 4 : 2, op, name); ++} ++ ++/* Mark len bytes as scanned, Returns insn_size + len. Reports an error ++ if these bytes have already been scanned. */ ++static int ++eat_bytes(const char *name, char *flags, int insn, int insn_size, int len) ++{ ++ while (len > 0) { ++ /* This should never occur in sane code. */ ++ if (flags[insn + insn_size] & FLAG_SCANNED) ++ error ("Overlapping instructions in %s", name); ++ flags[insn + insn_size] |= FLAG_SCANNED; ++ insn_size++; ++ len--; ++ } ++ return insn_size; ++} ++ ++static void ++trace_i386_insn (const char *name, uint8_t *start_p, char *flags, int insn, ++ int len) ++{ ++ uint8_t *ptr; ++ uint8_t op; ++ int modrm; ++ int is_prefix; ++ int op_size; ++ int addr_size; ++ int insn_size; ++ int is_ret; ++ int is_condjmp; ++ int is_jmp; ++ int is_exit; ++ int is_pcrel; ++ int immed; ++ int seen_rexw; ++ int32_t disp; ++ ++ ptr = start_p + insn; ++ /* nonzero if this insn has a ModR/M byte. */ ++ modrm = 1; ++ /* The size of the immediate value in this instruction. */ ++ immed = 0; ++ /* The operand size. */ ++ op_size = 4; ++ /* The address size */ ++ addr_size = 4; ++ /* The total length of this instruction. */ ++ insn_size = 0; ++ is_prefix = 1; ++ is_ret = 0; ++ is_condjmp = 0; ++ is_jmp = 0; ++ is_exit = 0; ++ seen_rexw = 0; ++ is_pcrel = 0; ++ ++ while (is_prefix) { ++ op = ptr[insn_size]; ++ insn_size = eat_bytes(name, flags, insn, insn_size, 1); ++ is_prefix = 0; ++ switch (op >> 4) { ++ case 0: ++ case 1: ++ case 2: ++ case 3: ++ if (op == 0x0f) { ++ /* two-byte opcode. */ ++ op = ptr[insn_size]; ++ insn_size = eat_bytes(name, flags, insn, insn_size, 1); ++ switch (op >> 4) { ++ case 0: ++ if ((op & 0xf) > 3) ++ modrm = 0; ++ break; ++ case 1: /* vector move or prefetch */ ++ case 2: /* various moves and vector compares. */ ++ case 4: /* cmov */ ++ case 5: /* vector instructions */ ++ case 6: ++ case 13: ++ case 14: ++ case 15: ++ break; ++ case 7: /* mmx */ ++ if (op & 0x77) /* emms */ ++ modrm = 0; ++ break; ++ case 3: /* wrmsr, rdtsc, rdmsr, rdpmc, sysenter, sysexit */ ++ modrm = 0; ++ break; ++ case 8: /* long conditional jump */ ++ is_condjmp = 1; ++ immed = op_size; ++ modrm = 0; ++ break; ++ case 9: /* setcc */ ++ break; ++ case 10: ++ switch (op & 0x7) { ++ case 0: /* push fs/gs */ ++ case 1: /* pop fs/gs */ ++ case 2: /* cpuid/rsm */ ++ modrm = 0; ++ break; ++ case 4: /* shld/shrd immediate */ ++ immed = 1; ++ break; ++ default: /* Normal instructions with a ModR/M byte. */ ++ break; ++ } ++ break; ++ case 11: ++ switch (op & 0xf) { ++ case 10: /* bt, bts, btr, btc */ ++ immed = 1; ++ break; ++ default: ++ /* cmpxchg, lss, btr, lfs, lgs, movzx, btc, bsf, bsr ++ undefined, and movsx */ ++ break; ++ } ++ break; ++ case 12: ++ if (op & 8) { ++ /* bswap */ ++ modrm = 0; ++ } else { ++ switch (op & 0x7) { ++ case 2: ++ case 4: ++ case 5: ++ case 6: ++ immed = 1; ++ break; ++ default: ++ break; ++ } ++ } ++ break; ++ } ++ } else if ((op & 0x07) <= 0x3) { ++ /* General arithmentic ax. */ ++ } else if ((op & 0x07) <= 0x5) { ++ /* General arithmetic ax, immediate. */ ++ if (op & 0x01) ++ immed = op_size; ++ else ++ immed = 1; ++ modrm = 0; ++ } else if ((op & 0x23) == 0x22) { ++ /* Segment prefix. */ ++ is_prefix = 1; ++ } else { ++ /* Segment register push/pop or DAA/AAA/DAS/AAS. */ ++ modrm = 0; ++ } ++ break; ++ ++#if defined(HOST_X86_64) ++ case 4: /* rex prefix. */ ++ is_prefix = 1; ++ /* The address/operand size is actually 64-bit, but the immediate ++ values in the instruction are still 32-bit. */ ++ op_size = 4; ++ addr_size = 4; ++ if (op & 8) ++ seen_rexw = 1; ++ break; ++#else ++ case 4: /* inc/dec register. */ ++#endif ++ case 5: /* push/pop general register. */ ++ modrm = 0; ++ break; ++ ++ case 6: ++ switch (op & 0x0f) { ++ case 0: /* pusha */ ++ case 1: /* popa */ ++ modrm = 0; ++ break; ++ case 2: /* bound */ ++ case 3: /* arpl */ ++ break; ++ case 4: /* FS */ ++ case 5: /* GS */ ++ is_prefix = 1; ++ break; ++ case 6: /* opcode size prefix. */ ++ op_size = 2; ++ is_prefix = 1; ++ break; ++ case 7: /* Address size prefix. */ ++ addr_size = 2; ++ is_prefix = 1; ++ break; ++ case 8: /* push immediate */ ++ immed = op_size; ++ modrm = 0; ++ break; ++ case 10: /* push 8-bit immediate */ ++ immed = 1; ++ modrm = 0; ++ break; ++ case 9: /* imul immediate */ ++ immed = op_size; ++ break; ++ case 11: /* imul 8-bit immediate */ ++ immed = 1; ++ break; ++ case 12: /* insb */ ++ case 13: /* insw */ ++ case 14: /* outsb */ ++ case 15: /* outsw */ ++ modrm = 0; ++ break; ++ } ++ break; ++ ++ case 7: /* Short conditional jump. */ ++ is_condjmp = 1; ++ immed = 1; ++ modrm = 0; ++ break; ++ ++ case 8: ++ if ((op & 0xf) <= 3) { ++ /* arithmetic immediate. */ ++ if ((op & 3) == 1) ++ immed = op_size; ++ else ++ immed = 1; ++ } ++ /* else test, xchg, mov, lea or pop general. */ ++ break; ++ ++ case 9: ++ /* Various single-byte opcodes with no modrm byte. */ ++ modrm = 0; ++ if (op == 10) { ++ /* Call */ ++ immed = 4; ++ } ++ break; ++ ++ case 10: ++ switch ((op & 0xe) >> 1) { ++ case 0: /* mov absoliute immediate. */ ++ case 1: ++ if (seen_rexw) ++ immed = 8; ++ else ++ immed = addr_size; ++ break; ++ case 4: /* test immediate. */ ++ if (op & 1) ++ immed = op_size; ++ else ++ immed = 1; ++ break; ++ default: /* Various string ops. */ ++ break; ++ } ++ modrm = 0; ++ break; ++ ++ case 11: /* move immediate to register */ ++ if (op & 8) { ++ if (seen_rexw) ++ immed = 8; ++ else ++ immed = op_size; ++ } else { ++ immed = 1; ++ } ++ modrm = 0; ++ break; ++ ++ case 12: ++ switch (op & 0xf) { ++ case 0: /* shift immediate */ ++ case 1: ++ immed = 1; ++ break; ++ case 2: /* ret immediate */ ++ immed = 2; ++ modrm = 0; ++ bad_opcode(name, op); ++ break; ++ case 3: /* ret */ ++ modrm = 0; ++ is_ret = 1; ++ case 4: /* les */ ++ case 5: /* lds */ ++ break; ++ case 6: /* mov immediate byte */ ++ immed = 1; ++ break; ++ case 7: /* mov immediate */ ++ immed = op_size; ++ break; ++ case 8: /* enter */ ++ /* TODO: Is this right? */ ++ immed = 3; ++ modrm = 0; ++ break; ++ case 10: /* retf immediate */ ++ immed = 2; ++ modrm = 0; ++ bad_opcode(name, op); ++ break; ++ case 13: /* int */ ++ immed = 1; ++ modrm = 0; ++ break; ++ case 11: /* retf */ ++ case 15: /* iret */ ++ modrm = 0; ++ bad_opcode(name, op); ++ break; ++ default: /* leave, int3 or into */ ++ modrm = 0; ++ break; ++ } ++ break; ++ ++ case 13: ++ if ((op & 0xf) >= 8) { ++ /* Coprocessor escape. For our purposes this is just a normal ++ instruction with a ModR/M byte. */ ++ } else if ((op & 0xf) >= 4) { ++ /* AAM, AAD or XLAT */ ++ modrm = 0; ++ } ++ /* else shift instruction */ ++ break; ++ ++ case 14: ++ switch ((op & 0xc) >> 2) { ++ case 0: /* loop or jcxz */ ++ is_condjmp = 1; ++ immed = 1; ++ break; ++ case 1: /* in/out immed */ ++ immed = 1; ++ break; ++ case 2: /* call or jmp */ ++ switch (op & 3) { ++ case 0: /* call */ ++ immed = op_size; ++ break; ++ case 1: /* long jump */ ++ immed = 4; ++ is_jmp = 1; ++ break; ++ case 2: /* far jmp */ ++ bad_opcode(name, op); ++ break; ++ case 3: /* short jmp */ ++ immed = 1; ++ is_jmp = 1; ++ break; ++ } ++ break; ++ case 3: /* in/out register */ ++ break; ++ } ++ modrm = 0; ++ break; ++ ++ case 15: ++ switch ((op & 0xe) >> 1) { ++ case 0: ++ case 1: ++ is_prefix = 1; ++ break; ++ case 2: ++ case 4: ++ case 5: ++ case 6: ++ modrm = 0; ++ /* Some privileged insns are used as markers. */ ++ switch (op) { ++ case 0xf4: /* hlt: Exit translation block. */ ++ is_exit = 1; ++ break; ++ case 0xfa: /* cli: Jump to label. */ ++ is_exit = 1; ++ immed = 4; ++ break; ++ case 0xfb: /* sti: TB patch jump. */ ++ /* Mark the insn for patching, but continue sscanning. */ ++ flags[insn] |= FLAG_EXIT; ++ immed = 4; ++ break; ++ } ++ break; ++ case 3: /* unary grp3 */ ++ if ((ptr[insn_size] & 0x38) == 0) { ++ if (op == 0xf7) ++ immed = op_size; ++ else ++ immed = 1; /* test immediate */ ++ } ++ break; ++ case 7: /* inc/dec grp4/5 */ ++ /* TODO: This includes indirect jumps. We should fail if we ++ encounter one of these. */ ++ break; ++ } ++ break; ++ } ++ } ++ ++ if (modrm) { ++ if (addr_size != 4) ++ error("16-bit addressing mode used in %s", name); ++ ++ disp = 0; ++ modrm = ptr[insn_size]; ++ insn_size = eat_bytes(name, flags, insn, insn_size, 1); ++ modrm &= 0xc7; ++ switch ((modrm & 0xc0) >> 6) { ++ case 0: ++ if (modrm == 5) ++ disp = 4; ++ break; ++ case 1: ++ disp = 1; ++ break; ++ case 2: ++ disp = 4; ++ break; ++ } ++ if ((modrm & 0xc0) != 0xc0 && (modrm & 0x7) == 4) { ++ /* SIB byte */ ++ if (modrm == 4 && (ptr[insn_size] & 0x7) == 5) { ++ disp = 4; ++ is_pcrel = 1; ++ } ++ insn_size = eat_bytes(name, flags, insn, insn_size, 1); ++ } ++ insn_size = eat_bytes(name, flags, insn, insn_size, disp); ++ } ++ insn_size = eat_bytes(name, flags, insn, insn_size, immed); ++ if (is_condjmp || is_jmp) { ++ if (immed == 1) { ++ disp = (int8_t)*(ptr + insn_size - 1); ++ } else { ++ disp = (((int32_t)*(ptr + insn_size - 1)) << 24) ++ | (((int32_t)*(ptr + insn_size - 2)) << 16) ++ | (((int32_t)*(ptr + insn_size - 3)) << 8) ++ | *(ptr + insn_size - 4); ++ } ++ disp += insn_size; ++ /* Jumps to external symbols point to the address of the offset ++ before relocation. */ ++ /* ??? These are probably a tailcall. We could fix them up by ++ replacing them with jmp to EOB + call, but it's easier to just ++ prevent the compiler generating them. */ ++ if (disp == 1) ++ error("Unconditional jump (sibcall?) in %s", name); ++ disp += insn; ++ if (disp < 0 || disp > len) ++ error("Jump outside instruction in %s", name); ++ ++ if ((flags[disp] & (FLAG_INSN | FLAG_SCANNED)) == FLAG_SCANNED) ++ error("Overlapping instructions in %s", name); ++ ++ flags[disp] |= (FLAG_INSN | FLAG_TARGET); ++ is_pcrel = 1; ++ } ++ if (is_pcrel) { ++ /* Mark the following insn as a jump target. This will stop ++ this instruction being moved. */ ++ flags[insn + insn_size] |= FLAG_TARGET; ++ } ++ if (is_ret) ++ flags[insn] |= FLAG_RET; ++ ++ if (is_exit) ++ flags[insn] |= FLAG_EXIT; ++ ++ if (!(is_jmp || is_ret || is_exit)) ++ flags[insn + insn_size] |= FLAG_INSN; ++} ++ ++/* Scan a function body. Returns the position of the return sequence. ++ Sets *patch_bytes to the number of bytes that need to be copied from that ++ location. If no patching is required (ie. the return is the last insn) ++ *patch_bytes will be set to -1. *plen is the number of code bytes to copy. ++ */ ++static int trace_i386_op(const char * name, uint8_t *start_p, int *plen, ++ int *patch_bytes, int *exit_addrs) ++{ ++ char *flags; ++ int more; ++ int insn; ++ int retpos; ++ int bytes; ++ int num_exits; ++ int len; ++ int last_insn; ++ ++ len = *plen; ++ flags = malloc(len + 1); ++ memset(flags, 0, len + 1); ++ flags[0] |= FLAG_INSN; ++ more = 1; ++ while (more) { ++ more = 0; ++ for (insn = 0; insn < len; insn++) { ++ if ((flags[insn] & (FLAG_INSN | FLAG_SCANNED)) == FLAG_INSN) { ++ trace_i386_insn(name, start_p, flags, insn, len); ++ more = 1; ++ } ++ } ++ } ++ ++ /* Strip any unused code at the end of the function. */ ++ while (len > 0 && flags[len - 1] == 0) ++ len--; ++ ++ retpos = -1; ++ num_exits = 0; ++ last_insn = 0; ++ for (insn = 0; insn < len; insn++) { ++ if (flags[insn] & FLAG_RET) { ++ /* ??? In theory it should be possible to handle multiple return ++ points. In practice it's not worth the effort. */ ++ if (retpos != -1) ++ error("Multiple return instructions in %s", name); ++ retpos = insn; ++ } ++ if (flags[insn] & FLAG_EXIT) { ++ if (num_exits == MAX_EXITS) ++ error("Too many block exits in %s", name); ++ exit_addrs[num_exits] = insn; ++ num_exits++; ++ } ++ if (flags[insn] & FLAG_INSN) ++ last_insn = insn; ++ } ++ ++ exit_addrs[num_exits] = -1; ++ if (retpos == -1) { ++ if (num_exits == 0) { ++ error ("No return instruction found in %s", name); ++ } else { ++ retpos = len; ++ last_insn = len; ++ } ++ } ++ ++ /* If the return instruction is the last instruction we can just ++ remove it. */ ++ if (retpos == last_insn) ++ *patch_bytes = -1; ++ else ++ *patch_bytes = 0; ++ ++ /* Back up over any nop instructions. */ ++ while (retpos > 0 ++ && (flags[retpos] & FLAG_TARGET) == 0 ++ && (flags[retpos - 1] & FLAG_INSN) != 0 ++ && start_p[retpos - 1] == 0x90) { ++ retpos--; ++ } ++ ++ if (*patch_bytes == -1) { ++ *plen = retpos; ++ free (flags); ++ return retpos; ++ } ++ *plen = len; ++ ++ /* The ret is in the middle of the function. Find four more bytes that ++ so the ret can be replaced by a jmp. */ ++ /* ??? Use a short jump where possible. */ ++ bytes = 4; ++ insn = retpos + 1; ++ /* We can clobber everything up to the next jump target. */ ++ while (insn < len && bytes > 0 && (flags[insn] & FLAG_TARGET) == 0) { ++ insn++; ++ bytes--; ++ } ++ if (bytes > 0) { ++ /* ???: Strip out nop blocks. */ ++ /* We can't do the replacement without clobbering anything important. ++ Copy preceeding instructions(s) to give us some space. */ ++ while (retpos > 0) { ++ /* If this byte is the target of a jmp we can't move it. */ ++ if (flags[retpos] & FLAG_TARGET) ++ break; ++ ++ (*patch_bytes)++; ++ bytes--; ++ retpos--; ++ ++ /* Break out of the loop if we have enough space and this is either ++ the first byte of an instruction or a pad byte. */ ++ if ((flags[retpos] & (FLAG_INSN | FLAG_SCANNED)) != FLAG_SCANNED ++ && bytes <= 0) { ++ break; ++ } ++ } ++ } ++ ++ if (bytes > 0) ++ error("Unable to replace ret with jmp in %s\n", name); ++ ++ free(flags); ++ return retpos; ++} ++ ++#endif ++ + #define MAX_ARGS 3 + + /* generate op code */ +@@ -1427,6 +2067,11 @@ void gen_code(const char *name, host_ulo + uint8_t args_present[MAX_ARGS]; + const char *sym_name, *p; + EXE_RELOC *rel; ++#if defined(HOST_I386) || defined(HOST_X86_64) ++ int patch_bytes; ++ int retpos; ++ int exit_addrs[MAX_EXITS]; ++#endif + + /* Compute exact size excluding prologue and epilogue instructions. + * Increment start_offset to skip epilogue instructions, then compute +@@ -1437,33 +2082,12 @@ void gen_code(const char *name, host_ulo + p_end = p_start + size; + start_offset = offset; + #if defined(HOST_I386) || defined(HOST_X86_64) +-#ifdef CONFIG_FORMAT_COFF +- { +- uint8_t *p; +- p = p_end - 1; +- if (p == p_start) +- error("empty code for %s", name); +- while (*p != 0xc3) { +- p--; +- if (p <= p_start) +- error("ret or jmp expected at the end of %s", name); +- } +- copy_size = p - p_start; +- } +-#else + { + int len; + len = p_end - p_start; +- if (len == 0) +- error("empty code for %s", name); +- if (p_end[-1] == 0xc3) { +- len--; +- } else { +- error("ret or jmp expected at the end of %s", name); +- } ++ retpos = trace_i386_op(name, p_start, &len, &patch_bytes, exit_addrs); + copy_size = len; + } +-#endif + #elif defined(HOST_PPC) + { + uint8_t *p; +@@ -1675,6 +2299,13 @@ void gen_code(const char *name, host_ulo + } + + if (gen_switch == 2) { ++#if defined(HOST_I386) || defined(HOST_X86_64) ++ if (patch_bytes != -1) ++ copy_size += patch_bytes; ++#ifdef DEBUG_OP ++ copy_size += 2; ++#endif ++#endif + fprintf(outfile, "DEF(%s, %d, %d)\n", name + 3, nb_args, copy_size); + } else if (gen_switch == 1) { + +@@ -1879,7 +2510,43 @@ void gen_code(const char *name, host_ulo + #error unsupport object format + #endif + } ++ } ++ /* Replace the marker instructions with the actual opcodes. */ ++ for (i = 0; exit_addrs[i] != -1; i++) { ++ int op; ++ switch (p_start[exit_addrs[i]]) ++ { ++ case 0xf4: op = 0xc3; break; /* hlt -> ret */ ++ case 0xfa: op = 0xe9; break; /* cli -> jmp */ ++ case 0xfb: op = 0xe9; break; /* sti -> jmp */ ++ default: error("Internal error"); ++ } ++ fprintf(outfile, ++ " *(uint8_t *)(gen_code_ptr + %d) = 0x%x;\n", ++ exit_addrs[i], op); + } ++ /* Fix up the return instruction. */ ++ if (patch_bytes != -1) { ++ if (patch_bytes) { ++ fprintf(outfile, " memcpy(gen_code_ptr + %d," ++ "gen_code_ptr + %d, %d);\n", ++ copy_size, retpos, patch_bytes); ++ } ++ fprintf(outfile, ++ " *(uint8_t *)(gen_code_ptr + %d) = 0xe9;\n", ++ retpos); ++ fprintf(outfile, ++ " *(uint32_t *)(gen_code_ptr + %d) = 0x%x;\n", ++ retpos + 1, copy_size - (retpos + 5)); ++ ++ copy_size += patch_bytes; ++ } ++#ifdef DEBUG_OP ++ fprintf(outfile, ++ " *(uint16_t *)(gen_code_ptr + %d) = 0x9090;\n", ++ copy_size); ++ copy_size += 2; ++#endif + } + #elif defined(HOST_X86_64) + { +@@ -1913,6 +2580,42 @@ void gen_code(const char *name, host_ulo + } + } + } ++ /* Replace the marker instructions with the actual opcodes. */ ++ for (i = 0; exit_addrs[i] != -1; i++) { ++ int op; ++ switch (p_start[exit_addrs[i]]) ++ { ++ case 0xf4: op = 0xc3; break; /* hlt -> ret */ ++ case 0xfa: op = 0xe9; break; /* cli -> jmp */ ++ case 0xfb: op = 0xe9; break; /* sti -> jmp */ ++ default: error("Internal error"); ++ } ++ fprintf(outfile, ++ " *(uint8_t *)(gen_code_ptr + %d) = 0x%x;\n", ++ exit_addrs[i], op); ++ } ++ /* Fix up the return instruction. */ ++ if (patch_bytes != -1) { ++ if (patch_bytes) { ++ fprintf(outfile, " memcpy(gen_code_ptr + %d," ++ "gen_code_ptr + %d, %d);\n", ++ copy_size, retpos, patch_bytes); ++ } ++ fprintf(outfile, ++ " *(uint8_t *)(gen_code_ptr + %d) = 0xe9;\n", ++ retpos); ++ fprintf(outfile, ++ " *(uint32_t *)(gen_code_ptr + %d) = 0x%x;\n", ++ retpos + 1, copy_size - (retpos + 5)); ++ ++ copy_size += patch_bytes; ++ } ++#ifdef DEBUG_OP ++ fprintf(outfile, ++ " *(uint16_t *)(gen_code_ptr + %d) = 0x9090;\n", ++ copy_size); ++ copy_size += 2; ++#endif + } + #elif defined(HOST_PPC) + { +--- qemu-0.8.3/exec-all.h.gcc4 2006-11-12 21:40:55.000000000 +0100 ++++ qemu-0.8.3/exec-all.h 2007-01-30 18:11:21.000000000 +0100 +@@ -326,14 +326,15 @@ do {\ + + #elif defined(__i386__) && defined(USE_DIRECT_JUMP) + +-/* we patch the jump instruction directly */ ++/* we patch the jump instruction directly. Use sti in place of the actual ++ jmp instruction so that dyngen can patch in the correct result. */ + #define GOTO_TB(opname, tbparam, n)\ + do {\ + asm volatile (".section .data\n"\ + ASM_OP_LABEL_NAME(n, opname) ":\n"\ + ".long 1f\n"\ + ASM_PREVIOUS_SECTION \ +- "jmp " ASM_NAME(__op_jmp) #n "\n"\ ++ "sti;.long " ASM_NAME(__op_jmp) #n " - 1f\n"\ + "1:\n");\ + } while (0) + +--- qemu-0.8.3/target-i386/op.c~ 2007-02-17 17:12:48.000000000 +0100 ++++ qemu-0.8.3/target-i386/op.c 2007-02-17 17:48:46.000000000 +0100 +@@ -303,6 +303,7 @@ + EDX = (uint32_t)(res >> 32); + CC_DST = res; + CC_SRC = (res != (int32_t)res); ++ FORCE_RET(); + } + + void OPPROTO op_imulw_T0_T1(void) +@@ -312,6 +313,7 @@ + T0 = res; + CC_DST = res; + CC_SRC = (res != (int16_t)res); ++ FORCE_RET(); + } + + void OPPROTO op_imull_T0_T1(void) +@@ -321,6 +323,7 @@ + T0 = res; + CC_DST = res; + CC_SRC = (res != (int32_t)res); ++ FORCE_RET(); + } + + #ifdef TARGET_X86_64 diff --git a/qemu-0.9.0-fadvise64.patch b/qemu-0.9.0-fadvise64.patch deleted file mode 100644 index 18750f0f..00000000 --- a/qemu-0.9.0-fadvise64.patch +++ /dev/null @@ -1,47 +0,0 @@ -Index: qemu-0.9.0/linux-user/syscall.c -=================================================================== ---- qemu-0.9.0.orig/linux-user/syscall.c -+++ qemu-0.9.0/linux-user/syscall.c -@@ -144,6 +144,7 @@ type name (type1 arg1,type2 arg2,type3 a - #define __NR_sys_getdents64 __NR_getdents64 - #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo - #define __NR_sys_syslog __NR_syslog -+#define __NR_sys_fadvise64 __NR_fadvise64 - - #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__) - #define __NR__llseek __NR_lseek -@@ -164,6 +165,7 @@ _syscall5(int, _llseek, uint, fd, ulon - loff_t *, res, uint, wh); - _syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo) - _syscall3(int,sys_syslog,int,type,char*,bufp,int,len) -+_syscall4(int,sys_fadvise64,int,fd,loff_t,offset,loff_t,len,int,advice) - #ifdef __NR_exit_group - _syscall1(int,exit_group,int,error_code) - #endif -@@ -4151,6 +4153,17 @@ long do_syscall(void *cpu_env, int num, - break; - } - #endif -+#ifdef TARGET_NR_fadvise64 -+ case TARGET_NR_fadvise64: -+ ret = get_errno(sys_fadvise64((int)arg1, arg2, arg3, (int)arg4)); -+ break; -+#endif -+#ifdef TARGET_NR_fadvise64_64 -+ case TARGET_NR_fadvise64_64: -+ // fadvise64_64 should be just a wrapper for fadvise_64 -+ ret = get_errno(sys_fadvise64((int)arg1, arg2, arg3, (int)arg4)); -+ break; -+#endif - default: - unimplemented: - gemu_log("qemu: Unsupported syscall: %d\n", num); -Index: qemu-0.9.0/linux-user/i386/syscall_nr.h -=================================================================== ---- qemu-0.9.0.orig/linux-user/i386/syscall_nr.h -+++ qemu-0.9.0/linux-user/i386/syscall_nr.h -@@ -272,3 +272,4 @@ - #define TARGET_NR_clock_nanosleep (TARGET_NR_timer_create+8) - - #define TARGET_NR_utimes 271 -+#define TARGET_NR_fadvise64_64 272 diff --git a/qemu-0.9.0-fix-cpus-chaining.patch b/qemu-0.9.0-fix-cpus-chaining.patch deleted file mode 100644 index 1af08d52..00000000 --- a/qemu-0.9.0-fix-cpus-chaining.patch +++ /dev/null @@ -1,46 +0,0 @@ -From gbeauchesne@mandriva.com Tue Mar 13 17:01:17 2007 -Date: Tue, 20 Feb 2007 01:44:37 +0100 (CET) -From: Gwenole Beauchesne -Reply-To: qemu-devel@nongnu.org -To: qemu-devel@nongnu.org -Subject: [Qemu-devel] [PATCH] Fix CPU chaining in linux-user emulation - -Hi, - -This patch fixes chaining of CPU instances. It was simply trashed with the -memcpy() thus causing problems in threaded programs (N > 2): an infinite -loop in next cpu_init(). - -================================================================================ ---- qemu-0.9.0/cpu-all.h -+++ qemu-0.9.0/cpu-all.h -@@ -760,6 +760,8 @@ - - #endif /* SINGLE_CPU_DEFINES */ - -+CPUState *cpu_copy(CPUState *env); -+ - void cpu_dump_state(CPUState *env, FILE *f, - int (*cpu_fprintf)(FILE *f, const char *fmt, ...), - int flags); ---- qemu-0.9.0/exec.c -+++ qemu-0.9.0/exec.c -@@ -1221,6 +1221,18 @@ - abort(); - } - -+CPUState *cpu_copy(CPUState *env) -+{ -+ CPUState *new_env = cpu_init(); -+ /* preserve chaining and index */ -+ CPUState *next_cpu = new_env->next_cpu; -+ int cpu_index = new_env->cpu_index; -+ memcpy(new_env, env, sizeof(CPUState)); -+ new_env->next_cpu = next_cpu; -+ new_env->cpu_index = cpu_index; -+ return new_env; -+} -+ - #if !defined(CONFIG_USER_ONLY) - - /* NOTE: if flush_global is true, also flush global entries (not diff --git a/qemu-0.9.0-fix-x86-fprem.patch b/qemu-0.9.0-fix-x86-fprem.patch deleted file mode 100644 index bfd5b4d7..00000000 --- a/qemu-0.9.0-fix-x86-fprem.patch +++ /dev/null @@ -1,151 +0,0 @@ -From jseward@acm.org Tue Mar 27 18:05:53 2007 -Date: Sat, 17 Mar 2007 17:35:38 +0000 -From: Julian Seward -Reply-To: qemu-devel@nongnu.org -To: qemu-devel@nongnu.org -Subject: [Qemu-devel] [PATCH] Fix guest x86/amd64 helper_fprem/helper_fprem1 - - -The helpers for x86/amd64 fprem and fprem1 in target-i386/helper.c are -significantly borked and, for example, cause konqueror in RedHat8 (x86 -guest) to go into an infinite loop when displaying http://news.bbc.co.uk. - -helper_fprem has the following borkage: -- various Inf/Nan/zero inputs not handled correctly -- incorrect rounding when converting negative 'dblq' to 'q' -- incorrect order of assignment to C bits (0,3,1 not 0,1,3) - -helper_fprem1 has those problems and is also incorrect about the points -at which its rounding needs to differ from that of helper_fprem. - -Patch below fixes all these. It brings the fprem and fprem1 behaviour -very much closer to the hardware -- not identical, but close. Some -+0.0 results should really be -0.0 and there may still be other differences. - -Anyway konquerer no longer loops with the patch applied. - ---- qemu-0.9.0/target-i386/helper.c.fix-x86-fprem 2007-03-27 13:48:10.000000000 -0400 -+++ qemu-0.9.0/target-i386/helper.c 2007-03-27 14:03:06.000000000 -0400 -@@ -3124,30 +3124,51 @@ void helper_fprem1(void) - CPU86_LDouble dblq, fpsrcop, fptemp; - CPU86_LDoubleU fpsrcop1, fptemp1; - int expdif; -- int q; -+ signed long long int q; -+ -+ if (isinf(ST0) || isnan(ST0) || isnan(ST1) || (ST1 == 0.0)) { -+ ST0 = 0.0 / 0.0; /* NaN */ -+ env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */ -+ return; -+ } - - fpsrcop = ST0; - fptemp = ST1; - fpsrcop1.d = fpsrcop; - fptemp1.d = fptemp; - expdif = EXPD(fpsrcop1) - EXPD(fptemp1); -+ -+ if (expdif < 0) { -+ /* optimisation? taken from the AMD docs */ -+ env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */ -+ /* ST0 is unchanged */ -+ return; -+ } -+ - if (expdif < 53) { - dblq = fpsrcop / fptemp; -- dblq = (dblq < 0.0)? ceil(dblq): floor(dblq); -+ /* round dblq towards nearest integer */ -+ dblq = rint(dblq); - ST0 = fpsrcop - fptemp*dblq; -- q = (int)dblq; /* cutting off top bits is assumed here */ -+ -+ /* convert dblq to q by truncating towards zero */ -+ if (dblq < 0.0) -+ q = (signed long long int)(-dblq); -+ else -+ q = (signed long long int)dblq; -+ - env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */ -- /* (C0,C1,C3) <-- (q2,q1,q0) */ -- env->fpus |= (q&0x4) << 6; /* (C0) <-- q2 */ -- env->fpus |= (q&0x2) << 8; /* (C1) <-- q1 */ -- env->fpus |= (q&0x1) << 14; /* (C3) <-- q0 */ -+ /* (C0,C3,C1) <-- (q2,q1,q0) */ -+ env->fpus |= (q&0x4) << (8-2); /* (C0) <-- q2 */ -+ env->fpus |= (q&0x2) << (14-1); /* (C3) <-- q1 */ -+ env->fpus |= (q&0x1) << (9-0); /* (C1) <-- q0 */ - } else { - env->fpus |= 0x400; /* C2 <-- 1 */ - fptemp = pow(2.0, expdif-50); - fpsrcop = (ST0 / ST1) / fptemp; -- /* fpsrcop = integer obtained by rounding to the nearest */ -- fpsrcop = (fpsrcop-floor(fpsrcop) < ceil(fpsrcop)-fpsrcop)? -- floor(fpsrcop): ceil(fpsrcop); -+ /* fpsrcop = integer obtained by chopping */ -+ fpsrcop = (fpsrcop < 0.0)? -+ -(floor(fabs(fpsrcop))): floor(fpsrcop); - ST0 -= (ST1 * fpsrcop * fptemp); - } - } -@@ -3157,26 +3178,48 @@ void helper_fprem(void) - CPU86_LDouble dblq, fpsrcop, fptemp; - CPU86_LDoubleU fpsrcop1, fptemp1; - int expdif; -- int q; -- -- fpsrcop = ST0; -- fptemp = ST1; -+ signed long long int q; -+ -+ if (isinf(ST0) || isnan(ST0) || isnan(ST1) || (ST1 == 0.0)) { -+ ST0 = 0.0 / 0.0; /* NaN */ -+ env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */ -+ return; -+ } -+ -+ fpsrcop = (CPU86_LDouble)ST0; -+ fptemp = (CPU86_LDouble)ST1; - fpsrcop1.d = fpsrcop; - fptemp1.d = fptemp; - expdif = EXPD(fpsrcop1) - EXPD(fptemp1); -+ -+ if (expdif < 0) { -+ /* optimisation? taken from the AMD docs */ -+ env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */ -+ /* ST0 is unchanged */ -+ return; -+ } -+ - if ( expdif < 53 ) { -- dblq = fpsrcop / fptemp; -+ dblq = fpsrcop/*ST0*/ / fptemp/*ST1*/; -+ /* round dblq towards zero */ - dblq = (dblq < 0.0)? ceil(dblq): floor(dblq); -- ST0 = fpsrcop - fptemp*dblq; -- q = (int)dblq; /* cutting off top bits is assumed here */ -+ ST0 = fpsrcop/*ST0*/ - fptemp*dblq; -+ -+ /* convert dblq to q by truncating towards zero */ -+ if (dblq < 0.0) -+ q = (signed long long int)(-dblq); -+ else -+ q = (signed long long int)dblq; -+ - env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */ -- /* (C0,C1,C3) <-- (q2,q1,q0) */ -- env->fpus |= (q&0x4) << 6; /* (C0) <-- q2 */ -- env->fpus |= (q&0x2) << 8; /* (C1) <-- q1 */ -- env->fpus |= (q&0x1) << 14; /* (C3) <-- q0 */ -+ /* (C0,C3,C1) <-- (q2,q1,q0) */ -+ env->fpus |= (q&0x4) << (8-2); /* (C0) <-- q2 */ -+ env->fpus |= (q&0x2) << (14-1); /* (C3) <-- q1 */ -+ env->fpus |= (q&0x1) << (9-0); /* (C1) <-- q0 */ - } else { -+ int N = 32 + (expdif % 32); /* as per AMD docs */ - env->fpus |= 0x400; /* C2 <-- 1 */ -- fptemp = pow(2.0, expdif-50); -+ fptemp = pow(2.0, (double)(expdif-N)); - fpsrcop = (ST0 / ST1) / fptemp; - /* fpsrcop = integer obtained by chopping */ - fpsrcop = (fpsrcop < 0.0)? diff --git a/qemu-0.9.0-futex.patch b/qemu-0.9.0-futex.patch deleted file mode 100644 index 5990228d..00000000 --- a/qemu-0.9.0-futex.patch +++ /dev/null @@ -1,114 +0,0 @@ -Index: qemu-0.9.0/linux-user/syscall.c -=================================================================== ---- qemu-0.9.0.orig/linux-user/syscall.c -+++ qemu-0.9.0/linux-user/syscall.c -@@ -2127,11 +2127,40 @@ static inline void host_to_target_timesp - unlock_user_struct(target_ts, target_addr, 1); - } - -+#ifdef BSWAP_NEEDED -+static int futex_op(int oldval, int op, int oparg) -+{ -+ int retval = oparg; -+ switch(op) { -+ case FUTEX_OP_SET: break; -+ case FUTEX_OP_ADD: retval += oparg; break; -+ case FUTEX_OP_OR: retval |= oparg; break; -+ case FUTEX_OP_ANDN: retval &= oparg; break; -+ case FUTEX_OP_XOR: retval ^= oparg; break; -+ } -+ return retval; -+} -+ -+static int futex_cmp(int oldval, int cmp, int cmparg) -+{ -+ switch(cmp) { -+ case FUTEX_OP_CMP_EQ: return oldval == cmparg; -+ case FUTEX_OP_CMP_NE: return oldval != cmparg; -+ case FUTEX_OP_CMP_LT: return oldval < cmparg; -+ case FUTEX_OP_CMP_LE: return oldval <= cmparg; -+ case FUTEX_OP_CMP_GT: return oldval > cmparg; -+ case FUTEX_OP_CMP_GE: return oldval >= cmparg; -+ } -+ return -1; -+} -+#endif -+ - static long do_futex(target_ulong uaddr, int op, uint32_t val, - target_ulong utime, target_ulong uaddr2, - uint32_t val3) - { - struct timespec host_utime; - unsigned long val2 = utime; -+ long retval; - - if (utime && (op == FUTEX_WAIT || op == FUTEX_LOCK_PI)) { -@@ -2141,6 +2170,7 @@ static long do_futex(target_ulong uaddr, - } - - #ifdef BSWAP_NEEDED -+// if( op == FUTEX_WAKE_OP ) { gemu_log("FUTEX_WAKE_OP -> FUTEX_WAKE\n"); op = FUTEX_WAKE; sleep(1); } - switch(op) { - case FUTEX_CMP_REQUEUE: - val3 = tswap32(val3); -@@ -2148,41 +2178,40 @@ static long do_futex(target_ulong uaddr, - val2 = tswap32(val2); - case FUTEX_WAIT: - case FUTEX_WAKE: -+ case FUTEX_WAKE_OP: - val = tswap32(val); - case FUTEX_LOCK_PI: /* This one's icky, but comes out OK */ - case FUTEX_UNLOCK_PI: - break; - default: - gemu_log("qemu: Unsupported futex op %d\n", op); -+ spin_unlock(&mmap_lock); - return -ENOSYS; - } --#if 0 /* No, it's worse than this */ - if (op == FUTEX_WAKE_OP) { - /* Need to munge the secondary operation (val3) */ - val3 = tswap32(val3); -- int op2 = (val3 >> 28) & 7; -- int cmp = (val3 >> 24) & 15; -- int oparg = (val3 << 8) >> 20; -- int cmparg = (val3 << 20) >> 20; -+ int op2 = (val3 >> 28) & 0xf; -+ int cmp = (val3 >> 24) & 0xf; -+ int oparg = (val3 >> 12) & 0xfff; -+ int cmparg = val3 & 0xfff; - int shift = val3 & (FUTEX_OP_OPARG_SHIFT << 28); -- -+ int oldval = tget32(uaddr2); - if (shift) -- oparg = (oparg & 7) + 24 - (oparg & 24); -- else oparg = -- if (op2 == FUTEX_OP_ADD) { -- gemu_log("qemu: Unsupported wrong-endian FUTEX_OP_ADD\n"); -- return -ENOSYS; -- } -- if (cmparg == FUTEX_OP_CMP_LT || cmparg == FUTEX_OP_CMP_GE || -- cmparg == FUTEX_OP_CMP_LE || cmparg == FUTEX_OP_CMP_GT) { -- gemu_log("qemu: Unsupported wrong-endian futex cmparg %d\n", cmparg); -- return -ENOSYS; -- } -- val3 = shift | (op2<<28) | (cmp<<24) | (oparg<<12) | cmparg; -+ oparg = 1 << oparg; -+ -+ tput32(uaddr2,futex_op(oldval, op2, oparg)); -+ retval = syscall(__NR_futex, g2h(uaddr), FUTEX_WAKE, val, 0, 0, 0); -+ if(futex_cmp(oldval, cmp, cmparg)) { -+ retval = syscall(__NR_futex, g2h(uaddr2), FUTEX_WAKE, val2, 0, 0, 0); -+ } -+ } else { -+ retval = syscall(__NR_futex, g2h(uaddr), op, val, val2, g2h(uaddr2), val3); - } --#endif -+#else -+ retval = syscall(__NR_futex, g2h(uaddr), op, val, val2, g2h(uaddr2), val3); - #endif -- return syscall(__NR_futex, g2h(uaddr), op, val, val2, g2h(uaddr2), val3); -+ return retval; - } - - int do_set_tid_address(target_ulong tidptr) diff --git a/qemu-0.9.0-initrd.patch b/qemu-0.9.0-initrd.patch deleted file mode 100644 index 2995e7dc..00000000 --- a/qemu-0.9.0-initrd.patch +++ /dev/null @@ -1,64 +0,0 @@ -Index: qemu-0.9.0/hw/pc.c -=================================================================== ---- qemu-0.9.0.orig/hw/pc.c -+++ qemu-0.9.0/hw/pc.c -@@ -32,9 +32,11 @@ - #define LINUX_BOOT_FILENAME "linux_boot.bin" - - #define KERNEL_LOAD_ADDR 0x00100000 --#define INITRD_LOAD_ADDR 0x00600000 -+#define MAX_INITRD_LOAD_ADDR 0x38000000 - #define KERNEL_PARAMS_ADDR 0x00090000 - #define KERNEL_CMDLINE_ADDR 0x00099000 -+/* Leave a chunk of memory at the top of RAM for the BIOS ACPI tables. */ -+#define ACPI_DATA_SIZE 0x10000 - - static fdctrl_t *floppy_controller; - static RTCState *rtc_state; -@@ -452,6 +454,7 @@ static void pc_init1(int ram_size, int v - char buf[1024]; - int ret, linux_boot, initrd_size, i; - unsigned long bios_offset, vga_bios_offset, option_rom_offset; -+ unsigned long initrd_offset; - int bios_size, isa_bios_size; - PCIBus *pci_bus; - int piix3_devfn = -1; -@@ -576,8 +579,28 @@ static void pc_init1(int ram_size, int v - - /* load initrd */ - initrd_size = 0; -+ initrd_offset = 0; - if (initrd_filename) { -- initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR); -+ initrd_size = get_image_size (initrd_filename); -+ if (initrd_size > 0) { -+ initrd_offset = (ram_size - initrd_size) & TARGET_PAGE_MASK; -+ /* Leave space for BIOS ACPI tables. */ -+ initrd_offset -= ACPI_DATA_SIZE; -+ /* Avoid the last 64k to avoid 2.2.x kernel bugs. */ -+ initrd_offset -= 0x10000; -+ if (initrd_offset > MAX_INITRD_LOAD_ADDR) -+ initrd_offset = MAX_INITRD_LOAD_ADDR; -+ -+ if (initrd_size > ram_size -+ || initrd_offset < KERNEL_LOAD_ADDR + ret) { -+ fprintf(stderr, -+ "qemu: memory too small for initial ram disk '%s'\n", -+ initrd_filename); -+ exit(1); -+ } -+ initrd_size = load_image(initrd_filename, -+ phys_ram_base + initrd_offset); -+ } - if (initrd_size < 0) { - fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", - initrd_filename); -@@ -585,7 +608,7 @@ static void pc_init1(int ram_size, int v - } - } - if (initrd_size > 0) { -- stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x218, INITRD_LOAD_ADDR); -+ stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x218, initrd_offset); - stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x21c, initrd_size); - } - pstrcpy(phys_ram_base + KERNEL_CMDLINE_ADDR, 4096, diff --git a/qemu-0.9.0-kernel-option-vga.patch b/qemu-0.9.0-kernel-option-vga.patch deleted file mode 100644 index b9e60778..00000000 --- a/qemu-0.9.0-kernel-option-vga.patch +++ /dev/null @@ -1,36 +0,0 @@ ---- qemu-0.9.0/hw/pc.c.kernel-option-vga 2007-02-13 14:41:12.000000000 +0100 -+++ qemu-0.9.0/hw/pc.c 2007-02-14 17:01:57.000000000 +0100 -@@ -567,6 +567,7 @@ static void pc_init1(int ram_size, int v - if (linux_boot) { - uint8_t bootsect[512]; - uint8_t old_bootsect[512]; -+ char *vmode; - - if (bs_table[0] == NULL) { - fprintf(stderr, "A disk image must be given for 'hda' when booting a Linux kernel\n"); -@@ -618,6 +619,25 @@ static void pc_init1(int ram_size, int v - KERNEL_CMDLINE_ADDR - KERNEL_PARAMS_ADDR); - /* loader type */ - stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x210, 0x01); -+ -+ /* handle vga= parameter */ -+ vmode = strstr(kernel_cmdline, "vga="); -+ if (vmode) { -+ char *space; -+ unsigned int video_mode; -+ /* skip "vga=" */ -+ vmode += 4; -+ if (!strncmp(vmode, "normal", 6)) { -+ video_mode = 0xffff; -+ } else if (!strncmp(vmode, "ext", 3)) { -+ video_mode = 0xfffe; -+ } else if (!strncmp(vmode, "ask", 3)) { -+ video_mode = 0xfffd; -+ } else { -+ video_mode = strtol(vmode, NULL, 0); -+ } -+ stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x1fa, video_mode); -+ } - } - - if (pci_enabled) { diff --git a/qemu-0.9.0-mmap.patch b/qemu-0.9.0-mmap.patch deleted file mode 100644 index e7ead357..00000000 --- a/qemu-0.9.0-mmap.patch +++ /dev/null @@ -1,203 +0,0 @@ -Index: qemu-0.9.0/linux-user/syscall.c -=================================================================== ---- qemu-0.9.0.orig/linux-user/syscall.c -+++ qemu-0.9.0/linux-user/syscall.c -@@ -185,6 +185,9 @@ extern int getresgid(gid_t *, gid_t *, g - extern int setgroups(int, gid_t *); - extern int uselib(const char*); - -+#include "exec-all.h" -+long mmap_lock; -+ - static inline long get_errno(long ret) - { - if (ret == -1) -@@ -227,9 +235,11 @@ long do_brk(target_ulong new_brk) - - /* We need to allocate more memory after the brk... */ - new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1); -+ spin_lock(&mmap_lock); - mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size, - PROT_READ|PROT_WRITE, - MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0)); -+ spin_unlock(&mmap_lock); - if (is_error(mapped_addr)) { - return mapped_addr; - } else { -@@ -2985,15 +3021,19 @@ long do_syscall(void *cpu_env, int num, - v5 = tswapl(v[4]); - v6 = tswapl(v[5]); - unlock_user(v, arg1, 0); -+ spin_lock(&mmap_lock); - ret = get_errno(target_mmap(v1, v2, v3, - target_to_host_bitmask(v4, mmap_flags_tbl), - v5, v6)); -+ spin_unlock(&mmap_lock); - } - #else -+ spin_lock(&mmap_lock); - ret = get_errno(target_mmap(arg1, arg2, arg3, - target_to_host_bitmask(arg4, mmap_flags_tbl), - arg5, - arg6)); -+ spin_unlock(&mmap_lock); - #endif - break; - #ifdef TARGET_NR_mmap2 -@@ -3003,36 +3043,54 @@ long do_syscall(void *cpu_env, int num, - #else - #define MMAP_SHIFT TARGET_PAGE_BITS - #endif -+ spin_lock(&mmap_lock); - ret = get_errno(target_mmap(arg1, arg2, arg3, - target_to_host_bitmask(arg4, mmap_flags_tbl), - arg5, - arg6 << MMAP_SHIFT)); -+ spin_unlock(&mmap_lock); - break; - #endif - case TARGET_NR_munmap: -+ spin_lock(&mmap_lock); - ret = get_errno(target_munmap(arg1, arg2)); -+ spin_unlock(&mmap_lock); - break; - case TARGET_NR_mprotect: -+ spin_lock(&mmap_lock); - ret = get_errno(target_mprotect(arg1, arg2, arg3)); -+ spin_unlock(&mmap_lock); - break; - case TARGET_NR_mremap: -+ spin_lock(&mmap_lock); - ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5)); -+ spin_unlock(&mmap_lock); - break; - /* ??? msync/mlock/munlock are broken for softmmu. */ - case TARGET_NR_msync: -+ spin_lock(&mmap_lock); - ret = get_errno(msync(g2h(arg1), arg2, arg3)); -+ spin_unlock(&mmap_lock); - break; - case TARGET_NR_mlock: -+ spin_lock(&mmap_lock); - ret = get_errno(mlock(g2h(arg1), arg2)); -+ spin_unlock(&mmap_lock); - break; - case TARGET_NR_munlock: -+ spin_lock(&mmap_lock); - ret = get_errno(munlock(g2h(arg1), arg2)); -+ spin_unlock(&mmap_lock); - break; - case TARGET_NR_mlockall: -+ spin_lock(&mmap_lock); - ret = get_errno(mlockall(arg1)); -+ spin_unlock(&mmap_lock); - break; - case TARGET_NR_munlockall: -+ spin_lock(&mmap_lock); - ret = get_errno(munlockall()); -+ spin_unlock(&mmap_lock); - break; - case TARGET_NR_truncate: - p = lock_user_string(arg1); -Index: qemu-0.9.0/exec.c -=================================================================== ---- qemu-0.9.0.orig/exec.c -+++ qemu-0.9.0/exec.c -@@ -1676,6 +1684,50 @@ void page_dump(FILE *f) - } - } - -+/* dump memory mappings */ -+target_ulong page_find_end() -+{ -+ unsigned long start, end; -+ int i, j, prot, prot1; -+ void *firsttb; -+ PageDesc *p; -+ target_ulong last = 0; -+ -+ start = -1; -+ end = -1; -+ prot = 0; -+ for(i = 0; i <= L1_SIZE; i++) { -+ if (i < L1_SIZE) -+ p = l1_map[i]; -+ else -+ p = NULL; -+ for(j = 0;j < L2_SIZE; j++) { -+ if (!p) { -+ firsttb = NULL; -+ prot1 = 0; -+ } -+ else { -+ prot1 = p[j].flags; -+ firsttb = p[j].first_tb; -+ } -+ if (prot1 != prot) { -+ end = (i << (32 - L1_BITS)) | (j << TARGET_PAGE_BITS); -+ if (start != -1) { -+ last = end; -+ } -+ if (prot1 != 0) -+ start = end; -+ else -+ start = -1; -+ prot = prot1; -+ } -+ if (!p) -+ break; -+ } -+ } -+ return last; -+} -+ - int page_get_flags(target_ulong address) - { - PageDesc *p; -Index: qemu-0.9.0/linux-user/mmap.c -=================================================================== ---- qemu-0.9.0.orig/linux-user/mmap.c -+++ qemu-0.9.0/linux-user/mmap.c -@@ -48,8 +48,14 @@ int target_mprotect(target_ulong start, - end = start + len; - if (end < start) - return -EINVAL; -- if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC)) -- return -EINVAL; -+ if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC)) { -+#ifdef DEBUG_MMAP -+ gemu_log("mprotect: ERROR (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC)\n"); -+#endif -+ // dirty hack to get mplayer running (sets PROT_GROWSDOWN) we just ignore advanced flags -+ prot &= (PROT_READ | PROT_WRITE | PROT_EXEC); -+// return -EINVAL; -+ } - if (len == 0) - return 0; - -@@ -205,9 +233,23 @@ long target_mmap(target_ulong start, tar - defined(__ia64) || defined(__CYGWIN__) - /* tell the kenel to search at the same place as i386 */ - if (real_start == 0) { -- real_start = last_start; -- last_start += HOST_PAGE_ALIGN(len); -+ target_ulong curend = page_find_end(); -+ -+ if(curend > last_start) { -+#ifdef DEBUG_MMAP -+ gemu_log("qemu: set last_start from %p to %p\n", last_start, curend + HOST_PAGE_ALIGN(len)); fflush(stdout); fflush(stderr); -+#endif -+ last_start = curend; -+#ifdef DEBUG_MMAP -+ } else { -+ gemu_log("qemu: curend(%p) <= last_start(%p)\n", curend, last_start); fflush(stdout); fflush(stderr); -+#endif -+ } -+ -+ real_start = last_start; -+ last_start += HOST_PAGE_ALIGN(len); - } -+ - #endif - if (0 && qemu_host_page_size != qemu_real_host_page_size) { - /* NOTE: this code is only for debugging with '-p' option */ diff --git a/qemu-0.9.0-nonetlink.patch b/qemu-0.9.0-nonetlink.patch deleted file mode 100644 index d07ef07e..00000000 --- a/qemu-0.9.0-nonetlink.patch +++ /dev/null @@ -1,12 +0,0 @@ -Index: qemu-0.9.0/linux-user/syscall.c -=================================================================== ---- qemu-0.9.0.orig/linux-user/syscall.c -+++ qemu-0.9.0/linux-user/syscall.c -@@ -791,6 +791,7 @@ static long do_socket(int domain, int ty - break; - } - #endif -+ if(domain == PF_NETLINK) return -EAFNOSUPPORT; - return get_errno(socket(domain, type, protocol)); - } - diff --git a/qemu-0.9.0-nptl.patch b/qemu-0.9.0-nptl.patch deleted file mode 100644 index 858c3f61..00000000 --- a/qemu-0.9.0-nptl.patch +++ /dev/null @@ -1,300 +0,0 @@ -Index: qemu-0.9.0/linux-user/main.c -=================================================================== ---- qemu-0.9.0.orig/linux-user/main.c -+++ qemu-0.9.0/linux-user/main.c -@@ -156,7 +156,7 @@ static void set_gate(void *ptr, unsigned - p[1] = tswapl(e2); - } - --uint64_t gdt_table[6]; -+uint64_t gdt_table[9]; - uint64_t idt_table[256]; - - /* only dpl matters as we do only user space emulation */ -@@ -1604,7 +1604,11 @@ int main(int argc, char **argv) - int optind; - const char *r; - int gdbstub_port = 0; -- -+ char *assume_kernel = getenv("QEMU_ASSUME_KERNEL"); -+ -+ if (assume_kernel) -+ setenv("LD_ASSUME_KERNEL", assume_kernel, 1); -+ - if (argc <= 1) - usage(); - -Index: qemu-0.9.0/linux-user/syscall.c -=================================================================== ---- qemu-0.9.0.orig/linux-user/syscall.c -+++ qemu-0.9.0/linux-user/syscall.c -@@ -17,6 +17,8 @@ - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -+ -+#define __user - #include - #include - #include -@@ -57,6 +59,7 @@ - #define tchars host_tchars /* same as target */ - #define ltchars host_ltchars /* same as target */ - -+#include - #include - #include - #include -@@ -1690,6 +1693,80 @@ int do_modify_ldt(CPUX86State *env, int - return ret; - } - -+int do_set_thread_area(CPUX86State *env, target_ulong ptr) -+{ -+ uint64_t *gdt_table = g2h(env->gdt.base); -+ struct target_modify_ldt_ldt_s ldt_info; -+ struct target_modify_ldt_ldt_s *target_ldt_info; -+ int seg_32bit, contents, read_exec_only, limit_in_pages; -+ int seg_not_present, useable; -+ uint32_t *lp, entry_1, entry_2; -+ int i; -+ -+ lock_user_struct(target_ldt_info, ptr, 1); -+ ldt_info.entry_number = tswap32(target_ldt_info->entry_number); -+ ldt_info.base_addr = tswapl(target_ldt_info->base_addr); -+ ldt_info.limit = tswap32(target_ldt_info->limit); -+ ldt_info.flags = tswap32(target_ldt_info->flags); -+ if (ldt_info.entry_number == -1) { -+ for (i=6; i<8; i++) -+ if (gdt_table[i] == 0) { -+ ldt_info.entry_number = i; -+ target_ldt_info->entry_number = tswap32(i); -+ break; -+ } -+ } -+ unlock_user_struct(target_ldt_info, ptr, 0); -+ -+ if (ldt_info.entry_number < 6 || ldt_info.entry_number > 8) -+ return -EINVAL; -+ seg_32bit = ldt_info.flags & 1; -+ contents = (ldt_info.flags >> 1) & 3; -+ read_exec_only = (ldt_info.flags >> 3) & 1; -+ limit_in_pages = (ldt_info.flags >> 4) & 1; -+ seg_not_present = (ldt_info.flags >> 5) & 1; -+ useable = (ldt_info.flags >> 6) & 1; -+ -+ if (contents == 3) { -+ if (seg_not_present == 0) -+ return -EINVAL; -+ } -+ -+ /* NOTE: same code as Linux kernel */ -+ /* Allow LDTs to be cleared by the user. */ -+ if (ldt_info.base_addr == 0 && ldt_info.limit == 0) { -+ if ((contents == 0 && -+ read_exec_only == 1 && -+ seg_32bit == 0 && -+ limit_in_pages == 0 && -+ seg_not_present == 1 && -+ useable == 0 )) { -+ entry_1 = 0; -+ entry_2 = 0; -+ goto install; -+ } -+ } -+ -+ entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) | -+ (ldt_info.limit & 0x0ffff); -+ entry_2 = (ldt_info.base_addr & 0xff000000) | -+ ((ldt_info.base_addr & 0x00ff0000) >> 16) | -+ (ldt_info.limit & 0xf0000) | -+ ((read_exec_only ^ 1) << 9) | -+ (contents << 10) | -+ ((seg_not_present ^ 1) << 15) | -+ (seg_32bit << 22) | -+ (limit_in_pages << 23) | -+ (useable << 20) | -+ 0x7000; -+ -+ /* Install the new entry ... */ -+install: -+ lp = (uint32_t *)(gdt_table + ldt_info.entry_number); -+ lp[0] = tswap32(entry_1); -+ lp[1] = tswap32(entry_2); -+ return 0; -+} - #endif /* defined(TARGET_I386) */ - - /* this stack is the equivalent of the kernel stack associated with a -@@ -1710,9 +1787,13 @@ int do_fork(CPUState *env, unsigned int - TaskState *ts; - uint8_t *new_stack; - CPUState *new_env; -- -+#if defined(TARGET_I386) -+ uint64_t *new_gdt_table; -+#endif - if (flags & CLONE_VM) { - ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE); -+ if (!ts) -+ return -ENOMEM; - memset(ts, 0, sizeof(TaskState)); - new_stack = ts->stack; - ts->used = 1; -@@ -1725,6 +1807,29 @@ int do_fork(CPUState *env, unsigned int - #if defined(TARGET_I386) - if (!newsp) - newsp = env->regs[R_ESP]; -+ new_gdt_table = malloc(9 * 8); -+ if (!new_gdt_table) { -+ free(new_env); -+ return -ENOMEM; -+ } -+ /* Copy main GDT table from parent, but clear TLS entries */ -+ memcpy(new_gdt_table, g2h(env->gdt.base), 6 * 8); -+ memset(&new_gdt_table[6], 0, 3 * 8); -+ new_env->gdt.base = h2g(new_gdt_table); -+ if (flags & 0x00080000 /* CLONE_SETTLS */) { -+ ret = do_set_thread_area(new_env, new_env->regs[R_ESI]); -+ if (ret) { -+ free(new_gdt_table); -+ free(new_env); -+ return ret; -+ } -+ } -+ cpu_x86_load_seg(env, R_CS, new_env->regs[R_CS]); -+ cpu_x86_load_seg(env, R_DS, new_env->regs[R_DS]); -+ cpu_x86_load_seg(env, R_ES, new_env->regs[R_ES]); -+ cpu_x86_load_seg(env, R_SS, new_env->regs[R_SS]); -+ cpu_x86_load_seg(env, R_FS, new_env->regs[R_FS]); -+ cpu_x86_load_seg(env, R_GS, new_env->regs[R_GS]); - new_env->regs[R_ESP] = newsp; - new_env->regs[R_EAX] = 0; - #elif defined(TARGET_ARM) -@@ -1991,6 +2096,68 @@ static inline void host_to_target_timesp - unlock_user_struct(target_ts, target_addr, 1); - } - -+static long do_futex(target_ulong uaddr, int op, uint32_t val, -+ target_ulong utime, target_ulong uaddr2, -+ uint32_t val3) -+{ -+ struct timespec host_utime; -+ unsigned long val2 = utime; -+ -+ if (utime && (op == FUTEX_WAIT || op == FUTEX_LOCK_PI)) { -+ target_to_host_timespec(&host_utime, utime); -+ val2 = (unsigned long)&host_utime; -+ } -+ -+#ifdef BSWAP_NEEDED -+ switch(op) { -+ case FUTEX_CMP_REQUEUE: -+ val3 = tswap32(val3); -+ case FUTEX_REQUEUE: -+ val2 = tswap32(val2); -+ case FUTEX_WAIT: -+ case FUTEX_WAKE: -+ val = tswap32(val); -+ case FUTEX_LOCK_PI: /* This one's icky, but comes out OK */ -+ case FUTEX_UNLOCK_PI: -+ break; -+ default: -+ gemu_log("qemu: Unsupported futex op %d\n", op); -+ return -ENOSYS; -+ } -+#if 0 /* No, it's worse than this */ -+ if (op == FUTEX_WAKE_OP) { -+ /* Need to munge the secondary operation (val3) */ -+ val3 = tswap32(val3); -+ int op2 = (val3 >> 28) & 7; -+ int cmp = (val3 >> 24) & 15; -+ int oparg = (val3 << 8) >> 20; -+ int cmparg = (val3 << 20) >> 20; -+ int shift = val3 & (FUTEX_OP_OPARG_SHIFT << 28); -+ -+ if (shift) -+ oparg = (oparg & 7) + 24 - (oparg & 24); -+ else oparg = -+ if (op2 == FUTEX_OP_ADD) { -+ gemu_log("qemu: Unsupported wrong-endian FUTEX_OP_ADD\n"); -+ return -ENOSYS; -+ } -+ if (cmparg == FUTEX_OP_CMP_LT || cmparg == FUTEX_OP_CMP_GE || -+ cmparg == FUTEX_OP_CMP_LE || cmparg == FUTEX_OP_CMP_GT) { -+ gemu_log("qemu: Unsupported wrong-endian futex cmparg %d\n", cmparg); -+ return -ENOSYS; -+ } -+ val3 = shift | (op2<<28) | (cmp<<24) | (oparg<<12) | cmparg; -+ } -+#endif -+#endif -+ return syscall(__NR_futex, g2h(uaddr), op, val, val2, g2h(uaddr2), val3); -+} -+ -+int do_set_tid_address(target_ulong tidptr) -+{ -+ return syscall(__NR_set_tid_address, g2h(tidptr)); -+} -+ - long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, - long arg4, long arg5, long arg6) - { -@@ -2008,7 +2175,7 @@ long do_syscall(void *cpu_env, int num, - _mcleanup(); - #endif - gdb_exit(cpu_env, arg1); -- /* XXX: should free thread stack and CPU env */ -+ /* XXX: should free thread stack, GDT and CPU env */ - _exit(arg1); - ret = 0; /* avoid warning */ - break; -@@ -3153,6 +3320,9 @@ long do_syscall(void *cpu_env, int num, - case TARGET_NR_vm86: - ret = do_vm86(cpu_env, arg1, arg2); - break; -+ case TARGET_NR_set_thread_area: -+ ret = get_errno(do_set_thread_area(cpu_env, arg1)); -+ break; - #endif - case TARGET_NR_adjtimex: - goto unimplemented; -@@ -3947,15 +4117,24 @@ long do_syscall(void *cpu_env, int num, - case TARGET_NR_fremovexattr: - goto unimplemented_nowarn; - #endif --#ifdef TARGET_NR_set_thread_area -- case TARGET_NR_set_thread_area: -- case TARGET_NR_get_thread_area: -- goto unimplemented_nowarn; --#endif - #ifdef TARGET_NR_getdomainname - case TARGET_NR_getdomainname: - goto unimplemented_nowarn; - #endif -+#ifdef TARGET_NR_futex -+ case TARGET_NR_futex: -+ ret = get_errno(do_futex(arg1, arg2, arg3, arg4, arg5, arg6)); -+ break; -+#endif -+#ifdef TARGET_NR_set_tid_address -+ case TARGET_NR_set_tid_address: -+ ret = get_errno(do_set_tid_address(arg1)); -+ break; -+#endif -+#ifdef TARGET_NR_set_robust_list -+ case TARGET_NR_set_robust_list: -+ goto unimplemented_nowarn; -+#endif - #ifdef TARGET_NR_clock_gettime - case TARGET_NR_clock_gettime: - { -@@ -3975,7 +4154,7 @@ long do_syscall(void *cpu_env, int num, - default: - unimplemented: - gemu_log("qemu: Unsupported syscall: %d\n", num); --#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_set_thread_area) || defined(TARGET_NR_getdomainname) -+#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_set_thread_area) || defined(TARGET_NR_set_robust_list) || defined(TARGET_NR_getdomainname) - unimplemented_nowarn: - #endif - ret = -ENOSYS; diff --git a/qemu-0.9.0-nptl2.patch b/qemu-0.9.0-nptl2.patch deleted file mode 100644 index a49fc959..00000000 --- a/qemu-0.9.0-nptl2.patch +++ /dev/null @@ -1,219 +0,0 @@ -Index: qemu-0.9.0/linux-user/i386/syscall_nr.h -=================================================================== ---- qemu-0.9.0.orig/linux-user/i386/syscall_nr.h -+++ qemu-0.9.0/linux-user/i386/syscall_nr.h -@@ -271,5 +271,6 @@ - #define TARGET_NR_clock_getres (TARGET_NR_timer_create+7) - #define TARGET_NR_clock_nanosleep (TARGET_NR_timer_create+8) - -+#define TARGET_NR_tgkill 270 - #define TARGET_NR_utimes 271 - #define TARGET_NR_fadvise64_64 272 -Index: qemu-0.9.0/linux-user/syscall.c -=================================================================== ---- qemu-0.9.0.orig/linux-user/syscall.c -+++ qemu-0.9.0/linux-user/syscall.c -@@ -145,6 +145,8 @@ type name (type1 arg1,type2 arg2,type3 a - #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo - #define __NR_sys_syslog __NR_syslog - #define __NR_sys_fadvise64 __NR_fadvise64 -+#define __NR_sys_tgkill __NR_tgkill -+#define __NR_sys_clone __NR_clone - - #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__) - #define __NR__llseek __NR_lseek -@@ -166,6 +168,8 @@ _syscall5(int, _llseek, uint, fd, ulon - _syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo) - _syscall3(int,sys_syslog,int,type,char*,bufp,int,len) - _syscall4(int,sys_fadvise64,int,fd,loff_t,offset,loff_t,len,int,advice) -+_syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig) -+_syscall5(int,sys_clone, int, flags, void *, child_stack, int *, parent_tidptr, struct user_desc *, newtls, int *, child_tidptr) - #ifdef __NR_exit_group - _syscall1(int,exit_group,int,error_code) - #endif -@@ -1699,7 +1704,7 @@ int do_modify_ldt(CPUX86State *env, int - return ret; - } - --int do_set_thread_area(CPUX86State *env, target_ulong ptr) -+int do_set_thread_area(CPUX86State *env, target_ulong ptr, int set_shadow_registers) - { - uint64_t *gdt_table = g2h(env->gdt.base); - struct target_modify_ldt_ldt_s ldt_info; -@@ -1708,6 +1713,7 @@ int do_set_thread_area(CPUX86State *env, - int seg_not_present, useable; - uint32_t *lp, entry_1, entry_2; - int i; -+ SegmentCache *sc = &env->segs[R_GS]; - - lock_user_struct(target_ldt_info, ptr, 1); - ldt_info.entry_number = tswap32(target_ldt_info->entry_number); -@@ -1767,6 +1767,12 @@ int do_set_thread_area(CPUX86State *env, - (useable << 20) | - 0x7000; - -+ if(set_shadow_registers) { -+ sc->selector = env->regs[R_GS]; -+ sc->base = ldt_info.base_addr; -+ sc->limit = ldt_info.limit; -+ sc->flags = entry_2; -+ } - /* Install the new entry ... */ - install: - lp = (uint32_t *)(gdt_table + ldt_info.entry_number); -@@ -1779,20 +1802,21 @@ install: - thread/process */ - #define NEW_STACK_SIZE 8192 - --static int clone_func(void *arg) -+static int clone_func(CPUState *cloneenv) - { -- CPUState *env = arg; -- cpu_loop(env); -+ cpu_loop(cloneenv); - /* never exits */ - return 0; - } - --int do_fork(CPUState *env, unsigned int flags, unsigned long newsp) -+int do_fork(CPUState *env, unsigned int flags, target_ulong newsp, target_ulong parent_tidptr, target_ulong newtls, target_ulong child_tidptr) - { - int ret; -+ int cpu_index; -+ unsigned long parent_tid=gettid(); - TaskState *ts; - uint8_t *new_stack; -- CPUState *new_env; -+ CPUState *new_env, *next_cpu; - #if defined(TARGET_I386) - uint64_t *new_gdt_table; - #endif -@@ -1807,9 +1835,14 @@ int do_fork(CPUState *env, unsigned int - /* add in task state list */ - ts->next = first_task_state; - first_task_state = ts; -- /* we create a new CPU instance. */ -- new_env = cpu_init(); -- memcpy(new_env, env, sizeof(CPUState)); -+ /* we create a new CPU instance. (cpu_copy() in cvs) */ -+ new_env = cpu_init(); -+ /* preserve chaining and index */ -+ next_cpu = new_env->next_cpu; -+ cpu_index = new_env->cpu_index; -+ memcpy(new_env, env, sizeof(CPUState)); -+ new_env->next_cpu = next_cpu; -+ new_env->cpu_index = cpu_index; - #if defined(TARGET_I386) - if (!newsp) - newsp = env->regs[R_ESP]; -@@ -1818,26 +1851,20 @@ int do_fork(CPUState *env, unsigned int - free(new_env); - return -ENOMEM; - } - /* Copy main GDT table from parent, but clear TLS entries */ - memcpy(new_gdt_table, g2h(env->gdt.base), 6 * 8); - memset(&new_gdt_table[6], 0, 3 * 8); - new_env->gdt.base = h2g(new_gdt_table); -- if (flags & 0x00080000 /* CLONE_SETTLS */) { -- ret = do_set_thread_area(new_env, new_env->regs[R_ESI]); -+ if (flags & CLONE_SETTLS) { -+ ret = do_set_thread_area(new_env, newtls, 1); - if (ret) { - free(new_gdt_table); - free(new_env); - return ret; - } - } -- cpu_x86_load_seg(env, R_CS, new_env->regs[R_CS]); -- cpu_x86_load_seg(env, R_DS, new_env->regs[R_DS]); -- cpu_x86_load_seg(env, R_ES, new_env->regs[R_ES]); -- cpu_x86_load_seg(env, R_SS, new_env->regs[R_SS]); -- cpu_x86_load_seg(env, R_FS, new_env->regs[R_FS]); -- cpu_x86_load_seg(env, R_GS, new_env->regs[R_GS]); - new_env->regs[R_ESP] = newsp; - new_env->regs[R_EAX] = 0; - #elif defined(TARGET_ARM) - if (!newsp) - newsp = env->regs[13]; -@@ -1877,16 +1933,28 @@ int do_fork(CPUState *env, unsigned int - #endif - new_env->opaque = ts; - #ifdef __ia64__ -- ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env); -+ ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags & ~(CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID), new_env); - #else -- ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env); -+ ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags & ~(CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID), new_env); - #endif - } else { - /* if no CLONE_VM, we consider it is a fork */ -- if ((flags & ~CSIGNAL) != 0) -- return -EINVAL; -- ret = fork(); -+ ret = sys_clone(flags & ~(CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID), 0, g2h(parent_tidptr), NULL, g2h(child_tidptr)); -+ } -+ /* Store child thread ID at location parent_tidptr in parent and child memory. -+ Currently this is only done in client memory*/ -+ if(flags & CLONE_PARENT_SETTID) { -+ tput32(parent_tidptr, parent_tid); -+ } -+ -+ /* Store child thread ID at location child_tidptr in child memory. */ -+ if(flags & CLONE_CHILD_SETTID) { -+ if(ret==0) { // only in client memory for fork() -+ tput32(child_tidptr, gettid()); -+ } else if(flags & CLONE_VM) { // real threads need it too -+ tput32(child_tidptr, ret); -+ } - } - return ret; - } - -@@ -2206,7 +2221,7 @@ long do_syscall(void *cpu_env, int num, - ret = do_brk(arg1); - break; - case TARGET_NR_fork: -- ret = get_errno(do_fork(cpu_env, SIGCHLD, 0)); -+ ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0,0,0)); - break; - case TARGET_NR_waitpid: - { -@@ -3281,7 +3297,7 @@ long do_syscall(void *cpu_env, int num, - ret = get_errno(fsync(arg1)); - break; - case TARGET_NR_clone: -- ret = get_errno(do_fork(cpu_env, arg1, arg2)); -+ ret = get_errno(do_fork(cpu_env, arg1, arg2,arg3,arg4,arg5)); - break; - #ifdef __NR_exit_group - /* new thread calls */ -@@ -3339,7 +3397,7 @@ long do_syscall(void *cpu_env, int num, - ret = do_vm86(cpu_env, arg1, arg2); - break; - case TARGET_NR_set_thread_area: -- ret = get_errno(do_set_thread_area(cpu_env, arg1)); -+ ret = get_errno(do_set_thread_area(cpu_env, arg1, 0)); - break; - #endif - case TARGET_NR_adjtimex: -@@ -3635,7 +3651,7 @@ long do_syscall(void *cpu_env, int num, - #endif - #ifdef TARGET_NR_vfork - case TARGET_NR_vfork: -- ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD, 0)); -+ ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD, 0, 0,0,0)); - break; - #endif - #ifdef TARGET_NR_ugetrlimit -@@ -4164,6 +4180,11 @@ long do_syscall(void *cpu_env, int num, - ret = get_errno(sys_fadvise64((int)arg1, arg2, arg3, (int)arg4)); - break; - #endif -+#ifdef TARGET_NR_tgkill -+ case TARGET_NR_tgkill: -+ ret = get_errno(sys_tgkill((int)arg1, (int)arg2, (int)arg3)); -+ break; -+#endif - default: - unimplemented: - gemu_log("qemu: Unsupported syscall: %d\n", num); diff --git a/qemu-0.9.0-robust_list.patch b/qemu-0.9.0-robust_list.patch deleted file mode 100644 index 4de83e0d..00000000 --- a/qemu-0.9.0-robust_list.patch +++ /dev/null @@ -1,10 +0,0 @@ -Index: qemu-0.9.0/linux-user/i386/syscall_nr.h -=================================================================== ---- qemu-0.9.0.orig/linux-user/i386/syscall_nr.h -+++ qemu-0.9.0/linux-user/i386/syscall_nr.h -@@ -274,3 +274,5 @@ - #define TARGET_NR_tgkill 270 - #define TARGET_NR_utimes 271 - #define TARGET_NR_fadvise64_64 272 -+ -+#define TARGET_NR_set_robust_list 311 diff --git a/qemu-0.9.0-sched.patch b/qemu-0.9.0-sched.patch deleted file mode 100644 index d9fd8352..00000000 --- a/qemu-0.9.0-sched.patch +++ /dev/null @@ -1,32 +0,0 @@ -Index: qemu-0.9.0/linux-user/syscall.c -=================================================================== ---- qemu-0.9.0.orig/linux-user/syscall.c -+++ qemu-0.9.0/linux-user/syscall.c -@@ -147,6 +147,7 @@ type name (type1 arg1,type2 arg2,type3 a - #define __NR_sys_fadvise64 __NR_fadvise64 - #define __NR_sys_tgkill __NR_tgkill - #define __NR_sys_clone __NR_clone -+#define __NR_sys_sched_getaffinity __NR_sched_getaffinity - - #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__) - #define __NR__llseek __NR_lseek -@@ -170,6 +171,7 @@ _syscall3(int,sys_syslog,int,type,char*, - _syscall4(int,sys_fadvise64,int,fd,loff_t,offset,loff_t,len,int,advice) - _syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig) - _syscall5(int,sys_clone, int, flags, void *, child_stack, int *, parent_tidptr, struct user_desc *, newtls, int *, child_tidptr) -+_syscall3(int,sys_sched_getaffinity,pid_t,pid,unsigned int,cpusetsize,void*,mask) - #ifdef __NR_exit_group - _syscall1(int,exit_group,int,error_code) - #endif -@@ -4248,6 +4250,11 @@ long do_syscall(void *cpu_env, int num, - ret = get_errno(sys_tgkill((int)arg1, (int)arg2, (int)arg3)); - break; - #endif -+#ifdef TARGET_NR_sched_getaffinity -+ case TARGET_NR_sched_getaffinity: -+ ret = get_errno(sys_sched_getaffinity((pid_t)arg1, (unsigned int)arg2, (void*)arg3)); -+ break; -+#endif - default: - unimplemented: - gemu_log("qemu: Unsupported syscall: %d\n", num); diff --git a/qemu-0.9.0-socket.patch b/qemu-0.9.0-socket.patch deleted file mode 100644 index c530f215..00000000 --- a/qemu-0.9.0-socket.patch +++ /dev/null @@ -1,22 +0,0 @@ -Index: qemu-0.9.0/linux-user/syscall.c -=================================================================== ---- qemu-0.9.0.orig/linux-user/syscall.c -+++ qemu-0.9.0/linux-user/syscall.c -@@ -869,7 +869,7 @@ static long do_getpeername(int fd, targe - target_ulong target_addrlen) - { - socklen_t addrlen = tget32(target_addrlen); -- void *addr = alloca(target_addrlen); -+ void *addr = alloca(addrlen); - long ret; - - gemu_log("getpeername(%d,0x%lx,0x%lx)\n", fd, addr, addrlen); -@@ -887,7 +887,7 @@ static long do_getsockname(int fd, targe - target_ulong target_addrlen) - { - socklen_t addrlen = tget32(target_addrlen); -- void *addr = alloca(target_addrlen); -+ void *addr = alloca(addrlen); - long ret; - - ret = get_errno(getsockname(fd, addr, &addrlen)); diff --git a/qemu-0.9.0-strace.patch b/qemu-0.9.0-strace.patch deleted file mode 100644 index fecf6a52..00000000 --- a/qemu-0.9.0-strace.patch +++ /dev/null @@ -1,1582 +0,0 @@ -Index: qemu/Makefile.target -=================================================================== ---- qemu.orig/Makefile.target 2007-06-02 11:43:16.000000000 -0400 -+++ qemu/Makefile.target 2007-06-02 11:43:22.000000000 -0400 -@@ -240,7 +240,7 @@ - endif - - ifdef CONFIG_LINUX_USER --OBJS= main.o syscall.o mmap.o signal.o path.o osdep.o thunk.o \ -+OBJS= main.o syscall.o syscall_names.o mmap.o signal.o path.o osdep.o thunk.o \ - elfload.o linuxload.o - LIBS+= $(AIOLIBS) - ifdef TARGET_HAS_BFLT -Index: qemu/linux-user/syscall.c -=================================================================== ---- qemu.orig/linux-user/syscall.c 2007-06-02 11:43:16.000000000 -0400 -+++ qemu/linux-user/syscall.c 2007-06-02 12:30:10.000000000 -0400 -@@ -2724,6 +2724,7 @@ - - #ifdef DEBUG - gemu_log("syscall %d", num); -+ print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6); - #endif - switch(num) { - case TARGET_NR_exit: -@@ -4906,6 +4907,7 @@ - } - fail: - #ifdef DEBUG -+ /* use this to end lines output by print_syscall() above */ - gemu_log(" = %ld\n", ret); - #endif - return ret; -Index: qemu/linux-user/syscall_names.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ qemu/linux-user/syscall_names.c 2007-06-02 12:26:31.000000000 -0400 -@@ -0,0 +1,30 @@ -+#include -+#include "qemu.h" -+ -+struct syscallname { -+ int nr; -+ char *name; -+ char *format; -+}; -+ -+static struct syscallname scnames[] = { -+#include "syscall_names.list" -+}; -+ -+static int nsyscalls = sizeof(scnames)/sizeof(struct syscallname); -+ -+void -+print_syscall(int num, long arg1, long arg2, long arg3, -+ long arg4, long arg5, long arg6) -+{ -+int i; -+char *format="%s(%ld,%ld,%ld,%ld,%ld,%ld)"; -+ -+for(i=0;itv_sec); -+ htp.tv_nsec = tswapl(ttp->tv_nsec); -+ ret = get_errno(clock_gettime((clockid_t)arg1, &htp)); -+ ttp->tv_sec = tswapl(htp.tv_sec); -+ ttp->tv_nsec = tswapl(htp.tv_nsec); -+ } else -+ ret = get_errno(clock_gettime((clockid_t)arg1, NULL)); -+ break; -+ } -+#endif - default: - unimplemented: - gemu_log("qemu: Unsupported syscall: %d\n", num); diff --git a/qemu-0.9.0-wine.patch b/qemu-0.9.0-wine.patch deleted file mode 100644 index 49dab7f9..00000000 --- a/qemu-0.9.0-wine.patch +++ /dev/null @@ -1,12 +0,0 @@ -Index: qemu-0.9.0/linux-user/main.c -=================================================================== ---- qemu-0.9.0.orig/linux-user/main.c -+++ qemu-0.9.0/linux-user/main.c -@@ -1787,6 +1787,7 @@ int main(int argc, char **argv) - cpu_x86_load_seg(env, R_FS, __USER_DS); - cpu_x86_load_seg(env, R_GS, __USER_DS); - -+ env->segs[R_FS].selector = 0; - #elif defined(TARGET_ARM) - { - int i; diff --git a/qemu-0.9.0-x86_64-opts.patch b/qemu-0.9.0-x86_64-opts.patch deleted file mode 100644 index 1dec5977..00000000 --- a/qemu-0.9.0-x86_64-opts.patch +++ /dev/null @@ -1,79 +0,0 @@ -2007-03-13 Gwenole Beauchesne - - * dyngen-exec.h (AREG4, AREG5): Temporarily disable for KVM support. - -2007-02-03 Gwenole Beauchesne - - * dyngen-exec.h (AREG4, AREG5): Enable when building with GCC4. - -2005-06-04 Gwenole Beauchesne - - * Add direct jump support to x86-64. - -================================================================================ ---- qemu-0.9.0/dyngen-exec.h -+++ qemu-0.9.0/dyngen-exec.h -@@ -95,8 +95,11 @@ - #define AREG1 "rbx" - #define AREG2 "r12" - #define AREG3 "r13" --//#define AREG4 "r14" --//#define AREG5 "r15" -+#if __GNUC__ >= 4 && ! USE_KVM -+/* XXX: earlier GCC crashes */ -+#define AREG4 "r14" -+#define AREG5 "r15" -+#endif - #endif - #ifdef __powerpc__ - #define AREG0 "r27" ---- qemu-0.9.0/dyngen.c -+++ qemu-0.9.0/dyngen.c -@@ -2614,6 +2614,17 @@ - if (rel->r_offset >= start_offset && - rel->r_offset < start_offset + copy_size) { - sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name; -+ if (strstart(sym_name, "__op_jmp", &p)) { -+ int n; -+ n = strtol(p, NULL, 10); -+ /* __op_jmp relocations are done at -+ runtime to do translated block -+ chaining: the offset of the instruction -+ needs to be stored */ -+ fprintf(outfile, " jmp_offsets[%d] = %d + (gen_code_ptr - gen_code_buf);\n", -+ n, rel->r_offset - start_offset); -+ continue; -+ } - get_reloc_expr(name, sizeof(name), sym_name); - type = ELF32_R_TYPE(rel->r_info); - addend = rel->r_addend; ---- qemu-0.9.0/exec-all.h -+++ qemu-0.9.0/exec-all.h -@@ -159,6 +159,9 @@ - #if defined(__i386__) && !defined(_WIN32) - #define USE_DIRECT_JUMP - #endif -+#if defined(__x86_64__) -+#define USE_DIRECT_JUMP -+#endif - - typedef struct TranslationBlock { - target_ulong pc; /* simulated PC corresponding to this block (EIP + CS base) */ -@@ -245,7 +248,7 @@ - asm volatile ("sync" : : : "memory"); - asm volatile ("isync" : : : "memory"); - } --#elif defined(__i386__) -+#elif defined(__i386__) || defined(__x86_64__) - static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr) - { - /* patch the branch destination */ -@@ -324,7 +327,7 @@ - "1:\n");\ - } while (0) - --#elif defined(__i386__) && defined(USE_DIRECT_JUMP) -+#elif (defined(__i386__) || defined(__x86_64__)) && defined(USE_DIRECT_JUMP) - - /* we patch the jump instruction directly. Use sti in place of the actual - jmp instruction so that dyngen can patch in the correct result. */ diff --git a/qemu-0.9.0.cvs.tar.bz2 b/qemu-0.9.0.cvs.tar.bz2 new file mode 100644 index 00000000..f1d91d81 --- /dev/null +++ b/qemu-0.9.0.cvs.tar.bz2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b21915f6e941724eba05dce9b0f96295e4f7ff69b7ea0f743f5798c678b8839e +size 2043438 diff --git a/qemu-0.9.0.patch b/qemu-0.9.0.patch deleted file mode 100644 index 301fc6a5..00000000 --- a/qemu-0.9.0.patch +++ /dev/null @@ -1,35 +0,0 @@ ---- linux-user/signal.c -+++ linux-user/signal.c 2007/02/12 12:47:45 -@@ -389,6 +389,8 @@ - { - int sig; - target_siginfo_t tinfo; -+ -+ //printf("host_signal_handler, signum %d\n",host_signum); - - /* the CPU emulator uses some host signals to detect exceptions, - we we forward to it some signals */ ---- Makefile -+++ Makefile 2007/02/12 12:48:38 -@@ -27,7 +27,7 @@ - ifndef CONFIG_DARWIN - ifndef CONFIG_WIN32 - ifndef CONFIG_SOLARIS --LIBS+=-lrt -+LIBS+=-lrt -lpthread - endif - endif - endif ---- Makefile.target -+++ Makefile.target 2007/02/12 12:47:45 -@@ -181,8 +181,8 @@ - - ######################################################### - --CPPFLAGS+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE --LIBS+=-lm -+CPPFLAGS+=-D_GNU_SOURCE -D_BSD_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -+LIBS+=-lm -lrt -lpthread - ifndef CONFIG_USER_ONLY - LIBS+=-lz - endif diff --git a/qemu-0.9.0.tar.bz2 b/qemu-0.9.0.tar.bz2 deleted file mode 100644 index 572da506..00000000 --- a/qemu-0.9.0.tar.bz2 +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1ce3d34e3fafde6a3802f3c6317dac14f6b482fa918df0d3af54edd8b0314242 -size 1625107 diff --git a/qemu-cvs-alsa_bitfield.patch b/qemu-cvs-alsa_bitfield.patch new file mode 100644 index 00000000..5f77dbe6 --- /dev/null +++ b/qemu-cvs-alsa_bitfield.patch @@ -0,0 +1,67 @@ +Index: qemu/thunk.h +=================================================================== +--- qemu.orig/thunk.h ++++ qemu/thunk.h +@@ -38,6 +38,7 @@ typedef enum argtype { + TYPE_PTR, + TYPE_ARRAY, + TYPE_STRUCT, ++ TYPE_INTBITFIELD, + } argtype; + + #define MK_PTR(type) TYPE_PTR, type +@@ -87,6 +88,7 @@ static inline int thunk_type_size(const + case TYPE_SHORT: + return 2; + case TYPE_INT: ++ case TYPE_INTBITFIELD: + return 4; + case TYPE_LONGLONG: + case TYPE_ULONGLONG: +@@ -124,6 +126,7 @@ static inline int thunk_type_align(const + case TYPE_SHORT: + return 2; + case TYPE_INT: ++ case TYPE_INTBITFIELD: + return 4; + case TYPE_LONGLONG: + case TYPE_ULONGLONG: +Index: qemu/thunk.c +=================================================================== +--- qemu.orig/thunk.c ++++ qemu/thunk.c +@@ -40,6 +40,7 @@ static inline const argtype *thunk_type_ + case TYPE_CHAR: + case TYPE_SHORT: + case TYPE_INT: ++ case TYPE_INTBITFIELD: + case TYPE_LONGLONG: + case TYPE_ULONGLONG: + case TYPE_LONG: +@@ -132,6 +133,26 @@ const argtype *thunk_convert(void *dst, + case TYPE_INT: + *(uint32_t *)dst = tswap32(*(uint32_t *)src); + break; ++ case TYPE_INTBITFIELD: ++#if defined(TARGET_I386) && defined(__powerpc__) ++ /* powerpc uses the MSB, whereas i386 uses the LSB ++ * to store the first bit in a field */ ++ { ++ unsigned char byte = *(uint8_t *)src; ++ *(uint8_t *)dst = ((byte >> 7) & 1) ++ | ((byte >> 5) & 2) ++ | ((byte >> 3) & 4) ++ | ((byte >> 1) & 8) ++ | ((byte << 1) & 16) ++ | ((byte << 3) & 32) ++ | ((byte << 5) & 64) ++ | ((byte << 7) & 128); ++ /* FIXME: implement for bitfields > 1 byte and other archs */ ++ } ++#else ++ *(uint32_t *)dst = tswap32(*(uint32_t *)src); ++#endif ++ break; + case TYPE_LONGLONG: + case TYPE_ULONGLONG: + *(uint64_t *)dst = tswap64(*(uint64_t *)src); diff --git a/qemu-cvs-alsa_ioctl.patch b/qemu-cvs-alsa_ioctl.patch new file mode 100644 index 00000000..1bfcfb89 --- /dev/null +++ b/qemu-cvs-alsa_ioctl.patch @@ -0,0 +1,3592 @@ +Index: qemu/linux-user/ioctls.h +=================================================================== +--- qemu.orig/linux-user/ioctls.h ++++ qemu/linux-user/ioctls.h +@@ -300,3 +300,8 @@ + + IOCTL(VFAT_IOCTL_READDIR_BOTH, IOC_R, MK_PTR(MK_ARRAY(MK_STRUCT(STRUCT_dirent), 2))) + IOCTL(VFAT_IOCTL_READDIR_SHORT, IOC_R, MK_PTR(MK_ARRAY(MK_STRUCT(STRUCT_dirent), 2))) ++ ++/* FIXME: including these on x86 / x86_64 breaks qemu-i386 */ ++#ifdef __powerpc__ ++#include "ioctls_alsa.h" ++#endif +Index: qemu/linux-user/ioctls_alsa.h +=================================================================== +--- /dev/null ++++ qemu/linux-user/ioctls_alsa.h +@@ -0,0 +1,465 @@ ++#define SNDRV_SEQ_IOCTL_PVERSION _IOR ('S', 0x00, int) ++#define SNDRV_SEQ_IOCTL_CLIENT_ID _IOR ('S', 0x01, int) ++#define SNDRV_SEQ_IOCTL_SYSTEM_INFO _IOWR('S', 0x02, struct sndrv_seq_system_info) ++#define SNDRV_SEQ_IOCTL_RUNNING_MODE _IOWR('S', 0x03, struct sndrv_seq_running_info) ++#define SNDRV_SEQ_IOCTL_GET_CLIENT_INFO _IOWR('S', 0x10, struct sndrv_seq_client_info) ++#define SNDRV_SEQ_IOCTL_SET_CLIENT_INFO _IOW ('S', 0x11, struct sndrv_seq_client_info) ++#define SNDRV_SEQ_IOCTL_CREATE_PORT _IOWR('S', 0x20, struct sndrv_seq_port_info) ++#define SNDRV_SEQ_IOCTL_DELETE_PORT _IOW ('S', 0x21, struct sndrv_seq_port_info) ++#define SNDRV_SEQ_IOCTL_GET_PORT_INFO _IOWR('S', 0x22, struct sndrv_seq_port_info) ++#define SNDRV_SEQ_IOCTL_SET_PORT_INFO _IOW ('S', 0x23, struct sndrv_seq_port_info) ++#define SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT _IOW ('S', 0x30, struct sndrv_seq_port_subscribe) ++#define SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT _IOW ('S', 0x31, struct sndrv_seq_port_subscribe) ++#define SNDRV_SEQ_IOCTL_CREATE_QUEUE _IOWR('S', 0x32, struct sndrv_seq_queue_info) ++#define SNDRV_SEQ_IOCTL_DELETE_QUEUE _IOW ('S', 0x33, struct sndrv_seq_queue_info) ++#define SNDRV_SEQ_IOCTL_GET_QUEUE_INFO _IOWR('S', 0x34, struct sndrv_seq_queue_info) ++#define SNDRV_SEQ_IOCTL_SET_QUEUE_INFO _IOWR('S', 0x35, struct sndrv_seq_queue_info) ++#define SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE _IOWR('S', 0x36, struct sndrv_seq_queue_info) ++#define SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS _IOWR('S', 0x40, struct sndrv_seq_queue_status) ++#define SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO _IOWR('S', 0x41, struct sndrv_seq_queue_tempo) ++#define SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO _IOW ('S', 0x42, struct sndrv_seq_queue_tempo) ++#define SNDRV_SEQ_IOCTL_GET_QUEUE_OWNER _IOWR('S', 0x43, struct sndrv_seq_queue_owner) ++#define SNDRV_SEQ_IOCTL_SET_QUEUE_OWNER _IOW ('S', 0x44, struct sndrv_seq_queue_owner) ++#define SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER _IOWR('S', 0x45, struct sndrv_seq_queue_timer) ++#define SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER _IOW ('S', 0x46, struct sndrv_seq_queue_timer) ++#define SNDRV_SEQ_IOCTL_GET_QUEUE_SYNC _IOWR('S', 0x53, struct sndrv_seq_queue_sync) ++#define SNDRV_SEQ_IOCTL_SET_QUEUE_SYNC _IOW ('S', 0x54, struct sndrv_seq_queue_sync) ++#define SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT _IOWR('S', 0x49, struct sndrv_seq_queue_client) ++#define SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT _IOW ('S', 0x4a, struct sndrv_seq_queue_client) ++#define SNDRV_SEQ_IOCTL_GET_CLIENT_POOL _IOWR('S', 0x4b, struct sndrv_seq_client_pool) ++#define SNDRV_SEQ_IOCTL_SET_CLIENT_POOL _IOW ('S', 0x4c, struct sndrv_seq_client_pool) ++#define SNDRV_SEQ_IOCTL_REMOVE_EVENTS _IOW ('S', 0x4e, struct sndrv_seq_remove_events) ++#define SNDRV_SEQ_IOCTL_QUERY_SUBS _IOWR('S', 0x4f, struct sndrv_seq_query_subs) ++#define SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION _IOWR('S', 0x50, struct sndrv_seq_port_subscribe) ++#define SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT _IOWR('S', 0x51, struct sndrv_seq_client_info) ++#define SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT _IOWR('S', 0x52, struct sndrv_seq_port_info) ++#define SNDRV_DM_FM_IOCTL_INFO _IOR('H', 0x20, snd_dm_fm_info_t) ++#define SNDRV_DM_FM_IOCTL_RESET _IO ('H', 0x21) ++#define SNDRV_DM_FM_IOCTL_PLAY_NOTE _IOW('H', 0x22, snd_dm_fm_note_t) ++#define SNDRV_DM_FM_IOCTL_SET_VOICE _IOW('H', 0x23, snd_dm_fm_voice_t) ++#define SNDRV_DM_FM_IOCTL_SET_PARAMS _IOW('H', 0x24, snd_dm_fm_params_t) ++#define SNDRV_DM_FM_IOCTL_SET_MODE _IOW('H', 0x25, int) ++#define SNDRV_DM_FM_IOCTL_SET_CONNECTION _IOW('H', 0x26, int) ++#define SNDRV_DM_FM_OSS_IOCTL_RESET 0x20 ++#define SNDRV_DM_FM_OSS_IOCTL_PLAY_NOTE 0x21 ++#define SNDRV_DM_FM_OSS_IOCTL_SET_VOICE 0x22 ++#define SNDRV_DM_FM_OSS_IOCTL_SET_PARAMS 0x23 ++#define SNDRV_DM_FM_OSS_IOCTL_SET_MODE 0x24 ++#define SNDRV_DM_FM_OSS_IOCTL_SET_OPL 0x25 ++#define SNDRV_HWDEP_IOCTL_PVERSION _IOR ('H', 0x00, int) ++#define SNDRV_HWDEP_IOCTL_INFO _IOR ('H', 0x01, struct sndrv_hwdep_info) ++#define SNDRV_HWDEP_IOCTL_DSP_STATUS _IOR('H', 0x02, struct sndrv_hwdep_dsp_status) ++#define SNDRV_HWDEP_IOCTL_DSP_LOAD _IOW('H', 0x03, struct sndrv_hwdep_dsp_image) ++#define SNDRV_PCM_IOCTL_PVERSION _IOR('A', 0x00, int) ++#define SNDRV_PCM_IOCTL_INFO _IOR('A', 0x01, struct sndrv_pcm_info) ++#define SNDRV_PCM_IOCTL_TSTAMP _IOW('A', 0x02, int) ++#define SNDRV_PCM_IOCTL_HW_REFINE _IOWR('A', 0x10, struct sndrv_pcm_hw_params) ++#define SNDRV_PCM_IOCTL_HW_PARAMS _IOWR('A', 0x11, struct sndrv_pcm_hw_params) ++#define SNDRV_PCM_IOCTL_HW_FREE _IO('A', 0x12) ++#define SNDRV_PCM_IOCTL_SW_PARAMS _IOWR('A', 0x13, struct sndrv_pcm_sw_params) ++#define SNDRV_PCM_IOCTL_STATUS _IOR('A', 0x20, struct sndrv_pcm_status) ++#define SNDRV_PCM_IOCTL_DELAY _IOR('A', 0x21, sndrv_pcm_sframes_t) ++#define SNDRV_PCM_IOCTL_HWSYNC _IO('A', 0x22) ++#define SNDRV_PCM_IOCTL_SYNC_PTR _IOWR('A', 0x23, struct sndrv_pcm_sync_ptr) ++#define SNDRV_PCM_IOCTL_CHANNEL_INFO _IOR('A', 0x32, struct sndrv_pcm_channel_info) ++#define SNDRV_PCM_IOCTL_PREPARE _IO('A', 0x40) ++#define SNDRV_PCM_IOCTL_RESET _IO('A', 0x41) ++#define SNDRV_PCM_IOCTL_START _IO('A', 0x42) ++#define SNDRV_PCM_IOCTL_DROP _IO('A', 0x43) ++#define SNDRV_PCM_IOCTL_DRAIN _IO('A', 0x44) ++#define SNDRV_PCM_IOCTL_PAUSE _IOW('A', 0x45, int) ++#define SNDRV_PCM_IOCTL_REWIND _IOW('A', 0x46, sndrv_pcm_uframes_t) ++#define SNDRV_PCM_IOCTL_RESUME _IO('A', 0x47) ++#define SNDRV_PCM_IOCTL_XRUN _IO('A', 0x48) ++#define SNDRV_PCM_IOCTL_FORWARD _IOW('A', 0x49, sndrv_pcm_uframes_t) ++#define SNDRV_PCM_IOCTL_WRITEI_FRAMES _IOW('A', 0x50, struct sndrv_xferi) ++#define SNDRV_PCM_IOCTL_READI_FRAMES _IOR('A', 0x51, struct sndrv_xferi) ++#define SNDRV_PCM_IOCTL_WRITEN_FRAMES _IOW('A', 0x52, struct sndrv_xfern) ++#define SNDRV_PCM_IOCTL_READN_FRAMES _IOR('A', 0x53, struct sndrv_xfern) ++#define SNDRV_PCM_IOCTL_LINK _IOW('A', 0x60, int) ++#define SNDRV_PCM_IOCTL_UNLINK _IO('A', 0x61) ++#define SNDRV_RAWMIDI_IOCTL_PVERSION _IOR('W', 0x00, int) ++#define SNDRV_RAWMIDI_IOCTL_INFO _IOR('W', 0x01, struct sndrv_rawmidi_info) ++#define SNDRV_RAWMIDI_IOCTL_PARAMS _IOWR('W', 0x10, struct sndrv_rawmidi_params) ++#define SNDRV_RAWMIDI_IOCTL_STATUS _IOWR('W', 0x20, struct sndrv_rawmidi_status) ++#define SNDRV_RAWMIDI_IOCTL_DROP _IOW('W', 0x30, int) ++#define SNDRV_RAWMIDI_IOCTL_DRAIN _IOW('W', 0x31, int) ++#define SNDRV_TIMER_IOCTL_PVERSION _IOR('T', 0x00, int) ++#define SNDRV_TIMER_IOCTL_NEXT_DEVICE _IOWR('T', 0x01, struct sndrv_timer_id) ++#define SNDRV_TIMER_IOCTL_TREAD _IOW('T', 0x02, int) ++#define SNDRV_TIMER_IOCTL_GINFO _IOWR('T', 0x03, struct sndrv_timer_ginfo) ++#define SNDRV_TIMER_IOCTL_GPARAMS _IOW('T', 0x04, struct sndrv_timer_gparams) ++#define SNDRV_TIMER_IOCTL_GSTATUS _IOWR('T', 0x05, struct sndrv_timer_gstatus) ++#define SNDRV_TIMER_IOCTL_SELECT _IOW('T', 0x10, struct sndrv_timer_select) ++#define SNDRV_TIMER_IOCTL_INFO _IOR('T', 0x11, struct sndrv_timer_info) ++#define SNDRV_TIMER_IOCTL_PARAMS _IOW('T', 0x12, struct sndrv_timer_params) ++#define SNDRV_TIMER_IOCTL_STATUS _IOR('T', 0x14, struct sndrv_timer_status) ++#define SNDRV_TIMER_IOCTL_START _IO('T', 0xa0) ++#define SNDRV_TIMER_IOCTL_STOP _IO('T', 0xa1) ++#define SNDRV_TIMER_IOCTL_CONTINUE _IO('T', 0xa2) ++#define SNDRV_TIMER_IOCTL_PAUSE _IO('T', 0xa3) ++#define SNDRV_CTL_IOCTL_PVERSION _IOR('U', 0x00, int) ++#define SNDRV_CTL_IOCTL_CARD_INFO _IOR('U', 0x01, struct sndrv_ctl_card_info) ++#define SNDRV_CTL_IOCTL_ELEM_LIST _IOWR('U', 0x10, struct sndrv_ctl_elem_list) ++#define SNDRV_CTL_IOCTL_ELEM_INFO _IOWR('U', 0x11, struct sndrv_ctl_elem_info) ++#define SNDRV_CTL_IOCTL_ELEM_READ _IOWR('U', 0x12, struct sndrv_ctl_elem_value) ++#define SNDRV_CTL_IOCTL_ELEM_WRITE _IOWR('U', 0x13, struct sndrv_ctl_elem_value) ++#define SNDRV_CTL_IOCTL_ELEM_LOCK _IOW('U', 0x14, struct sndrv_ctl_elem_id) ++#define SNDRV_CTL_IOCTL_ELEM_UNLOCK _IOW('U', 0x15, struct sndrv_ctl_elem_id) ++#define SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS _IOWR('U', 0x16, int) ++#define SNDRV_CTL_IOCTL_ELEM_ADD _IOWR('U', 0x17, struct sndrv_ctl_elem_info) ++#define SNDRV_CTL_IOCTL_ELEM_REPLACE _IOWR('U', 0x18, struct sndrv_ctl_elem_info) ++#define SNDRV_CTL_IOCTL_ELEM_REMOVE _IOWR('U', 0x19, struct sndrv_ctl_elem_id) ++#define SNDRV_CTL_IOCTL_TLV_READ _IOWR('U', 0x1a, struct sndrv_ctl_tlv) ++#define SNDRV_CTL_IOCTL_TLV_WRITE _IOWR('U', 0x1b, struct sndrv_ctl_tlv) ++#define SNDRV_CTL_IOCTL_TLV_COMMAND _IOWR('U', 0x1c, struct sndrv_ctl_tlv) ++#define SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE _IOWR('U', 0x20, int) ++#define SNDRV_CTL_IOCTL_HWDEP_INFO _IOR('U', 0x21, struct sndrv_hwdep_info) ++#define SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE _IOR('U', 0x30, int) ++#define SNDRV_CTL_IOCTL_PCM_INFO _IOWR('U', 0x31, struct sndrv_pcm_info) ++#define SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE _IOW('U', 0x32, int) ++#define SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE _IOWR('U', 0x40, int) ++#define SNDRV_CTL_IOCTL_RAWMIDI_INFO _IOWR('U', 0x41, struct sndrv_rawmidi_info) ++#define SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE _IOW('U', 0x42, int) ++#define SNDRV_CTL_IOCTL_POWER _IOWR('U', 0xd0, int) ++#define SNDRV_CTL_IOCTL_POWER_STATE _IOR('U', 0xd1, int) ++#define SNDRV_IOCTL_READV _IOW('K', 0x00, struct sndrv_xferv) ++#define SNDRV_IOCTL_WRITEV _IOW('K', 0x01, struct sndrv_xferv) ++#define SNDRV_EMU10K1_IOCTL_INFO _IOR ('H', 0x10, emu10k1_fx8010_info_t) ++#define SNDRV_EMU10K1_IOCTL_CODE_POKE _IOW ('H', 0x11, emu10k1_fx8010_code_t) ++#define SNDRV_EMU10K1_IOCTL_CODE_PEEK _IOWR('H', 0x12, emu10k1_fx8010_code_t) ++#define SNDRV_EMU10K1_IOCTL_TRAM_SETUP _IOW ('H', 0x20, int) ++#define SNDRV_EMU10K1_IOCTL_TRAM_POKE _IOW ('H', 0x21, emu10k1_fx8010_tram_t) ++#define SNDRV_EMU10K1_IOCTL_TRAM_PEEK _IOWR('H', 0x22, emu10k1_fx8010_tram_t) ++#define SNDRV_EMU10K1_IOCTL_PCM_POKE _IOW ('H', 0x30, emu10k1_fx8010_pcm_t) ++#define SNDRV_EMU10K1_IOCTL_PCM_PEEK _IOWR('H', 0x31, emu10k1_fx8010_pcm_t) ++#define SNDRV_EMU10K1_IOCTL_PVERSION _IOR ('H', 0x40, int) ++#define SNDRV_EMU10K1_IOCTL_STOP _IO ('H', 0x80) ++#define SNDRV_EMU10K1_IOCTL_CONTINUE _IO ('H', 0x81) ++#define SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER _IO ('H', 0x82) ++#define SNDRV_EMU10K1_IOCTL_SINGLE_STEP _IOW ('H', 0x83, int) ++#define SNDRV_EMU10K1_IOCTL_DBG_READ _IOR ('H', 0x84, int) ++#define SNDRV_HDSP_IOCTL_GET_PEAK_RMS _IOR('H', 0x40, hdsp_peak_rms_t) ++#define SNDRV_HDSP_IOCTL_GET_CONFIG_INFO _IOR('H', 0x41, hdsp_config_info_t) ++#define SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE _IOW('H', 0x42, hdsp_firmware_t) ++#define SNDRV_HDSP_IOCTL_GET_VERSION _IOR('H', 0x43, hdsp_version_t) ++#define SNDRV_HDSP_IOCTL_GET_MIXER _IOR('H', 0x44, hdsp_mixer_t) ++#define SNDRV_HDSP_IOCTL_GET_9632_AEB _IOR('H', 0x45, hdsp_9632_aeb_t) ++#define SNDRV_SB_CSP_IOCTL_INFO _IOR('H', 0x10, snd_sb_csp_info_t) ++#define SNDRV_SB_CSP_IOCTL_LOAD_CODE _IOW('H', 0x11, snd_sb_csp_microcode_t) ++#define SNDRV_SB_CSP_IOCTL_UNLOAD_CODE _IO('H', 0x12) ++#define SNDRV_SB_CSP_IOCTL_START _IOW('H', 0x13, snd_sb_csp_start_t) ++#define SNDRV_SB_CSP_IOCTL_STOP _IO('H', 0x14) ++#define SNDRV_SB_CSP_IOCTL_PAUSE _IO('H', 0x15) ++#define SNDRV_SB_CSP_IOCTL_RESTART _IO('H', 0x16) ++#define SND_SSCAPE_LOAD_BOOTB _IOWR('P', 100, struct sscape_bootblock) ++#define SND_SSCAPE_LOAD_MCODE _IOW ('P', 101, struct sscape_microcode) ++ ++ ++#define TARGET_SNDRV_SEQ_IOCTL_PVERSION TARGET_IOR ('S', 0x00, int) ++#define TARGET_SNDRV_SEQ_IOCTL_CLIENT_ID TARGET_IOR ('S', 0x01, int) ++#define TARGET_SNDRV_SEQ_IOCTL_SYSTEM_INFO TARGET_IOWRU('S', 0x02) ++#define TARGET_SNDRV_SEQ_IOCTL_RUNNING_MODE TARGET_IOWRU('S', 0x03) ++#define TARGET_SNDRV_SEQ_IOCTL_GET_CLIENT_INFO TARGET_IOWRU('S', 0x10) ++#define TARGET_SNDRV_SEQ_IOCTL_SET_CLIENT_INFO TARGET_IOWU ('S', 0x11) ++#define TARGET_SNDRV_SEQ_IOCTL_CREATE_PORT TARGET_IOWRU('S', 0x20) ++#define TARGET_SNDRV_SEQ_IOCTL_DELETE_PORT TARGET_IOWU ('S', 0x21) ++#define TARGET_SNDRV_SEQ_IOCTL_GET_PORT_INFO TARGET_IOWRU('S', 0x22) ++#define TARGET_SNDRV_SEQ_IOCTL_SET_PORT_INFO TARGET_IOWU ('S', 0x23) ++#define TARGET_SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT TARGET_IOWU ('S', 0x30) ++#define TARGET_SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT TARGET_IOWU ('S', 0x31) ++#define TARGET_SNDRV_SEQ_IOCTL_CREATE_QUEUE TARGET_IOWRU('S', 0x32) ++#define TARGET_SNDRV_SEQ_IOCTL_DELETE_QUEUE TARGET_IOWU ('S', 0x33) ++#define TARGET_SNDRV_SEQ_IOCTL_GET_QUEUE_INFO TARGET_IOWRU('S', 0x34) ++#define TARGET_SNDRV_SEQ_IOCTL_SET_QUEUE_INFO TARGET_IOWRU('S', 0x35) ++#define TARGET_SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE TARGET_IOWRU('S', 0x36) ++#define TARGET_SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS TARGET_IOWRU('S', 0x40) ++#define TARGET_SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO TARGET_IOWRU('S', 0x41) ++#define TARGET_SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO TARGET_IOWU ('S', 0x42) ++#define TARGET_SNDRV_SEQ_IOCTL_GET_QUEUE_OWNER TARGET_IOWRU('S', 0x43) ++#define TARGET_SNDRV_SEQ_IOCTL_SET_QUEUE_OWNER TARGET_IOWU ('S', 0x44) ++#define TARGET_SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER TARGET_IOWRU('S', 0x45) ++#define TARGET_SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER TARGET_IOWU ('S', 0x46) ++#define TARGET_SNDRV_SEQ_IOCTL_GET_QUEUE_SYNC TARGET_IOWRU('S', 0x53) ++#define TARGET_SNDRV_SEQ_IOCTL_SET_QUEUE_SYNC TARGET_IOWU ('S', 0x54) ++#define TARGET_SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT TARGET_IOWRU('S', 0x49) ++#define TARGET_SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT TARGET_IOWU ('S', 0x4a) ++#define TARGET_SNDRV_SEQ_IOCTL_GET_CLIENT_POOL TARGET_IOWRU('S', 0x4b) ++#define TARGET_SNDRV_SEQ_IOCTL_SET_CLIENT_POOL TARGET_IOWU ('S', 0x4c) ++#define TARGET_SNDRV_SEQ_IOCTL_REMOVE_EVENTS TARGET_IOWU ('S', 0x4e) ++#define TARGET_SNDRV_SEQ_IOCTL_QUERY_SUBS TARGET_IOWRU('S', 0x4f) ++#define TARGET_SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION TARGET_IOWRU('S', 0x50) ++#define TARGET_SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT TARGET_IOWRU('S', 0x51) ++#define TARGET_SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT TARGET_IOWRU('S', 0x52) ++#define TARGET_SNDRV_DM_FM_IOCTL_INFO TARGET_IORU('H', 0x20) ++#define TARGET_SNDRV_DM_FM_IOCTL_RESET TARGET_IO ('H', 0x21) ++#define TARGET_SNDRV_DM_FM_IOCTL_PLAY_NOTE TARGET_IOWU('H', 0x22) ++#define TARGET_SNDRV_DM_FM_IOCTL_SET_VOICE TARGET_IOWU('H', 0x23) ++#define TARGET_SNDRV_DM_FM_IOCTL_SET_PARAMS TARGET_IOWU('H', 0x24) ++#define TARGET_SNDRV_DM_FM_IOCTL_SET_MODE TARGET_IOW('H', 0x25, int) ++#define TARGET_SNDRV_DM_FM_IOCTL_SET_CONNECTION TARGET_IOW('H', 0x26, int) ++#define TARGET_SNDRV_DM_FM_OSS_IOCTL_RESET 0x20 ++#define TARGET_SNDRV_DM_FM_OSS_IOCTL_PLAY_NOTE 0x21 ++#define TARGET_SNDRV_DM_FM_OSS_IOCTL_SET_VOICE 0x22 ++#define TARGET_SNDRV_DM_FM_OSS_IOCTL_SET_PARAMS 0x23 ++#define TARGET_SNDRV_DM_FM_OSS_IOCTL_SET_MODE 0x24 ++#define TARGET_SNDRV_DM_FM_OSS_IOCTL_SET_OPL 0x25 ++#define TARGET_SNDRV_HWDEP_IOCTL_PVERSION TARGET_IOR ('H', 0x00, int) ++#define TARGET_SNDRV_HWDEP_IOCTL_INFO TARGET_IORU ('H', 0x01) ++#define TARGET_SNDRV_HWDEP_IOCTL_DSP_STATUS TARGET_IORU('H', 0x02) ++#define TARGET_SNDRV_HWDEP_IOCTL_DSP_LOAD TARGET_IOWU('H', 0x03) ++#define TARGET_SNDRV_PCM_IOCTL_PVERSION TARGET_IOR('A', 0x00, int) ++#define TARGET_SNDRV_PCM_IOCTL_INFO TARGET_IORU('A', 0x01) ++#define TARGET_SNDRV_PCM_IOCTL_TSTAMP TARGET_IOW('A', 0x02, int) ++#define TARGET_SNDRV_PCM_IOCTL_HW_REFINE TARGET_IOWRU('A', 0x10) ++#define TARGET_SNDRV_PCM_IOCTL_HW_PARAMS TARGET_IOWRU('A', 0x11) ++#define TARGET_SNDRV_PCM_IOCTL_HW_FREE TARGET_IO('A', 0x12) ++#define TARGET_SNDRV_PCM_IOCTL_SW_PARAMS TARGET_IOWRU('A', 0x13) ++#define TARGET_SNDRV_PCM_IOCTL_STATUS TARGET_IORU('A', 0x20) ++#define TARGET_SNDRV_PCM_IOCTL_DELAY TARGET_IORU('A', 0x21) ++#define TARGET_SNDRV_PCM_IOCTL_HWSYNC TARGET_IO('A', 0x22) ++#define TARGET_SNDRV_PCM_IOCTL_SYNC_PTR TARGET_IOWRU('A', 0x23) ++#define TARGET_SNDRV_PCM_IOCTL_CHANNEL_INFO TARGET_IORU('A', 0x32) ++#define TARGET_SNDRV_PCM_IOCTL_PREPARE TARGET_IO('A', 0x40) ++#define TARGET_SNDRV_PCM_IOCTL_RESET TARGET_IO('A', 0x41) ++#define TARGET_SNDRV_PCM_IOCTL_START TARGET_IO('A', 0x42) ++#define TARGET_SNDRV_PCM_IOCTL_DROP TARGET_IO('A', 0x43) ++#define TARGET_SNDRV_PCM_IOCTL_DRAIN TARGET_IO('A', 0x44) ++#define TARGET_SNDRV_PCM_IOCTL_PAUSE TARGET_IOW('A', 0x45, int) ++#define TARGET_SNDRV_PCM_IOCTL_REWIND TARGET_IOWU('A', 0x46) ++#define TARGET_SNDRV_PCM_IOCTL_RESUME TARGET_IO('A', 0x47) ++#define TARGET_SNDRV_PCM_IOCTL_XRUN TARGET_IO('A', 0x48) ++#define TARGET_SNDRV_PCM_IOCTL_FORWARD TARGET_IOWU('A', 0x49) ++#define TARGET_SNDRV_PCM_IOCTL_WRITEI_FRAMES TARGET_IOWU('A', 0x50) ++#define TARGET_SNDRV_PCM_IOCTL_READI_FRAMES TARGET_IORU('A', 0x51) ++#define TARGET_SNDRV_PCM_IOCTL_WRITEN_FRAMES TARGET_IOWU('A', 0x52) ++#define TARGET_SNDRV_PCM_IOCTL_READN_FRAMES TARGET_IORU('A', 0x53) ++#define TARGET_SNDRV_PCM_IOCTL_LINK TARGET_IOW('A', 0x60, int) ++#define TARGET_SNDRV_PCM_IOCTL_UNLINK TARGET_IO('A', 0x61) ++#define TARGET_SNDRV_RAWMIDI_IOCTL_PVERSION TARGET_IOR('W', 0x00, int) ++#define TARGET_SNDRV_RAWMIDI_IOCTL_INFO TARGET_IORU('W', 0x01) ++#define TARGET_SNDRV_RAWMIDI_IOCTL_PARAMS TARGET_IOWRU('W', 0x10) ++#define TARGET_SNDRV_RAWMIDI_IOCTL_STATUS TARGET_IOWRU('W', 0x20) ++#define TARGET_SNDRV_RAWMIDI_IOCTL_DROP TARGET_IOW('W', 0x30, int) ++#define TARGET_SNDRV_RAWMIDI_IOCTL_DRAIN TARGET_IOW('W', 0x31, int) ++#define TARGET_SNDRV_TIMER_IOCTL_PVERSION TARGET_IOR('T', 0x00, int) ++#define TARGET_SNDRV_TIMER_IOCTL_NEXT_DEVICE TARGET_IOWRU('T', 0x01) ++#define TARGET_SNDRV_TIMER_IOCTL_TREAD TARGET_IOW('T', 0x02, int) ++#define TARGET_SNDRV_TIMER_IOCTL_GINFO TARGET_IOWRU('T', 0x03) ++#define TARGET_SNDRV_TIMER_IOCTL_GPARAMS TARGET_IOWU('T', 0x04) ++#define TARGET_SNDRV_TIMER_IOCTL_GSTATUS TARGET_IOWRU('T', 0x05) ++#define TARGET_SNDRV_TIMER_IOCTL_SELECT TARGET_IOWU('T', 0x10) ++#define TARGET_SNDRV_TIMER_IOCTL_INFO TARGET_IORU('T', 0x11) ++#define TARGET_SNDRV_TIMER_IOCTL_PARAMS TARGET_IOWU('T', 0x12) ++#define TARGET_SNDRV_TIMER_IOCTL_STATUS TARGET_IORU('T', 0x14) ++#define TARGET_SNDRV_TIMER_IOCTL_START TARGET_IO('T', 0xa0) ++#define TARGET_SNDRV_TIMER_IOCTL_STOP TARGET_IO('T', 0xa1) ++#define TARGET_SNDRV_TIMER_IOCTL_CONTINUE TARGET_IO('T', 0xa2) ++#define TARGET_SNDRV_TIMER_IOCTL_PAUSE TARGET_IO('T', 0xa3) ++#define TARGET_SNDRV_CTL_IOCTL_PVERSION TARGET_IOR('U', 0x00, int) ++#define TARGET_SNDRV_CTL_IOCTL_CARD_INFO TARGET_IORU('U', 0x01) ++#define TARGET_SNDRV_CTL_IOCTL_ELEM_LIST TARGET_IOWRU('U', 0x10) ++#define TARGET_SNDRV_CTL_IOCTL_ELEM_INFO TARGET_IOWRU('U', 0x11) ++#define TARGET_SNDRV_CTL_IOCTL_ELEM_READ TARGET_IOWRU('U', 0x12) ++#define TARGET_SNDRV_CTL_IOCTL_ELEM_WRITE TARGET_IOWRU('U', 0x13) ++#define TARGET_SNDRV_CTL_IOCTL_ELEM_LOCK TARGET_IOWU('U', 0x14) ++#define TARGET_SNDRV_CTL_IOCTL_ELEM_UNLOCK TARGET_IOWU('U', 0x15) ++#define TARGET_SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS TARGET_IOWR('U', 0x16, int) ++#define TARGET_SNDRV_CTL_IOCTL_ELEM_ADD TARGET_IOWRU('U', 0x17) ++#define TARGET_SNDRV_CTL_IOCTL_ELEM_REPLACE TARGET_IOWRU('U', 0x18) ++#define TARGET_SNDRV_CTL_IOCTL_ELEM_REMOVE TARGET_IOWRU('U', 0x19) ++#define TARGET_SNDRV_CTL_IOCTL_TLV_READ TARGET_IOWRU('U', 0x1a) ++#define TARGET_SNDRV_CTL_IOCTL_TLV_WRITE TARGET_IOWRU('U', 0x1b) ++#define TARGET_SNDRV_CTL_IOCTL_TLV_COMMAND TARGET_IOWRU('U', 0x1c) ++#define TARGET_SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE TARGET_IOWR('U', 0x20, int) ++#define TARGET_SNDRV_CTL_IOCTL_HWDEP_INFO TARGET_IORU('U', 0x21) ++#define TARGET_SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE TARGET_IOR('U', 0x30, int) ++#define TARGET_SNDRV_CTL_IOCTL_PCM_INFO TARGET_IOWRU('U', 0x31) ++#define TARGET_SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE TARGET_IOW('U', 0x32, int) ++#define TARGET_SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE TARGET_IOWR('U', 0x40, int) ++#define TARGET_SNDRV_CTL_IOCTL_RAWMIDI_INFO TARGET_IOWRU('U', 0x41) ++#define TARGET_SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE TARGET_IOW('U', 0x42, int) ++#define TARGET_SNDRV_CTL_IOCTL_POWER TARGET_IOWR('U', 0xd0, int) ++#define TARGET_SNDRV_CTL_IOCTL_POWER_STATE TARGET_IOR('U', 0xd1, int) ++#define TARGET_SNDRV_IOCTL_READV TARGET_IOWU('K', 0x00) ++#define TARGET_SNDRV_IOCTL_WRITEV TARGET_IOWU('K', 0x01) ++#define TARGET_SNDRV_EMU10K1_IOCTL_INFO TARGET_IORU ('H', 0x10) ++#define TARGET_SNDRV_EMU10K1_IOCTL_CODE_POKE TARGET_IOWU ('H', 0x11) ++#define TARGET_SNDRV_EMU10K1_IOCTL_CODE_PEEK TARGET_IOWRU('H', 0x12) ++#define TARGET_SNDRV_EMU10K1_IOCTL_TRAM_SETUP TARGET_IOW ('H', 0x20, int) ++#define TARGET_SNDRV_EMU10K1_IOCTL_TRAM_POKE TARGET_IOWU ('H', 0x21) ++#define TARGET_SNDRV_EMU10K1_IOCTL_TRAM_PEEK TARGET_IOWRU('H', 0x22) ++#define TARGET_SNDRV_EMU10K1_IOCTL_PCM_POKE TARGET_IOWU ('H', 0x30) ++#define TARGET_SNDRV_EMU10K1_IOCTL_PCM_PEEK TARGET_IOWRU('H', 0x31) ++#define TARGET_SNDRV_EMU10K1_IOCTL_PVERSION TARGET_IOR ('H', 0x40, int) ++#define TARGET_SNDRV_EMU10K1_IOCTL_STOP TARGET_IO ('H', 0x80) ++#define TARGET_SNDRV_EMU10K1_IOCTL_CONTINUE TARGET_IO ('H', 0x81) ++#define TARGET_SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER TARGET_IO ('H', 0x82) ++#define TARGET_SNDRV_EMU10K1_IOCTL_SINGLE_STEP TARGET_IOW ('H', 0x83, int) ++#define TARGET_SNDRV_EMU10K1_IOCTL_DBG_READ TARGET_IOR ('H', 0x84, int) ++#define TARGET_SNDRV_HDSP_IOCTL_GET_PEAK_RMS TARGET_IORU('H', 0x40) ++#define TARGET_SNDRV_HDSP_IOCTL_GET_CONFIG_INFO TARGET_IORU('H', 0x41) ++#define TARGET_SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE TARGET_IOWU('H', 0x42) ++#define TARGET_SNDRV_HDSP_IOCTL_GET_VERSION TARGET_IORU('H', 0x43) ++#define TARGET_SNDRV_HDSP_IOCTL_GET_MIXER TARGET_IORU('H', 0x44) ++#define TARGET_SNDRV_HDSP_IOCTL_GET_9632_AEB TARGET_IORU('H', 0x45) ++#define TARGET_SNDRV_SB_CSP_IOCTL_INFO TARGET_IORU('H', 0x10) ++#define TARGET_SNDRV_SB_CSP_IOCTL_LOAD_CODE TARGET_IOWU('H', 0x11) ++#define TARGET_SNDRV_SB_CSP_IOCTL_UNLOAD_CODE TARGET_IO('H', 0x12) ++#define TARGET_SNDRV_SB_CSP_IOCTL_START TARGET_IOWU('H', 0x13) ++#define TARGET_SNDRV_SB_CSP_IOCTL_STOP TARGET_IO('H', 0x14) ++#define TARGET_SNDRV_SB_CSP_IOCTL_PAUSE TARGET_IO('H', 0x15) ++#define TARGET_SNDRV_SB_CSP_IOCTL_RESTART TARGET_IO('H', 0x16) ++#define TARGET_SND_SSCAPE_LOAD_BOOTB TARGET_IOWRU('P', 100) ++#define TARGET_SND_SSCAPE_LOAD_MCODE TARGET_IOWU ('P', 101) ++ ++IOCTL( SNDRV_SEQ_IOCTL_PVERSION , IOC_R, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_SEQ_IOCTL_CLIENT_ID , IOC_R, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_SEQ_IOCTL_SYSTEM_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_system_info)) ) ++IOCTL( SNDRV_SEQ_IOCTL_RUNNING_MODE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_running_info)) ) ++IOCTL( SNDRV_SEQ_IOCTL_GET_CLIENT_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_client_info)) ) ++IOCTL( SNDRV_SEQ_IOCTL_SET_CLIENT_INFO , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_client_info)) ) ++IOCTL( SNDRV_SEQ_IOCTL_CREATE_PORT , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_info)) ) ++IOCTL( SNDRV_SEQ_IOCTL_DELETE_PORT , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_info)) ) ++IOCTL( SNDRV_SEQ_IOCTL_GET_PORT_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_info)) ) ++IOCTL( SNDRV_SEQ_IOCTL_SET_PORT_INFO , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_info)) ) ++IOCTL( SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_subscribe)) ) ++IOCTL( SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_subscribe)) ) ++IOCTL( SNDRV_SEQ_IOCTL_CREATE_QUEUE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_info)) ) ++IOCTL( SNDRV_SEQ_IOCTL_DELETE_QUEUE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_info)) ) ++IOCTL( SNDRV_SEQ_IOCTL_GET_QUEUE_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_info)) ) ++IOCTL( SNDRV_SEQ_IOCTL_SET_QUEUE_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_info)) ) ++IOCTL( SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_info)) ) ++IOCTL( SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_status)) ) ++IOCTL( SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_tempo)) ) ++IOCTL( SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_tempo)) ) ++//IOCTL( SNDRV_SEQ_IOCTL_GET_QUEUE_OWNER , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_owner)) ) ++//IOCTL( SNDRV_SEQ_IOCTL_SET_QUEUE_OWNER , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_owner)) ) ++IOCTL( SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_timer)) ) ++IOCTL( SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_timer)) ) ++//IOCTL( SNDRV_SEQ_IOCTL_GET_QUEUE_SYNC , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_sync)) ) ++//IOCTL( SNDRV_SEQ_IOCTL_SET_QUEUE_SYNC , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_sync)) ) ++IOCTL( SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_client)) ) ++IOCTL( SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_client)) ) ++IOCTL( SNDRV_SEQ_IOCTL_GET_CLIENT_POOL , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_client_pool)) ) ++IOCTL( SNDRV_SEQ_IOCTL_SET_CLIENT_POOL , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_client_pool)) ) ++IOCTL( SNDRV_SEQ_IOCTL_REMOVE_EVENTS , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_remove_events)) ) ++IOCTL( SNDRV_SEQ_IOCTL_QUERY_SUBS , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_query_subs)) ) ++IOCTL( SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_subscribe)) ) ++IOCTL( SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_client_info)) ) ++IOCTL( SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_info)) ) ++IOCTL( SNDRV_DM_FM_IOCTL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_snd_dm_fm_info)) ) ++IOCTL( SNDRV_DM_FM_IOCTL_RESET , 0, TYPE_NULL ) ++IOCTL( SNDRV_DM_FM_IOCTL_PLAY_NOTE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_snd_dm_fm_note)) ) ++IOCTL( SNDRV_DM_FM_IOCTL_SET_VOICE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_snd_dm_fm_voice)) ) ++IOCTL( SNDRV_DM_FM_IOCTL_SET_PARAMS , IOC_W, MK_PTR(MK_STRUCT(STRUCT_snd_dm_fm_params)) ) ++IOCTL( SNDRV_DM_FM_IOCTL_SET_MODE , IOC_W, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_DM_FM_IOCTL_SET_CONNECTION , IOC_W, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_HWDEP_IOCTL_PVERSION , IOC_R, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_HWDEP_IOCTL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_hwdep_info)) ) ++IOCTL( SNDRV_HWDEP_IOCTL_DSP_STATUS , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_hwdep_dsp_status)) ) ++IOCTL( SNDRV_HWDEP_IOCTL_DSP_LOAD , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_hwdep_dsp_image)) ) ++IOCTL( SNDRV_PCM_IOCTL_PVERSION , IOC_R, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_PCM_IOCTL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_info)) ) ++IOCTL( SNDRV_PCM_IOCTL_TSTAMP , IOC_W, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_PCM_IOCTL_HW_REFINE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_hw_params)) ) ++IOCTL( SNDRV_PCM_IOCTL_HW_PARAMS , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_hw_params)) ) ++IOCTL( SNDRV_PCM_IOCTL_HW_FREE , 0, TYPE_NULL ) ++IOCTL( SNDRV_PCM_IOCTL_SW_PARAMS , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_sw_params)) ) ++IOCTL( SNDRV_PCM_IOCTL_STATUS , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_status)) ) ++IOCTL( SNDRV_PCM_IOCTL_DELAY , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_sframes)) ) ++IOCTL( SNDRV_PCM_IOCTL_HWSYNC , 0, TYPE_NULL ) ++IOCTL( SNDRV_PCM_IOCTL_SYNC_PTR , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_sync_ptr)) ) ++IOCTL( SNDRV_PCM_IOCTL_CHANNEL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_channel_info)) ) ++IOCTL( SNDRV_PCM_IOCTL_PREPARE , 0, TYPE_NULL ) ++IOCTL( SNDRV_PCM_IOCTL_RESET , 0, TYPE_NULL ) ++IOCTL( SNDRV_PCM_IOCTL_START , 0, TYPE_NULL ) ++IOCTL( SNDRV_PCM_IOCTL_DROP , 0, TYPE_NULL ) ++IOCTL( SNDRV_PCM_IOCTL_DRAIN , 0, TYPE_NULL ) ++IOCTL( SNDRV_PCM_IOCTL_PAUSE , IOC_W, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_PCM_IOCTL_REWIND , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_uframes)) ) ++IOCTL( SNDRV_PCM_IOCTL_RESUME , 0, TYPE_NULL ) ++IOCTL( SNDRV_PCM_IOCTL_XRUN , 0, TYPE_NULL ) ++IOCTL( SNDRV_PCM_IOCTL_FORWARD , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_uframes)) ) ++IOCTL( SNDRV_PCM_IOCTL_WRITEI_FRAMES , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_xferi)) ) ++IOCTL( SNDRV_PCM_IOCTL_READI_FRAMES , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_xferi)) ) ++IOCTL( SNDRV_PCM_IOCTL_WRITEN_FRAMES , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_xfern)) ) ++IOCTL( SNDRV_PCM_IOCTL_READN_FRAMES , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_xfern)) ) ++IOCTL( SNDRV_PCM_IOCTL_LINK , IOC_W, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_PCM_IOCTL_UNLINK , 0, TYPE_NULL ) ++IOCTL( SNDRV_RAWMIDI_IOCTL_PVERSION , IOC_R, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_RAWMIDI_IOCTL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_rawmidi_info)) ) ++IOCTL( SNDRV_RAWMIDI_IOCTL_PARAMS , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_rawmidi_params)) ) ++IOCTL( SNDRV_RAWMIDI_IOCTL_STATUS , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_rawmidi_status)) ) ++IOCTL( SNDRV_RAWMIDI_IOCTL_DROP , IOC_W, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_RAWMIDI_IOCTL_DRAIN , IOC_W, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_TIMER_IOCTL_PVERSION , IOC_R, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_TIMER_IOCTL_NEXT_DEVICE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_id)) ) ++IOCTL( SNDRV_TIMER_IOCTL_TREAD , IOC_W, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_TIMER_IOCTL_GINFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_ginfo)) ) ++IOCTL( SNDRV_TIMER_IOCTL_GPARAMS , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_gparams)) ) ++IOCTL( SNDRV_TIMER_IOCTL_GSTATUS , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_gstatus)) ) ++IOCTL( SNDRV_TIMER_IOCTL_SELECT , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_select)) ) ++IOCTL( SNDRV_TIMER_IOCTL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_info)) ) ++IOCTL( SNDRV_TIMER_IOCTL_PARAMS , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_params)) ) ++IOCTL( SNDRV_TIMER_IOCTL_STATUS , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_status)) ) ++IOCTL( SNDRV_TIMER_IOCTL_START , 0, TYPE_NULL ) ++IOCTL( SNDRV_TIMER_IOCTL_STOP , 0, TYPE_NULL ) ++IOCTL( SNDRV_TIMER_IOCTL_CONTINUE , 0, TYPE_NULL ) ++IOCTL( SNDRV_TIMER_IOCTL_PAUSE , 0, TYPE_NULL ) ++IOCTL( SNDRV_CTL_IOCTL_PVERSION , IOC_R, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_CTL_IOCTL_CARD_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_card_info)) ) ++IOCTL( SNDRV_CTL_IOCTL_ELEM_LIST , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_list)) ) ++IOCTL( SNDRV_CTL_IOCTL_ELEM_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_info)) ) ++IOCTL( SNDRV_CTL_IOCTL_ELEM_READ , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_value)) ) ++IOCTL( SNDRV_CTL_IOCTL_ELEM_WRITE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_value)) ) ++IOCTL( SNDRV_CTL_IOCTL_ELEM_LOCK , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_id)) ) ++IOCTL( SNDRV_CTL_IOCTL_ELEM_UNLOCK , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_id)) ) ++IOCTL( SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS , IOC_RW, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_CTL_IOCTL_ELEM_ADD , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_info)) ) ++IOCTL( SNDRV_CTL_IOCTL_ELEM_REPLACE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_info)) ) ++IOCTL( SNDRV_CTL_IOCTL_ELEM_REMOVE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_id)) ) ++IOCTL( SNDRV_CTL_IOCTL_TLV_READ , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_tlv)) ) ++IOCTL( SNDRV_CTL_IOCTL_TLV_WRITE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_tlv)) ) ++IOCTL( SNDRV_CTL_IOCTL_TLV_COMMAND , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_tlv)) ) ++IOCTL( SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE , IOC_RW, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_CTL_IOCTL_HWDEP_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_hwdep_info)) ) ++IOCTL( SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE , IOC_R, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_CTL_IOCTL_PCM_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_info)) ) ++IOCTL( SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE , IOC_W, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE , IOC_RW, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_CTL_IOCTL_RAWMIDI_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_rawmidi_info)) ) ++IOCTL( SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE , IOC_W, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_CTL_IOCTL_POWER , IOC_RW, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_CTL_IOCTL_POWER_STATE , IOC_R, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_IOCTL_READV , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_xferv)) ) ++IOCTL( SNDRV_IOCTL_WRITEV , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_xferv)) ) ++IOCTL( SNDRV_EMU10K1_IOCTL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_emu10k1_fx8010_info)) ) ++IOCTL( SNDRV_EMU10K1_IOCTL_CODE_POKE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_emu10k1_fx8010_code)) ) ++IOCTL( SNDRV_EMU10K1_IOCTL_CODE_PEEK , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_emu10k1_fx8010_code)) ) ++IOCTL( SNDRV_EMU10K1_IOCTL_TRAM_SETUP , IOC_W, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_EMU10K1_IOCTL_TRAM_POKE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_emu10k1_fx8010_tram)) ) ++IOCTL( SNDRV_EMU10K1_IOCTL_TRAM_PEEK , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_emu10k1_fx8010_tram)) ) ++IOCTL( SNDRV_EMU10K1_IOCTL_PCM_POKE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_emu10k1_fx8010_pcm)) ) ++IOCTL( SNDRV_EMU10K1_IOCTL_PCM_PEEK , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_emu10k1_fx8010_pcm)) ) ++IOCTL( SNDRV_EMU10K1_IOCTL_PVERSION , IOC_R, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_EMU10K1_IOCTL_STOP , 0, TYPE_NULL ) ++IOCTL( SNDRV_EMU10K1_IOCTL_CONTINUE , 0, TYPE_NULL ) ++IOCTL( SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER , 0, TYPE_NULL ) ++IOCTL( SNDRV_EMU10K1_IOCTL_SINGLE_STEP , IOC_W, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_EMU10K1_IOCTL_DBG_READ , IOC_R, MK_PTR(TYPE_INT) ) ++IOCTL( SNDRV_HDSP_IOCTL_GET_PEAK_RMS , IOC_R, MK_PTR(MK_STRUCT(STRUCT_hdsp_peak_rms)) ) ++IOCTL( SNDRV_HDSP_IOCTL_GET_CONFIG_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_hdsp_config_info)) ) ++IOCTL( SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_hdsp_firmware)) ) ++IOCTL( SNDRV_HDSP_IOCTL_GET_VERSION , IOC_R, MK_PTR(MK_STRUCT(STRUCT_hdsp_version)) ) ++IOCTL( SNDRV_HDSP_IOCTL_GET_MIXER , IOC_R, MK_PTR(MK_STRUCT(STRUCT_hdsp_mixer)) ) ++IOCTL( SNDRV_HDSP_IOCTL_GET_9632_AEB , IOC_R, MK_PTR(MK_STRUCT(STRUCT_hdsp_9632_aeb)) ) ++IOCTL( SNDRV_SB_CSP_IOCTL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_snd_sb_csp_info)) ) ++IOCTL( SNDRV_SB_CSP_IOCTL_LOAD_CODE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_snd_sb_csp_microcode)) ) ++IOCTL( SNDRV_SB_CSP_IOCTL_UNLOAD_CODE , 0, TYPE_NULL ) ++IOCTL( SNDRV_SB_CSP_IOCTL_START , IOC_W, MK_PTR(MK_STRUCT(STRUCT_snd_sb_csp_start)) ) ++IOCTL( SNDRV_SB_CSP_IOCTL_STOP , 0, TYPE_NULL ) ++IOCTL( SNDRV_SB_CSP_IOCTL_PAUSE , 0, TYPE_NULL ) ++IOCTL( SNDRV_SB_CSP_IOCTL_RESTART , 0, TYPE_NULL ) ++IOCTL( SND_SSCAPE_LOAD_BOOTB , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sscape_bootblock)) ) ++IOCTL( SND_SSCAPE_LOAD_MCODE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sscape_microcode)) ) +Index: qemu/linux-user/ioctls_alsa_structs.h +=================================================================== +--- /dev/null ++++ qemu/linux-user/ioctls_alsa_structs.h +@@ -0,0 +1,1740 @@ ++/* ++ * Advanced Linux Sound Architecture ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ */ ++ ++#ifndef __u8 ++#define __u8 uint8_t ++#define __u16 uint16_t ++#define __u32 uint32_t ++#define __s8 int8_t ++#define __s16 int16_t ++#define __s32 int32_t ++#endif ++ ++#define SNDRV_SB_CSP_MAX_MICROCODE_FILE_SIZE 0x3000 ++#define HDSP_MATRIX_MIXER_SIZE 2048 ++#define SNDRV_MASK_MAX 256 ++ ++typedef struct fm_operator { ++ unsigned char am_vib; ++ unsigned char ksl_level; ++ unsigned char attack_decay; ++ unsigned char sustain_release; ++ unsigned char wave_select; ++} fm_operator_t; ++ ++typedef struct { ++ unsigned int share_id[4]; /* share id - zero = no sharing */ ++ unsigned char type; /* instrument type */ ++ ++ fm_operator_t op[4]; ++ unsigned char feedback_connection[2]; ++ ++ unsigned char echo_delay; ++ unsigned char echo_atten; ++ unsigned char chorus_spread; ++ unsigned char trnsps; ++ unsigned char fix_dur; ++ unsigned char modes; ++ unsigned char fix_key; ++} fm_instrument_t; ++ ++typedef struct fm_xoperator { ++ __u8 am_vib; ++ __u8 ksl_level; ++ __u8 attack_decay; ++ __u8 sustain_release; ++ __u8 wave_select; ++} fm_xoperator_t; ++ ++typedef struct fm_xinstrument { ++ __u32 stype; /* structure type */ ++ ++ __u32 share_id[4]; /* share id - zero = no sharing */ ++ __u8 type; /* instrument type */ ++ ++ fm_xoperator_t op[4]; /* fm operators */ ++ __u8 feedback_connection[2]; ++ ++ __u8 echo_delay; ++ __u8 echo_atten; ++ __u8 chorus_spread; ++ __u8 trnsps; ++ __u8 fix_dur; ++ __u8 modes; ++ __u8 fix_key; ++} fm_xinstrument_t; ++ ++typedef struct gf1_wave { ++ unsigned int share_id[4]; /* share id - zero = no sharing */ ++ unsigned int format; /* wave format */ ++ ++ struct { ++ unsigned int number; /* some other ID for this instrument */ ++ unsigned int memory; /* begin of waveform in onboard memory */ ++ unsigned char *ptr; /* pointer to waveform in system memory */ ++ } address; ++ ++ unsigned int size; /* size of waveform in samples */ ++ unsigned int start; /* start offset in samples * 16 (lowest 4 bits - fraction) */ ++ unsigned int loop_start; /* bits loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ unsigned int loop_end; /* loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ unsigned short loop_repeat; /* loop repeat - 0 = forever */ ++ ++ unsigned char flags; /* GF1 patch flags */ ++ unsigned char pad; ++ unsigned int sample_rate; /* sample rate in Hz */ ++ unsigned int low_frequency; /* low frequency range */ ++ unsigned int high_frequency; /* high frequency range */ ++ unsigned int root_frequency; /* root frequency range */ ++ signed short tune; ++ unsigned char balance; ++ unsigned char envelope_rate[6]; ++ unsigned char envelope_offset[6]; ++ unsigned char tremolo_sweep; ++ unsigned char tremolo_rate; ++ unsigned char tremolo_depth; ++ unsigned char vibrato_sweep; ++ unsigned char vibrato_rate; ++ unsigned char vibrato_depth; ++ unsigned short scale_frequency; ++ unsigned short scale_factor; /* 0-2048 or 0-2 */ ++ ++ struct gf1_wave *next; ++} gf1_wave_t; ++ ++typedef struct { ++ unsigned short exclusion; ++ unsigned short exclusion_group; /* 0 - none, 1-65535 */ ++ ++ unsigned char effect1; /* effect 1 */ ++ unsigned char effect1_depth; /* 0-127 */ ++ unsigned char effect2; /* effect 2 */ ++ unsigned char effect2_depth; /* 0-127 */ ++ ++ gf1_wave_t *wave; /* first waveform */ ++} gf1_instrument_t; ++ ++typedef struct gf1_xwave { ++ __u32 stype; /* structure type */ ++ ++ __u32 share_id[4]; /* share id - zero = no sharing */ ++ __u32 format; /* wave format */ ++ ++ __u32 size; /* size of waveform in samples */ ++ __u32 start; /* start offset in samples * 16 (lowest 4 bits - fraction) */ ++ __u32 loop_start; /* bits loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ __u32 loop_end; /* loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ __u16 loop_repeat; /* loop repeat - 0 = forever */ ++ ++ __u8 flags; /* GF1 patch flags */ ++ __u8 pad; ++ __u32 sample_rate; /* sample rate in Hz */ ++ __u32 low_frequency; /* low frequency range */ ++ __u32 high_frequency; /* high frequency range */ ++ __u32 root_frequency; /* root frequency range */ ++ __s16 tune; ++ __u8 balance; ++ __u8 envelope_rate[6]; ++ __u8 envelope_offset[6]; ++ __u8 tremolo_sweep; ++ __u8 tremolo_rate; ++ __u8 tremolo_depth; ++ __u8 vibrato_sweep; ++ __u8 vibrato_rate; ++ __u8 vibrato_depth; ++ __u16 scale_frequency; ++ __u16 scale_factor; /* 0-2048 or 0-2 */ ++} gf1_xwave_t; ++ ++typedef struct gf1_xinstrument { ++ __u32 stype; ++ ++ __u16 exclusion; ++ __u16 exclusion_group; /* 0 - none, 1-65535 */ ++ ++ __u8 effect1; /* effect 1 */ ++ __u8 effect1_depth; /* 0-127 */ ++ __u8 effect2; /* effect 2 */ ++ __u8 effect2_depth; /* 0-127 */ ++} gf1_xinstrument_t; ++ ++typedef struct gf1_info { ++ unsigned char flags; /* supported wave flags */ ++ unsigned char pad[3]; ++ unsigned int features; /* supported features */ ++ unsigned int max8_len; /* maximum 8-bit wave length */ ++ unsigned int max16_len; /* maximum 16-bit wave length */ ++} gf1_info_t; ++ ++typedef struct iwffff_wave { ++ unsigned int share_id[4]; /* share id - zero = no sharing */ ++ unsigned int format; /* wave format */ ++ ++ struct { ++ unsigned int number; /* some other ID for this wave */ ++ unsigned int memory; /* begin of waveform in onboard memory */ ++ unsigned char *ptr; /* pointer to waveform in system memory */ ++ } address; ++ ++ unsigned int size; /* size of waveform in samples */ ++ unsigned int start; /* start offset in samples * 16 (lowest 4 bits - fraction) */ ++ unsigned int loop_start; /* bits loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ unsigned int loop_end; /* loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ unsigned short loop_repeat; /* loop repeat - 0 = forever */ ++ unsigned int sample_ratio; /* sample ratio (44100 * 1024 / rate) */ ++ unsigned char attenuation; /* 0 - 127 (no corresponding midi controller) */ ++ unsigned char low_note; /* lower frequency range for this waveform */ ++ unsigned char high_note; /* higher frequency range for this waveform */ ++ unsigned char pad; ++ ++ struct iwffff_wave *next; ++} iwffff_wave_t; ++ ++typedef struct iwffff_lfo { ++ unsigned short freq; /* (0-2047) 0.01Hz - 21.5Hz */ ++ signed short depth; /* volume +- (0-255) 0.48675dB/step */ ++ signed short sweep; /* 0 - 950 deciseconds */ ++ unsigned char shape; /* see to IWFFFF_LFO_SHAPE_XXXX */ ++ unsigned char delay; /* 0 - 255 deciseconds */ ++} iwffff_lfo_t; ++ ++typedef struct iwffff_env_point { ++ unsigned short offset; ++ unsigned short rate; ++} iwffff_env_point_t; ++ ++typedef struct iwffff_env_record { ++ unsigned short nattack; ++ unsigned short nrelease; ++ unsigned short sustain_offset; ++ unsigned short sustain_rate; ++ unsigned short release_rate; ++ unsigned char hirange; ++ unsigned char pad; ++ struct iwffff_env_record *next; ++ /* points are stored here */ ++ /* count of points = nattack + nrelease */ ++} iwffff_env_record_t; ++ ++typedef struct iwffff_env { ++ unsigned char flags; ++ unsigned char mode; ++ unsigned char index; ++ unsigned char pad; ++ struct iwffff_env_record *record; ++} iwffff_env_t; ++ ++typedef struct iwffff_layer { ++ unsigned char flags; ++ unsigned char velocity_mode; ++ unsigned char layer_event; ++ unsigned char low_range; /* range for layer based */ ++ unsigned char high_range; /* on either velocity or frequency */ ++ unsigned char pan; /* pan offset from CC1 (0 left - 127 right) */ ++ unsigned char pan_freq_scale; /* position based on frequency (0-127) */ ++ unsigned char attenuation; /* 0-127 (no corresponding midi controller) */ ++ iwffff_lfo_t tremolo; /* tremolo effect */ ++ iwffff_lfo_t vibrato; /* vibrato effect */ ++ unsigned short freq_scale; /* 0-2048, 1024 is equal to semitone scaling */ ++ unsigned char freq_center; /* center for keyboard frequency scaling */ ++ unsigned char pad; ++ iwffff_env_t penv; /* pitch envelope */ ++ iwffff_env_t venv; /* volume envelope */ ++ ++ iwffff_wave_t *wave; ++ struct iwffff_layer *next; ++} iwffff_layer_t; ++ ++typedef struct { ++ unsigned short exclusion; ++ unsigned short layer_type; ++ unsigned short exclusion_group; /* 0 - none, 1-65535 */ ++ ++ unsigned char effect1; /* effect 1 */ ++ unsigned char effect1_depth; /* 0-127 */ ++ unsigned char effect2; /* effect 2 */ ++ unsigned char effect2_depth; /* 0-127 */ ++ ++ iwffff_layer_t *layer; /* first layer */ ++} iwffff_instrument_t; ++ ++typedef struct iwffff_xwave { ++ __u32 stype; /* structure type */ ++ ++ __u32 share_id[4]; /* share id - zero = no sharing */ ++ ++ __u32 format; /* wave format */ ++ __u32 offset; /* offset to ROM (address) */ ++ ++ __u32 size; /* size of waveform in samples */ ++ __u32 start; /* start offset in samples * 16 (lowest 4 bits - fraction) */ ++ __u32 loop_start; /* bits loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ __u32 loop_end; /* loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ __u16 loop_repeat; /* loop repeat - 0 = forever */ ++ __u32 sample_ratio; /* sample ratio (44100 * 1024 / rate) */ ++ __u8 attenuation; /* 0 - 127 (no corresponding midi controller) */ ++ __u8 low_note; /* lower frequency range for this waveform */ ++ __u8 high_note; /* higher frequency range for this waveform */ ++ __u8 pad; ++} iwffff_xwave_t; ++ ++typedef struct iwffff_xlfo { ++ __u16 freq; /* (0-2047) 0.01Hz - 21.5Hz */ ++ __s16 depth; /* volume +- (0-255) 0.48675dB/step */ ++ __s16 sweep; /* 0 - 950 deciseconds */ ++ __u8 shape; /* see to ULTRA_IW_LFO_SHAPE_XXXX */ ++ __u8 delay; /* 0 - 255 deciseconds */ ++} iwffff_xlfo_t; ++ ++typedef struct iwffff_xenv_point { ++ __u16 offset; ++ __u16 rate; ++} iwffff_xenv_point_t; ++ ++typedef struct iwffff_xenv_record { ++ __u32 stype; ++ __u16 nattack; ++ __u16 nrelease; ++ __u16 sustain_offset; ++ __u16 sustain_rate; ++ __u16 release_rate; ++ __u8 hirange; ++ __u8 pad; ++ /* points are stored here.. */ ++ /* count of points = nattack + nrelease */ ++} iwffff_xenv_record_t; ++ ++typedef struct iwffff_xenv { ++ __u8 flags; ++ __u8 mode; ++ __u8 index; ++ __u8 pad; ++} iwffff_xenv_t; ++ ++typedef struct iwffff_xlayer { ++ __u32 stype; ++ __u8 flags; ++ __u8 velocity_mode; ++ __u8 layer_event; ++ __u8 low_range; /* range for layer based */ ++ __u8 high_range; /* on either velocity or frequency */ ++ __u8 pan; /* pan offset from CC1 (0 left - 127 right) */ ++ __u8 pan_freq_scale; /* position based on frequency (0-127) */ ++ __u8 attenuation; /* 0-127 (no corresponding midi controller) */ ++ iwffff_xlfo_t tremolo; /* tremolo effect */ ++ iwffff_xlfo_t vibrato; /* vibrato effect */ ++ __u16 freq_scale; /* 0-2048, 1024 is equal to semitone scaling */ ++ __u8 freq_center; /* center for keyboard frequency scaling */ ++ __u8 pad; ++ iwffff_xenv_t penv; /* pitch envelope */ ++ iwffff_xenv_t venv; /* volume envelope */ ++} iwffff_xlayer_t; ++ ++typedef struct iwffff_xinstrument { ++ __u32 stype; ++ ++ __u16 exclusion; ++ __u16 layer_type; ++ __u16 exclusion_group; /* 0 - none, 1-65535 */ ++ ++ __u8 effect1; /* effect 1 */ ++ __u8 effect1_depth; /* 0-127 */ ++ __u8 effect2; /* effect 2 */ ++ __u8 effect2_depth; /* 0-127 */ ++} iwffff_xinstrument_t; ++ ++typedef struct { ++ __u8 iwave[8]; ++ __u8 revision; ++ __u8 series_number; ++ __u8 series_name[16]; ++ __u8 date[10]; ++ __u16 vendor_revision_major; ++ __u16 vendor_revision_minor; ++ __u32 rom_size; ++ __u8 copyright[128]; ++ __u8 vendor_name[64]; ++ __u8 description[128]; ++} iwffff_rom_header_t; ++ ++typedef struct iwffff_info { ++ unsigned int format; /* supported format bits */ ++ unsigned int effects; /* supported effects (1 << IWFFFF_EFFECT*) */ ++ unsigned int lfos; /* LFO effects */ ++ unsigned int max8_len; /* maximum 8-bit wave length */ ++ unsigned int max16_len; /* maximum 16-bit wave length */ ++} iwffff_info_t; ++ ++typedef struct simple_instrument_info { ++ unsigned int format; /* supported format bits */ ++ unsigned int effects; /* supported effects (1 << SIMPLE_EFFECT_*) */ ++ unsigned int max8_len; /* maximum 8-bit wave length */ ++ unsigned int max16_len; /* maximum 16-bit wave length */ ++} simple_instrument_info_t; ++ ++typedef struct { ++ unsigned int share_id[4]; /* share id - zero = no sharing */ ++ unsigned int format; /* wave format */ ++ ++ struct { ++ unsigned int number; /* some other ID for this instrument */ ++ unsigned int memory; /* begin of waveform in onboard memory */ ++ unsigned char *ptr; /* pointer to waveform in system memory */ ++ } address; ++ ++ unsigned int size; /* size of waveform in samples */ ++ unsigned int start; /* start offset in samples * 16 (lowest 4 bits - fraction) */ ++ unsigned int loop_start; /* loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ unsigned int loop_end; /* loop end offset in samples * 16 (lowest 4 bits - fraction) */ ++ unsigned short loop_repeat; /* loop repeat - 0 = forever */ ++ ++ unsigned char effect1; /* effect 1 */ ++ unsigned char effect1_depth; /* 0-127 */ ++ unsigned char effect2; /* effect 2 */ ++ unsigned char effect2_depth; /* 0-127 */ ++} simple_instrument_t; ++ ++typedef struct simple_xinstrument { ++ __u32 stype; ++ ++ __u32 share_id[4]; /* share id - zero = no sharing */ ++ __u32 format; /* wave format */ ++ ++ __u32 size; /* size of waveform in samples */ ++ __u32 start; /* start offset in samples * 16 (lowest 4 bits - fraction) */ ++ __u32 loop_start; /* bits loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ __u32 loop_end; /* loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ __u16 loop_repeat; /* loop repeat - 0 = forever */ ++ ++ __u8 effect1; /* effect 1 */ ++ __u8 effect1_depth; /* 0-127 */ ++ __u8 effect2; /* effect 2 */ ++ __u8 effect2_depth; /* 0-127 */ ++} simple_xinstrument_t; ++ ++typedef unsigned char sndrv_seq_event_type_t; ++ ++/** event address */ ++struct sndrv_seq_addr { ++ unsigned char client; /**< Client number: 0..255, 255 = broadcast to all clients */ ++ unsigned char port; /**< Port within client: 0..255, 255 = broadcast to all ports */ ++}; ++ ++/** port connection */ ++struct sndrv_seq_connect { ++ struct sndrv_seq_addr sender; ++ struct sndrv_seq_addr dest; ++}; ++ ++struct sndrv_seq_ev_note { ++ unsigned char channel; ++ unsigned char note; ++ unsigned char velocity; ++ unsigned char off_velocity; /* only for SNDRV_SEQ_EVENT_NOTE */ ++ unsigned int duration; /* only for SNDRV_SEQ_EVENT_NOTE */ ++}; ++ ++ /* controller event */ ++struct sndrv_seq_ev_ctrl { ++ unsigned char channel; ++ unsigned char unused1, unused2, unused3; /* pad */ ++ unsigned int param; ++ signed int value; ++}; ++ ++ /* generic set of bytes (12x8 bit) */ ++struct sndrv_seq_ev_raw8 { ++ unsigned char d[12]; /* 8 bit value */ ++}; ++ ++ /* generic set of integers (3x32 bit) */ ++struct sndrv_seq_ev_raw32 { ++ unsigned int d[3]; /* 32 bit value */ ++}; ++ ++ /* external stored data */ ++struct sndrv_seq_ev_ext { ++ unsigned int len; /* length of data */ ++ void *ptr; /* pointer to data (note: maybe 64-bit) */ ++} __attribute__((packed)); ++ ++/* Instrument cluster type */ ++typedef unsigned int sndrv_seq_instr_cluster_t; ++ ++/* Instrument type */ ++struct sndrv_seq_instr { ++ sndrv_seq_instr_cluster_t cluster; ++ unsigned int std; /* the upper byte means a private instrument (owner - client #) */ ++ unsigned short bank; ++ unsigned short prg; ++}; ++ ++ /* sample number */ ++struct sndrv_seq_ev_sample { ++ unsigned int std; ++ unsigned short bank; ++ unsigned short prg; ++}; ++ ++ /* sample cluster */ ++struct sndrv_seq_ev_cluster { ++ sndrv_seq_instr_cluster_t cluster; ++}; ++ ++ /* sample position */ ++typedef unsigned int sndrv_seq_position_t; /* playback position (in samples) * 16 */ ++ ++ /* sample stop mode */ ++enum sndrv_seq_stop_mode { ++ SAMPLE_STOP_IMMEDIATELY = 0, /* terminate playing immediately */ ++ SAMPLE_STOP_VENVELOPE = 1, /* finish volume envelope */ ++ SAMPLE_STOP_LOOP = 2 /* terminate loop and finish wave */ ++}; ++ ++ /* sample frequency */ ++typedef int sndrv_seq_frequency_t; /* playback frequency in HZ * 16 */ ++ ++ /* sample volume control; if any value is set to -1 == do not change */ ++struct sndrv_seq_ev_volume { ++ signed short volume; /* range: 0-16383 */ ++ signed short lr; /* left-right balance; range: 0-16383 */ ++ signed short fr; /* front-rear balance; range: 0-16383 */ ++ signed short du; /* down-up balance; range: 0-16383 */ ++}; ++ ++ /* simple loop redefinition */ ++struct sndrv_seq_ev_loop { ++ unsigned int start; /* loop start (in samples) * 16 */ ++ unsigned int end; /* loop end (in samples) * 16 */ ++}; ++ ++struct sndrv_seq_ev_sample_control { ++ unsigned char channel; ++ unsigned char unused1, unused2, unused3; /* pad */ ++ union { ++ struct sndrv_seq_ev_sample sample; ++ struct sndrv_seq_ev_cluster cluster; ++ sndrv_seq_position_t position; ++ int stop_mode; ++ sndrv_seq_frequency_t frequency; ++ struct sndrv_seq_ev_volume volume; ++ struct sndrv_seq_ev_loop loop; ++ unsigned char raw8[8]; ++ } param; ++}; ++ ++ ++ ++/* INSTR_BEGIN event */ ++struct sndrv_seq_ev_instr_begin { ++ int timeout; /* zero = forever, otherwise timeout in ms */ ++}; ++ ++struct sndrv_seq_result { ++ int event; /* processed event type */ ++ int result; ++}; ++ ++ ++struct sndrv_seq_real_time { ++ unsigned int tv_sec; /* seconds */ ++ unsigned int tv_nsec; /* nanoseconds */ ++}; ++ ++typedef unsigned int sndrv_seq_tick_time_t; /* midi ticks */ ++ ++union sndrv_seq_timestamp { ++ sndrv_seq_tick_time_t tick; ++ struct sndrv_seq_real_time time; ++}; ++ ++struct sndrv_seq_queue_skew { ++ unsigned int value; ++ unsigned int base; ++}; ++ ++ /* queue timer control */ ++struct sndrv_seq_ev_queue_control { ++ unsigned char queue; /* affected queue */ ++ unsigned char pad[3]; /* reserved */ ++ union { ++ signed int value; /* affected value (e.g. tempo) */ ++ union sndrv_seq_timestamp time; /* time */ ++ unsigned int position; /* sync position */ ++ struct sndrv_seq_queue_skew skew; ++ unsigned int d32[2]; ++ unsigned char d8[8]; ++ } param; ++}; ++ ++ /* quoted event - inside the kernel only */ ++struct sndrv_seq_ev_quote { ++ struct sndrv_seq_addr origin; /* original sender */ ++ unsigned short value; /* optional data */ ++ struct sndrv_seq_event *event; /* quoted event */ ++} __attribute__((packed)); ++ ++ ++ /* sequencer event */ ++struct sndrv_seq_event { ++ sndrv_seq_event_type_t type; /* event type */ ++ unsigned char flags; /* event flags */ ++ char tag; ++ ++ unsigned char queue; /* schedule queue */ ++ union sndrv_seq_timestamp time; /* schedule time */ ++ ++ ++ struct sndrv_seq_addr source; /* source address */ ++ struct sndrv_seq_addr dest; /* destination address */ ++ ++ union { /* event data... */ ++ struct sndrv_seq_ev_note note; ++ struct sndrv_seq_ev_ctrl control; ++ struct sndrv_seq_ev_raw8 raw8; ++ struct sndrv_seq_ev_raw32 raw32; ++ struct sndrv_seq_ev_ext ext; ++ struct sndrv_seq_ev_queue_control queue; ++ union sndrv_seq_timestamp time; ++ struct sndrv_seq_addr addr; ++ struct sndrv_seq_connect connect; ++ struct sndrv_seq_result result; ++ struct sndrv_seq_ev_instr_begin instr_begin; ++ struct sndrv_seq_ev_sample_control sample; ++ struct sndrv_seq_ev_quote quote; ++ } data; ++}; ++ ++ ++/* ++ * bounce event - stored as variable size data ++ */ ++struct sndrv_seq_event_bounce { ++ int err; ++ struct sndrv_seq_event event; ++ /* external data follows here. */ ++}; ++ ++struct sndrv_seq_system_info { ++ int queues; /* maximum queues count */ ++ int clients; /* maximum clients count */ ++ int ports; /* maximum ports per client */ ++ int channels; /* maximum channels per port */ ++ int cur_clients; /* current clients */ ++ int cur_queues; /* current queues */ ++ char reserved[24]; ++}; ++ ++struct sndrv_seq_running_info { ++ unsigned char client; /* client id */ ++ unsigned char big_endian; /* 1 = big-endian */ ++ unsigned char cpu_mode; /* 4 = 32bit, 8 = 64bit */ ++ unsigned char pad; /* reserved */ ++ unsigned char reserved[12]; ++}; ++ ++enum sndrv_seq_client_type { ++ NO_CLIENT = 0, ++ USER_CLIENT = 1, ++ KERNEL_CLIENT = 2 ++}; ++ ++struct sndrv_seq_client_info { ++ int client; /* client number to inquire */ ++ int type; /* client type */ ++ char name[64]; /* client name */ ++ unsigned int filter; /* filter flags */ ++ unsigned char multicast_filter[8]; /* multicast filter bitmap */ ++ unsigned char event_filter[32]; /* event filter bitmap */ ++ int num_ports; /* RO: number of ports */ ++ int event_lost; /* number of lost events */ ++ char reserved[64]; /* for future use */ ++}; ++ ++struct sndrv_seq_client_pool { ++ int client; /* client number to inquire */ ++ int output_pool; /* outgoing (write) pool size */ ++ int input_pool; /* incoming (read) pool size */ ++ int output_room; /* minimum free pool size for select/blocking mode */ ++ int output_free; /* unused size */ ++ int input_free; /* unused size */ ++ char reserved[64]; ++}; ++ ++struct sndrv_seq_remove_events { ++ unsigned int remove_mode; /* Flags that determine what gets removed */ ++ ++ union sndrv_seq_timestamp time; ++ ++ unsigned char queue; /* Queue for REMOVE_DEST */ ++ struct sndrv_seq_addr dest; /* Address for REMOVE_DEST */ ++ unsigned char channel; /* Channel for REMOVE_DEST */ ++ ++ int type; /* For REMOVE_EVENT_TYPE */ ++ char tag; /* Tag for REMOVE_TAG */ ++ ++ int reserved[10]; /* To allow for future binary compatibility */ ++ ++}; ++ ++struct sndrv_seq_port_info { ++ struct sndrv_seq_addr addr; /* client/port numbers */ ++ char name[64]; /* port name */ ++ ++ unsigned int capability; /* port capability bits */ ++ unsigned int type; /* port type bits */ ++ int midi_channels; /* channels per MIDI port */ ++ int midi_voices; /* voices per MIDI port */ ++ int synth_voices; /* voices per SYNTH port */ ++ ++ int read_use; /* R/O: subscribers for output (from this port) */ ++ int write_use; /* R/O: subscribers for input (to this port) */ ++ ++ void *kernel; /* reserved for kernel use (must be NULL) */ ++ unsigned int flags; /* misc. conditioning */ ++ unsigned char time_queue; /* queue # for timestamping */ ++ char reserved[59]; /* for future use */ ++}; ++ ++struct sndrv_seq_queue_info { ++ int queue; /* queue id */ ++ ++ /* ++ * security settings, only owner of this queue can start/stop timer ++ * etc. if the queue is locked for other clients ++ */ ++ int owner; /* client id for owner of the queue */ ++ int locked:1; /* timing queue locked for other queues */ ++ char name[64]; /* name of this queue */ ++ unsigned int flags; /* flags */ ++ char reserved[60]; /* for future use */ ++ ++}; ++ ++struct sndrv_seq_queue_status { ++ int queue; /* queue id */ ++ int events; /* read-only - queue size */ ++ sndrv_seq_tick_time_t tick; /* current tick */ ++ struct sndrv_seq_real_time time; /* current time */ ++ int running; /* running state of queue */ ++ int flags; /* various flags */ ++ char reserved[64]; /* for the future */ ++}; ++ ++struct sndrv_seq_queue_tempo { ++ int queue; /* sequencer queue */ ++ unsigned int tempo; /* current tempo, us/tick */ ++ int ppq; /* time resolution, ticks/quarter */ ++ unsigned int skew_value; /* queue skew */ ++ unsigned int skew_base; /* queue skew base */ ++ char reserved[24]; /* for the future */ ++}; ++ ++struct sndrv_timer_id { ++ int dev_class; ++ int dev_sclass; ++ int card; ++ int device; ++ int subdevice; ++}; ++ ++struct sndrv_seq_queue_timer { ++ int queue; /* sequencer queue */ ++ int type; /* source timer type */ ++ union { ++ struct { ++ struct sndrv_timer_id id; /* ALSA's timer ID */ ++ unsigned int resolution; /* resolution in Hz */ ++ } alsa; ++ } u; ++ char reserved[64]; /* for the future use */ ++}; ++ ++struct sndrv_seq_queue_client { ++ int queue; /* sequencer queue */ ++ int client; /* sequencer client */ ++ int used; /* queue is used with this client ++ (must be set for accepting events) */ ++ /* per client watermarks */ ++ char reserved[64]; /* for future use */ ++}; ++ ++struct sndrv_seq_port_subscribe { ++ struct sndrv_seq_addr sender; /* sender address */ ++ struct sndrv_seq_addr dest; /* destination address */ ++ unsigned int voices; /* number of voices to be allocated (0 = don't care) */ ++ unsigned int flags; /* modes */ ++ unsigned char queue; /* input time-stamp queue (optional) */ ++ unsigned char pad[3]; /* reserved */ ++ char reserved[64]; ++}; ++ ++struct sndrv_seq_query_subs { ++ struct sndrv_seq_addr root; /* client/port id to be searched */ ++ int type; /* READ or WRITE */ ++ int index; /* 0..N-1 */ ++ int num_subs; /* R/O: number of subscriptions on this port */ ++ struct sndrv_seq_addr addr; /* R/O: result */ ++ unsigned char queue; /* R/O: result */ ++ unsigned int flags; /* R/O: result */ ++ char reserved[64]; /* for future use */ ++}; ++ ++/* size of ROM/RAM */ ++typedef unsigned int sndrv_seq_instr_size_t; ++ ++struct sndrv_seq_instr_info { ++ int result; /* operation result */ ++ unsigned int formats[8]; /* bitmap of supported formats */ ++ int ram_count; /* count of RAM banks */ ++ sndrv_seq_instr_size_t ram_sizes[16]; /* size of RAM banks */ ++ int rom_count; /* count of ROM banks */ ++ sndrv_seq_instr_size_t rom_sizes[8]; /* size of ROM banks */ ++ char reserved[128]; ++}; ++ ++struct sndrv_seq_instr_status { ++ int result; /* operation result */ ++ sndrv_seq_instr_size_t free_ram[16]; /* free RAM in banks */ ++ int instrument_count; /* count of downloaded instruments */ ++ char reserved[128]; ++}; ++ ++struct sndrv_seq_instr_format_info { ++ char format[16]; /* format identifier - SNDRV_SEQ_INSTR_ID_* */ ++ unsigned int len; /* max data length (without this structure) */ ++}; ++ ++struct sndrv_seq_instr_format_info_result { ++ int result; /* operation result */ ++ char format[16]; /* format identifier */ ++ unsigned int len; /* filled data length (without this structure) */ ++}; ++ ++struct sndrv_seq_instr_data { ++ char name[32]; /* instrument name */ ++ char reserved[16]; /* for the future use */ ++ int type; /* instrument type */ ++ union { ++ char format[16]; /* format identifier */ ++ struct sndrv_seq_instr alias; ++ } data; ++}; ++ ++struct sndrv_seq_instr_header { ++ union { ++ struct sndrv_seq_instr instr; ++ sndrv_seq_instr_cluster_t cluster; ++ } id; /* instrument identifier */ ++ unsigned int cmd; /* get/put/free command */ ++ unsigned int flags; /* query flags (only for get) */ ++ unsigned int len; /* real instrument data length (without header) */ ++ int result; /* operation result */ ++ char reserved[16]; /* for the future */ ++ struct sndrv_seq_instr_data data; /* instrument data (for put/get result) */ ++}; ++ ++struct sndrv_seq_instr_cluster_set { ++ sndrv_seq_instr_cluster_t cluster; /* cluster identifier */ ++ char name[32]; /* cluster name */ ++ int priority; /* cluster priority */ ++ char reserved[64]; /* for the future use */ ++}; ++ ++struct sndrv_seq_instr_cluster_get { ++ sndrv_seq_instr_cluster_t cluster; /* cluster identifier */ ++ char name[32]; /* cluster name */ ++ int priority; /* cluster priority */ ++ char reserved[64]; /* for the future use */ ++}; ++ ++typedef struct snd_dm_fm_info { ++ unsigned char fm_mode; /* OPL mode, see SNDRV_DM_FM_MODE_XXX */ ++ unsigned char rhythm; /* percussion mode flag */ ++} snd_dm_fm_info_t; ++ ++typedef struct snd_dm_fm_voice { ++ unsigned char op; /* operator cell (0 or 1) */ ++ unsigned char voice; /* FM voice (0 to 17) */ ++ ++ unsigned char am; /* amplitude modulation */ ++ unsigned char vibrato; /* vibrato effect */ ++ unsigned char do_sustain; /* sustain phase */ ++ unsigned char kbd_scale; /* keyboard scaling */ ++ unsigned char harmonic; /* 4 bits: harmonic and multiplier */ ++ unsigned char scale_level; /* 2 bits: decrease output freq rises */ ++ unsigned char volume; /* 6 bits: volume */ ++ ++ unsigned char attack; /* 4 bits: attack rate */ ++ unsigned char decay; /* 4 bits: decay rate */ ++ unsigned char sustain; /* 4 bits: sustain level */ ++ unsigned char release; /* 4 bits: release rate */ ++ ++ unsigned char feedback; /* 3 bits: feedback for op0 */ ++ unsigned char connection; /* 0 for serial, 1 for parallel */ ++ unsigned char left; /* stereo left */ ++ unsigned char right; /* stereo right */ ++ unsigned char waveform; /* 3 bits: waveform shape */ ++} snd_dm_fm_voice_t; ++ ++typedef struct snd_dm_fm_note { ++ unsigned char voice; /* 0-17 voice channel */ ++ unsigned char octave; /* 3 bits: what octave to play */ ++ unsigned int fnum; /* 10 bits: frequency number */ ++ unsigned char key_on; /* set for active, clear for silent */ ++} snd_dm_fm_note_t; ++ ++typedef struct snd_dm_fm_params { ++ unsigned char am_depth; /* amplitude modulation depth (1=hi) */ ++ unsigned char vib_depth; /* vibrato depth (1=hi) */ ++ unsigned char kbd_split; /* keyboard split */ ++ unsigned char rhythm; /* percussion mode select */ ++ ++ /* This block is the percussion instrument data */ ++ unsigned char bass; ++ unsigned char snare; ++ unsigned char tomtom; ++ unsigned char cymbal; ++ unsigned char hihat; ++} snd_dm_fm_params_t; ++ ++#include ++#if __BYTE_ORDER == __LITTLE_ENDIAN ++#define SNDRV_LITTLE_ENDIAN ++#elif __BYTE_ORDER == __BIG_ENDIAN ++#define SNDRV_BIG_ENDIAN ++#else ++#error "Unsupported endian..." ++#endif ++ ++#include ++#include ++ ++struct sndrv_aes_iec958 { ++ unsigned char status[24]; /* AES/IEC958 channel status bits */ ++ unsigned char subcode[147]; /* AES/IEC958 subcode bits */ ++ unsigned char pad; /* nothing */ ++ unsigned char dig_subframe[4]; /* AES/IEC958 subframe bits */ ++}; ++ ++enum sndrv_hwdep_iface { ++ SNDRV_HWDEP_IFACE_OPL2 = 0, ++ SNDRV_HWDEP_IFACE_OPL3, ++ SNDRV_HWDEP_IFACE_OPL4, ++ SNDRV_HWDEP_IFACE_SB16CSP, /* Creative Signal Processor */ ++ SNDRV_HWDEP_IFACE_EMU10K1, /* FX8010 processor in EMU10K1 chip */ ++ SNDRV_HWDEP_IFACE_YSS225, /* Yamaha FX processor */ ++ SNDRV_HWDEP_IFACE_ICS2115, /* Wavetable synth */ ++ SNDRV_HWDEP_IFACE_SSCAPE, /* Ensoniq SoundScape ISA card (MC68EC000) */ ++ SNDRV_HWDEP_IFACE_VX, /* Digigram VX cards */ ++ SNDRV_HWDEP_IFACE_MIXART, /* Digigram miXart cards */ ++ SNDRV_HWDEP_IFACE_USX2Y, /* Tascam US122, US224 & US428 usb */ ++ SNDRV_HWDEP_IFACE_EMUX_WAVETABLE, /* EmuX wavetable */ ++ SNDRV_HWDEP_IFACE_BLUETOOTH, /* Bluetooth audio */ ++ SNDRV_HWDEP_IFACE_USX2Y_PCM, /* Tascam US122, US224 & US428 rawusb pcm */ ++ SNDRV_HWDEP_IFACE_PCXHR, /* Digigram PCXHR */ ++ SNDRV_HWDEP_IFACE_SB_RC, /* SB Extigy/Audigy2NX remote control */ ++ ++ /* Don't forget to change the following: */ ++ SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_SB_RC ++}; ++ ++struct sndrv_hwdep_info { ++ unsigned int device; /* WR: device number */ ++ int card; /* R: card number */ ++ unsigned char id[64]; /* ID (user selectable) */ ++ unsigned char name[80]; /* hwdep name */ ++ int iface; /* hwdep interface */ ++ unsigned char reserved[64]; /* reserved for future */ ++}; ++ ++/* generic DSP loader */ ++struct sndrv_hwdep_dsp_status { ++ unsigned int version; /* R: driver-specific version */ ++ unsigned char id[32]; /* R: driver-specific ID string */ ++ unsigned int num_dsps; /* R: number of DSP images to transfer */ ++ unsigned int dsp_loaded; /* R: bit flags indicating the loaded DSPs */ ++ unsigned int chip_ready; /* R: 1 = initialization finished */ ++ unsigned char reserved[16]; /* reserved for future use */ ++}; ++ ++struct sndrv_hwdep_dsp_image { ++ unsigned int index; /* W: DSP index */ ++ unsigned char name[64]; /* W: ID (e.g. file name) */ ++ unsigned char *image; /* W: binary image */ ++ size_t length; /* W: size of image in bytes */ ++ unsigned long driver_data; /* W: driver-specific data */ ++}; ++ ++typedef unsigned long sndrv_pcm_uframes_t; ++typedef long sndrv_pcm_sframes_t; ++ ++enum sndrv_pcm_class { ++ SNDRV_PCM_CLASS_GENERIC = 0, /* standard mono or stereo device */ ++ SNDRV_PCM_CLASS_MULTI, /* multichannel device */ ++ SNDRV_PCM_CLASS_MODEM, /* software modem class */ ++ SNDRV_PCM_CLASS_DIGITIZER, /* digitizer class */ ++ /* Don't forget to change the following: */ ++ SNDRV_PCM_CLASS_LAST = SNDRV_PCM_CLASS_DIGITIZER, ++}; ++ ++enum sndrv_pcm_subclass { ++ SNDRV_PCM_SUBCLASS_GENERIC_MIX = 0, /* mono or stereo subdevices are mixed together */ ++ SNDRV_PCM_SUBCLASS_MULTI_MIX, /* multichannel subdevices are mixed together */ ++ /* Don't forget to change the following: */ ++ SNDRV_PCM_SUBCLASS_LAST = SNDRV_PCM_SUBCLASS_MULTI_MIX, ++}; ++ ++enum sndrv_pcm_stream { ++ SNDRV_PCM_STREAM_PLAYBACK = 0, ++ SNDRV_PCM_STREAM_CAPTURE, ++ SNDRV_PCM_STREAM_LAST = SNDRV_PCM_STREAM_CAPTURE, ++}; ++ ++enum sndrv_pcm_access { ++ SNDRV_PCM_ACCESS_MMAP_INTERLEAVED = 0, /* interleaved mmap */ ++ SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED, /* noninterleaved mmap */ ++ SNDRV_PCM_ACCESS_MMAP_COMPLEX, /* complex mmap */ ++ SNDRV_PCM_ACCESS_RW_INTERLEAVED, /* readi/writei */ ++ SNDRV_PCM_ACCESS_RW_NONINTERLEAVED, /* readn/writen */ ++ SNDRV_PCM_ACCESS_LAST = SNDRV_PCM_ACCESS_RW_NONINTERLEAVED, ++}; ++ ++enum sndrv_pcm_format { ++ SNDRV_PCM_FORMAT_S8 = 0, ++ SNDRV_PCM_FORMAT_U8, ++ SNDRV_PCM_FORMAT_S16_LE, ++ SNDRV_PCM_FORMAT_S16_BE, ++ SNDRV_PCM_FORMAT_U16_LE, ++ SNDRV_PCM_FORMAT_U16_BE, ++ SNDRV_PCM_FORMAT_S24_LE, /* low three bytes */ ++ SNDRV_PCM_FORMAT_S24_BE, /* low three bytes */ ++ SNDRV_PCM_FORMAT_U24_LE, /* low three bytes */ ++ SNDRV_PCM_FORMAT_U24_BE, /* low three bytes */ ++ SNDRV_PCM_FORMAT_S32_LE, ++ SNDRV_PCM_FORMAT_S32_BE, ++ SNDRV_PCM_FORMAT_U32_LE, ++ SNDRV_PCM_FORMAT_U32_BE, ++ SNDRV_PCM_FORMAT_FLOAT_LE, /* 4-byte float, IEEE-754 32-bit, range -1.0 to 1.0 */ ++ SNDRV_PCM_FORMAT_FLOAT_BE, /* 4-byte float, IEEE-754 32-bit, range -1.0 to 1.0 */ ++ SNDRV_PCM_FORMAT_FLOAT64_LE, /* 8-byte float, IEEE-754 64-bit, range -1.0 to 1.0 */ ++ SNDRV_PCM_FORMAT_FLOAT64_BE, /* 8-byte float, IEEE-754 64-bit, range -1.0 to 1.0 */ ++ SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE, /* IEC-958 subframe, Little Endian */ ++ SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE, /* IEC-958 subframe, Big Endian */ ++ SNDRV_PCM_FORMAT_MU_LAW, ++ SNDRV_PCM_FORMAT_A_LAW, ++ SNDRV_PCM_FORMAT_IMA_ADPCM, ++ SNDRV_PCM_FORMAT_MPEG, ++ SNDRV_PCM_FORMAT_GSM, ++ SNDRV_PCM_FORMAT_SPECIAL = 31, ++ SNDRV_PCM_FORMAT_S24_3LE = 32, /* in three bytes */ ++ SNDRV_PCM_FORMAT_S24_3BE, /* in three bytes */ ++ SNDRV_PCM_FORMAT_U24_3LE, /* in three bytes */ ++ SNDRV_PCM_FORMAT_U24_3BE, /* in three bytes */ ++ SNDRV_PCM_FORMAT_S20_3LE, /* in three bytes */ ++ SNDRV_PCM_FORMAT_S20_3BE, /* in three bytes */ ++ SNDRV_PCM_FORMAT_U20_3LE, /* in three bytes */ ++ SNDRV_PCM_FORMAT_U20_3BE, /* in three bytes */ ++ SNDRV_PCM_FORMAT_S18_3LE, /* in three bytes */ ++ SNDRV_PCM_FORMAT_S18_3BE, /* in three bytes */ ++ SNDRV_PCM_FORMAT_U18_3LE, /* in three bytes */ ++ SNDRV_PCM_FORMAT_U18_3BE, /* in three bytes */ ++ SNDRV_PCM_FORMAT_LAST = SNDRV_PCM_FORMAT_U18_3BE, ++ ++#ifdef SNDRV_LITTLE_ENDIAN ++ SNDRV_PCM_FORMAT_S16 = SNDRV_PCM_FORMAT_S16_LE, ++ SNDRV_PCM_FORMAT_U16 = SNDRV_PCM_FORMAT_U16_LE, ++ SNDRV_PCM_FORMAT_S24 = SNDRV_PCM_FORMAT_S24_LE, ++ SNDRV_PCM_FORMAT_U24 = SNDRV_PCM_FORMAT_U24_LE, ++ SNDRV_PCM_FORMAT_S32 = SNDRV_PCM_FORMAT_S32_LE, ++ SNDRV_PCM_FORMAT_U32 = SNDRV_PCM_FORMAT_U32_LE, ++ SNDRV_PCM_FORMAT_FLOAT = SNDRV_PCM_FORMAT_FLOAT_LE, ++ SNDRV_PCM_FORMAT_FLOAT64 = SNDRV_PCM_FORMAT_FLOAT64_LE, ++ SNDRV_PCM_FORMAT_IEC958_SUBFRAME = SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE, ++#endif ++#ifdef SNDRV_BIG_ENDIAN ++ SNDRV_PCM_FORMAT_S16 = SNDRV_PCM_FORMAT_S16_BE, ++ SNDRV_PCM_FORMAT_U16 = SNDRV_PCM_FORMAT_U16_BE, ++ SNDRV_PCM_FORMAT_S24 = SNDRV_PCM_FORMAT_S24_BE, ++ SNDRV_PCM_FORMAT_U24 = SNDRV_PCM_FORMAT_U24_BE, ++ SNDRV_PCM_FORMAT_S32 = SNDRV_PCM_FORMAT_S32_BE, ++ SNDRV_PCM_FORMAT_U32 = SNDRV_PCM_FORMAT_U32_BE, ++ SNDRV_PCM_FORMAT_FLOAT = SNDRV_PCM_FORMAT_FLOAT_BE, ++ SNDRV_PCM_FORMAT_FLOAT64 = SNDRV_PCM_FORMAT_FLOAT64_BE, ++ SNDRV_PCM_FORMAT_IEC958_SUBFRAME = SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE, ++#endif ++}; ++ ++enum sndrv_pcm_subformat { ++ SNDRV_PCM_SUBFORMAT_STD = 0, ++ SNDRV_PCM_SUBFORMAT_LAST = SNDRV_PCM_SUBFORMAT_STD, ++}; ++ ++enum sndrv_pcm_state { ++ SNDRV_PCM_STATE_OPEN = 0, /* stream is open */ ++ SNDRV_PCM_STATE_SETUP, /* stream has a setup */ ++ SNDRV_PCM_STATE_PREPARED, /* stream is ready to start */ ++ SNDRV_PCM_STATE_RUNNING, /* stream is running */ ++ SNDRV_PCM_STATE_XRUN, /* stream reached an xrun */ ++ SNDRV_PCM_STATE_DRAINING, /* stream is draining */ ++ SNDRV_PCM_STATE_PAUSED, /* stream is paused */ ++ SNDRV_PCM_STATE_SUSPENDED, /* hardware is suspended */ ++ SNDRV_PCM_STATE_DISCONNECTED, /* hardware is disconnected */ ++ SNDRV_PCM_STATE_LAST = SNDRV_PCM_STATE_DISCONNECTED, ++}; ++ ++enum { ++ SNDRV_PCM_MMAP_OFFSET_DATA = 0x00000000, ++ SNDRV_PCM_MMAP_OFFSET_STATUS = 0x80000000, ++ SNDRV_PCM_MMAP_OFFSET_CONTROL = 0x81000000, ++}; ++ ++union sndrv_pcm_sync_id { ++ unsigned char id[16]; ++ unsigned short id16[8]; ++ unsigned int id32[4]; ++}; ++ ++struct sndrv_pcm_info { ++ unsigned int device; /* RO/WR (control): device number */ ++ unsigned int subdevice; /* RO/WR (control): subdevice number */ ++ int stream; /* RO/WR (control): stream number */ ++ int card; /* R: card number */ ++ unsigned char id[64]; /* ID (user selectable) */ ++ unsigned char name[80]; /* name of this device */ ++ unsigned char subname[32]; /* subdevice name */ ++ int dev_class; /* SNDRV_PCM_CLASS_* */ ++ int dev_subclass; /* SNDRV_PCM_SUBCLASS_* */ ++ unsigned int subdevices_count; ++ unsigned int subdevices_avail; ++ union sndrv_pcm_sync_id sync; /* hardware synchronization ID */ ++ unsigned char reserved[64]; /* reserved for future... */ ++}; ++ ++enum sndrv_pcm_hw_param { ++ SNDRV_PCM_HW_PARAM_ACCESS = 0, /* Access type */ ++ SNDRV_PCM_HW_PARAM_FIRST_MASK = SNDRV_PCM_HW_PARAM_ACCESS, ++ SNDRV_PCM_HW_PARAM_FORMAT, /* Format */ ++ SNDRV_PCM_HW_PARAM_SUBFORMAT, /* Subformat */ ++ SNDRV_PCM_HW_PARAM_LAST_MASK = SNDRV_PCM_HW_PARAM_SUBFORMAT, ++ ++ SNDRV_PCM_HW_PARAM_SAMPLE_BITS = 8, /* Bits per sample */ ++ SNDRV_PCM_HW_PARAM_FIRST_INTERVAL = SNDRV_PCM_HW_PARAM_SAMPLE_BITS, ++ SNDRV_PCM_HW_PARAM_FRAME_BITS, /* Bits per frame */ ++ SNDRV_PCM_HW_PARAM_CHANNELS, /* Channels */ ++ SNDRV_PCM_HW_PARAM_RATE, /* Approx rate */ ++ SNDRV_PCM_HW_PARAM_PERIOD_TIME, /* Approx distance between interrupts ++ in us */ ++ SNDRV_PCM_HW_PARAM_PERIOD_SIZE, /* Approx frames between interrupts */ ++ SNDRV_PCM_HW_PARAM_PERIOD_BYTES, /* Approx bytes between interrupts */ ++ SNDRV_PCM_HW_PARAM_PERIODS, /* Approx interrupts per buffer */ ++ SNDRV_PCM_HW_PARAM_BUFFER_TIME, /* Approx duration of buffer in us */ ++ SNDRV_PCM_HW_PARAM_BUFFER_SIZE, /* Size of buffer in frames */ ++ SNDRV_PCM_HW_PARAM_BUFFER_BYTES, /* Size of buffer in bytes */ ++ SNDRV_PCM_HW_PARAM_TICK_TIME, /* Approx tick duration in us */ ++ SNDRV_PCM_HW_PARAM_LAST_INTERVAL = SNDRV_PCM_HW_PARAM_TICK_TIME ++}; ++ ++struct sndrv_interval { ++ unsigned int min, max; ++ unsigned int openmin:1, ++ openmax:1, ++ integer:1, ++ empty:1; ++}; ++ ++struct sndrv_mask { ++ u_int32_t bits[(SNDRV_MASK_MAX+31)/32]; ++}; ++ ++struct sndrv_pcm_hw_params { ++ unsigned int flags; ++ struct sndrv_mask masks[SNDRV_PCM_HW_PARAM_LAST_MASK - ++ SNDRV_PCM_HW_PARAM_FIRST_MASK + 1]; ++ struct sndrv_mask mres[5]; /* reserved masks */ ++ struct sndrv_interval intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL - ++ SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1]; ++ struct sndrv_interval ires[9]; /* reserved intervals */ ++ unsigned int rmask; /* W: requested masks */ ++ unsigned int cmask; /* R: changed masks */ ++ unsigned int info; /* R: Info flags for returned setup */ ++ unsigned int msbits; /* R: used most significant bits */ ++ unsigned int rate_num; /* R: rate numerator */ ++ unsigned int rate_den; /* R: rate denominator */ ++ sndrv_pcm_uframes_t fifo_size; /* R: chip FIFO size in frames */ ++ unsigned char reserved[64]; /* reserved for future */ ++}; ++ ++enum sndrv_pcm_tstamp { ++ SNDRV_PCM_TSTAMP_NONE = 0, ++ SNDRV_PCM_TSTAMP_MMAP, ++ SNDRV_PCM_TSTAMP_LAST = SNDRV_PCM_TSTAMP_MMAP, ++}; ++ ++struct sndrv_pcm_sw_params { ++ int tstamp_mode; /* timestamp mode */ ++ unsigned int period_step; ++ unsigned int sleep_min; /* min ticks to sleep */ ++ sndrv_pcm_uframes_t avail_min; /* min avail frames for wakeup */ ++ sndrv_pcm_uframes_t xfer_align; /* xfer size need to be a multiple */ ++ sndrv_pcm_uframes_t start_threshold; /* min hw_avail frames for automatic start */ ++ sndrv_pcm_uframes_t stop_threshold; /* min avail frames for automatic stop */ ++ sndrv_pcm_uframes_t silence_threshold; /* min distance from noise for silence filling */ ++ sndrv_pcm_uframes_t silence_size; /* silence block size */ ++ sndrv_pcm_uframes_t boundary; /* pointers wrap point */ ++ unsigned char reserved[64]; /* reserved for future */ ++}; ++ ++struct sndrv_pcm_channel_info { ++ unsigned int channel; ++ long int offset; /* mmap offset */ ++ unsigned int first; /* offset to first sample in bits */ ++ unsigned int step; /* samples distance in bits */ ++}; ++ ++struct sndrv_pcm_status { ++ int state; /* stream state */ ++ struct timespec trigger_tstamp; /* time when stream was started/stopped/paused */ ++ struct timespec tstamp; /* reference timestamp */ ++ sndrv_pcm_uframes_t appl_ptr; /* appl ptr */ ++ sndrv_pcm_uframes_t hw_ptr; /* hw ptr */ ++ sndrv_pcm_sframes_t delay; /* current delay in frames */ ++ sndrv_pcm_uframes_t avail; /* number of frames available */ ++ sndrv_pcm_uframes_t avail_max; /* max frames available on hw since last status */ ++ sndrv_pcm_uframes_t overrange; /* count of ADC (capture) overrange detections from last status */ ++ int suspended_state; /* suspended stream state */ ++ unsigned char reserved[60]; /* must be filled with zero */ ++}; ++ ++struct sndrv_pcm_mmap_status { ++ int state; /* RO: state - SNDRV_PCM_STATE_XXXX */ ++ int pad1; /* Needed for 64 bit alignment */ ++ sndrv_pcm_uframes_t hw_ptr; /* RO: hw ptr (0...boundary-1) */ ++ struct timespec tstamp; /* Timestamp */ ++ int suspended_state; /* RO: suspended stream state */ ++}; ++ ++struct sndrv_pcm_mmap_control { ++ sndrv_pcm_uframes_t appl_ptr; /* RW: appl ptr (0...boundary-1) */ ++ sndrv_pcm_uframes_t avail_min; /* RW: min available frames for wakeup */ ++}; ++ ++struct sndrv_pcm_sync_ptr { ++ unsigned int flags; ++ union { ++ struct sndrv_pcm_mmap_status status; ++ unsigned char reserved[64]; ++ } s; ++ union { ++ struct sndrv_pcm_mmap_control control; ++ unsigned char reserved[64]; ++ } c; ++}; ++ ++struct sndrv_xferi { ++ sndrv_pcm_sframes_t result; ++ void *buf; ++ sndrv_pcm_uframes_t frames; ++}; ++ ++struct sndrv_xfern { ++ sndrv_pcm_sframes_t result; ++ void **bufs; ++ sndrv_pcm_uframes_t frames; ++}; ++ ++enum sndrv_rawmidi_stream { ++ SNDRV_RAWMIDI_STREAM_OUTPUT = 0, ++ SNDRV_RAWMIDI_STREAM_INPUT, ++ SNDRV_RAWMIDI_STREAM_LAST = SNDRV_RAWMIDI_STREAM_INPUT, ++}; ++ ++struct sndrv_rawmidi_info { ++ unsigned int device; /* RO/WR (control): device number */ ++ unsigned int subdevice; /* RO/WR (control): subdevice number */ ++ int stream; /* WR: stream */ ++ int card; /* R: card number */ ++ unsigned int flags; /* SNDRV_RAWMIDI_INFO_XXXX */ ++ unsigned char id[64]; /* ID (user selectable) */ ++ unsigned char name[80]; /* name of device */ ++ unsigned char subname[32]; /* name of active or selected subdevice */ ++ unsigned int subdevices_count; ++ unsigned int subdevices_avail; ++ unsigned char reserved[64]; /* reserved for future use */ ++}; ++ ++struct sndrv_rawmidi_params { ++ int stream; ++ size_t buffer_size; /* queue size in bytes */ ++ size_t avail_min; /* minimum avail bytes for wakeup */ ++ unsigned int no_active_sensing: 1; /* do not send active sensing byte in close() */ ++ unsigned char reserved[16]; /* reserved for future use */ ++}; ++ ++struct sndrv_rawmidi_status { ++ int stream; ++ struct timespec tstamp; /* Timestamp */ ++ size_t avail; /* available bytes */ ++ size_t xruns; /* count of overruns since last status (in bytes) */ ++ unsigned char reserved[16]; /* reserved for future use */ ++}; ++ ++enum sndrv_timer_class { ++ SNDRV_TIMER_CLASS_NONE = -1, ++ SNDRV_TIMER_CLASS_SLAVE = 0, ++ SNDRV_TIMER_CLASS_GLOBAL, ++ SNDRV_TIMER_CLASS_CARD, ++ SNDRV_TIMER_CLASS_PCM, ++ SNDRV_TIMER_CLASS_LAST = SNDRV_TIMER_CLASS_PCM, ++}; ++ ++/* slave timer classes */ ++enum sndrv_timer_slave_class { ++ SNDRV_TIMER_SCLASS_NONE = 0, ++ SNDRV_TIMER_SCLASS_APPLICATION, ++ SNDRV_TIMER_SCLASS_SEQUENCER, /* alias */ ++ SNDRV_TIMER_SCLASS_OSS_SEQUENCER, /* alias */ ++ SNDRV_TIMER_SCLASS_LAST = SNDRV_TIMER_SCLASS_OSS_SEQUENCER, ++}; ++ ++struct sndrv_timer_ginfo { ++ struct sndrv_timer_id tid; /* requested timer ID */ ++ unsigned int flags; /* timer flags - SNDRV_TIMER_FLG_* */ ++ int card; /* card number */ ++ unsigned char id[64]; /* timer identification */ ++ unsigned char name[80]; /* timer name */ ++ unsigned long reserved0; /* reserved for future use */ ++ unsigned long resolution; /* average period resolution in ns */ ++ unsigned long resolution_min; /* minimal period resolution in ns */ ++ unsigned long resolution_max; /* maximal period resolution in ns */ ++ unsigned int clients; /* active timer clients */ ++ unsigned char reserved[32]; ++}; ++ ++struct sndrv_timer_gparams { ++ struct sndrv_timer_id tid; /* requested timer ID */ ++ unsigned long period_num; /* requested precise period duration (in seconds) - numerator */ ++ unsigned long period_den; /* requested precise period duration (in seconds) - denominator */ ++ unsigned char reserved[32]; ++}; ++ ++struct sndrv_timer_gstatus { ++ struct sndrv_timer_id tid; /* requested timer ID */ ++ unsigned long resolution; /* current period resolution in ns */ ++ unsigned long resolution_num; /* precise current period resolution (in seconds) - numerator */ ++ unsigned long resolution_den; /* precise current period resolution (in seconds) - denominator */ ++ unsigned char reserved[32]; ++}; ++ ++struct sndrv_timer_select { ++ struct sndrv_timer_id id; /* bind to timer ID */ ++ unsigned char reserved[32]; /* reserved */ ++}; ++ ++struct sndrv_timer_info { ++ unsigned int flags; /* timer flags - SNDRV_TIMER_FLG_* */ ++ int card; /* card number */ ++ unsigned char id[64]; /* timer identificator */ ++ unsigned char name[80]; /* timer name */ ++ unsigned long reserved0; /* reserved for future use */ ++ unsigned long resolution; /* average period resolution in ns */ ++ unsigned char reserved[64]; /* reserved */ ++}; ++ ++struct sndrv_timer_params { ++ unsigned int flags; /* flags - SNDRV_MIXER_PSFLG_* */ ++ unsigned int ticks; /* requested resolution in ticks */ ++ unsigned int queue_size; /* total size of queue (32-1024) */ ++ unsigned int reserved0; /* reserved, was: failure locations */ ++ unsigned int filter; /* event filter (bitmask of SNDRV_TIMER_EVENT_*) */ ++ unsigned char reserved[60]; /* reserved */ ++}; ++ ++struct sndrv_timer_status { ++ struct timespec tstamp; /* Timestamp - last update */ ++ unsigned int resolution; /* current period resolution in ns */ ++ unsigned int lost; /* counter of master tick lost */ ++ unsigned int overrun; /* count of read queue overruns */ ++ unsigned int queue; /* used queue size */ ++ unsigned char reserved[64]; /* reserved */ ++}; ++ ++struct sndrv_timer_read { ++ unsigned int resolution; ++ unsigned int ticks; ++}; ++ ++enum sndrv_timer_event { ++ SNDRV_TIMER_EVENT_RESOLUTION = 0, /* val = resolution in ns */ ++ SNDRV_TIMER_EVENT_TICK, /* val = ticks */ ++ SNDRV_TIMER_EVENT_START, /* val = resolution in ns */ ++ SNDRV_TIMER_EVENT_STOP, /* val = 0 */ ++ SNDRV_TIMER_EVENT_CONTINUE, /* val = resolution in ns */ ++ SNDRV_TIMER_EVENT_PAUSE, /* val = 0 */ ++ SNDRV_TIMER_EVENT_EARLY, /* val = 0, early event */ ++ SNDRV_TIMER_EVENT_SUSPEND, /* val = 0 */ ++ SNDRV_TIMER_EVENT_RESUME, /* val = resolution in ns */ ++ /* master timer events for slave timer instances */ ++ SNDRV_TIMER_EVENT_MSTART = SNDRV_TIMER_EVENT_START + 10, ++ SNDRV_TIMER_EVENT_MSTOP = SNDRV_TIMER_EVENT_STOP + 10, ++ SNDRV_TIMER_EVENT_MCONTINUE = SNDRV_TIMER_EVENT_CONTINUE + 10, ++ SNDRV_TIMER_EVENT_MPAUSE = SNDRV_TIMER_EVENT_PAUSE + 10, ++ SNDRV_TIMER_EVENT_MSUSPEND = SNDRV_TIMER_EVENT_SUSPEND + 10, ++ SNDRV_TIMER_EVENT_MRESUME = SNDRV_TIMER_EVENT_RESUME + 10, ++}; ++ ++struct sndrv_timer_tread { ++ int event; ++ struct timespec tstamp; ++ unsigned int val; ++}; ++ ++struct sndrv_ctl_card_info { ++ int card; /* card number */ ++ int pad; /* reserved for future (was type) */ ++ unsigned char id[16]; /* ID of card (user selectable) */ ++ unsigned char driver[16]; /* Driver name */ ++ unsigned char name[32]; /* Short name of soundcard */ ++ unsigned char longname[80]; /* name + info text about soundcard */ ++ unsigned char reserved_[16]; /* reserved for future (was ID of mixer) */ ++ unsigned char mixername[80]; /* visual mixer identification */ ++ unsigned char components[80]; /* card components / fine identification, delimited with one space (AC97 etc..) */ ++ unsigned char reserved[48]; /* reserved for future */ ++}; ++ ++enum sndrv_ctl_elem_type { ++ SNDRV_CTL_ELEM_TYPE_NONE = 0, /* invalid */ ++ SNDRV_CTL_ELEM_TYPE_BOOLEAN, /* boolean type */ ++ SNDRV_CTL_ELEM_TYPE_INTEGER, /* integer type */ ++ SNDRV_CTL_ELEM_TYPE_ENUMERATED, /* enumerated type */ ++ SNDRV_CTL_ELEM_TYPE_BYTES, /* byte array */ ++ SNDRV_CTL_ELEM_TYPE_IEC958, /* IEC958 (S/PDIF) setup */ ++ SNDRV_CTL_ELEM_TYPE_INTEGER64, /* 64-bit integer type */ ++ SNDRV_CTL_ELEM_TYPE_LAST = SNDRV_CTL_ELEM_TYPE_INTEGER64, ++}; ++ ++enum sndrv_ctl_elem_iface { ++ SNDRV_CTL_ELEM_IFACE_CARD = 0, /* global control */ ++ SNDRV_CTL_ELEM_IFACE_HWDEP, /* hardware dependent device */ ++ SNDRV_CTL_ELEM_IFACE_MIXER, /* virtual mixer device */ ++ SNDRV_CTL_ELEM_IFACE_PCM, /* PCM device */ ++ SNDRV_CTL_ELEM_IFACE_RAWMIDI, /* RawMidi device */ ++ SNDRV_CTL_ELEM_IFACE_TIMER, /* timer device */ ++ SNDRV_CTL_ELEM_IFACE_SEQUENCER, /* sequencer client */ ++ SNDRV_CTL_ELEM_IFACE_LAST = SNDRV_CTL_ELEM_IFACE_SEQUENCER, ++}; ++ ++struct sndrv_ctl_elem_id { ++ unsigned int numid; /* numeric identifier, zero = invalid */ ++ int iface; /* interface identifier */ ++ unsigned int device; /* device/client number */ ++ unsigned int subdevice; /* subdevice (substream) number */ ++ unsigned char name[44]; /* ASCII name of item */ ++ unsigned int index; /* index of item */ ++}; ++ ++struct sndrv_ctl_elem_list { ++ unsigned int offset; /* W: first element ID to get */ ++ unsigned int space; /* W: count of element IDs to get */ ++ unsigned int used; /* R: count of element IDs set */ ++ unsigned int count; /* R: count of all elements */ ++ struct sndrv_ctl_elem_id *pids; /* R: IDs */ ++ unsigned char reserved[50]; ++}; ++ ++struct sndrv_ctl_elem_info { ++ struct sndrv_ctl_elem_id id; /* W: element ID */ ++ int type; /* R: value type - SNDRV_CTL_ELEM_TYPE_* */ ++ unsigned int access; /* R: value access (bitmask) - SNDRV_CTL_ELEM_ACCESS_* */ ++ unsigned int count; /* count of values */ ++ pid_t owner; /* owner's PID of this control */ ++ union { ++ struct { ++ long min; /* R: minimum value */ ++ long max; /* R: maximum value */ ++ long step; /* R: step (0 variable) */ ++ } integer; ++ struct { ++ long long min; /* R: minimum value */ ++ long long max; /* R: maximum value */ ++ long long step; /* R: step (0 variable) */ ++ } integer64; ++ struct { ++ unsigned int items; /* R: number of items */ ++ unsigned int item; /* W: item number */ ++ char name[64]; /* R: value name */ ++ } enumerated; ++ unsigned char reserved[128]; ++ } value; ++ union { ++ unsigned short d[4]; /* dimensions */ ++ unsigned short *d_ptr; /* indirect */ ++ } dimen; ++ unsigned char reserved[64-4*sizeof(unsigned short)]; ++}; ++ ++struct sndrv_ctl_elem_value { ++ struct sndrv_ctl_elem_id id; /* W: element ID */ ++ unsigned int indirect: 1; /* W: use indirect pointer (xxx_ptr member) */ ++ union { ++ union { ++ long value[128]; ++ long *value_ptr; ++ } integer; ++ union { ++ long long value[64]; ++ long long *value_ptr; ++ } integer64; ++ union { ++ unsigned int item[128]; ++ unsigned int *item_ptr; ++ } enumerated; ++ union { ++ unsigned char data[512]; ++ unsigned char *data_ptr; ++ } bytes; ++ struct sndrv_aes_iec958 iec958; ++ } value; /* RO */ ++ struct timespec tstamp; ++ unsigned char reserved[128-sizeof(struct timespec)]; ++}; ++ ++struct sndrv_ctl_tlv { ++ unsigned int numid; /* control element numeric identification */ ++ unsigned int length; /* in bytes aligned to 4 */ ++ unsigned int tlv[0]; /* first TLV */ ++}; ++ ++enum sndrv_ctl_event_type { ++ SNDRV_CTL_EVENT_ELEM = 0, ++ SNDRV_CTL_EVENT_LAST = SNDRV_CTL_EVENT_ELEM, ++}; ++ ++struct sndrv_ctl_event { ++ int type; /* event type - SNDRV_CTL_EVENT_* */ ++ union { ++ struct { ++ unsigned int mask; ++ struct sndrv_ctl_elem_id id; ++ } elem; ++ unsigned char data8[60]; ++ } data; ++}; ++ ++struct sndrv_xferv { ++ const struct iovec *vector; ++ unsigned long count; ++}; ++ ++typedef struct { ++ unsigned int internal_tram_size; /* in samples */ ++ unsigned int external_tram_size; /* in samples */ ++ char fxbus_names[16][32]; /* names of FXBUSes */ ++ char extin_names[16][32]; /* names of external inputs */ ++ char extout_names[32][32]; /* names of external outputs */ ++ unsigned int gpr_controls; /* count of GPR controls */ ++} emu10k1_fx8010_info_t; ++ ++enum emu10k1_ctl_elem_iface { ++ EMU10K1_CTL_ELEM_IFACE_MIXER = 2, /* virtual mixer device */ ++ EMU10K1_CTL_ELEM_IFACE_PCM = 3, /* PCM device */ ++}; ++ ++typedef struct { ++ unsigned int pad; /* don't use */ ++ int iface; /* interface identifier */ ++ unsigned int device; /* device/client number */ ++ unsigned int subdevice; /* subdevice (substream) number */ ++ unsigned char name[44]; /* ASCII name of item */ ++ unsigned int index; /* index of item */ ++} emu10k1_ctl_elem_id_t; ++ ++typedef struct { ++ emu10k1_ctl_elem_id_t id; /* full control ID definition */ ++ unsigned int vcount; /* visible count */ ++ unsigned int count; /* count of GPR (1..16) */ ++ unsigned short gpr[32]; /* GPR number(s) */ ++ unsigned int value[32]; /* initial values */ ++ unsigned int min; /* minimum range */ ++ unsigned int max; /* maximum range */ ++ unsigned int translation; /* translation type (EMU10K1_GPR_TRANSLATION*) */ ++ unsigned int *tlv; ++} emu10k1_fx8010_control_gpr_t; ++ ++typedef struct { ++ char name[128]; ++ ++ unsigned long gpr_valid[0x200/(sizeof(unsigned long)*8)]; /* bitmask of valid initializers */ ++ uint32_t *gpr_map; /* initializers */ ++ ++ unsigned int gpr_add_control_count; /* count of GPR controls to add/replace */ ++ emu10k1_fx8010_control_gpr_t *gpr_add_controls; /* GPR controls to add/replace */ ++ ++ unsigned int gpr_del_control_count; /* count of GPR controls to remove */ ++ emu10k1_ctl_elem_id_t *gpr_del_controls; /* IDs of GPR controls to remove */ ++ ++ unsigned int gpr_list_control_count; /* count of GPR controls to list */ ++ unsigned int gpr_list_control_total; /* total count of GPR controls */ ++ emu10k1_fx8010_control_gpr_t *gpr_list_controls; /* listed GPR controls */ ++ ++ unsigned long tram_valid[0x100/(sizeof(unsigned long)*8)]; /* bitmask of valid initializers */ ++ uint32_t *tram_data_map; /* data initializers */ ++ uint32_t *tram_addr_map; /* map initializers */ ++ ++ unsigned long code_valid[1024/(sizeof(unsigned long)*8)]; /* bitmask of valid instructions */ ++ uint32_t *code; /* one instruction - 64 bits */ ++} emu10k1_fx8010_code_t; ++ ++typedef struct { ++ unsigned int address; /* 31.bit == 1 -> external TRAM */ ++ unsigned int size; /* size in samples (4 bytes) */ ++ unsigned int *samples; /* pointer to samples (20-bit) */ ++ /* NULL->clear memory */ ++} emu10k1_fx8010_tram_t; ++ ++typedef struct { ++ unsigned int substream; /* substream number */ ++ unsigned int res1; /* reserved */ ++ unsigned int channels; /* 16-bit channels count, zero = remove this substream */ ++ unsigned int tram_start; /* ring buffer position in TRAM (in samples) */ ++ unsigned int buffer_size; /* count of buffered samples */ ++ unsigned short gpr_size; /* GPR containing size of ringbuffer in samples (host) */ ++ unsigned short gpr_ptr; /* GPR containing current pointer in the ring buffer (host = reset, FX8010) */ ++ unsigned short gpr_count; /* GPR containing count of samples between two interrupts (host) */ ++ unsigned short gpr_tmpcount; /* GPR containing current count of samples to interrupt (host = set, FX8010) */ ++ unsigned short gpr_trigger; /* GPR containing trigger (activate) information (host) */ ++ unsigned short gpr_running; /* GPR containing info if PCM is running (FX8010) */ ++ unsigned char pad; /* reserved */ ++ unsigned char etram[32]; /* external TRAM address & data (one per channel) */ ++ unsigned int res2; /* reserved */ ++} emu10k1_fx8010_pcm_t; ++ ++typedef enum { ++ Digiface, ++ Multiface, ++ H9652, ++ H9632, ++ Undefined, ++} HDSP_IO_Type; ++ ++typedef struct _snd_hdsp_peak_rms hdsp_peak_rms_t; ++ ++struct _snd_hdsp_peak_rms { ++ uint32_t input_peaks[26]; ++ uint32_t playback_peaks[26]; ++ uint32_t output_peaks[28]; ++ uint64_t input_rms[26]; ++ uint64_t playback_rms[26]; ++ /* These are only used for H96xx cards */ ++ uint64_t output_rms[26]; ++}; ++ ++typedef struct _snd_hdsp_config_info hdsp_config_info_t; ++ ++struct _snd_hdsp_config_info { ++ unsigned char pref_sync_ref; ++ unsigned char wordclock_sync_check; ++ unsigned char spdif_sync_check; ++ unsigned char adatsync_sync_check; ++ unsigned char adat_sync_check[3]; ++ unsigned char spdif_in; ++ unsigned char spdif_out; ++ unsigned char spdif_professional; ++ unsigned char spdif_emphasis; ++ unsigned char spdif_nonaudio; ++ unsigned int spdif_sample_rate; ++ unsigned int system_sample_rate; ++ unsigned int autosync_sample_rate; ++ unsigned char system_clock_mode; ++ unsigned char clock_source; ++ unsigned char autosync_ref; ++ unsigned char line_out; ++ unsigned char passthru; ++ unsigned char da_gain; ++ unsigned char ad_gain; ++ unsigned char phone_gain; ++ unsigned char xlr_breakout_cable; ++ unsigned char analog_extension_board; ++}; ++ ++typedef struct _snd_hdsp_firmware hdsp_firmware_t; ++ ++struct _snd_hdsp_firmware { ++ void *firmware_data; /* 24413 x 4 bytes */ ++}; ++ ++typedef struct _snd_hdsp_version hdsp_version_t; ++ ++struct _snd_hdsp_version { ++ HDSP_IO_Type io_type; ++ unsigned short firmware_rev; ++}; ++ ++typedef struct _snd_hdsp_mixer hdsp_mixer_t; ++ ++struct _snd_hdsp_mixer { ++ unsigned short matrix[HDSP_MATRIX_MIXER_SIZE]; ++}; ++ ++typedef struct _snd_hdsp_9632_aeb hdsp_9632_aeb_t; ++ ++struct _snd_hdsp_9632_aeb { ++ int aebi; ++ int aebo; ++}; ++ ++typedef struct snd_sb_csp_mc_header { ++ char codec_name[16]; /* id name of codec */ ++ unsigned short func_req; /* requested function */ ++} snd_sb_csp_mc_header_t; ++ ++typedef struct snd_sb_csp_microcode { ++ snd_sb_csp_mc_header_t info; ++ unsigned char data[SNDRV_SB_CSP_MAX_MICROCODE_FILE_SIZE]; ++} snd_sb_csp_microcode_t; ++ ++typedef struct snd_sb_csp_start { ++ int sample_width; /* sample width, look above */ ++ int channels; /* channels, look above */ ++} snd_sb_csp_start_t; ++ ++typedef struct snd_sb_csp_info { ++ char codec_name[16]; /* id name of codec */ ++ unsigned short func_nr; /* function number */ ++ unsigned int acc_format; /* accepted PCM formats */ ++ unsigned short acc_channels; /* accepted channels */ ++ unsigned short acc_width; /* accepted sample width */ ++ unsigned short acc_rates; /* accepted sample rates */ ++ unsigned short csp_mode; /* CSP mode, see above */ ++ unsigned short run_channels; /* current channels */ ++ unsigned short run_width; /* current sample width */ ++ unsigned short version; /* version id: 0x10 - 0x1f */ ++ unsigned short state; /* state bits */ ++} snd_sb_csp_info_t; ++ ++struct sscape_bootblock ++{ ++ unsigned char code[256]; ++ unsigned version; ++}; ++ ++struct sscape_microcode ++{ ++ unsigned char *code; ++}; +Index: qemu/linux-user/syscall_defs.h +=================================================================== +--- qemu.orig/linux-user/syscall_defs.h ++++ qemu/linux-user/syscall_defs.h +@@ -1677,3 +1677,4 @@ struct target_sysinfo { + #include "socket.h" + + #include "errno_defs.h" ++#include "ioctls_alsa_structs.h" +Index: qemu/linux-user/syscall_types.h +=================================================================== +--- qemu.orig/linux-user/syscall_types.h ++++ qemu/linux-user/syscall_types.h +@@ -79,3 +79,8 @@ STRUCT(count_info, + + STRUCT(mixer_info, + MK_ARRAY(TYPE_CHAR, 16), MK_ARRAY(TYPE_CHAR, 32), TYPE_INT, MK_ARRAY(TYPE_INT, 10)) ++ ++/* FIXME: including these on x86 / x86_64 breaks qemu-i386 */ ++#ifdef __powerpc__ ++#include "syscall_types_alsa.h" ++#endif +Index: qemu/linux-user/syscall_types_alsa.h +=================================================================== +--- /dev/null ++++ qemu/linux-user/syscall_types_alsa.h +@@ -0,0 +1,1337 @@ ++/* ++ * Advanced Linux Sound Architecture ++ * ++ * This program is free software, you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY, without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * aTYPE_LONG, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ */ ++ ++STRUCT (sndrv_pcm_sframes, TYPE_LONG) ++STRUCT (sndrv_seq_event_type, TYPE_CHAR) ++STRUCT (sndrv_seq_instr_cluster, TYPE_INT) ++STRUCT (sndrv_seq_position, TYPE_INT) ++STRUCT (sndrv_seq_frequency, TYPE_INT) ++STRUCT (sndrv_seq_tick_time, TYPE_INT) ++STRUCT (sndrv_seq_instr_size, TYPE_INT) ++STRUCT (sndrv_pcm_uframes, TYPE_ULONG) ++ ++ ++STRUCT (timespec, ++ TYPE_LONG, ++ TYPE_LONG ++ ) ++ ++STRUCT( fm_operator, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR ++) ++ ++STRUCT(fm_instrument, ++ MK_ARRAY(TYPE_INT, 4), /* share id - zero = no sharing */ ++ TYPE_CHAR, /* instrument type */ ++ ++ MK_ARRAY(MK_STRUCT(STRUCT_fm_operator), 4), ++ MK_ARRAY(TYPE_CHAR, 2), ++ ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR ++) ++ ++STRUCT( fm_xoperator, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR ++) ++ ++STRUCT( fm_xinstrument, ++ TYPE_INT, /* structure type */ ++ ++ MK_ARRAY(TYPE_INT, 4), /* share id - zero = no sharing */ ++ TYPE_CHAR, /* instrument type */ ++ ++ MK_ARRAY(MK_STRUCT(STRUCT_fm_xoperator), 4), /* fm operators */ ++ MK_ARRAY(TYPE_CHAR, 2), ++ ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR ++) ++ ++STRUCT( gf1_wave, ++ MK_ARRAY(TYPE_INT, 4), /* share id - zero = no sharing */ ++ TYPE_INT, /* wave format */ ++ ++ TYPE_INT, /* some other ID for this instrument */ ++ TYPE_INT, /* begin of waveform in onboard memory */ ++ TYPE_PTRVOID, /* poTYPE_INTer to waveform in system memory */ ++ ++ TYPE_INT, /* size of waveform in samples */ ++ TYPE_INT, /* start offset in samples * 16 (lowest 4 bits - fraction) */ ++ TYPE_INT, /* bits loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ TYPE_INT, /* loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ TYPE_SHORT, /* loop repeat - 0 = forever */ ++ ++ TYPE_CHAR, /* GF1 patch flags */ ++ TYPE_CHAR, ++ TYPE_INT, /* sample rate in Hz */ ++ TYPE_INT, /* low frequency range */ ++ TYPE_INT, /* high frequency range */ ++ TYPE_INT, /* root frequency range */ ++ TYPE_SHORT, ++ TYPE_CHAR, ++ MK_ARRAY(TYPE_CHAR, 6), ++ MK_ARRAY(TYPE_CHAR, 6), ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_SHORT, ++ TYPE_SHORT, /* 0-2048 or 0-2 */ ++ ++ TYPE_PTRVOID ++) ++ ++STRUCT(gf1_instrument, ++ TYPE_SHORT, ++ TYPE_SHORT, /* 0 - none, 1-65535 */ ++ ++ TYPE_CHAR, /* effect 1 */ ++ TYPE_CHAR, /* 0-127 */ ++ TYPE_CHAR, /* effect 2 */ ++ TYPE_CHAR, /* 0-127 */ ++ ++ TYPE_PTRVOID /* first waveform */ ++) ++ ++STRUCT( gf1_xwave, ++ TYPE_INT, /* structure type */ ++ ++ MK_ARRAY(TYPE_INT, 4), /* share id - zero = no sharing */ ++ TYPE_INT, /* wave format */ ++ ++ TYPE_INT, /* size of waveform in samples */ ++ TYPE_INT, /* start offset in samples * 16 (lowest 4 bits - fraction) */ ++ TYPE_INT, /* bits loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ TYPE_INT, /* loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ TYPE_SHORT, /* loop repeat - 0 = forever */ ++ ++ TYPE_CHAR, /* GF1 patch flags */ ++ TYPE_CHAR, ++ TYPE_INT, /* sample rate in Hz */ ++ TYPE_INT, /* low frequency range */ ++ TYPE_INT, /* high frequency range */ ++ TYPE_INT, /* root frequency range */ ++ TYPE_SHORT, ++ TYPE_CHAR, ++ MK_ARRAY(TYPE_CHAR, 6), ++ MK_ARRAY(TYPE_CHAR, 6), ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_SHORT, ++ TYPE_SHORT /* 0-2048 or 0-2 */ ++) ++ ++STRUCT( gf1_xinstrument, ++ TYPE_INT, ++ ++ TYPE_SHORT, ++ TYPE_SHORT, /* 0 - none, 1-65535 */ ++ ++ TYPE_CHAR, /* effect 1 */ ++ TYPE_CHAR, /* 0-127 */ ++ TYPE_CHAR, /* effect 2 */ ++ TYPE_CHAR /* 0-127 */ ++) ++ ++STRUCT( gf1_info, ++ TYPE_CHAR, /* supported wave flags */ ++ MK_ARRAY(TYPE_CHAR, 3), ++ TYPE_INT, /* supported features */ ++ TYPE_INT, /* maximum 8-bit wave length */ ++ TYPE_INT /* maximum 16-bit wave length */ ++) ++ ++STRUCT( iwffff_wave, ++ MK_ARRAY(TYPE_INT, 4), /* share id - zero = no sharing */ ++ TYPE_INT, /* wave format */ ++ ++ TYPE_INT, /* some other ID for this wave */ ++ TYPE_INT, /* begin of waveform in onboard memory */ ++ TYPE_PTRVOID, /* poTYPE_INTer to waveform in system memory */ ++ ++ TYPE_INT, /* size of waveform in samples */ ++ TYPE_INT, /* start offset in samples * 16 (lowest 4 bits - fraction) */ ++ TYPE_INT, /* bits loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ TYPE_INT, /* loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ TYPE_SHORT, /* loop repeat - 0 = forever */ ++ TYPE_INT, /* sample ratio (44100 * 1024 / rate) */ ++ TYPE_CHAR, /* 0 - 127 (no corresponding midi controller) */ ++ TYPE_CHAR, /* lower frequency range for this waveform */ ++ TYPE_CHAR, /* higher frequency range for this waveform */ ++ TYPE_CHAR, ++ ++ TYPE_PTRVOID ++) ++ ++STRUCT( iwffff_lfo, ++ TYPE_SHORT, /* (0-2047) 0.01Hz - 21.5Hz */ ++ TYPE_SHORT, /* volume +- (0-255) 0.48675dB/step */ ++ TYPE_SHORT, /* 0 - 950 deciseconds */ ++ TYPE_CHAR, /* see to IWFFFF_LFO_SHAPE_XXXX */ ++ TYPE_CHAR /* 0 - 255 deciseconds */ ++) ++ ++STRUCT( iwffff_env_point, ++ TYPE_SHORT, ++ TYPE_SHORT ++) ++ ++STRUCT( iwffff_env_record, ++ TYPE_SHORT, ++ TYPE_SHORT, ++ TYPE_SHORT, ++ TYPE_SHORT, ++ TYPE_SHORT, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_PTRVOID ++) ++ ++STRUCT( iwffff_env, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_PTRVOID // MK_STRUCT(STRUCT_iwffff_env_record) ++) ++ ++STRUCT( iwffff_layer, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, /* range for layer based */ ++ TYPE_CHAR, /* on either velocity or frequency */ ++ TYPE_CHAR, /* pan offset from CC1 (0 left - 127 right) */ ++ TYPE_CHAR, /* position based on frequency (0-127) */ ++ TYPE_CHAR, /* 0-127 (no corresponding midi controller) */ ++ MK_STRUCT(STRUCT_iwffff_lfo), /* tremolo effect */ ++ MK_STRUCT(STRUCT_iwffff_lfo), /* vibrato effect */ ++ TYPE_SHORT, /* 0-2048, 1024 is equal to semitone scaling */ ++ TYPE_CHAR, /* center for keyboard frequency scaling */ ++ TYPE_CHAR, ++ MK_STRUCT(STRUCT_iwffff_env), /* pitch envelope */ ++ MK_STRUCT(STRUCT_iwffff_env), /* volume envelope */ ++ ++ TYPE_PTRVOID, // iwffff_wave_t *wave, ++ TYPE_PTRVOID // MK_STRUCT(STRUCT_iwffff_layer) ++) ++ ++STRUCT(iwffff_instrument, ++ TYPE_SHORT, ++ TYPE_SHORT, ++ TYPE_SHORT, /* 0 - none, 1-65535 */ ++ ++ TYPE_CHAR, /* effect 1 */ ++ TYPE_CHAR, /* 0-127 */ ++ TYPE_CHAR, /* effect 2 */ ++ TYPE_CHAR, /* 0-127 */ ++ ++ TYPE_PTRVOID // iwffff_layer_t *layer, /* first layer */ ++) ++ ++STRUCT( iwffff_xwave, ++ TYPE_INT, /* structure type */ ++ ++ MK_ARRAY(TYPE_INT, 4), /* share id - zero = no sharing */ ++ ++ TYPE_INT, /* wave format */ ++ TYPE_INT, /* offset to ROM (address) */ ++ ++ TYPE_INT, /* size of waveform in samples */ ++ TYPE_INT, /* start offset in samples * 16 (lowest 4 bits - fraction) */ ++ TYPE_INT, /* bits loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ TYPE_INT, /* loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ TYPE_SHORT, /* loop repeat - 0 = forever */ ++ TYPE_INT, /* sample ratio (44100 * 1024 / rate) */ ++ TYPE_CHAR, /* 0 - 127 (no corresponding midi controller) */ ++ TYPE_CHAR, /* lower frequency range for this waveform */ ++ TYPE_CHAR, /* higher frequency range for this waveform */ ++ TYPE_CHAR ++) ++ ++STRUCT( iwffff_xlfo, ++ TYPE_SHORT, /* (0-2047) 0.01Hz - 21.5Hz */ ++ TYPE_SHORT, /* volume +- (0-255) 0.48675dB/step */ ++ TYPE_SHORT, /* 0 - 950 deciseconds */ ++ TYPE_CHAR, /* see to ULTRA_IW_LFO_SHAPE_XXXX */ ++ TYPE_CHAR /* 0 - 255 deciseconds */ ++) ++ ++STRUCT( iwffff_xenv_point, ++ TYPE_SHORT, ++ TYPE_SHORT ++) ++ ++STRUCT( iwffff_xenv_record, ++ TYPE_INT, ++ TYPE_SHORT, ++ TYPE_SHORT, ++ TYPE_SHORT, ++ TYPE_SHORT, ++ TYPE_SHORT, ++ TYPE_CHAR, ++ TYPE_CHAR ++) ++ ++STRUCT( iwffff_xenv, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR ++) ++ ++STRUCT( iwffff_xlayer, ++ TYPE_INT, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, /* range for layer based */ ++ TYPE_CHAR, /* on either velocity or frequency */ ++ TYPE_CHAR, /* pan offset from CC1 (0 left - 127 right) */ ++ TYPE_CHAR, /* position based on frequency (0-127) */ ++ TYPE_CHAR, /* 0-127 (no corresponding midi controller) */ ++ MK_STRUCT(STRUCT_iwffff_xlfo), /* tremolo effect */ ++ MK_STRUCT(STRUCT_iwffff_xlfo), /* vibrato effect */ ++ TYPE_SHORT, /* 0-2048, 1024 is equal to semitone scaling */ ++ TYPE_CHAR, /* center for keyboard frequency scaling */ ++ TYPE_CHAR, ++ MK_STRUCT(STRUCT_iwffff_xenv), /* pitch envelope */ ++ MK_STRUCT(STRUCT_iwffff_xenv) /* volume envelope */ ++) ++ ++STRUCT( iwffff_xinstrument, ++ TYPE_INT, ++ ++ TYPE_SHORT, ++ TYPE_SHORT, ++ TYPE_SHORT, /* 0 - none, 1-65535 */ ++ ++ TYPE_CHAR, /* effect 1 */ ++ TYPE_CHAR, /* 0-127 */ ++ TYPE_CHAR, /* effect 2 */ ++ TYPE_CHAR /* 0-127 */ ++) ++ ++STRUCT(iwffff_rom_header, ++ MK_ARRAY(TYPE_CHAR, 8), ++ TYPE_CHAR, ++ TYPE_CHAR, ++ MK_ARRAY(TYPE_CHAR, 16), ++ MK_ARRAY(TYPE_CHAR, 10), ++ TYPE_SHORT, ++ TYPE_SHORT, ++ TYPE_INT, ++ MK_ARRAY(TYPE_CHAR, 128), ++ MK_ARRAY(TYPE_CHAR, 64), ++ MK_ARRAY(TYPE_CHAR, 128) ++) ++ ++STRUCT( iwffff_info, ++ TYPE_INT, /* supported format bits */ ++ TYPE_INT, /* supported effects (1 << IWFFFF_EFFECT*) */ ++ TYPE_INT, /* LFO effects */ ++ TYPE_INT, /* maximum 8-bit wave length */ ++ TYPE_INT /* maximum 16-bit wave length */ ++) ++ ++STRUCT( simple_instrument_info, ++ TYPE_INT, /* supported format bits */ ++ TYPE_INT, /* supported effects (1 << SIMPLE_EFFECT_*) */ ++ TYPE_INT, /* maximum 8-bit wave length */ ++ TYPE_INT /* maximum 16-bit wave length */ ++) ++ ++STRUCT(simple_instrument, ++ MK_ARRAY(TYPE_INT, 4), /* share id - zero = no sharing */ ++ TYPE_INT, /* wave format */ ++ ++ TYPE_INT, /* some other ID for this instrument */ ++ TYPE_INT, /* begin of waveform in onboard memory */ ++ TYPE_PTRVOID, /* poTYPE_INTer to waveform in system memory */ ++ ++ TYPE_INT, /* size of waveform in samples */ ++ TYPE_INT, /* start offset in samples * 16 (lowest 4 bits - fraction) */ ++ TYPE_INT, /* loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ TYPE_INT, /* loop end offset in samples * 16 (lowest 4 bits - fraction) */ ++ TYPE_SHORT, /* loop repeat - 0 = forever */ ++ ++ TYPE_CHAR, /* effect 1 */ ++ TYPE_CHAR, /* 0-127 */ ++ TYPE_CHAR, /* effect 2 */ ++ TYPE_CHAR /* 0-127 */ ++) ++ ++STRUCT( simple_xinstrument, ++ TYPE_INT, ++ ++ MK_ARRAY(TYPE_INT, 4), /* share id - zero = no sharing */ ++ TYPE_INT, /* wave format */ ++ ++ TYPE_INT, /* size of waveform in samples */ ++ TYPE_INT, /* start offset in samples * 16 (lowest 4 bits - fraction) */ ++ TYPE_INT, /* bits loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ TYPE_INT, /* loop start offset in samples * 16 (lowest 4 bits - fraction) */ ++ TYPE_SHORT, /* loop repeat - 0 = forever */ ++ ++ TYPE_CHAR, /* effect 1 */ ++ TYPE_CHAR, /* 0-127 */ ++ TYPE_CHAR, /* effect 2 */ ++ TYPE_CHAR /* 0-127 */ ++) ++ ++/** event address */ ++STRUCT( sndrv_seq_addr, ++ TYPE_CHAR, /**< Client number: 0..255, 255 = broadcast to all clients */ ++ TYPE_CHAR /**< Port within client: 0..255, 255 = broadcast to all ports */ ++) ++ ++/** port connection */ ++STRUCT( sndrv_seq_connect, ++ MK_STRUCT(STRUCT_sndrv_seq_addr), ++ MK_STRUCT(STRUCT_sndrv_seq_addr) ++) ++ ++STRUCT( sndrv_seq_ev_note, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, /* only for SNDRV_SEQ_EVENT_NOTE */ ++ TYPE_INT /* only for SNDRV_SEQ_EVENT_NOTE */ ++) ++ ++ /* controller event */ ++STRUCT( sndrv_seq_ev_ctrl, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, /* pad */ ++ TYPE_INT, ++ TYPE_INT ++) ++ ++ /* generic set of bytes (12x8 bit) */ ++STRUCT( sndrv_seq_ev_raw8, ++ MK_ARRAY(TYPE_CHAR, 12) /* 8 bit value */ ++) ++ ++ /* generic set of TYPE_INTegers (3x32 bit) */ ++STRUCT( sndrv_seq_ev_raw32, ++ MK_ARRAY(TYPE_INT, 3) /* 32 bit value */ ++) ++ ++ /* external stored data */ ++STRUCT( sndrv_seq_ev_ext, ++ TYPE_INT, /* length of data */ ++ TYPE_PTRVOID /* poTYPE_INTer to data (note: maybe 64-bit) */ ++) ++ ++/* Instrument type */ ++STRUCT( sndrv_seq_instr, ++ TYPE_INT, ++ TYPE_INT, /* the upper byte means a private instrument (owner - client #) */ ++ TYPE_SHORT, ++ TYPE_SHORT ++) ++ ++ /* sample number */ ++STRUCT( sndrv_seq_ev_sample, ++ TYPE_INT, ++ TYPE_SHORT, ++ TYPE_SHORT ++) ++ ++ /* sample cluster */ ++STRUCT( sndrv_seq_ev_cluster, ++ TYPE_INT ++) ++ ++ /* sample volume control, if any value is set to -1 == do not change */ ++STRUCT( sndrv_seq_ev_volume, ++ TYPE_SHORT, /* range: 0-16383 */ ++ TYPE_SHORT, /* left-right balance, range: 0-16383 */ ++ TYPE_SHORT, /* front-rear balance, range: 0-16383 */ ++ TYPE_SHORT /* down-up balance, range: 0-16383 */ ++) ++ ++ /* simple loop redefinition */ ++STRUCT( sndrv_seq_ev_loop, ++ TYPE_INT, /* loop start (in samples) * 16 */ ++ TYPE_INT /* loop end (in samples) * 16 */ ++) ++ ++STRUCT( sndrv_seq_ev_sample_control, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, /* pad */ ++ MK_ARRAY(TYPE_INT, 2) ++) ++ ++ ++ ++/* INSTR_BEGIN event */ ++STRUCT( sndrv_seq_ev_instr_begin, ++ TYPE_INT ++) ++ ++STRUCT( sndrv_seq_result, ++ TYPE_INT, ++ TYPE_INT ++) ++ ++ ++STRUCT( sndrv_seq_real_time, ++ TYPE_INT, ++ TYPE_INT ++) ++ ++STRUCT( sndrv_seq_queue_skew, ++ TYPE_INT, ++ TYPE_INT ++) ++ ++ /* queue timer control */ ++STRUCT( sndrv_seq_ev_queue_control, ++ TYPE_CHAR, /* affected queue */ ++ MK_ARRAY(TYPE_CHAR, 3), /* reserved */ ++ MK_ARRAY(TYPE_INT, 2) ++) ++ ++ /* quoted event - inside the kernel only */ ++STRUCT( sndrv_seq_ev_quote, ++ MK_STRUCT(STRUCT_sndrv_seq_addr), /* original sender */ ++ TYPE_SHORT, /* optional data */ ++ MK_STRUCT(STRUCT_sndrv_seq_event) /* quoted event */ ++) ++ ++ ++ /* sequencer event */ ++STRUCT( sndrv_seq_event, ++ TYPE_CHAR, /* event type */ ++ TYPE_CHAR, /* event flags */ ++ TYPE_CHAR, ++ ++ TYPE_CHAR, /* schedule queue */ ++ MK_STRUCT(STRUCT_sndrv_seq_real_time), /* schedule time */ ++ ++ ++ MK_STRUCT(STRUCT_sndrv_seq_addr), /* source address */ ++ MK_STRUCT(STRUCT_sndrv_seq_addr), /* destination address */ ++ ++ MK_ARRAY(TYPE_INT,3) ++) ++ ++ ++/* ++ * bounce event - stored as variable size data ++ */ ++STRUCT( sndrv_seq_event_bounce, ++ TYPE_INT, ++ MK_STRUCT(STRUCT_sndrv_seq_event) ++ /* external data follows here. */ ++) ++ ++STRUCT( sndrv_seq_system_info, ++ TYPE_INT, /* maximum queues count */ ++ TYPE_INT, /* maximum clients count */ ++ TYPE_INT, /* maximum ports per client */ ++ TYPE_INT, /* maximum channels per port */ ++ TYPE_INT, /* current clients */ ++ TYPE_INT, /* current queues */ ++ MK_ARRAY(TYPE_CHAR, 24) ++) ++ ++STRUCT( sndrv_seq_running_info, ++ TYPE_CHAR, /* client id */ ++ TYPE_CHAR, /* 1 = big-endian */ ++ TYPE_CHAR, ++ TYPE_CHAR, /* reserved */ ++ MK_ARRAY(TYPE_CHAR, 12) ++) ++ ++STRUCT( sndrv_seq_client_info, ++ TYPE_INT, /* client number to inquire */ ++ TYPE_INT, /* client type */ ++ MK_ARRAY(TYPE_CHAR, 64), /* client name */ ++ TYPE_INT, /* filter flags */ ++ MK_ARRAY(TYPE_CHAR, 8), /* multicast filter bitmap */ ++ MK_ARRAY(TYPE_CHAR, 32), /* event filter bitmap */ ++ TYPE_INT, /* RO: number of ports */ ++ TYPE_INT, /* number of lost events */ ++ MK_ARRAY(TYPE_CHAR, 64) /* for future use */ ++) ++ ++STRUCT( sndrv_seq_client_pool, ++ TYPE_INT, /* client number to inquire */ ++ TYPE_INT, /* outgoing (write) pool size */ ++ TYPE_INT, /* incoming (read) pool size */ ++ TYPE_INT, /* minimum free pool size for select/blocking mode */ ++ TYPE_INT, /* unused size */ ++ TYPE_INT, /* unused size */ ++ MK_ARRAY(TYPE_CHAR, 64) ++) ++ ++STRUCT( sndrv_seq_remove_events, ++ TYPE_INT, /* Flags that determine what gets removed */ ++ ++ MK_STRUCT(STRUCT_sndrv_seq_real_time), ++ ++ TYPE_CHAR, /* Queue for REMOVE_DEST */ ++ MK_STRUCT(STRUCT_sndrv_seq_addr), /* Address for REMOVE_DEST */ ++ TYPE_CHAR, /* Channel for REMOVE_DEST */ ++ ++ TYPE_INT, /* For REMOVE_EVENT_TYPE */ ++ TYPE_CHAR, /* Tag for REMOVE_TAG */ ++ ++ MK_ARRAY(TYPE_INT, 10) /* To allow for future binary compatibility */ ++ ++) ++ ++STRUCT( sndrv_seq_port_info, ++ MK_STRUCT(STRUCT_sndrv_seq_addr), /* client/port numbers */ ++ MK_ARRAY(TYPE_CHAR, 64), /* port name */ ++ ++ TYPE_INT, /* port capability bits */ ++ TYPE_INT, /* port type bits */ ++ TYPE_INT, /* channels per MIDI port */ ++ TYPE_INT, /* voices per MIDI port */ ++ TYPE_INT, /* voices per SYNTH port */ ++ ++ TYPE_INT, /* R/O: subscribers for output (from this port) */ ++ TYPE_INT, /* R/O: subscribers for input (to this port) */ ++ ++ TYPE_PTRVOID, /* reserved for kernel use (must be NULL) */ ++ TYPE_INT, /* misc. conditioning */ ++ TYPE_CHAR, /* queue # for timestamping */ ++ MK_ARRAY(TYPE_CHAR, 59) /* for future use */ ++) ++ ++STRUCT( sndrv_seq_queue_info, ++ TYPE_INT, /* queue id */ ++ ++ /* ++ * security settings, only owner of this queue can start/stop timer ++ * etc. if the queue is locked for other clients ++ */ ++ TYPE_INT, /* client id for owner of the queue */ ++ TYPE_INT, /* timing queue locked for other queues */ ++ MK_ARRAY(TYPE_CHAR, 64), /* name of this queue */ ++ TYPE_INT, /* flags */ ++ MK_ARRAY(TYPE_CHAR, 60) /* for future use */ ++ ++) ++ ++STRUCT( sndrv_seq_queue_status, ++ TYPE_INT, /* queue id */ ++ TYPE_INT, /* read-only - queue size */ ++ TYPE_INT, /* current tick */ ++ MK_STRUCT(STRUCT_sndrv_seq_real_time), /* current time */ ++ TYPE_INT, /* running state of queue */ ++ TYPE_INT, /* various flags */ ++ MK_ARRAY(TYPE_CHAR, 64) /* for the future */ ++) ++ ++STRUCT( sndrv_seq_queue_tempo, ++ TYPE_INT, /* sequencer queue */ ++ TYPE_INT, ++ TYPE_INT, ++ TYPE_INT, /* queue skew */ ++ TYPE_INT, /* queue skew base */ ++ MK_ARRAY(TYPE_CHAR, 24) /* for the future */ ++) ++ ++STRUCT( sndrv_timer_id, ++ TYPE_INT, ++ TYPE_INT, ++ TYPE_INT, ++ TYPE_INT, ++ TYPE_INT ++) ++ ++STRUCT( sndrv_seq_queue_timer, ++ TYPE_INT, /* sequencer queue */ ++ TYPE_INT, /* source timer type */ ++ MK_STRUCT(STRUCT_sndrv_timer_id), /* ALSA's timer ID */ ++ TYPE_INT, /* resolution in Hz */ ++ MK_ARRAY(TYPE_CHAR, 64) /* for the future use */ ++) ++ ++STRUCT( sndrv_seq_queue_client, ++ TYPE_INT, /* sequencer queue */ ++ TYPE_INT, /* sequencer client */ ++ TYPE_INT, /* queue is used with this client ++ (must be set for accepting events) */ ++ /* per client watermarks */ ++ MK_ARRAY(TYPE_CHAR, 64) /* for future use */ ++) ++ ++STRUCT( sndrv_seq_port_subscribe, ++ MK_STRUCT(STRUCT_sndrv_seq_addr), /* sender address */ ++ MK_STRUCT(STRUCT_sndrv_seq_addr), /* destination address */ ++ TYPE_INT, /* number of voices to be allocated (0 = don't care) */ ++ TYPE_INT, /* modes */ ++ TYPE_CHAR, /* input time-stamp queue (optional) */ ++ MK_ARRAY(TYPE_CHAR, 3), /* reserved */ ++ MK_ARRAY(TYPE_CHAR, 64) ++) ++ ++STRUCT( sndrv_seq_query_subs, ++ MK_STRUCT(STRUCT_sndrv_seq_addr), /* client/port id to be searched */ ++ TYPE_INT, /* READ or WRITE */ ++ TYPE_INT, /* 0..N-1 */ ++ TYPE_INT, /* R/O: number of subscriptions on this port */ ++ MK_STRUCT(STRUCT_sndrv_seq_addr), /* R/O: result */ ++ TYPE_CHAR, /* R/O: result */ ++ TYPE_INT, /* R/O: result */ ++ MK_ARRAY(TYPE_CHAR, 64) /* for future use */ ++) ++ ++STRUCT( sndrv_seq_instr_info, ++ TYPE_INT, /* operation result */ ++ MK_ARRAY(TYPE_INT, 8), /* bitmap of supported formats */ ++ TYPE_INT, /* count of RAM banks */ ++ MK_ARRAY(TYPE_INT, 16), /* size of RAM banks */ ++ TYPE_INT, /* count of ROM banks */ ++ MK_ARRAY(TYPE_INT, 8), /* size of ROM banks */ ++ MK_ARRAY(TYPE_CHAR, 128) ++) ++ ++STRUCT( sndrv_seq_instr_status, ++ TYPE_INT, /* operation result */ ++ MK_ARRAY(TYPE_INT, 16), /* free RAM in banks */ ++ TYPE_INT, /* count of downloaded instruments */ ++ MK_ARRAY(TYPE_CHAR, 128) ++) ++ ++STRUCT( sndrv_seq_instr_format_info, ++ MK_ARRAY(TYPE_CHAR, 16), /* format identifier - SNDRV_SEQ_INSTR_ID_* */ ++ TYPE_INT /* max data length (without this structure) */ ++) ++ ++STRUCT( sndrv_seq_instr_format_info_result, ++ TYPE_INT, /* operation result */ ++ MK_ARRAY(TYPE_CHAR, 16), /* format identifier */ ++ TYPE_INT /* filled data length (without this structure) */ ++) ++ ++STRUCT( sndrv_seq_instr_data, ++ MK_ARRAY(TYPE_CHAR, 32), /* instrument name */ ++ MK_ARRAY(TYPE_CHAR, 16), /* for the future use */ ++ TYPE_INT, /* instrument type */ ++ MK_STRUCT(STRUCT_sndrv_seq_instr), ++ MK_ARRAY(TYPE_CHAR, 4) /* fillup */ ++) ++ ++STRUCT( sndrv_seq_instr_header, ++ MK_STRUCT(STRUCT_sndrv_seq_instr), ++ TYPE_INT, /* get/put/free command */ ++ TYPE_INT, /* query flags (only for get) */ ++ TYPE_INT, /* real instrument data length (without header) */ ++ TYPE_INT, /* operation result */ ++ MK_ARRAY(TYPE_CHAR, 16), /* for the future */ ++ MK_STRUCT(STRUCT_sndrv_seq_instr_data) /* instrument data (for put/get result) */ ++) ++ ++STRUCT( sndrv_seq_instr_cluster_set, ++ TYPE_INT, /* cluster identifier */ ++ MK_ARRAY(TYPE_CHAR, 32), /* cluster name */ ++ TYPE_INT, /* cluster priority */ ++ MK_ARRAY(TYPE_CHAR, 64) /* for the future use */ ++) ++ ++STRUCT( sndrv_seq_instr_cluster_get, ++ TYPE_INT, /* cluster identifier */ ++ MK_ARRAY(TYPE_CHAR, 32), /* cluster name */ ++ TYPE_INT, /* cluster priority */ ++ MK_ARRAY(TYPE_CHAR, 64) /* for the future use */ ++) ++ ++STRUCT( snd_dm_fm_info, ++ TYPE_CHAR, ++ TYPE_CHAR ++) ++ ++STRUCT( snd_dm_fm_voice, ++ TYPE_CHAR, /* operator cell (0 or 1) */ ++ TYPE_CHAR, /* FM voice (0 to 17) */ ++ ++ TYPE_CHAR, /* amplitude modulation */ ++ TYPE_CHAR, /* vibrato effect */ ++ TYPE_CHAR, /* sustain phase */ ++ TYPE_CHAR, /* keyboard scaling */ ++ TYPE_CHAR, /* 4 bits: harmonic and multiplier */ ++ TYPE_CHAR, /* 2 bits: decrease output freq rises */ ++ TYPE_CHAR, /* 6 bits: volume */ ++ ++ TYPE_CHAR, /* 4 bits: attack rate */ ++ TYPE_CHAR, /* 4 bits: decay rate */ ++ TYPE_CHAR, /* 4 bits: sustain level */ ++ TYPE_CHAR, /* 4 bits: release rate */ ++ ++ TYPE_CHAR, /* 3 bits: feedback for op0 */ ++ TYPE_CHAR, ++ TYPE_CHAR, /* stereo left */ ++ TYPE_CHAR, /* stereo right */ ++ TYPE_CHAR /* 3 bits: waveform shape */ ++) ++ ++STRUCT( snd_dm_fm_note, ++ TYPE_CHAR, /* 0-17 voice channel */ ++ TYPE_CHAR, /* 3 bits: what octave to play */ ++ TYPE_INT, /* 10 bits: frequency number */ ++ TYPE_CHAR ++) ++ ++STRUCT( snd_dm_fm_params, ++ TYPE_CHAR, /* amplitude modulation depth (1=hi) */ ++ TYPE_CHAR, /* vibrato depth (1=hi) */ ++ TYPE_CHAR, /* keyboard split */ ++ TYPE_CHAR, /* percussion mode select */ ++ ++ /* This block is the percussion instrument data */ ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR ++) ++ ++STRUCT( sndrv_aes_iec958, ++ MK_ARRAY(TYPE_CHAR, 24), /* AES/IEC958 channel status bits */ ++ MK_ARRAY(TYPE_CHAR, 147), /* AES/IEC958 subcode bits */ ++ TYPE_CHAR, /* nothing */ ++ MK_ARRAY(TYPE_CHAR, 4) /* AES/IEC958 subframe bits */ ++) ++ ++STRUCT( sndrv_hwdep_info, ++ TYPE_INT, /* WR: device number */ ++ TYPE_INT, /* R: card number */ ++ MK_ARRAY(TYPE_CHAR, 64), /* ID (user selectable) */ ++ MK_ARRAY(TYPE_CHAR, 80), /* hwdep name */ ++ TYPE_INT, /* hwdep interface */ ++ MK_ARRAY(TYPE_CHAR, 64) /* reserved for future */ ++) ++ ++/* generic DSP loader */ ++STRUCT( sndrv_hwdep_dsp_status, ++ TYPE_INT, /* R: driver-specific version */ ++ MK_ARRAY(TYPE_CHAR, 32), /* R: driver-specific ID string */ ++ TYPE_INT, /* R: number of DSP images to transfer */ ++ TYPE_INT, /* R: bit flags indicating the loaded DSPs */ ++ TYPE_INT, /* R: 1 = initialization finished */ ++ MK_ARRAY(TYPE_CHAR, 16) /* reserved for future use */ ++) ++ ++STRUCT( sndrv_hwdep_dsp_image, ++ TYPE_INT, /* W: DSP index */ ++ MK_ARRAY(TYPE_CHAR, 64), /* W: ID (e.g. file name) */ ++ TYPE_CHAR, /* W: binary image */ ++ TYPE_LONG, /* W: size of image in bytes */ ++ TYPE_LONG /* W: driver-specific data */ ++) ++ ++STRUCT( sndrv_pcm_info, ++ TYPE_INT, /* RO/WR (control): device number */ ++ TYPE_INT, /* RO/WR (control): subdevice number */ ++ TYPE_INT, /* RO/WR (control): stream number */ ++ TYPE_INT, /* R: card number */ ++ MK_ARRAY(TYPE_CHAR, 64), /* ID (user selectable) */ ++ MK_ARRAY(TYPE_CHAR, 80), /* name of this device */ ++ MK_ARRAY(TYPE_CHAR, 32), /* subdevice name */ ++ TYPE_INT, /* SNDRV_PCM_CLASS_* */ ++ TYPE_INT, /* SNDRV_PCM_SUBCLASS_* */ ++ TYPE_INT, ++ TYPE_INT, ++ MK_ARRAY(TYPE_INT, 4), ++ ++ MK_ARRAY(TYPE_CHAR, 64) /* reserved for future... */ ++) ++ ++STRUCT( sndrv_interval, ++ TYPE_INT, ++ TYPE_INT, ++ TYPE_INTBITFIELD ++) ++ ++STRUCT( sndrv_mask, ++ MK_ARRAY(TYPE_INT, (SNDRV_MASK_MAX+31)/32) ++) ++ ++STRUCT( sndrv_pcm_hw_params, ++ TYPE_INT, ++ MK_ARRAY(MK_STRUCT(STRUCT_sndrv_mask),SNDRV_PCM_HW_PARAM_LAST_MASK - SNDRV_PCM_HW_PARAM_FIRST_MASK + 1), ++ MK_ARRAY(MK_STRUCT(STRUCT_sndrv_mask), 5), /* reserved masks */ ++ MK_ARRAY(MK_STRUCT(STRUCT_sndrv_interval), SNDRV_PCM_HW_PARAM_LAST_INTERVAL - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1), ++ MK_ARRAY(MK_STRUCT(STRUCT_sndrv_interval), 9), /* reserved intervals */ ++ TYPE_INT, /* W: requested masks */ ++ TYPE_INT, /* R: changed masks */ ++ TYPE_INT, /* R: Info flags for returned setup */ ++ TYPE_INT, /* R: used most significant bits */ ++ TYPE_INT, /* R: rate numerator */ ++ TYPE_INT, /* R: rate denominator */ ++ TYPE_LONG, /* R: chip FIFO size in frames */ ++ MK_ARRAY(TYPE_CHAR, 64) /* reserved for future */ ++) ++ ++STRUCT( sndrv_pcm_sw_params, ++ TYPE_INT, /* timestamp mode */ ++ TYPE_INT, ++ TYPE_INT, /* min ticks to sleep */ ++ TYPE_LONG, /* min avail frames for wakeup */ ++ TYPE_LONG, /* xfer size need to be a multiple */ ++ TYPE_LONG, /* min hw_avail frames for automatic start */ ++ TYPE_LONG, /* min avail frames for automatic stop */ ++ TYPE_LONG, /* min distance from noise for silence filling */ ++ TYPE_LONG, /* silence block size */ ++ TYPE_LONG, /* poTYPE_INTers wrap point */ ++ MK_ARRAY(TYPE_CHAR, 64) /* reserved for future */ ++) ++ ++STRUCT( sndrv_pcm_channel_info, ++ TYPE_INT, ++ TYPE_LONG, /* mmap offset (FIXME) */ ++ TYPE_INT, /* offset to first sample in bits */ ++ TYPE_INT /* samples distance in bits */ ++) ++ ++ ++STRUCT( sndrv_pcm_status, ++ TYPE_INT, /* stream state */ ++ MK_STRUCT(STRUCT_timespec), /* time when stream was started/stopped/paused */ ++ MK_STRUCT(STRUCT_timespec), /* reference timestamp */ ++ TYPE_LONG, /* appl ptr */ ++ TYPE_LONG, /* hw ptr */ ++ TYPE_LONG, /* current delay in frames */ ++ TYPE_LONG, /* number of frames available */ ++ TYPE_LONG, /* max frames available on hw since last status */ ++ TYPE_LONG, /* count of ADC (capture) overrange detections from last status */ ++ TYPE_INT, /* suspended stream state */ ++ MK_ARRAY(TYPE_CHAR, 60) /* must be filled with zero */ ++) ++ ++STRUCT( sndrv_pcm_mmap_status, ++ TYPE_INT, /* RO: state - SNDRV_PCM_STATE_XXXX */ ++ TYPE_INT, /* Needed for 64 bit alignment */ ++ TYPE_LONG, /* RO: hw ptr (0...boundary-1) */ ++ MK_STRUCT(STRUCT_timespec), /* Timestamp */ ++ TYPE_INT /* RO: suspended stream state */ ++) ++ ++STRUCT( sndrv_pcm_mmap_control, ++ TYPE_LONG, /* RW: appl ptr (0...boundary-1) */ ++ TYPE_LONG /* RW: min available frames for wakeup */ ++) ++ ++STRUCT( sndrv_pcm_sync_ptr, ++ TYPE_INT, ++ // FIXME: does not work with 64-bit target ++ MK_STRUCT(STRUCT_sndrv_pcm_mmap_status), // 28 bytes on 32-bit target ++ MK_ARRAY(TYPE_CHAR, 64 - 24), // so we pad to 64 bytes (was a union) ++ ++ MK_STRUCT(STRUCT_sndrv_pcm_mmap_control), // 8 bytes on 32-bit target ++ MK_ARRAY(TYPE_CHAR, 64 - 8) // so we pad to 64 bytes (was a union)) ++) ++ ++STRUCT( sndrv_xferi, ++ TYPE_LONG, ++ TYPE_PTRVOID, ++ TYPE_LONG ++) ++ ++STRUCT( sndrv_xfern, ++ TYPE_LONG, ++ TYPE_PTRVOID, ++ TYPE_LONG ++) ++ ++STRUCT( sndrv_rawmidi_info, ++ TYPE_INT, /* RO/WR (control): device number */ ++ TYPE_INT, /* RO/WR (control): subdevice number */ ++ TYPE_INT, /* WR: stream */ ++ TYPE_INT, /* R: card number */ ++ TYPE_INT, /* SNDRV_RAWMIDI_INFO_XXXX */ ++ MK_ARRAY(TYPE_CHAR, 64), /* ID (user selectable) */ ++ MK_ARRAY(TYPE_CHAR, 80), /* name of device */ ++ MK_ARRAY(TYPE_CHAR, 32), /* name of active or selected subdevice */ ++ TYPE_INT, ++ TYPE_INT, ++ MK_ARRAY(TYPE_CHAR, 64) /* reserved for future use */ ++) ++ ++STRUCT( sndrv_rawmidi_params, ++ TYPE_INT, ++ TYPE_LONG, /* queue size in bytes */ ++ TYPE_LONG, /* minimum avail bytes for wakeup */ ++ TYPE_INT, /* do not send active sensing byte in close() */ ++ MK_ARRAY(TYPE_CHAR, 16) /* reserved for future use */ ++) ++ ++STRUCT( sndrv_rawmidi_status, ++ TYPE_INT, ++ MK_STRUCT(STRUCT_timespec), /* Timestamp */ ++ TYPE_LONG, /* available bytes */ ++ TYPE_LONG, /* count of overruns since last status (in bytes) */ ++ MK_ARRAY(TYPE_CHAR, 16) /* reserved for future use */ ++) ++ ++STRUCT( sndrv_timer_ginfo, ++ MK_STRUCT(STRUCT_sndrv_timer_id), /* requested timer ID */ ++ TYPE_INT, /* timer flags - SNDRV_TIMER_FLG_* */ ++ TYPE_INT, /* card number */ ++ MK_ARRAY(TYPE_CHAR, 64), /* timer identification */ ++ MK_ARRAY(TYPE_CHAR, 80), /* timer name */ ++ TYPE_LONG, /* reserved for future use */ ++ TYPE_LONG, /* average period resolution in ns */ ++ TYPE_LONG, /* minimal period resolution in ns */ ++ TYPE_LONG, /* maximal period resolution in ns */ ++ TYPE_INT, /* active timer clients */ ++ MK_ARRAY(TYPE_CHAR, 32) ++) ++ ++STRUCT( sndrv_timer_gparams, ++ MK_STRUCT(STRUCT_sndrv_timer_id), /* requested timer ID */ ++ TYPE_LONG, /* requested precise period duration (in seconds) - numerator */ ++ TYPE_LONG, /* requested precise period duration (in seconds) - denominator */ ++ MK_ARRAY(TYPE_CHAR, 32) ++) ++ ++STRUCT( sndrv_timer_gstatus, ++ MK_STRUCT(STRUCT_sndrv_timer_id), /* requested timer ID */ ++ TYPE_LONG, /* current period resolution in ns */ ++ TYPE_LONG, /* precise current period resolution (in seconds) - numerator */ ++ TYPE_LONG, /* precise current period resolution (in seconds) - denominator */ ++ MK_ARRAY(TYPE_CHAR, 32) ++) ++ ++STRUCT( sndrv_timer_select, ++ MK_STRUCT(STRUCT_sndrv_timer_id), /* bind to timer ID */ ++ MK_ARRAY(TYPE_CHAR, 32) /* reserved */ ++) ++ ++STRUCT( sndrv_timer_info, ++ TYPE_INT, /* timer flags - SNDRV_TIMER_FLG_* */ ++ TYPE_INT, /* card number */ ++ MK_ARRAY(TYPE_CHAR, 64), /* timer identificator */ ++ MK_ARRAY(TYPE_CHAR, 80), /* timer name */ ++ TYPE_LONG, /* reserved for future use */ ++ TYPE_LONG, /* average period resolution in ns */ ++ MK_ARRAY(TYPE_CHAR, 64) /* reserved */ ++) ++ ++STRUCT( sndrv_timer_params, ++ TYPE_INT, /* flags - SNDRV_MIXER_PSFLG_* */ ++ TYPE_INT, /* requested resolution in ticks */ ++ TYPE_INT, /* total size of queue (32-1024) */ ++ TYPE_INT, ++ TYPE_INT, /* event filter (bitmask of SNDRV_TIMER_EVENT_*) */ ++ MK_ARRAY(TYPE_CHAR, 60) /* reserved */ ++) ++ ++STRUCT( sndrv_timer_status, ++ MK_STRUCT(STRUCT_timespec), /* Timestamp - last update */ ++ TYPE_INT, /* current period resolution in ns */ ++ TYPE_INT, /* counter of master tick lost */ ++ TYPE_INT, /* count of read queue overruns */ ++ TYPE_INT, /* used queue size */ ++ MK_ARRAY(TYPE_CHAR, 64) /* reserved */ ++) ++ ++STRUCT( sndrv_timer_read, ++ TYPE_INT, ++ TYPE_INT ++) ++ ++STRUCT( sndrv_timer_tread, ++ TYPE_INT, ++ MK_STRUCT(STRUCT_timespec), ++ TYPE_INT ++) ++ ++STRUCT( sndrv_ctl_card_info, ++ TYPE_INT, /* card number */ ++ TYPE_INT, /* reserved for future (was type) */ ++ MK_ARRAY(TYPE_CHAR, 16), /* ID of card (user selectable) */ ++ MK_ARRAY(TYPE_CHAR, 16), /* Driver name */ ++ MK_ARRAY(TYPE_CHAR, 32), /* Short name of soundcard */ ++ MK_ARRAY(TYPE_CHAR, 80), /* name + info text about soundcard */ ++ MK_ARRAY(TYPE_CHAR, 16), /* reserved for future (was ID of mixer) */ ++ MK_ARRAY(TYPE_CHAR, 80), /* visual mixer identification */ ++ MK_ARRAY(TYPE_CHAR, 80), /* card components / fine identification, delimited with one space (AC97 etc..) */ ++ MK_ARRAY(TYPE_CHAR, 48) /* reserved for future */ ++) ++ ++STRUCT( sndrv_ctl_elem_id, ++ TYPE_INT, ++ TYPE_INT, /* interface identifier */ ++ TYPE_INT, /* device/client number */ ++ TYPE_INT, /* subdevice (substream) number */ ++ MK_ARRAY(TYPE_CHAR, 44), /* ASCII name of item */ ++ TYPE_INT /* index of item */ ++) ++ ++STRUCT( sndrv_ctl_elem_list, ++ TYPE_INT, /* W: first element ID to get */ ++ TYPE_INT, /* W: count of element IDs to get */ ++ TYPE_INT, /* R: count of element IDs set */ ++ TYPE_INT, /* R: count of all elements */ ++ MK_STRUCT(STRUCT_sndrv_ctl_elem_id), /* R: IDs */ ++ MK_ARRAY(TYPE_CHAR, 50) ++) ++ ++STRUCT( sndrv_ctl_elem_info, ++ MK_STRUCT(STRUCT_sndrv_ctl_elem_id), /* W: element ID */ ++ TYPE_INT, /* R: value type - SNDRV_CTL_ELEM_TYPE_* */ ++ TYPE_INT, /* R: value access (bitmask) - SNDRV_CTL_ELEM_ACCESS_* */ ++ TYPE_INT, /* count of values */ ++ TYPE_INT, /* owner's PID of this control */ ++ MK_ARRAY(TYPE_CHAR, 128), // FIXME: prone to break (was union) ++ MK_ARRAY(TYPE_SHORT, 4), /* dimensions */ ++ MK_ARRAY(TYPE_CHAR, 64-4*sizeof(unsigned short)) ++) ++ ++STRUCT( sndrv_ctl_elem_value, ++ MK_STRUCT(STRUCT_sndrv_ctl_elem_id), /* W: element ID */ ++ TYPE_INT, /* W: use indirect pointer (xxx_ptr member) */ ++ MK_ARRAY(TYPE_INT, 128), ++ MK_STRUCT(STRUCT_timespec), ++ MK_ARRAY(TYPE_CHAR, 128-sizeof(struct timespec)) // FIXME: breaks on 64-bit host ++) ++ ++STRUCT( sndrv_ctl_tlv, ++ TYPE_INT, /* control element numeric identification */ ++ TYPE_INT, /* in bytes aligned to 4 */ ++ MK_ARRAY(TYPE_INT, 0) /* first TLV */ // FIXME: what is this supposed to become? ++) ++ ++STRUCT( sndrv_ctl_event, ++ TYPE_INT, /* event type - SNDRV_CTL_EVENT_* */ ++ TYPE_INT, ++ MK_STRUCT(STRUCT_sndrv_ctl_elem_id) // 64 bytes ++) ++ ++STRUCT( iovec, ++ TYPE_PTRVOID, ++ TYPE_LONG ++ ) ++ ++ ++STRUCT( sndrv_xferv, ++ MK_STRUCT(STRUCT_iovec), ++ TYPE_LONG ++) ++ ++STRUCT(emu10k1_fx8010_info, ++ TYPE_INT, /* in samples */ ++ TYPE_INT, /* in samples */ ++ MK_ARRAY(MK_ARRAY(TYPE_CHAR, 32), 16), /* names of FXBUSes */ ++ MK_ARRAY(MK_ARRAY(TYPE_CHAR, 32), 16), /* names of external inputs */ ++ MK_ARRAY(MK_ARRAY(TYPE_CHAR, 32), 32), /* names of external outputs */ ++ TYPE_INT /* count of GPR controls */ ++) ++ ++STRUCT(emu10k1_ctl_elem_id, ++ TYPE_INT, /* don't use */ ++ TYPE_INT, /* interface identifier */ ++ TYPE_INT, /* device/client number */ ++ TYPE_INT, /* subdevice (substream) number */ ++ MK_ARRAY(TYPE_CHAR, 44), /* ASCII name of item */ ++ TYPE_INT /* index of item */ ++) ++ ++STRUCT(emu10k1_fx8010_control_gpr, ++ MK_STRUCT(STRUCT_emu10k1_ctl_elem_id), /* full control ID definition */ ++ TYPE_INT, /* visible count */ ++ TYPE_INT, /* count of GPR (1..16) */ ++ MK_ARRAY(TYPE_SHORT, 32), /* GPR number(s) */ ++ MK_ARRAY(TYPE_INT, 32), /* initial values */ ++ TYPE_INT, /* minimum range */ ++ TYPE_INT, /* maximum range */ ++ TYPE_INT, /* translation type (EMU10K1_GPR_TRANSLATION*) */ ++ TYPE_INT ++) ++ ++#ifndef TARGET_LONG_SIZE ++#define TARGET_LONG_SIZE 4 ++#endif ++ ++STRUCT(emu10k1_fx8010_code, ++ MK_ARRAY(TYPE_CHAR, 128), ++ ++ MK_ARRAY(TYPE_LONG, 0x200/(TARGET_LONG_SIZE*8)), /* bitmask of valid initializers */ ++ TYPE_PTRVOID, /* initializers */ ++ ++ TYPE_INT, /* count of GPR controls to add/replace */ ++ MK_STRUCT(STRUCT_emu10k1_fx8010_control_gpr), /* GPR controls to add/replace */ ++ ++ TYPE_INT, /* count of GPR controls to remove */ ++ MK_STRUCT(STRUCT_emu10k1_ctl_elem_id), /* IDs of GPR controls to remove */ ++ ++ TYPE_INT, /* count of GPR controls to list */ ++ TYPE_INT, /* total count of GPR controls */ ++ MK_STRUCT(STRUCT_emu10k1_fx8010_control_gpr), /* listed GPR controls */ ++ ++ MK_ARRAY(TYPE_LONG, 0x100/(TARGET_LONG_SIZE*8)), /* bitmask of valid initializers */ ++ TYPE_PTRVOID, /* data initializers */ ++ TYPE_PTRVOID, /* map initializers */ ++ ++ MK_ARRAY(TYPE_LONG, 1024/(TARGET_LONG_SIZE*8)), /* bitmask of valid instructions */ ++ TYPE_PTRVOID /* one instruction - 64 bits */ ++) ++ ++STRUCT(emu10k1_fx8010_tram, ++ TYPE_INT, /* 31.bit == 1 -> external TRAM */ ++ TYPE_INT, /* size in samples (4 bytes) */ ++ TYPE_INT /* pointer to samples (20-bit) */ ++ /* NULL->clear memory */ ++) ++ ++STRUCT(emu10k1_fx8010_pcm, ++ TYPE_INT, /* substream number */ ++ TYPE_INT, /* reserved */ ++ TYPE_INT, ++ TYPE_INT, /* ring buffer position in TRAM (in samples) */ ++ TYPE_INT, /* count of buffered samples */ ++ TYPE_SHORT, /* GPR containing size of ringbuffer in samples (host) */ ++ TYPE_SHORT, ++ TYPE_SHORT, /* GPR containing count of samples between two TYPE_INTerrupts (host) */ ++ TYPE_SHORT, ++ TYPE_SHORT, /* GPR containing trigger (activate) information (host) */ ++ TYPE_SHORT, /* GPR containing info if PCM is running (FX8010) */ ++ TYPE_CHAR, /* reserved */ ++ MK_ARRAY(TYPE_CHAR, 32), /* external TRAM address & data (one per channel) */ ++ TYPE_INT /* reserved */ ++) ++ ++STRUCT( hdsp_peak_rms, ++ MK_ARRAY(TYPE_INT, 26), ++ MK_ARRAY(TYPE_INT, 26), ++ MK_ARRAY(TYPE_INT, 28), ++ MK_ARRAY(TYPE_LONGLONG, 26), ++ MK_ARRAY(TYPE_LONGLONG, 26), ++ /* These are only used for H96xx cards */ ++ MK_ARRAY(TYPE_LONGLONG, 26) ++) ++ ++STRUCT( hdsp_config_info, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ MK_ARRAY(TYPE_CHAR, 3), ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_INT, ++ TYPE_INT, ++ TYPE_INT, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR, ++ TYPE_CHAR ++) ++ ++STRUCT( hdsp_firmware, ++ TYPE_PTRVOID /* 24413 x 4 bytes */ ++) ++ ++STRUCT( hdsp_version, ++ TYPE_INT, ++ TYPE_SHORT ++) ++ ++STRUCT( hdsp_mixer, ++ MK_ARRAY(TYPE_SHORT, HDSP_MATRIX_MIXER_SIZE) ++) ++ ++STRUCT( hdsp_9632_aeb, ++ TYPE_INT, ++ TYPE_INT ++) ++ ++STRUCT( snd_sb_csp_mc_header, ++ MK_ARRAY(TYPE_CHAR, 16), /* id name of codec */ ++ TYPE_SHORT /* requested function */ ++) ++ ++STRUCT( snd_sb_csp_microcode, ++ MK_STRUCT(STRUCT_snd_sb_csp_mc_header), ++ MK_ARRAY(TYPE_CHAR, SNDRV_SB_CSP_MAX_MICROCODE_FILE_SIZE) ++) ++ ++STRUCT( snd_sb_csp_start, ++ TYPE_INT, ++ TYPE_INT ++) ++ ++STRUCT( snd_sb_csp_info, ++ MK_ARRAY(TYPE_CHAR, 16), /* id name of codec */ ++ TYPE_SHORT, /* function number */ ++ TYPE_INT, /* accepted PCM formats */ ++ TYPE_SHORT, /* accepted channels */ ++ TYPE_SHORT, /* accepted sample width */ ++ TYPE_SHORT, /* accepted sample rates */ ++ TYPE_SHORT, ++ TYPE_SHORT, /* current channels */ ++ TYPE_SHORT, /* current sample width */ ++ TYPE_SHORT, /* version id: 0x10 - 0x1f */ ++ TYPE_SHORT /* state bits */ ++) ++ ++STRUCT( sscape_bootblock, ++ MK_ARRAY(TYPE_CHAR, 256), ++ TYPE_INT ++) ++ ++STRUCT( sscape_microcode, ++ TYPE_PTRVOID ++) ++ diff --git a/qemu-cvs-alsa_mmap.patch b/qemu-cvs-alsa_mmap.patch new file mode 100644 index 00000000..1b34f51b --- /dev/null +++ b/qemu-cvs-alsa_mmap.patch @@ -0,0 +1,32 @@ +Index: qemu/linux-user/mmap.c +=================================================================== +--- qemu.orig/linux-user/mmap.c ++++ qemu/linux-user/mmap.c +@@ -152,6 +152,9 @@ static int mmap_frag(target_ulong real_s + return 0; + } + ++#define SNDRV_PCM_MMAP_OFFSET_STATUS 0x80000000 ++#define SNDRV_PCM_MMAP_OFFSET_CONTROL 0x81000000 ++ + /* NOTE: all the constants are the HOST ones */ + long target_mmap(target_ulong start, target_ulong len, int prot, + int flags, int fd, target_ulong offset) +@@ -192,6 +195,17 @@ long target_mmap(target_ulong start, tar + } + #endif + ++ /* Alsa tries to communcate with the kernel via mmap. This usually ++ * is a good idea when user- and kernelspace are running on the ++ * same architecture but does not work out when not. To make alsa ++ * not to use mmap, we can just have it fail on the mmap calls that ++ * would initiate this. ++ */ ++ if(offset == SNDRV_PCM_MMAP_OFFSET_STATUS || offset == SNDRV_PCM_MMAP_OFFSET_CONTROL) { ++ errno = EINVAL; ++ return -1; ++ } ++ + if (offset & ~TARGET_PAGE_MASK) { + errno = EINVAL; + return -1; diff --git a/qemu-cvs-flash.patch b/qemu-cvs-flash.patch new file mode 100644 index 00000000..22464548 --- /dev/null +++ b/qemu-cvs-flash.patch @@ -0,0 +1,13 @@ +Index: qemu/linux-user/syscall.c +=================================================================== +--- qemu.orig/linux-user/syscall.c ++++ qemu/linux-user/syscall.c +@@ -1736,6 +1736,8 @@ static long do_ipc(long call, long first + + switch (call) { + case IPCOP_semop: ++ ret = -EINVAL; ++ break; + { + struct sembuf *target_sops; + int i; diff --git a/qemu-cvs-futex.patch b/qemu-cvs-futex.patch new file mode 100644 index 00000000..b8d38770 --- /dev/null +++ b/qemu-cvs-futex.patch @@ -0,0 +1,125 @@ +Index: qemu.bkp/linux-user/syscall.c +=================================================================== +--- qemu.bkp.orig/linux-user/syscall.c ++++ qemu.bkp/linux-user/syscall.c +@@ -17,6 +17,8 @@ + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ ++ ++#define __user + #include + #include + #include +@@ -60,6 +62,7 @@ + #define tchars host_tchars /* same as target */ + #define ltchars host_ltchars /* same as target */ + ++#include + #include + #include + #include +@@ -2554,6 +2557,91 @@ static inline void host_to_target_timesp + unlock_user_struct(target_ts, target_addr, 1); + } + ++#ifdef BSWAP_NEEDED ++static int futex_op(int oldval, int op, int oparg) ++{ ++ int retval = oparg; ++ switch(op) { ++ case FUTEX_OP_SET: break; ++ case FUTEX_OP_ADD: retval += oparg; break; ++ case FUTEX_OP_OR: retval |= oparg; break; ++ case FUTEX_OP_ANDN: retval &= oparg; break; ++ case FUTEX_OP_XOR: retval ^= oparg; break; ++ } ++ return retval; ++} ++ ++static int futex_cmp(int oldval, int cmp, int cmparg) ++{ ++ switch(cmp) { ++ case FUTEX_OP_CMP_EQ: return oldval == cmparg; ++ case FUTEX_OP_CMP_NE: return oldval != cmparg; ++ case FUTEX_OP_CMP_LT: return oldval < cmparg; ++ case FUTEX_OP_CMP_LE: return oldval <= cmparg; ++ case FUTEX_OP_CMP_GT: return oldval > cmparg; ++ case FUTEX_OP_CMP_GE: return oldval >= cmparg; ++ } ++ return -1; ++} ++#endif ++ ++static long do_futex(target_ulong uaddr, int op, uint32_t val, ++ target_ulong utime, target_ulong uaddr2, ++ uint32_t val3) ++{ ++ struct timespec host_utime; ++ unsigned long val2 = utime; ++ long retval; ++ ++ if (utime && (op == FUTEX_WAIT || op == FUTEX_LOCK_PI)) { ++ target_to_host_timespec(&host_utime, utime); ++ val2 = (unsigned long)&host_utime; ++ } ++ ++#ifdef BSWAP_NEEDED ++ switch(op) { ++ case FUTEX_CMP_REQUEUE: ++ val3 = tswap32(val3); ++ case FUTEX_REQUEUE: ++ val2 = tswap32(val2); ++ case FUTEX_WAIT: ++ case FUTEX_WAKE: ++ case FUTEX_WAKE_OP: ++ val = tswap32(val); ++ case FUTEX_LOCK_PI: /* This one's icky, but comes out OK */ ++ case FUTEX_UNLOCK_PI: ++ break; ++ default: ++ gemu_log("qemu: Unsupported futex op %d\n", op); ++ return -ENOSYS; ++ } ++ if (op == FUTEX_WAKE_OP) { ++ /* Need to munge the secondary operation (val3) */ ++ gemu_log("qemu: Tricky FUTEX_WAKE_OP - trying to emulate it\n"); ++ val3 = tswap32(val3); ++ int op2 = (val3 >> 28) & 0xf; ++ int cmp = (val3 >> 24) & 0xf; ++ int oparg = (val3 >> 12) & 0xfff; ++ int cmparg = val3 & 0xfff; ++ int shift = val3 & (FUTEX_OP_OPARG_SHIFT << 28); ++ int oldval = tget32(uaddr2); ++ if (shift) ++ oparg = 1 << oparg; ++ ++ tput32(uaddr2,futex_op(oldval, op2, oparg)); ++ retval = syscall(__NR_futex, g2h(uaddr), FUTEX_WAKE, val, 0, 0, 0); ++ if(futex_cmp(oldval, cmp, cmparg)) { ++ retval = syscall(__NR_futex, g2h(uaddr2), FUTEX_WAKE, val2, 0, 0, 0); ++ } ++ } else { ++ retval = syscall(__NR_futex, g2h(uaddr), op, val, val2, g2h(uaddr2), val3); ++ } ++#else ++ retval = syscall(__NR_futex, g2h(uaddr), op, val, val2, g2h(uaddr2), val3); ++#endif ++ return retval; ++} ++ + long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, + long arg4, long arg5, long arg6) + { +@@ -4713,6 +4801,11 @@ long do_syscall(void *cpu_env, int num, + } + #endif + ++#ifdef TARGET_NR_futex ++ case TARGET_NR_futex: ++ ret = get_errno(do_futex(arg1, arg2, arg3, arg4, arg5, arg6)); ++ break; ++#endif + #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address) + case TARGET_NR_set_tid_address: + ret = get_errno(set_tid_address((int *) arg1)); diff --git a/qemu-cvs-gettimeofday.patch b/qemu-cvs-gettimeofday.patch new file mode 100644 index 00000000..14a37d6d --- /dev/null +++ b/qemu-cvs-gettimeofday.patch @@ -0,0 +1,34 @@ +Index: qemu/linux-user/syscall.c +=================================================================== +--- qemu.orig/linux-user/syscall.c ++++ qemu/linux-user/syscall.c +@@ -3596,6 +3596,7 @@ long do_syscall(void *cpu_env, int num, + case TARGET_NR_gettimeofday: + { + struct timeval tv; ++ target_to_host_timeval(&tv, arg1); + ret = get_errno(gettimeofday(&tv, NULL)); + if (!is_error(ret)) { + host_to_target_timeval(arg1, &tv); +Index: qemu/linux-user/signal.c +=================================================================== +--- qemu.orig/linux-user/signal.c ++++ qemu/linux-user/signal.c +@@ -207,6 +207,8 @@ static inline void host_to_target_siginf + /* should never come here, but who knows. The information for + the target is irrelevant */ + tinfo->_sifields._sigfault._addr = 0; ++ } else if (sig == SIGIO) { ++ tinfo->_sifields._sigpoll._fd = info->si_fd; + } else if (sig >= TARGET_SIGRTMIN) { + tinfo->_sifields._rt._pid = info->si_pid; + tinfo->_sifields._rt._uid = info->si_uid; +@@ -228,6 +230,8 @@ static void tswap_siginfo(target_siginfo + sig == SIGBUS || sig == SIGTRAP) { + tinfo->_sifields._sigfault._addr = + tswapl(info->_sifields._sigfault._addr); ++ } else if (sig == SIGIO) { ++ tinfo->_sifields._sigpoll._fd = tswap32(info->_sifields._sigpoll._fd); + } else if (sig >= TARGET_SIGRTMIN) { + tinfo->_sifields._rt._pid = tswap32(info->_sifields._rt._pid); + tinfo->_sifields._rt._uid = tswap32(info->_sifields._rt._uid); diff --git a/qemu-cvs-ia64.patch b/qemu-cvs-ia64.patch new file mode 100644 index 00000000..ca245f6c --- /dev/null +++ b/qemu-cvs-ia64.patch @@ -0,0 +1,47 @@ +--- Makefile.target.~1.186.~ 2007-07-02 17:08:34.000000000 +0200 ++++ Makefile.target 2007-07-09 19:13:35.000000000 +0200 +@@ -92,6 +92,8 @@ cc-option = $(shell if $(CC) $(OP_CFLAGS + OP_CFLAGS+=$(call cc-option, -fno-reorder-blocks, "") + OP_CFLAGS+=$(call cc-option, -fno-gcse, "") + OP_CFLAGS+=$(call cc-option, -fno-tree-ch, "") ++OP_CFLAGS+=$(call cc-option, -fno-tree-dominator-opts, "") ++OP_CFLAGS+=$(call cc-option, -fno-tree-vrp, "") + OP_CFLAGS+=$(call cc-option, -fno-optimize-sibling-calls, "") + OP_CFLAGS+=$(call cc-option, -fno-crossjumping, "") + OP_CFLAGS+=$(call cc-option, -fno-align-labels, "") +@@ -165,8 +167,9 @@ BASE_LDFLAGS+=-Wl,-T,$(SRC_PATH)/$(ARCH) + endif + + ifeq ($(ARCH),ia64) +-BASE_CFLAGS+=-mno-sdata +-OP_CFLAGS+=-mno-sdata ++OP_CFLAGS+=$(call cc-option, -mno-sched-ar-data-spec, "") ++BASE_CFLAGS+=-G0 -mno-sdata ++OP_CFLAGS+=-G0 -mno-sdata + BASE_LDFLAGS+=-Wl,-G0 -Wl,-T,$(SRC_PATH)/$(ARCH).ld + endif + +--- target-alpha/op.c.~1.1.~ 2007-04-05 08:58:33.000000000 +0200 ++++ target-alpha/op.c 2007-07-09 20:11:42.000000000 +0200 +@@ -18,8 +18,6 @@ + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +-#define DEBUG_OP +- + #include "config.h" + #include "exec.h" + +@@ -125,8 +123,12 @@ + void OPPROTO op_no_op (void) + { + #if !defined (DEBUG_OP) ++#ifdef __ia64__ ++ __asm__ __volatile__("nop 0" : : : "memory"); ++#else + __asm__ __volatile__("nop" : : : "memory"); + #endif ++#endif + RETURN(); + } + diff --git a/qemu-cvs-img.patch b/qemu-cvs-img.patch new file mode 100644 index 00000000..b5744dd8 --- /dev/null +++ b/qemu-cvs-img.patch @@ -0,0 +1,11 @@ +--- Makefile.orig 2007-07-05 14:43:40.000000000 +0000 ++++ Makefile 2007-07-05 14:46:50.000000000 +0000 +@@ -33,7 +33,7 @@ + recurse-all: $(patsubst %,subdir-%, $(TARGET_DIRS)) + + qemu-img$(EXESUF): qemu-img.c cutils.c block.c block-raw.c block-cow.c block-qcow.c aes.c block-vmdk.c block-cloop.c block-dmg.c block-bochs.c block-vpc.c block-vvfat.c block-qcow2.c +- $(CC) -DQEMU_TOOL $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) $(LDFLAGS) $(BASE_LDFLAGS) -o $@ $^ -lz $(LIBS) ++ $(CC) -DQEMU_TOOL $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) $(LDFLAGS) -o $@ $^ -lz $(LIBS) + + dyngen$(EXESUF): dyngen.c + $(HOST_CC) $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -o $@ $^ diff --git a/qemu-cvs-ioctl_debug.patch b/qemu-cvs-ioctl_debug.patch new file mode 100644 index 00000000..cd3ca9c1 --- /dev/null +++ b/qemu-cvs-ioctl_debug.patch @@ -0,0 +1,18 @@ +Index: qemu/linux-user/syscall.c +=================================================================== +--- qemu.orig/linux-user/syscall.c ++++ qemu/linux-user/syscall.c +@@ -1950,7 +1950,12 @@ static long do_ioctl(long fd, long cmd, + ie = ioctl_entries; + for(;;) { + if (ie->target_cmd == 0) { +- gemu_log("Unsupported ioctl: cmd=0x%04lx\n", cmd); ++ int i; ++ gemu_log("Unsupported ioctl: cmd=0x%04lx (%x)\n", cmd, (cmd & (TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) >> TARGET_IOC_SIZESHIFT); ++ for(i=0;ioctl_entries[i].target_cmd;i++) { ++ if((ioctl_entries[i].target_cmd & ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) == (cmd & ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT))) ++ gemu_log("%p\t->\t%s (%x)\n", ioctl_entries[i].host_cmd, ioctl_entries[i].name, (ioctl_entries[i].target_cmd & (TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) >> TARGET_IOC_SIZESHIFT); ++ } + return -ENOSYS; + } + if (ie->target_cmd == cmd) diff --git a/qemu-cvs-ioctl_nodirection.patch b/qemu-cvs-ioctl_nodirection.patch new file mode 100644 index 00000000..11c99d08 --- /dev/null +++ b/qemu-cvs-ioctl_nodirection.patch @@ -0,0 +1,24 @@ +Index: qemu/linux-user/syscall.c +=================================================================== +--- qemu.orig/linux-user/syscall.c ++++ qemu/linux-user/syscall.c +@@ -1980,6 +1980,11 @@ static long do_ioctl(long fd, long cmd, + arg_type++; + target_size = thunk_type_size(arg_type, 0); + switch(ie->access) { ++ /* FIXME: actually the direction given in the ioctl should be ++ * correct so we can assume the communication is uni-directional. ++ * The alsa developers did not like this concept though and ++ * declared ioctls IOC_R and IOC_W even though they were IOC_RW.*/ ++/* + case IOC_R: + ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp)); + if (!is_error(ret)) { +@@ -1994,6 +1999,7 @@ static long do_ioctl(long fd, long cmd, + unlock_user(argptr, arg, 0); + ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp)); + break; ++*/ + default: + case IOC_RW: + argptr = lock_user(arg, target_size, 1); diff --git a/qemu-cvs-ipc.patch b/qemu-cvs-ipc.patch new file mode 100644 index 00000000..82b3ae3c --- /dev/null +++ b/qemu-cvs-ipc.patch @@ -0,0 +1,341 @@ +Index: qemu/linux-user/syscall.c +=================================================================== +--- qemu.orig/linux-user/syscall.c ++++ qemu/linux-user/syscall.c +@@ -29,7 +29,7 @@ + #include + #include + #include +-#include ++#include + #include + #include + #include +@@ -46,6 +46,9 @@ + #include + #include + #include ++#include ++#include ++#include + #include + #include + #include +@@ -150,6 +153,7 @@ type name (type1 arg1,type2 arg2,type3 a + #define __NR_sys_tgkill __NR_tgkill + #define __NR_sys_clone __NR_clone + #define __NR_sys_sched_getaffinity __NR_sched_getaffinity ++#define __NR_sys_ipc __NR_ipc + + #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__) + #define __NR__llseek __NR_lseek +@@ -172,6 +176,10 @@ _syscall3(int,sys_rt_sigqueueinfo,int,pi + _syscall3(int,sys_syslog,int,type,char*,bufp,int,len) + _syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig) + _syscall5(int,sys_clone, int, flags, void *, child_stack, int *, parent_tidptr, void *, newtls, int *, child_tidptr) ++#ifdef __NR_ipc ++_syscall6(int,sys_ipc, long, call, long, first, long, second, long, third, void *, ptr, long, fifth) ++#define semctl(a,b,c,d) sys_ipc(IPCOP_semctl,a,b,c,&d,0l) ++#endif + _syscall3(int,sys_sched_getaffinity,pid_t,pid,unsigned int,cpusetsize,void*,mask) + #ifdef __NR_exit_group + _syscall1(int,exit_group,int,error_code) +@@ -1255,6 +1263,21 @@ struct target_ipc_perm + target_ulong __unused2; + }; + ++struct target_ipc64_perm ++{ ++ int key; ++ unsigned int uid; ++ unsigned int gid; ++ unsigned int cuid; ++ unsigned int cgid; ++ unsigned short mode; ++ unsigned short __pad1; ++ unsigned short seq; ++ unsigned short __pad2; ++ target_ulong __unused1; ++ target_ulong __unused2; ++}; ++ + struct target_semid_ds + { + struct target_ipc_perm sem_perm; +@@ -1267,6 +1290,18 @@ struct target_semid_ds + target_ulong __unused4; + }; + ++struct target_semid64_ds ++{ ++ struct target_ipc64_perm sem_perm; ++ target_ulong sem_otime; ++ target_ulong __unused1; ++ target_ulong sem_ctime; ++ target_ulong __unused2; ++ target_ulong sem_nsems; ++ target_ulong __unused3; ++ target_ulong __unused4; ++}; ++ + static inline void target_to_host_ipc_perm(struct ipc_perm *host_ip, + target_ulong target_addr) + { +@@ -1301,6 +1336,41 @@ static inline void host_to_target_ipc_pe + unlock_user_struct(target_sd, target_addr, 1); + } + ++static inline void target_to_host_ipc64_perm( struct ipc64_perm *host_ip, target_ulong target_addr ) ++{ ++ struct target_ipc64_perm *target_ip; ++ struct target_semid64_ds *target_sd; ++ ++ lock_user_struct(target_sd, target_addr, 1); ++ target_ip=&(target_sd->sem_perm); ++ host_ip->key = tswapl(target_ip->key); ++ host_ip->uid = tswapl(target_ip->uid); ++ host_ip->gid = tswapl(target_ip->gid); ++ host_ip->cuid = tswapl(target_ip->cuid); ++ host_ip->cgid = tswapl(target_ip->cgid); ++ host_ip->mode = tswap16(target_ip->mode); ++ host_ip->seq = tswap16(target_ip->seq); ++ unlock_user_struct(target_sd, target_addr, 1); ++} ++ ++static inline void host_to_target_ipc64_perm(target_ulong target_addr, ++ struct ipc64_perm *host_ip) ++{ ++ struct target_ipc64_perm *target_ip; ++ struct target_semid64_ds *target_sd; ++ ++ lock_user_struct(target_sd, target_addr, 0); ++ target_ip = &(target_sd->sem_perm); ++ target_ip->key = tswapl(host_ip->key); ++ target_ip->uid = tswapl(host_ip->uid); ++ target_ip->gid = tswapl(host_ip->gid); ++ target_ip->cuid = tswapl(host_ip->cuid); ++ target_ip->cgid = tswapl(host_ip->cgid); ++ target_ip->mode = tswap16(host_ip->mode); ++ target_ip->seq = tswap16(host_ip->seq); ++ unlock_user_struct(target_sd, target_addr, 1); ++} ++ + static inline void target_to_host_semid_ds(struct semid_ds *host_sd, + target_ulong target_addr) + { +@@ -1327,6 +1397,32 @@ static inline void host_to_target_semid_ + unlock_user_struct(target_sd, target_addr, 1); + } + ++static inline void target_to_host_semid64_ds(struct semid64_ds *host_sd, ++ target_ulong target_addr) ++{ ++ struct target_semid64_ds *target_sd; ++ ++ lock_user_struct(target_sd, target_addr, 1); ++ target_to_host_ipc64_perm(&(host_sd->sem_perm),target_addr); ++ host_sd->sem_nsems = tswapl(target_sd->sem_nsems); ++ host_sd->sem_otime = tswapl(target_sd->sem_otime); ++ host_sd->sem_ctime = tswapl(target_sd->sem_ctime); ++ unlock_user_struct(target_sd, target_addr, 0); ++} ++ ++static inline void host_to_target_semid64_ds(target_ulong target_addr, ++ struct semid64_ds *host_sd) ++{ ++ struct target_semid64_ds *target_sd; ++ ++ lock_user_struct(target_sd, target_addr, 0); ++ host_to_target_ipc64_perm(target_addr,&(host_sd->sem_perm)); ++ target_sd->sem_nsems = tswapl(host_sd->sem_nsems); ++ target_sd->sem_otime = tswapl(host_sd->sem_otime); ++ target_sd->sem_ctime = tswapl(host_sd->sem_ctime); ++ unlock_user_struct(target_sd, target_addr, 1); ++} ++ + union semun { + int val; + struct semid_ds *buf; +@@ -1339,6 +1435,10 @@ union target_semun { + unsigned short int *array; + }; + ++#ifndef IPC_64 ++#define IPC_64 0x100 ++#endif ++ + static inline void target_to_host_semun(unsigned long cmd, + union semun *host_su, + target_ulong target_addr, +@@ -1350,7 +1450,16 @@ static inline void target_to_host_semun( + case IPC_STAT: + case IPC_SET: + lock_user_struct(target_su, target_addr, 1); +- target_to_host_semid_ds(ds,target_su->buf); ++ target_to_host_semid_ds(ds,tswapl(target_su->buf)); ++ host_su->buf = ds; ++ unlock_user_struct(target_su, target_addr, 0); ++ break; ++ case IPC_STAT + IPC_64: ++ case IPC_SET + IPC_64: ++ lock_user_struct(target_su, target_addr, 1); ++ ++ //target_to_host_semid_ds(ds,tswapl(target_su->buf)); ++ target_to_host_semid64_ds((struct semid64_ds *)ds,tswapl(target_su->buf)); + host_su->buf = ds; + unlock_user_struct(target_su, target_addr, 0); + break; +@@ -1382,7 +1491,14 @@ static inline void host_to_target_semun( + case IPC_STAT: + case IPC_SET: + lock_user_struct(target_su, target_addr, 0); +- host_to_target_semid_ds(target_su->buf,ds); ++ host_to_target_semid_ds(tswapl(target_su->buf),ds); ++ unlock_user_struct(target_su, target_addr, 1); ++ break; ++ case IPC_STAT + IPC_64: ++ case IPC_SET + IPC_64: ++ lock_user_struct(target_su, target_addr, 0); ++ //host_to_target_semid_ds(tswapl(target_su->buf),ds); ++ host_to_target_semid64_ds(tswapl(target_su->buf),(struct semid64_ds *)ds); + unlock_user_struct(target_su, target_addr, 1); + break; + case GETVAL: +@@ -1406,7 +1522,8 @@ static inline long do_semctl(long first, + { + union semun arg; + struct semid_ds dsarg; +- int cmd = third&0xff; ++ struct semid64_ds dsarg64; ++ int cmd = third; // & 0xff; + long ret = 0; + + switch( cmd ) { +@@ -1435,13 +1552,23 @@ static inline long do_semctl(long first, + ret = get_errno(semctl(first, second, cmd, arg)); + host_to_target_semun(cmd,ptr,&arg,&dsarg); + break; ++ case IPC_STAT + IPC_64: ++ target_to_host_semun(cmd,&arg,ptr,(struct semid_ds *)&dsarg64); ++ ret = get_errno(semctl(first, second, cmd, arg)); ++ host_to_target_semun(cmd,ptr,&arg,(struct semid_ds *)&dsarg64); ++ break; + case IPC_SET: + target_to_host_semun(cmd,&arg,ptr,&dsarg); + ret = get_errno(semctl(first, second, cmd, arg)); + host_to_target_semun(cmd,ptr,&arg,&dsarg); + break; +- default: ++ case IPC_SET + IPC_64: ++ target_to_host_semun(cmd,&arg,ptr,(struct semid_ds *)&dsarg64); + ret = get_errno(semctl(first, second, cmd, arg)); ++ host_to_target_semun(cmd,ptr,&arg,(struct semid_ds *)&dsarg64); ++ break; ++ default: ++ ret = get_errno(semctl(first, second, cmd & 0xff, arg)); + } + + return ret; +@@ -1465,6 +1592,42 @@ struct target_msqid_ds + target_ulong __unused5; + }; + ++ ++struct target_shmid64_ds { ++ struct target_ipc64_perm shm_perm; /* operation perms */ ++ target_ulong shm_segsz; /* size of segment (bytes) */ ++ target_ulong shm_atime; /* last attach time */ ++ target_ulong __unused1; ++ target_ulong shm_dtime; /* last detach time */ ++ target_ulong __unused2; ++ target_ulong shm_ctime; /* last change time */ ++ target_ulong __unused3; ++ int32_t shm_cpid; /* pid of creator */ ++ int32_t shm_lpid; /* pid of last operator */ ++ target_ulong shm_nattch; /* no. of current attaches */ ++ target_ulong __unused4; ++ target_ulong __unused5; ++}; ++ ++/* Data structure describing a set of semaphores. */ ++struct target_shmid_ds ++ { ++ struct target_ipc_perm shm_perm; /* operation permission struct */ ++ unsigned int __unused1; ++ target_ulong shm_atime; /* time of last shmat() */ ++ unsigned int __unused2; ++ target_ulong shm_dtime; /* time of last shmdt() */ ++ unsigned int __unused3; ++ target_ulong shm_ctime; /* time of last change by shmctl() */ ++ unsigned int __unused4; ++ target_ulong shm_segsz; /* size of segment in bytes */ ++ unsigned int shm_cpid; /* pid of creator */ ++ unsigned int shm_lpid; /* pid of last shmop */ ++ target_ulong shm_nattch; /* number of current attaches */ ++ unsigned long __unused5; ++ unsigned long __unused6; ++ }; ++ + static inline void target_to_host_msqid_ds(struct msqid_ds *host_md, + target_ulong target_addr) + { +@@ -1665,11 +1828,59 @@ static long do_ipc(long call, long first + case IPCOP_shmctl: + switch(second) { + case IPC_RMID: ++ case IPC_RMID + IPC_64: + case SHM_LOCK: ++ case SHM_LOCK + IPC_64: + case SHM_UNLOCK: ++ case SHM_UNLOCK + IPC_64: + ret = get_errno(shmctl(first, second, NULL)); + break; ++ case IPC_STAT + IPC_64: ++ { ++ struct shmid64_ds buf; ++ struct target_shmid64_ds *target_buf; ++#ifdef DEBUG ++ gemu_log("qemu: doing IPC_STAT\n"); ++#endif ++ lock_user_struct(target_buf, ptr, 1); ++ ret = get_errno(shmctl(first, second, (struct shmid_ds*)&buf)); ++ ++ host_to_target_ipc64_perm(ptr, &buf.shm_perm); ++ target_buf->shm_atime = tswapl(buf.shm_atime); ++ target_buf->shm_dtime = tswapl(buf.shm_dtime); ++ target_buf->shm_ctime = tswapl(buf.shm_ctime); ++ target_buf->shm_segsz = tswapl(buf.shm_segsz); ++ target_buf->shm_cpid = tswap32(buf.shm_cpid); ++ target_buf->shm_lpid = tswap32(buf.shm_lpid); ++ target_buf->shm_nattch = tswapl(buf.shm_nattch); ++ unlock_user_struct(target_buf, ptr, 0); ++ break; ++ } ++ case IPC_SET + IPC_64: ++ { ++ struct shmid64_ds buf; ++ struct target_shmid64_ds *target_buf; ++#ifdef DEBUG ++ gemu_log("qemu: doing IPC_SET\n"); ++#endif ++ lock_user_struct(target_buf, ptr, 1); ++ ++ target_to_host_ipc64_perm(&buf.shm_perm, ptr); ++ buf.shm_atime = tswapl(target_buf->shm_atime); ++ buf.shm_dtime = tswapl(target_buf->shm_dtime); ++ buf.shm_ctime = tswapl(target_buf->shm_ctime); ++ buf.shm_segsz = tswapl(target_buf->shm_segsz); ++ buf.shm_cpid = tswap32(target_buf->shm_cpid); ++ buf.shm_lpid = tswap32(target_buf->shm_lpid); ++ buf.shm_nattch = tswapl(target_buf->shm_nattch); ++ ++ ret = get_errno(shmctl(first, second, (struct shmid_ds*)&buf)); ++ ++ unlock_user_struct(target_buf, ptr, 0); ++ break; ++ } + default: ++ gemu_log("Unsopported shmctl(%ld,%#lx)\n", second, second); + goto unimplemented; + } + break; diff --git a/qemu-cvs-ipc_semop.patch b/qemu-cvs-ipc_semop.patch new file mode 100644 index 00000000..1984196e --- /dev/null +++ b/qemu-cvs-ipc_semop.patch @@ -0,0 +1,26 @@ +Index: qemu/linux-user/syscall.c +=================================================================== +--- qemu.orig/linux-user/syscall.c ++++ qemu/linux-user/syscall.c +@@ -1573,9 +1732,19 @@ static long do_ipc(long call, long first + + switch (call) { + case IPCOP_semop: +- ret = get_errno(semop(first,(struct sembuf *) ptr, second)); ++ { ++ struct sembuf *target_sops; ++ int i; ++ lock_user_struct(target_sops, ptr, 0); ++ for(i=0; i %#x)\n", prot, prot & (PROT_READ | PROT_WRITE | PROT_EXEC)); ++ prot &= (PROT_READ | PROT_WRITE | PROT_EXEC); ++ } + if (len == 0) + return 0; + diff --git a/qemu-cvs-netlink.patch b/qemu-cvs-netlink.patch new file mode 100644 index 00000000..c9872715 --- /dev/null +++ b/qemu-cvs-netlink.patch @@ -0,0 +1,12 @@ +Index: qemu/linux-user/syscall.c +=================================================================== +--- qemu.orig/linux-user/syscall.c ++++ qemu/linux-user/syscall.c +@@ -898,6 +906,7 @@ static long do_socket(int domain, int ty + break; + } + #endif ++ if(domain == PF_NETLINK) return -EAFNOSUPPORT; /* do not make NETLINK socket connections possible */ + return get_errno(socket(domain, type, protocol)); + } + diff --git a/qemu-0.9.0-alt-path.patch b/qemu-cvs-newpath.patch similarity index 89% rename from qemu-0.9.0-alt-path.patch rename to qemu-cvs-newpath.patch index 1b5953d8..2bce5e2d 100644 --- a/qemu-0.9.0-alt-path.patch +++ b/qemu-cvs-newpath.patch @@ -1,6 +1,8 @@ ---- qemu/linux-user/path.c -+++ qemu/linux-user/path.c -@@ -1,147 +1,81 @@ +Index: qemu.bkp/linux-user/path.c +=================================================================== +--- qemu.bkp.orig/linux-user/path.c ++++ qemu.bkp/linux-user/path.c +@@ -1,159 +1,81 @@ /* Code to mangle pathnames into those matching a given prefix. eg. open("/lib/foo.so") => open("/usr/gnemul/i386-linux/lib/foo.so"); - @@ -98,28 +100,7 @@ - for (i = 0; i < child->num_entries; i++) - set_parents(child->entries[i], child); -} -+static struct path_list_head* list_head; - - void init_paths(const char *prefix) - { - if (prefix[0] != '/' || -- prefix[0] == '\0' || -- !strcmp(prefix, "/")) -+ prefix[0] == '\0' || -+ !strcmp(prefix, "/")) - return; - -- base = new_entry("", NULL, prefix+1); -- base = add_dir_maybe(base); -- if (base->num_entries == 0) { -- free (base); -- base = NULL; -- } else { -- set_parents(base, base); -- } --} -+ list_head = malloc(sizeof(struct path_list_head)); - +- -/* FIXME: Doesn't handle DIR/.. where DIR is not in emulated dir. */ -static const char * -follow_path(const struct pathelem *cursor, const char *name) @@ -144,6 +125,41 @@ - - /* Not found */ - return NULL; +-} ++static struct path_list_head* list_head; + + void init_paths(const char *prefix) + { +- char pref_buf[PATH_MAX]; +- +- if (prefix[0] == '\0' || +- !strcmp(prefix, "/")) ++ if (prefix[0] != '/' || ++ prefix[0] == '\0' || ++ !strcmp(prefix, "/")) + return; + +- if (prefix[0] != '/') { +- char *cwd = get_current_dir_name(); +- if (!cwd) +- abort(); +- strcpy(pref_buf, cwd); +- strcat(pref_buf, "/"); +- strcat(pref_buf, prefix); +- free(cwd); +- } else +- strcpy(pref_buf,prefix + 1); +- +- base = new_entry("", NULL, pref_buf); +- base = add_dir_maybe(base); +- if (base->num_entries == 0) { +- free (base); +- base = NULL; +- } else { +- set_parents(base, base); +- } ++ list_head = malloc(sizeof(struct path_list_head)); ++ + /* first element of list is prefix */ + list_head->path = strdup(prefix); + list_head->next = NULL; @@ -162,14 +178,13 @@ Could do relative by tracking cwd. */ - if (!base || name[0] != '/') - return name; -- -- return follow_path(base, name) ?: name; + if (!list_head || result[0] != '/') + goto exit; + + strncpy(newname, list_head->path, path_length); + strncat(newname, name, path_length); -+ + +- return follow_path(base, name) ?: name; + /* look for place where path should be present */ + while ( list->next && (strcmp(list->next->path, newname) < 0) ) + list = list->next; diff --git a/qemu-cvs-nofadvise64.patch b/qemu-cvs-nofadvise64.patch new file mode 100644 index 00000000..9e08293c --- /dev/null +++ b/qemu-cvs-nofadvise64.patch @@ -0,0 +1,16 @@ +Index: qemu/linux-user/syscall.c +=================================================================== +--- qemu.orig/linux-user/syscall.c ++++ qemu/linux-user/syscall.c +@@ -5059,6 +5059,11 @@ long do_syscall(void *cpu_env, int num, + goto unimplemented_nowarn; + #endif + ++#ifdef TARGET_NR_fadvise64 ++ case TARGET_NR_fadvise64: ++ goto unimplemented_nowarn; ++#endif ++ + #ifdef TARGET_NR_sched_getaffinity + case TARGET_NR_sched_getaffinity: + { diff --git a/qemu-cvs-noppcemb.patch b/qemu-cvs-noppcemb.patch new file mode 100644 index 00000000..83f2a606 --- /dev/null +++ b/qemu-cvs-noppcemb.patch @@ -0,0 +1,13 @@ +Index: qemu-0.9.0/configure +=================================================================== +--- qemu-0.9.0.orig/configure ++++ qemu-0.9.0/configure +@@ -473,7 +473,7 @@ fi + if test -z "$target_list" ; then + # these targets are portable + if [ "$softmmu" = "yes" ] ; then +- target_list="i386-softmmu ppc-softmmu sparc-softmmu x86_64-softmmu mips-softmmu mipsel-softmmu mips64-softmmu mips64el-softmmu arm-softmmu ppc64-softmmu ppcemb-softmmu m68k-softmmu z80-softmmu" ++ target_list="i386-softmmu ppc-softmmu sparc-softmmu x86_64-softmmu mips-softmmu mipsel-softmmu mips64-softmmu mips64el-softmmu arm-softmmu ppc64-softmmu m68k-softmmu z80-softmmu" + fi + # the following are Linux specific + if [ "$linux_user" = "yes" ] ; then diff --git a/qemu-cvs-pthread.patch b/qemu-cvs-pthread.patch new file mode 100644 index 00000000..91f9d810 --- /dev/null +++ b/qemu-cvs-pthread.patch @@ -0,0 +1,13 @@ +Index: qemu-0.9.0/Makefile +=================================================================== +--- qemu-0.9.0.orig/Makefile ++++ qemu-0.9.0/Makefile +@@ -12,7 +12,7 @@ BASE_CFLAGS += $(OS_CFLAGS) $(ARCH_CFLAG + BASE_LDFLAGS += $(OS_LDFLAGS) $(ARCH_LDFLAGS) + + CPPFLAGS += -I. -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE +-LIBS= ++LIBS=-lpthread + TOOLS=qemu-img$(EXESUF) + ifdef CONFIG_STATIC + BASE_LDFLAGS += -static diff --git a/qemu-cvs-sched_getaffinity.patch b/qemu-cvs-sched_getaffinity.patch new file mode 100644 index 00000000..f26d76fd --- /dev/null +++ b/qemu-cvs-sched_getaffinity.patch @@ -0,0 +1,38 @@ +Index: qemu.bkp/linux-user/syscall.c +=================================================================== +--- qemu.bkp.orig/linux-user/syscall.c ++++ qemu.bkp/linux-user/syscall.c +@@ -149,6 +149,7 @@ type name (type1 arg1,type2 arg2,type3 a + #define __NR_sys_syslog __NR_syslog + #define __NR_sys_tgkill __NR_tgkill + #define __NR_sys_clone __NR_clone ++#define __NR_sys_sched_getaffinity __NR_sched_getaffinity + + #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__) + #define __NR__llseek __NR_lseek +@@ -171,6 +172,7 @@ _syscall3(int,sys_rt_sigqueueinfo,int,pi + _syscall3(int,sys_syslog,int,type,char*,bufp,int,len) + _syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig) + _syscall5(int,sys_clone, int, flags, void *, child_stack, int *, parent_tidptr, void *, newtls, int *, child_tidptr) ++_syscall3(int,sys_sched_getaffinity,pid_t,pid,unsigned int,cpusetsize,void*,mask) + #ifdef __NR_exit_group + _syscall1(int,exit_group,int,error_code) + #endif +@@ -4823,6 +4825,17 @@ long do_syscall(void *cpu_env, int num, + goto unimplemented_nowarn; + #endif + ++#ifdef TARGET_NR_sched_getaffinity ++ case TARGET_NR_sched_getaffinity: ++ { ++ cpu_set_t *mask; ++ lock_user_struct(mask, arg3, 1); ++ ret = get_errno(sys_sched_getaffinity((pid_t)arg1, (unsigned int)arg2, mask)); ++ unlock_user_struct(mask, arg3, 0); ++ break; ++ } ++#endif ++ + default: + unimplemented: + gemu_log("qemu: Unsupported syscall: %d\n", num); diff --git a/qemu-cvs-tls.patch b/qemu-cvs-tls.patch new file mode 100644 index 00000000..d4e88710 --- /dev/null +++ b/qemu-cvs-tls.patch @@ -0,0 +1,260 @@ +Index: qemu.bkp/linux-user/main.c +=================================================================== +--- qemu.bkp.orig/linux-user/main.c ++++ qemu.bkp/linux-user/main.c +@@ -156,7 +156,7 @@ static void set_gate(void *ptr, unsigned + p[1] = tswapl(e2); + } + +-uint64_t gdt_table[6]; ++uint64_t gdt_table[9]; + uint64_t idt_table[256]; + + /* only dpl matters as we do only user space emulation */ +Index: qemu.bkp/linux-user/syscall.c +=================================================================== +--- qemu.bkp.orig/linux-user/syscall.c ++++ qemu.bkp/linux-user/syscall.c +@@ -145,6 +145,7 @@ type name (type1 arg1,type2 arg2,type3 a + #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo + #define __NR_sys_syslog __NR_syslog + #define __NR_sys_tgkill __NR_tgkill ++#define __NR_sys_clone __NR_clone + + #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__) + #define __NR__llseek __NR_lseek +@@ -166,6 +167,7 @@ _syscall5(int, _llseek, uint, fd, ulon + _syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo) + _syscall3(int,sys_syslog,int,type,char*,bufp,int,len) + _syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig) ++_syscall5(int,sys_clone, int, flags, void *, child_stack, int *, parent_tidptr, void *, newtls, int *, child_tidptr) + #ifdef __NR_exit_group + _syscall1(int,exit_group,int,error_code) + #endif +@@ -2115,29 +2117,107 @@ int do_modify_ldt(CPUX86State *env, int + return ret; + } + ++int do_set_thread_area(CPUX86State *env, target_ulong ptr) ++{ ++ uint64_t *gdt_table = g2h(env->gdt.base); ++ struct target_modify_ldt_ldt_s ldt_info; ++ struct target_modify_ldt_ldt_s *target_ldt_info; ++ int seg_32bit, contents, read_exec_only, limit_in_pages; ++ int seg_not_present, useable; ++ uint32_t *lp, entry_1, entry_2; ++ int i; ++ ++ lock_user_struct(target_ldt_info, ptr, 1); ++ ldt_info.entry_number = tswap32(target_ldt_info->entry_number); ++ ldt_info.base_addr = tswapl(target_ldt_info->base_addr); ++ ldt_info.limit = tswap32(target_ldt_info->limit); ++ ldt_info.flags = tswap32(target_ldt_info->flags); ++ if (ldt_info.entry_number == -1) { ++ for (i=6; i<8; i++) ++ if (gdt_table[i] == 0) { ++ ldt_info.entry_number = i; ++ target_ldt_info->entry_number = tswap32(i); ++ break; ++ } ++ } ++ unlock_user_struct(target_ldt_info, ptr, 0); ++ ++ if (ldt_info.entry_number < 6 || ldt_info.entry_number > 8) ++ return -EINVAL; ++ seg_32bit = ldt_info.flags & 1; ++ contents = (ldt_info.flags >> 1) & 3; ++ read_exec_only = (ldt_info.flags >> 3) & 1; ++ limit_in_pages = (ldt_info.flags >> 4) & 1; ++ seg_not_present = (ldt_info.flags >> 5) & 1; ++ useable = (ldt_info.flags >> 6) & 1; ++ ++ if (contents == 3) { ++ if (seg_not_present == 0) ++ return -EINVAL; ++ } ++ ++ /* NOTE: same code as Linux kernel */ ++ /* Allow LDTs to be cleared by the user. */ ++ if (ldt_info.base_addr == 0 && ldt_info.limit == 0) { ++ if ((contents == 0 && ++ read_exec_only == 1 && ++ seg_32bit == 0 && ++ limit_in_pages == 0 && ++ seg_not_present == 1 && ++ useable == 0 )) { ++ entry_1 = 0; ++ entry_2 = 0; ++ goto install; ++ } ++ } ++ ++ entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) | ++ (ldt_info.limit & 0x0ffff); ++ entry_2 = (ldt_info.base_addr & 0xff000000) | ++ ((ldt_info.base_addr & 0x00ff0000) >> 16) | ++ (ldt_info.limit & 0xf0000) | ++ ((read_exec_only ^ 1) << 9) | ++ (contents << 10) | ++ ((seg_not_present ^ 1) << 15) | ++ (seg_32bit << 22) | ++ (limit_in_pages << 23) | ++ (useable << 20) | ++ 0x7000; ++ ++ /* Install the new entry ... */ ++install: ++ lp = (uint32_t *)(gdt_table + ldt_info.entry_number); ++ lp[0] = tswap32(entry_1); ++ lp[1] = tswap32(entry_2); ++ return 0; ++} + #endif /* defined(TARGET_I386) */ + + /* this stack is the equivalent of the kernel stack associated with a + thread/process */ + #define NEW_STACK_SIZE 8192 + +-static int clone_func(void *arg) ++static int clone_func(void *cloneenv) + { +- CPUState *env = arg; +- cpu_loop(env); ++ cpu_loop((CPUState *)cloneenv); + /* never exits */ + return 0; + } + +-int do_fork(CPUState *env, unsigned int flags, unsigned long newsp) ++int do_fork(CPUState *env, unsigned int flags, target_ulong newsp, target_ulong parent_tidptr, target_ulong newtls, target_ulong child_tidptr) + { + int ret; ++ unsigned long parent_tid=gettid(); + TaskState *ts; + uint8_t *new_stack; + CPUState *new_env; +- ++#if defined(TARGET_I386) ++ uint64_t *new_gdt_table; ++#endif + if (flags & CLONE_VM) { + ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE); ++ if (!ts) ++ return -ENOMEM; + memset(ts, 0, sizeof(TaskState)); + new_stack = ts->stack; + ts->used = 1; +@@ -2149,6 +2229,27 @@ int do_fork(CPUState *env, unsigned int + #if defined(TARGET_I386) + if (!newsp) + newsp = env->regs[R_ESP]; ++ new_gdt_table = malloc(9 * 8); ++ if (!new_gdt_table) { ++ free(new_env); ++ return -ENOMEM; ++ } ++ /* Copy main GDT table from parent, but clear TLS entries */ ++ memcpy(new_gdt_table, g2h(env->gdt.base), 6 * 8); ++ memset(&new_gdt_table[6], 0, 3 * 8); ++ new_env->gdt.base = h2g(new_gdt_table); ++ if (flags & CLONE_SETTLS) { ++ ret = do_set_thread_area(new_env, newtls); ++ if (ret) { ++ free(new_gdt_table); ++ free(new_env); ++ return ret; ++ } ++ } ++ ++ cpu_x86_load_seg(new_env, R_FS, new_env->segs[R_FS].selector); ++ cpu_x86_load_seg(new_env, R_GS, new_env->segs[R_GS].selector); ++ + new_env->regs[R_ESP] = newsp; + new_env->regs[R_EAX] = 0; + #elif defined(TARGET_ARM) +@@ -2202,15 +2303,27 @@ int do_fork(CPUState *env, unsigned int + #endif + new_env->opaque = ts; + #ifdef __ia64__ +- ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env); ++ ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags & ~(CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID), new_env); + #else +- ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env); ++ ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags & ~(CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID), new_env); + #endif + } else { + /* if no CLONE_VM, we consider it is a fork */ +- if ((flags & ~CSIGNAL) != 0) +- return -EINVAL; +- ret = fork(); ++ ret = sys_clone(flags & ~(CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID), 0, g2h(parent_tidptr), NULL, g2h(child_tidptr)); ++ } ++ /* Store child thread ID at location parent_tidptr in parent and child memory. ++ Currently this is only done in client memory */ ++ if(flags & CLONE_PARENT_SETTID) { ++ tput32(parent_tidptr, parent_tid); ++ } ++ ++ /* Store child thread ID at location child_tidptr in child memory. */ ++ if(flags & CLONE_CHILD_SETTID) { ++ if(ret==0) { /* only in client memory for fork() */ ++ tput32(child_tidptr, gettid()); ++ } else if(flags & CLONE_VM) { /* real threads need it too */ ++ tput32(child_tidptr, ret); ++ } + } + return ret; + } +@@ -2458,7 +2571,7 @@ long do_syscall(void *cpu_env, int num, + _mcleanup(); + #endif + gdb_exit(cpu_env, arg1); +- /* XXX: should free thread stack and CPU env */ ++ /* XXX: should free thread stack, GDT and CPU env */ + _exit(arg1); + ret = 0; /* avoid warning */ + break; +@@ -2487,7 +2600,7 @@ long do_syscall(void *cpu_env, int num, + ret = do_brk(arg1); + break; + case TARGET_NR_fork: +- ret = get_errno(do_fork(cpu_env, SIGCHLD, 0)); ++ ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0,0,0)); + break; + #ifdef TARGET_NR_waitpid + case TARGET_NR_waitpid: +@@ -3651,7 +3764,7 @@ long do_syscall(void *cpu_env, int num, + ret = get_errno(fsync(arg1)); + break; + case TARGET_NR_clone: +- ret = get_errno(do_fork(cpu_env, arg1, arg2)); ++ ret = get_errno(do_fork(cpu_env, arg1, arg2,arg3,arg4,arg5)); + break; + #ifdef __NR_exit_group + /* new thread calls */ +@@ -4039,7 +4152,7 @@ long do_syscall(void *cpu_env, int num, + #endif + #ifdef TARGET_NR_vfork + case TARGET_NR_vfork: +- ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD, 0)); ++ ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD, 0, 0,0,0)); + break; + #endif + #ifdef TARGET_NR_ugetrlimit +@@ -4561,12 +4674,12 @@ long do_syscall(void *cpu_env, int num, + #ifdef TARGET_NR_set_thread_area + case TARGET_NR_set_thread_area: + #ifdef TARGET_MIPS +- ((CPUMIPSState *) cpu_env)->tls_value = arg1; +- ret = 0; +- break; ++ ((CPUMIPSState *) cpu_env)->tls_value = arg1; ++ ret = 0; + #else +- goto unimplemented_nowarn; ++ ret = get_errno(do_set_thread_area(cpu_env, arg1)); + #endif ++ break; + #endif + #ifdef TARGET_NR_get_thread_area + case TARGET_NR_get_thread_area: diff --git a/qemu-m68k.diff b/qemu-m68k.diff new file mode 100644 index 00000000..0304d95d --- /dev/null +++ b/qemu-m68k.diff @@ -0,0 +1,2766 @@ +Index: gdbstub.c +=================================================================== +RCS file: /sources/qemu/qemu/gdbstub.c,v +retrieving revision 1.59 +diff -u -a -p -r1.59 gdbstub.c +--- gdbstub.c 7 Jul 2007 20:53:22 -0000 1.59 ++++ gdbstub.c 10 Jul 2007 12:36:35 -0000 +@@ -510,7 +510,9 @@ static int cpu_gdb_read_registers(CPUSta + for (i = 0; i < 8; i++) { + u.d = env->fregs[i]; + *(uint32_t *)ptr = tswap32(u.l.upper); ++ ptr += 4; + *(uint32_t *)ptr = tswap32(u.l.lower); ++ ptr += 8; + } + /* FP control regs (not implemented). */ + memset (ptr, 0, 3 * 4); +@@ -544,7 +546,9 @@ static void cpu_gdb_write_registers(CPUS + ColdFire has 8-bit double precision registers. */ + for (i = 0; i < 8; i++) { + u.l.upper = tswap32(*(uint32_t *)ptr); ++ ptr += 4; + u.l.lower = tswap32(*(uint32_t *)ptr); ++ ptr += 8; + env->fregs[i] = u.d; + } + /* FP control regs (not implemented). */ +Index: target-m68k/cpu.h +=================================================================== +RCS file: /sources/qemu/qemu/target-m68k/cpu.h,v +retrieving revision 1.11 +diff -u -a -p -r1.11 cpu.h +--- target-m68k/cpu.h 3 Jun 2007 21:02:38 -0000 1.11 ++++ target-m68k/cpu.h 10 Jul 2007 12:36:35 -0000 +@@ -86,7 +86,10 @@ typedef struct CPUM68KState { + /* Temporary storage for DIV helpers. */ + uint32_t div1; + uint32_t div2; +- ++ ++ /* Upper 32 bits of a 64bit operand for quad MUL/DIV. */ ++ uint32_t quadh; ++ + /* MMU status. */ + struct { + uint32_t ar; +@@ -133,14 +136,26 @@ enum { + CC_OP_DYNAMIC, /* Use env->cc_op */ + CC_OP_FLAGS, /* CC_DEST = CVZN, CC_SRC = unused */ + CC_OP_LOGIC, /* CC_DEST = result, CC_SRC = unused */ ++ CC_OP_ADDB, /* CC_DEST = result, CC_SRC = source */ ++ CC_OP_ADDW, /* CC_DEST = result, CC_SRC = source */ + CC_OP_ADD, /* CC_DEST = result, CC_SRC = source */ ++ CC_OP_SUBB, /* CC_DEST = result, CC_SRC = source */ ++ CC_OP_SUBW, /* CC_DEST = result, CC_SRC = source */ + CC_OP_SUB, /* CC_DEST = result, CC_SRC = source */ +- CC_OP_CMPB, /* CC_DEST = result, CC_SRC = source */ +- CC_OP_CMPW, /* CC_DEST = result, CC_SRC = source */ ++ CC_OP_ADDXB, /* CC_DEST = result, CC_SRC = source */ ++ CC_OP_ADDXW, /* CC_DEST = result, CC_SRC = source */ + CC_OP_ADDX, /* CC_DEST = result, CC_SRC = source */ ++ CC_OP_SUBXB, /* CC_DEST = result, CC_SRC = source */ ++ CC_OP_SUBXW, /* CC_DEST = result, CC_SRC = source */ + CC_OP_SUBX, /* CC_DEST = result, CC_SRC = source */ ++ CC_OP_SHLB, /* CC_DEST = source, CC_SRC = shift */ ++ CC_OP_SHLW, /* CC_DEST = source, CC_SRC = shift */ + CC_OP_SHL, /* CC_DEST = source, CC_SRC = shift */ ++ CC_OP_SHRB, /* CC_DEST = source, CC_SRC = shift */ ++ CC_OP_SHRW, /* CC_DEST = source, CC_SRC = shift */ + CC_OP_SHR, /* CC_DEST = source, CC_SRC = shift */ ++ CC_OP_SARB, /* CC_DEST = source, CC_SRC = shift */ ++ CC_OP_SARW, /* CC_DEST = source, CC_SRC = shift */ + CC_OP_SAR, /* CC_DEST = source, CC_SRC = shift */ + }; + +@@ -189,6 +204,12 @@ void do_m68k_semihosting(CPUM68KState *e + ISA revisions mentioned. */ + + enum m68k_features { ++ M68K_FEATURE_M68000, ++ M68K_FEATURE_M68020, ++ M68K_FEATURE_M68020_40, /* Features common to 68020 - 68040 */ ++ M68K_FEATURE_M68040, ++ M68K_FEATURE_M68020_60, /* Feature common to 68020 - 68060 */ ++ M68K_FEATURE_M68060, + M68K_FEATURE_CF_ISA_A, + M68K_FEATURE_CF_ISA_B, /* (ISA B or C). */ + M68K_FEATURE_CF_ISA_APLUSC, /* BIT/BITREV, FF1, STRLDSR (ISA A+ or C). */ +@@ -199,7 +220,9 @@ enum m68k_features { + M68K_FEATURE_CF_EMAC_B, /* Revision B EMAC (dual accumulate). */ + M68K_FEATURE_USP, /* User Stack Pointer. (ISA A+, B or C). */ + M68K_FEATURE_EXT_FULL, /* 68020+ full extension word. */ +- M68K_FEATURE_WORD_INDEX /* word sized address index registers. */ ++ M68K_FEATURE_WORD_INDEX, /* word sized address index registers. */ ++ M68K_FEATURE_SCALED_INDEX, /* scaled address index registers. */ ++ M68K_FEATURE_FPU + }; + + static inline int m68k_feature(CPUM68KState *env, int feature) +@@ -210,8 +233,8 @@ static inline int m68k_feature(CPUM68KSt + void register_m68k_insns (CPUM68KState *env); + + #ifdef CONFIG_USER_ONLY +-/* Linux uses 8k pages. */ +-#define TARGET_PAGE_BITS 13 ++/* Linux uses 4k pages. */ ++#define TARGET_PAGE_BITS 12 + #else + /* Smallest TLB entry size is 1k. */ + #define TARGET_PAGE_BITS 10 +Index: target-m68k/exec.h +=================================================================== +RCS file: /sources/qemu/qemu/target-m68k/exec.h,v +retrieving revision 1.3 +diff -u -a -p -r1.3 exec.h +--- target-m68k/exec.h 3 Jun 2007 17:44:36 -0000 1.3 ++++ target-m68k/exec.h 10 Jul 2007 12:36:35 -0000 +@@ -48,6 +48,10 @@ void cpu_m68k_flush_flags(CPUM68KState * + float64 helper_sub_cmpf64(CPUM68KState *env, float64 src0, float64 src1); + void helper_movec(CPUM68KState *env, int reg, uint32_t val); + ++extern const uint8_t rox8_table[64]; ++extern const uint8_t rox16_table[64]; ++extern const uint8_t rox32_table[64]; ++ + void cpu_loop_exit(void); + + static inline int cpu_halted(CPUState *env) { +Index: target-m68k/helper.c +=================================================================== +RCS file: /sources/qemu/qemu/target-m68k/helper.c,v +retrieving revision 1.6 +diff -u -a -p -r1.6 helper.c +--- target-m68k/helper.c 3 Jun 2007 12:35:08 -0000 1.6 ++++ target-m68k/helper.c 10 Jul 2007 12:36:35 -0000 +@@ -27,6 +27,10 @@ + #include "exec-all.h" + + enum m68k_cpuid { ++ M68K_CPUID_M68000, ++ M68K_CPUID_M68020, ++ M68K_CPUID_M68040, ++ M68K_CPUID_M68060, + M68K_CPUID_M5206, + M68K_CPUID_M5208, + M68K_CPUID_CFV4E, +@@ -39,6 +43,10 @@ struct m68k_def_t { + }; + + static m68k_def_t m68k_cpu_defs[] = { ++ {"m68000", M68K_CPUID_M68000}, ++ {"m68020", M68K_CPUID_M68020}, ++ {"m68040", M68K_CPUID_M68040}, ++ {"m68060", M68K_CPUID_M68060}, + {"m5206", M68K_CPUID_M5206}, + {"m5208", M68K_CPUID_M5208}, + {"cfv4e", M68K_CPUID_CFV4E}, +@@ -63,12 +71,41 @@ int cpu_m68k_set_model(CPUM68KState *env + return 1; + + switch (def->id) { ++ case M68K_CPUID_M68000: ++ m68k_set_feature(env, M68K_FEATURE_M68000); ++ m68k_set_feature(env, M68K_FEATURE_USP); ++ m68k_set_feature(env, M68K_FEATURE_WORD_INDEX); ++ break; ++ case M68K_CPUID_M68020: ++ case M68K_CPUID_M68040: ++ m68k_set_feature(env, M68K_FEATURE_M68000); ++ m68k_set_feature(env, M68K_FEATURE_M68020_40); ++ m68k_set_feature(env, M68K_FEATURE_M68020_60); ++ m68k_set_feature(env, M68K_FEATURE_USP); ++ m68k_set_feature(env, M68K_FEATURE_BRAL); ++ m68k_set_feature(env, M68K_FEATURE_EXT_FULL); ++ m68k_set_feature(env, M68K_FEATURE_WORD_INDEX); ++ m68k_set_feature(env, M68K_FEATURE_SCALED_INDEX); ++ m68k_set_feature(env, M68K_FEATURE_FPU); ++ break; ++ case M68K_CPUID_M68060: ++ m68k_set_feature(env, M68K_FEATURE_M68000); ++ m68k_set_feature(env, M68K_FEATURE_M68020_60); ++ m68k_set_feature(env, M68K_FEATURE_USP); ++ m68k_set_feature(env, M68K_FEATURE_BRAL); ++ m68k_set_feature(env, M68K_FEATURE_EXT_FULL); ++ m68k_set_feature(env, M68K_FEATURE_WORD_INDEX); ++ m68k_set_feature(env, M68K_FEATURE_SCALED_INDEX); ++ m68k_set_feature(env, M68K_FEATURE_FPU); ++ break; + case M68K_CPUID_M5206: + m68k_set_feature(env, M68K_FEATURE_CF_ISA_A); ++ m68k_set_feature(env, M68K_FEATURE_SCALED_INDEX); + break; + case M68K_CPUID_M5208: + m68k_set_feature(env, M68K_FEATURE_CF_ISA_A); + m68k_set_feature(env, M68K_FEATURE_CF_ISA_APLUSC); ++ m68k_set_feature(env, M68K_FEATURE_SCALED_INDEX); + m68k_set_feature(env, M68K_FEATURE_BRAL); + m68k_set_feature(env, M68K_FEATURE_CF_EMAC); + m68k_set_feature(env, M68K_FEATURE_USP); +@@ -76,12 +113,19 @@ int cpu_m68k_set_model(CPUM68KState *env + case M68K_CPUID_CFV4E: + m68k_set_feature(env, M68K_FEATURE_CF_ISA_A); + m68k_set_feature(env, M68K_FEATURE_CF_ISA_B); ++ m68k_set_feature(env, M68K_FEATURE_SCALED_INDEX); + m68k_set_feature(env, M68K_FEATURE_BRAL); + m68k_set_feature(env, M68K_FEATURE_CF_FPU); + m68k_set_feature(env, M68K_FEATURE_CF_EMAC); + m68k_set_feature(env, M68K_FEATURE_USP); + break; + case M68K_CPUID_ANY: ++ m68k_set_feature(env, M68K_FEATURE_M68000); ++ m68k_set_feature(env, M68K_FEATURE_M68020); ++ m68k_set_feature(env, M68K_FEATURE_M68020_40); ++ m68k_set_feature(env, M68K_FEATURE_M68040); ++ m68k_set_feature(env, M68K_FEATURE_M68020_60); ++ m68k_set_feature(env, M68K_FEATURE_M68060); + m68k_set_feature(env, M68K_FEATURE_CF_ISA_A); + m68k_set_feature(env, M68K_FEATURE_CF_ISA_B); + m68k_set_feature(env, M68K_FEATURE_CF_ISA_APLUSC); +@@ -93,6 +137,7 @@ int cpu_m68k_set_model(CPUM68KState *env + m68k_set_feature(env, M68K_FEATURE_CF_EMAC_B); + m68k_set_feature(env, M68K_FEATURE_USP); + m68k_set_feature(env, M68K_FEATURE_EXT_FULL); ++ m68k_set_feature(env, M68K_FEATURE_SCALED_INDEX); + m68k_set_feature(env, M68K_FEATURE_WORD_INDEX); + break; + } +@@ -102,6 +147,42 @@ int cpu_m68k_set_model(CPUM68KState *env + return 0; + } + ++/* modulo 33 table */ ++const uint8_t rox32_table[64] = { ++ 0, 1, 2, 3, 4, 5, 6, 7, ++ 8, 9,10,11,12,13,14,15, ++ 16,17,18,19,20,21,22,23, ++ 24,25,26,27,28,29,30,31, ++ 32, 0, 1, 2, 3, 4, 5, 6, ++ 7, 8, 9,10,11,12,13,14, ++ 15,16,17,18,19,20,21,22, ++ 23,24,25,26,27,28,29,30, ++}; ++ ++/* modulo 17 table */ ++const uint8_t rox16_table[64] = { ++ 0, 1, 2, 3, 4, 5, 6, 7, ++ 8, 9,10,11,12,13,14,15, ++ 16, 0, 1, 2, 3, 4, 5, 6, ++ 7, 8, 9,10,11,12,13,14, ++ 15,16, 0, 1, 2, 3, 4, 5, ++ 6, 7, 8, 9,10,11,12,13, ++ 14,15,16, 0, 1, 2, 3, 4, ++ 5, 6, 7, 8, 9,10,11,12, ++}; ++ ++/* modulo 9 table */ ++const uint8_t rox8_table[64] = { ++ 0, 1, 2, 3, 4, 5, 6, 7, ++ 8, 0, 1, 2, 3, 4, 5, 6, ++ 7, 8, 0, 1, 2, 3, 4, 5, ++ 6, 7, 8, 0, 1, 2, 3, 4, ++ 5, 6, 7, 8, 0, 1, 2, 3, ++ 4, 5, 6, 7, 8, 0, 1, 2, ++ 3, 4, 5, 6, 7, 8, 0, 1, ++ 2, 3, 4, 5, 6, 7, 8, 0, ++}; ++ + void cpu_m68k_flush_flags(CPUM68KState *env, int cc_op) + { + int flags; +@@ -127,6 +208,66 @@ void cpu_m68k_flush_flags(CPUM68KState * + flags |= CCF_V; \ + } while (0) + ++#define SET_FLAGS_ADD(type, utype) do { \ ++ SET_NZ((type)dest); \ ++ if ((utype) dest < (utype) src) \ ++ flags |= CCF_C; \ ++ tmp = dest - src; \ ++ if ((1u << (sizeof(type) * 8 - 1)) & (src ^ dest) & (tmp ^ src)) \ ++ flags |= CCF_V; \ ++ } while (0) ++ ++#define SET_FLAGS_ADDX(type, utype) do { \ ++ SET_NZ((type)dest); \ ++ if ((utype) dest <= (utype) src) \ ++ flags |= CCF_C; \ ++ tmp = dest - src - 1; \ ++ if ((1u << (sizeof(type) * 8 - 1)) & (src ^ dest) & (tmp ^ src)) \ ++ flags |= CCF_V; \ ++ } while (0) ++ ++#define SET_FLAGS_SUBX(type, utype) do { \ ++ SET_NZ((type)dest); \ ++ tmp = dest + src + 1; \ ++ if ((utype) dest <= (utype) src) \ ++ flags |= CCF_C; \ ++ if ((1u << (sizeof(type) * 8 - 1)) & (tmp ^ dest) & (tmp ^ src)) \ ++ flags |= CCF_V; \ ++ } while (0) ++ ++#define SET_FLAGS_SHL(type) do { \ ++ if (src >= sizeof(type) * 8) { \ ++ SET_NZ(0); \ ++ } else { \ ++ tmp = dest << src; \ ++ SET_NZ((type)tmp); \ ++ } \ ++ if (src && src <= sizeof(type) * 8 && (dest & (1 << (sizeof(type) * 8 - src)))) \ ++ flags |= CCF_C; \ ++ } while (0) ++ ++#define SET_FLAGS_SHR(type) do { \ ++ if (src >= sizeof(type) * 8) { \ ++ SET_NZ(0); \ ++ } else { \ ++ tmp = dest >> src; \ ++ SET_NZ((type)tmp); \ ++ } \ ++ if (src && src <= sizeof(type) * 8 && ((dest >> (src - 1)) & 1)) \ ++ flags |= CCF_C; \ ++ } while (0) ++ ++#define SET_FLAGS_SAR(type) do { \ ++ if (src >= sizeof(type) * 8) { \ ++ SET_NZ(-((type)dest < 0)); \ ++ } else { \ ++ tmp = dest >> src; \ ++ SET_NZ((type)tmp); \ ++ } \ ++ if (src && src <= sizeof(type) * 8 && (((type)dest >> (src - 1)) & 1)) \ ++ flags |= CCF_C; \ ++ } while (0) ++ + flags = 0; + src = env->cc_src; + dest = env->cc_dest; +@@ -137,68 +278,68 @@ void cpu_m68k_flush_flags(CPUM68KState * + case CC_OP_LOGIC: + SET_NZ(dest); + break; ++ case CC_OP_ADDB: ++ SET_FLAGS_ADD(int8_t, uint8_t); ++ break; ++ case CC_OP_ADDW: ++ SET_FLAGS_ADD(int16_t, uint16_t); ++ break; + case CC_OP_ADD: +- SET_NZ(dest); +- if (dest < src) +- flags |= CCF_C; +- tmp = dest - src; +- if (HIGHBIT & (src ^ dest) & ~(tmp ^ src)) +- flags |= CCF_V; ++ SET_FLAGS_ADD(int32_t, uint32_t); ++ break; ++ case CC_OP_SUBB: ++ SET_FLAGS_SUB(int8_t, uint8_t); ++ break; ++ case CC_OP_SUBW: ++ SET_FLAGS_SUB(int16_t, uint16_t); + break; + case CC_OP_SUB: + SET_FLAGS_SUB(int32_t, uint32_t); + break; +- case CC_OP_CMPB: +- SET_FLAGS_SUB(int8_t, uint8_t); ++ case CC_OP_ADDXB: ++ SET_FLAGS_ADDX(int8_t, uint8_t); + break; +- case CC_OP_CMPW: +- SET_FLAGS_SUB(int16_t, uint16_t); ++ case CC_OP_ADDXW: ++ SET_FLAGS_ADDX(int16_t, uint16_t); + break; + case CC_OP_ADDX: +- SET_NZ(dest); +- if (dest <= src) +- flags |= CCF_C; +- tmp = dest - src - 1; +- if (HIGHBIT & (src ^ dest) & ~(tmp ^ src)) +- flags |= CCF_V; ++ SET_FLAGS_ADDX(int32_t, uint32_t); ++ break; ++ case CC_OP_SUBXB: ++ SET_FLAGS_SUBX(int8_t, uint8_t); ++ break; ++ case CC_OP_SUBXW: ++ SET_FLAGS_SUBX(int16_t, uint16_t); + break; + case CC_OP_SUBX: +- SET_NZ(dest); +- tmp = dest + src + 1; +- if (tmp <= src) +- flags |= CCF_C; +- if (HIGHBIT & (tmp ^ dest) & (tmp ^ src)) +- flags |= CCF_V; ++ SET_FLAGS_SUBX(int32_t, uint32_t); ++ break; ++ case CC_OP_SHLB: ++ SET_FLAGS_SHL(int8_t); ++ break; ++ case CC_OP_SHLW: ++ SET_FLAGS_SHL(int16_t); + break; + case CC_OP_SHL: +- if (src >= 32) { +- SET_NZ(0); +- } else { +- tmp = dest << src; +- SET_NZ(tmp); +- } +- if (src && src <= 32 && (dest & (1 << (32 - src)))) +- flags |= CCF_C; ++ SET_FLAGS_SHL(int32_t); ++ break; ++ case CC_OP_SHRB: ++ SET_FLAGS_SHR(int8_t); ++ break; ++ case CC_OP_SHRW: ++ SET_FLAGS_SHR(int16_t); + break; + case CC_OP_SHR: +- if (src >= 32) { +- SET_NZ(0); +- } else { +- tmp = dest >> src; +- SET_NZ(tmp); +- } +- if (src && src <= 32 && ((dest >> (src - 1)) & 1)) +- flags |= CCF_C; ++ SET_FLAGS_SHR(int32_t); ++ break; ++ case CC_OP_SARB: ++ SET_FLAGS_SAR(int8_t); ++ break; ++ case CC_OP_SARW: ++ SET_FLAGS_SAR(int16_t); + break; + case CC_OP_SAR: +- if (src >= 32) { +- SET_NZ(-1); +- } else { +- tmp = (int32_t)dest >> src; +- SET_NZ(tmp); +- } +- if (src && src <= 32 && (((int32_t)dest >> (src - 1)) & 1)) +- flags |= CCF_C; ++ SET_FLAGS_SAR(int32_t); + break; + default: + cpu_abort(env, "Bad CC_OP %d", cc_op); +Index: target-m68k/op-hacks.h +=================================================================== +RCS file: /sources/qemu/qemu/target-m68k/op-hacks.h,v +retrieving revision 1.3 +diff -u -a -p -r1.3 op-hacks.h +--- target-m68k/op-hacks.h 9 Jun 2007 20:50:00 -0000 1.3 ++++ target-m68k/op-hacks.h 10 Jul 2007 12:36:35 -0000 +@@ -89,6 +89,36 @@ static inline void gen_op_sar_im_cc(int + gen_op_sar_cc(val, gen_im32(shift)); + } + ++static inline void gen_op_shl8_im_cc(int dest, int src, int shift) ++{ ++ gen_op_shl8_cc(dest, src, gen_im32(shift)); ++} ++ ++static inline void gen_op_shr8_im_cc(int dest, int src, int shift) ++{ ++ gen_op_shr8_cc(dest, src, gen_im32(shift)); ++} ++ ++static inline void gen_op_sar8_im_cc(int dest, int src, int shift) ++{ ++ gen_op_sar8_cc(dest, src, gen_im32(shift)); ++} ++ ++static inline void gen_op_shl16_im_cc(int dest, int src, int shift) ++{ ++ gen_op_shl16_cc(dest, src, gen_im32(shift)); ++} ++ ++static inline void gen_op_shr16_im_cc(int dest, int src, int shift) ++{ ++ gen_op_shr16_cc(dest, src, gen_im32(shift)); ++} ++ ++static inline void gen_op_sar16_im_cc(int dest, int src, int shift) ++{ ++ gen_op_sar16_cc(dest, src, gen_im32(shift)); ++} ++ + #ifdef USE_DIRECT_JUMP + #define TBPARAM(x) + #else +Index: target-m68k/op.c +=================================================================== +RCS file: /sources/qemu/qemu/target-m68k/op.c,v +retrieving revision 1.11 +diff -u -a -p -r1.11 op.c +--- target-m68k/op.c 9 Jun 2007 20:50:01 -0000 1.11 ++++ target-m68k/op.c 10 Jul 2007 12:36:35 -0000 +@@ -136,6 +136,76 @@ OP(mul32) + FORCE_RET(); + } + ++OP(mulu32_cc) ++{ ++ uint32_t op2 = get_op(PARAM2); ++ uint32_t op3 = get_op(PARAM3); ++ uint64_t result = (uint32_t)op2 * op3; ++ uint32_t flags; ++ set_op(PARAM1, result); ++ flags = 0; ++ if (result >> 32) ++ flags |= CCF_V; ++ if ((uint32_t)result == 0) ++ flags |= CCF_Z; ++ if ((int32_t)result < 0) ++ flags |= CCF_N; ++ env->cc_dest = flags; ++ FORCE_RET(); ++} ++ ++OP(muls32_cc) ++{ ++ int32_t op2 = get_op(PARAM2); ++ int32_t op3 = get_op(PARAM3); ++ int64_t result = (int32_t)op2 * op3; ++ uint32_t flags; ++ set_op(PARAM1, result); ++ flags = 0; ++ if (result != (int64_t)(int32_t)result) ++ flags |= CCF_V; ++ if ((uint32_t)result == 0) ++ flags |= CCF_Z; ++ if ((int32_t)result < 0) ++ flags |= CCF_N; ++ env->cc_dest = flags; ++ FORCE_RET(); ++} ++ ++OP(mulu64) ++{ ++ uint32_t op2 = get_op(PARAM2); ++ uint32_t op3 = get_op(PARAM3); ++ uint64_t result = (uint64_t)op2 * op3; ++ uint32_t flags; ++ set_op(PARAM1, result); ++ env->quadh = result >> 32; ++ flags = 0; ++ if (result == 0) ++ flags |= CCF_Z; ++ if ((int64_t)result < 0) ++ flags |= CCF_N; ++ env->cc_dest = flags; ++ FORCE_RET(); ++} ++ ++OP(muls64) ++{ ++ int32_t op2 = get_op(PARAM2); ++ int32_t op3 = get_op(PARAM3); ++ int64_t result = (uint64_t)op2 * op3; ++ uint32_t flags; ++ set_op(PARAM1, result); ++ env->quadh = result >> 32; ++ flags = 0; ++ if (result == 0) ++ flags |= CCF_Z; ++ if (result < 0) ++ flags |= CCF_N; ++ env->cc_dest = flags; ++ FORCE_RET(); ++} ++ + OP(not32) + { + uint32_t arg = get_op(PARAM2); +@@ -180,6 +250,22 @@ OP(ff1) + FORCE_RET(); + } + ++OP(bfffo) ++{ ++ uint32_t arg = get_op(PARAM2); ++ int width = get_op(PARAM3); ++ int n; ++ uint32_t mask; ++ mask = 0x80000000; ++ for (n = 0; n < width; n++) { ++ if (arg & mask) ++ break; ++ mask >>= 1; ++ } ++ set_op(PARAM1, n); ++ FORCE_RET(); ++} ++ + OP(subx_cc) + { + uint32_t op1 = get_op(PARAM1); +@@ -253,14 +339,60 @@ OP(shl32) + FORCE_RET(); + } + ++OP(shl8_cc) ++{ ++ uint8_t op2 = get_op(PARAM2); ++ uint8_t op3 = get_op(PARAM3); ++ uint8_t result; ++ if (op3 < 8) ++ result = op2 << op3; ++ else ++ result = 0; ++ set_op(PARAM1, result); ++ if (op3 > 0) { ++ if (op3 <= 8) ++ env->cc_x = (op2 << (op3 - 1)) & 0x80; ++ else ++ env->cc_x = 0; ++ } ++ FORCE_RET(); ++} ++ ++OP(shl16_cc) ++{ ++ uint16_t op2 = get_op(PARAM2); ++ uint16_t op3 = get_op(PARAM3); ++ uint16_t result; ++ if (op3 < 16) ++ result = op2 << op3; ++ else ++ result = 0; ++ set_op(PARAM1, result); ++ if (op3 > 0) { ++ if (op3 <= 16) ++ env->cc_x = (op2 << (op3 - 1)) & 0x8000; ++ else ++ env->cc_x = 0; ++ } ++ FORCE_RET(); ++} ++ + OP(shl_cc) + { + uint32_t op1 = get_op(PARAM1); + uint32_t op2 = get_op(PARAM2); + uint32_t result; +- result = op1 << op2; ++ if (op2 < 32) ++ result = op1 << op2; ++ else ++ result = 0; + set_op(PARAM1, result); +- env->cc_x = (op1 << (op2 - 1)) & 1; ++ if (op2 > 0) { ++ if (op2 <= 32) ++ env->cc_x = (op1 << (op2 - 1)) & 0x80000000; ++ else ++ env->cc_x = 0; ++ } + FORCE_RET(); + } + +@@ -279,9 +411,55 @@ OP(shr_cc) + uint32_t op1 = get_op(PARAM1); + uint32_t op2 = get_op(PARAM2); + uint32_t result; +- result = op1 >> op2; ++ if (op2 < 32) ++ result = op1 >> op2; ++ else ++ result = 0; + set_op(PARAM1, result); +- env->cc_x = (op1 >> (op2 - 1)) & 1; ++ if (op2 > 0) { ++ if (op2 <= 32) ++ env->cc_x = (op1 >> (op2 - 1)) & 1; ++ else ++ env->cc_x = 0; ++ } ++ FORCE_RET(); ++} ++ ++OP(shr8_cc) ++{ ++ uint8_t op2 = get_op(PARAM2); ++ uint8_t op3 = get_op(PARAM3); ++ uint8_t result; ++ if (op3 < 8) ++ result = op2 >> op3; ++ else ++ result = 0; ++ set_op(PARAM1, result); ++ if (op3 > 0) { ++ if (op3 <= 8) ++ env->cc_x = (op2 >> (op3 - 1)) & 1; ++ else ++ env->cc_x = 0; ++ } ++ FORCE_RET(); ++} ++ ++OP(shr16_cc) ++{ ++ uint16_t op2 = get_op(PARAM2); ++ uint16_t op3 = get_op(PARAM3); ++ uint16_t result; ++ if (op3 < 16) ++ result = op2 >> op3; ++ else ++ result = 0; ++ set_op(PARAM1, result); ++ if (op3 > 0) { ++ if (op3 <= 16) ++ env->cc_x = (op2 >> (op3 - 1)) & 1; ++ else ++ env->cc_x = 0; ++ } + FORCE_RET(); + } + +@@ -300,12 +478,199 @@ OP(sar_cc) + int32_t op1 = get_op(PARAM1); + uint32_t op2 = get_op(PARAM2); + uint32_t result; +- result = op1 >> op2; ++ if (op2 < 32) ++ result = op1 >> op2; ++ else ++ result = 0; ++ set_op(PARAM1, result); ++ if (op2 > 0) { ++ if (op2 <= 32) ++ env->cc_x = (op1 >> (op2 - 1)) & 1; ++ else ++ env->cc_x = 0; ++ } ++ FORCE_RET(); ++} ++ ++OP(sar8_cc) ++{ ++ int8_t op2 = get_op(PARAM2); ++ uint8_t op3 = get_op(PARAM3); ++ uint8_t result; ++ if (op3 < 8) ++ result = op2 >> op3; ++ else ++ result = 0; ++ set_op(PARAM1, result); ++ if (op3 > 0) { ++ if (op3 <= 8) ++ env->cc_x = (op2 >> (op3 - 1)) & 1; ++ else ++ env->cc_x = 0; ++ } ++ FORCE_RET(); ++} ++ ++OP(sar16_cc) ++{ ++ int16_t op2 = get_op(PARAM2); ++ uint16_t op3 = get_op(PARAM3); ++ uint16_t result; ++ if (op3 < 16) ++ result = op2 >> op3; ++ else ++ result = 0; + set_op(PARAM1, result); +- env->cc_x = (op1 >> (op2 - 1)) & 1; ++ if (op3 > 0) { ++ if (op3 <= 16) ++ env->cc_x = (op2 >> (op3 - 1)) & 1; ++ else ++ env->cc_x = 0; ++ } + FORCE_RET(); + } + ++OP(rol32) ++{ ++ uint32_t op2 = get_op(PARAM2); ++ uint32_t op3 = get_op(PARAM3); ++ uint32_t result; ++ result = (op2 << op3) | (op2 >> (32 - op3)); ++ set_op(PARAM1, result); ++ FORCE_RET(); ++} ++ ++OP(ror32) ++{ ++ uint32_t op2 = get_op(PARAM2); ++ uint32_t op3 = get_op(PARAM3); ++ uint32_t result; ++ result = (op2 >> op3) | (op2 << (32 - op3)); ++ set_op(PARAM1, result); ++ FORCE_RET(); ++} ++ ++#define OP_ROL(type, bits) \ ++OP(glue(glue(rol,bits),_cc)) \ ++{ \ ++ type op2 = get_op(PARAM2); \ ++ uint32_t op3 = get_op(PARAM3); \ ++ type result; \ ++ uint32_t flags; \ ++ int count = op3 & (bits - 1); \ ++ if (count) \ ++ result = (op2 << count) | (op2 >> (bits - count)); \ ++ else \ ++ result = op2; \ ++ set_op(PARAM1, result); \ ++ flags = 0; \ ++ if (result == 0) \ ++ flags |= CCF_Z; \ ++ if (result & (1 << (bits - 1))) \ ++ flags |= CCF_N; \ ++ if (op3 && result & 1) \ ++ flags |= CCF_C; \ ++ env->cc_dest = flags; \ ++ FORCE_RET(); \ ++} ++OP_ROL(uint8_t, 8) ++OP_ROL(uint16_t, 16) ++OP_ROL(uint32_t, 32) ++ ++#define OP_ROR(type, bits) \ ++OP(glue(glue(ror,bits),_cc)) \ ++{ \ ++ type op2 = get_op(PARAM2); \ ++ uint32_t op3 = get_op(PARAM3); \ ++ type result; \ ++ uint32_t flags; \ ++ int count = op3 & (bits - 1); \ ++ if (count) \ ++ result = (op2 >> count) | (op2 << (bits - count)); \ ++ else \ ++ result = op2; \ ++ set_op(PARAM1, result); \ ++ flags = 0; \ ++ if (result == 0) \ ++ flags |= CCF_Z; \ ++ if (result & (1 << (bits - 1))) \ ++ flags |= CCF_N; \ ++ if (op3 && result & (1 << (bits - 1))) \ ++ flags |= CCF_C; \ ++ env->cc_dest = flags; \ ++ FORCE_RET(); \ ++} ++OP_ROR(uint8_t, 8) ++OP_ROR(uint16_t, 16) ++OP_ROR(uint32_t, 32) ++ ++#define OP_ROXR(type, bits) \ ++OP(glue(glue(roxr,bits),_cc)) \ ++{ \ ++ type op2 = get_op(PARAM2); \ ++ uint32_t op3 = get_op(PARAM3); \ ++ type result; \ ++ uint32_t flags; \ ++ int count = op3; \ ++ if (bits == 8) count = rox8_table[count]; \ ++ if (bits == 16) count = rox16_table[count]; \ ++ if (bits == 32) count = rox32_table[count]; \ ++ if (count) { \ ++ result = (op2 >> count) | ((type)env->cc_x << (bits - count)); \ ++ if (count > 1) \ ++ result |= op2 << (bits + 1 - count); \ ++ env->cc_x = (op2 >> (count - 1)) & 1; \ ++ } else \ ++ result = op2; \ ++ set_op(PARAM1, result); \ ++ flags = 0; \ ++ if (result == 0) \ ++ flags |= CCF_Z; \ ++ if (result & (1 << (bits - 1))) \ ++ flags |= CCF_N; \ ++ if (env->cc_x) \ ++ flags |= CCF_C; \ ++ env->cc_dest = flags; \ ++ FORCE_RET(); \ ++} ++OP_ROXR(uint8_t, 8) ++OP_ROXR(uint16_t, 16) ++OP_ROXR(uint32_t, 32) ++ ++#define OP_ROXL(type, bits) \ ++OP(glue(glue(roxl,bits),_cc)) \ ++{ \ ++ type op2 = get_op(PARAM2); \ ++ uint32_t op3 = get_op(PARAM3); \ ++ type result; \ ++ uint32_t flags; \ ++ int count; \ ++ count = op3; \ ++ if (bits == 8) count = rox8_table[count]; \ ++ if (bits == 16) count = rox16_table[count]; \ ++ if (bits == 32) count = rox32_table[count]; \ ++ if (count) { \ ++ result = (op2 << count) | ((type)env->cc_x << (count - 1)); \ ++ if (count > 1) \ ++ result |= op2 >> (bits + 1 - count); \ ++ env->cc_x = (op2 >> (bits - count)) & 1; \ ++ } else \ ++ result = op2; \ ++ set_op(PARAM1, result); \ ++ flags = 0; \ ++ if (result == 0) \ ++ flags |= CCF_Z; \ ++ if (result & (1 << (bits - 1))) \ ++ flags |= CCF_N; \ ++ if (env->cc_x) \ ++ flags |= CCF_C; \ ++ env->cc_dest = flags; \ ++ FORCE_RET(); \ ++} ++OP_ROXL(uint8_t, 8) ++OP_ROXL(uint16_t, 16) ++OP_ROXL(uint32_t, 32) ++ + /* Value extend. */ + + OP(ext8u32) +@@ -361,14 +726,17 @@ OP(divu) + /* Avoid using a PARAM1 of zero. This breaks dyngen because it uses + the address of a symbol, and gcc knows symbols can't have address + zero. */ +- if (PARAM1 == 2 && quot > 0xffff) ++ if (PARAM1 == 1 && quot > 0xffff) + flags |= CCF_V; + if (quot == 0) + flags |= CCF_Z; + else if ((int32_t)quot < 0) + flags |= CCF_N; +- env->div1 = quot; +- env->div2 = rem; ++ /* Don't modify destination if overflow occured. */ ++ if ((flags & CCF_V) == 0) { ++ env->div1 = quot; ++ env->div2 = rem; ++ } + env->cc_dest = flags; + FORCE_RET(); + } +@@ -379,7 +747,7 @@ OP(divs) + int32_t den; + int32_t quot; + int32_t rem; +- int32_t flags; ++ uint32_t flags; + + num = env->div1; + den = env->div2; +@@ -388,14 +756,78 @@ OP(divs) + quot = num / den; + rem = num % den; + flags = 0; +- if (PARAM1 == 2 && quot != (int16_t)quot) ++ if (PARAM1 == 1 && quot != (int16_t)quot) ++ flags |= CCF_V; ++ if (quot == 0) ++ flags |= CCF_Z; ++ else if (quot < 0) ++ flags |= CCF_N; ++ /* Don't modify destination if overflow occured. */ ++ if ((flags & CCF_V) == 0) { ++ env->div1 = quot; ++ env->div2 = rem; ++ } ++ env->cc_dest = flags; ++ FORCE_RET(); ++} ++ ++OP(divu64) ++{ ++ uint32_t num; ++ uint32_t den; ++ uint64_t quot; ++ uint32_t rem; ++ uint32_t flags; ++ ++ num = env->div1; ++ den = env->div2; ++ /* ??? This needs to make sure the throwing location is accurate. */ ++ if (den == 0) ++ RAISE_EXCEPTION(EXCP_DIV0); ++ quot = (num | ((uint64_t)env->quadh << 32)) / den; ++ rem = (num | ((uint64_t)env->quadh << 32)) % den; ++ flags = 0; ++ if (quot > 0xffffffff) ++ flags |= CCF_V; ++ if (quot == 0) ++ flags |= CCF_Z; ++ else if ((int64_t)quot < 0) ++ flags |= CCF_N; ++ /* Don't modify destination if overflow occured. */ ++ if ((flags & CCF_V) == 0) { ++ env->div1 = quot; ++ env->div2 = rem; ++ } ++ env->cc_dest = flags; ++ FORCE_RET(); ++} ++ ++OP(divs64) ++{ ++ int32_t num; ++ int32_t den; ++ int64_t quot; ++ int32_t rem; ++ uint32_t flags; ++ ++ num = env->div1; ++ den = env->div2; ++ if (den == 0) ++ RAISE_EXCEPTION(EXCP_DIV0); ++ quot = (num | ((int64_t)env->quadh << 32)) / den; ++ rem = (num | ((int64_t)env->quadh << 32)) % den; ++ flags = 0; ++ if (quot != (int32_t)quot) + flags |= CCF_V; + if (quot == 0) + flags |= CCF_Z; + else if (quot < 0) + flags |= CCF_N; +- env->div1 = quot; +- env->div2 = rem; ++ /* Don't modify destination if overflow occured. */ ++ if ((flags & CCF_V) == 0) { ++ env->div1 = quot; ++ env->div2 = rem; ++ } + env->cc_dest = flags; + FORCE_RET(); + } +Index: target-m68k/qregs.def +=================================================================== +RCS file: /sources/qemu/qemu/target-m68k/qregs.def,v +retrieving revision 1.3 +diff -u -a -p -r1.3 qregs.def +--- target-m68k/qregs.def 29 May 2007 14:57:59 -0000 1.3 ++++ target-m68k/qregs.def 10 Jul 2007 12:36:35 -0000 +@@ -32,6 +32,7 @@ DEFO32(CC_SRC, cc_src) + DEFO32(CC_X, cc_x) + DEFO32(DIV1, div1) + DEFO32(DIV2, div2) ++DEFO32(QUADH, quadh) + DEFO32(EXCEPTION, exception_index) + DEFO32(MACSR, macsr) + DEFO32(MAC_MASK, mac_mask) +Index: target-m68k/translate.c +=================================================================== +RCS file: /sources/qemu/qemu/target-m68k/translate.c,v +retrieving revision 1.17 +diff -u -a -p -r1.17 translate.c +--- target-m68k/translate.c 9 Jun 2007 21:30:14 -0000 1.17 ++++ target-m68k/translate.c 10 Jul 2007 12:36:35 -0000 +@@ -250,6 +250,9 @@ static int gen_lea_indexed(DisasContext + if ((ext & 0x800) == 0 && !m68k_feature(s->env, M68K_FEATURE_WORD_INDEX)) + return -1; + ++ if (!m68k_feature(s->env, M68K_FEATURE_SCALED_INDEX)) ++ ext &= ~(3 << 9); ++ + if (ext & 0x100) { + /* full extension word format */ + if (!m68k_feature(s->env, M68K_FEATURE_EXT_FULL)) +@@ -258,7 +261,7 @@ static int gen_lea_indexed(DisasContext + if ((ext & 0x30) > 0x10) { + /* base displacement */ + if ((ext & 0x30) == 0x20) { +- bd = (int16_t)lduw_code(s->pc); ++ bd = ldsw_code(s->pc); + s->pc += 2; + } else { + bd = read_im32(s); +@@ -307,7 +310,7 @@ static int gen_lea_indexed(DisasContext + if ((ext & 3) > 1) { + /* outer displacement */ + if ((ext & 3) == 2) { +- od = (int16_t)lduw_code(s->pc); ++ od = ldsw_code(s->pc); + s->pc += 2; + } else { + od = read_im32(s); +@@ -366,6 +369,25 @@ static inline int opsize_bytes(int opsiz + } + } + ++static inline int insn_opsize(int insn, int pos) ++{ ++ switch ((insn >> pos) & 3) { ++ case 0: return OS_BYTE; ++ case 1: return OS_WORD; ++ case 2: return OS_LONG; ++ default: abort(); ++ } ++} ++ ++#define SET_CC_OP(opsize, op) do { \ ++ switch (opsize) { \ ++ case OS_BYTE: s->cc_op = CC_OP_##op##B; break; \ ++ case OS_WORD: s->cc_op = CC_OP_##op##W; break; \ ++ case OS_LONG: s->cc_op = CC_OP_##op; break; \ ++ default: abort(); \ ++ } \ ++ } while (0) ++ + /* Assign value to a register. If the width is less than the register width + only the low part of the register is set. */ + static void gen_partset_reg(int opsize, int reg, int val) +@@ -881,8 +903,27 @@ DISAS_INSN(divl) + + ext = lduw_code(s->pc); + s->pc += 2; +- if (ext & 0x87f8) { +- gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED); ++ if (ext & 0x400) { ++ if (!m68k_feature(s->env, M68K_FEATURE_M68020_40)) { ++ gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED); ++ return; ++ } ++ num = DREG(ext, 12); ++ reg = DREG(ext, 0); ++ gen_op_mov32(QREG_DIV1, num); ++ gen_op_mov32(QREG_QUADH, reg); ++ SRC_EA(den, OS_LONG, 0, NULL); ++ gen_op_mov32(QREG_DIV2, den); ++ if (ext & 0x0800) { ++ gen_op_divs64(); ++ } else { ++ gen_op_divu64(); ++ } ++ gen_op_mov32 (num, QREG_DIV1); ++ if (num != reg) ++ gen_op_mov32 (reg, QREG_DIV2); ++ gen_op_flags_set(); ++ s->cc_op = CC_OP_FLAGS; + return; + } + num = DREG(ext, 12); +@@ -895,13 +936,10 @@ DISAS_INSN(divl) + } else { + gen_op_divu(2); + } +- if (num == reg) { +- /* div */ +- gen_op_mov32 (reg, QREG_DIV1); +- } else { +- /* rem */ +- gen_op_mov32 (reg, QREG_DIV2); +- } ++ if (num == reg || m68k_feature(s->env, M68K_FEATURE_M68020_60)) ++ gen_op_mov32 (num, QREG_DIV1); ++ if (num != reg) ++ gen_op_mov32 (reg, QREG_DIV2); + gen_op_flags_set(); + s->cc_op = CC_OP_FLAGS; + } +@@ -914,31 +952,33 @@ DISAS_INSN(addsub) + int tmp; + int addr; + int add; ++ int opsize; + + add = (insn & 0x4000) != 0; ++ opsize = insn_opsize(insn, 6); + reg = DREG(insn, 9); + dest = gen_new_qreg(QMODE_I32); + if (insn & 0x100) { +- SRC_EA(tmp, OS_LONG, 0, &addr); ++ SRC_EA(tmp, opsize, -1, &addr); + src = reg; + } else { + tmp = reg; +- SRC_EA(src, OS_LONG, 0, NULL); ++ SRC_EA(src, opsize, -1, NULL); + } + if (add) { + gen_op_add32(dest, tmp, src); + gen_op_update_xflag_lt(dest, src); +- s->cc_op = CC_OP_ADD; ++ SET_CC_OP(opsize, ADD); + } else { + gen_op_update_xflag_lt(tmp, src); + gen_op_sub32(dest, tmp, src); +- s->cc_op = CC_OP_SUB; ++ SET_CC_OP(opsize, SUB); + } + gen_op_update_cc_add(dest, src); + if (insn & 0x100) { +- DEST_EA(insn, OS_LONG, dest, &addr); ++ DEST_EA(insn, opsize, dest, &addr); + } else { +- gen_op_mov32(reg, dest); ++ gen_partset_reg(opsize, reg, dest); + } + } + +@@ -1065,6 +1105,8 @@ DISAS_INSN(movem) + int reg; + int tmp; + int is_load; ++ int opsize; ++ int incr; + + mask = lduw_code(s->pc); + s->pc += 2; +@@ -1076,21 +1118,40 @@ DISAS_INSN(movem) + addr = gen_new_qreg(QMODE_I32); + gen_op_mov32(addr, tmp); + is_load = ((insn & 0x0400) != 0); +- for (i = 0; i < 16; i++, mask >>= 1) { +- if (mask & 1) { +- if (i < 8) +- reg = DREG(i, 0); +- else +- reg = AREG(i, 0); +- if (is_load) { +- tmp = gen_load(s, OS_LONG, addr, 0); +- gen_op_mov32(reg, tmp); +- } else { +- gen_store(s, OS_LONG, addr, reg); +- } +- if (mask != 1) +- gen_op_add32(addr, addr, gen_im32(4)); +- } ++ opsize = (insn & 0x40) != 0 ? OS_LONG : OS_WORD; ++ incr = gen_im32(opsize_bytes(opsize)); ++ if (!is_load && (insn & 070) == 040) { ++ for (i = 15; i >= 0; i--, mask >>= 1) { ++ if (mask & 1) { ++ if (i < 8) ++ reg = DREG(i, 0); ++ else ++ reg = AREG(i, 0); ++ gen_store(s, opsize, addr, reg); ++ if (mask != 1) ++ gen_op_sub32(addr, addr, incr); ++ } ++ } ++ gen_op_mov32(AREG(insn, 0), addr); ++ } else { ++ for (i = 0; i < 16; i++, mask >>= 1) { ++ if (mask & 1) { ++ if (i < 8) ++ reg = DREG(i, 0); ++ else ++ reg = AREG(i, 0); ++ if (is_load) { ++ tmp = gen_load(s, opsize, addr, 1); ++ gen_op_mov32(reg, tmp); ++ } else { ++ gen_store(s, opsize, addr, reg); ++ } ++ if (mask != 1 || (insn & 070) == 030) ++ gen_op_add32(addr, addr, incr); ++ } ++ } ++ if ((insn & 070) == 030) ++ gen_op_mov32(AREG(insn, 0), addr); + } + } + +@@ -1158,10 +1219,26 @@ DISAS_INSN(arith_im) + int dest; + int src2; + int addr; ++ int opsize; + + op = (insn >> 9) & 7; +- SRC_EA(src1, OS_LONG, 0, (op == 6) ? NULL : &addr); +- src2 = gen_im32(read_im32(s)); ++ opsize = insn_opsize(insn, 6); ++ switch (opsize) { ++ case OS_BYTE: ++ src2 = gen_im32(ldsb_code(s->pc + 1)); ++ s->pc += 2; ++ break; ++ case OS_WORD: ++ src2 = gen_im32(ldsw_code(s->pc)); ++ s->pc += 2; ++ break; ++ case OS_LONG: ++ src2 = gen_im32(read_im32(s)); ++ break; ++ default: ++ abort(); ++ } ++ SRC_EA(src1, opsize, -1, (op == 6) ? NULL : &addr); + dest = gen_new_qreg(QMODE_I32); + switch (op) { + case 0: /* ori */ +@@ -1177,14 +1254,14 @@ DISAS_INSN(arith_im) + gen_op_update_xflag_lt(dest, src2); + gen_op_sub32(dest, dest, src2); + gen_op_update_cc_add(dest, src2); +- s->cc_op = CC_OP_SUB; ++ SET_CC_OP(opsize, SUB); + break; + case 3: /* addi */ + gen_op_mov32(dest, src1); + gen_op_add32(dest, dest, src2); + gen_op_update_cc_add(dest, src2); + gen_op_update_xflag_lt(dest, src2); +- s->cc_op = CC_OP_ADD; ++ SET_CC_OP(opsize, ADD); + break; + case 5: /* eori */ + gen_op_xor32(dest, src1, src2); +@@ -1194,13 +1271,13 @@ DISAS_INSN(arith_im) + gen_op_mov32(dest, src1); + gen_op_sub32(dest, dest, src2); + gen_op_update_cc_add(dest, src2); +- s->cc_op = CC_OP_SUB; ++ SET_CC_OP(opsize, SUB); + break; + default: + abort(); + } + if (op != 6) { +- DEST_EA(insn, OS_LONG, dest, &addr); ++ DEST_EA(insn, opsize, dest, &addr); + } + } + +@@ -1290,19 +1367,7 @@ DISAS_INSN(clr) + { + int opsize; + +- switch ((insn >> 6) & 3) { +- case 0: /* clr.b */ +- opsize = OS_BYTE; +- break; +- case 1: /* clr.w */ +- opsize = OS_WORD; +- break; +- case 2: /* clr.l */ +- opsize = OS_LONG; +- break; +- default: +- abort(); +- } ++ opsize = insn_opsize(insn, 6); + DEST_EA(insn, opsize, gen_im32(0), NULL); + gen_logic_cc(s, gen_im32(0)); + } +@@ -1331,17 +1396,20 @@ DISAS_INSN(move_from_ccr) + + DISAS_INSN(neg) + { +- int reg; + int src1; ++ int dest; ++ int addr; ++ int opsize; + +- reg = DREG(insn, 0); +- src1 = gen_new_qreg(QMODE_I32); +- gen_op_mov32(src1, reg); +- gen_op_neg32(reg, src1); +- s->cc_op = CC_OP_SUB; +- gen_op_update_cc_add(reg, src1); +- gen_op_update_xflag_lt(gen_im32(0), src1); +- s->cc_op = CC_OP_SUB; ++ opsize = insn_opsize(insn, 6); ++ SRC_EA(src1, opsize, -1, &addr); ++ dest = gen_new_qreg(QMODE_I32); ++ gen_op_neg32(dest, src1); ++ DEST_EA(insn, opsize, dest, &addr); ++ SET_CC_OP(opsize, SUB); ++ gen_op_update_cc_add(src1, dest); ++ gen_op_update_xflag_lt(gen_im32(0), dest); ++ SET_CC_OP(opsize, SUB); + } + + static void gen_set_sr_im(DisasContext *s, uint16_t val, int ccr_only) +@@ -1390,11 +1458,17 @@ DISAS_INSN(move_to_ccr) + + DISAS_INSN(not) + { +- int reg; ++ int src1; ++ int dest; ++ int addr; ++ int opsize; + +- reg = DREG(insn, 0); +- gen_op_not32(reg, reg); +- gen_logic_cc(s, reg); ++ opsize = insn_opsize(insn, 6); ++ SRC_EA(src1, opsize, -1, &addr); ++ dest = gen_new_qreg(QMODE_I32); ++ gen_op_not32(dest, src1); ++ DEST_EA(insn, opsize, dest, &addr); ++ gen_logic_cc(s, dest); + } + + DISAS_INSN(swap) +@@ -1452,19 +1526,7 @@ DISAS_INSN(tst) + int opsize; + int tmp; + +- switch ((insn >> 6) & 3) { +- case 0: /* tst.b */ +- opsize = OS_BYTE; +- break; +- case 1: /* tst.w */ +- opsize = OS_WORD; +- break; +- case 2: /* tst.l */ +- opsize = OS_LONG; +- break; +- default: +- abort(); +- } ++ opsize = insn_opsize(insn, 6); + SRC_EA(tmp, opsize, -1, NULL); + gen_logic_cc(s, tmp); + } +@@ -1493,28 +1555,149 @@ DISAS_INSN(tas) + DEST_EA(insn, OS_BYTE, dest, &addr); + } + ++DISAS_INSN(cas) ++{ ++ int opsize; ++ int src; ++ int tmp; ++ int ext; ++ int regc; ++ int regu; ++ int l1, l2; ++ int addr; ++ ++ ext = lduw_code(s->pc); ++ s->pc += 2; ++ regc = DREG(ext, 0); ++ regu = DREG(ext, 6); ++ tmp = gen_new_qreg(QMODE_I32); ++ switch ((insn >> 9) & 3) { ++ case 1: ++ opsize = OS_BYTE; ++ break; ++ case 2: ++ opsize = OS_WORD; ++ break; ++ case 3: ++ opsize = OS_LONG; ++ break; ++ default: ++ abort(); ++ } ++ SRC_EA(src, opsize, -1, &addr); ++ gen_op_sub32(tmp, src, regc); ++ gen_op_update_cc_add(tmp, regc); ++ SET_CC_OP(opsize, SUB); ++ l1 = gen_new_label(); ++ l2 = gen_new_label(); ++ gen_jmpcc(s, 6, l1); ++ DEST_EA(insn, opsize, regu, &addr); ++ gen_op_jmp(l2); ++ gen_set_label(l1); ++ gen_partset_reg(opsize, regc, src); ++ gen_set_label(l2); ++} ++ ++DISAS_INSN(cas2) ++{ ++ int opsize; ++ int src1, src2; ++ int cmp1, cmp2; ++ int ext1, ext2; ++ int regc1, regc2; ++ int regu1, regu2; ++ int tmp; ++ int l1, l2; ++ ++ ext1 = lduw_code(s->pc); ++ s->pc += 2; ++ regc1 = DREG(ext1, 0); ++ regu1 = DREG(ext1, 6); ++ if (ext1 & 0x8000) ++ src1 = AREG(ext1, 12); ++ else ++ src1 = DREG(ext1, 12); ++ ext2 = lduw_code(s->pc); ++ s->pc += 2; ++ regc2 = DREG(ext2, 0); ++ regu2 = DREG(ext2, 6); ++ if (ext2 & 0x8000) ++ src2 = AREG(ext2, 12); ++ else ++ src2 = DREG(ext2, 12); ++ if (insn & 0x200) ++ opsize = OS_LONG; ++ else ++ opsize = OS_WORD; ++ l1 = gen_new_label(); ++ l2 = gen_new_label(); ++ tmp = gen_new_qreg(QMODE_I32); ++ cmp1 = gen_load(s, opsize, src1, 1); ++ cmp2 = gen_load(s, opsize, src2, 1); ++ gen_op_sub32(tmp, cmp1, regc1); ++ gen_op_update_cc_add(tmp, regc1); ++ SET_CC_OP(opsize, SUB); ++ gen_jmpcc(s, 6, l1); ++ gen_op_sub32(tmp, cmp2, regc2); ++ gen_op_update_cc_add(tmp, regc2); ++ SET_CC_OP(opsize, SUB); ++ gen_jmpcc(s, 6, l1); ++ gen_store(s, opsize, src1, regu1); ++ gen_store(s, opsize, src2, regu2); ++ gen_op_jmp(l2); ++ gen_set_label(l1); ++ gen_partset_reg(opsize, regc1, cmp1); ++ gen_partset_reg(opsize, regc2, cmp2); ++ gen_set_label(l2); ++} ++ + DISAS_INSN(mull) + { + uint16_t ext; + int reg; + int src1; + int dest; ++ int regh; + + /* The upper 32 bits of the product are discarded, so + muls.l and mulu.l are functionally equivalent. */ + ext = lduw_code(s->pc); + s->pc += 2; +- if (ext & 0x87ff) { +- gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED); +- return; ++ if (ext & 0x400) { ++ if (!m68k_feature(s->env, M68K_FEATURE_M68020_40)) { ++ gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED); ++ return; ++ } ++ reg = DREG(ext, 12); ++ regh = DREG(ext, 0); ++ SRC_EA(src1, OS_LONG, 0, NULL); ++ dest = gen_new_qreg(QMODE_I32); ++ if (ext & 0x800) ++ gen_op_muls64(dest, src1, reg); ++ else ++ gen_op_mulu64(dest, src1, reg); ++ gen_op_mov32(reg, dest); ++ gen_op_mov32(regh, QREG_QUADH); ++ gen_op_flags_set(); ++ s->cc_op = CC_OP_FLAGS; ++ return; + } + reg = DREG(ext, 12); + SRC_EA(src1, OS_LONG, 0, NULL); + dest = gen_new_qreg(QMODE_I32); +- gen_op_mul32(dest, src1, reg); ++ if (m68k_feature(s->env, M68K_FEATURE_M68000)) { ++ if (ext & 0x800) ++ gen_op_muls32_cc(dest, src1, reg); ++ else ++ gen_op_mulu32_cc(dest, src1, reg); ++ gen_op_flags_set(); ++ s->cc_op = CC_OP_FLAGS; ++ } else { ++ gen_op_mul32(dest, src1, reg); ++ /* Unlike m68k, coldfire always clears the overflow bit. */ ++ gen_logic_cc(s, dest); ++ } + gen_op_mov32(reg, dest); +- /* Unlike m68k, coldfire always clears the overflow bit. */ +- gen_logic_cc(s, dest); + } + + DISAS_INSN(link) +@@ -1534,6 +1717,22 @@ DISAS_INSN(link) + gen_op_add32(QREG_SP, tmp, gen_im32(offset)); + } + ++DISAS_INSN(linkl) ++{ ++ int32_t offset; ++ int reg; ++ int tmp; ++ ++ offset = read_im32(s); ++ reg = AREG(insn, 0); ++ tmp = gen_new_qreg(QMODE_I32); ++ gen_op_sub32(tmp, QREG_SP, gen_im32(4)); ++ gen_store(s, OS_LONG, tmp, reg); ++ if (reg != QREG_SP) ++ gen_op_mov32(reg, tmp); ++ gen_op_add32(QREG_SP, tmp, gen_im32(offset)); ++} ++ + DISAS_INSN(unlk) + { + int src; +@@ -1586,8 +1785,14 @@ DISAS_INSN(addsubq) + int dest; + int val; + int addr; ++ int opsize; + +- SRC_EA(src1, OS_LONG, 0, &addr); ++ if ((insn & 070) == 010) { ++ /* Operation on address register is always long. */ ++ opsize = OS_LONG; ++ } else ++ opsize = insn_opsize(insn, 6); ++ SRC_EA(src1, opsize, -1, &addr); + val = (insn >> 9) & 7; + if (val == 0) + val = 8; +@@ -1606,15 +1811,15 @@ DISAS_INSN(addsubq) + if (insn & 0x0100) { + gen_op_update_xflag_lt(dest, src2); + gen_op_sub32(dest, dest, src2); +- s->cc_op = CC_OP_SUB; ++ SET_CC_OP(opsize, SUB); + } else { + gen_op_add32(dest, dest, src2); + gen_op_update_xflag_lt(dest, src2); +- s->cc_op = CC_OP_ADD; ++ SET_CC_OP(opsize, ADD); + } + gen_op_update_cc_add(dest, src2); + } +- DEST_EA(insn, OS_LONG, dest, &addr); ++ DEST_EA(insn, opsize, dest, &addr); + } + + DISAS_INSN(tpf) +@@ -1633,6 +1838,47 @@ DISAS_INSN(tpf) + } + } + ++DISAS_INSN(scc_mem) ++{ ++ int l1; ++ int cond; ++ int dest; ++ ++ l1 = gen_new_label(); ++ cond = (insn >> 8) & 0xf; ++ dest = gen_new_qreg(QMODE_I32); ++ gen_op_mov32(dest, gen_im32(0)); ++ gen_jmpcc(s, cond ^ 1, l1); ++ gen_op_mov32(dest, gen_im32(0xff)); ++ gen_set_label(l1); ++ DEST_EA(insn, OS_BYTE, dest, NULL); ++} ++ ++DISAS_INSN(dbcc) ++{ ++ int l1; ++ int reg; ++ int tmp; ++ int16_t offset; ++ uint32_t base; ++ ++ reg = DREG(insn, 0); ++ base = s->pc; ++ offset = ldsw_code(s->pc); ++ s->pc += 2; ++ l1 = gen_new_label(); ++ gen_jmpcc(s, (insn >> 8) & 0xf, l1); ++ tmp = gen_new_qreg(QMODE_I32); ++ gen_op_ext16s32(tmp, reg); ++ gen_op_set_T0_z32(tmp); ++ gen_op_add32(tmp, tmp, gen_im32(-1)); ++ gen_partset_reg(OS_WORD, reg, tmp); ++ gen_op_jmp_T0(l1); ++ gen_jmp_tb(s, 1, base + offset); ++ gen_set_label(l1); ++ gen_jmp_tb(s, 0, s->pc); ++} ++ + DISAS_INSN(branch) + { + int32_t offset; +@@ -1698,17 +1944,19 @@ DISAS_INSN(or) + int dest; + int src; + int addr; ++ int opsize; + ++ opsize = insn_opsize(insn, 6); + reg = DREG(insn, 9); + dest = gen_new_qreg(QMODE_I32); + if (insn & 0x100) { +- SRC_EA(src, OS_LONG, 0, &addr); ++ SRC_EA(src, opsize, -1, &addr); + gen_op_or32(dest, src, reg); +- DEST_EA(insn, OS_LONG, dest, &addr); ++ DEST_EA(insn, opsize, dest, &addr); + } else { +- SRC_EA(src, OS_LONG, 0, NULL); ++ SRC_EA(src, opsize, 0, NULL); + gen_op_or32(dest, src, reg); +- gen_op_mov32(reg, dest); ++ gen_partset_reg(opsize, reg, dest); + } + gen_logic_cc(s, dest); + } +@@ -1718,7 +1966,7 @@ DISAS_INSN(suba) + int src; + int reg; + +- SRC_EA(src, OS_LONG, 0, NULL); ++ SRC_EA(src, (insn & 0x100) ? OS_LONG : OS_WORD, -1, NULL); + reg = AREG(insn, 9); + gen_op_sub32(reg, reg, src); + } +@@ -1763,34 +2011,18 @@ DISAS_INSN(mov3q) + + DISAS_INSN(cmp) + { +- int op; + int src; + int reg; + int dest; + int opsize; + +- op = (insn >> 6) & 3; +- switch (op) { +- case 0: /* cmp.b */ +- opsize = OS_BYTE; +- s->cc_op = CC_OP_CMPB; +- break; +- case 1: /* cmp.w */ +- opsize = OS_WORD; +- s->cc_op = CC_OP_CMPW; +- break; +- case 2: /* cmp.l */ +- opsize = OS_LONG; +- s->cc_op = CC_OP_SUB; +- break; +- default: +- abort(); +- } ++ opsize = insn_opsize(insn, 6); + SRC_EA(src, opsize, -1, NULL); + reg = DREG(insn, 9); + dest = gen_new_qreg(QMODE_I32); + gen_op_sub32(dest, reg, src); + gen_op_update_cc_add(dest, src); ++ SET_CC_OP(opsize, SUB); + } + + DISAS_INSN(cmpa) +@@ -1810,7 +2042,7 @@ DISAS_INSN(cmpa) + dest = gen_new_qreg(QMODE_I32); + gen_op_sub32(dest, reg, src); + gen_op_update_cc_add(dest, src); +- s->cc_op = CC_OP_SUB; ++ SET_CC_OP(opsize, SUB); + } + + DISAS_INSN(eor) +@@ -1819,13 +2051,15 @@ DISAS_INSN(eor) + int reg; + int dest; + int addr; ++ int opsize; + +- SRC_EA(src, OS_LONG, 0, &addr); ++ opsize = insn_opsize(insn, 6); ++ SRC_EA(src, opsize, -1, &addr); + reg = DREG(insn, 9); + dest = gen_new_qreg(QMODE_I32); + gen_op_xor32(dest, src, reg); + gen_logic_cc(s, dest); +- DEST_EA(insn, OS_LONG, dest, &addr); ++ DEST_EA(insn, opsize, dest, &addr); + } + + DISAS_INSN(and) +@@ -1834,17 +2068,19 @@ DISAS_INSN(and) + int reg; + int dest; + int addr; ++ int opsize; + ++ opsize = insn_opsize(insn, 6); + reg = DREG(insn, 9); + dest = gen_new_qreg(QMODE_I32); + if (insn & 0x100) { +- SRC_EA(src, OS_LONG, 0, &addr); ++ SRC_EA(src, opsize, -1, &addr); + gen_op_and32(dest, src, reg); +- DEST_EA(insn, OS_LONG, dest, &addr); ++ DEST_EA(insn, opsize, dest, &addr); + } else { +- SRC_EA(src, OS_LONG, 0, NULL); ++ SRC_EA(src, opsize, -1, NULL); + gen_op_and32(dest, src, reg); +- gen_op_mov32(reg, dest); ++ gen_partset_reg(opsize, reg, dest); + } + gen_logic_cc(s, dest); + } +@@ -1854,7 +2090,7 @@ DISAS_INSN(adda) + int src; + int reg; + +- SRC_EA(src, OS_LONG, 0, NULL); ++ SRC_EA(src, (insn & 0x100) ? OS_LONG : OS_WORD, -1, NULL); + reg = AREG(insn, 9); + gen_op_add32(reg, reg, src); + } +@@ -1907,6 +2143,58 @@ DISAS_INSN(shift_im) + } + } + ++DISAS_INSN(shift8_im) ++{ ++ int reg; ++ int dest; ++ int tmp; ++ ++ reg = DREG(insn, 0); ++ tmp = (insn >> 9) & 7; ++ if (tmp == 0) ++ tmp = 8; ++ dest = gen_new_qreg(QMODE_I32); ++ if (insn & 0x100) { ++ gen_op_shl8_im_cc(dest, reg, tmp); ++ s->cc_op = CC_OP_SHLB; ++ } else { ++ if (insn & 8) { ++ gen_op_shr8_im_cc(dest, reg, tmp); ++ s->cc_op = CC_OP_SHRB; ++ } else { ++ gen_op_sar8_im_cc(dest, reg, tmp); ++ s->cc_op = CC_OP_SARB; ++ } ++ } ++ gen_partset_reg(OS_BYTE, reg, dest); ++} ++ ++DISAS_INSN(shift16_im) ++{ ++ int reg; ++ int dest; ++ int tmp; ++ ++ reg = DREG(insn, 0); ++ tmp = (insn >> 9) & 7; ++ if (tmp == 0) ++ tmp = 8; ++ dest = gen_new_qreg(QMODE_I32); ++ if (insn & 0x100) { ++ gen_op_shl16_im_cc(dest, reg, tmp); ++ s->cc_op = CC_OP_SHLW; ++ } else { ++ if (insn & 8) { ++ gen_op_shr16_im_cc(dest, reg, tmp); ++ s->cc_op = CC_OP_SHRW; ++ } else { ++ gen_op_sar16_im_cc(dest, reg, tmp); ++ s->cc_op = CC_OP_SARW; ++ } ++ } ++ gen_partset_reg(OS_WORD, reg, dest); ++} ++ + DISAS_INSN(shift_reg) + { + int reg; +@@ -1931,6 +2219,603 @@ DISAS_INSN(shift_reg) + } + } + ++DISAS_INSN(shift8_reg) ++{ ++ int reg; ++ int src; ++ int dest; ++ int tmp; ++ ++ reg = DREG(insn, 0); ++ src = DREG(insn, 9); ++ tmp = gen_new_qreg(QMODE_I32); ++ gen_op_and32(tmp, src, gen_im32(63)); ++ dest = gen_new_qreg(QMODE_I32); ++ if (insn & 0x100) { ++ gen_op_shl8_cc(dest, reg, tmp); ++ s->cc_op = CC_OP_SHLB; ++ } else { ++ if (insn & 8) { ++ gen_op_shr8_cc(dest, reg, tmp); ++ s->cc_op = CC_OP_SHRB; ++ } else { ++ gen_op_sar8_cc(dest, reg, tmp); ++ s->cc_op = CC_OP_SARB; ++ } ++ } ++ gen_partset_reg(OS_BYTE, reg, dest); ++} ++ ++DISAS_INSN(shift16_reg) ++{ ++ int reg; ++ int src; ++ int dest; ++ int tmp; ++ ++ reg = DREG(insn, 0); ++ src = DREG(insn, 9); ++ tmp = gen_new_qreg(QMODE_I32); ++ gen_op_and32(tmp, src, gen_im32(63)); ++ dest = gen_new_qreg(QMODE_I32); ++ if (insn & 0x100) { ++ gen_op_shl16_cc(dest, reg, tmp); ++ s->cc_op = CC_OP_SHLW; ++ } else { ++ if (insn & 8) { ++ gen_op_shr16_cc(dest, reg, tmp); ++ s->cc_op = CC_OP_SHRW; ++ } else { ++ gen_op_sar16_cc(dest, reg, tmp); ++ s->cc_op = CC_OP_SARW; ++ } ++ } ++ gen_partset_reg(OS_WORD, reg, dest); ++} ++ ++DISAS_INSN(shift_mem) ++{ ++ int src; ++ int dest; ++ int addr; ++ ++ SRC_EA(src, OS_WORD, 0, &addr); ++ dest = gen_new_qreg(QMODE_I32); ++ if (insn & 0x100) { ++ gen_op_shl16_im_cc(dest, src, 1); ++ s->cc_op = CC_OP_SHLW; ++ } else { ++ if (insn & 8) { ++ gen_op_shr16_im_cc(dest, src, 1); ++ s->cc_op = CC_OP_SHRW; ++ } else { ++ gen_op_sar16_im_cc(dest, src, 1); ++ s->cc_op = CC_OP_SARW; ++ } ++ } ++ DEST_EA(insn, OS_WORD, dest, &addr); ++} ++ ++DISAS_INSN(rotate_im) ++{ ++ int reg; ++ int tmp; ++ ++ reg = DREG(insn, 0); ++ tmp = (insn >> 9) & 7; ++ if (tmp == 0) ++ tmp = 8; ++ tmp = gen_im32(tmp); ++ if (insn & 8) { ++ if (insn & 0x100) { ++ gen_op_rol32_cc(reg, reg, tmp); ++ } else { ++ gen_op_ror32_cc(reg, reg, tmp); ++ } ++ } else { ++ if (insn & 0x100) { ++ gen_op_roxl32_cc(reg, reg, tmp); ++ } else { ++ gen_op_roxr32_cc(reg, reg, tmp); ++ } ++ } ++ gen_op_flags_set(); ++ s->cc_op = CC_OP_FLAGS; ++} ++ ++DISAS_INSN(rotate8_im) ++{ ++ int reg; ++ int dest; ++ int tmp; ++ ++ reg = DREG(insn, 0); ++ tmp = (insn >> 9) & 7; ++ if (tmp == 0) ++ tmp = 8; ++ tmp = gen_im32(tmp); ++ dest = gen_new_qreg(QMODE_I32); ++ if (insn & 8) { ++ if (insn & 0x100) { ++ gen_op_rol8_cc(dest, reg, tmp); ++ } else { ++ gen_op_ror8_cc(dest, reg, tmp); ++ } ++ } else { ++ if (insn & 0x100) { ++ gen_op_roxl8_cc(dest, reg, tmp); ++ } else { ++ gen_op_roxr8_cc(dest, reg, tmp); ++ } ++ } ++ gen_op_flags_set(); ++ s->cc_op = CC_OP_FLAGS; ++ gen_partset_reg(OS_BYTE, reg, dest); ++} ++ ++DISAS_INSN(rotate16_im) ++{ ++ int reg; ++ int dest; ++ int tmp; ++ ++ reg = DREG(insn, 0); ++ tmp = (insn >> 9) & 7; ++ if (tmp == 0) ++ tmp = 8; ++ tmp = gen_im32(tmp); ++ dest = gen_new_qreg(QMODE_I32); ++ if (insn & 8) { ++ if (insn & 0x100) { ++ gen_op_rol16_cc(dest, reg, tmp); ++ } else { ++ gen_op_ror16_cc(dest, reg, tmp); ++ } ++ } else { ++ if (insn & 0x100) { ++ gen_op_roxl16_cc(dest, reg, tmp); ++ } else { ++ gen_op_roxr16_cc(dest, reg, tmp); ++ } ++ } ++ gen_op_flags_set(); ++ s->cc_op = CC_OP_FLAGS; ++ gen_partset_reg(OS_WORD, reg, dest); ++} ++ ++DISAS_INSN(rotate_reg) ++{ ++ int reg; ++ int src; ++ int tmp; ++ ++ reg = DREG(insn, 0); ++ src = DREG(insn, 9); ++ tmp = gen_new_qreg(QMODE_I32); ++ gen_op_and32(tmp, src, gen_im32(63)); ++ if (insn & 8) { ++ if (insn & 0x100) { ++ gen_op_rol32_cc(reg, reg, tmp); ++ } else { ++ gen_op_ror32_cc(reg, reg, tmp); ++ } ++ } else { ++ if (insn & 0x100) { ++ gen_op_roxl32_cc(reg, reg, tmp); ++ } else { ++ gen_op_roxr32_cc(reg, reg, tmp); ++ } ++ } ++ gen_op_flags_set(); ++ s->cc_op = CC_OP_FLAGS; ++} ++ ++DISAS_INSN(rotate8_reg) ++{ ++ int reg; ++ int src; ++ int dest; ++ int tmp; ++ ++ reg = DREG(insn, 0); ++ src = DREG(insn, 9); ++ tmp = gen_new_qreg(QMODE_I32); ++ gen_op_and32(tmp, src, gen_im32(63)); ++ dest = gen_new_qreg(QMODE_I32); ++ if (insn & 8) { ++ if (insn & 0x100) { ++ gen_op_rol8_cc(dest, reg, tmp); ++ } else { ++ gen_op_ror8_cc(dest, reg, tmp); ++ } ++ } else { ++ if (insn & 0x100) { ++ gen_op_roxl8_cc(dest, reg, tmp); ++ } else { ++ gen_op_roxr8_cc(dest, reg, tmp); ++ } ++ } ++ gen_op_flags_set(); ++ s->cc_op = CC_OP_FLAGS; ++ gen_partset_reg(OS_BYTE, reg, dest); ++} ++ ++DISAS_INSN(rotate16_reg) ++{ ++ int reg; ++ int src; ++ int dest; ++ int tmp; ++ ++ reg = DREG(insn, 0); ++ src = DREG(insn, 9); ++ tmp = gen_new_qreg(QMODE_I32); ++ gen_op_and32(tmp, src, gen_im32(63)); ++ dest = gen_new_qreg(QMODE_I32); ++ if (insn & 8) { ++ if (insn & 0x100) { ++ gen_op_rol16_cc(dest, reg, tmp); ++ } else { ++ gen_op_ror16_cc(dest, reg, tmp); ++ } ++ } else { ++ if (insn & 0x100) { ++ gen_op_roxl16_cc(dest, reg, tmp); ++ } else { ++ gen_op_roxr16_cc(dest, reg, tmp); ++ } ++ } ++ gen_op_flags_set(); ++ s->cc_op = CC_OP_FLAGS; ++ gen_partset_reg(OS_WORD, reg, dest); ++} ++ ++DISAS_INSN(rotate_mem) ++{ ++ int src; ++ int dest; ++ int addr; ++ ++ SRC_EA(src, OS_WORD, 0, &addr); ++ dest = gen_new_qreg(QMODE_I32); ++ if (insn & 8) { ++ if (insn & 0x100) { ++ gen_op_rol16_cc(dest, src, gen_im32(1)); ++ } else { ++ gen_op_ror16_cc(dest, src, gen_im32(1)); ++ } ++ } else { ++ if (insn & 0x100) { ++ gen_op_roxl16_cc(dest, src, gen_im32(1)); ++ } else { ++ gen_op_roxr16_cc(dest, src, gen_im32(1)); ++ } ++ } ++ gen_op_flags_set(); ++ s->cc_op = CC_OP_FLAGS; ++ DEST_EA(insn, OS_WORD, dest, &addr); ++} ++ ++DISAS_INSN(bitfield_reg) ++{ ++ uint16_t ext; ++ int tmp; ++ int tmp1; ++ int reg; ++ int offset; ++ int width; ++ int op; ++ int reg2; ++ uint32_t mask; ++ ++ reg = DREG(insn, 0); ++ op = (insn >> 8) & 7; ++ ext = lduw_code(s->pc); ++ s->pc += 2; ++ if ((ext & 0x820) == 0) { ++ /* constant offset and width */ ++ offset = (ext >> 6) & 31; ++ width = (ext & 31); ++ if (width == 0) ++ width = 32; ++ reg2 = DREG(ext, 12); ++ mask = 0xffffffff << (32 - width); ++ if (offset > 0) ++ mask = (mask >> offset) | (mask << (32 - offset)); ++ tmp = gen_new_qreg(QMODE_I32); ++ gen_op_and32(tmp, reg, gen_im32(mask)); ++ if (offset > 0) { ++ tmp1 = gen_new_qreg(QMODE_I32); ++ gen_op_rol32(tmp1, tmp, gen_im32(offset)); ++ } else ++ tmp1 = tmp; ++ gen_logic_cc(s, tmp1); ++ switch (op) { ++ case 0: /* bftst */ ++ break; ++ case 1: /* bfextu */ ++ if (offset + width != 32) ++ gen_op_rol32(reg2, tmp, gen_im32((offset + width) & 31)); ++ else ++ gen_op_mov32(reg2, tmp); ++ break; ++ case 2: /* bfchg */ ++ gen_op_xor32(reg, reg, gen_im32(mask)); ++ break; ++ case 3: /* bfexts */ ++ if (offset > 0) ++ gen_op_rol32(reg2, tmp, gen_im32(offset)); ++ if (width < 32) ++ gen_op_sar32(reg2, reg2, gen_im32(32 - width)); ++ break; ++ case 4: /* bfclr */ ++ gen_op_and32(reg, reg, gen_im32(~mask)); ++ break; ++ case 5: /* bfffo */ ++ if (offset > 0) ++ gen_op_rol32(reg2, tmp, gen_im32(offset)); ++ gen_op_bfffo(tmp, tmp, gen_im32(width)); ++ gen_op_add32(reg2, tmp, gen_im32(offset)); ++ break; ++ case 6: /* bfset */ ++ gen_op_or32(reg, reg, gen_im32(mask)); ++ break; ++ case 7: /* bfins */ ++ if (width == 32) { ++ if (offset > 0) ++ gen_op_ror32(reg, reg2, gen_im32(offset)); ++ else ++ gen_op_mov32(reg, reg2); ++ } else { ++ gen_op_and32(tmp, reg2, gen_im32((1u << width) - 1)); ++ if (offset + width != 32) ++ gen_op_ror32(tmp, tmp, gen_im32((offset + width) & 31)); ++ gen_op_and32(reg, reg, gen_im32(~mask)); ++ gen_op_or32(reg, reg, tmp); ++ } ++ break; ++ } ++ return; ++ } ++ /* Not yet implemented */ ++ gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED); ++} ++ ++/* Generate a load from a bitfield. */ ++static void gen_bitfield_load(DisasContext *s, int addr, int endpos, ++ int *val1, int *val2) ++{ ++ int tmp; ++ ++ if (endpos <= 8) ++ *val1 = gen_load(s, OS_BYTE, addr, 0); ++ else if (endpos <= 24) { ++ *val1 = gen_load(s, OS_WORD, addr, 0); ++ if (endpos > 16) { ++ tmp = gen_new_qreg(QMODE_I32); ++ gen_op_add32(tmp, addr, gen_im32(2)); ++ *val2 = gen_load(s, OS_BYTE, tmp, 0); ++ } ++ } else { ++ *val1 = gen_load(s, OS_LONG, addr, 0); ++ if (endpos > 32) { ++ tmp = gen_new_qreg(QMODE_I32); ++ gen_op_add32(tmp, addr, gen_im32(4)); ++ *val2 = gen_load(s, OS_BYTE, tmp, 0); ++ } ++ } ++} ++ ++/* Generate a store to a bitfield. */ ++static void gen_bitfield_store(DisasContext *s, int addr, int endpos, ++ int val1, int val2) ++{ ++ int tmp; ++ ++ if (endpos <= 8) ++ gen_store(s, OS_BYTE, addr, val1); ++ else if (endpos <= 24) { ++ gen_store(s, OS_WORD, addr, val1); ++ if (endpos > 16) { ++ tmp = gen_new_qreg(QMODE_I32); ++ gen_op_add32(tmp, addr, gen_im32(2)); ++ gen_store(s, OS_BYTE, tmp, val2); ++ } ++ } else { ++ gen_store(s, OS_LONG, addr, val1); ++ if (endpos > 32) { ++ tmp = gen_new_qreg(QMODE_I32); ++ gen_op_add32(tmp, addr, gen_im32(4)); ++ gen_store(s, OS_BYTE, tmp, val2); ++ } ++ } ++} ++ ++static int gen_bitfield_cc(DisasContext *s, int offset, int width, ++ int val1, int val2) ++{ ++ int dest; ++ int tmp; ++ ++ dest = gen_new_qreg(QMODE_I32); ++ if (offset + width <= 8) ++ gen_op_shl32(dest, val1, gen_im32(24 + offset)); ++ else if (offset + width <= 24) { ++ gen_op_shl32(dest, val1, gen_im32(16 + offset)); ++ if (offset + width > 16) { ++ tmp = gen_new_qreg(QMODE_I32); ++ gen_op_shl32(tmp, val2, gen_im32(8 + offset)); ++ gen_op_or32(dest, dest, tmp); ++ } ++ } else { ++ gen_op_shl32(dest, val1, gen_im32(offset)); ++ if (offset + width > 32) { ++ tmp = gen_new_qreg(QMODE_I32); ++ gen_op_shr32(tmp, val2, gen_im32(offset)); ++ gen_op_or32(dest, dest, tmp); ++ } ++ } ++ gen_op_and32(dest, dest, gen_im32(0xffffffff << (32 - width))); ++ gen_logic_cc(s, dest); ++ return dest; ++} ++ ++static void gen_bitfield_op(int offset, int width, int op, int val1, int val2) ++{ ++ uint32_t mask1; ++ uint32_t mask2; ++ int endpos = offset + width; ++ ++ if (endpos <= 8) { ++ mask1 = (0xff >> offset) & (0xff << (8 - endpos)); ++ mask2 = 0; ++ } else if (endpos <= 16) { ++ mask1 = (0xffff >> offset) & (0xffff << (16 - endpos)); ++ mask2 = 0; ++ } else if (endpos <= 24) { ++ mask1 = 0xffffff >> offset; ++ mask2 = 0xff & (0xff << (24 - endpos)); ++ } else if (endpos <= 32) { ++ mask1 = (0xffffffff >> offset) & (0xffffffff << (32 - endpos)); ++ mask2 = 0; ++ } else { ++ mask1 = 0xffffffff >> offset; ++ mask2 = 0xff & (0xff << (40 - endpos)); ++ } ++ switch (op) { ++ case 2: /* bfchg */ ++ gen_op_xor32(val1, val1, gen_im32(mask1)); ++ if (mask2) ++ gen_op_xor32(val2, val2, gen_im32(mask2)); ++ break; ++ case 4: /* bfclr */ ++ gen_op_and32(val1, val1, gen_im32(~mask1)); ++ if (mask2) ++ gen_op_and32(val2, val2, gen_im32(~mask2)); ++ break; ++ case 6: /* bfset */ ++ gen_op_or32(val1, val1, gen_im32(mask1)); ++ if (mask2) ++ gen_op_or32(val2, val2, gen_im32(mask2)); ++ break; ++ } ++} ++ ++static void gen_bitfield_ins(int offset, int width, int src, ++ int val1, int val2) ++{ ++ int tmp; ++ int endpos = offset + width; ++ ++ tmp = gen_new_qreg(QMODE_I32); ++ if (width < 32) { ++ gen_op_and32(tmp, src, gen_im32((1u << width) - 1)); ++ } else ++ gen_op_mov32(tmp, src); ++ if (endpos <= 8) { ++ if (endpos < 8) ++ gen_op_shl32(tmp, tmp, gen_im32(8 - endpos)); ++ gen_op_or32(val1, val1, tmp); ++ } else if (endpos <= 16) { ++ if (endpos < 16) ++ gen_op_shl32(tmp, tmp, gen_im32(16 - endpos)); ++ gen_op_or32(val1, val1, tmp); ++ } else if (endpos <= 24) { ++ gen_op_shr32(tmp, tmp, gen_im32(endpos - 16)); ++ gen_op_or32(val1, val1, tmp); ++ gen_op_and32(tmp, src, gen_im32((1u << (endpos - 16)) - 1)); ++ if (endpos < 24) ++ gen_op_shl32(tmp, tmp, gen_im32(24 - endpos)); ++ gen_op_or32(val2, val2, tmp); ++ } else if (endpos <= 32) { ++ if (endpos < 32) ++ gen_op_shl32(tmp, tmp, gen_im32(32 - endpos)); ++ gen_op_or32(val1, val1, tmp); ++ } else { ++ gen_op_shr32(tmp, tmp, gen_im32(endpos - 32)); ++ gen_op_or32(val1, val1, tmp); ++ gen_op_and32(tmp, src, gen_im32((1u << (endpos - 32)) - 1)); ++ gen_op_shr32(tmp, tmp, gen_im32(32 - endpos)); ++ gen_op_or32(val2, val2, tmp); ++ } ++} ++ ++DISAS_INSN(bitfield_mem) ++{ ++ uint16_t ext; ++ int val; ++ int val1, val2; ++ int src; ++ int offset; ++ int width; ++ int op; ++ int reg; ++ int addr; ++ uint32_t mask; ++ ++ op = (insn >> 8) & 7; ++ ext = lduw_code(s->pc); ++ s->pc += 2; ++ src = gen_lea(s, insn, OS_LONG); ++ if (src == -1) { ++ gen_addr_fault(s); ++ return; ++ } ++ if ((ext & 0x820) == 0) { ++ /* constant offset and width */ ++ offset = (ext >> 6) & 31; ++ width = (ext & 31); ++ if (width == 0) ++ width = 32; ++ reg = DREG(ext, 12); ++ mask = 0xffffffff << (32 - width); ++ addr = gen_new_qreg(QMODE_I32); ++ if (offset > 7) { ++ gen_op_add32(addr, src, gen_im32(offset >> 3)); ++ offset &= 7; ++ } else ++ gen_op_mov32(addr, src); ++ if (offset > 0) ++ mask <<= 32 - offset; ++ gen_bitfield_load(s, addr, offset + width, &val1, &val2); ++ val = gen_bitfield_cc(s, offset, width, val1, val2); ++ switch (op) { ++ case 0: /* bftst */ ++ break; ++ case 1: /* bfextu */ ++ if (width < 32) ++ gen_op_shr32(reg, val, gen_im32(32 - width)); ++ else ++ gen_op_mov32(reg, val); ++ break; ++ case 3: /* bfexts */ ++ if (width < 32) ++ gen_op_sar32(reg, val, gen_im32(32 - width)); ++ else ++ gen_op_mov32(reg, val); ++ break; ++ case 5: /* bfffo */ ++ gen_op_bfffo(val, val, gen_im32(width)); ++ gen_op_add32(reg, val, gen_im32(offset)); ++ break; ++ case 2: /* bfchg */ ++ case 4: /* bfclr */ ++ case 6: /* bfset */ ++ gen_bitfield_op(offset, width, op, val1, val2); ++ gen_bitfield_store(s, addr, offset + width, val1, val2); ++ break; ++ case 7: /* bfins */ ++ gen_bitfield_op(offset, width, 4, val1, val2); ++ gen_bitfield_ins(offset, width, reg, val1, val2); ++ gen_bitfield_store(s, addr, offset + width, val1, val2); ++ break; ++ } ++ return; ++ } ++ /* Not yet implemented */ ++ gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED); ++} ++ + DISAS_INSN(ff1) + { + int reg; +@@ -2194,17 +3079,42 @@ DISAS_INSN(fpu) + case 7: + { + int addr; ++ int incr; + uint16_t mask; +- if ((ext & 0x1f00) != 0x1000 || (ext & 0xff) == 0) ++ if ((ext & 0xf00) != 0 || (ext & 0xff) == 0) + goto undef; +- src = gen_lea(s, insn, OS_LONG); +- if (src == -1) { +- gen_addr_fault(s); +- return; +- } ++ if ((ext & 0x1000) == 0 && !m68k_feature(s->env, M68K_FEATURE_FPU)) ++ goto undef; ++ if ((insn & 070) == 040) ++ src = AREG(insn, 0); ++ else { ++ src = gen_lea(s, insn, OS_LONG); ++ if (src == -1) { ++ gen_addr_fault(s); ++ return; ++ } ++ } + addr = gen_new_qreg(QMODE_I32); + gen_op_mov32(addr, src); + mask = 0x80; ++ if (m68k_feature(s->env, M68K_FEATURE_FPU)) ++ incr = gen_im32(12); ++ else ++ incr = gen_im32(8); ++ if ((ext & (1 << 13)) && (insn & 070) == 040) { ++ dest = QREG_F7; ++ while (mask) { ++ if (ext & mask) { ++ s->is_mem = 1; ++ gen_op_sub32(addr, addr, incr); ++ gen_op_mov32(AREG(insn, 0), addr); ++ gen_st(s, f64, addr, dest); ++ } ++ mask >>= 1; ++ dest++; ++ } ++ return; ++ } + dest = QREG_F0; + while (mask) { + if (ext & mask) { +@@ -2216,8 +3126,11 @@ DISAS_INSN(fpu) + /* load */ + gen_ld(s, f64, dest, addr); + } +- if (ext & (mask - 1)) +- gen_op_add32(addr, addr, gen_im32(8)); ++ if (ext & (mask - 1) || (insn & 070) == 030) { ++ gen_op_add32(addr, addr, incr); ++ if ((insn & 070) == 030) ++ gen_op_mov32(AREG(insn, 0), addr); ++ } + } + mask >>= 1; + dest++; +@@ -2293,6 +3206,12 @@ DISAS_INSN(fpu) + case 0x23: case 0x63: case 0x67: /* fmul */ + gen_op_mulf64(res, res, src); + break; ++ case 0x24: /* fsgldiv */ ++ gen_op_divf64(res, res, src); ++ break; ++ case 0x27: /* fsglmul */ ++ gen_op_mulf64(res, res, src); ++ break; + case 0x28: case 0x68: case 0x6c: /* fsub */ + gen_op_subf64(res, res, src); + break; +@@ -2759,85 +3678,158 @@ void register_m68k_insns (CPUM68KState * + register_opcode(disas_##name, 0x##opcode, 0x##mask); \ + } while(0) + INSN(undef, 0000, 0000, CF_ISA_A); ++ INSN(undef, 0000, 0000, M68000); + INSN(arith_im, 0080, fff8, CF_ISA_A); ++ INSN(arith_im, 0000, ff00, M68000); ++ INSN(undef, 00c0, ffc0, M68000); + INSN(bitrev, 00c0, fff8, CF_ISA_APLUSC); + INSN(bitop_reg, 0100, f1c0, CF_ISA_A); ++ INSN(bitop_reg, 0100, f1c0, M68000); + INSN(bitop_reg, 0140, f1c0, CF_ISA_A); ++ INSN(bitop_reg, 0140, f1c0, M68000); + INSN(bitop_reg, 0180, f1c0, CF_ISA_A); ++ INSN(bitop_reg, 0180, f1c0, M68000); + INSN(bitop_reg, 01c0, f1c0, CF_ISA_A); ++ INSN(bitop_reg, 01c0, f1c0, M68000); + INSN(arith_im, 0280, fff8, CF_ISA_A); ++ INSN(arith_im, 0200, ff00, M68000); ++ INSN(undef, 02c0, ffc0, M68000); + INSN(byterev, 02c0, fff8, CF_ISA_APLUSC); + INSN(arith_im, 0480, fff8, CF_ISA_A); ++ INSN(arith_im, 0400, ff00, M68000); ++ INSN(undef, 04c0, ffc0, M68000); + INSN(ff1, 04c0, fff8, CF_ISA_APLUSC); + INSN(arith_im, 0680, fff8, CF_ISA_A); ++ INSN(arith_im, 0600, ff00, M68000); ++ INSN(undef, 06c0, ffc0, M68000); ++ INSN(cas, 08c0, f8c0, M68020_60); ++ INSN(cas2, 0cfc, fdff, M68020_40); + INSN(bitop_im, 0800, ffc0, CF_ISA_A); ++ INSN(bitop_im, 0800, ffc0, M68000); + INSN(bitop_im, 0840, ffc0, CF_ISA_A); ++ INSN(bitop_im, 0840, ffc0, M68000); + INSN(bitop_im, 0880, ffc0, CF_ISA_A); ++ INSN(bitop_im, 0880, ffc0, M68000); + INSN(bitop_im, 08c0, ffc0, CF_ISA_A); ++ INSN(bitop_im, 08c0, ffc0, M68000); + INSN(arith_im, 0a80, fff8, CF_ISA_A); ++ INSN(arith_im, 0a00, ff00, M68000); ++ INSN(undef, 0ac0, ffc0, M68000); + INSN(arith_im, 0c00, ff38, CF_ISA_A); ++ INSN(arith_im, 0c00, ff00, M68000); ++ INSN(undef, 0cc0, ffc0, M68000); + INSN(move, 1000, f000, CF_ISA_A); ++ INSN(move, 1000, f000, M68000); + INSN(move, 2000, f000, CF_ISA_A); ++ INSN(move, 2000, f000, M68000); + INSN(move, 3000, f000, CF_ISA_A); ++ INSN(move, 3000, f000, M68000); + INSN(strldsr, 40e7, ffff, CF_ISA_APLUSC); + INSN(negx, 4080, fff8, CF_ISA_A); ++ INSN(negx, 4000, ff00, M68000); ++ INSN(undef, 40c0, ffc0, M68000); + INSN(move_from_sr, 40c0, fff8, CF_ISA_A); ++ INSN(move_from_sr, 40c0, fff8, M68000); + INSN(lea, 41c0, f1c0, CF_ISA_A); ++ INSN(lea, 41c0, f1c0, M68000); + INSN(clr, 4200, ff00, CF_ISA_A); ++ INSN(clr, 4200, ff00, M68000); + INSN(undef, 42c0, ffc0, CF_ISA_A); ++ INSN(undef, 42c0, ffc0, M68000); + INSN(move_from_ccr, 42c0, fff8, CF_ISA_A); + INSN(neg, 4480, fff8, CF_ISA_A); ++ INSN(neg, 4400, ff00, M68000); ++ INSN(undef, 44c0, ffc0, M68000); + INSN(move_to_ccr, 44c0, ffc0, CF_ISA_A); ++ INSN(move_to_ccr, 44c0, ffc0, M68000); + INSN(not, 4680, fff8, CF_ISA_A); ++ INSN(not, 4600, ff00, M68000); ++ INSN(undef, 46c0, ffc0, M68000); + INSN(move_to_sr, 46c0, ffc0, CF_ISA_A); ++ INSN(linkl, 4808, fff8, M68020_60); + INSN(pea, 4840, ffc0, CF_ISA_A); ++ INSN(pea, 4840, ffc0, M68000); + INSN(swap, 4840, fff8, CF_ISA_A); ++ INSN(swap, 4840, fff8, M68000); + INSN(movem, 48c0, fbc0, CF_ISA_A); ++ INSN(movem, 48c0, fbc0, M68000); + INSN(ext, 4880, fff8, CF_ISA_A); ++ INSN(ext, 4880, fff8, M68000); + INSN(ext, 48c0, fff8, CF_ISA_A); ++ INSN(ext, 48c0, fff8, M68000); + INSN(ext, 49c0, fff8, CF_ISA_A); ++ INSN(ext, 49c0, fff8, M68000); + INSN(tst, 4a00, ff00, CF_ISA_A); ++ INSN(tst, 4a00, ff00, M68000); + INSN(tas, 4ac0, ffc0, CF_ISA_B); ++ INSN(tas, 4ac0, ffc0, M68000); + INSN(halt, 4ac8, ffff, CF_ISA_A); + INSN(pulse, 4acc, ffff, CF_ISA_A); + INSN(illegal, 4afc, ffff, CF_ISA_A); ++ INSN(illegal, 4afc, ffff, M68000); + INSN(mull, 4c00, ffc0, CF_ISA_A); ++ INSN(mull, 4c00, ffc0, M68020_60); + INSN(divl, 4c40, ffc0, CF_ISA_A); ++ INSN(divl, 4c40, ffc0, M68020_60); + INSN(sats, 4c80, fff8, CF_ISA_B); + INSN(trap, 4e40, fff0, CF_ISA_A); ++ INSN(trap, 4e40, fff0, M68000); + INSN(link, 4e50, fff8, CF_ISA_A); ++ INSN(link, 4e50, fff8, M68000); + INSN(unlk, 4e58, fff8, CF_ISA_A); ++ INSN(unlk, 4e58, fff8, M68000); + INSN(move_to_usp, 4e60, fff8, USP); + INSN(move_from_usp, 4e68, fff8, USP); + INSN(nop, 4e71, ffff, CF_ISA_A); ++ INSN(nop, 4e71, ffff, M68000); + INSN(stop, 4e72, ffff, CF_ISA_A); ++ INSN(stop, 4e72, ffff, M68000); + INSN(rte, 4e73, ffff, CF_ISA_A); ++ INSN(rte, 4e73, ffff, M68000); + INSN(rts, 4e75, ffff, CF_ISA_A); ++ INSN(rts, 4e75, ffff, M68000); + INSN(movec, 4e7b, ffff, CF_ISA_A); + INSN(jump, 4e80, ffc0, CF_ISA_A); ++ INSN(jump, 4e80, ffc0, M68000); + INSN(jump, 4ec0, ffc0, CF_ISA_A); +- INSN(addsubq, 5180, f1c0, CF_ISA_A); ++ INSN(jump, 4ec0, ffc0, M68000); ++ INSN(addsubq, 5080, f0c0, CF_ISA_A); ++ INSN(addsubq, 5000, f080, M68000); ++ INSN(addsubq, 5080, f0c0, M68000); + INSN(scc, 50c0, f0f8, CF_ISA_A); +- INSN(addsubq, 5080, f1c0, CF_ISA_A); ++ INSN(scc_mem, 50c0, f0c0, M68000); ++ INSN(scc, 50c0, f0f8, M68000); ++ INSN(dbcc, 50c8, f0f8, M68000); + INSN(tpf, 51f8, fff8, CF_ISA_A); + + /* Branch instructions. */ + INSN(branch, 6000, f000, CF_ISA_A); ++ INSN(branch, 6000, f000, M68000); + /* Disable long branch instructions, then add back the ones we want. */ + INSN(undef, 60ff, f0ff, CF_ISA_A); /* All long branches. */ ++ INSN(undef, 60ff, f0ff, M68000); /* All long branches. */ + INSN(branch, 60ff, f0ff, CF_ISA_B); + INSN(undef, 60ff, ffff, CF_ISA_B); /* bra.l */ + INSN(branch, 60ff, ffff, BRAL); ++ INSN(branch, 60ff, f0ff, M68020_60); + + INSN(moveq, 7000, f100, CF_ISA_A); ++ INSN(moveq, 7000, f100, M68000); + INSN(mvzs, 7100, f100, CF_ISA_B); + INSN(or, 8000, f000, CF_ISA_A); ++ INSN(or, 8000, f000, M68000); + INSN(divw, 80c0, f0c0, CF_ISA_A); ++ INSN(divw, 80c0, f0c0, M68000); + INSN(addsub, 9000, f000, CF_ISA_A); ++ INSN(addsub, 9000, f000, M68000); ++ INSN(undef, 90c0, f0c0, CF_ISA_A); + INSN(subx, 9180, f1f8, CF_ISA_A); ++ INSN(subx, 9100, f138, M68000); + INSN(suba, 91c0, f1c0, CF_ISA_A); ++ INSN(suba, 90c0, f0c0, M68000); + + INSN(undef_mac, a000, f000, CF_ISA_A); ++ INSN(undef_mac, a000, f000, M68000); + INSN(mac, a000, f100, CF_EMAC); + INSN(from_mac, a180, f9b0, CF_EMAC); + INSN(move_mac, a110, f9fc, CF_EMAC); +@@ -2856,19 +3848,50 @@ void register_m68k_insns (CPUM68KState * + INSN(cmpa, b0c0, f1c0, CF_ISA_B); /* cmpa.w */ + INSN(cmp, b080, f1c0, CF_ISA_A); + INSN(cmpa, b1c0, f1c0, CF_ISA_A); ++ INSN(cmp, b000, f100, M68000); ++ INSN(cmpa, b0c0, f0c0, M68000); + INSN(eor, b180, f1c0, CF_ISA_A); ++ INSN(eor, b180, f1c0, M68000); + INSN(and, c000, f000, CF_ISA_A); ++ INSN(and, c000, f000, M68000); + INSN(mulw, c0c0, f0c0, CF_ISA_A); ++ INSN(mulw, c0c0, f0c0, M68000); + INSN(addsub, d000, f000, CF_ISA_A); ++ INSN(addsub, d000, f000, M68000); ++ INSN(undef, d0c0, f0c0, CF_ISA_A); + INSN(addx, d180, f1f8, CF_ISA_A); ++ INSN(addx, d100, f138, M68000); + INSN(adda, d1c0, f1c0, CF_ISA_A); ++ INSN(adda, d0c0, f0c0, M68000); + INSN(shift_im, e080, f0f0, CF_ISA_A); + INSN(shift_reg, e0a0, f0f0, CF_ISA_A); ++ INSN(shift_im, e080, f0f0, M68000); ++ INSN(shift8_im, e000, f0f0, M68000); ++ INSN(shift16_im, e040, f0f0, M68000); ++ INSN(shift_reg, e0a0, f0f0, M68000); ++ INSN(shift8_reg, e020, f0f0, M68000); ++ INSN(shift16_reg, e060, f0f0, M68000); ++ INSN(rotate_im, e090, f0f0, M68000); ++ INSN(rotate8_im, e010, f0f0, M68000); ++ INSN(rotate16_im, e050, f0f0, M68000); ++ INSN(rotate_reg, e0b0, f0f0, M68000); ++ INSN(rotate8_reg, e030, f0f0, M68000); ++ INSN(rotate16_reg,e070, f0f0, M68000); ++ INSN(shift_mem, e0c0, fcc0, M68000); ++ INSN(rotate_mem, e4c0, fcc0, M68000); ++ INSN(bitfield_mem,e8c0, f8c0, M68020_60); ++ INSN(bitfield_reg,e8c0, f8f8, M68020_60); ++ + INSN(undef_fpu, f000, f000, CF_ISA_A); ++ INSN(undef_fpu, f000, f000, M68000); + INSN(fpu, f200, ffc0, CF_FPU); + INSN(fbcc, f280, ffc0, CF_FPU); + INSN(frestore, f340, ffc0, CF_FPU); + INSN(fsave, f340, ffc0, CF_FPU); ++ INSN(fpu, f200, ffc0, FPU); ++ INSN(fbcc, f280, ffc0, FPU); ++ INSN(frestore, f340, ffc0, FPU); ++ INSN(fsave, f340, ffc0, FPU); + INSN(intouch, f340, ffc0, CF_ISA_A); + INSN(cpushl, f428, ff38, CF_ISA_A); + INSN(wddata, fb00, ff00, CF_ISA_A); diff --git a/qemu-z80.diff b/qemu-z80.diff index 39ed88c1..9b4e9194 100644 --- a/qemu-z80.diff +++ b/qemu-z80.diff @@ -1,19 +1,63 @@ -diff -urN qemu-0.9.0/configure qemu-z80/configure ---- qemu-0.9.0/configure 2007-02-05 23:01:54.000000000 +0000 -+++ qemu-z80/configure 2007-03-27 21:07:11.000000000 +0100 -@@ -415,7 +415,7 @@ +diff --exclude='*.orig' --exclude=CVS -ruN qemu/configure qemu-z80/configure +--- qemu/configure 2007-06-23 18:03:35.000000000 +0200 ++++ qemu-z80/configure 2007-07-06 13:07:47.000000000 +0200 +@@ -86,6 +86,7 @@ + dsound="no" + coreaudio="no" + alsa="no" ++libspectrum="no" + fmod="no" + fmod_lib="" + fmod_inc="" +@@ -245,6 +246,8 @@ + ;; + --fmod-inc=*) fmod_inc="$optarg" + ;; ++ --enable-libspectrum) libspectrum="yes" ++ ;; + --enable-mingw32) mingw32="yes" ; cross_prefix="i386-mingw32-" ; linux_user="no" + ;; + --disable-slirp) slirp="no" +@@ -355,6 +358,7 @@ + echo " --enable-alsa enable ALSA audio driver" + echo " --enable-fmod enable FMOD audio driver" + echo " --enable-dsound enable DirectSound audio driver" ++echo " --enable-libspectrum enable ZX Spectrum snapshot loading" + echo " --enable-system enable all system emulation targets" + echo " --disable-system disable all system emulation targets" + echo " --enable-linux-user enable all linux usermode emulation targets" +@@ -473,7 +477,7 @@ if test -z "$target_list" ; then # these targets are portable if [ "$softmmu" = "yes" ] ; then -- target_list="i386-softmmu ppc-softmmu sparc-softmmu x86_64-softmmu mips-softmmu mipsel-softmmu arm-softmmu" -+ target_list="i386-softmmu ppc-softmmu sparc-softmmu x86_64-softmmu mips-softmmu mipsel-softmmu arm-softmmu z80-softmmu" +- target_list="i386-softmmu ppc-softmmu sparc-softmmu x86_64-softmmu mips-softmmu mipsel-softmmu mips64-softmmu mips64el-softmmu arm-softmmu ppc64-softmmu ppcemb-softmmu m68k-softmmu" ++ target_list="i386-softmmu ppc-softmmu sparc-softmmu x86_64-softmmu mips-softmmu mipsel-softmmu mips64-softmmu mips64el-softmmu arm-softmmu ppc64-softmmu ppcemb-softmmu m68k-softmmu z80-softmmu" fi # the following are Linux specific if [ "$linux_user" = "yes" ] ; then -@@ -911,6 +911,11 @@ - echo "#define TARGET_ARCH \"m68k\"" >> $config_h - echo "#define TARGET_M68K 1" >> $config_h - bflt="yes" +@@ -680,6 +684,7 @@ + if test -n "$sparc_cpu"; then + echo "Target Sparc Arch $sparc_cpu" + fi ++echo "libspec. support $libspectrum" + echo "kqemu support $kqemu" + echo "Documentation $build_docs" + [ ! -z "$uname_release" ] && \ +@@ -841,6 +846,10 @@ + echo "CONFIG_FMOD_INC=$fmod_inc" >> $config_mak + echo "#define CONFIG_FMOD 1" >> $config_h + fi ++if test "$libspectrum" = "yes" ; then ++ echo "CONFIG_LIBSPECTRUM=yes" >> $config_mak ++ echo "#define CONFIG_LIBSPECTRUM 1" >> $config_h ++fi + qemu_version=`head $source_path/VERSION` + echo "VERSION=$qemu_version" >>$config_mak + echo "#define QEMU_VERSION \"$qemu_version\"" >> $config_h +@@ -1008,6 +1017,11 @@ + echo "TARGET_ARCH=alpha" >> $config_mak + echo "#define TARGET_ARCH \"alpha\"" >> $config_h + echo "#define TARGET_ALPHA 1" >> $config_h +elif test "$target_cpu" = "z80" ; then + echo "TARGET_ARCH=z80" >> $config_mak + echo "#define TARGET_ARCH \"z80\"" >> $config_h @@ -22,29 +66,12 @@ diff -urN qemu-0.9.0/configure qemu-z80/configure else echo "Unsupported target CPU" exit 1 -diff -urN qemu-0.9.0/cpu-all.h qemu-z80/cpu-all.h ---- qemu-0.9.0/cpu-all.h 2007-02-05 23:01:54.000000000 +0000 -+++ qemu-z80/cpu-all.h 2007-03-27 21:07:11.000000000 +0100 -@@ -746,6 +746,13 @@ - #define cpu_gen_code cpu_sh4_gen_code - #define cpu_signal_handler cpu_sh4_signal_handler - -+#elif defined(TARGET_Z80) -+#define CPUState CPUZ80State -+#define cpu_init cpu_z80_init -+#define cpu_exec cpu_z80_exec -+#define cpu_gen_code cpu_z80_gen_code -+#define cpu_signal_handler cpu_z80_signal_handler -+ - #else - - #error unsupported target CPU -diff -urN qemu-0.9.0/cpu-exec.c qemu-z80/cpu-exec.c ---- qemu-0.9.0/cpu-exec.c 2007-02-05 23:01:54.000000000 +0000 -+++ qemu-z80/cpu-exec.c 2007-04-17 21:14:13.000000000 +0100 -@@ -202,6 +202,10 @@ - flags = env->sr & (SR_MD | SR_RB); - cs_base = 0; /* XXXXX */ +diff --exclude='*.orig' --exclude=CVS -ruN qemu/cpu-exec.c qemu-z80/cpu-exec.c +--- qemu/cpu-exec.c 2007-06-03 20:52:15.000000000 +0200 ++++ qemu-z80/cpu-exec.c 2007-07-05 18:36:50.000000000 +0200 +@@ -209,6 +209,10 @@ + flags = env->ps; + cs_base = 0; pc = env->pc; +#elif defined(TARGET_Z80) + flags = env->hflags; @@ -53,7 +80,7 @@ diff -urN qemu-0.9.0/cpu-exec.c qemu-z80/cpu-exec.c #else #error unsupported CPU #endif -@@ -325,6 +329,12 @@ +@@ -284,6 +288,15 @@ #elif defined(TARGET_MIPS) #elif defined(TARGET_SH4) /* XXXXX */ @@ -63,13 +90,16 @@ diff -urN qemu-0.9.0/cpu-exec.c qemu-z80/cpu-exec.c + CC_SRC = env->eflags & (CC_S | CC_Z | CC_P | CC_C); + CC_OP = CC_OP_EFLAGS; + env->eflags &= ~(CC_S | CC_Z | CC_P | CC_C); ++#elif defined(TARGET_Z80) ++ /* restore flags in standard format */ ++// env->eflags = env->eflags | cc_table[CC_OP].compute_all(); #else #error unsupported target CPU #endif -@@ -525,6 +535,13 @@ +@@ -500,6 +513,13 @@ + env->exception_index = env->pending_vector; + do_interrupt(1); } - #elif defined(TARGET_SH4) - /* XXXXX */ +#elif defined(TARGET_Z80) + if (interrupt_request & CPU_INTERRUPT_HARD) { + env->interrupt_request &= ~CPU_INTERRUPT_HARD; @@ -80,18 +110,18 @@ diff -urN qemu-0.9.0/cpu-exec.c qemu-z80/cpu-exec.c #endif /* Don't use the cached interupt_request value, do_interrupt may have updated the EXITTB flag. */ -@@ -593,6 +610,8 @@ - cpu_dump_state(env, logfile, fprintf, 0); - #elif defined(TARGET_SH4) +@@ -547,6 +567,8 @@ cpu_dump_state(env, logfile, fprintf, 0); + #elif defined(TARGET_ALPHA) + cpu_dump_state(env, logfile, fprintf, 0); +#elif defined(TARGET_Z80) -+ cpu_dump_state(env, logfile, fprintf, 0); ++ cpu_dump_state(env, logfile, fprintf, 0); #else #error unsupported target CPU #endif -@@ -785,6 +804,9 @@ - #elif defined(TARGET_MIPS) +@@ -741,6 +763,9 @@ #elif defined(TARGET_SH4) + #elif defined(TARGET_ALPHA) /* XXXXX */ +#elif defined(TARGET_Z80) + /* restore flags in standard format */ @@ -99,32 +129,32 @@ diff -urN qemu-0.9.0/cpu-exec.c qemu-z80/cpu-exec.c #else #error unsupported target CPU #endif -diff -urN qemu-0.9.0/disas.c qemu-z80/disas.c ---- qemu-0.9.0/disas.c 2007-02-05 23:01:54.000000000 +0000 -+++ qemu-z80/disas.c 2007-03-27 21:07:11.000000000 +0100 -@@ -197,6 +197,8 @@ - #elif defined(TARGET_SH4) - disasm_info.mach = bfd_mach_sh4; - print_insn = print_insn_sh; +diff --exclude='*.orig' --exclude=CVS -ruN qemu/disas.c qemu-z80/disas.c +--- qemu/disas.c 2007-06-03 21:16:42.000000000 +0200 ++++ qemu-z80/disas.c 2007-07-05 18:03:59.000000000 +0200 +@@ -200,6 +200,8 @@ + #elif defined(TARGET_ALPHA) + disasm_info.mach = bfd_mach_alpha; + print_insn = print_insn_alpha; +#elif defined(TARGET_Z80) + print_insn = print_insn_z80; #else fprintf(out, "0x" TARGET_FMT_lx ": Asm output not supported on this arch\n", code); -diff -urN qemu-0.9.0/dis-asm.h qemu-z80/dis-asm.h ---- qemu-0.9.0/dis-asm.h 2007-02-05 23:01:54.000000000 +0000 -+++ qemu-z80/dis-asm.h 2007-03-27 21:07:11.000000000 +0100 -@@ -377,6 +377,7 @@ - extern int print_insn_v850 PARAMS ((bfd_vma, disassemble_info*)); +diff --exclude='*.orig' --exclude=CVS -ruN qemu/dis-asm.h qemu-z80/dis-asm.h +--- qemu/dis-asm.h 2007-04-05 09:22:49.000000000 +0200 ++++ qemu-z80/dis-asm.h 2007-07-05 18:05:17.000000000 +0200 +@@ -379,6 +379,7 @@ extern int print_insn_tic30 PARAMS ((bfd_vma, disassemble_info*)); extern int print_insn_ppc PARAMS ((bfd_vma, disassemble_info*)); + extern int print_insn_alpha PARAMS ((bfd_vma, disassemble_info*)); +extern int print_insn_z80 PARAMS ((bfd_vma, disassemble_info*)); #if 0 /* Fetch the disassembler for a given BFD, if that support is available. */ -diff -urN qemu-0.9.0/exec-all.h qemu-z80/exec-all.h ---- qemu-0.9.0/exec-all.h 2007-02-05 23:01:54.000000000 +0000 -+++ qemu-z80/exec-all.h 2007-04-17 21:26:41.000000000 +0100 +diff --exclude='*.orig' --exclude=CVS -ruN qemu/exec-all.h qemu-z80/exec-all.h +--- qemu/exec-all.h 2007-07-02 16:06:26.000000000 +0200 ++++ qemu-z80/exec-all.h 2007-07-05 18:04:44.000000000 +0200 @@ -69,7 +69,7 @@ typedef void (GenOpFunc2)(long, long); typedef void (GenOpFunc3)(long, long, long); @@ -134,19 +164,19 @@ diff -urN qemu-0.9.0/exec-all.h qemu-z80/exec-all.h void optimize_flags_init(void); -@@ -572,6 +572,8 @@ - is_user = ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR); - #elif defined (TARGET_SH4) - is_user = ((env->sr & SR_MD) == 0); +@@ -586,6 +586,8 @@ + is_user = ((env->ps >> 3) & 3); + #elif defined (TARGET_M68K) + is_user = ((env->sr & SR_S) == 0); +#elif defined (TARGET_Z80) + is_user = 0; /* no user-mode */ #else #error unimplemented CPU #endif -diff -urN qemu-0.9.0/exec.c qemu-z80/exec.c ---- qemu-0.9.0/exec.c 2007-02-05 23:01:54.000000000 +0000 -+++ qemu-z80/exec.c 2007-04-15 22:54:52.000000000 +0100 -@@ -679,6 +679,9 @@ +diff --exclude='*.orig' --exclude=CVS -ruN qemu/exec.c qemu-z80/exec.c +--- qemu/exec.c 2007-07-01 20:21:11.000000000 +0200 ++++ qemu-z80/exec.c 2007-07-06 12:04:38.000000000 +0200 +@@ -709,6 +709,9 @@ current_flags |= (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK)); current_cs_base = (target_ulong)env->segs[R_CS].base; current_pc = current_cs_base + env->eip; @@ -156,12 +186,12 @@ diff -urN qemu-0.9.0/exec.c qemu-z80/exec.c #else #error unsupported CPU #endif -diff -urN qemu-0.9.0/gdbstub.c qemu-z80/gdbstub.c ---- qemu-0.9.0/gdbstub.c 2007-02-05 23:01:54.000000000 +0000 -+++ qemu-z80/gdbstub.c 2007-04-04 21:35:14.000000000 +0100 -@@ -700,6 +700,34 @@ - LOAD (env->macl); - LOAD (env->sr); +diff --exclude='*.orig' --exclude=CVS -ruN qemu/gdbstub.c qemu-z80/gdbstub.c +--- qemu/gdbstub.c 2007-06-03 19:08:32.000000000 +0200 ++++ qemu-z80/gdbstub.c 2007-07-05 18:03:12.000000000 +0200 +@@ -718,6 +718,34 @@ + for (i = 0; i < 8; i++) LOAD(env->gregs[i]); + for (i = 0; i < 8; i++) LOAD(env->gregs[i + 16]); } +#elif defined(TARGET_Z80) +/* Z80 FIXME Z80 TODO Z80 */ @@ -194,10 +224,10 @@ diff -urN qemu-0.9.0/gdbstub.c qemu-z80/gdbstub.c #else static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) { -diff -urN qemu-0.9.0/hw/zx_spectrum.c qemu-z80/hw/zx_spectrum.c ---- qemu-0.9.0/hw/zx_spectrum.c 1970-01-01 01:00:00.000000000 +0100 -+++ qemu-z80/hw/zx_spectrum.c 2007-04-17 20:27:16.000000000 +0100 -@@ -0,0 +1,236 @@ +diff --exclude='*.orig' --exclude=CVS -ruN qemu/hw/zx_spectrum.c qemu-z80/hw/zx_spectrum.c +--- qemu/hw/zx_spectrum.c 1970-01-01 01:00:00.000000000 +0100 ++++ qemu-z80/hw/zx_spectrum.c 2007-07-06 13:17:46.000000000 +0200 +@@ -0,0 +1,303 @@ +/* + * QEMU ZX Spectrum Emulator + * @@ -223,6 +253,9 @@ diff -urN qemu-0.9.0/hw/zx_spectrum.c qemu-z80/hw/zx_spectrum.c + * THE SOFTWARE. + */ +#include "vl.h" ++#ifdef CONFIG_LIBSPECTRUM ++#include ++#endif + +/* output Bochs bios info messages */ +//#define DEBUG_BIOS @@ -259,12 +292,14 @@ diff -urN qemu-0.9.0/hw/zx_spectrum.c qemu-z80/hw/zx_spectrum.c + return io_keyboard_read(opaque, addr); +} + ++#if 0 +/* MSDOS compatibility mode FPU exception support */ +/* XXX: add IGNNE support */ +void cpu_set_ferr(CPUZ80State *s) +{ + pic_set_irq(13, 1); +} ++#endif + +/* TSC handling */ +uint64_t cpu_get_tsc(CPUZ80State *env) @@ -380,7 +415,7 @@ diff -urN qemu-0.9.0/hw/zx_spectrum.c qemu-z80/hw/zx_spectrum.c + register_savevm("cpu", 0, 4, cpu_save, cpu_load, env); + qemu_register_reset(main_cpu_reset, env); + -+ cpu_register_physical_memory(0, 0x10000, 0); ++ cpu_register_physical_memory(0x4000, 0x10000 - 0x4000, 0 | IO_MEM_RAM); + + /* allocate RAM */ +// ram_addr = qemu_ram_alloc(0x10000 - 0x5b00); @@ -412,8 +447,70 @@ diff -urN qemu-0.9.0/hw/zx_spectrum.c qemu-z80/hw/zx_spectrum.c + register_ioport_read(0, 0x10000, 1, io_spectrum_read, NULL); + + zx_ula_init(ds, phys_ram_base + ram_size, ram_size); ++ + zx_keyboard_init(); + zx_timer_init(ds); ++ ++#ifdef CONFIG_LIBSPECTRUM ++ if(kernel_filename) { ++ libspectrum_id_t type; ++ libspectrum_class_t cls; ++ libspectrum_snap* snap; ++ uint8_t* snapmem; ++ libspectrum_byte* page; ++ int length; ++ int i; ++ if(libspectrum_init() != LIBSPECTRUM_ERROR_NONE || ++ libspectrum_identify_file(&type, kernel_filename, NULL, 0) != LIBSPECTRUM_ERROR_NONE || ++ libspectrum_identify_class(&cls, type) != LIBSPECTRUM_ERROR_NONE || ++ libspectrum_snap_alloc(&snap) != LIBSPECTRUM_ERROR_NONE) { ++ fprintf(stderr, "%s: libspectrum error\n", __FUNCTION__); ++ exit(1); ++ } ++ if(cls != LIBSPECTRUM_CLASS_SNAPSHOT) { ++ fprintf(stderr, "%s: %s is not a snapshot\n", __FUNCTION__, kernel_filename); ++ exit(1); ++ } ++ snapmem = malloc(65536); ++ length = load_image(kernel_filename, snapmem); ++ //printf("loaded %d bytes from %s\n",length, kernel_filename); ++ if(libspectrum_snap_read(snap, snapmem, length, type, NULL) != LIBSPECTRUM_ERROR_NONE) { ++ fprintf(stderr, "%s: failed to load snapshot %s\n", __FUNCTION__, kernel_filename); ++ exit(1); ++ } ++ //printf("snap pc = %d\n",libspectrum_snap_pc(snap)); ++ page = libspectrum_snap_pages(snap, 5); ++ for(i = 0x4000; i < 0x8000; i++) { ++ //printf("storing 0x%x in 0x%x\n",page[i-0x4000],i); ++ stb_phys(i, page[i - 0x4000]); ++ } ++ page = libspectrum_snap_pages(snap, 2); ++ for(i = 0x8000; i < 0xc000; i++) ++ stb_phys(i, page[i - 0x8000]); ++ page = libspectrum_snap_pages(snap, 0); ++ for(i = 0xc000; i < 0x10000; i++) ++ stb_phys(i, page[i - 0xc000]); ++ env->regs[R_A] = libspectrum_snap_a(snap); ++ env->regs[R_F] = libspectrum_snap_f(snap); ++ env->regs[R_BC] = libspectrum_snap_bc(snap); ++ env->regs[R_DE] = libspectrum_snap_de(snap); ++ env->regs[R_HL] = libspectrum_snap_hl(snap); ++ env->regs[R_AFX] = libspectrum_snap_a_(snap) << 8 | libspectrum_snap_f_(snap); ++ env->regs[R_BCX] = libspectrum_snap_bc_(snap); ++ env->regs[R_DEX] = libspectrum_snap_de_(snap); ++ env->regs[R_HLX] = libspectrum_snap_hl_(snap); ++ env->regs[R_IX] = libspectrum_snap_ix(snap); ++ env->regs[R_IY] = libspectrum_snap_iy(snap); ++ env->regs[R_I] = libspectrum_snap_i(snap); ++ env->regs[R_R] = libspectrum_snap_r(snap); ++ env->regs[R_SP] = libspectrum_snap_sp(snap); ++ env->pc = libspectrum_snap_pc(snap); ++ env->iff1 = libspectrum_snap_iff1(snap); ++ env->iff2 = libspectrum_snap_iff2(snap); ++ env->imode = libspectrum_snap_im(snap); ++ ++ } ++#endif +} + +static void zx_spectrum_init(int ram_size, int vga_ram_size, int boot_device, @@ -434,9 +531,9 @@ diff -urN qemu-0.9.0/hw/zx_spectrum.c qemu-z80/hw/zx_spectrum.c + "Z80 Machine", + zx_spectrum_init, +}; -diff -urN qemu-0.9.0/hw/zx_ula.c qemu-z80/hw/zx_ula.c ---- qemu-0.9.0/hw/zx_ula.c 1970-01-01 01:00:00.000000000 +0100 -+++ qemu-z80/hw/zx_ula.c 2007-04-17 20:55:28.000000000 +0100 +diff --exclude='*.orig' --exclude=CVS -ruN qemu/hw/zx_ula.c qemu-z80/hw/zx_ula.c +--- qemu/hw/zx_ula.c 1970-01-01 01:00:00.000000000 +0100 ++++ qemu-z80/hw/zx_ula.c 2007-07-06 13:01:14.000000000 +0200 @@ -0,0 +1,355 @@ +/* + * QEMU ZX Spectrum Video Emulation. @@ -652,8 +749,8 @@ diff -urN qemu-0.9.0/hw/zx_ula.c qemu-z80/hw/zx_ula.c + ZXVState *s = (ZXVState *)opaque; + uint32_t addr, attrib; + -+ if (!s->dirty) -+ return; ++ //if (!s->dirty) ++ // return; + + d = s->ds->data; + d += s->bheight * s->ds->linesize; @@ -783,43 +880,46 @@ diff -urN qemu-0.9.0/hw/zx_ula.c qemu-z80/hw/zx_ula.c + s->border = 0; + dpy_resize(s->ds, s->twidth, s->theight); + -+ zx_io_memory = cpu_register_io_memory(0, zx_mem_read, zx_mem_write, s); -+ cpu_register_physical_memory(0x4000, 0x1b00, zx_io_memory); ++ //zx_io_memory = cpu_register_io_memory(0, zx_mem_read, zx_mem_write, s); ++ //cpu_register_physical_memory(0x4000, 0x2000, zx_io_memory); +// cpu_register_physical_memory(0x4000, 0x2000, zx_io_memory); +// cpu_register_physical_memory(0x4000, 0xc000, zx_io_memory); -+ s->vram_ptr = phys_ram_base + zx_io_memory; -+ s->vram_offset = zx_io_memory; ++ s->vram_ptr = phys_ram_base + 0;//x4000;//zx_io_memory; ++ s->vram_offset = 0;//x4000;//zx_io_memory; + + /* ZX Spectrum ULA */ + register_ioport_write(0, 0x10000, 1, io_spectrum_write, s); +} -diff -urN qemu-0.9.0/Makefile qemu-z80/Makefile ---- qemu-0.9.0/Makefile 2007-02-05 23:01:54.000000000 +0000 -+++ qemu-z80/Makefile 2007-03-27 21:07:11.000000000 +0100 -@@ -79,7 +79,7 @@ +diff --exclude='*.orig' --exclude=CVS -ruN qemu/Makefile qemu-z80/Makefile +--- qemu/Makefile 2007-06-17 18:41:04.000000000 +0200 ++++ qemu-z80/Makefile 2007-07-05 18:07:36.000000000 +0200 +@@ -72,7 +72,7 @@ mkdir -p "$(DESTDIR)$(datadir)" for x in bios.bin vgabios.bin vgabios-cirrus.bin ppc_rom.bin \ - video.x openbios-sparc32 linux_boot.bin pxe-ne2k_pci.bin \ + video.x openbios-sparc32 pxe-ne2k_pci.bin \ - pxe-rtl8139.bin pxe-pcnet.bin; do \ + pxe-rtl8139.bin pxe-pcnet.bin zx-rom.bin ; do \ $(INSTALL) -m 644 $(SRC_PATH)/pc-bios/$$x "$(DESTDIR)$(datadir)"; \ done ifndef CONFIG_WIN32 -diff -urN qemu-0.9.0/Makefile.target qemu-z80/Makefile.target ---- qemu-0.9.0/Makefile.target 2007-02-05 23:01:54.000000000 +0000 -+++ qemu-z80/Makefile.target 2007-04-15 19:35:13.000000000 +0100 -@@ -271,6 +271,10 @@ - LIBOBJS+= helper.o +diff --exclude='*.orig' --exclude=CVS -ruN qemu/Makefile.target qemu-z80/Makefile.target +--- qemu/Makefile.target 2007-06-30 19:32:17.000000000 +0200 ++++ qemu-z80/Makefile.target 2007-07-06 14:59:02.000000000 +0200 +@@ -315,6 +315,13 @@ + LIBOBJS+= op_helper.o helper.o alpha_palcode.o endif +ifeq ($(TARGET_BASE_ARCH), z80) +LIBOBJS+=helper.o helper2.o ++ifdef CONFIG_LIBSPECTRUM ++LIBS+=-lspectrum ++endif +endif + # NOTE: the disassembler code is only needed for debugging LIBOBJS+=disas.o ifeq ($(findstring i386, $(TARGET_ARCH) $(ARCH)),i386) -@@ -303,6 +307,9 @@ +@@ -347,6 +354,9 @@ ifeq ($(findstring sh4, $(TARGET_ARCH) $(ARCH)),sh4) LIBOBJS+=sh4-dis.o endif @@ -829,9 +929,9 @@ diff -urN qemu-0.9.0/Makefile.target qemu-z80/Makefile.target ifdef CONFIG_GDBSTUB OBJS+=gdbstub.o -@@ -407,6 +414,10 @@ - ifeq ($(TARGET_BASE_ARCH), sh4) - VL_OBJS+= shix.o sh7750.o sh7750_regnames.o tc58128.o +@@ -472,6 +482,10 @@ + VL_OBJS+= an5206.o mcf5206.o ptimer.o mcf_uart.o mcf_intc.o mcf5208.o mcf_fec.o + VL_OBJS+= m68k-semi.o endif +ifeq ($(TARGET_BASE_ARCH), z80) +VL_OBJS+= zx_spectrum.o zx_ula.o dma.o $(AUDIODRV) @@ -840,7 +940,7 @@ diff -urN qemu-0.9.0/Makefile.target qemu-z80/Makefile.target ifdef CONFIG_GDBSTUB VL_OBJS+=gdbstub.o endif -@@ -514,9 +525,15 @@ +@@ -582,9 +596,15 @@ helper.o: helper.c $(CC) $(HELPER_CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -c -o $@ $< else @@ -856,7 +956,7 @@ diff -urN qemu-0.9.0/Makefile.target qemu-z80/Makefile.target cpu-exec.o: cpu-exec.c $(CC) $(HELPER_CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -c -o $@ $< -@@ -529,6 +546,9 @@ +@@ -601,6 +621,9 @@ ifeq ($(TARGET_BASE_ARCH), i386) op.o: op.c opreg_template.h ops_template.h ops_template_mem.h ops_mem.h ops_sse.h endif @@ -866,32 +966,32 @@ diff -urN qemu-0.9.0/Makefile.target qemu-z80/Makefile.target ifeq ($(TARGET_ARCH), arm) op.o: op.c op_template.h -Binary files qemu-0.9.0/pc-bios/zx-rom.bin and qemu-z80/pc-bios/zx-rom.bin differ -diff -urN qemu-0.9.0/softmmu_header.h qemu-z80/softmmu_header.h ---- qemu-0.9.0/softmmu_header.h 2007-02-05 23:01:54.000000000 +0000 -+++ qemu-z80/softmmu_header.h 2007-03-27 21:07:11.000000000 +0100 -@@ -63,6 +63,8 @@ - #define CPU_MEM_INDEX ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR) - #elif defined (TARGET_SH4) - #define CPU_MEM_INDEX ((env->sr & SR_MD) == 0) +Files qemu/school.z80 and qemu-z80/school.z80 differ +diff --exclude='*.orig' --exclude=CVS -ruN qemu/softmmu_header.h qemu-z80/softmmu_header.h +--- qemu/softmmu_header.h 2007-05-23 21:58:10.000000000 +0200 ++++ qemu-z80/softmmu_header.h 2007-07-05 18:11:08.000000000 +0200 +@@ -67,6 +67,8 @@ + #define CPU_MEM_INDEX ((env->ps >> 3) & 3) + #elif defined (TARGET_M68K) + #define CPU_MEM_INDEX ((env->sr & SR_S) == 0) +#elif defined (TARGET_Z80) +#define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3) #else #error unsupported CPU #endif -@@ -82,6 +84,8 @@ - #define CPU_MEM_INDEX ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR) - #elif defined (TARGET_SH4) - #define CPU_MEM_INDEX ((env->sr & SR_MD) == 0) +@@ -90,6 +92,8 @@ + #define CPU_MEM_INDEX ((env->ps >> 3) & 3) + #elif defined (TARGET_M68K) + #define CPU_MEM_INDEX ((env->sr & SR_S) == 0) +#elif defined (TARGET_Z80) +#define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3) #else #error unsupported CPU #endif -diff -urN qemu-0.9.0/target-z80/cpu.h qemu-z80/target-z80/cpu.h ---- qemu-0.9.0/target-z80/cpu.h 1970-01-01 01:00:00.000000000 +0100 -+++ qemu-z80/target-z80/cpu.h 2007-04-17 21:05:57.000000000 +0100 -@@ -0,0 +1,235 @@ +diff --exclude='*.orig' --exclude=CVS -ruN qemu/target-z80/cpu.h qemu-z80/target-z80/cpu.h +--- qemu/target-z80/cpu.h 1970-01-01 01:00:00.000000000 +0100 ++++ qemu-z80/target-z80/cpu.h 2007-07-06 11:59:06.000000000 +0200 +@@ -0,0 +1,243 @@ +/* + * Z80 virtual CPU header + * @@ -1083,6 +1183,7 @@ diff -urN qemu-0.9.0/target-z80/cpu.h qemu-z80/target-z80/cpu.h + uint32_t smbase; + int interrupt_request; + int user_mode_only; /* user mode only simulation */ ++ int halted; + + CPU_COMMON + @@ -1124,13 +1225,20 @@ diff -urN qemu-0.9.0/target-z80/cpu.h qemu-z80/target-z80/cpu.h +void cpu_smm_update(CPUZ80State *env); + +#define TARGET_PAGE_BITS 12 ++ ++#define CPUState CPUZ80State ++#define cpu_init cpu_z80_init ++#define cpu_exec cpu_z80_exec ++#define cpu_gen_code cpu_z80_gen_code ++#define cpu_signal_handler cpu_z80_signal_handler ++ +#include "cpu-all.h" + +#endif /* CPU_Z80_H */ -diff -urN qemu-0.9.0/target-z80/exec.h qemu-z80/target-z80/exec.h ---- qemu-0.9.0/target-z80/exec.h 1970-01-01 01:00:00.000000000 +0100 -+++ qemu-z80/target-z80/exec.h 2007-04-17 21:02:26.000000000 +0100 -@@ -0,0 +1,361 @@ +diff --exclude='*.orig' --exclude=CVS -ruN qemu/target-z80/exec.h qemu-z80/target-z80/exec.h +--- qemu/target-z80/exec.h 1970-01-01 01:00:00.000000000 +0100 ++++ qemu-z80/target-z80/exec.h 2007-07-05 18:30:59.000000000 +0200 +@@ -0,0 +1,372 @@ +/* + * Z80 execution defines + * @@ -1492,9 +1600,20 @@ diff -urN qemu-0.9.0/target-z80/exec.h qemu-z80/target-z80/exec.h + env->regs[R_HLX] = HLX; +#endif +} -diff -urN qemu-0.9.0/target-z80/helper2.c qemu-z80/target-z80/helper2.c ---- qemu-0.9.0/target-z80/helper2.c 1970-01-01 01:00:00.000000000 +0100 -+++ qemu-z80/target-z80/helper2.c 2007-04-17 21:29:49.000000000 +0100 ++ ++static inline int cpu_halted(CPUState* env) { ++ if (!env->halted) ++ return 0; ++ if (env->interrupt_request & CPU_INTERRUPT_HARD) { ++ env->halted = 0; ++ env->hflags &= ~HF_HALTED_MASK; ++ return 0; ++ } ++ return EXCP_HALTED; ++} +diff --exclude='*.orig' --exclude=CVS -ruN qemu/target-z80/helper2.c qemu-z80/target-z80/helper2.c +--- qemu/target-z80/helper2.c 1970-01-01 01:00:00.000000000 +0100 ++++ qemu-z80/target-z80/helper2.c 2007-07-05 18:37:36.000000000 +0200 @@ -0,0 +1,170 @@ +/* + * Z80 helpers (without register variable usage) @@ -1655,7 +1774,7 @@ diff -urN qemu-0.9.0/target-z80/helper2.c qemu-z80/target-z80/helper2.c + return ret; +} + -+target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr) ++target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) +{ + uint32_t pte, paddr, page_offset, page_size; + @@ -1666,10 +1785,10 @@ diff -urN qemu-0.9.0/target-z80/helper2.c qemu-z80/target-z80/helper2.c + paddr = (pte & TARGET_PAGE_MASK) + page_offset; + return paddr; +} -diff -urN qemu-0.9.0/target-z80/helper.c qemu-z80/target-z80/helper.c ---- qemu-0.9.0/target-z80/helper.c 1970-01-01 01:00:00.000000000 +0100 -+++ qemu-z80/target-z80/helper.c 2007-04-25 17:54:06.000000000 +0100 -@@ -0,0 +1,283 @@ +diff --exclude='*.orig' --exclude=CVS -ruN qemu/target-z80/helper.c qemu-z80/target-z80/helper.c +--- qemu/target-z80/helper.c 1970-01-01 01:00:00.000000000 +0100 ++++ qemu-z80/target-z80/helper.c 2007-07-05 18:38:49.000000000 +0200 +@@ -0,0 +1,276 @@ +/* + * Z80 helpers + * @@ -1760,14 +1879,6 @@ diff -urN qemu-0.9.0/target-z80/helper.c qemu-z80/target-z80/helper.c + spin_unlock(&global_cpu_lock); +} + -+void cpu_loop_exit(void) -+{ -+ /* NOTE: the register at this point must be saved by hand because -+ longjmp restore them */ -+ regs_to_env(); -+ longjmp(env->jmp_env, 1); -+} -+ +void do_interrupt(CPUZ80State *env) +{ +// printf("z80: do_interrupt()\n"); @@ -1849,6 +1960,7 @@ diff -urN qemu-0.9.0/target-z80/helper.c qemu-z80/target-z80/helper.c + +void helper_hlt(void) +{ ++ env->halted = 1; + env->hflags &= ~HF_INHIBIT_IRQ_MASK; /* needed if sti is just before */ + env->hflags |= HF_HALTED_MASK; + env->exception_index = EXCP_HLT; @@ -1953,9 +2065,9 @@ diff -urN qemu-0.9.0/target-z80/helper.c qemu-z80/target-z80/helper.c + fl & 0x01 ? 'C' : '-', + env->imode, env->iff1, env->iff2, env->regs[R_I], env->regs[R_R]); +} -diff -urN qemu-0.9.0/target-z80/op.c qemu-z80/target-z80/op.c ---- qemu-0.9.0/target-z80/op.c 1970-01-01 01:00:00.000000000 +0100 -+++ qemu-z80/target-z80/op.c 2007-04-25 17:41:33.000000000 +0100 +diff --exclude='*.orig' --exclude=CVS -ruN qemu/target-z80/op.c qemu-z80/target-z80/op.c +--- qemu/target-z80/op.c 1970-01-01 01:00:00.000000000 +0100 ++++ qemu-z80/target-z80/op.c 2007-07-05 18:03:12.000000000 +0200 @@ -0,0 +1,1175 @@ +/* + * Z80 micro operations @@ -3132,9 +3244,9 @@ diff -urN qemu-0.9.0/target-z80/op.c qemu-z80/target-z80/op.c +{ + cpu_unlock(); +} -diff -urN qemu-0.9.0/target-z80/opreg_template2.h qemu-z80/target-z80/opreg_template2.h ---- qemu-0.9.0/target-z80/opreg_template2.h 1970-01-01 01:00:00.000000000 +0100 -+++ qemu-z80/target-z80/opreg_template2.h 2007-03-27 21:42:55.000000000 +0100 +diff --exclude='*.orig' --exclude=CVS -ruN qemu/target-z80/opreg_template2.h qemu-z80/target-z80/opreg_template2.h +--- qemu/target-z80/opreg_template2.h 1970-01-01 01:00:00.000000000 +0100 ++++ qemu-z80/target-z80/opreg_template2.h 2007-07-05 18:03:12.000000000 +0200 @@ -0,0 +1,63 @@ +/* + * Z80 micro operations (templates for various register related @@ -3199,9 +3311,9 @@ diff -urN qemu-0.9.0/target-z80/opreg_template2.h qemu-z80/target-z80/opreg_temp + REGHIGH = (uint16_t)(T1 >> 8); + REGLOW = (uint16_t)T1; +} -diff -urN qemu-0.9.0/target-z80/opreg_template.h qemu-z80/target-z80/opreg_template.h ---- qemu-0.9.0/target-z80/opreg_template.h 1970-01-01 01:00:00.000000000 +0100 -+++ qemu-z80/target-z80/opreg_template.h 2007-03-27 21:43:07.000000000 +0100 +diff --exclude='*.orig' --exclude=CVS -ruN qemu/target-z80/opreg_template.h qemu-z80/target-z80/opreg_template.h +--- qemu/target-z80/opreg_template.h 1970-01-01 01:00:00.000000000 +0100 ++++ qemu-z80/target-z80/opreg_template.h 2007-07-05 18:03:12.000000000 +0200 @@ -0,0 +1,74 @@ +/* + * Z80 micro operations (templates for various register related @@ -3277,9 +3389,9 @@ diff -urN qemu-0.9.0/target-z80/opreg_template.h qemu-z80/target-z80/opreg_templ +{ + REG = (uint16_t)T1; +} -diff -urN qemu-0.9.0/target-z80/ops_mem.h qemu-z80/target-z80/ops_mem.h ---- qemu-0.9.0/target-z80/ops_mem.h 1970-01-01 01:00:00.000000000 +0100 -+++ qemu-z80/target-z80/ops_mem.h 2007-04-15 19:39:49.000000000 +0100 +diff --exclude='*.orig' --exclude=CVS -ruN qemu/target-z80/ops_mem.h qemu-z80/target-z80/ops_mem.h +--- qemu/target-z80/ops_mem.h 1970-01-01 01:00:00.000000000 +0100 ++++ qemu-z80/target-z80/ops_mem.h 2007-07-05 18:03:12.000000000 +0200 @@ -0,0 +1,59 @@ +void OPPROTO glue(glue(op_ldub, MEMSUFFIX), _T0_A0)(void) +{ @@ -3340,9 +3452,9 @@ diff -urN qemu-0.9.0/target-z80/ops_mem.h qemu-z80/target-z80/ops_mem.h +} + +#undef MEMSUFFIX -diff -urN qemu-0.9.0/target-z80/translate.c qemu-z80/target-z80/translate.c ---- qemu-0.9.0/target-z80/translate.c 1970-01-01 01:00:00.000000000 +0100 -+++ qemu-z80/target-z80/translate.c 2007-04-25 17:54:16.000000000 +0100 +diff --exclude='*.orig' --exclude=CVS -ruN qemu/target-z80/translate.c qemu-z80/target-z80/translate.c +--- qemu/target-z80/translate.c 1970-01-01 01:00:00.000000000 +0100 ++++ qemu-z80/target-z80/translate.c 2007-07-05 18:03:12.000000000 +0200 @@ -0,0 +1,1600 @@ +/* + * Z80 translation @@ -4944,10 +5056,10 @@ diff -urN qemu-0.9.0/target-z80/translate.c qemu-z80/target-z80/translate.c + return gen_intermediate_code_internal(env, tb, 1); +} + -diff -urN qemu-0.9.0/vl.c qemu-z80/vl.c ---- qemu-0.9.0/vl.c 2007-02-05 23:01:54.000000000 +0000 -+++ qemu-z80/vl.c 2007-04-25 17:58:06.000000000 +0100 -@@ -5201,6 +5201,7 @@ +diff --exclude='*.orig' --exclude=CVS -ruN qemu/vl.c qemu-z80/vl.c +--- qemu/vl.c 2007-07-02 17:03:13.000000000 +0200 ++++ qemu-z80/vl.c 2007-07-05 18:09:48.000000000 +0200 +@@ -5595,6 +5595,7 @@ qemu_get_be64s(f, &env->fmask); qemu_get_be64s(f, &env->kernelgsbase); #endif @@ -4955,7 +5067,7 @@ diff -urN qemu-0.9.0/vl.c qemu-z80/vl.c if (version_id >= 4) qemu_get_be32s(f, &env->smbase); -@@ -5319,6 +5320,19 @@ +@@ -5846,6 +5847,19 @@ return 0; } @@ -4975,21 +5087,21 @@ diff -urN qemu-0.9.0/vl.c qemu-z80/vl.c #else #warning No CPU save/restore functions -@@ -6368,6 +6382,8 @@ - qemu_register_machine(&realview_machine); - #elif defined(TARGET_SH4) - qemu_register_machine(&shix_machine); +@@ -6997,6 +7011,8 @@ + #elif defined(TARGET_M68K) + qemu_register_machine(&mcf5208evb_machine); + qemu_register_machine(&an5206_machine); +#elif defined(TARGET_Z80) + qemu_register_machine(&z80pc_machine); #else #error unsupported CPU #endif -diff -urN qemu-0.9.0/vl.h qemu-z80/vl.h ---- qemu-0.9.0/vl.h 2007-02-05 23:01:54.000000000 +0000 -+++ qemu-z80/vl.h 2007-04-17 20:16:51.000000000 +0100 -@@ -901,6 +901,11 @@ - void isa_cirrus_vga_init(DisplayState *ds, uint8_t *vga_ram_base, - unsigned long vga_ram_offset, int vga_ram_size); +diff --exclude='*.orig' --exclude=CVS -ruN qemu/vl.h qemu-z80/vl.h +--- qemu/vl.h 2007-06-30 19:32:17.000000000 +0200 ++++ qemu-z80/vl.h 2007-07-05 18:03:12.000000000 +0200 +@@ -959,6 +959,11 @@ + void pci_vmsvga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base, + unsigned long vga_ram_offset, int vga_ram_size); +/* zx_ula.c */ +void zx_ula_init(DisplayState *ds, uint8_t *zx_screen_base, @@ -4997,9 +5109,9 @@ diff -urN qemu-0.9.0/vl.h qemu-z80/vl.h +void zx_set_flash_dirty(void); + /* sdl.c */ - void sdl_display_init(DisplayState *ds, int full_screen); + void sdl_display_init(DisplayState *ds, int full_screen, int no_frame); -@@ -1065,6 +1070,9 @@ +@@ -1150,6 +1155,9 @@ extern QEMUMachine isapc_machine; extern int fd_bootchk; @@ -5009,9 +5121,9 @@ diff -urN qemu-0.9.0/vl.h qemu-z80/vl.h void ioport_set_a20(int enable); int ioport_get_a20(void); -diff -urN qemu-0.9.0/z80-dis.c qemu-z80/z80-dis.c ---- qemu-0.9.0/z80-dis.c 1970-01-01 01:00:00.000000000 +0100 -+++ qemu-z80/z80-dis.c 2007-02-01 15:20:38.000000000 +0000 +diff --exclude='*.orig' --exclude=CVS -ruN qemu/z80-dis.c qemu-z80/z80-dis.c +--- qemu/z80-dis.c 1970-01-01 01:00:00.000000000 +0100 ++++ qemu-z80/z80-dis.c 2007-07-05 18:03:12.000000000 +0200 @@ -0,0 +1,621 @@ +/* Print Z80 and R800 instructions + Copyright 2005 Free Software Foundation, Inc. diff --git a/qemu.changes b/qemu.changes index 115b57a5..06874480 100644 --- a/qemu.changes +++ b/qemu.changes @@ -1,3 +1,27 @@ +------------------------------------------------------------------- +Tue Jul 10 15:44:03 CEST 2007 - schwab@suse.de + +- Add (incomplete) m68k emulation. + +------------------------------------------------------------------- +Mon Jul 9 17:02:48 CEST 2007 - agraf@suse.de + +- included alsa support in qemu-user +- update to current cvs + - TFTP booting from host directory (Anthony Liguori, Erwan Velu) + - Tap device emulation for Solaris (Sittichai Palanisong) + - Monitor multiplexing to several I/O channels (Jason Wessel) + - ds1225y nvram support (Herve Poussineau) + - CPU model selection support (J. Mayer, Paul Brook, Herve Poussineau) + - Several Sparc fixes (Aurelien Jarno, Blue Swirl) + - MIPS 64-bit FPU support (Thiemo Seufer) + - Xscale PDA emulation (Andrzei Zaborowski) + - ColdFire system emulation (Paul Brook) + - Improved SH4 support (Magnus Damm) + - MIPS64 support (Aurelien Jarno, Thiemo Seufer) + - Preliminary Alpha guest support (J. Mayer) + - IPC fixes + ------------------------------------------------------------------- Wed Jun 20 14:38:47 CEST 2007 - agraf@suse.de diff --git a/qemu.spec b/qemu.spec index 1d2b7258..28720786 100644 --- a/qemu.spec +++ b/qemu.spec @@ -1,5 +1,5 @@ # -# spec file for package qemu (Version 0.9.0) +# spec file for package qemu (Version 0.9.0.cvs) # # Copyright (c) 2007 SUSE LINUX Products GmbH, Nuernberg, Germany. # This file and all modifications and additions to the pristine @@ -13,11 +13,11 @@ Name: qemu BuildRequires: SDL-devel bison e2fsprogs-devel URL: http://fabrice.bellard.free.fr/qemu/ -License: BSD License and BSD-like, GNU General Public License (GPL) -Group: System/Emulators/Other +License: BSD 3-Clause, GPL v2 or later +Group: System/Emulators/PC Summary: Universal CPU emulator -Version: 0.9.0 -Release: 38 +Version: 0.9.0.cvs +Release: 1 Source: %name-%version.tar.bz2 #Patch400: qemu-0.7.0-gcc4-dot-syms.patch #Patch401: qemu-0.8.0-gcc4-hacks.patch @@ -25,38 +25,39 @@ Source: %name-%version.tar.bz2 Patch1: qemu-0.7.0-binfmt.patch Patch5: qemu-0.7.0-sigaltstackhack.patch Patch6: qemu-0.7.0-amd64.patch -Patch8: qemu-0.9.0.patch +Patch8: qemu-cvs-pthread.patch Patch10: linkerscripts.patch -Patch11: qemu-0.7.2-kqemu.patch Patch14: qemu-0.7.1-jobsignals.patch -Patch15: qemu-0.9.0-syscalls.patch Patch16: qemu-0.7.1-armfpaex.patch Patch19: qemu-0.9.0-nousbdevfs.patch Patch20: qemu-0.9.0-usbheaders.patch -Patch21: qemu-0.9.0-initrd.patch -Patch22: qemu-0.9.0-nptl.patch -Patch23: qemu-0.9.0-fadvise64.patch -Patch25: qemu-0.9.0-nptl2.patch -Patch26: qemu-0.9.0-socket.patch -Patch27: qemu-0.9.0-strace.patch -Patch28: qemu-0.9.0-mmap.patch -Patch29: qemu-0.9.0-alt-path.patch -Patch30: qemu-0.9.0-nonetlink.patch -Patch31: qemu-0.9.0-kernel-option-vga.patch -Patch32: qemu-0.9.0-x86_64-opts.patch -Patch33: qemu-0.9.0-fix-cpus-chaining.patch Patch34: qemu-0.9.0-migration.patch -Patch36: qemu-0.9.0-fix-x86-fprem.patch Patch37: qemu-0.9.0-kvm.patch Patch38: qemu-0.9.0-kvm-bios.patch Patch39: qemu-0.9.0-kvm-kqemu-window-caption.patch -Patch40: qemu-z80.diff -Patch41: qemu-0.9.0-sched.patch -Patch42: qemu-0.8.2-alt-mmap.patch -Patch43: qemu-0.9.0-futex.patch -Patch44: qemu-0.9.0-robust_list.patch -Patch45: qemu-0.9.0-wine.patch -Patch46: bug-252519_goo-qemu-sec-0.9.0.diff +Patch48: qemu-z80.diff +Patch49: qemu-cvs-img.patch +Patch50: qemu-cvs-newpath.patch +Patch51: qemu-cvs-tls.patch +Patch52: qemu-cvs-futex.patch +Patch53: qemu-cvs-sched_getaffinity.patch +Patch54: qemu-cvs-mplayer.patch +Patch55: qemu-cvs-netlink.patch +Patch56: qemu-cvs-ipc.patch +Patch57: qemu-cvs-ipc_semop.patch +Patch58: qemu-cvs-ioctl_debug.patch +Patch59: qemu-cvs-alsa_bitfield.patch +Patch60: qemu-cvs-alsa_ioctl.patch +Patch61: qemu-cvs-ioctl_nodirection.patch +Patch62: qemu-cvs-alsa_mmap.patch +Patch63: qemu-cvs-gettimeofday.patch +Patch64: qemu-cvs-nofadvise64.patch +Patch65: qemu-cvs-flash.patch +Patch66: qemu-cvs-mmap-amd64.patch +Patch67: qemu-cvs-noppcemb.patch +Patch68: qemu-0.8.3-gcc4.patch +Patch69: qemu-cvs-ia64.patch +Patch70: qemu-m68k.diff Source200: kvm_bios.bin Source201: zx-rom.bin Source202: COPYING.zx-rom @@ -98,6 +99,8 @@ Patch663: gcc-ppc-nostartfileprefix.patch Patch664: gcc-ppc-nof.patch Patch700: gcc-abuildappease.patch Patch701: gcc-3.3.5.dif +# this is to make lint happy +Source300: rpmlintrc BuildRoot: %{_tmppath}/%{name}-%{version}-build ExclusiveArch: %ix86 ppc sparc x86_64 ia64 @@ -119,41 +122,45 @@ Authors: #%patch400 -p1 #%patch401 -p1 #%patch402 -p1 -%patch1 +%patch1 -p1 %patch5 %patch6 -%patch8 +%patch8 -p1 %patch10 -%patch11 %patch14 -%patch15 %patch16 %patch19 %patch20 -%patch21 -p1 -%patch22 -p1 -%patch23 -p1 -%patch25 -p1 -%patch26 -p1 -%patch27 -p1 -%patch28 -p1 -%patch29 -p1 -%patch30 -p1 -%patch31 -p1 -%patch32 -p1 -%patch33 -p1 -%patch34 -p1 -%patch36 -p1 -%patch37 -p1 -%patch38 -p1 -%patch39 -p1 -%patch40 -p1 -%patch41 -p1 -%patch42 -p1 -%patch43 -p1 -%patch44 -p1 -%patch45 -p1 -%patch46 -p1 +#%patch34 -p1 +#%patch37 -p1 +#%patch38 -p1 +#%patch39 -p1 +%patch48 -p1 +%patch49 +%patch50 -p1 +%patch51 -p1 +%patch52 -p1 +%patch53 -p1 +%patch54 -p1 +%patch55 -p1 +%patch56 -p1 +%patch57 -p1 +%patch58 -p1 +%patch59 -p1 +%patch60 -p1 +%patch61 -p1 +%patch62 -p1 +%patch63 -p1 +%patch64 -p1 +%patch65 -p1 +%patch66 -p1 +%patch67 -p1 +%patch69 +%patch70 +%ifarch ia64 ppc64 +#this is the dyngen for gcc4 patch (does not work on x86) +%patch68 -p1 +%endif cp -p %SOURCE200 pc-bios/ cp -p %SOURCE202 . cd gcc-3.3.5 @@ -192,9 +199,12 @@ cd gcc-3.3.5 cd .. %build -QEMU_OPT_FLAGS="$RPM_OPT_FLAGS" +%ifarch ia64 ppc64 +%define qemucc gcc +%else %define gcc33tmp /tmp/gcc33 %define qemucc %{gcc33tmp}/bin/gcc +QEMU_OPT_FLAGS="$RPM_OPT_FLAGS" # fix opt flags for gcc3 %ifarch %ix86 QEMU_OPT_FLAGS="${RPM_OPT_FLAGS/-mtune=/-mcpu=}" @@ -214,79 +224,41 @@ cd gcc-3.3.5 make bootstrap-lean BOOT_CFLAGS="$QEMU_OPT_FLAGS" STAGE1_CFLAGS="$QEMU_OPT_FLAGS" CFLAGS="$QEMU_OPT_FLAGS" %{?jobs:-j%{jobs}} make install cd .. +QEMU_OPT_FLAGS="$QEMU_OPT_FLAGS -fno-strict-aliasing" +%endif # build QEMU +mkdir -p dynamic +# build qemu-system without kqemu support +./configure --prefix=/usr \ + --interp-prefix=/usr/share/qemu/qemu-i386 \ + --cc=%qemucc --enable-adlib --disable-gcc-check \ + --extra-cflags="$QEMU_OPT_FLAGS" --enable-system --disable-linux-user +make %{?jobs:-j%{jobs}} +mv */qemu */qemu-* dynamic || true +make clean +# build qemu-system with kqemu support # kqemu target +%ifarch %ix86 x86_64 %ifarch x86_64 target_list_kqemu="x86_64-softmmu" %else target_list_kqemu="i386-softmmu" %endif -# targets for all platforms -target_list="ppc-softmmu sparc-softmmu mips-softmmu mipsel-softmmu arm-softmmu z80-softmmu" -# AMD64 -> i386 without kqemu -# x86 -> AMD64 without kqemu -# others -> both without kqemu -%ifarch x86_64 -target_list="$target_list i386-softmmu" -%else -%ifarch %ix86 -target_list="$target_list x86_64-softmmu" -%else -target_list="$target_list i386-softmmu x86_64-softmmu" -%endif -%endif -# linux-user targets -target_list_user="" -%ifnarch %ix86 x86_64 -target_list_user="$target_list_user i386-linux-user" -%endif -%ifnarch armv4l -target_list_user="$target_list_user arm-linux-user" -%endif -%ifnarch armv4b -target_list_user="$target_list_user armeb-linux-user" -%endif -%ifnarch sparc sparc64 -target_list_user="$target_list_user sparc-linux-user" -%endif -%ifnarch ppc ppc64 -target_list_user="$target_list_user ppc-linux-user" -%endif -%ifnarch mips -target_list_user="$target_list_user mips-linux-user" -%endif -%ifnarch mipsel -target_list_user="$target_list_user mipsel-linux-user" -%endif -%ifnarch m68k -target_list_user="$target_list_user m68k-linux-user" -%endif -QEMU_OPT_FLAGS="$QEMU_OPT_FLAGS -fno-strict-aliasing" -mkdir -p dynamic -%ifarch %ix86 x86_64 -# build i386/x86_64 system with kqemu support ./configure --prefix=/usr \ --interp-prefix=/usr/share/qemu/qemu-i386 \ --target-list="$target_list_kqemu" --cc=%qemucc \ - --enable-adlib --extra-cflags="$QEMU_OPT_FLAGS" + --enable-adlib --extra-cflags="$QEMU_OPT_FLAGS" echo '#define USE_KQEMU 1' >>config-host.h make %{?jobs:-j%{jobs}} mv */qemu */qemu-* dynamic || true make clean %endif -# build system emus without kqemu support -./configure --prefix=/usr \ - --interp-prefix=/usr/share/qemu/qemu-i386 \ - --target-list="$target_list" --cc=%qemucc \ - --enable-adlib --extra-cflags="$QEMU_OPT_FLAGS" -make %{?jobs:-j%{jobs}} -mv */qemu *-*/qemu-* dynamic || true -make clean # build userland emus ./configure --prefix=/usr \ --interp-prefix=/usr/share/qemu/qemu-i386 \ - --target-list="$target_list_user" --cc=%qemucc \ - --static --extra-cflags="$QEMU_OPT_FLAGS" + --enable-linux-user --disable-system --cc=%qemucc \ + --static --disable-gcc-check \ + --extra-cflags="$QEMU_OPT_FLAGS" make %{?jobs:-j%{jobs}} %install @@ -299,7 +271,7 @@ install -m 755 */qemu-*[^.]? $RPM_BUILD_ROOT/usr/bin install -d -m 755 $RPM_BUILD_ROOT/%{_mandir}/man1 install -m 644 qemu.1 $RPM_BUILD_ROOT/%{_mandir}/man1 install -d -m 755 $RPM_BUILD_ROOT/usr/share/qemu -install -m 644 pc-bios/*.bin pc-bios/video.x pc-bios/openbios-sparc32 $RPM_BUILD_ROOT/usr/share/qemu +install -m 644 pc-bios/*.bin pc-bios/video.x pc-bios/openbios-sparc* $RPM_BUILD_ROOT/usr/share/qemu install -d -m 755 $RPM_BUILD_ROOT/usr/sbin install -m 755 qemu-binfmt-conf.sh $RPM_BUILD_ROOT/usr/sbin install -m 755 qemu-img $RPM_BUILD_ROOT/usr/bin @@ -332,6 +304,24 @@ rm -rf %{gcc33tmp} %endif %changelog +* Tue Jul 10 2007 - schwab@suse.de +- Add (incomplete) m68k emulation. +* Mon Jul 09 2007 - agraf@suse.de +- included alsa support in qemu-user +- update to current cvs + - TFTP booting from host directory (Anthony Liguori, Erwan Velu) + - Tap device emulation for Solaris (Sittichai Palanisong) + - Monitor multiplexing to several I/O channels (Jason Wessel) + - ds1225y nvram support (Herve Poussineau) + - CPU model selection support (J. Mayer, Paul Brook, Herve Poussineau) + - Several Sparc fixes (Aurelien Jarno, Blue Swirl) + - MIPS 64-bit FPU support (Thiemo Seufer) + - Xscale PDA emulation (Andrzei Zaborowski) + - ColdFire system emulation (Paul Brook) + - Improved SH4 support (Magnus Damm) + - MIPS64 support (Aurelien Jarno, Thiemo Seufer) + - Preliminary Alpha guest support (J. Mayer) + - IPC fixes * Wed Jun 20 2007 - agraf@suse.de - applied proper fix for x86_64 and the MAP_32BIT flag * Wed Jun 20 2007 - uli@suse.de diff --git a/rpmlintrc b/rpmlintrc new file mode 100644 index 00000000..719aa890 --- /dev/null +++ b/rpmlintrc @@ -0,0 +1,5 @@ +# This line is mandatory to access the configuration functions +from Config import * + +addFilter("qemu arch-dependent-file-in-usr-share") +