From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Iz8FE-00089t-EY for qemu-devel@nongnu.org; Mon, 03 Dec 2007 05:09:44 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1Iz8FD-00088b-BO for qemu-devel@nongnu.org; Mon, 03 Dec 2007 05:09:43 -0500 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Iz8FC-00088O-AQ for qemu-devel@nongnu.org; Mon, 03 Dec 2007 05:09:42 -0500 Received: from ecfrec.frec.bull.fr ([129.183.4.8]) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1Iz8F9-0002NX-V3 for qemu-devel@nongnu.org; Mon, 03 Dec 2007 05:09:42 -0500 Received: from localhost (localhost [127.0.0.1]) by ecfrec.frec.bull.fr (Postfix) with ESMTP id 42E7119D922 for ; Mon, 3 Dec 2007 11:09:38 +0100 (CET) Received: from ecfrec.frec.bull.fr ([127.0.0.1]) by localhost (ecfrec.frec.bull.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 18489-10 for ; Mon, 3 Dec 2007 11:09:34 +0100 (CET) Received: from ecn002.frec.bull.fr (ecn002.frec.bull.fr [129.183.4.6]) by ecfrec.frec.bull.fr (Postfix) with ESMTP id 62E4019D9D3 for ; Mon, 3 Dec 2007 11:09:31 +0100 (CET) In-Reply-To: <1196676560457@bull.net> Date: Mon, 3 Dec 2007 11:09:20 +0100 Message-Id: <11966765602186@bull.net> Mime-Version: 1.0 From: Laurent Vivier Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="iso-8859-1" Subject: [Qemu-devel] [PATCH 2/2 v2] Direct IDE I/O Reply-To: Laurent Vivier , qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-devel@nongnu.org This patch enhances the "-drive ,cache=3Doff" mode with IDE drive emulation by removing the buffer used in the IDE emulation. --- block.c | 10 +++ block.h | 2=20 block_int.h | 1=20 cpu-all.h | 1=20 exec.c | 19 ++++++ hw/ide.c | 176 +++++++++++++++++++++++++++++++++++++++++++++++++++++++= ++--- vl.c | 1=20 7 files changed, 204 insertions(+), 6 deletions(-) Index: qemu/block.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- qemu.orig/block.c 2007-12-03 09:54:47.000000000 +0100 +++ qemu/block.c 2007-12-03 09:54:53.000000000 +0100 @@ -758,6 +758,11 @@ void bdrv_set_translation_hint(BlockDriv bs->translation =3D translation; } =20 +void bdrv_set_cache_hint(BlockDriverState *bs, int cache) +{ + bs->cache =3D cache; +} + void bdrv_get_geometry_hint(BlockDriverState *bs, int *pcyls, int *pheads, int *psecs) { @@ -786,6 +791,11 @@ int bdrv_is_read_only(BlockDriverState * return bs->read_only; } =20 +int bdrv_is_cached(BlockDriverState *bs) +{ + return bs->cache; +} + /* XXX: no longer used */ void bdrv_set_change_cb(BlockDriverState *bs, void (*change_cb)(void *opaque), void *opaque) Index: qemu/block.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- qemu.orig/block.h 2007-12-03 09:54:47.000000000 +0100 +++ qemu/block.h 2007-12-03 09:54:53.000000000 +0100 @@ -113,6 +113,7 @@ void bdrv_set_geometry_hint(BlockDriverS int cyls, int heads, int secs); void bdrv_set_type_hint(BlockDriverState *bs, int type); void bdrv_set_translation_hint(BlockDriverState *bs, int translation); +void bdrv_set_cache_hint(BlockDriverState *bs, int cache); void bdrv_get_geometry_hint(BlockDriverState *bs, int *pcyls, int *pheads, int *psecs); int bdrv_get_type_hint(BlockDriverState *bs); @@ -120,6 +121,7 @@ int bdrv_get_translation_hint(BlockDrive int bdrv_is_removable(BlockDriverState *bs); int bdrv_is_read_only(BlockDriverState *bs); int bdrv_is_inserted(BlockDriverState *bs); +int bdrv_is_cached(BlockDriverState *bs); int bdrv_media_changed(BlockDriverState *bs); int bdrv_is_locked(BlockDriverState *bs); void bdrv_set_locked(BlockDriverState *bs, int locked); Index: qemu/block_int.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- qemu.orig/block_int.h 2007-12-03 09:53:30.000000000 +0100 +++ qemu/block_int.h 2007-12-03 09:54:53.000000000 +0100 @@ -124,6 +124,7 @@ struct BlockDriverState { drivers. They are not used by the block driver */ int cyls, heads, secs, translation; int type; + int cache; char device_name[32]; BlockDriverState *next; }; Index: qemu/vl.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- qemu.orig/vl.c 2007-12-03 09:54:47.000000000 +0100 +++ qemu/vl.c 2007-12-03 09:54:53.000000000 +0100 @@ -5112,6 +5112,7 @@ static int drive_init(const char *str, i bdrv_flags |=3D BDRV_O_SNAPSHOT; if (!cache) bdrv_flags |=3D BDRV_O_DIRECT; + bdrv_set_cache_hint(bdrv, cache); if (bdrv_open(bdrv, file, bdrv_flags) < 0 || qemu_key_check(bdrv, file= )) { fprintf(stderr, "qemu: could not open disk image %s\n", file); Index: qemu/hw/ide.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- qemu.orig/hw/ide.c 2007-12-03 09:54:47.000000000 +0100 +++ qemu/hw/ide.c 2007-12-03 09:54:53.000000000 +0100 @@ -816,7 +816,7 @@ static int dma_buf_rw(BMDMAState *bm, in } =20 /* XXX: handle errors */ -static void ide_read_dma_cb(void *opaque, int ret) +static void ide_read_dma_cb_buffered(void *opaque, int ret) { BMDMAState *bm =3D opaque; IDEState *s =3D bm->ide_if; @@ -856,7 +856,86 @@ static void ide_read_dma_cb(void *opaque printf("aio_read: sector_num=3D%lld n=3D%d\n", sector_num, n); #endif bm->aiocb =3D bdrv_aio_read(s->bs, sector_num, s->io_buffer, n, - ide_read_dma_cb, bm); + ide_read_dma_cb_buffered, bm); +} + +static void ide_read_dma_cb_unbuffered(void *opaque, int ret) +{ + BMDMAState *bm =3D opaque; + IDEState *s =3D bm->ide_if; + int64_t sector_num; + int nsector; + int len; + uint8_t *phy_addr; + + if (s->nsector =3D=3D 0) { + s->status =3D READY_STAT | SEEK_STAT; + ide_set_irq(s); + eot: + bm->status &=3D ~BM_STATUS_DMAING; + bm->status |=3D BM_STATUS_INT; + bm->dma_cb =3D NULL; + bm->ide_if =3D NULL; + bm->aiocb =3D NULL; + return; + } + + /* launch next transfer */ + + if (bm->cur_prd_len =3D=3D 0) { + struct { + uint32_t addr; + uint32_t size; + } prd; + + cpu_physical_memory_read(bm->cur_addr, (uint8_t *)&prd, 8); + + bm->cur_addr +=3D 8; + prd.addr =3D le32_to_cpu(prd.addr); + prd.size =3D le32_to_cpu(prd.size); + len =3D prd.size & 0xfffe; + if (len =3D=3D 0) + len =3D 0x10000; + bm->cur_prd_addr =3D prd.addr; + while ((bm->cur_addr - bm->addr) < 4096) { + int tmp_len; + cpu_physical_memory_read(bm->cur_addr, (uint8_t *)&prd, 8); + prd.addr =3D le32_to_cpu(prd.addr); + prd.size =3D le32_to_cpu(prd.size); + if (bm->cur_prd_addr + len !=3D prd.addr) + break; + tmp_len =3D prd.size & 0xfffe; + if (tmp_len =3D=3D 0) + tmp_len =3D 0x10000; + len +=3D tmp_len; + bm->cur_addr +=3D 8; + if (prd.size & 0x80000000) + break; + } + bm->cur_prd_len =3D len; + } + + phy_addr =3D cpu_physical_page_addr(bm->cur_prd_addr); + if (phy_addr =3D=3D (uint8_t *)-1) + goto eot; + + len =3D (s->nsector<<9); + if (len > bm->cur_prd_len) + len =3D bm->cur_prd_len; + + nsector =3D (len>>9); + bm->cur_prd_addr +=3D (nsector<<9); + bm->cur_prd_len -=3D (nsector<<9); + + sector_num =3D ide_get_sector(s); + ide_set_sector(s, sector_num + nsector); + s->nsector-=3Dnsector; + +#ifdef DEBUG_AIO + printf("aio_read: sector_num=3D%lld n=3D%d\n", (unsigned long long)sec= tor_num, nsector); +#endif + bm->aiocb =3D bdrv_aio_read(s->bs, sector_num, phy_addr, nsector, + ide_read_dma_cb_unbuffered, bm); } =20 static void ide_sector_read_dma(IDEState *s) @@ -864,7 +943,10 @@ static void ide_sector_read_dma(IDEState s->status =3D READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT; s->io_buffer_index =3D 0; s->io_buffer_size =3D 0; - ide_dma_start(s, ide_read_dma_cb); + if (bdrv_is_cached(s->bs)) + ide_dma_start(s, ide_read_dma_cb_buffered); + else + ide_dma_start(s, ide_read_dma_cb_unbuffered); } =20 static void ide_sector_write_timer_cb(void *opaque) @@ -917,7 +999,7 @@ static void ide_sector_write(IDEState *s } =20 /* XXX: handle errors */ -static void ide_write_dma_cb(void *opaque, int ret) +static void ide_write_dma_cb_buffered(void *opaque, int ret) { BMDMAState *bm =3D opaque; IDEState *s =3D bm->ide_if; @@ -958,7 +1040,86 @@ static void ide_write_dma_cb(void *opaqu printf("aio_write: sector_num=3D%lld n=3D%d\n", sector_num, n); #endif bm->aiocb =3D bdrv_aio_write(s->bs, sector_num, s->io_buffer, n, - ide_write_dma_cb, bm); + ide_write_dma_cb_buffered, bm); +} + +static void ide_write_dma_cb_unbuffered(void *opaque, int ret) +{ + BMDMAState *bm =3D opaque; + IDEState *s =3D bm->ide_if; + int64_t sector_num; + int nsector; + int len; + uint8_t *phy_addr; + + if (s->nsector =3D=3D 0) { + s->status =3D READY_STAT | SEEK_STAT; + ide_set_irq(s); + eot: + bm->status &=3D ~BM_STATUS_DMAING; + bm->status |=3D BM_STATUS_INT; + bm->dma_cb =3D NULL; + bm->ide_if =3D NULL; + bm->aiocb =3D NULL; + return; + } + + /* launch next transfer */ + + if (bm->cur_prd_len =3D=3D 0) { + struct { + uint32_t addr; + uint32_t size; + } prd; + + cpu_physical_memory_read(bm->cur_addr, (uint8_t *)&prd, 8); + + bm->cur_addr +=3D 8; + prd.addr =3D le32_to_cpu(prd.addr); + prd.size =3D le32_to_cpu(prd.size); + len =3D prd.size & 0xfffe; + if (len =3D=3D 0) + len =3D 0x10000; + bm->cur_prd_addr =3D prd.addr; + while ((bm->cur_addr - bm->addr) < 4096) { + int tmp_len; + cpu_physical_memory_read(bm->cur_addr, (uint8_t *)&prd, 8); + prd.addr =3D le32_to_cpu(prd.addr); + prd.size =3D le32_to_cpu(prd.size); + if (bm->cur_prd_addr + len !=3D prd.addr) + break; + tmp_len =3D prd.size & 0xfffe; + if (tmp_len =3D=3D 0) + tmp_len =3D 0x10000; + len +=3D tmp_len; + bm->cur_addr +=3D 8; + if (prd.size & 0x80000000) + break; + } + bm->cur_prd_len =3D len; + } + + phy_addr =3D cpu_physical_page_addr(bm->cur_prd_addr); + if (phy_addr =3D=3D (uint8_t *)-1) + goto eot; + + len =3D (s->nsector<<9); + if (len > bm->cur_prd_len) + len =3D bm->cur_prd_len; + + nsector =3D (len>>9); + bm->cur_prd_addr +=3D (nsector<<9); + bm->cur_prd_len -=3D (nsector<<9); + + sector_num =3D ide_get_sector(s); + ide_set_sector(s, sector_num + nsector); + s->nsector-=3Dnsector; + +#ifdef DEBUG_AIO + printf("aio_write: sector_num=3D%lld n=3D%d\n", (unsigned long long)se= ctor_num, nsector); +#endif + bm->aiocb =3D bdrv_aio_write(s->bs, sector_num, phy_addr, nsector, + ide_write_dma_cb_unbuffered, bm); } =20 static void ide_sector_write_dma(IDEState *s) @@ -966,7 +1127,10 @@ static void ide_sector_write_dma(IDEStat s->status =3D READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT; s->io_buffer_index =3D 0; s->io_buffer_size =3D 0; - ide_dma_start(s, ide_write_dma_cb); + if (bdrv_is_cached(s->bs)) + ide_dma_start(s, ide_write_dma_cb_buffered); + else + ide_dma_start(s, ide_write_dma_cb_unbuffered); } =20 static void ide_atapi_cmd_ok(IDEState *s) Index: qemu/exec.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- qemu.orig/exec.c 2007-12-03 09:53:30.000000000 +0100 +++ qemu/exec.c 2007-12-03 09:54:53.000000000 +0100 @@ -2054,6 +2054,25 @@ void cpu_register_physical_memory(target } } =20 +uint8_t * cpu_physical_page_addr(target_phys_addr_t addr) +{ + target_phys_addr_t page; + unsigned long pd; + PhysPageDesc *p; + unsigned long addr1; + + page =3D addr & TARGET_PAGE_MASK; + p =3D phys_page_find(page >> TARGET_PAGE_BITS); + if (!p) + return (uint8_t*)-1; + + pd =3D p->phys_offset; + + addr1 =3D (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK); + + return phys_ram_base + addr1; +} + /* XXX: temporary until new memory mapping API */ uint32_t cpu_get_physical_page_desc(target_phys_addr_t addr) { Index: qemu/cpu-all.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- qemu.orig/cpu-all.h 2007-12-03 09:53:30.000000000 +0100 +++ qemu/cpu-all.h 2007-12-03 09:54:53.000000000 +0100 @@ -837,6 +837,7 @@ int cpu_register_io_memory(int io_index, CPUWriteMemoryFunc **cpu_get_io_memory_write(int io_index); CPUReadMemoryFunc **cpu_get_io_memory_read(int io_index); =20 +extern uint8_t * cpu_physical_page_addr(target_phys_addr_t addr); void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, int len, int is_write); static inline void cpu_physical_memory_read(target_phys_addr_t addr,