From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pf1-f175.google.com (mail-pf1-f175.google.com [209.85.210.175]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9CD791E889 for ; Sat, 27 Apr 2024 11:36:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.175 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714217815; cv=none; b=VnDW5ZC4C44WoEYA0TcHxD+ehsOOKNzMoAMRL8eoYqTUcJ53mhlSedQJxupTlvUBZQN6HSmcaEorEiEZ4CojzCpChT6fPHFiuLPOHPyPvLJBIwMvqkfYf8aoKXS2Sb+460/UAljHKEnkzQnPnWJxyUWLNXi4onb6DN447ZZdO7g= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714217815; c=relaxed/simple; bh=4ZrINV4KLgHRlvgk/hu79PRnd4meIKu7L4pWkSEktc4=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=RGkLze10l7x/xzzu7FlCckOhY0mEXBErLjbM44wR0Z8rJr7jWPguvT3cFNCTO8ohIMSEIlQ1tOQzRMZuqDkqzR3nRwMEgLu7A4dJHz6GS62HNGTmz/3ItG2S6fMWWzN/yTVIQKuvCfJrkx+942kzPFZpncez20D6GTW7Hg3jUxc= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org; spf=pass smtp.mailfrom=linaro.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b=UprG36up; arc=none smtp.client-ip=209.85.210.175 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linaro.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="UprG36up" Received: by mail-pf1-f175.google.com with SMTP id d2e1a72fcca58-6ed3cafd766so2805076b3a.0 for ; Sat, 27 Apr 2024 04:36:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1714217813; x=1714822613; darn=vger.kernel.org; h=in-reply-to:content-transfer-encoding:content-disposition :mime-version:references:message-id:subject:cc:to:from:date:from:to :cc:subject:date:message-id:reply-to; bh=Jp4hRN3U63+VTp/kbaxaSBNFon3bWbhJwCyaL1wC8dE=; b=UprG36upcSxmUcaOso/Qv5/e7kS9Aoi9uslK1U6aLKfMvkyxMxOL1ugL3aJGXaKj5P trmZ19yQw0KqHHPNy+4aH0z6l1vLyX0VYs8VFfLONaLHPjp5vQFMt6t0yMxNjnsA+xfG 6iQnyQkO31/q7hWWPNe8IVGekOCShLRokqUclF8FAkFHNOu/viwHGwrZ1FdMAmzNXWCd UNxU2y7EttbHBWIoqF89niBIpJ3bXr9L5wIFzKb1CqjBQF0eKbxFweDm/mKSNkpv1CEO 8t9mxoRj9npgiexXTwZ8dUT5CLklgtNIEhM6z5W7XCLZ1TQ7IFfPwc2j+qZwzn6VodZY bFuw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714217813; x=1714822613; h=in-reply-to:content-transfer-encoding:content-disposition :mime-version:references:message-id:subject:cc:to:from:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Jp4hRN3U63+VTp/kbaxaSBNFon3bWbhJwCyaL1wC8dE=; b=uPatRRgLu9gXCgM/cAt5HUKCct/eTZIQq95dOedR7u99b18/6/diERU3O0hHzOgGsQ Nh819nXR56LOVy/S/elph41zil4YgBhbVSjSlAM5KrMlqoTozLGrp7/Waee5a8GcRR7y KAo/xRByT1dyyynQT3BOWYJ7c3Alwf90dR93IzMsg7R+jALH7AjtuYXx0MkO6R+VS5EB LaxJszsH6M+iBrSaVQCWAyhtLnutNA3nkJcS3uOQfUqBmWNlnfWhp5bXsotghA8UDPyU qA3aej91OJ32TGXbZ/IrzSp6FhiVDDDN1Mo9z3UjtwPC0sUlEnpTjBLrBCO2Ji92iHpv u0IA== X-Forwarded-Encrypted: i=1; AJvYcCWBeU/usCetjLqoux6g4zKEi9SFz21GEFM9D2vpGLpbgrq9XlGB30grW+9CyAw5JWLjHu74X4dx25kcHfp2Bw/2AD2R X-Gm-Message-State: AOJu0Yxg9EzR5BRqgnKmLxSyFL01UDCBnn1RbdpSQ6iuG8/BnrBNjExF HqoNiaDqC83FFiUgY0qjpFRXEbF9wr1Jv6u/qmZw+80fR9jXyEfbGFDANL6FUQ== X-Google-Smtp-Source: AGHT+IFPz6Ruq5+jtEUhJad2ZGgPJk+uB6ynLPk+rZsXWFAqu91AklU9J738m/6o+4YI5RYMxlBsTg== X-Received: by 2002:a05:6a00:ace:b0:6e7:b3c4:43a4 with SMTP id c14-20020a056a000ace00b006e7b3c443a4mr6315088pfl.25.1714217812667; Sat, 27 Apr 2024 04:36:52 -0700 (PDT) Received: from thinkpad ([117.213.97.210]) by smtp.gmail.com with ESMTPSA id s6-20020aa78286000000b006f0aea608efsm15463745pfm.143.2024.04.27.04.36.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 27 Apr 2024 04:36:52 -0700 (PDT) Date: Sat, 27 Apr 2024 17:06:43 +0530 From: Manivannan Sadhasivam To: Frank Li Cc: Richard Zhu , Lucas Stach , Lorenzo Pieralisi , Krzysztof =?utf-8?Q?Wilczy=C5=84ski?= , Rob Herring , Bjorn Helgaas , Shawn Guo , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam , NXP Linux Team , Philipp Zabel , Liam Girdwood , Mark Brown , Krzysztof Kozlowski , Conor Dooley , linux-pci@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, devicetree@vger.kernel.org Subject: Re: [PATCH v3 08/11] PCI: imx: Config look up table(LUT) to support MSI ITS and IOMMU for i.MX95 Message-ID: <20240427113643.GM1981@thinkpad> References: <20240402-pci2_upstream-v3-0-803414bdb430@nxp.com> <20240402-pci2_upstream-v3-8-803414bdb430@nxp.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20240402-pci2_upstream-v3-8-803414bdb430@nxp.com> PCI: imx6: Add support for configuring BDF to SID mapping for i.MX95 On Tue, Apr 02, 2024 at 10:33:44AM -0400, Frank Li wrote: > i.MX95 need config LUT to convert bpf to stream id. IOMMU and ITS use the Did you mean BDF? Here and everywhere. > same stream id. Check msi-map and smmu-map and make sure the same PCI bpf > map to the same stream id. Then config LUT related registers. > These DT properties not documented in the binding. > Signed-off-by: Frank Li > --- > drivers/pci/controller/dwc/pcie-imx.c | 175 ++++++++++++++++++++++++++++++++++ > 1 file changed, 175 insertions(+) > > diff --git a/drivers/pci/controller/dwc/pcie-imx.c b/drivers/pci/controller/dwc/pcie-imx.c > index af0f960f28757..653d8e8ee1abc 100644 > --- a/drivers/pci/controller/dwc/pcie-imx.c > +++ b/drivers/pci/controller/dwc/pcie-imx.c > @@ -55,6 +55,22 @@ > #define IMX95_PE0_GEN_CTRL_3 0x1058 > #define IMX95_PCIE_LTSSM_EN BIT(0) > > +#define IMX95_PE0_LUT_ACSCTRL 0x1008 > +#define IMX95_PEO_LUT_RWA BIT(16) > +#define IMX95_PE0_LUT_ENLOC GENMASK(4, 0) > + > +#define IMX95_PE0_LUT_DATA1 0x100c > +#define IMX95_PE0_LUT_VLD BIT(31) > +#define IMX95_PE0_LUT_DAC_ID GENMASK(10, 8) > +#define IMX95_PE0_LUT_STREAM_ID GENMASK(5, 0) > + > +#define IMX95_PE0_LUT_DATA2 0x1010 > +#define IMX95_PE0_LUT_REQID GENMASK(31, 16) > +#define IMX95_PE0_LUT_MASK GENMASK(15, 0) > + > +#define IMX95_SID_MASK GENMASK(5, 0) > +#define IMX95_MAX_LUT 32 > + > #define to_imx_pcie(x) dev_get_drvdata((x)->dev) > > enum imx_pcie_variants { > @@ -217,6 +233,159 @@ static int imx95_pcie_init_phy(struct imx_pcie *imx_pcie) > return 0; > } > > +static int imx_pcie_update_lut(struct imx_pcie *imx_pcie, int index, u16 reqid, u16 mask, u8 sid) > +{ > + struct dw_pcie *pci = imx_pcie->pci; > + struct device *dev = pci->dev; > + u32 data1, data2; > + > + if (sid >= 64) { > + dev_err(dev, "Too big stream id: %d\n", sid); 'Invalid SID for index (%d): %d\n', index, sid > + return -EINVAL; > + } > + > + data1 = FIELD_PREP(IMX95_PE0_LUT_DAC_ID, 0); > + data1 |= FIELD_PREP(IMX95_PE0_LUT_STREAM_ID, sid); > + data1 |= IMX95_PE0_LUT_VLD; > + > + regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA1, data1); > + > + data2 = mask; > + data2 |= FIELD_PREP(IMX95_PE0_LUT_REQID, reqid); > + > + regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA2, data2); > + > + regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_ACSCTRL, index); > + > + return 0; > +} > + > +struct imx_of_map { imx_iommu_map > + u32 bdf; > + u32 phandle; > + u32 sid; > + u32 sid_len; > +}; > + > +static int imx_check_msi_and_smmmu(struct imx_pcie *imx_pcie, > + struct imx_of_map *msi_map, u32 msi_size, u32 msi_map_mask, > + struct imx_of_map *smmu_map, u32 smmu_size, u32 smmu_map_mask) > +{ > + struct dw_pcie *pci = imx_pcie->pci; > + struct device *dev = pci->dev; > + int i; > + if (!msi_map || !smmu_map) return 0; > + if (msi_map && smmu_map) { > + if (msi_size != smmu_size) > + return -EINVAL; > + if (msi_map_mask != smmu_map_mask) > + return -EINVAL; if (msi_size != smmu_size || msi_map_mask != smmu_map_mask) return -EINVAL; > + > + for (i = 0; i < msi_size / sizeof(*msi_map); i++) { > + if (msi_map->bdf != smmu_map->bdf) { > + dev_err(dev, "bdf setting is not match\n"); 'BDF mismatch between msi-map and iommu-map' > + return -EINVAL; > + } > + if ((msi_map->sid & IMX95_SID_MASK) != smmu_map->sid) { > + dev_err(dev, "sid setting is not match\n"); 'SID mismatch between msi-map and iommu-map' > + return -EINVAL; > + } > + if ((msi_map->sid_len & IMX95_SID_MASK) != smmu_map->sid_len) { > + dev_err(dev, "sid_len setting is not match\n"); 'SID length mismatch between msi-map and iommu-map' > + return -EINVAL; > + } > + } > + } > + > + return 0; > +} > + > +/* > + * Simple static config lut according to dts settings DAC index and stream ID used as a match result > + * of LUT pre-allocated and used by PCIes. > + * Please reword the above sentence. > + * Currently stream ID from 32-64 for PCIe. > + * 32-40: first PCI bus. > + * 40-48: second PCI bus. I believe this is an SoC specific info. So better not add it here. It belongs to DT. > + * > + * DAC_ID is index of TRDC.DAC index, start from 2 at iMX95. > + * ITS [pci(2bit): streamid(6bits)] > + * pci 0 is 0 > + * pci 1 is 3 > + */ > +static int imx_pcie_config_sid(struct imx_pcie *imx_pcie) > +{ > + struct imx_of_map *msi_map = NULL, *smmu_map = NULL, *cur; > + int i, j, lut_index, nr_map, msi_size = 0, smmu_size = 0; > + u32 msi_map_mask = 0xffff, smmu_map_mask = 0xffff; > + struct dw_pcie *pci = imx_pcie->pci; > + struct device *dev = pci->dev; > + u32 mask; > + int size; > + > + of_get_property(dev->of_node, "msi-map", &msi_size); > + if (msi_size) { You mentioned in the commit message that msi-map and iommu-map needs to be the same for this SoC. But here you are just ignoring the absence of 'msi-map' property. > + msi_map = devm_kzalloc(dev, msi_size, GFP_KERNEL); > + if (!msi_map) > + return -ENOMEM; > + > + if (of_property_read_u32_array(dev->of_node, "msi-map", (u32 *)msi_map, > + msi_size / sizeof(u32))) > + return -EINVAL; > + > + of_property_read_u32(dev->of_node, "msi-map-mask", &msi_map_mask); > + } > + > + cur = msi_map; > + size = msi_size; > + mask = msi_map_mask; > + > + of_get_property(dev->of_node, "iommu-map", &smmu_size); Same comment as above. > + if (smmu_size) { > + smmu_map = devm_kzalloc(dev, smmu_size, GFP_KERNEL); > + if (!smmu_map) > + return -ENOMEM; > + > + if (of_property_read_u32_array(dev->of_node, "iommu-map", (u32 *)smmu_map, > + smmu_size / sizeof(u32))) > + return -EINVAL; > + > + of_property_read_u32(dev->of_node, "iommu_map_mask", &smmu_map_mask); > + } > + > + if (imx_check_msi_and_smmmu(imx_pcie, msi_map, msi_size, msi_map_mask, > + smmu_map, smmu_size, smmu_map_mask)) > + return -EINVAL; > + Hmm, so you want to continue even if the 'msi-map' and 'iommu-map' properties don't exist i.e., for old platforms? > + if (!cur) { > + cur = smmu_map; > + size = smmu_size; > + mask = smmu_map_mask; > + } > + > + nr_map = size / (sizeof(*cur)); > + > + lut_index = 0; Just initialize it while defining itself. > + for (i = 0; i < nr_map; i++) { > + for (j = 0; j < cur->sid_len; j++) { > + imx_pcie_update_lut(imx_pcie, lut_index, cur->bdf + j, mask, > + (cur->sid + j) & IMX95_SID_MASK); > + lut_index++; > + } > + cur++; > + > + if (lut_index >= IMX95_MAX_LUT) { > + dev_err(dev, "its-map/iommu-map exceed HW limiation\n"); 'Too many msi-map/iommu-map entries' But I think you can just continue to use the allowed entries. > + return -EINVAL; > + } > + } > + > + devm_kfree(dev, smmu_map); > + devm_kfree(dev, msi_map); Please don't explicitly free the devm_ managed resources unless really needed. Else don't use devm_ at all. > + > + return 0; > +} > + > static void imx_pcie_configure_type(struct imx_pcie *imx_pcie) > { > const struct imx_pcie_drvdata *drvdata = imx_pcie->drvdata; > @@ -950,6 +1119,12 @@ static int imx_pcie_host_init(struct dw_pcie_rp *pp) > goto err_phy_off; > } > > + ret = imx_pcie_config_sid(imx_pcie); > + if (ret < 0) { > + dev_err(dev, "failed to config sid:%d\n", ret); 'Failed to config BDF to SID mapping: %d\n' - Mani -- மணிவண்ணன் சதாசிவம் From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D76A4C4345F for ; Sat, 27 Apr 2024 11:37:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:References: Message-ID:Subject:Cc:To:From:Date:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=jDhxuqqkmmASAG0+Od9xH35RRJesoL3QaFWpr2rKdII=; b=vbGBC3+exqd921 l/jN0tuFOIfs91Fpg2XWuS0qT9GZTDYHIiB7jnPl34hjIiyMyTbp/9ZpNrzMWsR3sN4cz0f/7xYIE TJorTOZQvSZ+KaSIThcYeZxbuW2OHkFAmJFLkwfFCH8tJ7L0hEqEYiZplH5RSgjJZisOG8IPar2GA 4/wkdcFwerErby89pz8dCC4jfm2UxIFKjV6XYvybgU9fArOeoa76RXo+YEUhBXdCWiR2+37TdNFBZ AJ0mh7qTmzu9u72WUuVCIcQViVq2dCfQ1tAP3GAMgTobT7xRz1YrvpNdrYhunYGvnk+fTZtpw/Qu7 bNTdQIhf/E8DB57LPIqQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1s0gMV-0000000FS9r-0Mzz; Sat, 27 Apr 2024 11:36:59 +0000 Received: from mail-pf1-x436.google.com ([2607:f8b0:4864:20::436]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1s0gMQ-0000000FS96-3xMW for linux-arm-kernel@lists.infradead.org; Sat, 27 Apr 2024 11:36:56 +0000 Received: by mail-pf1-x436.google.com with SMTP id d2e1a72fcca58-6ed3cafd766so2805080b3a.0 for ; Sat, 27 Apr 2024 04:36:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1714217813; x=1714822613; darn=lists.infradead.org; h=in-reply-to:content-transfer-encoding:content-disposition :mime-version:references:message-id:subject:cc:to:from:date:from:to :cc:subject:date:message-id:reply-to; bh=Jp4hRN3U63+VTp/kbaxaSBNFon3bWbhJwCyaL1wC8dE=; b=d3A8laZzYxijXxthG7Aaqff5IXZQKLZXU9vXQVJx6s17LwC4nFxQofaYieUruf3mHQ AQKRMsTW+jLiivlf5TfC9OCeAFCxGRsRFCnh5+9r+EzCUPBw9lRg9UG5kXhg1b4pxgMW pCNmT7VNp5UZm3P0MIJ/Wu9VCzIXU5pcqBxOFF1XntQezuUm7927X5P/0pzNdQvVWxUT +kImBmcid215mIF5Sfanu0DCnfiojDudmW6s3/x2581BbR74TtQ4Ppf0yaZtPWHDpy7k x4lhCjxf5kYPDDS9xoyhyYR2WMtqN9P0d9qQ6u66R4ot/obq0dK0dh8jlqazjYbw7BSW g6RA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714217813; x=1714822613; h=in-reply-to:content-transfer-encoding:content-disposition :mime-version:references:message-id:subject:cc:to:from:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Jp4hRN3U63+VTp/kbaxaSBNFon3bWbhJwCyaL1wC8dE=; b=bg4CneTCfM9jIoOtt+sjoRGZbwxMKEIiTLOkRNz/R9yN0wFnlhKVzYFuPnGQZdUGKT 3YJWtWkeKE+xSBnOud5gI4mjXT5GzwIe6TIU/1Q8b9LOWHpw7nb9LgPl1jftV21FLjQh +f9YQ6r884Bqxt685/RgwogcH8HKHaRMvG9wchgiu5o7oVUWqd+9g9t39tTgQoHK7GRn wBTofXL/D9UnrxHtezixHA4SQnag6q2rlokoNYb2DCoG1Pnud0qsELRJ3xFILN3PHTaB u63rVea8RP1C2f5d73Sdq+GswLWk9gWYtsq6n/f6baNLwQAkgitwF4vsZedexELQC1qF 1oSw== X-Forwarded-Encrypted: i=1; AJvYcCUML2v/6L3FR4nwemuNcF2TdunNAaFaF1xptonDy/ok63jf1NbMHLpZNG/VPnvpCBG8ZwQm0Be3ZhbPoBmSbsL8D5dCYn+V7PJUHbiQlVTYcB0vQmc= X-Gm-Message-State: AOJu0YyWOxUAZrzk3G8HG7zDG/SivGqfub7MpBnifR4cfEjFCquHNXUL a4IVrKps805/s5Hqbf5DmCha832Xs9eWq973T+VFaf/H8aLeRN0ah2327LEU+w== X-Google-Smtp-Source: AGHT+IFPz6Ruq5+jtEUhJad2ZGgPJk+uB6ynLPk+rZsXWFAqu91AklU9J738m/6o+4YI5RYMxlBsTg== X-Received: by 2002:a05:6a00:ace:b0:6e7:b3c4:43a4 with SMTP id c14-20020a056a000ace00b006e7b3c443a4mr6315088pfl.25.1714217812667; Sat, 27 Apr 2024 04:36:52 -0700 (PDT) Received: from thinkpad ([117.213.97.210]) by smtp.gmail.com with ESMTPSA id s6-20020aa78286000000b006f0aea608efsm15463745pfm.143.2024.04.27.04.36.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 27 Apr 2024 04:36:52 -0700 (PDT) Date: Sat, 27 Apr 2024 17:06:43 +0530 From: Manivannan Sadhasivam To: Frank Li Cc: Richard Zhu , Lucas Stach , Lorenzo Pieralisi , Krzysztof =?utf-8?Q?Wilczy=C5=84ski?= , Rob Herring , Bjorn Helgaas , Shawn Guo , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam , NXP Linux Team , Philipp Zabel , Liam Girdwood , Mark Brown , Krzysztof Kozlowski , Conor Dooley , linux-pci@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, devicetree@vger.kernel.org Subject: Re: [PATCH v3 08/11] PCI: imx: Config look up table(LUT) to support MSI ITS and IOMMU for i.MX95 Message-ID: <20240427113643.GM1981@thinkpad> References: <20240402-pci2_upstream-v3-0-803414bdb430@nxp.com> <20240402-pci2_upstream-v3-8-803414bdb430@nxp.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20240402-pci2_upstream-v3-8-803414bdb430@nxp.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240427_043655_096958_99169B0E X-CRM114-Status: GOOD ( 32.53 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org UENJOiBpbXg2OiBBZGQgc3VwcG9ydCBmb3IgY29uZmlndXJpbmcgQkRGIHRvIFNJRCBtYXBwaW5n IGZvciBpLk1YOTUKCk9uIFR1ZSwgQXByIDAyLCAyMDI0IGF0IDEwOjMzOjQ0QU0gLTA0MDAsIEZy YW5rIExpIHdyb3RlOgo+IGkuTVg5NSBuZWVkIGNvbmZpZyBMVVQgdG8gY29udmVydCBicGYgdG8g c3RyZWFtIGlkLiBJT01NVSBhbmQgSVRTIHVzZSB0aGUKCkRpZCB5b3UgbWVhbiBCREY/IEhlcmUg YW5kIGV2ZXJ5d2hlcmUuCgo+IHNhbWUgc3RyZWFtIGlkLiBDaGVjayBtc2ktbWFwIGFuZCBzbW11 LW1hcCBhbmQgbWFrZSBzdXJlIHRoZSBzYW1lIFBDSSBicGYKPiBtYXAgdG8gdGhlIHNhbWUgc3Ry ZWFtIGlkLiBUaGVuIGNvbmZpZyBMVVQgcmVsYXRlZCByZWdpc3RlcnMuCj4gCgpUaGVzZSBEVCBw cm9wZXJ0aWVzIG5vdCBkb2N1bWVudGVkIGluIHRoZSBiaW5kaW5nLgoKPiBTaWduZWQtb2ZmLWJ5 OiBGcmFuayBMaSA8RnJhbmsuTGlAbnhwLmNvbT4KPiAtLS0KPiAgZHJpdmVycy9wY2kvY29udHJv bGxlci9kd2MvcGNpZS1pbXguYyB8IDE3NSArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr KysrCj4gIDEgZmlsZSBjaGFuZ2VkLCAxNzUgaW5zZXJ0aW9ucygrKQo+IAo+IGRpZmYgLS1naXQg YS9kcml2ZXJzL3BjaS9jb250cm9sbGVyL2R3Yy9wY2llLWlteC5jIGIvZHJpdmVycy9wY2kvY29u dHJvbGxlci9kd2MvcGNpZS1pbXguYwo+IGluZGV4IGFmMGY5NjBmMjg3NTcuLjY1M2Q4ZThlZTFh YmMgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9wY2kvY29udHJvbGxlci9kd2MvcGNpZS1pbXguYwo+ ICsrKyBiL2RyaXZlcnMvcGNpL2NvbnRyb2xsZXIvZHdjL3BjaWUtaW14LmMKPiBAQCAtNTUsNiAr NTUsMjIgQEAKPiAgI2RlZmluZSBJTVg5NV9QRTBfR0VOX0NUUkxfMwkJCTB4MTA1OAo+ICAjZGVm aW5lIElNWDk1X1BDSUVfTFRTU01fRU4JCQlCSVQoMCkKPiAgCj4gKyNkZWZpbmUgSU1YOTVfUEUw X0xVVF9BQ1NDVFJMCQkJMHgxMDA4Cj4gKyNkZWZpbmUgSU1YOTVfUEVPX0xVVF9SV0EJCQlCSVQo MTYpCj4gKyNkZWZpbmUgSU1YOTVfUEUwX0xVVF9FTkxPQwkJCUdFTk1BU0soNCwgMCkKPiArCj4g KyNkZWZpbmUgSU1YOTVfUEUwX0xVVF9EQVRBMQkJCTB4MTAwYwo+ICsjZGVmaW5lIElNWDk1X1BF MF9MVVRfVkxECQkJQklUKDMxKQo+ICsjZGVmaW5lIElNWDk1X1BFMF9MVVRfREFDX0lECQkJR0VO TUFTSygxMCwgOCkKPiArI2RlZmluZSBJTVg5NV9QRTBfTFVUX1NUUkVBTV9JRAkJCUdFTk1BU0so NSwgMCkKPiArCj4gKyNkZWZpbmUgSU1YOTVfUEUwX0xVVF9EQVRBMgkJCTB4MTAxMAo+ICsjZGVm aW5lIElNWDk1X1BFMF9MVVRfUkVRSUQJCQlHRU5NQVNLKDMxLCAxNikKPiArI2RlZmluZSBJTVg5 NV9QRTBfTFVUX01BU0sJCQlHRU5NQVNLKDE1LCAwKQo+ICsKPiArI2RlZmluZSBJTVg5NV9TSURf TUFTSwkJCQlHRU5NQVNLKDUsIDApCj4gKyNkZWZpbmUgSU1YOTVfTUFYX0xVVAkJCQkzMgo+ICsK PiAgI2RlZmluZSB0b19pbXhfcGNpZSh4KQlkZXZfZ2V0X2RydmRhdGEoKHgpLT5kZXYpCj4gIAo+ ICBlbnVtIGlteF9wY2llX3ZhcmlhbnRzIHsKPiBAQCAtMjE3LDYgKzIzMywxNTkgQEAgc3RhdGlj IGludCBpbXg5NV9wY2llX2luaXRfcGh5KHN0cnVjdCBpbXhfcGNpZSAqaW14X3BjaWUpCj4gIAly ZXR1cm4gMDsKPiAgfQo+ICAKPiArc3RhdGljIGludCBpbXhfcGNpZV91cGRhdGVfbHV0KHN0cnVj dCBpbXhfcGNpZSAqaW14X3BjaWUsIGludCBpbmRleCwgdTE2IHJlcWlkLCB1MTYgbWFzaywgdTgg c2lkKQo+ICt7Cj4gKwlzdHJ1Y3QgZHdfcGNpZSAqcGNpID0gaW14X3BjaWUtPnBjaTsKPiArCXN0 cnVjdCBkZXZpY2UgKmRldiA9IHBjaS0+ZGV2Owo+ICsJdTMyIGRhdGExLCBkYXRhMjsKPiArCj4g KwlpZiAoc2lkID49IDY0KSB7Cj4gKwkJZGV2X2VycihkZXYsICJUb28gYmlnIHN0cmVhbSBpZDog JWRcbiIsIHNpZCk7CgonSW52YWxpZCBTSUQgZm9yIGluZGV4ICglZCk6ICVkXG4nLCBpbmRleCwg c2lkCgo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsJfQo+ICsKPiArCWRhdGExID0gRklFTERfUFJF UChJTVg5NV9QRTBfTFVUX0RBQ19JRCwgMCk7Cj4gKwlkYXRhMSB8PSBGSUVMRF9QUkVQKElNWDk1 X1BFMF9MVVRfU1RSRUFNX0lELCBzaWQpOwo+ICsJZGF0YTEgfD0gSU1YOTVfUEUwX0xVVF9WTEQ7 Cj4gKwo+ICsJcmVnbWFwX3dyaXRlKGlteF9wY2llLT5pb211eGNfZ3ByLCBJTVg5NV9QRTBfTFVU X0RBVEExLCBkYXRhMSk7Cj4gKwo+ICsJZGF0YTIgPSBtYXNrOwo+ICsJZGF0YTIgfD0gRklFTERf UFJFUChJTVg5NV9QRTBfTFVUX1JFUUlELCByZXFpZCk7Cj4gKwo+ICsJcmVnbWFwX3dyaXRlKGlt eF9wY2llLT5pb211eGNfZ3ByLCBJTVg5NV9QRTBfTFVUX0RBVEEyLCBkYXRhMik7Cj4gKwo+ICsJ cmVnbWFwX3dyaXRlKGlteF9wY2llLT5pb211eGNfZ3ByLCBJTVg5NV9QRTBfTFVUX0FDU0NUUkws IGluZGV4KTsKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RydWN0IGlteF9vZl9tYXAg ewoKaW14X2lvbW11X21hcAoKPiArCXUzMiBiZGY7Cj4gKwl1MzIgcGhhbmRsZTsKPiArCXUzMiBz aWQ7Cj4gKwl1MzIgc2lkX2xlbjsKPiArfTsKPiArCj4gK3N0YXRpYyBpbnQgaW14X2NoZWNrX21z aV9hbmRfc21tbXUoc3RydWN0IGlteF9wY2llICppbXhfcGNpZSwKPiArCQkJCSAgIHN0cnVjdCBp bXhfb2ZfbWFwICptc2lfbWFwLCB1MzIgbXNpX3NpemUsIHUzMiBtc2lfbWFwX21hc2ssCj4gKwkJ CQkgICBzdHJ1Y3QgaW14X29mX21hcCAqc21tdV9tYXAsIHUzMiBzbW11X3NpemUsIHUzMiBzbW11 X21hcF9tYXNrKQo+ICt7Cj4gKwlzdHJ1Y3QgZHdfcGNpZSAqcGNpID0gaW14X3BjaWUtPnBjaTsK PiArCXN0cnVjdCBkZXZpY2UgKmRldiA9IHBjaS0+ZGV2Owo+ICsJaW50IGk7Cj4gKwoKCWlmICgh bXNpX21hcCB8fCAhc21tdV9tYXApCgkJcmV0dXJuIDA7Cgo+ICsJaWYgKG1zaV9tYXAgJiYgc21t dV9tYXApIHsKPiArCQlpZiAobXNpX3NpemUgIT0gc21tdV9zaXplKQo+ICsJCQlyZXR1cm4gLUVJ TlZBTDsKPiArCQlpZiAobXNpX21hcF9tYXNrICE9IHNtbXVfbWFwX21hc2spCj4gKwkJCXJldHVy biAtRUlOVkFMOwoKCWlmIChtc2lfc2l6ZSAhPSBzbW11X3NpemUgfHwgbXNpX21hcF9tYXNrICE9 IHNtbXVfbWFwX21hc2spCgkJcmV0dXJuIC1FSU5WQUw7Cgo+ICsKPiArCQlmb3IgKGkgPSAwOyBp IDwgbXNpX3NpemUgLyBzaXplb2YoKm1zaV9tYXApOyBpKyspIHsKPiArCQkJaWYgKG1zaV9tYXAt PmJkZiAhPSBzbW11X21hcC0+YmRmKSB7Cj4gKwkJCQlkZXZfZXJyKGRldiwgImJkZiBzZXR0aW5n IGlzIG5vdCBtYXRjaFxuIik7CgonQkRGIG1pc21hdGNoIGJldHdlZW4gbXNpLW1hcCBhbmQgaW9t bXUtbWFwJwoKPiArCQkJCXJldHVybiAtRUlOVkFMOwo+ICsJCQl9Cj4gKwkJCWlmICgobXNpX21h cC0+c2lkICYgSU1YOTVfU0lEX01BU0spICE9IHNtbXVfbWFwLT5zaWQpIHsKPiArCQkJCWRldl9l cnIoZGV2LCAic2lkIHNldHRpbmcgaXMgbm90IG1hdGNoXG4iKTsKCidTSUQgbWlzbWF0Y2ggYmV0 d2VlbiBtc2ktbWFwIGFuZCBpb21tdS1tYXAnCgo+ICsJCQkJcmV0dXJuIC1FSU5WQUw7Cj4gKwkJ CX0KPiArCQkJaWYgKChtc2lfbWFwLT5zaWRfbGVuICYgSU1YOTVfU0lEX01BU0spICE9IHNtbXVf bWFwLT5zaWRfbGVuKSB7Cj4gKwkJCQlkZXZfZXJyKGRldiwgInNpZF9sZW4gc2V0dGluZyBpcyBu b3QgbWF0Y2hcbiIpOwoKJ1NJRCBsZW5ndGggIG1pc21hdGNoIGJldHdlZW4gbXNpLW1hcCBhbmQg aW9tbXUtbWFwJwoKPiArCQkJCXJldHVybiAtRUlOVkFMOwo+ICsJCQl9Cj4gKwkJfQo+ICsJfQo+ ICsKPiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ICsvKgo+ICsgKiBTaW1wbGUgc3RhdGljIGNvbmZp ZyBsdXQgYWNjb3JkaW5nIHRvIGR0cyBzZXR0aW5ncyBEQUMgaW5kZXggYW5kIHN0cmVhbSBJRCB1 c2VkIGFzIGEgbWF0Y2ggcmVzdWx0Cj4gKyAqIG9mIExVVCBwcmUtYWxsb2NhdGVkIGFuZCB1c2Vk IGJ5IFBDSWVzLgo+ICsgKgoKUGxlYXNlIHJld29yZCB0aGUgYWJvdmUgc2VudGVuY2UuCgo+ICsg KiBDdXJyZW50bHkgc3RyZWFtIElEIGZyb20gMzItNjQgZm9yIFBDSWUuCj4gKyAqIDMyLTQwOiBm aXJzdCBQQ0kgYnVzLgo+ICsgKiA0MC00ODogc2Vjb25kIFBDSSBidXMuCgpJIGJlbGlldmUgdGhp cyBpcyBhbiBTb0Mgc3BlY2lmaWMgaW5mby4gU28gYmV0dGVyIG5vdCBhZGQgaXQgaGVyZS4gSXQg YmVsb25ncyB0bwpEVC4KCj4gKyAqCj4gKyAqIERBQ19JRCBpcyBpbmRleCBvZiBUUkRDLkRBQyBp bmRleCwgc3RhcnQgZnJvbSAyIGF0IGlNWDk1Lgo+ICsgKiBJVFMgW3BjaSgyYml0KTogc3RyZWFt aWQoNmJpdHMpXQo+ICsgKglwY2kgMCBpcyAwCj4gKyAqCXBjaSAxIGlzIDMKPiArICovCj4gK3N0 YXRpYyBpbnQgaW14X3BjaWVfY29uZmlnX3NpZChzdHJ1Y3QgaW14X3BjaWUgKmlteF9wY2llKQo+ ICt7Cj4gKwlzdHJ1Y3QgaW14X29mX21hcCAqbXNpX21hcCA9IE5VTEwsICpzbW11X21hcCA9IE5V TEwsICpjdXI7Cj4gKwlpbnQgaSwgaiwgbHV0X2luZGV4LCBucl9tYXAsIG1zaV9zaXplID0gMCwg c21tdV9zaXplID0gMDsKPiArCXUzMiBtc2lfbWFwX21hc2sgPSAweGZmZmYsIHNtbXVfbWFwX21h c2sgPSAweGZmZmY7Cj4gKwlzdHJ1Y3QgZHdfcGNpZSAqcGNpID0gaW14X3BjaWUtPnBjaTsKPiAr CXN0cnVjdCBkZXZpY2UgKmRldiA9IHBjaS0+ZGV2Owo+ICsJdTMyIG1hc2s7Cj4gKwlpbnQgc2l6 ZTsKPiArCj4gKwlvZl9nZXRfcHJvcGVydHkoZGV2LT5vZl9ub2RlLCAibXNpLW1hcCIsICZtc2lf c2l6ZSk7Cj4gKwlpZiAobXNpX3NpemUpIHsKCllvdSBtZW50aW9uZWQgaW4gdGhlIGNvbW1pdCBt ZXNzYWdlIHRoYXQgbXNpLW1hcCBhbmQgaW9tbXUtbWFwIG5lZWRzIHRvIGJlIHRoZQpzYW1lIGZv ciB0aGlzIFNvQy4gQnV0IGhlcmUgeW91IGFyZSBqdXN0IGlnbm9yaW5nIHRoZSBhYnNlbmNlIG9m ICdtc2ktbWFwJwpwcm9wZXJ0eS4KCj4gKwkJbXNpX21hcCA9IGRldm1fa3phbGxvYyhkZXYsIG1z aV9zaXplLCBHRlBfS0VSTkVMKTsKPiArCQlpZiAoIW1zaV9tYXApCj4gKwkJCXJldHVybiAtRU5P TUVNOwo+ICsKPiArCQlpZiAob2ZfcHJvcGVydHlfcmVhZF91MzJfYXJyYXkoZGV2LT5vZl9ub2Rl LCAibXNpLW1hcCIsICh1MzIgKiltc2lfbWFwLAo+ICsJCQkJCSAgICAgICBtc2lfc2l6ZSAvIHNp emVvZih1MzIpKSkKPiArCQkJcmV0dXJuIC1FSU5WQUw7Cj4gKwo+ICsJCW9mX3Byb3BlcnR5X3Jl YWRfdTMyKGRldi0+b2Zfbm9kZSwgIm1zaS1tYXAtbWFzayIsICZtc2lfbWFwX21hc2spOwo+ICsJ fQo+ICsKPiArCWN1ciA9IG1zaV9tYXA7Cj4gKwlzaXplID0gbXNpX3NpemU7Cj4gKwltYXNrID0g bXNpX21hcF9tYXNrOwo+ICsKPiArCW9mX2dldF9wcm9wZXJ0eShkZXYtPm9mX25vZGUsICJpb21t dS1tYXAiLCAmc21tdV9zaXplKTsKClNhbWUgY29tbWVudCBhcyBhYm92ZS4KCj4gKwlpZiAoc21t dV9zaXplKSB7Cj4gKwkJc21tdV9tYXAgPSBkZXZtX2t6YWxsb2MoZGV2LCBzbW11X3NpemUsIEdG UF9LRVJORUwpOwo+ICsJCWlmICghc21tdV9tYXApCj4gKwkJCXJldHVybiAtRU5PTUVNOwo+ICsK PiArCQlpZiAob2ZfcHJvcGVydHlfcmVhZF91MzJfYXJyYXkoZGV2LT5vZl9ub2RlLCAiaW9tbXUt bWFwIiwgKHUzMiAqKXNtbXVfbWFwLAo+ICsJCQkJCSAgICAgICBzbW11X3NpemUgLyBzaXplb2Yo dTMyKSkpCj4gKwkJCXJldHVybiAtRUlOVkFMOwo+ICsKPiArCQlvZl9wcm9wZXJ0eV9yZWFkX3Uz MihkZXYtPm9mX25vZGUsICJpb21tdV9tYXBfbWFzayIsICZzbW11X21hcF9tYXNrKTsKPiArCX0K PiArCj4gKwlpZiAoaW14X2NoZWNrX21zaV9hbmRfc21tbXUoaW14X3BjaWUsIG1zaV9tYXAsIG1z aV9zaXplLCBtc2lfbWFwX21hc2ssCj4gKwkJCQkgICAgIHNtbXVfbWFwLCBzbW11X3NpemUsIHNt bXVfbWFwX21hc2spKQo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsKCkhtbSwgc28geW91IHdhbnQg dG8gY29udGludWUgZXZlbiBpZiB0aGUgJ21zaS1tYXAnIGFuZCAnaW9tbXUtbWFwJyBwcm9wZXJ0 aWVzCmRvbid0IGV4aXN0IGkuZS4sIGZvciBvbGQgcGxhdGZvcm1zPwoKPiArCWlmICghY3VyKSB7 Cj4gKwkJY3VyID0gc21tdV9tYXA7Cj4gKwkJc2l6ZSA9IHNtbXVfc2l6ZTsKPiArCQltYXNrID0g c21tdV9tYXBfbWFzazsKPiArCX0KPiArCj4gKwlucl9tYXAgPSBzaXplIC8gKHNpemVvZigqY3Vy KSk7Cj4gKwo+ICsJbHV0X2luZGV4ID0gMDsKCkp1c3QgaW5pdGlhbGl6ZSBpdCB3aGlsZSBkZWZp bmluZyBpdHNlbGYuCgo+ICsJZm9yIChpID0gMDsgaSA8IG5yX21hcDsgaSsrKSB7Cj4gKwkJZm9y IChqID0gMDsgaiA8IGN1ci0+c2lkX2xlbjsgaisrKSB7Cj4gKwkJCWlteF9wY2llX3VwZGF0ZV9s dXQoaW14X3BjaWUsIGx1dF9pbmRleCwgY3VyLT5iZGYgKyBqLCBtYXNrLAo+ICsJCQkJCSAgICAo Y3VyLT5zaWQgKyBqKSAmIElNWDk1X1NJRF9NQVNLKTsKPiArCQkJbHV0X2luZGV4Kys7Cj4gKwkJ fQo+ICsJCWN1cisrOwo+ICsKPiArCQlpZiAobHV0X2luZGV4ID49IElNWDk1X01BWF9MVVQpIHsK PiArCQkJZGV2X2VycihkZXYsICJpdHMtbWFwL2lvbW11LW1hcCBleGNlZWQgSFcgbGltaWF0aW9u XG4iKTsKCidUb28gbWFueSBtc2ktbWFwL2lvbW11LW1hcCBlbnRyaWVzJwoKQnV0IEkgdGhpbmsg eW91IGNhbiBqdXN0IGNvbnRpbnVlIHRvIHVzZSB0aGUgYWxsb3dlZCBlbnRyaWVzLgoKPiArCQkJ cmV0dXJuIC1FSU5WQUw7Cj4gKwkJfQo+ICsJfQo+ICsKPiArCWRldm1fa2ZyZWUoZGV2LCBzbW11 X21hcCk7Cj4gKwlkZXZtX2tmcmVlKGRldiwgbXNpX21hcCk7CgpQbGVhc2UgZG9uJ3QgZXhwbGlj aXRseSBmcmVlIHRoZSBkZXZtXyBtYW5hZ2VkIHJlc291cmNlcyB1bmxlc3MgcmVhbGx5IG5lZWRl ZC4KRWxzZSBkb24ndCB1c2UgZGV2bV8gYXQgYWxsLgoKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ ICsKPiAgc3RhdGljIHZvaWQgaW14X3BjaWVfY29uZmlndXJlX3R5cGUoc3RydWN0IGlteF9wY2ll ICppbXhfcGNpZSkKPiAgewo+ICAJY29uc3Qgc3RydWN0IGlteF9wY2llX2RydmRhdGEgKmRydmRh dGEgPSBpbXhfcGNpZS0+ZHJ2ZGF0YTsKPiBAQCAtOTUwLDYgKzExMTksMTIgQEAgc3RhdGljIGlu dCBpbXhfcGNpZV9ob3N0X2luaXQoc3RydWN0IGR3X3BjaWVfcnAgKnBwKQo+ICAJCWdvdG8gZXJy X3BoeV9vZmY7Cj4gIAl9Cj4gIAo+ICsJcmV0ID0gaW14X3BjaWVfY29uZmlnX3NpZChpbXhfcGNp ZSk7Cj4gKwlpZiAocmV0IDwgMCkgewo+ICsJCWRldl9lcnIoZGV2LCAiZmFpbGVkIHRvIGNvbmZp ZyBzaWQ6JWRcbiIsIHJldCk7CgonRmFpbGVkIHRvIGNvbmZpZyBCREYgdG8gU0lEIG1hcHBpbmc6 ICVkXG4nCgotIE1hbmkKCi0tIArgrq7grqPgrr/grrXgrqPgr43grqPgrqngr40g4K6a4K6k4K6+ 4K6a4K6/4K614K6u4K+NCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fXwpsaW51eC1hcm0ta2VybmVsIG1haWxpbmcgbGlzdApsaW51eC1hcm0ta2VybmVsQGxp c3RzLmluZnJhZGVhZC5vcmcKaHR0cDovL2xpc3RzLmluZnJhZGVhZC5vcmcvbWFpbG1hbi9saXN0 aW5mby9saW51eC1hcm0ta2VybmVsCg==