From patchwork Tue Jul 10 13:47:04 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Kardashevskiy X-Patchwork-Id: 170186 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id C18EC2C0207 for ; Tue, 10 Jul 2012 23:48:12 +1000 (EST) Received: from localhost ([::1]:45979 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SoanS-0003jC-LQ for incoming@patchwork.ozlabs.org; Tue, 10 Jul 2012 09:48:10 -0400 Received: from eggs.gnu.org ([208.118.235.92]:53154) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Soamn-0002H7-4u for qemu-devel@nongnu.org; Tue, 10 Jul 2012 09:47:35 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Soamg-0001EG-Ur for qemu-devel@nongnu.org; Tue, 10 Jul 2012 09:47:28 -0400 Received: from mail-pb0-f45.google.com ([209.85.160.45]:52125) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Soamg-0001Cd-Of for qemu-devel@nongnu.org; Tue, 10 Jul 2012 09:47:22 -0400 Received: by mail-pb0-f45.google.com with SMTP id ro12so336197pbb.4 for ; Tue, 10 Jul 2012 06:47:21 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :x-gm-message-state; bh=o0rU+oUYE3040NXmxA+TwFfp/u8/vFdBwmThwGWUn3I=; b=CLSwaxURn6+usTEOPrW0usNnFshp9drgirMXDn+jyMlvn9G5SiWefZZqzxknb+H0Fp vMT6GWFCuJkoipOLoMEKLBsT5GIt3YkBuHGVeMEI6DHFKh3XhOGW9lQch5J8YvtOHmgf KvKgzmWakfnNlBzjWwYU0u9amyKF5KVKmbcKq1HNf6TMHXm6w9bR/0/THcVuFxqztzkR rEKXCtSFqQbRx9O1P/ZcTE5qpjpeS6FetO+jxlDw7lBOvpqb/KLS+syDW9oF4q5ES272 0eD8GE20SOmDa2XX8jGoIrugFMlH/7esnw4FHdvI35dctB3TvjDYhl+GBJGubsJZZOJJ XChw== Received: by 10.68.227.198 with SMTP id sc6mr69272629pbc.138.1341928041654; Tue, 10 Jul 2012 06:47:21 -0700 (PDT) Received: from ka1.ozlabs.ibm.com (ibmaus65.lnk.telstra.net. [165.228.126.9]) by mx.google.com with ESMTPS id nv6sm29910038pbc.42.2012.07.10.06.47.19 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 10 Jul 2012 06:47:21 -0700 (PDT) From: Alexey Kardashevskiy To: Date: Tue, 10 Jul 2012 23:47:04 +1000 Message-Id: <1341928025-5669-3-git-send-email-aik@ozlabs.ru> X-Mailer: git-send-email 1.7.10 In-Reply-To: <1341928025-5669-1-git-send-email-aik@ozlabs.ru> References: <1341928025-5669-1-git-send-email-aik@ozlabs.ru> X-Gm-Message-State: ALoCoQmiSZUL1/D25+/QFzhmPlvPd5VuGAvy0pwB5ntVmTG7EOgudJ4Uzt5BE70B9irgNKm16v7n X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.160.45 Cc: Alexey Kardashevskiy , qemu-devel@nongnu.org, Alexander Graf , qemu-ppc@nongnu.org, David Gibson Subject: [Qemu-devel] [PATCH 2/3] pseries pci: added memory window for MSI/MSIX vectors X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org As any other PHB, the one in sPAPR has to implement addresses which to be used as MSI/MSIX vectors. It also needs to provide a mechanism to retrieve IRQs number for subsequent qemu_irq_pulse(). This patch includes: 1. A "config_space_address to msi_table" map to provide IRQ resolving from config-address as MSI RTAS calls take a PCI config space address as an identifier. 2. A MSIX memory region is added to catch msi_notify()/msix_notiry() from virtio-pci and pass them to the guest via qemu_irq_pulse(). Signed-off-by: Alexey Kardashevskiy --- hw/spapr.c | 4 +++- hw/spapr_pci.c | 43 ++++++++++++++++++++++++++++++++++++++++++- hw/spapr_pci.h | 10 +++++++++- 3 files changed, 54 insertions(+), 3 deletions(-) diff --git a/hw/spapr.c b/hw/spapr.c index af3f479..37f6026 100644 --- a/hw/spapr.c +++ b/hw/spapr.c @@ -80,6 +80,7 @@ #define SPAPR_PCI_MEM_WIN_ADDR (0x10000000000ULL + 0xA0000000) #define SPAPR_PCI_MEM_WIN_SIZE 0x20000000 #define SPAPR_PCI_IO_WIN_ADDR (0x10000000000ULL + 0x80000000) +#define SPAPR_PCI_MSI_WIN_ADDR (0x10000000000ULL + 0x90000000) #define PHANDLE_XICP 0x00001111 @@ -768,7 +769,8 @@ static void ppc_spapr_init(ram_addr_t ram_size, spapr_create_phb(spapr, "pci", SPAPR_PCI_BUID, SPAPR_PCI_MEM_WIN_ADDR, SPAPR_PCI_MEM_WIN_SIZE, - SPAPR_PCI_IO_WIN_ADDR); + SPAPR_PCI_IO_WIN_ADDR, + SPAPR_PCI_MSI_WIN_ADDR); for (i = 0; i < nb_nics; i++) { NICInfo *nd = &nd_table[i]; diff --git a/hw/spapr_pci.c b/hw/spapr_pci.c index ff742ef..650d847 100644 --- a/hw/spapr_pci.c +++ b/hw/spapr_pci.c @@ -24,6 +24,7 @@ */ #include "hw.h" #include "pci.h" +#include "msi.h" #include "pci_host.h" #include "hw/spapr.h" #include "hw/spapr_pci.h" @@ -280,6 +281,33 @@ static const MemoryRegionOps spapr_io_ops = { }; /* + * MSI/MSIX memory region implementation. + * The handler handles both MSI and MSIX. + * For MSI-X, the vector number is encoded as a part of the address, + * data is set to 0. + * For MSI, the vector number is encoded in least bits in data. + */ +static void spapr_msi_write(void *opaque, target_phys_addr_t addr, + uint64_t data, unsigned size) +{ + sPAPRPHBState *phb = opaque; + int ndev = addr >> 16; + int vec = ((addr & 0xFFFF) >> 2) | data; + uint32_t dt_irq = phb->msi_table[ndev].dt_irq + vec; + + trace_spapr_pci_msi_write(addr, data, dt_irq); + + qemu_irq_pulse(xics_assign_irq(spapr->icp, dt_irq, XICS_MSI)); +} + +static const MemoryRegionOps spapr_msi_ops = { + /* There is no .read as the read result is undefined by PCI spec */ + .read = NULL, + .write = spapr_msi_write, + .endianness = DEVICE_LITTLE_ENDIAN +}; + +/* * PHB PCI device */ static DMAContext *spapr_pci_dma_context_fn(PCIBus *bus, void *opaque, @@ -329,6 +357,17 @@ static int spapr_phb_init(SysBusDevice *s) memory_region_add_subregion(get_system_memory(), phb->io_win_addr, &phb->iowindow); + /* As MSI/MSIX interrupts trigger by writing at MSI/MSIX vectors, + * we need to allocate some memory to catch those writes coming + * from msi_notify()/msix_notify() */ + if (msi_supported) { + sprintf(namebuf, "%s.msi", phb->dtbusname); + memory_region_init_io(&phb->msiwindow, &spapr_msi_ops, phb, + namebuf, SPAPR_MSIX_MAX_DEVS * 0x10000); + memory_region_add_subregion(get_system_memory(), phb->msi_win_addr, + &phb->msiwindow); + } + bus = pci_register_bus(&phb->host_state.busdev.qdev, phb->busname ? phb->busname : phb->dtbusname, pci_spapr_set_irq, NULL, pci_spapr_map_irq, phb, @@ -362,6 +401,7 @@ static Property spapr_phb_properties[] = { DEFINE_PROP_HEX64("mem_win_size", sPAPRPHBState, mem_win_size, 0x20000000), DEFINE_PROP_HEX64("io_win_addr", sPAPRPHBState, io_win_addr, 0), DEFINE_PROP_HEX64("io_win_size", sPAPRPHBState, io_win_size, 0x10000), + DEFINE_PROP_HEX64("msi_win_addr", sPAPRPHBState, msi_win_addr, 0), DEFINE_PROP_END_OF_LIST(), }; @@ -384,7 +424,7 @@ static TypeInfo spapr_phb_info = { void spapr_create_phb(sPAPREnvironment *spapr, const char *busname, uint64_t buid, uint64_t mem_win_addr, uint64_t mem_win_size, - uint64_t io_win_addr) + uint64_t io_win_addr, uint64_t msi_win_addr) { DeviceState *dev; @@ -397,6 +437,7 @@ void spapr_create_phb(sPAPREnvironment *spapr, qdev_prop_set_uint64(dev, "mem_win_addr", mem_win_addr); qdev_prop_set_uint64(dev, "mem_win_size", mem_win_size); qdev_prop_set_uint64(dev, "io_win_addr", io_win_addr); + qdev_prop_set_uint64(dev, "msi_win_addr", msi_win_addr); qdev_init_nofail(dev); } diff --git a/hw/spapr_pci.h b/hw/spapr_pci.h index e54809a..145071c 100644 --- a/hw/spapr_pci.h +++ b/hw/spapr_pci.h @@ -27,6 +27,8 @@ #include "hw/pci_host.h" #include "hw/xics.h" +#define SPAPR_MSIX_MAX_DEVS 32 + typedef struct sPAPRPHBState { PCIHostState host_state; @@ -49,6 +51,12 @@ typedef struct sPAPRPHBState { uint32_t dt_irq; } lsi_table[PCI_NUM_PINS]; + struct { + uint32_t config_addr; + uint32_t dt_irq; + int nvec; + } msi_table[SPAPR_MSIX_MAX_DEVS]; + QLIST_ENTRY(sPAPRPHBState) list; } sPAPRPHBState; @@ -58,7 +66,7 @@ typedef struct sPAPRPHBState { void spapr_create_phb(sPAPREnvironment *spapr, const char *busname, uint64_t buid, uint64_t mem_win_addr, uint64_t mem_win_size, - uint64_t io_win_addr); + uint64_t io_win_addr, uint64_t msi_win_addr); int spapr_populate_pci_dt(sPAPRPHBState *phb, uint32_t xics_phandle,