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=-10.1 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, MENTIONS_GIT_HOSTING,NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS,USER_AGENT_SANE_1 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 F3720C433E0 for ; Tue, 9 Mar 2021 18:08:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B961F65238 for ; Tue, 9 Mar 2021 18:08:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231127AbhCISI0 (ORCPT ); Tue, 9 Mar 2021 13:08:26 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49760 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230173AbhCISHy (ORCPT ); Tue, 9 Mar 2021 13:07:54 -0500 Received: from smtp.domeneshop.no (smtp.domeneshop.no [IPv6:2a01:5b40:0:3005::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9402EC06174A for ; Tue, 9 Mar 2021 10:07:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=tronnes.org ; s=ds202012; h=Content-Transfer-Encoding:Content-Type:In-Reply-To: MIME-Version:Date:Message-ID:From:References:Cc:To:Subject:Sender:Reply-To: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=GmBMPW+tTISD6uwv8VQMdpaP5z44nBOdyC9Ca3KH5BQ=; b=RLM6dqwmY3E2wxWOF1JKB1r2HD yTFjtCdAyt0hi+vU28fIRQQIhzvca+7RhPVqgjOpInEAUxxsHjlj+Gl3JRi3++5cf8b6VYjoMitdZ prcs8ZJZyIvJZUmc54n18vWlGgrLrWP2ubdh+btLh/5p1wK2bAIepXybVveeWsuiDXsoVdvIK30OT KTVCByFGlfCqD4ThEDYyUGwcYu6LNH4sYj+gDonInQgVfXqLv7f3CS5epuc67n+AlHZWVgEDOrcLU TrAlDYNzHCH74fHI1jqF08XJQWRdRrUguItLlM89Va080ZgHY1mHqE8jSAx/XwwT+rx88I9OPaooE GPpdhaUg==; Received: from [2a01:799:95f:4600:cca0:57ac:c55d:a485] (port=49211) by smtp.domeneshop.no with esmtpsa (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1lJglr-0005z9-Cf; Tue, 09 Mar 2021 19:07:51 +0100 Subject: Re: [PATCH v7 3/3] drm: Add GUD USB Display driver To: Peter Stuge Cc: dri-devel@lists.freedesktop.org, hudson@trmm.net, markus@raatikainen.cc, sam@ravnborg.org, linux-usb@vger.kernel.org, th020394@gmail.com, lkundrak@v3.sk, pontus.fuchs@gmail.com, Daniel Vetter References: <20210305163104.30756-1-noralf@tronnes.org> <20210305163104.30756-4-noralf@tronnes.org> <20210309140200.13094.qmail@stuge.se> From: =?UTF-8?Q?Noralf_Tr=c3=b8nnes?= Message-ID: <59bf10c7-91aa-ba09-7128-91e87272e29e@tronnes.org> Date: Tue, 9 Mar 2021 19:07:46 +0100 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Thunderbird/78.8.0 MIME-Version: 1.0 In-Reply-To: <20210309140200.13094.qmail@stuge.se> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Den 09.03.2021 15.02, skrev Peter Stuge: > Hello Noralf, > > I've made some progress with my test device. I'm implementing R1 > first and once that works I'll test RGB111 as well. Along the way > I've found a couple of things in the code: > > Noralf Trønnes wrote: >> +++ b/drivers/gpu/drm/gud/gud_drv.c > .. >> +static int gud_probe(struct usb_interface *intf, const struct usb_device_id *id) > .. >> + if (format == GUD_DRM_FORMAT_R1) >> + continue; /* Internal not for userspace */ > > You already found RGB111 missing here. > > >> +static int gud_usb_control_msg(struct usb_interface *intf, bool in, >> + u8 request, u16 value, void *buf, size_t len) > .. >> +static int gud_usb_transfer(struct gud_device *gdrm, bool in, u8 request, u16 index, > .. >> + ret = gud_usb_control_msg(intf, in, request, index, buf, len); > > The u16 index parameter to gud_usb_transfer() and at least also > gud_usb_{get,set,get_u8,set_u8}() is eventually passed in u16 value > in the call to gud_usb_control_msg(), which had me confused for a bit. > > What do you think about renaming all of those parameters to wValue, > to show that and where they are part of the control request? I think > it would help make the protocol more clear. > Only connector requests use this value and in that case it's the connector index. I need to get this driver applied now, and can't spend more time polishing it, so I'll just keep it as-is. > > Finally, an actual bug: > >> + ret = gud_get_properties(gdrm); >> + if (ret) { >> + dev_err(dev, "Failed to get properties (error=%d)\n", ret); >> + return ret; >> + } > > If gud_get_properties() and gud_connector_add_properties() receive > and process (only!) one or more unknown properties then they return > the number of bytes received from the device rather than 0. > > I fixed this by setting ret = 0; before the for() loop, but maybe you > want to do it another way. > I'll do that. > > I found this because I can't get my device to send 0 bytes IN when > the host requests more, if I provide no data the request STALLs. This > is for sure a bug in my device and I'll come back to it, but for now > I added a dummy 65535 property as a workaround. > > What do you think about formalizing this, adding an actual dummy property? > I want to avoid that. I'd rather add a descriptor flag GUD_DISPLAY_FLAG_CANT_RETURN_ZERO or something for such devices. Also this property warning is just a debug message so not a very big problem. Worse is EDID if you don't want to support that since it prints an error in that case. > Or maybe adding flags to the display descriptor for "I have properties", > "I have connector properties" and "I have EDID" ? > Then I might as well go back to the previous version and have count in the structs won't I ;) > >> +++ b/drivers/gpu/drm/gud/gud_pipe.c > .. >> +static int gud_prep_flush(struct gud_device *gdrm, struct drm_framebuffer *fb, > .. >> + /* >> + * Imported buffers are assumed to be write-combined and thus uncached >> + * with slow reads (at least on ARM). >> + */ >> + if (format != fb->format) { >> + if (format->format == GUD_DRM_FORMAT_R1) { >> + len = gud_xrgb8888_to_r124(buf, format, vaddr, fb, rect); >> + if (!len) { >> + ret = -ENOMEM; >> + goto end_cpu_access; >> + } >> + } else if (format->format == DRM_FORMAT_RGB565) { >> + drm_fb_xrgb8888_to_rgb565(buf, vaddr, fb, rect, gud_is_big_endian()); >> + } else { >> + len = gud_xrgb8888_to_color(buf, format, vaddr, fb, rect); >> + } > > Does this section also need a RGB111 case? > gud_xrgb8888_to_color() handles that, although broken in this version for partial updates. Here's the fix: https://gist.github.com/notro/a94d381cf98b7e15fcddbc90e4af0a21 > >> +void gud_pipe_update(struct drm_simple_display_pipe *pipe, > .. >> + if (fb && (crtc->state->mode_changed || crtc->state->connectors_changed)) >> + gud_usb_set(gdrm, GUD_REQ_SET_STATE_COMMIT, 0, NULL, 0); > > You mentioned that commit must not fail; what happens/should happen > if a request does fail in pipe_update()? Some reasons could be that > the device was unplugged, a bad cable is glitchy or even that some > device doesn't even implement STATE_COMMIT or does it incorrectly and > will report back failure? > The failure is just ignored since there's nothing to be done. The error counter for the debufgs file is increased, making it somewhat visible. I've chosen to only print probe errors, flush errors and devices returning incorrect reply lengths. I hate drivers that fill the logs with errors, but I might have gone to far on the silent side, I don't know. But one nice thing about DRM is that debug is always builtin and can be enabled. > >> +++ b/include/drm/gud.h > .. >> + #define GUD_STATUS_REQUEST_NOT_SUPPORTED 0x02 > > Maybe this can be removed? SET_VERSION has been removed so it's no > longer used anywhere, and in any case devices typically signal that > requests are unsupported using a protocol STALL, which comes back > as -EPIPE from the USB stack. > The driver issues a GUD_REQ_GET_STATUS on -EPIPE to find out what the exact problem is. GUD_STATUS_REQUEST_NOT_SUPPORTED is returned by the device on an unsupported/unrecognised request. > > > Finally, here's the drm debug output when I connect my device: > > Mar 09 14:57:19 vm kernel: usb 1-1: new full-speed USB device number 24 using uhci_hcd > Mar 09 14:57:19 vm kernel: gud 1-1:27.0: [drm:gud_probe] version=1 flags=0x2 compression=0x0 max_buffer_size=0 > Mar 09 14:57:19 vm kernel: gud 1-1:27.0: [drm:gud_usb_transfer] get: request=0x40 index=0 len=32 > Mar 09 14:57:19 vm kernel: gud 1-1:27.0: [drm:gud_usb_transfer] get: request=0x41 index=0 len=320 > Mar 09 14:57:19 vm kernel: gud 1-1:27.0: [drm:gud_probe] Ignoring unknown property: 65535 > Mar 09 14:57:19 vm kernel: gud 1-1:27.0: [drm:gud_usb_transfer] get: request=0x50 index=0 len=256 > Mar 09 14:57:19 vm kernel: gud 1-1:27.0: [drm:gud_get_connectors] Connector: index=0 type=0 flags=0x0 > Mar 09 14:57:19 vm kernel: gud 1-1:27.0: [drm:gud_usb_transfer] get: request=0x51 index=0 len=320 > Mar 09 14:57:19 vm kernel: gud 1-1:27.0: [drm:gud_get_connectors] property: 65535 = 0(0x0) > Mar 09 14:57:19 vm kernel: gud 1-1:27.0: [drm:gud_get_connectors] Ignoring unknown property: 65535 > Mar 09 14:57:19 vm kernel: [drm:drm_minor_register] > Mar 09 14:57:19 vm kernel: [drm:drm_minor_register] > Mar 09 14:57:19 vm kernel: [drm:drm_minor_register] new minor registered 0 > Mar 09 14:57:19 vm kernel: [drm:drm_sysfs_connector_add] adding "USB-1" to sysfs > Mar 09 14:57:19 vm kernel: [drm:drm_sysfs_hotplug_event] generating hotplug event > Mar 09 14:57:19 vm kernel: [drm] Initialized gud 1.0.0 20200422 for 1-1:27.0 on minor 0 > Mar 09 14:57:19 vm kernel: [drm:drm_client_modeset_probe] > Mar 09 14:57:19 vm kernel: [drm:drm_mode_object_get] OBJ ID: 35 (2) > Mar 09 14:57:19 vm kernel: [drm:drm_helper_probe_single_connector_modes] [CONNECTOR:35:USB-1] > Mar 09 14:57:19 vm kernel: gud 1-1:27.0: [drm:gud_usb_transfer] set: request=0x53 index=0 len=0 > Mar 09 14:57:19 vm kernel: gud 1-1:27.0: [drm:gud_usb_transfer] get: request=0x54 index=0 len=1 > Mar 09 14:57:19 vm kernel: [drm:drm_helper_probe_single_connector_modes] [CONNECTOR:35:USB-1] status updated from unknown to connected > Mar 09 14:57:19 vm kernel: gud 1-1:27.0: [drm:gud_usb_transfer] get: request=0x56 index=0 len=2048 > Mar 09 14:57:19 vm kernel: [drm:drm_sysfs_hotplug_event] generating hotplug event > Mar 09 14:57:19 vm kernel: gud 1-1:27.0: USB-1: Invalid EDID size (ret=1) > Mar 09 14:57:19 vm kernel: gud 1-1:27.0: [drm:gud_usb_transfer] get: request=0x55 index=0 len=3072 > Mar 09 14:57:19 vm kernel: [drm:drm_helper_probe_single_connector_modes] [CONNECTOR:35:USB-1] probed modes : > Mar 09 14:57:19 vm kernel: [drm:drm_mode_debug_printmodeline] Modeline "400x240": 104 10000 400 400 400 400 240 240 240 240 0x40 0x0 > Mar 09 14:57:19 vm kernel: [drm:drm_client_modeset_probe] connector 35 enabled? yes > Mar 09 14:57:19 vm kernel: [drm:drm_client_modeset_probe] Not using firmware configuration > Mar 09 14:57:19 vm kernel: [drm:drm_client_modeset_probe] looking for cmdline mode on connector 35 > Mar 09 14:57:19 vm kernel: [drm:drm_client_modeset_probe] looking for preferred mode on connector 35 0 > Mar 09 14:57:19 vm kernel: [drm:drm_client_modeset_probe] found mode 400x240 > Mar 09 14:57:19 vm kernel: [drm:drm_client_modeset_probe] picking CRTCs for 400x240 config > Mar 09 14:57:19 vm kernel: [drm:drm_client_modeset_probe] desired mode 400x240 set on crtc 33 (0,0) > Mar 09 14:57:19 vm kernel: [drm:drm_mode_object_get] OBJ ID: 35 (2) > Mar 09 14:57:19 vm kernel: [drm:drm_mode_object_put.part.0] OBJ ID: 35 (3) > Mar 09 14:57:19 vm kernel: gud 1-1:27.0: [drm:__drm_fb_helper_initial_config_and_unlock] test CRTC 0 primary plane > Mar 09 14:57:19 vm kernel: gud 1-1:27.0: [drm:drm_fb_helper_generic_probe] surface width(400), height(240) and bpp(32) > Mar 09 14:57:19 vm kernel: [drm:drm_mode_addfb2] [FB:36] > Mar 09 14:57:19 vm kernel: [drm:drm_mode_object_put.part.0] OBJ ID: 36 (2) > Mar 09 14:57:19 vm kernel: gud 1-1:27.0: [drm] fb0: guddrmfb frame buffer device > > > It looks good, I think? However, neither GUD_REQ_SET_CONTROLLER_ENABLE > nor GUD_REQ_SET_DISPLAY_ENABLE is ever called, and there is no bulk > output if I write to /dev/fb0. > > Can you tell what's missing? > IIRC you need ioctl FBIOPUT_VSCREENINFO to enable the pipeline. You can use 'con2fbmap' to put a console on the fbdev or use 'fbi' to show an image. They will do the necessary ioctls. I use modetest for simple testing: https://github.com/notro/tinydrm/wiki/Development#modetest I have made tool that employs usbmon to show what happens just outside the wire (runs on the host): https://github.com/notro/gud/blob/master/tools/monitor.py I haven't got a proper USB analyser, so this was second best. I was primarily looking for performance numbers, but it has been helpful in debugging problems as well. It's not perfect, GUD_DISPLAY_FLAG_FULL_UPDATE is not handled for instance. Depending on how long it takes for the DMA mask dependency patch to show up in drm-misc-next, I will either publish a new version or apply the current and provide patches with the necessary fixes. It's tiresome to stay out-of-tree for a long time, DRM is constantly changing. And I've spent way to long on this project already. This is one of those things that would never have happened if I knew how long it would take :) Thanks for helping me improve it, especially the protocol which is difficult to change after the fact. Noralf. 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=-10.1 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, MENTIONS_GIT_HOSTING,NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS,USER_AGENT_SANE_1 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 2DE7EC433DB for ; Tue, 9 Mar 2021 18:07:56 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 97869652B3 for ; Tue, 9 Mar 2021 18:07:55 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 97869652B3 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=tronnes.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 16D5E6E10B; Tue, 9 Mar 2021 18:07:55 +0000 (UTC) Received: from smtp.domeneshop.no (smtp.domeneshop.no [IPv6:2a01:5b40:0:3005::1]) by gabe.freedesktop.org (Postfix) with ESMTPS id 491126E10B for ; Tue, 9 Mar 2021 18:07:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=tronnes.org ; s=ds202012; h=Content-Transfer-Encoding:Content-Type:In-Reply-To: MIME-Version:Date:Message-ID:From:References:Cc:To:Subject:Sender:Reply-To: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=GmBMPW+tTISD6uwv8VQMdpaP5z44nBOdyC9Ca3KH5BQ=; b=RLM6dqwmY3E2wxWOF1JKB1r2HD yTFjtCdAyt0hi+vU28fIRQQIhzvca+7RhPVqgjOpInEAUxxsHjlj+Gl3JRi3++5cf8b6VYjoMitdZ prcs8ZJZyIvJZUmc54n18vWlGgrLrWP2ubdh+btLh/5p1wK2bAIepXybVveeWsuiDXsoVdvIK30OT KTVCByFGlfCqD4ThEDYyUGwcYu6LNH4sYj+gDonInQgVfXqLv7f3CS5epuc67n+AlHZWVgEDOrcLU TrAlDYNzHCH74fHI1jqF08XJQWRdRrUguItLlM89Va080ZgHY1mHqE8jSAx/XwwT+rx88I9OPaooE GPpdhaUg==; Received: from [2a01:799:95f:4600:cca0:57ac:c55d:a485] (port=49211) by smtp.domeneshop.no with esmtpsa (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1lJglr-0005z9-Cf; Tue, 09 Mar 2021 19:07:51 +0100 Subject: Re: [PATCH v7 3/3] drm: Add GUD USB Display driver To: Peter Stuge References: <20210305163104.30756-1-noralf@tronnes.org> <20210305163104.30756-4-noralf@tronnes.org> <20210309140200.13094.qmail@stuge.se> From: =?UTF-8?Q?Noralf_Tr=c3=b8nnes?= Message-ID: <59bf10c7-91aa-ba09-7128-91e87272e29e@tronnes.org> Date: Tue, 9 Mar 2021 19:07:46 +0100 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Thunderbird/78.8.0 MIME-Version: 1.0 In-Reply-To: <20210309140200.13094.qmail@stuge.se> X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: hudson@trmm.net, markus@raatikainen.cc, Daniel Vetter , linux-usb@vger.kernel.org, dri-devel@lists.freedesktop.org, th020394@gmail.com, lkundrak@v3.sk, pontus.fuchs@gmail.com, sam@ravnborg.org Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" CgpEZW4gMDkuMDMuMjAyMSAxNS4wMiwgc2tyZXYgUGV0ZXIgU3R1Z2U6Cj4gSGVsbG8gTm9yYWxm LAo+IAo+IEkndmUgbWFkZSBzb21lIHByb2dyZXNzIHdpdGggbXkgdGVzdCBkZXZpY2UuIEknbSBp bXBsZW1lbnRpbmcgUjEKPiBmaXJzdCBhbmQgb25jZSB0aGF0IHdvcmtzIEknbGwgdGVzdCBSR0Ix MTEgYXMgd2VsbC4gQWxvbmcgdGhlIHdheQo+IEkndmUgZm91bmQgYSBjb3VwbGUgb2YgdGhpbmdz IGluIHRoZSBjb2RlOgo+IAo+IE5vcmFsZiBUcsO4bm5lcyB3cm90ZToKPj4gKysrIGIvZHJpdmVy cy9ncHUvZHJtL2d1ZC9ndWRfZHJ2LmMKPiAuLgo+PiArc3RhdGljIGludCBndWRfcHJvYmUoc3Ry dWN0IHVzYl9pbnRlcmZhY2UgKmludGYsIGNvbnN0IHN0cnVjdCB1c2JfZGV2aWNlX2lkICppZCkK PiAuLgo+PiArCQlpZiAoZm9ybWF0ID09IEdVRF9EUk1fRk9STUFUX1IxKQo+PiArCQkJY29udGlu dWU7IC8qIEludGVybmFsIG5vdCBmb3IgdXNlcnNwYWNlICovCj4gCj4gWW91IGFscmVhZHkgZm91 bmQgUkdCMTExIG1pc3NpbmcgaGVyZS4KPiAKPiAKPj4gK3N0YXRpYyBpbnQgZ3VkX3VzYl9jb250 cm9sX21zZyhzdHJ1Y3QgdXNiX2ludGVyZmFjZSAqaW50ZiwgYm9vbCBpbiwKPj4gKwkJCSAgICAg ICB1OCByZXF1ZXN0LCB1MTYgdmFsdWUsIHZvaWQgKmJ1Ziwgc2l6ZV90IGxlbikKPiAuLgo+PiAr c3RhdGljIGludCBndWRfdXNiX3RyYW5zZmVyKHN0cnVjdCBndWRfZGV2aWNlICpnZHJtLCBib29s IGluLCB1OCByZXF1ZXN0LCB1MTYgaW5kZXgsCj4gLi4KPj4gKwlyZXQgPSBndWRfdXNiX2NvbnRy b2xfbXNnKGludGYsIGluLCByZXF1ZXN0LCBpbmRleCwgYnVmLCBsZW4pOwo+IAo+IFRoZSB1MTYg aW5kZXggcGFyYW1ldGVyIHRvIGd1ZF91c2JfdHJhbnNmZXIoKSBhbmQgYXQgbGVhc3QgYWxzbyAK PiBndWRfdXNiX3tnZXQsc2V0LGdldF91OCxzZXRfdTh9KCkgaXMgZXZlbnR1YWxseSBwYXNzZWQg aW4gdTE2IHZhbHVlCj4gaW4gdGhlIGNhbGwgdG8gZ3VkX3VzYl9jb250cm9sX21zZygpLCB3aGlj aCBoYWQgbWUgY29uZnVzZWQgZm9yIGEgYml0Lgo+IAo+IFdoYXQgZG8geW91IHRoaW5rIGFib3V0 IHJlbmFtaW5nIGFsbCBvZiB0aG9zZSBwYXJhbWV0ZXJzIHRvIHdWYWx1ZSwKPiB0byBzaG93IHRo YXQgYW5kIHdoZXJlIHRoZXkgYXJlIHBhcnQgb2YgdGhlIGNvbnRyb2wgcmVxdWVzdD8gSSB0aGlu awo+IGl0IHdvdWxkIGhlbHAgbWFrZSB0aGUgcHJvdG9jb2wgbW9yZSBjbGVhci4KPiAKCk9ubHkg Y29ubmVjdG9yIHJlcXVlc3RzIHVzZSB0aGlzIHZhbHVlIGFuZCBpbiB0aGF0IGNhc2UgaXQncyB0 aGUKY29ubmVjdG9yIGluZGV4LiBJIG5lZWQgdG8gZ2V0IHRoaXMgZHJpdmVyIGFwcGxpZWQgbm93 LCBhbmQgY2FuJ3Qgc3BlbmQKbW9yZSB0aW1lIHBvbGlzaGluZyBpdCwgc28gSSdsbCBqdXN0IGtl ZXAgaXQgYXMtaXMuCgo+IAo+IEZpbmFsbHksIGFuIGFjdHVhbCBidWc6Cj4gCj4+ICsJcmV0ID0g Z3VkX2dldF9wcm9wZXJ0aWVzKGdkcm0pOwo+PiArCWlmIChyZXQpIHsKPj4gKwkJZGV2X2Vycihk ZXYsICJGYWlsZWQgdG8gZ2V0IHByb3BlcnRpZXMgKGVycm9yPSVkKVxuIiwgcmV0KTsKPj4gKwkJ cmV0dXJuIHJldDsKPj4gKwl9Cj4gCj4gSWYgZ3VkX2dldF9wcm9wZXJ0aWVzKCkgYW5kIGd1ZF9j b25uZWN0b3JfYWRkX3Byb3BlcnRpZXMoKSByZWNlaXZlCj4gYW5kIHByb2Nlc3MgKG9ubHkhKSBv bmUgb3IgbW9yZSB1bmtub3duIHByb3BlcnRpZXMgdGhlbiB0aGV5IHJldHVybgo+IHRoZSBudW1i ZXIgb2YgYnl0ZXMgcmVjZWl2ZWQgZnJvbSB0aGUgZGV2aWNlIHJhdGhlciB0aGFuIDAuCj4gCj4g SSBmaXhlZCB0aGlzIGJ5IHNldHRpbmcgcmV0ID0gMDsgYmVmb3JlIHRoZSBmb3IoKSBsb29wLCBi dXQgbWF5YmUgeW91Cj4gd2FudCB0byBkbyBpdCBhbm90aGVyIHdheS4KPiAKCkknbGwgZG8gdGhh dC4KCj4gCj4gSSBmb3VuZCB0aGlzIGJlY2F1c2UgSSBjYW4ndCBnZXQgbXkgZGV2aWNlIHRvIHNl bmQgMCBieXRlcyBJTiB3aGVuCj4gdGhlIGhvc3QgcmVxdWVzdHMgbW9yZSwgaWYgSSBwcm92aWRl IG5vIGRhdGEgdGhlIHJlcXVlc3QgU1RBTExzLiBUaGlzCj4gaXMgZm9yIHN1cmUgYSBidWcgaW4g bXkgZGV2aWNlIGFuZCBJJ2xsIGNvbWUgYmFjayB0byBpdCwgYnV0IGZvciBub3cKPiBJIGFkZGVk IGEgZHVtbXkgNjU1MzUgcHJvcGVydHkgYXMgYSB3b3JrYXJvdW5kLgo+IAo+IFdoYXQgZG8geW91 IHRoaW5rIGFib3V0IGZvcm1hbGl6aW5nIHRoaXMsIGFkZGluZyBhbiBhY3R1YWwgZHVtbXkgcHJv cGVydHk/Cj4gCgpJIHdhbnQgdG8gYXZvaWQgdGhhdC4gSSdkIHJhdGhlciBhZGQgYSBkZXNjcmlw dG9yIGZsYWcKR1VEX0RJU1BMQVlfRkxBR19DQU5UX1JFVFVSTl9aRVJPIG9yIHNvbWV0aGluZyBm b3Igc3VjaCBkZXZpY2VzLgpBbHNvIHRoaXMgcHJvcGVydHkgd2FybmluZyBpcyBqdXN0IGEgZGVi dWcgbWVzc2FnZSBzbyBub3QgYSB2ZXJ5IGJpZwpwcm9ibGVtLiBXb3JzZSBpcyBFRElEIGlmIHlv dSBkb24ndCB3YW50IHRvIHN1cHBvcnQgdGhhdCBzaW5jZSBpdCBwcmludHMKYW4gZXJyb3IgaW4g dGhhdCBjYXNlLgoKPiBPciBtYXliZSBhZGRpbmcgZmxhZ3MgdG8gdGhlIGRpc3BsYXkgZGVzY3Jp cHRvciBmb3IgIkkgaGF2ZSBwcm9wZXJ0aWVzIiwKPiAiSSBoYXZlIGNvbm5lY3RvciBwcm9wZXJ0 aWVzIiBhbmQgIkkgaGF2ZSBFRElEIiA/Cj4gCgpUaGVuIEkgbWlnaHQgYXMgd2VsbCBnbyBiYWNr IHRvIHRoZSBwcmV2aW91cyB2ZXJzaW9uIGFuZCBoYXZlIGNvdW50IGluCnRoZSBzdHJ1Y3RzIHdv bid0IEkgOykKCj4gCj4+ICsrKyBiL2RyaXZlcnMvZ3B1L2RybS9ndWQvZ3VkX3BpcGUuYwo+IC4u Cj4+ICtzdGF0aWMgaW50IGd1ZF9wcmVwX2ZsdXNoKHN0cnVjdCBndWRfZGV2aWNlICpnZHJtLCBz dHJ1Y3QgZHJtX2ZyYW1lYnVmZmVyICpmYiwKPiAuLgo+PiArCS8qCj4+ICsJICogSW1wb3J0ZWQg YnVmZmVycyBhcmUgYXNzdW1lZCB0byBiZSB3cml0ZS1jb21iaW5lZCBhbmQgdGh1cyB1bmNhY2hl ZAo+PiArCSAqIHdpdGggc2xvdyByZWFkcyAoYXQgbGVhc3Qgb24gQVJNKS4KPj4gKwkgKi8KPj4g KwlpZiAoZm9ybWF0ICE9IGZiLT5mb3JtYXQpIHsKPj4gKwkJaWYgKGZvcm1hdC0+Zm9ybWF0ID09 IEdVRF9EUk1fRk9STUFUX1IxKSB7Cj4+ICsJCQlsZW4gPSBndWRfeHJnYjg4ODhfdG9fcjEyNChi dWYsIGZvcm1hdCwgdmFkZHIsIGZiLCByZWN0KTsKPj4gKwkJCWlmICghbGVuKSB7Cj4+ICsJCQkJ cmV0ID0gLUVOT01FTTsKPj4gKwkJCQlnb3RvIGVuZF9jcHVfYWNjZXNzOwo+PiArCQkJfQo+PiAr CQl9IGVsc2UgaWYgKGZvcm1hdC0+Zm9ybWF0ID09IERSTV9GT1JNQVRfUkdCNTY1KSB7Cj4+ICsJ CQlkcm1fZmJfeHJnYjg4ODhfdG9fcmdiNTY1KGJ1ZiwgdmFkZHIsIGZiLCByZWN0LCBndWRfaXNf YmlnX2VuZGlhbigpKTsKPj4gKwkJfSBlbHNlIHsKPj4gKwkJCWxlbiA9IGd1ZF94cmdiODg4OF90 b19jb2xvcihidWYsIGZvcm1hdCwgdmFkZHIsIGZiLCByZWN0KTsKPj4gKwkJfQo+IAo+IERvZXMg dGhpcyBzZWN0aW9uIGFsc28gbmVlZCBhIFJHQjExMSBjYXNlPwo+IAoKZ3VkX3hyZ2I4ODg4X3Rv X2NvbG9yKCkgaGFuZGxlcyB0aGF0LCBhbHRob3VnaCBicm9rZW4gaW4gdGhpcyB2ZXJzaW9uCmZv ciBwYXJ0aWFsIHVwZGF0ZXMuIEhlcmUncyB0aGUgZml4OgpodHRwczovL2dpc3QuZ2l0aHViLmNv bS9ub3Ryby9hOTRkMzgxY2Y5OGI3ZTE1ZmNkZGJjOTBlNGFmMGEyMQoKPiAKPj4gK3ZvaWQgZ3Vk X3BpcGVfdXBkYXRlKHN0cnVjdCBkcm1fc2ltcGxlX2Rpc3BsYXlfcGlwZSAqcGlwZSwKPiAuLgo+ PiArCWlmIChmYiAmJiAoY3J0Yy0+c3RhdGUtPm1vZGVfY2hhbmdlZCB8fCBjcnRjLT5zdGF0ZS0+ Y29ubmVjdG9yc19jaGFuZ2VkKSkKPj4gKwkJZ3VkX3VzYl9zZXQoZ2RybSwgR1VEX1JFUV9TRVRf U1RBVEVfQ09NTUlULCAwLCBOVUxMLCAwKTsKPiAKPiBZb3UgbWVudGlvbmVkIHRoYXQgY29tbWl0 IG11c3Qgbm90IGZhaWw7IHdoYXQgaGFwcGVucy9zaG91bGQgaGFwcGVuCj4gaWYgYSByZXF1ZXN0 IGRvZXMgZmFpbCBpbiBwaXBlX3VwZGF0ZSgpPyBTb21lIHJlYXNvbnMgY291bGQgYmUgdGhhdAo+ IHRoZSBkZXZpY2Ugd2FzIHVucGx1Z2dlZCwgYSBiYWQgY2FibGUgaXMgZ2xpdGNoeSBvciBldmVu IHRoYXQgc29tZQo+IGRldmljZSBkb2Vzbid0IGV2ZW4gaW1wbGVtZW50IFNUQVRFX0NPTU1JVCBv ciBkb2VzIGl0IGluY29ycmVjdGx5IGFuZAo+IHdpbGwgcmVwb3J0IGJhY2sgZmFpbHVyZT8KPiAK ClRoZSBmYWlsdXJlIGlzIGp1c3QgaWdub3JlZCBzaW5jZSB0aGVyZSdzIG5vdGhpbmcgdG8gYmUg ZG9uZS4gVGhlIGVycm9yCmNvdW50ZXIgZm9yIHRoZSBkZWJ1ZmdzIGZpbGUgaXMgaW5jcmVhc2Vk LCBtYWtpbmcgaXQgc29tZXdoYXQgdmlzaWJsZS4KCkkndmUgY2hvc2VuIHRvIG9ubHkgcHJpbnQg cHJvYmUgZXJyb3JzLCBmbHVzaCBlcnJvcnMgYW5kIGRldmljZXMKcmV0dXJuaW5nIGluY29ycmVj dCByZXBseSBsZW5ndGhzLiBJIGhhdGUgZHJpdmVycyB0aGF0IGZpbGwgdGhlIGxvZ3MKd2l0aCBl cnJvcnMsIGJ1dCBJIG1pZ2h0IGhhdmUgZ29uZSB0byBmYXIgb24gdGhlIHNpbGVudCBzaWRlLCBJ IGRvbid0Cmtub3cuIEJ1dCBvbmUgbmljZSB0aGluZyBhYm91dCBEUk0gaXMgdGhhdCBkZWJ1ZyBp cyBhbHdheXMgYnVpbHRpbiBhbmQKY2FuIGJlIGVuYWJsZWQuCgo+IAo+PiArKysgYi9pbmNsdWRl L2RybS9ndWQuaAo+IC4uCj4+ICsgICNkZWZpbmUgR1VEX1NUQVRVU19SRVFVRVNUX05PVF9TVVBQ T1JURUQJMHgwMgo+IAo+IE1heWJlIHRoaXMgY2FuIGJlIHJlbW92ZWQ/IFNFVF9WRVJTSU9OIGhh cyBiZWVuIHJlbW92ZWQgc28gaXQncyBubwo+IGxvbmdlciB1c2VkIGFueXdoZXJlLCBhbmQgaW4g YW55IGNhc2UgZGV2aWNlcyB0eXBpY2FsbHkgc2lnbmFsIHRoYXQKPiByZXF1ZXN0cyBhcmUgdW5z dXBwb3J0ZWQgdXNpbmcgYSBwcm90b2NvbCBTVEFMTCwgd2hpY2ggY29tZXMgYmFjawo+IGFzIC1F UElQRSBmcm9tIHRoZSBVU0Igc3RhY2suCj4gCgpUaGUgZHJpdmVyIGlzc3VlcyBhIEdVRF9SRVFf R0VUX1NUQVRVUyBvbiAtRVBJUEUgdG8gZmluZCBvdXQgd2hhdCB0aGUKZXhhY3QgcHJvYmxlbSBp cy4gR1VEX1NUQVRVU19SRVFVRVNUX05PVF9TVVBQT1JURUQgaXMgcmV0dXJuZWQgYnkgdGhlCmRl dmljZSBvbiBhbiB1bnN1cHBvcnRlZC91bnJlY29nbmlzZWQgcmVxdWVzdC4KCj4gCj4gCj4gRmlu YWxseSwgaGVyZSdzIHRoZSBkcm0gZGVidWcgb3V0cHV0IHdoZW4gSSBjb25uZWN0IG15IGRldmlj ZToKPiAKPiBNYXIgMDkgMTQ6NTc6MTkgdm0ga2VybmVsOiB1c2IgMS0xOiBuZXcgZnVsbC1zcGVl ZCBVU0IgZGV2aWNlIG51bWJlciAyNCB1c2luZyB1aGNpX2hjZAo+IE1hciAwOSAxNDo1NzoxOSB2 bSBrZXJuZWw6IGd1ZCAxLTE6MjcuMDogW2RybTpndWRfcHJvYmVdIHZlcnNpb249MSBmbGFncz0w eDIgY29tcHJlc3Npb249MHgwIG1heF9idWZmZXJfc2l6ZT0wCj4gTWFyIDA5IDE0OjU3OjE5IHZt IGtlcm5lbDogZ3VkIDEtMToyNy4wOiBbZHJtOmd1ZF91c2JfdHJhbnNmZXJdIGdldDogcmVxdWVz dD0weDQwIGluZGV4PTAgbGVuPTMyCj4gTWFyIDA5IDE0OjU3OjE5IHZtIGtlcm5lbDogZ3VkIDEt MToyNy4wOiBbZHJtOmd1ZF91c2JfdHJhbnNmZXJdIGdldDogcmVxdWVzdD0weDQxIGluZGV4PTAg bGVuPTMyMAo+IE1hciAwOSAxNDo1NzoxOSB2bSBrZXJuZWw6IGd1ZCAxLTE6MjcuMDogW2RybTpn dWRfcHJvYmVdIElnbm9yaW5nIHVua25vd24gcHJvcGVydHk6IDY1NTM1Cj4gTWFyIDA5IDE0OjU3 OjE5IHZtIGtlcm5lbDogZ3VkIDEtMToyNy4wOiBbZHJtOmd1ZF91c2JfdHJhbnNmZXJdIGdldDog cmVxdWVzdD0weDUwIGluZGV4PTAgbGVuPTI1Ngo+IE1hciAwOSAxNDo1NzoxOSB2bSBrZXJuZWw6 IGd1ZCAxLTE6MjcuMDogW2RybTpndWRfZ2V0X2Nvbm5lY3RvcnNdIENvbm5lY3RvcjogaW5kZXg9 MCB0eXBlPTAgZmxhZ3M9MHgwCj4gTWFyIDA5IDE0OjU3OjE5IHZtIGtlcm5lbDogZ3VkIDEtMToy Ny4wOiBbZHJtOmd1ZF91c2JfdHJhbnNmZXJdIGdldDogcmVxdWVzdD0weDUxIGluZGV4PTAgbGVu PTMyMAo+IE1hciAwOSAxNDo1NzoxOSB2bSBrZXJuZWw6IGd1ZCAxLTE6MjcuMDogW2RybTpndWRf Z2V0X2Nvbm5lY3RvcnNdIHByb3BlcnR5OiA2NTUzNSA9IDAoMHgwKQo+IE1hciAwOSAxNDo1Nzox OSB2bSBrZXJuZWw6IGd1ZCAxLTE6MjcuMDogW2RybTpndWRfZ2V0X2Nvbm5lY3RvcnNdIElnbm9y aW5nIHVua25vd24gcHJvcGVydHk6IDY1NTM1Cj4gTWFyIDA5IDE0OjU3OjE5IHZtIGtlcm5lbDog W2RybTpkcm1fbWlub3JfcmVnaXN0ZXJdIAo+IE1hciAwOSAxNDo1NzoxOSB2bSBrZXJuZWw6IFtk cm06ZHJtX21pbm9yX3JlZ2lzdGVyXSAKPiBNYXIgMDkgMTQ6NTc6MTkgdm0ga2VybmVsOiBbZHJt OmRybV9taW5vcl9yZWdpc3Rlcl0gbmV3IG1pbm9yIHJlZ2lzdGVyZWQgMAo+IE1hciAwOSAxNDo1 NzoxOSB2bSBrZXJuZWw6IFtkcm06ZHJtX3N5c2ZzX2Nvbm5lY3Rvcl9hZGRdIGFkZGluZyAiVVNC LTEiIHRvIHN5c2ZzCj4gTWFyIDA5IDE0OjU3OjE5IHZtIGtlcm5lbDogW2RybTpkcm1fc3lzZnNf aG90cGx1Z19ldmVudF0gZ2VuZXJhdGluZyBob3RwbHVnIGV2ZW50Cj4gTWFyIDA5IDE0OjU3OjE5 IHZtIGtlcm5lbDogW2RybV0gSW5pdGlhbGl6ZWQgZ3VkIDEuMC4wIDIwMjAwNDIyIGZvciAxLTE6 MjcuMCBvbiBtaW5vciAwCj4gTWFyIDA5IDE0OjU3OjE5IHZtIGtlcm5lbDogW2RybTpkcm1fY2xp ZW50X21vZGVzZXRfcHJvYmVdIAo+IE1hciAwOSAxNDo1NzoxOSB2bSBrZXJuZWw6IFtkcm06ZHJt X21vZGVfb2JqZWN0X2dldF0gT0JKIElEOiAzNSAoMikKPiBNYXIgMDkgMTQ6NTc6MTkgdm0ga2Vy bmVsOiBbZHJtOmRybV9oZWxwZXJfcHJvYmVfc2luZ2xlX2Nvbm5lY3Rvcl9tb2Rlc10gW0NPTk5F Q1RPUjozNTpVU0ItMV0KPiBNYXIgMDkgMTQ6NTc6MTkgdm0ga2VybmVsOiBndWQgMS0xOjI3LjA6 IFtkcm06Z3VkX3VzYl90cmFuc2Zlcl0gc2V0OiByZXF1ZXN0PTB4NTMgaW5kZXg9MCBsZW49MAo+ IE1hciAwOSAxNDo1NzoxOSB2bSBrZXJuZWw6IGd1ZCAxLTE6MjcuMDogW2RybTpndWRfdXNiX3Ry YW5zZmVyXSBnZXQ6IHJlcXVlc3Q9MHg1NCBpbmRleD0wIGxlbj0xCj4gTWFyIDA5IDE0OjU3OjE5 IHZtIGtlcm5lbDogW2RybTpkcm1faGVscGVyX3Byb2JlX3NpbmdsZV9jb25uZWN0b3JfbW9kZXNd IFtDT05ORUNUT1I6MzU6VVNCLTFdIHN0YXR1cyB1cGRhdGVkIGZyb20gdW5rbm93biB0byBjb25u ZWN0ZWQKPiBNYXIgMDkgMTQ6NTc6MTkgdm0ga2VybmVsOiBndWQgMS0xOjI3LjA6IFtkcm06Z3Vk X3VzYl90cmFuc2Zlcl0gZ2V0OiByZXF1ZXN0PTB4NTYgaW5kZXg9MCBsZW49MjA0OAo+IE1hciAw OSAxNDo1NzoxOSB2bSBrZXJuZWw6IFtkcm06ZHJtX3N5c2ZzX2hvdHBsdWdfZXZlbnRdIGdlbmVy YXRpbmcgaG90cGx1ZyBldmVudAo+IE1hciAwOSAxNDo1NzoxOSB2bSBrZXJuZWw6IGd1ZCAxLTE6 MjcuMDogVVNCLTE6IEludmFsaWQgRURJRCBzaXplIChyZXQ9MSkKPiBNYXIgMDkgMTQ6NTc6MTkg dm0ga2VybmVsOiBndWQgMS0xOjI3LjA6IFtkcm06Z3VkX3VzYl90cmFuc2Zlcl0gZ2V0OiByZXF1 ZXN0PTB4NTUgaW5kZXg9MCBsZW49MzA3Mgo+IE1hciAwOSAxNDo1NzoxOSB2bSBrZXJuZWw6IFtk cm06ZHJtX2hlbHBlcl9wcm9iZV9zaW5nbGVfY29ubmVjdG9yX21vZGVzXSBbQ09OTkVDVE9SOjM1 OlVTQi0xXSBwcm9iZWQgbW9kZXMgOgo+IE1hciAwOSAxNDo1NzoxOSB2bSBrZXJuZWw6IFtkcm06 ZHJtX21vZGVfZGVidWdfcHJpbnRtb2RlbGluZV0gTW9kZWxpbmUgIjQwMHgyNDAiOiAxMDQgMTAw MDAgNDAwIDQwMCA0MDAgNDAwIDI0MCAyNDAgMjQwIDI0MCAweDQwIDB4MAo+IE1hciAwOSAxNDo1 NzoxOSB2bSBrZXJuZWw6IFtkcm06ZHJtX2NsaWVudF9tb2Rlc2V0X3Byb2JlXSBjb25uZWN0b3Ig MzUgZW5hYmxlZD8geWVzCj4gTWFyIDA5IDE0OjU3OjE5IHZtIGtlcm5lbDogW2RybTpkcm1fY2xp ZW50X21vZGVzZXRfcHJvYmVdIE5vdCB1c2luZyBmaXJtd2FyZSBjb25maWd1cmF0aW9uCj4gTWFy IDA5IDE0OjU3OjE5IHZtIGtlcm5lbDogW2RybTpkcm1fY2xpZW50X21vZGVzZXRfcHJvYmVdIGxv b2tpbmcgZm9yIGNtZGxpbmUgbW9kZSBvbiBjb25uZWN0b3IgMzUKPiBNYXIgMDkgMTQ6NTc6MTkg dm0ga2VybmVsOiBbZHJtOmRybV9jbGllbnRfbW9kZXNldF9wcm9iZV0gbG9va2luZyBmb3IgcHJl ZmVycmVkIG1vZGUgb24gY29ubmVjdG9yIDM1IDAKPiBNYXIgMDkgMTQ6NTc6MTkgdm0ga2VybmVs OiBbZHJtOmRybV9jbGllbnRfbW9kZXNldF9wcm9iZV0gZm91bmQgbW9kZSA0MDB4MjQwCj4gTWFy IDA5IDE0OjU3OjE5IHZtIGtlcm5lbDogW2RybTpkcm1fY2xpZW50X21vZGVzZXRfcHJvYmVdIHBp Y2tpbmcgQ1JUQ3MgZm9yIDQwMHgyNDAgY29uZmlnCj4gTWFyIDA5IDE0OjU3OjE5IHZtIGtlcm5l bDogW2RybTpkcm1fY2xpZW50X21vZGVzZXRfcHJvYmVdIGRlc2lyZWQgbW9kZSA0MDB4MjQwIHNl dCBvbiBjcnRjIDMzICgwLDApCj4gTWFyIDA5IDE0OjU3OjE5IHZtIGtlcm5lbDogW2RybTpkcm1f bW9kZV9vYmplY3RfZ2V0XSBPQkogSUQ6IDM1ICgyKQo+IE1hciAwOSAxNDo1NzoxOSB2bSBrZXJu ZWw6IFtkcm06ZHJtX21vZGVfb2JqZWN0X3B1dC5wYXJ0LjBdIE9CSiBJRDogMzUgKDMpCj4gTWFy IDA5IDE0OjU3OjE5IHZtIGtlcm5lbDogZ3VkIDEtMToyNy4wOiBbZHJtOl9fZHJtX2ZiX2hlbHBl cl9pbml0aWFsX2NvbmZpZ19hbmRfdW5sb2NrXSB0ZXN0IENSVEMgMCBwcmltYXJ5IHBsYW5lCj4g TWFyIDA5IDE0OjU3OjE5IHZtIGtlcm5lbDogZ3VkIDEtMToyNy4wOiBbZHJtOmRybV9mYl9oZWxw ZXJfZ2VuZXJpY19wcm9iZV0gc3VyZmFjZSB3aWR0aCg0MDApLCBoZWlnaHQoMjQwKSBhbmQgYnBw KDMyKQo+IE1hciAwOSAxNDo1NzoxOSB2bSBrZXJuZWw6IFtkcm06ZHJtX21vZGVfYWRkZmIyXSBb RkI6MzZdCj4gTWFyIDA5IDE0OjU3OjE5IHZtIGtlcm5lbDogW2RybTpkcm1fbW9kZV9vYmplY3Rf cHV0LnBhcnQuMF0gT0JKIElEOiAzNiAoMikKPiBNYXIgMDkgMTQ6NTc6MTkgdm0ga2VybmVsOiBn dWQgMS0xOjI3LjA6IFtkcm1dIGZiMDogZ3VkZHJtZmIgZnJhbWUgYnVmZmVyIGRldmljZQo+IAo+ IAo+IEl0IGxvb2tzIGdvb2QsIEkgdGhpbms/IEhvd2V2ZXIsIG5laXRoZXIgR1VEX1JFUV9TRVRf Q09OVFJPTExFUl9FTkFCTEUKPiBub3IgR1VEX1JFUV9TRVRfRElTUExBWV9FTkFCTEUgaXMgZXZl ciBjYWxsZWQsIGFuZCB0aGVyZSBpcyBubyBidWxrCj4gb3V0cHV0IGlmIEkgd3JpdGUgdG8gL2Rl di9mYjAuCj4gCj4gQ2FuIHlvdSB0ZWxsIHdoYXQncyBtaXNzaW5nPwo+IAoKSUlSQyB5b3UgbmVl ZCBpb2N0bCBGQklPUFVUX1ZTQ1JFRU5JTkZPIHRvIGVuYWJsZSB0aGUgcGlwZWxpbmUuIFlvdSBj YW4KdXNlICdjb24yZmJtYXAnIHRvIHB1dCBhIGNvbnNvbGUgb24gdGhlIGZiZGV2IG9yIHVzZSAn ZmJpJyB0byBzaG93IGFuCmltYWdlLiBUaGV5IHdpbGwgZG8gdGhlIG5lY2Vzc2FyeSBpb2N0bHMu CgpJIHVzZSBtb2RldGVzdCBmb3Igc2ltcGxlIHRlc3Rpbmc6Cmh0dHBzOi8vZ2l0aHViLmNvbS9u b3Ryby90aW55ZHJtL3dpa2kvRGV2ZWxvcG1lbnQjbW9kZXRlc3QKCkkgaGF2ZSBtYWRlIHRvb2wg dGhhdCBlbXBsb3lzIHVzYm1vbiB0byBzaG93IHdoYXQgaGFwcGVucyBqdXN0IG91dHNpZGUKdGhl IHdpcmUgKHJ1bnMgb24gdGhlIGhvc3QpOgpodHRwczovL2dpdGh1Yi5jb20vbm90cm8vZ3VkL2Js b2IvbWFzdGVyL3Rvb2xzL21vbml0b3IucHkKCkkgaGF2ZW4ndCBnb3QgYSBwcm9wZXIgVVNCIGFu YWx5c2VyLCBzbyB0aGlzIHdhcyBzZWNvbmQgYmVzdC4gSSB3YXMKcHJpbWFyaWx5IGxvb2tpbmcg Zm9yIHBlcmZvcm1hbmNlIG51bWJlcnMsIGJ1dCBpdCBoYXMgYmVlbiBoZWxwZnVsIGluCmRlYnVn Z2luZyBwcm9ibGVtcyBhcyB3ZWxsLiBJdCdzIG5vdCBwZXJmZWN0LApHVURfRElTUExBWV9GTEFH X0ZVTExfVVBEQVRFIGlzIG5vdCBoYW5kbGVkIGZvciBpbnN0YW5jZS4KCkRlcGVuZGluZyBvbiBo b3cgbG9uZyBpdCB0YWtlcyBmb3IgdGhlIERNQSBtYXNrIGRlcGVuZGVuY3kgcGF0Y2ggdG8gc2hv dwp1cCBpbiBkcm0tbWlzYy1uZXh0LCBJIHdpbGwgZWl0aGVyIHB1Ymxpc2ggYSBuZXcgdmVyc2lv biBvciBhcHBseSB0aGUKY3VycmVudCBhbmQgcHJvdmlkZSBwYXRjaGVzIHdpdGggdGhlIG5lY2Vz c2FyeSBmaXhlcy4gSXQncyB0aXJlc29tZSB0bwpzdGF5IG91dC1vZi10cmVlIGZvciBhIGxvbmcg dGltZSwgRFJNIGlzIGNvbnN0YW50bHkgY2hhbmdpbmcuIEFuZCBJJ3ZlCnNwZW50IHdheSB0byBs b25nIG9uIHRoaXMgcHJvamVjdCBhbHJlYWR5LiBUaGlzIGlzIG9uZSBvZiB0aG9zZSB0aGluZ3MK dGhhdCB3b3VsZCBuZXZlciBoYXZlIGhhcHBlbmVkIGlmIEkga25ldyBob3cgbG9uZyBpdCB3b3Vs ZCB0YWtlIDopCgpUaGFua3MgZm9yIGhlbHBpbmcgbWUgaW1wcm92ZSBpdCwgZXNwZWNpYWxseSB0 aGUgcHJvdG9jb2wgd2hpY2ggaXMKZGlmZmljdWx0IHRvIGNoYW5nZSBhZnRlciB0aGUgZmFjdC4K Ck5vcmFsZi4KX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18K ZHJpLWRldmVsIG1haWxpbmcgbGlzdApkcmktZGV2ZWxAbGlzdHMuZnJlZWRlc2t0b3Aub3JnCmh0 dHBzOi8vbGlzdHMuZnJlZWRlc2t0b3Aub3JnL21haWxtYW4vbGlzdGluZm8vZHJpLWRldmVsCg==