From patchwork Thu Oct 12 12:18:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= X-Patchwork-Id: 732470 Delivered-To: patch@linaro.org Received: by 2002:a5d:54d1:0:b0:31d:da82:a3b4 with SMTP id x17csp916917wrv; Thu, 12 Oct 2023 05:20:34 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHwFCg0WcNSG/muyGTYZJU0XPTR9rp7CqYoP59u72dJcEdDYTsuJe/OAtjnA7HUkNI9DADZ X-Received: by 2002:a05:620a:1a0d:b0:773:ca55:e836 with SMTP id bk13-20020a05620a1a0d00b00773ca55e836mr27392599qkb.8.1697113233976; Thu, 12 Oct 2023 05:20:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1697113233; cv=none; d=google.com; s=arc-20160816; b=blGhpSP58xl9Hhv1hxNScoxD1hD3RfqeMYMYaGjEqAR0rlt6IsPRgDneWaDWnDHrVP j/3Esuyf9EQV5dF/dXqMubOdGT1UUoc1xNCOpahhkqSMmW8hK1qsJmNDyqFdntJFeBcx 9zpVZY6GAmLP+GJ78uRzJO5ew3oHwPYs674bvthrIkmjYOwEi9Q3e0WM+vQFcEqZAh4U YFLecKPeJaOPOJg2ZX86/Pg20ufpxIc0BjR/9Pn+2pmUJmLa/fpx++/gb+QO6mUfAMC1 7TbwRKQXPdaR+VWE8k3W1Aq/LCA9loejXelpjU+jOrAEbpjvO6bkVF5SfHxLAsnIPj4W S1Dg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=vwJ45+LzAe2ikUIZ7U1vT0BShidVUnLgV99Ux1OJYV8=; fh=uMYo3jOuXUsDthaXCE4/M6n3+voY5rtHQA7Grzg1cYU=; b=gOMqrFTObihR7cG3Kz1slekWz0mxUwW55ReEVQ6gu+0k57rzZwG2O3ezq+sBdB/+R9 jcl7tnVZ+Nu47z9IkwwPJvzeE9mOZ6c8VQKzX3g/DjPfw1eQx/VW8m5YrpK+Vig30pD6 dSuCESyhhxMcw1CZJfVsES7h/4zGbrPtHFptyRev732Hx51Ldn3/5nUIcq4Yy7XibIyX WZAACFJbny0NxofsqoClNmDKIaf59W4fFYzwjxfJrq6GyQJFS+GFPPKt/DwhA0MvaVTG ce0Rl2YQF3yRDX51uly4/MvH/MoyNLcfFL/Q1Y34gHdXSp8WUVk/gIKoDHXXO5DHaqlS T4eA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="T/GtfZCe"; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id s4-20020a05620a030400b007758878b8edsi10308999qkm.557.2023.10.12.05.20.33 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 12 Oct 2023 05:20:33 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="T/GtfZCe"; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qqufW-0003nB-St; Thu, 12 Oct 2023 08:19:58 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qqufU-0003af-6R for qemu-devel@nongnu.org; Thu, 12 Oct 2023 08:19:57 -0400 Received: from mail-ed1-x531.google.com ([2a00:1450:4864:20::531]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qqufS-0001uJ-42 for qemu-devel@nongnu.org; Thu, 12 Oct 2023 08:19:55 -0400 Received: by mail-ed1-x531.google.com with SMTP id 4fb4d7f45d1cf-53e08b60febso1093460a12.1 for ; Thu, 12 Oct 2023 05:19:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1697113191; x=1697717991; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=vwJ45+LzAe2ikUIZ7U1vT0BShidVUnLgV99Ux1OJYV8=; b=T/GtfZCe4cU2YZc80xbTcw1Fy8+WmbCOBpkvBdwjGz9ikp08ThDn8peZCEfY10tJGj uSbE11v8fPnIvMbMKBHMNUc9BH1fQscgoGvgMZTadULxKsKMyUBcJjtRTW7v3Pan55S/ m4whQzEsPMBvkPAeiXrTDiUvezycDvx6ejCIuqgJIgww+SV5IFW5BggjcJTQzpkY6MIm FwrpEZhut3paaMsAjHd4b/uZ06VWd9bErUQgsxzI0/3kHB+6VnOj39UDeYOOQIs6lPOV MIYdeA90rOz6znLpKLmI3BQYgL376i1WAL8DH2JAat5O/hDSr2H6/ccXs2akhTBG8FLc 4o5A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697113191; x=1697717991; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=vwJ45+LzAe2ikUIZ7U1vT0BShidVUnLgV99Ux1OJYV8=; b=Yh++Tshh3vO35iHbLWLWC00W9Fuhm0NnI9fGP9uLSIO3KE35E2IXr0OlGGqag3XouC 4mY4LFAdtkh8cumFlsNTZlbuAPP9u6pV3xKd2wH/yF+A99L3TQ01rbcVLBAewujEiqDg 0VSQJIrG2xZz2InSsqcTlyuPylzqv1dmAmSlBDxtvZFVKr7XYZFwsrQScf8PHf/Vpcdk 1M/1sV6exfHzhlhiOxNGTySQQOXdpotNsAL0wg982wGFRVd/HBHPW9DqBUm7cUSP1MgX 2cttmtgI3EfA+5fBPhcnp7BakyeVz17ts0bjzJrYxGK7fVcLvhB6TD9MskN0ZJbcnihG tIvQ== X-Gm-Message-State: AOJu0YwZqOQPBfV2kSL9MJBFk4tJvL1uS2WSE0rSxyNty5LXcPM0BNDR lFvgh6hXZSDhKWtM0kj2Ep5k0EUyxm3f7Vn1fhcUhQ== X-Received: by 2002:a05:6402:699:b0:522:3a89:a7bc with SMTP id f25-20020a056402069900b005223a89a7bcmr17242908edy.42.1697113191434; Thu, 12 Oct 2023 05:19:51 -0700 (PDT) Received: from m1x-phil.lan (176-131-211-232.abo.bbox.fr. [176.131.211.232]) by smtp.gmail.com with ESMTPSA id c25-20020aa7d619000000b0053622a35665sm9929836edr.66.2023.10.12.05.19.50 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Thu, 12 Oct 2023 05:19:50 -0700 (PDT) From: =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= To: qemu-devel@nongnu.org Cc: Andrey Smirnov , qemu-arm@nongnu.org, Peter Maydell , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= Subject: [PATCH 8/8] hw/pci-host/designware: Create ViewPorts during host bridge realization Date: Thu, 12 Oct 2023 14:18:56 +0200 Message-ID: <20231012121857.31873-9-philmd@linaro.org> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231012121857.31873-1-philmd@linaro.org> References: <20231012121857.31873-1-philmd@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::531; envelope-from=philmd@linaro.org; helo=mail-ed1-x531.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: qemu-devel-bounces+patch=linaro.org@nongnu.org ViewPorts are managed by the host bridge part, so create them when the host bridge is realized. The host bridge become the owner of the memory regions. The PCI root function realize() method now only contains PCI specific code. Signed-off-by: Philippe Mathieu-Daudé --- hw/pci-host/designware.c | 207 +++++++++++++++++++-------------------- 1 file changed, 102 insertions(+), 105 deletions(-) diff --git a/hw/pci-host/designware.c b/hw/pci-host/designware.c index 6cb8655a75..e5dc9b4b8d 100644 --- a/hw/pci-host/designware.c +++ b/hw/pci-host/designware.c @@ -384,22 +384,10 @@ static char *designware_pcie_viewport_name(const char *direction, static void designware_pcie_root_realize(PCIDevice *dev, Error **errp) { DesignwarePCIERoot *root = DESIGNWARE_PCIE_ROOT(dev); - DesignwarePCIEHost *host = DESIGNWARE_PCIE_HOST( - qdev_get_parent_bus(DEVICE(dev))->parent); - MemoryRegion *host_mem = get_system_memory(); - MemoryRegion *address_space = &host->pci.memory; PCIBridge *br = PCI_BRIDGE(dev); - DesignwarePCIEViewport *viewport; - /* - * Dummy values used for initial configuration of MemoryRegions - * that belong to a given viewport - */ - const hwaddr dummy_offset = 0; - const uint64_t dummy_size = 4; - size_t i; br->bus_name = "dw-pcie"; - root->host = host; + root->host = DESIGNWARE_PCIE_HOST(qdev_get_parent_bus(DEVICE(dev))->parent); pci_set_word(dev->config + PCI_COMMAND, PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); @@ -414,97 +402,6 @@ static void designware_pcie_root_realize(PCIDevice *dev, Error **errp) msi_nonbroken = true; msi_init(dev, 0x50, 32, true, true, &error_fatal); - - for (i = 0; i < DESIGNWARE_PCIE_NUM_VIEWPORTS; i++) { - MemoryRegion *source, *destination, *mem; - const char *direction; - char *name; - - viewport = &host->viewports[DESIGNWARE_PCIE_VIEWPORT_INBOUND][i]; - viewport->inbound = true; - viewport->base = 0x0000000000000000ULL; - viewport->target = 0x0000000000000000ULL; - viewport->limit = UINT32_MAX; - viewport->cr[0] = DESIGNWARE_PCIE_ATU_TYPE_MEM; - - source = &host->pci.address_space_root; - destination = host_mem; - direction = "Inbound"; - - /* - * Configure MemoryRegion implementing PCI -> CPU memory - * access - */ - mem = &viewport->mem; - name = designware_pcie_viewport_name(direction, i, "MEM"); - memory_region_init_alias(mem, OBJECT(root), name, destination, - dummy_offset, dummy_size); - memory_region_add_subregion_overlap(source, dummy_offset, mem, -1); - memory_region_set_enabled(mem, false); - g_free(name); - - viewport = &host->viewports[DESIGNWARE_PCIE_VIEWPORT_OUTBOUND][i]; - viewport->host = host; - viewport->inbound = false; - viewport->base = 0x0000000000000000ULL; - viewport->target = 0x0000000000000000ULL; - viewport->limit = UINT32_MAX; - viewport->cr[0] = DESIGNWARE_PCIE_ATU_TYPE_MEM; - - destination = &host->pci.memory; - direction = "Outbound"; - source = host_mem; - - /* - * Configure MemoryRegion implementing CPU -> PCI memory - * access - */ - mem = &viewport->mem; - name = designware_pcie_viewport_name(direction, i, "MEM"); - memory_region_init_alias(mem, OBJECT(root), name, destination, - dummy_offset, dummy_size); - memory_region_add_subregion(source, dummy_offset, mem); - memory_region_set_enabled(mem, false); - g_free(name); - - /* - * Configure MemoryRegion implementing access to configuration - * space - */ - mem = &viewport->cfg; - name = designware_pcie_viewport_name(direction, i, "CFG"); - memory_region_init_io(&viewport->cfg, OBJECT(root), - &designware_pci_host_conf_ops, - viewport, name, dummy_size); - memory_region_add_subregion(source, dummy_offset, mem); - memory_region_set_enabled(mem, false); - g_free(name); - } - - /* - * If no inbound iATU windows are configured, HW defaults to - * letting inbound TLPs to pass in. We emulate that by explicitly - * configuring first inbound window to cover all of target's - * address space. - * - * NOTE: This will not work correctly for the case when first - * configured inbound window is window 0 - */ - viewport = &host->viewports[DESIGNWARE_PCIE_VIEWPORT_INBOUND][0]; - viewport->cr[1] = DESIGNWARE_PCIE_ATU_ENABLE; - designware_pcie_update_viewport(root, viewport); - - memory_region_init_io(&host->msi.iomem, OBJECT(root), - &designware_pci_host_msi_ops, - root, "pcie-msi", 0x4); - /* - * We initially place MSI interrupt I/O region at address 0 and - * disable it. It'll be later moved to correct offset and enabled - * in designware_pcie_root_update_msi_mapping() as a part of - * initialization done by guest OS - */ - memory_region_add_subregion(address_space, dummy_offset, &host->msi.iomem); - memory_region_set_enabled(&host->msi.iomem, false); } static void designware_pcie_set_irq(void *opaque, int irq_num, int level) @@ -590,7 +487,7 @@ static void designware_pcie_root_class_init(ObjectClass *klass, void *data) dc->reset = pci_bridge_reset; /* * PCI-facing part of the host bridge, not usable without the - * host-facing part, which can't be device_add'ed, yet. + * host-facing part. */ dc->user_creatable = false; dc->vmsd = &vmstate_designware_pcie_root; @@ -650,8 +547,17 @@ static void designware_pcie_host_realize(DeviceState *dev, Error **errp) PCIHostState *pci = PCI_HOST_BRIDGE(dev); DesignwarePCIEHost *s = DESIGNWARE_PCIE_HOST(dev); SysBusDevice *sbd = SYS_BUS_DEVICE(dev); + MemoryRegion *host_mem = get_system_memory(); + DesignwarePCIEViewport *viewport; size_t i; + /* + * Dummy values used for initial configuration of MemoryRegions + * that belong to a given viewport + */ + const hwaddr dummy_offset = 0; + const uint64_t dummy_size = 4; + for (i = 0; i < ARRAY_SIZE(s->pci.irqs); i++) { sysbus_init_irq(sbd, &s->pci.irqs[i]); } @@ -694,6 +600,97 @@ static void designware_pcie_host_realize(DeviceState *dev, Error **errp) qdev_prop_set_int32(DEVICE(&s->root), "addr", PCI_DEVFN(0, 0)); qdev_prop_set_bit(DEVICE(&s->root), "multifunction", false); qdev_realize(DEVICE(&s->root), BUS(pci->bus), &error_fatal); + + memory_region_init_io(&s->msi.iomem, OBJECT(s), + &designware_pci_host_msi_ops, + s, "pcie-msi", 0x4); + /* + * We initially place MSI interrupt I/O region at address 0 and + * disable it. It'll be later moved to correct offset and enabled + * in designware_pcie_host_update_msi_mapping() as a part of + * initialization done by guest OS + */ + memory_region_add_subregion(&s->pci.memory, dummy_offset, &s->msi.iomem); + memory_region_set_enabled(&s->msi.iomem, false); + + for (i = 0; i < DESIGNWARE_PCIE_NUM_VIEWPORTS; i++) { + MemoryRegion *source, *destination, *mem; + const char *direction; + char *name; + + viewport = &s->viewports[DESIGNWARE_PCIE_VIEWPORT_INBOUND][i]; + viewport->inbound = true; + viewport->base = 0x0000000000000000ULL; + viewport->target = 0x0000000000000000ULL; + viewport->limit = UINT32_MAX; + viewport->cr[0] = DESIGNWARE_PCIE_ATU_TYPE_MEM; + + source = &s->pci.address_space_root; + destination = host_mem; + direction = "Inbound"; + + /* + * Configure MemoryRegion implementing PCI -> CPU memory + * access + */ + mem = &viewport->mem; + name = designware_pcie_viewport_name(direction, i, "MEM"); + memory_region_init_alias(mem, OBJECT(s), name, destination, + dummy_offset, dummy_size); + memory_region_add_subregion_overlap(source, dummy_offset, mem, -1); + memory_region_set_enabled(mem, false); + g_free(name); + + viewport = &s->viewports[DESIGNWARE_PCIE_VIEWPORT_OUTBOUND][i]; + viewport->host = s; + viewport->inbound = false; + viewport->base = 0x0000000000000000ULL; + viewport->target = 0x0000000000000000ULL; + viewport->limit = UINT32_MAX; + viewport->cr[0] = DESIGNWARE_PCIE_ATU_TYPE_MEM; + + destination = &s->pci.memory; + direction = "Outbound"; + source = host_mem; + + /* + * Configure MemoryRegion implementing CPU -> PCI memory + * access + */ + mem = &viewport->mem; + name = designware_pcie_viewport_name(direction, i, "MEM"); + memory_region_init_alias(mem, OBJECT(s), name, destination, + dummy_offset, dummy_size); + memory_region_add_subregion(source, dummy_offset, mem); + memory_region_set_enabled(mem, false); + g_free(name); + + /* + * Configure MemoryRegion implementing access to configuration + * space + */ + mem = &viewport->cfg; + name = designware_pcie_viewport_name(direction, i, "CFG"); + memory_region_init_io(&viewport->cfg, OBJECT(s), + &designware_pci_host_conf_ops, + viewport, name, dummy_size); + memory_region_add_subregion(source, dummy_offset, mem); + memory_region_set_enabled(mem, false); + g_free(name); + } + + /* + * If no inbound iATU windows are configured, HW defaults to + * letting inbound TLPs to pass in. We emulate that by explicitly + * configuring first inbound window to cover all of target's + * address space. + * + * NOTE: This will not work correctly for the case when first + * configured inbound window is window 0 + */ + viewport = &s->viewports[DESIGNWARE_PCIE_VIEWPORT_INBOUND][0]; + viewport->cr[1] = DESIGNWARE_PCIE_ATU_ENABLE; + designware_pcie_update_viewport(&s->root, viewport); } static const VMStateDescription vmstate_designware_pcie_host = {