From patchwork Sun Aug 15 19:27:19 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eduard - Gabriel Munteanu X-Patchwork-Id: 119631 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.4/8.14.3) with ESMTP id o7FJUq8a022813 for ; Sun, 15 Aug 2010 19:30:53 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751211Ab0HOTat (ORCPT ); Sun, 15 Aug 2010 15:30:49 -0400 Received: from mail-fx0-f46.google.com ([209.85.161.46]:47103 "EHLO mail-fx0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751217Ab0HOTan (ORCPT ); Sun, 15 Aug 2010 15:30:43 -0400 Received: by mail-fx0-f46.google.com with SMTP id 13so2628979fxm.19 for ; Sun, 15 Aug 2010 12:30:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:sender:from:to:cc:subject :date:message-id:x-mailer:in-reply-to:references; bh=ztyGnH6afOkQbHj/a6pifQSwRIJTdyHdBD3CKMwX+Pg=; b=dRoRAMNzr9B2AdORVOrPVcsWaZgdeFYeVyh4PBYGad/fsi+8NBB00/lkiAszrMm58M tStaaHbdC9t90PonL25lTLRMyFhvEXsQHfcsndE4F03UfdCNi75Icw4+3HDzWfDUOLZT AOfkY5oSlpu0nhoZ3Dk+QshPfAJ7BuumL7E6Y= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=sender:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; b=TLywf0i7bSo5uwDtW4/C9M5HziNaADkvEhQRNuVclYKlQFf/PfEcx8ai2dZrQ78ekm 2df7lesXrqiDY//+izv7e8NLoXIsEVxIjcwzx2bM8UTdisJZp6y+7bwxWP23/4NJiIcI Ws3EoPMdVFR9BfGzSiZqbDpDN737rVJxs0Vt0= Received: by 10.223.104.148 with SMTP id p20mr4403502fao.11.1281900642333; Sun, 15 Aug 2010 12:30:42 -0700 (PDT) Received: from localhost.localdomain ([178.138.32.54]) by mx.google.com with ESMTPS id r4sm1362656faa.43.2010.08.15.12.30.40 (version=SSLv3 cipher=RC4-MD5); Sun, 15 Aug 2010 12:30:42 -0700 (PDT) From: Eduard - Gabriel Munteanu To: joro@8bytes.org Cc: paul@codesourcery.com, blauwirbel@gmail.com, anthony@codemonkey.ws, avi@redhat.com, kvm@vger.kernel.org, qemu-devel@nongnu.org, Eduard - Gabriel Munteanu Subject: [PATCH 4/7] ide: use the PCI memory access interface Date: Sun, 15 Aug 2010 22:27:19 +0300 Message-Id: <1281900442-29971-5-git-send-email-eduard.munteanu@linux360.ro> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1281900442-29971-1-git-send-email-eduard.munteanu@linux360.ro> References: <1281900442-29971-1-git-send-email-eduard.munteanu@linux360.ro> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Sun, 15 Aug 2010 19:30:53 +0000 (UTC) diff --git a/dma-helpers.c b/dma-helpers.c index d4fc077..9c3a21a 100644 --- a/dma-helpers.c +++ b/dma-helpers.c @@ -10,12 +10,36 @@ #include "dma.h" #include "block_int.h" -void qemu_sglist_init(QEMUSGList *qsg, int alloc_hint) +static void *qemu_sglist_default_map(void *opaque, + QEMUSGInvalMapFunc *inval_cb, + void *inval_opaque, + target_phys_addr_t addr, + target_phys_addr_t *len, + int is_write) +{ + return cpu_physical_memory_map(addr, len, is_write); +} + +static void qemu_sglist_default_unmap(void *opaque, + void *buffer, + target_phys_addr_t len, + int is_write, + target_phys_addr_t access_len) +{ + cpu_physical_memory_unmap(buffer, len, is_write, access_len); +} + +void qemu_sglist_init(QEMUSGList *qsg, int alloc_hint, + QEMUSGMapFunc *map, QEMUSGUnmapFunc *unmap, void *opaque) { qsg->sg = qemu_malloc(alloc_hint * sizeof(ScatterGatherEntry)); qsg->nsg = 0; qsg->nalloc = alloc_hint; qsg->size = 0; + + qsg->map = map ? map : qemu_sglist_default_map; + qsg->unmap = unmap ? unmap : qemu_sglist_default_unmap; + qsg->opaque = opaque; } void qemu_sglist_add(QEMUSGList *qsg, target_phys_addr_t base, @@ -73,12 +97,23 @@ static void dma_bdrv_unmap(DMAAIOCB *dbs) int i; for (i = 0; i < dbs->iov.niov; ++i) { - cpu_physical_memory_unmap(dbs->iov.iov[i].iov_base, - dbs->iov.iov[i].iov_len, !dbs->is_write, - dbs->iov.iov[i].iov_len); + dbs->sg->unmap(dbs->sg->opaque, + dbs->iov.iov[i].iov_base, + dbs->iov.iov[i].iov_len, !dbs->is_write, + dbs->iov.iov[i].iov_len); } } +static void dma_bdrv_cancel(void *opaque) +{ + DMAAIOCB *dbs = opaque; + + bdrv_aio_cancel(dbs->acb); + dma_bdrv_unmap(dbs); + qemu_iovec_destroy(&dbs->iov); + qemu_aio_release(dbs); +} + static void dma_bdrv_cb(void *opaque, int ret) { DMAAIOCB *dbs = (DMAAIOCB *)opaque; @@ -100,7 +135,8 @@ static void dma_bdrv_cb(void *opaque, int ret) while (dbs->sg_cur_index < dbs->sg->nsg) { cur_addr = dbs->sg->sg[dbs->sg_cur_index].base + dbs->sg_cur_byte; cur_len = dbs->sg->sg[dbs->sg_cur_index].len - dbs->sg_cur_byte; - mem = cpu_physical_memory_map(cur_addr, &cur_len, !dbs->is_write); + mem = dbs->sg->map(dbs->sg->opaque, dma_bdrv_cancel, dbs, + cur_addr, &cur_len, !dbs->is_write); if (!mem) break; qemu_iovec_add(&dbs->iov, mem, cur_len); diff --git a/dma.h b/dma.h index f3bb275..d48f35c 100644 --- a/dma.h +++ b/dma.h @@ -15,6 +15,19 @@ #include "hw/hw.h" #include "block.h" +typedef void QEMUSGInvalMapFunc(void *opaque); +typedef void *QEMUSGMapFunc(void *opaque, + QEMUSGInvalMapFunc *inval_cb, + void *inval_opaque, + target_phys_addr_t addr, + target_phys_addr_t *len, + int is_write); +typedef void QEMUSGUnmapFunc(void *opaque, + void *buffer, + target_phys_addr_t len, + int is_write, + target_phys_addr_t access_len); + typedef struct { target_phys_addr_t base; target_phys_addr_t len; @@ -25,9 +38,15 @@ typedef struct { int nsg; int nalloc; target_phys_addr_t size; + + QEMUSGMapFunc *map; + QEMUSGUnmapFunc *unmap; + void *opaque; } QEMUSGList; -void qemu_sglist_init(QEMUSGList *qsg, int alloc_hint); +void qemu_sglist_init(QEMUSGList *qsg, int alloc_hint, + QEMUSGMapFunc *map, QEMUSGUnmapFunc *unmap, + void *opaque); void qemu_sglist_add(QEMUSGList *qsg, target_phys_addr_t base, target_phys_addr_t len); void qemu_sglist_destroy(QEMUSGList *qsg); diff --git a/hw/ide/core.c b/hw/ide/core.c index 0b3b7c2..c19013a 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -435,7 +435,8 @@ static int dma_buf_prepare(BMDMAState *bm, int is_write) } prd; int l, len; - qemu_sglist_init(&s->sg, s->nsector / (IDE_PAGE_SIZE / 512) + 1); + qemu_sglist_init(&s->sg, s->nsector / (IDE_PAGE_SIZE / 512) + 1, + bm->map, bm->unmap, bm->opaque); s->io_buffer_size = 0; for(;;) { if (bm->cur_prd_len == 0) { @@ -443,7 +444,7 @@ static int dma_buf_prepare(BMDMAState *bm, int is_write) if (bm->cur_prd_last || (bm->cur_addr - bm->addr) >= IDE_PAGE_SIZE) return s->io_buffer_size != 0; - cpu_physical_memory_read(bm->cur_addr, (uint8_t *)&prd, 8); + bmdma_memory_read(bm, bm->cur_addr, (uint8_t *)&prd, 8); bm->cur_addr += 8; prd.addr = le32_to_cpu(prd.addr); prd.size = le32_to_cpu(prd.size); @@ -526,7 +527,7 @@ static int dma_buf_rw(BMDMAState *bm, int is_write) if (bm->cur_prd_last || (bm->cur_addr - bm->addr) >= IDE_PAGE_SIZE) return 0; - cpu_physical_memory_read(bm->cur_addr, (uint8_t *)&prd, 8); + bmdma_memory_read(bm, bm->cur_addr, (uint8_t *)&prd, 8); bm->cur_addr += 8; prd.addr = le32_to_cpu(prd.addr); prd.size = le32_to_cpu(prd.size); @@ -541,11 +542,11 @@ static int dma_buf_rw(BMDMAState *bm, int is_write) l = bm->cur_prd_len; if (l > 0) { if (is_write) { - cpu_physical_memory_write(bm->cur_prd_addr, - s->io_buffer + s->io_buffer_index, l); + bmdma_memory_write(bm, bm->cur_prd_addr, + s->io_buffer + s->io_buffer_index, l); } else { - cpu_physical_memory_read(bm->cur_prd_addr, - s->io_buffer + s->io_buffer_index, l); + bmdma_memory_read(bm, bm->cur_prd_addr, + s->io_buffer + s->io_buffer_index, l); } bm->cur_prd_addr += l; bm->cur_prd_len -= l; diff --git a/hw/ide/internal.h b/hw/ide/internal.h index eef1ee1..0f3b707 100644 --- a/hw/ide/internal.h +++ b/hw/ide/internal.h @@ -476,6 +476,24 @@ struct IDEDeviceInfo { #define BM_CMD_START 0x01 #define BM_CMD_READ 0x08 +typedef void BMDMAInvalMapFunc(void *opaque); +typedef void BMDMARWFunc(void *opaque, + target_phys_addr_t addr, + uint8_t *buf, + target_phys_addr_t len, + int is_write); +typedef void *BMDMAMapFunc(void *opaque, + BMDMAInvalMapFunc *inval_cb, + void *inval_opaque, + target_phys_addr_t addr, + target_phys_addr_t *len, + int is_write); +typedef void BMDMAUnmapFunc(void *opaque, + void *buffer, + target_phys_addr_t len, + int is_write, + target_phys_addr_t access_len); + struct BMDMAState { uint8_t cmd; uint8_t status; @@ -495,8 +513,29 @@ struct BMDMAState { int64_t sector_num; uint32_t nsector; QEMUBH *bh; + + BMDMARWFunc *rw; + BMDMAMapFunc *map; + BMDMAUnmapFunc *unmap; + void *opaque; }; +static inline void bmdma_memory_read(BMDMAState *bm, + target_phys_addr_t addr, + uint8_t *buf, + target_phys_addr_t len) +{ + bm->rw(bm->opaque, addr, buf, len, 0); +} + +static inline void bmdma_memory_write(BMDMAState *bm, + target_phys_addr_t addr, + uint8_t *buf, + target_phys_addr_t len) +{ + bm->rw(bm->opaque, addr, buf, len, 1); +} + static inline IDEState *idebus_active_if(IDEBus *bus) { return bus->ifs + bus->unit; diff --git a/hw/ide/pci.c b/hw/ide/pci.c index 4d95cc5..5879044 100644 --- a/hw/ide/pci.c +++ b/hw/ide/pci.c @@ -183,4 +183,11 @@ void pci_ide_create_devs(PCIDevice *dev, DriveInfo **hd_table) continue; ide_create_drive(d->bus+bus[i], unit[i], hd_table[i]); } + + for (i = 0; i < 2; i++) { + d->bmdma[i].rw = (void *) pci_memory_rw; + d->bmdma[i].map = (void *) pci_memory_map; + d->bmdma[i].unmap = (void *) pci_memory_unmap; + d->bmdma[i].opaque = dev; + } }