From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from galahad.ideasonboard.com ([185.26.127.97]:34527 "EHLO galahad.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752880AbcE0V2D (ORCPT ); Fri, 27 May 2016 17:28:03 -0400 From: Laurent Pinchart To: Sergei Shtylyov Cc: airlied@linux.ie, dri-devel@lists.freedesktop.org, linux-renesas-soc@vger.kernel.org Subject: Re: [PATCH 2/4] rcar-du: add TCON encoder driver Date: Sat, 28 May 2016 00:28:02 +0300 Message-ID: <2235354.1XRvauYedm@avalon> In-Reply-To: <1606151.cnY0qcbrgr@wasted.cogentembedded.com> References: <1787748.qAADjKK4gv@wasted.cogentembedded.com> <1606151.cnY0qcbrgr@wasted.cogentembedded.com> MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" Sender: linux-renesas-soc-owner@vger.kernel.org List-ID: Hi Sergei, Thank you for the patch. On Friday 29 Apr 2016 00:03:29 Sergei Shtylyov wrote: > Renesas R-Car SoCs include the timing controller (TCON) that can directly > drive LCDs. It receives the H/VSYNC, etc. from the Display Unit (DU) and > converts them to the set of signals that a LCD panel can understand (the > RBG signals are effectively passed thru). TCON has a set of registers > that we need to program based on the video mode timings, so we're adding > a DU encoder driver doing that... > > Based on a large patch by Andrey Gusakov. > > Signed-off-by: Andrey Gusakov > Signed-off-by: Sergei Shtylyov > > --- > drivers/gpu/drm/rcar-du/Kconfig | 6 > drivers/gpu/drm/rcar-du/Makefile | 1 > drivers/gpu/drm/rcar-du/rcar_du_drv.h | 4 > drivers/gpu/drm/rcar-du/rcar_du_encoder.c | 9 + > drivers/gpu/drm/rcar-du/rcar_du_encoder.h | 3 > drivers/gpu/drm/rcar-du/rcar_du_kms.c | 4 > drivers/gpu/drm/rcar-du/rcar_du_tconenc.c | 184 ++++++++++++++++++++++++++ > drivers/gpu/drm/rcar-du/rcar_du_tconenc.h | 37 ++++++ > drivers/gpu/drm/rcar-du/rcar_tcon_regs.h | 70 +++++++++++ > 9 files changed, 318 insertions(+) > > Index: linux/drivers/gpu/drm/rcar-du/Kconfig > =================================================================== > --- linux.orig/drivers/gpu/drm/rcar-du/Kconfig > +++ linux/drivers/gpu/drm/rcar-du/Kconfig > @@ -24,6 +24,12 @@ config DRM_RCAR_LVDS > help > Enable support for the R-Car Display Unit embedded LVDS encoders. > > +config DRM_RCAR_TCON > + bool "R-Car DU TCON Encoder Support" > + depends on DRM_RCAR_DU > + help > + Enable support for the R-Car Display Unit embedded TCON encoders. > + > config DRM_RCAR_VSP > bool "R-Car DU VSP Compositor Support" > depends on DRM_RCAR_DU > Index: linux/drivers/gpu/drm/rcar-du/Makefile > =================================================================== > --- linux.orig/drivers/gpu/drm/rcar-du/Makefile > +++ linux/drivers/gpu/drm/rcar-du/Makefile > @@ -10,6 +10,7 @@ rcar-du-drm-y := rcar_du_crtc.o \ > rcar-du-drm-$(CONFIG_DRM_RCAR_HDMI) += rcar_du_hdmicon.o \ > rcar_du_hdmienc.o > rcar-du-drm-$(CONFIG_DRM_RCAR_LVDS) += rcar_du_lvdsenc.o > +rcar-du-drm-$(CONFIG_DRM_RCAR_TCON) += rcar_du_tconenc.o > > rcar-du-drm-$(CONFIG_DRM_RCAR_VSP) += rcar_du_vsp.o > > Index: linux/drivers/gpu/drm/rcar-du/rcar_du_drv.h > =================================================================== > --- linux.orig/drivers/gpu/drm/rcar-du/rcar_du_drv.h > +++ linux/drivers/gpu/drm/rcar-du/rcar_du_drv.h > @@ -59,6 +59,7 @@ struct rcar_du_output_routing { > * @num_crtcs: total number of CRTCs > * @routes: array of CRTC to output routes, indexed by output > (RCAR_DU_OUTPUT_*) * @num_lvds: number of internal LVDS encoders > + * @num_tcon: number of internal TCON encoders > */ > struct rcar_du_device_info { > unsigned int gen; > @@ -67,11 +68,13 @@ struct rcar_du_device_info { > unsigned int num_crtcs; > struct rcar_du_output_routing routes[RCAR_DU_OUTPUT_MAX]; > unsigned int num_lvds; > + unsigned int num_tcon; > }; > > #define RCAR_DU_MAX_CRTCS 4 > #define RCAR_DU_MAX_GROUPS DIV_ROUND_UP(RCAR_DU_MAX_CRTCS, 2) > #define RCAR_DU_MAX_LVDS 2 > +#define RCAR_DU_MAX_TCON 1 > #define RCAR_DU_MAX_VSPS 4 > > struct rcar_du_device { > @@ -99,6 +102,7 @@ struct rcar_du_device { > unsigned int vspd1_sink; > > struct rcar_du_lvdsenc *lvds[RCAR_DU_MAX_LVDS]; > + struct rcar_du_tconenc *tcon[RCAR_DU_MAX_TCON]; > > struct { > wait_queue_head_t wait; > Index: linux/drivers/gpu/drm/rcar-du/rcar_du_encoder.c > =================================================================== > --- linux.orig/drivers/gpu/drm/rcar-du/rcar_du_encoder.c > +++ linux/drivers/gpu/drm/rcar-du/rcar_du_encoder.c > @@ -24,6 +24,7 @@ > #include "rcar_du_kms.h" > #include "rcar_du_lvdscon.h" > #include "rcar_du_lvdsenc.h" > +#include "rcar_du_tconenc.h" > #include "rcar_du_vgacon.h" > > /* ------------------------------------------------------------------------ > @@ -48,6 +49,8 @@ static void rcar_du_encoder_disable(stru > > if (renc->lvds) > rcar_du_lvdsenc_enable(renc->lvds, encoder->crtc, false); > + if (renc->tcon) > + rcar_du_tconenc_enable(renc->tcon, encoder->crtc, false); > } > > static void rcar_du_encoder_enable(struct drm_encoder *encoder) > @@ -56,6 +59,8 @@ static void rcar_du_encoder_enable(struc > > if (renc->lvds) > rcar_du_lvdsenc_enable(renc->lvds, encoder->crtc, true); > + if (renc->tcon) > + rcar_du_tconenc_enable(renc->tcon, encoder->crtc, true); > } > > static int rcar_du_encoder_atomic_check(struct drm_encoder *encoder, > @@ -142,6 +147,10 @@ int rcar_du_encoder_init(struct rcar_du_ > renc->lvds = rcdu->lvds[1]; > break; > > + case RCAR_DU_OUTPUT_TCON: > + renc->tcon = rcdu->tcon[0]; > + break; > + > default: > break; > } > Index: linux/drivers/gpu/drm/rcar-du/rcar_du_encoder.h > =================================================================== > --- linux.orig/drivers/gpu/drm/rcar-du/rcar_du_encoder.h > +++ linux/drivers/gpu/drm/rcar-du/rcar_du_encoder.h > @@ -20,6 +20,7 @@ > struct rcar_du_device; > struct rcar_du_hdmienc; > struct rcar_du_lvdsenc; > +struct rcar_du_tconenc; > > enum rcar_du_encoder_type { > RCAR_DU_ENCODER_UNUSED = 0, > @@ -27,6 +28,7 @@ enum rcar_du_encoder_type { > RCAR_DU_ENCODER_VGA, > RCAR_DU_ENCODER_LVDS, > RCAR_DU_ENCODER_HDMI, > + RCAR_DU_ENCODER_TCON, > }; > > struct rcar_du_encoder { > @@ -34,6 +36,7 @@ struct rcar_du_encoder { > enum rcar_du_output output; > struct rcar_du_hdmienc *hdmi; > struct rcar_du_lvdsenc *lvds; > + struct rcar_du_tconenc *tcon; > }; > > #define to_rcar_encoder(e) \ > Index: linux/drivers/gpu/drm/rcar-du/rcar_du_kms.c > =================================================================== > --- linux.orig/drivers/gpu/drm/rcar-du/rcar_du_kms.c > +++ linux/drivers/gpu/drm/rcar-du/rcar_du_kms.c > @@ -27,6 +27,7 @@ > #include "rcar_du_encoder.h" > #include "rcar_du_kms.h" > #include "rcar_du_lvdsenc.h" > +#include "rcar_du_tconenc.h" > #include "rcar_du_regs.h" > #include "rcar_du_vsp.h" > > @@ -619,6 +620,9 @@ int rcar_du_modeset_init(struct rcar_du_ > ret = rcar_du_lvdsenc_init(rcdu); > if (ret < 0) > return ret; > + ret = rcar_du_tconenc_init(rcdu); > + if (ret < 0) > + return ret; > > ret = rcar_du_encoders_init(rcdu); > if (ret < 0) > Index: linux/drivers/gpu/drm/rcar-du/rcar_du_tconenc.c > =================================================================== > --- /dev/null > +++ linux/drivers/gpu/drm/rcar-du/rcar_du_tconenc.c > @@ -0,0 +1,184 @@ > +/* > + * rcar_du_tconenc.c -- R-Car Display Unit TCON Encoder > + * > + * Copyright (C) 2015-2016 Cogent Embedded, Inc. > > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "rcar_du_drv.h" > +#include "rcar_du_encoder.h" > +#include "rcar_du_tconenc.h" > +#include "rcar_tcon_regs.h" > + > +struct rcar_du_tconenc { > + struct rcar_du_device *dev; > + > + unsigned int index; > + void __iomem *mmio; > + struct clk *clock; > + bool enabled; > +}; > + > +static void rcar_tcon_write(struct rcar_du_tconenc *tcon, u32 reg, u32 > data) > +{ > + iowrite32(data, tcon->mmio + reg); > +} > + > +static int rcar_du_tconenc_start(struct rcar_du_tconenc *tcon, > + struct rcar_du_crtc *rcrtc) > +{ > + const struct drm_display_mode *mode = &rcrtc->crtc.mode; > + int ret; > + > + if (tcon->enabled) Now that the DU driver implements the atomic API the DRM/KMS core is supposed to only enable/disable CRTCs and encoders when needed. Can this still happen ? Same comment for the stop function. > + return 0; > + > + ret = clk_prepare_enable(tcon->clock); > + if (ret < 0) > + return ret; > + > + /* Update */ > + rcar_tcon_write(tcon, OUT_V_LATCH, OUTCNT_VEN); > + rcar_tcon_write(tcon, TCON_V_LATCH, TCON_VEN); Aren't you supposed to set those bits after modifying the registers only, not before ? > + /* Signals: > + * R-Car Display > + * QCLK SSC (Source Driver Clock Input) > + * QSTH SSP (Source Scanning Signal Left/Right) > + * QSTB SOE (Source Driver Output Enable) > + * QCPV GOE (Gate Driver Output Enable) > + * QPOLA POL (Polarity Control Signal) > + * QPOLB GSC (Gate Driver Scanning Clock) > + * QSTVA GSP (Gate Scanning Start Signal Up/Down) > + * QSTVB nope > + */ > + /* Setup timings */ > + rcar_tcon_write(tcon, TCON_TIM, TCON_TIMING(50, 0)); > + /* Horizontal timings */ > + rcar_tcon_write(tcon, TCON_TIM_STH1, TCON_TIMING(mode->htotal - > + mode->hsync_start - 1, > + 1)); > + rcar_tcon_write(tcon, TCON_TIM_STH2, TCON_SEL_STH_SP_HS); > + rcar_tcon_write(tcon, TCON_TIM_STB1, TCON_TIMING(mode->htotal - > + mode->hsync_start + > + mode->hdisplay + 6, > + 3)); > + rcar_tcon_write(tcon, TCON_TIM_STB2, TCON_SEL_STB_LP_HE); > + rcar_tcon_write(tcon, TCON_TIM_POLB1, > + TCON_TIMING(mode->htotal - mode->hsync_start + > + mode->hdisplay - 8, mode->htotal / 2)); > + rcar_tcon_write(tcon, TCON_TIM_POLB2, > + TCON_SEL_POLB | TCON_INV | TCON_MD_NORM); > + rcar_tcon_write(tcon, TCON_TIM_CPV1, > + TCON_TIMING(mode->htotal - mode->hsync_start + > + mode->hdisplay - 33, 50)); > + rcar_tcon_write(tcon, TCON_TIM_CPV2, TCON_SEL_CPV_GCK); > + rcar_tcon_write(tcon, TCON_TIM_POLA1, > + TCON_TIMING(mode->htotal - mode->hsync_start + > + mode->hdisplay + 1, 39)); > + rcar_tcon_write(tcon, TCON_TIM_POLA2, > + TCON_SEL_POLA | TCON_INV | TCON_MD_1X1); > + > + /* Vertical timings */ > + rcar_tcon_write(tcon, TCON_TIM_STVA1, > + TCON_TIMING(mode->vtotal - mode->vsync_start, 1)); > + rcar_tcon_write(tcon, TCON_TIM_STVA2, TCON_SEL_STVA_VS); > + rcar_tcon_write(tcon, TCON_TIM_STVB1, TCON_TIMING(0, 0)); > + rcar_tcon_write(tcon, TCON_TIM_STVB2, TCON_SEL_STVB_VE); > + > + /* Data clocked out on the falling edge of QCLK, latched in LCD on > + * the rising edge > + */ > + rcar_tcon_write(tcon, OUT_CLK_PHASE, OUTCNT_LCD_EDGE); I can't verify all those settings as I have no idea how TCON operates. However, it looks like we have lots of magic numbers, and I have a feeling those actually depend on the panel model. Am I wrong ? > + /* Update */ > + rcar_tcon_write(tcon, OUT_V_LATCH, OUTCNT_VEN); > + rcar_tcon_write(tcon, TCON_V_LATCH, TCON_VEN); > + > + tcon->enabled = true; > + > + return 0; > +} > + > +static void rcar_du_tconenc_stop(struct rcar_du_tconenc *tcon) > +{ > + if (!tcon->enabled) > + return; > + > + clk_disable_unprepare(tcon->clock); > + > + tcon->enabled = false; > +} > + > +int rcar_du_tconenc_enable(struct rcar_du_tconenc *tcon, struct drm_crtc > *crtc, > + bool enable) > +{ > + if (!enable) { > + rcar_du_tconenc_stop(tcon); > + return 0; > + } else if (crtc) { > + struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc); > + > + return rcar_du_tconenc_start(tcon, rcrtc); > + } else > + return -EINVAL; Missing { } around the last branch. Is this needed though, can enable be true and crtc NULL ? If so, under which circumstances ? > +} > + > +static int rcar_du_tconenc_get_resources(struct rcar_du_tconenc *tcon, > + struct platform_device *pdev) > +{ > + struct resource *mem; > + char name[7]; > + > + sprintf(name, "tcon.%u", tcon->index); > + > + mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); > + tcon->mmio = devm_ioremap_resource(&pdev->dev, mem); > + if (IS_ERR(tcon->mmio)) > + return PTR_ERR(tcon->mmio); > + > + tcon->clock = devm_clk_get(&pdev->dev, name); > + if (IS_ERR(tcon->clock)) { > + dev_err(&pdev->dev, "failed to get clock for %s\n", name); > + return PTR_ERR(tcon->clock); > + } I wasn't very proud of my very similar implementation of the LVDS encoder code. It's a separate IP core, it should have been modeled by a separate DT node. I can't really ask you to do so for TCON given that I haven't done it for LVDS though, but I suspect we'll pay the price at some point (for instance when we'll have an SoC with the DU and TCON in separate power domains). If you have a clever idea to enhance this, please let me know. > + return 0; > +} > + > +int rcar_du_tconenc_init(struct rcar_du_device *rcdu) > +{ > + struct platform_device *pdev = to_platform_device(rcdu->dev); > + struct rcar_du_tconenc *tcon; > + unsigned int i; > + int ret; > + > + for (i = 0; i < rcdu->info->num_tcon; ++i) { > + tcon = devm_kzalloc(&pdev->dev, sizeof(*tcon), GFP_KERNEL); > + if (tcon == NULL) > + return -ENOMEM; > + > + tcon->dev = rcdu; > + tcon->index = i; > + tcon->enabled = false; > + > + ret = rcar_du_tconenc_get_resources(tcon, pdev); > + if (ret < 0) > + return ret; > + > + rcdu->tcon[i] = tcon; > + } > + > + return 0; > +} > Index: linux/drivers/gpu/drm/rcar-du/rcar_du_tconenc.h > =================================================================== > --- /dev/null > +++ linux/drivers/gpu/drm/rcar-du/rcar_du_tconenc.h > @@ -0,0 +1,37 @@ > +/* > + * rcar_du_tconenc.h -- R-Car Display Unit TCON Encoder > + * > + * Copyright (C) 2015-2016 CogentEmbedded, Inc. > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + */ > + > +#ifndef __RCAR_DU_TCONENC_H__ > +#define __RCAR_DU_TCONENC_H__ > + > +#include > +#include > + > +struct rcar_drm_crtc; > +struct rcar_du_tconenc; > + > +#if IS_ENABLED(CONFIG_DRM_RCAR_TCON) > +int rcar_du_tconenc_init(struct rcar_du_device *rcdu); > +int rcar_du_tconenc_enable(struct rcar_du_tconenc *tcon, > + struct drm_crtc *crtc, bool enable); > +#else > +static inline int rcar_du_tconenc_init(struct rcar_du_device *rcdu) > +{ > + return 0; > +} > +static inline int rcar_du_tconenc_enable(struct rcar_du_tconenc *tcon, > + struct drm_crtc *crtc, bool enable) > +{ > + return 0; > +} > +#endif > + > +#endif /* __RCAR_DU_TCONENC_H__ */ > Index: linux/drivers/gpu/drm/rcar-du/rcar_tcon_regs.h > =================================================================== > --- /dev/null > +++ linux/drivers/gpu/drm/rcar-du/rcar_tcon_regs.h > @@ -0,0 +1,70 @@ > +/* > + * rcar_tcon_regs.h -- R-Car TCON Registers Definitions > + * > + * Copyright (C) 2015-2016 CogentEmbedded, Inc. > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 > + * as published by the Free Software Foundation. > + */ > + > +#ifndef __RCAR_TCON_REGS_H__ > +#define __RCAR_TCON_REGS_H__ > + > +#define OUT_V_LATCH 0x0000 > +#define OUTCNT_VEN (1 << 0) > + > +#define OUT_CLK_PHASE 0x0024 > +#define OUTCNT_LCD_EDGE (1 << 8) /* If set, LCDOUT[23:0] are */ > + /* output on the falling edge */ > + /* of QCLK */ > + > +#define TCON_V_LATCH 0x0280 > +#define TCON_VEN (1 << 0) > + > +#define TCON_TIM 0x0284 > + > +/* Synced to VSYNC */ > +#define TCON_TIM_STVA1 0x0288 > +#define TCON_TIM_STVA2 0x028c > +#define TCON_TIM_STVB1 0x0290 > +#define TCON_TIM_STVB2 0x0294 > + > +/* Synced to HSYNC */ > +#define TCON_TIM_STH1 0x0298 > +#define TCON_TIM_STH2 0x029c > +#define TCON_TIM_STB1 0x02a0 > +#define TCON_TIM_STB2 0x02a4 > +#define TCON_TIM_CPV1 0x02a8 > +#define TCON_TIM_CPV2 0x02ac > +#define TCON_TIM_POLA1 0x02b0 > +#define TCON_TIM_POLA2 0x02b4 > +#define TCON_TIM_POLB1 0x02b8 > +#define TCON_TIM_POLB2 0x02bc > +#define TCON_TIM_DE 0x02c0 For the sake of completeness, could you define the TCON_DE_INV bit ? > + > +/* Common definitions for all TCON_TIM_*1 registers */ > +#define TCON_TIMING(start, width) (((start) << 16) | ((width) << 0)) > + > +/* Common definitions for all TCON_TIM_*2 registers */ > +#define TCON_INV (1 << 4) > +/* Output signal select */ > +#define TCON_SEL_STVA_VS 0 Could you write this as (0 << 0) (and some for the other bits below) to make it clearer that those are bit values ? > +#define TCON_SEL_STVB_VE 1 > +#define TCON_SEL_STH_SP_HS 2 > +#define TCON_SEL_STB_LP_HE 3 > +#define TCON_SEL_CPV_GCK 4 > +#define TCON_SEL_POLA 5 > +#define TCON_SEL_POLB 6 > +#define TCON_SEL_DE 7 I'd add a blank line here. > +/* Definitions for HSYNC-related TIM registers */ I'd list the registers explicitly here, or would add a short comment after each of them above to tell what they control. > +#define TCON_HS_SEL (1 << 8) /* If set, horizontal sync */ > + /* signal reference after the */ > + /* offset */ And a blank linke here too. > +/* Polarity generation mode */ Could you mention that this is applicable to POLA2 and POLB2 only ? > +#define TCON_MD_NORM (0 << 12) > +#define TCON_MD_1X1 (1 << 12) > +#define TCON_MD_1X2 (2 << 12) > +#define TCON_MD_2X2 (3 << 12) > + > +#endif /* __RCAR_TCON_REGS_H__ */ -- Regards, Laurent Pinchart From mboxrd@z Thu Jan 1 00:00:00 1970 From: Laurent Pinchart Subject: Re: [PATCH 2/4] rcar-du: add TCON encoder driver Date: Sat, 28 May 2016 00:28:02 +0300 Message-ID: <2235354.1XRvauYedm@avalon> References: <1787748.qAADjKK4gv@wasted.cogentembedded.com> <1606151.cnY0qcbrgr@wasted.cogentembedded.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from galahad.ideasonboard.com (galahad.ideasonboard.com [IPv6:2001:4b98:dc2:45:216:3eff:febb:480d]) by gabe.freedesktop.org (Postfix) with ESMTPS id D99CF6E292 for ; Fri, 27 May 2016 21:28:01 +0000 (UTC) In-Reply-To: <1606151.cnY0qcbrgr@wasted.cogentembedded.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: Sergei Shtylyov Cc: linux-renesas-soc@vger.kernel.org, dri-devel@lists.freedesktop.org List-Id: dri-devel@lists.freedesktop.org SGkgU2VyZ2VpLAoKVGhhbmsgeW91IGZvciB0aGUgcGF0Y2guCgpPbiBGcmlkYXkgMjkgQXByIDIw MTYgMDA6MDM6MjkgU2VyZ2VpIFNodHlseW92IHdyb3RlOgo+IFJlbmVzYXMgIFItQ2FyIFNvQ3Mg IGluY2x1ZGUgdGhlIHRpbWluZyBjb250cm9sbGVyIChUQ09OKSB0aGF0IGNhbiBkaXJlY3RseQo+ IGRyaXZlIExDRHMuIEl0IHJlY2VpdmVzICB0aGUgSC9WU1lOQywgZXRjLiBmcm9tIHRoZSBEaXNw bGF5IFVuaXQgKERVKSAgYW5kCj4gY29udmVydHMgIHRoZW0gdG8gdGhlIHNldCBvZiBzaWduYWxz ICB0aGF0IGEgTENEIHBhbmVsIGNhbiB1bmRlcnN0YW5kICh0aGUKPiBSQkcgIHNpZ25hbHMgYXJl IGVmZmVjdGl2ZWx5IHBhc3NlZCB0aHJ1KS4gIFRDT04gaGFzIGEgc2V0IG9mIHJlZ2lzdGVycwo+ IHRoYXQgd2UgbmVlZCB0byAgcHJvZ3JhbSBiYXNlZCBvbiB0aGUgdmlkZW8gbW9kZSB0aW1pbmdz LCBzbyB3ZSdyZSBhZGRpbmcKPiBhIERVIGVuY29kZXIgZHJpdmVyIGRvaW5nIHRoYXQuLi4KPiAK PiBCYXNlZCBvbiBhIGxhcmdlIHBhdGNoIGJ5IEFuZHJleSBHdXNha292Lgo+IAo+IFNpZ25lZC1v ZmYtYnk6IEFuZHJleSBHdXNha292IDxhbmRyZXkuZ3VzYWtvdkBjb2dlbnRlbWJlZGRlZC5jb20+ Cj4gU2lnbmVkLW9mZi1ieTogU2VyZ2VpIFNodHlseW92IDxzZXJnZWkuc2h0eWx5b3ZAY29nZW50 ZW1iZWRkZWQuY29tPgo+IAo+IC0tLQo+ICBkcml2ZXJzL2dwdS9kcm0vcmNhci1kdS9LY29uZmln ICAgICAgICAgICB8ICAgIDYKPiAgZHJpdmVycy9ncHUvZHJtL3JjYXItZHUvTWFrZWZpbGUgICAg ICAgICAgfCAgICAxCj4gIGRyaXZlcnMvZ3B1L2RybS9yY2FyLWR1L3JjYXJfZHVfZHJ2LmggICAg IHwgICAgNAo+ICBkcml2ZXJzL2dwdS9kcm0vcmNhci1kdS9yY2FyX2R1X2VuY29kZXIuYyB8ICAg IDkgKwo+ICBkcml2ZXJzL2dwdS9kcm0vcmNhci1kdS9yY2FyX2R1X2VuY29kZXIuaCB8ICAgIDMK PiAgZHJpdmVycy9ncHUvZHJtL3JjYXItZHUvcmNhcl9kdV9rbXMuYyAgICAgfCAgICA0Cj4gIGRy aXZlcnMvZ3B1L2RybS9yY2FyLWR1L3JjYXJfZHVfdGNvbmVuYy5jIHwgIDE4NCArKysrKysrKysr KysrKysrKysrKysrKysrKwo+ICBkcml2ZXJzL2dwdS9kcm0vcmNhci1kdS9yY2FyX2R1X3Rjb25l bmMuaCB8ICAgMzcgKysrKysrCj4gIGRyaXZlcnMvZ3B1L2RybS9yY2FyLWR1L3JjYXJfdGNvbl9y ZWdzLmggIHwgICA3MCArKysrKysrKysrKwo+ICA5IGZpbGVzIGNoYW5nZWQsIDMxOCBpbnNlcnRp b25zKCspCj4gCj4gSW5kZXg6IGxpbnV4L2RyaXZlcnMvZ3B1L2RybS9yY2FyLWR1L0tjb25maWcK PiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09 PT09PT09PT09PT09Cj4gLS0tIGxpbnV4Lm9yaWcvZHJpdmVycy9ncHUvZHJtL3JjYXItZHUvS2Nv bmZpZwo+ICsrKyBsaW51eC9kcml2ZXJzL2dwdS9kcm0vcmNhci1kdS9LY29uZmlnCj4gQEAgLTI0 LDYgKzI0LDEyIEBAIGNvbmZpZyBEUk1fUkNBUl9MVkRTCj4gIAloZWxwCj4gIAkgIEVuYWJsZSBz dXBwb3J0IGZvciB0aGUgUi1DYXIgRGlzcGxheSBVbml0IGVtYmVkZGVkIExWRFMgZW5jb2RlcnMu Cj4gCj4gK2NvbmZpZyBEUk1fUkNBUl9UQ09OCj4gKwlib29sICJSLUNhciBEVSBUQ09OIEVuY29k ZXIgU3VwcG9ydCIKPiArCWRlcGVuZHMgb24gRFJNX1JDQVJfRFUKPiArCWhlbHAKPiArCSAgRW5h YmxlIHN1cHBvcnQgZm9yIHRoZSBSLUNhciBEaXNwbGF5IFVuaXQgZW1iZWRkZWQgVENPTiBlbmNv ZGVycy4KPiArCj4gIGNvbmZpZyBEUk1fUkNBUl9WU1AKPiAgCWJvb2wgIlItQ2FyIERVIFZTUCBD b21wb3NpdG9yIFN1cHBvcnQiCj4gIAlkZXBlbmRzIG9uIERSTV9SQ0FSX0RVCj4gSW5kZXg6IGxp bnV4L2RyaXZlcnMvZ3B1L2RybS9yY2FyLWR1L01ha2VmaWxlCj4gPT09PT09PT09PT09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQo+IC0tLSBs aW51eC5vcmlnL2RyaXZlcnMvZ3B1L2RybS9yY2FyLWR1L01ha2VmaWxlCj4gKysrIGxpbnV4L2Ry aXZlcnMvZ3B1L2RybS9yY2FyLWR1L01ha2VmaWxlCj4gQEAgLTEwLDYgKzEwLDcgQEAgcmNhci1k dS1kcm0teSA6PSByY2FyX2R1X2NydGMubyBcCj4gIHJjYXItZHUtZHJtLSQoQ09ORklHX0RSTV9S Q0FSX0hETUkpCSs9IHJjYXJfZHVfaGRtaWNvbi5vIFwKPiAgCQkJCQkgICByY2FyX2R1X2hkbWll bmMubwo+ICByY2FyLWR1LWRybS0kKENPTkZJR19EUk1fUkNBUl9MVkRTKQkrPSByY2FyX2R1X2x2 ZHNlbmMubwo+ICtyY2FyLWR1LWRybS0kKENPTkZJR19EUk1fUkNBUl9UQ09OKQkrPSByY2FyX2R1 X3Rjb25lbmMubwo+IAo+ICByY2FyLWR1LWRybS0kKENPTkZJR19EUk1fUkNBUl9WU1ApCSs9IHJj YXJfZHVfdnNwLm8KPiAKPiBJbmRleDogbGludXgvZHJpdmVycy9ncHUvZHJtL3JjYXItZHUvcmNh cl9kdV9kcnYuaAo+ID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT0KPiAtLS0gbGludXgub3JpZy9kcml2ZXJzL2dwdS9kcm0v cmNhci1kdS9yY2FyX2R1X2Rydi5oCj4gKysrIGxpbnV4L2RyaXZlcnMvZ3B1L2RybS9yY2FyLWR1 L3JjYXJfZHVfZHJ2LmgKPiBAQCAtNTksNiArNTksNyBAQCBzdHJ1Y3QgcmNhcl9kdV9vdXRwdXRf cm91dGluZyB7Cj4gICAqIEBudW1fY3J0Y3M6IHRvdGFsIG51bWJlciBvZiBDUlRDcwo+ICAgKiBA cm91dGVzOiBhcnJheSBvZiBDUlRDIHRvIG91dHB1dCByb3V0ZXMsIGluZGV4ZWQgYnkgb3V0cHV0 Cj4gKFJDQVJfRFVfT1VUUFVUXyopICogQG51bV9sdmRzOiBudW1iZXIgb2YgaW50ZXJuYWwgTFZE UyBlbmNvZGVycwo+ICsgKiBAbnVtX3Rjb246IG51bWJlciBvZiBpbnRlcm5hbCBUQ09OIGVuY29k ZXJzCj4gICAqLwo+ICBzdHJ1Y3QgcmNhcl9kdV9kZXZpY2VfaW5mbyB7Cj4gIAl1bnNpZ25lZCBp bnQgZ2VuOwo+IEBAIC02NywxMSArNjgsMTMgQEAgc3RydWN0IHJjYXJfZHVfZGV2aWNlX2luZm8g ewo+ICAJdW5zaWduZWQgaW50IG51bV9jcnRjczsKPiAgCXN0cnVjdCByY2FyX2R1X291dHB1dF9y b3V0aW5nIHJvdXRlc1tSQ0FSX0RVX09VVFBVVF9NQVhdOwo+ICAJdW5zaWduZWQgaW50IG51bV9s dmRzOwo+ICsJdW5zaWduZWQgaW50IG51bV90Y29uOwo+ICB9Owo+IAo+ICAjZGVmaW5lIFJDQVJf RFVfTUFYX0NSVENTCQk0Cj4gICNkZWZpbmUgUkNBUl9EVV9NQVhfR1JPVVBTCQlESVZfUk9VTkRf VVAoUkNBUl9EVV9NQVhfQ1JUQ1MsIDIpCj4gICNkZWZpbmUgUkNBUl9EVV9NQVhfTFZEUwkJMgo+ ICsjZGVmaW5lIFJDQVJfRFVfTUFYX1RDT04JCTEKPiAgI2RlZmluZSBSQ0FSX0RVX01BWF9WU1BT CQk0Cj4gCj4gIHN0cnVjdCByY2FyX2R1X2RldmljZSB7Cj4gQEAgLTk5LDYgKzEwMiw3IEBAIHN0 cnVjdCByY2FyX2R1X2RldmljZSB7Cj4gIAl1bnNpZ25lZCBpbnQgdnNwZDFfc2luazsKPiAKPiAg CXN0cnVjdCByY2FyX2R1X2x2ZHNlbmMgKmx2ZHNbUkNBUl9EVV9NQVhfTFZEU107Cj4gKwlzdHJ1 Y3QgcmNhcl9kdV90Y29uZW5jICp0Y29uW1JDQVJfRFVfTUFYX1RDT05dOwo+IAo+ICAJc3RydWN0 IHsKPiAgCQl3YWl0X3F1ZXVlX2hlYWRfdCB3YWl0Owo+IEluZGV4OiBsaW51eC9kcml2ZXJzL2dw dS9kcm0vcmNhci1kdS9yY2FyX2R1X2VuY29kZXIuYwo+ID09PT09PT09PT09PT09PT09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KPiAtLS0gbGludXgu b3JpZy9kcml2ZXJzL2dwdS9kcm0vcmNhci1kdS9yY2FyX2R1X2VuY29kZXIuYwo+ICsrKyBsaW51 eC9kcml2ZXJzL2dwdS9kcm0vcmNhci1kdS9yY2FyX2R1X2VuY29kZXIuYwo+IEBAIC0yNCw2ICsy NCw3IEBACj4gICNpbmNsdWRlICJyY2FyX2R1X2ttcy5oIgo+ICAjaW5jbHVkZSAicmNhcl9kdV9s dmRzY29uLmgiCj4gICNpbmNsdWRlICJyY2FyX2R1X2x2ZHNlbmMuaCIKPiArI2luY2x1ZGUgInJj YXJfZHVfdGNvbmVuYy5oIgo+ICAjaW5jbHVkZSAicmNhcl9kdV92Z2Fjb24uaCIKPiAKPiAgLyog LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tCj4gQEAgLTQ4LDYgKzQ5LDggQEAgc3RhdGljIHZvaWQgcmNhcl9kdV9l bmNvZGVyX2Rpc2FibGUoc3RydQo+IAo+ICAJaWYgKHJlbmMtPmx2ZHMpCj4gIAkJcmNhcl9kdV9s dmRzZW5jX2VuYWJsZShyZW5jLT5sdmRzLCBlbmNvZGVyLT5jcnRjLCBmYWxzZSk7Cj4gKwlpZiAo cmVuYy0+dGNvbikKPiArCQlyY2FyX2R1X3Rjb25lbmNfZW5hYmxlKHJlbmMtPnRjb24sIGVuY29k ZXItPmNydGMsIGZhbHNlKTsKPiAgfQo+IAo+ICBzdGF0aWMgdm9pZCByY2FyX2R1X2VuY29kZXJf ZW5hYmxlKHN0cnVjdCBkcm1fZW5jb2RlciAqZW5jb2RlcikKPiBAQCAtNTYsNiArNTksOCBAQCBz dGF0aWMgdm9pZCByY2FyX2R1X2VuY29kZXJfZW5hYmxlKHN0cnVjCj4gCj4gIAlpZiAocmVuYy0+ bHZkcykKPiAgCQlyY2FyX2R1X2x2ZHNlbmNfZW5hYmxlKHJlbmMtPmx2ZHMsIGVuY29kZXItPmNy dGMsIHRydWUpOwo+ICsJaWYgKHJlbmMtPnRjb24pCj4gKwkJcmNhcl9kdV90Y29uZW5jX2VuYWJs ZShyZW5jLT50Y29uLCBlbmNvZGVyLT5jcnRjLCB0cnVlKTsKPiAgfQo+IAo+ICBzdGF0aWMgaW50 IHJjYXJfZHVfZW5jb2Rlcl9hdG9taWNfY2hlY2soc3RydWN0IGRybV9lbmNvZGVyICplbmNvZGVy LAo+IEBAIC0xNDIsNiArMTQ3LDEwIEBAIGludCByY2FyX2R1X2VuY29kZXJfaW5pdChzdHJ1Y3Qg cmNhcl9kdV8KPiAgCQlyZW5jLT5sdmRzID0gcmNkdS0+bHZkc1sxXTsKPiAgCQlicmVhazsKPiAK PiArCWNhc2UgUkNBUl9EVV9PVVRQVVRfVENPTjoKPiArCQlyZW5jLT50Y29uID0gcmNkdS0+dGNv blswXTsKPiArCQlicmVhazsKPiArCj4gIAlkZWZhdWx0Ogo+ICAJCWJyZWFrOwo+ICAJfQo+IElu ZGV4OiBsaW51eC9kcml2ZXJzL2dwdS9kcm0vcmNhci1kdS9yY2FyX2R1X2VuY29kZXIuaAo+ID09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09 PT09PT09PT0KPiAtLS0gbGludXgub3JpZy9kcml2ZXJzL2dwdS9kcm0vcmNhci1kdS9yY2FyX2R1 X2VuY29kZXIuaAo+ICsrKyBsaW51eC9kcml2ZXJzL2dwdS9kcm0vcmNhci1kdS9yY2FyX2R1X2Vu Y29kZXIuaAo+IEBAIC0yMCw2ICsyMCw3IEBACj4gIHN0cnVjdCByY2FyX2R1X2RldmljZTsKPiAg c3RydWN0IHJjYXJfZHVfaGRtaWVuYzsKPiAgc3RydWN0IHJjYXJfZHVfbHZkc2VuYzsKPiArc3Ry dWN0IHJjYXJfZHVfdGNvbmVuYzsKPiAKPiAgZW51bSByY2FyX2R1X2VuY29kZXJfdHlwZSB7Cj4g IAlSQ0FSX0RVX0VOQ09ERVJfVU5VU0VEID0gMCwKPiBAQCAtMjcsNiArMjgsNyBAQCBlbnVtIHJj YXJfZHVfZW5jb2Rlcl90eXBlIHsKPiAgCVJDQVJfRFVfRU5DT0RFUl9WR0EsCj4gIAlSQ0FSX0RV X0VOQ09ERVJfTFZEUywKPiAgCVJDQVJfRFVfRU5DT0RFUl9IRE1JLAo+ICsJUkNBUl9EVV9FTkNP REVSX1RDT04sCj4gIH07Cj4gCj4gIHN0cnVjdCByY2FyX2R1X2VuY29kZXIgewo+IEBAIC0zNCw2 ICszNiw3IEBAIHN0cnVjdCByY2FyX2R1X2VuY29kZXIgewo+ICAJZW51bSByY2FyX2R1X291dHB1 dCBvdXRwdXQ7Cj4gIAlzdHJ1Y3QgcmNhcl9kdV9oZG1pZW5jICpoZG1pOwo+ICAJc3RydWN0IHJj YXJfZHVfbHZkc2VuYyAqbHZkczsKPiArCXN0cnVjdCByY2FyX2R1X3Rjb25lbmMgKnRjb247Cj4g IH07Cj4gCj4gICNkZWZpbmUgdG9fcmNhcl9lbmNvZGVyKGUpIFwKPiBJbmRleDogbGludXgvZHJp dmVycy9ncHUvZHJtL3JjYXItZHUvcmNhcl9kdV9rbXMuYwo+ID09PT09PT09PT09PT09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KPiAtLS0gbGlu dXgub3JpZy9kcml2ZXJzL2dwdS9kcm0vcmNhci1kdS9yY2FyX2R1X2ttcy5jCj4gKysrIGxpbnV4 L2RyaXZlcnMvZ3B1L2RybS9yY2FyLWR1L3JjYXJfZHVfa21zLmMKPiBAQCAtMjcsNiArMjcsNyBA QAo+ICAjaW5jbHVkZSAicmNhcl9kdV9lbmNvZGVyLmgiCj4gICNpbmNsdWRlICJyY2FyX2R1X2tt cy5oIgo+ICAjaW5jbHVkZSAicmNhcl9kdV9sdmRzZW5jLmgiCj4gKyNpbmNsdWRlICJyY2FyX2R1 X3Rjb25lbmMuaCIKPiAgI2luY2x1ZGUgInJjYXJfZHVfcmVncy5oIgo+ICAjaW5jbHVkZSAicmNh cl9kdV92c3AuaCIKPiAKPiBAQCAtNjE5LDYgKzYyMCw5IEBAIGludCByY2FyX2R1X21vZGVzZXRf aW5pdChzdHJ1Y3QgcmNhcl9kdV8KPiAgCXJldCA9IHJjYXJfZHVfbHZkc2VuY19pbml0KHJjZHUp Owo+ICAJaWYgKHJldCA8IDApCj4gIAkJcmV0dXJuIHJldDsKPiArCXJldCA9IHJjYXJfZHVfdGNv bmVuY19pbml0KHJjZHUpOwo+ICsJaWYgKHJldCA8IDApCj4gKwkJcmV0dXJuIHJldDsKPiAKPiAg CXJldCA9IHJjYXJfZHVfZW5jb2RlcnNfaW5pdChyY2R1KTsKPiAgCWlmIChyZXQgPCAwKQo+IElu ZGV4OiBsaW51eC9kcml2ZXJzL2dwdS9kcm0vcmNhci1kdS9yY2FyX2R1X3Rjb25lbmMuYwo+ID09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09 PT09PT09PT0KPiAtLS0gL2Rldi9udWxsCj4gKysrIGxpbnV4L2RyaXZlcnMvZ3B1L2RybS9yY2Fy LWR1L3JjYXJfZHVfdGNvbmVuYy5jCj4gQEAgLTAsMCArMSwxODQgQEAKPiArLyoKPiArICogcmNh cl9kdV90Y29uZW5jLmMgLS0gUi1DYXIgRGlzcGxheSBVbml0IFRDT04gRW5jb2Rlcgo+ICsgKgo+ ICsgKiBDb3B5cmlnaHQgKEMpIDIwMTUtMjAxNiBDb2dlbnQgRW1iZWRkZWQsIEluYy4KPiA8c291 cmNlQGNvZ2VudGVtYmVkZGVkLmNvbT4KPiArICoKPiArICogVGhpcyBwcm9ncmFtIGlzIGZyZWUg c29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKPiArICogaXQg dW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJs aXNoZWQgYnkKPiArICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNp b24gMiBvZiB0aGUgTGljZW5zZSwgb3IKPiArICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIg dmVyc2lvbi4KPiArICovCj4gKwo+ICsjaW5jbHVkZSA8bGludXgvY2xrLmg+Cj4gKyNpbmNsdWRl IDxsaW51eC9kZWxheS5oPgo+ICsjaW5jbHVkZSA8bGludXgvaW8uaD4KPiArI2luY2x1ZGUgPGxp bnV4L3BsYXRmb3JtX2RldmljZS5oPgo+ICsjaW5jbHVkZSA8bGludXgvc2xhYi5oPgo+ICsjaW5j bHVkZSA8ZHJtL2RybV9lbmNvZGVyX3NsYXZlLmg+Cj4gKwo+ICsjaW5jbHVkZSAicmNhcl9kdV9k cnYuaCIKPiArI2luY2x1ZGUgInJjYXJfZHVfZW5jb2Rlci5oIgo+ICsjaW5jbHVkZSAicmNhcl9k dV90Y29uZW5jLmgiCj4gKyNpbmNsdWRlICJyY2FyX3Rjb25fcmVncy5oIgo+ICsKPiArc3RydWN0 IHJjYXJfZHVfdGNvbmVuYyB7Cj4gKwlzdHJ1Y3QgcmNhcl9kdV9kZXZpY2UgKmRldjsKPiArCj4g Kwl1bnNpZ25lZCBpbnQgaW5kZXg7Cj4gKwl2b2lkIF9faW9tZW0gKm1taW87Cj4gKwlzdHJ1Y3Qg Y2xrICpjbG9jazsKPiArCWJvb2wgZW5hYmxlZDsKPiArfTsKPiArCj4gK3N0YXRpYyB2b2lkIHJj YXJfdGNvbl93cml0ZShzdHJ1Y3QgcmNhcl9kdV90Y29uZW5jICp0Y29uLCB1MzIgcmVnLCB1MzIK PiBkYXRhKQo+ICt7Cj4gKwlpb3dyaXRlMzIoZGF0YSwgdGNvbi0+bW1pbyArIHJlZyk7Cj4gK30K PiArCj4gK3N0YXRpYyBpbnQgcmNhcl9kdV90Y29uZW5jX3N0YXJ0KHN0cnVjdCByY2FyX2R1X3Rj b25lbmMgKnRjb24sCj4gKwkJCQkgc3RydWN0IHJjYXJfZHVfY3J0YyAqcmNydGMpCj4gK3sKPiAr CWNvbnN0IHN0cnVjdCBkcm1fZGlzcGxheV9tb2RlICptb2RlID0gJnJjcnRjLT5jcnRjLm1vZGU7 Cj4gKwlpbnQgcmV0Owo+ICsKPiArCWlmICh0Y29uLT5lbmFibGVkKQoKTm93IHRoYXQgdGhlIERV IGRyaXZlciBpbXBsZW1lbnRzIHRoZSBhdG9taWMgQVBJIHRoZSBEUk0vS01TIGNvcmUgaXMgc3Vw cG9zZWQgCnRvIG9ubHkgZW5hYmxlL2Rpc2FibGUgQ1JUQ3MgYW5kIGVuY29kZXJzIHdoZW4gbmVl ZGVkLiBDYW4gdGhpcyBzdGlsbCBoYXBwZW4gPyAKU2FtZSBjb21tZW50IGZvciB0aGUgc3RvcCBm dW5jdGlvbi4KCj4gKwkJcmV0dXJuIDA7Cj4gKwo+ICsJcmV0ID0gY2xrX3ByZXBhcmVfZW5hYmxl KHRjb24tPmNsb2NrKTsKPiArCWlmIChyZXQgPCAwKQo+ICsJCXJldHVybiByZXQ7Cj4gKwo+ICsJ LyogVXBkYXRlICovCj4gKwlyY2FyX3Rjb25fd3JpdGUodGNvbiwgT1VUX1ZfTEFUQ0gsIE9VVENO VF9WRU4pOwo+ICsJcmNhcl90Y29uX3dyaXRlKHRjb24sIFRDT05fVl9MQVRDSCwgVENPTl9WRU4p OwoKQXJlbid0IHlvdSBzdXBwb3NlZCB0byBzZXQgdGhvc2UgYml0cyBhZnRlciBtb2RpZnlpbmcg dGhlIHJlZ2lzdGVycyBvbmx5LCBub3QgCmJlZm9yZSA/Cgo+ICsJLyogU2lnbmFsczoKPiArCSAq IFItQ2FyCURpc3BsYXkKPiArCSAqIFFDTEsJCVNTQyAoU291cmNlIERyaXZlciBDbG9jayBJbnB1 dCkKPiArCSAqIFFTVEgJCVNTUCAoU291cmNlIFNjYW5uaW5nIFNpZ25hbCBMZWZ0L1JpZ2h0KQo+ ICsJICogUVNUQgkJU09FIChTb3VyY2UgRHJpdmVyIE91dHB1dCBFbmFibGUpCj4gKwkgKiBRQ1BW CQlHT0UgKEdhdGUgRHJpdmVyIE91dHB1dCBFbmFibGUpCj4gKwkgKiBRUE9MQQlQT0wgKFBvbGFy aXR5IENvbnRyb2wgU2lnbmFsKQo+ICsJICogUVBPTEIJR1NDIChHYXRlIERyaXZlciBTY2Fubmlu ZyBDbG9jaykKPiArCSAqIFFTVFZBCUdTUCAoR2F0ZSBTY2FubmluZyBTdGFydCBTaWduYWwgVXAv RG93bikKPiArCSAqIFFTVFZCCW5vcGUKPiArCSAqLwo+ICsJLyogU2V0dXAgdGltaW5ncyAqLwo+ ICsJcmNhcl90Y29uX3dyaXRlKHRjb24sIFRDT05fVElNLCBUQ09OX1RJTUlORyg1MCwgMCkpOwo+ ICsJLyogSG9yaXpvbnRhbCB0aW1pbmdzICovCj4gKwlyY2FyX3Rjb25fd3JpdGUodGNvbiwgVENP Tl9USU1fU1RIMSwgVENPTl9USU1JTkcobW9kZS0+aHRvdGFsIC0KPiArCQkJCQkJCSBtb2RlLT5o c3luY19zdGFydCAtIDEsCj4gKwkJCQkJCQkgMSkpOwo+ICsJcmNhcl90Y29uX3dyaXRlKHRjb24s IFRDT05fVElNX1NUSDIsIFRDT05fU0VMX1NUSF9TUF9IUyk7Cj4gKwlyY2FyX3Rjb25fd3JpdGUo dGNvbiwgVENPTl9USU1fU1RCMSwgVENPTl9USU1JTkcobW9kZS0+aHRvdGFsIC0KPiArCQkJCQkJ CSBtb2RlLT5oc3luY19zdGFydCArCj4gKwkJCQkJCQkgbW9kZS0+aGRpc3BsYXkgKyA2LAo+ICsJ CQkJCQkJIDMpKTsKPiArCXJjYXJfdGNvbl93cml0ZSh0Y29uLCBUQ09OX1RJTV9TVEIyLCBUQ09O X1NFTF9TVEJfTFBfSEUpOwo+ICsJcmNhcl90Y29uX3dyaXRlKHRjb24sIFRDT05fVElNX1BPTEIx LAo+ICsJCQlUQ09OX1RJTUlORyhtb2RlLT5odG90YWwgLSBtb2RlLT5oc3luY19zdGFydCArCj4g KwkJCQkgICAgbW9kZS0+aGRpc3BsYXkgLSA4LCBtb2RlLT5odG90YWwgLyAyKSk7Cj4gKwlyY2Fy X3Rjb25fd3JpdGUodGNvbiwgVENPTl9USU1fUE9MQjIsCj4gKwkJCVRDT05fU0VMX1BPTEIgfCBU Q09OX0lOViB8IFRDT05fTURfTk9STSk7Cj4gKwlyY2FyX3Rjb25fd3JpdGUodGNvbiwgVENPTl9U SU1fQ1BWMSwKPiArCQkJVENPTl9USU1JTkcobW9kZS0+aHRvdGFsIC0gbW9kZS0+aHN5bmNfc3Rh cnQgKwo+ICsJCQkJICAgIG1vZGUtPmhkaXNwbGF5IC0gMzMsIDUwKSk7Cj4gKwlyY2FyX3Rjb25f d3JpdGUodGNvbiwgVENPTl9USU1fQ1BWMiwgVENPTl9TRUxfQ1BWX0dDSyk7Cj4gKwlyY2FyX3Rj b25fd3JpdGUodGNvbiwgVENPTl9USU1fUE9MQTEsCj4gKwkJCVRDT05fVElNSU5HKG1vZGUtPmh0 b3RhbCAtIG1vZGUtPmhzeW5jX3N0YXJ0ICsKPiArCQkJCSAgICBtb2RlLT5oZGlzcGxheSArIDEs IDM5KSk7Cj4gKwlyY2FyX3Rjb25fd3JpdGUodGNvbiwgVENPTl9USU1fUE9MQTIsCj4gKwkJCVRD T05fU0VMX1BPTEEgfCBUQ09OX0lOViB8IFRDT05fTURfMVgxKTsKPiArCj4gKwkvKiBWZXJ0aWNh bCB0aW1pbmdzICovCj4gKwlyY2FyX3Rjb25fd3JpdGUodGNvbiwgVENPTl9USU1fU1RWQTEsCj4g KwkJCVRDT05fVElNSU5HKG1vZGUtPnZ0b3RhbCAtIG1vZGUtPnZzeW5jX3N0YXJ0LCAxKSk7Cj4g KwlyY2FyX3Rjb25fd3JpdGUodGNvbiwgVENPTl9USU1fU1RWQTIsIFRDT05fU0VMX1NUVkFfVlMp Owo+ICsJcmNhcl90Y29uX3dyaXRlKHRjb24sIFRDT05fVElNX1NUVkIxLCBUQ09OX1RJTUlORygw LCAwKSk7Cj4gKwlyY2FyX3Rjb25fd3JpdGUodGNvbiwgVENPTl9USU1fU1RWQjIsIFRDT05fU0VM X1NUVkJfVkUpOwo+ICsKPiArCS8qIERhdGEgY2xvY2tlZCBvdXQgb24gdGhlIGZhbGxpbmcgZWRn ZSBvZiBRQ0xLLCBsYXRjaGVkIGluIExDRCBvbgo+ICsJICogdGhlIHJpc2luZyBlZGdlCj4gKwkg Ki8KPiArCXJjYXJfdGNvbl93cml0ZSh0Y29uLCBPVVRfQ0xLX1BIQVNFLCBPVVRDTlRfTENEX0VE R0UpOwoKSSBjYW4ndCB2ZXJpZnkgYWxsIHRob3NlIHNldHRpbmdzIGFzIEkgaGF2ZSBubyBpZGVh IGhvdyBUQ09OIG9wZXJhdGVzLiAKSG93ZXZlciwgaXQgbG9va3MgbGlrZSB3ZSBoYXZlIGxvdHMg b2YgbWFnaWMgbnVtYmVycywgYW5kIEkgaGF2ZSBhIGZlZWxpbmcgCnRob3NlIGFjdHVhbGx5IGRl cGVuZCBvbiB0aGUgcGFuZWwgbW9kZWwuIEFtIEkgd3JvbmcgPwoKPiArCS8qIFVwZGF0ZSAqLwo+ ICsJcmNhcl90Y29uX3dyaXRlKHRjb24sIE9VVF9WX0xBVENILCBPVVRDTlRfVkVOKTsKPiArCXJj YXJfdGNvbl93cml0ZSh0Y29uLCBUQ09OX1ZfTEFUQ0gsIFRDT05fVkVOKTsKPiArCj4gKwl0Y29u LT5lbmFibGVkID0gdHJ1ZTsKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIHZv aWQgcmNhcl9kdV90Y29uZW5jX3N0b3Aoc3RydWN0IHJjYXJfZHVfdGNvbmVuYyAqdGNvbikKPiAr ewo+ICsJaWYgKCF0Y29uLT5lbmFibGVkKQo+ICsJCXJldHVybjsKPiArCj4gKwljbGtfZGlzYWJs ZV91bnByZXBhcmUodGNvbi0+Y2xvY2spOwo+ICsKPiArCXRjb24tPmVuYWJsZWQgPSBmYWxzZTsK PiArfQo+ICsKPiAraW50IHJjYXJfZHVfdGNvbmVuY19lbmFibGUoc3RydWN0IHJjYXJfZHVfdGNv bmVuYyAqdGNvbiwgc3RydWN0IGRybV9jcnRjCj4gKmNydGMsCj4gKwkJCSAgIGJvb2wgZW5hYmxl KQo+ICt7Cj4gKwlpZiAoIWVuYWJsZSkgewo+ICsJCXJjYXJfZHVfdGNvbmVuY19zdG9wKHRjb24p Owo+ICsJCXJldHVybiAwOwo+ICsJfSBlbHNlIGlmIChjcnRjKSB7Cj4gKwkJc3RydWN0IHJjYXJf ZHVfY3J0YyAqcmNydGMgPSB0b19yY2FyX2NydGMoY3J0Yyk7Cj4gKwo+ICsJCXJldHVybiByY2Fy X2R1X3Rjb25lbmNfc3RhcnQodGNvbiwgcmNydGMpOwo+ICsJfSBlbHNlCj4gKwkJcmV0dXJuIC1F SU5WQUw7CgpNaXNzaW5nIHsgfSBhcm91bmQgdGhlIGxhc3QgYnJhbmNoLiBJcyB0aGlzIG5lZWRl ZCB0aG91Z2gsIGNhbiBlbmFibGUgYmUgdHJ1ZSAKYW5kIGNydGMgTlVMTCA/IElmIHNvLCB1bmRl ciB3aGljaCBjaXJjdW1zdGFuY2VzID8KCj4gK30KPiArCj4gK3N0YXRpYyBpbnQgcmNhcl9kdV90 Y29uZW5jX2dldF9yZXNvdXJjZXMoc3RydWN0IHJjYXJfZHVfdGNvbmVuYyAqdGNvbiwKPiArCQkJ CQkgc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKPiArewo+ICsJc3RydWN0IHJlc291cmNl ICptZW07Cj4gKwljaGFyIG5hbWVbN107Cj4gKwo+ICsJc3ByaW50ZihuYW1lLCAidGNvbi4ldSIs IHRjb24tPmluZGV4KTsKPiArCj4gKwltZW0gPSBwbGF0Zm9ybV9nZXRfcmVzb3VyY2VfYnluYW1l KHBkZXYsIElPUkVTT1VSQ0VfTUVNLCBuYW1lKTsKPiArCXRjb24tPm1taW8gPSBkZXZtX2lvcmVt YXBfcmVzb3VyY2UoJnBkZXYtPmRldiwgbWVtKTsKPiArCWlmIChJU19FUlIodGNvbi0+bW1pbykp Cj4gKwkJcmV0dXJuIFBUUl9FUlIodGNvbi0+bW1pbyk7Cj4gKwo+ICsJdGNvbi0+Y2xvY2sgPSBk ZXZtX2Nsa19nZXQoJnBkZXYtPmRldiwgbmFtZSk7Cj4gKwlpZiAoSVNfRVJSKHRjb24tPmNsb2Nr KSkgewo+ICsJCWRldl9lcnIoJnBkZXYtPmRldiwgImZhaWxlZCB0byBnZXQgY2xvY2sgZm9yICVz XG4iLCBuYW1lKTsKPiArCQlyZXR1cm4gUFRSX0VSUih0Y29uLT5jbG9jayk7Cj4gKwl9CgpJIHdh c24ndCB2ZXJ5IHByb3VkIG9mIG15IHZlcnkgc2ltaWxhciBpbXBsZW1lbnRhdGlvbiBvZiB0aGUg TFZEUyBlbmNvZGVyIApjb2RlLiBJdCdzIGEgc2VwYXJhdGUgSVAgY29yZSwgaXQgc2hvdWxkIGhh dmUgYmVlbiBtb2RlbGVkIGJ5IGEgc2VwYXJhdGUgRFQgCm5vZGUuIEkgY2FuJ3QgcmVhbGx5IGFz ayB5b3UgdG8gZG8gc28gZm9yIFRDT04gZ2l2ZW4gdGhhdCBJIGhhdmVuJ3QgZG9uZSBpdCAKZm9y IExWRFMgdGhvdWdoLCBidXQgSSBzdXNwZWN0IHdlJ2xsIHBheSB0aGUgcHJpY2UgYXQgc29tZSBw b2ludCAoZm9yIGluc3RhbmNlIAp3aGVuIHdlJ2xsIGhhdmUgYW4gU29DIHdpdGggdGhlIERVIGFu ZCBUQ09OIGluIHNlcGFyYXRlIHBvd2VyIGRvbWFpbnMpLiBJZiB5b3UgCmhhdmUgYSBjbGV2ZXIg aWRlYSB0byBlbmhhbmNlIHRoaXMsIHBsZWFzZSBsZXQgbWUga25vdy4KCj4gKwlyZXR1cm4gMDsK PiArfQo+ICsKPiAraW50IHJjYXJfZHVfdGNvbmVuY19pbml0KHN0cnVjdCByY2FyX2R1X2Rldmlj ZSAqcmNkdSkKPiArewo+ICsJc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldiA9IHRvX3BsYXRm b3JtX2RldmljZShyY2R1LT5kZXYpOwo+ICsJc3RydWN0IHJjYXJfZHVfdGNvbmVuYyAqdGNvbjsK PiArCXVuc2lnbmVkIGludCBpOwo+ICsJaW50IHJldDsKPiArCj4gKwlmb3IgKGkgPSAwOyBpIDwg cmNkdS0+aW5mby0+bnVtX3Rjb247ICsraSkgewo+ICsJCXRjb24gPSBkZXZtX2t6YWxsb2MoJnBk ZXYtPmRldiwgc2l6ZW9mKCp0Y29uKSwgR0ZQX0tFUk5FTCk7Cj4gKwkJaWYgKHRjb24gPT0gTlVM TCkKPiArCQkJcmV0dXJuIC1FTk9NRU07Cj4gKwo+ICsJCXRjb24tPmRldiA9IHJjZHU7Cj4gKwkJ dGNvbi0+aW5kZXggPSBpOwo+ICsJCXRjb24tPmVuYWJsZWQgPSBmYWxzZTsKPiArCj4gKwkJcmV0 ID0gcmNhcl9kdV90Y29uZW5jX2dldF9yZXNvdXJjZXModGNvbiwgcGRldik7Cj4gKwkJaWYgKHJl dCA8IDApCj4gKwkJCXJldHVybiByZXQ7Cj4gKwo+ICsJCXJjZHUtPnRjb25baV0gPSB0Y29uOwo+ ICsJfQo+ICsKPiArCXJldHVybiAwOwo+ICt9Cj4gSW5kZXg6IGxpbnV4L2RyaXZlcnMvZ3B1L2Ry bS9yY2FyLWR1L3JjYXJfZHVfdGNvbmVuYy5oCj4gPT09PT09PT09PT09PT09PT09PT09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQo+IC0tLSAvZGV2L251bGwK PiArKysgbGludXgvZHJpdmVycy9ncHUvZHJtL3JjYXItZHUvcmNhcl9kdV90Y29uZW5jLmgKPiBA QCAtMCwwICsxLDM3IEBACj4gKy8qCj4gKyAqIHJjYXJfZHVfdGNvbmVuYy5oIC0tIFItQ2FyIERp c3BsYXkgVW5pdCBUQ09OIEVuY29kZXIKPiArICoKPiArICogQ29weXJpZ2h0IChDKSAyMDE1LTIw MTYgQ29nZW50RW1iZWRkZWQsIEluYy4gPHNvdXJjZUBjb2dlbnRlbWJlZGRlZC5jb20+Cj4gKyAq Cj4gKyAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0 ZSBpdCBhbmQvb3IgbW9kaWZ5Cj4gKyAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdl bmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5Cj4gKyAqIHRoZSBGcmVlIFNvZnR3 YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yCj4gKyAq IChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCj4gKyAqLwo+ICsKPiArI2lmbmRl ZiBfX1JDQVJfRFVfVENPTkVOQ19IX18KPiArI2RlZmluZSBfX1JDQVJfRFVfVENPTkVOQ19IX18K PiArCj4gKyNpbmNsdWRlIDxsaW51eC9pby5oPgo+ICsjaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+ Cj4gKwo+ICtzdHJ1Y3QgcmNhcl9kcm1fY3J0YzsKPiArc3RydWN0IHJjYXJfZHVfdGNvbmVuYzsK PiArCj4gKyNpZiBJU19FTkFCTEVEKENPTkZJR19EUk1fUkNBUl9UQ09OKQo+ICtpbnQgcmNhcl9k dV90Y29uZW5jX2luaXQoc3RydWN0IHJjYXJfZHVfZGV2aWNlICpyY2R1KTsKPiAraW50IHJjYXJf ZHVfdGNvbmVuY19lbmFibGUoc3RydWN0IHJjYXJfZHVfdGNvbmVuYyAqdGNvbiwKPiArCQkJICAg c3RydWN0IGRybV9jcnRjICpjcnRjLCBib29sIGVuYWJsZSk7Cj4gKyNlbHNlCj4gK3N0YXRpYyBp bmxpbmUgaW50IHJjYXJfZHVfdGNvbmVuY19pbml0KHN0cnVjdCByY2FyX2R1X2RldmljZSAqcmNk dSkKPiArewo+ICsJcmV0dXJuIDA7Cj4gK30KPiArc3RhdGljIGlubGluZSBpbnQgcmNhcl9kdV90 Y29uZW5jX2VuYWJsZShzdHJ1Y3QgcmNhcl9kdV90Y29uZW5jICp0Y29uLAo+ICsJCQkJCSBzdHJ1 Y3QgZHJtX2NydGMgKmNydGMsIGJvb2wgZW5hYmxlKQo+ICt7Cj4gKwlyZXR1cm4gMDsKPiArfQo+ ICsjZW5kaWYKPiArCj4gKyNlbmRpZiAvKiBfX1JDQVJfRFVfVENPTkVOQ19IX18gKi8KPiBJbmRl eDogbGludXgvZHJpdmVycy9ncHUvZHJtL3JjYXItZHUvcmNhcl90Y29uX3JlZ3MuaAo+ID09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09 PT09PT0KPiAtLS0gL2Rldi9udWxsCj4gKysrIGxpbnV4L2RyaXZlcnMvZ3B1L2RybS9yY2FyLWR1 L3JjYXJfdGNvbl9yZWdzLmgKPiBAQCAtMCwwICsxLDcwIEBACj4gKy8qCj4gKyAqIHJjYXJfdGNv bl9yZWdzLmggLS0gUi1DYXIgVENPTiBSZWdpc3RlcnMgRGVmaW5pdGlvbnMKPiArICoKPiArICog Q29weXJpZ2h0IChDKSAyMDE1LTIwMTYgQ29nZW50RW1iZWRkZWQsIEluYy4gPHNvdXJjZUBjb2dl bnRlbWJlZGRlZC5jb20+Cj4gKyAqCj4gKyAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJl OyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5Cj4gKyAqIGl0IHVuZGVyIHRo ZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyCj4gKyAq IGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgo+ICsgKi8KPiAr Cj4gKyNpZm5kZWYgX19SQ0FSX1RDT05fUkVHU19IX18KPiArI2RlZmluZSBfX1JDQVJfVENPTl9S RUdTX0hfXwo+ICsKPiArI2RlZmluZSBPVVRfVl9MQVRDSAkJMHgwMDAwCj4gKyNkZWZpbmUgT1VU Q05UX1ZFTgkJKDEgPDwgMCkKPiArCj4gKyNkZWZpbmUgT1VUX0NMS19QSEFTRQkJMHgwMDI0Cj4g KyNkZWZpbmUgT1VUQ05UX0xDRF9FREdFCQkoMSA8PCA4KQkvKiBJZiBzZXQsIExDRE9VVFsyMzow XSBhcmUgKi8KPiArCQkJCQkJLyogb3V0cHV0IG9uIHRoZSBmYWxsaW5nIGVkZ2UgKi8KPiArCQkJ CQkJLyogb2YgUUNMSyAqLwo+ICsKPiArI2RlZmluZSBUQ09OX1ZfTEFUQ0gJCTB4MDI4MAo+ICsj ZGVmaW5lIFRDT05fVkVOCQkoMSA8PCAwKQo+ICsKPiArI2RlZmluZSBUQ09OX1RJTQkJMHgwMjg0 Cj4gKwo+ICsvKiBTeW5jZWQgdG8gVlNZTkMgKi8KPiArI2RlZmluZSBUQ09OX1RJTV9TVFZBMQkJ MHgwMjg4Cj4gKyNkZWZpbmUgVENPTl9USU1fU1RWQTIJCTB4MDI4Ywo+ICsjZGVmaW5lIFRDT05f VElNX1NUVkIxCQkweDAyOTAKPiArI2RlZmluZSBUQ09OX1RJTV9TVFZCMgkJMHgwMjk0Cj4gKwo+ ICsvKiBTeW5jZWQgdG8gSFNZTkMgKi8KPiArI2RlZmluZSBUQ09OX1RJTV9TVEgxCQkweDAyOTgK PiArI2RlZmluZSBUQ09OX1RJTV9TVEgyCQkweDAyOWMKPiArI2RlZmluZSBUQ09OX1RJTV9TVEIx CQkweDAyYTAKPiArI2RlZmluZSBUQ09OX1RJTV9TVEIyCQkweDAyYTQKPiArI2RlZmluZSBUQ09O X1RJTV9DUFYxCQkweDAyYTgKPiArI2RlZmluZSBUQ09OX1RJTV9DUFYyCQkweDAyYWMKPiArI2Rl ZmluZSBUQ09OX1RJTV9QT0xBMQkJMHgwMmIwCj4gKyNkZWZpbmUgVENPTl9USU1fUE9MQTIJCTB4 MDJiNAo+ICsjZGVmaW5lIFRDT05fVElNX1BPTEIxCQkweDAyYjgKPiArI2RlZmluZSBUQ09OX1RJ TV9QT0xCMgkJMHgwMmJjCj4gKyNkZWZpbmUgVENPTl9USU1fREUJCTB4MDJjMAoKRm9yIHRoZSBz YWtlIG9mIGNvbXBsZXRlbmVzcywgY291bGQgeW91IGRlZmluZSB0aGUgVENPTl9ERV9JTlYgYml0 ID8KCj4gKwo+ICsvKiBDb21tb24gZGVmaW5pdGlvbnMgZm9yIGFsbCBUQ09OX1RJTV8qMSByZWdp c3RlcnMgKi8KPiArI2RlZmluZSBUQ09OX1RJTUlORyhzdGFydCwgd2lkdGgpICgoKHN0YXJ0KSA8 PCAxNikgfCAoKHdpZHRoKSA8PCAwKSkKPiArCj4gKy8qIENvbW1vbiBkZWZpbml0aW9ucyBmb3Ig YWxsIFRDT05fVElNXyoyIHJlZ2lzdGVycyAqLwo+ICsjZGVmaW5lIFRDT05fSU5WCQkoMSA8PCA0 KQo+ICsvKiBPdXRwdXQgc2lnbmFsIHNlbGVjdCAqLwo+ICsjZGVmaW5lIFRDT05fU0VMX1NUVkFf VlMJMAoKQ291bGQgeW91IHdyaXRlIHRoaXMgYXMgKDAgPDwgMCkgKGFuZCBzb21lIGZvciB0aGUg b3RoZXIgYml0cyBiZWxvdykgdG8gbWFrZSAKaXQgY2xlYXJlciB0aGF0IHRob3NlIGFyZSBiaXQg dmFsdWVzID8KCj4gKyNkZWZpbmUgVENPTl9TRUxfU1RWQl9WRQkxCj4gKyNkZWZpbmUgVENPTl9T RUxfU1RIX1NQX0hTCTIKPiArI2RlZmluZSBUQ09OX1NFTF9TVEJfTFBfSEUJMwo+ICsjZGVmaW5l IFRDT05fU0VMX0NQVl9HQ0sJNAo+ICsjZGVmaW5lIFRDT05fU0VMX1BPTEEJCTUKPiArI2RlZmlu ZSBUQ09OX1NFTF9QT0xCCQk2Cj4gKyNkZWZpbmUgVENPTl9TRUxfREUJCTcKCkknZCBhZGQgYSBi bGFuayBsaW5lIGhlcmUuCgo+ICsvKiBEZWZpbml0aW9ucyBmb3IgSFNZTkMtcmVsYXRlZCBUSU0g cmVnaXN0ZXJzICovCgpJJ2QgbGlzdCB0aGUgcmVnaXN0ZXJzIGV4cGxpY2l0bHkgaGVyZSwgb3Ig d291bGQgYWRkIGEgc2hvcnQgY29tbWVudCBhZnRlciAKZWFjaCBvZiB0aGVtIGFib3ZlIHRvIHRl bGwgd2hhdCB0aGV5IGNvbnRyb2wuCgo+ICsjZGVmaW5lIFRDT05fSFNfU0VMCQkoMSA8PCA4KQkv KiBJZiBzZXQsIGhvcml6b250YWwgc3luYyAgICAqLwo+ICsJCQkJCQkvKiBzaWduYWwgcmVmZXJl bmNlIGFmdGVyIHRoZSAqLwo+ICsJCQkJCQkvKiBvZmZzZXQgKi8KCkFuZCBhIGJsYW5rIGxpbmtl IGhlcmUgdG9vLgoKPiArLyogUG9sYXJpdHkgZ2VuZXJhdGlvbiBtb2RlICovCgpDb3VsZCB5b3Ug bWVudGlvbiB0aGF0IHRoaXMgaXMgYXBwbGljYWJsZSB0byBQT0xBMiBhbmQgUE9MQjIgb25seSA/ Cgo+ICsjZGVmaW5lIFRDT05fTURfTk9STQkJKDAgPDwgMTIpCj4gKyNkZWZpbmUgVENPTl9NRF8x WDEJCSgxIDw8IDEyKQo+ICsjZGVmaW5lIFRDT05fTURfMVgyCQkoMiA8PCAxMikKPiArI2RlZmlu ZSBUQ09OX01EXzJYMgkJKDMgPDwgMTIpCj4gKwo+ICsjZW5kaWYgLyogX19SQ0FSX1RDT05fUkVH U19IX18gKi8KCi0tIApSZWdhcmRzLAoKTGF1cmVudCBQaW5jaGFydAoKX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KZHJpLWRldmVsIG1haWxpbmcgbGlzdApk cmktZGV2ZWxAbGlzdHMuZnJlZWRlc2t0b3Aub3JnCmh0dHBzOi8vbGlzdHMuZnJlZWRlc2t0b3Au b3JnL21haWxtYW4vbGlzdGluZm8vZHJpLWRldmVsCg==