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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D773CC433F5 for ; Thu, 20 Jan 2022 19:08:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1377400AbiATTId (ORCPT ); Thu, 20 Jan 2022 14:08:33 -0500 Received: from ams.source.kernel.org ([145.40.68.75]:40022 "EHLO ams.source.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1346936AbiATTIc (ORCPT ); Thu, 20 Jan 2022 14:08:32 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 21913B81E2D; Thu, 20 Jan 2022 19:08:31 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 81313C340E0; Thu, 20 Jan 2022 19:08:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1642705709; bh=SSw+nMmX8JglpTPwJ3g4vpCvPSa5IL311wRyPrz7B1o=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=OGuw1qX0yKUNnipHwSs+tFlxWSk85V4sr77ePA6GSKZOqjYNNCMoHH3d3+OdmZg0X udvA0J+ZDZCGi0gv3/cTEO6BDRu11d891nFh9rBeQGH7+fut7w1BLxJ5w2fQfrY0G6 aEIS9EyCILn/AcjIWRF0eS3LyqAPm+rR5lN5Y6yB9YLvMnkfzM5MmiBDKpDTnu5p/g N1erb8R4uzZ/uUoLeWCb+iTiWhRQ4Gen+QKaSV2vuewuLiWqII2WL33uxZ5KyCpDJ0 cWSBEXlmHEfM0uY/2jmnPYKSsnooD6AF9fEv3dEFpuzChd0/tYI+RQ9voiXFrY8aLH p+XBpgaAINkhw== Received: by pali.im (Postfix) id D266A791; Thu, 20 Jan 2022 20:08:26 +0100 (CET) Date: Thu, 20 Jan 2022 20:08:26 +0100 From: Pali =?utf-8?B?Um9ow6Fy?= To: Bjorn Helgaas Cc: Thomas Petazzoni , Lorenzo Pieralisi , Rob Herring , Krzysztof =?utf-8?Q?Wilczy=C5=84ski?= , Bjorn Helgaas , Marek =?utf-8?B?QmVow7pu?= , linux-pci@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH 08/15] PCI: mvebu: Propagate errors when updating PCI_IO_BASE and PCI_MEM_BASE registers Message-ID: <20220120190826.wkhkcx53lmafq2yp@pali> References: <20220113103523.5usmja7bp44f7ju7@pali> <20220120175047.GA1050722@bhelgaas> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20220120175047.GA1050722@bhelgaas> User-Agent: NeoMutt/20180716 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thursday 20 January 2022 11:50:47 Bjorn Helgaas wrote: > On Thu, Jan 13, 2022 at 11:35:23AM +0100, Pali Rohár wrote: > > On Wednesday 12 January 2022 18:19:21 Bjorn Helgaas wrote: > > > On Sat, Jan 08, 2022 at 12:46:58AM +0100, Pali Rohár wrote: > > > > On Friday 07 January 2022 17:16:17 Bjorn Helgaas wrote: > > > > > On Fri, Jan 07, 2022 at 11:28:26PM +0100, Pali Rohár wrote: > > > > > > On Friday 07 January 2022 15:55:04 Bjorn Helgaas wrote: > > > > > > > On Thu, Nov 25, 2021 at 01:45:58PM +0100, Pali Rohár wrote: > > > > > > > > Properly propagate failure from mvebu_pcie_add_windows() > > > > > > > > function back to the caller > > > > > > > > mvebu_pci_bridge_emul_base_conf_write() and correctly > > > > > > > > updates PCI_IO_BASE, PCI_MEM_BASE and > > > > > > > > PCI_IO_BASE_UPPER16 registers on error. On error set > > > > > > > > base value higher than limit value which indicates that > > > > > > > > address range is disabled. > > > > > > > > > > > > > > Does the spec say that if software programs something > > > > > > > invalid, hardware should proactively set the base and > > > > > > > limit registers to disable the window? > > > > > > > > > > > > No. But this patch address something totally different. > > > > > > Software can do fully valid operation, e.g. try to set > > > > > > forwarding memory window as large as possible. But because > > > > > > this driver "emulates" pci bridge by calling software/kernel > > > > > > function (mvebu_pcie_add_windows), some operations which in > > > > > > real HW cannot happen, are possible in software. > > > > > > > > > > > > For example there are limitations in sizes of forwarding > > > > > > memory windows, because it is done by mvebu-mbus driver, > > > > > > which is responsible for configuring mapping and forwarding > > > > > > of PCIe I/O and MEM windows. And due to Marvell HW, there > > > > > > are restrictions which are not in PCIe HW. > > > > > > > > > > > > Currently if such error happens, obviously kernel is not > > > > > > able to set PCIe windows and it just print warnings to > > > > > > dmesg. Trying to access these windows would result in the > > > > > > worst case in crashes. > > > > > > > > > > > > With this change when mvebu_pcie_add_windows() function > > > > > > fails then into emulated config space is put information > > > > > > that particular forwarding window is disabled. I think that > > > > > > it is better to indicate it in config space what is the > > > > > > current "reality" of hardware configuration. If window is > > > > > > disabled in real-HW (meaning in mvebu-mbus driver) then show > > > > > > it also in emulated config space of pci bridge. > > > > > > > > > > > > Do you have better idea what should emulated pci bridge do, > > > > > > if software try to set fully valid configuration of > > > > > > forwarding window, but it is not possible to achieve it > > > > > > (even compliant PCI bridge must be able to do it)? > > > > > > > > > > On an ACPI system, the host bridge window sizes are > > > > > constrained by the host bridge _CRS method. I assume there's > > > > > a similar constraint in DT. > > > > > > > > > > Is the fact that mvebu_pcie_add_windows() can fail a symptom > > > > > of a DT that describes more available space than mvebu-bus can > > > > > map? > > > > > > > > Memory maps for mvebu are more complicated. There is no explicit > > > > size in DT ranges property as it is dynamically allocated by > > > > mvebu-mbus: > > > > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm/boot/dts/armada-385.dtsi?h=v5.15#n47 > > > > > > I wish I knew how to really interpret those "ranges" properties. > > > (Is there a good description in Documentation/ somewhere? All > > > I've found so far is https://elinux.org/Device_Tree_Usage, which > > > is good, but doesn't match this example completely.) > > > > > > I see: > > > > > > pciec: pcie { > > > ranges = <...>; > > > pcie1: pcie@1,0 { > > > ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 > > > 0x81000000 0 0 0x81000000 0x1 0 1 0>; > > > }; > > > pcie2: pcie@2,0 { > > > ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0 > > > 0x81000000 0 0 0x81000000 0x2 0 1 0>; > > > }; > > > pcie3: pcie@3,0 { > > > ranges = <0x82000000 0 0 0x82000000 0x3 0 1 0 > > > 0x81000000 0 0 0x81000000 0x3 0 1 0>; > > > }; > > > pcie4: pcie@4,0 { > > > ranges = <0x82000000 0 0 0x82000000 0x4 0 1 0 > > > 0x81000000 0 0 0x81000000 0x4 0 1 0>; > > > }; > > > }; > > > > > > What does this look like in dmesg, i.e., what CPU address ranges are > > > mapped to what PCI bus addresses? > > > > These explicit ranges in DT are probably ignored as they are invalid. > > You can see them (0xffffffffffffffff) in dmesg. > > Are you saying that this DT ranges and the dmesg line are connected? > > ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 > 0x81000000 0 0 0x81000000 0x1 0 1 0>; > > mvebu-pcie soc:pcie: MEM 0xffffffffffffffff..0x00fffffffe -> 0x0100000000 > > 1) It would be nice if there were a hint somewhere in Documentation/ > that would allow mere mortals to see the connection there. I agree, that there is missing lot of documentation related to Marvell PCIe controllers, both pci-mvebu.c and pci-aardvark.c. The main problem now is that it is hard to find information which explain everything... like mysterious Memory Controller (which is now explained): https://lore.kernel.org/linux-pci/20211003120944.3lmwxylnhlp2kfj7@pali/ > 2) Why do we have these DT entries if they are invalid and useless? Sorry, I do not know. I was not involved during introducing of DT files for this platform. I'm just observing how it works... > > MEM and I/O resources are parsed in pci-mvebu.c driver in > > mvebu_pcie_parse_request_resources() function. > > So mvebu-mbus.c fills in the static mbus_state from the DT > "pcie-mem-aperture", which seems unconnected to the DT descriptions of > the PCI controllers: > > static struct mvebu_mbus_state mbus_state; > > mvebu_mbus_dt_init > mvebu_mbus_get_pcie_resources(&mbus_state.pcie_mem_aperture) > of_property_read_u32_array("pcie-mem-aperture") > > mvebu_pcie_probe > mvebu_pcie_parse_request_resources > mvebu_mbus_get_pcie_mem_aperture(&pcie->mem) > *res = mbus_state.pcie_mem_aperture > pci_add_resource(&bridge->windows, &pcie->mem) > > > Here is relevant dmesg output: > > > > mvebu-pcie soc:pcie: host bridge /soc/pcie ranges: > > mvebu-pcie soc:pcie: MEM 0x00f1080000..0x00f1081fff -> 0x0000080000 > > mvebu-pcie soc:pcie: MEM 0x00f1040000..0x00f1041fff -> 0x0000040000 > > mvebu-pcie soc:pcie: MEM 0x00f1044000..0x00f1045fff -> 0x0000044000 > > mvebu-pcie soc:pcie: MEM 0x00f1048000..0x00f1049fff -> 0x0000048000 > > mvebu-pcie soc:pcie: MEM 0xffffffffffffffff..0x00fffffffe -> 0x0100000000 > > mvebu-pcie soc:pcie: IO 0xffffffffffffffff..0x00fffffffe -> 0x0100000000 > > mvebu-pcie soc:pcie: MEM 0xffffffffffffffff..0x00fffffffe -> 0x0200000000 > > mvebu-pcie soc:pcie: IO 0xffffffffffffffff..0x00fffffffe -> 0x0200000000 > > mvebu-pcie soc:pcie: MEM 0xffffffffffffffff..0x00fffffffe -> 0x0300000000 > > mvebu-pcie soc:pcie: IO 0xffffffffffffffff..0x00fffffffe -> 0x0300000000 > > mvebu-pcie soc:pcie: MEM 0xffffffffffffffff..0x00fffffffe -> 0x0400000000 > > mvebu-pcie soc:pcie: IO 0xffffffffffffffff..0x00fffffffe -> 0x0400000000 > > mvebu-pcie soc:pcie: PCI host bridge to bus 0000:00 > > pci_bus 0000:00: root bus resource [bus 00-ff] > > pci_bus 0000:00: root bus resource [mem 0xf1080000-0xf1081fff] (bus address [0x00080000-0x00081fff]) > > pci_bus 0000:00: root bus resource [mem 0xf1040000-0xf1041fff] (bus address [0x00040000-0x00041fff]) > > pci_bus 0000:00: root bus resource [mem 0xf1044000-0xf1045fff] (bus address [0x00044000-0x00045fff]) > > pci_bus 0000:00: root bus resource [mem 0xf1048000-0xf1049fff] (bus address [0x00048000-0x00049fff]) > > pci_bus 0000:00: root bus resource [mem 0xe0000000-0xe7ffffff] > > I see 0xf1080000-0xf1081fff, 0xf1040000-0xf1041fff, etc mentioned in > the DT info above, but I don't see where [mem 0xe0000000-0xe7ffffff] > came from. 0xe0000000 is defined in above mentioned "pcie-mem-aperture" DT property and it is in armada-38x.dtsi DTS file included from armada-385.dtsi: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm/boot/dts/armada-38x.dtsi?h=v5.15#n42 > Regardless, this means PCI thinks [mem 0xe0000000-0xe7ffffff] is > available on bus 00 and can be assigned to devices on bus 00 according > to the normal PCI rules (BARs aligned on size, PCI bridge windows > aligned on 1MB and multiple of 1MB in size). IIUC, mvebu imposes > additional alignment constraints on the bridge windows. > > These are the bridge window assignments from your dmesg: > > > pci 0000:00:01.0: BAR 8: assigned [mem 0xe0000000-0xe00fffff] > > pci 0000:00:02.0: BAR 8: assigned [mem 0xe0200000-0xe04fffff] > > pci 0000:00:03.0: BAR 8: assigned [mem 0xe0100000-0xe01fffff] > > > pci 0000:00:01.0: PCI bridge to [bus 01] > > pci 0000:00:01.0: bridge window [mem 0xe0000000-0xe00fffff] > > pci 0000:00:02.0: PCI bridge to [bus 02] > > pci 0000:00:02.0: bridge window [mem 0xe0200000-0xe04fffff] > > pci 0000:00:03.0: PCI bridge to [bus 03] > > pci 0000:00:03.0: bridge window [mem 0xe0100000-0xe01fffff] > > The PCI core knows nothing about the mvebu constraints. Are we just > lucky here that when PCI assigned these bridge windows, they happen to > be supported on mvebu? What happens if PCI decides it needs 29MB on > bus 01? In this case pci-mvebu.c split 29MB window into continuous ranges of power of two (16MB + 8MB + 4MB + 1MB) and then register each range to mbus slot. Code is in function mvebu_pcie_add_windows(): https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/pci/controller/pci-mvebu.c?h=v5.15#n300 So at the end there is continuous space of 29MB PCIe window, just it "eats" 4 mbus slots. This function may fail (if there is not enough free mbus slots) and this patch is propagating that failure back to the caller. > > > Are pcie1, pcie2, etc Root Ports? Or are they each separate host > > > bridges (they each have "bus-range = <0x00 0xff>")? > > > > From kernel point of view they are root ports. But in reality every of > > these root port is on separate bus segment, but kernel pci-mvebu.c > > driver merges all these segments/domains into one host bridge and put > > all root ports into bus 0. > > > > Here is lspci -tvnn output with topology: > > > > $ lspci -tvnn > > -[0000:00]-+-01.0-[01]----00.0 Device [1e0f:0001] > > +-02.0-[02]----00.0 Qualcomm Atheros QCA986x/988x 802.11ac Wireless Network Adapter [168c:003c] > > \-03.0-[03]----00.0 Qualcomm Atheros AR9287 Wireless Network Adapter (PCI-Express) [168c:002e] > > > Buses 1, 2 and 3 represents mPCIe cards, all of them are in reality > > in separate bus segments and on different HW host bridges. So they > > do *not* share access to config space, do *not* share INTx > > interrupts, etc... > > > > > Is space from pciec dynamically assigned to pcie1, pcie2, etc? If > > > so, I assume there are more restrictions on the size and alignment > > > than on PCI bridge windows, which allow size/alignment down to > > > 1MB? > > > > Yes, exactly. I do not know now all restrictions. At least there are > > fixed number of memory slots and each has to be of size 2^N. They > > are dynamically assigned by kernel mbus driver at time when somebody > > updates BASE/LIMIT registers. And that kernel mbus driver takes care > > to split non-aligned window size to more slots of size 2^N. And > > resources are shared from pool with other HW parts (e.g. DMA), so > > other drivers loaded in kernel can "eat" available slots before > > pci-mvebu and then there does not have to be nothing to allocate for > > PCI. > > So IIUC, > > pcie1 == 00:01.0 Root Port > pcie2 == 00:02.0 Root Port > pcie3 == 00:03.0 Root Port > > From a software point of view, they're all under a single host bridge, > and Linux assumes everything under a host bridge plays by the PCI > rules. Yes. > In this case, the root ports *don't* play by the rules since they have > additional alignment restrictions, so I think these really should be > described as separate host bridges in DT with the address space > carved up statically among them. I fully agree with you. But pci-mvebu.c driver and also its DT bindings are written differently. Changing it probably would not be simple due to backward compatibility and will take development resources... > It's common on x86 to have multiple host bridges that all appear to > software to be in domain 0000. The bus number ranges under each are > static, e.g., one bridge has [bus 00-7f] and another has [bus 80-ff]. For mvebu they are dynamic and kernel assigns them at boot. As my above printed lspci topology is simple, first bridge has assigned [bus 01-01], second bridge [bus 02-02] and third bridge [bus 03-03]. > > But most Armada boards do not have exported all peripherals from SoC, > > unconnected are disabled in DT and therefore exhaustion should not > > happen. > > > > > I'm trying to see how this could be described in ACPI because that's a > > > fairly general model that accommodates most machines. Possibly > > > describing mvebu in ACPI would involve losing some flexibility. > > > > I do not understand APCI model very well and I'm in impression that it > > is impossible to represent mvebu in ACPI. > > It could be described as a separate host bridge for every root port. > ACPI uses _CRS (current resource settings) to describe the apertures > to PCI and any address translation. Currently the _CRS description is > static, but ACPI does allow those resource assignments to be modified > via _PRS (possible resource settings) and _SRS (set resource > settings). > > Bjorn 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 3C78EC433F5 for ; Thu, 20 Jan 2022 19:09:53 +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=1noVXC69mu1h3NwMhycgryO0m00BzRmTbHBjhRHwbnk=; b=xSrBldy7Wq6VIh 3yqLyX5wD2TP9bSlD0cXWLyYCMNCNepGdZ2rvflIa+9o/Pi963WeHitggTAwhmgqaQ2elAuCafrMl mPeZEgMgHzVcZI43E6qQ+1LeICHcm6dLEf5CgeiqeHGJa7ql9s2QBFvCAiADVSD8K7dhPAOSoJWlU jBat//iI5JdmeGxTbpP72QcHNPCCuLQldaBYE0mYhUUwWdwGK8hiED/1VGjWBhCmmwIJmOKosdWNa xKTkxno5fTKBO6adlUlzJcu9aLwwKbEPZJYXB13gvw/z9+VuHOz9pAaO8N8zugqnDFS7jrj8flu/e 7gqeZfcmj8ronRAoaNjg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nAcnV-00Cvc6-SO; Thu, 20 Jan 2022 19:08:38 +0000 Received: from dfw.source.kernel.org ([2604:1380:4641:c500::1]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nAcnP-00CvZb-1I for linux-arm-kernel@lists.infradead.org; Thu, 20 Jan 2022 19:08:35 +0000 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 6DBED617A8; Thu, 20 Jan 2022 19:08:30 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 81313C340E0; Thu, 20 Jan 2022 19:08:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1642705709; bh=SSw+nMmX8JglpTPwJ3g4vpCvPSa5IL311wRyPrz7B1o=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=OGuw1qX0yKUNnipHwSs+tFlxWSk85V4sr77ePA6GSKZOqjYNNCMoHH3d3+OdmZg0X udvA0J+ZDZCGi0gv3/cTEO6BDRu11d891nFh9rBeQGH7+fut7w1BLxJ5w2fQfrY0G6 aEIS9EyCILn/AcjIWRF0eS3LyqAPm+rR5lN5Y6yB9YLvMnkfzM5MmiBDKpDTnu5p/g N1erb8R4uzZ/uUoLeWCb+iTiWhRQ4Gen+QKaSV2vuewuLiWqII2WL33uxZ5KyCpDJ0 cWSBEXlmHEfM0uY/2jmnPYKSsnooD6AF9fEv3dEFpuzChd0/tYI+RQ9voiXFrY8aLH p+XBpgaAINkhw== Received: by pali.im (Postfix) id D266A791; Thu, 20 Jan 2022 20:08:26 +0100 (CET) Date: Thu, 20 Jan 2022 20:08:26 +0100 From: Pali =?utf-8?B?Um9ow6Fy?= To: Bjorn Helgaas Cc: Thomas Petazzoni , Lorenzo Pieralisi , Rob Herring , Krzysztof =?utf-8?Q?Wilczy=C5=84ski?= , Bjorn Helgaas , Marek =?utf-8?B?QmVow7pu?= , linux-pci@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH 08/15] PCI: mvebu: Propagate errors when updating PCI_IO_BASE and PCI_MEM_BASE registers Message-ID: <20220120190826.wkhkcx53lmafq2yp@pali> References: <20220113103523.5usmja7bp44f7ju7@pali> <20220120175047.GA1050722@bhelgaas> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20220120175047.GA1050722@bhelgaas> User-Agent: NeoMutt/20180716 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220120_110831_195941_F29F2905 X-CRM114-Status: GOOD ( 67.36 ) 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 T24gVGh1cnNkYXkgMjAgSmFudWFyeSAyMDIyIDExOjUwOjQ3IEJqb3JuIEhlbGdhYXMgd3JvdGU6 Cj4gT24gVGh1LCBKYW4gMTMsIDIwMjIgYXQgMTE6MzU6MjNBTSArMDEwMCwgUGFsaSBSb2jDoXIg d3JvdGU6Cj4gPiBPbiBXZWRuZXNkYXkgMTIgSmFudWFyeSAyMDIyIDE4OjE5OjIxIEJqb3JuIEhl bGdhYXMgd3JvdGU6Cj4gPiA+IE9uIFNhdCwgSmFuIDA4LCAyMDIyIGF0IDEyOjQ2OjU4QU0gKzAx MDAsIFBhbGkgUm9ow6FyIHdyb3RlOgo+ID4gPiA+IE9uIEZyaWRheSAwNyBKYW51YXJ5IDIwMjIg MTc6MTY6MTcgQmpvcm4gSGVsZ2FhcyB3cm90ZToKPiA+ID4gPiA+IE9uIEZyaSwgSmFuIDA3LCAy MDIyIGF0IDExOjI4OjI2UE0gKzAxMDAsIFBhbGkgUm9ow6FyIHdyb3RlOgo+ID4gPiA+ID4gPiBP biBGcmlkYXkgMDcgSmFudWFyeSAyMDIyIDE1OjU1OjA0IEJqb3JuIEhlbGdhYXMgd3JvdGU6Cj4g PiA+ID4gPiA+ID4gT24gVGh1LCBOb3YgMjUsIDIwMjEgYXQgMDE6NDU6NThQTSArMDEwMCwgUGFs aSBSb2jDoXIgd3JvdGU6Cj4gPiA+ID4gPiA+ID4gPiBQcm9wZXJseSBwcm9wYWdhdGUgZmFpbHVy ZSBmcm9tIG12ZWJ1X3BjaWVfYWRkX3dpbmRvd3MoKQo+ID4gPiA+ID4gPiA+ID4gZnVuY3Rpb24g YmFjayB0byB0aGUgY2FsbGVyCj4gPiA+ID4gPiA+ID4gPiBtdmVidV9wY2lfYnJpZGdlX2VtdWxf YmFzZV9jb25mX3dyaXRlKCkgYW5kIGNvcnJlY3RseQo+ID4gPiA+ID4gPiA+ID4gdXBkYXRlcyBQ Q0lfSU9fQkFTRSwgUENJX01FTV9CQVNFIGFuZAo+ID4gPiA+ID4gPiA+ID4gUENJX0lPX0JBU0Vf VVBQRVIxNiByZWdpc3RlcnMgb24gZXJyb3IuICBPbiBlcnJvciBzZXQKPiA+ID4gPiA+ID4gPiA+ IGJhc2UgdmFsdWUgaGlnaGVyIHRoYW4gbGltaXQgdmFsdWUgd2hpY2ggaW5kaWNhdGVzIHRoYXQK PiA+ID4gPiA+ID4gPiA+IGFkZHJlc3MgcmFuZ2UgaXMgZGlzYWJsZWQuIAo+ID4gPiA+ID4gPiA+ IAo+ID4gPiA+ID4gPiA+IERvZXMgdGhlIHNwZWMgc2F5IHRoYXQgaWYgc29mdHdhcmUgcHJvZ3Jh bXMgc29tZXRoaW5nCj4gPiA+ID4gPiA+ID4gaW52YWxpZCwgaGFyZHdhcmUgc2hvdWxkIHByb2Fj dGl2ZWx5IHNldCB0aGUgYmFzZSBhbmQKPiA+ID4gPiA+ID4gPiBsaW1pdCByZWdpc3RlcnMgdG8g ZGlzYWJsZSB0aGUgd2luZG93Pwo+ID4gPiA+ID4gPiAKPiA+ID4gPiA+ID4gTm8uIEJ1dCB0aGlz IHBhdGNoIGFkZHJlc3Mgc29tZXRoaW5nIHRvdGFsbHkgZGlmZmVyZW50Lgo+ID4gPiA+ID4gPiBT b2Z0d2FyZSBjYW4gZG8gZnVsbHkgdmFsaWQgb3BlcmF0aW9uLCBlLmcuIHRyeSB0byBzZXQKPiA+ ID4gPiA+ID4gZm9yd2FyZGluZyBtZW1vcnkgd2luZG93IGFzIGxhcmdlIGFzIHBvc3NpYmxlLiBC dXQgYmVjYXVzZQo+ID4gPiA+ID4gPiB0aGlzIGRyaXZlciAiZW11bGF0ZXMiIHBjaSBicmlkZ2Ug YnkgY2FsbGluZyBzb2Z0d2FyZS9rZXJuZWwKPiA+ID4gPiA+ID4gZnVuY3Rpb24gKG12ZWJ1X3Bj aWVfYWRkX3dpbmRvd3MpLCBzb21lIG9wZXJhdGlvbnMgd2hpY2ggaW4KPiA+ID4gPiA+ID4gcmVh bCBIVyBjYW5ub3QgaGFwcGVuLCBhcmUgcG9zc2libGUgaW4gc29mdHdhcmUuCj4gPiA+ID4gPiA+ IAo+ID4gPiA+ID4gPiBGb3IgZXhhbXBsZSB0aGVyZSBhcmUgbGltaXRhdGlvbnMgaW4gc2l6ZXMg b2YgZm9yd2FyZGluZwo+ID4gPiA+ID4gPiBtZW1vcnkgd2luZG93cywgYmVjYXVzZSBpdCBpcyBk b25lIGJ5IG12ZWJ1LW1idXMgZHJpdmVyLAo+ID4gPiA+ID4gPiB3aGljaCBpcyByZXNwb25zaWJs ZSBmb3IgY29uZmlndXJpbmcgbWFwcGluZyBhbmQgZm9yd2FyZGluZwo+ID4gPiA+ID4gPiBvZiBQ Q0llIEkvTyBhbmQgTUVNIHdpbmRvd3MuIEFuZCBkdWUgdG8gTWFydmVsbCBIVywgdGhlcmUKPiA+ ID4gPiA+ID4gYXJlIHJlc3RyaWN0aW9ucyB3aGljaCBhcmUgbm90IGluIFBDSWUgSFcuCj4gPiA+ ID4gPiA+IAo+ID4gPiA+ID4gPiBDdXJyZW50bHkgaWYgc3VjaCBlcnJvciBoYXBwZW5zLCBvYnZp b3VzbHkga2VybmVsIGlzIG5vdAo+ID4gPiA+ID4gPiBhYmxlIHRvIHNldCBQQ0llIHdpbmRvd3Mg YW5kIGl0IGp1c3QgcHJpbnQgd2FybmluZ3MgdG8KPiA+ID4gPiA+ID4gZG1lc2cuIFRyeWluZyB0 byBhY2Nlc3MgdGhlc2Ugd2luZG93cyB3b3VsZCByZXN1bHQgaW4gdGhlCj4gPiA+ID4gPiA+IHdv cnN0IGNhc2UgaW4gY3Jhc2hlcy4KPiA+ID4gPiA+ID4gCj4gPiA+ID4gPiA+IFdpdGggdGhpcyBj aGFuZ2Ugd2hlbiBtdmVidV9wY2llX2FkZF93aW5kb3dzKCkgZnVuY3Rpb24KPiA+ID4gPiA+ID4g ZmFpbHMgdGhlbiBpbnRvIGVtdWxhdGVkIGNvbmZpZyBzcGFjZSBpcyBwdXQgaW5mb3JtYXRpb24K PiA+ID4gPiA+ID4gdGhhdCBwYXJ0aWN1bGFyIGZvcndhcmRpbmcgd2luZG93IGlzIGRpc2FibGVk LiBJIHRoaW5rIHRoYXQKPiA+ID4gPiA+ID4gaXQgaXMgYmV0dGVyIHRvIGluZGljYXRlIGl0IGlu IGNvbmZpZyBzcGFjZSB3aGF0IGlzIHRoZQo+ID4gPiA+ID4gPiBjdXJyZW50ICJyZWFsaXR5IiBv ZiBoYXJkd2FyZSBjb25maWd1cmF0aW9uLiBJZiB3aW5kb3cgaXMKPiA+ID4gPiA+ID4gZGlzYWJs ZWQgaW4gcmVhbC1IVyAobWVhbmluZyBpbiBtdmVidS1tYnVzIGRyaXZlcikgdGhlbiBzaG93Cj4g PiA+ID4gPiA+IGl0IGFsc28gaW4gZW11bGF0ZWQgY29uZmlnIHNwYWNlIG9mIHBjaSBicmlkZ2Uu Cj4gPiA+ID4gPiA+IAo+ID4gPiA+ID4gPiBEbyB5b3UgaGF2ZSBiZXR0ZXIgaWRlYSB3aGF0IHNo b3VsZCBlbXVsYXRlZCBwY2kgYnJpZGdlIGRvLAo+ID4gPiA+ID4gPiBpZiBzb2Z0d2FyZSB0cnkg dG8gc2V0IGZ1bGx5IHZhbGlkIGNvbmZpZ3VyYXRpb24gb2YKPiA+ID4gPiA+ID4gZm9yd2FyZGlu ZyB3aW5kb3csIGJ1dCBpdCBpcyBub3QgcG9zc2libGUgdG8gYWNoaWV2ZSBpdAo+ID4gPiA+ID4g PiAoZXZlbiBjb21wbGlhbnQgUENJIGJyaWRnZSBtdXN0IGJlIGFibGUgdG8gZG8gaXQpPwo+ID4g PiA+ID4gCj4gPiA+ID4gPiBPbiBhbiBBQ1BJIHN5c3RlbSwgdGhlIGhvc3QgYnJpZGdlIHdpbmRv dyBzaXplcyBhcmUKPiA+ID4gPiA+IGNvbnN0cmFpbmVkIGJ5IHRoZSBob3N0IGJyaWRnZSBfQ1JT IG1ldGhvZC4gIEkgYXNzdW1lIHRoZXJlJ3MKPiA+ID4gPiA+IGEgc2ltaWxhciBjb25zdHJhaW50 IGluIERULgo+ID4gPiA+ID4gCj4gPiA+ID4gPiBJcyB0aGUgZmFjdCB0aGF0IG12ZWJ1X3BjaWVf YWRkX3dpbmRvd3MoKSBjYW4gZmFpbCBhIHN5bXB0b20KPiA+ID4gPiA+IG9mIGEgRFQgdGhhdCBk ZXNjcmliZXMgbW9yZSBhdmFpbGFibGUgc3BhY2UgdGhhbiBtdmVidS1idXMgY2FuCj4gPiA+ID4g PiBtYXA/Cj4gPiA+ID4gCj4gPiA+ID4gTWVtb3J5IG1hcHMgZm9yIG12ZWJ1IGFyZSBtb3JlIGNv bXBsaWNhdGVkLiBUaGVyZSBpcyBubyBleHBsaWNpdAo+ID4gPiA+IHNpemUgaW4gRFQgcmFuZ2Vz IHByb3BlcnR5IGFzIGl0IGlzIGR5bmFtaWNhbGx5IGFsbG9jYXRlZCBieQo+ID4gPiA+IG12ZWJ1 LW1idXM6Cj4gPiA+ID4gaHR0cHM6Ly9naXQua2VybmVsLm9yZy9wdWIvc2NtL2xpbnV4L2tlcm5l bC9naXQvdG9ydmFsZHMvbGludXguZ2l0L3RyZWUvYXJjaC9hcm0vYm9vdC9kdHMvYXJtYWRhLTM4 NS5kdHNpP2g9djUuMTUjbjQ3Cj4gPiA+IAo+ID4gPiBJIHdpc2ggSSBrbmV3IGhvdyB0byByZWFs bHkgaW50ZXJwcmV0IHRob3NlICJyYW5nZXMiIHByb3BlcnRpZXMuCj4gPiA+IChJcyB0aGVyZSBh IGdvb2QgZGVzY3JpcHRpb24gaW4gRG9jdW1lbnRhdGlvbi8gc29tZXdoZXJlPyAgQWxsCj4gPiA+ IEkndmUgZm91bmQgc28gZmFyIGlzIGh0dHBzOi8vZWxpbnV4Lm9yZy9EZXZpY2VfVHJlZV9Vc2Fn ZSwgd2hpY2gKPiA+ID4gaXMgZ29vZCwgYnV0IGRvZXNuJ3QgbWF0Y2ggdGhpcyBleGFtcGxlIGNv bXBsZXRlbHkuKQo+ID4gPiAKPiA+ID4gSSBzZWU6Cj4gPiA+IAo+ID4gPiAgIHBjaWVjOiBwY2ll IHsKPiA+ID4gICAgIHJhbmdlcyA9IDwuLi4+Owo+ID4gPiAgICAgcGNpZTE6IHBjaWVAMSwwIHsK PiA+ID4gICAgICAgcmFuZ2VzID0gPDB4ODIwMDAwMDAgMCAwIDB4ODIwMDAwMDAgMHgxIDAgMSAw Cj4gPiA+IAkgICAgICAgIDB4ODEwMDAwMDAgMCAwIDB4ODEwMDAwMDAgMHgxIDAgMSAwPjsKPiA+ ID4gICAgIH07Cj4gPiA+ICAgICBwY2llMjogcGNpZUAyLDAgewo+ID4gPiAgICAgICByYW5nZXMg PSA8MHg4MjAwMDAwMCAwIDAgMHg4MjAwMDAwMCAweDIgMCAxIDAKPiA+ID4gCSAgICAgICAgMHg4 MTAwMDAwMCAwIDAgMHg4MTAwMDAwMCAweDIgMCAxIDA+Owo+ID4gPiAgICAgfTsKPiA+ID4gICAg IHBjaWUzOiBwY2llQDMsMCB7Cj4gPiA+ICAgICAgIHJhbmdlcyA9IDwweDgyMDAwMDAwIDAgMCAw eDgyMDAwMDAwIDB4MyAwIDEgMAo+ID4gPiAJICAgICAgICAweDgxMDAwMDAwIDAgMCAweDgxMDAw MDAwIDB4MyAwIDEgMD47Cj4gPiA+ICAgICB9Owo+ID4gPiAgICAgcGNpZTQ6IHBjaWVANCwwIHsK PiA+ID4gICAgICAgcmFuZ2VzID0gPDB4ODIwMDAwMDAgMCAwIDB4ODIwMDAwMDAgMHg0IDAgMSAw Cj4gPiA+IAkgICAgICAgIDB4ODEwMDAwMDAgMCAwIDB4ODEwMDAwMDAgMHg0IDAgMSAwPjsKPiA+ ID4gICAgIH07Cj4gPiA+ICAgfTsKPiA+ID4gCj4gPiA+IFdoYXQgZG9lcyB0aGlzIGxvb2sgbGlr ZSBpbiBkbWVzZywgaS5lLiwgd2hhdCBDUFUgYWRkcmVzcyByYW5nZXMgYXJlCj4gPiA+IG1hcHBl ZCB0byB3aGF0IFBDSSBidXMgYWRkcmVzc2VzPwo+ID4gCj4gPiBUaGVzZSBleHBsaWNpdCByYW5n ZXMgaW4gRFQgYXJlIHByb2JhYmx5IGlnbm9yZWQgYXMgdGhleSBhcmUgaW52YWxpZC4KPiA+IFlv dSBjYW4gc2VlIHRoZW0gKDB4ZmZmZmZmZmZmZmZmZmZmZikgaW4gZG1lc2cuIAo+IAo+IEFyZSB5 b3Ugc2F5aW5nIHRoYXQgdGhpcyBEVCByYW5nZXMgYW5kIHRoZSBkbWVzZyBsaW5lIGFyZSBjb25u ZWN0ZWQ/Cj4gCj4gICByYW5nZXMgPSA8MHg4MjAwMDAwMCAwIDAgMHg4MjAwMDAwMCAweDEgMCAx IDAKPiAgICAgICAgICAgICAweDgxMDAwMDAwIDAgMCAweDgxMDAwMDAwIDB4MSAwIDEgMD47Cj4g Cj4gICBtdmVidS1wY2llIHNvYzpwY2llOiBNRU0gMHhmZmZmZmZmZmZmZmZmZmZmLi4weDAwZmZm ZmZmZmUgLT4gMHgwMTAwMDAwMDAwCj4gCj4gMSkgSXQgd291bGQgYmUgbmljZSBpZiB0aGVyZSB3 ZXJlIGEgaGludCBzb21ld2hlcmUgaW4gRG9jdW1lbnRhdGlvbi8KPiB0aGF0IHdvdWxkIGFsbG93 IG1lcmUgbW9ydGFscyB0byBzZWUgdGhlIGNvbm5lY3Rpb24gdGhlcmUuCgpJIGFncmVlLCB0aGF0 IHRoZXJlIGlzIG1pc3NpbmcgbG90IG9mIGRvY3VtZW50YXRpb24gcmVsYXRlZCB0byBNYXJ2ZWxs ClBDSWUgY29udHJvbGxlcnMsIGJvdGggcGNpLW12ZWJ1LmMgYW5kIHBjaS1hYXJkdmFyay5jLiBU aGUgbWFpbiBwcm9ibGVtCm5vdyBpcyB0aGF0IGl0IGlzIGhhcmQgdG8gZmluZCBpbmZvcm1hdGlv biB3aGljaCBleHBsYWluIGV2ZXJ5dGhpbmcuLi4KbGlrZSBteXN0ZXJpb3VzIE1lbW9yeSBDb250 cm9sbGVyICh3aGljaCBpcyBub3cgZXhwbGFpbmVkKToKaHR0cHM6Ly9sb3JlLmtlcm5lbC5vcmcv bGludXgtcGNpLzIwMjExMDAzMTIwOTQ0LjNsbXd4eWxuaGxwMmtmajdAcGFsaS8KCj4gMikgV2h5 IGRvIHdlIGhhdmUgdGhlc2UgRFQgZW50cmllcyBpZiB0aGV5IGFyZSBpbnZhbGlkIGFuZCB1c2Vs ZXNzPwoKU29ycnksIEkgZG8gbm90IGtub3cuIEkgd2FzIG5vdCBpbnZvbHZlZCBkdXJpbmcgaW50 cm9kdWNpbmcgb2YgRFQgZmlsZXMKZm9yIHRoaXMgcGxhdGZvcm0uIEknbSBqdXN0IG9ic2Vydmlu ZyBob3cgaXQgd29ya3MuLi4KCj4gPiBNRU0gYW5kIEkvTyByZXNvdXJjZXMgYXJlIHBhcnNlZCBp biBwY2ktbXZlYnUuYyBkcml2ZXIgaW4KPiA+IG12ZWJ1X3BjaWVfcGFyc2VfcmVxdWVzdF9yZXNv dXJjZXMoKSBmdW5jdGlvbi4KPiAKPiBTbyBtdmVidS1tYnVzLmMgZmlsbHMgaW4gdGhlIHN0YXRp YyBtYnVzX3N0YXRlIGZyb20gdGhlIERUCj4gInBjaWUtbWVtLWFwZXJ0dXJlIiwgd2hpY2ggc2Vl bXMgdW5jb25uZWN0ZWQgdG8gdGhlIERUIGRlc2NyaXB0aW9ucyBvZgo+IHRoZSBQQ0kgY29udHJv bGxlcnM6Cj4gCj4gICBzdGF0aWMgc3RydWN0IG12ZWJ1X21idXNfc3RhdGUgbWJ1c19zdGF0ZTsK PiAKPiAgIG12ZWJ1X21idXNfZHRfaW5pdAo+ICAgICBtdmVidV9tYnVzX2dldF9wY2llX3Jlc291 cmNlcygmbWJ1c19zdGF0ZS5wY2llX21lbV9hcGVydHVyZSkKPiAgICAgICBvZl9wcm9wZXJ0eV9y ZWFkX3UzMl9hcnJheSgicGNpZS1tZW0tYXBlcnR1cmUiKQo+IAo+ICAgbXZlYnVfcGNpZV9wcm9i ZQo+ICAgICBtdmVidV9wY2llX3BhcnNlX3JlcXVlc3RfcmVzb3VyY2VzCj4gICAgICAgbXZlYnVf bWJ1c19nZXRfcGNpZV9tZW1fYXBlcnR1cmUoJnBjaWUtPm1lbSkKPiAJKnJlcyA9IG1idXNfc3Rh dGUucGNpZV9tZW1fYXBlcnR1cmUKPiAgICAgICBwY2lfYWRkX3Jlc291cmNlKCZicmlkZ2UtPndp bmRvd3MsICZwY2llLT5tZW0pCj4gCj4gPiBIZXJlIGlzIHJlbGV2YW50IGRtZXNnIG91dHB1dDoK PiA+IAo+ID4gbXZlYnUtcGNpZSBzb2M6cGNpZTogaG9zdCBicmlkZ2UgL3NvYy9wY2llIHJhbmdl czoKPiA+IG12ZWJ1LXBjaWUgc29jOnBjaWU6ICAgICAgTUVNIDB4MDBmMTA4MDAwMC4uMHgwMGYx MDgxZmZmIC0+IDB4MDAwMDA4MDAwMAo+ID4gbXZlYnUtcGNpZSBzb2M6cGNpZTogICAgICBNRU0g MHgwMGYxMDQwMDAwLi4weDAwZjEwNDFmZmYgLT4gMHgwMDAwMDQwMDAwCj4gPiBtdmVidS1wY2ll IHNvYzpwY2llOiAgICAgIE1FTSAweDAwZjEwNDQwMDAuLjB4MDBmMTA0NWZmZiAtPiAweDAwMDAw NDQwMDAKPiA+IG12ZWJ1LXBjaWUgc29jOnBjaWU6ICAgICAgTUVNIDB4MDBmMTA0ODAwMC4uMHgw MGYxMDQ5ZmZmIC0+IDB4MDAwMDA0ODAwMAo+ID4gbXZlYnUtcGNpZSBzb2M6cGNpZTogICAgICBN RU0gMHhmZmZmZmZmZmZmZmZmZmZmLi4weDAwZmZmZmZmZmUgLT4gMHgwMTAwMDAwMDAwCj4gPiBt dmVidS1wY2llIHNvYzpwY2llOiAgICAgICBJTyAweGZmZmZmZmZmZmZmZmZmZmYuLjB4MDBmZmZm ZmZmZSAtPiAweDAxMDAwMDAwMDAKPiA+IG12ZWJ1LXBjaWUgc29jOnBjaWU6ICAgICAgTUVNIDB4 ZmZmZmZmZmZmZmZmZmZmZi4uMHgwMGZmZmZmZmZlIC0+IDB4MDIwMDAwMDAwMAo+ID4gbXZlYnUt cGNpZSBzb2M6cGNpZTogICAgICAgSU8gMHhmZmZmZmZmZmZmZmZmZmZmLi4weDAwZmZmZmZmZmUg LT4gMHgwMjAwMDAwMDAwCj4gPiBtdmVidS1wY2llIHNvYzpwY2llOiAgICAgIE1FTSAweGZmZmZm ZmZmZmZmZmZmZmYuLjB4MDBmZmZmZmZmZSAtPiAweDAzMDAwMDAwMDAKPiA+IG12ZWJ1LXBjaWUg c29jOnBjaWU6ICAgICAgIElPIDB4ZmZmZmZmZmZmZmZmZmZmZi4uMHgwMGZmZmZmZmZlIC0+IDB4 MDMwMDAwMDAwMAo+ID4gbXZlYnUtcGNpZSBzb2M6cGNpZTogICAgICBNRU0gMHhmZmZmZmZmZmZm ZmZmZmZmLi4weDAwZmZmZmZmZmUgLT4gMHgwNDAwMDAwMDAwCj4gPiBtdmVidS1wY2llIHNvYzpw Y2llOiAgICAgICBJTyAweGZmZmZmZmZmZmZmZmZmZmYuLjB4MDBmZmZmZmZmZSAtPiAweDA0MDAw MDAwMDAKPiA+IG12ZWJ1LXBjaWUgc29jOnBjaWU6IFBDSSBob3N0IGJyaWRnZSB0byBidXMgMDAw MDowMAo+ID4gcGNpX2J1cyAwMDAwOjAwOiByb290IGJ1cyByZXNvdXJjZSBbYnVzIDAwLWZmXQo+ ID4gcGNpX2J1cyAwMDAwOjAwOiByb290IGJ1cyByZXNvdXJjZSBbbWVtIDB4ZjEwODAwMDAtMHhm MTA4MWZmZl0gKGJ1cyBhZGRyZXNzIFsweDAwMDgwMDAwLTB4MDAwODFmZmZdKQo+ID4gcGNpX2J1 cyAwMDAwOjAwOiByb290IGJ1cyByZXNvdXJjZSBbbWVtIDB4ZjEwNDAwMDAtMHhmMTA0MWZmZl0g KGJ1cyBhZGRyZXNzIFsweDAwMDQwMDAwLTB4MDAwNDFmZmZdKQo+ID4gcGNpX2J1cyAwMDAwOjAw OiByb290IGJ1cyByZXNvdXJjZSBbbWVtIDB4ZjEwNDQwMDAtMHhmMTA0NWZmZl0gKGJ1cyBhZGRy ZXNzIFsweDAwMDQ0MDAwLTB4MDAwNDVmZmZdKQo+ID4gcGNpX2J1cyAwMDAwOjAwOiByb290IGJ1 cyByZXNvdXJjZSBbbWVtIDB4ZjEwNDgwMDAtMHhmMTA0OWZmZl0gKGJ1cyBhZGRyZXNzIFsweDAw MDQ4MDAwLTB4MDAwNDlmZmZdKQo+ID4gcGNpX2J1cyAwMDAwOjAwOiByb290IGJ1cyByZXNvdXJj ZSBbbWVtIDB4ZTAwMDAwMDAtMHhlN2ZmZmZmZl0KPiAKPiBJIHNlZSAweGYxMDgwMDAwLTB4ZjEw ODFmZmYsIDB4ZjEwNDAwMDAtMHhmMTA0MWZmZiwgZXRjIG1lbnRpb25lZCBpbgo+IHRoZSBEVCBp bmZvIGFib3ZlLCBidXQgSSBkb24ndCBzZWUgd2hlcmUgW21lbSAweGUwMDAwMDAwLTB4ZTdmZmZm ZmZdCj4gY2FtZSBmcm9tLgoKMHhlMDAwMDAwMCBpcyBkZWZpbmVkIGluIGFib3ZlIG1lbnRpb25l ZCAicGNpZS1tZW0tYXBlcnR1cmUiIERUIHByb3BlcnR5CmFuZCBpdCBpcyBpbiBhcm1hZGEtMzh4 LmR0c2kgRFRTIGZpbGUgaW5jbHVkZWQgZnJvbSBhcm1hZGEtMzg1LmR0c2k6Cmh0dHBzOi8vZ2l0 Lmtlcm5lbC5vcmcvcHViL3NjbS9saW51eC9rZXJuZWwvZ2l0L3RvcnZhbGRzL2xpbnV4LmdpdC90 cmVlL2FyY2gvYXJtL2Jvb3QvZHRzL2FybWFkYS0zOHguZHRzaT9oPXY1LjE1I240MgoKPiBSZWdh cmRsZXNzLCB0aGlzIG1lYW5zIFBDSSB0aGlua3MgW21lbSAweGUwMDAwMDAwLTB4ZTdmZmZmZmZd IGlzCj4gYXZhaWxhYmxlIG9uIGJ1cyAwMCBhbmQgY2FuIGJlIGFzc2lnbmVkIHRvIGRldmljZXMg b24gYnVzIDAwIGFjY29yZGluZwo+IHRvIHRoZSBub3JtYWwgUENJIHJ1bGVzIChCQVJzIGFsaWdu ZWQgb24gc2l6ZSwgUENJIGJyaWRnZSB3aW5kb3dzCj4gYWxpZ25lZCBvbiAxTUIgYW5kIG11bHRp cGxlIG9mIDFNQiBpbiBzaXplKS4gIElJVUMsIG12ZWJ1IGltcG9zZXMKPiBhZGRpdGlvbmFsIGFs aWdubWVudCBjb25zdHJhaW50cyBvbiB0aGUgYnJpZGdlIHdpbmRvd3MuCj4gCj4gVGhlc2UgYXJl IHRoZSBicmlkZ2Ugd2luZG93IGFzc2lnbm1lbnRzIGZyb20geW91ciBkbWVzZzoKPiAKPiA+IHBj aSAwMDAwOjAwOjAxLjA6IEJBUiA4OiBhc3NpZ25lZCBbbWVtIDB4ZTAwMDAwMDAtMHhlMDBmZmZm Zl0KPiA+IHBjaSAwMDAwOjAwOjAyLjA6IEJBUiA4OiBhc3NpZ25lZCBbbWVtIDB4ZTAyMDAwMDAt MHhlMDRmZmZmZl0KPiA+IHBjaSAwMDAwOjAwOjAzLjA6IEJBUiA4OiBhc3NpZ25lZCBbbWVtIDB4 ZTAxMDAwMDAtMHhlMDFmZmZmZl0KPiAKPiA+IHBjaSAwMDAwOjAwOjAxLjA6IFBDSSBicmlkZ2Ug dG8gW2J1cyAwMV0KPiA+IHBjaSAwMDAwOjAwOjAxLjA6ICAgYnJpZGdlIHdpbmRvdyBbbWVtIDB4 ZTAwMDAwMDAtMHhlMDBmZmZmZl0KPiA+IHBjaSAwMDAwOjAwOjAyLjA6IFBDSSBicmlkZ2UgdG8g W2J1cyAwMl0KPiA+IHBjaSAwMDAwOjAwOjAyLjA6ICAgYnJpZGdlIHdpbmRvdyBbbWVtIDB4ZTAy MDAwMDAtMHhlMDRmZmZmZl0KPiA+IHBjaSAwMDAwOjAwOjAzLjA6IFBDSSBicmlkZ2UgdG8gW2J1 cyAwM10KPiA+IHBjaSAwMDAwOjAwOjAzLjA6ICAgYnJpZGdlIHdpbmRvdyBbbWVtIDB4ZTAxMDAw MDAtMHhlMDFmZmZmZl0KPiAKPiBUaGUgUENJIGNvcmUga25vd3Mgbm90aGluZyBhYm91dCB0aGUg bXZlYnUgY29uc3RyYWludHMuICBBcmUgd2UganVzdAo+IGx1Y2t5IGhlcmUgdGhhdCB3aGVuIFBD SSBhc3NpZ25lZCB0aGVzZSBicmlkZ2Ugd2luZG93cywgdGhleSBoYXBwZW4gdG8KPiBiZSBzdXBw b3J0ZWQgb24gbXZlYnU/ICBXaGF0IGhhcHBlbnMgaWYgUENJIGRlY2lkZXMgaXQgbmVlZHMgMjlN QiBvbgo+IGJ1cyAwMT8KCkluIHRoaXMgY2FzZSBwY2ktbXZlYnUuYyBzcGxpdCAyOU1CIHdpbmRv dyBpbnRvIGNvbnRpbnVvdXMgcmFuZ2VzIG9mCnBvd2VyIG9mIHR3byAoMTZNQiArIDhNQiArIDRN QiArIDFNQikgYW5kIHRoZW4gcmVnaXN0ZXIgZWFjaCByYW5nZSB0bwptYnVzIHNsb3QuIENvZGUg aXMgaW4gZnVuY3Rpb24gbXZlYnVfcGNpZV9hZGRfd2luZG93cygpOgpodHRwczovL2dpdC5rZXJu ZWwub3JnL3B1Yi9zY20vbGludXgva2VybmVsL2dpdC90b3J2YWxkcy9saW51eC5naXQvdHJlZS9k cml2ZXJzL3BjaS9jb250cm9sbGVyL3BjaS1tdmVidS5jP2g9djUuMTUjbjMwMAoKU28gYXQgdGhl IGVuZCB0aGVyZSBpcyBjb250aW51b3VzIHNwYWNlIG9mIDI5TUIgUENJZSB3aW5kb3csIGp1c3Qg aXQKImVhdHMiIDQgbWJ1cyBzbG90cy4KClRoaXMgZnVuY3Rpb24gbWF5IGZhaWwgKGlmIHRoZXJl IGlzIG5vdCBlbm91Z2ggZnJlZSBtYnVzIHNsb3RzKSBhbmQgdGhpcwpwYXRjaCBpcyBwcm9wYWdh dGluZyB0aGF0IGZhaWx1cmUgYmFjayB0byB0aGUgY2FsbGVyLgoKPiA+ID4gQXJlIHBjaWUxLCBw Y2llMiwgZXRjIFJvb3QgUG9ydHM/ICBPciBhcmUgdGhleSBlYWNoIHNlcGFyYXRlIGhvc3QKPiA+ ID4gYnJpZGdlcyAodGhleSBlYWNoIGhhdmUgImJ1cy1yYW5nZSA9IDwweDAwIDB4ZmY+Iik/Cj4g PiAKPiA+IEZyb20ga2VybmVsIHBvaW50IG9mIHZpZXcgdGhleSBhcmUgcm9vdCBwb3J0cy4gQnV0 IGluIHJlYWxpdHkgZXZlcnkgb2YKPiA+IHRoZXNlIHJvb3QgcG9ydCBpcyBvbiBzZXBhcmF0ZSBi dXMgc2VnbWVudCwgYnV0IGtlcm5lbCBwY2ktbXZlYnUuYwo+ID4gZHJpdmVyIG1lcmdlcyBhbGwg dGhlc2Ugc2VnbWVudHMvZG9tYWlucyBpbnRvIG9uZSBob3N0IGJyaWRnZSBhbmQgcHV0Cj4gPiBh bGwgcm9vdCBwb3J0cyBpbnRvIGJ1cyAwLgo+ID4gCj4gPiBIZXJlIGlzIGxzcGNpIC10dm5uIG91 dHB1dCB3aXRoIHRvcG9sb2d5Ogo+ID4gCj4gPiAkIGxzcGNpIC10dm5uCj4gPiAtWzAwMDA6MDBd LSstMDEuMC1bMDFdLS0tLTAwLjAgIERldmljZSBbMWUwZjowMDAxXQo+ID4gICAgICAgICAgICAr LTAyLjAtWzAyXS0tLS0wMC4wICBRdWFsY29tbSBBdGhlcm9zIFFDQTk4NngvOTg4eCA4MDIuMTFh YyBXaXJlbGVzcyBOZXR3b3JrIEFkYXB0ZXIgWzE2OGM6MDAzY10KPiA+ICAgICAgICAgICAgXC0w My4wLVswM10tLS0tMDAuMCAgUXVhbGNvbW0gQXRoZXJvcyBBUjkyODcgV2lyZWxlc3MgTmV0d29y ayBBZGFwdGVyIChQQ0ktRXhwcmVzcykgWzE2OGM6MDAyZV0KPiAKPiA+IEJ1c2VzIDEsIDIgYW5k IDMgcmVwcmVzZW50cyBtUENJZSBjYXJkcywgYWxsIG9mIHRoZW0gYXJlIGluIHJlYWxpdHkKPiA+ IGluIHNlcGFyYXRlIGJ1cyBzZWdtZW50cyBhbmQgb24gZGlmZmVyZW50IEhXIGhvc3QgYnJpZGdl cy4gU28gdGhleQo+ID4gZG8gKm5vdCogc2hhcmUgYWNjZXNzIHRvIGNvbmZpZyBzcGFjZSwgZG8g Km5vdCogc2hhcmUgSU5UeAo+ID4gaW50ZXJydXB0cywgZXRjLi4uCj4gPiAKPiA+ID4gSXMgc3Bh Y2UgZnJvbSBwY2llYyBkeW5hbWljYWxseSBhc3NpZ25lZCB0byBwY2llMSwgcGNpZTIsIGV0Yz8g IElmCj4gPiA+IHNvLCBJIGFzc3VtZSB0aGVyZSBhcmUgbW9yZSByZXN0cmljdGlvbnMgb24gdGhl IHNpemUgYW5kIGFsaWdubWVudAo+ID4gPiB0aGFuIG9uIFBDSSBicmlkZ2Ugd2luZG93cywgd2hp Y2ggYWxsb3cgc2l6ZS9hbGlnbm1lbnQgZG93biB0bwo+ID4gPiAxTUI/Cj4gPiAKPiA+IFllcywg ZXhhY3RseS4gSSBkbyBub3Qga25vdyBub3cgYWxsIHJlc3RyaWN0aW9ucy4gQXQgbGVhc3QgdGhl cmUgYXJlCj4gPiBmaXhlZCBudW1iZXIgb2YgbWVtb3J5IHNsb3RzIGFuZCBlYWNoIGhhcyB0byBi ZSBvZiBzaXplIDJeTi4gVGhleQo+ID4gYXJlIGR5bmFtaWNhbGx5IGFzc2lnbmVkIGJ5IGtlcm5l bCBtYnVzIGRyaXZlciBhdCB0aW1lIHdoZW4gc29tZWJvZHkKPiA+IHVwZGF0ZXMgQkFTRS9MSU1J VCByZWdpc3RlcnMuIEFuZCB0aGF0IGtlcm5lbCBtYnVzIGRyaXZlciB0YWtlcyBjYXJlCj4gPiB0 byBzcGxpdCBub24tYWxpZ25lZCB3aW5kb3cgc2l6ZSB0byBtb3JlIHNsb3RzIG9mIHNpemUgMl5O LiBBbmQKPiA+IHJlc291cmNlcyBhcmUgc2hhcmVkIGZyb20gcG9vbCB3aXRoIG90aGVyIEhXIHBh cnRzIChlLmcuIERNQSksIHNvCj4gPiBvdGhlciBkcml2ZXJzIGxvYWRlZCBpbiBrZXJuZWwgY2Fu ICJlYXQiIGF2YWlsYWJsZSBzbG90cyBiZWZvcmUKPiA+IHBjaS1tdmVidSBhbmQgdGhlbiB0aGVy ZSBkb2VzIG5vdCBoYXZlIHRvIGJlIG5vdGhpbmcgdG8gYWxsb2NhdGUgZm9yCj4gPiBQQ0kuCj4g Cj4gU28gSUlVQywKPiAKPiAgIHBjaWUxID09IDAwOjAxLjAgUm9vdCBQb3J0Cj4gICBwY2llMiA9 PSAwMDowMi4wIFJvb3QgUG9ydAo+ICAgcGNpZTMgPT0gMDA6MDMuMCBSb290IFBvcnQKPiAKPiBG cm9tIGEgc29mdHdhcmUgcG9pbnQgb2YgdmlldywgdGhleSdyZSBhbGwgdW5kZXIgYSBzaW5nbGUg aG9zdCBicmlkZ2UsCj4gYW5kIExpbnV4IGFzc3VtZXMgZXZlcnl0aGluZyB1bmRlciBhIGhvc3Qg YnJpZGdlIHBsYXlzIGJ5IHRoZSBQQ0kKPiBydWxlcy4KClllcy4KCj4gSW4gdGhpcyBjYXNlLCB0 aGUgcm9vdCBwb3J0cyAqZG9uJ3QqIHBsYXkgYnkgdGhlIHJ1bGVzIHNpbmNlIHRoZXkgaGF2ZQo+ IGFkZGl0aW9uYWwgYWxpZ25tZW50IHJlc3RyaWN0aW9ucywgc28gSSB0aGluayB0aGVzZSByZWFs bHkgc2hvdWxkIGJlCj4gZGVzY3JpYmVkIGFzIHNlcGFyYXRlIGhvc3QgYnJpZGdlcyBpbiBEVCB3 aXRoIHRoZSBhZGRyZXNzIHNwYWNlCj4gY2FydmVkIHVwIHN0YXRpY2FsbHkgYW1vbmcgdGhlbS4K CkkgZnVsbHkgYWdyZWUgd2l0aCB5b3UuCgpCdXQgcGNpLW12ZWJ1LmMgZHJpdmVyIGFuZCBhbHNv IGl0cyBEVCBiaW5kaW5ncyBhcmUgd3JpdHRlbiBkaWZmZXJlbnRseS4KQ2hhbmdpbmcgaXQgcHJv YmFibHkgd291bGQgbm90IGJlIHNpbXBsZSBkdWUgdG8gYmFja3dhcmQgY29tcGF0aWJpbGl0eQph bmQgd2lsbCB0YWtlIGRldmVsb3BtZW50IHJlc291cmNlcy4uLgoKPiBJdCdzIGNvbW1vbiBvbiB4 ODYgdG8gaGF2ZSBtdWx0aXBsZSBob3N0IGJyaWRnZXMgdGhhdCBhbGwgYXBwZWFyIHRvCj4gc29m dHdhcmUgdG8gYmUgaW4gZG9tYWluIDAwMDAuICBUaGUgYnVzIG51bWJlciByYW5nZXMgdW5kZXIg ZWFjaCBhcmUKPiBzdGF0aWMsIGUuZy4sIG9uZSBicmlkZ2UgaGFzIFtidXMgMDAtN2ZdIGFuZCBh bm90aGVyIGhhcyBbYnVzIDgwLWZmXS4KCkZvciBtdmVidSB0aGV5IGFyZSBkeW5hbWljIGFuZCBr ZXJuZWwgYXNzaWducyB0aGVtIGF0IGJvb3QuIEFzIG15IGFib3ZlCnByaW50ZWQgbHNwY2kgdG9w b2xvZ3kgaXMgc2ltcGxlLCBmaXJzdCBicmlkZ2UgaGFzIGFzc2lnbmVkIFtidXMgMDEtMDFdLApz ZWNvbmQgYnJpZGdlIFtidXMgMDItMDJdIGFuZCB0aGlyZCBicmlkZ2UgW2J1cyAwMy0wM10uCgo+ ID4gQnV0IG1vc3QgQXJtYWRhIGJvYXJkcyBkbyBub3QgaGF2ZSBleHBvcnRlZCBhbGwgcGVyaXBo ZXJhbHMgZnJvbSBTb0MsCj4gPiB1bmNvbm5lY3RlZCBhcmUgZGlzYWJsZWQgaW4gRFQgYW5kIHRo ZXJlZm9yZSBleGhhdXN0aW9uIHNob3VsZCBub3QKPiA+IGhhcHBlbi4KPiA+IAo+ID4gPiBJJ20g dHJ5aW5nIHRvIHNlZSBob3cgdGhpcyBjb3VsZCBiZSBkZXNjcmliZWQgaW4gQUNQSSBiZWNhdXNl IHRoYXQncyBhCj4gPiA+IGZhaXJseSBnZW5lcmFsIG1vZGVsIHRoYXQgYWNjb21tb2RhdGVzIG1v c3QgbWFjaGluZXMuICBQb3NzaWJseQo+ID4gPiBkZXNjcmliaW5nIG12ZWJ1IGluIEFDUEkgd291 bGQgaW52b2x2ZSBsb3Npbmcgc29tZSBmbGV4aWJpbGl0eS4KPiA+IAo+ID4gSSBkbyBub3QgdW5k ZXJzdGFuZCBBUENJIG1vZGVsIHZlcnkgd2VsbCBhbmQgSSdtIGluIGltcHJlc3Npb24gdGhhdCBp dAo+ID4gaXMgaW1wb3NzaWJsZSB0byByZXByZXNlbnQgbXZlYnUgaW4gQUNQSS4KPiAKPiBJdCBj b3VsZCBiZSBkZXNjcmliZWQgYXMgYSBzZXBhcmF0ZSBob3N0IGJyaWRnZSBmb3IgZXZlcnkgcm9v dCBwb3J0Lgo+IEFDUEkgdXNlcyBfQ1JTIChjdXJyZW50IHJlc291cmNlIHNldHRpbmdzKSB0byBk ZXNjcmliZSB0aGUgYXBlcnR1cmVzCj4gdG8gUENJIGFuZCBhbnkgYWRkcmVzcyB0cmFuc2xhdGlv bi4gIEN1cnJlbnRseSB0aGUgX0NSUyBkZXNjcmlwdGlvbiBpcwo+IHN0YXRpYywgYnV0IEFDUEkg ZG9lcyBhbGxvdyB0aG9zZSByZXNvdXJjZSBhc3NpZ25tZW50cyB0byBiZSBtb2RpZmllZAo+IHZp YSBfUFJTIChwb3NzaWJsZSByZXNvdXJjZSBzZXR0aW5ncykgYW5kIF9TUlMgKHNldCByZXNvdXJj ZQo+IHNldHRpbmdzKS4KPiAKPiBCam9ybgoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX18KbGludXgtYXJtLWtlcm5lbCBtYWlsaW5nIGxpc3QKbGludXgtYXJt LWtlcm5lbEBsaXN0cy5pbmZyYWRlYWQub3JnCmh0dHA6Ly9saXN0cy5pbmZyYWRlYWQub3JnL21h aWxtYW4vbGlzdGluZm8vbGludXgtYXJtLWtlcm5lbAo=