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 X-Spam-Level: X-Spam-Status: No, score=-13.1 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,MENTIONS_GIT_HOSTING,SIGNED_OFF_BY,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A5EDCC43387 for ; Wed, 16 Jan 2019 17:05:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5252220651 for ; Wed, 16 Jan 2019 17:05:34 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="QMSpQLRM" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2391430AbfAPRFc (ORCPT ); Wed, 16 Jan 2019 12:05:32 -0500 Received: from fllv0015.ext.ti.com ([198.47.19.141]:44998 "EHLO fllv0015.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730306AbfAPRFc (ORCPT ); Wed, 16 Jan 2019 12:05:32 -0500 Received: from lelv0266.itg.ti.com ([10.180.67.225]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id x0GH5LxG022561; Wed, 16 Jan 2019 11:05:21 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1547658321; bh=Al0Urcp4O7KPspzsdtP37aPzd5IjNr1giteeheotbCE=; h=Subject:To:CC:References:From:Date:In-Reply-To; b=QMSpQLRMSmOMhY4ilLFbtEBVR6M97a6X3PbjKxlrFoGEoWMYJb/DHtVz2m+7Ws+Da 8GGFsPdczRf2Q/vvj3D2ZU+uV5529zpuI6XYRPOlRsx2SpIx5cs+4z2WZQClVuVcKR qxgJh7K1NdaivRo7jx6B9C/rCzoDvgIB+vLtp87U= Received: from DFLE115.ent.ti.com (dfle115.ent.ti.com [10.64.6.36]) by lelv0266.itg.ti.com (8.15.2/8.15.2) with ESMTPS id x0GH5L32123334 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 16 Jan 2019 11:05:21 -0600 Received: from DFLE114.ent.ti.com (10.64.6.35) by DFLE115.ent.ti.com (10.64.6.36) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1591.10; Wed, 16 Jan 2019 11:05:20 -0600 Received: from dlep32.itg.ti.com (157.170.170.100) by DFLE114.ent.ti.com (10.64.6.35) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1591.10 via Frontend Transport; Wed, 16 Jan 2019 11:05:20 -0600 Received: from [172.22.93.115] (ileax41-snat.itg.ti.com [10.172.224.153]) by dlep32.itg.ti.com (8.14.3/8.13.8) with ESMTP id x0GH5KlG021402; Wed, 16 Jan 2019 11:05:20 -0600 Subject: Re: [PATCH 13/14] staging: android: ion: Do not sync CPU cache on map/unmap To: Brian Starkey CC: Liam Mark , Laura Abbott , Sumit Semwal , Greg Kroah-Hartman , =?UTF-8?Q?Arve_Hj=c3=b8nnev=c3=a5g?= , "devel@driverdev.osuosl.org" , "linux-kernel@vger.kernel.org" , dri-devel , nd References: <20190111180523.27862-1-afd@ti.com> <20190111180523.27862-14-afd@ti.com> <79eb70f6-00b0-2939-5ec9-65e196ab4987@ti.com> <20190116151946.66vc6ibbivijdzvd@DESKTOP-E1NTVVP.localdomain> From: "Andrew F. Davis" Message-ID: <4a5d4147-765d-711f-af98-9022d0253b3b@ti.com> Date: Wed, 16 Jan 2019 11:05:20 -0600 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.2.1 MIME-Version: 1.0 In-Reply-To: <20190116151946.66vc6ibbivijdzvd@DESKTOP-E1NTVVP.localdomain> Content-Type: text/plain; charset="utf-8" Content-Language: en-US Content-Transfer-Encoding: 7bit X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 1/16/19 9:19 AM, Brian Starkey wrote: > Hi :-) > > On Tue, Jan 15, 2019 at 12:40:16PM -0600, Andrew F. Davis wrote: >> On 1/15/19 12:38 PM, Andrew F. Davis wrote: >>> On 1/15/19 11:45 AM, Liam Mark wrote: >>>> On Tue, 15 Jan 2019, Andrew F. Davis wrote: >>>> >>>>> On 1/14/19 11:13 AM, Liam Mark wrote: >>>>>> On Fri, 11 Jan 2019, Andrew F. Davis wrote: >>>>>> >>>>>>> Buffers may not be mapped from the CPU so skip cache maintenance here. >>>>>>> Accesses from the CPU to a cached heap should be bracketed with >>>>>>> {begin,end}_cpu_access calls so maintenance should not be needed anyway. >>>>>>> >>>>>>> Signed-off-by: Andrew F. Davis >>>>>>> --- >>>>>>> drivers/staging/android/ion/ion.c | 7 ++++--- >>>>>>> 1 file changed, 4 insertions(+), 3 deletions(-) >>>>>>> >>>>>>> diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c >>>>>>> index 14e48f6eb734..09cb5a8e2b09 100644 >>>>>>> --- a/drivers/staging/android/ion/ion.c >>>>>>> +++ b/drivers/staging/android/ion/ion.c >>>>>>> @@ -261,8 +261,8 @@ static struct sg_table *ion_map_dma_buf(struct dma_buf_attachment *attachment, >>>>>>> >>>>>>> table = a->table; >>>>>>> >>>>>>> - if (!dma_map_sg(attachment->dev, table->sgl, table->nents, >>>>>>> - direction)) >>>>>>> + if (!dma_map_sg_attrs(attachment->dev, table->sgl, table->nents, >>>>>>> + direction, DMA_ATTR_SKIP_CPU_SYNC)) >>>>>> >>>>>> Unfortunately I don't think you can do this for a couple reasons. >>>>>> You can't rely on {begin,end}_cpu_access calls to do cache maintenance. >>>>>> If the calls to {begin,end}_cpu_access were made before the call to >>>>>> dma_buf_attach then there won't have been a device attached so the calls >>>>>> to {begin,end}_cpu_access won't have done any cache maintenance. >>>>>> >>>>> >>>>> That should be okay though, if you have no attachments (or all >>>>> attachments are IO-coherent) then there is no need for cache >>>>> maintenance. Unless you mean a sequence where a non-io-coherent device >>>>> is attached later after data has already been written. Does that >>>>> sequence need supporting? >>>> >>>> Yes, but also I think there are cases where CPU access can happen before >>>> in Android, but I will focus on later for now. >>>> >>>>> DMA-BUF doesn't have to allocate the backing >>>>> memory until map_dma_buf() time, and that should only happen after all >>>>> the devices have attached so it can know where to put the buffer. So we >>>>> shouldn't expect any CPU access to buffers before all the devices are >>>>> attached and mapped, right? >>>>> >>>> >>>> Here is an example where CPU access can happen later in Android. >>>> >>>> Camera device records video -> software post processing -> video device >>>> (who does compression of raw data) and writes to a file >>>> >>>> In this example assume the buffer is cached and the devices are not >>>> IO-coherent (quite common). >>>> >>> >>> This is the start of the problem, having cached mappings of memory that >>> is also being accessed non-coherently is going to cause issues one way >>> or another. On top of the speculative cache fills that have to be >>> constantly fought back against with CMOs like below; some coherent >>> interconnects behave badly when you mix coherent and non-coherent access >>> (snoop filters get messed up). >>> >>> The solution is to either always have the addresses marked non-coherent >>> (like device memory, no-map carveouts), or if you really want to use >>> regular system memory allocated at runtime, then all cached mappings of >>> it need to be dropped, even the kernel logical address (area as painful >>> as that would be). > > Ouch :-( I wasn't aware about these potential interconnect issues. How > "real" is that? It seems that we aren't really hitting that today on > real devices. > Sadly there is at least one real device like this now (TI AM654). We spent some time working with the ARM interconnect spec designers to see if this was allowed behavior, final conclusion was mixing coherent and non-coherent accesses is never a good idea.. So we have been working to try to minimize any cases of mixed attributes [0], if a region is coherent then everyone in the system needs to treat it as such and vice-versa, even clever CMO that work on other systems wont save you here. :( [0] https://github.com/ARM-software/arm-trusted-firmware/pull/1553 >>> >>>> ION buffer is allocated. >>>> >>>> //Camera device records video >>>> dma_buf_attach >>>> dma_map_attachment (buffer needs to be cleaned) >>> >>> Why does the buffer need to be cleaned here? I just got through reading >>> the thread linked by Laura in the other reply. I do like +Brian's >> >> Actually +Brian this time :) >> >>> suggestion of tracking if the buffer has had CPU access since the last >>> time and only flushing the cache if it has. As unmapped heaps never get >>> CPU mapped this would never be the case for unmapped heaps, it solves my >>> problem. >>> >>>> [camera device writes to buffer] >>>> dma_buf_unmap_attachment (buffer needs to be invalidated) >>> >>> It doesn't know there will be any further CPU access, it could get freed >>> after this for all we know, the invalidate can be saved until the CPU >>> requests access again. > > We don't have any API to allow the invalidate to happen on CPU access > if all devices already detached. We need a struct device pointer to > give to the DMA API, otherwise on arm64 there'll be no invalidate. > > I had a chat with a few people internally after the previous > discussion with Liam. One suggestion was to use > DMA_ATTR_SKIP_CPU_SYNC in unmap_dma_buf, but only if there's at least > one other device attached (guarantees that we can do an invalidate in > the future if begin_cpu_access is called). If the last device > detaches, do a sync then. > > Conversely, in map_dma_buf, we would track if there was any CPU access > and use/skip the sync appropriately. > Now that I think this all through I agree this patch is probably wrong. The real fix needs to be better handling in the dma_map_sg() to deal with the case of the memory not being mapped (what I'm dealing with for unmapped heaps), and for cases when the memory in question is not cached (Liam's issue I think). For both these cases the dma_map_sg() does the wrong thing. > I did start poking the code to check out how that would look, but then > Christmas happened and I'm still catching back up. > >>> >>>> dma_buf_detach (device cannot stay attached because it is being sent down >>>> the pipeline and Camera doesn't know the end of the use case) >>>> >>> >>> This seems like a broken use-case, I understand the desire to keep >>> everything as modular as possible and separate the steps, but at this >>> point no one owns this buffers backing memory, not the CPU or any >>> device. I would go as far as to say DMA-BUF should be free now to >>> de-allocate the backing storage if it wants, that way it could get ready >>> for the next attachment, which may change the required backing memory >>> completely. >>> >>> All devices should attach before the first mapping, and only let go >>> after the task is complete, otherwise this buffers data needs copied off >>> to a different location or the CPU needs to take ownership in-between. >>> > > Yeah.. that's certainly the theory. Are there any DMA-BUF > implementations which actually do that? I hear it quoted a lot, > because that's what the docs say - but if the reality doesn't match > it, maybe we should change the docs. > Do you mean on the userspace side? I'm not sure, seems like Android might be doing this wrong from what I can gather. From kernel side if you mean the "de-allocate the backing storage", we will have some cases like this soon, so I want to make sure userspace is not abusing DMA-BUF in ways not specified in the documentation. Changing the docs to force the backing memory to always be allocated breaks the central goal in having attach/map in DMA-BUF separate. >>>> //buffer is send down the pipeline >>>> >>>> // Usersapce software post processing occurs >>>> mmap buffer >>> >>> Perhaps the invalidate should happen here in mmap. >>> >>>> DMA_BUF_IOCTL_SYNC IOCT with flags DMA_BUF_SYNC_START // No CMO since no >>>> devices attached to buffer >>> >>> And that should be okay, mmap does the sync, and if no devices are >>> attached nothing could have changed the underlying memory in the >>> mean-time, DMA_BUF_SYNC_START can safely be a no-op as they are. > > Yeah, that's true - so long as you did an invalidate in unmap_dma_buf. > Liam was saying that it's too painful for them to do that every time a > device unmaps - when in many cases (device->device, no CPU) it's not > needed. Invalidates are painless, at least compared to a real cache flush, just set the invalid bit vs actually writing out lines. I thought the issue was on the map side. > >>> >>>> [CPU reads/writes to the buffer] >>>> DMA_BUF_IOCTL_SYNC IOCTL with flags DMA_BUF_SYNC_END // No CMO since no >>>> devices attached to buffer >>>> munmap buffer >>>> >>>> //buffer is send down the pipeline >>>> // Buffer is send to video device (who does compression of raw data) and >>>> writes to a file >>>> dma_buf_attach >>>> dma_map_attachment (buffer needs to be cleaned) >>>> [video device writes to buffer] >>>> dma_buf_unmap_attachment >>>> dma_buf_detach (device cannot stay attached because it is being sent down >>>> the pipeline and Video doesn't know the end of the use case) >>>> >>>> >>>> >>>>>> Also ION no longer provides DMA ready memory, so if you are not doing CPU >>>>>> access then there is no requirement (that I am aware of) for you to call >>>>>> {begin,end}_cpu_access before passing the buffer to the device and if this >>>>>> buffer is cached and your device is not IO-coherent then the cache maintenance >>>>>> in ion_map_dma_buf and ion_unmap_dma_buf is required. >>>>>> >>>>> >>>>> If I am not doing any CPU access then why do I need CPU cache >>>>> maintenance on the buffer? >>>>> >>>> >>>> Because ION no longer provides DMA ready memory. >>>> Take the above example. >>>> >>>> ION allocates memory from buddy allocator and requests zeroing. >>>> Zeros are written to the cache. >>>> >>>> You pass the buffer to the camera device which is not IO-coherent. >>>> The camera devices writes directly to the buffer in DDR. >>>> Since you didn't clean the buffer a dirty cache line (one of the zeros) is >>>> evicted from the cache, this zero overwrites data the camera device has >>>> written which corrupts your data. >>>> >>> >>> The zeroing *is* a CPU access, therefor it should handle the needed CMO >>> for CPU access at the time of zeroing. >>> > > Actually that should be at the point of the first non-coherent device > mapping the buffer right? No point in doing CMO if the future accesses > are coherent. I see your point, as long as the zeroing is guaranteed to be the first access to this buffer then it should be safe. Andrew > > Cheers, > -Brian > >>> Andrew >>> >>>> Liam >>>> >>>> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, >>>> a Linux Foundation Collaborative Project >>>> From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Andrew F. Davis" Subject: Re: [PATCH 13/14] staging: android: ion: Do not sync CPU cache on map/unmap Date: Wed, 16 Jan 2019 11:05:20 -0600 Message-ID: <4a5d4147-765d-711f-af98-9022d0253b3b@ti.com> References: <20190111180523.27862-1-afd@ti.com> <20190111180523.27862-14-afd@ti.com> <79eb70f6-00b0-2939-5ec9-65e196ab4987@ti.com> <20190116151946.66vc6ibbivijdzvd@DESKTOP-E1NTVVP.localdomain> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from fllv0015.ext.ti.com (fllv0015.ext.ti.com [198.47.19.141]) by gabe.freedesktop.org (Postfix) with ESMTPS id 23D006F15F for ; Wed, 16 Jan 2019 17:05:28 +0000 (UTC) In-Reply-To: <20190116151946.66vc6ibbivijdzvd@DESKTOP-E1NTVVP.localdomain> Content-Language: en-US List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: Brian Starkey Cc: "devel@driverdev.osuosl.org" , nd , Greg Kroah-Hartman , "linux-kernel@vger.kernel.org" , Liam Mark , =?UTF-8?Q?Arve_Hj=c3=b8nnev=c3=a5g?= , dri-devel List-Id: dri-devel@lists.freedesktop.org T24gMS8xNi8xOSA5OjE5IEFNLCBCcmlhbiBTdGFya2V5IHdyb3RlOgo+IEhpIDotKQo+IAo+IE9u IFR1ZSwgSmFuIDE1LCAyMDE5IGF0IDEyOjQwOjE2UE0gLTA2MDAsIEFuZHJldyBGLiBEYXZpcyB3 cm90ZToKPj4gT24gMS8xNS8xOSAxMjozOCBQTSwgQW5kcmV3IEYuIERhdmlzIHdyb3RlOgo+Pj4g T24gMS8xNS8xOSAxMTo0NSBBTSwgTGlhbSBNYXJrIHdyb3RlOgo+Pj4+IE9uIFR1ZSwgMTUgSmFu IDIwMTksIEFuZHJldyBGLiBEYXZpcyB3cm90ZToKPj4+Pgo+Pj4+PiBPbiAxLzE0LzE5IDExOjEz IEFNLCBMaWFtIE1hcmsgd3JvdGU6Cj4+Pj4+PiBPbiBGcmksIDExIEphbiAyMDE5LCBBbmRyZXcg Ri4gRGF2aXMgd3JvdGU6Cj4+Pj4+Pgo+Pj4+Pj4+IEJ1ZmZlcnMgbWF5IG5vdCBiZSBtYXBwZWQg ZnJvbSB0aGUgQ1BVIHNvIHNraXAgY2FjaGUgbWFpbnRlbmFuY2UgaGVyZS4KPj4+Pj4+PiBBY2Nl c3NlcyBmcm9tIHRoZSBDUFUgdG8gYSBjYWNoZWQgaGVhcCBzaG91bGQgYmUgYnJhY2tldGVkIHdp dGgKPj4+Pj4+PiB7YmVnaW4sZW5kfV9jcHVfYWNjZXNzIGNhbGxzIHNvIG1haW50ZW5hbmNlIHNo b3VsZCBub3QgYmUgbmVlZGVkIGFueXdheS4KPj4+Pj4+Pgo+Pj4+Pj4+IFNpZ25lZC1vZmYtYnk6 IEFuZHJldyBGLiBEYXZpcyA8YWZkQHRpLmNvbT4KPj4+Pj4+PiAtLS0KPj4+Pj4+PiAgZHJpdmVy cy9zdGFnaW5nL2FuZHJvaWQvaW9uL2lvbi5jIHwgNyArKysrLS0tCj4+Pj4+Pj4gIDEgZmlsZSBj aGFuZ2VkLCA0IGluc2VydGlvbnMoKyksIDMgZGVsZXRpb25zKC0pCj4+Pj4+Pj4KPj4+Pj4+PiBk aWZmIC0tZ2l0IGEvZHJpdmVycy9zdGFnaW5nL2FuZHJvaWQvaW9uL2lvbi5jIGIvZHJpdmVycy9z dGFnaW5nL2FuZHJvaWQvaW9uL2lvbi5jCj4+Pj4+Pj4gaW5kZXggMTRlNDhmNmViNzM0Li4wOWNi NWE4ZTJiMDkgMTAwNjQ0Cj4+Pj4+Pj4gLS0tIGEvZHJpdmVycy9zdGFnaW5nL2FuZHJvaWQvaW9u L2lvbi5jCj4+Pj4+Pj4gKysrIGIvZHJpdmVycy9zdGFnaW5nL2FuZHJvaWQvaW9uL2lvbi5jCj4+ Pj4+Pj4gQEAgLTI2MSw4ICsyNjEsOCBAQCBzdGF0aWMgc3RydWN0IHNnX3RhYmxlICppb25fbWFw X2RtYV9idWYoc3RydWN0IGRtYV9idWZfYXR0YWNobWVudCAqYXR0YWNobWVudCwKPj4+Pj4+PiAg Cj4+Pj4+Pj4gIAl0YWJsZSA9IGEtPnRhYmxlOwo+Pj4+Pj4+ICAKPj4+Pj4+PiAtCWlmICghZG1h X21hcF9zZyhhdHRhY2htZW50LT5kZXYsIHRhYmxlLT5zZ2wsIHRhYmxlLT5uZW50cywKPj4+Pj4+ PiAtCQkJZGlyZWN0aW9uKSkKPj4+Pj4+PiArCWlmICghZG1hX21hcF9zZ19hdHRycyhhdHRhY2ht ZW50LT5kZXYsIHRhYmxlLT5zZ2wsIHRhYmxlLT5uZW50cywKPj4+Pj4+PiArCQkJICAgICAgZGly ZWN0aW9uLCBETUFfQVRUUl9TS0lQX0NQVV9TWU5DKSkKPj4+Pj4+Cj4+Pj4+PiBVbmZvcnR1bmF0 ZWx5IEkgZG9uJ3QgdGhpbmsgeW91IGNhbiBkbyB0aGlzIGZvciBhIGNvdXBsZSByZWFzb25zLgo+ Pj4+Pj4gWW91IGNhbid0IHJlbHkgb24ge2JlZ2luLGVuZH1fY3B1X2FjY2VzcyBjYWxscyB0byBk byBjYWNoZSBtYWludGVuYW5jZS4KPj4+Pj4+IElmIHRoZSBjYWxscyB0byB7YmVnaW4sZW5kfV9j cHVfYWNjZXNzIHdlcmUgbWFkZSBiZWZvcmUgdGhlIGNhbGwgdG8gCj4+Pj4+PiBkbWFfYnVmX2F0 dGFjaCB0aGVuIHRoZXJlIHdvbid0IGhhdmUgYmVlbiBhIGRldmljZSBhdHRhY2hlZCBzbyB0aGUg Y2FsbHMgCj4+Pj4+PiB0byB7YmVnaW4sZW5kfV9jcHVfYWNjZXNzIHdvbid0IGhhdmUgZG9uZSBh bnkgY2FjaGUgbWFpbnRlbmFuY2UuCj4+Pj4+Pgo+Pj4+Pgo+Pj4+PiBUaGF0IHNob3VsZCBiZSBv a2F5IHRob3VnaCwgaWYgeW91IGhhdmUgbm8gYXR0YWNobWVudHMgKG9yIGFsbAo+Pj4+PiBhdHRh Y2htZW50cyBhcmUgSU8tY29oZXJlbnQpIHRoZW4gdGhlcmUgaXMgbm8gbmVlZCBmb3IgY2FjaGUK Pj4+Pj4gbWFpbnRlbmFuY2UuIFVubGVzcyB5b3UgbWVhbiBhIHNlcXVlbmNlIHdoZXJlIGEgbm9u LWlvLWNvaGVyZW50IGRldmljZQo+Pj4+PiBpcyBhdHRhY2hlZCBsYXRlciBhZnRlciBkYXRhIGhh cyBhbHJlYWR5IGJlZW4gd3JpdHRlbi4gRG9lcyB0aGF0Cj4+Pj4+IHNlcXVlbmNlIG5lZWQgc3Vw cG9ydGluZz8gCj4+Pj4KPj4+PiBZZXMsIGJ1dCBhbHNvIEkgdGhpbmsgdGhlcmUgYXJlIGNhc2Vz IHdoZXJlIENQVSBhY2Nlc3MgY2FuIGhhcHBlbiBiZWZvcmUgCj4+Pj4gaW4gQW5kcm9pZCwgYnV0 IEkgd2lsbCBmb2N1cyBvbiBsYXRlciBmb3Igbm93Lgo+Pj4+Cj4+Pj4+IERNQS1CVUYgZG9lc24n dCBoYXZlIHRvIGFsbG9jYXRlIHRoZSBiYWNraW5nCj4+Pj4+IG1lbW9yeSB1bnRpbCBtYXBfZG1h X2J1ZigpIHRpbWUsIGFuZCB0aGF0IHNob3VsZCBvbmx5IGhhcHBlbiBhZnRlciBhbGwKPj4+Pj4g dGhlIGRldmljZXMgaGF2ZSBhdHRhY2hlZCBzbyBpdCBjYW4ga25vdyB3aGVyZSB0byBwdXQgdGhl IGJ1ZmZlci4gU28gd2UKPj4+Pj4gc2hvdWxkbid0IGV4cGVjdCBhbnkgQ1BVIGFjY2VzcyB0byBi dWZmZXJzIGJlZm9yZSBhbGwgdGhlIGRldmljZXMgYXJlCj4+Pj4+IGF0dGFjaGVkIGFuZCBtYXBw ZWQsIHJpZ2h0Pwo+Pj4+Pgo+Pj4+Cj4+Pj4gSGVyZSBpcyBhbiBleGFtcGxlIHdoZXJlIENQVSBh Y2Nlc3MgY2FuIGhhcHBlbiBsYXRlciBpbiBBbmRyb2lkLgo+Pj4+Cj4+Pj4gQ2FtZXJhIGRldmlj ZSByZWNvcmRzIHZpZGVvIC0+IHNvZnR3YXJlIHBvc3QgcHJvY2Vzc2luZyAtPiB2aWRlbyBkZXZp Y2UgCj4+Pj4gKHdobyBkb2VzIGNvbXByZXNzaW9uIG9mIHJhdyBkYXRhKSBhbmQgd3JpdGVzIHRv IGEgZmlsZQo+Pj4+Cj4+Pj4gSW4gdGhpcyBleGFtcGxlIGFzc3VtZSB0aGUgYnVmZmVyIGlzIGNh Y2hlZCBhbmQgdGhlIGRldmljZXMgYXJlIG5vdCAKPj4+PiBJTy1jb2hlcmVudCAocXVpdGUgY29t bW9uKS4KPj4+Pgo+Pj4KPj4+IFRoaXMgaXMgdGhlIHN0YXJ0IG9mIHRoZSBwcm9ibGVtLCBoYXZp bmcgY2FjaGVkIG1hcHBpbmdzIG9mIG1lbW9yeSB0aGF0Cj4+PiBpcyBhbHNvIGJlaW5nIGFjY2Vz c2VkIG5vbi1jb2hlcmVudGx5IGlzIGdvaW5nIHRvIGNhdXNlIGlzc3VlcyBvbmUgd2F5Cj4+PiBv ciBhbm90aGVyLiBPbiB0b3Agb2YgdGhlIHNwZWN1bGF0aXZlIGNhY2hlIGZpbGxzIHRoYXQgaGF2 ZSB0byBiZQo+Pj4gY29uc3RhbnRseSBmb3VnaHQgYmFjayBhZ2FpbnN0IHdpdGggQ01PcyBsaWtl IGJlbG93OyBzb21lIGNvaGVyZW50Cj4+PiBpbnRlcmNvbm5lY3RzIGJlaGF2ZSBiYWRseSB3aGVu IHlvdSBtaXggY29oZXJlbnQgYW5kIG5vbi1jb2hlcmVudCBhY2Nlc3MKPj4+IChzbm9vcCBmaWx0 ZXJzIGdldCBtZXNzZWQgdXApLgo+Pj4KPj4+IFRoZSBzb2x1dGlvbiBpcyB0byBlaXRoZXIgYWx3 YXlzIGhhdmUgdGhlIGFkZHJlc3NlcyBtYXJrZWQgbm9uLWNvaGVyZW50Cj4+PiAobGlrZSBkZXZp Y2UgbWVtb3J5LCBuby1tYXAgY2FydmVvdXRzKSwgb3IgaWYgeW91IHJlYWxseSB3YW50IHRvIHVz ZQo+Pj4gcmVndWxhciBzeXN0ZW0gbWVtb3J5IGFsbG9jYXRlZCBhdCBydW50aW1lLCB0aGVuIGFs bCBjYWNoZWQgbWFwcGluZ3Mgb2YKPj4+IGl0IG5lZWQgdG8gYmUgZHJvcHBlZCwgZXZlbiB0aGUg a2VybmVsIGxvZ2ljYWwgYWRkcmVzcyAoYXJlYSBhcyBwYWluZnVsCj4+PiBhcyB0aGF0IHdvdWxk IGJlKS4KPiAKPiBPdWNoIDotKCBJIHdhc24ndCBhd2FyZSBhYm91dCB0aGVzZSBwb3RlbnRpYWwg aW50ZXJjb25uZWN0IGlzc3Vlcy4gSG93Cj4gInJlYWwiIGlzIHRoYXQ/IEl0IHNlZW1zIHRoYXQg d2UgYXJlbid0IHJlYWxseSBoaXR0aW5nIHRoYXQgdG9kYXkgb24KPiByZWFsIGRldmljZXMuCj4g CgpTYWRseSB0aGVyZSBpcyBhdCBsZWFzdCBvbmUgcmVhbCBkZXZpY2UgbGlrZSB0aGlzIG5vdyAo VEkgQU02NTQpLiBXZQpzcGVudCBzb21lIHRpbWUgd29ya2luZyB3aXRoIHRoZSBBUk0gaW50ZXJj b25uZWN0IHNwZWMgZGVzaWduZXJzIHRvIHNlZQppZiB0aGlzIHdhcyBhbGxvd2VkIGJlaGF2aW9y LCBmaW5hbCBjb25jbHVzaW9uIHdhcyBtaXhpbmcgY29oZXJlbnQgYW5kCm5vbi1jb2hlcmVudCBh Y2Nlc3NlcyBpcyBuZXZlciBhIGdvb2QgaWRlYS4uIFNvIHdlIGhhdmUgYmVlbiB3b3JraW5nIHRv CnRyeSB0byBtaW5pbWl6ZSBhbnkgY2FzZXMgb2YgbWl4ZWQgYXR0cmlidXRlcyBbMF0sIGlmIGEg cmVnaW9uIGlzCmNvaGVyZW50IHRoZW4gZXZlcnlvbmUgaW4gdGhlIHN5c3RlbSBuZWVkcyB0byB0 cmVhdCBpdCBhcyBzdWNoIGFuZAp2aWNlLXZlcnNhLCBldmVuIGNsZXZlciBDTU8gdGhhdCB3b3Jr IG9uIG90aGVyIHN5c3RlbXMgd29udCBzYXZlIHlvdQpoZXJlLiA6KAoKWzBdIGh0dHBzOi8vZ2l0 aHViLmNvbS9BUk0tc29mdHdhcmUvYXJtLXRydXN0ZWQtZmlybXdhcmUvcHVsbC8xNTUzCgoKPj4+ Cj4+Pj4gSU9OIGJ1ZmZlciBpcyBhbGxvY2F0ZWQuCj4+Pj4KPj4+PiAvL0NhbWVyYSBkZXZpY2Ug cmVjb3JkcyB2aWRlbwo+Pj4+IGRtYV9idWZfYXR0YWNoCj4+Pj4gZG1hX21hcF9hdHRhY2htZW50 IChidWZmZXIgbmVlZHMgdG8gYmUgY2xlYW5lZCkKPj4+Cj4+PiBXaHkgZG9lcyB0aGUgYnVmZmVy IG5lZWQgdG8gYmUgY2xlYW5lZCBoZXJlPyBJIGp1c3QgZ290IHRocm91Z2ggcmVhZGluZwo+Pj4g dGhlIHRocmVhZCBsaW5rZWQgYnkgTGF1cmEgaW4gdGhlIG90aGVyIHJlcGx5LiBJIGRvIGxpa2Ug K0JyaWFuJ3MKPj4KPj4gQWN0dWFsbHkgK0JyaWFuIHRoaXMgdGltZSA6KQo+Pgo+Pj4gc3VnZ2Vz dGlvbiBvZiB0cmFja2luZyBpZiB0aGUgYnVmZmVyIGhhcyBoYWQgQ1BVIGFjY2VzcyBzaW5jZSB0 aGUgbGFzdAo+Pj4gdGltZSBhbmQgb25seSBmbHVzaGluZyB0aGUgY2FjaGUgaWYgaXQgaGFzLiBB cyB1bm1hcHBlZCBoZWFwcyBuZXZlciBnZXQKPj4+IENQVSBtYXBwZWQgdGhpcyB3b3VsZCBuZXZl ciBiZSB0aGUgY2FzZSBmb3IgdW5tYXBwZWQgaGVhcHMsIGl0IHNvbHZlcyBteQo+Pj4gcHJvYmxl bS4KPj4+Cj4+Pj4gW2NhbWVyYSBkZXZpY2Ugd3JpdGVzIHRvIGJ1ZmZlcl0KPj4+PiBkbWFfYnVm X3VubWFwX2F0dGFjaG1lbnQgKGJ1ZmZlciBuZWVkcyB0byBiZSBpbnZhbGlkYXRlZCkKPj4+Cj4+ PiBJdCBkb2Vzbid0IGtub3cgdGhlcmUgd2lsbCBiZSBhbnkgZnVydGhlciBDUFUgYWNjZXNzLCBp dCBjb3VsZCBnZXQgZnJlZWQKPj4+IGFmdGVyIHRoaXMgZm9yIGFsbCB3ZSBrbm93LCB0aGUgaW52 YWxpZGF0ZSBjYW4gYmUgc2F2ZWQgdW50aWwgdGhlIENQVQo+Pj4gcmVxdWVzdHMgYWNjZXNzIGFn YWluLgo+IAo+IFdlIGRvbid0IGhhdmUgYW55IEFQSSB0byBhbGxvdyB0aGUgaW52YWxpZGF0ZSB0 byBoYXBwZW4gb24gQ1BVIGFjY2Vzcwo+IGlmIGFsbCBkZXZpY2VzIGFscmVhZHkgZGV0YWNoZWQu IFdlIG5lZWQgYSBzdHJ1Y3QgZGV2aWNlIHBvaW50ZXIgdG8KPiBnaXZlIHRvIHRoZSBETUEgQVBJ LCBvdGhlcndpc2Ugb24gYXJtNjQgdGhlcmUnbGwgYmUgbm8gaW52YWxpZGF0ZS4KPiAKPiBJIGhh ZCBhIGNoYXQgd2l0aCBhIGZldyBwZW9wbGUgaW50ZXJuYWxseSBhZnRlciB0aGUgcHJldmlvdXMK PiBkaXNjdXNzaW9uIHdpdGggTGlhbS4gT25lIHN1Z2dlc3Rpb24gd2FzIHRvIHVzZQo+IERNQV9B VFRSX1NLSVBfQ1BVX1NZTkMgaW4gdW5tYXBfZG1hX2J1ZiwgYnV0IG9ubHkgaWYgdGhlcmUncyBh dCBsZWFzdAo+IG9uZSBvdGhlciBkZXZpY2UgYXR0YWNoZWQgKGd1YXJhbnRlZXMgdGhhdCB3ZSBj YW4gZG8gYW4gaW52YWxpZGF0ZSBpbgo+IHRoZSBmdXR1cmUgaWYgYmVnaW5fY3B1X2FjY2VzcyBp cyBjYWxsZWQpLiBJZiB0aGUgbGFzdCBkZXZpY2UKPiBkZXRhY2hlcywgZG8gYSBzeW5jIHRoZW4u Cj4gCj4gQ29udmVyc2VseSwgaW4gbWFwX2RtYV9idWYsIHdlIHdvdWxkIHRyYWNrIGlmIHRoZXJl IHdhcyBhbnkgQ1BVIGFjY2Vzcwo+IGFuZCB1c2Uvc2tpcCB0aGUgc3luYyBhcHByb3ByaWF0ZWx5 Lgo+IAoKTm93IHRoYXQgSSB0aGluayB0aGlzIGFsbCB0aHJvdWdoIEkgYWdyZWUgdGhpcyBwYXRj aCBpcyBwcm9iYWJseSB3cm9uZy4KVGhlIHJlYWwgZml4IG5lZWRzIHRvIGJlIGJldHRlciBoYW5k bGluZyBpbiB0aGUgZG1hX21hcF9zZygpIHRvIGRlYWwKd2l0aCB0aGUgY2FzZSBvZiB0aGUgbWVt b3J5IG5vdCBiZWluZyBtYXBwZWQgKHdoYXQgSSdtIGRlYWxpbmcgd2l0aCBmb3IKdW5tYXBwZWQg aGVhcHMpLCBhbmQgZm9yIGNhc2VzIHdoZW4gdGhlIG1lbW9yeSBpbiBxdWVzdGlvbiBpcyBub3Qg Y2FjaGVkCihMaWFtJ3MgaXNzdWUgSSB0aGluaykuIEZvciBib3RoIHRoZXNlIGNhc2VzIHRoZSBk bWFfbWFwX3NnKCkgZG9lcyB0aGUKd3JvbmcgdGhpbmcuCgo+IEkgZGlkIHN0YXJ0IHBva2luZyB0 aGUgY29kZSB0byBjaGVjayBvdXQgaG93IHRoYXQgd291bGQgbG9vaywgYnV0IHRoZW4KPiBDaHJp c3RtYXMgaGFwcGVuZWQgYW5kIEknbSBzdGlsbCBjYXRjaGluZyBiYWNrIHVwLgo+IAo+Pj4KPj4+ PiBkbWFfYnVmX2RldGFjaCAgKGRldmljZSBjYW5ub3Qgc3RheSBhdHRhY2hlZCBiZWNhdXNlIGl0 IGlzIGJlaW5nIHNlbnQgZG93biAKPj4+PiB0aGUgcGlwZWxpbmUgYW5kIENhbWVyYSBkb2Vzbid0 IGtub3cgdGhlIGVuZCBvZiB0aGUgdXNlIGNhc2UpCj4+Pj4KPj4+Cj4+PiBUaGlzIHNlZW1zIGxp a2UgYSBicm9rZW4gdXNlLWNhc2UsIEkgdW5kZXJzdGFuZCB0aGUgZGVzaXJlIHRvIGtlZXAKPj4+ IGV2ZXJ5dGhpbmcgYXMgbW9kdWxhciBhcyBwb3NzaWJsZSBhbmQgc2VwYXJhdGUgdGhlIHN0ZXBz LCBidXQgYXQgdGhpcwo+Pj4gcG9pbnQgbm8gb25lIG93bnMgdGhpcyBidWZmZXJzIGJhY2tpbmcg bWVtb3J5LCBub3QgdGhlIENQVSBvciBhbnkKPj4+IGRldmljZS4gSSB3b3VsZCBnbyBhcyBmYXIg YXMgdG8gc2F5IERNQS1CVUYgc2hvdWxkIGJlIGZyZWUgbm93IHRvCj4+PiBkZS1hbGxvY2F0ZSB0 aGUgYmFja2luZyBzdG9yYWdlIGlmIGl0IHdhbnRzLCB0aGF0IHdheSBpdCBjb3VsZCBnZXQgcmVh ZHkKPj4+IGZvciB0aGUgbmV4dCBhdHRhY2htZW50LCB3aGljaCBtYXkgY2hhbmdlIHRoZSByZXF1 aXJlZCBiYWNraW5nIG1lbW9yeQo+Pj4gY29tcGxldGVseS4KPj4+Cj4+PiBBbGwgZGV2aWNlcyBz aG91bGQgYXR0YWNoIGJlZm9yZSB0aGUgZmlyc3QgbWFwcGluZywgYW5kIG9ubHkgbGV0IGdvCj4+ PiBhZnRlciB0aGUgdGFzayBpcyBjb21wbGV0ZSwgb3RoZXJ3aXNlIHRoaXMgYnVmZmVycyBkYXRh IG5lZWRzIGNvcGllZCBvZmYKPj4+IHRvIGEgZGlmZmVyZW50IGxvY2F0aW9uIG9yIHRoZSBDUFUg bmVlZHMgdG8gdGFrZSBvd25lcnNoaXAgaW4tYmV0d2Vlbi4KPj4+Cj4gCj4gWWVhaC4uIHRoYXQn cyBjZXJ0YWlubHkgdGhlIHRoZW9yeS4gQXJlIHRoZXJlIGFueSBETUEtQlVGCj4gaW1wbGVtZW50 YXRpb25zIHdoaWNoIGFjdHVhbGx5IGRvIHRoYXQ/IEkgaGVhciBpdCBxdW90ZWQgYSBsb3QsCj4g YmVjYXVzZSB0aGF0J3Mgd2hhdCB0aGUgZG9jcyBzYXkgLSBidXQgaWYgdGhlIHJlYWxpdHkgZG9l c24ndCBtYXRjaAo+IGl0LCBtYXliZSB3ZSBzaG91bGQgY2hhbmdlIHRoZSBkb2NzLgo+IAoKRG8g eW91IG1lYW4gb24gdGhlIHVzZXJzcGFjZSBzaWRlPyBJJ20gbm90IHN1cmUsIHNlZW1zIGxpa2Ug QW5kcm9pZAptaWdodCBiZSBkb2luZyB0aGlzIHdyb25nIGZyb20gd2hhdCBJIGNhbiBnYXRoZXIu IEZyb20ga2VybmVsIHNpZGUgaWYKeW91IG1lYW4gdGhlICJkZS1hbGxvY2F0ZSB0aGUgYmFja2lu ZyBzdG9yYWdlIiwgd2Ugd2lsbCBoYXZlIHNvbWUgY2FzZXMKbGlrZSB0aGlzIHNvb24sIHNvIEkg d2FudCB0byBtYWtlIHN1cmUgdXNlcnNwYWNlIGlzIG5vdCBhYnVzaW5nIERNQS1CVUYKaW4gd2F5 cyBub3Qgc3BlY2lmaWVkIGluIHRoZSBkb2N1bWVudGF0aW9uLiBDaGFuZ2luZyB0aGUgZG9jcyB0 byBmb3JjZQp0aGUgYmFja2luZyBtZW1vcnkgdG8gYWx3YXlzIGJlIGFsbG9jYXRlZCBicmVha3Mg dGhlIGNlbnRyYWwgZ29hbCBpbgpoYXZpbmcgYXR0YWNoL21hcCBpbiBETUEtQlVGIHNlcGFyYXRl LgoKPj4+PiAvL2J1ZmZlciBpcyBzZW5kIGRvd24gdGhlIHBpcGVsaW5lCj4+Pj4KPj4+PiAvLyBV c2Vyc2FwY2Ugc29mdHdhcmUgcG9zdCBwcm9jZXNzaW5nIG9jY3Vycwo+Pj4+IG1tYXAgYnVmZmVy Cj4+Pgo+Pj4gUGVyaGFwcyB0aGUgaW52YWxpZGF0ZSBzaG91bGQgaGFwcGVuIGhlcmUgaW4gbW1h cC4KPj4+Cj4+Pj4gRE1BX0JVRl9JT0NUTF9TWU5DIElPQ1Qgd2l0aCBmbGFncyBETUFfQlVGX1NZ TkNfU1RBUlQgLy8gTm8gQ01PIHNpbmNlIG5vIAo+Pj4+IGRldmljZXMgYXR0YWNoZWQgdG8gYnVm ZmVyCj4+Pgo+Pj4gQW5kIHRoYXQgc2hvdWxkIGJlIG9rYXksIG1tYXAgZG9lcyB0aGUgc3luYywg YW5kIGlmIG5vIGRldmljZXMgYXJlCj4+PiBhdHRhY2hlZCBub3RoaW5nIGNvdWxkIGhhdmUgY2hh bmdlZCB0aGUgdW5kZXJseWluZyBtZW1vcnkgaW4gdGhlCj4+PiBtZWFuLXRpbWUsIERNQV9CVUZf U1lOQ19TVEFSVCBjYW4gc2FmZWx5IGJlIGEgbm8tb3AgYXMgdGhleSBhcmUuCj4gCj4gWWVhaCwg dGhhdCdzIHRydWUgLSBzbyBsb25nIGFzIHlvdSBkaWQgYW4gaW52YWxpZGF0ZSBpbiB1bm1hcF9k bWFfYnVmLgo+IExpYW0gd2FzIHNheWluZyB0aGF0IGl0J3MgdG9vIHBhaW5mdWwgZm9yIHRoZW0g dG8gZG8gdGhhdCBldmVyeSB0aW1lIGEKPiBkZXZpY2UgdW5tYXBzIC0gd2hlbiBpbiBtYW55IGNh c2VzIChkZXZpY2UtPmRldmljZSwgbm8gQ1BVKSBpdCdzIG5vdAo+IG5lZWRlZC4KCkludmFsaWRh dGVzIGFyZSBwYWlubGVzcywgYXQgbGVhc3QgY29tcGFyZWQgdG8gYSByZWFsIGNhY2hlIGZsdXNo LCBqdXN0CnNldCB0aGUgaW52YWxpZCBiaXQgdnMgYWN0dWFsbHkgd3JpdGluZyBvdXQgbGluZXMu IEkgdGhvdWdodCB0aGUgaXNzdWUKd2FzIG9uIHRoZSBtYXAgc2lkZS4KCj4gCj4+Pgo+Pj4+IFtD UFUgcmVhZHMvd3JpdGVzIHRvIHRoZSBidWZmZXJdCj4+Pj4gRE1BX0JVRl9JT0NUTF9TWU5DIElP Q1RMIHdpdGggZmxhZ3MgRE1BX0JVRl9TWU5DX0VORCAvLyBObyBDTU8gc2luY2Ugbm8gCj4+Pj4g ZGV2aWNlcyBhdHRhY2hlZCB0byBidWZmZXIKPj4+PiBtdW5tYXAgYnVmZmVyCj4+Pj4KPj4+PiAv L2J1ZmZlciBpcyBzZW5kIGRvd24gdGhlIHBpcGVsaW5lCj4+Pj4gLy8gQnVmZmVyIGlzIHNlbmQg dG8gdmlkZW8gZGV2aWNlICh3aG8gZG9lcyBjb21wcmVzc2lvbiBvZiByYXcgZGF0YSkgYW5kIAo+ Pj4+IHdyaXRlcyB0byBhIGZpbGUKPj4+PiBkbWFfYnVmX2F0dGFjaAo+Pj4+IGRtYV9tYXBfYXR0 YWNobWVudCAoYnVmZmVyIG5lZWRzIHRvIGJlIGNsZWFuZWQpCj4+Pj4gW3ZpZGVvIGRldmljZSB3 cml0ZXMgdG8gYnVmZmVyXQo+Pj4+IGRtYV9idWZfdW5tYXBfYXR0YWNobWVudCAKPj4+PiBkbWFf YnVmX2RldGFjaCAgKGRldmljZSBjYW5ub3Qgc3RheSBhdHRhY2hlZCBiZWNhdXNlIGl0IGlzIGJl aW5nIHNlbnQgZG93biAKPj4+PiB0aGUgcGlwZWxpbmUgYW5kIFZpZGVvIGRvZXNuJ3Qga25vdyB0 aGUgZW5kIG9mIHRoZSB1c2UgY2FzZSkKPj4+Pgo+Pj4+Cj4+Pj4KPj4+Pj4+IEFsc28gSU9OIG5v IGxvbmdlciBwcm92aWRlcyBETUEgcmVhZHkgbWVtb3J5LCBzbyBpZiB5b3UgYXJlIG5vdCBkb2lu ZyBDUFUgCj4+Pj4+PiBhY2Nlc3MgdGhlbiB0aGVyZSBpcyBubyByZXF1aXJlbWVudCAodGhhdCBJ IGFtIGF3YXJlIG9mKSBmb3IgeW91IHRvIGNhbGwgCj4+Pj4+PiB7YmVnaW4sZW5kfV9jcHVfYWNj ZXNzIGJlZm9yZSBwYXNzaW5nIHRoZSBidWZmZXIgdG8gdGhlIGRldmljZSBhbmQgaWYgdGhpcyAK Pj4+Pj4+IGJ1ZmZlciBpcyBjYWNoZWQgYW5kIHlvdXIgZGV2aWNlIGlzIG5vdCBJTy1jb2hlcmVu dCB0aGVuIHRoZSBjYWNoZSBtYWludGVuYW5jZQo+Pj4+Pj4gaW4gaW9uX21hcF9kbWFfYnVmIGFu ZCBpb25fdW5tYXBfZG1hX2J1ZiBpcyByZXF1aXJlZC4KPj4+Pj4+Cj4+Pj4+Cj4+Pj4+IElmIEkg YW0gbm90IGRvaW5nIGFueSBDUFUgYWNjZXNzIHRoZW4gd2h5IGRvIEkgbmVlZCBDUFUgY2FjaGUK Pj4+Pj4gbWFpbnRlbmFuY2Ugb24gdGhlIGJ1ZmZlcj8KPj4+Pj4KPj4+Pgo+Pj4+IEJlY2F1c2Ug SU9OIG5vIGxvbmdlciBwcm92aWRlcyBETUEgcmVhZHkgbWVtb3J5Lgo+Pj4+IFRha2UgdGhlIGFi b3ZlIGV4YW1wbGUuCj4+Pj4KPj4+PiBJT04gYWxsb2NhdGVzIG1lbW9yeSBmcm9tIGJ1ZGR5IGFs bG9jYXRvciBhbmQgcmVxdWVzdHMgemVyb2luZy4KPj4+PiBaZXJvcyBhcmUgd3JpdHRlbiB0byB0 aGUgY2FjaGUuCj4+Pj4KPj4+PiBZb3UgcGFzcyB0aGUgYnVmZmVyIHRvIHRoZSBjYW1lcmEgZGV2 aWNlIHdoaWNoIGlzIG5vdCBJTy1jb2hlcmVudC4KPj4+PiBUaGUgY2FtZXJhIGRldmljZXMgd3Jp dGVzIGRpcmVjdGx5IHRvIHRoZSBidWZmZXIgaW4gRERSLgo+Pj4+IFNpbmNlIHlvdSBkaWRuJ3Qg Y2xlYW4gdGhlIGJ1ZmZlciBhIGRpcnR5IGNhY2hlIGxpbmUgKG9uZSBvZiB0aGUgemVyb3MpIGlz IAo+Pj4+IGV2aWN0ZWQgZnJvbSB0aGUgY2FjaGUsIHRoaXMgemVybyBvdmVyd3JpdGVzIGRhdGEg dGhlIGNhbWVyYSBkZXZpY2UgaGFzIAo+Pj4+IHdyaXR0ZW4gd2hpY2ggY29ycnVwdHMgeW91ciBk YXRhLgo+Pj4+Cj4+Pgo+Pj4gVGhlIHplcm9pbmcgKmlzKiBhIENQVSBhY2Nlc3MsIHRoZXJlZm9y IGl0IHNob3VsZCBoYW5kbGUgdGhlIG5lZWRlZCBDTU8KPj4+IGZvciBDUFUgYWNjZXNzIGF0IHRo ZSB0aW1lIG9mIHplcm9pbmcuCj4+Pgo+IAo+IEFjdHVhbGx5IHRoYXQgc2hvdWxkIGJlIGF0IHRo ZSBwb2ludCBvZiB0aGUgZmlyc3Qgbm9uLWNvaGVyZW50IGRldmljZQo+IG1hcHBpbmcgdGhlIGJ1 ZmZlciByaWdodD8gTm8gcG9pbnQgaW4gZG9pbmcgQ01PIGlmIHRoZSBmdXR1cmUgYWNjZXNzZXMK PiBhcmUgY29oZXJlbnQuCgpJIHNlZSB5b3VyIHBvaW50LCBhcyBsb25nIGFzIHRoZSB6ZXJvaW5n IGlzIGd1YXJhbnRlZWQgdG8gYmUgdGhlIGZpcnN0CmFjY2VzcyB0byB0aGlzIGJ1ZmZlciB0aGVu IGl0IHNob3VsZCBiZSBzYWZlLgoKQW5kcmV3Cgo+IAo+IENoZWVycywKPiAtQnJpYW4KPiAKPj4+ IEFuZHJldwo+Pj4KPj4+PiBMaWFtCj4+Pj4KPj4+PiBRdWFsY29tbSBJbm5vdmF0aW9uIENlbnRl ciwgSW5jLiBpcyBhIG1lbWJlciBvZiBDb2RlIEF1cm9yYSBGb3J1bSwKPj4+PiBhIExpbnV4IEZv dW5kYXRpb24gQ29sbGFib3JhdGl2ZSBQcm9qZWN0Cj4+Pj4KX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX18KZHJpLWRldmVsIG1haWxpbmcgbGlzdApkcmktZGV2 ZWxAbGlzdHMuZnJlZWRlc2t0b3Aub3JnCmh0dHBzOi8vbGlzdHMuZnJlZWRlc2t0b3Aub3JnL21h aWxtYW4vbGlzdGluZm8vZHJpLWRldmVsCg==