From patchwork Mon Oct 5 10:06:58 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Isaku Yamahata X-Patchwork-Id: 34983 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 4AE79B7BB9 for ; Mon, 5 Oct 2009 22:03:20 +1100 (EST) Received: from localhost ([127.0.0.1]:42598 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MulLZ-0005FY-KG for incoming@patchwork.ozlabs.org; Mon, 05 Oct 2009 07:03:17 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MukV8-0001EI-Na for qemu-devel@nongnu.org; Mon, 05 Oct 2009 06:09:08 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MukUu-00012q-FY for qemu-devel@nongnu.org; Mon, 05 Oct 2009 06:08:56 -0400 Received: from [199.232.76.173] (port=44766 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MukUu-00012i-4u for qemu-devel@nongnu.org; Mon, 05 Oct 2009 06:08:52 -0400 Received: from mail.valinux.co.jp ([210.128.90.3]:55411) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1MukUt-00076Y-0s for qemu-devel@nongnu.org; Mon, 05 Oct 2009 06:08:51 -0400 Received: from nm.local.valinux.co.jp (vagw.valinux.co.jp [210.128.90.14]) by mail.valinux.co.jp (Postfix) with ESMTP id 1F08449D8C; Mon, 5 Oct 2009 19:08:42 +0900 (JST) Received: from yamahata by nm.local.valinux.co.jp with local (Exim 4.69) (envelope-from ) id 1MukTA-0004DK-7E; Mon, 05 Oct 2009 19:07:04 +0900 From: Isaku Yamahata To: qemu-devel@nongnu.org, mst@redhat.com Date: Mon, 5 Oct 2009 19:06:58 +0900 Message-Id: <1254737223-16129-19-git-send-email-yamahata@valinux.co.jp> X-Mailer: git-send-email 1.6.0.2 In-Reply-To: <1254737223-16129-1-git-send-email-yamahata@valinux.co.jp> References: <1254737223-16129-1-git-send-email-yamahata@valinux.co.jp> X-Virus-Scanned: clamav-milter 0.95.2 at va-mail.local.valinux.co.jp X-Virus-Status: Clean X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 3) Cc: yamahata@valinux.co.jp Subject: [Qemu-devel] [PATCH 18/23] pci: add helper functions for pci config write function. X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org add helper functions for pci config write function to check if its configuration space is changed. Those function will be used later and generic enough for specific pci device to use. Signed-off-by: Isaku Yamahata --- hw/pci.h | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 59 insertions(+), 0 deletions(-) diff --git a/hw/pci.h b/hw/pci.h index 1f402d2..0ea08b7 100644 --- a/hw/pci.h +++ b/hw/pci.h @@ -393,6 +393,65 @@ static inline uint32_t pcie_config_size(PCIDevice *d) return pci_is_pcie(d)? PCIE_CONFIG_SPACE_SIZE: PCI_CONFIG_SPACE_SIZE; } +struct pci_config_update { + PCIDevice *d; + uint32_t addr; + uint32_t val; + int len; + + uint8_t orig[4]; +}; + +static inline void pci_write_config_init(struct pci_config_update *update, + PCIDevice *d, + uint32_t addr, uint32_t val, int len) +{ + assert(len == 1 || len == 2 || len == 4); + + update->d = d; + update->addr = addr; + update->val = val; + update->len = len; + memcpy(update->orig, &d->config[addr], len); +} + +static inline void pci_write_config_update(struct pci_config_update *update) +{ + PCIDevice *d = update->d; + uint32_t addr = update->addr; + uint32_t val = update->val; + uint32_t config_size = pcie_config_size(d); + int i; + + for(i = 0; i < update->len && addr < config_size; val >>= 8, ++i, ++addr) { + uint8_t wmask = d->wmask[addr]; + d->config[addr] = (d->config[addr] & ~wmask) | (val & wmask); + } +} + +static inline int pci_config_changed(const struct pci_config_update *update, + uint32_t base, uint32_t end) +{ + uint32_t low = MAX(update->addr, base); + uint32_t high = MIN(update->addr + update->len, end); + + /* Check if [addr, addr + len) intersects [base, end). + The intersection is [low, high), so see if it's empty or not */ + if (low >= high) + return 0; + + return memcmp(update->orig + (low - update->addr), + update->d->config + low, + high - low); +} + +/* for convinience not to type symbol constant twice */ +static inline int pci_config_changed_with_size( + const struct pci_config_update *update, uint32_t base, uint32_t size) +{ + return pci_config_changed(update, base, base + size); +} + /* lsi53c895a.c */ #define LSI_MAX_DEVS 7