From patchwork Tue Oct 19 09:06:36 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Isaku Yamahata X-Patchwork-Id: 68297 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 DF32AB70D5 for ; Tue, 19 Oct 2010 20:52:35 +1100 (EST) Received: from localhost ([127.0.0.1]:49722 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1P88rv-0006pr-Qj for incoming@patchwork.ozlabs.org; Tue, 19 Oct 2010 05:52:31 -0400 Received: from [140.186.70.92] (port=55873 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1P889x-0002d9-3h for qemu-devel@nongnu.org; Tue, 19 Oct 2010 05:07:14 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1P889i-0006Na-PU for qemu-devel@nongnu.org; Tue, 19 Oct 2010 05:07:04 -0400 Received: from mail.valinux.co.jp ([210.128.90.3]:32862) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1P889i-0006Mk-49 for qemu-devel@nongnu.org; Tue, 19 Oct 2010 05:06:50 -0400 Received: from ps.local.valinux.co.jp (vagw.valinux.co.jp [210.128.90.14]) by mail.valinux.co.jp (Postfix) with SMTP id D256D873C4; Tue, 19 Oct 2010 18:06:43 +0900 (JST) Received: (nullmailer pid 27267 invoked by uid 1000); Tue, 19 Oct 2010 09:06:41 -0000 From: Isaku Yamahata To: qemu-devel@nongnu.org Date: Tue, 19 Oct 2010 18:06:36 +0900 Message-Id: <00559fa88be06e8c14f173cad086230736e1d2d2.1287478251.git.yamahata@valinux.co.jp> X-Mailer: git-send-email 1.7.1.1 In-Reply-To: References: In-Reply-To: References: X-Virus-Scanned: clamav-milter 0.95.2 at va-mail.local.valinux.co.jp X-Virus-Status: Clean X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) Cc: skandasa@cisco.com, adnan@khaleel.us, wexu2@cisco.com, mst@redhat.com, yamahata@valinux.co.jp, etmartin@cisco.com Subject: [Qemu-devel] [PATCH v5 09/14] pcie port: define struct PCIEPort/PCIESlot and helper functions 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 define struct PCIEPort which represents common part of pci express port.(root, upstream and downstream.) add a helper function for pcie port which can be used commonly by root/upstream/downstream port. define struct PCIESlot which represents common part of pcie slot.(root and downstream.) and helper functions for it. helper functions for chassis, slot -> PCIESlot conversion. Signed-off-by: Isaku Yamahata --- Changes v4 -> v5: - use pci_xxx_test_and_xxx_mask() Changes v3 -> v4: - Initialize prefetchable memory base/limit registers correctly. They must support 64bit. - compilation adjustment. Changes v2 -> v3: - static'fy chassis. - compilation adjustment. --- Makefile.objs | 2 +- hw/pcie_port.c | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ hw/pcie_port.h | 51 ++++++++++++++++++++++++ qemu-common.h | 2 + 4 files changed, 170 insertions(+), 1 deletions(-) create mode 100644 hw/pcie_port.c create mode 100644 hw/pcie_port.h diff --git a/Makefile.objs b/Makefile.objs index 68bcc48..6c3b84a 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -186,7 +186,7 @@ hw-obj-$(CONFIG_PIIX4) += piix4.o # PCI watchdog devices hw-obj-y += wdt_i6300esb.o -hw-obj-y += pcie.o pcie_aer.o +hw-obj-y += pcie.o pcie_aer.o pcie_port.o hw-obj-y += msix.o msi.o # PCI network cards diff --git a/hw/pcie_port.c b/hw/pcie_port.c new file mode 100644 index 0000000..117de61 --- /dev/null +++ b/hw/pcie_port.c @@ -0,0 +1,116 @@ +/* + * pcie_port.c + * + * Copyright (c) 2010 Isaku Yamahata + * VA Linux Systems Japan K.K. + * + * 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, see . + */ + +#include "pcie_port.h" + +void pcie_port_init_reg(PCIDevice *d) +{ + /* Unlike pci bridge, + 66MHz and fast back to back don't apply to pci express port. */ + pci_set_word(d->config + PCI_STATUS, 0); + pci_set_word(d->config + PCI_SEC_STATUS, 0); + + /* 7.5.3.5 Prefetchable Memory Base Limit + * The Prefetchable Memory Base and Prefetchable Memory Limit registers + * must indicate that 64-bit addresses are supported, as defined in + * PCI-to-PCI Bridge Architecture Specification, Revision 1.2. + */ + pci_word_test_and_set_mask(d->config + PCI_PREF_MEMORY_BASE, + PCI_PREF_RANGE_TYPE_64); + pci_word_test_and_set_mask(d->config + PCI_PREF_MEMORY_LIMIT, + PCI_PREF_RANGE_TYPE_64); +} + +/************************************************************************** + * (chassis number, pcie physical slot number) -> pcie slot conversion + */ +struct PCIEChassis { + uint8_t number; + + QLIST_HEAD(, PCIESlot) slots; + QLIST_ENTRY(PCIEChassis) next; +}; + +static QLIST_HEAD(, PCIEChassis) chassis = QLIST_HEAD_INITIALIZER(chassis); + +static struct PCIEChassis *pcie_chassis_find(uint8_t chassis_number) +{ + struct PCIEChassis *c; + QLIST_FOREACH(c, &chassis, next) { + if (c->number == chassis_number) { + break; + } + } + return c; +} + +void pcie_chassis_create(uint8_t chassis_number) +{ + struct PCIEChassis *c; + c = pcie_chassis_find(chassis_number); + if (c) { + return; + } + c = qemu_mallocz(sizeof(*c)); + c->number = chassis_number; + QLIST_INIT(&c->slots); + QLIST_INSERT_HEAD(&chassis, c, next); +} + +static PCIESlot *pcie_chassis_find_slot_with_chassis(struct PCIEChassis *c, + uint8_t slot) +{ + PCIESlot *s; + QLIST_FOREACH(s, &c->slots, next) { + if (s->slot == slot) { + break; + } + } + return s; +} + +PCIESlot *pcie_chassis_find_slot(uint8_t chassis_number, uint16_t slot) +{ + struct PCIEChassis *c; + c = pcie_chassis_find(chassis_number); + if (!c) { + return NULL; + } + return pcie_chassis_find_slot_with_chassis(c, slot); +} + +int pcie_chassis_add_slot(struct PCIESlot *slot) +{ + struct PCIEChassis *c; + c = pcie_chassis_find(slot->chassis); + if (!c) { + return -ENODEV; + } + if (pcie_chassis_find_slot_with_chassis(c, slot->slot)) { + return -EBUSY; + } + QLIST_INSERT_HEAD(&c->slots, slot, next); + return 0; +} + +void pcie_chassis_del_slot(PCIESlot *s) +{ + QLIST_REMOVE(s, next); +} diff --git a/hw/pcie_port.h b/hw/pcie_port.h new file mode 100644 index 0000000..3709583 --- /dev/null +++ b/hw/pcie_port.h @@ -0,0 +1,51 @@ +/* + * pcie_port.h + * + * Copyright (c) 2010 Isaku Yamahata + * VA Linux Systems Japan K.K. + * + * 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, see . + */ + +#ifndef QEMU_PCIE_PORT_H +#define QEMU_PCIE_PORT_H + +#include "pci_bridge.h" +#include "pci_internals.h" + +struct PCIEPort { + PCIBridge br; + + /* pci express switch port */ + uint8_t port; +}; + +void pcie_port_init_reg(PCIDevice *d); + +struct PCIESlot { + PCIEPort port; + + /* pci express switch port with slot */ + uint8_t chassis; + uint16_t slot; + QLIST_ENTRY(PCIESlot) next; +}; + +void pcie_chassis_create(uint8_t chassis_number); +void pcie_main_chassis_create(void); +PCIESlot *pcie_chassis_find_slot(uint8_t chassis, uint16_t slot); +int pcie_chassis_add_slot(struct PCIESlot *slot); +void pcie_chassis_del_slot(PCIESlot *s); + +#endif /* QEMU_PCIE_PORT_H */ diff --git a/qemu-common.h b/qemu-common.h index 94b2c11..63ee8c3 100644 --- a/qemu-common.h +++ b/qemu-common.h @@ -224,6 +224,8 @@ typedef struct PCIBridge PCIBridge; typedef struct PCIEAERMsg PCIEAERMsg; typedef struct PCIEAERLog PCIEAERLog; typedef struct PCIEAERErr PCIEAERErr; +typedef struct PCIEPort PCIEPort; +typedef struct PCIESlot PCIESlot; typedef struct SerialState SerialState; typedef struct IRQState *qemu_irq; typedef struct PCMCIACardState PCMCIACardState;